# HG changeset patch # User Ritor1 # Date 1364183361 -21600 # Node ID f57bd5c0890cd1cfe073c7dfb800aa3cd35ff76c # Parent 11dab247bd726d65c4c54baa1f1d7de4aea4d8ac# Parent 346f7069676a17e9b6bd96c809e23e8a28205dde Слияние diff -r 11dab247bd72 -r f57bd5c0890c DecalBuilder.cpp --- a/DecalBuilder.cpp Mon Mar 25 09:49:12 2013 +0600 +++ b/DecalBuilder.cpp Mon Mar 25 09:49:21 2013 +0600 @@ -467,7 +467,7 @@ if (pFace->uAttributes & 0x400000) return true; - if (pFace->Animated()) + if (pFace->Fluid()) return true; for (uint i = 0; i < pBloodsplatContainer->std__vector_pBloodsplats_size; ++i) diff -r 11dab247bd72 -r f57bd5c0890c Game.cpp --- a/Game.cpp Mon Mar 25 09:49:12 2013 +0600 +++ b/Game.cpp Mon Mar 25 09:49:21 2013 +0600 @@ -22,6 +22,7 @@ #include "Arcomage.h" #include "texts.h" #include "Actor.h" +#include "GUIFont.h" #include "Log.h" //#include "MM7.h" @@ -119,6 +120,11 @@ } pRenderer->DrawBillboards_And_MaybeRenderSpecialEffects_And_EndScene(); LABEL_22: + + //DEBUG: force redraw gui + viewparams->bRedrawGameUI = true; + + pRenderer->BeginScene(); if (pRenderer->pRenderD3D) pMouse->DrawCursorToTarget(); @@ -166,12 +172,35 @@ pOtherOverlayList->DrawTurnBasedIcon(v4); GameUI_DrawTorchlightAndWizardEye(); } + + if (uCurrentlyLoadedLevelType == LEVEL_Indoor) + { + sprintf(pTmpBuf, "Party Sector ID: %u/%u\n", pBLVRenderParams->uPartySectorID, pIndoor->uNumSectors); + pPrimaryWindow->DrawText(pFontArrus, 16, 16, GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(255, 255, 255), pTmpBuf, 0, 0, 0xFFFFFFFF); + } + sprintf(pTmpBuf, "Party Position: % d % d % d", pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z); + pPrimaryWindow->DrawText(pFontArrus, 16, 16 + 16, GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(255, 255, 255), pTmpBuf, 0, 0, 0xFFFFFFFF); + + if (uCurrentlyLoadedLevelType == LEVEL_Indoor) + { + uint uFaceID; + auto floor_level = BLV_GetFloorLevel(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z, pBLVRenderParams->uPartySectorID, &uFaceID); + sprintf(pTmpBuf, "BLV_GetFloorLevel: %d face_id %d\n", floor_level, uFaceID); + } + else + { + int on_water, _a6; + auto floor_level = ODM_GetFloorLevel(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z, 0, &on_water, &_a6, false); + sprintf(pTmpBuf, "ODM_GetFloorLevel: %d on_water: %s a6 = %d\n", floor_level, on_water ? "true" : "false", _a6); + } + pPrimaryWindow->DrawText(pFontArrus, 16, 16 + 16 + 16, GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(255, 255, 255), pTmpBuf, 0, 0, 0xFFFFFFFF); + GUI_UpdateWindows(); pParty->UpdatePlayersAndHirelingsEmotions(); ++stru_51076C.field_8; _unused_5B5924_is_travel_ui_drawn = false; if (v4) - pMouse->field_14 = 1; + pMouse->bRedraw = true; pMouse->_469EA4(); pMouse->DrawCursor(); pMouse->_469E1C(); diff -r 11dab247bd72 -r f57bd5c0890c Indoor.cpp --- a/Indoor.cpp Mon Mar 25 09:49:12 2013 +0600 +++ b/Indoor.cpp Mon Mar 25 09:49:21 2013 +0600 @@ -23,6 +23,9 @@ #include "PaletteManager.h" #include "MapInfo.h" #include "IndoorCamera.h" +#include "GUIWindow.h" +#include "GUIButton.h" +#include "GUIFont.h" #include "mm7_data.h" @@ -375,10 +378,14 @@ if (viewparams->draw_d3d_outlines) _this.uFlags |= INDOOR_CAMERA_DRAW_D3D_OUTLINES; + _this.uFlags |= INDOOR_CAMERA_DRAW_D3D_OUTLINES; + _this.uFlags |= INDOOR_CAMERA_DRAW_SW_OUTLINES; + //INDOOR_CAMERA_DRAW_TERRAIN_OUTLINES + _this.field_0_timer = pEventTimer->uTotalGameTimeElapsed; _this.field_1C_mb_fov = 65; - _this.vPosition.x = pParty->vPosition.x - ((stru_5C6E00->Cos(pParty->sRotationY) * (signed __int64)pParty->y_rotation_granularity) >> 16); - _this.vPosition.y = pParty->vPosition.y - ((stru_5C6E00->Sin(pParty->sRotationY) * (signed __int64)pParty->y_rotation_granularity) >> 16); + _this.vPosition.x = pParty->vPosition.x - fixpoint_mul(stru_5C6E00->Cos(pParty->sRotationY), pParty->y_rotation_granularity); + _this.vPosition.y = pParty->vPosition.y - fixpoint_mul(stru_5C6E00->Sin(pParty->sRotationY), pParty->y_rotation_granularity); _this.vPosition.z = pParty->vPosition.z + pParty->sEyelevel; _this.sRotationX = pParty->sRotationX; _this.sRotationY = pParty->sRotationY; @@ -537,7 +544,7 @@ if (pDecalBuilder->uNumDecals > 0) pDecalBuilder->ApplyDecals(a4a, 1, &stru_F7B60C, uNumVerticesa, array_507D30, pVertices, 0, pFace->uSectorID); - if (pFace->Animated() && + if (pFace->Fluid() && pFace->uBitmapID == pRenderer->hd_water_tile_id ) { __debugbreak(); @@ -545,7 +552,7 @@ goto LABEL_42; } - if (pFace->Animated()) + if (pFace->Fluid()) { //auto v24 = GetTickCount() / 4; //auto v25 = v24 - stru_5C6E00->uIntegerHalfPi; @@ -1467,6 +1474,7 @@ } if (pBLVRenderParams->uFlags & INDOOR_CAMERA_DRAW_SW_OUTLINES) pGame->pIndoorCameraD3D->PrepareAndDrawDebugOutline(pFace, 0x1E1EFF); + //pGame->pIndoorCameraD3D->DebugDrawPortal(pFace); } } @@ -3121,10 +3129,10 @@ ///Vec3_short_ *v29; // eax@26 //Vec3_short_ *v30; // edx@26 //int v31; // edx@26 - signed int v32; // edi@27 + //signed int v32; // edi@27 signed __int64 v33; // qtt@27 //Vec3_short_ *v34; // edx@27 - int v35; // edx@32 + //int v35; // edx@32 int v37; // edi@38 int pSectorID; // ebx@40 int v39; // eax@41 @@ -3150,12 +3158,10 @@ int v59; // [sp+110h] [bp-4h]@16 v4 = 0; - //v7 = __OFSUB__(this->uNumSectors, 1); - //v5 = this->uNumSectors == 1; - //v6 = this->uNumSectors - 1 < 0; + v43[0] = 0; + v55 = 0; - v43[0] = 0; - //v56 = 1; + if (uNumSectors < 2) return 0; @@ -3163,126 +3169,101 @@ { auto pSector = pSectors + i; - if (pSector->pBounding.x1 <= sX && pSector->pBounding.x2 >= sX) - if (pSector->pBounding.y1 <= sY && pSector->pBounding.y2 >= sY) - if (pSector->pBounding.z1 - 64 <= sZ && pSector->pBounding.z2 + 64 >= sZ) - { + if (pSector->pBounding.x1 > sX || pSector->pBounding.x2 < sX || + pSector->pBounding.y1 > sY || pSector->pBounding.y2 < sY || + pSector->pBounding.z1 - 64 > sZ || pSector->pBounding.z2 + 64 < sZ) + continue; + //Log::Warning(L"Sector[%u]", i); - v51 = pSector->uNumFloors + pSector->uNumPortals; - if (!v51) - continue; - - //v9 = pSector->uNumFloors; - //v10 = v9 + pSector->uNumPortals; - //v11 = 0; - //v44 = v9; - //v48 = 0; - - //v12 = -2 * v9; - //v53 = -2 * v9; - for (uint j = 0; j < v51; ++j) - { - unsigned int uFaceID; - if (j < pSector->uNumFloors) - uFaceID = pSector->pFloors[j]; - else - uFaceID = pSector->pPortals[j - pSector->uNumFloors]; - - auto pFace = pFaces + uFaceID; - //v14 = (signed __int16)v13; - //v15 = this->pFaces; - //v46 = v13; - //v14 *= 96; - //v45 = v13 * sizeof(BLVFace); - //v16 = pFaces + uFaceID; - //v17 = v16->uPolygonType; - if (pFace->uPolygonType == POLYGON_Floor || - pFace->uPolygonType == POLYGON_InBetweenFloorAndWall) - { - //pVertexIDs = pFace->pVertexIDs; - //v19 = this->pVertices; - //v20 = pVertices[pFace->pVertexIDs[0]].y; - v54 = 0; - //v57 = 0; - //v5 = v16->uNumVertices == 0; - v59 = pVertices[pFace->pVertexIDs[0]].y >= sY; - - //v21 = pFace->pVertexIDs + 1; - for (uint k = 0; k < pFace->uNumVertices; k++) - { - if (v54 >= 2) - break; - - //v49 = &pVertices[pFace->pVertexIDs[k]]; - auto v2 = &pVertices[pFace->pVertexIDs[k]]; - //v22 = pVertex->y; - //v47 = pVertex->y; - v50 = v2->y >= sY; - if ( v59 != v50 ) - { - //v58 = &pVertices[pFace->pVertexIDs[k - 1]]; - auto v1 = &pVertices[pFace->pVertexIDs[k]]; - //v23 = v58->x; - //HIWORD(v24) = HIWORD(v49); - //LOWORD(v24) = v49->x; - //v49 = v24; - //v59 = v49->x; - v25 = v1->x >= sX ? 0 : 2; - v26 = v25 | v2->x < sX; - if ( v26 != 3 ) - { - if (!v26) - ++v54; - else - { - if (v1->x >= v2->x) - { - int _a58; + v51 = pSector->uNumFloors + pSector->uNumPortals; + if (!v51) + continue; + + + for (uint j = 0; j < v51; ++j) + { + uint uFaceID; + if (j < pSector->uNumFloors) + uFaceID = pSector->pFloors[j]; + else + uFaceID = pSector->pPortals[j - pSector->uNumFloors]; + + auto pFace = pFaces + uFaceID; + if (pFace->uPolygonType != POLYGON_Floor && + pFace->uPolygonType != POLYGON_InBetweenFloorAndWall) + continue; + + v54 = 0; + v50 = pVertices[pFace->pVertexIDs[0]].y >= sY; + + for (uint k = 1; k < pFace->uNumVertices; k++) + { + v59 = v50; + + if (v54 >= 2) + break; + + auto v2 = &pVertices[pFace->pVertexIDs[k]]; + v50 = v2->y >= sY; + + if ( v59 == v50 ) + continue; + + auto v1 = &pVertices[pFace->pVertexIDs[k - 1]]; + v25 = v2->x >= sX ? 0 : 2; + v26 = v25 | (v1->x < sX); + + if (v26 == 3) + continue; + + if (!v26) + ++v54; + else + { + if (v1->x >= v2->x) + { + /*int _a58; int _a59; v32 = v1->x - v2->x; LODWORD(v33) = v32 << 16; - HIDWORD(v33) = v32 >> 16; - _a58 = v33 / (v1->y - v2->y); - _a59 = (unsigned __int64)(_a58 * (__int64)(sY - v2->y)) >> 16; - - if (v59 + pVertices[k].x > sX) - ++v54; - } - else - { - int _a58; + HIDWORD(v33) = v32 >> 16;*/ + //fixpoint_div(v1->x - v2->x, v1->y - v2->y); + //_a58 = v33 / (v1->y - v2->y); + //_a59 = fixpoint_mul(_a58, sY - v2->y); + auto x_div_y = fixpoint_div(v1->x - v2->x, v1->y - v2->y); + auto rval = fixpoint_mul(x_div_y, sY - v2->y); // a / b * c - looks like projection + if (rval + v2->x > sX) + ++v54; + } + else + { + auto x_div_y = fixpoint_div(v2->x - v1->x, v2->y - v1->y); + auto res = fixpoint_mul(x_div_y, sY - v1->y); + + if (res + v1->x > sX) + ++v54; + + /*int _a58; int _a59; - v32 = v2->x - v1->x; + auto v32 = v2->x - v1->x; LODWORD(v33) = v32 << 16; HIDWORD(v33) = v32 >> 16; _a58 = v33 / (v2->y - v1->y); - _a59 = (unsigned __int64)(_a58 * (signed __int64)(sY - v1->y)) >> 16; + _a59 = fixpoint_mul(_a58, sY - v1->y); if (_a59 + pVertices[k].x > sX) - ++v54; - } - } - } - } - - v59 = v50; - } - - if (pFace->uNumVertices) - { - if (v54 == 1) - { - v35 = v55++; - v43[v35] = uFaceID; - } - } - } + ++v54;*/ } - v4 = v43[0]; } + } + + if (pFace->uNumVertices && v54 == 1) + v43[v55++] = uFaceID; + } } + v4 = v43[0]; if ( v55 == 1 ) return this->pFaces[v4].uSectorID; v37 = 0; diff -r 11dab247bd72 -r f57bd5c0890c Indoor.h --- a/Indoor.h Mon Mar 25 09:49:12 2013 +0600 +++ b/Indoor.h Mon Mar 25 09:49:21 2013 +0600 @@ -252,7 +252,7 @@ #define FACE_PORTAL 0x00000001 // portal/two-sided #define FACE_CAN_SATURATE_COLOR 0x00000002 -#define FACE_TEXTURE_ANIMATED 0x00000010 // like wavy water +#define FACE_FLUID 0x00000010 // wavy animated water or lava #define FACE_INVISIBLE 0x00002000 #define FACE_TEXTURE_FRAME 0x00004000 // Texture ID is a frameset from TextureFrameTable, otherwise BitmapID #define FACE_OUTLINED 0x00010000 // outline face edges @@ -285,7 +285,7 @@ inline bool Invisible() const {return uAttributes & FACE_INVISIBLE;} inline bool Visible() const {return !Invisible();} inline bool Portal() const {return uAttributes & FACE_PORTAL;} - inline bool Animated() const {return uAttributes & FACE_TEXTURE_ANIMATED;} + inline bool Fluid() const {return uAttributes & FACE_FLUID;} inline bool Clickable() const {return uAttributes & FACE_CLICKABLE;} @@ -527,6 +527,10 @@ #pragma pack(push, 1) struct BLVRenderParams { + inline BLVRenderParams(): + uFlags(0) + {} + int Reset(struct IndoorLocation_drawstru *a2); int field_0_timer_; diff -r 11dab247bd72 -r f57bd5c0890c IndoorCamera.h --- a/IndoorCamera.h Mon Mar 25 09:49:12 2013 +0600 +++ b/IndoorCamera.h Mon Mar 25 09:49:21 2013 +0600 @@ -4,6 +4,7 @@ #define INDOOR_CAMERA_DRAW_SW_OUTLINES 1 #define INDOOR_CAMERA_DRAW_D3D_OUTLINES 2 +#define INDOOR_CAMERA_DRAW_TERRAIN_OUTLINES 4 /* 157 */ #pragma pack(push, 1) struct IndoorCamera diff -r 11dab247bd72 -r f57bd5c0890c IndoorCameraD3D.cpp --- a/IndoorCameraD3D.cpp Mon Mar 25 09:49:12 2013 +0600 +++ b/IndoorCameraD3D.cpp Mon Mar 25 09:49:21 2013 +0600 @@ -998,6 +998,59 @@ do_draw_debug_line_sw(&a2[v5], uDiffuse, a2, uDiffuse, 0, a5); } + +void IndoorCameraD3D::DebugDrawPortal(BLVFace *pFace) +{ + assert(pFace->uNumVertices <= 32); + + RenderVertexSoft sw[32]; + for (uint i = 0; i < pFace->uNumVertices; ++i) + { + sw[i].vWorldPosition.x = pIndoor->pVertices[pFace->pVertexIDs[i]].x; + sw[i].vWorldPosition.y = pIndoor->pVertices[pFace->pVertexIDs[i]].y; + sw[i].vWorldPosition.z = pIndoor->pVertices[pFace->pVertexIDs[i]].z; + } + ViewTransform(sw, pFace->uNumVertices); + Project(sw, pFace->uNumVertices, 0); + + + + RenderVertexD3D3 v[32]; + for (uint i = 0; i < pFace->uNumVertices; ++i) + { + v[i].pos.x = sw[i].vWorldViewProjX; + v[i].pos.y = sw[i].vWorldViewProjY; + v[i].pos.z = 1.0 - 1.0 / (sw[i].vWorldViewPosition.x * 0.061758894); + v[i].rhw = 1.0 / sw[i].vWorldViewPosition.x; + v[i].diffuse = 0x80F020F0; + v[i].specular = 0; + //v[i].texcoord.x = pFace->pVertexUIDs[i] / (double)pTex->uTextureWidth; + //v[i].texcoord.y = pFace->pVertexUIDs[i] / (double)pTex->uTextureHeight; + v[i].texcoord.x = 0; + v[i].texcoord.y = 0; + } + + + //ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false)); + //ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, false)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA)); + + ErrD3D(pRenderer->pRenderD3D->pDevice->SetTexture(0, nullptr)); + ErrD3D(pRenderer->pRenderD3D->pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, + v, + pFace->uNumVertices, + 28)); + + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO)); + ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE)); + //ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, TRUE)); + //ErrD3D(pRenderer->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE)); +} + //----- (00437906) -------------------------------------------------------- void IndoorCameraD3D::PrepareAndDrawDebugOutline(BLVFace *pFace, unsigned int uDiffuse) { diff -r 11dab247bd72 -r f57bd5c0890c IndoorCameraD3D.h --- a/IndoorCameraD3D.h Mon Mar 25 09:49:12 2013 +0600 +++ b/IndoorCameraD3D.h Mon Mar 25 09:49:21 2013 +0600 @@ -158,6 +158,8 @@ void ViewTransfrom_OffsetUV(struct RenderVertexSoft *pVertices, unsigned int uNumVertices, struct RenderVertexSoft *pOutVertices, struct stru320 *a5); char ApplyViewTransform_TrueIfStillVisible(int x, int y, int z, signed int *pOutX, int *pOutZ, int *pOutY, char bDoNotShow); + void DebugDrawPortal(struct BLVFace *pFace); + //void (__thiscall ***vdestructor_ptr)(IndoorCameraD3D *, bool); IndoorCameraD3D_Vec3 field_4[3]; //IndoorCameraD3D_Vec3 field_14; diff -r 11dab247bd72 -r f57bd5c0890c Mouse.cpp --- a/Mouse.cpp Mon Mar 25 09:49:12 2013 +0600 +++ b/Mouse.cpp Mon Mar 25 09:49:21 2013 +0600 @@ -89,7 +89,7 @@ v2->uCursorTextureID_2 = v9; v2->AllocCursorSystemMem(); v2->field_C = 0; - v2->field_14 = 1; + v2->bRedraw = 1; v2->bActive = 1; if ( !areWeLoadingTexture ) { @@ -378,7 +378,7 @@ v8 = v1->pCursorBitmapRect.z; v1->bActive = 0; v1->uCursorBitmapWidth = v8 - v5->x; - v11 = v1->field_14 == 0; + v11 = v1->bRedraw == 0; v1->uCursorBitmapHeight = v1->pCursorBitmapRect.w - v1->pCursorBitmapRect.y; if ( !v11 ) { @@ -393,7 +393,7 @@ pRenderer->pTargetSurface, pRenderer->uTargetSurfacePitch, &v1->pCursorBitmapRect); - v1->field_14 = 0; + v1->bRedraw = false; } } } diff -r 11dab247bd72 -r f57bd5c0890c Mouse.h --- a/Mouse.h Mon Mar 25 09:49:12 2013 +0600 +++ b/Mouse.h Mon Mar 25 09:49:21 2013 +0600 @@ -84,7 +84,7 @@ int field_8; int field_C; unsigned int bInitialized; - int field_14; + unsigned int bRedraw; int field_18; int field_1C; int field_20; diff -r 11dab247bd72 -r f57bd5c0890c Outdoor.cpp --- a/Outdoor.cpp Mon Mar 25 09:49:12 2013 +0600 +++ b/Outdoor.cpp Mon Mar 25 09:49:21 2013 +0600 @@ -88,6 +88,7 @@ pIndoorCamera->flags = 0; if (viewparams->draw_d3d_outlines) pIndoorCamera->flags |= INDOOR_CAMERA_DRAW_D3D_OUTLINES; + //INDOOR_CAMERA_DRAW_TERRAIN_OUTLINES pIndoorCamera->sRotationX = pParty->sRotationX; pIndoorCamera->sRotationY = pParty->sRotationY; diff -r 11dab247bd72 -r f57bd5c0890c Outdoor.h --- a/Outdoor.h Mon Mar 25 09:49:12 2013 +0600 +++ b/Outdoor.h Mon Mar 25 09:49:21 2013 +0600 @@ -89,7 +89,8 @@ inline bool Invisible() const {return uAttributes & FACE_INVISIBLE;} inline bool Visible() const {return !Invisible();} - inline bool TwoSided() const {return uAttributes & FACE_PORTAL;} + inline bool Portal() const {return uAttributes & FACE_PORTAL;} + inline bool Fluid() const {return uAttributes & FACE_FLUID;} struct Plane_int_ pFacePlane; int zCalc1; diff -r 11dab247bd72 -r f57bd5c0890c Render.cpp --- a/Render.cpp Mon Mar 25 09:49:12 2013 +0600 +++ b/Render.cpp Mon Mar 25 09:49:21 2013 +0600 @@ -7609,8 +7609,7 @@ } } - if (pIndoorCamera->flags & INDOOR_CAMERA_DRAW_D3D_OUTLINES || - pBLVRenderParams->uFlags & INDOOR_CAMERA_DRAW_D3D_OUTLINES ) + if (pIndoorCamera->flags & INDOOR_CAMERA_DRAW_TERRAIN_OUTLINES || pBLVRenderParams->uFlags & INDOOR_CAMERA_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 diff -r 11dab247bd72 -r f57bd5c0890c UIHouses.cpp --- a/UIHouses.cpp Mon Mar 25 09:49:12 2013 +0600 +++ b/UIHouses.cpp Mon Mar 25 09:49:21 2013 +0600 @@ -1484,13 +1484,6 @@ v37 = v36 * (100 - pPlayers[uActiveCharacter]->GetMerchant()) / 100; if ( v37 < v36 / 3 ) v37 = v36 / 3; - - __debugbreak(); - //pSkillAvailabilityPerClass[8 + v58->uClass][4 + v23] - // or - //byte_4ED970_skill_learn_ability_by_class_table[v58->uClass][v23 - 36] - // or - //byte_4ED970_skill_learn_ability_by_class_table[v58->uClass - 1][v23 + 1] //if (false) if(byte_4ED970_skill_learn_ability_by_class_table[v35->classType][uMessageParam-36]) diff -r 11dab247bd72 -r f57bd5c0890c mm7_1.cpp --- a/mm7_1.cpp Mon Mar 25 09:49:12 2013 +0600 +++ b/mm7_1.cpp Mon Mar 25 09:49:21 2013 +0600 @@ -58,11 +58,18 @@ bool __fastcall FindMM7CD(HWND hWnd, char *pCDDrive); bool __fastcall Initialize(HINSTANCE hInst, char *pCmdLine); + +//----- (004A1780) mm6_chinese--------------------------------------------- +int fixpoint_div(int a1, int a2) +{ + return ((__int64)a1 << 16) / a2; +} + //----- (004453C0) mm6----------------------------------------------------- //----- (004A1760) mm6_chinese--------------------------------------------- int fixpoint_mul(int a1, int a2) { - return ((__int64)a1 * a2) >> 16; + return ((__int64)a1 * (__int64)a2) / 65536; } //----- (004196A0) -------------------------------------------------------- @@ -1164,7 +1171,7 @@ } else { - if ( (v0 & 7) != OBJECT_BModel || (unsigned int)v0 >= 0x2000000 ) + if ( (v0 & 7) != OBJECT_BModel || (signed)v0 >= 0x2000000 ) { v4 = pParty->pPickedItem.uItemID; if ( !pParty->pPickedItem.uItemID ) diff -r 11dab247bd72 -r f57bd5c0890c mm7_3.cpp --- a/mm7_3.cpp Mon Mar 25 09:49:12 2013 +0600 +++ b/mm7_3.cpp Mon Mar 25 09:49:21 2013 +0600 @@ -7756,7 +7756,7 @@ } //----- (0048257A) -------------------------------------------------------- -int __fastcall GetTerrainHeightsAroundParty2(int a1, int a2, int *a3, int a4) +int __fastcall GetTerrainHeightsAroundParty2(int a1, int a2, int *pIsOnWater, int a4) { unsigned int v4; // ebx@1 unsigned int v5; // edi@1 @@ -7787,11 +7787,11 @@ dword_76D51C_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4 + 1, v5); dword_76D520_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4 + 1, v5 + 1); dword_76D524_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4, v5 + 1); - *a3 = 0; + *pIsOnWater = false; if ( pOutdoor->ActuallyGetSomeOtherTileInfo(v4, v5) & 2 ) - *a3 = 1; + *pIsOnWater = true; v14 = 0; - if ( !a4 && *a3 ) + if ( !a4 && *pIsOnWater ) v14 = -60; if ( dword_76D518_terrain_cell_world_pos_around_party_y != dword_76D51C_terrain_cell_world_pos_around_party_y || dword_76D51C_terrain_cell_world_pos_around_party_y != dword_76D520_terrain_cell_world_pos_around_party_y @@ -11973,8 +11973,8 @@ v6 = ((unsigned short)_evt->v12 << 8) + _evt->v11; - v3->field_C = ((unsigned short)_evt->v12 << 8) + _evt->v11; - v3->field_E = ((unsigned short)_evt->v12 << 8) + _evt->v11; + v3->time_left_to_fire = ((unsigned short)_evt->v12 << 8) + _evt->v11; + v3->fire_interval = ((unsigned short)_evt->v12 << 8) + _evt->v11; if (v3->timer_evt_type == EVENT_OnLongTimer && !(short)v6 ) { if ( v20 ) @@ -11988,7 +11988,7 @@ if ( v3->field_10 ) { ++dword_5B65C8_timers_count; - v3->field_0_time = 0; + v3->next_fire_time = 0; continue; } } @@ -11997,7 +11997,7 @@ v26 != 0 || !v20) { ++dword_5B65C8_timers_count; - v3->field_0_time = 0; + v3->next_fire_time = 0; continue; } } @@ -12052,7 +12052,7 @@ } } } - v3->field_0_time = (signed __int64)((double)((seconds + v3->next_fire_time = (signed __int64)((double)((seconds + 60 * minutes + 3600 * hours + 0x93A80 * weeks @@ -13522,95 +13522,65 @@ } //----- (00448B67) -------------------------------------------------------- -void __thiscall OnTimer(int a1) -{ - int v1; // ebp@1 - unsigned int v2; // ebx@4 - unsigned int v3; // edi@4 - char *pField_C; // esi@6 - __int16 v5; // ax@8 - int v6; // ecx@10 - unsigned int v7; // ebp@12 - int v8; // eax@16 - int v9; // eax@19 - unsigned __int64 v10; // qax@20 - int v11; // ecx@24 - int v12; // [sp+Ch] [bp-10h]@5 - unsigned int v13; // [sp+10h] [bp-Ch]@4 - - v1 = 0; - if ( !pEventTimer->bPaused ) - { - if ( a1 ) - dword_5773C0 = 0; - v3 = HIDWORD(pParty->uTimePlayed); - v2 = LODWORD(pParty->uTimePlayed); - v13 = (signed __int64)(pParty->uTimePlayed - _5773B8_event_timer) / 128; - if ( v13 ) - { - _5773B8_event_timer = pParty->uTimePlayed; - v12 = 0; - if ( dword_5B65C8_timers_count > 0 ) - { - pField_C = (char *)&array_5B5928_timers[0].field_C; - while ( 1 ) - { - v5 = *(short *)pField_C; - if ( *(short *)pField_C != (short)v1 ) - break; - v7 = *((int *)pField_C - 2); - if ( v7 <= v3 && (v7 < v3 || *((int *)pField_C - 3) <= v2) ) - { - if ( *((short *)pField_C + 2) ) - { - v8 = 29030400; - } - else - { - if ( *((short *)pField_C + 3) ) - { - v8 = 2419200; - } - else - { - v9 = -(*((short *)pField_C + 4) != 0); - v8 = (v9 & 0x7E900) + 86400; - } - } - v10 = v7 + *((int *)pField_C - 3) + (signed __int64)((double)((signed __int64)v8 << 7) * 0.033333335);//v10 = __PAIR__(v7, *((int *)v4 - 3)) + (signed __int64)((double)((signed __int64)v8 << 7) * 0.033333335); - *((int *)pField_C - 3) = v10; - *((int *)pField_C - 2) = HIDWORD(v10); - if ( HIDWORD(v10) <= v3 && (HIDWORD(v10) < v3 || *((int *)pField_C - 3) < v2) ) - { - *((int *)pField_C - 3) = v2; - *((int *)pField_C - 2) = v3; - } - v11 = *((short *)pField_C - 2); - start_event_seq_number = *((short *)pField_C - 1); - EventProcessor(v11, 0, 1); - start_event_seq_number = 0; -LABEL_25: - v3 = HIDWORD(pParty->uTimePlayed); - v2 = LODWORD(pParty->uTimePlayed); - } -LABEL_26: - ++v12; - pField_C += 32; - if ( v12 >= dword_5B65C8_timers_count ) - return; - v1 = 0; - } - if ( v13 < v5 ) - { - *(short *)pField_C = v5 - v13; - goto LABEL_26; - } - v6 = *((short *)pField_C - 2); - *(short *)pField_C = *((short *)pField_C + 1); - start_event_seq_number = *((short *)pField_C - 1); - EventProcessor(v6, 0, 1); - start_event_seq_number = v1; - goto LABEL_25; +void OnTimer(int __unused) +{ + if (pEventTimer->bPaused) + return; + + if (__unused) + _5773C0_unused = 0; + + auto v13 = (signed __int64)(pParty->uTimePlayed - _5773B8_event_timer) / 128; + if (!v13) + return; + + //uint _v2v3 = pParty->uTimePlayed; + //v3 = HIDWORD(pParty->uTimePlayed); + //v2 = LODWORD(pParty->uTimePlayed); + + _5773B8_event_timer = pParty->uTimePlayed; + + for (uint i = 0; i < dword_5B65C8_timers_count; ++i) + { + //v4 = (char *)&array_5B5928_timers[0].field_C; + auto timer = array_5B5928_timers + i; + //while ( 1 ) + //{ + //v5 = *(short *)v4; + if (timer->time_left_to_fire) + { + if (v13 < timer->time_left_to_fire) + timer->time_left_to_fire -= v13; + else + { + timer->time_left_to_fire = timer->fire_interval; + + start_event_seq_number = timer->timer_evt_seq_num; + EventProcessor(timer->timer_evt_ID, 0, 1); + + start_event_seq_number = 0; + } + } + else + { + if (timer->next_fire_time < pParty->uTimePlayed) + { + uint next_trigger_time = 1 * 60 * 60 * 24; // 1 day + if (timer->field_10) + next_trigger_time = 336 * 60 * 60 * 24; // 1 year + else if (timer->field_12) + next_trigger_time = 28 * 60 * 60 * 24; // 1 month + else if (timer->field_14) + next_trigger_time = 7 * 60 * 60 * 24; // 1 week + + timer->next_fire_time += (next_trigger_time * 128) / 3.0f; + if (timer->next_fire_time < pParty->uTimePlayed) // make sure in wont fire several times in a row is big time interval has lapsed + timer->next_fire_time = pParty->uTimePlayed; + + start_event_seq_number = timer->timer_evt_seq_num; + EventProcessor(timer->timer_evt_ID, 0, 1); + + start_event_seq_number = 0; } } } diff -r 11dab247bd72 -r f57bd5c0890c mm7_4.cpp --- a/mm7_4.cpp Mon Mar 25 09:49:12 2013 +0600 +++ b/mm7_4.cpp Mon Mar 25 09:49:21 2013 +0600 @@ -439,7 +439,7 @@ } //----- (0046D49E) -------------------------------------------------------- -int __fastcall ODM_GetFloorLevel(int X, signed int Y, int Z, int a4, int *a5, int *a6, int a7) +int __fastcall ODM_GetFloorLevel(int X, signed int Y, int Z, int __unused, int *pIsOnWater, int *a6, int bWaterWalk) { BSPModel *pBModel; // esi@4 ODMFace *pFace; // ecx@11 @@ -474,7 +474,7 @@ v46 = 1; dword_721160[0] = -1; dword_721110[0] = -1; - odm_floor_level[0] = GetTerrainHeightsAroundParty2(X, Y, a5, a7); + odm_floor_level[0] = GetTerrainHeightsAroundParty2(X, Y, pIsOnWater, bWaterWalk); if ( (signed int)pOutdoor->uNumBModels <= 0 ) { *a6 = 0; @@ -605,9 +605,9 @@ if ( v27 ) { v32 = &pOutdoor->pBModels[dword_721160[v27]].pFaces[dword_721110[v27]]; - *a5 = 0; - if ( v32->uAttributes & 0x10 ) - *a5 = 1; + *pIsOnWater = false; + if ( v32->Fluid()) + *pIsOnWater = true; } if ( odm_floor_level[v27] >= odm_floor_level[0] ) odm_floor_level[0] = odm_floor_level[v27]; diff -r 11dab247bd72 -r f57bd5c0890c mm7_data.cpp --- a/mm7_data.cpp Mon Mar 25 09:49:12 2013 +0600 +++ b/mm7_data.cpp Mon Mar 25 09:49:21 2013 +0600 @@ -1640,7 +1640,7 @@ int dword_576E28; // weak int dword_576E2C; // weak __int64 _5773B8_event_timer; // weak -int dword_5773C0; // weak +int _5773C0_unused; // weak int dword_591084; // weak diff -r 11dab247bd72 -r f57bd5c0890c mm7_data.h --- a/mm7_data.h Mon Mar 25 09:49:12 2013 +0600 +++ b/mm7_data.h Mon Mar 25 09:49:21 2013 +0600 @@ -1146,7 +1146,7 @@ extern int dword_576E28; // weak extern int dword_576E2C; // weak extern __int64 _5773B8_event_timer; // weak -extern int dword_5773C0; // weak +extern int _5773C0_unused; // weak extern int dword_591084; // weak @@ -1857,7 +1857,7 @@ void __fastcall sub_44892E_set_faces_bit(int sCogNumber, int bit, int on); void __fastcall ToggleActorGroupFlag(unsigned int uGroupID, unsigned int uFlag, unsigned int bToggle); void __thiscall GameUI_StatusBar_UpdateTimedString(unsigned int bForceHide); // idb -void __thiscall OnTimer(int a1); +void OnTimer(int); void __fastcall sub_448CF4_spawn_monsters(__int16 typeindex, __int16 level, int count, int x, int y, int z, int group, unsigned int uUniqueName); void __fastcall sub_448DF8_cast_spell(int spellnum, int rank, int level, int fromx, int fromy, int fromz, int tox, int toy, int toz); __int16 __fastcall sub_449A49_door_switch_animation(unsigned int uDoorID, int a2); // idb @@ -1969,7 +1969,7 @@ bool __fastcall _46BFFA_check_object_intercept(unsigned int uLayingItemID, signed int a2); void __cdecl check_event_triggers(); int BLV_GetFloorLevel(int x, int y, int z, unsigned int uSectorID, unsigned int *pFaceID); -int __fastcall ODM_GetFloorLevel(int X, signed int Y, int Z, int a4, int *a5, int *a6, int a7); +int __fastcall ODM_GetFloorLevel(int X, signed int Y, int Z, int, int *pOnWater, int *a6, int bWaterWalk); int __fastcall sub_46D8E3(int a1, signed int a2, int a3, int a4); void ODM_GetTerrainNormalAt(int pos_x, int pos_z, Vec3_int_ *out); unsigned int __fastcall sub_46DEF2(signed int a2, unsigned int uLayingItemID); @@ -2169,6 +2169,7 @@ void DamageMonsterFromParty(signed int a1, unsigned int uActorID_Monster, struct Vec3_int_ *pVelocity); int fixpoint_mul(int, int); +int fixpoint_div(int, int); #define ErrD3D(hr) do {extern void ErrHR(HRESULT, const char *, const char *, const char *, int); ErrHR(hr, "Direct3D", __FUNCTION__, __FILE__, __LINE__);} while(0) diff -r 11dab247bd72 -r f57bd5c0890c stru176.h --- a/stru176.h Mon Mar 25 09:49:12 2013 +0600 +++ b/stru176.h Mon Mar 25 09:49:21 2013 +0600 @@ -5,11 +5,11 @@ #pragma pack(push, 1) struct stru176 { - signed __int64 field_0_time; + __int64 next_fire_time; // timer will either fire event at this time (type 2, field_C == 0) __int16 timer_evt_ID; __int16 timer_evt_seq_num; - __int16 field_C; - __int16 field_E; + __int16 time_left_to_fire; + __int16 fire_interval; // or fire on these intervals (type 1) __int16 field_10; __int16 field_12; __int16 field_14;