Removed call to glutDestroyWindow and removed linking with Xmu library.
[crack-attack.git] / src / Displayer.cxx
blob8fb4b7b265a9202e9bcd59d089d677c794b2a416
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 //FIXME: This file may need GL/glext.h
34 #include "glext.h"
36 #ifdef DEVELOPMENT
37 #include <iomanip>
38 #include "sstream.h"
39 #endif
41 #include <sys/time.h>
43 using namespace std;
45 #include "TextureLoader.h"
46 #include "Game.h"
47 #include "Displayer.h"
48 #include "CelebrationManager.h"
49 #include "GarbageFlavorImage.h"
50 #include "SignManager.h"
51 #include "LightManager.h"
52 #include "MetaState.h"
53 #include "SparkleManager.h"
54 #include "String.h"
55 #include "ScoreRecordManager.h"
56 #include "Score.h"
58 GLenum Displayer::rescale_method;
59 bool Displayer::opengl_version_1_2;
61 int Displayer::state;
62 int Displayer::main_window;
63 GLfloat Displayer::play_offset_y;
65 #ifndef NO_MULTITEXTURING
66 # ifndef _WIN32
67 # else
68 # ifndef __MINGW32__
69 PFNGLACTIVETEXTUREARBPROC Displayer::glActiveTextureARB;
70 PFNGLCLIENTACTIVETEXTUREARBPROC Displayer::glClientActiveTextureARB;
71 # endif
72 # endif
73 #endif
75 #ifdef DEVELOPMENT
76 GLint Displayer::screen_length;
77 #endif
79 void Displayer::initialize ( int width, int height )
81 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
82 if (width != -1 && height != -1) {
83 glutInitWindowSize(width, height);
84 } else {
85 glutInitWindowSize(DC_WINDOW_PIXEL_STARTING_WIDTH,
86 DC_WINDOW_PIXEL_STARTING_HEIGHT);
88 main_window = glutCreateWindow(GC_NAME);
90 state = 0;
92 opengl_version_1_2 = false;
93 char *string = (char *) glGetString(GL_VERSION);
94 if (string[0] > '1' || (string[0] == '1' && string[2] >= '2'))
95 opengl_version_1_2 = true;
97 // determine rescaling method for normals
98 if (opengl_version_1_2)
99 rescale_method = GL_RESCALE_NORMAL;
100 else
101 rescale_method = GL_NORMALIZE;
103 #ifndef NO_MULTITEXTURING
104 // check for multitexturing
105 if (checkExtension("GL_ARB_multitexture")) {
106 GLint n;
107 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &n);
108 if (n > 1) state |= DS_MULTITEXTURING;
111 # ifndef _WIN32
112 # else
113 // locate the extension function pointers
114 if (state & DS_MULTITEXTURING) {
115 glActiveTextureARB
116 = (PFNGLACTIVETEXTUREARBPROC) wglGetProcAddress("glActiveTextureARB");
117 glClientActiveTextureARB
118 = (PFNGLCLIENTACTIVETEXTUREARBPROC) wglGetProcAddress("glClientActiveTextureARB");
120 # endif
121 #endif
122 SparkleManager::initialize();
123 SignManager::initialize();
124 LightManager::initialize();
125 GarbageFlavorImage::initialize();
126 CelebrationManager::initialize();
127 ScoreRecordManager::initialize();
129 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
131 glEnable(GL_TEXTURE_2D);
132 glEnable(GL_BLEND);
134 glEnable(GL_CLIP_PLANE_PLAY_FLOOR);
135 const GLdouble play_bottom[]
136 = { 0.0, 1.0, 0.0, DC_PLAY_HEIGHT * DC_CAMERA_HEIGHT_RATIO };
137 glClipPlane(GL_CLIP_PLANE_PLAY_FLOOR, play_bottom);
139 glEnable(GL_LIGHT0);
140 const GLfloat headlight_position[]
141 = { 0.0f, DC_HEADLIGHT_Y_OFFSET, DC_HEADLIGHT_Z_OFFSET, 1.0f };
142 glLightfv(GL_LIGHT0, GL_POSITION, headlight_position);
144 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
146 GLfloat white[] = { 1.0f, 1.0f, 1.0f, 1.0f };
147 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, white);
148 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
150 generateBlockDisplayList();
151 generateGarbageExtras();
152 generateGarbageThinMiddleList();
153 generateGarbageThinCapList();
154 generateGarbageThickCornerList();
155 generateGarbageThickEdgeList();
156 generateGarbageThickMiddleList();
157 generateGarbageSmallList();
158 generateSparkleList();
159 generateSignList();
160 generateSwapperList();
161 generateExternalCandy();
162 generateLevelLights();
163 generateClock();
164 generateMessages();
166 String::readyLetterTextures();
167 generateNameTexture();
168 generateScoreRecord();
170 glMatrixMode(GL_PROJECTION);
171 glLoadIdentity();
172 glFrustum(-(DC_PLAY_PIXEL_OFFSET_X / DC_PLAY_PIXEL_WIDTH + 0.5f)
173 * DC_PLAY_WIDTH, ((1.0f - DC_PLAY_PIXEL_OFFSET_X - DC_PLAY_PIXEL_WIDTH)
174 / DC_PLAY_PIXEL_WIDTH + 0.5f) * DC_PLAY_WIDTH, -DC_PLAY_HEIGHT
175 * DC_CAMERA_HEIGHT_RATIO, DC_PLAY_HEIGHT * (1.0 - DC_CAMERA_HEIGHT_RATIO),
176 40.0, 65.0);
177 glMatrixMode(GL_MODELVIEW);
180 void Displayer::gameStart ( )
182 LightManager::resetHeadLight();
183 ScoreRecordManager::gameStart();
186 void Displayer::gameFinish ( )
188 CelebrationManager::gameFinish();
189 ScoreRecordManager::gameFinish();
192 void Displayer::cleanUp ( )
194 for (int n = DC_NUMBER_USE_GARBAGE_TEX; n--; )
195 if (garbage_texture_data[n] != null) {
196 delete [] garbage_texture_data[n];
197 garbage_texture_data[n] = null;
199 for (int n = DC_NUMBER_MESSAGE_TEX; n--; )
200 if (message_texture_data[n] != null) {
201 delete [] message_texture_data[n];
202 message_texture_data[n] = null;
205 if (player_rank_texture_data != null) {
206 delete [] player_rank_texture_data;
207 player_rank_texture_data = null;
209 if (MetaState::mode & CM_SOLO)
210 for (int n = GC_SCORE_REC_LENGTH - 1; n--; )
211 if (record_texture_data[n] != null) {
212 delete [] record_texture_data[n];
213 record_texture_data[n] = null;
215 if (record_texture_data != null) {
216 delete [] record_texture_data;
217 record_texture_data = null;
220 String::freeLetterTextures();
223 void Displayer::reshape ( int width, int height )
225 if (DC_WINDOW_PIXEL_WIDTH * height / DC_WINDOW_PIXEL_HEIGHT != width) {
226 height = (height + width) >> 1;
227 glutReshapeWindow(DC_WINDOW_PIXEL_WIDTH * height / DC_WINDOW_PIXEL_HEIGHT,
228 height);
229 } else {
230 glViewport(0, 0, width, height);
231 #ifdef DEVELOPMENT
232 screen_length = width;
233 #endif
237 void Displayer::displayMeta ( )
239 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
241 glLoadIdentity();
243 // disables GL_BLEND internally
244 drawExternalCandy();
246 drawScoreToBeatMessage();
248 glDisable(GL_TEXTURE_2D);
250 if (!(MetaState::mode & CM_REALLY_LOW_GRAPHICS))
251 glEnable(GL_LIGHTING);
252 glEnable(GL_COLOR_MATERIAL);
254 if (!(MetaState::mode & CM_REALLY_LOW_GRAPHICS))
255 drawLevelLights();
257 if (CelebrationManager::draw_game) {
259 LightManager::timeStepInitialize();
261 int hold_time_step = Game::time_step;
262 Game::time_step = MetaState::final_time_step;
264 calculatePlayOffset();
266 glEnable(GL_DEPTH_TEST);
267 glEnable(GL_CULL_FACE);
269 LightManager::setupHeadLightMeta();
271 drawBlocks();
273 glEnable(GL_TEXTURE_2D);
275 drawGarbage();
277 glDisable(GL_CULL_FACE);
278 glDisable(GL_TEXTURE_2D);
280 drawSwapper();
282 glDisable(GL_DEPTH_TEST);
284 LightManager::resetHeadLight();
286 Game::time_step = hold_time_step;
289 if (!(MetaState::mode & CM_REALLY_LOW_GRAPHICS))
290 glDisable(GL_LIGHTING);
291 glDisable(GL_COLOR_MATERIAL);
293 glEnable(GL_BLEND);
294 glEnable(GL_TEXTURE_2D);
296 drawMessage();
298 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
300 if (!(MetaState::mode & CM_REALLY_LOW_GRAPHICS)) {
301 drawWinRecord();
302 // calls glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
303 // internally
304 drawCandy();
307 drawScoreRecord();
309 glutSwapBuffers();
312 void Displayer::displayPlay ( )
314 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
316 glLoadIdentity();
318 // calls glDisable(GL_BLEND) internally
319 drawExternalCandy();
321 glDisable(GL_TEXTURE_2D);
323 if (!(MetaState::mode & CM_REALLY_LOW_GRAPHICS))
324 glEnable(GL_LIGHTING);
325 glEnable(GL_COLOR_MATERIAL);
327 if (!(MetaState::mode & CM_REALLY_LOW_GRAPHICS))
328 drawLevelLights();
330 if (!((Game::state & (GS_PAUSED | GS_SYNC_WAIT)) == GS_PAUSED)) {
332 LightManager::timeStepInitialize();
334 calculatePlayOffset();
336 glEnable(GL_DEPTH_TEST);
337 glEnable(GL_CULL_FACE);
339 LightManager::setupHeadLightPlay();
341 drawBlocks();
343 glEnable(GL_TEXTURE_2D);
345 drawGarbage();
347 glDisable(GL_CULL_FACE);
348 glDisable(GL_TEXTURE_2D);
350 drawSwapper();
352 glDisable(GL_DEPTH_TEST);
354 LightManager::resetHeadLight();
357 if (!(MetaState::mode & CM_REALLY_LOW_GRAPHICS))
358 glDisable(GL_LIGHTING);
359 glDisable(GL_COLOR_MATERIAL);
361 glEnable(GL_BLEND);
362 glEnable(GL_TEXTURE_2D);
364 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
366 if (!(MetaState::mode & CM_REALLY_LOW_GRAPHICS)) {
367 drawWinRecord();
368 // calls glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
369 // internally
370 drawCandy();
373 if (!(Game::state & GS_PAUSED))
374 drawCountDown();
375 else
376 drawMessage();
378 glutSwapBuffers();
381 bool Displayer::checkExtension ( const char *extension_name )
383 char *extensions = (char *) glGetString(GL_EXTENSIONS);
385 if (!extensions) return false;
387 int length = strlen(extension_name);
388 char *end = extensions + strlen(extensions);
390 while (extensions < end) {
391 int n = strcspn(extensions, " ");
393 if (n == length && strncmp(extension_name, extensions, n) == 0)
394 return true;
396 extensions += n + 1;
399 return false;
402 #ifdef DEVELOPMENT
403 void Displayer::screenShot ( )
405 static int count = 0;
406 GLubyte *image = new GLubyte[4 * screen_length * screen_length];
408 glReadPixels(0, 0, screen_length, screen_length, GL_RGBA, GL_UNSIGNED_BYTE,
409 image);
411 ostringstream file_name;
412 file_name << DC_SCREEN_SHOT_FILE_NAME_BASE "_" << setw(GC_GARBAGE_TEX_NUMBER_DIGITS)
413 << setfill('0') << count << ".tga" << ends;
414 TextureLoader::createTGA(file_name.str().c_str(), image, screen_length, screen_length,
415 TL_SCREEN_SHOT_TGA_ID);
417 MESSAGE("creating " << file_name.str());
419 count++;
421 if (image != null) {
422 delete [] image;
423 image = null;
426 #endif