namcos22: Time Crisis light gun as MAME, with crosshair (#2207)

- the gun ports use MAME's position ranges (X 68-694, Y 43-284), what
  the game reads, instead of 8-bit values scaled in the handler;
- the screen edges read as off screen, as MAME: before, an off-screen
  position (1 or 254) reached the game as a shot at the edge;
- the crosshair (core option) is drawn where the game sees the shot,
  as MAME's PORT_CROSSHAIR(X/Y, 1.0, 0.0, 0).


Claude-Session: https://claude.ai/code/session_01N3fzdsnzkQVtgYtYzqepjX

Co-authored-by: Claude Opus 5.5 <[email protected]>
This commit is contained in:
zanacandClaude Opus 5.5 authored and GitHub committed 2026-11-06 03:33:05 -05:00
1 parent d41198a39d
commit 888122871c
3 files changed
+33 -13

No files matched your search

+31 -13
View File
@@ -1117,20 +1117,21 @@ static void trackball_update(int param)
***************************************************************************/
/* MAME's light gun ranges (tuned for CRT): X 68-694, Y 43-284; the screen edges mean off-screen */
#define TIMECRIS_GUN_X_MIN 68
#define TIMECRIS_GUN_X_MAX (68 + 626)
#define TIMECRIS_GUN_Y_MIN 43
#define TIMECRIS_GUN_Y_MAX (43 + 241)
static READ32_HANDLER( timecris_gun_r )
{
int gx = readinputport(PORT_ADC0) & 0xff;
int gy = readinputport(PORT_ADC0 + 1) & 0xff;
UINT16 xpos, ypos;
UINT16 xpos = readinputport(PORT_ADC0);
UINT16 ypos = readinputport(PORT_ADC0 + 1);
if (gx == 0 || gx == 0xff || gy == 0 || gy == 0xff)
/* the screen edges are off screen (MAME) */
if (xpos <= TIMECRIS_GUN_X_MIN || xpos >= TIMECRIS_GUN_X_MAX || ypos <= TIMECRIS_GUN_Y_MIN || ypos >= TIMECRIS_GUN_Y_MAX)
xpos = ypos = 0;
else
{
xpos = 68 + gx * 626 / 0xff;
ypos = 43 + gy * 241 / 0xff;
}
/* 430004 and 430008 both give y: the game adds them */
switch (offset)
{
case 0: return xpos << 16;
@@ -1140,6 +1141,21 @@ static READ32_HANDLER( timecris_gun_r )
return 0;
}
/* the gun crosshair, on the whole screen as MAME's PORT_CROSSHAIR(X/Y, 1.0, 0.0, 0) */
void namcos22_draw_crosshairs(struct mame_bitmap *bitmap, const struct rectangle *cliprect)
{
const struct rectangle *visible = &Machine->visible_area;
int x, y;
if (namcos22_gametype != NAMCOS22_TIME_CRISIS)
return;
x = readinputport(PORT_ADC0) - TIMECRIS_GUN_X_MIN;
y = readinputport(PORT_ADC0 + 1) - TIMECRIS_GUN_Y_MIN;
x = visible->min_x + x * (visible->max_x - visible->min_x) / (TIMECRIS_GUN_X_MAX - TIMECRIS_GUN_X_MIN);
y = visible->min_y + y * (visible->max_y - visible->min_y) / (TIMECRIS_GUN_Y_MAX - TIMECRIS_GUN_Y_MIN);
draw_crosshair(1, bitmap, x, y, cliprect);
}
/***************************************************************************
Alpine Surfer ROM banking
@@ -1621,10 +1637,12 @@ INPUT_PORTS_START( timecris )
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_START /* gun X */
PORT_ANALOG( 0xff, 0x80, IPT_LIGHTGUN_X | IPF_PLAYER1, 50, 15, 1, 0xfe )
PORT_START /* gun Y */
PORT_ANALOG( 0xff, 0x80, IPT_LIGHTGUN_Y | IPF_PLAYER1, 50, 15, 1, 0xfe )
/* the gun position as the game reads it (MAME's ranges, tuned for a CRT);
the edges are off screen, to reload */
PORT_START /* OPT.0: gun X */
PORT_ANALOG( 0xffff, TIMECRIS_GUN_X_MIN + 626 / 2, IPT_LIGHTGUN_X | IPF_PLAYER1, 48, 10, TIMECRIS_GUN_X_MIN, TIMECRIS_GUN_X_MAX )
PORT_START /* OPT.1: gun Y */
PORT_ANALOG( 0xffff, TIMECRIS_GUN_Y_MIN + 241 / 2, IPT_LIGHTGUN_Y | IPF_PLAYER1, 64, 4, TIMECRIS_GUN_Y_MIN, TIMECRIS_GUN_Y_MAX )
INPUT_PORTS_END
INPUT_PORTS_START( propcycl )
+1
View File
@@ -60,6 +60,7 @@ extern INT32 namcos22_point_read(offs_t offs);
extern void namcos22_pdp_handle_commands(UINT16 offs);
extern UINT8 namcos22_syscontrol[0x20];
extern int namcos22_irq_enabled, namcos22_irq_state;
void namcos22_draw_crosshairs(struct mame_bitmap *bitmap, const struct rectangle *cliprect);
/* vidhrdw/namcos22_vidhrdw.c */
VIDEO_START( namcos22s );
+1
View File
@@ -2928,6 +2928,7 @@ VIDEO_UPDATE( namcos22s )
if (fj.layer & 2) draw_sprites();
if (fj.layer & 1) draw_polygons();
render_frame(ss22_frame_rows);
namcos22_draw_crosshairs(bitmap, cliprect);
}
VIDEO_START( namcos22 )