Make autopackage work
[crack-attack.git] / src / Displayer.cxx
blob9f23b4dce76531e41e90af3f75dec6c968c4da34
1 /*
2 * Displayer.cxx
3 * Daniel Nelson - 8/26/0
5 * Copyright (C) 2000 Daniel Nelson
6 * Copyright (C) 2004 Andrew Sayman
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 * Daniel Nelson - aluminumangel.org
23 * 174 W. 18th Ave.
24 * Columbus, OH 43210
26 * Handles all the prettyness; or uglyness, as it now stands.
29 #include <cstring>
30 #include <cctype>
31 #include <GL/glut.h>
33 #ifndef _WIN32
34 # include <GL/glext.h>
35 #else
36 # include <glext.h>
37 #endif
39 #ifdef DEVELOPMENT
40 #include <iomanip>
41 #ifndef _WIN32
42 # include <sstream>
43 #else
44 # include <strstrea.h>
45 #endif
46 #endif
48 #include <sys/time.h>
50 using namespace std;
52 #include "TextureLoader.h"
53 #include "Game.h"
54 #include "Displayer.h"
55 #include "CelebrationManager.h"
56 #include "GarbageFlavorImage.h"
57 #include "SignManager.h"
58 #include "LightManager.h"
59 #include "MetaState.h"
60 #include "SparkleManager.h"
61 #include "String.h"
62 #include "ScoreRecordManager.h"
63 #include "Score.h"
65 GLenum Displayer::rescale_method;
66 bool Displayer::opengl_version_1_2;
68 int Displayer::state;
69 int Displayer::main_window;
70 GLfloat Displayer::play_offset_y;
72 #ifndef NO_MULTITEXTURING
73 # ifndef _WIN32
74 # else
75 PFNGLACTIVETEXTUREARBPROC Displayer::glActiveTextureARB;
76 PFNGLCLIENTACTIVETEXTUREARBPROC Displayer::glClientActiveTextureARB;
77 # endif
78 #endif
80 #ifdef DEVELOPMENT
81 GLint Displayer::screen_length;
82 #endif
84 void Displayer::initialize ( int width, int height )
86 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
87 if (width != -1 && height != -1) {
88 glutInitWindowSize(width, height);
89 } else {
90 glutInitWindowSize(DC_WINDOW_PIXEL_STARTING_WIDTH,
91 DC_WINDOW_PIXEL_STARTING_HEIGHT);
93 main_window = glutCreateWindow(GC_NAME);
95 state = 0;
97 opengl_version_1_2 = false;
98 char *string = (char *) glGetString(GL_VERSION);
99 if (string[0] > '1' || (string[0] == '1' && string[2] >= '2'))
100 opengl_version_1_2 = true;
102 // determine rescaling method for normals
103 if (opengl_version_1_2)
104 rescale_method = GL_RESCALE_NORMAL;
105 else
106 rescale_method = GL_NORMALIZE;
108 #ifndef NO_MULTITEXTURING
109 // check for multitexturing
110 if (checkExtension("GL_ARB_multitexture")) {
111 GLint n;
112 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &n);
113 if (n > 1) state |= DS_MULTITEXTURING;
116 # ifndef _WIN32
117 # else
118 // locate the extension function pointers
119 if (state & DS_MULTITEXTURING) {
120 glActiveTextureARB
121 = (PFNGLACTIVETEXTUREARBPROC) wglGetProcAddress("glActiveTextureARB");
122 glClientActiveTextureARB
123 = (PFNGLCLIENTACTIVETEXTUREARBPROC) wglGetProcAddress("glClientActiveTextureARB");
125 # endif
126 #endif
128 #ifdef DEVELOPMENT
129 string = (char *) glGetString(GL_EXTENSIONS);
130 cout << "OpenGL version: " << glGetString(GL_VERSION)
131 << "\nOpenGL extensions:\n " << *string;
132 for (char *p = string + 1; *p; p++) {
133 if (isspace(*p)) continue;
134 if (isspace(*(p - 1)))
135 cout << "\n ";
136 cout << *p;
138 cout << endl;
139 #endif
141 SparkleManager::initialize();
142 SignManager::initialize();
143 LightManager::initialize();
144 GarbageFlavorImage::initialize();
145 CelebrationManager::initialize();
146 ScoreRecordManager::initialize();
148 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
150 glEnable(GL_TEXTURE_2D);
151 glEnable(GL_BLEND);
153 glEnable(GL_CLIP_PLANE_PLAY_FLOOR);
154 const GLdouble play_bottom[]
155 = { 0.0, 1.0, 0.0, DC_PLAY_HEIGHT * DC_CAMERA_HEIGHT_RATIO };
156 glClipPlane(GL_CLIP_PLANE_PLAY_FLOOR, play_bottom);
158 glEnable(GL_LIGHT0);
159 const GLfloat headlight_position[]
160 = { 0.0f, DC_HEADLIGHT_Y_OFFSET, DC_HEADLIGHT_Z_OFFSET, 1.0f };
161 glLightfv(GL_LIGHT0, GL_POSITION, headlight_position);
163 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
165 GLfloat white[] = { 1.0f, 1.0f, 1.0f, 1.0f };
166 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, white);
167 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
169 generateBlockDisplayList();
170 generateGarbageExtras();
171 generateGarbageThinMiddleList();
172 generateGarbageThinCapList();
173 generateGarbageThickCornerList();
174 generateGarbageThickEdgeList();
175 generateGarbageThickMiddleList();
176 generateGarbageSmallList();
177 generateSparkleList();
178 generateSignList();
179 generateSwapperList();
180 generateExternalCandy();
181 generateLevelLights();
182 generateClock();
183 generateMessages();
185 String::readyLetterTextures();
186 generateNameTexture();
187 generateScoreRecord();
189 glMatrixMode(GL_PROJECTION);
190 glLoadIdentity();
191 glFrustum(-(DC_PLAY_PIXEL_OFFSET_X / DC_PLAY_PIXEL_WIDTH + 0.5f)
192 * DC_PLAY_WIDTH, ((1.0f - DC_PLAY_PIXEL_OFFSET_X - DC_PLAY_PIXEL_WIDTH)
193 / DC_PLAY_PIXEL_WIDTH + 0.5f) * DC_PLAY_WIDTH, -DC_PLAY_HEIGHT
194 * DC_CAMERA_HEIGHT_RATIO, DC_PLAY_HEIGHT * (1.0 - DC_CAMERA_HEIGHT_RATIO),
195 40.0, 65.0);
196 glMatrixMode(GL_MODELVIEW);
199 void Displayer::gameStart ( )
201 LightManager::resetHeadLight();
202 ScoreRecordManager::gameStart();
205 void Displayer::gameFinish ( )
207 CelebrationManager::gameFinish();
208 ScoreRecordManager::gameFinish();
211 void Displayer::cleanUp ( )
213 glutDestroyWindow(main_window);
214 for (int n = DC_NUMBER_USE_GARBAGE_TEX; n--; )
215 if (garbage_texture_data[n] != null) {
216 delete [] garbage_texture_data[n];
217 garbage_texture_data[n] = null;
219 for (int n = DC_NUMBER_MESSAGE_TEX; n--; )
220 if (message_texture_data[n] != null) {
221 delete [] message_texture_data[n];
222 message_texture_data[n] = null;
225 if (player_rank_texture_data != null) {
226 delete [] player_rank_texture_data;
227 player_rank_texture_data = null;
229 if (MetaState::mode & CM_SOLO)
230 for (int n = GC_SCORE_REC_LENGTH - 1; n--; )
231 if (record_texture_data[n] != null) {
232 delete [] record_texture_data[n];
233 record_texture_data[n] = null;
235 if (record_texture_data != null) {
236 delete [] record_texture_data;
237 record_texture_data = null;
240 String::freeLetterTextures();
243 void Displayer::reshape ( int width, int height )
245 if (DC_WINDOW_PIXEL_WIDTH * height / DC_WINDOW_PIXEL_HEIGHT != width) {
246 height = (height + width) >> 1;
247 glutReshapeWindow(DC_WINDOW_PIXEL_WIDTH * height / DC_WINDOW_PIXEL_HEIGHT,
248 height);
249 } else {
250 glViewport(0, 0, width, height);
251 #ifdef DEVELOPMENT
252 screen_length = width;
253 #endif
257 void Displayer::displayMeta ( )
259 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
261 glLoadIdentity();
263 // disables GL_BLEND internally
264 drawExternalCandy();
266 drawScoreToBeatMessage();
268 glDisable(GL_TEXTURE_2D);
270 if (!(MetaState::mode & CM_REALLY_LOW_GRAPHICS))
271 glEnable(GL_LIGHTING);
272 glEnable(GL_COLOR_MATERIAL);
274 if (!(MetaState::mode & CM_REALLY_LOW_GRAPHICS))
275 drawLevelLights();
277 if (CelebrationManager::draw_game) {
279 LightManager::timeStepInitialize();
281 int hold_time_step = Game::time_step;
282 Game::time_step = MetaState::final_time_step;
284 calculatePlayOffset();
286 glEnable(GL_DEPTH_TEST);
287 glEnable(GL_CULL_FACE);
289 LightManager::setupHeadLightMeta();
291 drawBlocks();
293 glEnable(GL_TEXTURE_2D);
295 drawGarbage();
297 glDisable(GL_CULL_FACE);
298 glDisable(GL_TEXTURE_2D);
300 drawSwapper();
302 glDisable(GL_DEPTH_TEST);
304 LightManager::resetHeadLight();
306 Game::time_step = hold_time_step;
309 if (!(MetaState::mode & CM_REALLY_LOW_GRAPHICS))
310 glDisable(GL_LIGHTING);
311 glDisable(GL_COLOR_MATERIAL);
313 glEnable(GL_BLEND);
314 glEnable(GL_TEXTURE_2D);
316 drawMessage();
318 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
320 if (!(MetaState::mode & CM_REALLY_LOW_GRAPHICS)) {
321 drawWinRecord();
322 // calls glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
323 // internally
324 drawCandy();
327 drawScoreRecord();
329 glutSwapBuffers();
332 void Displayer::displayPlay ( )
334 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
336 glLoadIdentity();
338 // calls glDisable(GL_BLEND) internally
339 drawExternalCandy();
341 glDisable(GL_TEXTURE_2D);
343 if (!(MetaState::mode & CM_REALLY_LOW_GRAPHICS))
344 glEnable(GL_LIGHTING);
345 glEnable(GL_COLOR_MATERIAL);
347 if (!(MetaState::mode & CM_REALLY_LOW_GRAPHICS))
348 drawLevelLights();
350 if (!((Game::state & (GS_PAUSED | GS_SYNC_WAIT)) == GS_PAUSED)) {
352 LightManager::timeStepInitialize();
354 calculatePlayOffset();
356 glEnable(GL_DEPTH_TEST);
357 glEnable(GL_CULL_FACE);
359 LightManager::setupHeadLightPlay();
361 drawBlocks();
363 glEnable(GL_TEXTURE_2D);
365 drawGarbage();
367 glDisable(GL_CULL_FACE);
368 glDisable(GL_TEXTURE_2D);
370 drawSwapper();
372 glDisable(GL_DEPTH_TEST);
374 LightManager::resetHeadLight();
377 if (!(MetaState::mode & CM_REALLY_LOW_GRAPHICS))
378 glDisable(GL_LIGHTING);
379 glDisable(GL_COLOR_MATERIAL);
381 glEnable(GL_BLEND);
382 glEnable(GL_TEXTURE_2D);
384 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
386 if (!(MetaState::mode & CM_REALLY_LOW_GRAPHICS)) {
387 drawWinRecord();
388 // calls glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
389 // internally
390 drawCandy();
393 if (!(Game::state & GS_PAUSED))
394 drawCountDown();
395 else
396 drawMessage();
398 glutSwapBuffers();
401 bool Displayer::checkExtension ( char *extension_name )
403 char *extensions = (char *) glGetString(GL_EXTENSIONS);
405 if (!extensions) return false;
407 int length = strlen(extension_name);
408 char *end = extensions + strlen(extensions);
410 while (extensions < end) {
411 int n = strcspn(extensions, " ");
413 if (n == length && strncmp(extension_name, extensions, n) == 0)
414 return true;
416 extensions += n + 1;
419 return false;
422 #ifdef DEVELOPMENT
423 void Displayer::screenShot ( )
425 static int count = 0;
426 GLubyte *image = new GLubyte[4 * screen_length * screen_length];
428 glReadPixels(0, 0, screen_length, screen_length, GL_RGBA, GL_UNSIGNED_BYTE,
429 image);
431 ostringstream file_name;
432 file_name << DC_SCREEN_SHOT_FILE_NAME_BASE "_" << setw(GC_GARBAGE_TEX_NUMBER_DIGITS)
433 << setfill('0') << count << ".tga" << ends;
434 TextureLoader::createTGA(file_name.str().c_str(), image, screen_length, screen_length,
435 TL_SCREEN_SHOT_TGA_ID);
437 MESSAGE("creating " << file_name.str());
439 count++;
441 if (image != null) {
442 delete [] image;
443 image = null;
446 #endif