/// <summary> /// Reads the data element from the given buffer. /// </summary> /// <param name="buffer">The buffer where the data element should be deserialized from.</param> public Condition ReadData(RAMBuffer buffer) { Type = (ConditionTypes)buffer.ReadUInteger(); ScenarioDataElementTools.AssertTrue(buffer.ReadUInteger() == 0x00000010); Amount = buffer.ReadInteger(); ResourceId = buffer.ReadInteger(); UnitInstanceId = buffer.ReadInteger(); UnitLocation = buffer.ReadInteger(); UnitType = buffer.ReadInteger(); Player = buffer.ReadInteger(); ResearchId = buffer.ReadInteger(); Timer = buffer.ReadInteger(); Unknown = buffer.ReadInteger(); AreaBottomLeftX = buffer.ReadInteger(); AreaBottomLeftY = buffer.ReadInteger(); AreaTopRightX = buffer.ReadInteger(); AreaTopRightY = buffer.ReadInteger(); UnitClass = buffer.ReadInteger(); UnitType2 = buffer.ReadInteger(); AiSignal = buffer.ReadInteger(); return(this); }
/// <summary> /// Erstellt aus der angegebenen Binär-Datei eine neue External-File-Struktur. /// </summary> /// <param name="data">Die auszulesende Binär-Datei.</param> /// <returns></returns> /// <remarks></remarks> public static ExternalFile FromBinary(RAMBuffer data) { // An den Anfang springen data.Position = 0; // Der Rückgabewert ExternalFile ret = new ExternalFile(); // Ausnahmen abfangen für ungültige Dateien try { // DRS-Dateiname uint drsNameLen = data.ReadUInteger(); ret.DRSFile = System.Text.Encoding.ASCII.GetString(data.ReadByteArray((int)drsNameLen)); // Datei-ID ret.FileID = data.ReadUInteger(); // Ressourcen-Typ uint resTypeLen = data.ReadUInteger(); ret.ResourceType = System.Text.Encoding.ASCII.GetString(data.ReadByteArray((int)resTypeLen)); // Data uint dataLen = data.ReadUInteger(); ret.Data = data.ReadByteArray((int)dataLen); } catch { // Fehler MessageBox.Show("Fehler: Das Datenobjekt konnte nicht fehlerfrei in ein ExternalFile-Objekt umgewandelt werden!", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error); } // Fertig return(ret); }
/// <summary> /// Reads the data element from the given buffer. /// </summary> /// <param name="buffer">The buffer where the data element should be deserialized from.</param> public AiFile ReadData(RAMBuffer buffer) { Unknown1 = buffer.ReadUInteger(); Unknown2 = buffer.ReadUInteger(); AiPerFileContent = buffer.ReadString(buffer.ReadInteger()); return(this); }
/// <summary> /// Reads the data element from the given buffer. /// </summary> /// <param name="buffer">The buffer where the data element should be deserialized from.</param> public PlayerDataHeader ReadData(RAMBuffer buffer) { Active = buffer.ReadUInteger(); Human = buffer.ReadUInteger(); CivId = buffer.ReadUInteger(); Unknown = buffer.ReadUInteger(); return(this); }
/// <summary> /// Deserializes the data elements from the internal buffer. /// </summary> /// <remarks></remarks> private void ReadData() { // Read version string version = _buffer.ReadString(4); if (version != "1.21") { throw new InvalidDataException($"Invalid primary file version: '{version}'"); } // Read remaining file header _buffer.ReadUInteger(); // Header length _buffer.ReadInteger(); // Unknown constant = 2 LastSaveTimestamp = _buffer.ReadUInteger(); int instructionsLength = _buffer.ReadInteger(); ScenarioInstructions = _buffer.ReadString(instructionsLength); _buffer.ReadUInteger(); // Unknown constant = 0 PlayerCount = _buffer.ReadUInteger(); // Create memory stream for decompression using (MemoryStream output = new MemoryStream()) using (MemoryStream input = _buffer.ToMemoryStream()) { // Go to begin of uncompressed data input.Seek(_buffer.Position, SeekOrigin.Begin); // Create decompressor stream using (DeflateStream decompressor = new DeflateStream(input, CompressionMode.Decompress)) { // Decompress decompressor.CopyTo(output); decompressor.Close(); } // Save decompressed data into buffer _buffer = new RAMBuffer(output.ToArray()); } // Read parts Header = new DataElements.Header().ReadData(_buffer); MessagesCinematics = new DataElements.MessagesCinematics().ReadData(_buffer); PlayerAiResources = new DataElements.PlayerAiResources().ReadData(_buffer); GlobalVictory = new DataElements.GlobalVictory().ReadData(_buffer); Diplomacy = new DataElements.Diplomacy().ReadData(_buffer); Disables = new DataElements.Disables().ReadData(_buffer); Map = new DataElements.Map().ReadData(_buffer); Units = new DataElements.Units().ReadData(_buffer); PlayerDiplomacyVarious = new DataElements.PlayerDiplomacyVarious().ReadData(_buffer); Triggers = new DataElements.Triggers().ReadData(_buffer); IncludedFiles = new DataElements.IncludedFiles().ReadData(_buffer); // Clear buffer to save memory _buffer.Clear(); }
/// <summary> /// Reads the data element from the given buffer. /// </summary> /// <param name="buffer">The buffer where the data element should be deserialized from.</param> public PlayerDiplomacyVariousEntry ReadData(RAMBuffer buffer) { PlayerName = buffer.ReadString(buffer.ReadUShort()); InitialCameraX = buffer.ReadFloat(); InitialCameraY = buffer.ReadFloat(); UnknownX = buffer.ReadShort(); UnknownY = buffer.ReadShort(); AlliedVictory = buffer.ReadByte(); ushort playerDiplomacyCount = buffer.ReadUShort(); Diplomacy1 = new List <DiplomacyTypes1>(playerDiplomacyCount); for (int i = 0; i < playerDiplomacyCount; i++) { Diplomacy1.Add((DiplomacyTypes1)buffer.ReadByte()); } Diplomacy2 = new List <DiplomacyTypes2>(playerDiplomacyCount); for (int i = 0; i < playerDiplomacyCount; i++) { Diplomacy2.Add((DiplomacyTypes2)buffer.ReadUInteger()); } Color = buffer.ReadUInteger(); Unknown1 = buffer.ReadFloat(); Unknown3Count = buffer.ReadUShort(); if (Unknown1 == 2) { Unknown2 = new List <byte>(8); for (int i = 0; i < 8; i++) { Unknown2.Add(buffer.ReadByte()); } } Unknown3 = new List <byte>(Unknown3Count * 44); for (int i = 0; i < Unknown3Count * 44; i++) { Unknown3.Add(buffer.ReadByte()); } Unknown4 = new List <byte>(7); for (int i = 0; i < 7; i++) { Unknown4.Add(buffer.ReadByte()); } Unknown5 = buffer.ReadInteger(); return(this); }
/// <summary> /// Reads the data element from the given buffer. /// </summary> /// <param name="buffer">The buffer where the data element should be deserialized from.</param> public Effect ReadData(RAMBuffer buffer) { Type = (EffectTypes)buffer.ReadUInteger(); ScenarioDataElementTools.AssertTrue(buffer.ReadUInteger() == 0x00000017); AiGoal = buffer.ReadInteger(); Amount = buffer.ReadInteger(); ResourceId = buffer.ReadInteger(); Diplomacy = buffer.ReadInteger(); int selectedUnitsCount = buffer.ReadInteger(); if (selectedUnitsCount < 0) { selectedUnitsCount = 0; } LocationUnitInstanceId = buffer.ReadInteger(); UnitType = buffer.ReadInteger(); PlayerSource = buffer.ReadInteger(); PlayerTarget = buffer.ReadInteger(); ResearchId = buffer.ReadInteger(); StringId = buffer.ReadInteger(); SoundId = buffer.ReadInteger(); DisplayTime = buffer.ReadInteger(); TriggerIndex = buffer.ReadInteger(); LocationX = buffer.ReadInteger(); LocationY = buffer.ReadInteger(); AreaBottomLeftX = buffer.ReadInteger(); AreaBottomLeftY = buffer.ReadInteger(); AreaTopRightX = buffer.ReadInteger(); AreaTopRightY = buffer.ReadInteger(); UnitClass = buffer.ReadInteger(); UnitType2 = buffer.ReadInteger(); InstructionPanel = buffer.ReadInteger(); Text = buffer.ReadString(buffer.ReadInteger()); SoundFileName = buffer.ReadString(buffer.ReadInteger()); SelectedUnitInstanceIds = new List <uint>(selectedUnitsCount); for (int i = 0; i < selectedUnitsCount; i++) { SelectedUnitInstanceIds.Add(buffer.ReadUInteger()); } return(this); }
/// <summary> /// Reads the data element from the given buffer. /// </summary> /// <param name="buffer">The buffer where the data element should be deserialized from.</param> public IncludedFiles ReadData(RAMBuffer buffer) { int filesIncluded = buffer.ReadInteger(); EsOnlyDataIncluded = buffer.ReadUInteger(); if (EsOnlyDataIncluded > 0) { EsOnlyData = new List <byte>(396); for (int i = 0; i < 396; ++i) { EsOnlyData.Add(buffer.ReadByte()); } } if (filesIncluded > 0) { int fileCount = buffer.ReadInteger(); Files = new List <IncludedFile>(fileCount); for (int i = 0; i < fileCount; i++) { Files.Add(new IncludedFile().ReadData(buffer)); } } return(this); }
/// <summary> /// Reads the data element from the given buffer. /// </summary> /// <param name="buffer">The buffer where the data element should be deserialized from.</param> public MessagesCinematics ReadData(RAMBuffer buffer) { InstructionsStringDllId = buffer.ReadUInteger(); HintsStringDllId = buffer.ReadUInteger(); VictoryStringDllId = buffer.ReadUInteger(); LossStringDllId = buffer.ReadUInteger(); HistoryStringDllId = buffer.ReadUInteger(); ScoutsStringDllId = buffer.ReadUInteger(); InstructionsString = buffer.ReadString(buffer.ReadShort()); HintsString = buffer.ReadString(buffer.ReadShort()); VictoryString = buffer.ReadString(buffer.ReadShort()); LossString = buffer.ReadString(buffer.ReadShort()); HistoryString = buffer.ReadString(buffer.ReadShort()); ScoutsString = buffer.ReadString(buffer.ReadShort()); PregameCinematicFileName = buffer.ReadString(buffer.ReadShort()); VictoryCinematicFileName = buffer.ReadString(buffer.ReadShort()); LossCinematicFileName = buffer.ReadString(buffer.ReadShort()); BackgroundFileName = buffer.ReadString(buffer.ReadShort()); BitmapIncluded = buffer.ReadUInteger(); buffer.ReadInteger(); // Width buffer.ReadInteger(); // Height buffer.ReadShort(); // Unknown, -1 for Bitmaps, 1 for no bitmaps Bitmap = BitmapIncluded != 0 ? new BitmapLibrary.BitmapLoader(buffer, readFileHeader: false) : null; return(this); }
/// <summary> /// Reads the data element from the given buffer. /// </summary> /// <param name="buffer">The buffer where the data element should be deserialized from.</param> public StancesToPlayers ReadData(RAMBuffer buffer) { Stances = new List <uint>(16); for (int i = 0; i < 16; ++i) { Stances.Add(buffer.ReadUInteger()); } return(this); }
/// <summary> /// Reads the data element from the given buffer. /// </summary> /// <param name="buffer">The buffer where the data element should be deserialized from.</param> public Diplomacy ReadData(RAMBuffer buffer) { StancesPerPlayer = new List <StancesToPlayers>(16); for (int i = 0; i < 16; ++i) { StancesPerPlayer.Add(new StancesToPlayers().ReadData(buffer)); } // Separator buffer.ReadByteArray(11520); ScenarioDataElementTools.AssertTrue(buffer.ReadUInteger() == 0xFFFFFF9D); AlliedVictoryObsolete = new List <uint>(16); for (int i = 0; i < 16; ++i) { AlliedVictoryObsolete.Add(buffer.ReadUInteger()); } return(this); }
/// <summary> /// Reads the data element from the given buffer. /// </summary> /// <param name="buffer">The buffer where the data element should be deserialized from.</param> public ResourcePopulationEntry ReadData(RAMBuffer buffer) { Gold = buffer.ReadFloat(); Wood = buffer.ReadFloat(); Food = buffer.ReadFloat(); Stone = buffer.ReadFloat(); Ore = buffer.ReadFloat(); Padding = buffer.ReadUInteger(); PopulationLimit = buffer.ReadFloat(); return(this); }
/// <summary> /// Reads the data element from the given buffer. /// </summary> /// <param name="buffer">The buffer where the data element should be deserialized from.</param> public Trigger ReadData(RAMBuffer buffer) { Enabled = buffer.ReadUInteger(); Looping = buffer.ReadUInteger(); State = buffer.ReadByte(); ShowAsObjective = buffer.ReadByte(); ObjectiveDescriptionIndex = buffer.ReadInteger(); Unknown = buffer.ReadUInteger(); Description = buffer.ReadString(buffer.ReadInteger()); Name = buffer.ReadString(buffer.ReadInteger()); int effectCount = buffer.ReadInteger(); Effects = new List <Effect>(effectCount); for (int i = 0; i < effectCount; i++) { Effects.Add(new Effect().ReadData(buffer)); } EffectDisplayIndices = new List <int>(effectCount); for (int i = 0; i < effectCount; i++) { EffectDisplayIndices.Add(buffer.ReadInteger()); } int conditionCount = buffer.ReadInteger(); Conditions = new List <Condition>(conditionCount); for (int i = 0; i < conditionCount; i++) { Conditions.Add(new Condition().ReadData(buffer)); } ConditionDisplayIndices = new List <int>(conditionCount); for (int i = 0; i < conditionCount; i++) { ConditionDisplayIndices.Add(buffer.ReadInteger()); } return(this); }
/// <summary> /// Reads the data element from the given buffer. /// </summary> /// <param name="buffer">The buffer where the data element should be deserialized from.</param> public Header ReadData(RAMBuffer buffer) { NextUnitIdToPlace = buffer.ReadUInteger(); float version = buffer.ReadFloat(); if (version != 1.22f) { throw new InvalidDataException($"Invalid secondary file version: '{version}'"); } PlayerNames = new List <string>(16); for (int i = 0; i < 16; ++i) { PlayerNames.Add(buffer.ReadString(256)); } PlayerNameDllIds = new List <uint>(16); for (int i = 0; i < 16; ++i) { PlayerNameDllIds.Add(buffer.ReadUInteger()); } PlayerData = new List <PlayerDataHeader>(16); for (int i = 0; i < 16; ++i) { PlayerData.Add(new PlayerDataHeader().ReadData(buffer)); } Unknown1 = buffer.ReadUInteger(); byte unknown = buffer.ReadByte(); // = 0 Unknown2 = buffer.ReadFloat(); short length = buffer.ReadShort(); OriginalFileName = buffer.ReadString(length); return(this); }
/// <summary> /// Reads the data element from the given buffer. /// </summary> /// <param name="buffer">The buffer where the data element should be deserialized from.</param> public Map ReadData(RAMBuffer buffer) { // Separator ScenarioDataElementTools.AssertTrue(buffer.ReadUInteger() == 0xFFFFFF9D); Player1CameraY = buffer.ReadInteger(); Player1CameraX = buffer.ReadInteger(); AiMapCode = buffer.ReadInteger(); MapWidth = buffer.ReadUInteger(); MapHeight = buffer.ReadUInteger(); Tiles = new List <List <MapTileTerrainData> >((int)MapWidth); for (int i = 0; i < MapWidth; ++i) { Tiles.Add(new List <MapTileTerrainData>((int)MapHeight)); for (int j = 0; j < MapHeight; ++j) { Tiles[i].Add(new MapTileTerrainData().ReadData(buffer)); } } return(this); }
/// <summary> /// Reads the data element from the given buffer. /// </summary> /// <param name="buffer">The buffer where the data element should be deserialized from.</param> public UnitEntry ReadData(RAMBuffer buffer) { PositionX = buffer.ReadFloat(); PositionY = buffer.ReadFloat(); PositionZ = buffer.ReadFloat(); Id = buffer.ReadUInteger(); UnitId = buffer.ReadUShort(); State = buffer.ReadByte(); Rotation = buffer.ReadFloat(); Frame = buffer.ReadUShort(); GarrisonId = buffer.ReadInteger(); return(this); }
/// <summary> /// Reads the data element from the given buffer. /// </summary> /// <param name="buffer">The buffer where the data element should be deserialized from.</param> public PlayerDiplomacyVarious ReadData(RAMBuffer buffer) { UnknownPlayerCount = buffer.ReadUInteger(); PlayerDiplomacyVariousEntries = new List <PlayerDiplomacyVariousEntry>(8); for (int i = 0; i < 8; i++) { PlayerDiplomacyVariousEntries.Add(new PlayerDiplomacyVariousEntry().ReadData(buffer)); } Unknown = buffer.ReadULong(); return(this); }
/// <summary> /// Reads the data element from the given buffer. /// </summary> /// <param name="buffer">The buffer where the data element should be deserialized from.</param> public ResourceEntry ReadData(RAMBuffer buffer) { Gold = buffer.ReadUInteger(); Wood = buffer.ReadUInteger(); Food = buffer.ReadUInteger(); Stone = buffer.ReadUInteger(); Ore = buffer.ReadUInteger(); Padding = buffer.ReadUInteger(); return(this); }
// Resources #endregion #region Functions /// <summary> /// Reads the data element from the given buffer. /// </summary> /// <param name="buffer">The buffer where the data element should be deserialized from.</param> public PlayerAiResources ReadData(RAMBuffer buffer) { UnknownStrings = new List <string>(32); for (int i = 0; i < 32; ++i) { UnknownStrings.Add(buffer.ReadString(buffer.ReadShort())); } AiNames = new List <string>(16); for (int i = 0; i < 16; ++i) { AiNames.Add(buffer.ReadString(buffer.ReadShort())); } AiFiles = new List <AiFile>(16); for (int i = 0; i < 16; ++i) { AiFiles.Add(new AiFile().ReadData(buffer)); } AiTypes = new List <byte>(16); for (int i = 0; i < 16; ++i) { AiTypes.Add(buffer.ReadByte()); } // Separator ScenarioDataElementTools.AssertTrue(buffer.ReadUInteger() == 0xFFFFFF9D); ResourceEntries = new List <ResourceEntry>(16); for (int i = 0; i < 16; ++i) { ResourceEntries.Add(new ResourceEntry().ReadData(buffer)); } return(this); }
/// <summary> /// Lädt die Bitmap-Datei aus dem angegebenen Puffer. /// </summary> /// <param name="buffer">Der Puffer, aus dem die Bitmap-Datei gelesen werden soll.</param> /// <param name="pal">Optional. Gibt die zu verwendende 256er-Farbtabelle an. Sonst wird die entweder die im Bitmap angegebene oder die 50500er-Farbtabelle verwendet.</param> /// <param name="readFileHeader">Optional. Gibt an, ob der Dateiheader gelesen werden oder direkt mit der BITMAPINFOHEADER-Struktur begonnen werden soll.</param> public BitmapLoader(RAMBuffer buffer, JASCPalette pal = null, bool readFileHeader = true) { // Header laden _header = new Header(); if (readFileHeader) { _header.type = buffer.ReadUShort(); _header.fileSize = buffer.ReadUInteger(); _header.reserved = buffer.ReadUInteger(); _header.offsetData = buffer.ReadUInteger(); } else { _header.type = 0x424D; _header.fileSize = 0; _header.reserved = 0; _header.offsetData = 54; } _header.imageHeaderSize = buffer.ReadUInteger(); _header.width = buffer.ReadInteger(); _header.height = buffer.ReadInteger(); _header.layerCount = buffer.ReadUShort(); _header.bitsPerPixel = buffer.ReadUShort(); _header.compression = buffer.ReadUInteger(); _header.size = buffer.ReadUInteger(); _header.xDPI = buffer.ReadInteger(); _header.yDPI = buffer.ReadInteger(); _header.colorCount = buffer.ReadUInteger(); _header.colorImportantCount = buffer.ReadUInteger(); // Farbtabellenanzahl nachjustieren if (_header.colorCount == 0 && _header.bitsPerPixel == 8) { _header.colorCount = 256; } // Farbtabelle laden bool needAdjustColorTable = false; if (_header.colorCount > 0) { // Bildfarbtabelle laden _colorTable = new ColorTable(ref buffer, _header.colorCount); // Falls eine Palette übergeben wurde, diese mit der Bildtabelle vergleichen if (pal == null || pal._farben.GetLength(0) != 256) { needAdjustColorTable = true; } else { for (int i = 0; i < 256; ++i) { // Farben vergleichen Color aktF = _colorTable[i]; if (pal._farben[i, 0] != aktF.R || pal._farben[i, 1] != aktF.G || pal._farben[i, 2] != aktF.B) { // Farbtabellen unterscheiden sich needAdjustColorTable = true; break; } } } } else { // Bei 24-Bit-Bitmaps wird die Farbtabelle später geladen _colorTable = null; } // Nach Bitzahl unterscheiden if (_header.bitsPerPixel == 8) { // Bilddatenbreite ggf. auf ein Vielfaches von 4 Bytes erhöhen int width = _header.width; // Hilfsvariable zur Performanceerhöhung (immer gleichwertig mit _header.width) int width2 = width; while (width2 % 4 != 0) { width2++; } // Binäre Original-Bilddaten einlesen _imageDataBin = buffer.ReadByteArray(width2 * Math.Abs(_header.height)); // Neues Bilddaten-Array anlegen (ohne Füllbytes) _imageData = new byte[width * Math.Abs(_header.height)]; // Richtung bestimmen bool dirTopDown = (_header.height < 0); // Der bisher nächste Farbindex byte nearestIndex = 0; // Der Abstand zum bisher nächsten Farbindex double nearestDistance; // Der aktuelle Farbabstand double tempDistance = 0.0; // Bilddaten abrufen int height2 = Math.Abs(_header.height); for (int x = 0; x < width2; x++) { for (int y = 0; y < height2; y++) { // Wenn es sich bei dem aktuellen Pixel um kein Füllbyte handelt, diesen übernehmen if (x < width) { // Pixel abrufen byte aktCol = _imageDataBin[y * width2 + x]; // TODO: 0-Indizes in 255 umwandeln?? // Falls nötig, Farben vergleichen if (needAdjustColorTable) { // Alle Farbwerte abrufen byte aktB = _colorTable[aktCol].B; byte aktG = _colorTable[aktCol].G; byte aktR = _colorTable[aktCol].R; // Die zur Pixelfarbe nächste Palettenfarbe suchen { // Werte zurücksetzen nearestIndex = 0; nearestDistance = 441.673; // Anfangswert: maximaler möglicher Abstand // Alle Einträge durchgehen for (int i = 0; i < 256; i++) { // Aktuelle Paletten-RGB-Werte abrufen byte pR = pal._farben[i, 0]; byte pG = pal._farben[i, 1]; byte pB = pal._farben[i, 2]; // Gleiche Einträge sofort filtern if (aktR == pR && aktB == pB && aktG == pG) { // Paletten-Index überschreiben nearestIndex = (byte)i; // Fertig break; } // Abstand berechnen (Vektorlänge im dreidimensionalen RGB-Farbraum) tempDistance = Math.Sqrt(Math.Pow(aktR - pR, 2) + Math.Pow(aktG - pG, 2) + Math.Pow(aktB - pB, 2)); // Vergleichen if (tempDistance < nearestDistance) { // Index merken nearestDistance = tempDistance; nearestIndex = (byte)i; } } // Paletten-Index überschreiben aktCol = nearestIndex; } } // Ende Adjust-ColorTable // Pixel zum Hauptbildarray hinzufügen und dabei nach Top-Down / Bottom-Up unterscheiden _imageData[(dirTopDown ? y : height2 - y - 1) * width + x] = aktCol; } } } } else if (_header.bitsPerPixel == 24) { // Es handelt sich um ein 24-Bit-Bitmap, somit muss eine Farbtabelle eingeführt werden { // Farbpalettenreader abrufen JASCPalette tempPal; if (pal == null) { tempPal = new JASCPalette(new RAMBuffer(BitmapLibrary.Properties.Resources.pal50500)); } else { tempPal = pal; } // Farbpaletteninhalt in eigene Farbtabelle schreiben _colorTable = new ColorTable(); for (int i = 0; i < tempPal._farben.GetLength(0); i++) { // Eintrag in Tabelle einfügen _colorTable[i] = Color.FromArgb(tempPal._farben[i, 0], tempPal._farben[i, 1], tempPal._farben[i, 2]); // Sicherheitshalber bei i = 255 abbrechen (falls Palette zu groß sein sollte) if (i == 255) { break; } } } // Bilddatenbreite ggf. auf ein Vielfaches von 4 Bytes erhöhen int width = _header.width; // Hilfsvariable zur Performanceerhöhung (immer gleichwertig mit _header.width) int fillBytes = 0; while (((width * 3) + fillBytes) % 4 != 0) { fillBytes++; } // Binäre Original-Bilddaten einlesen _imageDataBin = buffer.ReadByteArray((3 * width + fillBytes) * Math.Abs(_header.height)); // Neues Bilddaten-Array anlegen (ohne Füllbytes) _imageData = new byte[width * Math.Abs(_header.height)]; // Richtung bestimmen bool dirTopDown = (_header.height < 0); // Der bisher nächste Farbindex byte nearestIndex = 0; // Der Abstand zum bisher nächsten Farbindex double nearestDistance; // Der aktuelle Farbabstand double tempDistance = 0.0; // Bilddaten abrufen int height2 = Math.Abs(_header.height); for (int x = 0; x < width; x++) { for (int y = 0; y < height2; y++) { // Pixel abrufen byte aktB = _imageDataBin[y * (3 * width + fillBytes) + 3 * x]; byte aktG = _imageDataBin[y * (3 * width + fillBytes) + 3 * x + 1]; byte aktR = _imageDataBin[y * (3 * width + fillBytes) + 3 * x + 2]; // Die zur Pixelfarbe nächste Palettenfarbe suchen { // Werte zurücksetzen nearestIndex = 0; nearestDistance = 441.673; // Anfangswert: maximaler möglicher Abstand // Alle Einträge durchgehen for (int i = 0; i < 256; i++) { // Aktuelle Paletten-RGB-Werte abrufen byte pR = _colorTable[i].R; byte pG = _colorTable[i].G; byte pB = _colorTable[i].B; // Gleiche Einträge sofort filtern if (aktR == pR && aktB == pB && aktG == pG) { // Pixel zum Hauptbildarray hinzufügen und dabei nach Top-Down / Bottom-Up unterscheiden _imageData[(dirTopDown ? y : height2 - y - 1) * width + x] = (byte)i; // Fertig break; } // Abstand berechnen (Vektorlänge im dreidimensionalen RGB-Farbraum) tempDistance = Math.Sqrt(Math.Pow(aktR - pR, 2) + Math.Pow(aktG - pG, 2) + Math.Pow(aktB - pB, 2)); // Vergleichen if (tempDistance < nearestDistance) { // Index merken nearestDistance = tempDistance; nearestIndex = (byte)i; } } // Pixel zum Hauptbildarray hinzufügen und dabei nach Top-Down / Bottom-Up unterscheiden _imageData[(dirTopDown ? y : height2 - y - 1) * width + x] = nearestIndex; } } // Ggf. Füllbytes überspringen (bei Dateiende nicht) if (buffer.Position < buffer.Length - fillBytes) { buffer.Position = (buffer.Position + fillBytes); } } } }
/// <summary> /// Reads the data element from the given buffer. /// </summary> /// <param name="buffer">The buffer where the data element should be deserialized from.</param> public GlobalVictory ReadData(RAMBuffer buffer) { // Separator ScenarioDataElementTools.AssertTrue(buffer.ReadUInteger() == 0xFFFFFF9D); ConquestRequired = buffer.ReadUInteger(); Unused1 = buffer.ReadUInteger(); NumberOfRelicsRequired = buffer.ReadUInteger(); Unused2 = buffer.ReadUInteger(); ExploredPercentRequired = buffer.ReadUInteger(); Unused3 = buffer.ReadUInteger(); AllCustomConditionsRequired = buffer.ReadUInteger(); Mode = (VictoryMode)buffer.ReadUInteger(); ScoreRequired = buffer.ReadUInteger(); TimeRequired = buffer.ReadUInteger(); return(this); }
/// <summary> /// Reads the data element from the given buffer. /// </summary> /// <param name="buffer">The buffer where the data element should be deserialized from.</param> public Disables ReadData(RAMBuffer buffer) { List <int> disabledTechCountPerPlayer = new List <int>(16); for (int i = 0; i < 16; ++i) { disabledTechCountPerPlayer.Add(buffer.ReadInteger()); } DisabledTechsPerPlayer = new List <List <uint> >(16); for (int i = 0; i < 16; ++i) { if (disabledTechCountPerPlayer[i] < 0) { disabledTechCountPerPlayer[i] = 0; } DisabledTechsPerPlayer.Add(new List <uint>(disabledTechCountPerPlayer[i])); for (int j = 0; j < disabledTechCountPerPlayer[i]; ++j) { DisabledTechsPerPlayer[i].Add(buffer.ReadUInteger()); } buffer.ReadByteArray(4 * (30 - disabledTechCountPerPlayer[i])); } List <int> disabledUnitsCountPerPlayer = new List <int>(16); for (int i = 0; i < 16; ++i) { disabledUnitsCountPerPlayer.Add(buffer.ReadInteger()); } DisabledUnitsPerPlayer = new List <List <uint> >(16); for (int i = 0; i < 16; ++i) { if (disabledUnitsCountPerPlayer[i] < 0) { disabledUnitsCountPerPlayer[i] = 0; } DisabledUnitsPerPlayer.Add(new List <uint>(disabledUnitsCountPerPlayer[i])); for (int j = 0; j < disabledUnitsCountPerPlayer[i]; ++j) { DisabledUnitsPerPlayer[i].Add(buffer.ReadUInteger()); } buffer.ReadByteArray(4 * (30 - disabledUnitsCountPerPlayer[i])); } List <int> disabledBuildingsCountPerPlayer = new List <int>(16); for (int i = 0; i < 16; ++i) { disabledBuildingsCountPerPlayer.Add(buffer.ReadInteger()); } DisabledBuildingsPerPlayer = new List <List <uint> >(16); for (int i = 0; i < 16; ++i) { if (disabledBuildingsCountPerPlayer[i] < 0) { disabledBuildingsCountPerPlayer[i] = 0; } DisabledBuildingsPerPlayer.Add(new List <uint>(disabledBuildingsCountPerPlayer[i])); for (int j = 0; j < disabledBuildingsCountPerPlayer[i]; ++j) { DisabledBuildingsPerPlayer[i].Add(buffer.ReadUInteger()); } buffer.ReadByteArray(4 * (20 - disabledBuildingsCountPerPlayer[i])); } Unused1 = buffer.ReadUInteger(); Unused2 = buffer.ReadUInteger(); FullTechMode = buffer.ReadUInteger(); StartingAges = new List <int>(16); for (int i = 0; i < 16; ++i) { StartingAges.Add(buffer.ReadInteger()); } return(this); }