Language…
18 users online: akawo, Alex No,  AmperSam, CharlieUltra, DanMario24YT, edgar, Fullcannon, Gemini0, Gulaschko, Hammerer, Heitor Porfirio,  MarioFanGamer, Maw, Metal-Yoshi94, NewPointless, Spedinja, steelsburg, timeisart - Guests: 273 - Bots: 359
Users: 64,795 (2,370 active)
Latest user: mathew

Window/Mask Registers Tutorial/Info

AdvancedASM CodingHDMA

Basic Q&A


Q. What is a Window Mask?
A. A window mask is a effect that "hides" the layer from being shown except for inside the "window." Regularly, you can only specify the left and right limits of the window,(meaning the top and bottom are the top and bottom of the screen,) but getting creative with HDMA will allow you to specify the top and bottom of the window, which truly makes it a window.
Q. What are the limits of these masks?
A. I've found a few so far:
1. You can only have two separate windows running.
2. You can only specify edges from left to right.
I'll add to this as I find more.
Q. How do I use these registers?
A. LevelASM or a sprite will do.

While regs.txt supplies a good amount of information on this, I'm going to try to describe these effects in layman's (or ASMman's) terms.
The "W" Variable
In all of these registers, I will use "W" as a variable. For pixels inside the range of the window, W is set. But outside the window, W is clear. Remember this.

Registers


2123 Window Mask Settings for BG1 and BG2
2124 Window Mask Settings for BG3 and BG4
2125 Window Mask Settings for OBJ and Color Window
Format: ABCDabcd

c = Enable the first window for Layer 1/ Layer 3/OBJ Layer
a = Enable the second window for Layer 1/ Layer 3/OBJ Layer
C/A = Enable both windows for Layer 2/Layer 4/Color
d = Window 1 Opposite for BG1/BG3/OBJ
b = Window 2 Opposite for BG1/BG3/OBJ
D/B = Window 1/2 Opposite for BG2/BG4/Color
What the Opposite bit does is it makes it so that the window specifices what ISN'T shown. If you have a window set in the center of the screen, but the opposite bit set, it actually makes the window where you CAN'T see the BG.
Technically, this is what's happening:
The "W" variable is usually, as you know, set for pixels inside the window and not for pixels outside the window. However, this bit sets ~W, which on the SNES means not. If it's set normally, it's unset. If it's unset normally, it's set. Makes sense if you think about it.

2126 Window 1 Left Position
2127 Window 1 Right Position
2128 Window 2 Left Position
2129 Window 2 Right Position
xxxxxxxx
Position on the screen. 00 = Left side of screen FF = Right. Up to FF. Left should ALWAYS be lower that the right position because otherwise it has "negative distance" and will not show.



212a Window mask logic for BGs
44332211
and

212b Window mask logic for OBJs and Color Window
----ccoo

44/33/22/11/oo/cc = Mask logic for Layer 1-4/OBJ Layer/Color
This address specifies what to do when two windows overlap.
Two bits, whose settings are:
Think of the "W" variable here. That's how they are adding these windows together.
00 = If there is a window on the specified area, it will show (Not working for me? Works like the AND) OR/ORA Operation.
01 = AND Operation. They will only show where they overlap.
10 = XOR Opertation. Same as below...?
11 = XNOR Operation. Window will now only effect where the windows overlap and where there is no window.

212e Window Mask Designation for the Main Screen
212f Window Mask Designation for the Subscreen
---o4321

1/2/3/4/o = If set, window will affect Layers 1-4/OBJ
This...seems to be a unnecissary register..? Seems to be able to disable a window effecting a layer.

2130 Color Addition Select
ccmm--sd
This register is used only when enabling COLOR in such registers above. The options are below:
cc = = Make colors black:
00 => Never
01 => Outside Window
10 => Inside Window
11 => Always

mm = Stop color math from happening
00 => Never
01 => Outside Window
10 => Inside Window
11 => Always

s = Add in subscreen
d = Direct color mode for 256-color BGs (?)

Note: BG2 will turn black wherever it can be effected. This is a overwrite caused by one of SMW's Windowing mirrors. It does not look like you can disable this; therefore, I'm going to try to write a patch to get rid of it.

Using these registers


Here I can supply examples on how to use these registers.
It's actually very basic, and only requires you know ORA, LDA, and STA.
I simply go down the list, setting the bits I want for the effect.
Example 1:
Masking off BG2 in about the early left part of the screen
Code
LDA #$20 ;\ Set bit C (enable window 1 for BG2)
STA $2123;/ On the BG1/BG2 Window Settings
LDA #$30 ;\ Pos. 30 for the left edge
STA $2126;/
LDA #$60 ;\ Pos. 60 for the right
STA $2127;/
; We ignore window mask logic, only one window enabled


Example 2:
Masking off BG1 and BG 2, in seperate windows that overlap..should be pretty weird.
Code
LDA #$82 ;\ Window 2 for BG2, Window 1 for BG1
STA $2123;/
LDA #$40 ;\
STA $2126;|
LDA #$A0 ;|
STA $2127;| Should cover a decent area, overlapping
LDA #$80 ;|
STA $2128;|
LDA #$E0 ;|
STA $2129;/
LDA #$0C ;\ ORA for BG1, XNOR for BG2
STA $212A;/

Example 3:
Some HDMA, now:
Code
DMATAB:
db $25 ; 25 scanline (all of status bar)
db $00 ; Normal, since you can't screw with the status bar

db $15 ; 15 scanline, 
db $02 ; Enable it

db $05 ; 05 scaline,
db $00 ; normal

db $10 ; 10 scanline,
db $03 ; Inversion+enable

db $01 ; 
db $20 ; Enable BG2 for window instead

db $00 ; done


STZ $4330 ;\
LDA #$23  ;|\
STA $4331 ;|/ $2123
REP #$20  ;|
LDA #DMATAB;|\ Storing the data
STA $4332  ;|/
PHK        ;|
PLY        ;|
STY $4334  ;|
SEP #$20   ;|
LDA #$08   ;|\ SMW Mirror for DMA enable
STA $0D9F  ;//
LDA #$40   ;\
STA $2126  ;| Nice bit of the screen
LDA #$EE   ;|
STA $2127  ;/
; No need for mask logic

^ That was quite a strange effect.
Example 4:
Color mask
Code
; I'm not using HDMA for simplicity's sake on this one.
LDA $2125;\
ORA #$20 ;| Color window enable, just for fun this time via ORA
STA $2125;/
LDA #$10 ;\
STA $2126;| almost ALL of the screen
LDA #$EF ;|
STA $2127;/
; No need for mask logic
LDA #$80 ;\ Make it black inside the window
STA $2130;/ (Alot will be blacked out)


Final Notes


--In every case, you'll want to use HDMA to get boxes rather than stripes. (You can find a tutorial in the ASM workshop summary.)
--I'm not done with this thread, and I'll edit as I learn more through others or my own tests.
--The OBJ layer is sprites, basically. (Yes, you can set windows on sprites. I don't know why you would, though.)
--The windows must be cut off at the status bar (A IRQ is triggered so it can't be touched.)
--Vertical scrolling causes the top of the window to flicker. You would be best disabling it.
--I'm convinced Carol uses some form of this for effects that are used often in Brutal Mario, but chances are that is a use of the circle mask effect in SMW than these registers.
LDA !imameliasJawYPosition
CLC
ADC #$7F
STA !imameliasJawYPosition

Wow. If I'd thought of it, I would have requested something like this, because I'm quite interested in learning more about windows and masking. (The vertical scrolling thing sucks, though...oh well.) I have a question or two, though...first of all, what if I want a colored mask rather than a black one? Would I need to involve $2132 in it...somehow? Also, this may sound like a stupid question, but...what exactly is a subscreen? I've heard the term before, but I don't think I ever found out the definition.

Nice, though. This looks very useful.

----------------

I'm working on a hack! Check it out here. Progress: 64/95 levels.
Originally posted by imamelia
first of all, what if I want a colored mask rather than a black one? Would I need to involve $2132 in it...somehow? Also, this may sound like a stupid question, but...what exactly is a subscreen? I've heard the term before, but I don't think I ever found out the definition.

Nice, though. This looks very useful.

Colored, I'm fairly sure, is just some color math. As for the subscreen....I don't know. It's been a really long while since I wrote and researched this information. :S

Nice job on making your jaw go down rather than through your head, we all appreciate that. :P
Isn't a subscreen just the top and bottom half of each screen, that Yoshi coins glitch on the boundary of?

World Community Grid: Thread | Team
 
The screen is made up of two screens: the main screen and the sub screen.

A not-so-accurate way to describe it would be that the main screen layers have priority over the sub screen ones. That's not the only difference but it's the one you'll most often run into.


Concerning color math... There's two ways to do color math: By adding/subtracting the fixed color (bg color), or adding/subtracting the sub screen(s). Adding the subscreen is how SMW does translucent levels. You take the color value of a pixel on the subscreen/bg color, and then literally add or subtract it to the pixel on the main screen.
Side note: There's a "1/2" flag that halves the subscreen colors before math is done. This is how SMW achieves the dark BG effect, and also how it doesn't blind you with pure white in translucent levels (since it is often adding two bright colors together).


Color windows are like the layer windows except they disable/enable color math. Works exactly how it sounds; the subscreen/bg colors aren't added/subtracted to the main screen ones if windowing tells them not to be.
I tried using the HDMA one in LevelASM, and it didn't work. I tried init and the regular, but it didn't work. It just crashed. Was there anything I had to change in the code first or something?
I have no idea what to change my layout it to...
Originally posted by TheGag96
I tried using the HDMA one in LevelASM, and it didn't work. I tried init and the regular, but it didn't work. It just crashed. Was there anything I had to change in the code first or something?

Yes. You need to move the "levelxx:" label to below the table, before STZ $4330.

AdvancedASM CodingHDMA