What's new

DragonMinded

Professional
Joined
Jun 2, 2019
Messages
152
Reaction score
598
Location
Chelsea, VT, USA
In my opinion the biggest issue with netbooting is that every time you load a new game, you have to change all of your settings. If your net-dimm battery is dead and you have to load a game every time you boot, you also lose your settings even if you stick with the same game. I previously tried hacking together a series of convenience patches for specific settings and you can even change defaults for some system settings in the Naomi ROM header (see https://www.arcade-projects.com/thr...free-play-and-no-attract-sound-patches.11202/ for details if you are curious). This made things better for me, but I still get annoyed at having to open my NNC control panel to calibrate analog joysticks and set up game settings.

Well, I figured out the magic init sequence for talking to the maple bus and put together a small program that can change your settings for you when you netboot a Naomi game! The way it works is that it patches the ROM to boot to a new section of code which checks to see if it needs to write your custom settings. Then after it has updated your EEPROM, it boots the regular game again. It even has smarts to figure out not to change settings again if you go into the test menu and further customize your settings. All system settings as well as all game settings are stored in the EEPROM for most games so it is possible to customize every option for almost every game! See the readme on my netboot project here: https://github.com/DragonMinded/netboot#attach_settings

What's Done?

- Main program which can attach to a Naomi ROM, executes when the game boots from netboot and can set your EEPROM settings for you.
- EEPROM layout description format so that anyone can specify how a game's EEPROM settings are laid out.
- EEPROM editor console program that can use layout descriptions and lets you edit system and game settings given a ROM file.
- Layout description for system settings: https://github.com/DragonMinded/netboot/blob/trunk/settings/definitions/system.settings
- Layout description for Marvel vs Capcom 2: https://github.com/DragonMinded/netboot/blob/trunk/settings/definitions/BBG0.settings
- EEPROM editor library that can create or parse JSON, so that web interfaces can be made to edit settings.

What's Needed?

- First, is this something anyone cares about? If no, then I will button up my web editor and use it on my own games and not make any more improvements. It sounds like people are interested in this so it is a go!
- Layout descriptions for every other Naomi 1/2 game needs to be figured out. I figured out MVC2 by saving settings one by one in demul and comparing the changes in the EEPROM. If you are interested in helping with other games, reply and I will help you get started! I am going to tackle Ikaruga and Monkey Ball next. If you want to help with definitions files, see the tutorials in this thread or post and ask for help!
- Possible integration with other web netboot programs. On my own web interface (https://github.com/DragonMinded/netboot/tree/trunk/netboot) I intend to add a settings editor for each ROM and then patch ROMs on the fly when sending them to my Naomi. That way I don't have to mess with the ROM files themselves but I can still pick game settings for each games before I boot them. The settings editor is integrated with my netboot menu as well as my netboot web interface. The libraries I wrote can be integrated into other python programs to do similar things. If you work on netbooting tools and want to integrate with this, post in the thread and ask for help!
- The settings editor is only tested on Linux with a recent version of Python. The tools should all work fine on Linux or Mac, but some work might be needed for Windows especially for the console editor program. The editor that ships with this project works fine on Linux and Windows, and probably Mac as well (I can't test Mac).

TL;DR - I wrote a Naomi program that can auto-set your game and system settings (things like free play, number of players, game difficulty, joystick calibrations, character unlocks) as well as tools to insert settings into a Naomi game so that when you netboot a game, your settings are auto-set for you. It only supports system settings as well as game options for MVC2 right now but if people help out other games will be supported!

EDIT - See below posts for how to get started trying this out as well as contributing new EEPROM definition files.
 
Last edited:
Love it. Could add some settings options before Launch Game option in the @chunksin WiPi loader?
 
Yeah! That's exactly what this can be used for. I would definitely need help with actually making settings files though, there's no way I can handle doing every game myself.
 
Okay, I've done a bit of tidying up and I also got the settings editor to work on Windows. It should already work on Mac and it is tested working on Linux. Here's how to get started playing with all of this:

Install Python 3

This should come pre-installed on Mac and Linux, but it needs to be installed on Windows. Make sure you get Python 3.6 or newer! On Windows you can download and install the latest version here: https://www.python.org/downloads/. Make sure to enable the option that says "Add Python to PATH" on the first screen, otherwise several of the commands below won't work!

On any platform (Windows, Linux, Mac) you can check that everything is set up by opening a terminal (command prompt on Windows) and typing "python3 --version". If the command works and prints out the python version and it is 3.6 or greater, you are ready to go on!

Set Up a Virtualenv

This step is optional but recommended. If you skip this, installing packages into your system python could make your system installation dirty. This is not the biggest deal so if you are super lazy or never use python for anything else on your computer you can skip this. But I recommend it!!!

In the terminal (or command prompt) that you just opened to check that python is working properly, make sure virtualenv is installed. To do that, run this command:

Code:
python3 -m pip install virtualenv

This will make sure that virtualenv is installed on your computer and available to use. Now, in a directory that you want to mess with (maybe create a new directory for this), run the following command:

Code:
python3 -m virutalenv environment

This will create a new virtual environment for the settings editor and stuff. Now, any time you want to mess with settings or do an on-the-fly netboot, you should first run this command from the same directory you ran the above command:

Code:
source environment/bin/activate

On Windows, you will run this command instead of the above command:

Code:
environment\Scripts\activate.bat

Download the Tools

Head to https://github.com/DragonMinded/netboot/ and click the green "Code" button on the top right of the page. Choose the "Download Zip" option and then unzip the downloaded zip file into the same directory you ran the virtualenv commands above. If you skipped creating a virtualenv then you can unzip it wherever you want. If you know what "git" is and you are comfortable using it, then you can download the code using that instead.

Install the Tools Dependencies

If you did everything right, you can enter the "netboot-trunk" directory that you just unzipped. Unless you skipped creating the virtualenv above, your terminal prompt should be prefixed with "(environment)" to let you know that you are active and ready to go. One last thing you'll need to do is install the tool dependencies, otherwise when you run anything you'll get crashes that complain about missing libraries and bad imports. To do this, run the following command:

Code:
python3 -m pip install -r requirements.txt

Once this finishes, you should be ready to go! Test everything out by seeing whether you can run some of the commands by running the following command:

Code:
./eeprominfo --help

On Windows you will need to prefix every command you type with "python3". So you will run the below command instead:

Code:
python3 ./eeprominfo --help

You're all Set!

At this point, everything should be working. You can read the readme file on https://github.com/DragonMinded/netboot/ to see what various tools do. For the all-in-one experience, try running "attach_settings" with a ROM file to edit the system and game settings. I recommend Marvel vs. Capcom 2 because it already has definition files. To do so, run this:

Code:
./attach_settings edit <path/to/marvelvscapcom2.bin>

If you want to make a copy of your rom and edit that instead, you can (and probably should, just in case!). An editor will pop up in your terminal that you can use to edit settings. Yes, it even supports mouse even though its in the terminal (this is tested on Windows and Linux, Mac might not work). Now, netboot the rom file you just edited settings with or load it in demul and see that your settings are auto-applied!
 
Last edited:
Oh hell yes, absolutely fantastic work!

I was actually in the middle of writing a patch generation routine which would enable my loader to patch on the fly without touching the original roms, using the old search and replace rom patching. This is much more streamlined. With your permission, May I incorporate this method into my project?

Of course, I will also contribute what I can for settings definitions.

Although, from what I can tell, this project is going to end up being what I've been trying to do, only much better executed. Constantly impressed with the effort you put into these things.
 
Last edited:
Code for patching on the fly from a hex file is here: https://github.com/DragonMinded/arcadeutils/blob/main/arcadeutils/binary.py and is the format all of these patches are in: https://github.com/DragonMinded/netboot/tree/trunk/patches

For binary patches (such as skipping coin checks or whatever) are best suited for that format. You can check applicability of a patch to a ROM using https://github.com/DragonMinded/arcadeutils/blob/main/arcadeutils/binary.py#L209 and this is how I can offer checkboxes for what patches to send on the fly when netbooting from my own server, like so:

1633310151268.png


Code for patching this on the fly is as simple as having the ROM in memory already as a bytes object and then just calling "patch" with a list of patches. See https://github.com/DragonMinded/netboot/blob/trunk/scripts/binary_patch.py#L89 for an example.

Code for patching specifically a Naomi ROM to load a 128-byte EEPROM is here: https://github.com/DragonMinded/netboot/blob/trunk/naomi/settings_patch.py and code which interfaces with the settings definition files to generate and manipulate those 128-byte EEPROMs is here: https://github.com/DragonMinded/netboot/blob/trunk/settings/settings.py

I haven't put together a web interface yet, so the curses interface in "scripts.edit_settings" will have to do as an example of what's possible. A good example of how to tie it all together is here: https://github.com/DragonMinded/netboot/blob/trunk/scripts/attach_settings.py#L257 the only thing you would need to change is what modifies the settings themselves (presumably a web interface) and the fact that your ROM will already by a bytes object in memory. Also note that settings.py above already has a "to_json" and "from_json" method that gives you a python dict or parses that python dict so you would be responsible just for the frontend manipulation logic.

I need to put together some documentation about 1) the definition format and 2) what integrations need to know about the library code above. I'll work on that soon but for now you can look at https://github.com/DragonMinded/netboot/blob/trunk/settings/editor.py for an example of how to deal with dependent settings and such.

The "arcadeutils" repo can be depended on as a pip dependency in your requirements.txt file like so: https://github.com/DragonMinded/netboot/blob/trunk/requirements.txt#L7 and then you can just use the binary patch methods, format and be compatible with all of the patches already in https://github.com/DragonMinded/netboot/tree/trunk/patches and then they're interchangeable. The arcadeutils repo is public domain and you can use it anywhere.

The "netboot" repo is a bit more of a top-level project but there's no reason why I can't create a setup.py and such for it so you can pull in the naomi directory (contains EEPROM and ROM header definitions for Naomi as well as the EEPROM patcher), settings directory (contains the code which parses out and manipulates EEPROM files by definition) and homebrew/settingstrojan/settingstrojan.bin (the payload for making EEPROM adjustments work on the actual naomi. I don't think you need the rest of the code for other projects. The "netboot" repo is also public domain and you can use it anywhere.

Attribution would be nice in both cases, but is not necessary.
 
Okay, @LazerFlux I just made some minor changes. First, the "netboot" repo now default to being installed as a package library. So if you git clone it and then "pip install ." into a virtualenv you will get just the libraries you want to implement this. This includes a new "get_default_trojan()" function that resides in the "naomi" package that you can call instead of trying to find and include the settingstrojan.bin file yourself when calling "NaomiSettingsPatcher". Second, I moved the "settings" directory to "naomi.settings" so that it is namespaced and you can use it in your code. So all the above links to files in the "settings" directory are unfortunately now dead, find them instead in https://github.com/DragonMinded/netboot/tree/trunk/naomi/settings

Both "arcadeutils" and "netboot" projects can now be depended on as libraries and used in your code. You'll still want to point to them using github, but if there's sufficient interest I can create PyPI packages for them and then you can just point to them in pip that way.

For everyone else, if you are following the above settings to play with this stuff, nothing is changed.
 
Thank you very much for the guidance and your accommodation!
Will 1000000000% credit and attribute anything I use.
 
Okay I lied. I pushed "arcadeutils" to https://pypi.org/project/arcadeutils/ since it is stable and I don't need to make modifications to it much. Feel free to depend on that in your requirements/project instead of the github repo. For "netboot" I still need to do a lot of work on it before I feel like it should or could go up on PyPI so for now continue depending on the package using the git syntax I documented above.
 
Okay, an additional update. The naomi settings libraries are now available on PyPI under the following package: https://pypi.org/project/naomiutils/ You can add "naomiutils" to your requirements.txt file and it will make "naomi" and "naomi.settings" available. As an added bonus, there's a new function in "naomi.settings" called "get_default_settings_directory" that will return the settings files that are inside the naomiutils package. That way you can just find the stuff that's already on github by asking for the directory and passing that to SettingsManager. This goes the same for the "get_default_trojan" function in "naomi". Ideally the package should be a self-contained library for anyone that wants to implement a settings editor or on-the-fly patching.

I've also documented both the arcadeutils programming interface and naomiutils programming interface. The summarized docs are available on the PyPI project pages, so that would be https://pypi.org/project/arcadeutils/ and https://pypi.org/project/naomiutils/.

That documentation is also available on github. For arcadeutils you can find it here: https://github.com/DragonMinded/arcadeutils/tree/main/arcadeutils
For naomiutils you can find it in separated to these locations: https://github.com/DragonMinded/netboot/tree/trunk/naomi for "naomi" module, https://github.com/DragonMinded/netboot/tree/trunk/naomi/settings for "naomi.settings" module and finally https://github.com/DragonMinded/netboot/tree/trunk/naomi/settings/definitions for the settings definition file format.

I'm going to work on doing a new game's settings definition. Probably Monkey Ball. I'll post a tutorial on how I do it here when I do that!
 
Excellent work! Hope this gets included down the line with one of the Netbooting solutions. Thanks for sharing.
 
Great stuff all around!

Saving settings for Monkey Ball would be great; don't you have to calibrate the joystick every time you switch [back] to that game? And would this cover the calibration settings?
 
That is exactly why I want to do Monkey Ball next. I netboot instead of using my chip/gdrom and as a result the calibration gets screwed up every single boot. The calibration is stored in the EEPROM so you would calibrate it once, get the settings off the screen and put them into a settings editor and then send it along every boot after that.
 
Excellent work! Hope this gets included down the line with one of the Netbooting solutions. Thanks for sharing.
I integrated it with my own netdimm utilities late last evening, but I have yet to put together a web interface for my own web-based netbooter. Hopefully other people working on netboot stuff will want to integrate the libraries I published. I'm not sure @chunksin has seen this but it sounds like @LazerFlux is integrating it into his setup.
 
Okay, as promised, here is a blog-style post on how I made the settings definition file for Monkey Ball (https://github.com/DragonMinded/netboot/blob/trunk/naomi/settings/definitions/BDF0.settings). Note that a prerequisite for following along on this post is that you have all of the utilities set up! See https://www.arcade-projects.com/threads/netboot-naomi-with-eeprom-presets.18977/#post-295167 if you have not set things up yet.

Okay, so lets get started figuring out the settings for Monkey Ball!

First, I make sure my BIOS and region and controls are correct in demul. I also delete the "dummy.sram" and "dummy.eeprom" files in the nvram folder just in case. This means I'll be starting off completely fresh. Now I load up the netboot ROM for Monkey Ball using the "Naomi/Naomi2 Boot" option and wait for the game to finish loading completely. Once it shows the attract screen, I completely close demul (it doesn't seem to write the eeprom files until its closed) and then I take the "dummy.eeprom" file and I run it through eeprominfo and I get this output:

Code:
$ ./eeprominfo dummy.eeprom
Serial: BDF0
Game Settings Hex: 00 03 00 00 00 00 00 00 00 00 00 00 00 ff 00 00 00 80 00 00 00 00 00 00 00 ff 00 00 00 80 00 00

Okay, so the game serial is BDF0 and the length of the game settings is 32 bytes. That's enough to start a settings file. I create a new file named "BDF0.settings" and I put the following in it:

Code:
Setting00: byte, read-only, default is 00
Setting01: byte, read-only, default is 03
Setting02: byte, read-only, default is 00
Setting03: byte, read-only, default is 00
Setting04: byte, read-only, default is 00
Setting05: byte, read-only, default is 00
Setting06: byte, read-only, default is 00
Setting07: byte, read-only, default is 00

Setting08: byte, read-only, default is 00
Setting09: byte, read-only, default is 00
Setting10: byte, read-only, default is 00
Setting11: byte, read-only, default is 00
Setting12: byte, read-only, default is 00
Setting13: byte, read-only, default is ff
Setting14: byte, read-only, default is 00
Setting15: byte, read-only, default is 00

Setting16: byte, read-only, default is 00
Setting17: byte, read-only, default is 80
Setting18: byte, read-only, default is 00
Setting19: byte, read-only, default is 00
Setting20: byte, read-only, default is 00
Setting21: byte, read-only, default is 00
Setting22: byte, read-only, default is 00
Setting23: byte, read-only, default is 00

Setting24: byte, read-only, default is 00
Setting25: byte, read-only, default is ff
Setting26: byte, read-only, default is 00
Setting27: byte, read-only, default is 00
Setting28: byte, read-only, default is 00
Setting29: byte, read-only, default is 80
Setting30: byte, read-only, default is 00
Setting31: byte, read-only, default is 00

If you compare the bytes, you can see that all I did was make a single-byte setting for each byte in the eeprom and write down the default for each. I set them all to read-only for now since I don't know what any of them do. To test that I got the defaults right, I run the following:

Code:
./edit_settings mbdefault.eeprom --serial BDF0

Its important to note that the "mbdefault.eeprom" file does not exist when I run this command, which is why I give it the "--serial BDF0" argument. I make no changes and exit, saying yes to write the EEPROM file out and then I compare the newly written "mbdefault.eeprom" against "dummy.eeprom". They're the exact same so I know I got the defaults right!

Now its time to start changing settings and seeing what happens to the file. I could try to reverse-engineer the test code for Monkey Ball, but that would take a long time and its not something that very many people can do. I boot up demul again, immediately go into the test menu right when I see the Naomi splash screen and head to game test mode. There's three sections that look like they are persistent: game assignments which is probably stored in the eeprom, joystick calibration which is also probably stored in the eeprom, and bookkeeping which might be stored in the eeprom or sram. I don't really care about how the bookkeeping is stored, so I make a note to myself to just ignore it. I head to game assignments first and look at what's available:

mb1.png


Let's start messing with one of these settings. Just looking at the eeprom data, I'm already betting that the second byte "03" is number of monkeys since it matches the number on the screen. So let's change that one. Cycling through it, I see that it can be set to 2 through 5. So lets set the number of monkeys to 5, exit back to system test, exit demul and run eeprominfo again:

Code:
$ ./eeprominfo dummy.eeprom
Serial: BDF0
Game Settings Hex: 00 05 00 00 00 00 00 00 00 00 00 00 00 ff 00 00 00 80 00 00 00 00 00 00 00 ff 00 00 00 80 00 00

Look at that, the second byte changed to 05 and the rest are the same. So that's for sure the "Number of Monkeys" setting. I'll update "Setting1" to this instead:

Code:
Number of Monkeys: byte, default is 03, values are 2 to 5

Now, I can test that it was right by doing the following:

Code:
$ ./eeprominfo dummy.eeprom --display-parsed-settings
Serial: BDF0
Game Settings Hex: 00 05 00 00 00 00 00 00 00 00 00 00 00 ff 00 00 00 80 00 00 00 00 00 00 00 ff 00 00 00 80 00 00
Parsed Game Settings:
  Number of Monkeys: 5

Cool, looks good to me! Now I'll tackle the other two settings by doing the exact same thing. I'll change one setting at a time, see how the setting hex changes and updating the settings file accordingly. Here's what I came up with:

Code:
Game Difficulty: byte, default is 00, 0 - Normal, 1 - Hard
Number of Monkeys: byte, default is 03, values are 2 to 5
Ball Velocity Boost: byte, default is 00, 0 - Off, 1 - On
Setting03: byte, read-only, default is 00
Setting04: byte, read-only, default is 00
Setting05: byte, read-only, default is 00
Setting06: byte, read-only, default is 00
Setting07: byte, read-only, default is 00

Setting08: byte, read-only, default is 00
Setting09: byte, read-only, default is 00
Setting10: byte, read-only, default is 00
Setting11: byte, read-only, default is 00
Setting12: byte, read-only, default is 00
Setting13: byte, read-only, default is ff
Setting14: byte, read-only, default is 00
Setting15: byte, read-only, default is 00

Setting16: byte, read-only, default is 00
Setting17: byte, read-only, default is 80
Setting18: byte, read-only, default is 00
Setting19: byte, read-only, default is 00
Setting20: byte, read-only, default is 00
Setting21: byte, read-only, default is 00
Setting22: byte, read-only, default is 00
Setting23: byte, read-only, default is 00

Setting24: byte, read-only, default is 00
Setting25: byte, read-only, default is ff
Setting26: byte, read-only, default is 00
Setting27: byte, read-only, default is 00
Setting28: byte, read-only, default is 00
Setting29: byte, read-only, default is 80
Setting30: byte, read-only, default is 00
Setting31: byte, read-only, default is 00

Now, its on to the calibration screen. I'll do the same thing on that screen as I did for game assignments and take a screenshot of the defaults and then save them. This is what I get when I run the eeprominfo utility:

Code:
$ ./eeprominfo dummy.eeprom
Serial: BDF0
Game Settings Hex: 01 05 01 00 00 00 00 00 00 60 00 00 00 a0 00 00 80 7f 00 00 00 60 00 00 00 a0 00 00 80 7f 00 00

And here's what the settings looked like before I saved:

mb2.png


I can see the 60 and a0 values that were displayed on the screen in a few places of the eeprom, so I'm willing to bet those are the calibration options. I'm going to try something a little bit different from the first section to see if I can't narrow it down faster. I'll add the settings to the settings definition file "BDF0.settings", set them to four different unique values using "edit_settings" and then copy "dummy.eeprom" back into the demul nvram folder. When I boot the game and go to game test mode, I'll see what the settings page says when I look.

Here's how I set the settings file to do this:

Code:
Game Difficulty: byte, default is 00, 0 - Normal, 1 - Hard
Number of Monkeys: byte, default is 03, values are 2 to 5
Ball Velocity Boost: byte, default is 00, 0 - Off, 1 - On
Setting03: byte, read-only, default is 00
Setting04: byte, read-only, default is 00
Setting05: byte, read-only, default is 00
Setting06: byte, read-only, default is 00
Setting07: byte, read-only, default is 00

Setting08: byte, read-only, default is 00
Setting09: byte, default is 60, values are 00 to ff in hex
Setting10: byte, read-only, default is 00
Setting11: byte, read-only, default is 00
Setting12: byte, read-only, default is 00
Setting13: byte, default is a0, values are 00 to ff in hex
Setting14: byte, read-only, default is 00
Setting15: byte, read-only, default is 00

Setting16: byte, read-only, default is 00
Setting17: byte, read-only, default is 80
Setting18: byte, read-only, default is 00
Setting19: byte, read-only, default is 00
Setting20: byte, read-only, default is 00
Setting21: byte, default is 60, values are 00 to ff in hex
Setting22: byte, read-only, default is 00
Setting23: byte, read-only, default is 00

Setting24: byte, read-only, default is 00
Setting25: byte, default is a0, values are 00 to ff in hex
Setting26: byte, read-only, default is 00
Setting27: byte, read-only, default is 00
Setting28: byte, read-only, default is 00
Setting29: byte, read-only, default is 80
Setting30: byte, read-only, default is 00
Setting31: byte, read-only, default is 00

Then I run:

Code:
./edit_settings dummy.eeprom

And after setting the values I copy the eeprom back to demul and re-start it. When I load game settings, nothing is changed though... Hmmmm. Maybe I'm missing something? But wait, when I went into calibration, changed nothing and chose the "exit with save" option, it didn't just change the 4 bytes that I messed with. It also messed with several other bytes as well. And when the game wrote defaults way back at the top, it didn't write 60 and a0 for the spots I think are calibration, it wrote 00 and ff. I bet you those other bytes that changed are related as well. So let's make those other settings default to their new values. I changed the definition file to this:

Code:
Game Difficulty: byte, default is 00, 0 - Normal, 1 - Hard
Number of Monkeys: byte, default is 03, values are 2 to 5
Ball Velocity Boost: byte, default is 00, 0 - Off, 1 - On
Setting03: byte, read-only, default is 00
Setting04: byte, read-only, default is 00
Setting05: byte, read-only, default is 00
Setting06: byte, read-only, default is 00
Setting07: byte, read-only, default is 00

Setting08: byte, read-only, default is 00
Setting09: byte, default is 60, values are 00 to ff in hex
Setting10: byte, read-only, default is 00
Setting11: byte, read-only, default is 00
Setting12: byte, read-only, default is 00
Setting13: byte, default is a0, values are 00 to ff in hex
Setting14: byte, read-only, default is 00
Setting15: byte, read-only, default is 00

Setting16: byte, read-only, default is 80
Setting17: byte, read-only, default is 7f
Setting18: byte, read-only, default is 00
Setting19: byte, read-only, default is 00
Setting20: byte, read-only, default is 00
Setting21: byte, default is 60, values are 00 to ff in hex
Setting22: byte, read-only, default is 00
Setting23: byte, read-only, default is 00

Setting24: byte, read-only, default is 00
Setting25: byte, default is a0, values are 00 to ff in hex
Setting26: byte, read-only, default is 00
Setting27: byte, read-only, default is 00
Setting28: byte, read-only, default is 80
Setting29: byte, read-only, default is 7f
Setting30: byte, read-only, default is 00
Setting31: byte, read-only, default is 00

Still no dice. The calibration screen only shows the defaults. That's a bummer. Okay, let's just configure some values on the configuration screen in demul and then print out what the eeprom looks like after calibrating:

Code:
$ ./eeprominfo dummy.eeprom --display
Serial: BDF0
Game Settings Hex: 00 03 00 00 00 00 00 00 39 39 00 00 ff fe 00 00 80 7f 00 00 00 60 00 00 ff fe 00 00 80 7f 00 00
Parsed Game Settings:
  Game Difficulty: Normal
  Number of Monkeys: 3
  Ball Velocity Boost: Off
  Setting09: 39
  Setting13: fe
  Setting21: 60
  Setting25: fe

Okay, so our guesses are sorta right. Let's go back in with a fresh eeprom, run the calibration one more time and see if we can't set some unique values for each setting.

mb3.png


After saving that exact calibration, let's print out the eeprom and see what values are there. It looks like we are actually right about the calibration values, but there's more going on:

Code:
$ ./eeprominfo dummy.eeprom --display
Serial: BDF0
Game Settings Hex: 00 03 00 00 00 00 00 00 26 26 00 00 e6 e5 00 00 80 7f 00 00 59 59 00 00 b9 b8 00 00 80 7f 00 00
Parsed Game Settings:
  Game Difficulty: Normal
  Number of Monkeys: 3
  Ball Velocity Boost: Off
  Setting09: 26
  Setting13: e5
  Setting21: 59
  Setting25: b8

Wait a minute, the 7f values that are defaulted are pretty suspicious. That's the Now H/Now V values. I bet those are the centering values. For some reason, the game is storing the low values twice, the center values twice (with the first value equal to the second value plus 1), and the high values twice (with the first value equal to the second value plus 1). We can work with that.

Let's start with the following settings modifications:

Code:
Game Difficulty: byte, default is 00, 0 - Normal, 1 - Hard
Number of Monkeys: byte, default is 03, values are 2 to 5
Ball Velocity Boost: byte, default is 00, 0 - Off, 1 - On
Setting03: byte, read-only, default is 00
Setting04: byte, read-only, default is 00
Setting05: byte, read-only, default is 00
Setting06: byte, read-only, default is 00
Setting07: byte, read-only, default is 00

Setting08: byte, read-only, default is 00
Left: byte, default is 60, values are 00 to ff in hex
Setting10: byte, read-only, default is 00
Setting11: byte, read-only, default is 00
Setting12: byte, read-only, default is 00
Right: byte, default is a0, values are 00 to ff in hex
Setting14: byte, read-only, default is 00
Setting15: byte, read-only, default is 00

Setting16: byte, read-only, default is 80
Horizontal Center (Now H): byte, default is 7f, values are 00 to ff in hex
Setting18: byte, read-only, default is 00
Setting19: byte, read-only, default is 00
Setting20: byte, read-only, default is 00
Push: byte, default is 60, values are 00 to ff in hex
Setting22: byte, read-only, default is 00
Setting23: byte, read-only, default is 00

Setting24: byte, read-only, default is 00
Pull: byte, default is a0, values are 00 to ff in hex
Setting26: byte, read-only, default is 00
Setting27: byte, read-only, default is 00
Setting28: byte, read-only, default is 80
Vertical Center (Now V): byte, default is 7f, values are 00 to ff in hex
Setting30: byte, read-only, default is 00
Setting31: byte, read-only, default is 00

Printing out the eeprom we have gives us this:

Code:
$ ./eeprominfo dummy.eeprom --display
Serial: BDF0
Game Settings Hex: 00 03 00 00 00 00 00 00 26 26 00 00 e6 e5 00 00 80 7f 00 00 59 59 00 00 b9 b8 00 00 80 7f 00 00
Parsed Game Settings:
  Game Difficulty: Normal
  Number of Monkeys: 3
  Ball Velocity Boost: Off
  Left: 26
  Right: e5
  Horizontal Center (Now H): 7f
  Push: 59
  Pull: b8
  Vertical Center (Now V): 7f

Okay, so we know that these are the right settings but we still have to handle the other bytes. We can do a fancy trick in "BDF0.settings" where we state that a setting default is dependent on another setting's value. Here's what my settings definition looks like now:

Code:
Game Difficulty: byte, default is 00, 0 - Normal, 1 - Hard
Number of Monkeys: byte, default is 03, values are 2 to 5
Ball Velocity Boost: byte, default is 00, 0 - Off, 1 - On
Setting03: byte, read-only, default is 00
Setting04: byte, read-only, default is 00
Setting05: byte, read-only, default is 00
Setting06: byte, read-only, default is 00
Setting07: byte, read-only, default is 00

LeftUnknown: byte, read-only, default is value of Left
Left: byte, default is 60, values are 00 to ff in hex
Setting10: byte, read-only, default is 00
Setting11: byte, read-only, default is 00
RightUnknown: byte, read-only, default is value of Right + 1
Right: byte, default is a0, values are 00 to ff in hex
Setting14: byte, read-only, default is 00
Setting15: byte, read-only, default is 00

HCenterUnknown: byte, read-only, default is value of Horizontal Center (Now H) + 1
Horizontal Center (Now H): byte, default is 7f, values are 00 to ff in hex
Setting18: byte, read-only, default is 00
Setting19: byte, read-only, default is 00
PushUnknown: byte, read-only, default is value of Push
Push: byte, default is 60, values are 00 to ff in hex
Setting22: byte, read-only, default is 00
Setting23: byte, read-only, default is 00

PullUnknown: byte, read-only, default is value of Pull + 1
Pull: byte, default is a0, values are 00 to ff in hex
Setting26: byte, read-only, default is 00
Setting27: byte, read-only, default is 00
VCenterUnknown: byte, read-only, default is value of Vertical Center (Now V) + 1
Vertical Center (Now V): byte, default is 7f, values are 00 to ff in hex
Setting30: byte, read-only, default is 00
Setting31: byte, read-only, default is 00

So it turns out that the game does not display the current calibration on the screen. It always resets back to 60-a0 for both left/right and push/pull. So my strategy of setting values and seeing what happens would never have worked. I figured that out by running the calibration, saving and exiting and immediately re-entering the screen at which point the calibration values were back to their defaults again. However, it lead me down the path of figuring out that there are other settings bytes that matter. Now that I have this all figured out, I tested it by going into demul, setting the values for the calibration to some random values, then making a copy of the eeprom. I edited the copy and changed some of the calibrations, and then looked at the output of eeprominfo:

Code:
$ ./eeprominfo dummy.eeprom --display
Serial: BDF0
Game Settings Hex: 00 03 00 00 00 00 00 00 39 39 00 00 ff fe 00 00 80 7f 00 00 00 00 00 00 ff fe 00 00 80 7f 00 00
Parsed Game Settings:
  Game Difficulty: Normal
  Number of Monkeys: 3
  Ball Velocity Boost: Off
  Left: 39
  Right: fe
  Horizontal Center (Now H): 7f
  Push: 00
  Pull: fe
  Vertical Center (Now V): 7f

Cool, its adjusting those other bytes the way it should! Finally, I set the values back to what they were before using "edit_settings" and then compared it to the copy of the eeprom that I made above. Everything matched byte-for-byte which means the settings definition is adjusting the correct bytes in the correct manner!

And that's it! Now I have a settings editor for Monkey Ball:

ss.png


Keep in mind that Monkey Ball ended up being a bit difficult to figure out due to the way the calibration screen works. When I did Marvel Vs. Capcom 2 it was much more straightforward. It should be pretty easy to figure out settings for other games. If you want to give it a try, you can post your results here!
 
Last edited:
Another minor update. I added the ability to change what order settings are displayed inside an editor so that settings can be re-arranged to show up in the same order as the Naomi test menu. This wasn't a problem for MVC2 but it was for a few other games.

I finished definition files for Marvel vs. Capcom 2, Monkey Ball, Jambo Safari and Crazy Taxi now. Check them out: https://github.com/DragonMinded/netboot/tree/trunk/naomi/settings/definitions

Monkey Ball, Jambo Safari and Crazy Taxi all have calibration that needs to be run every netboot. If you use these tools, you can run the calibration once on your cabinet, write down the settings displayed on the screen before saving the calibration, and then run "./attach_settings edit" on a copy of the ROM file to configure your calibration for every netboot!

It turns out that Ikaruga does not use EEPROM for its settings at all. Instead, it uses the SRAM. So while system settings are supported by this project, game settings are not. If you want to netboot Ikaruga with custom game options, set them up in demul and then use "./attach_sram" to attach the "dummy.sram" file to your ROM so it shows up every boot. Note that this WILL overwrite any high scores so if you are netbooting Ikaruga and want to save your scores don't do this!
 
I integrated it with my own netdimm utilities late last evening, but I have yet to put together a web interface for my own web-based netbooter. Hopefully other people working on netboot stuff will want to integrate the libraries I published. I'm not sure @chunksin has seen this but it sounds like @LazerFlux is integrating it into his setup.
This is fantastic work! very interested in integrating it into the WiPi image, I wish I could offer some time to help build configs but I'm flat out on the card printing and don't want to lose focus on that
 
Haha for sure, I definitely have a lot of other stuff on my plate which is why I can't do all the configs either! I've put together a bunch of documentation for anyone who wants to integrate this but feel free to ask questions as well! I also want to think through how to do SRAM-style configs but the format of SRAM is much more variable. For now, the best I can come up with is to allow attaching an SRAM from an emulator to a ROM (either on the fly when netbooting or using ROM modification tools I made) so that the settings made in an emulator work on the Naomi. That takes care of the atomiswave conversions as well as Ikaruga and probably some other games that also use SRAM for settings instead of EEPROM.
 
Couple more updates:

First, I've done a few little fixes to to_json/from_json to make it easier to use for web interfaces that make use of https://pypi.org/project/naomiutils/ in their projects. I've pushed a new package for that including documentation. I've extended the patching utilities in naomiutils to also allow attaching an SRAM, much like the "attach_sram" utility which lives in my repo does. This means if you integrate with my tools you will be able to attach both EEPROMs and SRAMs on the fly when netbooting (but not both at once). SRAM attachment is mostly useful for setting up your settings for atomiswave conversions. All of this should be pretty transparent to you if you are integrating with your own netboot code.

Second, if you are using my netboot tools themselves from https://github.com/DragonMinded/netboot/ either on the command-line or with the web interface, that's been updated to integrate settings as well as several bugfixes. I spent a bit of time reverse engineering transfergame.exe and implemented an undocumented information get packet that lets you fetch the net dimm's memory size, current game CRC and firmware revision. That's available as 'netdimm_info' as well as on the config screen of my netboot utilities.

Here's what my web configuration looks like for Monkey Ball, which I am now booting with calibration set up!

finished.png


Hopefully this sort of thing shows up in other netboot solutions soon! For now, I'm going to keep messing with settings definition files for games that I care about and if anyone else wants to jump in and make definitions I can help you here as well.
 
Back
Top