Main Restorations Software Audio/Jukebox/MP3 Everything Else Buy/Sell/Trade
Project Announcements Monitor/Video GroovyMAME Merit/JVL Touchscreen Meet Up Retail Vendors
Driving & Racing Woodworking Software Support Forums Consoles Project Arcade Reviews
Automated Projects Artwork Frontend Support Forums Pinball Forum Discussion Old Boards
Raspberry Pi & Dev Board controls.dat Linux Miscellaneous Arcade Wiki Discussion Old Archives
Lightguns Arcade1Up Try the site in https mode Site News

Unread posts | New Replies | Recent posts | Rules | Chatroom | Wiki | File Repository | RSS | Submit news

  

Author Topic: Solved - Need diff to disable load state messages  (Read 14208 times)

0 Members and 1 Guest are viewing this topic.

rCadeGaming

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 1256
  • Last login:April 13, 2025, 12:14:40 pm
  • Just call me Rob!
Solved - Need diff to disable load state messages
« on: October 17, 2011, 11:37:24 pm »
Edit: This has been solved.  Scroll down for solution.

Full disclosure: I originally asked this on the MameWorld forums and was referred here.  Not much to see, but that thread can be found here:
http://www.mameworld.info/ubbthreads/showflat.php?Cat=&Number=266435&page=&view=expanded&sb=5&o=&fpart=&vc=1#Post266435

Hi everyone, I've been slowly working out the details for my MAME cabinet and I've thought of a feature that I think some people might find interesting.

In most fighting games it can be a pain in the butt to select a difficulty level. You can usually choose from 8, but it would be nice to be able to let friends playing your cabinet do so without giving them access to the service menu.

Another problem is setting up a two-player match. After one person wins, the loser can put another coin in for a rematch, but only the loser has a choice to change characters.

These problems also apply to some puzzle games, and other games as well.

My solution is to have nine small buttons across the top of the control panel. The buttons are physically mapped to the 0 through 8 keys on a keyboard encoder. In MAME, 0 through 8 are all mapped to load state.

1.sta is a save state where the difficulty is set to 1.
2.sta is a save state where the difficulty is set to 2, etc.

I think you can see where I'm going with this.

0.sta is a save state where both players are ready choose a character on the character select screen.

As you can see, when you are playing you can simply double tap 1 through 8 to reset the game on a different difficulty, or 0 to start a two-player match.

I already have this working perfectly, the one problem is that during the process the messages "Select position to load from" and "State successfully loaded. Warning: save states are not officially supported for this game" are displayed. In this application, these messages look awful and don't make any sense to the end user on a cabinet.

So, to get to my point (finally), I'm wondering if there would be anyone willing to write a .diff that would disable these two particular messages from displaying? I can't do this myself as I have no knowledge of programming in MAME, but I could pay someone some cash through PayPal if need be.

The .diff would have to be compatible with hiscore.diff. I don't mean that I need high scores to be carried over after a load state, I realize that constantly loading state will constantly reset the high scores. This is not a problem. I'll just have to make a decision for each game whether I'd like to use save states or enable high score saving; it's usually not much of a conflict. Games which could use my load state feature (like Street Fighter II) are usually oriented around defeating the computer player or having repeated two-player matches; whereas games that are oriented around getting a high score (like Ms. Pac-Man or Donkey Kong) generally have no need for my load state feature. Anyway, what I need to say is that I will still need the nag-screen and loading-screen removing feaures of hiscore.diff in every game, but high score saving is only needed in games which won't use save states.

It would be optimal to make the buttons load state with one press, instead of double tapping. It could also be neat if the messages were loaded from a .txt file. That way they could be changed to say something more appropriate, or simply left blank to hide them. These would be added bonuses, but I think simply disabling those two messages would be fairly adequate.

Please let me know if anyone is willing to do any of this. Also let me know if there are any other places I should be asking.

Thank you.
« Last Edit: October 19, 2011, 05:39:47 pm by rCadeGaming »

syph007

  • Trade Count: (+2)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 598
  • Last login:June 24, 2014, 04:30:03 pm
  • With a router big enough, we can shape the world!
Re: Need diff to disable load state messages
« Reply #1 on: October 18, 2011, 06:07:11 pm »
I've done exactly what you are asking.  Look in ui.c. Its quite obvious where the message dialogs are.  Just delete those lines and build.


Edit:  Look for the method handler_load_save.

It will look like this in the code:

static UINT32 handler_load_save(running_machine &machine, render_container *container, UINT32 state)

Delete all of this:

    /* okay, we're waiting for a key to select a slot; display a message */
     if (state == LOADSAVE_SAVE)
        ui_draw_message_window(container, "Select position to save to");
     else
        ui_draw_message_window(container, "Select position to load from");

And all the lines that say popmessage, such as

   popmessage("Save to position %c", file);

And that should solve your issue.
« Last Edit: October 18, 2011, 06:28:48 pm by syph007 »

rCadeGaming

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 1256
  • Last login:April 13, 2025, 12:14:40 pm
  • Just call me Rob!
Re: Need diff to disable load state messages
« Reply #2 on: October 19, 2011, 05:30:00 pm »
Thanks, this was the breakthrough I needed.  I had already looked at ui.c, but was searching for the "save states are not officially supported..." message.  This got me on track, then I found that message in machine.c.  Also, I realized that the modifications have to be written differently in different versions, so there's not much advantage in a writing a .diff for each version over modifying each version manually.  That is unless it becomes a popular feature and needs to be distributed easily, but I don't see that happening any time soon, considering how much of a niche application this is.  Anyway, I'll post the solution here for anyone who finds this in the future:


- Solution -

See original post for the purpose of this modification.  The solution is to modify some of the source files found in src/emu.  These files are written in C, I was able to open them in MS Visual Studio and Notepad.  Note that this solution is for version 143 (current at time of writing), and may need to be adapted slightly for different versions.  machine.c does not exist before version 138u3, corresponding sections shown from machine.c can be found in mame.c in some earlier versions.

To remove saving or loading messages, the highlighted sections of code can all be deleted.  You may want to choose which messages to keep and which to remove.  Alternatively, the text between quotation marks (") can be rewritten for custom messages.  When doing so, be sure to remove constants if you delete a reference to one (if you delete %c or %s, delete the text ', file' or ', opname' or ', opnamed' after the message).


From ui.c:

/*-------------------------------------------------
    handler_load_save - leads the user through
    specifying a game to save or load
-------------------------------------------------*/

static UINT32 handler_load_save(running_machine &machine, render_container *container, UINT32 state)
{
   char filename[20];
   input_code code;
   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)
      ui_draw_message_window(container, "Select position to save to");
   else
      ui_draw_message_window(container, "Select position to load from");


   /* check for cancel key */
   if (ui_input_pressed(machine, IPT_UI_CANCEL))
   {
      /* display a popup indicating things were cancelled */
      if (state == LOADSAVE_SAVE)
         popmessage("Save cancelled");
      else
         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)
      return state;

   /* display a popup indicating that the save will proceed */
   sprintf(filename, "%c", file);
   if (state == LOADSAVE_SAVE)
   {
      popmessage("Save to position %c", file);
      machine.schedule_save(filename);
   }
   else
   {
      popmessage("Load from position %c", file);
      machine.schedule_load(filename);
   }

   /* remove the pause and reset the state */
   machine.resume();
   return UI_HANDLER_CANCEL;
}


From machine.c:

//-------------------------------------------------
//  handle_saveload - attempt to perform a save
//  or load
//-------------------------------------------------

void running_machine::handle_saveload()
{
   UINT32 openflags = (m_saveload_schedule == SLS_LOAD) ? OPEN_FLAG_READ : (OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
   const char *opnamed = (m_saveload_schedule == SLS_LOAD) ? "loaded" : "saved";
   const char *opname = (m_saveload_schedule == SLS_LOAD) ? "load" : "save";
   file_error filerr = FILERR_NONE;

   // if no name, bail
   emu_file file(m_saveload_searchpath, openflags);
   if (!m_saveload_pending_file)
      goto cancel;

   // if there are anonymous timers, we can't save just yet, and we can't load yet either
   // because the timers might overwrite data we have loaded
   if (!m_scheduler.can_save())
   {
      // if more than a second has passed, we're probably screwed
      if ((this->time() - m_saveload_schedule_time) > attotime::from_seconds(1))
      {
         popmessage("Unable to %s due to pending anonymous timers. See error.log for details.", opname);
         goto cancel;
      }
      return;
   }

   // open the file
   filerr = file.open(m_saveload_pending_file);
   if (filerr == FILERR_NONE)
   {
      // read/write the save state
      save_error saverr = (m_saveload_schedule == SLS_LOAD) ? m_save.read_file(file) : m_save.write_file(file);

      // handle the result
      switch (saverr)
      {
         case STATERR_ILLEGAL_REGISTRATIONS:
            popmessage("Error: Unable to %s state due to illegal registrations. See error.log for details.", opname);
            break;

         case STATERR_INVALID_HEADER:
            popmessage("Error: Unable to %s state due to an invalid header. Make sure the save state is correct for this
                                game.", opname);

            break;

         case STATERR_READ_ERROR:
            popmessage("Error: Unable to %s state due to a read error (file is likely corrupt).", opname);
            break;

         case STATERR_WRITE_ERROR:
            popmessage("Error: Unable to %s state due to a write error. Verify there is enough disk space.", opname);
            break;

         case STATERR_NONE:
            if (!(m_system.flags & GAME_SUPPORTS_SAVE))
               popmessage("State successfully %s.\nWarning: Save states are not officially supported for this game.",
                                        opnamed);
            else
               popmessage("State successfully %s.", opnamed);

            break;

         default:
            popmessage("Error: Unknown error during state %s.", opnamed);
            break;
      }

      // close and perhaps delete the file
      if (saverr != STATERR_NONE && m_saveload_schedule == SLS_SAVE)
         file.remove_on_close();
   }
   else
      popmessage("Error: Failed to open file for %s operation.", opname);


   // unschedule the operation
cancel:
   m_saveload_pending_file.reset();
   m_saveload_searchpath = NULL;
   m_saveload_schedule = SLS_NONE;
}