source: trunk/monsterz/title.cpp @ 322

Last change on this file since 322 was 322, checked in by sam, 10 years ago

Implement title screen animations.

File size: 5.8 KB
Line 
1//
2// Monsterz
3//
4// Copyright: (c) 2005-2011 Sam Hocevar <sam@hocevar.net>
5//   This program is free software; you can redistribute it and/or
6//   modify it under the terms of the Do What The Fuck You Want To
7//   Public License, Version 2, as published by Sam Hocevar. See
8//   http://sam.zoy.org/projects/COPYING.WTFPL for more details.
9//
10
11#if defined HAVE_CONFIG_H
12#   include "config.h"
13#endif
14
15#include <cstdio>
16#include <cmath>
17#include <cstdlib>
18#include <ctime>
19
20#include "core.h"
21#include "monsterz.h"
22#include "title.h"
23
24/*
25 * Title implementation class
26 */
27
28class TitleData
29{
30    friend class Title;
31
32private:
33    int screen, title, logo;
34    int anim[6];
35    int event[7];
36
37    enum
38    {
39        IDLE,
40        ANIM,
41        EVENT,
42    }
43    state;
44
45    enum
46    {
47        DAY,
48        NIGHT,
49        STEALTH,
50        RADIO,
51    }
52    period, nextperiod;
53
54    float timer, length;
55    int nframes, animid;
56};
57
58/*
59 * Public Title class
60 */
61
62Title::Title()
63  : data(new TitleData())
64{
65    srand(rand() ^ time(NULL));
66
67    data->screen = Tiler::Register(PNG_BACKGROUND, 640, 480, 1.0f);
68    data->logo = Tiler::Register(PNG_LOGO, 380, 181, 1.0f);
69    data->title = Tiler::Register(PNG_TITLE, 384, 384, 1.0f);
70    for (int n = 0; n < 6; n++)
71        data->anim[n] = Tiler::Register(PNG_TITLEANIM[n], 384, 384, 1.0f);
72    for (int n = 0; n < 7; n++)
73        data->event[n] = Tiler::Register(PNG_TITLEEVENT[n], 384, 384, 1.0f);
74    data->state = TitleData::IDLE;
75    data->period = TitleData::DAY;
76    data->nextperiod = TitleData::DAY;
77    data->timer = RandF(2000.0f, 3000.0f);
78}
79
80void Title::TickGame(float deltams)
81{
82    Entity::TickGame(deltams);
83
84    data->timer -= deltams;
85
86    /* Probability of playing an animation given the current period */
87    static float const p1[] = { 0.6f, 0.3f, 0.0f, 0.2f };
88    /* Probability of a period change given the current period */
89    static float const p2[] = { 0.1f, 0.2f, 0.5f, 0.5f };
90    /* Number of frames in transition anims and events */
91    static int const t1[] = { 31, 26, 7, 7, 32, 6, 31 };
92    static int const t2[] = { 2, 4, 11, 4, 6, 2 };
93
94    switch (data->state)
95    {
96    case TitleData::IDLE:
97        if (data->timer > 0.0f)
98            break;
99        if (RandF() < p1[data->period])
100        {
101            switch (data->period)
102            {
103            case TitleData::DAY:
104                data->animid = rand() % 4;
105                break;
106            case TitleData::NIGHT:
107                data->animid = (rand() % 2) ? 4 : 6;
108                break;
109            case TitleData::STEALTH:
110                /* XXX: we should not be here! */
111                break;
112            case TitleData::RADIO:
113                data->animid = 5;
114                break;
115            }
116            data->state = TitleData::EVENT;
117            data->nframes = t1[data->animid];
118            data->timer = data->length = data->nframes * 100.0f;
119        }
120        else if (RandF() < p2[data->period])
121        {
122            switch (data->period)
123            {
124            case TitleData::DAY:
125                data->nextperiod = TitleData::NIGHT;
126                data->animid = 0;
127                break;
128            case TitleData::NIGHT:
129                if (RandF() < 0.6f)
130                {
131                    data->nextperiod = TitleData::DAY;
132                    data->animid = 5;
133                }
134                else
135                {
136                    data->nextperiod = TitleData::STEALTH;
137                    data->animid = 1;
138                }
139                break;
140            case TitleData::STEALTH:
141                if (RandF() < 0.3f)
142                {
143                    data->nextperiod = TitleData::RADIO;
144                    data->animid = 2;
145                }
146                else
147                {
148                    data->nextperiod = TitleData::NIGHT;
149                    data->animid = 4;
150                }
151                break;
152            case TitleData::RADIO:
153                data->nextperiod = TitleData::STEALTH;
154                data->animid = 3;
155                break;
156            }
157            data->state = TitleData::ANIM;
158            data->nframes = t2[data->animid];
159            data->timer = data->length = data->nframes * 100.0f;
160        }
161        else
162        {
163            data->timer = RandF(500.0f, 1000.0f);
164        }
165        break;
166    case TitleData::ANIM:
167        if (data->timer < 0.0f)
168            data->period = data->nextperiod;
169            /* Fall through */
170    case TitleData::EVENT:
171        if (data->timer < 0.0f)
172        {
173            data->state = TitleData::IDLE;
174            data->timer = RandF(500.0f, 1000.0f);
175        }
176        break;
177    }
178}
179
180void Title::TickDraw(float deltams)
181{
182    Entity::TickDraw(deltams);
183
184    int tiler = data->title;
185    int id = 0;
186
187    switch (data->state)
188    {
189    case TitleData::IDLE:
190        id = (int)data->period;
191        break;
192    case TitleData::ANIM:
193        tiler = data->anim[data->animid];
194        id = data->nframes - 1 - (data->nframes * data->timer / data->length);
195        if (id < 0) id = 0;
196        if (id > data->nframes - 1) id = data->nframes - 1;
197        break;
198    case TitleData::EVENT:
199        tiler = data->event[data->animid];
200        id = data->nframes - 1 - (data->nframes * data->timer / data->length);
201        if (id < 0) id = 0;
202        if (id > data->nframes - 1) id = data->nframes - 1;
203        break;
204    }
205
206    Scene::GetDefault()->AddTile((data->screen << 16) | 0, 0, 0, 0, 0);
207    Scene::GetDefault()->AddTile((tiler << 16) | id, 24, 72, 1, 0);
208    Scene::GetDefault()->AddTile((data->logo << 16) | 0, 26, 250, 2, 0);
209}
210
211Title::~Title()
212{
213    Tiler::Deregister(data->screen);
214    Tiler::Deregister(data->logo);
215    Tiler::Deregister(data->title);
216    for (int n = 0; n < 6; n++)
217        Tiler::Deregister(data->anim[n]);
218    for (int n = 0; n < 7; n++)
219        Tiler::Deregister(data->event[n]);
220    delete data;
221}
222
Note: See TracBrowser for help on using the repository browser.