source: trunk/orbital/orbital.cpp @ 1509

Last change on this file since 1509 was 1509, checked in by sam, 9 years ago

orbital: start working on the generic chamfer solution.

File size: 9.4 KB
Line 
1//
2// Orbital
3//
4// Copyright: (c) 2009-2012 Cédric Lecacheur <jordx@free.fr>
5//            (c) 2009-2012 Benjamin Huet <huet.benjamin@gmail.com>
6//            (c) 2012 Sam Hocevar <sam@hocevar.net>
7//
8
9#if defined HAVE_CONFIG_H
10#   include "config.h"
11#endif
12
13#if defined _WIN32
14#   include <direct.h>
15#endif
16
17#if defined _XBOX
18#   define _USE_MATH_DEFINES /* for M_PI */
19#   include <xtl.h>
20#   undef near /* Fuck Microsoft */
21#   undef far /* Fuck Microsoft again */
22#elif defined _WIN32
23#   define _USE_MATH_DEFINES /* for M_PI */
24#   define WIN32_LEAN_AND_MEAN
25#   include <windows.h>
26#   undef near /* Fuck Microsoft */
27#   undef far /* Fuck Microsoft again */
28#else
29#   include <cmath>
30#endif
31
32#if USE_SDL && defined __APPLE__
33#   include <SDL_main.h>
34#endif
35
36#include "core.h"
37#include "loldebug.h"
38
39using namespace std;
40using namespace lol;
41
42#include "orbital.h"
43
44Orbital::Orbital(bool editor)
45  : m_model(1.f),
46    m_stick(0),
47    m_angle(0.f),
48    m_zoom(5.f),
49    m_editor(editor)
50{
51#if 0
52    int max_x = 20;
53    int max_y = 20;
54    for (int j = 0; j < max_x; j++)
55    {
56        for (int i = 0; i < max_y; i++)
57        {
58            m.Compile(((i + j) % 2) ? "sc.0,.1,.2,1,scb.0,.1,.2,1"
59                                        : "sc.0,.0,.1,1,scb.0,.0,.1,1");
60            m.Compile("ac4,2,44,40,0,0,ty-1,ad4,40,0,ry45");
61            m.Scale(vec3(std::sqrt(0.5f)));
62            m.Translate(vec3(   i * 44 - (44 * (max_x * 0.5f)), 0,
63                                j * 44 - (44 * (max_y * 0.5f))));
64            m.Flush();
65        }
66    }
67#endif
68
69#if 0
70    /* Yellow sphere */
71    m.Compile("sc1,1,0,1,asph10,30,20,24");
72    m.Compile("t0,0,60,fl");
73
74    /* Pink box */
75    m.Compile("sc1,0,1,1,afcb10,10,10,1,rx45,rz45");
76    m.Compile("t-20,20,0,fl");
77
78    /* Large meteor */
79    m.Compile("sc0,0,0.3,1,afcb30,30,30,5,ry45,rx45,afcb30,30,30,5");
80    m.Compile("t40,40,0,fl");
81
82    /* Orange/white alien */
83    m.Compile("sc1,0.7,0,1,afcb12,3,10,0.4,tz3,sc1,1,1,1,afcb2,10,10,0.4");
84    m.Compile("t0,40,-20,fl");
85    //m.Compile("rx20,ry30,t0,40,-20,fl");
86
87    /* Orange fire */
88    m.Compile("sc1,1,0,1,scb1,0,0,0,at4,1,s1.5,1,4,tz-13,ad6,5.8,1");
89    m.Compile("t-40,40,0,fl");
90
91    /* Lasers */
92    m.Compile("sc1,1,1,1,scb0,0,0,1,aq8,1,sx0.25,tx-3,sc1,0,0,1,scb0,0,0,1,aq8,1,tx4,sz50,sx0.3,tz-200,mx,as10,12,8,1,1,ty60,fl");
93#endif
94
95    //m_particlesystem = new ParticleSystem();
96    //Ticker::Ref(m_particlesystem);
97
98    m_small_stars = new StarField(100, 1.f, 20.f);
99    Ticker::Ref(m_small_stars);
100    m_large_stars = new StarField(100, 2.f, 10.f);
101    Ticker::Ref(m_large_stars);
102
103    /* Create a camera that matches the settings of XNA Orbital */
104    m_camera = new Camera(vec3(0.f, 600.f, 50.f),
105                          vec3(0.f, 0.f, 50.f),
106                          vec3(0, 0, -1));
107    m_camera->SetRotation(quat::fromeuler_yxz(0.f, -30.f, 0.f));
108    m_camera->SetOrtho(1280.f / 3, 960.f / 3, -1000.f, 1000.f);
109    Ticker::Ref(m_camera);
110
111    if (m_editor)
112    {
113        /* Grey/red bonus */
114        //m.Compile("[sc#9ac afcb7 4 7 0.6 sc#f04 afcb4 7 4 0.6]");
115        #if 0
116        m.Compile("sc#d91"
117                  "[afcb30 3 3 .8]"
118                  "sc#cca"
119                  "[afcb10 10 10 1]"
120                  "[afcb.4 .4 12 .4 tz3 tx8 mx]"
121                  "[afcb.4 .4 12 .4 tz3 tx12 mx]"
122                  "sc#69c9"
123                  "[afcb5 8 8 1 ty3 tz3]");
124         #endif
125         m.Compile("sc#f00 scb#f00 [acg10 5 8 8 2 2 0 0 ch.4]");
126    }
127    else
128    {
129        /* Add tanks */
130        for (int j = 0; j < 2; j++)
131        for (int i = 0; i < 2; i++)
132        {
133            m_tanks << new Tank();
134            m_tanks.Last()->m_position = vec3(i * 80.f, 0, j * 80.f + 120.f);
135            m_tanks.Last()->SetTarget(vec3(i * 160.f - 200.f, 0, j * 160.f - 130.f));
136            Ticker::Ref(m_tanks.Last());
137        }
138
139        //m_snakes.Push(new Snake(3));
140        //Ticker::Ref(m_snakes.Last());
141        //m_snakes.Push(new Snake(8));
142        //Ticker::Ref(m_snakes.Last());
143        m_snakes.Push(new Snake(33));
144        Ticker::Ref(m_snakes.Last());
145
146        /* Add players */
147        for (int i = 0; i < 2; i++)
148        {
149            m_players << new Player(i);
150            Ticker::Ref(m_players.Last());
151        }
152    }
153
154        m_Lolnament = NULL;//new Lolnament();
155        Ticker::Ref(m_Lolnament);
156
157    m_ready = false;
158}
159
160void Orbital::TickGame(float seconds)
161{
162    WorldEntity::TickGame(seconds);
163
164    if (Input::GetButtonState(27 /*SDLK_ESCAPE*/))
165        Ticker::Shutdown();
166
167#if 0
168    if (m_auto_cam_timer > 0.0f)
169        m_auto_cam_timer -= seconds;
170
171    //Doing the query with actual values, cause I want to stay SDL-free for now.
172
173    int HMovement = Input::GetButtonState(275 /*SDLK_RIGHT*/) - Input::GetButtonState(276 /*SDLK_LEFT*/);
174    int VMovement = Input::GetButtonState(274 /*SDLK_DOWN*/) - Input::GetButtonState(273 /*SDLK_UP*/);
175    int RMovement = Input::GetButtonState(280 /*SDLK_PAGEUP*/) - Input::GetButtonState(281 /*SDLK_PAGEDOWN*/);
176
177    vec3 new_angular_velocity = vec3(0.0f);
178
179    if (VMovement != 0 || HMovement != 0 || RMovement != 0)
180    {
181        new_angular_velocity = vec3(HMovement, VMovement, RMovement) * 50.0f;
182        m_auto_cam_timer = 2.0f;
183    }
184    else if (m_auto_cam_timer <= 0.0f)
185    {
186        /* Order is yaw, pitch, roll */
187        new_angular_velocity = clamp(-m_angle, vec3(40.f, -20.f, -40.f),
188                                               vec3(40.f,  20.f,  40.f));
189    }
190
191    m_angular_velocity += (new_angular_velocity - m_angular_velocity)
192                          * (seconds / (seconds + 0.3f));
193    m_angle += m_angular_velocity * seconds;
194
195    /* TODO: implement "vec3 % float" or "fmod(vec3, float)" */
196    for (int n = 0; n < 3; n++)
197    {
198        if (m_angle[n] > 180.f)
199            m_angle[n] -= 360.f;
200        else if (m_angle[n] < -180.f)
201            m_angle[n] += 360.f;
202    }
203
204    /* Yaw around Y, Pitch around X, Roll around Z. Since it's the camera
205     * we want to move, use the inverse transform. */
206    mat4 anim = mat4(1.f / quat::fromeuler_yxz(m_angle));
207#endif
208
209#if 0
210    vec3 new_camera_pos = vec3(0,0,0);
211
212    for (int i = 0; i < m_tanks.Count(); i++)
213        new_camera_pos += m_tanks[i]->m_position;
214    for (int i = 0; i < m_snakes.Count(); i++)
215        new_camera_pos += m_snakes[i]->GetBarycenter();
216    for (int i = 0; i < m_players.Count(); i++)
217        new_camera_pos += m_players[i]->m_position;
218
219    new_camera_pos /= (float)(m_players.Count() + m_tanks.Count() + m_snakes.Count());
220    new_camera_pos += vec3(0.f, 0.f, -50.f);
221
222    new_camera_pos = m_camera->GetTarget() + (new_camera_pos - m_camera->GetTarget()) * (seconds / (seconds + 0.15f));
223    m_camera->SetPosition(new_camera_pos + vec3(0.f, 600.f, 0.f));
224    m_camera->SetTarget(new_camera_pos);
225#endif
226
227    if (m_editor)
228    {
229        float rightleft = 0.f, updown = 0.f, inout = 0.f;
230
231        if (!m_stick)
232            m_stick = Input::TrackStick();
233        if (m_stick && m_stick->GetAxisCount() >= 4)
234        {
235            rightleft += 1.f * m_stick->GetAxis(2);
236            updown += -1.f * m_stick->GetAxis(3);
237            inout += -1.f * m_stick->GetAxis(1);
238        }
239
240        if (rightleft * rightleft + updown * updown > 0.2f)
241        {
242            float angle = atan2(updown, rightleft);
243            angle = (int)(angle / ((float)M_PI / 4.f) + 8.5f) * ((float)M_PI / 4.f);
244            rightleft = cos(angle);
245            updown = sin(angle);
246        }
247        else
248        {
249            rightleft = updown = 0.f;
250        }
251
252        m_model = mat4::fromeuler_zyx(0.f, 5.f * rightleft, 5.f * updown)
253                   * m_model;
254        m_zoom *= 1.f + seconds * 0.8f * inout;
255        if (m_zoom > 10.f) m_zoom = 10.f;
256        else if (m_zoom < 0.1f) m_zoom = 0.1f;
257        m_angle += 50.f * seconds;
258    }
259    else
260    {
261    }
262}
263
264void Orbital::TickDraw(float seconds)
265{
266    WorldEntity::TickDraw(seconds);
267
268    if (!m_ready)
269    {
270        m.MeshConvert();
271
272        /* FIXME: this object never cleans up */
273        m_ready = true;
274    }
275
276    Video::SetClearColor(vec4(0.0f, 0.0f, 0.12f, 1.0f));
277
278    if (m_editor)
279    {
280        mat4 anim1 = mat4::rotate(m_angle, vec3(1.f, 0.f, 0.f));
281        mat4 anim2 = mat4::rotate(m_angle, vec3(0.f, 1.f, 0.f));
282        mat4 anim3 = mat4::rotate(m_angle, vec3(0.f, 0.f, 1.f));
283
284        m.Render(mat4::scale(vec3(m_zoom))
285                  * mat4::translate(0.f, 10.f, 10.f)
286                  * m_model);
287
288        m.Render(mat4::translate(-150.f, -350.f, 0.f) * anim1);
289        m.Render(mat4::translate(-150.f, -200.f, 0.f) * anim2);
290        m.Render(mat4::translate(-150.f, -50.f, 0.f) * anim3);
291        m.Render(mat4::translate(-150.f, 100.f, 0.f));
292    }
293}
294
295Orbital::~Orbital()
296{
297    for (int i = 0; i < m_tanks.Count(); i++)
298        Ticker::Unref(m_tanks[i]);
299    for (int i = 0; i < m_players.Count(); i++)
300        Ticker::Unref(m_players[i]);
301    for (int i = 0; i < m_snakes.Count(); i++)
302        Ticker::Unref(m_snakes[i]);
303    if (m_stick)
304        Input::UntrackStick(m_stick);
305    //Ticker::Unref(m_particlesystem);
306    Ticker::Unref(m_small_stars);
307    Ticker::Unref(m_large_stars);
308    Ticker::Unref(m_camera);
309    Ticker::Unref(m_Lolnament);
310}
311
312int main(int argc, char **argv)
313{
314    //Application app("Orbital", ivec2(1280, 720), 60.0f);
315    Application app("Orbital", ivec2(800, 600), 60.0f);
316
317#if defined _MSC_VER && !defined _XBOX
318    _chdir("..");
319#elif defined _WIN32 && !defined _XBOX
320    _chdir("../..");
321#endif
322
323    //new DebugFps(5, 5);
324    new Orbital(argc > 1);
325    app.ShowPointer(false);
326
327    app.Run();
328
329    return EXIT_SUCCESS;
330}
331
Note: See TracBrowser for help on using the repository browser.