1 /*
2  * Zaz
3  * Copyright (C) Remigiusz Dybka 2009 <remigiusz.dybka@gmail.com>
4  *
5  Zaz is free software: you can redistribute it and/or modify it
6  under the terms of the GNU General Public License as published by the
7  Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  Zaz is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  See the GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License along
16  with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #ifndef __BALLPATH_H__
20 #define __BALLPATH_H__
21 
22 #include "common.h"
23 
24 #include <deque>
25 #include <GL/gl.h>
26 #include <cmath>
27 #include <stack>
28 #include "scene.h"
29 #include "textureloader.h"
30 #include "bezier.h"
31 #include "audiobuffer.h"
32 #include "mixer.h"
33 
34 #define NBALLCOLORS 16
35 #define STEPSPERBALL 200
36 #define POINTSPRITEFADEOUTTIME 100
37 #define BALLSIZE 5
38 #define BALLTEXTURECOUNT 8
39 
40 enum Bonus {BONUS_NONE = 0, BONUS_ACCURACY, BONUS_PAUSE, BONUS_SLOW, BONUS_REVERSE, BONUS_BOMB};
41 
42 struct Explosion
43 {
44     double x;
45     double y;
46     int frame;
47     int fc;
48     double r;
49     double s;
50 
51     Explosion(double x, double y, int frame = 0)
xExplosion52             :x(x), y(y), frame(frame), fc(0)
53     {
54         r = rand()%360;
55         s = (rand()%60) + 30;
56     };
57 };
58 
59 struct PointSprite
60 {
61     int points;
62     double x;
63     double y;
64     double xx;
65     double yy;
66     double r;
67     int time;
68 
RecalcPointSprite69     void Recalc()
70     {
71         r+=0.1;
72         x = xx + 2 * cos(r);
73         y = yy;
74 
75         yy += 0.2;
76     };
77 
PointSpritePointSprite78     PointSprite(int points, double x, double y)
79             : points(points), xx(x), yy(y), r(0), time(POINTSPRITEFADEOUTTIME)
80     {
81         r = double(rand()%300) / 100.0;
82         Recalc();
83     };
84 };
85 
86 struct ShotAddr
87 {
88     int pos;
89     bool front;
90 
91     ShotAddr(int pos, bool front = true)
posShotAddr92             :pos(pos), front(front) {};
93 };
94 
95 struct PathStep
96 {
97     double x;
98     double y;
99     double r;
100     bool under;
101     bool hidden;
102 
103     PathStep(double x, double y, double r = 0.0, bool under = false, bool hidden = false)
xPathStep104             : x(x), y(y), r(r), under(under), hidden(hidden) {};
105 };
106 
107 struct PathState
108 {
109     bool ballOut;
110     int score;
111     double feedRate;
112     double startFeedRate;
113     int ballsToDraw;
114     int ballsFromStart;
115     int extraBall;
116     int colors;
117     int lastColors;
118     int comboCnt;
119     bool accuracyShotTriggered;
120     bool bonusPause;
121     int bonusPauseTime;
122 
123     bool bonusSlow;
124     int bonusSlowTime;
125 
126     int bonusReverseBallsLeft;
127     bool hadBonusBomb;
128     bool hadBonusReverse;
129     bool kidsMode;
130     int bonusFrequency;
131     bool speedUp;
132     bool survival;
133 
PathStatePathState134     PathState() : ballOut(false), score(0), feedRate(1), ballsToDraw(-1), extraBall(-1),
135             colors(NBALLCOLORS), lastColors(NBALLCOLORS), comboCnt(0), accuracyShotTriggered(false), bonusPause(false), bonusSlow(false),
136             bonusReverseBallsLeft(0), hadBonusBomb(false), hadBonusReverse(false), kidsMode(false), bonusFrequency(-1),
137             speedUp(false), survival(false) {};
138 };
139 
140 struct Ball
141 {
142     int col;
143     Bonus bonus;
144     double frame;
145     double pos;
146     int size;
147     bool elim;
148     bool elbomb;
149     bool explode;
150 
BallBall151     Ball(int col, Bonus bonus, uint pos)
152             : col(col), bonus(bonus), frame(rand()%(BALLTEXTURECOUNT*BALLTEXTURECOUNT)), pos(pos), size(STEPSPERBALL), elim(false), elbomb(false), explode(false) {};
153 
uposBall154     uint upos()
155     {
156         if (pos > 0)
157         {
158             return (uint)iround(pos);
159         }
160 
161         return 0;
162     }
163 };
164 
165 class BallPath
166 {
167     friend class Player;
168     friend class Game;
169     friend struct Ball;
170     const static int stepsPerBall = STEPSPERBALL;
171     const static int attractDelay = 0;
172     const static int maxPullSpeed = 30;
173     int ballSize;
174     const static int ballGrowSpeed = 10;
175     const static int scoreElimination = 10;
176     const static int maxBallDistanceToAttract = 200;
177     const static int bombDistance = 7;
178     const static int bonusPauseTimeout = 1000;
179     const static int bonusSlowTimeout = 2000;
180     const static int bonusReverseBalls = 20;
181     const static int bonusFrequency = 5;
182     const static int pointSpriteFadeoutTime = POINTSPRITEFADEOUTTIME;
183     const static int extraBallFadeinTime = 150;
184     const static int ballTextureSize = 512;
185     const static int ballTextureCount = BALLTEXTURECOUNT;
186     const static int ballAnimFrames = ballTextureCount * ballTextureCount;
187     const static int ballOneTextureSize = ballTextureSize / ballTextureCount;
188     const static int speedUpMultiplier = 10;
189 
190     Bezier path;
191     bool drawPath;
192     bool pathLooped;
193 
194     uint pthLen;
195     int currPt;
196     double pullSpeed;
197     int waitAttract;
198     bool hasGap;
199     Ball DrawBall();
200     Bonus DrawBonus();
201     void GenRotation();
202     void Attract();
203     void Eliminate();
204     void Anim();
205 
206     GLuint *tex;
207     std::vector<PathStep> ballPath;
208     std::deque<Ball> balls;
209 
210     Scenes::AudioBuffer *rollSound;
211     bool playRoll;
212     stack<Ball>reversedBalls;
213 
214     std::vector<PointSprite> pointSprites;
215     std::vector<Explosion> explosions;
216 
217     Scenes::Mixer **mixer;
218     bool extraBallFading;
219     int extraBallFadeinTimeout;
220 
221 public:
222     PathState state;
223     BallPath(Bezier path, GLuint *tex, Scenes::Mixer **mixer, bool drawPath = false, double ballSizeFactor = 1.0);
224     int Pick(double x, double y, double vx, double vy);
225     ShotAddr PickShot(double x, double y);
226     void InsertBall(ShotAddr addr, int col, Bonus bonus = BONUS_NONE);
227     ~BallPath();
228     void Drive(double d);
229     void NewBall();
230     void Render(bool render_balls = true, bool render_sprites = true, bool render_under = true, bool render_over = true);
231     void Logic();
232 };
233 
234 #endif //__BALLPATH_H__
235