home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 January / macformat-020.iso / Shareware City / Developers / Synthesizer Source / Synthesizer Folder / MainWindowStuff.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-01  |  82.9 KB  |  2,876 lines  |  [TEXT/KAHL]

  1. /* MainWindowStuff.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Synthesizer:  Digital Music Synthesis on General Purpose Computers     */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "MainWindowStuff.h"
  31. #include "Memory.h"
  32. #include "Files.h"
  33. #include "WindowDispatcher.h"
  34. #include "Array.h"
  35. #include "CodeCenter.h"
  36. #include "TextEdit.h"
  37. #include "SampleList.h"
  38. #include "FunctionList.h"
  39. #include "AlgoSampList.h"
  40. #include "WaveTableList.h"
  41. #include "AlgoWaveTableList.h"
  42. #include "InstrList.h"
  43. #include "TrackList.h"
  44. #include "Alert.h"
  45. #include "StartupOpen.h"
  46. #include "CalculatorWindow.h"
  47. #include "GrowIcon.h"
  48. #include "Main.h"
  49. #include "DisassemblyWindow.h"
  50. #include "PcodeSystem.h"
  51. #include "DataMunging.h"
  52. #include "NumberDialog.h"
  53. #include "Numbers.h"
  54. #include "GlobalWindowMenuList.h"
  55. #include "BinaryCodedDecimal.h"
  56. #include "PlayPrefsDialog.h"
  57. #include "ImportWAVSample.h"
  58. #include "ImportRAWSample.h"
  59. #include "ImportAIFFSample.h"
  60. #include "BufferedFileInput.h"
  61. #include "BufferedFileOutput.h"
  62.  
  63.  
  64. #define MINTABCOUNT (1)
  65. #define MAXTABCOUNT (255)
  66. #define DEFAULTTABSIZE (2)
  67.  
  68.  
  69. #define MAINWINSIZEX (450)
  70. #define MAINWINSIZEY (250)
  71.  
  72. /* top-left corner */
  73. #define TRACKX(W,H) (-1)
  74. #define TRACKY(W,H) (-1)
  75. #define TRACKWIDTH(W,H) ((W) / 3)
  76. #define TRACKHEIGHT(W,H) ((H) / 3)
  77.  
  78. /* top-middle */
  79. #define WAVETABLEX(W,H) (TRACKX(W,H) + TRACKWIDTH(W,H) + 1)
  80. #define WAVETABLEY(W,H) (TRACKY(W,H))
  81. #define WAVETABLEWIDTH(W,H) (((W) - WAVETABLEX(W,H)) / 2)
  82. #define WAVETABLEHEIGHT(W,H) (TRACKHEIGHT(W,H))
  83.  
  84. /* top-right corner */
  85. #define SAMPLEX(W,H) (WAVETABLEX(W,H) + WAVETABLEWIDTH(W,H) + 1)
  86. #define SAMPLEY(W,H) (WAVETABLEY(W,H))
  87. #define SAMPLEWIDTH(W,H) ((W) - SAMPLEX(W,H) + 1)
  88. #define SAMPLEHEIGHT(W,H) (WAVETABLEHEIGHT(W,H))
  89.  
  90. /* middle-left */
  91. #define INSTRUMENTX(W,H) (TRACKX(W,H))
  92. #define INSTRUMENTY(W,H) (TRACKY(W,H) + TRACKHEIGHT(W,H))
  93. #define INSTRUMENTWIDTH(W,H) (TRACKWIDTH(W,H))
  94. #define INSTRUMENTHEIGHT(W,H) (((H) - INSTRUMENTY(W,H)) / 2)
  95.  
  96. /* middle-middle */
  97. #define ALGOWAVETABLEX(W,H) (WAVETABLEX(W,H))
  98. #define ALGOWAVETABLEY(W,H) (INSTRUMENTY(W,H))
  99. #define ALGOWAVETABLEWIDTH(W,H) (WAVETABLEWIDTH(W,H))
  100. #define ALGOWAVETABLEHEIGHT(W,H) (INSTRUMENTHEIGHT(W,H))
  101.  
  102. /* middle-right */
  103. #define ALGOSAMPLEX(W,H) (SAMPLEX(W,H))
  104. #define ALGOSAMPLEY(W,H) (ALGOWAVETABLEY(W,H))
  105. #define ALGOSAMPLEWIDTH(W,H) (SAMPLEWIDTH(W,H))
  106. #define ALGOSAMPLEHEIGHT(W,H) (ALGOWAVETABLEHEIGHT(W,H))
  107.  
  108. /* bottom-left corner */
  109. #define FUNCTIONX(W,H) (INSTRUMENTX(W,H))
  110. #define FUNCTIONY(W,H) (INSTRUMENTY(W,H) + INSTRUMENTHEIGHT(W,H))
  111. #define FUNCTIONWIDTH(W,H) (INSTRUMENTWIDTH(W,H))
  112. #define FUNCTIONHEIGHT(W,H) ((H) - FUNCTIONY(W,H) + 1)
  113.  
  114. /* bottom-middle and bottom-right corner */
  115. #define COMMENTX(W,H) (FUNCTIONX(W,H) + FUNCTIONWIDTH(W,H) + 1)
  116. #define COMMENTY(W,H) (FUNCTIONY(W,H) + 1)
  117. #define COMMENTWIDTH(W,H) ((W) - COMMENTX(W,H) + 1)
  118. #define COMMENTHEIGHT(W,H) (FUNCTIONHEIGHT(W,H) - 1)
  119.  
  120.  
  121. /* this structure contains all the information for a document */
  122. struct MainWindowRec
  123.     {
  124.         WinType*                        ScreenID;
  125.         MyBoolean                        EverBeenSaved;
  126.         FileSpec*                        TheFileLocation; /* only valid if EverBeenSaved is true */
  127.         FileType*                        TheFile; /* only valid if EverBeenSaved is true */
  128.         GenericWindowRec*        MyGenericWindow; /* how the window event dispatcher knows us */
  129.         MenuItemType*                MyMenuItem;
  130.  
  131.         FileSpec*                        DeleteUndoFileLocation; /* NIL = none */
  132.         FileType*                        DeleteUndoFile; /* NIL = none */
  133.  
  134.         ArrayRec*                        ListOfCalcWindows;
  135.         ArrayRec*                        ListOfDisassemblies;
  136.         CodeCenterRec*            CodeCenter; /* keeps all the object code */
  137.  
  138.         /* generic control parameters */
  139.         long                                TabSize;
  140.         TextEditRec*                CommentInfo;
  141.  
  142.         /* score data */
  143.         SampleListRec*            SampleList;
  144.         FunctionListRec*        FunctionList;
  145.         AlgoSampListRec*        AlgoSampList;
  146.         WaveTableListRec*        WaveTableList;
  147.         AlgoWaveTableListRec*    AlgoWaveTableList;
  148.         InstrListRec*                InstrumentList;
  149.         TrackListRec*                TrackList;
  150.  
  151.         MyBoolean                        StuffModified;
  152.  
  153.         /* playback preferences */
  154.         MyBoolean                        StereoPlayback;
  155.         MyBoolean                        SurroundEncoding;
  156.         long                                SamplingRate;
  157.         long                                EnvelopeUpdateRate;
  158.         LargeBCDType                DefaultBeatsPerMinute;
  159.         LargeBCDType                OverallVolumeScalingFactor;
  160.         OutputNumBitsType        OutputNumBits;
  161.         MyBoolean                        InterpolateOverTime;
  162.         MyBoolean                        InterpolateAcrossWaves;
  163.         LargeBCDType                ScanningGap;
  164.         LargeBCDType                BufferDuration;
  165.         MyBoolean                        ClipWarning;
  166.         char*                                SongPostProcessing;
  167.         MyBoolean                        SongPostProcessingEnable;
  168.     };
  169.  
  170.  
  171. static ArrayRec*                ListOfDocuments = NIL;
  172.  
  173.  
  174. /* initialize internal data structures for documents */
  175. MyBoolean                        InitializeDocuments(void)
  176.     {
  177.         APRINT(("+InitializeDocuments"));
  178.         ListOfDocuments = NewArray();
  179.         if (ListOfDocuments == NIL)
  180.             {
  181.                 APRINT(("-InitializeDocuments failed"));
  182.                 return False;
  183.             }
  184.         APRINT(("-InitializeDocuments"));
  185.         return True;
  186.     }
  187.  
  188.  
  189. /* clean up any internal data structures used for documents */
  190. void                                ShutdownDocuments(void)
  191.     {
  192.         APRINT(("+ShutdownDocuments"));
  193.         ERROR(ArrayGetLength(ListOfDocuments) != 0,PRERR(AllowResume,
  194.             "ShutdownDocuments:  Not all documents disposed of"));
  195.         DisposeArray(ListOfDocuments);
  196.         APRINT(("-ShutdownDocuments"));
  197.     }
  198.  
  199.  
  200. /* open a new document window and load the document in.  the function takes */
  201. /* ownership of the file specification. */
  202. void                                OpenDocument(FileSpec* TheFile)
  203.     {
  204.         MainWindowRec*        Window;
  205.  
  206.         /* allocation */
  207.         Window = (MainWindowRec*)AllocPtrCanFail(sizeof(MainWindowRec),"MainWindowRec");
  208.         if (Window == NIL)
  209.             {
  210.              FailurePoint1:
  211.                 AlertHalt("There is not enough memory available to open the document.",NIL);
  212.                 if (TheFile != NIL)
  213.                     {
  214.                         DisposeFileSpec(TheFile);
  215.                     }
  216.                 return;
  217.             }
  218.         if (!ArrayAppendElement(ListOfDocuments,Window))
  219.             {
  220.              FailurePoint2:
  221.                 ReleasePtr((char*)Window);
  222.                 goto FailurePoint1;
  223.             }
  224.  
  225.         /* constructing members */
  226.  
  227.         Window->TabSize = DEFAULTTABSIZE;
  228.  
  229.         Window->CodeCenter = NewCodeCenter();
  230.         if (Window->CodeCenter == NIL)
  231.             {
  232.              FailurePoint3:
  233.                 ArrayDeleteElement(ListOfDocuments,ArrayFindElement(ListOfDocuments,Window));
  234.                 goto FailurePoint2;
  235.             }
  236.  
  237.         Window->ScreenID = MakeNewWindow(eDocumentWindow,eWindowClosable,
  238.             eWindowZoomable,eWindowResizable,4 + WindowOtherEdgeWidths(eDocumentWindow),
  239.             4 + WindowTitleBarHeight(eDocumentWindow),MAINWINSIZEX,MAINWINSIZEY,
  240.             (void (*)(void*))&MainWindowUpdator,Window);
  241.         if (Window->ScreenID == 0)
  242.             {
  243.              FailurePoint4:
  244.                 DisposeCodeCenter(Window->CodeCenter);
  245.                 goto FailurePoint3;
  246.             }
  247.  
  248.         Window->CommentInfo = NewTextEdit(Window->ScreenID,
  249.             eTEHScrollBar | eTEVScrollBar,GetScreenFont(),9,
  250.             COMMENTX(MAINWINSIZEX,MAINWINSIZEY),COMMENTY(MAINWINSIZEX,MAINWINSIZEY),
  251.             COMMENTWIDTH(MAINWINSIZEX,MAINWINSIZEY),COMMENTHEIGHT(MAINWINSIZEX,MAINWINSIZEY));
  252.         if (Window->CommentInfo == NIL)
  253.             {
  254.              FailurePoint5:
  255.                 KillWindow(Window->ScreenID);
  256.                 goto FailurePoint4;
  257.             }
  258.  
  259.         Window->SampleList = NewSampleList(Window,Window->CodeCenter,
  260.             Window->ScreenID,SAMPLEX(MAINWINSIZEX,MAINWINSIZEY),
  261.             SAMPLEY(MAINWINSIZEX,MAINWINSIZEY),SAMPLEWIDTH(MAINWINSIZEX,MAINWINSIZEY),
  262.             SAMPLEHEIGHT(MAINWINSIZEX,MAINWINSIZEY));
  263.         if (Window->SampleList == NIL)
  264.             {
  265.              FailurePoint6:
  266.                 DisposeTextEdit(Window->CommentInfo);
  267.                 goto FailurePoint5;
  268.             }
  269.  
  270.         Window->FunctionList = NewFunctionList(Window,Window->CodeCenter,
  271.             Window->ScreenID,FUNCTIONX(MAINWINSIZEX,MAINWINSIZEY),
  272.             FUNCTIONY(MAINWINSIZEX,MAINWINSIZEY),FUNCTIONWIDTH(MAINWINSIZEX,MAINWINSIZEY),
  273.             FUNCTIONHEIGHT(MAINWINSIZEX,MAINWINSIZEY));
  274.         if (Window->FunctionList == NIL)
  275.             {
  276.              FailurePoint7:
  277.                 DisposeSampleList(Window->SampleList);
  278.                 goto FailurePoint6;
  279.             }
  280.  
  281.         Window->AlgoSampList = NewAlgoSampList(Window,Window->CodeCenter,
  282.             Window->ScreenID,ALGOSAMPLEX(MAINWINSIZEX,MAINWINSIZEY),
  283.             ALGOSAMPLEY(MAINWINSIZEX,MAINWINSIZEY),
  284.             ALGOSAMPLEWIDTH(MAINWINSIZEX,MAINWINSIZEY),
  285.             ALGOSAMPLEHEIGHT(MAINWINSIZEX,MAINWINSIZEY));
  286.         if (Window->AlgoSampList == NIL)
  287.             {
  288.              FailurePoint8:
  289.                 DisposeFunctionList(Window->FunctionList);
  290.                 goto FailurePoint7;
  291.             }
  292.  
  293.         Window->WaveTableList = NewWaveTableList(Window,Window->CodeCenter,
  294.             Window->ScreenID,WAVETABLEX(MAINWINSIZEX,MAINWINSIZEY),
  295.             WAVETABLEY(MAINWINSIZEX,MAINWINSIZEY),WAVETABLEWIDTH(MAINWINSIZEX,MAINWINSIZEY),
  296.             WAVETABLEHEIGHT(MAINWINSIZEX,MAINWINSIZEY));
  297.         if (Window->WaveTableList == NIL)
  298.             {
  299.              FailurePoint9:
  300.                 DisposeAlgoSampList(Window->AlgoSampList);
  301.                 goto FailurePoint8;
  302.             }
  303.  
  304.         Window->AlgoWaveTableList = NewAlgoWaveTableList(Window,Window->CodeCenter,
  305.             Window->ScreenID,ALGOWAVETABLEX(MAINWINSIZEX,MAINWINSIZEY),
  306.             ALGOWAVETABLEY(MAINWINSIZEX,MAINWINSIZEY),
  307.             ALGOWAVETABLEWIDTH(MAINWINSIZEX,MAINWINSIZEY),
  308.             ALGOWAVETABLEHEIGHT(MAINWINSIZEX,MAINWINSIZEY));
  309.         if (Window->AlgoWaveTableList == NIL)
  310.             {
  311.              FailurePoint10:
  312.                 DisposeWaveTableList(Window->WaveTableList);
  313.                 goto FailurePoint9;
  314.             }
  315.  
  316.         Window->InstrumentList = NewInstrList(Window,Window->CodeCenter,
  317.             Window->ScreenID,INSTRUMENTX(MAINWINSIZEX,MAINWINSIZEY),
  318.             INSTRUMENTY(MAINWINSIZEX,MAINWINSIZEY),INSTRUMENTWIDTH(MAINWINSIZEX,MAINWINSIZEY),
  319.             INSTRUMENTHEIGHT(MAINWINSIZEX,MAINWINSIZEY));
  320.         if (Window->InstrumentList == NIL)
  321.             {
  322.              FailurePoint11:
  323.                 DisposeAlgoWaveTableList(Window->AlgoWaveTableList);
  324.                 goto FailurePoint10;
  325.             }
  326.  
  327.         Window->TrackList = NewTrackList(Window,Window->CodeCenter,
  328.             Window->ScreenID,TRACKX(MAINWINSIZEX,MAINWINSIZEY),TRACKY(MAINWINSIZEX,MAINWINSIZEY),
  329.             TRACKWIDTH(MAINWINSIZEX,MAINWINSIZEY),TRACKHEIGHT(MAINWINSIZEX,MAINWINSIZEY));
  330.         if (Window->TrackList == NIL)
  331.             {
  332.              FailurePoint12:
  333.                 DisposeInstrList(Window->InstrumentList);
  334.                 goto FailurePoint11;
  335.             }
  336.  
  337.         Window->ListOfCalcWindows = NewArray();
  338.         if (Window->ListOfCalcWindows == NIL)
  339.             {
  340.              FailurePoint13:
  341.                 DisposeTrackList(Window->TrackList);
  342.                 goto FailurePoint12;
  343.             }
  344.  
  345.         Window->ListOfDisassemblies = NewArray();
  346.         if (Window->ListOfDisassemblies == NIL)
  347.             {
  348.              FailurePoint14:
  349.                 DisposeArray(Window->ListOfCalcWindows);
  350.                 goto FailurePoint13;
  351.             }
  352.  
  353.         Window->MyGenericWindow = CheckInNewWindow(Window->ScreenID,Window,
  354.             (void (*)(void*,MyBoolean,OrdType,OrdType,ModifierFlags))&MainWindowDoIdle,
  355.             (void (*)(void*))&MainWindowBecomeActive,
  356.             (void (*)(void*))&MainWindowBecomeInactive,
  357.             (void (*)(void*))&MainWindowJustResized,
  358.             (void (*)(OrdType,OrdType,ModifierFlags,void*))&MainWindowDoMouseDown,
  359.             (void (*)(unsigned char,ModifierFlags,void*))&MainWindowDoKeyDown,
  360.             (void (*)(void*))&MainWindowClose,
  361.             (void (*)(void*))&MainWindowMenuSetup,
  362.             (void (*)(void*,MenuItemType*))&MainWindowDoMenuCommand);
  363.         if (Window->MyGenericWindow == NIL)
  364.             {
  365.              FailurePoint15:
  366.                 DisposeArray(Window->ListOfDisassemblies);
  367.                 goto FailurePoint14;
  368.             }
  369.  
  370.         Window->MyMenuItem = MakeNewMenuItem(mmWindowMenu,"x",0);
  371.         if (Window->MyMenuItem == NIL)
  372.             {
  373.              FailurePoint16:
  374.                 CheckOutDyingWindow(Window->MyGenericWindow);
  375.                 goto FailurePoint15;
  376.             }
  377.         if (!RegisterWindowMenuItem(Window->MyMenuItem,(void (*)(void*))&ActivateThisWindow,
  378.             Window->ScreenID))
  379.             {
  380.              FailurePoint17:
  381.                 KillMenuItem(Window->MyMenuItem);
  382.                 goto FailurePoint16;
  383.             }
  384.  
  385.         Window->SongPostProcessing = StringToBlockCopy("#song postprocessing\x0a");
  386.         if (Window->SongPostProcessing == NIL)
  387.             {
  388.              FailurePoint18:
  389.                 DeregisterWindowMenuItem(Window->MyMenuItem);
  390.                 goto FailurePoint17;
  391.             }
  392.         SetTag(Window->SongPostProcessing,"SongPostProcessing");
  393.  
  394.         Window->StereoPlayback = True;
  395.         Window->SurroundEncoding = False;
  396.         Window->SamplingRate = 44100;
  397.         Window->EnvelopeUpdateRate = 441;
  398.         Window->DefaultBeatsPerMinute = Double2LargeBCD(120);
  399.         Window->OverallVolumeScalingFactor = Double2LargeBCD(1);
  400.         Window->OutputNumBits = eOutput16Bits;
  401.         Window->InterpolateOverTime = True;
  402.         Window->InterpolateAcrossWaves = True;
  403.         Window->StuffModified = False;
  404.         Window->ScanningGap = Double2LargeBCD(2);
  405.         Window->BufferDuration = Double2LargeBCD(8);
  406.         Window->ClipWarning = True;
  407.         Window->SongPostProcessingEnable = False;
  408.  
  409.         Window->DeleteUndoFileLocation = NIL;
  410.         Window->DeleteUndoFile = NIL;
  411.  
  412.         /* reading the data or making an empty instrument */
  413.         if (TheFile == NIL)
  414.             {
  415.                 /* create a new empty one */
  416.                 Window->EverBeenSaved = False;
  417.             }
  418.          else
  419.             {
  420.                 FileType*                    FileDesc;
  421.  
  422.                 /* read a file in and update the file refnum and location variables */
  423.                 if (OpenFile(TheFile,&FileDesc,eReadAndWrite))
  424.                     {
  425.                         BufferedInputRec*    InputFileThang;
  426.  
  427.                         InputFileThang = NewBufferedInput(FileDesc);
  428.                         if (InputFileThang == NIL)
  429.                             {
  430.                                 AlertHalt("There is not enough memory available to read the file.",NIL);
  431.                                 ReleasePtr(Window->SongPostProcessing);
  432.                                 goto FailurePoint18;
  433.                             }
  434.                          else
  435.                             {
  436.                                 FileLoadingErrors    Error;
  437.  
  438.                                 Error = MainWindowReadData(Window,InputFileThang);
  439.                                 if (Error == eFileLoadNoError)
  440.                                     {
  441.                                         Error = SampleListReadData(Window->SampleList,InputFileThang);
  442.                                         if (Error == eFileLoadNoError)
  443.                                             {
  444.                                                 Error = FunctionListReadData(Window->FunctionList,
  445.                                                     InputFileThang);
  446.                                                 if (Error == eFileLoadNoError)
  447.                                                     {
  448.                                                         Error = AlgoSampListReadData(Window->AlgoSampList,
  449.                                                             InputFileThang);
  450.                                                         if (Error == eFileLoadNoError)
  451.                                                             {
  452.                                                                 Error = WaveTableListReadData(Window->WaveTableList,
  453.                                                                     InputFileThang);
  454.                                                                 if (Error == eFileLoadNoError)
  455.                                                                     {
  456.                                                                         Error = AlgoWaveTableListReadData(
  457.                                                                             Window->AlgoWaveTableList,InputFileThang);
  458.                                                                         if (Error == eFileLoadNoError)
  459.                                                                             {
  460.                                                                                 Error = InstrListReadData(Window->InstrumentList,
  461.                                                                                     InputFileThang);
  462.                                                                                 if (Error == eFileLoadNoError)
  463.                                                                                     {
  464.                                                                                         Error = TrackListReadData(Window->TrackList,
  465.                                                                                             InputFileThang);
  466.                                                                                     }
  467.                                                                             }
  468.                                                                     }
  469.                                                             }
  470.                                                     }
  471.                                             }
  472.                                     }
  473.                                 switch (Error)
  474.                                     {
  475.                                         default:
  476.                                             EXECUTE(PRERR(ForceAbort,"OpenDocument:  bad error code"));
  477.                                             break;
  478.                                         case eFileLoadNoError:
  479.                                             break;
  480.                                         case eFileLoadBadFormat:
  481.                                             AlertHalt("The file format is unrecognized.",NIL);
  482.                                             break;
  483.                                         case eFileLoadDiskError:
  484.                                             AlertHalt("A disk error occurred and the file could not be "
  485.                                                 "completely loaded.",NIL);
  486.                                             break;
  487.                                         case eFileLoadOutOfMemory:
  488.                                             AlertHalt("There is not enough memory available to completely "
  489.                                                 "load the file.  Try closing windows or quitting other "
  490.                                                 "applications to make more memory available.",NIL);
  491.                                             break;
  492.                                     }
  493.                             }
  494.                         EndBufferedInput(InputFileThang);
  495.                         MainWindowDeselectAllOtherStringLists(Window,NIL/*deselect all*/);
  496.                     }
  497.                  else
  498.                     {
  499.                         AlertHalt("Unable to open file for reading.",NIL);
  500.                         ReleasePtr(Window->SongPostProcessing);
  501.                         goto FailurePoint18;
  502.                     }
  503.                 Window->EverBeenSaved = True;
  504.                 Window->TheFileLocation = TheFile;
  505.                 Window->TheFile = FileDesc;
  506.             }
  507.  
  508.         MainWindowDispatchNameChange(Window);
  509.     }
  510.  
  511.  
  512. /* save the document into the current file.  if it hasn't been saved, then call SaveAs */
  513. /* it returns False if it fails. */
  514. MyBoolean                        SaveDocument(MainWindowRec* Window)
  515.     {
  516.         CheckPtrExistence(Window);
  517.         if (!Window->EverBeenSaved)
  518.             {
  519.                 return SaveDocumentAs(Window);
  520.             }
  521.          else
  522.             {
  523.                 FileType*                    TempFile;
  524.                 FileSpec*                    TempFileLocation;
  525.                 BufferedOutputRec*    OutputFileThang;
  526.                 FileLoadingErrors    Error;
  527.  
  528.                 /* create new file and write the data out here */
  529.                 /* create a temporary file in the same directory */
  530.                 TempFileLocation = NewTempFileInTheSameDirectory(Window->TheFileLocation);
  531.                 if (TempFileLocation == NIL)
  532.                     {
  533.                      FailurePoint1:
  534.                         AlertHalt("Unable to write out the data.",NIL);
  535.                         return False;
  536.                     }
  537.                 /* open the file */
  538.                 if (!OpenFile(TempFileLocation,&TempFile,eReadAndWrite))
  539.                     {
  540.                      FailurePoint2:
  541.                         DisposeFileSpec(TempFileLocation);
  542.                         goto FailurePoint1;
  543.                     }
  544.                 /* write all the data out */
  545.                 OutputFileThang = NewBufferedOutput(TempFile);
  546.                 if (OutputFileThang == NIL)
  547.                     {
  548.                      FailurePoint3:
  549.                         CloseFile(TempFile);
  550.                         DeleteFile(TempFileLocation);
  551.                         goto FailurePoint2;
  552.                     }
  553.                 Error = MainWindowWriteData(Window,OutputFileThang);
  554.                 if (Error == eFileLoadNoError)
  555.                     {
  556.                         Error = SampleListWriteData(Window->SampleList,OutputFileThang);
  557.                         if (Error == eFileLoadNoError)
  558.                             {
  559.                                 Error = FunctionListWriteData(Window->FunctionList,OutputFileThang);
  560.                                 if (Error == eFileLoadNoError)
  561.                                     {
  562.                                         Error = AlgoSampListWriteData(Window->AlgoSampList,OutputFileThang);
  563.                                         if (Error == eFileLoadNoError)
  564.                                             {
  565.                                                 Error = WaveTableListWriteData(Window->WaveTableList,
  566.                                                     OutputFileThang);
  567.                                                 if (Error == eFileLoadNoError)
  568.                                                     {
  569.                                                         Error = AlgoWaveTableListWriteData(Window->AlgoWaveTableList,
  570.                                                             OutputFileThang);
  571.                                                         if (Error == eFileLoadNoError)
  572.                                                             {
  573.                                                                 Error = InstrListWriteData(Window->InstrumentList,
  574.                                                                     OutputFileThang);
  575.                                                                 if (Error == eFileLoadNoError)
  576.                                                                     {
  577.                                                                         Error = TrackListWriteData(Window->TrackList,
  578.                                                                             OutputFileThang);
  579.                                                                         if (Error == eFileLoadNoError)
  580.                                                                             {
  581.                                                                                 if (EndBufferedOutput(OutputFileThang))
  582.                                                                                     {
  583.                                                                                         Error = eFileLoadNoError;
  584.                                                                                     }
  585.                                                                                  else
  586.                                                                                     {
  587.                                                                                         Error = eFileLoadDiskError;
  588.                                                                                     }
  589.                                                                             }
  590.                                                                     }
  591.                                                             }
  592.                                                     }
  593.                                             }
  594.                                     }
  595.                             }
  596.                     }
  597.                 switch (Error)
  598.                     {
  599.                         default:
  600.                             EXECUTE(PRERR(ForceAbort,"OpenDocument:  bad error code"));
  601.                             break;
  602.                         case eFileLoadNoError:
  603.                             break;
  604.                         case eFileLoadDiskError:
  605.                             AlertHalt("A disk error occurred and the file could not be saved.",NIL);
  606.                             goto FailurePoint3;
  607.                         case eFileLoadOutOfMemory:
  608.                             AlertHalt("There is not enough memory available to save the file.  "
  609.                                 "Try closing windows or quitting other applications to make more "
  610.                                 "memory available.",NIL);
  611.                             goto FailurePoint3;
  612.                     }
  613.                 FlushLocalBuffers(TempFile);
  614.                 /* swap the files on the disk */
  615.                 if (!SwapFileDataForks(TempFileLocation,Window->TheFileLocation,TempFile,
  616.                     &(Window->TheFile)))
  617.                     {
  618.                         /* if this fails, then the parameters are unaltered */
  619.                         goto FailurePoint3;
  620.                     }
  621.                 /* at this point, Window->TheFile has been fixed up, TempFile is closed, */
  622.                 /* and we need to dispose TempFileLocation */
  623.                 DisposeFileSpec(TempFileLocation);
  624.                 /* mark the data to indicate that it has been saved. */
  625.                 FunctionListMarkAllObjectsSaved(Window->FunctionList);
  626.                 SampleListMarkAllObjectsSaved(Window->SampleList);
  627.                 AlgoSampListMarkAllObjectsSaved(Window->AlgoSampList);
  628.                 WaveTableListMarkAllObjectsSaved(Window->WaveTableList);
  629.                 AlgoWaveTableListMarkAllObjectsSaved(Window->AlgoWaveTableList);
  630.                 InstrListMarkAllObjectsSaved(Window->InstrumentList);
  631.                 TrackListMarkAllObjectsSaved(Window->TrackList);
  632.                 TextEditHasBeenSaved(Window->CommentInfo);
  633.                 Window->StuffModified = False;
  634.                 /* return true since it saved correctly */
  635.                 return True;
  636.             }
  637.         EXECUTE(PRERR(ForceAbort,"SaveDocument:  control reached end of function"));
  638.     }
  639.  
  640.  
  641. /* close all open documents, subject to the user's ok */
  642. void                                DoCloseAllQuitPending(void)
  643.     {
  644.         while (ArrayGetLength(ListOfDocuments) > 0)
  645.             {
  646.                 MainWindowRec*        Window;
  647.  
  648.                 Window = (MainWindowRec*)ArrayGetElement(ListOfDocuments,0);
  649.                 ActivateThisWindow(Window->ScreenID);
  650.                 if (!CloseDocument(Window))
  651.                     {
  652.                         /* user cancelled */
  653.                         AbortQuitInProgress();
  654.                         return;
  655.                     }
  656.                 /* else keep going */
  657.             }
  658.     }
  659.  
  660.  
  661. /* close a document.  If the user cancelled, then return False, otherwise True */
  662. MyBoolean                        CloseDocument(MainWindowRec* Window)
  663.     {
  664.         long                Scan;
  665.  
  666.         CheckPtrExistence(Window);
  667.         if (HasDocumentBeenModified(Window))
  668.             {
  669.                 /* hafta ask permission */
  670.                 YesNoCancelType        WhatToDo;
  671.                 char*                            Filename;
  672.                 char*                            XFilename;
  673.  
  674.                 XFilename = GetCopyOfDocumentName(Window);
  675.                 if (XFilename == NIL)
  676.                     {
  677.                      FailurePoint1:
  678.                         AlertHalt("There is not enough memory to close the document.",NIL);
  679.                         return False;
  680.                     }
  681.                 Filename = BlockToStringCopy(XFilename);
  682.                 ReleasePtr(XFilename);
  683.                 if (Filename == NIL)
  684.                     {
  685.                         goto FailurePoint1;
  686.                     }
  687.                 WhatToDo = AskYesNoCancel("Save changes to Synthesizer document '_'?",
  688.                     Filename,"Save","Don't Save","Cancel");
  689.                 ReleasePtr(Filename);
  690.                 if (WhatToDo == eYes)
  691.                     {
  692.                         if (!SaveDocument(Window))
  693.                             {
  694.                                 /* save was cancelled or failed */
  695.                                 return False;
  696.                             }
  697.                     }
  698.                 else if (WhatToDo == eCancel)
  699.                     {
  700.                         return False; /* user cancelled */
  701.                     }
  702.                 /* fall through to deletion point */
  703.             }
  704.  
  705.         if (Window->DeleteUndoFileLocation != NIL)
  706.             {
  707.                 CloseFile(Window->DeleteUndoFile);
  708.                 DeleteFile(Window->DeleteUndoFileLocation);
  709.                 DisposeFileSpec(Window->DeleteUndoFileLocation);
  710.             }
  711.  
  712.         /* perform the data deletion here */
  713.         DisposeFunctionList(Window->FunctionList);
  714.         DisposeSampleList(Window->SampleList);
  715.         DisposeAlgoSampList(Window->AlgoSampList);
  716.         DisposeWaveTableList(Window->WaveTableList);
  717.         DisposeAlgoWaveTableList(Window->AlgoWaveTableList);
  718.         DisposeInstrList(Window->InstrumentList);
  719.         DisposeTrackList(Window->TrackList);
  720.  
  721.         DisposeTextEdit(Window->CommentInfo);
  722.  
  723.         for (Scan = 0; Scan < ArrayGetLength(Window->ListOfCalcWindows); Scan += 1)
  724.             {
  725.                 DisposeCalculatorWindow((CalcWindowRec*)ArrayGetElement(
  726.                     Window->ListOfCalcWindows,Scan));
  727.             }
  728.         DisposeArray(Window->ListOfCalcWindows);
  729.  
  730.         for (Scan = 0; Scan < ArrayGetLength(Window->ListOfDisassemblies); Scan += 1)
  731.             {
  732.                 DisposeDisassemblyWindow((DisaWindowRec*)ArrayGetElement(
  733.                     Window->ListOfDisassemblies,Scan));
  734.             }
  735.         DisposeArray(Window->ListOfDisassemblies);
  736.  
  737.         /* delete object code */
  738.         DisposeCodeCenter(Window->CodeCenter);
  739.  
  740.         ReleasePtr(Window->SongPostProcessing);
  741.  
  742.         DeregisterWindowMenuItem(Window->MyMenuItem);
  743.         KillMenuItem(Window->MyMenuItem);
  744.         CheckOutDyingWindow(Window->MyGenericWindow);
  745.         KillWindow(Window->ScreenID);
  746.         if (Window->EverBeenSaved)
  747.             {
  748.                 CloseFile(Window->TheFile);
  749.                 DisposeFileSpec(Window->TheFileLocation);
  750.             }
  751.         ERROR(ArrayFindElement(ListOfDocuments,Window) < 0,PRERR(ForceAbort,
  752.             "CloseDocument:  couldn't find document in the list"));
  753.         ArrayDeleteElement(ListOfDocuments,ArrayFindElement(ListOfDocuments,Window));
  754.         ReleasePtr((char*)Window);
  755.         return True;
  756.     }
  757.  
  758.  
  759. /* save the document into a new file (don't disturb the current one).  returns False */
  760. /* if it fails.  this function calls SaveDocument() to do the work. */
  761. MyBoolean                        SaveDocumentAs(MainWindowRec* Window)
  762.     {
  763.         FileSpec*                    NewWhere;
  764.         char*                            FilenameNull;
  765.         char*                            StringTempFileNameThing;
  766.  
  767.         CheckPtrExistence(Window);
  768.         StringTempFileNameThing = GetCopyOfDocumentName(Window);
  769.         if (StringTempFileNameThing == NIL)
  770.             {
  771.              FailurePoint1:
  772.                 AlertHalt("There is not enough memory to save the document.",NIL);
  773.                 return False;
  774.             }
  775.         FilenameNull = BlockToStringCopy(StringTempFileNameThing);
  776.         ReleasePtr(StringTempFileNameThing);
  777.         if (FilenameNull == NIL)
  778.             {
  779.                 goto FailurePoint1;
  780.             }
  781.         /* where do they want to save it */
  782.         NewWhere = PutFile(FilenameNull);
  783.         ReleasePtr(FilenameNull);
  784.         if (NewWhere != NIL)
  785.             {
  786.                 FileType*                    NewFile;
  787.                 char*                            XFilename;
  788.                 MyBoolean                    SaveWasSuccessful;
  789.  
  790.                 XFilename = ExtractFileName(NewWhere);
  791.                 if (XFilename == NIL)
  792.                     {
  793.                         goto FailurePoint1;
  794.                     }
  795.                 FilenameNull = BlockToStringCopy(XFilename);
  796.                 ReleasePtr(XFilename);
  797.                 if (FilenameNull == NIL)
  798.                     {
  799.                         goto FailurePoint1;
  800.                     }
  801.                 if (!CreateFile(NewWhere,ApplicationCreator,ApplicationFileType))
  802.                     {
  803.                         AlertHalt("Couldn't create the file '_'.",FilenameNull);
  804.                         ReleasePtr(FilenameNull);
  805.                         return False;
  806.                     }
  807.                 if (!OpenFile(NewWhere,&NewFile,eReadAndWrite))
  808.                     {
  809.                         AlertHalt("Couldn't open the file '_'.",FilenameNull);
  810.                         ReleasePtr(FilenameNull);
  811.                         return False;
  812.                     }
  813.                 if (Window->EverBeenSaved)
  814.                     {
  815.                         CloseFile(Window->TheFile);
  816.                         DisposeFileSpec(Window->TheFileLocation);
  817.                         Window->EverBeenSaved = False;
  818.                     }
  819.                 Window->EverBeenSaved = True;
  820.                 Window->TheFileLocation = NewWhere;
  821.                 Window->TheFile = NewFile;
  822.                 ReleasePtr(FilenameNull);
  823.                 SaveWasSuccessful = SaveDocument(Window);
  824.                 if (!SaveWasSuccessful)
  825.                     {
  826.                         /* if save wasn't successful, then get rid of the file stuff */
  827.                         CloseFile(Window->TheFile);
  828.                         DeleteFile(Window->TheFileLocation);
  829.                         DisposeFileSpec(Window->TheFileLocation);
  830.                         Window->EverBeenSaved = False;
  831.                     }
  832.                 MainWindowDispatchNameChange(Window);
  833.                 return SaveWasSuccessful;
  834.             }
  835.          else
  836.             {
  837.                 return False;
  838.             }
  839.         EXECUTE(PRERR(ForceAbort,"SaveDocumentAs:  control reached end of function"));
  840.     }
  841.  
  842.  
  843. /* return True if the document has been modified & should be saved. */
  844. MyBoolean                        HasDocumentBeenModified(MainWindowRec* Window)
  845.     {
  846.         CheckPtrExistence(Window);
  847.         return Window->StuffModified
  848.             || TextEditDoesItNeedToBeSaved(Window->CommentInfo)
  849.             || DoesFunctionListNeedToBeSaved(Window->FunctionList)
  850.             || DoesSampleListNeedToBeSaved(Window->SampleList)
  851.             || DoesAlgoSampListNeedToBeSaved(Window->AlgoSampList)
  852.             || DoesWaveTableListNeedToBeSaved(Window->WaveTableList)
  853.             || DoesAlgoWaveTableListNeedToBeSaved(Window->AlgoWaveTableList)
  854.             || DoesInstrListNeedToBeSaved(Window->InstrumentList)
  855.             || DoesTrackListNeedToBeSaved(Window->TrackList);
  856.     }
  857.  
  858.  
  859. void                                MainWindowDoIdle(MainWindowRec* Window,
  860.                                             MyBoolean CheckCursorFlag, OrdType XLoc, OrdType YLoc,
  861.                                             ModifierFlags Modifiers)
  862.     {
  863.         CheckPtrExistence(Window);
  864.         TextEditUpdateCursor(Window->CommentInfo);
  865.         if (CheckCursorFlag)
  866.             {
  867.                 if (TextEditIBeamTest(Window->CommentInfo,XLoc,YLoc))
  868.                     {
  869.                         SetIBeamCursor();
  870.                     }
  871.                  else
  872.                     {
  873.                         SetArrowCursor();
  874.                     }
  875.             }
  876.     }
  877.  
  878.  
  879. void                                MainWindowBecomeActive(MainWindowRec* Window)
  880.     {
  881.         OrdType            XSize;
  882.         OrdType            YSize;
  883.  
  884.         CheckPtrExistence(Window);
  885.         EnableTextEditSelection(Window->CommentInfo);
  886.         FunctionListBecomeActive(Window->FunctionList);
  887.         SampleListBecomeActive(Window->SampleList);
  888.         AlgoSampListBecomeActive(Window->AlgoSampList);
  889.         WaveTableListBecomeActive(Window->WaveTableList);
  890.         AlgoWaveTableListBecomeActive(Window->AlgoWaveTableList);
  891.         InstrListBecomeActive(Window->InstrumentList);
  892.         TrackListBecomeActive(Window->TrackList);
  893.         XSize = GetWindowWidth(Window->ScreenID);
  894.         YSize = GetWindowHeight(Window->ScreenID);
  895.         SetClipRect(Window->ScreenID,XSize - 15,YSize - 15,XSize,YSize);
  896.         DrawBitmap(Window->ScreenID,XSize-15,YSize-15,GetGrowIcon(True/*enablegrowicon*/));
  897.     }
  898.  
  899.  
  900. void                                MainWindowBecomeInactive(MainWindowRec* Window)
  901.     {
  902.         OrdType            XSize;
  903.         OrdType            YSize;
  904.  
  905.         CheckPtrExistence(Window);
  906.         DisableTextEditSelection(Window->CommentInfo);
  907.         FunctionListBecomeInactive(Window->FunctionList);
  908.         SampleListBecomeInactive(Window->SampleList);
  909.         AlgoSampListBecomeInactive(Window->AlgoSampList);
  910.         WaveTableListBecomeInactive(Window->WaveTableList);
  911.         AlgoWaveTableListBecomeInactive(Window->AlgoWaveTableList);
  912.         InstrListBecomeInactive(Window->InstrumentList);
  913.         TrackListBecomeInactive(Window->TrackList);
  914.         XSize = GetWindowWidth(Window->ScreenID);
  915.         YSize = GetWindowHeight(Window->ScreenID);
  916.         SetClipRect(Window->ScreenID,XSize - 15,YSize - 15,XSize,YSize);
  917.         DrawBitmap(Window->ScreenID,XSize-15,YSize-15,GetGrowIcon(False/*disablegrowicon*/));
  918.     }
  919.  
  920.  
  921. void                                MainWindowJustResized(MainWindowRec* Window)
  922.     {
  923.         OrdType            XSize;
  924.         OrdType            YSize;
  925.  
  926.         CheckPtrExistence(Window);
  927.         XSize = GetWindowWidth(Window->ScreenID);
  928.         YSize = GetWindowHeight(Window->ScreenID);
  929.         SetClipRect(Window->ScreenID,0,0,XSize,YSize);
  930.         DrawBoxErase(Window->ScreenID,0,0,XSize,YSize);
  931.         SetTextEditPosition(Window->CommentInfo,
  932.             COMMENTX(XSize,YSize),COMMENTY(XSize,YSize),
  933.             COMMENTWIDTH(XSize,YSize),COMMENTHEIGHT(XSize,YSize));
  934.         SetFunctionListLocation(Window->FunctionList,
  935.             FUNCTIONX(XSize,YSize),FUNCTIONY(XSize,YSize),
  936.             FUNCTIONWIDTH(XSize,YSize),FUNCTIONHEIGHT(XSize,YSize));
  937.         SetSampleListLocation(Window->SampleList,
  938.             SAMPLEX(XSize,YSize),SAMPLEY(XSize,YSize),
  939.             SAMPLEWIDTH(XSize,YSize),SAMPLEHEIGHT(XSize,YSize));
  940.         SetAlgoSampListLocation(Window->AlgoSampList,
  941.             ALGOSAMPLEX(XSize,YSize),ALGOSAMPLEY(XSize,YSize),
  942.             ALGOSAMPLEWIDTH(XSize,YSize),ALGOSAMPLEHEIGHT(XSize,YSize));
  943.         SetWaveTableListLocation(Window->WaveTableList,
  944.             WAVETABLEX(XSize,YSize),WAVETABLEY(XSize,YSize),WAVETABLEWIDTH(XSize,YSize),
  945.             WAVETABLEHEIGHT(XSize,YSize));
  946.         SetAlgoWaveTableListLocation(Window->AlgoWaveTableList,
  947.             ALGOWAVETABLEX(XSize,YSize),ALGOWAVETABLEY(XSize,YSize),
  948.             ALGOWAVETABLEWIDTH(XSize,YSize),ALGOWAVETABLEHEIGHT(XSize,YSize));
  949.         SetInstrListLocation(Window->InstrumentList,INSTRUMENTX(XSize,YSize),
  950.             INSTRUMENTY(XSize,YSize),INSTRUMENTWIDTH(XSize,YSize),INSTRUMENTHEIGHT(XSize,YSize));
  951.         SetTrackListLocation(Window->TrackList,TRACKX(XSize,YSize),TRACKY(XSize,YSize),
  952.             TRACKWIDTH(XSize,YSize),TRACKHEIGHT(XSize,YSize));
  953.     }
  954.  
  955.  
  956. void                                MainWindowDoMouseDown(OrdType XLoc, OrdType YLoc,
  957.                                             ModifierFlags Modifiers, MainWindowRec* Window)
  958.     {
  959.         CheckPtrExistence(Window);
  960.         if ((XLoc >= GetWindowWidth(Window->ScreenID) - 15)
  961.             && (XLoc < GetWindowWidth(Window->ScreenID))
  962.             && (YLoc >= GetWindowHeight(Window->ScreenID) - 15)
  963.             && (YLoc < GetWindowHeight(Window->ScreenID)))
  964.             {
  965.                 UserGrowWindow(Window->ScreenID,XLoc,YLoc);
  966.                 MainWindowJustResized(Window);
  967.             }
  968.         else if (TextEditHitTest(Window->CommentInfo,XLoc,YLoc))
  969.             {
  970.                 TextEditDoMouseDown(Window->CommentInfo,XLoc,YLoc,Modifiers);
  971.             }
  972.         else if (FunctionListHitTest(Window->FunctionList,XLoc,YLoc))
  973.             {
  974.                 MainWindowDeselectAllOtherStringLists(Window,Window->FunctionList);
  975.                 FunctionListDoMouseDown(Window->FunctionList,XLoc,YLoc,Modifiers);
  976.             }
  977.         else if (SampleListHitTest(Window->SampleList,XLoc,YLoc))
  978.             {
  979.                 MainWindowDeselectAllOtherStringLists(Window,Window->SampleList);
  980.                 SampleListDoMouseDown(Window->SampleList,XLoc,YLoc,Modifiers);
  981.             }
  982.         else if (AlgoSampListHitTest(Window->AlgoSampList,XLoc,YLoc))
  983.             {
  984.                 MainWindowDeselectAllOtherStringLists(Window,Window->AlgoSampList);
  985.                 AlgoSampListDoMouseDown(Window->AlgoSampList,XLoc,YLoc,Modifiers);
  986.             }
  987.         else if (WaveTableListHitTest(Window->WaveTableList,XLoc,YLoc))
  988.             {
  989.                 MainWindowDeselectAllOtherStringLists(Window,Window->WaveTableList);
  990.                 WaveTableListDoMouseDown(Window->WaveTableList,XLoc,YLoc,Modifiers);
  991.             }
  992.         else if (AlgoWaveTableListHitTest(Window->AlgoWaveTableList,XLoc,YLoc))
  993.             {
  994.                 MainWindowDeselectAllOtherStringLists(Window,Window->AlgoWaveTableList);
  995.                 AlgoWaveTableListDoMouseDown(Window->AlgoWaveTableList,XLoc,YLoc,Modifiers);
  996.             }
  997.         else if (InstrListHitTest(Window->InstrumentList,XLoc,YLoc))
  998.             {
  999.                 MainWindowDeselectAllOtherStringLists(Window,Window->InstrumentList);
  1000.                 InstrListDoMouseDown(Window->InstrumentList,XLoc,YLoc,Modifiers);
  1001.             }
  1002.         else if (TrackListHitTest(Window->TrackList,XLoc,YLoc))
  1003.             {
  1004.                 MainWindowDeselectAllOtherStringLists(Window,Window->TrackList);
  1005.                 TrackListDoMouseDown(Window->TrackList,XLoc,YLoc,Modifiers);
  1006.             }
  1007.     }
  1008.  
  1009.  
  1010. void                                MainWindowDoKeyDown(unsigned char KeyCode, ModifierFlags Modifiers,
  1011.                                             MainWindowRec* Window)
  1012.     {
  1013.         CheckPtrExistence(Window);
  1014.         TextEditDoKeyPressed(Window->CommentInfo,KeyCode,Modifiers);
  1015.     }
  1016.  
  1017.  
  1018. void                                MainWindowClose(MainWindowRec* Window)
  1019.     {
  1020.         CheckPtrExistence(Window);
  1021.         CloseDocument(Window);
  1022.     }
  1023.  
  1024.  
  1025. void                                MainWindowUpdator(MainWindowRec* Window)
  1026.     {
  1027.         OrdType                        XSize;
  1028.         OrdType                        YSize;
  1029.  
  1030.         CheckPtrExistence(Window);
  1031.         FunctionListRedraw(Window->FunctionList);
  1032.         SampleListRedraw(Window->SampleList);
  1033.         AlgoSampListRedraw(Window->AlgoSampList);
  1034.         WaveTableListRedraw(Window->WaveTableList);
  1035.         AlgoWaveTableListRedraw(Window->AlgoWaveTableList);
  1036.         InstrListRedraw(Window->InstrumentList);
  1037.         TrackListRedraw(Window->TrackList);
  1038.         TextEditFullRedraw(Window->CommentInfo);
  1039.         XSize = GetWindowWidth(Window->ScreenID);
  1040.         YSize = GetWindowHeight(Window->ScreenID);
  1041.         SetClipRect(Window->ScreenID,XSize - 15,YSize - 15,XSize,YSize);
  1042.         DrawBitmap(Window->ScreenID,XSize-15,YSize-15,
  1043.             GetGrowIcon(Window->MyGenericWindow == GetCurrentWindowID()));
  1044.     }
  1045.  
  1046.  
  1047. /* enable global menu items.  these are menu items that can be chosen regardless */
  1048. /* of which editor is open (such as New Object, Save...) */
  1049. void                                MainWindowMenuSetup(MainWindowRec* Window)
  1050.     {
  1051.         MainWindowEnableGlobalMenus(Window);
  1052.         EnableMenuItem(mPaste);
  1053.         if (TextEditIsThereValidSelection(Window->CommentInfo))
  1054.             {
  1055.                 EnableMenuItem(mCut);
  1056.                 EnableMenuItem(mCopy);
  1057.                 EnableMenuItem(mClear);
  1058.             }
  1059.         EnableMenuItem(mSelectAll);
  1060.         if (TextEditCanWeUndo(Window->CommentInfo))
  1061.             {
  1062.                 EnableMenuItem(mUndo);
  1063.                 ChangeItemName(mUndo,"Undo Text Edit");
  1064.             }
  1065.         if (Window->DeleteUndoFileLocation != NIL)
  1066.             {
  1067.                 EnableMenuItem(mUndo);
  1068.                 ChangeItemName(mUndo,"Undo Object Deletion");
  1069.             }
  1070.         ChangeItemName(mCloseFile,"Close Document");
  1071.         EnableMenuItem(mCloseFile);
  1072.  
  1073.         EnableMenuItem(mPasteObject);
  1074.         EnableMenuItem(mCopyObject);
  1075.         EnableMenuItem(mOpenObject);
  1076.         EnableMenuItem(mDeleteObject);
  1077.         if (FunctionListIsThereSelection(Window->FunctionList))
  1078.             {
  1079.                 ChangeItemName(mOpenObject,"Edit Function Module");
  1080.                 ChangeItemName(mDeleteObject,"Delete Function Module");
  1081.                 ChangeItemName(mCopyObject,"Copy Function Module");
  1082.             }
  1083.         else if (SampleListIsThereSelection(Window->SampleList))
  1084.             {
  1085.                 ChangeItemName(mOpenObject,"Edit Sample");
  1086.                 ChangeItemName(mDeleteObject,"Delete Sample");
  1087.                 ChangeItemName(mCopyObject,"Copy Sample");
  1088.             }
  1089.         else if (AlgoSampListIsThereSelection(Window->AlgoSampList))
  1090.             {
  1091.                 ChangeItemName(mOpenObject,"Edit Algorithmic Sample");
  1092.                 ChangeItemName(mDeleteObject,"Delete Algorithmic Sample");
  1093.                 ChangeItemName(mCopyObject,"Copy Algorithmic Sample");
  1094.             }
  1095.         else if (WaveTableListIsThereSelection(Window->WaveTableList))
  1096.             {
  1097.                 ChangeItemName(mOpenObject,"Edit Wave Table");
  1098.                 ChangeItemName(mDeleteObject,"Delete Wave Table");
  1099.                 ChangeItemName(mCopyObject,"Copy Wave Table");
  1100.             }
  1101.         else if (AlgoWaveTableListIsThereSelection(Window->AlgoWaveTableList))
  1102.             {
  1103.                 ChangeItemName(mOpenObject,"Edit Algorithmic Wave Table");
  1104.                 ChangeItemName(mDeleteObject,"Delete Algorithmic Wave Table");
  1105.                 ChangeItemName(mCopyObject,"Copy Algorithmic Wave Table");
  1106.             }
  1107.         else if (InstrListIsThereSelection(Window->InstrumentList))
  1108.             {
  1109.                 ChangeItemName(mOpenObject,"Edit Instrument");
  1110.                 ChangeItemName(mDeleteObject,"Delete Instrument");
  1111.                 ChangeItemName(mCopyObject,"Copy Instrument");
  1112.             }
  1113.         else if (TrackListIsThereSelection(Window->TrackList))
  1114.             {
  1115.                 ChangeItemName(mOpenObject,"Edit Track");
  1116.                 ChangeItemName(mDeleteObject,"Delete Track");
  1117.                 ChangeItemName(mCopyObject,"Copy Track");
  1118.             }
  1119.         else
  1120.             {
  1121.                 DisableMenuItem(mOpenObject);
  1122.                 DisableMenuItem(mDeleteObject);
  1123.                 DisableMenuItem(mCopyObject);
  1124.             }
  1125.         SetItemCheckmark(Window->MyMenuItem);
  1126.     }
  1127.  
  1128.  
  1129. void                                MainWindowDoMenuCommand(MainWindowRec* Window,
  1130.                                             MenuItemType* MenuItem)
  1131.     {
  1132.         CheckPtrExistence(Window);
  1133.         if (MainWindowDoGlobalMenuItem(Window,MenuItem))
  1134.             {
  1135.             }
  1136.         else if (MenuItem == mPaste)
  1137.             {
  1138.                 TextEditDoMenuPaste(Window->CommentInfo);
  1139.             }
  1140.         else if (MenuItem == mCut)
  1141.             {
  1142.                 TextEditDoMenuCut(Window->CommentInfo);
  1143.             }
  1144.         else if (MenuItem == mCopy)
  1145.             {
  1146.                 TextEditDoMenuCopy(Window->CommentInfo);
  1147.             }
  1148.         else if (MenuItem == mClear)
  1149.             {
  1150.                 TextEditDoMenuClear(Window->CommentInfo);
  1151.             }
  1152.         else if (MenuItem == mSelectAll)
  1153.             {
  1154.                 TextEditDoMenuSelectAll(Window->CommentInfo);
  1155.             }
  1156.         else if (MenuItem == mUndo)
  1157.             {
  1158.                 /* object deletion undo takes precedence */
  1159.                 if (Window->DeleteUndoFileLocation != NIL)
  1160.                     {
  1161.                         MyBoolean                    DidIt = True;
  1162.  
  1163.                         if (!FunctionListPasteFromFile(Window->FunctionList,
  1164.                             Window->DeleteUndoFile))
  1165.                             {
  1166.                                 if (!SampleListPasteFromFile(Window->SampleList,
  1167.                                     Window->DeleteUndoFile))
  1168.                                     {
  1169.                                         if (!AlgoSampListPasteFromFile(Window->AlgoSampList,
  1170.                                             Window->DeleteUndoFile))
  1171.                                             {
  1172.                                                 if (!WaveTableListPasteFromFile(Window->WaveTableList,
  1173.                                                     Window->DeleteUndoFile))
  1174.                                                     {
  1175.                                                         if (!AlgoWaveTableListPasteFromFile(Window->AlgoWaveTableList,
  1176.                                                             Window->DeleteUndoFile))
  1177.                                                             {
  1178.                                                                 if (!InstrListPasteFromFile(Window->InstrumentList,
  1179.                                                                     Window->DeleteUndoFile))
  1180.                                                                     {
  1181.                                                                         if (!TrackListPasteFromFile(Window->TrackList,
  1182.                                                                             Window->DeleteUndoFile))
  1183.                                                                             {
  1184.                                                                                 /* couldn't do it, maybe out of memory */
  1185.                                                                                 DidIt = False;
  1186.                                                                             }
  1187.                                                                     }
  1188.                                                             }
  1189.                                                     }
  1190.                                             }
  1191.                                     }
  1192.                             }
  1193.                         if (DidIt)
  1194.                             {
  1195.                                 CloseFile(Window->DeleteUndoFile);
  1196.                                 DeleteFile(Window->DeleteUndoFileLocation);
  1197.                                 DisposeFileSpec(Window->DeleteUndoFileLocation);
  1198.                                 Window->DeleteUndoFileLocation = NIL;
  1199.                                 Window->DeleteUndoFile = NIL;
  1200.                             }
  1201.                     }
  1202.                  else
  1203.                     {
  1204.                         TextEditDoMenuUndo(Window->CommentInfo);
  1205.                     }
  1206.             }
  1207.         else if (MenuItem == mCloseFile)
  1208.             {
  1209.                 CloseDocument(Window);
  1210.             }
  1211.         else if (MenuItem == mOpenObject)
  1212.             {
  1213.                 if (FunctionListIsThereSelection(Window->FunctionList))
  1214.                     {
  1215.                         FunctionListOpenSelection(Window->FunctionList);
  1216.                     }
  1217.                 else if (SampleListIsThereSelection(Window->SampleList))
  1218.                     {
  1219.                         SampleListOpenSelection(Window->SampleList);
  1220.                     }
  1221.                 else if (AlgoSampListIsThereSelection(Window->AlgoSampList))
  1222.                     {
  1223.                         AlgoSampListOpenSelection(Window->AlgoSampList);
  1224.                     }
  1225.                 else if (WaveTableListIsThereSelection(Window->WaveTableList))
  1226.                     {
  1227.                         WaveTableListOpenSelection(Window->WaveTableList);
  1228.                     }
  1229.                 else if (AlgoWaveTableListIsThereSelection(Window->AlgoWaveTableList))
  1230.                     {
  1231.                         AlgoWaveTableListOpenSelection(Window->AlgoWaveTableList);
  1232.                     }
  1233.                 else if (InstrListIsThereSelection(Window->InstrumentList))
  1234.                     {
  1235.                         InstrListOpenSelection(Window->InstrumentList);
  1236.                     }
  1237.                 else if (TrackListIsThereSelection(Window->TrackList))
  1238.                     {
  1239.                         TrackListOpenSelection(Window->TrackList);
  1240.                     }
  1241.                 else
  1242.                     {
  1243.                         EXECUTE(PRERR(AllowResume,
  1244.                             "MainWindowDoMenuCommand(mOpenObject):  no known selection"));
  1245.                     }
  1246.             }
  1247.         else if (MenuItem == mDeleteObject)
  1248.             {
  1249.                 if (FunctionListIsThereSelection(Window->FunctionList))
  1250.                     {
  1251.                         FunctionListDeleteSelection(Window->FunctionList);
  1252.                     }
  1253.                 else if (SampleListIsThereSelection(Window->SampleList))
  1254.                     {
  1255.                         SampleListDeleteSelection(Window->SampleList);
  1256.                     }
  1257.                 else if (AlgoSampListIsThereSelection(Window->AlgoSampList))
  1258.                     {
  1259.                         AlgoSampListDeleteSelection(Window->AlgoSampList);
  1260.                     }
  1261.                 else if (WaveTableListIsThereSelection(Window->WaveTableList))
  1262.                     {
  1263.                         WaveTableListDeleteSelection(Window->WaveTableList);
  1264.                     }
  1265.                 else if (AlgoWaveTableListIsThereSelection(Window->AlgoWaveTableList))
  1266.                     {
  1267.                         AlgoWaveTableListDeleteSelection(Window->AlgoWaveTableList);
  1268.                     }
  1269.                 else if (InstrListIsThereSelection(Window->InstrumentList))
  1270.                     {
  1271.                         InstrListDeleteSelection(Window->InstrumentList);
  1272.                     }
  1273.                 else if (TrackListIsThereSelection(Window->TrackList))
  1274.                     {
  1275.                         TrackListDeleteSelection(Window->TrackList);
  1276.                     }
  1277.                 else
  1278.                     {
  1279.                         EXECUTE(PRERR(AllowResume,
  1280.                             "MainWindowDoMenuCommand(mDeleteObject):  no known selection"));
  1281.                     }
  1282.             }
  1283.         else if (MenuItem == mPasteObject)
  1284.             {
  1285.                 if (!FunctionListPasteObject(Window->FunctionList))
  1286.                     {
  1287.                         if (!SampleListPasteObject(Window->SampleList))
  1288.                             {
  1289.                                 if (!AlgoSampListPasteObject(Window->AlgoSampList))
  1290.                                     {
  1291.                                         if (!WaveTableListPasteObject(Window->WaveTableList))
  1292.                                             {
  1293.                                                 if (!AlgoWaveTableListPasteObject(Window->AlgoWaveTableList))
  1294.                                                     {
  1295.                                                         if (!InstrListPasteObject(Window->InstrumentList))
  1296.                                                             {
  1297.                                                                 if (!TrackListPasteObject(Window->TrackList))
  1298.                                                                     {
  1299.                                                                         /* oh well, it must not be an object */
  1300.                                                                     }
  1301.                                                             }
  1302.                                                     }
  1303.                                             }
  1304.                                     }
  1305.                             }
  1306.                     }
  1307.             }
  1308.         else if (MenuItem == mCopyObject)
  1309.             {
  1310.                 if (FunctionListIsThereSelection(Window->FunctionList))
  1311.                     {
  1312.                         FunctionListCopyObject(Window->FunctionList);
  1313.                     }
  1314.                 else if (SampleListIsThereSelection(Window->SampleList))
  1315.                     {
  1316.                         SampleListCopyObject(Window->SampleList);
  1317.                     }
  1318.                 else if (AlgoSampListIsThereSelection(Window->AlgoSampList))
  1319.                     {
  1320.                         AlgoSampListCopyObject(Window->AlgoSampList);
  1321.                     }
  1322.                 else if (WaveTableListIsThereSelection(Window->WaveTableList))
  1323.                     {
  1324.                         WaveTableListCopyObject(Window->WaveTableList);
  1325.                     }
  1326.                 else if (AlgoWaveTableListIsThereSelection(Window->AlgoWaveTableList))
  1327.                     {
  1328.                         AlgoWaveTableListCopyObject(Window->AlgoWaveTableList);
  1329.                     }
  1330.                 else if (InstrListIsThereSelection(Window->InstrumentList))
  1331.                     {
  1332.                         InstrListCopyObject(Window->InstrumentList);
  1333.                     }
  1334.                 else if (TrackListIsThereSelection(Window->TrackList))
  1335.                     {
  1336.                         TrackListCopyObject(Window->TrackList);
  1337.                     }
  1338.                 else
  1339.                     {
  1340.                         EXECUTE(PRERR(AllowResume,
  1341.                             "MainWindowDoMenuCommand(mCopyObject):  no known selection"));
  1342.                     }
  1343.             }
  1344.         else
  1345.             {
  1346.                 EXECUTE(PRERR(AllowResume,"MainWindowDoMenuCommand:  unknown menu command"));
  1347.             }
  1348.     }
  1349.  
  1350.  
  1351. /* deselect any selection in a scrolling list other than the specified list. */
  1352. /* specified list may be NIL for unconditional deselect */
  1353. void                                MainWindowDeselectAllOtherStringLists(MainWindowRec* Window,
  1354.                                             void* TheDontDeselectStringList)
  1355.     {
  1356.         CheckPtrExistence(Window);
  1357.         if (TheDontDeselectStringList != Window->FunctionList)
  1358.             {
  1359.                 FunctionListDeselect(Window->FunctionList);
  1360.             }
  1361.         if (TheDontDeselectStringList != Window->SampleList)
  1362.             {
  1363.                 SampleListDeselect(Window->SampleList);
  1364.             }
  1365.         if (TheDontDeselectStringList != Window->AlgoSampList)
  1366.             {
  1367.                 AlgoSampListDeselect(Window->AlgoSampList);
  1368.             }
  1369.         if (TheDontDeselectStringList != Window->WaveTableList)
  1370.             {
  1371.                 WaveTableListDeselect(Window->WaveTableList);
  1372.             }
  1373.         if (TheDontDeselectStringList != Window->AlgoWaveTableList)
  1374.             {
  1375.                 AlgoWaveTableListDeselect(Window->AlgoWaveTableList);
  1376.             }
  1377.         if (TheDontDeselectStringList != Window->InstrumentList)
  1378.             {
  1379.                 InstrListDeselect(Window->InstrumentList);
  1380.             }
  1381.         if (TheDontDeselectStringList != Window->TrackList)
  1382.             {
  1383.                 TrackListDeselect(Window->TrackList);
  1384.             }
  1385.     }
  1386.  
  1387.  
  1388. /* create a new calculator window.  the main window keeps track of all calculator */
  1389. /* objects that it has created */
  1390. void                                MainWindowNewCalculator(MainWindowRec* Window)
  1391.     {
  1392.         CalcWindowRec*        Calc;
  1393.  
  1394.         CheckPtrExistence(Window);
  1395.         Calc = NewCalculatorWindow(Window,Window->CodeCenter);
  1396.         if (Calc == NIL)
  1397.             {
  1398.              FailurePoint1:
  1399.                 AlertHalt("There is not enough memory available to "
  1400.                     "open a calculator window.",NIL);
  1401.                 return;
  1402.             }
  1403.         if (!ArrayAppendElement(Window->ListOfCalcWindows,Calc))
  1404.             {
  1405.              FailurePoint2:
  1406.                 DisposeCalculatorWindow(Calc);
  1407.                 goto FailurePoint1;
  1408.             }
  1409.     }
  1410.  
  1411.  
  1412. /* when a calculator window closes, it calls this to make sure the main window */
  1413. /* object knows that it no longer exists */
  1414. void                                MainWindowCalculatorClosingNotify(MainWindowRec* Window,
  1415.                                             CalcWindowRec* Calc)
  1416.     {
  1417.         CheckPtrExistence(Window);
  1418.         ERROR(ArrayFindElement(Window->ListOfCalcWindows,Calc) < 0,PRERR(ForceAbort,
  1419.             "MainWindowCalculatorClosingNotify:  unknown calculator window"));
  1420.         ArrayDeleteElement(Window->ListOfCalcWindows,
  1421.             ArrayFindElement(Window->ListOfCalcWindows,Calc));
  1422.     }
  1423.  
  1424.  
  1425. /* notify the main window that a new disassembly window has been created. */
  1426. MyBoolean                        MainWindowNewDisassemblyNotify(MainWindowRec* Window,
  1427.                                             struct DisaWindowRec* DisassemblyWindow)
  1428.     {
  1429.         CheckPtrExistence(Window);
  1430.         if (!ArrayAppendElement(Window->ListOfDisassemblies,DisassemblyWindow))
  1431.             {
  1432.                 return False;
  1433.             }
  1434.         return True;
  1435.     }
  1436.  
  1437.  
  1438. /* notify the main window that a disassembly window has been destroyed. */
  1439. void                                MainWindowDisassemblyClosingNotify(MainWindowRec* Window,
  1440.                                             struct DisaWindowRec* DisassemblyWindow)
  1441.     {
  1442.         CheckPtrExistence(Window);
  1443.         ERROR(ArrayFindElement(Window->ListOfDisassemblies,DisassemblyWindow) < 0,
  1444.             PRERR(ForceAbort,"MainWindowDisassemblyClosingNotify:  unknown disassembly"));
  1445.         ArrayDeleteElement(Window->ListOfDisassemblies,
  1446.             ArrayFindElement(Window->ListOfDisassemblies,DisassemblyWindow));
  1447.     }
  1448.  
  1449.  
  1450. /* get the number of spaces per tab that editors should use */
  1451. long                                MainWindowGetTabSize(MainWindowRec* Window)
  1452.     {
  1453.         CheckPtrExistence(Window);
  1454.         return Window->TabSize;
  1455.     }
  1456.  
  1457.  
  1458. /* build any function objects that need to be built.  returns True if all of them */
  1459. /* were built without a problem. */
  1460. MyBoolean                        MainWindowMakeUpToDateFunctions(MainWindowRec* Window)
  1461.     {
  1462.         CheckPtrExistence(Window);
  1463.         return FunctionListMakeUpToDate(Window->FunctionList);
  1464.     }
  1465.  
  1466.  
  1467. /* build any algorithmic samples that need to be built.  returns True if all of them */
  1468. /* were built without a problem. */
  1469. MyBoolean                        MainWindowMakeUpToDateAlgoSamps(MainWindowRec* Window)
  1470.     {
  1471.         CheckPtrExistence(Window);
  1472.         return AlgoSampListMakeUpToDate(Window->AlgoSampList);
  1473.     }
  1474.  
  1475.  
  1476. /* build any algorithmic wave tables that need to be built.  returns True if all of */
  1477. /* them were built without a problem. */
  1478. MyBoolean                        MainWindowMakeUpToDateAlgoWaveTables(MainWindowRec* Window)
  1479.     {
  1480.         CheckPtrExistence(Window);
  1481.         return AlgoWaveTableListMakeUpToDate(Window->AlgoWaveTableList);
  1482.     }
  1483.  
  1484.  
  1485. /* build any instrument specifications that need to be built.  returns True if all of */
  1486. /* them were built without a problem. */
  1487. MyBoolean                        MainWindowMakeUpToDateInstrList(MainWindowRec* Window)
  1488.     {
  1489.         CheckPtrExistence(Window);
  1490.         return InstrListMakeUpToDate(Window->InstrumentList);
  1491.     }
  1492.  
  1493.  
  1494. /* build everything.  returns True if everything built correctly */
  1495. MyBoolean                        MainWindowMakeEverythingUpToDate(MainWindowRec* Window)
  1496.     {
  1497.         MyBoolean                    ReturnValue;
  1498.  
  1499.         CheckPtrExistence(Window);
  1500.         ReturnValue = False;
  1501.         if (MainWindowMakeUpToDateFunctions(Window))
  1502.             {
  1503.                 if (MainWindowMakeUpToDateAlgoSamps(Window))
  1504.                     {
  1505.                         if (MainWindowMakeUpToDateAlgoWaveTables(Window))
  1506.                             {
  1507.                                 if (MainWindowMakeUpToDateInstrList(Window))
  1508.                                     {
  1509.                                         ReturnValue = True;
  1510.                                     }
  1511.                             }
  1512.                     }
  1513.             }
  1514.         return ReturnValue;
  1515.     }
  1516.  
  1517.  
  1518. void                                MainWindowEnableGlobalMenus(MainWindowRec* Window)
  1519.     {
  1520.         char*                            StrNumber;
  1521.  
  1522.         CheckPtrExistence(Window);
  1523.         EnableMenuItem(mSaveAs);
  1524.         if (HasDocumentBeenModified(Window) || !Window->EverBeenSaved)
  1525.             {
  1526.                 EnableMenuItem(mSaveFile);
  1527.             }
  1528.         EnableMenuItem(mNewFunction);
  1529.         EnableMenuItem(mNewSample);
  1530.         EnableMenuItem(mNewAlgoSample);
  1531.         EnableMenuItem(mNewWaveTable);
  1532.         EnableMenuItem(mNewAlgoWaveTable);
  1533.         EnableMenuItem(mNewInstrument);
  1534.         EnableMenuItem(mNewTrack);
  1535.         EnableMenuItem(mUnbuildAllFunctions);
  1536.         EnableMenuItem(mBuildEntireProject);
  1537.         EnableMenuItem(mCalculator);
  1538.         EnableMenuItem(mSetTabSize);
  1539.         EnableMenuItem(mPlay);
  1540.  
  1541.         StrNumber = IntegerToString(Window->TabSize);
  1542.         if (StrNumber != NIL)
  1543.             {
  1544.                 char*                            StrKey;
  1545.  
  1546.                 StrKey = StringToBlockCopy("_");
  1547.                 if (StrKey != NIL)
  1548.                     {
  1549.                         char*                            StrValue;
  1550.  
  1551.                         StrValue = StringToBlockCopy("Set Tab Size... (_)");
  1552.                         if (StrValue != NIL)
  1553.                             {
  1554.                                 char*                            StrResult;
  1555.  
  1556.                                 StrResult = ReplaceBlockCopy(StrValue,StrKey,StrNumber);
  1557.                                 if (StrResult != NIL)
  1558.                                     {
  1559.                                         char*                            Temp;
  1560.  
  1561.                                         Temp = BlockToStringCopy(StrResult);
  1562.                                         if (Temp != NIL)
  1563.                                             {
  1564.                                                 ReleasePtr(StrResult);
  1565.                                                 StrResult = Temp;
  1566.                                                 ChangeItemName(mSetTabSize,StrResult);
  1567.                                             }
  1568.                                         ReleasePtr(StrResult);
  1569.                                     }
  1570.                                 ReleasePtr(StrValue);
  1571.                             }
  1572.                         ReleasePtr(StrKey);
  1573.                     }
  1574.                 ReleasePtr(StrNumber);
  1575.             }
  1576.  
  1577.         EnableMenuItem(mImportWAVFormat);
  1578.         EnableMenuItem(mImportRAWFormat);
  1579.         EnableMenuItem(mImportAIFFFormat);
  1580.  
  1581.         WindowMenuEnableItems();
  1582.     }
  1583.  
  1584.  
  1585. /* this checks to see if the menu item is a global menu item.  if it is, the */
  1586. /* associated action is performed and it returns True.  if not, then it returns */
  1587. /* False and the specific editor window must handle the menu item. */
  1588. MyBoolean                        MainWindowDoGlobalMenuItem(MainWindowRec* Window,
  1589.                                             MenuItemType* MenuItem)
  1590.     {
  1591.         CheckPtrExistence(Window);
  1592.         if (MenuItem == mSaveAs)
  1593.             {
  1594.                 SaveDocumentAs(Window);
  1595.             }
  1596.         else if (MenuItem == mSaveFile)
  1597.             {
  1598.                 SaveDocument(Window);
  1599.             }
  1600.         else if (MenuItem == mNewFunction)
  1601.             {
  1602.                 FunctionListNewModule(Window->FunctionList);
  1603.             }
  1604.         else if (MenuItem == mNewSample)
  1605.             {
  1606.                 SampleListNewSample(Window->SampleList);
  1607.             }
  1608.         else if (MenuItem == mNewAlgoSample)
  1609.             {
  1610.                 AlgoSampListNewAlgoSamp(Window->AlgoSampList);
  1611.             }
  1612.         else if (MenuItem == mNewWaveTable)
  1613.             {
  1614.                 WaveTableListNewWaveTable(Window->WaveTableList);
  1615.             }
  1616.         else if (MenuItem == mNewAlgoWaveTable)
  1617.             {
  1618.                 AlgoWaveTableListNewAlgoWaveTable(Window->AlgoWaveTableList);
  1619.             }
  1620.         else if (MenuItem == mNewInstrument)
  1621.             {
  1622.                 InstrListNewInstr(Window->InstrumentList);
  1623.             }
  1624.         else if (MenuItem == mNewTrack)
  1625.             {
  1626.                 TrackListNewTrack(Window->TrackList);
  1627.             }
  1628.         else if (MenuItem == mUnbuildAllFunctions)
  1629.             {
  1630.                 FunctionListUnbuildAll(Window->FunctionList);
  1631.                 AlgoSampListUnbuildAll(Window->AlgoSampList);
  1632.                 AlgoWaveTableListUnbuildAll(Window->AlgoWaveTableList);
  1633.                 InstrListUnbuildAll(Window->InstrumentList);
  1634.             }
  1635.         else if (MenuItem == mBuildEntireProject)
  1636.             {
  1637.                 MainWindowMakeEverythingUpToDate(Window);
  1638.             }
  1639.         else if (MenuItem == mCalculator)
  1640.             {
  1641.                 MainWindowNewCalculator(Window);
  1642.             }
  1643.         else if (MenuItem == mSetTabSize)
  1644.             {
  1645.                 Window->TabSize = DoNumberDialog("Enter new tab size:",Window->TabSize,mCut,
  1646.                     mPaste,mCopy,mUndo,mSelectAll,mClear);
  1647.                 if (Window->TabSize < MINTABCOUNT)
  1648.                     {
  1649.                         Window->TabSize = MINTABCOUNT;
  1650.                     }
  1651.                 if (Window->TabSize > MAXTABCOUNT)
  1652.                     {
  1653.                         Window->TabSize = MAXTABCOUNT;
  1654.                     }
  1655.                 Window->StuffModified = True;
  1656.                 /* we should probably have a dispatch that changes the tab size in */
  1657.                 /* all objects */
  1658.             }
  1659.         else if (MenuItem == mPlay)
  1660.             {
  1661.                 DoPlayPrefsDialog(Window,Window->TrackList);
  1662.             }
  1663.         else if (MenuItem == mImportWAVFormat)
  1664.             {
  1665.                 ImportWAVSample(Window);
  1666.             }
  1667.         else if (MenuItem == mImportRAWFormat)
  1668.             {
  1669.                 ImportRAWSample(Window);
  1670.             }
  1671.         else if (MenuItem == mImportAIFFFormat)
  1672.             {
  1673.                 ImportAIFFSample(Window);
  1674.             }
  1675.         else if (DispatchWindowMenuItem(MenuItem))
  1676.             {
  1677.                 /* no action, but fall through and return True */
  1678.             }
  1679.         else
  1680.             {
  1681.                 return False;
  1682.             }
  1683.         return True;
  1684.     }
  1685.  
  1686.  
  1687. /* get a copy of the left-channel array from a stereo sample.  an error is returned */
  1688. /* indicating the success or failure of this call.  the caller is responsible for */
  1689. /* disposing both the returned array (*DataOut) and the name string */
  1690. SampleErrors                MainWindowGetSampleLeftCopy(void* Window,
  1691.                                             char* NullTerminatedName, largefixedsigned** DataOut)
  1692.     {
  1693.         char*                            NameCopy;
  1694.         SampleErrors            ReturnValue;
  1695.  
  1696.         CheckPtrExistence(Window);
  1697.         NameCopy = StringToBlockCopy(NullTerminatedName);
  1698.         if (NameCopy == NIL)
  1699.             {
  1700.                 return eEvalSampleNotEnoughMemoryToCopy;
  1701.             }
  1702.         ReturnValue = SampleListGetSampleLeftFixed(((MainWindowRec*)Window)->SampleList,
  1703.             NameCopy,DataOut);
  1704.         ReleasePtr(NameCopy);
  1705.         return ReturnValue;
  1706.     }
  1707.  
  1708.  
  1709. /* get a copy of the right-channel array from a stereo sample.  an error is returned */
  1710. /* indicating the success or failure of this call.  the caller is responsible for */
  1711. /* disposing both the returned array (*DataOut) and the name string */
  1712. SampleErrors                MainWindowGetSampleRightCopy(void* Window,
  1713.                                             char* NullTerminatedName, largefixedsigned** DataOut)
  1714.     {
  1715.         char*                            NameCopy;
  1716.         SampleErrors            ReturnValue;
  1717.  
  1718.         CheckPtrExistence(Window);
  1719.         NameCopy = StringToBlockCopy(NullTerminatedName);
  1720.         if (NameCopy == NIL)
  1721.             {
  1722.                 return eEvalSampleNotEnoughMemoryToCopy;
  1723.             }
  1724.         ReturnValue = SampleListGetSampleRightFixed(((MainWindowRec*)Window)->SampleList,
  1725.             NameCopy,DataOut);
  1726.         ReleasePtr(NameCopy);
  1727.         return ReturnValue;
  1728.     }
  1729.  
  1730.  
  1731. /* get a copy of the sample array from a mono sample.  an error is returned */
  1732. /* indicating the success or failure of this call.  the caller is responsible for */
  1733. /* disposing both the returned array (*DataOut) and the name string */
  1734. SampleErrors                MainWindowGetSampleMonoCopy(void* Window,
  1735.                                             char* NullTerminatedName, largefixedsigned** DataOut)
  1736.     {
  1737.         char*                            NameCopy;
  1738.         SampleErrors            ReturnValue;
  1739.  
  1740.         CheckPtrExistence(Window);
  1741.         NameCopy = StringToBlockCopy(NullTerminatedName);
  1742.         if (NameCopy == NIL)
  1743.             {
  1744.                 return eEvalSampleNotEnoughMemoryToCopy;
  1745.             }
  1746.         ReturnValue = SampleListGetSampleMonoFixed(((MainWindowRec*)Window)->SampleList,
  1747.             NameCopy,DataOut);
  1748.         ReleasePtr(NameCopy);
  1749.         return ReturnValue;
  1750.     }
  1751.  
  1752.  
  1753. /* get the number of frames per wave period for the specified wave table.  an error */
  1754. /* code is returned indicating success or failure.  the caller is responsible for */
  1755. /* disposing of the name string. */
  1756. SampleErrors                MainWindowGetWaveTableFrameCount(void* Window,
  1757.                                             char* NullTerminatedName, long* FrameCountOut)
  1758.     {
  1759.         char*                            NameCopy;
  1760.         SampleErrors            ReturnValue;
  1761.  
  1762.         CheckPtrExistence(Window);
  1763.         NameCopy = StringToBlockCopy(NullTerminatedName);
  1764.         if (NameCopy == NIL)
  1765.             {
  1766.                 return eEvalSampleNotEnoughMemoryToCopy;
  1767.             }
  1768.         ReturnValue = WaveTableListGetWaveTableFrameCount(
  1769.             ((MainWindowRec*)Window)->WaveTableList,NameCopy,FrameCountOut);
  1770.         ReleasePtr(NameCopy);
  1771.         return ReturnValue;
  1772.     }
  1773.  
  1774.  
  1775. /* get the number of tables in the specified wave table.  an error */
  1776. /* code is returned indicating success or failure.  the caller is responsible for */
  1777. /* disposing of the name string. */
  1778. SampleErrors                MainWindowGetWaveTableTableCount(void* Window,
  1779.                                             char* NullTerminatedName, long* TableCountOut)
  1780.     {
  1781.         char*                            NameCopy;
  1782.         SampleErrors            ReturnValue;
  1783.  
  1784.         CheckPtrExistence(Window);
  1785.         NameCopy = StringToBlockCopy(NullTerminatedName);
  1786.         if (NameCopy == NIL)
  1787.             {
  1788.                 return eEvalSampleNotEnoughMemoryToCopy;
  1789.             }
  1790.         ReturnValue = WaveTableListGetWaveTableTableCount(
  1791.             ((MainWindowRec*)Window)->WaveTableList,NameCopy,TableCountOut);
  1792.         ReleasePtr(NameCopy);
  1793.         return ReturnValue;
  1794.     }
  1795.  
  1796.  
  1797. /* get a copy of the sample array from a wave table.  an error is returned */
  1798. /* indicating the success or failure of this call.  the caller is responsible for */
  1799. /* disposing both the returned array (*DataOut) and the name string */
  1800. SampleErrors                MainWindowGetWaveTableArray(void* Window,
  1801.                                             char* NullTerminatedName, largefixedsigned** DataOut)
  1802.     {
  1803.         char*                            NameCopy;
  1804.         SampleErrors            ReturnValue;
  1805.  
  1806.         CheckPtrExistence(Window);
  1807.         NameCopy = StringToBlockCopy(NullTerminatedName);
  1808.         if (NameCopy == NIL)
  1809.             {
  1810.                 return eEvalSampleNotEnoughMemoryToCopy;
  1811.             }
  1812.         ReturnValue = WaveTableListGetWaveTableArray(
  1813.             ((MainWindowRec*)Window)->WaveTableList,NameCopy,DataOut);
  1814.         ReleasePtr(NameCopy);
  1815.         return ReturnValue;
  1816.     }
  1817.  
  1818.  
  1819. /* open a new sample editor initialized with the parameters and install the data */
  1820. /* in the array RawData into it.  this array is NOT largefixedsigned, but rather is */
  1821. /* signed char or signed short, depending on the setting of NumBits.  the caller */
  1822. /* is responsible for disposing of RawData. */
  1823. struct SampleObjectRec*    MainWindowCopyRawSampleAndOpen(MainWindowRec* Window,
  1824.                                             char* RawData, NumBitsType NumBits, NumChannelsType NumChannels,
  1825.                                             long Origin, long LoopStart1, long LoopStart2, long LoopStart3,
  1826.                                             long LoopEnd1, long LoopEnd2, long LoopEnd3, long SamplingRate,
  1827.                                             double NaturalFrequency)
  1828.     {
  1829.         CheckPtrExistence(Window);
  1830.         if (RawData != NIL)
  1831.             {
  1832.                 CheckPtrExistence(RawData);
  1833.                 return SampleListCopyRawSampleAndOpen(Window->SampleList,RawData,NumBits,
  1834.                     NumChannels,Origin,LoopStart1,LoopStart2,LoopStart3,LoopEnd1,LoopEnd2,
  1835.                     LoopEnd3,SamplingRate,NaturalFrequency);
  1836.             }
  1837.          else
  1838.             {
  1839.                 return NIL;
  1840.             }
  1841.     }
  1842.  
  1843.  
  1844. /* open a new wave table editor initialized with the parameters and install the data */
  1845. /* in the array RawData into it.  this array is not largefixedsigned, but rather is */
  1846. /* signed char or signed short, depending on the setting of NumBits.  the caller */
  1847. /* is responsible for disposing of RawData. */
  1848. struct WaveTableObjectRec*    MainWindowCopyRawWaveTableAndOpen(MainWindowRec* Window,
  1849.                                             char* RawData, NumBitsType NumBits, long NumTables,
  1850.                                             long FramesPerTable)
  1851.     {
  1852.         CheckPtrExistence(Window);
  1853.         if (RawData != NIL)
  1854.             {
  1855.                 CheckPtrExistence(RawData);
  1856.                 return WaveTableListCopyRawWaveTableAndOpen(Window->WaveTableList,RawData,
  1857.                     NumBits,NumTables,FramesPerTable);
  1858.             }
  1859.          else
  1860.             {
  1861.                 return NIL;
  1862.             }
  1863.     }
  1864.  
  1865.  
  1866. /* get a copy of the name of the current document file.  the name is a heap-allocated */
  1867. /* non-null-terminated block. */
  1868. char*                                GetCopyOfDocumentName(MainWindowRec* Window)
  1869.     {
  1870.         char*                            Filename;
  1871.  
  1872.         if (Window->EverBeenSaved)
  1873.             {
  1874.                 Filename = ExtractFileName(Window->TheFileLocation);
  1875.             }
  1876.          else
  1877.             {
  1878.                 Filename = StringToBlockCopy("Untitled");
  1879.             }
  1880.         if (Filename != NIL)
  1881.             {
  1882.                 SetTag(Filename,"GetCopyOfDocumentName");
  1883.             }
  1884.         return Filename;
  1885.     }
  1886.  
  1887.  
  1888. /* dispatch a name change event.  this tells all editors that the document title */
  1889. /* has changed, and the window titles should be updated accordingly. */
  1890. void                                MainWindowDispatchNameChange(MainWindowRec* Window)
  1891.     {
  1892.         char*                            Filename;
  1893.  
  1894.         CheckPtrExistence(Window);
  1895.         Filename = GetCopyOfDocumentName(Window);
  1896.         if (Filename != NIL)
  1897.             {
  1898.                 char*                            FilenameNullTerminated;
  1899.  
  1900.                 SampleListGlobalNameChange(Window->SampleList,Filename);
  1901.                 FunctionListGlobalNameChange(Window->FunctionList,Filename);
  1902.                 AlgoSampListGlobalNameChange(Window->AlgoSampList,Filename);
  1903.                 WaveTableListGlobalNameChange(Window->WaveTableList,Filename);
  1904.                 AlgoWaveTableListGlobalNameChange(Window->AlgoWaveTableList,Filename);
  1905.                 InstrListGlobalNameChange(Window->InstrumentList,Filename);
  1906.                 TrackListGlobalNameChange(Window->TrackList,Filename);
  1907.                 FilenameNullTerminated = BlockToStringCopy(Filename);
  1908.                 if (FilenameNullTerminated != NIL)
  1909.                     {
  1910.                         SetWindowName(Window->ScreenID,FilenameNullTerminated);
  1911.                         ChangeItemName(Window->MyMenuItem,FilenameNullTerminated);
  1912.                         ReleasePtr(FilenameNullTerminated);
  1913.                     }
  1914.                 ReleasePtr(Filename);
  1915.             }
  1916.     }
  1917.  
  1918.  
  1919. MyBoolean                        MainWindowGetStereo(MainWindowRec* Window)
  1920.     {
  1921.         CheckPtrExistence(Window);
  1922.         return Window->StereoPlayback;
  1923.     }
  1924.  
  1925.  
  1926. MyBoolean                        MainWindowGetSurround(MainWindowRec* Window)
  1927.     {
  1928.         CheckPtrExistence(Window);
  1929.         return Window->SurroundEncoding;
  1930.     }
  1931.  
  1932.  
  1933. long                                MainWindowGetSamplingRate(MainWindowRec* Window)
  1934.     {
  1935.         CheckPtrExistence(Window);
  1936.         return Window->SamplingRate;
  1937.     }
  1938.  
  1939.  
  1940. long                                MainWindowGetEnvelopeRate(MainWindowRec* Window)
  1941.     {
  1942.         CheckPtrExistence(Window);
  1943.         return Window->EnvelopeUpdateRate;
  1944.     }
  1945.  
  1946.  
  1947. double                            MainWindowGetBeatsPerMinute(MainWindowRec* Window)
  1948.     {
  1949.         CheckPtrExistence(Window);
  1950.         return LargeBCD2Double(Window->DefaultBeatsPerMinute);
  1951.     }
  1952.  
  1953.  
  1954. double                            MainWindowGetVolumeScaling(MainWindowRec* Window)
  1955.     {
  1956.         CheckPtrExistence(Window);
  1957.         return LargeBCD2Double(Window->OverallVolumeScalingFactor);
  1958.     }
  1959.  
  1960.  
  1961. OutputNumBitsType        MainWindowGetOutputNumBits(MainWindowRec* Window)
  1962.     {
  1963.         CheckPtrExistence(Window);
  1964.         return Window->OutputNumBits;
  1965.     }
  1966.  
  1967.  
  1968. MyBoolean                        MainWindowGetInterpolationOverTime(MainWindowRec* Window)
  1969.     {
  1970.         CheckPtrExistence(Window);
  1971.         return Window->InterpolateOverTime;
  1972.     }
  1973.  
  1974.  
  1975. MyBoolean                        MainWindowGetInterpolationAcrossWaves(MainWindowRec* Window)
  1976.     {
  1977.         CheckPtrExistence(Window);
  1978.         return Window->InterpolateAcrossWaves;
  1979.     }
  1980.  
  1981.  
  1982. double                            MainWindowGetScanningGap(MainWindowRec* Window)
  1983.     {
  1984.         CheckPtrExistence(Window);
  1985.         return LargeBCD2Double(Window->ScanningGap);
  1986.     }
  1987.  
  1988.  
  1989. double                            MainWindowGetBufferDuration(MainWindowRec* Window)
  1990.     {
  1991.         CheckPtrExistence(Window);
  1992.         return LargeBCD2Double(Window->BufferDuration);
  1993.     }
  1994.  
  1995.  
  1996. MyBoolean                        MainWindowGetClipWarning(MainWindowRec* Window)
  1997.     {
  1998.         CheckPtrExistence(Window);
  1999.         return Window->ClipWarning;
  2000.     }
  2001.  
  2002.  
  2003. char*                                MainWindowGetPostProcessing(MainWindowRec* Window)
  2004.     {
  2005.         char*                            StringTemp;
  2006.  
  2007.         CheckPtrExistence(Window);
  2008.         StringTemp = CopyPtr(Window->SongPostProcessing);
  2009.         if (StringTemp != NIL)
  2010.             {
  2011.                 SetTag(StringTemp,"SongPostProcessing");
  2012.             }
  2013.         return StringTemp;
  2014.     }
  2015.  
  2016.  
  2017. MyBoolean                        MainWindowGetPostProcessingEnable(MainWindowRec* Window)
  2018.     {
  2019.         CheckPtrExistence(Window);
  2020.         return Window->SongPostProcessingEnable;
  2021.     }
  2022.  
  2023.  
  2024. void                                PutMainWindowStereo(MainWindowRec* Window, MyBoolean NewStereoFlag)
  2025.     {
  2026.         CheckPtrExistence(Window);
  2027.         if (Window->StereoPlayback != NewStereoFlag)
  2028.             {
  2029.                 Window->StereoPlayback = NewStereoFlag;
  2030.                 Window->StuffModified = True;
  2031.             }
  2032.     }
  2033.  
  2034.  
  2035. void                                PutMainWindowSurround(MainWindowRec* Window, MyBoolean NewSurround)
  2036.     {
  2037.         CheckPtrExistence(Window);
  2038.         if (Window->SurroundEncoding != NewSurround)
  2039.             {
  2040.                 Window->SurroundEncoding = NewSurround;
  2041.                 Window->StuffModified = True;
  2042.             }
  2043.     }
  2044.  
  2045.  
  2046. void                                PutMainWindowSamplingRate(MainWindowRec* Window,
  2047.                                             long NewSamplingRate)
  2048.     {
  2049.         CheckPtrExistence(Window);
  2050.         if (NewSamplingRate < MINSAMPLINGRATE)
  2051.             {
  2052.                 NewSamplingRate = MINSAMPLINGRATE;
  2053.             }
  2054.         if (NewSamplingRate > MAXSAMPLINGRATE)
  2055.             {
  2056.                 NewSamplingRate = MAXSAMPLINGRATE;
  2057.             }
  2058.         if (Window->SamplingRate != NewSamplingRate)
  2059.             {
  2060.                 Window->SamplingRate = NewSamplingRate;
  2061.                 Window->StuffModified = True;
  2062.             }
  2063.     }
  2064.  
  2065.  
  2066. void                                PutMainWindowEnvelopeRate(MainWindowRec* Window,
  2067.                                             long NewEnvelopeRate)
  2068.     {
  2069.         CheckPtrExistence(Window);
  2070.         if (NewEnvelopeRate < 1)
  2071.             {
  2072.                 NewEnvelopeRate = 1;
  2073.             }
  2074.         if (NewEnvelopeRate > MAXSAMPLINGRATE)
  2075.             {
  2076.                 NewEnvelopeRate = MAXSAMPLINGRATE;
  2077.             }
  2078.         if (Window->EnvelopeUpdateRate != NewEnvelopeRate)
  2079.             {
  2080.                 Window->EnvelopeUpdateRate = NewEnvelopeRate;
  2081.                 Window->StuffModified = True;
  2082.             }
  2083.     }
  2084.  
  2085.  
  2086. void                                PutMainWindowBeatsPerMinute(MainWindowRec* Window,
  2087.                                             double NewBeatsPerMinute)
  2088.     {
  2089.         LargeBCDType            BPM;
  2090.  
  2091.         CheckPtrExistence(Window);
  2092.         BPM = Double2LargeBCD(NewBeatsPerMinute);
  2093.         if (Window->DefaultBeatsPerMinute != BPM)
  2094.             {
  2095.                 Window->DefaultBeatsPerMinute = BPM;
  2096.                 Window->StuffModified = True;
  2097.             }
  2098.     }
  2099.  
  2100.  
  2101. void                                PutMainWindowVolumeScaling(MainWindowRec* Window,
  2102.                                             double NewVolumeScaling)
  2103.     {
  2104.         LargeBCDType            Vol;
  2105.  
  2106.         CheckPtrExistence(Window);
  2107.         Vol = Double2LargeBCD(NewVolumeScaling);
  2108.         if (Window->OverallVolumeScalingFactor != Vol)
  2109.             {
  2110.                 Window->OverallVolumeScalingFactor = Vol;
  2111.                 Window->StuffModified = True;
  2112.             }
  2113.     }
  2114.  
  2115.  
  2116. void                                PutMainWindowOutputNumBits(MainWindowRec* Window,
  2117.                                             OutputNumBitsType NewOutputNumBits)
  2118.     {
  2119.         CheckPtrExistence(Window);
  2120.         ERROR((NewOutputNumBits != eOutput8Bits) && (NewOutputNumBits != eOutput16Bits)
  2121.             && (NewOutputNumBits != eOutput24Bits) && (NewOutputNumBits != eOutput32Bits),
  2122.             PRERR(ForceAbort,"PutMainWindowOutputNumBits:  bad value"));
  2123.         if (Window->OutputNumBits != NewOutputNumBits)
  2124.             {
  2125.                 Window->OutputNumBits = NewOutputNumBits;
  2126.                 Window->StuffModified = True;
  2127.             }
  2128.     }
  2129.  
  2130.  
  2131. void                                PutMainWindowInterpolationOverTime(MainWindowRec* Window,
  2132.                                             MyBoolean NewInterpOverTime)
  2133.     {
  2134.         CheckPtrExistence(Window);
  2135.         if (Window->InterpolateOverTime != NewInterpOverTime)
  2136.             {
  2137.                 Window->InterpolateOverTime = NewInterpOverTime;
  2138.                 Window->StuffModified = True;
  2139.             }
  2140.     }
  2141.  
  2142.  
  2143. void                                PutMainWindowInterpolationAcrossWaves(MainWindowRec* Window,
  2144.                                             MyBoolean NewInterpAcrossWaves)
  2145.     {
  2146.         CheckPtrExistence(Window);
  2147.         if (Window->InterpolateAcrossWaves != NewInterpAcrossWaves)
  2148.             {
  2149.                 Window->InterpolateAcrossWaves = NewInterpAcrossWaves;
  2150.                 Window->StuffModified = True;
  2151.             }
  2152.     }
  2153.  
  2154.  
  2155. void                                PutMainWindowScanningGap(MainWindowRec* Window, double NewScanningGap)
  2156.     {
  2157.         LargeBCDType            Gap;
  2158.  
  2159.         CheckPtrExistence(Window);
  2160.         Gap = Double2LargeBCD(NewScanningGap);
  2161.         if (Gap != Window->ScanningGap)
  2162.             {
  2163.                 Window->ScanningGap = Gap;
  2164.                 Window->StuffModified = True;
  2165.             }
  2166.     }
  2167.  
  2168.  
  2169. void                                PutMainWindowBufferDuration(MainWindowRec* Window,
  2170.                                             double NewBufferDuration)
  2171.     {
  2172.         LargeBCDType            Buffering;
  2173.  
  2174.         CheckPtrExistence(Window);
  2175.         Buffering = Double2LargeBCD(NewBufferDuration);
  2176.         if (Buffering != Window->BufferDuration)
  2177.             {
  2178.                 Window->BufferDuration = Buffering;
  2179.                 Window->StuffModified = True;
  2180.             }
  2181.     }
  2182.  
  2183.  
  2184. void                                PutMainWindowClipWarning(MainWindowRec* Window,
  2185.                                             MyBoolean NewClipWarning)
  2186.     {
  2187.         CheckPtrExistence(Window);
  2188.         if (NewClipWarning != Window->ClipWarning)
  2189.             {
  2190.                 Window->ClipWarning = NewClipWarning;
  2191.                 Window->StuffModified = True;
  2192.             }
  2193.     }
  2194.  
  2195.  
  2196. void                                PutMainWindowPostProcessing(MainWindowRec* Window,
  2197.                                             char* NewPostProcessing)
  2198.     {
  2199.         CheckPtrExistence(Window);
  2200.         CheckPtrExistence(NewPostProcessing);
  2201.         ReleasePtr(Window->SongPostProcessing);
  2202.         Window->SongPostProcessing = NewPostProcessing;
  2203.         Window->StuffModified = True;
  2204.     }
  2205.  
  2206.  
  2207. void                                PutMainWindowPostProcessingEnable(MainWindowRec* Window,
  2208.                                             MyBoolean NewPostProcessingEnable)
  2209.     {
  2210.         CheckPtrExistence(Window);
  2211.         if (Window->SongPostProcessingEnable != NewPostProcessingEnable)
  2212.             {
  2213.                 Window->SongPostProcessingEnable = NewPostProcessingEnable;
  2214.                 Window->StuffModified = True;
  2215.             }
  2216.     }
  2217.  
  2218.  
  2219. /* General Information Subblock Structure: */
  2220. /*   4-byte file format version code */
  2221. /*       "Syn1" - first file format */
  2222. /*   1-byte unsigned tab size code */
  2223. /*       should be in the range of 1..255 */
  2224. /*   4-byte little endian comment text length (positive 2s complement, in bytes) */
  2225. /*   n-byte character data for comment text (line feed = 0x0a) */
  2226. /*   1-byte stereo playback flag */
  2227. /*       0 = mono */
  2228. /*       1 = stereo */
  2229. /*   1-byte surround encoding flag */
  2230. /*       0 = no surround encoding */
  2231. /*       1 = generic surround encoding */
  2232. /*   4-byte little endian output sampling rate */
  2233. /*       should be in the range of 100..65535 */
  2234. /*   4-byte little endian envelope update rate */
  2235. /*       should be in the range of 1..65535 */
  2236. /*   4-byte little endian large integer coded decimal beats per minute */
  2237. /*       large integer coded decimal is decimal * 1000000 with a */
  2238. /*       range of -1999.999999 to 1999.999999 */
  2239. /*   4-byte little endian large integer coded decimal total volume scaling factor */
  2240. /*   1-byte number of bits to output */
  2241. /*       should be 8, 16, 24, or 32 */
  2242. /*   1-byte flag for interpolation over time */
  2243. /*       0 = don't interpolate over time */
  2244. /*       1 = do interpolate over time (when resampling waveforms) */
  2245. /*   1-byte flag for interpolation across waves */
  2246. /*       0 = don't interpolate across waves */
  2247. /*       1 = do interpolate across waves (when wave table synthesis index is */
  2248. /*           not an integer) */
  2249. /*   4-byte little endian large integer coded decimal scanning gap */
  2250. /*   4-byte little endian large integer coded decimal buffer duration (in seconds) */
  2251. /*   1-byte flag for clipping warning */
  2252. /*       0 = don't warn about clipped samples */
  2253. /*       1 = do warn about clipped samples */
  2254. /*   1-byte flag for song post processing enabling */
  2255. /*       0 = don't do song postprocessing */
  2256. /*       1 = do song postprocessing */
  2257. /*   4-byte little endian length of song post processing function */
  2258. /*   n-bytes of post processing function text (line fed = 0x0a) */
  2259.  
  2260.  
  2261. /* read the general information subblock from the specified file. */
  2262. FileLoadingErrors        MainWindowReadData(MainWindowRec* Window,
  2263.                                             struct BufferedInputRec* Input)
  2264.     {
  2265.         char                            FileFormatVersion[4];
  2266.         signed long                BlockLength;
  2267.         char*                            StringTemp;
  2268.         unsigned char            BuffChar;
  2269.         signed long                SignedLong;
  2270.  
  2271.         CheckPtrExistence(Window);
  2272.         CheckPtrExistence(Input);
  2273.  
  2274.         /*   4-byte file format version code */
  2275.         /*       "Syn1" - first file format */
  2276.         if (!ReadBufferedInput(Input,4,FileFormatVersion))
  2277.             {
  2278.                 return eFileLoadDiskError;
  2279.             }
  2280.         if (!MemEqu(FileFormatVersion,"Syn1",4))
  2281.             {
  2282.                 return eFileLoadBadFormat;
  2283.             }
  2284.  
  2285.         /*   1-byte unsigned tab size code */
  2286.         /*       should be in the range of 1..255 */
  2287.         if (!ReadBufferedUnsignedChar(Input,&BuffChar))
  2288.             {
  2289.                 return eFileLoadDiskError;
  2290.             }
  2291.         if (BuffChar < MINTABCOUNT)
  2292.             {
  2293.                 BuffChar = MINTABCOUNT;
  2294.             }
  2295.         if (BuffChar > MAXTABCOUNT)
  2296.             {
  2297.                 BuffChar = MAXTABCOUNT;
  2298.             }
  2299.         Window->TabSize = BuffChar;
  2300.  
  2301.         /*   4-byte little endian comment text length (in bytes) */
  2302.         if (!ReadBufferedSignedLongLittleEndian(Input,&BlockLength))
  2303.             {
  2304.                 return eFileLoadDiskError;
  2305.             }
  2306.         if (BlockLength < 0)
  2307.             {
  2308.                 return eFileLoadBadFormat;
  2309.             }
  2310.         StringTemp = AllocPtrCanFail(BlockLength,"MainWindowReadData:  comment string temp");
  2311.         if (StringTemp == NIL)
  2312.             {
  2313.                 return eFileLoadOutOfMemory;
  2314.             }
  2315.         /*   n-byte character data for comment text (line feed = 0x0a) */
  2316.         if (!ReadBufferedInput(Input,BlockLength,StringTemp))
  2317.             {
  2318.                 ReleasePtr(StringTemp);
  2319.                 return eFileLoadDiskError;
  2320.             }
  2321.         if (!TextEditNewRawData(Window->CommentInfo,StringTemp,"\x0a"))
  2322.             {
  2323.                 ReleasePtr(StringTemp);
  2324.                 return eFileLoadOutOfMemory;
  2325.             }
  2326.         TextEditHasBeenSaved(Window->CommentInfo);
  2327.         ReleasePtr(StringTemp);
  2328.  
  2329.         /*   1-byte stereo playback flag */
  2330.         /*       0 = mono */
  2331.         /*       1 = stereo */
  2332.         if (!ReadBufferedUnsignedChar(Input,&BuffChar))
  2333.             {
  2334.                 return eFileLoadDiskError;
  2335.             }
  2336.         if (BuffChar == 0)
  2337.             {
  2338.                 Window->StereoPlayback = False;
  2339.             }
  2340.         else if (BuffChar == 1)
  2341.             {
  2342.                 Window->StereoPlayback = True;
  2343.             }
  2344.         else
  2345.             {
  2346.                 return eFileLoadBadFormat;
  2347.             }
  2348.  
  2349.         /*   1-byte surround encoding flag */
  2350.         /*       0 = no surround encoding */
  2351.         /*       1 = dolby surround encoding */
  2352.         if (!ReadBufferedUnsignedChar(Input,&BuffChar))
  2353.             {
  2354.                 return eFileLoadDiskError;
  2355.             }
  2356.         if (BuffChar == 0)
  2357.             {
  2358.                 Window->SurroundEncoding = False;
  2359.             }
  2360.         else if (BuffChar == 1)
  2361.             {
  2362.                 Window->SurroundEncoding = True;
  2363.             }
  2364.         else
  2365.             {
  2366.                 return eFileLoadBadFormat;
  2367.             }
  2368.  
  2369.         /*   4-byte little endian output sampling rate */
  2370.         /*       should be in the range of 100..65535 */
  2371.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  2372.             {
  2373.                 return eFileLoadDiskError;
  2374.             }
  2375.         if (SignedLong < MINSAMPLINGRATE)
  2376.             {
  2377.                 SignedLong = MINSAMPLINGRATE;
  2378.             }
  2379.         if (SignedLong > MAXSAMPLINGRATE)
  2380.             {
  2381.                 SignedLong = MAXSAMPLINGRATE;
  2382.             }
  2383.         Window->SamplingRate = SignedLong;
  2384.  
  2385.         /*   4-byte little endian envelope update rate */
  2386.         /*       should be in the range of 1..65535 */
  2387.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  2388.             {
  2389.                 return eFileLoadDiskError;
  2390.             }
  2391.         if (SignedLong < 1)
  2392.             {
  2393.                 SignedLong = 1;
  2394.             }
  2395.         if (SignedLong > MAXSAMPLINGRATE)
  2396.             {
  2397.                 SignedLong = MAXSAMPLINGRATE;
  2398.             }
  2399.         Window->EnvelopeUpdateRate = SignedLong;
  2400.  
  2401.         /*   4-byte little endian large integer coded decimal beats per minute */
  2402.         /*       large integer coded decimal is decimal * 1000000 with a */
  2403.         /*       range of -1999.999999 to 1999.999999 */
  2404.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  2405.             {
  2406.                 return eFileLoadDiskError;
  2407.             }
  2408.         Window->DefaultBeatsPerMinute = SignedLong;
  2409.  
  2410.         /*   4-byte little endian large integer coded total volume scaling factor */
  2411.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  2412.             {
  2413.                 return eFileLoadDiskError;
  2414.             }
  2415.         Window->OverallVolumeScalingFactor = SignedLong;
  2416.  
  2417.         /*   1-byte number of bits to output */
  2418.         /*       should be 8, 16, 24, or 32 */
  2419.         if (!ReadBufferedUnsignedChar(Input,&BuffChar))
  2420.             {
  2421.                 return eFileLoadDiskError;
  2422.             }
  2423.         if (BuffChar == 8)
  2424.             {
  2425.                 Window->OutputNumBits = eOutput8Bits;
  2426.             }
  2427.         else if (BuffChar == 16)
  2428.             {
  2429.                 Window->OutputNumBits = eOutput16Bits;
  2430.             }
  2431.         else if (BuffChar == 24)
  2432.             {
  2433.                 Window->OutputNumBits = eOutput24Bits;
  2434.             }
  2435.         else if (BuffChar == 32)
  2436.             {
  2437.                 Window->OutputNumBits = eOutput32Bits;
  2438.             }
  2439.         else
  2440.             {
  2441.                 return eFileLoadBadFormat;
  2442.             }
  2443.  
  2444.         /*   1-byte flag for interpolation over time */
  2445.         /*       0 = don't interpolate over time */
  2446.         /*       1 = do interpolate over time (when resampling waveforms) */
  2447.         if (!ReadBufferedUnsignedChar(Input,&BuffChar))
  2448.             {
  2449.                 return eFileLoadDiskError;
  2450.             }
  2451.         if (BuffChar == 0)
  2452.             {
  2453.                 Window->InterpolateOverTime = False;
  2454.             }
  2455.         else if (BuffChar == 1)
  2456.             {
  2457.                 Window->InterpolateOverTime = True;
  2458.             }
  2459.         else
  2460.             {
  2461.                 return eFileLoadBadFormat;
  2462.             }
  2463.  
  2464.         /*   1-byte flag for interpolation across waves */
  2465.         /*       0 = don't interpolate across waves */
  2466.         /*       1 = do interpolate across waves (when wave table synthesis index is */
  2467.         /*           not an integer) */
  2468.         if (!ReadBufferedUnsignedChar(Input,&BuffChar))
  2469.             {
  2470.                 return eFileLoadDiskError;
  2471.             }
  2472.         if (BuffChar == 0)
  2473.             {
  2474.                 Window->InterpolateAcrossWaves = False;
  2475.             }
  2476.         else if (BuffChar == 1)
  2477.             {
  2478.                 Window->InterpolateAcrossWaves = True;
  2479.             }
  2480.         else
  2481.             {
  2482.                 return eFileLoadBadFormat;
  2483.             }
  2484.  
  2485.         /*   4-byte little endian large integer coded decimal scanning gap */
  2486.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  2487.             {
  2488.                 return eFileLoadDiskError;
  2489.             }
  2490.         Window->ScanningGap = SignedLong;
  2491.  
  2492.         /*   4-byte little endian large integer coded decimal buffer duration (in seconds) */
  2493.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  2494.             {
  2495.                 return eFileLoadDiskError;
  2496.             }
  2497.         Window->BufferDuration = SignedLong;
  2498.  
  2499.         /*   1-byte flag for clipping warning */
  2500.         /*       0 = don't warn about clipped samples */
  2501.         /*       1 = do warn about clipped samples */
  2502.         if (!ReadBufferedUnsignedChar(Input,&BuffChar))
  2503.             {
  2504.                 return eFileLoadDiskError;
  2505.             }
  2506.         if (BuffChar == 0)
  2507.             {
  2508.                 Window->ClipWarning = False;
  2509.             }
  2510.         else if (BuffChar == 1)
  2511.             {
  2512.                 Window->ClipWarning = True;
  2513.             }
  2514.         else
  2515.             {
  2516.                 return eFileLoadBadFormat;
  2517.             }
  2518.  
  2519.         /*   1-byte flag for song post processing enabling */
  2520.         /*       0 = don't do song postprocessing */
  2521.         /*       1 = do song postprocessing */
  2522.         if (!ReadBufferedUnsignedChar(Input,&BuffChar))
  2523.             {
  2524.                 return eFileLoadDiskError;
  2525.             }
  2526.         if (BuffChar == 0)
  2527.             {
  2528.                 Window->SongPostProcessingEnable = False;
  2529.             }
  2530.         else if (BuffChar == 1)
  2531.             {
  2532.                 Window->SongPostProcessingEnable = True;
  2533.             }
  2534.         else
  2535.             {
  2536.                 return eFileLoadBadFormat;
  2537.             }
  2538.  
  2539.         /*   4-byte little endian length of song post processing function */
  2540.         if (!ReadBufferedSignedLongLittleEndian(Input,&SignedLong))
  2541.             {
  2542.                 return eFileLoadDiskError;
  2543.             }
  2544.         if (SignedLong < 0)
  2545.             {
  2546.                 return eFileLoadBadFormat;
  2547.             }
  2548.  
  2549.         /*   n-bytes of post processing function text (line fed = 0x0a) */
  2550.         StringTemp = AllocPtrCanFail(SignedLong,"SongPostProcessing");
  2551.         if (StringTemp == NIL)
  2552.             {
  2553.                 return eFileLoadOutOfMemory;
  2554.             }
  2555.         if (!ReadBufferedInput(Input,SignedLong,StringTemp))
  2556.             {
  2557.                 ReleasePtr(StringTemp);
  2558.                 return eFileLoadDiskError;
  2559.             }
  2560.         ReleasePtr(Window->SongPostProcessing);
  2561.         Window->SongPostProcessing = StringTemp;
  2562.  
  2563.         return eFileLoadNoError;
  2564.     }
  2565.  
  2566.  
  2567. /* write the general information subblock to the specified file. */
  2568. FileLoadingErrors        MainWindowWriteData(MainWindowRec* Window,
  2569.                                             struct BufferedOutputRec* Output)
  2570.     {
  2571.         char*                            StringTemp;
  2572.  
  2573.         CheckPtrExistence(Window);
  2574.         CheckPtrExistence(Output);
  2575.  
  2576.         /*   4-byte file format version code */
  2577.         /*       "Syn1" - first file format */
  2578.         if (!WriteBufferedOutput(Output,4,"Syn1"))
  2579.             {
  2580.                 return eFileLoadDiskError;
  2581.             }
  2582.  
  2583.         /*   1-byte unsigned tab size code */
  2584.         /*       should be in the range of 1..255 */
  2585.         if (!WriteBufferedUnsignedChar(Output,Window->TabSize))
  2586.             {
  2587.                 return eFileLoadDiskError;
  2588.             }
  2589.  
  2590.         /*   4-byte little endian comment text length (in bytes) */
  2591.         StringTemp = TextEditGetRawData(Window->CommentInfo,"\x0a");
  2592.         if (StringTemp == NIL)
  2593.             {
  2594.                 return eFileLoadOutOfMemory;
  2595.             }
  2596.         if (!WriteBufferedSignedLongLittleEndian(Output,PtrSize(StringTemp)))
  2597.             {
  2598.                 ReleasePtr(StringTemp);
  2599.                 return eFileLoadDiskError;
  2600.             }
  2601.         /*   n-byte character data for comment text (line feed = 0x0a) */
  2602.         if (!WriteBufferedOutput(Output,PtrSize(StringTemp),StringTemp))
  2603.             {
  2604.                 ReleasePtr(StringTemp);
  2605.                 return eFileLoadDiskError;
  2606.             }
  2607.         ReleasePtr(StringTemp);
  2608.  
  2609.         /*   1-byte stereo playback flag */
  2610.         /*       0 = mono */
  2611.         /*       1 = stereo */
  2612.         if (Window->StereoPlayback)
  2613.             {
  2614.                 if (!WriteBufferedUnsignedChar(Output,1))
  2615.                     {
  2616.                         return eFileLoadDiskError;
  2617.                     }
  2618.             }
  2619.          else
  2620.             {
  2621.                 if (!WriteBufferedUnsignedChar(Output,0))
  2622.                     {
  2623.                         return eFileLoadDiskError;
  2624.                     }
  2625.             }
  2626.  
  2627.         /*   1-byte surround encoding flag */
  2628.         /*       0 = no surround encoding */
  2629.         /*       1 = dolby surround encoding */
  2630.         if (Window->SurroundEncoding)
  2631.             {
  2632.                 if (!WriteBufferedUnsignedChar(Output,1))
  2633.                     {
  2634.                         return eFileLoadDiskError;
  2635.                     }
  2636.             }
  2637.          else
  2638.             {
  2639.                 if (!WriteBufferedUnsignedChar(Output,0))
  2640.                     {
  2641.                         return eFileLoadDiskError;
  2642.                     }
  2643.             }
  2644.  
  2645.         /*   4-byte little endian output sampling rate */
  2646.         /*       should be in the range of 100..65535 */
  2647.         if (!WriteBufferedSignedLongLittleEndian(Output,Window->SamplingRate))
  2648.             {
  2649.                 return eFileLoadDiskError;
  2650.             }
  2651.  
  2652.         /*   4-byte little endian envelope update rate */
  2653.         /*       should be in the range of 1..65535 */
  2654.         if (!WriteBufferedSignedLongLittleEndian(Output,Window->EnvelopeUpdateRate))
  2655.             {
  2656.                 return eFileLoadDiskError;
  2657.             }
  2658.  
  2659.         /*   4-byte little endian large integer coded decimal beats per minute */
  2660.         /*       large integer coded decimal is decimal * 1000000 with a */
  2661.         /*       range of -1999.999999 to 1999.999999 */
  2662.         if (!WriteBufferedSignedLongLittleEndian(Output,Window->DefaultBeatsPerMinute))
  2663.             {
  2664.                 return eFileLoadDiskError;
  2665.             }
  2666.  
  2667.         /*   4-byte little endian large integer coded total volume scaling factor */
  2668.         if (!WriteBufferedSignedLongLittleEndian(Output,Window->OverallVolumeScalingFactor))
  2669.             {
  2670.                 return eFileLoadDiskError;
  2671.             }
  2672.  
  2673.         /*   1-byte number of bits to output */
  2674.         /*       should be 8, 16, 24, or 32 */
  2675.         switch (Window->OutputNumBits)
  2676.             {
  2677.                 default:
  2678.                     EXECUTE(PRERR(ForceAbort,"MainWindowWriteData:  bad value in Window->OutputNumBits"));
  2679.                     break;
  2680.                 case eOutput8Bits:
  2681.                     if (!WriteBufferedUnsignedChar(Output,8))
  2682.                         {
  2683.                             return eFileLoadDiskError;
  2684.                         }
  2685.                     break;
  2686.                 case eOutput16Bits:
  2687.                     if (!WriteBufferedUnsignedChar(Output,16))
  2688.                         {
  2689.                             return eFileLoadDiskError;
  2690.                         }
  2691.                     break;
  2692.                 case eOutput24Bits:
  2693.                     if (!WriteBufferedUnsignedChar(Output,24))
  2694.                         {
  2695.                             return eFileLoadDiskError;
  2696.                         }
  2697.                     break;
  2698.                 case eOutput32Bits:
  2699.                     if (!WriteBufferedUnsignedChar(Output,32))
  2700.                         {
  2701.                             return eFileLoadDiskError;
  2702.                         }
  2703.                     break;
  2704.             }
  2705.  
  2706.         /*   1-byte flag for interpolation over time */
  2707.         /*       0 = don't interpolate over time */
  2708.         /*       1 = do interpolate over time (when resampling waveforms) */
  2709.         if (Window->InterpolateOverTime)
  2710.             {
  2711.                 if (!WriteBufferedUnsignedChar(Output,1))
  2712.                     {
  2713.                         return eFileLoadDiskError;
  2714.                     }
  2715.             }
  2716.          else
  2717.             {
  2718.                 if (!WriteBufferedUnsignedChar(Output,0))
  2719.                     {
  2720.                         return eFileLoadDiskError;
  2721.                     }
  2722.             }
  2723.  
  2724.         /*   1-byte flag for interpolation across waves */
  2725.         /*       0 = don't interpolate across waves */
  2726.         /*       1 = do interpolate across waves (when wave table synthesis index is */
  2727.         /*           not an integer) */
  2728.         if (Window->InterpolateAcrossWaves)
  2729.             {
  2730.                 if (!WriteBufferedUnsignedChar(Output,1))
  2731.                     {
  2732.                         return eFileLoadDiskError;
  2733.                     }
  2734.             }
  2735.          else
  2736.             {
  2737.                 if (!WriteBufferedUnsignedChar(Output,0))
  2738.                     {
  2739.                         return eFileLoadDiskError;
  2740.                     }
  2741.             }
  2742.  
  2743.         /*   4-byte little endian large integer coded decimal scanning gap */
  2744.         if (!WriteBufferedSignedLongLittleEndian(Output,Window->ScanningGap))
  2745.             {
  2746.                 return eFileLoadDiskError;
  2747.             }
  2748.  
  2749.         /*   4-byte little endian large integer coded decimal buffer duration (in seconds) */
  2750.         if (!WriteBufferedSignedLongLittleEndian(Output,Window->BufferDuration))
  2751.             {
  2752.                 return eFileLoadDiskError;
  2753.             }
  2754.  
  2755.         /*   1-byte flag for clipping warning */
  2756.         /*       0 = don't warn about clipped samples */
  2757.         /*       1 = do warn about clipped samples */
  2758.         if (Window->ClipWarning)
  2759.             {
  2760.                 if (!WriteBufferedUnsignedChar(Output,1))
  2761.                     {
  2762.                         return eFileLoadDiskError;
  2763.                     }
  2764.             }
  2765.          else
  2766.             {
  2767.                 if (!WriteBufferedUnsignedChar(Output,0))
  2768.                     {
  2769.                         return eFileLoadDiskError;
  2770.                     }
  2771.             }
  2772.  
  2773.         /*   1-byte flag for song post processing enabling */
  2774.         /*       0 = don't do song postprocessing */
  2775.         /*       1 = do song postprocessing */
  2776.         if (Window->SongPostProcessingEnable)
  2777.             {
  2778.                 if (!WriteBufferedUnsignedChar(Output,1))
  2779.                     {
  2780.                         return eFileLoadDiskError;
  2781.                     }
  2782.             }
  2783.          else
  2784.             {
  2785.                 if (!WriteBufferedUnsignedChar(Output,0))
  2786.                     {
  2787.                         return eFileLoadDiskError;
  2788.                     }
  2789.             }
  2790.  
  2791.         /*   4-byte little endian length of song post processing function */
  2792.         StringTemp = MainWindowGetPostProcessing(Window);
  2793.         if (StringTemp == NIL)
  2794.             {
  2795.                 return eFileLoadOutOfMemory;
  2796.             }
  2797.         if (!WriteBufferedSignedLongLittleEndian(Output,PtrSize(StringTemp)))
  2798.             {
  2799.                 ReleasePtr(StringTemp);
  2800.                 return eFileLoadDiskError;
  2801.             }
  2802.  
  2803.         /*   n-bytes of post processing function text (line fed = 0x0a) */
  2804.         if (!WriteBufferedOutput(Output,PtrSize(StringTemp),StringTemp))
  2805.             {
  2806.                 ReleasePtr(StringTemp);
  2807.                 return eFileLoadDiskError;
  2808.             }
  2809.         ReleasePtr(StringTemp);
  2810.  
  2811.         return eFileLoadNoError;
  2812.     }
  2813.  
  2814.  
  2815. /* get the sample list object for the specified document.  the actual thing */
  2816. /* is returned */
  2817. struct SampleListRec*    MainWindowGetSampleList(MainWindowRec* Window)
  2818.     {
  2819.         CheckPtrExistence(Window);
  2820.         return Window->SampleList;
  2821.     }
  2822.  
  2823.  
  2824. /* get the algorithmic sample list object for the specified document.  the actual */
  2825. /* thing is returned. */
  2826. struct AlgoSampListRec*    MainWindowGetAlgoSampList(MainWindowRec* Window)
  2827.     {
  2828.         CheckPtrExistence(Window);
  2829.         return Window->AlgoSampList;
  2830.     }
  2831.  
  2832.  
  2833. /* get the wave table list object for the specified document.  the actual thing */
  2834. /* is returned */
  2835. struct WaveTableListRec*    MainWindowGetWaveTableList(MainWindowRec* Window)
  2836.     {
  2837.         CheckPtrExistence(Window);
  2838.         return Window->WaveTableList;
  2839.     }
  2840.  
  2841.  
  2842. /* get the algorithmic wave table list object for the specified document.  the */
  2843. /* actual thing is returned */
  2844. struct AlgoWaveTableListRec*    MainWindowGetAlgoWaveTableList(MainWindowRec* Window)
  2845.     {
  2846.         CheckPtrExistence(Window);
  2847.         return Window->AlgoWaveTableList;
  2848.     }
  2849.  
  2850.  
  2851. /* get the instrument list object for the specified document.  the actual thing */
  2852. /* is returned */
  2853. struct InstrListRec*    MainWindowGetInstrList(MainWindowRec* Window)
  2854.     {
  2855.         CheckPtrExistence(Window);
  2856.         return Window->InstrumentList;
  2857.     }
  2858.  
  2859.  
  2860. /* this updates the object deletion undo information */
  2861. void                                MainWindowNewDeleteUndoInfo(MainWindowRec* Window,
  2862.                                             struct FileSpec* Location, struct FileType* File)
  2863.     {
  2864.         CheckPtrExistence(Window);
  2865.         CheckPtrExistence(Location);
  2866.         CheckPtrExistence(File);
  2867.         if (Window->DeleteUndoFileLocation != NIL)
  2868.             {
  2869.                 CloseFile(Window->DeleteUndoFile);
  2870.                 DeleteFile(Window->DeleteUndoFileLocation);
  2871.                 DisposeFileSpec(Window->DeleteUndoFileLocation);
  2872.             }
  2873.         Window->DeleteUndoFileLocation = Location;
  2874.         Window->DeleteUndoFile = File;
  2875.     }
  2876.