diff options
author | 2016-04-23 11:25:03 +0200 | |
---|---|---|
committer | 2016-04-23 11:26:47 +0200 | |
commit | 1c726824f2b2cc7c6c03ff975e548b72f9b2c0a9 (patch) | |
tree | 020f20da5a8cd822065c1839bc7a53f826803a3d /src/emu/ui/ui.cpp | |
parent | 01657a63c13c79c5f045ba4ecb4c2fd7f7c5a1f8 (diff) |
Split UI and frontend part from core [Miodrag Milanovic]
Diffstat (limited to 'src/emu/ui/ui.cpp')
-rw-r--r-- | src/emu/ui/ui.cpp | 2704 |
1 files changed, 0 insertions, 2704 deletions
diff --git a/src/emu/ui/ui.cpp b/src/emu/ui/ui.cpp deleted file mode 100644 index 65d1711a4e0..00000000000 --- a/src/emu/ui/ui.cpp +++ /dev/null @@ -1,2704 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Nicola Salmoria, Aaron Giles, Nathan Woods -/********************************************************************* - - ui.cpp - - Functions used to handle MAME's user interface. - -*********************************************************************/ - -#include "emu.h" -#include "emuopts.h" -#include "mameopts.h" -#include "video/vector.h" -#include "machine/laserdsc.h" -#include "render.h" -#include "luaengine.h" -#include "cheat.h" -#include "rendfont.h" -#include "uiinput.h" -#include "ui/ui.h" -#include "ui/menu.h" -#include "ui/mainmenu.h" -#include "ui/filemngr.h" -#include "ui/sliders.h" -#include "ui/viewgfx.h" -#include "imagedev/cassette.h" -#include "image.h" - - -/*************************************************************************** - CONSTANTS -***************************************************************************/ - -enum -{ - LOADSAVE_NONE, - LOADSAVE_LOAD, - LOADSAVE_SAVE -}; - -#define MAX_SAVED_STATE_JOYSTICK 4 - - -/*************************************************************************** - LOCAL VARIABLES -***************************************************************************/ - -// list of natural keyboard keys that are not associated with UI_EVENT_CHARs -static const input_item_id non_char_keys[] = -{ - ITEM_ID_ESC, - ITEM_ID_F1, - ITEM_ID_F2, - ITEM_ID_F3, - ITEM_ID_F4, - ITEM_ID_F5, - ITEM_ID_F6, - ITEM_ID_F7, - ITEM_ID_F8, - ITEM_ID_F9, - ITEM_ID_F10, - ITEM_ID_F11, - ITEM_ID_F12, - ITEM_ID_NUMLOCK, - ITEM_ID_0_PAD, - ITEM_ID_1_PAD, - ITEM_ID_2_PAD, - ITEM_ID_3_PAD, - ITEM_ID_4_PAD, - ITEM_ID_5_PAD, - ITEM_ID_6_PAD, - ITEM_ID_7_PAD, - ITEM_ID_8_PAD, - ITEM_ID_9_PAD, - ITEM_ID_DEL_PAD, - ITEM_ID_PLUS_PAD, - ITEM_ID_MINUS_PAD, - ITEM_ID_INSERT, - ITEM_ID_DEL, - ITEM_ID_HOME, - ITEM_ID_END, - ITEM_ID_PGUP, - ITEM_ID_PGDN, - ITEM_ID_UP, - ITEM_ID_DOWN, - ITEM_ID_LEFT, - ITEM_ID_RIGHT, - ITEM_ID_PAUSE, - ITEM_ID_CANCEL -}; - -static const char *s_color_list[] = { - OPTION_UI_BORDER_COLOR, - OPTION_UI_BACKGROUND_COLOR, - OPTION_UI_GFXVIEWER_BG_COLOR, - OPTION_UI_UNAVAILABLE_COLOR, - OPTION_UI_TEXT_COLOR, - OPTION_UI_TEXT_BG_COLOR, - OPTION_UI_SUBITEM_COLOR, - OPTION_UI_CLONE_COLOR, - OPTION_UI_SELECTED_COLOR, - OPTION_UI_SELECTED_BG_COLOR, - OPTION_UI_MOUSEOVER_COLOR, - OPTION_UI_MOUSEOVER_BG_COLOR, - OPTION_UI_MOUSEDOWN_COLOR, - OPTION_UI_MOUSEDOWN_BG_COLOR, - OPTION_UI_DIPSW_COLOR, - OPTION_UI_SLIDER_COLOR -}; - -/*************************************************************************** - GLOBAL VARIABLES -***************************************************************************/ - -// messagebox buffer -std::string ui_manager::messagebox_text; -std::string ui_manager::messagebox_poptext; -rgb_t ui_manager::messagebox_backcolor; - -// slider info -std::vector<ui_menu_item> ui_manager::slider_list; -slider_state *ui_manager::slider_current; - - -/*************************************************************************** - FUNCTION PROTOTYPES -***************************************************************************/ - -// slider controls -static slider_state *slider_alloc(running_machine &machine, const char *title, INT32 minval, INT32 defval, INT32 maxval, INT32 incval, slider_update update, void *arg); -static INT32 slider_volume(running_machine &machine, void *arg, int id, std::string *str, INT32 newval); -static INT32 slider_mixervol(running_machine &machine, void *arg, int id, std::string *str, INT32 newval); -static INT32 slider_adjuster(running_machine &machine, void *arg, int id, std::string *str, INT32 newval); -static INT32 slider_overclock(running_machine &machine, void *arg, int id, std::string *str, INT32 newval); -static INT32 slider_refresh(running_machine &machine, void *arg, int id, std::string *str, INT32 newval); -static INT32 slider_brightness(running_machine &machine, void *arg, int id, std::string *str, INT32 newval); -static INT32 slider_contrast(running_machine &machine, void *arg, int id, std::string *str, INT32 newval); -static INT32 slider_gamma(running_machine &machine, void *arg, int id, std::string *str, INT32 newval); -static INT32 slider_xscale(running_machine &machine, void *arg, int id, std::string *str, INT32 newval); -static INT32 slider_yscale(running_machine &machine, void *arg, int id, std::string *str, INT32 newval); -static INT32 slider_xoffset(running_machine &machine, void *arg, int id, std::string *str, INT32 newval); -static INT32 slider_yoffset(running_machine &machine, void *arg, int id, std::string *str, INT32 newval); -static INT32 slider_overxscale(running_machine &machine, void *arg, int id, std::string *str, INT32 newval); -static INT32 slider_overyscale(running_machine &machine, void *arg, int id, std::string *str, INT32 newval); -static INT32 slider_overxoffset(running_machine &machine, void *arg, int id, std::string *str, INT32 newval); -static INT32 slider_overyoffset(running_machine &machine, void *arg, int id, std::string *str, INT32 newval); -static INT32 slider_flicker(running_machine &machine, void *arg, int id, std::string *str, INT32 newval); -static INT32 slider_beam_width_min(running_machine &machine, void *arg, int id, std::string *str, INT32 newval); -static INT32 slider_beam_width_max(running_machine &machine, void *arg, int id, std::string *str, INT32 newval); -static INT32 slider_beam_intensity_weight(running_machine &machine, void *arg, int id, std::string *str, INT32 newval); -static std::string slider_get_screen_desc(screen_device &screen); -#ifdef MAME_DEBUG -static INT32 slider_crossscale(running_machine &machine, void *arg, int id, std::string *str, INT32 newval); -static INT32 slider_crossoffset(running_machine &machine, void *arg, int id, std::string *str, INT32 newval); -#endif - - -/*************************************************************************** - INLINE FUNCTIONS -***************************************************************************/ - -//------------------------------------------------- -// load ui options -//------------------------------------------------- - -static void load_ui_options(running_machine &machine) -{ - // parse the file - std::string error; - // attempt to open the output file - emu_file file(machine.options().ini_path(), OPEN_FLAG_READ); - if (file.open("ui.ini") == osd_file::error::NONE) - { - bool result = machine.ui().options().parse_ini_file((util::core_file&)file, OPTION_PRIORITY_MAME_INI, OPTION_PRIORITY_DRIVER_INI, error); - if (!result) - osd_printf_error("**Error loading ui.ini**"); - } -} - -//------------------------------------------------- -// is_breakable_char - is a given unicode -// character a possible line break? -//------------------------------------------------- - -static inline int is_breakable_char(unicode_char ch) -{ - // regular spaces and hyphens are breakable - if (ch == ' ' || ch == '-') - return TRUE; - - // In the following character sets, any character is breakable: - // Hiragana (3040-309F) - // Katakana (30A0-30FF) - // Bopomofo (3100-312F) - // Hangul Compatibility Jamo (3130-318F) - // Kanbun (3190-319F) - // Bopomofo Extended (31A0-31BF) - // CJK Strokes (31C0-31EF) - // Katakana Phonetic Extensions (31F0-31FF) - // Enclosed CJK Letters and Months (3200-32FF) - // CJK Compatibility (3300-33FF) - // CJK Unified Ideographs Extension A (3400-4DBF) - // Yijing Hexagram Symbols (4DC0-4DFF) - // CJK Unified Ideographs (4E00-9FFF) - if (ch >= 0x3040 && ch <= 0x9fff) - return TRUE; - - // Hangul Syllables (AC00-D7AF) are breakable - if (ch >= 0xac00 && ch <= 0xd7af) - return TRUE; - - // CJK Compatibility Ideographs (F900-FAFF) are breakable - if (ch >= 0xf900 && ch <= 0xfaff) - return TRUE; - - return FALSE; -} - - - -/*************************************************************************** - CORE IMPLEMENTATION -***************************************************************************/ - -static const UINT32 mouse_bitmap[32*32] = -{ - 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff, - 0x09a46f30,0x81ac7c43,0x24af8049,0x00ad7d45,0x00a8753a,0x00a46f30,0x009f6725,0x009b611c,0x00985b14,0x0095560d,0x00935308,0x00915004,0x00904e02,0x008f4e01,0x008f4d00,0x008f4d00,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff, - 0x00a16a29,0xa2aa783d,0xffbb864a,0xc0b0824c,0x5aaf7f48,0x09ac7b42,0x00a9773c,0x00a67134,0x00a26b2b,0x009e6522,0x009a5e19,0x00965911,0x0094550b,0x00925207,0x00915004,0x008f4e01,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff, - 0x009a5e18,0x39a06827,0xffb97c34,0xffe8993c,0xffc88940,0xedac7c43,0x93ad7c44,0x2dac7c43,0x00ab793f,0x00a87438,0x00a46f30,0x00a06827,0x009c611d,0x00985c15,0x0095570e,0x00935309,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff, - 0x00935308,0x00965810,0xcc9a5e19,0xffe78a21,0xfffb9929,0xfff49931,0xffd88e39,0xffb9813f,0xc9ac7c43,0x66ad7c44,0x0cac7a41,0x00a9773c,0x00a67134,0x00a26b2b,0x009e6522,0x009a5e19,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff, - 0x008f4e01,0x00904e02,0x60925106,0xffba670a,0xfff88b11,0xfff98f19,0xfff99422,0xfff9982b,0xffe89434,0xffc9883c,0xf3ac7a41,0x9cad7c44,0x39ac7c43,0x00ab7a40,0x00a87539,0x00a56f31,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff, - 0x008e4d00,0x008e4d00,0x098e4d00,0xea8f4d00,0xffee7f03,0xfff68407,0xfff6870d,0xfff78b15,0xfff78f1d,0xfff79426,0xfff49730,0xffd98d38,0xffbc823f,0xd2ac7c43,0x6fad7c44,0x12ac7b42,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff, - 0x008e4d00,0x008e4d00,0x008e4c00,0x8a8e4c00,0xffc46800,0xfff37e00,0xfff37f02,0xfff38106,0xfff3830a,0xfff48711,0xfff48b19,0xfff58f21,0xfff5942b,0xffe79134,0xffcb863b,0xf9ac7a41,0xa5ac7c43,0x3fac7c43,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff, - 0x008e4d00,0x008e4d00,0x008e4c00,0x218d4c00,0xfc8e4c00,0xffee7a00,0xfff07c00,0xfff17c00,0xfff17d02,0xfff17e04,0xfff18008,0xfff2830d,0xfff28614,0xfff38a1c,0xfff38f25,0xfff2932e,0xffd98b37,0xffbc813e,0xdbac7c43,0x78ad7c44,0x15ac7b42,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff, - 0x008e4d00,0x008e4d00,0x008e4d00,0x008e4c00,0xb18d4c00,0xffcf6b00,0xffed7900,0xffed7900,0xffee7900,0xffee7a01,0xffee7a01,0xffee7b03,0xffee7c06,0xffef7e0a,0xffef8110,0xfff08618,0xfff08a20,0xfff18f2a,0xffe78f33,0xffcc863b,0xfcab7a40,0xaeac7c43,0x4bac7c43,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff, - 0x008f4d00,0x008e4d00,0x008e4d00,0x008e4c00,0x488d4c00,0xffa85800,0xffe97500,0xffea7600,0xffea7600,0xffeb7600,0xffeb7600,0xffeb7600,0xffeb7701,0xffeb7702,0xffeb7804,0xffec7a07,0xffec7d0d,0xffec8013,0xffed851c,0xffee8a25,0xffee8f2e,0xffd98937,0xffbe813d,0xe4ab7a40,0x81ab7a40,0x1ba9763b,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff, - 0x008f4d00,0x008e4d00,0x008e4d00,0x008e4c00,0x008d4c00,0xdb8d4c00,0xffd86c00,0xffe77300,0xffe77300,0xffe87300,0xffe87300,0xffe87300,0xffe87300,0xffe87300,0xffe87401,0xffe87401,0xffe87503,0xffe97606,0xffe9780a,0xffe97c10,0xffea7f16,0xffeb831d,0xffeb8623,0xffe48426,0xffc67725,0xffa5661f,0xb7985c15,0x54935309,0x038e4d00,0x00ffffff,0x00ffffff,0x00ffffff, - 0x008f4d00,0x008e4d00,0x008e4d00,0x008e4d00,0x008e4c00,0x6f8d4c00,0xffb25b00,0xffe36f00,0xffe47000,0xffe47000,0xffe57000,0xffe57000,0xffe57000,0xffe57000,0xffe57000,0xffe57000,0xffe57000,0xffe57000,0xffe57101,0xffe57000,0xffe47000,0xffe16e00,0xffde6c00,0xffd86900,0xffd06600,0xffc76200,0xffaa5500,0xff8a4800,0xea743f00,0x5a7a4200,0x00ffffff,0x00ffffff, - 0x008f4d00,0x008f4d00,0x008e4d00,0x008e4d00,0x008e4c00,0x0f8d4c00,0xf38d4c00,0xffdc6a00,0xffe16d00,0xffe16d00,0xffe26d00,0xffe26d00,0xffe26d00,0xffe26d00,0xffe26d00,0xffe16d00,0xffe06c00,0xffde6b00,0xffd96900,0xffd16500,0xffc76000,0xffb95900,0xffab5200,0xff9c4b00,0xff894300,0xff6b3600,0xf9512c00,0xa5542d00,0x3c5e3200,0x00ffffff,0x00ffffff,0x00ffffff, - 0x008f4d00,0x008f4d00,0x008e4d00,0x008e4d00,0x008e4c00,0x008d4c00,0x968d4c00,0xffbc5d00,0xffde6a00,0xffde6a00,0xffde6a00,0xffdf6a00,0xffdf6a00,0xffdf6a00,0xffde6a00,0xffdc6800,0xffd66600,0xffcc6100,0xffbf5b00,0xffaf5300,0xff9d4a00,0xff8a4200,0xff6d3500,0xff502900,0xe7402300,0x7b3f2200,0x15442500,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff, - 0x008f4d00,0x008f4d00,0x008f4d00,0x008e4d00,0x008e4d00,0x008e4c00,0x2a8d4c00,0xff9b5000,0xffda6600,0xffdb6700,0xffdb6700,0xffdc6700,0xffdc6700,0xffdb6700,0xffd96500,0xffd16200,0xffc25b00,0xffad5100,0xff974700,0xff7f3c00,0xff602f00,0xff472500,0xbd3d2100,0x513d2100,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff, - 0x008f4d00,0x008f4d00,0x008f4d00,0x008e4d00,0x008e4d00,0x008e4c00,0x008e4c00,0xc08d4c00,0xffc35c00,0xffd76300,0xffd76300,0xffd86300,0xffd86300,0xffd76300,0xffd06000,0xffc05800,0xffa54c00,0xff7f3b00,0xff582c00,0xf03f2200,0x903c2000,0x2a3e2100,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff, - 0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008e4d00,0x008e4d00,0x008e4c00,0x548d4c00,0xffa55200,0xffd35f00,0xffd46000,0xffd46000,0xffd46000,0xffd25e00,0xffc65900,0xffac4e00,0xff833c00,0xe7472600,0x693c2000,0x0c3d2100,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff, - 0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008e4d00,0x008e4d00,0x008e4c00,0x038d4c00,0xe48d4c00,0xffc95a00,0xffd15d00,0xffd15d00,0xffd15d00,0xffcb5a00,0xffb95200,0xff984300,0xff5f2e00,0x723f2200,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff, - 0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008e4d00,0x008e4d00,0x008e4d00,0x008e4c00,0x7b8d4c00,0xffad5200,0xffce5a00,0xffce5a00,0xffcd5900,0xffc35500,0xffaa4a00,0xff853a00,0xf9472600,0x15432400,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff, - 0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008e4d00,0x008e4d00,0x008e4c00,0x188d4c00,0xf98e4c00,0xffc95600,0xffcb5700,0xffc75500,0xffb94f00,0xff9b4200,0xff6c3100,0xab442500,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff, - 0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008e4d00,0x008e4d00,0x008e4d00,0x008e4c00,0xa58d4c00,0xffb35000,0xffc75300,0xffc05000,0xffac4800,0xff8b3a00,0xff542a00,0x45462500,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff, - 0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008e4d00,0x008e4d00,0x008e4c00,0x398d4c00,0xff994d00,0xffc24f00,0xffb74b00,0xff9e4000,0xff763200,0xde472600,0x03492800,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff, - 0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008e4d00,0x008e4d00,0x008e4c00,0x008e4c00,0xcf8d4c00,0xffb24b00,0xffab4500,0xff8d3900,0xff5e2b00,0x7e452500,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff, - 0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008e4d00,0x008e4d00,0x008e4d00,0x008e4c00,0x638d4c00,0xff984800,0xffa03f00,0xff7e3200,0xfc492800,0x1b472600,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff, - 0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008e4d00,0x008e4d00,0x008e4c00,0x098b4b00,0xed824600,0xff903800,0xff692c00,0xb4462600,0x004c2900,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff, - 0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008e4d00,0x008e4d00,0x008e4c00,0x008a4a00,0x8a7e4400,0xff793500,0xff572900,0x51472600,0x00542d00,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff, - 0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008e4d00,0x008d4c00,0x00884900,0x247a4200,0xfc633500,0xe74f2a00,0x034d2900,0x005e3300,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff, - 0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008e4d00,0x008d4c00,0x00884900,0x00794100,0xb4643600,0x87552e00,0x00593000,0x006b3900,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff, - 0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008f4d00,0x008d4c00,0x00884900,0x007c4300,0x486d3b00,0x24643600,0x00693800,0x00774000,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff, - 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff, - 0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff -}; - - -//------------------------------------------------- -// ctor - set up the user interface -//------------------------------------------------- - -ui_manager::ui_manager(running_machine &machine) - : m_machine(machine) -{ -} - -void ui_manager::init() -{ - load_ui_options(machine()); - // initialize the other UI bits - ui_menu::init(machine()); - ui_gfx_init(machine()); - - // reset instance variables - m_font = nullptr; - m_handler_callback = nullptr; - m_handler_param = 0; - m_single_step = false; - m_showfps = false; - m_showfps_end = 0; - m_show_profiler = false; - m_popup_text_end = 0; - m_use_natural_keyboard = false; - m_mouse_arrow_texture = nullptr; - m_show_timecode_counter = false; - m_show_timecode_total = false; - m_load_save_hold = false; - - get_font_rows(&machine()); - decode_ui_color(0, &machine()); - - // more initialization - set_handler(handler_messagebox, 0); - m_non_char_keys_down = std::make_unique<UINT8[]>((ARRAY_LENGTH(non_char_keys) + 7) / 8); - m_mouse_show = machine().system().flags & MACHINE_CLICKABLE_ARTWORK ? true : false; - - // request a callback upon exiting - machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(ui_manager::exit), this)); - - // retrieve options - m_use_natural_keyboard = machine().options().natural_keyboard(); - bitmap_argb32 *ui_mouse_bitmap = auto_alloc(machine(), bitmap_argb32(32, 32)); - UINT32 *dst = &ui_mouse_bitmap->pix32(0); - memcpy(dst,mouse_bitmap,32*32*sizeof(UINT32)); - m_mouse_arrow_texture = machine().render().texture_alloc(); - m_mouse_arrow_texture->set_bitmap(*ui_mouse_bitmap, ui_mouse_bitmap->cliprect(), TEXFORMAT_ARGB32); -} - - -//------------------------------------------------- -// exit - clean up ourselves on exit -//------------------------------------------------- - -void ui_manager::exit() -{ - // free the mouse texture - machine().render().texture_free(m_mouse_arrow_texture); - m_mouse_arrow_texture = nullptr; - - // free the font - if (m_font != nullptr) - { - machine().render().font_free(m_font); - m_font = nullptr; - } -} - - -//------------------------------------------------- -// initialize - initialize ui lists -//------------------------------------------------- - -void ui_manager::initialize(running_machine &machine) -{ - // initialize the on-screen display system - slider_list = slider_init(machine); - if (slider_list.size() > 0) - { - slider_current = reinterpret_cast<slider_state *>(slider_list[0].ref); - } - else - { - slider_current = nullptr; - } -} - - -//------------------------------------------------- -// set_handler - set a callback/parameter -// pair for the current UI handler -//------------------------------------------------- - -UINT32 ui_manager::set_handler(ui_callback callback, UINT32 param) -{ - m_handler_callback = callback; - m_handler_param = param; - return param; -} - - -//------------------------------------------------- -// display_startup_screens - display the -// various startup screens -//------------------------------------------------- - -void ui_manager::display_startup_screens(bool first_time) -{ - const int maxstate = 3; - int str = machine().options().seconds_to_run(); - bool show_gameinfo = !machine().options().skip_gameinfo(); - bool show_warnings = true, show_mandatory_fileman = true; - int state; - - // disable everything if we are using -str for 300 or fewer seconds, or if we're the empty driver, - // or if we are debugging - if (!first_time || (str > 0 && str < 60*5) || &machine().system() == &GAME_NAME(___empty) || (machine().debug_flags & DEBUG_FLAG_ENABLED) != 0) - show_gameinfo = show_warnings = show_mandatory_fileman = FALSE; - - #if defined(EMSCRIPTEN) - // also disable for the JavaScript port since the startup screens do not run asynchronously - show_gameinfo = show_warnings = FALSE; - #endif - - // loop over states - set_handler(handler_ingame, 0); - for (state = 0; state < maxstate && !machine().scheduled_event_pending() && !ui_menu::stack_has_special_main_menu(); state++) - { - // default to standard colors - messagebox_backcolor = UI_BACKGROUND_COLOR; - - // pick the next state - switch (state) - { - case 0: - if (show_warnings && warnings_string(messagebox_text).length() > 0) - { - set_handler(handler_messagebox_anykey, 0); - if (machine().system().flags & (MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_COLORS | MACHINE_REQUIRES_ARTWORK | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_KEYBOARD | MACHINE_NO_SOUND)) - messagebox_backcolor = UI_YELLOW_COLOR; - if (machine().system().flags & (MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION | MACHINE_MECHANICAL)) - messagebox_backcolor = UI_RED_COLOR; - } - break; - - case 1: - if (show_gameinfo && game_info_astring(messagebox_text).length() > 0) - set_handler(handler_messagebox_anykey, 0); - break; - - case 2: - if (show_mandatory_fileman && machine().image().mandatory_scan(messagebox_text).length() > 0) - { - std::string warning; - warning.assign(_("This driver requires images to be loaded in the following device(s): ")).append(messagebox_text.substr(0, messagebox_text.length() - 2)); - ui_menu_file_manager::force_file_manager(machine(), &machine().render().ui_container(), warning.c_str()); - } - break; - } - - // clear the input memory - machine().input().reset_polling(); - while (machine().input().poll_switches() != INPUT_CODE_INVALID) { } - - // loop while we have a handler - while (m_handler_callback != handler_ingame && !machine().scheduled_event_pending() && !ui_menu::stack_has_special_main_menu()) - { - machine().video().frame_update(); - } - - // clear the handler and force an update - set_handler(handler_ingame, 0); - machine().video().frame_update(); - } - - // if we're the empty driver, force the menus on - if (ui_menu::stack_has_special_main_menu()) - set_handler(ui_menu::ui_handler, 0); -} - - -//------------------------------------------------- -// set_startup_text - set the text to display -// at startup -//------------------------------------------------- - -void ui_manager::set_startup_text(const char *text, bool force) -{ - static osd_ticks_t lastupdatetime = 0; - osd_ticks_t curtime = osd_ticks(); - - // copy in the new text - messagebox_text.assign(text); - messagebox_backcolor = UI_BACKGROUND_COLOR; - - // don't update more than 4 times/second - if (force || (curtime - lastupdatetime) > osd_ticks_per_second() / 4) - { - lastupdatetime = curtime; - machine().video().frame_update(); - } -} - - -//------------------------------------------------- -// update_and_render - update the UI and -// render it; called by video.c -//------------------------------------------------- - -void ui_manager::update_and_render(render_container *container) -{ - // always start clean - container->empty(); - - // if we're paused, dim the whole screen - if (machine().phase() >= MACHINE_PHASE_RESET && (single_step() || machine().paused())) - { - int alpha = (1.0f - machine().options().pause_brightness()) * 255.0f; - if (ui_menu::stack_has_special_main_menu()) - alpha = 255; - if (alpha > 255) - alpha = 255; - if (alpha >= 0) - container->add_rect(0.0f, 0.0f, 1.0f, 1.0f, rgb_t(alpha,0x00,0x00,0x00), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); - } - - // render any cheat stuff at the bottom - if (machine().phase() >= MACHINE_PHASE_RESET) - { - machine().manager().lua()->on_frame_done(); - machine().cheat().render_text(*container); - } - - // call the current UI handler - assert(m_handler_callback != nullptr); - m_handler_param = (*m_handler_callback)(machine(), container, m_handler_param); - - // display any popup messages - if (osd_ticks() < m_popup_text_end) - draw_text_box(container, messagebox_poptext.c_str(), JUSTIFY_CENTER, 0.5f, 0.9f, messagebox_backcolor); - else - m_popup_text_end = 0; - - // display the internal mouse cursor - if (m_mouse_show || (is_menu_active() && machine().options().ui_mouse())) - { - INT32 mouse_target_x, mouse_target_y; - bool mouse_button; - render_target *mouse_target = machine().ui_input().find_mouse(&mouse_target_x, &mouse_target_y, &mouse_button); - - if (mouse_target != nullptr) - { - float mouse_y=-1,mouse_x=-1; - if (mouse_target->map_point_container(mouse_target_x, mouse_target_y, *container, mouse_x, mouse_y)) - { - const float cursor_size = 0.6 * machine().ui().get_line_height(); - container->add_quad(mouse_x, mouse_y, mouse_x + cursor_size*container->manager().ui_aspect(container), mouse_y + cursor_size, UI_TEXT_COLOR, m_mouse_arrow_texture, PRIMFLAG_ANTIALIAS(1) | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); - } - } - } - - // cancel takes us back to the ingame handler - if (m_handler_param == UI_HANDLER_CANCEL) - set_handler(handler_ingame, 0); -} - - -//------------------------------------------------- -// get_font - return the UI font -//------------------------------------------------- - -render_font *ui_manager::get_font() -{ - // allocate the font and messagebox string - if (m_font == nullptr) - m_font = machine().render().font_alloc(machine().options().ui_font()); - return m_font; -} - - -//------------------------------------------------- -// get_line_height - return the current height -// of a line -//------------------------------------------------- - -float ui_manager::get_line_height() -{ - INT32 raw_font_pixel_height = get_font()->pixel_height(); - render_target &ui_target = machine().render().ui_target(); - INT32 target_pixel_height = ui_target.height(); - float one_to_one_line_height; - float scale_factor; - - // compute the font pixel height at the nominal size - one_to_one_line_height = (float)raw_font_pixel_height / (float)target_pixel_height; - - // determine the scale factor - scale_factor = UI_TARGET_FONT_HEIGHT / one_to_one_line_height; - - // if our font is small-ish, do integral scaling - if (raw_font_pixel_height < 24) - { - // do we want to scale smaller? only do so if we exceed the threshold - if (scale_factor <= 1.0f) - { - if (one_to_one_line_height < UI_MAX_FONT_HEIGHT || raw_font_pixel_height < 12) - scale_factor = 1.0f; - } - - // otherwise, just ensure an integral scale factor - else - scale_factor = floor(scale_factor); - } - - // otherwise, just make sure we hit an even number of pixels - else - { - INT32 height = scale_factor * one_to_one_line_height * (float)target_pixel_height; - scale_factor = (float)height / (one_to_one_line_height * (float)target_pixel_height); - } - - return scale_factor * one_to_one_line_height; -} - - -//------------------------------------------------- -// get_char_width - return the width of a -// single character -//------------------------------------------------- - -float ui_manager::get_char_width(unicode_char ch) -{ - return get_font()->char_width(get_line_height(), machine().render().ui_aspect(), ch); -} - - -//------------------------------------------------- -// get_string_width - return the width of a -// character string -//------------------------------------------------- - -float ui_manager::get_string_width(const char *s, float text_size) -{ - return get_font()->utf8string_width(get_line_height() * text_size, machine().render().ui_aspect(), s); -} - - -//------------------------------------------------- -// draw_outlined_box - add primitives to draw -// an outlined box with the given background -// color -//------------------------------------------------- - -void ui_manager::draw_outlined_box(render_container *container, float x0, float y0, float x1, float y1, rgb_t backcolor) -{ - draw_outlined_box(container, x0, y0, x1, y1, UI_BORDER_COLOR, backcolor); -} - - -//------------------------------------------------- -// draw_outlined_box - add primitives to draw -// an outlined box with the given background -// color -//------------------------------------------------- - -void ui_manager::draw_outlined_box(render_container *container, float x0, float y0, float x1, float y1, rgb_t fgcolor, rgb_t bgcolor) -{ - container->add_rect(x0, y0, x1, y1, bgcolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); - container->add_line(x0, y0, x1, y0, UI_LINE_WIDTH, fgcolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); - container->add_line(x1, y0, x1, y1, UI_LINE_WIDTH, fgcolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); - container->add_line(x1, y1, x0, y1, UI_LINE_WIDTH, fgcolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); - container->add_line(x0, y1, x0, y0, UI_LINE_WIDTH, fgcolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); -} - - -//------------------------------------------------- -// draw_text - simple text renderer -//------------------------------------------------- - -void ui_manager::draw_text(render_container *container, const char *buf, float x, float y) -{ - draw_text_full(container, buf, x, y, 1.0f - x, JUSTIFY_LEFT, WRAP_WORD, DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr); -} - - -//------------------------------------------------- -// draw_text_full - full featured text -// renderer with word wrapping, justification, -// and full size computation -//------------------------------------------------- - -void ui_manager::draw_text_full(render_container *container, const char *origs, float x, float y, float origwrapwidth, int justify, int wrap, int draw, rgb_t fgcolor, rgb_t bgcolor, float *totalwidth, float *totalheight, float text_size) -{ - float lineheight = get_line_height() * text_size; - const char *ends = origs + strlen(origs); - float wrapwidth = origwrapwidth; - const char *s = origs; - const char *linestart; - float cury = y; - float maxwidth = 0; - float aspect = machine().render().ui_aspect(container); - - // if we don't want wrapping, guarantee a huge wrapwidth - if (wrap == WRAP_NEVER) - wrapwidth = 1000000.0f; - if (wrapwidth <= 0) - return; - - // loop over lines - while (*s != 0) - { - const char *lastbreak = nullptr; - int line_justify = justify; - unicode_char schar; - int scharcount; - float lastbreak_width = 0; - float curwidth = 0; - float curx = x; - - // get the current character - scharcount = uchar_from_utf8(&schar, s, ends - s); - if (scharcount == -1) - break; - - // if the line starts with a tab character, center it regardless - if (schar == '\t') - { - s += scharcount; - line_justify = JUSTIFY_CENTER; - } - - // remember the starting position of the line - linestart = s; - - // loop while we have characters and are less than the wrapwidth - while (*s != 0 && curwidth <= wrapwidth) - { - float chwidth; - - // get the current chcaracter - scharcount = uchar_from_utf8(&schar, s, ends - s); - if (scharcount == -1) - break; - - // if we hit a newline, stop immediately - if (schar == '\n') - break; - - // get the width of this character - chwidth = get_font()->char_width(lineheight, aspect, schar); - - // if we hit a space, remember the location and width *without* the space - if (schar == ' ') - { - lastbreak = s; - lastbreak_width = curwidth; - } - - // add the width of this character and advance - curwidth += chwidth; - s += scharcount; - - // if we hit any non-space breakable character, remember the location and width - // *with* the breakable character - if (schar != ' ' && is_breakable_char(schar) && curwidth <= wrapwidth) - { - lastbreak = s; - lastbreak_width = curwidth; - } - } - - // if we accumulated too much for the current width, we need to back off - if (curwidth > wrapwidth) - { - // if we're word wrapping, back up to the last break if we can - if (wrap == WRAP_WORD) - { - // if we hit a break, back up to there with the appropriate width - if (lastbreak != nullptr) - { - s = lastbreak; - curwidth = lastbreak_width; - } - - // if we didn't hit a break, back up one character - else if (s > linestart) - { - // get the previous character - s = (const char *)utf8_previous_char(s); - scharcount = uchar_from_utf8(&schar, s, ends - s); - if (scharcount == -1) - break; - - curwidth -= get_font()->char_width(lineheight, aspect, schar); - // if back to 0, there is no space to draw even a single char - if (curwidth <= 0) - break; - } - } - - // if we're truncating, make sure we have enough space for the ... - else if (wrap == WRAP_TRUNCATE) - { - // add in the width of the ... - curwidth += 3.0f * get_font()->char_width(lineheight, aspect, '.'); - - // while we are above the wrap width, back up one character - while (curwidth > wrapwidth && s > linestart) - { - // get the previous character - s = (const char *)utf8_previous_char(s); - scharcount = uchar_from_utf8(&schar, s, ends - s); - if (scharcount == -1) - break; - - curwidth -= get_font()->char_width(lineheight, aspect, schar); - } - } - } - - // align according to the justfication - if (line_justify == JUSTIFY_CENTER) - curx += (origwrapwidth - curwidth) * 0.5f; - else if (line_justify == JUSTIFY_RIGHT) - curx += origwrapwidth - curwidth; - - // track the maximum width of any given line - if (curwidth > maxwidth) - maxwidth = curwidth; - - // if opaque, add a black box - if (draw == DRAW_OPAQUE) - container->add_rect(curx, cury, curx + curwidth, cury + lineheight, bgcolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); - - // loop from the line start and add the characters - while (linestart < s) - { - // get the current character - unicode_char linechar; - int linecharcount = uchar_from_utf8(&linechar, linestart, ends - linestart); - if (linecharcount == -1) - break; - - if (draw != DRAW_NONE) - { - container->add_char(curx, cury, lineheight, aspect, fgcolor, *get_font(), linechar); - curx += get_font()->char_width(lineheight, aspect, linechar); - } - linestart += linecharcount; - } - - // append ellipses if needed - if (wrap == WRAP_TRUNCATE && *s != 0 && draw != DRAW_NONE) - { - container->add_char(curx, cury, lineheight, aspect, fgcolor, *get_font(), '.'); - curx += get_font()->char_width(lineheight, aspect, '.'); - container->add_char(curx, cury, lineheight, aspect, fgcolor, *get_font(), '.'); - curx += get_font()->char_width(lineheight, aspect, '.'); - container->add_char(curx, cury, lineheight, aspect, fgcolor, *get_font(), '.'); - curx += get_font()->char_width(lineheight, aspect, '.'); - } - - // if we're not word-wrapping, we're done - if (wrap != WRAP_WORD) - break; - - // advance by a row - cury += lineheight; - - // skip past any spaces at the beginning of the next line - scharcount = uchar_from_utf8(&schar, s, ends - s); - if (scharcount == -1) - break; - - if (schar == '\n') - s += scharcount; - else - while (*s && isspace(schar)) - { - s += scharcount; - scharcount = uchar_from_utf8(&schar, s, ends - s); - if (scharcount == -1) - break; - } - } - - // report the width and height of the resulting space - if (totalwidth) - *totalwidth = maxwidth; - if (totalheight) - *totalheight = cury - y; -} - - -//------------------------------------------------- -// draw_text_box - draw a multiline text -// message with a box around it -//------------------------------------------------- - -void ui_manager::draw_text_box(render_container *container, const char *text, int justify, float xpos, float ypos, rgb_t backcolor) -{ - float line_height = get_line_height(); - float max_width = 2.0f * ((xpos <= 0.5f) ? xpos : 1.0f - xpos) - 2.0f * UI_BOX_LR_BORDER; - float target_width = max_width; - float target_height = line_height; - float target_x = 0, target_y = 0; - float last_target_height = 0; - - // limit this iteration to a finite number of passes - for (int pass = 0; pass < 5; pass++) - { - // determine the target location - target_x = xpos - 0.5f * target_width; - target_y = ypos - 0.5f * target_height; - - // make sure we stay on-screen - if (target_x < UI_BOX_LR_BORDER) - target_x = UI_BOX_LR_BORDER; - if (target_x + target_width + UI_BOX_LR_BORDER > 1.0f) - target_x = 1.0f - UI_BOX_LR_BORDER - target_width; - if (target_y < UI_BOX_TB_BORDER) - target_y = UI_BOX_TB_BORDER; - if (target_y + target_height + UI_BOX_TB_BORDER > 1.0f) - target_y = 1.0f - UI_BOX_TB_BORDER - target_height; - - // compute the multi-line target width/height - draw_text_full(container, text, target_x, target_y, target_width + 0.00001f, - justify, WRAP_WORD, DRAW_NONE, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, &target_width, &target_height); - if (target_height > 1.0f - 2.0f * UI_BOX_TB_BORDER) - target_height = floorf((1.0f - 2.0f * UI_BOX_TB_BORDER) / line_height) * line_height; - - // if we match our last value, we're done - if (target_height == last_target_height) - break; - last_target_height = target_height; - } - - // add a box around that - draw_outlined_box(container, target_x - UI_BOX_LR_BORDER, - target_y - UI_BOX_TB_BORDER, - target_x + target_width + UI_BOX_LR_BORDER, - target_y + target_height + UI_BOX_TB_BORDER, backcolor); - draw_text_full(container, text, target_x, target_y, target_width + 0.00001f, - justify, WRAP_WORD, DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr); -} - - -//------------------------------------------------- -// draw_message_window - draw a multiline text -// message with a box around it -//------------------------------------------------- - -void ui_manager::draw_message_window(render_container *container, const char *text) -{ - draw_text_box(container, text, JUSTIFY_LEFT, 0.5f, 0.5f, UI_BACKGROUND_COLOR); -} - - -//------------------------------------------------- -// show_fps_temp - show the FPS counter for -// a specific period of time -//------------------------------------------------- - -void ui_manager::show_fps_temp(double seconds) -{ - if (!m_showfps) - m_showfps_end = osd_ticks() + seconds * osd_ticks_per_second(); -} - - -//------------------------------------------------- -// set_show_fps - show/hide the FPS counter -//------------------------------------------------- - -void ui_manager::set_show_fps(bool show) -{ - m_showfps = show; - if (!show) - { - m_showfps = 0; - m_showfps_end = 0; - } -} - - -//------------------------------------------------- -// show_fps - return the current FPS -// counter visibility state -//------------------------------------------------- - -bool ui_manager::show_fps() const -{ - return m_showfps || (m_showfps_end != 0); -} - - -//------------------------------------------------- -// show_fps_counter -//------------------------------------------------- - -bool ui_manager::show_fps_counter() -{ - bool result = m_showfps || osd_ticks() < m_showfps_end; - if (!result) - m_showfps_end = 0; - return result; -} - - -//------------------------------------------------- -// set_show_profiler - show/hide the profiler -//------------------------------------------------- - -void ui_manager::set_show_profiler(bool show) -{ - m_show_profiler = show; - g_profiler.enable(show); -} - - -//------------------------------------------------- -// show_profiler - return the current -// profiler visibility state -//------------------------------------------------- - -bool ui_manager::show_profiler() const -{ - return m_show_profiler; -} - - -//------------------------------------------------- -// show_menu - show the menus -//------------------------------------------------- - -void ui_manager::show_menu() -{ - set_handler(ui_menu::ui_handler, 0); -} - - -//------------------------------------------------- -// show_mouse - change mouse status -//------------------------------------------------- - -void ui_manager::show_mouse(bool status) -{ - m_mouse_show = status; -} - - -//------------------------------------------------- -// is_menu_active - return true if the menu -// UI handler is active -//------------------------------------------------- - -bool ui_manager::is_menu_active(void) -{ - return (m_handler_callback == ui_menu::ui_handler); -} - - -bool ui_manager::show_timecode_counter() -{ - return m_show_timecode_counter; -} -bool ui_manager::show_timecode_total() -{ - return m_show_timecode_total; -} - - - -/*************************************************************************** - TEXT GENERATORS -***************************************************************************/ - -//------------------------------------------------- -// warnings_string - print the warning flags -// text to the given buffer -//------------------------------------------------- - -std::string &ui_manager::warnings_string(std::string &str) -{ -#define WARNING_FLAGS ( MACHINE_NOT_WORKING | \ - MACHINE_UNEMULATED_PROTECTION | \ - MACHINE_MECHANICAL | \ - MACHINE_WRONG_COLORS | \ - MACHINE_IMPERFECT_COLORS | \ - MACHINE_REQUIRES_ARTWORK | \ - MACHINE_NO_SOUND | \ - MACHINE_IMPERFECT_SOUND | \ - MACHINE_IMPERFECT_GRAPHICS | \ - MACHINE_IMPERFECT_KEYBOARD | \ - MACHINE_NO_COCKTAIL| \ - MACHINE_IS_INCOMPLETE| \ - MACHINE_NO_SOUND_HW ) - - str.clear(); - - // if no warnings, nothing to return - if (machine().rom_load().warnings() == 0 && machine().rom_load().knownbad() == 0 && !(machine().system().flags & WARNING_FLAGS) && machine().rom_load().software_load_warnings_message().length() == 0) - return str; - - // add a warning if any ROMs were loaded with warnings - if (machine().rom_load().warnings() > 0) - { - str.append(_("One or more ROMs/CHDs for this machine are incorrect. The machine may not run correctly.\n")); - if (machine().system().flags & WARNING_FLAGS) - str.append("\n"); - } - - if (machine().rom_load().software_load_warnings_message().length()>0) { - str.append(machine().rom_load().software_load_warnings_message()); - if (machine().system().flags & WARNING_FLAGS) - str.append("\n"); - } - // if we have at least one warning flag, print the general header - if ((machine().system().flags & WARNING_FLAGS) || machine().rom_load().knownbad() > 0) - { - str.append(_("There are known problems with this machine\n\n")); - - // add a warning if any ROMs are flagged BAD_DUMP/NO_DUMP - if (machine().rom_load().knownbad() > 0) { - str.append(_("One or more ROMs/CHDs for this machine have not been correctly dumped.\n")); - } - // add one line per warning flag - if (machine().system().flags & MACHINE_IMPERFECT_KEYBOARD) - str.append(_("The keyboard emulation may not be 100% accurate.\n")); - if (machine().system().flags & MACHINE_IMPERFECT_COLORS) - str.append(_("The colors aren't 100% accurate.\n")); - if (machine().system().flags & MACHINE_WRONG_COLORS) - str.append(_("The colors are completely wrong.\n")); - if (machine().system().flags & MACHINE_IMPERFECT_GRAPHICS) - str.append(_("The video emulation isn't 100% accurate.\n")); - if (machine().system().flags & MACHINE_IMPERFECT_SOUND) - str.append(_("The sound emulation isn't 100% accurate.\n")); - if (machine().system().flags & MACHINE_NO_SOUND) { - str.append(_("The machine lacks sound.\n")); - } - if (machine().system().flags & MACHINE_NO_COCKTAIL) - str.append(_("Screen flipping in cocktail mode is not supported.\n")); - - // check if external artwork is present before displaying this warning? - if (machine().system().flags & MACHINE_REQUIRES_ARTWORK) { - str.append(_("The machine requires external artwork files\n")); - } - - if (machine().system().flags & MACHINE_IS_INCOMPLETE ) - { - str.append(_("This machine was never completed. It may exhibit strange behavior or missing elements that are not bugs in the emulation.\n")); - } - - if (machine().system().flags & MACHINE_NO_SOUND_HW ) - { - str.append(_("This machine has no sound hardware, MAME will produce no sounds, this is expected behaviour.\n")); - } - - // if there's a NOT WORKING, UNEMULATED PROTECTION or GAME MECHANICAL warning, make it stronger - if (machine().system().flags & (MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION | MACHINE_MECHANICAL)) - { - // add the strings for these warnings - if (machine().system().flags & MACHINE_UNEMULATED_PROTECTION) { - str.append(_("The machine has protection which isn't fully emulated.\n")); - } - if (machine().system().flags & MACHINE_NOT_WORKING) { - str.append(_("\nTHIS MACHINE DOESN'T WORK. The emulation for this machine is not yet complete. " - "There is nothing you can do to fix this problem except wait for the developers to improve the emulation.\n")); - } - if (machine().system().flags & MACHINE_MECHANICAL) { - str.append(_("\nCertain elements of this machine cannot be emulated as it requires actual physical interaction or consists of mechanical devices. " - "It is not possible to fully play this machine.\n")); - } - - // find the parent of this driver - driver_enumerator drivlist(machine().options()); - int maindrv = drivlist.find(machine().system()); - int clone_of = drivlist.non_bios_clone(maindrv); - if (clone_of != -1) - maindrv = clone_of; - - // scan the driver list for any working clones and add them - bool foundworking = false; - while (drivlist.next()) - if (drivlist.current() == maindrv || drivlist.clone() == maindrv) - if ((drivlist.driver().flags & (MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION | MACHINE_MECHANICAL)) == 0) - { - // this one works, add a header and display the name of the clone - if (!foundworking) { - str.append(_("\n\nThere are working clones of this machine: ")); - } - else - str.append(", "); - str.append(drivlist.driver().name); - foundworking = true; - } - - if (foundworking) - str.append("\n"); - } - } - - // add the 'press OK' string - str.append(_("\n\nPress any key to continue")); - return str; -} - - -//------------------------------------------------- -// game_info_std::string - populate an allocated -// string with the game info text -//------------------------------------------------- - -std::string &ui_manager::game_info_astring(std::string &str) -{ - std::ostringstream buf; - - // print description, manufacturer, and CPU: - util::stream_format(buf, _("%1$s\n%2$s %3$s\nDriver: %4$s\n\nCPU:\n"), - machine().system().description, - machine().system().year, - machine().system().manufacturer, - core_filename_extract_base(machine().system().source_file)); - - // loop over all CPUs - execute_interface_iterator execiter(machine().root_device()); - std::unordered_set<std::string> exectags; - for (device_execute_interface &exec : execiter) - { - if (!exectags.insert(exec.device().tag()).second) - continue; - // get cpu specific clock that takes internal multiplier/dividers into account - int clock = exec.device().clock(); - - // count how many identical CPUs we have - int count = 1; - const char *name = exec.device().name(); - for (device_execute_interface &scan : execiter) - { - if (exec.device().type() == scan.device().type() && strcmp(name, scan.device().name()) == 0 && exec.device().clock() == scan.device().clock()) - if (exectags.insert(scan.device().tag()).second) - count++; - } - - // if more than one, prepend a #x in front of the CPU name - // display clock in kHz or MHz - util::stream_format(buf, - (count > 1) ? "%1$d" UTF8_MULTIPLY "%2$s %3$d.%4$0*5$d%6$s\n" : "%2$s %3$d.%4$0*5$d%6$s\n", - count, - name, - (clock >= 1000000) ? (clock / 1000000) : (clock / 1000), - (clock >= 1000000) ? (clock % 1000000) : (clock % 1000), - (clock >= 1000000) ? 6 : 3, - (clock >= 1000000) ? _("MHz") : _("kHz")); - } - - // loop over all sound chips - sound_interface_iterator snditer(machine().root_device()); - std::unordered_set<std::string> soundtags; - bool found_sound = false; - for (device_sound_interface &sound : snditer) - { - if (!soundtags.insert(sound.device().tag()).second) - continue; - - // append the Sound: string - if (!found_sound) - buf << _("\nSound:\n"); - found_sound = true; - - // count how many identical sound chips we have - int count = 1; - for (device_sound_interface &scan : snditer) - { - if (sound.device().type() == scan.device().type() && sound.device().clock() == scan.device().clock()) - if (soundtags.insert(scan.device().tag()).second) - count++; - } - - // if more than one, prepend a #x in front of the CPU name - // display clock in kHz or MHz - int clock = sound.device().clock(); - util::stream_format(buf, - (count > 1) - ? ((clock != 0) ? "%1$d" UTF8_MULTIPLY "%2$s %3$d.%4$0*5$d%6$s\n" : "%1$d" UTF8_MULTIPLY "%2$s\n") - : ((clock != 0) ? "%2$s %3$d.%4$0*5$d%6$s\n" : "%2$s\n"), - count, - sound.device().name(), - (clock >= 1000000) ? (clock / 1000000) : (clock / 1000), - (clock >= 1000000) ? (clock % 1000000) : (clock % 1000), - (clock >= 1000000) ? 6 : 3, - (clock >= 1000000) ? _("MHz") : _("kHz")); - } - - // display screen information - buf << _("\nVideo:\n"); - screen_device_iterator scriter(machine().root_device()); - int scrcount = scriter.count(); - if (scrcount == 0) - buf << _("None\n"); - else - { - for (screen_device &screen : scriter) - { - std::string detail; - if (screen.screen_type() == SCREEN_TYPE_VECTOR) - detail = _("Vector"); - else - { - const rectangle &visarea = screen.visible_area(); - detail = string_format("%d " UTF8_MULTIPLY " %d (%s) %f" UTF8_NBSP "Hz", - visarea.width(), visarea.height(), - (machine().system().flags & ORIENTATION_SWAP_XY) ? "V" : "H", - ATTOSECONDS_TO_HZ(screen.frame_period().attoseconds())); - } - - util::stream_format(buf, - (scrcount > 1) ? _("%1$s: %2$s\n") : _("%2$s\n"), - slider_get_screen_desc(screen), detail); - } - } - - return str = buf.str(); -} - - - -/*************************************************************************** - UI HANDLERS -***************************************************************************/ - -//------------------------------------------------- -// handler_messagebox - displays the current -// messagebox_text string but handles no input -//------------------------------------------------- - -UINT32 ui_manager::handler_messagebox(running_machine &machine, render_container *container, UINT32 state) -{ - machine.ui().draw_text_box(container, messagebox_text.c_str(), JUSTIFY_LEFT, 0.5f, 0.5f, messagebox_backcolor); - return 0; -} - - -//------------------------------------------------- -// handler_messagebox_anykey - displays the -// current messagebox_text string and waits for -// any keypress -//------------------------------------------------- - -UINT32 ui_manager::handler_messagebox_anykey(running_machine &machine, render_container *container, UINT32 state) -{ - // draw a standard message window - machine.ui().draw_text_box(container, messagebox_text.c_str(), JUSTIFY_LEFT, 0.5f, 0.5f, messagebox_backcolor); - - // if the user cancels, exit out completely - if (machine.ui_input().pressed(IPT_UI_CANCEL)) - { - machine.schedule_exit(); - state = UI_HANDLER_CANCEL; - } - - // if any key is pressed, just exit - else if (machine.input().poll_switches() != INPUT_CODE_INVALID) - state = UI_HANDLER_CANCEL; - - return state; -} - - -//------------------------------------------------- -// process_natural_keyboard - processes any -// natural keyboard input -//------------------------------------------------- - -void ui_manager::process_natural_keyboard() -{ - ui_event event; - int i, pressed; - input_item_id itemid; - input_code code; - UINT8 *key_down_ptr; - UINT8 key_down_mask; - - // loop while we have interesting events - while (machine().ui_input().pop_event(&event)) - { - // if this was a UI_EVENT_CHAR event, post it - if (event.event_type == UI_EVENT_CHAR) - machine().ioport().natkeyboard().post(event.ch); - } - - // process natural keyboard keys that don't get UI_EVENT_CHARs - for (i = 0; i < ARRAY_LENGTH(non_char_keys); i++) - { - // identify this keycode - itemid = non_char_keys[i]; - code = machine().input().code_from_itemid(itemid); - - // ...and determine if it is pressed - pressed = machine().input().code_pressed(code); - - // figure out whey we are in the key_down map - key_down_ptr = &m_non_char_keys_down[i / 8]; - key_down_mask = 1 << (i % 8); - - if (pressed && !(*key_down_ptr & key_down_mask)) - { - // this key is now down - *key_down_ptr |= key_down_mask; - - // post the key - machine().ioport().natkeyboard().post(UCHAR_MAMEKEY_BEGIN + code.item_id()); - } - else if (!pressed && (*key_down_ptr & key_down_mask)) - { - // this key is now up - *key_down_ptr &= ~key_down_mask; - } - } -} - - -//------------------------------------------------- -// increase_frameskip -//------------------------------------------------- - -void ui_manager::increase_frameskip() -{ - // get the current value and increment it - int newframeskip = machine().video().frameskip() + 1; - if (newframeskip > MAX_FRAMESKIP) - newframeskip = -1; - machine().video().set_frameskip(newframeskip); - - // display the FPS counter for 2 seconds - machine().ui().show_fps_temp(2.0); -} - - -//------------------------------------------------- -// decrease_frameskip -//------------------------------------------------- - -void ui_manager::decrease_frameskip() -{ - // get the current value and decrement it - int newframeskip = machine().video().frameskip() - 1; - if (newframeskip < -1) - newframeskip = MAX_FRAMESKIP; - machine().video().set_frameskip(newframeskip); - - // display the FPS counter for 2 seconds - machine().ui().show_fps_temp(2.0); -} - - -//------------------------------------------------- -// can_paste -//------------------------------------------------- - -bool ui_manager::can_paste() -{ - // retrieve the clipboard text - char *text = osd_get_clipboard_text(); - - // free the string if allocated - if (text != nullptr) - osd_free(text); - - // did we have text? - return text != nullptr; -} - - -//------------------------------------------------- -// paste - does a paste from the keyboard -//------------------------------------------------- - -void ui_manager::paste() -{ - // retrieve the clipboard text - char *text = osd_get_clipboard_text(); - - // was a result returned? - if (text != nullptr) - { - // post the text - machine().ioport().natkeyboard().post_utf8(text); - - // free the string - osd_free(text); - } -} - - -//------------------------------------------------- -// image_handler_ingame - execute display -// callback function for each image device -//------------------------------------------------- - -void ui_manager::image_handler_ingame() -{ - // run display routine for devices - if (machine().phase() == MACHINE_PHASE_RUNNING) - for (device_image_interface &image : image_interface_iterator(machine().root_device())) - image.call_display(); -} - - -//------------------------------------------------- -// handler_ingame - in-game handler takes care -// of the standard keypresses -//------------------------------------------------- - -UINT32 ui_manager::handler_ingame(running_machine &machine, render_container *container, UINT32 state) -{ - bool is_paused = machine.paused(); - - // first draw the FPS counter - if (machine.ui().show_fps_counter()) - { - machine.ui().draw_text_full(container, machine.video().speed_text().c_str(), 0.0f, 0.0f, 1.0f, - JUSTIFY_RIGHT, WRAP_WORD, DRAW_OPAQUE, ARGB_WHITE, ARGB_BLACK, nullptr, nullptr); - } - - // Show the duration of current part (intro or gameplay or extra) - if (machine.ui().show_timecode_counter()) { - std::string tempstring; - machine.ui().draw_text_full(container, machine.video().timecode_text(tempstring).c_str(), 0.0f, 0.0f, 1.0f, - JUSTIFY_RIGHT, WRAP_WORD, DRAW_OPAQUE, rgb_t(0xf0,0xf0,0x10,0x10), ARGB_BLACK, NULL, NULL); - } - // Show the total time elapsed for the video preview (all parts intro, gameplay, extras) - if (machine.ui().show_timecode_total()) { - std::string tempstring; - machine.ui().draw_text_full(container, machine.video().timecode_total_text(tempstring).c_str(), 0.0f, 0.0f, 1.0f, - JUSTIFY_LEFT, WRAP_WORD, DRAW_OPAQUE, rgb_t(0xf0,0x10,0xf0,0x10), ARGB_BLACK, NULL, NULL); - } - - - // draw the profiler if visible - if (machine.ui().show_profiler()) - { - const char *text = g_profiler.text(machine); - machine.ui().draw_text_full(container, text, 0.0f, 0.0f, 1.0f, JUSTIFY_LEFT, WRAP_WORD, DRAW_OPAQUE, ARGB_WHITE, ARGB_BLACK, nullptr, nullptr); - } - - // if we're single-stepping, pause now - if (machine.ui().single_step()) - { - machine.pause(); - machine.ui().set_single_step(false); - } - - // determine if we should disable the rest of the UI - bool ui_disabled = (machine.ioport().has_keyboard() && !machine.ui_active()); - - // is ScrLk UI toggling applicable here? - if (machine.ioport().has_keyboard()) - { - // are we toggling the UI with ScrLk? - if (machine.ui_input().pressed(IPT_UI_TOGGLE_UI)) - { - // toggle the UI - machine.set_ui_active(!machine.ui_active()); - - // display a popup indicating the new status - if (machine.ui_active()) - { - machine.ui().popup_time(2, "%s\n%s\n%s\n%s\n%s\n%s\n", - _("Keyboard Emulation Status"), - "-------------------------", - _("Mode: PARTIAL Emulation"), - _("UI: Enabled"), - "-------------------------", - _("**Use ScrLock to toggle**")); - } - else - { - machine.ui().popup_time(2, "%s\n%s\n%s\n%s\n%s\n%s\n", - _("Keyboard Emulation Status"), - "-------------------------", - _("Mode: FULL Emulation"), - _("UI: Disabled"), - "-------------------------", - _("**Use ScrLock to toggle**")); - } - } - } - - // is the natural keyboard enabled? - if (machine.ui().use_natural_keyboard() && (machine.phase() == MACHINE_PHASE_RUNNING)) - machine.ui().process_natural_keyboard(); - - if (!ui_disabled) - { - // paste command - if (machine.ui_input().pressed(IPT_UI_PASTE)) - machine.ui().paste(); - } - - machine.ui().image_handler_ingame(); - - // handle a save input timecode request - if (machine.ui_input().pressed(IPT_UI_TIMECODE)) - machine.video().save_input_timecode(); - - if (ui_disabled) return ui_disabled; - - if (machine.ui_input().pressed(IPT_UI_CANCEL)) - { - machine.ui().request_quit(); - return 0; - } - - // turn on menus if requested - if (machine.ui_input().pressed(IPT_UI_CONFIGURE)) - return machine.ui().set_handler(ui_menu::ui_handler, 0); - - // if the on-screen display isn't up and the user has toggled it, turn it on - if ((machine.debug_flags & DEBUG_FLAG_ENABLED) == 0 && machine.ui_input().pressed(IPT_UI_ON_SCREEN_DISPLAY)) - return machine.ui().set_handler(ui_menu_sliders::ui_handler, 1); - - // handle a reset request - if (machine.ui_input().pressed(IPT_UI_RESET_MACHINE)) - machine.schedule_hard_reset(); - if (machine.ui_input().pressed(IPT_UI_SOFT_RESET)) - machine.schedule_soft_reset(); - - // handle a request to display graphics/palette - if (machine.ui_input().pressed(IPT_UI_SHOW_GFX)) - { - if (!is_paused) - machine.pause(); - return machine.ui().set_handler(ui_gfx_ui_handler, is_paused); - } - - // handle a tape control key - if (machine.ui_input().pressed(IPT_UI_TAPE_START)) - { - for (cassette_image_device &cass : cassette_device_iterator(machine.root_device())) - { - cass.change_state(CASSETTE_PLAY, CASSETTE_MASK_UISTATE); - return 0; - } - } - if (machine.ui_input().pressed(IPT_UI_TAPE_STOP)) - { - for (cassette_image_device &cass : cassette_device_iterator(machine.root_device())) - { - cass.change_state(CASSETTE_STOPPED, CASSETTE_MASK_UISTATE); - return 0; - } - } - - // handle a save state request - if (machine.ui_input().pressed(IPT_UI_SAVE_STATE)) - { - machine.pause(); - machine.ui().m_load_save_hold = true; - return machine.ui().set_handler(handler_load_save, LOADSAVE_SAVE); - } - - // handle a load state request - if (machine.ui_input().pressed(IPT_UI_LOAD_STATE)) - { - machine.pause(); - machine.ui().m_load_save_hold = true; - return machine.ui().set_handler(handler_load_save, LOADSAVE_LOAD); - } - - // handle a save snapshot request - if (machine.ui_input().pressed(IPT_UI_SNAPSHOT)) - machine.video().save_active_screen_snapshots(); - - // toggle pause - if (machine.ui_input().pressed(IPT_UI_PAUSE)) - machine.toggle_pause(); - - // pause single step - if (machine.ui_input().pressed(IPT_UI_PAUSE_SINGLE)) - { - machine.ui().set_single_step(true); - machine.resume(); - } - - // handle a toggle cheats request - if (machine.ui_input().pressed(IPT_UI_TOGGLE_CHEAT)) - machine.cheat().set_enable(!machine.cheat().enabled()); - - // toggle movie recording - if (machine.ui_input().pressed(IPT_UI_RECORD_MOVIE)) - machine.video().toggle_record_movie(); - - // toggle profiler display - if (machine.ui_input().pressed(IPT_UI_SHOW_PROFILER)) - machine.ui().set_show_profiler(!machine.ui().show_profiler()); - - // toggle FPS display - if (machine.ui_input().pressed(IPT_UI_SHOW_FPS)) - machine.ui().set_show_fps(!machine.ui().show_fps()); - - // increment frameskip? - if (machine.ui_input().pressed(IPT_UI_FRAMESKIP_INC)) - machine.ui().increase_frameskip(); - - // decrement frameskip? - if (machine.ui_input().pressed(IPT_UI_FRAMESKIP_DEC)) - machine.ui().decrease_frameskip(); - - // toggle throttle? - if (machine.ui_input().pressed(IPT_UI_THROTTLE)) - machine.video().toggle_throttle(); - - // toggle autofire - if (machine.ui_input().pressed(IPT_UI_TOGGLE_AUTOFIRE)) - { - if (!machine.options().cheat()) - { - machine.popmessage(_("Autofire can't be enabled")); - } - else - { - bool autofire_toggle = machine.ioport().get_autofire_toggle(); - machine.ioport().set_autofire_toggle(!autofire_toggle); - machine.popmessage("Autofire %s", autofire_toggle ? _("Enabled") : _("Disabled")); - } - } - - // check for fast forward - if (machine.ioport().type_pressed(IPT_UI_FAST_FORWARD)) - { - machine.video().set_fastforward(true); - machine.ui().show_fps_temp(0.5); - } - else - machine.video().set_fastforward(false); - - return 0; -} - - -//------------------------------------------------- -// handler_load_save - leads the user through -// specifying a game to save or load -//------------------------------------------------- - -UINT32 ui_manager::handler_load_save(running_machine &machine, render_container *container, UINT32 state) -{ - char filename[20]; - char file = 0; - - // if we're not in the middle of anything, skip - if (state == LOADSAVE_NONE) - return 0; - - // okay, we're waiting for a key to select a slot; display a message - if (state == LOADSAVE_SAVE) - machine.ui().draw_message_window(container, _("Select position to save to")); - else - machine.ui().draw_message_window(container, _("Select position to load from")); - - // if load/save state sequence is still being pressed, do not read the filename yet - if (machine.ui().m_load_save_hold) { - bool seq_in_progress = false; - const input_seq &load_save_seq = state == LOADSAVE_SAVE ? - machine.ioport().type_seq(IPT_UI_SAVE_STATE) : - machine.ioport().type_seq(IPT_UI_LOAD_STATE); - - for (int i = 0; i < load_save_seq.length(); i++) - if (machine.input().code_pressed_once(load_save_seq[i])) - seq_in_progress = true; - - if (seq_in_progress) - return state; - else - machine.ui().m_load_save_hold = false; - } - - // check for cancel key - if (machine.ui_input().pressed(IPT_UI_CANCEL)) - { - // display a popup indicating things were cancelled - if (state == LOADSAVE_SAVE) - machine.popmessage(_("Save cancelled")); - else - machine.popmessage(_("Load cancelled")); - - // reset the state - machine.resume(); - return UI_HANDLER_CANCEL; - } - - // check for A-Z or 0-9 - for (input_item_id id = ITEM_ID_A; id <= ITEM_ID_Z; ++id) - if (machine.input().code_pressed_once(input_code(DEVICE_CLASS_KEYBOARD, 0, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, id))) - file = id - ITEM_ID_A + 'a'; - if (file == 0) - for (input_item_id id = ITEM_ID_0; id <= ITEM_ID_9; ++id) - if (machine.input().code_pressed_once(input_code(DEVICE_CLASS_KEYBOARD, 0, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, id))) - file = id - ITEM_ID_0 + '0'; - if (file == 0) - for (input_item_id id = ITEM_ID_0_PAD; id <= ITEM_ID_9_PAD; ++id) - if (machine.input().code_pressed_once(input_code(DEVICE_CLASS_KEYBOARD, 0, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, id))) - file = id - ITEM_ID_0_PAD + '0'; - if (file == 0) - { - bool found = false; - - for (int joy_index = 0; joy_index <= MAX_SAVED_STATE_JOYSTICK; joy_index++) - for (input_item_id id = ITEM_ID_BUTTON1; id <= ITEM_ID_BUTTON32; ++id) - if (machine.input().code_pressed_once(input_code(DEVICE_CLASS_JOYSTICK, joy_index, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, id))) - { - snprintf(filename, sizeof(filename), "joy%i-%i", joy_index, id - ITEM_ID_BUTTON1 + 1); - found = true; - break; - } - - if (!found) - return state; - } - else - { - sprintf(filename, "%c", file); - } - - // display a popup indicating that the save will proceed - if (state == LOADSAVE_SAVE) - { - machine.popmessage(_("Save to position %s"), filename); - machine.schedule_save(filename); - } - else - { - machine.popmessage(_("Load from position %s"), filename); - machine.schedule_load(filename); - } - - // avoid handling the name of the save state slot as a seperate input - machine.ui_input().mark_all_as_pressed(); - - // remove the pause and reset the state - machine.resume(); - return UI_HANDLER_CANCEL; -} - - -//------------------------------------------------- -// request_quit -//------------------------------------------------- - -void ui_manager::request_quit() -{ - if (!machine().options().confirm_quit()) - machine().schedule_exit(); - else - set_handler(handler_confirm_quit, 0); -} - - -//------------------------------------------------- -// handler_confirm_quit - leads the user through -// confirming quit emulation -//------------------------------------------------- - -UINT32 ui_manager::handler_confirm_quit(running_machine &machine, render_container *container, UINT32 state) -{ - // get the text for 'UI Select' - std::string ui_select_text = machine.input().seq_name(machine.ioport().type_seq(IPT_UI_SELECT, 0, SEQ_TYPE_STANDARD)); - - // get the text for 'UI Cancel' - std::string ui_cancel_text = machine.input().seq_name(machine.ioport().type_seq(IPT_UI_CANCEL, 0, SEQ_TYPE_STANDARD)); - - // assemble the quit message - std::string quit_message = string_format(_("Are you sure you want to quit?\n\n" - "Press ''%1$s'' to quit,\n" - "Press ''%2$s'' to return to emulation."), - ui_select_text, - ui_cancel_text); - - machine.ui().draw_text_box(container, quit_message.c_str(), JUSTIFY_CENTER, 0.5f, 0.5f, UI_RED_COLOR); - machine.pause(); - - // if the user press ENTER, quit the game - if (machine.ui_input().pressed(IPT_UI_SELECT)) - machine.schedule_exit(); - - // if the user press ESC, just continue - else if (machine.ui_input().pressed(IPT_UI_CANCEL)) - { - machine.resume(); - state = UI_HANDLER_CANCEL; - } - - return state; -} - - -/*************************************************************************** - SLIDER CONTROLS -***************************************************************************/ - -//------------------------------------------------- -// ui_get_slider_list - get the list of sliders -//------------------------------------------------- - -std::vector<ui_menu_item>& ui_manager::get_slider_list(void) -{ - return slider_list; -} - - -//------------------------------------------------- -// slider_alloc - allocate a new slider entry -//------------------------------------------------- - -static slider_state *slider_alloc(running_machine &machine, const char *title, INT32 minval, INT32 defval, INT32 maxval, INT32 incval, slider_update update, void *arg) -{ - int size = sizeof(slider_state) + strlen(title); - slider_state *state = (slider_state *)auto_alloc_array_clear(machine, UINT8, size); - - state->minval = minval; - state->defval = defval; - state->maxval = maxval; - state->incval = incval; - state->update = update; - state->arg = arg; - state->id = -1; - strcpy(state->description, title); - - return state; -} - - -//---------------------------------------------------------- -// ui_manager::slider_init - initialize the list of slider -// controls -//---------------------------------------------------------- - -std::vector<ui_menu_item> ui_manager::slider_init(running_machine &machine) -{ - std::vector<slider_state *> sliders; - - // add overall volume - sliders.push_back(slider_alloc(machine, _("Master Volume"), -32, 0, 0, 1, slider_volume, nullptr)); - - // add per-channel volume - mixer_input info; - for (int item = 0; machine.sound().indexed_mixer_input(item, info); item++) - { - INT32 maxval = 2000; - INT32 defval = 1000; - - std::string str = string_format(_("%1$s Volume"), info.stream->input_name(info.inputnum)); - sliders.push_back(slider_alloc(machine, str.c_str(), 0, defval, maxval, 20, slider_mixervol, (void *)(FPTR)item)); - } - - // add analog adjusters - for (ioport_port &port : machine.ioport().ports()) - { - for (ioport_field &field : port.fields()) - { - if (field.type() == IPT_ADJUSTER) - { - sliders.push_back(slider_alloc(machine, field.name(), field.minval(), field.defvalue(), field.maxval(), 1, slider_adjuster, (void *)&field)); - } - } - } - - // add CPU overclocking (cheat only) - if (machine.options().cheat()) - { - for (device_execute_interface &exec : execute_interface_iterator(machine.root_device())) - { - void *param = (void *)&exec.device(); - std::string str = string_format(_("Overclock CPU %1$s"), exec.device().tag()); - sliders.push_back(slider_alloc(machine, str.c_str(), 10, 1000, 2000, 1, slider_overclock, param)); - } - } - - // add screen parameters - screen_device_iterator scriter(machine.root_device()); - for (screen_device &screen : scriter) - { - int defxscale = floor(screen.xscale() * 1000.0f + 0.5f); - int defyscale = floor(screen.yscale() * 1000.0f + 0.5f); - int defxoffset = floor(screen.xoffset() * 1000.0f + 0.5f); - int defyoffset = floor(screen.yoffset() * 1000.0f + 0.5f); - void *param = (void *)&screen; - std::string screen_desc = slider_get_screen_desc(screen); - - // add refresh rate tweaker - if (machine.options().cheat()) - { - std::string str = string_format(_("%1$s Refresh Rate"), screen_desc); - sliders.push_back(slider_alloc(machine, str.c_str(), -10000, 0, 10000, 1000, slider_refresh, param)); - } - - // add standard brightness/contrast/gamma controls per-screen - std::string str = string_format(_("%1$s Brightness"), screen_desc); - sliders.push_back(slider_alloc(machine, str.c_str(), 100, 1000, 2000, 10, slider_brightness, param)); - str = string_format(_("%1$s Contrast"), screen_desc); - sliders.push_back(slider_alloc(machine, str.c_str(), 100, 1000, 2000, 50, slider_contrast, param)); - str = string_format(_("%1$s Gamma"), screen_desc); - sliders.push_back(slider_alloc(machine, str.c_str(), 100, 1000, 3000, 50, slider_gamma, param)); - - // add scale and offset controls per-screen - str = string_format(_("%1$s Horiz Stretch"), screen_desc); - sliders.push_back(slider_alloc(machine, str.c_str(), 500, defxscale, 1500, 2, slider_xscale, param)); - str = string_format(_("%1$s Horiz Position"), screen_desc); - sliders.push_back(slider_alloc(machine, str.c_str(), -500, defxoffset, 500, 2, slider_xoffset, param)); - str = string_format(_("%1$s Vert Stretch"), screen_desc); - sliders.push_back(slider_alloc(machine, str.c_str(), 500, defyscale, 1500, 2, slider_yscale, param)); - str = string_format(_("%1$s Vert Position"), screen_desc); - sliders.push_back(slider_alloc(machine, str.c_str(), -500, defyoffset, 500, 2, slider_yoffset, param)); - } - - for (laserdisc_device &laserdisc : laserdisc_device_iterator(machine.root_device())) - { - if (laserdisc.overlay_configured()) - { - laserdisc_overlay_config config; - laserdisc.get_overlay_config(config); - int defxscale = floor(config.m_overscalex * 1000.0f + 0.5f); - int defyscale = floor(config.m_overscaley * 1000.0f + 0.5f); - int defxoffset = floor(config.m_overposx * 1000.0f + 0.5f); - int defyoffset = floor(config.m_overposy * 1000.0f + 0.5f); - void *param = (void *)&laserdisc; - - // add scale and offset controls per-overlay - std::string str = string_format(_("Laserdisc '%1$s' Horiz Stretch"), laserdisc.tag()); - sliders.push_back(slider_alloc(machine, str.c_str(), 500, (defxscale == 0) ? 1000 : defxscale, 1500, 2, slider_overxscale, param)); - str = string_format(_("Laserdisc '%1$s' Horiz Position"), laserdisc.tag()); - sliders.push_back(slider_alloc(machine, str.c_str(), -500, defxoffset, 500, 2, slider_overxoffset, param)); - str = string_format(_("Laserdisc '%1$s' Vert Stretch"), laserdisc.tag()); - sliders.push_back(slider_alloc(machine, str.c_str(), 500, (defyscale == 0) ? 1000 : defyscale, 1500, 2, slider_overyscale, param)); - str = string_format(_("Laserdisc '%1$s' Vert Position"), laserdisc.tag()); - sliders.push_back(slider_alloc(machine, str.c_str(), -500, defyoffset, 500, 2, slider_overyoffset, param)); - } - } - - for (screen_device &screen : scriter) - { - if (screen.screen_type() == SCREEN_TYPE_VECTOR) - { - // add vector control - sliders.push_back(slider_alloc(machine, _("Vector Flicker"), 0, 0, 1000, 10, slider_flicker, nullptr)); - sliders.push_back(slider_alloc(machine, _("Beam Width Minimum"), 1, 100, 1000, 1, slider_beam_width_min, nullptr)); - sliders.push_back(slider_alloc(machine, _("Beam Width Maximum"), 1, 100, 1000, 1, slider_beam_width_max, nullptr)); - sliders.push_back(slider_alloc(machine, _("Beam Intensity Weight"), -1000, 0, 1000, 10, slider_beam_intensity_weight, nullptr)); - break; - } - } - -#ifdef MAME_DEBUG - // add crosshair adjusters - for (ioport_port &port : machine.ioport().ports()) - { - for (ioport_field &field : port.fields()) - { - if (field.crosshair_axis() != CROSSHAIR_AXIS_NONE && field.player() == 0) - { - std::string str = string_format(_("Crosshair Scale %1$s"), (field.crosshair_axis() == CROSSHAIR_AXIS_X) ? _("X") : _("Y")); - sliders.push_back(slider_alloc(machine, str.c_str(), -3000, 1000, 3000, 100, slider_crossscale, (void *)&field)); - str = string_format(_("Crosshair Offset %1$s"), (field.crosshair_axis() == CROSSHAIR_AXIS_X) ? _("X") : _("Y")); - sliders.push_back(slider_alloc(machine, str.c_str(), -3000, 0, 3000, 100, slider_crossoffset, (void *)&field)); - } - } - } -#endif - - std::vector<ui_menu_item> items; - for (slider_state *slider : sliders) - { - ui_menu_item item; - item.text = slider->description; - item.subtext = ""; - item.flags = 0; - item.ref = slider; - item.type = ui_menu_item_type::SLIDER; - items.push_back(item); - } - - return items; -} - - -//------------------------------------------------- -// slider_volume - global volume slider callback -//------------------------------------------------- - -static INT32 slider_volume(running_machine &machine, void *arg, int id, std::string *str, INT32 newval) -{ - if (newval != SLIDER_NOCHANGE) - machine.sound().set_attenuation(newval); - if (str) - *str = string_format(_("%1$3ddB"), machine.sound().attenuation()); - return machine.sound().attenuation(); -} - - -//------------------------------------------------- -// slider_mixervol - single channel volume -// slider callback -//------------------------------------------------- - -static INT32 slider_mixervol(running_machine &machine, void *arg, int id, std::string *str, INT32 newval) -{ - mixer_input info; - if (!machine.sound().indexed_mixer_input((FPTR)arg, info)) - return 0; - if (newval != SLIDER_NOCHANGE) - { - INT32 curval = floor(info.stream->user_gain(info.inputnum) * 1000.0f + 0.5f); - if (newval > curval && (newval - curval) <= 4) newval += 4; // round up on increment - info.stream->set_user_gain(info.inputnum, (float)newval * 0.001f); - } - if (str) - *str = string_format("%4.2f", info.stream->user_gain(info.inputnum)); - return floorf(info.stream->user_gain(info.inputnum) * 1000.0f + 0.5f); -} - - -//------------------------------------------------- -// slider_adjuster - analog adjuster slider -// callback -//------------------------------------------------- - -static INT32 slider_adjuster(running_machine &machine, void *arg, int id, std::string *str, INT32 newval) -{ - ioport_field *field = (ioport_field *)arg; - ioport_field::user_settings settings; - - field->get_user_settings(settings); - if (newval != SLIDER_NOCHANGE) - { - settings.value = newval; - field->set_user_settings(settings); - } - if (str) - *str = string_format(_("%1$d%%"), settings.value); - return settings.value; -} - - -//------------------------------------------------- -// slider_overclock - CPU overclocker slider -// callback -//------------------------------------------------- - -static INT32 slider_overclock(running_machine &machine, void *arg, int id, std::string *str, INT32 newval) -{ - device_t *cpu = (device_t *)arg; - if (newval != SLIDER_NOCHANGE) - cpu->set_clock_scale((float)newval * 0.001f); - if (str) - *str = string_format(_("%1$3.0f%%"), floor(cpu->clock_scale() * 100.0 + 0.5)); - return floor(cpu->clock_scale() * 1000.0 + 0.5); -} - - -//------------------------------------------------- -// slider_refresh - refresh rate slider callback -//------------------------------------------------- - -static INT32 slider_refresh(running_machine &machine, void *arg, int id, std::string *str, INT32 newval) -{ - screen_device *screen = reinterpret_cast<screen_device *>(arg); - double defrefresh = ATTOSECONDS_TO_HZ(screen->refresh_attoseconds()); - double refresh; - - if (newval != SLIDER_NOCHANGE) - { - int width = screen->width(); - int height = screen->height(); - const rectangle &visarea = screen->visible_area(); - screen->configure(width, height, visarea, HZ_TO_ATTOSECONDS(defrefresh + (double)newval * 0.001)); - } - if (str) - *str = string_format(_("%1$.3ffps"), ATTOSECONDS_TO_HZ(machine.first_screen()->frame_period().attoseconds())); - refresh = ATTOSECONDS_TO_HZ(machine.first_screen()->frame_period().attoseconds()); - return floor((refresh - defrefresh) * 1000.0 + 0.5); -} - - -//------------------------------------------------- -// slider_brightness - screen brightness slider -// callback -//------------------------------------------------- - -static INT32 slider_brightness(running_machine &machine, void *arg, int id, std::string *str, INT32 newval) -{ - screen_device *screen = reinterpret_cast<screen_device *>(arg); - render_container::user_settings settings; - - screen->container().get_user_settings(settings); - if (newval != SLIDER_NOCHANGE) - { - settings.m_brightness = (float)newval * 0.001f; - screen->container().set_user_settings(settings); - } - if (str) - *str = string_format(_("%1$.3f"), settings.m_brightness); - return floor(settings.m_brightness * 1000.0f + 0.5f); -} - - -//------------------------------------------------- -// slider_contrast - screen contrast slider -// callback -//------------------------------------------------- - -static INT32 slider_contrast(running_machine &machine, void *arg, int id, std::string *str, INT32 newval) -{ - screen_device *screen = reinterpret_cast<screen_device *>(arg); - render_container::user_settings settings; - - screen->container().get_user_settings(settings); - if (newval != SLIDER_NOCHANGE) - { - settings.m_contrast = (float)newval * 0.001f; - screen->container().set_user_settings(settings); - } - if (str) - *str = string_format(_("%1$.3f"), settings.m_contrast); - return floor(settings.m_contrast * 1000.0f + 0.5f); -} - - -//------------------------------------------------- -// slider_gamma - screen gamma slider callback -//------------------------------------------------- - -static INT32 slider_gamma(running_machine &machine, void *arg, int id, std::string *str, INT32 newval) -{ - screen_device *screen = reinterpret_cast<screen_device *>(arg); - render_container::user_settings settings; - - screen->container().get_user_settings(settings); - if (newval != SLIDER_NOCHANGE) - { - settings.m_gamma = (float)newval * 0.001f; - screen->container().set_user_settings(settings); - } - if (str) - *str = string_format(_("%1$.3f"), settings.m_gamma); - return floor(settings.m_gamma * 1000.0f + 0.5f); -} - - -//------------------------------------------------- -// slider_xscale - screen horizontal scale slider -// callback -//------------------------------------------------- - -static INT32 slider_xscale(running_machine &machine, void *arg, int id, std::string *str, INT32 newval) -{ - screen_device *screen = reinterpret_cast<screen_device *>(arg); - render_container::user_settings settings; - - screen->container().get_user_settings(settings); - if (newval != SLIDER_NOCHANGE) - { - settings.m_xscale = (float)newval * 0.001f; - screen->container().set_user_settings(settings); - } - if (str) - *str = string_format(_("%1$.3f"), settings.m_xscale); - return floor(settings.m_xscale * 1000.0f + 0.5f); -} - - -//------------------------------------------------- -// slider_yscale - screen vertical scale slider -// callback -//------------------------------------------------- - -static INT32 slider_yscale(running_machine &machine, void *arg, int id, std::string *str, INT32 newval) -{ - screen_device *screen = reinterpret_cast<screen_device *>(arg); - render_container::user_settings settings; - - screen->container().get_user_settings(settings); - if (newval != SLIDER_NOCHANGE) - { - settings.m_yscale = (float)newval * 0.001f; - screen->container().set_user_settings(settings); - } - if (str) - *str = string_format(_("%1$.3f"), settings.m_yscale); - return floor(settings.m_yscale * 1000.0f + 0.5f); -} - - -//------------------------------------------------- -// slider_xoffset - screen horizontal position -// slider callback -//------------------------------------------------- - -static INT32 slider_xoffset(running_machine &machine, void *arg, int id, std::string *str, INT32 newval) -{ - screen_device *screen = reinterpret_cast<screen_device *>(arg); - render_container::user_settings settings; - - screen->container().get_user_settings(settings); - if (newval != SLIDER_NOCHANGE) - { - settings.m_xoffset = (float)newval * 0.001f; - screen->container().set_user_settings(settings); - } - if (str) - *str = string_format(_("%1$.3f"), settings.m_xoffset); - return floor(settings.m_xoffset * 1000.0f + 0.5f); -} - - -//------------------------------------------------- -// slider_yoffset - screen vertical position -// slider callback -//------------------------------------------------- - -static INT32 slider_yoffset(running_machine &machine, void *arg, int id, std::string *str, INT32 newval) -{ - screen_device *screen = reinterpret_cast<screen_device *>(arg); - render_container::user_settings settings; - - screen->container().get_user_settings(settings); - if (newval != SLIDER_NOCHANGE) - { - settings.m_yoffset = (float)newval * 0.001f; - screen->container().set_user_settings(settings); - } - if (str) - *str = string_format(_("%1$.3f"), settings.m_yoffset); - return floor(settings.m_yoffset * 1000.0f + 0.5f); -} - - -//------------------------------------------------- -// slider_overxscale - screen horizontal scale slider -// callback -//------------------------------------------------- - -static INT32 slider_overxscale(running_machine &machine, void *arg, int id, std::string *str, INT32 newval) -{ - laserdisc_device *laserdisc = (laserdisc_device *)arg; - laserdisc_overlay_config settings; - - laserdisc->get_overlay_config(settings); - if (newval != SLIDER_NOCHANGE) - { - settings.m_overscalex = (float)newval * 0.001f; - laserdisc->set_overlay_config(settings); - } - if (str) - *str = string_format(_("%1$.3f"), settings.m_overscalex); - return floor(settings.m_overscalex * 1000.0f + 0.5f); -} - - -//------------------------------------------------- -// slider_overyscale - screen vertical scale slider -// callback -//------------------------------------------------- - -static INT32 slider_overyscale(running_machine &machine, void *arg, int id, std::string *str, INT32 newval) -{ - laserdisc_device *laserdisc = (laserdisc_device *)arg; - laserdisc_overlay_config settings; - - laserdisc->get_overlay_config(settings); - if (newval != SLIDER_NOCHANGE) - { - settings.m_overscaley = (float)newval * 0.001f; - laserdisc->set_overlay_config(settings); - } - if (str) - *str = string_format(_("%1$.3f"), settings.m_overscaley); - return floor(settings.m_overscaley * 1000.0f + 0.5f); -} - - -//------------------------------------------------- -// slider_overxoffset - screen horizontal position -// slider callback -//------------------------------------------------- - -static INT32 slider_overxoffset(running_machine &machine, void *arg, int id, std::string *str, INT32 newval) -{ - laserdisc_device *laserdisc = (laserdisc_device *)arg; - laserdisc_overlay_config settings; - - laserdisc->get_overlay_config(settings); - if (newval != SLIDER_NOCHANGE) - { - settings.m_overposx = (float)newval * 0.001f; - laserdisc->set_overlay_config(settings); - } - if (str) - *str = string_format(_("%1$.3f"), settings.m_overposx); - return floor(settings.m_overposx * 1000.0f + 0.5f); -} - - -//------------------------------------------------- -// slider_overyoffset - screen vertical position -// slider callback -//------------------------------------------------- - -static INT32 slider_overyoffset(running_machine &machine, void *arg, int id, std::string *str, INT32 newval) -{ - laserdisc_device *laserdisc = (laserdisc_device *)arg; - laserdisc_overlay_config settings; - - laserdisc->get_overlay_config(settings); - if (newval != SLIDER_NOCHANGE) - { - settings.m_overposy = (float)newval * 0.001f; - laserdisc->set_overlay_config(settings); - } - if (str) - *str = string_format(_("%1$.3f"), settings.m_overposy); - return floor(settings.m_overposy * 1000.0f + 0.5f); -} - - -//------------------------------------------------- -// slider_flicker - vector flicker slider -// callback -//------------------------------------------------- - -static INT32 slider_flicker(running_machine &machine, void *arg, int id, std::string *str, INT32 newval) -{ - if (newval != SLIDER_NOCHANGE) - vector_options::s_flicker = (float)newval * 0.001f; - if (str) - *str = string_format(_("%1$1.2f"), vector_options::s_flicker); - return floor(vector_options::s_flicker * 1000.0f + 0.5f); -} - - -//------------------------------------------------- -// slider_beam_width_min - minimum vector beam width slider -// callback -//------------------------------------------------- - -static INT32 slider_beam_width_min(running_machine &machine, void *arg, int id, std::string *str, INT32 newval) -{ - if (newval != SLIDER_NOCHANGE) - vector_options::s_beam_width_min = MIN((float)newval * 0.01f, vector_options::s_beam_width_max); - if (str != nullptr) - *str = string_format(_("%1$1.2f"), vector_options::s_beam_width_min); - return floor(vector_options::s_beam_width_min * 100.0f + 0.5f); -} - - -//------------------------------------------------- -// slider_beam_width_max - maximum vector beam width slider -// callback -//------------------------------------------------- - -static INT32 slider_beam_width_max(running_machine &machine, void *arg, int id, std::string *str, INT32 newval) -{ - if (newval != SLIDER_NOCHANGE) - vector_options::s_beam_width_max = MAX((float)newval * 0.01f, vector_options::s_beam_width_min); - if (str != nullptr) - *str = string_format(_("%1$1.2f"), vector_options::s_beam_width_max); - return floor(vector_options::s_beam_width_max * 100.0f + 0.5f); -} - - -//------------------------------------------------- -// slider_beam_intensity_weight - vector beam intensity weight slider -// callback -//------------------------------------------------- - -static INT32 slider_beam_intensity_weight(running_machine &machine, void *arg, int id, std::string *str, INT32 newval) -{ - if (newval != SLIDER_NOCHANGE) - vector_options::s_beam_intensity_weight = (float)newval * 0.001f; - if (str != nullptr) - *str = string_format(_("%1$1.2f"), vector_options::s_beam_intensity_weight); - return floor(vector_options::s_beam_intensity_weight * 1000.0f + 0.5f); -} - - -//------------------------------------------------- -// slider_get_screen_desc - returns the -// description for a given screen -//------------------------------------------------- - -static std::string slider_get_screen_desc(screen_device &screen) -{ - if (screen_device_iterator(screen.machine().root_device()).count() > 1) - return string_format(_("Screen '%1$s'"), screen.tag()); - else - return _("Screen"); -} - -//------------------------------------------------- -// slider_crossscale - crosshair scale slider -// callback -//------------------------------------------------- - -#ifdef MAME_DEBUG -static INT32 slider_crossscale(running_machine &machine, void *arg, int id, std::string *str, INT32 newval) -{ - ioport_field *field = (ioport_field *)arg; - - if (newval != SLIDER_NOCHANGE) - field->set_crosshair_scale(float(newval) * 0.001); - if (str) - *str = string_format((field->crosshair_axis() == CROSSHAIR_AXIS_X) ? _("Crosshair Scale X %1$1.3f") : _("Crosshair Scale Y %1$1.3f"), float(newval) * 0.001f); - return floor(field->crosshair_scale() * 1000.0f + 0.5f); -} -#endif - - -//------------------------------------------------- -// slider_crossoffset - crosshair scale slider -// callback -//------------------------------------------------- - -#ifdef MAME_DEBUG -static INT32 slider_crossoffset(running_machine &machine, void *arg, int id, std::string *str, INT32 newval) -{ - ioport_field *field = (ioport_field *)arg; - - if (newval != SLIDER_NOCHANGE) - field->set_crosshair_offset(float(newval) * 0.001f); - if (str) - *str = string_format((field->crosshair_axis() == CROSSHAIR_AXIS_X) ? _("Crosshair Offset X %1$1.3f") : _("Crosshair Offset Y %1$1.3f"), float(newval) * 0.001f); - return field->crosshair_offset(); -} -#endif - - -//------------------------------------------------- -// use_natural_keyboard - returns -// whether the natural keyboard is active -//------------------------------------------------- - -bool ui_manager::use_natural_keyboard() const -{ - return m_use_natural_keyboard; -} - - -//------------------------------------------------- -// set_use_natural_keyboard - specifies -// whether the natural keyboard is active -//------------------------------------------------- - -void ui_manager::set_use_natural_keyboard(bool use_natural_keyboard) -{ - m_use_natural_keyboard = use_natural_keyboard; - std::string error; - machine().options().set_value(OPTION_NATURAL_KEYBOARD, use_natural_keyboard, OPTION_PRIORITY_CMDLINE, error); - assert(error.empty()); -} - -//------------------------------------------------- -// wrap_text -//------------------------------------------------- - -int ui_manager::wrap_text(render_container *container, const char *origs, float x, float y, float origwrapwidth, std::vector<int> &xstart, std::vector<int> &xend, float text_size) -{ - float lineheight = get_line_height() * text_size; - const char *ends = origs + strlen(origs); - float wrapwidth = origwrapwidth; - const char *s = origs; - const char *linestart; - float maxwidth = 0; - float aspect = machine().render().ui_aspect(container); - int count = 0; - - // loop over lines - while (*s != 0) - { - const char *lastbreak = nullptr; - unicode_char schar; - int scharcount; - float lastbreak_width = 0; - float curwidth = 0; - - // get the current character - scharcount = uchar_from_utf8(&schar, s, ends - s); - if (scharcount == -1) - break; - - // remember the starting position of the line - linestart = s; - - // loop while we have characters and are less than the wrapwidth - while (*s != 0 && curwidth <= wrapwidth) - { - float chwidth; - - // get the current chcaracter - scharcount = uchar_from_utf8(&schar, s, ends - s); - if (scharcount == -1) - break; - - // if we hit a newline, stop immediately - if (schar == '\n') - break; - - // get the width of this character - chwidth = get_font()->char_width(lineheight, aspect, schar); - - // if we hit a space, remember the location and width *without* the space - if (schar == ' ') - { - lastbreak = s; - lastbreak_width = curwidth; - } - - // add the width of this character and advance - curwidth += chwidth; - s += scharcount; - - // if we hit any non-space breakable character, remember the location and width - // *with* the breakable character - if (schar != ' ' && is_breakable_char(schar) && curwidth <= wrapwidth) - { - lastbreak = s; - lastbreak_width = curwidth; - } - } - - // if we accumulated too much for the current width, we need to back off - if (curwidth > wrapwidth) - { - // if we hit a break, back up to there with the appropriate width - if (lastbreak != nullptr) - { - s = lastbreak; - curwidth = lastbreak_width; - } - - // if we didn't hit a break, back up one character - else if (s > linestart) - { - // get the previous character - s = (const char *)utf8_previous_char(s); - scharcount = uchar_from_utf8(&schar, s, ends - s); - if (scharcount == -1) - break; - - curwidth -= get_font()->char_width(lineheight, aspect, schar); - } - } - - // track the maximum width of any given line - if (curwidth > maxwidth) - maxwidth = curwidth; - - xstart.push_back(linestart - origs); - xend.push_back(s - origs); - - // loop from the line start and add the characters - while (linestart < s) - { - // get the current character - unicode_char linechar; - int linecharcount = uchar_from_utf8(&linechar, linestart, ends - linestart); - if (linecharcount == -1) - break; - linestart += linecharcount; - } - - // advance by a row - count++; - - // skip past any spaces at the beginning of the next line - scharcount = uchar_from_utf8(&schar, s, ends - s); - if (scharcount == -1) - break; - - if (schar == '\n') - s += scharcount; - else - while (*s && isspace(schar)) - { - s += scharcount; - scharcount = uchar_from_utf8(&schar, s, ends - s); - if (scharcount == -1) - break; - } - } - return count; -} - -//------------------------------------------------- -// draw_textured_box - add primitives to -// draw an outlined box with the given -// textured background and line color -//------------------------------------------------- - -void ui_manager::draw_textured_box(render_container *container, float x0, float y0, float x1, float y1, rgb_t backcolor, rgb_t linecolor, render_texture *texture, UINT32 flags) -{ - container->add_quad(x0, y0, x1, y1, backcolor, texture, flags); - container->add_line(x0, y0, x1, y0, UI_LINE_WIDTH, linecolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); - container->add_line(x1, y0, x1, y1, UI_LINE_WIDTH, linecolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); - container->add_line(x1, y1, x0, y1, UI_LINE_WIDTH, linecolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); - container->add_line(x0, y1, x0, y0, UI_LINE_WIDTH, linecolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); -} - -//------------------------------------------------- -// decode UI color options -//------------------------------------------------- - -rgb_t decode_ui_color(int id, running_machine *machine) -{ - static rgb_t color[ARRAY_LENGTH(s_color_list)]; - - if (machine != nullptr) { - ui_options option; - for (int x = 0; x < ARRAY_LENGTH(s_color_list); ++x) { - const char *o_default = option.value(s_color_list[x]); - const char *s_option = machine->ui().options().value(s_color_list[x]); - int len = strlen(s_option); - if (len != 8) - color[x] = rgb_t((UINT32)strtoul(o_default, nullptr, 16)); - else - color[x] = rgb_t((UINT32)strtoul(s_option, nullptr, 16)); - } - } - return color[id]; -} - -//------------------------------------------------- -// get font rows from options -//------------------------------------------------- - -int get_font_rows(running_machine *machine) -{ - static int value; - - return ((machine != nullptr) ? value = machine->ui().options().font_rows() : value); -} |