1 // Untahris (Common Playground)
2 // copyright (C) 2006 longuens@users.sourceforge.net
3 // Released under GNU General Public License (see the file COPYING)
4 // --------------------------------------------------------------
5 // Header file for everything.
6
7 #include <vector>
8 #include <string>
9 #include <SDL/SDL.h>
10 #include <SDL/SDL_ttf.h>
11 #include <SDL/SDL_mixer.h>
12
13 using namespace std;
14
15 #define MAXX 128
16 #define MAXY 128
17
18 #define NEVER 2000000000
19
20 int ky[4] = {-1, 0, 1, 0};
21 int kx[4] = {0, 1, 0, -1};
22
23 typedef char int8;
24 typedef short int16;
25 typedef long int32;
26 typedef long long int64;
27
28 enum PlayerKey {
29 keyUp,
30 keyRight,
31 keyDown,
32 keyLeft,
33 keyFire,
34 keyEarth,
35 keyAir,
36 keyWater,
37 // fake keys
38 keyLMB,
39 keyRMB,
40 keyMoveMouse,
41 keyJoinGame
42 };
43
44 char* ctnames = ".#Xabcdefghi0FGLSRjklmxw";
45
46 enum CellType {
47 cFree,
48 cBreakWall,
49 cPermaWall,
50
51 cSnakeHead,
52 cSnakeDead,
53 cSnakeLeft,
54 cSnakeRight,
55 cSnakeUp,
56 cSnakeDown,
57 cSnakeTRON,
58
59 cTetris,
60 cTetrisDown,
61
62 cBig,
63
64 cCannonF,
65 cCannonA,
66
67 cBonusLevel,
68 cBonusScore,
69 cBonusAmmo,
70
71 cCastleWall,
72
73 cBomb1,
74 cBomb2,
75 cExplosion,
76
77 cXunux,
78 cXunuxStable
79 };
80
81 struct TBuffer;
82
83 enum IconId {
84 icFree, icBreak, icPerma,
85 icAmmo, icLevel, icScore,
86 icThrust, icBall, icBullet, icBomber, icBomb1, icBomb2, icSpawn,
87 icExplosion, icExplosion1, icExplosion2, icExplosion3,
88 icCastle, icCannon, icCannonA, icCannonP, icTarget,
89 icWorm, icBazooka, icXunux, icIncastle,
90 icLastIcon
91 };
92
93 // display's icon indexed by given ID
94 #define Ic(x) icons[int(x)]
95 #define DIc(x) ow()->icons[int(x)]
96
97 static const int numIcons = int(icLastIcon);
98
99 static char* iconnames[numIcons] = {
100 "FREE", "BREAK", "PERMA",
101 "AMMO", "LEVEL", "SCORE",
102 "THRUST", "BULLET", "BALL", "BOMBER", "BOMB1", "BOMB2", "SPAWN",
103 "EXPLOSION", "EXPLOSION1", "EXPLOSION2", "EXPLOSION3",
104 "CASTLE", "CANNON", "CANNONA", "CANNONP", "TARGET",
105 "WORM", "BAZOOKA", "XUNUX", "INCASTLE"
106 };
107
108 struct TIcon {
109 int size;
110 int pixel[64][64];
111 };
112
113 struct TDisplayIcon {
114 TIcon i;
115 void loadFrom(FILE *f);
116 void fillWith(const char *chars, int size);
117 void fillTile(TDisplayIcon &orig, int size);
118 void gradFill(int x0, int y0, int x1, int y1, int c0, int c1);
119 void gradBall(int x0, int y0, int x1, int y1, int c0, int c1);
120 void drawLines(int x0, int y0, int x1, int y1, int color, int type);
121 };
122
123 struct TPlayerIcon {
124 TIcon i;
125 int color;
126 void drawAt(int x, int y);
127 void drawAtFlipped(int x, int y);
128 void assignColor(int c);
drawAtCenteredTPlayerIcon129 void drawAtCentered(int x, int y) { drawAt(x-i.size/2, y-i.size/2); }
drawAtCenteredFlippedTPlayerIcon130 void drawAtCenteredFlipped(int x, int y) { drawAtFlipped(x-i.size/2, y-i.size/2); }
131 void drawAtRotated(int x, int y, int rx, int ry);
132 };
133
134 struct TKeypress {
135 int32 time;
136 int8 pressed, mx, my, key;
137 int32 player; // int32 because also used for color
138 };
139
size(vector<T> v)140 template<class T> static inline int size(vector<T> v) {return v.size();}
141
142 enum TGameType {gLocal, gHost, gClient};
143
144 enum TWorldType {
145 wtEmpty,
146 wtCavern,
147 wtSwissCheese,
148 wtConstruction,
149 wtFrame,
150 wtGrid,
151 wtRuins,
152 wtWall,
153 wtLoad,
154 wtLastWorldType
155 };
156
157 static const int numWorldTypes = int(wtLastWorldType);
158
159 static char* worldNames[numWorldTypes] = {
160 "EMPTY", "CAVERN", "SWISS CHEESE", "CONSTRUCTION", "FRAME", "GRID", "RUINS", "WALL", "SAVED MAP"
161 };
162
163 enum TBackground {
164 bgBlack,
165 bgPlasma,
166 bgGradient,
167 bgGrid,
168 bgGray
169 };
170
171 enum TGraphicsType {
172 gtGradient,
173 gtRetro,
174 gtLines,
175 gtASCII
176 };
177
178 static char* bgNames[5] = {"BLACK", "PLASMA", "GRADIENT", "GRID", "GRAY"};
179
180 static char* gtNames[3] = {"GRADIENT", "RETRO", "LINES"};
181
182 struct TEntityConfig {
183 int32 initSpeed;
184 int32 speedBonus;
185 int32 maxSpeed;
186 int32 initAmmo;
187 int32 bonusAmmo;
188 int32 ammoPerShoot;
189 };
190
191 struct TConfig {
192 TGameType gt;
193 string server;
194 string mapname;
195 int port;
196 int res;
197 int pctX, pctY, scorelines;
198 int resX;
199 int resY;
200 int initialWorld;
201 int initBonus;
202
203 int background;
204 int graphicsType;
205
206 bool fs;
207 bool centered;
208
209 string err;
210 bool ok;
211 };
212
213 struct TGameConfig {
214 TEntityConfig ec[9];
215
216 int32 ballSpeed, bombInitRange, bombBonusRange, castleInitEnergy, castleRotSpeed, castleRegenSpeed, castlePowerBase,
217 ammoPerCannon, utetrisMinLength, initFuel, bonusFuel, thrustAcc, fuelUseSpeed, wormWalkSpeed, wormFlySpeed,
218 ninjaRopeLength, ninjaPullSpeed;
219
220 bool
221 ballsTakeBonuses,
222 regenerateLevel, regenerateScore, regenerateAmmo, regenerateDestroyed,
223
224 bulletsKillBalls, cannonsKillBalls, explosionsDestroyBalls, ballsDestroyXunux, ballsDestroyWalls,
225 xunuxKillsSnake, xunuxKillsThruster, xunuxKillsXunux, xunuxAttacksXunux;
226
regenerateTGameConfig227 bool regenerate(CellType c) {
228 if(c == cBonusLevel) return regenerateLevel;
229 if(c == cBonusScore) return regenerateScore;
230 if(c == cBonusAmmo ) return regenerateAmmo;
231 }
232 };
233
234 TConfig c;
235 TGameConfig gc;
236
237 struct TLocalPlayer {
238 int index; // index in the player table
239 int keys[8]; // keys for this player
240 int color;
241 };
242
243 struct TDisplay {
244
245 TDisplayIcon icons[numIcons];
246
247 Mix_Chunk
248 *sndBirth, *sndDeath,
249 *sndBlue, *sndGreen, *sndRed,
250 *sndShoot, *sndHit, *sndPlace;
251
252 SDL_Surface *surface;
253 TTF_Font *font;
254 int sizeX;
255 int sizeY;
256 int ofsX;
257 int ofsY;
258 int Res;
259 bool stop;
260
261 int *bground; // background image
262
263 int interpretPixel(char ch);
264
265 int delta; // time difference
266
267 int getCurrentTime();
268 void setCurrentTime(int val);
269
270 void init();
271
272 void setMode();
273
274 void initForGame();
275
276 void initBackground();
277
278 void loop();
279
280 void draw();
281
282 void putpix(int x, int y, int c);
283
284 void playSoundAt(Mix_Chunk *sound, int x, int y);
285
286 void addKeypress(int key, bool type);
287 void addMouseEvent(int x, int y, int type, int button);
288
289 void putText(int x, int y, int color, const char *text, int align);
290
291 void menuLoop();
292 void menuKey(int key);
293 void menuDraw();
294
295 int menupos;
296
297 void genBGround(int x0, int y0, int x1, int y1, int sy);
298 };
299
300 struct TException {
301 string msg;
302 int data;
303 string ds;
304 TException(string m, int d=0, string s="") {msg=m; data=d; ds=s;}
305 };
306
307 struct TPlayer {
308 TPlayerIcon icons[numIcons];
309 int8 index;
310 int8 editing, charid, editid;
311 int16 lives, frags;
312 int32 score, level, ammo, typeval;
313 int16 killer; // who killed us - used by Xunux
314 char *getTypeName();
315 int32 color; // color used
316 bool key[8]; // keys pressed
localDrawTPlayer317 void localDraw() {}
318 void init(int c);
useAmmoTPlayer319 bool useAmmo(int qty)
320 {if(ammo < qty) return false; ammo -= qty; return true;}
ecTPlayer321 TEntityConfig& ec() { return gc.ec[charid]; }
useAmmoTPlayer322 bool useAmmo() { useAmmo(ec().ammoPerShoot); }
gainAmmoTPlayer323 void gainAmmo() { ammo += ec().bonusAmmo; }
324 void save(TBuffer& b);
325 void load(TBuffer& b);
326 void createIcons();
327 };
328
329 struct TPlayObject {
330 public:
331 int8 owner;
332 int32 time;
getTimeTPlayObject333 int getTime() {return time;}
~TPlayObjectTPlayObject334 virtual ~TPlayObject () {}
reactToKeyTPlayObject335 virtual void reactToKey(PlayerKey pk, bool pressed) {}
336 virtual void reactToKey(TKeypress& k);
drawTPlayObject337 virtual void draw() {}
goTPlayObject338 virtual void go() {}
339 virtual void pausedGo();
delayTPlayObject340 virtual void delay(int t) { time += t; } // remove for non-paused objects
341 TPlayer *ow();
342
ecTPlayObject343 struct TEntityConfig& ec() { return ow()->ec(); }
344 int spd();
scoreGainTPlayObject345 int scoreGain() { return (10+ow()->level)*(10+ow()->level)/10; }
bulletSpeedTPlayObject346 int bulletSpeed() { return 50 + ow()->level/4; }
347 virtual void save(TBuffer& b) = 0;
348
349 // these methods are supposed to check whether the two collide
reactToBulletTPlayObject350 virtual bool reactToBullet(struct OBullet* bullet) {return false;}
351 // return true if the bullet is to disappear
reactToPadTPlayObject352 virtual bool reactToPad(struct OPad* pad) {return false;}
353 // return true if it kills the pad (reactToPad destroys pad object)
reactToThrusterTPlayObject354 virtual bool reactToThruster(struct OThruster* bullet) {return false;}
355 // return true if it kills the thruster (react destroy thuster)
smashedByBallTPlayObject356 virtual bool smashedByBall(struct OBall* ball) {return false;}
357 // return true if it changes the ball's direction
reactToCannonTPlayObject358 virtual void reactToCannon(struct OCannonball* ball) {}
359 // return true if it changes the ball's direction
destroyBallsTPlayObject360 virtual void destroyBalls() { }
361 // react to 'no balls' command
catchesRopeTPlayObject362 virtual bool catchesRope(int rx, int ry) {return false;}
363 // does ninja rope at (rx,ry) hook to it?
pullRopeTPlayObject364 virtual void pullRope(struct OWorm *worm, int ddx, int ddy) {}
365 // pull the ninja rope at (x,y)
366
367 void killedBy(int player);
368 // player killed me -- this deletes the object and scores a frag
369 };
370
371 struct TPlayground {
372 int32 time;
373 int32 kqpos;
374 bool paused;
375
376 int64 seed;
377 int rand();
378
379 int16 sizeX, sizeY;
380 CellType map[MAXY][MAXX];
381 char owner[MAXY][MAXX];
382
mapSetTPlayground383 void mapSet(int x, int y, CellType c, char o) {
384 map[y][x] = c;
385 owner[y][x] = o;
386 }
387
388 vector<TPlayer*> pl;
389 vector<TPlayObject*> objects;
390
391 void upTime(int newTime);
392
393 void cleanup();
394 void init(int sx, int sy);
395 void generate();
396 void saveMap();
397 void destroyBalls();
398
399 int addPlayer(TPlayer* p);
400
401 void deleteObject(TPlayObject *obj);
402
403 void save(TBuffer& b);
404 void load(TBuffer& b);
405 };
406
407 char *charnames[10] = {
408 "SNAKE",
409 "UTRON",
410 "UTETRIS",
411 "THRUSTER",
412 "BOMBER",
413 "CASTLE",
414 "WORM",
415 "PAD",
416 "XUNUX",
417 "Ball"
418 };
419
420 char *editnames[13] = {
421 "-neutral ball-",
422 "-break wall-",
423 "-perma wall-",
424 "-clear-",
425 "-cannon-",
426 "-bonus ammo-",
427 "-bonus level-",
428 "-bonus other-",
429 "generate [F7]",
430 "no balls [F8]",
431 "save map [F2]",
432 "pause game [F4]",
433 "quit game [ESC]"
434 };
435
436 #define tnSNAKE 0
437 #define tnUTRON 1
438 #define tnUTETRIS 2
439 #define tnTHRUSTER 3
440 #define tnBOMBER 4
441 #define tnCASTLE 5
442 #define tnWORM 6
443 #define tnPAD 7
444 #define tnXUNUX 8
445
446 #define KQSIZE 32768
447
448 TDisplay d;
449 TPlayground g;
450 vector<TLocalPlayer> lps;
451
452 TKeypress kqueue[KQSIZE];
453 int kqend;
454
455 void addKeyToQueue(TKeypress& kp);
456
457 void startGame();
458 void dataTransfer();
459 void broadcastKey(TKeypress& kp);
460
461