private void ReadTitle(WarResource res) { int index = 0x22; int offset = ReadInt(index, res.data); while (offset < res.data.Length) { ushort firstVal = ReadUShort(offset, res.data); if (firstVal == 0xFFFF) { // Means => end of title section return; } UIEntry Label = new UIEntry(); Label.Type = UIEntryType.Label; Label.Alignment = (UIEntryTextAlignment)firstVal; Label.X = ReadUShort(offset + 2, res.data); Label.Y = ReadUShort(offset + 4, res.data); Label.Text = ReadString(offset + 6, res); Labels.Add(Label); offset += 0x0A; } }
private void ReadPlayerInfo(WarResource res) { // 0xCC, 0xCE => Starting position of camera (divide by 2) (ushort) StartCameraX = ReadUShort(0xCC, res.data) / 2; StartCameraY = ReadUShort(0xCE, res.data) / 2; // 0x86 => if 1, human player is "Humans" // 0x84 => if 1, human player is "Orcs" Race humanPlayerRace = Race.Humans; if (ReadUShort(0x86, res.data) > 0) { humanPlayerRace = Race.Humans; } else { if (ReadUShort(0x84, res.data) > 0) { humanPlayerRace = Race.Orcs; } } if (PlayerInfos [0] != null) { PlayerInfos [0].Race = humanPlayerRace; } for (int i = 1; i < 5; i++) { if (PlayerInfos [i] != null) { PlayerInfos [i].Race = (humanPlayerRace == Race.Humans ? Race.Orcs : Race.Humans); } } }
private void Init(WarResource res) { ushort nmbrEntries = ReadUShort(0, res.data); ushort unk = ReadUShort(2, res.data); int[] offsets = new int[nmbrEntries]; for (int i = 0; i < nmbrEntries; i++) { unk = ReadUShort(4 + (i * 8) + 0, res.data); unk = ReadUShort(4 + (i * 8) + 2, res.data); offsets[i] = ReadInt(4 + (i * 8) + 4, res.data); } int offset = offsets[0]; List <byte[]> datas = new List <byte[]>(); for (int i = 0; i < nmbrEntries; i++) { int length = 0; if (i < nmbrEntries - 1) { length = offsets[i + 1] - offsets[i]; } else { length = res.data.Length - offsets[i]; } byte[] data = ReadBytes(offsets[i], length, res.data); datas.Add(WarResource.RLEUncompress(data)); offset += length; } }
/// <summary> /// Load all tilesets /// </summary> internal static void LoadAllTilesets() { // TODO: FIXME with new WarFile resource loading strategy WarResource tileset = ((RawResource)WarFile.GetResourceByName("Barrens 1")).Resource; WarResource tiles = ((RawResource)WarFile.GetResourceByName("Barrens 2")).Resource; PaletteResource tilesPAL = WarFile.GetResourceByName("Barrens 3") as PaletteResource; MapTileset swamp = new MapTileset(Tileset.Swamp, tileset, tiles, tilesPAL); knownTilesets.Add(swamp); tileset = ((RawResource)WarFile.GetResourceByName("Summer 1")).Resource; tiles = ((RawResource)WarFile.GetResourceByName("Summer 2")).Resource; tilesPAL = WarFile.GetResourceByName("Summer 3") as PaletteResource; MapTileset summer = new MapTileset(Tileset.Summer, tileset, tiles, tilesPAL); knownTilesets.Add(summer); if (WarFile.IsDemo == false) { tileset = ((RawResource)WarFile.GetResourceByName("Dungeon 1")).Resource; tiles = ((RawResource)WarFile.GetResourceByName("Dungeon 2")).Resource; tilesPAL = WarFile.GetResourceByName("Dungeon 3") as PaletteResource; MapTileset dungeon = new MapTileset(Tileset.Dungeon, tileset, tiles, tilesPAL); knownTilesets.Add(dungeon); } }
private void Init(WarResource res) { ushort nmbrEntries = ReadUShort(0, res.data); ushort unk = ReadUShort(2, res.data); int[] offsets = new int[nmbrEntries]; for (int i = 0; i < nmbrEntries; i++) { unk = ReadUShort(4 + (i * 8) + 0, res.data); unk = ReadUShort(4 + (i * 8) + 2, res.data); offsets[i] = ReadInt(4 + (i * 8) + 4, res.data); } int offset = offsets[0]; List<byte[]> datas = new List<byte[]>(); for (int i = 0; i < nmbrEntries; i++) { int length = 0; if (i < nmbrEntries - 1) length = offsets[i + 1] - offsets[i]; else length = res.data.Length - offsets[i]; byte[] data = ReadBytes(offsets[i], length, res.data); datas.Add(WarResource.RLEUncompress(data)); offset += length; } }
// LevelVisualResource(setData, setOffset) /// <summary> /// Create visual data /// </summary> void CreateVisualData(WarResource setData) { // Levels are always 64 x 64 in size visualData = new ushort[64 * 64]; if (setData.data != null) { unsafe { fixed (byte* org_ptr = &setData.data[0]) { ushort* ptr = (ushort*)org_ptr; for (int y = 0; y < 64; y++) { for (int x = 0; x < 64; x++) { visualData[x + y * 64] = *ptr; ptr++; } } } // fixed } // fixed } // if }
private string[] ReadMultiselectValues(int buttonIndex, WarResource res) { int index = 0x1A; int offset = ReadInt(index, res.data); int counter = 1; while (offset < res.data.Length) { List <string> list = ReadMultiselectValuesRowAtOffset(offset, res); if (list.Count == 0) { return(new string[0]); } if (counter == buttonIndex) { return(list.ToArray()); } counter++; offset += list.Count * 4 + 4; } return(new string[0]); }
private LevelObject[] ReadStartObjects(int offset, WarResource res, out int endOffset) { List <LevelObject> result = new List <LevelObject>(); while (offset < res.data.Length) { uint val = ReadUShort(offset, res.data); if (val == 0xFFFF) { break; } LevelObject lo = new LevelObject(); lo.X = (byte)(res.data[offset + 0] / 2); lo.Y = (byte)(res.data[offset + 1] / 2); lo.Type = (LevelObjectType)res.data[offset + 2]; lo.Player = res.data[offset + 3]; offset += 4; if (lo.Type == LevelObjectType.Goldmine) { lo.Value1 = res.data[offset + 0]; lo.Value2 = res.data[offset + 1]; offset += 2; } result.Add(lo); } endOffset = offset; return(result.ToArray()); }
internal SpriteResource(WarResource data, WarResource palette, WarResource addPalette) { Type = ContentFileType.FileSprite; Frames = null; CreateImageData(data, palette, addPalette); }
internal TableResource(WarResource data) { Type = ContentFileType.FileTable; if (data == null) throw new ArgumentNullException("data"); Init(data); }
/// <summary> /// Create level visual resource /// </summary> internal LevelPassableResource(WarResource setData) { Type = ContentFileType.FileLevelPassable; width = 64; height = 64; CreatePassableData(setData); }
private void ReadConstructs(int offset, WarResource res) { // FF FF // Roads => x/y - x2/y2 - owner // FF FF // Walls => x/y - x2/y2 - owner // FF FF List <Construct> roads = new List <Construct>(); List <Construct> walls = new List <Construct>(); ushort val = ReadUShort(offset, res.data); if (val != 0xFFFF) { throw new InvalidOperationException(); } offset += 2; // Read roads while (offset < res.data.Length) { val = ReadUShort(offset, res.data); if (val == 0xFFFF) { break; } byte startX = (byte)(res.data[offset++] / 2); byte startY = (byte)(res.data[offset++] / 2); byte endX = (byte)(res.data[offset++] / 2); byte endY = (byte)(res.data[offset++] / 2); byte owner = res.data[offset++]; CreateConstructsFromTo(startX, startY, endX, endY, owner, ConstructType.Road, roads); } StartRoads = roads.ToArray(); offset += 2; // Read walls while (offset < res.data.Length) { val = ReadUShort(offset, res.data); if (val == 0xFFFF) { break; } byte startX = (byte)(res.data[offset++] / 2); byte startY = (byte)(res.data[offset++] / 2); byte endX = (byte)(res.data[offset++] / 2); byte endY = (byte)(res.data[offset++] / 2); byte owner = res.data[offset++]; CreateConstructsFromTo(startX, startY, endX, endY, owner, ConstructType.Wall, walls); } StartWalls = walls.ToArray(); }
private void Init(WarResource data) { Labels = new List<UIEntry>(); Elements = new List<UIEntry>(); ReadBackgroundImage(data); ReadSubHeader(data); ReadTitle(data); ReadUIElements(data); }
private void Init(WarResource data) { Labels = new List <UIEntry>(); Elements = new List <UIEntry>(); ReadBackgroundImage(data); ReadSubHeader(data); ReadTitle(data); ReadUIElements(data); }
protected ushort ReadResourceIndexDirectUShort(int offset, WarResource res) { ushort resIndex = ReadUShort(offset, res.data); if (resIndex == 0 || resIndex == 0xFFFF) { return(0); } return((ushort)(resIndex - 2)); }
internal UIResource(WarResource data) { Type = ContentFileType.FileUI; if (data == null) { throw new ArgumentNullException("data"); } Init(data); }
internal TextResource(WarResource data) { Type = ContentFileType.FileText; if (data == null) { throw new ArgumentNullException(nameof(data)); } Init(data); }
private string ReadString(int index, WarResource res) { int offset = ReadInt(index, res.data); if (offset == 0) { return(string.Empty); } return(ReadStringDirect(offset, res)); }
protected int ReadResourceIndexDirectInt(int offset, WarResource res) { int resIndex = ReadInt(offset, res.data); if (resIndex == 0 || resIndex >= 0xFFFF) { return(0); } return(resIndex - 2); }
// MapTileset() #endregion #region ctor /// <summary> /// Create map tileset /// </summary> internal MapTileset(Tileset setTilesetType, WarResource setTileset, WarResource setTiles, PaletteResource setTilesetPal) { tiles = setTiles; tileset = setTileset; tilesetPal = setTilesetPal; tilesetType = setTilesetType; CreateTiles(); CreateRoadTypes(); }
private void ReadResourceIndices(WarResource res) { // 0xCA => -2 to get next map (ushort) NextLevelResourceIndex = ReadResourceIndexDirectUShort(0xCA, res); // 0xD0, 0xD2 => -2 to get level visual and level passable (ushort) VisualResourceIndex = ReadResourceIndexDirectUShort(0xD0, res); PassableResourceIndex = ReadResourceIndexDirectUShort(0xD2, res); // 0xD4, 0xD6, 0xD8 => -2 to get map tileset, etc.. (ushort) TilesetResourceIndex = ReadResourceIndexDirectUShort(0xD4, res); TilesResourceIndex = ReadResourceIndexDirectUShort(0xD6, res); TilesPaletteResourceIndex = ReadResourceIndexDirectUShort(0xD8, res); }
protected string ReadStringDirect(int offset, WarResource res) { StringBuilder result = new StringBuilder(); byte b = res.data[offset++]; // Nullterminated string while (b != 0x00) { result.Append((char)b); b = res.data[offset++]; } return(result.ToString()); }
private void ReadSubHeader(WarResource res) { // Unknown int ==> Always 0x2A // "Enter" button index // "Escape" button index // In some cases, there's more data in this section int index = 0x1E; int offset = ReadInt(index, res.data); EnterButtonIndex = ReadUShort(offset + 4, res.data); EscapeButtonIndex = ReadUShort(offset + 6, res.data); ushort unk1 = ReadUShort(offset + 8, res.data); ushort unk2 = ReadUShort(offset + 10, res.data); }
// LevelVisualResource(setData, setOffset) /// <summary> /// Create visual data /// </summary> private void CreatePassableData(WarResource setData) { passableData = new short[width, height]; if (setData.data != null) { int offset = 0; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { passableData[x, y] = ReadShort(offset, setData.data); offset += 2; } } } // if }
// LevelVisualResource(setData, setOffset) /// <summary> /// Create visual data /// </summary> void CreateVisualData(WarResource setData) { // Levels are always 64 x 64 in size visualData = new ushort[64 * 64]; if (setData.data != null) { int offset = 0; for (int y = 0; y < 64; y++) { for (int x = 0; x < 64; x++) { visualData[x + y * 64] = ReadUShort(offset, setData.data); offset += 2; } } } // if }
private void Init(WarResource data) { Columns = (ushort)(data.data[0] + (data.data[1] << 8)); Rows = (ushort)(data.data[2] + (data.data[3] << 8)); tableData = new ushort[Columns, Rows]; int offset = 4; for (int y = 0; y < Rows; y++) { for (int x = 0; x < Columns; x++) { tableData[x, y] = (ushort)(data.data[offset] + (data.data[offset + 1] << 8)); offset += 2; } } }
private void ReadHeaders(WarResource res) { // 54 (0x36) bytes header Magic = ReadBytes(0, 4, res.data); levelInfoType = DetermineType(Magic); Header = ReadBytes(4, 50, res.data); // 4 bytes FF FF FF FF // 32 (0x20) bytes follow SubHeader = new ushort[16]; int offset = 0x3A; for (int i = 0; i < SubHeader.Length; i++) { SubHeader[i] = (ushort)(res.data[offset] + (res.data[offset + 1] << 8)); offset += 2; } // 2 bytes FF FF }
private List <string> ReadMultiselectValuesRowAtOffset(int offset, WarResource res) { List <string> result = new List <string>(); while (offset < res.data.Length) { int val = ReadInt(offset, res.data); if (val == unchecked ((int)0xFFFFFFFF) || val == 0) { break; } result.Add(ReadStringDirect(val, res)); offset += 4; } return(result); }
private void ReadMissionText(WarResource res) { // 0x94 => Offset to mission text (ushort) uint missionTextOffset = ReadUInt(0x94, res.data); MissionText = string.Empty; if (missionTextOffset > 0)// 0 => No MissionText { StringBuilder sb = new StringBuilder(); uint idx = missionTextOffset; // Nullterminated string while (res.data[idx] != 0x00) { sb.Append((char)res.data [idx]); idx++; } MissionText = sb.ToString(); } }
private void LoadData(WarResource res) { PlayerInfos = new PlayerInfo[5]; ReadHeaders(res); ReadStartingResources(res); ReadPlayerInfo(res); ReadMissionText(res); ReadResourceIndices(res); // Usually 0x03 ushort unk = ReadUShort(0xDA, res.data); // 7 bytes (always 0x0A 0x72 0x77 0x0A 0x79 0x7E 0x00) byte[] unk2 = ReadBytes(0xDC, 7, res.data); // 0xE3 start of dynamic data // TODO: Needs figuring out how this is actually stored and what the data means // For now, just search for the next chunk int offset = 0xE3; while (ReadUInt(offset, res.data) != 0xFFFFFFFF) { offset++; } offset += 4; int startObjOffset = offset; startObjOffset = (int)ReadUShort(startObjOffset, res.data); // Read start objects int endOffsetStartObjects = 0; StartObjects = ReadStartObjects(startObjOffset, res, out endOffsetStartObjects); // Read constructs (roads/walls) ReadConstructs(endOffsetStartObjects, res); }
private string[] ReadMultiselectValues(int buttonIndex, WarResource res) { int index = 0x1A; int offset = ReadInt(index, res.data); int counter = 1; while (offset < res.data.Length) { List<string> list = ReadMultiselectValuesRowAtOffset(offset, res); if (list.Count == 0) return new string[0]; if (counter == buttonIndex) return list.ToArray(); counter++; offset += list.Count * 4 + 4; } return new string[0]; }
private void ReadStartingResources(WarResource res) { // 0x5C => Starting amount of lumber (uint) Player 1 // 0x60 => Starting amount of lumber (uint) Player 2 // 0x64 => Starting amount of lumber (uint) Player 3 // 0x68 => Starting amount of lumber (uint) Player 4 // 0x6C => Starting amount of lumber (uint) Player 5? for (int i = 0; i < 5; i++) { int startLumber = ReadInt(0x5C + i * 4, res.data); if (startLumber > 0) { if (PlayerInfos[i] == null) { PlayerInfos[i] = new PlayerInfo(); } PlayerInfos[i].StartLumber = startLumber; } } // 0x70=> Starting amount of gold (uint) Player 1 // 0x74=> Starting amount of gold (uint) Player 2 // 0x78=> Starting amount of gold (uint) Player 3 // 0x7C=> Starting amount of gold (uint) Player 4 // 0x80=> Starting amount of gold (uint) Player 5? for (int i = 0; i < 5; i++) { int startGold = ReadInt(0x70 + i * 4, res.data); if (startGold > 0) { if (PlayerInfos[i] == null) { PlayerInfos[i] = new PlayerInfo(); } PlayerInfos[i].StartGold = startGold; } } }
/// <summary> /// Create visual data /// </summary> private void CreatePassableData(WarResource setData) { passableData = new short[width, height]; if (setData.data != null) { unsafe { fixed (byte* org_ptr = &setData.data[0]) { short* ptr = (short*)org_ptr; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { passableData [x, y] = *ptr; ptr++; } } } // fixed } // fixed } // if }
private void ReadBackgroundImage(WarResource res) { BackgroundImageResourceIndex = ReadResourceIndex(0x12, res); }
private void ReadUIElements(WarResource res) { int index = 0x26; int offset = ReadInt(index, res.data); // Length of one button => 0x1C while (offset < res.data.Length) { ushort firstVal = ReadUShort(offset, res.data); if (firstVal == 0xFFFF) { break; } UIEntry me = new UIEntry(); me.Type = (UIEntryType)ReadUShort(offset, res.data); me.Alignment = (UIEntryTextAlignment)ReadUShort(offset + 2, res.data); // This is just a guess based on the label section me.X = ReadUShort(offset + 4, res.data); me.Y = ReadUShort(offset + 6, res.data); ushort unk = ReadUShort(offset + 8, res.data); me.ButtonReleasedResourceIndex = ReadResourceIndex(offset + 10, res); me.ButtonPressedResourceIndex = ReadResourceIndex(offset + 14, res); me.Text = string.Empty; if (me.Type == UIEntryType.Button || me.Type == UIEntryType.TextFieldSelectable || me.Type == UIEntryType.ListBoxSelectButton || me.Type == UIEntryType.TextFieldButton || me.Type == UIEntryType.TextFieldHidden) { me.Text = ReadString(offset + 18, res); } else if (me.Type == UIEntryType.ValueList || me.Type == UIEntryType.ListBox) { // Read values int valuesOffset = ReadInt(offset + 18, res.data); while (valuesOffset < res.data.Length) { int valueOff = ReadInt(valuesOffset, res.data); if (valueOff == unchecked ((int)0xFFFFFFFF) || valueOff == 0) { break; } string val = ReadStringDirect(valueOff, res); me.Values.Add(val); valuesOffset += 4; } } else { me.ValueCount = ReadInt(offset + 18, res.data); } me.ButtonIndex = ReadInt(offset + 22, res.data); me.HotKey = ReadUShort(offset + 26, res.data); Elements.Add(me); if (me.Type == UIEntryType.ListBoxSelectButton) { // Fill values which will be pasted into the listbox me.Values = new List <string>(ReadMultiselectValues(me.ButtonIndex, res)); } offset += 0x1C; } }
internal CursorResource(WarResource data, WarResource palette) { Type = ContentFileType.FileCursor; CreateImageData(data, palette); }
private List<string> ReadMultiselectValuesRowAtOffset(int offset, WarResource res) { List<string> result = new List<string>(); while (offset < res.data.Length) { int val = ReadInt(offset, res.data); if (val == unchecked((int)0xFFFFFFFF) || val == 0) break; result.Add(ReadStringDirect(val, res)); offset += 4; } return result; }
/// <summary> /// Create level visual resource /// </summary> internal LevelVisualResource(WarResource setData) { Type = ContentFileType.FileLevelVisual; CreateVisualData(setData); }
internal void CreateImageData(WarResource imgResource, WarResource palette) { if (imgResource == null) return; unsafe { fixed (byte* org_ptr = &imgResource.data[0]) { ushort* usptr = (ushort*)org_ptr; HotSpotX = *usptr++; HotSpotY = *usptr++; width = *usptr++; height = *usptr++; byte* b_ptr = (byte*)usptr; image_data = new byte[width * height * 4]; int cnt = 0; int x, y; if (palette == null) // No palette for this image or grayscale forced ... use grayscale palette { for (y = 0; y < height; y++) for (x = 0; x < width; x++) { image_data [cnt] = b_ptr [x + y * width]; cnt++; image_data [cnt] = b_ptr [x + y * width]; cnt++; image_data [cnt] = b_ptr [x + y * width]; cnt++; image_data [cnt] = 255; cnt++; } } else { // We have a palette ... use it! fixed (byte* pal_org_ptr = &palette.data[0]) { byte* pal_dataptr = pal_org_ptr; int pal_index; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { pal_index = b_ptr [x + y * width] * 3; image_data [cnt] = (byte)(pal_dataptr [pal_index + 0] * 4); cnt++; image_data [cnt] = (byte)(pal_dataptr [pal_index + 1] * 4); cnt++; image_data [cnt] = (byte)(pal_dataptr [pal_index + 2] * 4); cnt++; image_data [cnt] = (byte)(((image_data[cnt - 3] == 0) && (image_data[cnt - 2] == 0) && (image_data[cnt - 1] == 0)) ? 0 : 255); cnt++; } } } } } } }
private void ReadUIElements(WarResource res) { int index = 0x26; int offset = ReadInt(index, res.data); // Length of one button => 0x1C while (offset < res.data.Length) { ushort firstVal = ReadUShort(offset, res.data); if (firstVal == 0xFFFF) break; UIEntry me = new UIEntry(); me.Type = (UIEntryType)ReadUShort(offset, res.data); me.Alignment = (UIEntryTextAlignment)ReadUShort(offset + 2, res.data); // This is just a guess based on the label section me.X = ReadUShort(offset + 4, res.data); me.Y = ReadUShort(offset + 6, res.data); ushort unk = ReadUShort(offset + 8, res.data); me.ButtonReleasedResourceIndex = ReadResourceIndex(offset + 10, res); me.ButtonPressedResourceIndex = ReadResourceIndex(offset + 14, res); me.Text = string.Empty; if (me.Type == UIEntryType.Button || me.Type == UIEntryType.TextFieldSelectable || me.Type == UIEntryType.ListBoxSelectButton || me.Type == UIEntryType.TextFieldButton || me.Type == UIEntryType.TextFieldHidden) { me.Text = ReadString(offset + 18, res); } else if (me.Type == UIEntryType.ValueList || me.Type == UIEntryType.ListBox) { // Read values int valuesOffset = ReadInt(offset + 18, res.data); while (valuesOffset < res.data.Length) { int valueOff = ReadInt(valuesOffset, res.data); if (valueOff == unchecked((int)0xFFFFFFFF) || valueOff == 0) break; string val = ReadStringDirect(valueOff, res); me.Values.Add(val); valuesOffset += 4; } } else { me.ValueCount = ReadInt(offset + 18, res.data); } me.ButtonIndex = ReadInt(offset + 22, res.data); me.HotKey = ReadUShort(offset + 26, res.data); Elements.Add(me); if (me.Type == UIEntryType.ListBoxSelectButton) { // Fill values which will be pasted into the listbox me.Values = new List<string>(ReadMultiselectValues(me.ButtonIndex, res)); } offset += 0x1C; } }
private void ReadTitle(WarResource res) { int index = 0x22; int offset = ReadInt(index, res.data); while (offset < res.data.Length) { ushort firstVal = ReadUShort(offset, res.data); if (firstVal == 0xFFFF) // Means => end of title section return; UIEntry Label = new UIEntry(); Label.Type = UIEntryType.Label; Label.Alignment = (UIEntryTextAlignment)firstVal; Label.X = ReadUShort(offset + 2, res.data); Label.Y = ReadUShort(offset + 4, res.data); Label.Text = ReadString(offset + 6, res); Labels.Add(Label); offset += 0x0A; } }
internal RawResource(WarResource setResource) { Type = ContentFileType.FileUnknown; Resource = setResource; }
internal PaletteResource(WarResource setData) { Type = ContentFileType.FilePalette; Colors = setData.data; }
private string ReadString(int index, WarResource res) { int offset = ReadInt(index, res.data); if (offset == 0) return string.Empty; return ReadStringDirect(offset, res); }
internal void CreateImageData(WarResource imgResource, WarResource palette, WarResource addPalette) { int i, offset, x, y, c; WarResource addPal = addPalette; unsafe { fixed (byte* org_ptr = &imgResource.data[0]) { FrameCount = org_ptr[0] + (org_ptr[1] << 8); MaxWidth = org_ptr[2]; MaxHeight = org_ptr[3]; Frames = new SpriteResourceFrame[FrameCount]; offset = 4; for (i = 0; i < FrameCount; i++) { Frames[i].disp_x = org_ptr[offset]; Frames[i].disp_y = org_ptr[offset + 1]; Frames[i].width = org_ptr[offset + 2]; Frames[i].height = org_ptr[offset + 3]; Frames[i].offset = org_ptr[offset + 4] + (org_ptr[offset + 5] << 8) + (org_ptr[offset + 6] << 16) + (org_ptr[offset + 7] << 24); offset += 8; } for (i = 0; i < FrameCount; i++) { offset = Frames[i].offset; Frames[i].image_data = new byte[MaxWidth * MaxHeight * 4]; int temp_index; if (palette == null) { // No palette for this image or grayscale forced ... use grayscale palette for (y = Frames [i].disp_y; y < (Frames [i].height + Frames [i].disp_y); y++) { for (x = Frames [i].disp_x; x < (Frames [i].width + Frames [i].disp_x); x++) { temp_index = (x + (y * MaxWidth)) * 4; for (c = 0; c < 3; c++) Frames [i].image_data [temp_index + c] = org_ptr [offset]; Frames [i].image_data [temp_index + 3] = 255; offset++; } } } else { // We have a palette ... use it! fixed (byte* pal_org_ptr = &palette.data[0]) { byte* pal_dataptr = pal_org_ptr; int pal_index; for (y = Frames[i].disp_y; y < (Frames[i].height + Frames[i].disp_y); y++) { for (x = Frames[i].disp_x; x < (Frames[i].width + Frames[i].disp_x); x++) { temp_index = (x + (y * MaxWidth)) * 4; pal_index = org_ptr[offset++] * 3; if (pal_index / 3 == 96) { // Shadow Frames[i].image_data[temp_index] = 0; Frames[i].image_data[temp_index + 1] = 0; Frames[i].image_data[temp_index + 2] = 0; Frames[i].image_data[temp_index + 3] = 127; continue; } for (c = 0; c < 3; c++) Frames [i].image_data [temp_index + c] = (byte)(pal_dataptr[pal_index + c] * 4); Frames[i].image_data[temp_index + 3] = (((Frames[i].image_data[temp_index] == 0) && (Frames[i].image_data[temp_index + 1] == 0) && (Frames[i].image_data[temp_index + 2] == 0)) ? (byte)0 : (byte)255); if ((Frames[i].image_data[temp_index] == 228) && (Frames[i].image_data[temp_index + 1] == 108) && (Frames[i].image_data[temp_index + 2] == 228)) { Frames[i].image_data[temp_index] = (byte)(addPal.data[pal_index + 0] * 4); Frames[i].image_data[temp_index + 1] = (byte)(addPal.data[pal_index + 1] * 4); Frames[i].image_data[temp_index + 2] = (byte)(addPal.data[pal_index + 2] * 4); Frames[i].image_data[temp_index + 3] = 255; } } } } } } } } }
internal EmbeddedDataResource(WarResource data) { Init(data); }
private void Init(WarResource data) { Text = Encoding.ASCII.GetString(data.data); }
/* // Offset of resource tables starts at 0x12 (uint) // Offset of string table starts at 0x16 (uint) // Offset of multiselect values starts at 0x1A (uint) // Offset of sub header starts at 0x1E (uint) // Offset of title info starts at 0x22 (uint) // Offset of button list starts at 0x26 (uint) // Resource table // -2 resource index of background image // -2 resource index of button // -2 resource index of pressed button */ private int ReadResourceIndex(int index, WarResource res) { int offset = ReadInt(index, res.data); return ReadResourceIndexDirectInt(offset, res); }