---
title: 'DX-Ball Rückentwicklung: Tonschwenken - REA'
url: https://rea.tools/de/showcase/dx-ball/
---

[Startseite](https://rea.tools/de/) / [Präsentieren](https://rea.tools/de/showcase/) Modell: DX-Ball

Fallstudie \* DX-Ball 1.07

# Umbau DX-Ball von seiner ausführbaren Datei.

Das Ziel ist eine wartbare C-Version des 1996er Windows-Spiels. REA hilft dem Agenten, das Original Funktion für Funktion zu inspizieren.

Modell: Windows i386 · C · REA

![DXBALL.Die EXE-Funktion 0x00406400 wird mit REA überprüft. Ein Brick-Hit-Aufrufer liefert 20 plus 30 mal tile_x. Anweisungen laden x, multiplizieren mit 1,5625, subtrahieren 500,0, wenden pan_scale an und geben eine Ganzzahl zurück. Das gepflegte C wird in 3.205 Fällen unabhängig gegen das ursprüngliche x86 und durch VC4.0-Compiler-Wiedergabe mit 63 Bytes überprüft.](https://rea.tools/assets/localized/de/figures/dx-ball-sound-pan-investigation.svg)

Eine Funktion, von ausführbar bis geprüft C. REA liefert die Anweisungen, Aufrufer und Datenlesungen; Das Rekonstruktionsprojekt implementiert und testet das Ergebnis. [Offene Figur](https://rea.tools/assets/localized/de/figures/dx-ball-sound-pan-investigation.svg)

55
:   beibehaltene C-Funktionen

45,380
:   vergleiche mit Originalcode

33
:   funktionen mit übereinstimmenden kompilierten Bytes

Projekt-Checkpoint: 7. Oktober 2026. [Fortschrittsbuch](https://github.com/N0zoM1z0/dx-ball/blob/a55dca27ec0a07018c1b2c95ae2be027f7d8c3c4/docs/PROGRESS.md) · [Testabdeckung](https://github.com/N0zoM1z0/dx-ball/blob/a55dca27ec0a07018c1b2c95ae2be027f7d8c3c4/docs/ORACLES.md)

## Das Projekt bisher

Der wiederhergestellte Code umfasst Brett- und Ressourcenhandhabung, Ziegelsteintreffer, Animationen, Partikel und Bonusproduktion. Aktuelle Builds bieten Inspektionsprogramme und eine Analysebibliothek. Die Arbeit am spielbaren Spiel wird mit Ball- und Paddelphysik, Power-Up-Handling und Windows-Integration fortgesetzt.

## Ermittlung der Berechnung der linken / rechten Schallposition

Wenn ein Stein getroffen wird, wird seine horizontale Position an den Soundcode übergeben. Die Untersuchung musste wiederhergestellt werden, wie diese Bildschirmkoordinate zu einem Links / Rechts-Schwenkwert wird.

Ihr Codierungsagent

Verwenden Sie REA, um herauszufinden, wie DX-Ball die Stereoklangpositionierung berechnet. Erklären Sie die Berechnung und zeigen Sie den Code.

Eine Beispielaufforderung für Ihren Codierungsagenten, wobei die lokale ausführbare Datei verfügbar ist. Die folgende Untersuchung zeigt die REA-Abfragen und Beweise hinter der Antwort.

Der Agent hat REA verwendet, um die Funktion zu überprüfen, seinem Aufrufer mit Ziegelsteinen zu folgen und die Konstanten aus der ausführbaren Datei zu lesen. Diese Ergebnisse lieferten die Eingabe und Arithmetik, die zum Schreiben der folgenden C-Funktion erforderlich waren.

Das erste Funktionsergebnis für `0x406400` enthaltene Pseudocode-Deklaration `FUN_00406400(void)` und ruft `__ftol()`. Die Anweisungsansicht zeigte eine Stapeleingabe und Gleitkommaoperationen. Diese Diskrepanz gab dem Agenten einen konkreten Grund, weiter zu ermitteln.

Die erste Decompiler-Ansicht

REA Ergebnis \* Pseudocode-Auszug

```
longlong FUN_00406400(void)
{
  longlong lVar1;

  lVar1 = __ftol();
  return lVar1;
}
```

Die Ausgabe zeigt einen Konvertierungsaufruf. Wenn Sie die folgenden Anweisungen lesen, werden die Eingabe und die Berechnung angezeigt, die diesen Aufruf einspeisen.

### Drei Fragen beantwortet durch REA

1. #### Stellen Sie die fehlende Eingabe wieder her

   Vertreter → REA · `analyze_function`

   ```
   {"procedure": "0x406400"}
   ```

   REA → Agent \* Anweisungsauszug

   ```
   0x406409: MOV EAX, dword ptr [EBP + 0x8]
   0x40640c: MOV dword ptr [EBP + -0xc], EAX
   0x40640f: FILD dword ptr [EBP + -0xc]
   ```

   Das Funktionsergebnis enthält Anweisungen neben Pseudocode und Aufrufern. Hier, `[EBP+8]` macht die Integer-Eingabe verfügbar, die in der Dekompilierungsansicht fehlt.
2. #### Die aufrufende Funktion erklärt die Eingabe

   Vertreter → REA · `analyze_function`

   ```
   {"procedure": "0x411f40"}
   ```

   REA → Agent · Auszug der aufrufenden Funktion

   ```
   0x411f5b: ADD EAX, 0x14
   0x411f5e: PUSH EAX
   0x411f5f: CALL 0x00406400
   ```

   REA nennt diese aufrufende Funktion bereits im ersten Ergebnis. Vor dem Aufruf multipliziert sie `tile_x` mit 30 und addiert 20. Das ergibt die Bildschirmkoordinate des Ziegels, `20 + 30 × tile_x`.
3. #### Lesen Sie die Werte hinter den Speicheradressen

   Vertreter → REA \* zwei `read_bytes` Antr

   ```
   {"address": "0x420068", "length": 16}
   {"address": "0x4210a0", "length": 8}
   ```

   REA Byte-Ergebnisse \* dekodiert als Doppel

   ```
   000000000000f93f → 1.5625
   0000000000407f40 → 500.0
   000000000000f03f → 1.0
   ```

   Die zurückgegebenen Bytes legen die beiden arithmetischen Konstanten und die anfängliche Schwenkskala fest. Der Agent hat jetzt die Werte, die für den C-Ausdruck benötigt werden.

### Von den Erkenntnissen von REA zu C

Befolgen Sie die folgenden fünf Schritte. Jede Auswahl hebt die ursprünglichen Anweisungen und die von ihnen informierten C-Zeilen hervor.

Original x86 \* Auszug

```
0x406409: MOV EAX, dword ptr [EBP + 0x8]
0x40640c: MOV dword ptr [EBP + -0xc], EAX
0x40640f: FILD dword ptr [EBP + -0xc]
0x406415: FMUL double ptr [0x00420068]
0x40641e: FSUB double ptr [0x00420070]
0x406427: FMUL double ptr [0x004210a0]
0x406430: CALL 0x0041678c
0x40643e: RET
```

Rekonstruiertes C

```
DxBallInt dxball_screen_pan(DxBallInt x)
{
    double pan;
    pan = (double)x;
    pan = pan * 1.5625;
    pan = pan - 500.0;
    pan = pan * dxball_pan_scale;
    return (DxBallInt)pan;
}
```

**01 \* Lesen Sie die Eingabe.** Die Anweisungsansicht im Funktionsergebnis von REA lautet `[EBP+8]` und verwendet `FILD` um die Ganzzahl zu laden. Wenn Sie seinem Aufrufer durch REA folgen, wird die Bildschirmkoordinatenbedeutung des Parameters C festgelegt `x`.

**02 \* Multiplizieren Sie mit 1,5625.** `FMUL` liest das Doppelte bei `0x420068`. Die von REAS zurückgegebenen Bytes `read_bytes` dekodieren zu `1.5625`; das C verwendet dieselbe Konstante.

**03 \* Subtrahieren Sie 500,0.** `FSUB` liest das Doppelte bei `0x420070`. Das Byte-Ergebnis von REA dekodiert zu `500.0`, verschieben des Berechnungsmittelpunkts auf die Bildschirmkoordinate `320`.

**04 · Wenden Sie die gespeicherte Skala an.** Zweiten `FMUL` lesen `0x4210a0`. Das Globale heißt `dxball_pan_scale` in der gepflegten Quelle. Das zweite gelesene Byte von REA legt den Anfangswert von fest `1.0`.

**05 \* Gibt eine Ganzzahl zurück.** Der Anruf bei `0x406430` Oberlauf `__ftol`, identifiziert in den angerufenen Ergebnissen von REA. Das C wirft das Ergebnis auf `DxBallInt`; original-x86-Vergleiche überprüfen den zurückgegebenen Wert.

Der Assemblyauszug wählt die Eingabe-, Arithmetik- und Rückgabeanweisungen aus. Die vollständige Liste unten enthält auch die dazwischenliegenden Speicher sowie die Einrichtung und Bereinigung von Funktionen.

Vollständige Versammlung und unterstützende Beweise

REA Ergebnis · 0x406400–0x40643e

```
0x406400: PUSH EBP
0x406401: MOV EBP, ESP
0x406403: SUB ESP, 0xc
0x406406: PUSH EBX
0x406407: PUSH ESI
0x406408: PUSH EDI
0x406409: MOV EAX, dword ptr [EBP + 0x8]
0x40640c: MOV dword ptr [EBP + -0xc], EAX
0x40640f: FILD dword ptr [EBP + -0xc]
0x406412: FST double ptr [EBP + -0x8]
0x406415: FMUL double ptr [0x00420068]
0x40641b: FST double ptr [EBP + -0x8]
0x40641e: FSUB double ptr [0x00420070]
0x406424: FST double ptr [EBP + -0x8]
0x406427: FMUL double ptr [0x004210a0]
0x40642d: FST double ptr [EBP + -0x8]
0x406430: CALL 0x0041678c
0x406435: JMP 0x0040643a
0x40643a: POP EDI
0x40643b: POP ESI
0x40643c: POP EBX
0x40643d: LEAVE
0x40643e: RET
```

### Was die aufrufende Funktion übergibt

Die Brick-Hit-Funktion bei `0x411f40` skaliert die Kachelkoordinate um 30, addiert 20 und schiebt sie dann vor den Anruf:

```
0x411f50: MOV EAX, dword ptr [EBP + 0x8]
0x411f53: ADD EAX, EAX
0x411f55: LEA EAX, [EAX + EAX*0x2]
0x411f58: LEA EAX, [EAX + EAX*0x4]
0x411f5b: ADD EAX, 0x14
0x411f5e: PUSH EAX
0x411f5f: CALL 0x00406400
0x411f64: ADD ESP, 0x4
```

### Was die Daten lesen, stellen Sie fest

REA Byte liest, dekodiert als Little-Endian-Doubles

| Anschrift | Wert | Verwendet für |
| --- | --- | --- |
| `0x420068` | `1.5625` | Erste Multiplikation |
| `0x420070` | `500.0` | Subtraktion |
| `0x4210a0` | `1.0` zunächst | Gespeicherte Pfannenwaage |

Aufgezeichnet mit REA 4.1.0 für das Hash-angeheftete DX-Ball 1.07-Ziel. Die verknüpften Ermittlungsnotizen behalten die Beweismittel-IDs bei.

[Gepflegte Quelle](https://github.com/N0zoM1z0/dx-ball/blob/a55dca27ec0a07018c1b2c95ae2be027f7d8c3c4/src/gameplay.c#L41) · [Ermittlungsnotizen und Beweisreferenzen](https://github.com/N0zoM1z0/dx-ball/blob/a55dca27ec0a07018c1b2c95ae2be027f7d8c3c4/docs/GAMEPLAY_OWNER.md)

## Überprüfen der wiederhergestellten Funktion

Die wiederhergestellte Funktion besteht zwei Prüfungen: Ihre Rückgabewerte stimmen mit dem Original überein und ihre kompilierten Bytes stimmen mit der ausführbaren Datei überein.

### 3.205 Verhaltensfälle

Die Tests führen die ursprüngliche x86-Funktion aus und vergleichen ihren Rückgabewert mit dem gepflegten C. Sie decken jede ganzzahlige Position von 0 bis 640 auf fünf Pan-Skalen ab: 0, 0,5, 1, 20 und -1.

### 63 übereinstimmende Bytes

Die C-Funktion wird mit der angehefteten VC4.0-Toolchain kompiliert. Die Compiler-Wiedergabe stimmt mit der vollständigen Funktion überein, nachdem die überprüften Verschiebungen angewendet und die referenzierten Konstanten überprüft wurden.

Bei einer Skala von 1 gibt die wiederhergestellte Berechnung -500 am linken Rand, 0 in der Mitte und 500 am rechten Rand zurück. Der nächste Teil der Audioarbeit besteht darin, diesen Wert in das Sound-Backend des Spiels zu integrieren.

[Lesen Sie die Compiler-Wiedergabedetails](https://github.com/N0zoM1z0/dx-ball/blob/a55dca27ec0a07018c1b2c95ae2be027f7d8c3c4/docs/BUILD_MATCHING.md)

## Setzen Sie die Untersuchung fort

Der gleiche Ansatz wird für Partikelaktualisierungen, Explosionswarteschlangen und Bonusgenerierung verwendet: Überprüfen Sie die relevanten Funktionen, stellen Sie ihren Zustand und ihre Abhängigkeiten wieder her und vergleichen Sie dann die Implementierung mit dem Original.

Um die Sound-Pan-Funktion selbst zu überprüfen, befolgen Sie die Einrichtungsanweisungen des DX-Ball-Projekts und geben Sie das passende Originalziel an. Dann lauf:

In der Kasse des DX-Ball

```
scripts/rea function original/DXBALL.EXE 0x00406400 \
  --snapshot .analysis/rea/dxball.snapshot.json --json
```

- [DX-Ball Archiv](https://github.com/N0zoM1z0/dx-ball)Aktuelle Quelle, Fortschritt und lokale Einrichtung.
- [REA Analyse-Arbeitsablauf](https://rea.tools/guides/native/)Befolgen Sie die Berechnung und verwenden Sie dann den gleichen Ansatz mit Ihrer eigenen Binärdatei.
- [Partikel- und Bonusproduktion](https://github.com/N0zoM1z0/dx-ball/blob/a55dca27ec0a07018c1b2c95ae2be027f7d8c3c4/docs/ENTITIES_OWNER.md)Eine größere Untersuchung zu Status, Warteschlangen und Pixelschreibvorgängen.

[Beginnen Sie mit Ihrem eigenen Ziel](https://rea.tools/get-started/)
