mirror of
https://github.com/holub/mame
synced 2025-06-06 21:03:47 +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
|
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.
|
||||||
|
@ -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.
|
||||||
|
@ -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"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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()
|
||||||
|
@ -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 );
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user