struct Background { struct ID { enum { BG1, BG2, BG3, BG4 }; }; unsigned id; struct Mode { enum { BPP2, BPP4, BPP8, Mode7, Inactive }; }; struct ScreenSize { enum { Size32x32, Size32x64, Size64x32, Size64x64 }; }; struct TileSize { enum { Size8x8, Size16x16 }; }; struct Screen { enum { Main, Sub }; }; struct Regs { uint16 tiledata_addr; uint16 screen_addr; uint2 screen_size; uint4 mosaic; bool tile_size; unsigned mode; unsigned priority0; unsigned priority1; bool main_enable; bool sub_enable; uint16 hoffset; uint16 voffset; } regs; struct Cache { uint16 hoffset; uint16 voffset; } cache; alwaysinline unsigned voffset() const; alwaysinline unsigned hoffset() const; struct Output { struct Pixel { unsigned priority; //0 = none (transparent) uint8 palette; uint16 tile; } main, sub; } output; struct Mosaic : Output::Pixel { unsigned vcounter; unsigned voffset; unsigned hcounter; unsigned hoffset; } mosaic; struct { signed x; signed y; unsigned tile_counter; unsigned tile; unsigned priority; unsigned palette_number; unsigned palette_index; uint8 data[8]; }; void frame(); void scanline(); void begin(); void run(bool screen); void reset(); void get_tile(); unsigned get_tile_color(); unsigned get_tile(unsigned x, unsigned y); alwaysinline signed clip(signed n); void begin_mode7(); void run_mode7(); void serialize(serializer&); Background(PPU& self, unsigned id); PPU& self; friend class PPU; };