mirror of
https://github.com/djhackersdev/legacy-tools.git
synced 2026-10-06 12:37:56 +03:00
202 lines
4.6 KiB
C++
202 lines
4.6 KiB
C++
#include "libutil/stdafx.h"
|
|
#include "libutil/util.h"
|
|
#include "libutil/input.h"
|
|
|
|
#include "imports/libavs-win32.h"
|
|
#include "imports/libsystem.h"
|
|
|
|
#define PICK_BIT 0x20
|
|
|
|
/* Weird backwards two-bit integer */
|
|
static const u32_t eff_lookup[] = { 0x0000, 0x0100, 0x0080, 0x0180 };
|
|
static const char *dbg_keys[] = { "autoplay", "neverend" };
|
|
|
|
static u32_t state[2];
|
|
static u8_t effector[2];
|
|
static bool dbg_state[2];
|
|
|
|
/* While Guitar Freaks only has one pick direction, Guitar Hero controllers have two,
|
|
* and rapid picking causes these controllers to alternate between these directions
|
|
* without going via zero on their vertical axis. A naive binding of both pick
|
|
* directions would therefore cause the pick to get 'stuck' at any reasonably fast
|
|
* picking speed.
|
|
*
|
|
* Therefore, we have separate synthetic 'Pick A' and 'Pick B' bindings. Alternation
|
|
* between these two actions causes a pick to be signalled to the game for one frame. */
|
|
|
|
static void STDCALL input_callback(u8_t action, bool edge, void *ctx)
|
|
{
|
|
u8_t index;
|
|
|
|
if (action < 0x10) {
|
|
/* Update 1P input bit */
|
|
state[0] |= (1 << action);
|
|
|
|
} else if (action < 0x20) {
|
|
/* Update 2P input bit */
|
|
state[1] |= (1 << (action - 0x10));
|
|
|
|
} else if (action < 0x30 && edge) {
|
|
/* Update 1P/2P pick */
|
|
index = action - 0x20;
|
|
state[index / 2] |= PICK_BIT;
|
|
|
|
} else if (action < 0x40 && edge) {
|
|
/* Update 1P/2P effector */
|
|
index = action - 0x30;
|
|
effector[index] = (effector[index] + 1) % 4;
|
|
|
|
} else if (action < 0x50 && edge) {
|
|
/* Fire a debugging toggle */
|
|
index = action - 0x40;
|
|
dbg_state[index] = !dbg_state[index];
|
|
sys_debug_dip_set_param(dbg_keys[index], dbg_state[index]);
|
|
|
|
} else if (action == 0xFF) {
|
|
/* Exit */
|
|
ExitProcess(0);
|
|
}
|
|
}
|
|
|
|
#ifndef NDEBUG
|
|
static void log_proc(void *ctx, const char *msg, int msg_len)
|
|
{
|
|
OutputDebugStringA(msg);
|
|
}
|
|
#endif
|
|
|
|
DLLEXPORT int device_check_secplug(int param)
|
|
{
|
|
static const int response[] = { 257, 256 };
|
|
return response[param];
|
|
}
|
|
|
|
DLLEXPORT void device_finalize(void)
|
|
{
|
|
timeEndPeriod(1);
|
|
libutil_fini();
|
|
}
|
|
|
|
DLLEXPORT void device_get_coinstock(unsigned short *,unsigned short *)
|
|
{}
|
|
|
|
DLLEXPORT unsigned char device_get_dipsw(int)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
DLLEXPORT unsigned int device_get_input(int player)
|
|
{
|
|
return state[player];
|
|
}
|
|
|
|
/* I don't know what this is used for, actually. It would be interesting
|
|
* to mess around with it. */
|
|
DLLEXPORT unsigned __int64 device_get_input_time(void)
|
|
{
|
|
return timeGetTime();
|
|
}
|
|
|
|
DLLEXPORT int device_get_jamma_history(struct T_JAMMA_HISTORY_INFO *,int)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
DLLEXPORT int device_get_status(void)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
DLLEXPORT int device_get_subboard_version(char *dest, int nbytes)
|
|
{
|
|
/* It's a shoutout to 2ch akin to lololololol, w or 0x77 doesn't actually
|
|
* mean anything :) */
|
|
strncpy(dest, "wwwwwwwwwwwwwwwwwww", nbytes);
|
|
return 0;
|
|
}
|
|
|
|
DLLEXPORT int device_initialize(void)
|
|
{
|
|
const wchar_t *cmdline;
|
|
bool quote;
|
|
|
|
timeBeginPeriod(1);
|
|
|
|
#ifndef NDEBUG
|
|
log_boot(log_proc, NULL);
|
|
#endif
|
|
|
|
cmdline = GetCommandLine();
|
|
quote = false;
|
|
|
|
/* Skip executable name */
|
|
while (*cmdline != L'\0' && !iswspace(*cmdline) && !quote) {
|
|
if (*cmdline == L'"') {
|
|
quote = !quote;
|
|
}
|
|
|
|
cmdline++;
|
|
}
|
|
|
|
/* Skip space after executable name */
|
|
while (*cmdline != L'\0' && iswspace(*cmdline)) {
|
|
cmdline++;
|
|
}
|
|
|
|
/* Determine game type */
|
|
if (wcscmp(cmdline, L"-g") == 0) {
|
|
std_setenv("/env/profile/mcode", "xxG33JAA");
|
|
libutil_init(L"gf");
|
|
} else if (wcscmp(cmdline, L"-d") == 0) {
|
|
std_setenv("/env/profile/mcode", "xxG32JAA");
|
|
libutil_init(L"dm");
|
|
} else {
|
|
panic(L"Process launched with unknown game type. Command line is: \"%s\"\n", GetCommandLine());
|
|
}
|
|
|
|
/* Set other security data */
|
|
std_setenv("/env/profile/hwid", "0000000000000000");
|
|
std_setenv("/env/profile/softid", "0000000000000000");
|
|
std_setenv("/env/profile/sysid", "0000000000000000");
|
|
|
|
return 0;
|
|
}
|
|
|
|
DLLEXPORT void device_poweroff(void)
|
|
{
|
|
ExitProcess(0);
|
|
}
|
|
|
|
DLLEXPORT void device_set_coincounter_controllable(unsigned char,unsigned char)
|
|
{}
|
|
|
|
DLLEXPORT void device_set_coincounter_merge(unsigned char)
|
|
{}
|
|
|
|
DLLEXPORT void device_set_coincounter_work(unsigned char,unsigned char)
|
|
{}
|
|
|
|
DLLEXPORT void device_set_jamma_asyncmode(void)
|
|
{}
|
|
|
|
DLLEXPORT void device_set_jamma_unti_inputskip(int)
|
|
{}
|
|
|
|
DLLEXPORT void device_set_portoutbit(int,int)
|
|
{}
|
|
|
|
DLLEXPORT void device_update(void)
|
|
{
|
|
int i;
|
|
|
|
memset(state, 0, sizeof(state));
|
|
input_scan(input_callback, NULL);
|
|
|
|
for (i = 0 ; i < 2 ; i++) {
|
|
state[i] |= eff_lookup[effector[i]];
|
|
}
|
|
}
|
|
|
|
DLLEXPORT void device_update_secplug(void)
|
|
{}
|