How hard would it be to hack these racers?
How hard would it be to hack these racers?
I've been playing Super Hang-On and OutRun lately. SHO is one of my favourites and I have a soft spot for OR , in spite of all its flaws.
Now, I noticed 2 things that many of you may also have noticed but unfortunately I don't know enough of programming/disassembling to even make a guess if the hacks I imagined are possible. Tell me what you think!
Here goes:
1 - S.H.O. - When you hit the brakes the bike swings from left to right (or right to left) much faster than it would normally do. So, braking apart from reducing speed also works as a direction speed modifier? If this is already encoded in the game, could it be triggered, binded or linked to left/right keys so that it would work like that (faster) permanently?
2 - O.R. 48k - When you load the game and start demo mode, did you notice the game plays faster while the revs sound is absent? Is this a coincidence? Could it be possible to disable revs sound by doing some poking to test this theory?
Now, I noticed 2 things that many of you may also have noticed but unfortunately I don't know enough of programming/disassembling to even make a guess if the hacks I imagined are possible. Tell me what you think!
Here goes:
1 - S.H.O. - When you hit the brakes the bike swings from left to right (or right to left) much faster than it would normally do. So, braking apart from reducing speed also works as a direction speed modifier? If this is already encoded in the game, could it be triggered, binded or linked to left/right keys so that it would work like that (faster) permanently?
2 - O.R. 48k - When you load the game and start demo mode, did you notice the game plays faster while the revs sound is absent? Is this a coincidence? Could it be possible to disable revs sound by doing some poking to test this theory?
Last edited by Old-User on Wed Dec 20, 2023 8:16 pm, edited 1 time in total.
- WhatHoSnorkers
- Manic Miner
- Posts: 255
- Joined: Tue Dec 10, 2019 3:22 pm
Re: How hard would it be to hack these racers?
I didn't know how to get demo mode to start, but in 48K mode the revs sounds will slow things down because there's no dedicated sound chip. Disabling that sounds interesting!
I have a little YouTube channel of nonsense
https://www.youtube.com/c/JamesOGradyWhatHoSnorkers
https://www.youtube.com/c/JamesOGradyWhatHoSnorkers
Re: How hard would it be to hack these racers?
Just press any key other than 1,2,3, or M.WhatHoSnorkers wrote: ↑Wed Dec 20, 2023 8:16 pm I didn't know how to get demo mode to start, but in 48K mode the revs sounds will slow things down because there's no dedicated sound chip. Disabling that sounds interesting!
Yes, I also speculated that and since it seems to makes things faster in the demo then perhaps it would be a fairly simple hack.
The corner-drifting sound doesn't seem to be critical in the demo and while the gear-change tyre spin sound isn't heard, mimic the demo mode could be a way to improve gameplay.
- Lee Bee
- Dynamite Dan
- Posts: 1359
- Joined: Sat Nov 16, 2019 11:01 pm
- Location: Devon, England
- Contact:
Re: How hard would it be to hack these racers?
Speaking of sound, Super-Hang on had a lovely arcade soundtrack. If anyone hacks this and can add music, I can happily provide the music. (Already did the original Hang On music.)
Re: How hard would it be to hack these racers?
Well, I've been tinkering with the debugger inside the Spin emulator.WhatHoSnorkers wrote: ↑Wed Dec 20, 2023 8:16 pm I didn't know how to get demo mode to start, but in 48K mode the revs sounds will slow things down because there's no dedicated sound chip. Disabling that sounds interesting!
I can barely understand what I'm looking at but I was able to recognize some "out" instructions to port 254 on certain locations. After some trial and error attempts I did manage to disable the menu music and all the sound fx during gameplay. But the game doesn't get any faster.
And then it hit me, I'm just nop'ing the speaker activation but the sound routines must be still running in the background taking cpu power...
Disassembling is not my cup of tea!
- ParadigmShifter
- Manic Miner
- Posts: 765
- Joined: Sat Sep 09, 2023 4:55 am
Re: How hard would it be to hack these racers?
Put a breakpoint on an OUT instruction that activates the speaker.
Look at the stack and work out the return address (may not be on the top of the stack. Look at the code and see which address on the stack corresponds to an instruction following a call). Or step through until you reach a RET instruction and see where you end up after executing that.
Comment out the CALL instruction (may be a conditional call e.g. CALL Z) by inserting NOPs instead. See if that still works and at least one sound is gone.
That's assuming the sound effects routine is called of course rather than duplicated in the code (e.g. only done once in 1 place in the gameloop so doesn't need to be a call). If it's not called you need to find where it loops and repeatedly does an OUT instruction and replace the beginning of that with a JP <address after the loop finishes>.
One of those 2 things should probably work.
Sfx loops typically look something like this, with some setup code beforehand which you probably also want to skip.
Sometimes they might use OUT (C), A instead of OUT (#FE), A (and then dec another register in the outer loop).
Look at the stack and work out the return address (may not be on the top of the stack. Look at the code and see which address on the stack corresponds to an instruction following a call). Or step through until you reach a RET instruction and see where you end up after executing that.
Comment out the CALL instruction (may be a conditional call e.g. CALL Z) by inserting NOPs instead. See if that still works and at least one sound is gone.
That's assuming the sound effects routine is called of course rather than duplicated in the code (e.g. only done once in 1 place in the gameloop so doesn't need to be a call). If it's not called you need to find where it loops and repeatedly does an OUT instruction and replace the beginning of that with a JP <address after the loop finishes>.
One of those 2 things should probably work.
Sfx loops typically look something like this, with some setup code beforehand which you probably also want to skip.
Code: Select all
.sfx
out (#fe), a
xor #18 ; or something similar which also toggles some bits in A (bit 4 and 5 looks like, either one or both)
ld b, d ; or some other register. May read from some memory location to get the value instead I guess
.sfxdelay
djnz .sfxdelay
dec c
jr nz, .sfx
Re: How hard would it be to hack these racers?
@ParadigmShifter : Thank you for your advice!
I'll take another look and follow your instructions.
Will report back later with the findings.
I'll take another look and follow your instructions.
Will report back later with the findings.
- ParadigmShifter
- Manic Miner
- Posts: 765
- Joined: Sat Sep 09, 2023 4:55 am
Re: How hard would it be to hack these racers?
In case you didn't know
opcode for NOP is 0
opcode for JP NN is $C3 = 195 decimal followed by 2 bytes for the address to jump to. The low bye is stored first so JP 1234 = JP $04D2 so you would change that instruction to the 3 byte sequence $C3 $D2 $04
Windows calculator in Programmer mode shows you numbers you type in both hex and decimal. Dunno why they removed the Statistics mode from recent versions of Windows, I used to use that quite a bit
Once you do that you should see the instruction change in the disassembly window.
EDIT: There's a chance that the program uses the fact that the loop counter registers will be 0 in the code following the loop (I do that in my code base quite a bit lol). If that is the case you would replace my example code snippet with LD BC, 0 then JP <addr> instructions. Look for stuff like LD reg, B or LD reg, C without first setting B or C to another value to see if they are doing that.
LD BC, 0 encodes as $01 $00 $00
I use this site to look up opcode values btw (also has instruction timings)
https://map.grauw.nl/resources/z80instr.php
opcode for NOP is 0
opcode for JP NN is $C3 = 195 decimal followed by 2 bytes for the address to jump to. The low bye is stored first so JP 1234 = JP $04D2 so you would change that instruction to the 3 byte sequence $C3 $D2 $04
Windows calculator in Programmer mode shows you numbers you type in both hex and decimal. Dunno why they removed the Statistics mode from recent versions of Windows, I used to use that quite a bit
Once you do that you should see the instruction change in the disassembly window.
EDIT: There's a chance that the program uses the fact that the loop counter registers will be 0 in the code following the loop (I do that in my code base quite a bit lol). If that is the case you would replace my example code snippet with LD BC, 0 then JP <addr> instructions. Look for stuff like LD reg, B or LD reg, C without first setting B or C to another value to see if they are doing that.
LD BC, 0 encodes as $01 $00 $00
I use this site to look up opcode values btw (also has instruction timings)
https://map.grauw.nl/resources/z80instr.php
- ParadigmShifter
- Manic Miner
- Posts: 765
- Joined: Sat Sep 09, 2023 4:55 am
Re: How hard would it be to hack these racers?
PM sent. (Well 2 actually). EDIT: 3 now lol
Looks like it is a routine that is called so NOP out the CALL (need to NOP 3 bytes to remove that).
Looks like it is a routine that is called so NOP out the CALL (need to NOP 3 bytes to remove that).
Re: How hard would it be to hack these racers?
Success!
All right people, this little hack for Outrun (disabling the ingame revs sound fx) seems to be working fine.
I must thank @ParadigmShifter for his invaluable help that allowed this happy development.
I don't think I could have done this without him.
I have been trying this on emulators but I still want to put real hardware to the test:
Poke 31005,0
Poke 31006,0
Poke 31007,0
and the revs sound during gamplay is gone.
Remember the target machine is 48k and this was a humble attempt at improving the game performance.
Does it work? Well, don't expect the game to run twice as fast.
In fact, don't get your hopes high, it's not a game changer at all but hopefully it should slightly enhance control responsiveness.
Let me know if you experience any difference for the better.
EDIT: BTW, one other thing that I think that could also be useful in this whole matter... I know this is highly subjective and while I cannot offer any evidence of I suspect not all outrun roms found 'out there' which I've tried perform equally. There is one tap file I found at spectrum4ever.org, a cracked version by Nicolas Rodionov and Kiril Panyushkin made back in 89 that seems to me it's the "faster" one. If this is true, did they intentionally or inadvertently caused that side effect?
Well, try that one with the above pokes and see if you notice anything different. Perhaps I'm talking silly but 1-2 fps more in this game makes me happy.
All right people, this little hack for Outrun (disabling the ingame revs sound fx) seems to be working fine.
I must thank @ParadigmShifter for his invaluable help that allowed this happy development.
I don't think I could have done this without him.
I have been trying this on emulators but I still want to put real hardware to the test:
Poke 31005,0
Poke 31006,0
Poke 31007,0
and the revs sound during gamplay is gone.
Remember the target machine is 48k and this was a humble attempt at improving the game performance.
Does it work? Well, don't expect the game to run twice as fast.
In fact, don't get your hopes high, it's not a game changer at all but hopefully it should slightly enhance control responsiveness.
Let me know if you experience any difference for the better.
EDIT: BTW, one other thing that I think that could also be useful in this whole matter... I know this is highly subjective and while I cannot offer any evidence of I suspect not all outrun roms found 'out there' which I've tried perform equally. There is one tap file I found at spectrum4ever.org, a cracked version by Nicolas Rodionov and Kiril Panyushkin made back in 89 that seems to me it's the "faster" one. If this is true, did they intentionally or inadvertently caused that side effect?
Well, try that one with the above pokes and see if you notice anything different. Perhaps I'm talking silly but 1-2 fps more in this game makes me happy.
Last edited by Old-User on Thu Feb 29, 2024 2:37 am, edited 2 times in total.
- ParadigmShifter
- Manic Miner
- Posts: 765
- Joined: Sat Sep 09, 2023 4:55 am
Re: How hard would it be to hack these racers?
You sent me 1 page of the disassembly and it seems the programmers were drunk or tripping when they wrote it lol. Maybe it's done for precise timing reasons but I doubt it
The Super Hang On thing sounds much more difficult to modify since it involves actual game logic rather than just removing SFX.
EDIT: Although 1278 is in the ROM so maybe they have some self modifying code going on there (modifying the LD HL, 1278 operand) thinking about it, to produce some white noise. But even so, there's no need to repeatedly write it back to address 34680 each time it jumps to the outerloop.
I am a bit drunk (but not tripping).
Code: Select all
PlayRevsFunction:
LD HL, 1278 ; $4FE
INC L ; why not just LD HL, 1279 = $4FF?
LD (34680), HL ; this is done every iteration of the loop even though HL never changes after this point
Whynotloophere
LD A, (HL); this is probably speed conversion to frequency to toggle the speaker variable
; snip. HL never changes now and it does a double loop toggling the speaker
JR NZ, PlayRevsFunction ; JR NZ, Whynotloophere would probably be better
EDIT: Although 1278 is in the ROM so maybe they have some self modifying code going on there (modifying the LD HL, 1278 operand) thinking about it, to produce some white noise. But even so, there's no need to repeatedly write it back to address 34680 each time it jumps to the outerloop.
I am a bit drunk (but not tripping).
Re: How hard would it be to hack these racers?
You are probably right, that 1278 was when I took the picture but its not always that same value, it changes.
- ParadigmShifter
- Manic Miner
- Posts: 765
- Joined: Sat Sep 09, 2023 4:55 am
Re: How hard would it be to hack these racers?
Not too drunk then yet
It's not self modifying that code in that function though so there's no need to repeatedly write it back to 34680. Unless they do that just to waste some T states so that the OUT instructions occur at some multiple of 8T (which is apparently a thing you should do, I know not much about SFX stuff).
I would assume precise timing of the OUT instructions are not required if it's some kind of noise generation though :/
It's not self modifying that code in that function though so there's no need to repeatedly write it back to 34680. Unless they do that just to waste some T states so that the OUT instructions occur at some multiple of 8T (which is apparently a thing you should do, I know not much about SFX stuff).
I would assume precise timing of the OUT instructions are not required if it's some kind of noise generation though :/
- ParadigmShifter
- Manic Miner
- Posts: 765
- Joined: Sat Sep 09, 2023 4:55 am
Re: How hard would it be to hack these racers?
You could try NOPing out a HALT instruction in the main loop if there is one (usually when you debug break in Spin debugger it is executing a HALT instruction if there is one I find) but that may cause screen tearing etc since drawing will not be synced to the vertical blank. And the frame rate may be super variable then which looks bad, running at a constant frame rate is usually better.
Unless they use the floaty bus thingio which would not use a HALT in the gameloop.
EDIT: I was also surprised they call the SFX routine from an address below 32768 so it is in contended memory which slows things down overall (unless it is drawing the border top or bottom IIRC). Maybe the code and graphics are massive so they couldn't put all the code in uncontended RAM though.
I try and put all my important for speed stuff in uncontended memory, set the stack pointer to uncontended memory as well (looks like they have done that in Out Run) and put all the front end code and graphics and stuff that is called very rarely or in exceptional circumstances below 32768 (so for SJOE things like scoring which is done only when you make a word and it's not drawing much to the screen on the frame that happens either). But that looks like it is part of the main loop.
Unless they use the floaty bus thingio which would not use a HALT in the gameloop.
EDIT: I was also surprised they call the SFX routine from an address below 32768 so it is in contended memory which slows things down overall (unless it is drawing the border top or bottom IIRC). Maybe the code and graphics are massive so they couldn't put all the code in uncontended RAM though.
I try and put all my important for speed stuff in uncontended memory, set the stack pointer to uncontended memory as well (looks like they have done that in Out Run) and put all the front end code and graphics and stuff that is called very rarely or in exceptional circumstances below 32768 (so for SJOE things like scoring which is done only when you make a word and it's not drawing much to the screen on the frame that happens either). But that looks like it is part of the main loop.
Re: How hard would it be to hack these racers?
I think @ParadigmShifter has got so excited about hacking the poor outrun code that by this time tomorrow he will have disassembled the whole game and optimized performance by 200%!
- ParadigmShifter
- Manic Miner
- Posts: 765
- Joined: Sat Sep 09, 2023 4:55 am
Re: How hard would it be to hack these racers?
Nah hacking is too difficult it's best to use something like Skoolkit to generate labels so you can move stuff about rather than poking NOPs everywhere.
That's a massive task though and I didn't even like Out Run much in the arcade either Space Harrier was more my thing. I did hear Out Run was a bad port though compared to something like Hang On which was excellent. (Out Run probably way too ambitious really anyway).
Anyway glad to help you did the hard work by identifying where the OUT instruction was that made the revs sound. Once you find the code you want to modify/disable it's usually pretty easy to know what to do (don't call it or skip over it to remove it). There's only really a few ways to easily do that as I elaborated on in this thread.
That's a massive task though and I didn't even like Out Run much in the arcade either Space Harrier was more my thing. I did hear Out Run was a bad port though compared to something like Hang On which was excellent. (Out Run probably way too ambitious really anyway).
Anyway glad to help you did the hard work by identifying where the OUT instruction was that made the revs sound. Once you find the code you want to modify/disable it's usually pretty easy to know what to do (don't call it or skip over it to remove it). There's only really a few ways to easily do that as I elaborated on in this thread.
Re: How hard would it be to hack these racers?
This code isn't located at 34679 by any chance? I.e. is the LD HL,1258 lowered byte being updated by the LD (34680), HL, so subsequent calls will carry on from where this left off? Still could probably have just done it once after the loop but hey ho...ParadigmShifter wrote: ↑Thu Feb 29, 2024 2:44 am Not too drunk then yet
It's not self modifying that code in that function though so there's no need to repeatedly write it back to 34680. Unless they do that just to waste some T states so that the OUT instructions occur at some multiple of 8T (which is apparently a thing you should do, I know not much about SFX stuff).
I would assume precise timing of the OUT instructions are not required if it's some kind of noise generation though :/
Re: How hard would it be to hack these racers?
It would still be slow as fuk though
Website: Tardis Remakes / Mostly remakes of Arcade and ZX Spectrum games.
My games for the Spectrum: Dingo, The Speccies, The Speccies 2, Vallation & Sqij.
Twitter: Sokurah
My games for the Spectrum: Dingo, The Speccies, The Speccies 2, Vallation & Sqij.
Twitter: Sokurah
- ParadigmShifter
- Manic Miner
- Posts: 765
- Joined: Sat Sep 09, 2023 4:55 am
Re: How hard would it be to hack these racers?
Correct, you are right.
Beer O'Clock goggles did not notice that well done.
So each time it does an OUT it bumps the value of the low byte so it reads from $400 to $4FF in ROM to get some randomish data.
- ParadigmShifter
- Manic Miner
- Posts: 765
- Joined: Sat Sep 09, 2023 4:55 am
Re: How hard would it be to hack these racers?
This is the code snippet I was sent anyway
https://ibb.co/PG1sB7g
Was enough for me to identify that the call was located at the instruction before the return address (31008).
https://ibb.co/PG1sB7g
Was enough for me to identify that the call was located at the instruction before the return address (31008).
Re: How hard would it be to hack these racers?
This is interesting.
I examined the headers of the game levels (stages) with tapir and found that by changing the value of one byte it is possible to set the paper color of the playing area, with or without bright.
This means it's possible to alter the predefined colors of the stages and create a customized set for every route according to personal preference.
For example, stage 1 header:
Green - 23
Bright Green - 62
Yellow - 30
Bright Yellow - 72
Red - 12
Bright Red - 51
White - 3B
Bright White - 7B
It's even possible to set colors not used in the game, like blue and cyan.
Edit: I've been looking at the game map...
and I feel there are some stages that need recoloring (stage 1 should be yellow instead of green?)
Which colors do you think best suit the stages?
I examined the headers of the game levels (stages) with tapir and found that by changing the value of one byte it is possible to set the paper color of the playing area, with or without bright.
This means it's possible to alter the predefined colors of the stages and create a customized set for every route according to personal preference.
For example, stage 1 header:
Green - 23
Bright Green - 62
Yellow - 30
Bright Yellow - 72
Red - 12
Bright Red - 51
White - 3B
Bright White - 7B
It's even possible to set colors not used in the game, like blue and cyan.
Edit: I've been looking at the game map...
and I feel there are some stages that need recoloring (stage 1 should be yellow instead of green?)
Which colors do you think best suit the stages?
Re: How hard would it be to hack these racers?
Hi @Old-User
Glad you have some progress with Outrun.
I did some research and found that some code does indeed run in slow memory and it costs up to 20% of performance (I compared the speed of the game running on original 128k machine vs running on pentagon (both emulated)).
Glad you have some progress with Outrun.
I did some research and found that some code does indeed run in slow memory and it costs up to 20% of performance (I compared the speed of the game running on original 128k machine vs running on pentagon (both emulated)).
Re: How hard would it be to hack these racers?
Hello!thealfest wrote: ↑Sun Mar 03, 2024 2:36 pm Hi @Old-User
Glad you have some progress with Outrun.
I did some research and found that some code does indeed run in slow memory and it costs up to 20% of performance (I compared the speed of the game running on original 128k machine vs running on pentagon (both emulated)).
It was a small breakthrough, but I'm happy considering how little my knowledge on this subject is.
So you have confirmed that 128K version does run a bit slower? That's really unfortunate.
(What about forcing 48k version to run on 128k machine as 48k version, i.e. , no ay, no bank switching? Assuming that's possible to hack would there be any benefit compared to a 48k machine?)
I have mixed feelings about the 128k version. On one hand it feels more complete because of the added graphic details and the AY tunes but I find the sfx unsuitable (beeper were better suited) and the slower gameplay spoils whatever fun still left.
That's why I'm sticking with the 48k version.