mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-04 08:17:40 +00:00
BACKENDS: ATARI: Refactor
This commit is contained in:
parent
740cf0989c
commit
6c5e3dbfd5
@ -19,8 +19,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_time_h
|
||||
|
||||
#include "backends/events/atari/atari-events.h"
|
||||
|
||||
#include <mint/osbind.h>
|
||||
@ -122,7 +120,7 @@ bool AtariEventSource::pollEvent(Common::Event &event) {
|
||||
|
||||
if (curMillis - startMillis >= 1000) {
|
||||
float avgFps = avgFpsSum / avgFpsCount;
|
||||
debug("*** Average FPS in 1s: %f ***", avgFps);
|
||||
//debug("*** Average FPS in 1s: %f ***", avgFps);
|
||||
startMillis = curMillis;
|
||||
avgFpsSum = 0;
|
||||
avgFpsCount = 0;
|
||||
|
@ -22,32 +22,20 @@
|
||||
#ifndef BACKENDS_GRAPHICS_ATARI_SUPERBLITTER_H
|
||||
#define BACKENDS_GRAPHICS_ATARI_SUPERBLITTER_H
|
||||
|
||||
#include <mint/trap14.h>
|
||||
#include <mint/cookie.h>
|
||||
#include <mint/falcon.h>
|
||||
|
||||
#define ct60_vm(mode, value) (long)trap_14_wwl((short)0xc60e, (short)(mode), (long)(value))
|
||||
#define ct60_vmalloc(value) ct60_vm(0, value)
|
||||
#define ct60_vmfree(value) ct60_vm(1, value)
|
||||
|
||||
// bits 26:0
|
||||
#define SV_BLITTER_SRC1 ((volatile long*)0x80010058)
|
||||
#define SV_BLITTER_SRC2 ((volatile long*)0x8001005C)
|
||||
#define SV_BLITTER_DST ((volatile long*)0x80010060)
|
||||
// The amount of bytes that are to be copied in a horizontal line, minus 1
|
||||
#define SV_BLITTER_COUNT ((volatile long*)0x80010064)
|
||||
// The amount of bytes that are to be added to the line start adress after a line has been copied, in order to reach the next one
|
||||
#define SV_BLITTER_SRC1_OFFSET ((volatile long*)0x80010068)
|
||||
#define SV_BLITTER_SRC2_OFFSET ((volatile long*)0x8001006C)
|
||||
#define SV_BLITTER_DST_OFFSET ((volatile long*)0x80010070)
|
||||
// bits 11:0 - The amount of horizontal lines to do
|
||||
#define SV_BLITTER_MASK_AND_LINES ((volatile long*)0x80010074)
|
||||
// bit 0 - busy / start
|
||||
// bits 4:1 - blit mode
|
||||
#define SV_BLITTER_CONTROL ((volatile long*)0x80010078)
|
||||
// bits 9:0
|
||||
#define SV_VERSION ((volatile long*)0x8001007C)
|
||||
// bit 0 - empty (read only)
|
||||
// bit 1 - full (read only)
|
||||
// bits 31:0 - data (write only)
|
||||
#define SV_BLITTER_FIFO ((volatile long*)0x80010080)
|
||||
#define SV_VERSION ((volatile long*)0x8001007C)
|
||||
|
||||
inline static bool hasSuperVidel() {
|
||||
static bool hasSuperVidel = VgetMonitor() == MON_VGA && Getcookie(C_SupV, NULL) == C_FOUND;
|
||||
return hasSuperVidel;
|
||||
}
|
||||
|
||||
static int superVidelFwVersion = hasSuperVidel() ? *SV_VERSION & 0x01ff : 0;
|
||||
|
||||
void lockSuperBlitter();
|
||||
void unlockSuperBlitter();
|
||||
|
||||
#endif
|
||||
|
@ -22,75 +22,42 @@
|
||||
#ifndef BACKENDS_GRAPHICS_ATARI_SUPERVIDEL_H
|
||||
#define BACKENDS_GRAPHICS_ATARI_SUPERVIDEL_H
|
||||
|
||||
#define USE_SV_BLITTER // TODO: into configure?
|
||||
|
||||
#include "backends/graphics/atari/atari-graphics.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <mint/osbind.h>
|
||||
|
||||
#ifdef USE_SV_BLITTER
|
||||
#include "backends/graphics/atari/atari-graphics-superblitter.h"
|
||||
#endif
|
||||
|
||||
#include "backends/graphics/atari/videl-resolutions.h"
|
||||
#include "common/debug.h" // error() & warning()
|
||||
#include "common/scummsys.h"
|
||||
#include "common/textconsole.h" // for error()
|
||||
|
||||
class AtariSuperVidelManager : public AtariGraphicsManager {
|
||||
public:
|
||||
AtariSuperVidelManager() {
|
||||
#ifdef USE_SV_BLITTER
|
||||
_fwVersion = *SV_VERSION & 0x01ff;
|
||||
debug("SuperVidel FW Revision: %d, using %s", _fwVersion, _fwVersion >= 9
|
||||
? "fast async FIFO" : "slower sync blitting" );
|
||||
debug("SuperVidel FW Revision: %d, using %s", superVidelFwVersion, superVidelFwVersion >= 9
|
||||
? "fast async FIFO" : "slower sync blitting");
|
||||
#else
|
||||
debug("SuperVidel FW Revision: %d, SuperBlitter not used", superVidelFwVersion);
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < SCREENS; ++i) {
|
||||
if (!allocateAtariSurface(_screen[i], _screenSurface,
|
||||
SCREEN_WIDTH, SCREEN_HEIGHT, PIXELFORMAT8,
|
||||
MX_STRAM, 0xA0000000))
|
||||
error("Failed to allocate screen memory in ST RAM");
|
||||
_screenAligned[i] = (byte*)_screenSurface.getPixels();
|
||||
}
|
||||
_screenSurface.setPixels(_screenAligned[getDefaultGraphicsMode() <= 1 ? FRONT_BUFFER : BACK_BUFFER1]);
|
||||
|
||||
if (!allocateAtariSurface(_chunkyBuffer, _chunkySurface,
|
||||
SCREEN_WIDTH, SCREEN_HEIGHT, PIXELFORMAT8,
|
||||
MX_PREFTTRAM))
|
||||
error("Failed to allocate chunky buffer memory in ST/TT RAM");
|
||||
|
||||
if (!allocateAtariSurface(_overlayScreen, _screenOverlaySurface,
|
||||
getOverlayWidth(), getOverlayHeight(), getOverlayFormat(),
|
||||
MX_STRAM, 0xA0000000))
|
||||
error("Failed to allocate overlay memory in ST RAM");
|
||||
|
||||
if (!allocateAtariSurface(_overlayBuffer, _overlaySurface,
|
||||
getOverlayWidth(), getOverlayHeight(), getOverlayFormat(),
|
||||
MX_PREFTTRAM))
|
||||
error("Failed to allocate overlay buffer memory in ST/TT RAM");
|
||||
if (Supexec(hasSvRamBoosted))
|
||||
debug("SV_XBIOS has the pmmu boost enabled");
|
||||
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();
|
||||
}
|
||||
|
||||
~AtariSuperVidelManager() {
|
||||
#ifdef USE_SV_BLITTER
|
||||
ct60_vmfree(_chunkyBuffer);
|
||||
#else
|
||||
Mfree(_chunkyBuffer);
|
||||
#endif
|
||||
_chunkyBuffer = nullptr;
|
||||
|
||||
#ifdef USE_SV_BLITTER
|
||||
ct60_vmfree(_overlayBuffer);
|
||||
#else
|
||||
Mfree(_overlayBuffer);
|
||||
#endif
|
||||
_overlayBuffer = nullptr;
|
||||
// using virtual methods so must be done here
|
||||
freeSurfaces();
|
||||
}
|
||||
|
||||
virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const override {
|
||||
@ -107,95 +74,56 @@ public:
|
||||
int16 getOverlayHeight() const override { return 2 * OVERLAY_HEIGHT; }
|
||||
int16 getOverlayWidth() const override { return 2 * OVERLAY_WIDTH; }
|
||||
|
||||
protected:
|
||||
AtariMemAlloc getStRamAllocFunc() const override {
|
||||
return [](size_t bytes) {
|
||||
uintptr ptr = Mxalloc(bytes, MX_STRAM);
|
||||
|
||||
if (ptr != 0)
|
||||
ptr |= 0xA0000000;
|
||||
|
||||
return (void*)ptr;
|
||||
};
|
||||
}
|
||||
AtariMemFree getStRamFreeFunc() const override {
|
||||
return [](void *ptr) { Mfree((uintptr)ptr & 0x00FFFFFF); };
|
||||
}
|
||||
|
||||
private:
|
||||
virtual void* allocFast(size_t bytes) const override {
|
||||
#ifdef USE_SV_BLITTER
|
||||
return (void*)ct60_vmalloc(bytes);
|
||||
#else
|
||||
return (void*)Mxalloc(bytes, MX_PREFTTRAM);
|
||||
#endif
|
||||
}
|
||||
|
||||
void copySurfaceToSurface(const Graphics::Surface &srcSurface, Graphics::Surface &dstSurface) const override {
|
||||
#ifdef USE_SV_BLITTER
|
||||
if (_fwVersion >= 9) {
|
||||
*SV_BLITTER_FIFO = (long)srcSurface.getPixels(); // SV_BLITTER_SRC1
|
||||
*SV_BLITTER_FIFO = 0x00000000; // SV_BLITTER_SRC2
|
||||
*SV_BLITTER_FIFO = (long)dstSurface.getPixels(); // SV_BLITTER_DST
|
||||
*SV_BLITTER_FIFO = srcSurface.w - 1; // SV_BLITTER_COUNT
|
||||
*SV_BLITTER_FIFO = srcSurface.pitch; // SV_BLITTER_SRC1_OFFSET
|
||||
*SV_BLITTER_FIFO = 0x00000000; // SV_BLITTER_SRC2_OFFSET
|
||||
*SV_BLITTER_FIFO = dstSurface.pitch; // SV_BLITTER_DST_OFFSET
|
||||
*SV_BLITTER_FIFO = srcSurface.h; // SV_BLITTER_MASK_AND_LINES
|
||||
*SV_BLITTER_FIFO = 0x01; // SV_BLITTER_CONTROL
|
||||
} else {
|
||||
sync();
|
||||
|
||||
*SV_BLITTER_SRC1 = (long)srcSurface.getPixels();
|
||||
*SV_BLITTER_SRC2 = 0x00000000;
|
||||
*SV_BLITTER_DST = (long)dstSurface.getPixels();
|
||||
*SV_BLITTER_COUNT = srcSurface.w - 1;
|
||||
*SV_BLITTER_SRC1_OFFSET = srcSurface.pitch;
|
||||
*SV_BLITTER_SRC2_OFFSET = 0x00000000;
|
||||
*SV_BLITTER_DST_OFFSET = dstSurface.pitch;
|
||||
*SV_BLITTER_MASK_AND_LINES = srcSurface.h;
|
||||
*SV_BLITTER_CONTROL = 0x01;
|
||||
}
|
||||
#else
|
||||
memcpy(dstSurface.getPixels(), srcSurface.getPixels(), srcSurface.h * srcSurface.pitch);
|
||||
#endif
|
||||
}
|
||||
|
||||
void copyRectToSurface(const Graphics::Surface &srcSurface, int destX, int destY, Graphics::Surface &dstSurface,
|
||||
void copyRectToSurface(Graphics::Surface &dstSurface,
|
||||
const Graphics::Surface &srcSurface, int destX, int destY,
|
||||
const Common::Rect &subRect) const override {
|
||||
#ifdef USE_SV_BLITTER
|
||||
if (_fwVersion >= 9) {
|
||||
*SV_BLITTER_FIFO = (long)srcSurface.getBasePtr(subRect.left, subRect.top); // SV_BLITTER_SRC1
|
||||
*SV_BLITTER_FIFO = 0x00000000; // SV_BLITTER_SRC2
|
||||
*SV_BLITTER_FIFO = (long)dstSurface.getBasePtr(destX, destY); // SV_BLITTER_DST
|
||||
*SV_BLITTER_FIFO = subRect.width() - 1; // SV_BLITTER_COUNT
|
||||
*SV_BLITTER_FIFO = srcSurface.pitch; // SV_BLITTER_SRC1_OFFSET
|
||||
*SV_BLITTER_FIFO = 0x00000000; // SV_BLITTER_SRC2_OFFSET
|
||||
*SV_BLITTER_FIFO = dstSurface.pitch; // SV_BLITTER_DST_OFFSET
|
||||
*SV_BLITTER_FIFO = subRect.height(); // SV_BLITTER_MASK_AND_LINES
|
||||
*SV_BLITTER_FIFO = 0x01; // SV_BLITTER_CONTROL
|
||||
} else {
|
||||
sync();
|
||||
|
||||
*SV_BLITTER_SRC1 = (long)srcSurface.getBasePtr(subRect.left, subRect.top);
|
||||
*SV_BLITTER_SRC2 = 0x00000000;
|
||||
*SV_BLITTER_DST = (long)dstSurface.getBasePtr(destX, destY);
|
||||
*SV_BLITTER_COUNT = subRect.width() - 1;
|
||||
*SV_BLITTER_SRC1_OFFSET = srcSurface.pitch;
|
||||
*SV_BLITTER_SRC2_OFFSET = 0x00000000;
|
||||
*SV_BLITTER_DST_OFFSET = dstSurface.pitch;
|
||||
*SV_BLITTER_MASK_AND_LINES = subRect.height();
|
||||
*SV_BLITTER_CONTROL = 0x01;
|
||||
}
|
||||
#else
|
||||
dstSurface.copyRectToSurface(srcSurface, destX, destY, subRect);
|
||||
#endif
|
||||
}
|
||||
|
||||
void copyRectToSurfaceWithKey(const Graphics::Surface &srcSurface, int destX, int destY, Graphics::Surface &dstSurface,
|
||||
void copyRectToSurfaceWithKey(Graphics::Surface &dstSurface,
|
||||
const Graphics::Surface &srcSurface, int destX, int destY,
|
||||
const Common::Rect &subRect, uint32 key) const override {
|
||||
sync();
|
||||
dstSurface.copyRectToSurfaceWithKey(srcSurface, destX, destY, subRect, key);
|
||||
}
|
||||
|
||||
virtual void sync() const override {
|
||||
#ifdef USE_SV_BLITTER
|
||||
// while FIFO not empty...
|
||||
if (_fwVersion >= 9)
|
||||
while (!(*SV_BLITTER_FIFO & 1));
|
||||
// while busy blitting...
|
||||
while (*SV_BLITTER_CONTROL & 1);
|
||||
#endif
|
||||
}
|
||||
static long hasSvRamBoosted() {
|
||||
register long ret __asm__ ("d0") = 0;
|
||||
|
||||
#ifdef USE_SV_BLITTER
|
||||
int _fwVersion = 0;
|
||||
#endif
|
||||
__asm__ volatile(
|
||||
"\tmovec %%itt0,%%d1\n"
|
||||
"\tcmp.l #0xA007E060,%%d1\n"
|
||||
"\tbne.s 1f\n"
|
||||
|
||||
"\tmovec %%dtt0,%%d1\n"
|
||||
"\tcmp.l #0xA007E060,%%d1\n"
|
||||
"\tbne.s 1f\n"
|
||||
|
||||
"\tmoveq #1,%%d0\n"
|
||||
|
||||
"1:\n"
|
||||
: "=g"(ret) /* outputs */
|
||||
: /* inputs */
|
||||
: __CLOBBER_RETURN("d0") "d1", "cc"
|
||||
);
|
||||
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -24,40 +24,19 @@
|
||||
|
||||
#include "backends/graphics/atari/atari-graphics.h"
|
||||
|
||||
#include <mint/osbind.h>
|
||||
|
||||
#include "backends/graphics/atari/atari_c2p-asm.h"
|
||||
#include "common/system.h"
|
||||
#include "common/textconsole.h" // for error()
|
||||
|
||||
class AtariVidelManager : public AtariGraphicsManager {
|
||||
public:
|
||||
AtariVidelManager() {
|
||||
for (int i = 0; i < SCREENS; ++i) {
|
||||
if (!allocateAtariSurface(_screen[i], _screenSurface, SCREEN_WIDTH, SCREEN_HEIGHT, PIXELFORMAT8, MX_STRAM))
|
||||
error("Failed to allocate screen memory in ST RAM");
|
||||
_screenAligned[i] = (byte*)_screenSurface.getPixels();
|
||||
}
|
||||
_screenSurface.setPixels(_screenAligned[getDefaultGraphicsMode() <= 1 ? FRONT_BUFFER : BACK_BUFFER1]);
|
||||
|
||||
if (!allocateAtariSurface(_chunkyBuffer, _chunkySurface, SCREEN_WIDTH, SCREEN_HEIGHT, PIXELFORMAT8, MX_PREFTTRAM))
|
||||
error("Failed to allocate chunky buffer memory in ST/TT RAM");
|
||||
|
||||
if (!allocateAtariSurface(_overlayScreen, _screenOverlaySurface, getOverlayWidth(), getOverlayHeight(),
|
||||
getOverlayFormat(), MX_STRAM))
|
||||
error("Failed to allocate overlay memory in ST RAM");
|
||||
|
||||
if (!allocateAtariSurface(_overlayBuffer, _overlaySurface, getOverlayWidth(), getOverlayHeight(),
|
||||
getOverlayFormat(), MX_PREFTTRAM))
|
||||
error("Failed to allocate overlay buffer memory in ST/TT RAM");
|
||||
// using virtual methods so must be done here
|
||||
allocateSurfaces();
|
||||
}
|
||||
|
||||
~AtariVidelManager() {
|
||||
Mfree(_chunkyBuffer);
|
||||
_chunkyBuffer = nullptr;
|
||||
|
||||
Mfree(_overlayBuffer);
|
||||
_overlayBuffer = nullptr;
|
||||
// using virtual methods so must be done here
|
||||
freeSurfaces();
|
||||
}
|
||||
|
||||
virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const override {
|
||||
@ -89,35 +68,35 @@ public:
|
||||
int16 getOverlayWidth() const override { return _vgaMonitor ? OVERLAY_WIDTH : 2 * OVERLAY_WIDTH; }
|
||||
|
||||
private:
|
||||
virtual void* allocFast(size_t bytes) const override {
|
||||
return (void*)Mxalloc(bytes, MX_PREFTTRAM);
|
||||
}
|
||||
|
||||
void copySurfaceToSurface(const Graphics::Surface &srcSurface, Graphics::Surface &dstSurface) const override {
|
||||
asm_c2p1x1_8(
|
||||
(const byte*)srcSurface.getPixels(),
|
||||
(const byte*)srcSurface.getBasePtr(srcSurface.w, srcSurface.h-1),
|
||||
(byte*)dstSurface.getPixels());
|
||||
}
|
||||
|
||||
void copyRectToSurface(const Graphics::Surface &srcSurface, int destX, int destY,
|
||||
Graphics::Surface &dstSurface, const Common::Rect &subRect) const override {
|
||||
void copyRectToSurface(Graphics::Surface &dstSurface,
|
||||
const Graphics::Surface &srcSurface, int destX, int destY,
|
||||
const Common::Rect &subRect) const override {
|
||||
// 'pChunkyEnd' is a delicate parameter: the c2p routine compares it to the address register
|
||||
// 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
|
||||
asm_c2p1x1_8_rect(
|
||||
(const byte*)srcSurface.getBasePtr(subRect.left, subRect.top),
|
||||
(const byte*)srcSurface.getBasePtr(subRect.right, subRect.bottom-1),
|
||||
subRect.width(),
|
||||
srcSurface.pitch,
|
||||
(byte*)dstSurface.getBasePtr(destX, destY),
|
||||
dstSurface.pitch);
|
||||
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 {
|
||||
asm_c2p1x1_8_rect(
|
||||
(const byte*)srcSurface.getBasePtr(subRect.left, subRect.top),
|
||||
(const byte*)srcSurface.getBasePtr(subRect.right, subRect.bottom-1),
|
||||
subRect.width(),
|
||||
srcSurface.pitch,
|
||||
(byte*)dstSurface.getBasePtr(destX, destY),
|
||||
dstSurface.pitch);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: allow specifying different background than _chunkySurface?
|
||||
void copyRectToSurfaceWithKey(const Graphics::Surface &srcSurface, int destX, int destY,
|
||||
Graphics::Surface &dstSurface, const Common::Rect &subRect, uint32 key) const override {
|
||||
// TODO: alignRect and this function could be perhaps better if we know that all surfaces
|
||||
// are aligned on 16px and their pitch is % 16 as well?
|
||||
void copyRectToSurfaceWithKey(Graphics::Surface &dstSurface,
|
||||
const Graphics::Surface &srcSurface, int destX, int destY,
|
||||
const Common::Rect &subRect, uint32 key) 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
|
||||
@ -144,9 +123,9 @@ private:
|
||||
cachedSurface.copyRectToSurfaceWithKey(srcSurface, deltaX, 0, subRect, key);
|
||||
|
||||
copyRectToSurface(
|
||||
dstSurface,
|
||||
cachedSurface,
|
||||
backgroundRect.left, backgroundRect.top,
|
||||
dstSurface,
|
||||
Common::Rect(cachedSurface.w, cachedSurface.h));
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <mint/osbind.h>
|
||||
|
||||
#include "backends/graphics/atari/atari-graphics-asm.h"
|
||||
#include "backends/graphics/atari/atari-graphics-superblitter.h"
|
||||
#include "backends/graphics/atari/videl-resolutions.h"
|
||||
#include "backends/keymapper/action.h"
|
||||
#include "backends/keymapper/keymap.h"
|
||||
@ -67,14 +68,6 @@ AtariGraphicsManager::AtariGraphicsManager() {
|
||||
|
||||
AtariGraphicsManager::~AtariGraphicsManager() {
|
||||
g_system->getEventManager()->getEventDispatcher()->unregisterObserver(this);
|
||||
|
||||
for (int i = 0; i < SCREENS; ++i) {
|
||||
Mfree(_screen[i]);
|
||||
_screen[i] = _screenAligned[i] = nullptr;
|
||||
}
|
||||
|
||||
Mfree(_overlayScreen);
|
||||
_overlayScreen = nullptr;
|
||||
}
|
||||
|
||||
bool AtariGraphicsManager::hasFeature(OSystem::Feature f) const {
|
||||
@ -293,6 +286,8 @@ void AtariGraphicsManager::updateScreen() {
|
||||
|
||||
bool screenUpdated = false;
|
||||
|
||||
lockSuperBlitter();
|
||||
|
||||
if (isOverlayVisible()) {
|
||||
screenUpdated = updateOverlay();
|
||||
} else {
|
||||
@ -310,14 +305,14 @@ void AtariGraphicsManager::updateScreen() {
|
||||
}
|
||||
}
|
||||
|
||||
unlockSuperBlitter();
|
||||
|
||||
//if (_cursor.outOfScreen)
|
||||
// warning("mouse out of screen");
|
||||
|
||||
bool vsync = _vsync;
|
||||
|
||||
if (_screenModified) {
|
||||
sync();
|
||||
|
||||
if (_currentState.mode == GraphicsMode::DoubleBuffering) {
|
||||
byte *tmp = _screenAligned[FRONT_BUFFER];
|
||||
_screenAligned[FRONT_BUFFER] = _screenAligned[BACK_BUFFER1];
|
||||
@ -532,6 +527,9 @@ void AtariGraphicsManager::setMouseCursor(const void *buf, uint w, uint h, int h
|
||||
bool dontScale, const Graphics::PixelFormat *format, const byte *mask) {
|
||||
//debug("setMouseCursor: %d, %d, %d, %d, %d, %d", w, h, hotspotX, hotspotY, keycolor, format ? format->bytesPerPixel : 1);
|
||||
|
||||
if (mask)
|
||||
warning("AtariGraphicsManager::setMouseCursor: Masks are not supported");
|
||||
|
||||
const Graphics::PixelFormat cursorFormat = format ? *format : PIXELFORMAT8;
|
||||
_cursor.setSurface(buf, (int)w, (int)h, hotspotX, hotspotY, keycolor, cursorFormat);
|
||||
}
|
||||
@ -575,21 +573,38 @@ Common::Keymap *AtariGraphicsManager::getKeymap() const {
|
||||
return keymap;
|
||||
}
|
||||
|
||||
bool AtariGraphicsManager::allocateAtariSurface(
|
||||
byte *&buf, Graphics::Surface &surface, int width, int height,
|
||||
const Graphics::PixelFormat &format, int mode, uintptr mask) {
|
||||
buf = (mode == MX_STRAM)
|
||||
? (byte*)Mxalloc(width * height * format.bytesPerPixel + 15, mode)
|
||||
: (byte*)allocFast(width * height * format.bytesPerPixel + 15);
|
||||
void AtariGraphicsManager::allocateSurfaces() {
|
||||
for (int i = 0; i < SCREENS; ++i) {
|
||||
if (!(_screen[i] = allocateAtariSurface(_screenSurface,
|
||||
SCREEN_WIDTH, SCREEN_HEIGHT, PIXELFORMAT8,
|
||||
getStRamAllocFunc())))
|
||||
error("Failed to allocate screen memory in ST RAM");
|
||||
_screenAligned[i] = (byte*)_screenSurface.getPixels();
|
||||
}
|
||||
_screenSurface.setPixels(_screenAligned[getDefaultGraphicsMode() <= 1 ? FRONT_BUFFER : BACK_BUFFER1]);
|
||||
|
||||
if (!buf)
|
||||
return false;
|
||||
_chunkySurface.create(SCREEN_WIDTH, SCREEN_HEIGHT, PIXELFORMAT8);
|
||||
|
||||
byte *bufAligned = (byte*)((((uintptr)buf + 15) | mask) & 0xfffffff0);
|
||||
memset(bufAligned, 0, width * height * format.bytesPerPixel);
|
||||
if (!(_overlayScreen = allocateAtariSurface(_screenOverlaySurface,
|
||||
getOverlayWidth(), getOverlayHeight(), getOverlayFormat(),
|
||||
getStRamAllocFunc())))
|
||||
error("Failed to allocate overlay memory in ST RAM");
|
||||
|
||||
surface.init(width, height, width * format.bytesPerPixel, bufAligned, format);
|
||||
return true;
|
||||
_overlaySurface.create(getOverlayWidth(), getOverlayHeight(), getOverlayFormat());
|
||||
}
|
||||
|
||||
void AtariGraphicsManager::freeSurfaces() {
|
||||
for (int i = 0; i < SCREENS; ++i) {
|
||||
freeAtariSurface(_screen[i], _screenSurface, getStRamFreeFunc());
|
||||
_screen[i] = _screenAligned[i] = nullptr;
|
||||
}
|
||||
|
||||
_chunkySurface.free();
|
||||
|
||||
freeAtariSurface(_overlayScreen, _screenOverlaySurface, getStRamFreeFunc());
|
||||
_overlayScreen = nullptr;
|
||||
|
||||
_overlaySurface.free();
|
||||
}
|
||||
|
||||
void AtariGraphicsManager::setVidelResolution() const {
|
||||
@ -755,10 +770,7 @@ bool AtariGraphicsManager::updateSingleBuffer() {
|
||||
if (!drawCursor && !_cursor.outOfScreen && _cursor.visible)
|
||||
drawCursor = rect.intersects(_cursor.dstRect);
|
||||
|
||||
if (rect.width() == _screenSurface.w && rect.height() == _screenSurface.h)
|
||||
copySurfaceToSurface(_chunkySurface, _screenSurface);
|
||||
else
|
||||
copyRectToSurface(_chunkySurface, rect.left, rect.top, _screenSurface, rect);
|
||||
copyRectToSurface(_screenSurface, _chunkySurface, rect.left, rect.top, rect);
|
||||
|
||||
_modifiedChunkyRects.pop_back();
|
||||
|
||||
@ -770,8 +782,10 @@ bool AtariGraphicsManager::updateSingleBuffer() {
|
||||
|
||||
if ((_cursor.positionChanged || !_cursor.visible) && !_oldCursorRect.isEmpty()) {
|
||||
alignRect(_chunkySurface, _oldCursorRect);
|
||||
copyRectToSurface(_chunkySurface, _oldCursorRect.left, _oldCursorRect.top,
|
||||
_screenSurface, _oldCursorRect);
|
||||
copyRectToSurface(
|
||||
_screenSurface, _chunkySurface,
|
||||
_oldCursorRect.left, _oldCursorRect.top,
|
||||
_oldCursorRect);
|
||||
|
||||
_oldCursorRect = Common::Rect();
|
||||
|
||||
@ -780,8 +794,10 @@ bool AtariGraphicsManager::updateSingleBuffer() {
|
||||
|
||||
if (drawCursor && _cursor.visible) {
|
||||
//debug("Redraw cursor (single): %d %d %d %d", _cursor.dstRect.left, _cursor.dstRect.top, _cursor.dstRect.width(), _cursor.dstRect.height());
|
||||
copyRectToSurfaceWithKey(_cursor.surface, _cursor.dstRect.left, _cursor.dstRect.top,
|
||||
_screenSurface, _cursor.srcRect, _cursor.keycolor);
|
||||
copyRectToSurfaceWithKey(
|
||||
_screenSurface, _cursor.surface,
|
||||
_cursor.dstRect.left, _cursor.dstRect.top,
|
||||
_cursor.srcRect, _cursor.keycolor);
|
||||
|
||||
_cursor.positionChanged = _cursor.surfaceChanged = false;
|
||||
_oldCursorRect = _cursor.dstRect;
|
||||
@ -799,7 +815,10 @@ bool AtariGraphicsManager::updateDoubleAndTripleBuffer() {
|
||||
if (_screenModified) {
|
||||
drawCursor = true;
|
||||
|
||||
copySurfaceToSurface(_chunkySurface, _screenSurface);
|
||||
copyRectToSurface(
|
||||
_screenSurface, _chunkySurface,
|
||||
0, 0,
|
||||
Common::Rect(_chunkySurface.w, _chunkySurface.h));
|
||||
|
||||
// updated in screen swapping
|
||||
//_screenModified = false;
|
||||
@ -816,8 +835,10 @@ bool AtariGraphicsManager::updateDoubleAndTripleBuffer() {
|
||||
|
||||
if ((_cursor.positionChanged || !_cursor.visible) && !_oldCursorRect.isEmpty() && !_screenModified) {
|
||||
alignRect(_chunkySurface, _oldCursorRect);
|
||||
copyRectToSurface(_chunkySurface, _oldCursorRect.left, _oldCursorRect.top,
|
||||
frontBufferScreenSurface, _oldCursorRect);
|
||||
copyRectToSurface(
|
||||
frontBufferScreenSurface, _chunkySurface,
|
||||
_oldCursorRect.left, _oldCursorRect.top,
|
||||
_oldCursorRect);
|
||||
|
||||
_oldCursorRect = Common::Rect();
|
||||
|
||||
@ -827,8 +848,10 @@ bool AtariGraphicsManager::updateDoubleAndTripleBuffer() {
|
||||
if (drawCursor && _cursor.visible) {
|
||||
//debug("Redraw cursor (double/triple): %d %d %d %d", _cursor.dstRect.left, _cursor.dstRect.top, _cursor.dstRect.width(), _cursor.dstRect.height());
|
||||
|
||||
copyRectToSurfaceWithKey(_cursor.surface, _cursor.dstRect.left, _cursor.dstRect.top,
|
||||
frontBufferScreenSurface, _cursor.srcRect, _cursor.keycolor);
|
||||
copyRectToSurfaceWithKey(
|
||||
frontBufferScreenSurface, _cursor.surface,
|
||||
_cursor.dstRect.left, _cursor.dstRect.top,
|
||||
_cursor.srcRect, _cursor.keycolor);
|
||||
|
||||
_cursor.positionChanged = _cursor.surfaceChanged = false;
|
||||
_oldCursorRect = _cursor.dstRect;
|
||||
@ -839,6 +862,26 @@ bool AtariGraphicsManager::updateDoubleAndTripleBuffer() {
|
||||
return updated;
|
||||
}
|
||||
|
||||
byte *AtariGraphicsManager::allocateAtariSurface(Graphics::Surface &surface,
|
||||
int width, int height, const Graphics::PixelFormat &format,
|
||||
const AtariMemAlloc &allocFunc) {
|
||||
byte *buf = (byte*)allocFunc(width * height * format.bytesPerPixel + 15);
|
||||
if (!buf)
|
||||
return buf;
|
||||
|
||||
byte *bufAligned = (byte*)(((uintptr)buf + 15) & 0xfffffff0);
|
||||
memset(bufAligned, 0, width * height * format.bytesPerPixel);
|
||||
|
||||
surface.init(width, height, width * format.bytesPerPixel, bufAligned, format);
|
||||
return buf;
|
||||
}
|
||||
|
||||
void AtariGraphicsManager::freeAtariSurface(byte *ptr, Graphics::Surface &surface,
|
||||
const AtariMemFree &freeFunc) {
|
||||
surface = Graphics::Surface();
|
||||
freeFunc(ptr);
|
||||
}
|
||||
|
||||
void AtariGraphicsManager::copySurface8ToSurface16(
|
||||
const Graphics::Surface &srcSurface, const byte *srcPalette,
|
||||
Graphics::Surface &dstSurface, int destX, int destY,
|
||||
|
@ -24,6 +24,8 @@
|
||||
|
||||
#include "backends/graphics/graphics.h"
|
||||
|
||||
#include <mint/osbind.h>
|
||||
|
||||
#include "common/array.h"
|
||||
#include "common/events.h"
|
||||
#include "common/rect.h"
|
||||
@ -92,11 +94,20 @@ public:
|
||||
|
||||
protected:
|
||||
const Graphics::PixelFormat PIXELFORMAT8 = Graphics::PixelFormat::createFormatCLUT8();
|
||||
const Graphics::PixelFormat PIXELFORMAT16 = getOverlayFormat();
|
||||
|
||||
bool allocateAtariSurface(byte *&buf, Graphics::Surface &surface,
|
||||
int width, int height, const Graphics::PixelFormat &format,
|
||||
int mode, uintptr mask = 0x00000000);
|
||||
typedef void* (*AtariMemAlloc)(size_t bytes);
|
||||
typedef void (*AtariMemFree)(void *ptr);
|
||||
|
||||
virtual AtariMemAlloc getStRamAllocFunc() const {
|
||||
return [](size_t bytes) { return (void*)Mxalloc(bytes, MX_STRAM); };
|
||||
}
|
||||
|
||||
virtual AtariMemFree getStRamFreeFunc() const {
|
||||
return [](void *ptr) { Mfree(ptr); };
|
||||
}
|
||||
|
||||
void allocateSurfaces();
|
||||
void freeSurfaces();
|
||||
|
||||
bool _vgaMonitor = true;
|
||||
|
||||
@ -129,18 +140,8 @@ protected:
|
||||
static const int FRONT_BUFFER = 0;
|
||||
static const int BACK_BUFFER1 = 1;
|
||||
static const int BACK_BUFFER2 = 2;
|
||||
byte *_screen[SCREENS] = {}; // for Mfree() purposes only
|
||||
byte *_screenAligned[SCREENS] = {};
|
||||
Graphics::Surface _screenSurface;
|
||||
|
||||
byte *_chunkyBuffer = nullptr; // for Mfree() purposes only
|
||||
Graphics::Surface _chunkySurface;
|
||||
|
||||
byte *_overlayScreen = nullptr; // for Mfree() purposes only
|
||||
Graphics::Surface _screenOverlaySurface;
|
||||
|
||||
byte *_overlayBuffer = nullptr; // for Mfree() purposes only
|
||||
Graphics::Surface _overlaySurface;
|
||||
Graphics::Surface _chunkySurface; // for Videl's copyRectToSurfaceWithKey
|
||||
|
||||
private:
|
||||
enum CustomEventAction {
|
||||
@ -155,15 +156,19 @@ private:
|
||||
bool updateSingleBuffer();
|
||||
bool updateDoubleAndTripleBuffer();
|
||||
|
||||
virtual void* allocFast(size_t bytes) const = 0;
|
||||
byte *allocateAtariSurface(Graphics::Surface &surface,
|
||||
int width, int height, const Graphics::PixelFormat &format,
|
||||
const AtariMemAlloc &allocFunc);
|
||||
|
||||
virtual void copySurfaceToSurface(const Graphics::Surface &srcSurface, Graphics::Surface &dstSurface) const = 0;
|
||||
virtual void copyRectToSurface(const Graphics::Surface &srcSurface, int destX, int destY,
|
||||
Graphics::Surface &dstSurface, const Common::Rect &subRect) const = 0;
|
||||
virtual void copyRectToSurfaceWithKey(const Graphics::Surface &srcSurface, int destX, int destY,
|
||||
Graphics::Surface &dstSurface, const Common::Rect &subRect, uint32 key) const = 0;
|
||||
void freeAtariSurface(byte *ptr, Graphics::Surface &surface, const AtariMemFree &freeFunc);
|
||||
|
||||
virtual void copyRectToSurface(Graphics::Surface &dstSurface,
|
||||
const Graphics::Surface &srcSurface, int destX, int destY,
|
||||
const Common::Rect &subRect) const = 0;
|
||||
virtual void copyRectToSurfaceWithKey(Graphics::Surface &dstSurface,
|
||||
const Graphics::Surface &srcSurface, int destX, int destY,
|
||||
const Common::Rect &subRect, uint32 key) const = 0;
|
||||
virtual void alignRect(const Graphics::Surface &srcSurface, Common::Rect &rect) const {}
|
||||
virtual void sync() const {}
|
||||
|
||||
enum class ScaleMode {
|
||||
NONE,
|
||||
@ -195,12 +200,19 @@ private:
|
||||
};
|
||||
int _pendingScreenChange = kPendingScreenChangeNone;
|
||||
|
||||
bool _screenModified = false; // double/triple buffering only
|
||||
byte *_screen[SCREENS] = {}; // for Mfree() purposes only
|
||||
byte *_screenAligned[SCREENS] = {};
|
||||
Graphics::Surface _screenSurface;
|
||||
Common::Rect _modifiedScreenRect; // direct rendering only
|
||||
bool _screenModified = false; // double/triple buffering only
|
||||
|
||||
Common::Array<Common::Rect> _modifiedChunkyRects;
|
||||
|
||||
byte *_overlayScreen = nullptr; // for Mfree() purposes only
|
||||
Graphics::Surface _screenOverlaySurface;
|
||||
bool _overlayVisible = false;
|
||||
|
||||
Graphics::Surface _overlaySurface;
|
||||
Common::Array<Common::Rect> _modifiedOverlayRects;
|
||||
|
||||
struct Cursor {
|
||||
|
@ -20,15 +20,12 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <mint/cookie.h>
|
||||
#include <mint/falcon.h>
|
||||
#include <mint/osbind.h>
|
||||
|
||||
// We use some stdio.h functionality here thus we need to allow some
|
||||
// symbols. Alternatively, we could simply allow everything by defining
|
||||
// FORBIDDEN_SYMBOL_ALLOW_ALL
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_FILE
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_stdout
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_stderr
|
||||
@ -51,6 +48,7 @@
|
||||
#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-superblitter.h"
|
||||
#include "backends/graphics/atari/atari-graphics-supervidel.h"
|
||||
#include "backends/graphics/atari/atari-graphics-videl.h"
|
||||
#include "gui/debugger.h"
|
||||
@ -115,8 +113,6 @@ void OSystem_Atari::initBackend() {
|
||||
|
||||
_startTime = clock();
|
||||
|
||||
bool superVidel = VgetMonitor() == MON_VGA && Getcookie(C_SupV, NULL) == C_FOUND;
|
||||
|
||||
_timerManager = new DefaultTimerManager();
|
||||
_savefileManager = new DefaultSaveFileManager("saves");
|
||||
|
||||
@ -125,7 +121,7 @@ void OSystem_Atari::initBackend() {
|
||||
|
||||
// AtariGraphicsManager needs _eventManager ready
|
||||
AtariGraphicsManager *atariGraphicsManager;
|
||||
if (superVidel)
|
||||
if (hasSuperVidel())
|
||||
atariGraphicsManager = new AtariSuperVidelManager();
|
||||
else
|
||||
atariGraphicsManager = new AtariVidelManager();
|
||||
|
@ -24,8 +24,6 @@
|
||||
|
||||
#include "backends/modular-backend.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
class OSystem_Atari : public ModularMixerBackend, public ModularGraphicsBackend {
|
||||
public:
|
||||
OSystem_Atari();
|
||||
@ -51,7 +49,7 @@ public:
|
||||
void update();
|
||||
|
||||
private:
|
||||
clock_t _startTime;
|
||||
long _startTime;
|
||||
|
||||
bool _video_initialized = false;
|
||||
bool _ikbd_initialized = false;
|
||||
|
@ -254,9 +254,7 @@ means that if the SuperVidel is detected, it does the following:
|
||||
|
||||
- when SuperVidel FW version >= 9 is detected, the async FIFO buffer is used
|
||||
instead of the slower sync blitting (where one has to wait for every
|
||||
rectangle blit to finish). This applies only for chunky buffer -> screen
|
||||
surfaces copy (as the generic surface copy can't rely on this behavior) but
|
||||
despite this limitation it sometimes leads to nearly zero-cost rendering
|
||||
rectangle blit to finish), this sometimes leads to nearly zero-cost rendering
|
||||
and makes a *huge* difference for 640x480 fullscreen updates.
|
||||
|
||||
|
||||
@ -269,7 +267,7 @@ to avoid unpleasant playing experiences.
|
||||
Game engines with unexpected performance hit
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
A typical example from this category is the Gobliins engine (and its
|
||||
A typical example from this category is the Gobliiins engine (and its
|
||||
sequels). At first it looks like our machine / backend is doing something
|
||||
terribly wrong but the truth is it is the engine itself which is doing a lot of
|
||||
unnecessary redraws and updates, sometimes even before reaching the backend.
|
||||
@ -383,8 +381,7 @@ Future plans
|
||||
|
||||
- avoid loading music/speech files (and thus slowing down everything) if muted
|
||||
|
||||
- assembly copy routines for screen/chunky surfaces (even with SuperVidel
|
||||
present it is not possible to use the SuperBlitter for every surface)
|
||||
- assembly copy routines when SuperVidel is not present or can't be used
|
||||
|
||||
- cached audio/video streams (i.e. don't load only "output_samples" number of
|
||||
samples but cache, say, 1 second so disk i/o wont be so stressed)
|
||||
@ -408,6 +405,12 @@ Future plans
|
||||
|
||||
- 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
|
||||
|
||||
|
||||
Closing words
|
||||
—------------
|
||||
|
||||
|
1
configure
vendored
1
configure
vendored
@ -3967,6 +3967,7 @@ case $_backend in
|
||||
;;
|
||||
atari)
|
||||
define_in_config_if_yes yes "ATARI"
|
||||
define_in_config_if_yes yes "USE_SV_BLITTER"
|
||||
append_var DEFINES "-DDISABLE_LAUNCHERDISPLAY_GRID"
|
||||
#append_var DEFINES "-DDISABLE_FANCY_THEMES"
|
||||
#append_var DEFINES "-DDISABLE_SID"
|
||||
|
@ -27,15 +27,68 @@
|
||||
#include <mint/cookie.h>
|
||||
#include <mint/falcon.h>
|
||||
|
||||
#include <mint/trap14.h>
|
||||
#define ct60_vm(mode, value) (long)trap_14_wwl((short)0xc60e, (short)(mode), (long)(value))
|
||||
#define ct60_vmalloc(value) ct60_vm(0, value)
|
||||
#define ct60_vmfree(value) ct60_vm(1, value)
|
||||
|
||||
#include "backends/graphics/atari/atari-graphics-superblitter.h"
|
||||
#include "common/textconsole.h" // error
|
||||
|
||||
// bits 26:0
|
||||
#define SV_BLITTER_SRC1 ((volatile long*)0x80010058)
|
||||
#define SV_BLITTER_SRC2 ((volatile long*)0x8001005C)
|
||||
#define SV_BLITTER_DST ((volatile long*)0x80010060)
|
||||
// The amount of bytes that are to be copied in a horizontal line, minus 1
|
||||
#define SV_BLITTER_COUNT ((volatile long*)0x80010064)
|
||||
// The amount of bytes that are to be added to the line start adress after a line has been copied, in order to reach the next one
|
||||
#define SV_BLITTER_SRC1_OFFSET ((volatile long*)0x80010068)
|
||||
#define SV_BLITTER_SRC2_OFFSET ((volatile long*)0x8001006C)
|
||||
#define SV_BLITTER_DST_OFFSET ((volatile long*)0x80010070)
|
||||
// bits 11:0 - The amount of horizontal lines to do
|
||||
#define SV_BLITTER_MASK_AND_LINES ((volatile long*)0x80010074)
|
||||
// bit 0 - busy / start
|
||||
// bits 4:1 - blit mode
|
||||
#define SV_BLITTER_CONTROL ((volatile long*)0x80010078)
|
||||
// bit 0 - empty (read only)
|
||||
// bit 1 - full (read only)
|
||||
// bits 31:0 - data (write only)
|
||||
#define SV_BLITTER_FIFO ((volatile long*)0x80010080)
|
||||
|
||||
static bool isSuperBlitterLocked;
|
||||
|
||||
static void syncSuperBlitter() {
|
||||
// if externally locked, let the owner decide when to sync (unlock)
|
||||
if (isSuperBlitterLocked)
|
||||
return;
|
||||
|
||||
// while FIFO not empty...
|
||||
if (superVidelFwVersion >= 9)
|
||||
while (!(*SV_BLITTER_FIFO & 1));
|
||||
// while busy blitting...
|
||||
while (*SV_BLITTER_CONTROL & 1);
|
||||
}
|
||||
|
||||
static inline bool hasMove16() {
|
||||
long val;
|
||||
static bool hasMove16 = Getcookie(C__CPU, &val) == C_FOUND && val >= 40;
|
||||
return hasMove16;
|
||||
}
|
||||
|
||||
void lockSuperBlitter() {
|
||||
assert(!isSuperBlitterLocked);
|
||||
|
||||
isSuperBlitterLocked = true;
|
||||
}
|
||||
|
||||
void unlockSuperBlitter() {
|
||||
assert(isSuperBlitterLocked);
|
||||
|
||||
isSuperBlitterLocked = false;
|
||||
if (hasSuperVidel())
|
||||
syncSuperBlitter();
|
||||
}
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
constexpr size_t ALIGN = 16; // 16 bytes
|
||||
@ -53,7 +106,7 @@ void Surface::create(int16 width, int16 height, const PixelFormat &f) {
|
||||
pitch = (w * format.bytesPerPixel + ALIGN - 1) & (-ALIGN);
|
||||
|
||||
if (width && height) {
|
||||
if (VgetMonitor() == MON_VGA && Getcookie(C_SupV, NULL) == C_FOUND) {
|
||||
if (hasSuperVidel()) {
|
||||
pixels = (void *)ct60_vmalloc(height * pitch);
|
||||
|
||||
if (!pixels)
|
||||
@ -97,21 +150,32 @@ void copyBlit(byte *dst, const byte *src,
|
||||
return;
|
||||
|
||||
if (((uintptr)src & 0xFF000000) >= 0xA0000000 && ((uintptr)dst & 0xFF000000) >= 0xA0000000) {
|
||||
// while busy blitting...
|
||||
while (*SV_BLITTER_CONTROL & 1);
|
||||
if (superVidelFwVersion >= 9) {
|
||||
*SV_BLITTER_FIFO = (long)src; // SV_BLITTER_SRC1
|
||||
*SV_BLITTER_FIFO = 0x00000000; // SV_BLITTER_SRC2
|
||||
*SV_BLITTER_FIFO = (long)dst; // SV_BLITTER_DST
|
||||
*SV_BLITTER_FIFO = w * bytesPerPixel - 1; // SV_BLITTER_COUNT
|
||||
*SV_BLITTER_FIFO = srcPitch; // SV_BLITTER_SRC1_OFFSET
|
||||
*SV_BLITTER_FIFO = 0x00000000; // SV_BLITTER_SRC2_OFFSET
|
||||
*SV_BLITTER_FIFO = dstPitch; // SV_BLITTER_DST_OFFSET
|
||||
*SV_BLITTER_FIFO = h; // SV_BLITTER_MASK_AND_LINES
|
||||
*SV_BLITTER_FIFO = 0x01; // SV_BLITTER_CONTROL
|
||||
} else {
|
||||
// make sure the blitter is idle
|
||||
while (*SV_BLITTER_CONTROL & 1);
|
||||
|
||||
*SV_BLITTER_SRC1 = (long)src;
|
||||
*SV_BLITTER_SRC2 = 0x00000000;
|
||||
*SV_BLITTER_DST = (long)dst;
|
||||
*SV_BLITTER_COUNT = w * bytesPerPixel - 1;
|
||||
*SV_BLITTER_SRC1_OFFSET = srcPitch;
|
||||
*SV_BLITTER_SRC2_OFFSET = 0x00000000;
|
||||
*SV_BLITTER_DST_OFFSET = dstPitch;
|
||||
*SV_BLITTER_MASK_AND_LINES = h;
|
||||
*SV_BLITTER_CONTROL = 0x01;
|
||||
*SV_BLITTER_SRC1 = (long)src;
|
||||
*SV_BLITTER_SRC2 = 0x00000000;
|
||||
*SV_BLITTER_DST = (long)dst;
|
||||
*SV_BLITTER_COUNT = w * bytesPerPixel - 1;
|
||||
*SV_BLITTER_SRC1_OFFSET = srcPitch;
|
||||
*SV_BLITTER_SRC2_OFFSET = 0x00000000;
|
||||
*SV_BLITTER_DST_OFFSET = dstPitch;
|
||||
*SV_BLITTER_MASK_AND_LINES = h;
|
||||
*SV_BLITTER_CONTROL = 0x01;
|
||||
}
|
||||
|
||||
// wait until we finish otherwise we may overwrite pixels written manually afterwards
|
||||
while (*SV_BLITTER_CONTROL & 1);
|
||||
syncSuperBlitter();
|
||||
} else if (dstPitch == srcPitch && ((w * bytesPerPixel) == dstPitch)) {
|
||||
if (hasMove16() && ((uintptr)src & (ALIGN - 1)) == 0 && ((uintptr)dst & (ALIGN - 1)) == 0) {
|
||||
__asm__ volatile(
|
||||
|
@ -25,7 +25,7 @@
|
||||
namespace Graphics {
|
||||
|
||||
// see graphics/blit-atari.cpp, Atari Falcon's SuperVidel addon allows accelerated blitting
|
||||
#ifndef ATARI
|
||||
#ifndef USE_SV_BLITTER
|
||||
// Function to blit a rect
|
||||
void copyBlit(byte *dst, const byte *src,
|
||||
const uint dstPitch, const uint srcPitch,
|
||||
|
@ -63,7 +63,7 @@ MODULE_OBJS += \
|
||||
scaler/downscalerARM.o
|
||||
endif
|
||||
|
||||
ifdef ATARI
|
||||
ifdef USE_SV_BLITTER
|
||||
MODULE_OBJS += \
|
||||
blit-atari.o
|
||||
endif
|
||||
|
@ -64,7 +64,7 @@ void Surface::drawThickLine(int x0, int y0, int x1, int y1, int penX, int penY,
|
||||
}
|
||||
|
||||
// see graphics/blit-atari.cpp, Atari Falcon's SuperVidel addon allows accelerated blitting
|
||||
#ifndef ATARI
|
||||
#ifndef USE_SV_BLITTER
|
||||
void Surface::create(int16 width, int16 height, const PixelFormat &f) {
|
||||
assert(width >= 0 && height >= 0);
|
||||
free();
|
||||
|
Loading…
Reference in New Issue
Block a user