|
DeveloperGuide
A guide for developers.
(this doc is very much work in progress) Building DolphinLook at the build guide page for your platform: WindowsBuild Linux_dependencies MacOSX_Build Test build in LinuxHere's how Windows users can test build their changes in Linux:
Code dependenciesIt is absolutely forbidden to introduce dependencies on wxWidgets into Core and Common. We want to be able to do a NoGUI build without requiring Wx. Also, optional dependencies (any kind of ALLOW_WX etc) is ABSOLUTELY FORBIDDEN in Core/Common!!!!!! In general, keep dependencies to a minimum. More code linked in = more bugs. The DebuggerTo start Dolphin in debugger mode, add -d or /d (Windows) to the command line (this can be done in Visual Studio by right-clicking the project, properties, and add this command in debugging/command arguments). The debugger you see in Dolphin is a complete rewrite (using wxWindows this time, the old one was Win32) of the one we used to have. Some features have been lost, but we try to add them back as we need them. If you want to see something meaningful in there when games are loaded, choose Symbols/Generate symbol map after you have loaded a game in order to discern functions. This works without the symbol database too, but then you won't get nice function names. (Note: totaldb.dsy is also available under Downloads on this site) Alternatively, if you have a .map file for a game (Zelda WW and a few others have one on the disc!), then you can load it. There's no GUI to do that in the new debugger yet, but it's coming. Menu OptionsCPU ModeInterpreter coreThis is nessesary to get break points and stepping to work as explained below. But it can be very slow, perhaps slower than 1 fps. Automatic startStarts the game directly instead of booting to pause. It also automatically loads the Default ISO when Dolphin starts, or the last game you loaded, if you have not passed Dolphin an elf file with --elf on the command line. This can be convenient if you are bugtesting with a certain game and want to rebuild and retry it several times, either with changes to Dolphin or if you are developing a homebrew game. Unlimited JIT CacheAvoid any involuntary JIT cache clearing, this may prevent Zelda TP from crashing. JIT off (JIT core)Turn off all JIT functions, but still use the JIT core from Jit.cpp. SymbolsSave codeSaves the entire disassembled code. This may take a several seconds and may require between 50 and 100 MB of hard drive space. It will only save code that is in the first 4 MB of memory; if you are debugging a game that loads .rel files with code to memory you may want to increase that to perhaps 8 MB, which you can do from SymbolDB::SaveMap(). Breakpoints and SteppingCPU breakpoints are triggered from CPU.cpp under case CPU_RUNNINGDEBUG. There are many limitations to using breakpoints in JIT mode. To begin with only the first address of a block may be considered for a breakpoint, the PC variable (PowerPC::ppcState.pc) will never have any address from within a block. Also if you use the JIT core multiple blocks will be executed at a time before execution leaves Jit64::Core::SingleStep() and goes back to the case. So breakpoints will often not hit even if you have added the first address of a block. So currently the only way to use breakpoints and stepping reliably is with the interpreter core. Because it can be very slow (less than 1 fps) an idea is to place a PanicAlert() at some function that is executed short before the function you want to break at, and when you get to the Alert, close the Alert window > press pause > change to interpreter. Currently it's important that you close the Alert box before you pause, if you don't Dolphin will exit without any message or DrWatson crash report. At least that's what happened for me with SSBB. For memory breakpoints (also called memory checks), i.e. breaks that are hit when a certain address outside the executable blocks are read from or written to, JIT mode will also be unreliable. It will only work for non-JITed memory instructions, for example lesser used instructions such as stmw or lmw. More common instructions such as lwz or stw will not trigger any breakpoints. The difference here is that you can still use the JIT core and get all (or almost all?) memory reads and writes to pass by Memmap.cpp so that they trigger a breakpoint. As mentioned this is breakpoints for addresses only, there is currently no option to break when a certain value is read or written. However you can do that manually in CheckForBadAddresses() in Memmap.cpp. But even with that there is no way to trigger a break from register-to-register copies of a certain data, it will only trigger from register-to-memory copies. We are looking at a way to add register-to-register breakpoint triggers to that will trigger when a certain value is copied to a register. Debugging WindowsLogManager windowVerbosity: Show different verbosity levels by changing the verbosity radio boxes. 0 is lowest verbosity and 3 is highest verbosity (high meaning most messages). Resolve symbols: Checking this will resolve symbols for verbosity level 0 and 1. Higher verbosity levels will not be resolved because of the speed issue. Write master: Check this to write all selected logs to the master log file. Show unique: Show only logs that are unique to that verbosity level. I.e. prevent logs from lower verbosity levels to fall through to this higher level (it only applies to what is shown in the window, lower level logs are still saved to the message list and to the files). Naturally it only applies to levels 1, 2 and 3, not 0. BreakPoints windowMemory checks for the main RAM located at 0x80000000 to 0x817fffff and 0xC0000000 to 0xC17fffff wont work for JITed LoadStore opcodes because they don't use the Memmap.cpp functions where the memory checks are. Memory checks for the hardware registers that are located at 0xCC000000 to 0xcc008004 seems to work even if JITed opcodes update them, but they are mostly unnecessary because all changes to these registers are also picked up by LOG messages. BPs and MCs buttons: They allow you to load breakpoints and memory checks from a GameIni/BreakPoints.ini and a GameIni/MemoryChecks.ini file. All memory check matches will result in a log message in the MI memmap log, but only selected checks will result in a break. Voluntary comments can be written after a #. BreakPoints.ini only accept one address per row and should look like this 802734fc # Starting address of a function 8045dc44 # Starting address of another function ... MemoryChecks.ini accept different formatting and can look like this 8037ffac # Only one address checked, and no break will occur cc000000 cc000080 # A range of memory, and no break will occur cc000000 cc000080 1 # A range of memory, and a break will occur ... A PowerPC PrimerThe GC and the Wii both have a modified PowerPC as a main CPU. PowerPC has 32 registers. R1, also known as sp, is the stack pointer. Return addresses are first keps in LR, the link register, and are only if necessary written to the stack. These are only some basic instructions. There are many more, of course.
OptimizationWhen you work on improving the framerate, work on the difficult cases, such as outdoors in Zelda. A change that improves the framerate indoors, where it's already fast enough, without having any measurable effect outdoors, is probably not worth doing if it complicates the code at all. Thread ModelDolphin has a choice of two thread models: "single core" and "dual core". As the name suggests, the "dual core" model is intended to spread the load over two cores on dual core machines. The "single core" model runs the following threads:
In the GUI version of Dolphin, this thread runs wxWidgets. In the non-GUI version of Dolphin, this thread sleeps most of the time. This thread starts in the main() function of the application executable. In the GUI version, wxWidgets contains the main() though and the Dolphin code is only called through event handlers. This thread starts running in the EmuThread() function defined in Source/Core/Core/Src/Core.cpp, created from the Main Thread. On Windows, this thread preprocesses input events. On other platforms, it just sleeps. This thread is started by the audio library (libao). This thread starts running in the CPUThread() function defined in Source/Core/Core/Src/Core.cpp, created from the Emu Thread. It runs the emulation of all hardware: the CPU (PowerPC), the GPU (GX) and the rest. In the "dual core" model, the video emulation is done on the Emu Thread instead of on the CPU Thread. Not useful docsRead this for your own fun ;)
|
Sign in to add a comment
It should probably be noted that you can't link Plugins to libcore.
It may be worth mentioning that if you don't want to pay for a VMWare License, you can use VirtualBox?, which is free, and tends to run faster than VMWare.