CarSelectScene.cpp

Go to the documentation of this file.
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

Get Racer at SourceForge.net. Fast, secure and Free Open Source software downloads

Generated at Mon Sep 6 00:41:13 2010 by Doxygen version 1.4.7 for Racer version svn335.