mirror of
https://github.com/libretro/scummvm.git
synced 2024-11-30 04:40:39 +00:00
BACKENDS: ATARI: Rework
- Atari TT support - all video and audio is now handled via XBIOS - reworked IKBD handling using Kbdvbase vectors, esp. Kbdvec() - video uses proper triple buffer - arbitrary game screen size support - many fixes and optimizations
This commit is contained in:
parent
8bf928c0d8
commit
5537759c53
@ -19,17 +19,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
.globl _asm_screen_tt_save
|
||||
.globl _asm_screen_falcon_save
|
||||
.global _asm_screen_tt_save
|
||||
.global _asm_screen_falcon_save
|
||||
|
||||
.globl _asm_screen_tt_restore
|
||||
.globl _asm_screen_falcon_restore
|
||||
|
||||
.globl _asm_screen_set_tt_palette
|
||||
.globl _asm_screen_set_falcon_palette
|
||||
|
||||
.globl _asm_screen_set_vram
|
||||
.globl _asm_screen_set_scp_res
|
||||
.global _asm_screen_tt_restore
|
||||
.global _asm_screen_falcon_restore
|
||||
|
||||
.text
|
||||
|
||||
@ -97,15 +91,6 @@ falcon_save_loop:
|
||||
move.w 0xffff8266.w,(a0)+ | f_s
|
||||
move.w 0xffff8260.w,(a0)+ | st_s
|
||||
|
||||
| install custom VBL handler
|
||||
move sr,-(sp)
|
||||
or #0x700,sr
|
||||
|
||||
move.l 0x70.w,old_vbl
|
||||
move.l #vbl,0x70.w
|
||||
|
||||
move (sp)+,sr
|
||||
|
||||
movem.l (sp)+,d2-d7/a2
|
||||
rts
|
||||
|
||||
@ -132,14 +117,6 @@ _asm_screen_tt_restore:
|
||||
_asm_screen_falcon_restore:
|
||||
movem.l d2-d7/a2,-(sp)
|
||||
|
||||
| uninstall custom VBL handler
|
||||
move sr,-(sp)
|
||||
or #0x700,sr
|
||||
|
||||
move.l old_vbl,0x70.w
|
||||
|
||||
move (sp)+,sr
|
||||
|
||||
bsr wait_vbl | avoid flickering
|
||||
|
||||
lea save_video,a0
|
||||
@ -199,152 +176,16 @@ falcon_restore_loop:
|
||||
movem.l (sp)+,d2-d7/a2
|
||||
rts
|
||||
|
||||
| extern void asm_screen_set_tt_palette(const uint16 pPalette[256]);
|
||||
|
|
||||
_asm_screen_set_tt_palette:
|
||||
move.l (4,sp),a0
|
||||
lea 0xffff8400.w,a1
|
||||
moveq #256/2-1,d0
|
||||
|
||||
set_tt_palette_loop:
|
||||
move.l (a0)+,(a1)+
|
||||
dbra d0,set_tt_palette_loop
|
||||
rts
|
||||
|
||||
| extern void asm_screen_set_falcon_palette(const byte pPalette[256*3]);
|
||||
|
|
||||
_asm_screen_set_falcon_palette:
|
||||
move.l (4,sp),a0
|
||||
lea pending_palette,a1
|
||||
move.w #256-1,d0
|
||||
|
||||
set_falcon_palette_loop:
|
||||
clr.l d1
|
||||
move.w (a0)+,d1
|
||||
swap d1
|
||||
move.b (a0)+,d1
|
||||
move.l d1,(a1)+
|
||||
dbra d0,set_falcon_palette_loop
|
||||
|
||||
addq.w #1,has_pending_palette
|
||||
rts
|
||||
|
||||
| extern void asm_screen_set_vram(const void* pScreen);
|
||||
|
|
||||
_asm_screen_set_vram:
|
||||
move.l (4,sp),pending_vram
|
||||
|
||||
addq.w #1,has_pending_vram
|
||||
rts
|
||||
|
||||
| void asm_screen_set_scp_res(const void* pScp);
|
||||
|
|
||||
_asm_screen_set_scp_res:
|
||||
move.l (4,sp),a0
|
||||
lea (122,a0),a0
|
||||
lea pending_scp,a1
|
||||
moveq #(158-122)/4-1,d0
|
||||
set_scp_res_loop:
|
||||
move.l (a0)+,(a1)+
|
||||
dbra d0,set_scp_res_loop
|
||||
|
||||
addq.w #1,has_pending_scp
|
||||
rts
|
||||
|
||||
wait_vbl:
|
||||
move.w #0x25,-(sp) | Vsync()
|
||||
trap #14 |
|
||||
addq.l #2,sp |
|
||||
rts
|
||||
|
||||
.ascii "XBRA"
|
||||
.ascii "SCUM"
|
||||
old_vbl:
|
||||
dc.l 0
|
||||
vbl:
|
||||
movem.l d0-d1/a0-a1,-(sp)
|
||||
|
||||
addq.l #1,0x0462.w | _vbclock
|
||||
addq.l #1,0x0466.w | _frclock
|
||||
|
||||
tst.w has_pending_scp
|
||||
beq.b vbl_no_pending_scp
|
||||
|
||||
lea pending_scp,a0
|
||||
move.l (a0)+,0xffff8282.w
|
||||
move.l (a0)+,0xffff8286.w
|
||||
move.l (a0)+,0xffff828a.w
|
||||
move.l (a0)+,0xffff82a2.w
|
||||
move.l (a0)+,0xffff82a6.w
|
||||
move.l (a0)+,0xffff82aa.w
|
||||
move.w (a0)+,0xffff820a.w
|
||||
move.w (a0)+,0xffff82c0.w
|
||||
clr.w 0xffff8266.w
|
||||
tst.w (a0)+
|
||||
bne.b vbl_st
|
||||
|
||||
vbl_falcon:
|
||||
move.w (a0)+,0xffff8266.w
|
||||
bra.b vbl_skip
|
||||
|
||||
vbl_st: addq.l #1,a0
|
||||
move.b (a0)+,0xffff8260.w
|
||||
|
||||
vbl_skip:
|
||||
move.w (a0)+,0xffff82c2.w
|
||||
move.w (a0)+,0xffff8210.w
|
||||
|
||||
clr.w has_pending_scp
|
||||
vbl_no_pending_scp:
|
||||
|
||||
tst.w has_pending_vram
|
||||
beq.b vbl_no_pending_vram
|
||||
|
||||
move.l pending_vram,d0
|
||||
move.l d0,d1
|
||||
lsr.w #8,d0
|
||||
move.l d0,0xffff8200.w
|
||||
move.b d1,0xffff820d.w
|
||||
|
||||
clr.w has_pending_vram
|
||||
vbl_no_pending_vram:
|
||||
|
||||
tst.w has_pending_palette
|
||||
beq.b vbl_no_pending_palette
|
||||
|
||||
lea pending_palette,a0
|
||||
lea 0xffff9800.w,a1
|
||||
moveq #256/2-1,d0
|
||||
|
||||
vbl_falcon_palette_loop:
|
||||
move.l (a0)+,(a1)+
|
||||
move.l (a0)+,(a1)+
|
||||
dbra d0,vbl_falcon_palette_loop
|
||||
|
||||
clr.w has_pending_palette
|
||||
|
||||
vbl_no_pending_palette:
|
||||
movem.l (sp)+,d0-d1/a0-a1
|
||||
rte
|
||||
|
||||
|
||||
.bss
|
||||
.even
|
||||
|
||||
has_pending_scp:
|
||||
ds.w 1
|
||||
has_pending_vram:
|
||||
ds.w 1
|
||||
has_pending_palette:
|
||||
ds.w 1
|
||||
|
||||
pending_scp:
|
||||
ds.b 158-122 | pending SCP resolution data
|
||||
pending_vram:
|
||||
ds.l 1 | pending vram pointer
|
||||
pending_palette:
|
||||
ds.l 256 | pending palette
|
||||
|
||||
save_pal:
|
||||
ds.l 256+16/2 | old colours (sized for falcon+ste palette)
|
||||
save_video:
|
||||
|
@ -44,27 +44,6 @@ void asm_screen_tt_restore(void);
|
||||
*/
|
||||
void asm_screen_falcon_restore(void);
|
||||
|
||||
/**
|
||||
* Set Atari TT palette.
|
||||
* @param pPalette 256 palette entries (0000 RRRR GGGG BBBB)
|
||||
*/
|
||||
void asm_screen_set_tt_palette(const uint16 pPalette[256]);
|
||||
/**
|
||||
* Set Atari Falcon palette.
|
||||
* @param pPalette 256 palette entries (RRRRRRRR GGGGGGGG BBBBBBBB)
|
||||
*/
|
||||
void asm_screen_set_falcon_palette(const byte pPalette[256*3]);
|
||||
|
||||
/**
|
||||
* Set Atari TT/Falcon video base.
|
||||
*/
|
||||
void asm_screen_set_vram(const void* pScreen);
|
||||
|
||||
/**
|
||||
* Set Atari Falcon Videl resolution (Screenspain's SCP format).
|
||||
*/
|
||||
void asm_screen_set_scp_res(const void* pScp);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -31,7 +31,8 @@
|
||||
#define SV_VERSION ((volatile long*)0x8001007C)
|
||||
|
||||
inline static bool hasSuperVidel() {
|
||||
static bool hasSuperVidel = VgetMonitor() == MON_VGA && Getcookie(C_SupV, NULL) == C_FOUND;
|
||||
// this works also on the TT
|
||||
static bool hasSuperVidel = Getcookie(C_SupV, NULL) == C_FOUND && VgetMonitor() == MON_VGA;
|
||||
return hasSuperVidel;
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include <mint/osbind.h>
|
||||
|
||||
#include "backends/graphics/atari/atari-graphics-superblitter.h"
|
||||
#include "backends/graphics/atari/videl-resolutions.h"
|
||||
#include "common/debug.h" // error() & warning()
|
||||
#include "common/scummsys.h"
|
||||
|
||||
@ -47,12 +46,6 @@ public:
|
||||
else
|
||||
warning("SV_XBIOS has the pmmu boost disabled, set 'pmmu_boost = true' in C:\\SV.INF");
|
||||
|
||||
// patch SPSHIFT for SuperVidel's BPS8C
|
||||
for (byte *p : {scp_320x200x8_vga, scp_320x240x8_vga, scp_640x400x8_vga, scp_640x480x8_vga}) {
|
||||
uint16 *p16 = (uint16*)(p + 122 + 30);
|
||||
*p16 |= 0x1000;
|
||||
}
|
||||
|
||||
// using virtual methods so must be done here
|
||||
allocateSurfaces();
|
||||
}
|
||||
|
@ -71,25 +71,50 @@ private:
|
||||
// used for pixel reading; two common mistakes:
|
||||
// 1. (subRect.left, subRect.bottom) = beginning of the next line *including the offset*
|
||||
// 2. (subRect.right, subRect.bottom) = even worse, end of the *next* line, not current one
|
||||
if (subRect.width() == dstSurface.w) {
|
||||
asm_c2p1x1_8(
|
||||
(const byte*)srcSurface.getBasePtr(subRect.left, subRect.top),
|
||||
(const byte*)srcSurface.getBasePtr(subRect.right, subRect.bottom-1),
|
||||
(byte*)dstSurface.getBasePtr(destX, destY));
|
||||
} else {
|
||||
const byte *pChunky = (const byte *)srcSurface.getBasePtr(subRect.left, subRect.top);
|
||||
const byte *pChunkyEnd = (const byte *)srcSurface.getBasePtr(subRect.right, subRect.bottom-1);
|
||||
|
||||
const uint32 bitsPerPixel = dstSurface.format.isCLUT8() || dstSurface.format == PIXELFORMAT_RGB332 ? 8 : 4;
|
||||
const uint32 screenPitch = dstSurface.pitch * bitsPerPixel/8;
|
||||
|
||||
byte *pScreen = (byte *)dstSurface.getPixels() + destY * screenPitch + destX * bitsPerPixel/8;
|
||||
|
||||
if (bitsPerPixel == 8) {
|
||||
if (srcSurface.pitch == subRect.width()) {
|
||||
if (srcSurface.pitch == dstSurface.pitch) {
|
||||
asm_c2p1x1_8(pChunky, pChunkyEnd, pScreen);
|
||||
return;
|
||||
} else if (srcSurface.pitch == dstSurface.pitch/2) {
|
||||
asm_c2p1x1_8_tt(pChunky, pChunkyEnd, pScreen, screenPitch);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
asm_c2p1x1_8_rect(
|
||||
(const byte*)srcSurface.getBasePtr(subRect.left, subRect.top),
|
||||
(const byte*)srcSurface.getBasePtr(subRect.right, subRect.bottom-1),
|
||||
pChunky, pChunkyEnd,
|
||||
subRect.width(),
|
||||
srcSurface.pitch,
|
||||
(byte*)dstSurface.getBasePtr(destX, destY),
|
||||
dstSurface.pitch);
|
||||
pScreen,
|
||||
screenPitch);
|
||||
} else {
|
||||
// compare unmodified dst pitch
|
||||
if (srcSurface.pitch == subRect.width() && srcSurface.pitch == dstSurface.pitch) {
|
||||
asm_c2p1x1_4(pChunky, pChunkyEnd, pScreen);
|
||||
return;
|
||||
}
|
||||
|
||||
asm_c2p1x1_4_rect(
|
||||
pChunky, pChunkyEnd,
|
||||
subRect.width(),
|
||||
srcSurface.pitch,
|
||||
pScreen,
|
||||
screenPitch);
|
||||
}
|
||||
}
|
||||
|
||||
void copyRectToSurfaceWithKey(Graphics::Surface &dstSurface, const Graphics::Surface &bgSurface,
|
||||
const Graphics::Surface &srcSurface, int destX, int destY,
|
||||
const Common::Rect &subRect, uint32 key, const byte srcPalette[256*3]) const override {
|
||||
void copyRectToSurfaceWithKey(Graphics::Surface &dstSurface, const Graphics::Surface &srcSurface,
|
||||
int destX, int destY, const Common::Rect &subRect, uint32 key,
|
||||
const Graphics::Surface &bgSurface, const byte srcPalette[256*3]) const override {
|
||||
Common::Rect backgroundRect(destX, destY, destX + subRect.width(), destY + subRect.height());
|
||||
|
||||
// ensure that background's left and right lie on a 16px boundary and double the width if needed
|
||||
@ -116,34 +141,7 @@ private:
|
||||
cachedSurface.copyRectToSurface(bgSurface, 0, 0, backgroundRect);
|
||||
|
||||
// copy cursor
|
||||
if (cachedSurface.format == PIXELFORMAT_RGB332) {
|
||||
assert(srcSurface.format == PIXELFORMAT_CLUT8);
|
||||
|
||||
// Convert CLUT8 to RGB332 palette and do copyRectToSurfaceWithKey() at the same time
|
||||
const byte *src = (const byte*)srcSurface.getBasePtr(subRect.left, subRect.top);
|
||||
byte *dst = (byte*)cachedSurface.getBasePtr(deltaX, 0);
|
||||
|
||||
const int16 w = subRect.width();
|
||||
const int16 h = subRect.height();
|
||||
|
||||
for (int16 y = 0; y < h; ++y) {
|
||||
for (int16 x = 0; x < w; ++x) {
|
||||
const uint32 color = *src++;
|
||||
if (color != key) {
|
||||
*dst++ = (srcPalette[color*3 + 0] & 0xe0)
|
||||
| ((srcPalette[color*3 + 1] >> 3) & 0x1c)
|
||||
| ((srcPalette[color*3 + 2] >> 6) & 0x03);
|
||||
} else {
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
|
||||
src += (srcSurface.pitch - w);
|
||||
dst += (cachedSurface.pitch - w);
|
||||
}
|
||||
} else {
|
||||
cachedSurface.copyRectToSurfaceWithKey(srcSurface, deltaX, 0, subRect, key);
|
||||
}
|
||||
convertRectToSurfaceWithKey(cachedSurface, srcSurface, deltaX, 0, subRect, key, srcPalette);
|
||||
|
||||
copyRectToSurface(
|
||||
dstSurface,
|
||||
@ -151,14 +149,6 @@ private:
|
||||
backgroundRect.left, backgroundRect.top,
|
||||
Common::Rect(cachedSurface.w, cachedSurface.h));
|
||||
}
|
||||
|
||||
void alignRect(const Graphics::Surface &srcSurface, Common::Rect &rect) const override {
|
||||
// align on 16px
|
||||
rect.left &= 0xfff0;
|
||||
rect.right = (rect.right + 15) & 0xfff0;
|
||||
if (rect.right > srcSurface.w)
|
||||
rect.right = srcSurface.w;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -25,6 +25,7 @@
|
||||
#include "backends/graphics/graphics.h"
|
||||
|
||||
#include <mint/osbind.h>
|
||||
#include <mint/ostruct.h>
|
||||
#include <vector>
|
||||
|
||||
#include "common/events.h"
|
||||
@ -67,12 +68,18 @@ public:
|
||||
void showOverlay(bool inGUI) override;
|
||||
void hideOverlay() override;
|
||||
bool isOverlayVisible() const override { return _overlayVisible; }
|
||||
Graphics::PixelFormat getOverlayFormat() const override { return PIXELFORMAT_RGB332; }
|
||||
Graphics::PixelFormat getOverlayFormat() const override {
|
||||
#ifndef DISABLE_FANCY_THEMES
|
||||
return _tt ? PIXELFORMAT_RGB121 : PIXELFORMAT_RGB332;
|
||||
#else
|
||||
return PIXELFORMAT_RGB121;
|
||||
#endif
|
||||
}
|
||||
void clearOverlay() override;
|
||||
void grabOverlay(Graphics::Surface &surface) const override;
|
||||
void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) override;
|
||||
int16 getOverlayHeight() const override { return 480; }
|
||||
int16 getOverlayWidth() const override { return 640; }
|
||||
int16 getOverlayWidth() const override { return _vgaMonitor ? 640 : 640*1.2; }
|
||||
|
||||
bool showMouse(bool visible) override;
|
||||
void warpMouse(int x, int y) override;
|
||||
@ -89,12 +96,16 @@ public:
|
||||
protected:
|
||||
const Graphics::PixelFormat PIXELFORMAT_CLUT8 = Graphics::PixelFormat::createFormatCLUT8();
|
||||
const Graphics::PixelFormat PIXELFORMAT_RGB332 = Graphics::PixelFormat(1, 3, 3, 2, 0, 5, 2, 0, 0);
|
||||
const Graphics::PixelFormat PIXELFORMAT_RGB121 = Graphics::PixelFormat(1, 1, 2, 1, 0, 3, 1, 0, 0);
|
||||
|
||||
typedef void* (*AtariMemAlloc)(size_t bytes);
|
||||
typedef void (*AtariMemFree)(void *ptr);
|
||||
|
||||
void allocateSurfaces();
|
||||
void freeSurfaces();
|
||||
void convertRectToSurfaceWithKey(Graphics::Surface &dstSurface, const Graphics::Surface &srcSurface,
|
||||
int destX, int destY, const Common::Rect &subRect, uint32 key,
|
||||
const byte srcPalette[256*3]) const;
|
||||
|
||||
enum class GraphicsMode : int {
|
||||
DirectRendering = 0,
|
||||
@ -117,12 +128,27 @@ protected:
|
||||
GraphicsState _pendingState{ (GraphicsMode)getDefaultGraphicsMode() };
|
||||
|
||||
private:
|
||||
enum {
|
||||
// maximum screen dimensions
|
||||
SCREEN_WIDTH = 640,
|
||||
SCREEN_HEIGHT = 480
|
||||
// use std::vector as its clear() doesn't reset capacity
|
||||
using DirtyRects = std::vector<Common::Rect>;
|
||||
|
||||
enum CustomEventAction {
|
||||
kActionToggleAspectRatioCorrection = 100,
|
||||
};
|
||||
|
||||
enum SteTtRezValue {
|
||||
kRezValueSTLow = 0, // 320x200@4bpp, ST palette
|
||||
kRezValueSTMid = 1, // 640x200@2bpp, ST palette
|
||||
kRezValueSTHigh = 2, // 640x400@1bpp, ST palette
|
||||
kRezValueTTLow = 7, // 320x480@8bpp, TT palette
|
||||
kRezValueTTMid = 4, // 640x480@4bpp, TT palette
|
||||
kRezValueTTHigh = 6 // 1280x960@1bpp, TT palette
|
||||
};
|
||||
|
||||
int16 getMaximumScreenHeight() const { return 480; }
|
||||
int16 getMaximumScreenWidth() const { return _tt ? 320 : (_vgaMonitor ? 640 : 640*1.2); }
|
||||
|
||||
bool updateScreenInternal(const Graphics::Surface &srcSurface, const DirtyRects &dirtyRects);
|
||||
|
||||
virtual AtariMemAlloc getStRamAllocFunc() const {
|
||||
return [](size_t bytes) { return (void*)Mxalloc(bytes, MX_STRAM); };
|
||||
}
|
||||
@ -130,29 +156,16 @@ private:
|
||||
return [](void *ptr) { Mfree(ptr); };
|
||||
}
|
||||
|
||||
// use std::vector as its clear() doesn't reset capacity
|
||||
using DirtyRects = std::vector<Common::Rect>;
|
||||
|
||||
enum CustomEventAction {
|
||||
kActionToggleAspectRatioCorrection = 100,
|
||||
};
|
||||
|
||||
void setVidelResolution() const;
|
||||
|
||||
bool updateDirect();
|
||||
bool updateBuffered(const Graphics::Surface &srcSurface, const DirtyRects &dirtyRects);
|
||||
|
||||
virtual void copyRectToSurface(Graphics::Surface &dstSurface,
|
||||
const Graphics::Surface &srcSurface, int destX, int destY,
|
||||
const Common::Rect &subRect) const {
|
||||
dstSurface.copyRectToSurface(srcSurface, destX, destY, subRect);
|
||||
}
|
||||
virtual void copyRectToSurfaceWithKey(Graphics::Surface &dstSurface, const Graphics::Surface &bgSurface,
|
||||
const Graphics::Surface &srcSurface, int destX, int destY,
|
||||
const Common::Rect &subRect, uint32 key, const byte srcPalette[256*3]) const {
|
||||
dstSurface.copyRectToSurfaceWithKey(srcSurface, destX, destY, subRect, key);
|
||||
virtual void copyRectToSurfaceWithKey(Graphics::Surface &dstSurface, const Graphics::Surface &srcSurface,
|
||||
int destX, int destY, const Common::Rect &subRect, uint32 key,
|
||||
const Graphics::Surface &bgSurface, const byte srcPalette[256*3]) const {
|
||||
convertRectToSurfaceWithKey(dstSurface, srcSurface, destX, destY, subRect, key, srcPalette);
|
||||
}
|
||||
virtual void alignRect(const Graphics::Surface &srcSurface, Common::Rect &rect) const {}
|
||||
|
||||
void cursorPositionChanged() {
|
||||
if (_overlayVisible) {
|
||||
@ -176,7 +189,27 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void cursorVisibilityChanged() {
|
||||
if (_overlayVisible) {
|
||||
_screen[OVERLAY_BUFFER]->cursorVisibilityChanged = true;
|
||||
} else {
|
||||
_screen[FRONT_BUFFER]->cursorVisibilityChanged
|
||||
= _screen[BACK_BUFFER1]->cursorVisibilityChanged
|
||||
= _screen[BACK_BUFFER2]->cursorVisibilityChanged
|
||||
= true;
|
||||
}
|
||||
}
|
||||
|
||||
int getOverlayPaletteSize() const {
|
||||
#ifndef DISABLE_FANCY_THEMES
|
||||
return _tt ? 16 : 256;
|
||||
#else
|
||||
return 16;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool _vgaMonitor = true;
|
||||
bool _tt = false;
|
||||
bool _aspectRatioCorrection = false;
|
||||
bool _oldAspectRatioCorrection = false;
|
||||
|
||||
@ -184,7 +217,7 @@ private:
|
||||
|
||||
enum PendingScreenChange {
|
||||
kPendingScreenChangeNone = 0,
|
||||
kPendingScreenChangeOverlay = 1<<0,
|
||||
kPendingScreenChangeMode = 1<<0,
|
||||
kPendingScreenChangeScreen = 1<<1,
|
||||
kPendingScreenChangePalette = 1<<2
|
||||
};
|
||||
@ -198,44 +231,48 @@ private:
|
||||
BUFFER_COUNT
|
||||
};
|
||||
|
||||
struct Screen {
|
||||
Screen(AtariGraphicsManager *manager, int width, int height, const Graphics::PixelFormat &format);
|
||||
~Screen();
|
||||
|
||||
void reset(int width, int height) {
|
||||
cursorPositionChanged = true;
|
||||
cursorSurfaceChanged = false;
|
||||
clearDirtyRects();
|
||||
oldCursorRect = Common::Rect();
|
||||
|
||||
// erase old screen
|
||||
surf.fillRect(Common::Rect(surf.w, surf.h), 0);
|
||||
// set new dimensions
|
||||
surf.pitch = width;
|
||||
surf.w = width;
|
||||
surf.h = height;
|
||||
class Palette {
|
||||
public:
|
||||
void clear() {
|
||||
memset(data, 0, sizeof(data));
|
||||
}
|
||||
|
||||
void addDirtyRect(Common::Rect rect);
|
||||
uint16 *const tt = reinterpret_cast<uint16*>(data);
|
||||
_RGB *const falcon = reinterpret_cast<_RGB*>(data);
|
||||
|
||||
private:
|
||||
byte data[256*4] = {};
|
||||
};
|
||||
|
||||
struct Screen {
|
||||
Screen(AtariGraphicsManager *manager, int width, int height, const Graphics::PixelFormat &format, const Palette *palette);
|
||||
~Screen();
|
||||
|
||||
void reset(int width, int height, int bitsPerPixel);
|
||||
void addDirtyRect(const Graphics::Surface &srcSurface, Common::Rect rect);
|
||||
|
||||
void clearDirtyRects() {
|
||||
dirtyRects.clear();
|
||||
_fullRedraw = false;
|
||||
fullRedraw = false;
|
||||
}
|
||||
|
||||
const bool &fullRedrawPending = _fullRedraw;
|
||||
|
||||
Graphics::Surface surf;
|
||||
const Palette *palette;
|
||||
bool cursorPositionChanged = true;
|
||||
bool cursorSurfaceChanged = false;
|
||||
bool cursorVisibilityChanged = false;
|
||||
DirtyRects dirtyRects = DirtyRects(512); // reserve 512 rects
|
||||
bool fullRedraw = false;
|
||||
Common::Rect oldCursorRect;
|
||||
int rez = -1;
|
||||
int mode = -1;
|
||||
Graphics::Surface *const offsettedSurf = &_offsettedSurf;
|
||||
|
||||
private:
|
||||
static constexpr size_t ALIGN = 16; // 16 bytes
|
||||
|
||||
bool _fullRedraw = false;
|
||||
AtariGraphicsManager *_manager;
|
||||
Graphics::Surface _offsettedSurf;
|
||||
};
|
||||
Screen *_screen[BUFFER_COUNT] = {};
|
||||
Screen *_workScreen = nullptr;
|
||||
@ -294,8 +331,8 @@ private:
|
||||
int hotspotY;
|
||||
} _cursor;
|
||||
|
||||
byte _palette[256*3] = {};
|
||||
byte _overlayPalette[256*3] = {};
|
||||
Palette _palette;
|
||||
Palette _overlayPalette;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -23,7 +23,10 @@
|
||||
| See https://github.com/Kalmalyzer/kalms-c2p
|
||||
|
||||
.globl _asm_c2p1x1_8
|
||||
.globl _asm_c2p1x1_8_tt
|
||||
.globl _asm_c2p1x1_8_rect
|
||||
.globl _asm_c2p1x1_4
|
||||
.globl _asm_c2p1x1_4_rect
|
||||
|
||||
|
||||
.text
|
||||
@ -225,6 +228,221 @@ c2p1x1_8_start:
|
||||
rts
|
||||
|
||||
|
||||
| void asm_c2p1x1_8_tt(const byte *pChunky, const byte *pChunkyEnd, byte *pScreen, uint32 screenPitch);
|
||||
_asm_c2p1x1_8_tt:
|
||||
movem.l d2-d7/a2-a6,-(sp) | 6 + 5 = 11 longs
|
||||
|
||||
move.l (11*4+4,sp),a0 | a0: chunky
|
||||
move.l (11*4+8,sp),a2 | a2: chunky end
|
||||
move.l (11*4+12,sp),a1 | a1: screen
|
||||
move.l (11*4+16,sp),d0 | d0.l: screen pitch (double width)
|
||||
|
||||
move.l sp,old_sp
|
||||
|
||||
move.l d0,screen_pitch
|
||||
|
||||
lsr.l #1,d0
|
||||
lea (a1,d0.l),a7 | a7: end of first dst line
|
||||
|
||||
move.l d0,screen_offset
|
||||
|
||||
move.l #0x0f0f0f0f,d4
|
||||
move.l #0x00ff00ff,d5
|
||||
move.l #0x55555555,d6
|
||||
|
||||
move.l (a0)+,d0
|
||||
move.l (a0)+,d1
|
||||
move.l (a0)+,d2
|
||||
move.l (a0)+,d3
|
||||
|
||||
| a7a6a5a4a3a2a1a0 b7b6b5b4b3b2b1b0 c7c6c5c4c3c2c1c0 d7d6d5d4d3d2d1d0
|
||||
| e7e6e5e4e3e2e1e0 f7f6f5f4f3f2f1f0 g7g6g5g4g3g2g1g0 h7h6h5h4h3h2h1h0
|
||||
| i7i6i5i4i3i2i1i0 j7j6j5j4j3j2j1j0 k7k6k5k4k3k2k1k0 l7l6l5l4l3l2l1l0
|
||||
| m7m6m5m4m3m2m1m0 n7n6n5n4n3n2n1n0 o7o6o5o4o3o2o1o0 p7p6p5p4p3p2p1p0
|
||||
|
||||
move.l d1,d7
|
||||
lsr.l #4,d7
|
||||
eor.l d0,d7
|
||||
and.l d4,d7
|
||||
eor.l d7,d0
|
||||
lsl.l #4,d7
|
||||
eor.l d7,d1
|
||||
move.l d3,d7
|
||||
lsr.l #4,d7
|
||||
eor.l d2,d7
|
||||
and.l d4,d7
|
||||
eor.l d7,d2
|
||||
lsl.l #4,d7
|
||||
eor.l d7,d3
|
||||
|
||||
| a7a6a5a4e7e6e5e4 b7b6b5b4f7f6f5f4 c7c6c5c4g7g6g5g4 d7d6d5d4h7h6h5h4
|
||||
| a3a2a1a0e3e2e1e0 b3b2b1b0f3f2f1f0 c3c2c1c0g3g2g1g0 d3d2d1d0h3h2h1h0
|
||||
| i7i6i5i4m7m6m5m4 j7j6j5j4n7n6n5n4 k7k6k5k4o7o6o5o4 l7l6l5l4p7p6p5p4
|
||||
| i3i2i1i0m3m2m1m0 j3j2j1j0n3n2n1n0 k3k2k1k0o3o2o1o0 l3l2l1l0p3p2p1p0
|
||||
|
||||
move.l d2,d7
|
||||
lsr.l #8,d7
|
||||
eor.l d0,d7
|
||||
and.l d5,d7
|
||||
eor.l d7,d0
|
||||
lsl.l #8,d7
|
||||
eor.l d7,d2
|
||||
move.l d3,d7
|
||||
lsr.l #8,d7
|
||||
eor.l d1,d7
|
||||
and.l d5,d7
|
||||
eor.l d7,d1
|
||||
lsl.l #8,d7
|
||||
eor.l d7,d3
|
||||
|
||||
| a7a6a5a4e7e6e5e4 i7i6i5i4m7m6m5m4 c7c6c5c4g7g6g5g4 k7k6k5k4o7o6o5o4
|
||||
| a3a2a1a0e3e2e1e0 i3i2i1i0m3m2m1m0 c3c2c1c0g3g2g1g0 k3k2k1k0o3o2o1o0
|
||||
| b7b6b5b4f7f6f5f4 j7j6j5j4n7n6n5n4 d7d6d5d4h7h6h5h4 l7l6l5l4p7p6p5p4
|
||||
| b3b2b1b0f3f2f1f0 j3j2j1j0n3n2n1n0 d3d2d1d0h3h2h1h0 l3l2l1l0p3p2p1p0
|
||||
|
||||
bra.s c2p1x1_8_tt_start
|
||||
|
||||
c2p1x1_8_tt_pix16:
|
||||
move.l (a0)+,d0
|
||||
move.l (a0)+,d1
|
||||
move.l (a0)+,d2
|
||||
move.l (a0)+,d3
|
||||
|
||||
| a7a6a5a4a3a2a1a0 b7b6b5b4b3b2b1b0 c7c6c5c4c3c2c1c0 d7d6d5d4d3d2d1d0
|
||||
| e7e6e5e4e3e2e1e0 f7f6f5f4f3f2f1f0 g7g6g5g4g3g2g1g0 h7h6h5h4h3h2h1h0
|
||||
| i7i6i5i4i3i2i1i0 j7j6j5j4j3j2j1j0 k7k6k5k4k3k2k1k0 l7l6l5l4l3l2l1l0
|
||||
| m7m6m5m4m3m2m1m0 n7n6n5n4n3n2n1n0 o7o6o5o4o3o2o1o0 p7p6p5p4p3p2p1p0
|
||||
|
||||
move.l d1,d7
|
||||
lsr.l #4,d7
|
||||
move.l a3,(a1)+
|
||||
eor.l d0,d7
|
||||
and.l d4,d7
|
||||
eor.l d7,d0
|
||||
lsl.l #4,d7
|
||||
eor.l d7,d1
|
||||
move.l d3,d7
|
||||
lsr.l #4,d7
|
||||
eor.l d2,d7
|
||||
and.l d4,d7
|
||||
eor.l d7,d2
|
||||
move.l a4,(a1)+
|
||||
lsl.l #4,d7
|
||||
eor.l d7,d3
|
||||
|
||||
| a7a6a5a4e7e6e5e4 b7b6b5b4f7f6f5f4 c7c6c5c4g7g6g5g4 d7d6d5d4h7h6h5h4
|
||||
| a3a2a1a0e3e2e1e0 b3b2b1b0f3f2f1f0 c3c2c1c0g3g2g1g0 d3d2d1d0h3h2h1h0
|
||||
| i7i6i5i4m7m6m5m4 j7j6j5j4n7n6n5n4 k7k6k5k4o7o6o5o4 l7l6l5l4p7p6p5p4
|
||||
| i3i2i1i0m3m2m1m0 j3j2j1j0n3n2n1n0 k3k2k1k0o3o2o1o0 l3l2l1l0p3p2p1p0
|
||||
|
||||
move.l d2,d7
|
||||
lsr.l #8,d7
|
||||
eor.l d0,d7
|
||||
and.l d5,d7
|
||||
eor.l d7,d0
|
||||
move.l a5,(a1)+
|
||||
lsl.l #8,d7
|
||||
eor.l d7,d2
|
||||
move.l d3,d7
|
||||
lsr.l #8,d7
|
||||
eor.l d1,d7
|
||||
and.l d5,d7
|
||||
eor.l d7,d1
|
||||
move.l a6,(a1)+
|
||||
lsl.l #8,d7
|
||||
eor.l d7,d3
|
||||
|
||||
| a7a6a5a4e7e6e5e4 i7i6i5i4m7m6m5m4 c7c6c5c4g7g6g5g4 k7k6k5k4o7o6o5o4
|
||||
| a3a2a1a0e3e2e1e0 i3i2i1i0m3m2m1m0 c3c2c1c0g3g2g1g0 k3k2k1k0o3o2o1o0
|
||||
| b7b6b5b4f7f6f5f4 j7j6j5j4n7n6n5n4 d7d6d5d4h7h6h5h4 l7l6l5l4p7p6p5p4
|
||||
| b3b2b1b0f3f2f1f0 j3j2j1j0n3n2n1n0 d3d2d1d0h3h2h1h0 l3l2l1l0p3p2p1p0
|
||||
|
||||
cmp.l a1,a7 | end of dst line?
|
||||
bne.s c2p1x1_8_tt_start
|
||||
|
||||
add.l (screen_offset,pc),a1
|
||||
add.l (screen_pitch,pc),a7
|
||||
|
||||
c2p1x1_8_tt_start:
|
||||
move.l d2,d7
|
||||
lsr.l #1,d7
|
||||
eor.l d0,d7
|
||||
and.l d6,d7
|
||||
eor.l d7,d0
|
||||
add.l d7,d7
|
||||
eor.l d7,d2
|
||||
move.l d3,d7
|
||||
lsr.l #1,d7
|
||||
eor.l d1,d7
|
||||
and.l d6,d7
|
||||
eor.l d7,d1
|
||||
add.l d7,d7
|
||||
eor.l d7,d3
|
||||
|
||||
| a7b7a5b5e7f7e5f5 i7j7i5j5m7n7m5n5 c7d7c5d5g7h7g5h5 k7l7k5l5o7p7o5p5
|
||||
| a3b3a1b1e3f3e1f1 i3j3i1j1m3n3m1n1 c3d3c1d1g3h3g1h1 k3l3k1l1o3p3o1p1
|
||||
| a6b6a4b4e6f6e4f4 i6j6i4j4m6n6m4n4 c6d6c4d4g6h6g4h4 k6l6k4l4o6p6o4p4
|
||||
| a2b2a0b0e2f2e0f0 i2j2i0j0m2n2m0n0 c2d2c0d0g2h2g0h0 k2l2k0l0o2p2o0p0
|
||||
|
||||
move.w d2,d7
|
||||
move.w d0,d2
|
||||
swap d2
|
||||
move.w d2,d0
|
||||
move.w d7,d2
|
||||
move.w d3,d7
|
||||
move.w d1,d3
|
||||
swap d3
|
||||
move.w d3,d1
|
||||
move.w d7,d3
|
||||
|
||||
| a7b7a5b5e7f7e5f5 i7j7i5j5m7n7m5n5 a6b6a4b4e6f6e4f4 i6j6i4j4m6n6m4n4
|
||||
| a3b3a1b1e3f3e1f1 i3j3i1j1m3n3m1n1 a2b2a0b0e2f2e0f0 i2j2i0j0m2n2m0n0
|
||||
| c7d7c5d5g7h7g5h5 k7l7k5l5o7p7o5p5 c6d6c4d4g6h6g4h4 k6l6k4l4o6p6o4p4
|
||||
| c3d3c1d1g3h3g1h1 k3l3k1l1o3p3o1p1 c2d2c0d0g2h2g0h0 k2l2k0l0o2p2o0p0
|
||||
|
||||
move.l d2,d7
|
||||
lsr.l #2,d7
|
||||
eor.l d0,d7
|
||||
and.l #0x33333333,d7
|
||||
eor.l d7,d0
|
||||
lsl.l #2,d7
|
||||
eor.l d7,d2
|
||||
move.l d3,d7
|
||||
lsr.l #2,d7
|
||||
eor.l d1,d7
|
||||
and.l #0x33333333,d7
|
||||
eor.l d7,d1
|
||||
lsl.l #2,d7
|
||||
eor.l d7,d3
|
||||
|
||||
| a7b7c7d7e7f7g7h7 i7j7k7l7m7n7o7p7 a6b6c6d6e6f6g6h6 i6j6k6l6m6n6o6p6
|
||||
| a3b3c3d3e3f3g3h3 i3j3k3l3m3n3o3p3 a2b2c2d2e2f2g2h2 i2j2k2l2m2n2o2p2
|
||||
| a5b5c5d5e5f5g5h5 i5j5k5l5m5n5o5p5 a4b4c4d4e4f4g4h4 i4j4k4l4m4n4o4p4
|
||||
| a1b1c1d1e1f1g1h1 i1j1k1l1m1n1o1p1 a0b0c0d0e0f0g0h0 i0j0k0l0m0n0o0p0
|
||||
|
||||
swap d0
|
||||
swap d1
|
||||
swap d2
|
||||
swap d3
|
||||
|
||||
move.l d0,a6
|
||||
move.l d2,a5
|
||||
move.l d1,a4
|
||||
move.l d3,a3
|
||||
|
||||
cmp.l a0,a2
|
||||
bne c2p1x1_8_tt_pix16
|
||||
|
||||
move.l a3,(a1)+
|
||||
move.l a4,(a1)+
|
||||
move.l a5,(a1)+
|
||||
move.l a6,(a1)+
|
||||
|
||||
move.l old_sp,sp
|
||||
movem.l (sp)+,d2-d7/a2-a6
|
||||
rts
|
||||
|
||||
|
||||
| void asm_c2p1x1_8_rect(const byte *pChunky, const byte *pChunkyEnd, uint32 chunkyWidth, uint32 chunkyPitch, byte *pScreen, uint32 screenPitch);
|
||||
_asm_c2p1x1_8_rect:
|
||||
movem.l d2-d7/a2-a6,-(sp) | 6 + 5 = 11 longs
|
||||
@ -456,6 +674,253 @@ c2p1x1_8_rect_done:
|
||||
movem.l (sp)+,d2-d7/a2-a6
|
||||
rts
|
||||
|
||||
|
||||
| void asm_c2p1x1_4(const byte *pChunky, const byte *pChunkyEnd, byte *pScreen);
|
||||
_asm_c2p1x1_4:
|
||||
move.l (4,sp),a0 | chunky
|
||||
move.l (8,sp),d0 | chunky end
|
||||
move.l (12,sp),a1 | screen
|
||||
movem.l d2-d7/a2-a6,-(sp)
|
||||
move.l d0,a2
|
||||
move.l #0x0f0f0f0f,d4
|
||||
move.l #0x00ff00ff,d5
|
||||
move.l #0x55555555,d6
|
||||
|
||||
move.l (a0)+,d0
|
||||
move.l (a0)+,d2
|
||||
move.l (a0)+,d1
|
||||
move.l (a0)+,d3
|
||||
and.l d4,d0
|
||||
and.l d4,d2
|
||||
and.l d4,d1
|
||||
and.l d4,d3
|
||||
lsl.l #4,d0
|
||||
lsl.l #4,d1
|
||||
or.l d2,d0
|
||||
or.l d3,d1
|
||||
bra.s c2p1x1_4_start
|
||||
|
||||
c2p1x1_4_pix16:
|
||||
move.l (a0)+,d0
|
||||
move.l (a0)+,d2
|
||||
move.l (a0)+,d1
|
||||
move.l (a0)+,d3
|
||||
and.l d4,d0
|
||||
and.l d4,d2
|
||||
move.l a5,(a1)+
|
||||
and.l d4,d1
|
||||
and.l d4,d3
|
||||
move.l a6,(a1)+
|
||||
lsl.l #4,d0
|
||||
lsl.l #4,d1
|
||||
or.l d2,d0
|
||||
or.l d3,d1
|
||||
|
||||
c2p1x1_4_start:
|
||||
|
||||
| a3a2a1a0e3e2e1e0 b3b2b1b0f3f2f1f0 c3c2c1c0g3g2g1g0 d3d2d1d0h3h2h1h0
|
||||
| i3i2i1i0m3m2m1m0 j3j2j1j0n3n2n1n0 k3k2k1k0o3o2o1o0 l3l2l1l0p3p2p1p0
|
||||
|
||||
move.l d1,d7
|
||||
lsr.l #8,d7
|
||||
eor.l d0,d7
|
||||
and.l d5,d7
|
||||
eor.l d7,d0
|
||||
lsl.l #8,d7
|
||||
eor.l d7,d1
|
||||
|
||||
| a3a2a1a0e3e2e1e0 i3i2i1i0m3m2m1m0 c3c2c1c0g3g2g1g0 k3k2k1k0o3o2o1o0
|
||||
| b3b2b1b0f3f2f1f0 j3j2j1j0n3n2n1n0 d3d2d1d0h3h2h1h0 l3l2l1l0p3p2p1p0
|
||||
|
||||
move.l d1,d7
|
||||
lsr.l #1,d7
|
||||
eor.l d0,d7
|
||||
and.l d6,d7
|
||||
eor.l d7,d0
|
||||
add.l d7,d7
|
||||
eor.l d7,d1
|
||||
|
||||
| a3b3a1b1e3f3e1f1 i3j3i1j1m3n3m1n1 c3d3c1d1g3h3g1h1 k3l3k1l1o3p3o1p1
|
||||
| a2b2a0b0e2f2e0f0 i2j2i0j0m2n2m0n0 c2d2c0d0g2h2g0h0 k2l2k0l0o2p2o0p0
|
||||
|
||||
move.w d1,d7
|
||||
move.w d0,d1
|
||||
swap d1
|
||||
move.w d1,d0
|
||||
move.w d7,d1
|
||||
|
||||
| a3b3a1b1e3f3e1f1 i3j3i1j1m3n3m1n1 a2b2a0b0e2f2e0f0 i2j2i0j0m2n2m0n0
|
||||
| c3d3c1d1g3h3g1h1 k3l3k1l1o3p3o1p1 c2d2c0d0g2h2g0h0 k2l2k0l0o2p2o0p0
|
||||
|
||||
move.l d1,d7
|
||||
lsr.l #2,d7
|
||||
eor.l d0,d7
|
||||
and.l #0x33333333,d7
|
||||
eor.l d7,d0
|
||||
lsl.l #2,d7
|
||||
eor.l d7,d1
|
||||
|
||||
| a3b3c3d3e3f3g3h3 i3j3k3l3m3n3o3p3 a2b2c2d2e2f2g2h2 i2j2k2l2m2n2o2p2
|
||||
| a1b1c1d1e1f1g1h1 i1j1k1l1m1n1o1p1 a0b0c0d0e0f0g0h0 i0j0k0l0m0n0o0p0
|
||||
|
||||
swap d0
|
||||
swap d1
|
||||
|
||||
move.l d1,a5
|
||||
move.l d0,a6
|
||||
|
||||
cmp.l a0,a2
|
||||
bne.s c2p1x1_4_pix16
|
||||
|
||||
move.l a5,(a1)+
|
||||
move.l a6,(a1)+
|
||||
|
||||
movem.l (sp)+,d2-d7/a2-a6
|
||||
rts
|
||||
|
||||
|
||||
| void asm_c2p1x1_4_rect(const byte *pChunky, const byte *pChunkyEnd, uint32 chunkyWidth, uint32 chunkyPitch, byte *pScreen, uint32 screenPitch);
|
||||
_asm_c2p1x1_4_rect:
|
||||
movem.l d2-d7/a2-a6,-(sp) | 6 + 5 = 11 longs
|
||||
|
||||
move.l (11*4+4,sp),a0 | a0: chunky
|
||||
move.l (11*4+8,sp),chunky_end
|
||||
move.l (11*4+12,sp),d0 | d0.l: chunky width
|
||||
move.l (11*4+16,sp),d2 | d2.l: chunky pitch
|
||||
move.l (11*4+20,sp),a1 | a1: screen
|
||||
move.l (11*4+24,sp),d1 | d1.l: screen pitch
|
||||
|
||||
move.l sp,old_sp
|
||||
|
||||
move.l d0,d3 | d3.l: screen width
|
||||
lsr.l #1,d3 |
|
||||
|
||||
lea (a0,d0.l),a2 | a2: end of first src line
|
||||
lea (a1,d3.l),a7 | a7: end of first dst line
|
||||
|
||||
move.l d1,screen_pitch
|
||||
|
||||
sub.l d3,d1
|
||||
move.l d1,screen_offset
|
||||
|
||||
move.l d2,chunky_pitch
|
||||
|
||||
sub.l d0,d2
|
||||
move.l d2,chunky_offset
|
||||
|
||||
move.l #0x0f0f0f0f,d4
|
||||
move.l #0x00ff00ff,d5
|
||||
move.l #0x55555555,d6
|
||||
|
||||
move.l (a0)+,d0
|
||||
move.l (a0)+,d2
|
||||
move.l (a0)+,d1
|
||||
move.l (a0)+,d3
|
||||
and.l d4,d0
|
||||
and.l d4,d2
|
||||
and.l d4,d1
|
||||
and.l d4,d3
|
||||
lsl.l #4,d0
|
||||
lsl.l #4,d1
|
||||
or.l d2,d0
|
||||
or.l d3,d1
|
||||
bra.s c2p1x1_4_rect_start
|
||||
|
||||
c2p1x1_4_rect_pix16:
|
||||
move.l (a0)+,d0
|
||||
move.l (a0)+,d2
|
||||
move.l (a0)+,d1
|
||||
move.l (a0)+,d3
|
||||
and.l d4,d0
|
||||
and.l d4,d2
|
||||
move.l a5,(a1)+
|
||||
and.l d4,d1
|
||||
and.l d4,d3
|
||||
move.l a6,(a1)+
|
||||
lsl.l #4,d0
|
||||
lsl.l #4,d1
|
||||
or.l d2,d0
|
||||
or.l d3,d1
|
||||
|
||||
cmp.l a1,a7 | end of dst line?
|
||||
bne.s c2p1x1_4_rect_start
|
||||
|
||||
add.l (screen_offset,pc),a1
|
||||
add.l (screen_pitch,pc),a7
|
||||
|
||||
c2p1x1_4_rect_start:
|
||||
|
||||
| a3a2a1a0e3e2e1e0 b3b2b1b0f3f2f1f0 c3c2c1c0g3g2g1g0 d3d2d1d0h3h2h1h0
|
||||
| i3i2i1i0m3m2m1m0 j3j2j1j0n3n2n1n0 k3k2k1k0o3o2o1o0 l3l2l1l0p3p2p1p0
|
||||
|
||||
move.l d1,d7
|
||||
lsr.l #8,d7
|
||||
eor.l d0,d7
|
||||
and.l d5,d7
|
||||
eor.l d7,d0
|
||||
lsl.l #8,d7
|
||||
eor.l d7,d1
|
||||
|
||||
| a3a2a1a0e3e2e1e0 i3i2i1i0m3m2m1m0 c3c2c1c0g3g2g1g0 k3k2k1k0o3o2o1o0
|
||||
| b3b2b1b0f3f2f1f0 j3j2j1j0n3n2n1n0 d3d2d1d0h3h2h1h0 l3l2l1l0p3p2p1p0
|
||||
|
||||
move.l d1,d7
|
||||
lsr.l #1,d7
|
||||
eor.l d0,d7
|
||||
and.l d6,d7
|
||||
eor.l d7,d0
|
||||
add.l d7,d7
|
||||
eor.l d7,d1
|
||||
|
||||
| a3b3a1b1e3f3e1f1 i3j3i1j1m3n3m1n1 c3d3c1d1g3h3g1h1 k3l3k1l1o3p3o1p1
|
||||
| a2b2a0b0e2f2e0f0 i2j2i0j0m2n2m0n0 c2d2c0d0g2h2g0h0 k2l2k0l0o2p2o0p0
|
||||
|
||||
move.w d1,d7
|
||||
move.w d0,d1
|
||||
swap d1
|
||||
move.w d1,d0
|
||||
move.w d7,d1
|
||||
|
||||
| a3b3a1b1e3f3e1f1 i3j3i1j1m3n3m1n1 a2b2a0b0e2f2e0f0 i2j2i0j0m2n2m0n0
|
||||
| c3d3c1d1g3h3g1h1 k3l3k1l1o3p3o1p1 c2d2c0d0g2h2g0h0 k2l2k0l0o2p2o0p0
|
||||
|
||||
move.l d1,d7
|
||||
lsr.l #2,d7
|
||||
eor.l d0,d7
|
||||
and.l #0x33333333,d7
|
||||
eor.l d7,d0
|
||||
lsl.l #2,d7
|
||||
eor.l d7,d1
|
||||
|
||||
| a3b3c3d3e3f3g3h3 i3j3k3l3m3n3o3p3 a2b2c2d2e2f2g2h2 i2j2k2l2m2n2o2p2
|
||||
| a1b1c1d1e1f1g1h1 i1j1k1l1m1n1o1p1 a0b0c0d0e0f0g0h0 i0j0k0l0m0n0o0p0
|
||||
|
||||
swap d0
|
||||
swap d1
|
||||
|
||||
move.l d1,a5
|
||||
move.l d0,a6
|
||||
|
||||
cmp.l a0,a2 | end of src line?
|
||||
bne c2p1x1_4_rect_pix16
|
||||
|
||||
cmp.l (chunky_end,pc),a2
|
||||
beq.s c2p1x1_4_rect_done
|
||||
|
||||
add.l (chunky_offset,pc),a0
|
||||
add.l (chunky_pitch,pc),a2
|
||||
|
||||
bra c2p1x1_4_rect_pix16
|
||||
|
||||
c2p1x1_4_rect_done:
|
||||
move.l a5,(a1)+
|
||||
move.l a6,(a1)+
|
||||
|
||||
move.l old_sp,sp
|
||||
movem.l (sp)+,d2-d7/a2-a6
|
||||
rts
|
||||
|
||||
|
||||
| place it within reach of 32K (PC relative)
|
||||
screen_pitch:
|
||||
ds.l 1
|
||||
|
@ -31,11 +31,22 @@ extern "C" {
|
||||
* Optimized for surface-to-surface copy with the same pitch.
|
||||
*
|
||||
* @param pChunky chunky buffer start
|
||||
* @param pChunkyEnd chunky buffer end (including the last byte)
|
||||
* @param pChunkyEnd chunky buffer end (past-the-end iterator)
|
||||
* @param pScreen bitplane screen start
|
||||
*/
|
||||
void asm_c2p1x1_8(const byte *pChunky, const byte *pChunkyEnd, byte *pScreen);
|
||||
|
||||
/**
|
||||
* Chunky to planar conversion routine. Converts a chunky (byte) buffer into eight bitplanes.
|
||||
* Optimized for surface-to-surface copy with the double screen pitch (typically 320x480).
|
||||
*
|
||||
* @param pChunky chunky buffer start
|
||||
* @param pChunkyEnd chunky buffer end (past-the-end iterator)
|
||||
* @param pScreen bitplane screen start
|
||||
* @param screenPitch bitplane screen width (in bytes)
|
||||
*/
|
||||
void asm_c2p1x1_8_tt(const byte *pChunky, const byte *pChunkyEnd, byte *pScreen, uint32 screenPitch);
|
||||
|
||||
/**
|
||||
* Chunky to planar conversion routine. Converts a chunky (byte) buffer into eight bitplanes.
|
||||
* Optimized for arbitrary rectangle position and dimension (16px aligned).
|
||||
@ -49,6 +60,29 @@ void asm_c2p1x1_8(const byte *pChunky, const byte *pChunkyEnd, byte *pScreen);
|
||||
*/
|
||||
void asm_c2p1x1_8_rect(const byte *pChunky, const byte *pChunkyEnd, uint32 chunkyWidth, uint32 chunkyPitch, byte *pScreen, uint32 screenPitch);
|
||||
|
||||
/**
|
||||
* Chunky to planar conversion routine. Converts a chunky (byte) buffer into four bitplanes.
|
||||
* Optimized for surface-to-surface copy with the same pitch.
|
||||
*
|
||||
* @param pChunky chunky buffer start
|
||||
* @param pChunkyEnd chunky buffer end (past-the-end iterator)
|
||||
* @param pScreen bitplane screen start
|
||||
*/
|
||||
void asm_c2p1x1_4(const byte *pChunky, const byte *pChunkyEnd, byte *pScreen);
|
||||
|
||||
/**
|
||||
* Chunky to planar conversion routine. Converts a chunky (byte) buffer into four bitplanes.
|
||||
* Optimized for arbitrary rectangle position and dimension (16px aligned).
|
||||
*
|
||||
* @param pChunky chunky buffer at rectangle's [X1, Y1] position
|
||||
* @param pChunkyEnd chunky buffer at rectangle's [X2, Y2] position (included)
|
||||
* @param chunkyWidth rectangle width
|
||||
* @param chunkyPitch chunky buffer width (in bytes)
|
||||
* @param pScreen bitplane screen at rectangle's [X1, Y1] position
|
||||
* @param screenPitch bitplane screen width (in bytes)
|
||||
*/
|
||||
void asm_c2p1x1_4_rect(const byte *pChunky, const byte *pChunkyEnd, uint32 chunkyWidth, uint32 chunkyPitch, byte *pScreen, uint32 screenPitch);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,194 +0,0 @@
|
||||
/* 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 "backends/graphics/atari/videl-resolutions.h"
|
||||
|
||||
#include "common/scummsys.h"
|
||||
|
||||
const byte scp_320x200x8_rgb[] = {
|
||||
0x53, 0x43, 0x50, 0x4e, 0x00, 0x09, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x48, 0x7a, 0xb0, 0x00, 0xa9, 0xc1, 0x08, 0x00, 0xc2, 0x8c, 0xb0,
|
||||
0x01, 0x64, 0x05, 0x00, 0x01, 0xf4, 0x00, 0x00, 0x3d, 0x09, 0x00, 0x00,
|
||||
0x00, 0xc0, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x40,
|
||||
0x00, 0xc8, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x01, 0xe8, 0x48, 0x00,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xfe, 0x00, 0x99, 0x00, 0x59, 0x00, 0x26, 0x00, 0x87,
|
||||
0x00, 0xd9, 0x02, 0x71, 0x02, 0x11, 0x00, 0x81, 0x00, 0x81, 0x02, 0x11,
|
||||
0x02, 0x6b, 0x02, 0x00, 0x01, 0x81, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
|
||||
0x00, 0xa0
|
||||
};
|
||||
|
||||
const byte scp_320x200x8_rgb60[] = {
|
||||
0x53, 0x43, 0x50, 0x4e, 0x00, 0x09, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x48, 0x7a, 0xb0, 0x00, 0xa7, 0xd8, 0xc0, 0x00, 0xc4, 0x74, 0xf8,
|
||||
0x01, 0x60, 0x05, 0x00, 0x02, 0x54, 0x00, 0x00, 0x3d, 0x09, 0x00, 0x00,
|
||||
0x00, 0xc0, 0x00, 0x00, 0x08, 0xc0, 0x00, 0x00, 0x06, 0xc0, 0x00, 0x23,
|
||||
0x00, 0xc8, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x01, 0xe8, 0x48, 0x00,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xfe, 0x00, 0x98, 0x00, 0x58, 0x00, 0x25, 0x00, 0x86,
|
||||
0x00, 0xd9, 0x02, 0x0d, 0x01, 0xd7, 0x00, 0x47, 0x00, 0x47, 0x01, 0xd7,
|
||||
0x02, 0x07, 0x02, 0x00, 0x01, 0x81, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
|
||||
0x00, 0xa0
|
||||
};
|
||||
|
||||
byte scp_320x200x8_vga[] = {
|
||||
0x53, 0x43, 0x50, 0x4e, 0x00, 0x09, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x3a, 0x2f, 0x00, 0x00, 0x19, 0x74, 0x90, 0x00, 0x46, 0x4e, 0x20,
|
||||
0x00, 0x2a, 0x02, 0x80, 0x02, 0x58, 0x00, 0x00, 0x7a, 0xee, 0x00, 0x00,
|
||||
0x00, 0x3e, 0x00, 0x00, 0x08, 0x7a, 0x00, 0x00, 0x06, 0x8a, 0x00, 0x46,
|
||||
0x01, 0x90, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x01, 0xe8, 0x48, 0x00,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xc6, 0x00, 0x8d, 0x00, 0x15, 0x02, 0x9a, 0x00, 0x7b,
|
||||
0x00, 0x97, 0x04, 0x19, 0x03, 0xad, 0x00, 0x8d, 0x00, 0x8d, 0x03, 0xad,
|
||||
0x04, 0x15, 0x02, 0x00, 0x01, 0x86, 0x00, 0x00, 0x00, 0x10, 0x00, 0x05,
|
||||
0x00, 0xa0
|
||||
};
|
||||
|
||||
const byte scp_320x240x8_rgb[] = {
|
||||
0x53, 0x43, 0x50, 0x4e, 0x00, 0x09, 0x00, 0x01, 0x33, 0x32, 0x30, 0x2a,
|
||||
0x32, 0x30, 0x30, 0x2c, 0x20, 0x32, 0x35, 0x36, 0x20, 0x46, 0x61, 0x72,
|
||||
0x62, 0x65, 0x6e, 0x2c, 0x20, 0x35, 0x30, 0x2e, 0x30, 0x20, 0x48, 0x7a,
|
||||
0x2c, 0x20, 0x31, 0x35, 0x36, 0x32, 0x35, 0x20, 0x48, 0x7a, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x48, 0x7a, 0xb0, 0x00, 0xa9, 0xc1, 0x08, 0x00, 0xc2, 0x8c, 0xb0,
|
||||
0x01, 0x64, 0x05, 0x00, 0x01, 0xf4, 0x00, 0x00, 0x3d, 0x09, 0x00, 0x00,
|
||||
0x00, 0xc0, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x2c,
|
||||
0x00, 0xf0, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x01, 0xe8, 0x48, 0x00,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xfe, 0x00, 0x99, 0x00, 0x59, 0x00, 0x26, 0x00, 0x87,
|
||||
0x00, 0xd9, 0x02, 0x71, 0x02, 0x39, 0x00, 0x59, 0x00, 0x59, 0x02, 0x39,
|
||||
0x02, 0x6b, 0x02, 0x00, 0x01, 0x81, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
|
||||
0x00, 0xa0
|
||||
};
|
||||
|
||||
byte scp_320x240x8_vga[] = {
|
||||
0x53, 0x43, 0x50, 0x4e, 0x00, 0x09, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x3a, 0x2f, 0x00, 0x00, 0x19, 0x74, 0x90, 0x00, 0x46, 0x4e, 0x20,
|
||||
0x00, 0x2a, 0x02, 0x80, 0x02, 0x58, 0x00, 0x00, 0x7a, 0xee, 0x00, 0x00,
|
||||
0x00, 0x3e, 0x00, 0x00, 0x03, 0xc1, 0x00, 0x00, 0x01, 0x93, 0x00, 0x1f,
|
||||
0x01, 0xe0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x01, 0xe8, 0x48, 0x00,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xc6, 0x00, 0x8d, 0x00, 0x15, 0x02, 0x9a, 0x00, 0x7b,
|
||||
0x00, 0x97, 0x04, 0x19, 0x03, 0xff, 0x00, 0x3f, 0x00, 0x3f, 0x03, 0xff,
|
||||
0x04, 0x15, 0x02, 0x00, 0x01, 0x86, 0x00, 0x00, 0x00, 0x10, 0x00, 0x05,
|
||||
0x00, 0xa0
|
||||
};
|
||||
|
||||
const byte scp_640x400x8_rgb[] = {
|
||||
0x53, 0x43, 0x50, 0x4e, 0x00, 0x09, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x48, 0x7a, 0xb0, 0x00, 0xab, 0xa9, 0x50, 0x00, 0xc1, 0x98, 0x8c,
|
||||
0x01, 0x68, 0x05, 0x00, 0x01, 0xf4, 0x00, 0x00, 0x3d, 0x09, 0x00, 0x00,
|
||||
0x00, 0xc0, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x40,
|
||||
0x00, 0xc8, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x01, 0xe8, 0x48, 0x00,
|
||||
0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0xfe, 0x01, 0x34, 0x00, 0xb4, 0x00, 0x71, 0x01, 0x22,
|
||||
0x01, 0xb3, 0x02, 0x70, 0x02, 0x11, 0x00, 0x81, 0x00, 0x80, 0x02, 0x10,
|
||||
0x02, 0x6b, 0x02, 0x00, 0x01, 0x81, 0x00, 0x00, 0x00, 0x10, 0x00, 0x06,
|
||||
0x01, 0x40
|
||||
};
|
||||
|
||||
const byte scp_640x400x8_rgb60[] = {
|
||||
0x53, 0x43, 0x50, 0x4e, 0x00, 0x09, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x47, 0x86, 0x8c, 0x00, 0xb1, 0x62, 0x28, 0x00, 0xbd, 0xc7, 0xfc,
|
||||
0x01, 0x74, 0x05, 0x00, 0x02, 0x53, 0x00, 0x00, 0x3c, 0xea, 0x00, 0x00,
|
||||
0x00, 0xc0, 0x00, 0x00, 0x09, 0x40, 0x00, 0x00, 0x06, 0x40, 0x00, 0x25,
|
||||
0x00, 0xc8, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x01, 0xe8, 0x48, 0x00,
|
||||
0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0xff, 0x01, 0x39, 0x00, 0xba, 0x00, 0x77, 0x01, 0x27,
|
||||
0x01, 0xb5, 0x02, 0x0c, 0x01, 0xdb, 0x00, 0x4b, 0x00, 0x4a, 0x01, 0xda,
|
||||
0x02, 0x07, 0x02, 0x00, 0x01, 0x81, 0x00, 0x00, 0x00, 0x10, 0x00, 0x06,
|
||||
0x01, 0x40
|
||||
};
|
||||
|
||||
byte scp_640x400x8_vga[] = {
|
||||
0x53, 0x43, 0x50, 0x4e, 0x00, 0x09, 0x00, 0x02, 0x36, 0x34, 0x30, 0x2a,
|
||||
0x34, 0x38, 0x30, 0x2c, 0x20, 0x32, 0x35, 0x36, 0x20, 0x46, 0x61, 0x72,
|
||||
0x62, 0x65, 0x6e, 0x2c, 0x20, 0x36, 0x30, 0x2e, 0x30, 0x20, 0x48, 0x7a,
|
||||
0x2c, 0x20, 0x33, 0x31, 0x34, 0x37, 0x30, 0x20, 0x48, 0x7a, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x3a, 0x2f, 0x00, 0x00, 0x1a, 0xaa, 0xe0, 0x00, 0x45, 0x17, 0xd0,
|
||||
0x00, 0x2c, 0x02, 0x80, 0x02, 0x58, 0x00, 0x00, 0x7a, 0xee, 0x00, 0x00,
|
||||
0x00, 0x3e, 0x00, 0x00, 0x08, 0x99, 0x00, 0x00, 0x06, 0x6b, 0x00, 0x47,
|
||||
0x01, 0x90, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x01, 0xe8, 0x48, 0x00,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xc6, 0x00, 0x8e, 0x00, 0x16, 0x02, 0xac, 0x00, 0x85,
|
||||
0x00, 0x97, 0x04, 0x19, 0x03, 0xaf, 0x00, 0x8f, 0x00, 0x8f, 0x03, 0xaf,
|
||||
0x04, 0x15, 0x02, 0x00, 0x01, 0x86, 0x00, 0x00, 0x00, 0x10, 0x00, 0x08,
|
||||
0x01, 0x40
|
||||
};
|
||||
|
||||
const byte scp_640x480x8_rgb[] = {
|
||||
0x53, 0x43, 0x50, 0x4e, 0x00, 0x09, 0x00, 0x01, 0x36, 0x34, 0x30, 0x2a,
|
||||
0x34, 0x30, 0x30, 0x2c, 0x20, 0x32, 0x35, 0x36, 0x20, 0x46, 0x61, 0x72,
|
||||
0x62, 0x65, 0x6e, 0x2c, 0x20, 0x35, 0x30, 0x2e, 0x30, 0x20, 0x48, 0x7a,
|
||||
0x20, 0x28, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6c, 0x2e, 0x29, 0x2c, 0x20,
|
||||
0x31, 0x35, 0x36, 0x32, 0x35, 0x20, 0x48, 0x7a, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x48, 0x7a, 0xb0, 0x00, 0xab, 0xa9, 0x50, 0x00, 0xc1, 0x98, 0x8c,
|
||||
0x01, 0x68, 0x05, 0x00, 0x01, 0xf4, 0x00, 0x00, 0x3d, 0x09, 0x00, 0x00,
|
||||
0x00, 0xc0, 0x00, 0x00, 0x0a, 0xc0, 0x00, 0x00, 0x07, 0x40, 0x00, 0x2b,
|
||||
0x00, 0xf0, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x01, 0xe8, 0x48, 0x00,
|
||||
0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0xfe, 0x01, 0x34, 0x00, 0xb4, 0x00, 0x71, 0x01, 0x22,
|
||||
0x01, 0xb3, 0x02, 0x70, 0x02, 0x37, 0x00, 0x57, 0x00, 0x56, 0x02, 0x36,
|
||||
0x02, 0x6b, 0x02, 0x00, 0x01, 0x81, 0x00, 0x00, 0x00, 0x10, 0x00, 0x06,
|
||||
0x01, 0x40
|
||||
};
|
||||
|
||||
byte scp_640x480x8_vga[] = {
|
||||
0x53, 0x43, 0x50, 0x4e, 0x00, 0x09, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x3a, 0x2f, 0x00, 0x00, 0x1a, 0xaa, 0xe0, 0x00, 0x45, 0x17, 0xd0,
|
||||
0x00, 0x2c, 0x02, 0x80, 0x02, 0x58, 0x00, 0x00, 0x7a, 0xee, 0x00, 0x00,
|
||||
0x00, 0x3e, 0x00, 0x00, 0x03, 0xc1, 0x00, 0x00, 0x01, 0x93, 0x00, 0x1f,
|
||||
0x01, 0xe0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x01, 0xe8, 0x48, 0x00,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xc6, 0x00, 0x8e, 0x00, 0x16, 0x02, 0xac, 0x00, 0x85,
|
||||
0x00, 0x97, 0x04, 0x19, 0x03, 0xff, 0x00, 0x3f, 0x00, 0x3f, 0x03, 0xff,
|
||||
0x04, 0x15, 0x02, 0x00, 0x01, 0x86, 0x00, 0x00, 0x00, 0x10, 0x00, 0x08,
|
||||
0x01, 0x40
|
||||
};
|
@ -1,43 +0,0 @@
|
||||
/* 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 BACKENDS_GRAPHICS_ATARI_VIDEL_RESOLUTIONS_H
|
||||
#define BACKENDS_GRAPHICS_ATARI_VIDEL_RESOLUTIONS_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
|
||||
constexpr int SCP_SIZE = 158;
|
||||
|
||||
extern const byte scp_320x200x8_rgb[SCP_SIZE];
|
||||
extern const byte scp_320x200x8_rgb60[SCP_SIZE];
|
||||
extern byte scp_320x200x8_vga[SCP_SIZE];
|
||||
|
||||
extern const byte scp_320x240x8_rgb[SCP_SIZE];
|
||||
extern byte scp_320x240x8_vga[SCP_SIZE];
|
||||
|
||||
extern const byte scp_640x400x8_rgb[SCP_SIZE];
|
||||
extern const byte scp_640x400x8_rgb60[SCP_SIZE];
|
||||
extern byte scp_640x400x8_vga[SCP_SIZE];
|
||||
|
||||
extern const byte scp_640x480x8_rgb[SCP_SIZE];
|
||||
extern byte scp_640x480x8_vga[SCP_SIZE];
|
||||
|
||||
#endif
|
@ -22,126 +22,197 @@
|
||||
#include "backends/mixer/atari/atari-mixer.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <mint/cookie.h>
|
||||
#include <mint/falcon.h>
|
||||
#include <mint/osbind.h>
|
||||
#include <mint/ostruct.h>
|
||||
|
||||
#include "common/config-manager.h"
|
||||
#include "common/debug.h"
|
||||
|
||||
#define DEFAULT_OUTPUT_RATE 24585
|
||||
|
||||
static bool s_audioNotAvailable = true;
|
||||
|
||||
void AtariAudioShutdown() {
|
||||
if (!s_audioNotAvailable) {
|
||||
Buffoper(0x00);
|
||||
Sndstatus(SND_RESET);
|
||||
Unlocksnd();
|
||||
}
|
||||
}
|
||||
|
||||
AtariMixerManager::AtariMixerManager() : MixerManager() {
|
||||
debug("AtariMixerManager()");
|
||||
|
||||
_audioSuspended = true;
|
||||
|
||||
ConfMan.registerDefault("output_rate", DEFAULT_OUTPUT_RATE);
|
||||
|
||||
_outputRate = ConfMan.getInt("output_rate");
|
||||
if (_outputRate <= 0)
|
||||
_outputRate = DEFAULT_OUTPUT_RATE;
|
||||
|
||||
int diff50, diff33, diff25, diff20, diff16, diff12, diff10, diff8;
|
||||
diff50 = abs(49170 - (int)_outputRate);
|
||||
diff33 = abs(32780 - (int)_outputRate);
|
||||
diff25 = abs(24585 - (int)_outputRate);
|
||||
diff20 = abs(19668 - (int)_outputRate);
|
||||
diff16 = abs(16390 - (int)_outputRate);
|
||||
diff12 = abs(12292 - (int)_outputRate);
|
||||
diff10 = abs(9834 - (int)_outputRate);
|
||||
diff8 = abs(8195 - (int)_outputRate);
|
||||
|
||||
if (diff50 < diff33) {
|
||||
_outputRate = 49170;
|
||||
_clk = CLK50K;
|
||||
} else if (diff33 < diff25) {
|
||||
_outputRate = 32780;
|
||||
_clk = CLK33K;
|
||||
} else if (diff25 < diff20) {
|
||||
_outputRate = 24585;
|
||||
_clk = CLK25K;
|
||||
} else if (diff20 < diff16) {
|
||||
_outputRate = 19668;
|
||||
_clk = CLK20K;
|
||||
} else if (diff16 < diff12) {
|
||||
_outputRate = 16390;
|
||||
_clk = CLK16K;
|
||||
} else if (diff12 < diff10) {
|
||||
_outputRate = 12292;
|
||||
_clk = CLK12K;
|
||||
} else if (diff10 < diff8) {
|
||||
_outputRate = 9834;
|
||||
_clk = CLK10K;
|
||||
} else {
|
||||
_outputRate = 8195;
|
||||
_clk = CLK8K;
|
||||
}
|
||||
|
||||
ConfMan.setInt("output_rate", _outputRate);
|
||||
debug("setting %d Hz mixing frequency", _outputRate);
|
||||
|
||||
_samples = 8192;
|
||||
while (_samples * 16 > _outputRate * 2)
|
||||
_samples >>= 1;
|
||||
|
||||
ConfMan.registerDefault("audio_buffer_size", (int)_samples);
|
||||
|
||||
int samples = ConfMan.getInt("audio_buffer_size");
|
||||
if (samples > 0)
|
||||
_samples = samples;
|
||||
|
||||
ConfMan.setInt("audio_buffer_size", (int)_samples);
|
||||
debug("sample buffer size: %d", _samples);
|
||||
|
||||
ConfMan.flushToDisk();
|
||||
|
||||
_samplesBuf = new uint8[_samples * 4];
|
||||
|
||||
g_system->getEventManager()->getEventDispatcher()->registerObserver(this, 10, false);
|
||||
}
|
||||
|
||||
AtariMixerManager::~AtariMixerManager() {
|
||||
debug("~AtariMixerManager()");
|
||||
|
||||
g_system->getEventManager()->getEventDispatcher()->unregisterObserver(this);
|
||||
|
||||
Buffoper(0x00);
|
||||
if (s_audioNotAvailable)
|
||||
return;
|
||||
|
||||
AtariAudioShutdown();
|
||||
|
||||
Mfree(_atariSampleBuffer);
|
||||
_atariSampleBuffer = _atariPhysicalSampleBuffer = _atariLogicalSampleBuffer = nullptr;
|
||||
|
||||
Sndstatus(SND_RESET);
|
||||
|
||||
Unlocksnd();
|
||||
|
||||
_atariInitialized = false;
|
||||
|
||||
delete[] _samplesBuf;
|
||||
}
|
||||
|
||||
void AtariMixerManager::init() {
|
||||
long cookie;
|
||||
bool useDevconnectReturnValue = false;
|
||||
|
||||
if (Getcookie(C__SND, &cookie) == C_FOUND) {
|
||||
if (cookie & SND_16BIT)
|
||||
s_audioNotAvailable = false;
|
||||
|
||||
useDevconnectReturnValue = (cookie & SND_EXT) != 0;
|
||||
}
|
||||
|
||||
if (s_audioNotAvailable) {
|
||||
warning("Mixer manager requires 16-bit stereo mode, disabling");
|
||||
} else {
|
||||
int clk;
|
||||
|
||||
if (Locksnd() < 0)
|
||||
error("Sound system is locked");
|
||||
|
||||
// try XBIOS APIs which do not set SND_EXT in _SND
|
||||
useDevconnectReturnValue |= (Getcookie(C_STFA, &cookie) == C_FOUND); // STFA
|
||||
useDevconnectReturnValue |= (Getcookie(C_McSn, &cookie) == C_FOUND); // X-SOUND, MacSound
|
||||
|
||||
// reset connection matrix (and other settings)
|
||||
Sndstatus(SND_RESET);
|
||||
|
||||
int diff50, diff33, diff25, diff20, diff16, diff12, diff10, diff8, diff6;
|
||||
diff50 = abs(49170 - (int)_outputRate);
|
||||
diff33 = abs(32780 - (int)_outputRate);
|
||||
diff25 = abs(24585 - (int)_outputRate);
|
||||
diff20 = abs(19668 - (int)_outputRate);
|
||||
diff16 = abs(16390 - (int)_outputRate);
|
||||
diff12 = abs(12292 - (int)_outputRate);
|
||||
diff10 = abs(9834 - (int)_outputRate);
|
||||
diff8 = abs(8195 - (int)_outputRate);
|
||||
|
||||
if (diff50 < diff33) {
|
||||
_outputRate = 49170;
|
||||
clk = CLK50K;
|
||||
} else if (diff33 < diff25) {
|
||||
_outputRate = 32780;
|
||||
clk = CLK33K;
|
||||
} else if (diff25 < diff20) {
|
||||
_outputRate = 24585;
|
||||
clk = CLK25K;
|
||||
} else if (diff20 < diff16) {
|
||||
_outputRate = 19668;
|
||||
clk = CLK20K;
|
||||
} else if (diff16 < diff12) {
|
||||
_outputRate = 16390;
|
||||
clk = CLK16K;
|
||||
} else if (diff12 < diff10) {
|
||||
_outputRate = 12292;
|
||||
clk = CLK12K;
|
||||
} else if (diff10 < diff8) {
|
||||
_outputRate = 9834;
|
||||
clk = CLK10K;
|
||||
} else {
|
||||
_outputRate = 8195;
|
||||
clk = CLK8K;
|
||||
}
|
||||
|
||||
// first try to use Devconnect() with a Falcon prescaler
|
||||
if (Devconnect(DMAPLAY, DAC, CLK25M, clk, NO_SHAKE) != 0) {
|
||||
// the return value is broken on Falcon
|
||||
if (useDevconnectReturnValue) {
|
||||
if (Devconnect(DMAPLAY, DAC, CLK25M, CLKOLD, NO_SHAKE) == 0) {
|
||||
// calculate compatible prescaler
|
||||
diff50 = abs(50066 - (int)_outputRate);
|
||||
diff25 = abs(25033 - (int)_outputRate);
|
||||
diff12 = abs(12517 - (int)_outputRate);
|
||||
diff6 = abs(6258 - (int)_outputRate);
|
||||
|
||||
if (diff50 < diff25) {
|
||||
_outputRate = 50066;
|
||||
clk = PRE160;
|
||||
} else if (diff25 < diff12) {
|
||||
_outputRate = 25033;
|
||||
clk = PRE320;
|
||||
} else if (diff12 < diff6) {
|
||||
_outputRate = 12517;
|
||||
clk = PRE640;
|
||||
} else {
|
||||
_outputRate = 6258;
|
||||
clk = PRE1280;
|
||||
}
|
||||
|
||||
Soundcmd(SETPRESCALE, clk);
|
||||
} else {
|
||||
error("Devconnect() failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ConfMan.setInt("output_rate", _outputRate);
|
||||
debug("setting %d Hz mixing frequency", _outputRate);
|
||||
|
||||
_samples = 8192;
|
||||
while (_samples * 16 > _outputRate * 2)
|
||||
_samples >>= 1;
|
||||
|
||||
ConfMan.registerDefault("audio_buffer_size", (int)_samples);
|
||||
|
||||
int samples = ConfMan.getInt("audio_buffer_size");
|
||||
if (samples > 0)
|
||||
_samples = samples;
|
||||
|
||||
ConfMan.setInt("audio_buffer_size", (int)_samples);
|
||||
debug("sample buffer size: %d", _samples);
|
||||
|
||||
ConfMan.flushToDisk();
|
||||
|
||||
_atariSampleBufferSize = _samples * 4;
|
||||
|
||||
_atariSampleBuffer = (byte*)Mxalloc(_atariSampleBufferSize * 2, MX_STRAM);
|
||||
if (!_atariSampleBuffer)
|
||||
error("Failed to allocate memory in ST RAM");
|
||||
|
||||
_atariPhysicalSampleBuffer = _atariSampleBuffer;
|
||||
_atariLogicalSampleBuffer = _atariSampleBuffer + _atariSampleBufferSize;
|
||||
|
||||
memset(_atariSampleBuffer, 0, 2 * _atariSampleBufferSize);
|
||||
|
||||
Setmode(MODE_STEREO16);
|
||||
Soundcmd(ADDERIN, MATIN);
|
||||
Setbuffer(SR_PLAY, _atariSampleBuffer, _atariSampleBuffer + 2 * _atariSampleBufferSize);
|
||||
Buffoper(SB_PLA_ENA | SB_PLA_RPT);
|
||||
|
||||
_samplesBuf = new uint8[_samples * 4];
|
||||
}
|
||||
|
||||
_mixer = new Audio::MixerImpl(_outputRate, _samples);
|
||||
_mixer->setReady(true);
|
||||
|
||||
_atariSampleBufferSize = _samples * 4;
|
||||
|
||||
_atariSampleBuffer = (byte*)Mxalloc(_atariSampleBufferSize * 2, MX_STRAM);
|
||||
if (!_atariSampleBuffer)
|
||||
return;
|
||||
|
||||
_atariPhysicalSampleBuffer = _atariSampleBuffer;
|
||||
_atariLogicalSampleBuffer = _atariSampleBuffer + _atariSampleBufferSize;
|
||||
|
||||
memset(_atariSampleBuffer, 0, 2 * _atariSampleBufferSize);
|
||||
|
||||
if (Locksnd() < 0)
|
||||
return;
|
||||
|
||||
Sndstatus(SND_RESET);
|
||||
Setmode(MODE_STEREO16);
|
||||
Devconnect(DMAPLAY, DAC, CLK25M, _clk, NO_SHAKE);
|
||||
Soundcmd(ADDERIN, MATIN);
|
||||
Setbuffer(SR_PLAY, _atariSampleBuffer, _atariSampleBuffer + 2 * _atariSampleBufferSize);
|
||||
Buffoper(SB_PLA_ENA | SB_PLA_RPT);
|
||||
|
||||
_atariInitialized = true;
|
||||
_audioSuspended = false;
|
||||
}
|
||||
|
||||
void AtariMixerManager::suspendAudio() {
|
||||
if (s_audioNotAvailable)
|
||||
return;
|
||||
|
||||
debug("suspendAudio");
|
||||
|
||||
Buffoper(0x00);
|
||||
@ -150,13 +221,10 @@ void AtariMixerManager::suspendAudio() {
|
||||
}
|
||||
|
||||
int AtariMixerManager::resumeAudio() {
|
||||
debug("resumeAudio 1");
|
||||
if (s_audioNotAvailable)
|
||||
return 0;
|
||||
|
||||
if (!_audioSuspended || !_atariInitialized) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
debug("resumeAudio 2");
|
||||
debug("resumeAudio");
|
||||
|
||||
Buffoper(SB_PLA_ENA | SB_PLA_RPT);
|
||||
|
||||
@ -165,10 +233,13 @@ int AtariMixerManager::resumeAudio() {
|
||||
}
|
||||
|
||||
bool AtariMixerManager::notifyEvent(const Common::Event &event) {
|
||||
if (s_audioNotAvailable)
|
||||
return false;
|
||||
|
||||
switch (event.type) {
|
||||
case Common::EVENT_QUIT:
|
||||
case Common::EVENT_RETURN_TO_LAUNCHER:
|
||||
debug("silencing the mixer");
|
||||
debug("silencing the mixer"); // TODO: is it for long enough?
|
||||
memset(_atariSampleBuffer, 0, 2 * _atariSampleBufferSize);
|
||||
return false;
|
||||
case Common::EVENT_MUTE:
|
||||
@ -187,6 +258,12 @@ void AtariMixerManager::update() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (s_audioNotAvailable) {
|
||||
static byte dummy[4];
|
||||
_mixer->mixCallback(dummy, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
static bool loadSampleFlag = true;
|
||||
byte *buf = nullptr;
|
||||
|
||||
@ -195,20 +272,18 @@ void AtariMixerManager::update() {
|
||||
return;
|
||||
|
||||
if (!loadSampleFlag) {
|
||||
// we play from _atariPhysicalSampleBuffer (1st buffer)
|
||||
if ((byte*)sPtr.play < _atariLogicalSampleBuffer) {
|
||||
buf = _atariLogicalSampleBuffer;
|
||||
loadSampleFlag = !loadSampleFlag;
|
||||
}
|
||||
} else {
|
||||
// we play from _atariLogicalSampleBuffer (2nd buffer)
|
||||
if ((byte*)sPtr.play >= _atariLogicalSampleBuffer) {
|
||||
buf = _atariPhysicalSampleBuffer;
|
||||
loadSampleFlag = !loadSampleFlag;
|
||||
}
|
||||
}
|
||||
|
||||
if (_atariInitialized && buf != nullptr) {
|
||||
if (buf != nullptr) {
|
||||
assert(_mixer);
|
||||
// generates stereo 16-bit samples
|
||||
int processed = _mixer->mixCallback(_samplesBuf, _muted ? 0 : _samples * 4);
|
||||
|
@ -43,12 +43,10 @@ public:
|
||||
bool notifyEvent(const Common::Event &event) override;
|
||||
|
||||
private:
|
||||
int _clk;
|
||||
uint32 _outputRate;
|
||||
uint32 _samples;
|
||||
uint8 *_samplesBuf;
|
||||
uint32 _samples = 0;
|
||||
uint8 *_samplesBuf = nullptr;
|
||||
|
||||
bool _atariInitialized = false;
|
||||
byte *_atariSampleBuffer = nullptr;
|
||||
byte *_atariPhysicalSampleBuffer = nullptr;
|
||||
byte *_atariLogicalSampleBuffer = nullptr;
|
||||
|
@ -360,7 +360,6 @@ MODULE_OBJS += \
|
||||
graphics/atari/atari_c2p-asm.o \
|
||||
graphics/atari/atari-graphics.o \
|
||||
graphics/atari/atari-graphics-asm.o \
|
||||
graphics/atari/videl-resolutions.o \
|
||||
mixer/atari/atari-mixer.o
|
||||
endif
|
||||
|
||||
|
@ -19,215 +19,58 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* IKBD 6301 interrupt routine
|
||||
*
|
||||
* Patrice Mandin
|
||||
*/
|
||||
.global _atari_kbdvec
|
||||
.global _atari_mousevec
|
||||
.global _atari_vkbderr
|
||||
|
||||
.globl _atari_ikbd_init
|
||||
.globl _atari_ikbd_shutdown
|
||||
|
||||
.globl _g_atari_ikbd_mouse_buttons_state
|
||||
.globl _g_atari_ikbd_mouse_delta_x
|
||||
.globl _g_atari_ikbd_mouse_delta_y
|
||||
|
||||
.globl _g_atari_ikbd_scancodes
|
||||
.globl _g_atari_ikbd_scancodes_size
|
||||
.globl _g_atari_ikbb_scancodes_head
|
||||
.extern _g_atari_ikbd_mouse_buttons_state
|
||||
.extern _g_atari_ikbd_mouse_delta_x
|
||||
.extern _g_atari_ikbd_mouse_delta_y
|
||||
|
||||
.extern _g_atari_ikbd_scancodes
|
||||
.extern _g_atari_ikbd_scancodes_mask
|
||||
.extern _g_atari_ikbb_scancodes_head
|
||||
|
||||
.text
|
||||
|
||||
_atari_ikbd_init:
|
||||
| Disable interrupts
|
||||
_atari_kbdvec:
|
||||
tst.w (vkbderr_count,pc)
|
||||
bne.b kbdvec_end
|
||||
|
||||
movew sr,d1
|
||||
movew #0x2700,sr
|
||||
|
||||
| Save MFP registers used for keyboard
|
||||
|
||||
lea 0xfffffa00:w,a0
|
||||
btst #6,a0@(0x09)
|
||||
sne ikbd_ierb
|
||||
btst #6,a0@(0x15)
|
||||
sne ikbd_imrb
|
||||
|
||||
| Set our routine
|
||||
|
||||
movel 0x118:w,old_ikbd
|
||||
movel #ikbd,0x118:w
|
||||
bset #6,0xfffffa09:w | IERB
|
||||
bset #6,0xfffffa15:w | IMRB
|
||||
|
||||
| Set mouse relative mode
|
||||
|
||||
moveb #8,0xfffffc02:w
|
||||
|
||||
| Reenable interrupts
|
||||
|
||||
movew d1,sr
|
||||
rts
|
||||
|
||||
_atari_ikbd_shutdown:
|
||||
| Disable interrupts
|
||||
|
||||
movew sr,d1
|
||||
movew #0x2700,sr
|
||||
|
||||
| Restore previous MFP registers
|
||||
|
||||
lea 0xfffffa00:w,a0
|
||||
|
||||
bclr #6,a0@(0x09)
|
||||
tstb ikbd_ierb
|
||||
beqs ikbd_restoreierb
|
||||
bset #6,a0@(0x09)
|
||||
ikbd_restoreierb:
|
||||
|
||||
bclr #6,a0@(0x15)
|
||||
tstb ikbd_imrb
|
||||
beqs ikbd_restoreimrb
|
||||
bset #6,a0@(0x15)
|
||||
ikbd_restoreimrb:
|
||||
|
||||
movel old_ikbd,0x118:w
|
||||
|
||||
| Clear keyboard buffer
|
||||
|
||||
lea 0xfffffc00:w,a0
|
||||
ikbd_videbuffer:
|
||||
btst #0,a0@
|
||||
beqs ikbd_finbuffer
|
||||
tstb a0@(0x02)
|
||||
bras ikbd_videbuffer
|
||||
ikbd_finbuffer:
|
||||
|
||||
| Reenable interrupts
|
||||
|
||||
movew d1,sr
|
||||
rts
|
||||
|
||||
.bss
|
||||
|
||||
.even
|
||||
ikbd_ierb:
|
||||
.ds.b 1
|
||||
ikbd_imrb:
|
||||
.ds.b 1
|
||||
|
||||
/*--- Our custom IKBD vector ---*/
|
||||
|
||||
.text
|
||||
.even
|
||||
.ascii "XBRA"
|
||||
.ascii "SCUM"
|
||||
old_ikbd:
|
||||
.dc.l 0
|
||||
ikbd:
|
||||
moveml d0-d1/a0,sp@-
|
||||
|
||||
| Check if source is IKBD or MIDI
|
||||
|
||||
btst #0,0xfffffc00.w
|
||||
beqs ikbd_oldmidi
|
||||
|
||||
moveb 0xfffffc02:w,d0
|
||||
|
||||
| Not supported packets ?
|
||||
|
||||
| status report
|
||||
cmpb #0xf6,d0
|
||||
beqs ikbd_endit_stack
|
||||
| absolute mouse position record
|
||||
cmpb #0xf7,d0
|
||||
beqs ikbd_endit_stack
|
||||
| time-of-day
|
||||
cmpb #0xfc,d0
|
||||
beqs ikbd_endit_stack
|
||||
|
||||
| Joystick packet ?
|
||||
|
||||
| joystick report (both sticks), joystick 0 event, joystick 1 event
|
||||
cmpb #0xfd,d0
|
||||
bhss ikbd_endit_stack
|
||||
|
||||
| Mouse packet ?
|
||||
|
||||
cmpb #0xf8,d0
|
||||
blos ikbd_no_mouse
|
||||
cmpb #0xfc,d0
|
||||
bhss ikbd_no_mouse
|
||||
|
||||
| Mouse packet, byte #1
|
||||
|
||||
ikbd_yes_mouse:
|
||||
andw #3,d0
|
||||
moveb d0,_g_atari_ikbd_mouse_buttons_state
|
||||
|
||||
movel #ikbd_mousex,0x118:w
|
||||
bras ikbd_endit_stack
|
||||
|
||||
| Keyboard press/release
|
||||
|
||||
ikbd_no_mouse:
|
||||
lea _g_atari_ikbd_scancodes,a0
|
||||
movew _g_atari_ikbb_scancodes_head,d1
|
||||
move.w _g_atari_ikbb_scancodes_head,d1
|
||||
|
||||
| g_atari_ikbd_scancodes[g_atari_ikbb_scancodes_head] = scancode
|
||||
|
||||
moveb d0,(0.b,a0,d1.w)
|
||||
move.b d0,(0.b,a0,d1.w)
|
||||
|
||||
addql #1,d1
|
||||
andw _g_atari_ikbd_scancodes_mask,d1
|
||||
movew d1,_g_atari_ikbb_scancodes_head
|
||||
addq.l #1,d1
|
||||
and.w _g_atari_ikbd_scancodes_mask,d1
|
||||
move.w d1,_g_atari_ikbb_scancodes_head
|
||||
|
||||
| End of interrupt
|
||||
|
||||
ikbd_endit_stack:
|
||||
moveml sp@+,d0-d1/a0
|
||||
|
||||
bclr #6,0xfffffa11:w
|
||||
rte
|
||||
|
||||
| Call old MIDI interrupt
|
||||
|
||||
ikbd_oldmidi:
|
||||
moveml sp@+,d0-d1/a0
|
||||
|
||||
movel old_ikbd,sp@-
|
||||
kbdvec_end:
|
||||
rts
|
||||
|
||||
| Mouse packet, byte #2
|
||||
|
||||
ikbd_mousex:
|
||||
moveml d0-d1/a0,sp@-
|
||||
_atari_vkbderr:
|
||||
addq.w #1,vkbderr_count
|
||||
rts
|
||||
|
||||
| Check if source is IKBD or MIDI
|
||||
btst #0,0xfffffc00.w
|
||||
beqs ikbd_oldmidi
|
||||
|
||||
moveb 0xfffffc02:w,d0
|
||||
extw d0
|
||||
addw d0,_g_atari_ikbd_mouse_delta_x
|
||||
_atari_mousevec:
|
||||
clr.w vkbderr_count
|
||||
|
||||
movel #ikbd_mousey,0x118:w
|
||||
bras ikbd_endit_stack
|
||||
move.b (a0)+,_g_atari_ikbd_mouse_buttons_state
|
||||
|
||||
| Mouse packet, byte #3
|
||||
move.b (a0)+,d0
|
||||
ext.w d0
|
||||
add.w d0,_g_atari_ikbd_mouse_delta_x
|
||||
|
||||
ikbd_mousey:
|
||||
moveml d0-d1/a0,sp@-
|
||||
move.b (a0)+,d0
|
||||
ext.w d0
|
||||
add.w d0,_g_atari_ikbd_mouse_delta_y
|
||||
rts
|
||||
|
||||
| Check if source is IKBD or MIDI
|
||||
|
||||
btst #0,0xfffffc00.w
|
||||
beqs ikbd_oldmidi
|
||||
|
||||
moveb 0xfffffc02:w,d0
|
||||
extw d0
|
||||
|
||||
addw d0,_g_atari_ikbd_mouse_delta_y
|
||||
|
||||
movel #ikbd,0x118:w
|
||||
bras ikbd_endit_stack
|
||||
// place it within reach of 32K (PC relative)
|
||||
vkbderr_count:
|
||||
dc.w 0
|
||||
|
@ -43,7 +43,10 @@ do
|
||||
unzip -d tmp "$f" && cd tmp && zip -0 ../$(basename "$f") * && cd .. && rm -r tmp && rm "$f"
|
||||
done
|
||||
)
|
||||
# absent gui-icons.dat massively speeds up startup time (used for the grid mode)
|
||||
rm ../data/gui-icons.dat
|
||||
cd -
|
||||
|
||||
# readme.txt
|
||||
cp ../backends/platform/atari/readme.txt dist-generic/scummvm
|
||||
unix2dos dist-generic/scummvm/readme.txt
|
||||
|
@ -28,7 +28,8 @@ then
|
||||
--disable-bink \
|
||||
--opengl-mode=none \
|
||||
--enable-verbose-build \
|
||||
--enable-text-console
|
||||
--enable-text-console \
|
||||
--disable-engine=hugo
|
||||
fi
|
||||
|
||||
make -j 16
|
||||
@ -36,7 +37,8 @@ rm -rf dist-generic
|
||||
make dist-generic
|
||||
|
||||
# remove themes
|
||||
rm -f dist-generic/scummvm/data/*.zip
|
||||
rm -f dist-generic/scummvm/data/*.zip dist-generic/scummvm/data/gui-icons.dat
|
||||
|
||||
# readme.txt
|
||||
cp ../backends/platform/atari/readme.txt dist-generic/scummvm
|
||||
unix2dos dist-generic/scummvm/readme.txt
|
||||
|
@ -22,34 +22,38 @@
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <gem.h>
|
||||
#include <mint/cookie.h>
|
||||
#include <mint/falcon.h>
|
||||
#include <mint/osbind.h>
|
||||
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_FILE
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_stdout
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_stderr
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_fputs
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_exit
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_time_h
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_getenv
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_sprintf
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_stderr
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_stdout
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_time_h
|
||||
|
||||
#include "backends/platform/atari/osystem_atari.h"
|
||||
|
||||
#if defined(ATARI)
|
||||
#include "backends/graphics/atari/atari-graphics-asm.h"
|
||||
#include "backends/keymapper/hardware-input.h"
|
||||
#include "backends/mutex/null/null-mutex.h"
|
||||
#include "base/main.h"
|
||||
|
||||
#include "backends/saves/default/default-saves.h"
|
||||
#include "backends/timer/default/default-timer.h"
|
||||
#include "backends/audiocd/default/default-audiocd.h"
|
||||
#include "common/config-manager.h"
|
||||
#include "backends/events/atari/atari-events.h"
|
||||
#include "backends/events/default/default-events.h"
|
||||
#include "backends/mixer/atari/atari-mixer.h"
|
||||
#include "backends/graphics/atari/atari-graphics.h"
|
||||
#include "backends/graphics/atari/atari-graphics-asm.h"
|
||||
#include "backends/graphics/atari/atari-graphics-superblitter.h"
|
||||
#include "backends/graphics/atari/atari-graphics-supervidel.h"
|
||||
#include "backends/graphics/atari/atari-graphics-videl.h"
|
||||
#include "backends/graphics/atari/atari-graphics.h"
|
||||
#include "backends/keymapper/hardware-input.h"
|
||||
#include "backends/mixer/atari/atari-mixer.h"
|
||||
#include "backends/mutex/null/null-mutex.h"
|
||||
#include "backends/saves/default/default-saves.h"
|
||||
#include "backends/timer/default/default-timer.h"
|
||||
#include "base/main.h"
|
||||
#include "gui/debugger.h"
|
||||
|
||||
/*
|
||||
@ -57,8 +61,9 @@
|
||||
*/
|
||||
#include "backends/fs/posix/posix-fs-factory.h"
|
||||
|
||||
extern "C" void atari_ikbd_init();
|
||||
extern "C" void atari_ikbd_shutdown();
|
||||
extern "C" void atari_kbdvec(void *);
|
||||
extern "C" void atari_mousevec(void *);
|
||||
extern "C" void atari_vkbderr(void);
|
||||
|
||||
extern "C" void atari_200hz_init();
|
||||
extern "C" void atari_200hz_shutdown();
|
||||
@ -67,36 +72,79 @@ extern "C" volatile uint32 counter_200hz;
|
||||
extern void nf_init(void);
|
||||
extern void nf_print(const char* msg);
|
||||
|
||||
OSystem_Atari::OSystem_Atari() {
|
||||
_fsFactory = new POSIXFilesystemFactory();
|
||||
}
|
||||
static int s_app_id = -1;
|
||||
static int16 s_vdi_handle;
|
||||
static int s_vdi_width, s_vdi_height;
|
||||
|
||||
OSystem_Atari::~OSystem_Atari() {
|
||||
debug("OSystem_Atari::~OSystem_Atari()");
|
||||
static bool s_tt = false;
|
||||
typedef void (*KBDVEC)(void *);
|
||||
static KBDVEC s_kbdvec = nullptr;
|
||||
static void (*s_vkbderr)(void) = nullptr;
|
||||
static KBDVEC s_mousevec = nullptr;
|
||||
|
||||
if (_video_initialized) {
|
||||
Supexec(asm_screen_falcon_restore);
|
||||
_video_initialized = false;
|
||||
}
|
||||
static void (*s_old_procterm)(void) = nullptr;
|
||||
|
||||
if (_200hz_initialized) {
|
||||
Supexec(atari_200hz_shutdown);
|
||||
_200hz_initialized = false;
|
||||
}
|
||||
static void exit_gem() {
|
||||
if (s_app_id != -1) {
|
||||
//wind_update(END_UPDATE);
|
||||
|
||||
if (_ikbd_initialized) {
|
||||
Supexec(atari_ikbd_shutdown);
|
||||
_ikbd_initialized = false;
|
||||
// redraw screen
|
||||
form_dial(FMD_FINISH, 0, 0, 0, 0, 0, 0, s_vdi_width, s_vdi_height);
|
||||
graf_mouse(M_ON, NULL);
|
||||
|
||||
v_clsvwk(s_vdi_handle);
|
||||
appl_exit();
|
||||
}
|
||||
}
|
||||
|
||||
static void critical_restore() {
|
||||
Supexec(asm_screen_falcon_restore);
|
||||
extern void AtariAudioShutdown();
|
||||
extern void AtariGraphicsShutdown();
|
||||
|
||||
AtariAudioShutdown();
|
||||
AtariGraphicsShutdown();
|
||||
|
||||
if (s_tt)
|
||||
Supexec(asm_screen_tt_restore);
|
||||
else
|
||||
Supexec(asm_screen_falcon_restore);
|
||||
Supexec(atari_200hz_shutdown);
|
||||
Supexec(atari_ikbd_shutdown);
|
||||
|
||||
if (s_kbdvec && s_vkbderr && s_mousevec) {
|
||||
_KBDVECS *kbdvecs = Kbdvbase();
|
||||
((uintptr *)kbdvecs)[-1] = (uintptr)s_kbdvec;
|
||||
kbdvecs->vkbderr = s_vkbderr;
|
||||
kbdvecs->mousevec = s_mousevec;
|
||||
s_kbdvec = s_mousevec = nullptr;
|
||||
}
|
||||
|
||||
exit_gem();
|
||||
}
|
||||
|
||||
void OSystem_Atari::initBackend() {
|
||||
OSystem_Atari::OSystem_Atari() {
|
||||
_fsFactory = new POSIXFilesystemFactory();
|
||||
|
||||
nf_init();
|
||||
|
||||
enum {
|
||||
VDO_NO_ATARI_HW = 0xffff,
|
||||
VDO_ST = 0,
|
||||
VDO_STE,
|
||||
VDO_TT,
|
||||
VDO_FALCON,
|
||||
VDO_MILAN
|
||||
};
|
||||
|
||||
long vdo = VDO_NO_ATARI_HW<<16;
|
||||
Getcookie(C__VDO, &vdo);
|
||||
vdo >>= 16;
|
||||
|
||||
if (vdo != VDO_TT && vdo != VDO_FALCON) {
|
||||
error("ScummVM requires Atari TT/Falcon compatible video");
|
||||
}
|
||||
|
||||
s_tt = (vdo == VDO_TT);
|
||||
|
||||
enum {
|
||||
MCH_ST = 0,
|
||||
MCH_STE,
|
||||
@ -110,16 +158,83 @@ void OSystem_Atari::initBackend() {
|
||||
Getcookie(C__MCH, &mch);
|
||||
mch >>= 16;
|
||||
|
||||
if (mch != MCH_FALCON && mch != MCH_ARANYM) {
|
||||
error("ScummVM works only on Atari Falcon and ARAnyM");
|
||||
}
|
||||
|
||||
if (mch == MCH_ARANYM && Getcookie(C_fVDI, NULL) == C_FOUND) {
|
||||
error("Disable fVDI, ScummVM accesses Videl directly");
|
||||
error("Disable fVDI, ScummVM uses XBIOS video calls");
|
||||
}
|
||||
|
||||
nf_init();
|
||||
_KBDVECS *kbdvecs = Kbdvbase();
|
||||
s_kbdvec = (KBDVEC)(((uintptr *)kbdvecs)[-1]);
|
||||
s_vkbderr = kbdvecs->vkbderr;
|
||||
s_mousevec = kbdvecs->mousevec;
|
||||
|
||||
((uintptr *)kbdvecs)[-1] = (uintptr)atari_kbdvec;
|
||||
kbdvecs->vkbderr = atari_vkbderr;
|
||||
kbdvecs->mousevec = atari_mousevec;
|
||||
|
||||
Supexec(atari_200hz_init);
|
||||
_timerInitialized = true;
|
||||
|
||||
if (s_tt)
|
||||
Supexec(asm_screen_tt_save);
|
||||
else
|
||||
Supexec(asm_screen_falcon_save);
|
||||
|
||||
_videoInitialized = true;
|
||||
|
||||
s_old_procterm = Setexc(VEC_PROCTERM, -1);
|
||||
(void)Setexc(VEC_PROCTERM, critical_restore);
|
||||
}
|
||||
|
||||
OSystem_Atari::~OSystem_Atari() {
|
||||
debug("OSystem_Atari::~OSystem_Atari()");
|
||||
|
||||
// _audiocdManager needs to be deleted before _mixerManager to avoid a crash.
|
||||
delete _audiocdManager;
|
||||
_audiocdManager = nullptr;
|
||||
|
||||
delete _mixerManager;
|
||||
_mixerManager = nullptr;
|
||||
|
||||
delete _graphicsManager;
|
||||
_graphicsManager = nullptr;
|
||||
|
||||
delete _eventManager;
|
||||
_eventManager = nullptr;
|
||||
|
||||
delete _savefileManager;
|
||||
_savefileManager = nullptr;
|
||||
|
||||
delete _timerManager;
|
||||
_timerManager = nullptr;
|
||||
|
||||
delete _fsFactory;
|
||||
_fsFactory = nullptr;
|
||||
|
||||
if (_videoInitialized) {
|
||||
if (s_tt)
|
||||
Supexec(asm_screen_tt_restore);
|
||||
else {
|
||||
Supexec(asm_screen_falcon_restore);
|
||||
}
|
||||
|
||||
_videoInitialized = false;
|
||||
}
|
||||
|
||||
if (_timerInitialized) {
|
||||
Supexec(atari_200hz_shutdown);
|
||||
_timerInitialized = false;
|
||||
}
|
||||
|
||||
if (s_kbdvec && s_vkbderr && s_mousevec) {
|
||||
_KBDVECS *kbdvecs = Kbdvbase();
|
||||
((uintptr *)kbdvecs)[-1] = (uintptr)s_kbdvec;
|
||||
kbdvecs->vkbderr = s_vkbderr;
|
||||
kbdvecs->mousevec = s_mousevec;
|
||||
s_kbdvec = s_mousevec = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void OSystem_Atari::initBackend() {
|
||||
_timerManager = new DefaultTimerManager();
|
||||
_savefileManager = new DefaultSaveFileManager("saves");
|
||||
|
||||
@ -142,17 +257,6 @@ void OSystem_Atari::initBackend() {
|
||||
// Setup and start mixer
|
||||
_mixerManager->init();
|
||||
|
||||
Supexec(atari_ikbd_init);
|
||||
_ikbd_initialized = true;
|
||||
|
||||
Supexec(atari_200hz_init);
|
||||
_200hz_initialized = true;
|
||||
|
||||
Supexec(asm_screen_falcon_save);
|
||||
_video_initialized = true;
|
||||
|
||||
(void)Setexc(VEC_PROCTERM, critical_restore);
|
||||
|
||||
_startTime = counter_200hz;
|
||||
|
||||
BaseBackend::initBackend();
|
||||
@ -207,7 +311,10 @@ void OSystem_Atari::quit() {
|
||||
|
||||
g_system->destroy();
|
||||
|
||||
exit(0);
|
||||
// graceful exit
|
||||
(void)Setexc(VEC_PROCTERM, s_old_procterm);
|
||||
|
||||
exit_gem();
|
||||
}
|
||||
|
||||
void OSystem_Atari::logMessage(LogMessageType::Type type, const char *message) {
|
||||
@ -218,10 +325,13 @@ void OSystem_Atari::logMessage(LogMessageType::Type type, const char *message) {
|
||||
else
|
||||
output = stderr;
|
||||
|
||||
fputs(message, output);
|
||||
static char str[1024+1];
|
||||
sprintf(str, "[%08d] %s", getMillis(), message);
|
||||
|
||||
fputs(str, output);
|
||||
fflush(output);
|
||||
|
||||
nf_print(message);
|
||||
nf_print(str);
|
||||
}
|
||||
|
||||
void OSystem_Atari::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) {
|
||||
@ -272,12 +382,47 @@ OSystem *OSystem_Atari_create() {
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
s_app_id = appl_init();
|
||||
if (s_app_id != -1) {
|
||||
// get the ID of the current physical screen workstation
|
||||
int16 dummy;
|
||||
s_vdi_handle = graf_handle(&dummy, &dummy, &dummy, &dummy);
|
||||
if (s_vdi_handle < 1) {
|
||||
appl_exit();
|
||||
error("graf_handle() failed");
|
||||
}
|
||||
|
||||
int16 work_in[16] = {};
|
||||
int16 work_out[57] = {};
|
||||
|
||||
// open a virtual screen workstation
|
||||
v_opnvwk(work_in, &s_vdi_handle, work_out);
|
||||
|
||||
if (s_vdi_handle == 0) {
|
||||
appl_exit();
|
||||
error("v_opnvwk() failed");
|
||||
}
|
||||
|
||||
s_vdi_width = work_out[0] + 1;
|
||||
s_vdi_height = work_out[1] + 1;
|
||||
|
||||
graf_mouse(M_OFF, NULL);
|
||||
// see https://github.com/freemint/freemint/issues/312
|
||||
//wind_update(BEG_UPDATE);
|
||||
}
|
||||
|
||||
g_system = OSystem_Atari_create();
|
||||
assert(g_system);
|
||||
|
||||
// Invoke the actual ScummVM main entry point:
|
||||
int res = scummvm_main(argc, argv);
|
||||
g_system->destroy();
|
||||
|
||||
// graceful exit
|
||||
(void)Setexc(VEC_PROCTERM, s_old_procterm);
|
||||
|
||||
exit_gem();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -51,9 +51,8 @@ public:
|
||||
private:
|
||||
long _startTime;
|
||||
|
||||
bool _video_initialized = false;
|
||||
bool _200hz_initialized = false;
|
||||
bool _ikbd_initialized = false;
|
||||
bool _videoInitialized = false;
|
||||
bool _timerInitialized = false;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -13,7 +13,7 @@ Yet another port?
|
||||
-----------------
|
||||
|
||||
Yes, I am aware of the official Atari/FreeMiNT port done by KeithS over the
|
||||
years (https://docs.scummvm.org/en/v2.6.1/other_platforms/atari.html). It is
|
||||
years (https://docs.scummvm.org/en/v2.7.0/other_platforms/atari.html). It is
|
||||
even updated every release and put on the official ScummVM website. That port
|
||||
is basically just a recompiled SDL backend for our platform - that certainly
|
||||
has some advantages (works in GEM, can be easily compiled for the FireBee etc.)
|
||||
@ -41,34 +41,41 @@ his own backend), I decided to do the same and see whether I could do better.
|
||||
And I could!
|
||||
|
||||
|
||||
Hardware requirements
|
||||
---------------------
|
||||
|
||||
This port requires an Atari computer with TT or Falcon compatible video modes.
|
||||
Ideally accelerated with at least 4+32 MB of RAM. It runs fine also in Hatari
|
||||
and ARAnyM but in case of ARAnyM don't forget to disable fVDI to show Videl
|
||||
output.
|
||||
|
||||
|
||||
Main features
|
||||
-------------
|
||||
|
||||
- Optimized for the Atari Falcon (ideally with the CT60/CT63/CT60e but for the
|
||||
less hungry games even a CT2/DFB@50 MHz or the AfterBurner040 could be enough).
|
||||
- Optimized for the Atari TT/Falcon: ideally the CT60/CT63/CT60e but some games
|
||||
run fine on the AfterBurner040, CT2/DFB@50 MHz, Speedy@48 MHz or even less!
|
||||
|
||||
- Full support for the SuperVidel, incl. the SuperBlitter (!)
|
||||
|
||||
- Removed features found too demanding for our platform; the most visible
|
||||
change is the exclusion of the 16bpp games (those are mostly hi-res anyway)
|
||||
but games in 640x480@8bpp work nicely.
|
||||
but games in 640x480@8bpp work nicely (Falcon only, unfortunately).
|
||||
|
||||
- Direct rendering and single/triple buffering support.
|
||||
|
||||
- Custom (and optimal) drawing routines (especially for the cursor).
|
||||
|
||||
- Custom (Super)Videl resolutions for the best possible performance and visual
|
||||
experience (320x240 in RGB, chunky modes with SuperVidel, 640x480@8bpp for
|
||||
the overlay, ...)
|
||||
- Tailored video settings for the best possible performance and visual
|
||||
experience (Falcon RGB overscan, chunky modes with the SuperVidel, TT 640x480
|
||||
for the overlay, ...)
|
||||
|
||||
- Custom (hardware based) aspect ratio correction (!)
|
||||
|
||||
- Support for PC keys (page up, page down, pause, F11/F12, ...) and mouse wheel
|
||||
(Eiffel/Aranym only)
|
||||
|
||||
This makes such games as The Curse of Monkey Island better playable (on
|
||||
SuperVidel nearly always also with CD (WAV) music and speech). Also, AdLib
|
||||
emulation works nicely with many games without noticeable slow downs.
|
||||
- AdLib emulation works nicely with many games without noticeable slow downs.
|
||||
|
||||
|
||||
Platform-specific features outside the GUI
|
||||
@ -81,8 +88,9 @@ Keyboard shortcut "CONTROL+ALT+a": immediate aspect ratio correction on/off
|
||||
toggle.
|
||||
|
||||
"output_rate" in scummvm.ini: sample rate for mixing, can be 49170, 32780,
|
||||
24585, 19668, 16390, 12292, 9834, 8195 (the lower the value, the faster the
|
||||
mixing but also in worse quality). Default is 24585 Hz (16-bit, stereo).
|
||||
24585, 19668, 16390, 12292, 9834, 8195 on the Falcon and 50066, 25033, 12517,
|
||||
6258 on the TT (the lower the value, the faster the mixing but also worse
|
||||
quality). Default is 24585/25033 Hz (16-bit, stereo).
|
||||
|
||||
"audio_buffer_size" in scummvm.ini: number of samples to preload. Default is
|
||||
2048 which equals to about 83ms of audio lag and seems to be about right for
|
||||
@ -118,13 +126,14 @@ Cons:
|
||||
- screen tearing in most cases
|
||||
|
||||
- SuperVidel only: using C2P would be not only suboptimal (every rectangle
|
||||
would be C2P'ed instead of just copy and C2P of the final screen) but poses an
|
||||
additional problem as C2P requires data aligned on a 16px boundary and
|
||||
ScummVM supplies arbitrarily-sized rectangles (this is solvable by custom
|
||||
Surface allocation but it's not bullet-proof). In theory I could implement
|
||||
direct rendering for the Falcon hicolor (320x240@16bpp) but this creates
|
||||
another set of issues like when palette would be updated but not the whole
|
||||
screen - so some rectangles would be rendered in old palette and some in new.
|
||||
would be C2P'ed instead of multiple copying and just one C2P of the final
|
||||
screen) but poses an additional problem as C2P requires data aligned on a
|
||||
16px boundary and ScummVM supplies arbitrarily-sized rectangles (this is
|
||||
solvable by custom Surface allocation but it's not bullet-proof). In theory I
|
||||
could implement direct rendering for the Falcon hicolor (320x240@16bpp) but
|
||||
this creates another set of issues like when palette would be updated but not
|
||||
the whole screen - so some rectangles would be rendered in old palette and
|
||||
some in new.
|
||||
|
||||
SuperBlitter used: sometimes (when ScummVM allocates surface via its create()
|
||||
function; custom/small buffers originating in the engine code are still copied
|
||||
@ -192,8 +201,7 @@ SuperVidel and SuperBlitter
|
||||
As mentioned, this port uses SuperVidel and its SuperBlitter heavily. That
|
||||
means that if the SuperVidel is detected, it does the following:
|
||||
|
||||
- patches all 8bpp VGA resolutions to chunky ones, rendering all C2P routines
|
||||
useless
|
||||
- uses 8bpp chunky resolutions
|
||||
|
||||
- patches all surface addresses with OR'ing 0xA0000000, i.e. using SV RAM
|
||||
instead of slow ST RAM (and even instead of TT RAM for allowing pure
|
||||
@ -205,6 +213,17 @@ means that if the SuperVidel is detected, it does the following:
|
||||
and makes a *huge* difference for 640x480 fullscreen updates.
|
||||
|
||||
|
||||
Audio mixing
|
||||
------------
|
||||
|
||||
ScummVM works internally with 16-bit stereo samples. This mode is not available
|
||||
on the TT so a substitute solution must be used. This solution is called STFA
|
||||
by The Removers: http://removers.free.fr/softs/stfa.php. Install, activate STFA
|
||||
BIOS in the CPX, done. Now you have 16-bit DMA available, too but beware, it is
|
||||
also quite CPU demanding so very few games can actually make use of it (see the
|
||||
chapter about audio performance considerations below).
|
||||
|
||||
|
||||
Performance considerations/pitfalls
|
||||
-----------------------------------
|
||||
|
||||
@ -233,11 +252,23 @@ is (by definition) the case of animated intros, especially those in 640x480.
|
||||
MIDI vs. AdLib vs. sampled music
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
It could seem that sample music replay must be the most demanding one but on the
|
||||
contrary! _Always_ choose a CD version of a game (with *.wav tracks) to any
|
||||
It could seem that sample music replay must be the most demanding one but on
|
||||
the contrary! Always choose a CD version of a game (with *.wav tracks) to any
|
||||
other version. With one exception: if you have a native MIDI device able to
|
||||
replay the given game's MIDI notes (using the STMIDI plugin). MIDI emulation
|
||||
(synthesis) can easily eat as much as 50% of all used CPU time.
|
||||
replay the given game's MIDI notes (using the STMIDI plugin).
|
||||
|
||||
MIDI emulation (synthesis) can easily eat as much as 50% of all used CPU time
|
||||
(on the CT60). By default, this port uses the MAME OPL emulation (which is said
|
||||
to be fastest but also least accurate) but some engines require the DOSBOX one
|
||||
which is even more demanding. By the way, you can put "FM_high_quality=true"
|
||||
or "FM_medium_quality=true" into scummvm.ini if you want to experiment with a
|
||||
better quality synthesis, otherwise the lowest quality will be used (applies
|
||||
for MAME OPL only).
|
||||
|
||||
On the TT, in 95% of cases it makes sense to enable music only if you have a
|
||||
native MIDI synthesizer (like mt32-pi: https://github.com/dwhinham/mt32-pi);
|
||||
STFA is usually slow to mix samples, too => mute it (see below) or don't
|
||||
install STFA (same effect).
|
||||
|
||||
CD music slows everything down
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@ -283,18 +314,41 @@ loading time. To speed things up in other cases, the "fat" version is
|
||||
distributed with repackaged theme files with compression level zero.
|
||||
|
||||
|
||||
"Slim" vs. "Fat" version
|
||||
------------------------
|
||||
|
||||
As a further optimisation step, a 030-only version of ScummVM is provided,
|
||||
aimed at accelerated TT and Falcon machines with the 68030 CPU. It further
|
||||
restricts features but also improves performance:
|
||||
|
||||
- compiled with -m68030 => 68030/68882-specific optimisations enabled
|
||||
|
||||
- disabled 040+/SuperVidel code => faster code path for blitting
|
||||
|
||||
- doesn't support hires (640x480) games => smaller executable size
|
||||
|
||||
- overlay is rendered in 16 colours => faster redraw
|
||||
|
||||
- overlay during gameplay has no game backround => ever faster redraw
|
||||
|
||||
- overlay doesn't support alternative themes => faster loading time
|
||||
|
||||
|
||||
Known issues
|
||||
------------
|
||||
|
||||
- aspect ratio correction works on RGB only (yet)
|
||||
|
||||
- SuperVidel's DVI output is stretched when in 320x200 or 640x400; I'll wait
|
||||
for other people's experiences, maybe only my LCD is so lame.
|
||||
|
||||
- adding a game in TOS and loading it in FreeMiNT (and vice versa) generates
|
||||
incompatible paths. Either use only one system or edit scummvm.ini and set
|
||||
there only relative paths (mintlib bug/limitation).
|
||||
|
||||
- when run on TT, screen contains horizontal black lines. That is due to the
|
||||
fact that TT offers only 320x480 in 256 colours. Possibly fixable by a Timer
|
||||
B interrupt.
|
||||
|
||||
- tooltips in overlay are sometimes drawn with corrupted background.
|
||||
|
||||
- the talkie version of MI1 needs to be merged from two sources: first generate
|
||||
the DOS version and then additionally also the flac version. Then convert all
|
||||
*.flac files into *.wav and replace monkey.sof (flac) with monster.sou (DOS).
|
||||
@ -306,11 +360,11 @@ Known issues
|
||||
Future plans
|
||||
------------
|
||||
|
||||
- aspect ratio correction for VGA/SuperVidel
|
||||
- aspect ratio correction for TT/VGA/SuperVidel
|
||||
|
||||
- unified file paths in scummvm.ini
|
||||
|
||||
- DSP-based sample mixer
|
||||
- DSP-based sample mixer (WAV, FLAC, MP2)
|
||||
|
||||
- avoid loading music/speech files (and thus slowing down everything) if muted
|
||||
|
||||
@ -320,24 +374,10 @@ Future plans
|
||||
- using LDG or Thorsten Otto's sharedlibs: https://tho-otto.de/sharedlibs.php
|
||||
for game engine plugins to relieve the huge binary size
|
||||
|
||||
- add support for the TT030; this would be easily possible when I rewrite the
|
||||
renderer with a more flexible resolution switching
|
||||
|
||||
- don't hardcode some of the buffers for cacheing purposes, determine the size
|
||||
based on amount of free RAM
|
||||
|
||||
- true audio CD support via MetaDOS API
|
||||
|
||||
- OPL2LPT and Retrowave support (if I manage to purchase it somewhere)
|
||||
|
||||
- engines based on Graphics::Screen don't have to use my chunky buffer (however
|
||||
it may be tricky to detect this situation)
|
||||
|
||||
- C2P could support 4- and 6-bit depth
|
||||
|
||||
- increase file buffer size with setvbuf or by using
|
||||
Common::wrapBufferedWriteStream and disabling stdio buffering
|
||||
|
||||
|
||||
Closing words
|
||||
-------------
|
||||
|
13
configure
vendored
13
configure
vendored
@ -3652,13 +3652,15 @@ if test -n "$_host"; then
|
||||
if test "$_optimizations" = "yes"; then
|
||||
# --enable-release, --enable-optimizations
|
||||
append_var CXXFLAGS "-fomit-frame-pointer"
|
||||
append_var CXXFLAGS "-fno-exceptions"
|
||||
append_var CXXFLAGS "-ffast-math"
|
||||
fi
|
||||
|
||||
# auto -> no
|
||||
if test "$_release_build" = "yes"; then
|
||||
# --enable-release
|
||||
append_var DEFINES "-DNDEBUG"
|
||||
append_var DEFINES "-DDISABLE_TEXT_CONSOLE"
|
||||
#append_var DEFINES "-DDISABLE_TEXT_CONSOLE"
|
||||
append_var CXXFLAGS "-I$HOME/gnu-tools/m68000/m68k-atari-mint/sys-root/opt/mintlib-dlmalloc/include"
|
||||
append_var LDFLAGS "-L$HOME/gnu-tools/m68000/m68k-atari-mint/sys-root/opt/mintlib-dlmalloc/lib/m68020-60"
|
||||
fi
|
||||
@ -3955,10 +3957,11 @@ case $_backend in
|
||||
;;
|
||||
atari)
|
||||
define_in_config_if_yes yes "ATARI"
|
||||
append_var DEFINES "-DDISABLE_LAUNCHERDISPLAY_GRID"
|
||||
append_var DEFINES "-DDISABLE_SID"
|
||||
append_var DEFINES "-DDISABLE_NES_APU"
|
||||
#append_var DEFINES "-DDISABLE_DOSBOX_OPL"
|
||||
append_var DEFINES "-DDISABLE_LAUNCHERDISPLAY_GRID"
|
||||
append_var DEFINES "-DDISABLE_SID"
|
||||
append_var DEFINES "-DDISABLE_NES_APU"
|
||||
#append_var DEFINES "-DDISABLE_DOSBOX_OPL"
|
||||
append_var LIBS "-lgem"
|
||||
;;
|
||||
dc)
|
||||
append_var INCLUDES '-I$(srcdir)/backends/platform/dc'
|
||||
|
@ -119,7 +119,7 @@ void Surface::create(int16 width, int16 height, const PixelFormat &f) {
|
||||
|
||||
if (width && height) {
|
||||
#ifdef USE_SV_BLITTER
|
||||
if (hasSuperVidel()) {
|
||||
if (hasSuperVidel() && w >= 64 && h >= 64) {
|
||||
pixels = (void *)ct60_vmalloc(height * pitch);
|
||||
|
||||
if (!pixels)
|
||||
|
Loading…
Reference in New Issue
Block a user