Advertisement
Kitomas

2024-07-19 (12/13)

Jul 19th, 2024
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 37.04 KB | None | 0 0
  1. /******************************************************************************/
  2. /******************************************************************************/
  3. //"kw32g\asset_scripts\convert_all_assets.py":
  4. #(DOES NOT CONVERT SCENE DATA!)
  5. #(ALSO DOESN'T TOUCH MUSIC, AS THAT DOESN'T NEED CONVERTING!)
  6.  
  7. #this program relies on its current working directory being exact,
  8. #which is not guaranteed if __name__ == '__main__'
  9. if __name__ != '__main__': exit(0)
  10.  
  11.  
  12.  
  13.  
  14. from time import time
  15. from os import getcwd, system as cmd
  16. from os.path import abspath, join
  17.  
  18.  
  19.  
  20.  
  21. timeStart = time()
  22.  
  23.  
  24. from _ambience   import convert_all_ambience
  25. from _background import convert_all_background
  26. from _img        import convert_all_img
  27. from _objimg     import convert_all_objimg
  28. from _sfx        import convert_all_sfx
  29. from _tileset    import convert_all_tileset
  30.  
  31. root = abspath(getcwd())
  32.  
  33. convert_all_ambience.main(   join(root, '_ambience'))
  34. convert_all_background.main( join(root, '_background'))
  35. convert_all_img.main(        join(root, '_img'))
  36. convert_all_objimg.main(     join(root, '_objimg'))
  37. convert_all_sfx.main(        join(root, '_sfx'))
  38. convert_all_tileset.main(    join(root, '_tileset'))
  39.  
  40.  
  41. print(f'ALL ASSETS CONVERTED IN {time()-timeStart} SECONDS')
  42. cmd('powershell -command pause')/******************************************************************************/
  43. /******************************************************************************/
  44. //"kw32g\asset_scripts\convert_all_background.py":
  45. _PRINT = True
  46. src_folder = '.\\_png\\'
  47. dst_folder = '.\\_qoi\\'
  48.  
  49. from time import time
  50. from os import system as cmd, walk, path, rename, chdir
  51. import subprocess
  52.  
  53.  
  54.  
  55. def tryInt(string):
  56.     try:
  57.         return int(string)
  58.     except ValueError:
  59.         return None
  60.     except TypeError:
  61.         return None
  62.  
  63.  
  64. def run_program(args, fatal=False):
  65.     if type(args) != list:
  66.         print('args must be of type list')
  67.         exit(-1)
  68.    
  69.     if _PRINT: print((' ').join(args))
  70.    
  71.     returnCode = subprocess.call(args, shell=True)
  72.     if returnCode >= 2**31: returnCode -= 2**32
  73.    
  74.     if fatal:
  75.         if returnCode != 0:
  76.             if _PRINT: print(f'failed to execute "{args}"')
  77.             exit(returnCode)
  78.         return True
  79.     else:
  80.         return returnCode == 0
  81.        
  82.  
  83. def tryCmd(s, ps=True):
  84.     if _PRINT: print(s)
  85.     if ps: cmd("powershell -command "+s)
  86.     else : cmd(s)
  87.    
  88.  
  89. def abspath(local_folder, file_name):
  90.     return path.abspath(path.join(local_folder,file_name))
  91.  
  92.  
  93.  
  94.    
  95.    
  96. def main(cwd = None):
  97.     if cwd != None: chdir(cwd)
  98.    
  99.     timeStart = time()
  100.  
  101.    
  102.     tryCmd(f'rm {dst_folder}*.*')
  103.     tryCmd(f'XCOPY /E /Y {src_folder} {dst_folder}')
  104.    
  105.  
  106.     #assumes there are no folders in .\_qoi\
  107.     files = []
  108.     for root, dirs, _files in walk(dst_folder):
  109.         files += _files
  110.        
  111.  
  112.     args = ['Super.QOI.converter.Console.exe']
  113.    
  114.     for file in files:
  115.         if file.split('.')[-1] != 'qoi':
  116.             args.append(abspath(dst_folder, file))
  117.    
  118.     #this qoi converter seems to be quite buggy, and it
  119.     #refuses to edit existing files without throwing an exception,
  120.     #so i need to tell it to not touch anything that already exists
  121.     args.append('-nc') #don't copy attr&dates; skip confirmation
  122.     args.append('-nd') #don't del originals; skip confirmation
  123.     args.append('-no') #don't overwrite output; skip confirmation
  124.        
  125.     run_program(args)
  126.    
  127.    
  128.     tryCmd(f'rm {dst_folder}*.png')
  129.    
  130.  
  131.     print(f'BACKGROUND CONVERTED IN {time()-timeStart} SECONDS')
  132.     if __name__ == '__main__':
  133.         tryCmd("pause")
  134.         exit(0)
  135.  
  136.  
  137.  
  138. if __name__ == '__main__': main()/******************************************************************************/
  139. /******************************************************************************/
  140. //"kw32g\asset_scripts\convert_all_img.py":
  141. _PRINT = True
  142. src_folder = '.\\_png\\'
  143. dst_folder = '.\\_qoi\\'
  144.  
  145. from time import time
  146. from os import system as cmd, walk, path, chdir
  147. import subprocess
  148.  
  149.  
  150.  
  151. def tryInt(string):
  152.     try:
  153.         return int(string)
  154.     except ValueError:
  155.         return None
  156.     except TypeError:
  157.         return None
  158.  
  159.  
  160. def run_program(args, fatal=False):
  161.     if type(args) != list:
  162.         print('args must be of type list')
  163.         exit(-1)
  164.    
  165.     if _PRINT: print((' ').join(args))
  166.    
  167.     returnCode = subprocess.call(args, shell=True)
  168.     if returnCode >= 2**31: returnCode -= 2**32
  169.    
  170.     if fatal:
  171.         if returnCode != 0:
  172.             if _PRINT: print(f'failed to execute "{args}"')
  173.             exit(-1)
  174.         return True
  175.     else:
  176.         return returnCode == 0
  177.        
  178.        
  179. def tryCmd(s, ps=True):
  180.     if _PRINT: print(s)
  181.     if ps: cmd("powershell -command "+s)
  182.     else : cmd(s)
  183.    
  184.  
  185. def abspath(local_folder, file_name):
  186.     return path.abspath(path.join(local_folder,file_name))
  187.  
  188.  
  189.  
  190.  
  191.    
  192.    
  193. def main(cwd = None):
  194.     if cwd != None: chdir(cwd)
  195.  
  196.     timeStart = time()
  197.  
  198.    
  199.     tryCmd(f'rm {dst_folder}*.*')
  200.     tryCmd(f'XCOPY /E /Y {src_folder} {dst_folder}')
  201.    
  202.  
  203.     #assumes there are no folders in .\_qoi\
  204.     files = []
  205.     for root, dirs, _files in walk(dst_folder):
  206.         files += _files
  207.        
  208.  
  209.     args = ['Super.QOI.converter.Console.exe']
  210.    
  211.     for file in files:
  212.         if file.split('.')[-1] != 'qoi':
  213.             args.append(abspath(dst_folder, file))
  214.    
  215.     #this qoi converter seems to be quite buggy, and it
  216.     #refuses to edit existing files without throwing an exception,
  217.     #so i need to tell it to not touch anything that already exists
  218.     args.append('-nc') #don't copy attr&dates; skip confirmation
  219.     args.append('-nd') #don't del originals; skip confirmation
  220.     args.append('-no') #don't overwrite output; skip confirmation
  221.        
  222.     run_program(args)
  223.    
  224.    
  225.     tryCmd(f'rm {dst_folder}*.png')
  226.    
  227.  
  228.     print(f'IMG CONVERTED IN {time()-timeStart} SECONDS')
  229.     if __name__ == '__main__':
  230.         tryCmd("pause")
  231.         exit(0)
  232.  
  233.  
  234.  
  235. if __name__ == '__main__': main()/******************************************************************************/
  236. /******************************************************************************/
  237. //"kw32g\asset_scripts\convert_all_objimg.py":
  238. _PRINT = True
  239. src_folder = '.\\_png\\'
  240. dst_folder = '.\\_qoi\\'
  241.  
  242. from time import time
  243. from os import system as cmd, walk, path, rename, chdir
  244. import subprocess
  245.  
  246.  
  247.  
  248. def tryInt(string):
  249.     try:
  250.         return int(string)
  251.     except ValueError:
  252.         return None
  253.     except TypeError:
  254.         return None
  255.  
  256.  
  257. def run_program(args, fatal=False):
  258.     if type(args) != list:
  259.         print('args must be of type list')
  260.         exit(-1)
  261.    
  262.     if _PRINT: print((' ').join(args))
  263.    
  264.     returnCode = subprocess.call(args, shell=True)
  265.     if returnCode >= 2**31: returnCode -= 2**32
  266.    
  267.     if fatal:
  268.         if returnCode != 0:
  269.             if _PRINT: print(f'failed to execute "{args}"')
  270.             exit(returnCode)
  271.         return True
  272.     else:
  273.         return returnCode == 0
  274.        
  275.  
  276. def tryCmd(s, ps=True):
  277.     if _PRINT: print(s)
  278.     if ps: cmd("powershell -command "+s)
  279.     else : cmd(s)
  280.    
  281.  
  282. def abspath(local_folder, file_name):
  283.     return path.abspath(path.join(local_folder,file_name))
  284.  
  285.  
  286.  
  287.    
  288.    
  289. def main(cwd = None):
  290.     if cwd != None: chdir(cwd)
  291.    
  292.     timeStart = time()
  293.  
  294.    
  295.     tryCmd(f'rm {dst_folder}*.*')
  296.     tryCmd(f'XCOPY /E /Y {src_folder} {dst_folder}')
  297.    
  298.  
  299.     #assumes there are no folders in .\_qoi\
  300.     files = []
  301.     for root, dirs, _files in walk(dst_folder):
  302.         files += _files
  303.        
  304.  
  305.     args = ['Super.QOI.converter.Console.exe']
  306.    
  307.     for file in files:
  308.         if file.split('.')[-1] != 'qoi':
  309.             args.append(abspath(dst_folder, file))
  310.    
  311.     #this qoi converter seems to be quite buggy, and it
  312.     #refuses to edit existing files without throwing an exception,
  313.     #so i need to tell it to not touch anything that already exists
  314.     args.append('-nc') #don't copy attr&dates; skip confirmation
  315.     args.append('-nd') #don't del originals; skip confirmation
  316.     args.append('-no') #don't overwrite output; skip confirmation
  317.        
  318.     run_program(args)
  319.    
  320.    
  321.     tryCmd(f'rm {dst_folder}*.png')
  322.    
  323.    
  324.     #convert names to "obj-img_<id>.qoi"
  325.     for root, dirs, files in walk(dst_folder):
  326.         for file in files:
  327.             file_src = path.join(root, file)
  328.             objimg_id = tryInt(file.split('_')[0])
  329.             if objimg_id == None:
  330.                 print(f'failed to get obj-img id from "{file_src}"')
  331.                 exit(-1)
  332.             file_dst = path.join(root, f'obj-img_{objimg_id}.qoi')
  333.             rename(file_src, file_dst)
  334.    
  335.  
  336.     print(f'OBJ-IMG CONVERTED IN {time()-timeStart} SECONDS')
  337.     if __name__ == '__main__':
  338.         tryCmd("pause")
  339.         exit(0)
  340.  
  341.  
  342.  
  343. if __name__ == '__main__': main()/******************************************************************************/
  344. /******************************************************************************/
  345. //"kw32g\asset_scripts\convert_all_sfx.py":
  346. _PRINT = True
  347. src_folder = '.\\_wav\\'
  348. dst_folder = '.\\_qoa\\'
  349. tst_folder = '.\\_test\\'
  350. def_prefix = '_opt_'
  351.  
  352. from time import time
  353. from os import system as cmd, walk, path, chdir
  354. import subprocess
  355.  
  356.  
  357.  
  358. def tryInt(string):
  359.     try:
  360.         return int(string)
  361.     except ValueError:
  362.         return None
  363.     except TypeError:
  364.         return None
  365.  
  366.  
  367. def run_program(args, fatal=False):
  368.     if type(args) != list:
  369.         print('args must be of type list')
  370.         exit(-1)
  371.    
  372.     if _PRINT: print((' ').join(args))
  373.    
  374.     returnCode = subprocess.call(args, shell=True)
  375.     if returnCode >= 2**31: returnCode -= 2**32
  376.    
  377.     if fatal:
  378.         if returnCode != 0:
  379.             if _PRINT: print(f'failed to execute "{args}"')
  380.             exit(-1)
  381.         return True
  382.     else:
  383.         return returnCode == 0
  384.        
  385.        
  386. def tryCmd(s, ps=True):
  387.     if _PRINT: print(s)
  388.     if ps: cmd("powershell -command "+s)
  389.     else : cmd(s)
  390.    
  391.  
  392. def convertPath(path, prefix = def_prefix):
  393.     name = path.split(prefix)[-1]
  394.     #assumes filename actually has an extension
  395.     return dst_folder + ('.').join(name.split('.')[:-1]) + '.qoa'
  396.    
  397.    
  398.    
  399. def main(cwd = None):
  400.     if cwd != None: chdir(cwd)
  401.    
  402.     timeStart = time()
  403.  
  404.  
  405.     tryCmd(f'rm {dst_folder}*.*')
  406.  
  407.  
  408.     #assumes there are no folders in .\_wav\
  409.     files = []
  410.     for root, dirs, _files in walk(src_folder):
  411.         files += _files
  412.        
  413.        
  414.     for file in files:
  415.         file_src = path.join(src_folder,file)
  416.         file_dst = convertPath(file)
  417.         file_tst = path.join(tst_folder,file)
  418.  
  419.         #first, convert all wavs to qoa
  420.         run_program(['qoa_convert.exe', file_src, file_dst])
  421.        
  422.         #then, do the reverse to check its output for
  423.         #any artifacts or 'rip headphone users' moments
  424.         run_program(['qoa_convert.exe', file_dst, file_tst])
  425.  
  426.  
  427.     print(f'SFX CONVERTED IN {time()-timeStart} SECONDS')
  428.     if __name__ == '__main__':
  429.         tryCmd('pause')
  430.         exit(0)
  431.  
  432.  
  433.  
  434. if __name__ == '__main__': main()/******************************************************************************/
  435. /******************************************************************************/
  436. //"kw32g\asset_scripts\convert_all_tileset.py":
  437. _PRINT = True
  438. src_folder = '.\\_png\\'
  439. dst_folder = '.\\_qoi\\'
  440.  
  441. from time import time
  442. from os import system as cmd, walk, path, rename, chdir
  443. import subprocess
  444.  
  445.  
  446.  
  447. def tryInt(string):
  448.     try:
  449.         return int(string)
  450.     except ValueError:
  451.         return None
  452.     except TypeError:
  453.         return None
  454.  
  455.  
  456. def run_program(args, fatal=False):
  457.     if type(args) != list:
  458.         print('args must be of type list')
  459.         exit(-1)
  460.    
  461.     if _PRINT: print((' ').join(args))
  462.    
  463.     returnCode = subprocess.call(args, shell=True)
  464.     if returnCode >= 2**31: returnCode -= 2**32
  465.    
  466.     if fatal:
  467.         if returnCode != 0:
  468.             if _PRINT: print(f'failed to execute "{args}"')
  469.             exit(returnCode)
  470.         return True
  471.     else:
  472.         return returnCode == 0
  473.        
  474.  
  475. def tryCmd(s, ps=True):
  476.     if _PRINT: print(s)
  477.     if ps: cmd("powershell -command "+s)
  478.     else : cmd(s)
  479.    
  480.  
  481. def abspath(local_folder, file_name):
  482.     return path.abspath(path.join(local_folder,file_name))
  483.  
  484.  
  485.  
  486.    
  487.    
  488. def main(cwd = None):
  489.     if cwd != None: chdir(cwd)
  490.    
  491.     timeStart = time()
  492.  
  493.    
  494.     tryCmd(f'rm {dst_folder}*.*')
  495.     tryCmd(f'XCOPY /E /Y {src_folder} {dst_folder}')
  496.    
  497.  
  498.     #assumes there are no folders in .\_qoi\
  499.     files = []
  500.     for root, dirs, _files in walk(dst_folder):
  501.         files += _files
  502.        
  503.  
  504.     args = ['Super.QOI.converter.Console.exe']
  505.    
  506.     for file in files:
  507.         if file.split('.')[-1] != 'qoi':
  508.             args.append(abspath(dst_folder, file))
  509.    
  510.     #this qoi converter seems to be quite buggy, and it
  511.     #refuses to edit existing files without throwing an exception,
  512.     #so i need to tell it to not touch anything that already exists
  513.     args.append('-nc') #don't copy attr&dates; skip confirmation
  514.     args.append('-nd') #don't del originals; skip confirmation
  515.     args.append('-no') #don't overwrite output; skip confirmation
  516.        
  517.     run_program(args)
  518.    
  519.    
  520.     tryCmd(f'rm {dst_folder}*.png')
  521.     tryCmd(f'rm {dst_folder}_tileset_collision.qoi')
  522.    
  523.  
  524.     print(f'TILESET CONVERTED IN {time()-timeStart} SECONDS')
  525.     if __name__ == '__main__':
  526.         tryCmd("pause")
  527.         exit(0)
  528.  
  529.  
  530.  
  531. if __name__ == '__main__': main()/******************************************************************************/
  532. /******************************************************************************/
  533. //"kw32g\asset_scripts\copy_all_assets.py":
  534. _PRINT = True
  535. project_folder = '\\kw32g'
  536.  
  537. from time import time
  538. from os import chdir, system as cmd
  539. from os.path import exists
  540.  
  541.  
  542.  
  543. def tryCmd(s, ps=True):
  544.     if _PRINT:
  545.         print(s)
  546.         if ps: cmd('powershell -command '+s)
  547.         else : cmd(s)
  548.     else:
  549.         if ps: cmd(f'powershell -command {s} >nul')
  550.         else : cmd(s+' >nul')
  551.  
  552.  
  553.  
  554. import _generate_arrlen
  555.  
  556. def main(cwd = None):
  557.     #if not None, cwd should be the root asset folder
  558.     if cwd != None: chdir(cwd)
  559.    
  560.     timeStart = time()
  561.    
  562.    
  563.     #and the game's root folder should be on
  564.     #the same level as the assets folder
  565.     game_bin = f'..{project_folder}\\bin'
  566.     deb_dat  = game_bin+'\\_Debug\\dat'
  567.     rel_dat  = game_bin+'\\_Release\\dat'
  568.    
  569.     dat_amb  = '\\ambience'
  570.     dat_bgn  = '\\background'
  571.     dat_img  = '\\img'
  572.     dat_mus  = '\\music'
  573.     dat_obj  = '\\obj-img'
  574.     dat_scn  = '\\scene'
  575.     dat_sfx  = '\\sfx'
  576.     dat_tls  = '\\tileset'
  577.    
  578.    
  579.     #delete save to account for any potential
  580.     #new differences in binary structure
  581.     #(otherwise it'll fail to read properly!)
  582.     tryCmd(f'rm {game_bin}\\_Debug\\save\\*.*')
  583.     tryCmd(f'rm {game_bin}\\_Release\\save\\*.*')  
  584.    
  585.     deb_sys = f'{game_bin}\\_Debug\\dat\\system_states.bin'
  586.     rel_sys = f'{game_bin}\\_Release\\dat\\system_states.bin'
  587.     if exists(deb_sys): tryCmd(f'rm {deb_sys}')
  588.     if exists(rel_sys): tryCmd(f'rm {rel_sys}')
  589.    
  590.    
  591.     tryCmd(f'rm {deb_dat}{dat_amb}\\*.*')
  592.     tryCmd(f'rm {deb_dat}{dat_bgn}\\*.*')
  593.     tryCmd(f'rm {deb_dat}{dat_img}\\*.*')
  594.     tryCmd(f'rm {deb_dat}{dat_mus}\\*.*')
  595.     tryCmd(f'rm {deb_dat}{dat_obj}\\*.*')
  596.     tryCmd(f'rm {deb_dat}{dat_scn}\\*.*')
  597.     tryCmd(f'rm {deb_dat}{dat_sfx}\\*.*')
  598.     tryCmd(f'rm {deb_dat}{dat_tls}\\*.*')
  599.    
  600.     tryCmd(f'rm {rel_dat}{dat_amb}\\*.*')
  601.     tryCmd(f'rm {rel_dat}{dat_bgn}\\*.*')
  602.     tryCmd(f'rm {rel_dat}{dat_img}\\*.*')
  603.     tryCmd(f'rm {rel_dat}{dat_mus}\\*.*')
  604.     tryCmd(f'rm {rel_dat}{dat_obj}\\*.*')
  605.     tryCmd(f'rm {rel_dat}{dat_scn}\\*.*')
  606.     tryCmd(f'rm {rel_dat}{dat_sfx}\\*.*')
  607.     tryCmd(f'rm {rel_dat}{dat_tls}\\*.*')
  608.    
  609.    
  610.     tryCmd(f'XCOPY /E /Y .\\_ambience\\_qoa {  deb_dat}{dat_amb}')
  611.     tryCmd(f'XCOPY /E /Y .\\_background\\_qoi {deb_dat}{dat_bgn}')
  612.     tryCmd(f'XCOPY /E /Y .\\_img\\_qoi {       deb_dat}{dat_img}')
  613.     tryCmd(f'XCOPY /E /Y .\\_music {           deb_dat}{dat_mus}')
  614.     tryCmd(f'XCOPY /E /Y .\\_objimg\\_qoi {    deb_dat}{dat_obj}')
  615.     tryCmd(f'XCOPY /E /Y .\\_scene\\_ksd {     deb_dat}{dat_scn}')
  616.     tryCmd(f'XCOPY /E /Y .\\_sfx\\_qoa {       deb_dat}{dat_sfx}')
  617.     tryCmd(f'XCOPY /E /Y .\\_tileset\\_qoi {   deb_dat}{dat_tls}')  
  618.    
  619.     tryCmd(f'XCOPY /E /Y .\\_ambience\\_qoa {  rel_dat}{dat_amb}')
  620.     tryCmd(f'XCOPY /E /Y .\\_background\\_qoi {rel_dat}{dat_bgn}')
  621.     tryCmd(f'XCOPY /E /Y .\\_img\\_qoi {       rel_dat}{dat_img}')
  622.     tryCmd(f'XCOPY /E /Y .\\_music {           rel_dat}{dat_mus}')
  623.     tryCmd(f'XCOPY /E /Y .\\_objimg\\_qoi {    rel_dat}{dat_obj}')
  624.     tryCmd(f'XCOPY /E /Y .\\_scene\\_ksd {     rel_dat}{dat_scn}')
  625.     tryCmd(f'XCOPY /E /Y .\\_sfx\\_qoa {       rel_dat}{dat_sfx}')
  626.     tryCmd(f'XCOPY /E /Y .\\_tileset\\_qoi {   rel_dat}{dat_tls}')
  627.    
  628.    
  629.     _generate_arrlen.main()
  630.    
  631.    
  632.     print(f'ALL ASSETS COPIED IN {time()-timeStart} SECONDS')
  633.     if __name__ == '__main__':
  634.         tryCmd('pause')
  635.         exit(0)
  636.        
  637.        
  638.        
  639. if __name__ == '__main__': main()/******************************************************************************/
  640. /******************************************************************************/
  641. //"kw32g\asset_scripts\_compile_and_run.py":
  642. _DEBUG = True #will run release build otherwise
  643. _PRINT = True
  644. project_folder = "\\kw32g"
  645.  
  646. from sys import argv
  647. from os import system as cmd, chdir, getcwd
  648. import subprocess
  649.  
  650. from os import listdir
  651. from os.path import isfile, join
  652.  
  653. def filesInDirectory(_dir):
  654.     return len([name for name in listdir(_dir) if isfile(join(_dir, name))])
  655.  
  656.  
  657. def tryInt(string):
  658.     try:
  659.         return int(string)
  660.     except ValueError:
  661.         return None
  662.     except TypeError:
  663.         return None
  664.  
  665.  
  666. def run_program(args, fatal=False):
  667.     if type(args) != list:
  668.         print('args must be of type list')
  669.         exit(-1)
  670.    
  671.     if _PRINT: print((' ').join(args))
  672.    
  673.     returnCode = subprocess.call(args, shell=True)
  674.     if returnCode >= 2**31: returnCode -= 2**32
  675.    
  676.     if fatal:
  677.         if returnCode != 0:
  678.             if _PRINT: print(f'failed to execute "{args}"')
  679.             exit(returnCode)
  680.         return True
  681.     else:
  682.         return returnCode == 0
  683.        
  684.              
  685. def tryCmd(s, ps=True):
  686.     if _PRINT:
  687.         print(s)
  688.         if ps: cmd('powershell -command '+s)
  689.         else : cmd(s)
  690.     else:
  691.         if ps: cmd(f'powershell -command {s} >nul')
  692.         else : cmd(s+' >nul')
  693.  
  694.  
  695.  
  696.  
  697.  
  698. import _compile_scene
  699.  
  700. def main(rangeMin = 1, rangeMax = -1):
  701.     if rangeMin < 1:
  702.         print("rangeMin cannot be less than 1")
  703.         exit(-1)
  704.  
  705.     #-2 to account for create_new_scene.py and scene 0,
  706.     #which only exists as a template when creating scene tilemaps
  707.     if rangeMax == -1:
  708.         rangeMax = filesInDirectory("../_tmx")-2
  709.        
  710.     if rangeMin > rangeMax:
  711.         print("rangeMin cannot be larger than rangeMax")
  712.         exit(-1)
  713.    
  714.    
  715.     _compile_scene.main(rangeMin, rangeMax)
  716.    
  717.    
  718.     cwd = getcwd()
  719.    
  720.     game_bin = f'..\\..\\..{project_folder}\\bin'
  721.    
  722.     if _DEBUG:
  723.         chdir(f'{game_bin}\\_Debug')
  724.         run_program(['kw32g_debug.exe'])
  725.     else:
  726.         chdir(f'{game_bin}\\_Release')
  727.         run_program(['kw32g.exe'])
  728.  
  729.     chdir(cwd) #just in case
  730.    
  731.     #workaround for a problem with Tiled's console output
  732.     tryCmd('pause >nul')
  733.  
  734.    
  735. #(all args are optional!)
  736.  
  737. #args go: rangeMin, rangeMax, "-r" to run release build
  738.  
  739. #if only 1 arg is given (excluding -r), rangeMax will
  740. #be set to rangeMin
  741.  
  742. #if none are given (excluding -r), rangeMin is 1,
  743. #  and rangeMax will be the total number of scenes
  744.  
  745. #(-r should be put as the last arg, regardless of
  746. # if rangeMin and rangeMax is given!)
  747.    
  748. if __name__ == "__main__":
  749.    
  750.     rangeMin, rangeMax  =  1, -1
  751.    
  752.     if len(argv) > 1:
  753.         _rangeMin = tryInt(argv[1])
  754.         if _rangeMin != None: rangeMin = _rangeMin
  755.         if argv[-1].lower() == "-r": _DEBUG = False
  756.    
  757.     if len(argv) > 2:
  758.         _rangeMax = tryInt(argv[2])
  759.         if _rangeMax != None: rangeMax = _rangeMax
  760.    
  761.     main(rangeMin, rangeMax)/******************************************************************************/
  762. /******************************************************************************/
  763. //"kw32g\asset_scripts\_compile_scene.py":
  764. _DEBUG = True
  765. scene_tmx_fmt = '..\\_tmx\\scene_{}.tmx'
  766.  
  767. from time import time
  768. from sys import argv
  769. from struct import pack as struct_pack
  770. from os import system as cmd
  771.  
  772. import _parse_scene as ps
  773. '''public stuff from ps:
  774.  
  775. ps.obj_data_types = {
  776.     "u8",  "s8",  "u16", "s16",  "u24", "s24",
  777.    "u32", "s32",  "u64", "s64",  "f32", "f64",
  778.    "rgb", "argb"
  779. }
  780.  
  781. ps.printError(s, fatal=True)
  782.  
  783. ps.sceneIdToPath(scene_id)
  784.  
  785. #returns None if int() conversion fails
  786. ps.tryInt(string)
  787.  
  788. #returns None if key is not in dict[ionary]
  789. ps.tryDict(dict, key)
  790.  
  791. #dataValue should always be of type str
  792. #type should be one of: int, bool, float, color, object, file
  793. ps.convertType(dataType, dataValue)
  794.  
  795. ps.printScene(scene, printLayers=_PRINT_LAYERS)
  796.  
  797. ps.parseSceneMap(scene_id, announce=False)
  798. '''
  799.  
  800.  
  801.  
  802.  
  803. #                      8      16        24          32                              64
  804. unsigned_max = (-1, 0xff, 0xffff, 0xffffff, 0xffffffff, -1, -1, -1, 0xffffffffffffffff)
  805. signed_min   = (-1,-0x80,-0x8000,-0x800000,-0x80000000, -1, -1, -1,-0x8000000000000000)
  806. signed_max   = (-1, 0x7f, 0x7fff, 0x7fffff, 0x7fffffff, -1, -1, -1, 0x7fffffffffffffff)
  807.  
  808. def to_bytes_integer(_v, byteCount, isSigned):
  809.     v = ps.tryInt(_v)
  810.     if v == None: ps.printError(f'cannot convert {_v} ({hex(v)}) to an integer')
  811.    
  812.     if isSigned:
  813.         if v < signed_min[byteCount]  or  v > signed_max[byteCount]:
  814.             ps.printError(f'cannot convert {v} ({hex(v)}) to s{byteCount*8}')
  815.         if v < 0:
  816.             v += unsigned_max[byteCount]+1
  817.            
  818.     else:
  819.         if v < 0  or  v > unsigned_max[byteCount]:
  820.             ps.printError(f'cannot convert {v} ({hex(v)}) to u{byteCount*8}')
  821.        
  822.     return v.to_bytes(byteCount, "little")
  823.    
  824.  
  825. def to_bytes_float(_v, doublePrecision):
  826.     v = float(_v)
  827.     if doublePrecision: return struct_pack("d", v)
  828.     else              : return struct_pack("f", v)
  829.    
  830.  
  831. #assumes (r,g,b,a), converts to [a]rgb in bytes
  832. def to_bytes_color(_v, useAlpha):
  833.     if type(_v) != list  and type(_v != tuple):
  834.         ps.printError("color must be of type \"list\" or \"tuple\"")
  835.     if len(_v) < 3:
  836.         ps.printError("color has less than 3 channels")
  837.        
  838.     red   = to_bytes_integer(_v[0], 1, False)
  839.     blue  = to_bytes_integer(_v[1], 1, False)
  840.     green = to_bytes_integer(_v[2], 1, False)
  841.    
  842.     if useAlpha:
  843.         if len(_v) < 4:
  844.             ps.printError("color has less than 4 channels, despite using alpha")
  845.         alpha = to_bytes_integer(_v[3], 1, False)
  846.         return alpha + red + green + blue
  847.        
  848.     else:
  849.         return red + green + blue
  850.  
  851.  
  852. def to_bytes_u8(v): return to_bytes_integer(v, 1, False)
  853. def to_bytes_s8(v): return to_bytes_integer(v, 1, True )
  854.  
  855. def to_bytes_u16(v): return to_bytes_integer(v, 2, False)
  856. def to_bytes_s16(v): return to_bytes_integer(v, 2, True )
  857.  
  858. def to_bytes_u24(v): return to_bytes_integer(v, 3, False)
  859. def to_bytes_s24(v): return to_bytes_integer(v, 3, True )
  860.  
  861. def to_bytes_u32(v): return to_bytes_integer(v, 4, False)
  862. def to_bytes_s32(v): return to_bytes_integer(v, 4, True )
  863.  
  864. def to_bytes_u64(v): return to_bytes_integer(v, 8, False)
  865. def to_bytes_s64(v): return to_bytes_integer(v, 8, True )
  866.  
  867. def to_bytes_f32(v): return to_bytes_float(v, False)
  868. def to_bytes_f64(v): return to_bytes_float(v, True )
  869.  
  870. def to_bytes_rgb (v): return to_bytes_color(v, False)
  871. def to_bytes_argb(v): return to_bytes_color(v, True )
  872.  
  873.  
  874. to_bytes = { #for example, "to_bytes["u16"](55)" will output "b'\x37\x00'"
  875.     "u8"  : to_bytes_u8,   "s8"  : to_bytes_s8,
  876.     "u16" : to_bytes_u16,  "s16" : to_bytes_s16,
  877.     "u24" : to_bytes_u24,  "s24" : to_bytes_s24,
  878.     "u32" : to_bytes_u32,  "s32" : to_bytes_s32,
  879.     "u64" : to_bytes_u64,  "s64" : to_bytes_s64,
  880.     "f32" : to_bytes_f32,  "f64" : to_bytes_f64,
  881.     "rgb" : to_bytes_rgb, "argb" : to_bytes_argb
  882. }
  883.  
  884.  
  885.  
  886.  
  887. def total_byte_length(bytes_list): return sum(len(i) for i in bytes_list)
  888. def join_bytes(bytes_list): return (b'').join(bytes_list)
  889. def high_bit_boolean(boolean, integer, byte_width):
  890.     bool_binary = str(int(boolean))
  891.     int_binary  = bin(integer)[2:].rjust(byte_width*8-1,'0') #([2:] to remove the "0b" prefix)
  892.     result_binary = bool_binary + int_binary
  893.    
  894.     if len(result_binary) > byte_width*8:
  895.         ps.printError(f"high_bit_boolean() result longer than {byte_width} bytes")
  896.        
  897.     return to_bytes_integer(int(result_binary, 2), byte_width, False)
  898.  
  899.  
  900. '''struct Object { //48B (28 bytes reserved for the user data)
  901.  kit::u64           _user_0; //data depends on object type
  902.  kit::u64           _user_1;  //
  903.  kit::u64           _user_2;  //
  904.  kit::u32           _user_3;  //
  905.  
  906.  struct {
  907.    kit::u16         x;
  908.    kit::u16         y;
  909.  } /*-----------*/ size;
  910.  struct {
  911.    kit::u8          x; //hitbox's offset relative to the
  912.     kit::u8          y;  //object's actual position
  913.   } /*---------*/ offset;
  914.  
  915.   kit::s16                 x;
  916.   kit::s16                 y;
  917.  
  918.   struct {
  919.     kit::u16            type : 14;
  920.     kit::u16      persistent :  1; //'never reset this object's cached data?'
  921.     kit::u16        in_front :  1; //to either display before player or after foreground
  922.   };
  923.  
  924.   Object_TickCallback update; //called for every tick that the object is active
  925. };'''
  926.  
  927. #returns a single byte object
  928. def assemble_object(obj):
  929.    if _DEBUG: print(f'    assembling object "{obj["name"]}"...')
  930.  
  931.  
  932.    #first 28 bytes of the 48 byte object
  933.    customs = []
  934.    for c in obj["data"]:
  935.        customs.append(to_bytes[c[0]](c[1]))
  936.    
  937.    customs_len = total_byte_length(customs)
  938.    if customs_len > 28: ps.printError("total length of properties exceeded 28 bytes")
  939.    if customs_len < 28: customs.append(b'\x00'*(28-customs_len)) #add padding to end
  940.    
  941.    
  942.    type       = obj["type"]
  943.    persistent = obj["name"][-1:] == "*"
  944.    in_front   = obj["name"][0:1] == "^"
  945.    
  946.    if type >= 2**14: ps.printError("object type id cannot exceed 16383")
  947.    if persistent: type += 16384 #set bit 14
  948.  
  949.    #last 20 bytes of the 48 byte object
  950.    intrinsics = [
  951.        to_bytes_integer(obj["width"      ], 2, False), #u16: hb.size.x
  952.        to_bytes_integer(obj["height"     ], 2, False), #u16: hb.size.y
  953.        to_bytes_integer(obj["hb_offset_x"], 1, False), #u8 : hb.offset.x
  954.        to_bytes_integer(obj["hb_offset_y"], 1, False), #u8 : hb.offset.y
  955.        to_bytes_integer(obj["x"          ], 2, True ), #s16: x
  956.        to_bytes_integer(obj["y"          ], 2, True ), #s16: y
  957.        high_bit_boolean(    in_front, type, 2       ), #u16: in_front, persistent, type
  958.        #(doesn't matter what this is set to, as it's overwritten at runtime anyway)
  959.        b'\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA'             #ptr: update
  960.    ]
  961.    
  962.    
  963.    #concatenate the result of the object's custom and intrinsic properties
  964.     return join_bytes(customs + intrinsics)
  965.  
  966.  
  967.  
  968.  
  969. '''//for storing the contents of a .ksd file (compressed scene data)
  970. #define KSD_MAGIC 0x4644536B //"kSDF"
  971. #define SD_FILELEN(_scene_desc) ((_scene_desc).dataSize+sizeof(SceneDescriptor))
  972. struct SceneDescriptor { //64B
  973. /*0x00*/  kit::u32      magic; //= 0x4644536B = "kSDF" (no null terminator)
  974. /*0x04*/  kit::u32   dataSize; //size of file in bytes, minus the header (which is always 64B)
  975.  
  976.          //offsets to array data in file (if nullptr, data is assumed to not be present!)
  977.          //(also, objs[x].type refers to the index inside gl_objCallbacks used by the object.
  978.           //each element of gl_objCallbacks is of type Object_TickCallback)
  979. /*0x08*/  Object*        objs; //contains the original states of each object in the scene
  980. /*0x10*/  Tile*        pat_mg; //pattern data is compressed using RLE, where the 1st element's .value
  981. /*0x18*/  Tile*        pat_fg;  //member is the run length, with the 2nd being the actual tile data
  982.  
  983.         struct {
  984. /*0x20*/  kit::u16     bmp_bg : 15; //associated background id
  985. /*0x21*/  kit::u16  repeat_bg :  1; //'should bg repeat?' (stretches to screen otherwise)
  986.         };
  987.  
  988.         struct {
  989. /*0x22*/  kit::u16   objs_len : 15; //number of objects in scene
  990. /*0x23*/  kit::u16    visited :  1; //used to help determine if objects should reset on load
  991.         };
  992.  
  993. /*0x24*/  kit::u16  tileset_a; //1st associated tileset
  994. /*0x26*/  kit::u16  tileset_b; //2nd associated tileset
  995.  
  996. /*0x28*/  kit::u16     edge_n; //scene id for north edge
  997. /*0x2A*/  kit::u16     edge_s; //scene id for south edge
  998. /*0x2C*/  kit::u16     edge_w; //scene id for west edge
  999. /*0x2E*/  kit::u16     edge_e; //scene id for east edge
  1000. /*0x30*/  kit::u16      scene; //scene id for scene itself
  1001.  
  1002. /*0x32*/  kit::u16      music; //music id;  0 for no change, -1 (65535) to stop
  1003. /*0x34*/  kit::u16 ambience_a; //ambient track id a;  0 for no change, -1 to stop
  1004. /*0x36*/  kit::u16 ambience_b; //ambient track id b;  0 for no change, -1 to stop
  1005.  
  1006. /*0x38*/  kit::BinaryData* fileData = nullptr; //raw file data; appears as nullptr in file
  1007.  
  1008. /*0x40*/  //... (array data is stored in order of: objs, pat_mg, and pat_fg)
  1009. };'''
  1010.  
  1011. #returns a single byte object
  1012. def assemble_header(props, dataSize, objs, pat_mg, pat_fg):
  1013.    bmp_bg    = props["bmp_bg"   ]
  1014.    repeat_bg = props["repeat_bg"]
  1015.    
  1016.    if props["objs_len"] < 0:
  1017.        ps.printError("objs_len cannot be < 0")
  1018.  
  1019.    return join_bytes((
  1020.        to_bytes_integer(         0x4644536B, 4, False), #u32
  1021.        to_bytes_integer(           dataSize, 4, False), #u32
  1022.        
  1023.        to_bytes_integer(               objs, 8, False), #ptr
  1024.        to_bytes_integer(             pat_mg, 8, False), #ptr
  1025.        to_bytes_integer(             pat_fg, 8, False), #ptr
  1026.        
  1027.        high_bit_boolean(  repeat_bg, bmp_bg, 2       ), #u16
  1028.        
  1029.        to_bytes_integer(props["objs_len"  ], 2, True ), #u15 (yes, 15-bit)
  1030.        
  1031.        to_bytes_integer(props["tileset_a" ], 2, False), #u16
  1032.        to_bytes_integer(props["tileset_b" ], 2, False), #u16
  1033.        
  1034.        to_bytes_integer(props["edge_n"    ], 2, False), #u16
  1035.        to_bytes_integer(props["edge_s"    ], 2, False), #u16
  1036.        to_bytes_integer(props["edge_w"    ], 2, False), #u16
  1037.        to_bytes_integer(props["edge_e"    ], 2, False), #u16
  1038.        to_bytes_integer(props["scene"     ], 2, False), #u16
  1039.        
  1040.        to_bytes_integer(props["music"     ], 2, False), #u16
  1041.        to_bytes_integer(props["ambience_a"], 2, False), #u16
  1042.        to_bytes_integer(props["ambience_b"], 2, False), #u16
  1043.        
  1044.        b'\x00\x00\x00\x00\x00\x00\x00\x00'              #ptr
  1045.    ))
  1046.  
  1047.  
  1048.  
  1049.  
  1050. #returns a list of byte objects
  1051. def assemble_layer(layers, which):
  1052.    layer_tile      = layers[which]
  1053.    layer_collision = layers["collision"]
  1054.    
  1055.    raw = [None,]*len(layer_tile)
  1056.    for i in range(len(layer_tile)):
  1057.        tile      = to_bytes_integer(layer_tile     [i], 1, False)
  1058.        collision = to_bytes_integer(layer_collision[i], 1, False)
  1059.        raw[i] = tile + collision
  1060.        
  1061.    rle      = []
  1062.    previous = raw[0]
  1063.    count    = 0
  1064.    for current in raw:
  1065.        if current == previous:
  1066.            count += 1
  1067.        else:
  1068.            run = to_bytes_integer(count, 2, False)
  1069.            rle.append(run + previous)
  1070.            count = 1
  1071.            previous = current
  1072.            
  1073.    if count != 0:
  1074.        run = to_bytes_integer(count, 2, False)
  1075.        rle.append(run + previous)
  1076.    
  1077.    return rle
  1078.  
  1079.  
  1080.  
  1081.  
  1082. #returns a list of byte objects
  1083. def assemble_scene(scene):
  1084.    if _DEBUG: print(f' GENERATING SCENE { scene["properties"]["scene"] }\'S DATA:')
  1085.    
  1086.     if ps.tryDict(scene, "objs"):
  1087.         #sort objects alphabetically based on their name (excluding ^)
  1088.         scene["objs"] = sorted(scene["objs"], key = lambda x:
  1089.                                x["name"][1:] if x["name"].startswith("^") else x["name"])
  1090.    
  1091.     #ps.pprint(scene["objs"])
  1092.    
  1093.     objs = [ assemble_object(obj) for obj in scene["objs"] ]
  1094.     mg   = assemble_layer(scene["layers"], "mg")
  1095.     fg   = assemble_layer(scene["layers"], "fg")
  1096.    
  1097.  
  1098.     objs_nonzero = len(scene["objs"]) > 0
  1099.     fg_nonzero   = scene["properties"]["fg_nonzero"]
  1100.     mg_nonzero   = scene["properties"]["mg_nonzero"]
  1101.    
  1102.     #header_len = 64
  1103.     objs_len = total_byte_length(objs)
  1104.     mg_len   = total_byte_length(mg  )
  1105.     fg_len   = total_byte_length(fg  )
  1106.    
  1107.     dataSize = 0
  1108.     if objs_nonzero: dataSize += objs_len
  1109.     else           : objs_len  = 0
  1110.     if mg_nonzero  : dataSize += mg_len
  1111.     else           : mg_len    = 0
  1112.     if fg_nonzero  : dataSize += fg_len
  1113.     else           : fg_len    = 0
  1114.    
  1115.     offset_objs = 64
  1116.     offset_mg   = offset_objs + objs_len
  1117.     offset_fg   = offset_mg   +   mg_len
  1118.    
  1119.     #offsets should be 0 in file if array is not used
  1120.     offset_objs *= objs_nonzero # x*False = 0, x*True = x
  1121.     offset_mg   *=   mg_nonzero
  1122.     offset_fg   *=   fg_nonzero
  1123.    
  1124.     header = assemble_header(scene["properties"], dataSize,
  1125.                              offset_objs, offset_mg, offset_fg)
  1126.    
  1127.     output = [header,]
  1128.     if objs_nonzero: output += objs
  1129.     if mg_nonzero  : output += mg
  1130.     if fg_nonzero  : output += fg
  1131.     return output
  1132.  
  1133.  
  1134.  
  1135.  
  1136. def write_scene(list_of_byte_objects, scene_id):
  1137.     if _DEBUG: print(f' WRITING SCENE { scene_id }\'S DATA TO FILE:')
  1138.     with open(f'../_ksd/scene_{scene_id}.ksd', "wb") as file:
  1139.         for chunk in list_of_byte_objects:
  1140.             file.write(chunk)
  1141.  
  1142.  
  1143.  
  1144.  
  1145. from os.path import exists
  1146.  
  1147. #writes scene data to descriptor file
  1148. def compile_scene(scene_id):
  1149.     timeStartTotal = time()
  1150.  
  1151.     if scene_id < 1:
  1152.         ps.printError('scene_id cannot be less than 1')
  1153.  
  1154.     scene_tmx_path = scene_tmx_fmt.format(scene_id)
  1155.     if not exists(scene_tmx_path):
  1156.         ps.printError(f'scene "{scene_tmx_path}" doesn\'t exist')
  1157.  
  1158.     timeStart = time()
  1159.     scene = ps.parseSceneMap(scene_id, announce=_DEBUG)
  1160.     timeTakenMS = (time()-timeStart)*1000
  1161.     if _DEBUG: print("  FINISHED PARSING IN: {:.4}ms".format(timeTakenMS))
  1162.    
  1163.     timeStart = time()
  1164.     scene_bytes = assemble_scene(scene)
  1165.     timeTakenMS = (time()-timeStart)*1000
  1166.     if _DEBUG: print("  FINISHED GENERATING IN: {:.4}ms".format(timeTakenMS))
  1167.    
  1168.     timeStart = time()
  1169.     write_scene(scene_bytes, scene_id)
  1170.     timeTakenMS = (time()-timeStart)*1000
  1171.     if _DEBUG: print("  FINISHED WRITING IN: {:.4}ms".format(timeTakenMS))
  1172.    
  1173.    
  1174.     timeTakenMS = (time()-timeStartTotal)*1000
  1175.     if _DEBUG: print(" TOTAL TIME SPENT: {:.4}ms".format(timeTakenMS))
  1176.     return timeTakenMS
  1177.  
  1178.  
  1179.  
  1180.  
  1181.  
  1182. from os import listdir
  1183. from os.path import isfile, join
  1184.  
  1185. def filesInDirectory(_dir):
  1186.     return len([name for name in listdir(_dir) if isfile(join(_dir, name))])
  1187.  
  1188. def tryCmd(s, ps=True):
  1189.     if _DEBUG:
  1190.         print(s)
  1191.         if ps: cmd('powershell -command '+s)
  1192.         else : cmd(s)
  1193.     else:
  1194.         if ps: cmd(f'powershell -command {s} >nul')
  1195.         else : cmd(s+' >nul')
  1196.  
  1197.  
  1198. import _copy_all_scenes
  1199. import _generate_arrlen_clone
  1200.  
  1201. def main(rangeMin, rangeMax, pauseOnExit=False):
  1202.     timeStart = time()
  1203.    
  1204.     if rangeMin < 1:
  1205.         ps.printError('rangeMin cannot be less than 1')
  1206.     if rangeMax < 1:
  1207.         ps.printError('rangeMax cannot be less than 1')
  1208.    
  1209.     tryCmd('rm ..\\_ksd\\*.*')
  1210.  
  1211.     for i in range(rangeMin, rangeMax+1):
  1212.         compile_scene(i)
  1213.  
  1214.     _copy_all_scenes.main()
  1215.     _generate_arrlen_clone.main()
  1216.  
  1217.     timeTakenMS = (time()-timeStart)*1000
  1218.     if _DEBUG: print(" SCENES {} -> {} COMPILED IN: {}ms".format(rangeMin, rangeMax, int(timeTakenMS)))
  1219.  
  1220.     if pauseOnExit and __name__ == "__main__":
  1221.         cmd("powershell -command pause")
  1222.  
  1223.  
  1224.  
  1225.  
  1226. #arguments go as follows: rangeMin, rangeMax, pauseOnExit, disablePrinting (AKA _DEBUG)
  1227. #rangeMax and pauseOnExit are optional, as if only rangeMin
  1228.  #is specified, rangeMax will be set to rangeMin as well
  1229. #(pauseOnExit and disablePrinting are false by default)
  1230.  
  1231. if __name__ == "__main__":
  1232.     #if no args are given, calculate the number of scenes,
  1233.     #and compile all of them
  1234.     if len(argv) < 2:
  1235.         #-2 to account for create_new_scene.py and scene 0,
  1236.         #which only exists as a template when creating scene tilemaps
  1237.         rangeMax = filesInDirectory("../_tmx")-2
  1238.         if rangeMax < 1:
  1239.             ps.printError('no valid scenes found! (or none greater than 0)')
  1240.         main(1, rangeMax)
  1241.         exit(0)
  1242.        
  1243.    
  1244.     rangeMin = int(argv[1])
  1245.  
  1246.     #(aka disablePrinting)
  1247.     if len(argv) >= 5: _DEBUG = argv[4].lower() == "false"
  1248.  
  1249.     pauseOnExit = False
  1250.     if len(argv) >= 4: pauseOnExit = argv[3].lower() == "true"
  1251.  
  1252.     rangeMax = rangeMin
  1253.     if len(argv) >= 3: rangeMax = int(argv[2])
  1254.  
  1255.  
  1256.     main(rangeMin, rangeMax, pauseOnExit)
  1257.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement