00001 00005 /* Copyright © 2010 James Legg. 00006 This program is free software: you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation, either version 3 of the License, or 00009 (at your option) any later version. 00010 */ 00011 00012 #include "CarSelectScene.h" 00013 #include "BasicFonts.h" 00014 #include "../Graphics/Window.h" 00015 #include "../Engine/ResourceHandler.h" 00016 #include "../MainLoop.h" 00017 #include <Debug.h> 00018 00019 #include <algorithm> 00020 #include <cmath> 00021 00023 void bordered_text(const char * message) 00024 { 00025 glPushMatrix(); 00026 // border 00027 glColor3f(0.0, 0.0, 0.0); 00028 glPushMatrix(); 00029 glTranslatef(-1, -1, 0); 00030 UI::BasicFonts::get_instance().big_font.Render(message); 00031 glPopMatrix(); 00032 glPushMatrix(); 00033 glTranslatef(1, -1, 0); 00034 UI::BasicFonts::get_instance().big_font.Render(message); 00035 glPopMatrix(); 00036 glPushMatrix(); 00037 glTranslatef(1, 1, 0); 00038 UI::BasicFonts::get_instance().big_font.Render(message); 00039 glPopMatrix(); 00040 glPushMatrix(); 00041 glTranslatef(-1, 1, 0); 00042 UI::BasicFonts::get_instance().big_font.Render(message); 00043 glPopMatrix(); 00044 // main text. 00045 glColor3f(1.0, 1.0, 1.0); 00046 glPushMatrix(); 00047 UI::BasicFonts::get_instance().big_font.Render(message); 00048 glPopMatrix(); 00049 glPopMatrix(); 00050 } 00051 00052 namespace UI 00053 { 00054 00055 const unsigned int number_of_cars = 2; 00056 00057 CarSelectScene::CarSelectScene() 00058 : m_canceled(false) 00059 { 00060 // Load shared textures if not already loaded. 00062 typedef Engine::ResourceHandler<Track::Texture, std::string, std::string> TextureStore; 00063 TextureStore & tex_store = TextureStore::get_instance(); 00064 #define tex_load(bind_name, file_name, variable)\ 00065 tex_store.check_load(bind_name, file_name);\ 00066 variable = tex_store.get(bind_name);\ 00067 variable->make_cache() 00068 tex_load("select.car.ui", "data/ui/car_select.png", m_car_select_texture); 00069 tex_load("border.car.ui", "data/ui/car_border.png", m_car_border_texture); 00070 tex_load("unused.bg.car.ui", "data/ui/car_unused_background.png", m_unused_background_texture); 00071 tex_load("0.pre.car.ui", "data/cars/1/preview.png", m_car_preview_texture[0]); 00072 tex_load("1.pre.car.ui", "data/cars/2/preview.png", m_car_preview_texture[1]); 00073 #undef tex_load 00074 00075 // Record all InputDevices, which default to unused. 00076 m_selection.resize(number_of_cars + 1); 00077 btScalar a = 0; 00078 const btScalar diff = 6.283185308 / 00079 btScalar(Engine::InputHandler::get_instance().get_number_of_devices()); 00080 const btScalar t = 2.094395103; 00081 const btScalar tt = t * 2.0; 00082 for (Engine::InputHandler::iterator it = Engine::InputHandler::get_instance().begin(); 00083 it != Engine::InputHandler::get_instance().end(); 00084 it++) 00085 { 00086 a += diff; 00087 m_selection[0].insert(it); 00088 DEBUG_MESSAGE("Using hue " << a); 00089 m_device_colours[it] = 00090 btVector3(std::sin(a) * 0.5 + 0.5, 00091 std::sin(a+t) * 0.5 + 0.5, 00092 std::sin(a+tt) * 0.5 + 0.5); 00093 DEBUG_MESSAGE("Colour " << m_device_colours[it].x() << ", " 00094 << m_device_colours[it].y() << ", " 00095 << m_device_colours[it].z()); 00096 } 00097 } 00098 00099 bool CarSelectScene::get_canceled() const 00100 { 00101 return m_canceled; 00102 } 00103 00104 std::vector<std::pair<Engine::InputHandler::iterator, unsigned int> > 00105 CarSelectScene::get_choice() const 00106 { 00107 // copy device list except for the devices that aren't playing. 00108 std::vector<std::pair<Engine::InputHandler::iterator, unsigned int> > result; 00109 for (unsigned int i = 0; i < number_of_cars; i++) 00110 { 00111 for (std::set<Engine::InputHandler::iterator>::iterator it = m_selection[i+1].begin(); 00112 it != m_selection[i+1].end(); 00113 it++) 00114 { 00115 result.push_back(std::make_pair(*it, i)); 00116 } 00117 } 00118 return result; 00119 } 00120 00121 void CarSelectScene::take_input(Engine::InputReport &report) 00122 { 00123 switch (report.get_report_type()) 00124 { 00125 case Engine::InputReport::RT_MENU_DOWN: 00126 // makes device unused. 00127 remove_device(report.get_input_device()); 00128 m_selection[0].insert(report.get_input_device()); 00129 break; 00130 case Engine::InputReport::RT_MENU_UP: 00131 case Engine::InputReport::RT_MENU_LEFT: 00132 remove_device(report.get_input_device()); 00133 m_selection[1].insert(report.get_input_device()); 00134 break; 00135 case Engine::InputReport::RT_MENU_RIGHT: 00136 remove_device(report.get_input_device()); 00137 m_selection[2].insert(report.get_input_device()); 00138 break; 00139 case Engine::InputReport::RT_MENU_BACK: 00140 m_canceled = true; 00141 main_loop->pop_scene(); 00142 break; 00143 case Engine::InputReport::RT_MENU_SELECT: 00144 // At least one InputDevice needs a car assigned to continue. 00145 if (m_selection[0].size() < Engine::InputHandler::get_instance().get_number_of_devices()) 00146 { 00147 main_loop->pop_scene(); 00148 } 00149 break; 00150 default: 00151 // Other inputs ignored. 00152 break; 00153 } 00154 } 00155 00156 void CarSelectScene::update_logic(unsigned int milliseconds_elapsed) 00157 { 00158 } 00159 00160 void CarSelectScene::draw() 00161 { 00162 glClear(GL_COLOR_BUFFER_BIT); 00163 00164 Graphics::Window::get_instance().set_ortho_projection(); 00165 00166 glDisable(GL_DEPTH_TEST); 00167 glEnable(GL_TEXTURE_2D); 00168 glEnable(GL_BLEND); 00169 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 00170 glColor4f(1.0, 1.0, 1.0, 1.0); 00171 glLoadIdentity(); 00172 glTranslatef(Graphics::Window::get_instance().get_width() / 2, 00173 Graphics::Window::get_instance().get_height() / 2, 00174 0.0 ); 00175 for (unsigned int i = 0; i < number_of_cars; i++) 00176 { 00177 glPushMatrix(); 00178 glTranslatef((signed(i) - 1) * 320 + 160, 34, 0); 00179 m_car_border_texture->bind(); 00180 glBegin(GL_QUADS); 00181 glTexCoord2i(0, 1); glVertex2i(-128, -128); 00182 glTexCoord2i(1, 1); glVertex2i(127, -128); 00183 glTexCoord2i(1, 0); glVertex2i(127, 127); 00184 glTexCoord2i(0, 0); glVertex2i(-128, 127); 00185 glEnd(); 00186 m_car_preview_texture[i]->bind(); 00187 // previews have premultiplied alpha 00188 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 00189 glBegin(GL_QUADS); 00190 glTexCoord2i(0, 1); glVertex2i(-128, -128); 00191 glTexCoord2i(1, 1); glVertex2i(127, -128); 00192 glTexCoord2i(1, 0); glVertex2i(127, 127); 00193 glTexCoord2i(0, 0); glVertex2i(-128, 127); 00194 glEnd(); 00195 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 00196 glTranslatef(0, 187, 0); 00197 draw_selections(i + 1); 00198 glPopMatrix(); 00199 } 00200 00201 00202 // Text for unused cars: 00203 const char message[] = "Unused controllers"; 00204 const int width_o = BasicFonts::get_instance().big_font.Advance(message) / 2; 00205 glPushMatrix(); 00206 glTranslatef(0, -208, 0); 00207 // background 00208 m_unused_background_texture->bind(); 00209 glBegin(GL_QUADS); 00210 glColor4f(1.0, 1.0, 1.0, 0.0); 00211 glTexCoord2f(0.0, 0.0); glVertex2i(-1000, 37); 00212 glTexCoord2f(0.0, 1.0); glVertex2i(-1000, -26); 00213 glColor4f(1.0, 1.0, 1.0, 1.0); 00214 glTexCoord2f(125.0, 1.0); glVertex2i(0, -26); 00215 glTexCoord2f(125.0, 0.0); glVertex2i(0, 37); 00216 00217 glTexCoord2f(0.0, 1.0); glVertex2i(0, -26); 00218 glTexCoord2f(0.0, 0.0); glVertex2i(0, 37); 00219 glColor4f(1.0, 1.0, 1.0, 0.0); 00220 glTexCoord2f(125.0, 0.0); glVertex2i(1000, 37); 00221 glTexCoord2f(125.0, 1.0); glVertex2i(1000, -26); 00222 glEnd(); 00223 glColor4f(1.0, 1.0, 1.0, 1.0); 00224 00225 // markers for unused devices 00226 glPushMatrix(); 00227 glTranslatef(0, 95, 0); 00228 draw_selections(0); 00229 glPopMatrix(); 00230 // text 00231 glTranslatef(-width_o, 0, 0); 00232 bordered_text(message); 00233 glPopMatrix(); 00234 00235 // Heading at the top 00236 const char title[] = "Select vehicles"; 00237 const int title_width_o = BasicFonts::get_instance().big_font.Advance(title) / 2; 00238 // background: dark rectangle. 00239 glDisable(GL_TEXTURE_2D); 00240 glColor4f(0.0, 0.0, 0.0, 0.5); 00241 glTranslatef(0, 208, 0); 00242 glBegin(GL_QUADS); 00243 glVertex2i(-title_width_o-4, 23); 00244 glVertex2i(-title_width_o-4, -6); 00245 glVertex2i(title_width_o+4, -6); 00246 glVertex2i(title_width_o+4, 23); 00247 glEnd(); 00248 glColor4f(0.0, 0.0, 0.0, 1.0); 00249 glBegin(GL_LINE_LOOP); 00250 glVertex2i(-title_width_o-4, 23); 00251 glVertex2i(-title_width_o-4, -6); 00252 glVertex2i(title_width_o+4, -6); 00253 glVertex2i(title_width_o+4, 23); 00254 glEnd(); 00255 glEnable(GL_TEXTURE_2D); 00256 // Text 00257 glTranslatef(-title_width_o, 0, 0); 00258 bordered_text(title); 00259 glDisable(GL_BLEND); 00260 } 00261 00262 void CarSelectScene::draw_selections(std::size_t choice) 00263 { 00264 std::size_t size = m_selection[choice].size(); 00265 if (size == 0) return; 00266 int offset = 256 / size; 00267 m_car_select_texture->bind(); 00268 glTranslatef(offset / 2 - 128, 0, 0); 00269 glPushMatrix(); 00270 for (std::set<Engine::InputHandler::iterator>::iterator it = m_selection[choice].begin(); 00271 it != m_selection[choice].end(); 00272 it++) 00273 { 00274 glBegin(GL_QUADS); 00275 glTexCoord2f(0.5 + 1.0 / 128.0, 0.0); glVertex2i(-64, 63); 00276 glTexCoord2f(1.0, 0.0); glVertex2i(63, 63); 00277 glTexCoord2f(1.0, 1.0); glVertex2i(63, -64); 00278 glTexCoord2f(0.5 + 1.0 / 128.0, 1.0); glVertex2i(-64, -64); 00279 glEnd(); 00280 const btVector3 & c = m_device_colours[*it]; 00281 glColor3f(c.x(), c.y(), c.z()); 00282 glBlendFunc(GL_SRC_COLOR, GL_ONE); 00283 glBegin(GL_QUADS); 00284 glTexCoord2f(0.0, 0.0); glVertex2i(-64, 63); 00285 glTexCoord2f(0.5, 0.0); glVertex2i(63, 63); 00286 glTexCoord2f(0.5, 1.0); glVertex2i(63, -64); 00287 glTexCoord2f(0.0, 1.0); glVertex2i(-64, -64); 00288 glEnd(); 00289 glColor3f(1.0, 1.0, 1.0); 00290 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 00291 glTranslatef(offset, 0, 0); 00292 } 00293 glPopMatrix(); 00294 } 00295 00296 void CarSelectScene::remove_device(Engine::InputHandler::iterator device) 00297 { 00298 for (std::vector<std::set<Engine::InputHandler::iterator> >::iterator it = m_selection.begin(); 00299 it != m_selection.end(); 00300 it++) 00301 { 00302 it->erase(device); 00303 } 00304 } 00305 00306 void CarSelectScene::do_sound() 00307 { 00308 } 00309 00310 } // namespace UI
Generated at Mon Sep 6 00:41:13 2010 by Doxygen version 1.4.7 for Racer version svn335.