News: 11 March 2016 - Forum Rules
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia, Danke

Author Topic: bad coding in roms  (Read 32809 times)

Normmatt

  • Full Member
  • ***
  • Posts: 137
    • View Profile
Re: bad coding in roms
« Reply #80 on: April 08, 2013, 01:55:08 am »
I see this a lot in Intelligent System's coding. It irks me because it wastes a *lot* of space (One 32-bit pointer per possible input) and if it somehow ever got a value out of range it'd jump to a garbage address.

Code: [Select]
08085430 0080     lsl     r0,r0,#0x2 ;Input here is lsl'd by four
08085432 4903     ldr     r1,=#0x8085444 ;A list of pointers here
08085434 1840     add     r0,r0,r1
08085436 6800     ldr     r0,[r0]
08085438 4687     mov     r15,r0 ;Then just updates the program counter. ;_;

This particular example is from Advance Wars 2. Although it seems to be in a lot of IS' GUI code. :|

That isn't bad coding. That is simply how jump tables are handled on arm. The default case (if the index is out of bounds etc) is generally handled before this segment of code so it's perfectly safe.

Bisqwit

  • Sr. Member
  • ****
  • Posts: 368
  • Polite, but politically incorrect.
    • View Profile
    • http://iki.fi/bisqwit/
Re: bad coding in roms
« Reply #81 on: April 10, 2013, 01:05:38 am »
In Simon's Quest:

Code: [Select]
PlotAction05_RunGameMaybe
        $CC24  A5 2C:       lda PlotAction05_GameLoop_WhichAction
        $CC26  C9 03:       cmp #$03
        $CC28  D0 0B:       bne +               ; $CC35
        $CC2A  20 15 C6:    jsr RenderHPbar
        $CC2D  20 08 D3:    jsr GameLoop_CheckIfPauseEnteredOrActive
        $CC30  A5 26:       lda GamePaused
        $CC32  F0 01:       beq +               ; $CC35
        $CC34  60:          rts

+       $CC35  A5 2C:       lda PlotAction05_GameLoop_WhichAction
        $CC37  20 BB C5:    jsr JumpWithParams
_JumpPointerTable_1CC3A
        $CC3A  54 CC:       .word (PlotAction05_Action00_ShowGameBeginScreenWithRemainingLives
        $CC3C  7E CC:       .word (PlotAction05_Action01_LevelLoad_ResetNPCs) ;CC7E (1CC7E) ()
        $CC3E  9A CC:       .word (PlotAction05_Action02_LevelLoad_Part2) ;CC9A (1CC9A) ()
        $CC40  D5 CD:       .word (PlotAction05_Action03_GameActive) ;CDD5 (1CDD5) ()
        $CC42  A2 CE:       .word (PlotAction05_Action04_NightTimeTransition_Begin) ;CEA2 (1CE
        $CC44  B8 CE:       .word (PlotAction05_Action05_NightTimeTransition_FadeOutLoop) ;CEB
        $CC46  CF CE:       .word (PlotAction05_Action06_NightTimeTransition_Middle) ;CECF (1C
        $CC48  F4 CE:       .word (PlotAction05_Action07_NightTimeTransition_FadeInLoop) ;CEF4
        $CC4A  8C CF:       .word (PlotAction05_Action08_RelocateSimonLevelBeginningMaybe) ;CF
        $CC4C  3A D0:       .word (PlotAction05_Action09_EnterOrExitRoom) ;D03A (1D03A) ()
        $CC4E  75 D0:       .word (PlotAction05_Action0A_RelocateSimonLevelBeginningMaybe) ;D0
        $CC50  03 D0:       .word (PlotAction05_Action0B) ;D003 (1D003) ()
        $CC52  79 CE:       .word (PlotAction05_Action0C) ;CE79 (1CE79) () 

For some unidentified reason, the game does an explicit check here whether the state is #3, and if it is, runs RenderHPbar, GameLoop_CheckIfPauseEnteredOrActive, and a check for GamePaused, and then anyway proceeds to branch using a jump table depending on the state number, instead of doing that stuff in the beginning of PlotAction05_Action03_GameActive, the routine that would be called if state indeed is #3. (And this is indeed the only location that accesses PlotAction05_Action03_GameActive).

Dwedit

  • Sr. Member
  • ****
  • Posts: 300
    • View Profile
    • Dwedit's Website
Re: bad coding in roms
« Reply #82 on: April 10, 2013, 10:32:08 pm »
Some of the dumber things I've seen I've chalked up to macros, such as code that performs arithmetic operations to build up a constant. Example:

Code: [Select]
lda #$0030
add #$0100
ora #$8000

instead of:
Code: [Select]
lda #$8130


On ARM, you pretty much have to build constants that way, since you can only fit 8 shifted bits of value into a constant.  The code would be two instructions to store 0x8130 into a register.
But this makes no sense on a 6502-style processor.
"We are merely sprites that dance at the beck and call of our button-pressing overlord."

Xenesis

  • Jr. Member
  • **
  • Posts: 90
  • Syogun Changer
    • View Profile
    • Wars World News
Re: bad coding in roms
« Reply #83 on: April 11, 2013, 08:18:29 pm »
That isn't bad coding. That is simply how jump tables are handled on arm. The default case (if the index is out of bounds etc) is generally handled before this segment of code so it's perfectly safe.

I'm aware of that, but it's so incredibly wasteful - it's a jump table with only 10 values that do anything and over a hundred null values.

Also, using mov r15 instead of bx always feels hacky.

FinS

  • Full Member
  • ***
  • Posts: 190
    • View Profile
    • nothing much
Re: bad coding in roms
« Reply #84 on: April 14, 2013, 01:03:25 pm »
Here's an easy one for SNES.
Code: [Select]
$03/BB5F A5 15       LDA $15   
$03/BB61 8D 04 42    STA $4204 
$03/BB64 9C 05 42    STZ $4205 
$03/BB67 A9 03       LDA #$03   
$03/BB69 8D 06 42    STA $4206 
$03/BB6C 20 B8 BF    JSR $BFB8 

$03/BFB8 EA          NOP       
$03/BFB9 60          RTS       

$03/BB6F 7B          TDC       
$03/BB70 AD 14 42    LDA $4214 
$03/BB73 0A          ASL A     
$03/BB74 AA          TAX       
$03/BB75 FA          PLX       
$03/BB76 7A          PLY       
$03/BB77 A9 3F       LDA #$3F   
It could have been more effectively written.
Code: [Select]
$03/BB5F 80 14       BRA 20
(NOP X 20 or fill in the blank)
$03/BB75 FA          PLX       
$03/BB76 7A          PLY       
$03/BB77 A9 3F       LDA #$3F 

KingMike

  • Forum Moderator
  • Hero Member
  • *****
  • Posts: 6480
  • *sigh* A changed avatar. Big deal.
    • View Profile
Re: bad coding in roms
« Reply #85 on: April 14, 2013, 01:46:12 pm »
I understand a delay is needed when using the multiplication/division registers, but when it seems to completely throw out the results at the end, what's the point of the code?
Quote
Sir Howard Stringer, chief executive of Sony, on Christmas sales of the PS3:
"It's a little fortuitous that the Wii is running out of hardware."

FinS

  • Full Member
  • ***
  • Posts: 190
    • View Profile
    • nothing much
Re: bad coding in roms
« Reply #86 on: April 14, 2013, 02:13:31 pm »
I understand a delay is needed when using the multiplication/division registers, but when it seems to completely throw out the results at the end, what's the point of the code?

Exactly. The only thing I can think is that they were originally trying to do something with it then decided against it but failed to clean up the code.

KC

  • Full Member
  • ***
  • Posts: 209
    • View Profile
Re: bad coding in roms
« Reply #87 on: October 25, 2013, 03:18:51 pm »
I found the perfect code to revive this topic: http://puu.sh/4ZjgS/af6ace21f3.png
The function jal jumps to is computing the length of the string given in a0: http://puu.sh/4Zk2B/dbb47c98f8.png

So the function in the first picture pretty much does...
Code: [Select]
int func(char* str)
{
int k = 0;
while (strlen(str) > k) k++;
return k;
}

BRPXQZME

  • Hero Member
  • *****
  • Posts: 4572
  • じー
    • View Profile
    • The BRPXQZME Network
Re: bad coding in roms
« Reply #88 on: October 27, 2013, 05:49:59 am »
It’s not a ROM, and it’s not an O(n2) strlen, but the XL Engline people recently found something similarly pointless in Daggerfall.

Silly compilers think alike, perhaps? One would hope, but you never know... ;)
we are in a horrible and deadly danger

FinS

  • Full Member
  • ***
  • Posts: 190
    • View Profile
    • nothing much
Re: bad coding in roms
« Reply #89 on: March 02, 2014, 11:02:24 am »
I have no idea what's going on here but the game appears to have successfully jumped into and navigated a pointer table.
Congrats! Densetsu no Ogre Battle!

I found this in my hack and looked at the original to see it was in there even before translation.

It occurs at the end of the opening sequence story.

Code: [Select]
$00/D86B A5 0A       LDA $0A    [$00:000A]   A:0AC0 X:006C Y:5501 P:envmxdizC
$00/D86D 20 D2 F5    JSR $F5D2  [$00:F5D2]   A:0200 X:006C Y:5501 P:envmxdizC
**********
$00/F5D2 A2 01 FF    LDX #$FF01              A:0200 X:006C Y:5501 P:envmxdizC
$00/F5D5 A0 E0 00    LDY #$00E0              A:0200 X:FF01 Y:5501 P:eNvmxdizC
$00/F5D8 C9 7F D0    CMP #$D07F              A:0200 X:FF01 Y:00E0 P:envmxdizC
$00/F5DB 1E EB A9    ASL $A9EB,x[$00:A8EC]   A:0200 X:FF01 Y:00E0 P:envmxdizc
$00/F5DE 80 85       BRA $85    [$F565]      A:0200 X:FF01 Y:00E0 P:eNvmxdizC
$00/F565 DE C0 DE    DEC $DEC0,x[$00:DDC1]   A:0200 X:FF01 Y:00E0 P:eNvmxdizC
$00/F568 C1 DE       CMP ($DE,x)[$00:FFD3]   A:0200 X:FF01 Y:00E0 P:eNvmxdizC
$00/F56A C2 DE       REP #$DE                A:0200 X:FF01 Y:00E0 P:eNvmxdizc
$00/F56C C3 DE       CMP $DE,s  [$00:20CE]   A:0200 X:FF01 Y:00E0 P:envmxdizc
$00/F56E C4 DE       CPY $DE    [$00:00DE]   A:0200 X:FF01 Y:00E0 P:envmxdizc
$00/F570 B3 DE       LDA ($DE,s),y[$00:5635] A:0200 X:FF01 Y:00E0 P:eNvmxdizc
$00/F572 CA          DEX                     A:8408 X:FF01 Y:00E0 P:eNvmxdizc
$00/F573 DE CB DE    DEC $DECB,x[$00:DDCB]   A:8408 X:FF00 Y:00E0 P:eNvmxdizc
$00/F576 CC DE CD    CPY $CDDE  [$00:CDDE]   A:8408 X:FF00 Y:00E0 P:envmxdizc
$00/F579 DE CE DE    DEC $DECE,x[$00:DDCE]   A:8408 X:FF00 Y:00E0 P:eNvmxdizc
$00/F57C CA          DEX                     A:8408 X:FF00 Y:00E0 P:eNvmxdizc
$00/F57D DF CB DF CC CMP $CCDFCB,x[$CC:DECA] A:8408 X:FEFF Y:00E0 P:eNvmxdizc
$00/F581 DF CD DF CE CMP $CEDFCD,x[$CE:DECC] A:8408 X:FEFF Y:00E0 P:envmxdizC
$00/F585 DF 86 02 A5 CMP $A50286,x[$A5:0185] A:8408 X:FEFF Y:00E0 P:envmxdizC
$00/F589 49 85 04    EOR #$0485              A:8408 X:FEFF Y:00E0 P:envmxdizC
$00/F58C A0 00 00    LDY #$0000              A:808D X:FEFF Y:00E0 P:eNvmxdizC
$00/F58F 64 05       STZ $05    [$00:0005]   A:808D X:FEFF Y:0000 P:envmxdiZC
$00/F591 7B          TDC                     A:808D X:FEFF Y:0000 P:envmxdiZC
$00/F592 B7 02       LDA [$02],y[$08:6E00]   A:0000 X:FEFF Y:0000 P:envmxdiZC
$00/F594 C9 20 B0    CMP #$B020              A:0808 X:FEFF Y:0000 P:envmxdizC
$00/F597 12 AA       ORA ($AA)  [$00:5500]   A:0808 X:FEFF Y:0000 P:envmxdizc
$00/F599 BD B2 F5    LDA $F5B2,x[$00:F4B1]   A:5D5D X:FEFF Y:0000 P:envmxdizc
$00/F59C F0 11       BEQ $11    [$F5AF]      A:5722 X:FEFF Y:0000 P:envmxdizc


Looks like it was supposed to enter that subroutine with an 8-bit accumulator. Following seems to have fixed it.
Code: [Select]
$00/D867 E2 20       SEP #$20   
$00/D869 A9 60       LDA #$60   
$00/D86B 85 0A       STA $0A   
$00/D86D 20 D2 F5    JSR $F5D2 
« Last Edit: March 02, 2014, 11:56:28 am by FinS »

Scio

  • Full Member
  • ***
  • Posts: 155
    • View Profile
Re: bad coding in roms
« Reply #90 on: March 03, 2014, 10:55:12 am »
There was this one Master System game that used a routine to read 3 bytes from the beginning of a text block (like 0A CA 80), and then placed a portrait of the character who was talking on the dialogue box. The thing is, these bytes only set the position onscreen (it's the next byte that changes the portrait)... but the portrait never moves from that position at all. Wouldn't it be easier to assume the portrait was always going to be in that position, instead of wasting 3 bytes in every line and a few processor cycles?

There was also a PSX game that read a 7-byte value to place a portrait (I think it was Rhapsody), where the first 4 bytes were entirely useless. Probably something left from the debug phase?
« Last Edit: March 03, 2014, 12:35:23 pm by Scio »

cret

  • Jr. Member
  • **
  • Posts: 75
    • View Profile
Re: bad coding in roms
« Reply #91 on: March 03, 2014, 04:36:44 pm »
Code: [Select]
╒ (fcn) sym.Interrupt_LCDC_Status 6
│                                 0x00000048   4        af           xor a
│                                 ;  Ramswitch
│                                 0x00000049  16        ea0040       ld [0x4000], a
│                                 0x0000004c   4        fb           ei
╘                                 0x0000004d  16        c9           ret

pokemon green, why are they doing ei. it doesn't do anything because ret from an interrupt disables it
go r2, use debug. .... White hand was fainted

Drenn

  • Jr. Member
  • **
  • Posts: 94
    • View Profile
Re: bad coding in roms
« Reply #92 on: March 03, 2014, 09:52:30 pm »
ret doesn't re-enable interrupts, reti does. Instead of "ei, ret" it could be just "reti". But of course, one opcode will hardly make a difference.
Zeldahacking.net: The hub for Zelda: Oracle of Ages and Seasons hacking. We have a discord!

KingMike

  • Forum Moderator
  • Hero Member
  • *****
  • Posts: 6480
  • *sigh* A changed avatar. Big deal.
    • View Profile
Re: bad coding in roms
« Reply #93 on: March 03, 2014, 09:55:36 pm »
Isn't Pokemon Red/Green pretty broken anyways?
SELECT Pokemon corruption! :P
Quote
Sir Howard Stringer, chief executive of Sony, on Christmas sales of the PS3:
"It's a little fortuitous that the Wii is running out of hardware."

OneCrudeDude

  • Full Member
  • ***
  • Posts: 110
    • View Profile
Re: bad coding in roms
« Reply #94 on: March 04, 2014, 02:47:52 pm »
I wonder, has anyone been able to pinpoint the reason why Contra Force suffers from so much slowdown?  There has to be something that's not coded right, aside from the entire game.

And another, more well known example (not sure if it's been mentioned) is Ghostbusters for the NES.  The Select button acts as the pause button, but here's the thing.  You can actually "pause" the title screen, and it will just keep flashing the press start text until it is unpaused.  Same as before, if you pause the "copyright info" screen that shows up after the title, you can pause that to indefinitely stay on that screen.  Finally, when the busters cross the streams, they turn into a pile of weird shapes.  That's because the game erroneously calls the beam graphics, which are located one 'line' above the actual "falling down" sprite that's in the game.  Finally, the in-game music likes to spit and sputter, which some people have said is a result due to PCM artifacting.

I have no code sources or the like, I found out most of them by pure luck.

KingMike

  • Forum Moderator
  • Hero Member
  • *****
  • Posts: 6480
  • *sigh* A changed avatar. Big deal.
    • View Profile
Re: bad coding in roms
« Reply #95 on: March 04, 2014, 10:23:16 pm »
Maybe Contra Force wasn't meant to be a Contra game? The canceled Japanese version was called Arc Hound.

Ghostbusters was probably just broken. If you went through all the trouble of beating the Japanese version,
your ending is a black screen with (eventually) two characters of glitch text.
Quote
Sir Howard Stringer, chief executive of Sony, on Christmas sales of the PS3:
"It's a little fortuitous that the Wii is running out of hardware."

Gideon Zhi

  • IRC Staff
  • Hero Member
  • *****
  • Posts: 3437
    • View Profile
    • Aeon Genesis
Re: bad coding in roms
« Reply #96 on: March 04, 2014, 11:05:42 pm »
Maybe Contra Force wasn't meant to be a Contra game? The canceled Japanese version was called Arc Hound.

This still doesn't explain how Contra 3 is Contra 3 when there are three NES Contra games (Contra, Contra Force, and Super C). It's not even numbered as such in Japan! *brain hurts*

Scio

  • Full Member
  • ***
  • Posts: 155
    • View Profile
Re: bad coding in roms
« Reply #97 on: March 04, 2014, 11:21:34 pm »
From what I gather, it's because they tried to do a lot of complicated things, and didn't finish them properly.

- The game has 4 selectable characters, all with different stats. You can change them during the stage, whenever a player loses a continue.
- The game has side-view and top-view stages.
- It has an AI system, if you don't have someone else to play as Player 2.

Are there any other NES games that use an AI system for player 2? I mean, something more code-intensive, like shooting in all directions and jumping, not just moving around. My best guess is that this part is the bottleneck, they probably didn't clean the code, and ended up wasting a ton of cycles for AI.

OneCrudeDude

  • Full Member
  • ***
  • Posts: 110
    • View Profile
Re: bad coding in roms
« Reply #98 on: March 05, 2014, 12:10:11 am »
@KingMike:  Supposedly the Japanese version has the same ending as the American version, but, unbelievably, it had one more typo; "great" was written as "grate".  I wouldn't be surprised if the people who programmed NES GhostBusters eventually went on to develop the Pokemon games.  The sheer magnitude of game breaking bugs present in GB and Pokemon Green is too much to be a mere coincidence.  Amazingly, Bits Laboratory co-developed Brawl for the Wii, and is probably their last game.

I was hoping that someone would've been able to unearth some of the code, and see why it's tied up.  Considering what Scio said about it being "very technical" and how the game was cancelled in Japan, it wouldn't be surprising if the game was just finalized so that they could get it out there.  Wasn't there a bootleg version of the game that supposedly fixes some of the slowdown?

KingMike

  • Forum Moderator
  • Hero Member
  • *****
  • Posts: 6480
  • *sigh* A changed avatar. Big deal.
    • View Profile
Re: bad coding in roms
« Reply #99 on: March 05, 2014, 01:42:05 am »
This still doesn't explain how Contra 3 is Contra 3 when there are three NES Contra games (Contra, Contra Force, and Super C). It's not even numbered as such in Japan! *brain hurts*
Operation C was released before Contra 3 (and considering the recently released "Contra IV" proto, maybe Konami did consider the GB game officially third at one point), Contra Force was released after.
It would've been great to consider OC the third game, giving the C a double-meaning. :D
Quote
Sir Howard Stringer, chief executive of Sony, on Christmas sales of the PS3:
"It's a little fortuitous that the Wii is running out of hardware."