ref: e2cea92259ab384150ee7056695db359745f9987
dir: /snes/ppu.h/
#ifndef ZELDA3_SNES_PPU_H_ #define ZELDA3_SNES_PPU_H_ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #include <stdbool.h> #include "saveload.h" typedef struct Ppu Ppu; #include "../types.h" typedef struct BgLayer { uint16_t hScroll; uint16_t vScroll; bool tilemapWider; bool tilemapHigher; uint16_t tilemapAdr; uint16_t tileAdr; bool bigTiles_always_zero; bool mosaicEnabled; } BgLayer; typedef struct Layer { bool screenEnabled[2]; // 0 = main, 1 = sub bool screenWindowed[2]; // 0 = main, 1 = sub } Layer; typedef struct WindowLayer { bool window1enabled; bool window2enabled; bool window1inversed; bool window2inversed; uint8_t maskLogic_always_zero; } WindowLayer; enum { kPpuXPixels = 256 + kPpuExtraLeftRight * 2, }; typedef struct PpuPixelPrioBufs { uint8_t pixel[kPpuXPixels]; uint8_t prio[kPpuXPixels]; } PpuPixelPrioBufs; enum { kPpuRenderFlags_NewRenderer = 1, // Render mode7 upsampled by 4x4 kPpuRenderFlags_4x4Mode7 = 2, // Use 240 height instead of 224 kPpuRenderFlags_Height240 = 4, // Disable sprite render limits kPpuRenderFlags_NoSpriteLimits = 8, }; struct Ppu { bool lineHasSprites; uint8_t lastBrightnessMult; uint8_t lastMosaicModulo; uint8_t renderFlags; uint32_t renderPitch; uint8_t *renderBuffer; uint8_t extraLeftCur, extraRightCur, extraLeftRight, extraBottomCur; float mode7PerspectiveLow, mode7PerspectiveHigh; // store 31 extra entries to remove the need for clamp uint8_t brightnessMult[32 + 31]; uint8_t brightnessMultHalf[32 * 2]; PpuPixelPrioBufs bgBuffers[2]; // vram access uint16_t vram[0x8000]; uint16_t vramPointer; bool vramIncrementOnHigh; uint16_t vramIncrement; uint8_t vramRemapMode; uint16_t vramReadBuffer; // cgram access uint16_t cgram[0x100]; uint8_t cgramPointer; bool cgramSecondWrite; uint8_t cgramBuffer; // oam access uint16_t oam[0x100]; uint8_t highOam[0x20]; uint8_t oamAdr; uint8_t oamAdrWritten; bool oamInHigh; bool oamInHighWritten; bool oamSecondWrite; uint8_t oamBuffer; // object/sprites bool objPriority; uint16_t objTileAdr1; uint16_t objTileAdr2; uint8_t objSize; PpuPixelPrioBufs objBuffer; bool timeOver; bool rangeOver; bool objInterlace_always_zero; // background layers BgLayer bgLayer[4]; uint8_t scrollPrev; uint8_t scrollPrev2; uint8_t mosaicSize; uint8_t mosaicStartLine; // layers Layer layer[5]; // mode 7 int16_t m7matrix[8]; // a, b, c, d, x, y, h, v uint8_t m7prev; bool m7largeField; bool m7charFill; bool m7xFlip; bool m7yFlip; bool m7extBg_always_zero; // mode 7 internal int32_t m7startX; int32_t m7startY; // windows WindowLayer windowLayer[6]; uint8_t window1left; uint8_t window1right; uint8_t window2left; uint8_t window2right; // color math uint8_t clipMode; uint8_t preventMathMode; bool addSubscreen; bool subtractColor; bool halfColor; bool mathEnabled[6]; uint8_t fixedColorR; uint8_t fixedColorG; uint8_t fixedColorB; // settings bool forcedBlank; uint8_t brightness; uint8_t mode; bool bg3priority; bool evenFrame; bool pseudoHires_always_zero; bool overscan_always_zero; bool frameOverscan_always_zero; // if we are overscanning this frame (determined at 0,225) bool interlace_always_zero; bool frameInterlace_always_zero; // if we are interlacing this frame (determined at start vblank) bool directColor_always_zero; // latching uint16_t hCount; uint16_t vCount; bool hCountSecond; bool vCountSecond; bool countersLatched; uint8_t ppu1openBus; uint8_t ppu2openBus; uint8_t mosaicModulo[kPpuXPixels]; uint32_t colorMapRgb[256]; }; Ppu* ppu_init(); void ppu_free(Ppu* ppu); void ppu_reset(Ppu* ppu); void ppu_handleVblank(Ppu* ppu); void ppu_runLine(Ppu* ppu, int line); uint8_t ppu_read(Ppu* ppu, uint8_t adr); void ppu_write(Ppu* ppu, uint8_t adr, uint8_t val); void ppu_saveload(Ppu *ppu, SaveLoadFunc *func, void *ctx); bool PpuBeginDrawing(Ppu *ppu, uint8_t *buffer, size_t pitch, uint32_t render_flags); void PpuSetMode7PerspectiveCorrection(Ppu *ppu, int low, int high); void PpuSetExtraSideSpace(Ppu *ppu, int left, int right, int bottom); #endif // ZELDA3_SNES_PPU_H_