# Unbekannte Dateiformate von Baphomets Fluch



## dajos (5. Mai 2008)

Hallo,

ich bin auf den Spuren eines alten PC Games. Baphomets Fluch 1. Ich bin auf der Suche nach Dateiformaten. Ich habe versucht alle Daten aus den CLU Archiven, die das Game bereitstellt zu extrahieren.

Dank eines Tools ist das auch recht gut gelungen, allerdings habe ich ausser SMK und RIFF WAVE Dateien auch unbekannte Dateiformate entpackt, die mir so nichts sagen bzw ich auch so nichts im internet finden kann.

Das ganze hat nun wenig mit Java zu tun, als vielmehr mit 2D Animationen in Form von Dateiformaten.

Ich habe zB Eine binäre Datei die mit den Werten CDT beginnt und eine mit den Werten Sprite , also jeweils ein Buchstabe entspricht einem Byte.

Die Dateien sind auch nicht unbedingt größer als 300KByte. Ich vermute es handelt sich um die 2D Animationen und Hintergründe. Das Game hat eine Auflösung von 640 x 480 px und ich vermute zur damaligen zeit 1996 war es in einem 8 bit Modus. Man müsste da irgendwie was auslesen können, mir fehlt da etwas die Erfahrung.

Weiß jmd wie ich diese Dateien auslesen kann? Oder welche Anwendung hier weiterhelfen könnte?

Ich kann auch gerne 2-3 Dateien online stellen um hier genauere Analysen durchführen zu können.

Danke schonmal. Jeder Hinweis kann mich weiterbringen.

Gruss

dajos7


----------



## pyr0t0n (5. Mai 2008)

kann dir leider nicht mit deinem problem helfen, aber hier die beschäftigen sich seit mehreren Jahren mit einer inoffiziellen fortsetzung

vllt kannste denen ja ein paar geheimnisse entlocken.


http://www.baphometsfluch25.de/cms/index.php?id=37,0,0,1,0,0


----------



## dajos7 (5. Mai 2008)

Danke, die hab ich schon angeschrieben, ich warte auf Antwort, aber die haben sicherlich selbst recht viel zu tun, naja ich warte mal ab. Habe auch eben eins der Wallpapers zT auslesen können. Aber die Farben stimmen nicht. Die sind sicherlich irgenwie codiert.

Vlt kann mir damit jmd helfen? ich hab es als 8bit mit 3bit rot 3bit grün und 2 bit Blau ausgelesen.

DATEI: 007ECFDC.2

Original (ohne den Charakter  )






Mein jämmerlicher Versuch


----------



## The_S (6. Mai 2008)

Zeig doch mal den Code für deinen jämmerlichen Versuch - dann müssen die Tüfftler unter uns schon zumindest nicht auch einen jämmerlichen Versuch von 0 auf starten  .


----------



## ARadauer (6. Mai 2008)

das passt doch schon,
da feigelts nur noch an der farbe...


----------



## dajos7 (6. Mai 2008)

Uh ja ich geb mal den Code:

Sorry der Code ist nur provesorisch, da ich diesen erst wieder heute abend zur hand habe, aber der Hauptkern entspricht dem Originalen. Werde den vollen Source heute abend posten.

Ich habe auch schon diverse umstellungen der Farbwerte versucht .. vergeblich. Kann es sein, dass hier ein Wert addiert oder subtrahiert wurde, um eine simple kodierung zu erreichen?


```
//Also ich öffne die Datei normal über nen FileInputStream und gebe es dann in einen DataInputStream
//für die darstellung benutze ich simple ein BufferedImage mit TYPE_INT_RGB

//Und manipuliere dann über das Raster die einzelnen Pixel
//Ich lese direkt vom Anfang der Datei ohne Header

int width = 600;
int height = 400;

for (int y = 0; y < height; y++) {
   for (int x = 0; x < width; x++) {

      int value = dos.read();

      int value1 = (value & 0xE0) >> 5 ;
      value1 = 256 * value1 / 8; //3bit auf 8bit hochrechnen ?

      int value2 = (value & 0x1C)  >> 2;
      value2 = 256 * value2 / 8; //3bit auf 8bit hochrechnen ?

      int value3 = (value & 0x03) ;
      value3 = 256 * value3 / 4; //2bit auf 8bit hochrechnen ?

       raster.setPixel(x,y,new int[] {value1,value2,value3});


  }
}

//Das ganze gebe ich dann auf einem JLabel als Icon aus.

dos.flush();
dos.close();

//und den anderen kram noch schliessen
```


----------



## Evil-Devil (6. Mai 2008)

Im Header könnten eventuell Informationen zu einer Farbpalette stehen, denn die volle Farbpalette wurde aus Platzmangel selten genutzt und entsprechend nur eine Palette von 256 Farben.


----------



## Illuvatar (6. Mai 2008)

Das einzige was mir auffällt sind eventuelle Rundungsfehler, ich würde die Zeilen 17/20/23 auf etwas wie

```
value1 = (int)(256 * value1 / 8.0);
```
ändern.

Ansonsten, sicher dass das mit 3/3/2bit etc. stimmt?


----------



## The_S (6. Mai 2008)

Hm, also ich glaube nicht, dass das Teil nen Header hat. Bin gerade ein bisschen am analysieren der bits und bytes und dabei ist mir folgendes aufgefallen:

Erster Pixel des Originalbildes (R,G,B) in Bit

10101 111 10110

Erste 3 Bytes der .C Datei

10101100 00111001 01000100

Kann aber auch paranoia sein


----------



## pyr0t0n (6. Mai 2008)

also die datei hat keinen header soviel kann ich euch dazu sagen ^^


----------



## SlaterB (6. Mai 2008)

sind nicht auch C-Zahlen anders kodiert, höchstes Bit/ kleinstes Bit, unsigned usw.?
du machst du ja schon ne Menge, aber vielleicht noch nicht genug,

wenn du mehr Code postest (wie wird aus dem Raster ein Bild)
dann würde ich da gerne auch bisschen basteln


----------



## dajos7 (6. Mai 2008)

Illuvatar hat gesagt.:
			
		

> Das einzige was mir auffällt sind eventuelle Rundungsfehler, ich würde die Zeilen 17/20/23 auf etwas wie
> 
> ```
> value1 = (int)(256 * value1 / 8.0);
> ...


ja das mit der fliesskommazahl hab ich gestern abend auch noch versucht. das wars aber leider auch nicht.

das mit den 3/3/2 hab ich aus wikipedia Farbtiefe unten die Tabelle.



> Hm, also ich glaube nicht, dass das Teil nen Header hat. Bin gerade ein bisschen am analysieren der bits und bytes und dabei ist mir folgendes aufgefallen:
> Erster Pixel des Originalbildes (R,G,B) in Bit
> 10101 111 10110
> Erste 3 Bytes der .C Datei
> ...


Das ist interessant, das ist mir noch nicht aufgefallen. Wenn der 2te und 3te pixel auch so codiert sind, dann wäre da ja ein Muster.. gleich mal nachschauen  Aber das ist ja alles in JPG kodiert, vlt kann man daher die pixel nicht direkt vergleichen? ich kann mein Bild auch nochmal als BMP posten... mach ich heut abend


Mein Arbeitskollege hatte hier eine super idee. Einfach ein Leeres BMP in 8bit Modus mit 600 x 400 erzeugen und anfangs- und endpixel setzen (zB schw / weiss) als markierung nutzen und dann die binären Daten der Datei in das BMP-Frame einfügen... vlt klappt das ja.


600 x 400 = 240.000 pixel  DATEI ist aber 256.000 Bytes gross. Macht nen Unterschied von 16000 Byte.


----------



## The_S (6. Mai 2008)

Joa, die Differenz ist mir auch schon aufgefallen ???:L . Was man daraus schließen kann ist mir auch schleierhaft.

Meinen Vergleich kann man durchaus weiter verfolgen, aber dadurch, dass du nur ein jpg und kein png oder bmp hast (png ist besser  ) und das Bild auch nicht den 600x400 entspricht wird das eher ungenau und schwierig. Um mein Beispiel ein bisschen zu erweitern:

Erste Pixel des Originalbildes (R,G,B) in Bit (horizontal)

10101 111 10110
100101 10011 100011
11011 10 10101
101111 10010 100110
111110 11110 110011
1001011 101011 1000000

Erste 3 Bytes der .C Datei

*10101*100 00*111*00*1 0100*0*100 101*01*100 01*100*100 011*00000 01100000 01100000 01100000 00100110 00111001 00010100 00111001 01100100 10101100 10101100

Aber danach verliert sich die Spur (was aber auch an der Farbverfälschung, der falschen Auflösung des Originals liegen könnte und/oder der Codierung, die bei "extremeren" Werten stärker zu buche schlägt).

Sollte das aber wirklich zur Lösung führen, steckt da noch ne ganze Menge mehr dahinter, weil 5,5 Bytes für 2 Pixel sind bei 256000 Bytes zu 240000 Pixel nicht wirklich möglich  .


----------



## dajos7 (6. Mai 2008)

Hobbit_Im_Blutrausch hat gesagt.:
			
		

> Aber danach verliert sich die Spur (was aber auch an der Farbverfälschung, der falschen Auflösung des Originals liegen könnte und/oder der Codierung, die bei "extremeren" Werten stärker zu buche schlägt).
> 
> Sollte das aber wirklich zur Lösung führen, steckt da noch ne ganze Menge mehr dahinter, weil 5,5 Bytes für 2 Pixel sind bei 256000 Bytes zu 240000 Pixel nicht wirklich möglich  .



Werde mal noch einen screenshot des original games mit der Szene machen, dann stimmt alles. Und werd es als BMP hochladen unkomprimiert, dann kann man direkt vergleichen. Im Prinzip könnte man auch so das ganze game direkt in eigene formate mit snapshots überführen, aber das ist ein riesen Aufwand 

Nachher wird es eh nochmals zu 256 x 192 pixel heruntergerechnet um es auf dem nintendoDS überhaupt anzeigen zu können. Hatte noch gar nicht erwähnt was ich damit eigentlich vor habe... Is vlt recht hoch gegriffen, aber möchte mich an einer Portierung des games auf den nintendo DS bemühen, es gibt das schon für den GBA, aber es geht mir um die erfahrung, und da mir das game so super gefällt, dachte ich versuch ich mich daran mal. Wird lange dauern, aber ich versuchs einfach mal ...


----------



## The_S (6. Mai 2008)

Ich könnte mir auch noch vorstellen, dass die 16.000 Bytes am Ende ein Footer sind, der den Dateiaufbau beschreibt ...


----------



## dajos7 (6. Mai 2008)

Hobbit_Im_Blutrausch hat gesagt.:
			
		

> Ich könnte mir auch noch vorstellen, dass die 16.000 Bytes am Ende ein Footer sind, der den Dateiaufbau beschreibt ...



Halt Fehler von mir ....

Es sind 640 x 400. Das Game hat eine 4:3 Auflösung von 640 x 480 px , aber durch menübalken am oberen und unteren Rand sind es nur 640 x 400, was genau den 256KBytes entspricht.

Sorry mein Fehler. Also es sind nicht 600 sondern 640 px in der Breite.


----------



## dajos7 (6. Mai 2008)

So der Quelltext ist da:

Wurde mit dem VE von Eclipse zusammengeklickt.

Klasse ImgCalc

```
package de;

import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;

import javax.swing.JOptionPane;

public class ImgCalc {

	
	
	public static BufferedImage readImg(int width, int height, String path, boolean red, boolean green, boolean blue) {
		
		
		BufferedImage bi = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
		WritableRaster raster = bi.getRaster();
		
		try {
		
			FileInputStream fis = new FileInputStream(new File("C:\\007ECFDC.2"));		
			DataInputStream dis = new DataInputStream(fis);
			
			
			for (int y =0; y < height; y++) {
				for (int x =0; x < width; x++) {
				
					int value = dis.read();
					
					int value_red = (value & 0xE0) >> 5;
					
					if (red) {
						value_red = (int)(32.0f * value_red);
					} else {
						value_red = 0;
					}
					
					int value_green = (value & 0x1C) >> 2;
					if (green) {
						value_green = (int)(32.0f * value_green);
					} else {
						value_green = 0;
					}
					
					
					int value_blue = (value & 0x03);
					
					if (blue) {
						value_blue = (int)(64.0f * value_blue);
					} else {
						value_blue = 0;
					}
					
					raster.setPixel(x,y,new int[] {value_red,value_green,value_blue});
					
				}				
			}
			
			dis.close();
			fis.close();
			
		} catch (Exception ex) {
			JOptionPane.showMessageDialog(null, "Fehler ist aufgetreten "+ex, "Fehler", JOptionPane.ERROR_MESSAGE);
		}
		
		return bi;
		
	}
	
	
}
```


Die Klasse MainApp mit main methode


```
package de;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.JTextField;
import javax.swing.JCheckBox;
import java.awt.Point;

public class MainApp extends JFrame {

	private static final long serialVersionUID = 1L;
	private JPanel jContentPane = null;
	private JPanel jPanel = null;
	private JButton jButton = null;
	private JLabel jLabel = null;
	private JTextField jTextFieldWidth = null;
	private JLabel jLabel1 = null;
	private JLabel jLabel2 = null;
	private JTextField jTextFieldHeight = null;
	private JTextField jTextFieldPath = null;
	private JLabel jLabel3 = null;
	private JCheckBox jCheckBoxRed = null;
	private JCheckBox jCheckBoxGreen = null;
	private JCheckBox jCheckBoxBlue = null;
	private JLabel jLabel4 = null;

	/**
	 * This method initializes jPanel	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getJPanel() {
		if (jPanel == null) {
			jLabel4 = new JLabel();
			jLabel4.setBounds(new Rectangle(11, 240, 90, 19));
			jLabel4.setText("Color layers:");
			jLabel3 = new JLabel();
			jLabel3.setBounds(new Rectangle(7, 180, 30, 14));
			jLabel3.setText("Path:");
			jLabel2 = new JLabel();
			jLabel2.setBounds(new Rectangle(6, 135, 54, 14));
			jLabel2.setText("Height:");
			jLabel1 = new JLabel();
			jLabel1.setBounds(new Rectangle(5, 89, 53, 14));
			jLabel1.setText("Width:");
			jPanel = new JPanel();
			jPanel.setLayout(null);
			jPanel.setPreferredSize(new Dimension(150, 150));
			jPanel.add(getJButton(), null);
			jPanel.add(getJTextFieldWidth(), null);
			jPanel.add(jLabel1, null);
			jPanel.add(jLabel2, null);
			jPanel.add(getJTextFieldHeight(), null);
			jPanel.add(getJTextFieldPath(), null);
			jPanel.add(jLabel3, null);
			jPanel.add(getJCheckBoxRed(), null);
			jPanel.add(getJCheckBoxGreen(), null);
			jPanel.add(getJCheckBoxBlue(), null);
			jPanel.add(jLabel4, null);
		}
		return jPanel;
	}

	/**
	 * This method initializes jButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getJButton() {
		if (jButton == null) {
			jButton = new JButton();
			jButton.setBounds(new Rectangle(12, 18, 124, 43));
			jButton.setText("Read it");
			jButton.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					try {
						BufferedImage img = ImgCalc.readImg(
							Integer.parseInt(jTextFieldWidth.getText()),
							Integer.parseInt(jTextFieldHeight.getText()),
							jTextFieldPath.getText(),
							jCheckBoxRed.isSelected(),
							jCheckBoxGreen.isSelected(),
							jCheckBoxBlue.isSelected()
						);
						
						ImageIcon iconImage = new ImageIcon(img);
						jLabel.setIcon(iconImage);
						jLabel.repaint();
						
					} catch (Exception ex) {
						JOptionPane.showMessageDialog(null, "Fehler ist aufgetreten "+ex, "Fehler", JOptionPane.ERROR_MESSAGE);
					}
					
					
					
					
				}
			});
		}
		return jButton;
	}

	/**
	 * This method initializes jTextFieldWidth	
	 * 	
	 * @return javax.swing.JTextField	
	 */
	private JTextField getJTextFieldWidth() {
		if (jTextFieldWidth == null) {
			jTextFieldWidth = new JTextField();
			jTextFieldWidth.setBounds(new Rectangle(4, 104, 78, 19));
			jTextFieldWidth.setText("640");
		}
		return jTextFieldWidth;
	}

	/**
	 * This method initializes jTextFieldHeight	
	 * 	
	 * @return javax.swing.JTextField	
	 */
	private JTextField getJTextFieldHeight() {
		if (jTextFieldHeight == null) {
			jTextFieldHeight = new JTextField();
			jTextFieldHeight.setBounds(new Rectangle(5, 150, 78, 19));
			jTextFieldHeight.setText("400");
		}
		return jTextFieldHeight;
	}

	/**
	 * This method initializes jTextFieldPath	
	 * 	
	 * @return javax.swing.JTextField	
	 */
	private JTextField getJTextFieldPath() {
		if (jTextFieldPath == null) {
			jTextFieldPath = new JTextField();
			jTextFieldPath.setBounds(new Rectangle(7, 195, 130, 19));
			jTextFieldPath.setText("C:\\007ECFDC.2");
		}
		return jTextFieldPath;
	}

	/**
	 * This method initializes jCheckBoxRed	
	 * 	
	 * @return javax.swing.JCheckBox	
	 */
	private JCheckBox getJCheckBoxRed() {
		if (jCheckBoxRed == null) {
			jCheckBoxRed = new JCheckBox();
			jCheckBoxRed.setText("Red");
			jCheckBoxRed.setLocation(new Point(15, 258));
			jCheckBoxRed.setSelected(true);
			jCheckBoxRed.setSize(new Dimension(74, 21));
		}
		return jCheckBoxRed;
	}

	/**
	 * This method initializes jCheckBoxGreen	
	 * 	
	 * @return javax.swing.JCheckBox	
	 */
	private JCheckBox getJCheckBoxGreen() {
		if (jCheckBoxGreen == null) {
			jCheckBoxGreen = new JCheckBox();
			jCheckBoxGreen.setText("Green");
			jCheckBoxGreen.setLocation(new Point(15, 277));
			jCheckBoxGreen.setSelected(true);
			jCheckBoxGreen.setSize(new Dimension(83, 22));
		}
		return jCheckBoxGreen;
	}

	/**
	 * This method initializes jCheckBoxBlue	
	 * 	
	 * @return javax.swing.JCheckBox	
	 */
	private JCheckBox getJCheckBoxBlue() {
		if (jCheckBoxBlue == null) {
			jCheckBoxBlue = new JCheckBox();
			jCheckBoxBlue.setText("Blue");
			jCheckBoxBlue.setLocation(new Point(15, 297));
			jCheckBoxBlue.setSelected(true);
			jCheckBoxBlue.setSize(new Dimension(67, 21));
		}
		return jCheckBoxBlue;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				MainApp thisClass = new MainApp();
				thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				thisClass.setVisible(true);
			}
		});
	}

	/**
	 * This is the default constructor
	 */
	public MainApp() {
		super();
		initialize();
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		this.setSize(853, 580);
		this.setContentPane(getJContentPane());
		this.setTitle("Image Reader");
	}

	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			jLabel = new JLabel();
			jLabel.setText("");
			jContentPane = new JPanel();
			jContentPane.setLayout(new BorderLayout());
			jContentPane.add(getJPanel(), BorderLayout.WEST);
			jContentPane.add(jLabel, BorderLayout.CENTER);
		}
		return jContentPane;
	}

}  //  @jve:decl-index=0:visual-constraint="10,10"
```


----------



## dajos7 (6. Mai 2008)

Habe noch die vermutung es könnte am Farbraum liegen?
Werde es noch mit ein paar Umrechnungen versuchen Farbräume Umrechnen

Habe auch noch den Header einer 8bit BMP genommen und die binären Daten durch die in der .C datei. Es wird etwas anzeigt, aber leider nur ein vollkommen schwarzes Bild.

Ich verzweifel langsam, das muss man doch auslesen können 

So hier noch die bilder im BMP. Müssten genau übereinstimmen.


----------



## The_S (7. Mai 2008)

OK, das Spiel verwendet (wie ich dann gestern auch irgendwann vermutet habe) eine Farbpalette. Ist jetzt nur die Frage, ob für alle Bilder die selbe Palette gilt, oder pro Bild eine unterschiedliche. Ich tendiere aber zu zweiteren. Du solltest wohl rausfinden wo die Farbpalette gespeichert wird. Für dieses Bild lautet sie wie folgt:

Byte 1 = -10277864 RGB
Byte 2 = -14086120 RGB
Byte 3 = -7573199 RGB
Byte 4 = -16247784 RGB
Byte 5 = -13552607 RGB
Byte 6 = -4357566 RGB
Byte 7 = -10267343 RGB
Byte 8 = -16773071 RGB
Byte 9 = -10267318 RGB
Byte 10 = -13552566 RGB
Byte 11 = -16777192 RGB
Byte 12 = -14086095 RGB
Byte 13 = -3760484 RGB
Byte 14 = -8686221 RGB
Byte 15 = -10864574 RGB
Byte 16 = -7579310 RGB
Byte 17 = -12438504 RGB
Byte 18 = -13035504 RGB
Byte 19 = -16241598 RGB
Byte 20 = -15726568 RGB
Byte 21 = -15199216 RGB
Byte 22 = -7046863 RGB
Byte 23 = -13021870 RGB
Byte 24 = -9223912 RGB
Byte 25 = -4880764 RGB
Byte 26 = -12441551 RGB
Byte 27 = -8102623 RGB
Byte 28 = -9218734 RGB
Byte 29 = -12438471 RGB
Byte 30 = -1059923 RGB
Byte 31 = -14081000 RGB
Byte 32 = -8673660 RGB
Byte 33 = -7046822 RGB
Byte 34 = -9222846 RGB
Byte 35 = -10868687 RGB
Byte 36 = -16777208 RGB
Byte 37 = -15697590 RGB
Byte 38 = -14610399 RGB
Byte 39 = -8101533 RGB
Byte 40 = -15197135 RGB
Byte 41 = -13019789 RGB
Byte 42 = -16776151 RGB
Byte 43 = -13555663 RGB
Byte 45 = -13035479 RGB
Byte 46 = -13029327 RGB
Byte 47 = -16767959 RGB
Byte 48 = -16239526 RGB
Byte 49 = -9213614 RGB
Byte 50 = -3756412 RGB
Byte 52 = -3239325 RGB
Byte 53 = -8104647 RGB
Byte 54 = -5932685 RGB
Byte 55 = -10861263 RGB
Byte 56 = -8687270 RGB
Byte 57 = -15726576 RGB
Byte 58 = -10271414 RGB
Byte 59 = -15202263 RGB
Byte 60 = -14086111 RGB
Byte 61 = -9227215 RGB
Byte 62 = -11918295 RGB
Byte 63 = -16769982 RGB
Byte 64 = -5933734 RGB
Byte 65 = -10267302 RGB
Byte 66 = -14605288 RGB
Byte 67 = -11913142 RGB
Byte 68 = -16777183 RGB
Byte 69 = -16772055 RGB
Byte 70 = -14080991 RGB
Byte 71 = -5937838 RGB
Byte 72 = -13557711 RGB
Byte 73 = -14605279 RGB
Byte 74 = -11917246 RGB
Byte 75 = -12421814 RGB
Byte 76 = -4334617 RGB
Byte 77 = -6504754 RGB
Byte 78 = -2704740 RGB
Byte 79 = -13553607 RGB
Byte 80 = -10267326 RGB
Byte 81 = -6527645 RGB
Byte 82 = -14602191 RGB
Byte 83 = -11909831 RGB
Byte 84 = -7046838 RGB
Byte 85 = -8689318 RGB
Byte 86 = -13555646 RGB
Byte 87 = -10276815 RGB
Byte 88 = -15202280 RGB
Byte 89 = -5930364 RGB
Byte 90 = -6527687 RGB
Byte 91 = -10270382 RGB
Byte 92 = -7571110 RGB
Byte 93 = -12400731 RGB
Byte 94 = -11913175 RGB
Byte 95 = -7584438 RGB
Byte 96 = -13033431 RGB
Byte 97 = -10272488 RGB
Byte 98 = -16777200 RGB
Byte 99 = -4883110 RGB
Byte 100 = -14084055 RGB
Byte 101 = -7585487 RGB
Byte 102 = -8098478 RGB
Byte 103 = -15722447 RGB
Byte 104 = -13558727 RGB
Byte 105 = -11917263 RGB
Byte 106 = -14609384 RGB
Byte 107 = -1591685 RGB
Byte 108 = -12436431 RGB
Byte 109 = -13547231 RGB
Byte 110 = -11383478 RGB
Byte 111 = -14600102 RGB
Byte 112 = -13555671 RGB
Byte 113 = -15197127 RGB
Byte 114 = -13550493 RGB
Byte 115 = -6528735 RGB
Byte 116 = -15719400 RGB
Byte 117 = -11918320 RGB
Byte 118 = -6520230 RGB
Byte 119 = -1054754 RGB
Byte 120 = -9217702 RGB
Byte 121 = -7570036 RGB
Byte 122 = -9739958 RGB
Byte 123 = -16251904 RGB
Byte 124 = -16775119 RGB
Byte 125 = -5923196 RGB
Byte 126 = -14608351 RGB
Byte 127 = -11388862 RGB
Byte 128 = -11912093 RGB
Byte 129 = -15723487 RGB
Byte 130 = -9739942 RGB
Byte 131 = -16251880 RGB
Byte 132 = -13542087 RGB
Byte 133 = -3235147 RGB
Byte 134 = -4352380 RGB
Byte 135 = -8100551 RGB
Byte 136 = -13030351 RGB
Byte 137 = -6519222 RGB
Byte 138 = -9221806 RGB
Byte 139 = -16198805 RGB
Byte 140 = -10275783 RGB
Byte 141 = -9740990 RGB
Byte 142 = -7572150 RGB
Byte 143 = -15191998 RGB
Byte 144 = -7578278 RGB
Byte 145 = -16775135 RGB
Byte 146 = -9203110 RGB
Byte 147 = -3236253 RGB
Byte 148 = -13029335 RGB
Byte 149 = -3765670 RGB
Byte 150 = -16235207 RGB
Byte 151 = -8100501 RGB
Byte 152 = -5928358 RGB
Byte 153 = -8690317 RGB
Byte 154 = -11389895 RGB
Byte 155 = -7585520 RGB
Byte 156 = -9747126 RGB
Byte 157 = -13014619 RGB
Byte 158 = -11914216 RGB
Byte 159 = -16245703 RGB
Byte 160 = -6526605 RGB
Byte 161 = -10274742 RGB
Byte 162 = -5932677 RGB
Byte 163 = -16242647 RGB
Byte 164 = -14081999 RGB
Byte 165 = -11910838 RGB
Byte 166 = -9217751 RGB
Byte 167 = -14612447 RGB
Byte 168 = -13026255 RGB
Byte 169 = -9222863 RGB
Byte 170 = -14083056 RGB
Byte 171 = -11383470 RGB
Byte 172 = -16251888 RGB
Byte 173 = -15723504 RGB
Byte 174 = -13031408 RGB
Byte 175 = -2179395 RGB
Byte 176 = -16244670 RGB
Byte 177 = -13031383 RGB
Byte 179 = -10271439 RGB
Byte 180 = -12437447 RGB
Byte 181 = -10865615 RGB
Byte 182 = -7047821 RGB
Byte 183 = -10270357 RGB
Byte 200 = -16777216 RGB
Byte 236 = -16244670 RGB

generiert (inkl. Hintergrundbild) durch diesen Code


```
BufferedImage img = ImageIO.read(new File("C:/orig.png"));
		
		FileInputStream fis = new FileInputStream(new File("C:/col.2"));
		int t = 0;
		
		for (int y = 0; y < img.getHeight(); y++) {
			for (int x = 0; x < img.getWidth(); x++) {
				t = fis.read();
				map.put(new Integer(t), new Integer(img.getRGB(x , y)));
			}
		}
		
		fis.close();
		fis = new FileInputStream(new File("C:/col.2"));
		
		for (int y = 0; y < img.getHeight(); y++) {
			for (int x = 0; x < img.getWidth(); x++) {
				img.setRGB(x, y, ((Integer)map.get(new Integer(fis.read()))).intValue());
			}
		}
		
		ImageIO.write(img, "png", new File("C:/co.png"));
		
		Vector vec = new Vector(map.keySet());
		Collections.sort(vec);
		for (int i = 0; i < vec.size(); i++) {
			System.out.println("Byte " + vec.elementAt(i) + " = " + map.get(new Integer(vec.elementAt(i).toString())) + " RGB");
		}
```


----------



## SlaterB (7. Mai 2008)

interessante Sache,
warum sind png oder zumindest bmp nicht größer, verwenden die auch Farbpalette?
bmp kannte ich ja bisher eher als Pixel-für-Pixel-Format, sind da auch mehr als 256 Farben möglich -> mehr Bytes pro Pixel?

um auch noch was beizutragen: für die 256 Bytes aus der Datei reicht ein Array statt einer Map und hundertausender Integer-Objekte  :bae: 


```
BufferedImage img = ImageIO.read(new File("orig.png"));

        FileInputStream fis = new FileInputStream(new File("007ECFDC.2"));
        int t = 0;
        int[] a = new int[256];
        int count = 0;
        for (int y = 0; y < img.getHeight(); y++)
        {
            for (int x = 0; x < img.getWidth(); x++)
            {
                t = fis.read();
                if (a[t] == 0)
                {
                    a[t] = img.getRGB(x, y);
                }
                else if (a[t] != img.getRGB(x, y))
                {
                    count++;
                }
            }
        }
        System.out.println("count: " + count);
        fis.close();
        fis = new FileInputStream(new File("007ECFDC.2"));

        for (int y = 0; y < img.getHeight(); y++)
        {
            for (int x = 0; x < img.getWidth(); x++)
            {
                img.setRGB(x, y, a[fis.read()]);
            }
        }

        ImageIO.write(img, "png", new File("co2.png"));
        for (int i = 0; i < 256; i++)
        {
            System.out.println("Byte " + i + " = " + a[i] + " RGB");
        }
```

die paar unterschiedlichen Stellen in den Bildern haben keine Auswirkungen,
für meinen Code sind alle fraglichen Farben schon vorher korrekt gesetzt, bei dem vom Hobbit nachher nochmal
bei 4527 Bytes weichen die Bilder voneinander ab,

Spielerei: ein Bild mit den Abweichungen + erstes Vorkommen aller Farben:


```
BufferedImage img = ImageIO.read(new File("orig.png"));

        FileInputStream fis = new FileInputStream(new File("007ECFDC.2"));
        int t = 0;
        int[] a = new int[256];
        for (int y = 0; y < img.getHeight(); y++)
        {
            for (int x = 0; x < img.getWidth(); x++)
            {
                t = fis.read();
                if (a[t] == 0)
                {
                    a[t] = img.getRGB(x, y);
                }
                else if (a[t] != img.getRGB(x, y))
                {
                    img.setRGB(x, y, a[1]);
                } else {
                    img.setRGB(x, y,  0);
                }
            }
        }
        ImageIO.write(img, "png", new File("co2.png"));
```


----------



## SlaterB (7. Mai 2008)

mit 3 Bit Rot/ 3 Bit Grün/ 2 Bit Blau siehts auch noch erstaunlich gut aus:

```
BufferedImage img = ImageIO.read(new File("orig.png"));

        FileInputStream fis = new FileInputStream(new File("007ECFDC.2"));
        int t = 0;
        int[] a = new int[256];
        int k = 0;
        for (int y = 0; y < img.getHeight(); y++)
        {
            for (int x = 0; x < img.getWidth(); x++)
            {
                t = fis.read();
                if (a[t] == 0)
                {
                    k++;
                    int rgb = img.getRGB(x, y);
                    int rot = (rgb >> 16) & 0xff;
                    rot = (int)(Math.round(rot / 32.) * 32);
                    int gruen = (rgb >> 8) & 0xff;
                    gruen = (int)(Math.round(gruen / 32.) * 32);
                    int blau = rgb & 0xff;
                    blau = (int)(Math.round(blau / 64.) * 64);
                    int alpha = rgb >> 24;

                    rgb = (alpha << 24) + (rot << 16) + (gruen << 8) + blau;

                    a[t] = rgb;

                }
                img.setRGB(x, y, a[t]);
            }
        }
        ImageIO.write(img, "png", new File("co3.png"));
```
den Einfluss von Alpha kenne ich gerade nicht so genau, macht vielleicht ne Menge aus, sind ja auch 8 Bit?


----------



## The_S (7. Mai 2008)

SlaterB hat gesagt.:
			
		

> warum sind png oder zumindest bmp nicht größer, verwenden die auch Farbpalette?



png verwendet ganz kryptische Methoden, die ich noch nie gecheckt habe ^^ (verschiedene Filter, Komprimierung, ...).Am besten mal den entsprechenden Wiki-Eintrag lesen, dort ist das ganz gut erklärt http://de.wikipedia.org/wiki/Portable_Network_Graphics#Technische_Details

Und BMP ist ja wohl mal das Größte überhaupt - normalerweise gar nicht komprimiert bzw. bestenfalls nur sehr schwach 



			
				SlaterB hat gesagt.:
			
		

> um auch noch was beizutragen: für die 256 Bytes aus der Datei reicht ein Array statt einer Map und hundertausender Integer-Objekte



Da ich nicht wusste *ob* und wenn ja *wie* eine Farbpalette verwendet wurde, und ich gerade nur n 1.4.2er JDK hatte, war das die schnellste Möglichkeit um rauszufinden ob und wie sie verwendet wird und dann gleich ohne große Fehlerbehandlung wieder auszugeben. Und anschließend war ich einfach zu faul nochmal meinen Code zu optimieren  .


----------



## SlaterB (7. Mai 2008)

> Und BMP ist ja wohl mal das Größte überhaupt - normalerweise gar nicht komprimiert bzw. bestenfalls nur sehr schwach 

ja, aber die org.bmp-Datei ist nunmal nur 250 kb groß, genau wie die kompoliziert zusammengesparte 007ECFDC.2-Datei (1078 Bytes größer),
also wird da wohl auch eine Farbtabelle sein


----------



## The_S (7. Mai 2008)

joa, standardfarbtabelle eben 



			
				wiki hat gesagt.:
			
		

> *1, 4 oder 8 bpp:*
> Die Daten jedes Pixels bestehen aus einem 0-basierten Index auf den Eintrag in der Farbtabelle.


----------



## The_S (7. Mai 2008)

SlaterB hat gesagt.:
			
		

> mit 3 Bit Rot/ 3 Bit Grün/ 2 Bit Blau siehts auch noch erstaunlich gut aus:



evtl. kommt das sehr nahe an die Standard-Farbpalette hin ... sollte man auch weiterverfolgen, deinen Ansatz.

Aber erstmal auf Feedback des Thread-Stellers warten ...


----------



## SlaterB (7. Mai 2008)

ob Standard oder nicht ist ja egal,
da ist ja nur die vorgegebene beliebige Tabelle auf gerundete Werte gekürzt,

hat jetzt auch keine echte Relevanz, du hattes ja das Coding geklärt,
nur Spielereien mit diesem mit immer wieder neuen Thema

alle paar Monate frage ich mich ab und zu mal, wie man eigentlich ein simples Bild simpel Pixel für Pixel einliest,
aber Code-Beispiele dafür zu suchen ist immer ein Krampf


----------



## dajos7 (7. Mai 2008)

*@SlaterB*
Als ich gestern versucht hatte die 007ECFDC.2-Datei in ein Bitmap einzufügen, war hinter dem Standardheader für das Windows Bitmap noch ein haufen Platz, bevor die Bilddaten angefangen haben, da ist wohl wirklich eine Palette möglich.

Bei deinem Versuch sieht man echt schön, wo die Layers der 2D Sprites auf dem Hintergrund liegen.



*@Hobbit_Im_Blutrausch*
Wird also eine Palette verwendet. Super. Danke. Ich werde mich dann mal gleich auf die Suche machen. Das Game hat entpackt mehrere hundert Dateien, wird evtl etwas dauern bis ich die gefunden habe.

Ich habe allerdings noch eine weitere Frage. Es gibt noch mehr Dateien, die mir unbekannt sind
zB die mit den Binären Daten "Sprite" beginnen. Als hex ist das 53 70 72 69 74 65. Ich werde dazu auch noch eine Datei hochladen. Vermutung, dass darin die 2D sprites versteckt sind. Frage ist hier, ob nur die Änderungen abgespeichert wurden in den Folgebildern, oder jedes Einzelne Bild.
Zumindest habe ich bis jetzt nicht rausfinden können, welcher Dateityp mit "Sprite" beginnt. Das einzigste was ich rausgefunden habe führte mich zu einem Tool namens Sizzler Animation von der Firma Totally Hip  , das gibt es leider nicht mehr, passt aber voll in die Entstehungszeit des Games.

Weiter habe ich noch unbekannte Dateien mit CDT am Anfang in HEX 43 44 54

Und PARALLAX LAYER in Hex 50 41 52 41 4C 4C 41 58 20 4C 41 59 45 52

Und Layer in Hex 4C 61 79 65 72
(vlt liegen die Farbtabellen der Bilder oder auch nur eine Farbtabelle in diesen Dateien?)

Die SMK (Smacker) Videos des Games sind auch ein veraltetes Format des Bink Video Softwareentwicklers. Die lassen sich super konvertieren, da der Hersteller ein Freeware Tool anbietet. Die RIFF WAVE Dateien sind auch wunderbar zu verarbeiten.


Ich dank euch bis hier mal recht herzlich. Ihr habt mir schon arg weitergeholfen.

PS falls jmd das Game hat und die Dateien selbst entpacken möchte  hier ist das Tool mit dem man die CLU Dateien entpacken kann.


----------



## The_S (7. Mai 2008)

Jap, dann stell deine Daten mal Online, evtl. findet da ja auch jemand was - interessant ist das Thema allemal, aber doch sehr aufwendig wenn nicht sogar fast aussichtslos  .

Ist naütrlich auch die Frage wie man so eine Farbpalette am Besten erkennt, die können ja auch in einem beliebigen Format (theoretisch sogar hard eincodiert) abgespeichert werden. Ich würde spontan mal einige Dateien (vorwärts und rückwärts) nach folgendem Byte-Muster durchsuchen (wobei r,g,b jeweils für eine andere, beliebige zahl steht):

0rgb1rgb2rgb3rgb4rgb5rgb bzw. 255rgb254rgb253rgb252rgb251rgb250rgb ...

evtl. auch nach ähnlichen Dateinamen/den Header durchsuchen, irgendwo muss die Palette ja einem Hintergrund zugeordnet werden. Und falls die Infos nicht auf-/absteigend hintereinander stehen auch mal sortieren, ob man da was findet.

=> alles sehr komplex, aber doch mal eine schöne Aufgabe, die garantiert den einen oder anderen Lerneffekt beinhaltet  .


----------



## dajos7 (7. Mai 2008)

So,

der Ratespass geht weiter 

zwei neue Dateien:

CDT

Sprite

Hierzu habe ich leider absolut keinen Anhaltspunkt. Es scheint in der Sprite Datei allerdings ähnliche strukturen zu geben wie in der ersten geposteten Datei (*.2).

In der Sprite Datei steht an einer Stelle JIM. In einer anderen Sprite-datei habe ich auch dort NONE stehen sehen.
Vermutung: Es könnten animierte Bilddaten sein, ähnlich wie es das GIF Dateiformat unterstützt.

Die CDT Datei sagt mir absolut gar nichts.

Sie sprite Version habe ich nunmal versucht auszulesen. Immer die breite verändert, es ist ein muster zu erkennen, aber  ich weis leider nicht wie breit das bild ist. Es lassen sich 26 Abschnitte erkennen.


----------



## dajos7 (7. Mai 2008)

Habe nun das simple Programm mal etwas ausgebaut, um Paramter live zu manipulieren. Ergebnis für die ermittelte Palette von unserem ersten Bild ist, dass man sie, wie Hobbit vermutet hatte, nicht übertragen kann. Dazu 2 Bilder:

Erstes Bild mit der ermittelten Palette





Ein anderes ermitteltes Bild mit der gleichen Palette von Hobbit





Das Original aus dem Game, mit Vordergund!


----------



## The_S (8. Mai 2008)

Stellt sich nur die Frage woher die Farbpalette kommt - such, dajos, such 

Deine anderen Dateien schau ich mir auch mal an. Evtl. wäre es hilfreich ein zip-file mit 3, 4 Dateien vom selben Typ anzubieten (sofern das keine lizenztechnischen Probleme hervorruft). So würden sich Muster vermutlich leichter erkennen lassen.

[edit] So, hab mir gerade mal die CDT angesehen. Da lässt sich leider nicht viel sagen, solang man nur eine einzige Datei hat. Was man mit ziemlicher Wahrscheinlichkeit sagen kann ist, dass die Datei einen 24-Byte großen Header hat, und danach irgendwelche Adressierungen/Zuweisungen kommen, die allesamt 12 Byte groß sind und auch alle mit den Bytes 39 (Hochkomma), 1, 0, 0, 64 (@), 0, 0 anfangen. Anschließend kommt ein fast durchgehend aufsteigend sortiertes Byte (ich denke das sollte wichtig sein) gefolgt von 3 "0"-Bytes. Aber um das genauer zu Analysieren benötigt man wie gesagt mehrere Dateien davon. Evtl. hat CDT auch was mit Sprite zu tun, da in der CDT ebenfalls im Header das Wort "NONE" vorkommt (sollte man überprüfen obs die auch mit "JIM" gibt - evtl. sowas wie die Animationsreihenfolge der Sprites!?). Es wäre auch interessant zu wissen, ob sich von den Dateinamen (auch bzw. vorallem Formatübergreifend) irgendwelche Muster erkennen lassen (nachdem wir ja zumindest schonmal die Hintergrundbilder zuweisen können).

[edit2] Diese Seite könnte sehr interessant sein, leider ist die Seite bei mir gesperrt :cry: www.tentakelvilla.de/technikfaq.html



			
				google Vorschau hat gesagt.:
			
		

> 2.6 Das Installationsprogramm von "Baphomets Fluch" bricht mit ..... Die Charaktere setzen sich aus Multicolor-Sprites zusammen, die jeweils den ...



evtl. findet man hier auch etwas http://filext.com/file-extension/sprite

wäre auch noch hilfreich, wenn du uns mitteilen würdest, WO du die "Abschnitte" in den sprites siehst, dann müssten wir da schonmal nicht selber drauf kommen  .

[edit3] So, ich vermute mal neue Infos zu den Sprites zu haben (zumindest zu der Datei, die du hochgeladen hast):

- die .sprites Datei hat einen 128 Byte großen Header
- die einzelnen Bilder fangen bei jedem neuen "JIM" (außgenommen dem 1. im sprites Header) an (26 an der Zahl, wie du schon sagtest)
- die einzelnen Bilder haben einen 19 Byte großen Header
- jedes Bild hat eine Auflösung von 12x96
- die Bilder greifen wohl auch auf eine Farbpalette zu

alles bis jetzt nur Vermutungen, sieht für mich aber gerade sehr realistisch aus  . to be continued ...


----------



## dajos7 (8. Mai 2008)

*@Hobbit*
Das mit der lizenzrechtlichen Frage ist mir ebenfalls durch den Kopf gegangen, weshalb ich bis jetzt auch noch nicht viel mehr onlinegestellt habe. Das Spiel ist ja schon gut älter als 10 Jahre. Was ja jetzt kein Freibrief fürs decodieren der Dateien ist. Zumindest ist es nicht kopiergeschützt. Ich könnte die Dateien, wie Du vorgeschlagen hast, zippen und mit Passwort versehen und das den Mitdiskutanten bekanntgeben, für den kurzen Zeitraum unseres Geplänkels.
Ich denke leider, das Revolution Soft hier nicht gross zustimmt mit dem was ich sowieso vorhabe, es soll ja auch absolut privat bleiben, bis was Brauchbares bei rauskommt. Und dann würde ich die Anfrage zu einer kostenlosen Veröffentlichung stellen. Also es liegt mir fern hier gegen Gesetze zu verstoßen.

Aber ok ich überleg mir da mal was. Ohne Hilfe ist es schon recht schwer deswegen freu ich mich, dass hier ein paar Leuts wirklich mit am Ball sind.



> http://filext.com/file-extension/sprite


Diese Seite habe ich mir auch schon angesehen, weshalb ich auf dieses Sizzler gekommen bin. aber das Acorn bitmap könnte auch einen Blick wert sein. Leider habe ich zu beiden nichts weiter gefunden. Die Firma Totally Hip antwortet auch nicht auf meine Anfrage.

Auf deinem ersten link steht unter der Angabe:



> 2.6 Das Installationsprogramm von "Baphomets Fluch" bricht mit Fehlermeldungen ab, oder das Spiel findet die CDs nicht.
> Leider ist das Installationsprogramm nicht sehr zuverlässig. Anfällig ist es vorallem, wenn die CD nicht im ersten CD-Laufwerk liegt oder die Laufwerksbuchstaben im System nicht lückenlos vergeben sind.
> Antwort 1: ScummVM ist nicht auf den verbugten Installer angewiesen, für die Verwendung unter ScummVM folge den Anweisungen dort!
> Antwort 2 (mit Originalinterpreter): Öffne die Datei SWORD.INF auf Deiner Festplatte und trage die Verzeichnispfade manuell ein! Die Angaben stehen jeweils abwechselnd für CD1 und CD2. So kann man auch mit 2 CD-Laufwerken spielen und muß die CD dann nicht mehr wechseln. Man kann die CD-Inhalte auch komplett auf die Festplatte kopieren und die Pfade in der SWORD.INF dann darauf zeigen lassen. Auch relative Pfadangaben sind möglich.
> ...



*zu edit3*
das ist interessant, dann werde ich mal da das programm noch nach deinen Angaben modifizieren. Werde heute abend auf jeden Fall die Farbpaletten suchen. Vlt kommt ja am Ende ein mini toolset raus um die Daten des Games zugänglich zu machen. Ich habe übrigend gestern noch ein Programm gefunden, das jede einzelne änderung auf dem Screen erkennt und als Screenshot abspeichert, damit lassen sich super Animationen einfangen. 
animget

und das hier ist auch ganz interessant gewesen (off Topic) : HD 2D Sprites


----------



## The_S (8. Mai 2008)

Hast du meinen 3. Edit schon gesehen?


----------



## dajos7 (8. Mai 2008)

Hobbit_Im_Blutrausch hat gesagt.:
			
		

> Hast du meinen 3. Edit schon gesehen?



ja grade eben


----------



## The_S (8. Mai 2008)

> das ist interessant, dann werde ich mal da das programm noch nach deinen Angaben modifizieren



Wie gesagt, nur Vermutungen! Das habe ich alleine aus den einzelnen bytes und mithilfe der Mathematik aus der sprites-Datei "gelesen". Kann auch eine vollkommen andere Struktur vorherschen  .


----------



## dajos7 (8. Mai 2008)

Hobbit_Im_Blutrausch hat gesagt.:
			
		

> > das ist interessant, dann werde ich mal da das programm noch nach deinen Angaben modifizieren
> 
> 
> 
> Wie gesagt, nur Vermutungen! Das habe ich alleine aus den einzelnen bytes und mithilfe der Mathematik aus der sprites-Datei "gelesen". Kann auch eine vollkommen andere Struktur vorherschen  .



Sicherlich kann es da ne andere Struktur geben, aber einen Versuch ist es auf jeden Fall wert. Du hattest mit der Farbpalette ja auch recht.
Aber deine Angaben hören sich sehr gut an, das könnte was werden. Es ist einfach genial wenn man da sitzt die breite der Datei (des Bildes) ändert und urplötzlich entsteht aus Rauschen ein Bild  1 Pixel bis 2 Pixel offset verschiebung führt zu unansehlichem Bildrauschen.


----------



## The_S (8. Mai 2008)

So, noch was in Erfahrung gebracht  . Scheinbar ist die Auflösung der Bilder in dem Sprite wo du hochgeladne hast doch nicht 12x96 sondern 12x85. Das ergibt sich dadurch, dass jedes Sprit scheinbar noch einen (unterschiedlichen langen) Footer besitzt. Das 5. Byte im Header eines jeden Bildes spezifiziert wie lang der Footer ist.

Soweit zumindest der aktuelle Kenntnisstand, der vermutlich noch 100mal übern Haufen geworfen wird 

[edit] So, hab mal folgendes geschrieben, mit dem man das von dir hochgeladene Sprite in Einzelbilder wandeln kann:


```
public static BufferedImage[] createSprites(String file, HashMap<Integer, Integer> map) throws Exception {
		
		BufferedImage[] sprites = null;
		FileInputStream fis = new FileInputStream(file);
		fis.read(new byte[20]); // Erste 20 Bytes unwichtig (bis jetzt)
		sprites = new BufferedImage[fis.read()]; // 21. Byte = Anzahl der Frames
		fis.read(new byte[3]); // Byte 22 - 24 unwichtig (bis jetzt)
		int spHeadSize = fis.read(); // 25. Byte = Größe des Sprit-Headers
		fis.read(new byte[3]); // Byte 26 - 28 unwichtig (bis jetzt)
		int picHeadSize1 = fis.read(); // 29. Byte = Größe des Frame-Headers nach der Footer-Größe
		int picHeadSize2 = fis.read(); // 30. Byte = Stelle im Frame-Header der Footer-Größe
		fis.read(new byte[spHeadSize - 30]); // Rest des Headers unwichtig (bis jetzt)
		int width = 12; // ???
		int height = 85; // ???
		for (int i = 0; i < sprites.length; i++) {
			fis.read(new byte[picHeadSize2 - 1]);
			int footer = fis.read();
			fis.read(new byte[picHeadSize1]);
			BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
			for (int y = 0, z = 0; y < img.getHeight(); y++) {
				for (int x = 0; x < img.getWidth(); x++, z++) {
					int temp = fis.read();
					img.setRGB(x, y, map.get(temp));
				}
			}
			fis.read(new byte[footer + 1]);
			sprites[i] = img;
		}
		return sprites;
	}
	
	public static void main(String[] args) throws Exception {
		
		HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
		for (int i = 0; i < 256; i++) {
			map.put(i, new Color(i, i, i).getRGB());
		}
		BufferedImage[] sprites = createSprites("C:/fluch/007EA95C.sprite", map);
		for (int i = 0; i < sprites.length; i++) {
			ImageIO.write(sprites[i], "png", new File("C:/fluch/sprite" + i + ".png"));
		}
	}
```

(@Slater ja, ich war immernoch zu faul von HashMap auf Integer umzustellen  )

Momentan ist das Ganze zwar nur schwarz weiß und definitiv mit der falschen Farbpalette, aber imho kann man da ne Animation draus erkennen.

Ich könnte mir des weiteren Vorstellen, dass das 21. Byte im Header des sprite-files die Anzahl an Bilder spezifiziert (steht halt zufällig auf 26 ^^), um das zu bestätigen bräuchte man aber mehrere sprites. Man müsste auch noch rausfinden, wo die Auflösung der Sprites (oder zumindest die Höhe/Breite) spezifiziert wird, da ein manuelles Auslesen sehr zeitaufwändig und fehleranfällig ist. 

Und wenn man dann noch rausfindet, ob der Header der Sprites immer 128 Bytes groß ist (auch bei NONE) und der Header der Bilder auch immer 19 Bytes groß ist, sollte sich damit wohl was anfangen lassen. Könnte aber auch sein, dass Byte 25 im Sprite-Header die größe des Sprit-Headers, und Byte 29 + 30 die Größe des Bild-Headers spezifiziert (dabei entspricht Byte 30 gleichzeitig der Stelle, die die Größe des Footers enthält).

[edit2] So, mal den Code meiner Theorie angepasst


----------



## dajos7 (8. Mai 2008)

Wäre es evtl möglich, das hier für die MiniBilder die Farbpallete angehängt ist? Wäre da genug Platz für so ne Minipalette?


----------



## The_S (8. Mai 2008)

Man beachte meinen edit  .

Wäre theoretisch möglich, ich hab hier eine Footer-Größe zwischen 120 und 140 Bytes. Da passt durchaus eine Farbpalette rein.

[edit] Scheinbar zeigt das 5. Byte nicht die Größe eines Footers, sondern spezifiziert sowas wie "Extra-Bytes". Diese zusätzlichen Bytes werden nämlich (wie soeben entdeckt  ) keinesfalls am Ende angefügt, sondern irgendwo verteilt im Bild. Ein genaues Schema konnte ich bis jetzt noch nicht entdecken, steh da jetzt auch gerade vor nem Rätsel ???:L . Aufjedenfall scheinen die Bilder-Segmente so unterschiedlich groß zu sein, wie es die Differenz des jeweils 5. Bytes aus dem Header ergibt. Aber die zusätzlichen Bytes werden nicht zusammenhängend eingefügt - glaub ich


----------



## dajos7 (8. Mai 2008)

Ich sehe grade Du machst deinem Namen alle Ehre  Ich kann momentan leider nichts machen, da ich auf der Arbeit sitze und meine Mittagspause grade mal hierfür "missbrauche".

Aber das hat mich jetzt nicht davon abgehalten deinen Code mal schnell zu testen. Da bewegt sich wirklich was. Ich versuche auch grade mal zu überlegen, ob ich diese Animation im Game evtl schon gesehen habe. Vlt stimmt die Breite und Höhe noch nicht ganz. Ich habe allerdings auch noch größere Sprite dateien, die man sicherlich besser erkennen kann. Dazu aber dann heute Abend mehr.

Aber irgendwie ist das lustig, es gibt viele leute denen man das zeigt und urplötzlich beginnen da unbedingt eine lösung herbeizuführen. das ist der "Hacker in uns"


----------



## The_S (8. Mai 2008)

OK, so einfach wird es vermutlich nicht die Bilder aus dem Sprites auszulesen. Vermutlich sind die Bilder in den Sprites irgendwie codiert - anders kann ich mir keine unterschiedliche Byte-Zahl pro Bild in ein und demselben Sprite erklären ???:L . Und ich vermute mal, dass das 5. Byte des Bild-Headers dabei eine wichtige Rolle spielt. Fragt sich nur welche ...  .

Kann auch sein, dass der Header kleiner als 19 Byte ist, kommt jetzt auf die Codierung an :cry:


----------



## dajos7 (8. Mai 2008)

Könnte man in betracht ziehen, dass vlt nur Änderungen beachtet werden in den Folgebildern?


----------



## The_S (8. Mai 2008)

Nein, das glaube ich nicht. Dafür sind sich die Folgebilder viel zu ähnlich.

Ich verlink gleich ne Datei, mom ...

[edit] http://www.java-forum.org/de/userfiles/user2530/jim.zip

Das ist das Sprite ein bisschen aufgeteilt. 

header.txt = Sprite-Header
jim*.txt = Frame, *=Nummer

Format:

Positioin (fortlaufend) - Dezimal - Character (evtl. müssen leerzeilen manuel entfernt werden) - Binär- Hex

Wie gesagt liegt mein Augenmerk momentan ein bisschen auf dem 5. Byte der Frame-Dateien. Die Frame-Dateien stimmen eigentlich größtenteils überein - kleinere Änderungen inbegriffen (sonst wärs ja keine Animation  ). Nur haben manche Frames mehr Bytes als andere. Dies lässt sich wie gesagt am 5. Byte auslesen und z. B. bei den ersten 4 Frames zwischen den Positionen 160 - 210 beobachten.

Evtl. fällt dir ja dazu was ein. Auffällig ist auch das Zusammenspiel von Großen Bytes (Index auf der Farbtabelle???), kleinen Bytes (Anzahl der Folgenden "Farbtabellen-Bytes"!?) und 0 Bytes (Trennzeichen!?). Aber das sind (mal wieder  ) nur Vermutungen und Möchtegern-Tatsachen, die sich ohne mehreren Dateien wohl weder bestätigen noch widerlegen lassen


----------



## dajos7 (9. Mai 2008)

Im Sprite header kommt wenn man immer 4 byte ab JIM_ liesst immer auf genau einen 4 byte langen wert. Das machst sogar Sinn, da die letzten (ersten) bytes meist 0 sind.

4 Byte erinnert mich an 1 auf 3 byte farbzuweisung ^^ Das könnte die Farbpaltette sein?
Problem es wäre fast nur rot vorhanden, also verfällt die Idee sicherlich auch. Macht dann nur sinn, wenn man es wirklich als 4 byte werte nimmt.


Wenn man in der ersten JIM datei direkt nach JIM_  4 byte liesst, hat man den Wert 1150, die länge zum nächten jim sind 1166, das macht 16 unterschied, vlt gibt das die länge des Bildes an und 16 bytes hängen noch dran? wenn man noch die jim länge von 4 byte und die 4 byte des Werten an sich nimmt macht es nur noch 8 byte unterschied.

nimmt man noch die beiden nachfolgenden 8 byte kommt man genau zu einer gruppierung, die RGB erkennen lasen könnten. 1150 wäre dann die zu lesende länge ab dort.

Sind volle 1150 pixel?

wären höhe und breite denkbar mit



2 x 575
5 x 230
10 x 115
23 x 50
25 x 46


*EDIT*
Im zweiten jim steht direkt nach JIM_ wieder ein 4 byte wert mit 1155 macht zusammen mit 16 genau 1171 was der länge des jims entspricht ^^

Und im 3ten Jim ist es ebenso...

Also vermute ich mal es ist ein 16 Byte langer Header in jedem jim von JIM_ ab gezählt. Könnten nun die 29 und 88 die pixel angeben (als 2 Byte wert getarnt)? die sind nämlich in jedem Jim gleich. Mich verwundert nur, dass die JIMs unterschiedlich lang sind. ich hoffe da ist keine Kompression im spiel.

*EDIT2*
Die folgenden Bytes nach dem JIM Header (16 bytes nach dem ersten Byte von JIM_ ) Sehen mir nach farbwerten aus, oder zumindest als referenz auf eine palette, was meinst Du Hobbit?


*EDIT3*
Hi ich habe gerade noch weitere Infos erhalten. Parallax Layer Datei wird wohl mit dem Stichwort Parallaxenverschiebung in Zusammenhang gebracht. Wusste ich bisher auch noch nichts von 

*EDIT4*
So und wieder einen Schritt weiter. Habe noch weitere Infos von einem netten Herren erhalten, der sich damit auch schon etwas beschäftigt hatte. Bei scummVM soll es im SVN die komplette Engine geben. Gleich mal nachschauen.  Sword 1 engine
Das ganze soll hochoffiziell von Revolution soft genehmigt sein, also ist das ganze mal nicht illegal. Nur mal erwähnt, damit Leute nicht auf Bedenken stoßen.
Die CDT könnten Color Definition Tables heissen, also die Farbpaletten bilden.

Da ScummVM auch schon den Weg auf die nintendo DS gefunden hat, liegt die Vermutung nahe, dass Broken Sword auch dort bereits existiert, was aber die Gamelist widerlegte scummvm.drunkencoders.com/#whichgames

Aber revolution Soft arbeitet gerade selber an einer Portierung

Quelle Wikipedia
Release Date soll  wohl September / Oktober 2008 sein.


> Broken Sword games on the Nintendo DS
> 
> Revolution Software is currently attempting to gauge interest in bringing the Broken Sword series to the Nintendo DS hand held gaming system. To that end, Tony Warriner posted a link to an online petition at the Revolution Chat website. The petition is an attempt to gauge interest in such titles on Nintendo's hand held in a more traditional 2D format.



*EDIT5*

Da sich das ganze nun von java recht weit entfernt, werd ich den Thread einstellen, aber an der Sache nicht aufhören. Wer Interesse hat, der kann sich ja gern per PM melden.


----------



## The_S (13. Mai 2008)

dajos7 hat gesagt.:
			
		

> *EDIT*
> Im zweiten jim steht direkt nach JIM_ wieder ein 4 byte wert mit 1155 macht zusammen mit 16 genau 1171 was der länge des jims entspricht ^^
> 
> Und im 3ten Jim ist es ebenso...
> ...



Ja ... das ist das 5. Byte, von dem ich die ganze Zeit rede ... hättest dir die Arbeit also sparen und einfach meine Beiträge lesen können 



			
				dajos7 hat gesagt.:
			
		

> Mich verwundert nur, dass die JIMs unterschiedlich lang sind. ich hoffe da ist keine Kompression im spiel.



Auch das habe ich schon festgestellt ... auch hier hättest du dir Arbeit durch lesen ersparen können ...



			
				dajos7 hat gesagt.:
			
		

> *EDIT2*
> Die folgenden Bytes nach dem JIM Header (16 bytes nach dem ersten Byte von JIM_ ) Sehen mir nach farbwerten aus, oder zumindest als referenz auf eine palette, was meinst Du Hobbit?



Glaub ich nicht, dafür kommen zuviele gleiche Werte vor. Eher wie erweiterte Informationen zum Sprite - oder schon der Anfang vom Sprite selber ???:L . Aber ich hab damit auch nicht sonderlich viel Erfahrung :bahnhof:



			
				dajos7 hat gesagt.:
			
		

> *EDIT3*
> Hi ich habe gerade noch weitere Infos erhalten. Parallax Layer Datei wird wohl mit dem Stichwort Parallaxenverschiebung in Zusammenhang gebracht. Wusste ich bisher auch noch nichts von



Ich auch nicht, aber leider komme ich auch nicht auf diese Seite.



			
				dajos7 hat gesagt.:
			
		

> *EDIT4*
> So und wieder einen Schritt weiter. Habe noch weitere Infos von einem netten Herren erhalten, der sich damit auch schon etwas beschäftigt hatte. Bei scummVM soll es im SVN die komplette Engine geben. Gleich mal nachschauen.  Sword 1 engine
> Das ganze soll hochoffiziell von Revolution soft genehmigt sein, also ist das ganze mal nicht illegal. Nur mal erwähnt, damit Leute nicht auf Bedenken stoßen.



Und auch hier wieder das Seiten-Problem 



			
				dajos7 hat gesagt.:
			
		

> Da ScummVM auch schon den Weg auf die nintendo DS gefunden hat, liegt die Vermutung nahe, dass Broken Sword auch dort bereits existiert, was aber die Gamelist widerlegte scummvm.drunkencoders.com/#whichgames



Siehe oben :cry:



			
				dajos7 hat gesagt.:
			
		

> Die CDT könnten Color Definition Tables heissen, also die Farbpaletten bilden.



Könnte sein, ich kann mir die anderen CDTs ja mal anschauen, evtl. find ich was verdächtiges  .



			
				dajos7 hat gesagt.:
			
		

> Da sich das ganze nun von java recht weit entfernt, werd ich den Thread einstellen, aber an der Sache nicht aufhören. Wer Interesse hat, der kann sich ja gern per PM melden.



Naja, der Thread kann trotzdem vortgesetzt werden, ist ja ansich ganz Interessant. Evtl. in die Plauderecke verschieben oder Programmierung Allgemein. Aber würde schon hier weitermachen.



			
				dajos7 hat gesagt.:
			
		

> Im Sprite header kommt wenn man immer 4 byte ab JIM_ liesst immer auf genau einen 4 byte langen wert. Das machst sogar Sinn, da die letzten (ersten) bytes meist 0 sind.
> 
> 4 Byte erinnert mich an 1 auf 3 byte farbzuweisung ^^ Das könnte die Farbpaltette sein?
> Problem es wäre fast nur rot vorhanden, also verfällt die Idee sicherlich auch. Macht dann nur sinn, wenn man es wirklich als 4 byte werte nimmt.
> ...



Ich glaub das Überschneidet sich mit deinen späteren/meinen vorhergehenden Aussagen und ist somit hinfällig!? Ansonsten muss ich wohl nochmal drüber nachdenken  .


----------



## dajos7 (13. Mai 2008)

*@Hobbit*

Nicht falsch verstehen, das ist kein Nachgeplapper, das ist ne Bestätigung deiner Feststellungen mit meiner Recherche.  Also ich stimm Dir da zu, mit dem was Du festgestellt hast.
Wieso kannst Du die Seiten denn nicht zugreifen? Hast Du limitiertes Internet? 

So noch zu den unterschiedlichen Längen der JIM Segmente: Da könnte Kompremierung im Spiel sein. Was denkst Du denn über die 2 x 2Bytes im JIM header. Könnte das die Höhe und Breite sein?

Ich hab im C++ Code noch das hier gefunden, aber das hat wohl eher was mit den Smack Videos zu tun.


```
void MoviePlayer::updatePalette(byte *pal, bool packed) {
	byte palette[4 * 256];
	byte *p = palette;

	uint32 maxWeight = 0;
	uint32 minWeight = 0xFFFFFFFF;

	for (int i = 0; i < 256; i++) {
		int r = *pal++;
		int g = *pal++;
		int b = *pal++;

		if (!packed)
			pal++;

		uint32 weight = 3 * r * r + 6 * g * g + 2 * b * b;

		if (weight >= maxWeight) {
			_white = i;
			maxWeight = weight;
		}

		if (weight <= minWeight) {
			_black = i;
			minWeight = i;
		}

		*p++ = r;
		*p++ = g;
		*p++ = b;
		*p++ = 0;
	}

	_system->setPalette(palette, 0, 256);
	_forceFrame = true;
}
```
animation.cpp

und auch das hier:



```
void Control::askForCd(void) {
	_screenBuf = (uint8*)malloc(640 * 480);
	uint32 fontId = SR_FONT;
	if (SwordEngine::_systemVars.language == BS1_CZECH)
		fontId = CZECH_SR_FONT;
	_font = (uint8*)_resMan->openFetchRes(fontId);
	uint8 *pal = (uint8*)_resMan->openFetchRes(SR_PALETTE);
	uint8 *palOut = (uint8*)malloc(256 * 4);
	for (uint16 cnt = 1; cnt < 256; cnt++) {
		palOut[cnt * 4 + 0] = pal[cnt * 3 + 0] << 2;
		palOut[cnt * 4 + 1] = pal[cnt * 3 + 1] << 2;
		palOut[cnt * 4 + 2] = pal[cnt * 3 + 2] << 2;
	}
	palOut[0] = palOut[1] = palOut[2] = palOut[3] = 0;
	_resMan->resClose(SR_PALETTE);
	_system->setPalette(palOut, 0, 256);
	free(palOut);

	char fName[10];
	uint8 textA[50];
	sprintf(fName, "cd%d.id", SwordEngine::_systemVars.currentCD);
	sprintf((char*)textA, "%s%d", _lStrings[STR_INSERT_CD_A], SwordEngine::_systemVars.currentCD);
	bool notAccepted = true;
	bool refreshText = true;
	do {
		if (refreshText) {
			memset(_screenBuf, 0, 640 * 480);
			renderText(textA, 320, 220, TEXT_CENTER);
			renderText(_lStrings[STR_INSERT_CD_B], 320, 240, TEXT_CENTER);
			_system->copyRectToScreen(_screenBuf, 640, 0, 0, 640, 480);
		}
		delay(300);
		if (_keyPressed.keycode) {
			if (!Common::File::exists(fName)) {
				memset(_screenBuf, 0, 640 * 480);
				renderText(_lStrings[STR_INCORRECT_CD], 320, 230, TEXT_CENTER);
				_system->copyRectToScreen(_screenBuf, 640, 0, 0, 640, 480);
				delay(2000);
				refreshText = true;
			} else {
				notAccepted = false;
			}
		}
	} while (notAccepted && (!SwordEngine::_systemVars.engineQuit));

	_resMan->resClose(fontId);
	free(_screenBuf);
}
```
control.cpp

Zu setPalette:


> virtual void OSystem::setPalette  	(   	const byte *   	 colors,
> uint  	start,
> uint  	num
> )  	[pure virtual]
> ...



Unter dem link mit der Parallaxenverschiebung steht


> Parallaxenverschiebung
> Aus Pixelwiki
> 
> Unter Parallaxenverschiebung versteht man einerseits einen häufig bei der Aufnahme von Panoramabildern auftretenden Fehler, durch den unterschiedlich weit entfernte Objekte beim Zusammenfügen der Einzelbilder nicht mehr zur Deckung zu bringen sind. Ursache ist die Drehung der Kamera außerhalb des Nodalpunkts zwischen den einzelnen Aufnahmen. Zu vermeiden ist das Problem durch die Verwendung eines Stativs mit Nodalpunktadapter oder ggf. durch den Verzicht auf kameranahe Objekte im Bildausschnitt.
> ...


Das ist quasi in unserem Fall eine Bitmap mit transparentem Bereichen, die als Layer vor dem Hintergrund animiert wird. zB im ersten Kapitel ist das eine Mauer mit Baum, die sich beim Scrollen nach rechts mathematisch berechnet  mit unterschiedlicher Geschwindigkeit zum Hintergrund bewegt. 
Auch interessant:
parallaxe


Zu den CDT Dateien. Die sind immer in 4 Byte Blöcken gehalten. Ich hab schon versucht es mit der 1 zu 3 Byte Weise zu lesen, aber 2 byte sind fast immer 0. Die Farbe wäre dann immer recht dunkel. Auch habe ich mal versucht die Bytes direkt als 4 byte zu lesen und als RGB Int zu interpretieren, vlt ist ja auch alpha kanal dabei, aber das endete immer in undefinierten Farben, meist sehr dunkel.

Wie gesagt ich vermute noch Kompression. Aber das wird nicht leicht das rauszubekommen, wenn es verwendet wird.


----------



## The_S (13. Mai 2008)

Dann is ja gut ... desweiteren kann man auch sicher sagen, dass das 21. Byte im Spride-Header die Anzahl der Bilder, und das 25. Byte im Spride-Header die größe des Spride Headers definiert.

Die bytes an Stelle 9 + 11 des JIM-Headers? Ja, das könnte die Größe sein, habe ich mir auch schon überlegt.

Werd mir deinen Post mal bei Gelegenheit durchlesen, ist ja einiges an Informationen  .


----------



## dajos7 (13. Mai 2008)

so ich hab noch was rausgefunden, falls Du dass schon erwähnt hast, es ist kein nachgeplapper, ich verlier zT bischen den überblick über den Thread, da bin ich ganz ehrlich.

Also:

Im Sprite Header kommt direkt nach der Anzahl der Bilder die Länge des Headers. Das ist aber nun auch die Adresse zum ersten JIM. Liesst man dann immer 4 Byte weiter und das mit der Anzahl der Bilder, erhält man alle 4 Byte den offset zum x-ten Bild. Das sind also Adressen zu den JIMs.

8tes Byte im sprite header ist die dateilänge.


----------



## The_S (13. Mai 2008)

Definier mal "direkt nach"



			
				me hat gesagt.:
			
		

> das 21. Byte im Spride-Header die Anzahl der Bilder, und das 25. Byte im Spride-Header die größe des Spride Headers definiert.



8tes Byte im Spride-Header ist bei mir eigentlich immer 0 ???:L


----------



## dajos7 (13. Mai 2008)

sorry ich meine immer den index, das wäre dann das 9.te byte und dann immer 4byte als INT in little endian lesen. dann erhält man die dateilänge.

Momentan hab ich folgendes:

6 Bytes - SPRITE
2 Bytes - immer 1
4 Bytes - Dateilänge
4 Bytes - JIM or NONE
4 Bytes - noch unbekannt (arbeite ich grade dran) Vermute das könnte ein Offset oder index zu einer Farbpalette sein?
4 Bytes - Bilderanzahl

dann immer 4 Bytes mit den Offsetwerten zu den Bildern

dann folgen die JIMs


*EDIT1*

Die Dateien tragen auch die namen von 4 Byte als Hex geschrieben. vlt kann man die daher referenzieren?
Ich muss nachhermal schauen ob ich die Datei 000379C6.cdt finde  Das ist der Index von dem unbekannten feld von datei 007F7F50.sprite

*EDIT2*
Eine entsprechnde Datei habe ich nicht gefunden.

*EDIT3*
Habe nun mal die Werte für die 5 Dateien ausgelesen und verglichen ... ich komm leider nicht drauf was das sein könnte. Ich beziehe mich auf die 4Bytes hinter dem "NONE" oder auch "JIM " des Sprite-Headers.
Zu erkennen ist, dass der Wert meist 20 Bytes kleiner ist als die Dateilänge, dass kommt wohl vom Index. Denn nach der Angabe steht man beim Offset 20. Aber manchmal ist der Wert auch viel größer, wenn man den longInt betrachtet. Es scheint einen Zusammenhang zw. den vorhergehenden 4Bytes (NONE or JIM) zu geben. NONE scheint wohl anzugeben, dass etwas nicht benötigt ist, oder nicht vorhanden. Vlt Kompression? Und der Wert gibt die tatsächliche Grösse an?

```
| filelength |  filename   |  unknown                    |             |      |
     |            |             |    longINT | word   | byte  |  hex        | flag |
     -------------------------------------------------------------------------------
     |            |             |            |        |       |             |      |
     | 130.855    |  007F0600   |  130.835   | 65299  |  19   | 13 FF 01 00 | NONE |
     | 127.623    |  007F99C8   |  148.409   | 17337  | 185   | B9 43 02 00 | JIM  |
     | 140.394    |  007E9FBC   |  140.374   |  9302  |  86   | 56 24 02 00 | NONE |
     | 126.711    |  007EC9D8   |  126.691   | 61155  | 227   | E3 EE 01 00 | NONE |
     | 125.191    |  007F7F50   |  227.782   | 31174  | 198   | C6 79 03 00 | JIM  |
     |            |             |            |        |       |             |      |
```


*EDIT4*
Werde hier mal einen Blick reinwerfen --> fileformats


----------



## The_S (15. Mai 2008)

Zu deinem 4. Edit: Ja, schaut sehr interessant aus. Und sorry, hab momentan nicht so viel Zeit mich darum zu kümmern, aber ich tu was ich kann  .


----------



## The_S (15. Mai 2008)

Das eine Sprite-File mit einem NONE-Flag (007EC9D8) verwendet als Startzeichen für die einzelnen Frames nicht JIM sondern RLE, was wohl eindeutig auf http://www.fileformat.info/mirror/egff/ch09_03.htm#RUEN-CHP-09 schließen lässt ...


----------



## dajos7 (15. Mai 2008)

So es gibt neues, Hobbit das mit dem RLE hab ich auch schon gesehen. Und deine Vermutung scheint korrekt zu sein 

RLE7 ist es um genauer zu sein. Zitat eines Mitstreiters:



> RLE7. Der Frame-Block beginnt wie gehabt:
> 
> char[4] "RLE7"
> uint32 Datenlänge ohne Header
> ...



dazu 2 Bilder, die er entschlüsselt hat.












*EDIT2*
Und hier noch ein Auszug aus dem SCUMMVM Source:

```
00677 
00678 void Screen::decompressTony(uint8 *src, uint32 compSize, uint8 *dest) {
00679     uint8 *endOfData = src + compSize;
00680     while (src < endOfData) {
00681         uint8 numFlat = *src++;
00682         if (numFlat) {
00683             memset(dest, *src, numFlat);
00684             src++;
00685             dest += numFlat;
00686         }
00687         if (src < endOfData) {
00688             uint8 numNoFlat = *src++;
00689             memcpy(dest, src, numNoFlat);
00690             src += numNoFlat;
00691             dest += numNoFlat;
00692         }
00693     }
00694 }
00695 
00696 void Screen::decompressRLE7(uint8 *src, uint32 compSize, uint8 *dest) {
00697     uint8 *compBufEnd = src + compSize;
00698     while (src < compBufEnd) {
00699         uint8 code = *src++;
00700         if ((code > 127) || (code == 0))
00701             *dest++ = code;
00702         else {
00703             code++;
00704             memset(dest, *src++, code);
00705             dest += code;
00706         }
00707     }
00708 }
00709 
00710 void Screen::decompressRLE0(uint8 *src, uint32 compSize, uint8 *dest) {
00711     uint8 *srcBufEnd = src + compSize;
00712     while (src < srcBufEnd) {
00713         uint8 color = *src++;
00714         if (color) {
00715             *dest++ = color;
00716         } else {
00717             uint8 skip = *src++;
00718             memset(dest, 0, skip);
00719             dest += skip;
00720         }
00721     }
00722 }
00723
```

*EDIT2*
Noch was neues:


> Noch ein kurzes Update: Mittlerweile habe ich etwas gefunden, das
> ziemlich eindeutig nach Paletten aussieht. In paris1.clu existieren
> diverse Dateien mit genau 768 (= 256 * 3) Bytes Größe:
> 
> ...


----------



## The_S (15. Mai 2008)

Na damit lässt sich doch arbeiten, hier eine kleine Beta-Version (erweiterbar  ):


```
public static byte[][] getDataFromSprite(File sprite) throws IOException {
		
		ArrayList<Byte> b = new ArrayList<Byte>();
		byte[] bytes = new byte[(int)sprite.length()];
		int pointer = 0;
		boolean start = false;
		String temp = null;
		FileInputStream fis = new FileInputStream(sprite);
		fis.read(bytes);
		Byte[][] retVal = new Byte[bytes[20] + 1][0];
		
		// Header
		for (pointer = 0; pointer < (bytes[24] & 0xFF); pointer++) {
			b.add(bytes[pointer]);
		}
		retVal[0] = b.toArray(new Byte[b.size()]);
		
		// Sprites
		for (int i = 0; i < (bytes[20] & 0xFF); i++) {
			b.clear();
			start = true;
			while (pointer < bytes.length) {
				if (pointer + 3 < bytes.length) {
					temp = new String(new byte[] {bytes[pointer], bytes[pointer + 1], bytes[pointer + 2], bytes[pointer + 3]});
					if (!start && ("JIM ".equals(temp) || temp.startsWith("RLE7"))) {
						break;
					}
				}
				b.add(bytes[pointer++]);
				start = false;
			}
			retVal[i + 1] = b.toArray(new Byte[b.size()]);
		}
		return convertByteTobyte(retVal);
	}

	public static void extractSprite(File f, HashMap<Integer, Integer> map) throws IOException {
		
		byte[][] val = getDataFromSprite(f);
		for (int i = 1; i < val.length; i++) {
			ImageIO.write(convertFrame(val[i], map), "png", new File("C:/fluch/sprites/" + i + ".png"));
		}
	}

	public static BufferedImage convertFrame(byte[] frame, HashMap<Integer, Integer> map) {
		
		int alpha = new Color(0, 0, 0, 0).getRGB();
		BufferedImage img = new BufferedImage(frame[8] & 0xFF, frame[10] & 0xFF, BufferedImage.TYPE_INT_ARGB);
		if (frame[0] == 'R' && frame[1] == 'L' && frame[2] == 'E' && frame[3] == '7') { // RLE7
			for (int i = 15, x = 0, y = 0; i < frame.length; i++) {
				if ((frame[i] & 0xFF) < 128) {
					int col = 0;
					if (map.get(frame[i + 1] & 0xFF) == null) {
						col = alpha;
					}
					else {
						col = map.get(frame[i + 1] & 0xFF);
					}
					for (int j = frame[i] & 0xFF; j > -1; j--) {
						if (img.getWidth() <= x) {
							x = 0;
							y++;
						}
						img.setRGB(x++, y, col);
					}
					i++;
				}
				else {
					if (img.getWidth() <= x) {
						x = 0;
						y++;
					}
					img.setRGB(x++, y, map.get(frame[i] & 0xFF));
				}
			}
		}
		return img;
	}

	public static byte[][] convertByteTobyte(Byte[][] byt) {
		
		byte[][] ret = new byte[byt.length][0];
		for (int i = 0; i < ret.length; i++) {
			ret[i] = convertByteTobyte(byt[i]);
		}
		return ret;
	}
	
	public static byte[] convertByteTobyte(Byte[] byt) {
		
		byte[] ret = new byte[byt.length];
		for (int i = 0; i < ret.length; i++) {
			ret[i] = byt[i];
		}
		return ret;
	}
```

Ist nur teilweise komisch verzerrt ... vermutlich liegt da noch irgendwo ein Fehler ...

[edit] ach, gerade festgestellt, dass hier die Größe des Sprite-Headers und der Frame-Auflösung noch nicht als int32 bzw. int16 betrachtet wird. Kommt also noch zu fehlern, wenn der Sprite-Header größer als 255 oder die Auflösung größer als 255x255 ist


----------



## dajos7 (15. Mai 2008)

und noch mehr:



> Die Parallax-Layer-Dateien sind meiner Ansicht nach wie folgt aufgebaut:
> 
> char[16] "PARALLAX LAYER",0,0
> uint16 Layerbreite
> ...


----------

