What's new

NRage Input Plugin V2.00 BETA (an overhaul)

OP
R

rabiddeity

Plugin Hacker
Harlay's bug is fixed. If anyone sees any more problems with the mempak names, please post a screenshot and/or your mempak file just as he did. Code page problems like that are easy to fix, as long as I have a mempak that uses that character.
 

MadManMarkAu

Transfer Pak Expert
Wow... leave for a few years and see what happens. :p

My goodness you've done a lot of work on this plugin over the last year and a half! You, sir, I take my hat off to. *bows*

Just wondering if you managed to get the GB timer working. I don't think I ever got around to doing that before work obligations forced me to more or less abandon the plugin.

Now, just need to find my controller >.>

EDIT: Oh ho, you did get the timer working! Nice job! I remember I was having difficulties with the VisualBoy save format. No$GMB was right out of the question.

EDIT2: Oh, not quite fixed :( Still messes up the days and stuff, but that might be an effect of VBA. VBA doesn't seem to hold the time correctly for some reason. :eek:
 
Last edited:
OP
R

rabiddeity

Plugin Hacker
Really, I owe it to you for doing all the Transfer Pak research and code. I don't want to know how much searching you had to do in order to get all those MBC modes figured out, in addition to the translation done by the transfer pak itself. From what I can tell it was all reverse engineered without any documentation. On the contrary, my hat is off to you.

There are very likely still some bugs in the GBA timer code. At this point I'm not really sure whether the kinks are in the NRage plugin code or in the GB emulator code. However, since VBA source code is available under GPL it shouldn't be too difficult to look at the source and make sure our end is writing to the save file correctly. Which of the Pokemon games uses the timer, and exactly how is it supposed to work?
 

MadManMarkAu

Transfer Pak Expert
If I remember correctly, Pokemon Silver and Gold use the timer as well as a few others, and can only be used with Pokemon Stadium 2. It's been far too long since I did anything with Transfer Paks so my memory is a little vague.

From memory, I believe you have to write a value to a certain area on the Transfer Pak to enable it. Once that is done, you can access the GB cart via a banked memory window of 0x4000 bytes, I think. The whole of the GB cart can be read or written via this memory window. By writing a value to another memory area on the Transfer Pak, you can switch the Transfer Pak's bank window between the addresses 0x0000-0x3FFF, 0x4000-0x7FFF, 0x8000-0xBFFF, 0xC000-0xFFFF on the GB cart. Reads and writes are 32-bytes in size, and I *think* they are clipped to the 32-byte boundaries (ie. a read from 0x27F will read 0x260).

Note, that this is accessing the cart itself directly, and not via the normal GameBoy internal memory bank switching. However, any bank switching supplied by the cart itself will still apply. This includes switching in the timer.

Everything was reverse engineered from a handful of data captures of a real adaptoid with a transfer pak, and lots of googling.

I'll take a look at the timer saves for VisualBoy and VisualBoy Advance later tonight if I get time, see if I can't work something out.
 

MadManMarkAu

Transfer Pak Expert
You know those times when you look back on code you've written in the past and gone, "What the hell was I thinking?"... This is one of those times.

I've fixed the timer code. The day counting was messed up badly. All works well now, I'm happy to say. I think the MBC7 chip needs work, too. There's some stuff I discovered looking at the VBA source that I never implemented. That's work for tomorrow. Now, it's waaay pate bed time.

radibdeity, I only had the 2.00 revision 17 source to go on, but as far as I know nothing in GBCart.cpp has changed since then, so I'll attach here. Hopefully it'll come through.

EDIT: Ok, attachments, for me at least, don't seem to be working. I've uploaded the file here: http://h1.ripway.com/MadManMarkAu/GBCart.zip
 
Last edited:

p_025

Voted Least Likely to Succeed
I stand thoroughly corrected, I guess you can use the Transfer Pak with an Adaptoid, to an extent. It looks like you just went right in there and fixed this timer issue in a matter of a couple hours. But what timer were you really talking about? If it's for the clock, I thought time was kept pretty well on the games...
 

MadManMarkAu

Transfer Pak Expert
I remember there was an issue with Pokemon Stadium 2 not getting the correct day, thus not allowing you to trade mystery gifts on consecutive days. Or, at least, the day was showing up wrong. Something like that.

As for the TPak with Adaptoid, I don't know how it was done, I didn't do it. I got the captures from N-Rage when I got the source.

(Note to self, staying up until 1AM coding, then getting up at 5AM for work, is NOT fun.)

EDIT: I'll just add, it was incorrect handling of the timer overflow flags that added 256 days to the timer every time it was updated, until the timer set its "512 or greater" flag, causing the GB game to ask to reset the time.
 
Last edited:
OP
R

rabiddeity

Plugin Hacker
You know those times when you look back on code you've written in the past and gone, "What the hell was I thinking?"... This is one of those times.

I've fixed the timer code. The day counting was messed up badly. All works well now, I'm happy to say. I think the MBC7 chip needs work, too. There's some stuff I discovered looking at the VBA source that I never implemented. That's work for tomorrow. Now, it's waaay pate bed time.

radibdeity, I only had the 2.00 revision 17 source to go on, but as far as I know nothing in GBCart.cpp has changed since then, so I'll attach here. Hopefully it'll come through.

EDIT: Ok, attachments, for me at least, don't seem to be working. I've uploaded the file here: http://h1.ripway.com/MadManMarkAu/GBCart.zip

OK, a couple things.

Send a PM to squall and he'll hook you up with access to the Subversion server. That way you can pull the most current source, update it yourself, and even if one of us screws up we can roll it back. We can even edit the source at the same time and merge the changes when we commit. If you've ever worked with source control like CVS it's a really awesome tool.

The RTC data is currently tacked on to the end of the Cart->RamData, because that's how the SAV format handles it. It's done this way because it makes mapping the file much easier but it complicates things for error cases or external TDF files. Example:

Line 394 in your version is not doing what you think it is. At this point in execution, the file exists but is read-only. As we can't map the file, we malloc some ram instead and read the data into that. The first call on 392 reads in the first 0x0800 bytes of the file into malloc'd Cart->RamData. The second call tries to read in the next 0x0800 bytes and overwrite Cart->RamData. If the file is exactly 0x0800 then the call fails and there's no problem. If it's longer (e.g. a SAV with RTC data), the call succeeds and the RamData gets clobbered. As it was before, if the SAV file is read-only then it only read in the RAM data and ignored the RTC. This was a bug, but I've tried to fix it. For reading TDF, that's a separate file and needs a separate handle and separate read, and shouldn't be handled within this error block. I'd say even add new functions, ReadTDF and WriteTDF and handle the read within there. I've stubbed them in but you'll have to add the WriteTDF code where it needs to go.

We need a flag in Cart called useTDF. We set it true if it's an RTC cart and the SAV file doesn't have the RTC data tacked on. I'll fix that shortly.

Your fix to UpdateRTC looks good. Also the fixes to RTC latching. I haven't tested it but if it works then it works!

I've fixed a bug I introduced that wouldn't malloc/read the data properly in the edge case where the SAV file was readonly and contained RTC data. Before it would just ignore it. Didn't matter much anyway, since it wouldn't save, but it wasn't good coding on my part. Reread the code around line 394 in the new edition of this file and see if it's a bit better.

http://www.randomwisdom.com/files/GBCart.zip
 

MadManMarkAu

Transfer Pak Expert
Oh my. You're right, I messed it up. One of the ReadFile lines wasn't supposed to be there. Also, I didn't follow my logic correctly. I'll tackle the TDF data tonight.

EDIT: Oh yeah. I'll message squall about the SVN server.

EDIT2: I can't remember what emulator used the TDF file for the timer. I've started on the .RTC file generated from NO$GMB-win instead.
 
Last edited:
OP
R

rabiddeity

Plugin Hacker
Cool, feel free to change the name of the function to make it more generic. I've committed your changes to the bountysource SVN and uploaded a new DEBUG.
 
OP
R

rabiddeity

Plugin Hacker
I don't know what it is, and I don't recommend putting it in your plugins folder. All I've been able to tell is that it's compressed with some sort of dll packer (DSPACK, maybe the Delphi packer?), so it's difficult to disassemble to figure out what it actually does. If it contains malicious code (which it probably does) then your emulator will switch execution to it as soon as you open up the properties list (N64 emulators call GetDllInfo so the DLL identifies itself).

If you send me a PM telling where you found it, that'd be interesting info.

As always, the links to the newest version of the plugin will be on the top post of this thread.
 

squall_leonhart

The Great Gunblade Wielder
well, according to bountysource dev's Bountysource development has ceased, and bountysource itself is no longer setting cookies when you log in (i've tried both firefox and ie) which means... I CAN'T LOGIN TO THE SITE.

...so im going to dump all the revisions and upload them to a google code svn.
 
OP
R

rabiddeity

Plugin Hacker
And I'll switch the link back to my own SVN server. If anyone wants commit access, PM me and I'll sort out the details.

squall, if you're dumping revisions, can you dump the revision set from my SVN? It's got a lot more detail for past updates, and it's at revision 33 right now. I think public access should let you do that, but if you need special access just ask. If there's a way to get it to sync with my SVN automatically that'd be fantastic.
 

squall_leonhart

The Great Gunblade Wielder
yeah; since i already started, i'll reset the svn on google code and move all of the stuff from your svn over.

it'll take a few days since my net is approaching being capped.
 

squall_leonhart

The Great Gunblade Wielder
Bountysource is back available

im contemplating moving to sourceforge rather then google code, since it seems friendlier for svn.
 

MadManMarkAu

Transfer Pak Expert
Unfortunately, I've never used an svn server, so I don't know any good ones. The code control we do at work I do by hand comparing files and copy/pasting procedures. Thankfully we sync our code every day or two, so updates usually involve two or three files.
 

score_under

New member
I made a patch to compile and run it on GCC, with a glovepie-compatible rumble feature (move mouse to 1,0 if rumbling, else 0,0)

BIG FILE AHEAD. Copy and paste it into a .patch file, and patch SVN revision 33 with it.
This works fine on GCC, but please someone tell me if it works on Visual C++ too. If it does - bring the changes into the SVN copy!
Code:
Index: Build.bat
===================================================================
--- Build.bat	(revision 0)
+++ Build.bat	(revision 0)
@@ -0,0 +1,3 @@
+@echo off
+windres -o res.o NRageP~1.rc
+gcc -shared -w -o NRageBeta.dll res.o NRagePluginV2.cpp International.cpp PakIO.cpp FileAccess.cpp Interface.cpp GBCart.cpp DirectInput.cpp Debug.cpp -lstdc++ -ldinput8 -lcomctl32 -lcomdlg32 -ldxguid 2>err.log
\ No newline at end of file
Index: Debug.cpp
===================================================================
--- Debug.cpp	(revision 33)
+++ Debug.cpp	(working copy)
@@ -154,4 +154,4 @@
 	{
 		FlushFileBuffers(hDebug);
 	}
-}
\ No newline at end of file
+}
Index: Debug.h
===================================================================
--- Debug.h	(revision 33)
+++ Debug.h	(working copy)
@@ -62,4 +62,4 @@
 #define DebugWrite DebugWriteA
 #endif
 
-#endif // #ifndef _DEBUG_H_
\ No newline at end of file
+#endif // #ifndef _DEBUG_H_
Index: DirectInput.cpp
===================================================================
--- DirectInput.cpp	(revision 33)
+++ DirectInput.cpp	(working copy)
@@ -561,7 +561,15 @@
 	{
 		HRESULT (WINAPI *lpGetDIHandle)( HINSTANCE, DWORD, REFIID, LPVOID*, LPUNKNOWN ) = NULL;
 		lpGetDIHandle = (HRESULT (WINAPI *)( HINSTANCE, DWORD, REFIID, LPVOID*, LPUNKNOWN ))GetProcAddress( g_hDirectInputDLL, "DirectInput8Create" );
-
+		if(g_strEmuInfo.hinst==NULL)
+		{
+			DllMain(GetModuleHandle("NRageBeta.dll"),DLL_PROCESS_ATTACH,0);
+		}
+		if(g_strEmuInfo.hinst/*still*/==NULL)
+		{
+			DllMain(GetModuleHandle(NULL),DLL_PROCESS_DETACH,0);
+			DllMain(GetModuleHandle(NULL),DLL_PROCESS_ATTACH,0);
+		}
 		if( lpGetDIHandle != NULL )
 		{
 			HRESULT hr;
@@ -1038,7 +1046,7 @@
 		}
 
 		ReleaseEffect( g_apdiEffect[i] );
-		if( g_pcControllers[i].guidFFDevice != GUID_NULL && GetInputDevice( g_strEmuInfo.hMainWindow, g_apFFDevice[i], g_pcControllers[i].guidFFDevice, DI8DEVTYPE_JOYSTICK, DIB_FF )) // not necessarily a joystick type device, but we don't use the data anyway
+		if( g_pcControllers[i].guidFFDevice != guidnull && GetInputDevice( g_strEmuInfo.hMainWindow, g_apFFDevice[i], g_pcControllers[i].guidFFDevice, DI8DEVTYPE_JOYSTICK, DIB_FF )) // not necessarily a joystick type device, but we don't use the data anyway
 		{
 			DIDEVICEINSTANCE diDev;
 			diDev.dwSize = sizeof( DIDEVICEINSTANCE );
@@ -1283,4 +1291,4 @@
 	default:
 		return false;
 	}
-}
\ No newline at end of file
+}
Index: DirectInput.h
===================================================================
--- DirectInput.h	(revision 33)
+++ DirectInput.h	(working copy)
@@ -153,4 +153,4 @@
 }
 
 
-#endif // #ifndef _DIRECTINPUT_H_
\ No newline at end of file
+#endif // #ifndef _DIRECTINPUT_H_
Index: FileAccess.cpp
===================================================================
--- FileAccess.cpp	(revision 33)
+++ FileAccess.cpp	(working copy)
@@ -1,4 +1,4 @@
- /*	
+/*	
 	N-Rage`s Dinput8 Plugin
     (C) 2002, 2006  Norbert Wladyka
 
@@ -192,7 +192,7 @@
 	{
 	case PL_RESET:
 		ZeroMemory( pszDeviceName, sizeof(pszDeviceName) );
-		gGUID = GUID_NULL;
+		gGUID = guidnull;
 		bDeviceNr = 0;
 		break;
 
@@ -314,6 +314,10 @@
 		if (pController)
 			pController->fVisualRumble = atoi(pszLine);
 		break;
+	case CHK_GLOVEPIERUMBLE:
+		if (pController)
+			pController->fGPieRumble = atoi(pszLine);
+		break;
 	case CHK_FFDEVICEGUID:
 		if (pController)
 		{
@@ -330,7 +334,7 @@
 				}
 				else
 				{
-					pController->guidFFDevice = GUID_NULL;
+					pController->guidFFDevice = guidnull;
 					return false;
 				}
 			}
@@ -373,12 +377,12 @@
 		break;
 
 	case CHK_DINPUTNAME:
-		gGUID = GUID_NULL;	// invalidate current GUID
+		gGUID = guidnull;	// invalidate current GUID
 		CHAR_TO_TCHAR( pszDeviceName, pszLine, MAX_PATH );
 		break;
 
 	case CHK_DINPUTNR:
-		gGUID = GUID_NULL;	// invalidate current GUID
+		gGUID = guidnull;	// invalidate current GUID
 		if( iLength >= sizeof(BYTE) )
 		{
 			TexttoHexA( pszLine, &bDeviceNr, sizeof(BYTE) );
@@ -389,7 +393,7 @@
 			return true;
 		else
 		{
-			gGUID = GUID_NULL;	// invalidate current GUID
+			gGUID = guidnull;	// invalidate current GUID
 			return false;
 		}
 		break;
@@ -453,7 +457,7 @@
 					else
 					{
 						DebugWrite(_T("ProcessKey: couldn't find a device in g_devList for %s %d\n"), pszDeviceName, bDeviceNr);
-						gGUID = GUID_NULL;
+						gGUID = guidnull;
 						btnWorking.parentDevice = NULL;
 					}
 				}
@@ -464,7 +468,7 @@
 				// bounds check on controlnum and buttonID
 				if ( (controlnum == -1 && buttonID != 0) && ((controlnum < 0) || (controlnum > 3) || (buttonID < 0) || (buttonID >= SC_TOTAL)) )
 				{
-					gGUID = GUID_NULL;	// since we may have cached an invalid GUID, invalidate it
+					gGUID = guidnull;	// since we may have cached an invalid GUID, invalidate it
 					return false;
 				}
 
@@ -485,7 +489,7 @@
 				// bounds check on controlnum and buttonID
 				if ( (controlnum < 0) || (controlnum > 3) || (buttonID < 0) || (buttonID >= ARRAYSIZE(g_pcControllers[0].aButton)) )
 				{
-					gGUID = GUID_NULL;	// since we may have cached an invalid GUID, invalidate it
+					gGUID = guidnull;	// since we may have cached an invalid GUID, invalidate it
 					return false;
 				}
 
@@ -555,7 +559,7 @@
 					}
 					else
 					{
-						gGUID = GUID_NULL;
+						gGUID = guidnull;
 						modWorking.btnButton.parentDevice = NULL;
 					}
 				}
@@ -564,7 +568,7 @@
 			// bounds check on controlnum and buttonID
 			if ( (controlnum < 0) || (controlnum > 3) )
 			{
-				gGUID = GUID_NULL;	// since we may have cached an invalid GUID, invalidate it
+				gGUID = guidnull;	// since we may have cached an invalid GUID, invalidate it
 				return false;
 			}
 
@@ -598,7 +602,6 @@
 
 		}
 		break;
-
 	}
 
 	return bReturn;
@@ -1487,6 +1490,7 @@
 	fprintf(fFile, STRING_INI_RUMBLETYPE "=%u\n", g_ivConfig->Controllers[i].bRumbleTyp);
 	fprintf(fFile, STRING_INI_RUMBLESTRENGTH "=%u\n", g_ivConfig->Controllers[i].bRumbleStrength);
 	fprintf(fFile, STRING_INI_VISUALRUMBLE "=%u\n", g_ivConfig->Controllers[i].fVisualRumble);
+	fprintf(fFile, STRING_INI_GLOVEPIERUMBLE "=%u\n", g_ivConfig->Controllers[i].fGPieRumble);
 
 	if (bIsINI)
 	{
@@ -1548,7 +1552,7 @@
 		if (bIsINI)
 		{
 			char szGUID[DEFAULT_BUFFER];
-			GUIDtoStringA(szGUID, GUID_NULL);
+			GUIDtoStringA(szGUID, guidnull);
 			fprintf(fFile, STRING_INI_DINPUTGUID "=%s\n", szGUID);
 		}
 		else
@@ -1671,4 +1675,4 @@
         hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
 
     return hash;
-}
\ No newline at end of file
+}
Index: FileAccess.h
===================================================================
--- FileAccess.h	(revision 33)
+++ FileAccess.h	(working copy)
@@ -101,6 +101,7 @@
 #define STRING_INI_RUMBLETYPE	"RumbleType"
 #define STRING_INI_RUMBLESTRENGTH	"RumbleStrength"
 #define STRING_INI_VISUALRUMBLE	"VisualRumble"
+#define STRING_INI_GLOVEPIERUMBLE	"GlovePieRumble"
 #define STRING_INI_FFDEVICEGUID	"FFDeviceGUID"
 #define STRING_INI_MEMPAKFILE	"MemPakFile"
 #define STRING_INI_GBROMFILE	"GBRomFile"
@@ -168,6 +169,7 @@
 #define CHK_RUMBLETYPE		3440038446
 #define CHK_RUMBLESTRENGTH	3038086267
 #define CHK_VISUALRUMBLE	1795686016
+#define CHK_GLOVEPIERUMBLE	0x55148147
 #define CHK_FFDEVICEGUID	2645316746
 #define CHK_MEMPAKFILE		2373591360
 #define CHK_GBROMFILE		2409678172
@@ -222,4 +224,4 @@
 	// 32 hex characters, 4 hyphens, 2 end braces
 #define GUID_STRINGLENGTH	32+4+2
 
-#endif // #ifndef _FILEACCESS_H_
\ No newline at end of file
+#endif // #ifndef _FILEACCESS_H_
Index: Interface.cpp
===================================================================
--- Interface.cpp	(revision 33)
+++ Interface.cpp	(working copy)
@@ -1715,7 +1715,7 @@
 	case WM_INITDIALOG:
 		hPakWindow = NULL;
 		bAdaptoidInList = false;
-		bCurrentPak = -1;
+		bCurrentPak = (BYTE)-1;
 
 		// DropDown-List;
 		hDlgItem = GetDlgItem( hDlg, IDC_PAKTYPE );
@@ -2165,7 +2165,7 @@
 			j = -1;
 			if( !( pszMemPakFile[1] == ':' || ( pszMemPakFile[1] == '\\' && pszMemPakFile[0] == '\\' )) )
 			{
-				i = SendMessage( hDlgItem, LB_FINDSTRINGEXACT, -1, (LPARAM)pszMemPakFile );
+				i = SendMessage( hDlgItem, LB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)pszMemPakFile );
 				if( i != LB_ERR )
 					j = i;
 			}
@@ -2381,6 +2381,10 @@
 		case IDC_VISUALRUMBLE:
 			pcController->fVisualRumble = ( IsDlgButtonChecked( hDlg, LOWORD(wParam) ) == BST_CHECKED );
 			return TRUE;
+			
+		case IDC_GLOVEPIERUMBLE:
+			pcController->fGPieRumble = ( IsDlgButtonChecked( hDlg, LOWORD(wParam) ) == BST_CHECKED );
+			return TRUE;
 
 		case IDC_RUMBLETEST:
 			if ( !g_pConfigEffect || bNewRumbleTyp )
@@ -2506,11 +2510,11 @@
 
 			// DropDownList
 			if( g_devList[j].bProductCounter == 0 )
-				i = SendMessage( hDlgItem, CB_FINDSTRINGEXACT, -1, (LPARAM)g_devList[j].szProductName );
+				i = SendMessage( hDlgItem, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)g_devList[j].szProductName );
 			else
 			{
 				wsprintf( szBuffer, _T("%s %i"), g_devList[j].szProductName, g_devList[j].bProductCounter );
-				i = SendMessage( hDlgItem, CB_FINDSTRINGEXACT, -1, (LPARAM)szBuffer ); // search index of Device-String
+				i = SendMessage( hDlgItem, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)szBuffer ); // search index of Device-String
 			}
 
 			SendMessage( hDlgItem, CB_SETCURSEL, i, 0 ); // select the right string
@@ -2569,6 +2573,7 @@
 			CheckDlgButton( hDlg, IDC_RUMBLE3, BST_UNCHECKED );
 
 		CheckDlgButton( hDlg, IDC_VISUALRUMBLE, pcController->fVisualRumble ? BST_CHECKED : BST_UNCHECKED );
+		CheckDlgButton( hDlg, IDC_GLOVEPIERUMBLE, pcController->fGPieRumble ? BST_CHECKED : BST_UNCHECKED );
 
 		// TrackBars
 		SendMessage( GetDlgItem( hDlg, IDC_RUMBLESTRENGTH ), TBM_SETPOS, TRUE, pcController->bRumbleStrength );
@@ -2888,7 +2893,7 @@
 			}
 
 		DWORD aIDs[3];
-		aIDs[2] = -1;
+		aIDs[2] = (DWORD)-1;
 		if( GetButtonID( aIDs, 2, BSET_SHORTCUTS ) )
 		{
 			GetButtonText( g_ivConfig->Shortcuts.bMouseLock, szBuffer );
@@ -3863,7 +3868,7 @@
 		}
 		else
 		{
-			g_pcControllers[i].guidFFDevice = GUID_NULL;
+			g_pcControllers[i].guidFFDevice = guidnull;
 		}
 
 
@@ -3949,4 +3954,4 @@
 	// Show the window (necessary to block input)
 	ShowWindow(hwnd, SW_SHOWNOACTIVATE);
 	return hwnd;
-}
\ No newline at end of file
+}
Index: Interface.h
===================================================================
--- Interface.h	(revision 33)
+++ Interface.h	(working copy)
@@ -90,4 +90,4 @@
 
 extern INTERFACEVALUES *g_ivConfig;
 
-#endif // _NRINTERFACE_
\ No newline at end of file
+#endif // _NRINTERFACE_
Index: International.cpp
===================================================================
--- International.cpp	(revision 33)
+++ International.cpp	(working copy)
@@ -114,7 +114,7 @@
     if (hMod) {
         pImmReleaseContext = (IMMRELEASECONTEXT)GetProcAddress(hMod,"ImmReleaseContext");
         if (pImmReleaseContext) {
-            bRet = pImmReleaseContext(NULL,NULL);
+            bRet = pImmReleaseContext(NULL,0);
         }
         FreeLibrary(hMod);
     }
Index: NRagePluginV2.cpp
===================================================================
--- NRagePluginV2.cpp	(revision 33)
+++ NRagePluginV2.cpp	(working copy)
@@ -64,6 +64,7 @@
 SHORTCUTS g_scShortcuts;
 LPDIRECTINPUTDEVICE8 g_apFFDevice[4] = { NULL, NULL, NULL, NULL };					// added by rabid
 LPDIRECTINPUTEFFECT  g_apdiEffect[4] = { NULL, NULL, NULL, NULL };					// array of handles for FF-Effects, one for each controller
+GUID guidnull={0,0,0,{0,0,0,0,0,0,0,0}};
 
 BOOL APIENTRY DllMain( HINSTANCE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved )
 {
@@ -384,7 +385,7 @@
 			}
 			else // we couldn't find the device specified in the INI file, or it was already null
 			{
-				g_pcControllers[i].guidFFDevice = GUID_NULL;
+				g_pcControllers[i].guidFFDevice = guidnull;
 				DebugWriteA("no rumble device/effect type set, ");
 			}
 
@@ -822,7 +823,7 @@
 // After enumerating DirectInput devices into g_devList, find a device by GUID.  Finding similar devices is impossible.
 int FindDeviceinList( REFGUID rGUID )
 {
-	if (rGUID == GUID_NULL )
+	if (rGUID == guidnull )
 		return -1;
 	int i = 0;
 	while( i < ARRAYSIZE(g_devList) )
@@ -1172,4 +1173,4 @@
 	LoadString( g_hResourceDLL, IDS_DLG_WARN_TITLE, tszTitle, DEFAULT_BUFFER );
 
 	return MessageBox( g_strEmuInfo.hMainWindow, tszText, tszTitle, uType );
-}
\ No newline at end of file
+}
Index: NRagePluginV2.h
===================================================================
--- NRagePluginV2.h	(revision 33)
+++ NRagePluginV2.h	(working copy)
@@ -144,6 +144,7 @@
 	unsigned fPakCRCError;		// The ROM sends CRC data when it tries to write to a mempak.  Is the CRC incorrect?  Usually indicates a bad ROM.
 	unsigned PakType;			// what type of controller pak? mempak? rumble? transfer? etc
 	unsigned fVisualRumble;		// is visual rumble enabled for this controller?
+	unsigned fGPieRumble;		//Is GlovePie rumble enabled? (moves mouse to (1,0) and (0,0), use with mouse.cursorposX==1 and mouse.cursorposy==0)
 
 	BYTE bRumbleTyp;				// what type of rumble effect? none, constant, ramp, or direct?
 
@@ -366,11 +367,13 @@
 extern LPDIRECTINPUTDEVICE8 g_apFFDevice[4];
 extern LPDIRECTINPUTEFFECT g_apdiEffect[4];
 extern CRITICAL_SECTION g_critical;
+extern GUID guidnull;
 
 extern bool g_bRunning;
 extern bool g_bConfiguring;
 extern bool g_bExclusiveMouse;
 
+extern BOOL APIENTRY DllMain( HINSTANCE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved );
 
 extern int g_iFirstController;
 
@@ -382,4 +385,4 @@
 void CheckShortcuts();
 bool ErrorMessage( UINT uID, DWORD dwError, bool fUserChoose );
 
-#endif
\ No newline at end of file
+#endif
Index: NRagePluginV2.rc
===================================================================
--- NRagePluginV2.rc	(revision 33)
+++ NRagePluginV2.rc	(working copy)
@@ -623,6 +623,8 @@
                     29,82,61,10
     CONTROL         "Visual Rumble",IDC_VISUALRUMBLE,"Button",
                     BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,99,58,61,10
+    CONTROL         "GlovePie-compatible Rumble",IDC_GLOVEPIERUMBLE,"Button",
+                    BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,99,70,120,10
     CTEXT           "Rumble Strength PLACEHOLDER",IDT_RUMBLESTRENGTH,29,100,
                     127,8,NOT WS_GROUP
     CONTROL         "",IDC_RUMBLESTRENGTH,"msctls_trackbar32",TBS_AUTOTICKS | 
Index: PakIO.cpp
===================================================================
--- PakIO.cpp	(revision 33)
+++ PakIO.cpp	(working copy)
@@ -38,6 +38,8 @@
 BYTE DataCRC( LPCBYTE Data, const int iLength );
 VOID CALLBACK WritebackProc( HWND hWnd, UINT msg, UINT_PTR idEvent, DWORD dwTime );
 
+#define min(x,y) ((x<y)?x:y)
+
 bool InitControllerPak( const int iControl )
 // Prepares the Pak
 {
@@ -495,6 +497,8 @@
 		{
 			if( g_pcControllers[iControl].fVisualRumble )
 				FlashWindow( g_strEmuInfo.hMainWindow, ( *Data != 0 ) ? TRUE : FALSE );
+			if( g_pcControllers[iControl].fGPieRumble ) //Oh, the haxx0redness
+				SetCursorPos(*Data!=0,0);
 			if( g_pcControllers[iControl].bRumbleTyp == RUMBLE_DIRECT )
 			{  // Adaptoid Direct Rumble
 				if( g_pcControllers[iControl].fIsAdaptoid )
@@ -1480,4 +1484,4 @@
 		}
 		return;
 	}
-}
\ No newline at end of file
+}
Index: PakIO.h
===================================================================
--- PakIO.h	(revision 33)
+++ PakIO.h	(working copy)
@@ -170,4 +170,4 @@
 	bool fRumblePak;
 } ADAPTOIDPAK, *LPADAPTOIDPAK;
 
-#endif // #ifndef _PAKIO_H_
\ No newline at end of file
+#endif // #ifndef _PAKIO_H_
Index: resource.h
===================================================================
--- resource.h	(revision 33)
+++ resource.h	(working copy)
@@ -299,6 +299,7 @@
 #define IDC_FORMATMEMPAK                1128
 #define IDC_SAVENOTE                    1129
 #define IDC_VISUALRUMBLE                1129
+#define IDC_GLOVEPIERUMBLE              2229
 #define IDC_SETMEMPAK_P3                1130
 #define IDC_INSERTNOTE                  1130
 #define IDC_STATE                       1130
Index: settings.h
===================================================================
--- settings.h	(revision 33)
+++ settings.h	(working copy)
@@ -136,4 +136,4 @@
 #define VERSIONINFO _T(VERSIONNUMBER)
 #endif // #ifdef _DEBUG
 
-#endif // #ifndef _SETTINGS_H_
\ No newline at end of file
+#endif // #ifndef _SETTINGS_H_

Edit: The script I used to control Zelda:OoT with the Wii Remote...
Code:
//WiiZelda64.PIE
PIE.FrameRate=75hz
var.calibration=0.7
debug=Wiimote1.Battery/1.92+'  --  '+MapRange(Wiimote1.RawForceX, -128,128, -1,1)
PPJoy1.Analog0=Wiimote1.Nunchuk.JoyX
PPJoy1.Analog1=Wiimote1.Nunchuk.JoyY
PPJoy1.Digital0=Wiimote1.A
PPJoy1.Digital1=Wiimote1.B||(MapRange(Wiimote1.RawForceX, -128,128, -1,1)>var.calibration||MapRange(Wiimote1.RawForceX, -128,128, -1,1)<-var.calibration) || (MapRange(Wiimote1.RawForceY, -128,128, -1,1)>var.calibration||MapRange(Wiimote1.RawForceY, -128,128, -1,1)<-var.calibration)
PPJoy1.Digital2=Wiimote1.Nunchuk.CButton
PPJoy1.Digital3=Wiimote1.Nunchuk.ZButton
PPJoy1.Digital4=Wiimote1.Home
PPJoy1.Digital5=Wiimote1.Up
PPJoy1.Digital6=Wiimote1.Down
PPJoy1.Digital7=Wiimote1.Left
PPJoy1.Digital8=Wiimote1.Right
PPJoy1.Digital9=Wiimote1.Plus
Key.F4=Wiimote1.Minus //PJ64 Speed Limit
Key.LeftControl+Key.C=Wiimote1.One //PJ64 Cheats
Key.Escape=Wiimote1.Two //Maximize PJ64
Wiimote1.Leds=1
//And finally, the hack!
Wiimote1.Rumble=(Mouse.CursorPosX==1)&&(Mouse.CursorPosY==0)
 
Last edited:

Top