aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.cpp2
-rw-r--r--morphos/Makefile16
-rw-r--r--morphos/morphos.cpp1326
-rw-r--r--morphos/morphos.h182
-rw-r--r--morphos/morphos_sound.cpp140
-rw-r--r--morphos/morphos_start.cpp309
-rw-r--r--scummsys.h1
-rw-r--r--scummvm.cpp2
-rw-r--r--system.h1
9 files changed, 1111 insertions, 868 deletions
diff --git a/main.cpp b/main.cpp
index 7176443fd1..4608b36cff 100644
--- a/main.cpp
+++ b/main.cpp
@@ -11,7 +11,7 @@ Gui gui;
Scumm *g_scumm;
-#if !defined(__APPLE__)
+#if !defined(__APPLE__) && !defined(__MORPHOS__)
#undef main
#endif
diff --git a/morphos/Makefile b/morphos/Makefile
index 238c730ae9..222f739e02 100644
--- a/morphos/Makefile
+++ b/morphos/Makefile
@@ -1,21 +1,23 @@
-vpath %.cpp ../:../sound/:../v3/:../v4/
+vpath %.cpp ../:../sound/:../v3/:../v4/:../simon/
+vpath %.h ../
CC = g++
CFLAGS = -Wno-multichar -fstrength-reduce -O2
-DEFINES =
+DEFINES = -DNO_PPCINLINE_STDARG -DNO_PPCINLINE_VARARGS
LDFLAGS := -noixemul -s
INCLUDES:= -I../ -I../sound
CPPFLAGS= $(DEFINES) $(INCLUDES)
LIBS = -lamiga -lamigastubs
ZIPFILE := scummvm-`date '+%Y-%m-%d'`.zip
-INCS = ../scumm.h ../scummsys.h ../stdafx.h
+INCS = scumm.h scummsys.h stdafx.h
OBJS = actor.o akos.o boxes.o costume.o gfx.o object.o resource.o \
- saveload.o script.o scummvm.o sound.o string.o \
- sys.o verbs.o morphos.o morphos_sound.o script_v1.o script_v2.o debug.o gui.o \
- imuse.o fmopl.o adlib.o gmidi.o debugrl.o vars.o insane.o \
- gameDetector.o init.o resource_v3.o resource_v4.o
+ saveload.o script.o scummvm.o sound.o string.o sys.o verbs.o \
+ morphos.o morphos_sound.o morphos_start.o script_v1.o script_v2.o debug.o gui.o \
+ imuse.o fmopl.o mixer.o mididrv.o debugrl.o vars.o insane.o \
+ gameDetector.o init.o resource_v3.o resource_v4.o main.o \
+ midi.o simon.o simonsys.o
DISTFILES=$(OBJS:.o=.cpp) Makefile scumm.h scummsys.h stdafx.h stdafx.cpp \
windows.cpp debugrl.h whatsnew.txt readme.txt copying.txt \
diff --git a/morphos/morphos.cpp b/morphos/morphos.cpp
index e8e30418a0..8887db05d2 100644
--- a/morphos/morphos.cpp
+++ b/morphos/morphos.cpp
@@ -25,27 +25,22 @@
#include "stdafx.h"
#include "scumm.h"
-#include "gui.h"
-#include "gameDetector.h"
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/libraries.h>
#include <exec/semaphores.h>
+#include <devices/ahi.h>
#include <dos/dostags.h>
#include <intuition/screens.h>
#include <cybergraphics/cybergraphics.h>
#include <devices/inputevent.h>
#include <intuition/intuition.h>
-#include <workbench/startup.h>
-#define NO_PPCINLINE_STDARG
-#define NO_PPCINLINE_VARARGS
#include <clib/alib_protos.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/graphics.h>
-#include <proto/icon.h>
#include <proto/intuition.h>
#include <proto/keymap.h>
#include <proto/timer.h>
@@ -56,154 +51,246 @@
#include <time.h>
-extern "C" struct WBStartup *_WBenchMsg;
-
-Scumm *scumm = NULL;
-ScummDebugger debugger;
-Gui gui;
-OSystem _system;
-GameDetector detector;
-
-IMuse sound;
-SOUND_DRIVER_TYPE snd_driv;
-
-typedef void (*ScalerFunc)( uint32 src_x, uint32 src_y, uint32 dest_x, uint32 dest_y, uint32 width, uint32 height );
-
-void Super2xSaI( uint32 src_x, uint32 src_y, uint32 dest_x, uint32 dest_y, uint32 width, uint32 height );
-void SuperEagle( uint32 src_x, uint32 src_y, uint32 dest_x, uint32 dest_y, uint32 width, uint32 height );
-void PointScaler( uint32 src_x, uint32 src_y, uint32 dest_x, uint32 dest_y, uint32 width, uint32 height );
-
-static struct Screen *ScummScreen = NULL;
-static struct Window *ScummWindow = NULL;
-static APTR ScummBuffer = NULL;
-static struct ScreenBuffer *ScummScreenBuffer[ 2 ] = { NULL, NULL };
-static struct BitMap *ScummRenderTo = NULL;
-static ULONG ScummPaintBuffer;
-static UWORD *ScummNoCursor = NULL;
-static struct Process *ScummMusicThread = NULL;
-static ScalerFunc ScummScaler = &Super2xSaI;
-static ULONG ScummColors[256];
-static USHORT ScummColors16[256];
-static WORD ScummWinX = -1;
-static WORD ScummWinY = -1;
-static bool ScummOrigMouse = false;
-static int ScummShakePos = 0;
-static bool ScummPCMode = false;
-
-static struct MsgPort *TimerMsgPort = NULL;
-static struct timerequest *TimerIORequest = NULL;
-static bool TimerStarted = false;
-
-static char*ScummStory = NULL;
-static char*ScummPath = NULL;
-static char ScummWndTitle[ 125 ];
-static int ScummDepth = 0;
-static int ScummScale = 1;
-static bool Scumm16ColFmt16 = false;
-static int ScummScrWidth = 0;
-static int ScummScrHeight = 0;
-static LONG ScummMidiUnit = 0;
-static LONG ScummMidiVolume = 0;
-static LONG ScummMidiTempo = 0;
-
-struct Library *CDDABase = NULL;
-static CDRIVEPTR CDrive = NULL;
-static struct TagItem FindCDTags[] = { { CDFA_VolumeName, (ULONG)"LoomCD" },
- { TAG_DONE, 0 } };
-
-static struct TagItem PlayTags[] = { { CDPA_StartTrack, 1 },
- { CDPA_StartFrame, 0 },
- { CDPA_EndTrack, 1 },
- { CDPA_EndFrame, 0 },
- { TAG_DONE, 0 }
- };
-static ULONG CDDATrackOffset = 0;
-
+#include "morphos.h"
-static struct RDArgs *ScummArgs = NULL;
-static BPTR OrigDirLock = 0;
+static struct TagItem FindCDTags[] = { { CDFA_VolumeName, 0 },
+ { TAG_DONE, 0 }
+ };
+static struct TagItem PlayTags[] = { { CDPA_StartTrack, 1 },
+ { CDPA_StartFrame, 0 },
+ { CDPA_EndTrack, 1 },
+ { CDPA_EndFrame, 0 },
+ { TAG_DONE, 0 }
+ };
-struct GfxScaler
-{
- STRPTR gs_Name;
- ScalerFunc gs_Function;
-};
-
-static struct GfxScaler ScummScalers[] = { { "none", NULL },
- { "Point", PointScaler },
- { "SuperEagle", SuperEagle },
- { "Super2xSaI", Super2xSaI },
- { NULL, NULL },
- { NULL, NULL },
- { NULL, NULL },
- { NULL, NULL },
- { NULL, NULL },
- { NULL, NULL }
- };
-
-// For command line parsing
-static STRPTR usageTemplate = "STORY/A,DATAPATH/K,WBWINDOW/S,SCALER/K,MIDIUNIT/K/N,NOMUSIC/S,VOLUME/K/N,TEMPO/K,NOSUBTITLES=NST/S";
-typedef enum { USG_STORY = 0, USG_DATAPATH, USG_WBWINDOW, USG_SCALER, USG_MIDIUNIT, USG_NOMUSIC, USG_VOLUME, USG_TEMPO, USG_NOSUBTITLES } usageFields;
-static LONG args[ 9 ] = { (ULONG)NULL, (ULONG)NULL, FALSE, (ULONG)NULL, (ULONG)NULL, false, (ULONG)NULL, (ULONG)NULL, false };
-
-// These are for the scaling engine
-static uint32 colorMask = 0xF7DEF7DE;
-static uint32 lowPixelMask = 0x08210821;
-static uint32 qcolorMask = 0xE79CE79C;
-static uint32 qlowpixelMask = 0x18631863;
-static uint32 redblueMask = 0xF81F;
-static uint32 greenMask = 0x7E0;
-static int PixelsPerMask = 2;
-static byte *src_line[4];
-static byte *dst_line[2];
-
-struct EmulFunc MyEmulFunc;
-struct TagItem musicProcTags[] = { { NP_Entry, (ULONG)&MyEmulFunc.Trap },
+OSystem_MorphOS::GfxScaler OSystem_MorphOS::ScummScalers[ 10 ] = { { "none", ST_NONE },
+ { "Point", ST_POINT },
+ { "SuperEagle", ST_SUPEREAGLE },
+ { "Super2xSaI", ST_SUPER2XSAI },
+ { NULL, ST_INVALID },
+ { NULL, ST_INVALID },
+ { NULL, ST_INVALID },
+ { NULL, ST_INVALID },
+ { NULL, ST_INVALID },
+ { NULL, ST_INVALID }
+ };
+
+struct TagItem musicProcTags[] = { { NP_Entry, 0 },
{ NP_Name, (ULONG)"ScummVM Music Thread" },
- { NP_StackSize, 16000 },
- { NP_Priority, 30 },
+ { NP_StackSize, 8192 },
+ { NP_Priority, 0 },
+ { TAG_DONE, 0 }
+ };
+struct TagItem soundProcTags[] = { { NP_Entry, 0 },
+ { NP_Name, (ULONG)"ScummVM Sound Thread" },
+ { NP_StackSize, 8192 },
+ { NP_Priority, 0 },
{ TAG_DONE, 0 }
};
-extern int morphos_music_thread( Scumm *s, ULONG MidiUnit, bool NoMusic );
+OSystem_MorphOS *OSystem_MorphOS::create( int game_id, SCALERTYPE gfx_scaler, bool full_screen )
+{
+ OSystem_MorphOS *syst = new OSystem_MorphOS( game_id, gfx_scaler, full_screen );
-extern struct SignalSemaphore ScummMusicThreadRunning;
+ return syst;
+}
-struct Library *CyberGfxBase = NULL;
-struct Device *TimerBase = NULL;
+OSystem_MorphOS::OSystem_MorphOS( int game_id, SCALERTYPE gfx_mode, bool full_screen )
+{
+ GameID = game_id;
+ ScummScreen = NULL;
+ ScummWindow = NULL;
+ ScummBuffer = NULL;
+ ScummScreenBuffer[ 0 ] = NULL;
+ ScummScreenBuffer[ 1 ] = NULL;
+ ScummRenderTo = NULL;
+ ScummNoCursor = NULL;
+ ScummMusicThread = NULL;
+ ScummSoundThread = NULL;
+ ScummWinX = -1;
+ ScummWinY = -1;
+ ScummOrigMouse = false;
+ ScummShakePos = 0;
+ ScummPCMode = false;
+ ScummScaler = gfx_mode;
+ ScummScale = (gfx_mode == ST_NONE) ? 0 : 1;
+ ScummDepth = 0;
+ Scumm16ColFmt16 = false;
+ ScummScrWidth = 0;
+ ScummScrHeight = 0;
+ FullScreenMode = full_screen;
+ CDrive = NULL;
+ CDDATrackOffset = 0;
+ strcpy( ScummWndTitle, "ScummVM MorphOS" );
+ TimerMsgPort = NULL;
+ TimerIORequest = NULL;
-void updateScreen(Scumm *s);
+ TimerMsgPort = CreateMsgPort();
+ if( TimerMsgPort == NULL )
+ {
+ puts( "Failed to create message port" );
+ exit( 1 );
+ }
-void BoxTest(int num)
-{
- /* Debug only, remove */
+ TimerIORequest = (struct timerequest *)CreateIORequest( TimerMsgPort, sizeof( struct timerequest ) );
+ if( TimerIORequest == NULL )
+ {
+ puts( "Failed to create IO request" );
+ exit( 1 );
+ }
+
+ if( OpenDevice( "timer.device", UNIT_MICROHZ, (struct IORequest *)TimerIORequest, 0 ) )
+ {
+ DeleteIORequest( (struct IORequest *)TimerIORequest );
+ TimerIORequest = NULL;
+ puts( "Failed to open timer device" );
+ exit( 1 );
+ }
+
+ ScummNoCursor = (UWORD *)AllocVec( 16, MEMF_CHIP | MEMF_CLEAR );
}
-int GetTicks()
+OSystem_MorphOS::~OSystem_MorphOS()
{
-/* unsigned long long time64;
- ULONG ClockTicks;
- struct EClockVal ClockVal;
+ if( CDrive && CDDABase )
+ {
+ CDDA_Stop( CDrive );
+ CDDA_ReleaseDrive( CDrive );
+ }
+
+ if( TimerIORequest )
+ {
+ CloseDevice( (struct IORequest *)TimerIORequest );
+ DeleteIORequest( (struct IORequest *)TimerIORequest );
+ }
+
+ if( TimerMsgPort )
+ DeleteMsgPort( TimerMsgPort );
+
+ if( ScummMusicThread )
+ {
+ Signal( (struct Task *)ScummMusicThread, SIGBREAKF_CTRL_F );
+ ObtainSemaphore( &ScummMusicThreadRunning ); /* Wait for thread to finish */
+ ReleaseSemaphore( &ScummMusicThreadRunning );
+ }
+
+ if( ScummSoundThread )
+ {
+ Signal( (struct Task *)ScummSoundThread, SIGBREAKF_CTRL_C );
+ ObtainSemaphore( &ScummSoundThreadRunning ); /* Wait for thread to finish */
+ ReleaseSemaphore( &ScummSoundThreadRunning );
+ }
+
+ if( ScummNoCursor )
+ FreeVec( ScummNoCursor );
+
+ if( ScummBuffer )
+ FreeVec( ScummBuffer );
- ClockTicks = ReadEClock( &ClockVal );
- time64 = ClockVal.ev_hi;
+ if( ScummRenderTo && !ScummScreen )
+ FreeBitMap( ScummRenderTo );
- time64 = (time64 << 32) | ClockVal.ev_lo;
- return (time64/ClockTicks)*1000;*/
+ if( ScummWindow )
+ CloseWindow( ScummWindow );
+ if( ScummScreen )
+ {
+ if( ScummScreenBuffer[ 0 ] )
+ FreeScreenBuffer( ScummScreen, ScummScreenBuffer[ 0 ] );
+ if( ScummScreenBuffer[ 1 ] )
+ FreeScreenBuffer( ScummScreen, ScummScreenBuffer[ 1 ] );
+ CloseScreen( ScummScreen );
+ }
+}
+
+uint32 OSystem_MorphOS::get_msecs()
+{
int ticks = clock();
ticks *= (1000/CLOCKS_PER_SEC);
return ticks;
}
-static int cd_track = 0, cd_num_loops = 0, cd_start_frame = 0;
-static ULONG cd_end_time = 0;
-static ULONG cd_stop_time = 0;
+void OSystem_MorphOS::delay_msecs(uint msecs)
+{
+ TimerIORequest->tr_node.io_Command = TR_ADDREQUEST;
+ TimerIORequest->tr_time.tv_secs = 0;
+ TimerIORequest->tr_time.tv_micro = msecs*1000;
+ DoIO( (struct IORequest *)TimerIORequest );
+}
+
+void *OSystem_MorphOS::create_thread(ThreadProc *proc, void *param)
+{
+/* MyEmulFunc.Trap = TRAP_FUNC;
+ MyEmulFunc.Address = (ULONG)proc;
+ MyEmulFunc.StackSize = 8192;
+ MyEmulFunc.Extension = 0;
+ MyEmulFunc.Arg1 = (ULONG)param;
+ MyEmulFunc.Arg2 = (ULONG)ScummMidiUnit;
+ MyEmulFunc.Arg3 = (ULONG)args[ USG_NOMUSIC ];
+ ScummMusicThread = CreateNewProc( musicProcTags );*/
+ return NULL;
+}
+
+uint32 OSystem_MorphOS::property(int param, uint32 value)
+{
+ switch( param )
+ {
+ case PROP_TOGGLE_FULLSCREEN:
+ create_screen( CSDSPTYPE_TOGGLE );
+ return 1;
+
+ case PROP_SET_WINDOW_CAPTION:
+ sprintf( ScummWndTitle, "ScummVM MorphOS - %s", (char *)value );
+ if( ScummWindow )
+ SetWindowTitles( ScummWindow, ScummWndTitle, ScummWndTitle );
+ return 1;
+
+ case PROP_OPEN_CD:
+ FindCDTags[ 0 ].ti_Data = (ULONG)((GameID == GID_LOOM256) ? "LoomCD" : "Monkey1CD");
+ if( !CDDABase ) CDDABase = OpenLibrary( "cdda.library", 0 );
+ if( CDDABase )
+ {
+ CDrive = CDDA_FindNextDrive( NULL, FindCDTags );
+ if( CDrive )
+ {
+ if( !CDDA_ObtainDrive( CDrive, CDDA_SHARED_ACCESS, NULL ) )
+ {
+ CDrive = NULL;
+ warning( "Failed to obtain CD drive - music will not play" );
+ }
+ else if( GameID == GID_LOOM256 )
+ {
+ // Offset correction *may* be required
+ struct CDS_TrackInfo ti;
+
+ if( CDDA_GetTrackInfo( CDrive, 1, 0, &ti ) )
+ CDDATrackOffset = ti.ti_TrackStart.tm_Format.tm_Frame-22650;
+ }
+ }
+ else
+ warning( "Could not find game CD inserted in CD-ROM drive - cd audio will not play" );
+ }
+ else
+ warning( "Failed to open cdda.library - cd audio will not play" );
+ break;
+
+ case PROP_SHOW_DEFAULT_CURSOR:
+ if( value )
+ ClearPointer( ScummWindow );
+ else
+ SetPointer( ScummWindow, ScummNoCursor, 1, 1, 0, 0 );
+ break;
+
+ case PROP_GET_SAMPLE_RATE:
+ return SAMPLES_PER_SEC;
+ }
+
+ return 0;
+}
void cd_play( Scumm *s, int track, int num_loops, int start_frame, int length )
{
- scumm->_vars[14] = 0;
- if( CDrive && start_frame >= 0 )
+/* if( CDrive && start_frame >= 0 )
{
struct CDS_TrackInfo ti;
@@ -223,31 +310,32 @@ void cd_play( Scumm *s, int track, int num_loops, int start_frame, int length )
CDDA_GetTrackInfo( CDrive, track, 0, &ti );
cd_end_time = GetTicks() + ti.ti_TrackLength.tm_Format.tm_Frame * 1000 / 75;
- }
+ }*/
}
// Schedule the music to be stopped after 1/10 sec, unless another
// track is started in the meantime.
void cd_stop()
{
- cd_stop_time = GetTicks() + 100;
- cd_num_loops = 0;
+/* cd_stop_time = GetTicks() + 100;
+ cd_num_loops = 0;*/
}
int cd_is_running()
{
- ULONG status;
+/* ULONG status;
if( CDrive == NULL )
return 0;
CDDA_GetAttr( CDDA_Status, CDrive, &status );
- return (cd_num_loops != 0 && (GetTicks() < cd_end_time || status != CDDA_Status_Ready));
+ return (cd_num_loops != 0 && (GetTicks() < cd_end_time || status != CDDA_Status_Ready));*/
+ return FALSE;
}
void cd_music_loop()
{
- if( CDrive )
+/* if( CDrive )
{
if( cd_stop_time != 0 && GetTicks() >= cd_stop_time )
{
@@ -282,81 +370,15 @@ void cd_music_loop()
CDDA_GetTrackInfo( CDrive, cd_track, 0, &ti );
cd_end_time = GetTicks() + ti.ti_TrackLength.tm_Format.tm_Frame * 1000 / 75;
}
- }
+ }*/
}
-void closeResources()
+void OSystem_MorphOS::quit()
{
- if( ScummMusicThread )
- {
- Signal( (struct Task *)ScummMusicThread, SIGBREAKF_CTRL_F );
- ObtainSemaphore( &ScummMusicThreadRunning ); /* Wait for thread to finish */
- ReleaseSemaphore( &ScummMusicThreadRunning );
- }
-
- if( TimerStarted )
- {
- AbortIO( (struct IORequest *)TimerIORequest );
- WaitIO( (struct IORequest *)TimerIORequest );
- }
-
- if( TimerIORequest )
- {
- CloseDevice( (struct IORequest *)TimerIORequest );
- DeleteIORequest( (struct IORequest *)TimerIORequest );
- }
-
- if( TimerMsgPort )
- DeleteMsgPort( TimerMsgPort );
-
- if( OrigDirLock )
- CurrentDir( OrigDirLock );
-
- if( ScummPath )
- FreeVec( ScummPath );
-
- if( ScummStory )
- FreeVec( ScummStory );
-
- if( ScummArgs )
- FreeArgs( ScummArgs );
-
- if( ScummNoCursor )
- FreeVec( ScummNoCursor );
-
- if( ScummBuffer )
- FreeVec( ScummBuffer );
-
- if( ScummRenderTo && !ScummScreen )
- FreeBitMap( ScummRenderTo );
-
- if( ScummWindow )
- CloseWindow( ScummWindow );
-
- if( ScummScreen )
- {
- if( ScummScreenBuffer[ 0 ] )
- FreeScreenBuffer( ScummScreen, ScummScreenBuffer[ 0 ] );
- if( ScummScreenBuffer[ 1 ] )
- FreeScreenBuffer( ScummScreen, ScummScreenBuffer[ 1 ] );
- CloseScreen( ScummScreen );
- }
-
- if( CDDABase )
- {
- if( CDrive && CDDABase )
- {
- CDDA_Stop( CDrive );
- CDDA_ReleaseDrive( CDrive );
- }
- CloseLibrary( CDDABase );
- }
-
- if( CyberGfxBase )
- CloseLibrary( CyberGfxBase );
+ exit( 0 );
}
-uint32 makeColForPixFmt( int pixfmt, int r, int g, int b )
+uint32 OSystem_MorphOS::make_color( int pixfmt, int r, int g, int b )
{
uint32 col = 0;
@@ -408,39 +430,30 @@ uint32 makeColForPixFmt( int pixfmt, int r, int g, int b )
return col;
}
-#define CVT8TO32( byte ) ((byte<<24) | (byte<<16) | (byte<<8) | byte)
+#define CVT8TO32( col ) ((col<<24) | (col<<16) | (col<<8) | col)
-void updatePalette( Scumm *s )
+void OSystem_MorphOS::set_palette(const byte *colors, uint start, uint num)
{
- int first = s->_palDirtyMin;
- int num = s->_palDirtyMax - first + 1;
- int i;
- byte *data = s->_currentPalette;
-
- data += first*3;
- for( i = first; i < first+num; i++, data+=3 )
+ const byte *data = colors;
+ for( uint i = start; i != start+num; i++ )
{
if( ScummDepth == 8 )
SetRGB32( &ScummScreen->ViewPort, i, CVT8TO32( data[ 0 ] ), CVT8TO32( data[ 1 ] ), CVT8TO32( data[ 2 ] ) );
ScummColors16[ i ] = Scumm16ColFmt16 ? (((data[ 0 ]*31)/255) << 11) | (((data[ 1 ]*63)/255) << 5) | ((data[ 2 ]*31)/255) : (((data[ 0 ]*31)/255) << 10) | (((data[ 1 ]*31)/255) << 5) | ((data[ 2 ]*31)/255);
ScummColors[ i ] = (data[ 0 ] << 16) | (data[ 1 ] << 8) | data[ 2 ];
+ data += 4;
}
-
- s->_palDirtyMax = -1;
- s->_palDirtyMin = 0x3E8;
}
-typedef enum { CSDSPTYPE_WINDOWED, CSDSPTYPE_FULLSCREEN, CSDSPTYPE_TOGGLE } CS_DSPTYPE;
-
-void createScreen( CS_DSPTYPE dspType )
+void OSystem_MorphOS::create_screen( CS_DSPTYPE dspType )
{
ULONG mode = INVALID_ID;
int depths[] = { 8, 15, 16, 24, 32, 0 };
int i;
struct Screen *wb = NULL;
- bool fullScreen;
- fullScreen = (dspType == CSDSPTYPE_FULLSCREEN) || (dspType == CSDSPTYPE_TOGGLE && ScummScreen == NULL);
+ if( dspType != CSDSPTYPE_KEEP )
+ FullScreenMode = (dspType == CSDSPTYPE_FULLSCREEN) || (dspType == CSDSPTYPE_TOGGLE && !FullScreenMode);
if( ScummRenderTo && !ScummScreen )
FreeBitMap( ScummRenderTo );
@@ -470,7 +483,7 @@ void createScreen( CS_DSPTYPE dspType )
ScummScrWidth = 320 << ScummScale;
ScummScrHeight = 200 << ScummScale;
- if( fullScreen )
+ if( FullScreenMode )
{
for( i = ScummScale; mode == INVALID_ID && depths[ i ]; i++ )
mode = BestCModeIDTags( CYBRBIDTG_NominalWidth, ScummScrWidth,
@@ -552,17 +565,18 @@ void createScreen( CS_DSPTYPE dspType )
WA_Activate, TRUE,
WA_Title, wb ? ScummWndTitle : NULL,
WA_ScreenTitle, wb ? ScummWndTitle : NULL,
- WA_Borderless, fullScreen,
- WA_CloseGadget, !fullScreen,
- WA_DepthGadget, !fullScreen,
- WA_DragBar, !fullScreen,
+ WA_Borderless, FullScreenMode,
+ WA_CloseGadget, !FullScreenMode,
+ WA_DepthGadget, !FullScreenMode,
+ WA_DragBar, !FullScreenMode,
WA_ReportMouse, TRUE,
WA_RMBTrap, TRUE,
+ WA_MouseQueue, 1,
WA_IDCMP, IDCMP_RAWKEY |
IDCMP_MOUSEMOVE |
IDCMP_CLOSEWINDOW |
IDCMP_MOUSEBUTTONS,
- WA_CustomScreen, fullScreen ? (ULONG)ScummScreen : (ULONG)wb,
+ WA_CustomScreen, FullScreenMode ? (ULONG)ScummScreen : (ULONG)wb,
TAG_DONE
);
@@ -635,12 +649,12 @@ void createScreen( CS_DSPTYPE dspType )
ScummPCMode = true;
debug( 1, "Pixelformat = %d", pixfmt );
- colorMask = (makeColForPixFmt( pixfmt, 255, 0, 0 ) - minr) | (makeColForPixFmt( pixfmt, 0, 255, 0 ) - ming) | (makeColForPixFmt( pixfmt, 0, 0, 255 ) - minb);
+ colorMask = (make_color( pixfmt, 255, 0, 0 ) - minr) | (make_color( pixfmt, 0, 255, 0 ) - ming) | (make_color( pixfmt, 0, 0, 255 ) - minb);
lowPixelMask = minr | ming | minb;
- qcolorMask = (makeColForPixFmt( pixfmt, 255, 0, 0 ) - 3*minr) | (makeColForPixFmt( pixfmt, 0, 255, 0) - 3*ming) | (makeColForPixFmt( pixfmt, 0, 0, 255 ) - 3*minb);
+ qcolorMask = (make_color( pixfmt, 255, 0, 0 ) - 3*minr) | (make_color( pixfmt, 0, 255, 0) - 3*ming) | (make_color( pixfmt, 0, 0, 255 ) - 3*minb);
qlowpixelMask = (minr * 3) | (ming * 3) | (minb * 3);
- redblueMask = makeColForPixFmt( pixfmt, 255, 0, 255 );
- greenMask = makeColForPixFmt( pixfmt, 0, 255, 0 );
+ redblueMask = make_color( pixfmt, 255, 0, 255 );
+ greenMask = make_color( pixfmt, 0, 255, 0 );
PixelsPerMask = (ScummDepth <= 16) ? 2 : 1;
@@ -654,28 +668,20 @@ void createScreen( CS_DSPTYPE dspType )
}
}
-int old_mouse_x, old_mouse_y;
-int old_mouse_h, old_mouse_w;
-bool has_mouse,hide_mouse;
-
-#define BAK_WIDTH 40
-#define BAK_HEIGHT 40
-byte old_backup[ BAK_WIDTH*BAK_HEIGHT*2 ];
-
-void SwitchScalerTo( ScalerFunc newScaler )
+void OSystem_MorphOS::SwitchScalerTo( SCALERTYPE newScaler )
{
- if( newScaler == NULL && ScummScale )
+ if( newScaler == ST_NONE && ScummScale != 0 )
{
- ScummScale = false;
- ScummScaler = NULL;
- createScreen( ScummScreen ? CSDSPTYPE_FULLSCREEN : CSDSPTYPE_WINDOWED );
+ ScummScale = 0;
+ ScummScaler = ST_NONE;
+ create_screen( ScummScreen ? CSDSPTYPE_FULLSCREEN : CSDSPTYPE_WINDOWED );
}
else
{
- if( !ScummScale )
+ if( ScummScale == 0 )
{
- ScummScale = true;
- createScreen( ScummScreen ? CSDSPTYPE_FULLSCREEN : CSDSPTYPE_WINDOWED );
+ ScummScale = 1;
+ create_screen( ScummScreen ? CSDSPTYPE_FULLSCREEN : CSDSPTYPE_WINDOWED );
}
if( ScummScaler != newScaler )
@@ -683,182 +689,154 @@ void SwitchScalerTo( ScalerFunc newScaler )
}
}
-void waitForTimer( Scumm *s, int msec_delay )
+bool OSystem_MorphOS::poll_event( Event *event )
{
struct IntuiMessage *ScummMsg;
- ULONG signals;
- bool AllDone = false;
- if (s->_fastMode&2)
- msec_delay = 0;
- else if (s->_fastMode&1)
- msec_delay = 10;
-
- TimerIORequest->tr_node.io_Command = TR_ADDREQUEST;
- TimerIORequest->tr_time.tv_secs = 0;
- TimerIORequest->tr_time.tv_micro = (msec_delay > 0 ? msec_delay : 1)*1000;
- SendIO( (struct IORequest *)TimerIORequest );
- TimerStarted = true;
-
- do
+ if( ScummMsg = (struct IntuiMessage *)GetMsg( ScummWindow->UserPort ) )
{
- while( ScummMsg = (struct IntuiMessage *)GetMsg( ScummWindow->UserPort ) )
+ switch( ScummMsg->Class )
{
- switch( ScummMsg->Class )
+ case IDCMP_RAWKEY:
{
- case IDCMP_RAWKEY:
- {
- struct InputEvent FakedIEvent;
- char charbuf;
+ struct InputEvent FakedIEvent;
+ char charbuf;
+ int qual = 0;
- memset( &FakedIEvent, 0, sizeof( struct InputEvent ) );
- FakedIEvent.ie_Class = IECLASS_RAWKEY;
- FakedIEvent.ie_Code = ScummMsg->Code;
+ memset( &FakedIEvent, 0, sizeof( struct InputEvent ) );
+ FakedIEvent.ie_Class = IECLASS_RAWKEY;
+ FakedIEvent.ie_Code = ScummMsg->Code;
- if( ScummMsg->Code >= 0x50 && ScummMsg->Code <= 0x59 )
- {
- // Function key
- s->_keyPressed = (ScummMsg->Code-0x50)+315;
- }
- else if( MapRawKey( &FakedIEvent, &charbuf, 1, NULL ) == 1 )
+ if( ScummMsg->Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT) )
+ qual |= KBD_ALT;
+ if( ScummMsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT) )
+ qual |= KBD_SHIFT;
+ if( ScummMsg->Qualifier & IEQUALIFIER_CONTROL )
+ qual |= KBD_CTRL;
+ event->kbd.flags = qual;
+
+ event->event_code = EVENT_KEYDOWN;
+
+ if( ScummMsg->Code >= 0x50 && ScummMsg->Code <= 0x59 )
+ {
+ /*
+ * Function key
+ */
+ event->kbd.ascii = (ScummMsg->Code-0x50)+315;
+ event->kbd.keycode = 0; //ev.key.keysym.sym;
+ }
+ else if( MapRawKey( &FakedIEvent, &charbuf, 1, NULL ) == 1 )
+ {
+ if( qual & KBD_CTRL )
{
- if( charbuf >= '0' && charbuf <= '9' && !(ScummMsg->Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT)) )
+ switch( charbuf )
{
- s->_saveLoadSlot = charbuf - '0';
- if( ScummMsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT) )
- {
- sprintf(s->_saveLoadName, "Quicksave %d", s->_saveLoadSlot);
- s->_saveLoadFlag = 1;
- }
- else if( ScummMsg->Qualifier & IEQUALIFIER_CONTROL )
- s->_saveLoadFlag = 2;
- s->_keyPressed = charbuf;
- s->_saveLoadCompatible = false;
- }
- else if( ScummMsg->Qualifier & IEQUALIFIER_CONTROL )
- {
- switch( charbuf )
- {
- case 'z':
- ReplyMsg( (struct Message *)ScummMsg );
- exit(1);
-
- case 'd':
- debugger.attach(s);
- break;
-
- case 's':
- s->resourceStats();
- break;
- }
- }
- else if( ScummMsg->Qualifier & (IEQUALIFIER_RALT | IEQUALIFIER_LALT) )
- {
- if( charbuf >= '0' && charbuf <= '9' && ScummScalers[ charbuf-'0' ].gs_Name )
- {
+ case 'z':
ReplyMsg( (struct Message *)ScummMsg );
- ScummMsg = NULL;
- SwitchScalerTo( ScummScalers[ charbuf-'0' ].gs_Function );
- }
- else if( charbuf == 0x0d )
- {
- ReplyMsg( (struct Message *)ScummMsg );
- ScummMsg = NULL;
- createScreen( CSDSPTYPE_TOGGLE );
- }
+ exit(1);
}
- else
- s->_keyPressed = charbuf;
}
- break;
- }
-
- case IDCMP_MOUSEMOVE:
- {
- int newx,newy;
-
- newx = (ScummMsg->MouseX-ScummWindow->BorderLeft) >> ScummScale;
- newy = (ScummMsg->MouseY-ScummWindow->BorderTop) >> ScummScale;
-
- if (newx != s->mouse.x || newy != s->mouse.y)
+ else if( qual & KBD_ALT )
{
- if( newx < 0 || newx > 320 ||
- newy < 0 || newy > 200
- )
+ if( charbuf >= '0' && charbuf <= '9' && ScummScalers[ charbuf-'0' ].gs_Name )
{
- if( !ScummOrigMouse )
- {
- ScummOrigMouse = true;
- ClearPointer( ScummWindow );
- }
+ ReplyMsg( (struct Message *)ScummMsg );
+ SwitchScalerTo( ScummScalers[ charbuf-'0' ].gs_Type );
+ return false;
}
- else if( ScummOrigMouse )
+ else if( charbuf == 0x0d )
{
- ScummOrigMouse = false;
- SetPointer( ScummWindow, ScummNoCursor, 1, 1, 0, 0 );
+ ReplyMsg( (struct Message *)ScummMsg );
+ create_screen( CSDSPTYPE_TOGGLE );
+ return false;
}
- s->mouse.x = newx;
- s->mouse.y = newy;
- s->drawMouse();
}
- break;
- }
-
- case IDCMP_MOUSEBUTTONS:
- switch( ScummMsg->Code )
+ else
{
- case SELECTDOWN:
- s->_leftBtnPressed |= msClicked|msDown;
- break;
-
- case SELECTUP:
- s->_leftBtnPressed &= ~msDown;
- break;
-
- case MENUDOWN:
- s->_rightBtnPressed |= msClicked|msDown;
- break;
-
- case MENUUP:
- s->_rightBtnPressed &= ~msDown;
- break;
+ event->kbd.ascii = charbuf;
+ event->kbd.keycode = 0; //ev.key.keysym.sym;
}
- break;
-
- case IDCMP_CLOSEWINDOW:
- ReplyMsg( (struct Message *)ScummMsg );
- exit(1);
- break;
+ }
+ break;
}
- if( ScummMsg )
- ReplyMsg( (struct Message *)ScummMsg );
+ case IDCMP_MOUSEMOVE:
+ {
+ int newx,newy;
- cd_music_loop();
+ newx = (ScummMsg->MouseX-ScummWindow->BorderLeft) >> ScummScale;
+ newy = (ScummMsg->MouseY-ScummWindow->BorderTop) >> ScummScale;
- if( GetMsg( TimerMsgPort ) )
- {
- TimerStarted = false;
- AllDone = true;
+ if( newx < 0 || newx > 320 ||
+ newy < 0 || newy > 200
+ )
+ {
+ if( !ScummOrigMouse )
+ {
+ ScummOrigMouse = true;
+ ClearPointer( ScummWindow );
+ }
+ }
+ else if( ScummOrigMouse )
+ {
+ ScummOrigMouse = false;
+ SetPointer( ScummWindow, ScummNoCursor, 1, 1, 0, 0 );
+ }
+ event->event_code = EVENT_MOUSEMOVE;
+ event->mouse.x = newx;
+ event->mouse.y = newy;
break;
}
- }
- if( !AllDone )
- {
- signals = Wait( (1 << (ScummWindow->UserPort->mp_SigBit)) | (1 << (TimerMsgPort->mp_SigBit) ) );
+ case IDCMP_MOUSEBUTTONS:
+ {
+ int newx,newy;
+
+ newx = (ScummMsg->MouseX-ScummWindow->BorderLeft) >> ScummScale;
+ newy = (ScummMsg->MouseY-ScummWindow->BorderTop) >> ScummScale;
+
+ switch( ScummMsg->Code )
+ {
+ case SELECTDOWN:
+ event->event_code = EVENT_LBUTTONDOWN;
+ break;
+
+ case SELECTUP:
+ event->event_code = EVENT_LBUTTONUP;
+ break;
+
+ case MENUDOWN:
+ event->event_code = EVENT_RBUTTONDOWN;
+ break;
+
+ case MENUUP:
+ event->event_code = EVENT_RBUTTONUP;
+ break;
+
+ default:
+ ReplyMsg( (struct Message *)ScummMsg );
+ return false;
+ }
+ event->mouse.x = newx;
+ event->mouse.y = newy;
+ break;
+ }
- if( signals & (1 << (TimerMsgPort->mp_SigBit)) )
- {
- AllDone = true;
- TimerStarted = false;
- GetMsg( TimerMsgPort );
- }
+ case IDCMP_CLOSEWINDOW:
+ ReplyMsg( (struct Message *)ScummMsg );
+ exit( 0 );
}
- } while ( !AllDone );
+
+ if( ScummMsg )
+ ReplyMsg( (struct Message *)ScummMsg );
+
+ return true;
+ }
+
+ return false;
}
-void setShakePos( Scumm *s, int shake_pos )
+void OSystem_MorphOS::set_shake_pos( int shake_pos )
{
ScummShakePos = shake_pos;
}
@@ -871,7 +849,7 @@ void setShakePos( Scumm *s, int shake_pos )
#define SWAP_WORD( word ) word = ((word & 0xff) << 8) | (word >> 8)
-void Super2xSaI( uint32 src_x, uint32 src_y, uint32 dest_x, uint32 dest_y, uint32 width, uint32 height )
+void OSystem_MorphOS::Super2xSaI( uint32 src_x, uint32 src_y, uint32 dest_x, uint32 dest_y, uint32 width, uint32 height )
{
unsigned int x, y;
unsigned long color[16];
@@ -1093,7 +1071,7 @@ void Super2xSaI( uint32 src_x, uint32 src_y, uint32 dest_x, uint32 dest_y, uint3
UnLockBitMap( handle );
}
-void SuperEagle( uint32 src_x, uint32 src_y, uint32 dest_x, uint32 dest_y, uint32 width, uint32 height )
+void OSystem_MorphOS::SuperEagle( uint32 src_x, uint32 src_y, uint32 dest_x, uint32 dest_y, uint32 width, uint32 height )
{
unsigned int x, y;
unsigned long color[12];
@@ -1321,7 +1299,7 @@ void SuperEagle( uint32 src_x, uint32 src_y, uint32 dest_x, uint32 dest_y, uint3
UnLockBitMap( handle );
}
-void PointScaler( uint32 src_x, uint32 src_y, uint32 dest_x, uint32 dest_y, uint32 width, uint32 height )
+void OSystem_MorphOS::PointScaler( uint32 src_x, uint32 src_y, uint32 dest_x, uint32 dest_y, uint32 width, uint32 height )
{
byte *src;
byte *dest;
@@ -1353,7 +1331,7 @@ void PointScaler( uint32 src_x, uint32 src_y, uint32 dest_x, uint32 dest_y, uint
g = (ScummColors[ *(src+x) ] >> 8) & 0xff;
b = ScummColors[ *(src+x) ] & 0xff;
- color = makeColForPixFmt( dest_pixfmt, r, g, b );
+ color = make_color( dest_pixfmt, r, g, b );
if( PixelsPerMask == 2 )
{
if( ScummPCMode )
@@ -1384,49 +1362,34 @@ void PointScaler( uint32 src_x, uint32 src_y, uint32 dest_x, uint32 dest_y, uint
}
/* Copy part of bitmap */
-void blitToScreen(Scumm *s, byte *src, int x, int y, int w, int h)
+void OSystem_MorphOS::copy_rect(const byte *src, int pitch, int x, int y, int w, int h)
{
byte *dst;
- hide_mouse = true;
- if( has_mouse )
- s->drawMouse();
-
- if( y < 0 )
- {
- h += y;
- src -= y*320;
- y = 0;
- }
-
- if( h > 200 - y )
- h = 200 - y;
+ if (x < 0) { w+=x; src-=x; x = 0; }
+ if (y < 0) { h+=y; src-=y*pitch; y = 0; }
+ if (w >= 320-x) { w = 320 - x; }
+ if (h >= 200-y) { h = 200 - y; }
- if( h<=0 )
+ if (w<=0 || h<=0)
return;
+ /* FIXME: undraw mouse only if the draw rect intersects with the mouse rect */
+ if( MouseDrawn )
+ undraw_mouse();
+
dst = (byte *)ScummBuffer+y*320 + x;
do
{
memcpy( dst, src, w );
dst += 320;
- src += 320;
+ src += pitch;
} while( --h );
}
-void updateScreen(Scumm *s)
+void OSystem_MorphOS::update_screen()
{
- if( s->_fastMode & 2 )
- return;
-
- if( hide_mouse )
- {
- hide_mouse = false;
- s->drawMouse();
- }
-
- if(s->_palDirtyMax != -1)
- updatePalette(s);
+ draw_mouse();
if( !ScummScale )
{
@@ -1448,7 +1411,21 @@ void updateScreen(Scumm *s)
src_y = -ScummShakePos;
else
dest_y = ScummShakePos;
- (*ScummScaler)( 0, src_y, 0, dest_y, 320, 200-src_y-dest_y );
+
+ switch( ScummScaler )
+ {
+ case ST_POINT:
+ PointScaler( 0, src_y, 0, dest_y, 320, 200-src_y-dest_y );
+ break;
+
+ case ST_SUPEREAGLE:
+ SuperEagle( 0, src_y, 0, dest_y, 320, 200-src_y-dest_y );
+ break;
+
+ case ST_SUPER2XSAI:
+ Super2xSaI( 0, src_y, 0, dest_y, 320, 200-src_y-dest_y );
+ break;
+ }
}
/* Account for shaking (blacken rest of screen) */
@@ -1479,462 +1456,183 @@ void updateScreen(Scumm *s)
}
}
-void drawMouse(int xdraw, int ydraw, int w, int h, byte *buf, bool visible )
+void OSystem_MorphOS::draw_mouse()
{
int x,y;
byte *dst,*bak;
byte color;
- if( hide_mouse )
- visible = false;
+ if( MouseDrawn || !MouseVisible )
+ return;
+ MouseDrawn = true;
- assert( w<=BAK_WIDTH && h<=BAK_HEIGHT );
+ const int ydraw = MouseY - MouseHotspotY;
+ const int xdraw = MouseX - MouseHotspotX;
+ const int w = MouseWidth;
+ const int h = MouseHeight;
+ bak = MouseBackup;
+ byte *buf = MouseImage;
- if( has_mouse )
- {
- dst = (byte*)ScummBuffer + old_mouse_y*320 + old_mouse_x;
- bak = old_backup;
-
- for( y = 0; y < old_mouse_h; y++, bak+=BAK_WIDTH, dst+=320 )
- {
- if( (uint)(old_mouse_y + y) < 200 )
- {
- for( x=0; x < old_mouse_w; x++ )
- {
- if( (uint)(old_mouse_x + x) < 320 )
- dst[ x ] = bak[ x ];
- }
- }
- }
- }
+ MouseOldX = xdraw;
+ MouseOldY = ydraw;
+ MouseOldWidth = w;
+ MouseOldHeight = h;
- if( visible )
- {
- dst = (byte*)ScummBuffer + ydraw*320 + xdraw;
- bak = old_backup;
+ dst = (byte*)ScummBuffer + ydraw*320 + xdraw;
+ bak = MouseBackup;
- for( y = 0; y < h; y++, dst += 320, bak += BAK_WIDTH, buf += w )
+ for( y = 0; y < h; y++, dst += 320, bak += MAX_MOUSE_W, buf += w )
+ {
+ if( (uint)(ydraw+y) < 200 )
{
- if( (uint)(ydraw+y) < 200 )
+ for( x = 0; x<w; x++ )
{
- for( x=0; x<w; x++ )
+ if( (uint)(xdraw+x)<320 )
{
- if( (uint)(xdraw+x)<320 )
- {
- bak[x] = dst[x];
- if( (color=buf[x])!=0xFF )
- dst[ x ] = color;
- }
+ bak[x] = dst[x];
+ if( (color=buf[x])!=0xFF )
+ dst[ x ] = color;
}
}
}
}
-
- if( has_mouse )
- has_mouse = false;
-
- if( visible )
- {
- has_mouse = true;
- old_mouse_x = xdraw;
- old_mouse_y = ydraw;
- old_mouse_w = w;
- old_mouse_h = h;
- }
}
-
-void launcherLoop()
+void OSystem_MorphOS::undraw_mouse()
{
-#if 0
- int last_time, new_time;
- int delta = 0;
- last_time = GetTicks();
-
- gui.launcher();
- do
- {
- updateScreen(&scumm);
-
- new_time = GetTicks();
- waitForTimer( &scumm, delta * 15 + last_time - new_time );
- last_time = GetTicks();
-
- if (gui._active)
- {
- gui.loop();
- delta = 5;
- } else
- error("gui closed!");
- } while(1);
-#endif
-};
-
-void setWindowName( Scumm *s )
-{
- /* this is done in initGraphics() ... */
-}
-
-void initGraphics( Scumm *s, bool fullScreen, unsigned int scaleFactor )
-{
- ScummNoCursor = (UWORD *)AllocVec( 16, MEMF_CHIP | MEMF_CLEAR );
-
- /*
- * Allocate image buffer
- */
- ScummBuffer = AllocVec( 320*200, MEMF_ANY | MEMF_CLEAR );
-
- if( ScummBuffer == NULL )
- {
- puts( "Couldn't allocate image buffer" );
- exit( 1 );
- }
-
- memset( ScummColors, 0, 256*sizeof( ULONG ) );
-
- sprintf( ScummWndTitle, "ScummVM MorphOS - %s", s->_gameText);
+ int x,y;
+ byte *dst,*bak;
- createScreen( args[ USG_WBWINDOW ] ? CSDSPTYPE_WINDOWED : CSDSPTYPE_FULLSCREEN );
+ if( !MouseDrawn )
+ return;
+ MouseDrawn = false;
- InitSemaphore( &ScummMusicThreadRunning );
+ dst = (byte*)ScummBuffer + MouseOldY*320 + MouseOldX;
+ bak = MouseBackup;
- // Prepare for CD audio if game is Loom CD version
- if( (s->_features & GF_AUDIOTRACKS) && !args[ USG_NOMUSIC ] )
+ for( y = 0; y < MouseOldHeight; y++, bak += MAX_MOUSE_W, dst += 320 )
{
- FindCDTags[ 0 ].ti_Data = (ULONG)((s->_gameId == GID_LOOM256) ? "LoomCD" : "Monkey1CD");
- CDDABase = OpenLibrary( "cdda.library", 0 );
- if( CDDABase )
+ if( (uint)(MouseOldY + y) < 200 )
{
- CDrive = CDDA_FindNextDrive( NULL, FindCDTags );
- if( CDrive )
+ for( x = 0; x < MouseOldWidth; x++ )
{
- if( !CDDA_ObtainDrive( CDrive, CDDA_SHARED_ACCESS, NULL ) )
- {
- CDrive = NULL;
- warning( "Failed to obtain CD drive - music will not play" );
- }
- else if( s->_gameId == GID_LOOM256 )
- {
- // Offset correction *may* be required
- struct CDS_TrackInfo ti;
-
- if( CDDA_GetTrackInfo( CDrive, 1, 0, &ti ) )
- CDDATrackOffset = ti.ti_TrackStart.tm_Format.tm_Frame-22650;
- }
+ if( (uint)(MouseOldX + x) < 320 )
+ dst[ x ] = bak[ x ];
}
- else
- warning( "Could not find game CD inserted in CD-ROM drive - music will not play" );
}
- else
- warning( "Failed to open cdda.library - music will not play" );
- args[ USG_NOMUSIC ] = TRUE; // this avoids AMidi being opened ...
- }
-
- // Create Music Thread
- MyEmulFunc.Trap = TRAP_FUNC;
- MyEmulFunc.Address = (ULONG)&morphos_music_thread;
- MyEmulFunc.StackSize = 8192;
- MyEmulFunc.Extension = 0;
- MyEmulFunc.Arg1 = (ULONG)&scumm;
- MyEmulFunc.Arg2 = (ULONG)ScummMidiUnit;
- MyEmulFunc.Arg3 = (ULONG)args[ USG_NOMUSIC ];
- ScummMusicThread = CreateNewProc( musicProcTags );
- if( !ScummMusicThread )
- {
- puts( "Failed to create music thread" );
- exit( 1 );
}
}
-static bool FindScaler( const char *ScalerName )
+bool OSystem_MorphOS::show_mouse(bool visible)
{
- int scaler = 0;
-
- while( ScummScalers[ scaler ].gs_Name )
- {
- if( !stricmp( ScalerName, ScummScalers[ scaler ].gs_Name ) )
- {
- ScummScaler = ScummScalers[ scaler ].gs_Function;
- break;
- }
- scaler++;
- }
+ if( MouseVisible == visible )
+ return visible;
- if( ScummScalers[ scaler ].gs_Name == NULL )
- {
- puts( "Invalid scaler name. Please use one of the following:" );
- for( scaler = 0; ScummScalers[ scaler ].gs_Name != NULL; scaler++ )
- printf( " %s\n", ScummScalers[ scaler ].gs_Name );
- return false;
- }
+ bool last = MouseVisible;
+ MouseVisible = visible;
- ScummScaler = ScummScalers[ scaler ].gs_Function;
- if( ScummScaler == NULL )
- ScummScale = 0;
+ if( visible )
+ draw_mouse();
else
- ScummScale = 1;
+ undraw_mouse();
- return true;
+ return last;
}
-static void ReadToolTypes( struct WBArg *OfFile )
+void OSystem_MorphOS::set_mouse_pos(int x, int y)
{
- struct DiskObject *dobj;
- char *ToolValue;
- char IconPath[ 256 ];
-
- NameFromLock( OfFile->wa_Lock, IconPath, 256 );
- AddPart( IconPath, OfFile->wa_Name, 256 );
-
- dobj = GetDiskObject( IconPath );
- if( dobj == NULL )
- return;
-
- if( ToolValue = (char *)FindToolType( dobj->do_ToolTypes, "STORY" ) )
- {
- if( ScummStory )
- FreeVec( ScummStory );
- ScummStory = (char *)AllocVec( strlen( ToolValue )+1, MEMF_PUBLIC );
- strcpy( ScummStory, ToolValue );
- }
-
- if( ToolValue = (char *)FindToolType( dobj->do_ToolTypes, "DATAPATH" ) )
- {
- if( ScummPath )
- FreeVec( ScummPath );
- ScummPath = (char *)AllocVec( strlen( ToolValue )+4, MEMF_PUBLIC );
- strcpy( ScummPath, "-p" );
- strcat( ScummPath, ToolValue );
- }
-
- if( ToolValue = (char *)FindToolType( dobj->do_ToolTypes, "WBWINDOW" ) )
- {
- if( MatchToolValue( ToolValue, "YES" ) )
- args[ USG_WBWINDOW ] = TRUE;
- else if( MatchToolValue( ToolValue, "NO" ) )
- args[ USG_WBWINDOW ] = FALSE;
- }
-
- if( ToolValue = (char *)FindToolType( dobj->do_ToolTypes, "SCALER" ) )
- {
- if( !FindScaler( ToolValue ) )
- {
- FreeDiskObject( dobj );
- exit( 1 );
- }
- }
-
- if( ToolValue = (char *)FindToolType( dobj->do_ToolTypes, "MUSIC" ) )
+ if (x != MouseX || y != MouseY)
{
- if( MatchToolValue( ToolValue, "YES" ) )
- args[ USG_NOMUSIC ] = FALSE;
- else if( MatchToolValue( ToolValue, "NO" ) )
- args[ USG_NOMUSIC ] = TRUE;
+ MouseX = x;
+ MouseY = y;
+ undraw_mouse();
}
+}
- if( ToolValue = (char *)FindToolType( dobj->do_ToolTypes, "MIDIUNIT" ) )
- ScummMidiUnit = atoi( ToolValue );
+void OSystem_MorphOS::set_mouse_cursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y)
+{
+ MouseWidth = w;
+ MouseHeight = h;
- if( ToolValue = (char *)FindToolType( dobj->do_ToolTypes, "VOLUME" ) )
- {
- int vol = atoi( ToolValue );
- if( vol >= 0 && vol <= 100 )
- {
- ScummMidiVolume = vol;
- args[ USG_VOLUME ] = (ULONG)&ScummMidiVolume;
- }
- }
+ MouseHotspotX = hotspot_x;
+ MouseHotspotY = hotspot_y;
- if( ToolValue = (char *)FindToolType( dobj->do_ToolTypes, "TEMPO" ) )
- {
- ScummMidiTempo = atoi( ToolValue );
- args[ USG_TEMPO ] = (ULONG)&ScummMidiTempo;
- }
-
- if( ToolValue = (char *)FindToolType( dobj->do_ToolTypes, "SUBTITLES" ) )
- {
- if( MatchToolValue( ToolValue, "YES" ) )
- args[ USG_NOSUBTITLES ] = FALSE;
- else if( MatchToolValue( ToolValue, "NO" ) )
- args[ USG_NOSUBTITLES ] = TRUE;
- }
+ MouseImage = (byte*)buf;
- FreeDiskObject( dobj );
+ undraw_mouse();
}
-#undef main
-
-int main( int argc, char *argv[] )
+void OSystem_MorphOS::set_sound_proc( void *param, OSystem::SoundProc *proc, byte format )
{
- int delta;
- int last_time, new_time;
-
- CyberGfxBase = OpenLibrary( "cybergraphics.library", 41 );
- if( CyberGfxBase == NULL )
- {
- puts( "Failed to open cybergraphics.library" );
- exit( 1 );
- }
+ static EmulFunc MySoundEmulFunc;
- atexit( &closeResources );
+ SoundProc = proc;
+ SoundParam = param;
- TimerMsgPort = CreateMsgPort();
- if( TimerMsgPort == NULL )
- {
- puts( "Failed to create message port" );
- exit( 1 );
- }
+ /*
+ * Create Sound Thread
+ */
+ MySoundEmulFunc.Trap = TRAP_FUNC;
+ MySoundEmulFunc.Address = (ULONG)&morphos_sound_thread;
+ MySoundEmulFunc.StackSize = 8192;
+ MySoundEmulFunc.Extension = 0;
+ MySoundEmulFunc.Arg1 = (ULONG)this;
+ MySoundEmulFunc.Arg2 = AHIST_M16S;
- TimerIORequest = (struct timerequest *)CreateIORequest( TimerMsgPort, sizeof( struct timerequest ) );
- if( TimerIORequest == NULL )
- {
- puts( "Failed to create IO request" );
- exit( 1 );
- }
+ soundProcTags[ 0 ].ti_Data = (ULONG)&MySoundEmulFunc;
+ ScummSoundThread = CreateNewProc( soundProcTags );
- if( OpenDevice( "timer.device", UNIT_MICROHZ, (struct IORequest *)TimerIORequest, 0 ) )
+ if( !ScummSoundThread )
{
- DeleteIORequest( (struct IORequest *)TimerIORequest );
- TimerIORequest = NULL;
- puts( "Failed to open timer device" );
+ puts( "Failed to create sound thread" );
exit( 1 );
}
+}
- TimerBase = TimerIORequest->tr_node.io_Device;
-
- if( _WBenchMsg == NULL )
- {
- /* Parse the command line here */
- ScummArgs = ReadArgs( usageTemplate, args, NULL );
- if( ScummArgs == NULL )
- {
- puts( "Error in command line - type \"ScummVM ?\" for usage.\n" );
- exit( 1 );
- }
-
- if( args[ USG_STORY ] )
- {
- ScummStory = (char *)AllocVec( strlen( (char *)args[ USG_STORY ] )+1, MEMF_PUBLIC );
- strcpy( ScummStory, (char *)args[ USG_STORY ] );
- }
-
- if( args[ USG_DATAPATH ] )
- {
- ScummPath = (char *)AllocVec( strlen( (char *)args[ USG_DATAPATH ] )+4, MEMF_PUBLIC );
- strcpy( ScummPath, "-p" );
- strcat( ScummPath, (char *)args[ USG_DATAPATH ] );
- }
-
- if( args[ USG_SCALER ] )
- {
- if( !FindScaler( (char *)args[ USG_SCALER ] ) )
- exit( 1 );
- }
-
- if( args[ USG_MIDIUNIT ] )
- ScummMidiUnit = *((LONG *)args[ USG_MIDIUNIT ]);
-
- if( args[ USG_TEMPO ] )
- ScummMidiTempo = *((LONG *)args[ USG_TEMPO ]);
-
- if( args[ USG_VOLUME ] )
- ScummMidiVolume = *((LONG *)args[ USG_VOLUME ]);
- }
+void OSystem_MorphOS::fill_sound( byte *stream, int len )
+{
+ if( SoundProc )
+ SoundProc( SoundParam, stream, len );
else
- {
- /* We've been started from Workbench */
- ReadToolTypes( &_WBenchMsg->sm_ArgList[ 0 ] );
- if( _WBenchMsg->sm_NumArgs > 1 )
- {
- ReadToolTypes( &_WBenchMsg->sm_ArgList[ 1 ] );
- OrigDirLock = CurrentDir( _WBenchMsg->sm_ArgList[ 1 ].wa_Lock );
- }
- }
-
- if( ScummPath )
- {
- char c = ScummPath[ strlen( ScummPath )-1 ];
- if( c != '/' && c != ':' )
- strcat( ScummPath, "/" );
- }
+ memset( stream, 0x0, len );
+}
- char *argvfake[] = { "ScummVM", (char *)ScummStory, "-e5", (char *)ScummPath };
- if( detector.detectMain( ScummPath ? 4 : 3, argvfake ) )
- exit( 1 );
+void OSystem_MorphOS::init_size( uint w, uint h )
+{
+ /*
+ * Allocate image buffer
+ */
+ ScummBuffer = AllocVec( w*h, MEMF_ANY | MEMF_CLEAR );
- if( detector._features & GF_OLD256 )
- scumm = new Scumm_v3;
- else if( detector._features & GF_SMALL_HEADER ) // this force loomCD as v4
- scumm = new Scumm_v4;
- else if( detector._features & GF_AFTER_V7 )
- scumm = new Scumm_v7;
- else if( detector._features & GF_AFTER_V6 ) // this force SamnmaxCD as v6
- scumm = new Scumm_v6;
- else
- scumm = new Scumm_v5;
-
- scumm->_fullScreen = detector._fullScreen;
- scumm->_debugMode = detector._debugMode;
- scumm->_bootParam = detector._bootParam;
- scumm->_scale = detector._scale;
- scumm->_gameDataPath = detector._gameDataPath;
- scumm->_gameTempo = detector._gameTempo;
- scumm->_videoMode = detector._videoMode;
- scumm->_exe_name = detector._exe_name;
- scumm->_gameId = detector._gameId;
- scumm->_gameText = detector._gameText;
- scumm->_features = detector._features;
- scumm->_soundCardType = detector._soundCardType;
- scumm->_noSubtitles = args[ USG_NOSUBTITLES ] != FALSE;
-
- if( args[ USG_VOLUME ] )
+ if( ScummBuffer == NULL )
{
- int vol = *(LONG *)args[ USG_VOLUME ];
- if( vol >= 0 && vol <= 100 )
- sound.set_music_volume( vol );
+ puts( "Couldn't allocate image buffer" );
+ exit( 1 );
}
- if( args[ USG_TEMPO ] )
- scumm->_gameTempo = *(LONG *)args[ USG_TEMPO ];
-
- scumm->delta=6;
-
- scumm->_gui = &gui;
- sound.initialize(scumm, &snd_driv);
-
- scumm->delta=0;
- scumm->_system = &_system;
- _system.last_time=0;
-
- scumm->launch();
-
- gui.init(scumm); /* Reinit GUI after loading a game */
- scumm->mainRun();
+ memset( ScummColors, 0, 256*sizeof( ULONG ) );
- return 0;
+ create_screen( CSDSPTYPE_KEEP );
}
-int OSystem::waitTick(int delta)
+OSystem_MorphOS::SCALERTYPE OSystem_MorphOS::FindScaler( const char *ScalerName )
{
- do
+ int scaler = 0;
+
+ while( ScummScalers[ scaler ].gs_Name )
{
- updateScreen( scumm );
- new_time = GetTicks();
- waitForTimer( scumm, delta * 15 + last_time - new_time );
- last_time = GetTicks();
- if( gui._active )
- {
- gui.loop( scumm );
- delta = 5;
- }
+ if( !stricmp( ScalerName, ScummScalers[ scaler ].gs_Name ) )
+ return ScummScalers[ scaler ].gs_Type;
+ scaler++;
}
- while( gui._active );
- return( delta );
-}
+ if( ScummScalers[ scaler ].gs_Name == NULL )
+ {
+ puts( "Invalid scaler name. Please use one of the following:" );
+ for( scaler = 0; ScummScalers[ scaler ].gs_Name != NULL; scaler++ )
+ printf( " %s\n", ScummScalers[ scaler ].gs_Name );
+ }
-OSystem::OSystem()
-{
- last_time = GetTicks();
+ return ST_INVALID;
}
diff --git a/morphos/morphos.h b/morphos/morphos.h
new file mode 100644
index 0000000000..be198f4715
--- /dev/null
+++ b/morphos/morphos.h
@@ -0,0 +1,182 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2002 Rüdiger Hanke (MorphOS port)
+ *
+ * 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * MorphOS-specific header file
+ *
+ * $Header$
+ *
+ */
+
+#include <exec/semaphores.h>
+#include <libraries/cdda.h>
+
+class OSystem_MorphOS : public OSystem
+{
+ public:
+ typedef enum { ST_INVALID = 0, ST_NONE, ST_POINT, ST_SUPEREAGLE, ST_SUPER2XSAI } SCALERTYPE;
+
+ OSystem_MorphOS( int game_id, SCALERTYPE gfx_mode, bool full_screen );
+ virtual ~OSystem_MorphOS();
+
+ // Set colors of the palette
+ virtual void set_palette(const byte *colors, uint start, uint num);
+
+ // Set the size of the video bitmap.
+ // Typically, 320x200
+ virtual void init_size(uint w, uint h);
+
+ // Draw a bitmap to screen.
+ // The screen will not be updated to reflect the new bitmap
+ virtual void copy_rect(const byte *buf, int pitch, int x, int y, int w, int h);
+
+ // Update the dirty areas of the screen
+ virtual void update_screen();
+
+ // Either show or hide the mouse cursor
+ virtual bool show_mouse(bool visible);
+
+ // Set the position of the mouse cursor
+ virtual void set_mouse_pos(int x, int y);
+
+ // Set the bitmap that's used when drawing the cursor.
+ virtual void set_mouse_cursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y);
+
+ // Shaking is used in SCUMM. Set current shake position.
+ virtual void set_shake_pos(int shake_pos);
+
+ // Get the number of milliseconds since the program was started.
+ virtual uint32 get_msecs();
+
+ // Delay for a specified amount of milliseconds
+ virtual void delay_msecs(uint msecs);
+
+ // Create a thread
+ virtual void *create_thread(ThreadProc *proc, void *param);
+
+ // Get the next event.
+ // Returns true if an event was retrieved.
+ virtual bool poll_event(Event *event);
+
+ // Set the function to be invoked whenever samples need to be generated
+ virtual void set_sound_proc(void *param, SoundProc *proc, byte format);
+ void fill_sound (byte * stream, int len);
+
+ virtual uint32 property(int param, uint32 value);
+
+ // Quit
+ virtual void quit();
+
+ static OSystem_MorphOS *create ( int game_id, SCALERTYPE gfx_scaler, bool full_screen );
+ static uint32 make_color( int pixfmt, int r, int g, int b );
+
+ static SCALERTYPE FindScaler ( const char *ScalerName );
+
+ private:
+ typedef void (*ScalerFunc)( uint32 src_x, uint32 src_y, uint32 dest_x, uint32 dest_y, uint32 width, uint32 height );
+ typedef enum { CSDSPTYPE_WINDOWED, CSDSPTYPE_FULLSCREEN, CSDSPTYPE_TOGGLE, CSDSPTYPE_KEEP } CS_DSPTYPE;
+
+ struct GfxScaler
+ {
+ STRPTR gs_Name;
+ SCALERTYPE gs_Type;
+ };
+
+ static const int MAX_MOUSE_W = 40;
+ static const int MAX_MOUSE_H = 40;
+
+ void create_screen ( CS_DSPTYPE dspType );
+ void SwitchScalerTo ( SCALERTYPE newScaler );
+ void Super2xSaI ( uint32 src_x, uint32 src_y, uint32 dest_x, uint32 dest_y, uint32 width, uint32 height );
+ void SuperEagle ( uint32 src_x, uint32 src_y, uint32 dest_x, uint32 dest_y, uint32 width, uint32 height );
+ void PointScaler ( uint32 src_x, uint32 src_y, uint32 dest_x, uint32 dest_y, uint32 width, uint32 height );
+
+ void draw_mouse();
+ void undraw_mouse();
+
+ /* Display-related attributes */
+ struct Screen *ScummScreen;
+ struct Window *ScummWindow;
+ char ScummWndTitle[ 125 ];
+ APTR ScummBuffer;
+ struct ScreenBuffer *ScummScreenBuffer[ 2 ];
+ struct BitMap *ScummRenderTo;
+ bool ScummPCMode;
+ ULONG ScummPaintBuffer;
+ int ScummScrWidth;
+ int ScummScrHeight;
+ int ScummDepth;
+ bool Scumm16ColFmt16;
+ UWORD *ScummNoCursor;
+ ULONG ScummColors[256];
+ USHORT ScummColors16[256];
+ WORD ScummWinX;
+ WORD ScummWinY;
+ bool ScummOrigMouse;
+ int ScummShakePos;
+ bool FullScreenMode;
+
+ /* Scaling-related attributes */
+ uint32 colorMask;
+ uint32 lowPixelMask;
+ uint32 qcolorMask;
+ uint32 qlowpixelMask;
+ uint32 redblueMask;
+ uint32 greenMask;
+ int PixelsPerMask;
+ byte *src_line[4];
+ byte *dst_line[2];
+
+ /* Sound-related attributes */
+ struct Process *ScummMusicThread;
+ struct Process *ScummSoundThread;
+ SoundProc *SoundProc;
+ void *SoundParam;
+
+ /* CD-ROM related attributes */
+ CDRIVEPTR CDrive;
+ ULONG CDDATrackOffset;
+
+ /* Scaling-related attributes */
+ SCALERTYPE ScummScaler;
+ int ScummScale;
+ static GfxScaler ScummScalers[ 10 ];
+
+ /* Mouse cursor-related attributes */
+ bool MouseVisible, MouseDrawn;
+ int MouseX, MouseY;
+ int MouseWidth, MouseHeight;
+ int MouseOldX, MouseOldY;
+ int MouseOldWidth, MouseOldHeight;
+ int MouseHotspotX, MouseHotspotY;
+ byte *MouseImage, MouseBackup[ MAX_MOUSE_W*MAX_MOUSE_H ];
+
+ /* Timer-related attributes */
+ struct MsgPort *TimerMsgPort;
+ struct timerequest *TimerIORequest;
+
+ /* Game-related attributes */
+ int GameID;
+};
+
+int morphos_sound_thread( OSystem_MorphOS *syst, ULONG SampleType );
+
+int morphos_main( int argc, char *argv[] );
+
+extern OSystem_MorphOS *TheSystem;
+extern struct SignalSemaphore ScummMusicThreadRunning;
+extern struct SignalSemaphore ScummSoundThreadRunning;
+
diff --git a/morphos/morphos_sound.cpp b/morphos/morphos_sound.cpp
index 99f55807fe..43de32f244 100644
--- a/morphos/morphos_sound.cpp
+++ b/morphos/morphos_sound.cpp
@@ -31,26 +31,22 @@
#include <devices/ahi.h>
#include <devices/amidi.h>
-#define NO_PPCINLINE_STDARG
-#define NO_PPCINLINE_VARARGS
#include <clib/alib_protos.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/ahi.h>
-extern int GetTicks();
-extern Scumm scumm;
-extern IMuse sound;
-extern SOUND_DRIVER_TYPE snd_driv;
+#include "morphos.h"
#define AHI_BUF_SIZE (8*1024)
struct SignalSemaphore ScummMusicThreadRunning;
+struct SignalSemaphore ScummSoundThreadRunning;
static struct MsgPort *ahiPort = NULL;
static struct AHIRequest *ahiReq[ 2 ] = { NULL, NULL };
static UWORD ahiCurBuf = 0;
-static BOOL ahiReqSent[ 2 ] = { FALSE, FALSE };
+static bool ahiReqSent[ 2 ] = { false, false };
static BYTE ahiDevice = -1;
UBYTE ahiUnit = AHI_DEFAULT_UNIT;
static char *ahiBuf[ 2 ] = { NULL, NULL };
@@ -58,7 +54,7 @@ static char *ahiBuf[ 2 ] = { NULL, NULL };
static struct MsgPort *ScummMidiPort = NULL;
struct IOMidiRequest *ScummMidiRequest = NULL;
-bool init_morphos_sound( ULONG MidiUnit, bool NoMusic )
+bool init_morphos_music( ULONG MidiUnit, bool NoMusic )
{
if( !NoMusic )
{
@@ -85,9 +81,29 @@ bool init_morphos_sound( ULONG MidiUnit, bool NoMusic )
}
if( !ScummMidiRequest )
+ {
warning( "Could not open AMidi - music will not play" );
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+void exit_morphos_music()
+{
+ if( ScummMidiRequest )
+ {
+ CloseDevice( (struct IORequest *)ScummMidiRequest );
+ DeleteIORequest( (struct IORequest *)ScummMidiRequest );
+ DeleteMsgPort( ScummMidiPort );
}
+}
+
+static bool init_morphos_sound()
+{
if( !(ahiPort = CreateMsgPort()) )
return false;
@@ -135,19 +151,16 @@ bool init_morphos_sound( ULONG MidiUnit, bool NoMusic )
CopyMem( ahiReq[ 0 ], ahiReq[ 1 ], sizeof( struct AHIRequest ) );
+ ahiCurBuf = 0;
+ ahiReqSent[ 0 ] = FALSE;
+ ahiReqSent[ 1 ] = FALSE;
+
return true;
}
-void exit_morphos_sound()
+static void exit_morphos_sound()
{
- if( ScummMidiRequest )
- {
- CloseDevice( (struct IORequest *)ScummMidiRequest );
- DeleteIORequest( (struct IORequest *)ScummMidiRequest );
- DeleteMsgPort( ScummMidiPort );
- }
-
if( ahiReq[ 1 ] )
FreeVec( ahiReq[ 1 ] );
@@ -167,6 +180,7 @@ void exit_morphos_sound()
int morphos_music_thread( Scumm *s, ULONG MidiUnit, bool NoMusic )
{
+#if 0
int old_time, cur_time;
bool initialized;
bool TimerAvailable = false;
@@ -175,7 +189,7 @@ int morphos_music_thread( Scumm *s, ULONG MidiUnit, bool NoMusic )
ObtainSemaphore( &ScummMusicThreadRunning );
- initialized = init_morphos_sound( MidiUnit, NoMusic );
+ initialized = init_morphos_music( MidiUnit, NoMusic );
if( !initialized )
warning( "Sound could not be initialized" );
@@ -204,44 +218,68 @@ int morphos_music_thread( Scumm *s, ULONG MidiUnit, bool NoMusic )
}
else
{
- old_time = GetTicks();
+ old_time = 0;//GetTicks();
for(;;)
{
if( CheckSignal( SIGBREAKF_CTRL_F ) )
- {
- if( ahiReqSent[ ahiCurBuf ] )
- {
- AbortIO( (struct IORequest *)ahiReq[ ahiCurBuf ] );
- WaitIO ( (struct IORequest *)ahiReq[ ahiCurBuf ] );
- }
break;
- }
- if( !snd_driv.wave_based() )
+/* if( !snd_driv.wave_based() )
{
cur_time = GetTicks();
while( old_time < cur_time )
{
old_time += 10;
sound.on_timer();
- }
+ }*/
/* TimerIORequest->tr_time.tv_micro = (old_time-cur_time)*1000;
if( TimerIORequest->tr_time.tv_micro == 0 )
TimerIORequest->tr_time.tv_micro = 100;*/
- TimerIORequest->tr_time.tv_micro = 10000;
+/* TimerIORequest->tr_time.tv_micro = 10000;
}
else
- TimerIORequest->tr_time.tv_micro = 10000;
+ TimerIORequest->tr_time.tv_micro = 10000;*/
TimerIORequest->tr_node.io_Command = TR_ADDREQUEST;
TimerIORequest->tr_time.tv_secs = 0;
DoIO( (struct IORequest *)TimerIORequest );
+ }
+ }
+
+ if( TimerAvailable )
+ {
+ CloseDevice( (struct IORequest *)TimerIORequest );
+ DeleteIORequest( (struct IORequest *)TimerIORequest );
+ DeleteMsgPort( TimerMsgPort );
+ }
+
+ exit_morphos_music();
+
+ ReleaseSemaphore( &ScummMusicThreadRunning );
+ return 0;
+#endif
+}
- if( !initialized )
- continue;
- if( !ahiReqSent[ ahiCurBuf ] || CheckIO( (struct IORequest *)ahiReq[ ahiCurBuf ] ) )
+int morphos_sound_thread( OSystem_MorphOS *syst, ULONG SampleType )
+{
+ ULONG signals;
+ bool initialized;
+
+ ObtainSemaphore( &ScummSoundThreadRunning );
+
+ initialized = init_morphos_sound();
+ if( !initialized )
+ {
+ warning( "Sound could not be initialized. The game may hang at some point (press Ctrl-z then)." );
+ Wait( SIGBREAKF_CTRL_C );
+ }
+ else
+ {
+ for(;;)
+ {
+ while( !ahiReqSent[ ahiCurBuf ] || CheckIO( (struct IORequest *)ahiReq[ ahiCurBuf ] ) )
{
struct AHIRequest *req = ahiReq[ ahiCurBuf ];
UWORD ahiOtherBuf = !ahiCurBuf;
@@ -249,38 +287,48 @@ int morphos_music_thread( Scumm *s, ULONG MidiUnit, bool NoMusic )
if( ahiReqSent[ ahiCurBuf ] )
WaitIO( (struct IORequest *)req );
- if( CheckSignal( SIGBREAKF_CTRL_F ) )
- break;
-
- scumm.mixWaves( (int16 *)ahiBuf[ ahiCurBuf ], AHI_BUF_SIZE >> 1 );
-
+ syst->fill_sound( (byte *)ahiBuf[ ahiCurBuf ], AHI_BUF_SIZE );
+
req->ahir_Std.io_Message.mn_Node.ln_Pri = 0;
req->ahir_Std.io_Command = CMD_WRITE;
req->ahir_Std.io_Data = ahiBuf[ ahiCurBuf ];
req->ahir_Std.io_Length = AHI_BUF_SIZE;
- req->ahir_Type = AHIST_M16S;
+ req->ahir_Type = SampleType;
req->ahir_Frequency = SAMPLES_PER_SEC;
req->ahir_Position = 0x8000;
req->ahir_Volume = 0x10000;
req->ahir_Link = (ahiReqSent[ ahiOtherBuf ] && !CheckIO( (struct IORequest *)ahiReq[ ahiOtherBuf ] )) ? ahiReq[ ahiOtherBuf ] : NULL;
SendIO( (struct IORequest *)req );
- ahiReqSent[ ahiCurBuf ] = TRUE;
+ ahiReqSent[ ahiCurBuf ] = true;
ahiCurBuf = ahiOtherBuf;
}
+
+ signals = Wait( SIGBREAKF_CTRL_C | (1 << ahiPort->mp_SigBit) );
+
+ if( signals & SIGBREAKF_CTRL_C )
+ break;
}
- }
- if( TimerAvailable )
- {
- CloseDevice( (struct IORequest *)TimerIORequest );
- DeleteIORequest( (struct IORequest *)TimerIORequest );
- DeleteMsgPort( TimerMsgPort );
+ if( ahiReqSent[ ahiCurBuf ] )
+ {
+ AbortIO( (struct IORequest *)ahiReq[ ahiCurBuf ] );
+ WaitIO ( (struct IORequest *)ahiReq[ ahiCurBuf ] );
+ ahiReqSent[ ahiCurBuf ] = false;
+ }
+
+ if( ahiReqSent[ !ahiCurBuf ] )
+ {
+ AbortIO( (struct IORequest *)ahiReq[ !ahiCurBuf ] );
+ WaitIO ( (struct IORequest *)ahiReq[ !ahiCurBuf ] );
+ ahiReqSent[ !ahiCurBuf ] = false;
+ }
}
exit_morphos_sound();
- ReleaseSemaphore( &ScummMusicThreadRunning );
+ ReleaseSemaphore( &ScummSoundThreadRunning );
+ RemTask( NULL );
return 0;
}
diff --git a/morphos/morphos_start.cpp b/morphos/morphos_start.cpp
new file mode 100644
index 0000000000..2e4438611c
--- /dev/null
+++ b/morphos/morphos_start.cpp
@@ -0,0 +1,309 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2002 Rüdiger Hanke (MorphOS port)
+ *
+ * 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * MorphOS startup handling
+ *
+ * $Header$
+ *
+ */
+
+#include <exec/types.h>
+#include <exec/memory.h>
+#include <exec/libraries.h>
+#include <workbench/startup.h>
+#include <workbench/workbench.h>
+
+#include <proto/exec.h>
+#include <proto/dos.h>
+#include <proto/cdda.h>
+#include <proto/cybergraphics.h>
+#include <proto/icon.h>
+
+#include "stdafx.h"
+#include "scumm.h"
+#include "morphos.h"
+
+extern "C" struct WBStartup *_WBenchMsg;
+
+// For command line parsing
+static STRPTR usageTemplate = "STORY/A,DATAPATH/K,WBWINDOW/S,SCALER/K,MIDIUNIT/K/N,NOMUSIC/S,VOLUME/K/N,TEMPO/K/N,ROLANDEMU/S,NOSUBTITLES=NST/S";
+typedef enum { USG_STORY = 0, USG_DATAPATH, USG_WBWINDOW, USG_SCALER, USG_MIDIUNIT, USG_NOMUSIC, USG_VOLUME, USG_TEMPO, USG_ROLANDEMU, USG_NOSUBTITLES } usageFields;
+static LONG args[ 10 ] = { (ULONG)NULL, (ULONG)NULL, FALSE, (ULONG)NULL, (ULONG)NULL, false, (ULONG)NULL, (ULONG)NULL, false, false };
+static struct RDArgs *ScummArgs = NULL;
+
+static char*ScummStory = NULL;
+static char*ScummPath = NULL;
+static LONG ScummMidiUnit = 0;
+static LONG ScummMidiVolume = 0;
+static LONG ScummMidiTempo = 0;
+static OSystem_MorphOS::SCALERTYPE ScummGfxScaler = OSystem_MorphOS::ST_INVALID;
+
+static BPTR OrigDirLock = 0;
+
+struct Library *CDDABase = NULL;
+struct Library *CyberGfxBase = NULL;
+
+OSystem_MorphOS *TheSystem = NULL;
+
+OSystem *OSystem_MorphOS_create( int game_id, int gfx_mode, bool full_screen)
+{
+ if( TheSystem )
+ delete TheSystem;
+
+ OSystem_MorphOS::SCALERTYPE gfx_scaler = OSystem_MorphOS::ST_NONE;
+ switch( gfx_mode )
+ {
+ case GFX_DOUBLESIZE:
+ gfx_scaler = OSystem_MorphOS::ST_POINT;
+ break;
+
+ case GFX_SUPEREAGLE:
+ gfx_scaler = OSystem_MorphOS::ST_SUPEREAGLE;
+ break;
+
+ case GFX_SUPER2XSAI:
+ gfx_scaler = OSystem_MorphOS::ST_SUPER2XSAI;
+ break;
+ }
+
+ TheSystem = OSystem_MorphOS::create( game_id, gfx_scaler, full_screen );
+ return TheSystem;
+}
+
+void close_resources()
+{
+ if( TheSystem )
+ delete TheSystem;
+
+ if( ScummPath )
+ FreeVec( ScummPath );
+
+ if( ScummStory )
+ FreeVec( ScummStory );
+
+ if( ScummArgs )
+ FreeArgs( ScummArgs );
+
+ if( OrigDirLock )
+ CurrentDir( OrigDirLock );
+
+ if( CDDABase )
+ CloseLibrary( CDDABase );
+
+ if( CyberGfxBase )
+ CloseLibrary( CyberGfxBase );
+}
+
+void ReadToolTypes( struct WBArg *OfFile )
+{
+ struct DiskObject *dobj;
+ char *ToolValue;
+ char IconPath[ 256 ];
+
+ NameFromLock( OfFile->wa_Lock, IconPath, 256 );
+ AddPart( IconPath, OfFile->wa_Name, 256 );
+
+ dobj = GetDiskObject( IconPath );
+ if( dobj == NULL )
+ return;
+
+ if( ToolValue = (char *)FindToolType( dobj->do_ToolTypes, "STORY" ) )
+ {
+ if( ScummStory )
+ FreeVec( ScummStory );
+ ScummStory = (char *)AllocVec( strlen( ToolValue )+1, MEMF_PUBLIC );
+ strcpy( ScummStory, ToolValue );
+ }
+
+ if( ToolValue = (char *)FindToolType( dobj->do_ToolTypes, "DATAPATH" ) )
+ {
+ if( ScummPath )
+ FreeVec( ScummPath );
+ ScummPath = (char *)AllocVec( strlen( ToolValue )+4, MEMF_PUBLIC );
+ strcpy( ScummPath, "-p" );
+ strcat( ScummPath, ToolValue );
+ }
+
+ if( ToolValue = (char *)FindToolType( dobj->do_ToolTypes, "WBWINDOW" ) )
+ {
+ if( MatchToolValue( ToolValue, "YES" ) )
+ args[ USG_WBWINDOW ] = TRUE;
+ else if( MatchToolValue( ToolValue, "NO" ) )
+ args[ USG_WBWINDOW ] = FALSE;
+ }
+
+ if( ToolValue = (char *)FindToolType( dobj->do_ToolTypes, "SCALER" ) )
+ {
+ if( (ScummGfxScaler = OSystem_MorphOS::FindScaler( ToolValue )) == OSystem_MorphOS::ST_INVALID )
+ {
+ FreeDiskObject( dobj );
+ exit( 1 );
+ }
+ }
+
+ if( ToolValue = (char *)FindToolType( dobj->do_ToolTypes, "MUSIC" ) )
+ {
+ if( MatchToolValue( ToolValue, "YES" ) )
+ args[ USG_NOMUSIC ] = FALSE;
+ else if( MatchToolValue( ToolValue, "NO" ) )
+ args[ USG_NOMUSIC ] = TRUE;
+ }
+
+ if( ToolValue = (char *)FindToolType( dobj->do_ToolTypes, "MIDIUNIT" ) )
+ ScummMidiUnit = atoi( ToolValue );
+
+ if( ToolValue = (char *)FindToolType( dobj->do_ToolTypes, "VOLUME" ) )
+ {
+ int vol = atoi( ToolValue );
+ if( vol >= 0 && vol <= 100 )
+ {
+ ScummMidiVolume = vol;
+ args[ USG_VOLUME ] = (ULONG)&ScummMidiVolume;
+ }
+ }
+
+ if( ToolValue = (char *)FindToolType( dobj->do_ToolTypes, "TEMPO" ) )
+ {
+ ScummMidiTempo = atoi( ToolValue );
+ args[ USG_TEMPO ] = (ULONG)&ScummMidiTempo;
+ }
+
+ if( ToolValue = (char *)FindToolType( dobj->do_ToolTypes, "ROLANDEMU" ) )
+ {
+ if( MatchToolValue( ToolValue, "YES" ) )
+ args[ USG_ROLANDEMU ] = FALSE;
+ else if( MatchToolValue( ToolValue, "NO" ) )
+ args[ USG_ROLANDEMU ] = TRUE;
+ }
+
+ if( ToolValue = (char *)FindToolType( dobj->do_ToolTypes, "SUBTITLES" ) )
+ {
+ if( MatchToolValue( ToolValue, "YES" ) )
+ args[ USG_NOSUBTITLES ] = FALSE;
+ else if( MatchToolValue( ToolValue, "NO" ) )
+ args[ USG_NOSUBTITLES ] = TRUE;
+ }
+
+ FreeDiskObject( dobj );
+}
+
+#undef main
+
+int main()
+{
+ int delta;
+ int last_time, new_time;
+ char *argv[ 10 ];
+ char volume[ 6 ], tempo[ 12 ], scaler[ 14 ];
+ char *SVMScalers[] = { "", "normal", "2x", "supereagle", "super2xsai" };
+ int argc = 0;
+
+ InitSemaphore( &ScummSoundThreadRunning );
+ InitSemaphore( &ScummMusicThreadRunning );
+
+ CyberGfxBase = OpenLibrary( "cybergraphics.library", 41 );
+ if( CyberGfxBase == NULL )
+ {
+ puts( "Failed to open cybergraphics.library" );
+ exit( 1 );
+ }
+
+ atexit( &close_resources );
+
+ if( _WBenchMsg == NULL )
+ {
+ /* Parse the command line here */
+ ScummArgs = ReadArgs( usageTemplate, args, NULL );
+ if( ScummArgs == NULL )
+ {
+ puts( "Error in command line - type \"ScummVM ?\" for usage.\n" );
+ exit( 1 );
+ }
+
+ if( args[ USG_STORY ] )
+ {
+ ScummStory = (char *)AllocVec( strlen( (char *)args[ USG_STORY ] )+1, MEMF_PUBLIC );
+ strcpy( ScummStory, (char *)args[ USG_STORY ] );
+ }
+
+ if( args[ USG_DATAPATH ] )
+ {
+ ScummPath = (char *)AllocVec( strlen( (char *)args[ USG_DATAPATH ] )+4, MEMF_PUBLIC );
+ strcpy( ScummPath, "-p" );
+ strcat( ScummPath, (char *)args[ USG_DATAPATH ] );
+ }
+
+ if( args[ USG_SCALER ] )
+ {
+ if( (ScummGfxScaler = OSystem_MorphOS::FindScaler( (char *)args[ USG_SCALER ] )) == OSystem_MorphOS::ST_INVALID )
+ exit( 1 );
+ }
+
+ if( args[ USG_MIDIUNIT ] )
+ ScummMidiUnit = *((LONG *)args[ USG_MIDIUNIT ]);
+
+ if( args[ USG_TEMPO ] )
+ ScummMidiTempo = *((LONG *)args[ USG_TEMPO ]);
+
+ if( args[ USG_VOLUME ] )
+ ScummMidiVolume = *((LONG *)args[ USG_VOLUME ]);
+ }
+ else
+ {
+ /* We've been started from Workbench */
+ ReadToolTypes( &_WBenchMsg->sm_ArgList[ 0 ] );
+ if( _WBenchMsg->sm_NumArgs > 1 )
+ {
+ ReadToolTypes( &_WBenchMsg->sm_ArgList[ 1 ] );
+ OrigDirLock = CurrentDir( _WBenchMsg->sm_ArgList[ 1 ].wa_Lock );
+ }
+ }
+
+ if( ScummPath )
+ {
+ char c = ScummPath[ strlen( ScummPath )-1 ];
+ if( c != '/' && c != ':' )
+ strcat( ScummPath, "/" );
+ }
+
+ argv[ argc++ ] = "ScummVM";
+ argv[ argc++ ] = ScummStory;
+ if( ScummPath ) argv[ argc++ ] = ScummPath;
+ if( !args[ USG_WBWINDOW ] ) argv[ argc++ ] = "-f";
+ if( args[ USG_NOSUBTITLES ] ) argv[ argc++ ] = "-n";
+ if( args[ USG_ROLANDEMU ] ) argv[ argc++ ] = "-r";
+ if( ScummGfxScaler != OSystem_MorphOS::ST_INVALID )
+ {
+ sprintf( scaler, "-g%s", SVMScalers[ (int)ScummGfxScaler ] );
+ argv[ argc++ ] = scaler;
+ }
+ else
+ argv[ argc++ ] = "-gsuper2xsai";
+ if( args[ USG_VOLUME ] && ScummMidiVolume >= 0 && ScummMidiVolume <= 100 )
+ {
+ sprintf( volume, "-m%d", ScummMidiVolume );
+ argv[ argc++ ] = volume;
+ }
+ if( args[ USG_TEMPO ] && ScummMidiTempo > 0 )
+ {
+ sprintf( tempo, "-t%lx", ScummMidiTempo );
+ argv[ argc++ ] = tempo;
+ }
+
+ return morphos_main( argc, argv );
+}
+
diff --git a/scummsys.h b/scummsys.h
index d72b1cb04b..07b7c96651 100644
--- a/scummsys.h
+++ b/scummsys.h
@@ -198,6 +198,7 @@ typedef signed long int32;
#define GCC_PACK
#define NORETURN
#endif
+#define main morphos_main
#elif defined(__DC__)
#define scumm_stricmp strcasecmp
diff --git a/scummvm.cpp b/scummvm.cpp
index be83449eb6..308824b24c 100644
--- a/scummvm.cpp
+++ b/scummvm.cpp
@@ -1124,7 +1124,9 @@ void Scumm::waitForTimer(int msec_delay) {
mouse.x = event.mouse.x;
mouse.y = event.mouse.y;
_system->set_mouse_pos(event.mouse.x, event.mouse.y);
+#if !defined(__MORPHOS__)
_system->update_screen();
+#endif
break;
case OSystem::EVENT_LBUTTONDOWN:
diff --git a/system.h b/system.h
index 8bfd7a85c0..7f173a6fc8 100644
--- a/system.h
+++ b/system.h
@@ -106,6 +106,7 @@ public:
/* OSystem_SDL */
OSystem *OSystem_SDL_create(int gfx_driver, bool full_screen);
OSystem *OSystem_NULL_create();
+OSystem *OSystem_MorphOS_create(int game_id, int gfx_driver, bool full_screen);
enum {
GFX_NORMAL = 0,