diff options
Diffstat (limited to 'backends/morphos/morphos.cpp')
-rw-r--r-- | backends/morphos/morphos.cpp | 1645 |
1 files changed, 0 insertions, 1645 deletions
diff --git a/backends/morphos/morphos.cpp b/backends/morphos/morphos.cpp deleted file mode 100644 index 889976afc4..0000000000 --- a/backends/morphos/morphos.cpp +++ /dev/null @@ -1,1645 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2002 Rüdiger Hanke - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * MorphOS interface - * - * $URL$ - * $Id$ - * - */ - -#include "common/stdafx.h" -#include "base/engine.h" -#include "common/util.h" -#include "scumm/scumm.h" - -#include <exec/types.h> -#include <exec/memory.h> -#include <exec/libraries.h> -#include <exec/semaphores.h> -#include <devices/ahi.h> -#include <devices/rawkeycodes.h> -#include <dos/dostags.h> -#include <intuition/screens.h> -#include <cybergraphics/cybergraphics.h> -#include <devices/input.h> -#include <devices/inputevent.h> -#include <intuition/intuition.h> - -#include <clib/alib_protos.h> -#include <proto/exec.h> -#include <proto/dos.h> -#include <proto/graphics.h> -#include <proto/intuition.h> -#include <proto/keymap.h> -#include <proto/timer.h> -#include <proto/cdda.h> -#include <proto/cybergraphics.h> - -#include <time.h> - -#include "morphos.h" -#include "morphos_sound.h" -#include "morphos_scaler.h" - -static TagItem PlayTags[] = { { CDPA_StartTrack, 1 }, - { CDPA_StartFrame, 0 }, - { CDPA_EndTrack, 1 }, - { CDPA_EndFrame, 0 }, - { CDPA_Loops, 1 }, - { TAG_DONE, 0 } - }; - -static CONST_STRPTR MonkeyCDIDs[] = { "ID2500496F035CBC", "ID250040360345DB", NULL }; -static CONST_STRPTR LoomCDIDs[] = { NULL }; -static CONST_STRPTR MonkeyNames[] = { "Monkey1CD", "Madness", NULL }; -static CONST_STRPTR LoomNames[] = { "LoomCD", NULL }; - -#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(SCALERTYPE gfx_scaler, bool full_screen) -{ - OSystem_MorphOS *syst = new OSystem_MorphOS(gfx_scaler, full_screen); - - if (!syst || !syst->Initialise()) - { - delete syst; - error("Failed to create system object. Exiting."); - } - - return syst; -} - -OSystem_MorphOS::OSystem_MorphOS(SCALERTYPE gfx_mode, bool full_screen) -{ - ScummScreen = NULL; - ScummWindow = NULL; - ScummBuffer = NULL; - ScummScreenBuffer[0] = NULL; - ScummScreenBuffer[1] = NULL; - ScummRenderTo = NULL; - ScummNoCursor = NULL; - ScummSoundThread = NULL; - ScummWinX = -1; - ScummWinY = -1; - ScummDefaultMouse = false; - ScummOrigMouse = false; - ScummShakePos = 0; - ScummScaler = gfx_mode; - ScummScale = (gfx_mode == ST_NONE) ? 0 : 1; - ScummDepth = 0; - Scumm16ColFmt16 = false; - ScummScrWidth = 0; - ScummScrHeight = 0; - ScreenChanged = false; - DirtyBlocks = NULL; - BlockColors = NULL; - UpdateRects = 0; - Scaler = NULL; - FullScreenMode = full_screen; - CDrive = NULL; - CDDATrackOffset = 0; - strcpy(ScummWndTitle, "ScummVM MorphOS"); - TimerMsgPort = NULL; - TimerIORequest = NULL; - InputMsgPort = NULL; - InputIORequest = NULL; - ThreadPort = NULL; - OvlCMap = NULL; - OvlBitMap = NULL; - OvlSavedBuffer = NULL; - TimerBase = NULL; - ScummNoCursor = NULL; - UpdateRegion = NULL; - NewUpdateRegion = NULL; - MouseImage = NULL; -} - -bool OSystem_MorphOS::Initialise() -{ - OpenATimer(&TimerMsgPort, (IORequest **) &TimerIORequest, UNIT_MICROHZ); - - if ((InputMsgPort = CreateMsgPort())) - { - if ((InputIORequest = (IOStdReq*) CreateIORequest(InputMsgPort, sizeof (IOStdReq)))) - { - if ((OpenDevice("input.device", NULL, (IORequest *) InputIORequest, NULL))) - { - DeleteIORequest(InputIORequest); - DeleteMsgPort(InputMsgPort); - InputIORequest = NULL; - InputMsgPort = NULL; - } - } - else - { - DeleteMsgPort(InputMsgPort); - InputMsgPort = NULL; - } - } - - if (!InputIORequest) - { - warning("input.device could not be opened"); - return false; - } - - ThreadPort = CreateMsgPort(); - if (!ThreadPort) - { - warning("Unable to create a message port"); - return false; - } - - OvlCMap = GetColorMap(256); - - InitSemaphore(&CritSec); - - TimerBase = (Library*) TimerIORequest->tr_node.io_Device; - ScummNoCursor = (UWORD *) AllocVec(16, MEMF_CLEAR); - UpdateRegion = NewRegion(); - NewUpdateRegion = NewRegion(); - if (!UpdateRegion || !NewUpdateRegion) - { - warning("Could not create region for screen update"); - return false; - } - if (!OvlCMap) - { - warning("Could not allocate overlay color map"); - return false; - } - if (!ScummNoCursor) - { - warning("Could not allocate empty cursor image"); - return false; - } - - return true; -} - -OSystem_MorphOS::~OSystem_MorphOS() -{ - if (DirtyBlocks) - { - FreeVec(DirtyBlocks); - - for (int b = 0; b < BLOCKS_X*BLOCKS_Y; b++) - FreeVec(BlockColors[b]); - FreeVec(BlockColors); - } - - if (OvlCMap) - FreeColorMap(OvlCMap); - - delete Scaler; - - if (UpdateRegion) - DisposeRegion(UpdateRegion); - - if (NewUpdateRegion) - DisposeRegion(NewUpdateRegion); - - if (ThreadPort) - DeleteMsgPort(ThreadPort); - - if (CDrive && CDDABase) - { - CDDA_Stop(CDrive); - CDDA_ReleaseDrive(CDrive); - } - - if (InputIORequest) - { - CloseDevice((IORequest *) InputIORequest); - DeleteIORequest((IORequest *) InputIORequest); - } - - if (InputMsgPort) - DeleteMsgPort(InputMsgPort); - - if (TimerIORequest) - { - CloseDevice((IORequest *) TimerIORequest); - DeleteIORequest((IORequest *) TimerIORequest); - } - - if (TimerMsgPort) - DeleteMsgPort(TimerMsgPort); - - if (ScummNoCursor) - FreeVec(ScummNoCursor); - - if (ScummBuffer) - FreeVec(ScummBuffer); - - if (OvlSavedBuffer) - FreeVec(OvlSavedBuffer); - - if (ScummRenderTo && !ScummScreen) - FreeBitMap(ScummRenderTo); - - if (OvlBitMap) - FreeVec(OvlBitMap); - - if (ScummWindow) - CloseWindow(ScummWindow); - - if (ScummScreen) - { - if (ScummScreenBuffer[0]) - FreeScreenBuffer(ScummScreen, ScummScreenBuffer[0]); - if( ScummScreenBuffer[1] ) - FreeScreenBuffer(ScummScreen, ScummScreenBuffer[1]); - CloseScreen(ScummScreen); - } -} - -bool OSystem_MorphOS::OpenATimer(MsgPort **port, IORequest **req, ULONG unit, bool required) -{ - *req = NULL; - const char *err_msg = NULL; - - *port = CreateMsgPort(); - if (*port) - { - *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"; - - if (err_msg) - { - if (required) - error(err_msg); - warning(err_msg); - } - - return *req != NULL; -} - -uint32 OSystem_MorphOS::getMillis() -{ - int ticks = clock(); - ticks *= (1000/CLOCKS_PER_SEC); - return ticks; -} - -void OSystem_MorphOS::delayMillis(uint msecs) -{ -/* TimerIORequest->tr_node.io_Command = TR_ADDREQUEST; - TimerIORequest->tr_time.tv_secs = 0; - TimerIORequest->tr_time.tv_micro = msecs*1000; - DoIO((IORequest *) TimerIORequest);*/ - TimeDelay(UNIT_MICROHZ, 0, msecs*1000); -} - -void OSystem_MorphOS::setTimerCallback(TimerProc callback, int timer) -{ - warning("setTimerCallback() unexpectedly called"); -} - -OSystem::MutexRef OSystem_MorphOS::createMutex() -{ - SignalSemaphore *sem = (SignalSemaphore *) AllocVec(sizeof (SignalSemaphore), MEMF_PUBLIC); - - if (sem) - InitSemaphore(sem); - - return (MutexRef)sem; -} - -void OSystem_MorphOS::lockMutex(MutexRef mutex) -{ - ObtainSemaphore((SignalSemaphore *) mutex); -} - -void OSystem_MorphOS::unlockMutex(MutexRef mutex) -{ - ReleaseSemaphore((SignalSemaphore *)mutex); -} - -void OSystem_MorphOS::deleteMutex(MutexRef mutex) -{ - FreeVec(mutex); -} - -uint32 OSystem_MorphOS::property(int param, Property *value) -{ - AUTO_LOCK - - switch (param) - { - case PROP_GET_FULLSCREEN: - return ScummScreen != NULL; - - case PROP_TOGGLE_FULLSCREEN: - CreateScreen(CSDSPTYPE_TOGGLE); - return 1; - - case PROP_SET_WINDOW_CAPTION: - sprintf(ScummWndTitle, "ScummVM MorphOS - %s", value->caption); - if (ScummWindow) - SetWindowTitles(ScummWindow, ScummWndTitle, ScummWndTitle); - return 1; - - case PROP_OPEN_CD: - { - CONST_STRPTR *ids = NULL, *names = NULL; - - if (g_scumm) - GameID = g_scumm->_gameId; - - switch (GameID) - { - case GID_MONKEY: - case GID_MONKEY_SEGA: - ids = MonkeyCDIDs; - names = MonkeyNames; - break; - - case GID_LOOM256: - ids = LoomCDIDs; - names = LoomNames; - break; - } - - if (!CDDABase) CDDABase = OpenLibrary("cdda.library", 2); - if (CDDABase) - { - CDrive = NULL; - if (ids) - { - int i = 0; - - while (ids[i] && !CDrive) - { - TagItem FindCDTags[] = { { CDFA_CDID, (ULONG) ids[i] }, - { TAG_DONE, 0 } - }; - CDrive = CDDA_FindNextDriveA(NULL, FindCDTags); - i++; - } - } - - if (!CDrive && names) - { - int i = 0; - - while (names[i] && !CDrive) - { - TagItem FindCDTags[] = { { CDFA_VolumeName, (ULONG) names[i] }, - { TAG_DONE, 0 } - }; - CDrive = CDDA_FindNextDriveA(NULL, FindCDTags); - i++; - } - } - - if (CDrive) - { - if (!CDDA_ObtainDriveA(CDrive, CDDA_SHARED_ACCESS, NULL)) - { - CDrive = NULL; - warning("Failed to obtain CD drive - music will not play"); - } - else if (GameID == GID_LOOM256) - { - // Offset correction *may* be required - CDS_TrackInfo ti = { sizeof (CDS_TrackInfo) }; - - if (CDDA_GetTrackInfo(CDrive, 1, 0, &ti)) - CDDATrackOffset = ti.ti_TrackStart.tm_Format.tm_Frame-22650; - } - } - else - warning( "Could not find game CD inserted in CD-ROM drive - cd audio will not play" ); - } - else - warning( "Failed to open cdda.library - cd audio will not play" ); - break; - } - - case PROP_GET_SAMPLE_RATE: - return SAMPLES_PER_SEC; - } - - return 0; -} - -void OSystem_MorphOS::playCD(int track, int num_loops, int start_frame, int duration) -{ - if (CDrive && 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 = (duration == 0) ? track+1 : track; - PlayTags[3].ti_Data = duration ? start_frame+duration : 0; - PlayTags[4].ti_Data = (num_loops == 0) ? 1 : num_loops; - CDDA_PlayA(CDrive, PlayTags); - } -} - -void OSystem_MorphOS::stopCD() -{ - if (CDrive) - CDDA_Stop(CDrive); -} - -bool OSystem_MorphOS::pollCD() -{ - ULONG status; - - if (CDrive == NULL) - return false; - - CDDA_GetAttr(CDDA_Status, CDrive, &status); - return status == CDDA_Status_Busy; -} - -void OSystem_MorphOS::updateCD() -{ -} - -void OSystem_MorphOS::quit() -{ - int num_threads = 0; - - if (ScummSoundThread) - { - num_threads++; - Signal((Task *) ScummSoundThread, SIGBREAKF_CTRL_C); - ScummSoundThread = NULL; - } - - // TODO: this code could probably greatly simplified now that there is - // only one thread left... - while (num_threads > 0) - { - Message* msg; - - WaitPort(ThreadPort); - while (msg = GetMsg(ThreadPort)) - num_threads--; - } - - exit(0); -} - -#define CVT8TO32(col) ((col<<24) | (col<<16) | (col<<8) | col) - -void OSystem_MorphOS::setPalette(const byte *colors, uint start, uint num) -{ - const byte *data = colors; - UWORD changed_colors[256]; - UWORD num_changed = 0; - - for (uint i = start; i != start+num; i++) - { - 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; - } - - 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::CreateScreen(CS_DSPTYPE dspType) -{ - LONG mode = INVALID_ID; - int depths[] = { 8, 32, 16, 15, 0 }; - int i; - Screen *wb = NULL; - - if (dspType != CSDSPTYPE_KEEP) - FullScreenMode = (dspType == CSDSPTYPE_FULLSCREEN) || (dspType == CSDSPTYPE_TOGGLE && !FullScreenMode); - - if (ScummRenderTo && !ScummScreen) - FreeBitMap(ScummRenderTo); - ScummRenderTo = NULL; - - if (ScummWindow) - { - if (ScummScreen == NULL) - { - ScummWinX = ScummWindow->LeftEdge; - ScummWinY = ScummWindow->TopEdge; - } - CloseWindow (ScummWindow); - ScummWindow = NULL; - } - - if (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) - { - 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]; - - if (mode == INVALID_ID) - error("Could not find suitable screenmode"); - - ScummScreen = OpenScreenTags(NULL, SA_AutoScroll, TRUE, - SA_Depth, ScummDepth, - SA_Width, STDSCREENWIDTH, - SA_Height, STDSCREENHEIGHT, - SA_DisplayID, mode, - SA_ShowTitle, FALSE, - SA_Type, CUSTOMSCREEN, - SA_Title, "ScummVM MorphOS", - TAG_DONE - ); - - if (ScummScreen == NULL) - error("Failed to open screen"); - - LONG RealDepth = GetBitMapAttr(&ScummScreen->BitMap, BMA_DEPTH); - if (RealDepth != ScummDepth) - { - 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; - ScummPaintBuffer = 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 - 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); - - if (ScummDepth == 8) - { - 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)); - } - } - } - else - { - wb = LockPubScreen(NULL); - if (wb == NULL) - error("Could not lock default public screen"); - - ScreenToFront(wb); - } - - 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, - WA_Activate, TRUE, - WA_Title, wb ? ScummWndTitle : NULL, - WA_ScreenTitle, wb ? ScummWndTitle : NULL, - WA_Borderless, FullScreenMode, - WA_CloseGadget, !FullScreenMode, - WA_DepthGadget, !FullScreenMode, - WA_DragBar, !FullScreenMode, - WA_ReportMouse, TRUE, - WA_RMBTrap, TRUE, - WA_IDCMP, IDCMP_RAWKEY | - IDCMP_MOUSEMOVE | - IDCMP_CLOSEWINDOW | - IDCMP_MOUSEBUTTONS, - WA_CustomScreen, FullScreenMode ? (ULONG)ScummScreen : (ULONG)wb, - TAG_DONE - ); - - if (wb) - UnlockPubScreen(NULL, wb); - - if (ScummWindow == NULL) - error("Failed to open window"); - - if (!ScummDefaultMouse) - { - SetPointer(ScummWindow, ScummNoCursor, 1, 1, 0, 0); - ScummOrigMouse = false; - } - - if (ScummScreen == NULL) - { - ScummDepth = GetCyberMapAttr(ScummWindow->RPort->BitMap, CYBRMATTR_DEPTH); - if (ScummDepth == 8) - error("Default public screen must be 15 bit or higher if you want to play in window mode"); - - ScummRenderTo = AllocBitMap(ScummScrWidth, ScummScrHeight, ScummDepth, BMF_MINPLANES, ScummWindow->RPort->BitMap); - if (ScummRenderTo == NULL) - error("Failed to allocate bitmap"); - } - - 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); - } - - if (OvlBitMap) - FreeVec(OvlBitMap); - - OvlBitMap = AllocVec(ScummBufferWidth*ScummBufferHeight*3, MEMF_PUBLIC | MEMF_CLEAR); - if (OvlBitMap == NULL) - error("Failed to allocated bitmap for overlay"); - - if (Scaler) - { - delete Scaler; - Scaler = NULL; - } - - if (ScummScale) - { - 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); - } - } - - AddUpdateRect(0, 0, ScummBufferWidth, ScummBufferHeight); -} - -void OSystem_MorphOS::SwitchScalerTo(SCALERTYPE newScaler) -{ - if (newScaler == ST_NONE && ScummScale != 0) - { - if (Scaler) - { - delete Scaler; - Scaler = NULL; - } - ScummScale = 0; - ScummScaler = ST_NONE; - CreateScreen(ScummScreen ? CSDSPTYPE_FULLSCREEN : CSDSPTYPE_WINDOWED); - } - else - { - if (ScummScale == 0) - { - ScummScale = 1; - ScummScaler = newScaler; - CreateScreen(ScummScreen ? CSDSPTYPE_FULLSCREEN : CSDSPTYPE_WINDOWED); - } - 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::pollEvent(Event &event) -{ - IntuiMessage *ScummMsg; - - ScummMsg = (IntuiMessage *) GetMsg(ScummWindow->UserPort); - if (ScummMsg) - { - switch (ScummMsg->Class) - { - case IDCMP_RAWKEY: - { - InputEvent FakedIEvent; - char charbuf; - int qual = 0; - - memset(&FakedIEvent, 0, sizeof (InputEvent)); - FakedIEvent.ie_Class = IECLASS_RAWKEY; - FakedIEvent.ie_Code = ScummMsg->Code; - - if (ScummMsg->Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT)) - qual |= KBD_ALT; - if (ScummMsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)) - qual |= KBD_SHIFT; - if (ScummMsg->Qualifier & IEQUALIFIER_CONTROL) - qual |= KBD_CTRL; - event.kbd.flags = qual; - - event.type = (ScummMsg->Code & IECODE_UP_PREFIX) ? EVENT_KEYUP : EVENT_KEYDOWN; - ScummMsg->Code &= ~IECODE_UP_PREFIX; - - if (ScummMsg->Code >= RAWKEY_F1 && ScummMsg->Code <= RAWKEY_F10) - { - /* - * Function key - */ - event.kbd.ascii = (ScummMsg->Code-RAWKEY_F1)+315; - event.kbd.keycode = 0; - } - else if (ScummMsg->Code == RAWKEY_F11 || ScummMsg->Code == RAWKEY_F12) - { - /* - * Function key on PC keyboard - */ - event.kbd.ascii = (ScummMsg->Code == RAWKEY_F11) ? 325 : 326; - event.kbd.keycode = 0; - } - else if (ScummMsg->Code == NM_WHEEL_UP || ScummMsg->Code == NM_WHEEL_DOWN) - { - /* - * Wheelmouse event - */ - event.type = (ScummMsg->Code == NM_WHEEL_UP) ? EVENT_WHEELUP : EVENT_WHEELDOWN; - } - else if (MapRawKey(&FakedIEvent, &charbuf, 1, NULL) == 1) - { - if (qual == KBD_CTRL && charbuf == 'z') - { - event.type = EVENT_QUIT; - break; - } - else if (qual == KBD_ALT) - { - if (charbuf >= '0' && charbuf <= '9') - { - SCALERTYPE new_scaler = MorphOSScaler::FindByIndex(charbuf-'0'); - ReplyMsg((Message *) ScummMsg); - if (new_scaler != ST_INVALID) - SwitchScalerTo(new_scaler); - return false; - } - else if (charbuf == 'x') - { - event.type = EVENT_QUIT; - break; - } - else if (charbuf == 0x0d) - { - ReplyMsg((Message *) ScummMsg); - CreateScreen(CSDSPTYPE_TOGGLE); - return false; - } - } - - event.kbd.ascii = charbuf; - event.kbd.keycode = charbuf; - } - break; - } - - case IDCMP_MOUSEMOVE: - { - LONG newx, newy; - - newx = (ScummMsg->MouseX-ScummWindow->BorderLeft) >> ScummScale; - newy = (ScummMsg->MouseY-ScummWindow->BorderTop) >> ScummScale; - - if (!FullScreenMode && !ScummDefaultMouse) - { - if (newx < 0 || newx > (LONG) ScummBufferWidth || - newy < 0 || newy > (LONG) ScummBufferHeight - ) - { - if (!ScummOrigMouse) - { - ScummOrigMouse = true; - ClearPointer(ScummWindow); - } - } - else if (ScummOrigMouse) - { - ScummOrigMouse = false; - SetPointer(ScummWindow, ScummNoCursor, 1, 1, 0, 0); - } - } - else if (FullScreenMode) - newy = newy <? (ScummScrHeight >> ScummScale)-2; - - event.type = EVENT_MOUSEMOVE; - event.mouse.x = newx; - event.mouse.y = newy; - set_mouse_pos(event.mouse.x, event.mouse.y); - break; - } - - case IDCMP_MOUSEBUTTONS: - { - int newx, newy; - - newx = (ScummMsg->MouseX-ScummWindow->BorderLeft) >> ScummScale; - newy = (ScummMsg->MouseY-ScummWindow->BorderTop) >> ScummScale; - - switch (ScummMsg->Code) - { - case SELECTDOWN: - event.type = EVENT_LBUTTONDOWN; - break; - - case SELECTUP: - event.type = EVENT_LBUTTONUP; - break; - - case MENUDOWN: - event.type = EVENT_RBUTTONDOWN; - break; - - case MENUUP: - event.type = EVENT_RBUTTONUP; - break; - - default: - ReplyMsg((Message *)ScummMsg); - return false; - } - event.mouse.x = newx; - event.mouse.y = newy; - break; - } - - case IDCMP_CLOSEWINDOW: - event.type = EVENT_QUIT; - break; - } - - if (ScummMsg) - ReplyMsg((Message *) ScummMsg); - - return true; - } - - return false; -} - -void OSystem_MorphOS::warpMouse(int x, int y) -{ - if (InputIORequest) - { - InputEvent* FakeIE; - IEPointerPixel* NewPixel; - - /* - * Fake a mousemove input event - */ - if ((FakeIE = (InputEvent*) AllocVec(sizeof (InputEvent), MEMF_PUBLIC))) - { - if ((NewPixel = (IEPointerPixel*) AllocVec(sizeof (IEPointerPixel), MEMF_PUBLIC))) - { - NewPixel->iepp_Screen = ScummWindow->WScreen; - NewPixel->iepp_Position.X = (x << ScummScale) + ScummWindow->LeftEdge + ScummWindow->BorderLeft; - NewPixel->iepp_Position.Y = (y << ScummScale) + ScummWindow->TopEdge + ScummWindow->BorderTop; - - FakeIE->ie_EventAddress = NewPixel; - FakeIE->ie_NextEvent = NULL; - FakeIE->ie_Class = IECLASS_NEWPOINTERPOS; - FakeIE->ie_SubClass = IESUBCLASS_PIXEL; - FakeIE->ie_Code = IECODE_NOBUTTON; - FakeIE->ie_Qualifier = NULL; - - InputIORequest->io_Data = FakeIE; - InputIORequest->io_Length = sizeof (InputEvent); - InputIORequest->io_Command = IND_WRITEEVENT; - DoIO((IORequest *) InputIORequest); - - FreeVec(NewPixel); - } - FreeVec(FakeIE); - } - } -} - -void OSystem_MorphOS::setShakePos(int shake_pos) -{ - ScummShakePos = shake_pos; - AddUpdateRect(0, 0, ScummBufferWidth, ScummBufferHeight); -} - -#define MOUSE_INTERSECTS(x, y, w, h) \ - (!((MouseOldX+MouseOldWidth <= x ) || (MouseOldX >= x+w) || \ - (MouseOldY+MouseOldHeight <= y) || (MouseOldY >= y+h))) - -/* Copy part of bitmap */ -void OSystem_MorphOS::copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h) -{ - byte *dst; - - 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; } - - if (w <= 0 || h <= 0) - return; - - AUTO_LOCK - - if (MouseDrawn) - { - if (MOUSE_INTERSECTS(x, y, w, h)) - UndrawMouse(); - } - - AddUpdateRect(x, y, w, h); - - dst = (byte *)ScummBuffer+y*ScummBufferWidth + x; - if (DirtyBlocks) - { - 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++) - { - for (cx = 0; cx < w; cx++) - { - UWORD old_pixel = *dst; - UWORD src_pixel = *src++; - if (old_pixel != src_pixel) - { - *dst++ = src_pixel; - block_cols[old_pixel]--; - block_cols[src_pixel]++; - } - else - dst++; - if (--next_block == 0) - { - block++; - block_cols = BlockColors[block]; - next_block = BLOCKSIZE_X; - } - } - if (--next_y_block == 0) - { - line_block += BLOCKS_X; - next_y_block = BLOCKSIZE_Y; - } - block = line_block; - block_cols = BlockColors[block]; - next_block = start_block; - dst += ScummBufferWidth-w; - src += pitch-w; - } - } - else - { - do - { - memcpy(dst, src, w); - dst += ScummBufferWidth; - src += pitch; - } while (--h); - } -} - -bool OSystem_MorphOS::AddUpdateRect(WORD x, WORD y, WORD w, WORD h) -{ - if (UpdateRects > 25) - return false; - - 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 false; - - if (++UpdateRects > 25) - { - x = 0; y = 0; - w = ScummBufferWidth; h = ScummBufferHeight; - } - - Rectangle update_rect = { x, y, x+w, y+h }; - OrRectRegion(NewUpdateRegion, &update_rect); - ScreenChanged = true; - - return true; -} - -void OSystem_MorphOS::updateScreen() -{ - AUTO_LOCK - - DrawMouse(); - - if (!ScreenChanged) - return; - - OrRegionRegion(NewUpdateRegion, UpdateRegion); - - if (ScummShakePos) - { - RastPort rp; - - InitRastPort(&rp); - rp.BitMap = ScummRenderTo; - - uint32 src_y = 0; - uint32 dest_y = 0; - if (ScummShakePos < 0) - src_y = -ScummShakePos; - else - dest_y = ScummShakePos; - - if (!ScummScale) - { - 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(); - } - - 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; - - InitRastPort(&rp); - rp.BitMap = ScummRenderTo; - - int32 src_x, src_y; - int32 src_w, src_h; - int32 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; - } - } - else - { - int32 src_x, src_y; - int32 src_w, src_h; - int32 reg_x, reg_y; - RegionRectangle *update_rect = UpdateRegion->RegionRectangle; - - reg_x = UpdateRegion->bounds.MinX; - reg_y = UpdateRegion->bounds.MinY; - - 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) - { - while (!ChangeScreenBuffer(ScummScreen, ScummScreenBuffer[ScummPaintBuffer])); - ScummPaintBuffer = !ScummPaintBuffer; - ScummRenderTo = ScummScreenBuffer[ScummPaintBuffer]->sb_BitMap; - } - else - { - 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)); - UpdateRects = 0; -} - -void OSystem_MorphOS::DrawMouse() -{ - int x,y; - byte *dst,*bak; - byte color; - - if (MouseDrawn || !MouseVisible) - return; - MouseDrawn = true; - - int ydraw = MouseY - MouseHotspotY; - int xdraw = MouseX - MouseHotspotX; - int w = MouseWidth; - int h = MouseHeight; - int x_mouseimg_offs = 0; - int y_mouseimg_offs = 0; - byte *buf; - - if (xdraw < 0) { x_mouseimg_offs = -xdraw; w += xdraw; xdraw = 0; } - if (ydraw < 0) { y_mouseimg_offs = -ydraw; h += ydraw; ydraw = 0; } - - MouseOldX = xdraw; - MouseOldY = ydraw; - MouseOldWidth = w; - MouseOldHeight = h; - - AddUpdateRect(xdraw, ydraw, w, h); - dst = (byte*)ScummBuffer + ydraw*ScummBufferWidth + xdraw; - bak = MouseBackup; - buf = MouseImage + y_mouseimg_offs*MAX_MOUSE_W + x_mouseimg_offs; - - for (y = 0; y < h; y++, dst += ScummBufferWidth, bak += MAX_MOUSE_W, buf += MouseWidth) - { - if (ydraw+y < ScummBufferHeight) - { - for (x = 0; x<w; x++) - { - if (xdraw+x < ScummBufferWidth) - { - bak[x] = dst[x]; - if ((color=buf[x])!=MouseKeycolor) - dst[x] = color; - } - } - } - else - break; - } -} - -void OSystem_MorphOS::UndrawMouse() -{ - int x,y; - byte *dst,*bak; - - if (!MouseDrawn) - return; - MouseDrawn = false; - - dst = (byte*)ScummBuffer + MouseOldY*ScummBufferWidth + MouseOldX; - bak = MouseBackup; - - AddUpdateRect(MouseOldX, MouseOldY, MouseOldWidth, MouseOldHeight); - - for (y = 0; y < MouseOldHeight; y++, bak += MAX_MOUSE_W, dst += ScummBufferWidth) - { - if (MouseOldY + y < ScummBufferHeight) - { - for (x = 0; x < MouseOldWidth; x++) - { - if (MouseOldX + x < ScummBufferWidth) - dst[x] = bak[x]; - } - } - else - break; - } -} - -bool OSystem_MorphOS::showMouse(bool visible) -{ - if (MouseVisible == visible) - return visible; - - bool last = MouseVisible; - MouseVisible = visible; - - if (!visible) - UndrawMouse(); - - return last; -} - -void OSystem_MorphOS::set_mouse_pos(int x, int y) -{ - if (x != MouseX || y != MouseY) - { - MouseX = x; - MouseY = y; - UndrawMouse(); - } -} - -void OSystem_MorphOS::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, byte keycolor) -{ - MouseWidth = w; - MouseHeight = h; - - MouseHotspotX = hotspot_x; - MouseHotspotY = hotspot_y; - - MouseKeycolor = keycolor; - - if (MouseImage) - free(MouseImage); - - MouseImage = (byte *)malloc(w * h); - memcpy(mouseImage, buf, w * h); - - UndrawMouse(); -} - -bool OSystem_MorphOS::setSoundCallback(OSystem::SoundProc proc, void *param) -{ - if (ScummSoundThread) - { - if (SoundProc == proc) - return true; - clearSoundCallback(); - } - - SoundProc = proc; - SoundParam = param; - - /* - * Create Sound Thread - */ - SoundStartup.mn_Node.ln_Type = NT_MESSAGE; - SoundStartup.mn_ReplyPort = ThreadPort; - SoundStartup.mn_Length = sizeof(SoundStartup); - - ScummSoundThread = CreateNewProcTags(NP_Entry, (ULONG) &morphos_sound_thread, - NP_CodeType, CODETYPE_PPC, - NP_Name, (ULONG) "ScummVM Sound Thread", - NP_StartupMsg, &SoundStartup, - NP_PPC_Arg1, (ULONG) this, - NP_PPC_Arg2, AHIST_S16S, TAG_DONE); - if (!ScummSoundThread) - { - puts("Failed to create sound thread"); - exit(1); - } - - return true; -} - - -void OSystem_MorphOS::fill_sound(byte *stream, int len) -{ - if (SoundProc) - SoundProc(SoundParam, stream, len); - else - memset(stream, 0x0, len); -} - -void OSystem_MorphOS::clearSoundCallback() -{ - if (ScummSoundThread) - { - Signal((Task *) ScummSoundThread, SIGBREAKF_CTRL_C); - ScummSoundThread = NULL; - /* Wait for thread to finish */ - WaitPort(ThreadPort); - } -} - -void OSystem_MorphOS::initSize(uint w, uint h) -{ - if (ScummBuffer) - { - FreeVec(ScummBuffer); - ScummBuffer = NULL; - } - if (DirtyBlocks) - { - FreeVec(DirtyBlocks); - - for (int b = 0; b < BLOCKS_X*BLOCKS_Y; b++) - FreeVec(BlockColors[b]); - FreeVec(BlockColors); - DirtyBlocks = NULL; - } - - /* - * Allocate image buffer - */ - ScummBuffer = AllocVec(w*h, MEMF_CLEAR); - - if (ScummBuffer == NULL) - { - puts("Couldn't allocate image buffer"); - exit(1); - } - - OvlSavedBuffer = AllocVec(w*h, MEMF_CLEAR); - - if (OvlSavedBuffer == NULL) - { - FreeVec(ScummBuffer); - puts("Couldn't allocate overlay backup image buffer"); - exit(1); - } - - memset(ScummColors, 0, 256*sizeof (ULONG)); - - ScummBufferWidth = w; - ScummBufferHeight = h; - - DirtyBlocks = (bool *) AllocVec(BLOCKS_X*BLOCKS_Y*sizeof (bool), MEMF_CLEAR); - if (DirtyBlocks) - { - BlockColors = (UWORD **) AllocVec(BLOCKS_X*BLOCKS_Y*sizeof (UWORD *), MEMF_CLEAR); - if (BlockColors) - { - int b; - - 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; - } - } - - CreateScreen(CSDSPTYPE_KEEP); -} - -int16 OSystem_MorphOS::getWidth() -{ - return ScummScrWidth; -} - -int16 OSystem_MorphOS::getHeight() -{ - return ScummScrHeight; -} - -void OSystem_MorphOS::showOverlay() -{ - UndrawMouse(); - memcpy(OvlSavedBuffer, ScummBuffer, ScummBufferWidth*ScummBufferHeight); - clearOverlay(); - for (int c = 0; c < 256; c++) - { - ULONG r, g, b; - r = ScummColors[c] >> 16; - g = (ScummColors[c] >> 8) & 0xff; - b = ScummColors[c] & 0xff; - SetRGB32CM(OvlCMap, c, CVT8TO32(r), CVT8TO32(g), CVT8TO32(b)); - } -} - -void OSystem_MorphOS::hideOverlay() -{ - copyRectToScreen((byte *) OvlSavedBuffer, ScummBufferWidth, 0, 0, ScummBufferWidth, ScummBufferHeight); -} - -void OSystem_MorphOS::clearOverlay() -{ - AUTO_LOCK - - UBYTE *src = (UBYTE *) ScummBuffer; - UBYTE *dest = (UBYTE *) OvlBitMap; - copyRectToScreen((byte *) OvlSavedBuffer, ScummBufferWidth, 0, 0, ScummBufferWidth, ScummBufferHeight); - for (int y = 0; y < ScummBufferHeight; y++) - for (int x = 0; x < ScummBufferWidth; x++) - { - *dest++ = ScummColors[*src] >> 16; - *dest++ = (ScummColors[*src] >> 8) & 0xff; - *dest++ = ScummColors[*src++] & 0xff; - } -} - -void OSystem_MorphOS::grabOverlay(int16 *buf, int pitch) -{ - int h = ScummBufferHeight; - int x; - UBYTE *src = (UBYTE *) OvlBitMap; - - do - { - for (x = 0; x < pitch; x++) - { - *buf++ = (src[0]*31/255 << 11) | (src[1]*63/255 << 5) | src[2]*31/255; - src += 3; - } - src += (ScummBufferWidth-pitch)*3; - } while (--h); -} - -void OSystem_MorphOS::copyRectToOverlay(const int16 *ovl, int pitch, int x, int y, int w, int h) -{ - int x1, y1; - UBYTE *dest; - UBYTE *bmap, *bmap_dest; - LONG last_col[2] = { -1, -1 }; - LONG last_pen[2] = { -1, -1 }; - - if (w > pitch) w = pitch; - bmap = (UBYTE*) AllocVec(w*h, MEMF_ANY); - if (bmap) - { - bmap_dest = bmap; - dest = ((UBYTE *) OvlBitMap)+y*ScummBufferWidth*3+x*3; - for (y1 = 0; y1 < h; y1++) - { - for (x1 = 0; x1 < w; x1++) - { - uint8 r, g, b; - int16 col; - - col = *ovl++; - colorToRGB(col, r, g, b); - *dest++ = r; - *dest++ = g; - *dest++ = b; - if (col == last_col[0]) - *bmap_dest++ = last_pen[0]; - else if (col == last_col[1]) - *bmap_dest++ = last_pen[1]; - else - { - last_col[1] = last_col[0]; - last_pen[1] = last_pen[0]; - last_col[0] = col; - last_pen[0] = FindColor(OvlCMap, CVT8TO32(r), CVT8TO32(g), CVT8TO32(b), -1); - *bmap_dest++ = last_pen[0]; - } - } - dest += (ScummBufferWidth-w)*3; - ovl += pitch-w; - } - copyRectToScreen(bmap, w, x, y, w, h); - FreeVec(bmap); - } -} - |