Register - Login
Views: 99793807
Main - Memberlist - Active users - Calendar - Wiki - IRC Chat - Online users
Ranks - Rules/FAQ - Stats - Latest Posts - Color Chart - Smilies
05-03-22 05:06:18 AM
Jul - General Game/ROM Hacking - some random tools I wrote in PHP New poll - New thread - New reply
Next newer thread | Next older thread
Techokami
Member
Developed for use only with NTSC Genesis systems.
Level: 24


Posts: 20/95
EXP: 68015
For next: 10110

Since: 07-25-07

From: LINUX

Since last post: 65 days
Last activity: 49 days

Posted on 04-24-09 02:11:52 AM (last edited by Techokami at 04-23-09 11:55 PM) Link | Quote
Yeah I've been needing to find some easier way to rip tilesets from certain SEGA Genesis ROMs that people have largely ignored, so I started making some PHP scripts to do the job, because I just like PHP. Is that a problem?

So, decoding Genesis graphics is actually much, much easier than decoding SNES graphics. This is due to interleaved bitplanes. For example, here is an example of an NES graphic, split into two bitplanes, then merged into a 3 color + transparency graphic:

The pallete isn't too pleasing because I'm showing how the two bitplanes are ADDed together (red [#FF0000] + green [#0000FF] = yellow [#FF00FF])

Graphics on the Genesis are already interleaved, so each nybble refers to a single pixel of a specified color value. So drawing Genesis graphics are simply a matter of
A) Building a pallete from the 0BGR format into the #RRBBGG format
B) Reading in each byte, splitting the byte in half and drawing both pixels it represents

I was able to achieve this using the graphic libraries in PHP, booyah

So the first game I tried to work with was Desert Demolition, an obscure licensed platformer based on Warner Bros' Road Runner cartoons. Click here to view the source code to this tool! Granted it's an absolute mess, and it's not very well-tested. I only wanted a rip of the Road Runner's first level's tileset, and given a savestate of said level, it should work and give you the Map32 data.
Here's the output you get if given the right savestate:


After learning from Desert Demolition I decided to tackle something a bit more easier: High Seas Havoc (or Cap'n Havoc if you're British), another obscure platformer that is best known for being brutally hard. Click here to view the source code to this tool! As you can see this is a bit easier to read - better organization of code, lots more functions, and it even pre-splits the Map256 data for you into individual PNGs! I played through the game to get savestates of every level, and I think the trauma was worth it to say that yes, this will work on any savestate of a regular stage you throw at it.
When you run it, you'll see something like this in your browser:

But the directory of the script (or a folder you specify with a GET argument) will have a bunch of images like this:


Now, High Seas Havoc was somewhat similar to a more famous game, so I decided to just go all the way and make a tool that did the same thing to Sonic the Hedgehog 2. But no, that wasn't enough! I wanted it to also render level layouts! And I wanted multiple game support! Well, I'm most of the way there on that last point! Click here to view the source code to this tool! This tool supports Sonic 2/3K savestates, will render Sonic 2 levels, and has some preliminary Sonic 1 support.
Click here for a very big image showing this script rendering a level map to the browser!
Levels are creatively rendered in HTML with alphatransparent PNGs using a table. First the background color is obtained and set as the table's background color. Then, each cell is loaded with the BG layer Map256 entry as the table cell background, and the FG layer is a normal image inside the cell. This works better with levels that don't really have slower BG scrollings, so there's an option to toggle layer visibility.

However, Sonic 1... I was flying by the seat of my pants because of all the things documented on the Retro wiki... Sonic 1's level format is not one of them. =/ I worked with Damizean on this, he was able to make a tool in C that rips the Map256 perfectly, but for some reason I can't get it to work right in my tool.

So, if someone can fix it, please do! It's been bothering me for far too long. For reference, here is what we believe to be the bitmask for Map16 tiles in the Map256 entry:
0000 VHTT TTTT TTTT
V being a vertical flip flag, H being a horizontal flip flag, and TT TTTT TTTT being the Map16 ID.

And finally, last night I discovered this bizzare little gem nobody has ever played: Socket. And it took me all of a half hour to put together a script that rips level data. DAMN I'M GOOD. Click here to view the source code to this tool! Though the one thing that really got me is the bizzaro format - rather than read left to right, it reads up to down. (Apparently XKeeper says it's not bizzaro because it's the same way SMB1 stores level data, but it's still a mild shocker to see for me)


I think the next logical progression is to turn this all into a framework of sorts! XD

EDIT: Added some more stuff. Better now, xk?

____________________
Raccoon Sam
Member
free speech disabled
Level: 32


Posts: 101/187
EXP: 187838
For next: 18604

Since: 07-25-07

From: Somewhat

Since last post: 4.5 years
Last activity: 1.1 years

Posted on 04-24-09 09:42:24 AM Link | Quote
Who-ho-hoa, I had no idea you did this kind of stuff..!
That's absolutely amazing. Great job, man.
Techokami
Member
Developed for use only with NTSC Genesis systems.
Level: 24


Posts: 22/95
EXP: 68015
For next: 10110

Since: 07-25-07

From: LINUX

Since last post: 65 days
Last activity: 49 days

Posted on 04-24-09 05:28:26 PM Link | Quote
Originally posted by Raccoon Sam
Who-ho-hoa, I had no idea you did this kind of stuff..!
That's absolutely amazing. Great job, man.

Thanks Sam

____________________
Click here to enter the SigChat
Next newer thread | Next older thread
Jul - General Game/ROM Hacking - some random tools I wrote in PHP New poll - New thread - New reply


Rusted Logic

Acmlmboard - commit 47be4dc [2021-08-23]
©2000-2022 Acmlm, Xkeeper, Kaito Sinclaire, et al.

29 database queries, 1 query cache hits.
Query execution time: 0.112292 seconds
Script execution time: 0.011154 seconds
Total render time: 0.123446 seconds