(MESS) sms: improved the code for the Light Phaser, by simplifying the routines

and making them slightly faster. [Enik Land]
This commit is contained in:
etabeta78 2015-02-22 19:39:07 +01:00
parent 2c4d4a7837
commit 6829f6262f
9 changed files with 112 additions and 110 deletions

View File

@ -1,6 +1,7 @@
/********************************************************************** /**********************************************************************
Sega Game Gear EXT port emulation Sega Game Gear EXT port emulation
Also known as Gear-to-Gear (or VS, in Japan) cable connector
Copyright MESS Team. Copyright MESS Team.
Visit http://mamedev.org for licensing and usage restrictions. Visit http://mamedev.org for licensing and usage restrictions.

View File

@ -1,6 +1,7 @@
/********************************************************************** /**********************************************************************
Sega Game Gear EXT port emulation Sega Game Gear EXT port emulation
Also known as Gear-to-Gear (or VS, in Japan) cable connector
Copyright MESS Team. Copyright MESS Team.
Visit http://mamedev.org for licensing and usage restrictions. Visit http://mamedev.org for licensing and usage restrictions.

View File

@ -16,7 +16,7 @@
#include "emu.h" #include "emu.h"
#include "ggext.h" #include "ggext.h"
#include "../sms_ctrl/smsctrl.h" #include "bus/sms_ctrl/smsctrl.h"

View File

@ -253,20 +253,15 @@ void sega8_cart_slot_device::set_lphaser_xoffset( UINT8 *rom, int size )
{ {
if (!memcmp(&rom[0x7ff0], signatures[0], 16) || !memcmp(&rom[0x7ff0], signatures[1], 16)) if (!memcmp(&rom[0x7ff0], signatures[0], 16) || !memcmp(&rom[0x7ff0], signatures[1], 16))
xoff = 26; xoff = 26;
else if (!memcmp(&rom[0x7ff0], signatures[2], 16))
if (!memcmp(&rom[0x7ff0], signatures[2], 16))
xoff = 36; xoff = 36;
else if (!memcmp(&rom[0x7ff0], signatures[3], 16))
if (!memcmp(&rom[0x7ff0], signatures[3], 16))
xoff = 32; xoff = 32;
else if (!memcmp(&rom[0x7ff0], signatures[4], 16))
if (!memcmp(&rom[0x7ff0], signatures[4], 16))
xoff = 30; xoff = 30;
else if (!memcmp(&rom[0x7ff0], signatures[5], 16))
if (!memcmp(&rom[0x7ff0], signatures[5], 16))
xoff = 39; xoff = 39;
else if (!memcmp(&rom[0x7ff0], signatures[6], 16))
if (!memcmp(&rom[0x7ff0], signatures[6], 16))
xoff = 38; xoff = 38;
} }

View File

@ -137,26 +137,27 @@ int sms_light_phaser_device::bright_aim_area( emu_timer *timer, int lgun_x, int
{ {
const int r_x_r = LGUN_RADIUS * LGUN_RADIUS; const int r_x_r = LGUN_RADIUS * LGUN_RADIUS;
const rectangle &visarea = m_screen->visible_area(); const rectangle &visarea = m_screen->visible_area();
rectangle aim_area;
int beam_x = m_screen->hpos(); int beam_x = m_screen->hpos();
int beam_y = m_screen->vpos(); int beam_y = m_screen->vpos();
int dx, dy; int beam_x_orig = beam_x;
int result = 1; int beam_y_orig = beam_y;
int pos_changed = 0; int dy, result = 1;
double dx_radius; double dx_radius;
bool new_check_point = false;
while (1) aim_area.min_y = MAX(lgun_y - LGUN_RADIUS, visarea.min_y);
aim_area.max_y = MIN(lgun_y + LGUN_RADIUS, visarea.max_y);
while (!new_check_point)
{ {
/* If beam's y isn't at a line where the aim area is, change it /* If beam's y doesn't point to a line where the aim area is,
the next line it enters that area. */ change it to the first line where the beam enters that area. */
dy = abs(beam_y - lgun_y); if (beam_y < aim_area.min_y || beam_y > aim_area.max_y)
if (dy > LGUN_RADIUS || beam_y < visarea.min_y || beam_y > visarea.max_y)
{ {
beam_y = lgun_y - LGUN_RADIUS; beam_y = aim_area.min_y;
if (beam_y < visarea.min_y)
beam_y = visarea.min_y;
dy = abs(beam_y - lgun_y);
pos_changed = 1;
} }
dy = abs(beam_y - lgun_y);
/* Caculate distance in x of the radius, relative to beam's y distance. /* Caculate distance in x of the radius, relative to beam's y distance.
First try some shortcuts. */ First try some shortcuts. */
@ -175,30 +176,37 @@ int sms_light_phaser_device::bright_aim_area( emu_timer *timer, int lgun_x, int
dx_radius = ceil((float) sqrt((float) (r_x_r - (dy * dy)))); dx_radius = ceil((float) sqrt((float) (r_x_r - (dy * dy))));
} }
/* If beam's x isn't in the circular aim area, change it aim_area.min_x = MAX(lgun_x - dx_radius, visarea.min_x);
to the next point it enters that area. */ aim_area.max_x = MIN(lgun_x + dx_radius, visarea.max_x);
dx = abs(beam_x - lgun_x);
if (dx > dx_radius || beam_x < visarea.min_x || beam_x > visarea.max_x) while (!new_check_point)
{ {
/* If beam's x has passed the aim area, advance to /* If beam's x has passed the aim area, change it to the
next line and recheck y/x coordinates. */ next line and go back to recheck y/x coordinates. */
if (beam_x > lgun_x) if (beam_x > aim_area.max_x)
{ {
beam_x = 0;
beam_y++;
continue;
}
beam_x = lgun_x - dx_radius;
if (beam_x < visarea.min_x)
beam_x = visarea.min_x; beam_x = visarea.min_x;
pos_changed = 1; beam_y++;
break;
} }
if (pos_changed) /* If beam's x isn't in the aim area, change it to the
break; next point where the beam enters that area. */
if (beam_x < aim_area.min_x)
if (m_sensor_last_state == 0) /* sensor is on */
{ {
beam_x = aim_area.min_x;
}
if (beam_x_orig != beam_x || beam_y_orig != beam_y)
{
/* adopt the new coordinates to adjust the timer */
new_check_point = true;
break;
}
if (m_sensor_last_state == 0)
{
/* sensor is already on */
/* keep sensor on until out of the aim area */ /* keep sensor on until out of the aim area */
result = 0; result = 0;
} }
@ -218,23 +226,23 @@ int sms_light_phaser_device::bright_aim_area( emu_timer *timer, int lgun_x, int
result = (brightness >= sensor_min_brightness) ? 0 : 1; result = (brightness >= sensor_min_brightness) ? 0 : 1;
} }
if (result == 0) if (result == 0) /* sensor on */
{ {
/* Set next check for when sensor will be off */ /* Set next check for when sensor will be off */
beam_x = lgun_x + dx_radius + 1; beam_x = aim_area.max_x + 1;
if (beam_x > visarea.max_x)
beam_x = visarea.max_x + 1; /* adopt the new coordinates to adjust the timer */
break; new_check_point = true;
} }
else else
{ {
/* Next check after the minimum interval */ /* Next check will happen after the minimum interval */
beam_x += LGUN_X_INTERVAL; beam_x += LGUN_X_INTERVAL;
pos_changed = 1;
} }
} }
timer->adjust(m_screen->time_until_pos(beam_y, beam_x)); }
timer->adjust(m_screen->time_until_pos(beam_y, beam_x));
return result; return result;
} }

View File

@ -254,6 +254,13 @@ void sega315_5124_device::set_display_settings()
} }
} }
set_frame_timing();
m_cram_dirty = 1;
}
void sega315_5124_device::set_frame_timing()
{
switch (m_y_pixels) switch (m_y_pixels)
{ {
case 192: case 192:
@ -268,7 +275,6 @@ void sega315_5124_device::set_display_settings()
m_frame_timing = (m_is_pal) ? pal_240 : ntsc_240; m_frame_timing = (m_is_pal) ? pal_240 : ntsc_240;
break; break;
} }
m_cram_dirty = 1;
} }
@ -675,7 +681,7 @@ WRITE8_MEMBER( sega315_5124_device::register_write )
case 2: /* VDP register write */ case 2: /* VDP register write */
reg_num = data & 0x0f; reg_num = data & 0x0f;
m_reg[reg_num] = m_addr & 0xff; m_reg[reg_num] = m_addr & 0xff;
//logerror("%s: %s: setting register %x to %02x\n", machine().describe_context(), tag(), reg_num, m_addr & 0xf ); //logerror("%s: %s: setting register %x to %02x\n", machine().describe_context(), tag(), reg_num, m_addr & 0xff);
switch (reg_num) switch (reg_num)
{ {
@ -1441,7 +1447,7 @@ void sega315_5124_device::update_palette()
{ {
int i; int i;
/* Exit if palette is has no changes */ /* Exit if palette has no changes */
if (m_cram_dirty == 0) if (m_cram_dirty == 0)
{ {
return; return;
@ -1468,7 +1474,7 @@ void sega315_5378_device::update_palette()
{ {
int i; int i;
/* Exit if palette is has no changes */ /* Exit if palette has no changes */
if (m_cram_dirty == 0) if (m_cram_dirty == 0)
{ {
return; return;
@ -1557,20 +1563,7 @@ void sega315_5124_device::stop_timers()
void sega315_5124_device::vdp_postload() void sega315_5124_device::vdp_postload()
{ {
switch (m_y_pixels) set_frame_timing();
{
case 192:
m_frame_timing = (m_is_pal) ? pal_192 : ntsc_192;
break;
case 224:
m_frame_timing = (m_is_pal) ? pal_224 : ntsc_224;
break;
case 240:
m_frame_timing = (m_is_pal) ? pal_240 : ntsc_240;
break;
}
} }
void sega315_5124_device::device_start() void sega315_5124_device::device_start()

View File

@ -91,6 +91,7 @@ public:
protected: protected:
void set_display_settings(); void set_display_settings();
void set_frame_timing();
virtual void update_palette(); virtual void update_palette();
virtual void cram_write(UINT8 data); virtual void cram_write(UINT8 data);
virtual void draw_scanline( int pixel_offset_x, int pixel_plot_y, int line ); virtual void draw_scanline( int pixel_offset_x, int pixel_plot_y, int line );

View File

@ -19,10 +19,10 @@
#define CONTROL1_TAG "ctrl1" #define CONTROL1_TAG "ctrl1"
#define CONTROL2_TAG "ctrl2" #define CONTROL2_TAG "ctrl2"
#include "bus/gamegear/ggext.h"
#include "bus/sms_ctrl/smsctrl.h"
#include "bus/sms_exp/smsexp.h"
#include "bus/sega8/sega8_slot.h" #include "bus/sega8/sega8_slot.h"
#include "bus/sms_exp/smsexp.h"
#include "bus/sms_ctrl/smsctrl.h"
#include "bus/gamegear/ggext.h"
class sms_state : public driver_device class sms_state : public driver_device
@ -32,9 +32,8 @@ public:
: driver_device(mconfig, type, tag), : driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"), m_maincpu(*this, "maincpu"),
m_vdp(*this, "sms_vdp"), m_vdp(*this, "sms_vdp"),
m_ym(*this, "ym2413"),
m_main_scr(*this, "screen"), m_main_scr(*this, "screen"),
m_region_maincpu(*this, "maincpu"), m_ym(*this, "ym2413"),
m_port_ctrl1(*this, CONTROL1_TAG), m_port_ctrl1(*this, CONTROL1_TAG),
m_port_ctrl2(*this, CONTROL2_TAG), m_port_ctrl2(*this, CONTROL2_TAG),
m_port_gg_ext(*this, "ext"), m_port_gg_ext(*this, "ext"),
@ -45,6 +44,7 @@ public:
m_port_scope(*this, "SEGASCOPE"), m_port_scope(*this, "SEGASCOPE"),
m_port_scope_binocular(*this, "SSCOPE_BINOCULAR"), m_port_scope_binocular(*this, "SSCOPE_BINOCULAR"),
m_port_persist(*this, "PERSISTENCE"), m_port_persist(*this, "PERSISTENCE"),
m_region_maincpu(*this, "maincpu"),
m_mainram(NULL), m_mainram(NULL),
m_is_gamegear(0), m_is_gamegear(0),
m_is_gg_region_japan(0), m_is_gg_region_japan(0),
@ -61,12 +61,12 @@ public:
// devices // devices
required_device<cpu_device> m_maincpu; required_device<cpu_device> m_maincpu;
required_device<sega315_5124_device> m_vdp; required_device<sega315_5124_device> m_vdp;
optional_device<ym2413_device> m_ym;
required_device<screen_device> m_main_scr; required_device<screen_device> m_main_scr;
required_memory_region m_region_maincpu; optional_device<ym2413_device> m_ym;
optional_device<sms_control_port_device> m_port_ctrl1; optional_device<sms_control_port_device> m_port_ctrl1;
optional_device<sms_control_port_device> m_port_ctrl2; optional_device<sms_control_port_device> m_port_ctrl2;
optional_device<gg_ext_port_device> m_port_gg_ext; optional_device<gg_ext_port_device> m_port_gg_ext;
optional_ioport m_port_gg_dc; optional_ioport m_port_gg_dc;
optional_ioport m_port_pause; optional_ioport m_port_pause;
optional_ioport m_port_reset; optional_ioport m_port_reset;
@ -75,6 +75,7 @@ public:
optional_ioport m_port_scope_binocular; optional_ioport m_port_scope_binocular;
optional_ioport m_port_persist; optional_ioport m_port_persist;
required_memory_region m_region_maincpu;
address_space *m_space; address_space *m_space;
UINT8 *m_mainram; UINT8 *m_mainram;
UINT8 *m_BIOS; UINT8 *m_BIOS;
@ -121,11 +122,12 @@ public:
UINT8 m_gg_sio[5]; UINT8 m_gg_sio[5];
int m_paused; int m_paused;
// Data needed for Light Phaser
UINT8 m_ctrl1_th_state; UINT8 m_ctrl1_th_state;
UINT8 m_ctrl2_th_state; UINT8 m_ctrl2_th_state;
UINT8 m_ctrl1_th_latch; UINT8 m_ctrl1_th_latch;
UINT8 m_ctrl2_th_latch; UINT8 m_ctrl2_th_latch;
// Data needed for Light Phaser
int m_lphaser_x_offs; /* Needed to 'calibrate' lphaser; set at cart loading */ int m_lphaser_x_offs; /* Needed to 'calibrate' lphaser; set at cart loading */
// Data needed for SegaScope (3D glasses) // Data needed for SegaScope (3D glasses)
@ -160,10 +162,10 @@ public:
DECLARE_READ8_MEMBER(sms_input_port_dc_r); DECLARE_READ8_MEMBER(sms_input_port_dc_r);
DECLARE_READ8_MEMBER(sms_input_port_dd_r); DECLARE_READ8_MEMBER(sms_input_port_dd_r);
DECLARE_READ8_MEMBER(gg_input_port_00_r); DECLARE_READ8_MEMBER(gg_input_port_00_r);
DECLARE_WRITE8_MEMBER(gg_sio_w);
DECLARE_READ8_MEMBER(gg_sio_r); DECLARE_READ8_MEMBER(gg_sio_r);
DECLARE_WRITE8_MEMBER(sms_fm_detect_w); DECLARE_WRITE8_MEMBER(gg_sio_w);
DECLARE_READ8_MEMBER(sms_fm_detect_r); DECLARE_READ8_MEMBER(sms_fm_detect_r);
DECLARE_WRITE8_MEMBER(sms_fm_detect_w);
DECLARE_WRITE8_MEMBER(sms_ym2413_register_port_w); DECLARE_WRITE8_MEMBER(sms_ym2413_register_port_w);
DECLARE_WRITE8_MEMBER(sms_ym2413_data_port_w); DECLARE_WRITE8_MEMBER(sms_ym2413_data_port_w);
DECLARE_READ8_MEMBER(sms_sscope_r); DECLARE_READ8_MEMBER(sms_sscope_r);

View File

@ -869,8 +869,9 @@ MACHINE_START_MEMBER(sms_state,sms)
// a bug in the program code. The only way this cartridge could have run // a bug in the program code. The only way this cartridge could have run
// successfully on a real unit is if the RAM would be initialized with // successfully on a real unit is if the RAM would be initialized with
// a F0 pattern on power up; F0 = RET P. // a F0 pattern on power up; F0 = RET P.
// This initialization breaks the some Game Gear games though (e.g. // This initialization breaks some Game Gear games though (e.g.
// tempojr), suggesting that not all systems had the same initialization. // tempojr), suggesting that not all systems had the same initialization.
// This also breaks some homebrew software (e.g. Nine Pixels).
// For the moment we apply this to systems that have the Japanese SMS // For the moment we apply this to systems that have the Japanese SMS
// cartridge slot. // cartridge slot.
if (m_has_jpn_sms_cart_slot) if (m_has_jpn_sms_cart_slot)