diff options
author | Ruediger Hanke | 2002-08-13 10:24:42 +0000 |
---|---|---|
committer | Ruediger Hanke | 2002-08-13 10:24:42 +0000 |
commit | cafc73f949201c60f68c4c5d25af2bf8f20e8456 (patch) | |
tree | 3f1e8b6c434fe347a58c96d69d00d5ccd4ffd851 | |
parent | 9792dc9f67bbdb6bdcdcea67c73a73338ccf9b97 (diff) | |
download | scummvm-rg350-cafc73f949201c60f68c4c5d25af2bf8f20e8456.tar.gz scummvm-rg350-cafc73f949201c60f68c4c5d25af2bf8f20e8456.tar.bz2 scummvm-rg350-cafc73f949201c60f68c4c5d25af2bf8f20e8456.zip |
Vast update to the MorphOS port which optimises graphics rendering, esp. efficient handling of color cycling. Also new formatting of source
svn-id: r4732
-rw-r--r-- | morphos/Makefile | 8 | ||||
-rw-r--r-- | morphos/morphos.cpp | 1717 | ||||
-rw-r--r-- | morphos/morphos.h | 138 | ||||
-rw-r--r-- | morphos/morphos_scaler.cpp | 823 | ||||
-rw-r--r-- | morphos/morphos_scaler.h | 93 | ||||
-rw-r--r-- | morphos/morphos_sound.cpp | 212 | ||||
-rw-r--r-- | morphos/morphos_start.cpp | 318 | ||||
-rw-r--r-- | morphos/morphos_timer.cpp | 36 |
8 files changed, 1895 insertions, 1450 deletions
diff --git a/morphos/Makefile b/morphos/Makefile index 4e18cf7387..7f92a45ceb 100644 --- a/morphos/Makefile +++ b/morphos/Makefile @@ -18,10 +18,10 @@ SIMONOBJS = midi.o simon.o simondebug.o simonitems.o simonres.o simonsys.o simon OBJS = actor.o akos.o boxes.o config-file.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 morphos_start.o morphos_timer.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 util.o main.o \ - bundle.o $(GUIOBJS) $(SIMONOBJS) + morphos.o morphos_scaler.o morphos_sound.o morphos_start.o morphos_timer.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 \ + util.o main.o bundle.o $(GUIOBJS) $(SIMONOBJS) 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 de1c5ff643..a949cbfd2f 100644 --- a/morphos/morphos.cpp +++ b/morphos/morphos.cpp @@ -50,56 +50,52 @@ #include <time.h> #include "morphos.h" - -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 }, - { CDPA_Loops, 1 }, - { TAG_DONE, 0 } - }; - -OSystem_MorphOS::GfxScaler OSystem_MorphOS::ScummScalers[ 10 ] = { { "none", ST_NONE }, - { "Point", ST_POINT }, - { "AdvMame2x", ST_ADVMAME2X }, - { "SuperEagle", ST_SUPEREAGLE }, - { "Super2xSaI", ST_SUPER2XSAI }, - { 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_Priority, 0 }, - { TAG_DONE, 0 } - }; -struct TagItem soundProcTags[] = { { NP_Entry, 0 }, - { NP_Name, (ULONG)"ScummVM Sound Thread" }, - { NP_Priority, 0 }, - { TAG_DONE, 0 } - }; - -OSystem_MorphOS *OSystem_MorphOS::create( int game_id, SCALERTYPE gfx_scaler, bool full_screen ) +#include "morphos_scaler.h" + +static TagItem FindCDTags[] = { { CDFA_VolumeName, 0 }, + { TAG_DONE, 0 } + }; +static TagItem PlayTags[] = { { CDPA_StartTrack, 1 }, + { CDPA_StartFrame, 0 }, + { CDPA_EndTrack, 1 }, + { CDPA_EndFrame, 0 }, + { CDPA_Loops, 1 }, + { TAG_DONE, 0 } + }; + +TagItem musicProcTags[] = { { NP_Entry, 0 }, + { NP_Name, (ULONG)"ScummVM Music Thread" }, + { NP_Priority, 0 }, + { TAG_DONE, 0 } + }; +TagItem soundProcTags[] = { { NP_Entry, 0 }, + { NP_Name, (ULONG)"ScummVM Sound Thread" }, + { NP_Priority, 0 }, + { TAG_DONE, 0 } + }; + +#define BLOCKSIZE_X 32 +#define BLOCKSIZE_Y 8 + +#define BLOCKS_X (ScummBufferWidth/BLOCKSIZE_X) +#define BLOCKS_Y (ScummBufferHeight/BLOCKSIZE_Y) +#define BLOCK_ID(x, y) ((y/BLOCKSIZE_Y)*BLOCKS_X+(x/BLOCKSIZE_X)) + +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 ); + OSystem_MorphOS *syst = new OSystem_MorphOS(game_id, gfx_scaler, full_screen); return syst; } -OSystem_MorphOS::OSystem_MorphOS( int game_id, SCALERTYPE gfx_mode, bool full_screen ) +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; + ScummScreenBuffer[0] = NULL; + ScummScreenBuffer[1] = NULL; ScummRenderTo = NULL; ScummNoCursor = NULL; ScummMusicThread = NULL; @@ -109,103 +105,136 @@ OSystem_MorphOS::OSystem_MorphOS( int game_id, SCALERTYPE gfx_mode, bool full_sc ScummDefaultMouse = false; ScummOrigMouse = false; ScummShakePos = 0; - ScummPCMode = false; ScummScaler = gfx_mode; - ScummScale = (gfx_mode == ST_NONE) ? 0 : 1; + ScummScale = (gfx_mode == ST_NONE) ? 0 : 1; ScummDepth = 0; Scumm16ColFmt16 = false; ScummScrWidth = 0; ScummScrHeight = 0; ScreenChanged = false; + DirtyBlocks = NULL; + BlockColors = NULL; + Scaler = NULL; FullScreenMode = full_screen; CDrive = NULL; CDDATrackOffset = 0; - strcpy( ScummWndTitle, "ScummVM MorphOS" ); + strcpy(ScummWndTitle, "ScummVM MorphOS"); TimerMsgPort = NULL; TimerIORequest = NULL; - OpenATimer( &TimerMsgPort, (struct IORequest **)&TimerIORequest, UNIT_MICROHZ ); + OpenATimer(&TimerMsgPort, (IORequest **) &TimerIORequest, UNIT_MICROHZ); TimerBase = TimerIORequest->tr_node.io_Device; - ScummNoCursor = (UWORD *)AllocVec( 16, MEMF_CHIP | MEMF_CLEAR ); + ScummNoCursor = (UWORD *) AllocVec(16, MEMF_CHIP | MEMF_CLEAR); + UpdateRegion = NewRegion(); + NewUpdateRegion = NewRegion(); + if (!UpdateRegion || !NewUpdateRegion) + error("Could not create region for screen update"); } OSystem_MorphOS::~OSystem_MorphOS() { - if( CDrive && CDDABase ) + if (DirtyBlocks) + { + FreeVec(DirtyBlocks); + + for (int b = 0; b < BLOCKS_X*BLOCKS_Y; b++) + FreeVec(BlockColors[b]); + FreeVec(BlockColors); + } + + if (Scaler) + delete Scaler; + + if (UpdateRegion) + DisposeRegion(UpdateRegion); + + if (NewUpdateRegion) + DisposeRegion(NewUpdateRegion); + + if (CDrive && CDDABase) { - CDDA_Stop( CDrive ); - CDDA_ReleaseDrive( CDrive ); + CDDA_Stop(CDrive); + CDDA_ReleaseDrive(CDrive); } - if( TimerIORequest ) + if (TimerIORequest) { - CloseDevice( (struct IORequest *)TimerIORequest ); - DeleteIORequest( (struct IORequest *)TimerIORequest ); + CloseDevice((IORequest *) TimerIORequest); + DeleteIORequest((IORequest *) TimerIORequest); } - if( TimerMsgPort ) - DeleteMsgPort( TimerMsgPort ); + if (TimerMsgPort) + DeleteMsgPort(TimerMsgPort); - if( ScummMusicThread ) + if (ScummMusicThread) { - Signal( (struct Task *)ScummMusicThread, SIGBREAKF_CTRL_C ); - ObtainSemaphore( &ScummMusicThreadRunning ); /* Wait for thread to finish */ - ReleaseSemaphore( &ScummMusicThreadRunning ); + Signal((Task *) ScummMusicThread, SIGBREAKF_CTRL_C); + ObtainSemaphore(&ScummMusicThreadRunning); /* Wait for thread to finish */ + ReleaseSemaphore(&ScummMusicThreadRunning); } - if( ScummSoundThread ) + if (ScummSoundThread) { - Signal( (struct Task *)ScummSoundThread, SIGBREAKF_CTRL_C ); - ObtainSemaphore( &ScummSoundThreadRunning ); /* Wait for thread to finish */ - ReleaseSemaphore( &ScummSoundThreadRunning ); + Signal((Task *) ScummSoundThread, SIGBREAKF_CTRL_C); + ObtainSemaphore(&ScummSoundThreadRunning); /* Wait for thread to finish */ + ReleaseSemaphore(&ScummSoundThreadRunning); } - if( ScummNoCursor ) - FreeVec( ScummNoCursor ); + if (ScummNoCursor) + FreeVec(ScummNoCursor); - if( ScummBuffer ) - FreeVec( ScummBuffer ); + if (ScummBuffer) + FreeVec(ScummBuffer); - if( ScummRenderTo && !ScummScreen ) - FreeBitMap( ScummRenderTo ); + if (ScummRenderTo && !ScummScreen) + FreeBitMap (ScummRenderTo); - if( ScummWindow ) - CloseWindow( ScummWindow ); + if (ScummWindow) + CloseWindow(ScummWindow); - if( ScummScreen ) + if (ScummScreen) { - if( ScummScreenBuffer[ 0 ] ) - FreeScreenBuffer( ScummScreen, ScummScreenBuffer[ 0 ] ); - if( ScummScreenBuffer[ 1 ] ) - FreeScreenBuffer( ScummScreen, ScummScreenBuffer[ 1 ] ); - CloseScreen( ScummScreen ); + if (ScummScreenBuffer[0]) + FreeScreenBuffer(ScummScreen, ScummScreenBuffer[0]); + if( ScummScreenBuffer[1] ) + FreeScreenBuffer(ScummScreen, ScummScreenBuffer[1]); + CloseScreen(ScummScreen); } } -void OSystem_MorphOS::OpenATimer( struct MsgPort **port, struct IORequest **req, ULONG unit ) +bool OSystem_MorphOS::OpenATimer(MsgPort **port, IORequest **req, ULONG unit, bool required) { + *req = NULL; + const char *err_msg = NULL; + *port = CreateMsgPort(); - if( *port == NULL ) + if (*port) { - puts( "Failed to create message port" ); - exit( 1 ); + *req = (IORequest *) CreateIORequest(*port, sizeof (timerequest)); + if (*req) + { + if (OpenDevice(TIMERNAME, unit, *req, 0)) + { + DeleteIORequest(*req); + *req = NULL; + err_msg = "Failed to open timer device"; + } + } + else + err_msg = "Failed to create IO request"; } + else + err_msg = "Failed to create message port"; - *req = (struct IORequest *)CreateIORequest( *port, sizeof( struct timerequest ) ); - if( *req == NULL ) + if (err_msg) { - puts( "Failed to create IO request" ); - exit( 1 ); + if (required) + error(err_msg); + warning(err_msg); } - if( OpenDevice( "timer.device", unit, *req, 0 ) ) - { - DeleteIORequest( *req ); - *req = NULL; - puts( "Failed to open timer device" ); - exit( 1 ); - } + return *req != NULL; } uint32 OSystem_MorphOS::get_msecs() @@ -217,10 +246,10 @@ uint32 OSystem_MorphOS::get_msecs() void OSystem_MorphOS::delay_msecs(uint msecs) { - TimerIORequest->tr_node.io_Command = TR_ADDREQUEST; - TimerIORequest->tr_time.tv_secs = 0; + TimerIORequest->tr_node.io_Command = TR_ADDREQUEST; + TimerIORequest->tr_time.tv_secs = 0; TimerIORequest->tr_time.tv_micro = msecs*1000; - DoIO( (struct IORequest *)TimerIORequest ); + DoIO((IORequest *) TimerIORequest); } void OSystem_MorphOS::set_timer(int timer, int (*callback)(int)) @@ -237,74 +266,74 @@ void *OSystem_MorphOS::create_thread(ThreadProc *proc, void *param) ThreadEmulFunc.StackSize = 16000; ThreadEmulFunc.Extension = 0; ThreadEmulFunc.Arg1 = (ULONG)param; - musicProcTags[ 0 ].ti_Data = (ULONG)&ThreadEmulFunc; - ScummMusicThread = CreateNewProc( musicProcTags ); + musicProcTags[0].ti_Data = (ULONG)&ThreadEmulFunc; + ScummMusicThread = CreateNewProc(musicProcTags); return ScummMusicThread; } void *OSystem_MorphOS::create_mutex(void) { - struct SignalSemaphore *sem = (struct SignalSemaphore *)AllocVec( sizeof( struct SignalSemaphore ), MEMF_PUBLIC ); + SignalSemaphore *sem = (SignalSemaphore *) AllocVec(sizeof (SignalSemaphore), MEMF_PUBLIC); - if( sem ) - InitSemaphore( sem ); + if (sem) + InitSemaphore(sem); return sem; } void OSystem_MorphOS::lock_mutex(void *mutex) { - ObtainSemaphore( (struct SignalSemaphore *)mutex ); + ObtainSemaphore((SignalSemaphore *) mutex); } void OSystem_MorphOS::unlock_mutex(void *mutex) { - ReleaseSemaphore( (struct SignalSemaphore *)mutex ); + ReleaseSemaphore((SignalSemaphore *)mutex); } void OSystem_MorphOS::delete_mutex(void *mutex) { - FreeVec( mutex ); + FreeVec(mutex); } uint32 OSystem_MorphOS::property(int param, Property *value) { - switch( param ) + switch (param) { case PROP_TOGGLE_FULLSCREEN: - create_screen( CSDSPTYPE_TOGGLE ); + CreateScreen(CSDSPTYPE_TOGGLE); return 1; case PROP_SET_WINDOW_CAPTION: - sprintf( ScummWndTitle, "ScummVM MorphOS - %s", value->caption ); - if( ScummWindow ) - SetWindowTitles( ScummWindow, ScummWndTitle, ScummWndTitle ); + sprintf(ScummWndTitle, "ScummVM MorphOS - %s", value->caption); + 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", 2 ); - if( CDDABase ) + FindCDTags[0].ti_Data = (ULONG) ((GameID == GID_LOOM256) ? "LoomCD" : "Monkey1CD"); + if (!CDDABase) CDDABase = OpenLibrary("cdda.library", 2); + if (CDDABase) { - CDrive = CDDA_FindNextDrive( NULL, FindCDTags ); - if( !CDrive && GameID == GID_MONKEY ) + CDrive = CDDA_FindNextDrive(NULL, FindCDTags); + if (!CDrive && GameID == GID_MONKEY) { - FindCDTags[ 0 ].ti_Data = (ULONG)"Madness"; - CDrive = CDDA_FindNextDrive( NULL, FindCDTags ); + FindCDTags[0].ti_Data = (ULONG) "Madness"; + CDrive = CDDA_FindNextDrive(NULL, FindCDTags); } - if( CDrive ) + if (CDrive) { - if( !CDDA_ObtainDrive( CDrive, CDDA_SHARED_ACCESS, NULL ) ) + if (!CDDA_ObtainDrive(CDrive, CDDA_SHARED_ACCESS, NULL)) { CDrive = NULL; - warning( "Failed to obtain CD drive - music will not play" ); + warning("Failed to obtain CD drive - music will not play"); } - else if( GameID == GID_LOOM256 ) + else if (GameID == GID_LOOM256) { // Offset correction *may* be required - struct CDS_TrackInfo ti = { sizeof( struct CDS_TrackInfo ) }; + CDS_TrackInfo ti = { sizeof (CDS_TrackInfo) }; - if( CDDA_GetTrackInfo( CDrive, 1, 0, &ti ) ) + if (CDDA_GetTrackInfo(CDrive, 1, 0, &ti)) CDDATrackOffset = ti.ti_TrackStart.tm_Format.tm_Frame-22650; } } @@ -316,10 +345,10 @@ uint32 OSystem_MorphOS::property(int param, Property *value) break; case PROP_SHOW_DEFAULT_CURSOR: - if( value->show_cursor ) - ClearPointer( ScummWindow ); + if (value->show_cursor) + ClearPointer(ScummWindow); else - SetPointer( ScummWindow, ScummNoCursor, 1, 1, 0, 0 ); + SetPointer(ScummWindow, ScummNoCursor, 1, 1, 0, 0); ScummOrigMouse = ScummDefaultMouse = value->show_cursor; break; @@ -330,35 +359,35 @@ uint32 OSystem_MorphOS::property(int param, Property *value) return 0; } -void OSystem_MorphOS::play_cdrom( int track, int num_loops, int start_frame, int length ) +void OSystem_MorphOS::play_cdrom(int track, int num_loops, int start_frame, int length) { - if( CDrive && start_frame >= 0 ) + if (CDrive && start_frame >= 0) { - if( start_frame > 0 ) + if (start_frame > 0) start_frame -= CDDATrackOffset; - PlayTags[ 0 ].ti_Data = track; - PlayTags[ 1 ].ti_Data = start_frame; - PlayTags[ 2 ].ti_Data = (length == 0) ? track+1 : track; - PlayTags[ 3 ].ti_Data = length ? start_frame+length : 0; - PlayTags[ 4 ].ti_Data = (num_loops == 0) ? 1 : num_loops; - CDDA_Play( CDrive, PlayTags ); + PlayTags[0].ti_Data = track; + PlayTags[1].ti_Data = start_frame; + PlayTags[2].ti_Data = (length == 0) ? track+1 : track; + PlayTags[3].ti_Data = length ? start_frame+length : 0; + PlayTags[4].ti_Data = (num_loops == 0) ? 1 : num_loops; + CDDA_Play(CDrive, PlayTags); } } void OSystem_MorphOS::stop_cdrom() { - CDDA_Stop( CDrive ); + CDDA_Stop(CDrive); } bool OSystem_MorphOS::poll_cdrom() { ULONG status; - if( CDrive == NULL ) + if (CDrive == NULL) return false; - CDDA_GetAttr( CDDA_Status, CDrive, &status ); + CDDA_GetAttr(CDDA_Status, CDrive, &status); return status == CDDA_Status_Busy; } @@ -368,132 +397,110 @@ void OSystem_MorphOS::update_cdrom() void OSystem_MorphOS::quit() { - exit( 0 ); -} - -uint32 OSystem_MorphOS::make_color( int pixfmt, int r, int g, int b ) -{ - uint32 col = 0; - - switch( pixfmt ) - { - case PIXFMT_RGB15: - case PIXFMT_RGB15PC: - col = (((r*31)/255) << 10) | (((g*31)/255) << 5) | ((b*31)/255); - break; - - case PIXFMT_BGR15: - case PIXFMT_BGR15PC: - col = (((b*31)/255) << 10) | (((g*31)/255) << 5) | ((r*31)/255); - break; - - case PIXFMT_RGB16: - case PIXFMT_RGB16PC: - col = (((r*31)/255) << 11) | (((g*63)/255) << 5) | ((b*31)/255); - break; - - case PIXFMT_BGR16: - case PIXFMT_BGR16PC: - col = (((b*31)/255) << 11) | (((g*63)/255) << 5) | ((r*31)/255); - break; - - case PIXFMT_RGB24: - case PIXFMT_ARGB32: - col = (r << 16) | (g << 8) | b; - break; - - case PIXFMT_BGR24: - col = (b << 16) | (g << 8) | r; - break; - - case PIXFMT_BGRA32: - col = (b << 24) | (g << 16) | (r << 8); - break; - - case PIXFMT_RGBA32: - col = (r << 24) | (g << 16) | (b << 8); - break; - - default: - error( "Unsupported pixel format: %d. Please contact author at tomjoad@muenster.de.", pixfmt ); - exit( 1 ); - } - - - return col; + exit(0); } -#define CVT8TO32( col ) ((col<<24) | (col<<16) | (col<<8) | col) +#define CVT8TO32(col) ((col<<24) | (col<<16) | (col<<8) | col) void OSystem_MorphOS::set_palette(const byte *colors, uint start, uint num) { const byte *data = colors; - for( uint i = start; i != start+num; i++ ) + UWORD changed_colors[256]; + UWORD num_changed = 0; + + 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 ]; + ULONG color32 = (data[0] << 16) | (data[1] << 8) | data[2]; + if (color32 != ScummColors[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] = color32; + changed_colors[num_changed++] = i; + } data += 4; } - ScreenChanged = true; + + if (ScummScale || ScummDepth != 8) + { + if (DirtyBlocks && num_changed < 200) + { + for (int b = 0; b < BLOCKS_X*BLOCKS_Y; b++) + { + UWORD *block_colors = BlockColors[b]; + UWORD *color_ptr = changed_colors; + for (int c = 0; c < num_changed; c++) + { + if (block_colors[*color_ptr++]) + { + UWORD x, y; + x = b % BLOCKS_X; + y = b / BLOCKS_X; + DirtyBlocks[b] = true; + AddUpdateRect(x*BLOCKSIZE_X, y*BLOCKSIZE_Y, BLOCKSIZE_X, BLOCKSIZE_Y); + break; + } + } + } + } + else + AddUpdateRect(0, 0, ScummBufferWidth, ScummBufferHeight); + } } -void OSystem_MorphOS::create_screen( CS_DSPTYPE dspType ) +void OSystem_MorphOS::CreateScreen(CS_DSPTYPE dspType) { ULONG mode = INVALID_ID; int depths[] = { 8, 15, 16, 24, 32, 0 }; int i; - struct Screen *wb = NULL; + Screen *wb = NULL; - if( dspType != CSDSPTYPE_KEEP ) + if (dspType != CSDSPTYPE_KEEP) FullScreenMode = (dspType == CSDSPTYPE_FULLSCREEN) || (dspType == CSDSPTYPE_TOGGLE && !FullScreenMode); - if( ScummRenderTo && !ScummScreen ) - FreeBitMap( ScummRenderTo ); + if (ScummRenderTo && !ScummScreen) + FreeBitMap(ScummRenderTo); ScummRenderTo = NULL; - if( ScummWindow ) + if (ScummWindow) { - if( ScummScreen == NULL ) + if (ScummScreen == NULL) { ScummWinX = ScummWindow->LeftEdge; ScummWinY = ScummWindow->TopEdge; } - CloseWindow( ScummWindow ); + CloseWindow (ScummWindow); ScummWindow = NULL; } - if( ScummScreen ) + if (ScummScreen) { - if( ScummScreenBuffer[ 0 ] ) - FreeScreenBuffer( ScummScreen, ScummScreenBuffer[ 0 ] ); - if( ScummScreenBuffer[ 1 ] ) - FreeScreenBuffer( ScummScreen, ScummScreenBuffer[ 1 ] ); - CloseScreen( ScummScreen ); + if (ScummScreenBuffer[0]) + FreeScreenBuffer(ScummScreen, ScummScreenBuffer[0]); + if (ScummScreenBuffer[1]) + FreeScreenBuffer(ScummScreen, ScummScreenBuffer[1]); + CloseScreen(ScummScreen); ScummScreen = NULL; } ScummScrWidth = ScummBufferWidth << ScummScale; ScummScrHeight = ScummBufferHeight << ScummScale; - if( FullScreenMode ) + if (FullScreenMode) { - for( i = ScummScale; mode == INVALID_ID && depths[ i ]; i++ ) - mode = BestCModeIDTags( CYBRBIDTG_NominalWidth, ScummScrWidth, - CYBRBIDTG_NominalHeight, ScummScrHeight, - CYBRBIDTG_Depth, depths[ i ], - TAG_DONE + for (i = ScummScale; mode == INVALID_ID && depths[i]; i++) + mode = BestCModeIDTags(CYBRBIDTG_NominalWidth, ScummScrWidth, + CYBRBIDTG_NominalHeight, ScummScrHeight, + CYBRBIDTG_Depth, depths[i], + TAG_DONE ); - ScummDepth = depths[ i-1 ]; + ScummDepth = depths[i-1]; - if( mode == INVALID_ID ) - { - error( "Could not find suitable screenmode" ); - exit(1); - } + if (mode == INVALID_ID) + error("Could not find suitable screenmode"); - ScummScreen = OpenScreenTags( NULL, SA_AutoScroll, TRUE, + ScummScreen = OpenScreenTags(NULL, SA_AutoScroll, TRUE, SA_Depth, ScummDepth, SA_Width, STDSCREENWIDTH, SA_Height, STDSCREENHEIGHT, @@ -504,64 +511,55 @@ void OSystem_MorphOS::create_screen( CS_DSPTYPE dspType ) TAG_DONE ); - if( ScummScreen == NULL ) - { - error( "Failed to open screen" ); - exit( 1 ); - } + if (ScummScreen == NULL) + error("Failed to open screen"); - ULONG RealDepth = GetBitMapAttr( &ScummScreen->BitMap, BMA_DEPTH ); - if( RealDepth != ScummDepth ) + ULONG RealDepth = GetBitMapAttr(&ScummScreen->BitMap, BMA_DEPTH); + if (RealDepth != ScummDepth) { - warning( "Screen did not open in expected depth" ); + warning("Screen did not open in expected depth"); ScummDepth = RealDepth; } - ScummScreenBuffer[ 0 ] = AllocScreenBuffer( ScummScreen, NULL, SB_SCREEN_BITMAP ); - ScummScreenBuffer[ 1 ] = AllocScreenBuffer( ScummScreen, NULL, 0 ); - ScummRenderTo = ScummScreenBuffer[ 1 ]->sb_BitMap; + ScummScreenBuffer[0] = AllocScreenBuffer(ScummScreen, NULL, SB_SCREEN_BITMAP); + ScummScreenBuffer[1] = AllocScreenBuffer(ScummScreen, NULL, 0); + ScummRenderTo = ScummScreenBuffer[1]->sb_BitMap; ScummPaintBuffer = 1; - if( ScummScreenBuffer[ 0 ] == NULL || ScummScreenBuffer[ 1 ] == NULL ) - { - error( "Failed to allocate screen buffer" ); - exit( 1 ); - } + if (ScummScreenBuffer[0] == NULL || ScummScreenBuffer[1] == NULL) + error("Failed to allocate screen buffer"); // Make both buffers black to avoid grey strip on bottom of screen - struct RastPort rp; - InitRastPort( &rp ); - SetRGB32( &ScummScreen->ViewPort, 0, 0, 0, 0 ); - rp.BitMap = ScummScreenBuffer[ 0 ]->sb_BitMap; - FillPixelArray( &ScummScreen->RastPort, 0, 0, ScummScreen->Width, ScummScreen->Height, 0 ); + RastPort rp; + InitRastPort(&rp); + SetRGB32(&ScummScreen->ViewPort, 0, 0, 0, 0); + rp.BitMap = ScummScreenBuffer[0]->sb_BitMap; + FillPixelArray(&ScummScreen->RastPort, 0, 0, ScummScreen->Width, ScummScreen->Height, 0); rp.BitMap = ScummRenderTo; - FillPixelArray( &rp, 0, 0, ScummScreen->Width, ScummScreen->Height, 0 ); + FillPixelArray(&rp, 0, 0, ScummScreen->Width, ScummScreen->Height, 0); - if( ScummDepth == 8 ) + if (ScummDepth == 8) { - for( int color = 0; color < 256; color++ ) + for (int color = 0; color < 256; color++) { ULONG r, g, b; - r = (ScummColors[ color ] >> 16) & 0xff; - g = (ScummColors[ color ] >> 8) & 0xff; - b = (ScummColors[ color ] >> 0) & 0xff; - SetRGB32( &ScummScreen->ViewPort, color, CVT8TO32( r ), CVT8TO32( g ), CVT8TO32( b ) ); + r = (ScummColors[color] >> 16) & 0xff; + g = (ScummColors[color] >> 8) & 0xff; + b = (ScummColors[color] >> 0) & 0xff; + SetRGB32(&ScummScreen->ViewPort, color, CVT8TO32(r), CVT8TO32(g), CVT8TO32(b)); } } } else { - wb = LockPubScreen( NULL ); - if( wb == NULL ) - { - error( "Could not lock default public screen" ); - exit( 1 ); - } + wb = LockPubScreen(NULL); + if (wb == NULL) + error("Could not lock default public screen"); - ScreenToFront( wb ); + ScreenToFront(wb); } - ScummWindow = OpenWindowTags( NULL, WA_Left, (wb && ScummWinX >= 0) ? ScummWinX : 0, + ScummWindow = OpenWindowTags(NULL, WA_Left, (wb && ScummWinX >= 0) ? ScummWinX : 0, WA_Top, wb ? ((ScummWinY >= 0) ? ScummWinY : wb->BarHeight+1) : 0, WA_InnerWidth, FullScreenMode ? ScummScreen->Width : ScummScrWidth, WA_InnerHeight, FullScreenMode ? ScummScreen->Height : ScummScrHeight, @@ -582,148 +580,128 @@ void OSystem_MorphOS::create_screen( CS_DSPTYPE dspType ) TAG_DONE ); - if( wb ) - UnlockPubScreen( NULL, wb ); + if (wb) + UnlockPubScreen(NULL, wb); - if( ScummWindow == NULL ) - { - error( "Failed to open window" ); - exit(1); - } + if (ScummWindow == NULL) + error("Failed to open window"); - if( !ScummDefaultMouse ) + if (!ScummDefaultMouse) { - SetPointer( ScummWindow, ScummNoCursor, 1, 1, 0, 0 ); + SetPointer(ScummWindow, ScummNoCursor, 1, 1, 0, 0); ScummOrigMouse = false; } - if( ScummScreen == NULL ) + if (ScummScreen == NULL) { - ScummDepth = GetCyberMapAttr( ScummWindow->RPort->BitMap, CYBRMATTR_DEPTH ); - if( ScummDepth == 8 ) - { - error( "Workbench screen must be running in 15 bit or higher" ); - exit( 1 ); - } + ScummDepth = GetCyberMapAttr(ScummWindow->RPort->BitMap, CYBRMATTR_DEPTH); + if (ScummDepth == 8) + error("Workbench screen must be running in 15 bit or higher"); - ScummRenderTo = AllocBitMap( ScummScrWidth, ScummScrHeight, ScummDepth, BMF_MINPLANES, ScummWindow->RPort->BitMap ); - if( ScummRenderTo == NULL ) - { - error( "Failed to allocate bitmap" ); - exit( 1 ); - } + ScummRenderTo = AllocBitMap(ScummScrWidth, ScummScrHeight, ScummDepth, BMF_MINPLANES, ScummWindow->RPort->BitMap); + if (ScummRenderTo == NULL) + error("Failed to allocate bitmap"); } - if( ScummScale ) + if ((ScummDepth == 15 && Scumm16ColFmt16) || (ScummDepth == 16 && !Scumm16ColFmt16)) { - /* Initialize scaling stuff */ - int minr, ming, minb; - - if( ScummDepth > 16 ) - { - minr = 1 << 16; - ming = 1 << 8; - minb = 1; - } - else + for (int col = 0; col < 256; col++) { - minr = 1 << ((ScummDepth == 15) ? 10 : 11); - ming = 1 << 5; - minb = 1; - - if( (ScummDepth == 15 && Scumm16ColFmt16) || (ScummDepth == 16 && !Scumm16ColFmt16) ) - { - for( int col = 0; col < 256; col++ ) - { - int r = (ScummColors[ col ] >> 16) & 0xff; - int g = (ScummColors[ col ] >> 8) & 0xff; - int b = ScummColors[ col ] & 0xff; - ScummColors16[ col ] = (Scumm16ColFmt16 == false) ? (((r*31)/255) << 11) | (((g*63)/255) << 5) | ((b*31)/255) : (((r*31)/255) << 10) | (((g*31)/255) << 5) | ((b*31)/255); - } - } - - Scumm16ColFmt16 = (ScummDepth == 16); + int r = (ScummColors[col] >> 16) & 0xff; + int g = (ScummColors[col] >> 8) & 0xff; + int b = ScummColors[col] & 0xff; + ScummColors16[col] = (Scumm16ColFmt16 == false) ? (((r*31)/255) << 11) | (((g*63)/255) << 5) | ((b*31)/255) : (((r*31)/255) << 10) | (((g*31)/255) << 5) | ((b*31)/255); } - int pixfmt = GetCyberMapAttr( ScummRenderTo, CYBRMATTR_PIXFMT ); - - ScummPCMode = false; - if( pixfmt == PIXFMT_RGB15PC || pixfmt == PIXFMT_BGR15PC || - pixfmt == PIXFMT_RGB16PC || pixfmt == PIXFMT_BGR16PC - ) - ScummPCMode = true; - debug( 1, "Pixelformat = %d", pixfmt ); - - 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 = (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 = make_color( pixfmt, 255, 0, 255 ); - greenMask = make_color( pixfmt, 0, 255, 0 ); + Scumm16ColFmt16 = (ScummDepth == 16); + } - PixelsPerMask = (ScummDepth <= 16) ? 2 : 1; + if (Scaler) + { + delete Scaler; + Scaler = NULL; + } - if( PixelsPerMask == 2 ) + if (ScummScale) + { + Scaler = MorphOSScaler::Create(ScummScaler, ScummBuffer, ScummBufferWidth, ScummBufferHeight, ScummColors, ScummColors16, ScummRenderTo); + if (Scaler == NULL) { - colorMask |= (colorMask << 16); - qcolorMask |= (qcolorMask << 16); - lowPixelMask |= (lowPixelMask << 16); - qlowpixelMask |= (qlowpixelMask << 16); + warning("Failed to create scaler - scaling will be disabled"); + SwitchScalerTo(ST_NONE); } } - ScreenChanged = true; + + AddUpdateRect(0, 0, ScummBufferWidth, ScummBufferHeight); } -void OSystem_MorphOS::SwitchScalerTo( SCALERTYPE newScaler ) +void OSystem_MorphOS::SwitchScalerTo(SCALERTYPE newScaler) { - if( newScaler == ST_NONE && ScummScale != 0 ) + if (newScaler == ST_NONE && ScummScale != 0) { + if (Scaler) + { + delete Scaler; + Scaler = NULL; + } ScummScale = 0; ScummScaler = ST_NONE; - create_screen( ScummScreen ? CSDSPTYPE_FULLSCREEN : CSDSPTYPE_WINDOWED ); + CreateScreen(ScummScreen ? CSDSPTYPE_FULLSCREEN : CSDSPTYPE_WINDOWED); } else { - if( ScummScale == 0 ) + if (ScummScale == 0) { ScummScale = 1; - create_screen( ScummScreen ? CSDSPTYPE_FULLSCREEN : CSDSPTYPE_WINDOWED ); + ScummScaler = newScaler; + CreateScreen(ScummScreen ? CSDSPTYPE_FULLSCREEN : CSDSPTYPE_WINDOWED); } - - if( ScummScaler != newScaler ) + else if (ScummScaler != newScaler) + { ScummScaler = newScaler; + if (Scaler) + delete Scaler; + Scaler = MorphOSScaler::Create(ScummScaler, ScummBuffer, ScummBufferWidth, ScummBufferHeight, ScummColors, ScummColors16, ScummRenderTo); + if (Scaler == NULL) + { + warning("Failed to create scaler - scaling will be disabled"); + SwitchScalerTo(ST_NONE); + } + else + AddUpdateRect(0, 0, ScummBufferWidth, ScummBufferHeight); + } } } -bool OSystem_MorphOS::poll_event( Event *event ) +bool OSystem_MorphOS::poll_event(Event *event) { - struct IntuiMessage *ScummMsg; + IntuiMessage *ScummMsg; - if( ScummMsg = (struct IntuiMessage *)GetMsg( ScummWindow->UserPort ) ) + if (ScummMsg = (IntuiMessage *) GetMsg(ScummWindow->UserPort)) { - switch( ScummMsg->Class ) + switch (ScummMsg->Class) { case IDCMP_RAWKEY: { - struct InputEvent FakedIEvent; + InputEvent FakedIEvent; char charbuf; int qual = 0; - memset( &FakedIEvent, 0, sizeof( struct InputEvent ) ); + memset(&FakedIEvent, 0, sizeof (InputEvent)); FakedIEvent.ie_Class = IECLASS_RAWKEY; FakedIEvent.ie_Code = ScummMsg->Code; - if( ScummMsg->Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT) ) + if (ScummMsg->Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT)) qual |= KBD_ALT; - if( ScummMsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT) ) + if (ScummMsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)) qual |= KBD_SHIFT; - if( ScummMsg->Qualifier & IEQUALIFIER_CONTROL ) + if (ScummMsg->Qualifier & IEQUALIFIER_CONTROL) qual |= KBD_CTRL; event->kbd.flags = qual; event->event_code = EVENT_KEYDOWN; - if( ScummMsg->Code >= 0x50 && ScummMsg->Code <= 0x59 ) + if (ScummMsg->Code >= 0x50 && ScummMsg->Code <= 0x59) { /* * Function key @@ -731,29 +709,36 @@ bool OSystem_MorphOS::poll_event( Event *event ) event->kbd.ascii = (ScummMsg->Code-0x50)+315; event->kbd.keycode = 0; } - else if( MapRawKey( &FakedIEvent, &charbuf, 1, NULL ) == 1 ) + else if (MapRawKey(&FakedIEvent, &charbuf, 1, NULL) == 1) { - if( qual == KBD_CTRL ) + if (qual == KBD_CTRL) { - switch( charbuf ) + switch (charbuf) { case 'z': - ReplyMsg( (struct Message *)ScummMsg ); - exit(1); + ReplyMsg((Message *) ScummMsg); + quit(); } } - else if( qual == KBD_ALT ) + else if (qual == KBD_ALT) { - if( charbuf >= '0' && charbuf <= '9' && ScummScalers[ charbuf-'0' ].gs_Name ) + if (charbuf >= '0' && charbuf <= '9') { - ReplyMsg( (struct Message *)ScummMsg ); - SwitchScalerTo( ScummScalers[ charbuf-'0' ].gs_Type ); - return false; + SCALERTYPE new_scaler = MorphOSScaler::FindByIndex(charbuf-'0'); + ReplyMsg((Message *) ScummMsg); + if (new_scaler != ST_INVALID) + SwitchScalerTo(new_scaler); + return false; + } + else if (charbuf == 'x') + { + ReplyMsg((Message *) ScummMsg); + quit(); } - else if( charbuf == 0x0d ) + else if (charbuf == 0x0d) { - ReplyMsg( (struct Message *)ScummMsg ); - create_screen( CSDSPTYPE_TOGGLE ); + ReplyMsg((Message *) ScummMsg); + CreateScreen(CSDSPTYPE_TOGGLE); return false; } } @@ -766,30 +751,30 @@ bool OSystem_MorphOS::poll_event( Event *event ) case IDCMP_MOUSEMOVE: { - int newx,newy; + LONG newx, newy; newx = (ScummMsg->MouseX-ScummWindow->BorderLeft) >> ScummScale; newy = (ScummMsg->MouseY-ScummWindow->BorderTop) >> ScummScale; - if( !FullScreenMode && !ScummDefaultMouse ) + if (!FullScreenMode && !ScummDefaultMouse) { - if( newx < 0 || newx > ScummBufferWidth || + if (newx < 0 || newx > ScummBufferWidth || newy < 0 || newy > ScummBufferHeight - ) + ) { - if( !ScummOrigMouse ) + if (!ScummOrigMouse) { ScummOrigMouse = true; - ClearPointer( ScummWindow ); + ClearPointer(ScummWindow); } } - else if( ScummOrigMouse ) + else if (ScummOrigMouse) { ScummOrigMouse = false; - SetPointer( ScummWindow, ScummNoCursor, 1, 1, 0, 0 ); + SetPointer(ScummWindow, ScummNoCursor, 1, 1, 0, 0); } } - else if( FullScreenMode ) + else if (FullScreenMode) newy = newy <? (ScummScrHeight >> ScummScale)-2; event->event_code = EVENT_MOUSEMOVE; @@ -799,46 +784,46 @@ bool OSystem_MorphOS::poll_event( Event *event ) } case IDCMP_MOUSEBUTTONS: - { - int newx,newy; + { + int newx, newy; newx = (ScummMsg->MouseX-ScummWindow->BorderLeft) >> ScummScale; newy = (ScummMsg->MouseY-ScummWindow->BorderTop) >> ScummScale; - switch( ScummMsg->Code ) - { - case SELECTDOWN: + switch (ScummMsg->Code) + { + case SELECTDOWN: event->event_code = EVENT_LBUTTONDOWN; - break; + break; - case SELECTUP: + case SELECTUP: event->event_code = EVENT_LBUTTONUP; - break; + break; case MENUDOWN: event->event_code = EVENT_RBUTTONDOWN; - break; + break; - case MENUUP: + case MENUUP: event->event_code = EVENT_RBUTTONUP; - break; + break; - default: - ReplyMsg( (struct Message *)ScummMsg ); - return false; - } + default: + ReplyMsg((Message *)ScummMsg); + return false; + } event->mouse.x = newx; event->mouse.y = newy; break; - } + } case IDCMP_CLOSEWINDOW: - ReplyMsg( (struct Message *)ScummMsg ); - exit( 0 ); + ReplyMsg((Message *)ScummMsg); + exit(0); } - if( ScummMsg ) - ReplyMsg( (struct Message *)ScummMsg ); + if (ScummMsg) + ReplyMsg((Message *) ScummMsg); return true; } @@ -846,733 +831,271 @@ bool OSystem_MorphOS::poll_event( Event *event ) return false; } -void OSystem_MorphOS::set_shake_pos( int shake_pos ) +void OSystem_MorphOS::set_shake_pos(int shake_pos) { ScummShakePos = shake_pos; - ScreenChanged = true; + AddUpdateRect(0, 0, 320, 200); } -#define GET_RESULT(A, B, C, D) ((A != C || A != D) - (B != C || B != D)) +#define MOUSE_INTERSECTS(x, y, w, h) \ + (!((MouseOldX+MouseOldWidth <= x ) || (MouseOldX >= x+w) || \ + (MouseOldY+MouseOldHeight <= y) || (MouseOldY >= y+h))) -#define INTERPOLATE(A, B) (((A & colorMask) >> 1) + ((B & colorMask) >> 1) + (A & B & lowPixelMask)) - -#define Q_INTERPOLATE(A, B, C, D) ((A & qcolorMask) >> 2) + ((B & qcolorMask) >> 2) + ((C & qcolorMask) >> 2) + ((D & qcolorMask) >> 2) + ((((A & qlowpixelMask) + (B & qlowpixelMask) + (C & qlowpixelMask) + (D & qlowpixelMask)) >> 2) & qlowpixelMask) - -#define SWAP_WORD( word ) word = ((word & 0xff) << 8) | (word >> 8) - -void OSystem_MorphOS::Super2xSaI( uint32 src_x, uint32 src_y, uint32 dest_x, uint32 dest_y, uint32 width, uint32 height ) +/* Copy part of bitmap */ +void OSystem_MorphOS::copy_rect(const byte *src, int pitch, int x, int y, int w, int h) { - unsigned int x, y; - unsigned long color[16]; - byte *src; - byte *dest; - uint32 dest_bpp; - uint32 dest_pitch; - APTR handle; - - if( (handle = LockBitMapTags( ScummRenderTo, LBMI_BYTESPERPIX, &dest_bpp, LBMI_BYTESPERROW, &dest_pitch, LBMI_BASEADDRESS, &dest, TAG_DONE )) == 0 ) - return; - - src = ((byte *)ScummBuffer)+src_y*ScummBufferWidth+src_x; - - /* Point to the first 3 lines. */ - src_line[0] = src; - src_line[1] = src; - src_line[2] = src + ScummBufferWidth; - src_line[3] = src + ScummBufferWidth * 2; - - dst_line[0] = dest+dest_y*2*dest_pitch+dest_x*2*dest_bpp; - dst_line[1] = dst_line[0]+dest_pitch; - - x = 0, y = 0; - - if( PixelsPerMask == 2 ) - { - byte *sbp; - sbp = src_line[0]; - color[0] = ScummColors16[ *sbp ]; color[1] = color[0]; color[2] = color[0]; color[3] = color[0]; - color[4] = color[0]; color[5] = color[0]; color[6] = ScummColors16[ *(sbp + 1) ]; color[7] = ScummColors16[ *(sbp + 2) ]; - sbp = src_line[2]; - color[8] = ScummColors16[ *sbp ]; color[9] = color[8]; color[10] = ScummColors16[ *(sbp + 1) ]; color[11] = ScummColors16[ *(sbp + 2) ]; - sbp = src_line[3]; - color[12] = ScummColors16[ *sbp ]; color[13] = color[12]; color[14] = ScummColors16[ *(sbp + 1) ]; color[15] = ScummColors16[ *(sbp + 2) ]; - } - else - { - byte *lbp; - lbp = src_line[0]; - color[0] = ScummColors[ *lbp ]; color[1] = color[0]; color[2] = color[0]; color[3] = color[0]; - color[4] = color[0]; color[5] = color[0]; color[6] = ScummColors[ *(lbp + 1) ]; color[7] = ScummColors[ *(lbp + 2) ]; - lbp = src_line[2]; - color[8] = ScummColors[ *lbp ]; color[9] = color[8]; color[10] = ScummColors[ *(lbp + 1) ]; color[11] = ScummColors[ *(lbp + 2) ]; - lbp = src_line[3]; - color[12] = ScummColors[ *lbp ]; color[13] = color[12]; color[14] = ScummColors[ *(lbp + 1) ]; color[15] = ScummColors[ *(lbp + 2) ]; - } - - for (y = 0; y < height; y++) - { - /* Todo: x = width - 2, x = width - 1 */ - for( x = 0; x < width; x++ ) - { - unsigned long product1a, product1b, product2a, product2b; - -//--------------------------------------- B0 B1 B2 B3 0 1 2 3 -// 4 5* 6 S2 -> 4 5* 6 7 -// 1 2 3 S1 8 9 10 11 -// A0 A1 A2 A3 12 13 14 15 -//-------------------------------------- - if( color[9] == color[6] && color[5] != color[10] ) - { - product2b = color[9]; - product1b = product2b; - } - else if( color[5] == color[10] && color[9] != color[6] ) - { - product2b = color[5]; - product1b = product2b; - } - else if( color[5] == color[10] && color[9] == color[6] ) - { - int r = 0; - - r += GET_RESULT(color[6], color[5], color[8], color[13]); - r += GET_RESULT(color[6], color[5], color[4], color[1]); - r += GET_RESULT(color[6], color[5], color[14], color[11]); - r += GET_RESULT(color[6], color[5], color[2], color[7]); - - if (r > 0) - product1b = color[6]; - else if (r < 0) - product1b = color[5]; - else - product1b = INTERPOLATE(color[5], color[6]); - - product2b = product1b; - - } - else - { - if( color[6] == color[10] && color[10] == color[13] && color[9] != color[14] && color[10] != color[12] ) - product2b = Q_INTERPOLATE(color[10], color[10], color[10], color[9]); - else if( color[5] == color[9] && color[9] == color[14] && color[13] != color[10] && color[9] != color[15] ) - product2b = Q_INTERPOLATE(color[9], color[9], color[9], color[10]); - else - product2b = INTERPOLATE(color[9], color[10]); - - if (color[6] == color[10] && color[6] == color[1] && color[5] != color[2] && color[6] != color[0]) - product1b = Q_INTERPOLATE(color[6], color[6], color[6], color[5]); - else if (color[5] == color[9] && color[5] == color[2] && color[1] != color[6] && color[5] != color[3]) - product1b = Q_INTERPOLATE(color[6], color[5], color[5], color[5]); - else - product1b = INTERPOLATE(color[5], color[6]); - } - - if (color[5] == color[10] && color[9] != color[6] && color[4] == color[5] && color[5] != color[14]) - product2a = INTERPOLATE(color[9], color[5]); - else if (color[5] == color[8] && color[6] == color[5] && color[4] != color[9] && color[5] != color[12]) - product2a = INTERPOLATE(color[9], color[5]); - else - product2a = color[9]; - - if (color[9] == color[6] && color[5] != color[10] && color[8] == color[9] && color[9] != color[2]) - product1a = INTERPOLATE(color[9], color[5]); - else if (color[4] == color[9] && color[10] == color[9] && color[8] != color[5] && color[9] != color[0]) - product1a = INTERPOLATE(color[9], color[5]); - else - product1a = color[5]; - - if (PixelsPerMask == 2) - { - if( ScummPCMode ) - { - SWAP_WORD( product1a ); - SWAP_WORD( product1b ); - SWAP_WORD( product2a ); - SWAP_WORD( product2b ); - } - *((unsigned long *) (&dst_line[0][x * 4])) = (product1a << 16) | product1b; - *((unsigned long *) (&dst_line[1][x * 4])) = (product2a << 16) | product2b; - } - else - { - *((unsigned long *) (&dst_line[0][x * 8])) = product1a; - *((unsigned long *) (&dst_line[0][x * 8 + 4])) = product1b; - *((unsigned long *) (&dst_line[1][x * 8])) = product2a; - *((unsigned long *) (&dst_line[1][x * 8 + 4])) = product2b; - } - - /* Move color matrix forward */ - color[0] = color[1]; color[4] = color[5]; color[8] = color[9]; color[12] = color[13]; - color[1] = color[2]; color[5] = color[6]; color[9] = color[10]; color[13] = color[14]; - color[2] = color[3]; color[6] = color[7]; color[10] = color[11]; color[14] = color[15]; - - if (x < width - 3) - { - x += 3; - if (PixelsPerMask == 2) - { - color[3] = ScummColors16[ *(src_line[0] + x) ]; - color[7] = ScummColors16[ *(src_line[1] + x) ]; - color[11] = ScummColors16[ *(src_line[2] + x) ]; - color[15] = ScummColors16[ *(src_line[3] + x) ]; - } - else - { - color[3] = ScummColors[ *(src_line[0] + x) ]; - color[7] = ScummColors[ *(src_line[1] + x) ]; - color[11] = ScummColors[ *(src_line[2] + x) ]; - color[15] = ScummColors[ *(src_line[3] + x) ]; - } - x -= 3; - } - } - - /* We're done with one line, so we shift the source lines up */ - src_line[0] = src_line[1]; - src_line[1] = src_line[2]; - src_line[2] = src_line[3]; - - /* Read next line */ - if (y + 3 >= height) - src_line[3] = src_line[2]; - else - src_line[3] = src_line[2] + ScummBufferWidth; - - /* Then shift the color matrix up */ - if (PixelsPerMask == 2) - { - byte *sbp; - sbp = src_line[0]; - color[0] = ScummColors16[ *sbp ]; color[1] = color[0]; color[2] = ScummColors16[ *(sbp + 1) ]; color[3] = ScummColors16[ *(sbp + 2) ]; - sbp = src_line[1]; - color[4] = ScummColors16[ *sbp ]; color[5] = color[4]; color[6] = ScummColors16[ *(sbp + 1) ]; color[7] = ScummColors16[ *(sbp + 2) ]; - sbp = src_line[2]; - color[8] = ScummColors16[ *sbp ]; color[9] = color[8]; color[10] = ScummColors16[ *(sbp + 1) ]; color[11] = ScummColors16[ *(sbp + 2) ]; - sbp = src_line[3]; - color[12] = ScummColors16[ *sbp ]; color[13] = color[12]; color[14] = ScummColors16[ *(sbp + 1) ]; color[15] = ScummColors16[ *(sbp + 2) ]; - - if( src_x > 0 ) - { - color[0] = ScummColors16[ src_line[0][-1] ]; - color[4] = ScummColors16[ src_line[1][-1] ]; - color[8] = ScummColors16[ src_line[2][-1] ]; - color[12] = ScummColors16[ src_line[3][-1] ]; - } - } - else - { - byte *lbp; - lbp = src_line[0]; - color[0] = ScummColors[ *lbp ]; color[1] = color[0]; color[2] = ScummColors[ *(lbp + 1) ]; color[3] = ScummColors[ *(lbp + 2) ]; - lbp = src_line[1]; - color[4] = ScummColors[ *lbp ]; color[5] = color[4]; color[6] = ScummColors[ *(lbp + 1) ]; color[7] = ScummColors[ *(lbp + 2) ]; - lbp = src_line[2]; - color[8] = ScummColors[ *lbp ]; color[9] = color[8]; color[10] = ScummColors[ *(lbp + 1) ]; color[11] = ScummColors[ *(lbp + 2) ]; - lbp = src_line[3]; - color[12] = ScummColors[ *lbp ]; color[13] = color[12]; color[14] = ScummColors[ *(lbp + 1) ]; color[15] = ScummColors[ *(lbp + 2) ]; - } - - if (y < height - 1) - { - dst_line[0] = dst_line[1]+dest_pitch; - dst_line[1] = dst_line[0]+dest_pitch; - } - } + byte *dst; - UnLockBitMap( handle ); -} + if (x < 0) { w+=x; src-=x; x = 0; } + if (y < 0) { h+=y; src-=y*pitch; y = 0; } + if (w >= ScummBufferWidth-x) { w = ScummBufferWidth - x; } + if (h >= ScummBufferHeight-y) { h = ScummBufferHeight - y; } -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]; - byte *src; - byte *dest; - uint32 dest_bpp; - uint32 dest_pitch; - APTR handle; - - if( (handle = LockBitMapTags( ScummRenderTo, LBMI_BYTESPERPIX, &dest_bpp, LBMI_BYTESPERROW, &dest_pitch, LBMI_BASEADDRESS, &dest, TAG_DONE )) == 0 ) + if (w <= 0 || h <= 0) return; - src = (byte *)ScummBuffer+src_y*ScummBufferWidth+src_x; - - /* Point to the first 3 lines. */ - src_line[0] = src; - src_line[1] = src; - src_line[2] = src + ScummBufferWidth; - src_line[3] = src + ScummBufferWidth * 2; - - dst_line[0] = dest+dest_y*2*dest_pitch+dest_x*2*dest_bpp; - dst_line[1] = dst_line[0]+dest_pitch; - - x = 0, y = 0; - - if (PixelsPerMask == 2) - { - byte *sbp; - sbp = src_line[0]; - color[0] = ScummColors16[ *sbp ]; color[1] = color[0]; color[2] = color[0]; color[3] = color[0]; - color[4] = ScummColors16[ *(sbp + 1) ]; color[5] = ScummColors16[ *(sbp + 2) ]; - sbp = src_line[2]; - color[6] = ScummColors16[ *sbp ]; color[7] = color[6]; color[8] = ScummColors16[ *(sbp + 1) ]; color[9] = ScummColors16[ *(sbp + 2) ]; - sbp = src_line[3]; - color[10] = ScummColors16[ *sbp ]; color[11] = ScummColors16[ *(sbp + 1) ]; - } - else + if (MouseDrawn) { - byte *lbp; - lbp = src_line[0]; - color[0] = ScummColors[ *lbp ]; color[1] = color[0]; color[2] = color[0]; color[3] = color[0]; - color[4] = ScummColors[ *(lbp + 1) ]; color[5] = ScummColors[ *(lbp + 2) ]; - lbp = src_line[2]; - color[6] = ScummColors[ *lbp ]; color[7] = color[6]; color[8] = ScummColors[ *(lbp + 1) ]; color[9] = ScummColors[ *(lbp + 2) ]; - lbp = src_line[3]; - color[10] = ScummColors[ *lbp ]; color[11] = ScummColors[ *(lbp + 1) ]; + if (MOUSE_INTERSECTS(x, y, w, h)) + UndrawMouse(); } - for (y = 0; y < height; y++) + AddUpdateRect(x, y, w, h); + + dst = (byte *)ScummBuffer+y*ScummBufferWidth + x; + if (DirtyBlocks) { - /* Todo: x = width - 2, x = width - 1 */ - - for (x = 0; x < width; x++) + int cx, cy; + int block = BLOCK_ID(x, y); + int line_block = block; + int start_block = BLOCKSIZE_X-(x % BLOCKSIZE_X); + int start_y_block = BLOCKSIZE_Y-(y % BLOCKSIZE_Y); + int next_block; + int next_y_block; + UWORD *block_cols = BlockColors[block]; + + if (start_block == 0) + start_block = BLOCKSIZE_X; + if (start_y_block == 0) + start_y_block = BLOCKSIZE_Y; + + next_block = start_block; + next_y_block = start_y_block; + for (cy = 0; cy < h; cy++) { - unsigned long product1a, product1b, product2a, product2b; - -//--------------------------------------- B1 B2 0 1 -// 4 5 6 S2 -> 2 3 4 5 -// 1 2 3 S1 6 7 8 9 -// A1 A2 10 11 - - if (color[7] == color[4] && color[3] != color[8]) - { - product1b = product2a = color[7]; - - if ((color[6] == color[7]) || (color[4] == color[1])) - product1a = INTERPOLATE(color[7], INTERPOLATE(color[7], color[3])); - else - product1a = INTERPOLATE(color[3], color[4]); - - if ((color[4] == color[5]) || (color[7] == color[10])) - product2b = INTERPOLATE(color[7], INTERPOLATE(color[7], color[8])); - else - product2b = INTERPOLATE(color[7], color[8]); - } - else if (color[3] == color[8] && color[7] != color[4]) - { - product2b = product1a = color[3]; - - if ((color[0] == color[3]) || (color[5] == color[9])) - product1b = INTERPOLATE(color[3], INTERPOLATE(color[3], color[4])); - else - product1b = INTERPOLATE(color[3], color[1]); - - if ((color[8] == color[11]) || (color[2] == color[3])) - product2a = INTERPOLATE(color[3], INTERPOLATE(color[3], color[2])); - else - product2a = INTERPOLATE(color[7], color[8]); - - } - else if (color[3] == color[8] && color[7] == color[4]) - { - register int r = 0; - - r += GET_RESULT(color[4], color[3], color[6], color[10]); - r += GET_RESULT(color[4], color[3], color[2], color[0]); - r += GET_RESULT(color[4], color[3], color[11], color[9]); - r += GET_RESULT(color[4], color[3], color[1], color[5]); - - if (r > 0) - { - product1b = product2a = color[7]; - product1a = product2b = INTERPOLATE(color[3], color[4]); - } - else if (r < 0) - { - product2b = product1a = color[3]; - product1b = product2a = INTERPOLATE(color[3], color[4]); - } - else - { - product2b = product1a = color[3]; - product1b = product2a = color[7]; - } - } - else - { - product2b = product1a = INTERPOLATE(color[7], color[4]); - product2b = Q_INTERPOLATE(color[8], color[8], color[8], product2b); - product1a = Q_INTERPOLATE(color[3], color[3], color[3], product1a); - - product2a = product1b = INTERPOLATE(color[3], color[8]); - product2a = Q_INTERPOLATE(color[7], color[7], color[7], product2a); - product1b = Q_INTERPOLATE(color[4], color[4], color[4], product1b); - } - - if (PixelsPerMask == 2) - { - if( ScummPCMode ) - { - SWAP_WORD( product1a ); - SWAP_WORD( product1b ); - SWAP_WORD( product2a ); - SWAP_WORD( product2b ); - } - *((unsigned long *) (&dst_line[0][x * 4])) = (product1a << 16) | product1b; - *((unsigned long *) (&dst_line[1][x * 4])) = (product2a << 16) | product2b; - } - else - { - *((unsigned long *) (&dst_line[0][x * 8])) = product1a; - *((unsigned long *) (&dst_line[0][x * 8 + 4])) = product1b; - *((unsigned long *) (&dst_line[1][x * 8])) = product2a; - *((unsigned long *) (&dst_line[1][x * 8 + 4])) = product2b; - } - - /* Move color matrix forward */ - color[0] = color[1]; - color[2] = color[3]; color[3] = color[4]; color[4] = color[5]; - color[6] = color[7]; color[7] = color[8]; color[8] = color[9]; - color[10] = color[11]; - - if (x < width - 2) + for (cx = 0; cx < w; cx++) { - x += 2; - if (PixelsPerMask == 2) + UWORD old_pixel = *dst; + UWORD src_pixel = *src++; + if (old_pixel != src_pixel) { - color[1] = ScummColors16[ *(src_line[0] + x) ]; - if( x < width-1 ) - { - color[5] = ScummColors16[ *(src_line[1] + x + 1) ]; - color[9] = ScummColors16[ *(src_line[2] + x + 1) ]; - } - color[11] = ScummColors16[ *(src_line[3] + x) ]; + *dst++ = src_pixel; + block_cols[old_pixel]--; + block_cols[src_pixel]++; } else + dst++; + if (--next_block == 0) { - color[1] = ScummColors[ *(src_line[0] + x) ]; - if( x < width-1 ) - { - color[5] = ScummColors[ *(src_line[1] + x + 1) ]; - color[9] = ScummColors[ *(src_line[2] + x + 1) ]; - } - color[11] = ScummColors[ *(src_line[3] + x) ]; + block++; + block_cols = BlockColors[block]; + next_block = BLOCKSIZE_X; } - x -= 2; } - } - - /* We're done with one line, so we shift the source lines up */ - src_line[0] = src_line[1]; - src_line[1] = src_line[2]; - src_line[2] = src_line[3]; - - /* Read next line */ - if (y + 3 >= height) - src_line[3] = src_line[2]; - else - src_line[3] = src_line[2] + ScummBufferWidth; - - /* Then shift the color matrix up */ - if (PixelsPerMask == 2) - { - byte *sbp; - sbp = src_line[0]; - color[0] = ScummColors16[ *sbp ]; color[1] = ScummColors16[ *(sbp + 1) ]; - sbp = src_line[1]; - color[2] = ScummColors16[ *sbp ]; color[3] = color[2]; color[4] = ScummColors16[ *(sbp + 1) ]; color[5] = ScummColors16[ *(sbp + 2) ]; - sbp = src_line[2]; - color[6] = ScummColors16[ *sbp ]; color[7] = color[6]; color[8] = ScummColors16[ *(sbp + 1) ]; color[9] = ScummColors16[ *(sbp + 2) ]; - sbp = src_line[3]; - color[10] = ScummColors16[ *sbp ]; color[11] = ScummColors16[ *(sbp + 1) ]; - } - else - { - byte *lbp; - lbp = src_line[0]; - color[0] = ScummColors[ *lbp ]; color[1] = ScummColors[ *(lbp + 1) ]; - lbp = src_line[1]; - color[2] = ScummColors[ *lbp ]; color[3] = color[2]; color[4] = ScummColors[ *(lbp + 1) ]; color[5] = ScummColors[ *(lbp + 2) ]; - lbp = src_line[2]; - color[6] = ScummColors[ *lbp ]; color[7] = color[6]; color[8] = ScummColors[ *(lbp + 1) ]; color[9] = ScummColors[ *(lbp + 2) ]; - lbp = src_line[3]; - color[10] = ScummColors[ *lbp ]; color[11] = ScummColors[ *(lbp + 1) ]; - } - - - if (y < height - 1) - { - dst_line[0] = dst_line[1]+dest_pitch; - dst_line[1] = dst_line[0]+dest_pitch; - } - } - - UnLockBitMap( handle ); -} - -void OSystem_MorphOS::AdvMame2xScaler( uint32 src_x, uint32 src_y, uint32 dest_x, uint32 dest_y, uint32 width, uint32 height ) -{ - byte *dest; - uint32 dest_bpp; - uint32 dest_pitch; - APTR handle; - - if( (handle = LockBitMapTags( ScummRenderTo, LBMI_BYTESPERPIX, &dest_bpp, LBMI_BYTESPERROW, &dest_pitch, LBMI_BASEADDRESS, &dest, TAG_DONE )) == 0 ) - return; - - byte *src = (byte *)ScummBuffer+src_y*ScummBufferWidth+src_x; - - src_line[0] = src; - src_line[1] = src; - src_line[2] = src + ScummBufferWidth; - - dst_line[0] = dest+dest_y*2*dest_pitch+dest_x*2*dest_bpp; - dst_line[1] = dst_line[0]+dest_pitch; - - for( int y = 0; y < height; y++ ) - { - for( int x = 0; x < width; x++ ) - { - uint32 B, D, E, F, H; - - if( PixelsPerMask == 2 ) - { - // short A = *(src + i - nextlineSrc - 1); - B = ScummColors16[ src_line[ 0 ][ x ] ]; - // short C = *(src + i - nextlineSrc + 1); - D = ScummColors16[ src_line[ 1 ][ x-1 ] ]; - E = ScummColors16[ src_line[ 1 ][ x ] ]; - F = ScummColors16[ src_line[ 1 ][ x+1 ] ]; - // short G = *(src + i + nextlineSrc - 1); - H = ScummColors16[ src_line[ 2 ][ x ] ]; - // short I = *(src + i + nextlineSrc + 1); - } - else + if (--next_y_block == 0) { - // short A = *(src + i - nextlineSrc - 1); - B = ScummColors[ src_line[ 0 ][ x ] ]; - // short C = *(src + i - nextlineSrc + 1); - D = ScummColors[ src_line[ 1 ][ x-1 ] ]; - E = ScummColors[ src_line[ 1 ][ x ] ]; - F = ScummColors[ src_line[ 1 ][ x+1 ] ]; - // short G = *(src + i + nextlineSrc - 1); - H = ScummColors[ src_line[ 2 ][ x ] ]; - // short I = *(src + i + nextlineSrc + 1); + line_block += BLOCKS_X; + next_y_block = BLOCKSIZE_Y; } - - - if (PixelsPerMask == 2) - { - if( ScummPCMode ) - { - SWAP_WORD( B ); - SWAP_WORD( D ); - SWAP_WORD( E ); - SWAP_WORD( F ); - SWAP_WORD( H ); - } - *((unsigned long *) (&dst_line[0][x * 4])) = ((D == B && B != F && D != H ? D : E) << 16) | (B == F && B != D && F != H ? F : E); - *((unsigned long *) (&dst_line[1][x * 4])) = ((D == H && D != B && H != F ? D : E) << 16) | (H == F && D != H && B != F ? F : E); - } - else - { - *((unsigned long *) (&dst_line[0][x * 8])) = D == B && B != F && D != H ? D : E; - *((unsigned long *) (&dst_line[0][x * 8 + 4])) = B == F && B != D && F != H ? F : E; - *((unsigned long *) (&dst_line[1][x * 8])) = D == H && D != B && H != F ? D : E; - *((unsigned long *) (&dst_line[1][x * 8 + 4])) = H == F && D != H && B != F ? F : E; - } - } - - src_line[0] = src_line[1]; - src_line[1] = src_line[2]; - if (y + 2 >= height) - src_line[2] = src_line[1]; - else - src_line[2] = src_line[1] + ScummBufferWidth; - - if( y < height - 1 ) - { - dst_line[0] = dst_line[1]+dest_pitch; - dst_line[1] = dst_line[0]+dest_pitch; + block = line_block; + block_cols = BlockColors[block]; + next_block = start_block; + dst += ScummBufferWidth-w; + src += pitch-w; } } - - UnLockBitMap( handle ); -} - -void OSystem_MorphOS::PointScaler( uint32 src_x, uint32 src_y, uint32 dest_x, uint32 dest_y, uint32 width, uint32 height ) -{ - byte *src; - byte *dest; - uint32 dest_bpp; - uint32 dest_pixfmt; - uint32 dest_pitch; - uint32 color; - uint32 r, g, b; - uint32 x, y; - APTR handle; - - if( (handle = LockBitMapTags( ScummRenderTo, LBMI_BYTESPERPIX, &dest_bpp, - LBMI_BYTESPERROW, &dest_pitch, - LBMI_BASEADDRESS, &dest, - LBMI_PIXFMT, &dest_pixfmt, - TAG_DONE )) == 0 ) - return; - - src = (byte *)ScummBuffer+src_y*ScummBufferWidth+src_x; - - dst_line[0] = dest+dest_y*2*dest_pitch+dest_x*2*dest_bpp; - dst_line[1] = dst_line[0]+dest_pitch; - - for( y = 0; y < height; y++ ) + else { - for( x = 0; x < width; x++ ) + do { - r = (ScummColors[ *(src+x) ] >> 16) & 0xff; - g = (ScummColors[ *(src+x) ] >> 8) & 0xff; - b = ScummColors[ *(src+x) ] & 0xff; - - color = make_color( dest_pixfmt, r, g, b ); - if( PixelsPerMask == 2 ) - { - if( ScummPCMode ) - SWAP_WORD( color ); - - *((unsigned long *) (&dst_line[0][x * 4])) = (color << 16) | color; - *((unsigned long *) (&dst_line[1][x * 4])) = (color << 16) | color; - } - else - { - *((unsigned long *) (&dst_line[0][x * 8])) = color; - *((unsigned long *) (&dst_line[0][x * 8 + 4])) = color; - *((unsigned long *) (&dst_line[1][x * 8])) = color; - *((unsigned long *) (&dst_line[1][x * 8 + 4])) = color; - } - } - - src += ScummBufferWidth; - - if (y < height - 1) - { - dst_line[0] = dst_line[1]+dest_pitch; - dst_line[1] = dst_line[0]+dest_pitch; - } + memcpy(dst, src, w); + dst += ScummBufferWidth; + src += pitch; + } while (--h); } - - UnLockBitMap( handle ); } -/* Copy part of bitmap */ -void OSystem_MorphOS::copy_rect(const byte *src, int pitch, int x, int y, int w, int h) +bool OSystem_MorphOS::AddUpdateRect(WORD x, WORD y, WORD w, WORD h) { - byte *dst; - - if (x < 0) { w+=x; src-=x; x = 0; } - if (y < 0) { h+=y; src-=y*pitch; y = 0; } + if (x < 0) { w+=x; x = 0; } + if (y < 0) { h+=y; y = 0; } if (w >= ScummBufferWidth-x) { w = ScummBufferWidth - x; } if (h >= ScummBufferHeight-y) { h = ScummBufferHeight - y; } - if (w<=0 || h<=0) - return; - - /* FIXME: undraw mouse only if the draw rect intersects with the mouse rect */ - if( MouseDrawn ) - undraw_mouse(); + if (w <= 0 || h <= 0) + return false; - dst = (byte *)ScummBuffer+y*ScummBufferWidth + x; - do - { - memcpy( dst, src, w ); - dst += ScummBufferWidth; - src += pitch; - } while( --h ); + Rectangle update_rect = { x, y, x+w, y+h }; + OrRectRegion(NewUpdateRegion, &update_rect); ScreenChanged = true; + + return true; } void OSystem_MorphOS::update_screen() { - if( !ScreenChanged ) + DrawMouse(); + + if (!ScreenChanged) return; - draw_mouse(); + OrRegionRegion(NewUpdateRegion, UpdateRegion); - if( !ScummScale ) + if (ScummShakePos) { - struct RastPort rp; + RastPort rp; - InitRastPort( &rp ); + InitRastPort(&rp); rp.BitMap = ScummRenderTo; - if( ScummDepth == 8 ) - WritePixelArray( ScummBuffer, 0, 0, ScummBufferWidth, &rp, 0, ScummShakePos, ScummBufferWidth, ScummBufferHeight, RECTFMT_LUT8 ); - else - WriteLUTPixelArray( ScummBuffer, 0, 0, ScummBufferWidth, &rp, ScummColors, 0, ScummShakePos, ScummBufferWidth, ScummBufferHeight, CTABFMT_XRGB8 ); - } - else - { uint32 src_y = 0; uint32 dest_y = 0; - if( ScummShakePos < 0 ) + if (ScummShakePos < 0) src_y = -ScummShakePos; else dest_y = ScummShakePos; - - switch( ScummScaler ) + + if (!ScummScale) { - case ST_POINT: - PointScaler( 0, src_y, 0, dest_y, ScummBufferWidth, ScummBufferHeight-src_y-dest_y ); - break; + if (ScummDepth == 8) + WritePixelArray(ScummBuffer, 0, src_y, ScummBufferWidth, &rp, 0, dest_y, ScummBufferWidth, ScummBufferHeight-src_y-dest_y, RECTFMT_LUT8); + else + WriteLUTPixelArray(ScummBuffer, 0, src_y, ScummBufferWidth, &rp, ScummColors, 0, dest_y, ScummBufferWidth, ScummBufferHeight-src_y-dest_y, CTABFMT_XRGB8); + } + else if (Scaler->Prepare(ScummRenderTo)) + { + Scaler->Scale(0, src_y, 0, dest_y, ScummBufferWidth, ScummBufferHeight-src_y-dest_y); + Scaler->Finish(); + } - case ST_ADVMAME2X: - AdvMame2xScaler( 0, src_y, 0, dest_y, ScummBufferWidth, ScummBufferHeight-src_y-dest_y ); - break; + if (ScummShakePos < 0) + FillPixelArray(&rp, 0, (ScummBufferHeight-1) << ScummScale, ScummScrWidth, -ScummShakePos << ScummScale, 0); + else + FillPixelArray(&rp, 0, 0, ScummScrWidth, ScummShakePos << ScummScale, 0); + } + else if (!ScummScale) + { + RastPort rp; - case ST_SUPEREAGLE: - SuperEagle( 0, src_y, 0, dest_y, ScummBufferWidth, ScummBufferHeight-src_y-dest_y ); - break; + InitRastPort(&rp); + rp.BitMap = ScummRenderTo; - case ST_SUPER2XSAI: - Super2xSaI( 0, src_y, 0, dest_y, ScummBufferWidth, ScummBufferHeight-src_y-dest_y ); - break; + uint32 src_x, src_y; + uint32 src_w, src_h; + uint32 reg_x, reg_y; + RegionRectangle *update_rect = UpdateRegion->RegionRectangle; + + reg_x = UpdateRegion->bounds.MinX; + reg_y = UpdateRegion->bounds.MinY; + while (update_rect) + { + src_x = update_rect->bounds.MinX; + src_y = update_rect->bounds.MinY; + src_w = update_rect->bounds.MaxX-src_x; + src_h = update_rect->bounds.MaxY-src_y; + src_x += reg_x; + src_y += reg_y; + + if (src_x) src_x--; + if (src_y) src_y--; + src_w += 2; + if (src_x+src_w >= ScummBufferWidth) + src_w = ScummBufferWidth-src_x; + src_h += 2; + if (src_y+src_h >= ScummBufferHeight) + src_h = ScummBufferHeight-src_y; + + if (ScummDepth == 8) + WritePixelArray(ScummBuffer, src_x, src_y, ScummBufferWidth, &rp, src_x, src_y, src_w, src_h, RECTFMT_LUT8); + else + WriteLUTPixelArray(ScummBuffer, src_x, src_y, ScummBufferWidth, &rp, ScummColors, src_x, src_y, src_w, src_h, CTABFMT_XRGB8); + + update_rect = update_rect->Next; } } - - /* Account for shaking (blacken rest of screen) */ - if( ScummShakePos ) + else { - struct RastPort rp; + uint32 src_x, src_y; + uint32 src_w, src_h; + uint32 reg_x, reg_y; + RegionRectangle *update_rect = UpdateRegion->RegionRectangle; - InitRastPort( &rp ); - rp.BitMap = ScummRenderTo; + reg_x = UpdateRegion->bounds.MinX; + reg_y = UpdateRegion->bounds.MinY; - if( ScummShakePos < 0 ) - FillPixelArray( &rp, 0, (ScummBufferHeight-1) << ScummScale, ScummScrWidth, -ScummShakePos << ScummScale, 0 ); - else - FillPixelArray( &rp, 0, 0, ScummScrWidth, ScummShakePos << ScummScale, 0 ); + if (!Scaler->Prepare(ScummRenderTo)) + update_rect = NULL; + + while (update_rect) + { + src_x = update_rect->bounds.MinX; + src_y = update_rect->bounds.MinY; + src_w = update_rect->bounds.MaxX-src_x; + src_h = update_rect->bounds.MaxY-src_y; + src_x += reg_x; + src_y += reg_y; + + if (src_x) src_x--; + if (src_y) src_y--; + src_w += 2; + if (src_x+src_w >= ScummBufferWidth) + src_w = ScummBufferWidth-src_x; + src_h += 2; + if (src_y+src_h >= ScummBufferHeight) + src_h = ScummBufferHeight-src_y; + + Scaler->Scale(src_x, src_y, src_x, src_y, src_w, src_h); + update_rect = update_rect->Next; + } + Scaler->Finish(); } - if( ScummScreen ) + if (ScummScreen) { - while( !ChangeScreenBuffer( ScummScreen, ScummScreenBuffer[ ScummPaintBuffer ] ) ); - WaitTOF(); + while (!ChangeScreenBuffer(ScummScreen, ScummScreenBuffer[ScummPaintBuffer])); ScummPaintBuffer = !ScummPaintBuffer; - ScummRenderTo = ScummScreenBuffer[ ScummPaintBuffer ]->sb_BitMap; + ScummRenderTo = ScummScreenBuffer[ScummPaintBuffer]->sb_BitMap; } else { - BltBitMapRastPort( ScummRenderTo, 0, 0, ScummWindow->RPort, ScummWindow->BorderLeft, ScummWindow->BorderTop, ScummScrWidth, ScummScrHeight, ABNC | ABC ); + int32 x = (UpdateRegion->bounds.MinX-1) << ScummScale; + int32 y = (UpdateRegion->bounds.MinY-1) << ScummScale; + if (x < 0) x = 0; + if (y < 0) y = 0; + int32 w = (UpdateRegion->bounds.MaxX << ScummScale)-x+(1 << ScummScale); + int32 h = (UpdateRegion->bounds.MaxY << ScummScale)-y+(1 << ScummScale); + if (x+w > ScummScrWidth) w = ScummScrWidth-x; + if (y+h > ScummScrHeight) h = ScummScrHeight-y; + BltBitMapRastPort(ScummRenderTo, x, y, ScummWindow->RPort, ScummWindow->BorderLeft+x, ScummWindow->BorderTop+y, w, h, ABNC | ABC); WaitBlit(); } + + Region *new_region_part = NewUpdateRegion; + NewUpdateRegion = UpdateRegion; + ClearRegion(NewUpdateRegion); + UpdateRegion = new_region_part; + ScreenChanged = false; + memset(DirtyBlocks, 0, BLOCKS_X*BLOCKS_Y*sizeof (bool)); } -void OSystem_MorphOS::draw_mouse() +void OSystem_MorphOS::DrawMouse() { int x,y; byte *dst,*bak; byte color; - if( MouseDrawn || !MouseVisible ) + if (MouseDrawn || !MouseVisible) return; MouseDrawn = true; @@ -1588,63 +1111,69 @@ void OSystem_MorphOS::draw_mouse() MouseOldWidth = w; MouseOldHeight = h; + AddUpdateRect(xdraw, ydraw, w, h); + dst = (byte*)ScummBuffer + ydraw*ScummBufferWidth + xdraw; bak = MouseBackup; - for( y = 0; y < h; y++, dst += ScummBufferWidth, bak += MAX_MOUSE_W, buf += w ) + for (y = 0; y < h; y++, dst += ScummBufferWidth, bak += MAX_MOUSE_W, buf += w) { - if( (uint)(ydraw+y) < ScummBufferHeight ) + if ((uint)(ydraw+y) < ScummBufferHeight) { for( x = 0; x<w; x++ ) { - if( (uint)(xdraw+x) < ScummBufferWidth ) + if ((uint)(xdraw+x) < ScummBufferWidth) { bak[x] = dst[x]; - if( (color=buf[x])!=0xFF ) + if ((color=buf[x])!=0xFF) dst[ x ] = color; } } } + else + break; } } -void OSystem_MorphOS::undraw_mouse() +void OSystem_MorphOS::UndrawMouse() { int x,y; byte *dst,*bak; - if( !MouseDrawn ) + if (!MouseDrawn) return; MouseDrawn = false; dst = (byte*)ScummBuffer + MouseOldY*ScummBufferWidth + MouseOldX; bak = MouseBackup; - for( y = 0; y < MouseOldHeight; y++, bak += MAX_MOUSE_W, dst += ScummBufferWidth ) + AddUpdateRect(MouseOldX, MouseOldY, MouseOldWidth, MouseOldHeight); + + for (y = 0; y < MouseOldHeight; y++, bak += MAX_MOUSE_W, dst += ScummBufferWidth) { - if( (uint)(MouseOldY + y) < ScummBufferHeight ) + if ((uint)(MouseOldY + y) < ScummBufferHeight) { - for( x = 0; x < MouseOldWidth; x++ ) + for (x = 0; x < MouseOldWidth; x++) { - if( (uint)(MouseOldX + x) < ScummBufferWidth ) - dst[ x ] = bak[ x ]; + if ((uint)(MouseOldX + x) < ScummBufferWidth) + dst[x] = bak[x]; } } + else + break; } } bool OSystem_MorphOS::show_mouse(bool visible) { - if( MouseVisible == visible ) + if (MouseVisible == visible) return visible; bool last = MouseVisible; MouseVisible = visible; - if( visible ) - draw_mouse(); - else - undraw_mouse(); + if (!visible) + UndrawMouse(); return last; } @@ -1655,8 +1184,7 @@ void OSystem_MorphOS::set_mouse_pos(int x, int y) { MouseX = x; MouseY = y; - undraw_mouse(); - ScreenChanged = true; + UndrawMouse(); } } @@ -1670,11 +1198,10 @@ void OSystem_MorphOS::set_mouse_cursor(const byte *buf, uint w, uint h, int hots MouseImage = (byte*)buf; - undraw_mouse(); - ScreenChanged = true; + UndrawMouse(); } -bool OSystem_MorphOS::set_sound_proc( void *param, OSystem::SoundProc *proc, byte format ) +bool OSystem_MorphOS::set_sound_proc(void *param, OSystem::SoundProc *proc, byte format) { static EmulFunc MySoundEmulFunc; @@ -1691,64 +1218,76 @@ bool OSystem_MorphOS::set_sound_proc( void *param, OSystem::SoundProc *proc, byt MySoundEmulFunc.Arg1 = (ULONG)this; MySoundEmulFunc.Arg2 = AHIST_S16S; - soundProcTags[ 0 ].ti_Data = (ULONG)&MySoundEmulFunc; - ScummSoundThread = CreateNewProc( soundProcTags ); + soundProcTags[0].ti_Data = (ULONG)&MySoundEmulFunc; + ScummSoundThread = CreateNewProc(soundProcTags); - if( !ScummSoundThread ) + if (!ScummSoundThread) { - puts( "Failed to create sound thread" ); - exit( 1 ); + puts("Failed to create sound thread"); + exit(1); } return true; } -void OSystem_MorphOS::fill_sound( byte *stream, int len ) +void OSystem_MorphOS::fill_sound(byte *stream, int len) { - if( SoundProc ) - SoundProc( SoundParam, stream, len ); + if (SoundProc) + SoundProc(SoundParam, stream, len); else - memset( stream, 0x0, len ); + memset(stream, 0x0, len); } -void OSystem_MorphOS::init_size( uint w, uint h ) +void OSystem_MorphOS::init_size(uint w, uint h) { /* * Allocate image buffer */ - ScummBuffer = AllocVec( w*h, MEMF_ANY | MEMF_CLEAR ); - - if( ScummBuffer == NULL ) + ScummBuffer = AllocVec(w*h, MEMF_CLEAR); + + if (ScummBuffer == NULL) { - puts( "Couldn't allocate image buffer" ); - exit( 1 ); + puts("Couldn't allocate image buffer"); + exit(1); } - memset( ScummColors, 0, 256*sizeof( ULONG ) ); + memset(ScummColors, 0, 256*sizeof (ULONG)); ScummBufferWidth = w; ScummBufferHeight = h; - create_screen( CSDSPTYPE_KEEP ); -} -OSystem_MorphOS::SCALERTYPE OSystem_MorphOS::FindScaler( const char *ScalerName ) -{ - int scaler = 0; - - while( ScummScalers[ scaler ].gs_Name ) + DirtyBlocks = (bool *) AllocVec(BLOCKS_X*BLOCKS_Y*sizeof (bool), MEMF_CLEAR); + if (DirtyBlocks) { - if( !stricmp( ScalerName, ScummScalers[ scaler ].gs_Name ) ) - return ScummScalers[ scaler ].gs_Type; - scaler++; - } + BlockColors = (UWORD **) AllocVec(BLOCKS_X*BLOCKS_Y*sizeof (UWORD *), MEMF_CLEAR); + if (BlockColors) + { + int b; - 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 ); + for (b = 0; b < BLOCKS_X*BLOCKS_Y; b++) + { + BlockColors[b] = (UWORD *) AllocVec(256*sizeof (UWORD), MEMF_CLEAR); + if (BlockColors[b] == NULL) + break; + BlockColors[b][0] = BLOCKSIZE_X*BLOCKSIZE_Y; + } + + if (b < BLOCKS_X*BLOCKS_Y) + { + for (--b; b >= 0; --b) + FreeVec(BlockColors[b]); + FreeVec(BlockColors); + BlockColors = NULL; + } + } + + if (!BlockColors) + { + FreeVec(DirtyBlocks); + DirtyBlocks = NULL; + } } - return ST_INVALID; + CreateScreen(CSDSPTYPE_KEEP); } diff --git a/morphos/morphos.h b/morphos/morphos.h index d0d05ea10d..75d2c79f7b 100644 --- a/morphos/morphos.h +++ b/morphos/morphos.h @@ -21,15 +21,22 @@ * */ +#ifndef MORPHOS_MORPHOS_H +#define MORPHOS_MORPHOS_H + #include <exec/semaphores.h> +#include <devices/amidi.h> +#include <graphics/regions.h> +#include <intuition/intuition.h> +#include <intuition/screens.h> #include <libraries/cdda.h> +#include "morphos_scaler.h" + class OSystem_MorphOS : public OSystem { public: - typedef enum { ST_INVALID = 0, ST_NONE, ST_POINT, ST_ADVMAME2X, ST_SUPEREAGLE, ST_SUPER2XSAI } SCALERTYPE; - - OSystem_MorphOS( int game_id, SCALERTYPE gfx_mode, bool full_screen ); + OSystem_MorphOS(int game_id, SCALERTYPE gfx_mode, bool full_screen); virtual ~OSystem_MorphOS(); // Set colors of the palette @@ -102,87 +109,66 @@ class OSystem_MorphOS : public OSystem // 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 void OpenATimer( struct MsgPort **port, struct IORequest **req, ULONG unit ); + static OSystem_MorphOS *create(int game_id, SCALERTYPE gfx_scaler, bool full_screen); - static SCALERTYPE FindScaler ( const char *ScalerName ); + static bool OpenATimer(MsgPort **port, IORequest **req, ULONG unit, bool required = true); 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 AdvMame2xScaler ( 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 CreateScreen(CS_DSPTYPE dspType); + void SwitchScalerTo(SCALERTYPE newScaler); + bool AddUpdateRect(WORD x, WORD y, WORD w, WORD h); - void draw_mouse(); - void undraw_mouse(); + void DrawMouse(); + void UndrawMouse(); /* Display-related attributes */ - struct Screen *ScummScreen; - struct Window *ScummWindow; - char ScummWndTitle[ 125 ]; - APTR ScummBuffer; - int ScummBufferWidth; - int ScummBufferHeight; - 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 ScummDefaultMouse; - bool ScummOrigMouse; - int ScummShakePos; - bool FullScreenMode; - bool ScreenChanged; - - /* 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]; + Screen *ScummScreen; + Window *ScummWindow; + char ScummWndTitle[125]; + APTR ScummBuffer; + int ScummBufferWidth; + int ScummBufferHeight; + ScreenBuffer *ScummScreenBuffer[2]; + BitMap *ScummRenderTo; + ULONG ScummPaintBuffer; + int ScummScrWidth; + int ScummScrHeight; + int ScummDepth; + bool Scumm16ColFmt16; + UWORD *ScummNoCursor; + ULONG ScummColors[256]; + USHORT ScummColors16[256]; + WORD ScummWinX; + WORD ScummWinY; + bool ScummDefaultMouse; + bool ScummOrigMouse; + int ScummShakePos; + bool FullScreenMode; + bool ScreenChanged; + UWORD **BlockColors; + bool *DirtyBlocks; + Region *UpdateRegion; + Region *NewUpdateRegion; /* Sound-related attributes */ - struct Process *ScummMusicThread; - struct Process *ScummSoundThread; - SoundProc *SoundProc; - void *SoundParam; + Process *ScummMusicThread; + Process *ScummSoundThread; + SoundProc *SoundProc; + void *SoundParam; /* CD-ROM related attributes */ - CDRIVEPTR CDrive; - ULONG CDDATrackOffset; + CDRIVEPTR CDrive; + ULONG CDDATrackOffset; /* Scaling-related attributes */ SCALERTYPE ScummScaler; int ScummScale; - static GfxScaler ScummScalers[ 10 ]; + MorphOSScaler *Scaler; /* Mouse cursor-related attributes */ bool MouseVisible, MouseDrawn; @@ -191,28 +177,30 @@ class OSystem_MorphOS : public OSystem int MouseOldX, MouseOldY; int MouseOldWidth, MouseOldHeight; int MouseHotspotX, MouseHotspotY; - byte *MouseImage, MouseBackup[ MAX_MOUSE_W*MAX_MOUSE_H ]; + byte *MouseImage, MouseBackup[MAX_MOUSE_W*MAX_MOUSE_H]; /* Timer-related attributes */ - struct MsgPort *TimerMsgPort; - struct timerequest *TimerIORequest; + MsgPort *TimerMsgPort; + timerequest *TimerIORequest; /* Game-related attributes */ int GameID; }; -int morphos_sound_thread( OSystem_MorphOS *syst, ULONG SampleType ); -bool init_morphos_music( ULONG MidiUnit ); +int morphos_sound_thread(OSystem_MorphOS *syst, ULONG SampleType); +bool init_morphos_music(ULONG MidiUnit); void exit_morphos_music(); -int morphos_main( int argc, char *argv[] ); +int morphos_main(int argc, char *argv[]); extern OSystem_MorphOS *TheSystem; -extern struct SignalSemaphore ScummMusicThreadRunning; -extern struct SignalSemaphore ScummSoundThreadRunning; +extern SignalSemaphore ScummMusicThreadRunning; +extern SignalSemaphore ScummSoundThreadRunning; extern STRPTR ScummMusicDriver; extern LONG ScummMidiUnit; -extern struct IOMidiRequest *ScummMidiRequest; -extern struct timerequest *MusicTimerIORequest; +extern IOMidiRequest *ScummMidiRequest; +extern timerequest *MusicTimerIORequest; + +#endif diff --git a/morphos/morphos_scaler.cpp b/morphos/morphos_scaler.cpp new file mode 100644 index 0000000000..dca4383016 --- /dev/null +++ b/morphos/morphos_scaler.cpp @@ -0,0 +1,823 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2002 The ScummVM project + * + * 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. + * + * $Header$ + */ + +#include "stdafx.h" +#include "scumm.h" + +#include <exec/types.h> +#include <cybergraphics/cybergraphics.h> + +#include <proto/cybergraphics.h> + +#include "morphos.h" +#include "morphos_scaler.h" + +#define GET_RESULT(A, B, C, D) ((A != C || A != D) - (B != C || B != D)) +#define INTERPOLATE(A, B) (((A & colorMask) >> 1) + ((B & colorMask) >> 1) + (A & B & lowPixelMask)) +#define Q_INTERPOLATE(A, B, C, D) ((A & qcolorMask) >> 2) + ((B & qcolorMask) >> 2) + ((C & qcolorMask) >> 2) + ((D & qcolorMask) >> 2) + ((((A & qlowpixelMask) + (B & qlowpixelMask) + (C & qlowpixelMask) + (D & qlowpixelMask)) >> 2) & qlowpixelMask) +#define SWAP_WORD(word) word = ((word & 0xff) << 8) | (word >> 8) + +MorphOSScaler::GfxScaler MorphOSScaler::ScummScalers[11] + = { { "none", "normal", ST_NONE }, + { "Point", "2x", ST_POINT }, + { "AdvMame2x", "advmame2x", ST_ADVMAME2X }, + { "SuperEagle", "supereagle", ST_SUPEREAGLE }, + { "Super2xSaI", "super2xsai", ST_SUPER2XSAI }, + { NULL, NULL, ST_INVALID }, + { NULL, NULL, ST_INVALID }, + { NULL, NULL, ST_INVALID }, + { NULL, NULL, ST_INVALID }, + { NULL, NULL, ST_INVALID }, + // This is the end marker ... do not assign a scaler to it! + { NULL, NULL, ST_INVALID } + }; + +MorphOSScaler::MorphOSScaler(APTR buffer, int width, int height, ULONG *col_table, UWORD *col_table16, BitMap *bmap) +{ + dest = NULL; + handle = NULL; + + Buffer = buffer; + BufferWidth = width; + BufferHeight = height; + + ScummColors = col_table; + ScummColors16 = col_table16; + + /* Initialize scaling stuff */ + int minr, ming, minb; + ULONG depth = GetCyberMapAttr(bmap, CYBRMATTR_DEPTH); + + if (depth > 16) + { + minr = 1 << 16; + ming = 1 << 8; + minb = 1; + } + else + { + minr = 1 << ((depth == 15) ? 10 : 11); + ming = 1 << 5; + minb = 1; + } + + int pixfmt = GetCyberMapAttr(bmap, CYBRMATTR_PIXFMT); + + ScummPCMode = false; + if (pixfmt == PIXFMT_RGB15PC || pixfmt == PIXFMT_BGR15PC || + pixfmt == PIXFMT_RGB16PC || pixfmt == PIXFMT_BGR16PC) + ScummPCMode = true; + + colorMask = (MakeColor(pixfmt, 255, 0, 0) - minr) | (MakeColor(pixfmt, 0, 255, 0) - ming) | (MakeColor(pixfmt, 0, 0, 255) - minb); + lowPixelMask = minr | ming | minb; + qcolorMask = (MakeColor(pixfmt, 255, 0, 0) - 3*minr) | (MakeColor(pixfmt, 0, 255, 0) - 3*ming) | (MakeColor(pixfmt, 0, 0, 255) - 3*minb); + qlowpixelMask = (minr * 3) | (ming * 3) | (minb * 3); + redblueMask = MakeColor(pixfmt, 255, 0, 255); + greenMask = MakeColor(pixfmt, 0, 255, 0); + + PixelsPerMask = (depth <= 16) ? 2 : 1; + + if (PixelsPerMask == 2) + { + colorMask |= (colorMask << 16); + qcolorMask |= (qcolorMask << 16); + lowPixelMask |= (lowPixelMask << 16); + qlowpixelMask |= (qlowpixelMask << 16); + } +} + +MorphOSScaler::~MorphOSScaler() +{ + Finish(); +} + +MorphOSScaler *MorphOSScaler::Create(SCALERTYPE scaler_type, APTR buffer, int width, int height, ULONG *col_table, UWORD *col_table16, BitMap *bmap) +{ + MorphOSScaler *new_scaler = NULL; + + switch (scaler_type) + { + case ST_POINT: + new_scaler = new PointScaler(buffer, width, height, col_table, col_table16, bmap); + break; + + case ST_ADVMAME2X: + new_scaler = new AdvMame2xScaler(buffer, width, height, col_table, col_table16, bmap); + break; + + case ST_SUPEREAGLE: + new_scaler = new SuperEagleScaler(buffer, width, height, col_table, col_table16, bmap); + break; + + case ST_SUPER2XSAI: + new_scaler = new Super2xSaIScaler(buffer, width, height, col_table, col_table16, bmap); + break; + + default: + warning("Invalid scaler requested - falling back to Super2xSaI"); + new_scaler = new Super2xSaIScaler(buffer, width, height, col_table, col_table16, bmap); + break; + } + + return new_scaler; +} + +bool MorphOSScaler::Prepare(BitMap *render_bmap) +{ + handle = LockBitMapTags(render_bmap, LBMI_BYTESPERPIX, &dest_bpp, + LBMI_BYTESPERROW, &dest_pitch, + LBMI_BASEADDRESS, &dest, + LBMI_PIXFMT, &dest_pixfmt, + TAG_DONE); + + return handle != NULL; +} + +void MorphOSScaler::Finish() +{ + if (handle) + { + UnLockBitMap(handle); + handle = NULL; + } +} + +uint32 MorphOSScaler::MakeColor(int pixfmt, int r, int g, int b) +{ + uint32 col = 0; + + switch (pixfmt) + { + case PIXFMT_RGB15: + case PIXFMT_RGB15PC: + col = (((r*31)/255) << 10) | (((g*31)/255) << 5) | ((b*31)/255); + break; + + case PIXFMT_BGR15: + case PIXFMT_BGR15PC: + col = (((b*31)/255) << 10) | (((g*31)/255) << 5) | ((r*31)/255); + break; + + case PIXFMT_RGB16: + case PIXFMT_RGB16PC: + col = (((r*31)/255) << 11) | (((g*63)/255) << 5) | ((b*31)/255); + break; + + case PIXFMT_BGR16: + case PIXFMT_BGR16PC: + col = (((b*31)/255) << 11) | (((g*63)/255) << 5) | ((r*31)/255); + break; + + case PIXFMT_RGB24: + case PIXFMT_ARGB32: + col = (r << 16) | (g << 8) | b; + break; + + case PIXFMT_BGR24: + col = (b << 16) | (g << 8) | r; + break; + + case PIXFMT_BGRA32: + col = (b << 24) | (g << 16) | (r << 8); + break; + + case PIXFMT_RGBA32: + col = (r << 24) | (g << 16) | (b << 8); + break; + + default: + error("Unsupported pixel format: %d. Please contact author at tomjoad@muenster.de.", pixfmt); + } + + return col; +} + +void Super2xSaIScaler::Scale(uint32 src_x, uint32 src_y, uint32 dest_x, uint32 dest_y, uint32 width, uint32 height) +{ + unsigned int x, y; + unsigned long color[16]; + byte *src; + + if (!handle) + return; + + src = ((byte *)Buffer)+src_y*BufferWidth+src_x; + + /* Point to the first 3 lines. */ + src_line[0] = src; + src_line[1] = src; + src_line[2] = src + BufferWidth; + src_line[3] = src + BufferWidth * 2; + + dst_line[0] = dest+dest_y*2*dest_pitch+dest_x*2*dest_bpp; + dst_line[1] = dst_line[0]+dest_pitch; + + if (PixelsPerMask == 2) + { + byte *sbp; + sbp = src_line[0]; + color[0] = ScummColors16[*sbp]; color[1] = color[0]; color[2] = color[0]; color[3] = color[0]; + color[4] = color[0]; color[5] = color[0]; color[6] = ScummColors16[*(sbp+1)]; color[7] = ScummColors16[*(sbp+2)]; + sbp = src_line[2]; + color[8] = ScummColors16[*sbp]; color[9] = color[8]; color[10] = ScummColors16[*(sbp+1)]; color[11] = ScummColors16[*(sbp+2)]; + sbp = src_line[3]; + color[12] = ScummColors16[*sbp]; color[13] = color[12]; color[14] = ScummColors16[*(sbp+1)]; color[15] = ScummColors16[*(sbp+2)]; + } + else + { + byte *lbp; + lbp = src_line[0]; + color[0] = ScummColors[*lbp]; color[1] = color[0]; color[2] = color[0]; color[3] = color[0]; + color[4] = color[0]; color[5] = color[0]; color[6] = ScummColors[*(lbp+1)]; color[7] = ScummColors[*(lbp+2)]; + lbp = src_line[2]; + color[8] = ScummColors[*lbp]; color[9] = color[8]; color[10] = ScummColors[*(lbp+1)]; color[11] = ScummColors[*(lbp+2)]; + lbp = src_line[3]; + color[12] = ScummColors[*lbp]; color[13] = color[12]; color[14] = ScummColors[*(lbp+1)]; color[15] = ScummColors[*(lbp+2)]; + } + + for (y = 0; y < height; y++) + { + for (x = 0; x < width; x++) + { + unsigned long product1a, product1b, product2a, product2b; + +//--------------------------------------- B0 B1 B2 B3 0 1 2 3 +// 4 5* 6 S2 -> 4 5* 6 7 +// 1 2 3 S1 8 9 10 11 +// A0 A1 A2 A3 12 13 14 15 +//-------------------------------------- + if (color[9] == color[6] && color[5] != color[10]) + { + product2b = color[9]; + product1b = product2b; + } + else if (color[5] == color[10] && color[9] != color[6]) + { + product2b = color[5]; + product1b = product2b; + } + else if (color[5] == color[10] && color[9] == color[6]) + { + int r = 0; + + r += GET_RESULT(color[6], color[5], color[8], color[13]); + r += GET_RESULT(color[6], color[5], color[4], color[1]); + r += GET_RESULT(color[6], color[5], color[14], color[11]); + r += GET_RESULT(color[6], color[5], color[2], color[7]); + + if (r > 0) + product1b = color[6]; + else if (r < 0) + product1b = color[5]; + else + product1b = INTERPOLATE(color[5], color[6]); + + product2b = product1b; + + } + else + { + if (color[6] == color[10] && color[10] == color[13] && color[9] != color[14] && color[10] != color[12]) + product2b = Q_INTERPOLATE(color[10], color[10], color[10], color[9]); + else if (color[5] == color[9] && color[9] == color[14] && color[13] != color[10] && color[9] != color[15]) + product2b = Q_INTERPOLATE(color[9], color[9], color[9], color[10]); + else + product2b = INTERPOLATE(color[9], color[10]); + + if (color[6] == color[10] && color[6] == color[1] && color[5] != color[2] && color[6] != color[0]) + product1b = Q_INTERPOLATE(color[6], color[6], color[6], color[5]); + else if (color[5] == color[9] && color[5] == color[2] && color[1] != color[6] && color[5] != color[3]) + product1b = Q_INTERPOLATE(color[6], color[5], color[5], color[5]); + else + product1b = INTERPOLATE(color[5], color[6]); + } + + if (color[5] == color[10] && color[9] != color[6] && color[4] == color[5] && color[5] != color[14]) + product2a = INTERPOLATE(color[9], color[5]); + else if (color[5] == color[8] && color[6] == color[5] && color[4] != color[9] && color[5] != color[12]) + product2a = INTERPOLATE(color[9], color[5]); + else + product2a = color[9]; + + if (color[9] == color[6] && color[5] != color[10] && color[8] == color[9] && color[9] != color[2]) + product1a = INTERPOLATE(color[9], color[5]); + else if (color[4] == color[9] && color[10] == color[9] && color[8] != color[5] && color[9] != color[0]) + product1a = INTERPOLATE(color[9], color[5]); + else + product1a = color[5]; + + if (PixelsPerMask == 2) + { + if (ScummPCMode) + { + SWAP_WORD(product1a); + SWAP_WORD(product1b); + SWAP_WORD(product2a); + SWAP_WORD(product2b); + } + *((unsigned long *) (&dst_line[0][x * 4])) = (product1a << 16) | product1b; + *((unsigned long *) (&dst_line[1][x * 4])) = (product2a << 16) | product2b; + } + else + { + *((unsigned long *) (&dst_line[0][x * 8])) = product1a; + *((unsigned long *) (&dst_line[0][x * 8 + 4])) = product1b; + *((unsigned long *) (&dst_line[1][x * 8])) = product2a; + *((unsigned long *) (&dst_line[1][x * 8 + 4])) = product2b; + } + + /* Move color matrix forward */ + color[0] = color[1]; color[4] = color[5]; color[8] = color[9]; color[12] = color[13]; + color[1] = color[2]; color[5] = color[6]; color[9] = color[10]; color[13] = color[14]; + color[2] = color[3]; color[6] = color[7]; color[10] = color[11]; color[14] = color[15]; + + if (src_x+x < BufferWidth-3) + { + x += 3; + if (PixelsPerMask == 2) + { + color[3] = ScummColors16[*(src_line[0] + x) ]; + color[7] = ScummColors16[*(src_line[1] + x) ]; + color[11] = ScummColors16[*(src_line[2] + x) ]; + color[15] = ScummColors16[*(src_line[3] + x) ]; + } + else + { + color[3] = ScummColors[*(src_line[0] + x)]; + color[7] = ScummColors[*(src_line[1] + x)]; + color[11] = ScummColors[*(src_line[2] + x)]; + color[15] = ScummColors[*(src_line[3] + x)]; + } + x -= 3; + } + } + + /* We're done with one line, so we shift the source lines up */ + src_line[0] = src_line[1]; + src_line[1] = src_line[2]; + src_line[2] = src_line[3]; + + /* Read next line */ + if (src_y + y + 3 >= BufferHeight) + src_line[3] = src_line[2]; + else + src_line[3] = src_line[2] + BufferWidth; + + /* Then shift the color matrix up */ + if (PixelsPerMask == 2) + { + byte *sbp; + sbp = src_line[0]; + color[0] = ScummColors16[*sbp]; color[1] = color[0]; color[2] = ScummColors16[ *(sbp + 1) ]; color[3] = ScummColors16[*(sbp + 2)]; + sbp = src_line[1]; + color[4] = ScummColors16[*sbp]; color[5] = color[4]; color[6] = ScummColors16[ *(sbp + 1) ]; color[7] = ScummColors16[*(sbp + 2)]; + sbp = src_line[2]; + color[8] = ScummColors16[*sbp]; color[9] = color[8]; color[10] = ScummColors16[ *(sbp + 1) ]; color[11] = ScummColors16[*(sbp + 2)]; + sbp = src_line[3]; + color[12] = ScummColors16[*sbp]; color[13] = color[12]; color[14] = ScummColors16[ *(sbp + 1) ]; color[15] = ScummColors16[*(sbp + 2)]; + + if (src_x + x > 0) + { + color[0] = ScummColors16[src_line[0][-1]]; + color[4] = ScummColors16[src_line[1][-1]]; + color[8] = ScummColors16[src_line[2][-1]]; + color[12] = ScummColors16[src_line[3][-1]]; + } + } + else + { + byte *lbp; + lbp = src_line[0]; + color[0] = ScummColors[*lbp]; color[1] = color[0]; color[2] = ScummColors[ *(lbp + 1) ]; color[3] = ScummColors[*(lbp+2)]; + lbp = src_line[1]; + color[4] = ScummColors[*lbp]; color[5] = color[4]; color[6] = ScummColors[ *(lbp + 1) ]; color[7] = ScummColors[*(lbp+2)]; + lbp = src_line[2]; + color[8] = ScummColors[*lbp]; color[9] = color[8]; color[10] = ScummColors[ *(lbp + 1) ]; color[11] = ScummColors[*(lbp+2)]; + lbp = src_line[3]; + color[12] = ScummColors[*lbp]; color[13] = color[12]; color[14] = ScummColors[ *(lbp + 1) ]; color[15] = ScummColors[*(lbp+2)]; + } + + if (src_y + y < BufferHeight - 1) + { + dst_line[0] = dst_line[1]+dest_pitch; + dst_line[1] = dst_line[0]+dest_pitch; + } + } +} + +void SuperEagleScaler::Scale(uint32 src_x, uint32 src_y, uint32 dest_x, uint32 dest_y, uint32 width, uint32 height) +{ + unsigned int x, y; + unsigned long color[12]; + byte *src; + + if (!handle) + return; + + src = (byte *)Buffer+src_y*BufferWidth+src_x; + + /* Point to the first 3 lines. */ + src_line[0] = src; + src_line[1] = src; + src_line[2] = src + BufferWidth; + src_line[3] = src + BufferWidth * 2; + + dst_line[0] = dest+dest_y*2*dest_pitch+dest_x*2*dest_bpp; + dst_line[1] = dst_line[0]+dest_pitch; + + x = 0, y = 0; + + if (PixelsPerMask == 2) + { + byte *sbp; + sbp = src_line[0]; + color[0] = ScummColors16[*sbp]; color[1] = color[0]; color[2] = color[0]; color[3] = color[0]; + color[4] = ScummColors16[*(sbp+1)]; color[5] = ScummColors16[*(sbp+2)]; + sbp = src_line[2]; + color[6] = ScummColors16[*sbp]; color[7] = color[6]; color[8] = ScummColors16[*(sbp+1)]; color[9] = ScummColors16[*(sbp+2)]; + sbp = src_line[3]; + color[10] = ScummColors16[*sbp]; color[11] = ScummColors16[*(sbp+1)]; + } + else + { + byte *lbp; + lbp = src_line[0]; + color[0] = ScummColors[*lbp]; color[1] = color[0]; color[2] = color[0]; color[3] = color[0]; + color[4] = ScummColors[*(lbp+1)]; color[5] = ScummColors[*(lbp+2)]; + lbp = src_line[2]; + color[6] = ScummColors[*lbp]; color[7] = color[6]; color[8] = ScummColors[*(lbp+1)]; color[9] = ScummColors[*(lbp+2)]; + lbp = src_line[3]; + color[10] = ScummColors[*lbp]; color[11] = ScummColors[*(lbp+1)]; + } + + for (y = 0; y < height; y++) + { + /* Todo: x = width - 2, x = width - 1 */ + + for (x = 0; x < width; x++) + { + unsigned long product1a, product1b, product2a, product2b; + +//--------------------------------------- B1 B2 0 1 +// 4 5 6 S2 -> 2 3 4 5 +// 1 2 3 S1 6 7 8 9 +// A1 A2 10 11 + + if (color[7] == color[4] && color[3] != color[8]) + { + product1b = product2a = color[7]; + + if ((color[6] == color[7]) || (color[4] == color[1])) + product1a = INTERPOLATE(color[7], INTERPOLATE(color[7], color[3])); + else + product1a = INTERPOLATE(color[3], color[4]); + + if ((color[4] == color[5]) || (color[7] == color[10])) + product2b = INTERPOLATE(color[7], INTERPOLATE(color[7], color[8])); + else + product2b = INTERPOLATE(color[7], color[8]); + } + else if (color[3] == color[8] && color[7] != color[4]) + { + product2b = product1a = color[3]; + + if ((color[0] == color[3]) || (color[5] == color[9])) + product1b = INTERPOLATE(color[3], INTERPOLATE(color[3], color[4])); + else + product1b = INTERPOLATE(color[3], color[1]); + + if ((color[8] == color[11]) || (color[2] == color[3])) + product2a = INTERPOLATE(color[3], INTERPOLATE(color[3], color[2])); + else + product2a = INTERPOLATE(color[7], color[8]); + + } + else if (color[3] == color[8] && color[7] == color[4]) + { + register int r = 0; + + r += GET_RESULT(color[4], color[3], color[6], color[10]); + r += GET_RESULT(color[4], color[3], color[2], color[0]); + r += GET_RESULT(color[4], color[3], color[11], color[9]); + r += GET_RESULT(color[4], color[3], color[1], color[5]); + + if (r > 0) + { + product1b = product2a = color[7]; + product1a = product2b = INTERPOLATE(color[3], color[4]); + } + else if (r < 0) + { + product2b = product1a = color[3]; + product1b = product2a = INTERPOLATE(color[3], color[4]); + } + else + { + product2b = product1a = color[3]; + product1b = product2a = color[7]; + } + } + else + { + product2b = product1a = INTERPOLATE(color[7], color[4]); + product2b = Q_INTERPOLATE(color[8], color[8], color[8], product2b); + product1a = Q_INTERPOLATE(color[3], color[3], color[3], product1a); + + product2a = product1b = INTERPOLATE(color[3], color[8]); + product2a = Q_INTERPOLATE(color[7], color[7], color[7], product2a); + product1b = Q_INTERPOLATE(color[4], color[4], color[4], product1b); + } + + if (PixelsPerMask == 2) + { + if (ScummPCMode) + { + SWAP_WORD(product1a); + SWAP_WORD(product1b); + SWAP_WORD(product2a); + SWAP_WORD(product2b); + } + *((unsigned long *) (&dst_line[0][x * 4])) = (product1a << 16) | product1b; + *((unsigned long *) (&dst_line[1][x * 4])) = (product2a << 16) | product2b; + } + else + { + *((unsigned long *) (&dst_line[0][x * 8])) = product1a; + *((unsigned long *) (&dst_line[0][x * 8 + 4])) = product1b; + *((unsigned long *) (&dst_line[1][x * 8])) = product2a; + *((unsigned long *) (&dst_line[1][x * 8 + 4])) = product2b; + } + + /* Move color matrix forward */ + color[0] = color[1]; + color[2] = color[3]; color[3] = color[4]; color[4] = color[5]; + color[6] = color[7]; color[7] = color[8]; color[8] = color[9]; + color[10] = color[11]; + + if (src_x+x < BufferWidth - 2) + { + x += 2; + if (PixelsPerMask == 2) + { + color[1] = ScummColors16[ *(src_line[0] + x) ]; + if (src_x+x < BufferWidth-1) + { + color[5] = ScummColors16[*(src_line[1]+x+1)]; + color[9] = ScummColors16[*(src_line[2]+x+1)]; + } + color[11] = ScummColors16[*(src_line[3]+x)]; + } + else + { + color[1] = ScummColors[*(src_line[0]+x)]; + if (src_x+x < BufferWidth-1) + { + color[5] = ScummColors[*(src_line[1]+x+1)]; + color[9] = ScummColors[ *(src_line[2]+x+1)]; + } + color[11] = ScummColors[*(src_line[3]+x)]; + } + x -= 2; + } + } + + /* We're done with one line, so we shift the source lines up */ + src_line[0] = src_line[1]; + src_line[1] = src_line[2]; + src_line[2] = src_line[3]; + + /* Read next line */ + if (src_y+y+3 >= BufferHeight) + src_line[3] = src_line[2]; + else + src_line[3] = src_line[2] + BufferWidth; + + /* Then shift the color matrix up */ + if (PixelsPerMask == 2) + { + byte *sbp; + sbp = src_line[0]; + color[0] = ScummColors16[*sbp]; color[1] = ScummColors16[*(sbp+1)]; + sbp = src_line[1]; + color[2] = ScummColors16[*sbp]; color[3] = color[2]; color[4] = ScummColors16[*(sbp+1)]; color[5] = ScummColors16[*(sbp+2)]; + sbp = src_line[2]; + color[6] = ScummColors16[*sbp]; color[7] = color[6]; color[8] = ScummColors16[*(sbp+1)]; color[9] = ScummColors16[*(sbp+2)]; + sbp = src_line[3]; + color[10] = ScummColors16[*sbp]; color[11] = ScummColors16[*(sbp+1)]; + } + else + { + byte *lbp; + lbp = src_line[0]; + color[0] = ScummColors[*lbp]; color[1] = ScummColors[*(lbp+1)]; + lbp = src_line[1]; + color[2] = ScummColors[*lbp]; color[3] = color[2]; color[4] = ScummColors[*(lbp+1)]; color[5] = ScummColors[*(lbp+2)]; + lbp = src_line[2]; + color[6] = ScummColors[*lbp]; color[7] = color[6]; color[8] = ScummColors[*(lbp+1)]; color[9] = ScummColors[*(lbp+2)]; + lbp = src_line[3]; + color[10] = ScummColors[*lbp]; color[11] = ScummColors[*(lbp+1)]; + } + + + if (src_y + y < BufferHeight - 1) + { + dst_line[0] = dst_line[1]+dest_pitch; + dst_line[1] = dst_line[0]+dest_pitch; + } + } +} + +void AdvMame2xScaler::Scale(uint32 src_x, uint32 src_y, uint32 dest_x, uint32 dest_y, uint32 width, uint32 height) +{ + if (!handle) + return; + + byte *src = (byte *)Buffer+src_y*BufferWidth+src_x; + + src_line[0] = src; + src_line[1] = src; + src_line[2] = src + BufferWidth; + + dst_line[0] = dest+dest_y*2*dest_pitch+dest_x*2*dest_bpp; + dst_line[1] = dst_line[0]+dest_pitch; + + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + uint32 B, D, E, F, H; + + if (PixelsPerMask == 2) + { + // short A = *(src + i - nextlineSrc - 1); + B = ScummColors16[src_line[0][x]]; + // short C = *(src + i - nextlineSrc + 1); + D = ScummColors16[src_line[1][x-1]]; + E = ScummColors16[src_line[1][x]]; + F = ScummColors16[src_line[1][x+1]]; + // short G = *(src + i + nextlineSrc - 1); + H = ScummColors16[src_line[2][x]]; + // short I = *(src + i + nextlineSrc + 1); + } + else + { + // short A = *(src + i - nextlineSrc - 1); + B = ScummColors[src_line[0][x]]; + // short C = *(src + i - nextlineSrc + 1); + D = ScummColors[src_line[1][x-1]]; + E = ScummColors[src_line[1][x]]; + F = ScummColors[src_line[1][x+1]]; + // short G = *(src + i + nextlineSrc - 1); + H = ScummColors[src_line[2][x]]; + // short I = *(src + i + nextlineSrc + 1); + } + + + if (PixelsPerMask == 2) + { + if (ScummPCMode) + { + SWAP_WORD(B); + SWAP_WORD(D); + SWAP_WORD(E); + SWAP_WORD(F); + SWAP_WORD(H); + } + *((unsigned long *) (&dst_line[0][x * 4])) = ((D == B && B != F && D != H ? D : E) << 16) | (B == F && B != D && F != H ? F : E); + *((unsigned long *) (&dst_line[1][x * 4])) = ((D == H && D != B && H != F ? D : E) << 16) | (H == F && D != H && B != F ? F : E); + } + else + { + *((unsigned long *) (&dst_line[0][x * 8])) = D == B && B != F && D != H ? D : E; + *((unsigned long *) (&dst_line[0][x * 8 + 4])) = B == F && B != D && F != H ? F : E; + *((unsigned long *) (&dst_line[1][x * 8])) = D == H && D != B && H != F ? D : E; + *((unsigned long *) (&dst_line[1][x * 8 + 4])) = H == F && D != H && B != F ? F : E; + } + } + + src_line[0] = src_line[1]; + src_line[1] = src_line[2]; + if (src_y+y+2 >= BufferHeight) + src_line[2] = src_line[1]; + else + src_line[2] = src_line[1] + BufferWidth; + + if (src_y+y < BufferHeight-1) + { + dst_line[0] = dst_line[1]+dest_pitch; + dst_line[1] = dst_line[0]+dest_pitch; + } + } +} + +void PointScaler::Scale(uint32 src_x, uint32 src_y, uint32 dest_x, uint32 dest_y, uint32 width, uint32 height) +{ + byte *src; + uint32 color; + uint32 r, g, b; + uint32 x, y; + + if (!handle) + return; + + src = (byte *)Buffer+src_y*BufferWidth+src_x; + + dst_line[0] = dest+dest_y*2*dest_pitch+dest_x*2*dest_bpp; + dst_line[1] = dst_line[0]+dest_pitch; + + for (y = 0; y < height; y++) + { + for (x = 0; x < width; x++) + { + r = (ScummColors[*(src+x)] >> 16) & 0xff; + g = (ScummColors[*(src+x)] >> 8) & 0xff; + b = ScummColors[*(src+x)] & 0xff; + + color = MakeColor(dest_pixfmt, r, g, b); + if (PixelsPerMask == 2) + { + if (ScummPCMode) + SWAP_WORD(color); + + *((unsigned long *) (&dst_line[0][x * 4])) = (color << 16) | color; + *((unsigned long *) (&dst_line[1][x * 4])) = (color << 16) | color; + } + else + { + *((unsigned long *) (&dst_line[0][x * 8])) = color; + *((unsigned long *) (&dst_line[0][x * 8 + 4])) = color; + *((unsigned long *) (&dst_line[1][x * 8])) = color; + *((unsigned long *) (&dst_line[1][x * 8 + 4])) = color; + } + } + + src += BufferWidth; + + if (src_y+y < BufferHeight-1) + { + dst_line[0] = dst_line[1]+dest_pitch; + dst_line[1] = dst_line[0]+dest_pitch; + } + } +} + +SCALERTYPE MorphOSScaler::FindByName(const char *ScalerName) +{ + int scaler = 0; + + while (ScummScalers[scaler].gs_Name) + { + if (!stricmp(ScalerName, ScummScalers[scaler].gs_Name)) + return ScummScalers[scaler].gs_Type; + scaler++; + } + + 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 ST_INVALID; +} + +SCALERTYPE MorphOSScaler::FindByIndex(int index) +{ + if (index >= 0 && index < 10 && ScummScalers[index].gs_Name) + return ScummScalers[index].gs_Type; + + return ST_INVALID; +} + +const char *MorphOSScaler::GetParamName(SCALERTYPE type) +{ + int scaler = 0; + + while (ScummScalers[scaler].gs_Name) + { + if (ScummScalers[scaler].gs_Type == type) + return ScummScalers[scaler].gs_ParamName; + scaler++; + } + + return NULL; +} + diff --git a/morphos/morphos_scaler.h b/morphos/morphos_scaler.h new file mode 100644 index 0000000000..c23de6cb8a --- /dev/null +++ b/morphos/morphos_scaler.h @@ -0,0 +1,93 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2002 The ScummVM project + * + * 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. + * + * $Header$ + */ + +#ifndef MORPHOS_MORPHOSSCALER_H +#define MORPHOS_MORPHOSSCALER_H + +#include <graphics/gfx.h> + +typedef enum { ST_INVALID = 0, ST_NONE, ST_POINT, ST_ADVMAME2X, ST_SUPEREAGLE, ST_SUPER2XSAI } SCALERTYPE; + +class MorphOSScaler +{ + public: + MorphOSScaler(APTR buffer, int width, int height, ULONG *col_table, UWORD *col_table16, BitMap *bmap); + virtual ~MorphOSScaler(); + + bool Prepare(BitMap *render_bmap); + void Finish(); + + virtual void Scale(uint32 src_x, uint32 src_y, uint32 dest_x, uint32 dest_y, uint32 width, uint32 height) = 0; + + static MorphOSScaler *Create(SCALERTYPE st, APTR buffer, int width, int height, ULONG *col_table, UWORD *col_table16, BitMap *bmap); + + static SCALERTYPE FindByName(const char *ScalerName); + static SCALERTYPE FindByIndex(int index); + static const char *GetParamName(SCALERTYPE type); + + protected: + struct GfxScaler + { + STRPTR gs_Name; + STRPTR gs_ParamName; + SCALERTYPE gs_Type; + }; + + static GfxScaler ScummScalers[11]; + + static uint32 MakeColor(int pixfmt, int r, int g, int b); + + byte *dest; + uint32 dest_bpp; + uint32 dest_pitch; + uint32 dest_pixfmt; + APTR handle; + + uint32 colorMask; + uint32 lowPixelMask; + uint32 qcolorMask; + uint32 qlowpixelMask; + uint32 redblueMask; + uint32 greenMask; + int PixelsPerMask; + byte *src_line[4]; + byte *dst_line[2]; + bool ScummPCMode; + + APTR Buffer; + int BufferWidth; + int BufferHeight; + ULONG *ScummColors; + USHORT *ScummColors16; +}; + +#define DECLARE_SCALER(scaler_name) class scaler_name ## Scaler : public MorphOSScaler \ + { public: scaler_name ## Scaler(APTR buffer, int width, int height, ULONG *col_table, UWORD *col_table16, BitMap *bmap) : MorphOSScaler(buffer, width, height, col_table, col_table16, bmap) {} \ + void Scale(uint32 src_x, uint32 src_y, uint32 dest_x, uint32 dest_y, uint32 width, uint32 height); \ + }; + + +DECLARE_SCALER(Point) +DECLARE_SCALER(AdvMame2x) +DECLARE_SCALER(SuperEagle) +DECLARE_SCALER(Super2xSaI) + +#endif + diff --git a/morphos/morphos_sound.cpp b/morphos/morphos_sound.cpp index 64ed693049..0585b8708b 100644 --- a/morphos/morphos_sound.cpp +++ b/morphos/morphos_sound.cpp @@ -38,80 +38,80 @@ #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 BYTE ahiDevice = -1; - UBYTE ahiUnit = AHI_DEFAULT_UNIT; -static char *ahiBuf[ 2 ] = { NULL, NULL }; - -static struct MsgPort *ScummMidiPort = NULL; - struct IOMidiRequest *ScummMidiRequest = NULL; -static struct MsgPort *MusicTimerMsgPort = NULL; - struct timerequest *MusicTimerIORequest = NULL; - -bool init_morphos_music( ULONG MidiUnit ) +SignalSemaphore ScummMusicThreadRunning; +SignalSemaphore ScummSoundThreadRunning; + +static MsgPort *ahiPort = NULL; +static AHIRequest *ahiReq[2] = { NULL, NULL }; +static UWORD ahiCurBuf = 0; +static bool ahiReqSent[2] = { false, false }; +static BYTE ahiDevice = -1; + UBYTE ahiUnit = AHI_DEFAULT_UNIT; +static char *ahiBuf[2] = { NULL, NULL }; + +static MsgPort *ScummMidiPort = NULL; + IOMidiRequest *ScummMidiRequest = NULL; +static MsgPort *MusicTimerMsgPort = NULL; + timerequest *MusicTimerIORequest = NULL; + +bool init_morphos_music(ULONG MidiUnit) { - if( ScummMusicDriver && !stricmp( ScummMusicDriver, "-eamidi" ) ) // just as ugly as the line below ... + if (ScummMusicDriver && !stricmp(ScummMusicDriver, "-eamidi")) // just as ugly as the line below ... { MidiUnit = ScummMidiUnit; // Ugly fix, but ... ScummMidiPort = CreateMsgPort(); - if( ScummMidiPort ) + if (ScummMidiPort) { - ScummMidiRequest = (struct IOMidiRequest *)CreateIORequest( ScummMidiPort, sizeof( struct IOMidiRequest ) ); - if( ScummMidiRequest ) + ScummMidiRequest = (IOMidiRequest *) CreateIORequest(ScummMidiPort, sizeof (IOMidiRequest)); + if (ScummMidiRequest) { ScummMidiRequest->amr_Version = 2; - if( OpenDevice( "amidi.device", MidiUnit, (struct IORequest *)ScummMidiRequest, AMIDIF_MIDISERVER ) ) + if (OpenDevice("amidi.device", MidiUnit, (IORequest *) ScummMidiRequest, AMIDIF_MIDISERVER)) { - DeleteIORequest( (struct IORequest *)ScummMidiRequest ); - DeleteMsgPort( ScummMidiPort ); + DeleteIORequest((IORequest *) ScummMidiRequest); + DeleteMsgPort(ScummMidiPort); ScummMidiRequest = NULL; ScummMidiPort = NULL; } } else { - DeleteMsgPort( ScummMidiPort ); + DeleteMsgPort(ScummMidiPort); ScummMidiPort = NULL; } } - if( !ScummMidiRequest ) + if (!ScummMidiRequest) { - warning( "Could not open AMidi - music will not play" ); + warning("Could not open AMidi - music will not play"); return false; } } MusicTimerMsgPort = CreateMsgPort(); - if( MusicTimerMsgPort ) + if (MusicTimerMsgPort) { - MusicTimerIORequest = (struct timerequest *)CreateIORequest( MusicTimerMsgPort, sizeof( struct timerequest ) ); - if( MusicTimerIORequest ) + MusicTimerIORequest = (timerequest *) CreateIORequest(MusicTimerMsgPort, sizeof (timerequest)); + if (MusicTimerIORequest) { - if( OpenDevice( "timer.device", UNIT_MICROHZ, (struct IORequest *)MusicTimerIORequest, 0 ) ) + if (OpenDevice("timer.device", UNIT_MICROHZ, (IORequest *) MusicTimerIORequest, 0)) { - DeleteIORequest( (struct IORequest *)MusicTimerIORequest ); - DeleteMsgPort( MusicTimerMsgPort ); + DeleteIORequest((IORequest *) MusicTimerIORequest); + DeleteMsgPort(MusicTimerMsgPort); MusicTimerIORequest = NULL; MusicTimerMsgPort = NULL; } } else { - DeleteMsgPort( MusicTimerMsgPort ); + DeleteMsgPort(MusicTimerMsgPort); MusicTimerMsgPort = NULL; } } - if( !MusicTimerIORequest ) + if (!MusicTimerIORequest) { - warning( "Could not open timer device - music will not play" ); + warning("Could not open timer device - music will not play"); return false; } @@ -121,74 +121,74 @@ bool init_morphos_music( ULONG MidiUnit ) void exit_morphos_music() { - if( ScummMidiRequest ) + if (ScummMidiRequest) { - CloseDevice( (struct IORequest *)ScummMidiRequest ); - DeleteIORequest( (struct IORequest *)ScummMidiRequest ); - DeleteMsgPort( ScummMidiPort ); + CloseDevice((IORequest *) ScummMidiRequest); + DeleteIORequest((IORequest *) ScummMidiRequest); + DeleteMsgPort(ScummMidiPort); } - if( MusicTimerIORequest ) + if (MusicTimerIORequest) { - CloseDevice( (struct IORequest *)MusicTimerIORequest ); - DeleteIORequest( (struct IORequest *)MusicTimerIORequest ); - DeleteMsgPort( MusicTimerMsgPort ); + CloseDevice((IORequest *) MusicTimerIORequest); + DeleteIORequest((IORequest *) MusicTimerIORequest); + DeleteMsgPort(MusicTimerMsgPort); } } static bool init_morphos_sound() { - if( !(ahiPort = CreateMsgPort()) ) + if (!(ahiPort = CreateMsgPort())) return false; - if( !(ahiReq[ 0 ] = (struct AHIRequest *)CreateIORequest( ahiPort, sizeof( struct AHIRequest ) )) ) + if (!(ahiReq[0] = (AHIRequest *) CreateIORequest(ahiPort, sizeof (AHIRequest)))) { - DeleteMsgPort( ahiPort ); + DeleteMsgPort(ahiPort); ahiPort = NULL; return false; } - if( !(ahiReq[ 1 ] = (struct AHIRequest *)AllocVec( sizeof( struct AHIRequest ), MEMF_ANY | MEMF_PUBLIC )) ) + if (!(ahiReq[1] = (AHIRequest *) AllocVec(sizeof (AHIRequest), MEMF_PUBLIC))) { - DeleteIORequest( ahiReq[ 0 ] ); - DeleteMsgPort( ahiPort ); - ahiReq[ 0 ] = NULL; + DeleteIORequest(ahiReq[0]); + DeleteMsgPort(ahiPort); + ahiReq[0] = NULL; ahiPort = NULL; return false; } - if( !(ahiBuf[ 0 ] = (char *)AllocVec( 2*AHI_BUF_SIZE, MEMF_ANY | MEMF_PUBLIC )) ) + if (!(ahiBuf[0] = (char *) AllocVec(2*AHI_BUF_SIZE, MEMF_PUBLIC))) { - FreeVec( ahiReq[ 1 ] ); - DeleteIORequest( ahiReq[ 0 ] ); - DeleteMsgPort( ahiPort ); - ahiReq[ 0 ] = NULL; - ahiReq[ 1 ] = NULL; + FreeVec(ahiReq[1]); + DeleteIORequest(ahiReq[0]); + DeleteMsgPort(ahiPort); + ahiReq[0] = NULL; + ahiReq[1] = NULL; ahiPort = NULL; return false; } - ahiBuf[ 1 ] = &ahiBuf[ 0 ][ AHI_BUF_SIZE ]; + ahiBuf[1] = &ahiBuf[0][AHI_BUF_SIZE]; - ahiReq[ 0 ]->ahir_Version = 4; - if( ahiDevice = OpenDevice( AHINAME, 0, (struct IORequest *)ahiReq[ 0 ], 0 ) ) + ahiReq[0]->ahir_Version = 4; + if (ahiDevice = OpenDevice(AHINAME, 0, (IORequest *) ahiReq[0], 0)) { - FreeVec( ahiBuf[ 0 ] ); - FreeVec( ahiReq[ 1 ] ); - DeleteIORequest( ahiReq[ 0 ] ); - DeleteMsgPort( ahiPort ); - ahiBuf[ 0 ] = NULL; - ahiReq[ 0 ] = NULL; - ahiReq[ 1 ] = NULL; + FreeVec(ahiBuf[0]); + FreeVec(ahiReq[1]); + DeleteIORequest(ahiReq[0]); + DeleteMsgPort(ahiPort); + ahiBuf[0] = NULL; + ahiReq[0] = NULL; + ahiReq[1] = NULL; ahiPort = NULL; return false; } - CopyMem( ahiReq[ 0 ], ahiReq[ 1 ], sizeof( struct AHIRequest ) ); + CopyMem(ahiReq[0], ahiReq[1], sizeof (AHIRequest)); ahiCurBuf = 0; - ahiReqSent[ 0 ] = FALSE; - ahiReqSent[ 1 ] = FALSE; + ahiReqSent[0] = FALSE; + ahiReqSent[1] = FALSE; return true; } @@ -196,89 +196,89 @@ static bool init_morphos_sound() static void exit_morphos_sound() { - if( ahiReq[ 1 ] ) - FreeVec( ahiReq[ 1 ] ); + if (ahiReq[1]) + FreeVec(ahiReq[1]); - if( ahiReq[ 0 ] ) + if (ahiReq[0]) { - CloseDevice( (struct IORequest *)ahiReq[ 0 ] ); - DeleteIORequest( ahiReq[ 0 ] ); + CloseDevice((IORequest *) ahiReq[0]); + DeleteIORequest(ahiReq[0]); } - if( ahiBuf[ 0 ] ) - FreeVec( (APTR)ahiBuf[ 0 ] ); + if (ahiBuf[0]) + FreeVec((APTR) ahiBuf[0]); - if( ahiPort ) - DeleteMsgPort( ahiPort ); + if (ahiPort) + DeleteMsgPort(ahiPort); } -int morphos_sound_thread( OSystem_MorphOS *syst, ULONG SampleType ) +int morphos_sound_thread(OSystem_MorphOS *syst, ULONG SampleType) { ULONG signals; bool initialized; - ObtainSemaphore( &ScummSoundThreadRunning ); + ObtainSemaphore(&ScummSoundThreadRunning); initialized = init_morphos_sound(); - if( !initialized ) + if (!initialized) { - warning( "Sound could not be initialized. The game may hang at some point (press Ctrl-z then)." ); - Wait( SIGBREAKF_CTRL_C ); + warning("Sound could not be initialized. The game may hang at some point (press Ctrl-z then)."); + Wait(SIGBREAKF_CTRL_C); } else { - for(;;) + for (;;) { - while( !ahiReqSent[ ahiCurBuf ] || CheckIO( (struct IORequest *)ahiReq[ ahiCurBuf ] ) ) + while (!ahiReqSent[ahiCurBuf] || CheckIO((IORequest *) ahiReq[ahiCurBuf])) { - struct AHIRequest *req = ahiReq[ ahiCurBuf ]; + AHIRequest *req = ahiReq[ahiCurBuf]; UWORD ahiOtherBuf = !ahiCurBuf; - if( ahiReqSent[ ahiCurBuf ] ) - WaitIO( (struct IORequest *)req ); + if (ahiReqSent[ahiCurBuf]) + WaitIO((IORequest *) req); - syst->fill_sound( (byte *)ahiBuf[ ahiCurBuf ], AHI_BUF_SIZE ); + 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_Data = ahiBuf[ahiCurBuf]; req->ahir_Std.io_Length = AHI_BUF_SIZE; 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 ); + req->ahir_Link = (ahiReqSent[ahiOtherBuf] && !CheckIO((IORequest *) ahiReq[ahiOtherBuf])) ? ahiReq[ahiOtherBuf] : NULL; + SendIO((IORequest *)req); - ahiReqSent[ ahiCurBuf ] = true; + ahiReqSent[ahiCurBuf] = true; ahiCurBuf = ahiOtherBuf; } - signals = Wait( SIGBREAKF_CTRL_C | (1 << ahiPort->mp_SigBit) ); + signals = Wait(SIGBREAKF_CTRL_C | (1 << ahiPort->mp_SigBit)); - if( signals & SIGBREAKF_CTRL_C ) + if (signals & SIGBREAKF_CTRL_C) break; } - if( ahiReqSent[ ahiCurBuf ] ) + if (ahiReqSent[ahiCurBuf]) { - AbortIO( (struct IORequest *)ahiReq[ ahiCurBuf ] ); - WaitIO ( (struct IORequest *)ahiReq[ ahiCurBuf ] ); - ahiReqSent[ ahiCurBuf ] = false; + AbortIO((IORequest *) ahiReq[ahiCurBuf]); + WaitIO((IORequest *) ahiReq[ahiCurBuf]); + ahiReqSent[ahiCurBuf] = false; } - if( ahiReqSent[ !ahiCurBuf ] ) + if (ahiReqSent[!ahiCurBuf]) { - AbortIO( (struct IORequest *)ahiReq[ !ahiCurBuf ] ); - WaitIO ( (struct IORequest *)ahiReq[ !ahiCurBuf ] ); - ahiReqSent[ !ahiCurBuf ] = false; + AbortIO((IORequest *) ahiReq[!ahiCurBuf]); + WaitIO((IORequest *) ahiReq[!ahiCurBuf]); + ahiReqSent[!ahiCurBuf] = false; } } exit_morphos_sound(); - ReleaseSemaphore( &ScummSoundThreadRunning ); - RemTask( NULL ); + ReleaseSemaphore(&ScummSoundThreadRunning); + RemTask(NULL); return 0; } diff --git a/morphos/morphos_start.cpp b/morphos/morphos_start.cpp index ea013fb53a..d3305cbe14 100644 --- a/morphos/morphos_start.cpp +++ b/morphos/morphos_start.cpp @@ -37,14 +37,15 @@ #include "stdafx.h" #include "scumm.h" #include "morphos.h" +#include "morphos_scaler.h" -extern "C" struct WBStartup *_WBenchMsg; +extern "C" WBStartup *_WBenchMsg; // For command line parsing static STRPTR usageTemplate = "STORY/A,DATAPATH/K,WBWINDOW/S,SCALER/K,AMIGA/S,MIDIUNIT/K/N,MUSIC/K,MUSICVOL/K/N,SFXVOL/K/N,TEMPO/K/N,TALKSPEED/K/N,NOSUBTITLES=NST/S"; -typedef enum { USG_STORY = 0, USG_DATAPATH, USG_WBWINDOW, USG_SCALER, USG_AMIGA, USG_MIDIUNIT, USG_MUSIC, USG_MUSICVOL, USG_SFXVOL, USG_TEMPO, USG_TALKSPEED, USG_NOSUBTITLES } usageFields; -static LONG args[ 13 ] = { (ULONG)NULL, (ULONG)NULL, FALSE, (ULONG)NULL, false, (ULONG)NULL, (ULONG)NULL, (ULONG)NULL, (ULONG)NULL, (ULONG)NULL, (ULONG)NULL, false }; -static struct RDArgs *ScummArgs = NULL; +typedef enum { USG_STORY = 0, USG_DATAPATH, USG_WBWINDOW, USG_SCALER, USG_AMIGA, USG_MIDIUNIT, USG_MUSIC, USG_MUSICVOL, USG_SFXVOL, USG_TEMPO, USG_TALKSPEED, USG_NOSUBTITLES } usageFields; +static LONG args[13] = { (ULONG) NULL, (ULONG) NULL, FALSE, (ULONG) NULL, false, (ULONG) NULL, (ULONG) NULL, (ULONG) NULL, (ULONG) NULL, (ULONG) NULL, (ULONG) NULL, false }; +static RDArgs *ScummArgs = NULL; static char*ScummStory = NULL; static char*ScummPath = NULL; @@ -54,184 +55,184 @@ static LONG ScummMidiVolume = 0; static LONG ScummMidiTempo = 0; static LONG ScummSfxVolume = 0; static LONG ScummTalkSpeed = 0; -static OSystem_MorphOS::SCALERTYPE ScummGfxScaler = OSystem_MorphOS::ST_INVALID; +static SCALERTYPE ScummGfxScaler = ST_INVALID; static BPTR OrigDirLock = 0; -struct Library *CDDABase = NULL; -struct Device *TimerBase = NULL; +Library *CDDABase = NULL; +Device *TimerBase = NULL; OSystem_MorphOS *TheSystem = NULL; -OSystem *OSystem_MorphOS_create( int game_id, int gfx_mode, bool full_screen) +OSystem *OSystem_MorphOS_create(int game_id, int gfx_mode, bool full_screen) { - if( TheSystem ) + if (TheSystem) delete TheSystem; - OSystem_MorphOS::SCALERTYPE gfx_scaler = OSystem_MorphOS::ST_NONE; - switch( gfx_mode ) + SCALERTYPE gfx_scaler = ST_NONE; + switch (gfx_mode) { case GFX_DOUBLESIZE: - gfx_scaler = OSystem_MorphOS::ST_POINT; + gfx_scaler = ST_POINT; break; case GFX_SUPEREAGLE: - gfx_scaler = OSystem_MorphOS::ST_SUPEREAGLE; + gfx_scaler = ST_SUPEREAGLE; break; case GFX_SUPER2XSAI: - gfx_scaler = OSystem_MorphOS::ST_SUPER2XSAI; + gfx_scaler = ST_SUPER2XSAI; break; } - TheSystem = OSystem_MorphOS::create( game_id, gfx_scaler, full_screen ); + TheSystem = OSystem_MorphOS::create(game_id, gfx_scaler, full_screen); return TheSystem; } void close_resources() { - if( TheSystem ) + if (TheSystem) delete TheSystem; - if( g_scumm ) + if (g_scumm) delete g_scumm; - if( ScummPath ) - FreeVec( ScummPath ); + if (ScummPath) + FreeVec(ScummPath); - if( ScummStory ) - FreeVec( ScummStory ); + if (ScummStory) + FreeVec(ScummStory); - if( ScummArgs ) - FreeArgs( ScummArgs ); + if (ScummArgs) + FreeArgs(ScummArgs); - if( OrigDirLock ) - CurrentDir( OrigDirLock ); + if (OrigDirLock) + CurrentDir(OrigDirLock); - if( CDDABase ) - CloseLibrary( CDDABase ); + if (CDDABase) + CloseLibrary(CDDABase); } -static STRPTR FindMusicDriver( STRPTR argval ) +static STRPTR FindMusicDriver(STRPTR argval) { - if( !stricmp( argval, "off" ) ) return "-enull"; - if( !stricmp( argval, "midi" ) ) return "-eamidi"; - if( !stricmp( argval, "midiemu" ) ) return "-emidiemu"; - if( !stricmp( argval, "adlib" ) ) return "-eadlib"; + if (!stricmp(argval, "off")) return "-enull"; + if (!stricmp(argval, "midi")) return "-eamidi"; + if (!stricmp(argval, "midiemu")) return "-emidiemu"; + if (!stricmp(argval, "adlib")) return "-eadlib"; - error( "No such music driver supported. Possible values are off, Midi, MidiEmu and Adlib." ); + error("No such music driver supported. Possible values are off, Midi, MidiEmu and Adlib."); return NULL; } -static void ReadToolTypes( struct WBArg *OfFile ) +static void ReadToolTypes(WBArg *OfFile) { - struct DiskObject *dobj; - char *ToolValue; - char IconPath[ 256 ]; + DiskObject *dobj; + char *ToolValue; + char IconPath[256]; - NameFromLock( OfFile->wa_Lock, IconPath, 256 ); - AddPart( IconPath, OfFile->wa_Name, 256 ); + NameFromLock(OfFile->wa_Lock, IconPath, 256); + AddPart(IconPath, OfFile->wa_Name, 256); - dobj = GetDiskObject( IconPath ); - if( dobj == NULL ) + dobj = GetDiskObject(IconPath); + if (dobj == NULL) return; - if( ToolValue = (char *)FindToolType( dobj->do_ToolTypes, "STORY" ) ) + if (ToolValue = (char *) FindToolType(dobj->do_ToolTypes, "STORY")) { - if( ScummStory ) - FreeVec( ScummStory ); - ScummStory = (char *)AllocVec( strlen( ToolValue )+1, MEMF_PUBLIC ); - strcpy( ScummStory, ToolValue ); + if (ScummStory) + FreeVec(ScummStory); + ScummStory = (char *) AllocVec(strlen(ToolValue)+1, MEMF_PUBLIC); + strcpy(ScummStory, ToolValue); } - if( ToolValue = (char *)FindToolType( dobj->do_ToolTypes, "DATAPATH" ) ) + 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 (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 (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 (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 (ToolValue = (char *) FindToolType(dobj->do_ToolTypes, "SCALER")) { - if( (ScummGfxScaler = OSystem_MorphOS::FindScaler( ToolValue )) == OSystem_MorphOS::ST_INVALID ) + if ((ScummGfxScaler = MorphOSScaler::FindByName(ToolValue)) == ST_INVALID) { - FreeDiskObject( dobj ); - exit( 1 ); + FreeDiskObject(dobj); + exit(1); } } - if( ToolValue = (char *)FindToolType( dobj->do_ToolTypes, "MUSIC" ) ) + if (ToolValue = (char *) FindToolType(dobj->do_ToolTypes, "MUSIC")) { - if( !(ScummMusicDriver = FindMusicDriver( ToolValue )) ) + if (!(ScummMusicDriver = FindMusicDriver(ToolValue))) { - FreeDiskObject( dobj ); - exit( 1 ); + FreeDiskObject(dobj); + exit(1); } - args[ USG_MUSIC ] = (ULONG)&ScummMusicDriver; + args[USG_MUSIC] = (ULONG) &ScummMusicDriver; } - if( ToolValue = (char *)FindToolType( dobj->do_ToolTypes, "MIDIUNIT" ) ) - ScummMidiUnit = atoi( ToolValue ); + if( ToolValue = (char *) FindToolType(dobj->do_ToolTypes, "MIDIUNIT")) + ScummMidiUnit = atoi(ToolValue); - if( ToolValue = (char *)FindToolType( dobj->do_ToolTypes, "MUSICVOL" ) ) + if( ToolValue = (char *) FindToolType(dobj->do_ToolTypes, "MUSICVOL")) { - int vol = atoi( ToolValue ); - if( vol >= 0 && vol <= 100 ) + int vol = atoi(ToolValue); + if (vol >= 0 && vol <= 100) { ScummMidiVolume = vol; - args[ USG_MUSICVOL ] = (ULONG)&ScummMidiVolume; + args[USG_MUSICVOL] = (ULONG) &ScummMidiVolume; } } - if( ToolValue = (char *)FindToolType( dobj->do_ToolTypes, "SFXVOL" ) ) + if (ToolValue = (char *) FindToolType(dobj->do_ToolTypes, "SFXVOL")) { - int vol = atoi( ToolValue ); - if( vol >= 0 && vol <= 255 ) + int vol = atoi(ToolValue); + if (vol >= 0 && vol <= 255) { ScummSfxVolume = vol; - args[ USG_SFXVOL ] = (ULONG)&ScummSfxVolume; + args[USG_SFXVOL] = (ULONG) &ScummSfxVolume; } } - if( ToolValue = (char *)FindToolType( dobj->do_ToolTypes, "TEMPO" ) ) + if (ToolValue = (char *) FindToolType(dobj->do_ToolTypes, "TEMPO")) { - ScummMidiTempo = atoi( ToolValue ); - args[ USG_TEMPO ] = (ULONG)&ScummMidiTempo; + ScummMidiTempo = atoi(ToolValue); + args[USG_TEMPO] = (ULONG) &ScummMidiTempo; } - if( ToolValue = (char *)FindToolType( dobj->do_ToolTypes, "TALKSPEED" ) ) + if (ToolValue = (char *) FindToolType(dobj->do_ToolTypes, "TALKSPEED")) { - ScummTalkSpeed = atoi( ToolValue ); - args[ USG_TALKSPEED ] = (ULONG)&ScummMidiTempo; + ScummTalkSpeed = atoi(ToolValue); + args[USG_TALKSPEED] = (ULONG) &ScummMidiTempo; } - if( ToolValue = (char *)FindToolType( dobj->do_ToolTypes, "SUBTITLES" ) ) + 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; + if (MatchToolValue(ToolValue, "YES")) + args[USG_NOSUBTITLES] = FALSE; + else if (MatchToolValue(ToolValue, "NO")) + args[USG_NOSUBTITLES] = TRUE; } - if( ToolValue = (char *)FindToolType( dobj->do_ToolTypes, "AMIGA" ) ) + if (ToolValue = (char *) FindToolType(dobj->do_ToolTypes, "AMIGA")) { - if( MatchToolValue( ToolValue, "YES" ) ) - args[ USG_AMIGA ] = FALSE; - else if( MatchToolValue( ToolValue, "NO" ) ) - args[ USG_AMIGA ] = TRUE; + if (MatchToolValue(ToolValue, "YES")) + args[USG_AMIGA] = FALSE; + else if (MatchToolValue(ToolValue, "NO")) + args[USG_AMIGA] = TRUE; } - FreeDiskObject( dobj ); + FreeDiskObject(dobj); } #undef main @@ -240,120 +241,119 @@ int main() { int delta; int last_time, new_time; - char *argv[ 20 ]; - char musicvol[ 6 ], sfxvol[ 6 ], talkspeed[ 12 ], tempo[ 12 ], scaler[ 14 ]; - char *SVMScalers[] = { "", "normal", "2x", "advmame2x", "supereagle", "super2xsai" }; + char *argv[20]; + char musicvol[6], sfxvol[6], talkspeed[12], tempo[12], scaler[14]; int argc = 0; - InitSemaphore( &ScummSoundThreadRunning ); - InitSemaphore( &ScummMusicThreadRunning ); + InitSemaphore(&ScummSoundThreadRunning); + InitSemaphore(&ScummMusicThreadRunning); g_scumm = NULL; - atexit( &close_resources ); + atexit(&close_resources); - if( _WBenchMsg == NULL ) + if (_WBenchMsg == NULL) { /* Parse the command line here */ - ScummArgs = ReadArgs( usageTemplate, args, NULL ); - if( ScummArgs == NULL ) + ScummArgs = ReadArgs(usageTemplate, args, NULL); + if (ScummArgs == NULL) { - puts( "Error in command line - type \"ScummVM ?\" for usage.\n" ); - exit( 1 ); + puts("Error in command line - type \"ScummVM ?\" for usage."); + exit(1); } - if( args[ USG_STORY ] ) + if (args[USG_STORY]) { - ScummStory = (char *)AllocVec( strlen( (char *)args[ USG_STORY ] )+1, MEMF_PUBLIC ); - strcpy( ScummStory, (char *)args[ USG_STORY ] ); + ScummStory = (char *) AllocVec(strlen((char *) args[USG_STORY])+1, MEMF_PUBLIC); + strcpy(ScummStory, (char *) args[USG_STORY]); } - if( args[ USG_DATAPATH ] ) + if (args[USG_DATAPATH]) { - ScummPath = (char *)AllocVec( strlen( (char *)args[ USG_DATAPATH ] )+4, MEMF_PUBLIC ); - strcpy( ScummPath, "-p" ); - strcat( ScummPath, (char *)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 (args[USG_SCALER]) { - if( (ScummGfxScaler = OSystem_MorphOS::FindScaler( (char *)args[ USG_SCALER ] )) == OSystem_MorphOS::ST_INVALID ) - exit( 1 ); + if ((ScummGfxScaler = MorphOSScaler::FindByName((char *) args[USG_SCALER])) == ST_INVALID) + exit(1); } - if( args[ USG_MUSIC ] ) + if (args[USG_MUSIC]) { - if( !(ScummMusicDriver = FindMusicDriver( (char *)args[ USG_MUSIC ] )) ) - exit( 1 ); + if (!(ScummMusicDriver = FindMusicDriver((char *) args[USG_MUSIC]))) + exit(1); } - if( args[ USG_MIDIUNIT ] ) - ScummMidiUnit = *((LONG *)args[ USG_MIDIUNIT ]); + if (args[USG_MIDIUNIT]) + ScummMidiUnit = *((LONG *) args[USG_MIDIUNIT]); - if( args[ USG_TEMPO ] ) - ScummMidiTempo = *((LONG *)args[ USG_TEMPO ]); + if (args[USG_TEMPO]) + ScummMidiTempo = *((LONG *) args[USG_TEMPO]); - if( args[ USG_MUSICVOL ] ) - ScummMidiVolume = *((LONG *)args[ USG_MUSICVOL ]); + if (args[USG_MUSICVOL]) + ScummMidiVolume = *((LONG *) args[USG_MUSICVOL]); - if( args[ USG_SFXVOL ] ) - ScummSfxVolume = *((LONG *)args[ USG_SFXVOL ]); + if (args[USG_SFXVOL]) + ScummSfxVolume = *((LONG *) args[USG_SFXVOL]); - if( args[ USG_TALKSPEED ] ) - ScummTalkSpeed = *((LONG *)args[ USG_TALKSPEED ]); + if (args[USG_TALKSPEED]) + ScummTalkSpeed = *((LONG *) args[USG_TALKSPEED]); } else { /* We've been started from Workbench */ - ReadToolTypes( &_WBenchMsg->sm_ArgList[ 0 ] ); - if( _WBenchMsg->sm_NumArgs > 1 ) + ReadToolTypes(&_WBenchMsg->sm_ArgList[0]); + if (_WBenchMsg->sm_NumArgs > 1) { - ReadToolTypes( &_WBenchMsg->sm_ArgList[ 1 ] ); - OrigDirLock = CurrentDir( _WBenchMsg->sm_ArgList[ 1 ].wa_Lock ); + ReadToolTypes(&_WBenchMsg->sm_ArgList[1]); + OrigDirLock = CurrentDir(_WBenchMsg->sm_ArgList[1].wa_Lock); } } - if( ScummPath ) + if (ScummPath) { - char c = ScummPath[ strlen( ScummPath )-1 ]; - if( c != '/' && c != ':' ) - strcat( ScummPath, "/" ); + char c = ScummPath[strlen(ScummPath)-1]; + if (c != '/' && c != ':') + strcat(ScummPath, "/"); } - argv[ argc++ ] = "ScummVM"; - if( ScummPath ) argv[ argc++ ] = ScummPath; - if( !args[ USG_WBWINDOW ] ) argv[ argc++ ] = "-f"; - if( args[ USG_NOSUBTITLES ] ) argv[ argc++ ] = "-n"; - if( args[ USG_AMIGA ] ) argv[ argc++ ] = "-a"; - if( args[ USG_MUSIC ] ) argv[ argc++ ] = ScummMusicDriver; - if( ScummGfxScaler != OSystem_MorphOS::ST_INVALID ) + argv[argc++] = "ScummVM"; + if (ScummPath) argv[argc++] = ScummPath; + if (!args[ USG_WBWINDOW ]) argv[argc++] = "-f"; + if (args[ USG_NOSUBTITLES ]) argv[argc++] = "-n"; + if (args[ USG_AMIGA ]) argv[argc++] = "-a"; + if (args[ USG_MUSIC ]) argv[argc++] = ScummMusicDriver; + if (ScummGfxScaler != ST_INVALID) { - sprintf( scaler, "-g%s", SVMScalers[ (int)ScummGfxScaler ] ); - argv[ argc++ ] = scaler; + sprintf(scaler, "-g%s", MorphOSScaler::GetParamName(ScummGfxScaler)); + argv[argc++] = scaler; } else - argv[ argc++ ] = "-gsuper2xsai"; - if( args[ USG_MUSICVOL ] && ScummMidiVolume >= 0 && ScummMidiVolume <= 100 ) + argv[argc++] = "-gsuper2xsai"; + if (args[USG_MUSICVOL] && ScummMidiVolume >= 0 && ScummMidiVolume <= 100) { - sprintf( musicvol, "-m%d", ScummMidiVolume ); - argv[ argc++ ] = musicvol; + sprintf(musicvol, "-m%d", ScummMidiVolume); + argv[argc++] = musicvol; } - if( args[ USG_SFXVOL ] && ScummSfxVolume >= 0 && ScummSfxVolume <= 255 ) + if (args[USG_SFXVOL] && ScummSfxVolume >= 0 && ScummSfxVolume <= 255) { - sprintf( sfxvol, "-s%d", ScummSfxVolume ); - argv[ argc++ ] = sfxvol; + sprintf(sfxvol, "-s%d", ScummSfxVolume); + argv[argc++] = sfxvol; } - if( args[ USG_TEMPO ] && ScummMidiTempo > 0 ) + if (args[USG_TEMPO] && ScummMidiTempo > 0) { - sprintf( tempo, "-t%lx", ScummMidiTempo ); - argv[ argc++ ] = tempo; + sprintf(tempo, "-t%lx", ScummMidiTempo); + argv[argc++] = tempo; } - if( args[ USG_TALKSPEED ] && ScummTalkSpeed >= 0 && ScummTalkSpeed <= 255 ) + if (args[USG_TALKSPEED] && ScummTalkSpeed >= 0 && ScummTalkSpeed <= 255) { - sprintf( talkspeed, "-y%d", ScummTalkSpeed ); - argv[ argc++ ] = talkspeed; + sprintf(talkspeed, "-y%d", ScummTalkSpeed); + argv[argc++] = talkspeed; } - argv[ argc++ ] = ScummStory; + argv[argc++] = ScummStory; - return morphos_main( argc, argv ); + return morphos_main(argc, argv); } diff --git a/morphos/morphos_timer.cpp b/morphos/morphos_timer.cpp index ccec0b7468..d106b9a1a9 100644 --- a/morphos/morphos_timer.cpp +++ b/morphos/morphos_timer.cpp @@ -152,22 +152,24 @@ void Timer::TimerService(Timer *this_ptr) if (tmsg->tsm_Interval > 1000) unit = UNIT_VBLANK; - OSystem_MorphOS::OpenATimer(&timer_slots[timers].ts_Port, (IORequest **) &timer_slots[timers].ts_IORequest, unit); - timer_slots[timers].ts_Callback = tmsg->tsm_Callback; - timer_slots[timers].ts_Interval = tmsg->tsm_Interval; - timer_slots[timers].ts_SignalBit = 1 << timer_slots[timers].ts_Port->mp_SigBit; - - signal_mask |= timer_slots[timers].ts_SignalBit; - timer_bits |= timer_slots[timers].ts_SignalBit; - - timerequest *req = timer_slots[timers].ts_IORequest; - interval = timer_slots[timers].ts_Interval; - req->tr_node.io_Command = TR_ADDREQUEST; - req->tr_time.tv_secs = interval/1000; - req->tr_time.tv_micro = (interval%1000)*1000; - SendIO(req); - - timers++; + if (OSystem_MorphOS::OpenATimer(&timer_slots[timers].ts_Port, (IORequest **) &timer_slots[timers].ts_IORequest, unit)) + { + timer_slots[timers].ts_Callback = tmsg->tsm_Callback; + timer_slots[timers].ts_Interval = tmsg->tsm_Interval; + timer_slots[timers].ts_SignalBit = 1 << timer_slots[timers].ts_Port->mp_SigBit; + + signal_mask |= timer_slots[timers].ts_SignalBit; + timer_bits |= timer_slots[timers].ts_SignalBit; + + timerequest *req = timer_slots[timers].ts_IORequest; + interval = timer_slots[timers].ts_Interval; + req->tr_node.io_Command = TR_ADDREQUEST; + req->tr_time.tv_secs = interval/1000; + req->tr_time.tv_micro = (interval%1000)*1000; + SendIO(req); + + timers++; + } } break; @@ -216,7 +218,7 @@ void Timer::TimerService(Timer *this_ptr) (*timer_slots[t].ts_Callback)(interval); GetSysTime(&end_callback); SubTime(&end_callback, &start_callback); - interval -= end_callback.tv_sec*1000+end_callback.tv_micro/1000+20; + interval -= end_callback.tv_sec*1000+end_callback.tv_micro/1000+40; req->tr_node.io_Command = TR_ADDREQUEST; req->tr_time.tv_secs = interval/1000; |