objects3.pas 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134
  1. {$R-}
  2. Unit Objects3;
  3. {Здесь находятся все объекты (классы) используемые в программе}
  4. {Версия 3я, используется страницы и память EMS}
  5. INTERFACE
  6. Uses Graph, Draw10H,My_MEM;
  7. type
  8. FLAG_ENUM = (NONE,CAN_DRAW,HEAT);
  9. FLAGS = set of FLAG_ENUM;
  10. Const
  11. M_360_2PI = 360/(2*Pi);
  12. GLOB_G : real = 0.01;
  13. FIELD_X : word = 600;
  14. TRES_LX : word = 10;
  15. TRES_MX : word = 630;
  16. TRES_LY : word = 10;
  17. TRES_MY : word = 340;
  18. SIZE_Y : word = 350;
  19. FPS : WORD = 1;
  20. TIME_FACTOR : real = 0.1;
  21. type
  22. {Globals}
  23. Vector = record
  24. x,y : real;
  25. end;
  26. TSprites = array [0..(65536 shr 2)-2] of Pointer;
  27. PSprites = ^TSprites;
  28. TWordArray = array [0..(65536 shr 1)-2] of word;
  29. PWordArray = ^TWordArray;
  30. TByteArray = array [0..65534] of Byte;
  31. PByteArray = ^TByteArray;
  32. TEMMFrames = record {For all frames allocating one memory block, with}
  33. Mem : EMMRec; { 'framecount' pages}
  34. Page : PWordArray; {This array handles number of pages, linked with
  35. framenum's}
  36. Offs : PWordArray;
  37. end;
  38. TParams = record
  39. Pos,Speed,Accel : Vector;
  40. end;
  41. PWorld = ^TWorld;
  42. { MAIN OBJECT (Global Parent) }
  43. PWorldObject = ^TWorldObject;
  44. TWorldObject = object
  45. ObjType : string[20];
  46. Flag : FLAGS;
  47. World : PWorld;
  48. LocTime : LONGINT;
  49. Params : TParams;
  50. Angle : integer;
  51. ZORDER : Byte;
  52. Started : boolean;
  53. Constructor Init;
  54. Procedure Frame(t:longInt);virtual; {Процедура, выполняемая на каждом
  55. шаге, t - время этого шага (отрезок)
  56. Для абсолютности времени}
  57. Destructor Done;virtual;
  58. end;
  59. pDrawable = ^tDrawAble;
  60. tDrawable = object (TWorldObject)
  61. { Frames : Psprites;}
  62. Frames : TEMMFrames;
  63. FramesCount : integer;
  64. FrameSize : PWordArray;
  65. xsize,ysize : PWordArray;
  66. CurFrame : integer;
  67. Constructor Init;
  68. Procedure Draw;virtual;
  69. Function Inside(aPos:Vector):boolean;virtual;
  70. end;
  71. pRAH = ^tRAH;
  72. tRAH = object (TDrawable)
  73. Masks : TEMMFrames;
  74. FileCount : integer;
  75. NextTrap : longint;
  76. FrameTime : longint;
  77. TrapBase, TrapVar : longint;
  78. SpeedBase, SpeedVar : longint;
  79. CountBase, CountVar : integer;
  80. A,B : Vector;
  81. Constructor Init(AnimDat:string;aPar : TParams;Zord:byte);
  82. Procedure DropTraps(aCount:byte);
  83. Procedure Frame(t : longint);virtual;
  84. Procedure Draw;virtual;
  85. Function Inside(aPos:Vector):boolean;virtual;
  86. Destructor Done;virtual;
  87. end;
  88. pTrap = ^tTrap;
  89. tTrap = object(TDrawable)
  90. MFrames : Psprites;
  91. Constructor Init(AnimDat:string;var aPos:vector; var aSpeed,aG : real; aAng:integer;zOrd:byte);
  92. Procedure Frame(t : longint);virtual;
  93. Procedure Draw;virtual;
  94. Function Inside(aPos:Vector):boolean;virtual;
  95. Destructor Done;virtual;
  96. end;
  97. pSting = ^tSting;
  98. tSting = object (TDrawable)
  99. dAngle : integer;
  100. Nose : Vector;
  101. Constructor Init(AnimDat:string;aPar : TParams;adAng:integer;Zord:byte);
  102. Procedure GetAngle;
  103. Procedure FindTarget(aDa:integer);
  104. Procedure ChangeAngle(dA : integer);
  105. Procedure Frame(t : longint);virtual;
  106. Procedure Draw;virtual;
  107. Destructor Done;virtual;
  108. end;
  109. pExpl = ^tExpl;
  110. tExpl = object (TDrawAble)
  111. Masks : TEMMFrames;
  112. LifeTime : Longint;
  113. Constructor Init(AnimDat:string;aLifeTime:longint;aPos:vector;Zord:byte);
  114. Procedure Frame(t : longint);virtual;
  115. Procedure Draw;virtual;
  116. Destructor Done;virtual;
  117. end;
  118. { - - - - - - - - - - - - - - - -}
  119. PWOsList = ^TWOsList;
  120. TWOsList = record
  121. o : PworldObject;
  122. next : PWOsLIst;
  123. end;
  124. TWorld = object
  125. Ending : boolean;
  126. MSG : string;
  127. MSGSize : word;
  128. MSGColor : byte;
  129. Procedure Gone(aObj : PWorldObject); {Objects, that needs to be killed}
  130. Constructor Init(aBGn : string); {aBGN - BackGround fileName}
  131. Procedure Draw;
  132. Procedure Frame(t:longint);
  133. Function Radar(aSelf:PWorldObject;aFlg:FLAG_ENUM;var a0:integer;a1:integer;var aDist:real):PWorldObject;
  134. Procedure StartObjects(aT:string);
  135. Procedure Explosion(aPos:vector);
  136. Procedure Message(aS:string;aSize:word;aColor:byte);
  137. Function AddObject(aOb : PWorldObject):boolean;
  138. Function RemoveObject(aOb:PWorldObject):boolean;
  139. Destructor Done;
  140. private
  141. WObjects : PWOsList;
  142. ToGone : PWOsList; {Стек объектов на "убийство"}
  143. { BackGround }
  144. xpos, ypos : PWordArray;
  145. xsize,ysize : PWordArray;
  146. FrameCount : Byte;
  147. BackGround : TEMMFrames;
  148. FrameSize : PWordArray;
  149. {}
  150. end;
  151. {----------- END OF OBJECTS ----------------------}
  152. IMPLEMENTATION
  153. { TWorldObject Dummy }
  154. {------------------------------------------}
  155. Procedure Error(aMSG : string);
  156. begin
  157. CloseGraph;
  158. WriteLn(aMSG);
  159. Halt(2);
  160. end;{Error}
  161. {------------}
  162. Constructor TworldObject.Init;
  163. begin
  164. ObjType := 'dummy';
  165. Flag := [NONE];
  166. Zorder := 0;
  167. LocTime := 0;
  168. Started := false;
  169. end;{TworldObject.Init}
  170. {----}
  171. Procedure TWorldObject.Frame;
  172. begin {Nothing here now}
  173. end; {TWorldObject.Frame}
  174. {----}
  175. Destructor TWorldObject.Done;
  176. begin {Nothing here now}
  177. end; {TWorldObject.Done}
  178. {----}
  179. Constructor TDrawable.Init;
  180. begin
  181. Inherited Init;
  182. Flag := Flag + [CAN_DRAW];
  183. Frames.Mem.EMMHandle:=0;
  184. Frames.Mem.PageCount:=0;
  185. Frames.Page:=nil;
  186. Frames.Offs:=nil;
  187. FramesCount:=0;
  188. FrameSize:=nil;
  189. xsize:=nil;ysize:=nil;
  190. CurFrame:=0;
  191. end;{TDrawable.Init}
  192. {----}
  193. Procedure TDrawable.Draw;
  194. begin
  195. end;{TDrawable.Draw}
  196. Function TDrawable.Inside;
  197. begin
  198. Inside:=false;
  199. end;{TDrawable.Inside}
  200. {------------------------------------------}
  201. { First object - Helicopter Commanche RAH-66}
  202. Constructor tRAH.Init;
  203. var
  204. i : byte;
  205. F : FILE;
  206. cOffs,cPage : word;
  207. AbsAddr : Pointer;
  208. begin
  209. Inherited Init;
  210. Randomize;
  211. FLAG := FLAG + [HEAT] - [NONE];
  212. ObjType := 'RAH-66';
  213. TrapBase := 100;
  214. TrapVar := 30;
  215. { NextTrap := TrapBase + random(TrapVar) - (TrapVar shr 1);}
  216. Params := aPar;
  217. ZOrder := zOrd;
  218. Assign(F,AnimDat);
  219. {$I-}
  220. Reset(F,1);
  221. If IOResult <> 0 then
  222. Error('Error opening animation library for RAH-66');
  223. {$I+}
  224. BlockRead(F,FileCount,2);
  225. FramesCount := (FileCount-1)*2;
  226. if not TestAllocEMM(FileSize(F)+1 shl 13) then
  227. begin CloseGraph;
  228. WriteLn('Sorry, not enough EMS memory, need ',FileSize(F)+1 shl 13,' get ',MaxEMM);
  229. Halt(255);
  230. end;
  231. if not AllocEMM(FileSize(F) shr 1 +1 shl 13,Frames.Mem) then
  232. Error('Error while allocating EMS memory for tRAH');
  233. if not AllocEMM(FileSize(F) shr 1 +1 shl 13,Masks.Mem) then
  234. Error('Error while allocating EMS memory for tRAH');
  235. GetMem(Frames.Page,FramesCount*sizeof(word));
  236. GetMem(Frames.Offs,FramesCount*sizeof(word));
  237. GetMem(Masks .Page,FramesCount*sizeof(word));
  238. GetMem(Masks .Offs,FramesCount*sizeof(word));
  239. GetMem(xsize, FramesCount*sizeof(Word));
  240. GetMem(ysize, FramesCount*sizeof(Word));
  241. GetMem(FrameSize,FramesCount*sizeof(Word));
  242. cPage:=0;
  243. cOffs:=0;
  244. for i := 0 to FileCount-1 do
  245. begin
  246. BlockRead(F,FrameSize^[i],2);
  247. BlockRead(F,xsize^[i],2);inc(xsize^[i]);
  248. BlockRead(F,ysize^[i],2);inc(ysize^[i]);
  249. Seek(F,FilePos(F)-4);
  250. if ((FrameSize^[i]+cOffs) shr 14) > 3 then begin inc(cPage); cOffs:=0; end;
  251. Frames.Page^[i] := cPage;
  252. Frames.Offs^[i] := cOffs;
  253. if not MapEMMMemory(Frames.Mem,cPage,cPage+(FrameSize^[i]+cOffs) shr 14) Then
  254. Error('Error mapping tRAH frame');
  255. AbsAddr := Ptr(SegEMMFrame,cOffs);
  256. BlockRead(F,AbsAddr^,FrameSize^[i]);
  257. Masks.Page^[i] := cPage;
  258. Masks.Offs^[i] := cOffs;
  259. if not MapEMMMemory(Masks.Mem,cPage,cPage+(FrameSize^[i]+cOffs) shr 14) then
  260. Error('Error mapping tRAH mask');
  261. AbsAddr := Ptr(SegEMMFrame,cOffs);
  262. BlockRead(F,AbsAddr^,FrameSize^[i]);
  263. Inc(cOffs, FrameSize^[i]);
  264. Inc(cPage, cOffs shr 14);
  265. cOffs := cOffs and $3FFF;
  266. end;
  267. A.X := -(xsize^[0] shr 1);
  268. B.X := xsize^[0] shr 1;
  269. A.Y := -(ysize^[0] shr 1);
  270. B.Y := ysize^[0] shr 1;
  271. for i := FileCount to FramesCount-1 do
  272. begin
  273. Frames.Page^[i] := Frames.Page^[FramesCount-i];
  274. Frames.Offs^[i] := Frames.Offs^[FramesCount-i];
  275. Masks.Page^[i] := Masks.Page^[FramesCount-i];
  276. Masks.Offs^[i] := Masks.Offs^[FramesCount-i];
  277. FrameSize^[i] := FrameSize^[FramesCount-i];
  278. xsize^[i] := xsize^[FramesCount-i];
  279. ysize^[i] := ysize^[FramesCount-i];
  280. end;
  281. Close(F);
  282. CurFrame := 0;
  283. end;{tRAH.Init}
  284. {----}
  285. Function tRAH.Inside;
  286. begin
  287. with Params.pos do
  288. Inside := (aPos.x > A.X+X) and (aPos.x < B.X+X) and
  289. (aPos.y > A.y+y) and (aPos.y < B.y+y);
  290. end;{tRAH.Inside}
  291. {----------------------}
  292. Procedure tRAH.Frame;
  293. begin
  294. if started then
  295. begin
  296. with Params do begin
  297. Speed.x := Speed.x+Accel.x*t*TIME_FACTOR;
  298. Speed.y := Speed.y+Accel.y*t*TIME_FACTOR;
  299. Pos.x := Pos.x + Speed.X*t*TIME_FACTOR;
  300. Pos.y := Pos.y + Speed.y*t*TIME_FACTOR;
  301. if Pos.x > FIELD_X then
  302. World^.Gone(@Self);
  303. end;
  304. LocTime := LocTime + t;
  305. inc(FrameTime,t);
  306. if LocTime > NextTrap then
  307. begin
  308. DropTraps(CountBase + random(Countvar)-(countvar shr 1));
  309. NextTrap := LocTime + TrapBase + random(TrapVar) - (TrapVar shr 1);
  310. end;
  311. end;
  312. end;{tRAH.Frame}
  313. {-----}
  314. Procedure tRAH.DropTraps;
  315. var
  316. aNewTrap : pTrap;
  317. i : byte;
  318. nspeed : real;
  319. nangle : integer;
  320. begin
  321. Randomize;
  322. for i := 1 to aCount do
  323. begin
  324. nangle := random(360);
  325. nspeed := speedBase + random*SpeedVar - (SpeedVar shr 1);
  326. New(aNewTrap,Init('trap.dat',Params.pos,nspeed,GLOB_G,nangle,Zorder+random(11)-5));
  327. World^.AddObject(aNewTrap);
  328. end;
  329. end;{tRAH.DropTrap}
  330. {----}
  331. Procedure tRAH.Draw;
  332. var
  333. Top,Left : word;
  334. AbsMem : pointer;
  335. begin
  336. Left := round(Params.Pos.x-(xsize^[CurFrame] shr 1));
  337. Top := SIZE_Y-round(Params.Pos.y+(ysize^[CurFrame] shr 1));
  338. if (Top<TRES_LY) or ((Top+ysize^[CurFrame])>=TRES_MY) or
  339. (Left<TRES_LX) or ((Left+xsize^[CurFrame])>=TRES_MX) then
  340. exit;
  341. if not MapEMMMemory(Masks.Mem,Masks.Page^[CurFrame],
  342. Masks.Page^[CurFrame]+(FrameSize^[CurFrame]+Masks.Offs^[CurFrame]) shr 14) then
  343. Error('Error mapping memory for mask while drawing tRAH');
  344. AbsMem := Ptr(SegEMMFrame,Masks.Offs^[CurFrame]);
  345. PutImage(Left,Top,AbsMem^,AndPut);
  346. if not MapEMMMemory(Frames.Mem,Frames.Page^[CurFrame],
  347. Frames.Page^[CurFrame]+(FrameSize^[CurFrame]+Frames.Offs^[CurFrame]) shr 14) then
  348. Error('Error mapping memory for frame while drawing tRAH');
  349. AbsMem := Ptr(SegEMMFrame,Frames.Offs^[CurFrame]);
  350. PutImage(Left,Top,AbsMem^,OrPut);
  351. CurFrame := (CurFrame+FrameTime div FPS) mod FramesCount;
  352. FrameTime := FrameTime mod FPS;
  353. end;{tRAH.Draw}
  354. {----}
  355. Destructor tRAH.Done;
  356. begin
  357. FreeEMM(Frames.Mem);
  358. FreeEMM(Masks.Mem);
  359. FreeMem(Frames.page,FramesCount*sizeof(word));
  360. FreeMem( Masks.page,FramesCount*sizeof(word));
  361. FreeMem(Frames.Offs,FramesCount*sizeof(word));
  362. FreeMem( Masks.Offs,FramesCount*sizeof(word));
  363. FreeMem(FrameSize, FramesCount*sizeof(Word));
  364. FreeMem(xsize, FramesCount*sizeof(Word));
  365. FreeMem(ysize, FramesCount*sizeof(Word));
  366. Inherited Done;
  367. end; {tRAH.Done}
  368. {-------------------------------------------------}
  369. { Second object - rocket earth-air Stinger (hand-made) :) }
  370. Constructor tSting.Init;
  371. var
  372. i : byte;
  373. F : FILE;
  374. cPage, cOffs : word;
  375. AbsMem : pointer;
  376. begin
  377. Inherited Init;
  378. ObjType := 'Stinger';
  379. Params := aPar;
  380. ZOrder := zOrd;
  381. dAngle := adAng;
  382. GetAngle;
  383. Nose.x:=Params.pos.x + xsize^[0]/2*cos(Angle/M_360_2PI);
  384. Nose.y:=Params.pos.y + xsize^[0]/2*sin(Angle/M_360_2PI);
  385. Assign(F,AnimDat);
  386. {$I-}
  387. Reset(F,1);
  388. If IOResult <> 0 then
  389. Error('Error opening animation library for Stinger');
  390. {$I+}
  391. BlockRead(F,FramesCount,2);
  392. GetMem(Frames.Page,FramesCount*sizeof(word));
  393. GetMem(Frames.Offs,FramesCount*sizeof(word));
  394. GetMem(xsize, FramesCount*sizeof(Word));
  395. GetMem(ysize, FramesCount*sizeof(Word));
  396. GetMem(FrameSize, FramesCount*sizeof(Word));
  397. if not TestAllocEMM(FileSize(F)+1 shl 13) then
  398. begin
  399. CloseGraph;
  400. WriteLn('Sorry, not enough EMM memory, need ',FileSize(F)+1 shl 13,' get ',MaxEMM);
  401. Halt(255);
  402. end;
  403. if not AllocEMM(FileSize(F)+1 shl 13,Frames.Mem) then
  404. Error('Error while allocating EMS memory for Stinger');
  405. cPage:=0;cOffs:=0;
  406. for i := 0 to FramesCount-1 do
  407. begin
  408. BlockRead(F,FrameSize^[i],2);
  409. BlockRead(F,xsize^[i],2);inc(xsize^[i]);
  410. BlockRead(F,ysize^[i],2);inc(ysize^[i]);
  411. Seek(F,FilePos(F)-4);
  412. if ((FrameSize^[i]+cOffs) shr 14) > 3 then begin inc(cPage); cOffs:=0; end;
  413. Frames.Page^[i]:=cPage;
  414. Frames.Offs^[i]:=cOffs;
  415. if not MapEMMMemory(Frames.Mem,cPage,cPage + (FrameSize^[i]+cOffs) shr 14) then
  416. Error('Error mapping memory for frame while reading stinger');
  417. AbsMem := Ptr(SegEMMFrame,cOffs);
  418. BlockRead(F,AbsMem^,FrameSize^[i]);
  419. Inc(cOffs, FrameSize^[i]);
  420. Inc(cPage, cOffs shr 14);
  421. cOffs := cOffs and $3FFF;
  422. end;
  423. Close(F);
  424. CurFrame := (Angle div (360 div FramesCount));
  425. if CurFrame < 0 then inc(curframe,FramesCount);
  426. end;{tSting.Init}
  427. {----}
  428. Procedure tSting.ChangeAngle(dA : integer);
  429. var
  430. speed : real;
  431. begin
  432. Angle := dA;
  433. while Angle < 0 do Inc(Angle,360);
  434. while Angle > 360 do dec(Angle,360);
  435. speed := sqrt(sqr(params.speed.x)+sqr(params.speed.y));
  436. Params.Speed.x := Speed * cos(Angle/M_360_2PI);
  437. Params.Speed.y := Speed * sin(Angle/M_360_2PI);
  438. end;
  439. {---------------}
  440. Procedure tSting.FindTarget;
  441. var
  442. ang:integer;
  443. dist : real;
  444. ob : PWorldObject;
  445. begin
  446. ang:=-ada;
  447. ob := World^.Radar(@Self,HEAT,ang,-ang,dist);
  448. if (ob <> nil) then
  449. begin
  450. ChangeAngle(ang);
  451. end
  452. else GetAngle;
  453. ang:=-30;
  454. ob := World^.Radar(@Self,HEAT,ang,-ang,dist);
  455. if ob = nil then exit;
  456. if PDrawable(ob)^.Inside(Nose) then
  457. begin
  458. World^.Explosion(ob^.params.pos);
  459. World^.Gone(@Self);
  460. World^.Gone(ob);
  461. if ob^.objtype = 'RAH-66' then World^.Message('You Win',4,LightRed)
  462. else World^.Message('You Lose',4,LightGray);
  463. end;
  464. end;{tSting.FindTarget}
  465. {--------}
  466. Procedure tSting.GetAngle;
  467. begin
  468. if Params.Speed.x = 0 then
  469. begin
  470. if Params.Speed.y > 0 then Angle := 90 else
  471. Angle := 270;
  472. end else
  473. Angle := round(M_360_2PI*ArcTan(Params.Speed.y/Params.Speed.x));
  474. if Angle < 0 then Inc(Angle,360);
  475. if Params.Speed.X < 0 then Inc(Angle, 180);
  476. if Angle >= 360 then Dec(Angle, 360);
  477. end;{tSting.GetAngle}
  478. {------}
  479. Procedure tSting.Frame;
  480. begin
  481. if started then
  482. begin
  483. with Params do begin
  484. Speed.x := Speed.x+Accel.x*t*TIME_FACTOR;
  485. Speed.y := Speed.y+Accel.y*t*TIME_FACTOR;
  486. FindTarget(dAngle);
  487. Pos.x := Pos.x + Speed.X*t*TIME_FACTOR;
  488. Pos.y := Pos.y + Speed.y*t*TIME_FACTOR;
  489. if not ((Pos.X>TRES_LX) and (Pos.X<TRES_MX) and
  490. (Pos.Y>TRES_LY) and (Pos.Y<TRES_MY)) then
  491. if (((Pos.x>TRES_MX) and ((Speed.X>0) or (Accel.X>0))) or
  492. ((Pos.x<TRES_LX) and ((Speed.X<0) or (Accel.X<0))) or
  493. ((Pos.y>TRES_MY) and ((Speed.Y>0) or (Accel.Y>0))) or
  494. ((Pos.y<TRES_LY) and ((Speed.Y<0) or (Accel.Y<0))))
  495. then
  496. World^.Gone(@Self);
  497. LocTime := LocTime + t;
  498. end;
  499. end;
  500. end;{tSting.Frame}
  501. {----}
  502. Procedure tSting.Draw;
  503. var
  504. Top,Left : integer;
  505. x12,x22,y12,y22 : real;
  506. AbsMem : pointer;
  507. begin
  508. CurFrame := (Angle div (360 div FramesCount));
  509. if CurFrame < 0 then inc(curframe,FramesCount);
  510. Left := round(Params.Pos.x-(xsize^[CurFrame] shr 1));
  511. Top := SIZE_Y-round(Params.Pos.y+(ysize^[CurFrame] shr 1));
  512. if (Top<TRES_LY) or ((Top+ysize^[CurFrame])>=TRES_MY) or
  513. (Left<TRES_LX) or ((Left+xsize^[CurFrame])>=TRES_MX) then
  514. exit;
  515. if not MapEMMMemory(Frames.Mem,Frames.Page^[CurFrame],
  516. Frames.Page^[CurFrame] + (FrameSize^[CurFrame]+Frames.Offs^[CurFrame]) shr 14) then
  517. Error('Error mapping memory for frame while drawing stinger');
  518. AbsMem := Ptr(SegEMMFrame,Frames.Offs^[CurFrame]);
  519. PutImage(Left,Top,AbsMem^,AndPut);
  520. Nose.x:=params.pos.x + xsize^[0]/2.1*cos(Angle/M_360_2PI);
  521. Nose.y:=params.pos.y + xsize^[0]/2.1*sin(Angle/M_360_2PI);
  522. x12:=Nose.x + 50*cos((Angle-dAngle)/M_360_2PI);
  523. y12:=Nose.y + 50*sin((Angle-dAngle)/M_360_2PI);
  524. x22:=Nose.x + 50*cos((Angle+dAngle)/M_360_2PI);
  525. y22:=Nose.y + 50*sin((Angle+dAngle)/M_360_2PI);
  526. SetColor(Black);
  527. Line(round(Nose.x),SIZE_Y-round(Nose.y),round(x12),SIZE_Y-round(y12));
  528. Line(round(Nose.x),SIZE_Y-round(Nose.y),round(x22),SIZE_Y-round(y22));
  529. end;{tSting.Draw}
  530. {----}
  531. Destructor tSting.Done;
  532. begin
  533. FreeEMM(Frames.Mem);
  534. FreeMem(Frames.Page,FramesCount*sizeof(word));
  535. FreeMem(Frames.Offs,FramesCount*sizeof(word));
  536. FreeMem(FrameSize, FramesCount*sizeof(Word));
  537. FreeMem(xsize, FramesCount*sizeof(Word));
  538. FreeMem(ysize, FramesCount*sizeof(Word));
  539. Inherited Done;
  540. end; {tSting.Done}
  541. {-------------------------------------------------}
  542. { Third object - just explosion}
  543. Constructor tExpl.Init;
  544. var
  545. i : byte;
  546. F : FILE;
  547. cPage,cOffs : word;
  548. AbsMem : Pointer;
  549. begin
  550. Inherited Init;
  551. ObjType := 'EXPL';
  552. LifeTime := aLifeTime;
  553. Params.pos := aPos;
  554. ZOrder := zOrd;
  555. Assign(F,AnimDat);
  556. {$I-}
  557. Reset(F,1);
  558. If IOResult <> 0 then
  559. Error('Error opening animation library for exposion');
  560. {$I+}
  561. BlockRead(F,FramesCount,2);
  562. GetMem(Frames.Page,FramesCount*sizeof(Word));
  563. GetMem( Masks.Page,FramesCount*sizeof(Word));
  564. GetMem(Frames.Offs,FramesCount*sizeof(Word));
  565. GetMem( Masks.Offs,FramesCount*sizeof(Word));
  566. GetMem(xsize, FramesCount*sizeof(Word));
  567. GetMem(ysize, FramesCount*sizeof(Word));
  568. GetMem(FrameSize, FramesCount*sizeof(Word));
  569. if not TestAllocEMM(FileSize(F)+1 shl 13) then
  570. begin
  571. CloseGraph;
  572. WriteLn('Sorry, not enough EMM memory, need ',FileSize(F)+1 shl 13,' get ',MaxEMM);
  573. Halt(255);
  574. end;
  575. if not AllocEMM(FileSize(F) shr 1+1 shl 13, Frames.Mem) then
  576. Error('Error allocating memory for explosion frames');
  577. if not AllocEMM(FileSize(F) shr 1+1 shl 13, Masks.Mem) then
  578. Error('Error allocating memory for explosion masks');
  579. cPage := 0;
  580. cOffs := 0;
  581. for i := 0 to FramesCount-1 do
  582. begin
  583. BlockRead(F,FrameSize^[i],2);
  584. BlockRead(F,xsize^[i],2);inc(xsize^[i]);
  585. BlockRead(F,ysize^[i],2);inc(ysize^[i]);
  586. Seek(F,FilePos(F)-4);
  587. if ((FrameSize^[i]+cOffs) shr 14) > 3 then begin inc(cPage); cOffs:=0; end;
  588. Frames.Page^[i]:=cPage;
  589. Frames.Offs^[i]:=cOffs;
  590. if not MapEMMMemory(Frames.Mem,cPage,cPage+(FrameSize^[i] + cOffs) shr 14) then
  591. Error('Error mapping memory for explosion''s frame while reading');
  592. AbsMem := Ptr(SegEMMFrame,cOffs);
  593. BlockRead(F,AbsMem^,FrameSize^[i]);
  594. Masks.Page^[i]:=cPage;
  595. Masks.Offs^[i]:=cOffs;
  596. if not MapEMMMemory(Masks.Mem,cPage,cPage+(FrameSize^[i] + cOffs) shr 14) then
  597. Error('Error mapping memory for explosion''s mask while reading');
  598. AbsMem := Ptr(SegEMMFrame,cOffs);
  599. BlockRead(F,AbsMem^,FrameSize^[i]);
  600. Inc(cOffs, FrameSize^[i]);
  601. Inc(cPage, cOffs shr 14);
  602. cOffs := cOffs and $3FFF;
  603. end;
  604. Close(F);
  605. CurFrame := 0;
  606. end;{tExpl.Init}
  607. {----}
  608. Procedure tExpl.Frame;
  609. begin
  610. if started then begin
  611. LocTime := LocTime + t;
  612. CurFrame := round((LocTime / LifeTime) * (FramesCount-1)) mod FramesCount;
  613. if LocTime >= LifeTime then World^.Gone(@Self);
  614. end;
  615. end;{tRAH.Frame}
  616. {----}
  617. Procedure tExpl.Draw;
  618. var
  619. Top,Left : word;
  620. AbsMem : pointer;
  621. begin
  622. Left := round(Params.Pos.x-(xsize^[CurFrame] shr 1));
  623. Top := SIZE_Y-round(Params.Pos.y+(ysize^[CurFrame] shr 1));
  624. if (Top<TRES_LY) or ((Top+ysize^[CurFrame])>=TRES_MY) or
  625. (Left<TRES_LX) or ((Left+xsize^[CurFrame])>=TRES_MX) then
  626. exit;
  627. if not MapEMMMemory(Masks.Mem,Masks.Page^[CurFrame],
  628. Masks.Page^[CurFrame] + (FrameSize^[CurFrame]+Masks.Offs^[CurFrame]) shr 14) then
  629. Error('Error mapping memory for explosion''s mask while drawing');
  630. AbsMem := Ptr(SegEMMFrame,Masks.Offs^[CurFrame]);
  631. PutImage(Left,Top,AbsMem^,AndPut);
  632. if not MapEMMMemory(Frames.Mem,Frames.Page^[CurFrame],
  633. Frames.Page^[CurFrame] +(FrameSize^[CurFrame] + Frames.Offs^[CurFrame]) shr 14) then
  634. Error('Error mapping memory for explosion''s frame while drawing');
  635. AbsMem := Ptr(SegEMMFrame,Frames.Offs^[CurFrame]);
  636. PutImage(Left,Top,AbsMem^,OrPut);
  637. end;{tExpl.Draw}
  638. {----}
  639. Destructor tExpl.Done;
  640. begin
  641. FreeEMM(Frames.Mem);
  642. FreeEMM( Masks.Mem);
  643. FreeMem(Frames.Page,FramesCount*sizeof(Word));
  644. FreeMem(Masks .Page,FramesCount*sizeof(Word));
  645. FreeMem(Frames.Offs,FramesCount*sizeof(Word));
  646. FreeMem(Masks .Offs,FramesCount*sizeof(Word));
  647. FreeMem(FrameSize, FramesCount*sizeof(Word));
  648. FreeMem(xsize, FramesCount*sizeof(Word));
  649. FreeMem(ysize, FramesCount*sizeof(Word));
  650. Inherited Done;
  651. end; {tExpl.Done}
  652. { Fourth object - Heat Trap }
  653. Constructor tTrap.Init(AnimDat:string;var aPos:vector; var aSpeed,aG : real; aAng:integer;zOrd:byte);
  654. var
  655. F:file;
  656. i:integer;
  657. begin
  658. Inherited Init;
  659. ObjType := 'HeatTrap';
  660. Flag := Flag + [HEAT];
  661. Params.Pos := aPos;
  662. Params.Accel.x:=0;
  663. Params.Accel.y:=-aG;
  664. Params.Speed.x := aSpeed * cos (aAng/M_360_2PI);
  665. Params.Speed.y := aSpeed * sin (aAng/M_360_2PI);
  666. ZOrder := zOrd;
  667. Assign(F,AnimDat);
  668. {$I-}
  669. Reset(F,1);
  670. If IOResult <> 0 then
  671. begin
  672. CloseGraph;
  673. WriteLn('Error opening animation library for Heat Trap (',AnimDat,')');
  674. Halt(255);
  675. end;
  676. {$I+}
  677. BlockRead(F,FramesCount,2);
  678. GetMem(MFrames, FramesCount*sizeof(Pointer));
  679. GetMem(xsize, FramesCount*sizeof(Word));
  680. GetMem(ysize, FramesCount*sizeof(Word));
  681. GetMem(FrameSize, FramesCount*sizeof(Word));
  682. if (MaxAvail < FileSize(F)) then
  683. begin
  684. CloseGraph;
  685. WriteLn('Sorry, not enough conv memory, need ',FileSize(F),' get ',MaxAvail);
  686. Halt(255);
  687. end;
  688. for i := 0 to FramesCount-1 do
  689. begin
  690. BlockRead(F,FrameSize^[i],2);
  691. if MaxAvail < FrameSize^[i] then
  692. begin
  693. CloseGraph;
  694. WriteLn('Sorry, not enough memory, need ',FrameSize^[i],' get ',MaxAvail);
  695. Halt(255);
  696. end;
  697. GetMem(MFrames^[i],FrameSize^[i]);
  698. BlockRead(F,xsize^[i],2);inc(xsize^[i]);
  699. BlockRead(F,ysize^[i],2);inc(ysize^[i]);
  700. Seek(F,FilePos(F)-4);
  701. BlockRead(F,MFrames^[i]^,FrameSize^[i]);
  702. end;
  703. Close(F);
  704. end;
  705. {----------}
  706. Function tTrap.Inside;
  707. begin
  708. with params.pos do
  709. Inside := (sqr(aPos.x-x) + sqr(aPos.y-y)) <= sqr(xsize^[0] shr 1);
  710. end;{tTrap.Inside}
  711. {---------------------}
  712. Procedure tTrap.Frame(t : longint);
  713. begin
  714. with Params do begin
  715. Speed.x := Speed.x+Accel.x*t*TIME_FACTOR;
  716. Speed.y := Speed.y+Accel.y*t*TIME_FACTOR;
  717. Pos.x := Pos.x + Speed.X*t*TIME_FACTOR;
  718. Pos.y := Pos.y + Speed.y*t*TIME_FACTOR;
  719. if not ((Pos.X>TRES_LX) and (Pos.X<TRES_MX) and
  720. (Pos.Y>TRES_LY) and (Pos.Y<TRES_MY)) then
  721. if (((Pos.x>TRES_MX) and ((Speed.X>0) or (Accel.X>0))) or
  722. ((Pos.x<TRES_LX) and ((Speed.X<0) or (Accel.X<0))) or
  723. ((Pos.y>TRES_MY) and ((Speed.Y>0) or (Accel.Y>0))) or
  724. ((Pos.y<TRES_LY) and ((Speed.Y<0) or (Accel.Y<0))))
  725. then
  726. World^.Gone(@Self);
  727. end;
  728. LocTime := LocTime + t;
  729. end;
  730. Procedure tTrap.Draw;
  731. var
  732. Top,Left : integer;
  733. begin
  734. Left := round(Params.Pos.x-(xsize^[CurFrame] shr 1));
  735. Top := SIZE_Y-round(Params.Pos.y+(ysize^[CurFrame] shr 1));
  736. if (Top<TRES_LY) or ((Top+ysize^[CurFrame])>=TRES_MY) or
  737. (Left<TRES_LX) or ((Left+xsize^[CurFrame])>=TRES_MX) then
  738. exit;
  739. PutImage(Left,Top,MFrames^[CurFrame]^,AndPut);
  740. end;{tTrap.Draw}
  741. {------------}
  742. Destructor tTrap.Done;
  743. var i : byte;
  744. begin
  745. for i := 0 to FramesCount-1 do
  746. FreeMem(MFrames^[i],FrameSize^[i]);
  747. FreeMem(MFrames,FramesCount*sizeof(Pointer));
  748. FreeMem(FrameSize,FramesCount*sizeof(Word));
  749. FreeMem(xsize,FramesCount*sizeof(Word));
  750. FreeMem(ysize,FramesCount*sizeof(Word));
  751. Inherited Done;
  752. end;
  753. { ------ WOLRD OBJECT ( управляет всем ) --------}
  754. Constructor TWorld.Init;
  755. var
  756. F: FILE;
  757. k:byte;
  758. cPage,cOffs : word;
  759. AbsMem : Pointer;
  760. begin
  761. New(WObjects); {Init Dummy Element in Objectlist}
  762. WObjects^.Next:=nil;
  763. WObjects^.O:=nil;
  764. MSG := '';
  765. ToGone:=nil;
  766. Ending := false; {Global variable showing need to end}
  767. if aBGN <> '' then
  768. begin
  769. Assign(F,aBGN);
  770. {$I-}
  771. Reset(F,1);
  772. If IOResult <> 0 then exit;
  773. {$I+}
  774. BlockRead(F,FrameCount,1);
  775. GetMem(Background.Page, FrameCount*sizeof(Word));
  776. GetMem(Background.Offs, FrameCount*sizeof(Word));
  777. GetMem(xpos, FrameCount*sizeof(word));
  778. GetMem(ypos, FrameCount*sizeof(word));
  779. GetMem(xsize, FrameCount*sizeof(word));
  780. GetMem(ysize, FrameCount*sizeof(word));
  781. GetMem(FrameSize, FrameCount*sizeof(word));
  782. if not TestAllocEMM(FileSize(F)+1 shl 13) then
  783. begin
  784. CloseGraph;
  785. WriteLn('Sorry, not enough EMM memory, need ',FileSize(F)+1 shl 13,' get ',MaxEMM);
  786. Halt(255);
  787. end;
  788. if not AllocEMM(FileSize(F)+1 shl 13, BackGround.Mem) then
  789. Error('Error allocating memory for background');
  790. cPage:=0;
  791. cOffs:=0;
  792. for k:=0 to FrameCount-1 do
  793. begin
  794. BlockRead(F,FrameSize^[k],2);
  795. BlockRead(F,xPos^[k],2);
  796. BlockRead(F,yPos^[k],2);
  797. BlockRead(F,xSize^[k],2);
  798. BlockRead(F,ySize^[k],2);
  799. if ((FrameSize^[k]+cOffs) shr 14) > 3 then
  800. begin
  801. inc(cPage);
  802. cOffs:=0;
  803. end;
  804. if not MapEMMMemory(Background.mem,cPage,cPage + (FrameSize^[k]+cOffs) shr 14) then
  805. Error('Error mapping memory for background');
  806. AbsMem := Ptr(SegEMMFrame,cOffs);
  807. BlockRead(F,AbsMem^,FrameSize^[k]);
  808. Background.Page^[k]:=cPage;
  809. background.offs^[k]:=cOffs;
  810. DrawSprite12H(xpos^[k],ypos^[k],xsize^[k],ysize^[k],CurPage,AbsMem);
  811. Inc(cOffs, FrameSize^[k]);
  812. Inc(cPage, cOffs shr 14);
  813. cOffs := cOffs and $3FFF;
  814. end;
  815. Close(F);
  816. end
  817. else
  818. begin
  819. BackGround.Page := nil;
  820. BackGround.Offs := nil;
  821. end;
  822. end;{TWorld.Init}
  823. {------}
  824. Function TWorld.Radar(aSelf:PWorldObject;aFlg:FLAG_ENUM;var a0:integer;a1:integer;var aDist:real):PWorldObject;
  825. var
  826. mo : PWorldObject;
  827. md,a,b : real;
  828. Ang : integer;
  829. aa : integer;
  830. c : PWOsList;
  831. begin
  832. Radar := nil;
  833. if (aSelf = nil) or (WObjects^.next = nil) then exit;
  834. md := 1E30;
  835. mo := nil;
  836. c:=Wobjects^.next;
  837. while (c<>nil) do
  838. begin
  839. if (aFLG in c^.o^.flag) then
  840. begin
  841. a:=c^.o^.params.pos.x-aSelf^.params.pos.x;
  842. b:=c^.o^.params.pos.y-aSelf^.params.pos.y;
  843. {<Calc angle>}
  844. if abs(a) < 0.001 then
  845. begin
  846. if b > 0 then Ang := 90 else
  847. Ang := 270;
  848. end else
  849. Ang := round(M_360_2PI*ArcTan(b/a));
  850. if Ang < 0 then Inc(Ang,360);
  851. if a < 0 then Inc(Ang, 180);
  852. if Ang >= 360 then Dec(Ang, 360);
  853. {</Calc angle>}
  854. Ang := aSelf^.Angle - Ang;
  855. if Ang > 180 then Ang := 360 - Ang;
  856. if Ang <-180 then Ang :=-360 - Ang;
  857. if (Ang>a0) and (Ang<a1) then
  858. begin
  859. if a*a+b*b < md then
  860. begin
  861. aa := ang;
  862. md := a*a+b*b;
  863. mo := c^.o;
  864. end;
  865. end;
  866. end;
  867. c:=c^.next;
  868. end;
  869. Radar := mo;
  870. a0 := aSelf^.Angle - aa;
  871. aDist := md;
  872. end;{Radar}
  873. {---------}
  874. Procedure TWorld.Explosion(aPos:vector);
  875. var
  876. aNew : PExpl;
  877. begin
  878. New(aNew,Init('expls.dat',round((random(5)+5)/TIME_FACTOR),aPos,255));
  879. AddObject(aNew);
  880. aNew^.Started := true;
  881. end;{TWorld.Explosion}
  882. {---------}
  883. Function TWorld.AddObject(aOb : PWorldObject):boolean;
  884. var
  885. N,C : PWOsList;
  886. begin
  887. New(N);
  888. N^.O := aOb;
  889. n^.Next:=NIL;
  890. aOb^.World := @Self;
  891. c:=WObjects; {Иниц. "бегунок"}
  892. while (c^.next <> nil) and {Пока не последний эл-т,}
  893. (aOb^.ZORDER > c^.next^.o^.ZORDER) {и выполняется отсортированность}
  894. do c:=c^.next;
  895. n^.next := c^.next; {Вставляем наш эл-т между "бегунком"}
  896. c^.next := n; {и следующим за ним}
  897. AddObject:=true;
  898. end;
  899. {------}
  900. Procedure TWorld.Gone;
  901. var
  902. N : PWOsList;
  903. begin
  904. New(N);
  905. N^.O := aObj;
  906. n^.Next:=ToGone;
  907. ToGone := n;
  908. end;
  909. {------}
  910. Function TWorld.RemoveObject(aOb:PWorldObject):boolean;
  911. var
  912. c,g : PWOsList;
  913. begin
  914. C:=WObjects;
  915. while (C^.next <> nil) and (c^.next^.o <> aOb) do c:=c^.next;
  916. if c^.next <> nil then
  917. begin
  918. RemoveObject:=true;
  919. g := c^.next;
  920. c^.next := g^.next;
  921. Dispose(g^.O,Done);
  922. Dispose(g);
  923. end
  924. else
  925. RemoveObject := false;
  926. end;{TWorld.RemoveObject}
  927. {----------------------------}
  928. Procedure TWorld.Frame;
  929. var
  930. c,c2 : PWOsList;
  931. ob : PDrawable;
  932. begin
  933. c := ToGone; {Killing dead objects}
  934. while c<>nil do
  935. begin
  936. RemoveObject(c^.o);
  937. c2:=c^.next;
  938. dispose(c);
  939. c:=c2;
  940. end;
  941. ToGone:=nil;
  942. c:=WObjects^.Next;
  943. if c = nil then Ending:=true;
  944. while c <> nil do
  945. begin
  946. C^.O^.Frame(t);
  947. C:=C^.next;
  948. end;
  949. end;{TWorld.Frame}
  950. {----------------------------}
  951. Procedure TWorld.Message;
  952. begin
  953. MSG := aS;
  954. MSGSize:=aSize;
  955. MSGColor:=aColor;
  956. end;{TWorld.Message}
  957. {----------------------------}
  958. Procedure TWorld.Draw;
  959. var
  960. c : PWOsList;
  961. k : byte;
  962. AbsMem : pointer;
  963. begin
  964. for k := 0 to FrameCount-1 do
  965. begin
  966. if not MapEMMMemory(Background.mem,background.page^[k],
  967. background.page^[k] + (FrameSize^[k]+background.offs^[k]) shr 14) then
  968. Error('Wrror mappinf memory for background while drawing');
  969. AbsMem := Ptr(SegEMMFrame,background.offs^[k]);
  970. DrawSprite12H(xpos^[k],ypos^[k],xsize^[k],ysize^[k],1-CurPage,AbsMem);
  971. end;
  972. If MSG <> '' then
  973. begin
  974. setColor(MSGColor);
  975. SetTextStyle(DefaultFont, HorizDir, MSGSize);
  976. SetTextJustify(CENTERTEXT,BOTTOMTEXT);
  977. OutTextXY(TRES_MX shr 1, TRES_MY,MSG);
  978. end;
  979. c:=WObjects^.Next;
  980. while c <> nil do
  981. begin
  982. if CAN_DRAW IN C^.O^.Flag then PDrawable(C^.O)^.Draw;
  983. C:=C^.next;
  984. end;
  985. end;{TWorld.Draw}
  986. {----------------------------}
  987. {----------------------------}
  988. Procedure TWorld.StartObjects;
  989. var
  990. c : PWOsList;
  991. begin
  992. c:=WObjects^.Next;
  993. while c <> nil do
  994. begin
  995. if CAN_DRAW IN C^.O^.Flag then
  996. if c^.o^.ObjType = aT then PDrawable(C^.O)^.Started := true;
  997. C:=C^.next;
  998. end;
  999. end;{TWorld.Draw}
  1000. {----------------------------}
  1001. Destructor TWorld.Done;
  1002. var
  1003. g:PWOsList;
  1004. i:byte;
  1005. begin
  1006. while WObjects <> nil do
  1007. begin
  1008. g := WObjects^.next;
  1009. if WObjects^.o <> nil then Dispose(WObjects^.o,Done);
  1010. Dispose(WObjecTs);
  1011. WObjects := g;
  1012. end;
  1013. while ToGone <> nil do
  1014. begin
  1015. g := ToGone^.next;
  1016. Dispose(ToGone^.o,Done);
  1017. Dispose(ToGone);
  1018. ToGone := g;
  1019. end;
  1020. if BackGround.Page <> nil then
  1021. begin
  1022. FreeEMM(Background.mem);
  1023. FreeMem(Background.Page,FrameCount*sizeof(Word));
  1024. FreeMem(Background.Offs,FrameCount*sizeof(word));
  1025. FreeMem(xpos,FrameCount*sizeof(word));
  1026. FreeMem(ypos,FrameCount*sizeof(word));
  1027. FreeMem(xsize,FrameCount*sizeof(word));
  1028. FreeMem(ysize,FrameCount*sizeof(word));
  1029. FreeMem(FrameSize,FrameCount*sizeof(word));
  1030. end;
  1031. end; {TWorld.Done}
  1032. {---------------------------------------------}
  1033. {------ OTHER PROCEDURES ---------------}
  1034. END.