Closed Timecraft closed 4 years ago
They also suggested that we should try to move the core's boot function to AFTER we set up controls
The lines were removed and the core boot function was moved to after setting up the controls. No avail
public class Timecraft.RetroGame.View : GLib.Object {
public Retro.CoreView game_view;
public Retro.MainLoop main_loop;
public static View? instance;
public View (Retro.Core core) {
game_view = new Retro.CoreView ();
game_view.set_core (core);
MainWindow.instance.add (game_view);
var key_joypad_mapping = new Retro.KeyJoypadMapping ();
var key_map = new GLib.HashTable<Retro.JoypadId, uint16> (null, null);
// Keycodes come from input-event-codes.h + 8 because that's what GDK does
// Normally you allow user to remap keys, so you get this value from GDK, but not here
// Agree it sucks and we should do something about it
key_map.insert (Retro.JoypadId.A, 45 + 8);
key_map.insert (Retro.JoypadId.B, 44 + 8);
key_map.insert (Retro.JoypadId.Y, 30 + 8);
key_map.insert (Retro.JoypadId.X, 31 + 8);
key_map.insert (Retro.JoypadId.UP, 103 + 8);
key_map.insert (Retro.JoypadId.DOWN, 108 + 8);
key_map.insert (Retro.JoypadId.LEFT, 105 + 8);
key_map.insert (Retro.JoypadId.RIGHT, 106 + 8);
key_map.insert (Retro.JoypadId.START, 28 + 8);
key_map.insert (Retro.JoypadId.SELECT, 54 + 8);
key_map.foreach ( (joypad, keyboard) => {
key_joypad_mapping.set_button_key (joypad, keyboard);
});
game_view.set_key_joypad_mapping (key_joypad_mapping);
game_view.set_as_default_controller (core);
// This keyboard input is different from Retro.ControllerType.KEYBOARD, you mostly
// need it for home computer platforms. Yay Libretro having multiple APIs for things
core.set_keyboard (game_view);
// This is needed so that you only control the first player with joypad, and not all
// at once. For other players assign the actual gamepads. In Games we use keyboard
// for the last one (e.g. if you have 2 gamepads in a 4-player game, players 1 and 2
// will use gamepads, player 3 will use keyboard, player 4 will just stand there)
core.set_default_controller (Retro.ControllerType.JOYPAD, null);
var core_view_joypad = game_view.as_controller (Retro.ControllerType.JOYPAD);
core.set_controller (0, core_view_joypad);
// You have to have save dir and system dir set to something.
// Save directory is where the core saves (not all cores use saveram, a lot
// just write a file into save directory), so you gotta have it
core.save_directory = ".";
// This is where firmware is. Once again, should be set to something meaningful,
// e.g. it matters for Nestopia UE core.
core.system_directory = ".";
try {
core.boot ();
}
catch (Error e) {
error ("%s", e.message);
}
// This you of course do after you boot, can't start the game before it booted
// Though tbh in 0.18 it might work, but that's still not something you should do
main_loop = new Retro.MainLoop (core);
main_loop.start ();
Headerbar.instance.remove_back_button ();
MainWindow.instance.show_all ();
instance = this;
}
}
Here's your view.vala
, fixed and with some explanations. :)
Holy crap, thank you for taking your precious time to do this!
I believe I understand now, quite a bit of set up that I neglected to do, assuming it would be obvious to the core (hey core, just put the save files where the game is!) and not understanding that some cores have... quirks...
Didn’t realize you had to initialize the MainLoop after booting the core
Again, thank you so very much!
You can maybe do it before, but e.g. in 1.0 you won't be able to do that (well, I removed RetroMainLoop
completely, but you can imagine retro_core_run()
won't be able to tell the remote runner process to start the core if the process does not exist yet :), and it's created in boot()
)
Cores have indeed a lot of quirks :( The most fun part will be when you add savestates. Some cores (MAME and ParaLLEl N64 in particular) fail to restore the state unless you run()/iteration() once before you load. 1.0 will do it implicitly, but 0.18 won't because stable API etc.
There's also content dir, DOSBox needs it, but that core sucks in general (incl. in RetroArch) and I've never been able to get it fully working.
Feel free to ask or use Games as a reference if you hit other problems :)
Also feel free to open issues in https://gitlab.gnome.org/GNOME/retro-gtk/issues if you feel the docs are unclear. They might very well be.
The “not remaking keys” thing is kind of a temporary measure too, just so I have something working right now
You could just not set anything, or do new Retro.KeyJoypadMapping.default ()
:) It also maps L, R (, 2, 3) that you forgot.
Also feel free to open issues in https://gitlab.gnome.org/GNOME/retro-gtk/issues if you feel the docs are unclear. They might very well be.
If retro-Gtk-1 is going to be an API break, perhaps it would be better to wait for the API to become more stable before publishing an issue on how the docs are
Well, 0.18 might be unclear too. These kinds of things are hard to notice when you develop both a library and an app using it so there might very well be parts that are "obvious" to me and Adrien, but that really aren't.
You could just not set anything, or do
new Retro.KeyJoypadMapping.default ()
:) It also maps L, R (, 2, 3) that you forgot.
What are the default controls, then? As for L/R 2 and L/R 3, again, temporary measure. The game I was testing with was a GameBoy Advance game, which doesn’t have to worry about that. I’ll have to get started immediately on remappable controls so that this issue can be more easily rectified (hopefully 😬)
GBA has L/R ;)
Defaults: WASD for XYBA, Q/E for L/R, Z/C for L2/R2, 1/3 for L3/R3, arrows for dpad, Enter for Start, Backspace for Select.
Edit: and of course it's not documented. Bingo!
GBA has L/R ;)
L/R 1, unless I’m mistaken in what those are supposed to be. GBA doesn’t have L/R 2 (triggers) or L/R 3 (press down on the stick)
Right. But your mapping doesn't have L/R 1 either.
A lot of this could also be my fault for not looking super closely at the docs. I was mostly trying to use the Vapi and assuming what was happening by the function names. Poor coding practice on my part!
Right. But your mapping doesn't have L/R 1 either.
Ah **** 😂
How did I not notice!
I wouldn't say that's a poor coding practice really, ideally names are self-documenting. :)
(I would say making every object a singleton is a poor practice though ;)
Ideally, I shouldn’t need any of those objects more than once, hence singleton
And, unless i’m mistaken, if I want to access a specific instance of the object that has already been created, I need to have an instance of it. I am fairly new/naive when it comes to programming
Ideally, I shouldn’t need any of those objects more than once, hence singleton
As soon as you want e.g. a second window, all that is thrown out the window. :)
You need an instance of course. You pass that instance via function arguments, properties etc. OOP is all about that :)
You pass that instance via function arguments, properties etc.
Fair. I’ll work on removing singletons from this app and my other app that is current
Can confirm that this issue is fixed. I can't stress enough how much I thank you!
Eh, you've messed up indentation in that file :)
My “spam the down arrow and tab key” technique didn’t work D: Copy/Paste from GitHub is kinda weird. Doesn’t preserve indentation, so you have to add that in manually
Can't you select everything and press tab once? IDK if that works in your editor, but it's a common thing.
I don’t believe so. I’m using elementary’s Code editor. I’ll have to try that and open an issue if that doesn’t work
Well, you learn something new every day (or in my case, about 20 thousand things in one day xD). elementary Code does in fact have the ability to do that
I was pretty sure it does that, as gedit and GNOME Builder do it and they all use GtkSourceView. Though wasn't 100% you use Code, so asked. Similarly, shift+tab unindents for one level.
I did find something interesting in retro-gtk, and it's probably not supposed to be happening
Inputs are still a bit buggy for some reason. I can press enter/return (equivalent to start) on the main screen and get to the save file screen, but from there I can only press X (B) and go back to the title screen. Odd.
Ok, so the issues with the input seems to be directly related to this issue on GitLab. This is what I get for only testing with one core
This is still somewhat of an issue. #4 has some updates on this.
In essence, controlling via the keyboard works great, but controlling via an actual controller is a question.
If I pass it the Retro.Controller
subclass RetroGamepad
, it "works". It accepts the input, but the controls are not customized; on my controller, the right stick button (R3) ends up being START. This is not ideal nor expected.
If I just try to make a Retro.KeyJoypadMapping
, pass that back to the MainWindow
and set the CoreView
to use that as its mapping, it does not have any input.
Retro.KeyJoypadMapping
is for keyboard. For gamepads mappings are handled by libmanette.
Currently input is not working. I have contacted someone working on retro-gtk to see if they can help me figure out my stupidity