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.