Compare commits
No commits in common. "81c669fe6436cfc75e611901467c9973292723ac" and "02534c5c19bb17adad294052edf708fae8c32f1d" have entirely different histories.
81c669fe64
...
02534c5c19
125
src/ppu.zig
125
src/ppu.zig
|
@ -164,7 +164,7 @@ pub const Ppu = struct {
|
||||||
const x = (sprite.x() +% i) % width;
|
const x = (sprite.x() +% i) % width;
|
||||||
const ix = @bitCast(i9, x);
|
const ix = @bitCast(i9, x);
|
||||||
|
|
||||||
if (!shouldDrawSprite(self.bldcnt, &self.scanline, x)) continue;
|
if (self.scanline.top()[x] != null) continue;
|
||||||
|
|
||||||
const sprite_start = sprite.x();
|
const sprite_start = sprite.x();
|
||||||
const isprite_start = @bitCast(i9, sprite_start);
|
const isprite_start = @bitCast(i9, sprite_start);
|
||||||
|
@ -191,10 +191,7 @@ pub const Ppu = struct {
|
||||||
const pal_id: u16 = if (!is_8bpp) get4bppTilePalette(sprite.palBank(), col, tile) else tile;
|
const pal_id: u16 = if (!is_8bpp) get4bppTilePalette(sprite.palBank(), col, tile) else tile;
|
||||||
|
|
||||||
// Sprite Palette starts at 0x0500_0200
|
// Sprite Palette starts at 0x0500_0200
|
||||||
if (pal_id != 0) {
|
if (pal_id != 0) self.scanline.top()[x] = self.palette.read(u16, 0x200 + pal_id * 2);
|
||||||
const bgr555 = self.palette.read(u16, 0x200 + pal_id * 2);
|
|
||||||
copyToSpriteBuffer(self.bldcnt, &self.scanline, x, bgr555);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,7 +211,15 @@ pub const Ppu = struct {
|
||||||
const x = (sprite.x() +% i) % width;
|
const x = (sprite.x() +% i) % width;
|
||||||
const ix = @bitCast(i9, x);
|
const ix = @bitCast(i9, x);
|
||||||
|
|
||||||
if (!shouldDrawSprite(self.bldcnt, &self.scanline, x)) continue;
|
if (self.scanline.top()[x] != null) continue;
|
||||||
|
|
||||||
|
if (self.scanline.btm()[x] != null) {
|
||||||
|
if (self.bldcnt.mode.read() != 0b01) continue;
|
||||||
|
|
||||||
|
const b_layers = self.bldcnt.layer_b.read();
|
||||||
|
const is_blend_enabled = (b_layers >> 4) & 1 == 1;
|
||||||
|
if (!is_blend_enabled) continue;
|
||||||
|
}
|
||||||
|
|
||||||
const sprite_start = sprite.x();
|
const sprite_start = sprite.x();
|
||||||
const isprite_start = @bitCast(i9, sprite_start);
|
const isprite_start = @bitCast(i9, sprite_start);
|
||||||
|
@ -249,7 +254,19 @@ pub const Ppu = struct {
|
||||||
// Sprite Palette starts at 0x0500_0200
|
// Sprite Palette starts at 0x0500_0200
|
||||||
if (pal_id != 0) {
|
if (pal_id != 0) {
|
||||||
const bgr555 = self.palette.read(u16, 0x200 + pal_id * 2);
|
const bgr555 = self.palette.read(u16, 0x200 + pal_id * 2);
|
||||||
copyToSpriteBuffer(self.bldcnt, &self.scanline, x, bgr555);
|
|
||||||
|
if (self.bldcnt.mode.read() == 0b01) {
|
||||||
|
// Alpha Blending
|
||||||
|
const a_layers = self.bldcnt.layer_a.read();
|
||||||
|
const is_blend_enabled = (a_layers >> 4) & 1 == 1;
|
||||||
|
|
||||||
|
if (is_blend_enabled) {
|
||||||
|
self.scanline.btm()[x] = bgr555;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.scanline.top()[x] = bgr555;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -295,7 +312,7 @@ pub const Ppu = struct {
|
||||||
|
|
||||||
if (pal_id != 0) {
|
if (pal_id != 0) {
|
||||||
const bgr555 = self.palette.read(u16, pal_id * 2);
|
const bgr555 = self.palette.read(u16, pal_id * 2);
|
||||||
copyToBackgroundBuffer(n, self.bldcnt, &self.scanline, i, bgr555);
|
drawToScanlineBuffer(n, self.bldcnt, &self.scanline, i, bgr555);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,7 +369,7 @@ pub const Ppu = struct {
|
||||||
|
|
||||||
if (pal_id != 0) {
|
if (pal_id != 0) {
|
||||||
const bgr555 = self.palette.read(u16, pal_id * 2);
|
const bgr555 = self.palette.read(u16, pal_id * 2);
|
||||||
copyToBackgroundBuffer(n, self.bldcnt, &self.scanline, i, bgr555);
|
drawToScanlineBuffer(n, self.bldcnt, &self.scanline, i, bgr555);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -390,7 +407,8 @@ pub const Ppu = struct {
|
||||||
const maybe_top = maybe_px;
|
const maybe_top = maybe_px;
|
||||||
const maybe_btm = self.scanline.btm()[i];
|
const maybe_btm = self.scanline.btm()[i];
|
||||||
|
|
||||||
const bgr555 = self.getBgr555(maybe_top, maybe_btm);
|
// TODO: Why must I reverse this?
|
||||||
|
const bgr555 = getBgr555(&self.palette, self.bldalpha, maybe_btm, maybe_top);
|
||||||
std.mem.writeIntNative(u32, self.framebuf.get(.Emulator)[fb_base + i * @sizeOf(u32) ..][0..@sizeOf(u32)], COLOUR_LUT[bgr555 & 0x7FFF]);
|
std.mem.writeIntNative(u32, self.framebuf.get(.Emulator)[fb_base + i * @sizeOf(u32) ..][0..@sizeOf(u32)], COLOUR_LUT[bgr555 & 0x7FFF]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -417,7 +435,8 @@ pub const Ppu = struct {
|
||||||
const maybe_top = maybe_px;
|
const maybe_top = maybe_px;
|
||||||
const maybe_btm = self.scanline.btm()[i];
|
const maybe_btm = self.scanline.btm()[i];
|
||||||
|
|
||||||
const bgr555 = self.getBgr555(maybe_top, maybe_btm);
|
// TODO: Why must I reverse this?
|
||||||
|
const bgr555 = getBgr555(&self.palette, self.bldalpha, maybe_btm, maybe_top);
|
||||||
std.mem.writeIntNative(u32, self.framebuf.get(.Emulator)[fb_base + i * @sizeOf(u32) ..][0..@sizeOf(u32)], COLOUR_LUT[bgr555 & 0x7FFF]);
|
std.mem.writeIntNative(u32, self.framebuf.get(.Emulator)[fb_base + i * @sizeOf(u32) ..][0..@sizeOf(u32)], COLOUR_LUT[bgr555 & 0x7FFF]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,7 +462,8 @@ pub const Ppu = struct {
|
||||||
const maybe_top = maybe_px;
|
const maybe_top = maybe_px;
|
||||||
const maybe_btm = self.scanline.btm()[i];
|
const maybe_btm = self.scanline.btm()[i];
|
||||||
|
|
||||||
const bgr555 = self.getBgr555(maybe_top, maybe_btm);
|
// TODO: Why must I reverse this?
|
||||||
|
const bgr555 = getBgr555(&self.palette, self.bldalpha, maybe_btm, maybe_top);
|
||||||
std.mem.writeIntNative(u32, self.framebuf.get(.Emulator)[fb_base + i * @sizeOf(u32) ..][0..@sizeOf(u32)], COLOUR_LUT[bgr555 & 0x7FFF]);
|
std.mem.writeIntNative(u32, self.framebuf.get(.Emulator)[fb_base + i * @sizeOf(u32) ..][0..@sizeOf(u32)], COLOUR_LUT[bgr555 & 0x7FFF]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,44 +514,6 @@ pub const Ppu = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getBgr555(self: *Self, maybe_top: ?u16, maybe_btm: ?u16) u16 {
|
|
||||||
if (maybe_btm) |btm| {
|
|
||||||
return switch (self.bldcnt.mode.read()) {
|
|
||||||
0b00 => if (maybe_top) |top| top else btm,
|
|
||||||
0b01 => if (maybe_top) |top| alphaBlend(btm, top, self.bldalpha) else btm,
|
|
||||||
0b10 => blk: {
|
|
||||||
const evy: u16 = self.bldy.evy.read();
|
|
||||||
|
|
||||||
const r = btm & 0x1F;
|
|
||||||
const g = (btm >> 5) & 0x1F;
|
|
||||||
const b = (btm >> 10) & 0x1F;
|
|
||||||
|
|
||||||
const bld_r = r + (((31 - r) * evy) >> 4);
|
|
||||||
const bld_g = g + (((31 - g) * evy) >> 4);
|
|
||||||
const bld_b = b + (((31 - b) * evy) >> 4);
|
|
||||||
|
|
||||||
break :blk (bld_b << 10) | (bld_g << 5) | bld_r;
|
|
||||||
},
|
|
||||||
0b11 => blk: {
|
|
||||||
const evy: u16 = self.bldy.evy.read();
|
|
||||||
|
|
||||||
const btm_r = btm & 0x1F;
|
|
||||||
const btm_g = (btm >> 5) & 0x1F;
|
|
||||||
const btm_b = (btm >> 10) & 0x1F;
|
|
||||||
|
|
||||||
const bld_r = btm_r - ((btm_r * evy) >> 4);
|
|
||||||
const bld_g = btm_g - ((btm_g * evy) >> 4);
|
|
||||||
const bld_b = btm_b - ((btm_b * evy) >> 4);
|
|
||||||
|
|
||||||
break :blk (bld_b << 10) | (bld_g << 5) | bld_r;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (maybe_top) |top| return top;
|
|
||||||
return self.palette.getBackdrop();
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Comment this + get a better understanding
|
// TODO: Comment this + get a better understanding
|
||||||
fn tilemapOffset(size: u2, x: u32, y: u32) u32 {
|
fn tilemapOffset(size: u2, x: u32, y: u32) u32 {
|
||||||
// Current Row: (y % PIXEL_COUNT) / 8
|
// Current Row: (y % PIXEL_COUNT) / 8
|
||||||
|
@ -1068,6 +1050,16 @@ fn toRgba8888Talarubi(bgr555: u16) u32 {
|
||||||
return @floatToInt(u32, out_r) << 24 | @floatToInt(u32, out_g) << 16 | @floatToInt(u32, out_b) << 8 | 0xFF;
|
return @floatToInt(u32, out_r) << 24 | @floatToInt(u32, out_g) << 16 | @floatToInt(u32, out_b) << 8 | 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn getBgr555(palette: *const Palette, bldalpha: io.BldAlpha, maybe_top: ?u16, maybe_btm: ?u16) u16 {
|
||||||
|
if (maybe_top) |top| {
|
||||||
|
if (maybe_btm) |btm| return alphaBlend(top, btm, bldalpha);
|
||||||
|
return top;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maybe_btm) |btm| return btm;
|
||||||
|
return palette.getBackdrop();
|
||||||
|
}
|
||||||
|
|
||||||
fn alphaBlend(top: u16, btm: u16, bldalpha: io.BldAlpha) u16 {
|
fn alphaBlend(top: u16, btm: u16, bldalpha: io.BldAlpha) u16 {
|
||||||
const eva: u16 = bldalpha.eva.read();
|
const eva: u16 = bldalpha.eva.read();
|
||||||
const evb: u16 = bldalpha.evb.read();
|
const evb: u16 = bldalpha.evb.read();
|
||||||
|
@ -1118,22 +1110,8 @@ fn shouldDrawBackground(comptime n: u2, bldcnt: io.BldCnt, scanline: *Scanline,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shouldDrawSprite(bldcnt: io.BldCnt, scanline: *Scanline, x: u9) bool {
|
fn drawToScanlineBuffer(comptime n: u2, bldcnt: io.BldCnt, scanline: *Scanline, i: usize, bgr555: u16) void {
|
||||||
if (scanline.top()[x] != null) return false;
|
if (bldcnt.mode.read() == 0b01) {
|
||||||
|
|
||||||
if (scanline.btm()[x] != null) {
|
|
||||||
if (bldcnt.mode.read() != 0b01) return false;
|
|
||||||
|
|
||||||
const b_layers = bldcnt.layer_b.read();
|
|
||||||
const is_blend_enabled = (b_layers >> 4) & 1 == 1;
|
|
||||||
if (!is_blend_enabled) return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn copyToBackgroundBuffer(comptime n: u2, bldcnt: io.BldCnt, scanline: *Scanline, i: usize, bgr555: u16) void {
|
|
||||||
if (bldcnt.mode.read() != 0b00) {
|
|
||||||
// Standard Alpha Blending
|
// Standard Alpha Blending
|
||||||
const a_layers = bldcnt.layer_a.read();
|
const a_layers = bldcnt.layer_a.read();
|
||||||
const is_blend_enabled = (a_layers >> n) & 1 == 1;
|
const is_blend_enabled = (a_layers >> n) & 1 == 1;
|
||||||
|
@ -1149,21 +1127,6 @@ fn copyToBackgroundBuffer(comptime n: u2, bldcnt: io.BldCnt, scanline: *Scanline
|
||||||
scanline.top()[i] = bgr555;
|
scanline.top()[i] = bgr555;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn copyToSpriteBuffer(bldcnt: io.BldCnt, scanline: *Scanline, x: u9, bgr555: u16) void {
|
|
||||||
if (bldcnt.mode.read() != 0b00) {
|
|
||||||
// Alpha Blending
|
|
||||||
const a_layers = bldcnt.layer_a.read();
|
|
||||||
const is_blend_enabled = (a_layers >> 4) & 1 == 1;
|
|
||||||
|
|
||||||
if (is_blend_enabled) {
|
|
||||||
scanline.btm()[x] = bgr555;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scanline.top()[x] = bgr555;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Scanline = struct {
|
const Scanline = struct {
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue