Initial commit
This commit is contained in:
40
backends/platform/atari/atari-debug.cpp
Normal file
40
backends/platform/atari/atari-debug.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
/* 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/platform/atari/atari-debug.h"
|
||||
|
||||
#ifdef DISABLE_TEXT_CONSOLE
|
||||
|
||||
void atari_debug(const char *s, ...) {
|
||||
va_list va;
|
||||
|
||||
va_start(va, s);
|
||||
|
||||
Common::String buf = Common::String::vformat(s, va);
|
||||
buf += '\n';
|
||||
|
||||
if (g_system)
|
||||
g_system->logMessage(LogMessageType::kDebug, buf.c_str());
|
||||
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
#endif
|
||||
42
backends/platform/atari/atari-debug.h
Normal file
42
backends/platform/atari/atari-debug.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/* 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 PLATFORM_ATARI_DEBUG_H
|
||||
#define PLATFORM_ATARI_DEBUG_H
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "common/str.h"
|
||||
#include "common/system.h"
|
||||
#include "common/textconsole.h"
|
||||
|
||||
#ifdef DISABLE_TEXT_CONSOLE
|
||||
|
||||
void atari_debug(const char *s, ...);
|
||||
#define atari_warning atari_debug
|
||||
|
||||
#else
|
||||
|
||||
#define atari_debug debug
|
||||
#define atari_warning warning
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
137
backends/platform/atari/atari.mk
Normal file
137
backends/platform/atari/atari.mk
Normal file
@@ -0,0 +1,137 @@
|
||||
.PHONY: atarilitedist atarifulldist fbdist
|
||||
|
||||
DIST_FILES_PLATFORM := $(srcdir)/backends/platform/atari/readme.txt
|
||||
ifneq (${BACKEND},sdl)
|
||||
DIST_FILES_PLATFORM += $(srcdir)/backends/platform/atari/patches
|
||||
endif
|
||||
|
||||
LITE_DIR := scummvm-${VERSION}-atari-lite
|
||||
LITE_DATA := ${LITE_DIR}/data
|
||||
LITE_DOCS := ${LITE_DIR}/doc
|
||||
LITE_THEMES :=
|
||||
|
||||
FULL_DIR := scummvm-${VERSION}-atari-full
|
||||
FULL_DATA := ${FULL_DIR}/data
|
||||
FULL_DOCS := ${FULL_DIR}/doc
|
||||
FULL_THEMES := ${FULL_DIR}/themes
|
||||
|
||||
FB_DIR := scummvm-${VERSION}-firebee
|
||||
FB_DATA := ${FB_DIR}
|
||||
FB_DOCS := ${FB_DIR}/doc
|
||||
FB_THEMES := ${FB_DIR}
|
||||
|
||||
atarilitedist: $(EXECUTABLE)
|
||||
$(RM_REC) ${LITE_DIR}
|
||||
$(MKDIR) ${LITE_DIR}
|
||||
|
||||
$(CP) $(EXECUTABLE) ${LITE_DIR}
|
||||
$(NM) -C ${LITE_DIR}/$(EXECUTABLE) | grep -vF ' .L' | grep ' [TtWV] ' | $(CXXFILT) | sort -u > ${LITE_DIR}/scummvm.sym
|
||||
$(STRIP) -s ${LITE_DIR}/$(EXECUTABLE)
|
||||
|
||||
$(MKDIR) ${LITE_DOCS}
|
||||
$(CP) $(DIST_FILES_DOCS) ${LITE_DOCS}
|
||||
|
||||
$(MKDIR) ${LITE_DATA}
|
||||
$(CP) $(DIST_FILES_ENGINEDATA) $(DIST_FILES_ENGINEDATA_BIG) ${LITE_DATA}
|
||||
|
||||
# remove unused files
|
||||
$(RM) ${LITE_DATA}/helpdialog.zip
|
||||
$(RM) $(addsuffix .dat, $(addprefix ${LITE_DATA}/, achievements classicmacfonts encoding macgui))
|
||||
|
||||
# rename remaining files still not fitting into the 8+3 limit (this has to be supported by the backend, too)
|
||||
! [ -f ${LITE_DATA}/supernova.dat ] || mv ${LITE_DATA}/supernova.dat ${LITE_DATA}/supernov.dat
|
||||
! [ -f ${LITE_DATA}/teenagent.dat ] || mv ${LITE_DATA}/teenagent.dat ${LITE_DATA}/teenagen.dat
|
||||
|
||||
# readme.txt
|
||||
$(CP) -r $(DIST_FILES_PLATFORM) ${LITE_DIR}
|
||||
unix2dos ${LITE_DIR}/readme.txt
|
||||
|
||||
ifeq ($(CREATE_ZIP),y)
|
||||
$(RM) ../${LITE_DIR}.zip
|
||||
$(ZIP) -r -9 ../${LITE_DIR}.zip ${LITE_DIR}
|
||||
endif
|
||||
|
||||
atarifulldist: $(EXECUTABLE)
|
||||
$(RM_REC) ${FULL_DIR}
|
||||
$(MKDIR) ${FULL_DIR}
|
||||
|
||||
$(CP) $(EXECUTABLE) ${FULL_DIR}
|
||||
$(NM) -C ${FULL_DIR}/$(EXECUTABLE) | grep -vF ' .L' | grep ' [TtWV] ' | $(CXXFILT) | sort -u > ${FULL_DIR}/scummvm.sym
|
||||
$(STRIP) -s ${FULL_DIR}/$(EXECUTABLE)
|
||||
|
||||
$(MKDIR) ${FULL_DOCS}
|
||||
$(CP) $(DIST_FILES_DOCS) ${FULL_DOCS}
|
||||
|
||||
$(MKDIR) ${FULL_DATA}
|
||||
$(CP) $(DIST_FILES_ENGINEDATA) $(DIST_FILES_ENGINEDATA_BIG) ${FULL_DATA}
|
||||
|
||||
# remove unused files
|
||||
$(RM) ${FULL_DATA}/helpdialog.zip
|
||||
$(RM) $(addsuffix .dat, $(addprefix ${FULL_DATA}/, achievements classicmacfonts encoding hadesch_translations macgui prince_translation))
|
||||
|
||||
# rename remaining files still not fitting into the 8+3 limit (this has to be supported by the backend, too)
|
||||
! [ -f ${FULL_DATA}/cryomni3d.dat ] || mv ${FULL_DATA}/cryomni3d.dat ${FULL_DATA}/cryomni3.dat
|
||||
! [ -f ${FULL_DATA}/neverhood.dat ] || mv ${FULL_DATA}/neverhood.dat ${FULL_DATA}/neverhoo.dat
|
||||
! [ -f ${FULL_DATA}/supernova.dat ] || mv ${FULL_DATA}/supernova.dat ${FULL_DATA}/supernov.dat
|
||||
! [ -f ${FULL_DATA}/teenagent.dat ] || mv ${FULL_DATA}/teenagent.dat ${FULL_DATA}/teenagen.dat
|
||||
|
||||
$(MKDIR) ${FULL_THEMES}
|
||||
$(CP) $(DIST_FILES_THEMES) ${FULL_THEMES}
|
||||
|
||||
# remove unused files; absent gui-icons.dat massively speeds up startup time (it is used for the grid mode only)
|
||||
$(RM) ${FULL_THEMES}/gui-icons.dat ${FULL_THEMES}/shaders.dat
|
||||
|
||||
# adjust to compression level zero for faster depacking
|
||||
cd ${FULL_THEMES} && \
|
||||
for f in *.zip; \
|
||||
do \
|
||||
unzip -q -d tmp "$$f" && $(RM) "$$f" && cd tmp && $(ZIP) -0 "../$$f" * && cd .. && $(RM_REC) tmp; \
|
||||
done
|
||||
|
||||
# readme.txt
|
||||
$(CP) -r $(DIST_FILES_PLATFORM) ${FULL_DIR}
|
||||
unix2dos ${FULL_DIR}/readme.txt
|
||||
|
||||
ifeq ($(CREATE_ZIP),y)
|
||||
$(RM) ../${FULL_DIR}.zip
|
||||
$(ZIP) -r -9 ../${FULL_DIR}.zip ${FULL_DIR}
|
||||
endif
|
||||
|
||||
fbdist: $(EXECUTABLE)
|
||||
$(RM_REC) ${FB_DIR}
|
||||
$(MKDIR) ${FB_DIR}
|
||||
|
||||
$(CP) $(EXECUTABLE) ${FB_DIR}
|
||||
$(STRIP) -s ${FB_DIR}/$(EXECUTABLE)
|
||||
|
||||
$(MKDIR) ${FB_DOCS}
|
||||
$(CP) $(DIST_FILES_DOCS) ${FB_DOCS}
|
||||
|
||||
$(MKDIR) ${FB_DATA}
|
||||
$(CP) $(DIST_FILES_ENGINEDATA) $(DIST_FILES_ENGINEDATA_BIG) ${FB_DATA}
|
||||
|
||||
# remove unused files
|
||||
$(RM) ${FB_DATA}/helpdialog.zip
|
||||
$(RM) $(addsuffix .dat, $(addprefix ${FB_DATA}/, achievements classicmacfonts encoding hadesch_translations macgui prince_translation))
|
||||
|
||||
$(MKDIR) ${FB_THEMES}
|
||||
$(CP) $(DIST_FILES_THEMES) ${FB_THEMES}
|
||||
|
||||
# remove unused files
|
||||
$(RM) ${FB_THEMES}/shaders.dat
|
||||
|
||||
# adjust to compression level zero for faster depacking
|
||||
cd ${FB_THEMES} && \
|
||||
for f in *.zip; \
|
||||
do \
|
||||
unzip -q -d tmp "$$f" && $(RM) "$$f" && cd tmp && $(ZIP) -0 "../$$f" * && cd .. && $(RM_REC) tmp; \
|
||||
done
|
||||
|
||||
# readme.txt
|
||||
$(CP) -r $(DIST_FILES_PLATFORM) ${FB_DIR}
|
||||
unix2dos ${FB_DIR}/readme.txt
|
||||
|
||||
ifeq ($(CREATE_ZIP),y)
|
||||
$(RM) ../${FB_DIR}.zip
|
||||
$(ZIP) -r -9 ../${FB_DIR}.zip ${FB_DIR}
|
||||
endif
|
||||
121
backends/platform/atari/atari_ikbd.S
Normal file
121
backends/platform/atari/atari_ikbd.S
Normal file
@@ -0,0 +1,121 @@
|
||||
/* 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 "symbols.h"
|
||||
|
||||
.global SYM(atari_kbdvec)
|
||||
.global SYM(atari_mousevec)
|
||||
|
||||
.global SYM(atari_old_kbdvec)
|
||||
.global SYM(atari_old_mousevec)
|
||||
|
||||
.extern SYM(g_atari_ikbd_mousebuttons)
|
||||
.extern SYM(g_atari_ikbd_mousebuttons_mask)
|
||||
.extern SYM(g_atari_ikbd_mousebuttons_head)
|
||||
|
||||
.extern SYM(g_atari_ikbd_mouse_delta_x)
|
||||
.extern SYM(g_atari_ikbd_mouse_delta_y)
|
||||
|
||||
.extern SYM(g_atari_ikbd_scancodes)
|
||||
.extern SYM(g_atari_ikbd_scancodes_mask)
|
||||
.extern SYM(g_atari_ikbd_scancodes_head)
|
||||
|
||||
.text
|
||||
|
||||
.ascii "XBRA"
|
||||
.ascii "SCUM"
|
||||
SYM(atari_old_kbdvec):
|
||||
dc.l 0
|
||||
SYM(atari_kbdvec):
|
||||
lea pressed_keys,a0
|
||||
clr.l d1
|
||||
move.b d0,d1
|
||||
bpl.b key_pressed | bit 7 cleared
|
||||
|
||||
key_released:
|
||||
and.b #0x7f,d1
|
||||
tst.b (a0,d1.l) | pressed before?
|
||||
bne.b key_released_ok
|
||||
|
||||
| if we get a sudden release key event,
|
||||
| let the original handler process it
|
||||
move.l (atari_old_kbdvec,pc),a0
|
||||
jmp (a0)
|
||||
|
||||
key_released_ok:
|
||||
clr.b (a0,d1.l) | mark as released
|
||||
bra.b kbdvec_process
|
||||
|
||||
key_pressed:
|
||||
addq.b #1,(a0,d1.l) | mark as pressed
|
||||
|
||||
kbdvec_process:
|
||||
lea SYM(g_atari_ikbd_scancodes),a0
|
||||
move.w SYM(g_atari_ikbd_scancodes_head),d1
|
||||
|
||||
| g_atari_ikbd_scancodes[g_atari_ikbd_scancodes_head] = scancode
|
||||
|
||||
move.b d0,(0.b,a0,d1.w)
|
||||
|
||||
addq.l #1,d1
|
||||
and.w SYM(g_atari_ikbd_scancodes_mask),d1
|
||||
move.w d1,SYM(g_atari_ikbd_scancodes_head)
|
||||
rts
|
||||
|
||||
|
||||
.ascii "XBRA"
|
||||
.ascii "SCUM"
|
||||
SYM(atari_old_mousevec):
|
||||
dc.l 0
|
||||
SYM(atari_mousevec):
|
||||
move.b (a0)+,d0
|
||||
cmp.b old_buttons,d0
|
||||
beq.b no_buttons
|
||||
|
||||
move.b d0,old_buttons
|
||||
|
||||
lea SYM(g_atari_ikbd_mousebuttons),a1
|
||||
move.w SYM(g_atari_ikbd_mousebuttons_head),d1
|
||||
|
||||
| g_atari_ikbd_mousebuttons[g_atari_ikbd_mousebuttons_head] = buttons
|
||||
|
||||
move.b d0,(0.b,a1,d1.w)
|
||||
|
||||
addq.w #1,d1
|
||||
and.w SYM(g_atari_ikbd_mousebuttons_mask),d1
|
||||
move.w d1,SYM(g_atari_ikbd_mousebuttons_head)
|
||||
|
||||
no_buttons:
|
||||
move.b (a0)+,d0
|
||||
ext.w d0
|
||||
add.w d0,SYM(g_atari_ikbd_mouse_delta_x)
|
||||
|
||||
move.b (a0)+,d0
|
||||
ext.w d0
|
||||
add.w d0,SYM(g_atari_ikbd_mouse_delta_y)
|
||||
rts
|
||||
|
||||
.bss
|
||||
|
||||
pressed_keys:
|
||||
ds.b 128
|
||||
old_buttons:
|
||||
ds.b 1
|
||||
45
backends/platform/atari/build-firebee.sh
Normal file
45
backends/platform/atari/build-firebee.sh
Normal file
@@ -0,0 +1,45 @@
|
||||
#!/bin/bash -eux
|
||||
# -e: Exit immediately if a command exits with a non-zero status.
|
||||
# -u: Treat unset variables as an error when substituting.
|
||||
# -x: Display expanded script commands
|
||||
|
||||
mkdir -p build-firebee
|
||||
cd build-firebee
|
||||
|
||||
PLATFORM=m68k-atari-mintelf
|
||||
FASTCALL=false
|
||||
export CXXFLAGS="-mcpu=5475"
|
||||
export LDFLAGS="-mcpu=5475"
|
||||
#export CXXFLAGS="-m68020-60"
|
||||
#export LDFLAGS="-m68020-60"
|
||||
|
||||
CPU_DIR=$(${PLATFORM}-gcc ${CXXFLAGS} -print-multi-directory)
|
||||
|
||||
export PKG_CONFIG_LIBDIR="$(${PLATFORM}-gcc -print-sysroot)/usr/lib/${CPU_DIR}/pkgconfig"
|
||||
|
||||
if $FASTCALL
|
||||
then
|
||||
CXXFLAGS="$CXXFLAGS -mfastcall"
|
||||
LDFLAGS="$LDFLAGS -mfastcall"
|
||||
fi
|
||||
|
||||
if [ -f ../backends/platform/atari/.patched ]
|
||||
then
|
||||
echo "FireBee SDL target shouldn't contain any ATARI patches!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
if [ ! -f config.log ]
|
||||
then
|
||||
../configure \
|
||||
--backend=sdl \
|
||||
--host=${PLATFORM} \
|
||||
--with-sdl-prefix="$(${PLATFORM}-gcc -print-sysroot)/usr/bin/${CPU_DIR}" \
|
||||
--with-freetype2-prefix="$(${PLATFORM}-gcc -print-sysroot)/usr/bin/${CPU_DIR}" \
|
||||
--with-mikmod-prefix="$(${PLATFORM}-gcc -print-sysroot)/usr/bin/${CPU_DIR}" \
|
||||
--enable-release \
|
||||
--enable-verbose-build
|
||||
fi
|
||||
|
||||
make -j$(getconf _NPROCESSORS_CONF) fbdist
|
||||
41
backends/platform/atari/build-release.sh
Normal file
41
backends/platform/atari/build-release.sh
Normal file
@@ -0,0 +1,41 @@
|
||||
#!/bin/bash -eux
|
||||
# -e: Exit immediately if a command exits with a non-zero status.
|
||||
# -u: Treat unset variables as an error when substituting.
|
||||
# -x: Display expanded script commands
|
||||
|
||||
mkdir -p build-release
|
||||
cd build-release
|
||||
|
||||
PLATFORM=m68k-atari-mintelf
|
||||
FASTCALL=false
|
||||
export ASFLAGS="-m68020-60"
|
||||
export CXXFLAGS="-m68020-60 -DUSE_MOVE16 -DUSE_SUPERVIDEL -DUSE_SV_BLITTER -DDISABLE_LAUNCHERDISPLAY_GRID"
|
||||
export LDFLAGS="-m68020-60"
|
||||
|
||||
export PKG_CONFIG_LIBDIR="$(${PLATFORM}-gcc -print-sysroot)/usr/lib/m68020-60/pkgconfig"
|
||||
|
||||
if $FASTCALL
|
||||
then
|
||||
ASFLAGS="$ASFLAGS -mfastcall"
|
||||
CXXFLAGS="$CXXFLAGS -mfastcall"
|
||||
LDFLAGS="$LDFLAGS -mfastcall"
|
||||
fi
|
||||
|
||||
if [ ! -f ../backends/platform/atari/.patched ]
|
||||
then
|
||||
cd .. && cat backends/platform/atari/patches/print_rate.patch | patch -p1 && cd -
|
||||
cd .. && cat backends/platform/atari/patches/tooltips.patch | patch -p1 && cd -
|
||||
touch ../backends/platform/atari/.patched
|
||||
fi
|
||||
|
||||
if [ ! -f config.log ]
|
||||
then
|
||||
../configure \
|
||||
--backend=atari \
|
||||
--host=${PLATFORM} \
|
||||
--enable-release \
|
||||
--enable-verbose-build \
|
||||
--disable-engine=hugo,director,cine,ultima
|
||||
fi
|
||||
|
||||
make -j$(getconf _NPROCESSORS_CONF) atarifulldist
|
||||
43
backends/platform/atari/build-release030.sh
Normal file
43
backends/platform/atari/build-release030.sh
Normal file
@@ -0,0 +1,43 @@
|
||||
#!/bin/bash -eux
|
||||
# -e: Exit immediately if a command exits with a non-zero status.
|
||||
# -u: Treat unset variables as an error when substituting.
|
||||
# -x: Display expanded script commands
|
||||
|
||||
mkdir -p build-release030
|
||||
cd build-release030
|
||||
|
||||
PLATFORM=m68k-atari-mintelf
|
||||
FASTCALL=false
|
||||
export ASFLAGS="-m68030"
|
||||
export CXXFLAGS="-m68030 -DDISABLE_FANCY_THEMES"
|
||||
export LDFLAGS="-m68030"
|
||||
|
||||
export PKG_CONFIG_LIBDIR="$(${PLATFORM}-gcc -print-sysroot)/usr/lib/m68020-60/pkgconfig"
|
||||
|
||||
if $FASTCALL
|
||||
then
|
||||
ASFLAGS="$ASFLAGS -mfastcall"
|
||||
CXXFLAGS="$CXXFLAGS -mfastcall"
|
||||
LDFLAGS="$LDFLAGS -mfastcall"
|
||||
fi
|
||||
|
||||
if [ ! -f ../backends/platform/atari/.patched ]
|
||||
then
|
||||
cd .. && cat backends/platform/atari/patches/print_rate.patch | patch -p1 && cd -
|
||||
cd .. && cat backends/platform/atari/patches/tooltips.patch | patch -p1 && cd -
|
||||
touch ../backends/platform/atari/.patched
|
||||
fi
|
||||
|
||||
if [ ! -f config.log ]
|
||||
then
|
||||
../configure \
|
||||
--backend=atari \
|
||||
--host=${PLATFORM} \
|
||||
--enable-release \
|
||||
--disable-highres \
|
||||
--disable-bink \
|
||||
--enable-verbose-build \
|
||||
--disable-engine=hugo,director,cine,ultima
|
||||
fi
|
||||
|
||||
make -j$(getconf _NPROCESSORS_CONF) atarilitedist
|
||||
4875
backends/platform/atari/dlmalloc.cpp
Normal file
4875
backends/platform/atari/dlmalloc.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1472
backends/platform/atari/dlmalloc.h
Normal file
1472
backends/platform/atari/dlmalloc.h
Normal file
File diff suppressed because it is too large
Load Diff
13
backends/platform/atari/module.mk
Normal file
13
backends/platform/atari/module.mk
Normal file
@@ -0,0 +1,13 @@
|
||||
MODULE := backends/platform/atari
|
||||
|
||||
MODULE_OBJS := \
|
||||
osystem_atari.o \
|
||||
atari-debug.o \
|
||||
atari_ikbd.o \
|
||||
native_features.o \
|
||||
dlmalloc.o
|
||||
|
||||
# We don't use rules.mk but rather manually update OBJS and MODULE_DIRS.
|
||||
MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS))
|
||||
OBJS := $(MODULE_OBJS) $(OBJS)
|
||||
MODULE_DIRS += $(sort $(dir $(MODULE_OBJS)))
|
||||
96
backends/platform/atari/native_features.cpp
Normal file
96
backends/platform/atari/native_features.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
// Taken from mintlib (https://github.com/freemint/mintlib)
|
||||
// (c) Thorsten Otto
|
||||
|
||||
#include <mint/osbind.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define NATFEAT_ID 0x7300
|
||||
#define NATFEAT_CALL 0x7301
|
||||
|
||||
#define ASM_NATFEAT3(opcode) "\t.word " #opcode "\n"
|
||||
#define ASM_NATFEAT2(opcode) ASM_NATFEAT3(opcode)
|
||||
#define ASM_NATFEAT(n) ASM_NATFEAT2(n)
|
||||
|
||||
static unsigned short const nf_id_opcodes[] = { NATFEAT_ID, 0x4e75 };
|
||||
static unsigned short const nf_call_opcodes[] = { NATFEAT_CALL, 0x4e75 };
|
||||
|
||||
#define _nf_get_id(feature_name) ((long (__CDECL *)(const char *))nf_id_opcodes)(feature_name)
|
||||
#define _nf_call(id, ...) ((long (__CDECL *)(long, ...))nf_call_opcodes)(id, __VA_ARGS__)
|
||||
|
||||
/*
|
||||
* on ColdFire, the NATFEAT_ID opcode is actually
|
||||
* "mvs.b d0,d1",
|
||||
* which means the following code will NOT detect
|
||||
* the presence of an emulator (should there ever
|
||||
* be an emulator capable of emulating a ColdFire processor).
|
||||
* Luckily, executing the code on a CF processor is still
|
||||
* harmless since all it does is clobber D1.
|
||||
*/
|
||||
static long _nf_detect_tos(void) {
|
||||
register long ret __asm__ ("d0");
|
||||
register const char *nf_version __asm__("a1") = "NF_VERSION";
|
||||
|
||||
__asm__ volatile(
|
||||
"\tmove.l %1,-(%%sp)\n"
|
||||
"\tmoveq #0,%%d0\n" /* assume no NatFeats available */
|
||||
"\tmove.l %%d0,-(%%sp)\n"
|
||||
"\tlea (1f:w,%%pc),%%a1\n"
|
||||
"\tmove.l (0x0010).w,%%a0\n" /* illegal instruction vector */
|
||||
"\tmove.l %%a1,(0x0010).w\n"
|
||||
"\tmove.l %%sp,%%a1\n" /* save the ssp */
|
||||
|
||||
"\tnop\n" /* flush pipelines (for 68040+) */
|
||||
|
||||
ASM_NATFEAT(NATFEAT_ID) /* Jump to NATFEAT_ID */
|
||||
"\ttst.l %%d0\n"
|
||||
"\tbeq.s 1f\n"
|
||||
"\tmoveq #1,%%d0\n" /* NatFeats detected */
|
||||
"\tmove.l %%d0,(%%sp)\n"
|
||||
|
||||
"1:\n"
|
||||
"\tmove.l %%a1,%%sp\n"
|
||||
"\tmove.l %%a0,(0x0010).w\n"
|
||||
"\tmove.l (%%sp)+,%%d0\n"
|
||||
"\taddq.l #4,%%sp\n" /* pop nf_version argument */
|
||||
|
||||
"\tnop\n" /* flush pipelines (for 68040+) */
|
||||
: "=g"(ret) /* outputs */
|
||||
: "g"(nf_version) /* inputs */
|
||||
: __CLOBBER_RETURN("d0") "a0", "d1", "cc" AND_MEMORY
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
long nf_stderr_id;
|
||||
|
||||
void nf_init(void) {
|
||||
long ret = Supexec(_nf_detect_tos);
|
||||
if (ret == 1)
|
||||
nf_stderr_id = _nf_get_id("NF_STDERR");
|
||||
}
|
||||
|
||||
void nf_print(const char* msg) {
|
||||
if (nf_stderr_id)
|
||||
_nf_call(nf_stderr_id | 0, (uint32_t)msg);
|
||||
}
|
||||
519
backends/platform/atari/osystem_atari.cpp
Normal file
519
backends/platform/atari/osystem_atari.cpp
Normal file
@@ -0,0 +1,519 @@
|
||||
/* 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 <stdio.h>
|
||||
#include <stdlib.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_fputs
|
||||
#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
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_fprintf
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_exit
|
||||
|
||||
#include "backends/platform/atari/osystem_atari.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/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/platform/atari/atari-debug.h"
|
||||
#include "backends/saves/default/default-saves.h"
|
||||
#include "backends/timer/default/default-timer.h"
|
||||
#include "base/main.h"
|
||||
|
||||
#define INPUT_ACTIVE
|
||||
|
||||
/*
|
||||
* Include header files needed for the getFilesystemFactory() method.
|
||||
*/
|
||||
#include "backends/fs/atari/atari-fs-factory.h"
|
||||
|
||||
bool g_gameEngineActive = false;
|
||||
|
||||
extern "C" void atari_kbdvec(void *);
|
||||
extern "C" void atari_mousevec(void *);
|
||||
typedef void (*KBDVEC)(void *);
|
||||
extern "C" KBDVEC atari_old_kbdvec;
|
||||
extern "C" KBDVEC atari_old_mousevec;
|
||||
|
||||
extern void nf_init(void);
|
||||
extern void nf_print(const char* msg);
|
||||
|
||||
static int s_app_id = -1;
|
||||
static void (*s_old_procterm)(void) = nullptr;
|
||||
|
||||
static volatile uint32 counter_200hz;
|
||||
|
||||
static bool s_dtor_already_called = false;
|
||||
|
||||
static long atari_200hz_init(void)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"\tmove %%sr,-(%%sp)\n"
|
||||
"\tor.w #0x700,%%sr\n"
|
||||
|
||||
"\tmove.l 0x114.w,old_200hz\n"
|
||||
"\tmove.l #my_200hz,0x114.w\n"
|
||||
|
||||
"\tmove (%%sp)+,%%sr\n"
|
||||
"\tjbra 1f\n"
|
||||
|
||||
"\tdc.l 0x58425241\n" /* "XBRA" */
|
||||
"\tdc.l 0x5343554d\n" /* "SCUM" */
|
||||
"old_200hz:\n"
|
||||
"\tdc.l 0\n"
|
||||
"my_200hz:\n"
|
||||
"\taddq.l #1,%0\n"
|
||||
|
||||
"\tmove.l old_200hz(%%pc),-(%%sp)\n"
|
||||
"\trts\n"
|
||||
"1:\n"
|
||||
: /* output */
|
||||
: "m"(counter_200hz) /* inputs */
|
||||
: "memory", "cc");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long atari_200hz_shutdown(void)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"\tmove %%sr,-(%%sp)\n"
|
||||
"\tor.w #0x700,%%sr\n"
|
||||
|
||||
"\tmove.l old_200hz,0x114.w\n"
|
||||
|
||||
"\tmove (%%sp)+,%%sr\n"
|
||||
: /* output */
|
||||
: /* inputs */
|
||||
: "memory", "cc");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void critical_restore() {
|
||||
//atari_debug("critical_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;
|
||||
kbdvecs->mousevec = atari_old_mousevec;
|
||||
atari_old_kbdvec = atari_old_mousevec = nullptr;
|
||||
}
|
||||
|
||||
// don't call GEM cleanup in the critical handler: it seems that v_clsvwk()
|
||||
// somehow manipulates the same memory area used for the critical handler's stack
|
||||
// what causes v_clsvwk() never returning and leading to a bus error (and another
|
||||
// critical_restore() called...)
|
||||
if (s_app_id != -1) {
|
||||
// ok, restore mouse cursor at least
|
||||
graf_mouse(M_ON, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
// avoid infinite recursion if either of the shutdown procedures fails
|
||||
(void)Setexc(VEC_PROCTERM, s_old_procterm);
|
||||
|
||||
extern void AtariAudioShutdown();
|
||||
extern void AtariGraphicsShutdown();
|
||||
|
||||
AtariAudioShutdown();
|
||||
AtariGraphicsShutdown();
|
||||
}
|
||||
|
||||
// called on normal program termination (via exit() or returning from main())
|
||||
static void exit_restore() {
|
||||
// causes a crash upon termination
|
||||
//atari_debug("exit_restore()");
|
||||
|
||||
if (!s_dtor_already_called)
|
||||
g_system->destroy();
|
||||
// else critical_restore() will be called, too
|
||||
}
|
||||
|
||||
OSystem_Atari::OSystem_Atari() {
|
||||
_fsFactory = new AtariFilesystemFactory();
|
||||
|
||||
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) {
|
||||
fprintf(stderr, "ScummVM requires Atari TT/Falcon compatible video\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
enum {
|
||||
MCH_ST = 0,
|
||||
MCH_STE,
|
||||
MCH_TT,
|
||||
MCH_FALCON,
|
||||
MCH_CLONE,
|
||||
MCH_ARANYM
|
||||
};
|
||||
|
||||
long mch = MCH_ST<<16;
|
||||
Getcookie(C__MCH, &mch);
|
||||
mch >>= 16;
|
||||
|
||||
if (mch == MCH_ARANYM && Getcookie(C_fVDI, NULL) == C_FOUND) {
|
||||
fprintf(stderr, "Disable fVDI, ScummVM uses XBIOS video calls\n");
|
||||
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;
|
||||
|
||||
// protect against sudden exit()
|
||||
atexit(exit_restore);
|
||||
// protect against sudden crash
|
||||
s_old_procterm = Setexc(VEC_PROCTERM, -1);
|
||||
(void)Setexc(VEC_PROCTERM, critical_restore);
|
||||
}
|
||||
|
||||
OSystem_Atari::~OSystem_Atari() {
|
||||
atari_debug("OSystem_Atari::~OSystem_Atari()");
|
||||
|
||||
s_dtor_already_called = true;
|
||||
|
||||
// _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 (_timerInitialized) {
|
||||
Supexec(atari_200hz_shutdown);
|
||||
_timerInitialized = false;
|
||||
}
|
||||
|
||||
if (atari_old_kbdvec && atari_old_mousevec) {
|
||||
_KBDVECS *kbdvecs = Kbdvbase();
|
||||
((uintptr *)kbdvecs)[-1] = (uintptr)atari_old_kbdvec;
|
||||
kbdvecs->mousevec = atari_old_mousevec;
|
||||
atari_old_kbdvec = atari_old_mousevec = nullptr;
|
||||
}
|
||||
|
||||
if (s_app_id != -1) {
|
||||
//wind_update(END_UPDATE);
|
||||
|
||||
// redraw screen
|
||||
form_dial(FMD_FINISH, 0, 0, 0, 0, 0, 0, _vdi_width, _vdi_height);
|
||||
graf_mouse(M_ON, NULL);
|
||||
|
||||
v_clsvwk(_vdi_handle);
|
||||
appl_exit();
|
||||
}
|
||||
|
||||
// graceful exit
|
||||
(void)Setexc(VEC_PROCTERM, s_old_procterm);
|
||||
}
|
||||
|
||||
void OSystem_Atari::initBackend() {
|
||||
atari_debug("OSystem_Atari::initBackend()");
|
||||
|
||||
s_app_id = appl_init();
|
||||
if (s_app_id != -1) {
|
||||
// get the ID of the current physical screen workstation
|
||||
int16 dummy;
|
||||
_vdi_handle = graf_handle(&dummy, &dummy, &dummy, &dummy);
|
||||
if (_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, &_vdi_handle, work_out);
|
||||
|
||||
if (_vdi_handle == 0) {
|
||||
appl_exit();
|
||||
error("v_opnvwk() failed");
|
||||
}
|
||||
|
||||
_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();
|
||||
_savefileManager = new DefaultSaveFileManager("saves");
|
||||
|
||||
AtariEventSource *atariEventSource = new AtariEventSource();
|
||||
_eventManager = new DefaultEventManager(makeKeyboardRepeatingEventSource(atariEventSource));
|
||||
|
||||
// AtariGraphicsManager needs _eventManager ready
|
||||
AtariGraphicsManager *atariGraphicsManager = new AtariGraphicsManager();
|
||||
_graphicsManager = atariGraphicsManager;
|
||||
|
||||
atariEventSource->setGraphicsManager(atariGraphicsManager);
|
||||
|
||||
#ifdef DISABLE_FANCY_THEMES
|
||||
// On the lite build force "STMIDI" as the audio driver, i.e. do not attempt
|
||||
// to emulate anything by default. That prevents mixing silence and enable
|
||||
// us to stop DMA playback which takes unnecessary cycles.
|
||||
if (!ConfMan.hasKey("music_driver")) {
|
||||
ConfMan.set("music_driver", "stmidi");
|
||||
}
|
||||
if (!ConfMan.hasKey("gm_device")) {
|
||||
ConfMan.set("gm_device", "auto");
|
||||
}
|
||||
if (!ConfMan.hasKey("mt32_device")) {
|
||||
ConfMan.set("mt32_device", "auto");
|
||||
}
|
||||
#endif
|
||||
|
||||
_mixerManager = new AtariMixerManager();
|
||||
// Setup and start mixer
|
||||
_mixerManager->init();
|
||||
|
||||
_startTime = counter_200hz;
|
||||
|
||||
BaseBackend::initBackend();
|
||||
}
|
||||
|
||||
void OSystem_Atari::engineInit() {
|
||||
//atari_debug("engineInit");
|
||||
|
||||
g_gameEngineActive = true;
|
||||
}
|
||||
|
||||
void OSystem_Atari::engineDone() {
|
||||
//atari_debug("engineDone");
|
||||
|
||||
g_gameEngineActive = false;
|
||||
}
|
||||
|
||||
Common::MutexInternal *OSystem_Atari::createMutex() {
|
||||
return new NullMutexInternal();
|
||||
}
|
||||
|
||||
uint32 OSystem_Atari::getMillis(bool skipRecord) {
|
||||
// CLOCKS_PER_SEC is 200, so no need to use floats
|
||||
return 1000 * (counter_200hz - _startTime) / CLOCKS_PER_SEC;
|
||||
}
|
||||
|
||||
void OSystem_Atari::delayMillis(uint msecs) {
|
||||
const uint32 threshold = getMillis() + msecs;
|
||||
while (getMillis() < threshold) {
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void OSystem_Atari::getTimeAndDate(TimeDate &td, bool skipRecord) const {
|
||||
//atari_debug("getTimeAndDate");
|
||||
time_t curTime = time(0);
|
||||
struct tm t = *localtime(&curTime);
|
||||
td.tm_sec = t.tm_sec;
|
||||
td.tm_min = t.tm_min;
|
||||
td.tm_hour = t.tm_hour;
|
||||
td.tm_mday = t.tm_mday;
|
||||
td.tm_mon = t.tm_mon;
|
||||
td.tm_year = t.tm_year;
|
||||
td.tm_wday = t.tm_wday;
|
||||
}
|
||||
|
||||
Common::KeymapArray OSystem_Atari::getGlobalKeymaps() {
|
||||
Common::KeymapArray globalMaps = BaseBackend::getGlobalKeymaps();
|
||||
|
||||
Common::Keymap *keymap = ((AtariGraphicsManager*)_graphicsManager)->getKeymap();
|
||||
globalMaps.push_back(keymap);
|
||||
|
||||
return globalMaps;
|
||||
}
|
||||
|
||||
Common::HardwareInputSet *OSystem_Atari::getHardwareInputSet() {
|
||||
Common::CompositeHardwareInputSet *inputSet = new Common::CompositeHardwareInputSet();
|
||||
inputSet->addHardwareInputSet(new Common::MouseHardwareInputSet(Common::defaultMouseButtons));
|
||||
inputSet->addHardwareInputSet(new Common::KeyboardHardwareInputSet(Common::defaultKeys, Common::defaultModifiers));
|
||||
|
||||
return inputSet;
|
||||
}
|
||||
|
||||
void OSystem_Atari::quit() {
|
||||
atari_debug("OSystem_Atari::quit()");
|
||||
|
||||
if (!s_dtor_already_called)
|
||||
destroy();
|
||||
}
|
||||
|
||||
void OSystem_Atari::fatalError() {
|
||||
atari_debug("OSystem_Atari::fatalError()");
|
||||
|
||||
quit();
|
||||
|
||||
// let exit_restore() and critical_restore() handle the recovery
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void OSystem_Atari::logMessage(LogMessageType::Type type, const char *message) {
|
||||
extern long nf_stderr_id;
|
||||
|
||||
static char str[1024+1];
|
||||
snprintf(str, sizeof(str), "[%08d] %s", getMillis(), message);
|
||||
|
||||
if (nf_stderr_id) {
|
||||
nf_print(str);
|
||||
} else {
|
||||
FILE *output = 0;
|
||||
|
||||
if (type == LogMessageType::kInfo || type == LogMessageType::kDebug)
|
||||
output = stdout;
|
||||
else
|
||||
output = stderr;
|
||||
|
||||
fputs(str, output);
|
||||
fflush(output);
|
||||
}
|
||||
}
|
||||
|
||||
void OSystem_Atari::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) {
|
||||
{
|
||||
Common::FSDirectory currentDirectory{ Common::Path(getFilesystemFactory()->makeCurrentDirectoryFileNode()->getPath()) };
|
||||
Common::FSDirectory *dataDirectory = currentDirectory.getSubDirectory("data");
|
||||
if (dataDirectory) {
|
||||
Common::FSNode dataNode = dataDirectory->getFSNode();
|
||||
if (dataNode.exists() && dataNode.isDirectory() && dataNode.isReadable()) {
|
||||
s.addDirectory(dataNode.getPath(), priority);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef DATA_PATH
|
||||
{
|
||||
// Add the global DATA_PATH to the directory search list
|
||||
// See also OSystem_SDL::addSysArchivesToSearchSet()
|
||||
Common::FSNode dataNode(DATA_PATH);
|
||||
if (dataNode.exists() && dataNode.isDirectory() && dataNode.isReadable()) {
|
||||
s.add(DATA_PATH, new Common::FSDirectory(dataNode, 4), priority);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Common::Path OSystem_Atari::getDefaultConfigFileName() {
|
||||
const Common::Path baseConfigName = OSystem::getDefaultConfigFileName();
|
||||
|
||||
const char *envVar = getenv("HOME");
|
||||
if (envVar && *envVar) {
|
||||
Common::Path configFile(envVar);
|
||||
configFile.joinInPlace(baseConfigName);
|
||||
|
||||
if (configFile.toString(Common::Path::kNativeSeparator).size() < MAXPATHLEN)
|
||||
return configFile;
|
||||
}
|
||||
|
||||
return baseConfigName;
|
||||
}
|
||||
|
||||
void OSystem_Atari::update() {
|
||||
// avoid a recursion loop if a timer callback decides to call OSystem::delayMillis()
|
||||
static bool inTimer = false;
|
||||
|
||||
if (!inTimer) {
|
||||
inTimer = true;
|
||||
((DefaultTimerManager *)_timerManager)->checkTimers();
|
||||
inTimer = false;
|
||||
} else {
|
||||
const Common::ConfigManager::Domain *activeDomain = ConfMan.getActiveDomain();
|
||||
assert(activeDomain);
|
||||
|
||||
warning("%s/%s calls update() from timer",
|
||||
activeDomain->getValOrDefault("engineid").c_str(),
|
||||
activeDomain->getValOrDefault("gameid").c_str());
|
||||
}
|
||||
|
||||
((AtariMixerManager *)_mixerManager)->update();
|
||||
}
|
||||
|
||||
OSystem *OSystem_Atari_create() {
|
||||
return new OSystem_Atari();
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
g_system = OSystem_Atari_create();
|
||||
assert(g_system);
|
||||
|
||||
// Invoke the actual ScummVM main entry point:
|
||||
int res = scummvm_main(argc, argv);
|
||||
g_system->destroy();
|
||||
|
||||
return res;
|
||||
}
|
||||
65
backends/platform/atari/osystem_atari.h
Normal file
65
backends/platform/atari/osystem_atari.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/* 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 PLATFORM_ATARI_H
|
||||
#define PLATFORM_ATARI_H
|
||||
|
||||
#include "backends/modular-backend.h"
|
||||
|
||||
class OSystem_Atari final : public ModularMixerBackend, public ModularGraphicsBackend {
|
||||
public:
|
||||
OSystem_Atari();
|
||||
virtual ~OSystem_Atari();
|
||||
|
||||
void initBackend() override;
|
||||
|
||||
void engineInit() override;
|
||||
void engineDone() override;
|
||||
|
||||
Common::MutexInternal *createMutex() override;
|
||||
uint32 getMillis(bool skipRecord = false) override;
|
||||
void delayMillis(uint msecs) override;
|
||||
void getTimeAndDate(TimeDate &td, bool skipRecord = false) const override;
|
||||
|
||||
Common::KeymapArray getGlobalKeymaps() override;
|
||||
Common::HardwareInputSet *getHardwareInputSet() override;
|
||||
|
||||
void quit() override;
|
||||
void fatalError() override;
|
||||
|
||||
void logMessage(LogMessageType::Type type, const char *message) override;
|
||||
|
||||
void addSysArchivesToSearchSet(Common::SearchSet &s, int priority) override;
|
||||
Common::Path getDefaultConfigFileName() override;
|
||||
|
||||
void update();
|
||||
|
||||
private:
|
||||
long _startTime;
|
||||
|
||||
bool _timerInitialized = false;
|
||||
|
||||
int16 _vdi_handle;
|
||||
int _vdi_width;
|
||||
int _vdi_height;
|
||||
};
|
||||
|
||||
#endif
|
||||
69
backends/platform/atari/patches/print_rate.patch
Normal file
69
backends/platform/atari/patches/print_rate.patch
Normal file
@@ -0,0 +1,69 @@
|
||||
commit 21a79a50b54df8b3c377f275e1d7bfa76ee50899
|
||||
Author: Miro Kropacek <miro.kropacek@gmail.com>
|
||||
Date: Tue Oct 31 23:48:25 2023 +0100
|
||||
|
||||
Introduce "print_rate"
|
||||
|
||||
This will never go to upstream.
|
||||
|
||||
diff --git a/audio/rate.cpp b/audio/rate.cpp
|
||||
index 7f0c50f9250..83dde41462f 100644
|
||||
--- a/audio/rate.cpp
|
||||
+++ b/audio/rate.cpp
|
||||
@@ -30,6 +30,8 @@
|
||||
#include "audio/audiostream.h"
|
||||
#include "audio/rate.h"
|
||||
#include "audio/mixer.h"
|
||||
+#include "backends/platform/atari/atari-debug.h"
|
||||
+#include "common/config-manager.h"
|
||||
#include "common/util.h"
|
||||
|
||||
namespace Audio {
|
||||
@@ -80,6 +82,20 @@ private:
|
||||
int simpleConvert(AudioStream &input, st_sample_t *outBuffer, st_size_t numSamples, st_volume_t vol_l, st_volume_t vol_r);
|
||||
int interpolateConvert(AudioStream &input, st_sample_t *outBuffer, st_size_t numSamples, st_volume_t vol_l, st_volume_t vol_r);
|
||||
|
||||
+ void printConvertType(const Common::String &name) {
|
||||
+ const Common::ConfigManager::Domain *activeDomain = ConfMan.getActiveDomain();
|
||||
+ if (activeDomain && ConfMan.getBool("print_rate")) {
|
||||
+ static st_rate_t previousInRate, previousOutRate;
|
||||
+ if (previousInRate != _inRate || previousOutRate != _outRate) {
|
||||
+ previousInRate = _inRate;
|
||||
+ previousOutRate = _outRate;
|
||||
+ atari_debug("RateConverter_Impl::%s[%s]: inRate %d Hz (%s) => outRate %d Hz (%s)",
|
||||
+ name.c_str(), activeDomain->getValOrDefault("gameid").c_str(),
|
||||
+ _inRate, inStereo ? "stereo" : "mono", _outRate, outStereo ? "stereo" : "mono");
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
public:
|
||||
RateConverter_Impl(st_rate_t inputRate, st_rate_t outputRate);
|
||||
virtual ~RateConverter_Impl() {}
|
||||
@@ -99,6 +115,8 @@ template<bool inStereo, bool outStereo, bool reverseStereo>
|
||||
int RateConverter_Impl<inStereo, outStereo, reverseStereo>::copyConvert(AudioStream &input, st_sample_t *outBuffer, st_size_t numSamples, st_volume_t volL, st_volume_t volR) {
|
||||
st_sample_t *outStart, *outEnd;
|
||||
|
||||
+ printConvertType("copyConvert");
|
||||
+
|
||||
outStart = outBuffer;
|
||||
outEnd = outBuffer + numSamples * (outStereo ? 2 : 1);
|
||||
|
||||
@@ -148,6 +166,8 @@ int RateConverter_Impl<inStereo, outStereo, reverseStereo>::simpleConvert(AudioS
|
||||
|
||||
st_sample_t *outStart, *outEnd;
|
||||
|
||||
+ printConvertType("simpleConvert");
|
||||
+
|
||||
outStart = outBuffer;
|
||||
outEnd = outBuffer + numSamples * (outStereo ? 2 : 1);
|
||||
|
||||
@@ -209,6 +229,8 @@ int RateConverter_Impl<inStereo, outStereo, reverseStereo>::interpolateConvert(A
|
||||
outStart = outBuffer;
|
||||
outEnd = outBuffer + numSamples * (outStereo ? 2 : 1);
|
||||
|
||||
+ printConvertType("interpolateConvert");
|
||||
+
|
||||
while (outBuffer < outEnd) {
|
||||
// Read enough input samples so that _outPosFrac < 0
|
||||
while ((frac_t)FRAC_ONE_LOW <= _outPosFrac) {
|
||||
268
backends/platform/atari/patches/tooltips.patch
Normal file
268
backends/platform/atari/patches/tooltips.patch
Normal file
@@ -0,0 +1,268 @@
|
||||
commit bc5168b5929bb7ce41c04aab54d71b88db432666
|
||||
Author: Miro Kropacek <miro.kropacek@gmail.com>
|
||||
Date: Sun Jun 4 14:50:49 2023 +0200
|
||||
|
||||
Don't merge: tooltips
|
||||
|
||||
diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp
|
||||
index 44d6c9487ed..cce47f9efdd 100644
|
||||
--- a/gui/ThemeEngine.cpp
|
||||
+++ b/gui/ThemeEngine.cpp
|
||||
@@ -916,7 +916,7 @@ bool ThemeEngine::loadThemeXML(const Common::String &themeId) {
|
||||
/**********************************************************
|
||||
* Draw Date descriptors drawing functions
|
||||
*********************************************************/
|
||||
-void ThemeEngine::drawDD(DrawData type, const Common::Rect &r, uint32 dynamic, bool forceRestore) {
|
||||
+void ThemeEngine::drawDD(DrawData type, const Common::Rect &r, uint32 dynamic, bool forceRestore, Common::Rect *bgRect) {
|
||||
WidgetDrawData *drawData = _widgets[type];
|
||||
|
||||
if (!drawData)
|
||||
@@ -942,6 +942,9 @@ void ThemeEngine::drawDD(DrawData type, const Common::Rect &r, uint32 dynamic, b
|
||||
// Cull the elements not in the clip rect
|
||||
if (extendedRect.isEmpty()) {
|
||||
return;
|
||||
+ } else if (bgRect) {
|
||||
+ *bgRect = extendedRect;
|
||||
+ return;
|
||||
}
|
||||
|
||||
if (forceRestore || drawData->_layer == kDrawLayerBackground)
|
||||
@@ -1177,7 +1180,7 @@ void ThemeEngine::drawScrollbar(const Common::Rect &r, int sliderY, int sliderHe
|
||||
drawDD(scrollState == kScrollbarStateSlider ? kDDScrollbarHandleHover : kDDScrollbarHandleIdle, r2);
|
||||
}
|
||||
|
||||
-void ThemeEngine::drawDialogBackground(const Common::Rect &r, DialogBackground bgtype) {
|
||||
+void ThemeEngine::drawDialogBackground(const Common::Rect &r, DialogBackground bgtype, Common::Rect *bgRect) {
|
||||
if (!ready())
|
||||
return;
|
||||
|
||||
@@ -1195,7 +1198,7 @@ void ThemeEngine::drawDialogBackground(const Common::Rect &r, DialogBackground b
|
||||
break;
|
||||
|
||||
case kDialogBackgroundTooltip:
|
||||
- drawDD(kDDTooltipBackground, r);
|
||||
+ drawDD(kDDTooltipBackground, r, 0, false, bgRect);
|
||||
break;
|
||||
|
||||
case kDialogBackgroundDefault:
|
||||
diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h
|
||||
index 940298eff25..a371c13dcd5 100644
|
||||
--- a/gui/ThemeEngine.h
|
||||
+++ b/gui/ThemeEngine.h
|
||||
@@ -53,6 +53,7 @@ class Dialog;
|
||||
class GuiObject;
|
||||
class ThemeEval;
|
||||
class ThemeParser;
|
||||
+class Tooltip;
|
||||
|
||||
/**
|
||||
* DrawData sets enumeration.
|
||||
@@ -212,6 +213,7 @@ protected:
|
||||
|
||||
friend class GUI::Dialog;
|
||||
friend class GUI::GuiObject;
|
||||
+ friend class GUI::Tooltip;
|
||||
|
||||
public:
|
||||
/// Vertical alignment of the text.
|
||||
@@ -492,7 +494,7 @@ public:
|
||||
|
||||
void drawLineSeparator(const Common::Rect &r);
|
||||
|
||||
- void drawDialogBackground(const Common::Rect &r, DialogBackground type);
|
||||
+ void drawDialogBackground(const Common::Rect &r, DialogBackground type, Common::Rect *bgRect = nullptr);
|
||||
|
||||
void drawText(const Common::Rect &r, const Common::U32String &str, WidgetStateInfo state = kStateEnabled,
|
||||
Graphics::TextAlign align = Graphics::kTextAlignCenter,
|
||||
@@ -712,7 +714,7 @@ protected:
|
||||
*
|
||||
* These functions are called from all the Widget drawing methods.
|
||||
*/
|
||||
- void drawDD(DrawData type, const Common::Rect &r, uint32 dynamic = 0, bool forceRestore = false);
|
||||
+ void drawDD(DrawData type, const Common::Rect &r, uint32 dynamic = 0, bool forceRestore = false, Common::Rect *bgRect = nullptr);
|
||||
void drawDDText(TextData type, TextColor color, const Common::Rect &r, const Common::U32String &text, bool restoreBg,
|
||||
bool elipsis, Graphics::TextAlign alignH = Graphics::kTextAlignLeft,
|
||||
TextAlignVertical alignV = kTextAlignVTop, int deltax = 0,
|
||||
diff --git a/gui/Tooltip.cpp b/gui/Tooltip.cpp
|
||||
index 79f0f9db91a..b08cc9939bc 100644
|
||||
--- a/gui/Tooltip.cpp
|
||||
+++ b/gui/Tooltip.cpp
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "gui/widget.h"
|
||||
#include "gui/dialog.h"
|
||||
#include "gui/gui-manager.h"
|
||||
+#include "graphics/VectorRenderer.h"
|
||||
|
||||
#include "gui/Tooltip.h"
|
||||
#include "gui/ThemeEval.h"
|
||||
@@ -31,7 +32,7 @@ namespace GUI {
|
||||
|
||||
|
||||
Tooltip::Tooltip() :
|
||||
- Dialog(-1, -1, -1, -1), _maxWidth(-1), _parent(nullptr), _xdelta(0), _ydelta(0), _xpadding(0), _ypadding(0) {
|
||||
+ Dialog(-1, -1, -1, -1), _maxWidth(-1), _parent(nullptr), _xdelta(0), _ydelta(0), _xpadding(0), _ypadding(0), _firstDraw(true) {
|
||||
|
||||
_backgroundType = GUI::ThemeEngine::kDialogBackgroundTooltip;
|
||||
}
|
||||
@@ -71,7 +72,40 @@ void Tooltip::drawDialog(DrawLayer layerToDraw) {
|
||||
int num = 0;
|
||||
int h = g_gui.theme()->getFontHeight(ThemeEngine::kFontStyleTooltip) + 2;
|
||||
|
||||
- Dialog::drawDialog(layerToDraw);
|
||||
+ // Dialog::drawDialog(layerToDraw)
|
||||
+ if (!isVisible())
|
||||
+ return;
|
||||
+
|
||||
+ g_gui.theme()->disableClipRect();
|
||||
+ g_gui.theme()->_layerToDraw = layerToDraw;
|
||||
+
|
||||
+ if (_firstDraw) {
|
||||
+ ThemeEngine *theme = g_gui.theme();
|
||||
+
|
||||
+ // store backgrounds from Backbuffer and Screen
|
||||
+ theme->drawDialogBackground(Common::Rect(_x, _y, _x + _w, _y + _h), _backgroundType, &_bgRect);
|
||||
+
|
||||
+ theme->drawToBackbuffer();
|
||||
+ _bgBackbufferSurf.create(_bgRect.width(), _bgRect.height(), theme->renderer()->getActiveSurface()->format);
|
||||
+ _bgBackbufferSurf.copyRectToSurface(*theme->renderer()->getActiveSurface(), 0, 0, _bgRect);
|
||||
+
|
||||
+ theme->drawToScreen();
|
||||
+ _bgScreenSurf.create(_bgRect.width(), _bgRect.height(), theme->renderer()->getActiveSurface()->format);
|
||||
+ _bgScreenSurf.copyRectToSurface(*theme->renderer()->getActiveSurface(), 0, 0, _bgRect);
|
||||
+
|
||||
+ theme->drawToBackbuffer();
|
||||
+ _firstDraw = false;
|
||||
+ }
|
||||
+
|
||||
+ g_gui.theme()->drawDialogBackground(Common::Rect(_x, _y, _x + _w, _y + _h), _backgroundType);
|
||||
+
|
||||
+ markWidgetsAsDirty();
|
||||
+
|
||||
+#ifdef LAYOUT_DEBUG_DIALOG
|
||||
+ return;
|
||||
+#endif
|
||||
+ drawWidgets();
|
||||
+ // end of Dialog::drawDialog(layerToDraw)
|
||||
|
||||
int16 textX = _x + 1 + _xpadding;
|
||||
if (g_gui.useRTL()) {
|
||||
@@ -98,4 +132,32 @@ void Tooltip::drawDialog(DrawLayer layerToDraw) {
|
||||
}
|
||||
}
|
||||
|
||||
+void Tooltip::open() {
|
||||
+ Dialog::open();
|
||||
+ g_gui._redrawStatus = GuiManager::kRedrawOpenTooltip;
|
||||
+}
|
||||
+
|
||||
+void Tooltip::close() {
|
||||
+ Dialog::close();
|
||||
+ g_gui._redrawStatus = GuiManager::kRedrawDisabled;
|
||||
+
|
||||
+ if (!_bgRect.isEmpty()) {
|
||||
+ ThemeEngine *theme = g_gui.theme();
|
||||
+
|
||||
+ theme->drawToBackbuffer();
|
||||
+ theme->renderer()->getActiveSurface()->copyRectToSurface(
|
||||
+ _bgBackbufferSurf, _bgRect.left, _bgRect.top, Common::Rect(_bgRect.width(), _bgRect.height()));
|
||||
+
|
||||
+ theme->drawToScreen();
|
||||
+ theme->renderer()->getActiveSurface()->copyRectToSurface(
|
||||
+ _bgScreenSurf, _bgRect.left, _bgRect.top, Common::Rect(_bgRect.width(), _bgRect.height()));
|
||||
+
|
||||
+ theme->addDirtyRect(_bgRect);
|
||||
+
|
||||
+ _bgRect = Common::Rect();
|
||||
+ _bgBackbufferSurf.free();
|
||||
+ _bgScreenSurf.free();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
}
|
||||
diff --git a/gui/Tooltip.h b/gui/Tooltip.h
|
||||
index 2f188764ff3..40caa7a1be4 100644
|
||||
--- a/gui/Tooltip.h
|
||||
+++ b/gui/Tooltip.h
|
||||
@@ -23,7 +23,9 @@
|
||||
#define GUI_TOOLTIP_H
|
||||
|
||||
#include "common/keyboard.h"
|
||||
+#include "common/rect.h"
|
||||
#include "common/str-array.h"
|
||||
+#include "graphics/surface.h"
|
||||
#include "gui/dialog.h"
|
||||
|
||||
namespace GUI {
|
||||
@@ -43,6 +45,9 @@ public:
|
||||
|
||||
void receivedFocus(int x = -1, int y = -1) override {}
|
||||
protected:
|
||||
+ void open() override;
|
||||
+ void close() override;
|
||||
+
|
||||
void handleMouseDown(int x, int y, int button, int clickCount) override {
|
||||
close();
|
||||
_parent->handleMouseDown(x + (getAbsX() - _parent->getAbsX()), y + (getAbsY() - _parent->getAbsY()), button, clickCount);
|
||||
@@ -72,6 +77,11 @@ protected:
|
||||
int _xpadding, _ypadding;
|
||||
|
||||
Common::U32StringArray _wrappedLines;
|
||||
+
|
||||
+ bool _firstDraw;
|
||||
+ Common::Rect _bgRect;
|
||||
+ Graphics::Surface _bgBackbufferSurf;
|
||||
+ Graphics::Surface _bgScreenSurf;
|
||||
};
|
||||
|
||||
} // End of namespace GUI
|
||||
diff --git a/gui/gui-manager.cpp b/gui/gui-manager.cpp
|
||||
index 02de69aa7c9..da57fdb2973 100644
|
||||
--- a/gui/gui-manager.cpp
|
||||
+++ b/gui/gui-manager.cpp
|
||||
@@ -453,6 +453,9 @@ void GuiManager::redrawInternal() {
|
||||
_theme->applyScreenShading(shading);
|
||||
}
|
||||
|
||||
+ // fall through
|
||||
+
|
||||
+ case kRedrawOpenTooltip:
|
||||
// Finally, draw the top dialog background
|
||||
_dialogStack.top()->drawDialog(kDrawLayerBackground);
|
||||
|
||||
@@ -753,8 +756,6 @@ void GuiManager::closeTopDialog() {
|
||||
|
||||
if (_redrawStatus != kRedrawFull)
|
||||
_redrawStatus = kRedrawCloseDialog;
|
||||
-
|
||||
- redraw();
|
||||
}
|
||||
|
||||
void GuiManager::setupCursor() {
|
||||
diff --git a/gui/gui-manager.h b/gui/gui-manager.h
|
||||
index 0718f631c8b..e8b646ec46c 100644
|
||||
--- a/gui/gui-manager.h
|
||||
+++ b/gui/gui-manager.h
|
||||
@@ -62,6 +62,7 @@ enum {
|
||||
|
||||
class Dialog;
|
||||
class ThemeEval;
|
||||
+class Tooltip;
|
||||
class GuiObject;
|
||||
|
||||
#define g_gui (GUI::GuiManager::instance())
|
||||
@@ -82,6 +83,7 @@ typedef Common::FixedStack<Dialog *> DialogStack;
|
||||
*/
|
||||
class GuiManager : public Common::Singleton<GuiManager>, public CommandSender {
|
||||
friend class Dialog;
|
||||
+ friend class Tooltip;
|
||||
friend class Common::Singleton<SingletonBaseType>;
|
||||
GuiManager();
|
||||
~GuiManager() override;
|
||||
@@ -159,6 +161,7 @@ protected:
|
||||
enum RedrawStatus {
|
||||
kRedrawDisabled = 0,
|
||||
kRedrawOpenDialog,
|
||||
+ kRedrawOpenTooltip,
|
||||
kRedrawCloseDialog,
|
||||
kRedrawTopDialog,
|
||||
kRedrawFull
|
||||
535
backends/platform/atari/readme.txt
Normal file
535
backends/platform/atari/readme.txt
Normal file
@@ -0,0 +1,535 @@
|
||||
ScummVM 2026.1.1git
|
||||
=============
|
||||
|
||||
This is a port of ScummVM (https://www.scummvm.org), a program which allows you
|
||||
to run certain classic graphical adventure and role-playing games, provided you
|
||||
already have their data files.
|
||||
|
||||
You can find a full list with details on which games are supported and how well
|
||||
on the compatibility page: https://www.scummvm.org/compatibility.
|
||||
|
||||
|
||||
New port?
|
||||
---------
|
||||
|
||||
Keith Scroggins (aka KeithS) has been providing ScummVM (and many other) builds
|
||||
for the Atari community for an unbelievable 17 years. He put quite a lot of time
|
||||
into testing each release, updating ScummVM dependencies to their latest
|
||||
versions and even regularly upgrading his compiler toolchain to get the best
|
||||
possible performance.
|
||||
|
||||
However, ScummVM (and SDL to some extent) is a beast; it requires quite a lot
|
||||
of attention regarding where the cycles go, e.g. an additional screen refresh
|
||||
can easily drop the frame rate by half.
|
||||
|
||||
After I had seen how snappy NovaCoder's ScummVM on the Amiga is (who coded his
|
||||
own backend), I decided to check whether there was a way to get a better
|
||||
performing port on our platform. And there is!
|
||||
|
||||
I have managed to create a "native" Atari port talking directly to the
|
||||
hardware, skipping the SDL layer altogether, which is in some cases usable even
|
||||
on a plain 32 MHz Atari TT.
|
||||
|
||||
|
||||
Differences between the versions
|
||||
--------------------------------
|
||||
|
||||
After talking to Keith we have decided to provide three flavours of ScummVM.
|
||||
Please refer to https://docs.scummvm.org/en/v2026.1.1git/other_platforms/atari.html
|
||||
for more details (TBD).
|
||||
|
||||
Atari Full package
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Minimum hardware requirements: Atari Falcon with 4 + 64 MB RAM, 68040 CPU.
|
||||
|
||||
- Because there is limited horsepower available on our platform, features like
|
||||
16bpp graphics, software synthesisers, scalers, real-time software
|
||||
MP3/OGG/FLAC playback etc., are omitted. This saves CPU cycles, memory and
|
||||
disk space.
|
||||
|
||||
- Tailored video settings for the best possible performance and visual
|
||||
experience (Falcon RGB overscan, chunky modes with the SuperVidel, TT 640x480
|
||||
for the overlay, ...).
|
||||
|
||||
- Direct rendering and single/triple buffering support.
|
||||
|
||||
- Blitting routines optimised for 68040 / 68060 CPU.
|
||||
|
||||
- Custom (and optimal) surface drawing (especially for the cursor).
|
||||
|
||||
- Custom (hardware based) aspect ratio correction (!)
|
||||
|
||||
- Full support for the SuperVidel, including the SuperBlitter (!)
|
||||
|
||||
- External DSP clock support for playing back samples at PC frequencies
|
||||
(Falcon only). Dual clock input frequency supported as well (Steinberg's
|
||||
FDI).
|
||||
|
||||
- Support for PC keys (page up, page down, pause, F11/F12, ...) and mouse wheel
|
||||
(Eiffel/Aranym only).
|
||||
|
||||
- Native MIDI output (if present).
|
||||
|
||||
- Runs also in Hatari and ARAnyM but in case of ARAnyM don't forget to disable
|
||||
fVDI to enable Videl output.
|
||||
|
||||
- FreeMiNT + memory protection friendly.
|
||||
|
||||
Atari Lite package
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Minimum hardware requirements: Atari TT / Falcon with 4 + 32 MB RAM.
|
||||
|
||||
As a further optimisation step, a 030-only version of ScummVM is provided, aimed
|
||||
at less powerful TT and Falcon machines with the 68030 CPU. It further restricts
|
||||
features but also improves performance and reduces executable size.
|
||||
|
||||
- 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 background => even faster redraw.
|
||||
|
||||
- Overlay doesn't support alternative themes => faster loading time.
|
||||
|
||||
- "STMIDI" driver is automatically enabled (i.e. MIDI emulation is never used
|
||||
but still allows playing speech/sfx samples and/or CD audio).
|
||||
|
||||
FireBee package
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Hardware requirements: MCF5475 Evaluation Board or FireBee.
|
||||
|
||||
This one is still built and provided by Keith.
|
||||
|
||||
- Based on the most recent SDL.
|
||||
|
||||
- Contains various optimisations discovered / implemented from the Atari
|
||||
backend.
|
||||
|
||||
- Works in GEM (in theory also in XBIOS but that seems to be still broken on
|
||||
FireBee).
|
||||
|
||||
- Support for all engines is included in the build; this does not mean all
|
||||
games work. For instance, support for OGG and MP3 audio is included but the
|
||||
system can not handle playback of compressed audio; there is not enough
|
||||
processing power for both gameplay and sound at the same time.
|
||||
|
||||
Scalers can be utilized to make the GEM window larger on the Firebee.
|
||||
Performance is best when not using AdLib sound; using STMIDI would be
|
||||
optimal, but untested as of yet (I have been unable to get MIDI to work on my
|
||||
FireBee).
|
||||
|
||||
- Removed features: FLAC, MPEG2, Network/Cloud Support, HQ Scalers.
|
||||
|
||||
|
||||
The rest of this document describes things specific to the Full / Lite package.
|
||||
For the FireBee (SDL) build please refer to generic ScummVM documentation.
|
||||
|
||||
|
||||
Platform-specific features outside the GUI
|
||||
------------------------------------------
|
||||
|
||||
Keyboard shortcut "CONTROL+ALT+a": immediate aspect ratio correction on/off
|
||||
toggle.
|
||||
|
||||
"output_rate" in scummvm.ini: sample rate for mixing. Allowed values depend on
|
||||
the hardware connected:
|
||||
- TT030: 50066, 25033, 12517, 6258 Hz
|
||||
- Falcon030: as TT030 (except 6258) plus 49170, 32780, 24585, 19668, 16390,
|
||||
12292, 9834, 8195 Hz
|
||||
- External 22.5792 MHz DSP clock: as Falcon030 plus 44100, 29400, 22050,
|
||||
17640, 14700, 11025, 8820, 7350 Hz
|
||||
- External 24.576 MHz DSP clock: as Falcon030 plus 48000, 32000, 24000,
|
||||
19200, 16000, 12000, 9600, 8000 Hz
|
||||
The lower the value, the faster the mixing but also worse quality. Default is
|
||||
24585/25033 Hz (16-bit, stereo). Please note you don't have to enter the value
|
||||
exactly, it will be rounded to the nearest sane value.
|
||||
|
||||
"output_channels" in scummvm.ini: mono (1) or stereo (2) mixing. Please note
|
||||
that Falcon doesn't allow mixing in 16-bit mono, so this will have no effect on
|
||||
this machine.
|
||||
|
||||
"print_rate" in scummvm.ini: used for optimising sample playback (where
|
||||
available). It prints input and output sample format as well as the name of the
|
||||
converter used. See below for details.
|
||||
|
||||
"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
|
||||
most games on my CT60@66 MHz.
|
||||
|
||||
If you want to play with "audio_buffer_size", the rule of thumb is: (lag in ms)
|
||||
= (audio_buffer_size / output_rate) * 1000. But it's totally OK just to double
|
||||
the samples value to get rid of stuttering in a heavier game.
|
||||
|
||||
|
||||
Graphics modes
|
||||
--------------
|
||||
|
||||
This topic is more complex than it looks. ScummVM renders game graphics using
|
||||
rectangles and this port offers the following options to render them:
|
||||
|
||||
Direct rendering
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
This is direct writing of the pixels into the screen buffer. On SuperVidel it is
|
||||
done natively, on Videl a chunky to planar conversion takes place beforehand.
|
||||
|
||||
Pros:
|
||||
|
||||
- On SuperVidel this offers fastest possible rendering (especially in 640x480
|
||||
with a lot of small rectangle updates where the buffer copying drags
|
||||
performance down).
|
||||
|
||||
- On Videl this _may_ offer fastest possible rendering if the rendering
|
||||
pipeline isn't flooded with too many small rectangles (C2P setup isn't for
|
||||
free). However with fullscreen intro sequences this is a no-brainer.
|
||||
|
||||
Cons:
|
||||
|
||||
- Screen tearing in most cases.
|
||||
|
||||
- On Videl, this may not work properly if a game engine uses its own buffers
|
||||
instead of surfaces (which are aligned on a 16pix boundary). Another source
|
||||
of danger is if an engine draws directly to the screen surface. Fortunately,
|
||||
each game can have its own graphics mode set separately so for games which do
|
||||
not work properly one can still leave the default graphics mode set.
|
||||
|
||||
- On Videl, overlay background isn't rendered (the GUI code can't work with
|
||||
bitplanes).
|
||||
|
||||
SuperBlitter used: sometimes (when ScummVM allocates surface via its create()
|
||||
function; custom/small buffers originating in the engine code are still copied
|
||||
using the CPU).
|
||||
|
||||
Single buffering
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
This is very similar to the previous mode with the difference that the engine
|
||||
uses an intermediate buffer for storing the rectangles but yet it remembers
|
||||
which ones they were.
|
||||
|
||||
Pros:
|
||||
|
||||
- Second fastest possible rendering.
|
||||
|
||||
Cons:
|
||||
|
||||
- Screen tearing in most cases.
|
||||
|
||||
- If there are too many smaller rectangles, it can be less efficient than
|
||||
updating the whole buffer at once.
|
||||
|
||||
SuperBlitter used: yes, for rectangle blitting to screen and cursor
|
||||
restoration. Sometimes also for generic copying between buffers (see above).
|
||||
|
||||
Triple buffering
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
This is the "true" triple buffering as described in
|
||||
https://en.wikipedia.org/wiki/Multiple_buffering#Triple_buffering and not "swap
|
||||
chain" as described in https://en.wikipedia.org/wiki/Swap_chain. The latter
|
||||
would be slightly slower as three buffers would need to be updated instead of
|
||||
two.
|
||||
|
||||
Pros:
|
||||
|
||||
- No screen tearing.
|
||||
|
||||
- Best compromise between performance and visual experience.
|
||||
|
||||
- Works well with both higher and lower frame rates.
|
||||
|
||||
Cons:
|
||||
|
||||
- If there are too many smaller rectangles, it can be less efficient than
|
||||
single buffering.
|
||||
|
||||
- Slightly irregular frame rate (depends solely on the game's complexity).
|
||||
|
||||
- In case of extremely fast rendering, one or more frames are dropped in favour
|
||||
of showing only the most recent one.
|
||||
|
||||
SuperBlitter used: yes, for rectangle blitting to screen and cursor
|
||||
restoration. Sometimes also for generic copying between buffers (see above).
|
||||
|
||||
Triple buffering is the default mode.
|
||||
|
||||
|
||||
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:
|
||||
|
||||
- Uses 8bpp chunky resolutions.
|
||||
|
||||
- Patches all surface addresses by OR'ing 0xA0000000, i.e. using SV RAM instead
|
||||
of slow ST RAM (and even instead of TT RAM for allowing pure SuperBlitter
|
||||
copying).
|
||||
|
||||
- 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 sometimes leads to nearly zero-cost rendering
|
||||
and makes a *huge* difference for 640x480 fullscreen updates.
|
||||
|
||||
|
||||
Aspect ratio correction
|
||||
-----------------------
|
||||
|
||||
Please refer to the official documentation about its usage. Normally ScummVM
|
||||
implements this functionality using yet another fullscreen transformation of
|
||||
320x200 surface into a 320x240 one (there is even a selection of algorithms for
|
||||
this task, varying in performance and quality).
|
||||
|
||||
Naturally, this would impose a terrible performance penalty on our backend so
|
||||
some cheating has been used:
|
||||
|
||||
- On RGB, the vertical refresh rate frequency is set to 60 Hz, creating an
|
||||
illusion of non-square pixels. Works best on CRT monitors.
|
||||
|
||||
- On VGA, the vertical refresh rate frequency is set to 70 Hz, with more or
|
||||
less the same effect as on RGB. Works best on CRT monitors.
|
||||
|
||||
- On SuperVidel, video output is modified in such way that the DVI/HDMI monitor
|
||||
receives a 320x200 image and if properly set/supported, it will automatically
|
||||
stretch the image to 320x240 (this is usually a setting called "picture
|
||||
expansion" or "picture stretch" -- make sure it isn't set to something like
|
||||
"1:1" or "dot by dot").
|
||||
|
||||
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.
|
||||
|
||||
|
||||
Audio mixing
|
||||
------------
|
||||
|
||||
ScummVM works internally with 16-bit samples so on the TT a simple downsampling
|
||||
to 8-bit resolution is used. However, there is still one piece missing - an
|
||||
XBIOS emulator (so ScummVM doesn't have to access hardware directly). There are
|
||||
two options (both available from https://mikrosk.github.io/xbios): STFA and
|
||||
X-SOUND, any of these will do. Or executing ScummVM in EmuTOS which contains
|
||||
the same routines as X-SOUND.
|
||||
|
||||
|
||||
Performance considerations/pitfalls
|
||||
-----------------------------------
|
||||
|
||||
It's important to understand what affects performance on our limited platform to
|
||||
avoid unpleasant gaming experiences.
|
||||
|
||||
Game engines with unexpected performance hit
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
A typical example from this category is Gobliiins (and its sequels), some SCI
|
||||
engine games (Gabriel Knight, Larry 2/7, ...) or the Sherlock engine (The Case
|
||||
of the Rose Tattoo). At first it looks like our machine or Atari backend is
|
||||
doing something terribly wrong but the truth is that it is the engine itself
|
||||
which is doing a lot of redraws, sometimes even before reaching the backend.
|
||||
The only solution is to profile and fix those engines.
|
||||
|
||||
Too many fullscreen updates
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Somewhat related to the previous point - sometimes the engine authors didn't
|
||||
realise the impact of every update on the overall performance and instead of
|
||||
updating only the rectangles that really had changed, they ask for a fullscreen
|
||||
update. Not a problem on a >1 GHz machine but very visible on Atari! Also, this
|
||||
is (by definition) the case of animated intros, especially those in 640x480.
|
||||
|
||||
MIDI vs. AdLib vs. sampled music
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
It could seem that sampled music replay must be the most demanding one but on
|
||||
the contrary! Always choose a CD version of a game (with *.wav tracks) over 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
|
||||
(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 TT, in most cases it makes sense to use ScummVM only if you own a native
|
||||
MIDI synthesiser (like mt32-pi: https://github.com/dwhinham/mt32-pi). MIDI
|
||||
emulation is out of the question and downsampling to 8-bit resolution takes a
|
||||
good chunk of CPU time which could be utilised elsewhere. However, there are
|
||||
games which are fine with sampled music/speech even on a plain TT (e.g. Lands
|
||||
of Lore).
|
||||
|
||||
CD music slows everything down
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Some games use separate audio *and* video streams (files). Even if the CPU is
|
||||
able to handle both, the bottleneck becomes ... disk access. This is visible in
|
||||
The Curse Of Monkey Island for example -- there's audible stuttering during the
|
||||
intro sequence (and during the game as well). Increasing "audio_buffer_size"
|
||||
makes the rendering literally crawl! Why? Because disk I/O is busy with loading
|
||||
even *more* sample data so there's less time for video loading and rendering.
|
||||
Try to put "musdisk1.bun" and "musdisk2.bun" into a ramdisk (i.e. symlink to
|
||||
u:/ram in FreeMiNT), you'll be pleasantly surprised with the performance boost
|
||||
gained.
|
||||
|
||||
Mute vs. "No music"
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Currently ScummVM requires each backend to mix samples, even though they may
|
||||
contain muted output (i.e. zeroes). This is because the progression of sample
|
||||
playback tells ScummVM how much time has passed in e.g. an animation.
|
||||
|
||||
"No music" means using the null audio plugin which prevents generating any MIDI
|
||||
music (and therefore avoiding the expensive synthesis emulation) but beware, it
|
||||
doesn't affect CD (*.wav) playback at all! Same applies for speech and sfx.
|
||||
|
||||
The least amount of cycles is spent when:
|
||||
- "No music" as "Preferred device": This prevents MIDI synthesis of any kind.
|
||||
- "Subtitles" as "Text and speech": This prevents any sampled speech to be
|
||||
mixed.
|
||||
- All external audio files are deleted (typically *.wav); that way the mixer
|
||||
won't have anything to mix. However beware, this is not allowed in every game!
|
||||
|
||||
Sample rate
|
||||
~~~~~~~~~~~
|
||||
|
||||
It's important to realise the impact the sample rate has on the given game. The
|
||||
most obvious setting is its value: the bigger, the more demanding audio mixing
|
||||
becomes. However, if you inspect many games' samples, you will notice that most
|
||||
of them (esp. the ones from the 80s/90s) use simple samples like mono 11025 Hz
|
||||
(sometimes even less).
|
||||
|
||||
Obviously, setting "output_channels" to "1" is the easiest improvement
|
||||
(unfortunately only on TT). Next best thing you can do is to buy an external
|
||||
DSP clock for your Falcon: nearly all games use sample frequencies which are
|
||||
multiples of 44100 Hz: 22050, 11025, ... so with the external clock there
|
||||
won't be the need to resample them.
|
||||
|
||||
There's one caveat, though: it is important whether your replay frequency is
|
||||
equal to, a multiple of, or other than the desired one. Let's consider 44100
|
||||
and 22050 frequencies as an example (also applies to all the other
|
||||
frequencies):
|
||||
|
||||
- If you set 44100 Hz and a game requests 44100 Hz => so called "copyConvert"
|
||||
method will be used (fastest).
|
||||
- If you set 22050 Hz and a game requests 44100 Hz => so called "simpleConvert"
|
||||
method will be used (skipping every second sample, second fastest).
|
||||
- If you set 44100 Hz and a game requests 22050 Hz => so called
|
||||
"interpolateConvert" method will be used (slowest!).
|
||||
- Any other combination: "interpolateConvert" (slowest).
|
||||
|
||||
So how do you know which frequency to set as "output_rate" ? This is where
|
||||
"print_rate" comes to rescue. Enabling this option in scummvm.ini will tell you
|
||||
for each game which sample converters are being used and for what input/values.
|
||||
So you can easily verify whether the given game's demands match your setting.
|
||||
|
||||
Unfortunately, currently per-game "output_rate" / "output_channels" is not
|
||||
possible but this may change in the future.
|
||||
|
||||
Slow GUI
|
||||
~~~~~~~~
|
||||
|
||||
Themes handling is quite slow - each theme must be depacked, each one contains
|
||||
quite a few XML files to parse and quite a few images to load/convert. That's
|
||||
the reason why the built-in one is used as default, it dramatically speeds up
|
||||
loading time. To speed things up in other cases, the full version is
|
||||
distributed with repackaged theme files with compression level zero.
|
||||
|
||||
|
||||
Changes to upstream
|
||||
-------------------
|
||||
|
||||
There are a few features that have been disabled or changed and are not possible
|
||||
/ plausible to merge into upstream:
|
||||
|
||||
- the aforementioned "print_rate" feature, too invasive for other platforms
|
||||
|
||||
- This port contains an implementation of much faster tooltips in the overlay.
|
||||
However, there is a minor rendering bug which sometimes corrupts the
|
||||
background. But since its impact is huge, I left it in.
|
||||
|
||||
|
||||
Known issues
|
||||
------------
|
||||
|
||||
- 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.
|
||||
|
||||
- Horizontal screen shaking doesn't work on TT because TT Shifter doesn't
|
||||
support fine scrolling. However it is "emulated" via vertical shaking.
|
||||
|
||||
- Aspect ratio correction has no effect on TT because it is not possible to
|
||||
alter its vertical screen refresh frequency.
|
||||
|
||||
- The talkie version of SOMI needs to be merged from two sources:
|
||||
- The DOS version (install.bat) to obtain file "monster.sou".
|
||||
- The FLAC version (install_flac.bat) to obtain folders "cd_music_flac" and
|
||||
"se_music_flac" (these *.flac files then have to be converted to *.wav
|
||||
manually).
|
||||
- Files "monkey.000" and "monkey.001" can be taken from either version.
|
||||
- Point the extra path to the folder with *.wav files (or copy its content
|
||||
where monkey.00? files are located).
|
||||
|
||||
- Following engines have been explicitly disabled:
|
||||
- Cine (2 games)
|
||||
- Incompatible with other engines / prone to freezes.
|
||||
- https://wiki.scummvm.org/index.php?title=Cine
|
||||
- Director (many games)
|
||||
- Huge game list slows detection for other games, and would require
|
||||
(currently missing) localization support.
|
||||
- Only small subset of games actually supported by upstream, but none of
|
||||
them detected on TOS 8+3 file system.
|
||||
- https://wiki.scummvm.org/index.php?title=Director
|
||||
- Hugo (3 games)
|
||||
- Uses (lot of) overlay dialogs which are problematic for Atari backend.
|
||||
- Engine GUI (for save/load/etc) does not support 8-bit screens.
|
||||
- https://wiki.scummvm.org/index.php?title=Hugo
|
||||
- Ultima (many games)
|
||||
- The only non-hires ultima engine is ultima1; see
|
||||
https://bugs.scummvm.org/ticket/14790
|
||||
- This prevents adding the 15 MB ultima.dat to the release archive.
|
||||
- https://wiki.scummvm.org/index.php?title=Ultima
|
||||
|
||||
- When using FreeMiNT, ScummVM requires a recent kernel (>= 2021), otherwise
|
||||
keyboard handling won't work properly.
|
||||
|
||||
- When using EmuTOS, ScummVM requires a recent release (>= 1.3), otherwise
|
||||
various screen- and sound-related issues may appear.
|
||||
|
||||
Future plans
|
||||
------------
|
||||
|
||||
- DSP-based sample mixer (WAV, FLAC, MP2).
|
||||
|
||||
- Avoid loading music/speech files (and thus slowing down everything) if muted.
|
||||
|
||||
- Cached audio/video streams (i.e. don't load only "audio_buffer_size" number
|
||||
of samples but cache, say, 1 second so disk i/o won't be so stressed).
|
||||
|
||||
- Using Thorsten Otto's sharedlibs: https://tho-otto.de/sharedlibs.php for game
|
||||
engine plugins to relieve the huge binary size.
|
||||
|
||||
- True audio CD support via MetaDOS API.
|
||||
|
||||
- OPL2LPT and Retrowave support (if I manage to purchase it somewhere).
|
||||
|
||||
|
||||
Closing words
|
||||
-------------
|
||||
|
||||
Many optimisations and improvements wouldn't be possible without the help of
|
||||
Eero Tamminen, so thank you for all the help with profiling in Hatari.
|
||||
|
||||
Miro Kropacek aka MiKRO
|
||||
Brisbane / Australia
|
||||
miro.kropacek@gmail.com
|
||||
http://mikro.atari.org
|
||||
535
backends/platform/atari/readme.txt.in
Normal file
535
backends/platform/atari/readme.txt.in
Normal file
@@ -0,0 +1,535 @@
|
||||
ScummVM @VERSION@
|
||||
=============
|
||||
|
||||
This is a port of ScummVM (https://www.scummvm.org), a program which allows you
|
||||
to run certain classic graphical adventure and role-playing games, provided you
|
||||
already have their data files.
|
||||
|
||||
You can find a full list with details on which games are supported and how well
|
||||
on the compatibility page: https://www.scummvm.org/compatibility.
|
||||
|
||||
|
||||
New port?
|
||||
---------
|
||||
|
||||
Keith Scroggins (aka KeithS) has been providing ScummVM (and many other) builds
|
||||
for the Atari community for an unbelievable 17 years. He put quite a lot of time
|
||||
into testing each release, updating ScummVM dependencies to their latest
|
||||
versions and even regularly upgrading his compiler toolchain to get the best
|
||||
possible performance.
|
||||
|
||||
However, ScummVM (and SDL to some extent) is a beast; it requires quite a lot
|
||||
of attention regarding where the cycles go, e.g. an additional screen refresh
|
||||
can easily drop the frame rate by half.
|
||||
|
||||
After I had seen how snappy NovaCoder's ScummVM on the Amiga is (who coded his
|
||||
own backend), I decided to check whether there was a way to get a better
|
||||
performing port on our platform. And there is!
|
||||
|
||||
I have managed to create a "native" Atari port talking directly to the
|
||||
hardware, skipping the SDL layer altogether, which is in some cases usable even
|
||||
on a plain 32 MHz Atari TT.
|
||||
|
||||
|
||||
Differences between the versions
|
||||
--------------------------------
|
||||
|
||||
After talking to Keith we have decided to provide three flavours of ScummVM.
|
||||
Please refer to https://docs.scummvm.org/en/v@VERSION@/other_platforms/atari.html
|
||||
for more details (TBD).
|
||||
|
||||
Atari Full package
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Minimum hardware requirements: Atari Falcon with 4 + 64 MB RAM, 68040 CPU.
|
||||
|
||||
- Because there is limited horsepower available on our platform, features like
|
||||
16bpp graphics, software synthesisers, scalers, real-time software
|
||||
MP3/OGG/FLAC playback etc., are omitted. This saves CPU cycles, memory and
|
||||
disk space.
|
||||
|
||||
- Tailored video settings for the best possible performance and visual
|
||||
experience (Falcon RGB overscan, chunky modes with the SuperVidel, TT 640x480
|
||||
for the overlay, ...).
|
||||
|
||||
- Direct rendering and single/triple buffering support.
|
||||
|
||||
- Blitting routines optimised for 68040 / 68060 CPU.
|
||||
|
||||
- Custom (and optimal) surface drawing (especially for the cursor).
|
||||
|
||||
- Custom (hardware based) aspect ratio correction (!)
|
||||
|
||||
- Full support for the SuperVidel, including the SuperBlitter (!)
|
||||
|
||||
- External DSP clock support for playing back samples at PC frequencies
|
||||
(Falcon only). Dual clock input frequency supported as well (Steinberg's
|
||||
FDI).
|
||||
|
||||
- Support for PC keys (page up, page down, pause, F11/F12, ...) and mouse wheel
|
||||
(Eiffel/Aranym only).
|
||||
|
||||
- Native MIDI output (if present).
|
||||
|
||||
- Runs also in Hatari and ARAnyM but in case of ARAnyM don't forget to disable
|
||||
fVDI to enable Videl output.
|
||||
|
||||
- FreeMiNT + memory protection friendly.
|
||||
|
||||
Atari Lite package
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Minimum hardware requirements: Atari TT / Falcon with 4 + 32 MB RAM.
|
||||
|
||||
As a further optimisation step, a 030-only version of ScummVM is provided, aimed
|
||||
at less powerful TT and Falcon machines with the 68030 CPU. It further restricts
|
||||
features but also improves performance and reduces executable size.
|
||||
|
||||
- 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 background => even faster redraw.
|
||||
|
||||
- Overlay doesn't support alternative themes => faster loading time.
|
||||
|
||||
- "STMIDI" driver is automatically enabled (i.e. MIDI emulation is never used
|
||||
but still allows playing speech/sfx samples and/or CD audio).
|
||||
|
||||
FireBee package
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Hardware requirements: MCF5475 Evaluation Board or FireBee.
|
||||
|
||||
This one is still built and provided by Keith.
|
||||
|
||||
- Based on the most recent SDL.
|
||||
|
||||
- Contains various optimisations discovered / implemented from the Atari
|
||||
backend.
|
||||
|
||||
- Works in GEM (in theory also in XBIOS but that seems to be still broken on
|
||||
FireBee).
|
||||
|
||||
- Support for all engines is included in the build; this does not mean all
|
||||
games work. For instance, support for OGG and MP3 audio is included but the
|
||||
system can not handle playback of compressed audio; there is not enough
|
||||
processing power for both gameplay and sound at the same time.
|
||||
|
||||
Scalers can be utilized to make the GEM window larger on the Firebee.
|
||||
Performance is best when not using AdLib sound; using STMIDI would be
|
||||
optimal, but untested as of yet (I have been unable to get MIDI to work on my
|
||||
FireBee).
|
||||
|
||||
- Removed features: FLAC, MPEG2, Network/Cloud Support, HQ Scalers.
|
||||
|
||||
|
||||
The rest of this document describes things specific to the Full / Lite package.
|
||||
For the FireBee (SDL) build please refer to generic ScummVM documentation.
|
||||
|
||||
|
||||
Platform-specific features outside the GUI
|
||||
------------------------------------------
|
||||
|
||||
Keyboard shortcut "CONTROL+ALT+a": immediate aspect ratio correction on/off
|
||||
toggle.
|
||||
|
||||
"output_rate" in scummvm.ini: sample rate for mixing. Allowed values depend on
|
||||
the hardware connected:
|
||||
- TT030: 50066, 25033, 12517, 6258 Hz
|
||||
- Falcon030: as TT030 (except 6258) plus 49170, 32780, 24585, 19668, 16390,
|
||||
12292, 9834, 8195 Hz
|
||||
- External 22.5792 MHz DSP clock: as Falcon030 plus 44100, 29400, 22050,
|
||||
17640, 14700, 11025, 8820, 7350 Hz
|
||||
- External 24.576 MHz DSP clock: as Falcon030 plus 48000, 32000, 24000,
|
||||
19200, 16000, 12000, 9600, 8000 Hz
|
||||
The lower the value, the faster the mixing but also worse quality. Default is
|
||||
24585/25033 Hz (16-bit, stereo). Please note you don't have to enter the value
|
||||
exactly, it will be rounded to the nearest sane value.
|
||||
|
||||
"output_channels" in scummvm.ini: mono (1) or stereo (2) mixing. Please note
|
||||
that Falcon doesn't allow mixing in 16-bit mono, so this will have no effect on
|
||||
this machine.
|
||||
|
||||
"print_rate" in scummvm.ini: used for optimising sample playback (where
|
||||
available). It prints input and output sample format as well as the name of the
|
||||
converter used. See below for details.
|
||||
|
||||
"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
|
||||
most games on my CT60@66 MHz.
|
||||
|
||||
If you want to play with "audio_buffer_size", the rule of thumb is: (lag in ms)
|
||||
= (audio_buffer_size / output_rate) * 1000. But it's totally OK just to double
|
||||
the samples value to get rid of stuttering in a heavier game.
|
||||
|
||||
|
||||
Graphics modes
|
||||
--------------
|
||||
|
||||
This topic is more complex than it looks. ScummVM renders game graphics using
|
||||
rectangles and this port offers the following options to render them:
|
||||
|
||||
Direct rendering
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
This is direct writing of the pixels into the screen buffer. On SuperVidel it is
|
||||
done natively, on Videl a chunky to planar conversion takes place beforehand.
|
||||
|
||||
Pros:
|
||||
|
||||
- On SuperVidel this offers fastest possible rendering (especially in 640x480
|
||||
with a lot of small rectangle updates where the buffer copying drags
|
||||
performance down).
|
||||
|
||||
- On Videl this _may_ offer fastest possible rendering if the rendering
|
||||
pipeline isn't flooded with too many small rectangles (C2P setup isn't for
|
||||
free). However with fullscreen intro sequences this is a no-brainer.
|
||||
|
||||
Cons:
|
||||
|
||||
- Screen tearing in most cases.
|
||||
|
||||
- On Videl, this may not work properly if a game engine uses its own buffers
|
||||
instead of surfaces (which are aligned on a 16pix boundary). Another source
|
||||
of danger is if an engine draws directly to the screen surface. Fortunately,
|
||||
each game can have its own graphics mode set separately so for games which do
|
||||
not work properly one can still leave the default graphics mode set.
|
||||
|
||||
- On Videl, overlay background isn't rendered (the GUI code can't work with
|
||||
bitplanes).
|
||||
|
||||
SuperBlitter used: sometimes (when ScummVM allocates surface via its create()
|
||||
function; custom/small buffers originating in the engine code are still copied
|
||||
using the CPU).
|
||||
|
||||
Single buffering
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
This is very similar to the previous mode with the difference that the engine
|
||||
uses an intermediate buffer for storing the rectangles but yet it remembers
|
||||
which ones they were.
|
||||
|
||||
Pros:
|
||||
|
||||
- Second fastest possible rendering.
|
||||
|
||||
Cons:
|
||||
|
||||
- Screen tearing in most cases.
|
||||
|
||||
- If there are too many smaller rectangles, it can be less efficient than
|
||||
updating the whole buffer at once.
|
||||
|
||||
SuperBlitter used: yes, for rectangle blitting to screen and cursor
|
||||
restoration. Sometimes also for generic copying between buffers (see above).
|
||||
|
||||
Triple buffering
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
This is the "true" triple buffering as described in
|
||||
https://en.wikipedia.org/wiki/Multiple_buffering#Triple_buffering and not "swap
|
||||
chain" as described in https://en.wikipedia.org/wiki/Swap_chain. The latter
|
||||
would be slightly slower as three buffers would need to be updated instead of
|
||||
two.
|
||||
|
||||
Pros:
|
||||
|
||||
- No screen tearing.
|
||||
|
||||
- Best compromise between performance and visual experience.
|
||||
|
||||
- Works well with both higher and lower frame rates.
|
||||
|
||||
Cons:
|
||||
|
||||
- If there are too many smaller rectangles, it can be less efficient than
|
||||
single buffering.
|
||||
|
||||
- Slightly irregular frame rate (depends solely on the game's complexity).
|
||||
|
||||
- In case of extremely fast rendering, one or more frames are dropped in favour
|
||||
of showing only the most recent one.
|
||||
|
||||
SuperBlitter used: yes, for rectangle blitting to screen and cursor
|
||||
restoration. Sometimes also for generic copying between buffers (see above).
|
||||
|
||||
Triple buffering is the default mode.
|
||||
|
||||
|
||||
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:
|
||||
|
||||
- Uses 8bpp chunky resolutions.
|
||||
|
||||
- Patches all surface addresses by OR'ing 0xA0000000, i.e. using SV RAM instead
|
||||
of slow ST RAM (and even instead of TT RAM for allowing pure SuperBlitter
|
||||
copying).
|
||||
|
||||
- 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 sometimes leads to nearly zero-cost rendering
|
||||
and makes a *huge* difference for 640x480 fullscreen updates.
|
||||
|
||||
|
||||
Aspect ratio correction
|
||||
-----------------------
|
||||
|
||||
Please refer to the official documentation about its usage. Normally ScummVM
|
||||
implements this functionality using yet another fullscreen transformation of
|
||||
320x200 surface into a 320x240 one (there is even a selection of algorithms for
|
||||
this task, varying in performance and quality).
|
||||
|
||||
Naturally, this would impose a terrible performance penalty on our backend so
|
||||
some cheating has been used:
|
||||
|
||||
- On RGB, the vertical refresh rate frequency is set to 60 Hz, creating an
|
||||
illusion of non-square pixels. Works best on CRT monitors.
|
||||
|
||||
- On VGA, the vertical refresh rate frequency is set to 70 Hz, with more or
|
||||
less the same effect as on RGB. Works best on CRT monitors.
|
||||
|
||||
- On SuperVidel, video output is modified in such way that the DVI/HDMI monitor
|
||||
receives a 320x200 image and if properly set/supported, it will automatically
|
||||
stretch the image to 320x240 (this is usually a setting called "picture
|
||||
expansion" or "picture stretch" -- make sure it isn't set to something like
|
||||
"1:1" or "dot by dot").
|
||||
|
||||
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.
|
||||
|
||||
|
||||
Audio mixing
|
||||
------------
|
||||
|
||||
ScummVM works internally with 16-bit samples so on the TT a simple downsampling
|
||||
to 8-bit resolution is used. However, there is still one piece missing - an
|
||||
XBIOS emulator (so ScummVM doesn't have to access hardware directly). There are
|
||||
two options (both available from https://mikrosk.github.io/xbios): STFA and
|
||||
X-SOUND, any of these will do. Or executing ScummVM in EmuTOS which contains
|
||||
the same routines as X-SOUND.
|
||||
|
||||
|
||||
Performance considerations/pitfalls
|
||||
-----------------------------------
|
||||
|
||||
It's important to understand what affects performance on our limited platform to
|
||||
avoid unpleasant gaming experiences.
|
||||
|
||||
Game engines with unexpected performance hit
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
A typical example from this category is Gobliiins (and its sequels), some SCI
|
||||
engine games (Gabriel Knight, Larry 2/7, ...) or the Sherlock engine (The Case
|
||||
of the Rose Tattoo). At first it looks like our machine or Atari backend is
|
||||
doing something terribly wrong but the truth is that it is the engine itself
|
||||
which is doing a lot of redraws, sometimes even before reaching the backend.
|
||||
The only solution is to profile and fix those engines.
|
||||
|
||||
Too many fullscreen updates
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Somewhat related to the previous point - sometimes the engine authors didn't
|
||||
realise the impact of every update on the overall performance and instead of
|
||||
updating only the rectangles that really had changed, they ask for a fullscreen
|
||||
update. Not a problem on a >1 GHz machine but very visible on Atari! Also, this
|
||||
is (by definition) the case of animated intros, especially those in 640x480.
|
||||
|
||||
MIDI vs. AdLib vs. sampled music
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
It could seem that sampled music replay must be the most demanding one but on
|
||||
the contrary! Always choose a CD version of a game (with *.wav tracks) over 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
|
||||
(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 TT, in most cases it makes sense to use ScummVM only if you own a native
|
||||
MIDI synthesiser (like mt32-pi: https://github.com/dwhinham/mt32-pi). MIDI
|
||||
emulation is out of the question and downsampling to 8-bit resolution takes a
|
||||
good chunk of CPU time which could be utilised elsewhere. However, there are
|
||||
games which are fine with sampled music/speech even on a plain TT (e.g. Lands
|
||||
of Lore).
|
||||
|
||||
CD music slows everything down
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Some games use separate audio *and* video streams (files). Even if the CPU is
|
||||
able to handle both, the bottleneck becomes ... disk access. This is visible in
|
||||
The Curse Of Monkey Island for example -- there's audible stuttering during the
|
||||
intro sequence (and during the game as well). Increasing "audio_buffer_size"
|
||||
makes the rendering literally crawl! Why? Because disk I/O is busy with loading
|
||||
even *more* sample data so there's less time for video loading and rendering.
|
||||
Try to put "musdisk1.bun" and "musdisk2.bun" into a ramdisk (i.e. symlink to
|
||||
u:/ram in FreeMiNT), you'll be pleasantly surprised with the performance boost
|
||||
gained.
|
||||
|
||||
Mute vs. "No music"
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Currently ScummVM requires each backend to mix samples, even though they may
|
||||
contain muted output (i.e. zeroes). This is because the progression of sample
|
||||
playback tells ScummVM how much time has passed in e.g. an animation.
|
||||
|
||||
"No music" means using the null audio plugin which prevents generating any MIDI
|
||||
music (and therefore avoiding the expensive synthesis emulation) but beware, it
|
||||
doesn't affect CD (*.wav) playback at all! Same applies for speech and sfx.
|
||||
|
||||
The least amount of cycles is spent when:
|
||||
- "No music" as "Preferred device": This prevents MIDI synthesis of any kind.
|
||||
- "Subtitles" as "Text and speech": This prevents any sampled speech to be
|
||||
mixed.
|
||||
- All external audio files are deleted (typically *.wav); that way the mixer
|
||||
won't have anything to mix. However beware, this is not allowed in every game!
|
||||
|
||||
Sample rate
|
||||
~~~~~~~~~~~
|
||||
|
||||
It's important to realise the impact the sample rate has on the given game. The
|
||||
most obvious setting is its value: the bigger, the more demanding audio mixing
|
||||
becomes. However, if you inspect many games' samples, you will notice that most
|
||||
of them (esp. the ones from the 80s/90s) use simple samples like mono 11025 Hz
|
||||
(sometimes even less).
|
||||
|
||||
Obviously, setting "output_channels" to "1" is the easiest improvement
|
||||
(unfortunately only on TT). Next best thing you can do is to buy an external
|
||||
DSP clock for your Falcon: nearly all games use sample frequencies which are
|
||||
multiples of 44100 Hz: 22050, 11025, ... so with the external clock there
|
||||
won't be the need to resample them.
|
||||
|
||||
There's one caveat, though: it is important whether your replay frequency is
|
||||
equal to, a multiple of, or other than the desired one. Let's consider 44100
|
||||
and 22050 frequencies as an example (also applies to all the other
|
||||
frequencies):
|
||||
|
||||
- If you set 44100 Hz and a game requests 44100 Hz => so called "copyConvert"
|
||||
method will be used (fastest).
|
||||
- If you set 22050 Hz and a game requests 44100 Hz => so called "simpleConvert"
|
||||
method will be used (skipping every second sample, second fastest).
|
||||
- If you set 44100 Hz and a game requests 22050 Hz => so called
|
||||
"interpolateConvert" method will be used (slowest!).
|
||||
- Any other combination: "interpolateConvert" (slowest).
|
||||
|
||||
So how do you know which frequency to set as "output_rate" ? This is where
|
||||
"print_rate" comes to rescue. Enabling this option in scummvm.ini will tell you
|
||||
for each game which sample converters are being used and for what input/values.
|
||||
So you can easily verify whether the given game's demands match your setting.
|
||||
|
||||
Unfortunately, currently per-game "output_rate" / "output_channels" is not
|
||||
possible but this may change in the future.
|
||||
|
||||
Slow GUI
|
||||
~~~~~~~~
|
||||
|
||||
Themes handling is quite slow - each theme must be depacked, each one contains
|
||||
quite a few XML files to parse and quite a few images to load/convert. That's
|
||||
the reason why the built-in one is used as default, it dramatically speeds up
|
||||
loading time. To speed things up in other cases, the full version is
|
||||
distributed with repackaged theme files with compression level zero.
|
||||
|
||||
|
||||
Changes to upstream
|
||||
-------------------
|
||||
|
||||
There are a few features that have been disabled or changed and are not possible
|
||||
/ plausible to merge into upstream:
|
||||
|
||||
- the aforementioned "print_rate" feature, too invasive for other platforms
|
||||
|
||||
- This port contains an implementation of much faster tooltips in the overlay.
|
||||
However, there is a minor rendering bug which sometimes corrupts the
|
||||
background. But since its impact is huge, I left it in.
|
||||
|
||||
|
||||
Known issues
|
||||
------------
|
||||
|
||||
- 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.
|
||||
|
||||
- Horizontal screen shaking doesn't work on TT because TT Shifter doesn't
|
||||
support fine scrolling. However it is "emulated" via vertical shaking.
|
||||
|
||||
- Aspect ratio correction has no effect on TT because it is not possible to
|
||||
alter its vertical screen refresh frequency.
|
||||
|
||||
- The talkie version of SOMI needs to be merged from two sources:
|
||||
- The DOS version (install.bat) to obtain file "monster.sou".
|
||||
- The FLAC version (install_flac.bat) to obtain folders "cd_music_flac" and
|
||||
"se_music_flac" (these *.flac files then have to be converted to *.wav
|
||||
manually).
|
||||
- Files "monkey.000" and "monkey.001" can be taken from either version.
|
||||
- Point the extra path to the folder with *.wav files (or copy its content
|
||||
where monkey.00? files are located).
|
||||
|
||||
- Following engines have been explicitly disabled:
|
||||
- Cine (2 games)
|
||||
- Incompatible with other engines / prone to freezes.
|
||||
- https://wiki.scummvm.org/index.php?title=Cine
|
||||
- Director (many games)
|
||||
- Huge game list slows detection for other games, and would require
|
||||
(currently missing) localization support.
|
||||
- Only small subset of games actually supported by upstream, but none of
|
||||
them detected on TOS 8+3 file system.
|
||||
- https://wiki.scummvm.org/index.php?title=Director
|
||||
- Hugo (3 games)
|
||||
- Uses (lot of) overlay dialogs which are problematic for Atari backend.
|
||||
- Engine GUI (for save/load/etc) does not support 8-bit screens.
|
||||
- https://wiki.scummvm.org/index.php?title=Hugo
|
||||
- Ultima (many games)
|
||||
- The only non-hires ultima engine is ultima1; see
|
||||
https://bugs.scummvm.org/ticket/14790
|
||||
- This prevents adding the 15 MB ultima.dat to the release archive.
|
||||
- https://wiki.scummvm.org/index.php?title=Ultima
|
||||
|
||||
- When using FreeMiNT, ScummVM requires a recent kernel (>= 2021), otherwise
|
||||
keyboard handling won't work properly.
|
||||
|
||||
- When using EmuTOS, ScummVM requires a recent release (>= 1.3), otherwise
|
||||
various screen- and sound-related issues may appear.
|
||||
|
||||
Future plans
|
||||
------------
|
||||
|
||||
- DSP-based sample mixer (WAV, FLAC, MP2).
|
||||
|
||||
- Avoid loading music/speech files (and thus slowing down everything) if muted.
|
||||
|
||||
- Cached audio/video streams (i.e. don't load only "audio_buffer_size" number
|
||||
of samples but cache, say, 1 second so disk i/o won't be so stressed).
|
||||
|
||||
- Using Thorsten Otto's sharedlibs: https://tho-otto.de/sharedlibs.php for game
|
||||
engine plugins to relieve the huge binary size.
|
||||
|
||||
- True audio CD support via MetaDOS API.
|
||||
|
||||
- OPL2LPT and Retrowave support (if I manage to purchase it somewhere).
|
||||
|
||||
|
||||
Closing words
|
||||
-------------
|
||||
|
||||
Many optimisations and improvements wouldn't be possible without the help of
|
||||
Eero Tamminen, so thank you for all the help with profiling in Hatari.
|
||||
|
||||
Miro Kropacek aka MiKRO
|
||||
Brisbane / Australia
|
||||
miro.kropacek@gmail.com
|
||||
http://mikro.atari.org
|
||||
79
backends/platform/atari/symbols.h
Normal file
79
backends/platform/atari/symbols.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
// Atari a.out / ELF symbol handling by Thorsten Otto.
|
||||
// include in each of the .S files and put every global symbol into
|
||||
// SYM(<symbol name>).
|
||||
|
||||
#ifndef __USER_LABEL_PREFIX__
|
||||
#define __USER_LABEL_PREFIX__ _
|
||||
#endif
|
||||
|
||||
#ifndef __REGISTER_PREFIX__
|
||||
#define __REGISTER_PREFIX__
|
||||
#endif
|
||||
|
||||
#ifndef __IMMEDIATE_PREFIX__
|
||||
#define __IMMEDIATE_PREFIX__ #
|
||||
#endif
|
||||
|
||||
#define CONCAT1(a, b) CONCAT2(a, b)
|
||||
#define CONCAT2(a, b) a ## b
|
||||
|
||||
/* Use the right prefix for global labels. */
|
||||
|
||||
#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
|
||||
|
||||
#ifdef __ELF__
|
||||
#define FUNC(x) .type SYM(x),function
|
||||
#else
|
||||
/* The .proc pseudo-op is accepted, but ignored, by GAS. We could just
|
||||
define this to the empty string for non-ELF systems, but defining it
|
||||
to .proc means that the information is available to the assembler if
|
||||
the need arises. */
|
||||
#define FUNC(x) .proc
|
||||
#endif
|
||||
|
||||
#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
|
||||
|
||||
#define IMM(x) CONCAT1 (__IMMEDIATE_PREFIX__, x)
|
||||
|
||||
#define d0 REG(d0)
|
||||
#define d1 REG(d1)
|
||||
#define d2 REG(d2)
|
||||
#define d3 REG(d3)
|
||||
#define d4 REG(d4)
|
||||
#define d5 REG(d5)
|
||||
#define d6 REG(d6)
|
||||
#define d7 REG(d7)
|
||||
#define a0 REG(a0)
|
||||
#define a1 REG(a1)
|
||||
#define a2 REG(a2)
|
||||
#define a3 REG(a3)
|
||||
#define a4 REG(a4)
|
||||
#define a5 REG(a5)
|
||||
#define a6 REG(a6)
|
||||
#define a7 REG(a7)
|
||||
#define fp REG(fp)
|
||||
#define sp REG(sp)
|
||||
#define pc REG(pc)
|
||||
|
||||
#define sr REG(sr)
|
||||
Reference in New Issue
Block a user