1 //-------------------------------------------------------------------------
2 /*
3 Copyright (C) 2010-2019 EDuke32 developers and contributors
4 Copyright (C) 2019 Nuke.YKT
5
6 This file is part of NBlood.
7
8 NBlood is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License version 2
10 as published by the Free Software Foundation.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16 See the GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22 //-------------------------------------------------------------------------
23 #pragma once
24 #include "baselayer.h"
25 #include "build.h"
26 #include "cache1d.h"
27 #include "common.h"
28 #include "pragmas.h"
29 #include "misc.h"
30 #include "network.h"
31
32 extern int g_useCwd;
33 #ifndef APPNAME
34 #define APPNAME "NBlood"
35 #endif
36
37 #ifndef APPBASENAME
38 #define APPBASENAME "nblood"
39 #endif
40
41 #define BLOODWIDESCREENDEF "blood_widescreen.def"
42
43 #define BYTEVERSION 103
44 #define EXEVERSION 101
45
46 void _SetErrorLoc(const char *pzFile, int nLine);
47 void _ThrowError(const char *pzFormat, ...);
48 void __dassert(const char *pzExpr, const char *pzFile, int nLine);
49 void QuitGame(void);
50 void _consoleSysMsg(const char* pMessage, ...);
51
52 #define ThrowError(...) \
53 { \
54 _SetErrorLoc(__FILE__,__LINE__); \
55 _ThrowError(__VA_ARGS__); \
56 }
57
58 // print error to console only
59 #define consoleSysMsg(...) \
60 { \
61 _SetErrorLoc(__FILE__,__LINE__); \
62 _consoleSysMsg(__VA_ARGS__); \
63 }
64
65 #define dassert(x) if (!(x)) __dassert(#x,__FILE__,__LINE__)
66
67
68 #define kMaxSectors MAXSECTORS
69 #define kMaxWalls MAXWALLS
70 #define kMaxSprites MAXSPRITES
71
72 #define kMaxTiles MAXTILES
73 #define kMaxStatus MAXSTATUS
74 #define kMaxPlayers 8
75 #define kMaxViewSprites maxspritesonscreen
76
77 #define kMaxVoxels MAXVOXELS
78
79 #define kTicRate 120
80 #define kTicsPerFrame 4
81 #define kTicsPerSec (kTicRate/kTicsPerFrame)
82
83 #define TILTBUFFER 4078
84
85 #define kExplodeMax 8
86
87 #define kLensSize 80
88 #define kViewEffectMax 20
89
90 #define kNoTile -1
91
92
93 // defined by NoOne:
94 // -------------------------------
95
96 #define kMaxPAL 5
97 #define kUserPLUStart 15
98
99 #define kDmgFall 0
100 #define kDmgBurn 1
101 #define kDmgBullet 2
102 #define kDmgExplode 3
103 #define kDmgChoke 4
104 #define kDmgSpirit 5
105 #define kDmgElectric 6
106 #define kDmgMax 7
107
108 // MEDIUM /////////////////////////////////////////////////////
109 enum {
110 kMediumNormal = 0,
111 kMediumWater = 1,
112 kMediumGoo = 2,
113 };
114
115 // STATNUMS /////////////////////////////////////////////////////
116 enum {
117 kStatNothing = -1,
118 kStatDecoration = 0,
119 kStatFX = 1,
120 kStatExplosion = 2,
121 kStatItem = 3,
122 kStatThing = 4,
123 kStatProjectile = 5,
124 kStatDude = 6,
125 kStatInactive = 7, // inactive (ambush) dudes
126 kStatRespawn = 8,
127 kStatPurge = 9,
128 kStatMarker = 10,
129 kStatTraps = 11,
130 kStatAmbience = 12,
131 kStatSpares = 13,
132 kStatFlare = 14,
133 kStatDebris = 15,
134 kStatPathMarker = 16,
135 kStatFree = 1024,
136 };
137
138 // POWERUPS /////////////////////////////////////////////////////
139 enum {
140 kPwUpFeatherFall = 12,
141 kPwUpShadowCloak = 13,
142 kPwUpDeathMask = 14,
143 kPwUpJumpBoots = 15,
144 kPwUpTwoGuns = 17,
145 kPwUpDivingSuit = 18,
146 kPwUpGasMask = 19,
147 kPwUpCrystalBall = 21,
148 kPwUpDoppleganger = 23,
149 kPwUpReflectShots = 24,
150 kPwUpBeastVision = 25,
151 kPwUpShadowCloakUseless = 26,
152 kPwUpDeliriumShroom = 28,
153 kPwUpGrowShroom = 29,
154 kPwUpShrinkShroom = 30,
155 kPwUpDeathMaskUseless = 31,
156 kPwUpAsbestArmor = 39,
157 kMaxPowerUps = 51,
158 };
159
160 enum {
161 kExplosionSmall = 0,
162 kExplosionStandard = 1,
163 kExplosionLarge = 2,
164 kExplosionFireball = 3,
165 kExplosionSpray = 4,
166 kExplosion5 = 5,
167 kExplosion6 = 6,
168 kExplosionNapalm = 7,
169 kExplosionMax = 8
170 };
171
172 // SPRITE TYPES /////////////////////////////////////////////////
173 enum {
174 kSpriteDecoration = 0,
175
176 // markers
177 kMarkerSPStart = 1,
178 kMarkerMPStart = 2,
179 kMarkerOff = 3,
180 kMarkerOn = 4,
181 kMarkerAxis = 5,
182 kMarkerLowLink = 6,
183 kMarkerUpLink = 7,
184 kMarkerWarpDest = 8,
185 kMarkerUpWater = 9,
186 kMarkerLowWater = 10,
187 kMarkerUpStack = 11,
188 kMarkerLowStack = 12,
189 kMarkerUpGoo = 13,
190 kMarkerLowGoo = 14,
191 kMarkerPath = 15,
192 kMarkerDudeSpawn = 18,
193 kMarkerEarthQuake = 19,
194
195 // switches
196 kSwitchBase = 20,
197 kSwitchToggle = 20,
198 kSwitchOneWay = 21,
199 kSwitchCombo = 22,
200 kSwitchPadlock = 23,
201 kSwitchMax = 24,
202
203 // decorations
204 kDecorationTorch = 30,
205 kDecorationCandle = 32,
206
207 // (weapons)
208 kItemWeaponBase = 40,
209 kItemWeaponSawedoff = 41,
210 kItemWeaponTommygun = 42,
211 kItemWeaponVoodooDoll = 44,
212 kItemWeaponLifeLeech = 50,
213 kItemWeaponMax = 51,
214
215 // items (ammos)
216 kItemAmmoBase = 60,
217 kItemAmmoSawedoffFew = 67,
218 kItemAmmoTommygunFew = 69,
219 kAmmoItemVoodooDoll = 70,
220 kItemAmmoMax = 81,
221
222 kItemBase = 100,
223
224 // items (keys)
225 kItemKeyBase = kItemBase,
226 kItemKeySkull = kItemKeyBase,
227 kItemKeyEye = 101,
228 kItemKeyFire = 102,
229 kItemKeyDagger = 103,
230 kItemKeySpider = 104,
231 kItemKeyMoon = 105,
232 kItemKeyKey7 = 106,
233 kItemKeyMax = 107,
234
235 // items (health)
236 kItemHealthDoctorBag = 107,
237 kItemHealthMedPouch = 108,
238 kItemHealthLifeEssense = 109,
239 kItemHealthLifeSeed = 110,
240 kItemHealthRedPotion = 111,
241
242 // items (misc)
243 kItemFeatherFall = 112,
244 kItemShadowCloak = 113, // ltdInvisibility
245 kItemDeathMask = 114, // invulnerability
246 kItemJumpBoots = 115,
247 kItemTwoGuns = 117,
248 kItemDivingSuit = 118,
249 kItemGasMask = 119,
250 kItemCrystalBall = 121,
251 kItemReflectShots = 124,
252 kItemBeastVision = 125,
253 kItemShroomDelirium = 128,
254
255 kItemArmorAsbest = 139,
256 kItemArmorBasic = 140,
257 kItemArmorBody = 141,
258 kItemArmorFire = 142,
259 kItemArmorSpirit = 143,
260 kItemArmorSuper = 144,
261
262 kItemFlagABase = 145,
263 kItemFlagBBase = 146,
264 kItemFlagA = 147,
265 kItemFlagB = 148,
266 kItemMax = 151,
267
268 // dudes
269 kDudeBase = 200,
270 kDudeCultistTommy = 201,
271 kDudeCultistShotgun = 202,
272 kDudeZombieAxeNormal = 203,
273 kDudeZombieButcher = 204,
274 kDudeZombieAxeBuried = 205,
275 kDudeGargoyleFlesh = 206,
276 kDudeGargoyleStone = 207,
277 kDudeGargoyleStatueFlesh = 208,
278 kDudeGargoyleStatueStone = 209,
279 kDudePhantasm = 210,
280 kDudeHellHound = 211,
281 kDudeHand = 212,
282 kDudeSpiderBrown = 213,
283 kDudeSpiderRed = 214,
284 kDudeSpiderBlack = 215,
285 kDudeSpiderMother = 216,
286 kDudeGillBeast = 217,
287 kDudeBoneEel = 218,
288 kDudeBat = 219,
289 kDudeRat = 220,
290 kDudePodGreen = 221,
291 kDudeTentacleGreen = 222,
292 kDudePodFire = 223,
293 kDudeTentacleFire = 224,
294 kDudePodMother = 225,
295 kDudeTentacleMother = 226,
296 kDudeCerberusTwoHead = 227,
297 kDudeCerberusOneHead = 228,
298 kDudeTchernobog = 229,
299 kDudeCultistTommyProne = 230,
300 kDudePlayer1 = 231,
301 kDudePlayer2 = 232,
302 kDudePlayer3 = 233,
303 kDudePlayer4 = 234,
304 kDudePlayer5 = 235,
305 kDudePlayer6 = 236,
306 kDudePlayer7 = 237,
307 kDudePlayer8 = 238,
308 kDudeBurningInnocent = 239,
309 kDudeBurningCultist = 240,
310 kDudeBurningZombieAxe = 241,
311 kDudeBurningZombieButcher = 242,
312 kDudeCultistReserved = 243, // unused
313 kDudeZombieAxeLaying = 244,
314 kDudeInnocent = 245,
315 kDudeCultistShotgunProne = 246,
316 kDudeCultistTesla = 247,
317 kDudeCultistTNT = 248,
318 kDudeCultistBeast = 249,
319 kDudeTinyCaleb = 250,
320 kDudeBeast = 251,
321 kDudeBurningTinyCaleb = 252,
322 kDudeBurningBeast = 253,
323 kDudeVanillaMax = 254,
324 kDudeMax = 256,
325
326 kMissileBase = 300,
327 kMissileButcherKnife = kMissileBase,
328 kMissileFlareRegular = 301,
329 kMissileTeslaAlt = 302,
330 kMissileFlareAlt = 303,
331 kMissileFlameSpray = 304,
332 kMissileFireball = 305,
333 kMissileTeslaRegular = 306,
334 kMissileEctoSkull = 307,
335 kMissileFlameHound = 308,
336 kMissilePukeGreen = 309,
337 kMissileUnused = 310,
338 kMissileArcGargoyle = 311,
339 kMissileFireballNapam = 312,
340 kMissileFireballCerberus = 313,
341 kMissileFireballTchernobog = 314,
342 kMissileLifeLeechRegular = 315,
343 kMissileLifeLeechAltNormal = 316,
344 kMissileLifeLeechAltSmall = 317,
345 kMissileMax = 318,
346
347 // things
348 kThingBase = 400,
349 kThingTNTBarrel = 400,
350 kThingArmedProxBomb = 401,
351 kThingArmedRemoteBomb = 402,
352 kThingCrateFace = 405,
353 kThingGlassWindow = 406,
354 kThingFluorescent = 407,
355 kThingWallCrack = 408,
356 kThingSpiderWeb = 410,
357 kThingMetalGrate = 411,
358 kThingFlammableTree = 412,
359 kTrapMachinegun = 413, // not really a thing, should be in traps instead
360 kThingFallingRock = 414,
361 kThingKickablePail = 415,
362 kThingObjectGib = 416,
363 kThingObjectExplode = 417,
364 kThingArmedTNTStick = 418,
365 kThingArmedTNTBundle = 419,
366 kThingArmedSpray = 420,
367 kThingBone = 421,
368 kThingDripWater = 423,
369 kThingDripBlood = 424,
370 kThingBloodBits = 425,
371 kThingBloodChunks = 426,
372 kThingZombieHead = 427,
373 kThingNapalmBall = 428,
374 kThingPodFireBall = 429,
375 kThingPodGreenBall = 430,
376 kThingDroppedLifeLeech = 431,
377 kThingVoodooHead = 432, // unused
378 kThingMax = 436,
379
380 // traps
381 kTrapFlame = 452,
382 kTrapSawCircular = 454,
383 kTrapZapSwitchable = 456,
384 kTrapExploder = 459,
385
386 // generators
387 kGenTrigger = 700,
388 kGenDripWater = 701,
389 kGenDripBlood = 702,
390 kGenMissileFireball = 703,
391 kGenMissileEctoSkull = 704,
392 kGenDart = 705,
393 kGenBubble = 706,
394 kGenBubbleMulti = 707,
395
396 // sound sprites
397 kGenSound = 708,
398 kSoundSector = 709,
399 kSoundPlayer = 711,
400 };
401
402 // WALL TYPES /////////////////////////////////////////////////
403 enum {
404 kWallBase = 500,
405 kWallStack = 501,
406 kWallGib = 511,
407 kWallMax = 512,
408 };
409
410
411 // SECTOR TYPES /////////////////////////////////////////////////
412 enum {
413 kSectorBase = 600,
414 kSectorZMotion = 600,
415 kSectorZMotionSprite = 602,
416 kSectorTeleport = 604,
417 kSectorPath = 612,
418 kSectorRotateStep = 613,
419 kSectorSlideMarked = 614,
420 kSectorRotateMarked = 615,
421 kSectorSlide = 616,
422 kSectorRotate = 617,
423 kSectorDamage = 618,
424 kSectorCounter = 619,
425 kSectorMax = 620,
426 };
427
428 // ai state types
429 enum {
430 kAiStateOther = -1,
431 kAiStateIdle = 0,
432 kAiStateGenIdle = 1,
433 kAiStateMove = 2,
434 kAiStateSearch = 3,
435 kAiStateChase = 4,
436 kAiStateRecoil = 5,
437 kAiStateAttack = 6,
438 #ifdef NOONE_EXTENSIONS
439 kAiStatePatrolBase = 7,
440 kAiStatePatrolWaitL = kAiStatePatrolBase,
441 kAiStatePatrolWaitC,
442 kAiStatePatrolWaitW,
443 kAiStatePatrolMoveL,
444 kAiStatePatrolMoveC,
445 kAiStatePatrolMoveW,
446 kAiStatePatrolMax,
447 #endif
448 };
449
450 // sprite attributes
451 #define kHitagAutoAim 0x0008
452 #define kHitagRespawn 0x0010
453 #define kHitagFree 0x0020
454 #define kHitagSmoke 0x0100
455
456 // sprite physics attributes
457 #define kPhysMove 0x0001 // affected by movement physics
458 #define kPhysGravity 0x0002 // affected by gravity
459 #define kPhysFalling 0x0004 // currently in z-motion
460
461 // sector cstat
462 #define kSecCParallax 0x01
463 #define kSecCSloped 0x02
464 #define kSecCSwapXY 0x04
465 #define kSecCExpand 0x08
466 #define kSecCFlipX 0x10
467 #define kSecCFlipY 0x20
468 #define kSecCFlipMask 0x34
469 #define kSecCRelAlign 0x40
470 #define kSecCFloorShade 0x8000
471
472 #define kAng5 28
473 #define kAng15 85
474 #define kAng30 170
475 #define kAng45 256
476 #define kAng60 341
477 #define kAng90 512
478 #define kAng120 682
479 #define kAng180 1024
480 #define kAng360 2048
481
482
483 // -------------------------------
484
485 // NUKE-TODO:
486 #define OSDTEXT_DEFAULT "^00"
487 #define OSDTEXT_DARKRED "^00"
488 #define OSDTEXT_GREEN "^00"
489 #define OSDTEXT_RED "^00"
490 #define OSDTEXT_YELLOW "^00"
491
492 #define OSDTEXT_BRIGHT "^S0"
493
494 #define OSD_ERROR OSDTEXT_DARKRED OSDTEXT_BRIGHT
495
496 enum BLOOD_GLOBALFLAGS {
497 BLOOD_FORCE_WIDELOADSCREEN = 1<<0,
498 };
499
500 enum searchpathtypes_t {
501 SEARCHPATH_REMOVE = 1<<0,
502 };
503
504 extern char *g_grpNamePtr;
505
506 extern int loaddefinitions_game(const char *fn, int32_t preload);
507
508 extern void G_AddSearchPaths(void);
509 extern void G_CleanupSearchPaths(void);
510
511 extern void G_ExtPreInit(int32_t argc, char const * const * argv);
512 extern void G_ExtInit(void);
513
514 void G_LoadGroupsInDir(const char *dirname);
515 void G_DoAutoload(const char *dirname);
516 extern void G_LoadGroups(int32_t autoload);
517
518 extern void G_SetupGlobalPsky(void);
519
520 #define G_ModDirSnprintf(buf, size, basename, ...) \
521 (((g_modDir[0] != '/') ? Bsnprintf(buf, size, "%s/" basename, g_modDir, ##__VA_ARGS__) : Bsnprintf(buf, size, basename, ##__VA_ARGS__)) \
522 >= ((int32_t)size) - 1)
523
524 #define G_ModDirSnprintfLite(buf, size, basename) \
525 ((g_modDir[0] != '/') ? Bsnprintf(buf, size, "%s/%s", g_modDir, basename) : Bsnprintf(buf, size, "%s", basename))
526
gameHandleEvents(void)527 static inline int gameHandleEvents(void)
528 {
529 netGetPackets();
530 return handleevents();
531 }
532
533 #if defined HAVE_FLAC || defined HAVE_VORBIS
534 # define FORMAT_UPGRADE_ELIGIBLE
535 extern int32_t S_OpenAudio(const char *fn, char searchfirst, uint8_t ismusic);
536 #else
537 # define S_OpenAudio(fn, searchfirst, ismusic) kopen4loadfrommod(fn, searchfirst)
538 #endif
539
540 #pragma pack(push,1)
541
542 #if 0
543 struct sectortype
544 {
545 short wallptr, wallnum;
546 int ceilingz, floorz;
547 unsigned short ceilingstat, floorstat;
548 short ceilingpicnum, ceilingheinum;
549 signed char ceilingshade;
550 char ceilingpal, ceilingxpanning, ceilingypanning;
551 short floorpicnum, floorheinum;
552 signed char floorshade;
553 char floorpal, floorxpanning, floorypanning;
554 char visibility, filler;
555 unsigned short lotag;
556 short hitag, extra;
557 };
558
559 struct walltype
560 {
561 int x, y;
562 short point2, nextwall, nextsector;
563 unsigned short cstat;
564 short picnum, overpicnum;
565 signed char shade;
566 char pal, xrepeat, yrepeat, xpanning, ypanning;
567 short lotag, hitag, extra;
568 };
569
570 struct spritetype
571 {
572 int x, y, z;
573 short cstat, picnum;
574 signed char shade;
575 char pal, clipdist, filler;
576 unsigned char xrepeat, yrepeat;
577 signed char xoffset, yoffset;
578 short sectnum, statnum;
579 short ang, owner, index, yvel, zvel;
580 short type, hitag, extra;
581 };
582
583 struct PICANM {
584 unsigned int animframes : 5;
585 unsigned int at0_5 : 1;
586 unsigned int animtype : 2;
587 signed int xoffset : 8;
588 signed int yoffset : 8;
589 unsigned int animspeed : 4;
590 unsigned int at3_4 : 3; // type
591 unsigned int at3_7 : 1; // filler
592 };
593 #endif
594
595 struct LOCATION {
596 int x, y, z;
597 int ang;
598 };
599
600 struct POINT2D {
601 int x, y;
602 };
603
604 struct POINT3D {
605 int x, y, z;
606 };
607
608 struct VECTOR2D {
609 int dx, dy;
610 };
611
612 struct Aim {
613 int dx, dy, dz;
614 };
615
616 #pragma pack(pop)
617
ksgnf(float f)618 inline int ksgnf(float f)
619 {
620 if (f < 0)
621 return -1;
622 if (f > 0)
623 return 1;
624 return 0;
625 }
626
IncBy(int a,int b)627 inline int IncBy(int a, int b)
628 {
629 a += b;
630 int q = a % b;
631 a -= q;
632 if (q < 0)
633 a -= b;
634 return a;
635 }
636
DecBy(int a,int b)637 inline int DecBy(int a, int b)
638 {
639 a--;
640 int q = a % b;
641 a -= q;
642 if (q < 0)
643 a -= b;
644 return a;
645 }
646
647 #if 0
648 inline float IncByF(float a, float b)
649 {
650 a += b;
651 float q = fmod(a, b);
652 a -= q;
653 if (q < 0)
654 a -= b;
655 return a;
656 }
657
658 inline float DecByF(float a, float b)
659 {
660 //a--;
661 a -= fabs(b)*0.001;
662 float q = fmod(a, b);
663 a -= q;
664 if (q < 0)
665 a -= b;
666 return a;
667 }
668 #endif
669
ClipLow(int a,int b)670 inline int ClipLow(int a, int b)
671 {
672 if (a < b)
673 return b;
674 return a;
675 }
676
ClipHigh(int a,int b)677 inline int ClipHigh(int a, int b)
678 {
679 if (a >= b)
680 return b;
681 return a;
682 }
683
ClipRange(int a,int b,int c)684 inline int ClipRange(int a, int b, int c)
685 {
686 if (a < b)
687 return b;
688 if (a > c)
689 return c;
690 return a;
691 }
692
ClipRangeF(float a,float b,float c)693 inline float ClipRangeF(float a, float b, float c)
694 {
695 if (a < b)
696 return b;
697 if (a > c)
698 return c;
699 return a;
700 }
701
interpolate(int a,int b,int c)702 inline int interpolate(int a, int b, int c)
703 {
704 return a+mulscale16(b-a,c);
705 }
706
interpolateang(int a,int b,int c)707 inline int interpolateang(int a, int b, int c)
708 {
709 return a+mulscale16(((b-a+1024)&2047)-1024, c);
710 }
711
interpolateangfix16(fix16_t a,fix16_t b,int c)712 inline fix16_t interpolateangfix16(fix16_t a, fix16_t b, int c)
713 {
714 return a+mulscale16(((b-a+0x4000000)&0x7ffffff)-0x4000000, c);
715 }
716
Chance(int a1)717 inline char Chance(int a1)
718 {
719 return wrand() < (a1>>1);
720 }
721
Random(int a1)722 inline unsigned int Random(int a1)
723 {
724 return mulscale(wrand(), a1, 15);
725 }
726
Random2(int a1)727 inline int Random2(int a1)
728 {
729 return mulscale(wrand(), a1, 14)-a1;
730 }
731
Random3(int a1)732 inline int Random3(int a1)
733 {
734 return mulscale(wrand()+wrand(), a1, 15) - a1;
735 }
736
QRandom(int a1)737 inline unsigned int QRandom(int a1)
738 {
739 return mulscale(qrand(), a1, 15);
740 }
741
QRandom2(int a1)742 inline int QRandom2(int a1)
743 {
744 return mulscale(qrand(), a1, 14)-a1;
745 }
746
SetBitString(char * pArray,int nIndex)747 inline void SetBitString(char *pArray, int nIndex)
748 {
749 pArray[nIndex>>3] |= 1<<(nIndex&7);
750 }
751
ClearBitString(char * pArray,int nIndex)752 inline void ClearBitString(char *pArray, int nIndex)
753 {
754 pArray[nIndex >> 3] &= ~(1 << (nIndex & 7));
755 }
756
TestBitString(char * pArray,int nIndex)757 inline char TestBitString(char *pArray, int nIndex)
758 {
759 return pArray[nIndex>>3] & (1<<(nIndex&7));
760 }
761
scale(int a1,int a2,int a3,int a4,int a5)762 inline int scale(int a1, int a2, int a3, int a4, int a5)
763 {
764 return a4 + (a5-a4) * (a1-a2) / (a3-a2);
765 }
766
mulscale16r(int a,int b)767 inline int mulscale16r(int a, int b)
768 {
769 int64_t acc = 1<<(16-1);
770 acc += ((int64_t)a) * b;
771 return (int)(acc>>16);
772 }
773
mulscale30r(int a,int b)774 inline int mulscale30r(int a, int b)
775 {
776 int64_t acc = 1<<(30-1);
777 acc += ((int64_t)a) * b;
778 return (int)(acc>>30);
779 }
780
dmulscale30r(int a,int b,int c,int d)781 inline int dmulscale30r(int a, int b, int c, int d)
782 {
783 int64_t acc = 1<<(30-1);
784 acc += ((int64_t)a) * b;
785 acc += ((int64_t)c) * d;
786 return (int)(acc>>30);
787 }
788
approxDist(int dx,int dy)789 inline int approxDist(int dx, int dy)
790 {
791 dx = klabs(dx);
792 dy = klabs(dy);
793 if (dx > dy)
794 dy = (3*dy)>>3;
795 else
796 dx = (3*dx)>>3;
797 return dx+dy;
798 }
799
800 class Rect {
801 public:
802 int x0, y0, x1, y1;
Rect(int _x0,int _y0,int _x1,int _y1)803 Rect(int _x0, int _y0, int _x1, int _y1)
804 {
805 x0 = _x0; y0 = _y0; x1 = _x1; y1 = _y1;
806 }
isValid(void)807 bool isValid(void) const
808 {
809 return x0 < x1 && y0 < y1;
810 }
isEmpty(void)811 char isEmpty(void) const
812 {
813 return !isValid();
814 }
815 bool operator!(void) const
816 {
817 return isEmpty();
818 }
819
820 Rect & operator&=(Rect &pOther)
821 {
822 x0 = ClipLow(x0, pOther.x0);
823 y0 = ClipLow(y0, pOther.y0);
824 x1 = ClipHigh(x1, pOther.x1);
825 y1 = ClipHigh(y1, pOther.y1);
826 return *this;
827 }
828
offset(int dx,int dy)829 void offset(int dx, int dy)
830 {
831 x0 += dx;
832 y0 += dy;
833 x1 += dx;
834 y1 += dy;
835 }
836
height()837 int height()
838 {
839 return y1 - y0;
840 }
841
width()842 int width()
843 {
844 return x1 - x0;
845 }
846
inside(Rect & other)847 bool inside(Rect& other)
848 {
849 return (x0 <= other.x0 && x1 >= other.x1 && y0 <= other.y0 && y1 >= other.y1);
850 }
851
inside(int x,int y)852 bool inside(int x, int y)
853 {
854 return (x0 <= x && x1 > x && y0 <= y && y1 > y);
855 }
856 };
857
858 class BitReader {
859 public:
860 int nBitPos;
861 int nSize;
862 char *pBuffer;
BitReader(char * _pBuffer,int _nSize,int _nBitPos)863 BitReader(char *_pBuffer, int _nSize, int _nBitPos) { pBuffer = _pBuffer; nSize = _nSize; nBitPos = _nBitPos; nSize -= nBitPos>>3; }
BitReader(char * _pBuffer,int _nSize)864 BitReader(char *_pBuffer, int _nSize) { pBuffer = _pBuffer; nSize = _nSize; nBitPos = 0; }
readBit()865 int readBit()
866 {
867 if (nSize <= 0)
868 ThrowError("Buffer overflow");
869 int bit = ((*pBuffer)>>nBitPos)&1;
870 if (++nBitPos >= 8)
871 {
872 nBitPos = 0;
873 pBuffer++;
874 nSize--;
875 }
876 return bit;
877 }
skipBits(int nBits)878 void skipBits(int nBits)
879 {
880 nBitPos += nBits;
881 pBuffer += nBitPos>>3;
882 nSize -= nBitPos>>3;
883 nBitPos &= 7;
884 if ((nSize == 0 && nBitPos > 0) || nSize < 0)
885 ThrowError("Buffer overflow");
886 }
readUnsigned(int nBits)887 unsigned int readUnsigned(int nBits)
888 {
889 unsigned int n = 0;
890 dassert(nBits <= 32);
891 for (int i = 0; i < nBits; i++)
892 n += readBit()<<i;
893 return n;
894 }
readSigned(int nBits)895 int readSigned(int nBits)
896 {
897 dassert(nBits <= 32);
898 int n = (int)readUnsigned(nBits);
899 n <<= 32-nBits;
900 n >>= 32-nBits;
901 return n;
902 }
903 };
904
905 class BitWriter {
906 public:
907 int nBitPos;
908 int nSize;
909 char *pBuffer;
BitWriter(char * _pBuffer,int _nSize,int _nBitPos)910 BitWriter(char *_pBuffer, int _nSize, int _nBitPos) { pBuffer = _pBuffer; nSize = _nSize; nBitPos = _nBitPos; memset(pBuffer, 0, nSize); nSize -= nBitPos>>3; }
BitWriter(char * _pBuffer,int _nSize)911 BitWriter(char *_pBuffer, int _nSize) { pBuffer = _pBuffer; nSize = _nSize; nBitPos = 0; memset(pBuffer, 0, nSize); }
writeBit(int bit)912 void writeBit(int bit)
913 {
914 if (nSize <= 0)
915 ThrowError("Buffer overflow");
916 *pBuffer |= bit<<nBitPos;
917 if (++nBitPos >= 8)
918 {
919 nBitPos = 0;
920 pBuffer++;
921 nSize--;
922 }
923 }
skipBits(int nBits)924 void skipBits(int nBits)
925 {
926 nBitPos += nBits;
927 pBuffer += nBitPos>>3;
928 nSize -= nBitPos>>3;
929 nBitPos &= 7;
930 if ((nSize == 0 && nBitPos > 0) || nSize < 0)
931 ThrowError("Buffer overflow");
932 }
write(int nValue,int nBits)933 void write(int nValue, int nBits)
934 {
935 dassert(nBits <= 32);
936 for (int i = 0; i < nBits; i++)
937 writeBit((nValue>>i)&1);
938 }
939 };
940
941