/// <summary> /// Load a GAT file /// </summary> /// <param name="data">GAT file data</param> public static GAT Load(MemoryStreamReader data) { string header = data.ReadBinaryString(4); //check for valid gat file if (!string.Equals(header, GAT.Header)) { throw new Exception("AltitudeLoader.Load: Header (" + header + ") is not \"GRAT\""); } //load parameters string version = Convert.ToString(data.ReadByte()); string subversion = Convert.ToString(data.ReadByte()); version += "." + subversion; uint width = data.ReadUInt(); uint height = data.ReadUInt(); GAT.Cell[] cells = new GAT.Cell[width * height]; //load the cells for (int i = 0; i < width * height; i++) { Vector4 heights = new Vector4(); heights[0] = data.ReadFloat() * 0.2f; // height 1 heights[1] = data.ReadFloat() * 0.2f; // height 2 heights[2] = data.ReadFloat() * 0.2f; // height 3 heights[3] = data.ReadFloat() * 0.2f; // height 4 cells[i].Heights = heights; cells[i].type = GAT.TYPE_TABLE[data.ReadUInt()]; // type } //exports return(new GAT(width, height, cells, version)); }
public static GND Load(MemoryStreamReader data) { string header = data.ReadBinaryString(4); if (!string.Equals(header, GND.Header)) { throw new Exception("GroundLoader.Load: Header (" + header + ") is not \"GRGN\""); } string version = Convert.ToString(data.ReadByte()); string subversion = Convert.ToString(data.ReadByte()); version += "." + subversion; GND gnd = new GND(version); gnd.width = data.ReadUInt(); gnd.height = data.ReadUInt(); gnd.zoom = data.ReadFloat(); ParseTextures(gnd, data); ParseLightmaps(gnd, data); gnd.tiles = ParseTiles(gnd, data); gnd.surfaces = ParseSurfaces(gnd, data); return(gnd); }
private static GND.Surface[] ParseSurfaces(GND gnd, MemoryStreamReader data) { var count = gnd.width * gnd.height; GND.Surface[] surfaces = new GND.Surface[count]; for (int i = 0; i < count; i++) { var surface = surfaces[i] = new GND.Surface(); surface.height = new Vector4(data.ReadFloat() / 5, data.ReadFloat() / 5, data.ReadFloat() / 5, data.ReadFloat() / 5); surface.tileUp = data.ReadInt(); surface.tileFront = data.ReadInt(); surface.tileRight = data.ReadInt(); } return(surfaces); }
public static ACT Load(MemoryStreamReader data) { string header = data.ReadBinaryString(2); if (!header.Equals(ACT.Header)) { throw new Exception("ActionLoader.Load: Header \"" + header + "\" is not \"AC\""); } string subversion = Convert.ToString(data.ReadByte()); string version = Convert.ToString(data.ReadByte()); version += "." + subversion; double dversion = double.Parse(version, CultureInfo.InvariantCulture); ACT act = new ACT(); act.version = version; ReadActions(act, data); if (dversion >= 2.1) { //sounds var count = data.ReadInt(); act.sounds = new string[count]; for (int i = 0; i < count; i++) { act.sounds[i] = data.ReadBinaryString(40); } //delay if (dversion >= 2.2) { for (int i = 0; i < act.actions.Length; i++) { act.actions[i].delay = data.ReadFloat() * 25; } } } return(act); }
private static GND.Tile[] ParseTiles(GND gnd, MemoryStreamReader data) { uint count = data.ReadUInt(); GND.Tile[] tiles = new GND.Tile[count]; var ATLAS_COLS = Math.Round(Math.Sqrt(gnd.textures.Length)); var ATLAS_ROWS = Math.Ceiling(Math.Sqrt(gnd.textures.Length)); var ATLAS_WIDTH = Math.Pow(2, Math.Ceiling(Math.Log(ATLAS_COLS * 258) / Math.Log(2))); var ATLAS_HEIGHT = Math.Pow(2, Math.Ceiling(Math.Log(ATLAS_ROWS * 258) / Math.Log(2))); var ATLAS_FACTOR_U = ATLAS_COLS * 258 / ATLAS_WIDTH; var ATLAS_FACTOR_V = ATLAS_ROWS * 258 / ATLAS_HEIGHT; var ATLAS_PX_U = 1 / 258f; var ATLAS_PX_V = 1 / 258f; for (int i = 0; i < count; i++) { var tile = tiles[i] = new GND.Tile(); tile.textureStart = new Vector4(data.ReadFloat(), data.ReadFloat(), data.ReadFloat(), data.ReadFloat()); tile.textureEnd = new Vector4(data.ReadFloat(), data.ReadFloat(), data.ReadFloat(), data.ReadFloat()); tile.texture = data.ReadUShort(); tile.light = data.ReadUShort(); var r = (byte)data.ReadByte(); var g = (byte)data.ReadByte(); var b = (byte)data.ReadByte(); var a = (byte)data.ReadByte(); tile.color = new byte[] { r, g, b, a }; tile.texture = (ushort)gnd.textureLookupList[tile.texture]; var start = tile.texture % ATLAS_COLS; var end = Math.Floor(tile.texture / ATLAS_COLS); for (int j = 0; j < 4; j++) { tile.textureStart[j] = (float)((start + tile.textureStart[j] * (1 - ATLAS_PX_U * 2) + ATLAS_PX_U) * ATLAS_FACTOR_U / ATLAS_COLS); tile.textureEnd[j] = (float)((end + tile.textureEnd[j] * (1 - ATLAS_PX_V * 2) + ATLAS_PX_V) * ATLAS_FACTOR_V / ATLAS_ROWS); } } return(tiles); }
private static ACT.Frame ReadLayers(ACT act, MemoryStreamReader data) { var count = data.ReadUInt(); var layers = new ACT.Layer[count]; var version = double.Parse(act.version, CultureInfo.InvariantCulture); for (int i = 0; i < count; i++) { var layer = layers[i] = new ACT.Layer() { pos = new Vector2Int(data.ReadInt(), data.ReadInt()), index = data.ReadInt(), isMirror = data.ReadInt() != 0, scale = Vector2.one, color = Color.white }; // RoRebuild checks if only if it's greater if (version > 2.0) { layer.color[0] = data.ReadByte() / 255f; //r layer.color[1] = data.ReadByte() / 255f; //g layer.color[2] = data.ReadByte() / 255f; //b layer.color[3] = data.ReadByte() / 255f; //a layer.scale[0] = data.ReadFloat(); layer.scale[1] = version <= 2.3 ? layer.scale[0] : data.ReadFloat(); layer.angle = data.ReadInt(); layer.sprType = data.ReadInt(); if (version >= 2.5) { layer.width = data.ReadInt(); layer.height = data.ReadInt(); } } } var soundId = version >= 2.0 ? data.ReadInt() : -1; Vector2Int[] pos = null; if (version >= 2.3) { pos = new Vector2Int[data.ReadInt()]; for (int i = 0; i < pos.Length; i++) { data.Seek(4, System.IO.SeekOrigin.Current); pos[i] = new Vector2Int(data.ReadInt(), data.ReadInt()); data.Seek(4, System.IO.SeekOrigin.Current); } } return(new ACT.Frame() { layers = layers.Where(t => t.index >= 0).ToArray(), soundId = soundId, pos = pos }); }
public static STR Load(MemoryStreamReader data, string path) { var header = data.ReadBinaryString(4); if (!header.Equals(STR.Header)) { throw new Exception("EffectLoader.Load: Header (" + header + ") is not \"STRM\""); } var version = data.ReadUInt(); if (version != 0x94) { throw new Exception("EffectLoader.Load: Unsupported STR version (v" + version + ")"); } STR str = new STR(); str.version = version; str.fps = data.ReadUInt(); str.maxKey = data.ReadUInt(); var layerCount = data.ReadUInt(); data.Seek(16, System.IO.SeekOrigin.Current); //read layers str.layers = new STR.Layer[layerCount]; for (uint i = 0; i < layerCount; i++) { STR.Layer layer = str.layers[i] = new STR.Layer(); //read texture filenames var textureCount = data.ReadInt(); layer.textures = new Texture2D[textureCount]; layer.texturesIds = new List <int>(); for (int j = 0; j < textureCount; j++) { var tex = data.ReadBinaryString(128); var texture = FileManager.Load(path + "/" + tex) as Texture2D; layer.textures[j] = texture; if (!textureNames.Contains(tex)) { layer.texturesIds.Add(textureNames.Count); textureIdLookup.Add(tex, textureNames.Count); textureNames.Add(tex); textures.Add(texture); } else { layer.texturesIds.Add(textureIdLookup[tex]); } } //read animations var animCount = data.ReadInt(); layer.animations = new STR.Animation[animCount]; for (int j = 0; j < animCount; j++) { var entry = new STR.Animation() { frame = data.ReadInt(), type = data.ReadUInt(), position = new Vector2(data.ReadFloat(), data.ReadFloat()) }; var uv = new float[] { data.ReadFloat(), data.ReadFloat(), data.ReadFloat(), data.ReadFloat(), data.ReadFloat(), data.ReadFloat(), data.ReadFloat(), data.ReadFloat() }; var xy = new float[] { data.ReadFloat(), data.ReadFloat(), data.ReadFloat(), data.ReadFloat(), data.ReadFloat(), data.ReadFloat(), data.ReadFloat(), data.ReadFloat() }; entry.uv = new Vector2[4]; entry.uv[0] = new Vector2(0, 0); entry.uv[1] = new Vector2(1, 0); entry.uv[2] = new Vector2(0, 1); entry.uv[3] = new Vector2(1, 1); entry.xy = new Vector2[4]; entry.xy[0] = new Vector2(xy[0], -xy[4]); entry.xy[1] = new Vector2(xy[1], -xy[5]); entry.xy[2] = new Vector2(xy[3], -xy[7]); entry.xy[3] = new Vector2(xy[2], -xy[6]); entry.animFrame = data.ReadFloat(); entry.animType = data.ReadUInt(); entry.delay = data.ReadFloat(); entry.angle = data.ReadFloat() / (1024f / 360f); entry.color = new Color(data.ReadFloat() / 255, data.ReadFloat() / 255, data.ReadFloat() / 255, data.ReadFloat() / 255); entry.srcAlpha = data.ReadUInt(); entry.destAlpha = data.ReadUInt(); entry.mtPreset = data.ReadUInt(); layer.animations[j] = entry; } } return(MakeAtlas(str, path)); }
public static RSM Load(MemoryStreamReader data) { var header = data.ReadBinaryString(4); if (header != RSM.Header) { throw new Exception("ModelLoader.Load: Header (" + header + ") is not \"GRSM\""); } RSM rsm = new RSM(); //read infos string version = Convert.ToString(data.ReadByte()); string subversion = Convert.ToString(data.ReadByte()); version += "." + subversion; double dversion = double.Parse(version, CultureInfo.InvariantCulture); rsm.version = version; rsm.animLen = data.ReadInt(); rsm.shadeType = (RSM.SHADING)data.ReadInt(); rsm.alpha = dversion >= 1.4 ? data.ReadByte() / 255f : 1; data.Seek(16, System.IO.SeekOrigin.Current); //read textures int textureCount = data.ReadInt(); rsm.textures = new string[textureCount]; for (int i = 0; i < textureCount; ++i) { rsm.textures[i] = data.ReadBinaryString(40); } //read nodes (meshes) rsm.name = data.ReadBinaryString(40); int nodeCount = data.ReadInt(); rsm.nodes = new RSM.Node[nodeCount]; for (int i = 0; i < nodeCount; ++i) { var node = rsm.nodes[i] = LoadNode(rsm, data, dversion); if (string.Equals(node.name, rsm.name)) { rsm.mainNode = node; } } //fallback for non defined main node if (rsm.mainNode == null) { rsm.mainNode = rsm.nodes[0]; } //read poskeyframes if (dversion < 1.5) { int count = data.ReadInt(); rsm.posKeyframes = new RSM.PositionKeyframe[count]; for (int i = 0; i < count; ++i) { rsm.posKeyframes[i] = new RSM.PositionKeyframe() { frame = data.ReadInt(), p = new Vector3(data.ReadFloat(), data.ReadFloat(), data.ReadFloat()) }; } } else { rsm.posKeyframes = new RSM.PositionKeyframe[0]; } //read volume box short vbCount = (short)data.ReadInt(); rsm.volumeBoxes = new RSM.VolumeBox[vbCount]; for (int i = 0; i < vbCount; ++i) { rsm.volumeBoxes[i] = new RSM.VolumeBox() { size = new Vector3(data.ReadFloat(), data.ReadFloat(), data.ReadFloat()), pos = new Vector3(data.ReadFloat(), data.ReadFloat(), data.ReadFloat()), rot = new Vector3(data.ReadFloat(), data.ReadFloat(), data.ReadFloat()), flag = dversion >= 1.3 ? data.ReadInt() : 0 }; } rsm.instances = new List <RSW.ModelDescriptor>(); rsm.box = new RSM.Box(); CalcBoundingBox(rsm); return(rsm); }
private static RSM.Node LoadNode(RSM rsm, MemoryStreamReader data, double version) { RSM.Node node = new RSM.Node(); node.model = rsm; node.isOnly = rsm.nodes.Length == 1; node.name = data.ReadBinaryString(40); node.parentName = data.ReadBinaryString(40); //read textures int textureCount = data.ReadInt(); node.textures = new long[textureCount]; for (int i = 0; i < textureCount; ++i) { node.textures[i] = data.ReadInt(); } //read options node.mat3 = new Vector3[] { new Vector3(data.ReadFloat(), data.ReadFloat(), data.ReadFloat()), new Vector3(data.ReadFloat(), data.ReadFloat(), data.ReadFloat()), new Vector3(data.ReadFloat(), data.ReadFloat(), data.ReadFloat()) }; node.offset = new Vector3(data.ReadFloat(), data.ReadFloat(), data.ReadFloat()); node.pos = new Vector3(data.ReadFloat(), data.ReadFloat(), data.ReadFloat()); node.rotAngle = data.ReadFloat(); node.rotAxis = new Vector3(data.ReadFloat(), data.ReadFloat(), data.ReadFloat()); node.scale = new Vector3(data.ReadFloat(), data.ReadFloat(), data.ReadFloat()); //read vertices int verticeCount = data.ReadInt(); node.vertices = new List <Vector3>(); for (int i = 0; i < verticeCount; ++i) { node.vertices.Add(new Vector3(data.ReadFloat(), data.ReadFloat(), data.ReadFloat())); } //read textures vertices int tverticeCount = data.ReadInt(); node.tVertices = new float[tverticeCount * 6]; for (int i = 0; i < tverticeCount; ++i) { if (version >= 1.2) { node.tVertices[i * 6 + 0] = data.ReadByte() / 255f; node.tVertices[i * 6 + 1] = data.ReadByte() / 255f; node.tVertices[i * 6 + 2] = data.ReadByte() / 255f; node.tVertices[i * 6 + 3] = data.ReadByte() / 255f; } node.tVertices[i * 6 + 4] = data.ReadFloat() * 0.98f + 0.01f; node.tVertices[i * 6 + 5] = data.ReadFloat() * 0.98f + 0.01f; } //read faces int faceCount = data.ReadInt(); node.faces = new RSM.Face[faceCount]; for (int i = 0; i < faceCount; ++i) { node.faces[i] = new RSM.Face() { vertidx = new Vector3Int(data.ReadUShort(), data.ReadUShort(), data.ReadUShort()), tvertidx = new Vector3Int(data.ReadUShort(), data.ReadUShort(), data.ReadUShort()), texid = data.ReadUShort(), padding = data.ReadUShort(), twoSided = data.ReadInt(), smoothGroup = version >= 1.2 ? data.ReadInt() : 0 }; } //read position keyframes // DIFF: roBrowser and open-ragnarok use (version >= 1.5) here. // BrowEdit does not read position keyframes at all for any version. if (version > 1.5) { int pkfCount = data.ReadInt(); for (int i = 0; i < pkfCount; ++i) { var key = data.ReadInt(); if (!node.posKeyframes.ContainsKey(key)) { node.posKeyframes.Add(key, new Vector3(data.ReadFloat(), data.ReadFloat(), data.ReadFloat())); } } } //read rotation keyframes int rkfCount = data.ReadInt(); for (int i = 0; i < rkfCount; ++i) { int time = data.ReadInt(); Quaternion quat = new Quaternion(data.ReadFloat(), data.ReadFloat(), data.ReadFloat(), data.ReadFloat()); if (!node.rotKeyframes.ContainsKey(time)) { //some models have multiple keyframes with the //same timestamp, here we just keep the first one //and throw out the rest. node.rotKeyframes.Add(time, quat); } } node.box = new RSM.Box(); return(node); }
public static RSW Load(MemoryStreamReader data) { //read header string header = data.ReadBinaryString(4); string version = Convert.ToString(data.ReadByte()); string subversion = Convert.ToString(data.ReadByte()); version += "." + subversion; double dversion = double.Parse(version, CultureInfo.InvariantCulture); //check for valid .rsw file if (!string.Equals(header, RSW.Header)) { throw new Exception("WorldLoader.Load: Header (" + header + ") is not \"GRSW\""); } RSW rsw = new RSW(version); //read sub files files.ini = data.ReadBinaryString(40); files.gnd = data.ReadBinaryString(40); files.gat = data.ReadBinaryString(40); if (dversion >= 1.4) { files.src = data.ReadBinaryString(40); } //read water info if (dversion >= 1.3) { rsw.water.level = data.ReadFloat() / 5; if (dversion >= 1.8) { rsw.water.type = data.ReadInt(); rsw.water.waveHeight = data.ReadFloat() / 5; rsw.water.waveSpeed = data.ReadFloat(); rsw.water.wavePitch = data.ReadFloat(); if (dversion >= 1.9) { rsw.water.animSpeed = data.ReadInt(); } } } //read lightmap if (dversion >= 1.5) { rsw.light.longitude = data.ReadInt(); rsw.light.latitude = data.ReadInt(); for (int i = 0; i < 3; i++) { rsw.light.diffuse[i] = data.ReadFloat(); } for (int i = 0; i < 3; i++) { rsw.light.ambient[i] = data.ReadFloat(); } if (dversion >= 1.7) { rsw.light.intensity = data.ReadFloat(); } } // Read ground if (dversion >= 1.6) { rsw.ground.top = data.ReadInt(); rsw.ground.bottom = data.ReadInt(); rsw.ground.left = data.ReadInt(); rsw.ground.right = data.ReadInt(); } // Read Object int count = data.ReadInt(); var models = rsw.modelDescriptors = new List <RSW.ModelDescriptor>(count); var lights = rsw.lights = new List <RSW.Light>(count); var sounds = rsw.sounds = new List <RSW.Sound>(count); var effects = rsw.effects = new List <RSW.Effect>(count); for (int i = 0; i < count; i++) { switch (data.ReadInt()) { case 1: //load model var model = new RSW.ModelDescriptor(); model.name = dversion >= 1.3 ? data.ReadBinaryString(40) : null; model.animType = dversion >= 1.3 ? data.ReadInt() : 0; model.animSpeed = dversion >= 1.3 ? data.ReadFloat() : 0f; model.blockType = dversion >= 1.3 ? data.ReadInt() : 0; model.filename = data.ReadBinaryString(80); model.nodename = data.ReadBinaryString(80); model.position = new float[3]; for (int j = 0; j < model.position.Length; j++) { model.position[j] = data.ReadFloat() / 5; } model.rotation = new float[3]; for (int j = 0; j < model.rotation.Length; j++) { model.rotation[j] = data.ReadFloat(); } model.scale = new float[3]; for (int j = 0; j < model.scale.Length; j++) { model.scale[j] = data.ReadFloat() / 5; } models.Add(model); continue; case 2: //load light var light = new RSW.Light(); light.name = data.ReadBinaryString(80); light.pos = new float[3]; for (int j = 0; j < light.pos.Length; j++) { light.pos[j] = data.ReadFloat() / 5; } light.color = new float[3]; for (int j = 0; j < light.color.Length; j++) { light.color[j] = data.ReadFloat(); } light.range = data.ReadFloat(); lights.Add(light); continue; case 3: //load sound var sound = new RSW.Sound(); sound.name = data.ReadBinaryString(80); sound.file = "data/wav/" + data.ReadBinaryString(80); sound.pos = new float[3]; for (int j = 0; j < sound.pos.Length; j++) { sound.pos[j] = data.ReadFloat() / 5; } sound.vol = data.ReadFloat(); sound.width = data.ReadInt(); sound.height = data.ReadInt(); sound.range = data.ReadFloat(); sound.cycle = dversion >= 2.0 ? data.ReadFloat() : 0f; sounds.Add(sound); continue; case 4: //load effect var effect = new RSW.Effect(); effect.name = data.ReadBinaryString(80); effect.pos = new float[3]; for (int j = 0; j < effect.pos.Length; j++) { effect.pos[j] = data.ReadFloat() / 5; } effect.id = data.ReadInt(); effect.delay = data.ReadFloat() * 10; effect.param = new float[4]; for (int j = 0; j < effect.param.Length; j++) { effect.param[j] = data.ReadFloat(); } effects.Add(effect); continue; } } models.TrimExcess(); sounds.TrimExcess(); lights.TrimExcess(); effects.TrimExcess(); return(rsw); }