Files
pico-launcher/arm9/source/gui/AdvancedPaletteManager.h
2025-11-25 17:41:31 +01:00

102 lines
2.4 KiB
C++

#pragma once
#include "common.h"
#include "PaletteManager.h"
#define HW_PALETTE_ROWS 16
class AdvancedPaletteManagerBase : public PaletteManager
{
public:
void Reset();
void VCount();
void VBlank()
{
_curSchemeEntry = _nextSchemeEntry;
VCount();
}
protected:
struct PaletteRow
{
u16 colors[16];
u8 startY;
u8 endY;
u8 hwRow;
u8 prev;
u32 next;
u32 hash;
bool ColorsEqualTo(const PaletteRow& other) const;
};
union SchemeEntry
{
struct
{
const u16* src;
vu16* dst;
};
struct
{
u32 endMarker;
u32 nextVCount;
};
};
explicit AdvancedPaletteManagerBase(vu16* targetPalette)
: _targetPalette(targetPalette), _curSchemeEntry(nullptr), _nextSchemeEntry(nullptr)
{
Reset();
}
u32 AllocRowInternal(PaletteRow* rows, const IPalette& palette, int yStart, int yEnd);
void CreateScheme(const PaletteRow* rows, SchemeEntry* scheme);
private:
struct HwPaletteRow
{
u8 count;
u8 first;
int FindPlace(const PaletteRow* rows, u32 yStart, u32 yEnd) const;
};
u32 _usedRows = 0;
HwPaletteRow _hwRows[HW_PALETTE_ROWS];
vu16* _targetPalette;
const SchemeEntry* _curSchemeEntry;
const SchemeEntry* _nextSchemeEntry;
u32 TryMerge(PaletteRow* rows, const PaletteRow& newRow, int yStart, int yEnd);
};
/// @brief Advanced palette manager that manages dynamic palette rows that are valid on a range of scanlines.
/// By reloading the palette during display this allows to use more than 16 palette rows in total
/// as long as only up to 16 are in use on a scanline.
/// @tparam MaxPaletteRows The maximum number of palette rows to manage.
template <u32 MaxPaletteRows>
class AdvancedPaletteManager : public AdvancedPaletteManagerBase
{
public:
explicit AdvancedPaletteManager(vu16* targetPalette)
: AdvancedPaletteManagerBase(targetPalette) { }
u32 AllocRow(const IPalette& palette, int yStart, int yEnd) override
{
return AllocRowInternal(_rows[_curSet], palette, yStart, yEnd);
}
void EndOfFrame()
{
CreateScheme(_rows[_curSet], _scheme[_curSet]);
_curSet = 1 - _curSet;
Reset();
}
private:
u32 _curSet = 0;
PaletteRow _rows[2][MaxPaletteRows];
SchemeEntry _scheme[2][MaxPaletteRows * 2];
};