Recompiling JSM scripts
See original GitHub issueI started writing support for JSM codes. I do it in a separate assembly, without changing the existing code. Currently ported Deling code to C#. I dunno how much is enough for me, but I hope to finish AST and nice formatting.
-
Investigation of Opcodes ⬛⬛⬛⬛⬛⬛⬜⬜⬜⬜ 60% We have an article on the wiki, a ready-made Deling and Garden sources, topics on the Qhimm forum and reverse engineering. Half the opcodes aren’t documented.
-
Disassembling of instructions ⬛⬛⬛⬛⬛⬛⬛⬛⬛⬛ 100% Handling the stack leads to a lot of errors. It is necessary to go from opcodes to a sequence of high-level instructions.
PSHN_L(0); PSHN_L(127); MUSICVOL => SetMusicVolume(channel: 0, volume: 127)There was a lot of work done in Deling. Unfortunately, only basic instructions are described. The rest will have to finish. Currently, the stack sizes have been clarified for all instructions that were in valid files (several files don’t correspond to the JSM standard or contain obvious errors [invalid jumps in test files], they will have to be processed separately). -
Building of abstract syntax tree ⬛⬛⬛⬛⬛⬛⬛⬛⬛⬛ 100% The bulk of the work has already been done in Deling. It is necessary to eliminate crutches that hide bugs and remove spaghetti from the code.
-
Print decompiled sources ⬛⬛⬛⬛⬛⬛⬛⬛⬜⬜ 80% Similar to the previous paragraph. Bugs less, spaghetti more. Need to refactor code. Instead of pseudocode, it is better to use C# syntax.
if var622_ubyte == 128 begin
if var599_ubyte == 32 begin
var1041_ubyte = 1
end
else if var622_ubyte < 128 begin
if var622_ubyte > 1 begin
var622_ubyte = 2
else if var622_ubyte == 1 begin
var622_ubyte = 1
else if var617_ubyte > 1 begin
var622_ubyte = 2
else if var617_ubyte == 1 begin
var622_ubyte = 1
else if var618_ubyte > 1 begin
var622_ubyte = 2
else if var618_ubyte == 1 begin
var622_ubyte = 1
else if var620_ubyte > 1 begin
var622_ubyte = 2
else if var620_ubyte == 1 begin
var622_ubyte = 1
else if var621_ubyte > 1 begin
var622_ubyte = 2
else if var621_ubyte == 1 begin
var622_ubyte = 1
else if var616_ubyte > 1 begin
var622_ubyte = 2
else if var616_ubyte == 1 begin
var622_ubyte = 1
else
var599_ubyte = 32
end
end
ret(8)
-
Translate to expression tree / IL Code / Custom execution logic ⬛⬛⬛⬛⬛⬛⬛⬜⬜⬜ 60% The easiest way to execute code without creating your own state machine is to translate instructions into IL code or Expressions. But to support such a thing is difficult. If we choose this path, it is necessary to cover each expression with tests. But we can use Roslyn, after generating a C# code, and then parsing it.
-
Parsing of scripts ⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜ 0% To support modifications, it is necessary to learn how to parse the text representation of scripts, which is easy for players to edit. If we can use .NET Core and Roslyn, the easiest way is to write scripts in C# and parse them as Syntax Tree.
-
Testing ⬛⬛⬛⬛⬜⬜⬜⬜⬜⬜ 40% The current version enumerates all fileds and generates pseudo-code for them. There is one known bug that I am going to fix soon. In the future, it is necessary to cover with tests all the mechanisms for working with JSM, in order to eliminate bugs in this segment. Analyzing errors in it is VERY difficult.
Issue Analytics
- State:
- Created 4 years ago
- Comments:12

Top Related StackOverflow Question
Instructions successfully combined into blocks. I caught all the obvious mistakes, but I could not notice anything. We’ll have to test in the future.
The next task is to bring this into a readable form.
Version 3:
Fixed, now conditional blocks correctly check conditions before execution!
In addition, I fixed one rare formatting error.
Now successfully executed (of course, with stubs instead of some actions) 57 out of 72 scripts in the bghoke_2 location.
I think I will check the rest tomorrow and start to upload the changes. Due to unforeseen problems, the dates went a bit, so I plan to finish at the end of this week.