home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Pascal / Games / Showwit! 1.0 / source code / Source / CShLevelsDoc.p < prev    next >
Encoding:
Text File  |  1996-02-10  |  9.6 KB  |  369 lines  |  [TEXT/PJMM]

  1. {****************************************************}
  2. {}
  3. {        CShLevelsDoc.p                                                                                                                                                                                                }
  4. {}
  5. {        Document class for the Showwit! application. Documents store levels                                }
  6. {        which can be played.                                                                                                                                                                                }
  7. {}
  8. {****************************************************}
  9.  
  10.  
  11. unit CShLevelsDoc;
  12.  
  13. interface
  14.  
  15.     uses
  16.         TCL, ShIntf;
  17.  
  18. implementation
  19.  
  20.  
  21. {****************************************************}
  22. {}
  23. {        IShLevelsDoc                                                                                                                                                                                                        }
  24. {}
  25. {        Construction of the levels document object.                                                                                                         }
  26. {}
  27. {****************************************************}
  28.  
  29.     procedure CShLevelsDoc.IShLevelsDoc (aSupervisor: CShApp);
  30.  
  31.     begin { IShLevelsDoc }
  32.         itsShApp := aSupervisor;
  33.  
  34.         { We store our own pointer to the file, which we know to be of type CResFile. }
  35.  
  36.         itsShLevelsFile := nil;
  37.  
  38.         itsProgBar := nil;
  39.  
  40.         IDocument(aSupervisor, kNotPrintable);
  41.     end; { IShLevelsDoc }
  42.  
  43.  
  44. {****************************************************}
  45. {}
  46. {        Free                                                                                                                                                                                                                                }
  47. {}
  48. {        Destruction of the levels document object. We set our pointers to nil, for the        }
  49. {        objects to which they were pointing will be disposed of in inherited methods.        }
  50. {}
  51. {****************************************************}
  52.  
  53.     procedure CShLevelsDoc.Free;
  54.  
  55.     begin { Free }
  56.         itsShApp := nil;
  57.         itsShLevelsFile := nil;
  58.  
  59.         itsProgBar := nil;
  60.  
  61.         inherited Free;
  62.     end; { Free }
  63.  
  64.  
  65. {****************************************************}
  66. {}
  67. {        OpenFile                                                                                                                                                                                                                    }
  68. {}
  69. {        Opens the levels file, reads the levels and then closes the document (we do             }
  70. {        not need the file open afterwards). Updates the progress bar whilst doing so.        }
  71. {}
  72. {****************************************************}
  73.  
  74.     procedure CShLevelsDoc.OpenFile (macSFReply: SFReply);
  75.  
  76.         var
  77.             theFile: CResFile;
  78.  
  79.             theList: CList;
  80.             theLevel: CShLevel;
  81.             theCount, theNumLevels: Integer;
  82.  
  83.             theSavedRes: Integer;
  84.             fi: FailInfo;
  85.  
  86.         procedure BuildWindow;
  87.  
  88.             var
  89.                 theWindow: CWindow;
  90.                 theWindRect: Rect;
  91.  
  92.                 thePicture: CPicture;
  93.  
  94.                 theReadingStr: Str255;
  95.                 theEditText: CEditText;
  96.  
  97.                 theProgBar: CProgressBar;
  98.  
  99.                 theBorder: CPaneBorder;
  100.  
  101.         begin { BuildWindow }
  102.             new(theWindow);
  103.             theWindow.IWindow(WINDReader, kNotFloating, gDesktop, SELF);
  104.             itsWindow := theWindow;
  105.  
  106.             { We don't want the window to be re-sizable. }
  107.  
  108.             SetRect(theWindRect, kReaderWindh, kReaderWindv, kReaderWindh, kReaderWindv);
  109.             itsWindow.SetSizeRect(theWindRect);
  110.  
  111.             { To be able to hide the window, it must be non-modal. }
  112.  
  113.             itsWindow.SetModal(kModeless);
  114.  
  115.             gDecorator.PlaceNewWindow(itsWindow);
  116.             gDecorator.CenterWindow(itsWindow);
  117.  
  118.             { Background picture. }
  119.  
  120.             new(thePicture);
  121.             thePicture.IPicture(itsWindow, SELF, kReaderWindh, kReaderWindv, 0, 0, sizFIXEDSTICKY, sizFIXEDSTICKY);
  122.             if gSystem.hasColorQD then begin
  123.                 thePicture.UsePICT(PICTReaderColour);
  124.             end { if }
  125.             else begin
  126.                 thePicture.UsePICT(PICTReaderBW);
  127.             end; { else }
  128.             thePicture.SetScaled(FALSE);
  129.  
  130.             { Text saying what file we are reading from. }
  131.  
  132.             new(theEditText);
  133.             theEditText.IEditText(itsWindow, SELF, kReaderTextLenh, kReaderTextLenv, kReaderTextPosh, kReaderTextPosv, sizFIXEDSTICKY, sizFIXEDSTICKY, kReaderTextLenh);
  134.             theEditText.Specify(kNotEditable, kNotSelectable, kNotStylable);
  135.             theEditText.SetAlignCmd(cmdAlignLeft);
  136.             theEditText.SetFontNumber(0); { System font, Chicago. }
  137.             GetIndString(theReadingStr, STRlistAppMessages, kSTRAppReading);
  138.             theEditText.SetTextString(Concat(theReadingStr, ' “', macSFReply.fName, '”.'));
  139.  
  140.             { Progress bar. }
  141.  
  142.             new(theProgBar);
  143.             theProgBar.IProgressBar(itsWindow, SELF, kReaderProgBarLenh, kReaderProgBarLenv, kReaderProgBarPosh, kReaderProgBarPosv, sizFIXEDSTICKY, sizFIXEDSTICKY, kUseColor, kHorizontal, KNoShadow, FinderFillColor, FinderBackColor);
  144.             itsProgBar := theProgBar;
  145.  
  146.             { Border for the progress bar. }
  147.  
  148.             new(theBorder);
  149.             theBorder.IPaneBorder(kBorderFrame);
  150.             theProgBar.SetBorder(theBorder);
  151.  
  152.             { Select the window to bring it to the front. }
  153.  
  154.             itsWindow.Select;
  155.  
  156.             { Until now, no updating has been done. }
  157.             { We have to force one now, to correctly draw the picture. }
  158.  
  159.             itsWindow.Update;
  160.         end; { BuildWindow }
  161.  
  162.         procedure HandleFailure (error: Integer; message: Longint);
  163.  
  164.         begin { HandleFailure }
  165.             { Something failed here. Restore the resource, forget the level, }
  166.             { then allow the exception to propagate. }
  167.  
  168.             ForgetObject(theList);
  169.             ForgetObject(theLevel);
  170.             itsFile.Close;
  171.             UseResFile(theSavedRes);
  172.         end; { HandleFailure }
  173.  
  174.     begin { OpenFile }
  175.         new(theFile);
  176.         theFile.IResFile;
  177.         theFile.SFSpecify(macSFReply);
  178.  
  179.         itsFile := theFile;        { For inherited methods. }
  180.         itsShLevelsFile := theFile;    { For our use. }
  181.  
  182.         BuildWindow;
  183.  
  184.         new(theList);
  185.         theList.IList;
  186.         theLevel := nil;
  187.  
  188.         { We know that the window has just been created, and hence that the }
  189.         { progress bar is currently at 0 percent. }
  190.  
  191.         { Store the current resource file so that we can restore it after }
  192.         { we are finished with the levels file. }
  193.  
  194.         theSavedRes := CurResFile;
  195.  
  196.         { Read each level from resource, and place in list. }
  197.  
  198.         CatchFailures(fi, HandleFailure);
  199.  
  200.         itsShLevelsFile.Open(fsRdPerm);
  201.  
  202.         { Assume numeric contiguity of levels, and load the number present. }
  203.         { SetLEVL and SetBEST handle the cases for invalid resources. }
  204.         theNumLevels := Count1Resources(kLEVLResType);
  205.         for theCount := 1 to theNumLevels do begin
  206.  
  207.             new(theLevel);
  208.             theLevel.SetLEVL(LEVLDefStart + theCount - 1);
  209.  
  210.             { We look at the best player resource here, so that }
  211.             { we correctly link the level with the player. }
  212.  
  213.             theLevel.SetBEST(BESTDefStart + theCount - 1);
  214.  
  215.             theList.InsertAt(theLevel, theCount);
  216.  
  217.             itsProgBar.UpdateProgress(Integer(LongInt(theCount) * 100 div theNumLevels));
  218.         end;
  219.  
  220.         itsShLevelsFile.Close;
  221.  
  222.         Success;
  223.  
  224.         UseResFile(theSavedRes);
  225.  
  226.         itsShApp.GameDirector.SetLevels(theList);
  227.  
  228.         { After setting levels, reselect the game director's window. Then hide our own window. }
  229.         { This order is important! }
  230.         { This is really a bit of trickery to ensure that the game director window is always foremost. }
  231.         { Generally, one would expect that a document's window would be the active one after opening. }
  232.  
  233.         itsShApp.GameDirector.GetWindow.Select;
  234.         itsWindow.Hide;
  235.     end; { OpenFile }
  236.  
  237.  
  238. {****************************************************}
  239. {}
  240. {        StoreBestPlayer                                                                                                                                                                                            }
  241. {}
  242. {        Stores the specified best player to the levels file.                                                                                        }
  243. {}
  244. {****************************************************}
  245.  
  246.     procedure CShLevelsDoc.StoreBestPlayer (aLevelNum: LevelsRange; aPlayer: Str15; aMoves: Integer; aTime: LongInt);
  247.  
  248.         var
  249.             theBEST: BESTtemplateH; { Handle to best player resource. }
  250.  
  251.             theSavedRes: Integer;
  252.             fi: FailInfo;
  253.  
  254.         procedure HandleFailure (error: Integer; message: Longint);
  255.  
  256.         begin { HandleFailure }
  257.             (* Something failed here. Restore the resource, *)
  258.             (* forget the level, then allow the exception to propagate.*)
  259.  
  260.             { Does closing the file really help? }
  261.  
  262.             itsShLevelsFile.Close;
  263.             UseResFile(theSavedRes);
  264.         end; { HandleFailure }
  265.  
  266.     begin { StoreBestPlayer }
  267.         theSavedRes := CurResFile;
  268.  
  269.         CatchFailures(fi, HandleFailure);
  270.  
  271.         itsShLevelsFile.Open(fsRdWrPerm);
  272.  
  273.         theBEST := BESTtemplateH(Get1Resource(kBESTResType, BESTDefStart + aLevelNum - 1));
  274.  
  275.         { We want to replace any existing resource of this type and ID. }
  276.  
  277.         if theBEST <> nil then begin
  278.             HNoPurge(Handle(theBest));
  279.  
  280.             { Set the new best player for this level. }
  281.             theBest^^.thePlayer := aPlayer;
  282.             theBest^^.theMoves := aMoves;
  283.             theBest^^.theTime := aTime;
  284.  
  285.             ChangedResource(Handle(theBest));
  286.             FailResError;
  287.             WriteResource(Handle(theBest));
  288.  
  289.             HPurge(Handle(theBest));
  290.         end { if }
  291.         else begin
  292.  
  293.             SetCriticalOperation(TRUE);
  294.             theBest := BESTtemplateH(NewHandleCanFail(SizeOf(BESTtemplate)));
  295.             FailNIL(theBest);
  296.             SetCriticalOperation(FALSE);
  297.  
  298.             { Set the new best player for this level. }
  299.             theBest^^.thePlayer := aPlayer;
  300.             theBest^^.theMoves := aMoves;
  301.             theBest^^.theTime := aTime;
  302.  
  303.             { Add it to the resource file. }
  304.             AddResource(Handle(theBest), kBESTResType, BESTDefStart + aLevelNum - 1, '');
  305.             FailResError;
  306.             WriteResource(Handle(theBest));
  307.  
  308.         end; { else }
  309.  
  310.         itsShLevelsFile.Close;
  311.  
  312.         UseResFile(theSavedRes);
  313.  
  314.         Success;
  315.     end; { StoreBestPlayer }
  316.  
  317.  
  318. {****************************************************}
  319. {}
  320. {        ClearBestPlayers                                                                                                                                                                                        }
  321. {}
  322. {        Clears the best players from the levels file.                                                                                                         }
  323. {}
  324. {****************************************************}
  325.  
  326.     procedure CShLevelsDoc.ClearBestPlayers;
  327.  
  328.         var
  329.             theBEST: BESTtemplateH; { Handle to best player resource. }
  330.  
  331.             theSavedRes: Integer;
  332.             fi: FailInfo;
  333.  
  334.         procedure HandleFailure (error: Integer; message: Longint);
  335.  
  336.         begin { HandleFailure }
  337.             (* Something failed here. Restore the resource, *)
  338.             (* forget the level, then allow the exception to propagate.*)
  339.  
  340.             { Does closing the file really help? }
  341.  
  342.             itsShLevelsFile.Close;
  343.             UseResFile(theSavedRes);
  344.         end; { HandleFailure }
  345.  
  346.     begin { ClearBestPlayers }
  347.         theSavedRes := CurResFile;
  348.  
  349.         CatchFailures(fi, HandleFailure);
  350.  
  351.         itsShLevelsFile.Open(fsRdWrPerm);
  352.  
  353.         { Can't use a for loop, because the act of removing a resource }
  354.         { changes the internal indices (probably). }
  355.         while Count1Resources(kBESTResType) > 0 do begin
  356.             theBEST := BESTtemplateH(Get1IndResource(kBESTResType, 1));
  357.             RmveResource(Handle(theBEST));
  358.             ForgetHandle(theBEST);    { Careful - don't use ForgetResource }
  359.         end; { while }
  360.  
  361.         itsShLevelsFile.Close;
  362.  
  363.         UseResFile(theSavedRes);
  364.  
  365.         Success;
  366.     end; { ClearBestPlayers }
  367.  
  368.  
  369. end. { CShLevelsDoc }