Advertisement
Guest User

Untitled

a guest
Aug 1st, 2011
617
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 36.00 KB | None | 0 0
  1. /*  NesYar/tools/ftm-exporter.c */
  2.  
  3. /*  Converts FamiTracker "FTM" files into ca65 sources.
  4.     Based on FamiTracker 0.3.5, http://famitracker.shoodot.net/downloads.php
  5.     Inspired by "Famitone", Copyright 2010, Shiru (nesdev.parodius.com)
  6.     Please see "./source/DocumentFile.cpp" and "./source/FamiTrackerDoc.cpp"
  7. */
  8.  
  9. /*
  10. ** ftm-exporter
  11. ** Copyright (C) 2011  Dennis Jenkins
  12. **
  13. ** This code is in the public domain.  Do as you wish with it, but
  14. ** don't sue me if it breaks anything.  Use at your own risk.
  15. */
  16.  
  17.  
  18. #if defined(_WIN32)
  19. #pragma warning (disable: 4786)
  20. #define _CRT_SECURE_NO_WARNINGS
  21. #endif
  22.  
  23. #include <stddef.h>
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <stdarg.h>
  27. #include <string.h>
  28. #include <assert.h>
  29. #include <time.h>
  30. #include <math.h>
  31.  
  32. #if defined(_WIN32)
  33. #define snprintf _snprintf
  34. #endif
  35.  
  36. typedef unsigned char byte;
  37. typedef unsigned short int word;
  38. typedef unsigned long dword;
  39.  
  40. // FamiTracker specific constants.
  41. #define BLOCK_ID_SIZE       16
  42. #define MAX_BLOCK_SIZE      0x80000
  43. #define MAX_STRINGZ_LEN     256
  44. #define SEQ_COUNT       5           // FamiTrackerDoc.h, line #126
  45. #define MAX_SEQUENCES       128         // FamiTrackerDoc.h, line #47
  46. #define MAX_SEQUENCE_ITEMS  128         // FamiTrackerDoc.h, line #50
  47. #define MAX_INSTRUMENTS     64          // FamiTrackerDoc.h, line #44
  48. #define MAX_EFFECT_COLUMNS  4           // FamiTrackerDoc.h, line #58
  49. #define MAX_CHANNELS        16          // I'm just guessing...
  50. #define MAX_TUNES       64          // FamiTrackerDoc.h, line #74 (MAX_TRACKS)
  51. #define MAX_PATTERNS        128         // FamiTrackerDoc.h, line #52
  52. #define MAX_PATTERN_LENGTH  256         // FamiTrackerDoc.h, line #54
  53. #define OCTAVE_RANGE            8
  54. #define FILE_VERSION            0x0420          // FT v 0.3.6-beta4, 2010-12-30.
  55. static const char FILE_HEADER[] = "FamiTracker Module";
  56.  
  57. // My own constants.
  58. #define MAX_NOTE_NAMES      15
  59. #define NOTE_MAX_RANGE      (12*9)
  60. #define NES_APU_CHANNELS    5
  61.  
  62. // Passed as first argument into "doWarning"
  63. #define NON_FATAL       0
  64. #define FATAL           1
  65.  
  66. typedef enum eSyntax
  67. {
  68.     SYNTAX_CA65,
  69.     SYNTAX_NESASM
  70. } eSyntax;
  71.  
  72. typedef enum eTarget
  73. {
  74.     TARGET_FAMITONE,        // Designed for Shiru's Famitone player.
  75.     TARGET_GRADUALORE,      // Same output as Gradualore's Famitracker plugin.
  76.     TARGET_ECOLIGAMES,      // For my own music player.
  77. } eTarget;
  78.  
  79. typedef enum eInstruments
  80. {
  81.     INST_2A03 = 1,
  82.     INST_VRC6,
  83.     INST_VRC7,
  84.     INST_FDS,
  85.     INST_N106,
  86.     INST_5B
  87. } eInstruments;
  88.  
  89. typedef enum eSequences
  90. {
  91.     SEQ_VOLUME,
  92.     SEQ_ARPEGGIO,
  93.     SEQ_PITCH,
  94.     SEQ_HIPITCH,
  95.     SEQ_DUTYCYCLE
  96. } eSequences;
  97.  
  98. typedef enum eEffects
  99. {
  100.     EF_NONE = 0,
  101.     EF_SPEED,       // 'F'
  102.     EF_JUMP,        // 'B'
  103.     EF_SKIP,        // 'D'
  104.     EF_HALT,        // 'C'
  105.     EF_VOLUME,      // 'E'
  106.     EF_PORTAMENTO,      // '3'
  107.     EF_PORTAOFF,        // unused!!
  108.     EF_SWEEPUP,     // 'H'
  109.     EF_SWEEPDOWN,       // 'I'
  110.     EF_ARPEGGIO,        // '0'
  111.     EF_VIBRATO,     // '4'
  112.     EF_TREMOLO,     // '7'
  113.     EF_PITCH,       // 'P'
  114.     EF_DELAY,       // 'G'
  115.     EF_DAC,         // 'Z'
  116.     EF_PORTA_UP,        // '1'
  117.     EF_PORTA_DOWN,      // '2'
  118.     EF_DUTY_CYCLE,      // 'V'
  119.     EF_SAMPLE_OFFSET,   // 'Y'
  120.     EF_SLIDE_UP,        // 'Q'
  121.     EF_SLIDE_DOWN,      // 'R'
  122.     EF_VOLUME_SLIDE,    // 'A'
  123.     EF_NOTE_CUT,        // 'S'
  124.     EF_RETRIGGER,       // 'X'
  125. //  EF_DELAYED_VOLUME,  // 'J'
  126.     EF_COUNT
  127. } eEffects;
  128.  
  129. // Channel effect letters
  130. static const char EFF_CHAR[] =
  131. {
  132.     'F',    // Speed
  133.     'B',    // Jump
  134.     'D',    // Skip
  135.     'C',    // Halt
  136.     'E',    // Volume
  137.     '3',    // Porta on
  138.     ' ',    // Porta off        // unused
  139.     'H',    // Sweep up
  140.     'I',    // Sweep down
  141.     '0',    // Arpeggio
  142.     '4',    // Vibrato
  143.     '7',    // Tremolo
  144.     'P',    // Pitch
  145.     'G',    // Note delay
  146.     'Z',    // DAC setting
  147.     '1',    // Portamento up
  148.     '2',    // Portamento down
  149.     'V',    // Duty cycle
  150.     'Y',    // Sample offset
  151.     'Q',    // Slide up
  152.     'R',    // Slide down
  153.     'A',    // Volume slide
  154.     'S',    // Note cut
  155.     'X',    // DPCM retrigger
  156. //  'J',    // Delayed volume
  157. };
  158.  
  159. typedef enum eNotes
  160. {
  161.     NOTE_NONE = 0,
  162.     NOTE_C,
  163.     NOTE_Cs,
  164.     NOTE_D,
  165.     NOTE_Ds,
  166.     NOTE_E,
  167.     NOTE_F,
  168.     NOTE_Fs,
  169.     NOTE_G,
  170.     NOTE_Gs,
  171.     NOTE_A,
  172.     NOTE_As,
  173.     NOTE_B,
  174.     NOTE_RELEASE,       // Release, note release
  175.     NOTE_HALT,      // Halt, note cut (a ***)
  176. } eNotes;
  177.  
  178. typedef enum eMachine
  179. {
  180.     NTSC,
  181.     PAL
  182. } eMachine;
  183.  
  184. typedef enum eVibrato
  185. {
  186.     VIBRATO_OLD = 0,
  187.     VIBRATO_NEW,
  188. } eVibrato;
  189.  
  190.  
  191.  
  192. typedef struct  BLOCK
  193. {
  194.     char        id[BLOCK_ID_SIZE + 1];
  195.     int     ver;
  196.     int     len;
  197.     size_t      file_pos;
  198.     byte        *data;
  199.     byte        *ptr;
  200. } BLOCK;
  201.  
  202. typedef struct  PARAMS
  203. {
  204.     int     expansion_chip;     // FTM ver 2 (char)
  205.     int     channels_avail;
  206.     int     machine;
  207.     int     engine_speed;
  208.     int     vibrato_style;      // FTM ver 3
  209. } PARAMS;
  210.  
  211. typedef struct  INFO
  212. {
  213.     char        song_name[33];
  214.     char        artist[33];
  215.     char        copyright[33];
  216. } INFO;
  217.  
  218. typedef struct  HEADER
  219. {
  220.     int     nTuneCount;
  221.     int     vChannelTypes[MAX_CHANNELS];
  222. } HEADER;
  223.  
  224. typedef struct  INST_SEQ
  225. {
  226.     int     nIndex;
  227.     int     nEnabled;
  228. } INST_SEQ;
  229.  
  230. typedef struct  INSTRUMENT
  231. {
  232.     int     nUsed;
  233.     int     nIndex;         // FIXME: We probably don't need this...
  234.     int     nType;
  235.     char        *pszName;
  236.     INST_SEQ    vSequences[SEQ_COUNT];
  237. } INSTRUMENT;
  238.  
  239. typedef struct  SEQUENCE
  240. {
  241.     int     nUsed;
  242.     int     nIndex;
  243.     int     nType;
  244.     int     nLoopPoint;
  245.     int     nSampleCount;
  246.     byte        *vSamples;      // 1-D array
  247.     byte        nReleasePoint;
  248.     int     nSetting;
  249. } SEQUENCE;
  250.  
  251. typedef struct  TUNE
  252. {
  253. // Read from "FRAME"
  254.     int     nIndex;
  255.     int     nFrameCount;        // Rows of 64 patterns.
  256.     int     nSongSpeed;
  257.     int     nSongTempo;
  258.     int     nPatternLength;
  259.     int     *vPatterns;     // 2-D array, [frame][channel]
  260.     char        *pszName;       // From "HEADER".
  261.  
  262. // Read from "HEADER"
  263.     int     nEffectColumns[MAX_CHANNELS];
  264. } TUNE;
  265.  
  266. typedef struct EFFECT
  267. {
  268.     byte        number;
  269.     byte        param;
  270. } EFFECT;
  271.  
  272. typedef struct  NOTE
  273. {
  274.     eNotes      note;           // Represents frequency of note being played.
  275.     byte        octave;
  276.     byte        vol;
  277.     byte        instrument;
  278.     EFFECT      effects[MAX_EFFECT_COLUMNS];
  279. } NOTE;
  280.  
  281. typedef struct  PATTERN
  282. {
  283.     int     nTune;
  284.     int     nChannel;       // sq1, sq2, etc...
  285.     int     nIndex;
  286.     int     nNotes;
  287.     NOTE        notes[MAX_PATTERN_LENGTH];
  288. } PATTERN;
  289.  
  290. typedef struct  FTM_FILE
  291. {
  292. // Data read from file.
  293.     int     file_version;
  294.     PARAMS      params;
  295.     INFO        info;
  296.     HEADER      header;
  297.     INSTRUMENT  instruments[MAX_INSTRUMENTS];
  298.     SEQUENCE    sequences[SEQ_COUNT][MAX_SEQUENCES];        // [type][nIndex]
  299.     TUNE        *tunes[MAX_TUNES];              // Called "Frames" in FTM file.
  300.     PATTERN     *patterns[MAX_TUNES][MAX_CHANNELS][MAX_PATTERNS];
  301. } FTM_FILE;
  302.  
  303.  
  304. typedef struct  BLOCK_FUNC
  305. {
  306.     char        *id;
  307.     int     (*func)(FTM_FILE *ftm);
  308. } BLOCK_FUNC;
  309.  
  310.  
  311. // Globals:
  312. static char     symbol_prefix[32];
  313. static char     *segname = NULL;
  314. static char     *ifname = "stdin";
  315. static FILE     *ifp;
  316. static FILE     *ofp;
  317. static int      verbose = 0;
  318. static int      warnings_are_fatal = 0;
  319. static BLOCK        block = {{0}};
  320. static byte     blockdata[MAX_BLOCK_SIZE];  // Leave in BSS, do not initialize.
  321.  
  322. static eSyntax      syntax = SYNTAX_CA65;
  323. static eTarget      target = TARGET_ECOLIGAMES;
  324. static int      bytes_out = 0;
  325. static int      warnings = 0;
  326.  
  327. static void doWarning (int nFatal, int src_line, const FTM_FILE *ftm, const char *fmt, ...)
  328. {
  329.     va_list     va;
  330.     const char  *err = nFatal ? "ERROR" : "WARNING";
  331.  
  332.     fprintf (stderr, "\n%s: ", err);
  333.     va_start (va, fmt);
  334.     vfprintf (stderr, fmt, va);
  335.     fprintf (stderr, "\n");
  336.     va_end (va);
  337.  
  338.     if (ifname) { fprintf (stderr, "  Input file: %s\n", ifname); }
  339.     if (ifp) { fprintf (stderr, "  Input byte offset: %ld\n", ftell (ifp)); }
  340.     if (src_line) { fprintf (stderr, "  ftm-exporter src line %d:\n", src_line); }
  341.  
  342.     if (warnings_are_fatal || nFatal)
  343.     {
  344.         exit (-1);
  345.     }
  346.  
  347.     warnings++;
  348. }
  349.  
  350.  
  351.  
  352. static __inline PATTERN* getPattern (FTM_FILE *ftm, int tune, int channel, int pattern)
  353. {
  354.     PATTERN     *p;
  355.  
  356.     assert (ftm);
  357.     assert (tune >= 0);
  358.     assert (tune < ftm->header.nTuneCount);
  359.     assert (channel >= 0);
  360.     assert (channel < ftm->params.channels_avail);
  361.     assert (pattern >= 0);
  362.     assert (pattern < MAX_PATTERNS);
  363.  
  364.     if (NULL == (p = ftm->patterns[tune][channel][pattern]))
  365.     {
  366.         p = ftm->patterns[tune][channel][pattern] = (PATTERN*)calloc (1, sizeof(PATTERN));
  367.         p->nTune = tune;
  368.         p->nChannel = channel;
  369.         p->nIndex = pattern;
  370.     }
  371.  
  372.     return p;
  373. }
  374.  
  375. static __inline int getPatternForTune (const FTM_FILE *ftm, int tune, int frame, int channel)
  376. {
  377.     assert (ftm);
  378.     assert (tune >= 0);
  379.     assert (tune < ftm->header.nTuneCount);
  380.     assert (ftm->tunes[tune]);
  381.     assert (frame >= 0);
  382.     assert (frame < ftm->tunes[tune]->nFrameCount);
  383.     assert (channel >= 0);
  384.     assert (channel < ftm->params.channels_avail);
  385.  
  386.     return ftm->tunes[tune]->vPatterns[frame * ftm->params.channels_avail + channel];
  387. }
  388.  
  389. static __inline TUNE* getTune (FTM_FILE *ftm, int tune)
  390. {
  391.     assert (ftm);
  392.     assert (tune >= 0);
  393.     assert (tune < ftm->header.nTuneCount);
  394.  
  395.     if (ftm->tunes[tune])
  396.     {
  397.         return ftm->tunes[tune];
  398.     }
  399.  
  400.     ftm->tunes[tune] = (TUNE*)calloc (1, sizeof(TUNE));
  401.     return ftm->tunes[tune];
  402. }
  403.  
  404.  
  405.  
  406. static const char *szNoteNames[12] =
  407. {
  408.     "C-", "C#", "D-", "D#",
  409.     "E-", "F-", "F#", "G-",
  410.     "G#", "A-", "A#", "B-",
  411. };
  412.  
  413. // "dest" should be 4 bytes or larger!
  414. static __inline int noteName(char *dest, int destlen, const NOTE *pNote)
  415. {
  416.     switch (pNote->note)
  417.     {
  418.         case NOTE_NONE:
  419.             return snprintf (dest, destlen, "none");
  420.  
  421.         case NOTE_RELEASE:
  422.             return snprintf (dest, destlen, "release");
  423.  
  424.         case NOTE_HALT:
  425.             return snprintf (dest, destlen, "halt");
  426.  
  427.         default:
  428.             if ((pNote->note >= NOTE_C) && (pNote->note <= NOTE_B))
  429.             {
  430.                 return snprintf (dest, destlen, "%2s%d", szNoteNames[pNote->note - NOTE_C], pNote->octave);
  431.             }
  432.     }
  433.  
  434.     return snprintf (dest, destlen, "unknown[%d,%d]", pNote->note, pNote->octave);
  435. }
  436.  
  437. static const char *szSequenceNames[SEQ_COUNT] =
  438. {
  439.     "vol", "arp", "pitch", "hipitch", "duty"
  440. };
  441.  
  442. static const float fDutyCycles[4] =
  443. {
  444.     12.5, 25.0, 50.0, 75.0
  445. };
  446.  
  447. static const char *szChannelNames[NES_APU_CHANNELS] =
  448. {
  449.     "sq1", "sq2", "tri", "noise", "dpcm"
  450. };
  451.  
  452. static char     blk_char (void)
  453. {
  454.     char ch = *(char*)(block.ptr);
  455.     block.ptr += sizeof (char);
  456.     return ch;
  457. }
  458.  
  459. static byte     blk_byte (void)
  460. {
  461.     byte by = *(byte*)(block.ptr);
  462.     block.ptr += sizeof (byte);
  463.     return by;
  464. }
  465.  
  466. static int      blk_int (void)
  467. {
  468.     int i = *(int*)(block.ptr);
  469.     block.ptr += sizeof (int);
  470.     return i;
  471. }
  472.  
  473. // "dest" MUST be "len+1" characters.
  474. static char*    blk_stringf (char *dest, int len)
  475. {
  476.     strncpy (dest, (const char*)block.ptr, len);
  477.     dest[len] = 0;
  478.     block.ptr += len;
  479.     return dest;
  480. }
  481.  
  482. // zero terminated string.
  483. static char*    blk_stringz (char *dest, int maxlen)
  484. {
  485.     block.ptr += snprintf (dest, maxlen, "%s", (const char*)block.ptr);
  486.     block.ptr++;    // Skip 'NUL' at end of string.
  487.     return dest;
  488. }
  489.  
  490.  
  491.  
  492. static int      read_params (FTM_FILE *ftm)
  493. {
  494.     ftm->params.expansion_chip = blk_char ();   // Read as char, stored as int.
  495.     ftm->params.channels_avail = blk_int ();
  496.     ftm->params.machine = blk_int ();
  497.     ftm->params.engine_speed = blk_int ();
  498.  
  499.     ftm->params.vibrato_style = 0;
  500.     if (block.ver >= 3)
  501.     {
  502.         ftm->params.vibrato_style = blk_int();
  503.     }
  504.  
  505.     if (ftm->params.channels_avail >= MAX_CHANNELS)
  506.     {
  507.         doWarning (FATAL, __LINE__, ftm, "params.channels_avail (%d) >= MAX_CHANNELS (%d).", ftm->params.channels_avail, MAX_CHANNELS);
  508.         return -1;
  509.     }
  510.  
  511.     return 0;
  512. }
  513.  
  514. static int      read_info (FTM_FILE *ftm)
  515. {
  516.     blk_stringf (ftm->info.song_name, 32);
  517.     blk_stringf (ftm->info.artist, 32);
  518.     blk_stringf (ftm->info.copyright, 32);
  519.  
  520.     return 0;
  521. }
  522.  
  523. static int      read_header (FTM_FILE *ftm)
  524. {
  525.     int     tune;
  526.     int     chan;
  527.     char        name[MAX_STRINGZ_LEN + 1];
  528.  
  529. // FamiTracker stores "tunes" minus one in the disk file.
  530. // I hate doing math that way in for loops, so I bump the value by one.
  531.  
  532.     ftm->header.nTuneCount = 1 + blk_char();    // CFamiTrackerDoc::WriteBlock_Header, line #483.
  533.  
  534.     for (tune = 0; tune < ftm->header.nTuneCount; tune++)
  535.     {
  536.         if (block.ver >= 3)
  537.         {
  538.             blk_stringz (name, sizeof(name));
  539.         }
  540.         else
  541.         {
  542.             name[0] = 0;
  543.         }
  544.  
  545.         getTune (ftm, tune)->pszName = strdup (name);
  546.     }
  547.  
  548.     for (chan = 0; chan < ftm->params.channels_avail; chan++)
  549.     {
  550.         ftm->header.vChannelTypes[chan] = blk_char();   // Read as char, stored as int.
  551.  
  552.         for (tune = 0; tune < ftm->header.nTuneCount; tune++)
  553.         {
  554.             getTune (ftm, tune)->nEffectColumns[chan] = blk_char ();
  555.         }
  556.     }
  557.  
  558.     return 0;
  559. }
  560.  
  561. static int      read_instruments (FTM_FILE *ftm)
  562. {
  563.     INSTRUMENT  *p = NULL;
  564.     int     nCount = 0;
  565.     int     nIndex = 0;
  566.     int     nSeqCount = 0;
  567.     int     nOctaves = 0;
  568.     int     index = 0;
  569.     int     seq = 0;
  570.     int     octave = 0;
  571.     int     namelen = 0;
  572.     int     j = 0;
  573.  
  574.     if (block.ver != 2)
  575.     {
  576.         doWarning (FATAL, __LINE__, ftm, "INSTRUMENT block version (%d) != 2.", block.ver);
  577.         return -1;
  578.     }
  579.  
  580.     nCount = blk_int ();    // Line #254.
  581.     if (nCount >= MAX_INSTRUMENTS)
  582.     {
  583.         doWarning (FATAL, __LINE__, ftm, "Too many instruments (%d).  Max = %d.", nCount, MAX_INSTRUMENTS);
  584.         return -1;
  585.     }
  586.  
  587.     for (index = 0; index < nCount; index++)
  588.     {
  589.         nIndex = blk_int();
  590.  
  591.         if (nIndex != index)
  592.         {
  593.             doWarning (NON_FATAL, __LINE__, ftm, "Instrument '%d' is out of order, expected '%d'.", nIndex, index);
  594.         }
  595.  
  596.         p = ftm->instruments + nIndex;
  597.  
  598.         p->nUsed = 1;
  599.         p->nIndex = nIndex;
  600.         p->nType = blk_char();
  601.  
  602. // Read vSequences().
  603. // bool CInstrument2A03::Load(CDocumentFile *pDocFile), Line #85
  604.  
  605.         nSeqCount = blk_int();
  606.         if (nSeqCount > SEQ_COUNT)
  607.         {
  608.             doWarning (FATAL, __LINE__, ftm, "Instrument '%d' has too many sequences (%d), max = %d.", nIndex, nSeqCount, SEQ_COUNT);
  609.             return -1;
  610.         }
  611.  
  612.         for (seq = 0; seq < nSeqCount; seq++)
  613.         {
  614.             p->vSequences[seq].nEnabled =  blk_char();
  615.             p->vSequences[seq].nIndex = blk_char();
  616.  
  617.             if (p->vSequences[seq].nIndex > MAX_SEQUENCES)
  618.             {
  619.                 doWarning (FATAL, __LINE__, ftm, "Instrument '%d' references out-of-range sequence %d.", nIndex, seq);
  620.                 return -1;
  621.             }
  622.         }
  623.  
  624. // Eat and discard the "octaves".
  625.         nOctaves = (block.ver == 1) ? 6 : OCTAVE_RANGE;         // Line #102.
  626.  
  627.         for (octave = 0; octave < nOctaves; octave++)
  628.         {
  629.             for (j = 0; j < 12; j++)
  630.             {
  631.                 blk_char();         // index
  632.                 blk_char();         // pitch
  633.             }
  634.         }
  635.  
  636.         if (0 < (namelen = blk_int()))
  637.         {
  638.             p->pszName = (char*)malloc (namelen + 1);
  639.             blk_stringf (p->pszName, namelen);
  640.         }
  641.     }
  642.  
  643.     return 0;
  644. }
  645.  
  646.  
  647. // void CFamiTrackerDoc::WriteBlock_Sequences(CDocumentFile *pDocFile)
  648. // bool CFamiTrackerDoc::ReadBlock_Sequences(CDocumentFile *pDocFile), Line #1363
  649. static int      read_sequences (FTM_FILE *ftm)
  650. {
  651.     SEQUENCE    *p = NULL;
  652.     int     nSeqCount = 0;
  653.     int     seq = 0;
  654.     int     nIndex = 0;
  655.     int     nType = 0;
  656.     int     i = 0;
  657.     int     map[MAX_SEQUENCES] = {0};
  658.  
  659.     if (block.ver < 3)
  660.     {
  661.         doWarning (FATAL, __LINE__, ftm, "Unable to read SEQEUNCES version %d (want >= 3).", block.ver);
  662.         return -1;
  663.     }
  664.  
  665.     nSeqCount = blk_int ();     // Line #524
  666.     if (nSeqCount >= MAX_SEQUENCES)
  667.     {
  668.         doWarning (FATAL, __LINE__, ftm, "Too many sequences (%d), max = %d.", nSeqCount, MAX_SEQUENCES);
  669.         return -1;
  670.     }
  671.  
  672.     for (seq = 0; seq < nSeqCount; seq++)
  673.     {
  674.         nIndex = blk_int ();
  675.         if (nIndex > MAX_SEQUENCES)
  676.         {
  677.             doWarning (FATAL, __LINE__, ftm, "Sequence '%d' is out of range (%d).", nIndex, MAX_SEQUENCES);
  678.             return -1;
  679.         }
  680.  
  681.         nType = blk_int();
  682.         if (nType > SEQ_COUNT)
  683.         {
  684.             doWarning (FATAL, __LINE__, ftm, "Sequence '%d' type (%d) is out of range.", nIndex, nType);
  685.             return -1;
  686.         }
  687.  
  688.         p = &(ftm->sequences[nType][nIndex]);
  689.  
  690.         p->nUsed = 1;
  691.         p->nIndex = nIndex;
  692.         p->nType = nType;
  693.         p->nSampleCount = blk_byte ();
  694.         p->nLoopPoint = blk_int ();
  695.  
  696.         map[nIndex] = seq;
  697.  
  698.         if (p->nSampleCount >= MAX_SEQUENCE_ITEMS)
  699.         {
  700.             doWarning (FATAL, __LINE__, ftm, "Sequence '%d' is too long.", nIndex);
  701.             return -1;
  702.         }
  703.  
  704.         if (block.ver == 4)     // FamiTrackerDoc.cpp, line #1433.
  705.         {
  706.             p->nReleasePoint = blk_int ();
  707.             p->nSetting = blk_int ();
  708.         }
  709.  
  710.         p->vSamples = (byte*)calloc (p->nSampleCount, sizeof (p->vSamples[0]));
  711.         for (i = 0; i < p->nSampleCount; i++)
  712.         {
  713.             p->vSamples[i] = blk_byte ();
  714.         }
  715.     }
  716.  
  717. // FIXME: This code is WRONG.  See FamiTrackerDoc.cpp, line #1446.
  718. // "m_Sequences2A03[][] is two dimensional, yet my crap above is one-dimensional...
  719.  
  720.     if (block.ver >= 5)
  721.     {
  722.         for (i = 0; i < nSeqCount; i++)
  723.         {
  724. //          ftm->sequences[map[i]].nReleasePoint = blk_int ();
  725. //          ftm->sequences[map[i]].nSetting = blk_int ();
  726.             blk_int ();
  727.             blk_int ();
  728.         }
  729.     }
  730.  
  731.     return 0;
  732. }
  733.  
  734. static int      read_frames (FTM_FILE *ftm)
  735. {
  736.     int     tune = 0;
  737.     TUNE        *s = NULL;
  738.     int     nPatterns = 0;
  739.     int     i = 0;
  740.  
  741.     if (block.ver != 3)
  742.     {
  743.         doWarning (FATAL, __LINE__, ftm, "Unable to load FRAMES version %d, expected %d.", block.ver, 3);
  744.         return -1;
  745.     }
  746.  
  747.     for (tune = 0; tune < ftm->header.nTuneCount; tune++)
  748.     {
  749.         s = getTune (ftm, tune);
  750.  
  751.         s->nFrameCount = blk_int ();            // FamiTrackerDoc.cpp, line #679.
  752.         s->nSongSpeed = blk_int ();
  753.         s->nSongTempo = blk_int ();
  754.         s->nPatternLength = blk_int ();
  755.         s->nIndex = tune;
  756.  
  757.         nPatterns = s->nFrameCount * ftm->params.channels_avail;
  758.         s->vPatterns = (int*)calloc (nPatterns, sizeof (s->vPatterns[0]));
  759.  
  760.         for (i = 0; i < nPatterns; i++)
  761.         {
  762.             // 2-D array, [frame][channel]
  763.             s->vPatterns[i] = blk_char ();      // Converting from char to int.
  764.         }
  765.     }
  766.  
  767.     return 0;
  768. }
  769.  
  770. // bool CFamiTrackerDoc::ReadBlock_Patterns(CDocumentFile *pDocFile)
  771. // FamiTrackerDoc.cpp, line #1610.
  772. static int      read_patterns (FTM_FILE *ftm)
  773. {
  774.     int     nTune = 0;
  775.     int     nChannel = 0;
  776.     int     nPattern = 0;
  777.     int     nItems = 0;
  778.     int     item = 0;               // Loop variable.
  779.     int     nItem = 0;              // Read from FTM file.
  780.     int     effect = 0;             // Loop variable.
  781.     NOTE        *pNote = NULL;
  782.     PATTERN     *pPattern = NULL;
  783.  
  784.     if (block.ver != 4)
  785.     {
  786.         doWarning (FATAL, __LINE__, ftm, "Unable to load PATTERNS version %d, expected %d.", block.ver, 4);
  787.         return -1;
  788.     }
  789.  
  790. // File does not encode how many to read.  We just read until we hit end of the block.
  791.     while (block.ptr < block.data + block.len)      // Line #1622
  792.     {
  793.         nTune = blk_int ();             // FT calls this a "track".
  794.         nChannel = blk_int ();
  795.         nPattern = blk_int ();
  796.         nItems = blk_int ();
  797.  
  798.         if (nTune >= MAX_TUNES)
  799.         {
  800.             doWarning (FATAL, __LINE__, ftm, "Pattern.track (%d) is out of range (%d).", nTune, MAX_TUNES);
  801.             return -1;
  802.         }
  803.  
  804.         if (nChannel >= MAX_CHANNELS)
  805.         {
  806.             doWarning (FATAL, __LINE__, ftm, "Pattern.channel (%d) is out of range (%d).", nChannel, MAX_CHANNELS);
  807.             return -1;
  808.         }
  809.  
  810.         if (nPattern >= MAX_PATTERNS)
  811.         {
  812.             doWarning (FATAL, __LINE__, ftm, "Pattern.index (%d) is out of range (%d).", nPattern, MAX_PATTERNS);
  813.             return -1;
  814.         }
  815.  
  816.         if ((nItems - 1) >= MAX_PATTERN_LENGTH)
  817.         {
  818.             doWarning (FATAL, __LINE__, ftm, "Pattern.length (%d) is out of range (%d).", nItems, MAX_PATTERN_LENGTH);
  819.             return -1;
  820.         }
  821.  
  822.         pPattern = getPattern (ftm, nTune, nChannel, nPattern);
  823.  
  824.         for (item = 0; item < nItems; item++)
  825.         {
  826.             nItem = blk_int();      // Line #1643 (min file ver > 0x0200, so this is ok).
  827.  
  828.             if (nItem >= MAX_PATTERN_LENGTH)
  829.             {
  830.                 doWarning (FATAL, __LINE__, ftm, "Pattern[%d,%d,%d] contains item %d, out of range (%d).",
  831.                     nTune, nChannel, nPattern, nItem, MAX_PATTERN_LENGTH);
  832.                 return -1;
  833.             }
  834.  
  835.             pPattern->nNotes++;
  836.             pNote = pPattern->notes + nItem;
  837.  
  838.             pNote->note = blk_byte ();  // Line #1650
  839.             pNote->octave = blk_byte ();
  840.             pNote->instrument = blk_byte ();
  841.             pNote->vol = blk_byte ();
  842.  
  843.             // 2011-04-01, Instruments == MAX_INSTRUMENTS mean "note cut".
  844.             if (pNote->instrument > MAX_INSTRUMENTS)
  845.             {
  846.                 doWarning (FATAL, __LINE__, ftm, "Note's instrument is %d (> %d).", pNote->instrument, MAX_INSTRUMENTS);
  847.             }
  848.  
  849. // Read effects (line #1676)
  850.             for (effect = 0; effect < getTune (ftm, nTune)->nEffectColumns[nChannel] + 1; effect++)
  851.             {
  852.                 pNote->effects[effect].number = blk_byte ();
  853.                 pNote->effects[effect].param = blk_byte ();
  854.  
  855.                 if (block.ver < 3)
  856.                 {
  857.                     if (pNote->effects[effect].number == EF_PORTAOFF)
  858.                     {
  859.                         pNote->effects[effect].number = EF_PORTAMENTO;
  860.                         pNote->effects[effect].param = 0;
  861.                     }
  862.                     else if (pNote->effects[effect].number == EF_PORTAMENTO)
  863.                     {
  864.                         if (pNote->effects[effect].param < 0xff)
  865.                         {
  866.                             pNote->effects[effect].param++;
  867.                         }
  868.                     }
  869.                 }
  870.             }
  871.         }
  872.     }
  873.  
  874.     return 0;
  875. }
  876.  
  877. static int      read_dpcm_samples (FTM_FILE *ftm)
  878. {
  879.     return 0;
  880. }
  881.  
  882. // Returns # bytes read, or -1 on error (its an error to fail to read nBytes).
  883. static int      ftm_read (FTM_FILE *ftm, void *pBuffer, size_t nBytes)
  884. {
  885.     size_t      nPos = 0;
  886.     size_t      nRead = 0;
  887.  
  888.     nPos = ftell (ifp);
  889.  
  890.     if (nBytes != (nRead = fread (pBuffer, 1, nBytes, ifp)))
  891.     {
  892.         doWarning (FATAL, __LINE__, ftm, "Failed to read %d bytes at offset %d.", (int)nBytes, (int)nPos);
  893.         return -1;
  894.     }
  895.  
  896.     return nRead;
  897. }
  898.  
  899. // Returns '1' if block is read ok, '0' on normal EOF, '-1' on error.
  900. static int      blockRead (FTM_FILE *ftm)
  901. {
  902. //   16-byte "Block Id" (string) -OR- 3 byte "END"
  903. //    4-byte "Block version" (int, 1-3)
  904. //    4-byte "Block size" (int)
  905. //   NN-byte "Block data" (size = "Block Size")
  906.  
  907.     size_t      nRead = 0;
  908.  
  909.     memset (blockdata, 0, sizeof(blockdata));
  910.     block.ptr = block.data = blockdata;
  911.  
  912.     block.file_pos = ftell (ifp);
  913.  
  914.     if (BLOCK_ID_SIZE != (nRead = fread (block.id, 1, BLOCK_ID_SIZE, ifp)))
  915.     {
  916.         if ((nRead == 3) && !strncmp (block.id, "END", 3))
  917.         {
  918.             return 0;       // Normal EOF detected.
  919.         }
  920.  
  921.         doWarning (FATAL, __LINE__, ftm, "Failed to read %d bytes at offset %d.", BLOCK_ID_SIZE, (int)block.file_pos);
  922.         return -1;          // Error.
  923.     }
  924.  
  925. // Terminate string (makes printing block name easier).
  926.     block.id[BLOCK_ID_SIZE] = 0;
  927.  
  928.     if (-1 == ftm_read (ftm, &block.ver, 4))
  929.     {
  930.         return -1;
  931.     }
  932.  
  933.     if (-1 == ftm_read (ftm, &block.len, 4))
  934.     {
  935.         return -1;
  936.     }
  937.  
  938.     if (-1 == ftm_read (ftm, blockdata, block.len))
  939.     {
  940.         return -1;
  941.     }
  942.  
  943.     if (verbose)
  944.     {
  945.         fprintf (stderr, "BLOCK: '%s', ver %d, len %d.\n", block.id, block.ver, block.len);
  946.     }
  947.  
  948.     return 1;
  949. }
  950.  
  951.  
  952. // Returns '0' on success, '-1' on fatal error.
  953. static int      verifyHeader (FTM_FILE *ftm)
  954. {
  955.     char        hdr[18];
  956.     int     ver = 0;
  957.  
  958. // File begins with a NON-terminated 18-character string.
  959.     if (-1 == ftm_read (ftm, hdr, 18))
  960.     {
  961.         return -1;
  962.     }
  963.  
  964.     if (strncmp (hdr, FILE_HEADER, strlen (FILE_HEADER)))
  965.     {
  966.         doWarning (FATAL, __LINE__, ftm, "Invalid file header.");
  967.         return -1;
  968.     }
  969.  
  970. // Followed by a 4-byte version number.
  971.     if (-1 == ftm_read (ftm, &ver, 4))
  972.     {
  973.         return -1;
  974.     }
  975.  
  976.     if (ver != FILE_VERSION)
  977.     {
  978.         doWarning (FATAL, __LINE__, ftm, "File version %d, expected %d.", ver, FILE_VERSION);
  979.         return -1;
  980.     }
  981.  
  982.     ftm->file_version = ver;
  983.  
  984.     return 0;
  985. }
  986.  
  987. static BLOCK_FUNC block_func[] =
  988. {
  989.     { "PARAMS", read_params },
  990.     { "INFO", read_info },
  991.     { "HEADER", read_header },
  992.     { "INSTRUMENTS", read_instruments },
  993.     { "SEQUENCES", read_sequences },
  994.     { "FRAMES", read_frames },
  995.     { "PATTERNS", read_patterns },
  996.     { "DPCM SAMPLES", read_dpcm_samples },
  997.     { NULL, NULL }
  998. };
  999.  
  1000. static int      import (FTM_FILE *ftm)
  1001. {
  1002.     int     nResult = 0;
  1003.     BLOCK_FUNC  *pHandler = NULL;
  1004.  
  1005.     if (-1 == verifyHeader (ftm))
  1006.     {
  1007.         return -1;
  1008.     }
  1009.  
  1010.     while (0 < (nResult = blockRead (ftm)))
  1011.     {
  1012.         for (pHandler = block_func; pHandler->id; ++pHandler)
  1013.         {
  1014.             if (!strcmp (pHandler->id, block.id))
  1015.             {
  1016.                 if (-1 == pHandler->func (ftm))
  1017.                 {
  1018.                     return -1;
  1019.                 }
  1020.  
  1021.                 if (block.ptr > (block.data + block.len))
  1022.                 {
  1023.                     doWarning (FATAL, __LINE__, ftm, "Read past end of block '%s'.", block.id);
  1024.                     return -1;
  1025.                 }
  1026.                 break;
  1027.             }
  1028.         }
  1029.  
  1030.         if (!pHandler->id)
  1031.         {
  1032.             doWarning (NON_FATAL, __LINE__, ftm, "No handler for block type '%s'.", block.id);
  1033.         }
  1034.     }
  1035.  
  1036.     return nResult;
  1037. }
  1038.  
  1039. static int  export_famitone_nesasm (const FTM_FILE *ftm)
  1040. {
  1041.     int i;
  1042.     int env;
  1043.     int out_size = 0;   // Count of bytes emitted.
  1044.  
  1045.     const SEQUENCE  *seq = NULL;
  1046.  
  1047.     fprintf (ofp, "\n%smodule\n", symbol_prefix);
  1048.  
  1049.     fprintf (ofp, "\t.dw ");
  1050.     for (i = 0; i < ftm->params.channels_avail; i++)
  1051.     {
  1052.         fprintf (ofp, ".chn%d,", i);
  1053.         out_size += 2;
  1054.     }
  1055.     fprintf (ofp, ".ins\n");
  1056.     out_size += 2;
  1057.  
  1058.     fprintf (ofp, "\t.db $%02x\n", ftm->params.engine_speed);
  1059.     out_size++;
  1060.  
  1061.     fprintf (ofp,".env_default\n\t.db $c0,$7f,$00\n");
  1062.     out_size += 3;
  1063.  
  1064.     for (env = 0; env < MAX_SEQUENCES; env++)
  1065.     {
  1066.         if (NULL == (seq = ftm->sequences[env]))
  1067.         {
  1068.             continue;
  1069.         }
  1070.  
  1071.         if (!seq->nUsed)
  1072.         {
  1073.             continue;
  1074.         }
  1075.  
  1076.         fprintf (ofp, ".env_%s%d\n", szSequenceNames[seq->nType], seq->nIndex);
  1077.     }
  1078.  
  1079.     fprintf (ofp, "#ERROR - Unfinished export routine.\n\n");
  1080.  
  1081.     return 0;
  1082. }
  1083.  
  1084. static void emit_byte_stream (const byte *pBuffer, int nCount)
  1085. {
  1086.     int i;
  1087.  
  1088.     for (i = 0; i < nCount; i++)
  1089.     {
  1090.         if (!(i % 8))
  1091.         {
  1092.             fprintf (ofp, "\n\t.byte\t");
  1093.         }
  1094.         else if (i)
  1095.         {
  1096.             fprintf (ofp, ", ");
  1097.         }
  1098.  
  1099.         fprintf (ofp, "$%02x", *pBuffer);
  1100.         pBuffer++;
  1101.         bytes_out++;
  1102.     }
  1103.  
  1104.     fprintf (ofp, "\n");
  1105. }
  1106.  
  1107.  
  1108. // Same format as Famitone:
  1109. // <127 is a number of repeats of previous output value
  1110. // 127 is end of an envelope, next byte is new offset in envelope
  1111. // 128..255 is output value + 192 (it is in -64..63 range)
  1112. // Envelopes can't be longer than 255 bytes
  1113.  
  1114. static void emit_sequence_ca65 (const SEQUENCE *seq)
  1115. {
  1116.     int     i;
  1117.     int     samples = seq->nSampleCount;
  1118.     byte        loop_point = seq->nLoopPoint;
  1119.     byte        buffer[MAX_SEQUENCE_ITEMS + 2];
  1120.     byte        *p = NULL;
  1121.  
  1122.     if (seq->nType == SEQ_DUTYCYCLE)
  1123.     {
  1124.         samples = 1;
  1125.     }
  1126.     else if (samples > MAX_SEQUENCE_ITEMS)
  1127.     {
  1128.         samples = MAX_SEQUENCE_ITEMS;
  1129.     }
  1130.  
  1131. // If no loop-point is set, repeat last note forever?
  1132.     if (seq->nLoopPoint < 0)
  1133.     {
  1134.         loop_point = seq->nSampleCount - 1;
  1135.     }
  1136.  
  1137.     for (i = 0, p = buffer; i < samples; i++, p++)
  1138.     {
  1139.         *p = seq->vSamples[i] + 0xc0;
  1140.     }
  1141.  
  1142.     *(p++) = 0x7f;          // Terminate envelope token.
  1143.     *(p++) = loop_point;
  1144.  
  1145.     fprintf (ofp, "\n%senv_%s%d:", symbol_prefix, szSequenceNames[seq->nType], seq->nIndex);
  1146.  
  1147.     emit_byte_stream (buffer, p - buffer);
  1148. }
  1149.  
  1150. static const byte env_default[3] = { 0xc0, 0x7f, 0x00 };
  1151.  
  1152. static void emit_sequences_ca65 (const FTM_FILE *ftm)
  1153. {
  1154.     int     seq_type = 0;
  1155.     int     seq_idx = 0;
  1156.  
  1157.     fprintf (ofp, "\n%senv_default:", symbol_prefix);
  1158.     emit_byte_stream (env_default, sizeof(env_default));
  1159.  
  1160.     for (seq_type = 0; seq_type < SEQ_COUNT; seq_type++)
  1161.     {
  1162.         for (seq_idx = 0; seq_idx < MAX_SEQUENCES; seq_idx++)
  1163.         {
  1164.             const SEQUENCE *seq = &(ftm->sequences[seq_type][seq_idx]);
  1165.  
  1166.             if (!seq->nUsed) continue;
  1167.  
  1168.             if (!seq->nSampleCount) continue;
  1169.  
  1170.             if ((seq->nType == SEQ_PITCH) || (seq->nType == SEQ_HIPITCH))
  1171.             {
  1172.                 doWarning (NON_FATAL, __LINE__, ftm, "Sequence ignored: %d, %s.", seq->nIndex, szSequenceNames[seq->nType]);
  1173.                 continue;
  1174.             }
  1175.  
  1176.             if ((seq->nType == SEQ_DUTYCYCLE) && (seq->nSampleCount > 1))
  1177.             {
  1178.                 doWarning (NON_FATAL, __LINE__, ftm, "Duty-Cycle sequence length error: (seq %d, len %d).", seq->nIndex, seq->nSampleCount);
  1179.                 // Emit anyway, for debugging.
  1180.             }
  1181.  
  1182.             if ((seq->nType == SEQ_DUTYCYCLE) && (seq->nSampleCount <= 1))
  1183.             {
  1184.                 continue;
  1185.             }
  1186.  
  1187.             emit_sequence_ca65 (seq);
  1188.         }
  1189.     }
  1190.  
  1191.     fprintf (ofp, "\n");
  1192. }
  1193.  
  1194.  
  1195. static void emit_instru_half_ptr (const FTM_FILE *ftm, eSequences seq_type, int _msb)
  1196. {
  1197.     const INSTRUMENT *ins = NULL;
  1198.     const char *oper = _msb ? ">" : "<";
  1199.  
  1200.     fprintf (ofp, "\n%sinstruments_%s_%s:\n", symbol_prefix, szSequenceNames[seq_type], _msb ? "msb" : "lsb");
  1201.  
  1202.     for (ins = ftm->instruments; ins < ftm->instruments + MAX_INSTRUMENTS; ins++)
  1203.     {
  1204.         if (!ins->nUsed) continue;
  1205.  
  1206.         fprintf (ofp, "\t.byte\t");
  1207.  
  1208.         if (ins->vSequences[seq_type].nEnabled)
  1209.         {
  1210.             fprintf (ofp, "%s%senv_%s%d", oper, symbol_prefix, szSequenceNames[seq_type], ins->vSequences[seq_type].nIndex);
  1211.         }
  1212.         else
  1213.         {
  1214.             fprintf (ofp, "%s%senv_default", oper, symbol_prefix);
  1215.         }
  1216.  
  1217.         bytes_out++;
  1218.         fprintf (ofp, "\t;; %02x, %s\n", ins->nIndex, ins->pszName);
  1219.     }
  1220. }
  1221.  
  1222. static void emit_instru_dutycycle (const FTM_FILE *ftm)
  1223. {
  1224.     const INSTRUMENT *ins;
  1225.     byte duty;
  1226.  
  1227.     fprintf (ofp, "\n%sinstruments_dutycycle:\n", symbol_prefix);
  1228.  
  1229.     for (ins = ftm->instruments; ins < ftm->instruments + MAX_INSTRUMENTS; ins++)
  1230.     {
  1231.         if (!ins->nUsed) continue;
  1232.  
  1233.         duty = 0;
  1234.  
  1235.         if (ins->vSequences[SEQ_DUTYCYCLE].nEnabled)
  1236.         {
  1237.             const SEQUENCE *seq = ftm->sequences[SEQ_DUTYCYCLE] + ins->vSequences[SEQ_DUTYCYCLE].nIndex;
  1238.  
  1239.             if (seq && seq->nSampleCount)
  1240.             {
  1241.                 duty = seq->vSamples[0];
  1242.             }
  1243.         }
  1244.  
  1245.         fprintf (ofp, "\t.byte\t$%02x\t\t;; (%5.2f%%) %02x, %s\n", duty, fDutyCycles[duty], ins->nIndex, ins->pszName);
  1246.         bytes_out++;
  1247.     }
  1248. }
  1249.  
  1250. static void emit_instruments_ca65 (const FTM_FILE *ftm)
  1251. {
  1252.     emit_instru_half_ptr (ftm, SEQ_VOLUME, 0);
  1253.     emit_instru_half_ptr (ftm, SEQ_VOLUME, 1);
  1254.     emit_instru_half_ptr (ftm, SEQ_ARPEGGIO, 0);
  1255.     emit_instru_half_ptr (ftm, SEQ_ARPEGGIO, 1);
  1256.     emit_instru_dutycycle (ftm);
  1257.  
  1258.     fprintf (ofp, "\n");
  1259. }
  1260.  
  1261. /* Famitone channel stream format:
  1262. %00nnnnnn is a note (0..59 are octaves 1-5, 63 note stop)
  1263. %01iiiiii is an instrument number (0 is default, silence)
  1264. %10rrrrrr is a empty rows (up to 63)
  1265. %11eeeeee is a special tag or effect
  1266.    eeeeee $01..19 speed
  1267. %11111110 is end of the stream, two next bytes are new pointer
  1268. %11111111 is a reference (next two bytes of absolute address, and number of rows)
  1269. No octaves on Noise channel, it is always 0..15;
  1270. */
  1271.  
  1272. /* My stream format:
  1273. $00 - $6f  112 (0 to 111) = Note (C-0 to B-8, 9 octaves, 12 notes each)
  1274. $70 - $7f  16  (112 to 127) = RLE empty row (count = n - $6f)
  1275. $80 - $bf  64  (128 to 191) = Select instrument
  1276. $c0 - $fd  62  (192 to 253) = Reserved
  1277. $fe        1   (254) = End of stream.  Next two bytes are ptr to new stream.
  1278. $ff        1   (255) = Jmp to new ptr (next two bytes are ptr).
  1279. */
  1280.  
  1281. static void emit_stream_byte (int row, byte value, const char *c1, const char *c2)
  1282. {
  1283.     fprintf (ofp, "\t.byte\t$%02x\t\t; [%02x]\t%-14.14s\t%s\n", value, row, c1, c2);
  1284.     bytes_out++;
  1285. }
  1286.  
  1287. static void emit_rle_silence_ca65 (int row, byte count)
  1288. {
  1289.     char        c2[16] = "";
  1290.     byte        value = 0;
  1291.     byte        rle = 0;
  1292.  
  1293.     while (count > 0)
  1294.     {
  1295.         value = (count > 16) ? 16 : count;
  1296.         rle = (value - 1) + 112;
  1297.  
  1298.         snprintf (c2, sizeof(c2), "%d rows", value);
  1299.         emit_stream_byte (row, rle, "empty row", c2);
  1300.         count -= value;
  1301.     }
  1302. }
  1303.  
  1304. static void emit_note_ca65 (int row, const NOTE *pNote)
  1305. {
  1306.     char        c2[16] = "";
  1307.     byte        note = ((pNote->note - 1) + pNote->octave * 12);
  1308.  
  1309.     noteName (c2, sizeof(c2), pNote);
  1310.     emit_stream_byte (row, note, "note", c2);
  1311. }
  1312.  
  1313. static void emit_set_instrument_ca65 (const FTM_FILE *ftm, int row, byte instrument)
  1314. {
  1315.     emit_stream_byte (row, (byte)(instrument + 128), "instrument", ftm->instruments[instrument].pszName);
  1316. }
  1317.  
  1318. static void emit_channel_ca65 (const FTM_FILE *ftm, const PATTERN *pat)
  1319. {
  1320.     const NOTE  *pNote = pat->notes;
  1321.     const NOTE  *pEnd = pat->notes + MAX_PATTERN_LENGTH;
  1322.     int     nNotes = pat->nNotes;
  1323.     char        chan_name[128];
  1324.     byte        prev_instru = (byte)-1;
  1325.     byte        silence = 0;
  1326.     int     effidx = 0;
  1327.  
  1328.     snprintf (chan_name, sizeof(chan_name), "%schan_%d_%d_%d", symbol_prefix, pat->nTune, pat->nChannel, pat->nIndex);
  1329.  
  1330.     fprintf (ofp, "\n%s:\t\t\t; '%s', '%s', %d\n", chan_name, ftm->tunes[pat->nTune]->pszName,
  1331.         szChannelNames[pat->nChannel], pat->nIndex);
  1332.     fprintf (ofp, "%s_loop:\n", chan_name);
  1333.  
  1334.     for (pNote = pat->notes; nNotes && (pNote < pEnd); pNote++)
  1335.     {
  1336.         for (effidx = 0; effidx < MAX_EFFECT_COLUMNS; effidx++)
  1337.         {
  1338.             if (pNote->effects[effidx].number == EF_HALT)
  1339.             {
  1340.                 goto channel_done;
  1341.             }
  1342.         }
  1343.  
  1344.         if (!pNote->note)
  1345.         {
  1346.             silence++;
  1347.             continue;
  1348.         }
  1349.  
  1350.         if (silence)
  1351.         {
  1352.             emit_rle_silence_ca65 ((pNote - pat->notes) - silence, silence);
  1353.             silence = 0;
  1354.         }
  1355.  
  1356.         if (pNote->instrument == MAX_INSTRUMENTS)       // "Note cut"
  1357.         {
  1358.             // Not a real instrument.  Don't change active instrument.
  1359.             emit_note_ca65 (pNote - pat->notes, pNote);
  1360.             nNotes--;
  1361.             continue;
  1362.         }
  1363.  
  1364.         if (pNote->instrument >= MAX_INSTRUMENTS)
  1365.         {
  1366.             fprintf (ofp, ";; ERROR: pNote->instrument = %d, skipping note.\n", pNote->instrument);
  1367.             continue;
  1368.         }
  1369.  
  1370.         if (pNote->instrument != prev_instru)
  1371.         {
  1372.             if (ftm->instruments[pNote->instrument].nUsed)
  1373.             {
  1374.                 emit_set_instrument_ca65 (ftm, pNote - pat->notes, pNote->instrument);
  1375.             }
  1376.             else
  1377.             {
  1378.                 doWarning (FATAL, __LINE__, ftm, "Channel '%s' references non-existant instrument '%d'.",
  1379.                     chan_name, pNote->instrument);
  1380.             }
  1381.  
  1382.             prev_instru = pNote->instrument;
  1383.         }
  1384.  
  1385.         emit_note_ca65 (pNote - pat->notes, pNote);
  1386.         nNotes--;
  1387.     }
  1388.  
  1389. channel_done:
  1390.     if (silence)
  1391.     {
  1392.         emit_rle_silence_ca65 ((pNote - pat->notes) - silence, silence);
  1393.         silence = 0;
  1394.     }
  1395.  
  1396.     fprintf (ofp, "\t.byte\t$%02x\t\t; End stream code.\n", 0xfe);
  1397.     fprintf (ofp, "\t.word\t%s_loop\n", chan_name);
  1398.     bytes_out += 3;
  1399. }
  1400.  
  1401. static void emit_channels_ca65 (const FTM_FILE *ftm)
  1402. {
  1403.     const PATTERN   *pat;
  1404.     int     tune;
  1405.     int     chan;
  1406.     int     npat;
  1407.  
  1408.     for (tune = 0; tune < ftm->header.nTuneCount; tune++)
  1409.     {
  1410.         for (chan = 0; chan < ftm->params.channels_avail; chan++)
  1411.         {
  1412.             for (npat = 0; npat < MAX_PATTERNS; npat++)
  1413.             {
  1414.                 if (NULL == (pat = ftm->patterns[tune][chan][npat]))
  1415.                 {
  1416.                     continue;
  1417.                 }
  1418.  
  1419.                 if (!ftm->tunes[pat->nTune])
  1420.                 {
  1421.                     doWarning (NON_FATAL, __LINE__, ftm, "pattern(%d,%d,%d) referse to a tune that does not exist (%d).",
  1422.                         tune, chan, npat, tune);
  1423.                     continue;
  1424.                 }
  1425.  
  1426.                 emit_channel_ca65 (ftm, pat);
  1427.             }
  1428.         }
  1429.     }
  1430. }
  1431.  
  1432. static const double CLOCK_NTSC = 21477277 / 12;
  1433. static const double CLOCK_PAL = 26601712 / 16;
  1434.  
  1435. // http://nesdev.parodius.com/bbs/viewtopic.php?p=22795#22795
  1436. static void emit_freq_table (const FTM_FILE *ftm)
  1437. {
  1438.     const double    clock = (ftm->params.machine == NTSC) ? CLOCK_NTSC : CLOCK_PAL;
  1439.     const double    base_freq = 32.70;
  1440.     int     period_table[NOTE_MAX_RANGE];
  1441.     byte        hi_table[NOTE_MAX_RANGE];
  1442.     byte        lo_table[NOTE_MAX_RANGE];
  1443.     int     i;
  1444.     char        nn[32];
  1445.  
  1446.     for (i = 0; i < NOTE_MAX_RANGE; i++)
  1447.     {
  1448.         // Subtract ONE from each period (makes output match Shiru's table in Famitone).
  1449.         period_table[i] = (int)((clock / 16.0) / (base_freq * pow (2, (double)i / 12.0)) - 1);
  1450.         hi_table[i] = period_table[i] >> 8;
  1451.         lo_table[i] = period_table[i] & 0xff;
  1452.     }
  1453.  
  1454.     if (verbose)
  1455.     {
  1456.         fprintf (ofp, "\n;; APU period register table (11 bits)\n\n");
  1457.  
  1458.         for (i = 0; i < NOTE_MAX_RANGE; i++)
  1459.         {
  1460.             NOTE    note = {0};
  1461.  
  1462.             note.note = (eNotes)(i % 12) + 1;
  1463.             note.octave = i / 12;
  1464.             noteName (nn, sizeof(nn), &note);
  1465.             fprintf (ofp, ";\t%3d:\t%s\t%d\t$%04x\n", i, nn, period_table[i], period_table[i]);
  1466.         }
  1467.     }
  1468.  
  1469.     fprintf (ofp, "\n.align\t\t%d\n", 256);
  1470.     fprintf (ofp, ".export\t\tapu_period_table_lo\n");
  1471.     fprintf (ofp, "apu_period_table_lo:");
  1472.     emit_byte_stream (lo_table, NOTE_MAX_RANGE);
  1473.  
  1474.     fprintf (ofp, "\n.export\t\tapu_period_table_hi\n");
  1475.     fprintf (ofp, "apu_period_table_hi:");
  1476.     emit_byte_stream (hi_table, NOTE_MAX_RANGE);
  1477. }
  1478.  
  1479. static int  export_ecoligames_ca65 (const FTM_FILE *ftm)
  1480. {
  1481.     time_t      now = time(NULL);
  1482.     struct tm   *tm = localtime(&now);
  1483.     char        temp[256];
  1484.  
  1485.     strftime (temp, sizeof(temp), "%Y-%m-%d %H:%M:%S", tm);
  1486.  
  1487.     fprintf (ofp, ";; Source:    \t%s\n", ifname);
  1488.     fprintf (ofp, ";; Converted: \t%s\n\n", temp);
  1489.     fprintf (ofp, ";; Title:     \t%s\n", ftm->info.song_name);
  1490.     fprintf (ofp, ";; Artist:    \t%s\n", ftm->info.artist);
  1491.     fprintf (ofp, ";; Copyright: \t%s\n\n", ftm->info.copyright);
  1492.  
  1493.     if (segname && strlen(segname))
  1494.     {
  1495.         fprintf (ofp, ".segment\t\t\"%s\"\n\n", segname);
  1496.     }
  1497.  
  1498.     emit_sequences_ca65 (ftm);
  1499.     emit_instruments_ca65 (ftm);
  1500.     emit_channels_ca65 (ftm);
  1501.     emit_freq_table (ftm);
  1502.  
  1503.     fprintf (ofp, "\n\n;; Size: %d bytes\n",  bytes_out);
  1504.  
  1505.     return 0;
  1506. }
  1507.  
  1508. int main (int argc, char *argv[])
  1509. {
  1510.     int     i = 0;
  1511.     int     ret_code = 0;
  1512.     FTM_FILE    ftm = {0};
  1513.  
  1514.     strcpy (symbol_prefix, "snd_");
  1515.     ofp = stdout;
  1516.     bytes_out = 0;
  1517.  
  1518.     for (i = 1; i < argc; i++)
  1519.     {
  1520.         if (!strcmp (argv[i], "-v"))
  1521.         {
  1522.             verbose++;
  1523.         }
  1524.         else if (!strcmp (argv[i], "-p"))
  1525.         {
  1526.             snprintf (symbol_prefix, sizeof(symbol_prefix), "%s_", argv[++i]);
  1527.         }
  1528.         else if (!strcmp (argv[i], "-s"))
  1529.         {
  1530.             segname = argv[++i];
  1531.         }
  1532.         else if (!strcmp (argv[i], "-w"))
  1533.         {
  1534.             warnings_are_fatal = 1;
  1535.         }
  1536.         else if (!strcmp (argv[i], "-famitone"))
  1537.         {
  1538.             target = TARGET_FAMITONE;
  1539.         }
  1540.         else if (!strcmp (argv[i], "-nesasm"))
  1541.         {
  1542.             syntax = SYNTAX_NESASM;
  1543.         }
  1544.         else if (!strcmp (argv[i], "-ca65"))
  1545.         {
  1546.             syntax = SYNTAX_CA65;
  1547.         }
  1548.         else if (argv[i][0] == '-')
  1549.         {
  1550.             fprintf (stderr, "ERROR: Unrecognized option: '%s'\n", argv[i]);
  1551.         }
  1552.         else
  1553.         {
  1554.             ifname = argv[i];
  1555.             if (NULL == (ifp = fopen (argv[i], "rb")))
  1556.             {
  1557.                 fprintf (stderr, "ERROR: Failed to open '%s' for reading.\n", argv[i]);
  1558.                 perror ("fopen");
  1559.                 exit (-1);
  1560.             }
  1561.         }
  1562.     }
  1563.  
  1564.     if (ifp)
  1565.     {
  1566.         if (-1 == import (&ftm))
  1567.         {
  1568.             exit (-1);
  1569.         }
  1570.  
  1571.         if (ifp != stdin) fclose (ifp);
  1572.         ifp = NULL;
  1573.     }
  1574.  
  1575.     if (target == TARGET_FAMITONE)
  1576.     {
  1577.         if (syntax == SYNTAX_NESASM)
  1578.         {
  1579.             ret_code = export_famitone_nesasm (&ftm);
  1580.         }
  1581.     }
  1582.     else if (target == TARGET_ECOLIGAMES)
  1583.     {
  1584.         if (syntax == SYNTAX_CA65)
  1585.         {
  1586.             ret_code = export_ecoligames_ca65 (&ftm);
  1587.         }
  1588.     }
  1589.  
  1590.     if (warnings)
  1591.     {
  1592.         fprintf (stderr, "There were %d warnings.\n", warnings);
  1593.     }
  1594.  
  1595.     return ret_code;
  1596. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement