Crosshair update

* Added Crosshair Options menu
  - ability to individually enable/disable crosshairs
  - ability for them to automatically disappear after a set amount of time
  - ability to select crosshair graphic
  - all settings are saved in the cfg file
 * Removed F1 toggle for crosshairs
 * Added new command option -crsshairpath
  - store all selectable graphics here
  - see config.txt for further info

OSD NOTE: render_load_png() has been changed to no longer force usage of the artwork directory.
Do a search for "render_load_png(" and replace with "render_load_png(OPTION_ARTPATH, " if needed.

----------------------------
F1 is now free to use for something new.  I was thinking it would be perfect for a context sensitive help file.  Each menu item could have a help tag, that it would look up and display info from an HTML file.
This commit is contained in:
Derrick Renaud 2009-03-28 22:55:34 +00:00
parent 9c63c95043
commit 01962d4fc5
15 changed files with 616 additions and 94 deletions

View file

@ -64,9 +64,6 @@ P Pauses the game.
Shift+P While paused, advances to next frame.
F1 Toggle crosshairs for games that use them. Each subsequent
press will enable crosshairs for one more player.
F2 Service Mode for games that support it.
F3 Resets the game.
@ -332,6 +329,15 @@ Core search path options
paths can be specified by separating them with semicolons. The default
is '.' (that is, search in the same directory as the MAME executable).
-crsshairpath <path>
Specifies a list of paths within which to find crosshair files. Multiple
paths can be specified by separating them with semicolons. The default
is 'crsshair' (that is, a directory "crsshair" in the same directory as
the MAME executable). If the Crosshair is set to default in the menu,
MAME will look for gamename\cross#.png and then cross#.png in the
specified crsshairpath, where # is the player number. Failing that,
MAME will use built-in default crosshairs.
Core Output Directory Options
@ -467,17 +473,17 @@ Core state/playback options
and names the snapshots under it starting with 0000 and increasing
from there.
-snapsize <width>x<height>
-snapsize <width>x<height>
Hard-codes the size for snapshots and movie recording. By default,
MAME will create snapshots at the game's current resolution in raw
pixels, and will create movies at the game's starting resolution in
raw pixels. If you specify this option, then MAME will create both
snapshots and movies at the size specified, and will bilinear filter
the result. Note that this size does not automatically rotate if the
the result. Note that this size does not automatically rotate if the
game is vertically oriented. The default is 'auto'.
-snapview <viewname>
-snapview <viewname>
Specifies the view to use when rendering snapshots and movies. By
default, both use a special 'internal' view, which renders a separate
@ -486,8 +492,8 @@ Core state/playback options
select a single view that will apply to all snapshots and movies.
Note that <viewname> does not need to be a perfect match; rather, it
will select the first view whose name matches all the characters
specified by <viewname>. For example, -snapview native will match the
"Native (15:14)" view even though it is not a perfect match.
specified by <viewname>. For example, -snapview native will match the
"Native (15:14)" view even though it is not a perfect match.
<viewname> can also be 'auto', which selects the first view with all
screens present. The default value is 'internal'.
@ -940,8 +946,8 @@ Debugging options
-[no]debug
Activates the integrated debugger. By default, the debugger is entered
by pressing the tilde (~) key during emulation. It is also entered
Activates the integrated debugger. By default, the debugger is entered
by pressing the tilde (~) key during emulation. It is also entered
immediately at startup. The default is OFF (-nodebug).
-debugscript <filename>

View file

@ -11,6 +11,8 @@
#include "driver.h"
#include "rendutil.h"
#include "config.h"
#include "xmlfile.h"
@ -29,15 +31,22 @@
typedef struct _crosshair_global crosshair_global;
struct _crosshair_global
{
UINT8 usage; /* true if any crosshairs are used */
UINT8 used[MAX_PLAYERS]; /* usage per player */
UINT8 mode[MAX_PLAYERS]; /* visibility mode per player */
UINT8 visible[MAX_PLAYERS]; /* visibility per player */
bitmap_t * bitmap[MAX_PLAYERS]; /* bitmap per player */
render_texture * texture[MAX_PLAYERS]; /* texture per player */
const device_config *screen[MAX_PLAYERS]; /* the screen on which this player's crosshair is drawn */
float x[MAX_PLAYERS]; /* current X position */
float y[MAX_PLAYERS]; /* current Y position */
float last_x[MAX_PLAYERS]; /* last X position */
float last_y[MAX_PLAYERS]; /* last Y position */
UINT8 fade; /* color fading factor */
UINT8 animation_counter; /* animation frame index */
UINT16 auto_time; /* time in seconds to turn invisible */
UINT16 time[MAX_PLAYERS]; /* time since last movement */
char name[MAX_PLAYERS][CROSSHAIR_PIC_NAME_LENGTH + 1]; /* name of crosshair png file */
};
@ -121,6 +130,9 @@ static const rgb_t crosshair_colors[] =
***************************************************************************/
static void crosshair_exit(running_machine *machine);
static void crosshair_load(running_machine *machine, int config_type, xml_data_node *parentnode);
static void crosshair_save(running_machine *machine, int config_type, xml_data_node *parentnode);
static void animate(const device_config *device, void *param, int vblank_state);
@ -134,44 +146,57 @@ static void animate(const device_config *device, void *param, int vblank_state);
structures for the given player
-------------------------------------------------*/
static void create_bitmap(int player)
static void create_bitmap(running_machine *machine, int player)
{
/* if we don't have a bitmap for this player yet */
int x, y;
char filename[20];
rgb_t color = crosshair_colors[player];
/* if we have a bitmap for this player, kill it */
if (global.bitmap[player] != NULL)
free(global.bitmap[player]);
if (global.name[player][0] != 0)
{
/* look for user specified file */
sprintf(filename, "%s.png", global.name[player]);
global.bitmap[player] = render_load_png(OPTION_CRSSHAIRPATH, NULL, filename, NULL, NULL);
}
else
{
/* look for default cross?.png in crsshair\game dir */
sprintf(filename, "cross%d.png", player + 1);
global.bitmap[player] = render_load_png(OPTION_CRSSHAIRPATH, machine->gamedrv->name, filename, NULL, NULL);
/* look for default cross?.png in crsshair dir */
if (global.bitmap[player] == NULL)
global.bitmap[player] = render_load_png(OPTION_CRSSHAIRPATH, NULL, filename, NULL, NULL);
}
/* if that didn't work, use the built-in one */
if (global.bitmap[player] == NULL)
{
int x, y;
char filename[20];
rgb_t color = crosshair_colors[player];
/* allocate a blank bitmap to start with */
global.bitmap[player] = bitmap_alloc(CROSSHAIR_RAW_SIZE, CROSSHAIR_RAW_SIZE, BITMAP_FORMAT_ARGB32);
bitmap_fill(global.bitmap[player], NULL, MAKE_ARGB(0x00,0xff,0xff,0xff));
/* first try to load a bitmap for the crosshair */
sprintf(filename, "cross%d.png", player);
global.bitmap[player] = render_load_png(NULL, filename, NULL, NULL);
/* if that didn't work, use the built-in one */
if (global.bitmap[player] == NULL)
/* extract the raw source data to it */
for (y = 0; y < CROSSHAIR_RAW_SIZE / 2; y++)
{
/* allocate a blank bitmap to start with */
global.bitmap[player] = bitmap_alloc(CROSSHAIR_RAW_SIZE, CROSSHAIR_RAW_SIZE, BITMAP_FORMAT_ARGB32);
bitmap_fill(global.bitmap[player], NULL, MAKE_ARGB(0x00,0xff,0xff,0xff));
/* assume it is mirrored vertically */
UINT32 *dest0 = BITMAP_ADDR32(global.bitmap[player], y, 0);
UINT32 *dest1 = BITMAP_ADDR32(global.bitmap[player], CROSSHAIR_RAW_SIZE - 1 - y, 0);
/* extract the raw source data to it */
for (y = 0; y < CROSSHAIR_RAW_SIZE / 2; y++)
{
/* assume it is mirrored vertically */
UINT32 *dest0 = BITMAP_ADDR32(global.bitmap[player], y, 0);
UINT32 *dest1 = BITMAP_ADDR32(global.bitmap[player], CROSSHAIR_RAW_SIZE - 1 - y, 0);
/* extract to two rows simultaneously */
for (x = 0; x < CROSSHAIR_RAW_SIZE; x++)
if ((crosshair_raw_top[y * CROSSHAIR_RAW_ROWBYTES + x / 8] << (x % 8)) & 0x80)
dest0[x] = dest1[x] = MAKE_ARGB(0xff,0x00,0x00,0x00) | color;
}
/* extract to two rows simultaneously */
for (x = 0; x < CROSSHAIR_RAW_SIZE; x++)
if ((crosshair_raw_top[y * CROSSHAIR_RAW_ROWBYTES + x / 8] << (x % 8)) & 0x80)
dest0[x] = dest1[x] = MAKE_ARGB(0xff,0x00,0x00,0x00) | color;
}
/* create a texture to reference the bitmap */
global.texture[player] = render_texture_alloc(render_texture_hq_scale, NULL);
render_texture_set_bitmap(global.texture[player], global.bitmap[player], NULL, TEXFORMAT_ARGB32, NULL);
}
/* create a texture to reference the bitmap */
global.texture[player] = render_texture_alloc(render_texture_hq_scale, NULL);
render_texture_set_bitmap(global.texture[player], global.bitmap[player], NULL, TEXFORMAT_ARGB32, NULL);
}
@ -191,6 +216,9 @@ void crosshair_init(running_machine *machine)
/* clear all the globals */
memset(&global, 0, sizeof(global));
/* setup the default auto visibility time */
global.auto_time = CROSSHAIR_VISIBILITY_AUTOTIME_DEFAULT;
/* determine who needs crosshairs */
for (port = machine->portconfig; port != NULL; port = port->next)
for (field = port->fieldlist; field != NULL; field = field->next)
@ -200,16 +228,22 @@ void crosshair_init(running_machine *machine)
assert(player < MAX_PLAYERS);
/* mark as used and visible */
/* mark as used and set the default visibility and mode */
global.usage = TRUE;
global.used[player] = TRUE;
global.visible[player] = TRUE;
global.mode[player] = CROSSHAIR_VISIBILITY_DEFAULT;
global.visible[player] = (CROSSHAIR_VISIBILITY_DEFAULT == CROSSHAIR_VISIBILITY_OFF) ? FALSE : TRUE;
/* for now, use the main screen */
global.screen[player] = machine->primary_screen;
create_bitmap(player);
create_bitmap(machine, player);
}
/* register callbacks for when we load/save configurations */
if (global.usage)
config_register(machine, "crosshairs", crosshair_load, crosshair_save);
/* register the animation callback */
if (machine->primary_screen != NULL)
video_screen_register_vblank_callback(machine->primary_screen, animate, NULL);
@ -240,31 +274,54 @@ static void crosshair_exit(running_machine *machine)
/*-------------------------------------------------
crosshair_toggle - toggle crosshair
visibility
crosshair_get_usage - return TRUE
if any crosshairs are used
-------------------------------------------------*/
void crosshair_toggle(running_machine *machine)
int crosshair_get_usage(running_machine *machine)
{
int player;
int first_hidden_player = -1;
return global.usage;
}
/* find the first invisible crosshair */
for (player = 0; player < MAX_PLAYERS; player++)
if (global.used[player] && !global.visible[player])
{
first_hidden_player = player;
break;
}
/* if all visible, turn all off */
if (first_hidden_player == -1)
for (player = 0; player < MAX_PLAYERS; player++)
global.visible[player] = FALSE;
/*-------------------------------------------------
crosshair_get_user_settings - return the
current crosshair settings for a player
Note: auto_time is common for all players
-------------------------------------------------*/
/* otherwise, turn on the first one that isn't currently on */
else
global.visible[first_hidden_player] = TRUE;
void crosshair_get_user_settings(running_machine *machine, UINT8 player, crosshair_user_settings *settings)
{
settings->auto_time = global.auto_time;
settings->used = global.used[player];
settings->mode = global.mode[player];
strcpy(settings->name, global.name[player]);
}
/*-------------------------------------------------
crosshair_set_user_settings - modify the
current crosshair settings for a player
Note: auto_time is common for all players
-------------------------------------------------*/
void crosshair_set_user_settings(running_machine *machine, UINT8 player, crosshair_user_settings *settings)
{
int changed = FALSE;
global.auto_time = settings->auto_time;
global.used[player] = settings->used;
global.mode[player] = settings->mode;
/* set visibility as specified by mode */
/* auto mode starts with visibility off */
global.visible[player] = (settings->mode == CROSSHAIR_VISIBILITY_ON) ? TRUE : FALSE;
/* update bitmap if name has changed */
changed = strcmp(settings->name, global.name[player]);
strcpy(global.name[player], settings->name);
if (changed)
create_bitmap(machine, player);
}
@ -285,10 +342,39 @@ static void animate(const device_config *device, void *param, int vblank_state)
else
global.fade = 0xa0 + (0x60 * (~global.animation_counter & 0x7f) / 0x80);
/* read all the lightgun values */
for (player = 0; player < MAX_PLAYERS; player++)
{
/* read all the lightgun values */
if (global.used[player])
input_port_get_crosshair_position(device->machine, player, &global.x[player], &global.y[player]);
/* auto visibility */
if (global.mode[player] == CROSSHAIR_VISIBILITY_AUTO)
{
if ((global.x[player] != global.last_x[player]) || (global.y[player] != global.last_y[player]))
{
/* crosshair has moved, keep crosshair visible */
global.visible[player] = TRUE;
global.last_x[player] = global.x[player];
global.last_y[player] = global.y[player];
global.time[player] = 0;
}
else
{
/* see if the player has been motionless for time specified */
/* note that the animate() routine is called twice per frame */
/* slightly confusing formula, but the effect is: */
/* auto_time = 1 makes the crosshair barely visible while moved */
/* every increment in auto_time is about .2s at 60Hz */
if (global.time[player] > global.auto_time * 24 - 20)
/* time exceeded so turn crosshair invisible */
global.visible[player] = FALSE;
/* increment player visibility time */
global.time[player]++;
}
}
}
}
@ -325,3 +411,124 @@ void crosshair_set_screen(running_machine *machine, int player, const device_con
{
global.screen[player] = screen;
}
/*-------------------------------------------------
crosshair_load - read and apply data from the
configuration file
-------------------------------------------------*/
static void crosshair_load(running_machine *machine, int config_type, xml_data_node *parentnode)
{
/* Note: crosshair_load() is only registered if croshairs are used */
xml_data_node *crosshairnode;
int auto_time;
/* we only care about game files */
if (config_type != CONFIG_TYPE_GAME)
return;
/* might not have any data */
if (parentnode == NULL)
return;
/* loop and get player crosshair info */
for (crosshairnode = xml_get_sibling(parentnode->child, "crosshair"); crosshairnode; crosshairnode = xml_get_sibling(crosshairnode->next, "crosshair"))
{
int player, mode;
player = xml_get_attribute_int(crosshairnode, "player", -1);
/* check to make sure we have a valid player */
/* also check if the player really uses a crosshair */
if (player >=0 && player < MAX_PLAYERS && global.used[player])
{
/* get, check, and store visibility mode */
mode = xml_get_attribute_int(crosshairnode, "mode", CROSSHAIR_VISIBILITY_DEFAULT);
if (mode >= CROSSHAIR_VISIBILITY_OFF && mode <= CROSSHAIR_VISIBILITY_AUTO)
{
global.mode[player] = (UINT8)mode;
/* set visibility as specified by mode */
/* auto mode starts with visibility off */
global.visible[player] = (mode == CROSSHAIR_VISIBILITY_ON) ? TRUE : FALSE;
}
/* get and store crosshair pic name, truncate name to max length */
strncpy(global.name[player], xml_get_attribute_string(crosshairnode, "pic", ""), CROSSHAIR_PIC_NAME_LENGTH);
/* update bitmap */
create_bitmap(machine, player);
}
}
/* get, check, and store auto visibility time */
crosshairnode = xml_get_sibling(parentnode->child, "autotime");
if (crosshairnode != NULL)
{
auto_time = xml_get_attribute_int(crosshairnode, "val", CROSSHAIR_VISIBILITY_AUTOTIME_DEFAULT);
if ((auto_time >= CROSSHAIR_VISIBILITY_AUTOTIME_MIN) && (auto_time <= CROSSHAIR_VISIBILITY_AUTOTIME_MAX))
global.auto_time = (UINT8)auto_time;
}
}
/*-------------------------------------------------
crosshair_save - save data to the
configuration file
-------------------------------------------------*/
static void crosshair_save(running_machine *machine, int config_type, xml_data_node *parentnode)
{
/* Note: crosshair_save() is only registered if crosshairs are used */
xml_data_node *crosshairnode;
int player;
/* we only care about game files */
if (config_type != CONFIG_TYPE_GAME)
return;
for (player = 0; player < MAX_PLAYERS; player++)
{
if (global.used[player])
{
/* create a node */
crosshairnode = xml_add_child(parentnode, "crosshair", NULL);
if (crosshairnode != NULL)
{
int changed = FALSE;
xml_set_attribute_int(crosshairnode, "player", player);
if (global.visible[player] != CROSSHAIR_VISIBILITY_DEFAULT)
{
xml_set_attribute_int(crosshairnode, "mode", global.mode[player]);
changed = TRUE;
}
/* the default graphic name is "", so only save if not */
if (strlen(global.name[player]) > 0)
{
xml_set_attribute(crosshairnode, "pic", global.name[player]);
changed = TRUE;
}
/* if nothing changed, kill the node */
if (!changed)
xml_delete_node(crosshairnode);
}
}
}
/* always store autotime so that it stays at the user value if it is needed */
if (global.auto_time != CROSSHAIR_VISIBILITY_AUTOTIME_DEFAULT)
{
/* create a node */
crosshairnode = xml_add_child(parentnode, "autotime", NULL);
if (crosshairnode != NULL)
xml_set_attribute_int(crosshairnode, "val", global.auto_time);
}
}

View file

@ -22,6 +22,36 @@
#define CROSSHAIR_SCREEN_NONE ((const device_config *) 0)
#define CROSSHAIR_SCREEN_ALL ((const device_config *) ~0)
/* user settings for visibility mode */
#define CROSSHAIR_VISIBILITY_OFF 0
#define CROSSHAIR_VISIBILITY_ON 1
#define CROSSHAIR_VISIBILITY_AUTO 2
#define CROSSHAIR_VISIBILITY_DEFAULT CROSSHAIR_VISIBILITY_ON
/* range allowed for auto visibility */
#define CROSSHAIR_VISIBILITY_AUTOTIME_MIN 1 /* do not change without changing formula */
#define CROSSHAIR_VISIBILITY_AUTOTIME_MAX 50
#define CROSSHAIR_VISIBILITY_AUTOTIME_DEFAULT 15
/* maximum crosshair pic filename size */
#define CROSSHAIR_PIC_NAME_LENGTH 12
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
/* user-controllable settings for a player */
typedef struct _crosshair_user_settings crosshair_user_settings;
struct _crosshair_user_settings
{
UINT8 used; /* is used */
UINT8 mode; /* visibility mode */
UINT8 auto_time; /* time in seconds to blank crosshair if no movement */
char name[CROSSHAIR_PIC_NAME_LENGTH + 1]; /* bitmap name */
};
/***************************************************************************
@ -40,6 +70,14 @@ void crosshair_toggle(running_machine *machine);
/* sets the screen(s) for a given player's crosshair */
void crosshair_set_screen(running_machine *machine, int player, const device_config *screen);
/* return TRUE if any crosshairs are used */
int crosshair_get_usage(running_machine *machine);
/* return the current crosshair settings for the given player */
void crosshair_get_user_settings(running_machine *machine, UINT8 player, crosshair_user_settings *settings);
/* modify the current crosshair settings for the given player */
void crosshair_set_user_settings(running_machine *machine, UINT8 player, crosshair_user_settings *settings);
#endif /* __CRSSHAIR_H__ */

View file

@ -43,6 +43,7 @@ const options_entry mame_core_options[] =
{ "inipath", ".;ini", 0, "path to ini files" },
{ "fontpath", ".", 0, "path to font files" },
{ "cheatpath", "cheat", 0, "path to cheat files" },
{ "crsshairpath", "crsshair", 0, "path to crosshair files" },
/* output directory options */
{ NULL, NULL, OPTION_HEADER, "CORE OUTPUT DIRECTORY OPTIONS" },

View file

@ -45,6 +45,7 @@
#define OPTION_INIPATH "inipath"
#define OPTION_FONTPATH "fontpath"
#define OPTION_CHEATPATH "cheatpath"
#define OPTION_CRSSHAIRPATH "crsshairpath"
/* core directory options */
#define OPTION_CFG_DIRECTORY "cfg_directory"

View file

@ -45,6 +45,7 @@
#define SEARCHPATH_INI OPTION_INIPATH
#define SEARCHPATH_FONT OPTION_FONTPATH
#define SEARCHPATH_CHEAT OPTION_CHEATPATH
#define SEARCHPATH_CRSSHAIRPATH OPTION_CRSSHAIRPATH
#define SEARCHPATH_IMAGE_DIFF OPTION_DIFF_DIRECTORY
#define SEARCHPATH_NVRAM OPTION_NVRAM_DIRECTORY

View file

@ -287,7 +287,6 @@ enum
IPT_UI_PASTE,
IPT_UI_SAVE_STATE,
IPT_UI_LOAD_STATE,
IPT_UI_TOGGLE_CROSSHAIR,
/* additional OSD-specified UI port types (up to 16) */
IPT_OSD_1,

View file

@ -563,7 +563,6 @@ static const input_type_desc core_types[] =
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_TOGGLE_DEBUG, "Toggle Debugger", SEQ_DEF_1(KEYCODE_F5) )
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_SAVE_STATE, "Save State", SEQ_DEF_2(KEYCODE_F7, KEYCODE_LSHIFT) )
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_LOAD_STATE, "Load State", SEQ_DEF_3(KEYCODE_F7, SEQCODE_NOT, KEYCODE_LSHIFT) )
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_TOGGLE_CROSSHAIR, "Toggle Crosshair", SEQ_DEF_1(KEYCODE_F1) )
INPUT_PORT_DIGITAL_TYPE( 0, UI, OSD_1, NULL, SEQ_DEF_0 )
INPUT_PORT_DIGITAL_TYPE( 0, UI, OSD_2, NULL, SEQ_DEF_0 )

View file

@ -1882,11 +1882,11 @@ static bitmap_t *load_component_bitmap(const char *dirname, const char *file, co
bitmap_t *bitmap;
/* load the basic bitmap */
bitmap = render_load_png(dirname, file, NULL, hasalpha);
bitmap = render_load_png(OPTION_ARTPATH, dirname, file, NULL, hasalpha);
if (bitmap != NULL && alphafile != NULL)
/* load the alpha bitmap if specified */
if (render_load_png(dirname, alphafile, bitmap, hasalpha) == NULL)
if (render_load_png(OPTION_ARTPATH, dirname, alphafile, bitmap, hasalpha) == NULL)
{
bitmap_free(bitmap);
bitmap = NULL;

View file

@ -559,7 +559,7 @@ void render_line_to_quad(const render_bounds *bounds, float width, render_bounds
bitmap_t
-------------------------------------------------*/
bitmap_t *render_load_png(const char *dirname, const char *filename, bitmap_t *alphadest, int *hasalpha)
bitmap_t *render_load_png(const char *path, const char *dirname, const char *filename, bitmap_t *alphadest, int *hasalpha)
{
bitmap_t *bitmap = NULL;
file_error filerr;
@ -573,7 +573,7 @@ bitmap_t *render_load_png(const char *dirname, const char *filename, bitmap_t *a
fname = astring_dupc(filename);
else
fname = astring_assemble_3(astring_alloc(), dirname, PATH_SEPARATOR, filename);
filerr = mame_fopen(SEARCHPATH_ARTWORK, astring_c(fname), OPEN_FLAG_READ, &file);
filerr = mame_fopen(path, astring_c(fname), OPEN_FLAG_READ, &file);
astring_free(fname);
if (filerr != FILERR_NONE)
return NULL;

View file

@ -29,7 +29,7 @@ void render_resample_argb_bitmap_hq(void *dest, UINT32 drowpixels, UINT32 dwidth
int render_clip_line(render_bounds *bounds, const render_bounds *clip);
int render_clip_quad(render_bounds *bounds, const render_bounds *clip, render_quad_texuv *texcoords);
void render_line_to_quad(const render_bounds *bounds, float width, render_bounds *bounds0, render_bounds *bounds1);
bitmap_t *render_load_png(const char *dirname, const char *filename, bitmap_t *alphadest, int *hasalpha);
bitmap_t *render_load_png(const char *path, const char *dirname, const char *filename, bitmap_t *alphadest, int *hasalpha);

View file

@ -36,23 +36,6 @@
CONSTANTS
***************************************************************************/
enum
{
INPUT_TYPE_DIGITAL = 0,
INPUT_TYPE_ANALOG = 1,
INPUT_TYPE_ANALOG_DEC = 2,
INPUT_TYPE_ANALOG_INC = 3
};
enum
{
ANALOG_ITEM_KEYSPEED = 0,
ANALOG_ITEM_CENTERSPEED,
ANALOG_ITEM_REVERSE,
ANALOG_ITEM_SENSITIVITY,
ANALOG_ITEM_COUNT
};
enum
{
LOADSAVE_NONE,
@ -1276,10 +1259,6 @@ static UINT32 handler_ingame(running_machine *machine, UINT32 state)
if (ui_input_pressed(machine, IPT_UI_SHOW_FPS))
ui_set_show_fps(!ui_get_show_fps());
/* toggle crosshair display */
if (ui_input_pressed(machine, IPT_UI_TOGGLE_CROSSHAIR))
crosshair_toggle(machine);
/* increment frameskip? */
if (ui_input_pressed(machine, IPT_UI_FRAMESKIP_INC))
{

View file

@ -85,6 +85,12 @@ enum
VIDEO_ITEM_VIEW
};
enum
{
CROSSHAIR_ITEM_VIS = 0,
CROSSHAIR_ITEM_PIC,
CROSSHAIR_ITEM_AUTO_TIME
};
/***************************************************************************
@ -203,6 +209,20 @@ struct _select_game_state
};
/* internal crosshair menu item data */
typedef struct _crosshair_item_data crosshair_item_data;
struct _crosshair_item_data
{
UINT8 type;
UINT8 player;
UINT8 min, max;
UINT8 cur;
UINT8 defvalue;
char last_name[CROSSHAIR_PIC_NAME_LENGTH + 1];
char next_name[CROSSHAIR_PIC_NAME_LENGTH + 1];
};
/***************************************************************************
GLOBAL VARIABLES
@ -281,6 +301,8 @@ static void menu_video_targets(running_machine *machine, ui_menu *menu, void *pa
static void menu_video_targets_populate(running_machine *machine, ui_menu *menu);
static void menu_video_options(running_machine *machine, ui_menu *menu, void *parameter, void *state);
static void menu_video_options_populate(running_machine *machine, ui_menu *menu, render_target *target);
static void menu_crosshair(running_machine *machine, ui_menu *menu, void *parameter, void *state);
static void menu_crosshair_populate(running_machine *machine, ui_menu *menu);
static void menu_quit_game(running_machine *machine, ui_menu *menu, void *parameter, void *state);
static void menu_select_game(running_machine *machine, ui_menu *menu, void *parameter, void *state);
static void menu_select_game_populate(running_machine *machine, ui_menu *menu, select_game_state *menustate);
@ -1489,6 +1511,10 @@ static void menu_main_populate(running_machine *machine, ui_menu *menu, void *st
/* add video options menu */
ui_menu_item_append(menu, "Video Options", NULL, 0, (render_target_get_indexed(1) != NULL) ? (void *)menu_video_targets : (void *)menu_video_options);
/* add crosshair options menu */
if (crosshair_get_usage(machine))
ui_menu_item_append(menu, "Crosshair Options", NULL, 0, menu_crosshair);
/* add cheat menu */
if (options_get_bool(mame_options(), OPTION_CHEAT) && cheat_get_next_menu_entry(machine, NULL, NULL, NULL, NULL) != NULL)
ui_menu_item_append(menu, "Cheat", NULL, 0, (void *)menu_cheat);
@ -3029,6 +3055,271 @@ static void menu_video_options_populate(running_machine *machine, ui_menu *menu,
}
/*-------------------------------------------------
menu_crosshair - handle the crosshair settings
menu
-------------------------------------------------*/
static void menu_crosshair(running_machine *machine, ui_menu *menu, void *parameter, void *state)
{
const ui_menu_event *event;
/* if the menu isn't built, populate now */
if (!ui_menu_populated(menu))
menu_crosshair_populate(machine, menu);
/* process the menu */
event = ui_menu_process(machine, menu, UI_MENU_PROCESS_LR_REPEAT);
/* handle events */
if (event != NULL && event->itemref != NULL)
{
crosshair_user_settings settings;
crosshair_item_data *data = event->itemref;
int changed = FALSE;
int set_def = FALSE;
int newval = data->cur;
/* retreive the user settings */
crosshair_get_user_settings(machine, data->player, &settings);
switch (event->iptkey)
{
/* if selected, reset to default value */
case IPT_UI_SELECT:
newval = data->defvalue;
set_def = TRUE;
break;
/* left decrements */
case IPT_UI_LEFT:
newval -= input_code_pressed(KEYCODE_LSHIFT) ? 10 : 1;
break;
/* right increments */
case IPT_UI_RIGHT:
newval += input_code_pressed(KEYCODE_LSHIFT) ? 10 : 1;
break;
}
/* clamp to range */
if (newval < data->min)
newval = data->min;
if (newval > data->max)
newval = data->max;
/* if things changed, update */
if (newval != data->cur)
{
switch (data->type)
{
/* visibility state */
case CROSSHAIR_ITEM_VIS:
settings.mode = newval;
changed = TRUE;
break;
/* auto time */
case CROSSHAIR_ITEM_AUTO_TIME:
settings.auto_time = newval;
changed = TRUE;
break;
}
}
/* crosshair graphic name */
if (data->type == CROSSHAIR_ITEM_PIC)
{
if (event->iptkey == IPT_UI_SELECT)
{
/* clear the name string to reset to default crosshair */
settings.name[0] = 0;
changed = TRUE;
}
else if (event->iptkey == IPT_UI_LEFT)
{
strcpy(settings.name, data->last_name);
changed = TRUE;
}
else if (event->iptkey == IPT_UI_RIGHT)
{
strcpy(settings.name, data->next_name);
changed = TRUE;
}
}
if (changed)
{
/* save the user settings */
crosshair_set_user_settings(machine, data->player, &settings);
/* rebuild the menu */
ui_menu_reset(menu, UI_MENU_RESET_REMEMBER_POSITION);
}
}
}
/*-------------------------------------------------
menu_crosshair_populate - populate the
crosshair settings menu
-------------------------------------------------*/
static void menu_crosshair_populate(running_machine *machine, ui_menu *menu)
{
crosshair_user_settings settings;
crosshair_item_data *data;
char temp_text[16];
int player;
UINT8 use_auto = FALSE;
UINT32 flags = 0;
mame_path *path;
/* loop over player and add the manual items */
for (player = 0; player < MAX_PLAYERS; player++)
{
/* get the user settings */
crosshair_get_user_settings(machine, player, &settings);
/* add menu items for usable crosshairs */
if (settings.used)
{
/* Make sure to keep these matched to the CROSSHAIR_VISIBILITY_xxx types */
static const char *const vis_text[] = { "Off", "On", "Auto" };
/* track if we need the auto time menu */
if (settings.mode == CROSSHAIR_VISIBILITY_AUTO) use_auto = TRUE;
/* CROSSHAIR_ITEM_VIS - allocate a data item and fill it */
data = ui_menu_pool_alloc(menu, sizeof(*data));
data->type = CROSSHAIR_ITEM_VIS;
data->player = player;
data->min = CROSSHAIR_VISIBILITY_OFF;
data->max = CROSSHAIR_VISIBILITY_AUTO;
data->defvalue = CROSSHAIR_VISIBILITY_DEFAULT;
data->cur = settings.mode;
/* put on arrows */
if (data->cur > data->min)
flags |= MENU_FLAG_LEFT_ARROW;
if (data->cur < data->max)
flags |= MENU_FLAG_RIGHT_ARROW;
/* add CROSSHAIR_ITEM_VIS menu */
sprintf(temp_text, "P%d Visibility", player + 1);
ui_menu_item_append(menu, temp_text, vis_text[settings.mode], flags, data);
/* CROSSHAIR_ITEM_PIC - allocate a data item and fill it */
data = ui_menu_pool_alloc(menu, sizeof(*data));
data->type = CROSSHAIR_ITEM_PIC;
data->player = player;
data->last_name[0] = 0;
/* other data item not used by this menu */
/* search for crosshair graphics */
/* open a path to the crosshairs */
path = mame_openpath(mame_options(), OPTION_CRSSHAIRPATH);
if (path != NULL)
{
const osd_directory_entry *dir;
/* reset search flags */
int using_default = FALSE;
int finished = FALSE;
int found = FALSE;
/* if we are using the default, then we just need to find the first in the list */
if (strlen(settings.name) == 0)
using_default = TRUE;
/* look for the current name, then remember the name before */
/* and find the next name */
while (((dir = mame_readpath(path)) != NULL) && !finished)
{
int length = strlen(dir->name);
/* look for files ending in .png with a name not larger then 9 chars*/
if ((length > 4) && (length <= CROSSHAIR_PIC_NAME_LENGTH + 4) &&
tolower(dir->name[length - 4] == '.') &&
tolower(dir->name[length - 3] == 'p') &&
tolower(dir->name[length - 2] == 'n') &&
tolower(dir->name[length - 1] == 'g'))
{
/* remove .png from length */
length -= 4;
if (found || using_default)
{
/* get the next name */
strncpy(data->next_name, dir->name, length);
data->next_name[length] = 0;
finished = TRUE;
}
else if (!strncmp(dir->name, settings.name, length))
{
/* we found the current name */
/* so loop once more to find the next name */
found = TRUE;
}
else
/* remember last name */
/* we will do it here in case files get added to the directory */
{
strncpy(data->last_name, dir->name, length);
data->last_name[length] = 0;
}
}
}
/* if name not found then next item is DEFAULT */
if (!found && !using_default)
{
data->next_name[0] = 0;
finished = TRUE;
}
/* setup the selection flags */
flags = 0;
if (finished)
flags |= MENU_FLAG_RIGHT_ARROW;
if (found)
flags |= MENU_FLAG_LEFT_ARROW;
/* add CROSSHAIR_ITEM_PIC menu */
sprintf(temp_text, "P%d Crosshair", player + 1);
ui_menu_item_append(menu, temp_text, using_default ? "DEFAULT" : settings.name, flags, data);
}
}
}
if (use_auto)
{
/* any player can be used to get the autotime */
crosshair_get_user_settings(machine, 0, &settings);
/* CROSSHAIR_ITEM_AUTO_TIME - allocate a data item and fill it */
data = ui_menu_pool_alloc(menu, sizeof(*data));
data->type = CROSSHAIR_ITEM_AUTO_TIME;
data->min = CROSSHAIR_VISIBILITY_AUTOTIME_MIN;
data->max = CROSSHAIR_VISIBILITY_AUTOTIME_MAX;
data->defvalue = CROSSHAIR_VISIBILITY_AUTOTIME_DEFAULT;
data->cur = settings.auto_time;
/* put on arrows in visible menu */
if (data->cur > data->min)
flags |= MENU_FLAG_LEFT_ARROW;
if (data->cur < data->max)
flags |= MENU_FLAG_RIGHT_ARROW;
/* add CROSSHAIR_ITEM_AUTO_TIME menu */
sprintf(temp_text, "%d", settings.auto_time);
ui_menu_item_append(menu, "Visible Delay", temp_text, flags, data);
}
// else
// /* leave a blank filler line when not in auto time so size does not rescale */
// ui_menu_item_append(menu, "", "", NULL, NULL);
}
/*-------------------------------------------------
menu_quit_game - handle the "menu" for
quitting the game

View file

@ -506,11 +506,11 @@ static int drawd3d_window_init(win_window_info *window)
// experimental: load a PNG to use for vector rendering; it is treated
// as a brightness map
d3d->vector_bitmap = render_load_png(NULL, "vector.png", NULL, NULL);
d3d->vector_bitmap = render_load_png(OPTION_ARTPATH, NULL, "vector.png", NULL, NULL);
if (d3d->vector_bitmap != NULL)
{
bitmap_fill(d3d->vector_bitmap, NULL, MAKE_ARGB(0xff,0xff,0xff,0xff));
d3d->vector_bitmap = render_load_png(NULL, "vector.png", d3d->vector_bitmap, NULL);
d3d->vector_bitmap = render_load_png(OPTION_ARTPATH, NULL, "vector.png", d3d->vector_bitmap, NULL);
}
// configure the adapter for the mode we want

View file

@ -450,7 +450,7 @@ static void load_effect_overlay(running_machine *machine, const char *filename)
strcpy(dest, ".png");
// load the file
effect_bitmap = render_load_png(NULL, tempstr, NULL, NULL);
effect_bitmap = render_load_png(OPTION_ARTPATH, NULL, tempstr, NULL, NULL);
if (effect_bitmap == NULL)
{
mame_printf_error("Unable to load PNG file '%s'\n", tempstr);