XQEMU is an open-source emulator to play original Xbox games on Windows, macOS, and Linux. Please visit xqemu.com to learn more.
Platform | Build Status |
---|---|
Windows | |
macOS | |
Ubuntu |
Simple graphical user interface to manage XQEMU
Home Page: http://xqemu.com
License: GNU General Public License v2.0
XQEMU is an open-source emulator to play original Xbox games on Windows, macOS, and Linux. Please visit xqemu.com to learn more.
Platform | Build Status |
---|---|
Windows | |
macOS | |
Ubuntu |
The UI should display the current LED color.
This needs emulation in the XQEMU SMC and addition of a QMP or HMP command to transfer the state to the UI.
For a (hacky, and possibly incorrect) implementation of the SMC LED code check xqemu-jfr.
For more information about the SMC (also known as PIC) and how the LED is hooked up, visit http://xboxdevwiki.net/
xqemu/xqemu#253 added the option to configure the reported video cable type. XQEMU-Manager should support this in the GUI.
I'd personally suggest using a naming like this for the GUI:
(So basically list the official MS adapter name, and then add some information about the video-standard / cable)
Now that we have CPU virtualization on all platforms, we need a way for users to enable it in the GUI.
The settings dialog can be opened while XQEMU is running.
However, many of its options configure the hardware state and should not be modifiable while the Xbox is already running (Flash / EEPROM / HDD image / LPC / SMC flags / ..).
We should disable most of the settings dialog while XQEMU is running.
Settings which should still be configurable at runtime:
Ideally, all of these would have a separate UI in the main-window, as these are features that a physical Xbox exposes to a user.
Other options could be runtime configurable if supported by QEMU (can it switch to hw-virt at runtime?), however, those should probably remain in the settings window.
Keep in mind that XQEMU is LLE and we can't always assume that it's running the official MS bios / kernel / licensed games. Anything which makes such assumptions is part of HLE.
HLE in XQEMU and its UI should always be entirely optional and it must be possible to disable such features (or they must handle non-MS code gracefully).
Following is some code which could be used to get information about the running XBE.
For more information, check http://xboxdevwiki.net/Xbe which also has a link to the file format at the bottom.
Function to do HMP commands via QMP:
def read(self, addr, size):
cmd = {
"execute": "human-monitor-command",
"arguments": { "command-line": "x /%dxb %d" % (size,addr) }
}
response = self.run_cmd(cmd)
lines = response['return'].replace('\r', '').split('\n')
data_string = ' '.join(l.partition(': ')[2] for l in lines).strip()
data = bytes(int(b, 16) for b in data_string.split(' '))
return data
Code to read, parse and print XBE fields:
base = 0x00010000
if t.read(base, 4) == b'XBEH':
xbe_timestamp = int.from_bytes(t.read(base + 0x114, 4), 'little')
ts = datetime.datetime.utcfromtimestamp(xbe_timestamp)
print("XBE Timestamp: %s (0x%08X)" % (str(ts), xbe_timestamp))
cert_address = int.from_bytes(t.read(base + 0x118, 4), 'little')
cert_timestamp = int.from_bytes(t.read(cert_address + 0x4, 4), 'little')
ts = datetime.datetime.utcfromtimestamp(cert_timestamp)
print("XBE Certificate Timestamp: %s (0x%08X)" % (str(ts), cert_timestamp))
title_id = int.from_bytes(t.read(cert_address + 0x8, 4), 'little')
a = title_id >> 24
b = (title_id >> 16) & 0xFF
i = title_id & 0xFFFF
print('XBE Title-ID: 0x%X (%c%c-%03d)' % (title_id, a, b, i))
title_name = t.read(cert_address + 0xC, 40 * 2).decode('utf-8')
print("XBE Title-Name: '%s'" % title_name)
else:
print("No XBE found")
Output:
XBE Timestamp: 2001-12-12 19:15:05 (0x3C17ACB9)
XBE Certificate Timestamp: 2002-03-04 15:58:09 (0x3C839991)
XBE Title-ID: 0x4D530007 (MS-007)
XBE Title-Name: 'Azurik - Rise of Perathia'
The primary use of this information would probably be that it could be displayed as part of the UI (possibly move it into the QEMU window title). This would be immediately visible for use in bug reports.
If we allow some kind of telemetry or motivate users to report often, we can also use this information to create a complete set of XBE header dumps / complete gameset, possibly discovering undumped DVDs.
A sneaky way to get telemetry could be rich presence (which I don't want for XQEMU) or pairing players for network games in the future (which I want, regardless of telemetry).
The memory-read gadget can also retrieve kernel information for bug reports.
Otherwise, it's quite limited in use, because the UI can get information directly through our hardware-emulation.
Reminder: Xbox RAM contains copyrighted or otherwise protected material during runtime. So I'd advise against doing full crashdumps.
We should selectively dump the metadata we need, much like the code above does.
The "Pause" button doesn't do anything if XQEMU is not running.
Therefore, the button should be disabled when XQEMU is not running.
This will be easy after #48 because we have a callback for starting/stopping of the XQEMU process.
As discussed on IM, this would greatly improve usability for first-time users, especially windows users, that are used to easy first-time setups.
That's why I would like to make it a wizard for the first xqemu run:
The wizard could accommodate other settings in the future, such as input, and console configuration (region, etc). But those three steps are the most important for first time users. Of course, the wizard would be cancellable, launchable again, pages could be skipped, and the downloaders could be called again directly from the settings.
An update check could also be performed on launch, and offer the user to upgrade if a new one is available.
As a reference, these were my alternative proposals to make the setup easier:
The UI checkbox is there but it doesn't do anything. It just needs to add the ,locked
flag to the HDD -drive
param.
When hitting the "Restart" button (which sends QMP system_reset
), I always seem to get:
hw/xbox/nv2a/nv2a_pfifo.c:278: pfifo_run_pusher: Assertion `false' failed.
I think we should remove the button for now, or hide/disable it (until XQEMU doesn't crash anymore).
@mborgerson has mentioned on IRC that he already fixed XQEMU system resets while working on snapshots. So if he fixes the issue in XQEMU soon, hiding the button might not be necessary.
Additionally, the "Restart" button is always enabled, even if XQEMU is not running. It just does nothing. So if we don't remove it, we'll need a new issue about this.
The UI hangs after hitting the start button, until QMP is connected.
This means that UI elements like the log that is being added in #48 are not refereshed, which means a large number of log messages are suddenly shown, once the connection is established.
The "Start" button won't change into "Stop" for about a second on my machine - this makes the UI feel unresponsive.
To avoid this, the connection loop should be improved / replaced:
Lines 288 to 302 in 00f3bf0
It currently points at the opened PR.
It links to:
https://ci.appveyor.com/project/xqemu-bot/xqemu-manager
It should link to:
https://ci.appveyor.com/project/xqemu-bot/xqemu-manager?branch=master
Same issue for the badge; please consult AppVeyor docs how to fix it.
The UI control is there but it's not hooked up yet.
I don't have the exact error message available, but I have a workaround:
pacman -S mingw-w64-x86_64-python2-pyqt5
pacman -S mingw-w64-x86_64-python3-pyqt5
One of those, depending on wether we want to promote python 2 or 3 (both for 64 bit only).
MSYS2 python seems to pick the highest available version as default.
So please decide a good default version for the shebang in main.py (Probably python 2 so we can use the same Python that's necessary for QEMU install)
Issue instead of PR as I don't have time to integrate this into README right now
The UI tab/components are there but nothing is hooked up. This needs to add the proper net flags to xqemu. Should support port forwarding. Here's a sample partial command line to get started:
-net nic,model=nvnet -net user,hostfwd=tcp:127.0.0.1:8081-:21,hostfwd=tcp:127.0.0.1:731-:731 \
The settings dialog can be opened multiple times.
That is confusing. Especially because the dialogs aren't synchronized and because of #15 (so the user doesn't know which settings are actually used).
We should only allow to open one settings-dialog.
In my opinion the current settings dialog is unintuitive design.
I always have the instinct to go back to confirm that my settings have been changed, because just closing a dialog doesn't confirm to me that anything has been saved.
It's also odd that you have to press the โ at the top of the window after working yourself from top-to-bottom for configuring each setting in the window.
The solution to this does not necessarily have to be a button labeled "Save changes" - other solutions are also possible, as long as it's intuitive.
Tested and confirmed in Grand Theft Auto San Andreas - with xqemu-manager it stucks (black screen - BS) after copyright screen just before Press Start. With bat-file it boots and after pressing Start button assertion error (its not xqemu-manager bug, already reported to xqemu's issue-tracker).
Tested on 5d4058d6.
Bat-file:
xqemu.exe -cpu pentium3 -machine xbox,short_animation,bootrom=mcpx.bin -bios bios.bin -m 64 -drive index=0,media=disk,file=hdd.qcow2,locked -drive index=1,media=cdrom,file=gtasa.iso -usb -device usb-xbox-gamepad
Titles (tested on xqemu-manager):
Grand Theft Auto San Andreas - BS after "Press Start" screen
Lord of the Rings: Third age - freezes (maybe its working, but I am not sure) at main menu, input is not response. Also it has some graphic glitches - yellow garbage.
Mortal Kombat Deception - BS after credits screen, just before FMVs.
If XQEMU fails to start, which might be caused by an invalid command line being passed to it (e.g. use controllers which are not connected), XQEMU-Manager will fail to connect to XQEMU over QMP. A cryptic "WinError 10061" error message will be displayed to users. In this case, we should be able to determine why XQEMU failed to start and report this to the user.
Additionally, XQEMU-Manager isn't aware of when the XQEMU subprocess crashes (e.g. hitting an assert), but it should be. We should be able to collect error messages and display them to the users. In the future, automated error reporting would be nice too but that's a separate issue.
not sure whats going on, I can start xqemu via a bat file and it works fine, but if I start it via the manager i get
QEMU 4.2.0 monitor - type 'help' for more information
(qemu) dsp_init
dsp_init
Found game controller 0 (XInput Controller)
ac97: invalid bm_index(3) in voice_set_active
ac97: invalid bm_index(3) in voice_set_active
ac97: invalid bm_index(3) in voice_set_active
ac97: invalid bm_index(3) in voice_set_active
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
ac97: invalid bm_index(3) in voice_set_active
ac97: invalid bm_index(3) in voice_set_active
dsound: Could not lock playback buffer
dsound: Reason: An invalid parameter was passed to the returning function
dsound: Failed to lock buffer
the command lines are virtually Identical (only small difference in structure, no additions and using same iso, mcpx and bios)
Via bat game runs, via manager it goes to xbox needs servicing
XQEMU had supported an EEPROM file for some time (xqemu/xqemu#107).
XQEMU-Manager doesn't support this yet.
It should be implemented.
Additionally, a warning should be added which tells users that writeback isn't supported (as we rejected xqemu/xqemu#122 ; new attempts at fixing it properly will be welcome!)
There is a discrepancy of what xqemu-manager claims to run (launchCmdToString(cmd)
), and what is actually being ran (cmd
).
There could be cases where launchCmdToString
and the expansion in subprocess.Popen
diverge. So copy pasting the "Running: ..." line from stdout might not produce the same result as running it through xqemu-manager.
Our UI labels the log as "XQEMU Messages", but the "XQEMU quit prematurely" message will refer to it as "log area".
We should make this more consistent.
We seem to have an issue with loading settings files created with an older version of the tool. XQEMU-Manager should be more robust in loading these older files instead of crashing.
RIP. Qxemu fails to do anything so unless I try this practically needed program that isn't included in the actual program's ZIP (GG) I can assume it will never work. Good job. Would love to see this file updated and fixed VERY soon.
Hello ๐
Due to appveyor keeping artifacts only for 1 month, the link to download the latest build is broken.
Could you please trigger a fresh build and make some GitHub release with a build copy as a release asset so it wouldn't be cleaned up after 1 month.
Thank you ๐
During review of the original log PR, we agreed that the log should eventually move into its own window. We already had some ideas how this could work:
See #48 (comment) for comment by @mborgerson
and #48 (comment) for comment by @JayFoxRox
When pressing "Restart" it will crash XQEMU (See #50). When pressing the button again, XQEMU-Manager will try to send another QMP command before realizing that XQEMU crashed.
This leads to XQEMU-Manager aborting (closing):
Traceback (most recent call last):
File "./main.py", line 426, in onRestartButtonClicked
self.inst.restart()
File "./main.py", line 330, in restart
return self.run_cmd('system_reset')
File "./main.py", line 318, in run_cmd
resp = self._qmp.cmd_obj(cmd)
File "xqemu-manager/qmp.py", line 174, in cmd_obj
resp = self.__json_read()
File "xqemu-manager/qmp.py", line 82, in __json_read
data = self.__sockfile.readline()
File "/usr/lib/python3.7/socket.py", line 589, in readinto
return self._sock.recv_into(b)
ConnectionResetError: [Errno 104] Connection reset by peer
Aborted (core dumped)
or
Traceback (most recent call last):
File "./main.py", line 426, in onRestartButtonClicked
self.inst.restart()
File "./main.py", line 330, in restart
return self.run_cmd('system_reset')
File "./main.py", line 320, in run_cmd
raise Exception('Disconnected!')
Exception: Disconnected!
Aborted (core dumped)
We should handle the disconnection / loss of connection more gracefully.
This might also affect other QMP commands.
For some advanced features, would be good to have a box for any extra args that aren't handled by the GUI.
While #12 was a hacky way to support spaces, we still don't support other symbols in paths (MCPX, Flash, HDD, DVD path).
This probably includes backslash (\
), comma (,
) and possibly more.
We should properly use a double quoted string in the command lines whenever necessary.
Also see previously mentioned #12 where to implement this.
Hi, I am on Win 10 device and unable to run your application, as it exits with "Failed to execute script main". I am using your latest AppVayor pre-build. What I got on the command line is:
ModuleNotFoundError: No module named 'PyQt5.sip'
I have PyQt5 and sip installed and latest. I didn't look at your code or recompiled but for the time being it doesn't work.
(Might not be necessary, depending on design chosen in #53)
The log currently changes the selection when appending a new message. This was already noted in the original log PR
Ideally the selection would remain.
As XQEMU Manager does not force a specific GUI / -display
, a default one is picked, which is typically Gtk on platforms which support it.
To avoid such variety, we should add ['-display', 'sdl']
into the cmd
array which forces the simple SDL UI.
Issue instead of PR due to lack of time - this is also a beginner task
if u haave it, pls share it.
There's 2 related bugs that we noticed during review of the original log PR #48 (comment):
It would be useful to be able to see what the command line invocation looks like.
The UI is there but nothing is hooked up yet. Should support enabling SuperIO, GDB (and port), and whether it should halt on startup to wait for connection.
Eventually XQEMU will support emulating Xbox controllers using SDL2 input devices (which might actually be Xbox controllers...). Once available, Update: XQEMU now supports SDL2 input devices! This should be configurable through this page. That is:
I think we should remove the "Screenshot" button - most operating systems have a feature for this built-in anyway (example: Alt+PrtSc on Windows puts screenshot of active Window in clipboard).
Having support for taking screenshots can potentially be useful for telemetry or bug reports, but this would need better integration.
Issues with the current implementation:
I think we should remove the button for now to avoid all of these issues.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.