DS: Use the Background class for the game screen

This commit is contained in:
Cameron Cawley 2020-12-05 17:04:44 +00:00 committed by Eugene Sandulenko
parent b37843f10d
commit 7ddd7e4931
5 changed files with 156 additions and 109 deletions

View file

@ -23,17 +23,32 @@
#include <nds.h> #include <nds.h>
#include "backends/platform/ds/background.h" #include "backends/platform/ds/background.h"
#include "backends/platform/ds/blitters.h"
namespace DS { namespace DS {
BgSize getBgSize(int width, int height, bool isRGB, int &realPitch) { Background::Background() :
_bg(-1), _visible(true), _swScale(false),
_realPitch(0), _realHeight(0),
_pfCLUT8(Graphics::PixelFormat::createFormatCLUT8()),
_pfABGR1555(Graphics::PixelFormat(2, 5, 5, 5, 1, 0, 5, 10, 15)) {
}
static BgSize getBgSize(uint16 width, uint16 height, bool isRGB, bool swScale, uint16 &realPitch, uint16 &realHeight) {
if (swScale) {
isRGB = true;
width = (width * 4) / 5;
}
BgSize size; BgSize size;
if (width > 512 && !isRGB) { if (width > 512 && !isRGB) {
size = BgSize_B8_1024x512; size = BgSize_B8_1024x512;
realPitch = 1024; realPitch = 1024;
realHeight = 512;
} else if (height > 512 && !isRGB) { } else if (height > 512 && !isRGB) {
size = BgSize_B8_512x1024; size = BgSize_B8_512x1024;
realPitch = 512; realPitch = 512;
realHeight = 1024;
} else if (height > 256) { } else if (height > 256) {
if (isRGB) { if (isRGB) {
size = BgSize_B16_512x512; size = BgSize_B16_512x512;
@ -42,6 +57,7 @@ BgSize getBgSize(int width, int height, bool isRGB, int &realPitch) {
size = BgSize_B8_512x512; size = BgSize_B8_512x512;
realPitch = 512; realPitch = 512;
} }
realHeight = 512;
} else if (width > 256) { } else if (width > 256) {
if (isRGB) { if (isRGB) {
size = BgSize_B16_512x256; size = BgSize_B16_512x256;
@ -50,6 +66,7 @@ BgSize getBgSize(int width, int height, bool isRGB, int &realPitch) {
size = BgSize_B8_512x256; size = BgSize_B8_512x256;
realPitch = 512; realPitch = 512;
} }
realHeight = 256;
} else if (width > 128 || height > 128) { } else if (width > 128 || height > 128) {
if (isRGB) { if (isRGB) {
size = BgSize_B16_256x256; size = BgSize_B16_256x256;
@ -58,6 +75,7 @@ BgSize getBgSize(int width, int height, bool isRGB, int &realPitch) {
size = BgSize_B8_256x256; size = BgSize_B8_256x256;
realPitch = 256; realPitch = 256;
} }
realHeight = 256;
} else { } else {
if (isRGB) { if (isRGB) {
size = BgSize_B16_128x128; size = BgSize_B16_128x128;
@ -66,41 +84,132 @@ BgSize getBgSize(int width, int height, bool isRGB, int &realPitch) {
size = BgSize_B8_128x128; size = BgSize_B8_128x128;
realPitch = 128; realPitch = 128;
} }
realHeight = 128;
} }
return size; return size;
} }
void Background::create(uint16 width, uint16 height, bool isRGB, int layer, bool isSub, int mapBase) { size_t Background::getRequiredVRAM(uint16 width, uint16 height, bool isRGB, bool swScale) {
const Graphics::PixelFormat f = isRGB ? Graphics::PixelFormat(2, 5, 5, 5, 1, 0, 5, 10, 15) : Graphics::PixelFormat::createFormatCLUT8(); uint16 realPitch, realHeight;
/* BgSize size = */ getBgSize(width, height, isRGB, swScale, realPitch, realHeight);
return realPitch * realHeight;
}
void Background::create(uint16 width, uint16 height, bool isRGB) {
const Graphics::PixelFormat f = isRGB ? _pfABGR1555 : _pfCLUT8;
Surface::create(width, height, f);
_bg = -1;
_swScale = false;
}
void Background::create(uint16 width, uint16 height, bool isRGB, int layer, bool isSub, int mapBase, bool swScale) {
const Graphics::PixelFormat f = isRGB ? _pfABGR1555 : _pfCLUT8;
Surface::create(width, height, f); Surface::create(width, height, f);
BgType type = isRGB ? BgType_Bmp16 : BgType_Bmp8; BgType type = (isRGB || swScale) ? BgType_Bmp16 : BgType_Bmp8;
BgSize size = getBgSize(width, height, isRGB, _realPitch); BgSize size = getBgSize(width, height, isRGB, swScale, _realPitch, _realHeight);
if (isSub) { if (isSub) {
_bg = bgInitSub(layer, type, size, mapBase, 0); _bg = bgInitSub(layer, type, size, mapBase, 0);
} else { } else {
_bg = bgInit(layer, type, size, mapBase, 0); _bg = bgInit(layer, type, size, mapBase, 0);
} }
_swScale = swScale;
}
void Background::init(Background *surface) {
Surface::init(surface->w, surface->h, surface->pitch, surface->pixels, surface->format);
_bg = -1;
_swScale = false;
}
void Background::init(Background *surface, int layer, bool isSub, int mapBase, bool swScale) {
Surface::init(surface->w, surface->h, surface->pitch, surface->pixels, surface->format);
bool isRGB = (format != _pfCLUT8);
BgType type = (isRGB || swScale) ? BgType_Bmp16 : BgType_Bmp8;
BgSize size = getBgSize(w, h, isRGB, swScale, _realPitch, _realHeight);
if (isSub) {
_bg = bgInitSub(layer, type, size, mapBase, 0);
} else {
_bg = bgInit(layer, type, size, mapBase, 0);
}
_swScale = swScale;
}
static void dmaBlit(uint16 *dst, const uint dstPitch, const uint16 *src, const uint srcPitch,
const uint w, const uint h, const uint bytesPerPixel) {
if (dstPitch == srcPitch && ((w * bytesPerPixel) == dstPitch)) {
dmaCopy(src, dst, dstPitch * h);
return;
}
// The DS video RAM doesn't support 8-bit writes because Nintendo wanted
// to save a few pennies/euro cents on the hardware.
uint row = w * bytesPerPixel;
for (uint dy = 0; dy < h; dy += 2) {
const u16 *src1 = src;
src += (srcPitch >> 1);
DC_FlushRange(src1, row << 1);
const u16 *src2 = src;
src += (srcPitch >> 1);
DC_FlushRange(src2, row << 1);
u16 *dest1 = dst;
dst += (dstPitch >> 1);
DC_FlushRange(dest1, row << 1);
u16 *dest2 = dst;
dst += (dstPitch >> 1);
DC_FlushRange(dest2, row << 1);
dmaCopyHalfWordsAsynch(2, src1, dest1, row);
dmaCopyHalfWordsAsynch(3, src2, dest2, row);
while (dmaBusy(2) || dmaBusy(3));
}
} }
void Background::update() { void Background::update() {
u16 *src = (u16 *)getPixels(); if (_bg < 0)
return;
u16 *dst = bgGetGfxPtr(_bg); u16 *dst = bgGetGfxPtr(_bg);
dmaCopy(src, dst, _realPitch * h); if (_swScale) {
if (format == _pfCLUT8) {
Rescale_320x256xPAL8_To_256x256x1555(
dst, (const u8 *)getPixels(), _realPitch / 2, pitch, BG_PALETTE, h);
} else {
Rescale_320x256x1555_To_256x256x1555(
dst, (const u16 *)getPixels(), _realPitch / 2, pitch / 2);
}
} else {
dmaBlit(dst, _realPitch, (const u16 *)getPixels(), pitch, w, h, format.bytesPerPixel);
}
} }
void Background::reset() { void Background::reset() {
if (_bg < 0)
return;
u16 *dst = bgGetGfxPtr(_bg); u16 *dst = bgGetGfxPtr(_bg);
dmaFillHalfWords(0, dst, _realPitch * h); dmaFillHalfWords(0, dst, _realPitch * h);
} }
void Background::show() { void Background::show() {
if (_bg >= 0)
bgShow(_bg); bgShow(_bg);
_visible = true; _visible = true;
} }
void Background::hide() { void Background::hide() {
if (_bg >= 0)
bgHide(_bg); bgHide(_bg);
_visible = false; _visible = false;
} }

View file

@ -29,7 +29,13 @@ namespace DS {
class Background : public Graphics::Surface { class Background : public Graphics::Surface {
public: public:
void create(uint16 width, uint16 height, bool isRGB, int layer, bool isSub, int mapBase); Background();
size_t getRequiredVRAM(uint16 width, uint16 height, bool isRGB, bool swScale);
void create(uint16 width, uint16 height, bool isRGB);
void create(uint16 width, uint16 height, bool isRGB, int layer, bool isSub, int mapBase, bool swScale);
void init(Background *surface);
void init(Background *surface, int layer, bool isSub, int mapBase, bool swScale);
void update(); void update();
void reset(); void reset();
@ -51,8 +57,9 @@ public:
protected: protected:
int _bg; int _bg;
bool _visible; bool _visible, _swScale;
int _realPitch; uint16 _realPitch, _realHeight;
const Graphics::PixelFormat _pfCLUT8, _pfABGR1555;
}; };
} // End of namespace DS } // End of namespace DS

View file

@ -23,7 +23,6 @@
#include <nds.h> #include <nds.h>
#include "backends/platform/ds/osystem_ds.h" #include "backends/platform/ds/osystem_ds.h"
#include "backends/platform/ds/blitters.h"
#include "common/translation.h" #include "common/translation.h"
@ -83,24 +82,17 @@ void setTopScreenTarget(int x, int y) {
subScTargetY <<=8; subScTargetY <<=8;
} }
void setGameSize(int width, int height, bool isRGB) { void setGameSize(int width, int height) {
gameWidth = width; gameWidth = width;
gameHeight = height; gameHeight = height;
vramSetBankB(VRAM_B_MAIN_BG_0x06020000);
vramSetBankD(VRAM_D_MAIN_BG_0x06040000);
if (g_system->getGraphicsMode() == GFX_SWSCALE) { if (g_system->getGraphicsMode() == GFX_SWSCALE) {
REG_BG3CNT = BG_BMP16_256x256 | BG_BMP_BASE(8);
REG_BG3PA = 256; REG_BG3PA = 256;
REG_BG3PB = 0; REG_BG3PB = 0;
REG_BG3PC = 0; REG_BG3PC = 0;
REG_BG3PD = (int) ((200.0f / 192.0f) * 256); REG_BG3PD = (int) ((200.0f / 192.0f) * 256);
} else { } else {
REG_BG3CNT = (isRGB ? BG_BMP16_512x256 :BG_BMP8_512x256) | BG_BMP_BASE(8);
REG_BG3PA = (int) (((float) (gameWidth) / 256.0f) * 256); REG_BG3PA = (int) (((float) (gameWidth) / 256.0f) * 256);
REG_BG3PB = 0; REG_BG3PB = 0;
REG_BG3PC = 0; REG_BG3PC = 0;
@ -108,8 +100,6 @@ void setGameSize(int width, int height, bool isRGB) {
} }
#ifdef DISABLE_TEXT_CONSOLE #ifdef DISABLE_TEXT_CONSOLE
REG_BG3CNT_SUB = BG_BMP8_512x256;
REG_BG3PA_SUB = (int) (subScreenWidth / 256.0f * 256); REG_BG3PA_SUB = (int) (subScreenWidth / 256.0f * 256);
REG_BG3PB_SUB = 0; REG_BG3PB_SUB = 0;
REG_BG3PC_SUB = 0; REG_BG3PC_SUB = 0;
@ -281,6 +271,8 @@ void initHardware() {
videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE); videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);
vramSetBankA(VRAM_A_MAIN_BG_0x06000000); vramSetBankA(VRAM_A_MAIN_BG_0x06000000);
vramSetBankB(VRAM_B_MAIN_BG_0x06020000);
vramSetBankD(VRAM_D_MAIN_BG_0x06040000);
vramSetBankE(VRAM_E_MAIN_SPRITE); vramSetBankE(VRAM_E_MAIN_SPRITE);
scX = 0; scX = 0;
@ -314,7 +306,7 @@ void OSystem_DS::initGraphics() {
oamInit(&oamMain, SpriteMapping_Bmp_1D_128, false); oamInit(&oamMain, SpriteMapping_Bmp_1D_128, false);
_cursorSprite = oamAllocateGfx(&oamMain, SpriteSize_64x64, SpriteColorFormat_Bmp); _cursorSprite = oamAllocateGfx(&oamMain, SpriteSize_64x64, SpriteColorFormat_Bmp);
_overlay.create(256, 192, true, 2, false, 0); _overlay.create(256, 192, true, 2, false, 0, false);
} }
bool OSystem_DS::hasFeature(Feature f) { bool OSystem_DS::hasFeature(Feature f) {
@ -404,17 +396,27 @@ Common::List<Graphics::PixelFormat> OSystem_DS::getSupportedFormats() const {
void OSystem_DS::initSize(uint width, uint height, const Graphics::PixelFormat *format) { void OSystem_DS::initSize(uint width, uint height, const Graphics::PixelFormat *format) {
Graphics::PixelFormat actualFormat = format ? *format : _pfCLUT8; Graphics::PixelFormat actualFormat = format ? *format : _pfCLUT8;
_framebuffer.create(width, height, actualFormat); bool isRGB = (actualFormat != _pfCLUT8), swScale = ((_graphicsMode == GFX_SWSCALE) && (width == 320));
// For Lost in Time, the title screen is displayed in 640x400. // For Lost in Time, the title screen is displayed in 640x400.
// In order to support this game, the screen mode is set, but // In order to support this game, the screen mode is set, but
// all draw calls are ignored until the game switches to 320x200. // all draw calls are ignored until the game switches to 320x200.
if ((width == 640) && (height == 400)) { if (_framebuffer.getRequiredVRAM(width, height, isRGB, swScale) > 0x40000) {
_graphicsEnable = false; _framebuffer.create(width, height, isRGB);
} else { } else {
_graphicsEnable = true; _framebuffer.reset();
DS::setGameSize(width, height, (actualFormat != _pfCLUT8)); _framebuffer.create(width, height, isRGB, 3, false, 8, swScale);
DS::setGameSize(width, height);
} }
#ifdef DISABLE_TEXT_CONSOLE
if (_framebuffer.getRequiredVRAM(width, height, isRGB, false) > 0x20000) {
_subScreen.init(&_framebuffer);
} else {
_subScreen.reset();
_subScreen.init(&_framebuffer, 3, true, 0, false);
}
#endif
} }
int16 OSystem_DS::getHeight() { int16 OSystem_DS::getHeight() {
@ -485,37 +487,6 @@ void OSystem_DS::copyRectToScreen(const void *buf, int pitch, int x, int y, int
_framebuffer.copyRectToSurface(buf, pitch, x, y, w, h); _framebuffer.copyRectToSurface(buf, pitch, x, y, w, h);
} }
void OSystem_DS::dmaBlit(uint16 *dst, const uint dstPitch, const uint16 *src, const uint srcPitch,
const uint w, const uint h, const uint bytesPerPixel) {
// The DS video RAM doesn't support 8-bit writes because Nintendo wanted
// to save a few pennies/euro cents on the hardware.
uint row = w * bytesPerPixel;
for (uint dy = 0; dy < h; dy += 2) {
const u16 *src1 = src;
src += (srcPitch >> 1);
DC_FlushRange(src1, row << 1);
const u16 *src2 = src;
src += (srcPitch >> 1);
DC_FlushRange(src2, row << 1);
u16 *dest1 = dst;
dst += (dstPitch >> 1);
DC_FlushRange(dest1, row << 1);
u16 *dest2 = dst;
dst += (dstPitch >> 1);
DC_FlushRange(dest2, row << 1);
dmaCopyHalfWordsAsynch(2, src1, dest1, row);
dmaCopyHalfWordsAsynch(3, src2, dest2, row);
while (dmaBusy(2) || dmaBusy(3));
}
}
void OSystem_DS::updateScreen() { void OSystem_DS::updateScreen() {
oamSet(&oamMain, 0, _cursorPos.x - _cursorHotX, _cursorPos.y - _cursorHotY, 0, 15, SpriteSize_64x64, oamSet(&oamMain, 0, _cursorPos.x - _cursorHotX, _cursorPos.y - _cursorHotY, 0, 15, SpriteSize_64x64,
SpriteColorFormat_Bmp, _cursorSprite, 0, false, !_cursorVisible, false, false, false); SpriteColorFormat_Bmp, _cursorSprite, 0, false, !_cursorVisible, false, false, false);
@ -523,36 +494,13 @@ void OSystem_DS::updateScreen() {
if (_overlay.isVisible()) { if (_overlay.isVisible()) {
_overlay.update(); _overlay.update();
} else if (_graphicsEnable) {
u16 *base = BG_GFX + 0x10000;
if (_graphicsMode == GFX_SWSCALE) {
if (_framebuffer.format == _pfCLUT8) {
Rescale_320x256xPAL8_To_256x256x1555(
base,
(const u8 *)_framebuffer.getPixels(),
256,
_framebuffer.pitch,
BG_PALETTE,
_framebuffer.h );
} else { } else {
Rescale_320x256x1555_To_256x256x1555( _framebuffer.update();
base,
(const u16 *)_framebuffer.getPixels(),
256,
_framebuffer.pitch / 2 );
}
} else {
dmaBlit(base, 512 * _framebuffer.format.bytesPerPixel,
(const u16 *)_framebuffer.getPixels(), _framebuffer.pitch,
_framebuffer.w, _framebuffer.h, _framebuffer.format.bytesPerPixel);
#ifdef DISABLE_TEXT_CONSOLE #ifdef DISABLE_TEXT_CONSOLE
if (_framebuffer.format == _pfCLUT8) _subScreen.update();
dmaCopy(base, BG_GFX_SUB, 512 * 256);
#endif #endif
} }
} }
}
void OSystem_DS::setShakePos(int shakeXOffset, int shakeYOffset) { void OSystem_DS::setShakePos(int shakeXOffset, int shakeYOffset) {
DS::setShakePos(shakeXOffset, shakeYOffset); DS::setShakePos(shakeXOffset, shakeYOffset);

View file

@ -45,9 +45,8 @@
OSystem_DS *OSystem_DS::_instance = NULL; OSystem_DS *OSystem_DS::_instance = NULL;
OSystem_DS::OSystem_DS() OSystem_DS::OSystem_DS()
: _eventSource(NULL), _isOverlayShown(true), : _eventSource(NULL), _disableCursorPalette(true),
_graphicsMode(GFX_HWSCALE), _stretchMode(100), _graphicsMode(GFX_HWSCALE), _stretchMode(100),
_disableCursorPalette(true), _graphicsEnable(true),
_pfCLUT8(Graphics::PixelFormat::createFormatCLUT8()), _pfCLUT8(Graphics::PixelFormat::createFormatCLUT8()),
_pfABGR1555(Graphics::PixelFormat(2, 5, 5, 5, 1, 0, 5, 10, 15)), _pfABGR1555(Graphics::PixelFormat(2, 5, 5, 5, 1, 0, 5, 10, 15)),
_callbackTimer(10), _currentTimeMillis(0) _callbackTimer(10), _currentTimeMillis(0)
@ -130,18 +129,6 @@ void OSystem_DS::getTimeAndDate(TimeDate &td) const {
void OSystem_DS::quit() { void OSystem_DS::quit() {
} }
void OSystem_DS::engineInit() {
#ifdef DISABLE_TEXT_CONSOLE
videoBgEnableSub(3);
#endif
}
void OSystem_DS::engineDone() {
#ifdef DISABLE_TEXT_CONSOLE
videoBgDisableSub(3);
#endif
}
void OSystem_DS::logMessage(LogMessageType::Type type, const char *message) { void OSystem_DS::logMessage(LogMessageType::Type type, const char *message) {
#ifndef DISABLE_TEXT_CONSOLE #ifndef DISABLE_TEXT_CONSOLE
printf("%s", message); printf("%s", message);

View file

@ -39,9 +39,11 @@ enum {
class OSystem_DS : public ModularMutexBackend, public ModularMixerBackend, public PaletteManager { class OSystem_DS : public ModularMutexBackend, public ModularMixerBackend, public PaletteManager {
protected: protected:
DS::Background _overlay; DS::Background _framebuffer, _overlay;
Graphics::Surface _framebuffer, _cursor; #ifdef DISABLE_TEXT_CONSOLE
bool _graphicsEnable, _isOverlayShown; DS::Background _subScreen;
#endif
Graphics::Surface _cursor;
int _graphicsMode, _stretchMode; int _graphicsMode, _stretchMode;
static OSystem_DS *_instance; static OSystem_DS *_instance;
@ -60,9 +62,6 @@ protected:
void initGraphics(); void initGraphics();
void dmaBlit(uint16 *dst, const uint dstPitch, const uint16 *src, const uint srcPitch,
const uint w, const uint h, const uint bytesPerPixel);
bool _disableCursorPalette; bool _disableCursorPalette;
const Graphics::PixelFormat _pfCLUT8, _pfABGR1555; const Graphics::PixelFormat _pfCLUT8, _pfABGR1555;
@ -138,9 +137,6 @@ public:
virtual void setFocusRectangle(const Common::Rect& rect); virtual void setFocusRectangle(const Common::Rect& rect);
virtual void clearFocusRectangle(); virtual void clearFocusRectangle();
virtual void engineInit();
virtual void engineDone();
virtual void initBackend(); virtual void initBackend();
virtual Graphics::Surface *lockScreen(); virtual Graphics::Surface *lockScreen();