Jump to content


  • Content count

  • Joined

  • Last visited

Community Reputation

7 Neutral

About xxOToTOxx

  • Rank
    Insert Coins

Profile Information

  • Hardware
    Linux PC, daphne, singe
  1. For any Linux users out there, there are a lack of GUI frontends for firing up these games. Began playing with GTK, and created some basic launchers here: [Hidden Content] Version 2 - layout based around DaphneLoader by Matt Ownby. If there is sufficient interest, I may extend.
  2. The singe.sh scripts accepts 4:3 ratios via the x,y variables at the base and resizing via SDL. I have run at 1600x1200 and 2048x1536 but image, of course, depends on source video quality and upscaling. Unless I am barking up the wrong tree....? Site won't seem to let me upload images at these resolutions, although only 800k....
  3. Hi, Looking back at this project, seems to stem from Singe 1.18, a fork of daphne plugin to run as a standalone. I hadn't come across this later release, so used it to commit a Github project. I think Singe2 may be be going a different route, but 1.18 has all the current singe games running that I have tried after applying some of the caveats learnt here. There are various changes listed in the changelog, including multiple mouse support, but primary fix I saw benefit from was the fix of some Alpha Blending issues. Giithub here: [Hidden Content]
  4. So starting to play around with the exposed LUA now, and annoyed by the 90 second Copyright notice at the beginning of each game, attempted to bypass it. Edit: This timing issue turned out to be a 32=>64 bit transition bug in the Lua os.clock() function - I fixed it in the singe 1.18 github repository: [Hidden Content] Note: The nil arithmetic bug still existed. The .singe bytecode files with fixed arithmetic checks are available in the above repo also. ..
  5. Code may be obfuscated due to contractual obligations, seems a normal, if not futile, practice: [Hidden Content] [Hidden Content] Cheers guys for all the help and testing.
  6. And a final observation for this evening, looking in the timegal.cfg file we see references to random variable keys names (have always been there): Fjfivmsr = 1 dfjejcnt = 3 dftfkjdd = 1 frebasao = 1 Kfitjgoi = 2 kUtReche = 0 frjrjfis = 1 ftkoeqxz = 1 xandswSU = 0 UJdktu1h = 2 These variables can now be seen in the decompiled timegal.singe file, so it would appear the weird random variable/key names now seen in this file are deliberate (or at least a result of the programming editor) and not just a consequence of the decompilation: egrep "Fjfivmsr|dfjejcnt|dftfkjdd|frebasao|Kfitjgoi|kUtReche|frjrjfis|ftkoeqxz|xandswSU|UJdktu1h" timegal.singe kUtReche = 0 kUtReche = tonumber(string.sub(s1, string.find(s1, "=") + 1)) io.write("Fjfivmsr = " .. jasAducr .. htwYFRwflXcVZa) io.write("dfjejcnt = " .. TugAphAt .. htwYFRwflXcVZa) io.write("dftfkjdd = 1" .. htwYFRwflXcVZa) io.write("dftfkjdd = 0" .. htwYFRwflXcVZa) io.write("frebasao = 1" .. htwYFRwflXcVZa) io.write("frebasao = 0" .. htwYFRwflXcVZa) io.write("Kfitjgoi = " .. PrurEmet .. htwYFRwflXcVZa) io.write("kUtReche = " .. kUtReche .. htwYFRwflXcVZa) io.write("frjrjfis = 1" .. htwYFRwflXcVZa) io.write("frjrjfis = 0" .. htwYFRwflXcVZa) io.write("ftkoeqxz = " .. yejuwaZu .. htwYFRwflXcVZa) io.write("xandswSU = " .. xanEcerU .. htwYFRwflXcVZa) io.write("UJdktu1h = " .. Ninrh5727G1h .. htwYFRwflXcVZa) if kUtReche == frUgAyUc then kUtReche = VuJusTaf elseif kUtReche == VuJusTaf then kUtReche = CHavuces elseif kUtReche == CHavuces then kUtReche = frUgAyUc if kUtReche == frUgAyUc then elseif kUtReche == VuJusTaf then elseif kUtReche == CHavuces then if kUtReche == VuJusTaf then elseif kUtReche == frUgAyUc then elseif kUtReche == CHavuces then if kUtReche == frUgAyUc then elseif kUtReche == VuJusTaf or kUtReche == CHavuces then and if you wanted to move those images, wav files or video around, the resource file locations are all in there too... nApsVkTfOXgV[QgCoRDPbRamB] = spriteLoad("singe/timegal/arrowup.png") nApsVkTfOXgV[lUnMpiXJSxkc] = spriteLoad("singe/timegal/arrowdown.png") nApsVkTfOXgV[qcmsoajvEqJL] = spriteLoad("singe/timegal/arrowleft.png") nApsVkTfOXgV[UkmyOwfLuZIb] = spriteLoad("singe/timegal/arrowright.png") nApsVkTfOXgV[YlTFylGvhQwi] = spriteLoad("singe/timegal/action.png") nApsVkTfOXgV[hlKgmyktfKtJ] = spriteLoad("singe/timegal/button.png") nApsVkTfOXgV[qmoxQCiuZIoD] = spriteLoad("singe/timegal/selarrow.png") ZPehxjlAqzHd[1] = spriteLoad("singe/timegal/num00.png") ZPehxjlAqzHd[2] = spriteLoad("singe/timegal/num01.png") ZPehxjlAqzHd[3] = spriteLoad("singe/timegal/num02.png") ZPehxjlAqzHd[4] = spriteLoad("singe/timegal/num03.png") ZPehxjlAqzHd[5] = spriteLoad("singe/timegal/num04.png") ZPehxjlAqzHd[6] = spriteLoad("singe/timegal/num05.png") ZPehxjlAqzHd[7] = spriteLoad("singe/timegal/num06.png") ZPehxjlAqzHd[8] = spriteLoad("singe/timegal/num07.png") ZPehxjlAqzHd[9] = spriteLoad("singe/timegal/num08.png") ZPehxjlAqzHd[10] = spriteLoad("singe/timegal/num09.png") RdJFibnSBkWS = soundLoad("singe/timegal/ring01.wav") NavaKuJe = soundLoad("singe/timegal/credit.wav") KdjYEmnP = soundLoad("singe/timegal/select.wav") VAwCIUamyhPc = soundLoad("singe/timegal/ring02.wav") lxwiLXgSbkTi = soundLoad("singe/timegal/right.wav") DTpbktchqWbn = soundLoad("singe/timegal/wrong.wav") FIdmwBkQYBgZ = soundLoad("singe/timegal/blip.wav") QVOtAJoajSxj = soundLoad("singe/timegal/teedo.wav") pylnQfoXjSBq[1] = spriteLoad("singe/timegal/getready.png") pylnQfoXjSBq[2] = spriteLoad("singe/timegal/topscore.png") pylnQfoXjSBq[3] = spriteLoad("singe/timegal/insertcoin.png") pylnQfoXjSBq[4] = spriteLoad("singe/timegal/freeplay.png") pylnQfoXjSBq[5] = spriteLoad("singe/timegal/player1.png") pylnQfoXjSBq[6] = spriteLoad("singe/timegal/credit.png") pylnQfoXjSBq[7] = spriteLoad("singe/timegal/gal.png") pylnQfoXjSBq[8] = spriteLoad("singe/timegal/topscore.png") pylnQfoXjSBq[9] = spriteLoad("singe/timegal/line1.png") pylnQfoXjSBq[10] = spriteLoad("singe/timegal/line2.png") pylnQfoXjSBq[11] = spriteLoad("singe/timegal/line3.png") pylnQfoXjSBq[12] = spriteLoad("singe/timegal/line4.png") pylnQfoXjSBq[13] = spriteLoad("singe/timegal/line5.png") pylnQfoXjSBq[14] = spriteLoad("singe/timegal/line6.png") pylnQfoXjSBq[15] = spriteLoad("singe/timegal/line100.png") pylnQfoXjSBq[16] = spriteLoad("singe/timegal/line101.png") pylnQfoXjSBq[17] = spriteLoad("singe/timegal/line102.png") pylnQfoXjSBq[18] = spriteLoad("singe/timegal/line103.png") pylnQfoXjSBq[19] = spriteLoad("singe/timegal/line104.png") pylnQfoXjSBq[20] = spriteLoad("singe/timegal/line105.png") pylnQfoXjSBq[21] = spriteLoad("singe/timegal/line106.png") pylnQfoXjSBq[22] = spriteLoad("singe/timegal/line107.png") pylnQfoXjSBq[23] = spriteLoad("singe/timegal/line108.png") pylnQfoXjSBq[24] = spriteLoad("singe/timegal/line109.png") pylnQfoXjSBq[25] = spriteLoad("singe/timegal/line110.png") pylnQfoXjSBq[26] = spriteLoad("singe/timegal/line111.png") pylnQfoXjSBq[27] = spriteLoad("singe/timegal/line112.png") pylnQfoXjSBq[28] = spriteLoad("singe/timegal/line113.png") pylnQfoXjSBq[29] = spriteLoad("singe/timegal/line114.png") pylnQfoXjSBq[30] = spriteLoad("singe/timegal/line115.png") pylnQfoXjSBq[31] = spriteLoad("singe/timegal/line116.png") pylnQfoXjSBq[32] = spriteLoad("singe/timegal/line117.png") pylnQfoXjSBq[33] = spriteLoad("singe/timegal/question.png") Interesting exercise......
  7. SINGE is LUA script based, so all the games use LUA scripts. [Hidden Content] It just happened that these games used compiled LUA (bytecode), for reasons best known to the author....
  8. And a similar fix on Hayate: --- hayate.singe.decompiled 2019-12-13 21:38:54.094021727 +0000 +++ hayate.singe 2019-12-14 00:57:58.251435675 +0000 @@ -6849,7 +6849,10 @@ local TFXAtbKTzHng = "" TFXAtbKTzHng = tostring(yxqcFRAjsHNc) for k = 1, string.len(TFXAtbKTzHng) do - j = tonumber(string.sub(TFXAtbKTzHng, k, k)) + 1 + j = tonumber(string.sub(TFXAtbKTzHng, k, k)) + if (j ~= nil) then + j = j +1 + end spriteDraw(RpMQMSEkgsbX + (k - 1) * 8, mWplUnviqWlO, xQzPvLUcOxgc[j]) end end
  9. Success, I can confirm that these are decompiled files and work! The error: error running function 'onOverlayUpdate': /home/user/.daphne/singe/timegal/timegal.singe:7771: attempt to perform arithmetic on a nil value I fixed the issue in the decompiled timegal.singe file thus: --- timegal.singe.decompiled 2019-12-14 01:04:29.345452887 +0000 +++ timegal.singe 2019-12-14 00:54:28.698076588 +0000 @@ -7768,7 +7768,10 @@ local s1 = "" s1 = tostring(KqDPOaTfvHTF) for k = 1, string.len(s1) do - j = tonumber(string.sub(s1, k, k)) + 1 + j = tonumber(string.sub(s1, k, k)) + if (j ~= nil) then + j = j + 1 + end spriteDraw(IUWIbuJzinwL + (k - 1) * 8, DpPBXJViXgVH, ZPehxjlAqzHd[j]) end end And we have a running game....... Not certain, why this issue seems specific to my installation, but the change to the singe file seems sane in any case.....
  10. I feel like this forum is turning into my personal Blog, please let me know if these posts are deemed inappropriate. So, two more interesting discoveries... 1) Referring to my investigation above, I was able to get the current 64bit singe library to read the original 32bit byte code singe file via trivial changes described in this post: [Hidden Content] The game then read the original compiled bytecode timegal.singe and loaded the game. However, when attempting to start the game I got exactly the same error as I do with... 2) .. the decompiled Lua given by the Java based unluac.jar process. I can't get testing past this point, HOWEVER, this may indicate that the Java decompiler may in fact be correctly decompiling the Lua. Therefore, could I ask one of you guys who have a working Time Gal or Hayate to swap out the relevant .singe file from above and see if the game still does actually play ? If that is the case, then I know that the issue my side is actually the linux singe implementaion and not the singe files and we do in fact have working decompiled files........
  11. Hey Famawizard, Many thanks for that, looks like a really young project. I was looking at source code of current singe 64bit library to see if I could alter the method the .singe file is opened and read, to get around the 32bit issue. Wonder if/how this project is handling it.... One to watch.
  12. THIS DECOMPILER DOES NOT WORK CORRECTLY - USE Java BASED unluac.jar FOR SANE Lua CONVERSION,,,, OK, so getting to the end of what I believe is possible in decompiling these byte code. I managed to get a 32bit version of luadec from [Hidden Content] compiled which was able to read and 'decompile' the files. It generated considerably more output than the Java decompiler (links above), however seems to actually work less in SINGE. It also stated several errors in the output: -- DECOMPILER ERROR at PC394: Confused about usage of register: R2 in 'UnsetPending' I think reverse engineering these bytecode Lua files is going to go beyond my ability and available time at this point, I will however post the newest Lua singe files here on the off chance that someone else who knows more about Lua may take an interest. Removed: [Hidden Content] - timegal_v2.singe Removed: [Hidden Content] - hayate_v2.singe Rather annoying, as obfuscating these files, as was most probably the original purpose, has also restricted them to 32bit systems... Be nice if it was possible to grab the original source and open them up......
  13. Pause SINGE: Script Error! SINGE: error running function 'onOverlayUpdate': /home/sgp/.daphne/singe/timegal/timegal.singe:7771: attempt to perform arithmetic on a nil value SINGE: Script Error! Segmentation fault DaphneLoader failed with an unknown exit code : 139. SINGE: Script Error! SINGE: error running function 'onOverlayUpdate': /home/sgp/.daphne/singe/hayate/hayate.singe:6852: attempt to perform arithmetic on a nil value SINGE: Script Error! Segmentation fault DaphneLoader failed with an unknown exit code : 139. So same issue in both games...... do we have any LUA language aficionados here, they could perhaps shed some light.... I haven't programmed Lua before The game and intro video start, accepts coins but bombs out as you attempt to start game...... Would be nice to have a method to reverse engineer these bytecode singe files... Update: I have found the parent repo to the unluac.jar code, which has a newer version, but provides the same Lua script: [Hidden Content] Compiled jar with: hg clone [Hidden Content] cd hgcode/src mkdir build javac -verbose -deprecation -Werror -d build unluac/*.java cat manifest.txt Manifest-Version: 1.0 Main-Class: unluac.Main jar vcfm unluac.jar manifest.txt -C build/ . java -jar unluac.jar unluac v1.2.3.309 error: no input file provided usage: java -jar unluac.jar [options] <file> [Hidden Content] - unluac.jar v1.2.3.309 Cheers
  14. OK, then I have some interesting news..... [Hidden Content] [Hidden Content] mv timegal.singe timegal.luac java -jar unluac_2015_06_13.jar timegal.luac > timegal.singe Booting ROM ... Starting Singe version 1.14 Search to 65212 received [blocking] Play Successfully changed speed to 1/1X Search to 3 received [blocking] Play Pause Search to 59536 received [blocking] Play Successfully changed speed to 1/1X SINGE: Game Settings Loaded. SINGE: Initializing Time Gal Singe v1.1 Search to 35 received [blocking] Play Successfully changed speed to 1/1X Stop Freeing memory used to store audio stream... Shutting down sound system... Shutting down video display... It takes an age to boot, and the timegal.singe is looking a little muggled, but it runs......!!! Getting late here now, so will try and run game tomorrow..... Cheers