protected wshort ReadS16AndAdvance(ref uint addr) { wshort retval = Mem.ReadS16(addr); addr += 2; return(retval); }
private void Draw3DHud() { Obj3D curObj; uint Addr = ReadPtr(Addr3D.ObjLLHead); while (Addr != 0) { ReadObj3D(Addr, out curObj); Obj3DType type = _3DTypeProvider.GetType(curObj.PtrMainFunc); int X, Y, Z; GetEcco3DScreenCoords(curObj, out X, out Y, out Z); int radius, width, height, depth = height = width = 0; switch (type) { case Obj3DType.Player: DrawBoxMWH(X, Y, 1, 1, Color.Orange); DrawBoxMWH(X, Z, 1, 1, Color.Red); break; case Obj3DType.Shell: case Obj3DType.Eagle: DrawBoxMWH(X, Y, 1, 1, Color.Lime, 0); DrawBoxMWH(X, Z, 1, 1, Color.Blue, 0); break; case Obj3DType.PoisonBubble: depth = 0x10; radius = width = 8; DrawOct(X, Y, radius, Color.Lime); DrawBoxMWH(X, Z, width, depth, Color.Blue); DrawBoxMWH(X, Y, 1, 1, Color.Lime, 0); DrawBoxMWH(X, Z, 1, 1, Color.Blue, 0); break; case Obj3DType.Ring: depth = 8; if (_player3D.ZVel < 0x1800) { depth = 4; } radius = 32; width = radius; DrawOct(X, Y, radius, (curObj.Mode == 0) ? Color.Orange : Color.Gray); DrawBoxMWH(X, Z, width, depth, Color.Red); DrawBoxMWH(X, Y, 1, 1, Color.Orange, 0); DrawBoxMWH(X, Z, 1, 1, Color.Red, 0); StatusText($" Ring X: {curObj.XPos / 4096.0,10:0.000000} Y: {curObj.YPos / 4096.0,10:0.000000} Z: {curObj.ZPos / 2048.0,10:0.000000} State: {curObj.State}", Color.Green); break; case Obj3DType.Vine: // Vine collisions are based on draw position, which is a f*****g pain in the ass to calculate { int Xvel = (curObj.XUnk - curObj.XPos); int Zvel = (curObj.ZUnk - curObj.ZPos); int dx = Mem.ReadS32(Addr3D.CamX) - Mem.ReadS32(0xFFD5C8) >> 3; int dy = Mem.ReadS32(Addr3D.CamY) - Mem.ReadS32(0xFFD5D0); dy = (dy >> 4) - (dy >> 6); int dz = Mem.ReadS32(Addr3D.CamZ) - Mem.ReadS32(0xFFD5CC); var chargeCount = _player3D.ChargeCtr; if (chargeCount == 0) { dz >>= 2; } else if ((chargeCount > 0x20) || (chargeCount <= 0x10)) { dz >>= 3; } else if (chargeCount > 0x10) { dz >>= 4; } if (curObj.AccelCounter == 0) { Xvel >>= 0xA; Zvel >>= 9; } else { Xvel >>= 9; Zvel >>= 0xA; } Xvel += curObj.XVel; Zvel += curObj.ZVel; int Zpos = (curObj.ZOrig + dz - Mem.ReadS32(Addr3D.CamZ)) >> 0xB; if ((Zpos < 0x600) && (Zpos > 0)) { Zpos += 0x20; int Xcur, Xmax, Ycur, Ymax; int Zpos2 = (curObj.ZPos + Zvel + dz - Mem.ReadS32(Addr3D.CamZ)) >> 0xB; Zpos2 = Math.Max(Zpos2 + 0x20, 1); if (curObj.Mode != 0) { int Xmid = curObj.XPos + dx + Xvel - Mem.ReadS32(Addr3D.CamX); if (Math.Abs(Xmid) > 0x400000) { continue; } int Xpos = curObj.XOrig + dx - Mem.ReadS32(Addr3D.CamX); if (Math.Abs(Xpos) > 0x400000) { continue; } Xcur = (Xmid << 2) / Zpos2 + (Xmid >> 5) + 0xA000 + (Xmid >> 5); Xmax = (Xpos << 2) / Zpos + (Xpos >> 5) + 0xA000 + (Xpos >> 5); } else { Xcur = 0; Xmax = 256; } int Ymid = Mem.ReadS32(Addr3D.CamY) + dy - curObj.YPos; Ycur = ((Ymid << 3) / Zpos2) + 0x6000; int Ypos = Mem.ReadS32(Addr3D.CamY) + dy - curObj.YOrig; Ymax = ((Ypos << 3) / Zpos) + 0x6000; dx = Xmax - Xcur; dy = Ymax - Ycur; wshort ang = Ecco2Asin(dx, dy); Xcur += Mem.ReadS8(0x2CC8 + ang) << 6; Ycur += Mem.ReadS8(0x2BC8 + ang) << 6; int rad = Math.Max(((OctRad(dx, dy) >> 8) + 0x1F) >> 5, 1); dx /= rad; dy /= rad; int Zmid = (curObj.ZPos + curObj.ZOrig) >> 1; Zmid >>= 0xC; Zmid = 112 + _top - (Zmid - Cam3D.Z); do { rad--; DrawRhomb((Xcur >> 8) + _left, (Ycur >> 8) + _top, 8, Color.Lime); DrawBoxMWH((Xcur >> 8) + _left, Zmid, 8, 0x10, Color.Blue); Xcur += dx; Ycur += dy; } while (rad >= 0); DrawBoxMWH((Mem.ReadS32(_player3D.ScreenX) >> 8) + _left, (_player3D.ScreenY >> 8) + _top, 1, 1, Color.Lime, 0); } } break; case Obj3DType.Shark: case Obj3DType.JellyFish: width = (curObj.Width >> 0xC); height = (curObj.Height >> 0xC); depth = (curObj.Depth >> 0xC); DrawBoxMWH(X, Y, width, height, Color.Lime); DrawBoxMWH(X, Z, width, depth, Color.Blue); DrawBoxMWH(X, Y, 1, 1, Color.Lime, 0); DrawBoxMWH(X, Z, 1, 1, Color.Blue, 0); break; case Obj3DType.SonarBlast: DrawOct(X, Y, 48, Color.Orange); DrawOct(X, Y, 32, Color.Lime); DrawBoxMWH(X, Z, 32, 32, Color.Blue); DrawBoxMWH(X, Y, 1, 1, Color.Lime, 0); DrawBoxMWH(X, Z, 1, 1, Color.Blue, 0); break; case Obj3DType.HomingBubble: DrawOct(X, Y, 32, Color.Lime); DrawBoxMWH(X, Z, 32, 32, Color.Blue); DrawBoxMWH(X, Y, 1, 1, Color.Lime, 0); DrawBoxMWH(X, Z, 1, 1, Color.Blue, 0); break; case Obj3DType.GfxBubble1: case Obj3DType.GfxBubble2: case Obj3DType.GfxSplash: break; default: DrawBoxMWH(X, Y, 1, 1, Color.Lime, 0); DrawBoxMWH(X, Z, 1, 1, Color.Blue, 0); PutText(curObj.PtrMainFunc.ToString("X8"), X, Y - 4, 1, 1, -1, -9, Color.White, Color.Blue); PutText(Addr.ToString("X8"), X, Y + 4, 1, 9, -1, -1, Color.White, Color.Blue); break; } Addr = curObj.PtrNext; } }