summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/ui/emenubar.c
diff options
context:
space:
mode:
author Nathan Woods <npwoods@mess.org>2014-04-12 20:52:03 +0000
committer Nathan Woods <npwoods@mess.org>2014-04-12 20:52:03 +0000
commit24026e123e547b8e7c59d67f95c32f4679aebb96 (patch)
tree5826d69d5bba9901c372a4e6eb977cdc3e2f6691 /src/emu/ui/emenubar.c
parentd46cefb7910ff6f1a363395a7e954e0a6bca8227 (diff)
Merge of new menubar code
Diffstat (limited to 'src/emu/ui/emenubar.c')
-rw-r--r--src/emu/ui/emenubar.c648
1 files changed, 648 insertions, 0 deletions
diff --git a/src/emu/ui/emenubar.c b/src/emu/ui/emenubar.c
new file mode 100644
index 00000000000..a2fb6c944ef
--- /dev/null
+++ b/src/emu/ui/emenubar.c
@@ -0,0 +1,648 @@
+/***************************************************************************
+
+ emenubar.c
+
+ Internal MAME menu bar for the user interface.
+
+ Copyright Nicola Salmoria and the MAME Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+***************************************************************************/
+
+#include "emu.h"
+#include "ui/emenubar.h"
+#include "ui/selgame.h"
+#include "ui/miscmenu.h"
+#include "ui/filesel.h"
+#include "ui/imginfo.h"
+#include "ui/tapectrl.h"
+#include "ui/bbcontrl.h"
+#include "ui/swlist.h"
+#include "ui/viewgfx.h"
+#include "ui/barcode.h"
+#include "softlist.h"
+#include "cheat.h"
+
+
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
+
+#ifdef MAME_PROFILER
+#define HAS_PROFILER 1
+#else // !MAME_PROFILER
+#define HAS_PROFILER 0
+#endif // MAME_PROFILER
+
+
+//**************************************************************************
+// MENUBAR IMPLEMENTATION
+//**************************************************************************
+
+astring ui_emu_menubar::s_softlist_result;
+device_image_interface *ui_emu_menubar::s_softlist_image;
+
+
+//-------------------------------------------------
+// ctor
+//-------------------------------------------------
+
+ui_emu_menubar::ui_emu_menubar(running_machine &machine)
+ : ui_menubar(machine)
+{
+}
+
+
+//-------------------------------------------------
+// handle
+//-------------------------------------------------
+
+void ui_emu_menubar::handle(render_container *container)
+{
+ // check to see if we have a softlist selection
+ if (s_softlist_result.len() > 0)
+ {
+ // do the load
+ s_softlist_image->load(s_softlist_result);
+
+ // clear out state
+ s_softlist_image = NULL;
+ s_softlist_result.reset();
+ }
+
+ // call inherited method
+ ui_menubar::handle(container);
+}
+
+
+//-------------------------------------------------
+// start_menu
+//-------------------------------------------------
+
+void ui_emu_menubar::start_menu(ui_menu *menu)
+{
+ machine().ui().set_handler(ui_menu::ui_handler, 0);
+ ui_menu::stack_push(menu);
+}
+
+
+//-------------------------------------------------
+// start_menu
+//-------------------------------------------------
+
+template<class _Menu>
+void ui_emu_menubar::start_menu()
+{
+ start_menu(auto_alloc_clear(machine(), _Menu(machine(), container())));
+}
+
+
+//-------------------------------------------------
+// menubar_draw_ui_elements
+//-------------------------------------------------
+
+void ui_emu_menubar::menubar_draw_ui_elements()
+{
+ // first draw the FPS counter
+ if (machine().ui().show_fps_counter())
+ {
+ astring tempstring;
+ machine().ui().draw_text_full(container(), machine().video().speed_text(tempstring), 0.0f, 0.0f, 1.0f,
+ JUSTIFY_RIGHT, WRAP_WORD, DRAW_OPAQUE, ARGB_WHITE, 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, NULL, NULL);
+ }
+
+ // 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);
+
+}
+
+
+//-------------------------------------------------
+// menubar_build_menus
+//-------------------------------------------------
+
+void ui_emu_menubar::menubar_build_menus()
+{
+ // build normal menus
+ build_file_menu();
+ if (has_images())
+ build_images_menu();
+ build_options_menu();
+ build_settings_menu();
+ build_help_menu();
+
+ // and customize them
+ machine().osd().customize_menubar(*this);
+}
+
+
+//-------------------------------------------------
+// build_file_menu
+//-------------------------------------------------
+
+void ui_emu_menubar::build_file_menu()
+{
+ astring menu_text;
+ menu_item &file_menu = root_menu().append("File");
+
+ // show gfx
+ if (ui_gfx_is_relevant(machine()))
+ file_menu.append("Show Graphics/Palette...", &ui_emu_menubar::set_ui_handler, *this, ui_gfx_ui_handler, (UINT32) machine().paused(), IPT_UI_SHOW_GFX);
+
+ // save screen snapshot
+ file_menu.append("Save Screen Snapshot(s)", &video_manager::save_active_screen_snapshots, machine().video(), IPT_UI_SNAPSHOT);
+
+ // record movie
+ menu_item &record_movie_menu = file_menu.append("Record Movie", &video_manager::toggle_record_movie, machine().video(), IPT_UI_RECORD_MOVIE);
+ record_movie_menu.set_checked(machine().video().is_recording());
+
+ // save state
+ file_menu.append("Save State...", &ui_emu_menubar::set_ui_handler, *this, ui_manager::ui_handler_load_save, (UINT32) LOADSAVE_SAVE, IPT_UI_SAVE_STATE);
+
+ // load state
+ file_menu.append("Load State...", &ui_emu_menubar::set_ui_handler, *this, ui_manager::ui_handler_load_save, (UINT32) LOADSAVE_LOAD, IPT_UI_LOAD_STATE);
+
+ // separator
+ file_menu.append_separator();
+
+ // paste
+ if (machine().ioport().has_keyboard() && machine().ioport().natkeyboard().can_post())
+ {
+ menu_item &paste_menu = file_menu.append("Paste", &ui_manager::paste, machine().ui(), IPT_UI_PASTE);
+ paste_menu.set_enabled(machine().ui().can_paste());
+ }
+
+ // pause
+ menu_item &pause_menu = file_menu.append("Pause", &running_machine::toggle_pause, machine(), IPT_UI_PAUSE);
+ pause_menu.set_checked(machine().paused());
+
+ // reset
+ menu_item &reset_menu = file_menu.append("Reset");
+ reset_menu.append("Hard", &running_machine::schedule_hard_reset, machine(), IPT_UI_RESET_MACHINE);
+ reset_menu.append("Soft", &running_machine::schedule_soft_reset, machine(), IPT_UI_SOFT_RESET);
+
+ // separator
+ file_menu.append_separator();
+
+ // select new game
+ menu_text.printf("Select New %s...", emulator_info::get_capstartgamenoun());
+ file_menu.append(menu_text, &ui_emu_menubar::select_new_game, *this);
+
+ // exit
+ file_menu.append("Exit", &ui_manager::request_quit, machine().ui(), IPT_UI_EXIT);
+}
+
+
+//-------------------------------------------------
+// build_images_menu
+//-------------------------------------------------
+
+void ui_emu_menubar::build_images_menu()
+{
+ // add the root "Images" menu
+ menu_item &images_menu = root_menu().append("Images");
+
+ // loop through all devices
+ image_interface_iterator iter(machine().root_device());
+ for (device_image_interface *image = iter.first(); image != NULL; image = iter.next())
+ {
+ bool is_loaded = image->basename() != NULL;
+
+ astring buffer;
+ buffer.printf("%s (%s): \t%s",
+ image->device().name(),
+ image->brief_instance_name(),
+ is_loaded ? image->basename() : "[empty]");
+
+ // append the menu item for this device
+ menu_item &menu = images_menu.append(buffer);
+
+ // software list
+ if (image->image_interface() != NULL)
+ {
+ if (build_software_list_menus(menu, image))
+ menu.append_separator();
+ }
+
+ // load
+ menu.append("Load...", &ui_emu_menubar::load, *this, image);
+
+ // unload
+ menu_item &unload_menu = menu.append("Unload", &device_image_interface::unload, *image);
+ unload_menu.set_enabled(is_loaded);
+
+ // tape control
+ cassette_image_device *cassette = dynamic_cast<cassette_image_device *>(image);
+ if (cassette != NULL)
+ {
+ menu_item &control_menu = menu.append("Tape Control...", &ui_emu_menubar::tape_control, *this, cassette);
+ control_menu.set_enabled(is_loaded);
+ }
+
+ // bitbanger control
+ bitbanger_device *bitbanger = dynamic_cast<bitbanger_device *>(image);
+ if (bitbanger != NULL)
+ {
+ menu_item &control_menu = menu.append("Bitbanger Control...", &ui_emu_menubar::bitbanger_control, *this, bitbanger);
+ control_menu.set_enabled(is_loaded);
+ }
+ }
+}
+
+
+//-------------------------------------------------
+// build_software_list_menus
+//-------------------------------------------------
+
+bool ui_emu_menubar::build_software_list_menus(menu_item &menu, device_image_interface *image)
+{
+ int item_count = 0;
+ menu_item *last_menu_item = NULL;
+ astring description;
+ softlist_type types[] = { SOFTWARE_LIST_ORIGINAL_SYSTEM, SOFTWARE_LIST_COMPATIBLE_SYSTEM };
+ software_list_device_iterator softlist_iter(machine().config().root_device());
+
+ // first do "original system" softlists, then do compatible ones
+ for (int typenum = 0; typenum < ARRAY_LENGTH(types); typenum++)
+ {
+ for (software_list_device *swlist = softlist_iter.first(); swlist != NULL; swlist = softlist_iter.next())
+ {
+ if ((swlist->list_type() == types[typenum]) && is_softlist_relevant(swlist, image->image_interface(), description))
+ {
+ // we've found a softlist; append the menu item
+ last_menu_item = &menu.append(description, &ui_emu_menubar::select_from_software_list, *this, image, swlist);
+ item_count++;
+ }
+ }
+ }
+
+ // if we only had one list, lets use a generic name
+ if (last_menu_item != NULL && (item_count == 1))
+ last_menu_item->set_text("Software list...");
+
+ return item_count > 0;
+}
+
+
+//-------------------------------------------------
+// build_options_menu
+//-------------------------------------------------
+
+void ui_emu_menubar::build_options_menu()
+{
+ astring menu_text;
+ menu_item &options_menu = root_menu().append("Options");
+
+ // throttle
+ float throttle_rates[] = { 10.0f, 5.0f, 2.0f, 1.0f, 0.5f, 0.2f, 0.1f, 0.0f };
+ float current_throttle_rate = machine().video().throttled()
+ ? machine().video().throttle_rate()
+ : 0.0f;
+ menu_item &throttle_menu = options_menu.append("Throttle");
+ for (int i = 0; i < ARRAY_LENGTH(throttle_rates); i++)
+ {
+ const char *item = "Unthrottled";
+ if (throttle_rates[i] != 0)
+ {
+ menu_text.printf("%d%%", (int) (throttle_rates[i] * 100));
+ item = menu_text;
+ }
+
+ menu_item &menu = throttle_menu.append(item, &ui_emu_menubar::set_throttle_rate, *this, throttle_rates[i]);
+ menu.set_checked(current_throttle_rate == throttle_rates[i]);
+ }
+
+ // frame skip
+ menu_item &frameskip_menu = options_menu.append("Frame Skip");
+ for (int i = -1; i <= MAX_FRAMESKIP; i++)
+ {
+ const char *item = "Auto";
+ if (i >= 0)
+ {
+ menu_text.printf("%d", i);
+ item = menu_text;
+ }
+
+ menu_item &menu = frameskip_menu.append(item, &video_manager::set_frameskip, machine().video(), i);
+ menu.set_checked(machine().video().frameskip() == i);
+ }
+
+ // separator
+ frameskip_menu.append_separator();
+
+ // increase
+ frameskip_menu.append("Increase", &ui_manager::increase_frameskip, machine().ui(), IPT_UI_FRAMESKIP_INC);
+
+ // decrease
+ frameskip_menu.append("Decrease", &ui_manager::decrease_frameskip, machine().ui(), IPT_UI_FRAMESKIP_DEC);
+
+ // show fps
+ options_menu.append("Show Frames Per Second", &ui_manager::set_show_fps, &ui_manager::show_fps, machine().ui(), IPT_UI_SHOW_FPS);
+
+ // show profiler
+ if (HAS_PROFILER)
+ options_menu.append("Show Profiler", &ui_manager::set_show_profiler, &ui_manager::show_profiler, machine().ui(), IPT_UI_SHOW_PROFILER);
+
+ // video
+ // do different things if we actually have multiple render targets
+ menu_item &video_menu = options_menu.append("Video");
+ if (machine().render().target_by_index(1) != NULL)
+ {
+ // multiple targets
+ int targetnum = 0;
+ render_target *target;
+ while((target = machine().render().target_by_index(targetnum)) != NULL)
+ {
+ astring buffer;
+ buffer.printf("Screen #%d", targetnum++);
+ menu_item &target_menu = options_menu.append(buffer);
+ build_video_target_menu(target_menu, *target);
+ }
+ }
+ else
+ {
+ // single target
+ build_video_target_menu(video_menu, *machine().render().first_target());
+ }
+
+ // separator
+ options_menu.append_separator();
+
+ // slot devices
+ slot_interface_iterator slotiter(machine().root_device());
+ if (slotiter.first() != NULL)
+ options_menu.append<ui_emu_menubar>("Slot Devices...", &ui_emu_menubar::start_menu<ui_menu_slot_devices>, *this);
+
+ // barcode reader
+ barcode_reader_device_iterator bcriter(machine().root_device());
+ if (bcriter.first() != NULL)
+ options_menu.append<ui_emu_menubar>("Barcode Reader...", &ui_emu_menubar::start_menu<ui_menu_barcode_reader>, *this);
+
+ // network devices
+ network_interface_iterator netiter(machine().root_device());
+ if (netiter.first() != NULL)
+ options_menu.append<ui_emu_menubar>("Network Devices...", &ui_emu_menubar::start_menu<ui_menu_network_devices>, *this);
+
+ // keyboard
+ if (machine().ioport().has_keyboard() && machine().ioport().natkeyboard().can_post())
+ {
+ menu_item &keyboard_menu = options_menu.append("Keyboard");
+ keyboard_menu.append("Emulated", &ui_manager::set_use_natural_keyboard, &ui_manager::use_natural_keyboard, machine().ui(), false);
+ keyboard_menu.append("Natural", &ui_manager::set_use_natural_keyboard, &ui_manager::use_natural_keyboard, machine().ui(), true);
+ }
+
+ // crosshair options
+ if (crosshair_get_usage(machine()))
+ options_menu.append<ui_emu_menubar>("Crosshair Options...", &ui_emu_menubar::start_menu<ui_menu_crosshair>, *this);
+
+ // memory card
+ if (machine().config().m_memcard_handler != NULL)
+ options_menu.append<ui_emu_menubar>("Memory Card...", &ui_emu_menubar::start_menu<ui_menu_memory_card>, *this);
+
+ // cheat
+ if (machine().options().cheat() && machine().cheat().first() != NULL)
+ {
+ options_menu.append_separator();
+ options_menu.append("Cheats enabled", &cheat_manager::set_enable, &cheat_manager::enabled, machine().cheat(), IPT_UI_TOGGLE_CHEAT);
+ options_menu.append<ui_emu_menubar>("Cheat...", &ui_emu_menubar::start_menu<ui_menu_cheat>, *this);
+ }
+}
+
+
+//-------------------------------------------------
+// build_video_target_menu
+//-------------------------------------------------
+
+void ui_emu_menubar::build_video_target_menu(menu_item &target_menu, render_target &target)
+{
+ astring tempstring;
+ const char *view_name;
+
+ // add the menu items for each view
+ for(int viewnum = 0; (view_name = target.view_name(viewnum)) != NULL; viewnum++)
+ {
+ // replace spaces with underscores
+ tempstring.cpy(view_name).replace(0, "_", " ");
+
+ // append the menu
+ target_menu.append(tempstring, &render_target::set_view, &render_target::view, target, viewnum);
+ }
+
+ // separator
+ target_menu.append_separator();
+
+ // rotation
+ menu_item &rotation_menu = target_menu.append("Rotation");
+ rotation_menu.append("None", &render_target::set_orientation, &render_target::orientation, target, ROT0);
+ rotation_menu.append("Clockwise 90", &render_target::set_orientation, &render_target::orientation, target, ROT90);
+ rotation_menu.append("180", &render_target::set_orientation, &render_target::orientation, target, ROT180);
+ rotation_menu.append("Counterclockwise 90", &render_target::set_orientation, &render_target::orientation, target, ROT270);
+
+ // show backdrops
+ target_menu.append("Show Backdrops", &render_target::set_backdrops_enabled, &render_target::backdrops_enabled, target);
+
+ // show overlay
+ target_menu.append("Show Overlays", &render_target::set_overlays_enabled, &render_target::overlays_enabled, target);
+
+ // show bezel
+ target_menu.append("Show Bezels", &render_target::set_bezels_enabled, &render_target::bezels_enabled, target);
+
+ // show cpanel
+ target_menu.append("Show CPanels", &render_target::set_cpanels_enabled, &render_target::cpanels_enabled, target);
+
+ // show marquee
+ target_menu.append("Show Marquees", &render_target::set_marquees_enabled, &render_target::marquees_enabled, target);
+
+ // view
+ menu_item &view_menu = target_menu.append("View");
+ view_menu.append("Cropped", &render_target::set_zoom_to_screen, &render_target::zoom_to_screen, target, true);
+ view_menu.append("Full", &render_target::set_zoom_to_screen, &render_target::zoom_to_screen, target, false);
+}
+
+
+//-------------------------------------------------
+// build_settings_menu
+//-------------------------------------------------
+
+void ui_emu_menubar::build_settings_menu()
+{
+ astring menu_text;
+ menu_item &settings_menu = root_menu().append("Settings");
+
+ // general input
+ // TODO - BREAK THIS APART?
+ settings_menu.append<ui_emu_menubar>("General Input...", &ui_emu_menubar::start_menu<ui_menu_input_groups>, *this);
+
+ // game input
+ menu_text.printf("%s Input...", emulator_info::get_capstartgamenoun());
+ settings_menu.append<ui_emu_menubar>(menu_text, &ui_emu_menubar::start_menu<ui_menu_input_specific>, *this);
+
+ // analog controls
+ if (machine().ioport().has_analog())
+ settings_menu.append<ui_emu_menubar>("Analog Controls...", &ui_emu_menubar::start_menu<ui_menu_analog>, *this);
+
+ // dip switches
+ if (machine().ioport().has_dips())
+ settings_menu.append<ui_emu_menubar>("Dip Switches...", &ui_emu_menubar::start_menu<ui_menu_settings_dip_switches>, *this);
+
+ // driver configuration
+ if (machine().ioport().has_configs())
+ {
+ menu_text.printf("%s Configuration...", emulator_info::get_capstartgamenoun());
+ settings_menu.append<ui_emu_menubar>(menu_text, &ui_emu_menubar::start_menu<ui_menu_settings_driver_config>, *this);
+ }
+
+ // bios selection
+ if (machine().ioport().has_bioses())
+ settings_menu.append<ui_emu_menubar>("Bios Selection...", &ui_emu_menubar::start_menu<ui_menu_bios_selection>, *this);
+
+ // sliders
+ settings_menu.append<ui_emu_menubar>("Sliders...", &ui_emu_menubar::start_menu<ui_menu_sliders>, *this, IPT_UI_ON_SCREEN_DISPLAY);
+}
+
+
+//-------------------------------------------------
+// build_help_menu
+//-------------------------------------------------
+
+void ui_emu_menubar::build_help_menu()
+{
+ astring menu_text;
+ menu_item &help_menu = root_menu().append("Help");
+
+ // bookkeeping info
+ help_menu.append<ui_emu_menubar>("Bookkeeping info...", &ui_emu_menubar::start_menu<ui_menu_bookkeeping>, *this);
+
+ // game info
+ menu_text.printf("%s Information...", emulator_info::get_capstartgamenoun());
+ help_menu.append<ui_emu_menubar>(menu_text, &ui_emu_menubar::start_menu<ui_menu_game_info>, *this);
+
+ // image information
+ image_interface_iterator imgiter(machine().root_device());
+ if (imgiter.first() != NULL)
+ help_menu.append<ui_emu_menubar>("Image Information...", &ui_emu_menubar::start_menu<ui_menu_image_info>, *this);
+}
+
+
+//-------------------------------------------------
+// is_softlist_relevant
+//-------------------------------------------------
+
+bool ui_emu_menubar::is_softlist_relevant(software_list_device *swlist, const char *interface, astring &list_description)
+{
+ bool result = false;
+
+ for (software_info *swinfo = swlist->first_software_info(); swinfo != NULL; swinfo = swinfo->next())
+ {
+ software_part *part = swinfo->find_part(NULL, NULL);
+ if (part->matches_interface(interface))
+ {
+ list_description.printf("%s...", swlist->description());
+ result = true;
+ break;
+ }
+ }
+
+ return result;
+}
+
+
+//-------------------------------------------------
+// set_ui_handler
+//-------------------------------------------------
+
+void ui_emu_menubar::set_ui_handler(ui_callback callback, UINT32 param)
+{
+ // first pause
+ machine().pause();
+
+ // and transfer control
+ machine().ui().set_handler(callback, param);
+}
+
+
+//-------------------------------------------------
+// select_new_game
+//-------------------------------------------------
+
+void ui_emu_menubar::select_new_game()
+{
+ start_menu(auto_alloc_clear(machine(), ui_menu_select_game(machine(), container(), machine().system().name)));
+}
+
+
+//-------------------------------------------------
+// select_from_software_list
+//-------------------------------------------------
+
+void ui_emu_menubar::select_from_software_list(device_image_interface *image, software_list_device *swlist)
+{
+ s_softlist_image = image;
+ start_menu(auto_alloc_clear(machine(), ui_menu_software_list(machine(), container(), swlist, image->image_interface(), s_softlist_result)));
+}
+
+
+//-------------------------------------------------
+// tape_control
+//-------------------------------------------------
+
+void ui_emu_menubar::tape_control(cassette_image_device *image)
+{
+ start_menu(auto_alloc_clear(machine(), ui_menu_mess_tape_control(machine(), container(), image)));
+}
+
+
+//-------------------------------------------------
+// bitbanger_control
+//-------------------------------------------------
+
+void ui_emu_menubar::bitbanger_control(bitbanger_device *image)
+{
+ start_menu(auto_alloc_clear(machine(), ui_menu_mess_bitbanger_control(machine(), container(), image)));
+}
+
+
+//-------------------------------------------------
+// load
+//-------------------------------------------------
+
+void ui_emu_menubar::load(device_image_interface *image)
+{
+ start_menu(image->get_selection_menu(machine(), container()));
+}
+
+
+//-------------------------------------------------
+// has_images
+//-------------------------------------------------
+
+bool ui_emu_menubar::has_images()
+{
+ image_interface_iterator iter(machine().root_device());
+ return iter.first() != NULL;
+}
+
+
+//-------------------------------------------------
+// set_throttle_rate
+//-------------------------------------------------
+
+void ui_emu_menubar::set_throttle_rate(float throttle_rate)
+{
+ machine().video().set_throttled(throttle_rate != 0.0);
+ if (throttle_rate != 0.0)
+ machine().video().set_throttle_rate(throttle_rate);
+}