HD Packs: Added ability to have multiple backgrounds on different layers (up to 40)
This commit is contained in:
parent
193235b11f
commit
c1f841b6dd
6 changed files with 132 additions and 107 deletions
|
@ -313,7 +313,8 @@ struct HdBackgroundInfo
|
|||
vector<HdPackCondition*> Conditions;
|
||||
float HorizontalScrollRatio;
|
||||
float VerticalScrollRatio;
|
||||
bool BehindBgPrioritySprites;
|
||||
uint8_t Priority;
|
||||
|
||||
uint32_t Left;
|
||||
uint32_t Top;
|
||||
|
||||
|
@ -377,7 +378,6 @@ enum class HdPackOptions
|
|||
None = 0,
|
||||
NoSpriteLimit = 1,
|
||||
AlternateRegisterRange = 2,
|
||||
NoContours = 4,
|
||||
DisableCache = 8,
|
||||
DontRenderOriginalTiles = 16
|
||||
};
|
|
@ -50,13 +50,13 @@ void HdNesPack::DrawColor(uint32_t color, uint32_t *outputBuffer, uint32_t scale
|
|||
}
|
||||
}
|
||||
|
||||
void HdNesPack::DrawCustomBackground(uint32_t *outputBuffer, uint32_t x, uint32_t y, uint32_t scale, uint32_t screenWidth)
|
||||
void HdNesPack::DrawCustomBackground(HdBackgroundInfo& bgInfo, uint32_t *outputBuffer, uint32_t x, uint32_t y, uint32_t scale, uint32_t screenWidth)
|
||||
{
|
||||
int brightness = _hdData->Backgrounds[_backgroundIndex].Brightness;
|
||||
uint32_t left = _hdData->Backgrounds[_backgroundIndex].Left;
|
||||
uint32_t top = _hdData->Backgrounds[_backgroundIndex].Top;
|
||||
uint32_t width = _hdData->Backgrounds[_backgroundIndex].Data->Width;
|
||||
uint32_t *pngData = _hdData->Backgrounds[_backgroundIndex].data() + ((top + y) * _hdData->Scale * width) + ((left + x) * _hdData->Scale);
|
||||
int brightness = bgInfo.Brightness;
|
||||
uint32_t left = bgInfo.Left;
|
||||
uint32_t top = bgInfo.Top;
|
||||
uint32_t width = bgInfo.Data->Width;
|
||||
uint32_t *pngData = bgInfo.data() + ((top + y) * _hdData->Scale * width) + ((left + x) * _hdData->Scale);
|
||||
uint32_t pixelColor;
|
||||
|
||||
for(uint32_t i = 0; i < scale; i++) {
|
||||
|
@ -145,32 +145,37 @@ uint32_t HdNesPack::GetScale()
|
|||
return _hdData->Scale;
|
||||
}
|
||||
|
||||
void HdNesPack::OnLineStart(HdPpuPixelInfo &lineFirstPixel)
|
||||
void HdNesPack::OnLineStart(HdPpuPixelInfo &lineFirstPixel, uint8_t y)
|
||||
{
|
||||
_scrollX = ((lineFirstPixel.TmpVideoRamAddr & 0x1F) << 3) | lineFirstPixel.XScroll | ((lineFirstPixel.TmpVideoRamAddr & 0x400) ? 0x100 : 0);
|
||||
_useCachedTile = false;
|
||||
|
||||
if(_backgroundIndex >= 0) {
|
||||
int32_t scrollY = (((lineFirstPixel.TmpVideoRamAddr & 0x3E0) >> 2) | ((lineFirstPixel.TmpVideoRamAddr & 0x7000) >> 12)) + ((lineFirstPixel.TmpVideoRamAddr & 0x800) ? 240 : 0);
|
||||
HdBackgroundInfo &bgInfo = _hdData->Backgrounds[_backgroundIndex];
|
||||
|
||||
_bgScrollX = (int32_t)(_scrollX * bgInfo.HorizontalScrollRatio);
|
||||
_bgScrollY = (int32_t)(scrollY * bgInfo.VerticalScrollRatio);
|
||||
int32_t scrollY = (((lineFirstPixel.TmpVideoRamAddr & 0x3E0) >> 2) | ((lineFirstPixel.TmpVideoRamAddr & 0x7000) >> 12)) + ((lineFirstPixel.TmpVideoRamAddr & 0x800) ? 240 : 0);
|
||||
|
||||
for(int layer = 0; layer < 4; layer++) {
|
||||
for(int i = 0; i < _activeBgCount[layer]; i++) {
|
||||
HdBgConfig& cfg = _bgConfig[layer * HdNesPack::PriorityLevelsPerLayer + i];
|
||||
HdBackgroundInfo& bgInfo = _hdData->Backgrounds[cfg.BackgroundIndex];
|
||||
cfg.BgScrollX = (int32_t)(_scrollX * bgInfo.HorizontalScrollRatio);
|
||||
cfg.BgScrollY = (int32_t)(scrollY * bgInfo.VerticalScrollRatio);
|
||||
if(y >= -cfg.BgScrollY && (y + bgInfo.Top + cfg.BgScrollY + 1) * _hdData->Scale <= bgInfo.Data->Height) {
|
||||
cfg.BgMinX = -cfg.BgScrollX;
|
||||
cfg.BgMaxX = bgInfo.Data->Width / _hdData->Scale - bgInfo.Left - cfg.BgScrollX - 1;
|
||||
} else {
|
||||
cfg.BgMinX = -1;
|
||||
cfg.BgMaxX = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HdNesPack::OnBeforeApplyFilter()
|
||||
int32_t HdNesPack::GetLayerIndex(uint8_t priority)
|
||||
{
|
||||
_palette = _hdData->Palette.size() == 0x40 ? _hdData->Palette.data() : _settings->GetRgbPalette();
|
||||
_contoursEnabled = (_hdData->OptionFlags & (int)HdPackOptions::NoContours) == 0;
|
||||
_cacheEnabled = (_hdData->OptionFlags & (int)HdPackOptions::DisableCache) == 0;
|
||||
|
||||
if(_hdData->OptionFlags & (int)HdPackOptions::NoSpriteLimit) {
|
||||
_settings->SetFlags(EmulationFlags::RemoveSpriteLimit | EmulationFlags::AdaptiveSpriteLimit);
|
||||
}
|
||||
|
||||
_backgroundIndex = -1;
|
||||
for(size_t i = 0; i < _hdData->Backgrounds.size(); i++) {
|
||||
if(_hdData->Backgrounds[i].Priority != priority) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bool isMatch = true;
|
||||
for(HdPackCondition* condition : _hdData->Backgrounds[i].Conditions) {
|
||||
if(!condition->CheckCondition(_hdScreenInfo, 0, 0, nullptr)) {
|
||||
|
@ -180,10 +185,32 @@ void HdNesPack::OnBeforeApplyFilter()
|
|||
}
|
||||
|
||||
if(isMatch) {
|
||||
_backgroundIndex = (int32_t)i;
|
||||
break;
|
||||
return (int32_t)i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void HdNesPack::OnBeforeApplyFilter()
|
||||
{
|
||||
_palette = _hdData->Palette.size() == 0x40 ? _hdData->Palette.data() : _settings->GetRgbPalette();
|
||||
_cacheEnabled = (_hdData->OptionFlags & (int)HdPackOptions::DisableCache) == 0;
|
||||
|
||||
if(_hdData->OptionFlags & (int)HdPackOptions::NoSpriteLimit) {
|
||||
_settings->SetFlags(EmulationFlags::RemoveSpriteLimit | EmulationFlags::AdaptiveSpriteLimit);
|
||||
}
|
||||
|
||||
for(int layer = 0; layer < 4; layer++) {
|
||||
uint32_t activeCount = 0;
|
||||
for(int i = 0; i < HdNesPack::PriorityLevelsPerLayer; i++) {
|
||||
int32_t index = GetLayerIndex(layer * HdNesPack::PriorityLevelsPerLayer + i);
|
||||
if(index >= 0) {
|
||||
_bgConfig[layer*10+activeCount].BackgroundIndex = index;
|
||||
activeCount++;
|
||||
}
|
||||
}
|
||||
_activeBgCount[layer] = activeCount;
|
||||
}
|
||||
|
||||
for(unique_ptr<HdPackCondition> &condition : _hdData->Conditions) {
|
||||
condition->ClearCache();
|
||||
|
@ -235,39 +262,15 @@ HdPackTileInfo* HdNesPack::GetMatchingTile(uint32_t x, uint32_t y, HdPpuTileInfo
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool HdNesPack::IsNextToSprite(uint32_t x, uint32_t y)
|
||||
bool HdNesPack::DrawBackgroundLayer(uint8_t priority, uint32_t x, uint32_t y, uint32_t* outputBuffer, uint32_t screenWidth)
|
||||
{
|
||||
bool hasNonBackgroundSurrounding = false;
|
||||
auto processAdjacentTile = [&hasNonBackgroundSurrounding](HdPpuPixelInfo& pixelInfo) {
|
||||
if(pixelInfo.Tile.BgColorIndex != 0) {
|
||||
hasNonBackgroundSurrounding = true;
|
||||
} else {
|
||||
for(int i = 0; i < pixelInfo.SpriteCount; i++) {
|
||||
if(pixelInfo.Sprite[i].SpriteColorIndex == 0 || pixelInfo.Sprite[i].SpriteColor != pixelInfo.Sprite[i].BgColor) {
|
||||
hasNonBackgroundSurrounding |= pixelInfo.Sprite[i].TileIndex != HdPpuTileInfo::NoTile && pixelInfo.Sprite[i].SpriteColorIndex != 0;
|
||||
}
|
||||
if(hasNonBackgroundSurrounding) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
for(int i = -1; i <= 1; i++) {
|
||||
if((int)y + i < 0 || y + i >= PPU::ScreenHeight) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for(int j = -1; j <= 1; j++) {
|
||||
if((int)x + j < 0 || x + j >= PPU::ScreenWidth) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!hasNonBackgroundSurrounding) {
|
||||
processAdjacentTile(_hdScreenInfo->ScreenTiles[(i + y) * 256 + j + x]);
|
||||
}
|
||||
}
|
||||
HdBgConfig bgConfig = _bgConfig[(int)priority];
|
||||
if((int32_t)x >= bgConfig.BgMinX && (int32_t)x <= bgConfig.BgMaxX) {
|
||||
HdBackgroundInfo& bgInfo = _hdData->Backgrounds[bgConfig.BackgroundIndex];
|
||||
DrawCustomBackground(bgInfo, outputBuffer, x + bgConfig.BgScrollX, y + bgConfig.BgScrollY, _hdData->Scale, screenWidth);
|
||||
return true;
|
||||
}
|
||||
return hasNonBackgroundSurrounding;
|
||||
return false;
|
||||
}
|
||||
|
||||
void HdNesPack::GetPixels(uint32_t x, uint32_t y, HdPpuPixelInfo &pixelInfo, uint32_t *outputBuffer, uint32_t screenWidth)
|
||||
|
@ -285,26 +288,9 @@ void HdNesPack::GetPixels(uint32_t x, uint32_t y, HdPpuPixelInfo &pixelInfo, uin
|
|||
|
||||
DrawColor(_palette[pixelInfo.Tile.PpuBackgroundColor], outputBuffer, _hdData->Scale, screenWidth);
|
||||
|
||||
bool hasCustomBackground = false;
|
||||
bool hasNonBackgroundSurrounding = false;
|
||||
bool backgroundBehindBgSprites = false;
|
||||
if(_backgroundIndex >= 0) {
|
||||
HdBackgroundInfo &bgInfo = _hdData->Backgrounds[_backgroundIndex];
|
||||
|
||||
//Enable custom background if the current pixel fits within the background's boundaries
|
||||
hasCustomBackground =
|
||||
(int32_t)x >= -_bgScrollX &&
|
||||
(int32_t)y >= -_bgScrollY &&
|
||||
(y + bgInfo.Top + _bgScrollY + 1) * _hdData->Scale <= bgInfo.Data->Height &&
|
||||
(x + bgInfo.Left + _bgScrollX + 1) * _hdData->Scale <= bgInfo.Data->Width;
|
||||
|
||||
if(hasCustomBackground) {
|
||||
hasNonBackgroundSurrounding = _contoursEnabled && IsNextToSprite(x, y);
|
||||
if(bgInfo.BehindBgPrioritySprites) {
|
||||
DrawCustomBackground(outputBuffer, x + _bgScrollX, y + _bgScrollY, _hdData->Scale, screenWidth);
|
||||
backgroundBehindBgSprites = true;
|
||||
}
|
||||
}
|
||||
bool hasBackground = false;
|
||||
for(int i = 0; i < _activeBgCount[0]; i++) {
|
||||
hasBackground |= DrawBackgroundLayer(HdNesPack::BehindBgSpritesPriority+i, x, y, outputBuffer, screenWidth);
|
||||
}
|
||||
|
||||
if(hasSprite) {
|
||||
|
@ -324,20 +310,23 @@ void HdNesPack::GetPixels(uint32_t x, uint32_t y, HdPpuPixelInfo &pixelInfo, uin
|
|||
}
|
||||
}
|
||||
|
||||
if (hasCustomBackground && !backgroundBehindBgSprites) {
|
||||
DrawCustomBackground(outputBuffer, x + _bgScrollX, y + _bgScrollY, _hdData->Scale, screenWidth);
|
||||
for(int i = 0; i < _activeBgCount[1]; i++) {
|
||||
hasBackground |= DrawBackgroundLayer(HdNesPack::BehindBgPriority+i, x, y, outputBuffer, screenWidth);
|
||||
}
|
||||
|
||||
|
||||
if(hdPackTileInfo) {
|
||||
DrawTile(pixelInfo.Tile, *hdPackTileInfo, outputBuffer, screenWidth);
|
||||
} else if(renderOriginalTiles) {
|
||||
//Draw regular SD background tile
|
||||
bool useCustomBackground = !hasNonBackgroundSurrounding && hasCustomBackground && pixelInfo.Tile.BgColorIndex == 0;
|
||||
if(!useCustomBackground && (pixelInfo.Tile.BgColorIndex != 0 || hasNonBackgroundSurrounding)) {
|
||||
if(!hasBackground || pixelInfo.Tile.BgColorIndex != 0) {
|
||||
DrawColor(_palette[pixelInfo.Tile.BgColor], outputBuffer, _hdData->Scale, screenWidth);
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < _activeBgCount[2]; i++) {
|
||||
DrawBackgroundLayer(HdNesPack::BehindFgSpritesPriority+i, x, y, outputBuffer, screenWidth);
|
||||
}
|
||||
|
||||
if(hasSprite) {
|
||||
for(int k = pixelInfo.SpriteCount - 1; k >= 0; k--) {
|
||||
if(!pixelInfo.Sprite[k].BackgroundPriority && lowestBgSprite > k) {
|
||||
|
@ -350,6 +339,10 @@ void HdNesPack::GetPixels(uint32_t x, uint32_t y, HdPpuPixelInfo &pixelInfo, uin
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < _activeBgCount[3]; i++) {
|
||||
DrawBackgroundLayer(HdNesPack::ForegroundPriority+i, x, y, outputBuffer, screenWidth);
|
||||
}
|
||||
}
|
||||
|
||||
void HdNesPack::Process(HdScreenInfo *hdScreenInfo, uint32_t* outputBuffer, OverscanDimensions &overscan)
|
||||
|
@ -360,7 +353,7 @@ void HdNesPack::Process(HdScreenInfo *hdScreenInfo, uint32_t* outputBuffer, Over
|
|||
|
||||
OnBeforeApplyFilter();
|
||||
for(uint32_t i = overscan.Top, iMax = 240 - overscan.Bottom; i < iMax; i++) {
|
||||
OnLineStart(hdScreenInfo->ScreenTiles[i << 8]);
|
||||
OnLineStart(hdScreenInfo->ScreenTiles[i << 8], i);
|
||||
uint32_t bufferIndex = (i - overscan.Top) * screenWidth * hdScale;
|
||||
uint32_t lineStartIndex = bufferIndex;
|
||||
for(uint32_t j = overscan.Left, jMax = 256 - overscan.Right; j < jMax; j++) {
|
||||
|
|
|
@ -7,19 +7,33 @@ class EmulationSettings;
|
|||
class HdNesPack
|
||||
{
|
||||
private:
|
||||
struct HdBgConfig
|
||||
{
|
||||
int32_t BackgroundIndex = -1;
|
||||
int32_t BgScrollX = 0;
|
||||
int32_t BgScrollY = 0;
|
||||
int16_t BgMinX = -1;
|
||||
int16_t BgMaxX = -1;
|
||||
};
|
||||
|
||||
shared_ptr<HdPackData> _hdData;
|
||||
EmulationSettings *_settings;
|
||||
|
||||
int32_t _backgroundIndex = -1;
|
||||
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;
|
||||
|
||||
uint8_t _activeBgCount[4] = {};
|
||||
HdBgConfig _bgConfig[40] = {};
|
||||
|
||||
HdScreenInfo *_hdScreenInfo = nullptr;
|
||||
uint32_t* _palette = nullptr;
|
||||
bool _contoursEnabled = false;
|
||||
HdPackTileInfo* _cachedTile = nullptr;
|
||||
bool _cacheEnabled = false;
|
||||
bool _useCachedTile = false;
|
||||
int32_t _scrollX = 0;
|
||||
int32_t _bgScrollX = 0;
|
||||
int32_t _bgScrollY = 0;
|
||||
|
||||
__forceinline void BlendColors(uint8_t output[4], uint8_t input[4]);
|
||||
__forceinline uint32_t AdjustBrightness(uint8_t input[4], int brightness);
|
||||
|
@ -29,16 +43,17 @@ private:
|
|||
__forceinline HdPackTileInfo* GetCachedMatchingTile(uint32_t x, uint32_t y, HdPpuTileInfo* tile);
|
||||
__forceinline HdPackTileInfo* GetMatchingTile(uint32_t x, uint32_t y, HdPpuTileInfo* tile, bool* disableCache = nullptr);
|
||||
|
||||
__forceinline bool IsNextToSprite(uint32_t x, uint32_t y);
|
||||
__forceinline void DrawCustomBackground(uint32_t *outputBuffer, uint32_t x, uint32_t y, uint32_t scale, uint32_t screenWidth);
|
||||
__forceinline bool DrawBackgroundLayer(uint8_t priority, uint32_t x, uint32_t y, uint32_t* outputBuffer, uint32_t screenWidth);
|
||||
__forceinline void DrawCustomBackground(HdBackgroundInfo& bgInfo, uint32_t *outputBuffer, uint32_t x, uint32_t y, uint32_t scale, uint32_t screenWidth);
|
||||
|
||||
void OnLineStart(HdPpuPixelInfo &lineFirstPixel);
|
||||
void OnLineStart(HdPpuPixelInfo &lineFirstPixel, uint8_t y);
|
||||
int32_t GetLayerIndex(uint8_t priority);
|
||||
void OnBeforeApplyFilter();
|
||||
__forceinline void GetPixels(uint32_t x, uint32_t y, HdPpuPixelInfo &pixelInfo, uint32_t *outputBuffer, uint32_t screenWidth);
|
||||
__forceinline void ProcessGrayscaleAndEmphasis(HdPpuPixelInfo &pixelInfo, uint32_t* outputBuffer, uint32_t hdScreenWidth);
|
||||
|
||||
public:
|
||||
static constexpr uint32_t CurrentVersion = 105;
|
||||
static constexpr uint32_t CurrentVersion = 106;
|
||||
|
||||
HdNesPack(shared_ptr<HdPackData> hdData, EmulationSettings* settings);
|
||||
~HdNesPack();
|
||||
|
|
|
@ -371,9 +371,6 @@ void HdPackBuilder::SaveHdPack()
|
|||
if(_hdData.OptionFlags & (int)HdPackOptions::AlternateRegisterRange) {
|
||||
ss << "alternateRegisterRange,";
|
||||
}
|
||||
if(_hdData.OptionFlags & (int)HdPackOptions::NoContours) {
|
||||
ss << "disableContours,";
|
||||
}
|
||||
if(_hdData.OptionFlags & (int)HdPackOptions::DisableCache) {
|
||||
ss << "disableCache,";
|
||||
}
|
||||
|
|
|
@ -392,8 +392,6 @@ void HdPackLoader::ProcessOptionTag(vector<string> &tokens)
|
|||
_data->OptionFlags |= (int)HdPackOptions::NoSpriteLimit;
|
||||
} else if(token == "alternateRegisterRange") {
|
||||
_data->OptionFlags |= (int)HdPackOptions::AlternateRegisterRange;
|
||||
} else if(token == "disableContours") {
|
||||
_data->OptionFlags |= (int)HdPackOptions::NoContours;
|
||||
} else if(token == "disableCache") {
|
||||
_data->OptionFlags |= (int)HdPackOptions::DisableCache;
|
||||
} else if(token == "disableOriginalTiles") {
|
||||
|
@ -577,7 +575,7 @@ void HdPackLoader::ProcessBackgroundTag(vector<string> &tokens, vector<HdPackCon
|
|||
}
|
||||
backgroundInfo.HorizontalScrollRatio = 0;
|
||||
backgroundInfo.VerticalScrollRatio = 0;
|
||||
backgroundInfo.BehindBgPrioritySprites = false;
|
||||
backgroundInfo.Priority = 10;
|
||||
backgroundInfo.Left = 0;
|
||||
backgroundInfo.Top = 0;
|
||||
|
||||
|
@ -605,7 +603,12 @@ void HdPackLoader::ProcessBackgroundTag(vector<string> &tokens, vector<HdPackCon
|
|||
}
|
||||
if(tokens.size() > 4) {
|
||||
checkConstraint(_data->Version >= 102, "[HDPack] This feature requires version 102+ of HD Packs");
|
||||
backgroundInfo.BehindBgPrioritySprites = tokens[4] == "Y";
|
||||
if(_data->Version >= 106) {
|
||||
backgroundInfo.Priority = std::stoi(tokens[4]);
|
||||
checkConstraint(backgroundInfo.Priority >= 0 && backgroundInfo.Priority < 40, "[HDPack] Invalid background priority value");
|
||||
} else {
|
||||
backgroundInfo.Priority = tokens[4] == "Y" ? 0 : 10;
|
||||
}
|
||||
}
|
||||
if(tokens.size() > 6) {
|
||||
checkConstraint(_data->Version >= 105, "[HDPack] This feature requires version 105+ of HD Packs");
|
||||
|
|
|
@ -55,14 +55,14 @@ Before you start recording, select the options you want to use and the location
|
|||
|
||||
## File Format (hires.txt) ##
|
||||
|
||||
The following are the specifications for the hires.txt file, as of version "105".
|
||||
The following are the specifications for the hires.txt file, as of version "106".
|
||||
|
||||
### <ver> tag ###
|
||||
|
||||
**Syntax**: `<ver>[integer]`
|
||||
**Example**: `<ver>105`
|
||||
**Example**: `<ver>106`
|
||||
|
||||
The format's version number (currently 105).
|
||||
The format's version number (currently 106).
|
||||
|
||||
### <scale> tag ###
|
||||
|
||||
|
@ -191,10 +191,10 @@ When `default tile` is enabled (with `Y`), the tile is marked as the `default ti
|
|||
|
||||
### <background> tag ###
|
||||
|
||||
**Syntax**: `<background>[name - text], [brightness level - float (default: 1.0)], [horizontal scroll ratio (optional) - float], [vertical scroll ratio (optional) - float], [showBehindBackgroundPrioritySprites (optional) - Y or N], [image left offset (optional) - int], [image top offset (optional) - int]`
|
||||
**Example**: `<background>myBackground.png,1.0,0,0,N,0,0`
|
||||
**Syntax**: `<background>[name - text], [brightness level - float (default: 1.0)], [horizontal scroll ratio (optional) - float], [vertical scroll ratio (optional) - float], [priority level (optional) - int, 0 to 39 (default 10)], [image left offset (optional) - int], [image top offset (optional) - int]`
|
||||
**Example**: `<background>myBackground.png,1.0,0,0,10,0,0`
|
||||
|
||||
`<background>` tags meant to be used alongside conditions to add a background image under certain conditions (e.g on a specific screen, for example).
|
||||
`<background>` tags are meant to be used alongside conditions to add a background image under certain conditions (e.g on a specific screen, for example).
|
||||
|
||||
The `Horizontal Scroll Ratio` and `Vertical Scroll Ratio` parameters are optional (their default value is `0.0`) and can be used to specify at what speed the background picture should scroll compared to the NES' scrolling.
|
||||
This can be used to create simple parallax scrolling effects.
|
||||
|
@ -202,7 +202,20 @@ This can be used to create simple parallax scrolling effects.
|
|||
The `Image Left Offset` and `Image Top Offset` parameters are optional (their default value is `0`) and can be used to offset the position of the background image within the PNG file. e.g: Specifying 100 for the left offset will cause the background to be scrolled 100 pixels to the left by default.
|
||||
With conditions, this can be used to create scrolling effects that are based on something other than the PPU's current scroll offset.
|
||||
|
||||
When the `Show Behind Background Priority Sprites` parameter is enabled (`Y`), the background priority sprites will be shown in front of the background image.
|
||||
The `Priority Level` parameter determines where the background is inserted compared to the NES' 3 "layers" (background sprites -> background tiles -> foreground sprites).
|
||||
The screen is drawn in this order:
|
||||
|
||||
* Priority 0 to 9 HD backgrounds (priority 0 is below priority 1, etc.)
|
||||
* Background-priority sprites
|
||||
* Priority 10 to 19 HD backgrounds
|
||||
* Background tiles
|
||||
* Priority 20 to 29 HD backgrounds
|
||||
* Foreground-priority sprites
|
||||
* Priority 30 to 39 HD backgrounds
|
||||
|
||||
Note: Only a single background can be active per priority level.
|
||||
|
||||
Backgrounds can use a PNG's alpha channel to allow the graphics below to show through them (this can be used to add a fog effect to the screen, etc.)
|
||||
|
||||
### <options> tag ###
|
||||
|
||||
|
@ -211,7 +224,6 @@ When the `Show Behind Background Priority Sprites` parameter is enabled (`Y`), t
|
|||
|
||||
**Available options**:
|
||||
`disableSpriteLimit`: Forces the emulator to disable the sprite limit when the HD pack is loaded.
|
||||
`disableContours`: Disables the outline effect that appears around sprites/tiles when using the `<background>` feature.
|
||||
`disableOriginalTiles`: Normally, when a replacement for a tile is not found, the original tile is drawn. When this option is enabled, the original tiles are never drawn, only their HD replacements.
|
||||
|
||||
### <bgm> tag ###
|
||||
|
@ -309,6 +321,11 @@ These registers return the ASCII string `NEA` (NES Enhanced Audio) - this can be
|
|||
|
||||
## File Format Changelog ##
|
||||
|
||||
### Version 106 ###
|
||||
|
||||
* Replaced `Show Behind Background Priority Sprites` flag for `<background>` tags by a 0 to 39 priority level value.
|
||||
* Removed contour feature for backgrounds, and removed `disableContours` option.
|
||||
|
||||
### Version 105 ###
|
||||
|
||||
* Brightness values above 1.0 are now allowed.
|
||||
|
|
Loading…
Add table
Reference in a new issue