diff options
Diffstat (limited to 'morphos/morphos.cpp')
-rw-r--r-- | morphos/morphos.cpp | 1717 |
1 files changed, 628 insertions, 1089 deletions
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); } |