mirror of
https://github.com/mamedev/mame.git
synced 2024-11-18 10:06:19 +01:00
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:
parent
9c63c95043
commit
01962d4fc5
15 changed files with 616 additions and 94 deletions
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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" },
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
|
||||
|
|
21
src/emu/ui.c
21
src/emu/ui.c
|
@ -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))
|
||||
{
|
||||
|
|
291
src/emu/uimenu.c
291
src/emu/uimenu.c
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue