DS: Use the Background class for the game screen
This commit is contained in:
parent
b37843f10d
commit
7ddd7e4931
5 changed files with 156 additions and 109 deletions
|
@ -23,17 +23,32 @@
|
|||
#include <nds.h>
|
||||
|
||||
#include "backends/platform/ds/background.h"
|
||||
#include "backends/platform/ds/blitters.h"
|
||||
|
||||
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;
|
||||
if (width > 512 && !isRGB) {
|
||||
size = BgSize_B8_1024x512;
|
||||
realPitch = 1024;
|
||||
realHeight = 512;
|
||||
} else if (height > 512 && !isRGB) {
|
||||
size = BgSize_B8_512x1024;
|
||||
realPitch = 512;
|
||||
realHeight = 1024;
|
||||
} else if (height > 256) {
|
||||
if (isRGB) {
|
||||
size = BgSize_B16_512x512;
|
||||
|
@ -42,6 +57,7 @@ BgSize getBgSize(int width, int height, bool isRGB, int &realPitch) {
|
|||
size = BgSize_B8_512x512;
|
||||
realPitch = 512;
|
||||
}
|
||||
realHeight = 512;
|
||||
} else if (width > 256) {
|
||||
if (isRGB) {
|
||||
size = BgSize_B16_512x256;
|
||||
|
@ -50,6 +66,7 @@ BgSize getBgSize(int width, int height, bool isRGB, int &realPitch) {
|
|||
size = BgSize_B8_512x256;
|
||||
realPitch = 512;
|
||||
}
|
||||
realHeight = 256;
|
||||
} else if (width > 128 || height > 128) {
|
||||
if (isRGB) {
|
||||
size = BgSize_B16_256x256;
|
||||
|
@ -58,6 +75,7 @@ BgSize getBgSize(int width, int height, bool isRGB, int &realPitch) {
|
|||
size = BgSize_B8_256x256;
|
||||
realPitch = 256;
|
||||
}
|
||||
realHeight = 256;
|
||||
} else {
|
||||
if (isRGB) {
|
||||
size = BgSize_B16_128x128;
|
||||
|
@ -66,42 +84,133 @@ BgSize getBgSize(int width, int height, bool isRGB, int &realPitch) {
|
|||
size = BgSize_B8_128x128;
|
||||
realPitch = 128;
|
||||
}
|
||||
realHeight = 128;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
void Background::create(uint16 width, uint16 height, bool isRGB, int layer, bool isSub, int mapBase) {
|
||||
const Graphics::PixelFormat f = isRGB ? Graphics::PixelFormat(2, 5, 5, 5, 1, 0, 5, 10, 15) : Graphics::PixelFormat::createFormatCLUT8();
|
||||
size_t Background::getRequiredVRAM(uint16 width, uint16 height, bool isRGB, bool swScale) {
|
||||
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);
|
||||
|
||||
BgType type = isRGB ? BgType_Bmp16 : BgType_Bmp8;
|
||||
BgSize size = getBgSize(width, height, isRGB, _realPitch);
|
||||
BgType type = (isRGB || swScale) ? BgType_Bmp16 : BgType_Bmp8;
|
||||
BgSize size = getBgSize(width, height, isRGB, swScale, _realPitch, _realHeight);
|
||||
|
||||
if (isSub) {
|
||||
_bg = bgInitSub(layer, type, size, mapBase, 0);
|
||||
} else {
|
||||
_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() {
|
||||
u16 *src = (u16 *)getPixels();
|
||||
if (_bg < 0)
|
||||
return;
|
||||
|
||||
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() {
|
||||
if (_bg < 0)
|
||||
return;
|
||||
|
||||
u16 *dst = bgGetGfxPtr(_bg);
|
||||
dmaFillHalfWords(0, dst, _realPitch * h);
|
||||
}
|
||||
|
||||
void Background::show() {
|
||||
bgShow(_bg);
|
||||
if (_bg >= 0)
|
||||
bgShow(_bg);
|
||||
_visible = true;
|
||||
}
|
||||
|
||||
void Background::hide() {
|
||||
bgHide(_bg);
|
||||
if (_bg >= 0)
|
||||
bgHide(_bg);
|
||||
_visible = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,13 @@ namespace DS {
|
|||
|
||||
class Background : public Graphics::Surface {
|
||||
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 reset();
|
||||
|
@ -51,8 +57,9 @@ public:
|
|||
|
||||
protected:
|
||||
int _bg;
|
||||
bool _visible;
|
||||
int _realPitch;
|
||||
bool _visible, _swScale;
|
||||
uint16 _realPitch, _realHeight;
|
||||
const Graphics::PixelFormat _pfCLUT8, _pfABGR1555;
|
||||
};
|
||||
|
||||
} // End of namespace DS
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include <nds.h>
|
||||
|
||||
#include "backends/platform/ds/osystem_ds.h"
|
||||
#include "backends/platform/ds/blitters.h"
|
||||
|
||||
#include "common/translation.h"
|
||||
|
||||
|
@ -83,24 +82,17 @@ void setTopScreenTarget(int x, int y) {
|
|||
subScTargetY <<=8;
|
||||
}
|
||||
|
||||
void setGameSize(int width, int height, bool isRGB) {
|
||||
void setGameSize(int width, int height) {
|
||||
gameWidth = width;
|
||||
gameHeight = height;
|
||||
|
||||
vramSetBankB(VRAM_B_MAIN_BG_0x06020000);
|
||||
vramSetBankD(VRAM_D_MAIN_BG_0x06040000);
|
||||
|
||||
if (g_system->getGraphicsMode() == GFX_SWSCALE) {
|
||||
REG_BG3CNT = BG_BMP16_256x256 | BG_BMP_BASE(8);
|
||||
|
||||
REG_BG3PA = 256;
|
||||
REG_BG3PB = 0;
|
||||
REG_BG3PC = 0;
|
||||
REG_BG3PD = (int) ((200.0f / 192.0f) * 256);
|
||||
|
||||
} else {
|
||||
REG_BG3CNT = (isRGB ? BG_BMP16_512x256 :BG_BMP8_512x256) | BG_BMP_BASE(8);
|
||||
|
||||
REG_BG3PA = (int) (((float) (gameWidth) / 256.0f) * 256);
|
||||
REG_BG3PB = 0;
|
||||
REG_BG3PC = 0;
|
||||
|
@ -108,8 +100,6 @@ void setGameSize(int width, int height, bool isRGB) {
|
|||
}
|
||||
|
||||
#ifdef DISABLE_TEXT_CONSOLE
|
||||
REG_BG3CNT_SUB = BG_BMP8_512x256;
|
||||
|
||||
REG_BG3PA_SUB = (int) (subScreenWidth / 256.0f * 256);
|
||||
REG_BG3PB_SUB = 0;
|
||||
REG_BG3PC_SUB = 0;
|
||||
|
@ -281,6 +271,8 @@ void initHardware() {
|
|||
|
||||
videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);
|
||||
vramSetBankA(VRAM_A_MAIN_BG_0x06000000);
|
||||
vramSetBankB(VRAM_B_MAIN_BG_0x06020000);
|
||||
vramSetBankD(VRAM_D_MAIN_BG_0x06040000);
|
||||
vramSetBankE(VRAM_E_MAIN_SPRITE);
|
||||
|
||||
scX = 0;
|
||||
|
@ -314,7 +306,7 @@ void OSystem_DS::initGraphics() {
|
|||
oamInit(&oamMain, SpriteMapping_Bmp_1D_128, false);
|
||||
_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) {
|
||||
|
@ -404,17 +396,27 @@ Common::List<Graphics::PixelFormat> OSystem_DS::getSupportedFormats() const {
|
|||
|
||||
void OSystem_DS::initSize(uint width, uint height, const Graphics::PixelFormat *format) {
|
||||
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.
|
||||
// In order to support this game, the screen mode is set, but
|
||||
// all draw calls are ignored until the game switches to 320x200.
|
||||
if ((width == 640) && (height == 400)) {
|
||||
_graphicsEnable = false;
|
||||
if (_framebuffer.getRequiredVRAM(width, height, isRGB, swScale) > 0x40000) {
|
||||
_framebuffer.create(width, height, isRGB);
|
||||
} else {
|
||||
_graphicsEnable = true;
|
||||
DS::setGameSize(width, height, (actualFormat != _pfCLUT8));
|
||||
_framebuffer.reset();
|
||||
_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() {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
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() {
|
||||
oamSet(&oamMain, 0, _cursorPos.x - _cursorHotX, _cursorPos.y - _cursorHotY, 0, 15, SpriteSize_64x64,
|
||||
SpriteColorFormat_Bmp, _cursorSprite, 0, false, !_cursorVisible, false, false, false);
|
||||
|
@ -523,34 +494,11 @@ void OSystem_DS::updateScreen() {
|
|||
|
||||
if (_overlay.isVisible()) {
|
||||
_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 {
|
||||
Rescale_320x256x1555_To_256x256x1555(
|
||||
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);
|
||||
|
||||
} else {
|
||||
_framebuffer.update();
|
||||
#ifdef DISABLE_TEXT_CONSOLE
|
||||
if (_framebuffer.format == _pfCLUT8)
|
||||
dmaCopy(base, BG_GFX_SUB, 512 * 256);
|
||||
_subScreen.update();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -45,9 +45,8 @@
|
|||
OSystem_DS *OSystem_DS::_instance = NULL;
|
||||
|
||||
OSystem_DS::OSystem_DS()
|
||||
: _eventSource(NULL), _isOverlayShown(true),
|
||||
: _eventSource(NULL), _disableCursorPalette(true),
|
||||
_graphicsMode(GFX_HWSCALE), _stretchMode(100),
|
||||
_disableCursorPalette(true), _graphicsEnable(true),
|
||||
_pfCLUT8(Graphics::PixelFormat::createFormatCLUT8()),
|
||||
_pfABGR1555(Graphics::PixelFormat(2, 5, 5, 5, 1, 0, 5, 10, 15)),
|
||||
_callbackTimer(10), _currentTimeMillis(0)
|
||||
|
@ -130,18 +129,6 @@ void OSystem_DS::getTimeAndDate(TimeDate &td) const {
|
|||
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) {
|
||||
#ifndef DISABLE_TEXT_CONSOLE
|
||||
printf("%s", message);
|
||||
|
|
|
@ -39,9 +39,11 @@ enum {
|
|||
|
||||
class OSystem_DS : public ModularMutexBackend, public ModularMixerBackend, public PaletteManager {
|
||||
protected:
|
||||
DS::Background _overlay;
|
||||
Graphics::Surface _framebuffer, _cursor;
|
||||
bool _graphicsEnable, _isOverlayShown;
|
||||
DS::Background _framebuffer, _overlay;
|
||||
#ifdef DISABLE_TEXT_CONSOLE
|
||||
DS::Background _subScreen;
|
||||
#endif
|
||||
Graphics::Surface _cursor;
|
||||
int _graphicsMode, _stretchMode;
|
||||
|
||||
static OSystem_DS *_instance;
|
||||
|
@ -60,9 +62,6 @@ protected:
|
|||
|
||||
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;
|
||||
|
||||
const Graphics::PixelFormat _pfCLUT8, _pfABGR1555;
|
||||
|
@ -138,9 +137,6 @@ public:
|
|||
virtual void setFocusRectangle(const Common::Rect& rect);
|
||||
virtual void clearFocusRectangle();
|
||||
|
||||
virtual void engineInit();
|
||||
virtual void engineDone();
|
||||
|
||||
virtual void initBackend();
|
||||
|
||||
virtual Graphics::Surface *lockScreen();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue