rumble, tilt, IR, wii controls support (merged from Carl Kenner's changes)

This commit is contained in:
dborth 2009-03-04 06:56:55 +00:00
parent 29985288e6
commit ea97d00742
5 changed files with 4151 additions and 80 deletions

3777
source/ngc/gameinput.cpp Normal file

File diff suppressed because it is too large Load Diff

129
source/ngc/gameinput.h Normal file
View File

@ -0,0 +1,129 @@
/****************************************************************************
* Visual Boy Advance GX
*
* Carl Kenner Febuary 2009
*
* gameinput.h
*
* Wii controls for individual games
***************************************************************************/
#ifndef _GAMEINPUT_H_
#define _GAMEINPUT_H_
#define gid(a,b,c) (a|(b<<8)|(c<<16))
#define BOKTAI1 gid('U','3','I')
#define BOKTAI2 gid('U','3','2')
#define BOKTAI3 gid('U','3','3')
#define ZELDA1 gid('F','Z','L')
#define ZELDA2 gid('F','L','B')
#define ALINKTOTHEPAST gid('A','Z','L')
#define LINKSAWAKENING 0xFF0001
#define ORACLEOFSEASONS gid('A','Z','7')
#define ORACLEOFAGES gid('A','Z','8')
#define MINISHCAP gid('B','Z','M')
#define METROID0 gid('B','M','X')
#define MARIO1CLASSIC gid('F','S','M')
#define MARIO1DX gid('A','H','Y')
#define MARIO2CLASSIC gid('F','M','2')
#define MARIO2ADV gid('A','M','Z')
#define MARIO3ADV gid('A','X','4')
#define MARIOWORLD gid('A','A','2')
#define YOSHIISLAND gid('A','3','A')
#define MARIOLAND1 0xFF0007
#define MARIOLAND2 0xFF0008
#define HARRYPOTTER1 gid('A','H','R')
#define HARRYPOTTER1GBC gid('B','H','V')
#define HARRYPOTTER2 gid('A','7','H')
#define HARRYPOTTER2GBC gid('B','H','6')
#define HARRYPOTTER3 gid('B','H','T')
#define HARRYPOTTER4 gid('B','H','8')
#define HARRYPOTTER5 gid('B','J','X')
#define QUIDDITCH gid('B','H','P')
#define TMNT gid('B','E','X')
#define RESIDENTEVIL gid('B','I','O')
#define MOHUNDERGROUND gid('A','U','G')
#define MOHINFILTRATOR gid('B','M','H')
#define KOROKORO gid('K','H','P')
#define YOSHIUG gid('K','Y','G')
#define KIRBYTNT gid('K','T','N')
#define KIRBYTNTJ gid('K','K','K')
#define TWISTED gid('R','Z','W')
#define MARIOGOLF gid('A','W','X')
#define MARIOTENNIS gid('B','M','8')
#define MARIOKART gid('A','M','K')
#define LSW1 gid('B','L','W')
#define LSW2 gid('B','L','7')
#define BIONICLEHEROES gid('B','I','H')
#define MK1 0xFF0002
#define MK2 0xFF0003
#define MK12 0xFF0004
#define MK3 0xFF0005
#define MK4 0xFF0006
#define MKA gid('A','M','5')
#define MKDA gid('A','X','D')
#define MKTE gid('A','W','4')
u8 gbReadMemory(register u16 address);
void gbWriteMemory(register u16 address, register u8 value);
u32 StandardDPad(unsigned short pad);
u32 StandardMovement(unsigned short pad);
u32 StandardSideways(unsigned short pad);
u32 StandardClassic(unsigned short pad);
u32 StandardGamecube(unsigned short pad);
u32 StandardKeyboard(unsigned short pad);
u32 MarioLand1Input(unsigned short pad);
u32 MarioLand2Input(unsigned short pad);
u32 LegoStarWars1Input(unsigned short pad);
u32 LegoStarWars2Input(unsigned short pad);
u32 MarioKartInput(unsigned short pad);
u32 MK1Input(unsigned short pad);
u32 MK4Input(unsigned short pad);
u32 MKAInput(unsigned short pad);
u32 MKTEInput(unsigned short pad);
u32 Zelda1Input(unsigned short pad);
u32 Zelda2Input(unsigned short pad);
u32 ALinkToThePastInput(unsigned short pad);
u32 LinksAwakeningInput(unsigned short pad);
u32 OracleOfAgesInput(unsigned short pad);
u32 MinishCapInput(unsigned short pad);
u32 MetroidZeroInput(unsigned short pad);
u32 TMNTInput(unsigned short pad);
u32 HarryPotter1Input(unsigned short pad);
u32 HarryPotter1GBCInput(unsigned short pad);
u32 HarryPotter2Input(unsigned short pad);
u32 HarryPotter2GBCInput(unsigned short pad);
u32 HarryPotter3Input(unsigned short pad);
u32 HarryPotter4Input(unsigned short pad);
u32 HarryPotter5Input(unsigned short pad);
u32 Mario1ClassicInput(unsigned short pad);
u32 Mario1DXInput(unsigned short pad);
u32 Mario2Input(unsigned short pad);
u32 Mario3Input(unsigned short pad);
u32 MarioWorldInput(unsigned short pad);
u32 YoshiIslandInput(unsigned short pad);
u32 UniversalGravitationInput(unsigned short pad);
u32 MohUndergroundInput(unsigned short pad);
u32 MohInfiltratorInput(unsigned short pad);
u32 TwistedInput(unsigned short pad);
u32 KirbyTntInput(unsigned short pad);
u32 BoktaiInput(unsigned short pad);
u32 Boktai2Input(unsigned short pad);
#endif

View File

@ -10,9 +10,9 @@
#include "gamesettings.h"
int gameSettingsCount = 104;
int gameSettingsCount = 106;
gameSetting gameSettings[104] = {
gameSetting gameSettings[106] = {
{
"Dragon Ball Z - The Legacy of Goku II (Europe)(En,Fr,De,Es,It)",
"ALFP",
@ -344,7 +344,7 @@ gameSetting gameSettings[104] = {
{
"Yoshi - Topsy-Turvy (USA)",
"KYGE",
1,
4,
-1,
-1,
-1
@ -844,5 +844,21 @@ gameSetting gameSettings[104] = {
-1,
131072,
-1
}
},
{
"WarioWare - Twisted! (USA)",
"RZWE",
-1,
1, // needs "RealTimeClock" (actually motion sensor and rumble)
-1,
-1
},
{
"Mawaru Made in Wario (Japan)",
"RZWJ",
-1,
1, // needs "RealTimeClock" (actually motion sensor and rumble)
-1,
-1
},
};

View File

@ -12,6 +12,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wiiuse/wpad.h>
#include <malloc.h>
#include "unzip.h"
@ -36,6 +37,7 @@
#include "audio.h"
#include "vmmem.h"
#include "input.h"
#include "gameinput.h"
#include "video.h"
#include "menudraw.h"
#include "gcunzip.h"
@ -52,8 +54,10 @@ u32 diff_usec(long long start,long long end);
static tb_t start, now;
u32 loadtimeradjust;
static int cartridgeType = 0;
int cartridgeType = 0;
u32 RomIdCode;
int SunBars = 3;
bool TiltSideways = false;
/****************************************************************************
* VBA Globals
@ -480,6 +484,8 @@ u32 systemReadJoypad(int which)
****************************************************************************/
static int sensorX = 2047;
static int sensorY = 2047;
static int sensorWario = 0x6C0;
static u8 sensorDarkness = 0xE8; // total darkness (including daylight on rainy days)
int systemGetSensorX()
{
@ -491,90 +497,145 @@ int systemGetSensorY()
return sensorY;
}
int systemGetSensorZ()
{
return sensorWario;
}
u8 systemGetSensorDarkness()
{
return sensorDarkness;
}
void systemUpdateSolarSensor()
{
u8 d, sun;
switch (SunBars)
{
case 0:
d = 0xE8;
break;
case 1:
d = 0xE0;
break;
case 2:
d = 0xDA;
break;
case 3:
d = 0xD0;
break;
case 4:
d = 0xC8;
break;
case 5:
d = 0xC0;
break;
case 6:
d = 0xB0;
break;
case 7:
d = 0xA0;
break;
case 8:
d = 0x88;
break;
case 9:
d = 0x70;
break;
case 10:
d = 0x50;
break;
default:
d = 0xE8;
break;
}
sun = 0xE8 - d;
struct tm *newtime;
time_t long_time;
// regardless of the weather, there should be no sun at night time!
time(&long_time); // Get time as long integer.
newtime = localtime(&long_time); // Convert to local time.
if (newtime->tm_hour > 21 || newtime->tm_hour < 5)
{
sun = 0; // total darkness, 9pm - 5am
}
else if (newtime->tm_hour > 20 || newtime->tm_hour < 6)
{
sun = sun / 9; // almost total darkness 8pm-9pm, 5am-6am
}
else if (newtime->tm_hour > 18 || newtime->tm_hour < 7)
{
sun = sun / 2; // half darkness 6pm-8pm, 6am-7am
}
#ifdef HW_RVL
// pointing the Gun Del Sol at the ground blocks the sun light,
// because sometimes you need the shade.
int chan = 0; // first wiimote
WPADData *Data = WPAD_Data(chan);
WPADData data = *Data;
float f;
if (data.orient.pitch > 0)
f = 1.0f - (data.orient.pitch/85.0f);
else
f = 1.0f;
if (f < 0)
f=0;
sun *= f;
#endif
sensorDarkness = 0xE8 - sun;
}
void systemUpdateMotionSensor()
{
/* int chan = 0; // first wiimote
#ifdef HW_RVL
int chan = 0; // first wiimote
WPADData *Data = WPAD_Data(chan);
WPADData data = *Data;
static float OldTiltAngle, OldAvg;
static bool WasFlat = false;
float DeltaAngle = 0;
WPAD_Orientation(chan, &data.orient);
WPAD_GForce(chan, &data.gforce);
WPAD_Accel(chan, &data.accel);
if (TiltSideways)
{
sensorY = 2047+(data.gforce.x*50);
sensorX = 2047+(data.gforce.y*50);
TiltAngle = ((-data.orient.pitch) + OldTiltAngle)/2.0f;
OldTiltAngle = -data.orient.pitch;
}
else
{
sensorX = 2047-(data.gforce.x*50);
sensorY = 2047+(data.gforce.y*50);
TiltAngle = ((data.orient.roll) + OldTiltAngle)/2.0f;
OldTiltAngle = data.orient.roll;
}
DeltaAngle = TiltAngle - OldAvg;
if (DeltaAngle> 180)
DeltaAngle -= 360;
else if (DeltaAngle < -180)
DeltaAngle += 360;
OldAvg = TiltAngle;
//rotz = (float)orient.roll;
//roty = (float)orient.pitch;
//rotx = (float)orient.yaw;
if (TiltAngle < 3.0f && TiltAngle> -3.0f)
{
WasFlat = true;
TiltAngle = 0;
}
else
{
if (WasFlat) TiltAngle = TiltAngle / 2.0f;
WasFlat = false;
}
//rotz = (float)(2.0*3.14159*((int)orient.roll/360.0));//Removing extra stuff fails too
//roty = (float)(2.0*3.14159*((int)orient.pitch/360.0));
//rotx = (float)(2.0*3.14159*((int)orient.yaw/360.0));
sensorWario = 0x6C0+DeltaAngle*11;
//rotz = (float)accel.z;
//roty = (float)accel.y;
//rotx = (float)accel.x;
#endif
//rotz = 200-(gforce.z*50);//Even doing this without the extra stuff fails
//roty = 200-(gforce.y*50);
//rotx = 200-(gforce.x*50);
printf("ACCEL X %d \n", (int)Data->accel.x);
printf("ACCEL Y %d \n", (int)Data->accel.y);
printf("ACCEL Z %d \n", (int)Data->accel.z);
printf("HORIENT ROLL %1.3f ", (float)Data->orient.roll);
printf("HORIENT PITCH %1.3f ", (float)Data->orient.pitch);
printf("HORIENT YAW %1.3f ", (float)Data->orient.yaw);
printf("GFORCE X %1.3f \n", (float)data.gforce.x);
printf("GFORCE Y %1.3f \n", (float)data.gforce.y);
printf("GFORCE Z %1.3f \n", (float)data.gforce.z);
*/
/*
if(sdlMotionButtons[KEY_LEFT]) {
sensorX += 3;
if(sensorX > 2197)
sensorX = 2197;
if(sensorX < 2047)
sensorX = 2057;
} else if(sdlMotionButtons[KEY_RIGHT]) {
sensorX -= 3;
if(sensorX < 1897)
sensorX = 1897;
if(sensorX > 2047)
sensorX = 2037;
} else if(sensorX > 2047) {
sensorX -= 2;
if(sensorX < 2047)
sensorX = 2047;
} else {
sensorX += 2;
if(sensorX > 2047)
sensorX = 2047;
}
if(sdlMotionButtons[KEY_UP]) {
sensorY += 3;
if(sensorY > 2197)
sensorY = 2197;
if(sensorY < 2047)
sensorY = 2057;
} else if(sdlMotionButtons[KEY_DOWN]) {
sensorY -= 3;
if(sensorY < 1897)
sensorY = 1897;
if(sensorY > 2047)
sensorY = 2037;
} else if(sensorY > 2047) {
sensorY -= 2;
if(sensorY < 2047)
sensorY = 2047;
} else {
sensorY += 2;
if(sensorY > 2047)
sensorY = 2047;
}
*/
systemUpdateSolarSensor();
}
/****************************************************************************
@ -589,6 +650,63 @@ void systemDrawScreen()
GX_Render( srcWidth, srcHeight, pix, srcPitch );
}
bool ValidGameId(u32 id)
{
if (id == 0)
return false;
for (int i = 1; i <= 4; i++)
{
u8 b = id & 0xFF;
id = id >> 8;
if (!(b >= 'A' && b <= 'Z') && !(b >= '0' && b <= '9'))
return false;
}
return true;
}
static void gbApplyPerImagePreferences()
{
// Only works for some GB Colour roms
u8 Colour = gbRom[0x143];
if (Colour == 0x80 || Colour == 0xC0)
{
RomIdCode = gbRom[0x13f] | (gbRom[0x140] << 8) | (gbRom[0x141] << 16)
| (gbRom[0x142] << 24);
if (!ValidGameId(RomIdCode))
RomIdCode = 0;
}
else
RomIdCode = 0;
// Otherwise we need to make up our own code
if (RomIdCode == 0)
{
char title[17];
title[15] = '\0';
title[16] = '\0';
if (gbRom[0x143] < 0x7F && gbRom[0x143] > 0x20)
strncpy(title, (const char *) &gbRom[0x134], 16);
else
strncpy(title, (const char *) &gbRom[0x134], 15);
//sprintf(DebugStr, "'%s' %x %x %d", title, Colour, gbRom[0x13f] | (gbRom[0x140] << 8) | (gbRom[0x141] << 16) | (gbRom[0x142] << 24), ValidGameId(gbRom[0x13f] | (gbRom[0x140] << 8) | (gbRom[0x141] << 16) | (gbRom[0x142] << 24)));
if (strcmp(title, "ZELDA") == 0)
RomIdCode = LINKSAWAKENING;
else if (strcmp(title, "MORTAL KOMBAT") == 0)
RomIdCode = MK1;
else if (strcmp(title, "MORTALKOMBATI&II") == 0)
RomIdCode = MK12;
else if (strcmp(title, "MORTAL KOMBAT II") == 0)
RomIdCode = MK2;
else if (strcmp(title, "MORTAL KOMBAT 3") == 0)
RomIdCode = MK3;
else if (strcmp(title, "MORTAL KOMBAT 4") == 0)
RomIdCode = MK4;
else if (strcmp(title, "SUPER MARIOLAND") == 0)
RomIdCode = MARIOLAND1;
else if (strcmp(title, "MARIOLAND2") == 0)
RomIdCode = MARIOLAND2;
}
}
/****************************************************************************
* ApplyPerImagePreferences
* Apply game specific settings, originally from vba-over.ini
@ -598,6 +716,7 @@ static void ApplyPerImagePreferences()
{
// look for matching game setting
int snum = -1;
RomIdCode = rom[0xac] | (rom[0xad] << 8) | (rom[0xae] << 16) | (rom[0xaf] << 24);
for(int i=0; i < gameSettingsCount; i++)
{
@ -623,6 +742,23 @@ static void ApplyPerImagePreferences()
if(gameSettings[snum].mirroringEnabled >= 0)
mirroringEnable = gameSettings[snum].mirroringEnabled;
}
// In most cases this is already handled in GameSettings, but just to make sure:
switch (rom[0xac])
{
case 'F': // Classic NES
cpuSaveType = 1; // EEPROM
mirroringEnable = 1;
break;
case 'K': // Accelerometers
cpuSaveType = 4; // EEPROM + sensor
break;
case 'R': // WarioWare Twisted style sensors
rtcEnable(1);
break;
case 'U': // Boktai solar sensor and clock
rtcEnable(1);
break;
}
}
void LoadPatch(int method)
@ -818,6 +954,9 @@ bool LoadVBAROM(int method)
LoadPatch(method);
// Apply preferences specific to this game
gbApplyPerImagePreferences();
gbSoundReset();
gbSoundSetDeclicking(true);
gbReset();

View File

@ -8,11 +8,21 @@
* VBA support code
***************************************************************************/
#ifndef VBASUPPORT_H
#define VBASUPPORT_H
#include "System.h"
extern struct EmulatedSystem emulator;
extern u32 loadtimeradjust;
extern int cartridgeType;
extern int SunBars;
extern u32 RomIdCode;
extern bool TiltSideways;
bool LoadVBAROM(int method);
void InitialisePalette();
bool LoadBatteryOrState(int method, int action, bool silent);
bool SaveBatteryOrState(int method, int action, bool silent);
#endif