Friday, 18 July 2025

Pretty fly for a transcode

Still plugging away at Frogger as time allows.

I've been working through the high-level foreground/background (depending on your nomenclature preference) and NMI code, ensuring I've transcoded everything that is not in a subroutine. Along the way I've managed to name a few more variables, mostly simple flags, but also decided others have multiple purposes (the classic 'temp' variable). Ugh. Work that had to be done, but resulted in no tangible difference on the screen.

My next thought was to implement the code that handles when your frog gets 'home' - that's quite brain-dead and clearly identified in my RE. Alas, it's not actually possible to get home without scrolling logs to position you in the center of each home. So back to the drawing board.

Next idea was to handle the (seemingly) random appearance of the fly in the frog's homes. There wasn't a great deal of code, and the timers involved were all ticking over already, so it didn't take a great deal of effort to see it working.

A fly appears briefly!

Now it's crunch time; no choice but to tackle the scrolling cars and logs, turtles, alligators etc. This involves diving into code that I haven't fully RE'd. Some of it I have a high level understanding of what it is doing, but don't understand any of the detail. For example there are tables of bytes that are copied into RAM that comprise logic & data for the scrolling entities, and calculations that are done on some of that data which escape my understanding atm.

But at the same time, there are aspects of the code that do offer good hints, like it seems there's a routine to construct/update each of the scrolling rows explicitly. So for example, I believe that I can transcode the routines to update, say, just the bottom row of vehicles on the road.

For now though, I'm in the middle of wrapping my head around a routine that I guess calculates where to start drawing the log on one of the rows. It works backwards from the VRAM address and a few bytes that would indicate some sort of scroll position maybe? Not the sort of routine that translates well from Z80 to 68K either, so understanding what it's doing is definitely going to be more beneficial than a brute-force transcode.

By my crude calculation, the transcode is now 39% done.

Tuesday, 8 July 2025

Transcode now one-third done!

Turns out the 'freezing' of the game after GAME OVER was due to a simple bug in the transcode. It was trashing a whole bunch of variables from which it never recovered.

Now it runs back through the attract mode screens as it should.

I also transcoded the routine that updates the high score table after a game. It hasn't been tested yet as I am unable to score more than 300 pts, but at least it no longer highlights any of the scores after the game (it highlights the scores on the high score list - if any - from the last game).

I have the estimated transcode at 34% done, so now "officially" one-third done!

No eye candy today.

Scoring!

Not much time to work on Frogger now that it's school holidays AND Tour de France time... but I did get the score updated whenever the frog hops forward.

Getting a frog to the top of the screen
will earn you 100 pts.

Not that I went looking to do this, but a side-effect of trying to stop the game freezing after GAME OVER rather than cycle through the attract mode screens again.

Friday, 4 July 2025

GAME OVER

I've now got it displaying "GAME OVER" when the last frog dies...

It animates the frogs dying
before showing the GAME OVER screen

However after subsequently clearing the screen, it hangs the Neo Geo.

I have done a little more RE and identified some more of the code, specifically the code that animates the dying frog. Not a huge leap forward, and the number of unlabeled flags, counters & timers just keeps growing, but I am trying to transcode the main NMI and background execution flows even if these variables remain 'unknown' in order to get the game cycling through attract mode and gameplay.

The transcode is nearing the one-third mark!

Thursday, 3 July 2025

Why did the frog cross the road?

Managed to fix the never-ending frogs left display; from memory (I've forgotten already) it was a flag/timer that was never updated in what I had transcoded, so it was forever decrementing a frog.

I also managed to get the player inputs working, after implementing another cascading execution flow of arbitrary flags and counters. Ironed out a few bugs in the input routines in the process and can now hop around the screen within the confines of the coded limits.

Hopping across the road in game mode

On that note, I had never realised you could jump down below the starting row, and over the timer bar. But I did subsequently confirm this on the emulated Frogger in MAME. You also can't jump left/right from the uppermost ('home') row, but that's a moot point because hitting that row you're either home or dead.

So with nothing to kill the frog, the time runs down until "TIME OVER" is displayed and then it just sits there. I'll now look at finishing off the logic that will properly end the game and re-enter attract mode. Besides a few bits that I've purposefully skipped - like high score table update - that'll be everything outside the gameplay mechanics of moving the objects and killing the frog.

I figure (roughly) that the transcode is now 30% done.

Wednesday, 2 July 2025

My frog still won't budge

I've been working towards getting the gameplay to a point where I can control the frog. Given that it hops around in attract mode, I figured the mechanics at least were there. But it has been a bit of a slog to get to the point where it will actually move, and I'm still not there yet.

The transcode is approximately 30% complete now, and during that time I've made very little progress on the RE side of things. I've named a few timers here and there but that's about it.

[rant]

I can't hold back any longer; this really is crappy code. For the amount of time I've spent on RE and transcode with this project, I can't believe I still don't have a clear picture in my head about the overall program structure. It's a tangled mess of spaghetti code with execution paths that just meander through the memory space, duplicated functionality in the code, functions that call seemingly unrelated subroutines, duplicated variables (as far as I can tell) and a plethora of flags and timers that defy a precise description of function. I can't even partition the code in my head between NMI (which is triggered by VBLANK and must run FAR longer) and main execution, they both seem to be doing a little bit of everything. This had to be written by an intern at Konami.

[/rant]

Anyway, the lack of structure makes it very difficult to work out which parts of the code I need to implement to get the player controlling the frog. You just need one timer to not be ticking, or one flag to not be set, and the whole execution flow breaks down. In my handful of transcodes thus far, I've never had this problem. It's going to be painful.

So the plan forward is to continue on with the transcode, and do what little RE I can in the process. I'm aiming to get the frog moving without any of the traffic or logs, turtles etc. in the picture but, given what I've seen so far, I wouldn't be surprised if the timer used (and updated in) the diving turtles routine also handles player inputs! OK, maybe not that bad, but it's a challenge.

I'll leave you with a screenshot of what I see after coining up and starting a game. Currently the code is continually incrementing and printing the number of frogs, and I'm not sure why yet. Maybe I need to look at the bonus frog logic...


It keeps incrementing the number of frogs...

UPDATE: It's actually calling decrement frogs continually...

Friday, 27 June 2025

Frogger

It's been a long time since I posted anything on this blog, and that's because I haven't done anything retro-porting related in all that time. I had started on a now-stalled project creating a new core for the MiSTer hardware, but even that was probably a year ago now.

In recent weeks I decided it was time to work on another port. To be honest, I struggled to find a candidate that I was both interested in personally, and could run on the Neo Geo - my favourite retro platform for porting. I was really looking for a horizontal title, but finally settled on Frogger thinking it would be relatively simple. After all, I had done Galaxian and it is essentially the same hardware.

I'm now a few weeks into the RE - I'd estimate about 65% done - and have actually started on the 68K implementation before finishing the RE. Initially the decision to start on the implementation was more due to impatience than anything else, but I've actually found it helps with the RE.

Not surprisingly, I was able to create the Neo Geo assets for Frogger using the same tools I built for Galaxian, almost without any changes. Ditto for the Neo Geo code itself. I'll have to keep this in mind for any future projects on the same hardware, and there were quite a lot of games on Galaxian hardware, even if some were bootlegs.

So, right now the attract screens - title, points table, high score, insert coin - have all been implemented. The static elements of the gameplay screen are drawn in attract mode, and the frog happily leaps across an otherwise empty screen as the time bar counts down. You can also coin up and start a game, though visually it appears to just hang on the start screen. A crude comparison of the Z80 and 68K assembler listings would suggest the transcode is about 21% done.

A few screenshots of  Neo Geo Frogger in action.

The frog hops around in the attract mode gameplay

The next step is adding gameplay elements. This will be a process of RE and transcoding in parallel.