What's new

Combine mupen64 and mupen64_nogui into one exe?

Richard42

Emulator Developer
Btw, is there a way for me to view the changes for a particular revision using tkdiff?

The "svn diff" command has on option called "--diff-cmd". This should use the given command for the diff operation.

There are no outstanding issues (that weren't there before I did the merge) in the testing I've done on my machine. In fact, the merge actually fixed a slow framerate problem I was having with the nogui exe before the merge. :) The only thing I haven't tested is lirc support, but I'm sure you'll let me know if there's an issue quickly after the merge. If you could do the merge this weekend, that'd be great. I'll work on getting a README file together.

I merged the branch into the trunk! I did a couple of compilations and fixed one warning, but the build went smoothly. I tried running it right after a fresh build and had a couple of problems. It crashed because it couldn't find the mupen64.conf file. I think we should add a stat() file existence check for the mupen64.conf and if not present, use the current dir as the config dir. For consistency's sake it would also be good to check for an install file (maybe logo.png?) and do the same for the install dir if it can't be found. Would this conflict with the new theory of operation?
 
OP
E

ebenblues

Mupen64Plus Dev.
I merged the branch into the trunk! I did a couple of compilations and fixed one warning, but the build went smoothly. I tried running it right after a fresh build and had a couple of problems. It crashed because it couldn't find the mupen64.conf file. I think we should add a stat() file existence check for the mupen64.conf and if not present, use the current dir as the config dir. For consistency's sake it would also be good to check for an install file (maybe logo.png?) and do the same for the install dir if it can't be found. Would this conflict with the new theory of operation?
Awesome, thanks for doing the merge! Hmm, it shouldn't be crashing if it can't find the mupen64.conf file...when you say crash, do you mean segfault, or exit with an error message? If you mean segfault then maybe there's a bug I missed because I ran it many times without a config file and it never crashed on me. If you mean it exited with an error, then it's probably working as designed. The behavior for selecting the config and install directories are in setConfigDir and setInstallDir in main/main.c, but I'll summarize what the behavior's supposed to be:

If the config dir was not specified at the commandline via --configdir, look for a ~/.mupen64 dir. If it's not there, create it. If you can't create it, exit with an error. For the install dir, If $PREFIX/share/mupen64 exists, set it to that, else, set it to whatever the config dir is set to.

Rather than change the program behavior to look in the current working dir, I'd suggest using the --configdir flag to specify where to look for config files. If you've never installed mupen64 using 'make install', then the install dir should automatically be set the same as the config dir. If you have, i.e. /usr/local/share/mupen64 exists on your system, then you should also use the --installdir flag to specify where to look for plugins, icons, lang files, etc. Also, when you initially start mupen64, it should tell you what it's using for the config dir and the install dir (it'll be displayed in the console in nogui mode and in the gui status bar in gui mode). I'd personally like to get away from having the program look for config files in the current working dir because I believe 95% of linux users are going to run make install and want the config files stored in ~/.mupen64. Changing the program to look in the cwd for config files is more a convenience for developers and why add that when you can just use --configdir?
 
OP
E

ebenblues

Mupen64Plus Dev.
Mupen64Plus README

Here's a README file I wrote and committed to serve as a build/install guide. It also contains information on the gui/nogui merge and multi-user support. Please note, I'm assuming you're going to put the RiceVideo and Glide plugins under the main Mupen64Plus tree before releasing v1.3. Any feedback is welcome:

Code:
Mupen64Plus Build and Install Guide
-----------------------------------

The Mupen64Plus package contains the mupen64 emulator program plus graphics, sound, input, and RSP plugins. To build from source, unzip and cd into the source directory, then build using make:

 $ unzip Mupen64Plus-x.y.zip
 $ cd Mupen64Plus-x.y
 $ make all

Type 'make' by itself to view all available build options:

 $ make
 Mupen64Plus makefile. 
   Targets:
     all           == Build Mupen64 and all plugins
     clean         == remove object files
     rebuild       == clean and re-build all
     install       == Install Mupen64 and all plugins
     uninstall     == Uninstall Mupen64 and all plugins
   Options:
     BITS=32       == build 32-bit binaries on 64-bit machine
     VCR=1         == enable video recording
     LIRC=1        == enable LIRC support
     NOGUI_ONLY=1  == build without GUI support
     PREFIX=path   == specify install prefix (default: /usr/local)
   Debugging Options:
     PROFILE=1     == build gprof instrumentation into binaries for profiling
     DBGSYM=1      == add debugging symbols to binaries
     DBG=1         == build graphical debugger
     DBG_CORE=1    == print debugging info in r4300 core
     DBG_COUNT=1   == print R4300 instruction count totals (64-bit dynarec only)
     DBG_COMPARE=1 == enable core-synchronized r4300 debugging
     DBG_PROFILE=1 == dump profiling data for r4300 dynarec to data file

Previous to version 1.3, building mupen64 built two programs: mupen64 and mupen64_nogui. mupen64 had a gtk graphical frontend including a rom browser. mupen64_nogui contained no graphical frontend and all options were specified via the commandline. As of version 1.3, the mupen64 and mupen64_nogui codebases have been combined and as a result, there is no more mupen64_nogui executable. The combined mupen64 executable can either be run with a gui (default) or without a gui by specifying --nogui at the commandline. For backwards compatability, if a symbolic link to the mupen64 executable called mupen64_nogui is created, running the mupen64_nogui symlink is equivalent to running mupen64 with the --nogui flag.

NOTE: If you want to build a nogui-only version of mupen64, i.e. without gtk+ dependencies, pass the NOGUI_ONLY=1 option to make, like this:

 $ make NOGUI_ONLY=1 all

Installation
------------

After building mupen64 and all plugins, su to root and type 'make install' to install Mupen64Plus. The install process will copy the executable to $PREFIX/bin and a directory called $PREFIX/share/mupen64 will be created to hold plugins, icons, and language translation files used by mupen64. By default, PREFIX is set to /usr/local. This can be changed by passing the PREFIX option to make. NOTE: you must pass the prefix, when building AND when running 'make install'. For example, to install mupen64 to /usr, do this:

 $ make PREFIX=/usr all
 $ su
 # make PREFIX=/usr install
 # exit
 $

Multi-user Support
------------------

As of version 1.3, Mupen64Plus now has support for multi-user environments.

The mupen64 program will look for user configuration files in a .mupen64 directory in the user's home directory. If the directory does not exist, it will be created and a default mupen64.conf file will be written to that directory on exit. An alternate config directory can be specified using the --configdir commandline option.

By default, the mupen64 program will look for plugins, icons, and language translation files in the install directory $PREFIX/share/mupen64 (see Installation section for details). If this directory does not exist, mupen64 will try to look in the user configuration directory. An alternate installation directory can be specified using the --installdir commandline option.

Run 'mupen64 --help' for a complete list of commandline options:

 $ mupen64 --help
 Usage: mupen64 [parameter(s)] rom

 Parameters:
         --nogui                 : do not display GUI
         --fullscreen            : turn fullscreen mode on
         --gfx (path)            : use gfx plugin given by (path)
         --audio (path)          : use audio plugin given by (path)
         --input (path)          : use input plugin given by (path)
         --rsp (path)            : use rsp plugin given by (path)
         --emumode (number)      : set emu mode to: 0=Interpreter 1=DynaRec 2=Pure Interpreter
         --sshotdir (dir)        : set screenshot directory to (dir)
         --configdir (dir)       : force config dir (must contain mupen64.conf)
         --installdir (dir)      : force install dir (place to look for plugins, icons, lang, etc)
         --noask                 : don't ask to force load on bad dumps
         -h, --help              : see this help message
 
Last edited:

Richard42

Emulator Developer
Awesome, thanks for doing the merge! Hmm, it shouldn't be crashing if it can't find the mupen64.conf file...when you say crash, do you mean segfault, or exit with an error message? If you mean segfault then maybe there's a bug I missed because I ran it many times without a config file and it never crashed on me.
...
I'd personally like to get away from having the program look for config files in the current working dir because I believe 95% of linux users are going to run make install and want the config files stored in ~/.mupen64. Changing the program to look in the cwd for config files is more a convenience for developers and why add that when you can just use --configdir?

It threw a segfault. I wanted to test a common usage scenario, or at least one that's common for me. I often want to build a project and just run it locally from the build dir before installing it to make sure that it works properly and there's no incompatibilities. So I deleted my ~/.mupen64 dir and ran the binary. It detected the absence of ~/.mupen64 and created it. But there still was nothing inside this newly created folder, and at some point afterwards it crashed..

I do like the config path and install path info message - that's a good diagnostic printout. But I would still like to be able to run a fresh build without having to install or be aware of required command-line switches. I don't know how common this scenario is for most linux users but it's common for me and if any newbies try to build and run it this way they're likely to think that it's broken. I would prefer to see the following file existence check logic:

1. If config dir is given on command line:
- if exist(<givenpath>/mupen64.conf), use <givenpath>
- else fail with error message
* else:
- if exist(~/.mupen64/mupen64.conf), use ~/.mupen64
- else if exist(<cwd>/mupen64.conf), use <cwd>
- else fail with error message

2. If install dir is given on command line:
- if exist(<givenpath>/icons/logo.png), use <givenpath>
- else fail with error message
* else:
- if exist($PREFIX/share/icons/logo.png), use $PREFIX/share
- else if exist(<cwd>/icons/logo.png), use <cwd>
- else fail with error message

I think this would be more robust. I can work on the code if you're getting tired of it; this shouldn't take too much work. Good job on the README file also, it looks pretty good.
 
OP
E

ebenblues

Mupen64Plus Dev.
It threw a segfault. I wanted to test a common usage scenario, or at least one that's common for me. I often want to build a project and just run it locally from the build dir before installing it to make sure that it works properly and there's no incompatibilities. So I deleted my ~/.mupen64 dir and ran the binary. It detected the absence of ~/.mupen64 and created it. But there still was nothing inside this newly created folder, and at some point afterwards it crashed..
Ok, that's a bug. I agree that's a common scenario and one I've tested on my machine many times without it crashing. Can you run the program in gdb and paste bt output after the crash? Also, can you give me the make options you used to build it and the command you ran so I can try to recreate it? I know you run with lirc support, and I haven't tested with that, so maybe that's related. Thanks.

I do like the config path and install path info message - that's a good diagnostic printout. But I would still like to be able to run a fresh build without having to install or be aware of required command-line switches.
Again, the crash is a bug. You should be able to run it just fine without any commandline switches. It'll just create a config file with default options in ~/.mupen64.

I'm ok with your algorithm, but I think it might cause a little confusion because when you run it the first time, if you happen to be within the source dir, then it'll use the mupen64.conf file in the source dir, but later, if you install it, leave that dir, and run it again, you'll lose all your config settings from before. What if we change that algorithm slightly to copy the mupen64.conf file from cwd to ~/.mupen64 and then use ~/.mupen64 as the config dir?

I can work on the code if you're getting tired of it; this shouldn't take too much work.
I don't mind writing it, I'm just trying to figure out how to write it in a way that will be least confusing for users who don't know how the code works.
 

Richard42

Emulator Developer
I'll run the test again tonight and get some more data on the source of the crash. It may have been a plugin that crashed and not Mupen64 itself.

I'm ok with your algorithm, but I think it might cause a little confusion because when you run it the first time, if you happen to be within the source dir, then it'll use the mupen64.conf file in the source dir, but later, if you install it, leave that dir, and run it again, you'll lose all your config settings from before. What if we change that algorithm slightly to copy the mupen64.conf file from cwd to ~/.mupen64 and then use ~/.mupen64 as the config dir?

I'm okay with that. I would propose to keep the same logic that I gave in the previous message for the install dir, and for the config dir:

Code:
1. If config dir is given on command line:
    - if exist(<givenpath>/mupen64.conf), use <givenpath>
    - else fail with error message
  * else:
    - if !exist(~/.mupen64/mupen64.conf), then:
      - create ~/.mupen64 and copy all files from <cwd>/config to ~/.mupen64
    - use ~/.mupen64

I also propose to do some cleanup, by creating a new top-level folder called "config" in the mupen64-64bit tree and placing all of the default config files in there.
 

Richard42

Emulator Developer
Here's the GDB output of the segfault:

Code:
20:44:38  mupen64-64bit > gdb ./mupen64
GNU gdb 6.7.1
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu"...
Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) run 
Starting program: /home/pyro/Desktop/sandbox/test/mupen64-64bit/mupen64 
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7fff459fe000
Creating /home/pyro/.mupen64 to store user data
/home/pyro/.mupen64/mupen64.conf: No such file or directory

Program received signal SIGSEGV, Segmentation fault.
0x00002ab567d0a8a0 in readdir64 () from /lib/libc.so.6
(gdb) info stack
#0  0x00002ab567d0a8a0 in readdir64 () from /lib/libc.so.6
#1  0x000000000041bf18 in plugin_scan_directory (directory=<value optimized out>) at main/plugin.c:211
#2  0x0000000000418247 in main (argc=1, argv=0x7fff458f1748) at main/main.c:1079
 
OP
E

ebenblues

Mupen64Plus Dev.
I also propose to do some cleanup, by creating a new top-level folder called "config" in the mupen64-64bit tree and placing all of the default config files in there.
I agree. Then we can edit the makefile to copy the default config dir to the install dir on 'make install'. We still need to add interfaces to the plugins to specify where to look for their config files. This should probably be done before the next release so everything works the same way.

It'd probably also be good to make the default configs more "default". For example, the window width/height settings are pretty large and the rombrowser dir is set to an absolute path on Richard42's machine...or did you just leave that there to make us jealous (/mnt/terabyte/...)? ;-)
 

Richard42

Emulator Developer
It'd probably also be good to make the default configs more "default". For example, the window width/height settings are pretty large and the rombrowser dir is set to an absolute path on Richard42's machine...or did you just leave that there to make us jealous (/mnt/terabyte/...)? ;-)

Oops. I was trying to keep my local machine paths out of the config files, too. Guess I missed that one. Definitely we should clean these; the problem is that running the emulator overwrites the files and then it's real easy to commit them into SVN when you don't want to. Maybe having them in a different directory will make it easier to keep them unmodified.

The Mupen64.ini file is stored as text in SVN but when the emulator overwrites it, it stores a binary gzipped stream. That's really annoying. I suppose that the mupen64/plugin .ini files should go in the user config directory as well.
 
OP
E

ebenblues

Mupen64Plus Dev.
Awesome, thanks for the info. Found the bug and fixed it. I'll add the new algorithm for determining the config/install directories and commit it tonight.
FYI, I did make this change and committed it to svn. Let me know if there are any issues with it. Thanks.
 

Richard42

Emulator Developer
FYI, I did make this change and committed it to svn. Let me know if there are any issues with it. Thanks.

Yeah I looked at the commit. I was planning on adding a 10ms 'nanosleep' call to the loop with SDL_PumpEvents because otherwise you'll load the CPU at 100% for no reason. I thought about using SDL_Delay but this wouldn't be good because SDL_TIMER isn't initialized by the Mupen64 core, but it is initialized by jttl_audio.

This is a good fix to have; I updated the TODO file. I think I may create a new repository for Mupen64Plus this weekend and move everything around for the new project. I'll PM all the developers so that we're synchronized on this.
 

Top