Fixes for datatype size on amd64.
[crack-attack.git] / src / Displayer.cxx
blob797a9170bf01794a6aaef987623f4e60d2d2e559
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 "Displayer.h"
31 #include <cstring>
32 #include <cctype>
33 #include <GL/glut.h>
35 //FIXME: This file may need GL/glext.h
36 #include "glext.h"
38 #ifdef DEVELOPMENT
39 #include <iomanip>
40 #include <sstream>
41 #endif
43 #include <sys/time.h>
45 #include "TextureLoader.h"
46 #include "Game.h"
47 #include "CelebrationManager.h"
48 #include "GarbageFlavorImage.h"
49 #include "SignManager.h"
50 #include "LightManager.h"
51 #include "MetaState.h"
52 #include "SparkleManager.h"
53 #include "String.h"
54 #include "ScoreRecordManager.h"
55 #include "Score.h"
57 GLenum Displayer::rescale_method;
58 bool Displayer::opengl_version_1_2;
60 int Displayer::state;
61 int Displayer::main_window;
62 GLfloat Displayer::play_offset_y;
64 #ifndef NO_MULTITEXTURING
65 # ifndef _WIN32
66 # else
67 # ifndef __MINGW32__
68 PFNGLACTIVETEXTUREARBPROC Displayer::glActiveTextureARB;
69 PFNGLCLIENTACTIVETEXTUREARBPROC Displayer::glClientActiveTextureARB;
70 # endif
71 # endif
72 #endif
74 #ifdef DEVELOPMENT
75 GLint Displayer::screen_length;
76 #endif
78 void Displayer::initialize ( int width, int height )
80 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
81 if (width != -1 && height != -1) {
82 glutInitWindowSize(width, height);
83 } else {
84 glutInitWindowSize(DC_WINDOW_PIXEL_STARTING_WIDTH,
85 DC_WINDOW_PIXEL_STARTING_HEIGHT);
87 main_window = glutCreateWindow(GC_NAME);
89 state = 0;
91 opengl_version_1_2 = false;
92 char *string = (char *) glGetString(GL_VERSION);
93 if (string[0] > '1' || (string[0] == '1' && string[2] >= '2'))
94 opengl_version_1_2 = true;
96 // determine rescaling method for normals
97 if (opengl_version_1_2)
98 rescale_method = GL_RESCALE_NORMAL;
99 else
100 rescale_method = GL_NORMALIZE;
102 #ifndef NO_MULTITEXTURING
103 // check for multitexturing
104 if (checkExtension("GL_ARB_multitexture")) {
105 GLint n;
106 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &n);
107 if (n > 1) state |= DS_MULTITEXTURING;
110 # ifndef _WIN32
111 # else
112 // locate the extension function pointers
113 if (state & DS_MULTITEXTURING) {
114 glActiveTextureARB
115 = (PFNGLACTIVETEXTUREARBPROC) wglGetProcAddress("glActiveTextureARB");
116 glClientActiveTextureARB
117 = (PFNGLCLIENTACTIVETEXTUREARBPROC) wglGetProcAddress("glClientActiveTextureARB");
119 # endif
120 #endif
121 SparkleManager::initialize();
122 SignManager::initialize();
123 LightManager::initialize();
124 GarbageFlavorImage::initialize();
125 CelebrationManager::initialize();
126 ScoreRecordManager::initialize();
128 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
130 glEnable(GL_TEXTURE_2D);
131 glEnable(GL_BLEND);
133 glEnable(GL_CLIP_PLANE_PLAY_FLOOR);
134 const GLdouble play_bottom[]
135 = { 0.0, 1.0, 0.0, DC_PLAY_HEIGHT * DC_CAMERA_HEIGHT_RATIO };
136 glClipPlane(GL_CLIP_PLANE_PLAY_FLOOR, play_bottom);
138 glEnable(GL_LIGHT0);
139 const GLfloat headlight_position[]
140 = { 0.0f, DC_HEADLIGHT_Y_OFFSET, DC_HEADLIGHT_Z_OFFSET, 1.0f };
141 glLightfv(GL_LIGHT0, GL_POSITION, headlight_position);
143 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
145 GLfloat white[] = { 1.0f, 1.0f, 1.0f, 1.0f };
146 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, white);
147 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
149 generateBlockDisplayList();
150 generateGarbageExtras();
151 generateGarbageThinMiddleList();
152 generateGarbageThinCapList();
153 generateGarbageThickCornerList();
154 generateGarbageThickEdgeList();
155 generateGarbageThickMiddleList();
156 generateGarbageSmallList();
157 generateSparkleList();
158 generateSignList();
159 generateSwapperList();
160 generateExternalCandy();
161 generateLevelLights();
162 generateClock();
163 generateMessages();
165 String::readyLetterTextures();
166 generateNameTexture();
167 generateScoreRecord();
169 glMatrixMode(GL_PROJECTION);
170 glLoadIdentity();
171 glFrustum(-(DC_PLAY_PIXEL_OFFSET_X / DC_PLAY_PIXEL_WIDTH + 0.5f)
172 * DC_PLAY_WIDTH, ((1.0f - DC_PLAY_PIXEL_OFFSET_X - DC_PLAY_PIXEL_WIDTH)
173 / DC_PLAY_PIXEL_WIDTH + 0.5f) * DC_PLAY_WIDTH, -DC_PLAY_HEIGHT
174 * DC_CAMERA_HEIGHT_RATIO, DC_PLAY_HEIGHT * (1.0 - DC_CAMERA_HEIGHT_RATIO),
175 40.0, 65.0);
176 glMatrixMode(GL_MODELVIEW);
179 void Displayer::gameStart ( )
181 LightManager::resetHeadLight();
182 ScoreRecordManager::gameStart();
185 void Displayer::gameFinish ( )
187 CelebrationManager::gameFinish();
188 ScoreRecordManager::gameFinish();
191 void Displayer::cleanUp ( )
193 for (int n = DC_NUMBER_USE_GARBAGE_TEX; n--; )
194 if (garbage_texture_data[n] != null) {
195 delete [] garbage_texture_data[n];
196 garbage_texture_data[n] = null;
198 for (int n = DC_NUMBER_MESSAGE_TEX; n--; )
199 if (message_texture_data[n] != null) {
200 delete [] message_texture_data[n];
201 message_texture_data[n] = null;
204 if (player_rank_texture_data != null) {
205 delete [] player_rank_texture_data;
206 player_rank_texture_data = null;
208 if (MetaState::mode & CM_SOLO)
209 for (int n = GC_SCORE_REC_LENGTH - 1; n--; )
210 if (record_texture_data[n] != null) {
211 delete [] record_texture_data[n];
212 record_texture_data[n] = null;
214 if (record_texture_data != null) {
215 delete [] record_texture_data;
216 record_texture_data = null;
219 String::freeLetterTextures();
222 void Displayer::reshape ( int width, int height )
224 if (DC_WINDOW_PIXEL_WIDTH * height / DC_WINDOW_PIXEL_HEIGHT != width) {
225 height = (height + width) >> 1;
226 glutReshapeWindow(DC_WINDOW_PIXEL_WIDTH * height / DC_WINDOW_PIXEL_HEIGHT,
227 height);
228 } else {
229 glViewport(0, 0, width, height);
230 #ifdef DEVELOPMENT
231 screen_length = width;
232 #endif
236 void Displayer::displayMeta ( )
238 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
240 glLoadIdentity();
242 // disables GL_BLEND internally
243 drawExternalCandy();
245 drawScoreToBeatMessage();
247 glDisable(GL_TEXTURE_2D);
249 if (!(MetaState::mode & CM_REALLY_LOW_GRAPHICS))
250 glEnable(GL_LIGHTING);
251 glEnable(GL_COLOR_MATERIAL);
253 if (!(MetaState::mode & CM_REALLY_LOW_GRAPHICS))
254 drawLevelLights();
256 if (CelebrationManager::draw_game) {
258 LightManager::timeStepInitialize();
260 int hold_time_step = Game::time_step;
261 Game::time_step = MetaState::final_time_step;
263 calculatePlayOffset();
265 glEnable(GL_DEPTH_TEST);
266 glEnable(GL_CULL_FACE);
268 LightManager::setupHeadLightMeta();
270 drawBlocks();
272 glEnable(GL_TEXTURE_2D);
274 drawGarbage();
276 glDisable(GL_CULL_FACE);
277 glDisable(GL_TEXTURE_2D);
279 drawSwapper();
281 glDisable(GL_DEPTH_TEST);
283 LightManager::resetHeadLight();
285 Game::time_step = hold_time_step;
288 if (!(MetaState::mode & CM_REALLY_LOW_GRAPHICS))
289 glDisable(GL_LIGHTING);
290 glDisable(GL_COLOR_MATERIAL);
292 glEnable(GL_BLEND);
293 glEnable(GL_TEXTURE_2D);
295 drawMessage();
297 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
299 if (!(MetaState::mode & CM_REALLY_LOW_GRAPHICS)) {
300 drawWinRecord();
301 // calls glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
302 // internally
303 drawCandy();
306 drawScoreRecord();
308 glutSwapBuffers();
311 void Displayer::displayPlay ( )
313 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
315 glLoadIdentity();
317 // calls glDisable(GL_BLEND) internally
318 drawExternalCandy();
320 glDisable(GL_TEXTURE_2D);
322 if (!(MetaState::mode & CM_REALLY_LOW_GRAPHICS))
323 glEnable(GL_LIGHTING);
324 glEnable(GL_COLOR_MATERIAL);
326 if (!(MetaState::mode & CM_REALLY_LOW_GRAPHICS))
327 drawLevelLights();
329 if (!((Game::state & (GS_PAUSED | GS_SYNC_WAIT)) == GS_PAUSED)) {
331 LightManager::timeStepInitialize();
333 calculatePlayOffset();
335 glEnable(GL_DEPTH_TEST);
336 glEnable(GL_CULL_FACE);
338 LightManager::setupHeadLightPlay();
340 drawBlocks();
342 glEnable(GL_TEXTURE_2D);
344 drawGarbage();
346 glDisable(GL_CULL_FACE);
347 glDisable(GL_TEXTURE_2D);
349 drawSwapper();
351 glDisable(GL_DEPTH_TEST);
353 LightManager::resetHeadLight();
356 if (!(MetaState::mode & CM_REALLY_LOW_GRAPHICS))
357 glDisable(GL_LIGHTING);
358 glDisable(GL_COLOR_MATERIAL);
360 glEnable(GL_BLEND);
361 glEnable(GL_TEXTURE_2D);
363 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
365 if (!(MetaState::mode & CM_REALLY_LOW_GRAPHICS)) {
366 drawWinRecord();
367 // calls glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
368 // internally
369 drawCandy();
372 if (!(Game::state & GS_PAUSED))
373 drawCountDown();
374 else
375 drawMessage();
377 glutSwapBuffers();
380 bool Displayer::checkExtension ( const char *extension_name )
382 char *extensions = (char *) glGetString(GL_EXTENSIONS);
384 if (!extensions) return false;
386 int length = strlen(extension_name);
387 char *end = extensions + strlen(extensions);
389 while (extensions < end) {
390 int n = strcspn(extensions, " ");
392 if (n == length && strncmp(extension_name, extensions, n) == 0)
393 return true;
395 extensions += n + 1;
398 return false;
401 #ifdef DEVELOPMENT
402 void Displayer::screenShot ( )
404 static int count = 0;
405 GLubyte *image = new GLubyte[4 * screen_length * screen_length];
407 glReadPixels(0, 0, screen_length, screen_length, GL_RGBA, GL_UNSIGNED_BYTE,
408 image);
410 std::ostringstream file_name;
411 file_name << DC_SCREEN_SHOT_FILE_NAME_BASE "_" << std::setw(GC_GARBAGE_TEX_NUMBER_DIGITS)
412 << std::setfill('0') << count << ".tga" << std::ends;
413 TextureLoader::createTGA(file_name.str().c_str(), image, screen_length, screen_length,
414 TL_SCREEN_SHOT_TGA_ID);
416 MESSAGE("creating " << file_name.str());
418 count++;
420 if (image != null) {
421 delete [] image;
422 image = null;
425 #endif