aboutsummaryrefslogtreecommitdiff
path: root/mac
diff options
context:
space:
mode:
authorMax Horn2002-06-03 21:13:27 +0000
committerMax Horn2002-06-03 21:13:27 +0000
commit27ea39a7be9f2756fd9ff3aebc6afb67a83117a2 (patch)
tree7d0f970b7506d96d90b0c9ceeee4f936c30053b9 /mac
parent8b7207666e236988ebd568eeaa5386314f90cdb9 (diff)
downloadscummvm-rg350-27ea39a7be9f2756fd9ff3aebc6afb67a83117a2.tar.gz
scummvm-rg350-27ea39a7be9f2756fd9ff3aebc6afb67a83117a2.tar.bz2
scummvm-rg350-27ea39a7be9f2756fd9ff3aebc6afb67a83117a2.zip
checkin of mutle's current work - note that this won't build right now, it needs some work first
svn-id: r4397
Diffstat (limited to 'mac')
-rw-r--r--mac/Carbon.r8
-rw-r--r--mac/mac.cpp2252
-rw-r--r--mac/scummvm.mcpbin158716 -> 158716 bytes
3 files changed, 1451 insertions, 809 deletions
diff --git a/mac/Carbon.r b/mac/Carbon.r
index 5104573275..a296c97b26 100644
--- a/mac/Carbon.r
+++ b/mac/Carbon.r
@@ -70,8 +70,10 @@ resource 'MENU'(999) {
"Zak McKracken and the Alien Mindbenders (256)", noIcon, noKey, noMark, plain,
"Loom", noIcon, noKey, noMark, plain,
"Monkey Island 1 (EGA)", noIcon, noKey, noMark, plain,
+ "Monkey Island 1 (256 color Floppy version)", noIcon, noKey, noMark, plain,
"Loom (256 color CD version)", noIcon, noKey, noMark, plain,
"Monkey Island 1", noIcon, noKey, noMark, plain,
+ "Monkey Island 1 (alt)", noIcon, noKey, noMark, plain,
"Monkey Island 2: LeChuck's revenge", noIcon, noKey, noMark, plain,
"Indiana Jones 4 and the Fate of Atlantis", noIcon, noKey, noMark, plain,
"Indiana Jones 4 and the Fate of Atlantis (Demo)", noIcon, noKey, noMark, plain,
@@ -81,7 +83,11 @@ resource 'MENU'(999) {
"Sam & Max (Demo)", noIcon, noKey, noMark, plain,
"Full Throttle", noIcon, noKey, noMark, plain,
"The Dig", noIcon, noKey, noMark, plain,
- "The Curse of Monkey Island", noIcon, noKey, noMark, plain
+ "The Curse of Monkey Island", noIcon, noKey, noMark, plain,
+ "-", noIcon, noKey, noMark, plain,
+ "Simon the Sorcerer 1 (DOS)", noIcon, noKey, noMark, plain,
+ "Simon the Sorcerer 1 (Windows)", noIcon, noKey, noMark, plain,
+ "Simon the Sorcerer 2 (Windows)", noIcon, noKey, noMark, plain
}
};
diff --git a/mac/mac.cpp b/mac/mac.cpp
index 0f89434ade..1339e3b031 100644
--- a/mac/mac.cpp
+++ b/mac/mac.cpp
@@ -1,6 +1,6 @@
/* ScummVM - Scumm Interpreter
* Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2002 Mutwin Kraus (Mac Port)
+ * Copyright (C) 2001/2002 Mutwin Kraus (Mac Port) and The ScummVM Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -21,61 +21,203 @@
*/
#include <Carbon.h>
-#include <CarbonEvents.h>
-
#include <sioux.h>
-#include <string.h>
-#include <assert.h>
-
#include "stdafx.h"
#include "scumm.h"
-#include "gui.h"
-#include "cdmusic.h"
+#include "mididrv.h"
#include "gameDetector.h"
+//#include "mp3_cd.h"
+#include "gui.h"
+//#include "gameDetector.h"
-#define SRC_WIDTH 320
-#define SRC_HEIGHT 200
-#define SRC_PITCH (320)
+#define MAX(a,b) (((a)<(b)) ? (b) : (a))
+#define MIN(a,b) (((a)>(b)) ? (b) : (a))
-#define MS_PER_TICK (1000.0/60.0)
+class OSystem_MAC : public OSystem {
+public:
+ // Set colors of the palette
+ void set_palette(const byte *colors, uint start, uint num);
-int Time()
-{
- UnsignedWide ms;
+ // Set the size of the video bitmap.
+ // Typically, 320x200
+ void init_size(uint w, uint h);
+
+ // Draw a bitmap to screen.
+ // The screen will not be updated to reflect the new bitmap
+ void copy_rect(const byte *buf, int pitch, int x, int y, int w, int h);
+
+ // Update the dirty areas of the screen
+ void update_screen();
+
+ // Either show or hide the mouse cursor
+ bool show_mouse(bool visible);
- Microseconds(&ms);
- //return(ms.lo * MS_PER_TICK);
- return(ms.lo / 1000);
-}
+ // Set the position of the mouse cursor
+ void set_mouse_pos(int x, int y);
+
+ // Set the bitmap that's used when drawing the cursor.
+ void set_mouse_cursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y);
+
+ // Shaking is used in SCUMM. Set current shake position.
+ void set_shake_pos(int shake_pos);
+
+ // Get the number of milliseconds since the program was started.
+ uint32 get_msecs();
+
+ // Delay for a specified amount of milliseconds
+ void delay_msecs(uint msecs);
+
+ // Create a thread
+ void *create_thread(ThreadProc *proc, void *param);
+
+ // Get the next event.
+ // Returns true if an event was retrieved.
+ bool poll_event(Event *event);
+
+ // Set function that generates samples
+ bool set_sound_proc(void *param, SoundProc *proc, byte sound);
+
+ // Poll cdrom status
+ // Returns true if cd audio is playing
+ bool poll_cdrom();
-int DEST_WIDTH, DEST_HEIGHT;
-static bool shutdown;
+ // Play cdrom audio track
+ void play_cdrom(int track, int num_loops, int start_frame, int end_frame);
-KeyMap fKeyMap;
+ // Stop cdrom audio track
+ void stop_cdrom();
-Rect srcRect, dstRect;
+ // Update cdrom audio status
+ void update_cdrom();
-enum
-{
- kNewGameCmd = 'newG',
- kQuitCmd = kHICommandQuit,
- kOpenGameCmd = 'opnG',
- kSaveGameCmd = 'savG',
- kPrefsCmd = kHICommandPreferences,
- kAboutCmd = 'abtG'
+ // Add a new callback timer
+ void set_timer(int timer, int (*callback)(int))
+ {
+ // FIXME - TODO
+ }
+
+ // Quit
+ void quit();
+
+ // Set a parameter
+ uint32 property(int param, Property *value);
+
+ static OSystem *create(int gfx_mode, bool full_screen);
+
+ void sound_callback(SndChannel *chan, SndCommand *cmd_passed);
+private:
+ typedef void TwoXSaiProc(uint8 *srcPtr, uint32 srcPitch, uint8 *deltaPtr,
+ uint8 *dstPtr, uint32 dstPitch, int width, int height);
+
+ GWorldPtr screenBuf;
+ WindowRef wref;
+ CTabHandle pal;
+ Rect blit_rect;
+
+ enum {
+ DF_WANT_RECT_OPTIM = 1 << 0,
+ DF_REAL_8BIT = 1 << 1,
+ DF_SEPARATE_TEMPSCREEN = 1 << 2,
+ DF_UPDATE_EXPAND_1_PIXEL = 1 << 3
+ };
+
+ int _mode;
+ bool _full_screen;
+ bool _mouse_visible;
+ bool _mouse_drawn;
+ uint32 _mode_flags;
+ byte _internal_scaling;
+
+ bool force_full; //Force full redraw on next update_screen
+ bool cksum_valid;
+
+ enum {
+ NUM_DIRTY_RECT = 100,
+
+ MAX_MOUSE_W = 40,
+ MAX_MOUSE_H = 40,
+ MAX_SCALING = 3
+ };
+
+ int SCREEN_WIDTH, SCREEN_HEIGHT, CKSUM_NUM;
+ Rect *dirty_rect_list;
+ int num_dirty_rects;
+ uint32 *dirty_checksums;
+
+ int scaling;
+
+ /* CD Audio */
+ int cd_track, cd_num_loops, cd_start_frame, cd_end_frame;
+ uint32 cd_end_time, cd_stop_time, cd_next_second;
+
+ struct MousePos {
+ int16 x,y,w,h;
+ };
+
+ byte *_ms_buf;
+ byte *_ms_backup;
+ MousePos _ms_cur;
+ MousePos _ms_old;
+ int16 _ms_hotspot_x;
+ int16 _ms_hotspot_y;
+ int _current_shake_pos;
+
+ byte* _gfx_buf; /* Graphics memory */
+ int16 *_sai_buf, *_tmp_buf;
+ uint _palette_changed_first, _palette_changed_last;
+
+ TwoXSaiProc *_sai_func;
+
+ void add_dirty_rgn_auto(const byte *buf);
+ void mk_checksums(const byte *buf);
+
+ static void fill_sound(void *userdata, uint8 * stream, int len);
+
+ void add_dirty_rect(int x, int y, int w, int h);
+
+ void draw_mouse();
+ void undraw_mouse();
+
+ void load_gfx_mode();
+ void unload_gfx_mode();
+
+ void hotswap_gfx_mode();
+
+ void get_320x200_image(byte *buf);
+
+ void init_mac_stuff();
+ void set_scaling();
+ void blit_to_screen();
+ void update_rects();
+
+ static uint32 autosave(uint32);
+
+ UInt8 *buffer[2];
+ CmpSoundHeader header;
+ SndChannelPtr channel;
+ int size;
+ SoundProc *sndProc;
+ void * parameter;
};
-static unsigned char *CToPascal(char *str);
+int Init_2xSaI (uint32 BitFormat);
+void _2xSaI(uint8 *srcPtr, uint32 srcPitch, uint8 *deltaPtr, uint8 *dstPtr,
+ uint32 dstPitch, int width, int height);
+void Super2xSaI(uint8 *srcPtr, uint32 srcPitch, uint8 *deltaPtr,
+ uint8 *dstPtr, uint32 dstPitch, int width, int height);
+void SuperEagle(uint8 *srcPtr, uint32 srcPitch, uint8 *deltaPtr,
+ uint8 *dstPtr, uint32 dstPitch, int width, int height);
+void AdvMame2x(uint8 *srcPtr, uint32 srcPitch, uint8 *null,
+ uint8 *dstPtr, uint32 dstPitch, int width, int height);
+void Normal1x(uint8 *srcPtr, uint32 srcPitch, uint8 *null,
+ uint8 *dstPtr, uint32 dstPitch, int width, int height);
+void Normal2x(uint8 *srcPtr, uint32 srcPitch, uint8 *null,
+ uint8 *dstPtr, uint32 dstPitch, int width, int height);
+void Normal3x(uint8 *srcPtr, uint32 srcPitch, uint8 *null,
+ uint8 *dstPtr, uint32 dstPitch, int width, int height);
-Boolean OptionKeyDown()
-{
- GetKeys(fKeyMap); // get info
- if (fKeyMap[1] & 4)
- return true;
- else
- return false;
-}
+KeyMap fKeyMap;
Boolean CommandKeyDown()
{
@@ -86,78 +228,31 @@ Boolean CommandKeyDown()
return false;
}
+static unsigned char *CToPascal(char *str) {
+ register char *p,*q;
+ register long len;
-Boolean ShiftKeyDown()
-{
- GetKeys(fKeyMap); // get info
- if (fKeyMap[1] & 1)
- return true;
- else
- return false;
-}
-
-
-// Fast macro for testing key codes.
-#define KeyCode(x,y) (BitTst(&(x), (y) ^ 0x07))
-
-Boolean IsKeyDown(unsigned short key)
-{
- GetKeys(fKeyMap); // get info
- return (KeyCode(fKeyMap, key));
+ len = strlen(str);
+ if (len > 255) len = 255;
+ p = str + len;
+ q = p-1;
+ while (p != str)
+ *p-- = *q--;
+ *str = len;
+ return((unsigned char *)str);
}
+static char *PascalToC(unsigned char *str) {
+ register unsigned char *p,*q,*end;
-class WndMan
-{
- bool terminated;
-public:
- byte *_vgabuf;
- GWorldPtr screenBuf;
- WindowRef wPtr;
- CTabHandle pal;
- bool newPal;
- CCrsrHandle theCrsr;
- bool fullscreen;
- StringPtr gameName;
- int scale;
- GWorldPtr workSrcMap, backSrcMap;
- GDHandle thisGDevice;
-
- void init();
-
- void ChangeScaling(short scaling);
- bool handleMessage();
- void run();
- void writeToScreen();
- void setPalette(byte *ctab, int first, int num);
-};
-
-int sel;
-Scumm *scumm;
-ScummDebugger debugger;
-Gui gui;
-IMuse sound;
-SOUND_DRIVER_TYPE snd_driv;
-OSystem _system;
-GameDetector detector;
-
-WndMan wm[1];
-byte veryFastMode;
-
-void About();
-void Preferences();
+ end = str + *str;
+ q = (p=str) + 1;
-void Quit()
-{
- QuitApplicationEventLoop();
- ExitToShell();
-}
+ while (p < end)
+ *p++ = *q++;
+ *p = '\0';
-void Error(const char* msg)
-{
-
- //DebugStr((const unsigned char*)msg);
- //ExitToShell();
+ return((char *)str);
}
const EventTypeSpec kCmdEvents[] =
@@ -178,363 +273,157 @@ const EventTypeSpec kWindowEvents[] =
pascal OSErr QuitEventHandler(const AppleEvent *theEvent, AppleEvent *theReply, SInt32 refCon)
{
- Quit();
+ //OSystem_MAC::quit();
return(noErr);
}
-static pascal OSStatus WindowEventHandler( EventHandlerCallRef inCallRef, EventRef inEvent, void* userData )
+enum
{
- OSStatus result = eventNotHandledErr;
-
- if(GetEventClass(inEvent) == kEventClassWindow)
- {
- switch(GetEventKind(inEvent))
- {
- case kEventWindowDrawContent:
- wm->writeToScreen();
- break;
-
- case kEventWindowHandleContentClick:
- if(CommandKeyDown())
- scumm->_rightBtnPressed |= msClicked|msDown;
- else
- scumm->_leftBtnPressed |= msClicked|msDown;
-
- if(wm->wPtr != FrontWindow())
- {
- ActivateWindow(wm->wPtr, true);
- BringToFront(wm->wPtr);
- }
- break;
-
- case kEventWindowClose:
- Quit();
- break;
- }
- }
- return result;
-}
+ kNewGameCmd = 'newG',
+ kQuitCmd = kHICommandQuit,
+ kOpenGameCmd = 'opnG',
+ kSaveGameCmd = 'savG',
+ kPrefsCmd = kHICommandPreferences,
+ kAboutCmd = 'abtG'
+};
-char mapKey(char key, char code, byte mod)
-{
- switch(code)
- {
- case 0x35:
- key = 27;
- break;
-
- case 0x31:
- key = 32;
- break;
-
- case 0x60:
- key = 601;
- }
- return key;
-}
+ControlRef radioGroupRef, musicVolumeSlider, masterVolumeSlider;
+char *gameTitle;
+ControlRef popUpControlRef, checkBoxControlRef;
-static pascal OSStatus EventHandler( EventHandlerCallRef inCallRef, EventRef inEvent, void* userData )
+OSStatus prefsEventHandler(EventHandlerCallRef eventHandlerCallRef,EventRef eventRef,
+ void *userData)
{
- OSStatus result = eventNotHandledErr;
- HICommand command;
- Point mouse;
-
- GetEventParameter( inEvent, kEventParamDirectObject, typeHICommand, NULL,
- sizeof( HICommand ), NULL, &command );
-
- switch(GetEventClass(inEvent))
- {
- case kEventClassCommand:
- switch(command.commandID)
- {
- case kNewGameCmd:
-
- break;
-
- case kOpenGameCmd:
- scumm->_saveLoadSlot = 0;
- scumm->_saveLoadFlag = 2;
- break;
-
- case kSaveGameCmd:
- scumm->_saveLoadSlot = 0;
- sprintf(scumm->_saveLoadName, "Quicksave %d", scumm->_saveLoadSlot);
- scumm->_saveLoadFlag = 1;
- break;
-
- case kQuitCmd:
- Quit();
- break;
-
- case kPrefsCmd:
- Preferences();
- break;
-
- case kAboutCmd:
- About();
- break;
- }
- break;
- break;
-
- case kEventClassKeyboard:
- if(GetEventKind(inEvent) == kEventRawKeyDown)
- {
- char key;
- UInt32 mod, code;
-
- GetEventParameter(inEvent, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &code);
- GetEventParameter(inEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &key);
- GetEventParameter(inEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &mod);
- scumm->_keyPressed = (int)mapKey(key, code, mod);
- }
- break;
-
- case kEventClassMouse:
- switch(GetEventKind(inEvent))
- {
- case kEventMouseDown:
- WindowRef theWin;
-
- GetEventParameter(inEvent, kEventParamDirectObject, typeWindowRef, NULL, sizeof(WindowRef),
- NULL, &theWin);
- if(theWin != FrontWindow())
- {
- ActivateWindow(theWin, true);
- BringToFront(theWin);
- }
- break;
-
- case kEventMouseUp:
- scumm->_rightBtnPressed &= ~msDown;
- scumm->_leftBtnPressed &= ~msDown;
- break;
-
- case kEventMouseMoved:
- GetEventParameter(inEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &mouse);
- Rect winRect;
-
- GetWindowBounds(wm->wPtr, kWindowContentRgn, &winRect);
- if(PtInRect(mouse, &winRect))
- {
- CGrafPtr oldPort;
-
- GetPort(&oldPort);
- SetPortWindowPort(wm->wPtr);
- GlobalToLocal(&mouse);
- scumm->mouse.x = mouse.h/wm->scale;
- scumm->mouse.y = mouse.v/wm->scale;
- }
- Point offset = {0, 0};
- ShieldCursor(&winRect, offset);
- break;
- }
- break;
- }
- return result;
-}
+ OSStatus result = eventNotHandledErr;
+ UInt32 eventClass;
+ UInt32 eventKind;
+ ControlRef controlRef;
+ ControlID controlID;
-pascal void DoGameLoop(EventLoopTimerRef theTimer, void *userData)
-{
- scumm->mainRun();
- QuitApplicationEventLoop();
-}
+ eventClass = GetEventClass(eventRef);
+ eventKind = GetEventKind(eventRef);
-void WndMan::init()
-{
- Rect rectWin;
-
- scumm->_scale = scale;
-
- DEST_WIDTH = 320 * scumm->_scale;
- DEST_HEIGHT = 200 * scumm->_scale;
-
- MenuRef AppleMenu = GetMenu(1000);
- InsertMenu(AppleMenu, 0);
- SetMenuItemCommandID(AppleMenu, 1, kAboutCmd);
- MenuRef FileMenu = GetMenu(1001);
- SetMenuItemCommandID(FileMenu, 1, kNewGameCmd);
- SetMenuItemCommandID(FileMenu, 2, kOpenGameCmd);
- SetMenuItemCommandID(FileMenu, 3, kSaveGameCmd);
- SetMenuItemCommandID(FileMenu, 5, kQuitCmd);
- DeleteMenuItems(FileMenu, CountMenuItems(FileMenu)-1, 2);
- InsertMenu(FileMenu, 0);
- MenuRef windMenu;
- CreateStandardWindowMenu(0, &windMenu);
- InsertMenu(windMenu, 0);
- EnableMenuCommand(NULL, kPrefsCmd);
- DrawMenuBar();
-
- SetRect(&rectWin, 0, 0, DEST_WIDTH, DEST_HEIGHT);
- UInt32 WinAttrib = (kWindowCloseBoxAttribute | kWindowCollapseBoxAttribute |
- kWindowInWindowMenuAttribute | kWindowStandardHandlerAttribute);
-
- if(noErr != CreateNewWindow(kDocumentWindowClass, WinAttrib, &rectWin, &wPtr))
- {
- Error("Couldn't create Window!");
- }
-
- RepositionWindow(wPtr, NULL, kWindowCenterOnMainScreen);
-
- Str255 WindowTitle = "\pScummVM";
- SetWTitle(wPtr, WindowTitle);
-
- SetPortWindowPort(wPtr);
- ShowWindow(wPtr);
-
- SetRect(&dstRect, 0, 0, DEST_WIDTH, DEST_HEIGHT);
- SetRect(&srcRect, 0, 0, SRC_WIDTH, SRC_HEIGHT);
+ if(eventClass == kEventClassControl)
+ {
+ if(eventKind == kEventControlHit)
+ {
+ GetEventParameter(eventRef,kEventParamDirectObject,typeControlRef,NULL,
+ sizeof(ControlRef),NULL,&controlRef);
- InstallApplicationEventHandler(NewEventHandlerUPP(EventHandler),
- GetEventTypeCount(kCmdEvents), kCmdEvents, 0, NULL);
- InstallStandardEventHandler(GetWindowEventTarget(wPtr));
- InstallWindowEventHandler(wPtr, NewEventHandlerUPP(WindowEventHandler),
- GetEventTypeCount(kWindowEvents), kWindowEvents, 0, NULL);
-
- OSStatus err = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(QuitEventHandler), 0L, false);
-
- EventLoopTimerRef theTimer;
- InstallEventLoopTimer(GetCurrentEventLoop(), 0, 0, NewEventLoopTimerUPP(DoGameLoop),
- NULL, &theTimer);
-
- NewGWorldFromPtr(&screenBuf, 8, &srcRect, pal, nil, 0, (char *)_vgabuf, SRC_WIDTH);
+ GetControlID(controlRef,&controlID);
+ if(controlID.id == 'okay')
+ {
+ /*scumm->_noSubtitles = (Boolean)!GetControlValue(checkBoxControlRef);
+ short scale = GetControlValue(radioGroupRef);
+ if(scale != scumm->_scale)
+ wm->ChangeScaling(scale);
+ short music_vol = GetControlValue(musicVolumeSlider);
+ if(music_vol != sound.get_music_volume())
+ sound.set_music_volume(music_vol);
+ short master_vol = GetControlValue(masterVolumeSlider);
+ if(master_vol != sound.get_master_volume())
+ sound.set_master_volume(master_vol);*/
+ QuitAppModalLoopForWindow((WindowRef)userData);
+ DisposeWindow((WindowRef)userData);
+ result = noErr;
+ }
+ }
+ }
}
-void WndMan::ChangeScaling(short scaling)
+void Preferences()
{
- scumm->_scale = scaling;
- scale = scaling;
-
- Rect rectWin;
-
- DEST_WIDTH = 320 * scumm->_scale;
- DEST_HEIGHT = 200 * scumm->_scale;
-
- SetRect(&rectWin, 0, 0, DEST_WIDTH, DEST_HEIGHT);
+ WindowRef prefsWin;
+ OSStatus osError = noErr;
+ Rect rect = { 0,0,210,300 };
+ Rect okButtonRect;
+ ControlID controlID;
+ ControlRef controlRef;
+ EventTypeSpec dialogEvents[] = { kEventClassControl, kEventControlHit };
+
+ osError = CreateNewWindow(kMovableModalWindowClass,kWindowStandardHandlerAttribute,&rect, &prefsWin);
+ SetWTitle(prefsWin, "\pPreferences");
+ RepositionWindow(prefsWin,FrontWindow(),kWindowAlertPositionOnMainScreen);
+ SetThemeWindowBackground(prefsWin,kThemeBrushDialogBackgroundActive,false);
+ CreateRootControl(prefsWin,&controlRef);
- SetWindowBounds(wPtr, kWindowContentRgn, &rectWin);
- RepositionWindow(wPtr, NULL, kWindowCenterOnMainScreen);
- dstRect = rectWin;
-}
-
-bool WndMan::handleMessage()
-{
- EventRef theEvent;
- EventTargetRef theTarget;
- OSStatus theErr;
+ SetRect(&rect, 5, 5, 150, 21);
- theTarget = GetEventDispatcherTarget();
- theErr = ReceiveNextEvent(GetEventTypeCount(kCmdEvents), kCmdEvents, kEventDurationNoWait,true, &theEvent);
- if(theErr == noErr && theEvent != NULL)
- {
- SendEventToEventTarget (theEvent, theTarget);
- ReleaseEvent(theEvent);
- }
-}
-
-void WndMan::run()
-{
-}
-
-void WndMan::writeToScreen()
-{
- CopyBits(GetPortBitMapForCopyBits(screenBuf),
- GetPortBitMapForCopyBits(GetWindowPort(wPtr)),
- &srcRect, &dstRect, srcCopy, 0L);
-}
-
-void waitForTimer(Scumm *s, int delay)
-{
- uint32 start_time;
+ CreateStaticTextControl(prefsWin, &rect, CFSTR("ScummVM Preferences"), NULL, &controlRef);
+ AutoEmbedControl(controlRef, prefsWin);
- if(s->_fastMode&2)
- delay = 0;
- else if(s->_fastMode&1)
- delay = 10;
+ SetRect(&okButtonRect, 225, 180, 295, 200);
- start_time = Time();
- do {
- wm->handleMessage();
- if(Time() >= start_time + delay)
- break;
- } while (1);
-}
-
-void WndMan::setPalette(byte *ctab, int first, int num)
-{
- pal = (CTabHandle)NewHandleClear(sizeof(ColorTable) + 255 * sizeof(ColorSpec));
- (*pal)->ctSeed = TickCount();
- (*pal)->ctFlags = 0;
- (*pal)->ctSize = 256;
- for(int i = 0; i < 256; i++, ctab +=3)
- {
- (*pal)->ctTable[i].value = i;
- (*pal)->ctTable[i].rgb.red = ctab[0]<<8;
- (*pal)->ctTable[i].rgb.green = ctab[1]<<8;
- (*pal)->ctTable[i].rgb.blue = ctab[2]<<8;
- }
- NewGWorldFromPtr(&screenBuf, 8, &srcRect, pal, nil, 0, (char *)_vgabuf, SRC_WIDTH);
-}
-
-void blitToScreen(Scumm *s, byte *src,int x, int y, int w, int h)
-{
- byte *dst;
- int i;
-
- dst = (byte*)wm->_vgabuf + y*320 + x;
-
- do {
- memcpy(dst, src, w);
- dst += 320;
- src += 320;
- } while (--h);
-}
-
-void updateScreen(Scumm *s)
-{
- if (s->_palDirtyMax != -1) {
- wm->setPalette(s->_currentPalette, 0, 256);
- s->_palDirtyMax = -1;
- }
+ CreatePushButtonControl(prefsWin,&okButtonRect,CFSTR("OK"),&controlRef);
+ SetWindowDefaultButton(prefsWin,controlRef);
+ controlID.id = 'okay';
+ SetControlID(controlRef,&controlID);
+ AutoEmbedControl(controlRef,prefsWin);
+
+ SetRect(&rect, 150, 35, 260, 51);
+
+ CreateCheckBoxControl(prefsWin,&rect, CFSTR("Subtitles"), 1, true, &checkBoxControlRef);
+ AutoEmbedControl(checkBoxControlRef, prefsWin);
+
+ //if(scumm->_noSubtitles)
+ SetControlValue(checkBoxControlRef, false);
+
+ OffsetRect(&rect, 0, 20);
+
+ CreateCheckBoxControl(prefsWin,&rect, CFSTR("Fullscreen"), 0, true, &controlRef);
+ AutoEmbedControl(controlRef, prefsWin);
+ DeactivateControl(controlRef);
+
+ Rect RadioGroupRect;
+ SetRect(&RadioGroupRect, 5, 35, 120, 100);
+ CreateRadioGroupControl(prefsWin, &RadioGroupRect, &radioGroupRef);
+ AutoEmbedControl(radioGroupRef, prefsWin);
+
+ ControlRef radioButton;
+
+ Rect RadioButtonRect;
+ SetRect(&RadioButtonRect, 5, 35, 120, 51);
+ CreateRadioButtonControl(prefsWin, &RadioButtonRect, CFSTR("Scaling 1x"), 0, true, &radioButton);
+ AutoEmbedControl(radioButton, prefsWin);
+
+ OffsetRect(&RadioButtonRect, 0, 20);
+ CreateRadioButtonControl(prefsWin, &RadioButtonRect, CFSTR("Scaling 2x"), 0, true, &radioButton);
+ AutoEmbedControl(radioButton, prefsWin);
+
+ OffsetRect(&RadioButtonRect, 0, 20);
+ CreateRadioButtonControl(prefsWin, &RadioButtonRect, CFSTR("Scaling 3x"), 0, true, &radioButton);
+ AutoEmbedControl(radioButton, prefsWin);
+
+ //SetControlValue(radioGroupRef, scumm->_scale);
+
+ SetRect(&rect, 5, 110, 175, 146);
+
+ CreateSliderControl(prefsWin, &rect, 100, 1, 100,
+ kControlSliderPointsDownOrRight, 10, false, NULL, &musicVolumeSlider);
+ AutoEmbedControl(musicVolumeSlider, prefsWin);
+
+ OffsetRect(&rect, 0, 36);
+
+ CreateSliderControl(prefsWin, &rect, 100, 1, 100,
+ kControlSliderPointsDownOrRight, 10, false, NULL, &masterVolumeSlider);
+ AutoEmbedControl(masterVolumeSlider, prefsWin);
+
+ OffsetRect(&rect, 180, -36);
+
+ CreateStaticTextControl(prefsWin, &rect, CFSTR("Music Volume"), NULL, &controlRef);
+ AutoEmbedControl(controlRef, prefsWin);
- wm->writeToScreen();
- s->drawMouse();
-}
-
-
-void initGraphics(Scumm *s, bool fullScreen, unsigned int scaleFactor) {
- s->_scale = scaleFactor;
- wm->init();
-}
-
-static unsigned char *CToPascal(char *str)
-{
- register char *p,*q;
- register long len;
-
- len = strlen(str);
- if (len > 255) len = 255;
- p = str + len;
- q = p-1;
- while (p != str) *p-- = *q--;
- *str = len;
- return((unsigned char *)str);
-}
-
-static char *PascalToC(unsigned char *str)
-{
- register unsigned char *p,*q,*end;
-
- end = str + *str;
- q = (p=str) + 1;
- while (p < end) *p++ = *q++;
- *p = '\0';
- return((char *)str);
+ OffsetRect(&rect, 0, 36);
+
+ CreateStaticTextControl(prefsWin, &rect, CFSTR("Master Volume"), NULL, &controlRef);
+ AutoEmbedControl(controlRef, prefsWin);
+
+ InstallWindowEventHandler(prefsWin, NewEventHandlerUPP((EventHandlerProcPtr) prefsEventHandler),
+ GetEventTypeCount(dialogEvents),dialogEvents,prefsWin,NULL);
+ ShowWindow(prefsWin);
+ osError = RunAppModalLoopForWindow(prefsWin);
}
-ControlRef popUpControlRef, checkBoxControlRef;
-char *gameTitle;
-
void LaunchGame(int id)
{
switch(id)
@@ -546,7 +435,7 @@ void LaunchGame(int id)
case 7:
gameTitle = "zak256";
break;
-
+
case 8:
gameTitle = "loom";
break;
@@ -556,47 +445,68 @@ void LaunchGame(int id)
break;
case 10:
- gameTitle = "loomcd";
+ gameTitle = "monkeyVGA";
break;
case 11:
- gameTitle = "monkey";
+ gameTitle = "loomcd";
break;
case 12:
- gameTitle = "monkey2";
+ gameTitle = "monkey";
break;
case 13:
- gameTitle = "atlantis";
+ gameTitle = "monkey1";
break;
case 14:
- gameTitle = "playfate";
+ gameTitle = "monkey2";
break;
case 15:
- gameTitle = "tentacle";
+ gameTitle = "atlantis";
break;
case 16:
- gameTitle = "dottdemo";
+ gameTitle = "playfate";
break;
case 17:
- gameTitle = "samnmax";
+ gameTitle = "tentacle";
break;
case 18:
- gameTitle = "snmdemo";
+ gameTitle = "dottdemo";
break;
case 19:
- gameTitle = "ft";
+ gameTitle = "samnmax";
break;
case 20:
+ gameTitle = "snmdemo";
+ break;
+
+ case 21:
+ gameTitle = "ft";
+ break;
+
+ case 22:
gameTitle = "dig";
+ break;
+
+ case 25:
+ gameTitle = "simon1dos";
+ break;
+
+ case 26:
+ gameTitle = "simon1win";
+ break;
+
+ case 27:
+ gameTitle = "simon2win";
+ break;
}
}
@@ -616,6 +526,7 @@ OSStatus dialogEventHandler(EventHandlerCallRef eventHandlerCallRef,EventRef eve
{
if(eventKind == kEventControlHit)
{
+
GetEventParameter(eventRef,kEventParamDirectObject,typeControlRef,NULL,
sizeof(ControlRef),NULL,&controlRef);
@@ -624,7 +535,6 @@ OSStatus dialogEventHandler(EventHandlerCallRef eventHandlerCallRef,EventRef eve
{
QuitAppModalLoopForWindow((WindowRef)userData);
LaunchGame(GetControlValue(popUpControlRef));
- wm->scale = 2;
DisposeWindow((WindowRef)userData);
result = noErr;
@@ -640,7 +550,7 @@ OSStatus dialogEventHandler(EventHandlerCallRef eventHandlerCallRef,EventRef eve
return result;
}
-void SelectGame()
+char* SelectGame()
{
WindowRef aboutWin;
OSStatus osError = noErr;
@@ -652,6 +562,18 @@ void SelectGame()
Rect checkboxRect = { 36, 10, 50, 80 };
EventTypeSpec dialogEvents[] = { kEventClassControl, kEventControlHit };
+ InitCursor();
+
+ SIOUXSettings.autocloseonquit = true;
+ SIOUXSettings.asktosaveonclose = false;
+ SIOUXSettings.showstatusline = false;
+ SIOUXSettings.fontsize = 9;
+ GetFNum("\pMonaco",&SIOUXSettings.fontid);
+ SIOUXSettings.standalone = false;
+ SIOUXSettings.setupmenus = false;
+ SIOUXSettings.toppixel = 40;
+ SIOUXSettings.leftpixel = 5;
+
osError = CreateNewWindow(kMovableModalWindowClass,kWindowStandardHandlerAttribute,&rect, &aboutWin);
SetWTitle(aboutWin, "\pPlease Select a GameÉ");
RepositionWindow(aboutWin,FrontWindow(),kWindowAlertPositionOnMainScreen);
@@ -663,7 +585,7 @@ void SelectGame()
controlID.id = 'okay';
SetControlID(controlRef,&controlID);
AutoEmbedControl(controlRef,aboutWin);
-
+
OffsetRect(&pushButtonRect, -100, 0);
CreatePushButtonControl(aboutWin,&pushButtonRect,CFSTR("Cancel"),&controlRef);
SetWindowCancelButton(aboutWin,controlRef);
@@ -674,393 +596,760 @@ void SelectGame()
CreatePopupButtonControl(aboutWin, &popupRect, CFSTR("Game: "), 999, false, -1, 0, NULL, &popUpControlRef);
SetWindowDefaultButton(aboutWin,popUpControlRef);
controlID.id = 'game';
+
SetControlID(popUpControlRef,&controlID);
AutoEmbedControl(controlRef,aboutWin);
-
+
InstallWindowEventHandler(aboutWin, NewEventHandlerUPP((EventHandlerProcPtr) dialogEventHandler),
GetEventTypeCount(dialogEvents),dialogEvents,aboutWin,NULL);
ShowWindow(aboutWin);
osError = RunAppModalLoopForWindow(aboutWin);
+ return gameTitle;
}
-static void DrawCenteredStringAt(Str255 theString, short yLocation)
-{
- Rect portRect;
- CGrafPtr thePort = GetQDGlobalsThePort();
+OSystem *OSystem_MAC::create(int gfx_mode, bool full_screen) {
+ Rect rectWin;
+ OSystem_MAC *syst = new OSystem_MAC();
+ syst->_mode = gfx_mode;
+ syst->_full_screen = full_screen;
- GetPortBounds(thePort, &portRect);
-
- MoveTo(portRect.left + ((portRect.right-portRect.left) >> 1) -
- (StringWidth(theString) >> 1), yLocation);
- DrawString(theString);
+ /* Macintosh init */
+ syst->init_mac_stuff();
+ return syst;
}
-void DrawAboutText(WindowRef win)
+uint32 OSystem_MAC::autosave(uint32 interval)
{
- CGrafPtr oldPort;
-
- GetPort(&oldPort);
- SetPortWindowPort(win);
+ g_scumm->_doAutosave = true;
+
+ return interval;
+}
+
+OSystem *OSystem_MAC_create(int gfx_mode, bool full_screen) {
+ return OSystem_MAC::create(gfx_mode, full_screen);
+}
+
+void OSystem_MAC::set_palette(const byte *colors, uint start, uint num) {
+ const byte *b = colors;
- TextFont(systemFont);
- TextSize(12);
+ (*pal)->ctSeed = TickCount();
+ for(int i = start; i < num; i++, b += 4) {
+ (*pal)->ctTable[i].value = i;
+ (*pal)->ctTable[i].rgb.red = b[0]<<8;
+ (*pal)->ctTable[i].rgb.green = b[1]<<8;
+ (*pal)->ctTable[i].rgb.blue = b[2]<<8;
+ }
- DrawCenteredStringAt("\pAbout ScummVMÉ", 32);
+ CTabChanged(pal);
- TextFont(applFont);
- TextSize(9);
+ if(_sai_func)
+ UpdateGWorld(&screenBuf, 16, &blit_rect, NULL, NULL, 0);
+ else
+ UpdateGWorld(&screenBuf, 8, &blit_rect, pal, NULL, 0);
- DrawCenteredStringAt("\pScummVM", 50);
- DrawCenteredStringAt("\pLet's you run all your favourite Scumm Games", 65);
- DrawCenteredStringAt("\pon MacOS 9 and X", 80);
+ if(start < _palette_changed_first)
+ _palette_changed_first = start;
- SetPort(oldPort);
+ if(start + num > _palette_changed_last)
+ _palette_changed_last = start + num;
}
-OSStatus aboutEventHandler(EventHandlerCallRef eventHandlerCallRef,EventRef eventRef,
- void *userData)
-{
- OSStatus result = eventNotHandledErr;
- UInt32 eventClass;
- UInt32 eventKind;
- ControlRef controlRef;
- ControlID controlID;
+void OSystem_MAC::load_gfx_mode() {
+ force_full = true;
+ scaling = 1;
+ _internal_scaling = 1;
+ _mode_flags = 0;
+ _sai_func = NULL;
+
+ switch(_mode) {
+ case GFX_2XSAI:
+ _sai_func = _2xSaI;
+ break;
+
+ case GFX_SUPER2XSAI:
+ _sai_func = Super2xSaI;
+ break;
+
+ case GFX_SUPEREAGLE:
+ _sai_func = SuperEagle;
+ break;
+
+ case GFX_ADVMAME2X:
+ _sai_func = AdvMame2x;
+ break;
+
+ case GFX_DOUBLESIZE:
+ scaling = 2;
+ _internal_scaling = 2;
+ _mode_flags = DF_WANT_RECT_OPTIM;
+ break;
+
+ case GFX_TRIPLESIZE:
+ if (_full_screen) {
+ warning("full screen in useless in triplesize mode, reverting to normal mode");
+ goto normal_mode;
+ }
+ scaling = 3;
+ _internal_scaling = 3;
+ _mode_flags = DF_WANT_RECT_OPTIM;
+ break;
+
+ case GFX_NORMAL:
+ normal_mode:;
+ _mode_flags = DF_WANT_RECT_OPTIM;
+ break;
+
+ }
+
+ if(_sai_func)
+ {
+ _mode_flags = DF_WANT_RECT_OPTIM | DF_SEPARATE_TEMPSCREEN | DF_UPDATE_EXPAND_1_PIXEL;
- eventClass = GetEventClass(eventRef);
- eventKind = GetEventKind(eventRef);
+ Init_2xSaI(565);
+ _tmp_buf = (int16*)calloc((SCREEN_WIDTH+3)*(SCREEN_HEIGHT+3), sizeof(int16));
+
+ scaling = 2;
+ }
+ else
+ {
+ switch(scaling) {
+ case 3:
+ _sai_func = Normal3x;
+ break;
+ case 2:
+ _sai_func = Normal2x;
+ break;
+ case 1:
+ _sai_func = Normal1x;
+ break;
+ }
- if(eventClass == kEventClassControl)
- {
- if(eventKind == kEventControlHit)
- {
- GetEventParameter(eventRef,kEventParamDirectObject,typeControlRef,NULL,
- sizeof(ControlRef),NULL,&controlRef);
+ _mode_flags = DF_WANT_RECT_OPTIM | DF_REAL_8BIT;
+ }
+
+ set_scaling();
+}
- GetControlID(controlRef,&controlID);
- if(controlID.id == 'okay')
- {
- QuitAppModalLoopForWindow((WindowRef)userData);
- DisposeWindow((WindowRef)userData);
- result = noErr;
- }
- }
- }
- else if(eventClass == kEventClassWindow)
- {
- if(eventKind == kEventWindowUpdate)
- {
- DrawAboutText((WindowRef)userData);
- }
- }
- return result;
+void OSystem_MAC::unload_gfx_mode() {
+ //warning("STUB: unload_gfx_mode()"); /* FIXME: Must free data here */
+
}
-void About()
-{
- WindowRef aboutWin;
- OSStatus osError = noErr;
- Rect rect = { 0,0,150,300 };
- Rect pushButtonRect = { 125,125,145,175 };
- ControlID controlID;
- ControlRef controlRef;
- EventTypeSpec dialogEvents[] = { { kEventClassControl, kEventControlHit },
- { kEventClassWindow, kEventWindowUpdate} };
-
- osError = CreateNewWindow(kMovableModalWindowClass,kWindowStandardHandlerAttribute,&rect, &aboutWin);
- SetWTitle(aboutWin, "\pAbout ScummVMÉ");
- RepositionWindow(aboutWin,FrontWindow(),kWindowAlertPositionOnMainScreen);
- SetThemeWindowBackground(aboutWin,kThemeBrushDialogBackgroundActive,false);
- CreateRootControl(aboutWin,&controlRef);
+void OSystem_MAC::init_size(uint w, uint h) {
+ //if (w != SCREEN_WIDTH && h != SCREEN_HEIGHT)
+ // error("320x200 is the only game resolution supported");
- DrawAboutText(aboutWin);
+ SCREEN_WIDTH = w;
+ SCREEN_HEIGHT = h;
+ CKSUM_NUM = (SCREEN_WIDTH * SCREEN_HEIGHT / (8*8));
+ dirty_rect_list = (Rect*)calloc(NUM_DIRTY_RECT, sizeof(Rect));
+ _ms_backup = (byte*)malloc(MAX_MOUSE_W * MAX_MOUSE_H * MAX_SCALING);
+ dirty_checksums = (uint32*)calloc(CKSUM_NUM*2, sizeof(uint32));
+
+ load_gfx_mode();
+}
+
+void OSystem_MAC::copy_rect(const byte *buf, int pitch, int x, int y, int w, int h) {
+ if (pitch == SCREEN_WIDTH && x==0 && y==0 && w==SCREEN_WIDTH && h==SCREEN_HEIGHT && _mode_flags&DF_WANT_RECT_OPTIM) {
+ /* Special, optimized case for full screen updates.
+ * It tries to determine what areas were actually changed,
+ * and just updates those, on the actual display. */
+ add_dirty_rgn_auto(buf);
+ } else {
+ /* Clip the coordinates */
+ if (x < 0) { w+=x; buf-=x; x = 0; }
+
+ if (y < 0) { h+=y; buf-=y*pitch; y = 0; }
+ if (w >= SCREEN_WIDTH-x) { w = SCREEN_WIDTH - x; }
+ if (h >= SCREEN_HEIGHT-y) { h = SCREEN_HEIGHT - y; }
+
+ if (w<=0 || h<=0)
+ return;
+
+ cksum_valid = false;
+ add_dirty_rect(x, y, w, h);
+ }
+
+ /* FIXME: undraw mouse only if the draw rect intersects with the mouse rect */
+ if (_mouse_drawn)
+ undraw_mouse();
- CreatePushButtonControl(aboutWin,&pushButtonRect,CFSTR("OK"),&controlRef);
- SetWindowDefaultButton(aboutWin,controlRef);
- controlID.id = 'okay';
- SetControlID(controlRef,&controlID);
- AutoEmbedControl(controlRef,aboutWin);
-
- InstallWindowEventHandler(aboutWin, NewEventHandlerUPP((EventHandlerProcPtr) aboutEventHandler),
- GetEventTypeCount(dialogEvents),dialogEvents,aboutWin,NULL);
- ShowWindow(aboutWin);
- osError = RunAppModalLoopForWindow(aboutWin);
+ byte *dst = (byte*)buf + y * SCREEN_WIDTH + x;
+ do {
+ memcpy(dst, buf, w);
+ dst += SCREEN_WIDTH;
+ buf += pitch;
+ } while(--h);
}
-ControlRef radioGroupRef, musicVolumeSlider, masterVolumeSlider;
+void OSystem_MAC::add_dirty_rect(int x, int y, int w, int h) {
+ if (force_full)
+ return;
-OSStatus prefsEventHandler(EventHandlerCallRef eventHandlerCallRef,EventRef eventRef,
- void *userData)
-{
- OSStatus result = eventNotHandledErr;
- UInt32 eventClass;
- UInt32 eventKind;
- ControlRef controlRef;
- ControlID controlID;
+ if (num_dirty_rects == NUM_DIRTY_RECT)
+ force_full = true;
+ else {
+ Rect *r = &dirty_rect_list[num_dirty_rects++];
+
+ /* Update the dirty region by 1 pixel for graphics drivers
+ * that "smear" the screen */
+ if (_mode_flags & DF_UPDATE_EXPAND_1_PIXEL) {
+ x--;
+ y--;
+ w+=2;
+ h+=2;
+ }
- eventClass = GetEventClass(eventRef);
- eventKind = GetEventKind(eventRef);
+ /* clip */
+ if (x<0) { w+=x; x=0; }
+ if (y<0) { h+=y; y=0; }
+ if (w>=SCREEN_WIDTH-x) { w=SCREEN_WIDTH-x; }
+ if (h>=SCREEN_HEIGHT-y) { h=SCREEN_HEIGHT-y; }
+
+ if (_internal_scaling != 1) {
+ x *= _internal_scaling;
+ y *= _internal_scaling;
+ w *= _internal_scaling;
+ h *= _internal_scaling;
+ }
- if(eventClass == kEventClassControl)
- {
- if(eventKind == kEventControlHit)
- {
- GetEventParameter(eventRef,kEventParamDirectObject,typeControlRef,NULL,
- sizeof(ControlRef),NULL,&controlRef);
+ r->left = x;
+ r->top = y;
+ r->right = x + w;
+ r->bottom = y + h;
+ }
+}
- GetControlID(controlRef,&controlID);
- if(controlID.id == 'okay')
- {
- scumm->_noSubtitles = (Boolean)!GetControlValue(checkBoxControlRef);
- short scale = GetControlValue(radioGroupRef);
- if(scale != scumm->_scale)
- wm->ChangeScaling(scale);
- short music_vol = GetControlValue(musicVolumeSlider);
- if(music_vol != sound.get_music_volume())
- sound.set_music_volume(music_vol);
- short master_vol = GetControlValue(masterVolumeSlider);
- if(master_vol != sound.get_master_volume())
- sound.set_master_volume(master_vol);
- QuitAppModalLoopForWindow((WindowRef)userData);
- DisposeWindow((WindowRef)userData);
- result = noErr;
- }
- }
- }
+#define ROL(a,n) a = (a<<(n)) | (a>>(32-(n)))
+#define DOLINE(x) a ^= ((uint32*)buf)[0+(x)*(SCREEN_WIDTH/4)]; b ^= ((uint32*)buf)[1+(x)*(SCREEN_WIDTH/4)]
+void OSystem_MAC::mk_checksums(const byte *buf) {
+ uint32 *sums = dirty_checksums;
+ uint x,y;
+
+ /* the 8x8 blocks in buf are enumerated starting in the top left corner and
+ * reading each line at a time from left to right */
+ for(y=0; y!=SCREEN_HEIGHT/8; y++,buf+=SCREEN_WIDTH*(8-1))
+ for(x=0; x!=SCREEN_WIDTH/8; x++,buf+=8) {
+ uint32 a = x;
+ uint32 b = y;
+
+ DOLINE(0); ROL(a,13); ROL(b,11);
+ DOLINE(2); ROL(a,13); ROL(b,11);
+ DOLINE(4); ROL(a,13); ROL(b,11);
+ DOLINE(6); ROL(a,13); ROL(b,11);
+
+ a*=0xDEADBEEF;
+ b*=0xBAADF00D;
+
+ DOLINE(1); ROL(a,13); ROL(b,11);
+ DOLINE(3); ROL(a,13); ROL(b,11);
+ DOLINE(5); ROL(a,13); ROL(b,11);
+ DOLINE(7); ROL(a,13); ROL(b,11);
+
+ /* output the checksum for this block */
+ *sums++=a+b;
+ }
}
+#undef DOLINE
+#undef ROL
-void Preferences()
-{
- WindowRef prefsWin;
- OSStatus osError = noErr;
- Rect rect = { 0,0,210,300 };
- Rect okButtonRect;
- ControlID controlID;
- ControlRef controlRef;
- EventTypeSpec dialogEvents[] = { kEventClassControl, kEventControlHit };
-
- osError = CreateNewWindow(kMovableModalWindowClass,kWindowStandardHandlerAttribute,&rect, &prefsWin);
- SetWTitle(prefsWin, "\pPreferences");
- RepositionWindow(prefsWin,FrontWindow(),kWindowAlertPositionOnMainScreen);
- SetThemeWindowBackground(prefsWin,kThemeBrushDialogBackgroundActive,false);
- CreateRootControl(prefsWin,&controlRef);
-
- SetRect(&rect, 5, 5, 150, 21);
-
- CreateStaticTextControl(prefsWin, &rect, CFSTR("ScummVM Preferences"), NULL, &controlRef);
- AutoEmbedControl(controlRef, prefsWin);
-
- SetRect(&okButtonRect, 225, 180, 295, 200);
-
- CreatePushButtonControl(prefsWin,&okButtonRect,CFSTR("OK"),&controlRef);
- SetWindowDefaultButton(prefsWin,controlRef);
- controlID.id = 'okay';
- SetControlID(controlRef,&controlID);
- AutoEmbedControl(controlRef,prefsWin);
-
- SetRect(&rect, 150, 35, 260, 51);
-
- CreateCheckBoxControl(prefsWin,&rect, CFSTR("Subtitles"), 1, true, &checkBoxControlRef);
- AutoEmbedControl(checkBoxControlRef, prefsWin);
-
- if(scumm->_noSubtitles)
- SetControlValue(checkBoxControlRef, false);
-
- OffsetRect(&rect, 0, 20);
-
- CreateCheckBoxControl(prefsWin,&rect, CFSTR("Fullscreen"), 0, true, &controlRef);
- AutoEmbedControl(controlRef, prefsWin);
- DeactivateControl(controlRef);
-
- Rect RadioGroupRect;
- SetRect(&RadioGroupRect, 5, 35, 120, 100);
- CreateRadioGroupControl(prefsWin, &RadioGroupRect, &radioGroupRef);
- AutoEmbedControl(radioGroupRef, prefsWin);
-
- ControlRef radioButton;
-
- Rect RadioButtonRect;
- SetRect(&RadioButtonRect, 5, 35, 120, 51);
- CreateRadioButtonControl(prefsWin, &RadioButtonRect, CFSTR("Scaling 1x"), 0, true, &radioButton);
- AutoEmbedControl(radioButton, prefsWin);
-
- OffsetRect(&RadioButtonRect, 0, 20);
- CreateRadioButtonControl(prefsWin, &RadioButtonRect, CFSTR("Scaling 2x"), 0, true, &radioButton);
- AutoEmbedControl(radioButton, prefsWin);
-
- OffsetRect(&RadioButtonRect, 0, 20);
- CreateRadioButtonControl(prefsWin, &RadioButtonRect, CFSTR("Scaling 3x"), 0, true, &radioButton);
- AutoEmbedControl(radioButton, prefsWin);
-
- SetControlValue(radioGroupRef, scumm->_scale);
-
- SetRect(&rect, 5, 110, 175, 146);
-
- CreateSliderControl(prefsWin, &rect, sound.get_music_volume(), 1, 100,
- kControlSliderPointsDownOrRight, 10, false, NULL, &musicVolumeSlider);
- AutoEmbedControl(musicVolumeSlider, prefsWin);
-
- OffsetRect(&rect, 0, 36);
-
- CreateSliderControl(prefsWin, &rect, sound.get_master_volume(), 1, 100,
- kControlSliderPointsDownOrRight, 10, false, NULL, &masterVolumeSlider);
- AutoEmbedControl(masterVolumeSlider, prefsWin);
-
- OffsetRect(&rect, 180, -36);
-
- CreateStaticTextControl(prefsWin, &rect, CFSTR("Music Volume"), NULL, &controlRef);
- AutoEmbedControl(controlRef, prefsWin);
+
+void OSystem_MAC::add_dirty_rgn_auto(const byte *buf) {
+ assert( ((uint32)buf & 3) == 0);
- OffsetRect(&rect, 0, 36);
-
- CreateStaticTextControl(prefsWin, &rect, CFSTR("Master Volume"), NULL, &controlRef);
- AutoEmbedControl(controlRef, prefsWin);
-
- InstallWindowEventHandler(prefsWin, NewEventHandlerUPP((EventHandlerProcPtr) prefsEventHandler),
- GetEventTypeCount(dialogEvents),dialogEvents,prefsWin,NULL);
- ShowWindow(prefsWin);
- osError = RunAppModalLoopForWindow(prefsWin);
-}
+ /* generate a table of the checksums */
+ mk_checksums(buf);
-/* FIXME: CD Music Stubs */
-void cd_playtrack(int track, int offset, int delay) {;}
-void cd_play(Scumm *s, int track, int num_loops, int start_frame, int end_frame) {;}
-void cd_stop() {;}
-int cd_is_running() {return 0;}
+if (!cksum_valid) {
+ force_full = true;
+ cksum_valid = true;
+ }
-void launcherLoop() {
- /* No launcher an Mac yet, probably there won't ever be one, as */
- /* there is a nice Mac-like Launcher already. */
+ /* go through the checksum list, compare it with the previous checksums,
+ and add all dirty rectangles to a list. try to combine small rectangles
+ into bigger ones in a simple way */
+ if (!force_full) {
+ uint x,y,w;
+ uint32 *ck = dirty_checksums;
+
+ for(y=0; y!=SCREEN_HEIGHT/8; y++) {
+ for(x=0; x!=SCREEN_WIDTH/8; x++,ck++) {
+ if (ck[0] != ck[CKSUM_NUM]) {
+ /* found a dirty 8x8 block, now go as far to the right as possible,
+ and at the same time, unmark the dirty status by setting old to new. */
+ w=0;
+ do {
+ ck[w+CKSUM_NUM] = ck[w];
+ w++;
+ } while (x+w != SCREEN_WIDTH/8 && ck[w] != ck[w+CKSUM_NUM]);
+
+ add_dirty_rect(x*8, y*8, w*8, 8);
+
+ if (force_full)
+ goto get_out;
+ }
+ }
+ }
+ } else {
+ get_out:;
+ /* Copy old checksums to new */
+ memcpy(dirty_checksums + CKSUM_NUM, dirty_checksums, CKSUM_NUM * sizeof(uint32));
+ }
}
-void BoxTest(int num) {
-}
+void OSystem_MAC::update_screen() {
+#if 0
+ /* First make sure the mouse is drawn, if it should be drawn. */
+ draw_mouse();
-void setShakePos(Scumm *s, int shake_pos) {}
+ if (_palette_changed_last != 0) {
+ //warning("MAC: Palette should be uploaded!");/* FIXME: Add Palette changing code */
+
+ /*GDevice **odisplay;
+ odisplay = GetGDevice();
+ SetGDevice(GetMainDevice());
+ SetEntries(0, (**pal).ctSize, (ColorSpec *)&(**pal).ctTable);
+ SetGDevice(odisplay);*/
+
+ /*_palette_changed_last = 0;
+ if (_mode_flags & DF_FORCE_FULL_ON_PALETTE)
+ */force_full = true;
+ }
-void drawMouse(int xdraw, int ydraw, int w, int h, byte *buf, bool visible)
-{
- int x, y;
- byte *mask, *src, *dst;
- byte color;
- Point mouse;
- GrafPtr oldPort;
- Rect r, r2;
+ /* force a full redraw, accomplish that by adding one big rect to the dirty
+ * rect list */
+ if (force_full) {
+ num_dirty_rects = 1;
+
+ dirty_rect_list[0].left = 0;
+ dirty_rect_list[0].top = 0;
+ dirty_rect_list[0].right = SCREEN_WIDTH;
+ dirty_rect_list[0].bottom = SCREEN_HEIGHT;
+ }
- if(visible)
+ if (num_dirty_rects > 0)
{
- GWorldPtr gw, gw2;
-
- src = buf;
- mask = (byte*)malloc(sizeof(byte) * w * h);
- dst = mask;
- for(y = 0; y < h; y++, dst += w, src += w)
- {
- if((uint)y < h)
- {
- for(x = 0; x < w; x++)
- {
- if((uint)x < w)
- {
- if(src[x] != 0xFF)
- dst[x] = 0xFF;
- else
- dst[x] = 0x00;
- }
+ Rect *r;
+ uint32 srcPitch, dstPitch;
+ Rect *last_rect = dirty_rect_list + num_dirty_rects;
+
+ /* Convert appropriate parts of the image into 16bpp */
+ if ((_mode_flags & DF_REAL_8BIT) == 0) {
+ Rect dst;
+ for(r=dirty_rect_list; r!=last_rect; ++r) {
+ dst = *r;
+ dst.left++;
+ dst.top++;
+ dst.right++;
+ dst.bottom++;
+ }
+ }
+
+ /*srcPitch = sdl_tmpscreen->pitch;
+ dstPitch = sdl_hwscreen->pitch;*/
+
+ if ((_mode_flags & DF_REAL_8BIT) == 0) {
+ for(r=dirty_rect_list; r!=last_rect; ++r) {
+ register int dst_y = r->y + _current_shake_pos;
+ register int dst_h = 0;
+ if (dst_y < SCREEN_HEIGHT) {
+ dst_h = r->h;
+ if (dst_h > SCREEN_HEIGHT - dst_y)
+ dst_h = SCREEN_HEIGHT - dst_y;
+
+ r->x <<= 1;
+ dst_y <<= 1;
+
+ _sai_func((byte*)sdl_tmpscreen->pixels + (r->x+2) + (r->y+1)*srcPitch, srcPitch, NULL,
+ (byte*)sdl_hwscreen->pixels + r->x*scaling + dst_y*dstPitch, dstPitch, r->w, dst_h);
+ }
+
+ r->y = dst_y;
+ r->w <<= 1;
+ r->h = dst_h << 1;
+ }
+ } else {
+ for(r=dirty_rect_list; r!=last_rect; ++r) {
+ register int dst_y = r->y + _current_shake_pos;
+ register int dst_h = 0;
+ if (dst_y < SCREEN_HEIGHT) {
+ dst_h = r->h;
+ if (dst_h > SCREEN_HEIGHT - dst_y)
+ dst_h = SCREEN_HEIGHT - dst_y;
+
+ dst_y *= scaling;
+
+ _sai_func((byte*)sdl_tmpscreen->pixels + r->x + r->y*srcPitch, srcPitch, NULL,
+ (byte*)sdl_hwscreen->pixels + r->x*scaling + dst_y*dstPitch, dstPitch, r->w, dst_h);
}
+
+ r->x *= scaling;
+ r->y = dst_y;
+ r->w *= scaling;
+ r->h = dst_h * scaling;
}
}
+
+ if (force_full) {
+ dirty_rect_list[0].y = 0;
+ dirty_rect_list[0].h = SCREEN_HEIGHT * scaling;
+ }
+ }
+
+ /*if(_mode_flags & DF_2xSAI)
+ {
+ Rect *r;
+ uint32 area = 0;
+
+ Rect *dr = dirty_rect_list + num_dirty_rects;
- SetRect(&r, 0, 0, w, h);
+ for(r = dirty_rect_list; r != dr; r++)
+ {
+ GWorldPtr gw;
+ Rect rec;
+ SetRect(&rec, 0, 0, 320, 200);
+ NewGWorldFromPtr(&gw, 16, &rec, NULL, NULL, 0, (char*)_tmp_buf, rec.right);
+ CopyBits(GetPortBitMapForCopyBits(gw), GetPortBitMapForCopyBits(screenBuf),
+ r, r, srcCopy, 0L);
+ }
- NewGWorldFromPtr(&gw, 8, &r, wm->pal, nil, 0, (char *)buf, w);
- NewGWorldFromPtr(&gw2, 8, &r, NULL, nil, 0, (char *)mask, w);
- SetRect(&r2, (s->mouse.x - w / 2) * s->_scale, (s->mouse.y - h / 2) * s->_scale,
- (s->mouse.x + w / 2) * s->_scale, (s->mouse.y + h / 2) * s->_scale);
- CopyMask(GetPortBitMapForCopyBits(gw), GetPortBitMapForCopyBits(gw2),
- GetPortBitMapForCopyBits(GetWindowPort(wm->wPtr)),
- &r, &r, &r2);
+ for(r = dirty_rect_list; r != dr; r++)
+ {
+ _sai_func((byte*)_tmp_buf + r->left * 2 + r->top * 640, 640, NULL,
+ (byte*)_sai_buf + r->left * 4 + r->top * 640 * 4, 640 * 2,
+ r->right - r->left, r->bottom - r->top);
+
+ area += (r->right - r->left) * (r->bottom - r->top);
+
+ r->left <<= 1;
+ r->right <<= 1;
+ r->top <<= 1;
+ r->bottom <<= 1;
+ }
+ }*/
+
+ update_rects();
+ //blit_to_screen();
+
+ num_dirty_rects = 0;
+
+#endif
+}
+
+bool OSystem_MAC::show_mouse(bool visible) {
+ if (_mouse_visible == visible)
+ return visible;
+
+ bool last = _mouse_visible;
+ _mouse_visible = visible;
+
+ if (visible)
+ draw_mouse();
+ else
+ undraw_mouse();
+
+ return last;
+}
+
+void OSystem_MAC::set_mouse_pos(int x, int y) {
+ if (x != _ms_cur.x || y != _ms_cur.y) {
+ _ms_cur.x = x;
+ _ms_cur.y = y;
+ undraw_mouse();
}
}
+
+void OSystem_MAC::set_mouse_cursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y) {
+ _ms_cur.w = w;
+ _ms_cur.h = h;
-void InitMacStuff()
-{
- InitCursor();
+ _ms_hotspot_x = hotspot_x;
+ _ms_hotspot_y = hotspot_y;
+
+ _ms_buf = (byte*)buf;
+
+ undraw_mouse();
+}
- SIOUXSettings.autocloseonquit = true;
- SIOUXSettings.asktosaveonclose = false;
- SIOUXSettings.showstatusline = false;
- SIOUXSettings.fontsize = 9;
- GetFNum("\pMonaco",&SIOUXSettings.fontid);
- SIOUXSettings.standalone = false;
- SIOUXSettings.setupmenus = false;
- SIOUXSettings.toppixel = 40;
- SIOUXSettings.leftpixel = 5;
+void OSystem_MAC::set_shake_pos(int shake_pos) {
+ /*int old_shake_pos = _current_shake_pos;
+ int dirty_height, dirty_blackheight;
+ int dirty_top, dirty_blacktop;
+
+ if (shake_pos != old_shake_pos) {
+ _current_shake_pos = shake_pos;
+ force_full = true;
+
+ /* Old shake pos was current_shake_pos, new is shake_pos.
+ * Move the screen up or down to account for the change.
+ */
+ //SDL_Rect dstr = { 0, shake_pos*scaling, 320*scaling, 200*scaling };
+ //SDL_Rect srcr = { 0, old_shake_pos*scaling, 320*scaling, 200*scaling };
+ //SDL_BlitSurface(sdl_screen, &srcr, sdl_screen, &dstr);
+ /* Rect srcr, dstr;
+
+ SetRect(&srcr, 0, old_shake_pos * scaling, 320 * scaling, 200 * scaling);
+ SetRect(&dstr, 0, shake_pos * scaling, 320 * scaling, 200 * scaling);
+
+ CopyBits(GetPortBitMapForCopyBits(screenBuf), GetPortBitMapForCopyBits(GetWindowPort(wref)),
+ &srcr, &dstr, srcCopy, 0L);
+
+ /* Refresh either the upper part of the screen,
+ * or the lower part */
+ /* if (shake_pos > old_shake_pos) {
+ dirty_height = MIN(shake_pos, 0) - MIN(old_shake_pos, 0);
+ dirty_top = -MIN(shake_pos, 0);
+ dirty_blackheight = MAX(shake_pos, 0) - MAX(old_shake_pos, 0);
+ dirty_blacktop = MAX(old_shake_pos, 0);
+ } else {
+ dirty_height = MAX(old_shake_pos, 0) - MAX(shake_pos, 0);
+ dirty_top = 200 - MAX(old_shake_pos, 0);
+ dirty_blackheight = MIN(old_shake_pos, 0) - MIN(shake_pos, 0);
+ dirty_blacktop = 200 + MIN(shake_pos, 0);
+ }
+
+ /* Fill the dirty area with blackness or the scumm image */
+ //SDL_Rect blackrect = {0, dirty_blacktop*scaling, 320*scaling, dirty_blackheight*scaling};
+ //SDL_FillRect(sdl_screen, &blackrect, 0);
+
+ /* FIXME: Um, screen seems to glitch since this
+ 'not needed' function was removed */
+ //g_scumm->redrawLines(dirty_top, dirty_top + dirty_height);
+/* }*/
}
+
+uint32 OSystem_MAC::get_msecs() {
+ UnsignedWide ms;
-void InitScummStuff()
-{
- detector.detectMain(2, &gameTitle);
+ Microseconds(&ms);
+ return(ms.lo / 1000);
+}
- if(detector._features & GF_OLD256)
- scumm = new Scumm_v3;
- else
- if(detector._features & GF_SMALL_HEADER) // this force loomCD as v4
- scumm = new Scumm_v4;
- else
- if(detector._features & GF_AFTER_V7)
- scumm = new Scumm_v7;
- else
- if(detector._features & GF_AFTER_V6) // this force SamnmaxCD as v6
- scumm = new Scumm_v6;
- else
- scumm = new Scumm_v5;
-
- scumm->_fullScreen = detector._fullScreen;
- scumm->_debugMode = detector._debugMode;
- scumm->_bootParam = detector._bootParam;
- scumm->_scale = detector._scale;
- scumm->_gameDataPath = detector._gameDataPath;
- scumm->_gameTempo = detector._gameTempo;
- scumm->_videoMode = detector._videoMode;
- scumm->_exe_name = detector._exe_name;
- scumm->_gameId = detector._gameId;
- scumm->_gameText = detector._gameText;
- scumm->_features = detector._features;
- scumm->_soundCardType = detector._soundCardType;
- scumm->_noSubtitles = detector._noSubtitles;
- scumm->_midi_driver = detector._midi_driver;
- scumm->_cdrom = detector._cdrom;
-
- scumm->delta=6;
- scumm->_gui = &gui;
- sound.initialize(scumm,&snd_driv);
-
- scumm->delta=0;
- scumm->_system = &_system;
+void OSystem_MAC::delay_msecs(uint msecs) {
+ uint32 start = get_msecs();
+ Event dummy;
+
+ do {
+ poll_event(&dummy); /* Do something to avoid CPU lock */
+ if(get_msecs() >= start + msecs)
+ break;
+ } while (1);
+}
+
+void *OSystem_MAC::create_thread(ThreadProc *proc, void *param) {
+ warning("MAC: Stub create_thread()");
+ //NewThread(kCooperativeThread, (void*)proc, param, 0L, kCreateIfNeeded, NULL, NULL);
}
-void setWindowName(Scumm *scumm)
+int mapKey(int key, byte code, byte mod)
{
- char buf[512], *gameName;
+ switch(code) {
+ case 0x35:
+ key = 27;
+ break;
+ case 0x31:
+ key = 32;
+ break;
+ case 0x60:
+ key = 601;
+ break;
+ }
- sprintf(buf, "ScummVM - %s", gameName = detector.getGameName());
- free(gameName);
- StringPtr gameText = CToPascal(buf);
- SetWTitle(wm->wPtr, gameText);
+ return key;
}
+
+bool OSystem_MAC::poll_event(Event *event)
+{
+ EventRef theEvent;
+ EventTargetRef theTarget;
+ OSStatus theErr;
+
+ OSStatus result = eventNotHandledErr;
+ HICommand command;
+ Point mouse;
-UInt8 *buffer[2];
-CmpSoundHeader header;
-SndChannelPtr channel;
-int size;
+ theTarget = GetEventDispatcherTarget();
+ theErr = ReceiveNextEvent(GetEventTypeCount(kCmdEvents), kCmdEvents, kEventDurationNoWait,true, &theEvent);
+
+ GetEventParameter( theEvent, kEventParamDirectObject, typeHICommand, NULL,
+ sizeof( HICommand ), NULL, &command );
+
+ switch(GetEventClass(theEvent))
+ {
+ case kEventClassWindow:
+ switch(GetEventKind(theEvent))
+ {
+ case kEventWindowDrawContent:
+ break;
+
+ case kEventWindowHandleContentClick:
+ EventMouseButton btn;
+
+ GetEventParameter(theEvent, kEventParamMouseButton, typeMouseButton, NULL,
+ sizeof(EventMouseButton), NULL, &btn);
+
+ if(btn == kEventMouseButtonPrimary)
+ event->event_code = EVENT_RBUTTONDOWN;
+ else if(btn == kEventMouseButtonSecondary)
+ event->event_code = EVENT_LBUTTONDOWN;
+
+ debug(1, "Mouse down!");
+
+ if(wref != FrontWindow())
+ {
+ ActivateWindow(wref, true);
+ BringToFront(wref);
+ }
+ return true;
+ break;
+
+ case kEventWindowClose:
+ quit();
+ break;
+ }
+ break;
+
+ case kEventClassCommand:
+ switch(command.commandID)
+ {
+ case kNewGameCmd:
+
+ break;
+
+ case kOpenGameCmd:
+ //scumm->_saveLoadSlot = 0;
+ //scumm->_saveLoadFlag = 2;
+ break;
+
+ case kSaveGameCmd:
+ //scumm->_saveLoadSlot = 0;
+ //sprintf(scumm->_saveLoadName, "Quicksave %d", scumm->_saveLoadSlot);
+ //scumm->_saveLoadFlag = 1;
+ break;
+
+ case kQuitCmd:
+ quit();
+ break;
+
+ case kPrefsCmd:
+ //Preferences();
+ break;
+
+ case kAboutCmd:
+ //About();
+ break;
+ }
+ break;
+
+ case kEventClassKeyboard:
+ if(GetEventKind(theEvent) == kEventRawKeyDown)
+ {
+ char key;
+ UInt32 mod, code;
+
+ GetEventParameter(theEvent, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &code);
+ GetEventParameter(theEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &key);
+ GetEventParameter(theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &mod);
+
+ event->event_code = EVENT_KEYDOWN;
+ event->kbd.keycode = code;
+ event->kbd.ascii = mapKey(key, code, mod);
+ debug(1, "Key down: %c", event->kbd.ascii);
+ return true;
+ }
+ break;
+
+ case kEventClassMouse:
+ EventMouseButton btn;
+ Rect winRect;
+
+ switch(GetEventKind(theEvent))
+ {
+ case kEventMouseDown:
+ WindowRef theWin;
+
+ GetEventParameter(theEvent, kEventParamDirectObject, typeWindowRef, NULL, sizeof(WindowRef),
+ NULL, &theWin);
+ if(theWin != FrontWindow())
+ {
+ ActivateWindow(theWin, true);
+ BringToFront(theWin);
+ }
+
+ GetEventParameter(theEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &mouse);
+
+ GetWindowBounds(wref, kWindowContentRgn, &winRect);
+ if(PtInRect(mouse, &winRect))
+ {
+ GetEventParameter(theEvent, kEventParamMouseButton, typeMouseButton, NULL,
+ sizeof(EventMouseButton), NULL, &btn);
+
+ if(btn == kEventMouseButtonPrimary)
+ event->event_code = EVENT_RBUTTONDOWN;
+ else if(btn == kEventMouseButtonSecondary)
+ event->event_code = EVENT_LBUTTONDOWN;
+
+ debug(1, "Mouse down!");
+ }
+ break;
+
+ case kEventMouseUp:
+
+ GetEventParameter(theEvent, kEventParamMouseButton, typeMouseButton, NULL,
+ sizeof(EventMouseButton), NULL, &btn);
+
+ if(btn == kEventMouseButtonPrimary)
+ event->event_code = EVENT_RBUTTONUP;
+ else if(btn == kEventMouseButtonSecondary)
+ event->event_code = EVENT_LBUTTONUP;
+
+ debug(1, "Mouse up!");
+
+ return true;
+ break;
+
+ case kEventMouseMoved:
+ GetEventParameter(theEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &mouse);
+
+ GetWindowBounds(wref, kWindowContentRgn, &winRect);
+ if(PtInRect(mouse, &winRect))
+ {
+ CGrafPtr oldPort;
+
+ GetPort(&oldPort);
+ SetPortWindowPort(wref);
+ GlobalToLocal(&mouse);
+
+ event->event_code = EVENT_MOUSEMOVE;
+ event->mouse.x = mouse.h / scaling;
+ event->mouse.y = mouse.v / scaling;
+
+ //scumm->mouse.x = mouse.h/wm->scale;
+ //scumm->mouse.y = mouse.v/wm->scale;
+ }
+ Point offset = {0, 0};
+ ShieldCursor(&winRect, offset);
+ return true;
+ break;
+ }
+ break;
+ }
+
+ if(theErr == noErr && theEvent != NULL) {
+ SendEventToEventTarget (theEvent, theTarget);
+ ReleaseEvent(theEvent);
+ }
+}
-void fill_sound(uint8 *stream, int len) {
- scumm->mixWaves((int16*)stream, len>>1);
+pascal void sound_callback(SndChannel *chan, SndCommand *cmd_passed)
+{
+ OSystem_MAC* syst = (OSystem_MAC*)chan->userInfo;
+ syst->sound_callback(chan, cmd_passed);
}
-pascal void callBackProc (SndChannel *chan, SndCommand *cmd_passed)
+void OSystem_MAC::sound_callback(SndChannel *chan, SndCommand *cmd_passed)
{
UInt32 fill_me, play_me;
SndCommand cmd;
@@ -1077,7 +1366,8 @@ pascal void callBackProc (SndChannel *chan, SndCommand *cmd_passed)
SndDoCommand(chan, &cmd, 0);
memset(buffer[fill_me], 0, size);
- fill_sound(buffer[fill_me], size);
+ //sndProc(parameter, buffer[fill_me], size);
+ //SoundMixer::on_generate_samples(parameter, buffer[fill_me], size);
cmd.cmd = callBackCmd;
cmd.param1 = 0;
@@ -1086,13 +1376,13 @@ pascal void callBackProc (SndChannel *chan, SndCommand *cmd_passed)
SndDoCommand(chan, &cmd, 0);
}
-void InitSound()
+bool OSystem_MAC::set_sound_proc(void *param, SoundProc *proc, byte format)
{
SndCallBackUPP callback;
int sample_size;
memset(&header, 0, sizeof(header));
- callback = NewSndCallBackUPP(callBackProc);
+ callback = NewSndCallBackUPP(::sound_callback);
size = ((0x9010 & 0xFF) / 8) * 2048;
sample_size = size / 2048 * 8;
header.numChannels = 1;
@@ -1109,56 +1399,402 @@ void InitSound()
channel = (SndChannelPtr)malloc(sizeof(*channel));
channel->qLength = 128;
+ channel->userInfo = (long)this;
SndNewChannel(&channel, sampledSynth, initMono, callback);
SndCommand cmd;
cmd.cmd = callBackCmd;
cmd.param2 = 0;
SndDoCommand(channel, &cmd, 0);
+
+ sndProc = proc;
+ parameter = param;
+
+ return true;
}
-void main(void)
+
+/* retrieve the 320x200 bitmap currently being displayed */
+void OSystem_MAC::get_320x200_image(byte *buf)
{
- InitMacStuff();
- SelectGame();
+ /* make sure the mouse is gone */
+ undraw_mouse();
- wm->_vgabuf = (byte*)calloc(320,200);
+ byte *src;
+ int x,y;
+
+ switch(_internal_scaling) {
+ case 1:
+ memcpy(buf, _gfx_buf, 320*200);
+ break;
+
+ case 2:
+ src = (byte*)_gfx_buf;
+ for(y=0; y!=200; y++) {
+ for(x=0; x!=320; x++)
+ buf[x] = src[x*2];
+ buf += 320;
+ src += 320 * 2 * 2;
+ }
+ break;
+
+ case 3:
+ src = (byte*)_gfx_buf;
+ for(y=0; y!=200; y++) {
+ for(x=0; x!=320; x++)
+ buf[x] = src[x*3];
+ buf += 320;
+ src += 320 * 3 * 3;
+ }
+ break;
+ }
+}
+
+void OSystem_MAC::hotswap_gfx_mode()
+{
+ /* hmm, need to allocate a 320x200 bitmap
+ * which will contain the "backup" of the screen during the change.
+ * then draw that to the new screen right after it's setup.
+ */
- InitScummStuff();
+ byte *bak_mem = (byte*)malloc(320*200);
+
+ get_320x200_image(bak_mem);
+
+ unload_gfx_mode();
+ load_gfx_mode();
+
+ force_full = true;
+
+ /* reset palette ? */
+ pal = (CTabHandle)NewHandleClear(sizeof(ColorTable) + 255 * sizeof(ColorSpec));
+ (*pal)->ctFlags = 0;
+ (*pal)->ctSize = 255;
- scumm->launch();
+ /* blit image */
+ copy_rect(bak_mem, 320, 0, 0, 320, 200);
+ free(bak_mem);
+
+ update_screen();
+}
+
+uint32 OSystem_MAC::property(int param, Property *value) {
+ switch(param) {
+ case PROP_TOGGLE_FULLSCREEN:
+ _full_screen ^= true;
+ return 1;
+
+ case PROP_SET_WINDOW_CAPTION:
+ StringPtr gameText = CToPascal((char*)value->caption);
+ SetWTitle(wref, gameText);
+ return 1;
+
+ case PROP_OPEN_CD:
+ break;
+
+ case PROP_SET_GFX_MODE:
+ if(value->gfx_mode >= 7)
+ return 0;
+ _mode = value->gfx_mode;
+ hotswap_gfx_mode();
+ return 1;
+
+
+ case PROP_SHOW_DEFAULT_CURSOR:
+ break;
- gui.init(scumm);
+ case PROP_GET_SAMPLE_RATE:
+ return SAMPLES_PER_SEC;
+ break;
+ }
- setWindowName(scumm);
+ return 0;
+}
+
+void OSystem_MAC::quit() {
+ unload_gfx_mode();
+
+ QuitApplicationEventLoop();
+ ExitToShell();
+}
+
+void OSystem_MAC::draw_mouse() {
+ if (_mouse_drawn || !_mouse_visible)
+ return;
+ _mouse_drawn = true;
- InitSound();
+ const int ydraw = _ms_cur.y + _current_shake_pos - _ms_hotspot_y;
+ const int xdraw = _ms_cur.x - _ms_hotspot_x;
+ const int w = _ms_cur.w;
+ const int h = _ms_cur.h;
+ int x,y;
+ byte color;
+ byte *dst, *bak = _ms_backup;
+ byte *buf = _ms_buf;
+
+ _ms_old.w = w;
+ _ms_old.h = h;
+ _ms_old.x = xdraw;
+ _ms_old.y = ydraw;
- RunApplicationEventLoop();
+ byte *src;
+ if(_sai_func)
+ src = (byte*)_tmp_buf;
+ else
+ src = _gfx_buf;
+
+ switch(_internal_scaling) {
+ case 1:
+ dst = (byte *)src + ydraw * 320 + xdraw;
+
+ for (y = 0; y < h; y++, dst += 320, bak += MAX_MOUSE_W, buf += w) {
+ if ((uint) (ydraw + y) < 200) {
+ for (x = 0; x < w; x++) {
+ if ((uint) (xdraw + x) < 320) {
+ bak[x] = dst[x];
+ if ((color = buf[x]) != 0xFF) {
+ dst[x] = color;
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case 2:
+ dst = (byte *)src + ydraw * 640 * 2 + xdraw * 2;
+
+ for (y = 0; y < h; y++, dst += 640 * 2, bak += MAX_MOUSE_W * 2, buf += w) {
+ if ((uint) (ydraw + y) < 200) {
+ for (x = 0; x < w; x++) {
+ if ((uint) (xdraw + x) < 320) {
+ bak[x * 2] = dst[x * 2];
+ bak[x * 2 + 1] = dst[x * 2 + 1];
+ if ((color = buf[x]) != 0xFF) {
+ dst[x * 2] = color;
+ dst[x * 2 + 1] = color;
+ dst[x * 2 + 640] = color;
+ dst[x * 2 + 1 + 640] = color;
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case 3:
+ dst = (byte *)src + ydraw * 960 * 3 + xdraw * 3;
+
+ for (y = 0; y < h; y++, dst += 960 * 3, bak += MAX_MOUSE_W * 3, buf += w) {
+ if ((uint) (ydraw + y) < 200) {
+ for (x = 0; x < w; x++) {
+ if ((uint) (xdraw + x) < 320) {
+ bak[x * 3] = dst[x * 3];
+ bak[x * 3 + 1] = dst[x * 3 + 1];
+ bak[x * 3 + 2] = dst[x * 3 + 2];
+ if ((color = buf[x]) != 0xFF) {
+ dst[x * 3] = color;
+ dst[x * 3 + 1] = color;
+ dst[x * 3 + 2] = color;
+ dst[x * 3 + 960] = color;
+ dst[x * 3 + 1 + 960] = color;
+ dst[x * 3 + 2 + 960] = color;
+ dst[x * 3 + 960 + 960] = color;
+ dst[x * 3 + 1 + 960 + 960] = color;
+ dst[x * 3 + 2 + 960 + 960] = color;
+ }
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ add_dirty_rect(xdraw,ydraw,w,h);
+}
+
+void OSystem_MAC::undraw_mouse() {
+ if (!_mouse_drawn)
+ return;
+ _mouse_drawn = false;
+
+ byte *dst, *bak = _ms_backup;
+ byte *src;
+ const int old_mouse_x = _ms_old.x;
+ const int old_mouse_y = _ms_old.y;
+ const int old_mouse_w = _ms_old.w;
+ const int old_mouse_h = _ms_old.h;
+ int x,y;
+
+ if(_sai_func)
+ src = (byte*)_tmp_buf;
+ else
+ src = _gfx_buf;
- return;
+ switch(_internal_scaling) {
+ case 1:
+ dst = (byte *)src + old_mouse_y * 320 + old_mouse_x;
+
+ for (y = 0; y < old_mouse_h; y++, bak += MAX_MOUSE_W, dst += 320) {
+ if ((uint) (old_mouse_y + y) < 200) {
+ for (x = 0; x < old_mouse_w; x++) {
+ if ((uint) (old_mouse_x + x) < 320) {
+ dst[x] = bak[x];
+ }
+ }
+ }
+ }
+ break;
+
+ case 2:
+ dst = (byte *)src + old_mouse_y * 640 * 2 + old_mouse_x * 2;
+
+ for (y = 0; y < old_mouse_h; y++, bak += MAX_MOUSE_W * 2, dst += 640 * 2) {
+ if ((uint) (old_mouse_y + y) < 200) {
+ for (x = 0; x < old_mouse_w; x++) {
+ if ((uint) (old_mouse_x + x) < 320) {
+ dst[x * 2 + 640] = dst[x * 2] = bak[x * 2];
+ dst[x * 2 + 640 + 1] = dst[x * 2 + 1] = bak[x * 2 + 1];
+ }
+ }
+ }
+ }
+ break;
+
+ case 3:
+ dst = (byte *)src + old_mouse_y * 960 * 3 + old_mouse_x * 3;
+
+ for (y = 0; y < old_mouse_h; y++, bak += MAX_MOUSE_W * 3, dst += 960 * 3) {
+ if ((uint) (old_mouse_y + y) < 200) {
+ for (x = 0; x < old_mouse_w; x++) {
+ if ((uint) (old_mouse_x + x) < 320) {
+ dst[x * 3 + 960] = dst[x * 3 + 960 + 960] = dst[x * 3] =
+ bak[x * 3];
+ dst[x * 3 + 960 + 1] = dst[x * 3 + 960 + 960 + 1] =
+ dst[x * 3 + 1] = bak[x * 3 + 1];
+ dst[x * 3 + 960 + 2] = dst[x * 3 + 960 + 960 + 2] =
+ dst[x * 3 + 2] = bak[x * 3 + 2];
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ add_dirty_rect(old_mouse_x, old_mouse_y, old_mouse_w, old_mouse_h);
+}
+
+void OSystem_MAC::stop_cdrom() {
+}
+
+void OSystem_MAC::play_cdrom(int track, int num_loops, int start_frame, int end_frame) {
+ /* Reset sync count */
+ g_scumm->_vars[g_scumm->VAR_MI1_TIMER] = 0;
+}
+
+bool OSystem_MAC::poll_cdrom() {
+}
+
+void OSystem_MAC::update_cdrom() {
}
-OSystem::OSystem()
+
+
+/*************************************************************/
+/** Mac specific code ****************************************/
+void OSystem_MAC::set_scaling() {
+ Rect rectWin;
+ SetRect(&rectWin, 0, 0, 320 * scaling, 200 * scaling);
+ HideWindow(wref);
+ SetWindowBounds(wref, kWindowContentRgn, &rectWin);
+ RepositionWindow(wref, NULL, kWindowCenterOnMainScreen);
+ ShowWindow(wref);
+ blit_rect = rectWin;
+
+ if(_sai_func)
+ {
+ Rect r;
+
+ //SetRect(&r, 0, 0, 320, 240);
+ _sai_buf = (int16*)malloc((320 * 200) * 2 * sizeof(int16));
+
+ NewGWorldFromPtr(&screenBuf, 16, &blit_rect, NULL, nil, 0, (char *)_sai_buf, blit_rect.right);
+ }
+ else
+ {
+ _gfx_buf = (byte*)malloc((320 * 200) * scaling * sizeof(byte));
+ NewGWorldFromPtr(&screenBuf, 8, &blit_rect, pal, nil, 0, (char *)_gfx_buf, blit_rect.right);
+ }
+
+ //NewGWorldFromPtr(&screenBuf, 8, &blit_rect, pal, nil, 0, (char *)_gfx_buf, blit_rect.right);
+
+ //if(screenBuf != NULL)
+ // UpdateGWorld(&screenBuf, 8, &blit_rect, pal, NULL, NULL);
+}
+
+void OSystem_MAC::blit_to_screen()
{
- last_time = Time();
+ CopyBits(GetPortBitMapForCopyBits(screenBuf),
+ GetPortBitMapForCopyBits(GetWindowPort(wref)), &blit_rect, &blit_rect, srcCopy, 0L);
+}
+
+void OSystem_MAC::init_mac_stuff()
+{
+ Rect rectWin;
+
+
+ MenuRef AppleMenu = GetMenu(1000);
+ InsertMenu(AppleMenu, 0);
+ SetMenuItemCommandID(AppleMenu, 1, kAboutCmd);
+ MenuRef FileMenu = GetMenu(1001);
+ SetMenuItemCommandID(FileMenu, 1, kNewGameCmd);
+ SetMenuItemCommandID(FileMenu, 2, kOpenGameCmd);
+ SetMenuItemCommandID(FileMenu, 3, kSaveGameCmd);
+ SetMenuItemCommandID(FileMenu, 5, kQuitCmd);
+ DeleteMenuItems(FileMenu, CountMenuItems(FileMenu)-1, 2);
+ InsertMenu(FileMenu, 0);
+ MenuRef windMenu;
+ CreateStandardWindowMenu(0, &windMenu);
+ InsertMenu(windMenu, 0);
+ EnableMenuCommand(NULL, kPrefsCmd);
+ DrawMenuBar();
+
+ SetRect(&rectWin, 0, 0, 320, 200);
+ UInt32 WinAttrib = (kWindowCloseBoxAttribute | kWindowCollapseBoxAttribute |
+ kWindowInWindowMenuAttribute | kWindowStandardHandlerAttribute);
+
+ if(noErr != CreateNewWindow(kDocumentWindowClass, WinAttrib, &rectWin, &wref))
+ {
+ //Error("Couldn't create Window!");
+ }
+
+ RepositionWindow(wref, NULL, kWindowCenterOnMainScreen);
+
+ Str255 WindowTitle = "\pScummVM";
+ SetWTitle(wref, WindowTitle);
+
+ SetPortWindowPort(wref);
+ //ShowWindow(wref);
+
+ InstallStandardEventHandler(GetWindowEventTarget(wref));
+
+ //OSStatus err = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(QuitEventHandler), 0L, false);
+
+ blit_rect = rectWin;
+ pal = (CTabHandle)NewHandleClear(sizeof(ColorTable) + 255 * sizeof(ColorSpec));
+ (*pal)->ctFlags = 0;
+ (*pal)->ctSize = 255;
+ //NewGWorld(&screenBuf, 8, &blit_rect, 0, 0, 0);
}
-int OSystem::waitTick(int delta)
+void OSystem_MAC::update_rects()
{
- do
+ for(int i = 0; i < num_dirty_rects; i++)
{
- updateScreen(scumm);
- new_time = Time();
- waitForTimer(scumm, delta * 15 + last_time - new_time);
- last_time = Time();
- if(gui._active)
- {
- gui.loop(scumm);
- delta = 5;
- }
- sound.on_timer();
- } while(gui._active);
+ Rect rec = dirty_rect_list[i];
- return(delta);
+ CopyBits(GetPortBitMapForCopyBits(screenBuf),
+ GetPortBitMapForCopyBits(GetWindowPort(wref)),
+ &rec, &rec, srcCopy, 0L);
+ }
} \ No newline at end of file
diff --git a/mac/scummvm.mcp b/mac/scummvm.mcp
index 35a051e06f..f11c90083a 100644
--- a/mac/scummvm.mcp
+++ b/mac/scummvm.mcp
Binary files differ