mirror of
https://github.com/SourMesen/Mesen2.git
synced 2025-04-02 10:21:44 -04:00
HD packs WIP
This commit is contained in:
parent
3e90df5ef4
commit
4ee43d8ba7
8 changed files with 48 additions and 66 deletions
|
@ -94,26 +94,19 @@ struct HdPpuTileInfo : public HdTileKey
|
|||
struct HdPpuPixelInfo
|
||||
{
|
||||
HdPpuTileInfo Tile;
|
||||
vector<HdPpuTileInfo> Sprite;
|
||||
int SpriteCount;
|
||||
HdPpuTileInfo Sprite[4];
|
||||
|
||||
uint16_t TmpVideoRamAddr;
|
||||
uint8_t XScroll;
|
||||
uint8_t EmphasisBits;
|
||||
bool Grayscale;
|
||||
|
||||
HdPpuPixelInfo()
|
||||
{
|
||||
for(int i = 0; i < 4; i++) {
|
||||
Sprite.push_back(HdPpuTileInfo());
|
||||
}
|
||||
}
|
||||
uint8_t SpriteCount;
|
||||
};
|
||||
|
||||
struct HdScreenInfo
|
||||
{
|
||||
HdPpuPixelInfo* ScreenTiles;
|
||||
std::unordered_map<uint32_t, uint8_t> WatchedAddressValues;
|
||||
unordered_map<uint32_t, uint8_t> WatchedAddressValues;
|
||||
uint32_t FrameNumber;
|
||||
|
||||
HdScreenInfo(const HdScreenInfo& that) = delete;
|
||||
|
@ -291,7 +284,7 @@ struct HdPackTileInfo : public HdTileKey
|
|||
|
||||
struct HdPackBitmapInfo
|
||||
{
|
||||
vector<uint8_t> PixelData;
|
||||
vector<uint32_t> PixelData;
|
||||
uint32_t Width;
|
||||
uint32_t Height;
|
||||
};
|
||||
|
|
|
@ -4,13 +4,15 @@
|
|||
#include "NES/HdPacks/HdNesPack.h"
|
||||
#include "NES/HdPacks/HdPackLoader.h"
|
||||
#include "NES/NesConsole.h"
|
||||
#include "NES/NesDefaultVideoFilter.h"
|
||||
#include "Shared/MessageManager.h"
|
||||
#include "Shared/EmuSettings.h"
|
||||
#include "Utilities/FolderUtilities.h"
|
||||
#include "Utilities/PNGHelper.h"
|
||||
|
||||
HdNesPack::HdNesPack(HdPackData* hdData)
|
||||
HdNesPack::HdNesPack(EmuSettings* settings, HdPackData* hdData)
|
||||
{
|
||||
_settings = settings;
|
||||
_hdData = hdData;
|
||||
}
|
||||
|
||||
|
@ -190,17 +192,16 @@ int32_t HdNesPack::GetLayerIndex(uint8_t priority)
|
|||
return -1;
|
||||
}
|
||||
|
||||
uint32_t palette[512] = {};
|
||||
|
||||
void HdNesPack::OnBeforeApplyFilter()
|
||||
{
|
||||
_palette = palette;
|
||||
//TODO
|
||||
//_palette = _hdData->Palette.size() == 0x40 ? _hdData->Palette.data() : _settings->GetRgbPalette();
|
||||
if(_hdData->Palette.size() == 0x40) {
|
||||
memcpy(_palette, _hdData->Palette.data(), 0x40 * sizeof(uint32_t));
|
||||
} else {
|
||||
NesDefaultVideoFilter::GetFullPalette(_palette, _settings->GetNesConfig(), PpuModel::Ppu2C02);
|
||||
}
|
||||
_cacheEnabled = (_hdData->OptionFlags & (int)HdPackOptions::DisableCache) == 0;
|
||||
//TODO
|
||||
/*
|
||||
if(_hdData->OptionFlags & (int)HdPackOptions::NoSpriteLimit) {
|
||||
/*if(_hdData->OptionFlags & (int)HdPackOptions::NoSpriteLimit) {
|
||||
_settings->SetFlags(EmulationFlags::RemoveSpriteLimit | EmulationFlags::AdaptiveSpriteLimit);
|
||||
}*/
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#include "stdafx.h"
|
||||
#include "NES/HdPacks/HdData.h"
|
||||
|
||||
class EmuSettings;
|
||||
|
||||
class HdNesPack
|
||||
{
|
||||
private:
|
||||
|
@ -14,19 +16,20 @@ private:
|
|||
int16_t BgMaxX = -1;
|
||||
};
|
||||
|
||||
HdPackData* _hdData;
|
||||
|
||||
static constexpr uint8_t PriorityLevelsPerLayer = 10;
|
||||
static constexpr uint8_t BehindBgSpritesPriority = 0 * PriorityLevelsPerLayer;
|
||||
static constexpr uint8_t BehindBgPriority = 1 * PriorityLevelsPerLayer;
|
||||
static constexpr uint8_t BehindFgSpritesPriority = 2 * PriorityLevelsPerLayer;
|
||||
static constexpr uint8_t ForegroundPriority = 3 * PriorityLevelsPerLayer;
|
||||
|
||||
EmuSettings* _settings = nullptr;
|
||||
HdPackData* _hdData = nullptr;
|
||||
|
||||
uint8_t _activeBgCount[4] = {};
|
||||
HdBgConfig _bgConfig[40] = {};
|
||||
|
||||
HdScreenInfo *_hdScreenInfo = nullptr;
|
||||
uint32_t* _palette = nullptr;
|
||||
uint32_t _palette[512] = {};
|
||||
HdPackTileInfo* _cachedTile = nullptr;
|
||||
bool _cacheEnabled = false;
|
||||
bool _useCachedTile = false;
|
||||
|
@ -52,7 +55,7 @@ private:
|
|||
public:
|
||||
static constexpr uint32_t CurrentVersion = 106;
|
||||
|
||||
HdNesPack(HdPackData* hdData);
|
||||
HdNesPack(EmuSettings* settings, HdPackData* hdData);
|
||||
~HdNesPack();
|
||||
|
||||
uint32_t GetScale();
|
||||
|
|
|
@ -12,10 +12,9 @@ HdNesPpu::HdNesPpu(NesConsole* console, HdPackData* hdData) : NesPpu(console)
|
|||
|
||||
if(_hdData) {
|
||||
_version = _hdData->Version;
|
||||
|
||||
bool isChrRamGame = !console->GetMapper()->HasChrRom();
|
||||
_screenInfo[0] = new HdScreenInfo(isChrRamGame);
|
||||
_screenInfo[1] = new HdScreenInfo(isChrRamGame);
|
||||
_isChrRam = !_console->GetMapper()->HasChrRom();
|
||||
_screenInfo[0] = new HdScreenInfo(_isChrRam);
|
||||
_screenInfo[1] = new HdScreenInfo(_isChrRam);
|
||||
_info = _screenInfo[0];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ class HdNesPpu final : public NesPpu<HdNesPpu>
|
|||
HdScreenInfo* _screenInfo[2] = {};
|
||||
HdScreenInfo* _info = nullptr;
|
||||
uint32_t _version = 0;
|
||||
bool _isChrRam = false;
|
||||
HdPackData* _hdData = nullptr;
|
||||
NesSpriteInfoEx _exSpriteInfo[64] = {};
|
||||
NesTileInfoEx _previousTileEx = {};
|
||||
|
@ -71,14 +72,12 @@ public:
|
|||
_lastSprite = nullptr;
|
||||
|
||||
if(IsRenderingEnabled() || ((_videoRamAddr & 0x3F00) != 0x3F00)) {
|
||||
bool isChrRam = !_console->GetMapper()->HasChrRom();
|
||||
BaseMapper* mapper = _console->GetMapper();
|
||||
|
||||
uint32_t color = GetPixelColor();
|
||||
pixel = (_paletteRAM[color & 0x03 ? color : 0] & _paletteRamMask) | _intensifyColorBits;
|
||||
|
||||
uint8_t tilePalette = (_xScroll + ((_cycle - 1) & 0x07) < 8) ? _previousTilePalette : _currentTilePalette;
|
||||
NesTileInfoEx& lastTileEx = (_xScroll + ((_cycle - 1) & 0x07) < 8) ? _previousTileEx : _currentTileEx;
|
||||
bool usePrev = (_xScroll + ((_cycle - 1) & 0x07) < 8);
|
||||
uint8_t tilePalette = usePrev ? _previousTilePalette : _currentTilePalette;
|
||||
NesTileInfoEx& lastTileEx = usePrev ? _previousTileEx : _currentTileEx;
|
||||
uint32_t backgroundColor = 0;
|
||||
if(_backgroundEnabled && _cycle > _minimumDrawBgCycle) {
|
||||
backgroundColor = (((_lowBitShift << _xScroll) & 0x8000) >> 15) | (((_highBitShift << _xScroll) & 0x8000) >> 14);
|
||||
|
@ -107,8 +106,8 @@ public:
|
|||
NesSpriteInfoEx& spriteEx = _exSpriteInfo[i];
|
||||
if(shift >= 0 && shift < 8) {
|
||||
tileInfo.Sprite[j].TileIndex = spriteEx.AbsoluteTileAddr / 16;
|
||||
if(isChrRam) {
|
||||
mapper->CopyChrTile(spriteEx.AbsoluteTileAddr & 0xFFFFFFF0, tileInfo.Sprite[j].TileData);
|
||||
if(_isChrRam) {
|
||||
_console->GetMapper()->CopyChrTile(spriteEx.AbsoluteTileAddr & 0xFFFFFFF0, tileInfo.Sprite[j].TileData);
|
||||
}
|
||||
if(_version >= 100) {
|
||||
tileInfo.Sprite[j].PaletteColors = 0xFF000000 | _paletteRAM[sprite.PaletteOffset + 3] | (_paletteRAM[sprite.PaletteOffset + 2] << 8) | (_paletteRAM[sprite.PaletteOffset + 1] << 16);
|
||||
|
@ -155,8 +154,8 @@ public:
|
|||
|
||||
if(_backgroundEnabled && _cycle > _minimumDrawBgCycle) {
|
||||
tileInfo.Tile.TileIndex = lastTileEx.AbsoluteTileAddr / 16;
|
||||
if(isChrRam) {
|
||||
mapper->CopyChrTile(lastTileEx.AbsoluteTileAddr & 0xFFFFFFF0, tileInfo.Tile.TileData);
|
||||
if(_isChrRam) {
|
||||
_console->GetMapper()->CopyChrTile(lastTileEx.AbsoluteTileAddr & 0xFFFFFFF0, tileInfo.Tile.TileData);
|
||||
}
|
||||
if(_version >= 100) {
|
||||
tileInfo.Tile.PaletteColors = _paletteRAM[tilePalette + 3] | (_paletteRAM[tilePalette + 2] << 8) | (_paletteRAM[tilePalette + 1] << 16) | (_paletteRAM[0] << 24);
|
||||
|
|
|
@ -209,13 +209,17 @@ bool HdPackLoader::ProcessImgTag(string src)
|
|||
vector<uint8_t> fileData;
|
||||
vector<uint8_t> pixelData;
|
||||
LoadFile(src, fileData);
|
||||
|
||||
_hdNesBitmaps.push_back({});
|
||||
HdPackBitmapInfo& bitmapInfo = _hdNesBitmaps.back();
|
||||
if(PNGHelper::ReadPNG(fileData, bitmapInfo.PixelData, bitmapInfo.Width, bitmapInfo.Height)) {
|
||||
uint32_t width, height;
|
||||
if(PNGHelper::ReadPNG(fileData, pixelData, width, height)) {
|
||||
_hdNesBitmaps.push_back({});
|
||||
HdPackBitmapInfo& bitmapInfo = _hdNesBitmaps.back();
|
||||
bitmapInfo.Width = width;
|
||||
bitmapInfo.Height = height;
|
||||
bitmapInfo.PixelData.resize(pixelData.size() / 4);
|
||||
memcpy(bitmapInfo.PixelData.data(), pixelData.data(), bitmapInfo.PixelData.size() * sizeof(bitmapInfo.PixelData[0]));
|
||||
PremultiplyAlpha(bitmapInfo.PixelData);
|
||||
return true;
|
||||
} else {
|
||||
_hdNesBitmaps.pop_back();
|
||||
MessageManager::Log("[HDPack] Error loading HDPack: PNG file " + src + " could not be read.");
|
||||
return false;
|
||||
}
|
||||
|
@ -225,7 +229,6 @@ void HdPackLoader::PremultiplyAlpha(vector<uint32_t> &pixelData)
|
|||
{
|
||||
for(size_t i = 0; i < pixelData.size(); i++) {
|
||||
if(pixelData[i] < 0xFF000000) {
|
||||
//If not fully opaque, pre-multiply alpha with R/G/B to avoid having to do this while running
|
||||
uint8_t* output = (uint8_t*)(pixelData.data() + i);
|
||||
uint8_t alpha = output[3] + 1;
|
||||
output[0] = (uint8_t)((alpha * output[0]) >> 8);
|
||||
|
@ -372,30 +375,13 @@ void HdPackLoader::ProcessTileTag(vector<string> &tokens, vector<HdPackCondition
|
|||
checkConstraint(tileInfo->BitmapIndex < _hdNesBitmaps.size(), "[HDPack] Invalid bitmap index: " + std::to_string(tileInfo->BitmapIndex));
|
||||
|
||||
HdPackBitmapInfo &bitmapInfo = _hdNesBitmaps[tileInfo->BitmapIndex];
|
||||
|
||||
uint32_t bitmapOffset = (tileInfo->Y * bitmapInfo.Width + tileInfo->X) * sizeof(uint32_t);
|
||||
uint8_t* pngData = bitmapInfo.PixelData.data();
|
||||
uint32_t bitmapOffset = tileInfo->Y * bitmapInfo.Width + tileInfo->X;
|
||||
uint32_t* pngData = (uint32_t*)bitmapInfo.PixelData.data();
|
||||
|
||||
tileInfo->HdTileData.resize(64 * _data->Scale * _data->Scale);
|
||||
for(uint32_t y = 0; y < 8 * _data->Scale; y++) {
|
||||
for(uint32_t x = 0; x < 8 * _data->Scale; x++) {
|
||||
uint8_t r = pngData[bitmapOffset];
|
||||
uint8_t g = pngData[bitmapOffset + 1];
|
||||
uint8_t b = pngData[bitmapOffset + 2];
|
||||
uint8_t a = pngData[bitmapOffset + 3];
|
||||
|
||||
if(a < 0xFF) {
|
||||
//If not fully opaque, pre-multiply alpha with R/G/B to avoid having to do this while running
|
||||
uint8_t alpha = a + 1;
|
||||
r = (uint8_t)((alpha * r) >> 8);
|
||||
g = (uint8_t)((alpha * g) >> 8);
|
||||
b = (uint8_t)((alpha * b) >> 8);
|
||||
}
|
||||
|
||||
tileInfo->HdTileData[y * 8 * _data->Scale + x] = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
bitmapOffset += sizeof(uint32_t);
|
||||
}
|
||||
bitmapOffset += (bitmapInfo.Width - (8 * _data->Scale)) * sizeof(uint32_t);
|
||||
memcpy(tileInfo->HdTileData.data() + (y * 8 * _data->Scale), pngData + bitmapOffset, 8 * _data->Scale * sizeof(uint32_t));
|
||||
bitmapOffset += bitmapInfo.Width;
|
||||
}
|
||||
|
||||
tileInfo->UpdateFlags();
|
||||
|
|
|
@ -3,12 +3,13 @@
|
|||
#include "NES/HdPacks/HdVideoFilter.h"
|
||||
#include "NES/NesConsole.h"
|
||||
#include "NES/NesConstants.h"
|
||||
#include "Shared/Emulator.h"
|
||||
#include "Shared/Video/BaseVideoFilter.h"
|
||||
|
||||
HdVideoFilter::HdVideoFilter(Emulator* emu, HdPackData* hdData) : BaseVideoFilter(emu)
|
||||
{
|
||||
_hdData = hdData;
|
||||
_hdNesPack.reset(new HdNesPack(hdData));
|
||||
_hdNesPack.reset(new HdNesPack(emu->GetSettings(), hdData));
|
||||
}
|
||||
|
||||
FrameInfo HdVideoFilter::GetFrameInfo()
|
||||
|
|
|
@ -54,10 +54,10 @@ bool PNGHelper::ReadPNG(vector<uint8_t> input, vector<uint8_t> &output, uint32_t
|
|||
|
||||
if(DecodePNG(output, width, height, input.data(), input.size()) == 0) {
|
||||
uint32_t *pngDataPtr = (uint32_t*)output.data();
|
||||
/*for(size_t i = 0, len = output.size() / 4; i < len; i++) {
|
||||
for(size_t i = 0, len = output.size() / 4; i < len; i++) {
|
||||
//ABGR to ARGB
|
||||
pngDataPtr[i] = (pngDataPtr[i] & 0xFF00FF00) | ((pngDataPtr[i] & 0xFF0000) >> 16) | ((pngDataPtr[i] & 0xFF) << 16);
|
||||
}*/
|
||||
}
|
||||
pngWidth = width;
|
||||
pngHeight = height;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue