Skip to content

Commit 8e95d94

Browse files
committed
Finished cleaning up pixelfetcher
1 parent 043b6fe commit 8e95d94

File tree

4 files changed

+100
-59
lines changed

4 files changed

+100
-59
lines changed

core/graphics/pixelPipeline/pixelFetcher.ts

Lines changed: 31 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
// Fetcher for the pixel pipeline
22
// https://youtu.be/HyzD8pNlpwI?t=2957
3-
import { PIXEL_PIPELINE_ENTIRE_SCANLINE_FIFO_LOCATION } from '../../constants';
43
import { checkBitOnByte, setBitOnByte, resetBitOnByte } from '../../helpers/index';
4+
import { eightBitLoadFromGBMemory, eightBitStoreIntoGBMemory } from '../../memory/index';
55
import { Lcd } from '../lcd';
66
import { getTileDataAddress } from '../tiles';
77
import { LoadFromVramBank } from '../util';
8-
import { PixelPipeline } from './pixelPipeline';
8+
import { PixelFifo } from './pixelFifo';
9+
import {
10+
getPaletteColorIdForPixelFromTileData,
11+
loadPixelFifoByteForPixelIndexFromWasmBoyMemory,
12+
storePixelFifoByteForPixelIndexIntoWasmBoyMemory
13+
} from './util';
914

1015
export class PixelFetcher {
1116
// Number of CPU cycles for the current step of the fetch
@@ -36,7 +41,7 @@ export class PixelFetcher {
3641
static tileDataByteOne: i32 = 0;
3742
static tileAttributes: i32 = 0;
3843

39-
static startFetch(tileMapLocation: i32, tileLine: i32, isSprite: boolean, spriteArrtributeIndex: i32): void {
44+
static startFetch(tileMapLocation: i32, tileLine: i32, isSprite: boolean, spriteAttributeIndex: i32): void {
4045
// Reset the fetcher
4146
PixelFetcher.currentStatus = 0;
4247
PixelFetcher.cycles = 0;
@@ -47,16 +52,16 @@ export class PixelFetcher {
4752
PixelFetcher.spriteAttributeIndex = spriteAttributeIndex;
4853
}
4954

50-
static update(numberOfCycles: i32) {
55+
static step() {
5156
// Check if we can continue idling
5257
// Pixel Fetcher won't add more pixels unless there are only 8 pixels left
53-
let pixelsRemainingInFifo = PixelPipeline.numberOfPixelsInFifo - pixelFifoIndex;
58+
let pixelsRemainingInFifo = PixelFifo.numberOfPixelsInFifo - PixelFifo.currentIndex;
5459
if (PixelFetcher.currentStatus === 0 && pixelsRemainingInFifo > 8) {
5560
return;
5661
}
5762

58-
// Update our cycles
59-
PixelFetcher.cycles += numberOfCycles;
63+
// Update our cycles (Each step should be 4 CPU Cycles)
64+
PixelFetcher.cycles += 4;
6065

6166
// Update our current status / Execute the step
6267
let cyclesPerStep = 8 << (<i32>Cpu.GBCDoubleSpeed);
@@ -112,7 +117,7 @@ function _readTileData(byteNumber: i32): i32 {
112117
let tileAttributes: i32 = 0;
113118
if (PixelFetcher.isSprite) {
114119
// Get our sprite attributes
115-
let spriteTableIndex = i * 4;
120+
let spriteTableIndex = PixelFetcher.spriteAttributeIndex * 4;
116121
let spriteMemoryLocation = Graphics.memoryLocationSpriteAttributesTable + spriteTableIndex;
117122

118123
// Pan docs of sprite attribute table (Byte 3 of Sprite Table Entry)
@@ -191,12 +196,10 @@ function _storeFetchIntoFifo(): void {
191196
if (PixelFetcher.isSprite) {
192197
// Need to mix the pixel on top of the old data
193198

194-
// Get the location of where we will be mixing
195-
// Which is the first 8 pixels in the fifo
196-
let pixelFifoIndex = PixelPipeline.pixelFifoIndex * 11;
197-
198-
// Get our type per pixel
199-
let typePerPixel = eightBitLoadFromGBMemory(PIXEL_PIPELINE_ENTIRE_SCANLINE_FIFO_LOCATION + pixelFifoIndex + 2);
199+
// Get our data and type per pixel
200+
let fifoTileDataByteZero = loadPixelFifoByteForPixelIndexFromWasmBoyMemory(0, PixelFifo.currentIndex);
201+
let fifoTileDataByteOne = loadPixelFifoByteForPixelIndexFromWasmBoyMemory(1, PixelFifo.currentIndex);
202+
let fifoTypePerPixel = loadPixelFifoByteForPixelIndexFromWasmBoyMemory(2, PixelFifo.currentIndex);
200203

201204
// Go one by one for the 8 pixels in the current fifo
202205
for (let i = 0; i < 8; i++) {
@@ -206,41 +209,19 @@ function _storeFetchIntoFifo(): void {
206209
}
207210

208211
// Get the Palette Color Ids of the pixel in our current sprite
209-
// Colors are represented by getting X position of ByteTwo, and X positon of Byte One
210-
// To Get the color Id.
211-
// For example, the result of the color id is 0000 00[xPixelByteTwo][xPixelByteOne]
212-
// See: How to draw a tile/sprite from memory: http://www.codeslinger.co.uk/pages/projects/gameboy/graphics.html
213-
let spritePaletteColorId = 0;
214-
if (checkBitOnByte(i, PixelFetcher.tileDataByteOne)) {
215-
// Byte one represents the second bit in our color id, so bit shift
216-
spritePaletteColorId += 1;
217-
spritePaletteColorId = spritePaletteColorId << 1;
218-
}
219-
if (checkBitOnByte(i, PixelFetcher.tileDataByteZero)) {
220-
spritePaletteColorId += 1;
221-
}
212+
let spritePaletteColorId = getPaletteColorIdForPixelFromTileData(i, PixelFetcher.tileDataByteZero, PixelFetcher.tileDataByteOne);
222213

223214
// Palette ColorId zero (last two bits of pallette) of a sprite are always transparent
224215
// http://gbdev.gg8.se/wiki/articles/Video_Display
225216
if (spriteColorId !== 0) {
226217
continue;
227218
}
228219

229-
// Load the data & attributes for the pixel
230-
let fifoTileDataByteZero = eightBitLoadFromGBMemory(PIXEL_PIPELINE_ENTIRE_SCANLINE_FIFO_LOCATION + pixelFifoIndex + 0);
231-
let fifoTileDataByteOne = eightBitLoadFromGBMemory(PIXEL_PIPELINE_ENTIRE_SCANLINE_FIFO_LOCATION + pixelFifoIndex + 1);
232-
let fifoTileAttributes = eightBitLoadFromGBMemory(PIXEL_PIPELINE_ENTIRE_SCANLINE_FIFO_LOCATION + pixelFifoIndex + 3 + i);
220+
// Load the attributes for the pixel
221+
loadPixelFifoByteForPixelIndexFromWasmBoyMemory(3 + i, PixelFifo.currentIndex + i);
233222

234223
// Get the Palette Color Ids of the pixel in the Fifo
235-
let fifoPaletteColorId = 0;
236-
if (checkBitOnByte(i, fifoTileDataByteOne)) {
237-
// Byte one represents the second bit in our color id, so bit shift
238-
fifoPaletteColorId += 1;
239-
fifoPaletteColorId = fifoPaletteColorId << 1;
240-
}
241-
if (checkBitOnByte(i, fifoTileDataByteZero)) {
242-
fifoPaletteColorId += 1;
243-
}
224+
let fifoPaletteColorId = getPaletteColorIdForPixelFromTileData(i, fifoTileDataByteZero, fifoTileDataByteOne);
244225

245226
// NOTE:
246227
// We are trying to draw a sprite pixel over a BG/Window pixel.
@@ -271,24 +252,21 @@ function _storeFetchIntoFifo(): void {
271252
setBitOnByte(i, typePerPixel);
272253

273254
// Write back to the fifo
274-
eightBitStoreIntoGBMemory(PIXEL_PIPELINE_ENTIRE_SCANLINE_FIFO_LOCATION + pixelFifoIndex, fifoTileDataByteZero);
275-
eightBitStoreIntoGBMemory(PIXEL_PIPELINE_ENTIRE_SCANLINE_FIFO_LOCATION + pixelFifoIndex + 1, fifoTileDataByteOne);
276-
eightBitStoreIntoGBMemory(PIXEL_PIPELINE_ENTIRE_SCANLINE_FIFO_LOCATION + pixelFifoIndex + 2, typePerPixel);
277-
eightBitStoreIntoGBMemory(PIXEL_PIPELINE_ENTIRE_SCANLINE_FIFO_LOCATION + pixelFifoIndex + 3 + i, PixelFetcher.tileAttributes);
255+
storePixelFifoByteForPixelIndexIntoWasmBoyMemory(0, PixelFifo.currentIndex, fifoTileDataByteZero);
256+
storePixelFifoByteForPixelIndexIntoWasmBoyMemory(1, PixelFifo.currentIndex, fifoTileDataByteOne);
257+
storePixelFifoByteForPixelIndexIntoWasmBoyMemory(2, PixelFifo.currentIndex, typePerPixel);
258+
storePixelFifoByteForPixelIndexIntoWasmBoyMemory(3 + i, PixelFifo.currentIndex + i, PixelFetcher.tileAttributes);
278259
}
279260
}
280261
} else {
281262
// Simply add the pixels to the end of the fifo
282-
// * 11, because Fifo has the 2 data tile bytes, and for WasmBoy Specifically,
283-
// A 3rd byte representing the type of pixel (0 = BG/Window, 1 = Sprite)
284-
// Bytes 4-11 represent the attributes for that tile's pixel
285-
let pixelFifoIndex = PixelPipeline.numberOfPixelsInFifo * 11;
286-
eightBitStoreIntoGBMemory(PIXEL_PIPELINE_ENTIRE_SCANLINE_FIFO_LOCATION + pixelFifoIndex, PixelFetcher.tileDataByteZero);
287-
eightBitStoreIntoGBMemory(PIXEL_PIPELINE_ENTIRE_SCANLINE_FIFO_LOCATION + pixelFifoIndex + 1, PixelFetcher.tileDataByteOne);
288-
eightBitStoreIntoGBMemory(PIXEL_PIPELINE_ENTIRE_SCANLINE_FIFO_LOCATION + pixelFifoIndex + 2, 0);
263+
storePixelFifoByteForPixelIndexIntoWasmBoyMemory(0, PixelFifo.numberOfPixelsInFifo, PixelFetcher.tileDataByteZero);
264+
storePixelFifoByteForPixelIndexIntoWasmBoyMemory(1, PixelFifo.numberOfPixelsInFifo, PixelFetcher.tileDataByteOne);
265+
// All BG/Window type pixels
266+
storePixelFifoByteForPixelIndexIntoWasmBoyMemory(2, PixelFifo.numberOfPixelsInFifo, 0);
289267
for (let i = 0; i < 8; i++) {
290-
eightBitStoreIntoGBMemory(PIXEL_PIPELINE_ENTIRE_SCANLINE_FIFO_LOCATION + pixelFifoIndex + 3 + i, PixelFetcher.tileAttributes);
268+
storePixelFifoByteForPixelIndexIntoWasmBoyMemory(3 + i, PixelFifo.numberOfPixelsInFifo + i, PixelFetcher.tileAttributes);
291269
}
292-
PixelPipeline.numberOfPixelsInFifo += 8;
270+
PixelFifo.numberOfPixelsInFifo += 8;
293271
}
294272
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,30 @@
11
// Class responsible for pushing our pixels with their respective palettes
2+
3+
export class PixelFifo {
4+
// Number of CPU cycles for the current step of the fifo
5+
static cycles: i32 = 0;
6+
7+
// Status of the Fetcher
8+
// 0: Idling
9+
// 1: Pushing Pixels
10+
static currentStatus: i32 = 0;
11+
12+
// Number of pixels in our fifo
13+
static numberOfPixelsInFifo: i32 = 0;
14+
15+
// Current index of the pixels we should pop next.
16+
static currentIndex: i32 = 0;
17+
18+
static step() {
19+
// Check if we can continue idling
20+
// Pixel Fifo won't push out pixels unless there are <= 8 pixels in the fifo
21+
let pixelsRemainingInFifo = PixelPipeline.numberOfPixelsInFifo - pixelFifoIndex;
22+
if (PixelFetcher.currentStatus === 0 && pixelsRemainingInFifo <= 8) {
23+
return;
24+
}
25+
26+
// We need to push out a pixel!
27+
28+
// Grab the info for the pixel
29+
}
30+
}

core/graphics/pixelPipeline/pixelPipeline.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,6 @@
22
// https://youtu.be/HyzD8pNlpwI?t=2957
33

44
export class PixelPipeline {
5-
// Number of pixels in our fifo
6-
static numberOfPixelsInFifo: i32 = 0;
7-
8-
// Current index of the pixels we should pop next.
9-
static pixelFifoIndex: i32 = 0;
10-
115
// Function to update/run the pixel pipeline
126
static update(numberOfCycles: i32): void {
137
// NOTE: In the case of scroll,

core/graphics/pixelPipeline/util.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Utility functions involving pixels
2+
import { PIXEL_PIPELINE_ENTIRE_SCANLINE_FIFO_LOCATION } from '../../constants';
3+
import { eightBitLoadFromGBMemory, eightBitStoreIntoGBMemory } from '../../memory/index';
4+
5+
export function getPaletteColorIdForPixelFromTileData(xIndex: i32, tileDataByteZero: i32, tileDataByteOne: i32) {
6+
// Colors are represented by getting X position of ByteTwo, and X positon of Byte One
7+
// To Get the color Id.
8+
// For example, the result of the color id is 0000 00[xPixelByteTwo][xPixelByteOne]
9+
// See: How to draw a tile/sprite from memory: http://www.codeslinger.co.uk/pages/projects/gameboy/graphics.html
10+
let paletteColorId = 0;
11+
if (checkBitOnByte(i, tileDataByteOne)) {
12+
// Byte one represents the second bit in our color id, so bit shift
13+
paletteColorId += 1;
14+
paletteColorId = paletteColorId << 1;
15+
}
16+
if (checkBitOnByte(i, tileDataByteZero)) {
17+
paletteColorId += 1;
18+
}
19+
20+
return paletteColorId;
21+
}
22+
23+
export function loadPixelFifoByteForPixelIndexFromWasmBoyMemory(byteNumber: i32, pixelIndex: i32) {
24+
let pixelFifoPixelIndexLocation = _getLocationOfPixelIndexFromPixelFifoFromWasmBoyMemory(pixelIndex);
25+
return eightBitLoadFromGBMemory(pixelFifoPixelIndexLocation + byteNumber);
26+
}
27+
28+
export function storePixelFifoByteForPixelIndexIntoWasmBoyMemory(byteNumber: i32, pixelIndex: i32, value: i32) {
29+
let pixelFifoPixelIndexLocation = _getLocationOfPixelIndexFromPixelFifoFromWasmBoyMemory(pixelIndex);
30+
return eightBitStoreIntoGBMemory(pixelFifoPixelIndexLocation + byteNumber, value);
31+
}
32+
33+
function _getLocationOfPixelIndexFromPixelFifoFromWasmBoyMemory(pixelIndex: i32) {
34+
// * 11, because Fifo has the 2 data tile bytes (as shown in ultimate gameboy talk),
35+
// and for WasmBoy Specifically:
36+
// A 3rd byte representing the type of pixel (0 = BG/Window, 1 = Sprite)
37+
// Bytes 4-11 represent the attributes for that tile's pixel
38+
let pixelFifoIndex = PixelFifo.numberOfPixelsInFifo * 11;
39+
return PIXEL_PIPELINE_ENTIRE_SCANLINE_FIFO_LOCATION + pixelFifoIndex;
40+
}

0 commit comments

Comments
 (0)