Language…
11 users online: Apple Boy, Cracka, Digital Entertainment, Easy Difficulty, fanfan21,  MarioFanGamer, Natsuz2, slopcore, The_Kingslayer17, wizTheBard,  YouFailMe - Guests: 107 - Bots: 117
Users: 68,104 (2,174 active)
Latest user: Ghast_500

Official Hex/ASM/Etc. Help Thread

  • Pages:
  • 1
  • 2
  • 3
  • 4
  • 5
  • 405
  • 406
  • 407
  • 408
  • 409
  • 410
  • 411
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
  • 419
  • 420
Well, what did you expect from programming? :P
Mersenne Numbers aren't that hard to understand as the the formula is "2^n - 1" (and most people in computer sciense will know the formula before the name). What makes them special in base 2 (and therefore programming) is that consecutive bits from zero to a specific bit are set (i.e. 0x01 has bit 0, 0x03 has bits 0 and 1, 0x07 has bits 0, 1 and 2, etc. set). The advantage of using these values is that performing a modulo in base 2 is pretty easy with these numbers since you just have to perform an "AND #$MN" (with MN being the Mersenne Number).

That being said, 0x7F should work as normal as that's 0b01111111 or 2^7 - 1.
I tested the values previously given (1F and 3F) it works as intented.
I looked at a list of mersenne numbers, but I can't find anything in hexadecimal. In decimal 7F=127 which id one of the lowest mersenne number. The equivalent of 3F in decimal isn't in the list, yet works, which makes me think it's different in hex and dec.
Super Mario Pants World
Luigi's Lost Levels
New Super Mario Pants World
Luigi's Lost Levels 2 - Back With A Revenge
Luigi's Lost Levels 3 - Electrik Boogaloo
VLDC12 - 72HoKaizo#1


Originally posted by Romano338
The equivalent of 3F in decimal isn't in the list, yet works, which makes me think it's different in hex and dec.

It is, actually, as 63.

Basically, the hex version of the Mercenne numbers are 00, 01, 03, 07, 0F, 1F, 3F, 7F, FF. You'll notice a repeating pattern of "1-3-7-F"; this continues for any additional digits too, like 1FF, 3FF, 7FF, FFF, etc. The reason Mercenne numbers are useful for hex is because they represent a "full binary"; if you convert each of those numbers to binary, you'll see that they fill in all bits below the top one, i.e. 00000001, 00000011, 00000111, 0000111, 00011111, 00111111, 01111111, 11111111.

Professional frame-by-frame time wizard. YouTube - Bluesky - SMW Glitch List - SMW Randomizer
Indeed these values work as intended. It doesn't give me a lot of options though.
Why is that in mersenne numbers, when tons of other coding is not? Is there an easy way to make it not in mersenne?
Like the speed of the projectile, I pick any number between 00 and 7F and each one is different. Gives a lot more room to work.
Super Mario Pants World
Luigi's Lost Levels
New Super Mario Pants World
Luigi's Lost Levels 2 - Back With A Revenge
Luigi's Lost Levels 3 - Electrik Boogaloo
VLDC12 - 72HoKaizo#1
Math time!

In a nutshell: AND-ing with Mersenne numbers is a particularly nice way to decrease the range of the frame counter. It lets you easily make counters that go from 0 to 1, from 0 to 2, from 0 to 4, from 0 to 8, from 0 to 16, and so on, but nothing inbetween. By checking when such a counter is zero, you can make things happen every second frame, or every fourth frame, or every 8th frame, or every 16th frame, and so on.

However, this method can't give you timers that go from, say, 0 to 12, so you can't make things happen every 12th frame this way. It's possible to do of course, but it's less elegant and requires more code, so people often willingly limit themselves to Mersenne numbers to be able to write elegant code.




 


In order to use other numbers, you need to set up an actual timer using a RAM address. Thankfully, SMW has a bunch of RAM tables already allocated for sprites which you can use, and some of those are already set up to be used as timers. It looks like the noob boss has $1558 unused, so try that one.

Basically, take this part of the code:

Code
	LDA $14
	AND #$7F
	BNE NoSpawn

And replace it with:

Code
	LDA !1558,x
	BNE NoSpawn
	LDA #$xx	; how long you want to wait between spawns
	STA !1558,x


Professional frame-by-frame time wizard. YouTube - Bluesky - SMW Glitch List - SMW Randomizer
What is function flashing layer 1 and 2 with palette destination 00 in Bowser Valley's Lightning?
Neon Peridot's YouTube Channel


You can enable and disable it per submap by using the #lm{aniset} menu.

If you want to recreate it, you can make a basic effect using ExAnimation (#lm{exan}).

Professional frame-by-frame time wizard. YouTube - Bluesky - SMW Glitch List - SMW Randomizer
lightning in layer 1 and 2 on bowser's valley
how it works?
Neon Peridot's YouTube Channel


Well, as I said, you can imitate it using ExAnimation. It's not messing with any actual graphics; it's just animating the palette.

The way the actual game does it is a bit more complicated, as it randomly performs the flashes. It uses a palette handler table at $0682 for updating the colors.

Professional frame-by-frame time wizard. YouTube - Bluesky - SMW Glitch List - SMW Randomizer
Is there a way to do this cleaner or is this spot on? Just a test case for %get_map16() atm.

Code
	REP #$20
	LDA $9A		; x current pix
	LSR			; convert to block coord
	LSR
	LSR
	LSR
	STA $00		; x lookup
	LDA $98		; y current pix
	LSR			; convert to block coord
	LSR
	LSR
	LSR
	INC			; Block below
	STA $02		; y lookup
	SEP #$20
	%get_map16()
	BCS error
	REP #$30
	LDA $0000
	TAX
	SEP #$20
	LDA $41C800,x	; Get Map16 into A
	XBA
	LDA $40C800,x
	REP #$20
	STA $400F34
	SEP #$30
return:
	RTL
error:
	REP #$20
	LDA #$8664
	STA $400F34
	SEP #$20
	RTL


Mostly concerned about the LSRs (is there a way to get block coord directly?) and if my REP/SEP fiddling to get the map16 tile at the end is clean? Thanks in advance for any feedback/critique!


Is this Pixi's %get_map16() routine? Because that should handle dealing with $9A/$98 already, as well as accessing the Map16 tables at $40C800/$41C800.
(also, you can write multiple LSR/ASL opcodes like "LSR #4". Doesn't save space though, it's just for readability)

Otherwise, though, yeah that's the only way to shift a value down a nibble. It looks wasteful, but LSR/ASL are actually very fast opcodes at only 2 cycles per shift (comparatively, a JSL takes 8 cycles, meaning four LSR/ASL opcodes can run in the same time as one JSL).

Professional frame-by-frame time wizard. YouTube - Bluesky - SMW Glitch List - SMW Randomizer
LSR #4 at least makes the code more readable so thanks a ton for that.
GPS is what it's for. I don't think it handles getting block coords, so that would mean I did it right!
On a related note:

I'm trying to implement a %next_map16() as per my asm request thread entry (dunno how I missed %get_map16() already existing when I requested them... :/)

Code
; call %get_map16() to prep input. then call the following:
next_map16:
	BCS error
	REP #$10
	LDX.w $00
	LDA $40C800,x
	CLC
	ADC #$01
	STA $40C800,x
	LDA $41C800,x	; Get Map16 Tile into A	
	ADC #$00
	STA $41C800,x	; Get Map16 Tile into A	
	SEP #$10
;Update...
;	JML $00C0FB|!bank	;pulled from %change_map16(), I *know* it needs more before it.
;Just not understanding what yet, seeing something about layers?
error:
	RTL


Any quick suggestions on this to get me pointed in the right direction/solve this?
(Trying to next_map16 so that I don't have to have 16+ copies of the same block asm, the usual use case I guess).
Not even sure if $00C0FB works the way I think it does.

Thanks as always by the way Thomas! I've gotten a couple cool blocks made already thanks to your help!

(If there's a more streamlined way of doing it you can think of that would be welcome feedback too!)

If it's *super* involved I'll probably just cheat and call get16,INC,change16...

EDIT: ended up doing just that. Looked like understanding the layer code would only save me about 16 instructions afaik, which just wasn't worth the optimization effort. (and fixed table stretch...)
Context: Know next to nothing about SPC. Or which/whatever does the music thingies! X3
Was the only idea I had just now to increase decrease loading time of music besides global music.

Question: Is it possible to cache a projected "next song" into RAM somewhere and DMA/"redirect via pointer (multibuffer)" to quickly load it when asked? Or is that RAM completely isolated/other technical difficulty (no actual speed gains, etc.)? If so, anyone have any pointers? Docs/wikis/RAM addresses/co-dev recommendations/gimme free code/pseudo code/write my will and testament?

Use Case: Eventual fleshing out of the Jukebox Block I posted in ASM Request. Waaaay down the road, but figured it wouldn't hurt to ask for help! Especially since learning an entire topic just for a (I would assume) few lines of code is... daunting (TT^TT)

Fringe Idea: Make 2 global songs that are just a "calloc()" of the largest song essentially and load next song into that ram via DMA then load that global song. This would be the multibuffer approach pseudo-concept.

Edit: Was bitten by the urge to poke and I'm now a little scared to touch this project. I was wrong. Very wrong. I see that now. Not a patch for the faint of heart. Seems I'd need to apply a patch maybe even hijack NMI to ignore SPC I/O when flagged and probably learn SPC-asm and SA1-asm so I can upload a byte at a time in a remotely fast manner. That about the gist of it? Or did I careen off course? *shivers*
Not sure if this is tool-related (ASAR) or asm-related...
Anywho, I'm making a patch and currently it's setup like so:
Code
org $someaddress
JMP routine

I'd like to replace that with:
Code
freecode
JMP routine

or similar. Only problem is, I need to access that location from outside the patch (shared-subroutine essentially, and I could do it that way if needed). Is there a way to get the generated address (I assume I can lock it in place with the static keyword? Maybe a define file?) Not really sure the best way to set this up. Any help with this? Or is this not possible?

Edit: This has been tried a couple times before it seems. For those who follow: yes you can get it by writing external tools, no you can't using just ASAR. Afaik, from what I found anyway.
I am looking for something that as soon as you press a button on the title screen, makes a small sound effect and lead directly to level C5. Any ideas?
Originally posted by Mandagary
I am looking for something that as soon as you press a button on the title screen, makes a small sound effect and lead directly to level C5. Any ideas?

Apply Patches:
One file, One player
No Overworld
Apply UberASM (game modes 07 and 08):
"Press start" sign
Inside the "Press Start" sign UberASM replace:
Code
main:

with:
Code
!sfx_number = $29
!sfx_port = $1DFC

if read1($00FFD5) == $23	;sa-1 compatibility
	!addr = $6000
else
	!addr = $0000
endif

main:
	LDA $18
	AND #$80
	ORA $16
	AND #$90
	BEQ .no_press	; check start, a, & b for press
	LDA #!sfx_number
	STA !sfx_port|!addr
	LDA #$00
	STA $0100
.no_press:

Ideally you'd want to disable controller input on game modes 04/05/06 (didn't test how far back you'd need to go but at least 6) and disable a/b/start for whichever ones you don't want to use (and edit the controller detect code accordingly)
Unfortunately, UberASM runs after the normal code though and I couldn't find the hijacks after 50 minutes :/

Edit: Not *thoroughly* tested. May break with saves. Didn't get that far in testing.
I'm trying to check a table to see if all the values are the same. If so, I want to conditionally compile different code.
Code
!counter = (table_end-table_start)
!prev = table_start+!counter
!flag = 0
while !counter
	if table_start+!counter-1 != !prev
		!flag #= 1
	!counter #= !counter--
endif

table_start
	db $00, $00, $00
table_end

table_start+!counter is, of course, not a table access afaik. Anyone know some preprocessor magic for this?
  • Pages:
  • 1
  • 2
  • 3
  • 4
  • 5
  • 405
  • 406
  • 407
  • 408
  • 409
  • 410
  • 411
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
  • 419
  • 420