home *** CD-ROM | disk | FTP | other *** search
/ PC Home 49 / PC_Home_Issue_49.iso / winprogs / playsk / dohintro.dxr / 00001.ls next >
Encoding:
Text File  |  1996-06-30  |  18.3 KB  |  570 lines

  1. on ExportScript
  2.   ExportPrologue()
  3.   set artList to []
  4.   set spriteList to []
  5.   AnalyzeTheScript(artList, spriteList)
  6.   ReallyExportScript(artList, spriteList)
  7.   put "...done"
  8. end
  9.  
  10. on ExportArt
  11.   ExportPrologue()
  12.   set artList to []
  13.   set spriteList to []
  14.   AnalyzeTheScript(artList, spriteList)
  15.   ReallyExportArt(artList)
  16.   put "...done"
  17. end
  18.  
  19. on ExportBoth
  20.   ExportPrologue()
  21.   set artList to []
  22.   set spriteList to []
  23.   AnalyzeTheScript(artList, spriteList)
  24.   ReallyExportScript(artList, spriteList)
  25.   ReallyExportArt(artList)
  26.   put "...done"
  27. end
  28.  
  29. on ExportPrologue
  30.   global gTheLastAnimationChannel, gStartFrameLabel, gEndFrameLabel, gCommandScript, gCommandScriptLines
  31.   set gTheLastAnimationChannel to 40
  32.   set gStartFrameLabel to "theStart"
  33.   set gEndFrameLabel to "theEnd"
  34.   set gCommandScript to EMPTY
  35.   set gCommandScriptLines to 0
  36. end
  37.  
  38. on AnalyzeTheScript usefulArtList, usefulSpriteList
  39.   global gTheLastAnimationChannel, gStartFrameLabel, gEndFrameLabel
  40.   put "Analyzing the script for art and sprites...."
  41.   set startFrame to label(gStartFrameLabel)
  42.   set endFrame to label(gEndFrameLabel)
  43.   if (startFrame = 0) or (endFrame = 0) then
  44.     put "Hey: missing label '" & gStartFrameLabel, "' or '" & gEndFrameLabel & "'"
  45.     abort()
  46.   end if
  47.   if startFrame > endFrame then
  48.     put "Hey: label '" & gStartFrameLabel & "' needs to come before label '" & gEndFrameLabel & "'"
  49.     abort()
  50.   end if
  51.   repeat with aFrame = startFrame to endFrame
  52.     go(aFrame)
  53.     repeat with aSprite = 2 to gTheLastAnimationChannel
  54.       set aCast to the castNum of sprite aSprite
  55.       if aCast = 0 then
  56.         set usefulPicture to 0
  57.       else
  58.         if the castType of cast aCast = #bitmap then
  59.           set usefulPicture to 1
  60.         else
  61.           if the castType of cast aCast = #picture then
  62.             set usefulPicture to 1
  63.           else
  64.             set usefulPicture to 0
  65.           end if
  66.         end if
  67.       end if
  68.       if usefulPicture then
  69.         set currentWidth to the right of sprite aSprite - the left of sprite aSprite
  70.         set currentHeight to the bottom of sprite aSprite - the top of sprite aSprite
  71.         set pictureEntry to [aCast, currentWidth, currentHeight]
  72.         if not ListContains(usefulArtList, pictureEntry) then
  73.           add(usefulArtList, pictureEntry)
  74.         end if
  75.         if not ListContains(usefulSpriteList, aSprite) then
  76.           add(usefulSpriteList, aSprite)
  77.         end if
  78.       end if
  79.     end repeat
  80.   end repeat
  81.   if (count(usefulArtList) = 0) or (count(usefulSpriteList) = 0) then
  82.     put "Hmm, no art found in scripts..."
  83.   end if
  84.   sort(usefulSpriteList)
  85. end
  86.  
  87. on PickCastMemberFileName itemIndex, addExtension
  88.   set baseName to the movie
  89.   if itemIndex < 10 then
  90.     set padding to "000"
  91.   else
  92.     if itemIndex < 100 then
  93.       set padding to "00"
  94.     else
  95.       if itemIndex < 1000 then
  96.         set padding to "0"
  97.       else
  98.         set padding to EMPTY
  99.       end if
  100.     end if
  101.   end if
  102.   if addExtension then
  103.     set extension to ".PICT"
  104.   else
  105.     set extension to EMPTY
  106.   end if
  107.   return baseName & "_" & padding & string(itemIndex) & extension
  108. end
  109.  
  110. on ListContains aList, anEntry
  111.   return ListIndex(aList, anEntry) > 0
  112. end
  113.  
  114. on ListIndex aList, anEntry
  115.   repeat with index = 1 to count(aList)
  116.     if SafeEquals(getAt(aList, index), anEntry) then
  117.       return index
  118.     end if
  119.   end repeat
  120.   return 0
  121. end
  122.  
  123. on SafeEquals thing1, thing2
  124.   set isList1 to listp(thing1)
  125.   set isList2 to listp(thing2)
  126.   if isList1 and isList2 then
  127.     set size1 to count(thing1)
  128.     set size2 to count(thing2)
  129.     if size1 <> size2 then
  130.       return 0
  131.     end if
  132.     repeat with index = 1 to size1
  133.       if not SafeEquals(getAt(thing1, index), getAt(thing2, index)) then
  134.         return 0
  135.       end if
  136.     end repeat
  137.     return 1
  138.   else
  139.     return thing1 = thing2
  140.   end if
  141. end
  142.  
  143. on ReadNumericText spriteNumber, defaultValue, numberName
  144.   set thisCastNumber to the castNum of sprite spriteNumber
  145.   if thisCastNumber <> 0 then
  146.     if the castType of cast thisCastNumber <> #empty then
  147.       if the castType of cast thisCastNumber <> #text then
  148.         put "Hey: bad " & numberName
  149.         abort()
  150.       end if
  151.       if not integerp(value(the text of cast thisCastNumber)) then
  152.         put "Hey: bad " & numberName
  153.         abort()
  154.       end if
  155.       return value(the text of cast thisCastNumber)
  156.     end if
  157.   end if
  158.   return defaultValue
  159. end
  160.  
  161. on GetNumericText theString, numberName
  162.   if integerp(value(theString)) then
  163.     return value(theString)
  164.   else
  165.     put "Hey: bad " & numberName
  166.     abort()
  167.   end if
  168. end
  169.  
  170. on ReadCommandScript headerScript
  171.   global gCommandScript, gCommandScriptLines
  172.   set gCommandScript to EMPTY
  173.   set gCommandScriptLines to 0
  174.   if the frameScript = 0 then
  175.     exit
  176.   end if
  177.   if headerScript then
  178.     set usefulCommands to ["NumberOfCommands:", "DropFrame:", "ActorLayer:"]
  179.   else
  180.     set usefulCommands to ["Loop:", "KeyFrame:", "Pause:", "Sound:", "Command:", "Goto:", "JumpIfQuiet:"]
  181.   end if
  182.   set lineCount to the number of lines in the scriptText of cast the frameScript
  183.   repeat with i = 1 to lineCount
  184.     set theLine to line i of the scriptText of cast the frameScript
  185.     if theLine starts "-- " then
  186.       if i = 1 then
  187.         set gCommandScript to theLine
  188.       else
  189.         set gCommandScript to gCommandScript & RETURN & theLine
  190.       end if
  191.       set gCommandScriptLines to gCommandScriptLines + 1
  192.       set theWord to word 2 of theLine
  193.       if not ListContains(usefulCommands, theWord) then
  194.         put "Hey: unknown directive '" & theWord & "'"
  195.         abort()
  196.       end if
  197.       next repeat
  198.     end if
  199.     if theLine = EMPTY then
  200.       exit repeat
  201.       next repeat
  202.     end if
  203.     put "Hey: bad command script"
  204.     abort()
  205.   end repeat
  206. end
  207.  
  208. on ReallyExportScript artList, usefulSpriteList
  209.   global gStartFrameLabel, gEndFrameLabel
  210.   if count(usefulSpriteList) = 0 then
  211.     set numOfChannels to 1
  212.   else
  213.     set numOfChannels to max(usefulSpriteList)
  214.   end if
  215.   set spriteInfoList to []
  216.   repeat with index = 1 to numOfChannels
  217.     add(spriteInfoList, [0, 0, 0, 0, index - 1])
  218.   end repeat
  219.   set frameInfoList to [0, [-1], []]
  220.   set animationInfoList to [0, 0, 2, 1]
  221.   AnalyzeHeaderInfo(animationInfoList, spriteInfoList)
  222.   WriteHeader(numOfChannels, animationInfoList)
  223.   set startFrame to label(gStartFrameLabel)
  224.   set endFrame to label(gEndFrameLabel)
  225.   repeat with aFrame = startFrame to endFrame
  226.     go(aFrame)
  227.     put "processing frame: " & the frame
  228.     ReadCommandScript(0)
  229.     WriteNewFrame(the frame, frameInfoList)
  230.     CheckForSounds(animationInfoList)
  231.     repeat with spriteSlot = 2 to numOfChannels
  232.       WritePictureInfo(spriteSlot, spriteInfoList, getAt(frameInfoList, 1), artList)
  233.     end repeat
  234.     CheckForCommands(animationInfoList)
  235.     CheckForGoto(frameInfoList)
  236.   end repeat
  237.   CleanUp()
  238.   set declaredLabels to getAt(frameInfoList, 2)
  239.   set gotoLabels to getAt(frameInfoList, 3)
  240.   repeat with theLabel in gotoLabels
  241.     if getOne(declaredLabels, theLabel) = 0 then
  242.       put "Hey: said goto " & theLabel & ", but label not declared"
  243.       abort()
  244.     end if
  245.   end repeat
  246. end
  247.  
  248. on AnalyzeHeaderInfo animationInfoList, spriteInfoList
  249.   global gCommandScript, gCommandScriptLines
  250.   go(1)
  251.   ReadCommandScript(1)
  252.   repeat with lineNumber = 1 to gCommandScriptLines
  253.     set theLine to line lineNumber of gCommandScript
  254.     set theWord to word 2 of theLine
  255.     if theWord = "NumberOfCommands:" then
  256.       setAt(animationInfoList, 1, GetNumericText(word 3 of theLine, "Number of commands"))
  257.       next repeat
  258.     end if
  259.     if theWord = "DropFrame:" then
  260.       setAt(animationInfoList, 2, GetNumericText(word 3 of theLine, "Drop frame"))
  261.       next repeat
  262.     end if
  263.     if theWord = "ActorLayer:" then
  264.       set theActor to GetNumericText(word 3 of theLine, "Actor layer")
  265.       set theLayer to GetNumericText(word 4 of theLine, "Actor layer")
  266.       set spriteInfo to getAt(spriteInfoList, theActor)
  267.       setAt(spriteInfo, 5, theLayer)
  268.     end if
  269.   end repeat
  270. end
  271.  
  272. on WriteHeader numberOfActors, animationInfoList
  273.   global FileIO, fileObj
  274.   if objectp(fileObj) then
  275.     fileObj(mdispose)
  276.   end if
  277.   set scriptName to the movie & ".scr"
  278.   set fileObj to FileIO(mnew, "write", the pathName & scriptName)
  279.   set numberOfCommands to getAt(animationInfoList, 1)
  280.   set dropFrames to getAt(animationInfoList, 2)
  281.   if fileObj(mStatus) <> 0 then
  282.     put "Hey: could not create: ", scriptName & "!"
  283.     abort()
  284.   end if
  285.   fileObj(mWriteString, "Animation " & the movie & RETURN)
  286.   fileObj(mWriteString, "BEGIN" & RETURN)
  287.   fileObj(mWriteString, TAB & "f_NumberOfActors " & numberOfActors - 1 & RETURN)
  288.   fileObj(mWriteString, TAB & "f_NumberOfSoundChannels " & 2 & RETURN)
  289.   fileObj(mWriteString, TAB & "f_NumberOfCommands " & numberOfCommands & RETURN)
  290.   fileObj(mWriteString, TAB & "f_DropFrame " & dropFrames & RETURN)
  291. end
  292.  
  293. on WriteNewFrame whichFrame, frameInfoList
  294.   global fileObj, gStartFrameLabel, gCommandScript, gCommandScriptLines
  295.   set hasSomeLabel to 0
  296.   if the frameLabel = gStartFrameLabel then
  297.     set currentFrameLabel to 1
  298.     set hasSomeLabel to 1
  299.   else
  300.     if the frameLabel <> EMPTY then
  301.       if integerp(value(the frameLabel)) then
  302.         set currentFrameLabel to value(the frameLabel)
  303.         set hasSomeLabel to 1
  304.       end if
  305.     end if
  306.   end if
  307.   if hasSomeLabel then
  308.     set currentListOfLabels to getAt(frameInfoList, 2)
  309.     if ListContains(getAt(frameInfoList, 2), currentFrameLabel) then
  310.       put "Hey: duplicate label " & string(currentFrameLabel)
  311.       abort()
  312.     end if
  313.   end if
  314.   if hasSomeLabel then
  315.     setAt(frameInfoList, 1, 1)
  316.     add(getAt(frameInfoList, 2), currentFrameLabel)
  317.   else
  318.     setAt(frameInfoList, 1, 0)
  319.     set currentFrameLabel to 0
  320.   end if
  321.   set currentFrameTempo to 1000 / the frameTempo
  322.   set loopFrames to 0
  323.   set loopCount to 0
  324.   set keyFrame to 0
  325.   repeat with lineNumber = 1 to gCommandScriptLines
  326.     set theLine to line lineNumber of gCommandScript
  327.     set theWord to word 2 of theLine
  328.     if theWord = "Loop:" then
  329.       set loopFrames to GetNumericText(word 3 of theLine, "Loop frame")
  330.       if word 4 of theLine = "sound" then
  331.         set loopCount to GetNumericText(word 5 of theLine, "Loop sound")
  332.         if (loopCount <> 1) and (loopCount <> 2) then
  333.           put "Hey: we only support two sound channels"
  334.           abort()
  335.         end if
  336.         set loopCount to -loopCount
  337.       else
  338.         set loopCount to GetNumericText(word 4 of theLine, "Loop count")
  339.       end if
  340.       setAt(frameInfoList, 1, 1)
  341.       next repeat
  342.     end if
  343.     if theWord = "KeyFrame:" then
  344.       set keyFrame to GetNumericText(word 3 of theLine, "Key frame")
  345.       next repeat
  346.     end if
  347.     if theWord = "Pause:" then
  348.       set pauseTime to GetNumericText(word 3 of theLine, "Pause amount")
  349.       if pauseTime < 0 then
  350.         put "Hey: bad pause amount"
  351.         abort()
  352.         next repeat
  353.       end if
  354.       if pauseTime = 0 then
  355.         set currentFrameTempo to -1
  356.         next repeat
  357.       end if
  358.       set currentFrameTempo to pauseTime
  359.     end if
  360.   end repeat
  361.   fileObj(mWriteString, TAB & "f_Frame (" & currentFrameLabel & ", " & currentFrameTempo & ", " & loopFrames & ", " & loopCount & ")" & RETURN)
  362.   if keyFrame <> 0 then
  363.     fileObj(mWriteString, TAB & TAB & "f_KeyFrame " & keyFrame & RETURN)
  364.   end if
  365. end
  366.  
  367. on CleanUp
  368.   global fileObj
  369.   fileObj(mWriteString, "END" & RETURN)
  370.   fileObj(mdispose)
  371. end
  372.  
  373. on CheckForSounds animationInfoList
  374.   global fileObj, gCommandScript, gCommandScriptLines
  375.   repeat with lineNumber = 1 to gCommandScriptLines
  376.     set theLine to line lineNumber of gCommandScript
  377.     set theWord to word 2 of theLine
  378.     if theWord = "Sound:" then
  379.       set whichChannel to GetNumericText(word 3 of theLine, "Channel number")
  380.       set soundName to word 4 of theLine
  381.       if soundName = "STOP" then
  382.         fileObj(mWriteString, TAB & TAB & "f_SoundChannel (" & whichChannel - 1 & ", 0, 0, 0)" & RETURN)
  383.         next repeat
  384.       end if
  385.       set loopIt to 0
  386.       set ourPriority to getAt(animationInfoList, whichChannel + 2)
  387.       if word 5 of theLine = "Loop" then
  388.         set loopIt to 1
  389.         if word 6 of theLine <> EMPTY then
  390.           set ourPriority to GetNumericText(word 6 of theLine, "Sound priority")
  391.         end if
  392.       else
  393.         if word 5 of theLine <> EMPTY then
  394.           set ourPriority to GetNumericText(word 5 of theLine, "Sound priority")
  395.         end if
  396.       end if
  397.       setAt(animationInfoList, whichChannel + 2, ourPriority)
  398.       fileObj(mWriteString, TAB & TAB & "f_SoundChannel (" & whichChannel - 1 & ", 1, " & loopIt & ", " & ourPriority & ")" & RETURN)
  399.       fileObj(mWriteString, TAB & TAB & "f_SoundEffect '" & soundName & "'" & RETURN)
  400.     end if
  401.   end repeat
  402. end
  403.  
  404. on WritePictureInfo currentSpriteSlot, spriteInfoList, forceWrite, artList
  405.   global fileObj
  406.   set theCastMember to the castNum of sprite currentSpriteSlot
  407.   if theCastMember = 0 then
  408.     set usefulPicture to 0
  409.   else
  410.     if the castType of cast theCastMember = #bitmap then
  411.       set usefulPicture to 1
  412.     else
  413.       if the castType of cast theCastMember = #picture then
  414.         set usefulPicture to 1
  415.       else
  416.         set usefulPicture to 0
  417.       end if
  418.     end if
  419.   end if
  420.   set previousSpriteInfo to getAt(spriteInfoList, currentSpriteSlot)
  421.   set previousLayer to getAt(previousSpriteInfo, 5)
  422.   if usefulPicture then
  423.     set currentLeft to the left of sprite currentSpriteSlot
  424.     set currentTop to the top of sprite currentSpriteSlot
  425.     set currentWidth to the right of sprite currentSpriteSlot - currentLeft
  426.     set currentHeight to the bottom of sprite currentSpriteSlot - currentTop
  427.     set pictureEntry to ListIndex(artList, [theCastMember, currentWidth, currentHeight])
  428.     if pictureEntry = 0 then
  429.       put "Hey: couldn't find an entry for [ " & theCastMember && currentWidth && currentHeight & " ]!!"
  430.       abort()
  431.     end if
  432.     set currentSpriteThing to [pictureEntry, 1, currentLeft, currentTop, previousLayer]
  433.   else
  434.     if forceWrite then
  435.       set currentSpriteThing to [0, 0, 0, 0, previousLayer]
  436.     else
  437.       set currentSpriteThing to [getAt(previousSpriteInfo, 1), 0, 0, 0, previousLayer]
  438.     end if
  439.   end if
  440.   if not SafeEquals(currentSpriteThing, previousSpriteInfo) or forceWrite then
  441.     set actorNumber to currentSpriteSlot - 2
  442.     set currentLeft to getAt(currentSpriteThing, 3)
  443.     set currentTop to getAt(currentSpriteThing, 4)
  444.     if getAt(currentSpriteThing, 2) then
  445.       set currentLayer to getAt(currentSpriteThing, 5)
  446.     else
  447.       set currentLayer to -1
  448.     end if
  449.     fileObj(mWriteString, TAB & TAB & "f_Actor (" & actorNumber & ", " & currentLayer & ", " & currentLeft & ", " & currentTop & ")" & RETURN)
  450.     set oldArtItem to getAt(previousSpriteInfo, 1)
  451.     set newArtItem to getAt(currentSpriteThing, 1)
  452.     if (newArtItem <> 0) and (forceWrite or (newArtItem <> oldArtItem)) then
  453.       set thisCastName to PickCastMemberFileName(newArtItem, 0)
  454.       fileObj(mWriteString, TAB & TAB & "f_ActorPicture " & "'" & thisCastName & "'" & RETURN)
  455.     end if
  456.   end if
  457.   setAt(spriteInfoList, currentSpriteSlot, currentSpriteThing)
  458. end
  459.  
  460. on CheckForCommands animationInfoList
  461.   global fileObj, gCommandScript, gCommandScriptLines
  462.   repeat with lineNumber = 1 to gCommandScriptLines
  463.     set theLine to line lineNumber of gCommandScript
  464.     set theWord to word 2 of theLine
  465.     if theWord = "Command:" then
  466.       set theCommand to GetNumericText(word 3 of theLine, "Command number")
  467.       if (theCommand < 0) or (theCommand >= getAt(animationInfoList, 1)) then
  468.         put "Hey: command value out of range"
  469.         abort()
  470.       end if
  471.       fileObj(mWriteString, TAB & TAB & "f_ExecuteCommand " & theCommand & RETURN)
  472.     end if
  473.   end repeat
  474. end
  475.  
  476. on CheckForGoto frameInfoList
  477.   global fileObj, gCommandScript, gCommandScriptLines
  478.   set foundGoto to 0
  479.   repeat with lineNumber = 1 to gCommandScriptLines
  480.     set theLine to line lineNumber of gCommandScript
  481.     set theWord to word 2 of theLine
  482.     if theWord = "Goto:" then
  483.       if foundGoto then
  484.         put "Hey: more than one goto in script!"
  485.         abort()
  486.       end if
  487.       set theLabel to GetNumericText(word 3 of theLine, "Label number")
  488.       fileObj(mWriteString, TAB & TAB & "f_GotoFrame " & theLabel & RETURN)
  489.       set gotoList to getAt(frameInfoList, 3)
  490.       add(gotoList, theLabel)
  491.       set foundGoto to 1
  492.       next repeat
  493.     end if
  494.     if theWord = "JumpIfQuiet:" then
  495.       if foundGoto then
  496.         put "Hey: JumpIfQuiet needs to go before Goto!"
  497.         abort()
  498.       end if
  499.       set theChannel to GetNumericText(word 3 of theLine, "Sound channel")
  500.       set theLabel to GetNumericText(word 4 of theLine, "Label number")
  501.       fileObj(mWriteString, TAB & TAB & "f_MaybeGotoFrame (" & theChannel - 1 & ", " & theLabel & ")" & RETURN)
  502.       set gotoList to getAt(frameInfoList, 3)
  503.       add(gotoList, theLabel)
  504.     end if
  505.   end repeat
  506. end
  507.  
  508. on ReallyExportArt artList
  509.   set oldColorDepth to the colorDepth
  510.   set the colorDepth to 8
  511.   OpenPictureExporter()
  512.   ExportPictures(artList)
  513.   ClosePictureExporter()
  514.   set the colorDepth to oldColorDepth
  515. end
  516.  
  517. on OpenPictureExporter
  518.   global copyObj
  519.   if objectp(copyObj) then
  520.     copyObj(mdispose)
  521.   end if
  522.   set copyObj to StageToPICT(mnew)
  523. end
  524.  
  525. on ClosePictureExporter
  526.   global copyObj
  527.   if objectp(copyObj) then
  528.     copyObj(mdispose)
  529.   end if
  530. end
  531.  
  532. on ExportPictures artList
  533.   go(label(gEndFrameLabel) + 1)
  534.   if the castNum of sprite 1 = 0 then
  535.     put "Hey: missing sprite in channel 1 in frame after 'theEnd'"
  536.     abort()
  537.   end if
  538.   repeat with index = 1 to count(artList)
  539.     set subItem to getAt(artList, index)
  540.     ExportOnePicture(index, getAt(subItem, 1), getAt(subItem, 2), getAt(subItem, 3))
  541.   end repeat
  542. end
  543.  
  544. on ExportOnePicture artIndex, theCastMember, itsWidth, itsHeight
  545.   global copyObj, oldFile
  546.   put "exporting cast" && theCastMember && "at" && itsWidth && "x" && itsHeight
  547.   set the ink of sprite 1 to 0
  548.   set the castNum of sprite 1 to theCastMember
  549.   updateStage()
  550.   set newLeft to ((the stageRight - the stageLeft) / 2) - (itsWidth / 2)
  551.   set newTop to ((the stageBottom - the stageTop) / 2) - (itsHeight / 2)
  552.   set newRight to newLeft + itsWidth
  553.   set newBottom to newTop + itsHeight
  554.   spriteBox(1, newLeft, newTop, newRight, newBottom)
  555.   updateStage()
  556.   set fileName to the pathName & PickCastMemberFileName(artIndex, 1)
  557.   if objectp(oldFile) then
  558.     oldFile(mdispose)
  559.   end if
  560.   set oldFile to FileIO(mnew, "read", fileName)
  561.   if objectp(oldFile) then
  562.     set theErr to oldFile(mDelete)
  563.   end if
  564.   set theErr to copyObj(mSaveAsPICT, the top of sprite 1, the left of sprite 1, the bottom of sprite 1, the right of sprite 1, fileName)
  565.   if theErr <> 0 then
  566.     put "Hey: cast member" && theCastMember && "failed to export!"
  567.     abort()
  568.   end if
  569. end
  570.