jotego / jtcores

FPGA cores compatible with multiple arcade game machines and KiCAD schematics of arcade games. Working on MiSTer FPGA/Analogue Pocket
https://patreon.com/jotego
GNU General Public License v3.0
228 stars 40 forks source link

s18: lghost controls #688

Closed jotego closed 2 months ago

jotego commented 3 months ago

Controls are completely missing in Laser Ghost. Look at what is needed to make it boot to attract mode at least. Add support for mouse and light gun.

gyurco commented 3 months ago

I'm trying to implement this, however I found out that the mouse module is not very usable. Mouse_dx and mouse_dy just stores the last movement, but I need cumulated coordinates (when mouse_st, the x <= x+dx, y <= y+dy). Is there any method with the current framework to achieve it? At least exporting a strobe when a new movement comes in would needed.

jotego commented 3 months ago

If I understand it correctly, you need absolute coordinates within a range. Use the paddle signals then. The paddle is emulated with a mouse automatically if a real one is not connected.

Another option is to use the analog sticks.

gyurco commented 3 months ago

The paddle coordinates are wrapping around, I think. I added a signal to the mouse:

diff --git a/modules/jtframe/hdl/keyboard/jtframe_mouse.v b/modules/jtframe/hdl/keyboard/jtframe_mouse.v
index d1bfb9d6..d32e1aec 100644
--- a/modules/jtframe/hdl/keyboard/jtframe_mouse.v
+++ b/modules/jtframe/hdl/keyboard/jtframe_mouse.v
@@ -35,7 +35,7 @@ module jtframe_mouse(
     // in 2's complement unless JTFRAME_MOUSE_NO2COMPL is defined
     output reg  [15:0] mouse_1p,
     output reg  [15:0] mouse_2p,
-
+    output reg   [1:0] mouse_strobe,

     output reg  [ 2:0] but_1p,
     output reg  [ 2:0] but_2p
@@ -79,16 +79,20 @@ always @(posedge clk, posedge rst) begin
         but_2p   <= 0;
         joy1_l   <= 0;
         joy2_l   <= 0;
+        mouse_strobe <= 0;
     end else if(!lock) begin
         joy1_l <= joy1;
         joy2_l <= joy2;
+        mouse_strobe <= 0;
         if( mouse_st ) begin
             if( !mouse_idx ) begin
                 mouse_1p <= { cv(mouse_dy), cv(mouse_dx) };
                 but_1p   <= mouse_f[2:0];
+                mouse_strobe[0] <= 1;
             end else begin
                 mouse_2p <= { cv(mouse_dy), cv(mouse_dx) };
                 but_2p   <= mouse_f[2:0];
+                mouse_strobe[1] <= 1;
             end
         end
         if( MOUSE_EMU ) begin

It works well so far. If it's acceptable, I would go this way.

jotego commented 3 months ago

I think the paddle should not wrap around. Please give it another chance. If you finally go for adding a strobe, follow the naming convention of the rest of the mouse signals, that include 1p/2p in the name. Like mouse_st_1p and mouse_st_2p or add one more bit to the mouse_1p/2p signals.

gyurco commented 3 months ago

I was wrong about the paddle, first the mouse movement converted back to quadrature encoding, then I have to convert back to movement, where I can make limits. Looks a bit redundant. Using two signals for the strobes requires to add two signals instead of one into all modules in the chain (there are quite a few), but I can do it if it's favourable.

jotego commented 3 months ago

You only need to add them in jts18_main, don't you? They are already part of the game ports when you define the macro.

gyurco commented 3 months ago

The extra strobes has to be added to all the way up from mouse to top, and then top to main. Counted 9 files so far.

gyurco commented 3 months ago

I pushed a commit, it's enough to start the game and play it.

jotego commented 3 months ago

The extra strobes has to be added to all the way up from mouse to top, and then top to main. Counted 9 files so far.

I see. I was thinking of the paddle signals, which only need to be added to the main module in the game core.

jotego commented 3 months ago

I tested the commit b95d6f00. It is looking good! Some notes:

I like the crosshair module. I think I will refactor it into jtframe_board, together with the video output. This will come handy on other games too.

Note that you do not need to count the screen size as it is available in two macros (JTFRAME_WIDTH and JTFRAME_HEIGHT) but it is no big deal.

I tested it with two mice and I could move the two crosshairs. Nice!

jotego commented 3 months ago

By the way, register the crosshair signal:

assign crosshair = ((x_diff[8:3] == 0 || &x_diff[8:3]) && y_diff == 0) ||
                   ((y_diff[8:3] == 0 || &y_diff[8:3]) && x_diff == 0);

The flip flop comes for free and helps with timing.

gyurco commented 3 months ago

Thanks for trying out! If another core can use it, then probably it would worth to put it into jtframe. Thinking about Operation Wolf. Probably the module could be used for wwally, too, just without displaying the actual crosshair. I'll do coin/start/service buttons ASAP.

jotego commented 3 months ago

Tested the latest commit (1f320a3). Coin and service buttons operate correctly now. It would be nice connect the two buttons for player 3, even if we are missing mouse support for it at the moment.

The game aim and the crosshair do not match around the screen centre. The game could be doing some non linear adjustment but the crosshair matches the aim in MAME so I think the game is not doing any trick. Maybe there is something odd in the crosshair module?

gyurco commented 3 months ago

Tested the latest commit (1f320a3). Coin and service buttons operate correctly now. It would be nice connect the two buttons for player 3, even if we are missing mouse support for it at the moment.

No problem, just need to define JTFRAME_4PLAYERS and connect player 3 buttons.

The game aim and the crosshair do not match around the screen centre. The game could be doing some non linear adjustment but the crosshair matches the aim in MAME so I think the game is not doing any trick. Maybe there is something odd in the crosshair module?

There's a transformation function already (x*204/256) to transform the screen coordinates to 0-255. In MAME, there are even further transformations: https://github.com/mamedev/mame/blob/029341aeb2b65ecc2c7463706f264d0b13e13e56/src/mame/sega/segas18.cpp#L454 I would skip floating point arithmetic in the core, but something simpler can be used for more precise shooting.

jotego commented 3 months ago

No problem, just need to define JTFRAME_4PLAYERS and connect player 3 buttons.

No need for JTFRAME_4PLAYERS anymore, the controls are always there. When I started with JTFRAME all game ports had to be entered manually so in order not to edit old files constantly I started adding new ports with macros. Now that the game ports are automatic and not in the developer's way anymore, I think I will remove many of these macros to simplify the framework.

There's a transformation function already (x*204/256) to transform the screen coordinates to 0-255. In MAME, there are even further transformations: https://github.com/mamedev/mame/blob/029341aeb2b65ecc2c7463706f264d0b13e13e56/src/mame/sega/segas18.cpp#L454 I would skip floating point arithmetic in the core, but something simpler can be used for more precise shooting.

I see. Another option would be a LUT as it would only take one 1 BRAM block and have simple logic.

jotego commented 2 months ago

The aim is much better now but still a bit off. Are you settling for the current state or do you think it can be improved to center it completely?

gyurco commented 2 months ago

I can try some more tweaks. Probably x[8:3]+x[8:5] could be x[8:3]+x[8:4] and 60-(x[8:3]+x[8:4]) for a slightly bigger adjustment towards/from the center of the screen.

jotego commented 2 months ago

I think it's worth giving it a final tweak

gyurco commented 2 months ago

Issued a PR with some more adjustments.

jotego commented 2 months ago

Thank you. It is not perfect, but good enough. The original wasn't probably 100% accurate either. @jtmiki marked it as finished.

gyurco commented 2 months ago

Was there a crosshair in the original arcade? As I read, there was some kind of light when you fired, but that was not a laser-pointer.

gyurco commented 2 months ago

BTW a perfect crosshair can be achieved by disassembling the game's code and check how it transfers gun coordinates to screen coordinates.

jotego commented 2 months ago

Indeed. If there's enough push by Patreon subscribers, we may invest more effort in the accuracy. Let's see how the support for this game is received.