Author Topic: Project looking for Programmer (I can't do it myself)  (Read 18426 times)

0 Members and 1 Guest are viewing this topic.

Offline Daniel3D

  • Newbie
  • Posts: 62
Re: Project looking for Programmer (I can't do it myself)
« Reply #60 on: October 12, 2021, 03:55:12 pm »
@Daniel3D

Would you be able to share files for me to try installing your racing game on my INTEL i7 computer (bare metal mode via booting from usb stick and booting from 3.5" floppy)(DOSbox various builds via windows desktop icon)?

I would like to try
Bare metal on a modern system is tricky because they often don't have legacy support. Usually sound support is most difficult. So I hope it works, and I know some tricks that might help. Let me know.

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
Re: Project looking for Programmer (I can't do it myself)
« Reply #61 on: October 24, 2021, 03:36:14 pm »
Just to understand:
Quote
The sound and music are of a custom format.
I can't share that. I can share a sample of the music.

the game is abandoneware, so no copyright is hanging on it, is it?
Is there no kind of informations about the custom format?

About installer I believe in my solution: write a Qbasic version of Installer to get a 16bit version usind Qbasic/QUickBasic and a 32/64 bit version using QB64.

Freebasic... it supports 16bit compiling... but for what? Are how many machines with 16bit OSes in the world?
Thanks for talking
Programming isn't difficult, only it's  consuming time and coffee

Offline Daniel3D

  • Newbie
  • Posts: 62
Re: Project looking for Programmer (I can't do it myself)
« Reply #62 on: October 25, 2021, 03:56:32 am »
Just to understand:
the game is abandoneware, so no copyright is hanging on it, is it?
no copyright. We have had contact with the EA, but they don't seem to remember having it.
Also the original developers are quite supportive.
Quote
Is there no kind of informations about the custom format?
there is a lot of information about it. Even some adaptation for the engine sounds.
It is basally a stripped down version of midi with a file for the music (*.KMS) and a file for the instruments (*.VCE)
KMS stands for Kris Music System and VCE is a abbreviation of Voice.

Below links to technical information.
https://moddingwiki.shikadi.net/wiki/Kris%27_Music_System_Format
https://moddingwiki.shikadi.net/wiki/Kris%27_Music_System_Voice_Format
Kris himself doesn't have the tools for this format any more, and they are considered to be lost.

Quote
About installer I believe in my solution: write a Qbasic version of Installer to get a 16bit version usind Qbasic/QUickBasic and a 32/64 bit version using QB64.
That sounds good. I'm only asking for the 16bit installer, but the modern ones are welcome.

Quote
Freebasic... it supports 16bit compiling... but for what? Are how many machines with 16bit OSes in the world?

There are still DOS (and other old OS) users (8bit and 16bit systems).
One member of our community ran the game successfully on an emulated Amstrad PC1512 (8086, 8MHz, CGA graphics)
Not quick, but that is as low as it can go. So all software we make to compliment the game should have this in mind.
« Last Edit: October 25, 2021, 05:57:12 am by Daniel3D »

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
Re: Project looking for Programmer (I can't do it myself)
« Reply #63 on: October 25, 2021, 12:21:15 pm »
Wow
Quote
One member of our community ran the game successfully on an emulated Amstrad PC1512 (8086, 8MHz, CGA graphics)
to  reach this kind of user I think that the installer must be written in C64 Basic! In a way GWBASICA/QBASIC compatible... so the code gets the good/versatle position that I have stressed!
Programming isn't difficult, only it's  consuming time and coffee

Offline Daniel3D

  • Newbie
  • Posts: 62
Re: Project looking for Programmer (I can't do it myself)
« Reply #64 on: October 25, 2021, 04:09:17 pm »
Wowto  reach this kind of user I think that the installer must be written in C64 Basic! In a way GWBASICA/QBASIC compatible... so the code gets the good/versatle position that I have stressed!
I think you are right.

Can you do it?

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
Re: Project looking for Programmer (I can't do it myself)
« Reply #65 on: October 25, 2021, 07:11:18 pm »
@Daniel3D
Hi
I never have had used a C64 or another Commodore machine. Some decades ago I have had a C64 emulator, (CCS64) and so I have tried some games of that machine. I was never been able to do other that drop on CCS64 icon the game file to play.

However this seems to be interesting
https://www.c64-wiki.com/wiki/BASIC

http://www.mypccollection.altervista.org/downloads/manuali/Dos/Dos_GWbasic%20manual%20(eng).pdf

I started coding with QBasic, but for the task request it seems the same that GW BASIC.
I'll try to have time to spend on this idea with code.
Programming isn't difficult, only it's  consuming time and coffee

Offline Daniel3D

  • Newbie
  • Posts: 62
Re: Project looking for Programmer (I can't do it myself)
« Reply #66 on: October 26, 2021, 06:26:37 pm »
@Daniel3D
Hi
I never have had used a C64 or another Commodore machine. Some decades ago I have had a C64 emulator, (CCS64) and so I have tried some games of that machine. I was never been able to do other that drop on CCS64 icon the game file to play.

However this seems to be interesting
https://www.c64-wiki.com/wiki/BASIC

http://www.mypccollection.altervista.org/downloads/manuali/Dos/Dos_GWbasic%20manual%20(eng).pdf

I started coding with QBasic, but for the task request it seems the same that GW BASIC.
I'll try to have time to spend on this idea with code.
O shoot.
noob...
I meant in sight of processing power, not operating system. We can only modify the DOS version...
So only the DOS usable programs are needed.

It didn't register in my head that the Amstrad was not DOS based. even though i did know that.

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
Re: Project looking for Programmer (I can't do it myself)
« Reply #67 on: October 31, 2021, 02:44:59 pm »
Hi Daniel3D

about your goal to have an installer DOS compatible for STUNTS and its MODS stored in a subfolder GARAGE
The OS is DOS both on old machines, both on WMWare emulation and both DOSBOX enviroment.
So here is the QBasic installer for STUNTS developed at 90%.

From game downloaded from abandonware website posted at reply 16 of this thread
I see it has a flat one folder structure (the game and its files are in the same folder with no subfolder or extra folder) with about 210 files.
And now reading the following replies in the thread I see screenshots about the idea of your installer and the pseudocode

Quote
------------------------------------------
on run install
- ask source of the game #(can be the same as the current dir or different, does not matter | does not need to be checked)
  # Enter drive to install form:
  # EXAMPLE: A:\ 
 
- check if the source contains SKID*.exe files (there should be four of them, but check for any)
 
ask for destination,
  # Enter GAME directory
  # EXAMPLE c:\stunts\
 
Check if the destination exists.  Create or Ask to overwrite or change destination.
Don't check for enough space.
 
then copy files [source directory + subdirectories + all files]
(ESC to terminate, don't revert, just stop)
show, install complete box Return to menu on enter.
-----------------------------------------------

Well I can say I got in different way the results.

Moreover you have posted  TREESTUNT.TXT in which you show that all Mods are in a subfolder called GARAGE. Good it makes easier to localize Mods.

I have tried to run in DOSBOX the sgar.exe posted into .ZIP as compiled of installer freebasic version, but I got error that you can see in screenshot after.
  [ You are not allowed to view this attachment ]  

Looking at code I see that it manages the Mods and let choose to the user what Mod to install and what not.
If you think to have a similar option, it is better to have an unique way to distinguish and to store Mods.

Anyway here the code for installer and Setup

  [ You are not allowed to view this attachment ]  
  [ You are not allowed to view this attachment ]  
  [ You are not allowed to view this attachment ]  
  [ You are not allowed to view this attachment ]  
Code: QB64: [Select]
  1. DECLARE SUB UpdateRunFile ()
  2. DECLARE SUB SaveConfig ()
  3. DECLARE SUB LoadConfig ()
  4. DECLARE SUB UpdateOp (oplist$, num%, opval$, length%)
  5. DECLARE FUNCTION Menu% (m AS ANY, mm$, ini%)
  6. declare sub header
  7.  
  8.  
  9. Type MenuType
  10.     x As Integer
  11.     y As Integer
  12.     c1 As Integer
  13.     c2 As Integer
  14.     w As Integer
  15.  
  16. Dim Shared men(1 To 5) As MenuType, ment$(1 To 5), ErrMsg$(1 To 3), CurErr%
  17. Dim Shared videoid$(1 To 5), soundid$(1 To 6), curvideo%, cursound%
  18. Dim Shared runfile$, SourcePath$, DestPath$, DummyCurpath%, DefaultSourcePath$, DefaultDestinationpath$
  19.  
  20. runfile$ = "STUNTS.BAT"
  21. Defaultsourcepat$ = ".\"
  22. DefaultDestinationpath$ = "c:\cs11"
  23. SourcePath$ = ".\"
  24. DestPath$ = "c:\cs11"
  25. DummyCurpath% = 1
  26.  
  27. videoid$(1) = "MCGA"
  28. videoid$(2) = "EGA"
  29. videoid$(3) = "Tandy"
  30. videoid$(4) = "Hercules"
  31. videoid$(5) = "CGA"
  32. curvideo% = 1
  33.  
  34. soundid$(1) = "No sound"
  35. soundid$(2) = "PC Speaker"
  36. soundid$(3) = "Tandy"
  37. soundid$(4) = "Ad Lib"
  38. soundid$(5) = "Sound Blaster"
  39. soundid$(6) = "MT-32"
  40. cursound% = 1
  41.  
  42.  
  43. header
  44.  
  45. men(1).x = 4
  46. men(1).y = 7
  47. men(1).w = 40
  48. men(1).c1 = 7
  49. men(1).c2 = 4
  50. ment$(1) = "Video display`Sound option`Install game to ...`Exit"
  51.  
  52. men(2).x = 13
  53. men(2).y = 12
  54. men(2).w = 27
  55. men(2).c1 = 0
  56. men(2).c2 = 2
  57. ment$(2) = "MGCA/VGA graphics`EGA graphics`Tandy graphics`Hercules graphics`CGA graphics"
  58.  
  59. men(3).x = 11
  60. men(3).y = 12
  61. men(3).w = 34
  62. men(3).c1 = 0
  63. men(3).c2 = 2
  64. ment$(3) = "No music or sound effects`Internal PC speaker`Tandy sound`Ad Lib card`Sound Blaster card`Roland MT-32"
  65.  
  66.  
  67. men(4).x = 11
  68. men(4).y = 12
  69. men(4).w = 40
  70. men(4).c1 = 0
  71. men(4).c2 = 1
  72. ment$(4) = "Source path`Destination path`Install game`Install mods`Exit"
  73.  
  74.  
  75. men(5).x = 67
  76. men(5).y = 15
  77. men(5).w = 10
  78. men(5).c1 = 0
  79. men(5).c2 = 4
  80. ment$(5) = "Yes`No`Cancel"
  81.  
  82. ErrMsg$(1) = "Error: file of configuration not found"
  83. ErrMsg$(2) = "Error: file of original installation not found"
  84. ErrMsg$(3) = "Error: file of Mods installation not found"
  85. CurErr% = 0
  86.  
  87. GoSub Fileok
  88. LoadConfig
  89.  
  90. UpdateOp ment$(1), 1, videoid$(curvideo%), men(1).w - 2
  91. UpdateOp ment$(1), 2, soundid$(cursound%), men(1).w - 2
  92.  
  93. curmain% = 1
  94.     a% = Menu%(men(1), ment$(1), curmain%)
  95.     If a% <> -1 Then curmain% = a%
  96.     Select Case a%
  97.         Case -1 ' exiting by EScape key from menu
  98.             Color 7, 0
  99.             Cls
  100.             Print
  101.             Exit Do
  102.         Case 4
  103.             SaveConfig
  104.             UpdateRunFile
  105.             Color 7, 0
  106.             Cls
  107.             Print
  108.             Print "Configuration saved."
  109.             Exit Do
  110.         Case 1 'video display settings
  111.             PCopy 0, 1
  112.             a% = Menu%(men(2), ment$(2), curvideo%)
  113.             If a% <> -1 Then curvideo% = a%
  114.             UpdateOp ment$(1), 1, videoid$(curvideo%), men(1).w - 2
  115.             PCopy 1, 0
  116.         Case 2 ' sound options
  117.             PCopy 0, 1
  118.             a% = Menu%(men(3), ment$(3), cursound%)
  119.             If a% <> -1 Then cursound% = a%
  120.             UpdateOp ment$(1), 2, soundid$(cursound%), men(1).w - 2
  121.             PCopy 1, 0
  122.         Case 3 'install options....
  123.             ' here user can choose destination folder, source folder
  124.             ' installation of original game
  125.             ' adding mods
  126.             PCopy 0, 1
  127.             Do
  128.                 PCopy 0, 2
  129.                 b% = Menu%(men(4), ment$(4), DummyCurpath%)
  130.                 Select Case b%
  131.                     Case 1 ' source path
  132.                         ShowMessage 14, 0, 16, 19, 15, 56, 0, 3, "Caution you are changing default source path!"
  133.                         Locate 19, 20: Color 14, 0: Print "Actual path: "; SourcePath$
  134.                         Locate 20, 20: Input "Type here Source path: ", a$
  135.                         If a$ = "" Or a$ = SourcePath$ Then
  136.                             Locate 21, 20: Print " No new path": Sleep 1
  137.                         Else
  138.                             Locate 21, 20: Print "This is the new source path: "; UCase$(a$); " , do you confirm?"
  139.                             c% = Menu%(men(5), ment$(5), DummyCurpath%)
  140.                             If c% = 1 Then
  141.                                 SourcePath$ = a$
  142.                             ElseIf c% = 2 Then
  143.                                 ' nothing is changed
  144.                             End If
  145.                         End If
  146.  
  147.                     Case 2 ' destination path
  148.                         ShowMessage 14, 0, 16, 19, 10, 59, 0, 3, "Caution you are changing default destination path!"
  149.                         Locate 19, 20: Color 14, 0: Print "Actual path: "; DestPath$
  150.                         Locate 20, 20: Input "Type here Destination path: ", a$
  151.                         If a$ = "" Or a$ = DestPath$ Then
  152.                             Locate 21, 20: Print " No new path": Sleep 1
  153.                         Else
  154.                             Locate 21, 20: Print "This is the new destination path: "; UCase$(a$); " , do you confirm?"
  155.                             c% = Menu%(men(5), ment$(5), DummyCurpath%)
  156.                             If c% = 1 Then
  157.                                 DestPath$ = a$
  158.                             ElseIf c% = 2 Then
  159.                                 ' nothing is changed
  160.                             End If
  161.                         End If
  162.                     Case 3 ' game standard installation
  163.                         GoSub Fileok
  164.                         CurErr% = 2
  165.                         Open "filen" For Input As #1
  166.  
  167.                         CurErr% = 0
  168.                         On Error GoTo 0
  169.                     Case 4 ' mods installation
  170.  
  171.                         GoSub Fileok
  172.                         CurErr% = 3
  173.                         Open "filen" For Input As #1
  174.  
  175.  
  176.                         CurErr% = 0
  177.                         On Error GoTo 0
  178.  
  179.                     Case 5 ' return to option menu
  180.                         PCopy 2, 0
  181.                         Exit Do
  182.                 End Select
  183.                 PCopy 2, 0
  184.             Loop
  185.  
  186.     End Select
  187.  
  188. Print "Use " + UCase$(runfile$) + " to play Stunts"
  189.  
  190. Fileok:
  191. On Error GoTo nofile
  192. If CurErr% = 0 Then CurErr% = 1
  193.  
  194. nofile:
  195. If CurErr% = 2 Then k = 4 Else k = 0
  196. ShowMessage 14, 0, 16, 19, 20, 50 + k, 0, 3, ErrMsg$(CurErr%)
  197.  
  198.  
  199. Sub ShowMessage (Fcol, Bcol, Urow, Brow, FstCo, WidthMsg, sFcol, sBcol, Msg$)
  200.     'Subroutine to show a message on the ASCII screen and restore
  201.     ' the previous screen after message has been shown
  202.     ' Usage: SHOWMESSAGE Forwardcolor, Backgroundcolor, UpRow, BottomRow,FirstColumn, WidthMessagge,shadowForwardColor,shadowBackgroundColor, Message$
  203.     Dim z As Integer
  204.  
  205.     PCopy 0, 1
  206.     Color Fcol, Bcol
  207.     For z = Urow To Brow
  208.         Locate z, FstCo: Print Space$(WidthMsg);
  209.     Next z
  210.     Color sFcol, sBcol
  211.     For z = Urow + 1 To Brow
  212.         Locate z, FstCo + WidthMsg: Print "  ";
  213.     Next z
  214.  
  215.     Locate Brow + 1, FstCo + 2: Print Space$(WidthMsg);
  216.     Color Fcol, Bcol
  217.     Locate Urow + 1, FstCo + 5: Print Msg$
  218.     a$ = Input$(1)
  219.     PCopy 1, 0
  220.  
  221.  
  222. Sub LoadConfig
  223.     'Make sure the file exists
  224.     '  Open "setup.cfg" For Binary As 1: Close 1
  225.  
  226.     Open "setup.cfg" For Input As 1
  227.     Do Until EOF(1)
  228.         Line Input #1, a$
  229.         n% = InStr(a$, "=")
  230.         If n% Then
  231.             p$ = LCase$(LTrim$(RTrim$(Left$(a$, n% - 1))))
  232.             v$ = LTrim$(RTrim$(Mid$(a$, n% + 1)))
  233.  
  234.             Select Case p$
  235.                 Case "video"
  236.                     For i% = 1 To 5
  237.                         If LCase$(v$) = LCase$(videoid$(i%)) Then
  238.                             curvideo% = i%
  239.                             Exit For
  240.                         End If
  241.                     Next i%
  242.                 Case "sound"
  243.                     For i% = 1 To 6
  244.                         If LCase$(v$) = LCase$(soundid$(i%)) Then
  245.                             cursound% = i%
  246.                             Exit For
  247.                         End If
  248.                     Next i%
  249.                 Case "runfile"
  250.                     runfile$ = Left$(v$, 12)
  251.             End Select
  252.         End If
  253.     Loop
  254.     Close 1
  255.  
  256. Function Menu% (m As MenuType, mm$, ini%)
  257.     Dim mop$(1 To 20), mops As Integer
  258.  
  259.     mt$ = mm$
  260.     Do Until Len(mt$) = 0
  261.         mops = mops + 1
  262.         n% = InStr(mt$, "`")
  263.         If n% Then
  264.             mop$(mops) = Left$(mt$, n% - 1)
  265.             mt$ = Mid$(mt$, n% + 1)
  266.         Else
  267.             mop$(mops) = mt$
  268.             mt$ = ""
  269.         End If
  270.     Loop
  271.  
  272.     Color m.c1, m.c2
  273.     Locate m.y, m.x
  274.     Print "Ú" + String$(m.w, 196) + "¿";
  275.     For i% = m.y + 1 To m.y + mops
  276.         Locate i%, m.x
  277.         Print "³ " + mop$(i% - m.y) + Space$(m.w - Len(mop$(i% - m.y)) - 1) + "³";
  278.     Next i%
  279.     Locate m.y + mops + 1, m.x
  280.     Print "À" + String$(m.w, 196) + "Ù";
  281.     Color 8, 0
  282.     For i% = m.y + 1 To m.y + mops + 1
  283.         Locate i%, m.x + m.w + 2
  284.         Print "  ";
  285.     Next i%
  286.     Locate i%, m.x + 2
  287.     Print Space$(m.w + 2);
  288.  
  289.     cur% = ini%
  290.     ex% = 1
  291.     Update% = -1
  292.     Do
  293.         If Update% Then
  294.             Color m.c1, m.c2
  295.             Locate m.y + ex%, m.x + 1
  296.             Print " " + mop$(ex%) + Space$(m.w - Len(mop$(ex%)) - 1);
  297.             Color 0, 7
  298.             Locate m.y + cur%, m.x + 1
  299.             Print " " + mop$(cur%) + Space$(m.w - Len(mop$(cur%)) - 1);
  300.             ex% = cur%
  301.             Update% = 0
  302.         End If
  303.  
  304.         akey$ = InKey$
  305.         Select Case akey$
  306.             Case Chr$(0) + Chr$(72)
  307.                 If cur% > 1 Then
  308.                     cur% = cur% - 1
  309.                 Else
  310.                     cur% = mops
  311.                 End If
  312.                 Update% = -1
  313.             Case Chr$(0) + Chr$(80)
  314.                 If cur% < mops Then
  315.                     cur% = cur% + 1
  316.                 Else
  317.                     cur% = 1
  318.                 End If
  319.                 Update% = -1
  320.             Case Chr$(13)
  321.                 Exit Do
  322.             Case Chr$(27)
  323.                 cur% = -1
  324.                 Exit Do
  325.         End Select
  326.     Loop
  327.  
  328.     Menu% = cur%
  329.  
  330. Sub SaveConfig
  331.     Open "setup.cfg" For Output As 1
  332.     Print #1, "video=" + videoid$(curvideo%)
  333.     Print #1, "sound=" + soundid$(cursound%)
  334.     Print #1, "runfile=" + runfile$
  335.     Close 1
  336.  
  337. Sub UpdateOp (oplist$, num%, opval$, length%)
  338.     Dim op$(1 To 20)
  339.  
  340.     o$ = oplist$ ' oplist$ is a string of name of items of menu separated by ' except the last one
  341.     Do While Len(o$)
  342.         ops% = ops% + 1
  343.         n% = InStr(o$, "`")
  344.         If n% Then
  345.             op$(ops%) = Left$(o$, n% - 1)
  346.             o$ = Mid$(o$, n% + 1)
  347.         Else
  348.             op$(ops%) = o$
  349.             o$ = ""
  350.         End If
  351.     Loop
  352.  
  353.     For i% = Len(op$(num%)) To 1 Step -1
  354.         If Mid$(op$(num%), i%, 1) = "(" Then Exit For
  355.     Next i%
  356.  
  357.     If i% Then op$(num%) = RTrim$(Left$(op$(num%), i% - 1))
  358.  
  359.     op$(num%) = op$(num%) + Space$(length% - Len(op$(num%)) - Len(opval$) - 2)
  360.     op$(num%) = op$(num%) + "(" + opval$ + ")"
  361.  
  362.     o$ = ""
  363.     For i% = 1 To ops%
  364.         o$ = o$ + op$(i%)
  365.         If i% <> ops% Then o$ = o$ + "`"
  366.     Next i%
  367.  
  368.     oplist$ = o$
  369.  
  370. Sub UpdateRunFile
  371.     Open runfile$ For Output As 1
  372.     If videoid$(curvideo%) = "Tandy" Then
  373.         v$ = "TDY"
  374.     ElseIf videoid$(curvideo%) = "Hercules" Then
  375.         v$ = "HERC"
  376.     Else
  377.         v$ = videoid$(curvideo%)
  378.     End If
  379.  
  380.     Print #1, "@SKID" + v$ + ".EXE";
  381.  
  382.     Select Case cursound%
  383.         Case 1: Print #1, " /spc /ns"
  384.         Case 2: Print #1, " /spc"
  385.         Case 3: Print #1, " /std"
  386.         Case 4: Print #1, " /sad"
  387.         Case 5: Print #1, " /ssb"
  388.         Case 6: Print #1, " /smt"
  389.         Case Else: Print #1,
  390.     End Select
  391.     Close 1
  392.  
  393. Sub header
  394.     'Color 15, 7
  395.     Cls , 7
  396.     Color 0, 3
  397.     Locate 25, 1
  398.     Print Space$(4) + Chr$(24) + " " + Chr$(25) + " to move highlight, ENTER to select option, ESC to exit, F1 for help" + Space$(5);
  399.     Color 15, 1
  400.     Locate 2, 3: Print Space$(74);
  401.     Locate 3, 3: Print Space$(74);
  402.     Locate 4, 3: Print Space$(74);
  403.     Color 8, 0: Locate 5, 5: Print Space$(74)
  404.     Locate 3, 77: Print "  ";: Locate 4, 77: Print "  ";
  405.     Color 15, 1
  406.     Locate 2, 28: Print Chr$(34) + "Stunts" + Chr$(34) + " Setup Program";
  407.     Locate 3, 34: Print "Version 1.1";
  408.     Locate 4, 18: Print "Copyright (c) 2021 Stunts Online Community";
waiting your feedback I hope it would be useful.
Programming isn't difficult, only it's  consuming time and coffee

Offline Daniel3D

  • Newbie
  • Posts: 62
Re: Project looking for Programmer (I can't do it myself)
« Reply #68 on: November 08, 2021, 08:29:53 am »
Hi,
sorry for the late reply. Life happens sometimes.
It looks very good. Good menu structure. very close to what i have in mind.

About the mods. In principle all mods are installed in the game directory. The only exception is cars. They van be in the game dir or in the garage. The game has a 32 car limit, so the option to park them in the garage is needed.

A small alteration to the menu (but a maybe a lot of work, so optional. The way it is, is good enough)
Now you have
  • source
  • destination
  • install game
  • install mod.


Can you make it sequential?
  • instal game > enter source > enter destination
  • install mod > enter source > enter destination.


if you run it them after each other or the same one again, the earlier selected source and destination should be opted for that session.

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
Re: Project looking for Programmer (I can't do it myself)
« Reply #69 on: November 08, 2021, 12:37:37 pm »
Hi Daniel3D
fine to see your feedback.

1. about
Quote
Can you make it sequential?
instal game > enter source > enter destination
install mod > enter source > enter destination.
Q1: Moving voices of menu isn't so hard... but let's talk about source and destination paths:
I think that it must be a value of default for the path and the destination, moreover the user can change one or both the paths manually. If you like to memorize the last used paths it is possible to do. Or do you prefer to memorize only the last paths used?

Q2: you prefer a sequential method, user chooses what to install, user chooses from where, user chooses to where...
if no new path is entered user uses a previous path... so the question is
"Do you like to use the last previous path or the Default path?"

about
"Original STUNTS and MODs"

Q1:  is good for installation the version that I have got from abandonware site? (about 210 files) I have downloaded both the game both the manual for security answer.

Q2: on the website that you have linked before http://stunts.kalpen.de/stunts.htm there is also the last version 1.1, is there some substantial difference? And if yes, what is the final version of game that will be installed?

Q3: Are MOD's files grouped following a standard structure or no?
It is clear to me that cars are max 32 in the main directory, the rest are in the garage (folder garage) and a separate module to install only MODs is useful to change the set of 32 cars loaded into game.

waiting your Answers...
Programming isn't difficult, only it's  consuming time and coffee

Offline Daniel3D

  • Newbie
  • Posts: 62
Re: Project looking for Programmer (I can't do it myself)
« Reply #70 on: November 09, 2021, 06:00:53 am »
Hi Daniel3D
fine to see your feedback.

1. about Q1: Moving voices of menu isn't so hard... but let's talk about source and destination paths:
I think that it must be a value of default for the path and the destination, moreover the user can change one or both the paths manually. If you like to memorize the last used paths it is possible to do. Or do you prefer to memorize only the last paths used?
als default source i would take "A:\"
as default destination i would take "c:\"
For game installation it should add the game folder (STUNTS), i forgot to specify that.
It is a good idea to store that path as the current game folder. (in this scenario it would default to "C:\STUNTS\) in a file for later sessions
Quote
Q2: you prefer a sequential method, user chooses what to install, user chooses from where, user chooses to where...
if no new path is entered user uses a previous path... so the question is
"Do you like to use the last previous path or the Default path?"
The source should be default "a:\" but if this is changed within the session it should show the latest used first. But not stored after the session closes.
For install game again show the folder without \STUNTS\, if it is a know game directory, ask for overwrite.
For install mod show the folder with \STUNTS\
Quote

about
"Original STUNTS and MODs"

Q1:  is good for installation the version that I have got from abandonware site? (about 210 files) I have downloaded both the game both the manual for security answer.
Install game: installs the game as it is, including all mods that are there. Deinstallation of mods is something for later. Cars can be deinstalled, but placing them in the garage is sufficient. Deinstallation of cars will be implemented in the garage program.
Quote
Q2: on the website that you have linked before http://stunts.kalpen.de/stunts.htm there is also the last version 1.1, is there some substantial difference? And if yes, what is the final version of game that will be installed?
Honest answer, there might never be a final version. The tree.txt that I made contains the version that will be for now (except sgar that is a mod, and the garage dir contains modded cars that are not part of the official release). Included a cleaned up version of the game tree.
Quote
Q3: Are MOD's files grouped following a standard structure or no?
It is clear to me that cars are max 32 in the main directory, the rest are in the garage (folder garage) and a separate module to install only MODs is useful to change the set of 32 cars loaded into game.
Mod programs and files should be installed in the game dir.. Cars should go in the garage if present. The game doesn't break if more than 32 cars are in the game folder. It will only list the first 32.
Quote

waiting your Answers...
Thanks for the quick reply.

Offline Daniel3D

  • Newbie
  • Posts: 62
Re: Project looking for Programmer (I can't do it myself)
« Reply #71 on: November 09, 2021, 06:11:15 am »
Afther thought.
cars are grouped in 4 files. It would be noob friendly if it could detect cars and show the car name, or just the res filename as car name, and treat the 4 files as one.

I don't know the way to extract the car name from the res file. It is code in sgar.bas.
I kind of fear that if I'm too demanding in my wishes you might not want to do it any more..

EDIT:
I forgot that basic is easier to read than assembly. So I looked it up,
Code: [Select]
Sub ExtractCarName (c As Car, path As String)
If Len(c.file(1)) = 0 Then
c.carname = "Unknown"
Exit Sub
End If

Dim f As Integer, s As String, n As Short, l As Long

f = FreeFile
Open path & SLASH & c.file(1) For Binary Access Read As f
s = Space(100)
Get #f, , s
n = InStr(s, "gnam")
Get #f, n + 16, l
l += 39
s = Space(255)
Get #f, l, s
n = InStr(s, Chr(0))
If n Then s = Left(s, n - 1) Else s = Left(s, 40)
Close f

c.carname = s
End Sub
It starts from line 180 if you would like to see the context.
« Last Edit: November 09, 2021, 06:19:56 am by Daniel3D »

Offline Daniel3D

  • Newbie
  • Posts: 62
Re: Project looking for Programmer (I can't do it myself)
« Reply #72 on: November 12, 2021, 05:45:13 pm »
I have tried to run in DOSBOX the sgar.exe posted into .ZIP as compiled of installer freebasic version, but I got error that you can see in screenshot after.
  [ You are not allowed to view this attachment ]  
Sorry i missed this part
Dosbox removed support for this in a version for some reason. Easy to fix.
https://dosgames.com/utilities.php#extenders

Quote
Ever try to run a game and get an error like:
Load error: no DPMI - Get csdpmi*b.zip
You need a DPMI server, and the most popular is CWSDPMI. Unzip the CWSDMPI.EXE file into the game's directory and try running it again, it should work.

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
Re: Project looking for Programmer (I can't do it myself)
« Reply #73 on: November 13, 2021, 07:22:29 pm »
Hi Daniel5D
here another step of development of STUNTS under DOS.

Code: QB64: [Select]
  1. ' 2021 11 13, Modifications to Installation menu
  2. ' 3 choices: install game, install mods, exit from installation
  3. DECLARE SUB UpdateRunFile ()
  4. DECLARE SUB SaveConfig ()
  5. DECLARE SUB LoadConfig ()
  6. DECLARE SUB UpdateOp (oplist$, num%, opval$, length%)
  7. DECLARE FUNCTION Menu% (m AS ANY, mm$, ini%)
  8. declare sub header
  9. declare sub changepath (kind as integer)
  10.  
  11. Type MenuType
  12.     x As Integer
  13.     y As Integer
  14.     c1 As Integer
  15.     c2 As Integer
  16.     w As Integer
  17.  
  18. Const Spath = "A:\", Dpath = "C:\STUNTS", Source = 1, Destination = 2
  19. Const MainWin = 1, InstallWin = 2, MsgWin = 7
  20. Dim Shared men(1 To 5) As MenuType, ment$(1 To 5), ErrMsg$(1 To 3), CurErr%
  21. Dim Shared videoid$(1 To 5), soundid$(1 To 6), curvideo%, cursound%, Mpath$(1 To 5, 1 To 2)
  22. Dim Shared runfile$, SourcePath$, DestPath$, DummyCurpath%, DefaultSourcePath$, DefaultDestinationpath$
  23.  
  24. runfile$ = "STUNTS.BAT"
  25. Defaultsourcepat$ = Spath
  26. DefaultDestinationpath$ = Dpath
  27. SourcePath$ = ".\"
  28. DestPath$ = "c:\cs11"
  29. DummyCurpath% = 1
  30.  
  31. videoid$(1) = "MCGA"
  32. videoid$(2) = "EGA"
  33. videoid$(3) = "Tandy"
  34. videoid$(4) = "Hercules"
  35. videoid$(5) = "CGA"
  36. curvideo% = 1
  37.  
  38. soundid$(1) = "No sound"
  39. soundid$(2) = "PC Speaker"
  40. soundid$(3) = "Tandy"
  41. soundid$(4) = "Ad Lib"
  42. soundid$(5) = "Sound Blaster"
  43. soundid$(6) = "MT-32"
  44. cursound% = 1
  45.  
  46.  
  47. header
  48.  
  49. men(1).x = 4
  50. men(1).y = 7
  51. men(1).w = 40
  52. men(1).c1 = 7
  53. men(1).c2 = 4
  54. ment$(1) = "Video display`Sound option`Install game to ...`Exit"
  55.  
  56. men(2).x = 13
  57. men(2).y = 12
  58. men(2).w = 27
  59. men(2).c1 = 0
  60. men(2).c2 = 2
  61. ment$(2) = "MGCA/VGA graphics`EGA graphics`Tandy graphics`Hercules graphics`CGA graphics"
  62.  
  63. men(3).x = 11
  64. men(3).y = 12
  65. men(3).w = 34
  66. men(3).c1 = 0
  67. men(3).c2 = 2
  68. ment$(3) = "No music or sound effects`Internal PC speaker`Tandy sound`Ad Lib card`Sound Blaster card`Roland MT-32"
  69.  
  70.  
  71. men(4).x = 11
  72. men(4).y = 12
  73. men(4).w = 40
  74. men(4).c1 = 0
  75. men(4).c2 = 1
  76. ment$(4) = "Install game`Install mods`Exit"
  77.  
  78.  
  79. men(5).x = 67
  80. men(5).y = 15
  81. men(5).w = 10
  82. men(5).c1 = 0
  83. men(5).c2 = 4
  84. ment$(5) = "Yes`No`Cancel"
  85.  
  86. ErrMsg$(1) = "Error: file of configuration not found"
  87. ErrMsg$(2) = "Error: file of original installation not found"
  88. ErrMsg$(3) = "Error: file of Mods installation not found"
  89. CurErr% = 0
  90.  
  91. Mpath$(1, Source) = "Caution you are changing default source path!"
  92. Mpath$(2, Source) = "Type here source path: "
  93. Mpath$(3, Source) = "This is the new source path: "
  94.  
  95. Mpath$(1, Destination) = "Caution you are changing default destination path!"
  96. Mpath$(2, Destination) = "Type here destination path: "
  97. Mpath$(3, Destination) = "This is the new destination path: "
  98.  
  99.  
  100. GoSub Fileok
  101. LoadConfig
  102.  
  103. UpdateOp ment$(1), 1, videoid$(curvideo%), men(1).w - 2
  104. UpdateOp ment$(1), 2, soundid$(cursound%), men(1).w - 2
  105.  
  106. curmain% = 1
  107.     a% = Menu%(men(1), ment$(1), curmain%)
  108.     If a% <> -1 Then curmain% = a%
  109.     Select Case a%
  110.         Case -1 ' exiting by EScape key from menu
  111.             Color 7, 0
  112.             Cls
  113.             Print
  114.             Exit Do
  115.         Case 4 'saving configuration
  116.             SaveConfig
  117.             UpdateRunFile
  118.             Color 7, 0
  119.             Cls
  120.             Print
  121.             Print "Configuration saved."
  122.             Exit Do
  123.         Case 1 'video display settings
  124.             PCopy 0, MainWin
  125.             a% = Menu%(men(2), ment$(2), curvideo%)
  126.             If a% <> -1 Then curvideo% = a%
  127.             UpdateOp ment$(1), 1, videoid$(curvideo%), men(1).w - 2
  128.             PCopy MainWin, 0
  129.         Case 2 ' sound options
  130.             PCopy 0, MainWin
  131.             a% = Menu%(men(3), ment$(3), cursound%)
  132.             If a% <> -1 Then cursound% = a%
  133.             UpdateOp ment$(1), 2, soundid$(cursound%), men(1).w - 2
  134.             PCopy MainWin, 0
  135.         Case 3 'install options....
  136.             ' here user can choose  installation of original game
  137.             ' adding mods
  138.             ' after doing this he can choose destination folder, source folder
  139.             PCopy 0, MainWin
  140.             Do
  141.  
  142.                 b% = Menu%(men(4), ment$(4), DummyCurpath%)
  143.                 PCopy 0, InstallWin
  144.                 Select Case b%
  145.                     Case 1 ' game standard installation
  146.                         ChangePath Source
  147.                         PCopy InstallWin, 0
  148.                         ChangePath Destination
  149.                         GoSub Fileok
  150.                         CurErr% = 2
  151.                         '       Open "filen" For Input As #1
  152.  
  153.                         CurErr% = 0
  154.                         On Error GoTo 0
  155.                         PCopy InstallWin, 0
  156.  
  157.  
  158.                     Case 2 ' mods installation
  159.                         ChangePath Source
  160.                         PCopy InstallWin, 0
  161.                         ChangePath Destination
  162.  
  163.                         GoSub Fileok
  164.                         CurErr% = 3
  165.                         '  Open "filen" For Input As #1
  166.  
  167.  
  168.                         CurErr% = 0
  169.                         On Error GoTo 0
  170.                         PCopy InstallWin, 0
  171.  
  172.                     Case 3 ' return to option menu
  173.                         PCopy MainWin, 0
  174.                         Exit Do
  175.  
  176.                 End Select
  177.  
  178.             Loop
  179.  
  180.     End Select
  181.  
  182. Print "Use " + UCase$(runfile$) + " to play Stunts"
  183.  
  184. Fileok:
  185. On Error GoTo nofile
  186. If CurErr% = 0 Then CurErr% = 1
  187.  
  188. nofile:
  189. If CurErr% = 2 Then k = 4 Else k = 0
  190. ShowMessage 14, 0, 16, 19, 20, 50 + k, 0, 3, ErrMsg$(CurErr%)
  191.  
  192. Sub ChangePath (Mtype As Integer)
  193.     If Mtype = Source Then Apath$ = SourcePath$ Else Apath$ = DestPath$
  194.     ShowMessage 14, 0, 16, 19, 15, 56, 0, 3, Mpath$(1, Mtype)
  195.     Locate 19, 20: Color 14, 0: Print "Actual path: "; Apath$
  196.     Locate 20, 20:
  197.     If Mtype = Source Then
  198.         Input "Type here source path: ", a$
  199.     ElseIf Mtype = Destination Then
  200.         Input "Type here destination path: ", a$
  201.     End If
  202.  
  203.     If a$ = "" Or a$ = Apath$ Then
  204.         Locate 21, 20: Print " No new path": Sleep 1
  205.     Else
  206.         Locate 21, 20: Print Mpath$(3, Mtype); UCase$(a$); " , do you confirm?"
  207.         c% = Menu%(men(5), ment$(5), DummyCurpath%)
  208.         If c% = 1 Then
  209.             Apath$ = a$
  210.             If Mtype = Source Then SourcePath$ = Apath$ Else DestPath$ = Apath$
  211.         ElseIf c% = 2 Then
  212.             ' nothing is changed
  213.         End If
  214.     End If
  215.  
  216.  
  217.  
  218. Sub ShowMessage (Fcol, Bcol, Urow, Brow, FstCo, WidthMsg, sFcol, sBcol, Msg$)
  219.     'Subroutine to show a message on the ASCII screen and restore
  220.     ' the previous screen after message has been shown
  221.     ' Usage: SHOWMESSAGE Forwardcolor, Backgroundcolor, UpRow, BottomRow,FirstColumn, WidthMessagge,shadowForwardColor,shadowBackgroundColor, Message$
  222.     Dim z As Integer
  223.  
  224.     PCopy 0, MsgWin
  225.     Color Fcol, Bcol
  226.     For z = Urow To Brow
  227.         Locate z, FstCo: Print Space$(WidthMsg);
  228.     Next z
  229.     Color sFcol, sBcol
  230.     For z = Urow + 1 To Brow
  231.         Locate z, FstCo + WidthMsg: Print "  ";
  232.     Next z
  233.  
  234.     Locate Brow + 1, FstCo + 2: Print Space$(WidthMsg);
  235.     Color Fcol, Bcol
  236.     Locate Urow + 1, FstCo + 5: Print Msg$
  237.     Sleep 2
  238.     PCopy MsgWin, 0
  239.  
  240. Sub LoadConfig
  241.     'Make sure the file exists
  242.     '  Open "setup.cfg" For Binary As 1: Close 1
  243.  
  244.     Open "setup.cfg" For Input As 1
  245.     Do Until EOF(1)
  246.         Line Input #1, a$
  247.         n% = InStr(a$, "=")
  248.         If n% Then
  249.             p$ = LCase$(LTrim$(RTrim$(Left$(a$, n% - 1))))
  250.             v$ = LTrim$(RTrim$(Mid$(a$, n% + 1)))
  251.  
  252.             Select Case p$
  253.                 Case "video"
  254.                     For i% = 1 To 5
  255.                         If LCase$(v$) = LCase$(videoid$(i%)) Then
  256.                             curvideo% = i%
  257.                             Exit For
  258.                         End If
  259.                     Next i%
  260.                 Case "sound"
  261.                     For i% = 1 To 6
  262.                         If LCase$(v$) = LCase$(soundid$(i%)) Then
  263.                             cursound% = i%
  264.                             Exit For
  265.                         End If
  266.                     Next i%
  267.                 Case "runfile"
  268.                     runfile$ = Left$(v$, 12)
  269.             End Select
  270.         End If
  271.     Loop
  272.     Close 1
  273.  
  274. Function Menu% (m As MenuType, mm$, ini%)
  275.     Dim mop$(1 To 20), mops As Integer
  276.  
  277.     mt$ = mm$
  278.     Do Until Len(mt$) = 0
  279.         mops = mops + 1
  280.         n% = InStr(mt$, "`")
  281.         If n% Then
  282.             mop$(mops) = Left$(mt$, n% - 1)
  283.             mt$ = Mid$(mt$, n% + 1)
  284.         Else
  285.             mop$(mops) = mt$
  286.             mt$ = ""
  287.         End If
  288.     Loop
  289.  
  290.     Color m.c1, m.c2
  291.     Locate m.y, m.x
  292.     Print "Ú" + String$(m.w, 196) + "¿";
  293.     For i% = m.y + 1 To m.y + mops
  294.         Locate i%, m.x
  295.         Print "³ " + mop$(i% - m.y) + Space$(m.w - Len(mop$(i% - m.y)) - 1) + "³";
  296.     Next i%
  297.     Locate m.y + mops + 1, m.x
  298.     Print "À" + String$(m.w, 196) + "Ù";
  299.     Color 8, 0
  300.     For i% = m.y + 1 To m.y + mops + 1
  301.         Locate i%, m.x + m.w + 2
  302.         Print "  ";
  303.     Next i%
  304.     Locate i%, m.x + 2
  305.     Print Space$(m.w + 2);
  306.  
  307.     cur% = ini%
  308.     ex% = 1
  309.     Update% = -1
  310.     Do
  311.         If Update% Then
  312.             Color m.c1, m.c2
  313.             Locate m.y + ex%, m.x + 1
  314.             Print " " + mop$(ex%) + Space$(m.w - Len(mop$(ex%)) - 1);
  315.             Color 0, 7
  316.             Locate m.y + cur%, m.x + 1
  317.             Print " " + mop$(cur%) + Space$(m.w - Len(mop$(cur%)) - 1);
  318.             ex% = cur%
  319.             Update% = 0
  320.         End If
  321.  
  322.         akey$ = InKey$
  323.         Select Case akey$
  324.             Case Chr$(0) + Chr$(72)
  325.                 If cur% > 1 Then
  326.                     cur% = cur% - 1
  327.                 Else
  328.                     cur% = mops
  329.                 End If
  330.                 Update% = -1
  331.             Case Chr$(0) + Chr$(80)
  332.                 If cur% < mops Then
  333.                     cur% = cur% + 1
  334.                 Else
  335.                     cur% = 1
  336.                 End If
  337.                 Update% = -1
  338.             Case Chr$(13)
  339.                 Exit Do
  340.             Case Chr$(27)
  341.                 cur% = -1
  342.                 Exit Do
  343.         End Select
  344.     Loop
  345.  
  346.     Menu% = cur%
  347.  
  348. Sub SaveConfig
  349.     Open "setup.cfg" For Output As 1
  350.     Print #1, "video=" + videoid$(curvideo%)
  351.     Print #1, "sound=" + soundid$(cursound%)
  352.     Print #1, "runfile=" + runfile$
  353.     Close 1
  354.  
  355. Sub UpdateOp (oplist$, num%, opval$, length%)
  356.     Dim op$(1 To 20)
  357.  
  358.     o$ = oplist$ ' oplist$ is a string of name of items of menu separated by ' except the last one
  359.     Do While Len(o$)
  360.         ops% = ops% + 1
  361.         n% = InStr(o$, "`")
  362.         If n% Then
  363.             op$(ops%) = Left$(o$, n% - 1)
  364.             o$ = Mid$(o$, n% + 1)
  365.         Else
  366.             op$(ops%) = o$
  367.             o$ = ""
  368.         End If
  369.     Loop
  370.  
  371.     For i% = Len(op$(num%)) To 1 Step -1
  372.         If Mid$(op$(num%), i%, 1) = "(" Then Exit For
  373.     Next i%
  374.  
  375.     If i% Then op$(num%) = RTrim$(Left$(op$(num%), i% - 1))
  376.  
  377.     op$(num%) = op$(num%) + Space$(length% - Len(op$(num%)) - Len(opval$) - 2)
  378.     op$(num%) = op$(num%) + "(" + opval$ + ")"
  379.  
  380.     o$ = ""
  381.     For i% = 1 To ops%
  382.         o$ = o$ + op$(i%)
  383.         If i% <> ops% Then o$ = o$ + "`"
  384.     Next i%
  385.  
  386.     oplist$ = o$
  387.  
  388. Sub UpdateRunFile
  389.     Open runfile$ For Output As 1
  390.     If videoid$(curvideo%) = "Tandy" Then
  391.         v$ = "TDY"
  392.     ElseIf videoid$(curvideo%) = "Hercules" Then
  393.         v$ = "HERC"
  394.     Else
  395.         v$ = videoid$(curvideo%)
  396.     End If
  397.  
  398.     Print #1, "@SKID" + v$ + ".EXE";
  399.  
  400.     Select Case cursound%
  401.         Case 1: Print #1, " /spc /ns"
  402.         Case 2: Print #1, " /spc"
  403.         Case 3: Print #1, " /std"
  404.         Case 4: Print #1, " /sad"
  405.         Case 5: Print #1, " /ssb"
  406.         Case 6: Print #1, " /smt"
  407.         Case Else: Print #1,
  408.     End Select
  409.     Close 1
  410.  
  411. Sub header
  412.     'Color 15, 7
  413.     Cls , 7
  414.     Color 0, 3
  415.     Locate 25, 1
  416.     Print Space$(4) + Chr$(24) + " " + Chr$(25) + " to move highlight, ENTER to select option, ESC to exit, F1 for help" + Space$(5);
  417.     Color 15, 1
  418.     Locate 2, 3: Print Space$(74);
  419.     Locate 3, 3: Print Space$(74);
  420.     Locate 4, 3: Print Space$(74);
  421.     Color 8, 0: Locate 5, 5: Print Space$(74)
  422.     Locate 3, 77: Print "  ";: Locate 4, 77: Print "  ";
  423.     Color 15, 1
  424.     Locate 2, 28: Print Chr$(34) + "Stunts" + Chr$(34) + " Setup Program";
  425.     Locate 3, 34: Print "Version 1.1";
  426.     Locate 4, 18: Print "Copyright (c) 2021 Stunts Online Community";
  427.  
Just to go on:
you must post here a definitive list of original (NO MODS)  files of the game Stunts.
as you can see from screenshot below there are some differences between you list TREESTU1.TXT and my list
LIST.TXT made on a folder of stunts got from abandonware.

  [ You are not allowed to view this attachment ]  

To solve DOSBOX issue to run sgar, for now it doesn't matter.
Waiting your answer....
Programming isn't difficult, only it's  consuming time and coffee

Offline Daniel3D

  • Newbie
  • Posts: 62
Re: Project looking for Programmer (I can't do it myself)
« Reply #74 on: November 15, 2021, 04:32:27 am »
The point of the whole new setup and installer is just what you see.
We compiled the executables again to be more original then the original release. (It was originally released with a space saving modification that hurts performance)
So there is a difference between your original and the new original.
TREESTU1 is the correct file list.

Additionally, your copy from abandon ware is not original either. Many trk files are player generated content.

The HDR and COD files are integrated into the executables now. Stunts.com and load.exe have been replaced.
« Last Edit: November 15, 2021, 06:37:10 am by Daniel3D »