Language…
21 users online:  Ahrion,  AmperSam, Beed28, CircleFriendo, crocodileman94, DanMario24YT, gizmo_321, Green, Heitor Porfirio, JezJitzu, Maw, Mohamad20ZX, OEO6, OrangeBronzeDaisy, Papangu, recam, signature_steve, SMW Magic, steelsburg, TrashCity, yoshisisland - Guests: 300 - Bots: 517
Users: 64,795 (2,370 active)
Latest user: mathew

Change Sprite Spawn X Range

Hi folks, I'm trying to utilize the widescreen support baseROM for BSNES-HD, and it works great, however the sprite spawn distance is the same, so now I can actually see sprites spawn in on that extended screen space. I found plenty of locations in the mapping documents regarding Y Spawn Range (especially since LM has Y Spawn Ranges already built in as an option), but didn't have any luck on the X or Horizontal Spawn Ranges.

What I'm hoping is that there's a way to extend the spawn range for how far to the left/right a sprite needs to be to actually spawn in, adding about ~6ish blocks to the current position.

I can barely cobble together very simple UberASM, and I'm assuming if this is a feasible idea, it'll take at minimum, a hijack of the sprite spawning routine, so it's definitely beyond my current abilities. If anyone has any ideas on where I should look, or wants to take it on themselves to try putting together a patch, I'll be happy to take the time to try to figure out how to get it working, or to test out the spawn distance values for what "feels" best to me. I really only build Kaizo: Light, so anything I come up with for what feels good will be based on that style of hack.

The extra space provided by the widescreen capability really makes the levels feel a lot more fluid, since you can see so much more of what's coming up, so I think getting the sprite spawning to feel equally good could be really useful for a lot of creators who might otherwise not be interested in adding widescreen support :)

Thanks in advance for any help you're able to provide!


The spawn region offsets can be found in two tables at $02A7F6, as follows:

Code
org $02A7F6
	db $D0,$00,$20
org $02A7F9
	db $FF,$00,$01


The first table contains the low bytes, and the second contains the high bytes. The first offset marks the left/top spawn edge, while the third is for the right/bottom edge (the second value is a should-be-0 value used for level load). Adjusting these values should change the line at which sprites spawn in.

However, you will likely also have to change the despawn line, as otherwise a lot of sprites will likely appear and then immediately disappear because they think they're far enough offscreen to despawn. This is a *slight* bit more complicated as the relevant offsets are located across several copies of a routine known as SubOffscreen. Here's a list of those tables:

Code
org $01AC11
	db $30,$C0,$A0,$C0,$A0,$F0,$60,$90	; copy #1 low bytes
org $01AC19
	db $01,$FF,$01,$FF,$01,$FF,$01,$FF	; copy #1 high bytes

org $02D007
	db $30,$C0,$A0,$C0,$A0,$70,$60,$B0	; copy #2 low bytes
org $02D00F
	db $01,$FF,$01,$FF,$01,$FF,$01,$FF	; copy #2 high bytes

org $03B83F
	db $30,$C0,$A0,$80,$A0,$40,$60,$B0	; copy #3 low bytes
org $03B847
	db $01,$FF,$01,$FF,$01,$00,$01,$FF	; copy #3 high bytes

You'll probably want to bump all of the values in here a few extra tiles left/right accordingly (note that not all of the values are exactly the same across the three tables though!).


Now, this *still* won't be completely perfect unfortunately, as various non-standard sprite types (e.g. projectiles) were only ever meant to be visible on 256-pixel screen, with them being deleted the second they start to cross over the screen edges. These sprite types don't have a high byte in their X position at all, and you would likely have to add support for them via hijacks. That said, these should be relatively minor and the above tables *should* fix most of your issues (as far as I can think of, at least).

Professional frame-by-frame time wizard. YouTube - Twitter - SMW Glitch List - SMW Randomizer
Awesome, thank you! I'll play around with these values tomorrow and see what I'm able to come up with. Working around the limitations of non-nirmal sprites should be a small price to pay, especially since they will still work. No difference in amount of time to react when compared to standard 4:3 resolution, and I'll of course have to design with 4:3 support in mind anyway since the majority of players probably won't install a specific branch of BSNES just to play one hack in 16:9. It'd be nice to see this adopted into the main BSNES branch and hopefully become a common feature of modern hacks once both sides get all the kinks worked out!


Originally posted by ElohssaYtrid
It'd be nice to see this adopted into the main BSNES branch and hopefully become a common feature of modern hacks once both sides get all the kinks worked out!

It'll definitely be cool, though notttt sure if it'll become a common feature since only one emulator currently supports it right now, and flash carts will likely not be able to support it (except maybeeee through the Super NT). If it could be applied on top of existing hacks, though, that would probably be easier to work with.

(though it's worth noting that custom sprites also have their own SubOffscreen method that PIXI places dynamically, so you'd have to figure out how to adjust that as well)

Professional frame-by-frame time wizard. YouTube - Twitter - SMW Glitch List - SMW Randomizer
Funny you should mention PIXI, I just got done hunting that down. The pixi table is at the end of SubOffscreen.asm in ..\Routines

Code
.spr_t14:	
db $30,$C0,$A0,$C0,$A0,$F0,$60,$90 		;bank 1 sizes
db $30,$C0,$A0,$80,$A0,$40,$60,$B0		;bank 3 sizes
.spr_t15:	
db $01,$FF,$01,$FF,$01,$FF,$01,$FF		;bank 1 sizes
db $01,$FF,$01,$FF,$01,$00,$01,$FF		;bank 3 sizes


Widescreen support on its own might work as a patch for existing ROMs, but I have no idea how to account for changing spawns without ruining setups. It might be good for more standard hacks though. Definitely an interesting idea!

I have the spawning working decently. I'm going to test a little more and will share a video and my values. Thanks again for the help!
Video

Spawning from the left still has a slight bit of pop in. I settled on the following values and 60 extra pixels on each side in the BSNES-HD settings. I ended up using SA-1 since having almost 1.5x the active area of course increases processing, but it seems to be pretty stable. The jittering at the beginning of the video was OBS running poorly, not the ROM itself. I likely may end up tweaking these once I start trying to actually build levels with these settings, but here's what I used for the video:

For the ASAR Hex edit:

Code
org $02A7F6
	db $A0,$00,$40
org $02A7F9
	db $FF,$00,$01

org $01AC11
	db $50,$00,$B0,$00,$B0,$B0,$80,$50	; copy #1 low bytes
org $01AC19
	db $01,$FF,$01,$FF,$01,$FF,$01,$FF	; copy #1 high bytes

org $02D007
	db $50,$00,$B0,$00,$B0,$10,$80,$80	; copy #2 low bytes
org $02D00F
	db $01,$FF,$01,$FF,$01,$FF,$01,$FF	; copy #2 high bytes

org $03B83F
	db $50,$00,$B0,$40,$B0,$F0,$80,$80	; copy #3 low bytes
org $03B847
	db $01,$FF,$01,$FF,$01,$00,$01,$FF	; copy #3 high bytes


And the same thing in PIXI\Routines\SubOffScreen.asm:

Code
.spr_t14:	db $50,$00,$B0,$00,$B0,$B0,$80,$50	;bank 1 sizes
		db $50,$00,$B0,$40,$B0,$F0,$80,$80	;bank 3 sizes
.spr_t15:	db $01,$FF,$01,$FF,$01,$FF,$01,$FF	;bank 1 sizes
		db $01,$FF,$01,$FF,$01,$00,$01,$FF	;bank 3 sizes


The bit of pop-in is probably actually do a bit in another sprite graphics-related routine, GetDrawInfo. That routine is partly responsible for determining whether a sprite is far enough offscreen to skip its graphics routine. One of the conditions it checks for is if the sprite is more than 4 tiles off either side of the screen, in which case it skips the graphics routine entirely.

You'll likely have to adjust the offsets it uses for those +/- 4 to account for the wide screen size. Like SubOffscreen, GetDrawInfo also has three copies, as well as a fourth copy included with Pixi.

The relevant code looks like
The two values marked "value 1" and "value 2" are what you want to change. The first value is the left-side offset, and the second value is the total width of the allowed area (i.e. #$0100 for the normal 256-pixel screen, plus the #$40 on either side). You'll want to adjust those two value accordingly.

Here's hex edits for each of the routine copies:

Code
org $01A386		; copy #1
	db $0040
org $01A389
	db $0180

org $02D399		; copy #2
	db $0040
org $02D39C
	db $0180

org $03B781		; copy #3
	db $0040
org $03B784
	db $0180


Professional frame-by-frame time wizard. YouTube - Twitter - SMW Glitch List - SMW Randomizer
Video


That was exactly the trick! Thank you so much for your help and patience. With a little bit more tweaking to the spawn offsets and adjusting the GetDrawInfo values, I was able to achieve clean spawning in native 16:9. Bullet Bill Shooters and directly placed Bullet Bills both work just fine, which is definitely a plus. Time will tell what other limitations will arise.