bool C4Menu::AddItem(C4MenuItem *pNew, const char *szCaption, const char *szCommand, int32_t iCount, C4Object *pObject, const char *szInfoCaption, C4ID idID, const char *szCommand2, bool fOwnValue, int32_t iValue, bool fIsSelectable) { #ifdef DEBUGREC_MENU if (Config.General.DebugRec) if (pObject) { C4RCMenuAdd rc = { pObject ? pObject->Number : -1, iCount, idID, fOwnValue, iValue, fIsSelectable }; AddDbgRec(RCT_MenuAdd, &rc, sizeof(C4RCMenuAdd)); if (szCommand) AddDbgRec(RCT_MenuAddC, szCommand, strlen(szCommand)+1); if (szCommand2) AddDbgRec(RCT_MenuAddC, szCommand2, strlen(szCommand2)+1); } #endif // Add it to the list pClientWindow->AddElement(pNew); // first menuitem is portrait, if it does not have text but a facet if (!ItemCount && (!szCaption || !*szCaption)) fHasPortrait = true; // Item count ItemCount++; // set new item size if (!pClientWindow->IsFrozen()) UpdateElementPositions(); // Init selection if not frozen if (Selection==-1 && fIsSelectable && !pClientWindow->IsFrozen()) SetSelection(ItemCount-1, false, false); // initial progress if (fTextProgressing) pNew->TextDisplayProgress = 0; // adjust scrolling, etc. UpdateScrollBar(); // Success return true; }
bool C4MassMoverSet::Create(int32_t x, int32_t y, bool fExecute) { if (Count == C4MassMoverChunk) return false; if (Config.General.DebugRec) { C4RCMassMover rc; rc.x=x; rc.y=y; AddDbgRec(RCT_MMC, &rc, sizeof(rc)); } int32_t cptr=CreatePtr; do { cptr++; if (cptr>=C4MassMoverChunk) cptr=0; if (Set[cptr].Mat==MNone) { if (!Set[cptr].Init(x,y)) return false; CreatePtr=cptr; if (fExecute) Set[cptr].Execute(); return true; } } while (cptr!=CreatePtr); return false; }
void C4MassMover::Cease() { if (Config.General.DebugRec) { C4RCMassMover rc; rc.x=x; rc.y=y; AddDbgRec(RCT_MMD, &rc, sizeof(rc)); } ::MassMover.Count--; Mat=MNone; }
void C4LArea::DebugRec(class C4Object *pObj, char cMarker) { C4RCArea rc; rc.op = cMarker; rc.obj = pObj ? pObj->Number : -1; rc.x1 = pFirst ? pFirst->x : -1; rc.y1 = pFirst ? pFirst->x /* 2do: y */ : -1; rc.xL = xL; rc.yL = yL; rc.dpitch = dpitch; rc.out = !!pOut; AddDbgRec(RCT_Area, &rc, sizeof(C4RCArea)); }
static void RecordRandom(uint32_t range, uint32_t val) { RandomCount++; if (Config.General.DebugRec) { // next pseudorandom value C4RCRandom rc; rc.Cnt=RandomCount; rc.Range=range; rc.Val=val; AddDbgRec(RCT_Random, &rc, sizeof(rc)); } }
void C4PXS::Deactivate() { #ifdef DEBUGREC_PXS if (Config.General.DebugRec) { C4RCExecPXS rc; rc.x=x; rc.y=y; rc.iMat=Mat; rc.pos = 2; AddDbgRec(RCT_ExecPXS, &rc, sizeof(rc)); } #endif Mat=MNone; ::PXS.Delete(this); }
void C4Shape::Rotate(int32_t iAngle, bool bUpdateVertices) { #ifdef DEBUGREC C4RCRotVtx rc; rc.x = x; rc.y = y; rc.wdt = Wdt; rc.hgt = Hgt; rc.r = iAngle; int32_t i = 0; for (; i < 4; ++i) { rc.VtxX[i] = VtxX[i]; rc.VtxY[i] = VtxY[i]; } AddDbgRec(RCT_RotVtx1, &rc, sizeof(rc)); #endif int32_t cnt, nvtx, nvty, rdia; // int32_t *vtx=VtxX; // int32_t *vty=VtxY; FIXED mtx[4]; FIXED fAngle = itofix(iAngle); if (bUpdateVertices) { // Calculate rotation matrix mtx[0] = Cos(fAngle); mtx[1] = -Sin(fAngle); mtx[2] = -mtx[1]; mtx[3] = mtx[0]; // Rotate vertices for (cnt = 0; cnt < VtxNum; cnt++) { // nvtx= (int32_t) ( mtx[0]*vtx[cnt] + mtx[1]*vty[cnt] ); // nvty= (int32_t) ( mtx[2]*vtx[cnt] + mtx[3]*vty[cnt] ); nvtx = fixtoi(mtx[0] * VtxX[cnt] + mtx[1] * VtxY[cnt]); nvty = fixtoi(mtx[2] * VtxX[cnt] + mtx[3] * VtxY[cnt]); VtxX[cnt] = nvtx; VtxY[cnt] = nvty; } /* This is freaking nuts. I used the int32_t* to shortcut the two int32_t arrays Shape.Vtx_[]. Without modifications to this code, after rotation the x-values of vertex 2 and 4 are screwed to that of vertex 0. Direct use of the array variables instead of the pointers helped. Later in development, again without modification to this code, the same error occured again. I moved back to pointer array shortcut and it worked again. ?! The error occurs after the C4DefCore structure has changed. It must have something to do with struct member alignment. But why does pointer usage vs. array index make a difference? */ } // Enlarge Rect rdia = (int32_t)sqrt(double(x * x + y * y)) + 2; x = -rdia; y = -rdia; Wdt = 2 * rdia; Hgt = 2 * rdia; #ifdef DEBUGREC rc.x = x; rc.y = y; rc.wdt = Wdt; rc.hgt = Hgt; for (i = 0; i < 4; ++i) { rc.VtxX[i] = VtxX[i]; rc.VtxY[i] = VtxY[i]; } AddDbgRec(RCT_RotVtx2, &rc, sizeof(rc)); #endif }
void C4PXS::Execute() { #ifdef DEBUGREC_PXS if (Config.General.DebugRec) { C4RCExecPXS rc; rc.x=x; rc.y=y; rc.iMat=Mat; rc.pos = 0; AddDbgRec(RCT_ExecPXS, &rc, sizeof(rc)); } #endif int32_t inmat; // Safety if (!MatValid(Mat)) { Deactivate(); return; } // Out of bounds if ((x<0) || (x>=::Landscape.GetWidth()) || (y<-10) || (y>=::Landscape.GetHeight())) { Deactivate(); return; } // Material conversion int32_t iX = fixtoi(x), iY = fixtoi(y); inmat=GBackMat(iX,iY); C4MaterialReaction *pReact = ::MaterialMap.GetReactionUnsafe(Mat, inmat); if (pReact && (*pReact->pFunc)(pReact, iX,iY, iX,iY, xdir,ydir, Mat,inmat, meePXSPos, NULL)) { Deactivate(); return; } // Gravity ydir+=GravAccel; if (GBackDensity(iX, iY + 1) < ::MaterialMap.Map[Mat].Density) { // Air speed: Wind plus some random int32_t iWind = Weather.GetWind(iX, iY); C4Real txdir = itofix(iWind, 15) + C4REAL256(Random(1200) - 600); C4Real tydir = C4REAL256(Random(1200) - 600); // Air friction, based on WindDrift. MaxSpeed is ignored. int32_t iWindDrift = std::max(::MaterialMap.Map[Mat].WindDrift - 20, 0); xdir += ((txdir - xdir) * iWindDrift) * WindDrift_Factor; ydir += ((tydir - ydir) * iWindDrift) * WindDrift_Factor; } C4Real ctcox = x + xdir; C4Real ctcoy = y + ydir; int32_t iToX = fixtoi(ctcox), iToY = fixtoi(ctcoy); // In bounds? if (Inside<int32_t>(iToX, 0, ::Landscape.GetWidth()-1) && Inside<int32_t>(iToY, 0, ::Landscape.GetHeight()-1)) // Check path if (::Landscape._PathFree(iX, iY, iToX, iToY)) { x=ctcox; y=ctcoy; return; } // Test path to target position int32_t iX0 = iX, iY0 = iY; bool fStopMovement = false; do { // Step int32_t inX = iX + Sign(iToX - iX), inY = iY + Sign(iToY - iY); // Contact? inmat = GBackMat(inX, inY); C4MaterialReaction *pReact = ::MaterialMap.GetReactionUnsafe(Mat, inmat); if (pReact) { if ((*pReact->pFunc)(pReact, iX,iY, inX,inY, xdir,ydir, Mat,inmat, meePXSMove, &fStopMovement)) { // destructive contact Deactivate(); return; } else { // no destructive contact, but speed or position changed: Stop moving for now if (fStopMovement) { // But keep fractional positions to allow proper movement on moving ground if (iX != iX0) x = itofix(iX); if (iY != iY0) y = itofix(iY); return; } // there was a reaction func, but it didn't do anything - continue movement } } iX = inX; iY = inY; } while (iX != iToX || iY != iToY); // No contact? Free movement x=ctcox; y=ctcoy; #ifdef DEBUGREC_PXS if (Config.General.DebugRec) { C4RCExecPXS rc; rc.x=x; rc.y=y; rc.iMat=Mat; rc.pos = 1; AddDbgRec(RCT_ExecPXS, &rc, sizeof(rc)); } #endif return; }