# m2:ros

**URL:** <http://selectbutton.net/t/m2-ros/5396>\
**Category:** King of Development\
**Tags:** metroid\
**Created:** [September 26, 2017, 8:38am UTC](http://selectbutton.net/t/m2-ros/5396 "2017-09-26T08:38:12Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![artee](http://selectbutton.net/user_avatar/selectbutton.net/artee/32/284596_2.png) [@artee](http://selectbutton.net/u/artee)\
**Post date:** [September 26, 2017, 8:38am UTC](http://selectbutton.net/t/m2-ros/5396/1 "2017-09-26T08:38:13Z")

</div>

> [@Samus Regurgitates](https://selectbutton.net/t/samus-regurgitates/5340/61):
>
> If you need me, I’ll be hacking the original game [Metroid II] because I’m an idiot.

That wasn’t a joke.

I’ve hacked/disassembled/poked at Metroid 2 intermittently over the past couple of years, but it wasn’t until literally last week that I got around to coding anything that could edit it. A while back some of us at metroidconstruction tried getting together to make an editor, but, um, nothing really came of it.

I wrote some stuff in Python to read the various kinds of level data, then I tried displaying it.

Here’s where I’m at so far: [https://imgur.com/a/gmpQ5](https://imgur.com/a/gmpQ5)

My code takes around ~15 seconds to render a full map. I know I’m using an interpreted language, but I suspect something is a _tad_ unoptimized (probably either file-io related or the fact that I literally have functions returning bitmaps).

Q: What’s a good GUI library for Python?

---

<div class="post-metadata">

**Author:** ![The\_Blueberry\_Hill](http://selectbutton.net/user_avatar/selectbutton.net/the_blueberry_hill/32/12009_2.png) [@The\_Blueberry\_Hill](http://selectbutton.net/u/The_Blueberry_Hill)\
**Post date:** [September 26, 2017, 11:00am UTC](http://selectbutton.net/t/m2-ros/5396/2 "2017-09-26T11:00:19Z")

</div>

Oh wow. This is ace.

> [@artee](#):
>
> Q: What’s a good GUI library for Python?

I was using PyQt for a thing. It was fine! Kinda depends on what you want to do, and where you wanna do it.

---

<div class="post-metadata">

**Author:** ![botagel](http://selectbutton.net/user_avatar/selectbutton.net/botagel/32/46461_2.png) [@botagel](http://selectbutton.net/u/botagel)\
**Post date:** [September 26, 2017, 1:37pm UTC](http://selectbutton.net/t/m2-ros/5396/3 "2017-09-26T13:37:20Z")

</div>

Comedy “wrap it in an Electron web app” option

---

<div class="post-metadata">

**Author:** ![Felix](http://selectbutton.net/user_avatar/selectbutton.net/felix/32/17_2.png) [@Felix](http://selectbutton.net/u/Felix)\
**Post date:** [September 26, 2017, 2:04pm UTC](http://selectbutton.net/t/m2-ros/5396/4 "2017-09-26T14:04:04Z")

</div>

yeah PyQt is acceptable

---

<div class="post-metadata">

**Author:** ![SUPERSONNICK](http://selectbutton.net/user_avatar/selectbutton.net/supersonnick/32/32271_2.png) [@SUPERSONNICK](http://selectbutton.net/u/SUPERSONNICK)\
**Post date:** [September 26, 2017, 3:48pm UTC](http://selectbutton.net/t/m2-ros/5396/5 "2017-09-26T15:48:11Z")

</div>

> [@artee](#):
>
> Q: What’s a good \_\_\_\_\_\_ library for Python?

is a good question, and a hard one at that.  
Phyton 2.x, I assume?

  
I curse the day i agreed to take python3 for the project at work that i am involved in atm, because IF you get a recommendation, ''of course it is for 2.x, you silly! why'd you use 3 you fool?''

Because We Can™

Anyway, in the request lib for doing lowlevel network & IP messaging stuff, an interesting issue has reared its head this week:  
Namely if you have the wireless connection to wayside going down and up again, new resolve.conf information never seems to get through to pythons innards, the lib and/or the application, and that’s a case we have to considerrrrrrrrrrrrrrrrrrr without kicking the application or god beware, rebooting the host, hrmmmmmmmmmmmm ~~~~~~~~

---

<div class="post-metadata">

**Author:** ![Felix](http://selectbutton.net/user_avatar/selectbutton.net/felix/32/17_2.png) [@Felix](http://selectbutton.net/u/Felix)\
**Post date:** [September 26, 2017, 4:05pm UTC](http://selectbutton.net/t/m2-ros/5396/6 "2017-09-26T16:05:35Z")

</div>

I think most people finally up and switched to 3 in 2015-2016. I still fuck up the print statement and iteritems occasionally but otherwise I’ve made my peace (though 3’s urllib is still terrible at unicode, you should be using requests instead)

---

<div class="post-metadata">

**Author:** ![botagel](http://selectbutton.net/user_avatar/selectbutton.net/botagel/32/46461_2.png) [@botagel](http://selectbutton.net/u/botagel)\
**Post date:** [September 26, 2017, 5:53pm UTC](http://selectbutton.net/t/m2-ros/5396/7 "2017-09-26T17:53:40Z")

</div>

Admittedly most of my Python work lately has been limited-use internal tools but I haven’t run into very much that’s _actually_ stuck in 2.X anymore. Maybe I’m just not looking in the “right” categories.

---

<div class="post-metadata">

**Author:** ![artee](http://selectbutton.net/user_avatar/selectbutton.net/artee/32/284596_2.png) [@artee](http://selectbutton.net/u/artee)\
**Post date:** [October 1, 2017, 6:11am UTC](http://selectbutton.net/t/m2-ros/5396/8 "2017-10-01T06:11:27Z")

</div>

> [@The\_Blueberry\_Hill](#):
>
> I was using PyQt for a thing. It was fine! Kinda depends on what you want to do, and where you wanna do it.

Thanks for the suggestion. I’ve decided to go with it.

> [@SUPERSONNICK](#):
>
> Phyton 2.x, I assume?

Python 3, actually. I was aware that it was incompatible with 2.x, but wasn’t really aware of the pros/cons. I’m relatively new to Python, and not really sure why I decided to do this project in that language, but here we are.

* * *

In the process of porting/refactoring my rendering code from using Pillow to PyQt, I produced this lovely image.

![pyqt metatileset](https://dlcn7yodlhcnn.cloudfront.net/original/3X/f/3/f34d26fad5e61aa80128feffe75814c630deaf2a.png)

The weird colors are because I had been ignoring tiles with indexes \>= 128, and in the process of moving the code over I removed the code that initialized the bitmaps with a solid fill-color, so I got some surprisingly nice looking uninitialized data.

That was enough to convince me to add support for the upper half of the tileset (it’s loaded separately), which also happens to be necessary for rendering the surface area (the ship takes a boatload of tiles).

So yeah, [here’s a map](https://imgur.com/a/KZnrH) with the surface area. Marvel at the differences between the beginning and ending landing sites. (Also, the new code renders it about 3 times faster.)

> **Here's the state of the "gui":**
>
> ![rose](https://dlcn7yodlhcnn.cloudfront.net/original/3X/d/2/d2c9656429d988a08f90b6015fb2cb6acf1be645.png)
> 
> Currently the only interactive portion is the file dialog, but hey it’s a start. The tutorials and documentation for PyQt have been very useful.

Another feature I added, as seen in the gui, is a visualization of the scroll data for each bank.

> **Behold**
>
> ![scroll9](https://dlcn7yodlhcnn.cloudfront.net/original/3X/e/6/e640ee4f6a0be090c8874213b0364703d2df2012.png) ![scroll10](https://dlcn7yodlhcnn.cloudfront.net/original/3X/4/d/4d287b9a00d809e6a41553baa34ee2e1a3ef8048.png) ![scroll11](https://dlcn7yodlhcnn.cloudfront.net/original/3X/9/1/914268ec4ad19c7440d28021d8a9d2f6c2b08da4.png)
> 
> ![scroll12](https://dlcn7yodlhcnn.cloudfront.net/original/3X/2/0/20eb0df1b6f442fe714e6584a980f44c2707e446.png) ![scroll13](https://dlcn7yodlhcnn.cloudfront.net/original/3X/1/7/17d86dfe9401f4518e80ca1ceb60c2218f9b3cb5.png) ![scroll14](https://dlcn7yodlhcnn.cloudfront.net/original/3X/3/f/3f72b5181d05c5310ce5230322fcbeee688b4fb2.png)
> 
> ![scroll15](https://dlcn7yodlhcnn.cloudfront.net/original/3X/1/1/11b41acd1d40dc1b1a9199ad8e8126ea474133ca.png)

Again, there are vestiges of unused rooms in some of these that I plan on documenting on TCRF eventually.

---

<div class="post-metadata">

**Author:** ![artee](http://selectbutton.net/user_avatar/selectbutton.net/artee/32/284596_2.png) [@artee](http://selectbutton.net/u/artee)\
**Post date:** [May 31, 2022, 6:05am UTC](http://selectbutton.net/t/m2-ros/5396/9 "2022-05-31T06:05:56Z")

</div>

5 years? dang

there are several reasons why i got burnt out on this, many of which boil down to “I don’t want to program some absurd spaghetti code to edit variable-length data in place in a binary file when an assembler could do those things for free”

with that in mind, I’ve been working on a disassembly for the past couple of weeks, and it feels like it’s might actually come together

> **[GitHub - alex-west/M2RoS: A disassembly of a classic Game Boy game.](https://github.com/alex-west/M2RoS)**
>
> A disassembly of a classic Game Boy game. Contribute to alex-west/M2RoS development by creating an account on GitHub.

the end goal of this (whether i make the editor or someone else does) is to have a workflow that more closely resembles a homebrew game, with an editor that operates on free-floating files rather than an ossified binary blob

---

<div class="post-metadata">

**Author:** ![artee](http://selectbutton.net/user_avatar/selectbutton.net/artee/32/284596_2.png) [@artee](http://selectbutton.net/u/artee)\
**Post date:** [June 2, 2022, 5:46am UTC](http://selectbutton.net/t/m2-ros/5396/10 "2022-06-02T05:46:03Z")

</div>

the most mysterious, wistful form of lost content:

![image](https://dlcn7yodlhcnn.cloudfront.net/original/3X/3/e/3e04ddf586045181c5a32bb3a08c9507d5ad19fe.png)

things that were commented out of the original source code, whose existence is only hinted at by a trail of dangling references

---

<div class="post-metadata">

**Author:** ![artee](http://selectbutton.net/user_avatar/selectbutton.net/artee/32/284596_2.png) [@artee](http://selectbutton.net/u/artee)\
**Post date:** [June 16, 2022, 6:16am UTC](http://selectbutton.net/t/m2-ros/5396/11 "2022-06-16T06:16:29Z")

</div>

extremely pointless missing content ™

![gullugg](https://dlcn7yodlhcnn.cloudfront.net/original/3X/a/0/a0465b10df4139b54ad161f5fcfa13dab2e919fb.gif)

the enemy only moves clockwise in-game, though apparently there are unused/unreferenced tables that would have made it move anti-clockwise

 ![image](https://dlcn7yodlhcnn.cloudfront.net/original/3X/5/6/561ee945b337bd58dab0fb28f745466f2275234d.png)

~scintillating~

---

<div class="post-metadata">

**Author:** ![artee](http://selectbutton.net/user_avatar/selectbutton.net/artee/32/284596_2.png) [@artee](http://selectbutton.net/u/artee)\
**Post date:** [June 23, 2022, 5:22am UTC](http://selectbutton.net/t/m2-ros/5396/12 "2022-06-23T05:22:09Z")

</div>

I was investigating how doors work, but was slightly confused. They had code that differed depending on if the door was hit from the right or the left, but I didn’t see any code path that would allow them to control which direction they spawned.

After just a little poking at some ram addresses, I discovered the terrifying truth:

![image](https://dlcn7yodlhcnn.cloudfront.net/original/3X/5/8/58706d25e91255459c304ad0c51ab8dfaf503bc8.png)

lmao

turns out that the left and right door caps are a single object, conjoined at all times

compared to what i’m used to with these games, this is a bewildering (brilliant) solution to this problem

---

<div class="post-metadata">

**Author:** ![artee](http://selectbutton.net/user_avatar/selectbutton.net/artee/32/284596_2.png) [@artee](http://selectbutton.net/u/artee)\
**Post date:** [June 29, 2022, 6:22am UTC](http://selectbutton.net/t/m2-ros/5396/13 "2022-06-29T06:22:47Z")

</div>

Puzzled out how the spider ball works:

 ![IMG_20220628_191848](https://dlcn7yodlhcnn.cloudfront.net/original/3X/d/3/d338e97e3ad48e96fae59f7ede520bf84350b4e5.jpeg)

Figured out things well enough that I was able to improve the controls with just a little effort:

> **[Improved Spider Ball Controls - Metroid Construction](https://metroidconstruction.com/resource.php?resource_id=568)**
>
> Metroid hacking community.

> This patch moderately improves the controls of the spider ball. Now, when resting on corners (and in every other spider ball state), the game will properly respond to any sensible cardinal or diagonal direction.

no more getting stuck on corners 🥳

---

<div class="post-metadata">

**Author:** ![artee](http://selectbutton.net/user_avatar/selectbutton.net/artee/32/284596_2.png) [@artee](http://selectbutton.net/u/artee)\
**Post date:** [July 16, 2022, 6:32pm UTC](http://selectbutton.net/t/m2-ros/5396/14 "2022-07-16T18:32:50Z")

</div>

CW: Photosensitivity Hazard

> **Animated GIF**
>
> ![bank 1 OH NO](https://dlcn7yodlhcnn.cloudfront.net/original/3X/e/3/e3df0342601aebd2b48ca7ce51cf7560accf5e68.gif)

Context: I’ve been working on having the contents of the banks be “fully relocatable”, which entails making sure all the pointer constants in the code/data use labels instead of hardcoded numbers. Reaching this milestone for each bank is important because it will allow hackers to add code/data to banks without worrying about breaking things.

I’ve been doing informal tests here by just putting an extra `nop` at the beginning of the bank and seeing if anything breaks. Apparently, in this case, I didn’t have labels for (a) the pointer table for enemy sprites or (b) the palette table for the fade-in effect, which resulted in that lovely, terrifying mess. (I’m surprised the game didn’t crash, honestly.)

With those things fixed now, bank 1 Seems To Work Fine Now ™ (fingers crossed).

---

<div class="post-metadata">

**Author:** ![artee](http://selectbutton.net/user_avatar/selectbutton.net/artee/32/284596_2.png) [@artee](http://selectbutton.net/u/artee)\
**Post date:** [July 23, 2022, 7:50pm UTC](http://selectbutton.net/t/m2-ros/5396/15 "2022-07-23T19:50:35Z")

</div>

Two things today:

1. Immediately after the table that defines the transverse (sideways) motion of the wave beam, there’s another table that is unused, but appears to work with the wave beam as well.

```auto
.waveSpeedTable: ; 01:5183 - Wave speed table (transverse velocity)
    db $00, $07, $05, $02, $00, $fe, $fb, $f9, $00, $f9, $fb, $fe, $00, $02, $05, $07
    db $80

.waveSpeedTable_alt: ; 01:5194 - Unused (alternate wave table -- motion blur makes it looks very spazer-like)
    db $0A, $F6, $F6, $0A, $0A, $F6, $F6, $0A, $0A, $F6, $F6, $0A, $80

```

Here’s what it looks like in action.

![alt wave beam](https://dlcn7yodlhcnn.cloudfront.net/original/3X/b/5/b5678b85a48a045b52396cc350250ecf2baab980.gif)

Apologies for my gif recorder making it look jankier than it is, but in person it mainly looks like a blurrier version of the spazer. Perhaps this was a earlier version of the spazer, or perhaps the visual similarity made them choose to make the wave beam’s pattern more sophisticated.

1. ![image](https://dlcn7yodlhcnn.cloudfront.net/original/3X/3/6/3614aeb21698c62812695637a9643405f7e257da.png)

💯 🥳 💯

now i just need to multiply that number by 20 and i’ll be caught up with the [link’s awakening disassembly](https://github.com/zladx/LADX-Disassembly) (that’s how code works right?)

---

<div class="post-metadata">

**Author:** ![artee](http://selectbutton.net/user_avatar/selectbutton.net/artee/32/284596_2.png) [@artee](http://selectbutton.net/u/artee)\
**Post date:** [July 30, 2022, 10:06pm UTC](http://selectbutton.net/t/m2-ros/5396/16 "2022-07-30T22:06:43Z")

</div>

In the metroid queen fight, the game does not allow you to pause. Fixing this is as simple as changing a conditional `ret` to a `nop` in the function that determines if you are allowed to pause (some other conditions include “are you standing on a save point” or “is a door transition in progress”).

I thought enabling this would cause some terrifying gamebreaking bug to happen, but no it just causes a couple minor graphical glitches:

![queen pause](https://dlcn7yodlhcnn.cloudfront.net/original/3X/1/d/1d769f27acc86dc386e975b091b277c77e6bf785.gif)

First, her feet keep on moving if they were moving when you paused (she’s quite impatient with you, it seems). This is because part of the animation logic for her feet is done during VBlank (lmao). Fixing this would be pretty simple, imho.

Second, the palette effect is not being applied to the lower half of the background layer. I believe this is related to the fact that the game uses raster interrupts to change her palette when she gets hit. Fixing this bit seems like it would be slightly harder.

---

<div class="post-metadata">

**Author:** ![artee](http://selectbutton.net/user_avatar/selectbutton.net/artee/32/284596_2.png) [@artee](http://selectbutton.net/u/artee)\
**Post date:** [July 31, 2022, 6:49am UTC](http://selectbutton.net/t/m2-ros/5396/17 "2022-07-31T06:49:58Z")

</div>

I did not expect to figure this out that quickly, but whatever:

![queen pause 2](https://dlcn7yodlhcnn.cloudfront.net/original/3X/c/d/cd972a707fe0e7acb4ff4cb80d8f0ba8596bafc1.gif)

only issue with the approach I took is that the bottom half of the screen updates a frame early, but at 60 FPS it’s only a minor issue

---

<div class="post-metadata">

**Author:** ![artee](http://selectbutton.net/user_avatar/selectbutton.net/artee/32/284596_2.png) [@artee](http://selectbutton.net/u/artee)\
**Post date:** [August 21, 2022, 10:46pm UTC](http://selectbutton.net/t/m2-ros/5396/18 "2022-08-21T22:46:29Z")

</div>

The other day, since I was nearing completion of a full bank of code, I decided to take the symbol file the assembler generates and create a spreadsheet to properly track my progress for each bank:

```auto
Porg Repor
 S - Satisfactory
 N - Needs Comments (or conversion to .chr or whatever)
 X - :-(
 Progress = (S + .5*N)/Total

```

| Bank | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Total |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| S | 91 | 45 | 87 | 19 | ---- | 17 | 2 | 0 | 23 | 284 |
| C | 66 | 16 | 0 | 8 | ---- | 20 | 24 | 11 | 11 | 156 |
| X | 58 | 18 | 2 | 60 | ---- | 16 | 0 | 0 | 0 | 154 |
| Total | 215 | 79 | 89 | 87 | ---- | 53 | 26 | 11 | 34 | 594 |
| Progress | 58% | 67% | 98% | 26% | ---- | 51% | 54% | 50% | 84% | 60.9% |

These counts are of labels (but not sub-labels), which mostly means functions. Also, some fairly substantial chunks of the rom (e.g. enemy data, doors, sprite data) are only represented as a single labels for the purposes of this analysis.

- Bank 0 is the core of the game. It is always loaded and fixed in place.
- Bank 1 contains sprite data, the code for drawing Samus and the HUD, and a lot of odds and ends.
- Bank 2 is almost entirely enemy AI routines. It is essentially done.
- Bank 3 is the enemy map data, enemy headers, and the mess known as the queen’s AI (handled entirely separately from the enemies).
- Bank 4 is the music engine and song data, hermetically sealed from the rest of the game. A buddy of mine offered to do it themselves, and they say they’re almost done.
- Bank 5 is the title screen, credits, and door data.
- Banks 6-8 are mostly graphics and tilesets, with a few odds and ends here and there. There are a lot of graphics files that are stored as plaintext .asm that I should probably convert to .chr files.
- Banks 9-F are the level map data and required basically zero work, so they are excluded from this table.

So yeah, I guess it turns out the buddy of mine who said when I started “yeah we should be able to get this done by the end of the year” wasn’t that far off!

---

<div class="post-metadata">

**Author:** ![artee](http://selectbutton.net/user_avatar/selectbutton.net/artee/32/284596_2.png) [@artee](http://selectbutton.net/u/artee)\
**Post date:** [August 24, 2022, 5:46am UTC](http://selectbutton.net/t/m2-ros/5396/19 "2022-08-24T05:46:58Z")

</div>

I discovered that the problem with keeping track of progress numerically like this is that sometimes you pick low-hanging fruit instead of important stuff so you can reach arbitrary important milestones:

![image](https://dlcn7yodlhcnn.cloudfront.net/original/3X/6/9/697c323df5d32590bbdb1f96ab9069c9c2d3edf2.png)

---

<div class="post-metadata">

**Author:** ![artee](http://selectbutton.net/user_avatar/selectbutton.net/artee/32/284596_2.png) [@artee](http://selectbutton.net/u/artee)\
**Post date:** [September 25, 2022, 3:52pm UTC](http://selectbutton.net/t/m2-ros/5396/20 "2022-09-25T15:52:11Z")

</div>

Trying to get back into this, I felt inspired to resolve a persistent bugbear: several tables in the ROM are indexed by an enemy’s sprite number (e.g. sprite pointer, hitbox pointer, damage value, etc.). Keeping these all properly correlated by hand in a text editor is a huge pain (like, if you want to edit them), so I spent some time the other day shoving them all into a spreadsheet (.csv) and making a tool to convert it into a bunch of .asm files at assembly-time:

 ![image](https://dlcn7yodlhcnn.cloudfront.net/original/3X/3/9/394676111560a9d71ce69dcc3b51204bc65006b0.png)

heaven help me if i ever properly fill out all 255 rows of this

[Next page](http://selectbutton.net/t/m2-ros/5396.md?page=2)
