📄 nesppu.pas
字号:
begin
//aOffset:=i*4;
Attr := SprRam[i + 2];
if (Attr and $20) = 0 then
begin
x := SprRam[i + 3];
y := SprRam[i];
TileNo := SprRam[i + 1];
DrawASprite(TileNo, x, y, Attr);
CopyBmpT(FSCanvas,x,y+1,SprCanvas,ppu_mem[$3f10]);
{ if TileNo=$1e then begin
SprCanvas.SaveToFile('d:\1e.bmp');
FSCanvas.SaveToFile('d:\1e1.bmp');
end; }
end;
dec(i, 4);
// FSCanvas.SaveToFile('d:\1e1.bmp');
end;
end;
procedure TPPU.Reset;
begin
ZeroMemory(@ppu_mem, $10000);
ZeroMemory(@SprRam, 256);
ZeroMemory(@registers,32);
end;
procedure TPPU.DrawASprite(Tiles, x, y, Attr: Byte);
var
ptAddr: Word;
i: integer;
b0, b1: byte;
P: PByteArray;
H16:Boolean;
begin
if (registers[0] and $20) = 0 then
begin //8x8 piexls
if (registers[0] and $8) = $8 then
ptAddr := $1000
else ptAddr := 0;
H16:=False;
SprCanvas.Height:=8;
end else //8x16 piexls
begin
if (Tiles mod 2)=0 then
//if (registers[0] and 1) = 0 then
ptAddr := 0
else begin
ptAddr := $1000;
Dec(Tiles);
end;
H16:=true;
SprCanvas.Height:=16;
end;
i := 0;
case (attr shr 6) of
0: begin
while i < 8 do
begin
b0 := ppu_mem[ptAddr + tiles * 16 + i];
b1 := ppu_mem[ptAddr + tiles * 16 + i + 8];
RenderSpritePixels(b0, b1, attr, i);
p := SprCanvas.ScanLine[i];
CopyMemory(p, @Line8, 8);
if H16 then begin
//----8x16 sprite;
b0 := ppu_mem[ptAddr + (tiles + 1)*16 + i];
b1 := ppu_mem[ptAddr + (tiles + 1)*16 + i + 8];
RenderSpritePixels(b0, b1, attr, i);
p := SprCanvas.ScanLine[i+8];
CopyMemory(p, @Line8, 8);
end;
Inc(i);
end;
end;
1: begin //horizontal flip
while i < 8 do
begin
b0 := ppu_mem[ptAddr + tiles * 16 + i];
b1 := ppu_mem[ptAddr + tiles * 16 + i + 8];
RenderSpritePixelsHF(b0, b1, attr, i);
p := SprCanvas.ScanLine[i];
CopyMemory(p, @Line8, 8);
if H16 then begin
//----8x16 sprite;
b0 := ppu_mem[ptAddr + (tiles + 1)*16 + i];
b1 := ppu_mem[ptAddr + (tiles + 1)*16 + i + 8];
RenderSpritePixelsHF(b0, b1, attr, i);
p := SprCanvas.ScanLine[i+8];
CopyMemory(p, @Line8, 8);
end;
Inc(i);
end;
end;
2: begin //vertical flip
while i < 8 do
begin
b0 := ppu_mem[ptAddr + tiles * 16 + 7 - i];
b1 := ppu_mem[ptAddr + tiles * 16 + 15 - i];
RenderSpritePixels(b0, b1, attr, i);
p := SprCanvas.ScanLine[i];
CopyMemory(p, @Line8, 8);
if H16 then begin
//----8x16 sprite;
b0 := ppu_mem[ptAddr + (tiles + 1)*16 + 7 -i];
b1 := ppu_mem[ptAddr + (tiles + 1)*16 + 15 - i ];
RenderSpritePixels(b0, b1, attr, i);
p := SprCanvas.ScanLine[i+8];
CopyMemory(p, @Line8, 8);
end;
Inc(i);
end
end;
3: begin // horizontal and vertical flip
while i < 8 do
begin
b0 := ppu_mem[ptAddr + tiles * 16 + 7 - i];
b1 := ppu_mem[ptAddr + tiles * 16 + 15 - i];
RenderSpritePixelshf(b0, b1, attr, i);
p := SprCanvas.ScanLine[i];
CopyMemory(p, @Line8, 8);
if H16 then begin
//----8x16 sprite;
b0 := ppu_mem[ptAddr + (tiles + 1)*16 + 7 - i];
b1 := ppu_mem[ptAddr + (tiles + 1)*16 + 15 - i];
RenderSpritePixels(b0, b1, attr, i);
p := SprCanvas.ScanLine[i+8];
CopyMemory(p, @Line8, 8);
end;
Inc(i);
end
end;
end;
end;
procedure TPPU.RenderSpritePixels(b0, b1, attr: Byte; i: integer);
var
bit00, bit01, bit02, bit03, bit04, bit05, bit06, bit07,
bit10, bit11, bit12, bit13, bit14, bit15, bit16, bit17,
low2, Upper2, color_offset, color, at: byte;
begin
bit00 := b0 and $1;
bit01 := b0 and $2;
bit02 := b0 and $4;
bit03 := b0 and $8;
bit04 := b0 and $10;
bit05 := b0 and $20;
bit06 := b0 and $40;
bit07 := b0 and $80;
bit10 := b1 and $1;
bit11 := b1 and $2;
bit12 := b1 and $4;
bit13 := b1 and $8;
bit14 := b1 and $10;
bit15 := b1 and $20;
bit16 := b1 and $40;
bit17 := b1 and $80;
upper2 := (Attr and 3) shl 2;
//0
low2 := (bit10 shl 1) or bit00;
color_offset := low2 or upper2;
color := ppu_mem[pal[1] + color_offset];
Line8[7] := color and $3F; //2006.2.9 modifed
//1
low2 := bit11 or (bit01 shr 1);
color_offset := low2 or upper2;
color := ppu_mem[pal[1] + color_offset];
Line8[6] := color and $3F; //2006.2.9 modifed
//2
low2 := (bit12 shr 1) or (bit02 shr 2);
color_offset := low2 or upper2;
color := ppu_mem[pal[1] + color_offset];
Line8[5] := color and $3F; //2006.2.9 modifed
//3
low2 := (bit13 shr 2) or (bit03 shr 3);
color_offset := low2 or upper2;
color := ppu_mem[pal[1] + color_offset];
Line8[4] := color and $3F; //2006.2.9 modifed
//4
low2 := (bit14 shr 3) or (bit04 shr 4);
color_offset := low2 or upper2;
color := ppu_mem[pal[1] + color_offset];
Line8[3] := color and $3F; //2006.2.9 modifed
//5
low2 := (bit15 shr 4) or (bit05 shr 5);
color_offset := low2 or upper2;
color := ppu_mem[pal[1] + color_offset];
Line8[2] := color and $3F; //2006.2.9 modifed
//6
low2 := (bit16 shr 5) or (bit06 shr 6);
color_offset := low2 or upper2;
color := ppu_mem[pal[1] + color_offset];
Line8[1] := color and $3F; //2006.2.9 modifed
//7
low2 := (bit17 shr 6) or (bit07 shr 7);
color_offset := low2 or upper2;
color := ppu_mem[pal[1] + color_offset];
Line8[0] := color and $3F; //2006.2.9 modifed
end;
procedure TPPU.RenderSpritePixelsHF(b0, b1, attr: Byte; i: Integer);
var
bit00, bit01, bit02, bit03, bit04, bit05, bit06, bit07,
bit10, bit11, bit12, bit13, bit14, bit15, bit16, bit17,
low2, Upper2, color_offset, color, at: byte;
begin
bit00 := b0 and $1;
bit01 := b0 and $2;
bit02 := b0 and $4;
bit03 := b0 and $8;
bit04 := b0 and $10;
bit05 := b0 and $20;
bit06 := b0 and $40;
bit07 := b0 and $80;
bit10 := b1 and $1;
bit11 := b1 and $2;
bit12 := b1 and $4;
bit13 := b1 and $8;
bit14 := b1 and $10;
bit15 := b1 and $20;
bit16 := b1 and $40;
bit17 := b1 and $80;
upper2 := (Attr and 3) shl 2;
//0
low2 := (bit10 shl 1) or bit00;
color_offset := low2 or upper2;
color := ppu_mem[pal[1] + color_offset];
Line8[0] := color and $3F; //2006.2.9 modifed
//1
low2 := bit11 or (bit01 shr 1);
color_offset := low2 or upper2;
color := ppu_mem[pal[1] + color_offset];
Line8[1] := color and $3F; //2006.2.9 modifed
//2
low2 := (bit12 shr 1) or (bit02 shr 2);
color_offset := low2 or upper2;
color := ppu_mem[pal[1] + color_offset];
Line8[2] := color and $3F; //2006.2.9 modifed
//3
low2 := (bit13 shr 2) or (bit03 shr 3);
color_offset := low2 or upper2;
color := ppu_mem[pal[1] + color_offset];
Line8[3] := color and $3F; //2006.2.9 modifed
//4
low2 := (bit14 shr 3) or (bit04 shr 4);
color_offset := low2 or upper2;
color := ppu_mem[pal[1] + color_offset];
Line8[4] := color and $3F; //2006.2.9 modifed
//5
low2 := (bit15 shr 4) or (bit05 shr 5);
color_offset := low2 or upper2;
color := ppu_mem[pal[1] + color_offset];
Line8[5] := color and $3F; //2006.2.9 modifed
//6
low2 := (bit16 shr 5) or (bit06 shr 6);
color_offset := low2 or upper2;
color := ppu_mem[pal[1] + color_offset];
Line8[6] := color and $3F; //2006.2.9 modifed
//7
low2 := (bit17 shr 6) or (bit07 shr 7);
color_offset := low2 or upper2;
color := ppu_mem[pal[1] + color_offset];
Line8[7] := color and $3F; //2006.2.9 modifed
end;
destructor TPPU.destory;
begin
BGCanvas.Free;
BSCanvas.Free;
FSCanvas.Free;
SprCanvas.Free;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -