Language…
4 users online:  patcdr,  Tahixham, Tulip Time Scholarship Games, Yuzu - Guests: 38 - Bots: 142
Users: 68,102 (2,175 active)
Latest user: KizzWang

Posts by Arujus

Arujus's Profile → Posts

I just found out about this patch and would really like to use it in my hack if possible. I hope it is still under development. Reading through this thread Vitor talked at one point about releasing the next version in a few days, but it was never released.

I have been doing some testing with this patch and the various tools that work with it, most recently the manual custom block inserter, and I was encountering crashes when a sprite touches a custom block, just like King Dedede a few pages back:

Originally posted by King Dedede
Eh... There's a problem with the SA-1 version of the Manual Custom Block Inserter patch. Whenever a sprite touches a block from the custom block pages, the game crashes. It happens even if there is no code for the block.


I'm pretty sure the reason for the crash is that the patch uses SNES multiplication registers that will only work when executing on the SNES cpu and not on the SA-1 cpu, and when a sprite touches a block the custom block code will be executed on SA-1 because sprites run on SA-1.

To fix it the patch needs to be modified to use the SA-1 multiplication registers if executing on SA-1. Is there an easy way to check if we are currently executing on SA-1 or SNES? If there isn't then I'll just have to manually set some flag in the SpriteV and SpriteH cases of the patch and use that instead.

On a different note, how can you do a trace of code that is executing on SA-1? It seems that in the Snes9x debugger breakpoints only work for code executing on SNES and not on SA-1. I know this because when I was looking at the custom block inserter crash I tried putting a breakpoint at the start of the patch code and it was crashing without reaching the breakpoint, which was making me think for a while that the crash was happening before it reached the patch code, when in reality it was just not triggering the breakpoint.

Originally posted by Vitor Vilela
Some days I had a idea of expanding the maximum number of sprites on screen to 30 (instead of 10), but this require moving all sprite related RAMs to another place, but it's impossible to find free ram on Direct Page for 6 sprite addresses.... So, should I find a workaround for this or better I give up?


It's too bad that there is no addressing mode for DP indirect indexed by x, otherwise you could just store the addresses of the new sprite tables where the old tables were and then just change the addressing mode. Currently this would only work in cases where the tables are indexed by y.

I can't think of a good solution for expanding those tables that doesn't involve doing something stupid like putting a JMP in every place that the tables are accessed.

Originally posted by jesus
Originally posted by Vitor Viela
Code
(assuming that XX is in the $00-$3F or $80-$BF range
and YY equals either XX or $7E)

$YY:0000-$YY:00FF to $XX:3000-$XX:30FF.
$YY:0100-$YY:1FFF to $XX:0100-$XX:1FFF.


I'm not sure if I'm just being dumb, but I don't get what you mean by this. Are you just saying that for those banks ($00-$3F, $7E, and $80-$BF) all addresses $0000-$00FF are mapped to $3000-$30FF? In other words, the bank is NOT changing?


I was confused by this too when I first read it but I think I understand how all the memory mapping works now. As far as I know this is saying that previously all addresses of the form $YY:0000-$YY:00FF (for YY in the range $00-$3F or $80-$BF or $7E) accessed the same data, and now that data is instead accessed through addresses of the form $XX:3000-$XX:30FF (for XX in the range $00-$3F or $80-$BF). The same thing for the second line, except there is a mistake and it should say "$YY:0100-$YY:1FFF to $XX:6100-$XX:7FFF".

The SNES DEV book linked to at the end of the readme had some very helpful images on pages 1-3-1 and 1-3-2 of book 2 that helped clarify things for me.
Originally posted by Vitor Vilela

I have no idea why that patch is not working correctly.
The registers are okay, because you only have to use the SA-1 math registers when you're using SA-1 CPU.


The patch code does get executed on the SA-1 CPU when a sprite touches a block. Basically, the sprite (which is executing on SA-1 CPU) calls into the custom block code when it touches a block.

I fixed the patch by making it use the SA-1 math registers for the SpriteV and SpriteH cases. You can download my fixed version of it here: http://bin.smwcentral.net/u/23642/block_inserter.zip

Edit: I just realized that this zip comes with 1 custom block already (in Block500.asm): a block that is solid for Mario but sprites can pass through. You might want to remove this if you are considering adding this to your list of patches that work with SA-1.

Originally posted by Vitor Vilela

Originally posted by Arujus

It's too bad that there is no addressing mode for DP indirect indexed by x, otherwise you could just store the addresses of the new sprite tables where the old tables were and then just change the addressing mode. Currently this would only work in cases where the tables are indexed by y.

I can't think of a good solution for expanding those tables that doesn't involve doing something stupid like putting a JMP in every place that the tables are accessed.


Yeah, it's too bad. I guess I will with the worst option: Hijack every place which accesses those RAMs. It's around ~1700 to replace iirc, so I will try doing a tool or abuse regex to do that.


Don't worry about working on remapping the sprite tables so that they can be expanded, I'm working on that. I came up with a MUCH better solution than hijacking in every place that a sprite table on the direct page is accessed.

My solution involves using indirection and takes advantage of the fact that when indexing the sprite tables by x, the value of x remains more or less constant for the entire duration that the sprite is being processed, until we move onto processing the next sprite at which point the value of x changes. The idea is this: at the start of processing each sprite you can store the addresses of where this sprite's data is in the new tables (so for example if sprite table $E4 is being remapped off of the direct page to $3200 and we are processing the sprite at index 4, we store #$3204 somewhere on the direct page, say at $EE. When we move on to processing sprite 3 we will store #$3203 in $EE instead). Then you can replace accesses to these tables indexed by x with indirect accesses (not indexed by x) to wherever on the direct page we stored the appropriate address (so, if using the previous example, essentially replacing instructions like LDA $E4,x with LDA ($EE), both of which use only 2 bytes, so no need to hijack).

To test how well this would work I've been working on creating a patch that remaps the sprite X low position table ($E4) off of the direct page. After fixing up some problems (i.e., cases where x changes while processing a sprite and that new index is used to access sprite tables on the direct page) the game seems to be functioning quite normally, besides a few minor problems that still need fixing.

I plan on remapping the sprite Y low position ($D8) and the sprite number ($9E) tables off of the direct page as well. I chose these tables because they seemed like the easiest to remap. One of the huge advantages of my solution is that fixing a problem spot with remapping $E4 off the direct page typically also fixes that same problem that would have been encountered with remapping the other tables. So I expect that it should be much easier to remap the other two tables as well when I am done remapping the first one.

After this is done, there will be enough free space on the direct page for the remaining three sprite tables to be expanded (after being remapped to other addresses on the direct page), and we will be able to have 22 sprite slots!
Originally posted by worldpeace
edit:
Originally posted by Arujus
I fixed the patch by making it use the SA-1 math registers for the SpriteV and SpriteH cases.

I am not sure, but couldn't be SA-1 math registers used for all cases?


I just tested it out and you're right, you can use SA-1 registers on the SNES CPU. That makes things easier. Here is the updated custom block inserter:

http://bin.smwcentral.net/u/23642/block_inserter.zip
Originally posted by Vitor Vilela
And no, you can't use the SA-1 math registers on SNES CPU. It can even work on some emulators, but on real hardware it will fail.


Are you sure about that? It worked in all of ZSNES, SNES9x and BSNES for me, and if you look at the images in the SNES dev manual you can see that SA-1 registers are included in the memory map from SNES CPU perspective.
Ok, I changed it back, although it's worrying that something can work on all those emulators (including BSNES) but fail or real hardware.

Do you think it would be a good idea to make all custom block offsets run on the same CPU (either SNES or SA-1)? Currently, if a custom block wanted to do some multiplication for both the sprite offsets and Mario offsets it would have to split into multiple cases like the patch does.
So my work with remapping three sprite tables off of the direct page ended up being successful and so I've been able to expand all of the sprite tables to hold 22 sprite slots.

I've created a patch that does this and allows 22 sprites to be on screen. I'm posting it here so that anyone who is interested can start playing around with it. It is NOT recommended to be used in hacks yet since it is still rather experimental and likely has quite a few bugs. The file more_sprites.asm in the zip is to be applied AFTER applying the SA-1 patch. It also requires the no more sprite tile limits patch and includes my own custom version this patch which gets automatically applied, which means that the sprite header setting must be set to 10 for more sprites to work. For those that try this out, let me know of any bugs that you encounter. Here is a download link:

http://bin.smwcentral.net/u/23642/more_sprites.zip

Since this patch requires the no more sprite tile limits patch and that patch is not compatible with several sprites, I can either work on making it compatible with those sprites or allow the more sprites patch to be used without no more sprite tile limits. I'm not sure how feasible the latter option is because it requires giving each sprite index its own area of the OAM table in which it can upload, but I'm not sure the OAM is big enough for this.

This patch will currently not be compatible with any custom sprites or any tools/patches/blocks that access sprite tables. If any feature of lunar magic accesses sprite tables that feature won't be usable yet (but I'm not sure if any features do this, level editing at least works).

Although this is a separate patch from the SA-1 patch, hopefully it can be added as part of the SA-1 patch in the future.

Also, I did a sprite stress test which basically involved spamming as many different sprites as I could to see how the game would perform:

There are a total of 19 sprites on screen in this image. This many sprites does produce some slowdown. It seems that 17 sprites usually has no slowdown but once you reach 18 a little slowdown starts to appear. This is a little less than I was expecting could be on screen without slowdown given the increased speed of the SA-1. I was thinking the problem might be the sprite/sprite interaction because each sprite has to iterate over every other sprite so we have O(n^2) running time, but it really doesn't look like sprite/sprite interaction does much if the sprites aren't right next to each other. Maybe there is some benchmarking that can be done to see where time is being spent.
Originally posted by Sakuya Izayoi
Wow, this looks really epic! However, I assume Sprite Tool plays with sprite tables and thus won't work with it? Having that many standard sprites on-screen may not be THAT useful. I mean, unless you put a lot of Diggin' and Puntin' Chucks in the same screen as a mean late-game trap, I can't see how a normally-designed level could exceed the normal limit. Unless you're making a Danmaku boss or something like that, but that would require custom sprites either way.

But no mather what, it is really impressive!


It should be easy to make tools and sprites and stuff work with this patch. All that needs to be done is make them access the new sprite table locations instead of the old ones. I've been more focused on making sure that all vanilla smw stuff works properly than making custom stuff work. However, you may notice the file sprite_tables.asm included in the zip I posted. I intended that when modifying custom sprites, blocks and patches to be supported, the addresses of sprite tables can be replaced with definitions in this file. This has the advantage of allowing the table locations to be easily changed (the current table locations are not finalized) and can also allow the same sprite to support all of non SA-1, normal SA-1, and more-sprites SA-1 at the same time, with the mode controlled by a single flag in sprite_tables.asm. Maybe this file should be extended to include all addresses that were remapped by SA-1 instead of just the sprite tables.

Originally posted by Vitor Vilela
As for the slowdown, I think if we optimize a little more this patch we can get that rid. Also, what emulator were you using? If I remember correctly, ZSNES only emulates SA-1 at 5 MHz, so probably if you run on snes9x or bsnes, the slowdown will not happen since SA-1 runs actually at 10 MHz.


You're right, it's just in zsnes that there is slowdown; snes9x and bsnes work fine. That's kind of unfortunate since zsnes is such a widely used emulator for smw hacks. I don't suppose there's a way to increase the SA-1 to the proper speed by just modifying the zsnes.cfg file?
I'm working on playing through the entire original SMW with my patch applied and fixing any bugs I come across. Hopefully by the time I'm done the patch will be free of any significant bugs. Hopefully I'll be done by the time you are ready to add my patch to the SA-1 pack.

I've opted to try to make the no more sprite tile limits patch compatible with everything in the original SMW and then have it enabled all the time, so that the more sprites patch can work with everything from the original game.

Also, I'm thinking about moving the locations of some of the sprite tables. Currently, I've basically just remapped all sprite tables to IRAM, but some of the sprite tables are barely ever used so it might be wasteful to have them in IRAM. The tables take up roughly all of $3200 to $35FF, leaving only $3600 to $37FF free for use. I could leave some of the tables in BW-RAM, maybe 1/4 of them or something to free up $100 bytes of IRAM. I guess it comes down to how much we want to preserve IRAM for community use.
Originally posted by imamelia
I tried remapping the sprite tables myself, and I just barely made them fit into my allotted space: all of the original area used for sprites (part of the direct page and part of $1400-$1FFF, the latter of which would now be BW-RAM in $7400-$7FFF), the unused area from $6110-$61FF, and $3500-$36FF. With the additional sprite tables used by Tessera (minus $7FAB1C; the older Sprite Tools use it, but Tessera doesn't), they just fit in, with not a single 22-byte block to spare. I'm still not entirely sure what the best way to do it is, though. I mostly went by priority, but they ended up being a bit jumbled.


I didn't think Tessera worked with SA-1. Are you in the process of adding SA-1 support and this is the space that it will use then?

So if Tessera is going to use 512 bytes of IRAM is that all for storing new sprite tables used by Tessera (that would be a lot of new sprite tables)? It would require even more space if the new tables were to be expanded to 22 bytes each. How many new tables does Tessera add how feasible would it be to expand them to 22 bytes each?
Ok, I've made a lot of updates, mainly bug fixes, to the maximum sprite increasing patch. The updated version is here: http://bin.smwcentral.net/u/23642/more_sprites.zip

I still wouldn't recommend using this in major projects until it is part of the SA-1 pack.

You can enable having more sprites on screen by setting the sprite header setting to 10. This patch also comes with an improved version of the no more sprite tile limits patch that gets applied automatically and should work with everything from the original game (this new version can actually probably replace the old version since it should be usable independently of the more sprites patch if you incsrc sprite_tables.asm). The nmstl is enabled all the time, regardless of sprite header setting, because not having it enabled can cause problems even when having extra sprites is disabled.

Unlike the previous version of this patch, some significant testing has gone into it this time. That's not to say it doesn't have any bugs now (it could probably use some testers other than myself), but it should be mostly bug-free.

I don't think it's compatible with any of the mode 7 koopa-kid bosses or Bowser (when sprite header setting is 10), but it should be compatible with the non mode 7 ones.

For the sprite table remapping I decided to leave enough tables in BW-RAM to fill up the space where the tables used to be, because otherwise it would be hard to for anyone else to make use of that space since using it would depend on this hack being applied. I chose the tables that had the fewest occurrences on all.log to leave in BW-RAM, the rest are in IRAM.
Originally posted by Roberto zampari

Well, with No Sprite Tile Limits integrated with SA-1, will be the Sprite memory options unneccesary?


Sprite memory options are mostly unnecessary at this point, however, since allowing extra sprite slots still currently does not work with certain things like some mode 7 bosses it still needs to be explicitly enabled by setting the sprite header setting to 10.

Originally posted by jesus
Also, I have a question about Arujus's patch: Are the 20 sprite slots shared by normal and cluster sprites, or can we have 20 normal sprites and some N number of cluster sprite at the same time?


Cluster sprites use different sprite slots than normal sprites. The number of cluster sprite slots has not been changed.
Originally posted by LadiesMan_217
It seems to be incompatible with Reznors (at least for me). Even on a normal level. The only way to make it work is if I change #lm{sprhead} to the NMSTL patch header, but even with that, it places the Reznors on the upper left corner of the screen. Any other headers and the game crashes.


Reznor is not yet compatible when extra sprites are enabled (when sprite header is 10). It should still work with the sprite header that it was originally used with though, which is 0E, but you won't be able to have 20 sprites on screen.

Originally posted by Sakuya Izayoi
Hmm, for some reason the triple chained platforms make Mario invisible while he steps on them. As soon as he jumps, he reverts to normal. It is not a sprite tile limit error.


Do you have any more information on how to reproduce this? When I play Donut Plains 3 from the original game the platforms work just fine.
Originally posted by Sakuya Izayoi
There are 2 single chained platforms in the vicinity of the triple one, a few Paratroopas and the sprite header thingy to 10.


Does the disappearing by any chance only happen when Mario is standing on two of the platforms at once? Because he disappears in that case for me but he also disappears in the original game from that as well so it's not a bug of the SA-1 pack. Other than that, I didn't get any disappearing when I tried creating the setup that you described.

Originally posted by LadiesMan_217
As far as the no slowdown, it's great! But there still seem to be sprite tile limits (Yes, I'm using the NMSTL patch sprite header). As I thought, the new NMSTL patch doesn't seem to be compatible with the cage sprite (88), swooper death bat ceiling cluster (causes quite a few sprites to jumble up with the bats and they go EVERYWHERE). Arujus, do you plan to make it compatible with these sprites in the future and Reznor? Still got fingers crossed for the mode 7 bosses too #w{=3}. Also, I had 2 red koopas and a message box on screen 00, and 5 bullet bill shooters stacked on screen 01, and only 3 bullet bills shot, didn't matter if I killed the 2 koopas or not.
Quite recently, the orange platform (5D) had a weird glitch that occurred on level 102. I put a jumping fish generator, and was on Yoshi, stepped on a silver POW, and for some reason, it's tilemap used the 1st GFX page, turned to a red palette, and was a harmful sprite (looked quite scary as it floated up with messed up GFX #ab{o_O}). I would think it had nothing to do with the new NMSTL patch as I didn't use that header (was using 00). After exiting to level to 1FF, the game froze upon crossing the finish line, it also froze quite a few times while on Yoshi.


I'm not getting any of the bugs that you are describing. Swooper death bat ceiling and flying cage sprite work fine for me. Did you apply any NMSTL patch yourself? The the only NMSTL patch that should be used is the one that is applied automatically by the sa1 patch. You shouldn't have to apply NMSTL manually.

Other than that, what other patches have you used on your hack? Maybe you applied something incompatible with the SA-1 pack?

Let me know if you can find a way to get any of the bugs you described in a hack that has nothing but the SA-1 pack inserted.
Originally posted by WhiteYoshiEgg

Also, regarding the new sprite addresses: Are there any addresses that weren't used for sprite tables in the original SMW?
For example, one of the new sprite tables is $754C, and looking at the RAM Map, $154C was also a sprite table in SMW, which is fine. Are there any addresses, though, that don't map like that? I mean, is any of the new tables something like $6DBF (whereas I'd expect $0DBFto still hold the amount of coins)?

Hope I made myself at least remotely clear.


The only RAM used for sprite tables now that wasn't used for sprite tables in the original SMW is IRAM, specifically $3200 to $3425.

On a different note, I've been encountering a weird bug that only happens with ZSNES. It seems that if subroutine $00BEB0 is called from SA-1 then there is a very small chance that it will crash ZSNES. $00BEB0 is the subroutine used to change a map16 tile and is called by sprites at times such as when a mole jumps out of the ground to generate the hole in the ground, or as a vine climbs to generate the vine tiles.

The bug is difficult to reproduce on the original game but I wrote a sprite that makes it easier to get the bug:
Code
print "INIT ",pc
    RTL

print "MAIN ",pc
    LDA $322C,x
    STA $9A
    LDA $326E,x
    STA $9B
    LDA $3216,x
    STA $98
    LDA $3258,x
    STA $99

    LDA #$03
    STA $9C
    JSL $00BEB0
    RTL

Place 4 or so of these next to eachother in a level and run around for a bit and it should cause zsnes to crash.

I did a little digging around and saw that the $00BEB0 subroutine gets hijacked by the SA-1 pack at $00BFC5 (see boost/sprites.asm for the code for this hijack). The hijack checks if it's currently running on the SA-1 CPU and if so it calls the SNES CPU to perform the remainder of the subroutine. The crashing must have something to do with the CPU switching here because in the sprite above, if I instead get the SA-1 to call SNES and have SNES call $00BEB0 itself so that no CPU switching happens in the subroutine itself, then it will no longer crash ZSNES. However, I've looked through the hijack code and can't see anything that might cause problems.

So I don't really know what could be causing this problem. Like I said, I can only get it crash on ZSNES and not on BSNES or SNES9x, so it could even be some weird unpredictable ZSNES bug. Any ideas?