Memory used to be precious. Last year I ported some text adventures games from the TRS-80 machines of the early 1980s to Android. While working on one of the games (Bedlam), I went through a process very similar to the article. Looked for strings that I knew had to be there in some form, ended up having to use a step debugger (the one in MESS) to trace through the code and discover the print routines and then the magic behind them.
It turned out Bedlam packed strings into contiguous bytes of ram, but using 5 bits per character. Byte 1 had all of character 1 in the lower 5 bits and the first 3 bits of character 2 in the upper 3 bits, and so on. Of course with only 32 values the character set was a bit odd. As I recall you had most letters but not Z or Q,the numbers 0,1, and 3, a period, comma, and space. Something like that. The routine to unpack the characters was quite small, just used shifts to build an offset into a table containing the ASCII values.
The games also ran in a somewhat ingenious "virtual machine", with all the game logic being expressed through sets of very tightly encoded high level rules rather than implemented directly in assembly. In the Android port, I literally load the original ROM into an array and then just process these same rules verbatim using a java implementation of the VM. Kind of amazing to me how portable yet efficient the design is.
It turned out Bedlam packed strings into contiguous bytes of ram, but using 5 bits per character. Byte 1 had all of character 1 in the lower 5 bits and the first 3 bits of character 2 in the upper 3 bits, and so on. Of course with only 32 values the character set was a bit odd. As I recall you had most letters but not Z or Q,the numbers 0,1, and 3, a period, comma, and space. Something like that. The routine to unpack the characters was quite small, just used shifts to build an offset into a table containing the ASCII values.
The games also ran in a somewhat ingenious "virtual machine", with all the game logic being expressed through sets of very tightly encoded high level rules rather than implemented directly in assembly. In the Android port, I literally load the original ROM into an array and then just process these same rules verbatim using a java implementation of the VM. Kind of amazing to me how portable yet efficient the design is.