English Amiga Board

English Amiga Board (http://eab.abime.net/index.php)
-   Retrogaming General Discussion (http://eab.abime.net/forumdisplay.php?f=17)
-   -   Speedball 2 reverse engineering & remake (http://eab.abime.net/showthread.php?t=61305)

Kroah 05 October 2011 17:10

1 Attachment(s)
Hey all,

Two weeks ago, after the release of my Gods Viewer, i had a conversation with a friend about the feasibility of remaking a (not too big) Amiga/Atari game on Windows in less than 1 month, using my method of disassembling the games.

I should use the word "conversion" instead of "remaking" because the aim is to do an exact copy of the game on Windows, without improving it. Of course, we could still improve it after and port it to other systems if needed, but that's not the main objective.

By "conversion", i mean both games could be run side by side and they should have the exact same behavior, therefore the same displayed frames. This implies the game should not use any kind of clock based RNG (random number generator) but instead soft RNG algorithm.

To help the conversion process, 2 things are essential:
- A good knowledge of the game is needed to understand the disassembled game and the data structure. I want a comprehensible remake with some structured objects, NOT a blind conversion where each ASM line is converted one by one.
- The simultaneous and frame by frame run of both games helps a lot the debugging part. Being synced with the RNG, even the smallest bug have big consequences in the following frames. Correcting the bug and running the simulation again with the same RNG seed up to the previously bugged frame confirms or not if the bug has been correctly fixed.

Otherwise, there aren't any way to know that some parts are badly converted because they 'seem' behaving correctly (visually correct and no crash) but in fact are incorrect and behave differently from the original game, thus giving a different gameplay experience.

I want the game to have the exact same feeling and gameplay than the original game!

My Colonial Conquest remake and OpenTTD (Open Transport Tycoon Deluxe) are good examples of extended 1-1 conversion.

After this introduction, let's go to the game itself.
Being a fan of Bitmap Brother's game, my choice is Speedball 2. Yes, zenox98, you were right ;).

Right now, the game is disassembled and the match part is fully converted (jumping, tackling, AI, bonus, score multiplier, bouncers...).
The game runs exactly the same frames as the original one with the same RNG seed. There's no sound, and controls are really basic (no joypad support).

I still track some subtle bugs but I should release something soon.

I don't know if i will have enough time in the upcoming weeks to add the remaining parts (sound, training, league, cup, amiga gfx, etc).

I don't post any screenshot because it's the same as the original. So here's the field map with initial and ingame Team 1 location. You can see red zones used by the players to know where they should act.

Attachment 29568

Edit 2011/10/07: WIP 01 released (read the thread)
http://bringerp.free.fr/RE/Speedball2/Images/WIP 01.png

zenox98 05 October 2011 21:30

Woot :)

EreWeGo 06 October 2011 02:25

Cool project! Will be interested to see a working build......don't suppose you like Sensible World of Soccer 96/97? :)

Kroah 06 October 2011 16:19

Quote:

Originally Posted by EreWeGo (Post 779793)
Cool project! Will be interested to see a working build...

Yay, and the source will be available for curious people. It's always interesting to see what algorithms the game used (AI, engine, etc).
Imho, the AI is really incredible for its time. Computer controlled players can use all features on the field (score multiplier, electrobouncer, stars), pickup items, pass the ball, throw the ball, the goalkeeper blocks, etc... The chosen action depends on the player stats (aggressiveness, inteligence, ...). This gives the computer a deep and unpredictable gameplay.

Quote:

Originally Posted by EreWeGo (Post 779793)
...don't suppose you like Sensible World of Soccer 96/97? :)

Stop reading in my mind please...
Yes, SWOS is one of my favorite game. I played Kick Off too, but i always went back to Sensible Soccer.
3 games were listed for the remake: Speedball 2, SWOS and Kick Off 2. The votes went to Speedball 2 for the gameplay diversity, but SWOS was very close behind.

kriz 07 October 2011 01:34

Cool project !!

Kroah 07 October 2011 02:48

First WIP version of my Speedball 2 remake available!
http://bringerp.free.fr/RE/Speedball2/remake.php5

http://bringerp.free.fr/RE/Speedball2/Images/WIP 01.png

The game launches a demo match (AI vs AI) of Brutal Deluxe versus a random opponent.

You can take control of Brutal Deluxe at any time by moving a player. Then the game stays Human vs AI until the end of the match.
Be aware, the opponent may be highly overpowered (depending on which team you meet).

The match is played in 2 legs. There are no winning or losing screen.

Controls:
- arrow keys: move the player
- control: joystick button
- left mouse button: pause the game & step by step mode
- right mouse button: unpause game & fast forward mode

Remarks:
- keys may be unresponsive sometimes due to a very basic coding
- only the Atari version is supported right now
- no sound
- .Net Framework v3.5 required to run the game
- the game has mainly been tested AI vs AI (as explained above). I think there are some bugs left when controlling a team (for example, it seems there are sometimes no owned players on screen for several seconds, anyone confirms?)

Source are included. You can use the free Microsoft Visual Studio C# Express to browse or compile the source. No special external libraries are needed.

I'm trying now to incorporate Amiga gfx and sound.

Have fun!

copse 07 October 2011 11:10

Quote:

Originally Posted by Kroah (Post 779962)
Source are included. You can use the free Microsoft Visual Studio C# Express to browse or compile the source. No special external libraries are needed.

I'm trying now to incorporate Amiga gfx and sound.

Have fun!

You are a machine :) Thanks for releasing the source.

Is there any chance you could give some highlights of your approach? How much time do you spend reverse engineering and how often? Are there any tips that you'd give for how to streamline the process? Perhaps, just get it to recompile and then play with changing things? Or under a debugger/WinUAE do the same?

Kroah 07 October 2011 17:46

Quote:

Originally Posted by copse (Post 779984)
Is there any chance you could give some highlights of your approach? How much time do you spend reverse engineering and how often? Are there any tips that you'd give for how to streamline the process? Perhaps, just get it to recompile and then play with changing things? Or under a debugger/WinUAE do the same?

Well, i'll try to sum up the process.

I use the following Windows softwares:
- Steem Engine with its extremely powerful debugger (sorry, but WinUAE debugger is awful and unstable)
- IDA (something similar to ReSource) to disassemble
- Ultraedit to edit some hex files
- Visual Studio C# Express

Even if each game is specific, i usually follow this general guideline:
1) I run the game up to the part i want to disassemble, trying to load as much data as i can (some games load everything at start, others load gradually).

2) Then i save the state and dump the RAM to a file.
Using a dump (loaded code) and not directly the binary executable has several advantage:

- It bypasses the eventual protected loader and/or decryption part.
- Both IDA and the emulator share the same memory reference. No need to convert or relocate addresses between them.
- pointers point to real data whatever the addressing mode is (relative or absolute)
- Structures in IDA can be applied to these data.

This method is ideal if the objective is to undestand the game (not to get a "ready to assemble" code). I think the fastest way to do a remake is to first understand the game logic and structures, then port it to another language. Having 10k asm lines without understanding anything from it, is a real nightmare to port.

3) I run IDA and load the dump.

4) Using the emulator stack, i look for the entry point of the code and ask IDA to disassemble from there. Usually up to 75% of the code is disassembled. The remaining parts are jump tables, interrupt routines and lazy loading. They will be disassembled later.

5) The big analysis phase starts now. Routines, variables and structures are identified and named. It's very important to label the input/ouput variables of each function because they appear at the function call and allow to find the meaning and type of the passed variables.

6) First step: top-bottom analysis. If applicable to the game,i look for the main game loop (update, draw, update, draw...). I run the game up to the main game loop (for a platform game, i load the first level and move a little for example), then look at the stack. I peek the first return address on the stack and set IDA to this address. If i see something similar to a game loop, nice. Otherwise i get the following rts address on the stack and so on.

7) With the main game loop identified, i take 1 function call in IDA, NOP it in the emulator and interpret the result (ie. the status bar disappears). If this is an easy function (draw the score for example), i try to find the low-level routines (PlaySound, DrawGfx, ReadInput) used in it. They are used very often, are easy to locate and don't need to be understood in detail. Sometimes 5-10% of the code are drawing functions for every case possible (sprite size, location on the screen, pre-shifted gfx, etc.).

8) Second step: bottom-up analysis. For each low-level function identified, i use the cross reference in IDA to get all the function calls for it and then name the passed variables. As stated above, the input parameters (x,y) can be used to identify many (many!) variables passed.

9) I take a part of the game i know very well and try to understand as much code as possible (naming, commenting) without insisting. Then take another one. Like a puzzle, it's easier to build several small parts and link them together later than building around 1 part only.
The emulator is often used to set breakpoints on a variable R/W access or to NOP a call and see the result. This helps so much to understand the code.

10) I decode the loading part of the data and gfx (disk access, decryption, unpacking) and write a C# program to extract them from the original disk. This will be the base of a viewer or a remake. This can be hard because of a custom file system, an unknown compression routine or a difficult decryption algorithm. Even those are coded.

11) Now if i want to remake a part of the game, i have everything needed. The disassembled code is globally understood, data are extracted, structured objects are known.
I begin by the main loop and port it to the new language. I stub all important called functions and then convert them. The difficulty is to convert the routines while refactoring AND keeping the same behavior. That's why it's best to refactor step by step: first remove the spaghetti code (add 'if', 'else' and 'for', remove jumps), then structure the data (use local variables, remove global variables, use identified structures).
Some functions will still be coded line by line from asm to get the exact same result, mainly routines with binary operations (random number generator, optimized math algebra).

12) To find incorrect behavior, the remake is run side by side with the emulator and frame by frame. As soon as a discrepancy is noticed, the previous frame is run step by step until the divergence is found.

For Speedball 2, i have disassembled and analyzed the code for ~40 hours. The remake took me about 20 hours to code and 20 hours to find discrepancies ('<' instead of '<=' for example) for a total of ~80hours over 3 weeks.
A full remake should take another 50 hours because there are a lot of screens with menus, sounds to rip, etc... without talking about the amiga gfx decoding.

Hope you liked the read,
Cheers

zenox98 07 October 2011 18:51

Quote:

Originally Posted by Kroah (Post 780034)
sorry, but WinUAE debugger is awful and unstable

Ouch! Beware the wrath of Toni :)


This is really cool reading. Thanks for sharing.

Kroah 07 October 2011 19:20

Quote:

Originally Posted by zenox98 (Post 780046)
Ouch! Beware the wrath of Toni :)

;) Maybe i should update my WinUAE install by the way, it dates from... 2006? hum...

Here's an excerpt of a subroutine in IDA and it's port in C#. You see, when variables and functions are named, it's not a difficult task. Only few functions uses a crazy amount of jumps, making it difficult to code.

http://bringerp.free.fr/Files/Speedb...ll 2 - IDA.png

C#:
Code:

    private void HandleTime () {
      _remainingTimeInTheSecond -= _timeSpeed;
      if (_remainingTimeInTheSecond <= 0) {
        _remainingTimeInTheSecond = 50;
        _stars.CheckFullRowActivated (this);
        if (!Bit7_IsClockPaused) {
          _legRemainingTime--;
          IncrementTimeInPossession ();
        }
        if (_token._heldSpriteIndex != 0)
          _token._remainingSeconds--;
        DrawStatusRemainingTime ();
        [...]
    }


Toni Wilen 07 October 2011 19:28

(Win)UAE debugger is crap (but it isn't unstable), it was never meant to be any kind of fully featured m68k debugger.

AFAIK it was originally only made to debug some compatibility problems, show custom chipset etc register contents and other state information, it is do-it-yourself debugger, new option/function is added when needed :)

Kroah 07 October 2011 19:51

Quote:

Originally Posted by Toni Wilen (Post 780051)
(Win)UAE debugger is crap (but it isn't unstable)

By unstable, i didn't mean crash, but the windows freezes (can't type anything in the command line) or disappears. Then i relaunch WinUAE and everything is fine. As i said, my install is old and i should update it before crying :).

Quote:

Originally Posted by Toni Wilen (Post 780051)
it was never meant to be any kind of fully featured m68k debugger.
AFAIK it was originally only made to debug some compatibility problems, show custom chipset etc register contents and other state information, it is do-it-yourself debugger, new option/function is added when needed :)

As you explain it well, i'm looking for something the WinUAE debugger is not meant to do at his stage of development, until someone add it. In fact, this is the fault of Steem Engine, his debugger is particularly powerful and we are used to it really quickly, so when i go to another debugger (Atari800, WinUAE), i feel very limited.
Anyway, thanks for the debugger, i still use it regularly when i debug on Amiga :).

Kroah 11 October 2011 00:32

WIP updated: http://bringerp.free.fr/RE/Speedball2/remake.php5

- Amiga graphics have been added.
- Both teams are random.

I've tried to add sound support... but thanks to Richard Joseph, even the in-game sounds use his custom player.
I've extracted the samples but the volume, the pitch and loops are updated in realtime. I don't see how i can easily implements this without a decent sound library and a good amount of time.

FYI, all graphics are extracted in their respective Amiga & Atari folder at runtime, this explains the initial long startup.

This remake being a POC (proof of concept), i don't think i will go any further.

Amiga Forever 11 October 2011 01:20

Will have Online?...so that we can play against Human than CPU(Computer AI) :)

Kroah 11 October 2011 02:14

Quote:

Originally Posted by Amiga Forever (Post 780499)
Will have Online?...so that we can play against Human than CPU(Computer AI) :)

Nice idea, but adding multiplayer support is not an easy task. Without talking about copyright issues.
Someone asked me to work on a Sensible Soccer remake too, but for the same reasons, i don't think we can do a complete remake.

Amiga Forever 11 October 2011 02:19

Try make Different Name on the game or anythings that you can get round it ;):great

Kroah 11 October 2011 02:22

While running the remake AI vs AI in loop to find bugs, i stumbled upon a bug.
I launched Steem and injected the random number generator seed and the team composition, I set the first player as computer and ran the game.

What was my surprise when i saw the game had the same bug. It did not crash the game, but one frame had an incorrect sprite (the remake raised an exception because it checks bounds).

Before:
http://bringerp.free.fr/Files/Speedb...g%20Before.png

After:
http://bringerp.free.fr/Files/Speedb...ug%20After.png

Notice the middle player sprite.
I don't know if the same bug occurs in the Amiga version.

CaptainNow 14 April 2015 21:00

Is this still going? I just stumbled across this completely by accident and nearly wet my pantaloons...what a stunning piece of work!

Kroah 14 April 2015 22:34

Quote:

Originally Posted by LordNipple (Post 1014945)
Is this still going? I just stumbled across this completely by accident and nearly wet my pantaloons...what a stunning piece of work!

Thank you, but most of the work has been done by the Bitmap Brothers. I've "only" translated the game from a language to another like we can do it from Java to C#, sort of ;).

I haven't planned to complete the port of this game because of copyrights. I don't own them and the owners are still actively (or recently) developing games for this franchise on different platforms.

I would be very disappointed if i receive a mail asking me to remove all materials about this game from my site. So i let the demo "as is", hoping they understand this unfinished game is only there for the show.

padrino 11 December 2018 19:44

Hi,

just saw a video on YT, where Chris White (the guy from the Cannonball Enginge of Outrun) tells a story about porting Speedball 2). :D

https://www.youtube.com/watch?v=OvmJ...youtu.be&t=466

Now, that's not you, is it? ;)

CU,
padrino


All times are GMT +2. The time now is 08:18.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2021, vBulletin Solutions Inc.

Page generated in 0.04734 seconds with 11 queries