nulldc-360/plugins/XMaple/XMaple.cpp

358 lines
No EOL
10 KiB
C++

#define _WIN32_WINNT 0x500
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "XMaple.h"
#include "FT0.h"
#include "FT4.h"
#include "FT8.h"
//////////////////////////////////////////////////////////////////////////
// TODO something
emu_info host;
u32 deviceMenu;
u32 devicemenuItem[4];
xmaple_settings maplesettings;
const char* deviceNames[] =
{
"Controller",
"Twinstick",
"Arcade Stick",
"Puru-Puru Pak",
"Mic",
"Dreameye Mic",
};
void mapleUpdateMenu(u32 parentmenu, maple_device_instance* inst, bool override);
/*
// win32 dlls gotta have it...
HMODULE hModule;
HINSTANCE hInstance;
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
::hModule = hModule;
hInstance = (HINSTANCE)hModule;
return TRUE;
}
*/
void mapleLoadConfig()
{
maplesettings.Controller.Deadzone = host.ConfigLoadInt("Xmaple", "Controller.DeadZone", 25);
maplesettings.PuruPuru.UseRealFreq = host.ConfigLoadInt("Xmaple", "PuruPuru.UseRealFrequency", 1) == 1 ? true:false;
maplesettings.PuruPuru.Length = host.ConfigLoadInt("Xmaple", "PuruPuru.Length", 175);
maplesettings.PuruPuru.Intensity = host.ConfigLoadInt("Xmaple", "PuruPuru.Intensity", 100);
// Just to be sure this ain't negative.
maplesettings.PuruPuru.Intensity = abs(maplesettings.PuruPuru.Intensity);
maplesettings.PuruPuru.Length = abs(maplesettings.PuruPuru.Length);
}
void mapleSaveConfig()
{
host.ConfigSaveInt("Xmaple", "PuruPuru.UseRealFrequency", maplesettings.PuruPuru.UseRealFreq);
}
//Called when plugin is loaded by the emu, the param has some handy functions so i make a copy of it ;)
s32 FASTCALL mapleLoad(emu_info* emu)
{
memcpy(&host, emu, sizeof(host));
mapleLoadConfig();
return rv_ok;
}
//called when plugin is unloaded by emu(only if Load was called)
void FASTCALL mapleUnload()
{
}
void EXPORT_CALL MaxiCallback(u32 id, void* w, void* p)
{
// Same setting for EVERY PuruPuru Pack, but doesn't crash. :)
// TODO: Make it per subdevice.
if (maplesettings.PuruPuru.UseRealFreq)
maplesettings.PuruPuru.UseRealFreq = 0;
else
maplesettings.PuruPuru.UseRealFreq = 1;
host.SetMenuItemStyle(id,maplesettings.PuruPuru.UseRealFreq?MIS_Checked:0,MIS_Checked);
mapleSaveConfig();
}
void EXPORT_CALL mapleAboutBoxCallback(u32 id, void* w, void* p)
{
/* MessageBox(
(HWND)w,
"XMaple input plugin for nullDC\n"
"By shuffle2\n\n",
"About XMaple",
MB_OK);*/
}
//MUST be EXPORT_CALL, because it is a callback for a menu ;)
//Called when the config menu is selected
//id = menu id (can be used to set the style with host.SetMenuItemStyle & co)
//w = window handle (HWND) that owns the menu
//p = user specified data
void EXPORT_CALL mapleConfigMainCallback(u32 id, void* w, void* p)
{
maple_device_instance* inst = (maple_device_instance*)p;
// Get the selection
MenuItem mi;
host.GetMenuItem(id, &mi, MIM_Text);
u8 newXPad = atoi(mi.Text+8);
((EmulatedDevices::MapleInterface*)inst->data)->SetXPad(newXPad); //"x360pad X"
// Delete the menu
for (int i = 0; i < 4; ++i)
host.DeleteMenuItem(devicemenuItem[i]);
// Recreate
mapleUpdateMenu(deviceMenu, inst, true);
// Make subdevice tag along
for (int i = 0; i < 5; ++i)
if (inst->subdevices[i].dma == EmulatedDevices::MapleInterface::ClassDMA)
((EmulatedDevices::MapleInterface*)inst->subdevices[i].data)->SetXPad(newXPad);
}
void mapleUpdateMenu(u32 parentmenu, maple_device_instance* inst, bool override)
{
// Get the port number
u32 x = inst->port >> 6;
// Pad selection parent menu
if (!deviceMenu)
deviceMenu = host.AddMenuItem(parentmenu, -1, "Device: NONE", 0, 0);
// so default is to not overlap with other devices
if (!override)
((EmulatedDevices::MapleInterface*)inst->data)->SetXPad(5);
// Add plugged pads
for (u32 i = 0; i < 4; ++i)
{
if (XInput::IsConnected(i))
{
char temp[512];
sprintf(temp, "x360pad %i", i);
devicemenuItem[i] = host.AddMenuItem(deviceMenu, -1, temp, mapleConfigMainCallback, 0);
//Set the user defined pointer for the menu to the device instance,
// so we can tell for which port the menu was called ;)
MenuItem mi;
mi.PUser = inst;
mi.Style = MIS_Radiocheck;
// default device
if (!override && x == i)
{
mi.Style |= MIS_Checked;
((EmulatedDevices::MapleInterface*)inst->data)->SetXPad(i);
//update parent menu text
char menu[512];
sprintf(menu, "Device: x360pad %i", i);
MenuItem parent;
parent.Text = menu;
host.SetMenuItem(deviceMenu, &parent, MIM_Text);
}
// user selection
if (override && i == ((EmulatedDevices::MapleInterface*)inst->data)->GetXPad())
{
mi.Style |= MIS_Checked;
//update parent menu text
char menu[512];
sprintf(menu, "Device: x360pad %i", i);
MenuItem parent;
parent.Text = menu;
host.SetMenuItem(deviceMenu, &parent, MIM_Text);
}
host.SetMenuItem(devicemenuItem[i], &mi, MIM_PUser | MIM_Style);
}
}
}
//Called to create a main device, like joystick, lightgun and such
///inst : instance info
//inst->port is the port (in the native maple format) of the device
//inst->dma must be filled
//inst->data can be filled (its what you get as data parameter on all the maple callbacks ;p)
//rest of it can be ignored (unless you want to do some ugly shit ;p)
///id : maple device id
//Its the index of the device on the Maple device list that the dcGetInterface gives to the emu
///flags : creation flags, ignore it for now (MDCF_HOTPLUG if the plugin is loaded after the emu startup)
///rootmenu : Root menu for the device
s32 FASTCALL mapleCreateMain(maple_device_instance* inst, u32 id, u32 flags, u32 rootmenu)
{
// Only FT0 here for the time being...so w/e
//pass the interface pointer using the device_instance field
inst->data = (EmulatedDevices::MapleInterface*)(EmulatedDevices::CreateFT0(id, inst));
if (inst->data == NULL)
{
printf("XMAPLE: BAD DEVICE ID\n");
return rv_error;
}
inst->dma = EmulatedDevices::MapleInterface::ClassDMA;
// Add type name
char name[512];
sprintf(name, deviceNames[((EmulatedDevices::MapleInterface*)inst->data)->GetID()]);
host.AddMenuItem(rootmenu, -1, name, 0, 0);
// About...
host.AddMenuItem(rootmenu, -1, "About...", mapleAboutBoxCallback, 0);
//gli UpdateMenu(rootmenu, inst, false);
//All done well !
return rv_ok;
}
//Create subdevice, same params as CreateMain
s32 FASTCALL mapleCreateSub(maple_subdevice_instance* inst, u32 id, u32 flags, u32 rootmenu)
{
printf("id %d\n",id);
//pass the interface pointer using the device_instance field
switch (id)
{
case ID_PURUPURUPACK:
{
inst->data = (EmulatedDevices::MapleInterface*)(EmulatedDevices::CreateFT8(id, inst));
// Frequency menuitem
host.AddMenuItem(rootmenu, -1, "Real Frequency Scaling", MaxiCallback, maplesettings.PuruPuru.UseRealFreq);
}
break;
case ID_MIC:
case ID_DREAMEYEMIC:
inst->data = (EmulatedDevices::MapleInterface*)(EmulatedDevices::CreateFT4(id, inst));
break;
}
if (inst->data == NULL)
{
printf("XMAPLE: BAD SUBDEVICE ID\n");
return rv_error;
}
inst->dma = EmulatedDevices::MapleInterface::ClassDMA;
// Add type name
char name[512];
sprintf(name, deviceNames[((EmulatedDevices::MapleInterface*)inst->data)->GetID()]);
host.AddMenuItem(rootmenu, -1, name, 0, 0);
return rv_ok;
}
//Called when emulation is started.
//data : the inst->data pointer as filled by the Create* functions
//id : device index on the dcGetInterface
//params : nothing useful (just a placeholder)
//NOTE: Hot plugged devices can miss this call if the emulation is started
// before the device is hotplugged.This is a bug on the emu %) ;p
s32 FASTCALL mapleInit(void* data, u32 id, maple_init_params* params)
{
//Emulation was started ! OMFG ! GET THE GUNSHIPS READYYYY
//Err, init dinput or smth, i do all my init work on the Create() part anyway ..
switch (id)
{
case ID_PURUPURUPACK:
((EmulatedDevices::FT8*)data)->StartVibThread();
break;
}
return rv_ok;
}
//Called when emulation is terminated
//data : the inst->data pointer as filled by the Create* functions
//id : device index on the dcGetInterface
//NOTE
// Called only if Init() was called ;)
void FASTCALL mapleTerm(void* data, u32 id)
{
//kill whatever you did on Init()
// TODO figure out why this only gets called for main devices
switch (id)
{
case ID_PURUPURUPACK:
((EmulatedDevices::FT8*)data)->StopVibThread();
break;
}
}
//Destroy the device
//data : the inst->data pointer as filled by the Create* functions
//id : device index on the dcGetInterface
void FASTCALL mapleDestroy(void* data,u32 id)
{
//Free any memory allocated (if any)
}
#define AddMapleDevice(name, flags) \
strcpy(info->maple.devices[id].Name, name" [XInput] (" __DATE__ ")"); \
info->maple.devices[id].Type = MDT_Main; \
info->maple.devices[id].Flags = flags; \
id++;
#define AddMapleSubDevice(name, flags) \
strcpy(info->maple.devices[id].Name, name" [XInput] (" __DATE__ ")"); \
info->maple.devices[id].Type = MDT_Sub; \
info->maple.devices[id].Flags = flags; \
id++;
//Give a list of the devices to the emu
//_T hijack so i can get unicode __DATE__ ;/
void EXPORT_CALL mapleGetInterface(plugin_interface* info)
{
//Fill in the common (for all plugin types) info
info->InterfaceVersion = PLUGIN_I_F_VERSION;
info->common.InterfaceVersion = MAPLE_PLUGIN_I_F_VERSION;
info->common.Load = mapleLoad;
info->common.Unload = mapleUnload;
info->common.Type = Plugin_Maple;
//wcscpy : unicode ;)
strcpy(info->common.Name, "XInput for nullDC by shuffle2 [" __DATE__ "]");
//Fill in the maple info
info->maple.CreateMain = mapleCreateMain;
info->maple.CreateSub = mapleCreateSub;
info->maple.Init = mapleInit;
info->maple.Term = mapleTerm;
info->maple.Destroy = mapleDestroy;
// Start at 0...
u32 id = ID_STDCONTROLLER;
#ifndef BUILD_NAOMI
AddMapleDevice("Controller", MDTF_Sub0|MDTF_Sub1|MDTF_Hotplug);
AddMapleDevice("Twinstick", MDTF_Sub0|MDTF_Hotplug);
AddMapleDevice("Arcade Stick", MDTF_Sub0|MDTF_Hotplug);
AddMapleSubDevice("Puru-Puru Pak", MDTF_Hotplug);
AddMapleSubDevice("Mic", MDTF_Hotplug);
AddMapleSubDevice("Dreameye Mic", MDTF_Hotplug);
#endif
//EOL marker
info->maple.devices[id].Type = MDT_EndOfList;
}