mirror of
https://github.com/libretro/gambatte-libretro.git
synced 2024-11-26 17:30:23 +00:00
Add rumble support
This commit is contained in:
parent
094b5768a1
commit
ba86c0288d
@ -513,6 +513,75 @@ static void check_frame_blend_variable(void)
|
||||
/* Interframe blending END */
|
||||
/***************************/
|
||||
|
||||
/************************/
|
||||
/* Rumble support START */
|
||||
/************************/
|
||||
|
||||
static struct retro_rumble_interface rumble = {0};
|
||||
static uint16_t rumble_strength_last = 0;
|
||||
static uint16_t rumble_strength_up = 0;
|
||||
static uint16_t rumble_strength_down = 0;
|
||||
static uint16_t rumble_level = 0;
|
||||
static bool rumble_active = false;
|
||||
|
||||
void cartridge_set_rumble(unsigned active)
|
||||
{
|
||||
if (!rumble.set_rumble_state ||
|
||||
!rumble_level)
|
||||
return;
|
||||
|
||||
if (active)
|
||||
rumble_strength_up++;
|
||||
else
|
||||
rumble_strength_down++;
|
||||
|
||||
rumble_active = true;
|
||||
}
|
||||
|
||||
static void apply_rumble(void)
|
||||
{
|
||||
uint16_t strength;
|
||||
|
||||
if (!rumble.set_rumble_state ||
|
||||
!rumble_level)
|
||||
return;
|
||||
|
||||
strength = (rumble_strength_up > 0) ?
|
||||
(rumble_strength_up * rumble_level) /
|
||||
(rumble_strength_up + rumble_strength_down) : 0;
|
||||
|
||||
rumble_strength_up = 0;
|
||||
rumble_strength_down = 0;
|
||||
|
||||
if (strength == rumble_strength_last)
|
||||
return;
|
||||
|
||||
rumble.set_rumble_state(0, RETRO_RUMBLE_WEAK, strength);
|
||||
rumble.set_rumble_state(0, RETRO_RUMBLE_STRONG, strength);
|
||||
|
||||
rumble_strength_last = strength;
|
||||
}
|
||||
|
||||
static void deactivate_rumble(void)
|
||||
{
|
||||
rumble_strength_up = 0;
|
||||
rumble_strength_down = 0;
|
||||
rumble_active = false;
|
||||
|
||||
if (!rumble.set_rumble_state ||
|
||||
(rumble_strength_last == 0))
|
||||
return;
|
||||
|
||||
rumble.set_rumble_state(0, RETRO_RUMBLE_WEAK, 0);
|
||||
rumble.set_rumble_state(0, RETRO_RUMBLE_STRONG, 0);
|
||||
|
||||
rumble_strength_last = 0;
|
||||
}
|
||||
|
||||
/**********************/
|
||||
/* Rumble support END */
|
||||
/**********************/
|
||||
|
||||
bool file_present_in_system(std::string fname)
|
||||
{
|
||||
const char *systemdirtmp = NULL;
|
||||
@ -769,6 +838,10 @@ void retro_deinit(void)
|
||||
video_buf = NULL;
|
||||
deinit_frame_blending();
|
||||
libretro_supports_bitmasks = false;
|
||||
|
||||
deactivate_rumble();
|
||||
memset(&rumble, 0, sizeof(struct retro_rumble_interface));
|
||||
rumble_level = 0;
|
||||
}
|
||||
|
||||
void retro_set_environment(retro_environment_t cb)
|
||||
@ -1045,10 +1118,10 @@ static void check_variables(void)
|
||||
darkFilterLevel = static_cast<unsigned>(atoi(var.value));
|
||||
}
|
||||
gb.setDarkFilterLevel(darkFilterLevel);
|
||||
|
||||
var.key = "gambatte_up_down_allowed";
|
||||
var.value = NULL;
|
||||
|
||||
up_down_allowed = false;
|
||||
var.key = "gambatte_up_down_allowed";
|
||||
var.value = NULL;
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
||||
{
|
||||
if (!strcmp(var.value, "enabled"))
|
||||
@ -1056,8 +1129,18 @@ static void check_variables(void)
|
||||
else
|
||||
up_down_allowed = false;
|
||||
}
|
||||
else
|
||||
up_down_allowed = false;
|
||||
|
||||
rumble_level = 0;
|
||||
var.key = "gambatte_rumble_level";
|
||||
var.value = NULL;
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
||||
{
|
||||
rumble_level = atoi(var.value);
|
||||
rumble_level = (rumble_level > 10) ? 10 : rumble_level;
|
||||
rumble_level = (rumble_level > 0) ? ((0x1999 * rumble_level) + 0x5) : 0;
|
||||
}
|
||||
if (rumble_level == 0)
|
||||
deactivate_rumble();
|
||||
|
||||
/* Interframe blending option has its own handler */
|
||||
check_frame_blend_variable();
|
||||
@ -1352,6 +1435,11 @@ bool retro_load_game(const struct retro_game_info *info)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE, &rumble))
|
||||
log_cb(RETRO_LOG_INFO, "Rumble environment supported.\n");
|
||||
else
|
||||
log_cb(RETRO_LOG_INFO, "Rumble environment not supported.\n");
|
||||
|
||||
struct retro_input_descriptor desc[] = {
|
||||
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" },
|
||||
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" },
|
||||
@ -1600,6 +1688,10 @@ void retro_run()
|
||||
audio_batch_cb(sound_buf.i16, read_avail);
|
||||
#endif
|
||||
|
||||
/* Apply any 'pending' rumble effects */
|
||||
if (rumble_active)
|
||||
apply_rumble();
|
||||
|
||||
frames_count++;
|
||||
|
||||
bool updated = false;
|
||||
|
@ -302,6 +302,26 @@ struct retro_core_option_definition option_defs_us[] = {
|
||||
},
|
||||
"disabled"
|
||||
},
|
||||
{
|
||||
"gambatte_rumble_level",
|
||||
"Gamepad Rumble Strength",
|
||||
"Enables haptic feedback effects for supported games (Pokemon Pinball, Perfect Dark...).",
|
||||
{
|
||||
{ "0", NULL },
|
||||
{ "1", NULL },
|
||||
{ "2", NULL },
|
||||
{ "3", NULL },
|
||||
{ "4", NULL },
|
||||
{ "5", NULL },
|
||||
{ "6", NULL },
|
||||
{ "7", NULL },
|
||||
{ "8", NULL },
|
||||
{ "9", NULL },
|
||||
{ "10", NULL },
|
||||
{ NULL, NULL },
|
||||
},
|
||||
"10"
|
||||
},
|
||||
#ifdef HAVE_NETWORK
|
||||
{
|
||||
"gambatte_show_gb_link_settings",
|
||||
|
@ -24,6 +24,8 @@
|
||||
#include <string.h>
|
||||
#include <algorithm>
|
||||
|
||||
extern void cartridge_set_rumble(unsigned active);
|
||||
|
||||
namespace gambatte
|
||||
{
|
||||
|
||||
@ -417,6 +419,7 @@ namespace gambatte
|
||||
unsigned short rombank;
|
||||
unsigned char rambank;
|
||||
bool enableRam;
|
||||
bool hasRumble;
|
||||
static unsigned adjustedRombank(const unsigned bank) { return bank; }
|
||||
void setRambank() const {
|
||||
memptrs.setRambank(enableRam ? MemPtrs::READ_EN | MemPtrs::WRITE_EN : 0,
|
||||
@ -424,29 +427,41 @@ namespace gambatte
|
||||
}
|
||||
void setRombank() const { memptrs.setRombank(adjustedRombank(rombank) & (rombanks(memptrs) - 1));}
|
||||
public:
|
||||
explicit Mbc5(MemPtrs &memptrs)
|
||||
explicit Mbc5(MemPtrs &memptrs, bool rumble)
|
||||
: memptrs(memptrs),
|
||||
rombank(1),
|
||||
rambank(0),
|
||||
enableRam(false)
|
||||
enableRam(false),
|
||||
hasRumble(rumble)
|
||||
{
|
||||
}
|
||||
virtual void romWrite(const unsigned P, const unsigned data) {
|
||||
switch (P >> 13 & 3) {
|
||||
case 0:
|
||||
switch (P >> 12 & 0x7) {
|
||||
case 0x0:
|
||||
case 0x1:
|
||||
enableRam = (data & 0xF) == 0xA;
|
||||
setRambank();
|
||||
break;
|
||||
case 1:
|
||||
case 0x2:
|
||||
case 0x3:
|
||||
rombank = P < 0x3000 ? (rombank & 0x100) | data
|
||||
: (data << 8 & 0x100) | (rombank & 0xFF);
|
||||
setRombank();
|
||||
break;
|
||||
case 2:
|
||||
rambank = data & 0xF;
|
||||
case 0x4:
|
||||
case 0x5:
|
||||
if(hasRumble && ((P >> 12 & 0x7) == 4))
|
||||
{
|
||||
cartridge_set_rumble((data >> 3) & 1);
|
||||
rambank = (data & ~8) & 0x0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
rambank = data & 0x0f;
|
||||
}
|
||||
setRambank();
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -527,6 +542,7 @@ namespace gambatte
|
||||
unsigned rombanks = 2;
|
||||
bool cgb = false;
|
||||
enum Cartridgetype { PLAIN, MBC1, MBC2, MBC3, MBC5, HUC1, HUC3 } type = PLAIN;
|
||||
bool rumble = false;
|
||||
|
||||
{
|
||||
unsigned i;
|
||||
@ -558,9 +574,9 @@ namespace gambatte
|
||||
case 0x19: printf("MBC5 ROM loaded.\n"); type = MBC5; break;
|
||||
case 0x1A: printf("MBC5 ROM+RAM loaded.\n"); type = MBC5; break;
|
||||
case 0x1B: printf("MBC5 ROM+RAM+BATTERY loaded.\n"); type = MBC5; break;
|
||||
case 0x1C: printf("MBC5+RUMBLE ROM not supported.\n"); type = MBC5; break;
|
||||
case 0x1D: printf("MBC5+RUMBLE+RAM ROM not suported.\n"); type = MBC5; break;
|
||||
case 0x1E: printf("MBC5+RUMBLE+RAM+BATTERY ROM not supported.\n"); type = MBC5; break;
|
||||
case 0x1C: printf("MBC5+RUMBLE ROM loaded.\n"); type = MBC5; rumble = true; break;
|
||||
case 0x1D: printf("MBC5+RUMBLE+RAM ROM loaded.\n"); type = MBC5; rumble = true; break;
|
||||
case 0x1E: printf("MBC5+RUMBLE+RAM+BATTERY ROM loaded.\n"); type = MBC5; rumble = true; break;
|
||||
case 0x20: printf("MBC6 ROM not supported.\n"); return -1;
|
||||
case 0x22: printf("MBC7 ROM not supported.\n"); return -1;
|
||||
case 0xFC: printf("Pocket Camera ROM not supported.\n"); return -1;
|
||||
@ -630,7 +646,7 @@ namespace gambatte
|
||||
break;
|
||||
case MBC2: mbc.reset(new Mbc2(memptrs_)); break;
|
||||
case MBC3: mbc.reset(new Mbc3(memptrs_, hasRtc(memptrs_.romdata()[0x147]) ? &rtc_ : 0)); break;
|
||||
case MBC5: mbc.reset(new Mbc5(memptrs_)); break;
|
||||
case MBC5: mbc.reset(new Mbc5(memptrs_, rumble)); break;
|
||||
case HUC1: mbc.reset(new HuC1(memptrs_)); break;
|
||||
case HUC3:
|
||||
huc3_.set(true);
|
||||
|
Loading…
Reference in New Issue
Block a user