If you ever want to write code for the Sega Saturn using the Psy-Q SDK (available here), you may encounter a small problem with the toolset when using #include directives.
This will crash with the following error: main.c:1: abc.h: No such file or directory, which is quite strange given that we explicitely told the compiler to look in that THING folder.
What we have:
CCSH.EXE : main compiler executable (CCompiler Super-H)
CPPSH.EXE preprocessor (CPreProcessor Super-H)
CCSH calls CPPSH with the source file first to get a raw code file to compile, and then actually compiles it. Here, we can see by running CPPSH alone that it still triggers the error, which means the problem effectively comes from CPPSH. After a thorough analysis in Ida, it seems that even though the code that handles parsing the command-line parameters related to include directories, those paths aren't actually added to the program's internal directory array and thus never actually used. I could have decompiled it and fixed it myself, but I found a faster and simpler way: use the PSX one.
Though CCSH and CCPSX are very different in nature (one compiles for Super-H and one for MIPS), their preprocessors are actually almost identical – when we think about it, it makes sense: the C language doesn't depend on the underlying architecture (most of the time), so why would its preprocessor do?
So here's the fix: rename CCSH to something else and copy CCPSX to CCSH. Solves all problems and finally allows compiling C code for the Sega Saturn on Windows (the only other working SDK on the Internet is for DOS, which requires using DOSBox and 8.3 filenames, which makes big projects complicated to organize).
That's nice and all but can we compile actual code? Seems that the answer is no. Here is a basic file:
Compiling this will give the following error:
In file included from bin/main.c:2:
D:\SATURN\INCLUDE\stdlib.h:7: conflicting types for 'size_t'
D:\SATURN\INCLUDE\stddef.h:166: previous declaration of 'size_t'
It seems that the STDLIB.H file in the SDK is somehow wrong, in that it has the following at the top:
Whereas its friend STDDEF.H looks like this:
Two incompatible declarations, the compiler dies. The simple fix is to remove the DEF at the end of the names in STDLIB.H, to get something like this:
I've recently encountered some pretty weird problems with my two USB3 external hard drives. Disk disconnecting when opening specific files, and refusing to reconnect on the computer until I plug it into another computer, then it works again, and so on.
Then I started noticing a pattern. The files that trigger the crash are always files that I have opened on another computer with that hard drive, which should give you a clue on what this might be about.
It seems that there's a bug in Windows' drive ejection system, which basically means that if you plug a hard drive on a computer, open a file in any software that keeps the descriptor open all the time (I'm looking at you, IDA Pro), and then eject the drive without closing the software first (which sometimes happens), the file will somehow still be marked as open in the NTFS attributes, and when you'll try to open it on another computer, Windows will flip out and disconnect the hard drive. And until you plug the HDD back on the other computer, it will refuse to read it on the first one, showing as RAW in the management console, even in another OS (I tried Ubuntu and FreeBSD) as long as you stay on that computer. But then, if you do plug it back, then it will magically unlock and it will work again on all computers. This took me about a week to figure out. Hope it'll have helped you figure it out in less time than me.
The project has come a long way since June of 2017.
Since the beginning of the project, the codebase has been divided into two separate branches: PC and PSX, which share a common "GAME" folder which contains the platform-independent game logic code.
More progress has been made on the PSX version since a lot of code is plain old MIPS assembly which we haven't had to decompile to C, so the PC version is still lagging behind. Problems with the old DirectX version used by the game (DX5) makes all of this much harder.
Also, debugging the PSX version has always been a pain in the ass because of the need to run it in an emulator (we've used no$psx most of the time).
To solve that problem, we've started working on what we call the Emulator, which is simply put an implementation of the PSY-Q PSX SDK acting as an HLE emulator for the game. That way, we can debug the game directly in VS which is quite appreciable. We simply need to link the game binary against our emulator DLL instead of the standard PSY-Q libs. The emulator is based on SDL for windowing and OpenGL for 3D rendering.
Lately, I've been decompiling Tomb Raider 5 with some friends and while researching potential sources of debug informations that could help the process, I stumbled upon the Pocket PC version of Tomb Raider 1. It was ported by Ideaworks3D, a London-based game development company specialized in porting.
It's supposed to run on low-performance handheld devices running Windows Mobile/CE 5.0 and thus one would imagine that they have simply taken the Windows code and tweaked it a little bit to make it run on CE. Well as I discovered, it's more complicated than that. First, there is no Windows version of TR1, it was only released for DOS and was never ported to either Win16 or Win32. Second, they actually didn't take the PC version as a base, but the PSX version.
It may seem weird, why take the PSX version if your product is going to run on Windows CE. As it appears, Ideaworks3D seems to have developed an in-house userland syscall JIT translator for PSX, and uses it when porting games to CE. In other words, they compile the PSX codebase to ARM code and link that binary against a DLL file called iepaella.dll which contains implementations of PSX syscalls that call the WinCE API. Apparently, they have also made a version of that DLL which runs on standard Win32 that they used to make an ActiveX port of their Pocket PC port of the PSX version. It allowed playing TR1 in Internet Explorer. Not sure why anyone would ever do that, though.
I find this quite interesting because the main game executable seems to have a code near-identical to the original PSX version, which means that "IEPaella" is effectively a full-featured userland PSX emulator for WinCE and Win32 that is capable of mapping the PSX system routines to DirectX API calls. I haven't been able to find any other similar product on the internet. The only software that could be considered similar is Usercorn, a userland emulator based on Unicorn which implements most of the Linux, BSD and Darwin syscalls and even some DOS interrupts. It's very basic though, nowhere near what Paella does.
Currently, the codebase of the decompilation project is divided in 3 main folders:
GAME contains the shared game code
SPEC_PSX contains the PSX platform code
SPEC_PC contains the PC platform code
Debugging on PSX is much harder than on PC, because the binary is run in an emulator and you can't just run the code step-by-step to see where it crashes. Using Paella would allow doing such a thing because the binary is effectively being run on the computer and works like any other C++ program. We're currently search for ways to implement Paella support in TOMB5, but it may take time because not all PSX syscalls are implemented. It will eventually work, though.
For my latest project (Turing), I chose to use PyQt 5 for the GUI because it's what seemed the best to me to allow the whole thing to be cross-platform without much of a hassle. It has done its job quite well for about everything.
After some months of development though, I ran into an issue I was unable to fix : there is a bug, somewhere inbetween pylupdate5 (that scans code files for lines to translate) and lrelease (that compiles .ts files to .qm files) which basically prevents using non-ASCII characters in source strings. You can use them in translated strings, but not in the code files.
Quite strange, since both the code files and the .ts files (which are in XML format) are encoded in UTF-8. Or so I thought.
It seems that lrelease assumes that everything is ASCII (well, to be precise, Latin-1) if you don't specify it at each <message> element in the file, even though the very first line of the file (the XML header) specifies the encoding, in this case utf-8. pylupdate5 has no problem with that and assumes UTF-8 by default.
The workaround is to add an attribute to each <message> element in the .ts file to force lrelease to understand that it's UTF-8. Basically, replacing <message> by <message encoding="UTF-8"> everywhere. The problem is that when pylupdate5 re-saves the file after adding the new lines from the code, it discards the attributes (maybe it assumes that they aren't needed, which is a correct assumption given that it's a freaking XML file). Thus, I needed to write a script that is executed between the two calls to make sure that lrelease always gets fed a file with the attributes, so that it always parses it correctly.
I don't know if it's a bug on the PyQt side or on the Qt side, but it stills seems quite weird to me that we still encounter this kind of problems in 2018, when every sane piece of software uses UTF-8 by default.
This article by Joel Spolsky is from 2003, and it seems that back then the basic knowledge of how to correctly use encodings had already been invented, so why are so many programs still unable to use text correctly?