Mercurial > mm7
view Render.cpp @ 2494:de8c5c223e9c
for ACTOR_
author | Ritor1 |
---|---|
date | Tue, 16 Sep 2014 17:48:58 +0600 |
parents | 0a0c6d75aabe |
children |
line wrap: on
line source
#define _CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h> #define _CRT_SECURE_NO_WARNINGS #include "ZlibWrapper.h" #include "ErrorHandling.h" #include "Render.h" #include "MediaPlayer.h" #include "Sprites.h" #include "Mouse.h" #include "GammaControl.h" #include "stru6.h" #include "GUIWindow.h" #include "DecalBuilder.h" #include "ParticleEngine.h" #include "Outdoor.h" #include "Party.h" #include "LOD.h" #include "Viewport.h" #include "OurMath.h" #include "PaletteManager.h" #include "Timer.h" #include "Game.h" #include "LightmapBuilder.h" #include "ObjectList.h" #include "SpriteObject.h" #include "DecorationList.h" #include "Actor.h" #include "Log.h" #include "MM7.h" #include "Lights.h" #include "Level/Decoration.h" #include "Vis.h" #include "Registry.h" #include "Weather.h" #include "MMT.h" //#pragma comment(lib, "lib\\legacy_dx\\lib\\ddraw.lib") //#pragma comment(lib, "lib\\legacy_dx\\lib\\dxguid.lib") struct IDirectDrawClipper *pDDrawClipper; struct IRender *pRenderer; // idb struct RenderVertexD3D3 pVertices[50]; int uNumDecorationsDrawnThisFrame; // weak RenderBillboard pBillboardRenderList[500]; unsigned int uNumBillboardsToDraw; int uNumSpritesDrawnThisFrame; // weak RenderVertexSoft array_507D30[50]; RenderVertexSoft array_50AC10[50]; RenderVertexSoft array_73D150[20]; RenderVertexD3D3 d3d_vertex_buffer[50]; /* 384 */ #pragma pack(push, 1) struct PCXHeader_1 { char manufacturer; char version; char encoding; char bpp; __int16 left; __int16 up; __int16 right; __int16 bottom; __int16 hdpi; __int16 vdpi; }; #pragma pack(pop) /* 385 */ #pragma pack(push, 1) struct PCXHeader_2 { char reserved; char planes; __int16 pitch; __int16 palette_info; }; #pragma pack(pop) HRESULT __stdcall D3DZBufferFormatEnumerator(DDPIXELFORMAT *Src, DDPIXELFORMAT *Dst); HRESULT __stdcall DDrawDisplayModesEnumerator(DDSURFACEDESC2 *pSurfaceDesc, __int16 *a2); HRESULT __stdcall D3DDeviceEnumerator(const GUID *lpGUID, const char *lpDeviceDesc, const char *lpDeviceName, D3DDEVICEDESC *pHWDesc, D3DDEVICEDESC *pSWDesc, struct RenderD3D_aux *a6); signed int __stdcall RenderD3D__DeviceEnumerator(GUID *lpGUID, const char *lpDevDesc, const char *lpDriverName, RenderD3D__DevInfo *pOut); // idb //----- (0049E79F) -------------------------------------------------------- bool Render::CheckTextureStages() { bool v0; // edi@1 IDirectDrawSurface4 *pSurface2; // [sp+Ch] [bp-14h]@1 IDirectDrawSurface4 *pSurface1; // [sp+10h] [bp-10h]@1 DWORD v4; // [sp+14h] [bp-Ch]@1 IDirect3DTexture2 *pTexture2; // [sp+18h] [bp-8h]@1 IDirect3DTexture2 *pTexture1; // [sp+1Ch] [bp-4h]@1 v0 = false; pRenderD3D->CreateTexture(64, 64, &pSurface1, &pTexture1, true, false, 32); pRenderD3D->CreateTexture(64, 64, &pSurface2, &pTexture2, true, false, 32); ErrD3D(pRenderD3D->pDevice->SetTexture(0, pTexture1)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLOROP, 2)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, 2)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, 2)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MINFILTER, 2)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, 1)); ErrD3D(pRenderD3D->pDevice->SetTexture(0, pTexture2)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_COLOROP, 7)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_COLORARG1, 2)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_COLORARG2, 1)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_MAGFILTER, 2)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_MINFILTER, 2)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_MIPFILTER, 1)); if ( !pRenderD3D->pDevice->ValidateDevice(&v4) && v4 == 1 ) v0 = true; ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_COLOROP, 1)); pTexture1->Release(); pTexture2->Release(); pSurface1->Release(); pSurface2->Release(); return v0; } //----- (00440CB8) -------------------------------------------------------- void Render::DrawBillboardList_BLV() { RenderBillboardTransform_local0 soft_billboard; // [sp+4h] [bp-50h]@1 soft_billboard.sParentBillboardID = -1; soft_billboard.pTarget = pBLVRenderParams->pRenderTarget; soft_billboard.pTargetZ = pBLVRenderParams->pTargetZBuffer; soft_billboard.uTargetPitch = uTargetSurfacePitch; soft_billboard.uViewportX = pBLVRenderParams->uViewportX; soft_billboard.uViewportY = pBLVRenderParams->uViewportY; soft_billboard.uViewportZ = pBLVRenderParams->uViewportZ - 1; soft_billboard.uViewportW = pBLVRenderParams->uViewportW; pODMRenderParams->uNumBillboards = ::uNumBillboardsToDraw; for (uint i = 0; i < ::uNumBillboardsToDraw; ++i) { RenderBillboard* p = &pBillboardRenderList[i]; soft_billboard.uScreenSpaceX = p->uScreenSpaceX; soft_billboard.sParentBillboardID = i; soft_billboard.uScreenSpaceY = p->uScreenSpaceY; soft_billboard._screenspace_x_scaler_packedfloat = p->_screenspace_x_scaler_packedfloat; soft_billboard._screenspace_y_scaler_packedfloat = p->_screenspace_y_scaler_packedfloat; soft_billboard.sZValue = p->sZValue; soft_billboard.uFlags = p->field_1E; soft_billboard.sTintColor = p->sTintColor; if ( p->HwSpriteID != -1 ) { if ( pRenderD3D ) DrawBillboard_Indoor(&soft_billboard, &pSprites_LOD->pHardwareSprites[p->HwSpriteID], p->dimming_level); else { soft_billboard.pPalette = PaletteManager::Get_Dark_or_Red_LUT(p->uPalette, p->dimming_level, 1); if (p->field_1E & 0x0100) soft_billboard.pPalette = pPaletteManager->field_261600[p->uPalette]; if ( !(soft_billboard.uFlags & 0x40) && soft_billboard.uFlags & 0x80 ) soft_billboard.pPalette2 = PaletteManager::Get_Dark_or_Red_LUT(p->uPalette, 0, 1); if ( p->HwSpriteID >= 0 ) pSprites_LOD->pSpriteHeaders[p->HwSpriteID].DrawSprite_sw(&soft_billboard, 1); } } } } //----- (004A16A5) -------------------------------------------------------- bool Render::AreRenderSurfacesOk() { return pFrontBuffer4 && pBackBuffer4; } //----- (004A19D8) -------------------------------------------------------- unsigned int BlendColors(unsigned int a1, unsigned int a2) { /*signed __int64 v2; // ST10_8@1 double v3; // st7@1 float v4; // ST24_4@1 double v5; // ST10_8@1 int v6; // ST1C_4@1 float v7; // ST24_4@1 double v8; // ST10_8@1 unsigned __int8 v9; // ST20_1@1 float v10; // ST24_4@1 double v11; // ST10_8@1 float v12; // ST24_4@1 double v13; // ST08_8@1*/ uint alpha = (uint)floorf(0.5f + (a1 >> 24) / 255.0f * (a2 >> 24) / 255.0f * 255.0f), red = (uint)floorf(0.5f + ((a1 >> 16) & 0xFF) / 255.0f * ((a2 >> 16) & 0xFF) / 255.0f * 255.0f), green = (uint)floorf(0.5f + ((a1 >> 8) & 0xFF) / 255.0f * ((a2 >> 8) & 0xFF) / 255.0f * 255.0f), blue = (uint)floorf(0.5f + ((a1 >> 0) & 0xFF) / 255.0f * ((a2 >> 0) & 0xFF) / 255.0f * 255.0f); return (alpha << 24) | (red << 16) | (green << 8) | blue; /*v2 = a1 >> 24; v3 = (double)v2 / 255.0f; HIDWORD(v2) = 0; LODWORD(v2) = a2 >> 24; v4 = v3 * (double)v2 / 255.0f * 255.0; v5 = v4 + 6.7553994e15; v6 = LODWORD(v5); v7 = (double)((a1 >> 16) & 0xFFi64) / 255.0f * (double)((a2 >> 16) & 0xFF) * 0.0039215689 * 255.0; v8 = v7 + 6.7553994e15; v9 = LOBYTE(v8); v10 = (double)((unsigned __int16)a1 >> 8) / 255.0f * (double)((unsigned __int16)a2 >> 8) / 255.0f * 255.0; v11 = v10 + 6.7553994e15; v12 = (double)(a1 & 0xFFi64) / 255.0f * (double)(unsigned __int8)a2 / 255.0f * 255.0; v13 = v12 + 6.7553994e15; return LOBYTE(v13) | ((LOBYTE(v11) | (((v6 << 8) | v9) << 8)) << 8);*/ } void Render::RenderTerrainD3D() // New function { int v6; // ecx@8 struct Polygon *pTilePolygon; // ebx@8 float Light_tile_dist; //warning: the game uses CW culling by default, ccw is incosistent pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CCW); static RenderVertexSoft pTerrainVertices[128 * 128];//vertexCountX and vertexCountZ //Генерация местоположения вершин------------------------------------------------------------------------- //решётка вершин делится на две части от -64 до 0 и от 0 до 64 // // -64 X 0 64 // --------------- 64 // | | | // | | | // | | | // 0|------+------| Z // | | | // | | | // | | | // --------------- // -64 int blockScale = 512; int heightScale = 32; for (unsigned int z = 0; z < 128; ++z) { for (unsigned int x = 0; x < 128; ++x) { pTerrainVertices[z * 128 + x].vWorldPosition.x = (-64 + (signed)x) * blockScale; pTerrainVertices[z * 128 + x].vWorldPosition.y = (64 - (signed)z) * blockScale; pTerrainVertices[z * 128 + x].vWorldPosition.z = heightScale * pOutdoor->pTerrain.pHeightmap[z * 128 + x]; pGame->pIndoorCameraD3D->ViewTransform(&pTerrainVertices[z * 128 + x], 1); pGame->pIndoorCameraD3D->Project(&pTerrainVertices[z * 128 + x], 1, 0); } } //-------(Отсечение невидимой части карты)------------------------------------------------------------------------------------------ float direction = (float)(pGame->pIndoorCameraD3D->sRotationY / 256);//direction of the camera(напрвление камеры) //0-East(B) //1-NorthEast(CB) //2-North(C) //3-WestNorth(CЗ) //4-West(З) //5-SouthWest(ЮЗ) //6-South(Ю) //7-SouthEast(ЮВ) unsigned int Start_X, End_X, Start_Z, End_Z; if ( direction >= 0 && direction < 1.0 )//East(B) - NorthEast(CB) { Start_X = pODMRenderParams->uMapGridCellX - 2, End_X = 127; Start_Z = 0, End_Z = 127; } else if (direction >= 1.0 && direction < 3.0)//NorthEast(CB) - WestNorth(CЗ) { Start_X = 0, End_X = 127; Start_Z = 0, End_Z = pODMRenderParams->uMapGridCellZ + 1; } else if (direction >= 3.0 && direction < 5.0)//WestNorth(CЗ) - SouthWest(ЮЗ) { Start_X = 0, End_X = pODMRenderParams->uMapGridCellX + 2; Start_Z = 0, End_Z = 127; } else if ( direction >= 5.0 && direction < 7.0 )//SouthWest(ЮЗ) - //SouthEast(ЮВ) { Start_X = 0, End_X = 127; Start_Z = pODMRenderParams->uMapGridCellZ - 2, End_Z = 127; } else//SouthEast(ЮВ) - East(B) { Start_X = pODMRenderParams->uMapGridCellX - 2, End_X = 127; Start_Z = 0, End_Z = 127; } for (unsigned int z = Start_Z; z < End_Z; ++z) { for (unsigned int x = Start_X; x < End_X; ++x) { pTilePolygon = &array_77EC08[pODMRenderParams->uNumPolygons]; pTilePolygon->flags = 0; pTilePolygon->field_32 = 0; pTilePolygon->uTileBitmapID = pOutdoor->DoGetTileTexture(x, z); pTilePolygon->pTexture = (Texture *)&pBitmaps_LOD->pHardwareTextures[pTilePolygon->uTileBitmapID]; if (pTilePolygon->uTileBitmapID == 0xFFFF) continue; //pTile->flags = 0x8010 |pOutdoor->GetSomeOtherTileInfo(x, z); pTilePolygon->flags = pOutdoor->GetSomeOtherTileInfo(x, z); pTilePolygon->field_32 = 0; pTilePolygon->field_59 = 1; pTilePolygon->sTextureDeltaU = 0; pTilePolygon->sTextureDeltaV = 0; // x,z x+1,z // .____________. // | | // | | // | | // | | // | | // .____________. // x,z+1 x+1,z+1 memcpy(&array_73D150[0], &pTerrainVertices[z * 128 + x], sizeof(RenderVertexSoft));//x, z array_73D150[0].u = 0; array_73D150[0].v = 0; memcpy(&array_73D150[1], &pTerrainVertices[z * 128 + x + 1], sizeof(RenderVertexSoft));//x + 1, z array_73D150[1].u = 1; array_73D150[1].v = 0; memcpy(&array_73D150[2], &pTerrainVertices[(z + 1) * 128 + x + 1], sizeof(RenderVertexSoft));//x + 1, z + 1 array_73D150[2].u = 1; array_73D150[2].v = 1; memcpy(&array_73D150[3], &pTerrainVertices[(z + 1) * 128 + x], sizeof(RenderVertexSoft));//x, z + 1 array_73D150[3].u = 0; array_73D150[3].v = 1; //v58 = 0; //if (v58 == 4) // if all y == first y; primitive in xz plane //pTile->field_32 |= 0x0001; pTilePolygon->pODMFace = nullptr; pTilePolygon->uNumVertices = 4; pTilePolygon->field_59 = 5; //shading (затенение)---------------------------------------------------------------------------- //uint norm_idx = pTerrainNormalIndices[2 * (z * 128 + x) + 1]; uint norm_idx = pTerrainNormalIndices[2 * (x * 128 + z) + 2]; assert(norm_idx < uNumTerrainNormals); Vec3_float_* norm = &pTerrainNormals[norm_idx]; float _f = ((norm->x * (float)pOutdoor->vSunlight.x / 65536.0) - (norm->y * (float)pOutdoor->vSunlight.y / 65536.0) - (norm->z * (float)pOutdoor->vSunlight.z / 65536.0)); pTilePolygon->dimming_level = 20.0 - floorf(20.0 * _f + 0.5f); if ( norm_idx < 0 || norm_idx > uNumTerrainNormals - 1 ) norm = 0; else norm = &pTerrainNormals[norm_idx]; if (for_refactoring) { MessageBoxA(nullptr, "Ritor1: function StackLights_TerrainFace needed refactoring and result - slows", "", 0); __debugbreak(); } //pGame->pLightmapBuilder->StackLights_TerrainFace(norm, &Light_tile_dist, array_50AC10, 4, 1);//Ritor1: slows //pDecalBuilder->_49BE8A(pTilePolygon, norm, &Light_tile_dist, array_50AC10, 4, 1); //unsigned int a5 = 4; //---------------------------------------------------------------------------- ++pODMRenderParams->uNumPolygons; ++pODMRenderParams->field_44; assert(pODMRenderParams->uNumPolygons < 20000); pTilePolygon->uBModelID = 0; pTilePolygon->uBModelFaceID = 0; pTilePolygon->field_50 = (8 * (0 | (0 << 6))) | 6; for (unsigned int k = 0; k < pTilePolygon->uNumVertices; ++k) { memcpy(&array_50AC10[k], &array_73D150[k], sizeof(struct RenderVertexSoft)); array_50AC10[k]._rhw = 1.0 / (array_73D150[k].vWorldViewPosition.x + 0.0000001000000011686097); } //---------Draw distance(Дальность отрисовки)------------------------------- int temp = pODMRenderParams->shading_dist_mist; if ( draw_terrain_dist_mist ) pODMRenderParams->shading_dist_mist = 0x5000; bool neer_clip = array_73D150[0].vWorldViewPosition.x < 8.0 || array_73D150[1].vWorldViewPosition.x < 8.0 || array_73D150[2].vWorldViewPosition.x < 8.0 || array_73D150[3].vWorldViewPosition.x < 8.0; bool far_clip = (double)pODMRenderParams->shading_dist_mist < array_73D150[0].vWorldViewPosition.x || (double)pODMRenderParams->shading_dist_mist < array_73D150[1].vWorldViewPosition.x || (double)pODMRenderParams->shading_dist_mist < array_73D150[2].vWorldViewPosition.x || (double)pODMRenderParams->shading_dist_mist < array_73D150[3].vWorldViewPosition.x; /* int v33 = 0; static stru154 static_sub_0048034E_stru_154; pGame->pLightmapBuilder->std__vector_000004_size = 0; if ( stru_F8AD28.uNumLightsApplied > 0 || pDecalBuilder->uNumDecals > 0 ) { if ( neer_clip ) v33 = 3; else v33 = far_clip != 0 ? 5 : 0; static_sub_0048034E_stru_154.ClassifyPolygon(norm, Light_tile_dist); if ( pDecalBuilder->uNumDecals > 0 ) pDecalBuilder->ApplyDecals(31 - pTilePolygon->dimming_level, 4, &static_sub_0048034E_stru_154, a5, array_50AC10, 0, *(float *)&v33, -1); } if ( stru_F8AD28.uNumLightsApplied > 0 ) pGame->pLightmapBuilder->ApplyLights(&stru_F8AD28, &static_sub_0048034E_stru_154, a5, array_50AC10, 0, v33);*/ if ( !byte_4D864C || ~pGame->uFlags & 0x80 ) { //if ( neer_clip ) //Ritor1: Даёт искажения на подъёме, возможно требуется ф-ция Безье //{ // pTilePolygon->uNumVertices = ODM_NearClip(pTilePolygon->uNumVertices); // ODM_Project(pTilePolygon->uNumVertices); //} if ( far_clip ) { pTilePolygon->uNumVertices = ODM_FarClip(pTilePolygon->uNumVertices); ODM_Project(pTilePolygon->uNumVertices); } } pODMRenderParams->shading_dist_mist = temp; // check the transparency and texture (tiles) mapping (проверка прозрачности и наложение текстур (тайлов))---------------------- bool transparent = false; if ( !( pTilePolygon->flags & 1 ) ) // не поддерживается TextureFrameTable { if ( /*pTile->flags & 2 && */pTilePolygon->uTileBitmapID == pRenderer->hd_water_tile_id) { //transparent = false; v6 = pRenderer->pHDWaterBitmapIDs[pRenderer->hd_water_current_frame]; } else { v6 = pTilePolygon->uTileBitmapID; if ( !_strnicmp(pBitmaps_LOD->pTextures[pTilePolygon->uTileBitmapID].pName, "wtrdr", 5) ) transparent = true; } assert(v6 < 1000); // many random crashes here // for all shore tiles - draw a tile water under them since they're half-empty if (!_strnicmp(pBitmaps_LOD->pTextures[pTilePolygon->uTileBitmapID].pName, "wtrdr", 5)) // all shore tile filenames are wtrdrXXX DrawBorderTiles(pTilePolygon); pRenderer->DrawTerrainPolygon(pTilePolygon->uNumVertices, pTilePolygon, pBitmaps_LOD->pHardwareTextures[v6], transparent, true); } //else //здесь уже пограничные тайлы воды //pTile->DrawBorderTiles(); //-------------------------------------------------------------------------------------------------------------------------------- --pODMRenderParams->uNumPolygons; --pODMRenderParams->field_44; } } } //----- (004811A3) -------------------------------------------------------- void Render::DrawBorderTiles(struct Polygon *poly) { pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false); DrawTerrainPolygon(poly->uNumVertices, poly, pBitmaps_LOD->pHardwareTextures[pHDWaterBitmapIDs[hd_water_current_frame]], false, true); pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, true); //DrawTerrainPolygon(poly->uNumVertices, poly, pBitmaps_LOD->pHardwareTextures[poly->uTileBitmapID], true, true); } //----- (0047BACF) -------------------------------------------------------- void Render::TransformBillboardsAndSetPalettesODM() { //int v0; // edi@1 //char *v1; // esi@2 //unsigned int v2; // edx@3 //int v3; // eax@3 //int v4; // edi@3 //int v5; // eax@3 //__int16 v6; // di@3 //int v7; // eax@3 //int v8; // ebx@4 // unsigned __int16 *v9; // eax@7 // char v10; // zf@9 //DWORD v11; // eax@13 // int v12; // eax@13 // int v13; // eax@14 RenderBillboardTransform_local0 billboard; // [sp+4h] [bp-60h]@1 // int v15; // [sp+54h] [bp-10h]@13 //int v16; // [sp+58h] [bp-Ch]@1 //int v17; // [sp+5Ch] [bp-8h]@2 // int v18; // [sp+60h] [bp-4h]@13 billboard.sParentBillboardID = -1; billboard.pTarget = pRenderer->pTargetSurface; billboard.pTargetZ = pRenderer->pActiveZBuffer; billboard.uTargetPitch = pRenderer->uTargetSurfacePitch; billboard.uViewportX = pViewport->uViewportTL_X; billboard.uViewportY = pViewport->uViewportTL_Y; billboard.uViewportZ = pViewport->uViewportBR_X - 1; billboard.uViewportW = pViewport->uViewportBR_Y; pODMRenderParams->uNumBillboards = uNumBillboardsToDraw; for (unsigned int i = 0; i < ::uNumBillboardsToDraw; ++i) { billboard.uScreenSpaceX = pBillboardRenderList[i].uScreenSpaceX; billboard.uScreenSpaceY = pBillboardRenderList[i].uScreenSpaceY; billboard.sParentBillboardID = i; billboard._screenspace_x_scaler_packedfloat = pBillboardRenderList[i]._screenspace_x_scaler_packedfloat; billboard.sTintColor = pBillboardRenderList[i].sTintColor; billboard._screenspace_y_scaler_packedfloat = pBillboardRenderList[i]._screenspace_y_scaler_packedfloat; billboard.sZValue = pBillboardRenderList[i].sZValue; billboard.uFlags = pBillboardRenderList[i].field_1E; if (pBillboardRenderList[i].HwSpriteID != -1) { if (!pRenderD3D) __debugbreak(); // no sw rendering //if (pRenderer->pRenderD3D) TransformBillboard(&billboard, &pSprites_LOD->pHardwareSprites[pBillboardRenderList[i].HwSpriteID], pBillboardRenderList[i].dimming_level, &pBillboardRenderList[i]); /*else { assert(false); auto v1 = (char *)&pBillboard->uScreenSpaceY; if ( *(v1 - 10) & 2 ) v9 = PaletteManager::Get_Dark_or_Red_LUT(*((short *)v1 - 7), 0, 1); else v9 = sr_GetBillboardPalette((RenderBillboard *)(v1 - 40), *((short *)v1 - 7), pBillboard->sZValue, *((short *)v1 + 1)); v10 = (*(v1 - 9) & 1) == 0; billboard.pPalette = v9; if ( !v10 ) billboard.pPalette = pPaletteManager->field_261600[*((short *)v1 - 7)]; if ( !(billboard.uFlags & 0x40) && billboard.uFlags & 0x80 ) { v12 = stru_5C6E00->Cos(i * 5 + GetTickCount()); v15 = abs(v12); v18 = (unsigned __int64)(15i64 * v15) >> 16; billboard.pPalette2 = PaletteManager::Get_Dark_or_Red_LUT(*((short *)v1 - 7), 15 - v18, 1); } v13 = *((short *)v1 - 8); if ( v13 >= 0 ) pSprites_LOD->pSpriteHeaders[v13].DrawSprite_sw(&billboard, 1); }*/ } } } //----- (0047AF11) -------------------------------------------------------- void Render::DrawSpriteObjects_ODM() { SpriteFrame *frame; // eax@10 unsigned int v6; // eax@10 int v9; // ecx@10 int v17; // ecx@25 int v18; // eax@25 // int v22; // ST3C_4@29 signed __int64 v23; // qtt@30 int v26; // eax@31 // char v27; // zf@31 int v30; // [sp+14h] [bp-2Ch]@23 int v37; // [sp+1Ch] [bp-24h]@23 int a6; // [sp+20h] [bp-20h]@10 int v42; // [sp+2Ch] [bp-14h]@23 int y; // [sp+30h] [bp-10h]@10 int x; // [sp+34h] [bp-Ch]@10 int z; // [sp+38h] [bp-8h]@10 signed __int16 v46; // [sp+3Ch] [bp-4h]@12 //v41 = 0; for (unsigned int i = 0; i < uNumSpriteObjects; ++i) { SpriteObject* object = &pSpriteObjects[i]; //auto v0 = (char *)&pSpriteObjects[i].uSectorID; //v0 = (char *)&pSpriteObjects[0].uSectorID; //do //{ if (!object->uObjectDescID) // item probably pciked up continue; assert(object->uObjectDescID < pObjectList->uNumObjects); ObjectDesc* object_desc = &pObjectList->pObjects[object->uObjectDescID]; if (object_desc->NoSprite()) continue; //v1 = &pObjectList->pObjects[*((short *)v0 - 13)]; //if ( !(v1->uFlags & 1) ) //{ //v2 = *((short *)v0 - 14) //v2 = object->uType; if ( (object->uType < 1000 || object->uType >= 10000) && (object->uType < 500 || object->uType >= 600) || pGame->pStru6Instance->_4A81CA(object) ) { //a5 = *(short *)v0; x = object->vPosition.x; y = object->vPosition.y; z = object->vPosition.z; frame = pSpriteFrameTable->GetFrame(object_desc->uSpriteID, object->uSpriteFrameID); a6 = frame->uGlowRadius * object->field_22_glow_radius_multiplier; v6 = stru_5C6E00->Atan2(object->vPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x, object->vPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y); //LOWORD(v7) = object->uFacing; //v8 = v36; v9 = ((signed int)(stru_5C6E00->uIntegerPi + ((signed int)stru_5C6E00->uIntegerPi >> 3) + object->uFacing - v6) >> 8) & 7; pBillboardRenderList[::uNumBillboardsToDraw].HwSpriteID = frame->pHwSpriteIDs[v9]; if ( frame->uFlags & 0x20 ) { //v8 = v36; z -= fixpoint_mul(frame->scale, pSprites_LOD->pSpriteHeaders[(signed __int16)frame->pHwSpriteIDs[v9]].uHeight) / 2; } v46 = 0; if ( frame->uFlags & 2 ) v46 = 2; //v11 = (int *)(256 << v9); if ( (256 << v9) & frame->uFlags ) v46 |= 4; if ( frame->uFlags & 0x40000 ) v46 |= 0x40; if ( frame->uFlags & 0x20000 ) LOBYTE(v46) = v46 | 0x80; if ( a6 ) { //LOBYTE(v11) = _4E94D3_light_type; pMobileLightsStack->AddLight(x, y, z, object->uSectorID, a6, 0xFF, 0xFF, 0xFF, _4E94D3_light_type); } if (pGame->pIndoorCameraD3D->sRotationX) { v30 = fixpoint_mul((x - pGame->pIndoorCameraD3D->vPartyPos.x) << 16, pGame->pIndoorCameraD3D->int_cosine_y) + fixpoint_mul((y - pGame->pIndoorCameraD3D->vPartyPos.y) << 16, pGame->pIndoorCameraD3D->int_sine_y); v37 = fixpoint_mul((x - pGame->pIndoorCameraD3D->vPartyPos.x) << 16, pGame->pIndoorCameraD3D->int_sine_y); v42 = fixpoint_mul((z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16, pGame->pIndoorCameraD3D->int_sine_x) + fixpoint_mul(v30, pGame->pIndoorCameraD3D->int_cosine_x); if ( v42 >= 0x40000 && v42 <= pODMRenderParams->shading_dist_mist << 16 ) { v17 = fixpoint_mul((y - pGame->pIndoorCameraD3D->vPartyPos.y) << 16, pGame->pIndoorCameraD3D->int_cosine_y) - v37; v18 = fixpoint_mul((z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16, pGame->pIndoorCameraD3D->int_cosine_x) - fixpoint_mul(v30, pGame->pIndoorCameraD3D->int_sine_x); if ( abs(v42) >= abs(v17) ) { LODWORD(v23) = 0; HIDWORD(v23) = SLOWORD(pODMRenderParams->int_fov_rad); object->uAttributes |= 1; pBillboardRenderList[::uNumBillboardsToDraw].uPalette = frame->uPaletteIndex; pBillboardRenderList[::uNumBillboardsToDraw].uIndoorSectorID = object->uSectorID; pBillboardRenderList[::uNumBillboardsToDraw]._screenspace_x_scaler_packedfloat = fixpoint_mul(frame->scale, v23 / v42); pBillboardRenderList[::uNumBillboardsToDraw].pSpriteFrame = frame; pBillboardRenderList[::uNumBillboardsToDraw]._screenspace_y_scaler_packedfloat = fixpoint_mul(frame->scale, v23 / v42); pBillboardRenderList[::uNumBillboardsToDraw].field_1E = v46; pBillboardRenderList[::uNumBillboardsToDraw].world_x = x; pBillboardRenderList[::uNumBillboardsToDraw].world_y = y; pBillboardRenderList[::uNumBillboardsToDraw].world_z = z; pBillboardRenderList[::uNumBillboardsToDraw].uScreenSpaceX = pViewport->uScreenCenterX - ((signed int)(fixpoint_mul(v23 / v42, v17) + 0x8000) >> 16); pBillboardRenderList[::uNumBillboardsToDraw].uScreenSpaceY = pViewport->uScreenCenterY - (((unsigned int)fixpoint_mul(v23 / v42, v18) + 0x8000) >> 16); HIWORD(v26) = HIWORD(v42); LOWORD(v26) = 0; pBillboardRenderList[::uNumBillboardsToDraw].sZValue = v26 + (PID(OBJECT_Item,i)); pBillboardRenderList[::uNumBillboardsToDraw].dimming_level = 0; pBillboardRenderList[::uNumBillboardsToDraw].sTintColor = 0; if ( !(object->uAttributes & 0x20) ) { if ( !pRenderD3D ) { __debugbreak(); pBillboardRenderList[::uNumBillboardsToDraw].sZValue = 0; } } //if (::uNumBillboardsToDraw >= 500) // return; assert(::uNumBillboardsToDraw < 500); ++::uNumBillboardsToDraw; ++uNumSpritesDrawnThisFrame; } } } else { v42 = fixpoint_mul((y - pGame->pIndoorCameraD3D->vPartyPos.y) << 16, pGame->pIndoorCameraD3D->int_sine_y) + fixpoint_mul((x - pGame->pIndoorCameraD3D->vPartyPos.x) << 16, pGame->pIndoorCameraD3D->int_cosine_y); if ( v42 >= 0x40000 && v42 <= pODMRenderParams->shading_dist_mist << 16 ) { v17 = fixpoint_mul((y - pGame->pIndoorCameraD3D->vPartyPos.y) << 16, pGame->pIndoorCameraD3D->int_cosine_y) - fixpoint_mul(((x - pGame->pIndoorCameraD3D->vPartyPos.x) << 16), pGame->pIndoorCameraD3D->int_sine_y); v18 = (z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16; if ( abs(v42) >= abs(v17) ) { LODWORD(v23) = 0; HIDWORD(v23) = SLOWORD(pODMRenderParams->int_fov_rad); object->uAttributes |= 1; pBillboardRenderList[::uNumBillboardsToDraw].uPalette = frame->uPaletteIndex; pBillboardRenderList[::uNumBillboardsToDraw].uIndoorSectorID = object->uSectorID; pBillboardRenderList[::uNumBillboardsToDraw]._screenspace_x_scaler_packedfloat = fixpoint_mul(frame->scale, v23 / v42); pBillboardRenderList[::uNumBillboardsToDraw].pSpriteFrame = frame; pBillboardRenderList[::uNumBillboardsToDraw]._screenspace_y_scaler_packedfloat = fixpoint_mul(frame->scale, v23 / v42); pBillboardRenderList[::uNumBillboardsToDraw].field_1E = v46; pBillboardRenderList[::uNumBillboardsToDraw].world_x = x; pBillboardRenderList[::uNumBillboardsToDraw].world_y = y; pBillboardRenderList[::uNumBillboardsToDraw].world_z = z; pBillboardRenderList[::uNumBillboardsToDraw].uScreenSpaceX = pViewport->uScreenCenterX - ((signed int)(fixpoint_mul(v23 / v42, v17) + 0x8000) >> 16); pBillboardRenderList[::uNumBillboardsToDraw].uScreenSpaceY = pViewport->uScreenCenterY - (((unsigned int)fixpoint_mul(v23 / v42, v18) + 0x8000) >> 16); HIWORD(v26) = HIWORD(v42); LOWORD(v26) = 0; pBillboardRenderList[::uNumBillboardsToDraw].sZValue = v26 + (PID(OBJECT_Item,i)); pBillboardRenderList[::uNumBillboardsToDraw].dimming_level = 0; pBillboardRenderList[::uNumBillboardsToDraw].sTintColor = 0; if ( !(object->uAttributes & 0x20) ) { if ( !pRenderD3D ) { __debugbreak(); pBillboardRenderList[::uNumBillboardsToDraw].sZValue = 0; } } //if (::uNumBillboardsToDraw >= 500) // return; assert(::uNumBillboardsToDraw < 500); ++::uNumBillboardsToDraw; ++uNumSpritesDrawnThisFrame; } } } } } } //----- (0049D9BC) -------------------------------------------------------- signed int __stdcall RenderD3D__DeviceEnumerator(GUID *lpGUID, const char *lpDevDesc, const char *lpDriverName, RenderD3D__DevInfo *pOut) { size_t v4; // eax@1 size_t v5; // eax@1 size_t v7; // eax@13 DDDEVICEIDENTIFIER ddDevId; // [sp+4h] [bp-4F8h]@11 DDSURFACEDESC2 v10;/*int v10; // [sp+42Ch] [bp-D0h]@16*/ DDSCAPS2 ddsCaps; // [sp+4A8h] [bp-54h]@14 unsigned int uFreeVideoMem; // [sp+4B8h] [bp-44h]@14 RenderD3D_aux aux; // [sp+4BCh] [bp-40h]@19 IDirect3D3 *pDirect3D3; // [sp+4C4h] [bp-38h]@18 int is_there_a_compatible_screen_mode; // [sp+4C8h] [bp-34h]@16 RenderD3D_D3DDevDesc v20; // [sp+4CCh] [bp-30h]@1 LPDIRECTDRAW pDirectDraw = nullptr; // [sp+4F4h] [bp-8h]@4 IDirectDraw4 *pDirectDraw4; // [sp+4F8h] [bp-4h]@7 v4 = strlen(lpDriverName); v20.pDriverName = new char[v4 + 1]; v5 = strlen(lpDevDesc); v20.pDeviceDesc = new char[v5 + 1]; strcpy(v20.pDriverName, lpDriverName); strcpy(v20.pDeviceDesc, lpDevDesc); if ( lpGUID ) { v20.pGUID = new GUID; memcpy(v20.pGUID, lpGUID, 0x10); } else v20.pGUID = 0; if (FAILED(DirectDrawCreate(v20.pGUID, &pDirectDraw, 0))) { delete [] v20.pDriverName; delete [] v20.pDeviceDesc; delete v20.pGUID; } else { if (FAILED(pDirectDraw->QueryInterface(IID_IDirectDraw4, (LPVOID *)&pDirectDraw4))) { delete [] v20.pDriverName; delete [] v20.pDeviceDesc; delete v20.pGUID; pDirectDraw->Release(); } else { pDirectDraw->Release(); if (FAILED( pDirectDraw4->GetDeviceIdentifier(&ddDevId, 1))) v20.pDDraw4DevDesc = 0; else { v7 = strlen(ddDevId.szDescription); v20.pDDraw4DevDesc = new char[v7 + 1]; strcpy(v20.pDDraw4DevDesc, ddDevId.szDescription); } memset(&ddsCaps, 0, sizeof(ddsCaps)); if (FAILED(pDirectDraw4->GetAvailableVidMem(&ddsCaps, (LPDWORD)&v20.uVideoMem, (LPDWORD)&uFreeVideoMem))) v20.uVideoMem = 0; memset(&v10, 0, sizeof(v10)); v10.dwSize = 124; v10.dwFlags = 6; v10.dwHeight = window->GetWidth(); v10.dwWidth = window->GetHeight(); v10.ddpfPixelFormat.dwSize = 32; is_there_a_compatible_screen_mode = false; if ( FAILED(pDirectDraw4->EnumDisplayModes(0, 0, &is_there_a_compatible_screen_mode, (LPDDENUMMODESCALLBACK2)DDrawDisplayModesEnumerator)) || !is_there_a_compatible_screen_mode || FAILED(pDirectDraw4->QueryInterface(IID_IDirect3D3, (LPVOID *)&pDirect3D3))) { delete [] v20.pDriverName; delete [] v20.pDeviceDesc; //free(v20.pDDraw4DevDesc); delete [] v20.pDDraw4DevDesc; delete v20.pGUID; pDirectDraw4->Release(); } else { aux.pInfo = pOut; aux.ptr_4 = &v20; pDirect3D3->EnumDevices((LPD3DENUMDEVICESCALLBACK)D3DDeviceEnumerator, &aux); delete [] v20.pDriverName; delete [] v20.pDeviceDesc; delete [] v20.pDDraw4DevDesc; delete v20.pGUID; pDirectDraw4->Release(); pDirectDraw4 = 0; pDirect3D3->Release(); } } } return 1; } //----- (0049D784) -------------------------------------------------------- HRESULT __stdcall D3DDeviceEnumerator(const GUID *lpGUID, const char *lpDeviceDesc, const char *lpDeviceName, D3DDEVICEDESC *pHWDesc, D3DDEVICEDESC *pSWDesc, RenderD3D_aux *a6) { signed int v7; // edi@1 v7 = -1; if ( pHWDesc->dwFlags ) { if ( !a6->ptr_4->pGUID ) v7 = 0; if ( pHWDesc->dwFlags && a6->ptr_4->pGUID ) v7 = 1; } if ( !strcmp(lpDeviceName, "RGB Emulation") && !a6->ptr_4->pGUID ) v7 = 2; if ( !strcmp(lpDeviceName, "Reference Rasterizer") && !a6->ptr_4->pGUID ) v7 = 3; if ( v7 != -1 ) { a6->pInfo[v7].bIsDeviceCompatible = 1; a6->pInfo[v7].uCaps = 0; if ( !(pHWDesc->dpcTriCaps.dwSrcBlendCaps & 0x10) ) a6->pInfo[v7].uCaps |= 2; if ( !(pHWDesc->dpcTriCaps.dwSrcBlendCaps & 2) ) a6->pInfo[v7].uCaps |= 4; if ( !(pHWDesc->dpcTriCaps.dwSrcBlendCaps & 1) ) a6->pInfo[v7].uCaps |= 8; if ( !(pHWDesc->dpcTriCaps.dwDestBlendCaps & 0x20) ) a6->pInfo[v7].uCaps |= 16; if ( !(pHWDesc->dpcTriCaps.dwDestBlendCaps & 2) ) a6->pInfo[v7].uCaps |= 32; if ( !(pHWDesc->dpcTriCaps.dwDestBlendCaps & 4) ) a6->pInfo[v7].uCaps |= 64; if ( !(BYTE1(pHWDesc->dwDevCaps) & 0x10) ) BYTE1(a6->pInfo[v7].uCaps) |= 1; if ( pHWDesc->dpcTriCaps.dwTextureCaps & 0x20 ) LOBYTE(a6->pInfo[v7].uCaps) |= 0x80; a6->pInfo[v7].pName = new char[strlen(lpDeviceName) + 1]; strcpy(a6->pInfo[v7].pName, lpDeviceName); a6->pInfo[v7].pDescription = new char[strlen(lpDeviceDesc) + 1]; strcpy(a6->pInfo[v7].pDescription, lpDeviceDesc); a6->pInfo[v7].pGUID = new GUID; memcpy(a6->pInfo[v7].pGUID, lpGUID, 0x10); a6->pInfo[v7].pDriverName = new char[strlen(a6->ptr_4->pDriverName) + 1]; strcpy(a6->pInfo[v7].pDriverName, a6->ptr_4->pDriverName); a6->pInfo[v7].pDeviceDesc = new char[strlen(a6->ptr_4->pDeviceDesc) + 1]; strcpy(a6->pInfo[v7].pDeviceDesc, a6->ptr_4->pDeviceDesc); a6->pInfo[v7].pDDraw4DevDesc = new char[strlen(a6->ptr_4->pDDraw4DevDesc) + 1]; strcpy(a6->pInfo[v7].pDDraw4DevDesc, a6->ptr_4->pDDraw4DevDesc); if ( a6->ptr_4->pGUID ) { a6->pInfo[v7].pDirectDrawGUID = new GUID; memcpy(a6->pInfo[v7].pDirectDrawGUID, a6->ptr_4->pGUID, 0x10); } else a6->pInfo[v7].pDirectDrawGUID = 0; a6->pInfo[v7].uVideoMem = a6->ptr_4->uVideoMem; } return 1; } //----- (0049D75C) -------------------------------------------------------- HRESULT __stdcall DDrawDisplayModesEnumerator(DDSURFACEDESC2 *pSurfaceDesc, __int16 *found_compatible_mode) { if ( pSurfaceDesc->ddsCaps.dwCaps | DDSCAPS_3DDEVICE /*&& pSurfaceDesc->ddpfPixelFormat.dwRGBBitCount == 16*/ ) { *found_compatible_mode = 1; return S_OK; } return 1; } //----- (0047A95E) -------------------------------------------------------- void Render::PrepareDecorationsRenderList_ODM() { unsigned int v6; // edi@9 int v7; // eax@9 SpriteFrame *v8; // eax@9 unsigned __int16 *v10; // eax@9 int v13; // ecx@9 int v14; // ecx@20 char v15; // dl@20 signed int v16; // eax@20 int v17; // eax@23 int v18; // ecx@24 int v19; // eax@24 int v20; // ecx@24 int v21; // ebx@26 int v22; // eax@26 signed __int64 v24; // qtt@31 int v25; // ebx@31 __int16 v29; // cx@37 int v30; // ecx@37 int v31; // ebx@37 Particle_sw local_0; // [sp+Ch] [bp-98h]@7 unsigned __int16 *v37; // [sp+84h] [bp-20h]@9 int v38; // [sp+88h] [bp-1Ch]@9 int v40; // [sp+90h] [bp-14h]@24 int v41; // [sp+94h] [bp-10h]@24 int v42; // [sp+98h] [bp-Ch]@9 int b; // [sp+A0h] [bp-4h]@22 for (unsigned int i = 0; i < uNumLevelDecorations; ++i) { //LevelDecoration* decor = &pLevelDecorations[i]; if ((!(pLevelDecorations[i].uFlags & LEVEL_DECORATION_OBELISK_CHEST) || pLevelDecorations[i].IsObeliskChestActive()) && !(pLevelDecorations[i].uFlags & LEVEL_DECORATION_INVISIBLE)) { DecorationDesc* decor_desc = &pDecorationList->pDecorations[pLevelDecorations[i].uDecorationDescID]; if ( (char)decor_desc->uFlags >= 0 ) { if ( !(decor_desc->uFlags & 0x22) ) { v6 = pMiscTimer->uTotalGameTimeElapsed; v7 = abs(pLevelDecorations[i].vPosition.x + pLevelDecorations[i].vPosition.y); #pragma region "New: seasons change" extern bool change_seasons; if (change_seasons) switch (pParty->uCurrentMonth) { // case 531 (tree60), 536 (tree65), 537 (tree66) have no autumn/winter sprites case 11: case 0: case 1: // winter switch (decor_desc->uSpriteID) { //case 468: //bush02 grows on swamps, which are evergreeen actually case 548: // flower10 case 547: // flower09 case 541: // flower03 case 539: continue; // flower01 case 483: // tree01 case 486: // tree04 case 492: // tree10 pSpriteFrameTable->InitializeSprite(decor_desc->uSpriteID + 2); v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID + 2, v6 + v7); break; default: v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID, v6 + v7); } break; case 2: case 3: case 4: // spring switch (decor_desc->uSpriteID) { } v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID, v6 + v7); break; case 8: case 9: case 10: // autumn switch (decor_desc->uSpriteID) { //case 468: //bush02 grows on swamps, which are evergreeen actually case 548: // flower10 case 547: // flower09 case 541: // flower03 case 539: continue; // flower01 case 483: // tree01 case 486: // tree04 case 492: // tree10 pSpriteFrameTable->InitializeSprite(decor_desc->uSpriteID + 1); v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID + 1, v6 + v7); break; default: v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID, v6 + v7); } break; case 5: case 6: case 7: // summer //all green by default v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID, v6 + v7); break; default: assert(pParty->uCurrentMonth >= 0 && pParty->uCurrentMonth < 12); } else v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID, v6 + v7); #pragma endregion //v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID, v6 + v7); v10 = (unsigned __int16 *)stru_5C6E00->Atan2(pLevelDecorations[i].vPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x, pLevelDecorations[i].vPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y); v38 = 0; v13 = ((signed int)(stru_5C6E00->uIntegerPi + ((signed int)stru_5C6E00->uIntegerPi >> 3) + pLevelDecorations[i].field_10_y_rot - (signed int)v10) >> 8) & 7; v37 = (unsigned __int16 *)v13; if ( v8->uFlags & 2 ) v38 = 2; if ( (256 << v13) & v8->uFlags ) v38 |= 4; if ( v8->uFlags & 0x40000 ) v38 |= 0x40; if ( v8->uFlags & 0x20000 ) LOBYTE(v38) = v38 | 0x80; if ( v8->uGlowRadius ) { if ( pRenderD3D && bUseColoredLights ) { v14 = /*255;//*/decor_desc->uColoredLightRed; v15 = /*255;//*/decor_desc->uColoredLightGreen; v16 = /*255;//*/decor_desc->uColoredLightBlue; } else { v16 = 255; v14 = 255; v15 = 255; } pStationaryLightsStack->AddLight(pLevelDecorations[i].vPosition.x, pLevelDecorations[i].vPosition.y, pLevelDecorations[i].vPosition.z + decor_desc->uDecorationHeight / 2, v8->uGlowRadius, v14, v15, v16, _4E94D0_light_type); } v17 = (pLevelDecorations[i].vPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x) << 16; if (pGame->pIndoorCameraD3D->sRotationX) { v40 = (pLevelDecorations[i].vPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y) << 16; v18 = fixpoint_mul(v17, pGame->pIndoorCameraD3D->int_cosine_y) + fixpoint_mul(v40, pGame->pIndoorCameraD3D->int_sine_y); v41 = fixpoint_mul((pLevelDecorations[i].vPosition.z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16, pGame->pIndoorCameraD3D->int_sine_x); v19 = fixpoint_mul(v18, pGame->pIndoorCameraD3D->int_cosine_x); v20 = v19 + fixpoint_mul((pLevelDecorations[i].vPosition.z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16, pGame->pIndoorCameraD3D->int_sine_x); if ( v20 >= 0x40000 && v20 <= pODMRenderParams->shading_dist_mist << 16 ) { v21 = fixpoint_mul(v40, pGame->pIndoorCameraD3D->int_cosine_y) - fixpoint_mul(v17, pGame->pIndoorCameraD3D->int_sine_y); v22 = fixpoint_mul((pLevelDecorations[i].vPosition.z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16, pGame->pIndoorCameraD3D->int_cosine_x) - fixpoint_mul(v18, pGame->pIndoorCameraD3D->int_sine_x); if ( 2 * abs(v20) >= abs(v21) ) { LODWORD(v24) = 0; HIDWORD(v24) = SLOWORD(pODMRenderParams->int_fov_rad); v25 = pViewport->uScreenCenterX - ((signed int)(fixpoint_mul(v24 / v20, v21) + 0x8000) >> 16); v40 = pViewport->uScreenCenterY - ((signed int)(fixpoint_mul(v24 / v20, v22) + 0x8000) >> 16); v41 = fixpoint_mul(v8->scale, v24 / v20); if ( pRenderD3D ) b = fixpoint_mul(pSprites_LOD->pHardwareSprites[v8->pHwSpriteIDs[(int)v37]].uBufferWidth / 2, v41); else { __debugbreak(); b = fixpoint_mul(pSprites_LOD->pSpriteHeaders[v8->pHwSpriteIDs[(int)v37]].uWidth / 2, v41); } if ( b + v25 >= (signed int)pViewport->uViewportTL_X && v25 - b <= (signed int)pViewport->uViewportBR_X ) { if (::uNumBillboardsToDraw >= 500) return; pBillboardRenderList[::uNumBillboardsToDraw].HwSpriteID = v8->pHwSpriteIDs[(int)v37]; pBillboardRenderList[::uNumBillboardsToDraw]._screenspace_x_scaler_packedfloat = v41; pBillboardRenderList[::uNumBillboardsToDraw]._screenspace_y_scaler_packedfloat = v41; v29 = v38; pBillboardRenderList[::uNumBillboardsToDraw].uScreenSpaceX = v25; HIBYTE(v29) |= 2; pBillboardRenderList[::uNumBillboardsToDraw].uPalette = v8->uPaletteIndex; pBillboardRenderList[::uNumBillboardsToDraw].field_1E = v29; pBillboardRenderList[::uNumBillboardsToDraw].world_x = pLevelDecorations[i].vPosition.x; pBillboardRenderList[::uNumBillboardsToDraw].world_y = pLevelDecorations[i].vPosition.y; pBillboardRenderList[::uNumBillboardsToDraw].world_z = pLevelDecorations[i].vPosition.z; pBillboardRenderList[::uNumBillboardsToDraw].uScreenSpaceY = v40; HIWORD(v30) = HIWORD(v20); v31 = PID(OBJECT_Decoration,i); LOWORD(v30) = 0; pBillboardRenderList[::uNumBillboardsToDraw].uIndoorSectorID = 0; pBillboardRenderList[::uNumBillboardsToDraw].sZValue = v30 + v31; pBillboardRenderList[::uNumBillboardsToDraw].dimming_level = 0; pBillboardRenderList[::uNumBillboardsToDraw].pSpriteFrame = v8; pBillboardRenderList[::uNumBillboardsToDraw].sTintColor = 0; ::uNumBillboardsToDraw++; ++uNumDecorationsDrawnThisFrame; } } continue; } } else { v42 = (pLevelDecorations[i].vPosition.x - pGame->pIndoorCameraD3D->vPartyPos.x) << 16; v40 = (pLevelDecorations[i].vPosition.y - pGame->pIndoorCameraD3D->vPartyPos.y) << 16; v20 = fixpoint_mul(v17, pGame->pIndoorCameraD3D->int_cosine_y) + fixpoint_mul(v40, pGame->pIndoorCameraD3D->int_sine_y); if ( v20 >= 0x40000 && v20 <= pODMRenderParams->shading_dist_mist << 16 ) { v21 = fixpoint_mul(v40, pGame->pIndoorCameraD3D->int_cosine_y) - fixpoint_mul(v42, pGame->pIndoorCameraD3D->int_sine_y); v22 = (pLevelDecorations[i].vPosition.z - pGame->pIndoorCameraD3D->vPartyPos.z) << 16; v42 = v22; if ( 2 * abs(v20) >= abs(v21) ) { LODWORD(v24) = 0; HIDWORD(v24) = SLOWORD(pODMRenderParams->int_fov_rad); v25 = pViewport->uScreenCenterX - ((signed int)(fixpoint_mul(v24 / v20, v21) + 0x8000) >> 16); v40 = pViewport->uScreenCenterY - ((signed int)(fixpoint_mul(v24 / v20, v42) + 0x8000) >> 16); v41 = fixpoint_mul(v8->scale, v24 / v20); if ( pRenderD3D ) b = fixpoint_mul(pSprites_LOD->pHardwareSprites[v8->pHwSpriteIDs[(int)v37]].uBufferWidth / 2, v41); else { __debugbreak(); b = fixpoint_mul(pSprites_LOD->pSpriteHeaders[v8->pHwSpriteIDs[(int)v37]].uWidth / 2, v41); } if ( b + v25 >= (signed int)pViewport->uViewportTL_X && v25 - b <= (signed int)pViewport->uViewportBR_X ) { if (::uNumBillboardsToDraw >= 500) return; pBillboardRenderList[::uNumBillboardsToDraw].HwSpriteID = v8->pHwSpriteIDs[(int)v37]; pBillboardRenderList[::uNumBillboardsToDraw]._screenspace_x_scaler_packedfloat = v41; pBillboardRenderList[::uNumBillboardsToDraw]._screenspace_y_scaler_packedfloat = v41; v29 = v38; pBillboardRenderList[::uNumBillboardsToDraw].uScreenSpaceX = v25; HIBYTE(v29) |= 2; pBillboardRenderList[::uNumBillboardsToDraw].uPalette = v8->uPaletteIndex; pBillboardRenderList[::uNumBillboardsToDraw].field_1E = v29; pBillboardRenderList[::uNumBillboardsToDraw].world_x = pLevelDecorations[i].vPosition.x; pBillboardRenderList[::uNumBillboardsToDraw].world_y = pLevelDecorations[i].vPosition.y; pBillboardRenderList[::uNumBillboardsToDraw].world_z = pLevelDecorations[i].vPosition.z; pBillboardRenderList[::uNumBillboardsToDraw].uScreenSpaceY = v40; HIWORD(v30) = HIWORD(v20); v31 = PID(OBJECT_Decoration,i); LOWORD(v30) = 0; pBillboardRenderList[::uNumBillboardsToDraw].uIndoorSectorID = 0; pBillboardRenderList[::uNumBillboardsToDraw].sZValue = v30 + v31; pBillboardRenderList[::uNumBillboardsToDraw].dimming_level = 0; pBillboardRenderList[::uNumBillboardsToDraw].pSpriteFrame = v8; pBillboardRenderList[::uNumBillboardsToDraw].sTintColor = 0; ::uNumBillboardsToDraw++; ++uNumDecorationsDrawnThisFrame; } } continue; } } } } else { memset(&local_0, 0, 0x68); local_0.type = ParticleType_Bitmap | ParticleType_Rotating | ParticleType_8; local_0.uDiffuse = 0xFF3C1E; local_0.x = (double)pLevelDecorations[i].vPosition.x; local_0.y = (double)pLevelDecorations[i].vPosition.y; local_0.z = (double)pLevelDecorations[i].vPosition.z; local_0.r = 0.0; local_0.g = 0.0; local_0.b = 0.0; local_0.flt_28 = 1.0; local_0.timeToLive = (rand() & 0x80) + 128; local_0.uTextureID = pBitmaps_LOD->LoadTexture("effpar01"); pGame->pParticleEngine->AddParticle(&local_0); } } } } //----- (0049D717) -------------------------------------------------------- HRESULT __stdcall D3DZBufferFormatEnumerator(DDPIXELFORMAT *Src, DDPIXELFORMAT *Dst) { if ( Src->dwFlags & (0x400 | 0x2000)) { if ( Src->dwRGBBitCount == 16 && !Src->dwRBitMask ) { memcpy(Dst, Src, sizeof(DDPIXELFORMAT)); return 0; } if ( !Dst->dwSize ) { memcpy(Dst, Src, sizeof(DDPIXELFORMAT)); return 1; } } return 1; } //----- (0049DC28) -------------------------------------------------------- void RenderD3D::GetAvailableDevices(RenderD3D__DevInfo **pOutDevices) { RenderD3D__DevInfo *v2; // eax@1 v2 = new RenderD3D__DevInfo[4];// 4 items *pOutDevices = v2; memset(v2, 0, sizeof(v2)); DirectDrawEnumerateExA((LPDDENUMCALLBACKEXA)RenderD3D__DeviceEnumerator, *pOutDevices, DDENUM_ATTACHEDSECONDARYDEVICES); } //----- (0049DC58) -------------------------------------------------------- RenderD3D::RenderD3D() { this->pHost = nullptr; this->pDirect3D = nullptr; this->pUnk = nullptr; this->pBackBuffer = nullptr; this->pFrontBuffer = nullptr; this->pZBuffer = nullptr; this->pDevice = nullptr; this->pViewport = nullptr; this->field_40 = 1; this->field_44 = 10; GetAvailableDevices(&this->pAvailableDevices); } //----- (0049DC90) -------------------------------------------------------- void RenderD3D::Release() { if ( !this->bWindowed ) { if ( this->pHost ) { this->pHost->RestoreDisplayMode(); this->pHost->SetCooperativeLevel(this->hWindow, DDSCL_NORMAL); this->pHost->FlipToGDISurface(); } } for (int i = 0; i < 4; i++) { delete[] this->pAvailableDevices[i].pDriverName; this->pAvailableDevices[i].pDriverName = nullptr; delete[] this->pAvailableDevices[i].pDeviceDesc; this->pAvailableDevices[i].pDeviceDesc = nullptr; delete[] this->pAvailableDevices[i].pDDraw4DevDesc; this->pAvailableDevices[i].pDDraw4DevDesc = nullptr; delete this->pAvailableDevices[i].pDirectDrawGUID; this->pAvailableDevices[i].pDirectDrawGUID = nullptr; delete[] this->pAvailableDevices[i].pName; this->pAvailableDevices[i].pName = nullptr; delete[] this->pAvailableDevices[i].pDescription; this->pAvailableDevices[i].pDescription = nullptr; delete this->pAvailableDevices[i].pGUID; this->pAvailableDevices[i].pGUID = nullptr; } delete[] this->pAvailableDevices; this->pAvailableDevices = NULL; if ( this->pViewport ) { this->pViewport->Release(); this->pViewport = NULL; } if ( this->pUnk ) { this->pUnk->Release(); this->pUnk = NULL; } if ( this->pZBuffer ) { this->pZBuffer->Release(); this->pZBuffer = NULL; } if ( this->pDevice ) { this->pDevice->Release(); this->pDevice = NULL; } if ( this->pDirect3D ) { this->pDirect3D->Release(); this->pDirect3D = NULL; } if ( this->pBackBuffer ) { this->pBackBuffer->Release(); this->pBackBuffer = NULL; } if ( this->pFrontBuffer ) { this->pFrontBuffer->Release(); this->pFrontBuffer = NULL; } if ( this->pHost ) { this->pHost->Release(); this->pHost = NULL; } } //----- (0049DE14) -------------------------------------------------------- bool RenderD3D::CreateDevice(unsigned int uDeviceID, int bWindowed, OSWindow *window) { DWORD v26; // [sp-4h] [bp-DCh]@30 DDSCAPS2 v27; // [sp+Ch] [bp-CCh]@37 DDSURFACEDESC2 ddsd2; // [sp+1Ch] [bp-BCh]@11 D3DVIEWPORT2 d3dvp2; // [sp+98h] [bp-40h]@28 IDirectDrawClipper *lpddclipper; // [sp+C4h] [bp-14h]@18 LPDIRECTDRAW lpDD; // [sp+C8h] [bp-10h]@1 auto hWnd = window->GetApiHandle(); int game_width = window->GetWidth(); int game_height = window->GetHeight(); this->bWindowed = bWindowed; this->hWindow = hWnd; //Создание объекта DirectDraw if (FAILED(DirectDrawCreate(pAvailableDevices[uDeviceID].pDirectDrawGUID, &lpDD, NULL))) { sprintf(pErrorMessage, "Init - Failed to create DirectDraw interface.\n"); return 0; } //Запрос интерфейса IDirectDraw4 if (FAILED(lpDD->QueryInterface(IID_IDirectDraw4, (LPVOID *)&pHost))) { sprintf(pErrorMessage, "Init - Failed to create DirectDraw4 interface.\n"); if (lpDD) lpDD->Release(); return 0; } lpDD->Release(); lpDD = NULL; //Задаём уровень совместного доступа для приложения DirectDraw в оконном режиме if (bWindowed && !pAvailableDevices[uDeviceID].pDirectDrawGUID) { if (FAILED(pHost->SetCooperativeLevel(hWnd, DDSCL_MULTITHREADED | DDSCL_NORMAL))) { sprintf(pErrorMessage, "Init - Failed to set cooperative level.\n"); if (pHost) { pHost->Release(); pHost = NULL; } return 0; } // memset(&ddsd2, 0, sizeof(DDSURFACEDESC2)); ddsd2.dwSize = sizeof(DDSURFACEDESC2); ddsd2.dwFlags = DDSD_CAPS; ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; //Создаём первичную поверхность if ( FAILED(pHost->CreateSurface(&ddsd2, &pFrontBuffer, NULL)) ) { sprintf(pErrorMessage, "Init - Failed to create front buffer.\n"); if (pHost) { pHost->Release(); pHost = NULL; } return 0; } ddsd2.dwSize = sizeof(DDSURFACEDESC2); pHost->GetDisplayMode(&ddsd2); if ( FORCE_16_BITS && ddsd2.ddpfPixelFormat.dwRGBBitCount != 16 ) { sprintf(pErrorMessage, "Init - Desktop isn't in 16 bit mode.\n"); if (pFrontBuffer) { pFrontBuffer->Release(); pFrontBuffer = NULL; } if (pHost) { pHost->Release(); pHost = NULL; } return 0; } ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; ddsd2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE; ddsd2.dwWidth = game_width; ddsd2.dwHeight = game_height; if (pHost->CreateSurface(&ddsd2, &pBackBuffer, NULL) ) { sprintf(pErrorMessage, "Init - Failed to create back buffer.\n"); if (pFrontBuffer) { pFrontBuffer->Release(); pFrontBuffer = NULL; } if (pHost) { pHost->Release(); pHost = NULL; } return 0; } //Создание отсекателя DirectDraw if ( pHost->CreateClipper(0, &lpddclipper, NULL) ) { sprintf(pErrorMessage, "Init - Failed to create clipper.\n"); if (pBackBuffer) { pBackBuffer->Release(); pBackBuffer = NULL; } if (pFrontBuffer) { pFrontBuffer->Release(); pFrontBuffer= NULL; } if (pHost) { pHost->Release(); pHost = NULL; } return 0; } lpddclipper->SetHWnd(0, hWnd); pFrontBuffer->SetClipper(lpddclipper); lpddclipper->Release(); lpddclipper = NULL; // pHost->QueryInterface(IID_IDirect3D3, (LPVOID *)&pDirect3D); ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; ddsd2.ddsCaps.dwCaps = DDSCAPS_ZBUFFER; ddsd2.dwWidth = game_width; ddsd2.dwHeight = game_height; if ( pDirect3D->EnumZBufferFormats(*pAvailableDevices[uDeviceID].pGUID, (HRESULT (__stdcall *)(DDPIXELFORMAT *, void *))D3DZBufferFormatEnumerator, &ddsd2.ddpfPixelFormat) ) { sprintf(pErrorMessage, "Init - Failed to enumerate Z buffer formats.\n"); if (pBackBuffer) { pBackBuffer->Release(); pBackBuffer = NULL; } if (pFrontBuffer) { pFrontBuffer->Release(); pFrontBuffer= NULL; } if (pHost) { pHost->Release(); pHost = NULL; } return 0; } if ( uDeviceID == 2 || uDeviceID == 3 ) ddsd2.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; if ( !pHost->CreateSurface(&ddsd2, &pZBuffer, NULL) ) { if ( !pBackBuffer->AddAttachedSurface(pZBuffer) ) { if ( !pDirect3D->CreateDevice(*pAvailableDevices[uDeviceID].pGUID, pBackBuffer, &pDevice, 0) ) { memset(&d3dvp2, 0, sizeof(D3DVIEWPORT2)); d3dvp2.dvClipWidth = 2.0; d3dvp2.dvClipY = 1.0; d3dvp2.dvClipHeight = 2.0; d3dvp2.dvMaxZ = 1.0; d3dvp2.dvMinZ = 0.0; goto LABEL_54; } sprintf(pErrorMessage, "Init - Failed to create D3D device.\n"); if (pDirect3D) { pDirect3D->Release(); pDirect3D = NULL; } if (pZBuffer) { pZBuffer->Release(); pZBuffer = NULL; } if (pBackBuffer) { pBackBuffer->Release(); pBackBuffer = NULL; } if (pFrontBuffer) { pFrontBuffer->Release(); pFrontBuffer= NULL; } if (pHost) { pHost->Release(); pHost = NULL; } return 0; } sprintf(pErrorMessage, "Init - Failed to attach z-buffer to back buffer.\n"); if (pZBuffer) { pZBuffer->Release(); pZBuffer = NULL; } if (pBackBuffer) { pBackBuffer->Release(); pBackBuffer = NULL; } if (pFrontBuffer) { pFrontBuffer->Release(); pFrontBuffer= NULL; } if (pHost) { pHost->Release(); pHost = NULL; } return 0; } sprintf(pErrorMessage, "Init - Failed to create z-buffer.\n"); if (pBackBuffer) { pBackBuffer->Release(); pBackBuffer = NULL; } if (pFrontBuffer) { pFrontBuffer->Release(); pFrontBuffer= NULL; } if (pHost) { pHost->Release(); pHost = NULL; } return 0; } if ( uDeviceID == 1 ) v26 = 1045; else v26 = 1041; if (pHost->SetCooperativeLevel(hWnd, v26) ) { sprintf(pErrorMessage, "Init - Failed to set cooperative level.\n"); if (pHost) { pHost->Release(); pHost = NULL; } return 0; } if (pHost->SetDisplayMode(window->GetWidth(), window->GetHeight(), 16, 0, 0) ) { sprintf(pErrorMessage, "Init - Failed to set display mode.\n"); if (pHost) { pHost->Release(); pHost = NULL; } return 0; } memset(&ddsd2, 0, sizeof(DDSURFACEDESC2)); ddsd2.dwSize = sizeof(DDSURFACEDESC2); //Подключение полей с достоверными данными ddsd2.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; //Запрос сложной структуры с возможностью переключения ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; //Присвоение полю счётчика задних буферов значения 1 ddsd2.dwBackBufferCount = 1; if ( pHost->CreateSurface(&ddsd2, &pFrontBuffer, NULL) ) { sprintf(pErrorMessage, "Init - Failed to create front buffer.\n"); if (pHost) { pHost->Release(); pHost = NULL; } return 0; } //a3a = &pBackBuffer; //v14 = *v34; memset(&v27, 0, sizeof(DDSCAPS2)); v27.dwCaps = DDSCAPS_BACKBUFFER; //v33 = (IDirect3DDevice3 **)v14->GetAttachedSurface(&v27, &pBackBuffer); //hWnda = &pDirect3D; pHost->QueryInterface(IID_IDirect3D3, (LPVOID *)&pDirect3D); if (FAILED(pFrontBuffer->GetAttachedSurface(&v27, &pBackBuffer))) { sprintf(pErrorMessage, "Init - Failed to get D3D interface.\n"); if (pBackBuffer) { pBackBuffer->Release(); pBackBuffer = NULL; } if (pFrontBuffer) { pFrontBuffer->Release(); pFrontBuffer= NULL; } if (pHost) { pHost->Release(); pHost = NULL; } return 0; } ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; ddsd2.ddsCaps.dwCaps = DDSCAPS_ZBUFFER; ddsd2.dwWidth = 640; ddsd2.dwHeight = 480; if ( pDirect3D->EnumZBufferFormats(*pAvailableDevices[uDeviceID].pGUID, (HRESULT (__stdcall *)(DDPIXELFORMAT *, void *))D3DZBufferFormatEnumerator, &ddsd2.ddpfPixelFormat) ) { sprintf(pErrorMessage, "Init - Failed to enumerate Z buffer formats.\n"); if (pBackBuffer) { pBackBuffer->Release(); pBackBuffer = 0; } if (pFrontBuffer) { pFrontBuffer->Release(); pFrontBuffer= 0; } if (pHost) { pHost->Release(); pHost = 0; } return 0; } if ( uDeviceID == 2 || uDeviceID == 3 ) BYTE1(ddsd2.ddsCaps.dwCaps) |= 8; //uDeviceIDa = &pZBuffer; if (pHost->CreateSurface(&ddsd2, &pZBuffer, NULL) ) { sprintf(pErrorMessage, "Init - Failed to create z-buffer.\n"); if (pBackBuffer) { pBackBuffer->Release(); pBackBuffer = 0; } if (pFrontBuffer) { pFrontBuffer->Release(); pFrontBuffer= 0; } if (pHost) { pHost->Release(); pHost = 0; } return 0; } if (pBackBuffer->AddAttachedSurface(pZBuffer)) { sprintf(pErrorMessage, "Init - Failed to attach z-buffer to back buffer.\n"); if (pZBuffer) { pZBuffer->Release(); pZBuffer = 0; } if (pBackBuffer) { pBackBuffer->Release(); pBackBuffer = 0; } if (pFrontBuffer) { pFrontBuffer->Release(); pFrontBuffer= 0; } if (pHost) { pHost->Release(); pHost = 0; } return 0; } //v33 = &pDevice; if (pDirect3D->CreateDevice(*pAvailableDevices[uDeviceID].pGUID, pBackBuffer, &pDevice, 0) ) { sprintf(pErrorMessage, "Init - Failed to create D3D device.\n"); if (pDirect3D) { pDirect3D->Release(); pDirect3D = 0; } if (pZBuffer) { pZBuffer->Release(); pZBuffer = 0; } if (pBackBuffer) { pBackBuffer->Release(); pBackBuffer = 0; } if (pFrontBuffer) { pFrontBuffer->Release(); pFrontBuffer= 0; } if (pHost) { pHost->Release(); pHost = 0; } return 0; } memset(&d3dvp2, 0, sizeof(D3DVIEWPORT2)); d3dvp2.dvClipWidth = 2.0; d3dvp2.dvClipY = 1.0; d3dvp2.dvClipHeight = 2.0; d3dvp2.dvMaxZ = 1.0; LABEL_54: d3dvp2.dwSize = sizeof(D3DVIEWPORT2); //v17 = *hWnda; d3dvp2.dwWidth = game_width; d3dvp2.dwHeight = game_height; d3dvp2.dvClipX = -1.0; //v18 = v17->lpVtbl; //v32 = &v4->pViewport; if (pDirect3D->CreateViewport(&pViewport, 0)) { sprintf(pErrorMessage, "Init - Failed to create viewport.\n"); if (pDevice) { pDevice->Release(); pDevice = 0; } if (pDirect3D) { pDirect3D->Release(); pDirect3D = 0; } if (pZBuffer) { pZBuffer->Release(); pZBuffer = 0; } if (pBackBuffer) { pBackBuffer->Release(); pBackBuffer = 0; } if (pFrontBuffer) { pFrontBuffer->Release(); pFrontBuffer= 0; } if (pHost) { pHost->Release(); pHost = 0; } return 0; } pDevice->AddViewport(pViewport); pViewport->SetViewport2(&d3dvp2); pDevice->SetCurrentViewport(pViewport); return 1; } //----- (0049E444) -------------------------------------------------------- unsigned int RenderD3D::GetDeviceCaps() { unsigned int v1; // ebx@1 unsigned int result; // eax@2 D3DDEVICEDESC refCaps; // [sp+Ch] [bp-1F8h]@1 D3DDEVICEDESC halCaps; // [sp+108h] [bp-FCh]@1 v1 = 0; memset(&halCaps, 0, sizeof(halCaps)); halCaps.dwSize = sizeof(halCaps); memset(&refCaps, 0, sizeof(refCaps)); refCaps.dwSize = sizeof(refCaps); if ( this->pDevice->GetCaps(&halCaps, &refCaps) ) result = 1; else { if ( !(halCaps.dpcTriCaps.dwSrcBlendCaps & D3DPBLENDCAPS_SRCALPHA) ) v1 = 2; if ( !(halCaps.dpcTriCaps.dwSrcBlendCaps & D3DPBLENDCAPS_ONE) ) v1 |= 4; if ( !(halCaps.dpcTriCaps.dwSrcBlendCaps & D3DPBLENDCAPS_ZERO) ) v1 |= 8; if ( !(halCaps.dpcTriCaps.dwDestBlendCaps & D3DPBLENDCAPS_INVSRCALPHA) ) v1 |= 16; if ( !(halCaps.dpcTriCaps.dwDestBlendCaps & D3DPBLENDCAPS_ONE) ) v1 |= 32; if ( !(halCaps.dpcTriCaps.dwDestBlendCaps & D3DPBLENDCAPS_SRCCOLOR) ) v1 |= 64; if ( halCaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_SQUAREONLY ) v1 |= 128; result = v1; } return result; } //----- (0049E4FC) -------------------------------------------------------- void RenderD3D::ClearTarget(unsigned int bClearColor, unsigned int uClearColor, unsigned int bClearDepth, float z_clear) { uint uClearFlags = 0; if (bClearColor) uClearFlags |= D3DCLEAR_TARGET; if (bClearDepth) uClearFlags |= D3DCLEAR_ZBUFFER; D3DRECT rects[] = {{0, 0, window->GetWidth(), window->GetHeight()}}; if (uClearFlags) pViewport->Clear2(1, rects, uClearFlags, uClearColor, z_clear, 0); } //----- (0049E54D) -------------------------------------------------------- void RenderD3D::Present(bool bForceBlit) { RECT source_rect; // [sp+18h] [bp-18h]@1 struct tagPOINT Point; // [sp+28h] [bp-8h]@4 source_rect.left = 0; source_rect.top = 0; source_rect.bottom = 480;//window->GetHeight(); //Ritor1: проблема с кнопкой "развернуть" source_rect.right = 640; //window->GetWidth(); if (bWindowed || bForceBlit) { RECT dest_rect; GetClientRect(hWindow, &dest_rect); Point.y = 0; Point.x = 0; ClientToScreen(hWindow, &Point); OffsetRect(&dest_rect, Point.x, Point.y); pFrontBuffer->Blt(&dest_rect, pBackBuffer, &source_rect, DDBLT_WAIT, NULL); } else pFrontBuffer->Flip(NULL, DDFLIP_WAIT); } //----- (0049E5D4) -------------------------------------------------------- bool RenderD3D::CreateTexture(unsigned int uTextureWidth, unsigned int uTextureHeight, IDirectDrawSurface4 **pOutSurface, IDirect3DTexture2 **pOutTexture, bool bAlphaChannel, bool bMipmaps, unsigned int uMinDeviceTexDim) { unsigned int v9; // ebx@5 unsigned int v10; // eax@5 DWORD v11; // edx@5 DDSURFACEDESC2 ddsd2; // [sp+Ch] [bp-80h]@1 memset(&ddsd2, 0, sizeof(ddsd2)); ddsd2.dwSize = sizeof(ddsd2); ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE; ddsd2.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE; ddsd2.dwHeight = uTextureHeight; ddsd2.dwWidth = uTextureWidth; if ( bMipmaps ) { if ( (signed int)uTextureHeight <= (signed int)uTextureWidth ) { ddsd2.dwMipMapCount = GetMaxMipLevels(uTextureHeight) - GetMaxMipLevels(uMinDeviceTexDim); if ( ddsd2.dwMipMapCount ) { ddsd2.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT; ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP; } goto LABEL_12; } if ( (signed int)uTextureWidth < (signed int)uMinDeviceTexDim ) { ddsd2.dwMipMapCount = GetMaxMipLevels(uMinDeviceTexDim); if ( ddsd2.dwMipMapCount ) { ddsd2.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT; ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP; } goto LABEL_12; } v9 = GetMaxMipLevels(uTextureWidth); v10 = GetMaxMipLevels(uMinDeviceTexDim); ddsd2.dwMipMapCount = v9 - v10; if ( v9 == v10 ) { ddsd2.dwFlags = 0x1007; __debugbreak(); // warning C4700: uninitialized local variable 'v11' used ddsd2.ddsCaps.dwCaps = v11; goto LABEL_12; } } else ddsd2.dwMipMapCount = 1; ddsd2.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT; ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP; LABEL_12: ddsd2.ddpfPixelFormat.dwRGBBitCount = 16; ddsd2.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); if (bAlphaChannel) { ddsd2.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS; ddsd2.ddpfPixelFormat.dwRBitMask = 0x7C00; ddsd2.ddpfPixelFormat.dwGBitMask = 0x03E0; ddsd2.ddpfPixelFormat.dwBBitMask = 0x001F; ddsd2.ddpfPixelFormat.dwRGBAlphaBitMask = 0x8000; } else { ddsd2.ddpfPixelFormat.dwFlags = DDPF_RGB; ddsd2.ddpfPixelFormat.dwRBitMask = 0xF800; ddsd2.ddpfPixelFormat.dwGBitMask = 0x07E0; ddsd2.ddpfPixelFormat.dwBBitMask = 0x001F; ddsd2.ddpfPixelFormat.dwRGBAlphaBitMask = 0; } if (FAILED(pHost->CreateSurface(&ddsd2, pOutSurface, NULL))) return false; if (FAILED((*pOutSurface)->QueryInterface(IID_IDirect3DTexture2, (void **)pOutTexture))) { (*pOutSurface)->Release(); *pOutSurface = 0; return false; } return true; } //----- (004A5190) -------------------------------------------------------- void RenderD3D::HandleLostResources() { pBitmaps_LOD->ReleaseLostHardwareTextures(); pBitmaps_LOD->_410423_move_textures_to_device(); pSprites_LOD->ReleaseLostHardwareSprites(); } //----- (004A2050) -------------------------------------------------------- void Render::DrawPolygon(unsigned int uNumVertices, struct Polygon *a3, ODMFace *a4, IDirect3DTexture2 *pTexture) { unsigned int v6; // ebx@1 int v8; // eax@7 unsigned int v41; // eax@29 //unsigned int v54; // [sp+5Ch] [bp-Ch]@3 signed int a2; // [sp+64h] [bp-4h]@4 v6 = 0; if ( this->uNumD3DSceneBegins && (signed int)uNumVertices >= 3 ) { //v54 = pGame->pLightmapBuilder->std__vector_000004_size; if ( pGame->pLightmapBuilder->std__vector_000004_size) a2 = -1; pGame->AlterGamma_ODM(a4, &a2); if ( byte_4D864C && pGame->uFlags & GAME_FLAGS_1_01_lightmap_related) { v8 = ::GetActorTintColor(a3->dimming_level, 0, array_50AC10[0].vWorldViewPosition.x, 0, 0); pGame->pLightmapBuilder->DrawLightmaps(/*v8, 0*/); } else { if ( !pGame->pLightmapBuilder->std__vector_000004_size || byte_4D864C && pGame->uFlags & 2 ) { ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CW)); if (bUsingSpecular) { ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); } for (uint i = 0; i < uNumVertices; ++i) { d3d_vertex_buffer[i].pos.x = array_50AC10[i].vWorldViewProjX; d3d_vertex_buffer[i].pos.y = array_50AC10[i].vWorldViewProjY; d3d_vertex_buffer[i].pos.z = 1.0 - 1.0 / ((array_50AC10[i].vWorldViewPosition.x * 1000) / (double)pODMRenderParams->shading_dist_mist); d3d_vertex_buffer[i].rhw = 1.0 / (array_50AC10[i].vWorldViewPosition.x + 0.0000001); d3d_vertex_buffer[i].diffuse = ::GetActorTintColor(a3->dimming_level, 0, array_50AC10[i].vWorldViewPosition.x, 0, 0); pGame->AlterGamma_ODM(a4, &d3d_vertex_buffer[i].diffuse); if ( this->bUsingSpecular ) d3d_vertex_buffer[i].specular = sub_47C3D7_get_fog_specular(0, 0, array_50AC10[i].vWorldViewPosition.x); else d3d_vertex_buffer[i].specular = 0; d3d_vertex_buffer[i].texcoord.x = array_50AC10[i].u; d3d_vertex_buffer[i].texcoord.y = array_50AC10[i].v; } if (a4->uAttributes & FACE_OUTLINED) { int color; if (GetTickCount() % 300 >= 150) color = 0xFFFF2020; else color = 0xFF901010; for (uint i = 0; i < uNumVertices; ++i) d3d_vertex_buffer[i].diffuse = color; } pRenderD3D->pDevice->SetTexture(0, pTexture); pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, d3d_vertex_buffer, uNumVertices, D3DDP_DONOTLIGHT); } else { for (uint i = 0; i < uNumVertices; ++i) { d3d_vertex_buffer[i].pos.x = array_50AC10[i].vWorldViewProjX; d3d_vertex_buffer[i].pos.y = array_50AC10[i].vWorldViewProjY; d3d_vertex_buffer[i].pos.z = 1.0 - 1.0 / ((array_50AC10[i].vWorldViewPosition.x * 1000) / (double)pODMRenderParams->shading_dist_mist); d3d_vertex_buffer[i].rhw = 1.0 / (array_50AC10[i].vWorldViewPosition.x + 0.0000001); d3d_vertex_buffer[i].diffuse = GetActorTintColor(a3->dimming_level, 0, array_50AC10[i].vWorldViewPosition.x, 0, 0); if ( this->bUsingSpecular ) d3d_vertex_buffer[i].specular = sub_47C3D7_get_fog_specular(0, 0, array_50AC10[i].vWorldViewPosition.x); else d3d_vertex_buffer[i].specular = 0; d3d_vertex_buffer[i].texcoord.x = array_50AC10[i].u; d3d_vertex_buffer[i].texcoord.y = array_50AC10[i].v; } ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); if (bUsingSpecular) ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE)); ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr)); ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, D3DFVF_XYZRHW | D3DFVF_TEX1 | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, d3d_vertex_buffer, uNumVertices, D3DDP_DONOTLIGHT)); //v50 = (const char *)v5->pRenderD3D->pDevice; ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE)); //(*(void (**)(void))(*(int *)v50 + 88))(); pGame->pLightmapBuilder->DrawLightmaps(/*-1, 0*/); for (uint i = 0; i < uNumVertices; ++i) { d3d_vertex_buffer[i].diffuse = a2; } ErrD3D(pRenderD3D->pDevice->SetTexture(0, pTexture)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); if ( !pRenderer->bUsingSpecular ) ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ZERO)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_SRCCOLOR)); ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, D3DFVF_XYZRHW | D3DFVF_TEX1 | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, d3d_vertex_buffer, uNumVertices, D3DDP_DONOTLIGHT)); if (bUsingSpecular) { ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); for (uint i = 0; i < uNumVertices; ++i) { d3d_vertex_buffer[i].diffuse = pRenderer->uFogColor | d3d_vertex_buffer[i].specular & 0xFF000000; d3d_vertex_buffer[i].specular = 0; } ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_INVSRCALPHA)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_SRCALPHA)); ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, D3DFVF_XYZRHW | D3DFVF_TEX1 | D3DFVF_DIFFUSE | D3DFVF_SPECULAR, d3d_vertex_buffer, uNumVertices, D3DDP_DONOTLIGHT)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE)); //v40 = pRenderer->pRenderD3D->pDevice->lpVtbl; v41 = GetLevelFogColor(); pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, GetLevelFogColor() & 0xFFFFFF); v6 = 0; pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, 0); } ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, v6)); } } } } // 4D864C: using guessed type char byte_4D864C; //----- (0049EB79) -------------------------------------------------------- Render::~Render() { free(this->pDefaultZBuffer); this->pD3DBitmaps.Release(); this->pD3DSprites.Release(); Release(); this->bWindowMode = 1; //nullsub_1(); //nullsub_1(); } //----- (0049E992) -------------------------------------------------------- Render::Render() { //Render *v1; // esi@1 // int v2; // eax@1 // char v3; // zf@1 //v1 = this; this->pDirectDraw4 = nullptr; this->pFrontBuffer4 = nullptr; this->pBackBuffer4 = nullptr; //this->pColorKeySurface4 = 0; //this->pDirectDraw2 = 0; //this->pFrontBuffer2 = 0; //this->pBackBuffer2 = 0; //this->pSomeSurface2 = 0; //RenderHWLContainer::RenderHWLContainer(&this->pD3DBitmaps); //RenderHWLContainer::RenderHWLContainer(&v1->pD3DSprites); this->bWindowMode = 1; //this->field_40054 = 0; //this->field_10 = 640; //this->field_14 = 480; //this->field_40030 = 0; //this->field_4002C = 0; this->pActiveZBuffer = nullptr; this->pDefaultZBuffer = nullptr; this->raster_clip_y = 0; this->raster_clip_x = 0; this->raster_clip_z = 639; this->raster_clip_w = 479; //this->field_4003C = 0x004EED80; //this->field_40040 = dword_4EED78; this->uClipZ = 640; //this->field_40044 = 2; //this->field_40048 = 6; this->pFrontBuffer4 = nullptr; this->pBackBuffer4 = nullptr; //this->pColorKeySurface4 = 0; this->pDirectDraw4 = nullptr; this->pRenderD3D = 0; this->uNumSceneBegins = 0; this->uNumD3DSceneBegins = 0; this->using_software_screen_buffer = 0; this->pTargetSurface = nullptr; this->uTargetSurfacePitch = 0; this->uClipY = 0; this->uClipX = 0; this->uClipW = 480; this->bClip = 1; //this->bColorKeySupported = 0; this->bRequiredTextureStagesAvailable = 0; this->bTinting = 1; //LOBYTE(this->field_103668) = 0; uNumBillboardsToDraw = 0; bFogEnabled = false; hd_water_tile_id = -1; hd_water_current_frame = 0; } bool Render::Initialize(OSWindow *window/*, bool bColoredLights, uint32_t uDetailLevel, bool bTinting*/) { //bUserDirect3D = true;//ReadWindowsRegistryInt("Use D3D", 0); this->window = window; //bStartInWindow = true; //windowed_mode_width = windowed_width; //windowed_mode_height = windowed_height; uDesiredDirect3DDevice = ReadWindowsRegistryInt("D3D Device", 0); bUseColoredLights = ReadWindowsRegistryInt("Colored Lights", false); uLevelOfDetail = ReadWindowsRegistryInt("Detail Level", 1); bTinting = ReadWindowsRegistryInt("Tinting", 1) != 0; bool r1 = pD3DBitmaps.Load(L"data\\d3dbitmap.hwl"); bool r2 = pD3DSprites.Load(L"data\\d3dsprite.hwl"); return r1 && r2; } //----- (0049ECC4) -------------------------------------------------------- void Render::ClearBlack() { //if (pRenderD3D) { if (using_software_screen_buffer) pRenderD3D->ClearTarget(true, 0, false, 0.0); } //else //memset(pRenderer->pTargetSurface, 0, 4 * (field_10 * field_14 / 2)); } //----- (0049ED18) -------------------------------------------------------- void Render::PresentBlackScreen() { IDirectDrawSurface *lpddsback; // eax@3 DDBLTFX lpDDBltFx; // [sp+4h] [bp-74h]@5 RECT dest_rect; // [sp+68h] [bp-10h]@3 memset(&lpDDBltFx, 0, sizeof(DDBLTFX)); lpDDBltFx.dwSize = sizeof(DDBLTFX); GetWindowRect(window->GetApiHandle(), &dest_rect); lpddsback = (IDirectDrawSurface *)this->pBackBuffer4; lpDDBltFx.dwFillColor = 0; lpddsback->Blt(&dest_rect, NULL, NULL, DDBLT_COLORFILL, &lpDDBltFx); pRenderer->Present(); } //----- (0049EDB6) -------------------------------------------------------- void Render::SavePCXScreenshot() { int v5; // eax@8 FILE *pOutFile; // edi@10 unsigned short *v8; // eax@11 signed int v12; // eax@18 char v15[56]; // [sp+Ch] [bp-158h]@10 DDSURFACEDESC2 Dst; // [sp+48h] [bp-11Ch]@7 char color_map[48]; // [sp+C4h] [bp-A0h]@10 char Filename[40]; // [sp+F4h] [bp-70h]@3 char *lineB; // [sp+11Ch] [bp-48h]@14 char *lineG; // [sp+120h] [bp-44h]@14 FILE *File; // [sp+128h] [bp-3Ch]@3 PCXHeader_1 header1; // [sp+130h] [bp-34h]@10 PCXHeader_2 header2; // [sp+140h] [bp-24h]@10 char *lineRGB; // [sp+148h] [bp-1Ch]@10 void *surface; // [sp+14Ch] [bp-18h]@8 unsigned int image_width; // [sp+150h] [bp-14h]@4 int pitch; // [sp+154h] [bp-10h]@4 char v31; // [sp+15Ah] [bp-Ah]@25 unsigned char pict_byte; // [sp+15Bh] [bp-9h]@17 unsigned short *line_picture_data; // [sp+15Ch] [bp-8h]@10 byte test_byte; // [sp+163h] [bp-1h]@17 int num_r_bits = 5; int num_g_bits = 6; int num_b_bits = 5; int r_mask = 0xF800; int g_mask = 0x7E0; int b_mask = 0x1F; if ( !this->pRenderD3D || this->using_software_screen_buffer ) { sprintf(Filename, "screen%0.2i.pcx", ScreenshotFileNumber++ % 100); File = fopen(Filename, "wb"); if ( File ) { pitch = this->GetRenderWidth(); if ( pitch & 1 ) pitch = pitch + 1; if ( this->pRenderD3D ) { memset(&Dst, 0, sizeof(Dst)); Dst.dwSize = sizeof(Dst); if ( !pRenderer->LockSurface_DDraw4(pRenderer->pBackBuffer4, &Dst, DDLOCK_WAIT) ) return; surface = Dst.lpSurface; v5 = Dst.lPitch / 2; } else { pRenderer->BeginScene(); surface = pRenderer->pTargetSurface; v5 = pRenderer->uTargetSurfacePitch; } header1.right = GetRenderWidth() - 1; header1.left = 0; header1.bottom = this->GetRenderHeight() - 1; header1.up = 0; header2.pitch = pitch; memset(color_map, 0, sizeof(color_map)); memset(v15, 0, sizeof(v15)); header2.reserved = 0; header1.manufacturer = 10; pOutFile = File; header1.version = 5; header1.encoding = 1; header1.bpp = 8; header1.hdpi = 75; header1.vdpi = 75; header2.planes = 3; header2.palette_info = 1; fwrite(&header1, 1, 1, File); fwrite(&header1.version, 1, 1, pOutFile); fwrite(&header1.encoding, 1, 1, pOutFile); fwrite(&header1.bpp, 1, 1, pOutFile); fwrite(&header1.left, 2, 1, pOutFile); fwrite(&header1.up, 2, 1, pOutFile); fwrite(&header1.right, 2, 1, pOutFile); fwrite(&header1.bottom, 2, 1, pOutFile); fwrite(&header1.hdpi, 2, 1, pOutFile); fwrite(&header1.vdpi, 2, 1, pOutFile); fwrite(color_map, 0x30, 1, pOutFile); fwrite(&header2, 1, 1, pOutFile); fwrite(&header2.planes, 1, 1, pOutFile); fwrite(&header2.pitch, 2, 1, pOutFile); fwrite(&header2.palette_info, 2, 1, pOutFile); fwrite(v15, 0x3Au, 1, pOutFile); lineRGB = (char *)malloc(3 * GetRenderWidth() + 6); if ( this->GetRenderHeight() > 0 ) { image_width = 3 * pitch; //v24 = 2 * v5; v8 = (unsigned short *)surface; for ( unsigned int y = 0; y < this->GetRenderHeight(); y++ ) { line_picture_data = v8; if ( GetRenderWidth() > 0 ) { lineG = (char *)lineRGB + pitch; lineB = (char *)lineRGB + 2 * pitch; for ( uint x = 0; x < this->GetRenderWidth(); x++ ) { //int p = *line_picture_data; //0x2818 //int for_rad = (pRenderer->uTargetGBits + pRenderer->uTargetBBits );//16 = 8 + 8 //int value = (pRenderer->uTargetRMask & *line_picture_data);//0 = 0xFF0000 & 0x2818 //int result = (pRenderer->uTargetRMask & *line_picture_data) >> (pRenderer->uTargetGBits + pRenderer->uTargetBBits ); lineRGB[x] = (uTargetRMask & *line_picture_data) >> (uTargetGBits + uTargetBBits );// + pRenderer->uTargetRBits - 8); lineG[x] = (uTargetGMask & *line_picture_data) >> (uTargetBBits);// + pRenderer->uTargetGBits - 8); //int value2 = (pRenderer->uTargetGMask & *line_picture_data); //10240 = 0xFF00 & 0x2818 //int result2 = (pRenderer->uTargetGMask & *line_picture_data) >> (pRenderer->uTargetBBits); lineB[x] = (uTargetBMask & *line_picture_data);// << (8 - pRenderer->uTargetBBits); //int value3 = (pRenderer->uTargetBMask & *line_picture_data);//24 = 0xFF & 0x2818 line_picture_data += 2; } } for ( uint i = 0; i < image_width; i += test_byte ) { pict_byte = lineRGB[i]; for ( test_byte = 1; test_byte < 0x3F; ++test_byte ) { v12 = i + test_byte; if ( lineRGB[v12] != pict_byte ) break; if ( !(v12 % pitch) ) break; } if ( i + test_byte > image_width ) test_byte = 3 * pitch - i; if ( test_byte > 1 || pict_byte >= 0xC0 ) { v31 = test_byte | 0xC0; fwrite(&v31, 1, 1, pOutFile); } fwrite(&pict_byte, 1, 1, pOutFile); } v8 += v5; } } if ( this->pRenderD3D ) ErrD3D(pRenderer->pBackBuffer4->Unlock(NULL)); else pRenderer->EndScene(); free(lineRGB); fclose(pOutFile); } } } //----- (0049F1BC) -------------------------------------------------------- void Render::SaveWinnersCertificate(const char *a1) { unsigned int v6; // eax@8 //FILE *v7; // edi@10 // int v8; // ecx@11 unsigned short *v9; // eax@11 int v10; // eax@13 signed int v13; // eax@18 // char v14; // zf@27 // HRESULT v15; // eax@29 char v16[56]; // [sp+Ch] [bp-12Ch]@10 __int16 v17; // [sp+44h] [bp-F4h]@10 DDSURFACEDESC2 Dst; // [sp+48h] [bp-F0h]@7 // int v19; // [sp+58h] [bp-E0h]@8 // unsigned __int16 *v20; // [sp+6Ch] [bp-CCh]@8 char color_map[48]; // [sp+C4h] [bp-74h]@10 // unsigned int v22; // [sp+F4h] [bp-44h]@11 char *lineB; // [sp+F8h] [bp-40h]@14 int image_width; // [sp+FCh] [bp-3Ch]@11 int v25; // [sp+100h] [bp-38h]@4 FILE *File; // [sp+104h] [bp-34h]@3 char Str; // [sp+108h] [bp-30h]@10 char v28; // [sp+109h] [bp-2Fh]@10 char v29; // [sp+10Ah] [bp-2Eh]@10 char v30; // [sp+10Bh] [bp-2Dh]@10 __int16 v31; // [sp+10Ch] [bp-2Ch]@10 __int16 v32; // [sp+10Eh] [bp-2Ah]@10 __int16 v33; // [sp+110h] [bp-28h]@10 __int16 v34; // [sp+112h] [bp-26h]@10 __int16 v35; // [sp+114h] [bp-24h]@10 __int16 v36; // [sp+116h] [bp-22h]@10 char v37; // [sp+118h] [bp-20h]@10 char v38; // [sp+119h] [bp-1Fh]@10 __int16 v39; // [sp+11Ah] [bp-1Eh]@10 __int16 v40; // [sp+11Ch] [bp-1Ch]@10 char *lineRGB; // [sp+120h] [bp-18h]@10 void *surface; // [sp+124h] [bp-14h]@8 int pitch; // [sp+128h] [bp-10h]@4 char v44; // [sp+12Fh] [bp-9h]@25 char *lineG; // [sp+130h] [bp-8h]@10 unsigned char pict_byte; // [sp+137h] [bp-1h]@17 byte test_byte; int num_r_bits = 5; int num_g_bits = 6; int num_b_bits = 5; int r_mask = 0xF800; int g_mask = 0x7E0; int b_mask = 0x1F; if ( !this->pRenderD3D || this->using_software_screen_buffer ) { static int _4EFA84_num_winners_certificates = 0; ++_4EFA84_num_winners_certificates; File = fopen(a1, "wb"); if ( File ) { v25 = this->GetRenderWidth(); pitch = v25; if ( pitch & 1 ) pitch = pitch + 1; if ( this->pRenderD3D ) { memset(&Dst, 0, 0x7C); Dst.dwSize = 124; if ( !pRenderer->LockSurface_DDraw4(pRenderer->pBackBuffer4, (DDSURFACEDESC2 *)&Dst, DDLOCK_WAIT) ) return; surface = Dst.lpSurface; v6 = Dst.lPitch / 2; } else { pRenderer->BeginScene(); surface = pRenderer->pTargetSurface; v6 = pRenderer->uTargetSurfacePitch; } v33 = this->GetRenderWidth() - 1; v31 = 0; v34 = (short)this->GetRenderHeight() - 1; v32 = 0; v39 = pitch; memset(&color_map, 0, sizeof(color_map)); memset(&v16, 0, sizeof(v16)); v37 = 0; Str = 10; v17 = 0; v28 = 5; v29 = 1; v30 = 8; v35 = 75; v36 = 75; v38 = 3; v40 = 1; fwrite(&Str, 1, 1, File); fwrite(&v28, 1, 1, File); fwrite(&v29, 1, 1, File); fwrite(&v30, 1, 1, File); fwrite(&v31, 2, 1, File); fwrite(&v32, 2, 1, File); fwrite(&v33, 2, 1, File); fwrite(&v34, 2, 1, File); fwrite(&v35, 2, 1, File); fwrite(&v36, 2, 1, File); fwrite(&color_map, 0x30, 1, File); fwrite(&v37, 1, 1, File); fwrite(&v38, 1, 1, File); fwrite(&v39, 2, 1, File); fwrite(&v40, 2, 1, File); fwrite(&v16, 0x3A, 1, File); lineRGB = (char *)malloc(3 * (v25 + 2)); if ( (signed int)this->GetRenderHeight() > 0 ) { image_width = 3 * pitch; v9 = (unsigned short *)surface; for ( uint j = 0; j < this->GetRenderHeight(); j++) { a1 = (const char *)v9; if ( v25 > 0 ) { lineG = (char *)lineRGB + pitch; lineB = (char *)lineRGB + 2 * pitch; for ( v10 = 0; v10 < v25; v10++ ) { lineRGB[v10] = (signed int)(r_mask & *(short *)a1) >> (num_g_bits + num_b_bits + num_r_bits - 8); lineG[v10] = (signed int)(g_mask & *(short *)a1) >> (num_b_bits + num_g_bits - 8); lineB[v10] = (b_mask & *(short *)a1) << (8 - num_b_bits); a1 += 2; } } for ( uint i = 0; i < image_width; i += test_byte ) { pict_byte = lineRGB[i]; for ( test_byte = 1; test_byte < 0x3F; test_byte ) { v13 = i + test_byte; if ( lineRGB[v13] != pict_byte ) break; if ( !(v13 % pitch) ) break; } if ( i + test_byte > image_width ) test_byte = 3 * pitch - i; if ( test_byte > 1 || pict_byte >= 0xC0 ) { v44 = test_byte | 0xC0; fwrite(&v44, 1, 1, File); } fwrite(&pict_byte, 1, 1, File); } v9 += pitch; } } if ( this->pRenderD3D ) ErrD3D(pRenderer->pBackBuffer4->Unlock(NULL)); else pRenderer->EndScene(); free(lineRGB); fclose(File); } } } //----- (0049F5A2) -------------------------------------------------------- void Render::PackPCXpicture( unsigned short* picture_data, int wight, int heidth, void *data_buff, int max_buff_size,unsigned int* packed_size ) { void *v8; // esi@3 void *v9; // esi@3 unsigned short* v11; // eax@4 // int v13; // eax@8 // int v14; // ecx@8 signed int v15; // eax@11 // char v16; // zf@20 // int result; // eax@21 char v18[58]; // [sp+Ch] [bp-ACh]@3 char v20[48]; // [sp+48h] [bp-70h]@3 char *lineG; // [sp+78h] [bp-40h]@7 char *lineB; // [sp+7Ch] [bp-3Ch]@7 int v23; // [sp+80h] [bp-38h]@4 int v24; // [sp+84h] [bp-34h]@4 int v25; // [sp+88h] [bp-30h]@4 int v26; // [sp+8Ch] [bp-2Ch]@4 PCXHeader_1 Src; // [sp+90h] [bp-28h]@3 PCXHeader_2 v27; // [sp+A0h] [bp-18h]@3 char *lineRGB; // [sp+A8h] [bp-10h]@3 int pitch; // [sp+ACh] [bp-Ch]@1 char v43; // [sp+B3h] [bp-5h]@18 int i; // [sp+B4h] [bp-4h]@6 unsigned short* line_picture_data; byte test_byte; unsigned char pict_byte; int num_r_bits = 5; int num_g_bits = 6; int num_b_bits = 5; int r_mask = 0xF800; int g_mask = 0x7E0; int b_mask = 0x1F; pitch = wight; if ( wight & 1 ) pitch = wight + 1; Src.left = 0; Src.up = 0; Src.right = wight - 1; Src.bottom = heidth - 1; v27.pitch = pitch; memset(&v20, 0, 0x30u); memset(&v18, 0, 0x38u); v8 = data_buff; v27.reserved = 0; *(_WORD *)&v18[56] = 0; Src.manufacturer = 10; Src.version = 5; Src.encoding = 1; Src.bpp = 8; Src.hdpi = 75; Src.vdpi = 75; v27.planes = 3; v27.palette_info = 1; memcpy(data_buff, &Src, 1); v8 = (char *)v8 + 1; memcpy(v8, &Src.version, 1); v8 = (char *)v8 + 1; memcpy(v8, &Src.encoding, 1); v8 = (char *)v8 + 1; memcpy(v8, &Src.bpp, 1); v8 = (char *)v8 + 1; memcpy(v8, &Src.left, 2); v8 = (char *)v8 + 2; memcpy(v8, &Src.up, 2); v8 = (char *)v8 + 2; memcpy(v8, &Src.right, 2); v8 = (char *)v8 + 2; memcpy(v8, &Src.bottom, 2); v8 = (char *)v8 + 2; memcpy(v8, &Src.hdpi, 2); v8 = (char *)v8 + 2; memcpy(v8, &Src.vdpi, 2); v8 = (char *)v8 + 2; memcpy(v8, &v20, 0x30u); v8 = (char *)v8 + 48; memcpy(v8, &v27, 1u); v8 = (char *)v8 + 1; memcpy(v8, &v27.planes, 1); v8 = (char *)v8 + 1; memcpy(v8, &v27.pitch, 2); v8 = (char *)v8 + 2; memcpy(v8, &v27.palette_info, 2); v8 = (char *)v8 + 2; memcpy(v8, &v18, 0x3Au); v9 = (char *)v8 + 58; lineRGB = (char*)malloc(3 * (wight + 2)); if ( heidth > 0 ) { v26 = 3 * pitch; v23 = 2 * wight; v11 = picture_data; v24 = (int)picture_data; for ( v25 = heidth; v25; v25-- ) { line_picture_data = v11; if ( wight > 0 ) { lineG = (char *)lineRGB + pitch; lineB = (char *)lineRGB + 2 * pitch; for ( uint i = 0; i < wight; i++ ) { lineRGB[i] = (signed int)(r_mask & *line_picture_data) >> (num_g_bits + num_b_bits + num_r_bits - 8); lineG[i] = (signed int)(g_mask & *line_picture_data) >> ( num_b_bits + num_g_bits- 8); lineB[i] = (b_mask & *line_picture_data) << (8 - num_b_bits); line_picture_data += 1; } } for ( i = 0; i < v26; v9 = (char *)v9 + 1 ) { pict_byte = lineRGB[i]; for ( test_byte = 1; test_byte < 63; ++test_byte ) { v15 = i + test_byte; if ( lineRGB[v15] != pict_byte )//Uninitialized memory access break; if ( !(v15 % pitch) ) break; } if ( i + test_byte > v26 ) test_byte = 3 * pitch - i; if ( test_byte > 1 || pict_byte >= 192 ) { v43 = test_byte | 0xC0; memcpy(v9, &v43, 1); v9 = (char *)v9 + 1; } memcpy(v9, &pict_byte, 1); i += test_byte; } v11 += wight; } } free(lineRGB); *(int *)packed_size = (char *)v9 - data_buff; } //----- (0049F8B5) -------------------------------------------------------- void Render::SavePCXImage(const char *Filename, unsigned short* picture_data, int width, int height) { FILE *result; // eax@1 FILE *pOutFile; // edi@4 unsigned short* v9; // eax@5 // int v10; // eax@7 signed int v12; // eax@12 // char v13; // zf@21 char v14[56]; // [sp+4h] [bp-A0h]@4 __int16 v15; // [sp+3Ch] [bp-68h]@4 char color_map[48]; // [sp+40h] [bp-64h]@4 int v18; // [sp+74h] [bp-30h]@5 // char *v19; // [sp+78h] [bp-2Ch]@5 int image_width; // [sp+7Ch] [bp-28h]@5 PCXHeader_1 header1; // [sp+80h] [bp-24h]@4 PCXHeader_2 header2; // [sp+90h] [bp-14h]@4 char *lineRGB; // [sp+98h] [bp-Ch]@4 int pitch; // [sp+9Ch] [bp-8h]@2 char *lineB; // [sp+A0h] [bp-4h]@8 char *lineG; unsigned short* line_pictute_data; byte test_byte; char v43; int num_r_bits = 5; int num_g_bits = 6; int num_b_bits = 5; int r_mask = 0xF800; int g_mask = 0x7E0; int b_mask = 0x1F; result = fopen(Filename, "wb"); Filename = (const char *)result; if ( result ) { pitch = width; if ( width & 1 ) pitch = width + 1; header1.left = 0; header1.up = 0; header1.right = width - 1; header1.bottom = height - 1; header2.pitch = pitch; memset(color_map, 0, sizeof(color_map)); header2.reserved = 0; memset(v14, 0, sizeof(v14)); v15 = 0; header1.manufacturer = 10; header1.version = 5; header1.encoding = 1; header1.bpp = 8; header1.hdpi = 75; header1.vdpi = 75; header2.planes = 3; header2.palette_info = 1; fwrite(&header1, 1, 1, (FILE *)Filename); pOutFile = (FILE *)Filename; fwrite(&header1.version, 1, 1, (FILE *)Filename); fwrite(&header1.encoding, 1, 1, pOutFile); fwrite(&header1.bpp, 1, 1, pOutFile); fwrite(&header1.left, 2, 1, pOutFile); fwrite(&header1.up, 2, 1, pOutFile); fwrite(&header1.right, 2, 1, pOutFile); fwrite(&header1.bottom, 2, 1, pOutFile); fwrite(&header1.hdpi, 2, 1, pOutFile); fwrite(&header1.vdpi, 2, 1, pOutFile); fwrite(color_map, 0x30u, 1, pOutFile); fwrite(&header2, 1, 1, pOutFile); fwrite(&header2.planes, 1, 1, pOutFile); fwrite(&header2.pitch, 2, 1, pOutFile); fwrite(&header2.palette_info, 2, 1, pOutFile); fwrite(v14, 0x3Au, 1, pOutFile); lineRGB = (char *)malloc(3 * (width + 2)); //При сохранении изображения подряд идущие пиксели одинакового цвета объединяются и вместо указания цвета для каждого пикселя //указывается цвет группы пикселей и их количество. image_width = 3 * pitch; v9 = picture_data; for ( v18 = 0; v18 < height; v18++ )//столбец { line_pictute_data = v9; lineG = (char *)lineRGB + pitch; lineB = (char *)lineRGB + 2 * pitch; for ( int i = 0; i < width; i++ )//строка { lineRGB[i] = (signed int)(r_mask & *line_pictute_data) >> (num_g_bits + num_b_bits + num_r_bits - 8); lineG[i] = (signed int)(g_mask & *line_pictute_data) >> (num_b_bits + num_g_bits - 8); lineB[i] = (b_mask & *line_pictute_data) << (8 - num_b_bits); line_pictute_data += 1; } test_byte = 1; for ( int i = 0; (signed int)i < image_width; i += test_byte ) { unsigned char pic_byte = lineRGB[i]; for ( test_byte; test_byte < 63; ++test_byte )// расчёт количества одинаковых цветов { v12 = i + test_byte; if ( lineRGB[v12] != pic_byte ) break; if ( !(v12 % pitch) ) break; } if ( i + test_byte > image_width ) test_byte = 3 * pitch - i; if ( test_byte > 1 || pic_byte >= 0xC0 ) { v43 = test_byte | 0xC0;//тест-байт объединения fwrite(&v43, 1, 1, pOutFile); } fwrite(&pic_byte, 1, 1, pOutFile); } v9 += width; } free(lineRGB); fclose(pOutFile); } } //----- (0049FBCD) -------------------------------------------------------- void Render::ClearTarget(unsigned int uColor) { //if (pRenderD3D) { if (using_software_screen_buffer) pRenderD3D->ClearTarget(true, uColor, false, 0.0); } //else //memset32(pTargetSurface, uColor, field_10 * field_14 / 2); } //----- (0049FC37) -------------------------------------------------------- void Render::Present() { //struct tagRECT Rect; // [sp+8h] [bp-28h]@11 //RECT a4; // [sp+18h] [bp-18h]@11 //struct tagPOINT Point; // [sp+28h] [bp-8h]@11 if ( !pRenderD3D || this->using_software_screen_buffer ) { this->pBeforePresentFunction(); if ( this->pRenderD3D ) { if ( this->using_software_screen_buffer ) pRenderD3D->Present(false); } else __debugbreak(); // no sr /*{ if ( this->bWindowMode ) { RestoreFrontBuffer(); GetClientRect(this->hWnd, &Rect); Point.y = 0; Point.x = 0; ClientToScreen(this->hWnd, &Point); OffsetRect(&Rect, Point.x, Point.y); a4.top = 0; a4.bottom = 480; a4.left = 0; a4.right = 640; PresentRect(&Rect, &a4); } else { RestoreFrontBuffer(); a4.top = 0; a4.bottom = 480; a4.left = 0; a4.right = 640; BltBackToFontFast(0, 0, &a4); } }*/ } } //----- (0049FD3A) -------------------------------------------------------- void Render::_49FD3A_fullscreen() { RECT src_rect; // [sp+8h] [bp-10h]@6 if ( this->pRenderD3D ) { if (pFrontBuffer4->IsLost() == DDERR_SURFACELOST) pFrontBuffer4->Restore(); if (pBackBuffer4->IsLost() == DDERR_SURFACELOST) pBackBuffer4->Restore(); src_rect.top = 0; src_rect.bottom = window->GetHeight(); src_rect.left = 0; src_rect.right = window->GetWidth(); this->pBackBuffer4->BltFast(NULL, NULL, this->pFrontBuffer4, &src_rect, DDBLTFAST_WAIT); } } //----- (0049FDBF) -------------------------------------------------------- void Render::CreateZBuffer() { if (!pDefaultZBuffer) { pDefaultZBuffer = pActiveZBuffer = (int *)malloc(0x12C000); memset32(pActiveZBuffer, 0xFFFF0000, 0x4B000u); // // inlined Render::ClearActiveZBuffer (mm8::004A085B) } } //----- (0049FE05) -------------------------------------------------------- void Render::Release() { //Render *v1; // esi@1 //RenderD3D *v2; // ecx@1 //char v3; // zf@4 //void *v4; // ebx@6 // IDirectDraw *v5; // eax@10 // IDirectDrawSurface2 *v6; // eax@11 // IDirectDrawSurface2 *v7; // eax@13 // IDirectDrawSurface2 *v8; // eax@15 // IDirectDraw2 *v9; // eax@17 // IDirectDraw4 *v10; // eax@19 // IDirectDrawSurface4 *v11; // eax@20 // IDirectDrawSurface4 *v12; // eax@22 // IDirectDrawSurface4 *v13; // eax@24 // IDirectDraw4 *v14; // eax@26 // unsigned __int16 **v15; // ebx@28 // void **v16; // esi@29 // v1 = this; if (pRenderD3D) { if ( this->using_software_screen_buffer ) { pRenderD3D->ClearTarget(true, 0, false, 1.0); pRenderD3D->Present(0); pRenderD3D->ClearTarget(true, 0, false, 1.0); } //this->pColorKeySurface4 = 0; this->pBackBuffer4 = nullptr; this->pFrontBuffer4 = nullptr; this->pDirectDraw4 = nullptr; delete [] this->pTargetSurface_unaligned; this->pTargetSurface = nullptr; this->pTargetSurface_unaligned = nullptr; if (pRenderD3D) { pRenderD3D->Release(); delete pRenderD3D; } pRenderD3D = nullptr; } else ;//__debugbreak(); // no sr /*{ if ( bWinNT4_0 == 1 ) { v5 = (IDirectDraw *)this->pDirectDraw2; if ( !v5 ) return; v5->SetCooperativeLevel(this->hWnd, 8u); this->pDirectDraw2->FlipToGDISurface(); v6 = this->pSomeSurface2; if ( v6 ) { v6->Release(); this->pSomeSurface2 = 0; } v7 = this->pBackBuffer2; if ( v7 ) { v7->Release(); this->pBackBuffer2 = 0; } v8 = this->pFrontBuffer2; if ( v8 ) { v8->Release(); this->pFrontBuffer2 = 0; } v9 = this->pDirectDraw2; if ( v9 ) { v9->Release(); this->pDirectDraw2 = 0; } } else { v10 = this->pDirectDraw4; if ( !v10 ) return; v10->SetCooperativeLevel(this->hWnd, 1032u); this->pDirectDraw4->FlipToGDISurface(); v11 = this->pColorKeySurface4; if ( v11 ) { v11->Release(); this->pColorKeySurface4 = 0; } v12 = this->pBackBuffer4; if ( v12 ) { v12->Release(); this->pBackBuffer4 = 0; } v13 = this->pFrontBuffer4; if ( v13 ) { v13->Release(); this->pFrontBuffer4 = 0; } v14 = this->pDirectDraw4; if ( v14 ) { v14->Release(); this->pDirectDraw4 = 0; } } v15 = &this->pTargetSurface; if ( this->pTargetSurface ) { v16 = (void **)&this->ptr_400E8; free(*v16); *v15 = 0; *v16 = 0; } }*/ } void Present32(unsigned __int32 *src, unsigned int src_pitch, unsigned __int32 *dst, unsigned int dst_pitch) { for (uint y = 0; y < 8; ++y) memcpy(dst + y * dst_pitch, src + y * src_pitch, src_pitch * sizeof(__int32)); for (uint y = 8; y < 352; ++y) { memcpy(dst + y * dst_pitch, src + y * src_pitch, 8 * sizeof(__int32)); memcpy(dst + 8 + game_viewport_width + y * dst_pitch, src + 8 + game_viewport_width + y * src_pitch, 174/*172*/ * sizeof(__int32)); } for (uint y = 352; y < 480; ++y) memcpy(dst + y * dst_pitch, src + y * src_pitch, src_pitch * sizeof(__int32)); for (uint y = pViewport->uViewportTL_Y; y < pViewport->uViewportBR_Y + 1; ++y) { for (uint x = pViewport->uViewportTL_X; x < pViewport->uViewportBR_X; ++x) { //if (src[x + y * src_pitch] != (pRenderer->uTargetGMask | pRenderer->uTargetBMask)) if (src[x + y * src_pitch] != 0xFF00FCF8) // FFF8FCF8 = Color32(Color16(g_mask | b_mask)) dst[x + y * dst_pitch] = src[x + y * src_pitch]; } } } //----- (004A597D) -------------------------------------------------------- void Present_NoColorKey() { void *v2; // edi@4 int v9; // eax@10 unsigned int v10; // esi@10 unsigned __int32 v11; // edi@10 unsigned int v13; // ebx@10 DDSURFACEDESC2 Dst; // [sp+Ch] [bp-98h]@3 int v21; // [sp+8Ch] [bp-18h]@10 __int32 v22; // [sp+90h] [bp-14h]@10 unsigned int v24; // [sp+98h] [bp-Ch]@4 int r_mask = 0xF800; int g_mask = 0x7E0; int b_mask = 0x1F; //if ( !pRenderer->uNumSceneBegins ) { //if ( pRenderer->using_software_screen_buffer ) //{ memset(&Dst, 0, sizeof(Dst)); Dst.dwSize = sizeof(Dst); if ( pRenderer->LockSurface_DDraw4(pRenderer->pBackBuffer4, &Dst, DDLOCK_WAIT) ) { //v26 = Dst.lpSurface; //pRenderer->pCurrentlyLockedSurfaceDataPtr = (unsigned __int16 *)Dst.lpSurface; v24 = g_mask | b_mask | ((g_mask | b_mask) << 16); //pRenderer->pCurrentlyLockedSoftSurface = pRenderer->pTargetSurface; //pRenderer->uCurrentlyLockedSurfacePitch = Dst.lPitch; //v1 = pRenderer->pTargetSurface; v2 = Dst.lpSurface; /*for (uint y = 0; y < 480; ++y) { auto pDst = (unsigned short *)((char *)Dst.lpSurface + y * Dst.lPitch); for (uint x = 0; x < 640; ++x) pDst[x] = pRenderer->uTargetRMask | pRenderer->uTargetBMask; }*/ if (!FORCE_16_BITS) Present32((unsigned __int32 *)pRenderer->pTargetSurface, pRenderer->uTargetSurfacePitch, (unsigned __int32 *)Dst.lpSurface, Dst.lPitch / 4); else { ushort* pSrc = (unsigned short *)pRenderer->pTargetSurface; short* pDst = (__int16 *)Dst.lpSurface; for (uint y = 0; y < 8; ++y) memcpy(pDst + y * Dst.lPitch / 2, pSrc + y * window->GetWidth(), window->GetWidth() * sizeof(__int16)); for (uint y = 8; y < 352; ++y) { memcpy(pDst + y * Dst.lPitch / 2, pSrc + y * window->GetWidth(), 8 * sizeof(__int16)); memcpy(pDst + 8 + game_viewport_width/*462*/ + y * Dst.lPitch / 2, pSrc + 8 + game_viewport_width/*462*/ + y * window->GetWidth(), 174/*172*/ * sizeof(__int16)); } for (uint y = 352; y < window->GetHeight(); ++y) memcpy(pDst + y * Dst.lPitch / 2, pSrc + y * window->GetWidth(), window->GetWidth() * sizeof(__int16)); ushort* pSrc_x1y1 = pSrc + window->GetWidth() * pViewport->uViewportTL_Y + pViewport->uViewportTL_X; //_this = (unsigned int)&pSrc[2 * (((signed int)pViewport->uViewportX >> 1) + 320 * pViewport->uViewportY)]; short* pDst_x1y1 = pDst + Dst.lPitch * pViewport->uViewportTL_Y + pViewport->uViewportTL_X; //v23 = (unsigned __int32)((char *)v26 + 4 * (((signed int)pViewport->uViewportX >> 1) + (Dst.lPitch >> 2) * pViewport->uViewportY)); v9 = ((signed int)pViewport->uViewportTL_X >> 1) - ((signed int)pViewport->uViewportBR_X >> 1); //v20 = ((signed int)pViewport->uViewportZ >> 1) - ((signed int)pViewport->uViewportX >> 1); v22 = 4 * ((Dst.lPitch / 4) + v9); v21 = 4 * v9 + 1280; //auto uNumLines = pViewport->uViewportW - pViewport->uViewportY + 1; //v26 = (LPVOID)(pViewport->uViewportW - pViewport->uViewportY + 1); v10 = (int)pSrc_x1y1; v11 = (int)pDst_x1y1; int uHalfWidth = (pViewport->uViewportBR_X - pViewport->uViewportTL_X) / 2; v13 = v24; for (uint y = pViewport->uViewportTL_Y; y < pViewport->uViewportBR_Y + 1; ++y) { //memcpy(pDst + pViewport->uViewportX + y * Dst.lPitch / 2, // pSrc + pViewport->uViewportX + y * 640, (pViewport->uViewportZ - pViewport->uViewportX) * sizeof(__int16)); for (uint x = pViewport->uViewportTL_X; x < pViewport->uViewportBR_X; ++x) { if (pSrc[y * window->GetWidth() + x] != (g_mask | b_mask)) pDst[y * Dst.lPitch / 2 + x] = pSrc[y * window->GetWidth() + x]; } } } ErrD3D(pRenderer->pBackBuffer4->Unlock(NULL)); /* while ( 1 ) { while ( 1 ) { v14 = *(int *)v10; v10 += 4; if ( v14 == v13 ) break; if ( (short)v14 == (short)v13 ) { *(int *)v11 = *(int *)v11 & 0xFFFF | v14 & 0xFFFF0000; v11 += 4; --uHalfWidth; if ( !uHalfWidth ) goto LABEL_21; } else { v15 = __ROL__(v14, 16); if ( (short)v15 == (short)v13 ) { v17 = __ROR__(v15, 16); *(int *)v11 = *(int *)v11 & 0xFFFF0000 | (unsigned __int16)v17; v11 += 4; --uHalfWidth; if ( !uHalfWidth ) goto LABEL_21; } else { v16 = __ROR__(v15, 16); *(int *)v11 = v16; v11 += 4; --uHalfWidth; if ( !uHalfWidth ) goto LABEL_21; } } } v11 += 4; --uHalfWidth; if ( !uHalfWidth ) { LABEL_21: v10 += v21; v11 += v22; uHalfWidth = v20; if ( !--uNumLines ) { ErrD3D(pRenderer->pBackBuffer4->Unlock(NULL)); return; } } }*/ } //} } } //----- (0049FFFB) -------------------------------------------------------- bool Render::InitializeFullscreen() { RenderD3D__DevInfo *v7; // ecx@5 bool v8; // eax@6 unsigned int v10; // eax@13 signed int v15; // ebx@31 int *v22; // eax@42 int v23; // ecx@42 D3DDEVICEDESC refCaps; // [sp+Ch] [bp-300h]@25 DDSURFACEDESC2 pDesc; // [sp+108h] [bp-204h]@40 D3DDEVICEDESC halCaps; // [sp+184h] [bp-188h]@25 int v29; // [sp+308h] [bp-4h]@2 //__debugbreak(); // Nomad this->using_software_screen_buffer = 0; //this->pColorKeySurface4 = 0; this->pBackBuffer4 = nullptr; this->pFrontBuffer4 = nullptr; this->pDirectDraw4 = nullptr; //this->bColorKeySupported = 0; Release(); //v3 = hWnd; this->window = window; CreateZBuffer(); /*if (!bUserDirect3D) { CreateDirectDraw(); SetDirectDrawCooperationMode(hWnd, 1); SetDirectDrawDisplayMode(640u, 480u, 16u); CreateDirectDrawPrimarySurface(); v15 = 1; } else {*/ pRenderD3D = new RenderD3D; //v28 = pRenderD3D; //v6 = uDesiredDirect3DDevice; v29 = -1; v7 = pRenderD3D->pAvailableDevices; if ( pRenderD3D->pAvailableDevices[uDesiredDirect3DDevice].bIsDeviceCompatible ) v8 = pRenderD3D->CreateDevice(uDesiredDirect3DDevice, /*0*/true, window); else { if ( v7[1].bIsDeviceCompatible ) v8 = pRenderD3D->CreateDevice(1, /*0*/true, window); else { if ( !v7->bIsDeviceCompatible ) Error("There aren't any D3D devices to create."); v8 = pRenderD3D->CreateDevice(0, /*0*/true, window); } } if ( !v8 ) Error("D3Drend->Init failed."); //v9 = pRenderD3D; pBackBuffer4 = pRenderD3D->pBackBuffer; pFrontBuffer4 = pRenderD3D->pFrontBuffer; pDirectDraw4 = pRenderD3D->pHost; v10 = pRenderD3D->GetDeviceCaps(); if ( v10 & 1 ) { if ( pRenderD3D ) { pRenderD3D->Release(); delete pRenderD3D; } pRenderD3D = nullptr; pBackBuffer4 = nullptr; pFrontBuffer4 = nullptr; pDirectDraw4 = nullptr; Error("Direct3D renderer: The device failed to return capabilities."); } if ( v10 & 0x3E ) { if ( pRenderD3D ) { pRenderD3D->Release(); delete pRenderD3D; } //pColorKeySurface4 = 0; pRenderD3D = nullptr; pBackBuffer4 = nullptr; pFrontBuffer4 = nullptr; pDirectDraw4 = nullptr; Error("Direct3D renderer: The device doesn't support the necessary alpha blending modes."); } if ( (v10 & 0x80) != 0 ) { if ( pRenderD3D ) { pRenderD3D->Release(); delete pRenderD3D; } pRenderD3D = nullptr; pBackBuffer4 = nullptr; pFrontBuffer4 = nullptr; pDirectDraw4 = nullptr; Error("Direct3D renderer: The device doesn't support non-square textures."); } //LOBYTE(field_10365C) = ~(unsigned __int8)(v10 >> 6) & 1; bRequiredTextureStagesAvailable = CheckTextureStages(); memset(&halCaps, 0, sizeof(halCaps)); halCaps.dwSize = sizeof(halCaps); memset(&refCaps, 0, sizeof(refCaps)); refCaps.dwSize = sizeof(refCaps); ErrD3D(pRenderD3D->pDevice->GetCaps(&halCaps, &refCaps)); uMinDeviceTextureDim = halCaps.dwMinTextureWidth; if ( (unsigned int)halCaps.dwMinTextureWidth >= halCaps.dwMinTextureHeight ) uMinDeviceTextureDim = halCaps.dwMinTextureHeight; uMinDeviceTextureDim = halCaps.dwMaxTextureWidth; if ( (unsigned int)halCaps.dwMaxTextureWidth < halCaps.dwMaxTextureHeight ) uMinDeviceTextureDim = halCaps.dwMaxTextureHeight; if ( (unsigned int)uMinDeviceTextureDim < 4 ) uMinDeviceTextureDim = 4; v15 = 1; ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, true)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, true)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, 2)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SPECULARENABLE, false)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_COLORKEYENABLE, false)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, false)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, 1)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, 2)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MINFILTER, 2)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, 3)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, 2)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, 0)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, 2)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, 2)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, 0)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLOROP, 4)); //} ddpfPrimarySuface.dwSize = 32; GetTargetPixelFormat(&ddpfPrimarySuface); ParseTargetPixelFormat(); if (!pRenderD3D) { __debugbreak(); pBeforePresentFunction = 0;//nullsub_1; } //else //{ /*v16 = IsColorKeySupported(pDirectDraw4); v17 = uAcquiredDirect3DDevice == v15; bColorKeySupported = v16; if ( !v17 ) bColorKeySupported = 0; if ( bColorKeySupported ) { memset(&ddsd2, 0, sizeof(ddsd2)); ddsd2.dwSize = sizeof(ddsd2); ddsd2.ddckCKSrcBlt.dwColorSpaceLowValue = uTargetGMask | uTargetBMask; ddsd2.ddckCKSrcBlt.dwColorSpaceHighValue = ddsd2.ddckCKSrcBlt.dwColorSpaceLowValue; ddsd2.dwFlags = 65543; ddsd2.ddsCaps.dwCaps = 2112; ddsd2.dwWidth = 640; ddsd2.dwHeight = 480; ErrD3D(pDirectDraw4->CreateSurface(&ddsd2, &pColorKeySurface4, NULL)); pBeforePresentFunction = Present_ColorKey; } else*/ { pTargetSurface = nullptr; pTargetSurface_unaligned = (unsigned int *)malloc(window->GetWidth() * window->GetHeight() * 2 + 32); if ( !pTargetSurface_unaligned ) return 0; memset(&pDesc, 0, sizeof(pDesc)); pDesc.dwSize = sizeof(pDesc); if ( !pRenderer->LockSurface_DDraw4(pRenderer->pBackBuffer4, &pDesc, v15) ) return 0; pBackBuffer4->Unlock(NULL); v22 = (int *)pTargetSurface_unaligned + 4; v23 = (unsigned int)pDesc.lpSurface & 7; LOBYTE(v22) = (unsigned __int8)v22 & 0xF8; uTargetSurfacePitch = window->GetWidth(); pBeforePresentFunction = Present_NoColorKey; v15 = 1; pTargetSurface = (unsigned __int32 *)((char *)v22 + 2 * v23); } using_software_screen_buffer = v15; //} bWindowMode = 0; pParty->uFlags |= 2; pViewport->SetFOV(flt_6BE3A0 * 65536.0f); return v15 != 0; } //----- (004A05F3) -------------------------------------------------------- bool Render::SwitchToWindow() { bool v7; // eax@7 unsigned int v9; // eax@12 int v12; // eax@24 int v13; // eax@26 D3DDEVICEDESC refCaps; // [sp+Ch] [bp-300h]@24 DDSURFACEDESC2 pDesc; // [sp+108h] [bp-204h]@37 D3DDEVICEDESC halCaps; // [sp+184h] [bp-188h]@24 int v29; // [sp+308h] [bp-4h]@2 pParty->uFlags |= PARTY_FLAGS_1_0002; pViewport->SetFOV(flt_6BE3A0 * 65536.0f); using_software_screen_buffer = 0; Release(); //pColorKeySurface4 = 0; pBackBuffer4 = nullptr; pFrontBuffer4 = nullptr; pDirectDraw4 = nullptr; //bColorKeySupported = 0; CreateZBuffer(); /*if (!bUserDirect3D) { CreateDirectDraw(); SetDirectDrawCooperationMode(hWnd, 0); field_4004C = 1; CreateFrontBuffer(); CreateClipper(hWnd); CreateBackBuffer(); field_40030 = 0; field_18_locked_pitch = 0; } else {*/ /*v3 = malloc(0x148u); thisa = (RenderD3D *)v3; v29 = 0; if ( v3 ) v4 = RenderD3D::RenderD3D((RenderD3D *)v3); else v4 = 0;*/ pRenderD3D = new RenderD3D; //v4 = pRenderD3D; //v5 = uDesiredDirect3DDevice; v29 = -1; //v6 = pRenderD3D->pAvailableDevices; if (pRenderD3D->pAvailableDevices[uDesiredDirect3DDevice].bIsDeviceCompatible && uDesiredDirect3DDevice != 1 ) { v7 = pRenderD3D->CreateDevice(uDesiredDirect3DDevice, true, window); } else { if ( !pRenderD3D->pAvailableDevices[0].bIsDeviceCompatible ) Error("There aren't any D3D devices to init."); v7 = pRenderD3D->CreateDevice(0, true, window); } if ( !v7 ) Error("D3Drend->Init failed."); //v8 = pRenderD3D; //pColorKeySurface4 = 0; pBackBuffer4 = pRenderD3D->pBackBuffer; pFrontBuffer4 = pRenderD3D->pFrontBuffer; pDirectDraw4 = pRenderD3D->pHost; v9 = pRenderD3D->GetDeviceCaps(); if ( v9 & 1 ) { if (pRenderD3D) { pRenderD3D->Release(); delete pRenderD3D; } pRenderD3D = nullptr; pBackBuffer4 = nullptr; pFrontBuffer4 = nullptr; pDirectDraw4 = nullptr; Error("Direct3D renderer: The device failed to return capabilities."); } if ( v9 & 0x3E ) { if (pRenderD3D) { pRenderD3D->Release(); delete pRenderD3D; } //pColorKeySurface4 = 0; pRenderD3D = nullptr; pBackBuffer4 = nullptr; pFrontBuffer4 = nullptr; pDirectDraw4 = nullptr; Error("Direct3D renderer: The device doesn't support the necessary alpha blending modes."); } if (v9 & 0x80) { if (pRenderD3D) { pRenderD3D->Release(); delete pRenderD3D; } pRenderD3D = nullptr; pBackBuffer4 = nullptr; pFrontBuffer4 = nullptr; pDirectDraw4 = nullptr; Error("Direct3D renderer: The device doesn't support non-square textures."); } //LOBYTE(field_10365C) = ~(unsigned __int8)(v9 >> 6) & 1; bRequiredTextureStagesAvailable = CheckTextureStages(); memset(&halCaps, 0, sizeof(halCaps)); halCaps.dwSize = sizeof(halCaps); memset(&refCaps, 0, sizeof(refCaps)); refCaps.dwSize = sizeof(refCaps); ErrD3D(pRenderD3D->pDevice->GetCaps(&halCaps, &refCaps)); v12 = halCaps.dwMinTextureWidth; if ( (unsigned int)halCaps.dwMinTextureWidth > halCaps.dwMinTextureHeight ) v12 = halCaps.dwMinTextureHeight; uMinDeviceTextureDim = v12; v13 = halCaps.dwMaxTextureWidth; if ( (unsigned int)halCaps.dwMaxTextureWidth < halCaps.dwMaxTextureHeight ) v13 = halCaps.dwMaxTextureHeight; uMaxDeviceTextureDim = v13; ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, 1)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, 1)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, 2)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SPECULARENABLE, 0)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_COLORKEYENABLE, 0)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, 1)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, 2)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MINFILTER, 2)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, 3)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, 2)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, 0)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, 2)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, 2)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, 0)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLOROP, 4)); //} ddpfPrimarySuface.dwSize = 32; GetTargetPixelFormat(&ddpfPrimarySuface); ParseTargetPixelFormat(); if ( !pRenderD3D ) { __debugbreak(); //pBeforePresentFunction = 0;//nullsub_1; //goto LABEL_47; } /*v14 = IsColorKeySupported(pDirectDraw4); v15 = uAcquiredDirect3DDevice == 1; bColorKeySupported = v14; if ( !v15 ) bColorKeySupported = 0;*/ //if ( bColorKeySupported ) if (false) { /*memset(&ddsd2, 0, 0x7Cu); ddsd2.ddckCKSrcBlt.dwColorSpaceLowValue = uTargetGMask | uTargetBMask; ddsd2.ddckCKSrcBlt.dwColorSpaceHighValue = ddsd2.ddckCKSrcBlt.dwColorSpaceLowValue; v16 = pDirectDraw4; ddsd2.dwSize = 124; ddsd2.dwFlags = 65543; ddsd2.ddsCaps.dwCaps = 2112; ddsd2.dwWidth = 640; ddsd2.dwHeight = 480; ErrD3D(v16->CreateSurface(&ddsd2, &pColorKeySurface4, NULL)); pBeforePresentFunction = Present_ColorKey;*/ using_software_screen_buffer = 1; //LABEL_47: bWindowMode = 1; //hWnd = hWnd; return 0; } pTargetSurface = 0; pTargetSurface_unaligned = 0; uint num_pixels = window->GetWidth() * window->GetHeight(); pTargetSurface_unaligned = new unsigned int[num_pixels]; if (!pTargetSurface_unaligned) return false; memset(&pDesc, 0, sizeof(pDesc)); pDesc.dwSize = sizeof(pDesc); if (!pRenderer->LockSurface_DDraw4(pRenderer->pBackBuffer4, &pDesc, DDLOCK_WAIT)) { delete [] pTargetSurface_unaligned; return false; } memset32(pTargetSurface_unaligned, -1, num_pixels); pRenderer->pBackBuffer4->Unlock(NULL); /*v19 = pTargetSurface_unaligned; v20 = (unsigned int)pDesc.lpSurface & 7; v21 = (unsigned int)ptr_400E8 & 7; if ( v21 == v20 ) pTargetSurface = (unsigned __int16 *)v19; else { if ( (signed int)v21 >= v20 ) v22 = (int)((char *)v19 + 2 * (v21 - v20) + 16); else v22 = (int)((char *)v19 + 2 * (v20 - v21) + 16); pTargetSurface = (unsigned __int16 *)v22; }*/ pTargetSurface = pTargetSurface_unaligned; uTargetSurfacePitch = window->GetWidth(); pBeforePresentFunction = Present_NoColorKey; using_software_screen_buffer = 1; bWindowMode = 1; return 0; } //----- (0044F2B2) -------------------------------------------------------- bool Render::IsGammaSupported() { // bool result; // eax@3 // HRESULT v1; // eax@4 //if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 ) { DDCAPS halCaps; // [sp+0h] [bp-180h]@4 memset(&halCaps, 0, sizeof(DDCAPS)); halCaps.dwSize = sizeof(DDCAPS); ErrD3D(pDirectDraw4->GetCaps(&halCaps, 0)); return (halCaps.dwCaps2 >> 17) & 1; } /*else return false;*/ } //----- (004A0BEE) -------------------------------------------------------- void Render::RasterLine2D(signed int uX, signed int uY, signed int uZ, signed int uW, unsigned __int16 uColor) { signed int lower_bound; // eax@17 // signed int left_bound; unsigned int v21; // edi@46 int v22; // esi@47 int v23; // ebx@47 signed int v24; // edx@50 signed int v25; // esi@52 unsigned __int16 *v26; // ecx@52 int v27; // ebx@54 int v28; // edi@55 int v29; // edx@55 int v30; // ebx@60 int v31; // edx@61 int v32; // edi@61 signed int upper_bound; // [sp+18h] [bp-4h]@28 unsigned int uXa; // [sp+24h] [bp+8h]@49 int uYb; // [sp+28h] [bp+Ch]@47 bool left_border_x = false; bool right_border_x = false; bool left_border_z = false; bool right_border_z = false; bool upper_border_y = false; bool bottom_border_y = false; bool upper_border_w = false; bool bottom_border_w = false; if ( uX < this->raster_clip_x )// x выходит за рамки левой границы left_border_x = true; if ( uX > this->raster_clip_z )// x выходит за рамки правой границы right_border_x = true; if ( uZ < this->raster_clip_x )// z выходит за рамки левой границы left_border_z = true; if ( uZ > this->raster_clip_z )// z выходит за рамки правой границы right_border_z = true; if ( uY < this->raster_clip_y )// y выходит за рамки верхней границы upper_border_y = true; if ( uY > this->raster_clip_w )// y выходит за рамки нижней границы bottom_border_y = true; if ( uW < this->raster_clip_y )// w выходит за рамки верхней границы upper_border_w = true; if ( uW > this->raster_clip_w )// w выходит за рамки нижней границы bottom_border_w = true; if ( (left_border_x && left_border_z) || (right_border_x && right_border_z ) || (upper_border_y && upper_border_w) || (bottom_border_y && bottom_border_w)) return; if ( left_border_x || left_border_z || right_border_x || right_border_z || upper_border_y || upper_border_w || bottom_border_y || bottom_border_w) { if ( left_border_x || left_border_z )//if ( (BYTE4(v36) ^ (unsigned __int8)v36) & 8 )//for left (левая граница) { if ( left_border_x )//left_border = true; х меньше левой границы { uY += (uW - uY) * ((this->raster_clip_x - uX) / (uZ - uX));//t = near_clip - v0.x / v1.x - v0.x (формула получения точки пересечения отрезка с плоскостью) uX = this->raster_clip_x; } else if ( left_border_z )//z меньше левой границы { uZ = this->raster_clip_x; uW += (uY - uW) * ((this->raster_clip_x - uZ) / (uX - uZ)); } } if ( right_border_x || right_border_z )//if ( (BYTE4(v36) ^ (unsigned __int8)v36) & 4 )//for right (правая граница) { if ( right_border_x ) //right_border = true; х больше правой границы { uY += (uY - uW) * ((this->raster_clip_z - uX) / (uZ - uX)); uX = this->raster_clip_z; } else if ( right_border_z )//z больше правой границы { uW += (uW - uY) * ((this->raster_clip_z - uZ) / (uX - uZ)); uZ = this->raster_clip_z; } } upper_bound = 0; if ( uY < this->raster_clip_y ) upper_bound = 2; if ( uY > this->raster_clip_w ) upper_bound |= 1; lower_bound = 0; if ( uW < this->raster_clip_y ) lower_bound = 2; if ( uW > this->raster_clip_w ) lower_bound |= 1; if ( !(lower_bound & upper_bound) )//for up and down(для верха и низа) { lower_bound ^= upper_bound; if ( lower_bound & 2 ) { if ( upper_bound & 2 ) { uX += (uZ - uX) * ((this->raster_clip_y - uY) / (uW - uY)); uY = this->raster_clip_y; } else { uZ += (uX - uZ) * ((this->raster_clip_y - uW) / (uY - uW)); uW = this->raster_clip_y; } } if ( lower_bound & 1 ) { if ( upper_bound & 1 ) { uX += (uZ - uX) * ((this->raster_clip_w - uY) / (uW - uY)); uY = this->raster_clip_w; } else { uZ += (uX - uZ) * ((this->raster_clip_w - uW) / (uY - uW)); uW = this->raster_clip_w; } } } } v21 = pRenderer->uTargetSurfacePitch; if ( pRenderer->uTargetSurfacePitch ) { //v12 = uX + uY * pRenderer->uTargetSurfacePitch; v22 = uW - uY; v23 = v22; uYb = v22; if ( v22 < 0 ) { v23 = -v22; uYb = -v22; v21 = -pRenderer->uTargetSurfacePitch; } uXa = uZ - uX; if ((signed)(uZ - uX) >= 0) v24 = 1; else { uXa = -uXa; v24 = -1; } v25 = 0; v26 = (unsigned __int16 *)this->pTargetSurface; if ( v26 ) { if ( (signed int)uXa <= v23 )//рисуем вертикальную линию { v30 = v23 + 1; if ( v30 > 0 ) { v31 = 2 * v24; v32 = 2 * v21; //v12 = (int)&v26[v12]; int y = 0; int x = 0; for ( v30; v30; --v30 ) { v25 += uXa; //*(short *)v12 = uColor; //v12 += v32; WritePixel16(uX + x, uY + y, uColor); if ( v32 >= 0 ) y += 1; else y -= 1; if ( v25 > 0 ) { v25 -= uYb; //v12 += v31; if ( v31 >= 0 ) x += 1; else x -= 1; } } } } else//рисуем горизонтальную линию { v27 = uXa + 1; if ( (signed int)(uXa + 1) > 0 ) { v28 = 2 * v21; v29 = 2 * v24; int y = 0; int x = 0; //v12 = (int)&v26[v12]; for ( v27; v27; --v27 ) { v25 += uYb; //*(short *)v12 = uColor; //v12 += v29; WritePixel16(uX + x, uY + y, uColor); if ( v29 >= 0 ) x += 1; else x -= 1; if ( v25 > (signed int)uXa ) { v25 -= uXa; //v12 += v28; if ( v28 >= 0 ) y += 1; else y -= 1; } } } } } } return; } //----- (004A0E80) -------------------------------------------------------- void Render::ClearZBuffer(int a2, int a3) { memset32(this->pActiveZBuffer, -65536, 0x4B000); } //----- (004A0E97) -------------------------------------------------------- void Render::SetRasterClipRect(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW) { this->raster_clip_x = uX; this->raster_clip_y = uY; this->raster_clip_z = uZ; this->raster_clip_w = uW; } //----- (004A0EB6) -------------------------------------------------------- void Render::ParseTargetPixelFormat() { signed int v2; // ecx@1 DWORD uRedMask; // edx@1 unsigned int uGreenMask; // esi@5 signed int v5; // ecx@5 unsigned int uBlueMask; // edx@9 signed int v7; // ecx@9 //unsigned int v8; // ecx@13 v2 = 0; uRedMask = this->ddpfPrimarySuface.dwRBitMask; this->uTargetBBits = 0; this->uTargetGBits = 0; this->uTargetRBits = 0; do { if ( (1 << v2) & uRedMask ) ++this->uTargetRBits; ++v2; } while ( v2 < 32 ); uGreenMask = this->ddpfPrimarySuface.dwGBitMask; v5 = 0; do { if ( (1 << v5) & uGreenMask ) ++this->uTargetGBits; ++v5; } while ( v5 < 32 ); uBlueMask = this->ddpfPrimarySuface.dwBBitMask; v7 = 0; do { if ( (1 << v7) & uBlueMask ) ++this->uTargetBBits; ++v7; } while ( v7 < 32 ); this->uTargetGMask = uGreenMask; this->uTargetRMask = this->ddpfPrimarySuface.dwRBitMask; this->uTargetBMask = uBlueMask; } //----- (004A0F40) -------------------------------------------------------- bool Render::LockSurface_DDraw4(IDirectDrawSurface4 *pSurface, DDSURFACEDESC2 *pDesc, unsigned int uLockFlags) { HRESULT result; // eax@1 HRESULT v6; // eax@4 char v9; // [sp+Bh] [bp-1h]@1 v9 = 1; result = pSurface->Lock(NULL, pDesc, uLockFlags, NULL); /* Когда объект DirectDrawSurface теряет поверхностную память, методы возвратят DDERR_SURFACELOST и не выполнят никакую другую функцию. Метод IDirectDrawSurface::Restore перераспределит поверхностную память и повторно присоединит ее к объекту DirectDrawSurface. */ if ( result == DDERR_SURFACELOST ) { v6 = pSurface->Restore();//Восстанавливает потерянную поверхность. Это происходит, когда поверхностная память, //связанная с объектом DirectDrawSurface была освобождена. if ( v6 ) { if ( v6 != DDERR_IMPLICITLYCREATED )//DDERR_IMPLICITLYCREATED - Поверхность не может быть восстановлена, //потому что она - неявно созданная поверхность. { v9 = 0; result = (bool)memset(pDesc, 0, 4); LOBYTE(result) = v9; return 0; } pRenderer->pFrontBuffer4->Restore(); pSurface->Restore(); } result = pSurface->Lock(NULL, pDesc, DDLOCK_WAIT, NULL); if ( result == DDERR_INVALIDRECT || result == DDERR_SURFACEBUSY )//DDERR_SURFACEBUSY - Доступ к этой поверхности отказан, //потому что поверхность блокирована другой нитью. DDERR_INVALIDRECT - Обеспечиваемый прямоугольник недопустим. { v9 = 0; result = (bool)memset(pDesc, 0, 4); LOBYTE(result) = v9; return result; } ErrD3D(result); if ( result ) { //v8 = 0; //v7 = 2161; //LABEL_19: //CheckHRESULT((CheckHRESULT_stru0 *)&pSurface, result, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Screen16.cpp", v7, v8); v9 = 0; result = (bool)memset(pDesc, 0, 4); LOBYTE(result) = v9; return result; } if ( pRenderD3D ) pRenderD3D->HandleLostResources(); result = pRenderer->pDirectDraw4->RestoreAllSurfaces(); } else { if ( result ) { if ( result == DDERR_INVALIDRECT || result == DDERR_SURFACEBUSY ) { v9 = 0; result = (bool)memset(pDesc, 0, 4); LOBYTE(result) = v9; return result; } ErrD3D(result); //v8 = 0; //v7 = 2199; //goto LABEL_19; } } return true; } //----- (004A10E4) -------------------------------------------------------- void Render::CreateDirectDraw() { //Render *v1; // edi@1 // HRESULT v2; // eax@1 // HRESULT v3; // eax@5 // int v6; // [sp-Ch] [bp-20h]@3 // unsigned int v9; // [sp+0h] [bp-14h]@0 IDirectDraw *lpDD; // [sp+10h] [bp-4h]@1 //v1 = this; ErrD3D(DirectDrawCreate(0, &lpDD, 0)); pDirectDraw4 = nullptr; ErrD3D(lpDD->QueryInterface(IID_IDirectDraw4, (void **)&pDirectDraw4)); lpDD->Release(); lpDD = nullptr; } //----- (004A1169) -------------------------------------------------------- void Render::SetDirectDrawCooperationMode(HWND hWnd, bool bFullscreen) { DWORD flags; // eax@1 //Установка взаимодействия для полноэкранного и оконного режимов flags = bFullscreen ? DDSCL_NORMAL | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN : DDSCL_NORMAL; ErrD3D(pDirectDraw4->SetCooperativeLevel(hWnd, flags | DDSCL_MULTITHREADED)); } //----- (004A11C6) -------------------------------------------------------- void Render::SetDirectDrawDisplayMode(unsigned int uWidth, unsigned int uHeight, unsigned int uBPP) { ErrD3D(pDirectDraw4->SetDisplayMode(uWidth, uHeight, uBPP, 0, 0)); } //----- (004A121C) -------------------------------------------------------- void Render::CreateFrontBuffer() { //Render *v1; // esi@1 IDirectDraw *pDD; // eax@3 IDirectDrawSurface **pOutSurf; // esi@3 struct _DDSURFACEDESC *v4; // edx@3 //// HRESULT v5; // eax@5 int v6; // [sp-8h] [bp-8Ch]@3 DDSURFACEDESC2 a2; // [sp+4h] [bp-80h]@3 //v1 = this; //if (pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || //pVersion->pVersionInfo.dwMajorVersion != 4 ) { memset(&a2, 0, sizeof(a2)); a2.dwSize = sizeof(a2); pDD = (IDirectDraw *)this->pDirectDraw4; a2.dwFlags = 1; a2.ddsCaps.dwCaps = 512;//DDSCAPS_PRIMARYSURFACE = 0x200 v6 = 2357; pOutSurf = (IDirectDrawSurface **)&this->pFrontBuffer4; v4 = (struct _DDSURFACEDESC *)&a2; } /*else { memset(&a2.lPitch, 0, 0x6Cu); // DDSURFACEDESC here pDD = (IDirectDraw *)v1->pDirectDraw2; a2.lPitch = 108; a2.dwBackBufferCount = 1; a2.dwTextureStage = 512; v6 = 2346; pOutSurf = (IDirectDrawSurface **)&v1->pFrontBuffer2; v4 = (struct _DDSURFACEDESC *)&a2.lPitch; }*/ ErrD3D(pDD->CreateSurface(v4, pOutSurf, NULL)); } //----- (004A12CD) -------------------------------------------------------- void Render::CreateBackBuffer() { //Render *v1; // esi@1 IDirectDraw *v2; // eax@3 IDirectDrawSurface **ppBackBuffer; // esi@3 struct _DDSURFACEDESC *v4; // edx@3 // HRESULT v5; // eax@5 int v6; // [sp-8h] [bp-8Ch]@3 unsigned int v7; // [sp-4h] [bp-88h]@3 DDSURFACEDESC2 a2; // [sp+4h] [bp-80h]@3 //v1 = this; //if (pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || // pVersion->pVersionInfo.dwMajorVersion != 4 ) { memset(&a2, 0, sizeof(a2)); a2.dwSize = sizeof(a2); v2 = (IDirectDraw *)this->pDirectDraw4; a2.dwFlags = 7; a2.ddsCaps.dwCaps = 2112;//0x840 = DDSCAPS_SYSTEMMEMORY = 0x800 | DDSCAPS_OFFSCREENPLAIN = 0x40 a2.dwWidth = window->GetWidth(); a2.dwHeight = window->GetHeight(); v7 = 0; v6 = 2387; ppBackBuffer = (IDirectDrawSurface **)&this->pBackBuffer4; v4 = (struct _DDSURFACEDESC *)&a2; } /*else { memset(&a2.lPitch, 0, 0x6Cu); v2 = (IDirectDraw *)v1->pDirectDraw2; a2.lPitch = 108; a2.dwBackBufferCount = 7; v7 = 0; a2.dwTextureStage = 2112; a2.dwAlphaBitDepth = 640; a2.dwMipMapCount = 480; v6 = 2374; ppBackBuffer = (IDirectDrawSurface **)&v1->pBackBuffer2; v4 = (struct _DDSURFACEDESC *)&a2.lPitch; // //DDSURFACEDESC here fo ddraw2 }*/ ErrD3D(v2->CreateSurface(v4, ppBackBuffer, NULL)); } //----- (004A139A) -------------------------------------------------------- void Render::CreateDirectDrawPrimarySurface() { IDirectDrawSurface *pFrontBuffer; // eax@3 DDSCAPS2 *v6; // edx@3 IDirectDraw4 *v7; // eax@4 int v9; // ST14_4@5 IDirectDrawSurface *v10; // ST10_4@5 IDirectDrawSurface **ppBackBuffer; // [sp-4h] [bp-A4h]@3 DDSURFACEDESC2 ddsd2; // [sp+Ch] [bp-94h]@3 DDSCAPS2 v17; // [sp+88h] [bp-18h]@4 //v1 = this; //if (pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || //pVersion->pVersionInfo.dwMajorVersion != 4 ) { //v2 = 0; //this->field_4004C = 1; memset(&ddsd2, 0, sizeof(ddsd2)); ddsd2.dwSize = sizeof(ddsd2); ddsd2.dwBackBufferCount = 1; ddsd2.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd2.ddsCaps.dwCaps = DDSCAPS_COMPLEX | DDSCAPS_FLIP | DDSCAPS_3DDEVICE | DDSCAPS_PRIMARYSURFACE; ErrD3D(this->pDirectDraw4->CreateSurface(&ddsd2, &pFrontBuffer4, NULL)); pFrontBuffer = (IDirectDrawSurface *)this->pFrontBuffer4; ppBackBuffer = (IDirectDrawSurface **)&this->pBackBuffer4; } /*else { v2 = 0; this->field_4004C = 1; DDSURFACEDESC ddsd; memset(&ddsd, 0, sizeof(DDSURFACEDESC)); ddsd.lpSurface = (LPVOID)1; ddsd.lPitch = 108; ddsd.dwBackBufferCount = 33; ddsd.ddsCaps.dwCaps = 8728; ErrD3D(pDirectDraw2->CreateSurface(&ddsd, (IDirectDrawSurface **)&pFrontBuffer2, NULL)); pFrontBuffer = (IDirectDrawSurface *)v1->pFrontBuffer2; ppBackBuffer = (IDirectDrawSurface **)&v1->pBackBuffer2; }*/ __debugbreak(); // warning C4700: uninitialized local variable 'v6' used v9 = (int)v6; v10 = pFrontBuffer; // BUG v17.dwCaps = 4; ErrD3D(pFrontBuffer->GetAttachedSurface((DDSCAPS *)&v17, ppBackBuffer));// hr = this->pFrontBuffer->GetAttachedSurface(&ddsCaps2, ppBackBuffer); //CheckHRESULT(&thisa, v11, (const char *)v10, v9, (unsigned int)ppBackBuffer); //v1->field_40030 = v2; //v1->field_18_locked_pitch = v2; } //----- (004A14F4) -------------------------------------------------------- void Render::CreateClipper(HWND a2) { ErrD3D(pDirectDraw4->CreateClipper(0, &pDDrawClipper, NULL)); ErrD3D(pDDrawClipper->SetHWnd(0, a2)); ErrD3D(pFrontBuffer4->SetClipper(pDDrawClipper)); } //----- (004A15D8) -------------------------------------------------------- void Render::GetTargetPixelFormat(DDPIXELFORMAT *pOut) { pFrontBuffer4->GetPixelFormat(pOut); } //----- (004A1605) -------------------------------------------------------- void Render::LockRenderSurface(void **pOutSurfacePtr, unsigned int *pOutPixelsPerRow) { signed int v4; // eax@3 //if (pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || //pVersion->pVersionInfo.dwMajorVersion != 4 ) { DDSURFACEDESC2 pDesc; // [sp+4h] [bp-7Ch]@3 memset(&pDesc, 0, sizeof(pDesc)); pDesc.dwSize = sizeof(pDesc); LockSurface_DDraw4(this->pBackBuffer4, &pDesc, DDLOCK_WAIT); *pOutSurfacePtr = pDesc.lpSurface; v4 = pDesc.lPitch; } /*else { DDSURFACEDESC pDesc; // [sp+4h] [bp-7Ch]@3 memset(&pDesc.lPitch, 0, 0x6Cu); pDesc.lPitch = 108; LockSurface_DDraw2(this->pBackBuffer2, &pDesc, 1); *pOutSurfacePtr = (void *)pDesc.lpSurface; v4 = pDesc.dwReserved; }*/ *pOutPixelsPerRow = v4 >> 1; } //----- (004A16E1) -------------------------------------------------------- void Render::UnlockBackBuffer() { ErrD3D(pBackBuffer4->Unlock(NULL)); } //----- (004A172E) -------------------------------------------------------- void Render::LockFrontBuffer(void **pOutSurface, unsigned int *pOutPixelsPerRow) { signed int v4; // eax@3 //if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 ) { DDSURFACEDESC2 pDesc; // [sp+4h] [bp-7Ch]@3 memset(&pDesc, 0, sizeof(pDesc)); pDesc.dwSize = sizeof(pDesc); LockSurface_DDraw4(this->pFrontBuffer4, &pDesc, DDLOCK_WAIT); *pOutSurface = pDesc.lpSurface; v4 = pDesc.lPitch; } /*else { DDSURFACEDESC pDesc; // [sp+4h] [bp-7Ch]@3 memset(&pDesc.lPitch, 0, 0x6Cu); pDesc.lPitch = 108; LockSurface_DDraw2(this->pFrontBuffer2, &pDesc, 1); *pOutSurface = (void *)pDesc.lpSurface; v4 = pDesc.dwReserved; }*/ *pOutPixelsPerRow = v4 >> 1; } //----- (004A17C7) -------------------------------------------------------- void Render::UnlockFrontBuffer() { ErrD3D(pFrontBuffer4->Unlock(NULL)); } //----- (004A1814) -------------------------------------------------------- void Render::RestoreFrontBuffer() { if (pFrontBuffer4->IsLost() == DDERR_SURFACELOST ) pFrontBuffer4->Restore(); } //----- (004A184C) -------------------------------------------------------- void Render::RestoreBackBuffer() { if ( pBackBuffer4->IsLost() == DDERR_SURFACELOST ) pBackBuffer4->Restore(); } //----- (004A18F5) -------------------------------------------------------- void Render::BltToFront(RECT *pDstRect, IDirectDrawSurface *pSrcSurface, RECT *pSrcRect, unsigned int uBltFlags) { ErrD3D(pFrontBuffer4->Blt(pDstRect, (IDirectDrawSurface4 *)pSrcSurface, pSrcRect, uBltFlags, nullptr)); } //----- (004A194A) -------------------------------------------------------- void Render::BltBackToFontFast(int a2, int a3, RECT *pSrcRect) { IDirectDrawSurface *pFront; // eax@3 IDirectDrawSurface *pBack; // [sp-Ch] [bp-Ch]@3 //if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 ) { pFront = (IDirectDrawSurface *)this->pFrontBuffer4; pBack = (IDirectDrawSurface *)this->pBackBuffer4; } /*else { pFront = (IDirectDrawSurface *)this->pFrontBuffer2; pBack = (IDirectDrawSurface *)this->pBackBuffer2; }*/ pFront->BltFast(NULL, NULL, pBack, pSrcRect, DDBLTFAST_WAIT); } //----- (004A1B22) -------------------------------------------------------- unsigned int Render::Billboard_ProbablyAddToListAndSortByZOrder(float z) { unsigned int v7; // edx@6 if (uNumBillboardsToDraw >= 999 ) return 0; if (!uNumBillboardsToDraw) { uNumBillboardsToDraw = 1; return 0; } for (int left = 0, right = uNumBillboardsToDraw; left < right; ) // binsearch { v7 = left + (right - left) / 2; if (z <= pRenderer->pBillboardRenderListD3D[v7].z_order) right = v7; else left = v7 + 1; } if (z > pRenderer->pBillboardRenderListD3D[v7].z_order ) { if ( v7 == pRenderer->uNumBillboardsToDraw - 1 ) v7 = pRenderer->uNumBillboardsToDraw; else { if ( (signed int)pRenderer->uNumBillboardsToDraw > (signed int)v7 ) { for ( uint i = 0; i < pRenderer->uNumBillboardsToDraw - v7; i++ ) { memcpy(&pRenderer->pBillboardRenderListD3D[pRenderer->uNumBillboardsToDraw - i], &pRenderer->pBillboardRenderListD3D[pRenderer->uNumBillboardsToDraw - (i + 1)], sizeof(pRenderer->pBillboardRenderListD3D[pRenderer->uNumBillboardsToDraw - i])); } } ++v7; } uNumBillboardsToDraw++; return v7; } if (z <= pRenderer->pBillboardRenderListD3D[v7].z_order ) { if ( (signed int)pRenderer->uNumBillboardsToDraw > (signed int)v7 ) { for ( uint i = 0; i < pRenderer->uNumBillboardsToDraw - v7; i++ ) { memcpy(&pRenderer->pBillboardRenderListD3D[pRenderer->uNumBillboardsToDraw - i], &pRenderer->pBillboardRenderListD3D[pRenderer->uNumBillboardsToDraw -(i + 1)], sizeof(pRenderer->pBillboardRenderListD3D[pRenderer->uNumBillboardsToDraw - i])); } } uNumBillboardsToDraw++; return v7; } return v7; } //----- (004A1E9D) -------------------------------------------------------- unsigned int Render::GetBillboardDrawListSize() { return pRenderer->uNumBillboardsToDraw; } //----- (004A1EA3) -------------------------------------------------------- unsigned int Render::GetParentBillboardID(unsigned int uBillboardID) { return pRenderer->pBillboardRenderListD3D[uBillboardID].sParentBillboardID; } //----- (004A1EB6) -------------------------------------------------------- void Render::BeginSceneD3D() { if (!uNumD3DSceneBegins++) { //if (pRenderD3D) { pRenderD3D->ClearTarget(true, 0x00F08020, true, 1.0); pRenderer->uNumBillboardsToDraw = 0; pRenderD3D->pDevice->BeginScene(); if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor ) uFogColor = GetLevelFogColor(); else uFogColor = 0; if ( uFogColor & 0xFF000000 ) { pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 1); pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, uFogColor & 0xFFFFFF); pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, 0); bUsingSpecular = true; } else { pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 0); bUsingSpecular = 0; } } /*else { LockRenderSurface((void **)&pTargetSurface, &uTargetSurfacePitch); if (pTargetSurface) field_18_locked_pitch = uTargetSurfacePitch; else --uNumD3DSceneBegins; }*/ } } //----- (004A1FE1) -------------------------------------------------------- void Render::DrawBillboards_And_MaybeRenderSpecialEffects_And_EndScene() { --uNumD3DSceneBegins; if (uNumD3DSceneBegins) return; if (pRenderD3D) { pGame->draw_debug_outlines(); DoRenderBillboards_D3D(); pGame->pStru6Instance->RenderSpecialEffects(); pRenderD3D->pDevice->EndScene(); } else pGame->pStru6Instance->RenderSpecialEffects(); } //----- (004A2031) -------------------------------------------------------- unsigned int Render::GetActorTintColor(float a2, int tint, int a4, int a5, RenderBillboard *a6) { // __debugbreak(); // should not fire outside decal builder return ::GetActorTintColor(tint, a4, a2, a5, a6); } /*void Render::DrawTerrainPolygon_new(Polygon *a3, IDirect3DTexture2 *pTexture)//new function { int v5; // ebx@1 int v6; // edi@1 int v8; // eax@7 float v9; // eax@12 float *v10; // esi@12 float v11; // ecx@14 double v12; // st7@14 double v13; // st7@14 double v14; // st7@14 signed int v15; // eax@14 int v16; // eax@15 float v17; // ST48_4@15 char v18; // zf@17 int v19; // eax@18 int v20; // eax@18 int v21; // edx@20 signed int v22; // ecx@20 int v23; // eax@20 const char *v24; // ST4C_4@20 unsigned int v25; // ST50_4@20 int v26; // ST54_4@20 int v27; // eax@20 _UNKNOWN *v28; // eax@21 int v29; // ecx@23 int v30; // eax@23 int v31; // eax@23 int v32; // eax@24 int v33; // eax@25 int v34; // eax@25 int v35; // eax@25 int v36; // eax@25 signed int v37; // ecx@26 int v38; // eax@26 _UNKNOWN *v39; // eax@27 int v40; // edx@28 int v41; // eax@29 int v42; // eax@29 int v43; // eax@29 int v44; // eax@29 unsigned int v46; // eax@29 int v47; // eax@30 int v48; // eax@30 int v49; // eax@30 double v52; // st6@35 const char *v55; // [sp+4Ch] [bp-1Ch]@20 int v57; // [sp+5Ch] [bp-Ch]@3 signed int v59; // [sp+60h] [bp-8h]@12 int v61; // [sp+64h] [bp-4h]@4 int i; v6 = (int)this; v5 = 0; if (!this->uNumD3DSceneBegins) return; this->pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP); this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE); if (this->bUsingSpecular) { this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE); this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO); } pVertices[0].pos.x = array_50AC10[0].vWorldViewProjX; pVertices[0].pos.y = array_50AC10[0].vWorldViewProjY; pVertices[0].pos.z = 1.0 - 1.0 / (1000 * array_50AC10[0].vWorldViewPosition.x / (double)pODMRenderParams->shading_dist_mist); pVertices[0].rhw = 1.0 / (array_50AC10[0].vWorldViewPosition.x + 0.0000001000000011686097); pVertices[0].diffuse = GetActorTintColor(a3->field_58, 0, array_50AC10[0].vWorldViewPosition.x, 0, 0); pVertices[0].specular = 0; pVertices[0].texcoord.x = array_50AC10[0].u; pVertices[0].texcoord.y = array_50AC10[0].v; pVertices[1].pos.x = array_50AC10[3].vWorldViewProjX; pVertices[1].pos.y = array_50AC10[3].vWorldViewProjY; pVertices[1].pos.z = 1.0 - 1.0 / (1000 * array_50AC10[3].vWorldViewPosition.x / (double)pODMRenderParams->shading_dist_mist); pVertices[1].rhw = 1.0 / (array_50AC10[3].vWorldViewPosition.x + 0.0000001000000011686097); pVertices[1].diffuse = GetActorTintColor(a3->field_58, 0, array_50AC10[3].vWorldViewPosition.x, 0, 0); pVertices[1].specular = 0; pVertices[1].texcoord.x = array_50AC10[3].u; pVertices[1].texcoord.y = array_50AC10[3].v; pVertices[2].pos.x = array_50AC10[1].vWorldViewProjX; pVertices[2].pos.y = array_50AC10[1].vWorldViewProjY; pVertices[2].pos.z = 1.0 - 1.0 / (1000 * array_50AC10[1].vWorldViewPosition.x / (double)pODMRenderParams->shading_dist_mist); pVertices[2].rhw = 1.0 / (array_50AC10[1].vWorldViewPosition.x + 0.0000001000000011686097); pVertices[2].diffuse = GetActorTintColor(a3->field_58, 0, array_50AC10[1].vWorldViewPosition.x, 0, 0); pVertices[2].specular = 0; pVertices[2].texcoord.x = array_50AC10[1].u; pVertices[2].texcoord.y = array_50AC10[1].v; memcpy(pVertices + 3, pVertices + 2, sizeof(RenderVertexD3D3)); memcpy(pVertices + 4, pVertices + 1, sizeof(RenderVertexD3D3)); pVertices[5].pos.x = array_50AC10[2].vWorldViewProjX; pVertices[5].pos.y = array_50AC10[2].vWorldViewProjY; pVertices[5].pos.z = 1.0 - 1.0 / (1000 * array_50AC10[2].vWorldViewPosition.x / (double)pODMRenderParams->shading_dist_mist); pVertices[5].rhw = 1.0 / (array_50AC10[2].vWorldViewPosition.x + 0.0000001000000011686097); pVertices[5].diffuse = GetActorTintColor(a3->field_58, 0, array_50AC10[2].vWorldViewPosition.x, 0, 0); pVertices[5].specular = 0; pVertices[5].texcoord.x = array_50AC10[2].u; pVertices[5].texcoord.y = array_50AC10[2].v; this->pRenderD3D->pDevice->SetTexture(0, pTexture); this->pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, pVertices, 6, D3DDP_DONOTLIGHT); }*/ //----- (004A26BC) -------------------------------------------------------- void Render::DrawTerrainPolygon(unsigned int uNumVertices, struct Polygon *a4, IDirect3DTexture2 *a5, bool transparent, bool clampAtTextureBorders) { unsigned int v8; // ebx@1 int v11; // eax@5 int v20; // eax@14 unsigned int v45; // eax@28 v8 = 0; if (!this->uNumD3DSceneBegins) return; if ( uNumVertices < 3) return; //v61 = pVertices; /* v9 = pGame->pLightmapBuilder; v65 = v9; v10 = v9->std__vector_000004_size;*/ if ( byte_4D864C && pGame->uFlags & GAME_FLAGS_1_01_lightmap_related) { v11 = ::GetActorTintColor(a4->dimming_level, 0, array_50AC10[0].vWorldViewPosition.x, 0, 0); pGame->pLightmapBuilder->DrawLightmaps(/*v11, 0*/); } else { if (transparent || !pGame->pLightmapBuilder->std__vector_000004_size || byte_4D864C && pGame->uFlags & 2 ) { if (clampAtTextureBorders) this->pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP); else this->pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP); if (transparent || this->bUsingSpecular) { this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); if (transparent) { this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA); this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA); //this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ZERO); //this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE); } else { this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE); this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO); } } for (uint i = 0; i < uNumVertices; ++i) { d3d_vertex_buffer[i].pos.x = array_50AC10[i].vWorldViewProjX; d3d_vertex_buffer[i].pos.y = array_50AC10[i].vWorldViewProjY; d3d_vertex_buffer[i].pos.z = 1.0 - 1.0 / ((array_50AC10[i].vWorldViewPosition.x * 1000) / (double)pODMRenderParams->shading_dist_mist); d3d_vertex_buffer[i].rhw = 1.0 / (array_50AC10[i].vWorldViewPosition.x + 0.0000001); d3d_vertex_buffer[i].diffuse = ::GetActorTintColor(a4->dimming_level, 0, array_50AC10[i].vWorldViewPosition.x, 0, 0); if ( this->bUsingSpecular ) { d3d_vertex_buffer[i].specular = sub_47C3D7_get_fog_specular(0, 0, array_50AC10[i].vWorldViewPosition.x); } else { d3d_vertex_buffer[i].specular = 0; } d3d_vertex_buffer[i].texcoord.x = array_50AC10[i].u; d3d_vertex_buffer[i].texcoord.y = array_50AC10[i].v; } this->pRenderD3D->pDevice->SetTexture(0, a5); this->pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, d3d_vertex_buffer, uNumVertices, 16); if (transparent) { ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); } } else { for (uint i = 0; i < uNumVertices; ++i) { d3d_vertex_buffer[i].pos.x = array_50AC10[i].vWorldViewProjX; d3d_vertex_buffer[i].pos.y = array_50AC10[i].vWorldViewProjY; d3d_vertex_buffer[i].pos.z = 1.0 - 1.0 / ((array_50AC10[i].vWorldViewPosition.x * 1000) / (double)pODMRenderParams->shading_dist_mist); d3d_vertex_buffer[i].rhw = 1.0 / (array_50AC10[i].vWorldViewPosition.x + 0.0000001); d3d_vertex_buffer[i].diffuse = GetActorTintColor(a4->dimming_level, 0, array_50AC10[i].vWorldViewPosition.x, 0, 0); if ( this->bUsingSpecular ) { d3d_vertex_buffer[i].specular = sub_47C3D7_get_fog_specular(0, 0, array_50AC10[i].vWorldViewPosition.x); } else { d3d_vertex_buffer[i].specular = 0; } __debugbreak(); // warning C4700: uninitialized local variable 'v20' used d3d_vertex_buffer[i].specular = v20; d3d_vertex_buffer[i].texcoord.x = array_50AC10[i].u; d3d_vertex_buffer[i].texcoord.y = array_50AC10[i].v; } ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); if (pRenderer->bUsingSpecular) ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE)); ErrD3D(pRenderD3D->pDevice->SetTexture(0, 0)); ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, d3d_vertex_buffer, uNumVertices, 16)); //v63 = (const char *)v7->pRenderD3D->pDevice; ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE)); //(*(void (**)(void))(*(int *)v63 + 88))(); pGame->pLightmapBuilder->DrawLightmaps(/*-1, 0*/); for (uint i = 0; i < uNumVertices; ++i) { d3d_vertex_buffer[i].diffuse = -1; } ErrD3D(pRenderD3D->pDevice->SetTexture(0, a5)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); if ( !pRenderer->bUsingSpecular ) { ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); } ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ZERO)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_SRCCOLOR)); ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, d3d_vertex_buffer, uNumVertices, 16)); if ( pRenderer->bUsingSpecular ) { ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); ErrD3D(pRenderD3D->pDevice->SetTexture(0, 0)); for (uint i = 0; i < uNumVertices; ++i) { d3d_vertex_buffer[i].diffuse = pRenderer->uFogColor | d3d_vertex_buffer[i].specular & 0xFF000000; d3d_vertex_buffer[i].specular = 0; } ErrD3D(pRenderD3D->pDevice->SetTexture(0, 0));//problem ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_INVSRCALPHA)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_SRCALPHA)); ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, d3d_vertex_buffer, uNumVertices, 16)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE)); //v44 = pRenderer->pRenderD3D->pDevice; v45 = GetLevelFogColor(); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, v45 & 0xFFFFFF)); v8 = 0; ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, 0)); } ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, v8)); } } //if (pIndoorCamera->flags & INDOOR_CAMERA_DRAW_TERRAIN_OUTLINES || pBLVRenderParams->uFlags & INDOOR_CAMERA_DRAW_TERRAIN_OUTLINES) if (pGame->pIndoorCameraD3D->debug_flags & ODM_RENDER_DRAW_TERRAIN_OUTLINES) pGame->pIndoorCameraD3D->debug_outline_d3d(d3d_vertex_buffer, uNumVertices, 0x00FFFFFF, 0.0); } // 4A26BC: could not find valid save-restore pair for esi // 4D864C: using guessed type char byte_4D864C; //----- (004A2DA3) -------------------------------------------------------- void Render::DrawOutdoorSkyPolygon(unsigned int uNumVertices, struct Polygon *pSkyPolygon, IDirect3DTexture2 *pTexture) { int v7; // eax@7 if ( !this->uNumD3DSceneBegins ) return; if ( uNumVertices >= 3 ) { this->pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP); if ( this->bUsingSpecular ) { this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE); this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO); } for ( uint i = 0; i < uNumVertices; ++i ) { pVertices[i].pos.x = array_50AC10[i].vWorldViewProjX; pVertices[i].pos.y = array_50AC10[i].vWorldViewProjY; pVertices[i].pos.z = 0.99989998; pVertices[i].rhw = array_50AC10[i]._rhw; pVertices[i].diffuse = ::GetActorTintColor(31, 0, array_50AC10[i].vWorldViewPosition.x, 1, 0); v7 = 0; if (this->bUsingSpecular) v7 = sub_47C3D7_get_fog_specular(0, 1, array_50AC10[i].vWorldViewPosition.x); pVertices[i].specular = v7; pVertices[i].texcoord.x = array_50AC10[i].u; pVertices[i].texcoord.y = array_50AC10[i].v; } pRenderD3D->pDevice->SetTexture(0, pTexture); pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, pVertices, uNumVertices, D3DDP_DONOTUPDATEEXTENTS | D3DDP_DONOTLIGHT); } } //----- (004A2ED5) -------------------------------------------------------- void Render::DrawIndoorSkyPolygon(signed int uNumVertices, struct Polygon *pSkyPolygon, IDirect3DTexture2 *pTexture) { int v5; // eax@3 if ( this->uNumD3DSceneBegins ) { if ( uNumVertices >= 3 ) { ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); v5 = 31 - (pSkyPolygon->dimming_level & 0x1F); if ( v5 < pOutdoor->max_terrain_dimming_level ) v5 = pOutdoor->max_terrain_dimming_level; for (uint i = 0; i < (unsigned int)uNumVertices; ++i) { d3d_vertex_buffer[i].pos.x = array_507D30[i].vWorldViewProjX; d3d_vertex_buffer[i].pos.y = array_507D30[i].vWorldViewProjY; d3d_vertex_buffer[i].pos.z = 1.0 - 1.0 / (array_507D30[i].vWorldViewPosition.x * 0.061758894); d3d_vertex_buffer[i].rhw = array_507D30[i]._rhw; d3d_vertex_buffer[i].diffuse = 8 * v5 | ((8 * v5 | (v5 << 11)) << 8); d3d_vertex_buffer[i].specular = 0; d3d_vertex_buffer[i].texcoord.x = array_507D30[i].u; d3d_vertex_buffer[i].texcoord.y = array_507D30[i].v; } ErrD3D(pRenderD3D->pDevice->SetTexture(0, pTexture)); ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, d3d_vertex_buffer, uNumVertices, 28)); } } } //----- (00479A53) -------------------------------------------------------- void Render::DrawIndoorSky(unsigned int uNumVertices, unsigned int uFaceID) { BLVFace *pFace; // esi@1 double v5; // st7@3 signed __int64 v6; // qax@3 int v12; // edx@7 int v13; // eax@7 int v17; // edi@9 double v18; // st7@9 signed int v19; // ebx@9 void *v20; // ecx@9 int v21; // ebx@11 int v22; // eax@14 signed __int64 v23; // qtt@16 double v28; // st7@20 double v33; // st6@23 const void *v35; // ecx@31 int v36; // eax@31 const void *v37; // edi@31 signed __int64 v38; // qax@31 int v39; // ecx@31 int v40; // ebx@33 int v41; // eax@36 signed __int64 v42; // qtt@39 int v43; // eax@39 double v48; // st7@41 double v51; // st7@46 struct Polygon pSkyPolygon; // [sp+14h] [bp-160h]@6 unsigned int v63; // [sp+120h] [bp-54h]@7 unsigned int v65; // [sp+128h] [bp-4Ch]@1 unsigned int v66; // [sp+12Ch] [bp-48h]@7 __int64 v69; // [sp+13Ch] [bp-38h]@3 int v70; // [sp+144h] [bp-30h]@3 int X; // [sp+148h] [bp-2Ch]@9 int v72; // [sp+14Ch] [bp-28h]@7 float v73; // [sp+150h] [bp-24h]@16 unsigned int v74; // [sp+154h] [bp-20h]@3 unsigned int v74_; // [sp+154h] [bp-20h]@3 RenderVertexSoft *v75; // [sp+158h] [bp-1Ch]@3 float v76; // [sp+15Ch] [bp-18h]@9 int v77; // [sp+160h] [bp-14h]@9 int v78; // [sp+164h] [bp-10h]@7 void *v79; // [sp+168h] [bp-Ch]@9 float v80; // [sp+16Ch] [bp-8h]@3 const void *v81; // [sp+170h] [bp-4h]@7 pFace = &pIndoor->pFaces[uFaceID]; //for floor and wall(for example Selesta)------------------- if (pFace->uPolygonType == POLYGON_InBetweenFloorAndWall || pFace->uPolygonType == POLYGON_Floor) { int v69 = (GetTickCount() / 32) - pGame->pIndoorCameraD3D->vPartyPos.x; int v55 = (GetTickCount() / 32) + pGame->pIndoorCameraD3D->vPartyPos.y; for (uint i = 0; i < uNumVertices; ++i) { array_507D30[i].u = (v69 + array_507D30[i].u) * 0.25f; array_507D30[i].v = (v55 + array_507D30[i].v) * 0.25f; } pRenderer->DrawIndoorPolygon(uNumVertices, pFace, pBitmaps_LOD->pHardwareTextures[pFace->uBitmapID], pFace->GetTexture(), PID(OBJECT_BModel, uFaceID), -1, 0); return; } //--------------------------------------- v70 = (signed __int64)((double)(pBLVRenderParams->fov_rad_fixpoint * pGame->pIndoorCameraD3D->vPartyPos.z)//179 / (((double)pBLVRenderParams->fov_rad_fixpoint + 16192.0) * 65536.0) + (double)pBLVRenderParams->uViewportCenterY); v5 = (double)pGame->pIndoorCameraD3D->sRotationX * 0.0030664064;//0 v6 = (signed __int64)((double)pBLVRenderParams->uViewportCenterY//183 - (double)pBLVRenderParams->fov_rad_fixpoint / ((cos(v5) * 16192.0 + 0.0000001) * 65535.0) * (sin(v5) * -16192.0 - (double)pGame->pIndoorCameraD3D->vPartyPos.z)); stru_8019C8._48653D_frustum_blv(65536, 0, 0, 0, 65536, 0); pSkyPolygon.Create_48607B(&stru_8019C8); pSkyPolygon.uTileBitmapID = pFace->uBitmapID; pSkyPolygon.pTexture = pBitmaps_LOD->GetTexture(pSkyPolygon.uTileBitmapID); if ( !pSkyPolygon.pTexture ) return; pSkyPolygon.dimming_level = 0; pSkyPolygon.uNumVertices = uNumVertices; pSkyPolygon.v_18.x = -stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationX + 16); pSkyPolygon.v_18.y = 0; pSkyPolygon.v_18.z = -stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationX + 16); memcpy(&array_507D30[uNumVertices], array_507D30, sizeof(array_507D30[uNumVertices])); pSkyPolygon.field_24 = 0x2000000; extern float _calc_fov(int viewport_width, int angle_degree); //v64 = (double)(signed int)(pBLVRenderParams->uViewportZ - pBLVRenderParams->uViewportX) * 0.5; //v72 = 65536 / (signed int)(signed __int64)(v64 / tan(0.6457717418670654) + 0.5); v72 = 65536.0f / _calc_fov(pBLVRenderParams->uViewportZ - pBLVRenderParams->uViewportX, 74); v12 = pSkyPolygon.pTexture->uWidthMinus1; v13 = pSkyPolygon.pTexture->uHeightMinus1; //v67 = 1.0 / (double)pSkyPolygon.pTexture->uTextureWidth; v63 = 224 * pMiscTimer->uTotalGameTimeElapsed & v13; v66 = 224 * pMiscTimer->uTotalGameTimeElapsed & v12; v78 = 0; //v81 = 0; float v68 = 1.0 / (double)pSkyPolygon.pTexture->uTextureHeight; if ( (signed int)pSkyPolygon.uNumVertices <= 0 ) return; int _507D30_idx = 0; for ( _507D30_idx; _507D30_idx < pSkyPolygon.uNumVertices; _507D30_idx++ ) { //v15 = (void *)(v72 * (v70 - (int)array_507D30[_507D30_idx].vWorldViewProjY)); v77 = fixpoint_mul(pSkyPolygon.ptr_38->viewing_angle_from_west_east, v72 * (v70 - array_507D30[_507D30_idx].vWorldViewProjY)); v74 = v77 + pSkyPolygon.ptr_38->angle_from_north; v77 = fixpoint_mul(pSkyPolygon.ptr_38->viewing_angle_from_north_south, v72 * (v70 - array_507D30[_507D30_idx].vWorldViewProjY)); v74_ = v77 + pSkyPolygon.ptr_38->angle_from_east; v79 = (void *)(fixpoint_mul(pSkyPolygon.v_18.z, v72 * (v70 - (int)array_507D30[_507D30_idx].vWorldViewProjY))); v17 = v72 * (pBLVRenderParams->uViewportCenterX - (int)array_507D30[_507D30_idx].vWorldViewProjX); v18 = array_507D30[_507D30_idx].vWorldViewProjY - 1.0; v19 = -pSkyPolygon.field_24; v77 = -pSkyPolygon.field_24; X = (int)((char *)v79 + pSkyPolygon.v_18.x); LODWORD(v76) = (signed __int64)v18; v20 = (void *)(v72 * (v70 - LODWORD(v76))); while ( 1 ) { v79 = v20; if ( !X ) goto LABEL_14; v21 = abs(v19 >> 14); if ( v21 <= abs(X) )//0x800 <= 0x28652 break; if ( SLODWORD(v76) <= (signed int)pViewport->uViewportTL_Y ) break; v19 = v77; v20 = v79; LABEL_14: v79 = (void *)fixpoint_mul(pSkyPolygon.v_18.z, (int)v20); v22 = fixpoint_mul(pSkyPolygon.v_18.z, (int)v20); --LODWORD(v76); v20 = (char *)v20 + v72; X = v22 + pSkyPolygon.v_18.x; v78 = 1; } if ( !v78 ) { LODWORD(v23) = v77 << 16; HIDWORD(v23) = v77 >> 16;//v23 = 0xfffffe0000000000 v79 = (void *)(v23 / X);//X = FFFF9014(-28652) v77 = v17; signed __int64 s = v74 + fixpoint_mul(pSkyPolygon.ptr_38->angle_from_west, v17);// s = 0xFFFFFFFF FFFF3EE6 LODWORD(v80) = v66 + ((signed int)fixpoint_mul(SLODWORD(s), v23 / X) >> 4); array_507D30[_507D30_idx].u = ((double)SLODWORD(v80) * 0.000015259022) * (1.0 / (double)pSkyPolygon.pTexture->uTextureWidth); signed __int64 s2 = v74_ + fixpoint_mul(pSkyPolygon.ptr_38->angle_from_south, v17); LODWORD(v80) = v63 + ((signed int)fixpoint_mul(SLODWORD(s2), v23 / X) >> 4); array_507D30[_507D30_idx].v = ((double)SLODWORD(v80) * 0.000015259022) * v68; v77 = fixpoint_mul(SLODWORD(s), v23 / X); LODWORD(v73) = fixpoint_mul(SLODWORD(s2), v23 / X); array_507D30[_507D30_idx]._rhw = 65536.0 / (double)(signed int)v79; //if ( (int)v81 >= pSkyPolygon.uNumVertices ) //{ // pRenderer->DrawIndoorSkyPolygon(pSkyPolygon.uNumVertices, &pSkyPolygon, // pBitmaps_LOD->pHardwareTextures[(signed __int16)pSkyPolygon.uTileBitmapID]); // return; //} continue; } break; } if ( _507D30_idx >= pSkyPolygon.uNumVertices ) { pRenderer->DrawIndoorSkyPolygon(pSkyPolygon.uNumVertices, &pSkyPolygon, pBitmaps_LOD->pHardwareTextures[(signed __int16)pSkyPolygon.uTileBitmapID]); return; } LODWORD(v73) = 0; v80 = v76; if ( (signed int)pSkyPolygon.uNumVertices > 0 ) { v28 = (double)SLODWORD(v76); LODWORD(v76) = (int)(char *)array_50AC10 + 28; uint i = 0; for ( v78 = pSkyPolygon.uNumVertices; v78; --v78 ) { ++LODWORD(v73); memcpy(&array_50AC10[i], &array_507D30[i], 0x30u); LODWORD(v76) += 48; if ( v28 < array_507D30[i].vWorldViewProjY | v28 == array_507D30[i].vWorldViewProjY || v28 >= array_507D30[i + 1].vWorldViewProjY ) { if ( v28 >= array_507D30[i].vWorldViewProjY || v28 <= array_507D30[i + 1].vWorldViewProjY ) { i++; continue; } v33 = (array_507D30[i + 1].vWorldViewProjX - array_507D30[i].vWorldViewProjX) * v28 / (array_507D30[i + 1].vWorldViewProjY - array_507D30[i].vWorldViewProjY) + array_507D30[i + 1].vWorldViewProjX; } else { v33 = (array_507D30[i].vWorldViewProjX - array_507D30[i + 1].vWorldViewProjX) * v28 / (array_507D30[i].vWorldViewProjY - array_507D30[i + 1].vWorldViewProjY) + array_507D30[i].vWorldViewProjX; } array_50AC10[i + 1].vWorldViewProjX = v33; ++LODWORD(v73); *(unsigned int *)LODWORD(v76) = v28; LODWORD(v76) += 48; i++; } } if ( SLODWORD(v73) <= 0 ) goto LABEL_40; //v34 = (char *)&array_50AC10[0].vWorldViewProjY; uint j = 0; v65 = v77 >> 14; //HIDWORD(v69) = LODWORD(v73); for ( int t = (int)LODWORD(v73); t > 1; t-- ) { v35 = (const void *)(v72 * (v70 - (unsigned __int64)(signed __int64)array_50AC10[j].vWorldViewProjY)); //v78 = pSkyPolygon.ptr_38->viewing_angle_from_west_east; //v81 = (const void *)fixpoint_mul(pSkyPolygon.ptr_38->viewing_angle_from_west_east, v35); v36 = (int)(fixpoint_mul(pSkyPolygon.ptr_38->viewing_angle_from_west_east, (int)v35) + pSkyPolygon.ptr_38->angle_from_north); v81 = v35; v74 = v36; //v78 = pSkyPolygon.ptr_38->viewing_angle_from_north_south; v81 = (const void *)fixpoint_mul(pSkyPolygon.ptr_38->viewing_angle_from_north_south, (int)v35); v78 = (int)v35; v75 = (RenderVertexSoft *)((char *)v81 + pSkyPolygon.ptr_38->angle_from_east); //v81 = (const void *)pSkyPolygon.v_18.z; v78 = fixpoint_mul(pSkyPolygon.v_18.z, (int)v35); v37 = (const void *)(v72 * (pBLVRenderParams->uViewportCenterX - (unsigned __int64)(signed __int64)array_50AC10[j].vWorldViewProjX)); v38 = (signed __int64)(array_50AC10[j].vWorldViewProjY - 1.0); v81 = 0; LODWORD(v76) = v38; v39 = v72 * (v70 - v38); while ( 1 ) { v78 = v39; if ( !X ) goto LABEL_36; v40 = abs(X); if ( abs((signed __int64)v65) <= v40 ) break; if ( SLODWORD(v76) <= (signed int)pViewport->uViewportTL_Y ) break; v39 = v78; LABEL_36: v78 = pSkyPolygon.v_18.z; v41 = fixpoint_mul(pSkyPolygon.v_18.z, v39); --LODWORD(v76); v39 += v72; X = v41 + pSkyPolygon.v_18.x; v81 = (const void *)1; } if ( v81 ) { v79 = (void *)pSkyPolygon.v_18.z; v78 = 2 * LODWORD(v76); v81 = (const void *)fixpoint_mul(pSkyPolygon.v_18.z, (((double)v70 - ((double)(2 * LODWORD(v76)) - array_50AC10[j].vWorldViewProjY)) * (double)v72)); X = (int)((char *)v81 + pSkyPolygon.v_18.x); } LODWORD(v42) = v77 << 16; HIDWORD(v42) = v77 >> 16; v79 = (void *)(v42 / X); v81 = v37; //v78 = pSkyPolygon.ptr_38->angle_from_west; v81 = (const void *)fixpoint_mul(pSkyPolygon.ptr_38->angle_from_west, (int)v37); v43 = v74 + fixpoint_mul(pSkyPolygon.ptr_38->angle_from_west, (int)v37); v74 = (unsigned int)v37; LODWORD(v76) = v43; //v78 = pSkyPolygon.ptr_38->angle_from_south; v75 = (RenderVertexSoft *)((char *)v75 + fixpoint_mul(pSkyPolygon.ptr_38->angle_from_south, (int)v37)); //v74 = fixpoint_mul(v43, v42 / X); v81 = (const void *)fixpoint_mul((int)v75, v42 / X); //v34 += 48; //v78 = v66 + ((signed int)fixpoint_mul(v43, v42 / X) >> 4); //v44 = HIDWORD(v69)-- == 1; //v45 = (double)(v66 + ((signed int)fixpoint_mul(v43, v42 / X) >> 4)) * 0.000015259022; //v78 = v63 + ((signed int)fixpoint_mul((int)v75, v42 / X) >> 4); array_50AC10[j].u = ((double)(v66 + ((signed int)fixpoint_mul(v43, v42 / X) >> 4)) * 0.000015259022) * (1.0 / (double)pSkyPolygon.pTexture->uTextureWidth); array_50AC10[j].v = ((double)(v66 + ((signed int)fixpoint_mul(v43, v42 / X) >> 4)) * 0.000015259022) * v68; //v46 = (double)(signed int)v79; array_50AC10[j].vWorldViewPosition.x = 0.000015258789 * (double)(signed int)v79; array_50AC10[j]._rhw = 65536.0 / (double)(signed int)v79; ++j; } //while ( !v44 ); LABEL_40: uint i = 0; if ( SLODWORD(v73) > 0 ) { v48 = (double)SLODWORD(v80); for ( HIDWORD(v69) = LODWORD(v73); HIDWORD(v69); --HIDWORD(v69) ) { if ( v48 >= array_50AC10[i].vWorldViewProjY ) { ++i; memcpy(&array_507D30[i], &array_50AC10[i], 0x30u); } } } pSkyPolygon.uNumVertices = i; pRenderer->DrawIndoorSkyPolygon(pSkyPolygon.uNumVertices, &pSkyPolygon, pBitmaps_LOD->pHardwareTextures[(signed __int16)pSkyPolygon.uTileBitmapID]); int pNumVertices = 0; if ( SLODWORD(v73) > 0 ) { v51 = (double)SLODWORD(v80); for ( v80 = v73; v80 != 0.0; --LODWORD(v80) ) { if ( v51 <= array_50AC10[pNumVertices].vWorldViewProjY ) { ++pNumVertices; memcpy(&array_507D30[pNumVertices], &array_50AC10[pNumVertices], 0x30u); } } } pRenderer->DrawIndoorSkyPolygon(pNumVertices, &pSkyPolygon, pBitmaps_LOD->pHardwareTextures[(signed __int16)pSkyPolygon.uTileBitmapID]); } //----- (004A2FC0) -------------------------------------------------------- void Render::DrawIndoorPolygon(unsigned int uNumVertices, BLVFace *pFace, IDirect3DTexture2 *pHwTex, Texture *pTex, int uPackedID, unsigned int uColor, int a8) { if (!uNumD3DSceneBegins || uNumVertices < 3) return; //auto a3 = pFace; //auto a6 = uPackedID; //v59 = pGame->pLightmapBuilder; //v9 = v59->std__vector_000004_size; int sCorrectedColor = uColor; if (pGame->pLightmapBuilder->std__vector_000004_size) sCorrectedColor = -1; pGame->AlterGamma_BLV(pFace, &sCorrectedColor); if (pFace->uAttributes & FACE_OUTLINED) { // int color; if (GetTickCount() % 300 >= 150) uColor = sCorrectedColor = 0xFF20FF20; else uColor = sCorrectedColor = 0xFF109010; } if (byte_4D864C && pGame->uFlags & GAME_FLAGS_1_01_lightmap_related) { __debugbreak(); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); for (uint i = 0; i < uNumVertices; ++i) { d3d_vertex_buffer[i].pos.x = array_507D30[i].vWorldViewProjX; d3d_vertex_buffer[i].pos.y = array_507D30[i].vWorldViewProjY; d3d_vertex_buffer[i].pos.z = 1.0 - 1.0 / (array_507D30[i].vWorldViewPosition.x * 0.061758894); d3d_vertex_buffer[i].rhw = 1.0 / array_507D30[i].vWorldViewPosition.x; d3d_vertex_buffer[i].diffuse = sCorrectedColor; d3d_vertex_buffer[i].specular = 0; d3d_vertex_buffer[i].texcoord.x = array_507D30[i].u / (double)pTex->uTextureWidth; d3d_vertex_buffer[i].texcoord.y = array_507D30[i].v / (double)pTex->uTextureHeight; } ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr)); ErrD3D(pRenderD3D->pDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, d3d_vertex_buffer, uNumVertices, 28)); pGame->pLightmapBuilder->DrawLightmaps(/*-1, 0*/); } else { if (!pGame->pLightmapBuilder->std__vector_000004_size || byte_4D864C && pGame->uFlags & 2) { for (uint i = 0; i < uNumVertices; ++i) { d3d_vertex_buffer[i].pos.x = array_507D30[i].vWorldViewProjX; d3d_vertex_buffer[i].pos.y = array_507D30[i].vWorldViewProjY; d3d_vertex_buffer[i].pos.z = 1.0 - 1.0 / (array_507D30[i].vWorldViewPosition.x * 0.061758894); d3d_vertex_buffer[i].rhw = 1.0 / array_507D30[i].vWorldViewPosition.x; d3d_vertex_buffer[i].diffuse = sCorrectedColor; d3d_vertex_buffer[i].specular = 0; d3d_vertex_buffer[i].texcoord.x = array_507D30[i].u / (double)pTex->uTextureWidth; d3d_vertex_buffer[i].texcoord.y = array_507D30[i].v / (double)pTex->uTextureHeight; } ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); ErrD3D(pRenderD3D->pDevice->SetTexture(0, pHwTex)); ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, d3d_vertex_buffer, uNumVertices, 28)); } else { for (uint i = 0; i < uNumVertices; ++i) { d3d_vertex_buffer[i].pos.x = array_507D30[i].vWorldViewProjX; d3d_vertex_buffer[i].pos.y = array_507D30[i].vWorldViewProjY; d3d_vertex_buffer[i].pos.z = 1.0 - 1.0 / (array_507D30[i].vWorldViewPosition.x * 0.061758894); d3d_vertex_buffer[i].rhw = 1.0 / array_507D30[i].vWorldViewPosition.x; d3d_vertex_buffer[i].diffuse = uColor; d3d_vertex_buffer[i].specular = 0; d3d_vertex_buffer[i].texcoord.x = array_507D30[i].u / (double)pTex->uTextureWidth; d3d_vertex_buffer[i].texcoord.y = array_507D30[i].v / (double)pTex->uTextureHeight; } //__debugbreak(); //if ( (signed int)uNumVertices > 0 ) //{ //v23 = pTex; //v24 = (char *)&array_507D30[0].vWorldViewPosition; //v25 = (char *)&d3d_vertex_buffer[0].pos.y; //pTex = (Texture *)uNumVertices; //uint v18; //do //{ //v26 = *(float *)v24 * 0.061758894; //v27 = *((int *)v24 + 3); //*((int *)v25 + 4) = 0; //*((int *)v25 - 1) = v27; //*(int *)v25 = *((int *)v24 + 4); //*((int *)v25 + 3) = uColor; //v25 += 32; //*((float *)v25 - 7) = 1.0 - 1.0 / v26; //v28 = 1.0 / *(float *)v24; //v24 += 48; //v18 = pTex == (Texture *)1; //pTex = (Texture *)((char *)pTex - 1); //*((float *)v25 - 6) = v28; //a3 = (BLVFace *)v23->uTextureWidth; //*((float *)v25 - 3) = *((float *)v24 - 6) / (double)(signed int)v23->uTextureWidth; //a3 = (BLVFace *)v23->uTextureHeight; //*((float *)v25 - 2) = *((float *)v24 - 5) / (double)(signed int)v23->uTextureHeight; //} //while ( !v18 ); //} ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr)); ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, d3d_vertex_buffer, uNumVertices, 28)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE)); pGame->pLightmapBuilder->DrawLightmaps(/*-1, 0*/); for (uint i = 0; i < uNumVertices; ++i) d3d_vertex_buffer[i].diffuse = sCorrectedColor; /*v33 = uNumVertices; if ( (signed int)uNumVertices > 0 ) { v34 = (char *)&d3d_vertex_buffer[0].diffuse; do { *(int *)v34 = uCorrectedColor; v34 += 32; --v33; } while ( v33 ); }*/ ErrD3D(pRenderD3D->pDevice->SetTexture(0, pHwTex)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ZERO)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_SRCCOLOR)); ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, d3d_vertex_buffer, uNumVertices, 28)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); } } } // 4D864C: using guessed type char byte_4D864C; //----- (004A43B1) -------------------------------------------------------- void Render::DrawBillboard_Indoor(RenderBillboardTransform_local0 *pSoftBillboard, Sprite *pSprite, int dimming_level) { unsigned int v7; // eax@2 signed int v11; // eax@9 signed int v12; // eax@9 double v15; // st5@12 double v16; // st4@12 double v17; // st3@12 double v18; // st2@12 int v19; // ecx@14 double v20; // st3@14 int v21; // ecx@16 double v22; // st3@16 float v27; // [sp+24h] [bp-Ch]@5 int v28; // [sp+28h] [bp-8h]@2 float v29; // [sp+2Ch] [bp-4h]@5 float v31; // [sp+3Ch] [bp+Ch]@5 float a1; // [sp+40h] [bp+10h]@5 if ( this->uNumD3DSceneBegins ) { //v4 = pSoftBillboard; //v5 = (double)pSoftBillboard->zbuffer_depth; //pSoftBillboarda = pSoftBillboard->zbuffer_depth; //v6 = pSoftBillboard->zbuffer_depth; v7 = Billboard_ProbablyAddToListAndSortByZOrder(pSoftBillboard->zbuffer_depth); //v8 = dimming_level; //v9 = v7; v28 = dimming_level & 0xFF000000; if ( dimming_level & 0xFF000000 ) pBillboardRenderListD3D[v7].opacity = RenderBillboardD3D::Opaque_3; else pBillboardRenderListD3D[v7].opacity = RenderBillboardD3D::Transparent; //v10 = a3; pBillboardRenderListD3D[v7].field_90 = pSoftBillboard->field_44; pBillboardRenderListD3D[v7].sZValue = pSoftBillboard->sZValue; pBillboardRenderListD3D[v7].sParentBillboardID = pSoftBillboard->sParentBillboardID; //v25 = pSoftBillboard->uScreenSpaceX; //v24 = pSoftBillboard->uScreenSpaceY; a1 = (pSoftBillboard->_screenspace_x_scaler_packedfloat & 0xFFFF) * 0.000015260186 + HIWORD(pSoftBillboard->_screenspace_x_scaler_packedfloat); v29 = (pSoftBillboard->_screenspace_y_scaler_packedfloat & 0xFFFF) * 0.000015260186 + HIWORD(pSoftBillboard->_screenspace_y_scaler_packedfloat); v31 = (double)((pSprite->uBufferWidth >> 1) - pSprite->uAreaX); v27 = (double)(pSprite->uBufferHeight - pSprite->uAreaY); if ( pSoftBillboard->uFlags & 4 ) v31 = v31 * -1.0; if ( pSoftBillboard->sTintColor && this->bTinting ) { v11 = ::GetActorTintColor(dimming_level, 0, pSoftBillboard->zbuffer_depth, 0, 0); v12 = BlendColors(pSoftBillboard->sTintColor, v11); if ( v28 ) v12 = (unsigned int)((char *)&array_77EC08[1852].pEdgeList1[17] + 3) & ((unsigned int)v12 >> 1); } else { v12 = ::GetActorTintColor(dimming_level, 0, pSoftBillboard->zbuffer_depth, 0, 0); } //v13 = (double)v25; pBillboardRenderListD3D[v7].pQuads[0].specular = 0; pBillboardRenderListD3D[v7].pQuads[0].diffuse = v12; pBillboardRenderListD3D[v7].pQuads[0].pos.x = pSoftBillboard->uScreenSpaceX - v31 * a1; //v14 = (double)v24; //v32 = v14; pBillboardRenderListD3D[v7].pQuads[0].pos.y = pSoftBillboard->uScreenSpaceY - v27 * v29; v15 = 1.0 - 1.0 / (pSoftBillboard->zbuffer_depth * 0.061758894); pBillboardRenderListD3D[v7].pQuads[0].pos.z = v15; v16 = 1.0 / pSoftBillboard->zbuffer_depth; pBillboardRenderListD3D[v7].pQuads[0].rhw = 1.0 / pSoftBillboard->zbuffer_depth; pBillboardRenderListD3D[v7].pQuads[0].texcoord.x = 0.0; pBillboardRenderListD3D[v7].pQuads[0].texcoord.y = 0.0; v17 = (double)((pSprite->uBufferWidth >> 1) - pSprite->uAreaX); v18 = (double)(pSprite->uBufferHeight - pSprite->uAreaY - pSprite->uAreaHeight); if ( pSoftBillboard->uFlags & 4 ) v17 = v17 * -1.0; pBillboardRenderListD3D[v7].pQuads[1].specular = 0; pBillboardRenderListD3D[v7].pQuads[1].diffuse = v12; pBillboardRenderListD3D[v7].pQuads[1].pos.x = pSoftBillboard->uScreenSpaceX - v17 * a1; pBillboardRenderListD3D[v7].pQuads[1].pos.y = pSoftBillboard->uScreenSpaceY - v18 * v29; pBillboardRenderListD3D[v7].pQuads[1].pos.z = v15; pBillboardRenderListD3D[v7].pQuads[1].rhw = v16; pBillboardRenderListD3D[v7].pQuads[1].texcoord.x = 0.0; pBillboardRenderListD3D[v7].pQuads[1].texcoord.y = 1.0; v19 = pSprite->uBufferHeight - pSprite->uAreaY - pSprite->uAreaHeight; v20 = (double)(pSprite->uAreaX + pSprite->uAreaWidth + (pSprite->uBufferWidth >> 1) - pSprite->uBufferWidth); if ( pSoftBillboard->uFlags & 4 ) v20 = v20 * -1.0; pBillboardRenderListD3D[v7].pQuads[2].specular = 0; pBillboardRenderListD3D[v7].pQuads[2].diffuse = v12; pBillboardRenderListD3D[v7].pQuads[2].pos.x = v20 * a1 + pSoftBillboard->uScreenSpaceX; pBillboardRenderListD3D[v7].pQuads[2].pos.y = pSoftBillboard->uScreenSpaceY - (double)v19 * v29; pBillboardRenderListD3D[v7].pQuads[2].pos.z = v15; pBillboardRenderListD3D[v7].pQuads[2].rhw = v16; pBillboardRenderListD3D[v7].pQuads[2].texcoord.x = 1.0; pBillboardRenderListD3D[v7].pQuads[2].texcoord.y = 1.0; v21 = pSprite->uBufferHeight - pSprite->uAreaY; v22 = (double)(pSprite->uAreaX + pSprite->uAreaWidth + (pSprite->uBufferWidth >> 1) - pSprite->uBufferWidth); if ( pSoftBillboard->uFlags & 4 ) v22 = v22 * -1.0; pBillboardRenderListD3D[v7].pQuads[3].specular = 0; pBillboardRenderListD3D[v7].pQuads[3].diffuse = v12; pBillboardRenderListD3D[v7].pQuads[3].pos.x = v22 * a1 + pSoftBillboard->uScreenSpaceX; pBillboardRenderListD3D[v7].pQuads[3].pos.y = pSoftBillboard->uScreenSpaceY - (double)v21 * v29; pBillboardRenderListD3D[v7].pQuads[3].pos.z = v15; pBillboardRenderListD3D[v7].pQuads[3].rhw = v16; pBillboardRenderListD3D[v7].pQuads[3].texcoord.x = 1.0; pBillboardRenderListD3D[v7].pQuads[3].texcoord.y = 0.0; //v23 = pSprite->pTexture; pBillboardRenderListD3D[v7].uNumVertices = 4; pBillboardRenderListD3D[v7].z_order = pSoftBillboard->zbuffer_depth; pBillboardRenderListD3D[v7].pTexture = pSprite->pTexture; } } //----- (004A354F) -------------------------------------------------------- void Render::MakeParticleBillboardAndPush_BLV(RenderBillboardTransform_local0 *a2, IDirect3DTexture2 *a3, unsigned int uDiffuse, int angle) { unsigned int v8; // esi@3 float v11; // ST28_4@3 float v16; // ST2C_4@3 float v17; // ST30_4@3 signed int v18; // ST18_4@3 signed int v19; // ST14_4@3 signed int v20; // ST10_4@3 signed int v21; // eax@3 double v22; // st6@3 float v23; // ST2C_4@3 float v24; // ST30_4@3 signed int v25; // ST10_4@3 signed int v26; // ST14_4@3 signed int v27; // ST18_4@3 signed int v28; // eax@3 double v29; // st6@3 float v30; // ecx@3 float v31; // ST2C_4@3 float v32; // ST30_4@3 signed int v33; // ST10_4@3 signed int v34; // ST14_4@3 signed int v35; // ST18_4@3 signed int v36; // eax@3 float v37; // ecx@3 double v38; // st6@3 float v39; // ST2C_4@3 float v40; // ST30_4@3 signed int v41; // ST10_4@3 signed int v42; // ST14_4@3 signed int v43; // ST18_4@3 signed int v44; // eax@3 double v45; // st6@3 float v46; // eax@3 if ( this->uNumD3DSceneBegins ) { if (a2->zbuffer_depth) { //v5 = (double)a2->zbuffer_depth; //v6 = v5; //v7 = v5; v8 = Billboard_ProbablyAddToListAndSortByZOrder(a2->zbuffer_depth); pBillboardRenderListD3D[v8].opacity = RenderBillboardD3D::Opaque_1; pBillboardRenderListD3D[v8].field_90 = a2->field_44; pBillboardRenderListD3D[v8].sZValue = a2->sZValue; pBillboardRenderListD3D[v8].sParentBillboardID = a2->sParentBillboardID; //v9 = a2->uScreenSpaceX; //v10 = a2->uScreenSpaceY; v11 = (a2->_screenspace_x_scaler_packedfloat & 0xFFFF) * 0.000015260186 + HIWORD(a2->_screenspace_x_scaler_packedfloat); //v12 = (double) a2->uScreenSpaceX; //v13 = v12; //v14 = (double)(a2->uScreenSpaceY - 12); //v15 = v14; v16 = (double)( a2->uScreenSpaceX - 12) - (double) a2->uScreenSpaceX; v17 = (double)(a2->uScreenSpaceY - 25) - (double)(a2->uScreenSpaceY - 12); v18 = stru_5C6E00->Cos(angle); v19 = stru_5C6E00->Sin(angle); v20 = stru_5C6E00->Sin(angle); v21 = stru_5C6E00->Cos(angle); pBillboardRenderListD3D[v8].pQuads[0].pos.x = (((double)(unsigned __int16)v18 * 0.000015259022 + (double)(v18 >> 16)) * v16 - ((double)(unsigned __int16)v19 * 0.000015259022 + (double)(v19 >> 16)) * v17) * v11 + (double) a2->uScreenSpaceX; v22 = (((double)(unsigned __int16)v21 * 0.000015259022 + (double)(v21 >> 16)) * v17 + ((double)(unsigned __int16)v20 * 0.000015259022 + (double)(v20 >> 16)) * v16 - 12.0) * v11 + (double)a2->uScreenSpaceY; pBillboardRenderListD3D[v8].pQuads[0].specular = 0; pBillboardRenderListD3D[v8].pQuads[0].diffuse = uDiffuse; pBillboardRenderListD3D[v8].pQuads[0].pos.y = v22; pBillboardRenderListD3D[v8].pQuads[0].pos.z = 1.0 - 1.0 / (a2->zbuffer_depth * 0.061758894); pBillboardRenderListD3D[v8].pQuads[0].rhw = 1.0 / a2->zbuffer_depth; pBillboardRenderListD3D[v8].pQuads[0].texcoord.x = 0.0; pBillboardRenderListD3D[v8].pQuads[0].texcoord.y = 0.0; v31 = (double)(a2->uScreenSpaceX + 12) - (double) a2->uScreenSpaceX; v32 = (double)a2->uScreenSpaceY - (double)(a2->uScreenSpaceY - 12); v25 = stru_5C6E00->Cos(angle); v26 = stru_5C6E00->Sin(angle); v27 = stru_5C6E00->Sin(angle); v28 = stru_5C6E00->Cos(angle); pBillboardRenderListD3D[v8].pQuads[1].pos.x = (((double)(unsigned __int16)v25 * 0.000015259022 + (double)(v25 >> 16)) * v31 - ((double)(unsigned __int16)v26 * 0.000015259022 + (double)(v26 >> 16)) * v32) * v11 + (double) a2->uScreenSpaceX; v29 = (((double)(unsigned __int16)v28 * 0.000015259022 + (double)(v28 >> 16)) * v32 + ((double)(unsigned __int16)v27 * 0.000015259022 + (double)(v27 >> 16)) * v31 - 12.0) * v11 + (double)a2->uScreenSpaceY; pBillboardRenderListD3D[v8].pQuads[1].pos.z = pRenderer->pBillboardRenderListD3D[v8].pQuads[0].pos.z; v30 = pBillboardRenderListD3D[v8].pQuads[0].rhw; pBillboardRenderListD3D[v8].pQuads[1].pos.y = v29; pBillboardRenderListD3D[v8].pQuads[1].specular = 0; pBillboardRenderListD3D[v8].pQuads[1].rhw = v30; pBillboardRenderListD3D[v8].pQuads[1].diffuse = uDiffuse; pBillboardRenderListD3D[v8].pQuads[1].texcoord.x = 0.0; pBillboardRenderListD3D[v8].pQuads[1].texcoord.y = 1.0; v23 = (double)(a2->uScreenSpaceX - 12) - (double) a2->uScreenSpaceX; v24 = (double)a2->uScreenSpaceY - (double)(a2->uScreenSpaceY - 12); v33 = stru_5C6E00->Cos(angle); v34 = stru_5C6E00->Sin(angle); v35 = stru_5C6E00->Sin(angle); v36 = stru_5C6E00->Cos(angle); pBillboardRenderListD3D[v8].pQuads[2].pos.x = (((double)(unsigned __int16)v33 * 0.000015259022 + (double)(v33 >> 16)) * v23 - ((double)(unsigned __int16)v34 * 0.000015259022 + (double)(v34 >> 16)) * v24) * v11 + (double) a2->uScreenSpaceX; v37 = pBillboardRenderListD3D[v8].pQuads[0].pos.z; v38 = (((double)(unsigned __int16)v36 * 0.000015259022 + (double)(v36 >> 16)) * v24 + ((double)(unsigned __int16)v35 * 0.000015259022 + (double)(v35 >> 16)) * v23 - 12.0) * v11 + (double)a2->uScreenSpaceY; pBillboardRenderListD3D[v8].pQuads[2].specular = 0; pBillboardRenderListD3D[v8].pQuads[2].pos.z = v37; pBillboardRenderListD3D[v8].pQuads[2].rhw = pBillboardRenderListD3D[v8].pQuads[0].rhw; pBillboardRenderListD3D[v8].pQuads[2].diffuse = uDiffuse; pBillboardRenderListD3D[v8].pQuads[2].pos.y = v38; pBillboardRenderListD3D[v8].pQuads[2].texcoord.x = 1.0; pBillboardRenderListD3D[v8].pQuads[2].texcoord.y = 1.0; v39 = (double)(a2->uScreenSpaceX + 12) - (double) a2->uScreenSpaceX; v40 = (double)(a2->uScreenSpaceY - 25) - (double)(a2->uScreenSpaceY - 12); v41 = stru_5C6E00->Cos(angle); v42 = stru_5C6E00->Sin(angle); v43 = stru_5C6E00->Sin(angle); v44 = stru_5C6E00->Cos(angle); pBillboardRenderListD3D[v8].pQuads[3].pos.x = (((double)(unsigned __int16)v41 * 0.000015259022 + (double)(v41 >> 16)) * v39 - ((double)(unsigned __int16)v42 * 0.000015259022 + (double)(v42 >> 16)) * v40) * v11 + (double) a2->uScreenSpaceX; v45 = (((double)(unsigned __int16)v44 * 0.000015259022 + (double)(v44 >> 16)) * v40 + ((double)(unsigned __int16)v43 * 0.000015259022 + (double)(v43 >> 16)) * v39 - 12.0) * v11 + (double)a2->uScreenSpaceY; v46 = pBillboardRenderListD3D[v8].pQuads[0].pos.z; pBillboardRenderListD3D[v8].pQuads[3].specular = 0; pBillboardRenderListD3D[v8].pQuads[3].pos.z = v46; pBillboardRenderListD3D[v8].pQuads[3].rhw = pBillboardRenderListD3D[v8].pQuads[0].rhw; pBillboardRenderListD3D[v8].pQuads[3].diffuse = uDiffuse; pBillboardRenderListD3D[v8].pTexture = a3; pBillboardRenderListD3D[v8].z_order = a2->zbuffer_depth; pBillboardRenderListD3D[v8].uNumVertices = 4; pBillboardRenderListD3D[v8].pQuads[3].pos.y = v45; pBillboardRenderListD3D[v8].pQuads[3].texcoord.x = 1.0; pBillboardRenderListD3D[v8].pQuads[3].texcoord.y = 0.0; } } } //----- (004A3AD9) -------------------------------------------------------- void Render::MakeParticleBillboardAndPush_ODM(RenderBillboardTransform_local0 *a2, IDirect3DTexture2 *a3, unsigned int uDiffuse, int angle) { double v5; // st7@2 float v6; // ST28_4@2 float v7; // ST00_4@2 unsigned int v8; // esi@2 //int v9; // eax@2 //int v10; // ebx@2 float v11; // ST34_4@2 double v12; // st7@2 float v13; // ST2C_4@2 double v14; // st6@2 float v15; // ST24_4@2 float v16; // ST38_4@2 float v17; // ST3C_4@2 signed int v18; // ST1C_4@2 int v19; // ST30_4@2 signed int v20; // ST20_4@2 signed int v21; // ST18_4@2 signed int v22; // eax@2 double v23; // st6@2 float v24; // ST20_4@2 float v25; // ST1C_4@2 float v26; // ST38_4@2 float v27; // ST3C_4@2 signed int v28; // ST18_4@2 signed int v29; // ST14_4@2 signed int v30; // ST10_4@2 signed int v31; // eax@2 double v32; // st6@2 float v33; // ST38_4@2 float v34; // ST3C_4@2 signed int v35; // ST10_4@2 signed int v36; // ST14_4@2 signed int v37; // ST18_4@2 signed int v38; // eax@2 double v39; // st6@2 float v40; // ST38_4@2 float v41; // ST3C_4@2 signed int v42; // ST10_4@2 signed int v43; // ST14_4@2 signed int v44; // ST18_4@2 signed int v45; // eax@2 double v46; // st6@2 if ( this->uNumD3DSceneBegins ) { v5 = (double)a2->zbuffer_depth; v6 = v5; v7 = v5; v8 = Billboard_ProbablyAddToListAndSortByZOrder(LODWORD(v7)); pBillboardRenderListD3D[v8].opacity = RenderBillboardD3D::Opaque_1; pBillboardRenderListD3D[v8].field_90 = a2->field_44; pBillboardRenderListD3D[v8].sZValue = a2->sZValue; pBillboardRenderListD3D[v8].sParentBillboardID = a2->sParentBillboardID; //v9 = a2->uScreenSpaceX; //v10 = a2->uScreenSpaceY; v11 = (a2->_screenspace_x_scaler_packedfloat & 0xFFFF) * 0.000015260186 + HIWORD(a2->_screenspace_x_scaler_packedfloat); v12 = (double)a2->uScreenSpaceX; v13 = (double)a2->uScreenSpaceX; v14 = (double)(a2->uScreenSpaceY - 12); v15 = v14; v16 = (double)(a2->uScreenSpaceX - 12) - v12; v17 = (double)(a2->uScreenSpaceY - 25) - v14; v18 = stru_5C6E00->Cos(angle); v19 = angle - stru_5C6E00->uIntegerHalfPi; v20 = stru_5C6E00->Sin(angle); v21 = stru_5C6E00->Sin(angle); v22 = stru_5C6E00->Cos(angle); pBillboardRenderListD3D[v8].pQuads[0].pos.x = (((double)(unsigned __int16)v18 * 0.000015259022 + (double)(v18 >> 16)) * v16 - ((double)(unsigned __int16)v20 * 0.000015259022 + (double)(v20 >> 16)) * v17) * v11 + v13; v23 = (((double)(unsigned __int16)v22 * 0.000015259022 + (double)(v22 >> 16)) * v17 + ((double)(unsigned __int16)v21 * 0.000015259022 + (double)(v21 >> 16)) * v16 - 12.0) * v11 + (double)a2->uScreenSpaceY; pBillboardRenderListD3D[v8].pQuads[0].specular = 0; pBillboardRenderListD3D[v8].pQuads[0].diffuse = uDiffuse; pBillboardRenderListD3D[v8].pQuads[0].pos.y = v23; v24 = 1.0 - 1.0 / (v6 * 1000.0 / (double)pODMRenderParams->shading_dist_mist); pBillboardRenderListD3D[v8].pQuads[0].pos.z = v24; v25 = 1.0 / v6; pBillboardRenderListD3D[v8].pQuads[0].rhw = v25; pBillboardRenderListD3D[v8].pQuads[0].texcoord.x = 0.0; pBillboardRenderListD3D[v8].pQuads[0].texcoord.y = 0.0; v26 = (double)(a2->uScreenSpaceX - 12) - v13; v27 = (double)a2->uScreenSpaceY - v15; v28 = stru_5C6E00->Cos(angle); v29 = stru_5C6E00->Sin(v19 + stru_5C6E00->uIntegerHalfPi); v30 = stru_5C6E00->Sin(v19 + stru_5C6E00->uIntegerHalfPi); v31 = stru_5C6E00->Cos(angle); pBillboardRenderListD3D[v8].pQuads[1].pos.x = (((double)(unsigned __int16)v28 * 0.000015259022 + (double)(v28 >> 16)) * v26 - ((double)(unsigned __int16)v29 * 0.000015259022 + (double)(v29 >> 16)) * v27) * v11 + v13; v32 = (((double)(unsigned __int16)v31 * 0.000015259022 + (double)(v31 >> 16)) * v27 + ((double)(unsigned __int16)v30 * 0.000015259022 + (double)(v30 >> 16)) * v26 - 12.0) * v11 + (double)a2->uScreenSpaceY; pBillboardRenderListD3D[v8].pQuads[1].pos.z = v24; pBillboardRenderListD3D[v8].pQuads[1].pos.y = v32; pBillboardRenderListD3D[v8].pQuads[1].specular = 0; pBillboardRenderListD3D[v8].pQuads[1].rhw = v25; pBillboardRenderListD3D[v8].pQuads[1].diffuse = uDiffuse; pBillboardRenderListD3D[v8].pQuads[1].texcoord.x = 0.0; pBillboardRenderListD3D[v8].pQuads[1].texcoord.y = 1.0; v33 = (double)(a2->uScreenSpaceX + 12) - v13; v34 = (double)a2->uScreenSpaceY - v15; v35 = stru_5C6E00->Cos(angle); v36 = stru_5C6E00->Sin(v19 + stru_5C6E00->uIntegerHalfPi); v37 = stru_5C6E00->Sin(v19 + stru_5C6E00->uIntegerHalfPi); v38 = stru_5C6E00->Cos(angle); pBillboardRenderListD3D[v8].pQuads[2].pos.x = (((double)(unsigned __int16)v35 * 0.000015259022 + (double)(v35 >> 16)) * v33 - ((double)(unsigned __int16)v36 * 0.000015259022 + (double)(v36 >> 16)) * v34) * v11 + v13; v39 = (((double)(unsigned __int16)v38 * 0.000015259022 + (double)(v38 >> 16)) * v34 + ((double)(unsigned __int16)v37 * 0.000015259022 + (double)(v37 >> 16)) * v33 - 12.0) * v11 + (double)a2->uScreenSpaceY; pBillboardRenderListD3D[v8].pQuads[2].specular = 0; pBillboardRenderListD3D[v8].pQuads[2].pos.z = v24; pBillboardRenderListD3D[v8].pQuads[2].rhw = v25; pBillboardRenderListD3D[v8].pQuads[2].diffuse = uDiffuse; pBillboardRenderListD3D[v8].pQuads[2].pos.y = v39; pBillboardRenderListD3D[v8].pQuads[2].texcoord.x = 1.0; pBillboardRenderListD3D[v8].pQuads[2].texcoord.y = 1.0; v40 = (double)(a2->uScreenSpaceX + 12) - v13; v41 = (double)(a2->uScreenSpaceY - 25) - v15; v42 = stru_5C6E00->Cos(angle); v43 = stru_5C6E00->Sin(v19 + stru_5C6E00->uIntegerHalfPi); v44 = stru_5C6E00->Sin(v19 + stru_5C6E00->uIntegerHalfPi); v45 = stru_5C6E00->Cos(angle); pBillboardRenderListD3D[v8].pQuads[3].pos.x = (((double)(unsigned __int16)v42 * 0.000015259022 + (double)(v42 >> 16)) * v40 - ((double)(unsigned __int16)v43 * 0.000015259022 + (double)(v43 >> 16)) * v41) * v11 + v13; v46 = (((double)(unsigned __int16)v45 * 0.000015259022 + (double)(v45 >> 16)) * v41 + ((double)(unsigned __int16)v44 * 0.000015259022 + (double)(v44 >> 16)) * v40 - 12.0) * v11 + (double)a2->uScreenSpaceY; pBillboardRenderListD3D[v8].pQuads[3].specular = 0; pBillboardRenderListD3D[v8].pQuads[3].pos.z = v24; pBillboardRenderListD3D[v8].pQuads[3].rhw = v25; pBillboardRenderListD3D[v8].pQuads[3].diffuse = uDiffuse; pBillboardRenderListD3D[v8].pTexture = a3; pBillboardRenderListD3D[v8].z_order = v6; pBillboardRenderListD3D[v8].uNumVertices = 4; pBillboardRenderListD3D[v8].pQuads[3].pos.y = v46; pBillboardRenderListD3D[v8].pQuads[3].texcoord.x = 1.0; pBillboardRenderListD3D[v8].pQuads[3].texcoord.y = 0.0; } } //----- (004A4023) -------------------------------------------------------- void Render::TransformBillboard(RenderBillboardTransform_local0 *a2, Sprite *pSprite, int dimming_level, RenderBillboard *pBillboard) { unsigned int v8; // esi@2 double v14; // st6@14 double v15; // st5@14 float v29; // [sp+28h] [bp-8h]@5 float v30; // [sp+2Ch] [bp-4h]@5 if (!uNumD3DSceneBegins) return; v8 = Billboard_ProbablyAddToListAndSortByZOrder(a2->zbuffer_depth); v30 = (a2->_screenspace_x_scaler_packedfloat & 0xFFFF) / 65530.0 + HIWORD(a2->_screenspace_x_scaler_packedfloat); v29 = (a2->_screenspace_y_scaler_packedfloat & 0xFFFF) / 65530.0 + HIWORD(a2->_screenspace_y_scaler_packedfloat); unsigned int diffuse = ::GetActorTintColor(dimming_level, 0, a2->zbuffer_depth, 0, pBillboard); if (a2->sTintColor & 0x00FFFFFF && bTinting) { diffuse = BlendColors(a2->sTintColor, diffuse); if (a2->sTintColor & 0xFF000000) diffuse = 0x007F7F7F & ((unsigned int)diffuse >> 1); } unsigned int specular = 0; if (bUsingSpecular) specular = sub_47C3D7_get_fog_specular(0, 0, a2->zbuffer_depth); v14 = (double)((int)pSprite->uBufferWidth / 2 - pSprite->uAreaX); v15 = (double)((int)pSprite->uBufferHeight - pSprite->uAreaY); if (a2->uFlags & 4) v14 *= -1.0; pBillboardRenderListD3D[v8].pQuads[0].diffuse = diffuse; pBillboardRenderListD3D[v8].pQuads[0].pos.x = (double)a2->uScreenSpaceX - v14 * v30; pBillboardRenderListD3D[v8].pQuads[0].pos.y = (double)a2->uScreenSpaceY - v15 * v29; pBillboardRenderListD3D[v8].pQuads[0].pos.z = 1.0 - 1.0 / (a2->zbuffer_depth * 1000.0 / (double)pODMRenderParams->shading_dist_mist); pBillboardRenderListD3D[v8].pQuads[0].rhw = 1.0 / a2->zbuffer_depth; pBillboardRenderListD3D[v8].pQuads[0].specular = specular; pBillboardRenderListD3D[v8].pQuads[0].texcoord.x = 0.0; pBillboardRenderListD3D[v8].pQuads[0].texcoord.y = 0.0; v14 = (double)((int)pSprite->uBufferWidth / 2 - pSprite->uAreaX); v15 = (double)((int)pSprite->uBufferHeight - pSprite->uAreaHeight - pSprite->uAreaY); if ( a2->uFlags & 4 ) v14 = v14 * -1.0; pBillboardRenderListD3D[v8].pQuads[1].specular = specular; pBillboardRenderListD3D[v8].pQuads[1].diffuse = diffuse; pBillboardRenderListD3D[v8].pQuads[1].pos.x = (double)a2->uScreenSpaceX - v14 * v30; pBillboardRenderListD3D[v8].pQuads[1].pos.y = (double)a2->uScreenSpaceY - v15 * v29; pBillboardRenderListD3D[v8].pQuads[1].pos.z = 1.0 - 1.0 / (a2->zbuffer_depth * 1000.0 / (double)pODMRenderParams->shading_dist_mist); pBillboardRenderListD3D[v8].pQuads[1].rhw = 1.0 / a2->zbuffer_depth; pBillboardRenderListD3D[v8].pQuads[1].texcoord.x = 0.0; pBillboardRenderListD3D[v8].pQuads[1].texcoord.y = 1.0; v14 = (double)((int)pSprite->uAreaWidth + pSprite->uAreaX + pSprite->uBufferWidth / 2 - pSprite->uBufferWidth); v15 = (double)((int)pSprite->uBufferHeight - pSprite->uAreaHeight - pSprite->uAreaY); if ( a2->uFlags & 4 ) v14 *= -1.0; pBillboardRenderListD3D[v8].pQuads[2].diffuse = diffuse; pBillboardRenderListD3D[v8].pQuads[2].specular = specular; pBillboardRenderListD3D[v8].pQuads[2].pos.x = (double)a2->uScreenSpaceX + v14 * v30; pBillboardRenderListD3D[v8].pQuads[2].pos.y = (double)a2->uScreenSpaceY - v15 * v29; pBillboardRenderListD3D[v8].pQuads[2].pos.z = 1.0 - 1.0 / (a2->zbuffer_depth * 1000.0 / (double)pODMRenderParams->shading_dist_mist); pBillboardRenderListD3D[v8].pQuads[2].rhw = 1.0 / a2->zbuffer_depth; pBillboardRenderListD3D[v8].pQuads[2].texcoord.x = 1.0; pBillboardRenderListD3D[v8].pQuads[2].texcoord.y = 1.0; v14 = (double)((int)pSprite->uAreaWidth + pSprite->uAreaX + pSprite->uBufferWidth / 2 - pSprite->uBufferWidth); v15 = (double)((int)pSprite->uBufferHeight - pSprite->uAreaY); if ( a2->uFlags & 4 ) v14 *= -1.0; pBillboardRenderListD3D[v8].pQuads[3].diffuse = diffuse; pBillboardRenderListD3D[v8].pQuads[3].specular = specular; pBillboardRenderListD3D[v8].pQuads[3].pos.x = (double)a2->uScreenSpaceX + v14 * v30; pBillboardRenderListD3D[v8].pQuads[3].pos.y = (double)a2->uScreenSpaceY - v15 * v29; pBillboardRenderListD3D[v8].pQuads[3].pos.z = 1.0 - 1.0 / (a2->zbuffer_depth * 1000.0 / (double)pODMRenderParams->shading_dist_mist); pBillboardRenderListD3D[v8].pQuads[3].rhw = 1.0 / a2->zbuffer_depth; pBillboardRenderListD3D[v8].pQuads[3].texcoord.x = 1.0; pBillboardRenderListD3D[v8].pQuads[3].texcoord.y = 0.0; pBillboardRenderListD3D[v8].uNumVertices = 4; pBillboardRenderListD3D[v8].pTexture = pSprite->pTexture; pBillboardRenderListD3D[v8].z_order = a2->zbuffer_depth; pBillboardRenderListD3D[v8].field_90 = a2->field_44; pBillboardRenderListD3D[v8].sZValue = a2->sZValue; pBillboardRenderListD3D[v8].sParentBillboardID = a2->sParentBillboardID; if (a2->sTintColor & 0xFF000000) pBillboardRenderListD3D[v8].opacity = RenderBillboardD3D::Opaque_3; else pBillboardRenderListD3D[v8].opacity = RenderBillboardD3D::Transparent; } //----- (004A49D0) -------------------------------------------------------- void Render::DrawProjectile(float srcX, float srcY, float a3, float a4, float dstX, float dstY, float a7, float a8, IDirect3DTexture2 *a9) { int absXDifference; // eax@1 int absYDifference; // eax@1 unsigned int smallerabsdiff; // ebx@1 unsigned int largerabsdiff; double v16; // st7@7 double v17; // st7@7 double v18; // st6@7 double v20; // st4@8 double v21; // st4@10 double v22; // st4@10 double v23; // st4@10 double v25; // st4@11 double v26; // st4@13 double v28; // st4@13 RenderVertexD3D3 v29[4]; // [sp+0h] [bp-94h]@7 int xDifference; // [sp+88h] [bp-Ch]@1 signed int v32; // [sp+8Ch] [bp-8h]@1 int yDifference; // [sp+90h] [bp-4h]@1 xDifference = bankersRounding(dstX - srcX); yDifference = bankersRounding(dstY - srcY); absYDifference = abs(yDifference); absXDifference = abs(xDifference); smallerabsdiff = min(absXDifference, absYDifference); largerabsdiff = max(absXDifference, absYDifference); v32 = (11 * smallerabsdiff >> 5) + largerabsdiff; v16 = 1.0 / (double)v32; v17 = (double)yDifference * v16 * a4; v18 = (double)xDifference * v16 * a4; if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor ) { v20 = a3 * 1000.0 / (double)pODMRenderParams->shading_dist_mist; v25 = a7 * 1000.0 / (double)pODMRenderParams->shading_dist_mist; } else { v20 = a3 * 0.061758894; v25 = a7 * 0.061758894; } v21 = 1.0 / a3; v22 = (double)yDifference * v16 * a8; v23 = (double)xDifference * v16 * a8; v26 = 1.0 - 1.0 / v25; v28 = 1.0 / a7; v29[0].pos.x = srcX + v17; v29[0].pos.y = srcY - v18; v29[0].pos.z = 1.0 - 1.0 / v20; v29[0].rhw = v21; v29[0].diffuse = -1; v29[0].specular = 0; v29[0].texcoord.x = 1.0; v29[0].texcoord.y = 0.0; v29[1].pos.x = v22 + dstX; v29[1].pos.y = dstY - v23; v29[1].pos.z = v26; v29[1].rhw = v28; v29[1].diffuse = -16711936; v29[1].specular = 0; v29[1].texcoord.x = 1.0; v29[1].texcoord.y = 1.0; v29[2].pos.x = dstX - v22; v29[2].pos.y = v23 + dstY; v29[2].pos.z = v26; v29[2].rhw = v28; v29[2].diffuse = -1; v29[2].specular = 0; v29[2].texcoord.x = 0.0; v29[2].texcoord.y = 1.0; v29[3].pos.x = srcX - v17; v29[3].pos.y = v18 + srcY; v29[3].pos.z = v29[0].pos.z; v29[3].rhw = v21; v29[3].diffuse = -1; v29[3].specular = 0; v29[3].texcoord.x = 0.0; v29[3].texcoord.y = 0.0; ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, FALSE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE)); ErrD3D(pRenderD3D->pDevice->SetTexture(0, a9)); ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, v29, 4, 24)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CW)); } //----- (004A4CC9) -------------------------------------------------------- void Render::_4A4CC9_AddSomeBillboard(stru6_stru1_indoor_sw_billboard *a1, int diffuse) { unsigned int v5; // eax@7 double v10; // st6@9 double v11; // st6@10 int v12; // ebx@13 if (a1->uNumVertices < 3) return; float depth = 1000000.0; for (uint i = 0; i < (unsigned int)a1->uNumVertices; ++i) { if (a1->field_104[i].z < depth) depth = a1->field_104[i * 4].z; } v5 = Billboard_ProbablyAddToListAndSortByZOrder(depth); pBillboardRenderListD3D[v5].field_90 = 0; pBillboardRenderListD3D[v5].sParentBillboardID = -1; pBillboardRenderListD3D[v5].opacity = RenderBillboardD3D::Opaque_2; pBillboardRenderListD3D[v5].pTexture = 0; pBillboardRenderListD3D[v5].uNumVertices = a1->uNumVertices; pBillboardRenderListD3D[v5].z_order = depth; for (uint i = 0; i < (unsigned int)a1->uNumVertices; ++i) { pBillboardRenderListD3D[v5].pQuads[i].pos.x = a1->field_104[i].x; pBillboardRenderListD3D[v5].pQuads[i].pos.y = a1->field_104[i].y; v10 = a1->field_104[i].z; if (uCurrentlyLoadedLevelType == LEVEL_Indoor) v11 = v10 * 0.061758894; else v11 = v10 * 1000.0 / (double)pODMRenderParams->shading_dist_mist; pBillboardRenderListD3D[v5].pQuads[i].pos.z = 1.0 - 1.0 / v11; pBillboardRenderListD3D[v5].pQuads[i].rhw = 1.0 / a1->field_104[i].z; if (diffuse & 0xFF000000) v12 = a1->field_104[i].diffuse; else v12 = diffuse; pBillboardRenderListD3D[v5].pQuads[i].diffuse = v12; pBillboardRenderListD3D[v5].pQuads[i].specular = 0; pBillboardRenderListD3D[v5].pQuads[i].texcoord.x = 0.0; pBillboardRenderListD3D[v5].pQuads[i].texcoord.y = 0.0; } } //----- (004A4DE1) -------------------------------------------------------- bool Render::LoadTexture(const char *pName, unsigned int bMipMaps, IDirectDrawSurface4 **pOutSurface, IDirect3DTexture2 **pOutTexture) { unsigned __int16 *v13; // ecx@19 unsigned __int16 *v14; // eax@19 DWORD v15; // edx@20 stru350 Dst; // [sp+Ch] [bp-F8h]@12 HWLTexture* pHWLTexture = pD3DBitmaps.LoadTexture(pName, bMipMaps); if ( pHWLTexture ) { bMipMaps = !strncmp(pName, "HDWTR", 5); if ( !pRenderD3D->CreateTexture(pHWLTexture->uWidth, pHWLTexture->uHeight, pOutSurface, pOutTexture, true, bMipMaps, uMinDeviceTextureDim) ) Error("HiScreen16::LoadTexture - D3Drend->CreateTexture() failed: %x", 0); if (bMipMaps) { Dst._450DDE(); Dst._450DF1(&stru_4EFCBC, &stru_4EFCBC); IDirectDrawSurface4 *pNextSurf = *pOutSurface; while ( 1 ) { DDSCAPS2 v19; memset(&v19, 0, sizeof(DDSCAPS2)); v19.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP; DDSURFACEDESC2 desc; memset(&desc, 0, sizeof(DDSURFACEDESC2)); desc.dwSize = sizeof(DDSURFACEDESC2); if ( LockSurface_DDraw4(pNextSurf, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY) ) { // linear scaling for (int s = 0; s < desc.dwHeight; ++s) for (int t = 0; t < desc.dwWidth; ++t) { unsigned int resampled_x = t * pHWLTexture->uWidth / desc.dwWidth, resampled_y = s * pHWLTexture->uHeight / desc.dwHeight; unsigned short sample = pHWLTexture->pPixels[resampled_y * pHWLTexture->uWidth + resampled_x]; ((unsigned short *)desc.lpSurface)[s * (desc.lPitch >> 1) + t] = sample; } //bicubic sampling //Dst.sub_451007_scale_image_bicubic(pHWLTexture->pPixels, pHWLTexture->uWidth, pHWLTexture->uHeight, pHWLTexture->uWidth, // (unsigned short *)desc.lpSurface, desc.dwWidth, desc.dwHeight, desc.lPitch >> 1, 0, 0); ErrD3D(pNextSurf->Unlock(NULL)); //bMipMaps = 0x4D86ACu; } if (FAILED(pNextSurf->GetAttachedSurface(&v19, &pNextSurf))) break; } //v20 = -1; //nullsub_1(); } else { DDSCAPS2 v19; memset(&v19, 0, sizeof(DDSCAPS2)); v19.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP; DDSURFACEDESC2 desc; memset(&desc, 0, sizeof(DDSURFACEDESC2)); desc.dwSize = sizeof(DDSURFACEDESC2); if ( LockSurface_DDraw4(*pOutSurface, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY) ) { bMipMaps = 0; v13 = pHWLTexture->pPixels; v14 = (unsigned __int16 *)desc.lpSurface; for(uint bMipMaps = 0; bMipMaps < desc.dwHeight; bMipMaps++) { for (v15 = 0; v15 < desc.dwWidth; v15++) { *v14 = *v13; ++v14; ++v13; } v14 += (desc.lPitch >> 1) - desc.dwWidth; } ErrD3D((*pOutSurface)->Unlock(NULL)); } } delete [] pHWLTexture->pPixels; delete pHWLTexture; return true; } return false; } //----- (004A5048) -------------------------------------------------------- bool Render::MoveSpriteToDevice( Sprite *pSprite ) { HWLTexture *sprite_texture; // eax@1 unsigned __int16 *v9; // edx@5 LPVOID v10; // eax@5 DDSURFACEDESC2 Dst; // [sp+Ch] [bp-7Ch]@4 sprite_texture = pD3DSprites.LoadTexture(pSprite->pName, pSprite->uPaletteID); if ( sprite_texture ) { pSprite->uAreaX = sprite_texture->uAreaX; pSprite->uAreaY = sprite_texture->uAreaY; pSprite->uBufferWidth = sprite_texture->uBufferWidth; pSprite->uBufferHeight = sprite_texture->uBufferHeight; pSprite->uAreaWidth = sprite_texture->uAreaWidth; pSprite->uAreaHeight = sprite_texture->uAreaHeigth; if (!pRenderD3D->CreateTexture(sprite_texture->uWidth, sprite_texture->uHeight, &pSprite->pTextureSurface, &pSprite->pTexture, 1u, 0, uMinDeviceTextureDim)) Error("HiScreen16::LoadTexture - D3Drend->CreateTexture() failed: %x", 0); memset(&Dst, 0, sizeof(DDSURFACEDESC2)); Dst.dwSize = 124; if ( LockSurface_DDraw4((IDirectDrawSurface4 *)pSprite->pTextureSurface, &Dst, DDLOCK_WAIT | DDLOCK_WRITEONLY) ) { v9 = sprite_texture->pPixels; v10 = Dst.lpSurface; for (uint i=0; i<sprite_texture->uHeight; ++i) { for (uint j=0; j<sprite_texture->uWidth/2; ++j) { *(int *)v10 = *(int *)v9; v9 += 2; v10 = (char *)v10 + 4; } v10 = (char *)v10 + Dst.lPitch-sprite_texture->uWidth*2; } ErrD3D(pSprite->pTextureSurface->Unlock(NULL)); } delete [] sprite_texture->pPixels; delete sprite_texture; return true; } return false; } //----- (004A51CB) -------------------------------------------------------- void Render::BeginScene() { //Render *v1; // esi@1 unsigned int v2; // eax@1 /*int v3; // eax@5 unsigned __int16 **v4; // edi@6 char *v5; // ebx@7*/ // DDSURFACEDESC2 Dst; // [sp+Ch] [bp-7Ch]@4 //v1 = this; v2 = this->uNumSceneBegins; this->uNumSceneBegins = v2 + 1; if ( !v2 ) { if ( this->pRenderD3D ) { /*if ( this->bColorKeySupported ) { memset(&Dst, 0, 0x7Cu); Dst.dwSize = 124; if ( LockSurface_DDraw4(this->pColorKeySurface4, &Dst, 0x800 | DDLOCK_WAIT) ) { this->pTargetSurface = (unsigned __int16 *)Dst.lpSurface; this->uTargetSurfacePitch = Dst.lPitch >> 1; this->field_18_locked_pitch = Dst.lPitch >> 1; } --this->uNumSceneBegins; }*/ } else { if ( !this->pTargetSurface ) { LockRenderSurface((void **)&this->pTargetSurface, &this->uTargetSurfacePitch); /*if ( this->pTargetSurface ) { this->field_18_locked_pitch = this->uTargetSurfacePitch; }*/ --this->uNumSceneBegins; } } RestoreFrontBuffer(); } } //----- (004A527D) -------------------------------------------------------- void Render::EndScene() { if ( this->uNumSceneBegins ) { this->uNumSceneBegins--; if ( !this->uNumSceneBegins ) { if ( this->pRenderD3D ) { /*if ( this->bColorKeySupported ) { this->pTargetSurface = 0; this->uTargetSurfacePitch = 0; this->field_18_locked_pitch = 0; ErrD3D(this->pColorKeySurface4->Unlock(NULL)); }*/ } else { this->pTargetSurface = 0; this->uTargetSurfacePitch = 0; //this->field_18_locked_pitch = 0; UnlockBackBuffer(); } } } } //----- (004A52F1) -------------------------------------------------------- void Render::ScreenFade(unsigned int color, float t) { unsigned int v3; // esi@1 unsigned int v7; // eax@6 RenderVertexD3D3 v36[4]; // [sp+Ch] [bp-94h]@6 int v40; // [sp+9Ch] [bp-4h]@6 v3 = 0; //{ if (t > 1.0f) t = 1.0f; else if (t < 0.0f) t = 0.0f; v40 = (char)floorf(t * 255.0f + 0.5f); v7 = color | (v40 << 24); v36[0].specular = 0; v36[0].pos.x = pViewport->uViewportTL_X; v36[0].pos.y = (double)pViewport->uViewportTL_Y; v36[0].pos.z = 0.0; v36[0].diffuse = v7; v36[0].rhw = 1.0; v36[0].texcoord.x = 0.0; v36[0].texcoord.y = 0.0; v36[1].specular = 0; v36[1].pos.x = pViewport->uViewportTL_X; v36[1].pos.y = (double)(pViewport->uViewportBR_Y + 1); v36[1].pos.z = 0.0; v36[1].diffuse = v7; v36[1].rhw = 1.0; v36[1].texcoord.x = 0.0; v36[1].texcoord.y = 0.0; v36[2].specular = 0; v36[2].pos.x = (double)pViewport->uViewportBR_X; v36[2].pos.y = (double)(pViewport->uViewportBR_Y + 1); v36[2].pos.z = 0.0; v36[2].diffuse = v7; v36[2].rhw = 1.0; v36[2].texcoord.x = 0.0; v36[2].texcoord.y = 0.0; v36[3].specular = 0; v36[3].pos.x = (double)pViewport->uViewportBR_X; v36[3].pos.y = (double)pViewport->uViewportTL_Y; v36[3].pos.z = 0.0; v36[3].diffuse = v7; v36[3].rhw = 1.0; v36[3].texcoord.x = 0.0; v36[3].texcoord.y = 0.0; ErrD3D(pRenderD3D->pDevice->SetTexture(0, 0)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, FALSE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, D3DCMP_ALWAYS)); ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, v36, 4, 28)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, D3DCMP_LESS)); /*} else { v40 = (1.0 - a3) * 65536.0; v39 = v40 + 6.7553994e15; LODWORD(a3) = LODWORD(v39); v38 = (signed int)(pViewport->uViewportBR_X - pViewport->uViewportTL_X) >> 1; HIDWORD(v39) = pViewport->uViewportBR_Y - pViewport->uViewportTL_Y + 1; v13 = pViewport->uViewportTL_X + ecx0->uTargetSurfacePitch - pViewport->uViewportBR_X; v14 = &ecx0->pTargetSurface[pViewport->uViewportTL_X + pViewport->uViewportTL_Y * ecx0->uTargetSurfacePitch]; v37 = 2 * v13; LODWORD(v40) = (int)v14; int __i = 0; v15 = dword_F1B430.data(); do { v16 = v3; v3 += LODWORD(a3); dword_F1B430[__i++] = v16 >> 16; } //while ( (signed int)v15 < (signed int)&Aureal3D_SplashScreen ); while (__i < 32); if ( pRenderer->uTargetGBits == 6 ) { v17 = sr_42690D_colors_cvt(this_); v18 = (65536 - LODWORD(a3)) * (v17 & 0x1F); this_ = (((65536 - LODWORD(a3)) * (unsigned __int16)(v17 & 0xF800) & 0xF800FFFF | v18 & 0x1F0000 | (65536 - LODWORD(a3)) * (v17 & 0x7E0) & 0x7E00000u) >> 16 << 16) | (((65536 - LODWORD(a3)) * (unsigned __int16)(v17 & 0xF800) & 0xF800FFFF | v18 & 0x1F0000 | (65536 - LODWORD(a3)) * (v17 & 0x7E0) & 0x7E00000u) >> 16); v19 = v40; v20 = off_4EFDB0; v21 = HIDWORD(v39); do { v22 = v38; v31 = v21; do { v23 = (*(int *)((char *)v20 + ((((unsigned __int16)(*(short *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF800u) >> 9)) << 11) | *(unsigned int *)LODWORD(v19) & 0x7FF) & 0x7C0u) >> 4)) << 6) | (*(int *)((char *)v20 + ((((*(int *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF800u) >> 9)) << 11) | (*(int *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF8000000u) >> 25)) << 27) | *(unsigned int *)LODWORD(v19) & 0x7FF07FF) & 0x7C00000u) >> 20)) << 22) | ((*(int *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF800u) >> 9)) << 11) | (*(int *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF8000000u) >> 25)) << 27) | *(unsigned int *)LODWORD(v19) & 0x7FF07FF) & 0xF81FF81F; result = this_ + (*((int *)v20 + (((unsigned __int8)(*((char *)v20 + ((((unsigned __int16)(*(short *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF800u) >> 9)) << 11) | *(unsigned int *)LODWORD(v19) & 0x7FF) & 0x7C0u) >> 4)) << 6) | *(unsigned int *)LODWORD(v19) & 0x1F) & 0x1F)) | (*(int *)((char *)v20 + ((v23 & 0x1F0000u) >> 14)) << 16) | ((*(int *)((char *)v20 + ((((unsigned __int16)(*(short *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF800u) >> 9)) << 11) | *(unsigned int *)LODWORD(v19) & 0x7FF) & 0x7C0u) >> 4)) << 6) | (*(int *)((char *)v20 + ((((*(int *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF800u) >> 9)) << 11) | (*(int *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF8000000u) >> 25)) << 27) | *(unsigned int *)LODWORD(v19) & 0x7FF07FF) & 0x7C00000u) >> 20)) << 22) | ((*(int *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF800u) >> 9)) << 11) | (*(int *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF8000000u) >> 25)) << 27) | *(unsigned int *)LODWORD(v19) & 0x7FF07FF) & 0xF81FF81F) & 0xFFE0FFE0); *(unsigned int *)LODWORD(v19) = result; LODWORD(v19) += 4; --v22; } while ( v22 ); LODWORD(v19) += v37; v21 = v31 - 1; } while ( v31 != 1 ); } else { v24 = sr_4268E3_smthn_to_a1r5g5b5(this_); v25 = (65536 - LODWORD(a3)) * (v24 & 0x1F); this_ = (((65536 - LODWORD(a3)) * (v24 & 0x7C00) & 0x7C000000 | v25 & 0x1F0000 | (65536 - LODWORD(a3)) * (v24 & 0x3E0) & 0x3E00000u) >> 16 << 16) | (((65536 - LODWORD(a3)) * (v24 & 0x7C00) & 0x7C000000 | v25 & 0x1F0000 | (65536 - LODWORD(a3)) * (v24 & 0x3E0) & 0x3E00000u) >> 16); v26 = v40; v27 = (char *)off_4EFDB0; v28 = HIDWORD(v39); do { v29 = v38; v32 = v28; do { v30 = 32 * *(int *)&v27[(((unsigned __int16)(*(short *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C00u) >> 8] << 10) | *(unsigned int *)LODWORD(v26) & 0x3FF) & 0x3E0u) >> 3] | (*(int *)&v27[(((*(int *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C00u) >> 8] << 10) | (*(int *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C000000u) >> 24] << 26) | *(unsigned int *)LODWORD(v26) & 0x3FF03FF) & 0x3E00000u) >> 19] << 21) | ((*(int *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C00u) >> 8] << 10) | (*(int *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C000000u) >> 24] << 26) | *(unsigned int *)LODWORD(v26) & 0x3FF03FF) & 0x7C1F7C1F; result = this_ + (*(int *)&v27[4 * (((unsigned __int8)(32 * v27[(((unsigned __int16)(*(short *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C00u) >> 8] << 10) | *(unsigned int *)LODWORD(v26) & 0x3FF) & 0x3E0u) >> 3]) | *(unsigned int *)LODWORD(v26) & 0x1F) & 0x1F)] | (*(int *)&v27[(v30 & 0x1F0000u) >> 14] << 16) | (32 * *(int *)&v27[(((unsigned __int16)(*(short *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C00u) >> 8] << 10) | *(unsigned int *)LODWORD(v26) & 0x3FF) & 0x3E0u) >> 3] | (*(int *)&v27[(((*(int *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C00u) >> 8] << 10) | (*(int *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C000000u) >> 24] << 26) | *(unsigned int *)LODWORD(v26) & 0x3FF03FF) & 0x3E00000u) >> 19] << 21) | ((*(int *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C00u) >> 8] << 10) | (*(int *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C000000u) >> 24] << 26) | *(unsigned int *)LODWORD(v26) & 0x3FF03FF) & 0x7C1F7C1F) & 0xFFE0FFE0); *(unsigned int *)LODWORD(v26) = result; LODWORD(v26) += 4; --v29; } while ( v29 ); LODWORD(v26) += v37; v28 = v32 - 1; } while ( v32 != 1 ); } }*/ } //----- (004A5B81) -------------------------------------------------------- void Render::SetTextureClipRect(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW) { this->bClip = 1; this->uClipX = uX; this->uClipY = uY; this->uClipZ = uZ; this->uClipW = uW; } //----- (004A5BB6) -------------------------------------------------------- void Render::ResetTextureClipRect() { this->bClip = 1; this->uClipX = 0; this->uClipY = 0; this->uClipZ = window->GetWidth(); this->uClipW = 480; } unsigned __int32 Color32(unsigned __int16 color16) { unsigned __int32 c = color16; unsigned int b = (c & 31) * 8; unsigned int g = ((c >> 5) & 63) * 4; unsigned int r = ((c >> 11) & 31) * 8; return (r << 16) | (g << 8) | b;// } //----- (0040DEF3) -------------------------------------------------------- unsigned __int16 Color16(unsigned __int32 r, unsigned __int32 g, unsigned __int32 b) { //return ((unsigned int)b >> (8 - LOBYTE(pRenderer->uTargetBBits))) | pRenderer->uTargetGMask & (g << (LOBYTE(pRenderer->uTargetGBits) + // LOBYTE(pRenderer->uTargetBBits) - 8)) | pRenderer->uTargetRMask & (r << (LOBYTE(pRenderer->uTargetGBits) + // LOBYTE(pRenderer->uTargetRBits) + LOBYTE(pRenderer->uTargetBBits) - 8)); return (b >> (8 - 5)) | 0x7E0 & (g << (6 + 5 - 8)) | 0xF800 & (r << (6 + 5 + 5 - 8)); } //----- (004A5BE3) -------------------------------------------------------- void Render::DrawTextureRGB(unsigned int uOutX, unsigned int uOutY, RGBTexture *a4) { int v4; // edi@3 unsigned __int16 *v6; // esi@3 unsigned int v8; // eax@5 unsigned int v9; // ebx@5 unsigned int v11; // eax@7 unsigned int v12; // ebx@8 unsigned int v15; // eax@14 int v19; // [sp+10h] [bp-8h]@3 int v23; // [sp+28h] [bp+10h]@3 if ( this->uNumSceneBegins && a4 ) { v4 = a4->uWidth; //v5 = &this->pTargetSurface[uOutX + uOutY * this->uTargetSurfacePitch]; v6 = a4->pPixels; v23 = a4->uHeight; v19 = v4; if ( this->bClip ) { if ( (signed int)uOutX < (signed int)this->uClipX ) { v8 = this->uClipX - uOutX; v9 = uOutX - this->uClipX; v8 *= 2; v4 += v9; v6 = (unsigned __int16 *)((char *)v6 + v8); //v5 = (unsigned __int16 *)((char *)v5 + v8); } if ( (signed int)uOutY < (signed int)this->uClipY ) { v11 = this->uClipY - uOutY; v6 += v19 * v11; v23 += uOutY - this->uClipY; //v5 += this->uTargetSurfacePitch * v11; } v12 = max(this->uClipX, uOutX); if ( (signed int)(v4 + v12) > (signed int)this->uClipZ ) { v4 = this->uClipZ - max(this->uClipX, uOutX); } v15 = max(this->uClipY, uOutY); if ( (signed int)(v15 + v23) > (signed int)this->uClipW ) { v23 = this->uClipW - max(this->uClipY, uOutY); } } for (int y = 0; y < v23; y++) { for (int x = 0; x < v4; x++) { WritePixel16(uOutX + x, uOutY + y, *v6); //*v5 = *v6; //++v5; ++v6; } v6 += v19 - v4; //v5 += this->uTargetSurfacePitch - v4; } } } //----- (004A5D33) -------------------------------------------------------- void Render::CreditsTextureScroll(unsigned int pX, unsigned int pY, int move_X, int move_Y, RGBTexture *pTexture) { //unsigned __int16 *v7; // ebx@3 int full_width; // ecx@3 int full_height; // edi@3 //int v23; // edi@23 unsigned __int16 *pTexturea; // [sp+28h] [bp+18h]@3 if ( this->uNumSceneBegins && pTexture ) { /*auto v7 = this->pTargetSurface; if (FORCE_16_BITS) v7 = (unsigned __int32 *)((char *)v7 + (pX + pY * this->uTargetSurfacePitch) * 2); else v7 = (unsigned __int32 *)((char *)v7 + (pX + pY * this->uTargetSurfacePitch) * 4);*/ full_width = pTexture->uWidth - move_X; full_height = pTexture->uHeight - move_Y; pTexturea = &pTexture->pPixels[move_X + move_Y * pTexture->uWidth]; if ( this->bClip ) { if ( pX < this->uClipX )//если кадр выходит за правую границу { pTexturea = (unsigned __int16 *)((char *)pTexturea + (2 * (this->uClipX - pX))); full_width += pX - this->uClipX; //v7 = (unsigned __int32 *)((char *)v7 + ((FORCE_16_BITS ? 2 : 4) * (this->uClipX - pX))); } if ( pY < this->uClipY )//если кадр выходит за верхнюю границу { pTexturea += pTexture->uWidth * (this->uClipY - pY); full_height += pY - this->uClipY; //v7 = (unsigned __int32 *)((char *)v7 + (FORCE_16_BITS ? 2 : 4) * this->uTargetSurfacePitch * (this->uClipY - pY)); } if ( this->uClipX < pX )//если правая граница окна меньше х координаты кадра this->uClipX = pX; if ( this->uClipY < pY )//если верхняя граница окна меньше y координаты кадра this->uClipY = pY; if ( (full_width + this->uClipX) > this->uClipZ )//если ширина кадра выходит за правую границу { if ( this->uClipX < pX ) this->uClipX = pX; full_width = this->uClipZ - this->uClipX; } if ( (full_height + this->uClipY) > this->uClipW )//если высота кадра выходит за нижнюю границу { if ( this->uClipY < pY ) this->uClipY = pY; full_height = this->uClipW - this->uClipY; } } for (int y = 0; y < full_height; ++y) { for (int x = 0; x < full_width; ++x) { if ( *pTexturea != Color16(0, 0xFFu, 0xFFu) ) { WritePixel16(pX + x, pY + y, *pTexturea); /*if (FORCE_16_BITS) *(unsigned __int16 *)v7 = *pTexturea; else *(unsigned __int32 *)v7 = r5g6b5_2_r8g8b8(*pTexturea);*/ } ++pTexturea; //++v7; } //v7 += this->uTargetSurfacePitch - full_width; pTexturea = (unsigned __int16 *)((char *)pTexturea + 2 * (pTexture->uWidth - full_width)); } } } //----- (004A6E7E) -------------------------------------------------------- void Render::DrawTranslucent(unsigned int a2, unsigned int a3, Texture *a4) { int v5; // edx@4 unsigned int v6; // edi@4 unsigned int v7; // edx@5 unsigned int v8; // edx@6 unsigned int v9; // edx@7 unsigned int v10; // edx@8 unsigned int v11; // ebx@9 unsigned int v12; // esi@11 unsigned int v13; // edx@12 unsigned int v14; // ebx@15 unsigned int v15; // esi@17 unsigned int v16; // edi@18 int v18; // [sp+14h] [bp-Ch]@4 int v19; // [sp+18h] [bp-8h]@4 unsigned __int8 *v20; // [sp+1Ch] [bp-4h]@4 if ( this->uNumSceneBegins && a4 && a4->pPalette16 ) { //v4 = &this->pTargetSurface[a2 + a3 * this->uTargetSurfacePitch]; v20 = a4->pLevelOfDetail0_prolly_alpha_mask; v5 = a4->uTextureWidth; v6 = a4->uTextureHeight; v19 = a4->uTextureWidth; v18 = a4->uTextureWidth; int clipped_out_x = a2; int clipped_out_y = a3; if ( this->bClip ) { v7 = this->uClipX; if ( (signed int)a2 < (signed int)v7 ) { v8 = v7 - a2; v20 += v8; v19 += a2 - this->uClipX; //v4 += v8; clipped_out_x = uClipX; } v9 = this->uClipY; if ( (signed int)a3 < (signed int)v9 ) { v10 = v9 - a3; v20 += v18 * v10; v6 = a3 - this->uClipY + a4->uTextureHeight; //v4 += this->uTargetSurfacePitch * v10; clipped_out_y = uClipY; } v11 = this->uClipX; v5 = v19; if ( (signed int)v11 < (signed int)a2 ) v11 = a2; v12 = this->uClipZ; if ( (signed int)(v19 + v11) > (signed int)v12 ) { v13 = this->uClipX; if ( (signed int)v13 < (signed int)a2 ) v13 = a2; v5 = v12 - v13; } v14 = this->uClipY; if ( (signed int)v14 < (signed int)a3 ) v14 = a3; v15 = this->uClipW; if ( (signed int)(v6 + v14) > (signed int)v15 ) { v16 = this->uClipY; if ( (signed int)v16 < (signed int)a3 ) v16 = a3; v6 = v15 - v16; } } for (uint y = 0; y < v6; ++y) { for (int x = 0; x < v5; ++x) { if ( *v20 ) WritePixel16(clipped_out_x + x, clipped_out_y + y, ((unsigned int)a4->pPalette16[*v20] >> 1) & 0x7BEF); ++v20; } v20 += v18 - v5; } /*if ( pRenderer->uTargetGBits == 5 ) { if ( (signed int)v6 > 0 ) { v23 = v6; do { if ( v5 > 0 ) { v21 = v5; do { if ( *v20 ) *v4 = ((unsigned int)a4->pPalette16[*v20] >> 1) & 0x3DEF; ++v4; ++v20; --v21; } while ( v21 ); } v20 += v18 - v5; v17 = v23-- == 1; v4 += this->uTargetSurfacePitch - v5; } while ( !v17 ); } } else { if ( (signed int)v6 > 0 ) { v24 = v6; do { if ( v5 > 0 ) { v22 = v5; do { if ( *v20 ) *v4 = ((unsigned int)a4->pPalette16[*v20] >> 1) & 0x7BEF; ++v4; ++v20; --v22; } while ( v22 ); } v20 += v18 - v5; v17 = v24-- == 1; v4 += this->uTargetSurfacePitch - v5; } while ( !v17 ); } }*/ } } //----- (004A6DF5) -------------------------------------------------------- void Render::_4A6DF5(unsigned __int16 *pBitmap, unsigned int uBitmapPitch, Vec2_int_ *pBitmapXY, void *pTarget, unsigned int uTargetPitch, Vec4_int_ *a7) { int width; // ecx@3 unsigned __int16 *pixels; // ebx@4 int height; // esi@4 if ( !pBitmap || !pTarget) return; width = a7->z - a7->x; height = a7->w - a7->y; pixels = (unsigned short *)pTarget + a7->x + uTargetPitch * a7->y; for ( int y = 0; y < height; ++y ) { for ( int x = 0; x < width; ++x ) { WritePixel16(a7->x + x, a7->y + y, *pixels); ++pixels; } pixels += uTargetPitch - width; } } //----- (004A6D87) -------------------------------------------------------- void Render::FillRectFast(unsigned int uX, unsigned int uY, unsigned int uWidth, unsigned int uHeight, unsigned int uColor16) { if (!uNumSceneBegins) return; unsigned __int32 twoColors = (uColor16 << 16) | uColor16; for (uint y = 0; y < uHeight; ++y) { void *pDst = (char *)pTargetSurface + (FORCE_16_BITS ? 2 : 4) * (uX + (y + uY) * uTargetSurfacePitch); memset32(pDst, FORCE_16_BITS ? twoColors : 0xFF000000 | Color32(uColor16), // two colors per int (16bit) or 1 (32bit) uWidth / (FORCE_16_BITS ? 2 : 1)); // two pixels per int (16bit) or 1 (32bit) if (FORCE_16_BITS && uWidth & 1) // we may miss one pixel for 16bit ((unsigned __int16 *)pTargetSurface)[uX + uWidth - 1 + (y + uY) * uTargetSurfacePitch] = uColor16; } } //----- (004A6C4F) -------------------------------------------------------- void Render::DrawText(signed int uOutX, signed int uOutY, unsigned __int8 *pFontPixels, unsigned int uCharWidth, unsigned int uCharHeight, unsigned __int16 *pFontPalette, unsigned __int16 uFaceColor, unsigned __int16 uShadowColor) { unsigned int v9; // edi@2 unsigned int v10; // esi@2 unsigned int v12; // ebx@3 //signed int v13; // edx@5 int v14; // edx@6 signed int v15; // ebx@7 //unsigned int v16; // edx@9 signed int v17; // edi@10 signed int v18; // ebx@13 unsigned int v19; // edx@15 signed int v20; // esi@16 unsigned __int16 v22; // dx@24 unsigned __int8 *v24; // [sp+Ch] [bp-4h]@2 if (!this->uNumSceneBegins) return; v9 = uCharWidth; v10 = uCharHeight; //v11 = &this->pTargetSurface[uOutX + uOutY * this->uTargetSurfacePitch]; v24 = pFontPixels; int clipped_out_x = uOutX, clipped_out_y = uOutY; if ( this->bClip ) { v12 = this->uClipX; if ( uOutX < (signed int)v12 ) { v24 = &pFontPixels[v12 - uOutX]; //v11 += v12 - uOutX; clipped_out_x = uClipX; v9 = uCharWidth + uOutX - v12; } //v13 = this->uClipY; if ( uOutY < this->uClipY ) { v14 = this->uClipY - uOutY; v24 += uCharWidth * v14; v10 = uCharHeight + uOutY - this->uClipY; //v11 += this->uTargetSurfacePitch * v14; clipped_out_y = uClipY; } v15 = this->uClipX; if ( this->uClipX < uOutX ) v15 = uOutX; //v16 = this->uClipZ; if ( (signed int)(v9 + v15) > (signed int)this->uClipZ ) { v17 = this->uClipX; if ( this->uClipX < uOutX ) v17 = uOutX; v9 = this->uClipZ - v17; } v18 = this->uClipY; if ( this->uClipY < uOutY ) v18 = uOutY; v19 = this->uClipW; if ( (signed int)(v10 + v18) > (signed int)v19 ) { v20 = this->uClipY; if ( this->uClipY < uOutY ) v20 = uOutY; v10 = v19 - v20; } } for (uint y = 0; y < v10; ++y) { for (uint x = 0; x < v9; ++x) { if (*v24) { v22 = uShadowColor; if ( *v24 != 1 ) v22 = uFaceColor; WritePixel16(clipped_out_x + x, clipped_out_y + y, v22); } ++v24; } v24 += uCharWidth - v9; //v23 = uOutXa-- == 1; //v11 += this->uTargetSurfacePitch - v9; } } //----- (004A6A68) -------------------------------------------------------- void Render::GetLeather(unsigned int a2, unsigned int a3, Texture *a4, __int16 height) { Texture tex; // [sp+Ch] [bp-48h]@1 memcpy(&tex, a4, sizeof(tex)); tex.uTextureHeight = a4->uTextureHeight - height; if ( (signed __int16)tex.uTextureHeight > 0 ) DrawTextureIndexed(a2, a3, &tex); } //----- (004A6AB1) -------------------------------------------------------- void Render::DrawTextPalette( int x, int y, unsigned char* font_pixels, int a5, unsigned int uFontHeight, unsigned __int16 *pPalette, int a8 ) { int v8; // edi@2 unsigned int v9; // esi@2 unsigned char *v11; // edx@2 int v14; // edx@6 signed int v15; // ebx@7 signed int v17; // edi@10 signed int v18; // ebx@13 signed int v20; // esi@16 unsigned __int16 v24; // si@35 int v25; // [sp+Ch] [bp-4h]@2 unsigned int v28; // [sp+20h] [bp+10h]@30 int a2 = x; int a3 = y; uint a6 = uFontHeight; if (!this->uNumSceneBegins) return; v8 = a5; v9 = a6; //v10 = &pTargetSurface[x + y * uTargetSurfacePitch]; v11 = (unsigned char *)font_pixels; v25 = (int)font_pixels; int clipped_out_x = x; int clipped_out_y = y; if ( this->bClip ) { if ( a2 < (signed int)this->uClipX ) { v25 = this->uClipX - a2 + (int)font_pixels; //v10 += v12 - a2; v8 = a5 + a2 - this->uClipX; clipped_out_x = uClipX; } if ( a3 < this->uClipY ) { v14 = this->uClipY - a3; v25 += a5 * v14; v9 = a6 + a3 - this->uClipY; //v10 += this->uTargetSurfacePitch * v14; clipped_out_y = uClipY; } v15 = this->uClipX; if ( this->uClipX < a2 ) v15 = a2; if ( v8 + v15 > (signed int)this->uClipZ ) { v17 = this->uClipX; if ( v17 < a2 ) v17 = a2; v8 = this->uClipZ - v17; } v18 = this->uClipY; if ( this->uClipY < a3 ) v18 = a3; if ( (signed int)(v9 + v18) > (signed int)this->uClipW ) { v20 = this->uClipY; if ( this->uClipY < a3 ) v20 = a3; v9 = this->uClipW - v20; } v11 = (unsigned char *)v25; } if ( a8 ) { v28 = 0x7FF; // 16bit pRenderer->uTargetGMask | pRenderer->uTargetBMask; for (uint dy = 0; dy < v9; ++dy) { for (int dx = 0; dx < v8; ++dx) { if ( *v11 ) v24 = pPalette[*v11]; else v24 = v28; WritePixel16(clipped_out_x + dx, clipped_out_y + dy, v24); //*v10 = v24; //++v10; ++v11; //--v27; } v11 += a5 - v8; } /*if ( (signed int)v9 > 0 ) { v23 = a5; v30 = v9; do { if ( v8 > 0 ) { v27 = v8; do { if ( *v11 ) v24 = pPalette[*v11]; else v24 = v28; *v10 = v24; ++v10; ++v11; --v27; } while ( v27 ); } v11 += v23 - v8; v22 = v30-- == 1; v10 += this->uTargetSurfacePitch - v8; } while ( !v22 ); }*/ } else { for (uint dy = 0; dy < v9; ++dy) { for (int dx = 0; dx < v8; ++dx) { if ( *v11 ) WritePixel16(clipped_out_x + dx, clipped_out_y + dy, pPalette[*v11]); //*v10 = v24; //++v10; ++v11; //--v27; } v11 += a5 - v8; } /*if ( (signed int)v9 > 0 ) { v21 = a5; v29 = v9; do { if ( v8 > 0 ) { v26 = v8; do { if ( *v11 ) *v10 = pPalette[*v11]; ++v10; ++v11; --v26; } while ( v26 ); } v11 += v21 - v8; v22 = v29-- == 1; v10 += this->uTargetSurfacePitch - v8; } while ( !v22 ); }*/ } } //----- (004A68EF) -------------------------------------------------------- void Render::DrawTransparentGreenShade(signed int a2, signed int a3, Texture *pTexture) { DrawMasked(a2, a3, pTexture, 0x07E0); } //----- (004A6776) -------------------------------------------------------- void Render::DrawTransparentRedShade(unsigned int a2, unsigned int a3, Texture *a4) { DrawMasked(a2, a3, a4, 0xF800); /*Texture *v4; // edi@2 unsigned int v5; // ebx@4 unsigned __int16 *v6; // eax@4 unsigned int v7; // edx@5 unsigned int v8; // edx@6 unsigned int v9; // edx@7 unsigned int v10; // edx@8 unsigned int v11; // edx@9 unsigned int v12; // esi@12 unsigned int v13; // esi@15 unsigned int v14; // edx@17 unsigned int v15; // esi@18 unsigned __int8 *v16; // ebx@22 char v17; // zf@28 int v18; // [sp+10h] [bp-10h]@4 unsigned __int8 *v19; // [sp+18h] [bp-8h]@4 int v20; // [sp+1Ch] [bp-4h]@4 int a2a; // [sp+28h] [bp+8h]@24 unsigned int a3a; // [sp+2Ch] [bp+Ch]@22 unsigned int a4a; // [sp+30h] [bp+10h]@11 if ( this->uNumSceneBegins ) { v4 = a4; if ( a4 ) { if ( a4->pPalette16 ) { v5 = a4->uTextureHeight; v6 = &this->pTargetSurface[a2 + a3 * this->uTargetSurfacePitch]; v19 = a4->pLevelOfDetail0_prolly_alpha_mask; v20 = a4->uTextureWidth; v18 = a4->uTextureWidth; if ( this->bClip ) { v7 = this->uClipX; if ( (signed int)a2 < (signed int)v7 ) { v8 = v7 - a2; v19 += v8; v20 += a2 - this->uClipX; v6 += v8; } v9 = this->uClipY; v5 = a4->uTextureHeight; if ( (signed int)a3 < (signed int)v9 ) { v10 = v9 - a3; v19 += v18 * v10; v5 = a3 - this->uClipY + a4->uTextureHeight; v4 = a4; v6 += this->uTargetSurfacePitch * v10; } v11 = this->uClipX; if ( (signed int)v11 < (signed int)a2 ) v11 = a2; a4a = this->uClipZ; if ( (signed int)(v11 + v20) > (signed int)a4a ) { v12 = this->uClipX; if ( (signed int)v12 < (signed int)a2 ) v12 = a2; v20 = a4a - v12; } v13 = this->uClipY; if ( (signed int)v13 < (signed int)a3 ) v13 = a3; v14 = this->uClipW; if ( (signed int)(v5 + v13) > (signed int)v14 ) { v15 = this->uClipY; if ( (signed int)v15 < (signed int)a3 ) v15 = a3; v5 = v14 - v15; } } if ( (signed int)v5 > 0 ) { a3a = v5; v16 = v19; do { if ( v20 > 0 ) { a2a = v20; do { if ( *v16 ) *v6 = this->uTargetRMask & v4->pPalette16[*v16]; ++v6; ++v16; --a2a; } while ( a2a ); } v16 += v18 - v20; v17 = a3a-- == 1; v6 += this->uTargetSurfacePitch - v20; } while ( !v17 ); } } } }*/ } //----- (004A68EF) -------------------------------------------------------- void Render::DrawMasked(signed int a2, signed int a3, Texture *pTexture, unsigned __int16 mask) { unsigned int v5; // ebx@4 int v10; // edx@8 signed int v11; // edx@9 signed int v12; // esi@12 signed int v13; // esi@15 signed int v15; // esi@18 unsigned __int8 *v16; // ebx@22 int v18; // [sp+10h] [bp-10h]@4 unsigned __int8 *v19; // [sp+18h] [bp-8h]@4 int v20; // [sp+1Ch] [bp-4h]@4 if (!uNumSceneBegins || !pTexture) return; if ( pTexture->pPalette16 ) { v5 = pTexture->uTextureHeight; //v6 = &this->pTargetSurface[a2 + a3 * this->uTargetSurfacePitch]; v19 = pTexture->pLevelOfDetail0_prolly_alpha_mask; v20 = pTexture->uTextureWidth; v18 = pTexture->uTextureWidth; int clipped_out_x = a2; int clipped_out_y = a3; if ( this->bClip ) { if ( a2 < this->uClipX ) { v19 += this->uClipX - a2; v20 += a2 - this->uClipX; clipped_out_x = uClipX; } v5 = pTexture->uTextureHeight; if ( a3 < this->uClipY ) { v10 = this->uClipY - a3; v19 += v18 * v10; v5 = a3 - this->uClipY + pTexture->uTextureHeight; clipped_out_y = uClipY; } v11 = this->uClipX; if ( this->uClipX < a2 ) v11 = a2; if ( v11 + v20 > (signed int)this->uClipZ ) { v12 = this->uClipX; if ( this->uClipX < a2 ) v12 = a2; v20 = this->uClipZ - v12; } v13 = this->uClipY; if ( this->uClipY < a3 ) v13 = a3; if ( (signed int)(v5 + v13) > (signed int)this->uClipW ) { v15 = this->uClipY; if ( this->uClipY < a3 ) v15 = a3; v5 = this->uClipW - v15; } } v16 = v19; for (uint y = 0; y < v5; ++y) { for (int x = 0; x < v20; ++x) { if ( *v16 ) WritePixel16(clipped_out_x + x, clipped_out_y + y, pTexture->pPalette16[*v16] & mask); ++v16; } v16 += v18 - v20; } /*if ( (signed int)v5 > 0 ) { v22 = v5; v16 = v19; do { if ( v20 > 0 ) { v21 = v20; do { if ( *v16 ) *v6 = this->uTargetGMask & v4->pPalette16[*v16]; ++v6; ++v16; --v21; } while ( v21 ); } v16 += v18 - v20; v17 = v22-- == 1; v6 += this->uTargetSurfacePitch - v20; } while ( !v17 ); }*/ } } //----- (004A65CC) -------------------------------------------------------- void Render::_4A65CC(unsigned int x, unsigned int y, Texture *a4, Texture *a5, int a6, int a7, int a8) { unsigned int uHeight; // edi@6 unsigned int v14; // edx@11 unsigned int v16; // edx@14 unsigned int v17; // edx@17 unsigned int v19; // edx@20 int v20; // eax@27 int v21; // edx@29 unsigned __int8 *v24; // [sp+14h] [bp-4h]@6 int Width; // [sp+2Ch] [bp+14h]@6 if ( this->uNumSceneBegins && a4 && a4->pPalette16 && a5 && a5->pPalette16 ) { v24 = a4->pLevelOfDetail0_prolly_alpha_mask; Width = a4->uTextureWidth; uHeight = a4->uTextureHeight; int clipped_out_x = x; int clipped_out_y = y; if ( this->bClip ) { if ( (signed int)x < (signed int)this->uClipX ) { v24 += this->uClipX - x; Width += x - this->uClipX; clipped_out_x = uClipX; } if ( (signed int)y < (signed int)this->uClipY ) { v24 += a4->uTextureWidth * (this->uClipY - y); uHeight = y - this->uClipY + a4->uTextureHeight; clipped_out_y = uClipY; } v14 = this->uClipX; if ( (signed int)this->uClipX < (signed int)x ) v14 = x; if ( (signed int)(Width + v14) > (signed int)this->uClipZ ) { v16 = this->uClipX; if ( (signed int)this->uClipX < (signed int)x ) v16 = x; Width = this->uClipZ - v16; } v17 = this->uClipY; if ( (signed int)this->uClipY < (signed int)y ) v17 = y; if ( (signed int)(uHeight + v17) > (signed int)this->uClipW ) { v19 = this->uClipY; if ( (signed int)this->uClipY < (signed int)y ) v19 = y; uHeight = this->uClipW - v19; } } for (uint dy = 0; dy < uHeight; ++dy) { for (int dx = 0; dx < Width; ++dx) { v20 = *v24; if ( v20 >= a7 && v20 <= a8 ) { v21 = a7 + (a6 + v20) % (2 * (a8 - a7)); if ( (a6 + v20) % (2 * (a8 - a7)) >= a8 - a7 ) v21 = 2 * a8 - v21 - a7; WritePixel16(clipped_out_x + dx, clipped_out_y + dy, a4->pPalette16[v21]); } ++v24; } v24 += a4->uTextureWidth - Width; } /*if ( (signed int)v9 > 0 ) { ya = v9; v23 = v22 - v27; do { if ( v27 > 0 ) { xa = v27; do { v20 = *v24; if ( v20 >= a7 && v20 <= a8 ) { v21 = a7 + (a6 + v20) % (2 * (a8 - a7)); if ( (a6 + v20) % (2 * (a8 - a7)) >= a8 - a7 ) v21 = 2 * a8 - v21 - a7; *v8 = a4->pPalette16[v21]; } ++v8; ++v24; --xa; } while ( xa ); } v8 += this->uTargetSurfacePitch - v27; v24 += v23; --ya; } while ( ya ); }*/ } } //----- (004A63E6) -------------------------------------------------------- void Render::DrawAura(unsigned int a2, unsigned int a3, Texture *a4, Texture *a5, int a6, int a7, int a8) { unsigned int v14; // edx@11 unsigned int v16; // edx@14 unsigned int v17; // edx@17 unsigned int v19; // edx@20 int v20; // eax@27 int v21; // edx@29 int Height; // [sp+10h] [bp-8h]@6 int Width; // [sp+14h] [bp-4h]@6 int v27; // [sp+24h] [bp+Ch]@23 unsigned __int8 *v28; // [sp+28h] [bp+10h]@6 if ( this->uNumSceneBegins ) { if ( a4 ) { if ( a4->pPalette16 ) { if ( a5 ) { if ( a5->pPalette16 ) { v28 = a4->pLevelOfDetail0_prolly_alpha_mask; Width = a4->uTextureWidth; Height = a4->uTextureHeight; int clipped_out_x = a2; int clipped_out_y = a3; if ( this->bClip ) { if ( (signed int)a2 < (signed int)this->uClipX ) { v28 += this->uClipX - a2; Width += a2 - this->uClipX; clipped_out_x = uClipX; } if ( (signed int)a3 < (signed int)this->uClipY ) { v28 += a4->uTextureWidth * (this->uClipY - a3); Height += a3 - this->uClipY; clipped_out_y = uClipY; } v14 = this->uClipX; if ( (signed int)this->uClipX < (signed int)a2 ) v14 = a2; if ( (signed int)(Width + v14) > (signed int)this->uClipZ ) { v16 = this->uClipX; if ( (signed int)this->uClipX < (signed int)a2 ) v16 = a2; Width = this->uClipZ - v16; } v17 = this->uClipY; if ( (signed int)this->uClipY < (signed int)a3 ) v17 = a3; if ( (signed int)(Height + v17) > (signed int)this->uClipW ) { v19 = this->uClipY; if ( (signed int)this->uClipY < (signed int)a3 ) v19 = a3; Height = this->uClipW - v19; } } v27 = 0; for (int y = 0; y < Height; ++y) { for (int x = 0; x < Width; ++x) { if ( *v28 ) { v20 = *(&a5->pLevelOfDetail0_prolly_alpha_mask[x & a5->uWidthMinus1] + a5->uTextureWidth * (v27 & a5->uHeightMinus1)); if ( v20 >= a7 ) { if ( v20 <= a8 ) { v21 = a7 + (a6 + v20) % (2 * (a8 - a7)); if ( (a6 + v20) % (2 * (a8 - a7)) >= a8 - a7 ) v21 = 2 * a8 - v21 - a7; //v9 = a5; //*v10 = a5->pPalette16[v21]; WritePixel16(clipped_out_x + x, clipped_out_y + y, a5->pPalette16[v21]); } } } v28++; } v28 += a4->uTextureWidth - Width; } /*if ( v24 > 0 ) { v23 = v22 - v25; do { for ( i = 0; i < v25; ++v28 ) { if ( *v28 ) { v20 = *(&v9->pLevelOfDetail0_prolly_alpha_mask[i & v9->uWidthMinus1] + v9->uTextureWidth * (v27 & v9->uHeightMinus1)); if ( v20 >= a7 ) { if ( v20 <= a8 ) { v21 = a7 + (a6 + v20) % (2 * (a8 - a7)); if ( (a6 + v20) % (2 * (a8 - a7)) >= a8 - a7 ) v21 = 2 * a8 - v21 - a7; v9 = a5; *v10 = a5->pPalette16[v21]; } } } ++i; ++v10; } ++v27; v10 += this->uTargetSurfacePitch - v25; v28 += v23; } while ( v27 < v24 ); }*/ } } } } } } //----- (004A6274) -------------------------------------------------------- void Render::DrawTextureTransparent(unsigned int uX, unsigned int uY, Texture *pTexture) { int uHeight; // ebx@4 unsigned int v11; // edx@9 unsigned int v12; // esi@12 unsigned int v13; // esi@15 unsigned int v15; // esi@18 unsigned __int8 *v19; // [sp+18h] [bp-8h]@4 int uWidth; // [sp+1Ch] [bp-4h]@4 if ( this->uNumSceneBegins ) { if ( pTexture ) { if ( pTexture->pPalette16 ) { uHeight = pTexture->uTextureHeight; v19 = pTexture->pLevelOfDetail0_prolly_alpha_mask; uWidth = pTexture->uTextureWidth; int clipped_out_x = uX; int clipped_out_y = uY; if ( this->bClip ) { if ( (signed int)uX < (signed int)this->uClipX ) { v19 += this->uClipX - uX; uWidth += uX - this->uClipX; clipped_out_x = uClipX; } uHeight = pTexture->uTextureHeight; if ( (signed int)uY < (signed int)this->uClipY ) { v19 += pTexture->uTextureWidth * (this->uClipY - uY); uHeight = uY - this->uClipY + pTexture->uTextureHeight; clipped_out_y = uClipY; } v11 = this->uClipX; if ( (signed int)this->uClipX < (signed int)uX ) v11 = uX; if ( (signed int)(v11 + uWidth) > (signed int)this->uClipZ ) { v12 = this->uClipX; if ( (signed int)this->uClipX < (signed int)uX ) v12 = uX; uWidth = this->uClipZ - v12; } v13 = this->uClipY; if ( (signed int)this->uClipY < (signed int)uY ) v13 = uY; if ( (signed int)(uHeight + v13) > (signed int)this->uClipW ) { v15 = this->uClipY; if ( (signed int)this->uClipY < (signed int)uY ) v15 = uY; uHeight = this->uClipW - v15; } } for (int y = 0; y < uHeight; ++y) { for (int x = 0; x < uWidth; ++x) { if ( *v19 ) WritePixel16(clipped_out_x + x, clipped_out_y + y, pTexture->pPalette16[*v19]); ++v19; } v19 += pTexture->uTextureWidth - uWidth; } /*if ( (signed int)uHeight > 0 ) { uYa = uHeight; v16 = v19; do { if ( uWidth > 0 ) { uXa = uWidth; do { if ( *v16 ) *v6 = pCurrentTexture->pPalette16[*v16]; ++v6; ++v16; } while ( uXa-- !=1 ); } v16 += v18 - uWidth; uFlag = uYa-- == 1; v6 += this->uTargetSurfacePitch - uWidth; } while ( !uFlag ); }*/ } } } } //----- (004A612A) -------------------------------------------------------- void Render::DrawMaskToZBuffer(signed int uOutX, unsigned int uOutY, Texture *pTexture, int zVal) { unsigned int v6; // edx@3 int v7; // ebx@3 int v8; // edi@3 int v10; // eax@5 signed int v12; // esi@8 signed int v14; // esi@11 unsigned int v15; // esi@14 unsigned int v17; // ecx@17 int v18; // edx@23 int v19; // [sp+Ch] [bp-Ch]@3 int v20; // [sp+10h] [bp-8h]@3 int uOutXa; // [sp+20h] [bp+8h]@21 unsigned __int8 *uOutYa; // [sp+24h] [bp+Ch]@3 int *pZBuffer; // [sp+28h] [bp+10h]@3 if ( this->uNumSceneBegins ) { if ( pTexture ) { v6 = uOutY; v7 = pTexture->uTextureHeight; pZBuffer = &this->pActiveZBuffer[uOutX + window->GetWidth() * uOutY]; uOutYa = pTexture->pLevelOfDetail0_prolly_alpha_mask; v8 = pTexture->uTextureWidth; v20 = pTexture->uTextureWidth; v19 = pTexture->uTextureWidth; if ( this->bClip ) { if ( uOutX < this->uClipX ) { v10 = this->uClipX - uOutX; uOutYa += v10; v8 += uOutX - this->uClipX; v20 = v8; pZBuffer += v10; } if ( (signed int)v6 < (signed int)this->uClipY ) { uOutYa += v19 * (this->uClipY - v6); v7 += v6 - this->uClipY; pZBuffer += window->GetWidth() * (this->uClipY - v6); v8 = v20; } v12 = this->uClipX; if ( this->uClipX < uOutX ) v12 = uOutX; if ( v8 + v12 > (signed int)this->uClipZ ) { v14 = this->uClipX; if ( this->uClipX < uOutX ) v14 = uOutX; v8 = this->uClipZ - v14; } v15 = this->uClipY; if ( (signed int)this->uClipY < (signed int)v6 ) v15 = v6; if ( (signed int)(v7 + v15) > (signed int)this->uClipW ) { v17 = this->uClipY; if ( (signed int)this->uClipY >= (signed int)v6 ) v6 = v17; v7 = this->uClipW - v6; } } if ( v7 > 0 ) { uOutXa = v7; do { if ( v8 > 0 ) { v18 = v8; do { if ( *uOutYa ) *pZBuffer = zVal; ++pZBuffer; ++uOutYa; --v18; } while ( v18 ); } pZBuffer += window->GetWidth() - v8; uOutYa += v19 - v8; --uOutXa; } while ( uOutXa ); } } } } //----- (004A601E) -------------------------------------------------------- void Render::ZBuffer_Fill_2(signed int a2, signed int a3, Texture *pTexture, int a5) { signed int v5; // edx@3 int v6; // ebx@3 int v7; // esi@3 void *v8; // esi@3 signed int v11; // edi@8 signed int v13; // edi@11 unsigned int v14; // edi@14 unsigned int v16; // ecx@17 int v17; // [sp+18h] [bp+Ch]@3 unsigned int pTexturea; // [sp+1Ch] [bp+10h]@3 if ( this->uNumSceneBegins && pTexture ) { v5 = a3; v6 = pTexture->uTextureHeight; v7 = 5 * a3; v17 = pTexture->uTextureHeight; v8 = &this->pActiveZBuffer[a2 + (v7 << 7)]; pTexturea = pTexture->uTextureWidth; if ( this->bClip ) { if ( a2 < (signed int)this->uClipX ) { pTexturea += a2 - this->uClipX; v8 = (char *)v8 + 4 * (this->uClipX - a2); } if ( v5 < (signed int)this->uClipY ) { v17 += v5 - this->uClipY; v8 = (char *)v8 + 2560 * (this->uClipY - v5); } v11 = this->uClipX; if ( this->uClipX < a2 ) v11 = a2; if ( (signed int)(pTexturea + v11) > (signed int)this->uClipZ ) { v13 = this->uClipX; if ( this->uClipX < a2 ) v13 = a2; pTexturea = this->uClipZ - v13; } v14 = this->uClipY; if ( (signed int)this->uClipY < v5 ) v14 = v5; v6 = v17; if ( (signed int)(v17 + v14) > (signed int)this->uClipW ) { v16 = this->uClipY; if ( (signed int)this->uClipY < v5 ) v16 = v5; v6 = this->uClipW - v16; } } if ( v6 > 0 ) { do { if ( (signed int)pTexturea > 0 ) { memset32(v8, a5, pTexturea); v8 = (char *)v8 + 4 * pTexturea; } v8 = (char *)v8 + 4 * (window->GetWidth() - pTexturea); --v6; } while ( v6 ); } } } //----- (004A5EB2) -------------------------------------------------------- void Render::DrawTextureIndexed(unsigned int uX, unsigned int uY, Texture *a4) { int v5; // ebx@4 unsigned int v8; // edx@6 unsigned int v10; // edx@8 unsigned int v11; // edx@9 unsigned int v12; // esi@12 unsigned int v13; // esi@15 unsigned int v15; // esi@18 int v18; // [sp+10h] [bp-10h]@4 unsigned __int8 *v19; // [sp+18h] [bp-8h]@4 int v20; // [sp+1Ch] [bp-4h]@4 if ( this->uNumSceneBegins ) { if ( a4 ) { if ( a4->pPalette16 ) { v5 = a4->uTextureHeight; //pTarget = &this->pTargetSurface[uX + uY * this->uTargetSurfacePitch]; v19 = a4->pLevelOfDetail0_prolly_alpha_mask; v20 = a4->uTextureWidth; v18 = a4->uTextureWidth; int clipped_out_x = uX; int clipped_out_y = uY; if ( this->bClip ) { if ( (signed int)uX < (signed int)this->uClipX ) { v8 = this->uClipX - uX; v19 += v8; v20 += uX - this->uClipX; clipped_out_x = uClipX; } v5 = a4->uTextureHeight; if ( (signed int)uY < (signed int)this->uClipY ) { v10 = this->uClipY - uY; v19 += v18 * v10; v5 = uY - this->uClipY + a4->uTextureHeight; //v4 = a4; clipped_out_y = uClipY; } v11 = this->uClipX; if ( (signed int)this->uClipX < (signed int)uX ) v11 = uX; if ( (signed int)(v11 + v20) > (signed int)this->uClipZ ) { v12 = this->uClipX; if ( (signed int)this->uClipX < (signed int)uX ) v12 = uX; v20 = this->uClipZ - v12; } v13 = this->uClipY; if ( (signed int)this->uClipY < (signed int)uY ) v13 = uY; if ( (signed int)(v5 + v13) > (signed int)uClipW ) { v15 = this->uClipY; if ( (signed int)this->uClipY < (signed int)uY ) v15 = uY; v5 = uClipW - v15; } } for (int y = 0; y < v5; ++y) { for (int x = 0; x < v20; ++x) { if ( a4->pPalette16[*v19] != 0x7FF )// 2047 WritePixel16(clipped_out_x + x, clipped_out_y + y, a4->pPalette16[*v19]); ++v19; } v19 += v18 - v20; } /*if ( (signed int)v5 > 0 ) { uYa = v5; v16 = v19; do { if ( v20 > 0 ) { uXa = v20; do { *pTarget = v4->pPalette16[*v16]; ++pTarget; ++v16; --uXa; } while ( uXa ); } v16 += v18 - v20; v17 = uYa-- == 1; pTarget += this->uTargetSurfacePitch - v20; } while ( !v17 ); }*/ } } } } //----- (004667E9) -------------------------------------------------------- void Render::ChangeBetweenWinFullscreenModes() { float v0; // ST14_4@17 int v4; // edx@26 ObjectDesc *v5; // eax@26 RGBTexture *v6; // esi@33 const char *v8; // [sp-4h] [bp-28h]@33 // struct tagRECT Rect; // [sp+14h] [bp-10h]@15 /*if ( !pRenderer->bWindowMode && (dword_6BE364_game_settings_1 & 2) ) { ModalWindow(pGlobalTXT_LocalizationStrings[62], UIMSG_0);// "Might and Magic VII requires your desktop to be in 16bit (32k or 65k) Color mode in order to operate in a window." return; }*/ if ( bWindowMode || pRenderD3D->pAvailableDevices->bIsDeviceCompatible ) { if ( pEventTimer->bPaused ) dword_6BE364_game_settings_1 |= GAME_SETTINGS_0800; else pEventTimer->Pause(); if ( pMiscTimer->bPaused ) dword_6BE364_game_settings_1 |= GAME_SETTINGS_1000; else pMiscTimer->Pause(); pMouse->bActive = 0; if ( pRenderD3D ) { pBitmaps_LOD->ReleaseHardwareTextures(); pSprites_LOD->ReleaseAll(); } if ( bWindowMode ) { //SetMenu(hWnd, 0); //SetWindowLongA(hWnd, -20, 0); //SetWindowLongA(hWnd, -16, 0x10000000u); window->SetFullscreenMode(); pRenderer->InitializeFullscreen(); v0 = (double)(signed int)uGammaPos * 0.1 + 0.6; pGame->pGammaController->Initialize(v0); } else { //ClipCursor(0); window->SetWindowedMode(window->GetWidth(), window->GetHeight()); pRenderer->SwitchToWindow(); } if ( pRenderD3D ) { pBitmaps_LOD->_410423_move_textures_to_device(); pSprites_LOD->MoveSpritesToVideoMemory(); } if (!( pPaletteManager->uNumTargetBBits == uTargetBBits && pPaletteManager->uNumTargetGBits == uTargetGBits && pPaletteManager->uNumTargetRBits == uTargetRBits )) { pPaletteManager->SetColorChannelInfo(uTargetRBits, uTargetGBits, uTargetBBits); pPaletteManager->RecalculateAll(); pBitmaps_LOD->SetupPalettes(uTargetRBits, uTargetGBits, uTargetBBits); pIcons_LOD->SetupPalettes(uTargetRBits, uTargetGBits, uTargetBBits); for (uint i = 0; i < pObjectList->uNumObjects; i++) { BYTE3(v4) = 0; v5 = &pObjectList->pObjects[i]; *(short *)((char *)&v4 + 1) = v5->uParticleTrailColorR; LOBYTE(v4) = v5->uParticleTrailColorG; v5->uParticleTrailColor = v5->uParticleTrailColorB | (v4 << 8); } SetUserInterface(pParty->alignment, true); if ( pMediaPlayer->pVideoFrame.pPixels ) pMediaPlayer->pVideoFrame.Load(pMediaPlayer->pVideoFrameTextureFilename, 1); if ( sCurrentMenuID != MENU_CREATEPARTY ) { if ( sCurrentMenuID == MENU_CREDITSPROC ) dword_A74C88 = 1; } else { if ( sCurrentMenuID ) { v6 = &pTexture_PCX; pTexture_PCX.Release(); v8 = "makeme.pcx"; } else { v6 = &pTexture_PCX; pTexture_PCX.Release(); v8 = "title.pcx"; if ( sCurrentMenuID ) v8 = "lsave640.pcx"; } v6->Load(v8, 0); } } viewparams->bRedrawGameUI = 1; viewparams->InitGrayPalette(); pMouse->SetCurrentCursorBitmap(); /*if ( pRenderer->bWindowMode ) { //MoveWindow(hWnd, uWindowX, uWindowY, uWindowWidth, uWindowHeight, 0); CenterWindowAndAdjustSize(hWnd, windowed_mode_width, windowed_mode_height); ShowWindow(hWnd, SW_SHOWNORMAL); }*/ pMouse->bActive = true; if ( pMovie_Track ) pMediaPlayer->SelectMovieType(); if (dword_6BE364_game_settings_1 & GAME_SETTINGS_0800) dword_6BE364_game_settings_1 &= ~GAME_SETTINGS_0800; else pEventTimer->Resume(); if (dword_6BE364_game_settings_1 & GAME_SETTINGS_1000) dword_6BE364_game_settings_1 &= ~GAME_SETTINGS_1000; else pMiscTimer->Resume(); } } //----- (004524D8) -------------------------------------------------------- HWLTexture *RenderHWLContainer::LoadTexture(const char *pName, int bMipMaps) { void *v13; // eax@13 int v16; // esi@14 int v17; // ecx@16 int v18; // esi@16 unsigned __int16 *v19; // eax@16 int v20; // edx@16 int v21; // ecx@16 int v22; // eax@16 int v23; // esi@16 unsigned __int16 *v26; // [sp+24h] [bp-10h]@13 int v27; // [sp+28h] [bp-Ch]@14 int v28; // [sp+2Ch] [bp-8h]@13 int pDestb; // [sp+3Ch] [bp+8h]@15 if (!uNumItems) return nullptr; /////////////////////////////// //quick search(быстрый поиск)// /////////////////////////////// uint idx1 = 0, idx2 = uNumItems; while (true) { uint i = idx1 + (idx2 - idx1) / 2; int res = _stricmp(pName, pSpriteNames[i]); if (!res) { fseek(pFile, pSpriteOffsets[i], SEEK_SET); break; } else if (res < 0) idx2 = idx1 + (idx2 - idx1) / 2; else idx1 = i + 1; if ( idx1 >= idx2 ) return false; } uint uCompressedSize = 0; fread(&uCompressedSize, 4, 1, pFile); HWLTexture* pTex = new HWLTexture; fread(&pTex->uBufferWidth, 4, 1, pFile); fread(&pTex->uBufferHeight, 4, 1, pFile); fread(&pTex->uAreaWidth, 4, 1, pFile); fread(&pTex->uAreaHeigth, 4, 1, pFile); fread(&pTex->uWidth, 4, 1, pFile); fread(&pTex->uHeight, 4, 1, pFile); fread(&pTex->uAreaX, 4, 1, pFile); fread(&pTex->uAreaY, 4, 1, pFile); pTex->pPixels = new unsigned __int16[pTex->uWidth * pTex->uHeight]; if (uCompressedSize) { char* pCompressedData = new char[uCompressedSize]; fread(pCompressedData, 1, uCompressedSize, pFile); uint uDecompressedSize = pTex->uWidth * pTex->uHeight * sizeof(short); zlib::MemUnzip(pTex->pPixels, &uDecompressedSize, pCompressedData, uCompressedSize); delete [] pCompressedData; } else fread(pTex->pPixels, 2, pTex->uWidth * pTex->uHeight, pFile); if ( scale_hwls_to_half ) { __debugbreak();//Ritor1 pTex->uHeight /= 2; pTex->uWidth /= 2; v13 = new unsigned __int16[pTex->uWidth * pTex->uHeight]; v28 = 0; v26 = (unsigned __int16 *)v13; if ( pTex->uHeight > 0 ) { v16 = pTex->uWidth; v27 = 1; do { pDestb = 0; if ( v16 > 0 ) { do { v17 = v16 * v27; v18 = v28 * v16; v19 = pTex->pPixels; v20 = pDestb + 2 * v18; v21 = (int)&v19[2 * (pDestb + v17)]; v22 = (int)&v19[2 * v20]; LOWORD(v20) = *(unsigned short *)(v21 + 2); LOWORD(v21) = *(unsigned short *)v21; v23 = pDestb + v18; pDestb++; v26[v23] = _452442_color_cvt(*(unsigned short *)v22, *(unsigned short *)(v22 + 2), v21, v20); v16 = pTex->uWidth; } while (pDestb < pTex->uWidth); } ++v28; v27 += 2; } while ( v28 < (signed int)pTex->uHeight ); } delete [] pTex->pPixels; pTex->pPixels = v26; } return pTex; } //----- (0045271F) -------------------------------------------------------- bool RenderHWLContainer::Release() { __int32 v4; // eax@6 FILE *v5; // ST24_4@6 FILE *File; // [sp+4h] [bp-4h]@6 if ( this->bDumpDebug) { File = fopen("logd3d.txt", "w"); v4 = ftell(this->pFile); v5 = this->pFile; this->uDataOffset = v4; fwrite(&this->uNumItems, 4u, 1u, v5); for (uint i = 0; i < this->uNumItems; i++) { fwrite(this->pSpriteNames[i], 1u, 0x14u, this->pFile); fprintf(File, "D3D texture name: %s\t\toffset: %x\n", this->pSpriteNames[i], *(unsigned int *)(&(this->pSpriteNames[i]) + 200000/sizeof(char*))); } fwrite(this->pSpriteOffsets, 4u, this->uNumItems, this->pFile); fseek(this->pFile, 4, 0); fwrite(&this->uDataOffset, 4u, 1u, this->pFile); fclose(this->pFile); fclose(File); } else { fclose(this->pFile); for (uint i = 0; i < this->uNumItems; i++) { delete[] this->pSpriteNames[i]; } } return true; } //----- (00452347) -------------------------------------------------------- RenderHWLContainer::RenderHWLContainer(): bDumpDebug(false) { this->pFile = 0; uSignature = 0; this->uDataOffset = 0; memset(&this->uNumItems, 0, 0x61A84u); this->uNumItems = 0; this->scale_hwls_to_half = false; } //----- (0045237F) -------------------------------------------------------- bool RenderHWLContainer::Load(const wchar_t *pFilename) { pFile = _wfopen(pFilename, L"rb"); if (!pFile) { Log::Warning(L"Failed to open file: %s", pFilename); return false; } fread(&uSignature, 1, 4, pFile); if (uSignature != 'TD3D') { Log::Warning(L"Invalid format: %s", pFilename); return false; } fread(&uDataOffset, 4, 1, pFile); fseek(pFile, uDataOffset, SEEK_SET); fread(&uNumItems, 4, 1, pFile); memset(pSpriteNames, 0, 50000 * sizeof(char *)); for (uint i = 0; i < uNumItems; ++i) { pSpriteNames[i] = new char[20]; fread(pSpriteNames[i], 1, 20, pFile); } fread(pSpriteOffsets, 4, uNumItems, pFile); return true; } //----- (004A1C1E) -------------------------------------------------------- void Render::DoRenderBillboards_D3D() { ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE)); /*if (pRenderer->uNumBillboardsToDraw) { auto p = &pRenderer->pBillboardRenderListD3D[0]; for (int i = 0; i < p->uNumVertices; ++i) { p->pQuads[i].pos.z -= p->pQuads[i].pos.z * 0.6; //p->pQuads[i].rhw = + 0.8 * (1.0f - p->pQuads[i].rhw); } p->pQuads[0].pos.x = 10; p->pQuads[0].pos.y = 10; p->pQuads[1].pos.x = 10; p->pQuads[1].pos.y = 200; p->pQuads[2].pos.x = 100; p->pQuads[2].pos.y = 200; p->pQuads[3].pos.x = 100; p->pQuads[3].pos.y = 10; if (p->uOpacity != RenderBillboardD3D::NoBlend) SetBillboardBlendOptions(p->uOpacity); pRenderer->pRenderD3D->pDevice->SetTexture(0, p->pTexture); ErrD3D(pRenderer->pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, p->pQuads, p->uNumVertices, D3DDP_DONOTLIGHT | D3DDP_DONOTUPDATEEXTENTS)); }*/ for (int i = uNumBillboardsToDraw - 1; i >= 0; --i) { if (pBillboardRenderListD3D[i].opacity != RenderBillboardD3D::NoBlend) SetBillboardBlendOptions(pBillboardRenderListD3D[i].opacity); pRenderD3D->pDevice->SetTexture(0, pBillboardRenderListD3D[i].pTexture); ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, pBillboardRenderListD3D[i].pQuads, pBillboardRenderListD3D[i].uNumVertices, D3DDP_DONOTLIGHT | D3DDP_DONOTUPDATEEXTENTS)); } if (bFogEnabled) { bFogEnabled = false; ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, GetLevelFogColor() & 0xFFFFFF)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, 0)); } ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CW)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE)); } //----- (004A1DA8) -------------------------------------------------------- void Render::SetBillboardBlendOptions(RenderBillboardD3D::OpacityType a1) { switch (a1) { case RenderBillboardD3D::Transparent: { if (bFogEnabled) { bFogEnabled = false; ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, GetLevelFogColor() & 0xFFFFFF)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, 0)); } ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE)); } break; case RenderBillboardD3D::Opaque_1: case RenderBillboardD3D::Opaque_2: case RenderBillboardD3D::Opaque_3: { if (bUsingSpecular) { if (!bFogEnabled) { bFogEnabled = true; ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE)); } } ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, FALSE)); } break; default: Log::Warning(L"SetBillboardBlendOptions: invalid opacity type (%u)", a1); assert(false); break; } } //----- (00424CD7) -------------------------------------------------------- int ODM_NearClip(unsigned int num_vertices) { bool current_vertices_flag; // edi@1 bool next_vertices_flag; // [sp+Ch] [bp-24h]@6 double t; // st6@10 bool bFound; bFound = false; if (!num_vertices) return 0; for (uint i = 0; i < num_vertices; ++i)// есть ли пограничные вершины { if ( array_50AC10[i].vWorldViewPosition.x > 8.0 ) { bFound = true; break; } } if ( !bFound ) return 0; memcpy(&array_50AC10[num_vertices], &array_50AC10[0], sizeof(array_50AC10[0])); current_vertices_flag = false; next_vertices_flag = false; if ( array_50AC10[0].vWorldViewPosition.x <= 8.0 ) current_vertices_flag = true; //check for near clip plane(проверка по ближней границе) // // v3.__________________. v0 // | | // | | // | | // ----------------------- 8.0(near_clip - 8.0) // | | // .__________________. // v2 v1 int out_num_vertices = 0; for (uint i = 0; i < num_vertices; ++i) { next_vertices_flag = array_50AC10[i + 1].vWorldViewPosition.x <= 8.0;// if ( current_vertices_flag ^ next_vertices_flag ) { if ( next_vertices_flag )//следующая вершина за ближней границей { //t = near_clip - v0.x / v1.x - v0.x (формула получения точки пересечения отрезка с плоскостью) t = (8.0 - array_50AC10[i].vWorldViewPosition.x) / (array_50AC10[i + 1].vWorldViewPosition.x - array_50AC10[i].vWorldViewPosition.x); array_507D30[out_num_vertices].vWorldViewPosition.x = 8.0; array_507D30[out_num_vertices].vWorldViewPosition.y = array_50AC10[i].vWorldViewPosition.y + (array_50AC10[i + 1].vWorldViewPosition.y - array_50AC10[i].vWorldViewPosition.y) * t; array_507D30[out_num_vertices].vWorldViewPosition.z = array_50AC10[i].vWorldViewPosition.z + (array_50AC10[i + 1].vWorldViewPosition.z - array_50AC10[i].vWorldViewPosition.z) * t; array_507D30[out_num_vertices].u = array_50AC10[i].u + (array_50AC10[i + 1].u - array_50AC10[i].u) * t; array_507D30[out_num_vertices].v = array_50AC10[i].v + (array_50AC10[i + 1].v - array_50AC10[i].v) * t; array_507D30[out_num_vertices]._rhw = 1.0 / 8.0; } else// текущая вершина за ближней границей { t = (8.0 - array_50AC10[i].vWorldViewPosition.x) / (array_50AC10[i].vWorldViewPosition.x - array_50AC10[i + 1].vWorldViewPosition.x); array_507D30[out_num_vertices].vWorldViewPosition.x = 8.0; array_507D30[out_num_vertices].vWorldViewPosition.y = array_50AC10[i].vWorldViewPosition.y + (array_50AC10[i].vWorldViewPosition.y - array_50AC10[i + 1].vWorldViewPosition.y) * t; array_507D30[out_num_vertices].vWorldViewPosition.z = array_50AC10[i].vWorldViewPosition.z + (array_50AC10[i].vWorldViewPosition.z - array_50AC10[i + 1].vWorldViewPosition.z) * t; array_507D30[out_num_vertices].u = array_50AC10[i].u + (array_50AC10[i].u - array_50AC10[i + 1].u) * t; array_507D30[out_num_vertices].v = array_50AC10[i].v + (array_50AC10[i].v - array_50AC10[i + 1].v) * t; array_507D30[out_num_vertices]._rhw = 1.0 / 8.0; } //array_507D30[out_num_vertices]._rhw = 0x3E000000u; ++out_num_vertices; } if ( !next_vertices_flag ) { memcpy(&array_507D30[out_num_vertices], &array_50AC10[i + 1], sizeof(array_50AC10[i + 1])); out_num_vertices++; } current_vertices_flag = next_vertices_flag; } return out_num_vertices >= 3 ? out_num_vertices : 0; } //----- (00424EE0) -------------------------------------------------------- int ODM_FarClip(unsigned int uNumVertices) { bool current_vertices_flag; // [sp+Ch] [bp-28h]@6 bool next_vertices_flag; // edi@1 double t; // st6@10 signed int depth_num_vertices; // [sp+18h] [bp-1Ch]@1 bool bFound; //Доп инфо "Программирование трёхмерных игр для windows" Ламот стр 910 bFound = false; memcpy(&array_50AC10[uNumVertices], &array_50AC10[0], sizeof(array_50AC10[uNumVertices])); depth_num_vertices = 0; current_vertices_flag = false; if ( array_50AC10[0].vWorldViewPosition.x >= pODMRenderParams->shading_dist_mist ) current_vertices_flag = true;//настоящая вершина больше границы видимости if ( (signed int)uNumVertices <= 0 ) return 0; for (uint i = 0; i < uNumVertices; ++i)// есть ли пограничные вершины { if ( array_50AC10[i].vWorldViewPosition.x < pODMRenderParams->shading_dist_mist ) { bFound = true; break; } } if ( !bFound ) return 0; //check for far clip plane(проверка по дальней границе) // // v3.__________________. v0 // | | // | | // | | // ----------------------- 8192.0(far_clip - 0x2000) // | | // .__________________. // v2 v1 for ( uint i = 0; i < uNumVertices; ++i ) { next_vertices_flag = array_50AC10[i + 1].vWorldViewPosition.x >= pODMRenderParams->shading_dist_mist; if ( current_vertices_flag ^ next_vertices_flag )//одна из граней за границей видимости { if ( next_vertices_flag )//следующая вершина больше границы видимости(настоящая вершина меньше границы видимости) - v3 { //t = far_clip - v2.x / v3.x - v2.x (формула получения точки пересечения отрезка с плоскостью) t = (pODMRenderParams->shading_dist_mist - array_50AC10[i].vWorldViewPosition.x) / (array_50AC10[i].vWorldViewPosition.x - array_50AC10[i + 1].vWorldViewPosition.x); array_507D30[depth_num_vertices].vWorldViewPosition.x = pODMRenderParams->shading_dist_mist; //New_y = v2.y + (v3.y - v2.y)*t array_507D30[depth_num_vertices].vWorldViewPosition.y = array_50AC10[i].vWorldViewPosition.y + (array_50AC10[i].vWorldViewPosition.y - array_50AC10[i + 1].vWorldViewPosition.y) * t; //New_z = v2.z + (v3.z - v2.z)*t array_507D30[depth_num_vertices].vWorldViewPosition.z = array_50AC10[i].vWorldViewPosition.z + (array_50AC10[i].vWorldViewPosition.z - array_50AC10[i + 1].vWorldViewPosition.z) * t; array_507D30[depth_num_vertices].u = array_50AC10[i].u + (array_50AC10[i].u - array_50AC10[i + 1].u) * t; array_507D30[depth_num_vertices].v = array_50AC10[i].v + (array_50AC10[i].v - array_50AC10[i + 1].v) * t; array_507D30[depth_num_vertices]._rhw = 1.0 / pODMRenderParams->shading_dist_mist; } else//настоящая вершина больше границы видимости(следующая вершина меньше границы видимости) - v0 { //t = far_clip - v1.x / v0.x - v1.x t = (pODMRenderParams->shading_dist_mist - array_50AC10[i].vWorldViewPosition.x) / (array_50AC10[i + 1].vWorldViewPosition.x - array_50AC10[i].vWorldViewPosition.x); array_507D30[depth_num_vertices].vWorldViewPosition.x = pODMRenderParams->shading_dist_mist; //New_y = (v0.y - v1.y)*t + v1.y array_507D30[depth_num_vertices].vWorldViewPosition.y = array_50AC10[i].vWorldViewPosition.y + (array_50AC10[i + 1].vWorldViewPosition.y - array_50AC10[i].vWorldViewPosition.y) * t; //New_z = (v0.z - v1.z)*t + v1.z array_507D30[depth_num_vertices].vWorldViewPosition.z = array_50AC10[i].vWorldViewPosition.z + (array_50AC10[i + 1].vWorldViewPosition.z - array_50AC10[i].vWorldViewPosition.z) * t; array_507D30[depth_num_vertices].u = array_50AC10[i].u + (array_50AC10[i + 1].u - array_50AC10[i].u) * t; array_507D30[depth_num_vertices].v = array_50AC10[i].v + (array_50AC10[i + 1].v - array_50AC10[i].v) * t; array_507D30[depth_num_vertices]._rhw = 1.0 / pODMRenderParams->shading_dist_mist; } ++depth_num_vertices; } if ( !next_vertices_flag )//оба в границе видимости { memcpy(&array_507D30[depth_num_vertices], &array_50AC10[i + 1], sizeof(array_507D30[depth_num_vertices])); depth_num_vertices++; } current_vertices_flag = next_vertices_flag; } return depth_num_vertices >= 3 ? depth_num_vertices : 0; } //----- (0047840D) -------------------------------------------------------- void Render::DrawBuildingsD3D() { int v9; // ecx@8 Texture *pFaceTexture; // eax@10 unsigned int v16; // edi@22 int v27; // eax@57 // int vertex_id; // eax@58 unsigned int v34; // eax@80 int v40; // [sp-4h] [bp-5Ch]@2 int v49; // [sp+2Ch] [bp-2Ch]@10 int v50; // [sp+30h] [bp-28h]@34 int v51; // [sp+34h] [bp-24h]@35 int v52; // [sp+38h] [bp-20h]@36 int v53; // [sp+3Ch] [bp-1Ch]@8 int uNumVertices; // [sp+4Ch] [bp-Ch]@34 int unused; // [sp+50h] [bp-8h]@3 if ( !pRenderD3D ) { MessageBoxW(nullptr, L"D3D version of RenderBuildings called in software!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Odbuild.cpp:73", 0); } unused = 0; if ( (signed int)pOutdoor->uNumBModels > 0 ) { for ( uint model_id = 0; model_id < (unsigned int)pOutdoor->uNumBModels; model_id++ ) { if ( IsBModelVisible(model_id, &unused) ) { pOutdoor->pBModels[model_id].field_40 |= 1; if ( pOutdoor->pBModels[model_id].uNumFaces > 0 ) { for ( int face_id = 0; face_id < pOutdoor->pBModels[model_id].uNumFaces; face_id++ ) { if (!pOutdoor->pBModels[model_id].pFaces[face_id].Invisible()) { v53 = 0; array_77EC08[pODMRenderParams->uNumPolygons].flags = 0; array_77EC08[pODMRenderParams->uNumPolygons].field_32 = 0; v9 = pOutdoor->pBModels[model_id].pFaces[face_id].uTextureID; if (pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & FACE_TEXTURE_FRAME) v9 = pTextureFrameTable->GetFrameTexture(v9, pEventTimer->uTotalGameTimeElapsed); pFaceTexture = pBitmaps_LOD->GetTexture(v9); array_77EC08[pODMRenderParams->uNumPolygons].pTexture = pFaceTexture; if (pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & FACE_FLUID) array_77EC08[pODMRenderParams->uNumPolygons].flags |= 2; if (pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & FACE_INDOOR_SKY ) HIBYTE(array_77EC08[pODMRenderParams->uNumPolygons].flags) |= 4; if ( pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & FACE_FLOW_DIAGONAL ) HIBYTE(array_77EC08[pODMRenderParams->uNumPolygons].flags) |= 4; else { if ( pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & FACE_FLOW_VERTICAL ) HIBYTE(array_77EC08[pODMRenderParams->uNumPolygons].flags) |= 8; } if (pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & FACE_FLOW_HORIZONTAL) array_77EC08[pODMRenderParams->uNumPolygons].flags |= 0x2000; else { if (pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & FACE_DONT_CACHE_TEXTURE) HIBYTE(array_77EC08[pODMRenderParams->uNumPolygons].flags) |= 0x10; } array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaU = pOutdoor->pBModels[model_id].pFaces[face_id].sTextureDeltaU; array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaV = pOutdoor->pBModels[model_id].pFaces[face_id].sTextureDeltaV; v16 = GetTickCount() >> 4; if ( pOutdoor->pBModels[model_id].pFaces[face_id].pFacePlane.vNormal.z && abs(pOutdoor->pBModels[model_id].pFaces[face_id].pFacePlane.vNormal.z) >= 59082 ) { if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 4 ) array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaV += v16 & array_77EC08[pODMRenderParams->uNumPolygons].pTexture->uHeightMinus1; if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 8 ) array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaV -= v16 & array_77EC08[pODMRenderParams->uNumPolygons].pTexture->uHeightMinus1; } else { if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 4 ) array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaV -= v16 & array_77EC08[pODMRenderParams->uNumPolygons].pTexture->uHeightMinus1; if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 8 ) array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaV += v16 & array_77EC08[pODMRenderParams->uNumPolygons].pTexture->uHeightMinus1; } if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 0x10 ) array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaU -= v16 & array_77EC08[pODMRenderParams->uNumPolygons].pTexture->uWidthMinus1; else { if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 0x20 ) array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaU += v16 & array_77EC08[pODMRenderParams->uNumPolygons].pTexture->uWidthMinus1; } v50 = 0; v49 = 0; uNumVertices = pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices; if ( pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices > 0 ) { for ( uint vertex_id = 1; vertex_id <= pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices; vertex_id++ ) { array_73D150[vertex_id - 1].vWorldPosition.x = pOutdoor->pBModels[model_id].pVertices.pVertices[pOutdoor->pBModels[model_id].pFaces[face_id].pVertexIDs[vertex_id - 1]].x; array_73D150[vertex_id - 1].vWorldPosition.y = pOutdoor->pBModels[model_id].pVertices.pVertices[pOutdoor->pBModels[model_id].pFaces[face_id].pVertexIDs[vertex_id - 1]].y; array_73D150[vertex_id - 1].vWorldPosition.z = pOutdoor->pBModels[model_id].pVertices.pVertices[pOutdoor->pBModels[model_id].pFaces[face_id].pVertexIDs[vertex_id - 1]].z; array_73D150[vertex_id - 1].u = (array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaU + (signed __int16)pOutdoor->pBModels[model_id].pFaces[face_id].pTextureUIDs[vertex_id - 1]) * (1.0 / (double)pFaceTexture->uTextureWidth); array_73D150[vertex_id - 1].v = (array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaV + (signed __int16)pOutdoor->pBModels[model_id].pFaces[face_id].pTextureVIDs[vertex_id - 1]) * (1.0 / (double)pFaceTexture->uTextureHeight); } for ( uint i = 1; i <= pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices; i++ ) { if ( pOutdoor->pBModels[model_id].pVertices.pVertices[pOutdoor->pBModels[model_id].pFaces[face_id].pVertexIDs[0]].z == array_73D150[i - 1].vWorldPosition.z ) ++v53; pGame->pIndoorCameraD3D->ViewTransform(&array_73D150[i - 1], 1); if ( array_73D150[i - 1].vWorldViewPosition.x < 8.0 || array_73D150[i - 1].vWorldViewPosition.x > pODMRenderParams->shading_dist_mist ) { if ( array_73D150[i - 1].vWorldViewPosition.x >= 8.0 ) v49 = 1; else v50 = 1; } else pGame->pIndoorCameraD3D->Project(&array_73D150[i - 1], 1, 0); } } if ( v53 == pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices ) LOBYTE(array_77EC08[pODMRenderParams->uNumPolygons].field_32) |= 1; array_77EC08[pODMRenderParams->uNumPolygons].pODMFace = &pOutdoor->pBModels[model_id].pFaces[face_id]; array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices = pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices; array_77EC08[pODMRenderParams->uNumPolygons].field_59 = 5; v51 = fixpoint_mul(-pOutdoor->vSunlight.x, pOutdoor->pBModels[model_id].pFaces[face_id].pFacePlane.vNormal.x); v53 = fixpoint_mul(-pOutdoor->vSunlight.y, pOutdoor->pBModels[model_id].pFaces[face_id].pFacePlane.vNormal.y); v52 = fixpoint_mul(-pOutdoor->vSunlight.z, pOutdoor->pBModels[model_id].pFaces[face_id].pFacePlane.vNormal.z); array_77EC08[pODMRenderParams->uNumPolygons].dimming_level = 20 - fixpoint_mul(20, v51 + v53 + v52); if ( array_77EC08[pODMRenderParams->uNumPolygons].dimming_level < 0 ) array_77EC08[pODMRenderParams->uNumPolygons].dimming_level = 0; if ( array_77EC08[pODMRenderParams->uNumPolygons].dimming_level > 31 ) array_77EC08[pODMRenderParams->uNumPolygons].dimming_level = 31; if ( pODMRenderParams->uNumPolygons >= 1999 + 5000) return; if ( ODMFace::IsBackfaceNotCulled(array_73D150, &array_77EC08[pODMRenderParams->uNumPolygons]) ) { pOutdoor->pBModels[model_id].pFaces[face_id].bVisible = 1; array_77EC08[pODMRenderParams->uNumPolygons].uBModelFaceID = face_id; array_77EC08[pODMRenderParams->uNumPolygons].uBModelID = model_id; v27 = 8 * (face_id | (model_id << 6)); LOBYTE(v27) = v27 | 6; array_77EC08[pODMRenderParams->uNumPolygons].field_50 = v27; for ( int vertex_id = 0; vertex_id < pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices; ++vertex_id) { memcpy(&array_50AC10[vertex_id], &array_73D150[vertex_id], sizeof(array_50AC10[vertex_id])); array_50AC10[vertex_id]._rhw = 1.0 / (array_73D150[vertex_id].vWorldViewPosition.x + 0.0000001); } static stru154 static_RenderBuildingsD3D_stru_73C834; /*static bool __init_flag = false; if (!__init_flag) { __init_flag = true; static_RenderBuildingsD3D_byte_73C84C_init_flag |= 1u; stru154::stru154(&static_RenderBuildingsD3D_stru_73C834); atexit(loc_4789D4); }*/ v40 = (int)&pOutdoor->pBModels[model_id].pFaces[face_id]; pGame->pLightmapBuilder->ApplyLights_OutdoorFace(&pOutdoor->pBModels[model_id].pFaces[face_id]); pDecalBuilder->ApplyDecals_OutdoorFace(&pOutdoor->pBModels[model_id].pFaces[face_id]); pGame->pLightmapBuilder->std__vector_000004_size = 0; int v31 = 0; if ( stru_F8AD28.uNumLightsApplied > 0 || pDecalBuilder->uNumDecals > 0 ) { v31 = v50 ? 3 : v49 != 0 ? 5 : 0; static_RenderBuildingsD3D_stru_73C834.GetFacePlaneAndClassify(&pOutdoor->pBModels[model_id].pFaces[face_id], &pOutdoor->pBModels[model_id].pVertices); if ( pDecalBuilder->uNumDecals > 0 ) { v40 = -1; pDecalBuilder->ApplyDecals(31 - array_77EC08[pODMRenderParams->uNumPolygons].dimming_level, 2, &static_RenderBuildingsD3D_stru_73C834, pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices, array_50AC10, 0, (char)v31, -1); } } if ( stru_F8AD28.uNumLightsApplied > 0 ) pGame->pLightmapBuilder->ApplyLights(&stru_F8AD28, &static_RenderBuildingsD3D_stru_73C834, uNumVertices, array_50AC10, 0, (char)v31); if ( v50 ) { array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices = ODM_NearClip(pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices); uNumVertices = array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices; ODM_Project(array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices); } if ( v49 ) { array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices = ODM_FarClip(pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices); uNumVertices = array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices; ODM_Project(array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices); } if ( uNumVertices ) { if ( array_77EC08[pODMRenderParams->uNumPolygons].flags & 2 ) { if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 0x3C ) v34 = pRenderer->pHDWaterBitmapIDs[0]; else v34 = pRenderer->pHDWaterBitmapIDs[pRenderer->hd_water_current_frame]; v40 = (int)pBitmaps_LOD->pHardwareTextures[v34]; } else v40 = (int)pBitmaps_LOD->pHardwareTextures[v9]; pRenderer->DrawPolygon(uNumVertices, &array_77EC08[pODMRenderParams->uNumPolygons], &pOutdoor->pBModels[model_id].pFaces[face_id], (IDirect3DTexture2 *)v40); } } } } } } } } return; } //----- (00479543) -------------------------------------------------------- void Render::DrawOutdoorSkyD3D() { int v9; // eax@4 int v10; // ebx@4 int v13; // edi@6 int v14; // ecx@6 int v15; // eax@8 int v16; // eax@12 signed __int64 v17; // qtt@13 signed int v18; // ecx@13 struct Polygon pSkyPolygon; // [sp+14h] [bp-150h]@1 int v30; // [sp+134h] [bp-30h]@1 int v32; // [sp+13Ch] [bp-28h]@6 int v33; // [sp+140h] [bp-24h]@2 signed __int64 v34; // [sp+144h] [bp-20h]@1 int v35; // [sp+148h] [bp-1Ch]@4 int v36; // [sp+14Ch] [bp-18h]@2 int v37; // [sp+154h] [bp-10h]@8 int v38; // [sp+158h] [bp-Ch]@1 int v39; // [sp+15Ch] [bp-8h]@4 v30 = (signed __int64)((double)(pODMRenderParams->int_fov_rad * pGame->pIndoorCameraD3D->vPartyPos.z) / ((double)pODMRenderParams->int_fov_rad + 8192.0) + (double)(pViewport->uScreenCenterY)); v34 = cos((double)pGame->pIndoorCameraD3D->sRotationX * 0.0030664064) * 0x2000;//(double)pODMRenderParams->shading_dist_mist, 8192 v38 = (signed __int64)((double)(pViewport->uScreenCenterY) - (double)pODMRenderParams->int_fov_rad / (v34 + 0.0000001) * (sin((double)pGame->pIndoorCameraD3D->sRotationX * 0.0030664064) * (double)-0x2000//(double)pODMRenderParams->shading_dist_mist - (double)pGame->pIndoorCameraD3D->vPartyPos.z)); pSkyPolygon.Create_48607B(&stru_8019C8);//заполняется ptr_38 pSkyPolygon.ptr_38->_48694B_frustum_sky(); pSkyPolygon.uTileBitmapID = pOutdoor->sSky_TextureID;//179(original 166) pSkyPolygon.pTexture = (Texture *)(SLOWORD(pOutdoor->sSky_TextureID) != -1 ? (int)&pBitmaps_LOD->pTextures[SLOWORD(pOutdoor->sSky_TextureID)] : 0); if ( pSkyPolygon.pTexture ) { pSkyPolygon.dimming_level = 0; pSkyPolygon.uNumVertices = 4; //centering(центруем)----------------------------------------------------------------- pSkyPolygon.v_18.x = -stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationX + 16); pSkyPolygon.v_18.y = 0; pSkyPolygon.v_18.z = -stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationX + 16); //sky wiew position(положение неба на экране)------------------------------------------ // X // 0._____________________________.3 // |8,8 468,8 | // | | // | | // Y| | // | | // |8,351 468,351 | // 1._____________________________.2 // array_50AC10[0].vWorldViewProjX = (double)(signed int)pViewport->uViewportTL_X;//8 array_50AC10[0].vWorldViewProjY = (double)(signed int)pViewport->uViewportTL_Y;//8 array_50AC10[1].vWorldViewProjX = (double)(signed int)pViewport->uViewportTL_X;//8 array_50AC10[1].vWorldViewProjY = (double)v38;//247 array_50AC10[2].vWorldViewProjX = (double)(signed int)pViewport->uViewportBR_X;//468 array_50AC10[2].vWorldViewProjY = (double)v38;//247 array_50AC10[3].vWorldViewProjX = (double)(signed int)pViewport->uViewportBR_X;//468 array_50AC10[3].vWorldViewProjY = (double)(signed int)pViewport->uViewportTL_Y;//8 pSkyPolygon.sTextureDeltaU = 224 * pMiscTimer->uTotalGameTimeElapsed;//7168 pSkyPolygon.sTextureDeltaV = 224 * pMiscTimer->uTotalGameTimeElapsed;//7168 pSkyPolygon.field_24 = 0x2000000u;//maybe attributes v33 = 65536 / (signed int)(signed __int64)(((double)(pViewport->uViewportBR_X - pViewport->uViewportTL_X) / 2) / tan(0.6457717418670654) + 0.5); for ( uint i = 0; i < pSkyPolygon.uNumVertices; ++i ) { //rotate skydome(вращение купола неба)-------------------------------------- // В игре принята своя система измерения углов. Полный угол (180). Значению угла 0 соответствует // направление на север и/или юг (либо на восток и/или запад), значению 65536 еденицам(0х10000) соответствует угол 90. // две переменные хранят данные по углу обзора. field_14 по западу и востоку. field_20 по югу и северу // от -25080 до 25080 v39 = fixpoint_mul(pSkyPolygon.ptr_38->viewing_angle_from_west_east, v33 * (v30 - floor(array_50AC10[i].vWorldViewProjY + 0.5))); v35 = v39 + pSkyPolygon.ptr_38->angle_from_north; v39 = fixpoint_mul(pSkyPolygon.ptr_38->viewing_angle_from_north_south, v33 * (v30 - floor(array_50AC10[i].vWorldViewProjY + 0.f))); v36 = v39 + pSkyPolygon.ptr_38->angle_from_east; v9 = fixpoint_mul(pSkyPolygon.v_18.z, v33 * (v30 - floor(array_50AC10[i].vWorldViewProjY + 0.5))); v10 = pSkyPolygon.v_18.x + v9; if ( v10 > 0 ) v10 = 0; v13 = v33 * (pViewport->uScreenCenterX - (signed __int64)array_50AC10[i].vWorldViewProjX); v34 = -pSkyPolygon.field_24; v32 = (signed __int64)array_50AC10[i].vWorldViewProjY - 1.0; v14 = v33 * (v30 - v32); while ( 1 ) { if ( v10 ) { v37 = abs((int)v34 >> 14); v15 = abs(v10); if ( v37 <= v15 || v32 <= (signed int)pViewport->uViewportTL_Y ) { if ( v10 <= 0 ) break; } } v16 = fixpoint_mul(pSkyPolygon.v_18.z, v14); --v32; v14 += v33; v10 = pSkyPolygon.v_18.x + v16; } LODWORD(v17) = LODWORD(v34) << 16; HIDWORD(v17) = v34 >> 16; v18 = v17 / v10; if ( v18 < 0 ) v18 = pODMRenderParams->shading_dist_mist; v37 = v35 + fixpoint_mul(pSkyPolygon.ptr_38->angle_from_west, v13); v35 = 224 * pMiscTimer->uTotalGameTimeElapsed + ((signed int)fixpoint_mul(v37, v18) >> 3); array_50AC10[i].u = (double)v35 / ((double)pSkyPolygon.pTexture->uTextureWidth * 65536.0); v36 = v36 + fixpoint_mul(pSkyPolygon.ptr_38->angle_from_south, v13); v35 = 224 * pMiscTimer->uTotalGameTimeElapsed + ((signed int)fixpoint_mul(v36, v18) >> 3); array_50AC10[i].v = (double)v35 / ((double)pSkyPolygon.pTexture->uTextureHeight * 65536.0); array_50AC10[i].vWorldViewPosition.x = (double)0x2000;//pODMRenderParams->shading_dist_mist 8192 array_50AC10[i]._rhw = 1.0 / (double)(v18 >> 16); } pRenderer->DrawOutdoorSkyPolygon(pSkyPolygon.uNumVertices, &pSkyPolygon, pBitmaps_LOD->pHardwareTextures[(signed __int16)pSkyPolygon.uTileBitmapID]); array_50AC10[0].vWorldViewProjY = (double)v10; array_50AC10[1].vWorldViewProjY = array_50AC10[1].vWorldViewProjY + 30.0; array_50AC10[2].vWorldViewProjY = array_50AC10[2].vWorldViewProjY + 30.0; array_50AC10[3].vWorldViewProjY = (double)v10; pRenderer->DrawOutdoorSkyPolygon(pSkyPolygon.uNumVertices, &pSkyPolygon, pBitmaps_LOD->pHardwareTextures[(signed __int16)pSkyPolygon.uTileBitmapID]); return; } } //----- (004226C2) -------------------------------------------------------- bool PauseGameDrawing() { if ( pCurrentScreen != SCREEN_GAME && pCurrentScreen != SCREEN_NPC_DIALOGUE && pCurrentScreen != SCREEN_CHANGE_LOCATION ) { if (pCurrentScreen == SCREEN_INPUT_BLV) return pMovie_Track;//pSmackerMovie != 0; if ( pCurrentScreen != SCREEN_BRANCHLESS_NPC_DIALOG ) return true; } return false; } //----- (0045E03A) -------------------------------------------------------- unsigned short *Render::MakeScreenshot(signed int width, signed int height) { unsigned __int16 *for_pixels; // ebx@1 DDSURFACEDESC2 Dst; // [sp+4h] [bp-A0h]@6 unsigned __int16 *pPixels; // [sp+80h] [bp-24h]@1 float interval_x; // [sp+84h] [bp-20h]@1 float interval_y; // [sp+8Ch] [bp-18h]@1 interval_x = game_viewport_width / (double)width; interval_y = game_viewport_height / (double)height; pPixels = (unsigned __int16 *)malloc(2 * height * width); memset(pPixels, 0 , 2 * height * width); for_pixels = pPixels; BeginSceneD3D(); if (uCurrentlyLoadedLevelType == LEVEL_Indoor) pIndoor->Draw(); else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) pOutdoor->Draw(); DrawBillboards_And_MaybeRenderSpecialEffects_And_EndScene(); memset(&Dst, 0, sizeof(Dst)); Dst.dwSize = sizeof(Dst); if ( LockSurface_DDraw4(pBackBuffer4, &Dst, DDLOCK_WAIT) ) { if (uCurrentlyLoadedLevelType == LEVEL_null) memset(&for_pixels, 0, sizeof(for_pixels)); else { for (uint y = 0; y < (unsigned int)height; ++y) { for (uint x = 0; x < (unsigned int)width; ++x) { if (Dst.ddpfPixelFormat.dwRGBBitCount == 32) { unsigned __int32 *p = (unsigned __int32 *)Dst.lpSurface + (int)(x * interval_x + 8.0) + (int)(y * interval_y + 8.0) * (Dst.lPitch >> 2); *for_pixels = Color16((*p >> 16) & 255, (*p >> 8) & 255, *p & 255); } else if (Dst.ddpfPixelFormat.dwRGBBitCount == 16) { unsigned __int16 * p = (unsigned __int16 *)Dst.lpSurface + (int)(x * interval_x + 8.0) + y * Dst.lPitch; *for_pixels = *p; } else assert(false); ++for_pixels; } } } ErrD3D(pBackBuffer4->Unlock(NULL)); } return pPixels; } //----- (0045E26C) -------------------------------------------------------- void Render::SaveScreenshot(const char *pFilename, unsigned int width, unsigned int height) { auto pixels = MakeScreenshot(width, height); SavePCXImage(pFilename, pixels, width, height); free(pixels); } void Render::PackScreenshot(unsigned int width, unsigned int height, void *data, unsigned int data_size, unsigned int *out_screenshot_size) { auto pixels = MakeScreenshot(150, 112); PackPCXpicture(pixels, 150, 112, data, 1000000, out_screenshot_size); free(pixels); } //----- (0046A7C8) -------------------------------------------------------- int Render::_46А6АС_GetActorsInViewport(int pDepth) { unsigned int v3; // eax@2 применяется в закле Жар печи для подсчёта кол-ва монстров видимых группе и заполнения массива id видимых монстров unsigned int v5; // eax@2 unsigned int v6; // eax@4 unsigned int v12; // [sp+10h] [bp-14h]@1 int mon_num; // [sp+1Ch] [bp-8h]@1 unsigned int a1a; // [sp+20h] [bp-4h]@1 mon_num = 0; v12 = GetBillboardDrawListSize(); if ( (signed int)GetBillboardDrawListSize() > 0 ) { for ( a1a = 0; (signed int)a1a < (signed int)v12; ++a1a ) { v3 = GetParentBillboardID(a1a); v5 = (unsigned __int16)pBillboardRenderList[v3].object_pid; if ( PID_TYPE(v5) == OBJECT_Actor) { if ( pBillboardRenderList[v3].sZValue <= (unsigned int)(pDepth << 16) ) { v6 = PID_ID(v5); if ( pActors[v6].uAIState != Dead && pActors[v6].uAIState != Dying && pActors[v6].uAIState != Removed && pActors[v6].uAIState != Disabled && pActors[v6].uAIState != Summoned ) { if ( pGame->pVisInstance->DoesRayIntersectBillboard((double)pDepth, a1a) ) { if ( mon_num < 100 ) { _50BF30_actors_in_viewport_ids[mon_num] = v6; mon_num++; } } } } } } } return mon_num; } void Render::BeginLightmaps() { ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP)); if (bUsingSpecular) pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, FALSE)); ErrD3D(pRenderD3D->pDevice->SetTexture(0, pGame->pIndoorCameraD3D->LoadTextureAndGetHardwarePtr("effpar03"))); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE)); } void Render::EndLightmaps() { ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE)); if (bUsingSpecular) { ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, uFogColor)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, 0)); } } void Render::BeginLightmaps2() { if (bUsingSpecular) ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, FALSE)); ErrD3D(pRenderD3D->pDevice->SetTexture(0, pGame->pIndoorCameraD3D->LoadTextureAndGetHardwarePtr("effpar03"))); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE)); } void Render::EndLightmaps2() { ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CW)); if (bUsingSpecular) ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE)); } //----- (00437C96) -------------------------------------------------------- void Render::do_draw_debug_line_d3d(const RenderVertexD3D3 *pLineBegin, signed int sDiffuseBegin, const RenderVertexD3D3 *pLineEnd, signed int sDiffuseEnd, float z_stuff) { double v6; // st7@2 //IDirect3DDevice3 *v7; // eax@2 // HRESULT v8; // eax@2 std::string v9; // [sp-18h] [bp-60h]@3 // const char *v10; // [sp-Ch] [bp-54h]@2 // const char *v11; // [sp-8h] [bp-50h]@2 // int v12; // [sp-4h] [bp-4Ch]@2 RenderVertexD3D3 v13[2]; // [sp+8h] [bp-40h]@2 //if ( pRenderer->pRenderD3D ) { v6 = 0.001 - z_stuff; memcpy(v13, pLineBegin, 0x20u); memcpy(&v13[1], pLineEnd, sizeof(v13[1])); v13[0].pos.z = v6; v13[1].pos.z = v6; v13[0].diffuse = sDiffuseBegin; v13[1].diffuse = sDiffuseEnd; ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr)); ErrD3D(pRenderD3D->pDevice->DrawPrimitive( D3DPT_LINELIST, 452, v13, 2, 16)); } } void Render::DrawLines(const RenderVertexD3D3 *vertices, unsigned int num_vertices) { ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr)); ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_LINELIST, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, (void *)vertices, num_vertices, D3DDP_DONOTLIGHT)); } void Render::DrawFansTransparent(const RenderVertexD3D3 *vertices, unsigned int num_vertices) { //ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false)); //ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, false)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA)); ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr)); ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, (void *)vertices, num_vertices, 28)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); //ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, TRUE)); //ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); } void Render::BeginDecals() { // code chunk from 0049C304 if (bUsingSpecular) ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE)); ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, FALSE)); ErrD3D(pRenderD3D->pDevice->SetTexture(0, pGame->pIndoorCameraD3D->LoadTextureAndGetHardwarePtr("hwsplat04"))); } void Render::EndDecals() { // code chunk from 0049C304 ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CW)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); if (bUsingSpecular) ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE)); } //----- (0049C095) -------------------------------------------------------- void Render::DrawDecal(Decal *pDecal, float z_bias) { signed int v21; // [sp+Ch] [bp-864h]@15 RenderVertexD3D3 pVerticesD3D[64]; // [sp+20h] [bp-850h]@6 if (pDecal->uNumVertices < 3) { Log::Warning(L"Decal has < 3 vertices"); return; } float color_mult; if ( pDecal->field_C1C & 1 ) color_mult = 1.0; else color_mult = pDecal->field_C18->_43B570_get_color_mult_by_time(); for (uint i = 0; i < (unsigned int)pDecal->uNumVertices; ++i) { uint uTint = Render::GetActorTintColor(pDecal->pVertices[i].vWorldViewPosition.x, pDecal->field_C14, 0, 0, nullptr); uint uTintR = (uTint >> 16) & 0xFF, uTintG = (uTint >> 8) & 0xFF, uTintB = uTint & 0xFF; uint uDecalColorMultR = (pDecal->uColorMultiplier >> 16) & 0xFF, uDecalColorMultG = (pDecal->uColorMultiplier >> 8) & 0xFF, uDecalColorMultB = pDecal->uColorMultiplier & 0xFF; uint uFinalR = floorf(uTintR / 255.0 * color_mult * uDecalColorMultR + 0.0f), uFinalG = floorf(uTintG / 255.0 * color_mult * uDecalColorMultG + 0.0f), uFinalB = floorf(uTintB / 255.0 * color_mult * uDecalColorMultB + 0.0f); float v15; if (fabs(z_bias) < 1e-5) v15 = 1.0 - 1.0 / ((1.0f / pGame->pIndoorCameraD3D->GetShadingDistMist()) * pDecal->pVertices[i].vWorldViewPosition.x * 1000.0); else { v15 = 1.0 - 1.0 / ((1.0f / pGame->pIndoorCameraD3D->GetShadingDistMist()) * pDecal->pVertices[i].vWorldViewPosition.x * 1000.0) - z_bias; if (v15 < 0.000099999997) v15 = 0.000099999997; } pVerticesD3D[i].pos.z = v15; pVerticesD3D[i].pos.x = pDecal->pVertices[i].vWorldViewProjX; pVerticesD3D[i].pos.y = pDecal->pVertices[i].vWorldViewProjY; pVerticesD3D[i].texcoord.x = pDecal->pVertices[i].u; pVerticesD3D[i].texcoord.y = pDecal->pVertices[i].v; pVerticesD3D[i].diffuse = (uFinalR << 16) | (uFinalG << 8) | uFinalB; pVerticesD3D[i].specular = 0; pVerticesD3D[i].rhw = 1.0 / pDecal->pVertices[i].vWorldViewPosition.x; } if (uCurrentlyLoadedLevelType == LEVEL_Indoor) v21 = D3DDP_DONOTLIGHT | D3DDP_DONOTCLIP | D3DDP_DONOTUPDATEEXTENTS; else v21 = D3DDP_DONOTLIGHT; ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, pVerticesD3D, pDecal->uNumVertices, v21)); } void Render::DrawSpecialEffectsQuad(const RenderVertexD3D3 *vertices, IDirect3DTexture2 *texture) { ErrD3D(pRenderD3D->pDevice->SetTexture(0, texture)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, FALSE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, D3DCMP_ALWAYS)); ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, (void *)vertices, 4, 28)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE)); ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, D3DCMP_LESS)); } //----- (00452442) -------------------------------------------------------- unsigned int __fastcall _452442_color_cvt(unsigned __int16 a1, unsigned __int16 a2, int a3, int a4) { int v4; // ebx@0 __int16 v5; // ST14_2@1 __int16 v6; // dx@1 int v7; // ecx@1 __int16 v8; // ST10_2@1 int v9; // edi@1 unsigned __int16 v10; // dh@1@1 int v11; // ebx@1 int v12; // ebx@1 __int16 a3a; // [sp+1Ch] [bp+8h]@1 v5 = a2 >> 2; v6 = (unsigned __int16)a4 >> 2; v8 = a1 >> 2; a3a = (unsigned __int16)a3 >> 2; LOWORD(v7) = a3a; v9 = v7; LOWORD(v4) = ((unsigned __int16)a4 >> 2) & 0xE0; LOWORD(v7) = a3a & 0xE0; LOWORD(v9) = v9 & 0x1C00; v11 = v7 + v4; LOWORD(v7) = v5 & 0xE0; v12 = v7 + v11; LOWORD(v7) = v8 & 0xE0; __debugbreak(); // warning C4700: uninitialized local variable 'v10' used return (PID_TYPE(v8) + PID_TYPE(v5) + PID_TYPE(a3a) + PID_TYPE(v6)) | (v7 + v12) | ((v8 & 0x1C00) + (v5 & 0x1C00) + v9 + (__PAIR__(v10, (unsigned __int16)a4 >> 2) & 0x1C00)); } //----- (0047C4FC) -------------------------------------------------------- int __fastcall GetActorTintColor(int max_dimm, int min_dimm, float distance, int a4, RenderBillboard *a5) { //int v5; // esi@1 signed int v6; // edx@1 //signed int result; // eax@2 int v8; // eax@3 double v9; // st7@12 //double v10; // ST0C_8@18 int v11; // ecx@28 //signed int v12; // edi@28 //double v13; // ST0C_8@33 //double v14; // ST0C_8@34 double v15; // st7@44 //double v16; // ST0C_8@44 //double v17; // ST0C_8@44 int v18; // ST14_4@44 //double v19; // ST0C_8@44 signed int v20; // [sp+10h] [bp-4h]@10 // float a3a; // [sp+1Ch] [bp+8h]@33 //float a3b; // [sp+1Ch] [bp+8h]@34 float a3c; // [sp+1Ch] [bp+8h]@44 //float a3d; // [sp+1Ch] [bp+8h]@44 //float a4b; // [sp+20h] [bp+Ch]@18 //int a4a; // [sp+20h] [bp+Ch]@33 //float a4c; // [sp+20h] [bp+Ch]@44 //float a4d; // [sp+20h] [bp+Ch]@44 int a5a; // [sp+24h] [bp+10h]@44 //v5 = a2; v6 = 0; if (uCurrentlyLoadedLevelType == LEVEL_Indoor) return 8 * (31 - max_dimm) | ((8 * (31 - max_dimm) | ((31 - max_dimm) << 11)) << 8); if (pParty->armageddon_timer) return 0xFFFF0000; v8 = pWeather->bNight; if (bUnderwater) v8 = 0; if (v8) { v20 = 1; if ((signed __int64)pParty->pPartyBuffs[PARTY_BUFF_TORCHLIGHT].uExpireTime > 0) v20 = pParty->pPartyBuffs[PARTY_BUFF_TORCHLIGHT].uPower; v9 = (double)v20 * 1024.0; if (a4) { v6 = 216; goto LABEL_20; } if (distance <= v9) { if (distance > 0.0) { //a4b = distance * 216.0 / v9; //v10 = a4b + 6.7553994e15; //v6 = LODWORD(v10); v6 = floorf(0.5f + distance * 216.0 / v9); if (v6 > 216) { v6 = 216; goto LABEL_20; } } } else { v6 = 216; } if (distance != 0.0) { LABEL_20: if (a5) v6 = 8 * _43F55F_get_billboard_light_level(a5, v6 >> 3); if (v6 > 216) v6 = 216; return (255 - v6) | ((255 - v6) << 16) | ((255 - v6) << 8); } //LABEL_19: v6 = 216; goto LABEL_20; } if (fabsf(distance) < 1.0e-6f) return 0xFFF8F8F8; // dim in measured in 8-steps v11 = 8 * (max_dimm - min_dimm); //v12 = v11; if (v11 >= 0) { if (v11 > 216) v11 = 216; } else v11 = 0; float fog_density_mult = 216.0f; if (a4) fog_density_mult += distance / (double)pODMRenderParams->shading_dist_shade * 32.0; v6 = v11 + floorf(pOutdoor->fFogDensity * fog_density_mult + 0.5f); /*if ( a4 ) { //a3b = pOutdoor->fFogDensity * 216.0; //v14 = a3b + 6.7553994e15; //a4a = floorf(a3b + 0.5f);//LODWORD(v14); } else { //a3a = (distance / (double)pODMRenderParams->shading_dist_shade * 32.0 + 216.0) * pOutdoor->fFogDensity; //v13 = a3a + 6.7553994e15; //a4a = floorf(a3a + 0.5f);//LODWORD(v13); } v6 = a4a + v11;*/ if (a5) v6 = 8 * _43F55F_get_billboard_light_level(a5, v6 >> 3); if (v6 > 216) v6 = 216; if (v6 < v11) v6 = v11; if (v6 > 8 * pOutdoor->max_terrain_dimming_level) v6 = 8 * pOutdoor->max_terrain_dimming_level; if (!bUnderwater) return (255 - v6) | ((255 - v6) << 16) | ((255 - v6) << 8); else { v15 = (double)(255 - v6) * 0.0039215689; a3c = v15; //a4c = v15 * 16.0; //v16 = a4c + 6.7553994e15; a5a = floorf(v15 * 16.0 + 0.5f);//LODWORD(v16); //a4d = a3c * 194.0; //v17 = a4d + 6.7553994e15; v18 = floorf(a3c * 194.0 + 0.5f);//LODWORD(v17); //a3d = a3c * 153.0; //v19 = a3d + 6.7553994e15; return (int)floorf(a3c * 153.0 + 0.5f)/*LODWORD(v19)*/ | ((v18 | (a5a << 8)) << 8); } } // 6BE3C4: using guessed type char bUnderwater; //----- (0043F55F) -------------------------------------------------------- int __fastcall _43F55F_get_billboard_light_level(RenderBillboard *a1, int uBaseLightLevel) { signed int v3; // ecx@2 if (uCurrentlyLoadedLevelType == LEVEL_Indoor) v3 = pIndoor->pSectors[a1->uIndoorSectorID].uMinAmbientLightLevel; else { if (uBaseLightLevel == -1) v3 = a1->dimming_level; else v3 = uBaseLightLevel; } return _43F5C8_get_point_light_level_with_respect_to_lights(v3, a1->uIndoorSectorID, a1->world_x, a1->world_y, a1->world_z); } //----- (0043F5C8) -------------------------------------------------------- int __fastcall _43F5C8_get_point_light_level_with_respect_to_lights(unsigned int uBaseLightLevel, int uSectorID, float x, float y, float z) { // int v5; // esi@1 signed int v6; // edi@1 int v8; // eax@6 int v9; // ebx@6 unsigned int v10; // ecx@6 unsigned int v11; // edx@9 unsigned int v12; // edx@11 signed int v13; // ecx@12 BLVLightMM7 *v16; // esi@20 int v17; // ebx@21 // int v18; // eax@24 // int v19; // ebx@24 // unsigned int v20; // ecx@24 // int v21; // edx@25 // unsigned int v22; // edx@27 // unsigned int v23; // edx@29 signed int v24; // ecx@30 int v26; // ebx@35 // int v27; // eax@38 // int v28; // ebx@38 // unsigned int v29; // ecx@38 // int v30; // edx@39 // unsigned int v31; // edx@41 // unsigned int v32; // edx@43 //signed int v33; // ecx@44 int v37; // [sp+Ch] [bp-18h]@37 // int v38; // [sp+10h] [bp-14h]@5 int v39; // [sp+10h] [bp-14h]@23 int v40; // [sp+10h] [bp-14h]@36 int v42; // [sp+14h] [bp-10h]@22 unsigned int v43; // [sp+18h] [bp-Ch]@12 unsigned int v44; // [sp+18h] [bp-Ch]@30 unsigned int v45; // [sp+18h] [bp-Ch]@44 v6 = uBaseLightLevel; for (uint i = 0; i < pMobileLightsStack->uNumLightsActive; ++i) { MobileLight* p = &pMobileLightsStack->pLights[i]; float distX = abs(p->vPosition.x - x); if (distX <= p->uRadius) { float distY = abs(p->vPosition.y - y); if (distY <= p->uRadius) { float distZ = abs(p->vPosition.z - z); if (distZ <= p->uRadius) { v8 = distX; v9 = distY; v10 = distZ; if (distX < distY) { v8 = distY; v9 = distX; } if (v8 < distZ) { v11 = v8; v8 = distZ; v10 = v11; } if (v9 < (signed int)v10) { v12 = v10; v10 = v9; v9 = v12; } v43 = ((unsigned int)(11 * v9) / 32) + (v10 / 4) + v8; v13 = p->uRadius; if ((signed int)v43 < v13) v6 += ((unsigned __int64)(30i64 * (signed int)(v43 << 16) / v13) >> 16) - 30; } } } } if (uCurrentlyLoadedLevelType == LEVEL_Indoor) { BLVSector* pSector = &pIndoor->pSectors[uSectorID]; for (uint i = 0; i < pSector->uNumLights; ++i) { v16 = pIndoor->pLights + pSector->pLights[i]; if (~v16->uAtributes & 8) { v17 = abs(v16->vPosition.x - x); if (v17 <= v16->uRadius) { v42 = abs(v16->vPosition.y - y); if (v42 <= v16->uRadius) { v39 = abs(v16->vPosition.z - z); if (v39 <= v16->uRadius) { v44 = int_get_vector_length(v17, v42, v39); v24 = v16->uRadius; if ((signed int)v44 < v24) v6 += ((unsigned __int64)(30i64 * (signed int)(v44 << 16) / v24) >> 16) - 30; } } } } } } for (uint i = 0; i < pStationaryLightsStack->uNumLightsActive; ++i) { //StationaryLight* p = &pStationaryLightsStack->pLights[i]; v26 = abs(pStationaryLightsStack->pLights[i].vPosition.x - x); if (v26 <= pStationaryLightsStack->pLights[i].uRadius) { v40 = abs(pStationaryLightsStack->pLights[i].vPosition.y - y); if (v40 <= pStationaryLightsStack->pLights[i].uRadius) { v37 = abs(pStationaryLightsStack->pLights[i].vPosition.z - z); if (v37 <= pStationaryLightsStack->pLights[i].uRadius) { v45 = int_get_vector_length(v26, v40, v37); //v33 = pStationaryLightsStack->pLights[i].uRadius; if ((signed int)v45 < pStationaryLightsStack->pLights[i].uRadius) v6 += ((unsigned __int64)(30i64 * (signed int)(v45 << 16) / pStationaryLightsStack->pLights[i].uRadius) >> 16) - 30; } } } } if (v6 <= 31) { if (v6 < 0) v6 = 0; } else v6 = 31; return v6; } //----- (0049D700) -------------------------------------------------------- unsigned int __fastcall GetMaxMipLevels(unsigned int uDim) { int v2; // ecx@1 unsigned int v3; // eax@1 v2 = 0; v3 = uDim - 1; while (v3 & 1) { v3 >>= 1; ++v2; } return v3 == 0 ? v2 : 0; } //----- (0046E44E) -------------------------------------------------------- int _46E44E_collide_against_faces_and_portals(unsigned int b1) { BLVSector *pSector; // edi@1 signed int v2; // ebx@1 BLVFace *pFace; // esi@2 __int16 pNextSector; // si@10 int pArrayNum; // ecx@12 unsigned __int8 v6; // sf@12 unsigned __int8 v7; // of@12 int result; // eax@14 //int v10; // ecx@15 int pFloor; // eax@16 int v15; // eax@24 int v16; // edx@25 int v17; // eax@29 unsigned int v18; // eax@33 int v21; // eax@35 int v22; // ecx@36 int v23; // eax@40 unsigned int v24; // eax@44 int a3; // [sp+10h] [bp-48h]@28 int v26; // [sp+14h] [bp-44h]@15 int i; // [sp+18h] [bp-40h]@1 int a10; // [sp+1Ch] [bp-3Ch]@1 int v29; // [sp+20h] [bp-38h]@14 int v32; // [sp+2Ch] [bp-2Ch]@15 int pSectorsArray[10]; // [sp+30h] [bp-28h]@1 pSector = &pIndoor->pSectors[stru_721530.uSectorID]; i = 1; a10 = b1; pSectorsArray[0] = stru_721530.uSectorID; for (v2 = 0; v2 < pSector->uNumPortals; ++v2) { pFace = &pIndoor->pFaces[pSector->pPortals[v2]]; if (stru_721530.sMaxX <= pFace->pBounding.x2 && stru_721530.sMinX >= pFace->pBounding.x1 && stru_721530.sMaxY <= pFace->pBounding.y2 && stru_721530.sMinY >= pFace->pBounding.y1 && stru_721530.sMaxZ <= pFace->pBounding.z2 && stru_721530.sMinZ >= pFace->pBounding.z1 && abs((pFace->pFacePlane_old.dist + stru_721530.normal.x * pFace->pFacePlane_old.vNormal.x + stru_721530.normal.y * pFace->pFacePlane_old.vNormal.y + stru_721530.normal.z * pFace->pFacePlane_old.vNormal.z) >> 16) <= stru_721530.field_6C + 16) { pNextSector = pFace->uSectorID == stru_721530.uSectorID ? pFace->uBackSectorID : pFace->uSectorID;//FrontSectorID pArrayNum = i++; v7 = i < 10; v6 = i - 10 < 0; pSectorsArray[pArrayNum] = pNextSector; if (!(v6 ^ v7)) break; } } result = 0; for (v29 = 0; v29 < i; v29++) { pSector = &pIndoor->pSectors[pSectorsArray[v29]]; v32 = pSector->uNumFloors + pSector->uNumWalls + pSector->uNumCeilings; for (v26 = 0; v26 < v32; v26++) { pFloor = pSector->pFloors[v26]; pFace = &pIndoor->pFaces[pSector->pFloors[v26]]; if (!pFace->Portal() && stru_721530.sMaxX <= pFace->pBounding.x2 && stru_721530.sMinX >= pFace->pBounding.x1 && stru_721530.sMaxY <= pFace->pBounding.y2 && stru_721530.sMinY >= pFace->pBounding.y1 && stru_721530.sMaxZ <= pFace->pBounding.z2 && stru_721530.sMinZ >= pFace->pBounding.z1 && pFloor != stru_721530.field_84) { v15 = (pFace->pFacePlane_old.dist + stru_721530.normal.x * pFace->pFacePlane_old.vNormal.x + stru_721530.normal.y * pFace->pFacePlane_old.vNormal.y + stru_721530.normal.z * pFace->pFacePlane_old.vNormal.z) >> 16; if (v15 > 0) { v16 = (pFace->pFacePlane_old.dist + stru_721530.normal2.x * pFace->pFacePlane_old.vNormal.x + stru_721530.normal2.y * pFace->pFacePlane_old.vNormal.y + stru_721530.normal2.z * pFace->pFacePlane_old.vNormal.z) >> 16; if (v15 <= stru_721530.prolly_normal_d || v16 <= stru_721530.prolly_normal_d) { if (v16 <= v15) { a3 = stru_721530.field_6C; if (sub_47531C(stru_721530.prolly_normal_d, &a3, stru_721530.normal.x, stru_721530.normal.y, stru_721530.normal.z, stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, pFace, a10)) { v17 = a3; } else { a3 = stru_721530.field_6C + stru_721530.prolly_normal_d; if (!sub_475D85(&stru_721530.normal, &stru_721530.direction, &a3, pFace)) goto LABEL_34; v17 = a3 - stru_721530.prolly_normal_d; a3 -= stru_721530.prolly_normal_d; } if (v17 < stru_721530.field_7C) { stru_721530.field_7C = v17; v18 = 8 * pSector->pFloors[v26]; LOBYTE(v18) = v18 | 6; stru_721530.uFaceID = v18; } } } } LABEL_34: if (!(stru_721530.field_0 & 1) || (v21 = (pFace->pFacePlane_old.dist + stru_721530.position.x * pFace->pFacePlane_old.vNormal.x + stru_721530.position.y * pFace->pFacePlane_old.vNormal.y + stru_721530.position.z * pFace->pFacePlane_old.vNormal.z) >> 16, v21 <= 0) || (v22 = (pFace->pFacePlane_old.dist + stru_721530.field_4C * pFace->pFacePlane_old.vNormal.x + stru_721530.field_50 * pFace->pFacePlane_old.vNormal.y + stru_721530.field_54 * pFace->pFacePlane_old.vNormal.z) >> 16, v21 > stru_721530.prolly_normal_d) && v22 > stru_721530.prolly_normal_d || v22 > v21) continue; a3 = stru_721530.field_6C; if (sub_47531C(stru_721530.field_8_radius, &a3, stru_721530.position.x, stru_721530.position.y, stru_721530.position.z, stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, pFace, a10)) { v23 = a3; goto LABEL_43; } a3 = stru_721530.field_6C + stru_721530.field_8_radius; if (sub_475D85(&stru_721530.position, &stru_721530.direction, &a3, pFace)) { v23 = a3 - stru_721530.prolly_normal_d; a3 -= stru_721530.prolly_normal_d; LABEL_43: if (v23 < stru_721530.field_7C) { stru_721530.field_7C = v23; v24 = 8 * pSector->pFloors[v26]; LOBYTE(v24) = v24 | 6; stru_721530.uFaceID = v24; } } } } result = v29 + 1; } return result; } // 46E44E: using guessed type int var_28[10]; //----- (0046E889) -------------------------------------------------------- int __fastcall _46E889_collide_against_bmodels(unsigned int ecx0) { int result; // eax@1 //int v3; // ebx@9 int v8; // eax@19 int v9; // ecx@20 int v10; // eax@24 unsigned int v14; // eax@28 int v15; // eax@30 int v16; // ecx@31 unsigned int v17; // eax@36 int v21; // eax@42 unsigned int v22; // eax@43 //int a11; // [sp+70h] [bp-18h]@1 //int a10; // [sp+80h] [bp-8h]@1 int a2; // [sp+84h] [bp-4h]@23 //a11 = ecx0; BLVFace face; // [sp+Ch] [bp-7Ch]@1 result = 0; for (uint i = 0; i < (signed int)pOutdoor->uNumBModels; ++i) { if (stru_721530.sMaxX <= pOutdoor->pBModels[i].sMaxX && stru_721530.sMinX >= pOutdoor->pBModels[i].sMinX && stru_721530.sMaxY <= pOutdoor->pBModels[i].sMaxY && stru_721530.sMinY >= pOutdoor->pBModels[i].sMinY && stru_721530.sMaxZ <= pOutdoor->pBModels[i].sMaxZ && stru_721530.sMinZ >= pOutdoor->pBModels[i].sMinZ) { for (uint j = 0; j < pOutdoor->pBModels[i].uNumFaces; ++j) { if (stru_721530.sMaxX <= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.x2 && stru_721530.sMinX >= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.x1 && stru_721530.sMaxY <= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.y2 && stru_721530.sMinY >= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.y1 && stru_721530.sMaxZ <= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.z2 && stru_721530.sMinZ >= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.z1) { face.pFacePlane_old.vNormal.x = pOutdoor->pBModels[i].pFaces[j].pFacePlane.vNormal.x; face.pFacePlane_old.vNormal.y = pOutdoor->pBModels[i].pFaces[j].pFacePlane.vNormal.y; face.pFacePlane_old.vNormal.z = pOutdoor->pBModels[i].pFaces[j].pFacePlane.vNormal.z; face.pFacePlane_old.dist = pOutdoor->pBModels[i].pFaces[j].pFacePlane.dist; //incorrect face.uAttributes = pOutdoor->pBModels[i].pFaces[j].uAttributes; face.pBounding.x1 = pOutdoor->pBModels[i].pFaces[j].pBoundingBox.x1; face.pBounding.y1 = pOutdoor->pBModels[i].pFaces[j].pBoundingBox.y1; face.pBounding.z1 = pOutdoor->pBModels[i].pFaces[j].pBoundingBox.z1; face.pBounding.x2 = pOutdoor->pBModels[i].pFaces[j].pBoundingBox.x2; face.pBounding.y2 = pOutdoor->pBModels[i].pFaces[j].pBoundingBox.y2; face.pBounding.z2 = pOutdoor->pBModels[i].pFaces[j].pBoundingBox.z2; face.zCalc1 = pOutdoor->pBModels[i].pFaces[j].zCalc1; face.zCalc2 = pOutdoor->pBModels[i].pFaces[j].zCalc2; face.zCalc3 = pOutdoor->pBModels[i].pFaces[j].zCalc3; face.pXInterceptDisplacements = pOutdoor->pBModels[i].pFaces[j].pXInterceptDisplacements; face.pYInterceptDisplacements = pOutdoor->pBModels[i].pFaces[j].pYInterceptDisplacements; face.pZInterceptDisplacements = pOutdoor->pBModels[i].pFaces[j].pZInterceptDisplacements; face.uPolygonType = (PolygonType)pOutdoor->pBModels[i].pFaces[j].uPolygonType; face.uNumVertices = pOutdoor->pBModels[i].pFaces[j].uNumVertices; face.uBitmapID = pOutdoor->pBModels[i].pFaces[j].uTextureID; face.pVertexIDs = pOutdoor->pBModels[i].pFaces[j].pVertexIDs; if (!face.Ethereal() && !face.Portal()) { v8 = (face.pFacePlane_old.dist + face.pFacePlane_old.vNormal.x * stru_721530.normal.x + face.pFacePlane_old.vNormal.y * stru_721530.normal.y + face.pFacePlane_old.vNormal.z * stru_721530.normal.z) >> 16; if (v8 > 0) { v9 = (face.pFacePlane_old.dist + face.pFacePlane_old.vNormal.x * stru_721530.normal2.x + face.pFacePlane_old.vNormal.y * stru_721530.normal2.y + face.pFacePlane_old.vNormal.z * stru_721530.normal2.z) >> 16; if (v8 <= stru_721530.prolly_normal_d || v9 <= stru_721530.prolly_normal_d) { if (v9 <= v8) { a2 = stru_721530.field_6C; if (sub_4754BF(stru_721530.prolly_normal_d, &a2, stru_721530.normal.x, stru_721530.normal.y, stru_721530.normal.z, stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, &face, i, ecx0)) { v10 = a2; } else { a2 = stru_721530.prolly_normal_d + stru_721530.field_6C; if (!sub_475F30(&a2, &face, stru_721530.normal.x, stru_721530.normal.y, stru_721530.normal.z, stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, i)) goto LABEL_29; v10 = a2 - stru_721530.prolly_normal_d; a2 -= stru_721530.prolly_normal_d; } if (v10 < stru_721530.field_7C) { stru_721530.field_7C = v10; v14 = 8 * (j | (i << 6)); LOBYTE(v14) = v14 | 6; stru_721530.uFaceID = v14; } } } } LABEL_29: if (stru_721530.field_0 & 1) { v15 = (face.pFacePlane_old.dist + face.pFacePlane_old.vNormal.x * stru_721530.position.x + face.pFacePlane_old.vNormal.y * stru_721530.position.y + face.pFacePlane_old.vNormal.z * stru_721530.position.z) >> 16; if (v15 > 0) { v16 = (face.pFacePlane_old.dist + face.pFacePlane_old.vNormal.x * stru_721530.field_4C + face.pFacePlane_old.vNormal.y * stru_721530.field_50 + face.pFacePlane_old.vNormal.z * stru_721530.field_54) >> 16; if (v15 <= stru_721530.prolly_normal_d || v16 <= stru_721530.prolly_normal_d) { if (v16 <= v15) { a2 = stru_721530.field_6C; if (sub_4754BF(stru_721530.field_8_radius, &a2, stru_721530.position.x, stru_721530.position.y, stru_721530.position.z, stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, &face, i, ecx0)) { if (a2 < stru_721530.field_7C) { stru_721530.field_7C = a2; v17 = 8 * (j | (i << 6)); LOBYTE(v17) = v17 | 6; stru_721530.uFaceID = v17; } } else { a2 = stru_721530.field_6C + stru_721530.field_8_radius; if (sub_475F30(&a2, &face, stru_721530.position.x, stru_721530.position.y, stru_721530.position.z, stru_721530.direction.x, stru_721530.direction.y, stru_721530.direction.z, i)) { v21 = a2 - stru_721530.prolly_normal_d; a2 -= stru_721530.prolly_normal_d; if (a2 < stru_721530.field_7C) { stru_721530.field_7C = v21; v22 = 8 * (j | (i << 6)); LOBYTE(v22) = v22 | 6; stru_721530.uFaceID = v22; } } } } } } } } } } } result = i; } return result; } //----- (0046ED1B) -------------------------------------------------------- int collide_against_floor(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID) { uint uFaceID = -1; int floor_level = BLV_GetFloorLevel(x, y, z, *pSectorID, &uFaceID); if (floor_level != -30000 && floor_level <= z + 50) { *pFaceID = uFaceID; return floor_level; } uint uSectorID = pIndoor->GetSector(x, y, z); *pSectorID = uSectorID; floor_level = BLV_GetFloorLevel(x, y, z, uSectorID, &uFaceID); if (uSectorID && floor_level != -30000) *pFaceID = uFaceID; else return -30000; return floor_level; } //----- (0046ED8A) -------------------------------------------------------- void __fastcall _46ED8A_collide_against_sprite_objects(unsigned int _this) { ObjectDesc *object; // edx@4 int v10; // ecx@12 int v11; // esi@13 for (uint i = 0; i < uNumSpriteObjects; ++i) { if (pSpriteObjects[i].uObjectDescID) { object = &pObjectList->pObjects[pSpriteObjects[i].uObjectDescID]; if (!(object->uFlags & OBJECT_DESC_NO_COLLISION)) { if (stru_721530.sMaxX <= pSpriteObjects[i].vPosition.x + object->uRadius && stru_721530.sMinX >= pSpriteObjects[i].vPosition.x - object->uRadius && stru_721530.sMaxY <= pSpriteObjects[i].vPosition.y + object->uRadius && stru_721530.sMinY >= pSpriteObjects[i].vPosition.y - object->uRadius && stru_721530.sMaxZ <= pSpriteObjects[i].vPosition.z + object->uHeight && stru_721530.sMinZ >= pSpriteObjects[i].vPosition.z) { if (abs(((pSpriteObjects[i].vPosition.x - stru_721530.normal.x) * stru_721530.direction.y - (pSpriteObjects[i].vPosition.y - stru_721530.normal.y) * stru_721530.direction.x) >> 16) <= object->uHeight + stru_721530.prolly_normal_d) { v10 = ((pSpriteObjects[i].vPosition.x - stru_721530.normal.x) * stru_721530.direction.x + (pSpriteObjects[i].vPosition.y - stru_721530.normal.y) * stru_721530.direction.y) >> 16; if (v10 > 0) { v11 = stru_721530.normal.z + ((unsigned __int64)(stru_721530.direction.z * (signed __int64)v10) >> 16); if (v11 >= pSpriteObjects[i].vPosition.z - stru_721530.prolly_normal_d) { if (v11 <= object->uHeight + stru_721530.prolly_normal_d + pSpriteObjects[i].vPosition.z) { if (v10 < stru_721530.field_7C) sub_46DEF2(_this, i); } } } } } } } } } //----- (0046EF01) -------------------------------------------------------- int _46EF01_collision_chech_player(int a1) { int result; // eax@1 int v3; // ebx@7 int v4; // esi@7 int v5; // edi@8 int v6; // ecx@9 int v7; // edi@12 int v10; // [sp+14h] [bp-8h]@7 int v11; // [sp+18h] [bp-4h]@7 result = pParty->vPosition.x; //v9 = pParty->uPartyHeight; if (stru_721530.sMaxX <= pParty->vPosition.x + (2 * pParty->field_14_radius) && stru_721530.sMinX >= pParty->vPosition.x - (2 * pParty->field_14_radius) && stru_721530.sMaxY <= pParty->vPosition.y + (2 * pParty->field_14_radius) && stru_721530.sMinY >= pParty->vPosition.y - (2 * pParty->field_14_radius) && stru_721530.sMaxZ <= pParty->vPosition.z + pParty->uPartyHeight && stru_721530.sMinZ >= pParty->vPosition.z) { v3 = stru_721530.prolly_normal_d + (2 * pParty->field_14_radius); v11 = pParty->vPosition.x - stru_721530.normal.x; v4 = ((pParty->vPosition.x - stru_721530.normal.x) * stru_721530.direction.y - (pParty->vPosition.y - stru_721530.normal.y) * stru_721530.direction.x) >> 16; v10 = pParty->vPosition.y - stru_721530.normal.y; result = abs(((pParty->vPosition.x - stru_721530.normal.x) * stru_721530.direction.y - (pParty->vPosition.y - stru_721530.normal.y) * stru_721530.direction.x) >> 16); if (result <= stru_721530.prolly_normal_d + (2 * pParty->field_14_radius)) { result = v10 * stru_721530.direction.y; v5 = (v10 * stru_721530.direction.y + v11 * stru_721530.direction.x) >> 16; if (v5 > 0) { v6 = fixpoint_mul(stru_721530.direction.z, v5) + stru_721530.normal.z; result = pParty->vPosition.z; if (v6 >= pParty->vPosition.z) { result = pParty->uPartyHeight + pParty->vPosition.z; if (v6 <= (signed int)(pParty->uPartyHeight + pParty->vPosition.z) || a1) { result = integer_sqrt(v3 * v3 - v4 * v4); v7 = v5 - integer_sqrt(v3 * v3 - v4 * v4); if (v7 < 0) v7 = 0; if (v7 < stru_721530.field_7C) { stru_721530.field_7C = v7; stru_721530.uFaceID = 4; } } } } } } return result; } //----- (0046E0B2) -------------------------------------------------------- void _46E0B2_collide_against_decorations() { BLVSector *sector; // ebp@1 LevelDecoration *decor; // edi@2 DecorationDesc *decor_desc; // esi@3 int v8; // ebx@10 int v9; // esi@11 int v11; // eax@12 int v12; // esi@14 unsigned int v13; // eax@17 signed int i; // [sp+4h] [bp-14h]@1 int v15; // [sp+8h] [bp-10h]@10 int v16; // [sp+Ch] [bp-Ch]@10 int v17; // [sp+10h] [bp-8h]@10 sector = &pIndoor->pSectors[stru_721530.uSectorID]; for (i = 0; i < sector->uNumDecorations; ++i) { decor = &pLevelDecorations[sector->pDecorationIDs[i]]; if (!(decor->uFlags & LEVEL_DECORATION_INVISIBLE)) { decor_desc = &pDecorationList->pDecorations[decor->uDecorationDescID]; if (!decor_desc->CanMoveThrough()) { if (stru_721530.sMaxX <= decor->vPosition.x + decor_desc->uRadius && stru_721530.sMinX >= decor->vPosition.x - decor_desc->uRadius && stru_721530.sMaxY <= decor->vPosition.y + decor_desc->uRadius && stru_721530.sMinY >= decor->vPosition.y - decor_desc->uRadius && stru_721530.sMaxZ <= decor->vPosition.z + decor_desc->uDecorationHeight && stru_721530.sMinZ >= decor->vPosition.z) { v16 = decor->vPosition.x - stru_721530.normal.x; v15 = decor->vPosition.y - stru_721530.normal.y; v8 = stru_721530.prolly_normal_d + decor_desc->uRadius; v17 = ((decor->vPosition.x - stru_721530.normal.x) * stru_721530.direction.y - (decor->vPosition.y - stru_721530.normal.y) * stru_721530.direction.x) >> 16; if (abs(v17) <= stru_721530.prolly_normal_d + decor_desc->uRadius) { v9 = (v16 * stru_721530.direction.x + v15 * stru_721530.direction.y) >> 16; if (v9 > 0) { v11 = stru_721530.normal.z + fixpoint_mul(stru_721530.direction.z, v9); if (v11 >= decor->vPosition.z) { if (v11 <= decor_desc->uDecorationHeight + decor->vPosition.z) { v12 = v9 - integer_sqrt(v8 * v8 - v17 * v17); if (v12 < 0) v12 = 0; if (v12 < stru_721530.field_7C) { stru_721530.field_7C = v12; v13 = 8 * sector->pDecorationIDs[i]; LOBYTE(v13) = v13 | 5; stru_721530.uFaceID = v13; } } } } } } } } } } //----- (0046F04E) -------------------------------------------------------- int _46F04E_collide_against_portals() { unsigned int v1; // eax@1 BLVFace *face; // eax@3 int v4; // ecx@9 int v5; // edx@9 signed int result; // eax@21 unsigned int v10; // [sp+8h] [bp-Ch]@1 int a3; // [sp+Ch] [bp-8h]@13 int v12; // [sp+10h] [bp-4h]@15 v1 = 0xFFFFFFu; v10 = 0xFFFFFFu; for (uint i = 0; i < pIndoor->pSectors[stru_721530.uSectorID].uNumPortals; ++i) { if (pIndoor->pSectors[stru_721530.uSectorID].pPortals[i] != stru_721530.field_80) { face = &pIndoor->pFaces[pIndoor->pSectors[stru_721530.uSectorID].pPortals[i]]; if (stru_721530.sMaxX <= face->pBounding.x2 && stru_721530.sMinX >= face->pBounding.x1 && stru_721530.sMaxY <= face->pBounding.y2 && stru_721530.sMinY >= face->pBounding.y1 && stru_721530.sMaxZ <= face->pBounding.z2 && stru_721530.sMinZ >= face->pBounding.z1) { v4 = (stru_721530.normal.x * face->pFacePlane_old.vNormal.x + face->pFacePlane_old.dist + stru_721530.normal.y * face->pFacePlane_old.vNormal.y + stru_721530.normal.z * face->pFacePlane_old.vNormal.z) >> 16; v5 = (stru_721530.normal2.z * face->pFacePlane_old.vNormal.z + face->pFacePlane_old.dist + stru_721530.normal2.x * face->pFacePlane_old.vNormal.x + stru_721530.normal2.y * face->pFacePlane_old.vNormal.y) >> 16; if ((v4 < stru_721530.prolly_normal_d || v5 < stru_721530.prolly_normal_d) && (v4 > -stru_721530.prolly_normal_d || v5 > -stru_721530.prolly_normal_d) && (a3 = stru_721530.field_6C, sub_475D85(&stru_721530.normal, &stru_721530.direction, &a3, face)) && a3 < (signed int)v10) { v10 = a3; v12 = pIndoor->pSectors[stru_721530.uSectorID].pPortals[i]; } } } } v1 = v10; if (stru_721530.field_7C >= (signed int)v1 && (signed int)v1 <= stru_721530.field_6C) { stru_721530.field_80 = v12; if (pIndoor->pFaces[v12].uSectorID == stru_721530.uSectorID) stru_721530.uSectorID = pIndoor->pFaces[v12].uBackSectorID; else stru_721530.uSectorID = pIndoor->pFaces[v12].uSectorID; stru_721530.field_7C = 268435455; result = 0; } else result = 1; return result; } //----- (0046DEF2) -------------------------------------------------------- unsigned int __fastcall sub_46DEF2(signed int a2, unsigned int uLayingItemID) { unsigned int result; // eax@1 result = uLayingItemID; if (pObjectList->pObjects[pSpriteObjects[uLayingItemID].uObjectDescID].uFlags & 0x10) result = _46BFFA_check_object_intercept(uLayingItemID, a2); return result; } //----- (0047253E) -------------------------------------------------------- void UpdateObjects() { ObjectDesc *object; // eax@5 int v5; // ecx@6 signed int v7; // eax@9 signed int v11; // eax@17 int v12; // edi@27 int v18; // [sp+4h] [bp-10h]@27 int v19; // [sp+8h] [bp-Ch]@27 for (uint i = 0; i < uNumSpriteObjects; ++i) { if (pSpriteObjects[i].uAttributes & OBJECT_40) pSpriteObjects[i].uAttributes &= ~OBJECT_40; else { object = &pObjectList->pObjects[pSpriteObjects[i].uObjectDescID]; if (pSpriteObjects[i].AttachedToActor()) { v5 = PID_ID(pSpriteObjects[i].spell_target_pid); pSpriteObjects[i].vPosition.x = pActors[v5].vPosition.x; pSpriteObjects[i].vPosition.y = pActors[v5].vPosition.y; pSpriteObjects[i].vPosition.z = pActors[v5].vPosition.z + pActors[v5].uActorHeight; if (!pSpriteObjects[i].uObjectDescID) continue; pSpriteObjects[i].uSpriteFrameID += pEventTimer->uTimeElapsed; if (!(object->uFlags & OBJECT_DESC_TEMPORARY)) continue; if (pSpriteObjects[i].uSpriteFrameID >= 0) { v7 = object->uLifetime; if (pSpriteObjects[i].uAttributes & ITEM_BROKEN) v7 = pSpriteObjects[i].field_20; if (pSpriteObjects[i].uSpriteFrameID < v7) continue; } SpriteObject::OnInteraction(i); continue; } if (pSpriteObjects[i].uObjectDescID) { pSpriteObjects[i].uSpriteFrameID += pEventTimer->uTimeElapsed; if (object->uFlags & OBJECT_DESC_TEMPORARY) { if (pSpriteObjects[i].uSpriteFrameID < 0) { SpriteObject::OnInteraction(i); continue; } v11 = object->uLifetime; if (pSpriteObjects[i].uAttributes & ITEM_BROKEN) v11 = pSpriteObjects[i].field_20; } if (!(object->uFlags & OBJECT_DESC_TEMPORARY) || pSpriteObjects[i].uSpriteFrameID < v11) { if (uCurrentlyLoadedLevelType == LEVEL_Indoor) SpriteObject::UpdateObject_fn0_BLV(i); else SpriteObject::UpdateObject_fn0_ODM(i); if (pParty->bTurnBasedModeOn != 1 || !(pSpriteObjects[i].uSectorID & 4)) continue; v12 = abs(pParty->vPosition.x - pSpriteObjects[i].vPosition.x); v18 = abs(pParty->vPosition.y - pSpriteObjects[i].vPosition.y); v19 = abs(pParty->vPosition.z - pSpriteObjects[i].vPosition.z); if (int_get_vector_length(v12, v18, v19) <= 5120) continue; SpriteObject::OnInteraction(i); continue; } if (!(object->uFlags & OBJECT_DESC_INTERACTABLE)) { SpriteObject::OnInteraction(i); continue; } _46BFFA_check_object_intercept(i, PID(OBJECT_Item, i)); } } } } //----- (0047531C) -------------------------------------------------------- bool sub_47531C(int a1, int *a2, int pos_x, int pos_y, int pos_z, int dir_x, int dir_y, int dir_z, BLVFace *face, int a10) { int v11; // ST1C_4@3 int v12; // edi@3 int v13; // esi@3 int v14; // edi@4 signed __int64 v15; // qtt@6 //__int16 v16; // si@7 int a7a; // [sp+30h] [bp+18h]@7 int a9b; // [sp+38h] [bp+20h]@3 int a9a; // [sp+38h] [bp+20h]@3 int a10b; // [sp+3Ch] [bp+24h]@3 signed int a10a; // [sp+3Ch] [bp+24h]@4 int a10c; // [sp+3Ch] [bp+24h]@5 if (a10 && face->Ethereal()) return 0; v11 = fixpoint_mul(dir_x, face->pFacePlane_old.vNormal.x); a10b = fixpoint_mul(dir_y, face->pFacePlane_old.vNormal.y); a9b = fixpoint_mul(dir_z, face->pFacePlane_old.vNormal.z); v12 = v11 + a9b + a10b; a9a = v11 + a9b + a10b; v13 = (a1 << 16) - pos_x * face->pFacePlane_old.vNormal.x - pos_y * face->pFacePlane_old.vNormal.y - pos_z * face->pFacePlane_old.vNormal.z - face->pFacePlane_old.dist; if (abs((a1 << 16) - pos_x * face->pFacePlane_old.vNormal.x - pos_y * face->pFacePlane_old.vNormal.y - pos_z * face->pFacePlane_old.vNormal.z - face->pFacePlane_old.dist) >= a1 << 16) { a10c = abs(v13) >> 14; if (a10c > abs(v12)) return 0; LODWORD(v15) = v13 << 16; HIDWORD(v15) = v13 >> 16; v14 = a1; a10a = v15 / a9a; } else { a10a = 0; v14 = abs(v13) >> 16; } //v16 = pos_y + ((unsigned int)fixpoint_mul(a10a, dir_y) >> 16); LOWORD(a7a) = (short)pos_x + ((unsigned int)fixpoint_mul(a10a, dir_x) >> 16) - fixpoint_mul(v14, face->pFacePlane_old.vNormal.x); HIWORD(a7a) = pos_y + ((unsigned int)fixpoint_mul(a10a, dir_y) >> 16) - fixpoint_mul(v14, face->pFacePlane_old.vNormal.y); if (!sub_475665(face, a7a, (short)pos_z + ((unsigned int)fixpoint_mul(a10a, dir_z) >> 16) - fixpoint_mul(v14, face->pFacePlane_old.vNormal.z))) return 0; *a2 = a10a >> 16; if (a10a >> 16 < 0) *a2 = 0; return 1; } //----- (004754BF) -------------------------------------------------------- bool sub_4754BF(int a1, int *a2, int X, int Y, int Z, int dir_x, int dir_y, int dir_z, BLVFace *face, int a10, int a11) { int v12; // ST1C_4@3 int v13; // edi@3 int v14; // esi@3 int v15; // edi@4 signed __int64 v16; // qtt@6 //__int16 v17; // si@7 int a7a; // [sp+30h] [bp+18h]@7 int a1b; // [sp+38h] [bp+20h]@3 int a1a; // [sp+38h] [bp+20h]@3 int a11b; // [sp+40h] [bp+28h]@3 signed int a11a; // [sp+40h] [bp+28h]@4 int a11c; // [sp+40h] [bp+28h]@5 if (a11 && face->Ethereal()) return false; v12 = fixpoint_mul(dir_x, face->pFacePlane_old.vNormal.x); a11b = fixpoint_mul(dir_y, face->pFacePlane_old.vNormal.y); a1b = fixpoint_mul(dir_z, face->pFacePlane_old.vNormal.z); v13 = v12 + a1b + a11b; a1a = v12 + a1b + a11b; v14 = (a1 << 16) - X * face->pFacePlane_old.vNormal.x - Y * face->pFacePlane_old.vNormal.y - Z * face->pFacePlane_old.vNormal.z - face->pFacePlane_old.dist; if (abs((a1 << 16) - X * face->pFacePlane_old.vNormal.x - Y * face->pFacePlane_old.vNormal.y - Z * face->pFacePlane_old.vNormal.z - face->pFacePlane_old.dist) >= a1 << 16) { a11c = abs(v14) >> 14; if (a11c > abs(v13)) return false; LODWORD(v16) = v14 << 16; HIDWORD(v16) = v14 >> 16; v15 = a1; a11a = v16 / a1a; } else { a11a = 0; v15 = abs(v14) >> 16; } //v17 = Y + ((unsigned int)fixpoint_mul(a11a, dir_y) >> 16); LOWORD(a7a) = (short)X + ((unsigned int)fixpoint_mul(a11a, dir_x) >> 16) - fixpoint_mul(v15, face->pFacePlane_old.vNormal.x); HIWORD(a7a) = Y + ((unsigned int)fixpoint_mul(a11a, dir_y) >> 16) - fixpoint_mul(v15, face->pFacePlane_old.vNormal.y); if (!sub_4759C9(face, a10, a7a, (short)Z + ((unsigned int)fixpoint_mul(a11a, dir_z) >> 16) - fixpoint_mul(v15, face->pFacePlane_old.vNormal.z))) return false; *a2 = a11a >> 16; if (a11a >> 16 < 0) *a2 = 0; return true; } //----- (00475665) -------------------------------------------------------- int sub_475665(BLVFace *face, int a2, __int16 a3) { bool v16; // edi@14 signed int v20; // ebx@18 int v21; // edi@20 signed int v22; // ST14_4@22 signed __int64 v23; // qtt@22 signed int result; // eax@25 int v25; // [sp+14h] [bp-10h]@14 int v26; // [sp+1Ch] [bp-8h]@2 signed int v27; // [sp+20h] [bp-4h]@2 signed int v28; // [sp+30h] [bp+Ch]@2 signed int v29; // [sp+30h] [bp+Ch]@7 signed int v30; // [sp+30h] [bp+Ch]@11 signed int v31; // [sp+30h] [bp+Ch]@14 if (face->uAttributes & FACE_XY_PLANE) { v26 = (signed __int16)a2; v27 = SHIWORD(a2); if (face->uNumVertices) { for (v28 = 0; v28 < face->uNumVertices; v28++) { word_720C10_intercepts_xs[2 * v28] = face->pXInterceptDisplacements[v28] + pIndoor->pVertices[face->pVertexIDs[v28]].x; word_720B40_intercepts_zs[2 * v28] = face->pYInterceptDisplacements[v28] + pIndoor->pVertices[face->pVertexIDs[v28]].y; word_720C10_intercepts_xs[2 * v28 + 1] = face->pXInterceptDisplacements[v28 + 1] + pIndoor->pVertices[face->pVertexIDs[v28 + 1]].x; word_720B40_intercepts_zs[2 * v28 + 1] = face->pYInterceptDisplacements[v28 + 1] + pIndoor->pVertices[face->pVertexIDs[v28 + 1]].y; } } } else { if (face->uAttributes & FACE_XZ_PLANE) { v26 = (signed __int16)a2; v27 = a3; if (face->uNumVertices) { for (v29 = 0; v29 < face->uNumVertices; v29++) { word_720C10_intercepts_xs[2 * v29] = face->pXInterceptDisplacements[v29] + pIndoor->pVertices[face->pVertexIDs[v29]].x; word_720B40_intercepts_zs[2 * v29] = face->pZInterceptDisplacements[v29] + pIndoor->pVertices[face->pVertexIDs[v29]].z; word_720C10_intercepts_xs[2 * v29 + 1] = face->pXInterceptDisplacements[v29 + 1] + pIndoor->pVertices[face->pVertexIDs[v29 + 1]].x; word_720B40_intercepts_zs[2 * v29 + 1] = face->pZInterceptDisplacements[v29 + 1] + pIndoor->pVertices[face->pVertexIDs[v29 + 1]].z; } } } else { v26 = SHIWORD(a2); v27 = a3; if (face->uNumVertices) { for (v30 = 0; v30 < face->uNumVertices; v30++) { word_720C10_intercepts_xs[2 * v30] = face->pYInterceptDisplacements[v30] + pIndoor->pVertices[face->pVertexIDs[v30]].y; word_720B40_intercepts_zs[2 * v30] = face->pZInterceptDisplacements[v30] + pIndoor->pVertices[face->pVertexIDs[v30]].z; word_720C10_intercepts_xs[2 * v30 + 1] = face->pYInterceptDisplacements[v30 + 1] + pIndoor->pVertices[face->pVertexIDs[v30 + 1]].y; word_720B40_intercepts_zs[2 * v30 + 1] = face->pZInterceptDisplacements[v30 + 1] + pIndoor->pVertices[face->pVertexIDs[v30 + 1]].z; } } } } v31 = 0; word_720C10_intercepts_xs[2 * face->uNumVertices] = word_720C10_intercepts_xs[0]; word_720B40_intercepts_zs[2 * face->uNumVertices] = word_720B40_intercepts_zs[0]; v16 = word_720B40_intercepts_zs[0] >= v27; if (2 * face->uNumVertices <= 0) return 0; for (v25 = 0; v25 < 2 * face->uNumVertices; ++v25) { if (v31 >= 2) break; if (v16 ^ (word_720B40_intercepts_zs[v25 + 1] >= v27)) { if (word_720C10_intercepts_xs[v25 + 1] >= v26) v20 = 0; else v20 = 2; v21 = v20 | (word_720C10_intercepts_xs[v25] < v26); if (v21 != 3) { v22 = word_720C10_intercepts_xs[v25 + 1] - word_720C10_intercepts_xs[v25]; LODWORD(v23) = v22 << 16; HIDWORD(v23) = v22 >> 16; if (!v21 || (word_720C10_intercepts_xs[v25] + ((signed int)(((unsigned __int64)(v23 / (word_720B40_intercepts_zs[v25 + 1] - word_720B40_intercepts_zs[v25]) * ((v27 - (signed int)word_720B40_intercepts_zs[v25]) << 16)) >> 16) + 32768) >> 16) >= v26)) ++v31; } } v16 = word_720B40_intercepts_zs[v25 + 1] >= v27; } result = 1; if (v31 != 1) result = 0; return result; } //----- (004759C9) -------------------------------------------------------- bool __fastcall sub_4759C9(BLVFace *face, int a2, int a3, __int16 a4) { bool v12; // edi@14 signed int v16; // ebx@18 int v17; // edi@20 signed int v18; // ST14_4@22 signed __int64 v19; // qtt@22 bool result; // eax@25 int v21; // [sp+14h] [bp-10h]@14 signed int v22; // [sp+18h] [bp-Ch]@1 int v23; // [sp+1Ch] [bp-8h]@2 signed int v24; // [sp+20h] [bp-4h]@2 signed int a4d; // [sp+30h] [bp+Ch]@14 if (face->uAttributes & FACE_XY_PLANE) { v23 = (signed __int16)a3; v24 = SHIWORD(a3); if (face->uNumVertices) { for (v22 = 0; v22 < face->uNumVertices; ++v22) { word_720A70_intercepts_xs_plus_xs[2 * v22] = face->pXInterceptDisplacements[v22] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22]].x); word_7209A0_intercepts_ys_plus_ys[2 * v22] = face->pYInterceptDisplacements[v22] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22]].y); word_720A70_intercepts_xs_plus_xs[2 * v22 + 1] = face->pXInterceptDisplacements[v22 + 1] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22 + 1]].x); word_7209A0_intercepts_ys_plus_ys[2 * v22 + 1] = face->pYInterceptDisplacements[v22 + 1] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22 + 1]].y); } } } else { if (face->uAttributes & FACE_XZ_PLANE) { v23 = (signed __int16)a3; v24 = a4; if (face->uNumVertices) { for (v22 = 0; v22 < face->uNumVertices; ++v22) { word_720A70_intercepts_xs_plus_xs[2 * v22] = face->pXInterceptDisplacements[v22] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22]].x); word_7209A0_intercepts_ys_plus_ys[2 * v22] = face->pZInterceptDisplacements[v22] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22]].z); word_720A70_intercepts_xs_plus_xs[2 * v22 + 1] = face->pXInterceptDisplacements[v22 + 1] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22 + 1]].x); word_7209A0_intercepts_ys_plus_ys[2 * v22 + 1] = face->pZInterceptDisplacements[v22 + 1] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22 + 1]].z); } } } else { v23 = SHIWORD(a3); v24 = a4; if (face->uNumVertices) { for (v22 = 0; v22 < face->uNumVertices; ++v22) { word_720A70_intercepts_xs_plus_xs[2 * v22] = face->pYInterceptDisplacements[v22] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22]].y); word_7209A0_intercepts_ys_plus_ys[2 * v22] = face->pZInterceptDisplacements[v22] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22]].z); word_720A70_intercepts_xs_plus_xs[2 * v22 + 1] = face->pYInterceptDisplacements[v22 + 1] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22 + 1]].y); word_7209A0_intercepts_ys_plus_ys[2 * v22 + 1] = face->pZInterceptDisplacements[v22 + 1] + LOWORD(pOutdoor->pBModels[a2].pVertices.pVertices[face->pVertexIDs[v22 + 1]].z); } } } } a4d = 0; word_720A70_intercepts_xs_plus_xs[2 * face->uNumVertices] = word_720A70_intercepts_xs_plus_xs[0]; word_7209A0_intercepts_ys_plus_ys[2 * face->uNumVertices] = word_7209A0_intercepts_ys_plus_ys[0]; v12 = word_7209A0_intercepts_ys_plus_ys[0] >= v24; if (2 * face->uNumVertices <= 0) return 0; for (v21 = 0; v21 < 2 * face->uNumVertices; ++v21) { if (a4d >= 2) break; if (v12 ^ (word_7209A0_intercepts_ys_plus_ys[v21 + 1] >= v24)) { if (word_720A70_intercepts_xs_plus_xs[v21 + 1] >= v23) v16 = 0; else v16 = 2; v17 = v16 | (word_720A70_intercepts_xs_plus_xs[v21] < v23); if (v17 != 3) { v18 = word_720A70_intercepts_xs_plus_xs[v21 + 1] - word_720A70_intercepts_xs_plus_xs[v21]; LODWORD(v19) = v18 << 16; HIDWORD(v19) = v18 >> 16; if (!v17 || (word_720A70_intercepts_xs_plus_xs[v21] + ((signed int)(((unsigned __int64)(v19 / (word_7209A0_intercepts_ys_plus_ys[v21 + 1] - word_7209A0_intercepts_ys_plus_ys[v21]) * ((v24 - (signed int)word_7209A0_intercepts_ys_plus_ys[v21]) << 16)) >> 16) + 0x8000) >> 16) >= v23)) ++a4d; } } v12 = word_7209A0_intercepts_ys_plus_ys[v21 + 1] >= v24; } result = 1; if (a4d != 1) result = 0; return result; } //----- (00475D85) -------------------------------------------------------- bool __fastcall sub_475D85(Vec3_int_ *a1, Vec3_int_ *a2, int *a3, BLVFace *a4) { BLVFace *v4; // ebx@1 int v5; // ST24_4@2 int v6; // ST28_4@2 int v7; // edi@2 int v8; // eax@5 signed int v9; // esi@5 signed __int64 v10; // qtt@10 Vec3_int_ *v11; // esi@11 int v12; // ST14_4@11 Vec3_int_ *v14; // [sp+Ch] [bp-18h]@1 Vec3_int_ *v15; // [sp+14h] [bp-10h]@1 // int v16; // [sp+18h] [bp-Ch]@2 int v17; // [sp+20h] [bp-4h]@10 int a4b; // [sp+30h] [bp+Ch]@2 int a4c; // [sp+30h] [bp+Ch]@9 signed int a4a; // [sp+30h] [bp+Ch]@10 v4 = a4; v15 = a2; v14 = a1; v5 = fixpoint_mul(a2->x, a4->pFacePlane_old.vNormal.x); a4b = fixpoint_mul(a2->y, a4->pFacePlane_old.vNormal.y); v6 = fixpoint_mul(a2->z, v4->pFacePlane_old.vNormal.z); v7 = v5 + v6 + a4b; //(v16 = v5 + v6 + a4b) == 0; if (a4->uAttributes & FACE_ETHEREAL || !v7 || v7 > 0 && !v4->Portal()) return 0; v8 = v4->pFacePlane_old.vNormal.z * a1->z; v9 = -(v4->pFacePlane_old.dist + v8 + a1->y * v4->pFacePlane_old.vNormal.y + a1->x * v4->pFacePlane_old.vNormal.x); if (v7 <= 0) { if (v4->pFacePlane_old.dist + v8 + a1->y * v4->pFacePlane_old.vNormal.y + a1->x * v4->pFacePlane_old.vNormal.x < 0) return 0; } else { if (v9 < 0) return 0; } a4c = abs(-(v4->pFacePlane_old.dist + v8 + a1->y * v4->pFacePlane_old.vNormal.y + a1->x * v4->pFacePlane_old.vNormal.x)) >> 14; v11 = v14; LODWORD(v10) = v9 << 16; HIDWORD(v10) = v9 >> 16; a4a = v10 / v7; v17 = v10 / v7; LOWORD(v12) = LOWORD(v14->x) + (((unsigned int)fixpoint_mul(v17, v15->x) + 0x8000) >> 16); HIWORD(v12) = LOWORD(v11->y) + (((unsigned int)fixpoint_mul(v17, v15->y) + 0x8000) >> 16); if (a4c > abs(v7) || (v17 > *a3 << 16) || !sub_475665(v4, v12, LOWORD(v11->z) + (((unsigned int)fixpoint_mul(v17, v15->z) + 0x8000) >> 16))) return 0; *a3 = a4a >> 16; return 1; } //----- (00475F30) -------------------------------------------------------- bool __fastcall sub_475F30(int *a1, BLVFace *a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9) { int v10; // ST20_4@2 int v11; // ST28_4@2 int v12; // ST24_4@2 int v13; // zf@2 int v14; // edi@2 signed int v16; // esi@5 int v17; // ST20_4@9 signed __int64 v18; // qtt@10 int v19; // ST14_4@11 int v22; // [sp+1Ch] [bp-8h]@2 int v23; // [sp+1Ch] [bp-8h]@10 signed int v24; // [sp+20h] [bp-4h]@10 v10 = fixpoint_mul(a6, a2->pFacePlane_old.vNormal.x); v11 = fixpoint_mul(a7, a2->pFacePlane_old.vNormal.y); v12 = fixpoint_mul(a8, a2->pFacePlane_old.vNormal.z); v13 = v10 + v12 + v11; v14 = v10 + v12 + v11; v22 = v10 + v12 + v11; if (a2->Ethereal() || !v13 || v14 > 0 && !a2->Portal()) return 0; v16 = -(a2->pFacePlane_old.dist + a4 * a2->pFacePlane_old.vNormal.y + a3 * a2->pFacePlane_old.vNormal.x + a5 * a2->pFacePlane_old.vNormal.z); if (v14 <= 0) { if (a2->pFacePlane_old.dist + a4 * a2->pFacePlane_old.vNormal.y + a3 * a2->pFacePlane_old.vNormal.x + a5 * a2->pFacePlane_old.vNormal.z < 0) return 0; } else { if (v16 < 0) return 0; } v17 = abs(-(a2->pFacePlane_old.dist + a4 * a2->pFacePlane_old.vNormal.y + a3 * a2->pFacePlane_old.vNormal.x + a5 * a2->pFacePlane_old.vNormal.z)) >> 14; LODWORD(v18) = v16 << 16; HIDWORD(v18) = v16 >> 16; v24 = v18 / v22; v23 = v18 / v22; LOWORD(v19) = a3 + (((unsigned int)fixpoint_mul(v23, a6) + 0x8000) >> 16); HIWORD(v19) = a4 + (((unsigned int)fixpoint_mul(v23, a7) + 0x8000) >> 16); if (v17 > abs(v14) || v23 > *a1 << 16 || !sub_4759C9(a2, a9, v19, a5 + (((unsigned int)fixpoint_mul(v23, a8) + 0x8000) >> 16))) return 0; *a1 = v24 >> 16; return 1; } //----- (00479089) -------------------------------------------------------- bool __fastcall IsBModelVisible(unsigned int uModelID, int *reachable) { int v3; // edi@1 int v4; // ebx@1 int v9; // eax@3 signed int v11; // esi@6 int v12; // esi@8 bool result; // eax@9 int v17; // [sp+1Ch] [bp-10h]@1 int v19; // [sp+20h] [bp-Ch]@3 int angle; // [sp+24h] [bp-8h]@1 angle = (signed int)(pODMRenderParams->uCameraFovInDegrees << 11) / 360 / 2; v3 = pOutdoor->pBModels[uModelID].vBoundingCenter.x - pGame->pIndoorCameraD3D->vPartyPos.x; v4 = pOutdoor->pBModels[uModelID].vBoundingCenter.y - pGame->pIndoorCameraD3D->vPartyPos.y; stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationX); v17 = v3 * stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationY) + v4 * stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationY); if (pGame->pIndoorCameraD3D->sRotationX) v17 = fixpoint_mul(v17, stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationX)); v19 = v4 * stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationY) - v3 * stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationY); v9 = int_get_vector_length(abs(v3), abs(v4), 0); //v10 = v14 * 188; //v22 = v9; *reachable = false; if (v9 < pOutdoor->pBModels[uModelID].sBoundingRadius + 256) *reachable = true; if (v19 >= 0) v11 = fixpoint_mul(stru_5C6E00->Sin(angle), v17) - fixpoint_mul(stru_5C6E00->Cos(angle), v19); else v11 = fixpoint_mul(stru_5C6E00->Cos(angle), v19) + fixpoint_mul(stru_5C6E00->Sin(angle), v17); v12 = v11 >> 16; if (v9 <= pODMRenderParams->shading_dist_mist + 2048) { //if ( abs(v12) > *(int *)((char *)&pOutdoor->pBModels->sBoundingRadius + v10) + 512 ) if (abs(v12) > pOutdoor->pBModels[uModelID].sBoundingRadius + 512) { result = v12 < 0; LOBYTE(result) = v12 >= 0; return result; } else return true; } return false; } //----- (00479295) -------------------------------------------------------- int Polygon::_479295() { int v3; // ecx@4 int v4; // eax@4 int v5; // edx@4 // int v6; // ST14_4@5 Vec3_int_ thisa; // [sp+Ch] [bp-10h]@8 int v11; // [sp+18h] [bp-4h]@4 if (!this->pODMFace->pFacePlane.vNormal.z) { v3 = this->pODMFace->pFacePlane.vNormal.x; v4 = -this->pODMFace->pFacePlane.vNormal.y; v5 = 0; v11 = 65536; } else if ((this->pODMFace->pFacePlane.vNormal.x || this->pODMFace->pFacePlane.vNormal.y) && abs(this->pODMFace->pFacePlane.vNormal.z) < 59082) { thisa.x = -this->pODMFace->pFacePlane.vNormal.y; thisa.y = this->pODMFace->pFacePlane.vNormal.x; thisa.z = 0; thisa.Normalize_float(); v4 = thisa.x; v3 = thisa.y; v5 = 0; v11 = 65536; } else { v3 = 0; v4 = 65536; v11 = 0; v5 = -65536; } sTextureDeltaU = this->pODMFace->sTextureDeltaU; sTextureDeltaV = this->pODMFace->sTextureDeltaV; ptr_38->_48616B_frustum_odm(v4, v3, 0, 0, v5, v11); return 1; } unsigned short *LoadTgaTexture(const wchar_t *filename, int *out_width = nullptr, int *out_height = nullptr) { #pragma pack(push, 1) struct TGAHeader { unsigned char tgaSkip; unsigned char colourmaptype; // type of colour map 0=none, 1=has palette unsigned char tgaType; // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed short colourmapstart; // first colour map entry in palette short colourmaplength; // number of colours in palette char colourmapbits; // number of bits per palette entry 15,16,24,32 //unsigned char tgaDontCare2[9]; short xstart; // image x origin short ystart; // image y origin unsigned short tgaWidth; unsigned short tgaHeight; unsigned char tgaBPP; char descriptor; // image descriptor bits: 00vhaaaa // h horizontal flip // v vertical flip // a alpha bits }; #pragma pack(pop) if (out_width) *out_width = 0; if (out_height) *out_height = 0; DWORD w; void* file = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); if (file == INVALID_HANDLE_VALUE) return nullptr; TGAHeader header; ReadFile(file, &header, sizeof(header), &w, nullptr); SetFilePointer(file, header.tgaSkip, nullptr, FILE_CURRENT); if (header.tgaBPP != 24 || header.tgaType != 2) { CloseHandle(file); return nullptr; } int imgSize = header.tgaWidth * header.tgaHeight * 3; unsigned char* pixels = new unsigned char[imgSize]; ReadFile(file, pixels, imgSize, &w, nullptr); CloseHandle(file); if (w != imgSize) { delete[] pixels; return nullptr; } if (out_width) *out_width = header.tgaWidth; if (out_height) *out_height = header.tgaHeight; unsigned short* pixels_16bit = new unsigned short[imgSize / 3]; for (int i = 0; i < imgSize / 3; ++i) { pixels_16bit[i] = (pixels[i * 3] / 8 & 0x1F) | ((pixels[i * 3 + 1] / 4 & 0x3F) << 5) | ((pixels[i * 3 + 2] / 8 & 0x1F) << 11); } delete[] pixels; return pixels_16bit; } unsigned short *skybox_xn, *skybox_xp, *skybox_yn, *skybox_yp, *skybox_zn, *skybox_zp; int skybox_width, skybox_height; IDirect3DTexture2 *skybox_texture; IDirectDrawSurface4 *skybox_surface; bool Skybox_Initialize(const wchar_t *skybox_name) { wchar_t xn_filename[1024], xp_filename[1024], yn_filename[1024], yp_filename[1024], zn_filename[1024], zp_filename[1024]; swprintf(xn_filename, wcslen(L"%s_xn.tga"), L"%s_xn.tga", skybox_name); swprintf(xp_filename, wcslen(L"%s_xp.tga"), L"%s_xp.tga", skybox_name); swprintf(yn_filename, wcslen(L"%s_yn.tga"), L"%s_yn.tga", skybox_name); swprintf(yp_filename, wcslen(L"%s_yp.tga"), L"%s_yp.tga", skybox_name); swprintf(zn_filename, wcslen(L"%s_zn.tga"), L"%s_zn.tga", skybox_name); swprintf(zp_filename, wcslen(L"%s_zp.tga"), L"%s_zp.tga", skybox_name); int xn_width, xn_height; skybox_xn = LoadTgaTexture(xn_filename, &xn_width, &xn_height); if (!skybox_xn) return false; int xp_width, xp_height; skybox_xp = LoadTgaTexture(xp_filename, &xp_width, &xp_height); if (!skybox_xp || xp_width != xn_width || xp_height != xn_height) { delete[] skybox_xn; delete[] skybox_xp; return false; } int yn_width, yn_height; skybox_yn = LoadTgaTexture(yn_filename, &yn_width, &yn_height); if (!skybox_yn || yn_width != xn_width || yn_height != xn_height) { delete[] skybox_xn; delete[] skybox_xp; delete[] skybox_yn; return false; } int yp_width, yp_height; skybox_yp = LoadTgaTexture(yp_filename, &yp_width, &yp_height); if (!skybox_yp || yp_width != xn_width || yp_height != xn_height) { delete[] skybox_xn; delete[] skybox_xp; delete[] skybox_yn; delete[] skybox_yp; return false; } int zn_width, zn_height; skybox_zn = LoadTgaTexture(zn_filename, &zn_width, &zn_height); if (!skybox_zn || zn_width != xn_width || zn_height != xn_height) { delete[] skybox_xn; delete[] skybox_xp; delete[] skybox_yn; delete[] skybox_yp; delete[] skybox_zn; return false; } int zp_width, zp_height; skybox_zp = LoadTgaTexture(zp_filename, &zp_width, &zp_height); if (!skybox_zp || zp_width != xn_width || zp_height != xn_height) { delete[] skybox_xn; delete[] skybox_xp; delete[] skybox_yn; delete[] skybox_yp; delete[] skybox_zn; delete[] skybox_zp; return false; } skybox_width = xn_width; skybox_height = xn_height; __debugbreak(); //if (!pRenderer->pRenderD3D->CreateTexture(skybox_width, skybox_height, &skybox_surface, &skybox_texture, //false, false, pRenderer->uMinDeviceTextureDim)) return false; return true; } struct vector { float x, y, z; }; struct matrix { float m[4][4]; }; void VectorNormalize(vector *v) { float invmag = 1.0f / sqrtf(v->x * v->x + v->y * v->y + v->z * v->z); v->x *= invmag; v->y *= invmag; v->z *= invmag; } void MatrixRotationAxis(matrix *pout, CONST vector *pv, float angle) { memset(pout, 0, sizeof(matrix)); pout->m[3][0] = 0; pout->m[3][1] = 0; pout->m[3][2] = 0; pout->m[3][3] = 1; vector v; v.x = pv->x; v.y = pv->y; v.z = pv->z; VectorNormalize(&v); pout->m[0][0] = (1.0f - cos(angle)) * v.x * v.x + cos(angle); pout->m[1][0] = (1.0f - cos(angle)) * v.x * v.y - sin(angle) * v.z; pout->m[2][0] = (1.0f - cos(angle)) * v.x * v.z + sin(angle) * v.y; pout->m[0][1] = (1.0f - cos(angle)) * v.y * v.x + sin(angle) * v.z; pout->m[1][1] = (1.0f - cos(angle)) * v.y * v.y + cos(angle); pout->m[2][1] = (1.0f - cos(angle)) * v.y * v.z - sin(angle) * v.x; pout->m[0][2] = (1.0f - cos(angle)) * v.z * v.x - sin(angle) * v.y; pout->m[1][2] = (1.0f - cos(angle)) * v.z * v.y + sin(angle) * v.x; pout->m[2][2] = (1.0f - cos(angle)) * v.z * v.z + cos(angle); } void VectorTransform(const matrix *m, const vector *v, vector *out) { out->x = m->m[0][0] * v->x + m->m[1][0] * v->y + m->m[2][0] * v->z + m->m[3][0]; out->y = m->m[0][1] * v->x + m->m[1][1] * v->y + m->m[2][1] * v->z + m->m[3][1]; out->z = m->m[0][2] * v->x + m->m[1][2] * v->y + m->m[2][2] * v->z + m->m[3][2]; } bool DrawSkyD3D_Skybox() { static bool initialized = false, initialization_failed = false; if (initialization_failed) return false; static int last_camera_rot_y, last_camera_rot_x; if (!initialized) { if (!Skybox_Initialize(L"data/skybox/stars")) { initialization_failed = true; return false; } initialized = true; last_camera_rot_y = pParty->sRotationY + 1; // force update for the first run last_camera_rot_x = pParty->sRotationX + 1; } /* r(y) = cos y 0 sin y 0 0 1 0 0 -sin y 0 cos y 0 0 0 0 1 x cos y - z sin y y x sin y + z cos y 1 r(x) = // should be r(right) actually 1 0 0 0 0 cos x -sin x 0 0 sin x cos x 0 0 0 0 1 x y cos x + z sin x -y sin x + z cos x 1 */ if (last_camera_rot_y == pParty->sRotationY && last_camera_rot_x == pParty->sRotationX) { draw: struct RenderVertexD3D3 v[6]; v[0].pos.x = pViewport->uScreen_TL_X; v[0].pos.y = pViewport->uScreen_TL_Y; v[0].pos.z = 0.99989998; v[0].rhw = 1; v[0].diffuse = -1; v[0].specular = 0; v[0].texcoord.x = 0; v[0].texcoord.y = 0; v[1].pos.x = pViewport->uScreen_TL_X + pViewport->uScreenWidth; v[1].pos.y = pViewport->uScreen_TL_Y + pViewport->uScreenHeight; v[1].pos.z = 0.99989998; v[1].rhw = 1; v[1].diffuse = -1; v[1].specular = 0; v[1].texcoord.x = (float)pViewport->uScreenWidth / skybox_width; v[1].texcoord.y = (float)pViewport->uScreenHeight / skybox_height; v[2].pos.x = pViewport->uScreen_TL_X + pViewport->uScreenWidth; v[2].pos.y = pViewport->uScreen_TL_Y; v[2].pos.z = 0.99989998; v[2].rhw = 1; v[2].diffuse = -1; v[2].specular = 0; v[2].texcoord.x = (float)pViewport->uScreenWidth / skybox_width; v[2].texcoord.y = 0; memcpy(&v[3], &v[0], sizeof(*v)); v[4].pos.x = pViewport->uScreen_TL_X; v[4].pos.y = pViewport->uScreen_TL_Y + pViewport->uScreenHeight; v[4].pos.z = 0.99989998; v[4].rhw = 1; v[4].diffuse = -1; v[4].specular = 0; v[4].texcoord.x = 0; v[4].texcoord.y = (float)pViewport->uScreenHeight / skybox_height; memcpy(&v[5], &v[1], sizeof(*v)); __debugbreak(); /* pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE); pRenderer->pRenderD3D->pDevice->SetTexture(0, skybox_texture); pRenderer->pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, v, 6, D3DDP_DONOTUPDATEEXTENTS | D3DDP_DONOTLIGHT); */ return true; } DDSURFACEDESC2 desc; desc.dwSize = sizeof(desc); if (!pRenderer->LockSurface_DDraw4(skybox_surface, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY)) return false; last_camera_rot_y = pParty->sRotationY; last_camera_rot_x = pParty->sRotationX; float aspect = (float)pViewport->uScreenWidth / (float)pViewport->uScreenHeight; float fov_x = 3.141592f * (pODMRenderParams->uCameraFovInDegrees + 0) / 360.0f; float fov_y = fov_x / aspect; float ray_dx = fov_x / (float)pViewport->uScreenWidth, ray_dy = fov_y / (float)pViewport->uScreenHeight; float party_angle_x = 2 * 3.141592653589 * pParty->sRotationX / 2048.0, party_angle_y = 2 * 3.141592653589 * pParty->sRotationY / 2048.0; for (int y = 0; y < pViewport->uScreenHeight; ++y) for (int x = 0; x < pViewport->uScreenWidth; ++x) { float angle_x = party_angle_x - (y - pViewport->uScreenHeight / 2) * ray_dy; float angle_y = party_angle_y - (x - pViewport->uScreenWidth / 2) * ray_dx; float _dir_x_ = 1, _dir_y_ = 0, _dir_z_ = 0; float dir_x_ = _dir_x_ * cosf(angle_y);// - _dir_z_ * sinf(angle_y); // rotation around y //float dir_y_ = _dir_y_; float dir_z_ = _dir_x_ * sinf(angle_y);// + _dir_z_ * cosf(angle_y); //float dir_x = dir_x_; // rotation around x //float dir_y = /*dir_y_ * cosf(angle_x)*/ + dir_z_ * sinf(angle_x); //float dir_z = /*-dir_y_ * sinf(angle_x)*/ + dir_z_ * cosf(angle_x); vector right; // rotate around right actually to avoid space distortion right.x = /*dir_y * 0*/ -dir_z_ * 1; right.y = /*dir_z_ * 0 - dir_x_ * */0; right.z = dir_x_ * 1/* - dir_y_ * 0*/; //VectorNormalize(&right); matrix rightMatrix; MatrixRotationAxis(&rightMatrix, &right, angle_x); vector v1, v2; v1.x = dir_x_; v1.y = 0; v1.z = dir_z_; VectorTransform(&rightMatrix, &v1, &v2); float dir_x = v2.x, dir_y = v2.y, dir_z = v2.z; float abs_dir_x = fabsf(dir_x), abs_dir_y = fabsf(dir_y), abs_dir_z = fabsf(dir_z); unsigned short color = (0x1F << 11) | (0x1F << 5) | (5); //default to orange if (abs_dir_x >= abs_dir_y) { if (abs_dir_x >= abs_dir_z) { if (dir_x >= 0) { float instersect_y = dir_y / (2.0f * dir_x); // plane equation for this side is x + 0.5 = 0 float instersect_z = dir_z / (2.0f * dir_x); float u = 1.0f - (instersect_z + 0.5f), v = 1.0f - (instersect_y + 0.5f); int tx = u * (skybox_width - 1), ty = v * (skybox_height - 1); color = skybox_xp[ty * skybox_width + tx]; //color = ty * 0x1F / skybox_height; } else { float instersect_y = dir_y / (2.0f * dir_x); float instersect_z = dir_z / (2.0f * dir_x); float u = 1.0f - (instersect_z + 0.5f), v = instersect_y + 0.5f; int tx = u * (skybox_width - 1), ty = v * (skybox_height - 1); color = skybox_xn[ty * skybox_width + tx]; //color = tx * 0x1F / skybox_height; } } else if (dir_z >= 0) goto DIR_ZP; else goto DIR_ZN; } else if (abs_dir_y >= abs_dir_z) { if (dir_y >= 0) { float instersect_x = dir_x / (2.0f * dir_y); float instersect_z = dir_z / (2.0f * dir_y); float u = instersect_x + 0.5f, v = instersect_z + 0.5f; int tx = u * (skybox_width - 1), ty = v * (skybox_height - 1); color = skybox_yp[ty * skybox_width + tx]; //color = tx * 0x1F / skybox_height; } /*else should never be seen i guess { __debugbreak(); // -y //Log::Warning(L"(%03u, %03u): -y", x, y); }*/ } else if (dir_z >= 0) { DIR_ZP: // +z float instersect_x = dir_x / (2.0f * dir_z); float instersect_y = dir_y / (2.0f * dir_z); //float intersect_z = 0.5f; float u = instersect_x + 0.5f, v = -instersect_y + 0.5f; int tx = u * (skybox_width - 1), ty = v * (skybox_height - 1); color = skybox_zp[ty * skybox_width + tx]; } else { DIR_ZN: // -z float instersect_x = -dir_x / (2.0f * dir_z); float instersect_y = -dir_y / (2.0f * dir_z); //float intersect_z = -0.5f; float u = 1.0f - instersect_x - 0.5f, v = -instersect_y + 0.5f; int tx = u * (skybox_width - 1), ty = v * (skybox_height - 1); color = skybox_zn[ty * skybox_width + tx]; } //pRenderer->pTargetSurface[(pViewport->uScreenY + y) * pRenderer->uTargetSurfacePitch + pViewport->uScreenX + x] = color; ((unsigned __int16 *)((char *)desc.lpSurface + y * desc.lPitch))[x] = color; } ErrD3D((skybox_surface)->Unlock(0)); goto draw; } //----- (00485F53) -------------------------------------------------------- void sr_485F53(Vec2_int_ *v) { ++v->y; if (v->y > 1000) v->y = 0; } //----- (0048607B) -------------------------------------------------------- void Polygon::Create_48607B(stru149 *a2) { this->pTexture = 0; this->ptr_38 = a2; } //----- (00486089) -------------------------------------------------------- void Polygon::_normalize_v_18() { //double v2; // st7@1 //double v3; // st6@1 //double v5; // st5@1 // v2 = (double)this->v_18.x; //v3 = (double)this->v_18.y; // v5 = (double)this->v_18.z; float len = sqrt((double)this->v_18.z * (double)this->v_18.z + (double)this->v_18.y * (double)this->v_18.y + (double)this->v_18.x * (double)this->v_18.x); if (fabsf(len) < 1e-6f) { v_18.x = 0; v_18.y = 0; v_18.z = 65536; } else { v_18.x = round_to_int((double)this->v_18.x / len * 65536.0); v_18.y = round_to_int((double)this->v_18.y / len * 65536.0); v_18.y = round_to_int((double)this->v_18.z / len * 65536.0); } } //----- (0048616B) -------------------------------------------------------- void stru149::_48616B_frustum_odm(int a2, int a3, int a4, int a5, int a6, int a7) { int v7; // ebx@1 int v9; // edi@1 int v11; // edx@1 int v17; // ST0C_4@6 int v19; // ST0C_4@9 int v24; // [sp+14h] [bp-14h]@1 int v25; // [sp+18h] [bp-10h]@1 int v27; // [sp+24h] [bp-4h]@1 v25 = pGame->pIndoorCameraD3D->int_cosine_x; v7 = pGame->pIndoorCameraD3D->int_sine_y; v27 = pGame->pIndoorCameraD3D->int_sine_x; //v8 = -pIndoorCamera->pos.y; v9 = pGame->pIndoorCameraD3D->int_cosine_y; //v26 = -pIndoorCamera->pos.z; v11 = pGame->pIndoorCameraD3D->int_cosine_y * -pGame->pIndoorCameraD3D->vPartyPos.x + pGame->pIndoorCameraD3D->int_sine_y * -pGame->pIndoorCameraD3D->vPartyPos.y; v24 = pGame->pIndoorCameraD3D->int_cosine_y * -pGame->pIndoorCameraD3D->vPartyPos.y - pGame->pIndoorCameraD3D->int_sine_y * -pGame->pIndoorCameraD3D->vPartyPos.x; if (pGame->pIndoorCameraD3D->sRotationX) { this->field_0_party_dir_x = fixpoint_mul(v11, pGame->pIndoorCameraD3D->int_cosine_x) + fixpoint_mul((-pGame->pIndoorCameraD3D->vPartyPos.z) << 16, pGame->pIndoorCameraD3D->int_sine_x); this->field_4_party_dir_y = v24; this->field_8_party_dir_z = fixpoint_mul((-pGame->pIndoorCameraD3D->vPartyPos.z) << 16, v25) - fixpoint_mul(v11, v27); } else { this->field_0_party_dir_x = v11; this->field_4_party_dir_y = v24; this->field_8_party_dir_z = (-pGame->pIndoorCameraD3D->vPartyPos.z) << 16; } if (pGame->pIndoorCameraD3D->sRotationX) { v17 = fixpoint_mul(a2, v9) + fixpoint_mul(a3, v7); this->angle_from_north = fixpoint_mul(v17, v25) + fixpoint_mul(a4, v27); this->angle_from_west = fixpoint_mul(a3, v9) - fixpoint_mul(a2, v7); this->viewing_angle_from_west_east = fixpoint_mul(a4, v25) - fixpoint_mul(v17, v27); } else { this->angle_from_north = fixpoint_mul(a2, v9) + fixpoint_mul(a3, v7); this->angle_from_west = fixpoint_mul(a3, v9) - fixpoint_mul(a2, v7); this->viewing_angle_from_west_east = a4; } if (pGame->pIndoorCameraD3D->sRotationX) { v19 = fixpoint_mul(a5, v9) + fixpoint_mul(a6, v7); this->angle_from_east = fixpoint_mul(v19, v25) + fixpoint_mul(a7, v27); this->angle_from_south = fixpoint_mul(a6, v9) - fixpoint_mul(a5, v7); this->viewing_angle_from_north_south = fixpoint_mul(a7, v25) - fixpoint_mul(v19, v27); } else { this->angle_from_east = fixpoint_mul(a5, v9) + fixpoint_mul(a6, v7); this->angle_from_south = fixpoint_mul(a6, v9) - fixpoint_mul(a5, v7); this->viewing_angle_from_north_south = a7; } this->angle_from_east = -this->angle_from_east; this->angle_from_south = -this->angle_from_south; this->viewing_angle_from_north_south = -this->viewing_angle_from_north_south; this->field_24 = fixpoint_dot(this->angle_from_north, this->field_0_party_dir_x, this->angle_from_west, this->field_4_party_dir_y, this->viewing_angle_from_west_east, this->field_8_party_dir_z); this->field_28 = fixpoint_dot(this->angle_from_east, this->field_0_party_dir_x, this->angle_from_south, this->field_4_party_dir_y, this->viewing_angle_from_north_south, this->field_8_party_dir_z); } //----- (0048694B) -------------------------------------------------------- void stru149::_48694B_frustum_sky() { this->angle_from_east = -this->angle_from_east; this->angle_from_south = -this->angle_from_south; this->viewing_angle_from_north_south = -this->viewing_angle_from_north_south; this->field_24 = fixpoint_dot(this->angle_from_north, this->field_0_party_dir_x, this->angle_from_west, this->field_4_party_dir_y, this->viewing_angle_from_west_east, this->field_8_party_dir_z); this->field_28 = fixpoint_dot(this->angle_from_east, this->field_0_party_dir_x, this->angle_from_south, this->field_4_party_dir_y, this->viewing_angle_from_north_south, this->field_8_party_dir_z); }