Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

View File

@@ -0,0 +1,259 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <portdefs.h> // Protect uintXX typedefs
#include <nds.h>
#include "backends/platform/ds/background.h"
#include "backends/platform/ds/blitters.h"
#include "graphics/surface.h"
namespace DS {
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;
realPitch = 1024;
} else {
size = BgSize_B8_512x512;
realPitch = 512;
}
realHeight = 512;
} else if (width > 256) {
if (isRGB) {
size = BgSize_B16_512x256;
realPitch = 1024;
} else {
size = BgSize_B8_512x256;
realPitch = 512;
}
realHeight = 256;
} else if (width > 128 || height > 128) {
if (isRGB) {
size = BgSize_B16_256x256;
realPitch = 512;
} else {
size = BgSize_B8_256x256;
realPitch = 256;
}
realHeight = 256;
} else {
if (isRGB) {
size = BgSize_B16_128x128;
realPitch = 256;
} else {
size = BgSize_B8_128x128;
realPitch = 128;
}
realHeight = 128;
}
return size;
}
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;
}
Background::Background(Graphics::Surface *surface, int layer, bool isSub, int mapBase, bool swScale) :
_bg(-1), _visible(true), _swScale(swScale),
_scaleX(1 << 8), _scaleY(1 << 8), _scrollX(0), _scrollY(0),
_surface(surface), _pitch(0) {
assert(_surface);
uint16 realPitch, realHeight;
bool isRGB = !_surface->format.isCLUT8();
BgType type = (isRGB || swScale) ? BgType_Bmp16 : BgType_Bmp8;
BgSize size = getBgSize(_surface->w, _surface->h, isRGB, swScale, realPitch, realHeight);
if (isSub) {
_bg = bgInitSub(layer, type, size, mapBase, 0);
} else {
_bg = bgInit(layer, type, size, mapBase, 0);
}
_pitch = realPitch;
}
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)) {
DC_FlushRange(src, dstPitch * h);
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() {
if (_bg < 0)
return;
u16 *dst = bgGetGfxPtr(_bg);
if (_swScale) {
if (_surface->format == Graphics::PixelFormat::createFormatCLUT8()) {
Rescale_320x256xPAL8_To_256x256x1555(
dst, (const u8 *)_surface->getPixels(), _pitch / 2, _surface->pitch, BG_PALETTE, _surface->h);
} else {
Rescale_320x256x1555_To_256x256x1555(
dst, (const u16 *)_surface->getPixels(), _pitch / 2, _surface->pitch / 2);
}
} else {
dmaBlit(dst, _pitch, (const u16 *)_surface->getPixels(), _surface->pitch, _surface->w, _surface->h, _surface->format.bytesPerPixel);
}
}
void Background::reset() {
if (_bg < 0)
return;
u16 *dst = bgGetGfxPtr(_bg);
dmaFillHalfWords(0, dst, _pitch * _surface->h);
}
void Background::show() {
if (_bg >= 0)
bgShow(_bg);
_visible = true;
}
void Background::hide() {
if (_bg >= 0)
bgHide(_bg);
_visible = false;
}
void Background::setScalef(int32 sx, int32 sy) {
if (_bg < 0 || (_scaleX == sx && _scaleY == sy))
return;
bgSetScale(_bg, _swScale ? 256 : sx, sy);
_scaleX = sx;
_scaleY = sy;
}
void Background::setScrollf(int32 x, int32 y) {
if (_bg < 0 || (_scrollX == x && _scrollY == y))
return;
bgSetScrollf(_bg, x, y);
_scrollX = x;
_scrollY = y;
}
Common::Point Background::realToScaled(int16 x, int16 y) const {
x = CLIP<int16>(((x * _scaleX) + _scrollX) >> 8, 0, _surface->w - 1);
y = CLIP<int16>(((y * _scaleY) + _scrollY) >> 8, 0, _surface->h - 1);
return Common::Point(x, y);
}
Common::Point Background::scaledToReal(int16 x, int16 y) const {
x = ((x << 8) - _scrollX) / _scaleX;
y = ((y << 8) - _scrollY) / _scaleY;
return Common::Point(x, y);
}
TiledBackground::TiledBackground(const unsigned int *tiles, size_t tilesLen, const unsigned short *map, size_t mapLen, int layer, bool isSub, int mapBase, int tileBase) :
_tiles(tiles), _tilesLen(tilesLen), _map(map), _mapLen(mapLen),
_bg(-1), _visible(true) {
if (isSub) {
_bg = bgInitSub(layer, BgType_Text8bpp, BgSize_T_256x256, mapBase, tileBase);
} else {
_bg = bgInit(layer, BgType_Text8bpp, BgSize_T_256x256, mapBase, tileBase);
}
}
void TiledBackground::update() {
if (_bg < 0)
return;
// Tiles come from code memory: they don't need to be flushed
dmaCopy(_tiles, bgGetGfxPtr(_bg), _tilesLen);
dmaCopy(_map, bgGetMapPtr(_bg), _mapLen);
}
void TiledBackground::reset() {
if (_bg < 0)
return;
dmaFillHalfWords(0, bgGetMapPtr(_bg), _mapLen);
dmaFillHalfWords(0, bgGetGfxPtr(_bg), _tilesLen);
}
void TiledBackground::show() {
if (_bg >= 0)
bgShow(_bg);
_visible = true;
}
void TiledBackground::hide() {
if (_bg >= 0)
bgHide(_bg);
_visible = false;
}
} // End of namespace DS

View File

@@ -0,0 +1,84 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef DS_BACKGROUND_H
#define DS_BACKGROUND_H
#include "common/rect.h"
namespace Graphics {
struct Surface;
}
namespace DS {
class Background {
public:
Background(Graphics::Surface *surface, int layer, bool isSub, int mapBase, bool swScale);
static size_t getRequiredVRAM(uint16 width, uint16 height, bool isRGB, bool swScale);
void update();
void reset();
void show();
void hide();
inline bool isVisible() const { return _visible; }
void setScalef(int32 sx, int32 sy);
inline void setScale(int sx, int sy) { setScalef(sx << 8, sy << 8); }
void setScrollf(int32 x, int32 y);
inline void setScroll(int x, int y) { setScrollf(x << 8, y << 8); }
Common::Point realToScaled(int16 x, int16 y) const;
Common::Point scaledToReal(int16 x, int16 y) const;
protected:
int _bg;
bool _visible, _swScale;
uint16 _pitch;
int32 _scrollX, _scrollY, _scaleX, _scaleY;
Graphics::Surface *_surface;
};
class TiledBackground {
public:
TiledBackground(const unsigned int *tiles, size_t tilesLen, const unsigned short *map, size_t mapLen, int layer, bool isSub, int mapBase, int tileBase);
void update();
void reset();
void show();
void hide();
inline bool isVisible() const { return _visible; }
protected:
const unsigned int *_tiles;
const unsigned short *_map;
size_t _tilesLen, _mapLen;
int _bg;
bool _visible;
};
} // End of namespace DS
#endif // #ifndef DS_BACKGROUND_H

View File

@@ -0,0 +1,32 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef _BLITTERS_H_
#define _BLITTERS_H_
extern "C" {
void ITCM_CODE Rescale_320x256xPAL8_To_256x256x1555(u16 *dest, const u8 *src, int destStride, int srcStride, const u16 *palette, u32 numLines);
void ITCM_CODE Rescale_320x256x1555_To_256x256x1555(u16 *dest, const u16 *src, int destStride, int srcStride);
}
#endif

View File

@@ -0,0 +1,282 @@
@ ScummVM - Graphic Adventure Engine
@
@ ScummVM is the legal property of its developers, whose names
@ are too numerous to list here. Please refer to the COPYRIGHT
@ file distributed with this source distribution.
@
@ This program is free software: you can redistribute it and/or modify
@ it under the terms of the GNU General Public License as published by
@ the Free Software Foundation, either version 3 of the License, or
@ (at your option) any later version.
@
@ This program is distributed in the hope that it will be useful,
@ but WITHOUT ANY WARRANTY; without even the implied warranty of
@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ GNU General Public License for more details.
@
@ You should have received a copy of the GNU General Public License
@ along with this program. If not, see <http://www.gnu.org/licenses/>.
@
@ @author Robin Watts (robin@wss.co.uk)
.global Rescale_320x256xPAL8_To_256x256x1555
.global Rescale_320x256x1555_To_256x256x1555
@ .section .itcm,"ax", %progbits
.align 2
.code 32
@ ARM implementation of Rescale_320x256x1555_To_256x256x1555
@
@ C prototype would be:
@
@ extern "C" void Rescale_320x256x1555_To_256x256x1555(
@ u16 *dst,
@ const u16 *src,
@ int dstStride,
@ int srcStride);
Rescale_320x256x1555_To_256x256x1555:
@ r0 = dst
@ r1 = src
@ r2 = dstStride
@ r3 = srcStride
STMFD r13!,{r4-r6,r8-r11,r14}
SUB r2,r2,#64*4 @ srcStride -= line length
SUB r3,r3,#64*5 @ dstStride -= line length
MOV r8, #0x0000001F
ORR r8, r8,#0x00007C00
ORR r8, r8,#0x03E00000 @ r8 = mask
MOV r6, #0x8000
ORR r6, r6, r6, LSL #16
MOV r5, #200 @ r5 = y
yLoop3:
MOV r4, #64 @ r4 = x
xLoop3:
LDRH r9, [r1],#2 @ r9 = src0
LDRH r10,[r1],#2 @ r10= src1
LDRH r11,[r1],#2 @ r11= src2
LDRH r12,[r1],#2 @ r12= src3
LDRH r14,[r1],#2 @ r14= src4
ORR r9, r9, r9, LSL #16 @ r9 = src0 | src0
ORR r10,r10,r10,LSL #16 @ r10= src1 | src1
ORR r11,r11,r11,LSL #16 @ r11= src2 | src2
ORR r12,r12,r12,LSL #16 @ r12= src3 | src3
ORR r14,r14,r14,LSL #16 @ r13= src4 | src4
AND r9, r9, r8 @ r9 = 0 | G0 | 0 | B0 | 0 | R0
AND r10,r10,r8 @ r10= 0 | G1 | 0 | B1 | 0 | R1
AND r11,r11,r8 @ r11= 0 | G2 | 0 | B2 | 0 | R2
AND r12,r12,r8 @ r12= 0 | G3 | 0 | B3 | 0 | R3
AND r14,r14,r8 @ r14= 0 | G4 | 0 | B4 | 0 | R4
ADD r9, r9, r9, LSL #1 @ r9 = 3*src0
ADD r9, r9, r10 @ r9 = dst0<<2
ADD r10,r10,r11 @ r10= dst1
ADD r11,r11,r12 @ r11= dst2
ADD r12,r12,r14 @ r12= src3 + src4
ADD r12,r12,r14,LSL #1 @ r12= src3 + src4*3 = dst3<<2
AND r9, r8, r9, LSR #2 @ r9 = dst0 (split)
AND r10,r8, r10,LSR #1 @ r10= dst1 (split)
AND r11,r8, r11,LSR #1 @ r11= dst2 (split)
AND r12,r8, r12,LSR #2 @ r12= dst3 (split)
ORR r9, r9, r9, ROR #16 @ r9 = dst0
ORR r10,r10,r10,ROR #16 @ r10= dst1
ORR r11,r11,r11,ROR #16 @ r11= dst2
ORR r12,r12,r12,ROR #16 @ r12= dst3
ORR r10,r6, r10,LSL #16
ORR r9, r10,r9, LSR #16
ORR r12,r6, r12,LSL #16
ORR r11,r12,r11,LSR #16
STMIA r0!,{r9,r11}
SUBS r4,r4,#1
BGT xLoop3
ADD r0,r0,r2,LSL #1
ADD r1,r1,r3,LSL #1
SUBS r5,r5,#1
BGT yLoop3
LDMFD r13!,{r4-r6,r8-r11,PC}
@ ARM implementation of Rescale_320x256xPAL8_To_256x256x1555
@
@ C prototype would be:
@
@ extern "C" void Rescale_320x256xPAL8_To_256x256x1555(
@ u16 *dst,
@ const u8 *src,
@ int dstStride,
@ int srcStride,
@ const u16 *pal,
@ u32 numLines);
Rescale_320x256xPAL8_To_256x256x1555:
@ r0 = dst
@ r1 = src
@ r2 = dstStride
@ r3 = srcStride
STMFD r13!,{r4-r11,r14}
MOV r8, #0x0000001F
ORR r8, r8,#0x0000FC00
ORR r8, r8,#0x03E00000 @ r8 = mask
LDR r9, [r13,#9*4] @ r9 = palette
LDR r7, [r13,#10*4] @ r7 = numLines
SUB r13,r13,#256*4 @ r13 = 1K of space on the stack.
MOV r5, r13 @ r5 points to this space
MOV r14,#256
palLoop:
LDRH r10,[r9],#2 @ r10 = palette entry
SUBS r14,r14,#1
ORR r10,r10,r10,LSL #16
AND r10,r10,r8 @ r10 = separated palette entry
ORR r10,r10,#0x00008000
STR r10,[r5], #4
BGT palLoop
SUB r2,r2,#64*4 @ srcStride -= line length
SUB r3,r3,#64*5 @ dstStride -= line length
MOV r14,#0xFF @ r14= 255
MOV r5,r7 @ r5 = numLines
yLoop4:
MOV r4,#16 @ r4 = x
xLoop4:
LDMIA r1!,{r10,r11,r12}
AND r6, r14,r10 @ r6 = src0
LDR r6, [r13,r6, LSL #2] @ r6 = pal[src0]
AND r7, r14,r10,LSR #8 @ r7 = src1
LDR r7, [r13,r7, LSL #2] @ r7 = pal[src1]
ADD r6, r6, r6, LSL #1 @ r6 = 3*pal[src0]
AND r9, r14,r10,LSR #16 @ r9 = src2
LDR r9, [r13,r9, LSL #2] @ r9 = pal[src2]
MOV r10,r10,LSR #24 @ r10= src3
LDR r10,[r13,r10,LSL #2] @ r10= pal[src3]
ADD r6, r6, r7 @ r6 = dst0<<2
AND r6, r8, r6, LSR #2 @ r6 = dst0 (split)
ORR r6, r6, r6, ROR #16 @ r6 = dst0 (in both halves)
ADD r7, r7, r9 @ r7 = dst1<<1
AND r7, r8, r7, LSR #1 @ r7 = dst1 (split)
ORR r7, r7, r7, ROR #16 @ r7 = dst1 (in both halves)
MOV r7, r7, LSL #16 @ r7 = dst1<<16
ORR r6, r7, r6, LSR #16 @ r6 = dst0 | dst1<<16
AND r7, r14,r11 @ r7 = src4
LDR r7, [r13,r7, LSL #2] @ r7 = pal[src4]
ADD r9, r9, r10 @ r9 = dst2<<1
AND r9, r8, r9, LSR #1 @ r9 = dst2 (split)
ORR r9, r9, r9, ROR #16 @ r9 = dst2 (in both halves)
ADD r10,r10,r7 @ r7 = pal[src3]+pal[src4]
ADD r10,r10,r7, LSL #1 @ r10= dst3<<2
AND r10,r8, r10,LSR #2 @ r10= dst3 (split)
ORR r10,r10,r10,ROR #16 @ r10= dst3 (in both halves)
MOV r7, r9, LSR #16
ORR r7, r7, r10, LSL #16 @ r7 = dst2 | dst3<<16
STMIA r0!,{r6,r7}
AND r6, r14,r11,LSR #8 @ r6 = src5
LDR r6, [r13,r6, LSL #2] @ r6 = pal[src5]
AND r7, r14,r11,LSR #16 @ r7 = src6
LDR r7, [r13,r7, LSL #2] @ r7 = pal[src6]
ADD r6, r6, r6, LSL #1 @ r6 = 3*pal[src5]
MOV r9, r11,LSR #24 @ r9 = src7
LDR r9, [r13,r9, LSL #2] @ r9 = pal[src7]
AND r10,r14,r12 @ r10= src8
LDR r10,[r13,r10,LSL #2] @ r10= pal[src8]
ADD r6, r6, r7 @ r6 = dst4<<2
AND r6, r8, r6, LSR #2 @ r6 = dst4 (split)
ORR r6, r6, r6, ROR #16 @ r6 = dst4 (in both halves)
ADD r7, r7, r9 @ r7 = dst5<<1
AND r7, r8, r7, LSR #1 @ r7 = dst5 (split)
ORR r7, r7, r7, ROR #16 @ r7 = dst5 (in both halves)
MOV r7, r7, LSL #16 @ r7 = dst5<<16
ORR r6, r7, r6, LSR #16 @ r6 = dst4 | dst5<<16
AND r7, r14,r12,LSR #8 @ r7 = src9
LDR r7, [r13,r7, LSL #2] @ r7 = pal[src9]
ADD r9, r9, r10 @ r9 = dst6<<1
AND r9, r8, r9, LSR #1 @ r9 = dst6 (split)
ORR r9, r9, r9, ROR #16 @ r9 = dst6 (in both halves)
ADD r10,r10,r7 @ r10= pal[src8]+pal[src9]
ADD r10,r10,r7, LSL #1 @ r10= dst7<<2
AND r10,r8, r10,LSR #2 @ r10= dst7 (split)
ORR r10,r10,r10,ROR #16 @ r10= dst7 (in both halves)
MOV r7, r9, LSR #16
ORR r7, r7, r10, LSL #16 @ r7 = dst6 | dst7<<16
LDMIA r1!,{r10,r11}
SUBS r4,r4,#1
STMIA r0!,{r6,r7}
AND r6, r14,r12,LSR #16 @ r6 = src10
LDR r6, [r13,r6, LSL #2] @ r6 = pal[src10]
MOV r7, r12,LSR #24 @ r7 = src11
LDR r7, [r13,r7, LSL #2] @ r7 = pal[src11]
ADD r6, r6, r6, LSL #1 @ r6 = 3*pal[src10]
AND r9, r14,r10 @ r9 = src12
LDR r9, [r13,r9, LSL #2] @ r9 = pal[src12]
AND r12,r14,r10,LSR #8 @ r11= src13
LDR r12,[r13,r12,LSL #2] @ r11= pal[src13]
ADD r6, r6, r7 @ r6 = dst8<<2
AND r6, r8, r6, LSR #2 @ r6 = dst8 (split)
ORR r6, r6, r6, ROR #16 @ r6 = dst8 (in both halves)
ADD r7, r7, r9 @ r7 = dst9<<1
AND r7, r8, r7, LSR #1 @ r7 = dst9 (split)
ORR r7, r7, r7, ROR #16 @ r7 = dst9 (in both halves)
MOV r7, r7, LSL #16 @ r7 = dst9<<16
ORR r6, r7, r6, LSR #16 @ r6 = dst8 | dst9<<16
AND r7, r14,r10,LSR #16 @ r7 = src14
LDR r7, [r13,r7, LSL #2] @ r7 = pal[src14]
ADD r9, r9, r12 @ r9 = dst10<<1
AND r9, r8, r9, LSR #1 @ r9 = dst10 (split)
ORR r9, r9, r9, ROR #16 @ r9 = dst10 (in both halves)
ADD r12,r12,r7 @ r12= pal[src13]+pal[src14]
ADD r12,r12,r7, LSL #1 @ r12= dst11<<2
AND r12,r8, r12,LSR #2 @ r12= dst11 (split)
ORR r12,r12,r12,ROR #16 @ r12= dst11 (in both halves)
MOV r7, r9, LSR #16
ORR r7, r7, r12, LSL #16 @ r7 = dst10 | dst11<<16
STMIA r0!,{r6,r7}
MOV r6, r10,LSR #24 @ r6 = src15
LDR r6, [r13,r6, LSL #2] @ r6 = pal[src15]
AND r7, r14,r11 @ r7 = src16
LDR r7, [r13,r7, LSL #2] @ r7 = pal[src16]
ADD r6, r6, r6, LSL #1 @ r6 = 3*pal[src15]
AND r9, r14,r11,LSR #8 @ r9 = src17
LDR r9, [r13,r9, LSL #2] @ r9 = pal[src17]
AND r12,r14,r11,LSR #16 @ r11= src18
LDR r12,[r13,r12,LSL #2] @ r11= pal[src18]
ADD r6, r6, r7 @ r6 = dst12<<2
AND r6, r8, r6, LSR #2 @ r6 = dst12 (split)
ORR r6, r6, r6, ROR #16 @ r6 = dst12 (in both halves)
ADD r7, r7, r9 @ r7 = dst13<<1
AND r7, r8, r7, LSR #1 @ r7 = dst13 (split)
ORR r7, r7, r7, ROR #16 @ r7 = dst13 (in both halves)
MOV r7, r7, LSL #16 @ r7 = dst13<<16
ORR r6, r7, r6, LSR #16 @ r6 = dst12 | dst13<<16
MOV r7, r11,LSR #24 @ r7 = src19
LDR r7, [r13,r7, LSL #2] @ r7 = pal[src19]
ADD r9, r9, r12 @ r9 = dst14<<1
AND r9, r8, r9, LSR #1 @ r9 = dst14 (split)
ORR r9, r9, r9, ROR #16 @ r9 = dst14 (in both halves)
ADD r12,r12,r7 @ r12= pal[src18]+pal[src19]
ADD r12,r12,r7, LSL #1 @ r12= dst15<<2
AND r12,r8, r12,LSR #2 @ r12= dst15 (split)
ORR r12,r12,r12,ROR #16 @ r12= dst15 (in both halves)
MOV r7, r9, LSR #16
ORR r7, r7, r12, LSL #16 @ r7 = dst14 | dst15<<16
STMIA r0!,{r6,r7}
BGT xLoop4
ADD r0,r0,r2,LSL #1
ADD r1,r1,r3
SUBS r5,r5,#1
BGT yLoop4
ADD r13,r13,#256*4
LDMFD r13!,{r4-r11,PC}

View File

@@ -0,0 +1,30 @@
#!/bin/sh
echo "FIXME: feature disabled in configure"
exit 1
#
# build-ds.sh -- script for building a ds build with every usable dynamic engine plugin
make clean
#Set up a static build with only engines usable by DS enabled
./configure --host=ds --disable-debug --disable-all-engines --enable-scumm --enable-sky --enable-queen --enable-agos --enable-gob --enable-cine --enable-agi --enable-kyra --enable-lure --enable-parallaction --enable-made --enable-cruise
make clean
make
#Dump all symbols used in this garbage-collected static build into a file
rm -f ds.syms
arm-eabi-objdump -t scummvm.elf > ds.syms
make clean
#Set up a dynamic build with only engines usable by the DS enabled
./configure --host=ds --enable-plugins --default-dynamic --disable-debug --disable-all-engines --enable-scumm --enable-sky --enable-queen --enable-gob --enable-cine --enable-agos --enable-agi --enable-kyra --enable-lure --enable-parallaction --enable-made --enable-cruise
make clean
#Make this final build, which is selectively stripped with the assistance of the ds.syms file that was generated earlier
make

View File

@@ -0,0 +1,696 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <portdefs.h> // Protect uintXX typedefs
#include <nds.h>
#include "backends/platform/ds/osystem_ds.h"
#include "backends/platform/ds/gfx/banner.h"
#include "common/translation.h"
#include "graphics/blit.h"
namespace DS {
// From console.c in NDSLib
// Defines
#define SCUMM_GAME_HEIGHT 142
#define SCUMM_GAME_WIDTH 227
// Scaled
static int scX;
static int scY;
static int subScX;
static int subScY;
static int subScTargetX;
static int subScTargetY;
static int subScreenWidth = SCUMM_GAME_WIDTH;
static int subScreenHeight = SCUMM_GAME_HEIGHT;
static int subScreenScale = 256;
// Shake
static int s_shakeXOffset = 0;
static int s_shakeYOffset = 0;
// 8-bit surface size
static int gameWidth = 320;
static int gameHeight = 200;
void setTopScreenZoom(int percentage) {
s32 scale = (percentage << 8) / 100;
subScreenScale = (256 * 256) / scale;
}
void setTopScreenTarget(int x, int y) {
subScTargetX = (x - (subScreenWidth >> 1));
subScTargetY = (y - (subScreenHeight >> 1));
if (subScTargetX < 0) subScTargetX = 0;
if (subScTargetX > gameWidth - subScreenWidth) subScTargetX = gameWidth - subScreenWidth;
if (subScTargetY < 0) subScTargetY = 0;
if (subScTargetY > gameHeight - subScreenHeight) subScTargetY = gameHeight - subScreenHeight;
subScTargetX <<=8;
subScTargetY <<=8;
}
void setGameSize(int width, int height) {
gameWidth = width;
gameHeight = height;
setTopScreenTarget(width / 2, height / 2);
}
void setShakePos(int shakeXOffset, int shakeYOffset) {
s_shakeXOffset = shakeXOffset;
s_shakeYOffset = shakeYOffset;
}
void VBlankHandler(void) {
int xCenter = subScTargetX + ((subScreenWidth >> 1) << 8);
int yCenter = subScTargetY + ((subScreenHeight >> 1) << 8);
subScreenWidth = (256 * subScreenScale) >> 8;
subScreenHeight = (192 * subScreenScale) >> 8;
if ( ((subScreenWidth) > 256 - 8) && ((subScreenWidth) < 256 + 8) ) {
subScreenWidth = 256;
subScreenHeight = 192;
} else if ( ((subScreenWidth) > 128 - 8) && ((subScreenWidth) < 128 + 8) ) {
subScreenWidth = 128;
subScreenHeight = 96;
} else if (subScreenWidth > 256) {
subScreenWidth = 320;
subScreenHeight = 200;
}
subScTargetX = xCenter - ((subScreenWidth >> 1) << 8);
subScTargetY = yCenter - ((subScreenHeight >> 1) << 8);
subScTargetX = CLIP(subScTargetX, 0, (gameWidth - subScreenWidth) << 8);
subScTargetY = CLIP(subScTargetY, 0, (gameHeight - subScreenHeight) << 8);
subScX += (subScTargetX - subScX) >> 2;
subScY += (subScTargetY - subScY) >> 2;
OSystem_DS::instance()->setSubScreen(subScX, subScY, subScreenWidth, ((subScreenHeight * (256 << 8)) / 192) >> 8);
if (g_system->getGraphicsMode() == GFX_NOSCALE) {
if (scX + 256 > gameWidth - 1) {
scX = gameWidth - 1 - 256;
}
if (scX < 0) {
scX = 0;
}
if (scY + 192 > gameHeight - 1) {
scY = gameHeight - 1 - 192;
}
if (scY < 0) {
scY = 0;
}
OSystem_DS::instance()->setMainScreen((scX << 8) + (s_shakeXOffset << 8), (scY << 8) + (s_shakeYOffset << 8), 256, 256);
} else {
if (scY > gameHeight - 192 - 1) {
scY = gameHeight - 192 - 1;
}
if (scY < 0) {
scY = 0;
}
OSystem_DS::instance()->setMainScreen(64 + (s_shakeXOffset << 8), (scY << 8) + (s_shakeYOffset << 8), gameWidth, ((gameHeight * (256 << 8)) / 192) >> 8);
}
}
void initHardware() {
pmPowerOn(POWCNT_ALL);
videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);
vramSetBankA(VRAM_A_MAIN_BG_0x06000000);
vramSetBankB(VRAM_B_MAIN_BG_0x06020000);
vramSetBankC(VRAM_C_SUB_BG_0x06200000);
vramSetBankD(VRAM_D_MAIN_BG_0x06040000);
vramSetBankE(VRAM_E_MAIN_SPRITE);
scX = 0;
scY = 0;
subScX = 0;
subScY = 0;
subScTargetX = 0;
subScTargetY = 0;
#ifdef DISABLE_TEXT_CONSOLE
videoSetModeSub(MODE_3_2D | DISPLAY_BG3_ACTIVE);
bgExtPaletteEnableSub();
/* The extended palette data can only be accessed in LCD mode. */
vramSetBankH(VRAM_H_LCD);
// bannerPal comes from code memory: it doesn't need to be flushed
dmaCopy(bannerPal, &VRAM_H_EXT_PALETTE[1][0], bannerPalLen);
vramSetBankH(VRAM_H_SUB_BG_EXT_PALETTE);
#endif
}
}
void OSystem_DS::initGraphics() {
DS::initHardware();
setSwapLCDs(false);
oamInit(&oamMain, SpriteMapping_Bmp_1D_128, false);
_cursorSprite = oamAllocateGfx(&oamMain, SpriteSize_64x64, SpriteColorFormat_Bmp);
_overlay.create(256, 192, _pfABGR1555);
_overlayScreen = new DS::Background(&_overlay, 2, false, 0, false);
_overlayScreen->reset();
_screen = nullptr;
#ifdef DISABLE_TEXT_CONSOLE
_subScreen = nullptr;
_banner = nullptr;
#endif
_keyboard = new DS::Keyboard(_eventManager->getEventDispatcher());
#ifndef DISABLE_TEXT_CONSOLE
_keyboard->init(0, 21, 1, false);
#endif
// Setup VBlank IRQ only when we are ready to handle it
irqSet(IRQ_VBLANK, DS::VBlankHandler);
}
void OSystem_DS::setMainScreen(int32 x, int32 y, int32 sx, int32 sy) {
if (_screen) {
_screen->setScalef(sx, sy);
_screen->setScrollf(x, y);
}
}
void OSystem_DS::setSubScreen(int32 x, int32 y, int32 sx, int32 sy) {
#ifdef DISABLE_TEXT_CONSOLE
if (_subScreen) {
_subScreen->setScalef(sx, sy);
_subScreen->setScrollf(x, y);
}
#endif
}
bool OSystem_DS::hasFeature(Feature f) {
return (f == kFeatureCursorPalette) || (f == kFeatureCursorAlpha) || (f == kFeatureStretchMode) || (f == kFeatureVirtualKeyboard) || (f == kFeatureTouchscreen);
}
void OSystem_DS::setFeatureState(Feature f, bool enable) {
if (f == kFeatureCursorPalette) {
_disableCursorPalette = !enable;
_cursorDirty = true;
} else if (f == kFeatureVirtualKeyboard) {
if (enable) {
setSwapLCDs(true);
#ifdef DISABLE_TEXT_CONSOLE
if (_subScreenActive) {
_subScreenActive = false;
if (_subScreen) {
_subScreen->hide();
_subScreen->reset();
} else if (_banner) {
_banner->hide();
}
_keyboard->init(0, 21, 1, false);
}
#endif
_keyboard->show();
} else if (_keyboard->isVisible()) {
_keyboard->hide();
#ifdef DISABLE_TEXT_CONSOLE
if (_subScreen) {
_subScreen->reset();
_subScreen->show();
_paletteDirty = true;
} else if (_banner) {
_banner->show();
}
_subScreenActive = true;
#endif
setSwapLCDs(false);
}
}
}
bool OSystem_DS::getFeatureState(Feature f) {
if (f == kFeatureCursorPalette)
return !_disableCursorPalette;
else if (f == kFeatureVirtualKeyboard)
return _keyboard->isVisible();
return false;
}
void OSystem_DS::setSwapLCDs(bool swap) {
if (swap) {
lcdMainOnTop();
_eventSource->handleTouch(false);
} else {
lcdMainOnBottom();
_eventSource->handleTouch(true);
}
}
static const OSystem::GraphicsMode graphicsModes[] = {
{ "NONE", _s("Unscaled"), GFX_NOSCALE },
{ "HW", _s("Hardware scale (fast, but low quality)"), GFX_HWSCALE },
{ "SW", _s("Software scale (good quality, but slower)"), GFX_SWSCALE },
{ nullptr, nullptr, 0 }
};
const OSystem::GraphicsMode *OSystem_DS::getSupportedGraphicsModes() const {
return graphicsModes;
}
int OSystem_DS::getDefaultGraphicsMode() const {
return GFX_HWSCALE;
}
bool OSystem_DS::setGraphicsMode(int mode, uint flags) {
assert(_transactionMode != kTransactionNone);
switch (mode) {
case GFX_NOSCALE:
case GFX_HWSCALE:
case GFX_SWSCALE:
_currentState.graphicsMode = mode;
return true;
default:
return false;
}
}
int OSystem_DS::getGraphicsMode() const {
return _currentState.graphicsMode;
}
static const OSystem::GraphicsMode stretchModes[] = {
{ "100", "100%", 100 },
{ "150", "150%", 150 },
{ "200", "200%", 200 },
{ nullptr, nullptr, 0 }
};
const OSystem::GraphicsMode *OSystem_DS::getSupportedStretchModes() const {
return stretchModes;
}
int OSystem_DS::getDefaultStretchMode() const {
return 100;
}
bool OSystem_DS::setStretchMode(int mode) {
assert(_transactionMode != kTransactionNone);
_currentState.stretchMode = mode;
return true;
}
int OSystem_DS::getStretchMode() const {
return _currentState.stretchMode;
}
Graphics::PixelFormat OSystem_DS::getScreenFormat() const {
return _currentState.format;
}
Common::List<Graphics::PixelFormat> OSystem_DS::getSupportedFormats() const {
Common::List<Graphics::PixelFormat> res;
res.push_back(_pfABGR1555);
res.push_back(_pfCLUT8);
return res;
}
void OSystem_DS::beginGFXTransaction() {
assert(_transactionMode == kTransactionNone);
// Start a transaction.
_oldState = _currentState;
_transactionMode = kTransactionActive;
}
void OSystem_DS::initSize(uint width, uint height, const Graphics::PixelFormat *format) {
_currentState.width = width;
_currentState.height = height;
_currentState.format = format ? *format : _pfCLUT8;
}
OSystem::TransactionError OSystem_DS::endGFXTransaction() {
assert(_transactionMode == kTransactionActive);
uint transactionError = OSystem::kTransactionSuccess;
// 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 ((_currentState.width > 512 || _currentState.height > 512) & !_hiresHack) {
_currentState.width = _oldState.width;
_currentState.height = _oldState.height;
transactionError |= OSystem::kTransactionSizeChangeFailed;
}
if (_currentState.format != _pfCLUT8) {
if (_currentState.width > 256 && _currentState.height > 256) {
_currentState.format = _pfCLUT8;
transactionError |= OSystem::kTransactionFormatNotSupported;
} else if (_currentState.format != _pfABGR1555) {
_currentState.format = _pfABGR1555;
transactionError |= OSystem::kTransactionFormatNotSupported;
}
}
const bool isRGB = (_currentState.format != _pfCLUT8);
bool setupNewGameScreen = false;
if (_oldState.graphicsMode != _currentState.graphicsMode
|| _oldState.width != _currentState.width
|| _oldState.height != _currentState.height
|| _oldState.format != _currentState.format) {
setupNewGameScreen = true;
}
bool bannerChanged = false;
#ifdef DISABLE_TEXT_CONSOLE
if ( (!_engineRunning && (_banner == NULL))
|| (_engineRunning && (_banner != NULL))) {
bannerChanged = true;
}
#endif
if (setupNewGameScreen) {
bool swScale = ((_currentState.graphicsMode == GFX_SWSCALE) && (_currentState.width == 320));
_framebuffer.create(_currentState.width, _currentState.height, _currentState.format);
if (_screen)
_screen->reset();
delete _screen;
_screen = nullptr;
if (DS::Background::getRequiredVRAM(_currentState.width, _currentState.height, isRGB, swScale) <= 0x40000) {
_screen = new DS::Background(&_framebuffer, 3, false, 8, swScale);
}
// Something changed, so update the screen change ID.
++_screenChangeID;
} else if (bannerChanged) {
if (_screen)
_screen->reset();
}
#ifdef DISABLE_TEXT_CONSOLE
if (setupNewGameScreen || bannerChanged) {
if (_subScreen && _subScreenActive)
_subScreen->reset();
delete _subScreen;
_subScreen = nullptr;
if (_engineRunning) {
if (_banner) {
_banner->reset();
_banner->hide();
}
delete _banner;
_banner = nullptr;
if (DS::Background::getRequiredVRAM(_currentState.width, _currentState.height, isRGB, false) <= 0x20000) {
_subScreen = new DS::Background(&_framebuffer, 3, true, 0, false);
}
} else {
if (!_banner)
_banner = new DS::TiledBackground(bannerTiles, bannerTilesLen, bannerMap, bannerMapLen, 1, true, 30, 0);
_banner->update();
}
}
#endif
DS::setGameSize(_currentState.width, _currentState.height);
DS::setTopScreenZoom(_currentState.stretchMode);
_transactionMode = kTransactionNone;
return (OSystem::TransactionError)transactionError;
}
int OSystem_DS::getScreenChangeID() const {
return _screenChangeID;
}
int16 OSystem_DS::getHeight() {
return _currentState.height;
}
int16 OSystem_DS::getWidth() {
return _currentState.width;
}
void OSystem_DS::setPalette(const byte *colors, uint start, uint num) {
for (unsigned int r = start; r < start + num; r++) {
int red = *colors;
int green = *(colors + 1);
int blue = *(colors + 2);
_palette[r] = RGB8(red, green, blue);
colors += 3;
}
_paletteDirty = true;
if (_disableCursorPalette)
_cursorDirty = true;
}
void OSystem_DS::setCursorPalette(const byte *colors, uint start, uint num) {
for (unsigned int r = start; r < start + num; r++) {
int red = *colors;
int green = *(colors + 1);
int blue = *(colors + 2);
_cursorPalette[r] = RGB8(red, green, blue);
colors += 3;
}
_disableCursorPalette = false;
_cursorDirty = true;
}
void OSystem_DS::grabPalette(unsigned char *colors, uint start, uint num) const {
for (unsigned int r = start; r < start + num; r++) {
*colors++ = (_palette[r] & 0x001F) << 3;
*colors++ = (_palette[r] & 0x03E0) >> 5 << 3;
*colors++ = (_palette[r] & 0x7C00) >> 10 << 3;
}
}
void OSystem_DS::copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) {
_framebuffer.copyRectToSurface(buf, pitch, x, y, w, h);
}
void OSystem_DS::updateScreen() {
swiWaitForVBlank();
bgUpdate();
if (_cursorDirty) {
refreshCursor(_cursorSprite, _cursor, !_disableCursorPalette ? _cursorPalette : _palette);
_cursorDirty = false;
}
oamSet(&oamMain, 0, _cursorPos.x - _cursorHotX, _cursorPos.y - _cursorHotY, 0, 15, SpriteSize_64x64,
SpriteColorFormat_Bmp, _cursorSprite, 0, false, !_cursorVisible, false, false, false);
oamUpdate(&oamMain);
if (_paletteDirty) {
DC_FlushRange(_palette, 256 * 2);
dmaCopyHalfWords(3, _palette, BG_PALETTE, 256 * 2);
#ifdef DISABLE_TEXT_CONSOLE
if (_subScreen && _subScreenActive)
dmaCopyHalfWords(3, _palette, BG_PALETTE_SUB, 256 * 2);
#endif
_paletteDirty = false;
}
if (_overlayScreen && _overlayScreen->isVisible()) {
_overlayScreen->update();
}
if (_screen && _screen->isVisible()) {
_screen->update();
#ifdef DISABLE_TEXT_CONSOLE
if (_subScreen && _subScreenActive)
_subScreen->update();
#endif
}
}
void OSystem_DS::setShakePos(int shakeXOffset, int shakeYOffset) {
DS::setShakePos(shakeXOffset, shakeYOffset);
}
void OSystem_DS::showOverlay(bool inGUI) {
assert(_overlayScreen);
_overlayInGUI = inGUI;
_overlayScreen->reset();
_overlayScreen->show();
}
void OSystem_DS::hideOverlay() {
assert(_overlayScreen);
_overlayInGUI = false;
_overlayScreen->hide();
}
bool OSystem_DS::isOverlayVisible() const {
assert(_overlayScreen);
return _overlayScreen->isVisible();
}
void OSystem_DS::clearOverlay() {
memset(_overlay.getPixels(), 0, _overlay.pitch * _overlay.h);
}
void OSystem_DS::grabOverlay(Graphics::Surface &surface) {
assert(surface.w >= getOverlayWidth());
assert(surface.h >= getOverlayHeight());
assert(surface.format.bytesPerPixel == _overlay.format.bytesPerPixel);
byte *src = (byte *)_overlay.getPixels();
byte *dst = (byte *)surface.getPixels();
Graphics::copyBlit(dst, src, surface.pitch, _overlay.pitch,
getOverlayWidth(), getOverlayHeight(), _overlay.format.bytesPerPixel);
}
void OSystem_DS::copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) {
_overlay.copyRectToSurface(buf, pitch, x, y, w, h);
}
int16 OSystem_DS::getOverlayHeight() const {
return _overlay.h;
}
int16 OSystem_DS::getOverlayWidth() const {
return _overlay.w;
}
Graphics::PixelFormat OSystem_DS::getOverlayFormat() const {
return _overlay.format;
}
Common::Point OSystem_DS::transformPoint(int16 x, int16 y) {
if (_overlayInGUI || !_screen)
return Common::Point(x, y);
else
return _screen->realToScaled(x, y);
}
bool OSystem_DS::showMouse(bool visible) {
const bool last = _cursorVisible;
_cursorVisible = visible;
return last;
}
void OSystem_DS::warpMouse(int x, int y) {
if (_overlayInGUI || !_screen)
_cursorPos = Common::Point(x, y);
else
_cursorPos = _screen->scaledToReal(x, y);
}
void OSystem_DS::setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, u32 keycolor, bool dontScale, const Graphics::PixelFormat *format, const byte *mask) {
if (!buf || w == 0 || h == 0)
return;
if (mask)
warning("OSystem_DS::setMouseCursor: Masks are not supported");
Graphics::PixelFormat actualFormat = format ? *format : _pfCLUT8;
if (_cursor.w != (int16)w || _cursor.h != (int16)h || _cursor.format != actualFormat)
_cursor.create(w, h, actualFormat);
_cursor.copyRectToSurface(buf, w * actualFormat.bytesPerPixel, 0, 0, w, h);
_cursorHotX = hotspotX;
_cursorHotY = hotspotY;
_cursorKey = keycolor;
if (actualFormat != _pfCLUT8 && actualFormat != _pfABGR1555) {
uint8 a, r, g, b;
actualFormat.colorToARGB(_cursorKey, a, r, g, b);
_cursorKey = _pfABGR1555.ARGBToColor(a, r, g, b);
_cursor.convertToInPlace(_pfABGR1555);
}
_cursorDirty = true;
}
void OSystem_DS::refreshCursor(u16 *dst, const Graphics::Surface &src, const uint16 *palette) {
const uint w = MIN<uint>(src.w, 64);
const uint h = MIN<uint>(src.h, 64);
dmaFillHalfWords(0, dst, 64 * 64 * 2);
if (src.format == _pfCLUT8) {
for (uint y = 0; y < h; y++) {
const uint8 *row = (const uint8 *)src.getBasePtr(0, y);
for (uint x = 0; x < w; x++) {
uint8 color = *row++;
if (color != _cursorKey)
dst[y * 64 + x] = palette[color] | 0x8000;
}
}
} else {
for (uint y = 0; y < h; y++) {
const uint16 *row = (const uint16 *)src.getBasePtr(0, y);
for (uint x = 0; x < w; x++) {
uint16 color = *row++;
if (color != _cursorKey)
dst[y * 64 + x] = color;
}
}
}
}
Graphics::Surface *OSystem_DS::lockScreen() {
return &_framebuffer;
}
void OSystem_DS::unlockScreen() {
// No need to do anything here. The screen will be updated in updateScreen().
}
void OSystem_DS::setFocusRectangle(const Common::Rect& rect) {
DS::setTopScreenTarget(rect.left + rect.width() / 2, rect.top + rect.height() / 2);
}
void OSystem_DS::clearFocusRectangle() {
}

View File

@@ -0,0 +1,92 @@
ifdef DYNAMIC_MODULES
DESCRIPTION ?= Built with dynamic plugin support
else
DESCRIPTION ?= DS Port
endif
NDSTOOL ?= ndstool
GRIT ?= grit
all: scummvm.nds
clean: dsclean
dsclean:
$(RM) backends/platform/ds/gfx/*.h
$(RM) backends/platform/ds/gfx/*.s
$(RM) scummvm.nds
$(RM) map.txt
$(RM_REC) romfs
$(RM_REC) dsdist
dsdist: scummvm.nds $(DIST_FILES_DOCS)
rm -rf dsdist
mkdir -p dsdist
cp scummvm.nds dsdist/
cp $(DIST_FILES_DOCS) dsdist/
.PHONY: dsclean dsdist
%.nds: %.elf romfs
$(NDSTOOL) -c $@ -9 $< -7 $(DEVKITPRO)/calico/bin/ds7_maine.elf -b $(srcdir)/backends/platform/ds/logo.bmp "$(@F);ScummVM calico $(VERSION);$(DESCRIPTION)" -d romfs
romfs: $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) $(DIST_FILES_NETWORKING) $(DIST_FILES_VKEYBD) $(PLUGINS)
@rm -rf romfs
@mkdir -p romfs
@cp $(DIST_FILES_THEMES) romfs/
ifdef DIST_FILES_ENGINEDATA
@cp $(DIST_FILES_ENGINEDATA) romfs/
endif
ifdef DIST_FILES_NETWORKING
@cp $(DIST_FILES_NETWORKING) romfs/
endif
ifdef DIST_FILES_VKEYBD
@cp $(DIST_FILES_VKEYBD) romfs/
endif
ifeq ($(DYNAMIC_MODULES),1)
@mkdir -p romfs/plugins
@for i in $(PLUGINS); do $(STRIP) --strip-debug $$i -o romfs/plugins/`basename $$i`; done
endif
QUIET_GRIT = @echo ' ' GRIT ' ' $@;
vpath %.grit $(srcdir)
vpath %.png $(srcdir)
%.s %.h : %.png %.grit
$(QUIET)$(MKDIR) $(*D)
$(QUIET_GRIT)$(GRIT) $< -fts -o$*
backends/platform/ds/ds-graphics.o: backends/platform/ds/gfx/banner.o
# When building with plugins, the main binary is too big for a DS ROM size
# We need to move some parts of it to the secondary ROM only available on DSi.
ifeq ($(DYNAMIC_MODULES),1)
$(EXECUTABLE): | fixup_twl
ifneq ($(findstring $(MAKEFLAGS),s),s)
ifneq ($(VERBOSE_BUILD),1)
ifneq ($(VERBOSE_BUILD),yes)
QUIET_MAKE_TWL = @echo ' ' TWL ' ' $+;
endif
endif
endif
fixup_twl: audio/libaudio.a image/libimage.a video/libvideo.a
$(QUIET_MAKE_TWL)
$(QUIET)for f in $+; do \
python3 $(srcdir)/dists/ds/make_twl.py $$f; \
done
.PHONY: fixup_twl
endif
# Command to build libmad is:
# ./configure --host=arm-elf --enable-speed --enable-sso -enable-fpm=arm CFLAGS='-specs=ds_arm9.specs -mthumb-interwork'
#
# I actually had to use
# ./configure --host=arm-elf --enable-speed --enable-sso -enable-fpm=arm CFLAGS='-specs=ds_arm9.specs -mthumb-interwork' LDFLAGS='C:/Progra~1/devkitpro/libnds/lib/libnds9.a' --disable-shared --disable-debugging
#
# Fingolfin used
# CXX=arm-eabi-g++ CC=arm-eabi-gcc ./configure --host=arm-elf --enable-speed --enable-sso -enable-fpm=arm CFLAGS='-specs=ds_arm9.specs -mthumb-interwork' --disable-shared --disable-debugging LDFLAGS=$DEVKITPRO/libnds/lib/libnds9.a

View File

@@ -0,0 +1,127 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
// - Remove scummconsole.c
// - Delete files
// - libcartreset
// - Alternative controls - tap for left click, double for right
// - Inherit the Earth?
// - Stereo audio?
// - Software scaler?
// - 100% scale
// - Arrow keys cause key events when keyboard enabled - Done
// - Mouse cursor display - Done
// - Disable scaler on options menu - Done
// - Fix scale icons on top screen - Done
// - Fseek optimisation? - No need
// - Fix agi hack to be cleaner - done
// - Fix not typing looong words - Done
// - Show keyboard by default in AGI games
// - Fix mouse moving when cursor on keyboard screen - Done
// - Fix 'fit' thingy always appearing - Done
// - check cine backbuffer code - Done
// - Add long filename support - Done
// - New icons
// - Add key config for gob engine: Start:F1, Shift-numbers: F keys - Done
// - Fix [ds] appearing in game menu
// - Find out what's going wrong when you turn the console off
// - enable console when asserting
// - Alternative controls?
// - Fix 512x256 backbuffer to 320x240 - Done
// - Fix keyboard appearing on wrong screen - Done
// - Volume amplify option
// - Make save/restore game screen use scaler buffer
// 1.0.0!
// - Fix text on tabs on config screen
// - Remove ini file debug msg
// - Memory size for ite
// - Try discworld?
#include <portdefs.h> // Protect uintXX typedefs
#include <nds.h>
#include "backends/platform/ds/osystem_ds.h"
#include "backends/plugins/ds/ds-provider.h"
#include "base/main.h"
namespace DS {
///////////////////
// Fast Ram
///////////////////
#define FAST_RAM_SIZE (22500)
#define ITCM_DATA __attribute__((section(".itcm")))
u8 *fastRamPointer;
u8 fastRamData[FAST_RAM_SIZE] ITCM_DATA;
void *fastRamAlloc(int size) {
void *result = (void *) fastRamPointer;
fastRamPointer += size;
if(fastRamPointer > fastRamData + FAST_RAM_SIZE) {
warning("FastRam (ITCM) allocation failed");
return malloc(size);
}
return result;
}
void fastRamReset() {
fastRamPointer = &fastRamData[0];
}
} // End of namespace DS
/////////////////
// Main
/////////////////
int main(int argc, char **argv) {
#ifndef DISABLE_TEXT_CONSOLE
videoSetModeSub(MODE_0_2D);
vramSetBankC(VRAM_C_SUB_BG_0x06200000);
consoleInit(NULL, 1, BgType_Text4bpp, BgSize_T_256x256, 30, 0, false, true);
#endif
g_system = new OSystem_DS();
assert(g_system);
#ifdef DYNAMIC_MODULES
PluginManager::instance().addPluginProvider(new DSPluginProvider());
#endif
// Invoke the actual ScummVM main entry point:
int res = scummvm_main(argc, argv);
// Free OSystem
g_system->destroy();
return res;
}

View File

@@ -0,0 +1,35 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef _DSMAIN_H
#define _DSMAIN_H
#include "common/scummsys.h"
namespace DS {
// Fast RAM allocation (ITCM)
void fastRamReset();
void* fastRamAlloc(int size);
} // End of namespace DS
#endif

View File

@@ -0,0 +1,11 @@
# 8 bit bitmap
-gB8
# tile format
-gt
# tile reduction by tiles, palette and hflip/vflip
-mRtf
# map layout standard bg format
-mLs

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1,134 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <portdefs.h> // Protect uintXX typedefs
#include <nds.h>
#include "backends/platform/ds/keyboard.h"
#include "common/system.h"
namespace DS {
Keyboard::Keyboard(Common::EventDispatcher *eventDispatcher) :
_eventDispatcher(eventDispatcher),
_lastKey(NOKEY),
_visible(false) {
_eventDispatcher->registerSource(this, false);
}
Keyboard::~Keyboard() {
_eventDispatcher->unregisterSource(this);
}
void Keyboard::init(int layer, int mapBase, int tileBase, bool mainDisplay) {
keyboardInit(nullptr, layer, BgType_Text4bpp, BgSize_T_256x512, mapBase, tileBase, mainDisplay, true);
}
void Keyboard::show() {
keyboardShow();
_visible = true;
}
void Keyboard::hide() {
keyboardHide();
_visible = false;
}
bool Keyboard::mapKey(int key, Common::KeyState &ks) {
switch (key) {
case DVK_BACKSPACE:
ks = Common::KeyState(Common::KEYCODE_BACKSPACE, Common::ASCII_BACKSPACE);
break;
case DVK_TAB:
ks = Common::KeyState(Common::KEYCODE_TAB, Common::ASCII_TAB);
break;
case DVK_ENTER:
ks = Common::KeyState(Common::KEYCODE_RETURN, Common::ASCII_RETURN);
break;
case DVK_SPACE:
ks = Common::KeyState(Common::KEYCODE_SPACE, Common::ASCII_SPACE);
break;
case DVK_MENU:
ks = Common::KeyState(Common::KEYCODE_MENU);
break;
case DVK_SHIFT:
ks = Common::KeyState(Common::KEYCODE_LSHIFT);
break;
case DVK_CAPS:
ks = Common::KeyState(Common::KEYCODE_CAPSLOCK);
break;
case DVK_CTRL:
ks = Common::KeyState(Common::KEYCODE_LCTRL);
break;
case DVK_UP:
ks = Common::KeyState(Common::KEYCODE_UP);
break;
case DVK_RIGHT:
ks = Common::KeyState(Common::KEYCODE_RIGHT);
break;
case DVK_DOWN:
ks = Common::KeyState(Common::KEYCODE_DOWN);
break;
case DVK_LEFT:
ks = Common::KeyState(Common::KEYCODE_LEFT);
break;
case DVK_FOLD:
ks = Common::KeyState(Common::KEYCODE_ESCAPE, Common::ASCII_ESCAPE);
break;
case DVK_ALT:
ks = Common::KeyState(Common::KEYCODE_LALT);
break;
default:
if (key < Common::KEYCODE_SPACE || key > Common::KEYCODE_z)
return false;
ks = Common::KeyState((Common::KeyCode)tolower(key), key);
break;
}
return true;
}
bool Keyboard::pollEvent(Common::Event &event) {
if (!_visible)
return false;
int key = keyboardUpdate();
if (key == _lastKey)
return false;
if (key == NOKEY) {
event.type = Common::EVENT_KEYUP;
if (!mapKey(_lastKey, event.kbd))
return false;
} else {
event.type = Common::EVENT_KEYDOWN;
if (!mapKey(key, event.kbd))
return false;
}
_lastKey = key;
// TODO: Handle flags
return true;
}
} // End of namespace DS

View File

@@ -0,0 +1,53 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef DS_KEYBOARD_H
#define DS_KEYBOARD_H
#include "common/events.h"
namespace DS {
class Keyboard : public Common::EventSource {
public:
Keyboard(Common::EventDispatcher *eventDispatcher);
~Keyboard();
void init(int layer, int mapBase, int tileBase, bool mainDisplay);
void show();
void hide();
inline bool isVisible() const { return _visible; }
// Implementation of the EventSource interface
virtual bool pollEvent(Common::Event &event);
protected:
Common::EventDispatcher *_eventDispatcher;
int _lastKey;
bool _visible;
bool mapKey(int key, Common::KeyState &ks);
};
} // End of namespace DS
#endif // #ifndef DS_KEYBOARD_H

Binary file not shown.

After

Width:  |  Height:  |  Size: 630 B

View File

@@ -0,0 +1,15 @@
MODULE := backends/platform/ds
MODULE_OBJS := \
background.o \
blitters_arm.o \
ds-graphics.o \
dsmain.o \
keyboard.o \
osystem_ds.o \
gfx/banner.o
# We don't use rules.mk but rather manually update OBJS and MODULE_DIRS.
MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS))
OBJS := $(MODULE_OBJS) $(OBJS)
MODULE_DIRS += $(sort $(dir $(MODULE_OBJS)))

View File

@@ -0,0 +1,243 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#define FORBIDDEN_SYMBOL_EXCEPTION_time_h
#define FORBIDDEN_SYMBOL_EXCEPTION_printf
#include <portdefs.h> // Protect uintXX typedefs
#include <nds.h>
#include <filesystem.h>
#include "backends/platform/ds/osystem_ds.h"
#include "common/config-manager.h"
#include "common/translation.h"
#include "backends/audiocd/default/default-audiocd.h"
#include "backends/events/default/default-events.h"
#include "backends/fs/devoptab/devoptab-fs-factory.h"
#include "backends/keymapper/hardware-input.h"
#include "backends/mixer/maxmod/maxmod-mixer.h"
#include "backends/mutex/null/null-mutex.h"
#include "backends/saves/default/default-saves.h"
#include "backends/timer/default/default-timer.h"
#include <time.h>
OSystem_DS *OSystem_DS::_instance = NULL;
OSystem_DS::OSystem_DS()
: _eventSource(NULL), _engineRunning(false), _disableCursorPalette(true),
_currentState(), _oldState(), _hiresHack(false), _screenChangeID(0),
_transactionMode(kTransactionNone),
_paletteDirty(false), _cursorDirty(false), _overlayInGUI(false),
_pfCLUT8(Graphics::PixelFormat::createFormatCLUT8()),
_pfABGR1555(Graphics::PixelFormat(2, 5, 5, 5, 1, 0, 5, 10, 15)),
_callbackTimer(10), _currentTimeMillis(0), _subScreenActive(true)
{
_instance = this;
nitroFSInit(NULL);
DevoptabFilesystemFactory *fsFactory = new DevoptabFilesystemFactory();
// Disable newlib's buffering, since libfat handles caching.
fsFactory->configureBuffering(DrivePOSIXFilesystemNode::kBufferingModeDisabled, 0);
_fsFactory = fsFactory;
}
OSystem_DS::~OSystem_DS() {
}
void timerTickHandler() {
OSystem_DS *system = OSystem_DS::instance();
if (system->_callbackTimer > 0) {
system->_callbackTimer--;
}
system->_currentTimeMillis++;
}
void OSystem_DS::initBackend() {
defaultExceptionHandler();
ConfMan.setInt("autosave_period", 0);
ConfMan.setBool("FM_medium_quality", true);
_eventSource = new DSEventSource();
_eventManager = new DSEventManager(_eventSource);
_savefileManager = new DefaultSaveFileManager();
_timerManager = new DefaultTimerManager();
timerStart(0, ClockDivider_1, (u16)TIMER_FREQ(1000), timerTickHandler);
_mixerManager = new MaxModMixerManager(11025, 32768);
_mixerManager->init();
initGraphics();
BaseBackend::initBackend();
}
void OSystem_DS::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) {
s.add("nitro:/", new Common::FSDirectory("nitro:/"), priority);
}
uint32 OSystem_DS::getMillis(bool skipRecord) {
return _currentTimeMillis;
}
void OSystem_DS::delayMillis(uint msecs) {
int st = getMillis();
doTimerCallback();
if (_mixerManager)
((MaxModMixerManager *)_mixerManager)->updateAudio();
while (st + msecs >= getMillis());
}
void OSystem_DS::doTimerCallback(int interval) {
DefaultTimerManager *tm = (DefaultTimerManager *)getTimerManager();
if (_callbackTimer <= 0) {
_callbackTimer += interval;
tm->handler();
}
}
void OSystem_DS::getTimeAndDate(TimeDate &td, bool skipRecord) const {
time_t curTime = time(0);
struct tm t = *localtime(&curTime);
td.tm_sec = t.tm_sec;
td.tm_min = t.tm_min;
td.tm_hour = t.tm_hour;
td.tm_mday = t.tm_mday;
td.tm_mon = t.tm_mon;
td.tm_year = t.tm_year;
td.tm_wday = t.tm_wday;
}
Common::MutexInternal *OSystem_DS::createMutex() {
return new NullMutexInternal();
}
void OSystem_DS::quit() {
}
void OSystem_DS::logMessage(LogMessageType::Type type, const char *message) {
#ifndef DISABLE_TEXT_CONSOLE
if (type == LogMessageType::kError) {
printf("\x1b[41m%s\x1b[39m", message);
} else {
printf("%s", message);
}
#endif
}
void OSystem_DS::messageBox(LogMessageType::Type type, const char *message) {
if (type == LogMessageType::kError) {
#ifdef DISABLE_TEXT_CONSOLE
consoleDemoInit();
printf("\x1b[41m%s\x1b[39m", message);
#endif
printf("\nPress any button to continue\n");
while(1) {
swiWaitForVBlank();
scanKeys();
if (keysDown()) break;
}
}
}
static const Common::HardwareInputTableEntry ndsJoystickButtons[] = {
{ "JOY_A", Common::JOYSTICK_BUTTON_A, _s("A") },
{ "JOY_B", Common::JOYSTICK_BUTTON_B, _s("B") },
{ "JOY_X", Common::JOYSTICK_BUTTON_X, _s("X") },
{ "JOY_Y", Common::JOYSTICK_BUTTON_Y, _s("Y") },
{ "JOY_BACK", Common::JOYSTICK_BUTTON_BACK, _s("Select") },
{ "JOY_START", Common::JOYSTICK_BUTTON_START, _s("Start") },
{ "JOY_LEFT_SHOULDER", Common::JOYSTICK_BUTTON_LEFT_SHOULDER, _s("L") },
{ "JOY_RIGHT_SHOULDER", Common::JOYSTICK_BUTTON_RIGHT_SHOULDER, _s("R") },
{ "JOY_UP", Common::JOYSTICK_BUTTON_DPAD_UP, _s("D-pad Up") },
{ "JOY_DOWN", Common::JOYSTICK_BUTTON_DPAD_DOWN, _s("D-pad Down") },
{ "JOY_LEFT", Common::JOYSTICK_BUTTON_DPAD_LEFT, _s("D-pad Left") },
{ "JOY_RIGHT", Common::JOYSTICK_BUTTON_DPAD_RIGHT, _s("D-pad Right") },
{ nullptr, 0, nullptr }
};
static const Common::AxisTableEntry ndsJoystickAxes[] = {
{ nullptr, 0, Common::kAxisTypeFull, nullptr }
};
const Common::HardwareInputTableEntry ndsMouseButtons[] = {
{ "MOUSE_LEFT", Common::MOUSE_BUTTON_LEFT, _s("Touch") },
{ nullptr, 0, nullptr }
};
Common::HardwareInputSet *OSystem_DS::getHardwareInputSet() {
using namespace Common;
CompositeHardwareInputSet *inputSet = new CompositeHardwareInputSet();
// Touch input sends mouse events for now, so we need to declare we have a mouse...
inputSet->addHardwareInputSet(new MouseHardwareInputSet(ndsMouseButtons));
inputSet->addHardwareInputSet(new JoystickHardwareInputSet(ndsJoystickButtons, ndsJoystickAxes));
return inputSet;
}
Common::String OSystem_DS::getSystemLanguage() const {
switch (PersonalData->language) {
case 0: return "ja_JP";
case 1: return "en_US";
case 2: return "fr_FR";
case 3: return "de_DE";
case 4: return "it_IT";
case 5: return "es_ES";
case 6: return "zh_CN";
default: return "en_US";
}
}
void OSystem_DS::engineInit() {
_engineRunning = true;
const Common::ConfigManager::Domain *activeDomain = ConfMan.getActiveDomain();
assert(activeDomain);
const Common::String engineId = activeDomain->getValOrDefault("engineid");
const Common::String gameId = activeDomain->getValOrDefault("gameid");
if ((engineId == "cine" && gameId == "fw") ||
(engineId == "gob" && gameId == "lit") ||
engineId == "supernova") {
_hiresHack = true;
} else {
_hiresHack = false;
}
}
void OSystem_DS::engineDone() {
_engineRunning = false;
_hiresHack = false;
}

View File

@@ -0,0 +1,216 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef _OSYSTEM_DS_H_
#define _OSYSTEM_DS_H_
#include "backends/modular-backend.h"
#include "backends/events/ds/ds-events.h"
#include "backends/mixer/mixer.h"
#include "backends/platform/ds/background.h"
#include "backends/platform/ds/keyboard.h"
#include "graphics/surface.h"
#include "graphics/paletteman.h"
enum {
GFX_NOSCALE = 0,
GFX_HWSCALE = 1,
GFX_SWSCALE = 2
};
class OSystem_DS : public ModularMixerBackend, public PaletteManager {
protected:
enum TransactionMode {
kTransactionNone = 0,
kTransactionActive = 1,
kTransactionRollback = 2
};
/**
* The current transaction mode.
*/
TransactionMode _transactionMode;
//
// Transaction support
//
struct VideoState {
constexpr VideoState() : width(0), height(0), format(),
graphicsMode(GFX_HWSCALE), stretchMode(100) {
}
uint width, height;
Graphics::PixelFormat format;
int graphicsMode;
int stretchMode;
};
/**
* The currently set up video state.
*/
VideoState _currentState;
/**
* The old video state used when doing a transaction rollback.
*/
VideoState _oldState;
/**
* The current screen change ID.
*/
int _screenChangeID;
Graphics::Surface _framebuffer, _overlay;
DS::Background *_screen, *_overlayScreen;
#ifdef DISABLE_TEXT_CONSOLE
DS::Background *_subScreen;
DS::TiledBackground *_banner;
#endif
bool _subScreenActive;
Graphics::Surface _cursor;
bool _hiresHack;
bool _paletteDirty, _cursorDirty;
static OSystem_DS *_instance;
u16 _palette[256];
u16 _cursorPalette[256];
u16 *_cursorSprite;
Common::Point _cursorPos;
int _cursorHotX;
int _cursorHotY;
uint32 _cursorKey;
bool _cursorVisible;
bool _overlayInGUI;
DSEventSource *_eventSource;
DS::Keyboard *_keyboard;
void initGraphics();
bool _disableCursorPalette;
const Graphics::PixelFormat _pfCLUT8, _pfABGR1555;
bool _engineRunning;
public:
OSystem_DS();
virtual ~OSystem_DS();
static OSystem_DS *instance() { return _instance; }
virtual bool hasFeature(Feature f);
virtual void setFeatureState(Feature f, bool enable);
virtual bool getFeatureState(Feature f);
virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
virtual int getDefaultGraphicsMode() const;
virtual bool setGraphicsMode(int mode, uint flags);
virtual int getGraphicsMode() const;
virtual const GraphicsMode *getSupportedStretchModes() const;
virtual int getDefaultStretchMode() const;
virtual bool setStretchMode(int mode);
virtual int getStretchMode() const;
virtual Graphics::PixelFormat getScreenFormat() const;
virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const;
virtual void beginGFXTransaction();
virtual OSystem::TransactionError endGFXTransaction();
virtual int getScreenChangeID() const;
virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format);
virtual int16 getHeight();
virtual int16 getWidth();
virtual PaletteManager *getPaletteManager() { return this; }
protected:
// PaletteManager API
virtual void setPalette(const byte *colors, uint start, uint num);
virtual void grabPalette(byte *colors, uint start, uint num) const;
public:
virtual void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h);
virtual void updateScreen();
virtual void setShakePos(int shakeXOffset, int shakeYOffset);
virtual void showOverlay(bool inGUI);
virtual void hideOverlay();
virtual bool isOverlayVisible() const;
virtual void clearOverlay();
virtual void grabOverlay(Graphics::Surface &surface);
virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h);
virtual int16 getOverlayHeight() const;
virtual int16 getOverlayWidth() const;
virtual Graphics::PixelFormat getOverlayFormat() const;
Common::Point transformPoint(int16 x, int16 y);
virtual bool showMouse(bool visible);
virtual void warpMouse(int x, int y);
virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, u32 keycolor, bool dontScale, const Graphics::PixelFormat *format, const byte *mask);
virtual void addSysArchivesToSearchSet(Common::SearchSet &s, int priority);
virtual uint32 getMillis(bool skipRecord = false);
virtual void delayMillis(uint msecs);
virtual void getTimeAndDate(TimeDate &td, bool skipRecord = false) const;
void doTimerCallback(int interval = 10);
virtual Common::MutexInternal *createMutex();
virtual Common::EventSource *getDefaultEventSource() { return _eventSource; }
virtual Common::HardwareInputSet *getHardwareInputSet();
virtual Common::String getSystemLanguage() const;
virtual void engineInit();
virtual void engineDone();
virtual void quit();
virtual void setFocusRectangle(const Common::Rect& rect);
virtual void clearFocusRectangle();
virtual void initBackend();
virtual Graphics::Surface *lockScreen();
virtual void unlockScreen();
virtual void setCursorPalette(const byte *colors, uint start, uint num);
void setSwapLCDs(bool swap);
void refreshCursor(u16 *dst, const Graphics::Surface &src, const uint16 *palette);
virtual void logMessage(LogMessageType::Type type, const char *message);
virtual void messageBox(LogMessageType::Type type, const char *message);
void setMainScreen(int32 x, int32 y, int32 sx, int32 sy);
void setSubScreen(int32 x, int32 y, int32 sx, int32 sy);
int _currentTimeMillis, _callbackTimer;
};
#endif

View File

@@ -0,0 +1,76 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef _PORTDEFS_H_
#define _PORTDEFS_H_
/**
* Include ndstypes.h for uint16 etc. typedefs
* These are deprecated so they clash with our typedefs
* Mask them by renaming them when including the header
*/
#define uint8 __nds_uint8
#define uint16 __nds_uint16
#define uint32 __nds_uint32
#define uint64 __nds_uint64
#define int8 __nds_int8
#define int16 __nds_int16
#define int32 __nds_int32
#define int64 __nds_int64
#include "nds/ndstypes.h"
#undef uint8
#undef uint16
#undef uint32
#undef uint64
#undef int8
#undef int16
#undef int32
#undef int64
// Include required headers
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stddef.h>
#include <assert.h>
#include <ctype.h>
#include <inttypes.h>
#include <limits.h>
#include <math.h>
#include <new>
#include <limits>
#include <nds/arm9/sassert.h>
#undef assert
#define assert(e) sassert(e, " ")
#ifndef DISABLE_COMMAND_LINE
#define DISABLE_COMMAND_LINE
#endif
#ifndef STREAM_AUDIO_FROM_DISK
#define STREAM_AUDIO_FROM_DISK
#endif
#endif

View File

@@ -0,0 +1,15 @@
#!/bin/sh
srcdir=$(realpath $(dirname $0)/../../..)
mkdir -p all-builds
for build in scumm access agi agos bbvs cge cge2 cine cruise director draci dragons drascula dreamweb gob griffon hugo illusions kyra lab lure made mads parallaction queen saga sci sherlock sky supernova teenagent tinsel tsage tucker voyeur xeen; do
echo "--- Setting up build $build ---"
mkdir -p build-$build && cd build-$build
$srcdir/configure --host=ds --disable-translation --disable-debug --disable-all-engines --enable-engine=$build --disable-ogg
make -j$(nproc) DESCRIPTION="Enabled engines: $build"
cp scummvm.nds ../all-builds/scummvm-$build.nds
cd ..
echo DONE
echo
done