mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-02 23:26:44 +00:00
BACKENDS: ATARI: QoL improvements
- fixed aspect ratio correction (overlay destroyed its state, keyboard shortcut didn't always work), as well as significantly sped it up on VGA and SuperVidel - smoother transitions between video modes - reduce the number of video mode changes - fixed a few extreme cases when triple buffering could lose an update - lighter ST RAM usage in the lite build - removed hardware accessing init/deinit routines
This commit is contained in:
parent
0c77d67845
commit
dd49c9e3ce
@ -21,172 +21,11 @@
|
||||
|
||||
#include "../../platform/atari/symbols.h"
|
||||
|
||||
.global SYM(asm_screen_tt_save)
|
||||
.global SYM(asm_screen_falcon_save)
|
||||
|
||||
.global SYM(asm_screen_tt_restore)
|
||||
.global SYM(asm_screen_falcon_restore)
|
||||
|
||||
.global SYM(asm_draw_4bpl_sprite)
|
||||
.global SYM(asm_draw_8bpl_sprite)
|
||||
|
||||
.text
|
||||
|
||||
| extern void asm_screen_tt_save(void);
|
||||
|
|
||||
SYM(asm_screen_tt_save):
|
||||
bsr wait_vbl | avoid flickering
|
||||
|
||||
lea 0xffff8400.w,a0
|
||||
lea save_pal,a1
|
||||
moveq #256/2-1,d0
|
||||
|
||||
tt_save_loop:
|
||||
move.l (a0)+,(a1)+
|
||||
dbra d0,tt_save_loop
|
||||
|
||||
lea save_video,a1
|
||||
move.l 0xffff8200.w,(a1)+ | vidhm
|
||||
move.w 0xffff820c.w,(a1)+ | vidl
|
||||
move.w 0xffff8262.w,(a1)+ | tt shifter
|
||||
rts
|
||||
|
||||
| extern void asm_screen_falcon_save(void);
|
||||
|
|
||||
SYM(asm_screen_falcon_save):
|
||||
movem.l d2-d7/a2,-(sp)
|
||||
|
||||
bsr wait_vbl | avoid flickering
|
||||
|
||||
lea 0xffff9800.w,a0 | save falcon palette
|
||||
lea save_pal,a1 |
|
||||
moveq #256/2-1,d7 |
|
||||
|
|
||||
falcon_save_loop:
|
||||
move.l (a0)+,(a1)+ |
|
||||
move.l (a0)+,(a1)+ |
|
||||
dbra d7,falcon_save_loop |
|
||||
|
||||
movem.l 0xffff8240.w,d0-d7 | save st palette
|
||||
movem.l d0-d7,(a1) |
|
||||
|
||||
lea save_video,a0
|
||||
move.l 0xffff8200.w,(a0)+ | vidhm
|
||||
move.w 0xffff820c.w,(a0)+ | vidl
|
||||
|
||||
move.l 0xffff8282.w,(a0)+ | h-regs
|
||||
move.l 0xffff8286.w,(a0)+ |
|
||||
move.l 0xffff828a.w,(a0)+ |
|
||||
|
||||
move.l 0xffff82a2.w,(a0)+ | v-regs
|
||||
move.l 0xffff82a6.w,(a0)+ |
|
||||
move.l 0xffff82aa.w,(a0)+ |
|
||||
|
||||
move.w 0xffff82c0.w,(a0)+ | vco
|
||||
move.w 0xffff82c2.w,(a0)+ | c_s
|
||||
|
||||
move.l 0xffff820e.w,(a0)+ | offset+width
|
||||
move.w 0xffff820a.w,(a0)+ | sync
|
||||
|
||||
move.b 0xffff8265.w,(a0)+ | p_o
|
||||
|
||||
cmpi.w #0xb0,0xffff8282.w | st(e) / falcon test
|
||||
sle (a0)+ | it's a falcon resolution
|
||||
|
||||
move.w 0xffff8266.w,(a0)+ | f_s
|
||||
move.w 0xffff8260.w,(a0)+ | st_s
|
||||
|
||||
movem.l (sp)+,d2-d7/a2
|
||||
rts
|
||||
|
||||
| extern void asm_screen_tt_restore(void);
|
||||
|
|
||||
SYM(asm_screen_tt_restore):
|
||||
bsr wait_vbl | avoid flickering
|
||||
|
||||
lea save_video,a1
|
||||
move.l (a1)+,0xffff8200.w | vidhm
|
||||
move.w (a1)+,0xffff820c.w | vidl
|
||||
move.w (a1)+,0xffff8262.w | tt shifter
|
||||
|
||||
lea save_pal,a0
|
||||
lea 0xffff8400.w,a1
|
||||
moveq #256/2-1,d0
|
||||
|
||||
.loop: move.l (a0)+,(a1)+
|
||||
dbra d0,.loop
|
||||
rts
|
||||
|
||||
| extern void asm_screen_falcon_restore(void);
|
||||
|
|
||||
SYM(asm_screen_falcon_restore):
|
||||
movem.l d2-d7/a2,-(sp)
|
||||
|
||||
bsr wait_vbl | avoid flickering
|
||||
|
||||
lea save_video,a0
|
||||
|
||||
move.l (a0)+,0xffff8200.w | videobase_address:h&m
|
||||
move.w (a0)+,0xffff820c.w | l
|
||||
|
||||
move.l (a0)+,0xffff8282.w | h-regs
|
||||
move.l (a0)+,0xffff8286.w |
|
||||
move.l (a0)+,0xffff828a.w |
|
||||
|
||||
move.l (a0)+,0xffff82a2.w | v-regs
|
||||
move.l (a0)+,0xffff82a6.w |
|
||||
move.l (a0)+,0xffff82aa.w |
|
||||
|
||||
move.w (a0)+,0xffff82c0.w | vco
|
||||
move.w (a0)+,0xffff82c2.w | c_s
|
||||
|
||||
move.l (a0)+,0xffff820e.w | offset+width
|
||||
move.w (a0)+,0xffff820a.w | sync
|
||||
|
||||
move.b (a0)+,0xffff8265.w | p_o
|
||||
|
||||
tst.b (a0)+ | st(e) compatible mode?
|
||||
bne falcon_restore_st_comp | yes
|
||||
|
||||
falcon_restore_falcon:
|
||||
move.l a0,-(sp)
|
||||
bsr wait_vbl | Patch to avoid
|
||||
clr.w 0xffff8266.w | monochrome sync errors
|
||||
bsr wait_vbl | (ripped from
|
||||
move.l (sp)+,a0 | FreeMiNT kernel,
|
||||
move.w (a0),0xffff8266.w | by Draco/Yescrew)
|
||||
|
||||
bra falcon_restore_restored
|
||||
|
||||
falcon_restore_st_comp:
|
||||
move.w (a0)+,0xffff8266.w | falcon-shift
|
||||
move.w (a0),0xffff8260.w | st-shift
|
||||
lea save_video,a0
|
||||
move.w 32(a0),0xffff82c2.w | c_s
|
||||
move.l 34(a0),0xffff820e.w | offset+width
|
||||
|
||||
falcon_restore_restored:
|
||||
lea save_pal,a0 | restore falcon palette
|
||||
lea 0xffff9800.w,a1 |
|
||||
moveq #128-1,d7 |
|
||||
|
|
||||
falcon_restore_loop:
|
||||
move.l (a0)+,(a1)+ |
|
||||
move.l (a0)+,(a1)+ |
|
||||
dbra d7,falcon_restore_loop |
|
||||
|
||||
movem.l (a0),d0-d7 | restore st palette
|
||||
movem.l d0-d7,0xffff8240.w |
|
||||
|
||||
movem.l (sp)+,d2-d7/a2
|
||||
rts
|
||||
|
||||
wait_vbl:
|
||||
move.w #0x25,-(sp) | Vsync()
|
||||
trap #14 |
|
||||
addq.l #2,sp |
|
||||
rts
|
||||
|
||||
| extern void asm_draw_4bpl_sprite(uint16 *dstBuffer, const uint16 *srcBuffer, const uint16 *srcMask,
|
||||
| uint destX, uint destY, uint dstPitch, uint w, uint h);
|
||||
|
|
||||
@ -206,7 +45,7 @@ SYM(asm_draw_4bpl_sprite):
|
||||
|
||||
| Draws a 4 bitplane sprite at any position on screen.
|
||||
| (c) 1999 Pieter van der Meer (EarX)
|
||||
|
||||
|
|
||||
| INPUT: d0.w: x position of sprite on screen (left side)
|
||||
| d1.w: y position of sprite on screen (top side)
|
||||
| d6.w: number of 16pixel X blocks to do
|
||||
|
@ -26,24 +26,6 @@
|
||||
|
||||
extern "C" {
|
||||
|
||||
/**
|
||||
* Save Atari TT video registers.
|
||||
*/
|
||||
void asm_screen_tt_save(void);
|
||||
/**
|
||||
* Save Atari Falcon video registers.
|
||||
*/
|
||||
void asm_screen_falcon_save(void);
|
||||
|
||||
/**
|
||||
* Restore Atari TT video registers.
|
||||
*/
|
||||
void asm_screen_tt_restore(void);
|
||||
/**
|
||||
* Restore Atari Falcon video registers.
|
||||
*/
|
||||
void asm_screen_falcon_restore(void);
|
||||
|
||||
/**
|
||||
* Copy 4bpl sprite into 4bpl buffer. Sprite's width must be multiply of 16.
|
||||
*
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "atari-graphics.h"
|
||||
|
||||
#include <mint/cookie.h>
|
||||
#include <mint/falcon.h>
|
||||
#include <mint/osbind.h>
|
||||
#include <mint/sysvars.h>
|
||||
|
||||
@ -49,18 +50,49 @@ static const Graphics::PixelFormat PIXELFORMAT_CLUT8 = Graphics::PixelFormat::cr
|
||||
static const Graphics::PixelFormat PIXELFORMAT_RGB332 = Graphics::PixelFormat(1, 3, 3, 2, 0, 5, 2, 0, 0);
|
||||
static const Graphics::PixelFormat PIXELFORMAT_RGB121 = Graphics::PixelFormat(1, 1, 2, 1, 0, 3, 1, 0, 0);
|
||||
|
||||
static bool s_shrinkVidelVisibleArea;
|
||||
|
||||
static void shrinkVidelVisibleArea() {
|
||||
// Active VGA screen area consists of 960 half-lines, i.e. 480 raster lines.
|
||||
// In case of 320x240, the number is still 480 but data is fetched
|
||||
// only for 240 lines so it doesn't make a difference to us.
|
||||
|
||||
if (hasSuperVidel()) {
|
||||
const int vOffset = ((480 - 400) / 2) * 2; // *2 because of half-lines
|
||||
|
||||
// VDB = VBE = VDB + paddding/2
|
||||
*((volatile uint16*)0xFFFF82A8) = *((volatile uint16*)0xFFFF82A6) = *((volatile uint16*)0xFFFF82A8) + vOffset;
|
||||
// VDE = VBB = VDE - padding/2
|
||||
*((volatile uint16*)0xFFFF82AA) = *((volatile uint16*)0xFFFF82A4) = *((volatile uint16*)0xFFFF82AA) - vOffset;
|
||||
} else {
|
||||
// 31500/60.1 = 524 raster lines
|
||||
// vft = 524 * 2 + 1 = 1049 half-lines
|
||||
// 480 visible lines = 960 half-lines
|
||||
// 1049 - 960 = 89 half-lines reserved for borders
|
||||
// we want 400 visible lines = 800 half-lines
|
||||
// vft = 800 + 89 = 889 half-lines in total ~ 70.1 Hz vertical frequency
|
||||
int16 vft = *((volatile int16*)0xFFFF82A2);
|
||||
int16 vss = *((volatile int16*)0xFFFF82AC); // vss = vft - vss_sync
|
||||
vss -= vft; // -vss_sync
|
||||
*((volatile int16*)0xFFFF82A2) = 889;
|
||||
*((volatile int16*)0xFFFF82AC) = 889 + vss;
|
||||
}
|
||||
}
|
||||
|
||||
static bool s_tt;
|
||||
static int s_shakeXOffset;
|
||||
static int s_shakeYOffset;
|
||||
|
||||
static int s_aspectRatioCorrectionYOffset;
|
||||
static Graphics::Surface *s_screenSurf;
|
||||
|
||||
static void VblHandler() {
|
||||
if (s_screenSurf) {
|
||||
#ifdef SCREEN_ACTIVE
|
||||
const int bitsPerPixel = (s_screenSurf->format == PIXELFORMAT_RGB121 ? 4 : 8);
|
||||
uintptr p = (uintptr)s_screenSurf->getBasePtr(0, MAX_V_SHAKE + s_shakeYOffset);
|
||||
uintptr p = (uintptr)s_screenSurf->getBasePtr(0, MAX_V_SHAKE + s_shakeYOffset + s_aspectRatioCorrectionYOffset);
|
||||
|
||||
if (!s_tt) {
|
||||
const int bitsPerPixel = (s_screenSurf->format == PIXELFORMAT_RGB121 ? 4 : 8);
|
||||
|
||||
s_shakeXOffset = -s_shakeXOffset;
|
||||
|
||||
if (s_shakeXOffset >= 0) {
|
||||
@ -85,6 +117,11 @@ static void VblHandler() {
|
||||
#endif
|
||||
s_screenSurf = nullptr;
|
||||
}
|
||||
|
||||
if (s_shrinkVidelVisibleArea) {
|
||||
shrinkVidelVisibleArea();
|
||||
s_shrinkVidelVisibleArea = false;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32 InstallVblHandler() {
|
||||
@ -119,50 +156,36 @@ static uint32 UninstallVblHandler() {
|
||||
return uninstalled;
|
||||
}
|
||||
|
||||
static void shrinkVidelVisibleArea() {
|
||||
// Active VGA screen area consists of 960 half-lines, i.e. 480 raster lines.
|
||||
// In case of 320x240, the number is still 480 but data is fetched
|
||||
// only for 240 lines so it doesn't make a difference to us.
|
||||
Vsync();
|
||||
|
||||
if (hasSuperVidel()) {
|
||||
const int vOffset = ((480 - 400) / 2) * 2; // *2 because of half-lines
|
||||
|
||||
// VDB = VBE = VDB + paddding/2
|
||||
*((volatile uint16*)0xFFFF82A8) = *((volatile uint16*)0xFFFF82A6) = *((volatile uint16*)0xFFFF82A8) + vOffset;
|
||||
// VDE = VBB = VDE - padding/2
|
||||
*((volatile uint16*)0xFFFF82AA) = *((volatile uint16*)0xFFFF82A4) = *((volatile uint16*)0xFFFF82AA) - vOffset;
|
||||
} else {
|
||||
// 31500/60.1 = 524 raster lines
|
||||
// vft = 524 * 2 + 1 = 1049 half-lines
|
||||
// 480 visible lines = 960 half-lines
|
||||
// 1049 - 960 = 89 half-lines reserved for borders
|
||||
// we want 400 visible lines = 800 half-lines
|
||||
// vft = 800 + 89 = 889 half-lines in total ~ 70.1 Hz vertical frequency
|
||||
int16 vft = *((volatile int16*)0xFFFF82A2);
|
||||
int16 vss = *((volatile int16*)0xFFFF82AC); // vss = vft - vss_sync
|
||||
vss -= vft; // -vss_sync
|
||||
*((volatile int16*)0xFFFF82A2) = 889;
|
||||
*((volatile int16*)0xFFFF82AC) = 889 + vss;
|
||||
}
|
||||
}
|
||||
|
||||
static int s_oldRez = -1;
|
||||
static int s_oldMode = -1;
|
||||
static void *s_oldPhysbase = nullptr;
|
||||
static Palette s_oldPalette;
|
||||
|
||||
void AtariGraphicsShutdown() {
|
||||
Supexec(UninstallVblHandler);
|
||||
|
||||
if (s_oldRez != -1) {
|
||||
Setscreen(SCR_NOCHANGE, s_oldPhysbase, s_oldRez);
|
||||
|
||||
EsetPalette(0, s_oldPalette.entries, s_oldPalette.tt);
|
||||
} else if (s_oldMode != -1) {
|
||||
// prevent setting video base address just on the VDB line
|
||||
Vsync();
|
||||
if (hasSuperVidel())
|
||||
VsetMode(SVEXT | SVEXT_BASERES(0) | COL80 | BPS8C); // resync to proper 640x480
|
||||
VsetMode(s_oldMode);
|
||||
static _RGB black[256];
|
||||
VsetRGB(0, 256, black);
|
||||
|
||||
VsetScreen(SCR_NOCHANGE, s_oldPhysbase, SCR_NOCHANGE, SCR_NOCHANGE);
|
||||
|
||||
if (hasSuperVidel()) {
|
||||
// SuperVidel XBIOS does not restore those (unlike TOS/EmuTOS)
|
||||
long ssp = Super(SUP_SET);
|
||||
//*((volatile char *)0xFFFF8265) = 0;
|
||||
*((volatile short *)0xFFFF820E) = 0;
|
||||
Super(ssp);
|
||||
|
||||
VsetMode(SVEXT | SVEXT_BASERES(0) | COL80 | BPS8C); // resync to proper 640x480
|
||||
}
|
||||
VsetMode(s_oldMode);
|
||||
|
||||
VsetRGB(0, s_oldPalette.entries, s_oldPalette.falcon);
|
||||
}
|
||||
}
|
||||
|
||||
@ -226,12 +249,31 @@ AtariGraphicsManager::AtariGraphicsManager() {
|
||||
}
|
||||
}
|
||||
|
||||
// although we store/restore video hardware in OSystem_Atari,
|
||||
// make sure that internal OS structures are updated correctly, too
|
||||
if (_tt) {
|
||||
s_oldRez = Getrez();
|
||||
// EgetPalette / EsetPalette doesn't care about current resolution's number of colors
|
||||
s_oldPalette.entries = 256;
|
||||
EgetPalette(0, 256, s_oldPalette.tt);
|
||||
} else {
|
||||
s_oldMode = VsetMode(VM_INQUIRE);
|
||||
switch (s_oldMode & NUMCOLS) {
|
||||
case BPS1:
|
||||
s_oldPalette.entries = 2;
|
||||
break;
|
||||
case BPS2:
|
||||
s_oldPalette.entries = 4;
|
||||
break;
|
||||
case BPS4:
|
||||
s_oldPalette.entries = 16;
|
||||
break;
|
||||
case BPS8:
|
||||
case BPS8C:
|
||||
s_oldPalette.entries = 256;
|
||||
break;
|
||||
default:
|
||||
s_oldPalette.entries = 0;
|
||||
}
|
||||
VgetRGB(0, s_oldPalette.entries, s_oldPalette.falcon);
|
||||
}
|
||||
s_oldPhysbase = Physbase();
|
||||
|
||||
@ -253,7 +295,7 @@ AtariGraphicsManager::~AtariGraphicsManager() {
|
||||
bool AtariGraphicsManager::hasFeature(OSystem::Feature f) const {
|
||||
switch (f) {
|
||||
case OSystem::Feature::kFeatureAspectRatioCorrection:
|
||||
//debug("hasFeature(kFeatureAspectRatioCorrection): %d", !_vgaMonitor);
|
||||
//debug("hasFeature(kFeatureAspectRatioCorrection): %d", !_tt);
|
||||
return !_tt;
|
||||
case OSystem::Feature::kFeatureCursorPalette:
|
||||
// FIXME: pretend to have cursor palette at all times, this function
|
||||
@ -266,14 +308,21 @@ bool AtariGraphicsManager::hasFeature(OSystem::Feature f) const {
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: kFeatureDisplayLogFile?, kFeatureClipboardSupport, kFeatureSystemBrowserDialog
|
||||
}
|
||||
|
||||
void AtariGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) {
|
||||
if (!hasFeature(f))
|
||||
return;
|
||||
|
||||
switch (f) {
|
||||
case OSystem::Feature::kFeatureAspectRatioCorrection:
|
||||
//debug("setFeatureState(kFeatureAspectRatioCorrection): %d", enable);
|
||||
_oldAspectRatioCorrection = _aspectRatioCorrection;
|
||||
_aspectRatioCorrection = enable;
|
||||
_pendingState.aspectRatioCorrection = enable;
|
||||
|
||||
if (_currentState.aspectRatioCorrection != _pendingState.aspectRatioCorrection)
|
||||
_pendingState.change |= GraphicsState::kAspectRatioCorrection;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -284,7 +333,7 @@ bool AtariGraphicsManager::getFeatureState(OSystem::Feature f) const {
|
||||
switch (f) {
|
||||
case OSystem::Feature::kFeatureAspectRatioCorrection:
|
||||
//debug("getFeatureState(kFeatureAspectRatioCorrection): %d", _aspectRatioCorrection);
|
||||
return _aspectRatioCorrection;
|
||||
return _currentState.aspectRatioCorrection;
|
||||
case OSystem::Feature::kFeatureCursorPalette:
|
||||
//debug("getFeatureState(kFeatureCursorPalette): %d", isOverlayVisible());
|
||||
//return isOverlayVisible();
|
||||
@ -297,14 +346,13 @@ bool AtariGraphicsManager::getFeatureState(OSystem::Feature f) const {
|
||||
bool AtariGraphicsManager::setGraphicsMode(int mode, uint flags) {
|
||||
debug("setGraphicsMode: %d, %d", mode, flags);
|
||||
|
||||
GraphicsMode graphicsMode = (GraphicsMode)mode;
|
||||
_pendingState.mode = (GraphicsMode)mode;
|
||||
|
||||
if (graphicsMode >= GraphicsMode::DirectRendering && graphicsMode <= GraphicsMode::TripleBuffering) {
|
||||
_pendingState.mode = graphicsMode;
|
||||
return true;
|
||||
}
|
||||
if (_currentState.mode != _pendingState.mode)
|
||||
_pendingState.change |= GraphicsState::kScreenAddress;
|
||||
|
||||
return false;
|
||||
// this doesn't seem to be checked anywhere
|
||||
return true;
|
||||
}
|
||||
|
||||
void AtariGraphicsManager::initSize(uint width, uint height, const Graphics::PixelFormat *format) {
|
||||
@ -313,10 +361,20 @@ void AtariGraphicsManager::initSize(uint width, uint height, const Graphics::Pix
|
||||
_pendingState.width = width;
|
||||
_pendingState.height = height;
|
||||
_pendingState.format = format ? *format : PIXELFORMAT_CLUT8;
|
||||
|
||||
if ((_pendingState.width > 0 && _pendingState.height > 0)
|
||||
&& (_currentState.width != _pendingState.width || _currentState.height != _pendingState.height)) {
|
||||
_pendingState.change |= GraphicsState::kVideoMode;
|
||||
}
|
||||
}
|
||||
|
||||
void AtariGraphicsManager::beginGFXTransaction() {
|
||||
debug("beginGFXTransaction");
|
||||
|
||||
// these serve as a flag whether we are launching a game; if not, they will be always zeroed
|
||||
_pendingState.width = 0;
|
||||
_pendingState.height = 0;
|
||||
_pendingState.change &= ~GraphicsState::kVideoMode;
|
||||
}
|
||||
|
||||
OSystem::TransactionError AtariGraphicsManager::endGFXTransaction() {
|
||||
@ -324,24 +382,42 @@ OSystem::TransactionError AtariGraphicsManager::endGFXTransaction() {
|
||||
|
||||
int error = OSystem::TransactionError::kTransactionSuccess;
|
||||
|
||||
if (_pendingState.mode < GraphicsMode::DirectRendering || _pendingState.mode > GraphicsMode::TripleBuffering)
|
||||
error |= OSystem::TransactionError::kTransactionModeSwitchFailed;
|
||||
|
||||
if (_pendingState.format != PIXELFORMAT_CLUT8)
|
||||
error |= OSystem::TransactionError::kTransactionFormatNotSupported;
|
||||
|
||||
if (_pendingState.width > getMaximumScreenWidth() || _pendingState.height > getMaximumScreenHeight())
|
||||
error |= OSystem::TransactionError::kTransactionSizeChangeFailed;
|
||||
if (_pendingState.width > 0 && _pendingState.height > 0) {
|
||||
if (_pendingState.width > getMaximumScreenWidth() || _pendingState.height > getMaximumScreenHeight())
|
||||
error |= OSystem::TransactionError::kTransactionSizeChangeFailed;
|
||||
|
||||
if (_pendingState.width % 16 != 0 && !hasSuperVidel()) {
|
||||
warning("Requested width not divisible by 16, please report");
|
||||
error |= OSystem::TransactionError::kTransactionSizeChangeFailed;
|
||||
if (_pendingState.width % 16 != 0 && !hasSuperVidel()) {
|
||||
warning("Requested width not divisible by 16, please report");
|
||||
error |= OSystem::TransactionError::kTransactionSizeChangeFailed;
|
||||
}
|
||||
}
|
||||
|
||||
if (error != OSystem::TransactionError::kTransactionSuccess) {
|
||||
warning("endGFXTransaction failed: %02x", (int)error);
|
||||
// all our errors are fatal but engine.cpp takes only this one seriously
|
||||
// all our errors are fatal as we don't support rollback so make sure that
|
||||
// initGraphicsAny() fails (note: setupGraphics() doesn't check errors at all)
|
||||
error |= OSystem::TransactionError::kTransactionSizeChangeFailed;
|
||||
return static_cast<OSystem::TransactionError>(error);
|
||||
}
|
||||
|
||||
// don't exit overlay unless there is real video mode to be set
|
||||
if (_pendingState.width == 0 || _pendingState.height == 0) {
|
||||
_ignoreHideOverlay = true;
|
||||
return OSystem::kTransactionSuccess;
|
||||
} else if (_overlayVisible) {
|
||||
// that's it, really. updateScreen() will take care of everything.
|
||||
_ignoreHideOverlay = false;
|
||||
_overlayVisible = false;
|
||||
// if being in the overlay, reset everything (same as hideOverlay() does)
|
||||
_pendingState.change |= GraphicsState::kAll;
|
||||
}
|
||||
|
||||
_chunkySurface.init(_pendingState.width, _pendingState.height, _pendingState.width,
|
||||
_chunkySurface.getPixels(), _pendingState.format);
|
||||
|
||||
@ -350,18 +426,16 @@ OSystem::TransactionError AtariGraphicsManager::endGFXTransaction() {
|
||||
_screen[BACK_BUFFER2]->reset(_pendingState.width, _pendingState.height, 8, true);
|
||||
_workScreen = _screen[_pendingState.mode <= GraphicsMode::SingleBuffering ? FRONT_BUFFER : BACK_BUFFER1];
|
||||
|
||||
s_screenSurf = nullptr;
|
||||
s_shakeXOffset = 0;
|
||||
s_shakeYOffset = 0;
|
||||
|
||||
// in case of resolution change from GUI
|
||||
if (_oldWorkScreen)
|
||||
_oldWorkScreen = _workScreen;
|
||||
|
||||
_palette.clear();
|
||||
_pendingScreenChange = kPendingScreenChangeMode | kPendingScreenChangeScreen | kPendingScreenChangePalette;
|
||||
_pendingState.change |= GraphicsState::kPalette;
|
||||
|
||||
// no point of setting this in updateScreen(), it would only complicate code
|
||||
_currentState = _pendingState;
|
||||
// currently there is no use for this
|
||||
_currentState.change = GraphicsState::kNone;
|
||||
|
||||
// apply new screen changes
|
||||
updateScreen();
|
||||
|
||||
return OSystem::kTransactionSuccess;
|
||||
}
|
||||
@ -387,7 +461,7 @@ void AtariGraphicsManager::setPalette(const byte *colors, uint start, uint num)
|
||||
}
|
||||
}
|
||||
|
||||
_pendingScreenChange |= kPendingScreenChangePalette;
|
||||
_pendingState.change |= GraphicsState::kPalette;
|
||||
}
|
||||
|
||||
void AtariGraphicsManager::grabPalette(byte *colors, uint start, uint num) const {
|
||||
@ -464,6 +538,8 @@ void AtariGraphicsManager::fillScreen(uint32 col) {
|
||||
}
|
||||
|
||||
void AtariGraphicsManager::fillScreen(const Common::Rect &r, uint32 col) {
|
||||
debug("fillScreen: %dx%d %d", r.width(), r.height(), col);
|
||||
|
||||
Graphics::Surface *screen = lockScreen();
|
||||
if (screen)
|
||||
screen->fillRect(r, col);
|
||||
@ -528,26 +604,20 @@ void AtariGraphicsManager::updateScreen() {
|
||||
assert(_workScreen == _screen[BACK_BUFFER1]);
|
||||
screenUpdated = updateScreenInternal(_chunkySurface);
|
||||
break;
|
||||
default:
|
||||
warning("Unknown graphics mode %d", (int)_currentState.mode);
|
||||
}
|
||||
}
|
||||
|
||||
_workScreen->clearDirtyRects();
|
||||
|
||||
#ifdef SCREEN_ACTIVE
|
||||
// first change video mode so we can modify video regs later
|
||||
if (_pendingScreenChange & kPendingScreenChangeMode) {
|
||||
if (_workScreen->rez != -1) {
|
||||
// unfortunately this reinitializes VDI, too
|
||||
Setscreen(SCR_NOCHANGE, SCR_NOCHANGE, _workScreen->rez);
|
||||
} else if (_workScreen->mode != -1) {
|
||||
VsetMode(_workScreen->mode);
|
||||
}
|
||||
if (!_overlayPending && (_pendingState.width == 0 || _pendingState.height == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_pendingScreenChange & kPendingScreenChangeScreen) {
|
||||
// calling (V)SetScreen without Vsync() is dangerous (at least on Falcon)
|
||||
s_screenSurf = isOverlayVisible() ? &_screen[OVERLAY_BUFFER]->surf : &_screen[FRONT_BUFFER]->surf;
|
||||
} else if (screenUpdated && !isOverlayVisible() && _currentState.mode == GraphicsMode::TripleBuffering) {
|
||||
if (screenUpdated
|
||||
&& !isOverlayVisible()
|
||||
&& _currentState.mode == GraphicsMode::TripleBuffering) {
|
||||
// Triple buffer:
|
||||
// - alternate BACK_BUFFER1 and BACK_BUFFER2
|
||||
// - check if FRONT_BUFFER has been displayed for at least one frame
|
||||
@ -585,111 +655,125 @@ void AtariGraphicsManager::updateScreen() {
|
||||
// FRONT_BUFFER is displayed and still contains previously finished frame
|
||||
}
|
||||
|
||||
if (_pendingScreenChange & kPendingScreenChangePalette) {
|
||||
if (_tt)
|
||||
EsetPalette(0, isOverlayVisible() ? getOverlayPaletteSize() : 256, _workScreen->palette->tt);
|
||||
else
|
||||
VsetRGB(0, isOverlayVisible() ? getOverlayPaletteSize() : 256, _workScreen->palette->falcon);
|
||||
const GraphicsState oldPendingState = _pendingState;
|
||||
if (_overlayPending) {
|
||||
debug("Forcing overlay pending state");
|
||||
_pendingState.change = GraphicsState::kAll;
|
||||
}
|
||||
|
||||
_pendingScreenChange = kPendingScreenChangeNone;
|
||||
bool doShrinkVidelVisibleArea = false;
|
||||
bool doSuperVidelReset = false;
|
||||
if (_pendingState.change & GraphicsState::kAspectRatioCorrection) {
|
||||
assert(_workScreen->mode != -1);
|
||||
|
||||
if (_oldAspectRatioCorrection != _aspectRatioCorrection) {
|
||||
if (!isOverlayVisible() && _currentState.height == 200) {
|
||||
if (_pendingState.aspectRatioCorrection && _currentState.height == 200 && !isOverlayVisible()) {
|
||||
// apply machine-specific aspect ratio correction
|
||||
if (!_vgaMonitor) {
|
||||
short mode = VsetMode(VM_INQUIRE);
|
||||
if (_aspectRatioCorrection) {
|
||||
// 60 Hz
|
||||
mode &= ~PAL;
|
||||
mode |= NTSC;
|
||||
} else {
|
||||
// 50 Hz
|
||||
mode &= ~NTSC;
|
||||
mode |= PAL;
|
||||
}
|
||||
VsetMode(mode);
|
||||
} else if (hasSuperVidel() || !_tt) {
|
||||
if (_aspectRatioCorrection) {
|
||||
for (int screenId : { FRONT_BUFFER, BACK_BUFFER1, BACK_BUFFER2 }) {
|
||||
Screen *screen = _screen[screenId];
|
||||
Graphics::Surface *offsettedSurf = screen->offsettedSurf;
|
||||
|
||||
// erase old screen
|
||||
offsettedSurf->fillRect(Common::Rect(offsettedSurf->w, offsettedSurf->h), 0);
|
||||
|
||||
// setup new screen
|
||||
screen->oldScreenSurfaceWidth = screen->surf.w;
|
||||
screen->oldScreenSurfaceHeight = screen->surf.h;
|
||||
screen->oldScreenSurfacePitch = screen->surf.pitch;
|
||||
screen->oldOffsettedSurfaceWidth = offsettedSurf->w;
|
||||
screen->oldOffsettedSurfaceHeight = offsettedSurf->h;
|
||||
|
||||
screen->surf.w = 320 + 2 * MAX_HZ_SHAKE;
|
||||
screen->surf.h = 200 + 2 * MAX_V_SHAKE;
|
||||
screen->surf.pitch = screen->surf.w;
|
||||
|
||||
offsettedSurf->init(
|
||||
320, 200, screen->surf.pitch,
|
||||
screen->surf.getBasePtr((screen->surf.w - 320) / 2, (screen->surf.h - 200) / 2),
|
||||
screen->surf.format);
|
||||
|
||||
screen->addDirtyRect(*lockScreen(), Common::Rect(offsettedSurf->w, offsettedSurf->h), _currentState.mode == GraphicsMode::DirectRendering);
|
||||
}
|
||||
|
||||
Supexec(shrinkVidelVisibleArea);
|
||||
} else {
|
||||
for (int screenId : { FRONT_BUFFER, BACK_BUFFER1, BACK_BUFFER2 }) {
|
||||
Screen *screen = _screen[screenId];
|
||||
Graphics::Surface *offsettedSurf = screen->offsettedSurf;
|
||||
|
||||
assert(screen->oldScreenSurfaceWidth != -1);
|
||||
assert(screen->oldScreenSurfaceHeight != -1);
|
||||
assert(screen->oldScreenSurfacePitch != -1);
|
||||
assert(screen->oldOffsettedSurfaceWidth != -1);
|
||||
assert(screen->oldOffsettedSurfaceHeight != -1);
|
||||
|
||||
// erase old screen
|
||||
offsettedSurf->fillRect(Common::Rect(offsettedSurf->w, offsettedSurf->h), 0);
|
||||
|
||||
// setup new screen
|
||||
screen->surf.w = screen->oldScreenSurfaceWidth;
|
||||
screen->surf.h = screen->oldScreenSurfaceHeight;
|
||||
screen->surf.pitch = screen->oldScreenSurfacePitch;
|
||||
|
||||
offsettedSurf->init(
|
||||
screen->oldOffsettedSurfaceWidth, screen->oldOffsettedSurfaceHeight, screen->surf.pitch,
|
||||
screen->surf.getBasePtr(
|
||||
(screen->surf.w - screen->oldOffsettedSurfaceWidth) / 2,
|
||||
(screen->surf.h - screen->oldOffsettedSurfaceHeight) / 2),
|
||||
screen->surf.format);
|
||||
|
||||
screen->oldScreenSurfaceWidth = -1;
|
||||
screen->oldScreenSurfaceHeight = -1;
|
||||
screen->oldScreenSurfacePitch = -1;
|
||||
screen->oldOffsettedSurfaceWidth = -1;
|
||||
screen->oldOffsettedSurfaceHeight = -1;
|
||||
|
||||
screen->addDirtyRect(*lockScreen(), Common::Rect(offsettedSurf->w, offsettedSurf->h), _currentState.mode == GraphicsMode::DirectRendering);
|
||||
}
|
||||
|
||||
if (hasSuperVidel())
|
||||
VsetMode(SVEXT | SVEXT_BASERES(0) | COL80 | BPS8C); // resync to proper 640x480
|
||||
VsetMode(_workScreen->mode);
|
||||
}
|
||||
_workScreen->mode &= ~PAL;
|
||||
// 60 Hz
|
||||
_workScreen->mode |= NTSC;
|
||||
_pendingState.change |= GraphicsState::kVideoMode;
|
||||
} else {
|
||||
// TODO: some tricks with TT's 480 lines?
|
||||
Screen *screen = _screen[FRONT_BUFFER];
|
||||
s_aspectRatioCorrectionYOffset = (screen->surf.h - 2*MAX_V_SHAKE - screen->offsettedSurf->h) / 2;
|
||||
_pendingState.change |= GraphicsState::kShakeScreen;
|
||||
|
||||
if (_pendingState.change & GraphicsState::kVideoMode)
|
||||
doShrinkVidelVisibleArea = true;
|
||||
else
|
||||
s_shrinkVidelVisibleArea = true;
|
||||
}
|
||||
} else {
|
||||
// reset back to default mode
|
||||
if (!_vgaMonitor) {
|
||||
_workScreen->mode &= ~NTSC;
|
||||
// 50 Hz
|
||||
_workScreen->mode |= PAL;
|
||||
_pendingState.change |= GraphicsState::kVideoMode;
|
||||
} else {
|
||||
s_aspectRatioCorrectionYOffset = 0;
|
||||
s_shrinkVidelVisibleArea = false;
|
||||
|
||||
if (hasSuperVidel())
|
||||
doSuperVidelReset = true;
|
||||
_pendingState.change |= GraphicsState::kVideoMode;
|
||||
}
|
||||
}
|
||||
|
||||
_pendingState.change &= ~GraphicsState::kAspectRatioCorrection;
|
||||
}
|
||||
|
||||
#ifdef SCREEN_ACTIVE
|
||||
if (_pendingState.change & GraphicsState::kVideoMode) {
|
||||
if (_workScreen->rez != -1) {
|
||||
// unfortunately this reinitializes VDI, too
|
||||
Setscreen(SCR_NOCHANGE, SCR_NOCHANGE, _workScreen->rez);
|
||||
|
||||
// strictly speaking, this is necessary only if kScreenAddress is set but makes code easier
|
||||
static uint16 black[256];
|
||||
// Vsync(); // done by Setscreen() above
|
||||
EsetPalette(0, isOverlayVisible() ? 16 : 256, black);
|
||||
} else if (_workScreen->mode != -1) {
|
||||
// VsetMode() must be called first: it resets all hz/v, scrolling and line width registers
|
||||
// so even if kScreenAddress wasn't scheduled, we have to set new s_screenSurf to refresh them
|
||||
static _RGB black[256];
|
||||
VsetRGB(0, 256, black);
|
||||
// Vsync(); // done by (either) VsetMode() below
|
||||
|
||||
if (doSuperVidelReset) {
|
||||
VsetMode(SVEXT | SVEXT_BASERES(0) | COL80 | BPS8C); // resync to proper 640x480
|
||||
doSuperVidelReset = false;
|
||||
}
|
||||
|
||||
_oldAspectRatioCorrection = _aspectRatioCorrection;
|
||||
|
||||
_pendingScreenChange |= kPendingScreenChangeScreen;
|
||||
updateScreen();
|
||||
} else {
|
||||
// ignore new value in overlay
|
||||
_aspectRatioCorrection = _oldAspectRatioCorrection;
|
||||
debug("VsetMode: %04x", _workScreen->mode);
|
||||
VsetMode(_workScreen->mode);
|
||||
}
|
||||
|
||||
// due to implied Vsync() above
|
||||
assert(s_screenSurf == nullptr);
|
||||
|
||||
// refresh Videl register settings
|
||||
s_screenSurf = isOverlayVisible() ? &_screen[OVERLAY_BUFFER]->surf : &_screen[FRONT_BUFFER]->surf;
|
||||
s_shrinkVidelVisibleArea = doShrinkVidelVisibleArea;
|
||||
|
||||
// keep kVideoMode for resetting the palette later
|
||||
_pendingState.change &= ~(GraphicsState::kScreenAddress | GraphicsState::kShakeScreen);
|
||||
}
|
||||
|
||||
if (_pendingState.change & GraphicsState::kScreenAddress) {
|
||||
// takes effect in the nearest VBL interrupt but we always wait for Vsync() in this case
|
||||
Vsync();
|
||||
assert(s_screenSurf == nullptr);
|
||||
|
||||
s_screenSurf = isOverlayVisible() ? &_screen[OVERLAY_BUFFER]->surf : &_screen[FRONT_BUFFER]->surf;
|
||||
_pendingState.change &= ~GraphicsState::kScreenAddress;
|
||||
}
|
||||
|
||||
if (_pendingState.change & GraphicsState::kShakeScreen) {
|
||||
// takes effect in the nearest VBL interrupt
|
||||
if (!s_screenSurf)
|
||||
s_screenSurf = isOverlayVisible() ? &_screen[OVERLAY_BUFFER]->surf : &_screen[FRONT_BUFFER]->surf;
|
||||
_pendingState.change &= ~GraphicsState::kShakeScreen;
|
||||
}
|
||||
|
||||
if (_pendingState.change & (GraphicsState::kVideoMode | GraphicsState::kPalette)) {
|
||||
if (!_tt) {
|
||||
// takes effect in the nearest VBL interrupt
|
||||
VsetRGB(0, isOverlayVisible() ? getOverlayPaletteSize() : 256, _workScreen->palette->falcon);
|
||||
} else {
|
||||
// takes effect immediatelly (it's possible that Vsync() hasn't been called: that's expected,
|
||||
// don't cripple framerate only for a palette change)
|
||||
EsetPalette(0, isOverlayVisible() ? getOverlayPaletteSize() : 256, _workScreen->palette->tt);
|
||||
}
|
||||
_pendingState.change &= ~(GraphicsState::kVideoMode | GraphicsState::kPalette);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (_overlayPending) {
|
||||
_pendingState = oldPendingState;
|
||||
_overlayPending = false;
|
||||
}
|
||||
|
||||
//debug("end of updateScreen");
|
||||
}
|
||||
|
||||
@ -704,12 +788,11 @@ void AtariGraphicsManager::setShakePos(int shakeXOffset, int shakeYOffset) {
|
||||
s_shakeYOffset = shakeYOffset;
|
||||
}
|
||||
|
||||
_pendingScreenChange |= kPendingScreenChangeScreen;
|
||||
updateScreen();
|
||||
_pendingState.change |= GraphicsState::kShakeScreen;
|
||||
}
|
||||
|
||||
void AtariGraphicsManager::showOverlay(bool inGUI) {
|
||||
debug("showOverlay");
|
||||
debug("showOverlay (visible: %d)", _overlayVisible);
|
||||
|
||||
if (_overlayVisible)
|
||||
return;
|
||||
@ -722,34 +805,38 @@ void AtariGraphicsManager::showOverlay(bool inGUI) {
|
||||
_workScreen = _screen[OVERLAY_BUFFER];
|
||||
|
||||
// do not cache dirtyRects and oldCursorRect
|
||||
const int bitsPerPixel = getBitsPerPixel(getOverlayFormat());
|
||||
static bool resetCursorPosition = true;
|
||||
_workScreen->reset(getOverlayWidth(), getOverlayHeight(), bitsPerPixel, resetCursorPosition);
|
||||
resetCursorPosition = false;
|
||||
|
||||
_pendingScreenChange = kPendingScreenChangeMode | kPendingScreenChangeScreen | kPendingScreenChangePalette;
|
||||
_workScreen->reset(getOverlayWidth(), getOverlayHeight(), getBitsPerPixel(getOverlayFormat()), false);
|
||||
|
||||
_overlayVisible = true;
|
||||
|
||||
assert(_pendingState.change == GraphicsState::kNone);
|
||||
_overlayPending = true;
|
||||
updateScreen();
|
||||
}
|
||||
|
||||
void AtariGraphicsManager::hideOverlay() {
|
||||
debug("hideOverlay");
|
||||
debug("hideOverlay (ignore: %d, visible: %d)", _ignoreHideOverlay, _overlayVisible);
|
||||
|
||||
if (!_overlayVisible)
|
||||
return;
|
||||
|
||||
if (_ignoreHideOverlay) {
|
||||
// faster than _workScreen->reset()
|
||||
_workScreen->clearDirtyRects();
|
||||
_workScreen->cursor.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
_workScreen = _oldWorkScreen;
|
||||
_oldWorkScreen = nullptr;
|
||||
|
||||
// FIXME: perhaps there's a better way but this will do for now
|
||||
_checkUnalignedPitch = true;
|
||||
|
||||
_pendingScreenChange = kPendingScreenChangeMode | kPendingScreenChangeScreen | kPendingScreenChangePalette;
|
||||
|
||||
_overlayVisible = false;
|
||||
|
||||
assert(_pendingState.change == GraphicsState::kNone);
|
||||
_pendingState.change = GraphicsState::kAll;
|
||||
updateScreen();
|
||||
}
|
||||
|
||||
@ -935,14 +1022,36 @@ void AtariGraphicsManager::updateMousePosition(int deltaX, int deltaY) {
|
||||
}
|
||||
|
||||
bool AtariGraphicsManager::notifyEvent(const Common::Event &event) {
|
||||
if (event.type != Common::EVENT_CUSTOM_BACKEND_ACTION_START) {
|
||||
return false;
|
||||
}
|
||||
switch (event.type) {
|
||||
case Common::EVENT_RETURN_TO_LAUNCHER:
|
||||
case Common::EVENT_QUIT:
|
||||
if (isOverlayVisible()) {
|
||||
_ignoreHideOverlay = true;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
switch ((CustomEventAction) event.customType) {
|
||||
case kActionToggleAspectRatioCorrection:
|
||||
_aspectRatioCorrection = !_aspectRatioCorrection;
|
||||
return true;
|
||||
case Common::EVENT_CUSTOM_BACKEND_ACTION_START:
|
||||
switch ((CustomEventAction) event.customType) {
|
||||
case kActionToggleAspectRatioCorrection:
|
||||
if (hasFeature(OSystem::Feature::kFeatureAspectRatioCorrection)) {
|
||||
_pendingState.aspectRatioCorrection = !_pendingState.aspectRatioCorrection;
|
||||
|
||||
if (_currentState.aspectRatioCorrection != _pendingState.aspectRatioCorrection) {
|
||||
_pendingState.change |= GraphicsState::kAspectRatioCorrection;
|
||||
|
||||
// would be updated in updateScreen() anyway
|
||||
_currentState.aspectRatioCorrection = _pendingState.aspectRatioCorrection;
|
||||
updateScreen();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -967,7 +1076,9 @@ void AtariGraphicsManager::allocateSurfaces() {
|
||||
_screen[i] = new Screen(this, getMaximumScreenWidth(), getMaximumScreenHeight(), PIXELFORMAT_CLUT8, &_palette);
|
||||
}
|
||||
|
||||
_screen[OVERLAY_BUFFER] = new Screen(this, getOverlayWidth(), getOverlayHeight(), getOverlayFormat(), &_overlayPalette);
|
||||
// overlay is the default screen upon start
|
||||
_workScreen = _screen[OVERLAY_BUFFER] = new Screen(this, getOverlayWidth(), getOverlayHeight(), getOverlayFormat(), &_overlayPalette);
|
||||
_workScreen->reset(getOverlayWidth(), getOverlayHeight(), getBitsPerPixel(getOverlayFormat()), true);
|
||||
|
||||
_chunkySurface.create(getMaximumScreenWidth(), getMaximumScreenHeight(), PIXELFORMAT_CLUT8);
|
||||
_overlaySurface.create(getOverlayWidth(), getOverlayHeight(), getOverlayFormat());
|
||||
|
@ -112,12 +112,24 @@ protected:
|
||||
void freeSurfaces();
|
||||
|
||||
private:
|
||||
enum class GraphicsMode : int {
|
||||
Unknown = -1,
|
||||
DirectRendering = 0,
|
||||
SingleBuffering = 1,
|
||||
TripleBuffering = 3
|
||||
};
|
||||
|
||||
enum CustomEventAction {
|
||||
kActionToggleAspectRatioCorrection = 100,
|
||||
};
|
||||
|
||||
#ifndef DISABLE_FANCY_THEMES
|
||||
int16 getMaximumScreenHeight() const { return 480; }
|
||||
int16 getMaximumScreenWidth() const { return _tt ? 320 : (_vgaMonitor ? 640 : 640*1.2); }
|
||||
#else
|
||||
int16 getMaximumScreenHeight() const { return _tt ? 480 : 240; }
|
||||
int16 getMaximumScreenWidth() const { return _tt ? 320 : (_vgaMonitor ? 320 : 320*1.2); }
|
||||
#endif
|
||||
|
||||
bool updateScreenInternal(const Graphics::Surface &srcSurface);
|
||||
|
||||
@ -162,38 +174,28 @@ private:
|
||||
|
||||
bool _vgaMonitor = true;
|
||||
bool _tt = false;
|
||||
bool _aspectRatioCorrection = false;
|
||||
bool _oldAspectRatioCorrection = false;
|
||||
bool _checkUnalignedPitch = false;
|
||||
|
||||
enum class GraphicsMode : int {
|
||||
DirectRendering = 0,
|
||||
SingleBuffering = 1,
|
||||
TripleBuffering = 3
|
||||
};
|
||||
|
||||
struct GraphicsState {
|
||||
GraphicsState(GraphicsMode mode_)
|
||||
: mode(mode_)
|
||||
, width(0)
|
||||
, height(0) {
|
||||
}
|
||||
|
||||
GraphicsMode mode;
|
||||
int width;
|
||||
int height;
|
||||
GraphicsMode mode = GraphicsMode::Unknown;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
Graphics::PixelFormat format;
|
||||
};
|
||||
GraphicsState _pendingState{ (GraphicsMode)getDefaultGraphicsMode() };
|
||||
GraphicsState _currentState{ (GraphicsMode)getDefaultGraphicsMode() };
|
||||
bool aspectRatioCorrection = false;
|
||||
|
||||
enum PendingScreenChange {
|
||||
kPendingScreenChangeNone = 0,
|
||||
kPendingScreenChangeMode = 1<<0,
|
||||
kPendingScreenChangeScreen = 1<<1,
|
||||
kPendingScreenChangePalette = 1<<2
|
||||
enum PendingScreenChange {
|
||||
kNone = 0,
|
||||
kVideoMode = 1<<0,
|
||||
kScreenAddress = 1<<1,
|
||||
kPalette = 1<<2,
|
||||
kAspectRatioCorrection = 1<<3,
|
||||
kShakeScreen = 1<<4,
|
||||
kAll = kVideoMode | kScreenAddress | kPalette | kAspectRatioCorrection | kShakeScreen,
|
||||
};
|
||||
int change = kNone;
|
||||
};
|
||||
int _pendingScreenChange = kPendingScreenChangeNone;
|
||||
GraphicsState _pendingState;
|
||||
GraphicsState _currentState;
|
||||
|
||||
enum {
|
||||
FRONT_BUFFER,
|
||||
@ -208,7 +210,9 @@ private:
|
||||
|
||||
Graphics::Surface _chunkySurface;
|
||||
|
||||
bool _overlayVisible = false;
|
||||
bool _overlayVisible = true;
|
||||
bool _overlayPending = true;
|
||||
bool _ignoreHideOverlay = true;
|
||||
Graphics::Surface _overlaySurface;
|
||||
|
||||
Palette _palette;
|
||||
|
@ -45,11 +45,14 @@ class Palette {
|
||||
public:
|
||||
void clear() {
|
||||
memset(data, 0, sizeof(data));
|
||||
entries = 0;
|
||||
}
|
||||
|
||||
uint16 *const tt = reinterpret_cast<uint16*>(data);
|
||||
_RGB *const falcon = reinterpret_cast<_RGB*>(data);
|
||||
|
||||
int entries = 0;
|
||||
|
||||
private:
|
||||
byte data[256*4] = {};
|
||||
};
|
||||
@ -80,12 +83,6 @@ struct Screen {
|
||||
int mode = -1;
|
||||
Graphics::Surface *const offsettedSurf = &_offsettedSurf;
|
||||
|
||||
int oldScreenSurfaceWidth = -1;
|
||||
int oldScreenSurfaceHeight = -1;
|
||||
int oldScreenSurfacePitch = -1;
|
||||
int oldOffsettedSurfaceWidth = -1;
|
||||
int oldOffsettedSurfaceHeight = -1;
|
||||
|
||||
private:
|
||||
static constexpr size_t ALIGN = 16; // 16 bytes
|
||||
|
||||
|
@ -25,13 +25,11 @@
|
||||
#include <mint/falcon.h>
|
||||
#include <mint/osbind.h>
|
||||
#include <mint/ostruct.h>
|
||||
#include <usound.h> // https://github.com/mikrosk/usound
|
||||
|
||||
#include "common/config-manager.h"
|
||||
#include "common/debug.h"
|
||||
|
||||
// see https://github.com/mikrosk/atari_sound_setup
|
||||
#include "../../../../atari_sound_setup.git/atari_sound_setup.h"
|
||||
|
||||
#define DEFAULT_OUTPUT_RATE 24585
|
||||
#define DEFAULT_OUTPUT_CHANNELS 2
|
||||
#define DEFAULT_SAMPLES 2048 // 83ms
|
||||
|
@ -59,6 +59,8 @@
|
||||
#include "base/main.h"
|
||||
#include "gui/debugger.h"
|
||||
|
||||
#define INPUT_ACTIVE
|
||||
|
||||
/*
|
||||
* Include header files needed for the getFilesystemFactory() method.
|
||||
*/
|
||||
@ -77,7 +79,6 @@ extern "C" volatile uint32 counter_200hz;
|
||||
extern void nf_init(void);
|
||||
extern void nf_print(const char* msg);
|
||||
|
||||
static bool s_tt = false;
|
||||
static int s_app_id = -1;
|
||||
|
||||
static bool exit_already_called = false;
|
||||
@ -89,12 +90,9 @@ static void critical_restore() {
|
||||
AtariAudioShutdown();
|
||||
AtariGraphicsShutdown();
|
||||
|
||||
if (s_tt)
|
||||
Supexec(asm_screen_tt_restore);
|
||||
else
|
||||
Supexec(asm_screen_falcon_restore);
|
||||
Supexec(atari_200hz_shutdown);
|
||||
|
||||
#ifdef INPUT_ACTIVE
|
||||
if (atari_old_kbdvec && atari_old_mousevec) {
|
||||
_KBDVECS *kbdvecs = Kbdvbase();
|
||||
((uintptr *)kbdvecs)[-1] = (uintptr)atari_old_kbdvec;
|
||||
@ -110,6 +108,7 @@ static void critical_restore() {
|
||||
// ok, restore mouse cursor at least
|
||||
graf_mouse(M_ON, NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// called on normal program termination (via exit() or returning from main())
|
||||
@ -141,8 +140,6 @@ OSystem_Atari::OSystem_Atari() {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
s_tt = (vdo == VDO_TT);
|
||||
|
||||
enum {
|
||||
MCH_ST = 0,
|
||||
MCH_STE,
|
||||
@ -161,23 +158,18 @@ OSystem_Atari::OSystem_Atari() {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#ifdef INPUT_ACTIVE
|
||||
_KBDVECS *kbdvecs = Kbdvbase();
|
||||
atari_old_kbdvec = (KBDVEC)(((uintptr *)kbdvecs)[-1]);
|
||||
atari_old_mousevec = kbdvecs->mousevec;
|
||||
|
||||
((uintptr *)kbdvecs)[-1] = (uintptr)atari_kbdvec;
|
||||
kbdvecs->mousevec = atari_mousevec;
|
||||
#endif
|
||||
|
||||
Supexec(atari_200hz_init);
|
||||
_timerInitialized = true;
|
||||
|
||||
if (s_tt)
|
||||
Supexec(asm_screen_tt_save);
|
||||
else
|
||||
Supexec(asm_screen_falcon_save);
|
||||
|
||||
_videoInitialized = true;
|
||||
|
||||
// protect against sudden exit()
|
||||
atexit(exit_restore);
|
||||
// protect against sudden crash
|
||||
@ -210,16 +202,6 @@ OSystem_Atari::~OSystem_Atari() {
|
||||
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;
|
||||
@ -273,9 +255,11 @@ void OSystem_Atari::initBackend() {
|
||||
_vdi_width = work_out[0] + 1;
|
||||
_vdi_height = work_out[1] + 1;
|
||||
|
||||
#ifdef INPUT_ACTIVE
|
||||
graf_mouse(M_OFF, NULL);
|
||||
// see https://github.com/freemint/freemint/issues/312
|
||||
//wind_update(BEG_UPDATE);
|
||||
#endif
|
||||
}
|
||||
|
||||
_timerManager = new DefaultTimerManager();
|
||||
|
@ -51,7 +51,6 @@ public:
|
||||
private:
|
||||
long _startTime;
|
||||
|
||||
bool _videoInitialized = false;
|
||||
bool _timerInitialized = false;
|
||||
|
||||
int16 _vdi_handle;
|
||||
|
@ -305,11 +305,6 @@ Yes, it's a hack. :) Owners of a CRT monitor can achieve the same effect by the
|
||||
analog knobs -- stretch and move the 320x200 picture unless black borders are no
|
||||
longer visible. This hack provides a more elegant and per-game functionality.
|
||||
|
||||
Realtime aspect ratio correction (CTRL+ALT+a) should be used with caution in
|
||||
Direct rendering mode because there's no way to refresh the screen. So if you
|
||||
change the setting and there isn't any game screen update coming, screen will
|
||||
stay black.
|
||||
|
||||
|
||||
Audio mixing
|
||||
------------
|
||||
|
@ -347,7 +347,7 @@ static void setupGraphics(OSystem &system) {
|
||||
system.setScaler(ConfMan.get("scaler").c_str(), ConfMan.getInt("scale_factor"));
|
||||
system.setShader(ConfMan.getPath("shader"));
|
||||
|
||||
#if defined(OPENDINGUX) || defined(MIYOO) || defined(MIYOOMINI)
|
||||
#if defined(OPENDINGUX) || defined(MIYOO) || defined(MIYOOMINI) || defined(ATARI)
|
||||
// 0, 0 means "autodetect" but currently only SDL supports
|
||||
// it and really useful only on Opendingux. When more platforms
|
||||
// support it we will switch to it.
|
||||
|
Loading…
Reference in New Issue
Block a user