Update to v103r22 release.

byuu says:

Changelog:

  - ruby: ported all remaining drivers to new API¹
  - ruby/wasapi: fix for dropping one sample per period [SuperMikeMan]
  - gb: emulated most of the TAMA RTC; but RTC state is still volatile²

¹: the new ports are:

  - audio/{directsound, alsa, pulseaudio, pulseaudiosimple, ao}
  - input/{udev, quartz, carbon}

It's pretty much guaranteed many of them will have compilation errors.
Please paste the error logs and I'll try to fix them up. It may take a
WIP or two to get there.

It's also possible things broke from the updates. If so, I could use
help comparing the old file to the new file, looking for mistakes, since
I can't test on these platforms apart from audio/directsound.

Please report working drivers in this list, so we can mark them off the
list. I'll need both macOS and Linux testers.

audio/directsound.cpp:112:

    if(DirectSoundCreate(0, &_interface, 0) != DS_OK) return terminate(), false;

²: once I get this working, I'll add load/save support for the RTC
values. For now, the RTC data will be lost when you close the emulator.

Right now, you can set the date/time in real-time mode, and when you
start the game, the time will be correct, and the time will tick
forward. Note that it runs off emulated time instead of actual real
time, so if you fast-forward to 300%, one minute will be 20 seconds.

The really big limitation right now is that when you exit the game, and
restart it, and resume a new game, the hour spot gets corrupted, and
this seems to instantly kill your pet. Fun. This is crazy because the
commands the game sends to the TAMA interface are identical between
starting a new game and getting in-game versus loading a game.

It's likely going to require disassembling the game's code and seeing
what in the hell it's doing, but I am extremely bad at LR35092 assembly.
Hopefully endrift can help here :|
This commit is contained in:
Tim Allen
2017-07-28 21:42:24 +10:00
parent 80841deaa5
commit e1223366a7
19 changed files with 728 additions and 715 deletions

View File

@@ -1,30 +1,18 @@
#include "keyboard/carbon.cpp"
struct InputCarbon : Input {
InputKeyboardCarbon carbonKeyboard;
InputCarbon() : carbonKeyboard(*this) {}
~InputCarbon() { term(); }
InputCarbon() : _keyboard(*this) { initialize(); }
~InputCarbon() { terminate(); }
auto cap(const string& name) -> bool {
if(name == Input::KeyboardSupport) return true;
return false;
}
auto get(const string& name) -> any {
return {};
}
auto set(const string& name, const any& value) -> bool {
return false;
}
auto ready() -> bool { return _ready; }
auto acquired() -> bool { return false; }
auto acquire() -> bool { return false; }
auto release() -> bool { return false; }
auto acquired() -> bool { return false; }
auto poll() -> vector<shared_pointer<HID::Device>> {
vector<shared_pointer<HID::Device>> devices;
carbonKeyboard.poll(devices);
_keyboard.poll(devices);
return devices;
}
@@ -32,12 +20,19 @@ struct InputCarbon : Input {
return false;
}
auto init() -> bool {
if(!carbonKeyboard.init()) return false;
return true;
private:
auto initialize() -> bool {
terminate();
if(!_keyboard.initialize()) return false;
return _ready = true;
}
auto term() -> void {
carbonKeyboard.term();
_ready = false;
_keyboard.terminate();
}
bool _ready = false;
InputKeyboardCarbon _keyboard;
};

View File

@@ -12,14 +12,14 @@ struct InputJoypadUdev {
udev_list_entry* item = nullptr;
struct JoypadInput {
signed code = 0;
unsigned id = 0;
int code = 0;
uint id = 0;
int16_t value = 0;
input_absinfo info;
JoypadInput() {}
JoypadInput(signed code) : code(code) {}
JoypadInput(signed code, unsigned id) : code(code), id(id) {}
JoypadInput(int code) : code(code) {}
JoypadInput(int code, uint id) : code(code), id(id) {}
bool operator< (const JoypadInput& source) const { return code < source.code; }
bool operator==(const JoypadInput& source) const { return code == source.code; }
};
@@ -36,7 +36,7 @@ struct InputJoypadUdev {
uint8_t keybit[(KEY_MAX + 7) / 8] = {0};
uint8_t absbit[(ABS_MAX + 7) / 8] = {0};
uint8_t ffbit[(FF_MAX + 7) / 8] = {0};
unsigned effects = 0;
uint effects = 0;
string name;
string manufacturer;
@@ -49,11 +49,11 @@ struct InputJoypadUdev {
set<JoypadInput> hats;
set<JoypadInput> buttons;
bool rumble = false;
unsigned effectID = 0;
uint effectID = 0;
};
vector<Joypad> joypads;
auto assign(shared_pointer<HID::Joypad> hid, unsigned groupID, unsigned inputID, int16_t value) -> void {
auto assign(shared_pointer<HID::Joypad> hid, uint groupID, uint inputID, int16_t value) -> void {
auto& group = hid->group(groupID);
if(group.input(inputID).value() == value) return;
input.doChange(hid, groupID, inputID, group.input(inputID).value(), value);
@@ -65,21 +65,21 @@ struct InputJoypadUdev {
for(auto& jp : joypads) {
input_event events[32];
signed length = 0;
int length = 0;
while((length = read(jp.fd, events, sizeof(events))) > 0) {
length /= sizeof(input_event);
for(unsigned i = 0; i < length; i++) {
signed code = events[i].code;
signed type = events[i].type;
signed value = events[i].value;
for(uint i : range(length)) {
int code = events[i].code;
int type = events[i].type;
int value = events[i].value;
if(type == EV_ABS) {
if(auto input = jp.axes.find({code})) {
signed range = input().info.maximum - input().info.minimum;
int range = input().info.maximum - input().info.minimum;
value = (value - input().info.minimum) * 65535ll / range - 32767;
assign(jp.hid, HID::Joypad::GroupID::Axis, input().id, sclamp<16>(value));
} else if(auto input = jp.hats.find({code})) {
signed range = input().info.maximum - input().info.minimum;
int range = input().info.maximum - input().info.minimum;
value = (value - input().info.minimum) * 65535ll / range - 32767;
assign(jp.hid, HID::Joypad::GroupID::Hat, input().id, sclamp<16>(value));
}
@@ -114,7 +114,7 @@ struct InputJoypadUdev {
return false;
}
auto init() -> bool {
auto initialize() -> bool {
context = udev_new();
if(context == nullptr) return false;
@@ -141,7 +141,7 @@ struct InputJoypadUdev {
return true;
}
auto term() -> void {
auto terminate() -> void {
if(enumerator) { udev_enumerate_unref(enumerator); enumerator = nullptr; }
}
@@ -210,10 +210,10 @@ private:
}
}
unsigned axes = 0;
unsigned hats = 0;
unsigned buttons = 0;
for(signed i = 0; i < ABS_MISC; i++) {
uint axes = 0;
uint hats = 0;
uint buttons = 0;
for(int i = 0; i < ABS_MISC; i++) {
if(testBit(jp.absbit, i)) {
if(i >= ABS_HAT0X && i <= ABS_HAT3Y) {
if(auto hat = jp.hats.insert({i, hats++})) {
@@ -226,12 +226,12 @@ private:
}
}
}
for(signed i = BTN_JOYSTICK; i < KEY_MAX; i++) {
for(int i = BTN_JOYSTICK; i < KEY_MAX; i++) {
if(testBit(jp.keybit, i)) {
jp.buttons.insert({i, buttons++});
}
}
for(signed i = BTN_MISC; i < BTN_JOYSTICK; i++) {
for(int i = BTN_MISC; i < BTN_JOYSTICK; i++) {
if(testBit(jp.keybit, i)) {
jp.buttons.insert({i, buttons++});
}
@@ -259,14 +259,14 @@ private:
uint64_t pathID = Hash::CRC32(jp.deviceName.data(), jp.deviceName.size()).value();
jp.hid->setID(pathID << 32 | jp.vendorID.hex() << 16 | jp.productID.hex() << 0);
for(unsigned n = 0; n < jp.axes.size(); n++) jp.hid->axes().append(n);
for(unsigned n = 0; n < jp.hats.size(); n++) jp.hid->hats().append(n);
for(unsigned n = 0; n < jp.buttons.size(); n++) jp.hid->buttons().append(n);
for(uint n : range(jp.axes.size())) jp.hid->axes().append(n);
for(uint n : range(jp.hats.size())) jp.hid->hats().append(n);
for(uint n : range(jp.buttons.size())) jp.hid->buttons().append(n);
jp.hid->setRumble(jp.rumble);
}
auto removeJoypad(udev_device* device, const string& deviceNode) -> void {
for(unsigned n = 0; n < joypads.size(); n++) {
for(uint n : range(joypads.size())) {
if(joypads[n].deviceNode == deviceNode) {
close(joypads[n].fd);
joypads.remove(n);

View File

@@ -31,7 +31,7 @@ struct InputKeyboardCarbon {
devices.append(hid);
}
auto init() -> bool {
auto initialize() -> bool {
keys.append({0x35, "Escape"});
keys.append({0x7a, "F1"});
keys.append({0x78, "F2"});
@@ -153,6 +153,6 @@ struct InputKeyboardCarbon {
return true;
}
auto term() -> void {
auto terminate() -> void {
}
};

View File

@@ -26,7 +26,7 @@ struct InputKeyboardQuartz {
devices.append(hid);
}
auto init() -> bool {
auto initialize() -> bool {
keys.append({"Escape", kVK_Escape});
keys.append({"F1", kVK_F1});
keys.append({"F2", kVK_F2});
@@ -148,6 +148,6 @@ struct InputKeyboardQuartz {
return true;
}
auto term() -> void {
auto terminate() -> void {
}
};

View File

@@ -1,30 +1,18 @@
#include "keyboard/quartz.cpp"
struct InputQuartz : Input {
InputKeyboardQuartz quartzKeyboard;
InputQuartz() : quartzKeyboard(*this) {}
~InputQuartz() { term(); }
InputQuartz() : _keyboard(*this) { initialize(); }
~InputQuartz() { terminate(); }
auto cap(const string& name) -> bool {
if(name == Input::KeyboardSupport) return true;
return false;
}
auto get(const string& name) -> any {
return {};
}
auto set(const string& name, const any& value) -> bool {
return false;
}
auto ready() -> bool { return _ready; }
auto acquired() -> bool { return false; }
auto acquire() -> bool { return false; }
auto release() -> bool { return false; }
auto acquired() -> bool { return false; }
auto poll() -> vector<shared_pointer<HID::Device>> {
vector<shared_pointer<HID::Device>> devices;
quartzKeyboard.poll(devices);
_keyboard.poll(devices);
return devices;
}
@@ -32,12 +20,18 @@ struct InputQuartz : Input {
return false;
}
auto init() -> bool {
if(!quartzKeyboard.init()) return false;
return true;
auto initialize() -> bool {
terminate();
if(!_keyboard.init()) return false;
return _ready = true;
}
auto term() -> void {
quartzKeyboard.term();
auto terminate() -> void {
_ready = false;
_keyboard.term();
}
bool _ready = false;
InputKeyboardQuartz _keyboard;
};

View File

@@ -47,6 +47,7 @@ struct InputSDL : Input {
private:
auto initialize() -> bool {
terminate();
if(!_context) return false;
if(!_keyboard.initialize()) return false;
if(!_mouse.initialize(_context)) return false;
if(!_joypad.initialize()) return false;

View File

@@ -13,72 +13,64 @@
#include "joypad/udev.cpp"
struct InputUdev : Input {
InputKeyboardXlib xlibKeyboard;
InputMouseXlib xlibMouse;
InputJoypadUdev udev;
InputUdev() : xlibKeyboard(*this), xlibMouse(*this), udev(*this) {}
~InputUdev() { term(); }
InputUdev() : _keyboard(*this), _mouse(*this), _joypad(*this) { initialize(); }
~InputUdev() { terminate(); }
struct Settings {
uintptr_t handle = 0;
} settings;
auto ready() -> bool { return _ready; }
auto cap(const string& name) -> bool {
if(name == Input::Handle) return true;
if(name == Input::KeyboardSupport) return true;
if(name == Input::MouseSupport) return true;
if(name == Input::JoypadSupport) return true;
if(name == Input::JoypadRumbleSupport) return true;
return false;
}
auto context() -> uintptr { return _context; }
auto get(const string& name) -> any {
if(name == Input::Handle) return settings.handle;
return {};
}
auto set(const string& name, const any& value) -> bool {
if(name == Input::Handle && value.is<uintptr_t>()) {
settings.handle = value.get<uintptr_t>();
return true;
}
return false;
}
auto acquire() -> bool {
return xlibMouse.acquire();
}
auto release() -> bool {
return xlibMouse.release();
auto setContext(uintptr context) -> bool {
if(_context == context) return true;
_context = context;
return initialize();
}
auto acquired() -> bool {
return xlibMouse.acquired();
return _mouse.acquired();
}
auto acquire() -> bool {
return _mouse.acquire();
}
auto release() -> bool {
return _mouse.release();
}
auto poll() -> vector<shared_pointer<HID::Device>> {
vector<shared_pointer<HID::Device>> devices;
xlibKeyboard.poll(devices);
xlibMouse.poll(devices);
udev.poll(devices);
_keyboard.poll(devices);
_mouse.poll(devices);
_joypad.poll(devices);
return devices;
}
auto rumble(uint64_t id, bool enable) -> bool {
return udev.rumble(id, enable);
return _joypad.rumble(id, enable);
}
private:
auto init() -> bool {
if(xlibKeyboard.init() == false) return false;
if(xlibMouse.init(settings.handle) == false) return false;
if(udev.init() == false) return false;
return true;
terminate();
if(!_context) return false;
if(!_keyboard.initialize()) return false;
if(!_mouse.initialize(_context)) return false;
if(!_joypad.initialize()) return false;
return _ready = true;
}
auto term() -> void {
xlibKeyboard.term();
xlibMouse.term();
udev.term();
auto terminate() -> void {
_ready = false;
_keyboard.terminate();
_mouse.terminate();
_joypad.terminate();
}
bool _ready = false;
uintptr _context = 0;
InputKeyboardXlib _keyboard;
InputMouseXlib _mouse;
InputJoypadUdev _joypad;
};