New PPU, comments.
This commit is contained in:
parent
f745c83b1c
commit
3e3fcce6f4
7 changed files with 255 additions and 87 deletions
|
@ -1 +0,0 @@
|
||||||
-std=c++11
|
|
|
@ -5,8 +5,8 @@ namespace Cartridge {
|
||||||
|
|
||||||
|
|
||||||
int banksMap[8]; // Map virtual memory to ROM.
|
int banksMap[8]; // Map virtual memory to ROM.
|
||||||
u8* rom;
|
u8* rom; // ROM data.
|
||||||
u8* vRam;
|
u8* vRam; // VRAM/VROM data.
|
||||||
|
|
||||||
/* PRG-ROM access */
|
/* PRG-ROM access */
|
||||||
template <bool wr> u8 access(u16 addr, u8 v)
|
template <bool wr> u8 access(u16 addr, u8 v)
|
||||||
|
@ -19,7 +19,7 @@ template u8 access<0>(u16, u8); template u8 access<1>(u16, u8);
|
||||||
/* CHR-ROM/RAM access */
|
/* CHR-ROM/RAM access */
|
||||||
template <bool wr> u8 chr_access(u16 addr, u8 v)
|
template <bool wr> u8 chr_access(u16 addr, u8 v)
|
||||||
{
|
{
|
||||||
return vRam[addr];
|
return vRam[addr]; // TODO: support CHR-RAM.
|
||||||
}
|
}
|
||||||
template u8 chr_access<0>(u16, u8); template u8 chr_access<1>(u16, u8);
|
template u8 chr_access<0>(u16, u8); template u8 chr_access<1>(u16, u8);
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ void load(const char* fname)
|
||||||
|
|
||||||
// Read PRG-ROM and CHR-ROM:
|
// Read PRG-ROM and CHR-ROM:
|
||||||
rom = new u8[0x4000 * prgRom_16k];
|
rom = new u8[0x4000 * prgRom_16k];
|
||||||
vRam = new u8[0x2000 * chrRom_8k];
|
vRam = new u8[0x2000 * chrRom_8k]; // TODO: CHR-RAM.
|
||||||
fread( rom, 0x4000, prgRom_16k, f);
|
fread( rom, 0x4000, prgRom_16k, f);
|
||||||
fread(vRam, 0x2000, chrRom_8k , f);
|
fread(vRam, 0x2000, chrRom_8k , f);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include "cartridge.hpp"
|
#include "cartridge.hpp"
|
||||||
|
#include "ppu.hpp"
|
||||||
#include "cpu.hpp"
|
#include "cpu.hpp"
|
||||||
|
|
||||||
namespace CPU {
|
namespace CPU {
|
||||||
|
@ -14,7 +15,7 @@ Flags P;
|
||||||
|
|
||||||
/* Cycle emulation */
|
/* Cycle emulation */
|
||||||
#define T tick()
|
#define T tick()
|
||||||
inline void tick() { return; }
|
inline void tick() { PPU::step(); PPU::step(); PPU::step(); }
|
||||||
|
|
||||||
/* Flags updating */
|
/* Flags updating */
|
||||||
inline void upd_cv(u8 x, u8 y, s16 r) { P.c = (r>0xFF); P.v = ~(x^y) & (x^r) & 0x80; }
|
inline void upd_cv(u8 x, u8 y, s16 r) { P.c = (r>0xFF); P.v = ~(x^y) & (x^r) & 0x80; }
|
||||||
|
@ -27,6 +28,7 @@ template <bool wr> inline u8 access(u16 addr, u8 v = 0)
|
||||||
{
|
{
|
||||||
T; u8* r;
|
T; u8* r;
|
||||||
if (addr < 0x2000) { r = &RAM[addr % 0x800]; if (wr) *r = v; return *r; } // RAM.
|
if (addr < 0x2000) { r = &RAM[addr % 0x800]; if (wr) *r = v; return *r; } // RAM.
|
||||||
|
else if (addr < 0x4000) { return PPU::access<wr>(addr % 8, v); } // PPU.
|
||||||
else if (addr < 0x8000) { return 0; }
|
else if (addr < 0x8000) { return 0; }
|
||||||
else { return Cartridge::access<wr>(addr, v); } // ROM.
|
else { return Cartridge::access<wr>(addr, v); } // ROM.
|
||||||
}
|
}
|
||||||
|
|
12
src/cpu.hpp
12
src/cpu.hpp
|
@ -11,14 +11,14 @@ union Flags
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
bool c : 1;
|
bool c : 1; // Carry.
|
||||||
bool z : 1;
|
bool z : 1; // Zero.
|
||||||
bool i : 1;
|
bool i : 1; // Interrupt priority.
|
||||||
bool d : 1;
|
bool d : 1; // Decimal (useless).
|
||||||
bool b : 1;
|
bool b : 1;
|
||||||
bool unused : 1;
|
bool unused : 1;
|
||||||
bool v : 1;
|
bool v : 1; // Overflow.
|
||||||
bool n : 1;
|
bool n : 1; // Negative.
|
||||||
};
|
};
|
||||||
u8 reg;
|
u8 reg;
|
||||||
|
|
||||||
|
|
188
src/ppu.cpp
188
src/ppu.cpp
|
@ -4,68 +4,81 @@
|
||||||
namespace PPU {
|
namespace PPU {
|
||||||
|
|
||||||
|
|
||||||
u8 ciRam[0x800];
|
u8 ciRam[0x800]; // VRAM for nametables.
|
||||||
u8 palette[0x20];
|
u8 palette[0x20]; // VRAM for palettes.
|
||||||
u8 oam[0x100];
|
u8 oam[0x100]; // VRAM for sprites.
|
||||||
|
|
||||||
Addr vAddr, tAddr;
|
Addr vAddr, tAddr; // Loopy V, T.
|
||||||
u8 fX;
|
u8 fX; // Fine X.
|
||||||
u8 oamAddr;
|
u8 oamAddr; // OAM address.
|
||||||
Ctrl ctrl;
|
|
||||||
Mask mask;
|
|
||||||
Status status;
|
|
||||||
|
|
||||||
static u8 rd(u16 addr)
|
Ctrl ctrl; // PPUCTRL ($2000) register.
|
||||||
|
Mask mask; // PPUMASK ($2001) register.
|
||||||
|
Status status; // PPUSTATUS ($2002) register.
|
||||||
|
|
||||||
|
// Background latches:
|
||||||
|
u8 nt, at, bgL, bgH;
|
||||||
|
// Background shift registers:
|
||||||
|
u8 atShift; u16 bgShiftL, bgShiftH;
|
||||||
|
|
||||||
|
// Rendering counters:
|
||||||
|
int scanline, cycle;
|
||||||
|
bool frameOdd;
|
||||||
|
|
||||||
|
/* Access PPU memory */
|
||||||
|
template <bool wr> u8 mem_access(u16 addr, u8 v = 0)
|
||||||
{
|
{
|
||||||
if (addr < 0x2000) return Cartridge::chr_access<0>(addr);
|
u8* ref;
|
||||||
else if (addr < 0x2800) return ciRam[addr - 0x2000];
|
|
||||||
else if (addr < 0x3000) return 0x00;
|
|
||||||
else if (addr < 0x3F00) return ciRam[addr - 0x3000];
|
|
||||||
else return palette[addr % 0x20];
|
|
||||||
}
|
|
||||||
|
|
||||||
static u8 wr(u16 addr, u8 v)
|
if (addr < 0x2000) return Cartridge::chr_access<wr>(addr, v); // CHR-ROM/RAM.
|
||||||
{
|
else if (addr < 0x2800) ref = &ciRam[addr - 0x2000]; // Nametables.
|
||||||
if (addr < 0x2000) return Cartridge::chr_access<1>(addr, v);
|
|
||||||
else if (addr < 0x2800) return ciRam[addr - 0x2000] = v;
|
|
||||||
else if (addr < 0x3000) return 0x00;
|
else if (addr < 0x3000) return 0x00;
|
||||||
else if (addr < 0x3F00) return ciRam[addr - 0x3000] = v;
|
else if (addr < 0x3F00) ref = &ciRam[addr - 0x3000]; // Nametables (mirror).
|
||||||
else return palette[addr % 0x20] = v;
|
else ref = &palette[addr % 0x20]; // Palettes.
|
||||||
}
|
|
||||||
|
|
||||||
|
if (wr) return *ref = v;
|
||||||
|
else return *ref;
|
||||||
|
}
|
||||||
|
inline u8 rd(u16 addr) { return mem_access<0>(addr); }
|
||||||
|
inline u8 wr(u16 addr, u8 v) { return mem_access<1>(addr, v); }
|
||||||
|
|
||||||
|
/* Access PPU through registers. */
|
||||||
template <bool write> u8 access(u16 index, u8 v)
|
template <bool write> u8 access(u16 index, u8 v)
|
||||||
{
|
{
|
||||||
static u8 res, buffer;
|
static u8 res; // Result of the operation.
|
||||||
static bool latch;
|
static u8 buffer; // VRAM read buffer.
|
||||||
|
static bool latch; // Detect second reading.
|
||||||
|
|
||||||
|
/* Write into register */
|
||||||
if (write)
|
if (write)
|
||||||
{
|
{
|
||||||
res = v;
|
res = v;
|
||||||
|
|
||||||
switch (index)
|
switch (index)
|
||||||
{
|
{
|
||||||
case 0: ctrl.r = v; tAddr.nt = ctrl.nt; break;
|
case 0: ctrl.r = v; tAddr.nt = ctrl.nt; break; // PPUCTRL ($2000).
|
||||||
case 1: mask.r = v; break;
|
case 1: mask.r = v; break; // PPUMASK ($2001).
|
||||||
case 3: oamAddr = v; break;
|
case 3: oamAddr = v; break; // OAMADDR ($2003).
|
||||||
case 4: oam[oamAddr++] = v; break;
|
case 4: oam[oamAddr++] = v; break; // OAMDATA ($2004).
|
||||||
case 5:
|
case 5: // PPUSCROLL ($2005).
|
||||||
if (!latch) { fX = v & 7; tAddr.cX = v >> 3; }
|
if (!latch) { fX = v & 7; tAddr.cX = v >> 3; } // First write.
|
||||||
else { tAddr.fY = v & 7; tAddr.cY = v & 0x1F; }
|
else { tAddr.fY = v & 7; tAddr.cY = v & 0x1F; } // Second write.
|
||||||
latch = !latch;
|
latch = !latch;
|
||||||
case 6:
|
case 6: // PPUADDR ($2006).
|
||||||
if (!latch) { tAddr.h = v & 0x3F; }
|
if (!latch) { tAddr.h = v & 0x3F; } // First write.
|
||||||
else { tAddr.l = v; vAddr.r = tAddr.r; }
|
else { tAddr.l = v; vAddr.r = tAddr.r; } // Second write.
|
||||||
latch = !latch;
|
latch = !latch;
|
||||||
case 7: wr(vAddr.addr, v); vAddr.addr += ctrl.incr; break;
|
case 7: wr(vAddr.addr, v); vAddr.addr += ctrl.incr ? 32 : 1; // PPUDATA ($2007).
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* Read from register */
|
||||||
else
|
else
|
||||||
switch (index)
|
switch (index)
|
||||||
{
|
{
|
||||||
|
// PPUSTATUS ($2002):
|
||||||
case 2: res = (res & 0x1F) | status.r; status.vBlank = 0; latch = 0; break;
|
case 2: res = (res & 0x1F) | status.r; status.vBlank = 0; latch = 0; break;
|
||||||
case 4: res = oam[oamAddr]; break;
|
case 4: res = oam[oamAddr]; break; // OAMDATA ($2004).
|
||||||
case 7:
|
case 7: // PPUDATA ($2007).
|
||||||
if (vAddr.addr <= 0x3EFF)
|
if (vAddr.addr <= 0x3EFF)
|
||||||
{
|
{
|
||||||
res = buffer;
|
res = buffer;
|
||||||
|
@ -73,13 +86,104 @@ template <bool write> u8 access(u16 index, u8 v)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
res = buffer = rd(vAddr.addr);
|
res = buffer = rd(vAddr.addr);
|
||||||
vAddr.addr += ctrl.incr;
|
vAddr.addr += ctrl.incr ? 32 : 1;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
template u8 access<0>(u16, u8); template u8 access<1>(u16, u8);
|
template u8 access<0>(u16, u8); template u8 access<1>(u16, u8);
|
||||||
|
|
||||||
|
/* Calculate graphics addresses */
|
||||||
|
inline u16 nt_addr() { return 0x2000 | (vAddr.addr); }
|
||||||
|
inline u16 at_addr() { return 0x23C0 | (vAddr.nt << 10) | ((vAddr.cY / 4) << 3) | (vAddr.cX / 4); }
|
||||||
|
inline u16 bg_addr() { return (ctrl.bgTbl * 0x1000) + (nt * 16) + vAddr.fY; }
|
||||||
|
/* Increment the scroll by one pixel */
|
||||||
|
inline void h_scroll() { if (vAddr.cX == 31) vAddr.r ^= 0x41F; else vAddr.cX++; }
|
||||||
|
inline void v_scroll()
|
||||||
|
{
|
||||||
|
if (vAddr.fY < 7) vAddr.fY++;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vAddr.fY = 0;
|
||||||
|
if (vAddr.cY == 31) vAddr.cY = 0;
|
||||||
|
else if (vAddr.cY == 29) { vAddr.cY = 0; vAddr.nt ^= 0b10; }
|
||||||
|
else vAddr.cY++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Copy scrolling data from loopy T to loopy V */
|
||||||
|
inline void h_update() { vAddr.r = (vAddr.r & ~0x041F) | (tAddr.r & 0x041F); }
|
||||||
|
inline void v_update() { vAddr.r = (vAddr.r & ~0x7BE0) | (tAddr.r & 0x7BE0); }
|
||||||
|
// Put new data into the shift registers:
|
||||||
|
inline void reload_shift()
|
||||||
|
{
|
||||||
|
bgShiftL = (bgShiftL & 0xFF00) | bgL;
|
||||||
|
bgShiftH = (bgShiftH & 0xFF00) | bgH;
|
||||||
|
atShift = (atShift << 2) | (at & 0b11);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pixel()
|
||||||
|
{
|
||||||
|
u8 px = ((atShift << 2) & 3) | ((bgShiftH << 1) & 1) | (bgShiftL & 1);
|
||||||
|
|
||||||
|
bgShiftL <<= 1;
|
||||||
|
bgShiftH <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Execute a cycle of a scanline (prerender or visible) */
|
||||||
|
template <bool pre> void scanline_()
|
||||||
|
{
|
||||||
|
static u16 addr;
|
||||||
|
|
||||||
|
switch (cycle)
|
||||||
|
{
|
||||||
|
// Nametable fetching:
|
||||||
|
TILE_PHASE_1: if (pre) status.vBlank = false; // Disable VBlank in prerender.
|
||||||
|
addr = nt_addr(); break;
|
||||||
|
TILE_PHASE_2: nt = rd(addr); break;
|
||||||
|
// Attribute fetching:
|
||||||
|
TILE_PHASE_3: addr = at_addr(); break;
|
||||||
|
TILE_PHASE_4: at = rd(addr); if (vAddr.cY & 2) at >>= 4;
|
||||||
|
if (vAddr.cX & 2) at >>= 2; break;
|
||||||
|
// Background fetching (low bits):
|
||||||
|
TILE_PHASE_5: addr = bg_addr(); break;
|
||||||
|
TILE_PHASE_6: bgL = rd(addr); break;
|
||||||
|
// Attribute fetching (high bits):
|
||||||
|
TILE_PHASE_7: addr += 8; break;
|
||||||
|
TILE_PHASE_8: bgH = rd(addr); h_scroll(); reload_shift(); break;
|
||||||
|
|
||||||
|
case 256: bgH = rd(addr); v_scroll(); reload_shift(); break; // End of line.
|
||||||
|
case 257: h_update(); // Update horizontal scrolling info.
|
||||||
|
|
||||||
|
case 280 ... 304: // Vertical scrolling update in prerender scanline.
|
||||||
|
if (pre) v_update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inline void scanline_visible() { scanline_<0>(); if (cycle >= 1 && cycle <= 256) pixel(); }
|
||||||
|
inline void scanline_prerender() { scanline_<1>(); }
|
||||||
|
|
||||||
|
/* Execute a PPU cycle. */
|
||||||
|
void step()
|
||||||
|
{
|
||||||
|
switch (scanline)
|
||||||
|
{
|
||||||
|
case 0 ... 238: scanline_visible(); break; // Visible scanline.
|
||||||
|
case 239: scanline_visible(); /*SDL_Flip(s);*/ break; // Last visible scanline.
|
||||||
|
|
||||||
|
case 241: if (cycle == 1) status.vBlank = true; break; // Signal VBlank.
|
||||||
|
|
||||||
|
case 261: // Pre-render scanline.
|
||||||
|
scanline_prerender();
|
||||||
|
if (cycle == 340)
|
||||||
|
{
|
||||||
|
// Restart from the first pixel on the screen:
|
||||||
|
cycle = frameOdd ? 1 : 0; // Skip one cicle on odd frames.
|
||||||
|
scanline = 0; frameOdd ^= 1;
|
||||||
|
return; // Don't update scanline and cycle.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Update current cycle and scanline:
|
||||||
|
cycle = (cycle + 1) % 341;
|
||||||
|
scanline = cycle ? scanline : (scanline + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
75
src/ppu.hpp
75
src/ppu.hpp
|
@ -1,69 +1,78 @@
|
||||||
|
#include "types.hpp"
|
||||||
|
|
||||||
#ifndef PPU_HPP
|
#ifndef PPU_HPP
|
||||||
#define PPU_HPP
|
#define PPU_HPP
|
||||||
namespace PPU {
|
namespace PPU {
|
||||||
|
|
||||||
|
|
||||||
union Status
|
/* PPUCTRL ($2000) register */
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
unsigned bus : 5;
|
|
||||||
unsigned sprOvf : 1;
|
|
||||||
unsigned sprHit : 1;
|
|
||||||
unsigned vBlank : 1;
|
|
||||||
};
|
|
||||||
u8 r;
|
|
||||||
};
|
|
||||||
|
|
||||||
union Ctrl
|
union Ctrl
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
unsigned nt : 2;
|
unsigned nt : 2; // Nametable ($2000 / $2400 / $2800 / $2C00).
|
||||||
unsigned incr : 1;
|
unsigned incr : 1; // Address increment (1 / 32).
|
||||||
unsigned sprTbl : 1;
|
unsigned sprTbl : 1; // Sprite pattern table ($0000 / $1000).
|
||||||
unsigned bgTbl : 1;
|
unsigned bgTbl : 1; // BG pattern table ($0000 / $1000).
|
||||||
unsigned sprSz : 1;
|
unsigned sprSz : 1; // Sprite size (8x8 / 16x8).
|
||||||
unsigned slave : 1;
|
unsigned slave : 1; // PPU master/slave.
|
||||||
unsigned nmi : 1;
|
unsigned nmi : 1; // Enable NMI.
|
||||||
};
|
};
|
||||||
u8 r;
|
u8 r;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* PPUMASK ($2001) register */
|
||||||
union Mask
|
union Mask
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
unsigned gray : 1;
|
unsigned gray : 1; // Grayscale.
|
||||||
unsigned bgLeft : 1;
|
unsigned bgLeft : 1; // Show background in leftmost 8 pixels.
|
||||||
unsigned sprLeft : 1;
|
unsigned sprLeft : 1; // Show sprite in leftmost 8 pixels.
|
||||||
unsigned bg : 1;
|
unsigned bg : 1; // Show background.
|
||||||
unsigned spr : 1;
|
unsigned spr : 1; // Show sprites.
|
||||||
unsigned red : 1;
|
unsigned red : 1; // Intensify reds.
|
||||||
unsigned green : 1;
|
unsigned green : 1; // Intensify greens.
|
||||||
unsigned blue : 1;
|
unsigned blue : 1; // Intensify blues.
|
||||||
};
|
};
|
||||||
u8 r;
|
u8 r;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* PPUSTATUS ($2002) register */
|
||||||
|
union Status
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned bus : 5; // Not significant.
|
||||||
|
unsigned sprOvf : 1; // Sprite overflow.
|
||||||
|
unsigned sprHit : 1; // Sprite 0 Hit.
|
||||||
|
unsigned vBlank : 1; // In VBlank?
|
||||||
|
};
|
||||||
|
u8 r;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Loopy's VRAM address */
|
||||||
union Addr
|
union Addr
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
unsigned cX : 5;
|
unsigned cX : 5; // Coarse X.
|
||||||
unsigned cY : 5;
|
unsigned cY : 5; // Coarse Y.
|
||||||
unsigned nt : 2;
|
unsigned nt : 2; // Nametable.
|
||||||
unsigned fY : 3;
|
unsigned fY : 3; // Fine Y.
|
||||||
};
|
};
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
unsigned l : 8;
|
unsigned l : 8;
|
||||||
unsigned h : 8;
|
unsigned h : 7;
|
||||||
};
|
};
|
||||||
unsigned addr : 12;
|
unsigned addr : 12; // Address part.
|
||||||
unsigned r : 15;
|
unsigned r : 15;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void step();
|
||||||
|
template <bool write> u8 access(u16 index, u8 v = 0);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif // PPU_HPP
|
#endif // PPU_HPP
|
||||||
|
|
54
src/ppu_case.hpp
Normal file
54
src/ppu_case.hpp
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#ifndef PPUCASE_HPP
|
||||||
|
#define PPUCASE_HPP
|
||||||
|
|
||||||
|
|
||||||
|
#define TILE_PHASE_1 \
|
||||||
|
case 1: case 9: case 17: case 25: case 33: case 41: case 49: case 57: case 65: \
|
||||||
|
case 73: case 81: case 89: case 97: case 105: case 113: case 121: case 129: case 137: \
|
||||||
|
case 145: case 153: case 161: case 169: case 177: case 185: case 193: case 201: case 209: \
|
||||||
|
case 217: case 225: case 233: case 241: case 249: case 321: case 329: case 337: case 339
|
||||||
|
|
||||||
|
#define TILE_PHASE_2 \
|
||||||
|
case 2: case 10: case 18: case 26: case 34: case 42: case 50: case 58: case 66: \
|
||||||
|
case 74: case 82: case 90: case 98: case 106: case 114: case 122: case 130: case 138: \
|
||||||
|
case 146: case 154: case 162: case 170: case 178: case 186: case 194: case 202: case 210: \
|
||||||
|
case 218: case 226: case 234: case 242: case 250: case 322: case 330: case 338: case 340
|
||||||
|
|
||||||
|
#define TILE_PHASE_3 \
|
||||||
|
case 3: case 11: case 19: case 27: case 35: case 43: case 51: case 59: case 67: \
|
||||||
|
case 75: case 83: case 91: case 99: case 107: case 115: case 123: case 131: case 139: \
|
||||||
|
case 147: case 155: case 163: case 171: case 179: case 187: case 195: case 203: case 211: \
|
||||||
|
case 219: case 227: case 235: case 243: case 251: case 323: case 331
|
||||||
|
|
||||||
|
#define TILE_PHASE_4 \
|
||||||
|
case 4: case 12: case 20: case 28: case 36: case 44: case 52: case 60: case 68: \
|
||||||
|
case 76: case 84: case 92: case 100: case 108: case 116: case 124: case 132: case 140: \
|
||||||
|
case 148: case 156: case 164: case 172: case 180: case 188: case 196: case 204: case 212: \
|
||||||
|
case 220: case 228: case 236: case 244: case 252: case 324: case 332
|
||||||
|
|
||||||
|
#define TILE_PHASE_5 \
|
||||||
|
case 5: case 13: case 21: case 29: case 37: case 45: case 53: case 61: case 69: \
|
||||||
|
case 77: case 85: case 93: case 101: case 109: case 117: case 125: case 133: case 141: \
|
||||||
|
case 149: case 157: case 165: case 173: case 181: case 189: case 197: case 205: case 213: \
|
||||||
|
case 221: case 229: case 237: case 245: case 253: case 325: case 333
|
||||||
|
|
||||||
|
#define TILE_PHASE_6 \
|
||||||
|
case 6: case 14: case 22: case 30: case 38: case 46: case 54: case 62: case 70: \
|
||||||
|
case 78: case 86: case 94: case 102: case 110: case 118: case 126: case 134: case 142: \
|
||||||
|
case 150: case 158: case 166: case 174: case 182: case 190: case 198: case 206: case 214: \
|
||||||
|
case 222: case 230: case 238: case 246: case 254: case 326: case 334
|
||||||
|
|
||||||
|
#define TILE_PHASE_7 \
|
||||||
|
case 7: case 15: case 23: case 31: case 39: case 47: case 55: case 63: case 71: \
|
||||||
|
case 79: case 87: case 95: case 103: case 111: case 119: case 127: case 135: case 143: \
|
||||||
|
case 151: case 159: case 167: case 175: case 183: case 191: case 199: case 207: case 215: \
|
||||||
|
case 223: case 231: case 239: case 247: case 255: case 327: case 335
|
||||||
|
|
||||||
|
#define TILE_PHASE_8 \
|
||||||
|
case 8: case 16: case 24: case 32: case 40: case 48: case 56: case 64: case 72: \
|
||||||
|
case 80: case 88: case 96: case 104: case 112: case 120: case 128: case 136: case 144: \
|
||||||
|
case 152: case 160: case 168: case 176: case 184: case 192: case 200: case 208: case 216: \
|
||||||
|
case 224: case 232: case 240: case 248: case 328: case 336
|
||||||
|
|
||||||
|
|
||||||
|
#endif // PPUCASE_HPP
|
Reference in a new issue