(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
Also known as Gear-to-Gear (or VS, in Japan) cable connector
Copyright MESS Team.
Visit http://mamedev.org for licensing and usage restrictions.

View File

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

View File

@ -16,7 +16,7 @@
#include "emu.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))
xoff = 26;
if (!memcmp(&rom[0x7ff0], signatures[2], 16))
else if (!memcmp(&rom[0x7ff0], signatures[2], 16))
xoff = 36;
if (!memcmp(&rom[0x7ff0], signatures[3], 16))
else if (!memcmp(&rom[0x7ff0], signatures[3], 16))
xoff = 32;
if (!memcmp(&rom[0x7ff0], signatures[4], 16))
else if (!memcmp(&rom[0x7ff0], signatures[4], 16))
xoff = 30;
if (!memcmp(&rom[0x7ff0], signatures[5], 16))
else if (!memcmp(&rom[0x7ff0], signatures[5], 16))
xoff = 39;
if (!memcmp(&rom[0x7ff0], signatures[6], 16))
else if (!memcmp(&rom[0x7ff0], signatures[6], 16))
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 rectangle &visarea = m_screen->visible_area();
rectangle aim_area;
int beam_x = m_screen->hpos();
int beam_y = m_screen->vpos();
int dx, dy;
int result = 1;
int pos_changed = 0;
int beam_x_orig = beam_x;
int beam_y_orig = beam_y;
int dy, result = 1;
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
the next line it enters that area. */
dy = abs(beam_y - lgun_y);
if (dy > LGUN_RADIUS || beam_y < visarea.min_y || beam_y > visarea.max_y)
/* If beam's y doesn't point to a line where the aim area is,
change it to the first line where the beam enters that area. */
if (beam_y < aim_area.min_y || beam_y > aim_area.max_y)
{
beam_y = lgun_y - LGUN_RADIUS;
if (beam_y < visarea.min_y)
beam_y = visarea.min_y;
dy = abs(beam_y - lgun_y);
pos_changed = 1;
beam_y = aim_area.min_y;
}
dy = abs(beam_y - lgun_y);
/* Caculate distance in x of the radius, relative to beam's y distance.
First try some shortcuts. */
@ -175,66 +176,73 @@ 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))));
}
/* If beam's x isn't in the circular aim area, change it
to the next point it enters that area. */
dx = abs(beam_x - lgun_x);
if (dx > dx_radius || beam_x < visarea.min_x || beam_x > visarea.max_x)
aim_area.min_x = MAX(lgun_x - dx_radius, visarea.min_x);
aim_area.max_x = MIN(lgun_x + dx_radius, visarea.max_x);
while (!new_check_point)
{
/* If beam's x has passed the aim area, advance to
next line and recheck y/x coordinates. */
if (beam_x > lgun_x)
/* If beam's x has passed the aim area, change it to the
next line and go back to recheck y/x coordinates. */
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;
pos_changed = 1;
}
beam_y++;
break;
}
if (pos_changed)
break;
/* If beam's x isn't in the aim area, change it to the
next point where the beam enters that area. */
if (beam_x < aim_area.min_x)
{
beam_x = aim_area.min_x;
}
if (m_sensor_last_state == 0) /* sensor is on */
{
/* keep sensor on until out of the aim area */
result = 0;
}
else
{
rgb_t color;
UINT8 brightness;
/* brightness of the lightgray color in the frame drawn by Light Phaser games */
const UINT8 sensor_min_brightness = 0x7f;
if (beam_x_orig != beam_x || beam_y_orig != beam_y)
{
/* adopt the new coordinates to adjust the timer */
new_check_point = true;
break;
}
color = m_port->pixel_r();
if (m_sensor_last_state == 0)
{
/* sensor is already on */
/* keep sensor on until out of the aim area */
result = 0;
}
else
{
rgb_t color;
UINT8 brightness;
/* brightness of the lightgray color in the frame drawn by Light Phaser games */
const UINT8 sensor_min_brightness = 0x7f;
/* reference: http://www.w3.org/TR/AERT#color-contrast */
brightness = (color.r() * 0.299) + (color.g() * 0.587) + (color.b() * 0.114);
//printf ("color brightness: %2X for x %d y %d\n", brightness, beam_x, beam_y);
color = m_port->pixel_r();
result = (brightness >= sensor_min_brightness) ? 0 : 1;
}
/* reference: http://www.w3.org/TR/AERT#color-contrast */
brightness = (color.r() * 0.299) + (color.g() * 0.587) + (color.b() * 0.114);
//printf ("color brightness: %2X for x %d y %d\n", brightness, beam_x, beam_y);
if (result == 0)
{
/* Set next check for when sensor will be off */
beam_x = lgun_x + dx_radius + 1;
if (beam_x > visarea.max_x)
beam_x = visarea.max_x + 1;
break;
}
else
{
/* Next check after the minimum interval */
beam_x += LGUN_X_INTERVAL;
pos_changed = 1;
result = (brightness >= sensor_min_brightness) ? 0 : 1;
}
if (result == 0) /* sensor on */
{
/* Set next check for when sensor will be off */
beam_x = aim_area.max_x + 1;
/* adopt the new coordinates to adjust the timer */
new_check_point = true;
}
else
{
/* Next check will happen after the minimum interval */
beam_x += LGUN_X_INTERVAL;
}
}
}
timer->adjust(m_screen->time_until_pos(beam_y, beam_x));
timer->adjust(m_screen->time_until_pos(beam_y, beam_x));
return result;
}

View File

@ -254,21 +254,27 @@ 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)
{
case 192:
m_frame_timing = (m_is_pal) ? pal_192 : ntsc_192;
break;
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 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;
case 240:
m_frame_timing = (m_is_pal) ? pal_240 : ntsc_240;
break;
}
m_cram_dirty = 1;
}
@ -675,7 +681,7 @@ WRITE8_MEMBER( sega315_5124_device::register_write )
case 2: /* VDP register write */
reg_num = data & 0x0f;
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)
{
@ -1441,7 +1447,7 @@ void sega315_5124_device::update_palette()
{
int i;
/* Exit if palette is has no changes */
/* Exit if palette has no changes */
if (m_cram_dirty == 0)
{
return;
@ -1468,7 +1474,7 @@ void sega315_5378_device::update_palette()
{
int i;
/* Exit if palette is has no changes */
/* Exit if palette has no changes */
if (m_cram_dirty == 0)
{
return;
@ -1557,20 +1563,7 @@ void sega315_5124_device::stop_timers()
void sega315_5124_device::vdp_postload()
{
switch (m_y_pixels)
{
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;
}
set_frame_timing();
}
void sega315_5124_device::device_start()

View File

@ -91,6 +91,7 @@ public:
protected:
void set_display_settings();
void set_frame_timing();
virtual void update_palette();
virtual void cram_write(UINT8 data);
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 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/sms_exp/smsexp.h"
#include "bus/sms_ctrl/smsctrl.h"
#include "bus/gamegear/ggext.h"
class sms_state : public driver_device
@ -32,9 +32,8 @@ public:
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_vdp(*this, "sms_vdp"),
m_ym(*this, "ym2413"),
m_main_scr(*this, "screen"),
m_region_maincpu(*this, "maincpu"),
m_ym(*this, "ym2413"),
m_port_ctrl1(*this, CONTROL1_TAG),
m_port_ctrl2(*this, CONTROL2_TAG),
m_port_gg_ext(*this, "ext"),
@ -45,6 +44,7 @@ public:
m_port_scope(*this, "SEGASCOPE"),
m_port_scope_binocular(*this, "SSCOPE_BINOCULAR"),
m_port_persist(*this, "PERSISTENCE"),
m_region_maincpu(*this, "maincpu"),
m_mainram(NULL),
m_is_gamegear(0),
m_is_gg_region_japan(0),
@ -61,12 +61,12 @@ public:
// devices
required_device<cpu_device> m_maincpu;
required_device<sega315_5124_device> m_vdp;
optional_device<ym2413_device> m_ym;
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_ctrl2;
optional_device<gg_ext_port_device> m_port_gg_ext;
optional_ioport m_port_gg_dc;
optional_ioport m_port_pause;
optional_ioport m_port_reset;
@ -75,6 +75,7 @@ public:
optional_ioport m_port_scope_binocular;
optional_ioport m_port_persist;
required_memory_region m_region_maincpu;
address_space *m_space;
UINT8 *m_mainram;
UINT8 *m_BIOS;
@ -121,11 +122,12 @@ public:
UINT8 m_gg_sio[5];
int m_paused;
// Data needed for Light Phaser
UINT8 m_ctrl1_th_state;
UINT8 m_ctrl2_th_state;
UINT8 m_ctrl1_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 */
// 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_dd_r);
DECLARE_READ8_MEMBER(gg_input_port_00_r);
DECLARE_WRITE8_MEMBER(gg_sio_w);
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_WRITE8_MEMBER(sms_fm_detect_w);
DECLARE_WRITE8_MEMBER(sms_ym2413_register_port_w);
DECLARE_WRITE8_MEMBER(sms_ym2413_data_port_w);
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
// successfully on a real unit is if the RAM would be initialized with
// 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.
// This also breaks some homebrew software (e.g. Nine Pixels).
// For the moment we apply this to systems that have the Japanese SMS
// cartridge slot.
if (m_has_jpn_sms_cart_slot)