mirror of
https://github.com/holub/mame
synced 2025-06-02 02:49:44 +03:00
(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:
parent
2c4d4a7837
commit
6829f6262f
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
#include "emu.h"
|
||||
#include "ggext.h"
|
||||
#include "../sms_ctrl/smsctrl.h"
|
||||
#include "bus/sms_ctrl/smsctrl.h"
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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 );
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user