Fixed audio playing
[kvidha.git] / kvidha.c
CommitLineData
02f87e18
FT
1#include <stdio.h>\r
2#include <memory.h>\r
3#include <malloc.h>\r
4#include <stdlib.h>\r
5#include <string.h>\r
6#include <math.h>\r
7#include <dirent.h>\r
8#include <SDL/SDL.h>\r
9\r
10#include "fileio.h"\r
11\r
12#define NUM_KEYS 9\r
13#define MAX_STACK 4096\r
14#define MAX_LINES 1000\r
15#define NUM_MASKS 1\r
16#define MAX_PIXELS 5000\r
17#define NUM_COLORS 256\r
18#define NUM_PLANES 2\r
19#define MAX_SOUNDS 64\r
20#define MAX_RASTERS 100\r
21#define NUM_SCRIPTS 5\r
22#define MAX_SPRITES 5000\r
23#define MAX_PLAYERS 16\r
24#define MAX_OBJECTS 3000\r
25#define NUM_WEAPONS 55\r
26#define MAX_SAMPLES 31\r
27#define MAX_OBJLISTS 16\r
28#define MAX_HITTESTS 100\r
29#define MAX_CHANNELS 12\r
30#define MAX_PATTERNS 128\r
31#define MAX_MENUITEMS 128\r
32#define SB_SIZE 1024\r
33#define PLAY_TIME 0\r
34#define SHOW_MAP 1\r
35#define CP_BLUR 0\r
36\r
37#define MAP_SHOOTABLE 1\r
38#define MAP_WALKABLE 2\r
39#define MAP_DESTROYABLE 4\r
40#define MAP_TEMPORARY 8\r
41\r
42typedef struct ColorType\r
43{\r
44 unsigned char B;\r
45 unsigned char G;\r
46 unsigned char R;\r
47 unsigned char Reserved;\r
48} Color;\r
49\r
50typedef struct PixelType\r
51{\r
52 float x;\r
53 float y;\r
54 float xv;\r
55 float yv;\r
56 unsigned long c;\r
57 unsigned char SetColor;\r
58 unsigned char Explode;\r
59 signed short Damage;\r
60 unsigned char Owner;\r
61 unsigned char Used;\r
62} Pixel;\r
63\r
64typedef struct CacheType\r
65{\r
66 unsigned short w;\r
67 unsigned short h;\r
68 unsigned char NumFrames;\r
69 unsigned char **Frames;\r
70 signed short *cx;\r
71 signed short *cy;\r
72 unsigned char AnimDelay;\r
73} Cache;\r
74\r
75typedef struct SpriteType\r
76{\r
77 signed short x;\r
78 signed short y;\r
79 signed char xv;\r
80 signed char yv;\r
81 unsigned char AnimCount;\r
82 unsigned char AnimTimer;\r
83 unsigned char AnimDelay;\r
84 unsigned char CurFrame;\r
85 unsigned char Template;\r
86 unsigned char Transparent;\r
87 unsigned char Used;\r
88} Sprite;\r
89\r
90typedef struct WeaponType\r
91{\r
92 unsigned short Class;\r
93 unsigned short ReloadDelay;\r
94 unsigned short FireDelay;\r
95 unsigned short Ammo;\r
96 unsigned short MaxClips;\r
97 unsigned long Name;\r
98 unsigned short NameLength;\r
99} Weapon;\r
100\r
101typedef struct PWeaponType\r
102{\r
103 unsigned short Weapon;\r
104 unsigned short ReloadTimer;\r
105 unsigned short FireTimer;\r
106 unsigned short AmmoLeft;\r
107 unsigned short NumClips;\r
108 signed short Vars[4];\r
109 unsigned char Used;\r
110} PWeapon;\r
111\r
112typedef struct PlayerType\r
113{\r
114 unsigned char Visual;\r
115 unsigned short VPointX1;\r
116 unsigned short VPointY1;\r
117 unsigned short VPointX2;\r
118 unsigned short VPointY2;\r
119 unsigned short AMeterX1;\r
120 unsigned short AMeterY1;\r
121 unsigned short AMeterX2;\r
122 unsigned short AMeterY2;\r
123 unsigned short LMeterX1;\r
124 unsigned short LMeterY1;\r
125 unsigned short LMeterX2;\r
126 unsigned short LMeterY2;\r
127 unsigned short lx, ly;\r
128 unsigned short kx, ky;\r
129 unsigned short cx, cy;\r
130 unsigned short Object;\r
131 unsigned short VPObject;\r
132 unsigned char Keys[NUM_KEYS];\r
133 unsigned char HeldKeys[NUM_KEYS];\r
134 unsigned short KeyCodes[NUM_KEYS];\r
135 unsigned char Left;\r
136 unsigned char Right;\r
137 unsigned char Up;\r
138 unsigned char Down;\r
139 unsigned char Change;\r
140 unsigned char Shoot;\r
141 unsigned char JustShot;\r
142 signed short CurWeapon;\r
143 float Angle;\r
144 float AngleVel;\r
145 unsigned char Dir;\r
146 unsigned long CrossColor;\r
147 signed short Kills;\r
148 signed short Lives;\r
149 signed short Health;\r
150 signed short MaxHealth;\r
151 signed short PVars[40];\r
152 struct MaskType\r
153 {\r
154 unsigned char *Buffer;\r
155 unsigned char Method;\r
156 unsigned char Effects[16];\r
157 } Masks[NUM_MASKS];\r
158 unsigned char Used;\r
159} Player;\r
160\r
161typedef struct ClassType\r
162{\r
163 unsigned char *Code;\r
164 unsigned short Scripts[NUM_SCRIPTS];\r
165 unsigned char TickDelay;\r
166 unsigned char Sprite;\r
167 unsigned char StartFrame;\r
168 unsigned char RunHitTests;\r
169 unsigned char TouchDelay;\r
170 unsigned char TransSprite;\r
171 signed short GravityMod;\r
172} Class;\r
173\r
174typedef struct ObjectType\r
175{\r
176 float x;\r
177 float y;\r
178 float xv;\r
179 float yv;\r
180 unsigned short Class;\r
181 unsigned char TickTimer;\r
182 signed short Variables[6];\r
183 unsigned short SpriteLink;\r
184 unsigned char TouchTimer;\r
185 unsigned char Owner;\r
186 unsigned char Used;\r
187} Object;\r
188\r
189typedef struct ObjectListType\r
190{\r
191 struct\r
192 {\r
193 unsigned short Object;\r
194 signed short x1, y1, x2, y2;\r
195 } Objects[MAX_OBJECTS + 1];\r
196 unsigned short NumObjects;\r
197 unsigned char Used;\r
198} ObjectList;\r
199\r
200typedef struct LineType\r
201{\r
202 signed short x1, y1;\r
203 signed short x2, y2;\r
204 unsigned long c1, c2;\r
205 unsigned short Transparent;\r
206 unsigned char UseSprite;\r
207 unsigned char AnimTimer;\r
208 unsigned char CurFrame;\r
209 unsigned char Used;\r
210} Line;\r
211\r
212typedef struct RasterType\r
213{\r
214 signed short x1, y1;\r
215 signed short x2, y2;\r
216 signed short x3, y3;\r
217 unsigned long Color;\r
218 unsigned char Transparent;\r
219 unsigned char Type;\r
220 unsigned char Used;\r
221} Raster;\r
222\r
223typedef struct PalType\r
224{\r
225 unsigned char r;\r
226 unsigned char g;\r
227 unsigned char b;\r
228} Pal;\r
229\r
230typedef struct SoundCacheType\r
231{\r
232 unsigned char *SoundBuffer;\r
233 unsigned long Length;\r
234} SoundCache;\r
235\r
236typedef struct SoundType\r
237{\r
238 unsigned short Sound;\r
239 unsigned char Playing;\r
240 unsigned char Repeat;\r
241 float Volume;\r
242 unsigned long Offset;\r
243 unsigned long Pitch;\r
244 unsigned long PitchError;\r
245} Sound;\r
246\r
247typedef struct ModSampleType\r
248{\r
249 unsigned long SampleLen;\r
250 unsigned char FineTune;\r
251 unsigned char Volume;\r
252 unsigned long LoopStart;\r
253 unsigned long LoopLen;\r
254 unsigned char Allocated;\r
255 signed char *Buffer;\r
256} ModSample;\r
257\r
258typedef struct ModChannelType\r
259{\r
260 unsigned short Period;\r
261 unsigned short CurPeriod;\r
262 unsigned short OldPeriod;\r
263 unsigned char Volume;\r
264 unsigned char CurVolume;\r
265 unsigned char Sample;\r
266 unsigned long Offset;\r
267 signed char LastSample;\r
268 unsigned char Looping;\r
269 unsigned char Playing;\r
270 unsigned long Reminder;\r
271 unsigned char Effect;\r
272 unsigned char Oscillation;\r
273 unsigned char OscAmp;\r
274 unsigned char OscFreq;\r
275 float OscOffset;\r
276 unsigned char OscWave;\r
277 unsigned char OscNoTrig;\r
278 union\r
279 {\r
280 struct TwinNibbleType\r
281 {\r
282 unsigned char n1 : 4;\r
283 unsigned char n2 : 4;\r
284 } Nibbles;\r
285 unsigned char b;\r
286 } EffectData;\r
287} ModChannel;\r
288\r
289typedef struct ModEventType\r
290{\r
291 unsigned short Period;\r
292 unsigned char Sample;\r
293 unsigned char Effect;\r
294 unsigned char EffectData;\r
295} ModEvent;\r
296\r
297struct CodeType\r
298{\r
299 signed short Parent, Size;\r
300 signed long Value;\r
301} Codes[4096];\r
302\r
303void SetMapPixel(unsigned short x, unsigned short y, unsigned long c, unsigned short Handle);\r
304unsigned long GetMapPixel(unsigned short x, unsigned short y, unsigned short Handle);\r
305void ShowMap(unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, unsigned short MapX, unsigned short MapY);\r
306void SetMode(unsigned char Mode);\r
307unsigned char SeekData(unsigned char *ID);\r
308unsigned char LoadSprite(unsigned char *ID, unsigned short CacheNum);\r
309unsigned short SpawnSprite(unsigned char Template, signed short x, signed short y, signed char xv, signed char yv, unsigned short AnimCount, unsigned char StartFrame, unsigned char Transparent);\r
310unsigned char Init(unsigned short *Result);\r
311void Terminate(void);\r
312void SpawnPixel(unsigned short x, unsigned short y, float xv, float yv, unsigned char Owner, unsigned char SetColor, unsigned char Explode, signed short Damage, unsigned long c);\r
313void ControlSprites(void);\r
314void ControlPixels(void);\r
315unsigned char ArgExist(unsigned short argc, unsigned char **argv, char *Match);\r
316void CopyToMap(signed short x, signed short y, unsigned char *Buffer, unsigned short w, unsigned short h, unsigned long bgc, unsigned char ColorPattern, unsigned char DestroyAll, unsigned short Attributes);\r
317void SpawnExplosion(signed short x, signed short y, unsigned char StartFrame, unsigned char Smokes, unsigned char Sound);\r
318unsigned short SpawnObject(unsigned short Class, unsigned char Owner, unsigned short x, unsigned short y, float xv, float yv);\r
319void ControlObjects(void);\r
320unsigned short WallAngle(unsigned short x, unsigned short y);\r
321void GetInputs(void);\r
322void DBPrint(unsigned char *Buffer, signed short x, signed short y, unsigned char bgc);\r
323void FontPrint(unsigned char *Buffer, signed short sx, signed short y, unsigned short bgc);\r
324unsigned char CollisionTest(signed short *x1, signed short *y1, signed short *x2, signed short *y2, unsigned char Pattern, unsigned char RunHitTests, unsigned short *ObjNum, unsigned char TestCache, unsigned short TestFrame);\r
325void DrawLine(signed short x1, signed short y1, signed short x2, signed short y2, unsigned long c1, unsigned long c2, unsigned char Method, unsigned char UseSprite);\r
326unsigned short CalcAngle(signed short x1, signed short y1, signed short x2, signed short y2);\r
327void AddHitTest(unsigned short ObjNum);\r
328void RemoveHitTest(unsigned short ObjNum);\r
329void HurtRadius(signed short x, signed short y, signed short StartDamage, signed short StopDamage, unsigned short StartDecRadius, unsigned short StopRadius, unsigned char Owner);\r
330void CollVel(signed short x, signed short y, float *xv, float *yv, unsigned char Attributes);\r
331void MessageBox(unsigned char *Buffer);\r
332void FillBuffer(void);\r
333unsigned char PlaySound(unsigned short Sound, unsigned char Repeat, unsigned short StartSound, unsigned short EndSound, unsigned long Pitch, float Volume);\r
334unsigned long MakeColor(unsigned char R, unsigned char G, unsigned char B);\r
335unsigned char MonoColor(unsigned long c);\r
336void __inline GetNextLineCoord(signed short *x, signed short *y, signed short *d, unsigned short dx, unsigned short dy, signed short xi, signed short yi);\r
337unsigned short GetObjectList(void);\r
338\r
339Pixel *Pixels[MAX_PIXELS];\r
340Cache **Caches;\r
341Sprite *Sprites[MAX_SPRITES];\r
342Object *Objects[MAX_OBJECTS];\r
343Player *Players[MAX_PLAYERS];\r
344PWeapon *PWeapons[MAX_PLAYERS][NUM_WEAPONS];\r
345ObjectList *ObjectLists[MAX_OBJLISTS];\r
346Sound Sounds[MAX_SOUNDS];\r
347SoundCache **SoundCaches;\r
348Class **Classes;\r
349Weapon **Weapons;\r
350unsigned char *Font;\r
351Line *Lines[MAX_LINES];\r
352Raster *Rasters[MAX_RASTERS];\r
353unsigned short HitTests[MAX_HITTESTS];\r
354unsigned char *Strings;\r
355Pal Palette[NUM_COLORS];\r
356unsigned char ColorInfo[NUM_COLORS];\r
357unsigned char *MenuItems[2][MAX_MENUITEMS];\r
358unsigned short MenuStack[16][3], MenuStackPos;\r
359KvidFile DataFile;\r
360float Gravity;\r
361SDL_Surface *VBuffer;\r
362unsigned char *DblBuffer;\r
363unsigned char FullScreen;\r
364signed short clip_x1, clip_x2;\r
365signed short clip_y1, clip_y2;\r
366unsigned short PagesFree;\r
367unsigned short BGSprite, BGFrame;\r
368unsigned char LevelFinished;\r
369unsigned short LevelWidth, LevelHeight;\r
370unsigned short MaxLW, MaxLH;\r
371unsigned char *LevelBuffer[NUM_PLANES];\r
372unsigned short NumSprites;\r
373unsigned short NumClasses;\r
374unsigned short NumWeapons;\r
375unsigned short NumSounds;\r
376unsigned char DebugMode;\r
377unsigned short FrameRate;\r
378unsigned short FontSprite;\r
379signed short Regs[32];\r
380signed short GameVars[40];\r
381unsigned char StackPos;\r
382unsigned short Stack[MAX_STACK];\r
383unsigned char SpecialKey;\r
384unsigned short AsciiTable[256];\r
385unsigned char AsciiTable2[256];\r
386float Sine[360], Cosine[360];\r
387float WaveForms[5][360];\r
388double PreSine[360], PreCosine[360];\r
389volatile unsigned char KeyTable[256];\r
390unsigned char RepeatKey;\r
391double RepeatData;\r
392unsigned char *TextBuffer;\r
393unsigned char *KeyboardBuffer;\r
394unsigned char *LevelFileName, *ModFileName;\r
395unsigned char LevelType;\r
396unsigned short DispLevelWidth, DispLevelHeight;\r
397unsigned short KeybWritePos, KeybReadPos;\r
398unsigned char *SoundBuffer;\r
399signed short *TestBuffer;\r
400unsigned char UseSound;\r
401unsigned char FreeSound;\r
402unsigned short DSPAddress;\r
403unsigned char DMAChannel;\r
404unsigned char IRQLine;\r
405unsigned char OldMask;\r
406unsigned char DMAPage, DMAAddress, DMACount;\r
407unsigned char PICAddress;\r
408unsigned char ReadyBuffer, BufferReady;\r
409unsigned char Bit16, Stereo;\r
410unsigned short SBSampleRate;\r
411unsigned char NumPlays;\r
412unsigned short *FontBuffer;\r
413unsigned char ModeInfo[256];\r
414unsigned char *MenuBuffer;\r
415unsigned char FogSprite;\r
416signed short FogX, FogY;\r
417void (*TransOps[5])(unsigned long *Bg, unsigned long Amount);\r
418ModSample Samples[MAX_SAMPLES];\r
419ModChannel Channels[MAX_CHANNELS];\r
420ModEvent *Patterns;\r
421unsigned char PatternOrder[MAX_PATTERNS];\r
422unsigned char ModPlaying, ModLen, ModRepeat, ModChannels;\r
423unsigned char ModPattern, ModRow;\r
424unsigned short ModOffset;\r
425unsigned char ModBPM, ModTPD;\r
426unsigned char MenuActive;\r
427unsigned short NumMenuItems, CurMenuItem, StartMenuItem, MenuID;\r
428unsigned char GameType;\r
429unsigned char BPP;\r
430unsigned char Paused;\r
431unsigned short CurNew, CurComp;\r
432\r
433#include "sdlmap.h"\r
434#include "newdb.h"\r
435#include "dblbuf.h"\r
436#include "executor.h"\r
437#include "sb.h"\r
438\r
439/*\r
440void NewKeyInt()\r
441{\r
442 unsigned char Data;\r
443\r
444 raw_key = inp(0x60);\r
445 Data = inp(0x61) | 0x82;\r
446 outp(0x61, Data);\r
447 outp(0x61, Data & 0x7F);\r
448 outp(0x20, 0x20);\r
449 if(raw_key < 128)\r
450 {\r
451 if(SpecialKey == 1)\r
452 {\r
453 KeyTable[raw_key + 128] = 1;\r
454 SpecialKey = 0;\r
455 RepeatKey = raw_key + 128;\r
456 RepeatData = 250;\r
457 KeyboardBuffer[KeybWritePos++] = raw_key + 128;\r
458 if(KeybWritePos >= 500)\r
459 KeybWritePos = 0;\r
460 } else {\r
461 KeyTable[raw_key] = 1;\r
462 RepeatKey = raw_key;\r
463 RepeatData = 250;\r
464 KeyboardBuffer[KeybWritePos++] = raw_key;\r
465 if(KeybWritePos >= 500)\r
466 KeybWritePos = 0;\r
467 }\r
468 } else {\r
469 if(raw_key == 0xE0)\r
470 {\r
471 SpecialKey = 1;\r
472 } else {\r
473 RepeatKey = 0;\r
474 if(SpecialKey == 1)\r
475 {\r
476 KeyTable[raw_key] = 0;\r
477 SpecialKey = 0;\r
478 } else {\r
479 KeyTable[raw_key - 128] = 0;\r
480 }\r
481 }\r
482 }\r
483}\r
484*/\r
485\r
486double ntime(void)\r
487{\r
488 struct timeval tv;\r
489 \r
490 gettimeofday(&tv, NULL);\r
491 return((double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0));\r
492}\r
493\r
494unsigned char ReadKey(void)\r
495{\r
496 unsigned char Data;\r
497\r
498 if((Data = KeyboardBuffer[KeybReadPos]) != 0)\r
499 {\r
500 KeyboardBuffer[KeybReadPos] = 0;\r
501 if(++KeybReadPos >= 500)\r
502 KeybReadPos = 0;\r
503 }\r
504 return(Data);\r
505}\r
506\r
507void EmptyKeyBuffer(void)\r
508{\r
509 KeybWritePos = KeybReadPos = 0;\r
510 memset(KeyboardBuffer, 0, 500);\r
511}\r
512\r
513void CopyToMap(signed short x, signed short y, unsigned char *Buffer, unsigned short w, unsigned short h, unsigned long bgc, unsigned char ColorPattern, unsigned char DestroyAll, unsigned short Attributes)\r
514{\r
515 unsigned short cx, cy, i;\r
516 unsigned long data;\r
517 unsigned char c;\r
518 unsigned char Colors[NUM_COLORS];\r
519 unsigned char NumColors;\r
520\r
521 NumColors = 0;\r
522 for(i = 0; i < NUM_COLORS; i++)\r
523 {\r
524 if(ColorInfo[i] == ColorPattern)\r
525 Colors[NumColors++] = i;\r
526 }\r
527 for(cy = 0; cy < h; cy++)\r
528 {\r
529 for(cx = 0; cx < w; cx++)\r
530 {\r
531 data = *(unsigned long *)Buffer;\r
532 Buffer += 4;\r
533 if(data != bgc)\r
534 {\r
535 if(((GetMapPixel(x + cx, y + cy, 1) & MAP_DESTROYABLE) == MAP_DESTROYABLE) || (DestroyAll == 1))\r
536 {\r
537 if(Attributes != 0xFFFF)\r
538 SetMapPixel(x + cx, y + cy, Attributes, 1);\r
539 if(ColorPattern == 0)\r
540 SetMapPixel(x + cx, y + cy, data, 0);\r
541 else\r
542 {\r
543 c = Colors[rand() % NumColors];\r
544 SetMapPixel(x + cx, y + cy, MakeColor(Palette[c].r, Palette[c].g, Palette[c].b), 0);\r
545 }\r
546 }\r
547 }\r
548 }\r
549 }\r
550}\r
551\r
552void ReInit(void)\r
553{\r
554 unsigned short i, o;\r
555\r
556 for(i = 0; i < MAX_PIXELS; i++)\r
557 Pixels[i]->Used = 0;\r
558 for(i = 0; i < MAX_OBJECTS; i++)\r
559 Objects[i]->Used = 0;\r
560 for(i = 0; i < MAX_PLAYERS; i++)\r
561 {\r
562 for(o = 0; o < NUM_KEYS; o++)\r
563 {\r
564 Players[i]->Keys[o] = 0;\r
565 Players[i]->HeldKeys[o] = 0;\r
566 }\r
567 }\r
568 for(i = 0; i < MAX_SPRITES; i++)\r
569 Sprites[i]->Used = 0;\r
570 for(i = 0; i < MAX_LINES; i++)\r
571 Lines[i]->Used = 0;\r
572 for(i = 0; i < MAX_RASTERS; i++)\r
573 Rasters[i]->Used = 0;\r
574 for(i = 0; i < MAX_SOUNDS; i++)\r
575 Sounds[i].Playing = 0;\r
576 for(i = 0; i < MAX_HITTESTS; i++)\r
577 HitTests[i] = 0xFFFF;\r
578 ModPlaying = 0;\r
579}\r
580\r
581/*\r
582void TimerInt(void)\r
583{\r
584 Ticks++;\r
585 TickError += FrameRate;\r
586 if(TickError >= TIMER_RES)\r
587 {\r
588 ReadyToGo = 1;\r
589 TickError -= TIMER_RES;\r
590 }\r
591 if(RepeatKey != 0)\r
592 {\r
593 if(--RepeatData == 0)\r
594 {\r
595 KeyboardBuffer[KeybWritePos++] = RepeatKey;\r
596 if(KeybWritePos >= 500)\r
597 KeybWritePos = 0;\r
598 RepeatData = 25;\r
599 }\r
600 }\r
601}\r
602*/\r
603\r
604void SetMapPixel(unsigned short x, unsigned short y, unsigned long c, unsigned short Handle)\r
605{\r
606 if((x >= LevelWidth) || (y >= LevelHeight))\r
607 return;\r
608 if(Handle == 0)\r
609 *(unsigned long *)&LevelBuffer[Handle][(x + (y * LevelWidth)) << 2] = c;\r
610 else\r
611 *(unsigned char *)&LevelBuffer[Handle][x + (y * LevelWidth)] = (unsigned short)c;\r
612}\r
613\r
614unsigned long GetMapPixel(unsigned short x, unsigned short y, unsigned short Handle)\r
615{\r
616 if((x >= LevelWidth) || (y >= LevelHeight))\r
617 return(0);\r
618 if(Handle == 0)\r
619 return(*(unsigned long *)&LevelBuffer[Handle][(x + (y * LevelWidth)) << 2]);\r
620 else\r
621 return((unsigned long)*(unsigned char *)&LevelBuffer[Handle][x + (y * LevelWidth)]);\r
622}\r
623\r
624void ShowMap(unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, unsigned short MapX, unsigned short MapY)\r
625{\r
626 unsigned short Window;\r
627 unsigned short cwx, cwy;\r
628 signed short x, y;\r
629 unsigned short i;\r
630 unsigned short CurFrame;\r
631 unsigned char Template;\r
632\r
633 if((MapX >= LevelWidth) || (MapY >= LevelHeight))\r
634 return;\r
635 DBSetClip(x1, y1, x2, y2);\r
636 cwx = (MapX / 2) % Caches[BGSprite]->w;\r
637 cwy = (MapY / 2) % Caches[BGSprite]->h;\r
638 #if CP_BLUR == 0\r
639 for(y = (signed short)(y1 - Caches[BGSprite]->h); y < (signed short)(y2 + Caches[BGSprite]->h); y += Caches[BGSprite]->h)\r
640 {\r
641 for(x = (signed short)(x1 - Caches[BGSprite]->w); x < (signed short)(x2 + Caches[BGSprite]->w); x += Caches[BGSprite]->w)\r
642 {\r
643 DBCopyBufferClip((signed short)x - cwx, (signed short)y - cwy, Caches[BGSprite]->Frames[BGFrame], Caches[BGSprite]->w, Caches[BGSprite]->h, -1);\r
644 }\r
645 }\r
646 #endif\r
647 DBCopyBufferClip((signed short)x1 - (signed short)MapX, (signed short)y1 - (signed short)MapY, LevelBuffer[0], LevelWidth, LevelHeight, 0);\r
648 //DBCopyMapBufferClip((signed short)x1 - (signed short)MapX, (signed short)y1 - (signed short)MapY, LevelBuffer[0], LevelBuffer[1], LevelWidth, LevelHeight);\r
649 for(i = 0; i < MAX_LINES; i++)\r
650 {\r
651 if(Lines[i]->Used > 0)\r
652 {\r
653 if(Lines[i]->UseSprite != 0xFF)\r
654 {\r
655 if(Lines[i]->Transparent != 0)\r
656 DBSpriteLineTrans(Lines[i]->x1 - MapX + x1 - Caches[Lines[i]->UseSprite]->cx[Lines[i]->CurFrame], Lines[i]->y1 - MapY + y1 - Caches[Lines[i]->UseSprite]->cy[Lines[i]->CurFrame], Lines[i]->x2 - MapX + x1 - Caches[Lines[i]->UseSprite]->cx[Lines[i]->CurFrame], Lines[i]->y2 - MapY + y1 - Caches[Lines[i]->UseSprite]->cy[Lines[i]->CurFrame], Caches[Lines[i]->UseSprite]->Frames[Lines[i]->CurFrame], Caches[Lines[i]->UseSprite]->w, Caches[Lines[i]->UseSprite]->h, Lines[i]->Transparent - 1);\r
657 else\r
658 DBSpriteLine(Lines[i]->x1 - MapX + x1 - Caches[Lines[i]->UseSprite]->cx[Lines[i]->CurFrame], Lines[i]->y1 - MapY + y1 - Caches[Lines[i]->UseSprite]->cy[Lines[i]->CurFrame], Lines[i]->x2 - MapY + x1 - Caches[Lines[i]->UseSprite]->cx[Lines[i]->CurFrame], Lines[i]->y2 - MapY + y1 - Caches[Lines[i]->UseSprite]->cy[Lines[i]->CurFrame], Caches[Lines[i]->UseSprite]->Frames[Lines[i]->CurFrame], Caches[Lines[i]->UseSprite]->w, Caches[Lines[i]->UseSprite]->h);\r
659 } else {\r
660 if(Lines[i]->Transparent != 0)\r
661 DBLineTrans(Lines[i]->x1 - MapX + x1, Lines[i]->y1 - MapY + y1, Lines[i]->x2 - MapX + x1, Lines[i]->y2 - MapY + y1, Lines[i]->c1, Lines[i]->c2, Lines[i]->Transparent - 1);\r
662 else\r
663 DBLine(Lines[i]->x1 - MapX + x1, Lines[i]->y1 - MapY + y1, Lines[i]->x2 - MapX + x1, Lines[i]->y2 - MapY + y1, Lines[i]->c1, Lines[i]->c2);\r
664 }\r
665 }\r
666 }\r
667 for(i = 0; i < MAX_PIXELS; i++)\r
668 {\r
669 if(Pixels[i]->Used == 1)\r
670 DBPSetC((unsigned short)(Pixels[i]->x - MapX + x1), (unsigned short)(Pixels[i]->y - MapY + y1), Pixels[i]->c);\r
671 }\r
672 for(i = 0; i < MAX_SPRITES; i++)\r
673 {\r
674 if(Sprites[i]->Used == 1)\r
675 {\r
676 CurFrame = Sprites[i]->CurFrame;\r
677 Template = Sprites[i]->Template;\r
678 CurFrame %= Caches[Template]->NumFrames;\r
679 if(Sprites[i]->Transparent != 0)\r
680 DBCopyBufferClipTrans((signed short)(Sprites[i]->x - MapX - Caches[Template]->cx[CurFrame] + x1), (signed short)(Sprites[i]->y - MapY - Caches[Template]->cy[CurFrame] + y1), Caches[Template]->Frames[CurFrame], Caches[Template]->w, Caches[Template]->h, 0, Sprites[i]->Transparent - 1);\r
681 else\r
682 DBCopyBufferClip((signed short)(Sprites[i]->x - MapX - Caches[Template]->cx[CurFrame] + x1), (signed short)(Sprites[i]->y - MapY - Caches[Template]->cy[CurFrame] + y1), Caches[Template]->Frames[CurFrame], Caches[Template]->w, Caches[Template]->h, 0);\r
683 }\r
684 }\r
685 for(i = 0; i < MAX_RASTERS; i++)\r
686 {\r
687 if(Rasters[i]->Used == 1)\r
688 {\r
689 if(Rasters[i]->Type == 0)\r
690 {\r
691 if(Rasters[i]->Transparent != 0)\r
692 DBFPolyTrans(x1 - MapX + Rasters[i]->x1, y1 - MapY + Rasters[i]->y1, x1 - MapX + Rasters[i]->x2, y1 - MapY + Rasters[i]->y2, x1 - MapX + Rasters[i]->x3, y1 - MapY + Rasters[i]->y3, Rasters[i]->Color, Rasters[i]->Transparent - 1);\r
693 else\r
694 DBFPoly(x1 - MapX + Rasters[i]->x1, y1 - MapY + Rasters[i]->y1, x1 - MapX + Rasters[i]->x2, y1 - MapY + Rasters[i]->y2, x1 - MapX + Rasters[i]->x3, y1 - MapY + Rasters[i]->y3, Rasters[i]->Color);\r
695 }\r
696 if(Rasters[i]->Type == 1)\r
697 {\r
698 if(Rasters[i]->Transparent != 0)\r
699 DBFCircleTrans(x1 - MapX + Rasters[i]->x1, y1 - MapY + Rasters[i]->y1, Rasters[i]->x2, Rasters[i]->Color, 1, 1, Rasters[i]->Transparent - 1);\r
700 else\r
701 DBFCircle(x1 - MapX + Rasters[i]->x1, y1 - MapY + Rasters[i]->y1, Rasters[i]->x2, Rasters[i]->Color, 1, 1);\r
702 }\r
703 }\r
704 }\r
705 /*for(y = (signed short)(y1 - Caches[FogSprite]->h); y < (signed short)(y2 + Caches[FogSprite]->h); y += Caches[FogSprite]->h)\r
706 {\r
707 for(x = (signed short)(x1 - Caches[FogSprite]->w); x < (signed short)(x2 + Caches[FogSprite]->w); x += Caches[FogSprite]->w)\r
708 {\r
709 DBCopyBufferClipTrans((signed short)x - FogX, (signed short)y - FogY, Caches[FogSprite]->Frames[0], Caches[FogSprite]->w, Caches[FogSprite]->h, -1, 1);\r
710 }\r
711 }*/\r
712 DBSetClip(0, 0, 319, 199);\r
713}\r
714\r
715unsigned char PlaySound(unsigned short Sound, unsigned char Repeat, unsigned short StartSound, unsigned short EndSound, unsigned long Pitch, float Volume)\r
716{\r
717 unsigned short i;\r
718\r
719 for(i = StartSound; i <= EndSound; i++)\r
720 {\r
721 if(Sounds[i].Playing == 0)\r
722 {\r
723 Sounds[i].Sound = Sound;\r
724 Sounds[i].Repeat = Repeat;\r
725 Sounds[i].Offset = 0;\r
726 Sounds[i].Pitch = Pitch;\r
727 Sounds[i].Volume = Volume;\r
728 Sounds[i].PitchError = 0;\r
729 Sounds[i].Playing = 1;\r
730 return(i);\r
731 }\r
732 }\r
733 return(0xFF);\r
734}\r
735\r
736void InitCodeTable(void)\r
737{\r
738 unsigned short i;\r
739\r
740 CurComp = 1;\r
741 CurNew = 0;\r
742 for(i = 0; i < 4096; i++)\r
743 {\r
744 Codes[i].Parent = -1;\r
745 Codes[i].Size = -1;\r
746 Codes[i].Value = -1;\r
747 }\r
748}\r
749\r
750signed short FindCode(signed long Value, signed short Parent)\r
751{\r
752 unsigned short i;\r
753\r
754 for(i = 0; i < (1 << CurComp); i++)\r
755 {\r
756 if((Codes[i].Value == Value) && (Codes[i].Parent == Parent))\r
757 return(i);\r
758 }\r
759 return(-1);\r
760}\r
761\r
762unsigned long ReadVarLen(KvidFile *FileStr)\r
763{\r
764 unsigned long Value;\r
765 unsigned char Finished, Shift;\r
766\r
767 Value = 0;\r
768 Finished = Shift = 0;\r
769 while(Finished == 0)\r
770 {\r
771 if(FileReadBits(1, FileStr) == 1)\r
772 Finished = 1;\r
773 Value += FileReadBits(7, FileStr) << Shift;\r
774 Shift += 7;\r
775 }\r
776 return(Value);\r
777}\r
778\r
779unsigned char AddCode(signed long Value, signed short Parent)\r
780{\r
781 Codes[CurNew].Value = Value;\r
782 Codes[CurNew].Parent = Parent;\r
783 if(Parent == -1)\r
784 Codes[CurNew].Size = 0;\r
785 else\r
786 Codes[CurNew].Size = Codes[Parent].Size + 1;\r
787 if(++CurNew == (1 << CurComp))\r
788 {\r
789 if(++CurComp >= 13)\r
790 {\r
791 InitCodeTable();\r
792 return(1);\r
793 }\r
794 }\r
795 return(0);\r
796}\r
797\r
798unsigned char LoadNewLevel(KvidFile *LevelFile)\r
799{\r
800 unsigned short i, p, x, y;\r
801 unsigned short CC, CurCode;\r
802 signed short Parent, CodeNum, Length, RLECount;\r
803 signed long Col, LastCol;\r
804 unsigned char InRLE, InCode, SType, NoAdd, HasParent, ReInited;\r
805\r
806 ReInit();\r
807 FileRead((void *)&LevelWidth, 2, LevelFile);\r
808 FileRead((void *)&LevelHeight, 2, LevelFile);\r
809 DispLevelWidth = LevelWidth;\r
810 DispLevelHeight = LevelHeight;\r
811 for(p = 0; p < 2; p++)\r
812 {\r
813 InitCodeTable();\r
814 Col = -1;\r
815 InRLE = InCode = 0;\r
816 NoAdd = 1;\r
817 HasParent = 0;\r
818 for(y = 0; y < LevelHeight; y++)\r
819 {\r
820 for(x = 0; x < LevelWidth; x++)\r
821 {\r
822 LastCol = Col;\r
823 if((InRLE == 0) && (InCode == 0))\r
824 {\r
825 InRLE = FileReadBits(1, LevelFile);\r
826 SType = FileReadBits(2, LevelFile);\r
827 if(InRLE == 1)\r
828 RLECount = ReadVarLen(LevelFile);\r
829 if(SType == 2)\r
830 {\r
831 InCode = 1;\r
832 CurCode = FileReadBits(CurComp, LevelFile);\r
833 Length = Codes[CurCode].Size;\r
834 CC = CurCode;\r
835 for(i = 0; i < Length; i++)\r
836 CC = Codes[CC].Parent;\r
837 Col = Codes[CC].Value;\r
838 }\r
839 if(SType == 0)\r
840 Col = FileReadBits(16, LevelFile);\r
841 if(NoAdd == 0)\r
842 {\r
843 if(HasParent == 0)\r
844 {\r
845 if((CodeNum = FindCode(LastCol, -1)) == -1)\r
846 {\r
847 Parent = CurNew;\r
848 ReInited = AddCode(LastCol, -1);\r
849 } else {\r
850 Parent = CodeNum;\r
851 ReInited = (FindCode(Col, CodeNum) == -1)?0:1;\r
852 }\r
853 } else {\r
854 ReInited = 0;\r
855 }\r
856 HasParent = 0;\r
857 if(ReInited == 0)\r
858 AddCode(Col, Parent);\r
859 }\r
860 if(FindCode(Col, -1) == -1)\r
861 AddCode(Col, -1);\r
862 NoAdd = 0;\r
863 }\r
864 if(InCode == 1)\r
865 {\r
866 CC = CurCode;\r
867 for(i = 0; i < Length; i++)\r
868 CC = Codes[CC].Parent;\r
869 Col = Codes[CC].Value;\r
870 if(--Length < 0)\r
871 {\r
872 if(InRLE == 1)\r
873 {\r
874 if(--RLECount <= 0)\r
875 InRLE = InCode = 0;\r
876 else\r
877 Length = Codes[CurCode].Size;\r
878 } else {\r
879 InCode = 0;\r
880 }\r
881 if(InCode == 0)\r
882 {\r
883 HasParent = 1;\r
884 Parent = CurCode;\r
885 }\r
886 }\r
887 } else {\r
888 if(InRLE == 1)\r
889 {\r
890 if(--RLECount <= 0)\r
891 InRLE = 0;\r
892 }\r
893 }\r
894 if(p == 0)\r
895 SetMapPixel(x, y, Color16To32((unsigned short)Col), p);\r
896 else\r
897 SetMapPixel(x, y, Col, p);\r
898 }\r
899 }\r
900 }\r
901 SpawnObject(0, -1, 0, 0, 0, 0);\r
902 FileClose(LevelFile);\r
903 return(0);\r
904}\r
905\r
906unsigned char LoadBMPLevel(KvidFile *LevelFile)\r
907{\r
908 unsigned short x, y;\r
909 unsigned long Buffer;\r
910 Color Col;\r
911\r
912 ReInit();\r
913 FileSkip(LevelFile, 16);\r
914 FileRead((void *)&Buffer, 4, LevelFile);\r
915 LevelWidth = DispLevelWidth = (unsigned short)Buffer;\r
916 FileRead((void *)&Buffer, 4, LevelFile);\r
917 LevelHeight = DispLevelHeight = (unsigned short)Buffer;\r
918 FileSkip(LevelFile, 28);\r
919 for(y = LevelHeight; y > 0; y--)\r
920 {\r
921 for(x = 0; x < LevelWidth; x++)\r
922 {\r
923 FileRead((void *)&Col, 3, LevelFile);\r
924 Col.Reserved = 0;\r
925 SetMapPixel(x, y - 1, *(unsigned long *)&Col, 0);\r
926 if((Col.R == 0) && (Col.G == 0) && (Col.B == 0))\r
927 {\r
928 SetMapPixel(x, y - 1, MAP_WALKABLE | MAP_SHOOTABLE, 1);\r
929 } else {\r
930 if((Col.R == Col.G) && (Col.R == Col.B))\r
931 SetMapPixel(x, y - 1, 0, 1);\r
932 else\r
933 SetMapPixel(x, y - 1, MAP_DESTROYABLE, 1);\r
934 }\r
935 }\r
936 FileSkip(LevelFile, LevelWidth % 4);\r
937 }\r
938 FileClose(LevelFile);\r
939 SpawnObject(0, -1, 0, 0, 0, 0);\r
940 return(0);\r
941}\r
942\r
943unsigned char LoadLevel(unsigned char *Name)\r
944{\r
945 KvidFile LevelFile, PalFile;\r
946 unsigned long Offset, Size;\r
947 unsigned short x, y, Count, Count2, Signature, i, o;\r
948 unsigned char Handle, RLEBase, c;\r
949 signed short ox, oy;\r
950 signed char Change, PalChange;\r
951 Color Col;\r
952\r
953 DBFRect(0, 0, 319, 199, MakeColor(0, 0, 0));\r
954 if(OpenFile(Name, &LevelFile) == 0)\r
955 return(1);\r
956 FileRead((void *)&Signature, 2, &LevelFile);\r
957 if(Signature == 0x4C4E)\r
958 return(LoadNewLevel(&LevelFile));\r
959 if(Signature == 0x4D42)\r
960 return(LoadBMPLevel(&LevelFile));\r
961 if(Signature != 0x464B)\r
962 return(2);\r
963 ReInit();\r
964 FileRead((void *)&LevelWidth, 2, &LevelFile);\r
965 PalChange = 0;\r
966 if(LevelWidth == 0)\r
967 {\r
968 FileRead((void *)&c, 1, &LevelFile);\r
969 FileRead((void *)TextBuffer, c, &LevelFile);\r
970 TextBuffer[c] = 0;\r
971 FileRead((void *)&LevelWidth, 2, &LevelFile);\r
972 if(OpenFile(TextBuffer, &PalFile) != 0)\r
973 {\r
974 PalChange = 1;\r
975 FileRead((void *)Palette, sizeof(Pal) * 256, &PalFile);\r
976 FileClose(&PalFile);\r
977 }\r
978 }\r
979 FileRead((void *)&LevelHeight, 2, &LevelFile);\r
980 DispLevelWidth = LevelWidth;\r
981 DispLevelHeight = LevelHeight;\r
982 FileRead((void *)&RLEBase, 1, &LevelFile);\r
983 Size = LevelWidth * LevelHeight;\r
984 for(Handle = 0; Handle < 2; Handle++)\r
985 {\r
986 x = 0;\r
987 y = 0;\r
988 Count = 0;\r
989 for(Offset = 0; Offset < Size; Offset++)\r
990 {\r
991 if(Count > 0)\r
992 Count--;\r
993 if(Count == 0)\r
994 {\r
995 c = FileGetChar(&LevelFile);\r
996 if(c >= RLEBase)\r
997 {\r
998 Count = (c - RLEBase) + 1;\r
999 c = FileGetChar(&LevelFile);\r
1000 }\r
1001 }\r
1002 if((Offset & 0xFFFF) == 0)\r
1003 {\r
1004 sprintf(TextBuffer, "Loading %s... %u%%\0", Name, (unsigned short)(50 * ((double)Offset / (double)Size)) + (Handle * 50));\r
1005 DBPrint(TextBuffer, 0, 0, 255);\r
1006 DisplayDB();\r
1007 }\r
1008 if(Handle == 0)\r
1009 SetMapPixel(x, y, MakeColor(Palette[c].r, Palette[c].g, Palette[c].b), Handle);\r
1010 else\r
1011 SetMapPixel(x, y, (unsigned long)c, Handle);\r
1012 if(++x >= LevelWidth)\r
1013 {\r
1014 x = 0;\r
1015 y++;\r
1016 }\r
1017 }\r
1018 }\r
1019 if(PalChange == 1)\r
1020 {\r
1021 if(OpenFile("DefaultPalette", &PalFile) != 0)\r
1022 {\r
1023 FileRead((void *)Palette, sizeof(Pal) * 256, &PalFile);\r
1024 FileClose(&PalFile);\r
1025 }\r
1026 }\r
1027 FileRead((void *)&Count, 2, &LevelFile);\r
1028 GameType = 255;\r
1029 for(i = 0; i < Count; i++)\r
1030 {\r
1031 FileRead((void *)&Signature, 2, &LevelFile);\r
1032 FileRead((void *)&x, 2, &LevelFile);\r
1033 FileRead((void *)&y, 2, &LevelFile);\r
1034 FileRead((void *)&Count2, 2, &LevelFile);\r
1035 for(o = 0; o < Count2; o++)\r
1036 {\r
1037 Regs[FileGetChar(&LevelFile) + (FileGetChar(&LevelFile) << 8)] = FileGetChar(&LevelFile) + (FileGetChar(&LevelFile) << 8);\r
1038 }\r
1039 SpawnObject(Signature, -1, x, y, 0, 0);\r
1040 }\r
1041 FileClose(&LevelFile);\r
1042 if(GameType == 255)\r
1043 SpawnObject(0, -1, 0, 0, 0, 0);\r
1044 /*for(Offset = 0; Offset < 300; Offset++)\r
1045 {\r
1046 x = (unsigned short)(rand() % LevelWidth);\r
1047 y = (unsigned short)(rand() % LevelWidth);\r
1048 while(GetMapPixel(x, y, 0) != MakeColor(Palette[6].r, Palette[6].g, Palette[6].b))\r
1049 {\r
1050 x = (unsigned short)(rand() % LevelWidth);\r
1051 y = (unsigned short)(rand() % LevelWidth);\r
1052 }\r
1053 for(oy = -1; oy <= 1; oy++)\r
1054 {\r
1055 for(ox = -1; ox <= 1; ox++)\r
1056 {\r
1057 Signature = GetMapPixel(x, y, 0);\r
1058 Col = *(Color *)&Signature;\r
1059 if((ox == 0) && (oy == 0))\r
1060 Change = 3;\r
1061 if((ox != 0) && (oy == 0) || (ox == 0) && (oy != 0))\r
1062 Change = 2;\r
1063 if((ox != 0) && (oy != 0))\r
1064 Change = 1;\r
1065 SetMapPixel((signed short)x + ox, (signed short)y + oy, MakeColor(Col.r - Change, Col.g - (Change << 1), Col.b - Change), 0);\r
1066 sprintf(TextBuffer, "Loading %s... %u%%\0", Name, (unsigned short)(100 * ((double)Offset / (double)300)));\r
1067 DBPrint(TextBuffer, 0, 0, 255);\r
1068 DisplayDB();\r
1069 }\r
1070 }\r
1071 }*/\r
1072 return(0);\r
1073}\r
1074\r
1075void RandomLevel(void)\r
1076{\r
1077 unsigned short x, y, i, o;\r
1078 unsigned char c0, c1, c2, c3, c4;\r
1079\r
1080 for(y = 0; y < LevelHeight; y++)\r
1081 {\r
1082 for(x = 0; x < LevelWidth; x++)\r
1083 {\r
1084 //SetMapPixel(x, y, (unsigned char)((rand() % 4) + 20), 0);\r
1085 SetMapPixel(x, y, 0, 0);\r
1086 }\r
1087 }\r
1088 for(y = 0; y < LevelHeight; y++)\r
1089 {\r
1090 for(x = 0; x < LevelWidth; x++)\r
1091 {\r
1092 SetMapPixel(x, y, MAP_WALKABLE | MAP_SHOOTABLE | MAP_DESTROYABLE, 1);\r
1093 }\r
1094 }\r
1095 for(i = 0; i < 75; i++)\r
1096 {\r
1097 x = rand() % LevelWidth;\r
1098 y = rand() % LevelHeight;\r
1099 CopyToMap(x - 15, y - 11, Caches[11]->Frames[rand() % Caches[11]->NumFrames], Caches[11]->w, Caches[11]->h, 0, 0, 0, 0);\r
1100 }\r
1101 for(i = 0; i < 150; i++)\r
1102 {\r
1103 x = rand() % LevelWidth;\r
1104 y = rand() % LevelHeight;\r
1105 CopyToMap(x - Caches[0]->cx[0], y - Caches[0]->cy[0], Caches[0]->Frames[0], Caches[0]->w, Caches[0]->h, 0, 3, 0, MAP_DESTROYABLE);\r
1106 }\r
1107 /*for(y = 0; y < LevelHeight; y++)\r
1108 {\r
1109 for(x = 0; x < LevelWidth; x++)\r
1110 {\r
1111 c0 = GetMapPixel(x, y, 0);\r
1112 if(c0 > 0)\r
1113 {\r
1114 c1 = GetMapPixel(x - 1, y, 0);\r
1115 c2 = GetMapPixel(x + 1, y, 0);\r
1116 c3 = GetMapPixel(x, y - 1, 0);\r
1117 c4 = GetMapPixel(x, y + 1, 0);\r
1118 c1 = (c1 == 0)?c0:c1;\r
1119 c2 = (c2 == 0)?c0:c2;\r
1120 c3 = (c3 == 0)?c0:c3;\r
1121 c4 = (c4 == 0)?c0:c4;\r
1122 SetMapPixel(x, y, (unsigned char)((c1 + c2 + c3 + c4) >> 2), 0);\r
1123 }\r
1124 }\r
1125 }*/\r
1126 for(i = 0; i < 100; i++)\r
1127 {\r
1128 x = rand() % LevelWidth;\r
1129 y = rand() % LevelHeight;\r
1130 while((GetMapPixel(x, y, 1) & MAP_WALKABLE) == 0)\r
1131 {\r
1132 x = rand() % LevelWidth;\r
1133 y = rand() % LevelHeight;\r
1134 }\r
1135 while((GetMapPixel(x, y, 1) & MAP_WALKABLE) == MAP_WALKABLE)\r
1136 y++;\r
1137 c0 = rand() % Caches[12]->NumFrames;\r
1138 CopyToMap(x - Caches[12]->cx[c0], y - Caches[12]->cy[c0], Caches[12]->Frames[c0], Caches[12]->w, Caches[12]->h, 0, 0, 0, MAP_WALKABLE | MAP_TEMPORARY);\r
1139 }\r
1140 for(i = 0; i < 4; i++)\r
1141 {\r
1142 for(o = 0; o < 15; o++)\r
1143 {\r
1144 x = rand() % LevelWidth;\r
1145 y = rand() % LevelHeight;\r
1146 while((GetMapPixel(x, y, 1) & MAP_WALKABLE) == 0)\r
1147 {\r
1148 x = rand() % (LevelWidth / 10);\r
1149 y = rand() % (LevelHeight / 10);\r
1150 }\r
1151 if(i == 0)\r
1152 while((GetMapPixel(x, ++y, 1) & MAP_WALKABLE) == MAP_WALKABLE);\r
1153 if(i == 1)\r
1154 while((GetMapPixel(--x, y, 1) & MAP_WALKABLE) == MAP_WALKABLE);\r
1155 if(i == 2)\r
1156 while((GetMapPixel(x, --y, 1) & MAP_WALKABLE) == MAP_WALKABLE);\r
1157 if(i == 3)\r
1158 while((GetMapPixel(++x, y, 1) & MAP_WALKABLE) == MAP_WALKABLE);\r
1159 c0 = rand() % Caches[12]->NumFrames;\r
1160 Regs[0] = i;\r
1161 SpawnObject(93, -1, x, y, 0, 0);\r
1162 }\r
1163 }\r
1164 for(y = 0; y < LevelHeight; y++)\r
1165 {\r
1166 for(x = 0; x < LevelWidth; x++)\r
1167 {\r
1168 if((GetMapPixel(x, y, 1) & MAP_TEMPORARY) == MAP_TEMPORARY)\r
1169 SetMapPixel(x, y, MAP_DESTROYABLE, 1);\r
1170 }\r
1171 }\r
1172 strcpy(LevelFileName, "Random");\r
1173 DispLevelWidth = LevelWidth;\r
1174 DispLevelHeight = LevelHeight;\r
1175 SpawnObject(0, -1, 0, 0, 0, 0);\r
1176}\r
1177\r
1178void DrawScreen(void)\r
1179{\r
1180 unsigned short i, o, cx, cy;\r
1181 signed short tx, ty, CurWeapon, x, y, x2, y2;\r
1182 float Per;\r
1183\r
1184 #if CP_BLUR == 0\r
1185 DBFillScreen(0);\r
1186 #else\r
1187 DBFRectTrans(0, 0, 319, 199, MakeColor(16, 16, 16), 1);\r
1188 #endif\r
1189 for(i = 0; i < MAX_PLAYERS; i++)\r
1190 {\r
1191 if(Players[i]->Visual == 1)\r
1192 {\r
1193 x = Objects[Players[i]->VPObject]->x;\r
1194 y = Objects[Players[i]->VPObject]->y;\r
1195 cx = (Players[i]->VPointX2 - Players[i]->VPointX1) >> 1;\r
1196 cy = (Players[i]->VPointY2 - Players[i]->VPointY1) >> 1;\r
1197 if(x > LevelWidth - cx - 2) x = LevelWidth - cx - 2;\r
1198 if(y > LevelHeight - cy - 2) y = LevelHeight - cy - 2;\r
1199 if(x < cx) x = cx;\r
1200 if(y < cy) y = cy;\r
1201 ShowMap(Players[i]->VPointX1, Players[i]->VPointY1, Players[i]->VPointX2, Players[i]->VPointY2, x - cx, y - cy);\r
1202 //*(unsigned long *)(Players[i]->Masks[0].Buffer + ((((unsigned short)Objects[Players[i]->Object]->y - (y - cy)) * (Players[i]->VPointX2 - Players[i]->VPointX1 + 1) + ((unsigned short)Objects[Players[i]->Object]->x - (x - cx))) << 2)) = MakeColor(255, 0, 0);\r
1203 DBSetClip(Players[i]->VPointX1, Players[i]->VPointY1, Players[i]->VPointX2, Players[i]->VPointY2);\r
1204 for(o = 0; o < NUM_MASKS; o++)\r
1205 {\r
1206 if(Players[i]->Masks[o].Method != 0)\r
1207 DBCopyBufferClipTrans(Players[i]->VPointX1, Players[i]->VPointY1, Players[i]->Masks[o].Buffer, Players[i]->VPointX2 - Players[i]->VPointX1 + 1, Players[i]->VPointY2 - Players[i]->VPointY1 + 1, -1, Players[i]->Masks[o].Method - 1);\r
1208 }\r
1209 x2 = (unsigned short)((unsigned short)(Objects[Players[i]->Object]->x) + (Cosine[(unsigned short)Players[i]->Angle] * ((Players[i]->Dir == 0)?15:-15)) - x + cx + Players[i]->VPointX1 + ((Players[i]->Dir == 0)?3:-2));\r
1210 y2 = (unsigned short)((unsigned short)(Objects[Players[i]->Object]->y) - (Sine[(unsigned short)Players[i]->Angle] * 15) - y + cy + Players[i]->VPointY1 - 2);\r
1211 DBPSetCTrans(x2 - 1, y2, Players[i]->CrossColor, 2);\r
1212 DBPSetCTrans(x2 + 1, y2, Players[i]->CrossColor, 2);\r
1213 DBPSetCTrans(x2, y2 - 1, Players[i]->CrossColor, 2);\r
1214 DBPSetCTrans(x2, y2 + 1, Players[i]->CrossColor, 2);\r
1215 if(Players[i]->Change)\r
1216 {\r
1217 tx = (signed short)(Objects[Players[i]->Object]->x - x + cx + Players[i]->VPointX1 - (Weapons[PWeapons[i][Players[i]->CurWeapon]->Weapon]->NameLength * 2));\r
1218 ty = (signed short)(Objects[Players[i]->Object]->y - y + cy + Players[i]->VPointY1 - 20);\r
1219 DBPrint((unsigned char *)&Strings[Weapons[PWeapons[i][Players[i]->CurWeapon]->Weapon]->Name], tx, ty, 0);\r
1220 }\r
1221 DBSetClip(0, 0, 319, 199);\r
1222 CurWeapon = Players[i]->CurWeapon;\r
1223 if(PWeapons[i][CurWeapon]->ReloadTimer == 0)\r
1224 Per = (float)PWeapons[i][CurWeapon]->AmmoLeft / (float)Weapons[PWeapons[i][Players[i]->CurWeapon]->Weapon]->Ammo;\r
1225 else\r
1226 Per = (float)PWeapons[i][CurWeapon]->ReloadTimer / (float)Weapons[PWeapons[i][CurWeapon]->Weapon]->ReloadDelay;\r
1227 if(Per > 0)\r
1228 DBFRect(Players[i]->AMeterX1, Players[i]->AMeterY1, Players[i]->AMeterX1 + (signed short)(Per * (Players[i]->AMeterX2 - Players[i]->AMeterX1)), Players[i]->AMeterY2, MakeColor(255 - (Per * 255), 0, 255));\r
1229 Per = (float)Players[i]->Health / (float)Players[i]->MaxHealth;\r
1230 if(Per > 0)\r
1231 {\r
1232 if(Per >= 0.5)\r
1233 DBFRect(Players[i]->LMeterX1, Players[i]->LMeterY1, Players[i]->LMeterX1 + (signed short)(Per * (Players[i]->LMeterX2 - Players[i]->LMeterX1)), Players[i]->LMeterY2, MakeColor(255 - ((Per - 0.5) * 254), 255, 0));\r
1234 else\r
1235 DBFRect(Players[i]->LMeterX1, Players[i]->LMeterY1, Players[i]->LMeterX1 + (signed short)(Per * (Players[i]->LMeterX2 - Players[i]->LMeterX1)), Players[i]->LMeterY2, MakeColor(255, 510 * Per, 0));\r
1236 }\r
1237 sprintf(TextBuffer, "Lives: %i\0", Players[i]->Lives);\r
1238 DBPrint(TextBuffer, Players[i]->lx, Players[i]->ly, 255);\r
1239 sprintf(TextBuffer, "Kills: %i\0", Players[i]->Kills);\r
1240 DBPrint(TextBuffer, Players[i]->kx, Players[i]->ky, 255);\r
1241 if(Weapons[PWeapons[i][CurWeapon]->Weapon]->MaxClips > 0)\r
1242 {\r
1243 sprintf(TextBuffer, "Ammo: %i\0", PWeapons[i][CurWeapon]->NumClips);\r
1244 DBPrint(TextBuffer, Players[i]->cx, Players[i]->cy, 255);\r
1245 }\r
1246 }\r
1247 }\r
1248 DBPrint(TextBuffer, 319 - (sprintf(TextBuffer, "%s (%u x %u)", LevelFileName, DispLevelWidth, DispLevelHeight) * 4), 194, 255);\r
1249 sprintf(TextBuffer, "%l08X", GetMapPixel(Objects[Players[1]->Object]->x, Objects[Players[1]->Object]->y, KeyTable[2]));\r
1250 DBPrint(TextBuffer, 0, 194, 255);\r
1251 #if SHOW_MAP == 1\r
1252 for(y = 0; y < 40; y++)\r
1253 {\r
1254 for(x = 0; x < 64; x++)\r
1255 {\r
1256 DBPSetCTrans(128 + x, 160 + y, GetMapPixel((float)x * ((float)LevelWidth / 64), (float)y * ((float)LevelHeight / 40), 0), 2);\r
1257 }\r
1258 }\r
1259 for(i = 0; i < MAX_PLAYERS; i++)\r
1260 {\r
1261 if(Players[i]->Used == 1)\r
1262 {\r
1263 DBPSetC(128 + (unsigned short)((float)Objects[Players[i]->Object]->x / ((float)LevelWidth / 64)), 160 + (unsigned short)((float)Objects[Players[i]->Object]->y / ((float)LevelHeight / 40)), MakeColor(200, 100, 0));\r
1264 }\r
1265 }\r
1266 #else\r
1267 DBCopyBufferClip(143, 180, Caches[15]->Frames[0], Caches[15]->w, Caches[15]->h, 0);\r
1268 #endif\r
1269}\r
1270\r
1271unsigned short CalcAngle(signed short x1, signed short y1, signed short x2, signed short y2)\r
1272{\r
1273 double a;\r
1274 unsigned char Q;\r
1275\r
1276 if(x1 == x2)\r
1277 {\r
1278 if(y1 >= y2)\r
1279 return(90);\r
1280 if(y1 < y2)\r
1281 return(270);\r
1282 }\r
1283 a = atan((double)(y1 - y2) / (double)(x1 - x2));\r
1284 if(a < 0)\r
1285 a = -a;\r
1286 if((y1 >= y2) && (x1 < x2))\r
1287 Q = 0;\r
1288 if((y1 >= y2) && (x1 >= x2))\r
1289 {\r
1290 Q = 1;\r
1291 a = 1.570796 - a;\r
1292 }\r
1293 if((y1 < y2) && (x1 >= x2))\r
1294 Q = 2;\r
1295 if((y1 < y2) && (x1 < x2))\r
1296 {\r
1297 Q = 3;\r
1298 a = 1.570796 - a;\r
1299 }\r
1300 return((unsigned short)(((a + (Q * 1.570796)) / 3.141593) * 180));\r
1301}\r
1302\r
1303unsigned long MakeColor(unsigned char R, unsigned char G, unsigned char B)\r
1304{\r
1305 return(((unsigned short)R << 16) + ((unsigned short)G << 8) + (unsigned short)B);\r
1306}\r
1307\r
1308unsigned char GetEvents(void)\r
1309{\r
1310 unsigned short i;\r
1311 SDL_Event e;\r
1312 \r
1313 while(SDL_PollEvent(&e))\r
1314 {\r
1315 if(e.type == SDL_QUIT)\r
1316 return(1);\r
1317 if(e.type == SDL_KEYDOWN)\r
1318 {\r
1319 for(i = 0; sdlmap[i].sdl != -1; i++)\r
1320 {\r
1321 if(sdlmap[i].sdl == e.key.keysym.sym)\r
1322 break;\r
1323 }\r
1324 if(sdlmap[i].sdl != -1)\r
1325 {\r
1326 KeyTable[sdlmap[i].dos] = 1;\r
1327 RepeatKey = sdlmap[i].dos;\r
1328 RepeatData = ntime() + 0.25;\r
1329 KeyboardBuffer[KeybWritePos++] = sdlmap[i].dos;\r
1330 if(KeybWritePos >= 500)\r
1331 KeybWritePos = 0;\r
1332 }\r
1333 }\r
1334 if(e.type == SDL_KEYUP)\r
1335 {\r
1336 for(i = 0; sdlmap[i].sdl != -1; i++)\r
1337 {\r
1338 if(sdlmap[i].sdl == e.key.keysym.sym)\r
1339 break;\r
1340 }\r
1341 if(sdlmap[i].sdl != -1)\r
1342 {\r
1343 KeyTable[sdlmap[i].dos] = 0;\r
1344 RepeatKey = 0;\r
1345 }\r
1346 }\r
1347 }\r
1348 if((RepeatKey != 0) && (ntime() > RepeatData))\r
1349 {\r
1350 KeyboardBuffer[KeybWritePos++] = RepeatKey;\r
1351 if(KeybWritePos >= 500)\r
1352 KeybWritePos = 0;\r
1353 RepeatData = ntime() + 0.025;\r
1354 }\r
1355 return(0);\r
1356}\r
1357\r
1358void GetInputs(void)\r
1359{\r
1360 unsigned char i, o, u;\r
1361\r
1362 for(i = 0; i < MAX_PLAYERS; i++)\r
1363 {\r
1364 for(o = 0; o < NUM_KEYS; o++)\r
1365 {\r
1366 if(((Players[i]->KeyCodes[o] & 0xFF00) == 0)?(KeyTable[Players[i]->KeyCodes[o]] == 1):((KeyTable[(Players[i]->KeyCodes[o] & 0xFF00) >> 8] == 1) && (KeyTable[Players[i]->KeyCodes[o] & 0x00FF] == 1)))\r
1367 {\r
1368 if((Players[i]->Keys[o] == 0) && (Players[i]->HeldKeys[o] == 0))\r
1369 {\r
1370 Players[i]->Keys[o] = 1;\r
1371 } else {\r
1372 Players[i]->Keys[o] = 2;\r
1373 }\r
1374 } else {\r
1375 Players[i]->Keys[o] = 0;\r
1376 }\r
1377 }\r
1378 for(o = 0; o < NUM_KEYS; o++)\r
1379 Players[i]->HeldKeys[o] = 0;\r
1380 for(o = 0; o < NUM_KEYS; o++)\r
1381 {\r
1382 if(((Players[i]->KeyCodes[o] & 0xFF00) != 0) && (Players[i]->Keys[o] != 0))\r
1383 {\r
1384 for(u = 0; u < NUM_KEYS; u++)\r
1385 {\r
1386 if((Players[i]->KeyCodes[u] == (Players[i]->KeyCodes[o] & 0x00FF)) || (Players[i]->KeyCodes[u] == ((Players[i]->KeyCodes[o] & 0xFF00) >> 8)))\r
1387 {\r
1388 Players[i]->Keys[u] = 0;\r
1389 Players[i]->HeldKeys[u] = 1;\r
1390 }\r
1391 }\r
1392 }\r
1393 }\r
1394 }\r
1395}\r
1396\r
1397void SetMode(unsigned char Mode)\r
1398{\r
1399 if(FullScreen != Mode)\r
1400 {\r
1401 SDL_WM_ToggleFullScreen(VBuffer);\r
1402 FullScreen = Mode;\r
1403 }\r
1404 if(FullScreen == 0)\r
1405 SDL_ShowCursor(SDL_ENABLE);\r
1406 else\r
1407 SDL_ShowCursor(SDL_DISABLE);\r
1408}\r
1409\r
1410void MessageBox(unsigned char *Buffer)\r
1411{\r
1412 DBFRect(68, 88, 252, 112, MakeColor(255, 0, 0));\r
1413 DBFRect(69, 89, 251, 111, MakeColor(0, 0, 0));\r
1414 DBPrint(Buffer, 70, 90, 255);\r
1415 DisplayDB();\r
1416 while(KeyTable[57] == 1) GetEvents();\r
1417 while(KeyTable[57] == 0) GetEvents();\r
1418}\r
1419\r
1420unsigned char LoadMod(KvidFile *ModFile)\r
1421{\r
1422 unsigned short i, o, MaxPattern, Granularity, BkOffset;\r
1423 unsigned long Signature, BkAU, u;\r
1424 unsigned char Bytes[4], NumSamples, OldMod;\r
1425 ModEvent *Buffer;\r
1426\r
1427 for(i = 0; i < MAX_SAMPLES; i++)\r
1428 {\r
1429 if(Samples[i].Allocated != 0)\r
1430 {\r
1431 Samples[i].Allocated = 0;\r
1432 free(Samples[i].Buffer);\r
1433 }\r
1434 }\r
1435 for(i = 0; i < MAX_CHANNELS; i++)\r
1436 {\r
1437 memset((void *)&Channels[i], 0, sizeof(ModChannel));\r
1438 }\r
1439 if((ModFile->DataFile == 1) || (ModFile->Parent != NULL))\r
1440 {\r
1441 BkAU = ModFile->CurAU;\r
1442 BkOffset = ModFile->Offset;\r
1443 } else {\r
1444 BkAU = ftell(ModFile->FilePtr);\r
1445 }\r
1446 FileSkip(ModFile, 1080);\r
1447 Signature = FileGetChar(ModFile);\r
1448 for(i = 0; i < 3; i++)\r
1449 {\r
1450 Signature <<= 8;\r
1451 Signature += FileGetChar(ModFile);\r
1452 }\r
1453 if((ModFile->DataFile == 1) || (ModFile->Parent != NULL))\r
1454 {\r
1455 ModFile->CurAU = BkAU;\r
1456 ModFile->Offset = BkOffset;\r
1457 ModFile->ReSeek = 1;\r
1458 } else {\r
1459 fseek(ModFile->FilePtr, BkAU, SEEK_SET);\r
1460 }\r
1461 FileSkip(ModFile, 20);\r
1462 ModChannels = 0;\r
1463 if((Signature == 0x4D2E4B2E) || (Signature == 0x4D214B21)) //"M.K." or "M!K!"\r
1464 ModChannels = 4;\r
1465 if(Signature == 0x3643484E) //"6CHN"\r
1466 ModChannels = 6;\r
1467 if(Signature == 0x3843484E) //"8CHN"\r
1468 ModChannels = 8;\r
1469 if(Signature == 0x31324348) //"12CH"\r
1470 ModChannels = 12;\r
1471 if(ModChannels == 0)\r
1472 {\r
1473 ModChannels = 4;\r
1474 NumSamples = 15;\r
1475 OldMod = 1;\r
1476 } else {\r
1477 NumSamples = 31;\r
1478 OldMod = 0;\r
1479 }\r
1480 for(i = 0; i < NumSamples; i++)\r
1481 {\r
1482 FileSkip(ModFile, 22);\r
1483 Samples[i].SampleLen = ((FileGetChar(ModFile) << 8) + FileGetChar(ModFile)) << 1;\r
1484 Samples[i].FineTune = FileGetChar(ModFile) & 0x0F;\r
1485 Samples[i].Volume = FileGetChar(ModFile);\r
1486 Samples[i].LoopStart = (FileGetChar(ModFile) << 8) + FileGetChar(ModFile);\r
1487 Samples[i].LoopLen = (FileGetChar(ModFile) << 8) + FileGetChar(ModFile);\r
1488 if(OldMod == 0)\r
1489 {\r
1490 Samples[i].LoopStart <<= 1;\r
1491 Samples[i].LoopLen <<= 1;\r
1492 }\r
1493 }\r
1494 ModLen = FileGetChar(ModFile);\r
1495 if(ModLen > 128)\r
1496 ModLen = 128;\r
1497 ModRepeat = FileGetChar(ModFile);\r
1498 MaxPattern = 0;\r
1499 for(i = 0; i < 128; i++)\r
1500 {\r
1501 if((PatternOrder[i] = FileGetChar(ModFile)) > MaxPattern)\r
1502 MaxPattern = PatternOrder[i];\r
1503 }\r
1504 if(NumSamples > 15)\r
1505 FileSkip(ModFile, 4);\r
1506 Granularity = 64 * ModChannels;\r
1507 for(i = 0; i <= MaxPattern; i++)\r
1508 {\r
1509 for(o = 0; o < Granularity; o++)\r
1510 {\r
1511 Buffer = &Patterns[(i * Granularity) + o];\r
1512 FileRead((void *)Bytes, 4, ModFile);\r
1513 Buffer->Period = ((Bytes[0] & 0x0F) << 8) | Bytes[1];\r
1514 Buffer->Sample = (Bytes[0] & 0xF0) | ((Bytes[2] & 0xF0) >> 4);\r
1515 Buffer->Effect = Bytes[2] & 0x0F;\r
1516 Buffer->EffectData = Bytes[3];\r
1517 }\r
1518 }\r
1519 for(i = 0; i < NumSamples; i++)\r
1520 {\r
1521 if(Samples[i].SampleLen > 0)\r
1522 {\r
1523 //Samples[i].SampleLen = SoundCaches[15]->Length;\r
1524 if((Samples[i].Buffer = (unsigned char *)malloc(Samples[i].SampleLen)) == NULL)\r
1525 return(2);\r
1526 FileRead((void *)Samples[i].Buffer, Samples[i].SampleLen, ModFile);\r
1527 //for(u = 0; u < Samples[i].SampleLen; u++)\r
1528 // Samples[i].Buffer[u] = (signed char)((signed short)(SoundCaches[15]->SoundBuffer[u]) - 128);\r
1529 Samples[i].Allocated = 1;\r
1530 }\r
1531 }\r
1532 ModPattern = 0;\r
1533 ModRow = 0;\r
1534 ModOffset = 0;\r
1535 ModBPM = 125;\r
1536 ModTPD = 6;\r
1537 return(0);\r
1538}\r
1539\r
1540unsigned char LoadSprite(unsigned char *ID, unsigned short CacheNum)\r
1541{\r
1542 unsigned short i, o, Found;\r
1543 KvidFile SpriteFile;\r
1544\r
1545 if(OpenFile(ID, &SpriteFile) == 0)\r
1546 return(1);\r
1547 FileRead((void *)&Caches[CacheNum]->w, 2, &SpriteFile);\r
1548 FileRead((void *)&Caches[CacheNum]->h, 2, &SpriteFile);\r
1549 FileRead((void *)&Caches[CacheNum]->NumFrames, 1, &SpriteFile);\r
1550 FileRead((void *)&Caches[CacheNum]->AnimDelay, 1, &SpriteFile);\r
1551 if((Caches[CacheNum]->cx = (signed short *)malloc(Caches[CacheNum]->NumFrames * 2)) == NULL)\r
1552 return(2);\r
1553 if((Caches[CacheNum]->cy = (signed short *)malloc(Caches[CacheNum]->NumFrames * 2)) == NULL)\r
1554 return(2);\r
1555 if((Caches[CacheNum]->Frames = (unsigned char **)malloc(Caches[CacheNum]->NumFrames * 4)) == NULL)\r
1556 return(2);\r
1557 for(o = 0; o < Caches[CacheNum]->NumFrames; o++)\r
1558 {\r
1559 FileRead((void *)&Caches[CacheNum]->cx[o], 2, &SpriteFile);\r
1560 FileRead((void *)&Caches[CacheNum]->cy[o], 2, &SpriteFile);\r
1561 if((Caches[CacheNum]->Frames[o] = (unsigned char *)malloc(Caches[CacheNum]->w * Caches[CacheNum]->h * 4)) == NULL)\r
1562 return(2);\r
1563 FileRead((void *)Caches[CacheNum]->Frames[o], Caches[CacheNum]->w * Caches[CacheNum]->h * 4, &SpriteFile);\r
1564 }\r
1565 FileClose(&SpriteFile);\r
1566 return(0);\r
1567}\r
1568\r
1569unsigned short SpawnSprite(unsigned char Template, signed short x, signed short y, signed char xv, signed char yv, unsigned short AnimCount, unsigned char StartFrame, unsigned char Transparent)\r
1570{\r
1571 unsigned short i;\r
1572\r
1573 for(i = 0; i < MAX_SPRITES; i++)\r
1574 {\r
1575 if(Sprites[i]->Used == 0)\r
1576 {\r
1577 Sprites[i]->x = x;\r
1578 Sprites[i]->y = y;\r
1579 Sprites[i]->xv = xv;\r
1580 Sprites[i]->yv = yv;\r
1581 Sprites[i]->AnimTimer = 0;\r
1582 Sprites[i]->AnimCount = AnimCount;\r
1583 Sprites[i]->AnimDelay = Caches[Template]->AnimDelay;\r
1584 Sprites[i]->CurFrame = StartFrame;\r
1585 Sprites[i]->Template = Template;\r
1586 Sprites[i]->Transparent = Transparent;\r
1587 Sprites[i]->Used = 1;\r
1588 return(i);\r
1589 }\r
1590 }\r
1591 return(0xFFFF);\r
1592}\r
1593\r
1594void FillBuffer(void)\r
1595{\r
1596 unsigned short i, o;\r
1597 unsigned long Offset;\r
1598 signed short Data, Data2;\r
1599 unsigned short ModBPD;\r
1600 unsigned short SampleRate;\r
1601 unsigned char Temp;\r
1602 float Amp;\r
1603 ModEvent *Buffer;\r
1604\r
1605 for(i = 0; i < SB_SIZE >> 1; i++)\r
1606 {\r
1607 SoundBuffer[i] = 128;\r
1608 }\r
1609 for(i = 0; i < MAX_SOUNDS; i++)\r
1610 {\r
1611 if(Sounds[i].Playing == 1)\r
1612 {\r
1613 for(o = 0; o < SB_SIZE >> 1; o++)\r
1614 {\r
1615 Sounds[i].PitchError += Sounds[i].Pitch;\r
1616 while(Sounds[i].PitchError >= SBSampleRate)\r
1617 {\r
1618 Sounds[i].PitchError -= SBSampleRate;\r
1619 Sounds[i].Offset++;\r
1620 }\r
1621 if(Sounds[i].Offset >= SoundCaches[Sounds[i].Sound]->Length)\r
1622 {\r
1623 if(Sounds[i].Repeat == 0)\r
1624 {\r
1625 Sounds[i].Playing = 0;\r
1626 break;\r
1627 } else {\r
1628 Sounds[i].Offset = 0;\r
1629 }\r
1630 }\r
1631 Data = ((signed short)SoundBuffer[o] - 128);\r
1632 Data += (((signed short)(SoundCaches[Sounds[i].Sound]->SoundBuffer[Sounds[i].Offset] - 128) * Sounds[i].Volume) / 4);\r
1633 if(Data > 127)\r
1634 Data = 127;\r
1635 if(Data < -128)\r
1636 Data = -128;\r
1637 SoundBuffer[o] = (unsigned char)(Data + 128);\r
1638 }\r
1639 }\r
1640 }\r
1641 if(ModPlaying != 0)\r
1642 {\r
1643 ModBPD = (SBSampleRate * 5 * ModTPD) / (ModBPM * 2);\r
1644 if(KeyTable[5] == 1)\r
1645 ModBPD >>= 1;\r
1646 for(i = 0; i < SB_SIZE >> 1; i++)\r
1647 {\r
1648 Data2 = 0;\r
1649 for(o = 0; o < ModChannels; o++)\r
1650 {\r
1651 if(ModOffset == 0)\r
1652 {\r
1653 Buffer = &Patterns[(((PatternOrder[ModPattern] << 6) + ModRow) * ModChannels) + o];\r
1654 if(Buffer->Period != 0)\r
1655 {\r
1656 Channels[o].Playing = 1;\r
1657 Channels[o].OldPeriod = Channels[o].CurPeriod;\r
1658 Channels[o].Period = Channels[o].CurPeriod = Buffer->Period;\r
1659 Channels[o].Offset = 0;\r
1660 Channels[o].Looping = 0;\r
1661 Channels[o].Reminder = 0;\r
1662 Channels[o].Effect = 0;\r
1663 Channels[o].EffectData.b = 0;\r
1664 }\r
1665 if(Buffer->Sample != 0)\r
1666 {\r
1667 if((Samples[Buffer->Sample - 1].SampleLen > 0) && (Samples[Buffer->Sample - 1].Volume > 0))\r
1668 {\r
1669 Channels[o].Playing = 1;\r
1670 Channels[o].Sample = Buffer->Sample - 1;\r
1671 Channels[o].Volume = Channels[o].CurVolume = Samples[Buffer->Sample - 1].Volume;\r
1672 Channels[o].Offset = 0;\r
1673 Channels[o].Looping = 0;\r
1674 Channels[o].Reminder = 0;\r
1675 Channels[o].Effect = 0;\r
1676 Channels[o].EffectData.b = 0;\r
1677 } else {\r
1678 Channels[o].Playing = 0;\r
1679 }\r
1680 }\r
1681 Channels[o].Effect = Buffer->Effect;\r
1682 Channels[o].EffectData.b = Buffer->EffectData;\r
1683 if(Buffer->Effect == 4)\r
1684 {\r
1685 Channels[o].Oscillation = 1;\r
1686 if((Channels[o].EffectData.Nibbles.n1 != 0) && (Channels[o].EffectData.Nibbles.n2 != 0))\r
1687 {\r
1688 Channels[o].OscFreq = Channels[o].EffectData.Nibbles.n1;\r
1689 Channels[o].OscAmp = Channels[o].EffectData.Nibbles.n2;\r
1690 }\r
1691 if(Channels[o].OscNoTrig == 0)\r
1692 Channels[o].OscOffset = 0;\r
1693 } else {\r
1694 if((Buffer->Effect != 7) && (Buffer->Effect != 6))\r
1695 Channels[o].Oscillation = 0;\r
1696 }\r
1697 if(Buffer->Effect == 7)\r
1698 {\r
1699 Channels[o].Oscillation = 2;\r
1700 if((Channels[o].EffectData.Nibbles.n1 != 0) && (Channels[o].EffectData.Nibbles.n2 != 0))\r
1701 {\r
1702 Channels[o].OscFreq = Channels[o].EffectData.Nibbles.n1;\r
1703 Channels[o].OscAmp = Channels[o].EffectData.Nibbles.n2;\r
1704 }\r
1705 if(Channels[o].OscNoTrig == 0)\r
1706 Channels[o].OscOffset = 0;\r
1707 } else {\r
1708 if((Buffer->Effect != 4) && (Buffer->Effect != 6))\r
1709 Channels[o].Oscillation = 0;\r
1710 }\r
1711 if(Buffer->Effect == 6)\r
1712 Channels[o].Effect = 10;\r
1713 if(Buffer->Effect == 9)\r
1714 Channels[o].Offset = Buffer->EffectData << 8;\r
1715 if(Buffer->Effect == 12)\r
1716 {\r
1717 Channels[o].Volume = Buffer->EffectData;\r
1718 if(Channels[o].Volume > 64)\r
1719 Channels[o].Volume = 64;\r
1720 Channels[o].CurVolume = Channels[o].Volume;\r
1721 }\r
1722 if(Buffer->Effect == 14)\r
1723 {\r
1724 if((Channels[o].EffectData.Nibbles.n1 = 4) || (Channels[o].EffectData.Nibbles.n1 = 7))\r
1725 {\r
1726 Channels[o].OscWave = Channels[o].EffectData.Nibbles.n2 & 3;\r
1727 Channels[o].OscOffset = 0;\r
1728 if(Channels[o].OscWave == 3)\r
1729 Channels[o].OscWave = rand() % 3;\r
1730 if(Channels[o].EffectData.Nibbles.n2 > 3)\r
1731 Channels[o].OscNoTrig = 1;\r
1732 else\r
1733 Channels[o].OscNoTrig = 0;\r
1734 }\r
1735 }\r
1736 if(Buffer->Effect == 15)\r
1737 {\r
1738 if(Buffer->EffectData <= 32)\r
1739 ModTPD = Buffer->EffectData;\r
1740 else\r
1741 ModBPM = Buffer->EffectData;\r
1742 ModBPD = ((5 * SBSampleRate) * ModTPD) / (ModBPM * 2);\r
1743 }\r
1744 }\r
1745 if(Channels[o].Playing != 0)\r
1746 {\r
1747 SampleRate = 7093789 / (Channels[o].CurPeriod << 1);\r
1748 if(KeyTable[6] == 1)\r
1749 SampleRate <<= 1;\r
1750 Channels[o].Reminder += SampleRate;\r
1751 if(Channels[o].Reminder >= SBSampleRate)\r
1752 {\r
1753 Channels[o].LastSample = Samples[Channels[o].Sample].Buffer[Channels[o].Offset];\r
1754 while(Channels[o].Reminder >= SBSampleRate)\r
1755 {\r
1756 Channels[o].Reminder -= SBSampleRate;\r
1757 Channels[o].Offset++;\r
1758 }\r
1759 }\r
1760 if(Channels[o].Looping != 0)\r
1761 {\r
1762 if(Channels[o].Offset >= Samples[Channels[o].Sample].LoopStart + Samples[Channels[o].Sample].LoopLen)\r
1763 Channels[o].Offset = Samples[Channels[o].Sample].LoopStart;\r
1764 } else {\r
1765 if(Channels[o].Offset >= Samples[Channels[o].Sample].SampleLen)\r
1766 {\r
1767 if(Samples[Channels[o].Sample].LoopLen > 2)\r
1768 {\r
1769 Channels[o].Looping = 1;\r
1770 Channels[o].Offset = Samples[Channels[o].Sample].LoopStart;\r
1771 } else {\r
1772 Channels[o].Playing = 0;\r
1773 }\r
1774 }\r
1775 }\r
1776 }\r
1777 if(Channels[o].Playing != 0)\r
1778 {\r
1779 Data = (signed short)Samples[Channels[o].Sample].Buffer[Channels[o].Offset];\r
1780 Data2 += (Data * Channels[o].CurVolume) / 256;\r
1781 if(Channels[o].Oscillation == 1)\r
1782 {\r
1783 Amp = (WaveForms[Channels[o].OscWave][(unsigned short)Channels[o].OscOffset] * (float)Channels[o].OscAmp) / 32;\r
1784 Channels[o].CurPeriod = (unsigned short)((double)Channels[o].Period * pow(2, (double)(Amp / 12)));\r
1785 Channels[o].OscOffset += ((float)Channels[o].OscFreq * (float)ModTPD * 360) / (64 * ModBPD);\r
1786 if(Channels[o].OscOffset >= 360)\r
1787 Channels[o].OscOffset -= 360;\r
1788 }\r
1789 if(Channels[o].Oscillation == 2)\r
1790 {\r
1791 Amp = WaveForms[Channels[o].OscWave][(unsigned short)Channels[o].OscOffset] * (float)Channels[o].OscAmp * (float)(ModTPD - 1);\r
1792 Channels[o].CurVolume = (unsigned char)((signed char)Channels[o].Volume + (signed char)Amp);\r
1793 if((Amp > 0) && (Channels[o].CurVolume > 64))\r
1794 Channels[o].CurVolume = 64;\r
1795 if((Amp < 0) && (Channels[o].CurVolume > 64))\r
1796 Channels[o].CurVolume = 0;\r
1797 Channels[o].OscOffset += ((float)Channels[o].OscFreq * (float)ModTPD * 360) / (64 * ModBPD);\r
1798 if(Channels[o].OscOffset >= 360)\r
1799 Channels[o].OscOffset -= 360;\r
1800 }\r
1801 if(Channels[o].Effect == 0)\r
1802 {\r
1803 if(ModOffset == (unsigned short)(ModBPD / 3))\r
1804 Channels[o].CurPeriod = (unsigned short)((double)Channels[o].Period * pow(2, (double)Channels[o].EffectData.Nibbles.n1 / 12));\r
1805 if(ModOffset == (unsigned short)((2 * ModBPD) / 3))\r
1806 Channels[o].CurPeriod = (unsigned short)((double)Channels[o].Period * pow(2, (double)Channels[o].EffectData.Nibbles.n2 / 12));\r
1807 }\r
1808 if(Channels[o].Effect == 1)\r
1809 {\r
1810 Channels[o].CurPeriod = Channels[o].Period - (unsigned short)(((unsigned long)Channels[o].EffectData.b * (unsigned long)ModTPD * (unsigned long)ModOffset) / (unsigned long)ModBPD);\r
1811 if((signed short)Channels[o].CurPeriod < 113)\r
1812 Channels[o].CurPeriod = 113;\r
1813 }\r
1814 if(Channels[o].Effect == 2)\r
1815 {\r
1816 Channels[o].CurPeriod = Channels[o].Period + (unsigned short)(((unsigned long)Channels[o].EffectData.b * (unsigned long)ModTPD * (unsigned long)ModOffset) / (unsigned long)ModBPD);\r
1817 if(Channels[o].CurPeriod > 856)\r
1818 Channels[o].CurPeriod = 856;\r
1819 }\r
1820 if(Channels[o].Effect == 3)\r
1821 {\r
1822 if(Channels[o].OldPeriod > Channels[o].Period)\r
1823 {\r
1824 Channels[o].CurPeriod = Channels[o].OldPeriod - (unsigned short)(((unsigned long)Channels[o].EffectData.b * (unsigned long)ModTPD * (unsigned long)ModOffset) / (unsigned long)ModBPD);\r
1825 if((signed short)Channels[o].CurPeriod < Channels[o].Period)\r
1826 Channels[o].CurPeriod = Channels[o].Period;\r
1827 } else {\r
1828 Channels[o].CurPeriod = Channels[o].OldPeriod + (unsigned short)(((unsigned long)Channels[o].EffectData.b * (unsigned long)ModTPD * (unsigned long)ModOffset) / (unsigned long)ModBPD);\r
1829 if(Channels[o].CurPeriod > Channels[o].Period)\r
1830 Channels[o].CurPeriod = Channels[o].Period;\r
1831 }\r
1832 }\r
1833 if((Channels[o].Effect == 10) && (Channels[o].EffectData.Nibbles.n1 > 0))\r
1834 {\r
1835 Channels[o].CurVolume = Channels[o].Volume + (unsigned char)(((unsigned long)Channels[o].EffectData.Nibbles.n1 * (unsigned long)ModTPD * (unsigned long)ModOffset) / (unsigned long)ModBPD);\r
1836 if(Channels[o].CurVolume > 64)\r
1837 Channels[o].CurVolume = 64;\r
1838 } else {\r
1839 if((Channels[o].Effect == 10) && (Channels[o].EffectData.Nibbles.n2 > 0))\r
1840 {\r
1841 Channels[o].CurVolume = Channels[o].Volume - (unsigned char)(((unsigned long)Channels[o].EffectData.Nibbles.n2 * (unsigned long)ModTPD * (unsigned long)ModOffset) / (unsigned long)ModBPD);\r
1842 if(Channels[o].CurVolume > 64)\r
1843 Channels[o].CurVolume = 0;\r
1844 }\r
1845 }\r
1846 }\r
1847 }\r
1848 if(++ModOffset >= ModBPD)\r
1849 {\r
1850 ModRow++;\r
1851 Temp = 0;\r
1852 for(o = 0; o < ModChannels; o++)\r
1853 {\r
1854 if(Channels[o].Effect == 11)\r
1855 {\r
1856 ModRow = 0;\r
1857 ModPattern = Channels[o].EffectData.b;\r
1858 }\r
1859 if((Channels[o].Effect == 13) && (Temp == 0))\r
1860 {\r
1861 if(++ModPattern >= ModLen)\r
1862 {\r
1863 if(ModRepeat >= ModLen)\r
1864 ModPattern = 0;\r
1865 else\r
1866 ModPattern = ModRepeat;\r
1867 }\r
1868 ModRow = (Channels[o].EffectData.Nibbles.n1 * 10) + Channels[o].EffectData.Nibbles.n2;\r
1869 Temp = 1;\r
1870 }\r
1871 }\r
1872 ModOffset = 0;\r
1873 if(ModRow >= 64)\r
1874 {\r
1875 ModRow = 0;\r
1876 if(++ModPattern >= ModLen)\r
1877 {\r
1878 if(ModRepeat >= ModLen)\r
1879 ModPattern = 0;\r
1880 else\r
1881 ModPattern = ModRepeat;\r
1882 }\r
1883 }\r
1884 }\r
1885 Data = (signed short)SoundBuffer[i] - 128;\r
1886 Data += Data2;\r
1887 if(Data > 127)\r
1888 Data = 127;\r
1889 if(Data < -128)\r
1890 Data = -128;\r
1891 SoundBuffer[i] = (unsigned char)(Data + 128);\r
1892 }\r
1893 }\r
1894 BufferReady = 0;\r
1895}\r
1896\r
1897unsigned long GetString(unsigned short StringNum, unsigned short *Length)\r
1898{\r
1899 unsigned long Offset, Offset2;\r
1900 unsigned short Count;\r
1901\r
1902 Offset = 0;\r
1903 Count = 0;\r
1904 while(Count < StringNum)\r
1905 {\r
1906 if(Strings[Offset++] == 0)\r
1907 Count++;\r
1908 }\r
1909 Offset2 = Offset;\r
1910 while(Strings[Offset2++] != 0);\r
1911 if(Length != NULL)\r
1912 *Length = Offset2 - Offset;\r
1913 return(Offset);\r
1914}\r
1915\r
1916void LoadMenu(unsigned short MenuNum)\r
1917{\r
1918 unsigned long Offset;\r
1919 unsigned short i, o;\r
1920 unsigned short NumItems, CurItem;\r
1921 unsigned char DataLength;\r
1922\r
1923 Offset = 0;\r
1924 CurItem = 0;\r
1925 MenuID = MenuNum;\r
1926 for(i = 0; i <= MenuNum; i++)\r
1927 {\r
1928 NumItems = *(unsigned short *)(MenuBuffer + Offset);\r
1929 Offset += 2;\r
1930 if(i == MenuNum)\r
1931 NumMenuItems = NumItems;\r
1932 for(o = 0; o < NumItems; o++)\r
1933 {\r
1934 DataLength = MenuBuffer[Offset++];\r
1935 if(i == MenuNum)\r
1936 {\r
1937 MenuItems[0][CurItem] = MenuBuffer + Offset;\r
1938 Offset += DataLength;\r
1939 strcpy(MenuItems[1][CurItem++], Strings + GetString(*(unsigned short *)(MenuBuffer + Offset - 2), NULL));\r
1940 } else {\r
1941 Offset += DataLength;\r
1942 }\r
1943 }\r
1944 }\r
1945}\r
1946\r
1947void LoadLayout(unsigned char NumPlayers)\r
1948{\r
1949 unsigned char i;\r
1950 unsigned short o, Buffer[18];\r
1951 KvidFile LayoutFile;\r
1952\r
1953 for(i = 0; i < MAX_PLAYERS; i++)\r
1954 Players[i]->Visual = 0;\r
1955 if(OpenFile("Layouts", &LayoutFile) == 0)\r
1956 return;\r
1957 for(i = 0; i < NumPlayers - 1; i++)\r
1958 {\r
1959 FileSkip(&LayoutFile, 36 * (i + 1));\r
1960 }\r
1961 for(i = 0; i < NumPlayers; i++)\r
1962 {\r
1963 FileRead((void *)&Buffer, 36, &LayoutFile);\r
1964 Players[i]->Visual = 1;\r
1965 Players[i]->VPointX1 = Buffer[0];\r
1966 Players[i]->VPointY1 = Buffer[1];\r
1967 Players[i]->VPointX2 = Buffer[2];\r
1968 Players[i]->VPointY2 = Buffer[3];\r
1969 Players[i]->AMeterX1 = Buffer[4];\r
1970 Players[i]->AMeterY1 = Buffer[5];\r
1971 Players[i]->AMeterX2 = Buffer[6];\r
1972 Players[i]->AMeterY2 = Buffer[7];\r
1973 Players[i]->LMeterX1 = Buffer[8];\r
1974 Players[i]->LMeterY1 = Buffer[9];\r
1975 Players[i]->LMeterX2 = Buffer[10];\r
1976 Players[i]->LMeterY2 = Buffer[11];\r
1977 Players[i]->lx = Buffer[12];\r
1978 Players[i]->ly = Buffer[13];\r
1979 Players[i]->kx = Buffer[14];\r
1980 Players[i]->ky = Buffer[15];\r
1981 Players[i]->cx = Buffer[16];\r
1982 Players[i]->cy = Buffer[17];\r
1983 for(o = 0; o < NUM_MASKS; o++)\r
1984 {\r
1985 if(Players[i]->Masks[o].Buffer != NULL)\r
1986 free(Players[i]->Masks[o].Buffer);\r
1987 Players[i]->Masks[o].Buffer = (unsigned char *)malloc((Buffer[2] - Buffer[0] + 1) * (Buffer[3] - Buffer[1] + 1) * 4);\r
1988 }\r
1989 }\r
1990 FileClose(&LayoutFile);\r
1991}\r
1992\r
1993unsigned char InitVar(void)\r
1994{\r
1995 unsigned short i, o;\r
1996 KvidFile KeyFile;\r
1997\r
1998 LoadLayout(2);\r
1999 for(i = 0; i < MAX_PLAYERS; i++)\r
2000 {\r
2001 if(i == 0)\r
2002 {\r
2003 if(OpenFile("player1.ctr", &KeyFile) == 0)\r
2004 return(1);\r
2005 }\r
2006 if(i == 1)\r
2007 {\r
2008 if(OpenFile("player2.ctr", &KeyFile) == 0)\r
2009 return(1);\r
2010 }\r
2011 if(i < 2)\r
2012 {\r
2013 for(o = 0; o < 9; o++)\r
2014 FileRead((void *)&Players[i]->KeyCodes[o], 2, &KeyFile);\r
2015 FileClose(&KeyFile);\r
2016 }\r
2017 Players[i]->Angle = 0;\r
2018 Players[i]->AngleVel = 0;\r
2019 Players[i]->Dir = 0;\r
2020 Players[i]->MaxHealth = 500;\r
2021 Players[i]->Health = Players[0]->MaxHealth;\r
2022 Players[i]->Kills = 0;\r
2023 Players[i]->Lives = 5;\r
2024 Players[i]->CurWeapon = 0;\r
2025 /*Players[i]->Masks[0].Method = 1;\r
2026 Players[i]->Masks[0].Effects[0] = 2;*/\r
2027 for(o = 0; o < NUM_WEAPONS; o++)\r
2028 {\r
2029 PWeapons[i][o]->Weapon = o;\r
2030 PWeapons[i][o]->Used = 1;\r
2031 }\r
2032 }\r
2033 for(i = 0; i < MAX_PLAYERS; i++)\r
2034 {\r
2035 for(o = 0; o < NUM_WEAPONS; o++)\r
2036 {\r
2037 if((Players[i]->Used == 1) && (PWeapons[i][o]->Used == 1))\r
2038 {\r
2039 PWeapons[i][o]->AmmoLeft = Weapons[PWeapons[i][o]->Weapon]->Ammo;\r
2040 PWeapons[i][o]->FireTimer = 0;\r
2041 PWeapons[i][o]->ReloadTimer = 0;\r
2042 PWeapons[i][o]->NumClips = Weapons[PWeapons[i][o]->Weapon]->MaxClips;\r
2043 }\r
2044 }\r
2045 }\r
2046 BGSprite = 53;\r
2047 BGFrame = 0;\r
2048 FogSprite = 48;\r
2049 FogX = 0;\r
2050 FogY = 0;\r
2051 return(0);\r
2052}\r
2053\r
2054unsigned char Init(unsigned short *Result)\r
2055{\r
2056 unsigned short i, o;\r
2057 unsigned char Buffer[80], InpBuffer, BufferPos, Finished, Major, Minor;\r
2058 unsigned long LastPos, Offset, Size, u, BkAU;\r
2059 unsigned short DataLength, Count, BkOffset;\r
2060 KvidFile OpenedFile, OpenedFile2;\r
2061 KvidFile SoundFile;\r
2062\r
2063 printf("Initializing...\n");\r
2064 MainDat = NULL;\r
2065 if((OpenDatFile("kvid.dat", &DataFile) == 0) || (DataFile.CanWrite == 0))\r
2066 return(3);\r
2067 MainDat = &DataFile;\r
2068 if(DebugMode != 0)\r
2069 printf("Initializing double buffer...\n");\r
2070 DBSetClip(0, 0, 319, 199);\r
2071 if(DebugMode != 0)\r
2072 printf("Initializing level...\n");\r
2073 MaxLW = 3200;\r
2074 MaxLH = 2000;\r
2075 for(i = 0; i < NUM_PLANES; i++)\r
2076 {\r
2077 if((LevelBuffer[i] = (unsigned char *)malloc(MaxLW * MaxLH * ((i == 0)?4:1))) == NULL)\r
2078 return(2);\r
2079 }\r
2080 if(DebugMode != 0)\r
2081 printf("Initializing variables...\n");\r
2082 for(i = 0; i < MAX_HITTESTS; i++)\r
2083 {\r
2084 HitTests[i] = 0xFFFF;\r
2085 }\r
2086 for(i = 0; i < MAX_PIXELS; i++)\r
2087 {\r
2088 if((Pixels[i] = (Pixel *)malloc(sizeof(Pixel))) == NULL)\r
2089 return(2);\r
2090 Pixels[i]->Used = 0;\r
2091 }\r
2092 for(i = 0; i < MAX_SPRITES; i++)\r
2093 {\r
2094 if((Sprites[i] = (Sprite *)malloc(sizeof(Sprite))) == NULL)\r
2095 return(2);\r
2096 Sprites[i]->Used = 0;\r
2097 }\r
2098 for(i = 0; i < MAX_OBJECTS; i++)\r
2099 {\r
2100 if((Objects[i] = (Object *)malloc(sizeof(Object))) == NULL)\r
2101 return(2);\r
2102 Objects[i]->Used = 0;\r
2103 }\r
2104 for(i = 0; i < MAX_OBJLISTS; i++)\r
2105 {\r
2106 if((ObjectLists[i] = (ObjectList *)malloc(sizeof(ObjectList))) == NULL)\r
2107 return(2);\r
2108 ObjectLists[i]->Used = 0;\r
2109 }\r
2110 for(i = 0; i < MAX_PLAYERS; i++)\r
2111 {\r
2112 if((Players[i] = (Player *)malloc(sizeof(Player))) == NULL)\r
2113 return(2);\r
2114 Players[i]->Used = 0;\r
2115 Players[i]->Visual = 0;\r
2116 for(o = 0; o < NUM_MASKS; o++)\r
2117 {\r
2118 Players[i]->Masks[o].Buffer = NULL;\r
2119 Players[i]->Masks[o].Method = 0;\r
2120 for(u = 0; u < 16; u++)\r
2121 Players[i]->Masks[o].Effects[u] = 0;\r
2122 }\r
2123 }\r
2124 for(i = 0; i < MAX_PLAYERS; i++)\r
2125 {\r
2126 for(o = 0; o < NUM_WEAPONS; o++)\r
2127 {\r
2128 if((PWeapons[i][o] = (PWeapon *)malloc(sizeof(PWeapon))) == NULL)\r
2129 return(2);\r
2130 PWeapons[i][o]->Used = 0;\r
2131 }\r
2132 }\r
2133 for(i = 0; i < MAX_LINES; i++)\r
2134 {\r
2135 if((Lines[i] = (Line *)malloc(sizeof(Line))) == NULL)\r
2136 return(2);\r
2137 Lines[i]->Used = 0;\r
2138 }\r
2139 for(i = 0; i < MAX_RASTERS; i++)\r
2140 {\r
2141 if((Rasters[i] = (Raster *)malloc(sizeof(Raster))) == NULL)\r
2142 return(2);\r
2143 Rasters[i]->Used = 0;\r
2144 }\r
2145 for(i = 0; i < MAX_MENUITEMS; i++)\r
2146 {\r
2147 if((MenuItems[1][i] = (unsigned char *)malloc(128)) == NULL)\r
2148 return(2);\r
2149 }\r
2150 for(i = 0; i < MAX_SOUNDS; i++)\r
2151 {\r
2152 Sounds[i].Playing = 0;\r
2153 }\r
2154 if((MenuBuffer = (unsigned char *)malloc(16384)) == NULL)\r
2155 return(2);\r
2156 if((TextBuffer = (unsigned char *)malloc(500)) == NULL)\r
2157 return(2);\r
2158 if((KeyboardBuffer = (unsigned char *)malloc(500)) == NULL)\r
2159 return(2);\r
2160 if((LevelFileName = (unsigned char *)malloc(100)) == NULL)\r
2161 return(2);\r
2162 if((Patterns = (ModEvent *)malloc(MAX_PATTERNS * 512 * sizeof(ModEvent))) == NULL)\r
2163 return(2);\r
2164 if((SoundBuffer = (unsigned char *)malloc(SB_SIZE >> 1)) == NULL)\r
2165 return(2);\r
2166 for(i = 0; i < SB_SIZE >> 1; i++)\r
2167 SoundBuffer[i] = 128;\r
2168 TransOps[0] = ColorAdd;\r
2169 TransOps[1] = ColorSub;\r
2170 TransOps[2] = ColorAvr;\r
2171 TransOps[3] = ColorSpc;\r
2172 TransOps[4] = ColorFul;\r
2173 Gravity = 0.02;\r
2174 LevelWidth = 640;\r
2175 LevelHeight = 400;\r
2176 FrameRate = 50;\r
2177 DSPAddress = 0x220;\r
2178 DMAChannel = 1;\r
2179 IRQLine = 5;\r
2180 ModPlaying = 0;\r
2181 MenuActive = 0;\r
2182 EmptyKeyBuffer();\r
2183 srand((unsigned int)time(NULL));\r
2184 for(i = 0; i < 360; i++)\r
2185 {\r
2186 Sine[i] = sin(((float)i / 180) * M_PI);\r
2187 Cosine[i] = cos(((float)i / 180) * M_PI);\r
2188 PreSine[i] = sin(((double)i / 90) * M_PI_2);\r
2189 PreCosine[i] = cos(((double)i / 90) * M_PI_2);\r
2190 WaveForms[0][i] = sin(((float)i / 180) * M_PI);\r
2191 WaveForms[1][i] = (float)(359 - i) / 359;\r
2192 WaveForms[2][i] = (i < 180)?1:0;\r
2193 WaveForms[3][i] = (float)i / 359;\r
2194 WaveForms[4][i] = (i < 180)?((float)i / 179):((float)(179 - (i - 180)) / 179);\r
2195 }\r
2196 for(i = 0; i < MAX_SAMPLES; i++)\r
2197 {\r
2198 Samples[i].Allocated = 0;\r
2199 }\r
2200 if(DebugMode != 0)\r
2201 printf("Loading data...\n");\r
2202 if(OpenFile("Layouts", &OpenedFile) == 0)\r
2203 return(4);\r
2204 FileClose(&OpenedFile);\r
2205 if(DebugMode != 0)\r
2206 printf("Loading menus\n");\r
2207 if(OpenFile("MenuData", &OpenedFile) == 0)\r
2208 return(4);\r
2209 FileRead((void *)&Count, 2, &OpenedFile);\r
2210 Offset = 0;\r
2211 for(i = 0; i < Count; i++)\r
2212 {\r
2213 FileRead((void *)&DataLength, 2, &OpenedFile);\r
2214 *(unsigned short *)(MenuBuffer + Offset) = DataLength;\r
2215 Offset += 2;\r
2216 for(o = 0; o < DataLength; o++)\r
2217 {\r
2218 FileRead((void *)&InpBuffer, 1, &OpenedFile);\r
2219 MenuBuffer[Offset++] = InpBuffer;\r
2220 FileRead((void *)(MenuBuffer + Offset), (unsigned long)InpBuffer, &OpenedFile);\r
2221 Offset += InpBuffer;\r
2222 }\r
2223 }\r
2224 FileClose(&OpenedFile);\r
2225 if(DebugMode != 0)\r
2226 printf("Loading palette...\n");\r
2227 if(OpenFile("DefaultPalette", &OpenedFile) == 0)\r
2228 return(4);\r
2229 FileRead((void *)Palette, sizeof(Pal) * NUM_COLORS, &OpenedFile);\r
2230 FileClose(&OpenedFile);\r
2231 if(DebugMode != 0)\r
2232 printf("Loading color info...\n");\r
2233 if(OpenFile("ColorInfo", &OpenedFile) == 0)\r
2234 return(4);\r
2235 FileRead((void *)ColorInfo, NUM_COLORS, &OpenedFile);\r
2236 FileClose(&OpenedFile);\r
2237 if(DebugMode != 0)\r
2238 printf("Loading ASCII Table...\n");\r
2239 if(OpenFile("AsciiConv", &OpenedFile) == 0)\r
2240 return(4);\r
2241 FileRead((void *)AsciiTable, 512, &OpenedFile);\r
2242 FileClose(&OpenedFile);\r
2243 if(OpenFile("MainAscii", &OpenedFile) == 0)\r
2244 return(4);\r
2245 FileRead((void *)AsciiTable2, 256, &OpenedFile);\r
2246 FileClose(&OpenedFile);\r
2247 if(DebugMode != 0)\r
2248 printf("Loading strings...\n");\r
2249 if(OpenFile("Strings", &OpenedFile) == 0)\r
2250 return(4);\r
2251 FileRead((void *)&LastPos, 4, &OpenedFile);\r
2252 if((Strings = (unsigned char *)malloc((unsigned short)LastPos)) == NULL)\r
2253 return(2);\r
2254 for(Offset = 0; Offset < LastPos; Offset++)\r
2255 Strings[Offset] = FileGetChar(&OpenedFile);\r
2256 FileClose(&OpenedFile);\r
2257 if(PLAY_TIME > 0)\r
2258 {\r
2259 if((OpenFile("BetaTime", &OpenedFile) == 0) || (OpenedFile.CanWrite == 0))\r
2260 return(4);\r
2261 FileRead((void *)&Count, 2, &OpenedFile);\r
2262 if(Count != 0x464B)\r
2263 return(4);\r
2264 BkAU = OpenedFile.CurAU;\r
2265 BkOffset = OpenedFile.Offset;\r
2266 FileRead((void *)&NumPlays, 1, &OpenedFile);\r
2267 if(NumPlays == 0)\r
2268 {\r
2269 printf("Your beta version has expired!\n");\r
2270 return(4);\r
2271 }\r
2272 OpenedFile.CurAU = BkAU;\r
2273 OpenedFile.Offset = BkOffset;\r
2274 OpenedFile.ReSeek = 1;\r
2275 FilePutChar(--NumPlays, &OpenedFile);\r
2276 printf("You have %u time(s) left to play!\n", (unsigned short)NumPlays);\r
2277 }\r
2278 if(DebugMode != 0)\r
2279 printf("Loading sprites...\n");\r
2280 if(OpenFile("SpriteCache", &OpenedFile) == 0)\r
2281 return(4);\r
2282 FileRead((void *)&NumSprites, 2, &OpenedFile);\r
2283 if((Caches = (Cache **)malloc(4 * NumSprites)) == NULL)\r
2284 return(2);\r
2285 for(i = 0; i < NumSprites; i++)\r
2286 {\r
2287 if((Caches[i] = (Cache *)malloc(sizeof(Cache))) == NULL)\r
2288 return(2);\r
2289 BufferPos = 0;\r
2290 Finished = 0;\r
2291 while(Finished == 0)\r
2292 {\r
2293 InpBuffer = FileGetChar(&OpenedFile);\r
2294 if(InpBuffer == 0)\r
2295 {\r
2296 Buffer[BufferPos] = 0;\r
2297 OpenedFile.ReSeek = 1;\r
2298 switch(LoadSprite((unsigned char *)Buffer, i))\r
2299 {\r
2300 case 1:\r
2301 return(4);\r
2302 case 2:\r
2303 return(2);\r
2304 }\r
2305 if(strcmp((char *)Buffer, (unsigned char *)"Spr_Font") == 0)\r
2306 FontSprite = i;\r
2307 Finished = 1;\r
2308 } else {\r
2309 Buffer[BufferPos++] = InpBuffer;\r
2310 }\r
2311 }\r
2312 }\r
2313 FileClose(&OpenedFile);\r
2314 if(DebugMode != 0)\r
2315 printf("Loading classes...\n");\r
2316 if(OpenFile("Classes", &OpenedFile) == 0)\r
2317 return(4);\r
2318 FileRead((void *)&NumClasses, 2, &OpenedFile);\r
2319 if((Classes = (Class **)malloc(4 * NumClasses)) == NULL)\r
2320 return(2);\r
2321 for(i = 0; i < NumClasses; i++)\r
2322 {\r
2323 if((Classes[i] = (Class *)malloc(sizeof(Class))) == NULL)\r
2324 return(2);\r
2325 FileRead((void *)&Classes[i]->Scripts, 2 * NUM_SCRIPTS, &OpenedFile);\r
2326 FileRead((void *)&Classes[i]->TickDelay, 1, &OpenedFile);\r
2327 FileRead((void *)&Classes[i]->GravityMod, 2, &OpenedFile);\r
2328 FileRead((void *)&Classes[i]->Sprite, 1, &OpenedFile);\r
2329 FileRead((void *)&Classes[i]->StartFrame, 1, &OpenedFile);\r
2330 FileRead((void *)&Classes[i]->RunHitTests, 1, &OpenedFile);\r
2331 FileRead((void *)&Classes[i]->TouchDelay, 1, &OpenedFile);\r
2332 FileRead((void *)&Classes[i]->TransSprite, 1, &OpenedFile);\r
2333 FileRead((void *)&DataLength, 2, &OpenedFile);\r
2334 if((Classes[i]->Code = (unsigned char *)malloc(DataLength)) == NULL)\r
2335 return(2);\r
2336 FileRead((void *)Classes[i]->Code, DataLength, &OpenedFile);\r
2337 }\r
2338 FileClose(&OpenedFile);\r
2339 if(DebugMode != 0)\r
2340 printf("Loading sounds...\n");\r
2341 UseSound = 1;\r
2342 FreeSound = 1;\r
2343 if(OpenDatFile("kvidsnd.dat", &SoundFile) == 0)\r
2344 {\r
2345 printf("Couldn't find sound file KVIDSND.DAT!\nUsing no sound...\n");\r
2346 UseSound = 0;\r
2347 FreeSound = 0;\r
2348 }\r
2349 if(UseSound == 1)\r
2350 {\r
2351 if(OpenNestedFile("LoadSound", &OpenedFile, &SoundFile, NULL) == 0)\r
2352 {\r
2353 printf("Sound file corrupt!\nUsing no sound...\n");\r
2354 UseSound = 0;\r
2355 FreeSound = 0;\r
2356 }\r
2357 }\r
2358 if(UseSound == 1)\r
2359 {\r
2360 FileRead((void *)&NumSounds, 2, &OpenedFile);\r
2361 if((SoundCaches = (SoundCache **)malloc(NumSounds << 2)) == NULL)\r
2362 return(2);\r
2363 for(i = 0; i < NumSounds; i++)\r
2364 SoundCaches[i] = NULL;\r
2365 BufferPos = 0;\r
2366 for(i = 0; i < NumSounds; i++)\r
2367 {\r
2368 OpenedFile.ReSeek = 1;\r
2369 for(BufferPos = 0; (Buffer[BufferPos] = FileGetChar(&OpenedFile)) != 0; BufferPos++);\r
2370 if(OpenNestedFile(Buffer, &OpenedFile2, &SoundFile, NULL) == 0)\r
2371 {\r
2372 printf("Sound file corrupt!\nUsing no sound...\n");\r
2373 UseSound = 0;\r
2374 break;\r
2375 }\r
2376 Offset = 0;\r
2377 if((SoundCaches[i] = (SoundCache *)malloc(sizeof(SoundCache))) == NULL)\r
2378 return(2);\r
2379 FileRead((void *)&Size, 4, &OpenedFile2);\r
2380 SoundCaches[i]->Length = Size;\r
2381 if((SoundCaches[i]->SoundBuffer = (unsigned char *)malloc(Size)) == NULL)\r
2382 return(2);\r
2383 DataLength = 0;\r
2384 for(u = 0; u <= Size; u++)\r
2385 {\r
2386 if(DataLength > 0)\r
2387 {\r
2388 SoundCaches[i]->SoundBuffer[Offset++] = InpBuffer;\r
2389 DataLength--;\r
2390 }\r
2391 if(DataLength == 0)\r
2392 {\r
2393 DataLength = 1;\r
2394 if((InpBuffer = FileGetChar(&OpenedFile2)) >= 192)\r
2395 {\r
2396 DataLength = InpBuffer - 191;\r
2397 InpBuffer = FileGetChar(&OpenedFile2);\r
2398 }\r
2399 }\r
2400 }\r
2401 FileClose(&OpenedFile2);\r
2402 }\r
2403 FileClose(&OpenedFile);\r
2404 FileClose(&SoundFile);\r
2405 }\r
2406 if(OpenFile("WeaponInfo", &OpenedFile) == 0)\r
2407 return(4);\r
2408 FileRead((void *)&NumWeapons, 2, &OpenedFile);\r
2409 if((Weapons = (Weapon **)malloc(4 * NumWeapons)) == NULL)\r
2410 return(2);\r
2411 for(i = 0; i < NumWeapons; i++)\r
2412 {\r
2413 if((Weapons[i] = (Weapon *)malloc(sizeof(Weapon))) == NULL)\r
2414 return(2);\r
2415 FileRead((void *)&Weapons[i]->Class, 2, &OpenedFile);\r
2416 FileRead((void *)&Weapons[i]->ReloadDelay, 2, &OpenedFile);\r
2417 FileRead((void *)&Weapons[i]->FireDelay, 2, &OpenedFile);\r
2418 FileRead((void *)&Weapons[i]->Ammo, 2, &OpenedFile);\r
2419 FileRead((void *)&Weapons[i]->MaxClips, 2, &OpenedFile);\r
2420 Weapons[i]->Name = 0;\r
2421 FileRead((void *)&Weapons[i]->Name, 2, &OpenedFile);\r
2422 Weapons[i]->Name = GetString((unsigned short)Weapons[i]->Name, (unsigned short *)&Weapons[i]->NameLength);\r
2423 }\r
2424 FileClose(&OpenedFile);\r
2425 if(OpenFile("MainFont", &OpenedFile) == 0)\r
2426 return(4);\r
2427 if((FontBuffer = (unsigned short *)malloc(16384)) == NULL)\r
2428 return(2);\r
2429 memset((void *)FontBuffer, 0, 16384);\r
2430 Offset = 0;\r
2431 Size = 1;\r
2432 for(i = 0; (i < 256) && (Size != 0); i++)\r
2433 {\r
2434 Size = 0;\r
2435 FileRead((void *)&Size, 2, &OpenedFile);\r
2436 FontBuffer[(i << 1)] = (unsigned short)Offset;\r
2437 FontBuffer[(i << 1) + 1] = (unsigned short)Size;\r
2438 for(o = 0; o < Size * 5; o++)\r
2439 {\r
2440 FileRead((void *)&FontBuffer[Offset + 512], 4, &OpenedFile);\r
2441 Offset += 2;\r
2442 }\r
2443 }\r
2444 FileClose(&OpenedFile);\r
2445 if(DebugMode != 0)\r
2446 printf("Initializing hardware...\n");\r
2447 if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) != 0)\r
2448 {\r
2449 printf("%s\n", SDL_GetError());\r
2450 return(0);\r
2451 }\r
2452 if((UseSound == 1) && (SBReset() != 0))\r
2453 {\r
2454 printf("Sound Blaster hardware reset failed!\n");\r
2455 UseSound = 0;\r
2456 }\r
2457 if(UseSound == 1)\r
2458 {\r
2459 SBSampleRate = 44100;\r
2460 } else {\r
2461 printf("Using no sound...\n");\r
2462 }\r
2463 VBuffer = SDL_SetVideoMode(320, 200, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);\r
2464 BPP = VBuffer->format->BytesPerPixel * 8;\r
2465 if(BPP != 32)\r
2466 {\r
2467 printf("Video mode format mismatch (BPP = %i)\n", BPP);\r
2468 return(1);\r
2469 }\r
2470 DblBuffer = VBuffer->pixels;\r
2471 FullScreen = 0;\r
2472 printf("Done!\n");\r
2473/* getch(); */\r
2474 SetMode(1);\r
2475 if(UseSound == 1)\r
2476 {\r
2477 ReadyBuffer = 0;\r
2478 BufferReady = 0;\r
2479 FillBuffer();\r
2480 ReadyBuffer = 1;\r
2481 StartPlayBack();\r
2482 }\r
2483 return(0xFF);\r
2484}\r
2485\r
2486void Terminate(void)\r
2487{\r
2488 unsigned short i, o;\r
2489\r
2490 SetMode(0);\r
2491 SDL_Quit();\r
2492 FileClose(&DataFile);\r
2493 MainDat = NULL;\r
2494 for(i = 0; i < NUM_PLANES; i++)\r
2495 free(LevelBuffer[i]);\r
2496 if(FontBuffer != NULL)\r
2497 free(FontBuffer);\r
2498 if(FreeSound == 1)\r
2499 {\r
2500 for(i = 0; i < NumSounds; i++)\r
2501 {\r
2502 if(SoundCaches[i] != NULL)\r
2503 {\r
2504 free(SoundCaches[i]->SoundBuffer);\r
2505 free(SoundCaches[i]);\r
2506 }\r
2507 }\r
2508 free(SoundCaches);\r
2509 }\r
2510 if(UseSound == 1)\r
2511 TerminatePlayBack();\r
2512 for(i = 0; i < MAX_PIXELS; i++)\r
2513 {\r
2514 if(Pixels[i] != NULL)\r
2515 free(Pixels[i]);\r
2516 }\r
2517 for(i = 0; i < NumSprites; i++)\r
2518 {\r
2519 if(Caches[i] != NULL)\r
2520 {\r
2521 if(Caches[i]->cx != NULL)\r
2522 free(Caches[i]->cx);\r
2523 if(Caches[i]->cy != NULL)\r
2524 free(Caches[i]->cy);\r
2525 if(Caches[i]->Frames != NULL)\r
2526 {\r
2527 for(o = 0; o < Caches[i]->NumFrames; o++)\r
2528 {\r
2529 if(Caches[i]->Frames[o] != NULL)\r
2530 free(Caches[i]->Frames[o]);\r
2531 }\r
2532 free(Caches[i]->Frames);\r
2533 }\r
2534 free(Caches[i]);\r
2535 }\r
2536 }\r
2537 if(Caches != NULL)\r
2538 free(Caches);\r
2539 for(i = 0; i < MAX_SPRITES; i++)\r
2540 {\r
2541 if(Sprites[i] != NULL)\r
2542 free(Sprites[i]);\r
2543 }\r
2544 for(i = 0; i < MAX_PLAYERS; i++)\r
2545 {\r
2546 if(Players[i] != NULL)\r
2547 {\r
2548 for(o = 0; o < NUM_MASKS; o++)\r
2549 {\r
2550 if(Players[i]->Masks[o].Buffer != NULL)\r
2551 free(Players[i]->Masks[o].Buffer);\r
2552 }\r
2553 free(Players[i]);\r
2554 }\r
2555 }\r
2556 for(i = 0; i < MAX_OBJECTS; i++)\r
2557 {\r
2558 if(Objects[i] != NULL)\r
2559 free(Objects[i]);\r
2560 }\r
2561 for(i = 0; i < NumClasses; i++)\r
2562 {\r
2563 if(Classes[i]->Code != NULL)\r
2564 free(Classes[i]->Code);\r
2565 if(Classes[i] != NULL)\r
2566 free(Classes[i]);\r
2567 }\r
2568 if(Classes != NULL)\r
2569 free(Classes);\r
2570 for(i = 0; i < NumWeapons; i++)\r
2571 {\r
2572 if(Weapons[i] != NULL)\r
2573 free(Weapons[i]);\r
2574 }\r
2575 if(Weapons != NULL)\r
2576 free(Weapons);\r
2577 for(i = 0; i < MAX_PLAYERS; i++)\r
2578 {\r
2579 for(o = 0; o < NUM_WEAPONS; o++)\r
2580 {\r
2581 if(PWeapons[i][o] != NULL)\r
2582 free(PWeapons[i][o]);\r
2583 }\r
2584 }\r
2585 for(i = 0; i < MAX_LINES; i++)\r
2586 {\r
2587 if(Lines[i] != NULL)\r
2588 free(Lines[i]);\r
2589 }\r
2590 for(i = 0; i < MAX_RASTERS; i++)\r
2591 {\r
2592 if(Rasters[i] != NULL)\r
2593 free(Rasters[i]);\r
2594 }\r
2595 for(i = 0; i < MAX_MENUITEMS; i++)\r
2596 {\r
2597 if(MenuItems[1][i] != NULL)\r
2598 free(MenuItems[1][i]);\r
2599 }\r
2600 if(Strings != NULL)\r
2601 free(Strings);\r
2602 if(MenuBuffer != NULL)\r
2603 free(MenuBuffer);\r
2604 if(TextBuffer != NULL)\r
2605 free(TextBuffer);\r
2606 if(KeyboardBuffer != NULL)\r
2607 free(KeyboardBuffer);\r
2608 if(LevelFileName != NULL)\r
2609 free(LevelFileName);\r
2610 if(SoundBuffer != NULL)\r
2611 free(SoundBuffer);\r
2612 if(Patterns != NULL)\r
2613 free(Patterns);\r
2614 for(i = 0; i < MAX_SAMPLES; i++)\r
2615 {\r
2616 if(Samples[i].Allocated != 0)\r
2617 free(Samples[i].Buffer);\r
2618 }\r
2619}\r
2620\r
2621void HurtRadius(signed short x, signed short y, signed short StartDamage, signed short StopDamage, unsigned short StartDecRadius, unsigned short StopRadius, unsigned char Owner)\r
2622{\r
2623 unsigned short i;\r
2624 signed long square, xdist, ydist;\r
2625 unsigned short Radius, Sprite;\r
2626 unsigned short Template;\r
2627 signed short Damage;\r
2628\r
2629 for(i = 0; i < MAX_OBJECTS; i++)\r
2630 {\r
2631 if(Objects[i]->Used == 1)\r
2632 {\r
2633 if((Objects[i]->SpriteLink != 0xFFFF) && (Sprites[Objects[i]->SpriteLink]->Template != 0xFF))\r
2634 {\r
2635 Sprite = Objects[i]->SpriteLink;\r
2636 Template = (unsigned short)Sprites[Sprite]->Template;\r
2637 xdist = (signed long)(x - (signed short)Objects[i]->x + Caches[Template]->cx[Sprites[Sprite]->CurFrame]);\r
2638 ydist = (signed long)(y - (signed short)Objects[i]->y + Caches[Template]->cy[Sprites[Sprite]->CurFrame]);\r
2639 if(xdist < 0) xdist = 0;\r
2640 if(ydist < 0) ydist = 0;\r
2641 if(xdist > (signed long)Caches[Template]->w) xdist = (signed long)Caches[Template]->w;\r
2642 if(ydist > (signed long)Caches[Template]->h) ydist = (signed long)Caches[Template]->h;\r
2643 xdist += (signed long)Objects[i]->x - (signed long)Caches[Template]->cx[Sprites[Sprite]->CurFrame];\r
2644 ydist += (signed long)Objects[i]->y - (signed long)Caches[Template]->cy[Sprites[Sprite]->CurFrame];\r
2645 } else {\r
2646 xdist = (signed long)Objects[i]->x;\r
2647 ydist = (signed long)Objects[i]->y;\r
2648 }\r
2649 xdist = (signed long)(x - (signed short)xdist);\r
2650 ydist = (signed long)(y - (signed short)ydist);\r
2651 square = (xdist * xdist) + (ydist * ydist);\r
2652 Radius = (unsigned short)sqrt((double)square);\r
2653 if(Radius < StopRadius)\r
2654 {\r
2655 if(Radius < StartDecRadius)\r
2656 {\r
2657 Damage = StartDamage;\r
2658 } else {\r
2659 Damage = (unsigned short)((((float)(Radius - StartDecRadius) / (float)(StopRadius - StartDecRadius)) * (float)(StartDamage - StopDamage)) + StopDamage);\r
2660 }\r
2661 Regs[16] = (signed short)i;\r
2662 Regs[17] = (signed short)Damage;\r
2663 Regs[18] = (signed short)Owner;\r
2664 Regs[19] = (signed short)Objects[i]->x;\r
2665 Regs[20] = (signed short)Objects[i]->y;\r
2666 Execute(Classes[Objects[i]->Class]->Code, (signed short *)&Objects[i]->Variables[0], Classes[Objects[i]->Class]->Scripts[3]); //TakeDamage\r
2667 }\r
2668 }\r
2669 }\r
2670}\r
2671\r
2672unsigned char SpritesOverlap(unsigned char Cache1, unsigned short Frame1, unsigned char Cache2, unsigned short Frame2, signed short dx, signed short dy)\r
2673{\r
2674 signed short x, y;\r
2675 unsigned short w, h;\r
2676 unsigned char *Buffer1;\r
2677 unsigned char *Buffer2;\r
2678 unsigned long Offset;\r
2679 unsigned long Data;\r
2680\r
2681 Buffer1 = Caches[Cache1]->Frames[Frame1];\r
2682 Buffer2 = Caches[Cache2]->Frames[Frame2];\r
2683 dx += Caches[Cache1]->cx[Frame1];\r
2684 dy += Caches[Cache1]->cy[Frame1];\r
2685 dx -= Caches[Cache2]->cx[Frame2];\r
2686 dy -= Caches[Cache2]->cy[Frame2];\r
2687 w = Caches[Cache2]->w;\r
2688 h = Caches[Cache2]->h;\r
2689 Offset = 0;\r
2690 y = dy;\r
2691 for(y = -dy; y < (signed short)Caches[Cache1]->h - dy; y++)\r
2692 {\r
2693 if((y < (signed short)h) && (y >= 0))\r
2694 {\r
2695 for(x = -dx; x < (signed short)Caches[Cache1]->w - dx; x++)\r
2696 {\r
2697 if((x < (signed short)w) && (x >= 0))\r
2698 {\r
2699 Data = *(unsigned long *)Buffer1;\r
2700 Buffer1 += 4;\r
2701 if(Data != 0)\r
2702 {\r
2703 if(*(unsigned long *)&Buffer2[(x + (y * w)) << 2] != 0)\r
2704 return(1);\r
2705 }\r
2706 } else {\r
2707 Buffer1 += 4;\r
2708 }\r
2709 }\r
2710 } else {\r
2711 Buffer1 += Caches[Cache1]->w << 2;\r
2712 }\r
2713 }\r
2714 return(0);\r
2715}\r
2716\r
2717void __inline GetNextLineCoord(signed short *x, signed short *y, signed short *d, unsigned short dx, unsigned short dy, signed short xi, signed short yi)\r
2718{\r
2719 if(dx > dy)\r
2720 {\r
2721 *d += dy;\r
2722 if(*d > dx)\r
2723 {\r
2724 *d -= dx;\r
2725 *y += yi;\r
2726 }\r
2727 *x += xi;\r
2728 } else {\r
2729 *d += dx;\r
2730 if(*d > 0)\r
2731 {\r
2732 *d -= dy;\r
2733 *x += xi;\r
2734 }\r
2735 *y += yi;\r
2736 }\r
2737}\r
2738\r
2739unsigned short HitTest(signed short x, signed short y, unsigned short ObjNum, unsigned char TestCache, unsigned short TestFrame)\r
2740{\r
2741 unsigned short i;\r
2742 unsigned short SpriteLink;\r
2743 unsigned char Template;\r
2744 signed short tx1, ty1, tx2, ty2;\r
2745 unsigned long Offset;\r
2746 unsigned char *FrameBuffer;\r
2747\r
2748 for(i = 0; i < MAX_HITTESTS; i++)\r
2749 {\r
2750 if(HitTests[i] == 0xFFFF)\r
2751 break;\r
2752 if(HitTests[i] == ObjNum)\r
2753 continue;\r
2754 SpriteLink = Objects[HitTests[i]]->SpriteLink;\r
2755 if(SpriteLink != 0xFFFF)\r
2756 {\r
2757 Template = Sprites[SpriteLink]->Template;\r
2758 if(TestCache == 0xFF)\r
2759 {\r
2760 tx1 = x;\r
2761 ty1 = y;\r
2762 tx2 = x;\r
2763 ty2 = y;\r
2764 } else {\r
2765 tx1 = x - Caches[TestCache]->cx[TestFrame];\r
2766 ty1 = y - Caches[TestCache]->cy[TestFrame];\r
2767 tx2 = tx1 + Caches[TestCache]->w;\r
2768 ty2 = ty1 + Caches[TestCache]->h;\r
2769 }\r
2770 if((tx2 >= Sprites[SpriteLink]->x - Caches[Template]->cx[Sprites[SpriteLink]->CurFrame]) && (ty2 >= Sprites[SpriteLink]->y - Caches[Template]->cy[Sprites[SpriteLink]->CurFrame]) && (tx1 < Sprites[SpriteLink]->x - Caches[Template]->cx[Sprites[SpriteLink]->CurFrame] + Caches[Template]->w) && (ty1 < Sprites[SpriteLink]->y - Caches[Template]->cy[Sprites[SpriteLink]->CurFrame] + Caches[Template]->h))\r
2771 {\r
2772 if(TestCache == 0xFF)\r
2773 {\r
2774 Offset = x - Sprites[SpriteLink]->x + Caches[Template]->cx[Sprites[SpriteLink]->CurFrame];\r
2775 Offset += (y - Sprites[SpriteLink]->y + Caches[Template]->cy[Sprites[SpriteLink]->CurFrame]) * Caches[Template]->w;\r
2776 FrameBuffer = Caches[Template]->Frames[Sprites[SpriteLink]->CurFrame];\r
2777 if((Offset < Caches[Template]->w * Caches[Template]->h) && (*(unsigned long *)&FrameBuffer[Offset << 2] != 0))\r
2778 return(HitTests[i]);\r
2779 } else {\r
2780 if(SpritesOverlap(TestCache, TestFrame, Template, Sprites[SpriteLink]->CurFrame, Sprites[SpriteLink]->x - x, Sprites[SpriteLink]->y - y) == 1)\r
2781 return(HitTests[i]);\r
2782 }\r
2783 }\r
2784 }\r
2785 }\r
2786 return(0xFFFF);\r
2787}\r
2788\r
2789unsigned char CollisionTest(signed short *x1, signed short *y1, signed short *x2, signed short *y2, unsigned char Pattern, unsigned char RunHitTests, unsigned short *ObjNum, unsigned char TestCache, unsigned short TestFrame)\r
2790{\r
2791 unsigned short i;\r
2792 signed short dx, dy, x, y, fx, fy;\r
2793 signed short xi, yi, d;\r
2794 unsigned long Data;\r
2795 unsigned char Collided;\r
2796 unsigned short Object, ObjectList, NumObjects;\r
2797\r
2798 dx = *x2 - *x1;\r
2799 dy = *y2 - *y1;\r
2800 if(dx >= 0)\r
2801 {\r
2802 xi = 1;\r
2803 } else {\r
2804 xi = -1;\r
2805 dx = -dx;\r
2806 }\r
2807 if(dy >= 0)\r
2808 {\r
2809 yi = 1;\r
2810 } else {\r
2811 yi = -1;\r
2812 dy = -dy;\r
2813 }\r
2814 d = 0;\r
2815 x = *x1;\r
2816 y = *y1;\r
2817 Collided = 0;\r
2818 ObjectList = 0xFFFF;\r
2819 if(dx > dy)\r
2820 {\r
2821 for(i = 0; i <= dx; i++)\r
2822 {\r
2823 fx = x;\r
2824 fy = y;\r
2825 d += dy;\r
2826 if(d > dx)\r
2827 {\r
2828 d -= dx;\r
2829 y += yi;\r
2830 }\r
2831 x += xi;\r
2832 Data = GetMapPixel((unsigned short)x, (unsigned short)y, 1);\r
2833 if((Data & Pattern) == 0)\r
2834 {\r
2835 *x1 = fx;\r
2836 *y1 = fy;\r
2837 *x2 = x;\r
2838 *y2 = y;\r
2839 if(Collided == 2)\r
2840 *ObjNum = ObjectList;\r
2841 return(1 | Collided);\r
2842 }\r
2843 if(RunHitTests != 0)\r
2844 {\r
2845 if((Object = HitTest(x, y, *ObjNum, TestCache, TestFrame)) != 0xFFFF)\r
2846 {\r
2847 if(RunHitTests == 1)\r
2848 {\r
2849 *x1 = fx;\r
2850 *y1 = fy;\r
2851 *x2 = x;\r
2852 *y2 = y;\r
2853 *ObjNum = Object;\r
2854 return(2);\r
2855 } else {\r
2856 if(ObjectList == 0xFFFF)\r
2857 {\r
2858 if((ObjectList = GetObjectList()) == 0xFFFF)\r
2859 {\r
2860 *x1 = fx;\r
2861 *y1 = fy;\r
2862 *x2 = x;\r
2863 *y2 = y;\r
2864 *ObjNum = 0xFFFF;\r
2865 return(2);\r
2866 }\r
2867 }\r
2868 NumObjects = ObjectLists[ObjectList]->NumObjects;\r
2869 ObjectLists[ObjectList]->Objects[NumObjects].Object = Object;\r
2870 ObjectLists[ObjectList]->Objects[NumObjects].x1 = fx;\r
2871 ObjectLists[ObjectList]->Objects[NumObjects].y1 = fy;\r
2872 ObjectLists[ObjectList]->Objects[NumObjects].x2 = x;\r
2873 ObjectLists[ObjectList]->Objects[NumObjects].y2 = y;\r
2874 ObjectLists[ObjectList]->Objects[NumObjects + 1].Object = 0xFFFF;\r
2875 ObjectLists[ObjectList]->NumObjects++;\r
2876 Collided = 2;\r
2877 }\r
2878 }\r
2879 }\r
2880 }\r
2881 } else {\r
2882 for(i = 0; i <= dy; i++)\r
2883 {\r
2884 fx = x;\r
2885 fy = y;\r
2886 d += dx;\r
2887 if(d > 0)\r
2888 {\r
2889 d -= dy;\r
2890 x += xi;\r
2891 }\r
2892 y += yi;\r
2893 Data = GetMapPixel((unsigned short)x, (unsigned short)y, 1);\r
2894 if((Data & Pattern) == 0)\r
2895 {\r
2896 *x1 = fx;\r
2897 *y1 = fy;\r
2898 *x2 = x;\r
2899 *y2 = y;\r
2900 if(Collided == 2)\r
2901 *ObjNum = ObjectList;\r
2902 return(1 | Collided);\r
2903 }\r
2904 if(RunHitTests != 0)\r
2905 {\r
2906 if((Object = HitTest(x, y, *ObjNum, TestCache, TestFrame)) != 0xFFFF)\r
2907 {\r
2908 if(RunHitTests == 1)\r
2909 {\r
2910 *x1 = fx;\r
2911 *y1 = fy;\r
2912 *x2 = x;\r
2913 *y2 = y;\r
2914 *ObjNum = Object;\r
2915 return(2);\r
2916 } else {\r
2917 if(ObjectList == 0xFFFF)\r
2918 {\r
2919 if((ObjectList = GetObjectList()) == 0xFFFF)\r
2920 {\r
2921 *x1 = fx;\r
2922 *y1 = fy;\r
2923 *x2 = x;\r
2924 *y2 = y;\r
2925 *ObjNum = 0xFFFF;\r
2926 return(2);\r
2927 }\r
2928 }\r
2929 NumObjects = ObjectLists[ObjectList]->NumObjects;\r
2930 ObjectLists[ObjectList]->Objects[NumObjects].Object = Object;\r
2931 ObjectLists[ObjectList]->Objects[NumObjects].x1 = fx;\r
2932 ObjectLists[ObjectList]->Objects[NumObjects].y1 = fy;\r
2933 ObjectLists[ObjectList]->Objects[NumObjects].x2 = x;\r
2934 ObjectLists[ObjectList]->Objects[NumObjects].y2 = y;\r
2935 ObjectLists[ObjectList]->Objects[NumObjects + 1].Object = 0xFFFF;\r
2936 ObjectLists[ObjectList]->NumObjects++;\r
2937 Collided = 2;\r
2938 }\r
2939 }\r
2940 }\r
2941 }\r
2942 }\r
2943 return(Collided);\r
2944}\r
2945\r
2946void AddHitTest(unsigned short ObjNum)\r
2947{\r
2948 unsigned short i;\r
2949\r
2950 for(i = 0; i < MAX_HITTESTS; i++)\r
2951 {\r
2952 if(HitTests[i] == 0xFFFF)\r
2953 {\r
2954 HitTests[i] = ObjNum;\r
2955 return;\r
2956 }\r
2957 }\r
2958}\r
2959\r
2960void RemoveHitTest(unsigned short ObjNum)\r
2961{\r
2962 unsigned short i;\r
2963\r
2964 for(i = 0; i < MAX_HITTESTS; i++)\r
2965 {\r
2966 if(HitTests[i] == ObjNum)\r
2967 {\r
2968 for(i = i; i < MAX_HITTESTS; i++)\r
2969 HitTests[i] = HitTests[i + 1];\r
2970 HitTests[MAX_HITTESTS - 1] = 0xFFFF;\r
2971 break;\r
2972 }\r
2973 }\r
2974}\r
2975\r
2976void FontPrint(unsigned char *Buffer, signed short sx, signed short y, unsigned short bgc)\r
2977{\r
2978 unsigned long Offset;\r
2979 unsigned char CurChar;\r
2980 unsigned short CharOffset;\r
2981 signed short x;\r
2982\r
2983 Offset = 0;\r
2984 x = sx;\r
2985 while((CurChar = Buffer[Offset++]) != 0)\r
2986 {\r
2987 switch(CurChar)\r
2988 {\r
2989 case 10:\r
2990 y += 6;\r
2991 break;\r
2992 case 13:\r
2993 x = sx;\r
2994 break;\r
2995 default:\r
2996 if(AsciiTable2[CurChar] != 255)\r
2997 {\r
2998 if(bgc != 0)\r
2999 DBFRect(x, y, x + FontBuffer[(AsciiTable2[CurChar] << 1) + 1], y + 4, bgc);\r
3000 DBCopyBufferClip(x, y, (unsigned char *)&FontBuffer[FontBuffer[AsciiTable2[CurChar] << 1] + 512], FontBuffer[(AsciiTable2[CurChar] << 1) + 1], 5, 0);\r
3001 } else {\r
3002 if(bgc != 0)\r
3003 DBFRect(x, y, x + 2, y + 4, bgc);\r
3004 }\r
3005 x += FontBuffer[(AsciiTable2[CurChar] << 1) + 1] + 1;\r
3006 break;\r
3007 }\r
3008 }\r
3009}\r
3010\r
3011void DBPrint(unsigned char *Buffer, signed short sx, signed short y, unsigned char bgc)\r
3012{\r
3013 unsigned long Offset;\r
3014 unsigned char CurChar;\r
3015 signed short x;\r
3016\r
3017 Offset = 0;\r
3018 x = sx;\r
3019 while((CurChar = Buffer[Offset++]) != 0)\r
3020 {\r
3021 switch(CurChar)\r
3022 {\r
3023 case 10:\r
3024 y += 5;\r
3025 break;\r
3026 case 13:\r
3027 x = sx;\r
3028 break;\r
3029 default:\r
3030 if(AsciiTable[CurChar] != 65535)\r
3031 {\r
3032 DBCopyBufferClip(x, y, Caches[FontSprite]->Frames[AsciiTable[CurChar]], Caches[FontSprite]->w, Caches[FontSprite]->h, bgc);\r
3033 } else {\r
3034 if(bgc != 0)\r
3035 DBFRect(x, y, x + 2, y + 3, MakeColor(0, 0, 0));\r
3036 }\r
3037 x += Caches[FontSprite]->w + 1;\r
3038 break;\r
3039 }\r
3040 }\r
3041}\r
3042\r
3043unsigned short WallAngle(unsigned short x, unsigned short y)\r
3044{\r
3045 return(0);\r
3046}\r
3047\r
3048void SpawnPixel(unsigned short x, unsigned short y, float xv, float yv, unsigned char Owner, unsigned char SetColor, unsigned char Explode, signed short Damage, unsigned long c)\r
3049{\r
3050 unsigned short i;\r
3051\r
3052 for(i = 0; i < MAX_PIXELS; i++)\r
3053 {\r
3054 if(Pixels[i]->Used == 0)\r
3055 {\r
3056 Pixels[i]->x = x;\r
3057 Pixels[i]->y = y;\r
3058 Pixels[i]->xv = xv;\r
3059 Pixels[i]->yv = yv;\r
3060 Pixels[i]->c = c;\r
3061 Pixels[i]->SetColor = SetColor;\r
3062 Pixels[i]->Explode = Explode;\r
3063 Pixels[i]->Damage = Damage;\r
3064 Pixels[i]->Owner = Owner;\r
3065 Pixels[i]->Used = 1;\r
3066 return;\r
3067 }\r
3068 }\r
3069}\r
3070\r
3071void DrawLightning(signed short x1, signed short y1, signed short x2, signed short y2, signed short NumPoints, unsigned char Template)\r
3072{\r
3073 unsigned short i;\r
3074 signed short x, y, fx, fy, nx, ny;\r
3075 unsigned short Dist;\r
3076 unsigned char Rad;\r
3077\r
3078 fx = x1;\r
3079 fy = y1;\r
3080 if(NumPoints <= 0)\r
3081 {\r
3082 while((Dist = (unsigned short)sqrt(((x2 - fx) * (x2 - fx)) + ((y2 - fy) * (y2 - fy)))) > 10)\r
3083 {\r
3084 nx = fx + (((x2 - fx) * 10) / Dist);\r
3085 ny = fy + (((y2 - fy) * 10) / Dist);\r
3086 Rad = -NumPoints;\r
3087 while((GetMapPixel((x = nx + (signed short)(rand() % ((Rad * 2) + 1)) - Rad), (y = ny + (signed short)(rand() % ((Rad * 2) + 1)) - Rad), 1) & MAP_SHOOTABLE) == 0)\r
3088 Rad++;\r
3089 //DrawLine(fx, fy, x, y, 0, 0, 1, Template);\r
3090 DrawLine(fx, fy, x, y, 0, 0, 1, Template);\r
3091 fx = x;\r
3092 fy = y;\r
3093 }\r
3094 DrawLine(fx, fy, x2, y2, 0, 0, 1, Template);\r
3095 } else {\r
3096 for(i = 0; i < NumPoints; i++)\r
3097 {\r
3098 x = x1 + (signed short)(((signed long)(x2 - x1) * (signed long)i) / (signed long)NumPoints);\r
3099 y = y1 + (signed short)(((signed long)(y2 - y1) * (signed long)i) / (signed long)NumPoints);\r
3100 x += (signed short)(rand() % 7) - 3;\r
3101 y += (signed short)(rand() % 7) - 3;\r
3102 DrawLine(fx, fy, x, y, 0, 0, 1, Template);\r
3103 fx = x;\r
3104 fy = y;\r
3105 }\r
3106 }\r
3107}\r
3108\r
3109void DrawLine(signed short x1, signed short y1, signed short x2, signed short y2, unsigned long c1, unsigned long c2, unsigned char Method, unsigned char UseSprite)\r
3110{\r
3111 static unsigned short i = 0;\r
3112 unsigned short Start;\r
3113\r
3114 for(Start = i; i < MAX_LINES; i++)\r
3115 {\r
3116 if(Lines[i]->Used == 0)\r
3117 {\r
3118 Lines[i]->x1 = x1;\r
3119 Lines[i]->y1 = y1;\r
3120 Lines[i]->x2 = x2;\r
3121 Lines[i]->y2 = y2;\r
3122 Lines[i]->c1 = c1;\r
3123 Lines[i]->c2 = c2;\r
3124 Lines[i]->Transparent = Method;\r
3125 Lines[i]->UseSprite = UseSprite;\r
3126 Lines[i]->AnimTimer = 0;\r
3127 Lines[i]->CurFrame = 0;\r
3128 if(UseSprite == 0xFF)\r
3129 Lines[i]->Used = 1;\r
3130 else\r
3131 Lines[i]->Used = Caches[UseSprite]->AnimDelay * Caches[UseSprite]->NumFrames;\r
3132 return;\r
3133 }\r
3134 }\r
3135 for(i = 0; i < Start; i++)\r
3136 {\r
3137 if(Lines[i]->Used == 0)\r
3138 {\r
3139 Lines[i]->x1 = x1;\r
3140 Lines[i]->y1 = y1;\r
3141 Lines[i]->x2 = x2;\r
3142 Lines[i]->y2 = y2;\r
3143 Lines[i]->c1 = c1;\r
3144 Lines[i]->c2 = c2;\r
3145 Lines[i]->Transparent = Method;\r
3146 Lines[i]->UseSprite = UseSprite;\r
3147 Lines[i]->AnimTimer = 0;\r
3148 Lines[i]->CurFrame = 0;\r
3149 if(UseSprite == 0xFF)\r
3150 Lines[i]->Used = 1;\r
3151 else\r
3152 Lines[i]->Used = Caches[UseSprite]->AnimDelay * Caches[UseSprite]->NumFrames;\r
3153 return;\r
3154 }\r
3155 }\r
3156}\r
3157\r
3158void DrawCircle(signed short x, signed short y, unsigned short r, unsigned long Color, unsigned char Transparent)\r
3159{\r
3160 unsigned short i;\r
3161\r
3162 for(i = 0; i < MAX_RASTERS; i++)\r
3163 {\r
3164 if(Rasters[i]->Used == 0)\r
3165 {\r
3166 Rasters[i]->x1 = x;\r
3167 Rasters[i]->y1 = y;\r
3168 Rasters[i]->x2 = r;\r
3169 Rasters[i]->Color = Color;\r
3170 Rasters[i]->Transparent = Transparent;\r
3171 Rasters[i]->Type = 1;\r
3172 Rasters[i]->Used = 1;\r
3173 return;\r
3174 }\r
3175 }\r
3176}\r
3177\r
3178void DrawPoly(signed short x1, signed short y1, signed short x2, signed short y2, signed short x3, signed short y3, unsigned long Color, unsigned char Transparent)\r
3179{\r
3180 unsigned short i;\r
3181\r
3182 for(i = 0; i < MAX_RASTERS; i++)\r
3183 {\r
3184 if(Rasters[i]->Used == 0)\r
3185 {\r
3186 Rasters[i]->x1 = x1;\r
3187 Rasters[i]->y1 = y1;\r
3188 Rasters[i]->x2 = x2;\r
3189 Rasters[i]->y2 = y2;\r
3190 Rasters[i]->x3 = x3;\r
3191 Rasters[i]->y3 = y3;\r
3192 Rasters[i]->Color = Color;\r
3193 Rasters[i]->Transparent = Transparent;\r
3194 Rasters[i]->Type = 0;\r
3195 Rasters[i]->Used = 1;\r
3196 return;\r
3197 }\r
3198 }\r
3199}\r
3200\r
3201unsigned short SpawnObject(unsigned short Class, unsigned char Owner, unsigned short x, unsigned short y, float xv, float yv)\r
3202{\r
3203 static unsigned short i = 0;\r
3204 unsigned short Start;\r
3205\r
3206 for(Start = i; i < MAX_OBJECTS; i++)\r
3207 {\r
3208 if(Objects[i]->Used == 0)\r
3209 {\r
3210 Objects[i]->x = (float)x;\r
3211 Objects[i]->y = (float)y;\r
3212 Objects[i]->xv = xv;\r
3213 Objects[i]->yv = yv;\r
3214 Objects[i]->Class = Class;\r
3215 Objects[i]->Owner = Owner;\r
3216 Objects[i]->TickTimer = 0;\r
3217 Objects[i]->TouchTimer = Classes[Class]->TouchDelay;\r
3218 Objects[i]->SpriteLink = (Classes[Class]->Sprite != 0xFF)?(SpawnSprite(Classes[Class]->Sprite, (signed short)x, (signed short)y, 0, 0, 0, Classes[Class]->StartFrame, Classes[Class]->TransSprite)):0xFFFF;\r
3219 Objects[i]->Used = 1;\r
3220 Regs[16] = i;\r
3221 Execute(Classes[Objects[i]->Class]->Code, (signed short *)&Objects[i]->Variables[0], Classes[Class]->Scripts[2]); //Init\r
3222 return(i);\r
3223 }\r
3224 }\r
3225 for(i = 0; i < Start; i++)\r
3226 {\r
3227 if(Objects[i]->Used == 0)\r
3228 {\r
3229 Objects[i]->x = (float)x;\r
3230 Objects[i]->y = (float)y;\r
3231 Objects[i]->xv = xv;\r
3232 Objects[i]->yv = yv;\r
3233 Objects[i]->Class = Class;\r
3234 Objects[i]->Owner = Owner;\r
3235 Objects[i]->TickTimer = 0;\r
3236 Objects[i]->TouchTimer = Classes[Class]->TouchDelay;\r
3237 Objects[i]->SpriteLink = (Classes[Class]->Sprite != 0xFF)?(SpawnSprite(Classes[Class]->Sprite, (signed short)x, (signed short)y, 0, 0, 0, Classes[Class]->StartFrame, Classes[Class]->TransSprite)):0xFFFF;\r
3238 Objects[i]->Used = 1;\r
3239 Regs[16] = i;\r
3240 Execute(Classes[Objects[i]->Class]->Code, (signed short *)&Objects[i]->Variables[0], Classes[Class]->Scripts[2]); //Init\r
3241 return(i);\r
3242 }\r
3243 }\r
3244 return(0xFFFF);\r
3245}\r
3246\r
3247unsigned short GetObjectList(void)\r
3248{\r
3249 unsigned char i;\r
3250\r
3251 for(i = 0; i < MAX_OBJLISTS; i++)\r
3252 {\r
3253 if(ObjectLists[i]->Used == 0)\r
3254 {\r
3255 ObjectLists[i]->Objects[0].Object = 0xFFFF;\r
3256 ObjectLists[i]->NumObjects = 0;\r
3257 ObjectLists[i]->Used = 1;\r
3258 return(i);\r
3259 }\r
3260 }\r
3261 return(0xFFFF);\r
3262}\r
3263\r
3264void ControlObjects(void)\r
3265{\r
3266 unsigned short i, o;\r
3267 unsigned short Class;\r
3268 signed short fx, fy, nx, ny, dx, dy, x, y;\r
3269 signed short x1, y1, x2, y2, tx1, ty1, tx2, ty2;\r
3270 unsigned char PixelInfo, Collided, Template;\r
3271 unsigned short ObjNum, SpriteLink, TestFrame;\r
3272 unsigned char *FrameBuffer;\r
3273\r
3274 for(i = 0; i < MAX_OBJECTS; i++)\r
3275 {\r
3276 if(Objects[i]->Used == 2)\r
3277 Objects[i]->Used = 0;\r
3278 }\r
3279 for(i = 0; i < MAX_OBJECTS; i++)\r
3280 {\r
3281 if(Objects[i]->Used == 1)\r
3282 {\r
3283 Class = Objects[i]->Class;\r
3284 fx = (signed short)Objects[i]->x;\r
3285 fy = (signed short)Objects[i]->y;\r
3286 Objects[i]->yv += Gravity * ((float)Classes[Class]->GravityMod / 10000);\r
3287 Objects[i]->x += Objects[i]->xv;\r
3288 Objects[i]->y += Objects[i]->yv;\r
3289 if(Objects[i]->TouchTimer > 0)\r
3290 Objects[i]->TouchTimer--;\r
3291 nx = (signed short)Objects[i]->x;\r
3292 ny = (signed short)Objects[i]->y;\r
3293 dx = nx - fx;\r
3294 dy = ny - fy;\r
3295 if(dx < 0)\r
3296 dx = -dx;\r
3297 if(dy < 0)\r
3298 dy = -dy;\r
3299 if((dx > 1) || (dy > 1))\r
3300 {\r
3301 ObjNum = i;\r
3302 SpriteLink = Objects[i]->SpriteLink;\r
3303 if(SpriteLink != 0xFFFF)\r
3304 Template = Sprites[SpriteLink]->Template;\r
3305 else\r
3306 Template = 0xFF;\r
3307 Collided = CollisionTest((signed short *)&fx, (signed short *)&fy, (signed short *)&nx, (signed short *)&ny, MAP_SHOOTABLE, Classes[Class]->RunHitTests, (unsigned short *)&ObjNum, Template, (Template == 0xFF)?0:Sprites[SpriteLink]->CurFrame);\r
3308 } else {\r
3309 Collided = (GetMapPixel((unsigned short)nx, (unsigned short)ny, 1) & MAP_SHOOTABLE) == 0;\r
3310 if(Classes[Class]->RunHitTests == 1)\r
3311 {\r
3312 x = nx;\r
3313 y = ny;\r
3314 if((SpriteLink = Objects[i]->SpriteLink) == 0xFFFF)\r
3315 {\r
3316 Template = 0xFF;\r
3317 } else {\r
3318 Template = Sprites[SpriteLink]->Template;\r
3319 TestFrame = Sprites[SpriteLink]->CurFrame;\r
3320 }\r
3321 if((ObjNum = HitTest(x, y, i, Template, TestFrame)) != 0xFFFF)\r
3322 Collided = 2;\r
3323 /*for(o = 0; o < MAX_HITTESTS; o++)\r
3324 {\r
3325 if(HitTests[o] == 0xFFFF)\r
3326 break;\r
3327 if(HitTests[o] == i)\r
3328 continue;\r
3329 SpriteLink = Objects[HitTests[o]]->SpriteLink;\r
3330 if(SpriteLink != 0xFFFF)\r
3331 {\r
3332 if(SpriteLink != 0xFFFF)\r
3333 Template = Sprites[SpriteLink]->Template;\r
3334 else\r
3335 Template = 0xFF;\r
3336 if(Objects[i]->SpriteLink != 0xFFFF)\r
3337 {\r
3338 SpriteLink2 = Objects[i]->SpriteLink;\r
3339 TestFrame = Sprites[SpriteLink2]->CurFrame;\r
3340 Template2 = Sprites[SpriteLink2]->Template;\r
3341 } else {\r
3342 SpriteLink2 = 0xFFFF;\r
3343 TestFrame = 0;\r
3344 Template2 = 0xFF;\r
3345 }\r
3346 if(Template2 == 0xFF)\r
3347 {\r
3348 tx1 = x;\r
3349 ty1 = y;\r
3350 tx2 = x;\r
3351 ty2 = y;\r
3352 } else {\r
3353 tx1 = x - Caches[Template2]->cx[TestFrame];\r
3354 ty1 = y - Caches[Template2]->cy[TestFrame];\r
3355 tx2 = x - Caches[Template2]->cx[TestFrame] + Caches[Template2]->w;\r
3356 ty2 = y - Caches[Template2]->cy[TestFrame] + Caches[Template2]->h;\r
3357 }\r
3358 if((tx2 >= Sprites[SpriteLink]->x - Caches[Template]->cx[Sprites[SpriteLink]->CurFrame]) && (ty2 >= Sprites[SpriteLink]->y - Caches[Template]->cy[Sprites[SpriteLink]->CurFrame]) && (tx1 < Sprites[SpriteLink]->x - Caches[Template]->cx[Sprites[SpriteLink]->CurFrame] + Caches[Template]->w) && (ty1 < Sprites[SpriteLink]->y - Caches[Template]->cy[Sprites[SpriteLink]->CurFrame] + Caches[Template]->h))\r
3359 {\r
3360 if(Objects[i]->SpriteLink == 0xFFFF)\r
3361 {\r
3362 Offset = x - Sprites[SpriteLink]->x + Caches[Template]->cx[Sprites[SpriteLink]->CurFrame];\r
3363 Offset += (y - Sprites[SpriteLink]->y + Caches[Template]->cy[Sprites[SpriteLink]->CurFrame]) * Caches[Template]->w;\r
3364 FrameBuffer = Caches[Template]->Frames[Sprites[SpriteLink]->CurFrame];\r
3365 if((Offset < Caches[Template]->w * Caches[Template]->h) && (*(unsigned long *)&FrameBuffer[Offset << 2] != 0))\r
3366 {\r
3367 ObjNum = HitTests[o];\r
3368 Collided = 2;\r
3369 break;\r
3370 }\r
3371 } else {\r
3372 if(SpritesOverlap(Template2, TestFrame, Template, Sprites[SpriteLink]->CurFrame, Sprites[SpriteLink]->x - x, Sprites[SpriteLink]->y - y))\r
3373 {\r
3374 ObjNum = HitTests[o];\r
3375 Collided = 2;\r
3376 break;\r
3377 }\r
3378 }\r
3379 }\r
3380 }\r
3381 }*/\r
3382 }\r
3383 }\r
3384 if(Collided != 0)\r
3385 {\r
3386 if((Collided == 2)?((Objects[i]->Owner != 0xFF)?((ObjNum == Players[Objects[i]->Owner]->Object)?(Objects[i]->TouchTimer == 0):1):1):1)\r
3387 {\r
3388 PixelInfo = GetMapPixel((unsigned short)nx, (unsigned short)ny, 1);\r
3389 Regs[16] = i;\r
3390 Regs[17] = fx;\r
3391 Regs[18] = fy;\r
3392 Regs[19] = ((PixelInfo & MAP_SHOOTABLE) == 0)?0:1;\r
3393 Regs[20] = ((PixelInfo & MAP_WALKABLE) == 0)?0:1;\r
3394 Regs[21] = ((PixelInfo & MAP_DESTROYABLE) == 0)?0:1;\r
3395 Regs[22] = nx;\r
3396 Regs[23] = ny;\r
3397 Regs[24] = Collided;\r
3398 Regs[25] = ObjNum;\r
3399 Execute(Classes[Objects[i]->Class]->Code, (signed short *)&Objects[i]->Variables[0], Classes[Class]->Scripts[1]); //Touch\r
3400 }\r
3401 }\r
3402 if((Classes[Class]->TickDelay != 0) && (Objects[i]->Used == 1))\r
3403 {\r
3404 if(++Objects[i]->TickTimer >= Classes[Class]->TickDelay)\r
3405 {\r
3406 PixelInfo = GetMapPixel((unsigned short)Objects[i]->x, (unsigned short)Objects[i]->y, 1);\r
3407 Objects[i]->TickTimer = 0;\r
3408 Regs[16] = i;\r
3409 Regs[17] = (signed short)Objects[i]->x;\r
3410 Regs[18] = (signed short)Objects[i]->y;\r
3411 Regs[19] = ((PixelInfo & MAP_SHOOTABLE) == 0)?0:1;\r
3412 Regs[20] = ((PixelInfo & MAP_WALKABLE) == 0)?0:1;\r
3413 Regs[21] = ((PixelInfo & MAP_DESTROYABLE) == 0)?0:1;\r
3414 Execute(Classes[Objects[i]->Class]->Code, (signed short *)&Objects[i]->Variables[0], Classes[Class]->Scripts[0]); //Tick\r
3415 }\r
3416 }\r
3417 if(Objects[i]->SpriteLink != 0xFFFF)\r
3418 {\r
3419 Sprites[Objects[i]->SpriteLink]->x = (signed short)Objects[i]->x;\r
3420 Sprites[Objects[i]->SpriteLink]->y = (signed short)Objects[i]->y;\r
3421 }\r
3422 }\r
3423 }\r
3424}\r
3425\r
3426void ControlSprites(void)\r
3427{\r
3428 unsigned short i;\r
3429 unsigned char Template;\r
3430\r
3431 for(i = 0; i < MAX_SPRITES; i++)\r
3432 {\r
3433 if(Sprites[i]->Used == 1)\r
3434 {\r
3435 Template = Sprites[i]->Template;\r
3436 Sprites[i]->x += Sprites[i]->xv;\r
3437 Sprites[i]->y += Sprites[i]->yv;\r
3438 if(Sprites[i]->AnimDelay != 0xFF)\r
3439 {\r
3440 if(++Sprites[i]->AnimTimer >= Sprites[i]->AnimDelay)\r
3441 {\r
3442 Sprites[i]->AnimTimer = 0;\r
3443 if(++Sprites[i]->CurFrame >= Caches[Template]->NumFrames)\r
3444 {\r
3445 Sprites[i]->CurFrame = 0;\r
3446 if(Sprites[i]->AnimCount > 0)\r
3447 {\r
3448 if(--Sprites[i]->AnimCount == 0)\r
3449 {\r
3450 Sprites[i]->Used = 0;\r
3451 }\r
3452 }\r
3453 }\r
3454 }\r
3455 }\r
3456 }\r
3457 }\r
3458 for(i = 0; i < MAX_LINES; i++)\r
3459 {\r
3460 if(Lines[i]->Used > 0)\r
3461 {\r
3462 Lines[i]->Used--;\r
3463 if((Lines[i]->UseSprite != 0xFF) && (Caches[Lines[i]->UseSprite]->AnimDelay != 0xFF))\r
3464 {\r
3465 if(++Lines[i]->AnimTimer >= Caches[Lines[i]->UseSprite]->AnimDelay)\r
3466 {\r
3467 Lines[i]->AnimTimer = 0;\r
3468 if(++Lines[i]->CurFrame >= Caches[Lines[i]->UseSprite]->NumFrames)\r
3469 Lines[i]->CurFrame = 0;\r
3470 }\r
3471 }\r
3472 }\r
3473 }\r
3474 for(i = 0; i < MAX_RASTERS; i++)\r
3475 Rasters[i]->Used = 0;\r
3476}\r
3477\r
3478void ControlPixels(void)\r
3479{\r
3480 unsigned short i, o;\r
3481 signed short fx, fy, nx, ny, dx, dy, x, y;\r
3482 unsigned char Collided;\r
3483 unsigned short ObjNum, SpriteLink, Template, Offset;\r
3484 unsigned char *FrameBuffer;\r
3485\r
3486 for(i = 0; i < MAX_PIXELS; i++)\r
3487 {\r
3488 if(Pixels[i]->Used == 1)\r
3489 {\r
3490 fx = (signed short)Pixels[i]->x;\r
3491 fy = (signed short)Pixels[i]->y;\r
3492 Pixels[i]->x += Pixels[i]->xv;\r
3493 Pixels[i]->y += Pixels[i]->yv;\r
3494 nx = (signed short)Pixels[i]->x;\r
3495 ny = (signed short)Pixels[i]->y;\r
3496 dx = nx - fx;\r
3497 dy = ny - fy;\r
3498 if(dx < 0)\r
3499 dx = -dx;\r
3500 if(dy < 0)\r
3501 dy = -dy;\r
3502 if((dx > 1) || (dy > 1))\r
3503 {\r
3504 ObjNum = 0xFFFF;\r
3505 Collided = CollisionTest((signed short *)&fx, (signed short *)&fy, (signed short *)&nx, (signed short *)&ny, MAP_SHOOTABLE, Pixels[i]->Explode, (unsigned short *)&ObjNum, 0xFF, 0);\r
3506 } else {\r
3507 Collided = (GetMapPixel((unsigned short)Pixels[i]->x, (unsigned short)Pixels[i]->y, 1) & MAP_SHOOTABLE) == 0;\r
3508 if(Pixels[i]->Explode == 1)\r
3509 {\r
3510 x = (signed short)Pixels[i]->x;\r
3511 y = (signed short)Pixels[i]->y;\r
3512 if((ObjNum = HitTest(x, y, 0xFFFF, 0xFF, 0)) != 0xFFFF)\r
3513 {\r
3514 Collided = 2;\r
3515 }\r
3516 }\r
3517 }\r
3518 Pixels[i]->yv += Gravity;\r
3519 if(Collided != 0)\r
3520 {\r
3521 if(Pixels[i]->SetColor == 1)\r
3522 {\r
3523 SetMapPixel((unsigned short)nx, (unsigned short)ny, Pixels[i]->c, 0);\r
3524 }\r
3525 if(Pixels[i]->SetColor == 2)\r
3526 {\r
3527 if((GetMapPixel((unsigned short)fx, (unsigned short)fy, 1) & MAP_SHOOTABLE) == MAP_SHOOTABLE)\r
3528 {\r
3529 SetMapPixel((unsigned short)fx, (unsigned short)fy, Pixels[i]->c, 0);\r
3530 SetMapPixel((unsigned short)fx, (unsigned short)fy, MAP_DESTROYABLE, 1);\r
3531 }\r
3532 }\r
3533 if(Pixels[i]->Explode == 1)\r
3534 {\r
3535 if(Collided == 1)\r
3536 SpawnExplosion((signed short)nx, (signed short)ny, 7, 0, 1);\r
3537 if(Collided == 2)\r
3538 {\r
3539 Objects[ObjNum]->xv += Pixels[i]->xv * (float)Pixels[i]->Damage * 0.013;\r
3540 Objects[ObjNum]->yv += Pixels[i]->yv * (float)Pixels[i]->Damage * 0.013;\r
3541 Regs[16] = (signed short)ObjNum;\r
3542 Regs[17] = Pixels[i]->Damage;\r
3543 Regs[18] = (signed short)Pixels[i]->Owner;\r
3544 Regs[19] = (signed short)Objects[ObjNum]->x;\r
3545 Regs[20] = (signed short)Objects[ObjNum]->y;\r
3546 Execute(Classes[Objects[ObjNum]->Class]->Code, (signed short *)&Objects[ObjNum]->Variables[0], Classes[Objects[ObjNum]->Class]->Scripts[3]); //TakeDamage\r
3547 }\r
3548 }\r
3549 Pixels[i]->Used = 0;\r
3550 }\r
3551 }\r
3552 }\r
3553}\r
3554\r
3555void CollVel(signed short x, signed short y, float *xv, float *yv, unsigned char Attributes)\r
3556{\r
3557 float Temp;\r
3558 signed char xa, ya;\r
3559 unsigned char a1, a2;\r
3560\r
3561 if(*xv < 0)\r
3562 xa = -1;\r
3563 else\r
3564 xa = 1;\r
3565 if(*yv < 0)\r
3566 ya = -1;\r
3567 else\r
3568 ya = 1;\r
3569 a1 = GetMapPixel(x, y + ya, 1) & Attributes;\r
3570 a2 = GetMapPixel(x + xa, y, 1) & Attributes;\r
3571 if(((a1 == 0) && (a2 == 0)) || ((a1 != 0) && (a2 != 0)))\r
3572 {\r
3573 Temp = *yv;\r
3574 *yv = *xv * (float)(xa * -ya);\r
3575 *xv = Temp * (float)(ya * -xa);\r
3576 } else {\r
3577 if(a1 == 0)\r
3578 *yv = -*yv;\r
3579 if(a2 == 0)\r
3580 *xv = -*xv;\r
3581 }\r
3582}\r
3583\r
3584void ControlPlayers(void)\r
3585{\r
3586 unsigned short i, o;\r
3587 unsigned short ObjNum;\r
3588 signed short PlayerAngle, CurWeapon;\r
3589\r
3590 for(i = 0; i < MAX_PLAYERS; i++)\r
3591 {\r
3592 if(Players[i]->Used == 1)\r
3593 {\r
3594 ObjNum = Players[i]->Object;\r
3595 PlayerAngle = Players[i]->Angle;\r
3596 if(PlayerAngle > 90)\r
3597 PlayerAngle -= 360;\r
3598 if(Players[i]->Dir == 1)\r
3599 PlayerAngle = 180 - PlayerAngle;\r
3600 if(PlayerAngle < 0)\r
3601 PlayerAngle += 360;\r
3602 for(o = 0; o < NUM_WEAPONS; o++)\r
3603 {\r
3604 if(PWeapons[i][o]->Used == 1)\r
3605 {\r
3606 if(PWeapons[i][o]->FireTimer > 0)\r
3607 {\r
3608 if(++PWeapons[i][o]->FireTimer > Weapons[PWeapons[i][o]->Weapon]->FireDelay)\r
3609 PWeapons[i][o]->FireTimer = 0;\r
3610 }\r
3611 if((PWeapons[i][o]->ReloadTimer > 0) && (Players[i]->CurWeapon == o))\r
3612 {\r
3613 if((Weapons[PWeapons[i][o]->Weapon]->MaxClips > 0) && (PWeapons[i][o]->NumClips == 0))\r
3614 {\r
3615 PWeapons[i][o]->ReloadTimer = 0;\r
3616 } else {\r
3617 if(++PWeapons[i][o]->ReloadTimer > Weapons[PWeapons[i][o]->Weapon]->ReloadDelay)\r
3618 {\r
3619 PWeapons[i][o]->ReloadTimer = 0;\r
3620 PWeapons[i][o]->AmmoLeft = Weapons[PWeapons[i][o]->Weapon]->Ammo;\r
3621 PlaySound(2, 0, 0, MAX_SOUNDS - 1, 22050, 1);\r
3622 }\r
3623 }\r
3624 }\r
3625 Regs[16] = (signed short)ObjNum;\r
3626 if(Players[i]->Dir == 0)\r
3627 {\r
3628 Regs[17] = (signed short)Objects[ObjNum]->x + 3 + Cosine[PlayerAngle] * 7;\r
3629 } else {\r
3630 Regs[17] = (signed short)Objects[ObjNum]->x - 1 + Cosine[PlayerAngle] * 7;\r
3631 }\r
3632 Regs[18] = (signed short)Objects[ObjNum]->y - 2 - Sine[PlayerAngle] * 7;\r
3633 Regs[19] = (signed short)PlayerAngle;\r
3634 Regs[20] = (signed short)i;\r
3635 Regs[21] = (signed short)o;\r
3636 Execute(Classes[Weapons[PWeapons[i][o]->Weapon]->Class]->Code, (signed short *)&PWeapons[i][o]->Vars[0], Classes[Weapons[PWeapons[i][o]->Weapon]->Class]->Scripts[1]); //Tick\r
3637 }\r
3638 }\r
3639 Players[i]->Angle += Players[i]->AngleVel;\r
3640 if((signed short)Players[i]->Angle >= 360)\r
3641 Players[i]->Angle -= 360;\r
3642 if((signed short)Players[i]->Angle < 0)\r
3643 Players[i]->Angle += 360;\r
3644 if((Players[i]->Angle < 300) && (Players[i]->Angle > 180))\r
3645 {\r
3646 Players[i]->Angle = 300;\r
3647 Players[i]->AngleVel = 0;\r
3648 }\r
3649 if((Players[i]->Angle > 90) && (Players[i]->Angle <= 180))\r
3650 {\r
3651 Players[i]->Angle = 90;\r
3652 Players[i]->AngleVel = 0;\r
3653 }\r
3654 if(((Players[i]->Left != 0) ^ (Players[i]->Right != 0)) & (Players[i]->Change == 0))\r
3655 {\r
3656 if(Players[i]->Left != 0)\r
3657 {\r
3658 if(((GetMapPixel((unsigned short)(Objects[ObjNum]->x) - 1, (unsigned short)(Objects[ObjNum]->y) - 1, 1) & MAP_WALKABLE) == MAP_WALKABLE) && (Objects[ObjNum]->xv > -1))\r
3659 Objects[ObjNum]->xv -= 0.1;\r
3660 Players[i]->Dir = 1;\r
3661 }\r
3662 if(Players[i]->Right != 0)\r
3663 {\r
3664 if(((GetMapPixel((unsigned short)(Objects[ObjNum]->x) + 1, (unsigned short)(Objects[ObjNum]->y) - 1, 1) & MAP_WALKABLE) == MAP_WALKABLE) && (Objects[ObjNum]->xv < 1))\r
3665 Objects[ObjNum]->xv += 0.1;\r
3666 Players[i]->Dir = 0;\r
3667 }\r
3668 } else {\r
3669 if((GetMapPixel((unsigned short)Objects[ObjNum]->x, (unsigned short)Objects[ObjNum]->y, 1) & MAP_WALKABLE) == 0)\r
3670 Objects[ObjNum]->xv *= 0.9;\r
3671 }\r
3672 if((Players[i]->Change != 0) && (Players[i]->Left == 1))\r
3673 {\r
3674 Players[i]->CurWeapon -= 1;\r
3675 if(Players[i]->CurWeapon < 0)\r
3676 Players[i]->CurWeapon += NUM_WEAPONS;\r
3677 while(PWeapons[i][Players[i]->CurWeapon]->Used == 0)\r
3678 {\r
3679 Players[i]->CurWeapon -= 1;\r
3680 if(Players[i]->CurWeapon < 0)\r
3681 Players[i]->CurWeapon += NUM_WEAPONS;\r
3682 }\r
3683 }\r
3684 if((Players[i]->Change != 0) && (Players[i]->Right == 1))\r
3685 {\r
3686 Players[i]->CurWeapon += 1;\r
3687 if(Players[i]->CurWeapon >= NUM_WEAPONS)\r
3688 Players[i]->CurWeapon -= NUM_WEAPONS;\r
3689 while(PWeapons[i][Players[i]->CurWeapon]->Used == 0)\r
3690 {\r
3691 Players[i]->CurWeapon += 1;\r
3692 if(Players[i]->CurWeapon >= NUM_WEAPONS)\r
3693 Players[i]->CurWeapon -= NUM_WEAPONS;\r
3694 }\r
3695 }\r
3696 if((Players[i]->Up != 0) ^ (Players[i]->Down != 0))\r
3697 {\r
3698 if((Players[i]->Up != 0) && (Players[i]->AngleVel < 3))\r
3699 Players[i]->AngleVel += .5;\r
3700 if((Players[i]->Down != 0) && (Players[i]->AngleVel > -3))\r
3701 Players[i]->AngleVel -= .5;\r
3702 } else {\r
3703 Players[i]->AngleVel *= .75;\r
3704 }\r
3705 PlayerAngle = Players[i]->Angle;\r
3706 if(PlayerAngle > 90)\r
3707 PlayerAngle -= 360;\r
3708 if(Players[i]->Dir == 1)\r
3709 PlayerAngle = 180 - PlayerAngle;\r
3710 if(PlayerAngle < 0)\r
3711 PlayerAngle += 360;\r
3712 CurWeapon = Players[i]->CurWeapon;\r
3713 Players[i]->JustShot = 0;\r
3714 if((Players[i]->Shoot != 0) && (PWeapons[i][CurWeapon]->FireTimer == 0) && (PWeapons[i][CurWeapon]->ReloadTimer == 0) && ((Weapons[PWeapons[i][CurWeapon]->Weapon]->MaxClips > 0)?(PWeapons[i][CurWeapon]->NumClips > 0):1))\r
3715 {\r
3716 PWeapons[i][Players[i]->CurWeapon]->FireTimer = 1;\r
3717 if(Players[i]->Dir == 0)\r
3718 {\r
3719 Regs[16] = (signed short)Objects[ObjNum]->x + 3 + Cosine[PlayerAngle] * 7;\r
3720 } else {\r
3721 Regs[16] = (signed short)Objects[ObjNum]->x - 1 + Cosine[PlayerAngle] * 7;\r
3722 }\r
3723 Regs[17] = (signed short)Objects[ObjNum]->y - 2 - Sine[PlayerAngle] * 7;\r
3724 Regs[18] = (signed short)PlayerAngle;\r
3725 Regs[19] = (signed short)(Objects[ObjNum]->xv * 100);\r
3726 Regs[20] = (signed short)(Objects[ObjNum]->yv * 100);\r
3727 Regs[21] = (signed short)i;\r
3728 if(Weapons[PWeapons[i][CurWeapon]->Weapon]->MaxClips > 0)\r
3729 PWeapons[i][CurWeapon]->NumClips--;\r
3730 Execute(Classes[Weapons[PWeapons[i][CurWeapon]->Weapon]->Class]->Code, (signed short *)&PWeapons[i][CurWeapon]->Vars[0], Classes[Weapons[PWeapons[i][CurWeapon]->Weapon]->Class]->Scripts[0]); //Fire\r
3731 if(--PWeapons[i][CurWeapon]->AmmoLeft <= 0)\r
3732 PWeapons[i][CurWeapon]->ReloadTimer = 1;\r
3733 Players[i]->JustShot = 1;\r
3734 }\r
3735 }\r
3736 }\r
3737}\r
3738\r
3739void SaveBitmap(unsigned char *Buffer, unsigned short w, unsigned short h, unsigned char *FileName)\r
3740{\r
3741 KvidFile BMPFile;\r
3742 unsigned long LongBuffer;\r
3743 unsigned short x, y;\r
3744\r
3745 if((CreateFile(FileName, &BMPFile, NULL, 0) == 0) || (BMPFile.CanWrite == 0))\r
3746 return;\r
3747 FileWrite((void *)"BM", 2, &BMPFile);\r
3748 LongBuffer = 54 + (w * h * 3) + ((w % 4) * h);\r
3749 FileWrite((void *)&LongBuffer, 4, &BMPFile);\r
3750 FileWrite((void *)"\x00\x00\x00\x00\x36\x00\x00\x00\x28\x00\x00\x00", 12, &BMPFile);\r
3751 LongBuffer = w;\r
3752 FileWrite((void *)&LongBuffer, 4, &BMPFile);\r
3753 LongBuffer = h;\r
3754 FileWrite((void *)&LongBuffer, 4, &BMPFile);\r
3755 FileWrite((void *)"\x01\x00\x18\x00\x00\x00\x00\x00", 8, &BMPFile);\r
3756 LongBuffer = (w * h * 3) + ((w % 4) * h);\r
3757 FileWrite((void *)&LongBuffer, 4, &BMPFile);\r
3758 FileWrite((void *)"\xC4\x0E\x00\x00\xC4\x0E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16, &BMPFile);\r
3759 LongBuffer = 0;\r
3760 for(y = 0; y < h; y++)\r
3761 {\r
3762 for(x = 0; x < w; x++)\r
3763 {\r
3764 FileWrite((void *)(Buffer + (x << 2) + ((h - y - 1) * 1280)), 3, &BMPFile);\r
3765 }\r
3766 FileWrite((void *)&LongBuffer, w % 4, &BMPFile);\r
3767 }\r
3768 FileClose(&BMPFile);\r
3769}\r
3770\r
3771void ControlMasks(void)\r
3772{\r
3773 unsigned short i, o, u;\r
3774 unsigned short x, y, w, h;\r
3775 unsigned short R, G, B;\r
3776 unsigned char Colors;\r
3777 unsigned char *Buffer;\r
3778 Color c;\r
3779\r
3780 for(i = 0; i < MAX_PLAYERS; i++)\r
3781 {\r
3782 if(Players[i]->Used == 1)\r
3783 {\r
3784 w = Players[i]->VPointX2 - Players[i]->VPointX1 + 1;\r
3785 h = Players[i]->VPointY2 - Players[i]->VPointY1 + 1;\r
3786 for(o = 0; o < NUM_MASKS; o++)\r
3787 {\r
3788 Buffer = Players[i]->Masks[o].Buffer;\r
3789 for(u = 0; u < 16; u++)\r
3790 {\r
3791 if(Players[i]->Masks[o].Effects[u] == 0)\r
3792 break;\r
3793 switch(Players[i]->Masks[o].Effects[u])\r
3794 {\r
3795 case 1:\r
3796 for(y = 0; y < h; y++)\r
3797 {\r
3798 for(x = 0; x < w; x++)\r
3799 {\r
3800 *(unsigned long *)&c = *(unsigned long *)(Buffer + ((y * w + x) << 2));\r
3801 R = c.R; G = c.G; B = c.B;\r
3802 Colors = 1;\r
3803 if(x > 0)\r
3804 {\r
3805 *(unsigned long *)&c = *(unsigned long *)(Buffer + ((y * w + (x - 1)) << 2));\r
3806 R += c.R; G += c.G; B += c.B;\r
3807 Colors++;\r
3808 }\r
3809 if(x < w - 1)\r
3810 {\r
3811 *(unsigned long *)&c = *(unsigned long *)(Buffer + ((y * w + (x + 1)) << 2));\r
3812 R += c.R; G += c.G; B += c.B;\r
3813 Colors++;\r
3814 }\r
3815 if(y > 0)\r
3816 {\r
3817 *(unsigned long *)&c = *(unsigned long *)(Buffer + (((y - 1) * w + x) << 2));\r
3818 R += c.R; G += c.G; B += c.B;\r
3819 Colors++;\r
3820 }\r
3821 if(y < h - 1)\r
3822 {\r
3823 *(unsigned long *)&c = *(unsigned long *)(Buffer + (((y + 1) * w + x) << 2));\r
3824 R += c.R; G += c.G; B += c.B;\r
3825 Colors++;\r
3826 }\r
3827 *(unsigned long *)&c = *(unsigned long *)(Buffer + ((y * w + x) << 2));\r
3828 R /= Colors;\r
3829 G /= Colors;\r
3830 B /= Colors;\r
3831 if(R > c.R || G > c.G || B > c.B)\r
3832 {\r
3833 c.R = R;\r
3834 c.G = G;\r
3835 c.B = B;\r
3836 }\r
3837 if(c.R > 0)\r
3838 c.R--;\r
3839 if(c.G > 0)\r
3840 c.G--;\r
3841 if(c.B > 0)\r
3842 c.B--;\r
3843 *(unsigned long *)(Buffer + ((y * w + x) << 2)) = *(unsigned long *)&c;\r
3844 }\r
3845 }\r
3846 break;\r
3847 case 2:\r
3848 for(y = 0; y < h; y++)\r
3849 {\r
3850 for(x = 0; x < w; x++)\r
3851 {\r
3852 *(unsigned long *)&c = *(unsigned long *)(Buffer + ((y * w + x) << 2));\r
3853 c.R /= 2;\r
3854 c.G /= 2;\r
3855 c.B /= 2;\r
3856 *(unsigned long *)(Buffer + ((y * w + x) << 2)) = *(unsigned long *)&c;\r
3857 }\r
3858 }\r
3859 break;\r
3860 }\r
3861 }\r
3862 }\r
3863 }\r
3864 }\r
3865}\r
3866\r
3867unsigned char ControlMenu(unsigned char Key)\r
3868{\r
3869 unsigned short i, o, x, y, Signature, l;\r
3870 KvidFile ModFile;\r
3871 unsigned char ValidLevel;\r
3872 DIR *d;\r
3873 struct dirent *de;\r
3874\r
3875 //DBFRectTrans(100, 30, 220, 150, MakeColor(0, 64, 0), 2);\r
3876 DBLine(100, 30, 100, 150, MakeColor(0, 150, 0), MakeColor(0, 150, 0));\r
3877 DBLine(100, 30, 220, 30, MakeColor(0, 150, 0), MakeColor(0, 150, 0));\r
3878 DBLine(220, 30, 220, 150, MakeColor(0, 150, 0), MakeColor(0, 150, 0));\r
3879 DBLine(100, 150, 220, 150, MakeColor(0, 150, 0), MakeColor(0, 150, 0));\r
3880 DBLineTrans(101, 31, 101, 149, MakeColor(0, 150, 0), MakeColor(0, 150, 0), 2);\r
3881 DBLineTrans(101, 31, 219, 31, MakeColor(0, 150, 0), MakeColor(0, 150, 0), 2);\r
3882 DBLineTrans(219, 31, 219, 149, MakeColor(0, 150, 0), MakeColor(0, 150, 0), 2);\r
3883 DBLineTrans(101, 149, 219, 149, MakeColor(0, 150, 0), MakeColor(0, 150, 0), 2);\r
3884 DBFRectTrans(102, 32, 218, 148, MakeColor(0, 64, 0), 2);\r
3885 if((Key == 200) && (CurMenuItem > 0))\r
3886 CurMenuItem--;\r
3887 if((Key == 208) && (CurMenuItem < NumMenuItems - 1))\r
3888 CurMenuItem++;\r
3889 if(CurMenuItem < StartMenuItem)\r
3890 StartMenuItem = CurMenuItem;\r
3891 if(CurMenuItem >= (StartMenuItem + 18))\r
3892 StartMenuItem = CurMenuItem - 17;\r
3893 if(Key == 1)\r
3894 {\r
3895 if(MenuStackPos == 0)\r
3896 {\r
3897 Paused = MenuActive = 0;\r
3898 } else {\r
3899 LoadMenu(MenuStack[--MenuStackPos][0]);\r
3900 CurMenuItem = MenuStack[MenuStackPos][1];\r
3901 StartMenuItem = MenuStack[MenuStackPos][2];\r
3902 }\r
3903 }\r
3904 if(Key == 28)\r
3905 {\r
3906 switch(*MenuItems[0][CurMenuItem])\r
3907 {\r
3908 case 0:\r
3909 MenuStack[MenuStackPos][0] = MenuID;\r
3910 MenuStack[MenuStackPos][1] = CurMenuItem;\r
3911 MenuStack[MenuStackPos++][2] = StartMenuItem;\r
3912 LoadMenu((unsigned short)MenuItems[0][CurMenuItem][1]);\r
3913 CurMenuItem = StartMenuItem = 0;\r
3914 break;\r
3915 case 1:\r
3916 if(InitVar() == 1)\r
3917 {\r
3918 MessageBox("Couldn't find the control files PLAYER1.CTR and PLAYER2.CTR!");\r
3919 return(1);\r
3920 }\r
3921 if(LevelType == 0)\r
3922 {\r
3923 if(LoadLevel(LevelFileName) != 0)\r
3924 LevelType = 1;\r
3925 }\r
3926 if(LevelType == 1)\r
3927 {\r
3928 ReInit();\r
3929 RandomLevel();\r
3930 }\r
3931 if(LevelType == 2)\r
3932 {\r
3933 ReInit();\r
3934 for(i = 0; i < 2; i++)\r
3935 {\r
3936 for(y = 0; y < LevelHeight; y++)\r
3937 {\r
3938 for(x = 0; x < LevelWidth; x++)\r
3939 {\r
3940 SetMapPixel((signed short)x, (signed short)y, (unsigned char)((i == 0)?0:7), i);\r
3941 }\r
3942 }\r
3943 }\r
3944 strcpy(LevelFileName, "Empty");\r
3945 DispLevelWidth = LevelWidth;\r
3946 DispLevelHeight = LevelHeight;\r
3947 SpawnObject(0, -1, 0, 0, 0, 0);\r
3948 }\r
3949 Paused = 0;\r
3950 MenuActive = 0;\r
3951 if(ModFileName == NULL)\r
3952 {\r
3953 PlaySound(0, 1, 0, MAX_SOUNDS - 1, 22050, 1);\r
3954 } else {\r
3955 if(OpenFile(ModFileName, &ModFile) == 0)\r
3956 {\r
3957 PlaySound(0, 1, 0, MAX_SOUNDS - 1, 22050, 1);\r
3958 } else {\r
3959 if(LoadMod(&ModFile) != 0)\r
3960 PlaySound(0, 1, 0, MAX_SOUNDS - 1, 22050, 1);\r
3961 else\r
3962 ModPlaying = 1;\r
3963 FileClose(&ModFile);\r
3964 }\r
3965 }\r
3966 LevelFinished = 0;\r
3967 return(0);\r
3968 case 2:\r
3969 return(1);\r
3970 case 3:\r
3971 if(UseSound == 1)\r
3972 {\r
3973 TerminatePlayBack();\r
3974 if(SBReset() == 0)\r
3975 {\r
3976 ReadyBuffer = 0;\r
3977 BufferReady = 0;\r
3978 FillBuffer();\r
3979 ReadyBuffer = 1;\r
3980 StartPlayBack();\r
3981 } else {\r
3982 UseSound = 0;\r
3983 }\r
3984 }\r
3985 break;\r
3986 case 4:\r
3987 LoadMenu(MenuStack[--MenuStackPos][0]);\r
3988 CurMenuItem = MenuStack[MenuStackPos][1];\r
3989 StartMenuItem = MenuStack[MenuStackPos][2];\r
3990 break;\r
3991 case 5:\r
3992 MenuStack[MenuStackPos][0] = MenuID;\r
3993 MenuStack[MenuStackPos][1] = CurMenuItem;\r
3994 MenuStack[MenuStackPos++][2] = StartMenuItem;\r
3995 CurMenuItem = StartMenuItem = 0;\r
3996 MenuItems[0][0] = "\x06";\r
3997 strcpy(MenuItems[1][0], "Random");\r
3998 MenuItems[0][1] = "\x07";\r
3999 strcpy(MenuItems[1][1], "Empty");\r
4000 NumMenuItems = 2;\r
4001 if((d = opendir(".")) != NULL)\r
4002 {\r
4003 while((de = readdir(d)) != NULL)\r
4004 {\r
4005 if((l = strlen(de->d_name)) < 4)\r
4006 continue;\r
4007 if(!strcmp(de->d_name + l - 4, ".lev") ||\r
4008 !strcmp(de->d_name + l - 4, ".bmp"))\r
4009 {\r
4010 MenuItems[0][NumMenuItems] = "\x08";\r
4011 strcpy(MenuItems[1][NumMenuItems++], de->d_name);\r
4012 }\r
4013 }\r
4014 closedir(d);\r
4015 }\r
4016 MenuItems[0][NumMenuItems] = "\x04";\r
4017 strcpy(MenuItems[1][NumMenuItems++], "Return");\r
4018 break;\r
4019 case 6:\r
4020 LevelType = 1;\r
4021 LoadMenu(MenuStack[--MenuStackPos][0]);\r
4022 CurMenuItem = MenuStack[MenuStackPos][1];\r
4023 StartMenuItem = MenuStack[MenuStackPos][2];\r
4024 strcpy(LevelFileName, "Random");\r
4025 DispLevelWidth = LevelWidth;\r
4026 DispLevelHeight = LevelHeight;\r
4027 break;\r
4028 case 7:\r
4029 LevelType = 2;\r
4030 LoadMenu(MenuStack[--MenuStackPos][0]);\r
4031 CurMenuItem = MenuStack[MenuStackPos][1];\r
4032 StartMenuItem = MenuStack[MenuStackPos][2];\r
4033 strcpy(LevelFileName, "Empty");\r
4034 DispLevelWidth = LevelWidth;\r
4035 DispLevelHeight = LevelHeight;\r
4036 break;\r
4037 case 8:\r
4038 if(OpenFile(MenuItems[1][CurMenuItem], &ModFile) == 0)\r
4039 {\r
4040 sprintf(TextBuffer, "Couldn't open %s!", MenuItems[1][CurMenuItem]);\r
4041 MessageBox(TextBuffer);\r
4042 break;\r
4043 }\r
4044 FileRead((void *)&Signature, 2, &ModFile);\r
4045 ValidLevel = 0;\r
4046 if(Signature == 0x464B)\r
4047 {\r
4048 ValidLevel = 1;\r
4049 FileRead((void *)&DispLevelWidth, 2, &ModFile);\r
4050 FileRead((void *)&DispLevelHeight, 2, &ModFile);\r
4051 }\r
4052 if(Signature == 0x4C4E)\r
4053 {\r
4054 ValidLevel = 1;\r
4055 FileRead((void *)&DispLevelWidth, 2, &ModFile);\r
4056 FileRead((void *)&DispLevelHeight, 2, &ModFile);\r
4057 }\r
4058 if(Signature == 0x4D42)\r
4059 {\r
4060 FileSkip(&ModFile, 16);\r
4061 ValidLevel = 1;\r
4062 FileRead((void *)&DispLevelWidth, 2, &ModFile);\r
4063 FileSkip(&ModFile, 2);\r
4064 FileRead((void *)&DispLevelHeight, 2, &ModFile);\r
4065 }\r
4066 if(ValidLevel == 0)\r
4067 {\r
4068 sprintf(TextBuffer, "%s is not a valid level file!", MenuItems[1][CurMenuItem]);\r
4069 MessageBox(TextBuffer);\r
4070 break;\r
4071 }\r
4072 FileClose(&ModFile);\r
4073 LevelType = 0;\r
4074 strcpy(LevelFileName, MenuItems[1][CurMenuItem]);\r
4075 LoadMenu(MenuStack[--MenuStackPos][0]);\r
4076 CurMenuItem = MenuStack[MenuStackPos][1];\r
4077 StartMenuItem = MenuStack[MenuStackPos][2];\r
4078 break;\r
4079 }\r
4080 }\r
4081 for(i = 0; ((i + StartMenuItem) < NumMenuItems) && (i < 18); i++)\r
4082 {\r
4083 FontPrint(MenuItems[1][i + StartMenuItem], 110, 40 + (i * 6), 0);\r
4084 if((i + StartMenuItem) == CurMenuItem)\r
4085 {\r
4086 DBCopyBufferClipTrans(109 - Caches[30]->w, 42 + (i * 6) - ((Caches[30]->h - 1) >> 1), Caches[30]->Frames[0], Caches[30]->w, Caches[30]->h, 0, 0);\r
4087 for(o = 109; o < 210; o += Caches[31]->w)\r
4088 DBCopyBufferClipTrans(o, 42 + (i * 6) - ((Caches[31]->h - 1) >> 1), Caches[31]->Frames[0], Caches[31]->w, Caches[31]->h, 0, 0);\r
4089 DBCopyBufferClipTrans(o, 42 + (i * 6) - ((Caches[30]->h - 1) >> 1), Caches[30]->Frames[1], Caches[30]->w, Caches[30]->h, 0, 0);\r
4090 }\r
4091 }\r
4092 return(0);\r
4093}\r
4094\r
4095unsigned char MonoColor(unsigned long c)\r
4096{\r
4097 Color Col;\r
4098\r
4099 Col = *(Color *)&c;\r
4100 return((unsigned char)((Col.R + ((Col.G * 31) / 63) + Col.B) / 3));\r
4101}\r
4102\r
4103unsigned long SmoothColor(unsigned long c1, unsigned long c2, unsigned long c3, unsigned long c4)\r
4104{\r
4105 Color Col0, Col1, Col2, Col3, Col4;\r
4106\r
4107 Col1 = *(Color *)&c1;\r
4108 Col2 = *(Color *)&c2;\r
4109 Col3 = *(Color *)&c3;\r
4110 Col4 = *(Color *)&c4;\r
4111 Col0.R = (Col1.R + Col2.R + Col3.R + Col4.R) >> 2;\r
4112 Col0.G = (Col1.G + Col2.G + Col3.G + Col4.G) >> 2;\r
4113 Col0.B = (Col1.B + Col2.B + Col3.B + Col4.B) >> 2;\r
4114 return(*(unsigned long *)&Col0);\r
4115}\r
4116\r
4117void SmoothArea(unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2)\r
4118{\r
4119 unsigned short x, y;\r
4120 unsigned long c0, a1, a2, a3, a4, s;\r
4121\r
4122 for(y = y1; y <= y2; y++)\r
4123 {\r
4124 for(x = x1; x <= x2; x++)\r
4125 {\r
4126 if(((GetMapPixel(x, y, 1) & MAP_WALKABLE) == 0) && ((GetMapPixel(x, y, 1) & MAP_DESTROYABLE) == MAP_DESTROYABLE))\r
4127 {\r
4128 a1 = GetMapPixel((signed short)x - 1, y, 1);\r
4129 a2 = GetMapPixel(x + 1, y, 1);\r
4130 a3 = GetMapPixel(x, (signed short)y - 1, 1);\r
4131 a4 = GetMapPixel(x, y + 1, 1);\r
4132 c0 = 0;\r
4133 if((a1 & MAP_WALKABLE) == 0)\r
4134 c0++;\r
4135 if((a2 & MAP_WALKABLE) == 0)\r
4136 c0++;\r
4137 if((a3 & MAP_WALKABLE) == 0)\r
4138 c0++;\r
4139 if((a4 & MAP_WALKABLE) == 0)\r
4140 c0++;\r
4141 if(c0 == 0)\r
4142 {\r
4143 SetMapPixel(x, y, MAP_WALKABLE | MAP_SHOOTABLE, 1);\r
4144 SpawnPixel(x, y, ((float)(rand() % 100) - 50) / 50, ((float)(rand() % 100) - 50) / 50, 255, 2, 0, 0, GetMapPixel(x, y, 0));\r
4145 SetMapPixel(x, y, 0, 0);\r
4146 }\r
4147 if(c0 < 4)\r
4148 {\r
4149 s = SmoothColor(GetMapPixel(x + 1, y, 0), GetMapPixel(x - 1, y, 0), GetMapPixel(x, y + 1, 0), GetMapPixel(x, y - 1, 0));\r
4150 if(MonoColor(s) > 20)\r
4151 SetMapPixel(x, y, s, 0);\r
4152 }\r
4153 }\r
4154 }\r
4155 }\r
4156}\r
4157\r
4158void SpawnExplosion(signed short x, signed short y, unsigned char StartFrame, unsigned char Smokes, unsigned char Sound)\r
4159{\r
4160 unsigned short i, Result;\r
4161\r
4162 Result = SpawnSprite(0, x, y, 0, 0, 1, StartFrame++, 1);\r
4163 CopyToMap(x - Caches[0]->cx[StartFrame], y - Caches[0]->cy[StartFrame], Caches[0]->Frames[StartFrame], Caches[0]->w, Caches[0]->h, 0, 1, 0, MAP_WALKABLE | MAP_SHOOTABLE | MAP_DESTROYABLE);\r
4164 SmoothArea(x - Caches[0]->cx[StartFrame], y - Caches[0]->cy[StartFrame], x - Caches[0]->cx[StartFrame] + Caches[0]->w, y - Caches[0]->cy[StartFrame] + Caches[0]->h);\r
4165 StartFrame--;\r
4166 if(Smokes > 0)\r
4167 {\r
4168 for(i = 0; i < Smokes; i++)\r
4169 {\r
4170 SpawnSprite(1, x + ((signed short)(rand() % 10) - 5), y + ((signed short)(rand() % 10) - 5), 0, -1, 1, 0, 2);\r
4171 }\r
4172 }\r
4173 if(Sound == 1)\r
4174 {\r
4175 if(StartFrame > 5)\r
4176 PlaySound((rand() % 2) + 4, 0, 22, 42, 22050, 1);\r
4177 else\r
4178 PlaySound(3, 0, 43, 63, 22050, 1);\r
4179 }\r
4180}\r
4181\r
4182unsigned char ArgExist(unsigned short argc, unsigned char **argv, char *Match)\r
4183{\r
4184 unsigned short i;\r
4185\r
4186 for(i = 1; i < argc; i++)\r
4187 {\r
4188 if(strcasecmp(argv[i], Match) == 0)\r
4189 return(i);\r
4190 }\r
4191 return(0);\r
4192}\r
4193\r
4194int main(int argc, unsigned char **argv)\r
4195{\r
4196 unsigned short Result, x, y, i, o;\r
4197 unsigned short Attributes;\r
4198 signed short Size;\r
4199 unsigned long Cycles;\r
4200 unsigned char Finished;\r
4201 unsigned char c0, c1, c2, c3, c4;\r
4202 unsigned short w, h;\r
4203 unsigned char MFR;\r
4204 unsigned char Key;\r
4205 unsigned long Start;\r
4206 double TickCounts[5];\r
4207 Color C0, C1, C2, C3, C4, FC;\r
4208 ModEvent *Buffer;\r
4209 KvidFile ModFile;\r
4210 double StartTime, CurTime;\r
4211 unsigned char NetFuncAddr[6];\r
4212 unsigned char *RetBuffer;\r
4213 float fcx[5], fcy[5];\r
4214 float fcxi[5], fcyi[5];\r
4215\r
4216 //*(unsigned long *)&NetFuncAddr[0] = 0x0040102E;\r
4217 //*(unsigned short *)&NetFuncAddr[4] = 0x0177;\r
4218 //RetBuffer = (unsigned char *)MakeFarCall(0, NULL, NetFuncAddr);\r
4219 DebugMode = 0;\r
4220 MFR = 0;\r
4221 c0 = c3 = 0;\r
4222 w = h = 0;\r
4223 if(argc > 1)\r
4224 {\r
4225 if(ArgExist(argc, argv, "/Debug") != 0)\r
4226 DebugMode = 1;\r
4227 if(ArgExist(argc, argv, "/FR") != 0)\r
4228 MFR = 1;\r
4229 if(ArgExist(argc, argv, "/Randomatiserad") != 0)\r
4230 c0 = 1;\r
4231 if(ArgExist(argc, argv, "/Empty") != 0)\r
4232 c0 = 2;\r
4233 if((c1 = (unsigned char)ArgExist(argc, argv, "/Bana")) != 0)\r
4234 c0 = 3;\r
4235 w = (unsigned short)ArgExist(argc, argv, "/Banbredd");\r
4236 h = (unsigned short)ArgExist(argc, argv, "/Banaltitud");\r
4237 if((c2 = (unsigned char)ArgExist(argc, argv, "/Bg")) != 0)\r
4238 c3 = 1;\r
4239 }\r
4240 switch(Init(&Result))\r
4241 {\r
4242 case 0:\r
4243 printf("SDL Failure\nQuitting...\n");\r
4244 Terminate();\r
4245 return(1);\r
4246 case 1:\r
4247 printf("VESA Failure\nQuitting...\n");\r
4248 Terminate();\r
4249 return(1);\r
4250 case 2:\r
4251 printf("Not enough memory!\n");\r
4252 Terminate();\r
4253 return(1);\r
4254 case 3:\r
4255 printf("Couldn't find the file KVID.DAT!\n");\r
4256 Terminate();\r
4257 return(1);\r
4258 case 4:\r
4259 printf("Datafile corrupted!\n");\r
4260 Terminate();\r
4261 return(1);\r
4262 }\r
4263 Players[0]->Used = 1;\r
4264 Players[1]->Used = 1;\r
4265 if(w > 0)\r
4266 LevelWidth = (unsigned short)atoi(argv[w + 1]);\r
4267 if(h > 0)\r
4268 LevelHeight = (unsigned short)atoi(argv[h + 1]);\r
4269 switch(c0)\r
4270 {\r
4271 case 0:\r
4272 strcpy(LevelFileName, "dm.lev");\r
4273 LevelType = 0;\r
4274 if(LoadLevel("dm.lev") != 0)\r
4275 {\r
4276 RandomLevel();\r
4277 LevelType = 1;\r
4278 }\r
4279 break;\r
4280 case 1:\r
4281 RandomLevel();\r
4282 LevelType = 1;\r
4283 break;\r
4284 case 2:\r
4285 for(i = 0; i < 2; i++)\r
4286 {\r
4287 for(y = 0; y < LevelHeight; y++)\r
4288 {\r
4289 for(x = 0; x < LevelWidth; x++)\r
4290 {\r
4291 SetMapPixel((signed short)x, (signed short)y, (unsigned char)((i == 0)?0:7), i);\r
4292 }\r
4293 }\r
4294 }\r
4295 strcpy(LevelFileName, "Empty");\r
4296 SpawnObject(0, -1, 0, 0, 0, 0);\r
4297 LevelType = 2;\r
4298 break;\r
4299 case 3:\r
4300 strcpy(LevelFileName, argv[c1 + 1]);\r
4301 LevelType = 0;\r
4302 if(LoadLevel(argv[c1 + 1]) != 0)\r
4303 {\r
4304 RandomLevel();\r
4305 LevelType = 1;\r
4306 }\r
4307 break;\r
4308 }\r
4309 if(InitVar() == 1)\r
4310 {\r
4311 Terminate();\r
4312 printf("Couldn't find control files!\nShould be named PLAYER1.CTR and PLAYER2.CTR\n");\r
4313 return(1);\r
4314 }\r
4315 ModFileName = NULL;\r
4316 if(c3 == 0)\r
4317 {\r
4318 if(OpenFile("DefaultMod", &ModFile) == 0)\r
4319 {\r
4320 PlaySound(0, 1, 0, MAX_SOUNDS - 1, 22050, 1);\r
4321 } else {\r
4322 if(LoadMod(&ModFile) != 0)\r
4323 {\r
4324 PlaySound(0, 1, 0, MAX_SOUNDS - 1, 22050, 1);\r
4325 } else {\r
4326 ModPlaying = 1;\r
4327 ModFileName = "DefaultMod";\r
4328 }\r
4329 FileClose(&ModFile);\r
4330 }\r
4331 } else {\r
4332 if(OpenFile(argv[c2 + 1], &ModFile) == 0)\r
4333 {\r
4334 PlaySound(0, 1, 0, MAX_SOUNDS - 1, 22050, 1);\r
4335 } else {\r
4336 if(LoadMod(&ModFile) != 0)\r
4337 {\r
4338 PlaySound(0, 1, 0, MAX_SOUNDS - 1, 22050, 1);\r
4339 } else {\r
4340 ModPlaying = 1;\r
4341 ModFileName = argv[c2 + 1];\r
4342 }\r
4343 FileClose(&ModFile);\r
4344 }\r
4345 }\r
4346 if(MFR == 1)\r
4347 {\r
4348 Start = (unsigned long)time(NULL);\r
4349 while((unsigned long)time(NULL) == Start);\r
4350 Start = (unsigned long)time(NULL);\r
4351 }\r
4352 Paused = 0;\r
4353 MenuActive = 0;\r
4354 Cycles = 0;\r
4355 Finished = 0;\r
4356 LevelFinished = 0;\r
4357 Size = 0;\r
4358 StartTime = 0;\r
4359 while(Finished == 0)\r
4360 {\r
4361 if(!MFR && !KeyTable[29])\r
4362 {\r
4363 CurTime = ntime();\r
4364 while(CurTime - StartTime < 0.02)\r
4365 {\r
4366 usleep((unsigned long)((0.02 - (CurTime - StartTime)) * 1000000));\r
4367 CurTime = ntime();\r
4368 }\r
4369 }\r
4370 StartTime = ntime();\r
4371 /*if(KeyTable[67] == 1)\r
4372 DebugMode = 1;\r
4373 if(KeyTable[68] == 1)\r
4374 DebugMode = 0;*/\r
4375 if(GetEvents())\r
4376 Finished = 1;\r
4377 for(i = 0; i < MAX_PLAYERS; i++)\r
4378 {\r
4379 Players[i]->Left = 0;\r
4380 Players[i]->Right = 0;\r
4381 Players[i]->Up = 0;\r
4382 Players[i]->Down = 0;\r
4383 Players[i]->Shoot = 0;\r
4384 Players[i]->Change = 0;\r
4385 }\r
4386 GetInputs();\r
4387 Key = ReadKey();\r
4388 if(Paused == 0)\r
4389 ControlPixels();\r
4390 TickCounts[0] = ntime();\r
4391 if(Paused == 0)\r
4392 ControlSprites();\r
4393 TickCounts[1] = ntime();\r
4394 if(Paused == 0)\r
4395 ControlObjects();\r
4396 TickCounts[2] = ntime();\r
4397 if(Paused == 0)\r
4398 ControlPlayers();\r
4399 TickCounts[3] = ntime();\r
4400 Cycles++;\r
4401 if(MFR == 1)\r
4402 if((unsigned long)time(NULL) - Start > 10)\r
4403 Finished = 1;\r
4404 c0 = KeyTable[63] * 4;\r
4405 if(KeyTable[64] == 1) c0 += 8;\r
4406 if(KeyTable[65] == 1) c0 += 16;\r
4407 if(KeyTable[59] == 1) BGFrame = c0;\r
4408 if(KeyTable[60] == 1) BGFrame = c0 + 1;\r
4409 if(KeyTable[61] == 1) BGFrame = c0 + 2;\r
4410 if(KeyTable[62] == 1) BGFrame = c0 + 3;\r
4411 if(KeyTable[66] == 1)\r
4412 {\r
4413 x = rand() % LevelWidth;\r
4414 y = rand() % LevelHeight;\r
4415 while((GetMapPixel(x, y, 1) & MAP_SHOOTABLE) == 0)\r
4416 {\r
4417 x = rand() % LevelWidth;\r
4418 y = rand() % LevelHeight;\r
4419 }\r
4420 SpawnObject(145, -1, x, y, 0, 0);\r
4421 }\r
4422 if((Key == 1) && (LevelFinished == 0) && (MenuActive == 0))\r
4423 {\r
4424 LoadMenu(0);\r
4425 MenuStackPos = 0;\r
4426 CurMenuItem = StartMenuItem = 0;\r
4427 Paused = MenuActive ^= 1;\r
4428 Key = 0;\r
4429 }\r
4430 if(KeyTable[87] == 1)\r
4431 {\r
4432 while(KeyTable[87] == 1)\r
4433 GetEvents();\r
4434 Objects[Players[1]->Object]->xv = 100;\r
4435 }\r
4436 ControlMasks();\r
4437 DrawScreen();\r
4438 TickCounts[4] = ntime();\r
4439 if(Key == 68)\r
4440 SetMode(!FullScreen);\r
4441 if(Key == 88)\r
4442 SaveBitmap(DblBuffer, 320, 200, "ss.bmp");\r
4443 if(MenuActive == 1)\r
4444 {\r
4445 if(ControlMenu(Key) == 1)\r
4446 Finished = 1;\r
4447 }\r
4448 if((LevelFinished == 1) && ((MenuActive == 0) || (Paused == 0)))\r
4449 {\r
4450 LoadMenu(0);\r
4451 CurMenuItem = StartMenuItem = 0;\r
4452 Paused = MenuActive = 1;\r
4453 }\r
4454#if PLAY_TIME > 0\r
4455 sprintf(TextBuffer, "Play time left: %li", (signed long)(PLAY_TIME - Cycles));\r
4456 DBPrint(TextBuffer, 0, 196, 255);\r
4457 if(Cycles >= PLAY_TIME)\r
4458 Finished = 1;\r
4459#endif\r
4460 x = 0;\r
4461 if(Cycles % 5 == 0)\r
4462 {\r
4463 if(--FogX < -Caches[FogSprite]->w)\r
4464 FogX += Caches[FogSprite]->w;\r
4465 }\r
4466 if(Cycles % 10 == 0)\r
4467 {\r
4468 if(--FogY < -Caches[FogSprite]->h)\r
4469 FogY += Caches[FogSprite]->h;\r
4470 }\r
4471 for(i = 0; i < 5; i++)\r
4472 {\r
4473 for(o = 0; o < (320 * ((TickCounts[i] - CurTime) / 0.02)); o++)\r
4474 {\r
4475 DBPSetC(x++, 199, MakeColor((i * 255) / 4, 0, ((4 - i) * 255) / 4));\r
4476 }\r
4477 CurTime = TickCounts[i];\r
4478 }\r
4479 if(KeyTable[203] == 1)\r
4480 Size--;\r
4481 if(KeyTable[205] == 1)\r
4482 Size++;\r
4483 if(Size < 0)\r
4484 Size += 360;\r
4485 if(Size >= 360)\r
4486 Size -= 360;\r
4487 //DBCopyBufferRotated(160, 100, Caches[47]->Frames[0], Caches[47]->w, Caches[47]->h, 0, Caches[47]->w >> 1, Caches[47]->h >> 1, Size);\r
4488 DBPSetC(160, 100, MakeColor(255, 0, 0));\r
4489 DisplayDB();\r
4490 }\r
4491 while(KeyTable[1] == 1)\r
4492 GetEvents();\r
4493 for(i = 0; i < 5; i++)\r
4494 {\r
4495 fcx[i] = (rand() % 320) + 1;\r
4496 fcy[i] = (rand() % 200) + 1;\r
4497 fcxi[i] = ((float)(rand() % 200) / 100) - 1;\r
4498 fcyi[i] = ((float)(rand() % 200) / 100) - 1;\r
4499 }\r
4500 while(KeyTable[1] == 0)\r
4501 {\r
4502 GetEvents();\r
4503 for(Start = 0; Start < 256000; Start += 4)\r
4504 {\r
4505 C0 = *(Color *)&DblBuffer[Start];\r
4506 if(Start >= 4)\r
4507 C1 = *(Color *)&DblBuffer[Start - 4];\r
4508 if(Start < 255996)\r
4509 C2 = *(Color *)&DblBuffer[Start + 4];\r
4510 if(Start >= 1280)\r
4511 C3 = *(Color *)&DblBuffer[Start - 1280];\r
4512 if(Start < 254720)\r
4513 C4 = *(Color *)&DblBuffer[Start + 1280];\r
4514 FC.R = (C0.R + C1.R + C2.R + C3.R + C4.R) / 5;\r
4515 FC.G = (C0.G + C1.G + C2.G + C3.G + C4.G) / 5;\r
4516 FC.B = (C0.B + C1.B + C2.B + C3.B + C4.B) / 5;\r
4517 *(unsigned long *)&DblBuffer[Start] = *(unsigned long *)&FC;\r
4518 }\r
4519 /*asm("\r
4520 movl $0, %%eax\r
4521 movd %%eax, %%mm2\r
4522 movl $0, %%ecx\r
4523 movd (%%edi), %%mm0\r
4524 punpcklbw %%mm2, %%mm0\r
4525 movd -1280(%%edi), %%mm1\r
4526 emms\r
4527 "\r
4528 :\r
4529 : "D" (DblBuffer)\r
4530 : "%eax", "%ecx"\r
4531 );*/\r
4532 /*DBFCircleFadedTrans(fcx[0], fcy[0], 50, MakeColor(0, 100, 0), 1, 0);\r
4533 DBFCircleFadedTrans(fcx[1], fcy[1], 50, MakeColor(0, 0, 100), 1, 0);\r
4534 DBFCircleFadedTrans(fcx[2], fcy[2], 50, MakeColor(100, 100, 0), 1, 0);\r
4535 DBFCircleFadedTrans(fcx[3], fcy[3], 50, MakeColor(100, 0, 50), 1, 0);\r
4536 DBFCircleFadedTrans(fcx[4], fcy[4], 50, MakeColor(100, 0, 0), 1, 0);\r
4537 for(i = 0; i < 5; i++)\r
4538 {\r
4539 fcx[i] += fcxi[i];\r
4540 fcy[i] += fcyi[i];\r
4541 if(fcx[i] > 270)\r
4542 fcxi[i] = -fabs(fcxi[i]);\r
4543 if(fcx[i] < 50)\r
4544 fcxi[i] = fabs(fcxi[i]);\r
4545 if(fcy[i] > 150)\r
4546 fcyi[i] = -fabs(fcyi[i]);\r
4547 if(fcy[i] < 50)\r
4548 fcyi[i] = fabs(fcyi[i]);\r
4549 }*/\r
4550 DisplayDB();\r
4551 }\r
4552 Terminate();\r
4553 printf("%lu\n", Cycles);\r
4554 return(0);\r
4555}\r