-
-
Notifications
You must be signed in to change notification settings - Fork 124
Document more of the Window's behaviour #626
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
ISSOtm
wants to merge
4
commits into
gbdev:master
Choose a base branch
from
ISSOtm:window
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| # Window behavior | ||
|
|
||
| ## FF4A–FF4B — WY, WX: Window Y position, X position plus 7 | ||
|
|
||
| These two registers specify the on-screen coordinates of [the Window]'s top-left pixel. | ||
|
|
||
| The Window is visible (if enabled) when `WX` and `WY` are in the range \[0; 166\] and \[0; 143\] respectively. | ||
| Values `WX`=7, `WY`=0 place the Window at the top left of the screen, completely covering the background. | ||
|
|
||
| ## Window mid-frame behavior | ||
|
|
||
| While the Window should work as just mentioned, writing to `WX`, `WY` etc. mid-frame displays more articulated behavior. | ||
| There are several aspects of the window that respond differently to various mid-frame interactions; the **tl;dr** is this: | ||
|
|
||
| - For the least glitchy results, only write to `WX`, `WY`, and `LCDC` during VBlank (possibly in your [VBlank interrupt handler]); if mid-frame writes are required, prefer writing during HBlank. | ||
| - If intending to hide the Window for part of the screen (e.g. to have a status bar at the *top* of the screen instead of the bottom), hide it by setting `WX` to a high value rather than writing to `LCDC`. | ||
|
|
||
| ### Window rendering criteria | ||
|
|
||
| The PPU keeps track of a “**Y condition**” throughout a frame. | ||
|
|
||
| - On each VBlank, the *Y condition* is cleared (becomes false). | ||
| - At the beginning of each scanline, if the value of `WY` is equal to [`LY`], the *Y condition* becomes true (and remains so for subsequent scanlines). | ||
|
|
||
| :::tip Note | ||
|
|
||
| On GBC, clearing the [Window enable bit] in `LCDC` resets the *Y condition*; `WY` must be set to `LY` or greater for the Window to display again in the current frame. | ||
|
|
||
| ::: | ||
|
|
||
| Additionally, the PPU maintains a counter, initialized to 0 at the beginning of each scanline. | ||
| The counter is incremented for each pixel rendered; however, it also increments 7 times before the first pixel is actually rendered (this covers pixels discarded during the initial "fine scroll" adjustment). | ||
|
|
||
| When this counter is equal to `WX`, if the *Y condition* is true and the [Window enable bit] is set in `LCDC`, background rendering is reset, beginning anew from the active row of the Window's tilemap. | ||
| The coordinate of the active Window row is then incremented. | ||
|
|
||
| - This process can happen more than once per scanline, making the Window's "tilemap Y coordinate" increase more than once in the scanline. | ||
| (This is demonstrated by the TODO test ROM.) | ||
|
|
||
| However, this requires "disabling" the Window by briefly clearing its enable bit from `LCDC` first. | ||
| - If this process doesn't happen, the Window's "tilemap Y coordinate" does not increase; so, if the Window is hidden (by any means) on a given scanline, the row of pixels rendered the next time it's shown will be the same as if it had not been hidden in the first place, producing a sort of vertical striped stretching: | ||
|
|
||
|  | ||
| - If `WX` is equal to 0, the Window is switched to before the initial "fine scroll" adjustment, causing it to be shifted left by <math><mi>SCX</mi> <mo>%</mo> <mn>8</mn></math> pixels. | ||
| - On monochrome systems, `WX` = 166 (which would normally show a single Window pixel, along the right edge of the screen) exhibits a bug: the Window spans the entire screen, but offset vertically by one scanline. | ||
| - On monochrome systems, if the Window is disabled via `LCDC`, but the other conditions are met *and* it would have started rendering exactly on a BG tile boundary, then where it would have started rendering, a single pixel with ID 0 (i.e. drawn as the first entry in [the BG palette]) is inserted; this offsets the remainder of the scanline.[^star_trek] | ||
avivace marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| [^star_trek]: This was discovered as affecting the game *Star Trek 25th anniversary*; more information and a test ROM are available [in this thread](https://github.com/LIJI32/SameBoy/issues/278#issuecomment-1189712129). | ||
|
|
||
| [the Window]: #Window | ||
| [VBlank interrupt handler]: <#INT $40 — VBlank interrupt> | ||
| [Window enable bit]: <#LCDC.5 — Window enable> | ||
| [`LY`]: <#FF44 — LY: LCD Y coordinate \[read-only\]> | ||
| [the BG palette]: <#FF47 — BGP (Non-CGB Mode only): BG palette data> | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You'd think the low bits of SCX would only be read once per line, because that's the logical way to do so, but unfortunately this isn't true. The fetched tile's X position is calculated (roughly) by adding SCX to LX and taking the 5 topmost bits, rather than adding the 5 topmost bits of SCX and LX.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. Do you know of a test ROM that checks this?
Also, it seems like it'd be a better fit for a separate PR, so I'll open one when I have some info to pen down.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ping @LIJI32