Merge from AppleWin-Tom branch:

Consolidated Save-State & Advanced prop sheets (now all on Advanced)
Disable joystick emulation via mouse when mouse interface is enabled
Support shift-f9 to cycle backwards through video modes
Use DirectInput to get mouse delta (instead of absolute WM_MOUSEMOVE msg)
Support Ctrl-Left Mouse Button to show the Windows cursor (otherwise GEOS never allows mouse to leave window)
Fix for Blazing Paddles (mouse support)
This commit is contained in:
tomch 2008-05-17 23:20:33 +00:00
parent 11281e81f9
commit a2f0bc5775
13 changed files with 753 additions and 310 deletions

View File

@ -121,6 +121,8 @@ BEGIN
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,114,166,10
LTEXT "(Shift+Insert during emulation)",IDC_STATIC,89,166,94,8
CONTROL "Mouse interface in slot 4",IDC_MOUSE_IN_SLOT4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,128,106,10
CONTROL "Show crosshairs in window's frame",IDC_MOUSE_CROSSHAIR,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,142,159,10
END
IDD_PROPPAGE_SOUND DIALOGEX 0, 0, 210, 221
@ -142,22 +144,6 @@ BEGIN
CONTROL "Disable soundcards",IDC_SOUNDCARD_DISABLE,"Button",BS_AUTORADIOBUTTON | BS_NOTIFY,10,194,78,10
END
IDD_PROPPAGE_SAVESTATE DIALOG 0, 0, 210, 221
STYLE DS_SETFONT | WS_CHILD | WS_VISIBLE | WS_DISABLED | WS_CAPTION | WS_SYSMENU
CAPTION "Save State"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Save State file name:",IDC_STATIC,5,29,74,8
GROUPBOX "Save State Control",IDC_STATIC,5,74,200,73
CONTROL "Save State on exit",IDC_SAVESTATE_ON_EXIT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,85,74,10
PUSHBUTTON "Save State",IDC_SAVESTATE,16,102,85,15
PUSHBUTTON "Load State",IDC_LOADSTATE,16,124,85,15
EDITTEXT IDC_SAVESTATE_FILENAME,5,40,143,12,ES_AUTOHSCROLL
LTEXT "(F11 during emulation)",IDC_STATIC,110,105,74,8
LTEXT "(F12 during emulation)",IDC_STATIC,110,127,90,8
PUSHBUTTON "Browse...",IDC_SAVESTATE_BROWSE,154,39,50,14
END
IDD_PROPPAGE_DISK DIALOGEX 0, 0, 210, 221
STYLE DS_SETFONT | WS_CHILD | WS_VISIBLE | WS_DISABLED | WS_CAPTION | WS_SYSMENU
CAPTION "Disk"
@ -198,10 +184,19 @@ STYLE DS_SETFONT | WS_CHILD | WS_VISIBLE | WS_DISABLED | WS_CAPTION | WS_SYSMENU
CAPTION "Advanced"
FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN
LTEXT "&Clone:",-1,5,29,40,8
COMBOBOX IDC_CLONETYPE,45,27,100,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "&Clone:",IDC_STATIC,5,165,40,8
COMBOBOX IDC_CLONETYPE,45,163,100,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
CONTROL "The Freeze's non-autostart F8 rom (Apple ][ or ][+ only)",IDC_THE_FREEZES_F8_ROM_FW,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,206,182,10
LTEXT "Save State file name:",IDC_STATIC,5,12,74,8
GROUPBOX "Save State Control",IDC_STATIC,5,57,200,73
CONTROL "Save State on exit",IDC_SAVESTATE_ON_EXIT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,68,74,10
PUSHBUTTON "Save State",IDC_SAVESTATE,16,85,85,15
PUSHBUTTON "Load State",IDC_LOADSTATE,16,107,85,15
EDITTEXT IDC_SAVESTATE_FILENAME,5,23,143,12,ES_AUTOHSCROLL
LTEXT "(F11 during emulation)",IDC_STATIC,110,88,74,8
LTEXT "(F12 during emulation)",IDC_STATIC,110,110,90,8
PUSHBUTTON "Browse...",IDC_SAVESTATE_BROWSE,154,22,50,14
END

View File

@ -16,7 +16,6 @@
#define IDC_SLIDER_CPU_SPEED 111
#define IDD_PROPPAGE_SOUND 112
#define IDC_DISKTYPE 113
#define IDD_PROPPAGE_SAVESTATE 114
#define IDC_JOYSTICK1 115
#define IDD_PROPPAGE_DISK 116
#define IDC_BENCHMARK 117
@ -78,6 +77,7 @@
#define IDC_SCROLLLOCK_TOGGLE 1043
#define IDC_MOUSE_IN_SLOT4 1044
#define IDC_THE_FREEZES_F8_ROM_FW 1045
#define IDC_MOUSE_CROSSHAIR 1045
#define IDC_CLONETYPE 1046
#define IDM_EXIT 40001
#define IDM_HELP 40002

View File

@ -438,6 +438,8 @@ void LoadConfiguration ()
if(LOAD(TEXT(REGVALUE_MOUSE_IN_SLOT4), &dwTmp))
g_uMouseInSlot4 = dwTmp;
if(LOAD(TEXT(REGVALUE_MOUSE_CROSSHAIR), &dwTmp))
g_uMouseShowCrosshair = dwTmp;
g_Slot4 = g_uMouseInSlot4 ? CT_MouseInterface : CT_Mockingboard;
//
@ -675,7 +677,7 @@ int APIENTRY WinMain (HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
//-----
// Initialize COM - so we can use CoCreateInstance
// . NB. DSInit() & DirectInputInit are done when g_hFrameWindow is created (WM_CREATE)
// . NB. DSInit() & DIMouse::DirectInputInit are done when g_hFrameWindow is created (WM_CREATE)
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
bool bSysClkOK = SysClk_InitTimer();

View File

@ -82,6 +82,7 @@ enum AppMode_e
#define REGVALUE_PDL_YTRIM "PDL Y-Trim"
#define REGVALUE_SCROLLLOCK_TOGGLE "ScrollLock Toggle"
#define REGVALUE_MOUSE_IN_SLOT4 "Mouse in slot 4"
#define REGVALUE_MOUSE_CROSSHAIR "Mouse crosshair"
#define REGVALUE_THE_FREEZES_F8_ROM "The Freeze's F8 Rom"
#define REGVALUE_CLONETYPE "Clone Type"

View File

@ -33,23 +33,27 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#define ENABLE_MENU 0
// Magic numbers (used by FrameCreateWindow to calc width/height):
#define MAGICX 5 // 3D border between Apple window & Emulator's RHS buttons
#define MAGICY 5 // 3D border between Apple window & Title bar
#define VIEWPORTCX 560
#if ENABLE_MENU
#define VIEWPORTCY 400
#else
#define VIEWPORTCY 384
#endif
#define BUTTONX (VIEWPORTCX+(VIEWPORTX<<1))
#define BUTTONX (VIEWPORTCX + VIEWPORTX*2)
#define BUTTONY 0
#define BUTTONCX 45
#define BUTTONCY 45
#define FSVIEWPORTX (640-BUTTONCX-5-VIEWPORTCX)
#define FSVIEWPORTY ((480-VIEWPORTCY)>>1)
// NB. FSxxx = FullScreen xxx
#define FSVIEWPORTX (640-BUTTONCX-MAGICX-VIEWPORTCX)
#define FSVIEWPORTY ((480-VIEWPORTCY)/2)
#define FSBUTTONX (640-BUTTONCX)
#define FSBUTTONY (((480-VIEWPORTCY)>>1)-1)
#define FSBUTTONY (((480-VIEWPORTCY)/2)-1)
#define BUTTONS 8
static HBITMAP capsbitmap[2];
static HBITMAP diskbitmap[ NUM_DISK_STATUS ];
@ -75,16 +79,15 @@ static BOOL painting = 0;
static HFONT smallfont = (HFONT)0;
static HWND tooltipwindow = (HWND)0;
static BOOL usingcursor = 0;
static int viewportx = VIEWPORTX;
static int viewporty = VIEWPORTY;
static int viewportx = VIEWPORTX; // Default to Normal (non-FullScreen) mode
static int viewporty = VIEWPORTY; // Default to Normal (non-FullScreen) mode
static LPDIRECTDRAW directdraw = (LPDIRECTDRAW)0;
static LPDIRECTDRAWSURFACE surface = (LPDIRECTDRAWSURFACE)0;
static UINT g_uPrevMouseX = 0;
static UINT g_uPrevMouseY = 0;
static bool g_bShowingCursor = true;
static bool g_bOldShowingCursor = true; // Used during MODE_PAUSE
static bool g_bLastCursorInAppleViewport = false;
void DrawStatusArea (HDC passdc, BOOL drawflags);
void ProcessButtonClick (int button);
@ -97,6 +100,11 @@ void SetUsingCursor (BOOL);
bool g_bScrollLock_FullSpeed = false;
// Prototypes:
static void FrameSetCursorPosByMousePos(int x, int y, int dx, int dy, bool bLeavingAppleScreen);
static void DrawCrosshairsMouse();
static void UpdateMouseInAppleViewport(int iOutOfBoundsX, int iOutOfBoundsY, int x=0, int y=0);
//===========================================================================
void CreateGdiObjects () {
ZeroMemory(buttonbitmap,BUTTONS*sizeof(HBITMAP));
@ -403,7 +411,7 @@ void DrawStatusArea (HDC passdc, int drawflags)
if (drawflags & DRAW_TITLE)
{
TCHAR title[40];
TCHAR title[80];
switch (g_Apple2Type)
{
case A2TYPE_APPLE2: _tcscpy(title, TITLE_APPLE_2); break;
@ -412,6 +420,11 @@ void DrawStatusArea (HDC passdc, int drawflags)
case A2TYPE_APPLE2EEHANCED: _tcscpy(title, TITLE_APPLE_2E_ENHANCED); break;
}
if (g_hCustomRomF8 != INVALID_HANDLE_VALUE)
_tcscat(title,TEXT(" (custom rom)"));
else if (g_uTheFreezesF8Rom && IS_APPLE2)
_tcscat(title,TEXT(" (The Freeze's non-autostart F8 rom)"));
switch (g_nAppMode)
{
case MODE_PAUSED : _tcscat(title,TEXT(" [")); _tcscat(title,TITLE_PAUSED ); _tcscat(title,TEXT("]")); break;
@ -491,6 +504,7 @@ LRESULT CALLBACK FrameWndProc (
g_hFrameWindow = window;
CreateGdiObjects();
DSInit();
DIMouse::DirectInputInit(window);
MB_Initialize();
SpkrInitialize();
DragAcceptFiles(window,1);
@ -538,6 +552,7 @@ LRESULT CALLBACK FrameWndProc (
VideoDestroy();
MB_Destroy();
DeleteGdiObjects();
DIMouse::DirectInputUninit(window);
PostQuitMessage(0); // Post WM_QUIT message to the thread's message queue
break;
@ -586,9 +601,20 @@ LRESULT CALLBACK FrameWndProc (
}
else if (wparam == VK_F9)
{
videotype++; // Cycle through available video modes
if (videotype >= VT_NUM_MODES)
videotype = 0;
// Cycle through available video modes
if (GetKeyState(VK_SHIFT) >= 0) // Backwards
{
if (videotype == 0)
videotype = VT_NUM_MODES;
videotype--;
}
else // Forwards
{
videotype++;
if (videotype >= VT_NUM_MODES)
videotype = 0;
}
VideoReinitialize();
if ((g_nAppMode != MODE_LOGO) || ((g_nAppMode == MODE_DEBUG) && (g_bDebuggerViewingAppleOutput))) // +PATCH
{
@ -628,17 +654,20 @@ LRESULT CALLBACK FrameWndProc (
g_nAppMode = MODE_PAUSED;
SoundCore_SetFade(FADE_OUT);
g_bOldShowingCursor = g_bShowingCursor;
if (sg_Mouse.Active() && !g_bShowingCursor)
if (sg_Mouse.IsActiveAndEnabled() && !g_bShowingCursor)
{
int nCount = ShowCursor(1);
_ASSERT(nCount >= 0);
g_bShowingCursor = true;
if (g_uMouseShowCrosshair) // Erase crosshairs if they are being drawn
DrawCrosshairs(0,0);
}
break;
case MODE_PAUSED:
g_nAppMode = MODE_RUNNING;
SoundCore_SetFade(FADE_IN);
if (sg_Mouse.Active() && !g_bOldShowingCursor)
if (sg_Mouse.IsActiveAndEnabled() && !g_bOldShowingCursor)
{
int nCount = ShowCursor(0);
_ASSERT(nCount < 0);
@ -723,9 +752,35 @@ LRESULT CALLBACK FrameWndProc (
{
SetUsingCursor(1);
}
else if (sg_Mouse.Active())
else if (sg_Mouse.IsActive())
{
sg_Mouse.SetButton(BUTTON0, BUTTON_DOWN);
if (wparam & (MK_CONTROL | MK_SHIFT))
{
sg_Mouse.SetEnabled(false);
int nCount = ShowCursor(1);
_ASSERT(nCount >= 0);
g_bShowingCursor = true;
if (g_uMouseShowCrosshair) // Erase crosshairs if they are being drawn
DrawCrosshairs(0,0);
}
else
{
if (!sg_Mouse.IsEnabled())
{
sg_Mouse.SetEnabled(true);
int nCount = ShowCursor(0);
_ASSERT(nCount < 0);
g_bShowingCursor = false;
// Don't call SetButton() when enabling
}
else
{
sg_Mouse.SetButton(BUTTON0, BUTTON_DOWN);
}
}
}
DebuggerMouseClick( x, y );
}
@ -749,7 +804,7 @@ LRESULT CALLBACK FrameWndProc (
{
JoySetButton(BUTTON0, BUTTON_UP);
}
else if (sg_Mouse.Active())
else if (sg_Mouse.IsActive())
{
sg_Mouse.SetButton(BUTTON0, BUTTON_UP);
}
@ -783,37 +838,50 @@ LRESULT CALLBACK FrameWndProc (
DrawCrosshairs(x,y);
JoySetPosition(x-viewportx-2, VIEWPORTCX-4, y-viewporty-2, VIEWPORTCY-4);
}
else if (sg_Mouse.Active() && (g_nAppMode == MODE_RUNNING))
else if (sg_Mouse.IsActiveAndEnabled() && (g_nAppMode == MODE_RUNNING))
{
if ((x >= viewportx+2) &&
(x < buttonx) &&
(y >= viewporty+2) &&
(y <= viewporty+VIEWPORTCY-1))
{
if (g_bShowingCursor)
{
int nCount = ShowCursor(0);
_ASSERT(nCount < 0);
g_bShowingCursor = false;
}
sg_Mouse.SetPositionRel(x-g_uPrevMouseX, y-g_uPrevMouseY);
}
else
{
if (!g_bShowingCursor)
{
int nCount = ShowCursor(1);
_ASSERT(nCount >= 0);
g_bShowingCursor = true;
}
}
if (g_bLastCursorInAppleViewport)
break;
const int iAppleScreenMaxX = VIEWPORTCX-1;
const int iAppleScreenMaxY = VIEWPORTCY-1;
const int iBoundMinX = viewportx;
const int iBoundMaxX = iAppleScreenMaxX;
const int iBoundMinY = viewporty;
const int iBoundMaxY = iAppleScreenMaxY;
int iOutOfBoundsX=0, iOutOfBoundsY=0;
if (x < iBoundMinX) iOutOfBoundsX=-1;
if (x > iBoundMaxX) iOutOfBoundsX=1;
if (y < iBoundMinY) iOutOfBoundsY=-1;
if (y > iBoundMaxY) iOutOfBoundsY=1;
UpdateMouseInAppleViewport(iOutOfBoundsX, iOutOfBoundsY, x, y);
}
RelayEvent(WM_MOUSEMOVE,wparam,lparam);
g_uPrevMouseX = x;
g_uPrevMouseY = y;
break;
}
case WM_TIMER:
if (wparam == IDEVENT_TIMER_MOUSE)
{
if (sg_Mouse.IsActiveAndEnabled() && (g_nAppMode == MODE_RUNNING))
{
if (g_bLastCursorInAppleViewport == false)
break;
int iOutOfBoundsX=0, iOutOfBoundsY=0;
long dX,dY;
if (DIMouse::ReadImmediateData(&dX, &dY) == S_OK)
sg_Mouse.SetPositionRel(dX, dY, &iOutOfBoundsX, &iOutOfBoundsY);
UpdateMouseInAppleViewport(iOutOfBoundsX, iOutOfBoundsY);
}
}
break;
// VSCROLL
// SB_LINEUP // Line Scrolling
// SB_PAGEUP // Page Scrolling
@ -833,7 +901,6 @@ LRESULT CALLBACK FrameWndProc (
}
break;
case WM_NOTIFY:
if(((LPNMTTDISPINFO)lparam)->hdr.hwndFrom == tooltipwindow &&
((LPNMTTDISPINFO)lparam)->hdr.code == TTN_GETDISPINFO)
@ -907,7 +974,7 @@ LRESULT CALLBACK FrameWndProc (
}
if (usingcursor)
{
if (sg_Mouse.Active())
if (sg_Mouse.IsActive())
sg_Mouse.SetButton(BUTTON1, (message == WM_RBUTTONDOWN) ? BUTTON_DOWN : BUTTON_UP);
else
JoySetButton(BUTTON1, (message == WM_RBUTTONDOWN) ? BUTTON_DOWN : BUTTON_UP);
@ -966,6 +1033,7 @@ LRESULT CALLBACK FrameWndProc (
case WM_USER_RESTART:
// . Changed Apple computer type (][+ or //e)
// . Changed disk speed (normal or enhanced)
// . Changed Freeze F8 rom setting
if (g_nAppMode != MODE_LOGO)
if (MessageBox(g_hFrameWindow,
TEXT("Restarting the emulator will reset the state ")
@ -1218,10 +1286,10 @@ void SetUsingCursor (BOOL newvalue) {
usingcursor = newvalue;
if (usingcursor) {
SetCapture(g_hFrameWindow);
RECT rect = {viewportx+2,
viewporty+2,
viewportx+VIEWPORTCX-1,
viewporty+VIEWPORTCY-1};
RECT rect = {viewportx+2, // left
viewporty+2, // top
viewportx+VIEWPORTCX-1, // right
viewporty+VIEWPORTCY-1}; // bottom
ClientToScreen(g_hFrameWindow,(LPPOINT)&rect.left);
ClientToScreen(g_hFrameWindow,(LPPOINT)&rect.right);
ClipCursor(&rect);
@ -1246,14 +1314,14 @@ void SetUsingCursor (BOOL newvalue) {
//===========================================================================
void FrameCreateWindow ()
{
int width = VIEWPORTCX + (VIEWPORTX<<1)
int width = VIEWPORTCX + VIEWPORTX*2
+ BUTTONCX
+ (GetSystemMetrics(SM_CXBORDER)<<1)
+ 5;
int height = VIEWPORTCY + (VIEWPORTY<<1)
+ GetSystemMetrics(SM_CXBORDER)*2
+ MAGICX;
int height = VIEWPORTCY + VIEWPORTY*2
+ GetSystemMetrics(SM_CYBORDER)
+ GetSystemMetrics(SM_CYCAPTION)
+ 5;
+ MAGICY;
int xpos;
if (!RegLoadValue(TEXT("Preferences"),TEXT("Window X-Position"),1,(DWORD *)&xpos))
@ -1393,3 +1461,159 @@ void FrameReleaseVideoDC () {
surface->Unlock(NULL);
}
}
//===========================================================================
// Called when:
// . Mouse f/w sets abs position
// . UpdateMouseInAppleViewport() is called and inside Apple screen
void FrameSetCursorPosByMousePos()
{
if (!g_hFrameWindow || g_bShowingCursor)
return;
int iX, iMinX, iMaxX;
int iY, iMinY, iMaxY;
sg_Mouse.GetXY(iX, iMinX, iMaxX, iY, iMinY, iMaxY);
_ASSERT(iMinX == 0 && iMinY == 0);
float fScaleX = (float)(iX-iMinX) / ((float)(iMaxX-iMinX));
float fScaleY = (float)(iY-iMinY) / ((float)(iMaxY-iMinY));
int iWindowX = (int)(fScaleX * (float)VIEWPORTCX);
int iWindowY = (int)(fScaleY * (float)VIEWPORTCY);
POINT Point = {viewportx+2, viewporty+2}; // top-left
ClientToScreen(g_hFrameWindow, &Point);
SetCursorPos(Point.x+iWindowX-MAGICX, Point.y+iWindowY-MAGICY);
#if defined(_DEBUG) && 0
static int OldX=0, OldY=0;
char szDbg[200];
int X=Point.x+iWindowX-MAGICX;
int Y=Point.y+iWindowY-MAGICY;
if (X != OldX || Y != OldY)
{
sprintf(szDbg, "[FrameSetCursorPosByMousePos] x,y=%d,%d (MaxX,Y=%d,%d)\n", X,Y, iMaxX,iMaxY); OutputDebugString(szDbg);
OldX=X; OldY=Y;
}
#endif
}
static void FrameSetCursorPosByMousePos(int x, int y, int dx, int dy, bool bLeavingAppleScreen)
{
// char szDbg[200];
if (!g_hFrameWindow || (g_bShowingCursor && bLeavingAppleScreen) || (!g_bShowingCursor && !bLeavingAppleScreen))
return;
int iX, iMinX, iMaxX;
int iY, iMinY, iMaxY;
sg_Mouse.GetXY(iX, iMinX, iMaxX, iY, iMinY, iMaxY);
_ASSERT(iMinX == 0 && iMinY == 0);
if (bLeavingAppleScreen)
{
// Set mouse x/y pos to edge of mouse's window
if (dx < 0) iX = iMinX;
if (dx > 0) iX = iMaxX;
if (dy < 0) iY = iMinY;
if (dy > 0) iY = iMaxY;
float fScaleX = (float)(iX-iMinX) / ((float)(iMaxX-iMinX));
float fScaleY = (float)(iY-iMinY) / ((float)(iMaxY-iMinY));
int iWindowX = (int)(fScaleX * (float)VIEWPORTCX) + dx;
int iWindowY = (int)(fScaleY * (float)VIEWPORTCY) + dy;
POINT Point = {viewportx+2, viewporty+2}; // top-left
ClientToScreen(g_hFrameWindow, &Point);
SetCursorPos(Point.x+iWindowX-MAGICX, Point.y+iWindowY-MAGICY);
// sprintf(szDbg, "[MOUSE_LEAVING ] x=%d, y=%d (Scale: x,y=%f,%f; iX,iY=%d,%d)\n", iWindowX, iWindowY, fScaleX, fScaleY, iX, iY); OutputDebugString(szDbg);
}
else // Mouse entering Apple screen area
{
// sprintf(szDbg, "[MOUSE_ENTERING] x=%d, y=%d\n", x, y); OutputDebugString(szDbg);
x -= (viewportx+2-MAGICX);
y -= (viewporty+2-MAGICY);
_ASSERT(x <= VIEWPORTCX);
_ASSERT(y <= VIEWPORTCY);
float fScaleX = (float)x / (float)VIEWPORTCX;
float fScaleY = (float)y / (float)VIEWPORTCY;
int iAppleX = iMinX + (int)(fScaleX * (float)(iMaxX-iMinX));
int iAppleY = iMinY + (int)(fScaleY * (float)(iMaxY-iMinY));
sg_Mouse.SetCursorPos(iAppleX, iAppleY); // Set new entry position
// Dump initial deltas (otherwise can get big deltas since last read when entering Apple screen area)
DIMouse::ReadImmediateData();
}
}
static void DrawCrosshairsMouse()
{
if (!g_uMouseShowCrosshair)
return;
int iX, iMinX, iMaxX;
int iY, iMinY, iMaxY;
sg_Mouse.GetXY(iX, iMinX, iMaxX, iY, iMinY, iMaxY);
_ASSERT(iMinX == 0 && iMinY == 0);
float fScaleX = (float)(iX-iMinX) / ((float)(iMaxX-iMinX));
float fScaleY = (float)(iY-iMinY) / ((float)(iMaxY-iMinY));
int iWindowX = (int)(fScaleX * (float)VIEWPORTCX);
int iWindowY = (int)(fScaleY * (float)VIEWPORTCY);
DrawCrosshairs(iWindowX,iWindowY);
}
#ifdef _DEBUG
//#define _DEBUG_SHOW_CURSOR // NB. Get an ASSERT on LMB (after Ctrl+LMB)
#endif
static void UpdateMouseInAppleViewport(int iOutOfBoundsX, int iOutOfBoundsY, int x, int y)
{
const bool bOutsideAppleViewport = iOutOfBoundsX || iOutOfBoundsY;
if (bOutsideAppleViewport)
{
g_bLastCursorInAppleViewport = false;
if (!g_bShowingCursor)
{
// Mouse leaving Apple screen area
FrameSetCursorPosByMousePos(0, 0, iOutOfBoundsX, iOutOfBoundsY, true);
#ifdef _DEBUG_SHOW_CURSOR
#else
int nCount = ShowCursor(1);
_ASSERT(nCount >= 0);
#endif
g_bShowingCursor = true;
}
}
else
{
g_bLastCursorInAppleViewport = true;
if (g_bShowingCursor)
{
// Mouse entering Apple screen area
FrameSetCursorPosByMousePos(x, y, 0, 0, false);
#ifdef _DEBUG_SHOW_CURSOR
#else
int nCount = ShowCursor(0);
_ASSERT(nCount < 0);
#endif
g_bShowingCursor = false;
}
else
{
FrameSetCursorPosByMousePos(); // Set cursor to Apple position each time
}
DrawCrosshairsMouse();
}
}

View File

@ -19,6 +19,7 @@ void FrameRefreshStatus (int);
void FrameRegisterClass ();
void FrameReleaseDC ();
void FrameReleaseVideoDC ();
void FrameSetCursorPosByMousePos();
LRESULT CALLBACK FrameWndProc (
HWND window,

View File

@ -53,10 +53,11 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#define MODE_CENTERING 2
#define MODE_SMOOTH 3
typedef struct _joyinforec {
typedef struct
{
int device;
int mode;
} joyinforec, *joyinfoptr;
} joyinforec;
static const joyinforec joyinfo[5] = {{DEVICE_NONE,MODE_NONE},
{DEVICE_JOYSTICK,MODE_STANDARD},
@ -111,7 +112,7 @@ static short g_nPdlTrimX = 0;
static short g_nPdlTrimY = 0;
//===========================================================================
void CheckJoystick0 ()
void CheckJoystick0()
{
static DWORD lastcheck = 0;
DWORD currtime = GetTickCount();
@ -141,7 +142,7 @@ void CheckJoystick0 ()
}
}
void CheckJoystick1 ()
void CheckJoystick1()
{
static DWORD lastcheck = 0;
DWORD currtime = GetTickCount();
@ -177,7 +178,7 @@ void CheckJoystick1 ()
//
//===========================================================================
void JoyInitialize ()
void JoyInitialize()
{
// Emulated joystick #0 can only use JOYSTICKID1 (if no joystick, then use mouse)
// Emulated joystick #1 can only use JOYSTICKID2 (if no joystick, then disable)
@ -249,7 +250,7 @@ void JoyInitialize ()
//===========================================================================
BOOL JoyProcessKey (int virtkey, BOOL extended, BOOL down, BOOL autorep)
BOOL JoyProcessKey(int virtkey, BOOL extended, BOOL down, BOOL autorep)
{
if( (joyinfo[joytype[0]].device != DEVICE_KEYBOARD) &&
(joyinfo[joytype[1]].device != DEVICE_KEYBOARD) &&
@ -366,7 +367,7 @@ BOOL JoyProcessKey (int virtkey, BOOL extended, BOOL down, BOOL autorep)
//===========================================================================
BYTE __stdcall JoyReadButton (WORD, WORD address, BYTE, BYTE, ULONG nCyclesLeft)
BYTE __stdcall JoyReadButton(WORD, WORD address, BYTE, BYTE, ULONG nCyclesLeft)
{
address &= 0xFF;
@ -420,7 +421,7 @@ BYTE __stdcall JoyReadButton (WORD, WORD address, BYTE, BYTE, ULONG nCyclesLeft)
static const double PDL_CNTR_INTERVAL = 2816.0 / 255.0; // 11.04 (From KEGS)
BYTE __stdcall JoyReadPosition (WORD programcounter, WORD address, BYTE, BYTE, ULONG nCyclesLeft)
BYTE __stdcall JoyReadPosition(WORD programcounter, WORD address, BYTE, BYTE, ULONG nCyclesLeft)
{
int nJoyNum = (address & 2) ? 1 : 0; // $C064..$C067
@ -438,7 +439,7 @@ BYTE __stdcall JoyReadPosition (WORD programcounter, WORD address, BYTE, BYTE, U
}
//===========================================================================
void JoyReset ()
void JoyReset()
{
int loop = 0;
while (loop < JK_MAX)
@ -446,7 +447,7 @@ void JoyReset ()
}
//===========================================================================
BYTE __stdcall JoyResetPosition (WORD, WORD, BYTE, BYTE, ULONG nCyclesLeft)
BYTE __stdcall JoyResetPosition(WORD, WORD, BYTE, BYTE, ULONG nCyclesLeft)
{
CpuCalcCycles(nCyclesLeft);
g_nJoyCntrResetCycle = g_nCumulativeCycles;
@ -462,7 +463,7 @@ BYTE __stdcall JoyResetPosition (WORD, WORD, BYTE, BYTE, ULONG nCyclesLeft)
//===========================================================================
// Called when mouse is being used as a joystick && mouse button changes
void JoySetButton (eBUTTON number, eBUTTONSTATE down)
void JoySetButton(eBUTTON number, eBUTTONSTATE down)
{
if (number > 1) // Sanity check on mouse button #
return;
@ -484,7 +485,7 @@ void JoySetButton (eBUTTON number, eBUTTONSTATE down)
}
//===========================================================================
BOOL JoySetEmulationType (HWND window, DWORD newtype, int nJoystickNumber)
BOOL JoySetEmulationType(HWND window, DWORD newtype, int nJoystickNumber)
{
if(joytype[nJoystickNumber] == newtype)
return 1; // Already set to this type. Return OK.
@ -508,7 +509,7 @@ BOOL JoySetEmulationType (HWND window, DWORD newtype, int nJoystickNumber)
else if ((joyinfo[newtype].device == DEVICE_MOUSE) &&
(joyinfo[joytype[nJoystickNumber]].device != DEVICE_MOUSE))
{
if (sg_Mouse.Active())
if (sg_Mouse.IsActive())
{
MessageBox(window,
TEXT("Mouse interface card is enabled - unable to use mouse for joystick emulation."),
@ -539,7 +540,7 @@ BOOL JoySetEmulationType (HWND window, DWORD newtype, int nJoystickNumber)
//===========================================================================
// Called when mouse is being used as a joystick && mouse position changes
void JoySetPosition (int xvalue, int xrange, int yvalue, int yrange)
void JoySetPosition(int xvalue, int xrange, int yvalue, int yrange)
{
int nJoyNum = (joyinfo[joytype[0]].device == DEVICE_MOUSE) ? 0 : 1;
xpos[nJoyNum] = (xvalue*255)/xrange;
@ -547,7 +548,7 @@ void JoySetPosition (int xvalue, int xrange, int yvalue, int yrange)
}
//===========================================================================
void JoyUpdatePosition ()
void JoyUpdatePosition()
{
if (buttonlatch[0]) --buttonlatch[0];
if (buttonlatch[1]) --buttonlatch[1];
@ -555,13 +556,24 @@ void JoyUpdatePosition ()
}
//===========================================================================
BOOL JoyUsingMouse ()
BOOL JoyUsingMouse()
{
return (joyinfo[joytype[0]].device == DEVICE_MOUSE) || (joyinfo[joytype[1]].device == DEVICE_MOUSE);
}
//===========================================================================
void JoyDisableUsingMouse()
{
if (joyinfo[joytype[0]].device == DEVICE_MOUSE)
joytype[0] = DEVICE_NONE;
if (joyinfo[joytype[1]].device == DEVICE_MOUSE)
joytype[1] = DEVICE_NONE;
}
//===========================================================================
void JoySetTrim(short nValue, bool bAxisX)
{
if(bAxisX)

View File

@ -4,19 +4,20 @@ enum JOYNUM {JN_JOYSTICK0=0, JN_JOYSTICK1};
extern DWORD joytype[2];
void JoyInitialize ();
BOOL JoyProcessKey (int,BOOL,BOOL,BOOL);
void JoyReset ();
void JoySetButton (eBUTTON,eBUTTONSTATE);
BOOL JoySetEmulationType (HWND,DWORD,int);
void JoySetPosition (int,int,int,int);
void JoyUpdatePosition ();
BOOL JoyUsingMouse ();
void JoyInitialize();
BOOL JoyProcessKey(int,BOOL,BOOL,BOOL);
void JoyReset();
void JoySetButton(eBUTTON,eBUTTONSTATE);
BOOL JoySetEmulationType(HWND,DWORD,int);
void JoySetPosition(int,int,int,int);
void JoyUpdatePosition();
BOOL JoyUsingMouse();
void JoyDisableUsingMouse();
void JoySetTrim(short nValue, bool bAxisX);
short JoyGetTrim(bool bAxisX);
DWORD JoyGetSnapshot(SS_IO_Joystick* pSS);
DWORD JoySetSnapshot(SS_IO_Joystick* pSS);
BYTE __stdcall JoyReadButton (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
BYTE __stdcall JoyReadPosition (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
BYTE __stdcall JoyResetPosition (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
BYTE __stdcall JoyReadButton(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
BYTE __stdcall JoyReadPosition(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
BYTE __stdcall JoyResetPosition(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);

View File

@ -1013,7 +1013,7 @@ void MemInitialize()
}
}
if (g_uTheFreezesF8Rom)
if (g_uTheFreezesF8Rom && IS_APPLE2)
{
hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDR_FREEZES_F8_ROM), "ROM");

View File

@ -5,6 +5,7 @@
#pragma hdrstop
#include "..\resource\resource.h"
#include "MouseInterface.h"
#include "Frame.h" // FrameSetCursorPosByMousePos()
// Sets mouse mode
#define MOUSE_SET 0x00
@ -104,6 +105,7 @@ void CMouseInterface::Initialize(LPBYTE pCxRomPeripheral, UINT uSlot)
//
m_bActive = true;
SetEnabled(true);
SetSlotRom(); // Pre: m_bActive == true
RegisterIoHandler(uSlot, &CMouseInterface::IORead, &CMouseInterface::IOWrite, NULL, NULL, this, NULL);
}
@ -319,6 +321,9 @@ void CMouseInterface::OnWrite()
switch( m_byBuff[0] & 0xF0 )
{
case MOUSE_CLAMP:
// Blazing Paddles:
// . MOUSE_CLAMP(Y, 0xFFEC, 0x00D3)
// . MOUSE_CLAMP(X, 0xFFEC, 0x012B)
nMin = ( m_byBuff[3] << 8 ) | m_byBuff[1];
nMax = ( m_byBuff[4] << 8 ) | m_byBuff[2];
if ( m_byBuff[0] & 1 ) // Clamp Y
@ -394,26 +399,52 @@ void CMouseInterface::Clear()
//===========================================================================
void CMouseInterface::ClampX()
int CMouseInterface::ClampX()
{
if ( m_iX > m_iMaxX )
{
m_iX = m_iMaxX;
return 1;
}
else if ( m_iX < m_iMinX )
{
m_iX = m_iMinX;
return -1;
}
return 0;
}
void CMouseInterface::ClampY()
int CMouseInterface::ClampY()
{
if ( m_iY > m_iMaxY )
{
m_iY = m_iMaxY;
return 1;
}
else if ( m_iY < m_iMinY )
{
m_iY = m_iMinY;
return -1;
}
return 0;
}
void CMouseInterface::SetClampX(int iMinX, int iMaxX)
{
if ( iMinX < 0 || iMinX > iMaxX )
if ( (UINT)iMinX > 0xFFFF || (UINT)iMaxX > 0xFFFF )
{
_ASSERT(0);
return;
}
if ( iMinX > iMaxX )
{
// For Blazing Paddles
int iNewMaxX = (iMinX + iMaxX) & 0xFFFF;
iMinX = 0;
iMaxX = iNewMaxX;
}
m_iMaxX = iMaxX;
m_iMinX = iMinX;
ClampX();
@ -421,8 +452,18 @@ void CMouseInterface::SetClampX(int iMinX, int iMaxX)
void CMouseInterface::SetClampY(int iMinY, int iMaxY)
{
if ( iMinY < 0 || iMinY > iMaxY )
if ( (UINT)iMinY > 0xFFFF || (UINT)iMaxY > 0xFFFF )
{
_ASSERT(0);
return;
}
if ( iMinY > iMaxY )
{
// For Blazing Paddles
int iNewMaxY = (iMinY + iMaxY) & 0xFFFF;
iMinY = 0;
iMaxY = iNewMaxY;
}
m_iMaxY = iMaxY;
m_iMinY = iMinY;
ClampY();
@ -430,17 +471,21 @@ void CMouseInterface::SetClampY(int iMinY, int iMaxY)
void CMouseInterface::SetPositionAbs(int x, int y)
{
#if defined(_DEBUG) && 0
char szDbg[200]; sprintf(szDbg, "[SetPositionAbs] x=%d, y=%d (m_iX=%d, m_iY=%d)\n", x,y, m_iX,m_iY); OutputDebugString(szDbg);
#endif
m_iX = x;
m_iY = y;
FrameSetCursorPosByMousePos();
}
void CMouseInterface::SetPositionRel(int dx, int dy)
void CMouseInterface::SetPositionRel(long dX, long dY, int* pOutOfBoundsX, int* pOutOfBoundsY)
{
m_iX += dx;
ClampX();
m_iX += dX;
*pOutOfBoundsX = ClampX();
m_iY += dy;
ClampY();
m_iY += dY;
*pOutOfBoundsY = ClampY();
OnMouseEvent();
}
@ -450,3 +495,189 @@ void CMouseInterface::SetButton(eBUTTON Button, eBUTTONSTATE State)
m_bButtons[Button]= (State == BUTTON_DOWN) ? TRUE : FALSE;
OnMouseEvent();
}
//=============================================================================
// DirectInput interface
//=============================================================================
//#define STRICT
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>
namespace DIMouse
{
static LPDIRECTINPUT8 g_pDI = NULL;
static LPDIRECTINPUTDEVICE8 g_pMouse = NULL;
#define SAMPLE_BUFFER_SIZE 16 // arbitrary number of buffer elements
static UINT_PTR g_TimerIDEvent = 0;
//-----------------------------------------------------------------------------
// Name: OnCreateDevice()
// Desc: Sets up the mouse device using the flags from the dialog.
//-----------------------------------------------------------------------------
HRESULT DirectInputInit( HWND hDlg )
{
HRESULT hr;
BOOL bExclusive;
BOOL bForeground;
BOOL bImmediate;
DWORD dwCoopFlags;
DirectInputUninit(hDlg);
// Determine where the buffer would like to be allocated
bExclusive = FALSE;
bForeground = FALSE; // Otherwise get DIERR_OTHERAPPHASPRIO (== E_ACCESSDENIED) on Acquire()
bImmediate = TRUE;
if( bExclusive )
dwCoopFlags = DISCL_EXCLUSIVE;
else
dwCoopFlags = DISCL_NONEXCLUSIVE;
if( bForeground )
dwCoopFlags |= DISCL_FOREGROUND;
else
dwCoopFlags |= DISCL_BACKGROUND;
// Create a DInput object
if( FAILED( hr = DirectInput8Create( GetModuleHandle(NULL), DIRECTINPUT_VERSION,
IID_IDirectInput8, (VOID**)&g_pDI, NULL ) ) )
return hr;
// Obtain an interface to the system mouse device.
if( FAILED( hr = g_pDI->CreateDevice( GUID_SysMouse, &g_pMouse, NULL ) ) )
return hr;
// Set the data format to "mouse format" - a predefined data format
//
// A data format specifies which controls on a device we
// are interested in, and how they should be reported.
//
// This tells DirectInput that we will be passing a
// DIMOUSESTATE2 structure to IDirectInputDevice::GetDeviceState.
if( FAILED( hr = g_pMouse->SetDataFormat( &c_dfDIMouse2 ) ) )
return hr;
// Set the cooperativity level to let DirectInput know how
// this device should interact with the system and with other
// DirectInput applications.
hr = g_pMouse->SetCooperativeLevel( hDlg, dwCoopFlags );
if( hr == DIERR_UNSUPPORTED && !bForeground && bExclusive )
{
DirectInputUninit(hDlg);
//MessageBox( hDlg, _T("SetCooperativeLevel() returned DIERR_UNSUPPORTED.\n")
// _T("For security reasons, background exclusive mouse\n")
// _T("access is not allowed."),
// _T("Mouse"), MB_OK );
return S_OK;
}
if( FAILED(hr) )
return hr;
if( !bImmediate )
{
// IMPORTANT STEP TO USE BUFFERED DEVICE DATA!
//
// DirectInput uses unbuffered I/O (buffer size = 0) by default.
// If you want to read buffered data, you need to set a nonzero
// buffer size.
//
// Set the buffer size to SAMPLE_BUFFER_SIZE (defined above) elements.
//
// The buffer size is a DWORD property associated with the device.
DIPROPDWORD dipdw;
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
dipdw.diph.dwObj = 0;
dipdw.diph.dwHow = DIPH_DEVICE;
dipdw.dwData = SAMPLE_BUFFER_SIZE; // Arbitary buffer size
if( FAILED( hr = g_pMouse->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph ) ) )
return hr;
}
// Acquire the newly created device
if (FAILED(hr = g_pMouse->Acquire()))
return hr;
// Setup timer to read mouse position
if (g_TimerIDEvent = SetTimer(hDlg, IDEVENT_TIMER_MOUSE, 8, NULL) == 0) // 120Hz timer
return -1;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: FreeDirectInput()
// Desc: Initialize the DirectInput variables.
//-----------------------------------------------------------------------------
void DirectInputUninit( HWND hDlg )
{
// Unacquire the device one last time just in case
// the app tried to exit while the device is still acquired.
if( g_pMouse )
g_pMouse->Unacquire();
// Release any DirectInput objects.
SAFE_RELEASE( g_pMouse );
SAFE_RELEASE( g_pDI );
if (g_TimerIDEvent)
KillTimer(hDlg, g_TimerIDEvent);
}
//-----------------------------------------------------------------------------
// Name: ReadImmediateData()
// Desc: Read the input device's state when in immediate mode and display it.
//-----------------------------------------------------------------------------
HRESULT ReadImmediateData( long* pX, long* pY )
{
HRESULT hr;
DIMOUSESTATE2 dims2; // DirectInput mouse state structure
if (pX) *pX = 0;
if (pY) *pY = 0;
if( NULL == g_pMouse )
return S_OK;
// Get the input's device state, and put the state in dims
ZeroMemory( &dims2, sizeof(dims2) );
hr = g_pMouse->GetDeviceState( sizeof(DIMOUSESTATE2), &dims2 );
if( FAILED(hr) )
{
// DirectInput may be telling us that the input stream has been
// interrupted. We aren't tracking any state between polls, so
// we don't have any special reset that needs to be done.
// We just re-acquire and try again.
// If input is lost then acquire and keep trying
hr = g_pMouse->Acquire();
while( hr == DIERR_INPUTLOST )
hr = g_pMouse->Acquire();
// Update the dialog text
if( hr == DIERR_OTHERAPPHASPRIO ||
hr == DIERR_NOTACQUIRED )
{
//SetDlgItemText( hDlg, IDC_DATA, TEXT("Unacquired") );
}
// hr may be DIERR_OTHERAPPHASPRIO or other errors. This
// may occur when the app is minimized or in the process of
// switching, so just try again later
return S_OK;
}
if (pX) *pX = dims2.lX;
if (pY) *pY = dims2.lY;
return S_OK;
}
}; // namespace DIMouse

View File

@ -19,10 +19,27 @@ public:
static BYTE __stdcall IORead(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft);
static BYTE __stdcall IOWrite(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft);
void SetPositionRel(int dx, int dy);
void SetPositionRel(long dx, long dy, int* pOutOfBoundsX, int* pOutOfBoundsY);
void SetButton(eBUTTON Button, eBUTTONSTATE State);
bool Active() { return m_bActive; }
bool IsActive() { return m_bActive; }
bool IsEnabled() { return m_bEnabled; }
bool IsActiveAndEnabled() { return IsActive() && IsEnabled(); }
void SetEnabled(bool bEnabled) { m_bEnabled = bEnabled; }
void SetVBlank(bool bVBL);
void GetXY(int& iX, int& iMinX, int& iMaxX, int& iY, int& iMinY, int& iMaxY)
{
iX = m_iX;
iMinX = m_iMinX;
iMaxX = m_iMaxX;
iY = m_iY;
iMinY = m_iMinY;
iMaxY = m_iMaxY;
}
void SetCursorPos(int iX, int iY)
{
m_iX = iX;
m_iY = iY;
}
protected:
void On6821_A(BYTE byData);
@ -37,8 +54,8 @@ protected:
//friend CALLBACK_HANDLER( MouseHandler );
void SetPositionAbs(int x, int y);
void ClampX();
void ClampY();
int ClampX();
int ClampY();
void SetClampX(int iMinX, int iMaxX);
void SetClampY(int iMinY, int iMaxY);
@ -74,7 +91,17 @@ protected:
//
bool m_bActive;
bool m_bActive; // Mouse h/w is active within the Apple][ VM
bool m_bEnabled; // Windows' mouse events get passed to Apple]['s mouse h/w
LPBYTE m_pSlotRom;
UINT m_uSlot;
};
#define IDEVENT_TIMER_MOUSE 1
namespace DIMouse
{
HRESULT DirectInputInit( HWND hDlg );
void DirectInputUninit( HWND hDlg );
HRESULT ReadImmediateData( long* pX=NULL, long* pY=NULL );
};

View File

@ -96,12 +96,13 @@ TCHAR discchoices[] = TEXT("Authentic Speed\0")
const UINT VOLUME_MIN = 0;
const UINT VOLUME_MAX = 59;
enum {PG_CONFIG=0, PG_INPUT, PG_SOUND, PG_SAVESTATE, PG_DISK, PG_ADVANCED, PG_NUM_SHEETS};
enum {PG_CONFIG=0, PG_INPUT, PG_SOUND, PG_DISK, PG_ADVANCED, PG_NUM_SHEETS};
UINT g_nLastPage = PG_CONFIG;
UINT g_uScrollLockToggle = 0;
UINT g_uMouseInSlot4 = 0;
UINT g_uMouseShowCrosshair = 0;
//
@ -255,9 +256,6 @@ static void ConfigDlg_OK(HWND window, UINT afterclose)
MB_ICONQUESTION | MB_YESNO | MB_SETFOREGROUND) == IDYES)
{
afterclose = WM_USER_RESTART;
if (NewApple2Type > A2TYPE_APPLE2PLUS)
g_uTheFreezesF8Rom = false;
}
}
@ -283,7 +281,6 @@ static void ConfigDlg_OK(HWND window, UINT afterclose)
SAVE(TEXT("Custom Speed") ,IsDlgButtonChecked(window,IDC_CUSTOM_SPEED));
SAVE(TEXT("Emulation Speed") ,g_dwSpeed);
SAVE(TEXT("Video Emulation") ,videotype);
SAVE(TEXT(REGVALUE_THE_FREEZES_F8_ROM),g_uTheFreezesF8Rom);
//
@ -470,6 +467,8 @@ static void InputDlg_OK(HWND window, UINT afterclose)
JoySetTrim((short)SendDlgItemMessage(window, IDC_SPIN_XTRIM, UDM_GETPOS, 0, 0), true);
JoySetTrim((short)SendDlgItemMessage(window, IDC_SPIN_YTRIM, UDM_GETPOS, 0, 0), false);
g_uMouseShowCrosshair = IsDlgButtonChecked(window, IDC_MOUSE_CROSSHAIR) ? 1 : 0;
// KeybSetBufferMode(bNewKeybBufferEnable);
SAVE(TEXT("Joystick 0 Emulation"),joytype[0]);
@ -478,6 +477,7 @@ static void InputDlg_OK(HWND window, UINT afterclose)
SAVE(TEXT(REGVALUE_PDL_YTRIM),JoyGetTrim(false));
SAVE(TEXT(REGVALUE_SCROLLLOCK_TOGGLE),g_uScrollLockToggle);
SAVE(TEXT(REGVALUE_MOUSE_IN_SLOT4),g_uMouseInSlot4);
SAVE(TEXT(REGVALUE_MOUSE_CROSSHAIR),g_uMouseShowCrosshair);
// SAVE(TEXT(REGVALUE_KEYB_BUFFER_ENABLE),KeybGetBufferMode() ? 1 : 0);
//
@ -571,12 +571,14 @@ static BOOL CALLBACK InputDlgProc (HWND window,
{
UINT uNewState = IsDlgButtonChecked(window, IDC_MOUSE_IN_SLOT4) ? 1 : 0;
LPCSTR pMsg = uNewState ?
TEXT("The emulator needs to restart as the slot configuration has changed.\n")
TEXT("Also Mockingboard/Phasor cards won't be available in slot 4.\n\n")
TEXT("The emulator needs to restart as the slot configuration has changed.\n\n")
TEXT("Also Mockingboard/Phasor cards won't be available in slot 4\n")
TEXT("and the mouse can't be used for joystick emulation.\n\n")
TEXT("Would you like to restart the emulator now?")
:
TEXT("The emulator needs to restart as the slot configuration has changed.\n")
TEXT("(Mockingboard/Phasor cards will now be available in slot 4.)\n\n")
TEXT("The emulator needs to restart as the slot configuration has changed.\n\n")
TEXT("(Mockingboard/Phasor cards will now be available in slot 4\n")
TEXT("and the mouse can be used for joystick emulation)\n\n")
TEXT("Would you like to restart the emulator now?");
if (MessageBox(window,
pMsg,
@ -584,6 +586,14 @@ static BOOL CALLBACK InputDlgProc (HWND window,
MB_ICONQUESTION | MB_YESNO | MB_SETFOREGROUND) == IDYES)
{
g_uMouseInSlot4 = uNewState;
if (uNewState)
{
JoyDisableUsingMouse();
InitJoystickChoices(window, JN_JOYSTICK0, IDC_JOYSTICK0);
InitJoystickChoices(window, JN_JOYSTICK1, IDC_JOYSTICK1);
}
afterclose = WM_USER_RESTART;
PropSheet_PressButton(GetParent(window), PSBTN_OK);
}
@ -618,6 +628,8 @@ static BOOL CALLBACK InputDlgProc (HWND window,
CheckDlgButton(window, IDC_SCROLLLOCK_TOGGLE, g_uScrollLockToggle ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(window, IDC_MOUSE_IN_SLOT4, g_uMouseInSlot4 ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(window, IDC_MOUSE_CROSSHAIR, g_uMouseShowCrosshair ? BST_CHECKED : BST_UNCHECKED);
EnableWindow(GetDlgItem(window, IDC_MOUSE_CROSSHAIR), g_uMouseInSlot4 ? TRUE : FALSE);
// CheckDlgButton(window, IDC_KEYB_BUFFER_ENABLE, KeybGetBufferMode() ? BST_CHECKED : BST_UNCHECKED);
}
}
@ -759,175 +771,6 @@ static BOOL CALLBACK SoundDlgProc (HWND window,
//===========================================================================
static char g_szNewDirectory[MAX_PATH];
static char g_szNewFilename[MAX_PATH];
static void SaveStateUpdate()
{
Snapshot_SetFilename(g_szNewFilename);
RegSaveString(TEXT("Configuration"),REGVALUE_SAVESTATE_FILENAME,1,Snapshot_GetFilename());
if(g_szNewDirectory[0])
RegSaveString(TEXT("Preferences"),REGVALUE_PREF_START_DIR,1,g_szNewDirectory);
}
static void SaveStateDlg_OK(HWND window, UINT afterclose)
{
char szFilename[MAX_PATH];
memset(szFilename, 0, sizeof(szFilename));
* ((USHORT*) szFilename) = sizeof(szFilename);
UINT nLineLength = SendDlgItemMessage(window,IDC_SAVESTATE_FILENAME,EM_LINELENGTH,0,0);
SendDlgItemMessage(window,IDC_SAVESTATE_FILENAME,EM_GETLINE,0,(LPARAM)szFilename);
nLineLength = nLineLength > sizeof(szFilename)-1 ? sizeof(szFilename)-1 : nLineLength;
szFilename[nLineLength] = 0x00;
SaveStateUpdate();
g_bSaveStateOnExit = IsDlgButtonChecked(window, IDC_SAVESTATE_ON_EXIT) ? true : false;
SAVE(TEXT(REGVALUE_SAVE_STATE_ON_EXIT), g_bSaveStateOnExit ? 1 : 0);
//
if (afterclose)
PostMessage(g_hFrameWindow,afterclose,0,0);
}
static void SaveStateDlg_CANCEL(HWND window)
{
}
//---------------------------------------------------------------------------
static int SaveStateSelectImage(HWND hWindow, TCHAR* pszTitle, bool bSave)
{
TCHAR szDirectory[MAX_PATH] = TEXT("");
TCHAR szFilename[MAX_PATH];
// Attempt to use drive1's image name as the name for the .aws file
LPCTSTR pDiskName0 = DiskGetName(0);
if (pDiskName0 && pDiskName0[0])
{
strcpy(szFilename, pDiskName0);
strcpy(&szFilename[strlen(pDiskName0)], ".aws");
// NB. OK'ing this property sheet will call Snapshot_SetFilename() with this new filename
}
else
{
strcpy(szFilename, Snapshot_GetFilename());
}
RegLoadString(TEXT("Preferences"),REGVALUE_PREF_START_DIR,1,szDirectory,MAX_PATH);
//
OPENFILENAME ofn;
ZeroMemory(&ofn,sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hWindow;
ofn.hInstance = g_hInstance;
ofn.lpstrFilter = TEXT("Save State files (*.aws)\0*.aws\0")
TEXT("All Files\0*.*\0");
ofn.lpstrFile = szFilename;
ofn.nMaxFile = MAX_PATH;
ofn.lpstrInitialDir = szDirectory;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
ofn.lpstrTitle = pszTitle;
int nRes = bSave ? GetSaveFileName(&ofn) : GetOpenFileName(&ofn);
if(nRes)
{
strcpy(g_szNewFilename, &szFilename[ofn.nFileOffset]);
szFilename[ofn.nFileOffset] = 0;
if (_tcsicmp(szDirectory, szFilename))
strcpy(g_szNewDirectory, szFilename);
}
return nRes;
}
//---------------------------------------------------------------------------
static BOOL CALLBACK SaveStateDlgProc (HWND window,
UINT message,
WPARAM wparam,
LPARAM lparam)
{
static UINT afterclose = 0;
switch (message)
{
case WM_NOTIFY:
{
// Property Sheet notifications
switch (((LPPSHNOTIFY)lparam)->hdr.code)
{
case PSN_KILLACTIVE:
SetWindowLong(window, DWL_MSGRESULT, FALSE); // Changes are valid
break;
case PSN_APPLY:
SetWindowLong(window, DWL_MSGRESULT, PSNRET_NOERROR); // Changes are valid
SaveStateDlg_OK(window, afterclose);
break;
case PSN_QUERYCANCEL:
// Can use this to ask user to confirm cancel
break;
case PSN_RESET:
SaveStateDlg_CANCEL(window);
break;
}
}
break;
case WM_COMMAND:
switch (LOWORD(wparam))
{
case IDC_SAVESTATE_FILENAME:
break;
case IDC_SAVESTATE_BROWSE:
if(SaveStateSelectImage(window, TEXT("Select Save State file"), true))
SendDlgItemMessage(window, IDC_SAVESTATE_FILENAME, WM_SETTEXT, 0, (LPARAM) g_szNewFilename);
break;
case IDC_SAVESTATE_ON_EXIT:
break;
case IDC_SAVESTATE:
afterclose = WM_USER_SAVESTATE;
break;
case IDC_LOADSTATE:
afterclose = WM_USER_LOADSTATE;
break;
}
break;
case WM_INITDIALOG:
{
g_nLastPage = PG_SAVESTATE;
SendDlgItemMessage(window,IDC_SAVESTATE_FILENAME,WM_SETTEXT,0,(LPARAM)Snapshot_GetFilename());
CheckDlgButton(window, IDC_SAVESTATE_ON_EXIT, g_bSaveStateOnExit ? BST_CHECKED : BST_UNCHECKED);
g_szNewDirectory[0] = 0x00;
afterclose = 0;
}
}
return 0;
}
//===========================================================================
static void EnableHDD(HWND window, BOOL bEnable)
{
EnableWindow(GetDlgItem(window, IDC_HDD1), bEnable);
@ -1064,8 +907,104 @@ static BOOL CALLBACK DiskDlgProc (HWND window,
//===========================================================================
static char g_szNewDirectory[MAX_PATH];
static char g_szNewFilename[MAX_PATH];
static void SaveStateUpdate()
{
Snapshot_SetFilename(g_szNewFilename);
RegSaveString(TEXT("Configuration"),REGVALUE_SAVESTATE_FILENAME,1,Snapshot_GetFilename());
if(g_szNewDirectory[0])
RegSaveString(TEXT("Preferences"),REGVALUE_PREF_START_DIR,1,g_szNewDirectory);
}
static int SaveStateSelectImage(HWND hWindow, TCHAR* pszTitle, bool bSave)
{
TCHAR szDirectory[MAX_PATH] = TEXT("");
TCHAR szFilename[MAX_PATH];
// Attempt to use drive1's image name as the name for the .aws file
LPCTSTR pDiskName0 = DiskGetName(0);
if (pDiskName0 && pDiskName0[0])
{
strcpy(szFilename, pDiskName0);
strcpy(&szFilename[strlen(pDiskName0)], ".aws");
// NB. OK'ing this property sheet will call Snapshot_SetFilename() with this new filename
}
else
{
strcpy(szFilename, Snapshot_GetFilename());
}
RegLoadString(TEXT("Preferences"),REGVALUE_PREF_START_DIR,1,szDirectory,MAX_PATH);
//
OPENFILENAME ofn;
ZeroMemory(&ofn,sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hWindow;
ofn.hInstance = g_hInstance;
ofn.lpstrFilter = TEXT("Save State files (*.aws)\0*.aws\0")
TEXT("All Files\0*.*\0");
ofn.lpstrFile = szFilename;
ofn.nMaxFile = MAX_PATH;
ofn.lpstrInitialDir = szDirectory;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
ofn.lpstrTitle = pszTitle;
int nRes = bSave ? GetSaveFileName(&ofn) : GetOpenFileName(&ofn);
if(nRes)
{
strcpy(g_szNewFilename, &szFilename[ofn.nFileOffset]);
szFilename[ofn.nFileOffset] = 0;
if (_tcsicmp(szDirectory, szFilename))
strcpy(g_szNewDirectory, szFilename);
}
return nRes;
}
static void InitFreezeDlgButton(HWND window)
{
if (g_bEnableFreezeDlgButton == UNDEFINED)
EnableWindow(GetDlgItem(window, IDC_THE_FREEZES_F8_ROM_FW), IS_APPLE2 ? TRUE : FALSE);
else
EnableWindow(GetDlgItem(window, IDC_THE_FREEZES_F8_ROM_FW), g_bEnableFreezeDlgButton ? TRUE : FALSE);
CheckDlgButton(window, IDC_THE_FREEZES_F8_ROM_FW, g_uTheFreezesF8Rom ? BST_CHECKED : BST_UNCHECKED);
}
//---------------------------------------------------------------------------
static void AdvancedDlg_OK(HWND window, UINT afterclose)
{
char szFilename[MAX_PATH];
memset(szFilename, 0, sizeof(szFilename));
* ((USHORT*) szFilename) = sizeof(szFilename);
UINT nLineLength = SendDlgItemMessage(window,IDC_SAVESTATE_FILENAME,EM_LINELENGTH,0,0);
SendDlgItemMessage(window,IDC_SAVESTATE_FILENAME,EM_GETLINE,0,(LPARAM)szFilename);
nLineLength = nLineLength > sizeof(szFilename)-1 ? sizeof(szFilename)-1 : nLineLength;
szFilename[nLineLength] = 0x00;
SaveStateUpdate();
g_bSaveStateOnExit = IsDlgButtonChecked(window, IDC_SAVESTATE_ON_EXIT) ? true : false;
SAVE(TEXT(REGVALUE_SAVE_STATE_ON_EXIT), g_bSaveStateOnExit ? 1 : 0);
//
g_uCloneType = (DWORD)SendDlgItemMessage(window, IDC_CLONETYPE, CB_GETCURSEL, 0, 0);
SAVE(TEXT(REGVALUE_CLONETYPE), g_uCloneType);
@ -1083,16 +1022,6 @@ static void AdvancedDlg_CANCEL(HWND window)
//---------------------------------------------------------------------------
static void InitFreezeDlgButton(HWND window)
{
if (g_bEnableFreezeDlgButton == UNDEFINED)
EnableWindow(GetDlgItem(window, IDC_THE_FREEZES_F8_ROM_FW), IS_APPLE2 ? TRUE : FALSE);
else
EnableWindow(GetDlgItem(window, IDC_THE_FREEZES_F8_ROM_FW), g_bEnableFreezeDlgButton ? TRUE : FALSE);
CheckDlgButton(window, IDC_THE_FREEZES_F8_ROM_FW, g_uTheFreezesF8Rom ? BST_CHECKED : BST_UNCHECKED);
}
static BOOL CALLBACK AdvancedDlgProc (HWND window,
UINT message,
WPARAM wparam,
@ -1132,6 +1061,23 @@ static BOOL CALLBACK AdvancedDlgProc (HWND window,
case WM_COMMAND:
switch (LOWORD(wparam))
{
case IDC_SAVESTATE_FILENAME:
break;
case IDC_SAVESTATE_BROWSE:
if(SaveStateSelectImage(window, TEXT("Select Save State file"), true))
SendDlgItemMessage(window, IDC_SAVESTATE_FILENAME, WM_SETTEXT, 0, (LPARAM) g_szNewFilename);
break;
case IDC_SAVESTATE_ON_EXIT:
break;
case IDC_SAVESTATE:
afterclose = WM_USER_SAVESTATE;
break;
case IDC_LOADSTATE:
afterclose = WM_USER_LOADSTATE;
break;
//
case IDC_THE_FREEZES_F8_ROM_FW:
{
UINT uNewState = IsDlgButtonChecked(window, IDC_THE_FREEZES_F8_ROM_FW) ? 1 : 0;
@ -1159,6 +1105,14 @@ static BOOL CALLBACK AdvancedDlgProc (HWND window,
{
g_nLastPage = PG_ADVANCED;
SendDlgItemMessage(window,IDC_SAVESTATE_FILENAME,WM_SETTEXT,0,(LPARAM)Snapshot_GetFilename());
CheckDlgButton(window, IDC_SAVESTATE_ON_EXIT, g_bSaveStateOnExit ? BST_CHECKED : BST_UNCHECKED);
g_szNewDirectory[0] = 0x00;
//
FillComboBox(window, IDC_CLONETYPE, g_CloneChoices, g_uCloneType);
InitFreezeDlgButton(window);
@ -1433,12 +1387,6 @@ void PSP_Init()
PropSheetPages[PG_SOUND].pszTemplate = MAKEINTRESOURCE(IDD_PROPPAGE_SOUND);
PropSheetPages[PG_SOUND].pfnDlgProc = (DLGPROC)SoundDlgProc;
PropSheetPages[PG_SAVESTATE].dwSize = sizeof(PROPSHEETPAGE);
PropSheetPages[PG_SAVESTATE].dwFlags = PSP_DEFAULT;
PropSheetPages[PG_SAVESTATE].hInstance = g_hInstance;
PropSheetPages[PG_SAVESTATE].pszTemplate = MAKEINTRESOURCE(IDD_PROPPAGE_SAVESTATE);
PropSheetPages[PG_SAVESTATE].pfnDlgProc = (DLGPROC)SaveStateDlgProc;
PropSheetPages[PG_DISK].dwSize = sizeof(PROPSHEETPAGE);
PropSheetPages[PG_DISK].dwFlags = PSP_DEFAULT;
PropSheetPages[PG_DISK].hInstance = g_hInstance;

View File

@ -9,5 +9,6 @@ void get_tfe_enabled(int *tfe_enabled);
extern UINT g_uScrollLockToggle;
extern UINT g_uMouseInSlot4;
extern UINT g_uMouseShowCrosshair;
extern UINT g_uTheFreezesF8Rom;
extern DWORD g_uCloneType;