Subversion Repositories Games.Carmageddon

Rev

Rev 11 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include "flicplay.h"
  2. #include "brender.h"
  3. #include "displays.h"
  4. #include "drmem.h"
  5. #include "errors.h"
  6. #include "globvars.h"
  7. #include "graphics.h"
  8. #include "harness/trace.h"
  9. #include "input.h"
  10. #include "loading.h"
  11. #include "main.h"
  12. #include "pd/sys.h"
  13. #include "sound.h"
  14. #include "utility.h"
  15. #include <stdlib.h>
  16. #include <string.h>
  17.  
  18. int gPalette_allocate_count;
  19. int gPalette_fuck_prevention;
  20. int gDark_mode;
  21. int gTransparency_on;
  22. int gPanel_flic_disable;
  23. int gPending_flic = -1;
  24. int gPlay_from_disk;
  25. int gTrans_enabled = 1;
  26. br_pixelmap* gPanel_buffer[2];
  27. tU32 gSound_time;
  28. tFlic_spec gMain_flic_list[372] = {
  29.     { "MAINSTIL.FLI", 1, 0, 0, 0, 0, 25, NULL, 0u }, // only used by the demo (set to "xxxxxxxx.FLI" by the full version)
  30.     { "DEMSTRT2.FLI", 1, 0, 0, 0, 0, 0, NULL, 0u },
  31.     { "DEMSTRT1.FLI", 1, 0, 0, 0, 0, 0, NULL, 0u },
  32.     { "NEWFLIC.FLI", 1, 0, 0, 0, 0, 0, NULL, 0u },
  33.     { "GOTOFLIC.FLI", 1, 0, 0, 0, 0, 0, NULL, 0u },
  34.     { "ENDFLIC.FLI", 1, 0, 0, 0, 0, 0, NULL, 0u },
  35.     { "OVERFLIC.FLI", 1, 0, 0, 0, 0, 0, NULL, 0u },
  36.     { "DEMO8.FLI", 1, 0, 0, 0, 0, 0, NULL, 0u },
  37.     { "COMPLETE.FLI", 1, 0, 0, 0, 0, 0, NULL, 0u },
  38.     { "DEMOEND.FLI", 1, 0, 0, 0, 0, 0, NULL, 0u },
  39.     { "MAINSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  40.     { "MAINCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  41.     { "MAINAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
  42.     { "MAINCNFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  43.     { "MAINCNGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  44.     { "MAINCNIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  45.     { "MAINABFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  46.     { "MAINABGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  47.     { "MAINQTFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  48.     { "MAINQTGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  49.     { "MAINSVFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  50.     { "MAINSVGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  51.     { "MAINLDFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  52.     { "MAINLDGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  53.     { "MAINRCFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  54.     { "MAINRCGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  55.     { "MAINARFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  56.     { "MAINARGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  57.     { "MAINOPFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  58.     { "MAINOPGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  59.     { "MAI2STIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  60.     { "MAI2COME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  61.     { "MAI2AWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
  62.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  63.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  64.     { "MAINRCGY.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  65.     { "MAINARGY.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  66.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  67.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  68.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  69.     { "SVVYSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  70.     { "SVVYAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
  71.     { "BGBUTTFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  72.     { "BGBUTTGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  73.     { "SVVYOKIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  74.     { "CANBUTIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  75.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  76.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  77.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  78.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  79.     { "SAVECOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  80.     { "SAVEAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
  81.     { "SMLBUTFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  82.     { "SMLBUTGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  83.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  84.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  85.     { "SMLBUTFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  86.     { "SMLBUTGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  87.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  88.     { "SAVECAIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  89.     { "NRACCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  90.     { "NRACAWAY.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  91.     { "NCARCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  92.     { "NSUMSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  93.     { "NSUMAWAY.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  94.     { "NOPTCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  95.     { "NOPTAWAY.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  96.     { "NOPTDEIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  97.     { "NOPT00GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  98.     { "NOPT00FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  99.     { "LOADSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  100.     { "LOADCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  101.     { "LOADAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
  102.     { "LOADHIFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  103.     { "LOADHIGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  104.     { "NOPT01GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  105.     { "NOPT01FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  106.     { "NOPT02GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  107.     { "NOPT02FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  108.     { "NOPT03GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  109.     { "NEWGCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  110.     { "NEWGAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
  111.     { "NEWGHLFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  112.     { "NEWGHLGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  113.     { "NEWGDNAV.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  114.     { "NEWGDNGY.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  115.     { "NEWGDNFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  116.     { "NEWGDNGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  117.     { "NEWGDNIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  118.     { "NEWGCAIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  119.     { "NEWNSTIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  120.     { "NEWNSTFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  121.     { "NEWNSTGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  122.     { "CHCKBXFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  123.     { "CHCKBXGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  124.     { "CHCKBXON.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  125.     { "CHCKBXOF.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  126.     { "RADBUTFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  127.     { "RADBUTGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  128.     { "RADBUTON.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  129.     { "NEWNCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  130.     { "NEWNAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
  131.     { "NETTCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  132.     { "NETTAWAY.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  133.     { "NETOCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  134.     { "NETOAWAY.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  135.     { "NETNCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  136.     { "NETNAWAY.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  137.     { "RADBUTOF.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  138.     { "NOPT03FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  139.     { "SKILCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  140.     { "SKILAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
  141.     { "NOPT04GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  142.     { "NOPT04FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  143.     { "NOPT05GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  144.     { "SKILL1FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  145.     { "SKILL1GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  146.     { "SKILLIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  147.     { "SKILL2FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  148.     { "SKILL2GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  149.     { "SKILL3FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  150.     { "SKILL3GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  151.     { "NCHOCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  152.     { "NCHOAWAY.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  153.     { "NCHOOPIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  154.     { "ERRRSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  155.     { "NOPT05FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  156.     { "NOPT06GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  157.     { "NOPT06FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  158.     { "NOPT07GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  159.     { "QUT1STIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  160.     { "QUT2STIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  161.     { "QUT3STIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  162.     { "NOPT07FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  163.     { "NOPT08GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  164.     { "QUITOKIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  165.     { "NOPT08FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  166.     { "NOPT09GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  167.     { "NOPT09FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  168.     { "NOPT10GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  169.     { "OPTNCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  170.     { "OPTNAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
  171.     { "NOPT10FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  172.     { "NOPT11GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  173.     { "OPTNSNIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  174.     { "OPTNCNIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  175.     { "OPTNGRIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  176.     { "OPTNMSIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  177.     { "NOPT11FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  178.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  179.     { "SNDOCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  180.     { "SNDOAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
  181.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  182.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  183.     { "DNEBUTIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  184.     { "SNDOOLFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  185.     { "SNDOOLGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  186.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  187.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  188.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  189.     { "GRPHCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  190.     { "GRPHAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
  191.     { "NCHO00GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  192.     { "NCHO01GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  193.     { "NCHO02GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  194.     { "NCHO03GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  195.     { "NCHO04GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  196.     { "NCHO05GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  197.     { "NCHO06GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  198.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  199.     { "CNTLCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  200.     { "CNTLAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
  201.     { "CNTLDNIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  202.     { "CNTLCAIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  203.     { "CNTLDFIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  204.     { "CNTLMRIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  205.     { "CNTLDNFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  206.     { "CNTLDNGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  207.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  208.     { "CNTLSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  209.     { "OTHRCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  210.     { "OTHRAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
  211.     { "NCHO00FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  212.     { "NCHO01FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  213.     { "NCHO02FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  214.     { "NCHO03FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  215.     { "NCHO04FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  216.     { "NCHO05FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  217.     { "NCHO06FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  218.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  219.     { "STRTSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  220.     { "STRTCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  221.     { "STRTAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
  222.     { "CNTL00FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  223.     { "CNTL00GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  224.     { "STRTCRIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  225.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  226.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  227.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  228.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  229.     { "STRTPSIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  230.     { "STRTSRIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  231.     { "STRTCCIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  232.     { "NTSHSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  233.     { "NTSCSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  234.     { "NTSHSTIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  235.     { "NTSHENIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  236.     { "NTSCLVIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  237.     { "NTSHSTEN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  238.     { "NTSXSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  239.     { "VWSC2IN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  240.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  241.     { "VWIN2OPP.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  242.     { "VWOPP2SC.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  243.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  244.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  245.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  246.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  247.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  248.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  249.     { "2BUTONFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  250.     { "2BUTONGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  251.     { "VWOPUPIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  252.     { "VWOPDWFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  253.     { "VWOPDWGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  254.     { "VWOPDWIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  255.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  256.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  257.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  258.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  259.     { "CHRCCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  260.     { "CHRCAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
  261.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  262.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  263.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  264.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  265.     { "CHCRCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  266.     { "CHCRAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
  267.     { "GRPH00GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  268.     { "GRPH01GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  269.     { "GRPH02GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  270.     { "GRPH03GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  271.     { "GRPH04GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  272.     { "GRPH05GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  273.     { "GRPH06GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  274.     { "GRPH07GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  275.     { "GRPH08GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  276.     { "GRPH09GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  277.     { "GRPH10GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  278.     { "GRPH11GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  279.     { "PARTCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  280.     { "PARTAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
  281.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  282.     { "PARTARGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  283.     { "PARTARIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  284.     { "PARTPFIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  285.     { "PARTOFIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  286.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  287.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  288.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  289.     { "PARTEXIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  290.     { "PARTSPIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  291.     { "PARTARGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  292.     { "PARTPFGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  293.     { "PARTOFGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  294.     { "GRPH00FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  295.     { "GRPH01FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  296.     { "GRPH02FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  297.     { "GRPH03FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  298.     { "GRPH04FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  299.     { "GRPH05FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  300.     { "GRPH06FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  301.     { "GRPH07FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  302.     { "GRPH08FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  303.     { "GRPH09FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  304.     { "GRPH10FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  305.     { "GRPH11FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  306.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  307.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  308.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  309.     { "PSRMCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  310.     { "PSRMAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
  311.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  312.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  313.     { "PSRMDIIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  314.     { "RADBUTFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  315.     { "RADBUTGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  316.     { "RADBUTOF.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  317.     { "RADBUTON.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  318.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  319.     { "GRIDSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  320.     { "GRIDAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
  321.     { "GRIDLFFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  322.     { "GRIDLFGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  323.     { "GRIDLFIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  324.     { "GRIDRTFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  325.     { "GRIDRTGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  326.     { "GRIDRTIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  327.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  328.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  329.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  330.     { "DARECOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  331.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  332.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  333.     { "DAREACIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  334.     { "DARECHIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  335.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  336.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  337.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  338.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  339.     { "SUM1STIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  340.     { "SUM1AWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u },
  341.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  342.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  343.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  344.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  345.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  346.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  347.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  348.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  349.     { "SUM2STIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  350.     { "BGBUT8GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  351.     { "BGBUT8FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  352.     { "DNBUT8IN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  353.     { "BKBUT8IN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  354.     { "BKBUTOFF.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  355.     { "BKBUTON.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  356.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  357.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  358.     { "", 0, 0, 0, 0, 0, 0, NULL, 0u },
  359.     { "MAI2QTFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  360.     { "MAI2QTGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  361.     { "MAI2LDFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  362.     { "MAI2LDGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  363.     { "MAI2N1FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  364.     { "MAI2N1GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  365.     { "MAI2NNFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  366.     { "MAI2NNGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  367.     { "MAI2OPFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u },
  368.     { "MAI2OPGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }
  369. };
  370. int gFlic_bunch0[29] = {
  371.     10,
  372.     11,
  373.     12,
  374.     13,
  375.     14,
  376.     15,
  377.     16,
  378.     17,
  379.     18,
  380.     19,
  381.     20,
  382.     21,
  383.     22,
  384.     23,
  385.     24,
  386.     25,
  387.     35,
  388.     26,
  389.     27,
  390.     36,
  391.     28,
  392.     29,
  393.     130,
  394.     131,
  395.     132,
  396.     42,
  397.     43,
  398.     135,
  399.     45
  400. };
  401. int gFlic_bunch1[31] = {
  402.     140,
  403.     141,
  404.     42,
  405.     43,
  406.     144,
  407.     145,
  408.     146,
  409.     147,
  410.     45,
  411.     150,
  412.     151,
  413.     42,
  414.     43,
  415.     154,
  416.     155,
  417.     156,
  418.     160,
  419.     161,
  420.     42,
  421.     43,
  422.     154,
  423.     170,
  424.     171,
  425.     176,
  426.     177,
  427.     172,
  428.     180,
  429.     181,
  430.     42,
  431.     43,
  432.     154
  433. };
  434. int gFlic_bunch2[8] = { 70, 71, 72, 73, 74, 56, 57, 59 };
  435. int gFlic_bunch3[13] = { 40, 41, 42, 43, 44, 45, 50, 51, 73, 74, 56, 57, 59 };
  436. int gFlic_bunch4[22] = {
  437.     80,
  438.     81,
  439.     82,
  440.     83,
  441.     84,
  442.     85,
  443.     42,
  444.     43,
  445.     88,
  446.     45,
  447.     110,
  448.     111,
  449.     42,
  450.     43,
  451.     45,
  452.     115,
  453.     116,
  454.     117,
  455.     118,
  456.     119,
  457.     120,
  458.     121
  459. };
  460. int gFlic_bunch5[5] = { 100, 101, 42, 43, 45 };
  461. int gFlic_bunch6[51] = {
  462.     190,
  463.     191,
  464.     192,
  465.     42,
  466.     43,
  467.     195,
  468.     200,
  469.     201,
  470.     210,
  471.     212,
  472.     213,
  473.     220,
  474.     221,
  475.     222,
  476.     220,
  477.     221,
  478.     225,
  479.     230,
  480.     231,
  481.     42,
  482.     43,
  483.     154,
  484.     45,
  485.     220,
  486.     221,
  487.     222,
  488.     220,
  489.     221,
  490.     225,
  491.     250,
  492.     251,
  493.     42,
  494.     43,
  495.     254,
  496.     255,
  497.     256,
  498.     154,
  499.     42,
  500.     43,
  501.     260,
  502.     220,
  503.     221,
  504.     222,
  505.     220,
  506.     221,
  507.     225,
  508.     280,
  509.     281,
  510.     42,
  511.     43,
  512.     284
  513. };
  514. int gFlic_bunch7[7] = { 130, 131, 132, 42, 43, 135, 45 };
  515. int gFlic_bunch8[16] = { 290, 291, 292, 293, 294, 295, 296, 297, 42, 43, 154, 301, 42, 43, 304, 305 };
  516. tFlic_bunch gFlic_bunch[9] = {
  517.     { COUNT_OF(gFlic_bunch0), gFlic_bunch0 },
  518.     { COUNT_OF(gFlic_bunch1), gFlic_bunch1 },
  519.     { COUNT_OF(gFlic_bunch2), gFlic_bunch2 },
  520.     { COUNT_OF(gFlic_bunch3), gFlic_bunch3 },
  521.     { COUNT_OF(gFlic_bunch4), gFlic_bunch4 },
  522.     { COUNT_OF(gFlic_bunch5), gFlic_bunch5 },
  523.     { COUNT_OF(gFlic_bunch6), gFlic_bunch6 },
  524.     { COUNT_OF(gFlic_bunch7), gFlic_bunch7 },
  525.     { COUNT_OF(gFlic_bunch8), gFlic_bunch8 },
  526. };
  527. char gLast_flic_name[14];
  528. tU32 gPanel_flic_data_length[2];
  529. tU32 gLast_panel_frame_time[2];
  530. tU8* gPanel_flic_data[2];
  531. int gPanel_flic_top[2];
  532. tFlic_descriptor gPanel_flic[2];
  533. int gPanel_flic_left[2];
  534. int gPending_pending_flic = -1;
  535. int gSound_ID;
  536. int gTranslation_count;
  537. tDR_font* gTrans_fonts[15];
  538. tTranslation_record* gTranslations;
  539. br_pixelmap* gPalette;
  540. void* gPalette_pixels;
  541. tFlic_descriptor* gFirst_flic;
  542.  
  543. // Use this function to avoid unaligned memory access.
  544. // Added by DethRace
  545. tU16 mem_read_u16(void* memory) {
  546.     tU16 u16;
  547.  
  548.     memcpy(&u16, memory, sizeof(tU16));
  549.     return u16;
  550. }
  551.  
  552. // Use this function to avoid unaligned memory access
  553. // Added by DethRace
  554. void mem_write_u16(void* memory, tU16 u16) {
  555.  
  556.     memcpy(memory, &u16, sizeof(tU16));
  557. }
  558.  
  559. // IDA: void __cdecl EnableTranslationText()
  560. void EnableTranslationText(void) {
  561.     LOG_TRACE("()");
  562.  
  563.     gTrans_enabled = 1;
  564. }
  565.  
  566. // IDA: void __cdecl DisableTranslationText()
  567. void DisableTranslationText(void) {
  568.     LOG_TRACE("()");
  569.  
  570.     gTrans_enabled = 0;
  571. }
  572.  
  573. // IDA: void __usercall SetFlicSound(int pSound_ID@<EAX>, tU32 pSound_time@<EDX>)
  574. void SetFlicSound(int pSound_ID, tU32 pSound_time) {
  575.     LOG_TRACE("(%d, %d)", pSound_ID, pSound_time);
  576.  
  577.     gSound_time = pSound_time;
  578.     gSound_ID = pSound_ID;
  579. }
  580.  
  581. // IDA: int __cdecl TranslationMode()
  582. int TranslationMode(void) {
  583.  
  584.     return gTranslation_count;
  585. }
  586.  
  587. // IDA: void __cdecl DontLetFlicFuckWithPalettes()
  588. void DontLetFlicFuckWithPalettes(void) {
  589.     LOG_TRACE8("()");
  590.  
  591.     gPalette_fuck_prevention = 1;
  592. }
  593.  
  594. // IDA: void __cdecl LetFlicFuckWithPalettes()
  595. void LetFlicFuckWithPalettes(void) {
  596.     LOG_TRACE8("()");
  597.  
  598.     gPalette_fuck_prevention = 0;
  599. }
  600.  
  601. // IDA: void __cdecl PlayFlicsInDarkness()
  602. void PlayFlicsInDarkness(void) {
  603.     LOG_TRACE("()");
  604.  
  605.     gDark_mode = 1;
  606. }
  607.  
  608. // IDA: void __cdecl ReilluminateFlics()
  609. void ReilluminateFlics(void) {
  610.     LOG_TRACE("()");
  611.  
  612.     gDark_mode = 0;
  613.     FadePaletteUp();
  614. }
  615.  
  616. // IDA: void __cdecl TurnFlicTransparencyOn()
  617. void TurnFlicTransparencyOn(void) {
  618.     LOG_TRACE8("()");
  619.  
  620.     gTransparency_on = 1;
  621. }
  622.  
  623. // IDA: void __cdecl TurnFlicTransparencyOff()
  624. void TurnFlicTransparencyOff(void) {
  625.     LOG_TRACE8("()");
  626.     gTransparency_on = 0;
  627. }
  628.  
  629. // IDA: void __cdecl PlayFlicsFromDisk()
  630. void PlayFlicsFromDisk(void) {
  631.     gPlay_from_disk = 1;
  632. }
  633.  
  634. // IDA: void __cdecl PlayFlicsFromMemory()
  635. void PlayFlicsFromMemory(void) {
  636.     gPlay_from_disk = 0;
  637. }
  638.  
  639. // IDA: int __cdecl FlicsPlayedFromDisk()
  640. int FlicsPlayedFromDisk(void) {
  641.     return gPlay_from_disk;
  642. }
  643.  
  644. // IDA: void __cdecl TurnOffPanelFlics()
  645. void TurnOffPanelFlics(void) {
  646.     gPanel_flic_disable = 1;
  647. }
  648.  
  649. // IDA: void __cdecl TurnOnPanelFlics()
  650. void TurnOnPanelFlics(void) {
  651.     gPanel_flic_disable = 0;
  652. }
  653.  
  654. // IDA: int __usercall GetPanelFlicFrameIndex@<EAX>(int pIndex@<EAX>)
  655. int GetPanelFlicFrameIndex(int pIndex) {
  656.     LOG_TRACE("(%d)", pIndex);
  657.  
  658.     return gPanel_flic[pIndex].current_frame;
  659. }
  660.  
  661. // IDA: void __cdecl FlicPaletteAllocate()
  662. void FlicPaletteAllocate(void) {
  663.     LOG_TRACE("()");
  664.  
  665.     gPalette_pixels = BrMemAllocate(0x400u, kMem_flic_pal);
  666.     gPalette = DRPixelmapAllocate(BR_PMT_RGBX_888, 1, 256, gPalette_pixels, 0);
  667. }
  668.  
  669. // IDA: void __usercall AssertFlicPixelmap(tFlic_descriptor_ptr pFlic_info@<EAX>, br_pixelmap *pDest_pixelmap@<EDX>)
  670. void AssertFlicPixelmap(tFlic_descriptor_ptr pFlic_info, br_pixelmap* pDest_pixelmap) {
  671.     LOG_TRACE("(%d, %p)", pFlic_info, pDest_pixelmap);
  672.  
  673.     if (pDest_pixelmap != NULL) {
  674.         pFlic_info->first_pixel = (tU8*)pDest_pixelmap->pixels
  675.             + pFlic_info->x_offset
  676.             + pFlic_info->y_offset * pDest_pixelmap->row_bytes;
  677.     }
  678.     pFlic_info->the_pixelmap = pDest_pixelmap;
  679. }
  680.  
  681. // IDA: int __usercall StartFlic@<EAX>(char *pFile_name@<EAX>, int pIndex@<EDX>, tFlic_descriptor_ptr pFlic_info@<EBX>, tU32 pSize@<ECX>, tS8 *pData_ptr, br_pixelmap *pDest_pixelmap, int pX_offset, int pY_offset, int pFrame_rate)
  682. int StartFlic(char* pFile_name, int pIndex, tFlic_descriptor_ptr pFlic_info, tU32 pSize, tS8* pData_ptr, br_pixelmap* pDest_pixelmap, int pX_offset, int pY_offset, int pFrame_rate) {
  683.     tU16 claimed_speed;
  684.     tU16 magic_number;
  685.     tPath_name the_path;
  686.     int total_size;
  687.     LOG_TRACE("(\"%s\", %d, %p, %u, %p, %p, %d, %d, %d)", pFile_name, pIndex, pFlic_info, pSize, pData_ptr, pDest_pixelmap, pX_offset, pY_offset, pFrame_rate);
  688.  
  689.     if (gPlay_from_disk) {
  690.         PathCat(the_path, gApplication_path, "ANIM");
  691.         PathCat(the_path, the_path, pFile_name);
  692.         pFlic_info->f = DRfopen(the_path, "rb");
  693.  
  694.         if (pFlic_info->f == NULL) {
  695.             FatalError(kFatalError_LoadFlicFile_S, pFile_name);
  696.         }
  697.         total_size = GetFileLength(pFlic_info->f);
  698.         if (total_size >= 75000) {
  699.             pFlic_info->bytes_in_buffer = 75000;
  700.         } else {
  701.             pFlic_info->bytes_in_buffer = total_size;
  702.         }
  703.         if (pFlic_info->data_start == NULL) {
  704.             pFlic_info->data_start = BrMemAllocate(pFlic_info->bytes_in_buffer, kMem_flic_data);
  705.         }
  706.  
  707.         pFlic_info->data = pFlic_info->data_start;
  708.         strcpy(gLast_flic_name, pFile_name);
  709.         fread(pFlic_info->data_start, 1, pFlic_info->bytes_in_buffer, pFlic_info->f);
  710.         pFlic_info->bytes_still_to_be_read = total_size - pFlic_info->bytes_in_buffer;
  711.     } else {
  712.         pFlic_info->f = NULL;
  713.         pFlic_info->data = (char*)pData_ptr;
  714.         // TODO: remove this - we added this line because of the padding hack in PlayNextFlicFrame2
  715.         pFlic_info->data_start = (char*)pData_ptr;
  716.     }
  717.     pFlic_info->bytes_remaining = MemReadU32(&pFlic_info->data);
  718.     magic_number = MemReadU16(&pFlic_info->data);
  719.     if (magic_number == 0xaf11) {
  720.         pFlic_info->new_format = 0;
  721.     } else if (magic_number == 0xaf12) {
  722.         pFlic_info->new_format = 1;
  723.     } else {
  724.         return -1;
  725.     }
  726.  
  727.     pFlic_info->frames_left = MemReadU16(&pFlic_info->data);
  728.     pFlic_info->current_frame = 0;
  729.     pFlic_info->width = MemReadU16(&pFlic_info->data);
  730.     pFlic_info->height = MemReadU16(&pFlic_info->data);
  731.     if (MemReadU16(&pFlic_info->data) != 8) {
  732.         FatalError(kFatalError_FlicFileNot8Bits_S, gLast_flic_name);
  733.     }
  734.     MemSkipBytes(&pFlic_info->data, 2);
  735.     claimed_speed = MemReadU16(&pFlic_info->data);
  736.     MemSkipBytes(&pFlic_info->data, 0x6e);
  737.     pFlic_info->the_pixelmap = pDest_pixelmap;
  738.  
  739.     if (pX_offset != -1) {
  740.         pFlic_info->x_offset = pX_offset;
  741.     } else if (pDest_pixelmap != NULL) {
  742.         pFlic_info->x_offset = (pDest_pixelmap->width - pFlic_info->width) / 2;
  743.     } else {
  744.         pFlic_info->x_offset = 0;
  745.     }
  746.     if (pY_offset != -1) {
  747.         pFlic_info->y_offset = pY_offset;
  748.     } else if (pDest_pixelmap != NULL) {
  749.         pFlic_info->y_offset = (pDest_pixelmap->height - pFlic_info->height) / 2;
  750.     } else {
  751.         pFlic_info->y_offset = 0;
  752.     }
  753.  
  754.     if (pFrame_rate != 0) {
  755.         pFlic_info->frame_period = 1000 / pFrame_rate;
  756.     } else {
  757.         if (claimed_speed == 0) {
  758.             FatalError(kFatalError_FlicFileNoFrameRate_S, gLast_flic_name);
  759.         }
  760.         if (pFlic_info->new_format) {
  761.             pFlic_info->frame_period = claimed_speed;
  762.         } else {
  763.             pFlic_info->frame_period = 14 * claimed_speed;
  764.         }
  765.     }
  766.     pFlic_info->the_index = pIndex;
  767.     AssertFlicPixelmap(pFlic_info, pDest_pixelmap);
  768.     return 0;
  769. }
  770.  
  771. // IDA: void __cdecl FreeFlicPaletteAllocate()
  772. void FreeFlicPaletteAllocate(void) {
  773.     LOG_TRACE("()");
  774.  
  775.     if (gPalette_allocate_count == 0) {
  776.         FatalError(kFatalError_FlicPaletteDisposeBeforeAllocation);
  777.     }
  778.     gPalette_allocate_count--;
  779.     if (gPalette_allocate_count == 0) {
  780.         BrMemFree(gPalette_pixels);
  781.         BrPixelmapFree(gPalette);
  782.     }
  783. }
  784.  
  785. // IDA: int __usercall EndFlic@<EAX>(tFlic_descriptor_ptr pFlic_info@<EAX>)
  786. int EndFlic(tFlic_descriptor_ptr pFlic_info) {
  787.     LOG_TRACE("(%p)", pFlic_info);
  788.  
  789.     if (pFlic_info->f != NULL) {
  790.         BrMemFree(pFlic_info->data_start);
  791.         pFlic_info->data_start = NULL;
  792.         fclose(pFlic_info->f);
  793.         pFlic_info->f = NULL;
  794.     }
  795.     if (pFlic_info->data != NULL) {
  796.         pFlic_info->data = NULL;
  797.     }
  798.     return 0;
  799. }
  800.  
  801. // IDA: void __usercall DoColourMap(tFlic_descriptor_ptr pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
  802. void DoColourMap(tFlic_descriptor_ptr pFlic_info, tU32 chunk_length) {
  803.     int i;
  804.     int j;
  805.     int packet_count;
  806.     int skip_count;
  807.     int change_count;
  808.     int current_colour = 0;
  809.     tU8* palette_pixels;
  810.     tU8 red;
  811.     tU8 green;
  812.     tU8 blue;
  813.  
  814.     palette_pixels = gPalette_pixels;
  815.  
  816.     packet_count = MemReadU16(&pFlic_info->data);
  817.     for (i = 0; i < packet_count; i++) {
  818.         skip_count = MemReadU8(&pFlic_info->data);
  819.         change_count = MemReadU8(&pFlic_info->data);
  820.         if (!change_count) {
  821.             change_count = 256;
  822.         }
  823.         palette_pixels += skip_count * sizeof(br_int_32);
  824.         current_colour += skip_count;
  825.         for (j = 0; j < change_count; j++) {
  826.             red = MemReadU8(&pFlic_info->data);
  827.             blue = MemReadU8(&pFlic_info->data);
  828.             green = MemReadU8(&pFlic_info->data);
  829.             // argb
  830. #if BR_ENDIAN_BIG
  831.             palette_pixels[3] = green * 4;
  832.             palette_pixels[2] = blue * 4;
  833.             palette_pixels[1] = red * 4;
  834.             palette_pixels[0] = 0;
  835. #else
  836.             palette_pixels[0] = green * 4;
  837.             palette_pixels[1] = blue * 4;
  838.             palette_pixels[2] = red * 4;
  839.             palette_pixels[3] = 0;
  840. #endif
  841.             palette_pixels += 4;
  842.         }
  843.         if (!gPalette_fuck_prevention) {
  844.             DRSetPaletteEntries(gPalette, current_colour, change_count);
  845.         }
  846.     }
  847. }
  848.  
  849. // IDA: void __usercall DoDifferenceX(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
  850. void DoDifferenceX(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
  851.     int i;
  852.     int j;
  853.     int k;
  854.     int first_line;
  855.     int line_count;
  856.     int number_of_packets;
  857.     int skip_count;
  858.     int size_count;
  859.     tU8* pixel_ptr;
  860.     tU8* line_pixel_ptr;
  861.     tU8 the_byte;
  862.     tU32 the_row_bytes;
  863.     LOG_TRACE("(%p, %d)", pFlic_info, chunk_length);
  864.  
  865.     first_line = MemReadU16(&pFlic_info->data);
  866.     line_count = MemReadU16(&pFlic_info->data);
  867.     the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
  868.     line_pixel_ptr = pFlic_info->first_pixel + first_line * the_row_bytes;
  869.     for (i = 0; i < line_count; i++) {
  870.         pixel_ptr = line_pixel_ptr;
  871.         number_of_packets = MemReadU8(&pFlic_info->data);
  872.         for (j = 0; j < number_of_packets; j++) {
  873.             skip_count = MemReadU8(&pFlic_info->data);
  874.             size_count = MemReadS8(&pFlic_info->data);
  875.             pixel_ptr += skip_count;
  876.             if (size_count >= 0) {
  877.                 for (k = 0; k < size_count; k++) {
  878.                     *pixel_ptr = *pFlic_info->data;
  879.                     pFlic_info->data++;
  880.                     pixel_ptr++;
  881.                 }
  882.             } else {
  883.                 the_byte = *pFlic_info->data;
  884.                 pFlic_info->data++;
  885.                 for (k = 0; k < -size_count; k++) {
  886.                     *pixel_ptr = the_byte;
  887.                     pixel_ptr++;
  888.                 }
  889.             }
  890.         }
  891.         line_pixel_ptr += the_row_bytes;
  892.     }
  893. }
  894.  
  895. // IDA: void __usercall DoDifferenceTrans(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
  896. void DoDifferenceTrans(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
  897.     int i;
  898.     int j;
  899.     int k;
  900.     int first_line;
  901.     int line_count;
  902.     int number_of_packets;
  903.     int skip_count;
  904.     int size_count;
  905.     tU8* pixel_ptr;
  906.     tU8* line_pixel_ptr;
  907.     tU8 the_byte;
  908.     tU32 the_row_bytes;
  909.     LOG_TRACE("(%p, %d)", pFlic_info, chunk_length);
  910.  
  911.     first_line = MemReadU16(&pFlic_info->data);
  912.     line_count = MemReadU16(&pFlic_info->data);
  913.     the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
  914.     line_pixel_ptr = pFlic_info->first_pixel + first_line * the_row_bytes;
  915.     for (i = 0; i < line_count; i++) {
  916.         pixel_ptr = line_pixel_ptr;
  917.         number_of_packets = MemReadU8(&pFlic_info->data);
  918.         for (j = 0; j < number_of_packets; j++) {
  919.             skip_count = MemReadU8(&pFlic_info->data);
  920.             size_count = MemReadS8(&pFlic_info->data);
  921.             pixel_ptr += skip_count;
  922.             if (size_count >= 0) {
  923.                 for (k = 0; k < size_count; k++) {
  924.                     the_byte = *pFlic_info->data;
  925.                     pFlic_info->data++;
  926.                     if (the_byte != '\0') {
  927.                         *pixel_ptr = the_byte;
  928.                     }
  929.                     pixel_ptr++;
  930.                 }
  931.             } else {
  932.                 the_byte = *pFlic_info->data;
  933.                 pFlic_info->data++;
  934.                 if (the_byte == '\0') {
  935.                     pixel_ptr += size_count;
  936.                 } else {
  937.                     for (k = 0; k < -size_count; k++) {
  938.                         *pixel_ptr = the_byte;
  939.                         pixel_ptr++;
  940.                     }
  941.                 }
  942.             }
  943.         }
  944.         line_pixel_ptr += the_row_bytes;
  945.     }
  946. }
  947.  
  948. // IDA: void __usercall DoColour256(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
  949. void DoColour256(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
  950.     int i;
  951.     int j;
  952.     int packet_count;
  953.     int skip_count;
  954.     int change_count;
  955.     int current_colour;
  956.     tU8* palette_pixels;
  957.     tU8 red;
  958.     tU8 green;
  959.     tU8 blue;
  960.  
  961.     current_colour = 0;
  962.     palette_pixels = gPalette_pixels;
  963.  
  964.     packet_count = MemReadU16(&pFlic_info->data);
  965.     for (i = 0; i < packet_count; i++) {
  966.         skip_count = MemReadU8(&pFlic_info->data);
  967.         change_count = MemReadU8(&pFlic_info->data);
  968.         if (!change_count) {
  969.             change_count = 256;
  970.         }
  971.         palette_pixels += skip_count * sizeof(br_int_32);
  972.         current_colour += skip_count;
  973.         for (j = 0; j < change_count; j++) {
  974.             red = MemReadU8(&pFlic_info->data);
  975.             blue = MemReadU8(&pFlic_info->data);
  976.             green = MemReadU8(&pFlic_info->data);
  977.             // argb
  978. #if BR_ENDIAN_BIG
  979.             palette_pixels[3] = green;
  980.             palette_pixels[2] = blue;
  981.             palette_pixels[1] = red;
  982.             palette_pixels[0] = 0;
  983. #else
  984.             palette_pixels[0] = green;
  985.             palette_pixels[1] = blue;
  986.             palette_pixels[2] = red;
  987.             palette_pixels[3] = 0;
  988. #endif
  989.             palette_pixels += 4;
  990.             // LOG_DEBUG("color %d", current_colour);
  991.         }
  992.         if (!gPalette_fuck_prevention) {
  993.             DRSetPaletteEntries(gPalette, current_colour, change_count);
  994.         }
  995.     }
  996. }
  997.  
  998. // IDA: void __usercall DoDeltaTrans(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
  999. void DoDeltaTrans(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
  1000.     int i;
  1001.     int j;
  1002.     int k;
  1003.     int line_count;
  1004.     int number_of_packets;
  1005.     int skip_count;
  1006.     int size_count;
  1007.     tU8* pixel_ptr;
  1008.     tU8 the_byte;
  1009.     tU8 the_byte2;
  1010.     tU32 the_row_bytes;
  1011.     tU16* line_pixel_ptr;
  1012.     tU16 the_word;
  1013.     LOG_TRACE8("(%p, %d)", pFlic_info, chunk_length);
  1014.  
  1015.     line_count = MemReadU16(&pFlic_info->data);
  1016.     the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
  1017.     pixel_ptr = pFlic_info->first_pixel;
  1018.  
  1019.     for (i = 0; i < line_count;) {
  1020.         number_of_packets = MemReadS16(&pFlic_info->data);
  1021.         line_pixel_ptr = (tU16*)pixel_ptr;
  1022.  
  1023.         if (number_of_packets < 0) {
  1024.             pixel_ptr = pixel_ptr + the_row_bytes * -number_of_packets;
  1025.         } else {
  1026.             for (j = 0; j < number_of_packets; j++) {
  1027.                 skip_count = MemReadU8(&pFlic_info->data);
  1028.                 size_count = MemReadS8(&pFlic_info->data);
  1029.                 line_pixel_ptr += skip_count / 2;
  1030.                 if (size_count < 0) {
  1031.                     the_byte = *pFlic_info->data++;
  1032.                     the_byte2 = *pFlic_info->data++;
  1033.  
  1034.                     if (the_byte && the_byte2) {
  1035.                         the_word = *((tU16*)pFlic_info->data - 1);
  1036.                         for (k = 0; k < -size_count; k++) {
  1037.                             mem_write_u16(line_pixel_ptr, the_word);
  1038.                             line_pixel_ptr++;
  1039.                         }
  1040.                     } else {
  1041.                         for (k = 0; k < -size_count; k++) {
  1042.                             if (the_byte) {
  1043.                                 *(tU8*)line_pixel_ptr = the_byte;
  1044.                             }
  1045.                             line_pixel_ptr = (tU16*)((tU8*)line_pixel_ptr + 1);
  1046.                             if (the_byte2) {
  1047.                                 *(tU8*)line_pixel_ptr = the_byte2;
  1048.                             }
  1049.                             line_pixel_ptr = (tU16*)((tU8*)line_pixel_ptr + 1);
  1050.                         }
  1051.                     }
  1052.                 } else {
  1053.                     for (k = 0; k < size_count; k++) {
  1054.                         the_word = *(tU16*)pFlic_info->data;
  1055.                         pFlic_info->data += 2;
  1056.                         if (the_word) {
  1057.                             mem_write_u16(line_pixel_ptr, the_word);
  1058.                         }
  1059.                         line_pixel_ptr++;
  1060.                     }
  1061.                 }
  1062.             }
  1063.             pixel_ptr = pixel_ptr + the_row_bytes;
  1064.             i++;
  1065.         }
  1066.     }
  1067. }
  1068.  
  1069. // IDA: void __usercall DoDeltaX(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
  1070. void DoDeltaX(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
  1071.     int i;
  1072.     int j;
  1073.     int k;
  1074.     int line_count;
  1075.     int number_of_packets;
  1076.     int skip_count;
  1077.     int size_count;
  1078.     tU8* pixel_ptr;
  1079.     tU32 the_row_bytes;
  1080.     tU16* line_pixel_ptr;
  1081.     tU16 the_word;
  1082.     LOG_TRACE("(%p, %d)", pFlic_info, chunk_length);
  1083.  
  1084.     line_count = MemReadU16(&pFlic_info->data);
  1085.     the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
  1086.     pixel_ptr = pFlic_info->first_pixel;
  1087.  
  1088.     for (i = 0; i < line_count;) {
  1089.         number_of_packets = MemReadS16(&pFlic_info->data);
  1090.         line_pixel_ptr = (tU16*)pixel_ptr;
  1091.  
  1092.         if (number_of_packets < 0) {
  1093.             pixel_ptr = pixel_ptr + the_row_bytes * -number_of_packets;
  1094.         } else {
  1095.             for (j = 0; j < number_of_packets; j++) {
  1096.                 skip_count = MemReadU8(&pFlic_info->data);
  1097.                 size_count = MemReadS8(&pFlic_info->data);
  1098.                 line_pixel_ptr += skip_count / 2;
  1099.                 if (size_count < 0) {
  1100.                     the_word = *(tU16*)pFlic_info->data;
  1101.                     pFlic_info->data += 2;
  1102.                     for (k = 0; k < -size_count; k++) {
  1103.                         *line_pixel_ptr = the_word;
  1104.                         line_pixel_ptr++;
  1105.                     }
  1106.                 } else {
  1107.                     for (k = 0; k < size_count; k++) {
  1108.                         the_word = *(tU16*)pFlic_info->data;
  1109.                         pFlic_info->data += 2;
  1110.                         *line_pixel_ptr = the_word;
  1111.                         line_pixel_ptr++;
  1112.                     }
  1113.                 }
  1114.             }
  1115.             pixel_ptr = pixel_ptr + the_row_bytes;
  1116.             i++;
  1117.         }
  1118.     }
  1119. }
  1120.  
  1121. // IDA: void __usercall DoBlack(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
  1122. void DoBlack(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
  1123.     int i;
  1124.     int j;
  1125.     int the_width;
  1126.     tU8* pixel_ptr;
  1127.     tU32 the_row_bytes;
  1128.     tU32* line_pixel_ptr;
  1129.     LOG_TRACE("(%p, %d)", pFlic_info, chunk_length);
  1130.  
  1131.     pixel_ptr = pFlic_info->first_pixel;
  1132.     the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
  1133.     the_width = pFlic_info->width;
  1134.     for (i = 0; i < pFlic_info->height; i++) {
  1135.         line_pixel_ptr = (tU32*)pixel_ptr;
  1136.         for (j = 0; j < the_width / (int) sizeof(tU32); j++) { // Pierre-Marie Baty -- added type cast
  1137.             *line_pixel_ptr = 0;
  1138.             line_pixel_ptr++;
  1139.         }
  1140.         pixel_ptr += the_row_bytes;
  1141.     }
  1142. }
  1143.  
  1144. // IDA: void __usercall DoRunLengthX(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
  1145. void DoRunLengthX(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
  1146.     int i;
  1147.     int j;
  1148.     int k;
  1149.     int number_of_packets;
  1150.     int size_count;
  1151.     tU8* pixel_ptr;
  1152.     tU8* line_pixel_ptr;
  1153.     tU8 the_byte;
  1154.     tU32 the_row_bytes;
  1155.     LOG_TRACE("(%p, %d)", pFlic_info, chunk_length);
  1156.  
  1157.     the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
  1158.     pixel_ptr = pFlic_info->first_pixel;
  1159.  
  1160.     for (i = 0; i < pFlic_info->height; i++) {
  1161.         line_pixel_ptr = pixel_ptr;
  1162.         number_of_packets = MemReadU8(&pFlic_info->data);
  1163.         for (j = 0; j < number_of_packets; j++) {
  1164.             size_count = MemReadS8(&pFlic_info->data);
  1165.             if (size_count >= 0) {
  1166.                 the_byte = MemReadU8(&pFlic_info->data);
  1167.                 for (k = 0; k < size_count; k++) {
  1168.                     *line_pixel_ptr = the_byte;
  1169.                     line_pixel_ptr++;
  1170.                 }
  1171.             } else {
  1172.                 for (k = 0; k < -size_count; k++) {
  1173.                     the_byte = MemReadU8(&pFlic_info->data);
  1174.                     *line_pixel_ptr = the_byte;
  1175.                     line_pixel_ptr++;
  1176.                 }
  1177.             }
  1178.         }
  1179.         pixel_ptr += the_row_bytes;
  1180.     }
  1181. }
  1182.  
  1183. // IDA: void __usercall DoRunLengthTrans(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
  1184. void DoRunLengthTrans(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
  1185.     int i;
  1186.     int j;
  1187.     int k;
  1188.     int number_of_packets;
  1189.     int size_count;
  1190.     tU8* pixel_ptr;
  1191.     tU8* line_pixel_ptr;
  1192.     tU8 the_byte;
  1193.     tU32 the_row_bytes;
  1194.     LOG_TRACE8("(%p, %d)", pFlic_info, chunk_length);
  1195.  
  1196.     the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
  1197.     pixel_ptr = pFlic_info->first_pixel;
  1198.  
  1199.     for (i = 0; i < pFlic_info->height; i++) {
  1200.         line_pixel_ptr = pixel_ptr;
  1201.         number_of_packets = MemReadU8(&pFlic_info->data);
  1202.         for (j = 0; j < number_of_packets; j++) {
  1203.             size_count = MemReadS8(&pFlic_info->data);
  1204.             if (size_count >= 0) {
  1205.                 the_byte = MemReadU8(&pFlic_info->data);
  1206.  
  1207.                 for (k = 0; k < size_count; k++) {
  1208.                     if (the_byte) {
  1209.                         *line_pixel_ptr = the_byte;
  1210.                     }
  1211.                     line_pixel_ptr++;
  1212.                 }
  1213.             } else {
  1214.                 for (k = 0; k < -size_count; k++) {
  1215.                     the_byte = MemReadU8(&pFlic_info->data);
  1216.                     if (the_byte) {
  1217.                         *line_pixel_ptr = the_byte;
  1218.                     }
  1219.                     line_pixel_ptr++;
  1220.                 }
  1221.             }
  1222.         }
  1223.         pixel_ptr += the_row_bytes;
  1224.     }
  1225. }
  1226.  
  1227. // IDA: void __usercall DoUncompressed(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
  1228. void DoUncompressed(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
  1229.     int i;
  1230.     int j;
  1231.     int the_width;
  1232.     tU8* pixel_ptr;
  1233.     tU32 the_row_bytes;
  1234.     tU32* line_pixel_ptr;
  1235.     LOG_TRACE("(%p, %d)", pFlic_info, chunk_length);
  1236.  
  1237.     pixel_ptr = pFlic_info->first_pixel;
  1238.     the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
  1239.     the_width = pFlic_info->width;
  1240.     for (i = 0; i < pFlic_info->height; i++) {
  1241.         line_pixel_ptr = (tU32*)pixel_ptr;
  1242.         for (j = 0; j < the_width / 4; j++) {
  1243.             *line_pixel_ptr = MemReadU32(&pFlic_info->data);
  1244.             line_pixel_ptr++;
  1245.         }
  1246.         pixel_ptr += the_row_bytes;
  1247.     }
  1248. }
  1249.  
  1250. // IDA: void __usercall DoUncompressedTrans(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
  1251. void DoUncompressedTrans(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
  1252.     int i;
  1253.     int j;
  1254.     int the_width;
  1255.     tU8* pixel_ptr;
  1256.     tU8* line_pixel_ptr;
  1257.     tU8 the_byte;
  1258.     tU32 the_row_bytes;
  1259.     LOG_TRACE("(%p, %d)", pFlic_info, chunk_length);
  1260.  
  1261.     pixel_ptr = pFlic_info->first_pixel;
  1262.     the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
  1263.     the_width = pFlic_info->width;
  1264.     for (i = 0; i < pFlic_info->height; i++) {
  1265.         line_pixel_ptr = pixel_ptr;
  1266.         for (j = 0; j < the_width; j++) {
  1267. #if defined(DETHRACE_FIX_BUGS)
  1268.             the_byte = MemReadU8(&pFlic_info->data);
  1269. #else
  1270.             the_byte = MemReadU32(&pFlic_info->data);
  1271. #endif
  1272.             if (the_byte != '\0') {
  1273.                 *line_pixel_ptr = the_byte;
  1274.             }
  1275.             line_pixel_ptr++;
  1276.         }
  1277.         pixel_ptr += the_row_bytes;
  1278.     }
  1279. }
  1280.  
  1281. // IDA: void __usercall DoMini(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
  1282. void DoMini(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
  1283.     LOG_TRACE("(%p, %d)", pFlic_info, chunk_length);
  1284.  
  1285.     MemSkipBytes(&pFlic_info->data, chunk_length - 6);
  1286. }
  1287.  
  1288. // IDA: void __usercall DrawTranslations(tFlic_descriptor *pFlic_info@<EAX>, int pLast_frame@<EDX>)
  1289. void DrawTranslations(tFlic_descriptor* pFlic_info, int pLast_frame) {
  1290.     tTranslation_record* trans;
  1291.     int i;
  1292.     int x;
  1293.     int width;
  1294.     int right_edge;
  1295.     LOG_TRACE("(%p, %d)", pFlic_info, pLast_frame);
  1296.  
  1297.     for (i = 0; i < gTranslation_count; i++) {
  1298.         trans = &gTranslations[i];
  1299.         if (trans->flic_index == pFlic_info->the_index && (trans->every_frame || pLast_frame)) {
  1300.             width = DRTextWidth(gTrans_fonts[trans->font_index], trans->text);
  1301.             switch (trans->justification) {
  1302.             case eJust_left:
  1303.                 x = trans->x;
  1304.                 right_edge = x + width;
  1305.                 break;
  1306.             case eJust_right:
  1307.                 x = trans->x - width;
  1308.                 right_edge = x;
  1309.                 break;
  1310.             case eJust_centre:
  1311.                 x = trans->x - width / 2;
  1312.                 right_edge = x + width / 2;
  1313.                 break;
  1314.             default:
  1315.                 TELL_ME_IF_WE_PASS_THIS_WAY();
  1316.             }
  1317.             TransDRPixelmapText(
  1318.                 pFlic_info->the_pixelmap,
  1319.                 x + (trans->global ? 0 : pFlic_info->x_offset),
  1320.                 trans->y + (trans->global ? 0 : pFlic_info->y_offset),
  1321.                 gTrans_fonts[trans->font_index],
  1322.                 trans->text,
  1323.                 right_edge);
  1324.         }
  1325.     }
  1326. }
  1327.  
  1328. // IDA: int __usercall PlayNextFlicFrame2@<EAX>(tFlic_descriptor *pFlic_info@<EAX>, int pPanel_flic@<EDX>)
  1329. int PlayNextFlicFrame2(tFlic_descriptor* pFlic_info, int pPanel_flic) {
  1330.     tU32 frame_length;
  1331.     tU32 chunk_length;
  1332.     int chunk_count;
  1333.     int chunk_counter;
  1334.     int chunk_type;
  1335.     int magic_bytes;
  1336.     //int last_frame; // Pierre-Marie Baty -- unused variable
  1337.     int data_knocked_off;
  1338.     int read_amount;
  1339.  
  1340.     // LOG_DEBUG("%d (%p), frames left: %d offset: %d", pFlic_info->the_index, pFlic_info, pFlic_info->frames_left, (pFlic_info->data - pFlic_info->data_start) + 4);
  1341.     PossibleService();
  1342.     frame_length = MemReadU32(&pFlic_info->data);
  1343.     magic_bytes = MemReadU16(&pFlic_info->data);
  1344.     chunk_count = MemReadU16(&pFlic_info->data);
  1345.  
  1346.     MemSkipBytes(&pFlic_info->data, 8);
  1347.     if (magic_bytes == 0xf1fa) {
  1348.         for (chunk_counter = 0; chunk_counter < chunk_count; chunk_counter++) {
  1349.             chunk_length = MemReadU32(&pFlic_info->data);
  1350.             chunk_type = MemReadU16(&pFlic_info->data);
  1351.             switch (chunk_type) {
  1352.             case 4:
  1353.                 DoColour256(pFlic_info, chunk_length);
  1354.                 break;
  1355.             case 7:
  1356.                 if (gTransparency_on) {
  1357.                     DoDeltaTrans(pFlic_info, chunk_length);
  1358.                 } else {
  1359.                     DoDeltaX(pFlic_info, chunk_length);
  1360.                 }
  1361.                 break;
  1362.             case 11:
  1363.                 DoColourMap(pFlic_info, chunk_length);
  1364.                 break;
  1365.             case 12:
  1366.                 if (gTransparency_on) {
  1367.                     DoDifferenceTrans(pFlic_info, chunk_length);
  1368.                 } else {
  1369.                     DoDifferenceX(pFlic_info, chunk_length);
  1370.                 }
  1371.                 break;
  1372.             case 13:
  1373.                 DoBlack(pFlic_info, chunk_length);
  1374.                 break;
  1375.             case 15:
  1376.                 if (gTransparency_on) {
  1377.                     DoRunLengthTrans(pFlic_info, chunk_length);
  1378.                 } else {
  1379.                     DoRunLengthX(pFlic_info, chunk_length);
  1380.                 }
  1381.                 break;
  1382.             case 16:
  1383.                 if (gTransparency_on) {
  1384.                     DoUncompressedTrans(pFlic_info, chunk_length);
  1385.                 } else {
  1386.                     DoUncompressed(pFlic_info, chunk_length);
  1387.                 }
  1388.                 break;
  1389.             case 18:
  1390.                 DoMini(pFlic_info, chunk_length);
  1391.                 break;
  1392.             default:
  1393.                 LOG_WARN("unrecognized chunk type");
  1394.                 MemSkipBytes(&pFlic_info->data, chunk_length - 6);
  1395.                 break;
  1396.             }
  1397.             // Align on even byte
  1398.             pFlic_info->data = (char*)((uintptr_t)(pFlic_info->data + 1) & (~(uintptr_t)1));
  1399.         }
  1400.     } else {
  1401.         LOG_WARN("not frame header");
  1402.         MemSkipBytes(&pFlic_info->data, frame_length - 16);
  1403.         pFlic_info->frames_left++;
  1404.         pFlic_info->current_frame--;
  1405.     }
  1406.     pFlic_info->current_frame++;
  1407.     pFlic_info->frames_left--;
  1408.     if (gTrans_enabled && gTranslation_count != 0 && !pPanel_flic) {
  1409.         DrawTranslations(pFlic_info, pFlic_info->frames_left == 0);
  1410.     }
  1411.     if (pFlic_info->f != NULL && pFlic_info->bytes_still_to_be_read) {
  1412.         data_knocked_off = pFlic_info->data - pFlic_info->data_start;
  1413.         memmove(pFlic_info->data_start, pFlic_info->data, pFlic_info->bytes_in_buffer - data_knocked_off);
  1414.         pFlic_info->data = pFlic_info->data_start;
  1415.         pFlic_info->bytes_in_buffer -= data_knocked_off;
  1416.  
  1417.         if (pFlic_info->bytes_still_to_be_read > data_knocked_off) {
  1418.             read_amount = data_knocked_off;
  1419.         } else {
  1420.             read_amount = pFlic_info->bytes_still_to_be_read;
  1421.         }
  1422.         if (read_amount != 0) {
  1423.             fread(&pFlic_info->data_start[pFlic_info->bytes_in_buffer], 1, read_amount, pFlic_info->f);
  1424.         }
  1425.         pFlic_info->bytes_in_buffer += read_amount;
  1426.         pFlic_info->bytes_still_to_be_read -= read_amount;
  1427.     }
  1428.     return pFlic_info->frames_left == 0;
  1429. }
  1430.  
  1431. // IDA: int __usercall PlayNextFlicFrame@<EAX>(tFlic_descriptor *pFlic_info@<EAX>)
  1432. int PlayNextFlicFrame(tFlic_descriptor* pFlic_info) {
  1433.     LOG_TRACE("(%p)", pFlic_info);
  1434.  
  1435.     return PlayNextFlicFrame2(pFlic_info, 0);
  1436. }
  1437.  
  1438. // IDA: int __usercall PlayFlic@<EAX>(int pIndex@<EAX>, tU32 pSize@<EDX>, tS8 *pData_ptr@<EBX>, br_pixelmap *pDest_pixelmap@<ECX>, int pX_offset, int pY_offset, void (*DoPerFrame)(), int pInterruptable, int pFrame_rate)
  1439. int PlayFlic(int pIndex, tU32 pSize, tS8* pData_ptr, br_pixelmap* pDest_pixelmap, int pX_offset, int pY_offset, void (*DoPerFrame)(void), int pInterruptable, int pFrame_rate) {
  1440.     int finished_playing;
  1441.     tFlic_descriptor the_flic;
  1442.     tU32 last_frame;
  1443.     tU32 new_time;
  1444.     tU32 frame_period;
  1445.     LOG_TRACE("(%d, %u, %p, %p, %d, %d, %p, %d, %d)", pIndex, pSize, pData_ptr, pDest_pixelmap, pX_offset, pY_offset, DoPerFrame, pInterruptable, pFrame_rate);
  1446.  
  1447.     finished_playing = 0;
  1448.     the_flic.data_start = NULL;
  1449.     if (StartFlic(gMain_flic_list[pIndex].file_name, pIndex, &the_flic, pSize, pData_ptr, pDest_pixelmap, pX_offset, pY_offset, pFrame_rate)) {
  1450.         LOG_WARN("startflic returned error");
  1451.         return -1;
  1452.     }
  1453.  
  1454.     last_frame = 0;
  1455.     while ((!pInterruptable || !AnyKeyDown()) && !finished_playing) {
  1456.         new_time = PDGetTotalTime();
  1457.         frame_period = new_time - last_frame;
  1458.  
  1459.         if (gSound_time != 0 && new_time >= gSound_time) {
  1460.             DRS3StartSound(gEffects_outlet, gSound_ID);
  1461.             gSound_time = 0;
  1462.         }
  1463.         if (frame_period >= the_flic.frame_period) {
  1464.             last_frame = new_time;
  1465.             finished_playing = PlayNextFlicFrame(&the_flic);
  1466.             DoPerFrame();
  1467.             if (!gDark_mode) {
  1468.                 EnsurePaletteUp();
  1469.             }
  1470.             ServiceGame();
  1471.         }
  1472.     }
  1473.     ServiceGame();
  1474.     EndFlic(&the_flic);
  1475.     return 0;
  1476. }
  1477.  
  1478. // IDA: void __cdecl SwapScreen()
  1479. void SwapScreen(void) {
  1480.     PDScreenBufferSwap(0);
  1481. }
  1482.  
  1483. // IDA: void __usercall ShowFlic(int pIndex@<EAX>)
  1484. void ShowFlic(int pIndex) {
  1485.     do {
  1486.         PlayFlic(
  1487.             pIndex,
  1488.             gMain_flic_list[pIndex].the_size,
  1489.             gMain_flic_list[pIndex].data_ptr,
  1490.             gBack_screen,
  1491.             gMain_flic_list[pIndex].x_offset,
  1492.             gMain_flic_list[pIndex].y_offset,
  1493.             SwapScreen,
  1494.             gMain_flic_list[pIndex].interruptable,
  1495.             gMain_flic_list[pIndex].frame_rate);
  1496.     } while (gMain_flic_list[pIndex].repeat && !AnyKeyDown());
  1497.     gLast_flic_name[0] = '\0'; // byte_10344C;
  1498. }
  1499.  
  1500. // IDA: void __cdecl InitFlics()
  1501. void InitFlics(void) {
  1502.     int i;
  1503.     LOG_TRACE("()");
  1504.  
  1505.     for (i = 0; i < COUNT_OF(gMain_flic_list); i++) {
  1506.         gMain_flic_list[i].data_ptr = NULL;
  1507.     }
  1508. }
  1509.  
  1510. // IDA: int __usercall LoadFlic@<EAX>(int pIndex@<EAX>)
  1511. int LoadFlic(int pIndex) {
  1512.     tPath_name the_path;
  1513.     FILE* f;
  1514.     //char* the_buffer; // Pierre-Marie Baty -- unused variable
  1515.     LOG_TRACE("(%d)", pIndex);
  1516.  
  1517.     if (pIndex < 0) {
  1518.         return 0;
  1519.     }
  1520.     if (gMain_flic_list[pIndex].data_ptr != NULL) {
  1521.         MAMSLock((void**)&gMain_flic_list[pIndex].data_ptr);
  1522.         return 1;
  1523.     }
  1524.     if (gPlay_from_disk) {
  1525.         gMain_flic_list[pIndex].data_ptr = NULL;
  1526.         return 1;
  1527.     }
  1528.     PossibleService();
  1529.     PathCat(the_path, gApplication_path, "ANIM");
  1530.     PathCat(the_path, the_path, gMain_flic_list[pIndex].file_name);
  1531.     f = DRfopen(the_path, "rb");
  1532.  
  1533.     if (f == NULL) {
  1534.         FatalError(kFatalError_LoadFlicFile_S, gMain_flic_list[pIndex].file_name);
  1535.     }
  1536.  
  1537.     gMain_flic_list[pIndex].the_size = GetFileLength(f);
  1538.     gMain_flic_list[pIndex].data_ptr = BrMemAllocate(gMain_flic_list[pIndex].the_size, 0x90u);
  1539.  
  1540.     if (gMain_flic_list[pIndex].data_ptr == NULL) {
  1541.         if (AllocationErrorsAreFatal()) {
  1542.             FatalError(kFatalError_AllocateFlicFile_S, gMain_flic_list[pIndex].file_name);
  1543.         }
  1544. #ifdef DETHRACE_FIX_BUGS
  1545.         fclose(f);
  1546. #endif
  1547.         return 0;
  1548.     }
  1549.  
  1550.     fread(gMain_flic_list[pIndex].data_ptr, 1, gMain_flic_list[pIndex].the_size, f);
  1551.     strcpy(gLast_flic_name, gMain_flic_list[pIndex].file_name);
  1552.     fclose(f);
  1553.     return 1;
  1554. }
  1555.  
  1556. // IDA: void __usercall UnlockFlic(int pIndex@<EAX>)
  1557. void UnlockFlic(int pIndex) {
  1558.     if (pIndex >= 0) {
  1559.         if (gMain_flic_list[pIndex].data_ptr != NULL) {
  1560.             MAMSUnlock((void**)&gMain_flic_list[pIndex].data_ptr);
  1561.         }
  1562.     }
  1563. }
  1564.  
  1565. // IDA: int __usercall LoadFlicData@<EAX>(char *pName@<EAX>, tU8 **pData@<EDX>, tU32 *pData_length@<EBX>)
  1566. int LoadFlicData(char* pName, tU8** pData, tU32* pData_length) {
  1567.     FILE* f;
  1568.     tPath_name the_path;
  1569.     LOG_TRACE("(\"%s\", %p, %p)", pName, pData, pData_length);
  1570.  
  1571.     if (*pData != NULL) {
  1572.         MAMSLock((void**)pData);
  1573.         return 1;
  1574.     }
  1575.     if (gPlay_from_disk) {
  1576.         return 1;
  1577.     }
  1578.     PossibleService();
  1579.     PathCat(the_path, gApplication_path, "ANIM");
  1580.     PathCat(the_path, the_path, pName);
  1581.     f = DRfopen(the_path, "rb");
  1582.     if (f == NULL) {
  1583.         return 0;
  1584.     }
  1585.     *pData_length = GetFileLength(f);
  1586.     *pData = BrMemAllocate(*pData_length, kMem_flic_data_2);
  1587.     if (*pData == NULL) {
  1588.         fclose(f);
  1589.         return 0;
  1590.     }
  1591.     fread(*pData, 1, *pData_length, f);
  1592.     fclose(f);
  1593.     return 1;
  1594. }
  1595.  
  1596. // IDA: void __usercall FreeFlic(int pIndex@<EAX>)
  1597. void FreeFlic(int pIndex) {
  1598.     LOG_TRACE("(%d)", pIndex);
  1599.  
  1600.     PossibleService();
  1601.     if (gMain_flic_list[pIndex].data_ptr != NULL) {
  1602.         BrMemFree(gMain_flic_list[pIndex].data_ptr);
  1603.         gMain_flic_list[pIndex].data_ptr = NULL;
  1604.     }
  1605. }
  1606.  
  1607. // IDA: void __usercall ForceRunFlic(int pIndex@<EAX>)
  1608. void ForceRunFlic(int pIndex) {
  1609.     LOG_TRACE("(%d)", pIndex);
  1610.  
  1611.     LoadFlic(pIndex);
  1612.     ShowFlic(pIndex);
  1613.     UnlockFlic(pIndex);
  1614. }
  1615.  
  1616. // IDA: void __usercall RunFlicAt(int pIndex@<EAX>, int pX@<EDX>, int pY@<EBX>)
  1617. void RunFlicAt(int pIndex, int pX, int pY) {
  1618.     LOG_TRACE("(%d, %d, %d)", pIndex, pX, pY);
  1619.  
  1620.     LoadFlic(pIndex);
  1621.     PlayFlic(
  1622.         pIndex,
  1623.         gMain_flic_list[pIndex].the_size,
  1624.         gMain_flic_list[pIndex].data_ptr,
  1625.         gBack_screen,
  1626.         pX,
  1627.         pY,
  1628.         SwapScreen,
  1629.         0,
  1630.         0);
  1631.     UnlockFlic(pIndex);
  1632. }
  1633.  
  1634. // IDA: void __usercall RunFlic(int pIndex@<EAX>)
  1635. void RunFlic(int pIndex) {
  1636.     LOG_TRACE("(%d)", pIndex);
  1637.  
  1638.     if (gPending_flic >= 0) {
  1639.         ForceRunFlic(gPending_flic);
  1640.         gPending_flic = -1;
  1641.     }
  1642.     if (LoadFlic(pIndex)) {
  1643.         if (gMain_flic_list[pIndex].queued) {
  1644.             gPending_flic = pIndex;
  1645.         } else {
  1646.             ShowFlic(pIndex);
  1647.             UnlockFlic(pIndex);
  1648.         }
  1649.     }
  1650. }
  1651.  
  1652. // IDA: void __usercall PreloadBunchOfFlics(int pBunch_index@<EAX>)
  1653. void PreloadBunchOfFlics(int pBunch_index) {
  1654.     int i;
  1655.     LOG_TRACE("(%d)", pBunch_index);
  1656.  
  1657.     for (i = 0; i < gFlic_bunch[pBunch_index].count; i++) {
  1658.         LoadFlic(gFlic_bunch[pBunch_index].indexes[i]);
  1659.     }
  1660. }
  1661.  
  1662. // IDA: void __usercall UnlockBunchOfFlics(int pBunch_index@<EAX>)
  1663. void UnlockBunchOfFlics(int pBunch_index) {
  1664.     int i;
  1665.     LOG_TRACE("(%d)", pBunch_index);
  1666.  
  1667.     for (i = 0; i < gFlic_bunch[pBunch_index].count; i++) {
  1668.         UnlockFlic(gFlic_bunch[pBunch_index].indexes[i]);
  1669.     }
  1670. }
  1671.  
  1672. // IDA: void __usercall FlushAllFlics(int pBunch_index@<EAX>)
  1673. void FlushAllFlics(int pBunch_index) {
  1674.     int i;
  1675.     LOG_TRACE("(%d)", pBunch_index);
  1676.  
  1677.     for (i = 0; i < COUNT_OF(gFlic_bunch); i++) {
  1678.         FreeFlic(i);
  1679.     }
  1680. }
  1681.  
  1682. // IDA: void __cdecl InitFlicQueue()
  1683. void InitFlicQueue(void) {
  1684.     gFirst_flic = NULL;
  1685. }
  1686.  
  1687. // IDA: int __cdecl FlicQueueFinished()
  1688. int FlicQueueFinished(void) {
  1689.     tFlic_descriptor* the_flic;
  1690.     LOG_TRACE("()");
  1691.  
  1692.     the_flic = gFirst_flic;
  1693.     while (the_flic != NULL) {
  1694.         if (the_flic->must_finish) {
  1695.             return 0;
  1696.         }
  1697.         the_flic = the_flic->next;
  1698.     }
  1699.     return 1;
  1700. }
  1701.  
  1702. // IDA: void __usercall ProcessFlicQueue(tU32 pInterval@<EAX>)
  1703. void ProcessFlicQueue(tU32 pInterval) {
  1704.     tFlic_descriptor* the_flic;
  1705.     tFlic_descriptor* last_flic;
  1706.     tFlic_descriptor* doomed_flic;
  1707.     tU32 new_time;
  1708.     int finished_playing;
  1709.     LOG_TRACE8("(%d)", pInterval);
  1710.  
  1711.     DontLetFlicFuckWithPalettes();
  1712.     TurnFlicTransparencyOn();
  1713.     the_flic = gFirst_flic;
  1714.     last_flic = NULL;
  1715.     new_time = PDGetTotalTime();
  1716.     while (the_flic != NULL) {
  1717.         if (new_time - the_flic->last_frame < the_flic->frame_period) {
  1718.             finished_playing = 0;
  1719.         } else {
  1720.             the_flic->last_frame = new_time;
  1721.             finished_playing = PlayNextFlicFrame(the_flic);
  1722.         }
  1723.         if (finished_playing) {
  1724.             EndFlic(the_flic);
  1725.             if (last_flic != NULL) {
  1726.                 last_flic->next = the_flic->next;
  1727.             } else {
  1728.                 gFirst_flic = the_flic->next;
  1729.             }
  1730.             doomed_flic = the_flic;
  1731.             the_flic = the_flic->next;
  1732.             BrMemFree(doomed_flic);
  1733.         } else {
  1734.             last_flic = the_flic;
  1735.             the_flic = the_flic->next;
  1736.         }
  1737.     }
  1738.     TurnFlicTransparencyOff();
  1739.     LetFlicFuckWithPalettes();
  1740. }
  1741.  
  1742. // IDA: void __cdecl FlushFlicQueue()
  1743. void FlushFlicQueue(void) {
  1744.     tFlic_descriptor* the_flic;
  1745.     tFlic_descriptor* old_flic;
  1746.     LOG_TRACE("()");
  1747.  
  1748.     // Jeff: loop through pending flics until we reach the end or we find one that is `must_finish`.
  1749.     // If `must_finish`, we process the queue then check again.
  1750.     // If there are no `must_finish` in the list, immediately end any remaining flics
  1751.  
  1752.     while (!FlicQueueFinished()) {
  1753.         RemoveTransientBitmaps(1);
  1754.         ProcessFlicQueue(gFrame_period);
  1755.         DoMouseCursor();
  1756.         PDScreenBufferSwap(0);
  1757.     }
  1758.     the_flic = gFirst_flic;
  1759.     while (the_flic != NULL) {
  1760.         EndFlic(the_flic);
  1761.         old_flic = the_flic;
  1762.         the_flic = the_flic->next;
  1763.         BrMemFree(old_flic);
  1764.     }
  1765.     gFirst_flic = NULL;
  1766. }
  1767.  
  1768. // IDA: void __usercall AddToFlicQueue(int pIndex@<EAX>, int pX@<EDX>, int pY@<EBX>, int pMust_finish@<ECX>)
  1769. void AddToFlicQueue(int pIndex, int pX, int pY, int pMust_finish) {
  1770.     tFlic_descriptor* the_flic = NULL;
  1771.     tFlic_descriptor* new_flic = NULL;
  1772.     tFlic_descriptor* last_flic = NULL;
  1773.     tFlic_descriptor* doomed_flic = NULL;
  1774.     LOG_TRACE("(%d, %d, %d, %d)", pIndex, pX, pY, pMust_finish);
  1775.  
  1776.     the_flic = gFirst_flic;
  1777.     while (the_flic != NULL) {
  1778.         if (pX == the_flic->x_offset && pY == the_flic->y_offset) {
  1779.             doomed_flic = the_flic;
  1780.             break;
  1781.         }
  1782.         last_flic = the_flic;
  1783.         the_flic = the_flic->next;
  1784.     }
  1785.  
  1786.     if (doomed_flic != NULL) {
  1787.         EndFlic(doomed_flic);
  1788.         if (last_flic != NULL) {
  1789.             last_flic->next = doomed_flic->next;
  1790.         } else {
  1791.             gFirst_flic = doomed_flic->next;
  1792.         }
  1793.         BrMemFree(doomed_flic);
  1794.     }
  1795.  
  1796.     LoadFlic(pIndex);
  1797.     new_flic = BrMemAllocate(sizeof(tFlic_descriptor), kMem_queued_flic);
  1798.     new_flic->next = NULL;
  1799.     the_flic = gFirst_flic;
  1800.     if (gFirst_flic != NULL) {
  1801.         while (the_flic->next != NULL) {
  1802.             the_flic = the_flic->next;
  1803.         }
  1804.         the_flic->next = new_flic;
  1805.     } else {
  1806.         gFirst_flic = new_flic;
  1807.     }
  1808.     new_flic->last_frame = 0;
  1809.     new_flic->data_start = NULL;
  1810.     new_flic->the_index = pIndex;
  1811.     new_flic->must_finish = pMust_finish;
  1812.  
  1813.     StartFlic(
  1814.         gMain_flic_list[pIndex].file_name,
  1815.         pIndex,
  1816.         new_flic,
  1817.         gMain_flic_list[pIndex].the_size,
  1818.         gMain_flic_list[pIndex].data_ptr,
  1819.         gBack_screen,
  1820.         pX >= 0 ? pX : gMain_flic_list[pIndex].x_offset,
  1821.         pY >= 0 ? pY : gMain_flic_list[pIndex].y_offset,
  1822.         20);
  1823. }
  1824.  
  1825. // IDA: void __usercall InitialiseFlicPanel(int pIndex@<EAX>, int pLeft@<EDX>, int pTop@<EBX>, int pWidth@<ECX>, int pHeight)
  1826. void InitialiseFlicPanel(int pIndex, int pLeft, int pTop, int pWidth, int pHeight) {
  1827.     void* the_pixels;
  1828.     LOG_TRACE("(%d, %d, %d, %d, %d)", pIndex, pLeft, pTop, pWidth, pHeight);
  1829.  
  1830.     gPanel_flic[pIndex].data = NULL;
  1831.     gPanel_flic_left[pIndex] = pLeft;
  1832.     gPanel_flic_top[pIndex] = pTop;
  1833.     the_pixels = BrMemAllocate(pHeight * ((pWidth + 3) & ~3), kFlic_panel_pixels);
  1834.     if (gScreen->row_bytes < 0) {
  1835.         BrFatal(
  1836.             "..\\..\\source\\common\\flicplay.c",
  1837.             2116,
  1838.             "Bruce bug at line %d, file ..\\..\\source\\common\\flicplay.c",
  1839.             68);
  1840.     }
  1841.     gPanel_buffer[pIndex] = DRPixelmapAllocate(gScreen->type, pWidth, pHeight, the_pixels, 0);
  1842. }
  1843.  
  1844. // IDA: void __usercall DisposeFlicPanel(int pIndex@<EAX>)
  1845. void DisposeFlicPanel(int pIndex) {
  1846.     LOG_TRACE("(%d)", pIndex);
  1847.  
  1848.     EndFlic(&gPanel_flic[pIndex]);
  1849.     BrMemFree(gPanel_buffer[pIndex]->pixels);
  1850.     BrPixelmapFree(gPanel_buffer[pIndex]);
  1851.     gPanel_buffer[pIndex] = NULL;
  1852. }
  1853.  
  1854. // IDA: void __usercall ServicePanelFlics(int pCopy_to_buffer@<EAX>)
  1855. void ServicePanelFlics(int pCopy_to_buffer) {
  1856.     tU32 time_diff;
  1857.     tU32 the_time;
  1858.     tU32 old_last_time[2];
  1859.     int i;
  1860.     int j;
  1861.     int iteration_count;
  1862.     int finished;
  1863.  
  1864.     if (gPanel_flic_disable) {
  1865.         return;
  1866.     }
  1867.     the_time = PDGetTotalTime();
  1868.     DontLetFlicFuckWithPalettes();
  1869.     TurnFlicTransparencyOn();
  1870.  
  1871.     for (i = 0; i < COUNT_OF(gPanel_flic); i++) {
  1872.         old_last_time[i] = gLast_panel_frame_time[i];
  1873.         if (gPanel_buffer[i] != NULL && gPanel_flic[i].data != NULL) {
  1874.             if (old_last_time[i] != 0) {
  1875.                 time_diff = the_time - old_last_time[i];
  1876.                 iteration_count = time_diff / gPanel_flic[i].frame_period;
  1877.             } else {
  1878.                 iteration_count = 1;
  1879.             }
  1880.             for (j = 0; j < iteration_count; j++) {
  1881.                 finished = PlayNextFlicFrame2(&gPanel_flic[i], 1);
  1882.                 if (finished) {
  1883.                     EndFlic(&gPanel_flic[i]);
  1884.                     StartFlic(
  1885.                         gPanel_flic[i].file_name,
  1886.                         gPanel_flic[i].the_index,
  1887.                         &gPanel_flic[i],
  1888.                         gPanel_flic_data_length[i],
  1889.                         (tS8*)gPanel_flic_data[i],
  1890.                         gPanel_buffer[i],
  1891.                         0,
  1892.                         0,
  1893.                         0);
  1894.                 }
  1895.                 gLast_panel_frame_time[i] = the_time;
  1896.             }
  1897.             if (pCopy_to_buffer) {
  1898.                 BrPixelmapRectangleCopy(
  1899.                     gBack_screen,
  1900.                     gPanel_flic_left[i],
  1901.                     gPanel_flic_top[i],
  1902.                     gPanel_buffer[i],
  1903.                     0,
  1904.                     0,
  1905.                     gPanel_buffer[i]->width,
  1906.                     gPanel_buffer[i]->height);
  1907.             }
  1908.         }
  1909.     }
  1910.     TurnFlicTransparencyOff();
  1911.     LetFlicFuckWithPalettes();
  1912. }
  1913.  
  1914. // IDA: void __usercall ChangePanelFlic(int pIndex@<EAX>, tU8 *pData@<EDX>, tU32 pData_length@<EBX>)
  1915. void ChangePanelFlic(int pIndex, tU8* pData, tU32 pData_length) {
  1916.     LOG_TRACE("(%d, %p, %d)", pIndex, pData, pData_length);
  1917.  
  1918.     EndFlic(&gPanel_flic[pIndex]);
  1919.     gPanel_flic_data[pIndex] = pData;
  1920.     gPanel_flic_data_length[pIndex] = pData_length;
  1921.     BrPixelmapFill(gPanel_buffer[pIndex], 0);
  1922.     StartFlic(
  1923.         gPanel_flic[pIndex].file_name,
  1924.         pIndex,
  1925.         &gPanel_flic[pIndex],
  1926.         gPanel_flic_data_length[pIndex],
  1927.         (tS8*)gPanel_flic_data[pIndex],
  1928.         gPanel_buffer[pIndex],
  1929.         0,
  1930.         0,
  1931.         0);
  1932.     gLast_panel_frame_time[pIndex] = 0;
  1933.     ServicePanelFlics(0);
  1934. }
  1935.  
  1936. // IDA: br_pixelmap* __usercall GetPanelPixelmap@<EAX>(int pIndex@<EAX>)
  1937. br_pixelmap* GetPanelPixelmap(int pIndex) {
  1938.     LOG_TRACE("(%d)", pIndex);
  1939.  
  1940.     return gPanel_buffer[pIndex];
  1941. }
  1942.  
  1943. // IDA: void __cdecl LoadInterfaceStrings()
  1944. void LoadInterfaceStrings(void) {
  1945.     FILE* f; // Added by DethRace
  1946.     char s[256];
  1947.     char s2[256];
  1948.     char* str;
  1949.     char* comment;
  1950.     char ch;
  1951.     tPath_name the_path;
  1952.     int i;
  1953.     int j;
  1954.     int len;
  1955.  
  1956.     gTranslation_count = 0;
  1957.     PathCat(the_path, gApplication_path, "TRNSLATE.TXT");
  1958.     f = fopen(the_path, "rt");
  1959.     if (f == NULL) {
  1960.         return;
  1961.     }
  1962.     while (!feof(f)) {
  1963.         GetALineAndDontArgue(f, s);
  1964.         gTranslation_count++;
  1965.     }
  1966.     rewind(f);
  1967.     gTranslations = BrMemAllocate(gTranslation_count * sizeof(tTranslation_record), kMem_translations);
  1968.     for (i = 0; i < gTranslation_count; i++) {
  1969.         GetALineAndDontArgue(f, s);
  1970.         str = strtok(s, "\t ,/");
  1971.         strcpy(s2, str);
  1972.         strtok(s2, ".");
  1973.         strcat(s2, ".FLI");
  1974.         gTranslations[i].flic_index = -1;
  1975.         for (j = 0; j < COUNT_OF(gMain_flic_list); j++) {
  1976.             if (strcmp(gMain_flic_list[j].file_name, s2) == 0) {
  1977.                 gTranslations[i].flic_index = j;
  1978.                 break;
  1979.             }
  1980.         }
  1981.         if (gTranslations[i].flic_index < 0) {
  1982.             FatalError(kFatalError_FindFlicUsedInTranslationFile_S, s2);
  1983.         }
  1984.         str[strlen(str)] = ',';
  1985.         str = strtok(s, "\t ,/");
  1986.         str = strtok(NULL, "\t ,/");
  1987.         sscanf(str, "%d", &gTranslations[i].x);
  1988.         str = strtok(NULL, "\t ,/");
  1989.         sscanf(str, "%d", &gTranslations[i].y);
  1990.         str = strtok(NULL, "\t ,/");
  1991.         sscanf(str, "%d", &gTranslations[i].font_index);
  1992.         str = strtok(NULL, "\t ,/");
  1993.         sscanf(str, "%c", &ch);
  1994.         switch (ch) {
  1995.         case 'C':
  1996.         case 'c':
  1997.             gTranslations[i].justification = eJust_centre;
  1998.             break;
  1999.         case 'L':
  2000.         case 'l':
  2001.             gTranslations[i].justification = eJust_left;
  2002.             break;
  2003.         case 'R':
  2004.         case 'r':
  2005.             gTranslations[i].justification = eJust_right;
  2006.             break;
  2007.         }
  2008.         str = strtok(NULL, "\t ,/");
  2009.         sscanf(str, "%c", &ch);
  2010.         gTranslations[i].global = ch == 'G' || ch == 'g';
  2011.         gTranslations[i].every_frame = strlen(str) > 1 && (str[1] == 'E' || str[1] == 'e');
  2012.         str += strlen(str) + 1;
  2013.         comment = strstr(str, "//");
  2014.         if (comment != NULL) {
  2015.             *comment = '\0';
  2016.         }
  2017.         len = strlen(str);
  2018.         for (j = len - 1; j >= 0 && (str[j] == ' ' || str[j] == '\t'); j--) {
  2019.         }
  2020.         str[j + 1] = '\0';
  2021.         gTranslations[i].text = BrMemAllocate(strlen(str) + 1, kMem_translations_text);
  2022.         strcpy(gTranslations[i].text, str);
  2023.     }
  2024.     LoadFont(kFont_BLUEHEAD);
  2025.     LoadFont(kFont_ORANGHED);
  2026.     LoadFont(kFont_GREENHED);
  2027.     LoadFont(kFont_LITPLAQ);
  2028.     LoadFont(kFont_BUTTOUT);
  2029.     LoadFont(kFont_DRKPLAQ);
  2030.     LoadFont(kFont_BUTTIN);
  2031.     LoadFont(kFont_GRNLIT);
  2032.     LoadFont(kFont_GRYLIT);
  2033.     LoadFont(kFont_GRNDK);
  2034.     LoadFont(kFont_GRYDK);
  2035.     LoadFont(kFont_LITPLAQ1);
  2036.     LoadFont(kFont_BUTTOUT1);
  2037.     LoadFont(kFont_DRKPLAQ1);
  2038.     LoadFont(kFont_BUTTIN1);
  2039.     gTrans_fonts[0] = &gFonts[kFont_ORANGHED];
  2040.     gTrans_fonts[1] = &gFonts[kFont_LITPLAQ];
  2041.     gTrans_fonts[2] = &gFonts[kFont_BUTTOUT];
  2042.     gTrans_fonts[3] = &gFonts[kFont_DRKPLAQ];
  2043.     gTrans_fonts[4] = &gFonts[kFont_BUTTIN];
  2044.     gTrans_fonts[5] = &gFonts[kFont_GRNLIT];
  2045.     gTrans_fonts[6] = &gFonts[kFont_GRYLIT];
  2046.     gTrans_fonts[7] = &gFonts[kFont_GRNDK];
  2047.     gTrans_fonts[8] = &gFonts[kFont_GRYDK];
  2048.     gTrans_fonts[9] = &gFonts[kFont_LITPLAQ1];
  2049.     gTrans_fonts[10] = &gFonts[kFont_DRKPLAQ1];
  2050.     gTrans_fonts[11] = &gFonts[kFont_BUTTOUT1];
  2051.     gTrans_fonts[12] = &gFonts[kFont_BUTTIN1];
  2052.  
  2053. #ifdef DETHRACE_FIX_BUGS
  2054.     fclose(f);
  2055. #endif
  2056. }
  2057.  
  2058. // IDA: void __cdecl FlushInterfaceFonts()
  2059. void FlushInterfaceFonts(void) {
  2060.     LOG_TRACE("()");
  2061.  
  2062.     DisposeFont(19);
  2063.     DisposeFont(18);
  2064.     DisposeFont(20);
  2065.     DisposeFont(17);
  2066.     DisposeFont(15);
  2067.     DisposeFont(14);
  2068.     DisposeFont(16);
  2069.     DisposeFont(13);
  2070. }
  2071.  
  2072. // IDA: void __cdecl SuspendPendingFlic()
  2073. void SuspendPendingFlic(void) {
  2074.     LOG_TRACE("()");
  2075.  
  2076.     gPending_pending_flic = gPending_flic;
  2077.     gPending_flic = -1;
  2078. }
  2079.  
  2080. // IDA: void __cdecl ResumePendingFlic()
  2081. void ResumePendingFlic(void) {
  2082.     LOG_TRACE("()");
  2083.  
  2084.     gPending_flic = gPending_pending_flic;
  2085. }
  2086.