private void WriteRoomHeader(ZRoom Room) { /* Write room header */ Helpers.Append64(ref Room.RoomData, 0x1600000000000000); /* Sound settings */ Helpers.Append64(ref Room.RoomData, 0x0800000000000000); /* Unknown */ Helpers.Append64(ref Room.RoomData, 0x1200000000000000); /* Skybox modifier */ if (IsOutdoors == true) /* Time settings */ { Helpers.Append64(ref Room.RoomData, 0x10000000FFFF0A00); } else { Helpers.Append64(ref Room.RoomData, 0x10000000FFFF0000); } CmdMeshHeaderOffset = Room.RoomData.Count; Helpers.Append64(ref Room.RoomData, 0x0A00000000000000); /* Mesh header */ /* Objects */ if (Room.ZObjects.Count != 0) { CmdObjectOffset = Room.RoomData.Count; Helpers.Append64(ref Room.RoomData, 0x0B00000000000000); } /* Actors */ if (Room.ZActors.Count != 0) { CmdActorOffset = Room.RoomData.Count; Helpers.Append64(ref Room.RoomData, 0x0100000000000000); } Helpers.Append64(ref Room.RoomData, 0x1400000000000000); /* End marker */ }
public void AddRoom(string Filename) { ZRoom NewRoom = new ZRoom(); NewRoom.ModelFilename = Filename; NewRoom.ModelShortFilename = Path.GetFileNameWithoutExtension(Filename); NewRoom.ObjModel = new ObjFile(Filename); NewRoom.ZObjects = new List <ZUShort>(); NewRoom.ZActors = new List <ZActor>(); NewRoom.InjectOffset = 0x035CF000; NewRoom.GroupSettings.TintAlpha = new uint[NewRoom.ObjModel.Groups.Count]; NewRoom.GroupSettings.TileS = new int[NewRoom.ObjModel.Groups.Count]; NewRoom.GroupSettings.TileT = new int[NewRoom.ObjModel.Groups.Count]; NewRoom.GroupSettings.PolyType = new int[NewRoom.ObjModel.Groups.Count]; NewRoom.GroupSettings.BackfaceCulling = new bool[NewRoom.ObjModel.Groups.Count]; NewRoom.GroupSettings.MultiTexMaterial = new int[NewRoom.ObjModel.Groups.Count]; NewRoom.GroupSettings.ShiftS = new int[NewRoom.ObjModel.Groups.Count]; NewRoom.GroupSettings.ShiftT = new int[NewRoom.ObjModel.Groups.Count]; for (int i = 0; i < NewRoom.ObjModel.Groups.Count; i++) { NewRoom.GroupSettings.TintAlpha[i] = 0xFFFFFFFF; NewRoom.GroupSettings.TileS[i] = GBI.G_TX_WRAP; NewRoom.GroupSettings.TileT[i] = GBI.G_TX_WRAP; NewRoom.GroupSettings.PolyType[i] = 0x0000000000000000; NewRoom.GroupSettings.BackfaceCulling[i] = true; NewRoom.GroupSettings.MultiTexMaterial[i] = -1; NewRoom.GroupSettings.ShiftS[i] = GBI.G_TX_NOLOD; NewRoom.GroupSettings.ShiftT[i] = GBI.G_TX_NOLOD; } _Rooms.Add(NewRoom); }
private void FixRoomHeader(ZRoom Room) { /* Fix room header commands; mesh header... */ if (CmdMeshHeaderOffset != -1) { Helpers.Overwrite32(ref Room.RoomData, CmdMeshHeaderOffset + 4, (uint)(0x03000000 | MeshHeaderOffset)); /* Mesh header */ } /* ...object list... */ if (Room.ZObjects.Count != 0 && CmdObjectOffset != -1) { Helpers.Overwrite32(ref Room.RoomData, CmdObjectOffset, (uint)(0x0B000000 | (Room.ZObjects.Count << 16))); /* Objects */ Helpers.Overwrite32(ref Room.RoomData, CmdObjectOffset + 4, (uint)(0x03000000 | ObjectOffset)); } /* ...actor list */ if (Room.ZActors.Count != 0 && CmdActorOffset != -1) { Helpers.Overwrite32(ref Room.RoomData, CmdActorOffset, (uint)(0x01000000 | (Room.ZActors.Count << 16))); /* Actors */ Helpers.Overwrite32(ref Room.RoomData, CmdActorOffset + 4, (uint)(0x03000000 | ActorOffset)); } if (MeshHeaderOffset != -1) { List <NDisplayList> opaqueLists = Room.DLists.FindAll(delegate(NDisplayList DL) { return((DL.TintAlpha >> 24) == 255); }); List <NDisplayList> translucentLists = Room.DLists.FindAll(delegate(NDisplayList DL) { return((DL.TintAlpha >> 24) != 255); }); int numEntries = Math.Max(opaqueLists.Count, translucentLists.Count); Helpers.Overwrite32(ref Room.RoomData, MeshHeaderOffset, (uint)(0x00000000 | (numEntries << 16))); Helpers.Overwrite32(ref Room.RoomData, MeshHeaderOffset + 4, (uint)(0x03000000 | MeshHeaderOffset + 12)); Helpers.Overwrite32(ref Room.RoomData, MeshHeaderOffset + 8, (uint)(0x03000000 | (MeshHeaderOffset + 12) + (numEntries * 8))); MeshHeaderOffset += 12; for (int i = 0; i < numEntries; i++) { if (i < opaqueLists.Count) { Helpers.Overwrite32(ref Room.RoomData, MeshHeaderOffset, (uint)(0x03000000 | opaqueLists[i].Offset)); } else { Helpers.Overwrite32(ref Room.RoomData, MeshHeaderOffset, 0); } MeshHeaderOffset += 4; if (i < translucentLists.Count) { Helpers.Overwrite32(ref Room.RoomData, MeshHeaderOffset, (uint)(0x03000000 | translucentLists[i].Offset)); } else { Helpers.Overwrite32(ref Room.RoomData, MeshHeaderOffset, 0); } MeshHeaderOffset += 4; } } }
public void ConvertScene(bool ConsecutiveRoomInject, bool ForceRGBATextures) { /* Check if collision model is valid */ if (ColModel == null) { throw new Exception("No collision model defined"); } /* Process rooms... */ for (int i = 0; i < _Rooms.Count; i++) { /* Get current room from list */ ZRoom Room = _Rooms[i]; /* Create new room file, DList offset list and texture list */ Room.RoomData = new List <byte>(); Room.DLists = new List <NDisplayList>(); Textures = new List <NTexture>(); /* Create room header */ WriteRoomHeader(Room); /* Write objects */ if (Room.ZObjects.Count != 0) { ObjectOffset = Room.RoomData.Count; foreach (ZUShort Obj in Room.ZObjects) { Helpers.Append16(ref Room.RoomData, Obj.Value); } AddPadding(ref Room.RoomData, 8); } /* Write actors */ if (Room.ZActors.Count != 0) { ActorOffset = Room.RoomData.Count; foreach (ZActor Actor in Room.ZActors) { Helpers.Append16(ref Room.RoomData, Actor.Number); Helpers.Append16(ref Room.RoomData, (ushort)Actor.XPos); Helpers.Append16(ref Room.RoomData, (ushort)Actor.YPos); Helpers.Append16(ref Room.RoomData, (ushort)Actor.ZPos); Helpers.Append16(ref Room.RoomData, (ushort)Actor.XRot); Helpers.Append16(ref Room.RoomData, (ushort)Actor.YRot); Helpers.Append16(ref Room.RoomData, (ushort)Actor.ZRot); Helpers.Append16(ref Room.RoomData, Actor.Variable); } AddPadding(ref Room.RoomData, 8); } /* Prepare dummy mesh header */ MeshHeaderOffset = Room.MeshHeaderOffset = Room.RoomData.Count; Helpers.Append32(ref Room.RoomData, 0); /* Mesh type X, Y meshes */ Helpers.Append32(ref Room.RoomData, 0); /* Start address */ Helpers.Append32(ref Room.RoomData, 0); /* End address */ for (int j = 0; j < Room.ObjModel.Groups.Count; j++) { Helpers.Append64(ref Room.RoomData, 0); Helpers.Append32(ref Room.RoomData, 0); /* Display List offset 1 */ Helpers.Append32(ref Room.RoomData, 0); /* Display List offset 2 */ } AddPadding(ref Room.RoomData, 8); /* Create textures */ for (int M = 0; M < Room.ObjModel.Materials.Count; M++) { /* Get material & force RGBA default */ ObjFile.Material Mat = Room.ObjModel.Materials[M]; Mat.ForceRGBA = ForceRGBATextures; /* ---VERY kludgy RGBA forcing code--- */ for (int x = 0; x < Room.ObjModel.Groups.Count; x++) { /* If group has multitex material number... */ if (Room.ObjModel.Groups[x].MultiTexMaterial != -1) { /* Turn force RGBA ON for multitex material */ Room.ObjModel.Materials[Room.ObjModel.Groups[x].MultiTexMaterial].ForceRGBA = true; /* Scan group's triangles for current material name... */ for (int y = 0; y < Room.ObjModel.Groups[x].Triangles.Count; y++) { if (Room.ObjModel.Groups[x].Triangles[y].MaterialName == Mat.Name) { /* Turn force RGBA ON for current material */ Mat.ForceRGBA = true; goto Cont; } } } } /* Continue here... */ Cont: if (Mat.TexImage == null) { continue; } /* Create new texture, convert current material */ NTexture Texture = new NTexture(); Texture.Convert(Mat); /* Add current offset to texture offset list */ Texture.TexOffset = ((uint)Room.RoomData.Count); /* Write converted data to room file */ Room.RoomData.AddRange(Texture.Data); /* See if we've got a CI-format texture... */ int Format = ((Texture.Type & 0xE0) >> 5); #if DEBUG Console.WriteLine("Texture format N64: " + Format.ToString("X2")); #endif if (Format == GBI.G_IM_FMT_CI) { /* If it's CI, add current offset to palette offset list */ Texture.PalOffset = ((uint)Room.RoomData.Count); /* Write palette data to room file */ Room.RoomData.AddRange(Texture.Palette); } else { /* Add dummy entry to palette offset list */ Texture.PalOffset = Dummy; } Textures.Add(Texture); } /* Create Display Lists */ for (int j = 0; j < Room.ObjModel.Groups.Count; j++) { NDisplayList DList = new NDisplayList(Scale, Room.ObjModel.Groups[j].TintAlpha, 1.0f, IsOutdoors, Room.ObjModel.Groups[j].BackfaceCulling); DList.Convert(Room.ObjModel, j, Textures, (uint)Room.RoomData.Count); if (DList.Data != null) { Room.RoomData.AddRange(DList.Data); } Room.DLists.Add(DList); } /* Fix room header and add missing data */ FixRoomHeader(Room); /* Add some padding for good measure */ AddPadding(ref Room.RoomData, 0x1000); /* Store room data length */ Room.FullDataLength = Room.RoomData.ToArray().Length; /* Put modified room info back into list */ _Rooms[i] = Room; } /* Create new scene file */ SceneData = new List <byte>(); /* Write scene header */ Helpers.Append64(ref SceneData, (ulong)(0x1502000000000000 | Music)); /* Sound settings */ CmdMapListOffset = SceneData.Count; Helpers.Append64(ref SceneData, 0x0400000000000000); /* Map list */ CmdTransitionsOffset = SceneData.Count; Helpers.Append64(ref SceneData, 0x0E00000000000000); /* Transition list */ Helpers.Append64(ref SceneData, 0x1900000000000003); /* Cutscenes */ CmdCollisionOffset = SceneData.Count; Helpers.Append64(ref SceneData, 0x0300000000000000); /* Collision header */ CmdEntranceListOffset = SceneData.Count; Helpers.Append64(ref SceneData, 0x0600000000000000); /* Entrance index */ if (IsOutdoors == true) /* Special objects */ { Helpers.Append64(ref SceneData, 0x0701000000000002); } else { Helpers.Append64(ref SceneData, 0x0702000000000003); } CmdSpawnPointOffset = SceneData.Count; Helpers.Append64(ref SceneData, 0x0000000000000000); /* Spawn point list */ if (IsOutdoors == true) /* Skybox / lighting settings */ { Helpers.Append64(ref SceneData, 0x1100000001000000); } else { Helpers.Append64(ref SceneData, 0x1100000000000100); } CmdExitListOffset = SceneData.Count; Helpers.Append64(ref SceneData, 0x1300000000000000); /* Exit list */ CmdEnvironmentsOffset = SceneData.Count; Helpers.Append64(ref SceneData, 0x0F00000000000000); /* Environments */ Helpers.Append64(ref SceneData, 0x1400000000000000); /* End marker */ /* Fix scene header; map list ... */ Helpers.Overwrite32(ref SceneData, CmdMapListOffset, (uint)(0x04000000 | (_Rooms.Count << 16))); Helpers.Overwrite32(ref SceneData, CmdMapListOffset + 4, (uint)(0x02000000 | SceneData.Count)); if (ConsecutiveRoomInject == true) { int RoomInjectOffset = _Rooms[0].InjectOffset; foreach (ZRoom Room in _Rooms) { Helpers.Append32(ref SceneData, (uint)RoomInjectOffset); Helpers.Append32(ref SceneData, (uint)(RoomInjectOffset + Room.FullDataLength)); RoomInjectOffset += Room.FullDataLength; } } else { foreach (ZRoom Room in _Rooms) { Helpers.Append32(ref SceneData, (uint)Room.InjectOffset); Helpers.Append32(ref SceneData, (uint)(Room.InjectOffset + Room.FullDataLength)); } } AddPadding(ref SceneData, 8); /* ... transition list ... */ Helpers.Overwrite32(ref SceneData, CmdTransitionsOffset, (uint)(0x0E000000 | (Transitions.Count << 16))); Helpers.Overwrite32(ref SceneData, CmdTransitionsOffset + 4, (uint)(0x02000000 | SceneData.Count)); foreach (ZActor Trans in Transitions) { SceneData.Add(Trans.FrontSwitchTo); SceneData.Add(Trans.FrontCamera); SceneData.Add(Trans.BackSwitchTo); SceneData.Add(Trans.BackCamera); Helpers.Append16(ref SceneData, Trans.Number); Helpers.Append16(ref SceneData, (ushort)Trans.XPos); Helpers.Append16(ref SceneData, (ushort)Trans.YPos); Helpers.Append16(ref SceneData, (ushort)Trans.ZPos); Helpers.Append16(ref SceneData, (ushort)Trans.YRot); Helpers.Append16(ref SceneData, Trans.Variable); } AddPadding(ref SceneData, 8); /* ... exit list ... */ Helpers.Overwrite32(ref SceneData, CmdExitListOffset + 4, (uint)(0x02000000 | SceneData.Count)); foreach (ZUShort Exit in ExitList) { Helpers.Append16(ref SceneData, Exit.Value); } AddPadding(ref SceneData, 8); /* ... spawn point list ... */ Helpers.Overwrite32(ref SceneData, CmdSpawnPointOffset, (uint)(0x00000000 | (SpawnPoints.Count << 16))); Helpers.Overwrite32(ref SceneData, CmdSpawnPointOffset + 4, (uint)(0x02000000 | SceneData.Count)); foreach (ZActor Spawn in SpawnPoints) { Helpers.Append16(ref SceneData, Spawn.Number); Helpers.Append16(ref SceneData, (ushort)Spawn.XPos); Helpers.Append16(ref SceneData, (ushort)Spawn.YPos); Helpers.Append16(ref SceneData, (ushort)Spawn.ZPos); Helpers.Append16(ref SceneData, (ushort)Spawn.XRot); Helpers.Append16(ref SceneData, (ushort)Spawn.YRot); Helpers.Append16(ref SceneData, (ushort)Spawn.ZRot); Helpers.Append16(ref SceneData, Spawn.Variable); } AddPadding(ref SceneData, 8); /* ... environments ... */ Helpers.Overwrite32(ref SceneData, CmdEnvironmentsOffset, (uint)(0x0F000000 | (Environments.Count << 16))); Helpers.Overwrite32(ref SceneData, CmdEnvironmentsOffset + 4, (uint)(0x02000000 | SceneData.Count)); foreach (ZEnvironment Env in Environments) { Helpers.Append48(ref SceneData, (ulong)(Env.C1C.ToArgb() & 0xFFFFFF)); Helpers.Append48(ref SceneData, (ulong)(Env.C2C.ToArgb() & 0xFFFFFF)); Helpers.Append48(ref SceneData, (ulong)(Env.C3C.ToArgb() & 0xFFFFFF)); Helpers.Append48(ref SceneData, (ulong)(Env.C4C.ToArgb() & 0xFFFFFF)); Helpers.Append48(ref SceneData, (ulong)(Env.C5C.ToArgb() & 0xFFFFFF)); Helpers.Append48(ref SceneData, (ulong)(Env.FogColorC.ToArgb() & 0xFFFFFF)); Helpers.Append16(ref SceneData, Env.FogDistance); Helpers.Append16(ref SceneData, Env.DrawDistance); } AddPadding(ref SceneData, 8); /* ... entrance list ... */ Helpers.Overwrite32(ref SceneData, CmdEntranceListOffset + 4, (uint)(0x02000000 | SceneData.Count)); Helpers.Append16(ref SceneData, 0x0000); /* Map 0, spawn point 0 */ AddPadding(ref SceneData, 8); /* ... collision */ WriteSceneCollision(); }
public void AddRoom(string Filename) { ZRoom NewRoom = new ZRoom(); NewRoom.ModelFilename = Filename; NewRoom.ModelShortFilename = Path.GetFileNameWithoutExtension(Filename); NewRoom.ObjModel = new ObjFile(Filename); NewRoom.ZObjects = new List<ZUShort>(); NewRoom.ZActors = new List<ZActor>(); NewRoom.InjectOffset = 0x035CF000; NewRoom.GroupSettings.TintAlpha = new uint[NewRoom.ObjModel.Groups.Count]; NewRoom.GroupSettings.TileS = new int[NewRoom.ObjModel.Groups.Count]; NewRoom.GroupSettings.TileT = new int[NewRoom.ObjModel.Groups.Count]; NewRoom.GroupSettings.PolyType = new int[NewRoom.ObjModel.Groups.Count]; NewRoom.GroupSettings.BackfaceCulling = new bool[NewRoom.ObjModel.Groups.Count]; NewRoom.GroupSettings.MultiTexMaterial = new int[NewRoom.ObjModel.Groups.Count]; NewRoom.GroupSettings.ShiftS = new int[NewRoom.ObjModel.Groups.Count]; NewRoom.GroupSettings.ShiftT = new int[NewRoom.ObjModel.Groups.Count]; for (int i = 0; i < NewRoom.ObjModel.Groups.Count; i++) { NewRoom.GroupSettings.TintAlpha[i] = 0xFFFFFFFF; NewRoom.GroupSettings.TileS[i] = GBI.G_TX_WRAP; NewRoom.GroupSettings.TileT[i] = GBI.G_TX_WRAP; NewRoom.GroupSettings.PolyType[i] = 0x0000000000000000; NewRoom.GroupSettings.BackfaceCulling[i] = true; NewRoom.GroupSettings.MultiTexMaterial[i] = -1; NewRoom.GroupSettings.ShiftS[i] = GBI.G_TX_NOLOD; NewRoom.GroupSettings.ShiftT[i] = GBI.G_TX_NOLOD; } _Rooms.Add(NewRoom); }
private void WriteRoomHeader(ZRoom Room) { /* Write room header */ Helpers.Append64(ref Room.RoomData, 0x1600000000000000); /* Sound settings */ Helpers.Append64(ref Room.RoomData, 0x0800000000000000); /* Unknown */ Helpers.Append64(ref Room.RoomData, 0x1200000000000000); /* Skybox modifier */ if (IsOutdoors == true) /* Time settings */ Helpers.Append64(ref Room.RoomData, 0x10000000FFFF0A00); else Helpers.Append64(ref Room.RoomData, 0x10000000FFFF0000); CmdMeshHeaderOffset = Room.RoomData.Count; Helpers.Append64(ref Room.RoomData, 0x0A00000000000000); /* Mesh header */ /* Objects */ if (Room.ZObjects.Count != 0) { CmdObjectOffset = Room.RoomData.Count; Helpers.Append64(ref Room.RoomData, 0x0B00000000000000); } /* Actors */ if (Room.ZActors.Count != 0) { CmdActorOffset = Room.RoomData.Count; Helpers.Append64(ref Room.RoomData, 0x0100000000000000); } Helpers.Append64(ref Room.RoomData, 0x1400000000000000); /* End marker */ }
private void FixRoomHeader(ZRoom Room) { /* Fix room header commands; mesh header... */ if (CmdMeshHeaderOffset != -1) Helpers.Overwrite32(ref Room.RoomData, CmdMeshHeaderOffset + 4, (uint)(0x03000000 | MeshHeaderOffset)); /* Mesh header */ /* ...object list... */ if (Room.ZObjects.Count != 0 && CmdObjectOffset != -1) { Helpers.Overwrite32(ref Room.RoomData, CmdObjectOffset, (uint)(0x0B000000 | (Room.ZObjects.Count << 16))); /* Objects */ Helpers.Overwrite32(ref Room.RoomData, CmdObjectOffset + 4, (uint)(0x03000000 | ObjectOffset)); } /* ...actor list */ if (Room.ZActors.Count != 0 && CmdActorOffset != -1) { Helpers.Overwrite32(ref Room.RoomData, CmdActorOffset, (uint)(0x01000000 | (Room.ZActors.Count << 16))); /* Actors */ Helpers.Overwrite32(ref Room.RoomData, CmdActorOffset + 4, (uint)(0x03000000 | ActorOffset)); } if (MeshHeaderOffset != -1) { List<NDisplayList> opaqueLists = Room.DLists.FindAll(delegate(NDisplayList DL) { return (DL.TintAlpha >> 24) == 255; }); List<NDisplayList> translucentLists = Room.DLists.FindAll(delegate(NDisplayList DL) { return (DL.TintAlpha >> 24) != 255; }); int numEntries = Math.Max(opaqueLists.Count, translucentLists.Count); Helpers.Overwrite32(ref Room.RoomData, MeshHeaderOffset, (uint)(0x00000000 | (numEntries << 16))); Helpers.Overwrite32(ref Room.RoomData, MeshHeaderOffset + 4, (uint)(0x03000000 | MeshHeaderOffset + 12)); Helpers.Overwrite32(ref Room.RoomData, MeshHeaderOffset + 8, (uint)(0x03000000 | (MeshHeaderOffset + 12) + (numEntries * 8))); MeshHeaderOffset += 12; for (int i = 0; i < numEntries; i++) { if (i < opaqueLists.Count) Helpers.Overwrite32(ref Room.RoomData, MeshHeaderOffset, (uint)(0x03000000 | opaqueLists[i].Offset)); else Helpers.Overwrite32(ref Room.RoomData, MeshHeaderOffset, 0); MeshHeaderOffset += 4; if (i < translucentLists.Count) Helpers.Overwrite32(ref Room.RoomData, MeshHeaderOffset, (uint)(0x03000000 | translucentLists[i].Offset)); else Helpers.Overwrite32(ref Room.RoomData, MeshHeaderOffset, 0); MeshHeaderOffset += 4; } } }