Quantcast

Results 1 to 8 of 8

Thread: Mega Bomberman: Fixing a bug in a 20-year-old game

  1. #1
    Road Rasher Oerg866's Avatar
    Join Date
    Dec 2009
    Location
    Frankfurt am Main (Germany)
    Age
    27
    Posts
    265
    Rep Power
    22

    Default Mega Bomberman: Fixing a bug in a 20-year-old game

    Hi,

    as some of you might know by now, a friend and I are fanatic Mega Bomberman players. Getting really good at this game had its drawbacks, as some infidelities in the game had surfaced...

    You may ask, why would you fix a bug in a game this old? Let alone one that has a thousand ports to modern consoles and computers? Aside from blazingly simple and lag-free netplayability using Kega Fusion... well, most Bomberman inevitably take the skill out of the equasion as they plaster the map with game-breaking gimmicks. The Mega Drive rendition lacks most of that, but that makes it all the more tactically brilliant. The set of items you are able to collect in a match is limited, simple and precise. The game allows you to tightly control kicked bombs. The controls are perfect and responsive, something that most, if not all, other bombermen lack.

    Stage 7 with the warpdoors is special. These introduce tons of new strategy. You can go for a rush, you can play it safe, lure the other player into doing things, precisely send bombs to other parts of the map. It's simply brilliant. However, at the higher skill levels during play, a massive oversight on Westone's part becomes obvious.

    If you don't know, the skull item is an item that selects randomly between 10 different "punishments" when collected. Either you get one of the nine preset "downgrades" (walking speed, explosion timer, cant stop laying bombs, etc.) or, and this is the fun bit, you swap positions and louies with another player.

    If you happen to be inside a warp door when someone triggers this swap, you will be invincible until either the game ends or you go in a warpdoor again. (another annoying glitch is that the other player will be stuck for a few seconds and then reappear on top of the first warpdoor instead of the real destination warpdoor).

    Here's a video I made of the bug as we first discovered it.



    So, as this started happening quite often, we decided to playing this game because it is factually broken now... Unelss I could fix the bug, we would never play Bomberman again!

    So, armed with Exodus and IDA, I got to work. I isolated the routines responsible for the skull (and subsequently the swap). The routine copies bytes (one by one!! *sigh*) between the players (position and louie attributes, etc.)

    Based on my earlier reverse-engineering of the game's memory contents (http://pastebin.com/YFqqUaf2), I found out that two values in a player's memory area corresponds to the state regarding the warpdoors (specifically the identifier for the warpdoor you're currently in and the amount of frames left in this state). I also found out that these bytes are NOT copied, neither are the original values deleted from the original player. As a consequence, the game thinks the player is still in the warpdoor, and thus he is internally marked invincible (as you cannot get killed while you're in a warpdoor, obviously) -- see the "invinc" bit on the player attribute byte...

    Code:
    ROM:00006BB2                 move.l  2(a4),-(sp)
    ROM:00006BB6                 move.l  2(a5),2(a4)
    ROM:00006BBC                 move.l  (sp)+,2(a5)
    ROM:00006BC0                 move.l  6(a4),-(sp)
    ROM:00006BC4                 move.l  6(a5),6(a4)
    ROM:00006BCA                 move.l  (sp)+,6(a5)
    ROM:00006BCE                 move.b  $26(a4),-(sp)
    ROM:00006BD2                 move.b  $26(a5),$26(a4)
    ROM:00006BD8                 move.b  (sp)+,$26(a5)
    ROM:00006BDC                 move.b  $27(a4),-(sp)
    ROM:00006BE0                 move.b  $27(a5),$27(a4)
    ROM:00006BE6                 move.b  (sp)+,$27(a5)
    ROM:00006BEA                 move.b  $28(a4),-(sp)
    ROM:00006BEE                 move.b  $28(a5),$28(a4)
    ROM:00006BF4                 move.b  (sp)+,$28(a5)
    ROM:00006BF8                 move.b  $29(a4),-(sp)
    ROM:00006BFC                 move.b  $29(a5),$29(a4)
    ROM:00006C02                 move.b  (sp)+,$29(a5)
    ROM:00006C06                 move.b  $2A(a4),-(sp)
    ROM:00006C0A                 move.b  $2A(a5),$2A(a4)
    ROM:00006C10                 move.b  (sp)+,$2A(a5)
    ROM:00006C14                 move.b  $2B(a4),-(sp)
    ROM:00006C18                 move.b  $2B(a5),$2B(a4)
    ROM:00006C1E                 move.b  (sp)+,$2B(a5)
    ROM:00006C22                 move.b  $15(a4),-(sp)
    ROM:00006C26                 move.b  $15(a5),$15(a4)
    ROM:00006C2C                 move.b  (sp)+,$15(a5)
    ROM:00006C30                 move.b  $14(a4),d0
    ROM:00006C34                 andi.b  #$7F,d0 ; ''
    ROM:00006C38                 ori.b   #$40,d0 ; '@'
    ROM:00006C3C                 move.b  $14(a5),d1
    ROM:00006C40                 move.b  d0,$14(a5)
    ROM:00006C44                 andi.b  #$7F,d1 ; ''
    ROM:00006C48                 ori.b   #$40,d1 ; '@'
    ROM:00006C4C                 move.b  d1,$14(a4)
    ROM:00006C50                 clr.b   $24(a4)
    ROM:00006C54                 clr.b   $24(a5)
    ROM:00006C58                 clr.b   $25(a4)
    ROM:00006C5C                 clr.b   $25(a5)
    This is the routine that copies the values. The values for the warpdoors would be $12(a*) and $3A(a*), they're missing.

    My bugfixed code looks like this:

    Code:
    		move.l	2(a4),-(sp)		; Copy information between the players...
    		move.l	2(a5),2(a4)		
    		move.l	(sp)+,2(a5)
    		move.l	6(a4),-(sp)		
    		move.l	6(a5),6(a4)
    		move.l	(sp)+,6(a5)
    		
    		move.l	$26(a4),-(sp)
    		move.l	$26(a5),$26(a4)	; These	have to	do with	louies.
    								; I so want to make this use longs instead of bytes.
    								;; Post-note: I did =P
    		move.l	(sp)+,$26(a5)
    	
    		move.w	$2A(a4),-(sp)
    		move.w	$2A(a5),$2A(a4)
    		move.w	(sp)+,$2A(a5)
    		
    		;;; The bugfix starts here
    		
    		; Copy Warping Doors Timer
    		
    		move.b $12(a4),-(sp)
    		move.b $12(a5),$12(a4)
    		move.b (sp)+,$12(a5)
    		
    		; Copy Current Warping Door ID
    		
    		move.b $3A(a4),-(sp)
    		move.b $3A(a5),$3A(a4)
    		move.b (sp)+,$3A(a5)
    		
    		;;;;; END BUGFIX!!!
    		
    		
    		move.b	$15(a4),-(sp)
    		move.b	$15(a5),$15(a4)	
    		move.b	(sp)+,$15(a5)
    		move.b	$14(a4),d0
    		andi.b	#$7F,d0	
    		ori.b	#$40,d0	
    		move.b	$14(a5),d1		; This byte stores the direction and walking
    								; properties of	the player.
    		move.b	d0,$14(a5)
    		andi.b	#$7F,d1	
    		ori.b	#$40,d1	
    		move.b	d1,$14(a4)
    		clr.b	$24(a4)
    		clr.b	$24(a5)
    		clr.b	$25(a4)
    		clr.b	$25(a5)
    		
    		rts


    The costs of jumping there and copying the additional values are mitigated by optimizing the code to use longwords instead of copying each byte separately :P

    The code is attached to the end of the ROM ($100000) and the original code is replaced with this:

    Code:
     4E B9 00 10 00 00 4E F9 00 00 6C 60
    This is a jsr to $100000 and a jmp to the end of the code (the lazy approach).

    The ROM I use actually has another perk which I call "tournament edition", it actually makes the game boot into battle-mode, thus saving time spent skipping the intro and going there manually :P It's done using - sort of - a savestate. I paused Exodus right before the menu appeared, and then exported everything important: RAM contents, register contents, VRAM contents, CRAM contents, Z80 memory contents. I modified the initial PC vector at offset 4 in the ROM to point to the new startup code I made, which restores all of this.

    Code:
    VDPControl EQU $C00004
    VDPData EQU $C00000
    SetVRAMAddr: macro addr, dest
    	move.l #$40000000|((\addr)&$3FFF)<<16|(\addr)>>14, (\dest)
    	endm
    Entry: 
    	move.w #$2700, sr
    	move.l #'SEGA', ($A14000)
    	
    	lea (VDPRegs), a0
    	move.w #24-1, d0
    @regs:
    	move.w (a0)+, (VDPControl)
    	dbf d0, @regs
    	
    	lea (Memory), a0
    	lea ($FF0000), a1
    	move.w #$10000/4-1, d0
    @memcpy:
    	move.l (a0)+, (a1)+
    	dbf d0, @memcpy
    
    	; Z80 Reset & Busreq
    
    	move.b #1, ($a11200)			; stop reset
    	move.b #1, ($a11100)			; request bus
    
    	lea (Z80Mem), a0
    	lea ($A00000), a1
    	
    	move.w #8192-1, d0
    @z80cpy:
    	move.b (a0)+, (a1)+
    	dbf d0, @z80cpy
    	
    	SetVRAMAddr 0, VDPControl
    	lea (VRAM), a0 
    	move.w #$10000/4-1, d0
    @vcpy:
    	move.l (a0)+, (VDPData)
    	dbf d0, @vcpy
    	
    	
    	move.b #0, ($a11200) 			; Start Z80 reset
    	move.b #0, ($a11100) 			; unrequest Z80 bus
    	move.b #1, ($a11200) 			; Stop Z80 reset
    	
    	MOVE.B #$40, ($A10009)			; Ctrl 1
    	MOVE.B #$40, ($A1000B) 			; Ctrl 2
    	
    	lea (regs), a0
    	movem.l (a0)+, d0-d7/a1-a7
    	move.l #$1A712, a0
    ;	bra.s *
    	jmp $00007C5A
    	
    	
    Memory: 
    	incbin ./mem.bin
    Z80Mem:
    	incbin ./z80.bin	
    VRAM:
    	incbin ./vram.bin
    VDPRegs:
    	dc.w $8004, $8124, $8238, $8338, $8407, $857F, $8600, $8700, $8800, $8900, $8A00, $8B00
    	dc.w $8C00, $8D3F, $8E00, $8F02, $9011, $9100, $9200, $9300, $9400, $9500, $96C0, $977F
    Regs:
    	dc.l $440, 5, 2, $808000, $6a6, $FF, 3, $128
    	dc.l $EFA92, $FFFFAD12, $DB7CC, $10564, $E2004EB8, $FF72B2, $FFFE9E
    So, I present to you Mega Bomberman: The bugfixed tournament edition :P


    http://oerg866.mdscene.net/f/mbtournament.bin

    PS: Unfortunately this ROM does not work in Regen, use Fusion or Exodus instead. Real Hardware support not tested.

    PPS: Due to replacing the init code with my own, Multitap/4-Way-Play devices are not initialized, so only two players can play (if someone supplies me with support code for it, i'll happily fix that)

    Cheers.
    Last edited by Oerg866; 05-16-2014 at 03:41 PM.

  2. #2
    Hero of Algol Kamahl's Avatar
    Join Date
    Jan 2011
    Location
    Belgium
    Age
    31
    Posts
    8,637
    Rep Power
    143

    Default

    This is pretty cool! Do note that posting such an edited rom is kinda sorta illegal, consider creating an ips patch just because .

  3. #3
    Road Rasher Oerg866's Avatar
    Join Date
    Dec 2009
    Location
    Frankfurt am Main (Germany)
    Age
    27
    Posts
    265
    Rep Power
    22

    Default

    I have acquired multitap code, courtesy of Sik, so the lack of 3/4-player support will be fixed very soon :P

    EDIT: Here: http://oerg866.titandemo.de/f/mbtournament_v1.1.bin

    EA 4-Way-Play only so far, because SEGA's multitap is shit and hard to initialize (and doesn't seem to work properly in netplay anyway :P)
    Last edited by Oerg866; 06-18-2014 at 08:02 AM.

  4. #4
    Master of Shinobi midnightrider's Avatar
    Join Date
    Nov 2013
    Posts
    2,270
    Rep Power
    47

    Default

    OK, but try using one of these to make a patch, and upload that, instead of a full rom:
    http://www.romhacking.net/utilities/893/
    http://www.romhacking.net/utilities/329/
    http://www.romhacking.net/utilities/677/

    http://www.romhacking.net/utilities/928/
    http://www.romhacking.net/utilities/598/ (frontend for the program in the previous link)

    All of those can create, as well as patch the files they create(except in the case of Ninja, which comes with a separate program to create patches).

    Also, when you talk about control precision, does that also mean this version has it over the TurboGrafx-16 original as well?

  5. #5
    Death Bringer ESWAT Veteran Black_Tiger's Avatar
    Join Date
    Oct 2006
    Location
    Vancouver
    Age
    44
    Posts
    5,043
    Rep Power
    119

    Default

    If you could fix the slowdown "bug" next that would be super cool.
    Quote Originally Posted by year2kill06
    everyone knows nintendo is far way cooler than sega just face it nintendo has more better games and originals

  6. #6
    Road Rasher Oerg866's Avatar
    Join Date
    Dec 2009
    Location
    Frankfurt am Main (Germany)
    Age
    27
    Posts
    265
    Rep Power
    22

    Default

    Quote Originally Posted by midnightrider View Post
    OK, but try using one of these to make a patch, and upload that, instead of a full rom:
    http://www.romhacking.net/utilities/893/
    http://www.romhacking.net/utilities/329/
    http://www.romhacking.net/utilities/677/

    http://www.romhacking.net/utilities/928/
    http://www.romhacking.net/utilities/598/ (frontend for the program in the previous link)

    All of those can create, as well as patch the files they create(except in the case of Ninja, which comes with a separate program to create patches).

    Also, when you talk about control precision, does that also mean this version has it over the TurboGrafx-16 original as well?
    Didn't really see anyone care about legalities in the sonic hacking threads, so I won't bother with that for now ...

    I haven't been able to play the TG16 game in a long time, so I can't judge that, but game-logic wise this should be a direct port, so it should be the same.

  7. #7
    Death Adder's minion
    Join Date
    Oct 2012
    Posts
    15
    Rep Power
    0

    Default

    Quote Originally Posted by Oerg866 View Post
    EA 4-Way-Play only so far, because SEGA's multitap is shit and hard to initialize (and doesn't seem to work properly in netplay anyway :P)
    Gens doesn't work with 2 multitaps. But Kega does. (netplay games works ok)
    Roms that use it:
    Mega Bomberman - 8 Player Demo (Unl)
    RRR - Tournament Edition v06b (Rock n' Roll Racing Hack)

  8. #8
    Death Bringer ESWAT Veteran Black_Tiger's Avatar
    Join Date
    Oct 2006
    Location
    Vancouver
    Age
    44
    Posts
    5,043
    Rep Power
    119

    Default

    Quote Originally Posted by Oerg866 View Post
    Didn't really see anyone care about legalities in the sonic hacking threads, so I won't bother with that for now ...

    I haven't been able to play the TG16 game in a long time, so I can't judge that, but game-logic wise this should be a direct port, so it should be the same.
    The game-logic seems the same for player interaction under optimal circumstances, but the occasional slowdown becomes worse than a 1st gen SNES game in the final area.
    Quote Originally Posted by year2kill06
    everyone knows nintendo is far way cooler than sega just face it nintendo has more better games and originals

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •