1
1
// Fetcher for the pixel pipeline
2
2
// https://youtu.be/HyzD8pNlpwI?t=2957
3
- import { PIXEL_PIPELINE_ENTIRE_SCANLINE_FIFO_LOCATION } from '../../constants' ;
4
3
import { checkBitOnByte , setBitOnByte , resetBitOnByte } from '../../helpers/index' ;
4
+ import { eightBitLoadFromGBMemory , eightBitStoreIntoGBMemory } from '../../memory/index' ;
5
5
import { Lcd } from '../lcd' ;
6
6
import { getTileDataAddress } from '../tiles' ;
7
7
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' ;
9
14
10
15
export class PixelFetcher {
11
16
// Number of CPU cycles for the current step of the fetch
@@ -36,7 +41,7 @@ export class PixelFetcher {
36
41
static tileDataByteOne : i32 = 0 ;
37
42
static tileAttributes : i32 = 0 ;
38
43
39
- static startFetch ( tileMapLocation : i32 , tileLine : i32 , isSprite : boolean , spriteArrtributeIndex : i32 ) : void {
44
+ static startFetch ( tileMapLocation : i32 , tileLine : i32 , isSprite : boolean , spriteAttributeIndex : i32 ) : void {
40
45
// Reset the fetcher
41
46
PixelFetcher . currentStatus = 0 ;
42
47
PixelFetcher . cycles = 0 ;
@@ -47,16 +52,16 @@ export class PixelFetcher {
47
52
PixelFetcher . spriteAttributeIndex = spriteAttributeIndex ;
48
53
}
49
54
50
- static update ( numberOfCycles : i32 ) {
55
+ static step ( ) {
51
56
// Check if we can continue idling
52
57
// 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 ;
54
59
if ( PixelFetcher . currentStatus === 0 && pixelsRemainingInFifo > 8 ) {
55
60
return ;
56
61
}
57
62
58
- // Update our cycles
59
- PixelFetcher . cycles += numberOfCycles ;
63
+ // Update our cycles (Each step should be 4 CPU Cycles)
64
+ PixelFetcher . cycles += 4 ;
60
65
61
66
// Update our current status / Execute the step
62
67
let cyclesPerStep = 8 << ( < i32 > Cpu . GBCDoubleSpeed ) ;
@@ -112,7 +117,7 @@ function _readTileData(byteNumber: i32): i32 {
112
117
let tileAttributes : i32 = 0 ;
113
118
if ( PixelFetcher . isSprite ) {
114
119
// Get our sprite attributes
115
- let spriteTableIndex = i * 4 ;
120
+ let spriteTableIndex = PixelFetcher . spriteAttributeIndex * 4 ;
116
121
let spriteMemoryLocation = Graphics . memoryLocationSpriteAttributesTable + spriteTableIndex ;
117
122
118
123
// Pan docs of sprite attribute table (Byte 3 of Sprite Table Entry)
@@ -191,12 +196,10 @@ function _storeFetchIntoFifo(): void {
191
196
if ( PixelFetcher . isSprite ) {
192
197
// Need to mix the pixel on top of the old data
193
198
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 ) ;
200
203
201
204
// Go one by one for the 8 pixels in the current fifo
202
205
for ( let i = 0 ; i < 8 ; i ++ ) {
@@ -206,41 +209,19 @@ function _storeFetchIntoFifo(): void {
206
209
}
207
210
208
211
// 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 ) ;
222
213
223
214
// Palette ColorId zero (last two bits of pallette) of a sprite are always transparent
224
215
// http://gbdev.gg8.se/wiki/articles/Video_Display
225
216
if ( spriteColorId !== 0 ) {
226
217
continue ;
227
218
}
228
219
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 ) ;
233
222
234
223
// 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 ) ;
244
225
245
226
// NOTE:
246
227
// We are trying to draw a sprite pixel over a BG/Window pixel.
@@ -271,24 +252,21 @@ function _storeFetchIntoFifo(): void {
271
252
setBitOnByte ( i , typePerPixel ) ;
272
253
273
254
// 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 ) ;
278
259
}
279
260
}
280
261
} else {
281
262
// 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 ) ;
289
267
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 ) ;
291
269
}
292
- PixelPipeline . numberOfPixelsInFifo += 8 ;
270
+ PixelFifo . numberOfPixelsInFifo += 8 ;
293
271
}
294
272
}
0 commit comments