Fixed some inconsistent line endings caused by previous commit
git-svn-id: https://svn.code.sf.net/p/extremetuxracer/code/trunk@354 0420edf4-82e4-42fc-9478-35b55e6d67a3master
parent
2ba849018f
commit
a10cdbd9ba
3
common.h
3
common.h
|
@ -74,7 +74,8 @@ extern const TColor colSky;
|
|||
// --------------------------------------------------------------------
|
||||
// print utils
|
||||
// --------------------------------------------------------------------
|
||||
// some simple functions to print out values on the
// terminal. Only used for development.
|
||||
// some simple functions to print out values on the
|
||||
// terminal. Only used for development.
|
||||
void PrintInt (const int val);
|
||||
void PrintInt (const string& s, const int val);
|
||||
void PrintStr (const char *val);
|
||||
|
|
|
@ -14,7 +14,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
GNU General Public License for more details.
|
||||
---------------------------------------------------------------------*/
|
||||
|
||||
/*
If you want to add a new option, do this:
|
||||
/*
|
||||
If you want to add a new option, do this:
|
||||
First add the option to the TParam struct (game_config.h).
|
||||
|
||||
Then edit the below functions:
|
||||
|
@ -24,11 +25,14 @@ Then edit the below functions:
|
|||
SPStrN for strings.
|
||||
The first value is always 'line', the second defines the tag within the
|
||||
brackets [ ], and the last value is the default.
|
||||
- SetConfigDefaults. These values are used as long as no options file exists.
|
||||
|
||||
- SetConfigDefaults. These values are used as long as no options file exists.
|
||||
It's a good idea to use the same values as the defaults in LoadConfigFile.
|
||||
- SaveConfigFile. See the other entries; it should be self-explanatory.
|
||||
|
||||
- SaveConfigFile. See the other entries; it should be self-explanatory.
|
||||
If an options file exists, you will have to change any value at runtime
|
||||
on the configuration screen to overwrite the file. Then you will see the
new entry.
|
||||
on the configuration screen to overwrite the file. Then you will see the
|
||||
new entry.
|
||||
*/
|
||||
|
||||
#include "config_screen.h"
|
||||
|
@ -71,7 +75,8 @@ void RestartSDL () {
|
|||
SDL_Quit (); // SDL main
|
||||
|
||||
// second restore the freed resources
|
||||
Winsys.Init (); // includes SetVideoMode
Audio.Open (); // clear, it has been closed before
|
||||
Winsys.Init (); // includes SetVideoMode
|
||||
Audio.Open (); // clear, it has been closed before
|
||||
Sound.LoadSoundList (); // all sounds must loaded again
|
||||
Music.LoadMusicList (); // same with music pieces
|
||||
Tex.LoadTextureList (); // common textures
|
||||
|
@ -111,7 +116,8 @@ void SetConfig () {
|
|||
}
|
||||
#endif
|
||||
}
|
||||
// the followind config params don't require a new VideoMode
|
||||
|
||||
// the followind config params don't require a new VideoMode
|
||||
// they only must stored in the param structure (and saved)
|
||||
param.music_volume = mus_vol->GetValue();
|
||||
Music.SetVolume (param.music_volume);
|
||||
|
@ -135,7 +141,8 @@ void CGameConfig::Keyb (unsigned int key, bool special, bool release, int x, int
|
|||
switch (key) {
|
||||
case SDLK_q: State::manager.RequestQuit(); break;
|
||||
case 27: State::manager.RequestEnterState (*State::manager.PreviousState()); break;
|
||||
case 13:
if(textbuttons[0]->focussed())
|
||||
case 13:
|
||||
if(textbuttons[0]->focussed())
|
||||
State::manager.RequestEnterState (*State::manager.PreviousState());
|
||||
else if(textbuttons[1]->focussed())
|
||||
SetConfig ();
|
||||
|
@ -174,7 +181,8 @@ static int framewidth, frameheight;
|
|||
static int dd, rightpos;
|
||||
|
||||
void CGameConfig::Enter() {
|
||||
Winsys.ShowCursor (!param.ice_cursor);
Winsys.KeyRepeat (true);
|
||||
Winsys.ShowCursor (!param.ice_cursor);
|
||||
Winsys.KeyRepeat (true);
|
||||
|
||||
LangList = &Trans.languages[0];
|
||||
|
||||
|
@ -191,7 +199,8 @@ void CGameConfig::Enter() {
|
|||
ResetGUI ();
|
||||
fullscreen = AddCheckbox (area.left, area.top, framewidth-16, Trans.Text(31));
|
||||
fullscreen->checked = param.fullscreen;
|
||||
resolution = AddUpDown(rightpos, area.top+dd*1, 0, NUM_RESOLUTIONS-1, (int)param.res_type);
|
||||
|
||||
resolution = AddUpDown(rightpos, area.top+dd*1, 0, NUM_RESOLUTIONS-1, (int)param.res_type);
|
||||
mus_vol = AddUpDown(rightpos, area.top+dd*2, 0, 120, param.music_volume);
|
||||
sound_vol = AddUpDown(rightpos, area.top+dd*3, 0, 120, param.sound_volume);
|
||||
detail_level = AddUpDown(rightpos, area.top+dd*4, 1, 3, param.perf_level);
|
||||
|
@ -209,11 +218,15 @@ void CGameConfig::Loop (double time_step) {
|
|||
int ww = param.x_resolution;
|
||||
int hh = param.y_resolution;
|
||||
|
||||
Music.Update ();
check_gl_error();
|
||||
Music.Update ();
set_gl_options (GUI);
|
||||
Music.Update ();
|
||||
|
||||
check_gl_error();
|
||||
Music.Update ();
|
||||
set_gl_options (GUI);
|
||||
ClearRenderContext ();
|
||||
SetupGuiDisplay ();
|
||||
if (param.ui_snow) {
|
||||
|
||||
if (param.ui_snow) {
|
||||
update_ui_snow (time_step);
|
||||
draw_ui_snow();
|
||||
}
|
||||
|
@ -224,7 +237,8 @@ void CGameConfig::Loop (double time_step) {
|
|||
Tex.Draw (TOP_LEFT, 0, 0, 1);
|
||||
Tex.Draw (TOP_RIGHT, ww-256, 0, 1);
|
||||
|
||||
// DrawFrameX (area.left, area.top, area.right-area.left, area.bottom - area.top,
// 0, colMBackgr, colBlack, 0.2);
|
||||
// DrawFrameX (area.left, area.top, area.right-area.left, area.bottom - area.top,
|
||||
// 0, colMBackgr, colBlack, 0.2);
|
||||
|
||||
FT.AutoSizeN (4);
|
||||
|
||||
|
@ -259,7 +273,8 @@ void CGameConfig::Loop (double time_step) {
|
|||
FT.DrawString (CENTER, AutoYPosN (68), Trans.Text(41));
|
||||
FT.DrawString (CENTER, AutoYPosN (72), Trans.Text(42));
|
||||
}
|
||||
#else
FT.SetColor (colWhite);
|
||||
#else
|
||||
FT.SetColor (colWhite);
|
||||
FT.AutoSizeN (3);
|
||||
FT.DrawString (CENTER, AutoYPosN (68), Trans.Text(41));
|
||||
FT.DrawString (CENTER, AutoYPosN (72), Trans.Text(42));
|
||||
|
|
|
@ -32,4 +32,4 @@ public:
|
|||
|
||||
extern CGameConfig GameConfig;
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -35,8 +35,10 @@ void setup_course_tex_gen () {
|
|||
glTexGenfv (GL_T, GL_OBJECT_PLANE, zplane);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
// render course
|
||||
// --------------------------------------------------------------------
void RenderCourse () {
|
||||
// --------------------------------------------------------------------
|
||||
// render course
|
||||
// --------------------------------------------------------------------
|
||||
void RenderCourse () {
|
||||
set_gl_options (COURSE);
|
||||
setup_course_tex_gen ();
|
||||
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
|
@ -55,7 +57,7 @@ void DrawTrees() {
|
|||
TObjectType* object_types = &Course.ObjTypes[0];
|
||||
CControl* ctrl = Players.GetCtrl (g_game.player_id);
|
||||
|
||||
set_gl_options (TREES);
|
||||
set_gl_options (TREES);
|
||||
double fwd_clip_limit = param.forward_clip_distance;
|
||||
double bwd_clip_limit = param.backward_clip_distance;
|
||||
|
||||
|
@ -114,7 +116,8 @@ void DrawTrees() {
|
|||
glEnd();
|
||||
glPopMatrix();
|
||||
}
|
||||
// items -----------------------------
|
||||
|
||||
// items -----------------------------
|
||||
TItem* itemLocs = &Course.NocollArr[0];
|
||||
size_t numItems = Course.NocollArr.size();
|
||||
|
||||
|
@ -124,11 +127,13 @@ void DrawTrees() {
|
|||
if (ctrl->viewpos.z - itemLocs[i].pt.z > fwd_clip_limit) continue;
|
||||
if (itemLocs[i].pt.z - ctrl->viewpos.z > bwd_clip_limit) continue;
|
||||
}
|
||||
if (itemLocs[i].item_type != item_type) {
|
||||
|
||||
if (itemLocs[i].item_type != item_type) {
|
||||
item_type = itemLocs[i].item_type;
|
||||
object_types[item_type].texture->Bind();
|
||||
}
|
||||
glPushMatrix();
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef (itemLocs[i].pt.x, itemLocs[i].pt.y, itemLocs[i].pt.z);
|
||||
double itemRadius = itemLocs[i].diam / 2;
|
||||
double itemHeight = itemLocs[i].height;
|
||||
|
@ -155,4 +160,5 @@ void DrawTrees() {
|
|||
glVertex3f (-itemRadius*normal.z, itemHeight, itemRadius*normal.x);
|
||||
glEnd();
|
||||
glPopMatrix();
|
||||
}
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,7 +85,8 @@ static TArea area;
|
|||
static int framewidth, frameheight, frametop1, frametop2;
|
||||
|
||||
void CEventSelect::Enter () {
|
||||
Winsys.ShowCursor (!param.ice_cursor);
EventList = &Events.EventList[0];
|
||||
Winsys.ShowCursor (!param.ice_cursor);
|
||||
EventList = &Events.EventList[0];
|
||||
CupList = &Events.CupList[0];
|
||||
|
||||
framewidth = 500 * param.scale;
|
||||
|
@ -114,9 +115,11 @@ void CEventSelect::Loop (double timestep) {
|
|||
int ww = param.x_resolution;
|
||||
int hh = param.y_resolution;
|
||||
TColor col;
|
||||
check_gl_error();
|
||||
|
||||
check_gl_error();
|
||||
set_gl_options (GUI );
|
||||
Music.Update ();
ClearRenderContext ();
|
||||
Music.Update ();
|
||||
ClearRenderContext ();
|
||||
SetupGuiDisplay ();
|
||||
|
||||
if (param.ui_snow) {
|
||||
|
@ -129,7 +132,9 @@ void CEventSelect::Loop (double timestep) {
|
|||
Tex.Draw (BOTTOM_RIGHT, ww-256, hh-256, 1);
|
||||
Tex.Draw (TOP_LEFT, 0, 0, 1);
|
||||
Tex.Draw (TOP_RIGHT, ww-256, 0, 1);
|
||||
// DrawFrameX (area.left, area.top, area.right-area.left, area.bottom - area.top,
// 0, colMBackgr, colBlack, 0.2);
|
||||
|
||||
// DrawFrameX (area.left, area.top, area.right-area.left, area.bottom - area.top,
|
||||
// 0, colMBackgr, colBlack, 0.2);
|
||||
|
||||
FT.AutoSizeN (3);
|
||||
FT.SetColor (colWhite);
|
||||
|
@ -149,7 +154,8 @@ void CEventSelect::Loop (double timestep) {
|
|||
|
||||
if (cup->focussed()) col = colDYell; else col = colWhite;
|
||||
DrawFrameX (area.left, frametop2, framewidth, frameheight, 3, colMBackgr, col, 1.0);
|
||||
if (Events.IsUnlocked (event->GetValue(), cup->GetValue())) FT.SetColor (colDYell);
else FT.SetColor (colLGrey);
|
||||
if (Events.IsUnlocked (event->GetValue(), cup->GetValue())) FT.SetColor (colDYell);
|
||||
else FT.SetColor (colLGrey);
|
||||
FT.DrawString (area.left + 20, frametop2, Events.GetCupTrivialName (event->GetValue(), cup->GetValue()));
|
||||
|
||||
textbuttons[0]->SetActive(Events.IsUnlocked (event->GetValue(), cup->GetValue()));
|
||||
|
|
2
font.h
2
font.h
|
@ -71,7 +71,7 @@ public:
|
|||
// auto
|
||||
int AutoSizeN (int rel_val); // rel_val = relative size, return: autosize
|
||||
int AutoDistanceN (int rel_val); // rel_val = relative dist
|
||||
|
||||
|
||||
// draw
|
||||
void DrawText (float x, float y, const char *text) const; // normal char*
|
||||
void DrawText (float x, float y, const wchar_t *text) const; // wide char*
|
||||
|
|
106
ft_font.cpp
106
ft_font.cpp
|
@ -1,14 +1,14 @@
|
|||
/* --------------------------------------------------------------------
|
||||
Extreme Tuxracer
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
Extreme Tuxracer
|
||||
|
||||
Copyright (c) 2001-2004 Henry Maddocks (FTGL)
|
||||
Copyright (C) 2010 Extreme Tuxracer Team (modification)
|
||||
|
||||
The FTGL library from H. Maddocks is published under the terms
|
||||
of the Lesser General Publish License (LGPL). You can find a
|
||||
of the Lesser General Publish License (LGPL). You can find a
|
||||
copy of the LGPL on the gnu website:
|
||||
http://www.gnu.org/copyleft/lesser.html
|
||||
|
||||
|
||||
Hint: almost all comments are removed from the code to make it
|
||||
shorter. So all modules could put together in a single module.
|
||||
To read the comments of the author you should download the
|
||||
|
@ -59,7 +59,7 @@ bool FTFont::Attach (const unsigned char *pBufferBytes, size_t bufferSizeInBytes
|
|||
bool FTFont::FaceSize (const unsigned int size, const unsigned int res) {
|
||||
charSize = face.Size (size, res);
|
||||
err = face.Error();
|
||||
|
||||
|
||||
if (err != 0) return false;
|
||||
if (glyphList != NULL) delete glyphList;
|
||||
glyphList = new FTGlyphContainer (&face);
|
||||
|
@ -81,7 +81,7 @@ float FTFont::Ascender() const {return charSize.Ascender();}
|
|||
float FTFont::Descender() const {return charSize.Descender();}
|
||||
float FTFont::LineHeight() const {return charSize.Height();}
|
||||
|
||||
void FTFont::BBox (const char* string, float& llx, float& lly, float& llz,
|
||||
void FTFont::BBox (const char* string, float& llx, float& lly, float& llz,
|
||||
float& urx, float& ury, float& urz) {
|
||||
FTBBox totalBBox;
|
||||
|
||||
|
@ -93,7 +93,7 @@ void FTFont::BBox (const char* string, float& llx, float& lly, float& llz,
|
|||
totalBBox = glyphList->BBox (*c);
|
||||
advance = glyphList->Advance (*c, *(c + 1));
|
||||
}
|
||||
|
||||
|
||||
while (*++c) {
|
||||
if(CheckGlyph (*c)) {
|
||||
FTBBox tempBBox = glyphList->BBox (*c);
|
||||
|
@ -112,7 +112,7 @@ void FTFont::BBox (const char* string, float& llx, float& lly, float& llz,
|
|||
urz = totalBBox.upperZ;
|
||||
}
|
||||
|
||||
void FTFont::BBox (const wchar_t* string, float& llx, float& lly, float& llz,
|
||||
void FTFont::BBox (const wchar_t* string, float& llx, float& lly, float& llz,
|
||||
float& urx, float& ury, float& urz) {
|
||||
FTBBox totalBBox;
|
||||
|
||||
|
@ -124,7 +124,7 @@ void FTFont::BBox (const wchar_t* string, float& llx, float& lly, float& llz,
|
|||
totalBBox = glyphList->BBox (*c);
|
||||
advance = glyphList->Advance (*c, *(c + 1));
|
||||
}
|
||||
|
||||
|
||||
while (*++c) {
|
||||
if(CheckGlyph (*c)) {
|
||||
FTBBox tempBBox = glyphList->BBox (*c);
|
||||
|
@ -256,8 +256,8 @@ FTFace::FTFace (const unsigned char *pBufferBytes, size_t bufferSizeInBytes)
|
|||
ftFace = new FT_Face;
|
||||
|
||||
err = FT_New_Memory_Face (
|
||||
*FTLibrary::Instance().GetLibrary(),
|
||||
(FT_Byte *)pBufferBytes,
|
||||
*FTLibrary::Instance().GetLibrary(),
|
||||
(FT_Byte *)pBufferBytes,
|
||||
bufferSizeInBytes, DEFAULT_FACE_INDEX, ftFace);
|
||||
|
||||
if (err) {
|
||||
|
@ -319,7 +319,7 @@ FTPoint FTFace::KernAdvance (unsigned int index1, unsigned int index2) {
|
|||
kernAdvance.x = kernAdvance.y = 0;
|
||||
|
||||
err = FT_Get_Kerning (*ftFace, index1, index2, ft_kerning_unfitted, &kernAdvance);
|
||||
if (!err) {
|
||||
if (!err) {
|
||||
x = static_cast<float> (kernAdvance.x) / 64.0f;
|
||||
y = static_cast<float> (kernAdvance.y) / 64.0f;
|
||||
}
|
||||
|
@ -338,19 +338,19 @@ FT_GlyphSlot FTFace::Glyph (unsigned int index, FT_Int load_flags) {
|
|||
// --------------------------------------------------------------------
|
||||
|
||||
bool operator == (const FTPoint &a, const FTPoint &b) {
|
||||
return((a.values[0] == b.values[0]) && (a.values[1] ==
|
||||
return((a.values[0] == b.values[0]) && (a.values[1] ==
|
||||
b.values[1]) && (a.values[2] == b.values[2]));
|
||||
}
|
||||
|
||||
bool operator != (const FTPoint &a, const FTPoint &b) {
|
||||
return((a.values[0] != b.values[0]) || (a.values[1]
|
||||
return((a.values[0] != b.values[0]) || (a.values[1]
|
||||
!= b.values[1]) || (a.values[2] != b.values[2]));
|
||||
}
|
||||
|
||||
FTPoint operator * (double multiplier, FTPoint& point){
|
||||
return point * multiplier;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// FTSize
|
||||
// --------------------------------------------------------------------
|
||||
|
@ -366,7 +366,7 @@ FTSize::FTSize()
|
|||
|
||||
FTSize::~FTSize() {}
|
||||
|
||||
bool FTSize::CharSize (FT_Face* face, unsigned int pointSize,
|
||||
bool FTSize::CharSize (FT_Face* face, unsigned int pointSize,
|
||||
unsigned int xRes, unsigned int yRes) {
|
||||
if (size != pointSize || xResolution != xRes || yResolution != yRes) {
|
||||
err = FT_Set_Char_Size (*face, 0L, pointSize * 64, xResolution, yResolution);
|
||||
|
@ -403,17 +403,17 @@ float FTSize::Descender() const {
|
|||
float FTSize::Height() const {
|
||||
if (0 == ftSize) return 0.0f;
|
||||
if (FT_IS_SCALABLE((*ftFace))) {
|
||||
return ((*ftFace)->bbox.yMax - (*ftFace)->bbox.yMin) *
|
||||
return ((*ftFace)->bbox.yMax - (*ftFace)->bbox.yMin) *
|
||||
((float)ftSize->metrics.y_ppem / (float)(*ftFace)->units_per_EM);
|
||||
} else return static_cast<float> (ftSize->metrics.height) / 64.0f;
|
||||
}
|
||||
|
||||
float FTSize::Width() const {
|
||||
if (0 == ftSize) return 0.0f;
|
||||
|
||||
|
||||
if (FT_IS_SCALABLE((*ftFace))) {
|
||||
return ((*ftFace)->bbox.xMax - (*ftFace)->bbox.xMin) *
|
||||
(static_cast<float>(ftSize->metrics.x_ppem) /
|
||||
return ((*ftFace)->bbox.xMax - (*ftFace)->bbox.xMin) *
|
||||
(static_cast<float>(ftSize->metrics.x_ppem) /
|
||||
static_cast<float>((*ftFace)->units_per_EM));
|
||||
} else return static_cast<float> (ftSize->metrics.max_advance) / 64.0f;
|
||||
}
|
||||
|
@ -477,21 +477,21 @@ FTBBox FTGlyphContainer::BBox (const unsigned int characterCode) const {
|
|||
return glyphs[charMap->GlyphListIndex (characterCode)]->BBox();
|
||||
}
|
||||
|
||||
float FTGlyphContainer::Advance (const unsigned int characterCode,
|
||||
float FTGlyphContainer::Advance (const unsigned int characterCode,
|
||||
const unsigned int nextCharacterCode) {
|
||||
unsigned int left = charMap->FontIndex (characterCode);
|
||||
unsigned int right = charMap->FontIndex (nextCharacterCode);
|
||||
|
||||
float width = face->KernAdvance (left, right).X();
|
||||
width += glyphs[charMap->GlyphListIndex (characterCode)]->Advance().X();
|
||||
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
FTPoint FTGlyphContainer::Render (const unsigned int characterCode,
|
||||
FTPoint FTGlyphContainer::Render (const unsigned int characterCode,
|
||||
const unsigned int nextCharacterCode, FTPoint penPosition) {
|
||||
FTPoint kernAdvance, advance;
|
||||
|
||||
|
||||
unsigned int left = charMap->FontIndex (characterCode);
|
||||
unsigned int right = charMap->FontIndex (nextCharacterCode);
|
||||
|
||||
|
@ -499,7 +499,7 @@ FTPoint FTGlyphContainer::Render (const unsigned int characterCode,
|
|||
if (!face->Error()) {
|
||||
advance = glyphs[charMap->GlyphListIndex (characterCode)]->Render (penPosition);
|
||||
}
|
||||
|
||||
|
||||
kernAdvance += advance;
|
||||
return kernAdvance;
|
||||
}
|
||||
|
@ -509,8 +509,8 @@ FTPoint FTGlyphContainer::Render (const unsigned int characterCode,
|
|||
// --------------------------------------------------------------------
|
||||
|
||||
GLint FTTextureGlyph::activeTextureID = 0;
|
||||
|
||||
FTTextureGlyph::FTTextureGlyph (FT_GlyphSlot glyph, int id, int xOffset,
|
||||
|
||||
FTTextureGlyph::FTTextureGlyph (FT_GlyphSlot glyph, int id, int xOffset,
|
||||
int yOffset, GLsizei width, GLsizei height)
|
||||
: FTGlyph (glyph), destWidth(0), destHeight(0), glTextureID(id) {
|
||||
err = FT_Render_Glyph (glyph, FT_RENDER_MODE_NORMAL);
|
||||
|
@ -519,7 +519,7 @@ FTTextureGlyph::FTTextureGlyph (FT_GlyphSlot glyph, int id, int xOffset,
|
|||
FT_Bitmap bitmap = glyph->bitmap;
|
||||
destWidth = bitmap.width;
|
||||
destHeight = bitmap.rows;
|
||||
|
||||
|
||||
if (destWidth && destHeight) {
|
||||
glPushClientAttrib (GL_CLIENT_PIXEL_STORE_BIT);
|
||||
glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE);
|
||||
|
@ -527,7 +527,7 @@ FTTextureGlyph::FTTextureGlyph (FT_GlyphSlot glyph, int id, int xOffset,
|
|||
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
glBindTexture (GL_TEXTURE_2D, glTextureID);
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0, xOffset, yOffset,
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0, xOffset, yOffset,
|
||||
destWidth, destHeight, GL_ALPHA, GL_UNSIGNED_BYTE, bitmap.buffer);
|
||||
|
||||
glPopClientAttrib();
|
||||
|
@ -537,7 +537,7 @@ FTTextureGlyph::FTTextureGlyph (FT_GlyphSlot glyph, int id, int xOffset,
|
|||
uv[0].Y (static_cast<float>(yOffset) / static_cast<float>(height));
|
||||
uv[1].X (static_cast<float> (xOffset + destWidth) / static_cast<float>(width));
|
||||
uv[1].Y (static_cast<float> (yOffset + destHeight) / static_cast<float>(height));
|
||||
|
||||
|
||||
pos.X (glyph->bitmap_left);
|
||||
pos.Y (glyph->bitmap_top);
|
||||
}
|
||||
|
@ -549,7 +549,7 @@ const FTPoint& FTTextureGlyph::Render (const FTPoint& pen) {
|
|||
glBindTexture (GL_TEXTURE_2D, (GLuint)glTextureID);
|
||||
activeTextureID = glTextureID;
|
||||
}
|
||||
|
||||
|
||||
glTranslatef (pen.X(), pen.Y(), 0.0f);
|
||||
|
||||
glBegin (GL_QUADS);
|
||||
|
@ -561,7 +561,7 @@ const FTPoint& FTTextureGlyph::Render (const FTPoint& pen) {
|
|||
|
||||
glTexCoord2f (uv[1].X(), uv[1].Y());
|
||||
glVertex2f (destWidth + pos.X(), pos.Y() - destHeight);
|
||||
|
||||
|
||||
glTexCoord2f (uv[1].X(), uv[0].Y());
|
||||
glVertex2f (destWidth + pos.X(), pos.Y());
|
||||
glEnd();
|
||||
|
@ -617,16 +617,16 @@ FTGLTextureFont::~FTGLTextureFont() {
|
|||
|
||||
FTGlyph* FTGLTextureFont::MakeGlyph (unsigned int glyphIndex) {
|
||||
FT_GlyphSlot ftGlyph = face.Glyph (glyphIndex, FT_LOAD_NO_HINTING);
|
||||
|
||||
|
||||
if (ftGlyph) {
|
||||
glyphHeight = static_cast<int> (charSize.Height());
|
||||
glyphWidth = static_cast<int> (charSize.Width());
|
||||
|
||||
|
||||
if (textureIDList.empty()) {
|
||||
textureIDList.push_back (CreateTexture());
|
||||
xOffset = yOffset = padding;
|
||||
}
|
||||
|
||||
|
||||
if (xOffset > (textureWidth - glyphWidth)) {
|
||||
xOffset = padding;
|
||||
yOffset += glyphHeight;
|
||||
|
@ -635,15 +635,15 @@ FTGlyph* FTGLTextureFont::MakeGlyph (unsigned int glyphIndex) {
|
|||
yOffset = padding;
|
||||
}
|
||||
}
|
||||
|
||||
FTTextureGlyph* tempGlyph =
|
||||
|
||||
FTTextureGlyph* tempGlyph =
|
||||
new FTTextureGlyph (ftGlyph, textureIDList[textureIDList.size() - 1],
|
||||
xOffset, yOffset, textureWidth, textureHeight);
|
||||
xOffset += static_cast<int> (tempGlyph->BBox().upperX - tempGlyph->BBox().lowerX + padding);
|
||||
|
||||
|
||||
--remGlyphs;
|
||||
return tempGlyph;
|
||||
}
|
||||
}
|
||||
err = face.Error();
|
||||
return NULL;
|
||||
}
|
||||
|
@ -652,7 +652,7 @@ void FTGLTextureFont::CalculateTextureSize() {
|
|||
if (!maximumGLTextureSize) {
|
||||
glGetIntegerv (GL_MAX_TEXTURE_SIZE, (GLint*)&maximumGLTextureSize);
|
||||
}
|
||||
|
||||
|
||||
textureWidth = NextPowerOf2 ((remGlyphs * glyphWidth) + (padding * 2));
|
||||
textureWidth = textureWidth > maximumGLTextureSize ? maximumGLTextureSize : textureWidth;
|
||||
int h = static_cast<int> ((textureWidth - (padding * 2)) / glyphWidth);
|
||||
|
@ -660,9 +660,9 @@ void FTGLTextureFont::CalculateTextureSize() {
|
|||
textureHeight = textureHeight > maximumGLTextureSize ? maximumGLTextureSize : textureHeight;
|
||||
}
|
||||
|
||||
GLuint FTGLTextureFont::CreateTexture() {
|
||||
GLuint FTGLTextureFont::CreateTexture() {
|
||||
CalculateTextureSize();
|
||||
|
||||
|
||||
int totalMemory = textureWidth * textureHeight;
|
||||
unsigned char* textureMemory = new unsigned char[totalMemory];
|
||||
memset (textureMemory, 0, totalMemory);
|
||||
|
@ -676,7 +676,7 @@ GLuint FTGLTextureFont::CreateTexture() {
|
|||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, GL_ALPHA, textureWidth, textureHeight, 0,
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, GL_ALPHA, textureWidth, textureHeight, 0,
|
||||
GL_ALPHA, GL_UNSIGNED_BYTE, textureMemory);
|
||||
|
||||
delete [] textureMemory;
|
||||
|
@ -692,7 +692,7 @@ bool FTGLTextureFont::FaceSize (const unsigned int size, const unsigned int res)
|
|||
return FTFont::FaceSize (size, res);
|
||||
}
|
||||
|
||||
void FTGLTextureFont::Render (const char* string) {
|
||||
void FTGLTextureFont::Render (const char* string) {
|
||||
glPushAttrib (GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE
|
||||
|
@ -701,7 +701,7 @@ void FTGLTextureFont::Render (const char* string) {
|
|||
glPopAttrib();
|
||||
}
|
||||
|
||||
void FTGLTextureFont::Render (const wchar_t* string) {
|
||||
void FTGLTextureFont::Render (const wchar_t* string) {
|
||||
glPushAttrib (GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE
|
||||
|
@ -760,10 +760,10 @@ FTPixmapGlyph::FTPixmapGlyph( FT_GlyphSlot glyph)
|
|||
FT_Bitmap bitmap = glyph->bitmap;
|
||||
int srcWidth = bitmap.width;
|
||||
int srcHeight = bitmap.rows;
|
||||
|
||||
|
||||
destWidth = srcWidth;
|
||||
destHeight = srcHeight;
|
||||
|
||||
|
||||
if (destWidth && destHeight) {
|
||||
data = new unsigned char[destWidth * destHeight * 2];
|
||||
unsigned char* src = bitmap.buffer;
|
||||
|
@ -789,7 +789,7 @@ FTPixmapGlyph::~FTPixmapGlyph() {delete [] data;}
|
|||
|
||||
const FTPoint& FTPixmapGlyph::Render( const FTPoint& pen) {
|
||||
glBitmap( 0, 0, 0.0f, 0.0f, pen.X() + pos.X(), pen.Y() - pos.Y(), (const GLubyte*)0);
|
||||
|
||||
|
||||
if( data) {
|
||||
glPixelStorei( GL_UNPACK_ROW_LENGTH, 0);
|
||||
glPixelStorei( GL_UNPACK_ALIGNMENT, 2);
|
||||
|
@ -832,7 +832,7 @@ FTGlyph* FTGLPixmapFont::MakeGlyph( unsigned int g) {
|
|||
}
|
||||
|
||||
|
||||
void FTGLPixmapFont::Render( const char* string) {
|
||||
void FTGLPixmapFont::Render( const char* string) {
|
||||
glPushAttrib( GL_ENABLE_BIT | GL_PIXEL_MODE_BIT | GL_COLOR_BUFFER_BIT);
|
||||
glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT);
|
||||
|
||||
|
@ -856,13 +856,13 @@ void FTGLPixmapFont::Render( const char* string) {
|
|||
}
|
||||
|
||||
|
||||
void FTGLPixmapFont::Render( const wchar_t* string) {
|
||||
void FTGLPixmapFont::Render( const wchar_t* string) {
|
||||
glPushAttrib( GL_ENABLE_BIT | GL_PIXEL_MODE_BIT | GL_COLOR_BUFFER_BIT);
|
||||
glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT);
|
||||
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
|
||||
glDisable( GL_TEXTURE_2D);
|
||||
|
||||
GLfloat ftglColour[4];
|
||||
|
|
98
ft_font.h
98
ft_font.h
|
@ -1,14 +1,14 @@
|
|||
/* --------------------------------------------------------------------
|
||||
Extreme Tuxracer
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
Extreme Tuxracer
|
||||
|
||||
Copyright (c) 2001-2004 Henry Maddocks (FTGL)
|
||||
Copyright (C) 2010 Extreme Tuxracer Team (modification)
|
||||
|
||||
The FTGL library from H. Maddocks is published under the terms
|
||||
of the Lesser General Publish License (LGPL). You can find a
|
||||
of the Lesser General Publish License (LGPL). You can find a
|
||||
copy of the LGPL on the gnu website:
|
||||
http://www.gnu.org/copyleft/lesser.html
|
||||
|
||||
|
||||
Hint: almost all comments are removed from the code to make it
|
||||
shorter. So all modules could put together in a single module.
|
||||
To read the comments of the author you should download the
|
||||
|
@ -38,7 +38,7 @@ typedef double FTGL_DOUBLE;
|
|||
#define FT_RENDER_MODE_NORMAL ft_render_mode_normal
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER // MS Visual C++
|
||||
#ifdef _MSC_VER // MS Visual C++
|
||||
#pragma warning(disable : 4251 )
|
||||
#pragma warning(disable : 4275 )
|
||||
#pragma warning(disable : 4786 )
|
||||
|
@ -49,12 +49,10 @@ typedef double FTGL_DOUBLE;
|
|||
# define FTGL_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
# define FTGL_EXPORT __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#else
|
||||
#define FTGL_EXPORT
|
||||
#endif
|
||||
|
||||
#endif
|
||||
// --------------------------------------------------------------------
|
||||
// FTVector
|
||||
// --------------------------------------------------------------------
|
||||
|
@ -68,12 +66,12 @@ class FTGL_EXPORT FTVector {
|
|||
typedef value_type* iterator;
|
||||
typedef const value_type* const_iterator;
|
||||
typedef size_t size_type;
|
||||
|
||||
|
||||
FTVector() {
|
||||
Capacity = Size = 0;
|
||||
Items = 0;
|
||||
}
|
||||
|
||||
|
||||
virtual ~FTVector() {clear();}
|
||||
|
||||
FTVector &operator = (const FTVector& v) {
|
||||
|
@ -85,7 +83,7 @@ class FTGL_EXPORT FTVector {
|
|||
Size = v.size();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
size_type size() const {return Size;}
|
||||
size_type capacity() const {return Capacity;}
|
||||
iterator begin() {return Items;}
|
||||
|
@ -95,7 +93,7 @@ class FTGL_EXPORT FTVector {
|
|||
bool empty() const {return size() == 0;}
|
||||
reference operator [](size_type pos) {return(*(begin() + pos));}
|
||||
const_reference operator [](size_type pos) const {return(*(begin() + pos));}
|
||||
|
||||
|
||||
void clear() {
|
||||
if(Capacity) {
|
||||
delete [] Items;
|
||||
|
@ -118,7 +116,7 @@ class FTGL_EXPORT FTVector {
|
|||
if (n == size()) {return;}
|
||||
reserve(n);
|
||||
iterator begin, end;
|
||||
|
||||
|
||||
if(n >= Size) {
|
||||
begin = this->end();
|
||||
end = this->begin() + n;
|
||||
|
@ -126,7 +124,7 @@ class FTGL_EXPORT FTVector {
|
|||
begin = this->begin() + n;
|
||||
end = this->end();
|
||||
}
|
||||
|
||||
|
||||
while(begin != end) {*begin++ = x;}
|
||||
Size = n;
|
||||
}
|
||||
|
@ -137,7 +135,7 @@ class FTGL_EXPORT FTVector {
|
|||
if(capacity_hint) {
|
||||
while(new_capacity < capacity_hint) {new_capacity *= 2;}
|
||||
}
|
||||
|
||||
|
||||
value_type *new_items = new value_type[new_capacity];
|
||||
iterator begin = this->begin();
|
||||
iterator end = this->end();
|
||||
|
@ -187,7 +185,7 @@ class FTGL_EXPORT FTList {
|
|||
tail = node;
|
||||
++listSize;
|
||||
}
|
||||
|
||||
|
||||
reference front() const {return head->next->payload;}
|
||||
reference back() const {return tail->payload;}
|
||||
|
||||
|
@ -198,7 +196,7 @@ class FTGL_EXPORT FTList {
|
|||
Node* next;
|
||||
value_type payload;
|
||||
};
|
||||
|
||||
|
||||
size_type listSize;
|
||||
Node* head;
|
||||
Node* tail;
|
||||
|
@ -212,7 +210,7 @@ class FTGL_EXPORT FTCharToGlyphIndexMap {
|
|||
public:
|
||||
typedef unsigned long CharacterCode;
|
||||
typedef signed long GlyphIndex;
|
||||
|
||||
|
||||
enum {
|
||||
NumberOfBuckets = 256,
|
||||
BucketSize = 256,
|
||||
|
@ -226,7 +224,7 @@ class FTGL_EXPORT FTCharToGlyphIndexMap {
|
|||
this->Indices = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void clear() {
|
||||
if (this->Indices) {
|
||||
for (int i = 0; i < FTCharToGlyphIndexMap::NumberOfBuckets; i++) {
|
||||
|
@ -240,7 +238,7 @@ class FTGL_EXPORT FTCharToGlyphIndexMap {
|
|||
|
||||
const GlyphIndex find(CharacterCode c) {
|
||||
if(!this->Indices) {return 0;}
|
||||
|
||||
|
||||
div_t pos = div(c, FTCharToGlyphIndexMap::BucketSize);
|
||||
if (!this->Indices[pos.quot]) {return 0;}
|
||||
const FTCharToGlyphIndexMap::GlyphIndex *ptr = &this->Indices[pos.quot][pos.rem];
|
||||
|
@ -296,19 +294,19 @@ class FTGL_EXPORT FTPoint {
|
|||
values[1] = 0;
|
||||
values[2] = 0;
|
||||
}
|
||||
|
||||
|
||||
FTPoint(const FTGL_DOUBLE x, const FTGL_DOUBLE y, const FTGL_DOUBLE z){
|
||||
values[0] = x;
|
||||
values[1] = y;
|
||||
values[2] = z;
|
||||
}
|
||||
|
||||
|
||||
FTPoint(const FT_Vector& ft_vector) {
|
||||
values[0] = ft_vector.x;
|
||||
values[1] = ft_vector.y;
|
||||
values[2] = 0;
|
||||
}
|
||||
|
||||
|
||||
FTPoint& operator += (const FTPoint& point) {
|
||||
values[0] += point.values[0];
|
||||
values[1] += point.values[1];
|
||||
|
@ -325,7 +323,7 @@ class FTGL_EXPORT FTPoint {
|
|||
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
FTPoint operator * (double multiplier) {
|
||||
FTPoint temp;
|
||||
temp.values[0] = values[0] * multiplier;
|
||||
|
@ -334,7 +332,7 @@ class FTGL_EXPORT FTPoint {
|
|||
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
friend FTPoint operator*(double multiplier, FTPoint& point);
|
||||
friend bool operator == (const FTPoint &a, const FTPoint &b);
|
||||
friend bool operator != (const FTPoint &a, const FTPoint &b);
|
||||
|
@ -346,7 +344,7 @@ class FTGL_EXPORT FTPoint {
|
|||
FTGL_DOUBLE X() const { return values[0];};
|
||||
FTGL_DOUBLE Y() const { return values[1];};
|
||||
FTGL_DOUBLE Z() const { return values[2];};
|
||||
|
||||
|
||||
private:
|
||||
FTGL_DOUBLE values[3];
|
||||
};
|
||||
|
@ -360,7 +358,7 @@ public:
|
|||
FTSize();
|
||||
virtual ~FTSize();
|
||||
|
||||
bool CharSize(FT_Face* face, unsigned int point_size,
|
||||
bool CharSize(FT_Face* face, unsigned int point_size,
|
||||
unsigned int x_resolution, unsigned int y_resolution);
|
||||
|
||||
unsigned int CharSize() const;
|
||||
|
@ -421,7 +419,7 @@ class FTGL_EXPORT FTBBox {
|
|||
upperY(0.0f),
|
||||
upperZ(0.0f)
|
||||
{}
|
||||
|
||||
|
||||
FTBBox(float lx, float ly, float lz, float ux, float uy, float uz)
|
||||
: lowerX(lx),
|
||||
lowerY(ly),
|
||||
|
@ -430,7 +428,7 @@ class FTGL_EXPORT FTBBox {
|
|||
upperY(uy),
|
||||
upperZ(uz)
|
||||
{}
|
||||
|
||||
|
||||
FTBBox(FT_GlyphSlot glyph)
|
||||
: lowerX(0.0f),
|
||||
lowerY(0.0f),
|
||||
|
@ -447,8 +445,7 @@ class FTGL_EXPORT FTBBox {
|
|||
upperX = static_cast<float>(bbox.xMax) / 64.0f;
|
||||
upperY = static_cast<float>(bbox.yMax) / 64.0f;
|
||||
upperZ = 0.0f;
|
||||
}
|
||||
|
||||
}
|
||||
FTBBox &Move (FTPoint distance)
|
||||
{
|
||||
lowerX += distance.X();
|
||||
|
@ -462,18 +459,18 @@ class FTGL_EXPORT FTBBox {
|
|||
|
||||
~FTBBox() {}
|
||||
|
||||
FTBBox &operator += (const FTBBox& bbox)
|
||||
FTBBox &operator += (const FTBBox& bbox)
|
||||
{
|
||||
lowerX = bbox.lowerX < lowerX? bbox.lowerX: lowerX;
|
||||
lowerX = bbox.lowerX < lowerX? bbox.lowerX: lowerX;
|
||||
lowerY = bbox.lowerY < lowerY? bbox.lowerY: lowerY;
|
||||
lowerZ = bbox.lowerZ < lowerZ? bbox.lowerZ: lowerZ;
|
||||
upperX = bbox.upperX > upperX? bbox.upperX: upperX;
|
||||
upperY = bbox.upperY > upperY? bbox.upperY: upperY;
|
||||
upperZ = bbox.upperZ > upperZ? bbox.upperZ: upperZ;
|
||||
|
||||
lowerZ = bbox.lowerZ < lowerZ? bbox.lowerZ: lowerZ;
|
||||
upperX = bbox.upperX > upperX? bbox.upperX: upperX;
|
||||
upperY = bbox.upperY > upperY? bbox.upperY: upperY;
|
||||
upperZ = bbox.upperZ > upperZ? bbox.upperZ: upperZ;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void SetDepth(float depth) {upperZ = lowerZ + depth;}
|
||||
float lowerX, lowerY, lowerZ, upperX, upperY, upperZ;
|
||||
protected:
|
||||
|
@ -519,7 +516,7 @@ class FTGL_EXPORT FTCharmap {
|
|||
const FT_Face ftFace;
|
||||
typedef FTCharToGlyphIndexMap CharacterMap;
|
||||
CharacterMap charMap;
|
||||
FT_Error err;
|
||||
FT_Error err;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
@ -537,7 +534,7 @@ class FTGL_EXPORT FTGlyphContainer {
|
|||
const FTGlyph* const Glyph(const unsigned int characterCode) const;
|
||||
FTBBox BBox(const unsigned int characterCode) const;
|
||||
float Advance(const unsigned int characterCode, const unsigned int nextCharacterCode);
|
||||
FTPoint Render(const unsigned int characterCode,
|
||||
FTPoint Render(const unsigned int characterCode,
|
||||
const unsigned int nextCharacterCode, FTPoint penPosition);
|
||||
FT_Error Error() const { return err;}
|
||||
|
||||
|
@ -554,7 +551,7 @@ class FTGL_EXPORT FTGlyphContainer {
|
|||
|
||||
class FTGL_EXPORT FTTextureGlyph : public FTGlyph {
|
||||
public:
|
||||
FTTextureGlyph(FT_GlyphSlot glyph, int id, int xOffset, int yOffset,
|
||||
FTTextureGlyph(FT_GlyphSlot glyph, int id, int xOffset, int yOffset,
|
||||
GLsizei width, GLsizei height);
|
||||
virtual ~FTTextureGlyph();
|
||||
virtual const FTPoint& Render(const FTPoint& pen);
|
||||
|
@ -590,9 +587,9 @@ class FTGL_EXPORT FTFont {
|
|||
float Ascender() const;
|
||||
float Descender() const;
|
||||
float LineHeight() const;
|
||||
void BBox(const char* string, float& llx, float& lly,
|
||||
void BBox(const char* string, float& llx, float& lly,
|
||||
float& llz, float& urx, float& ury, float& urz);
|
||||
void BBox (const wchar_t* string, float& llx, float& lly,
|
||||
void BBox (const wchar_t* string, float& llx, float& lly,
|
||||
float& llz, float& urx, float& ury, float& urz);
|
||||
float Advance (const wchar_t* string);
|
||||
float Advance (const char* string);
|
||||
|
@ -606,7 +603,7 @@ class FTGL_EXPORT FTFont {
|
|||
FTSize charSize;
|
||||
bool useDisplayLists;
|
||||
FT_Error err;
|
||||
private:
|
||||
private:
|
||||
inline bool CheckGlyph(const unsigned int chr);
|
||||
FTGlyphContainer* glyphList;
|
||||
FTPoint pen;
|
||||
|
@ -652,7 +649,7 @@ class FTGL_EXPORT FTGLPixmapFont : public FTFont
|
|||
|
||||
private:
|
||||
inline virtual FTGlyph* MakeGlyph( unsigned int g);
|
||||
|
||||
|
||||
};
|
||||
|
||||
class FTGL_EXPORT FTPixmapGlyph : public FTGlyph
|
||||
|
@ -665,8 +662,7 @@ class FTGL_EXPORT FTPixmapGlyph : public FTGlyph
|
|||
int destWidth;
|
||||
int destHeight;
|
||||
FTPoint pos;
|
||||
unsigned char* data;
|
||||
unsigned char* data;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -296,7 +296,8 @@ void CPlayers::LoadAvatars () {
|
|||
avatars.back().filename = filename;
|
||||
avatars.back().texture = texture;
|
||||
AvatarIndex[filename] = avatars.size()-1;
|
||||
} else
delete texture;
|
||||
} else
|
||||
delete texture;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,8 @@ static TVector2 cursor_pos(0, 0);
|
|||
static TTextButton* textbuttons[7];
|
||||
|
||||
void EnterPractice () {
|
||||
g_game.game_type = PRACTICING;
State::manager.RequestEnterState (RaceSelect);
|
||||
g_game.game_type = PRACTICING;
|
||||
State::manager.RequestEnterState (RaceSelect);
|
||||
}
|
||||
|
||||
void QuitGameType () {
|
||||
|
@ -69,12 +70,14 @@ void CGameTypeSelect::Keyb (unsigned int key, bool special, bool release, int x,
|
|||
|
||||
KeyGUI(key, 0, release);
|
||||
switch (key) {
|
||||
case SDLK_u: param.ui_snow = !param.ui_snow; break;
case 27: State::manager.RequestQuit(); break;
|
||||
case SDLK_u: param.ui_snow = !param.ui_snow; break;
|
||||
case 27: State::manager.RequestQuit(); break;
|
||||
case 274: IncreaseFocus(); break;
|
||||
case 273: DecreaseFocus(); break;
|
||||
case 13: QuitGameType(); break;
|
||||
case SDLK_w: Music.FreeMusics(); break;
|
||||
}
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGameTypeSelect::Motion (int x, int y) {
|
||||
MouseMoveGUI(x, y);
|
||||
|
@ -113,10 +116,12 @@ void CGameTypeSelect::Loop (double time_step) {
|
|||
int hh = param.y_resolution;
|
||||
|
||||
check_gl_error();
|
||||
Music.Update ();
set_gl_options (GUI);
|
||||
Music.Update ();
|
||||
set_gl_options (GUI);
|
||||
ClearRenderContext ();
|
||||
SetupGuiDisplay ();
|
||||
if (param.ui_snow) {
|
||||
|
||||
if (param.ui_snow) {
|
||||
update_ui_snow (time_step);
|
||||
draw_ui_snow();
|
||||
}
|
||||
|
|
21
hud.cpp
21
hud.cpp
|
@ -103,14 +103,17 @@ TVector2 calc_new_fan_pt (double angle) {
|
|||
|
||||
void start_tri_fan() {
|
||||
glBegin (GL_TRIANGLE_FAN);
|
||||
glVertex2f (ENERGY_GAUGE_CENTER_X,
ENERGY_GAUGE_CENTER_Y);
|
||||
TVector2 pt = calc_new_fan_pt (SPEEDBAR_BASE_ANGLE);
glVertex2f (pt.x, pt.y);
|
||||
glVertex2f (ENERGY_GAUGE_CENTER_X,
|
||||
ENERGY_GAUGE_CENTER_Y);
|
||||
TVector2 pt = calc_new_fan_pt (SPEEDBAR_BASE_ANGLE);
|
||||
glVertex2f (pt.x, pt.y);
|
||||
}
|
||||
|
||||
void draw_partial_tri_fan (double fraction) {
|
||||
bool trifan = false;
|
||||
|
||||
double angle = SPEEDBAR_BASE_ANGLE +
(SPEEDBAR_MAX_ANGLE - SPEEDBAR_BASE_ANGLE) * fraction;
|
||||
double angle = SPEEDBAR_BASE_ANGLE +
|
||||
(SPEEDBAR_MAX_ANGLE - SPEEDBAR_BASE_ANGLE) * fraction;
|
||||
|
||||
int divs = (int)((SPEEDBAR_BASE_ANGLE - angle) * CIRCLE_DIVISIONS / 360.0);
|
||||
double cur_angle = SPEEDBAR_BASE_ANGLE;
|
||||
|
@ -181,7 +184,8 @@ void draw_gauge (double speed, double energy) {
|
|||
|
||||
if (speed > SPEEDBAR_GREEN_MAX_SPEED) {
|
||||
speedbar_frac = SPEEDBAR_GREEN_FRACTION;
|
||||
if (speed > SPEEDBAR_YELLOW_MAX_SPEED) {
|
||||
|
||||
if (speed > SPEEDBAR_YELLOW_MAX_SPEED) {
|
||||
speedbar_frac += SPEEDBAR_YELLOW_FRACTION;
|
||||
if (speed > SPEEDBAR_RED_MAX_SPEED) {
|
||||
speedbar_frac += SPEEDBAR_RED_FRACTION;
|
||||
|
@ -192,7 +196,8 @@ void draw_gauge (double speed, double energy) {
|
|||
} else {
|
||||
speedbar_frac += (speed - SPEEDBAR_GREEN_MAX_SPEED) /
|
||||
(SPEEDBAR_YELLOW_MAX_SPEED - SPEEDBAR_GREEN_MAX_SPEED) * SPEEDBAR_YELLOW_FRACTION;
|
||||
}
} else {
|
||||
}
|
||||
} else {
|
||||
speedbar_frac += speed/SPEEDBAR_GREEN_MAX_SPEED * SPEEDBAR_GREEN_FRACTION;
|
||||
}
|
||||
|
||||
|
@ -216,7 +221,8 @@ void draw_gauge (double speed, double energy) {
|
|||
void DrawSpeed (double speed) {
|
||||
string speedstr = Int_StrN ((int)speed, 3);
|
||||
if (param.use_papercut_font < 2) {
|
||||
Tex.DrawNumStr (speedstr.c_str(),
param.x_resolution - 85, param.y_resolution-74, 1, colWhite);
|
||||
Tex.DrawNumStr (speedstr.c_str(),
|
||||
param.x_resolution - 85, param.y_resolution-74, 1, colWhite);
|
||||
} else {
|
||||
FT.SetColor (colDDYell);
|
||||
FT.DrawString (param.x_resolution-82, param.y_resolution-80, speedstr);
|
||||
|
@ -227,7 +233,8 @@ void DrawWind (double dir, double speed) {
|
|||
Tex.Draw (SPEEDMETER, 10, param.y_resolution - 150, 1.0);
|
||||
glPushMatrix ();
|
||||
glDisable (GL_TEXTURE_2D );
|
||||
glColor4f (1, 0, 0, 0.5);
|
||||
|
||||
glColor4f (1, 0, 0, 0.5);
|
||||
glTranslatef (82, 77, 0);
|
||||
glRotatef (dir, 0, 0, 1);
|
||||
glBegin (GL_QUADS);
|
||||
|
|
16
intro.cpp
16
intro.cpp
|
@ -62,7 +62,8 @@ void CIntro::Enter() {
|
|||
g_game.herring = 0;
|
||||
g_game.score = 0;
|
||||
g_game.time = 0.0;
|
||||
g_game.race_result = -1;
g_game.raceaborted = false;
|
||||
g_game.race_result = -1;
|
||||
g_game.raceaborted = false;
|
||||
|
||||
ctrl->Init ();
|
||||
|
||||
|
@ -71,7 +72,7 @@ void CIntro::Enter() {
|
|||
set_view_mode (ctrl, ABOVE);
|
||||
SetCameraDistance (4.0);
|
||||
SetStationaryCamera (false);
|
||||
update_view (ctrl, EPS);
|
||||
update_view (ctrl, EPS);
|
||||
size_t num_items = Course.NocollArr.size();
|
||||
TItem* item_locs = &Course.NocollArr[0];
|
||||
for (size_t i = 0; i < num_items; i++) {
|
||||
|
@ -82,7 +83,8 @@ void CIntro::Enter() {
|
|||
|
||||
InitSnow (ctrl);
|
||||
InitWind ();
|
||||
Music.PlayTheme (g_game.theme_id, MUS_RACING);
|
||||
|
||||
Music.PlayTheme (g_game.theme_id, MUS_RACING);
|
||||
param.show_hud = true;
|
||||
g_game.loopdelay = 1;
|
||||
}
|
||||
|
@ -103,14 +105,16 @@ void CIntro::Loop (double time_step) {
|
|||
update_view (ctrl, time_step);
|
||||
SetupViewFrustum (ctrl);
|
||||
|
||||
Music.Update ();
Env.DrawSkybox (ctrl->viewpos);
|
||||
Music.Update ();
|
||||
Env.DrawSkybox (ctrl->viewpos);
|
||||
|
||||
Env.DrawFog ();
|
||||
Env.SetupLight ();
|
||||
RenderCourse ();
|
||||
DrawTrackmarks ();
|
||||
DrawTrees ();
|
||||
UpdateWind (time_step, ctrl);
|
||||
|
||||
UpdateWind (time_step, ctrl);
|
||||
UpdateSnow (time_step, ctrl);
|
||||
DrawSnow (ctrl);
|
||||
|
||||
|
@ -120,7 +124,7 @@ void CIntro::Loop (double time_step) {
|
|||
Reshape (width, height);
|
||||
Winsys.SwapBuffers ();
|
||||
|
||||
}
|
||||
}
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
void CIntro::Keyb (unsigned int key, bool special, bool release, int x, int y) {
|
||||
|
|
6
main.cpp
6
main.cpp
|
@ -81,7 +81,8 @@ int main( int argc, char **argv ) {
|
|||
// written on the console):
|
||||
// Winsys.PrintJoystickInfo ();
|
||||
// PrintGLInfo ();
|
||||
// theses resources must or should be loaded before splashscreen starts
|
||||
|
||||
// theses resources must or should be loaded before splashscreen starts
|
||||
Tex.LoadTextureList ();
|
||||
FT.LoadFontlist ();
|
||||
Winsys.SetFonttype ();
|
||||
|
@ -92,7 +93,8 @@ int main( int argc, char **argv ) {
|
|||
switch (g_game.argument) {
|
||||
case 0: State::manager.Run(SplashScreen); break;
|
||||
case 4:
|
||||
g_game.toolmode = TUXSHAPE;
State::manager.Run(Tools);
|
||||
g_game.toolmode = TUXSHAPE;
|
||||
State::manager.Run(Tools);
|
||||
break;
|
||||
case 9: State::manager.Run(OglTest); break;
|
||||
}
|
||||
|
|
|
@ -43,7 +43,8 @@ void QuitAndAddPlayer () {
|
|||
|
||||
void CNewPlayer::Keyb_spec (SDL_keysym sym, bool release) {
|
||||
if (release) return;
|
||||
KeyGUI(sym.sym, sym.mod, release);
|
||||
|
||||
KeyGUI(sym.sym, sym.mod, release);
|
||||
switch (sym.sym) {
|
||||
case 27: State::manager.RequestEnterState (Regist); break;
|
||||
case 13:
|
||||
|
|
44
ogl.cpp
44
ogl.cpp
|
@ -55,8 +55,7 @@ void init_glfloat_array (int num, GLfloat arr[], ...) {
|
|||
PFNGLLOCKARRAYSEXTPROC glLockArraysEXT_p = NULL;
|
||||
PFNGLUNLOCKARRAYSEXTPROC glUnlockArraysEXT_p = NULL;
|
||||
|
||||
typedef void (*(*get_gl_proc_fptr_t)(const GLubyte *))();
|
||||
|
||||
typedef void (*(*get_gl_proc_fptr_t)(const GLubyte *))();
|
||||
void InitOpenglExtensions () {
|
||||
get_gl_proc_fptr_t get_gl_proc;
|
||||
|
||||
|
@ -69,13 +68,13 @@ void InitOpenglExtensions () {
|
|||
#endif
|
||||
|
||||
if (get_gl_proc) {
|
||||
glLockArraysEXT_p = (PFNGLLOCKARRAYSEXTPROC)
|
||||
glLockArraysEXT_p = (PFNGLLOCKARRAYSEXTPROC)
|
||||
(*get_gl_proc)((GLubyte*) "glLockArraysEXT");
|
||||
glUnlockArraysEXT_p = (PFNGLUNLOCKARRAYSEXTPROC)
|
||||
glUnlockArraysEXT_p = (PFNGLUNLOCKARRAYSEXTPROC)
|
||||
(*get_gl_proc)((GLubyte*) "glUnlockArraysEXT");
|
||||
|
||||
|
||||
if (glLockArraysEXT_p != NULL && glUnlockArraysEXT_p != NULL) {
|
||||
|
||||
|
||||
} else {
|
||||
Message ("GL_EXT_compiled_vertex_array extension NOT supported", "");
|
||||
glLockArraysEXT_p = NULL;
|
||||
|
@ -144,7 +143,7 @@ void set_material (const TColor& diffuse_colour, const TColor& specular_colour,
|
|||
mat_amb_diff[0] = diffuse_colour.r;
|
||||
mat_amb_diff[1] = diffuse_colour.g;
|
||||
mat_amb_diff[2] = diffuse_colour.b;
|
||||
mat_amb_diff[3] = diffuse_colour.a;
|
||||
mat_amb_diff[3] = diffuse_colour.a;
|
||||
glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_amb_diff);
|
||||
|
||||
mat_specular[0] = specular_colour.r;
|
||||
|
@ -155,10 +154,9 @@ void set_material (const TColor& diffuse_colour, const TColor& specular_colour,
|
|||
|
||||
glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, specular_exp);
|
||||
|
||||
glColor4f (diffuse_colour.r, diffuse_colour.g, diffuse_colour.b,
|
||||
glColor4f (diffuse_colour.r, diffuse_colour.g, diffuse_colour.b,
|
||||
diffuse_colour.a);
|
||||
}
|
||||
|
||||
}
|
||||
void ClearRenderContext () {
|
||||
glDepthMask (GL_TRUE);
|
||||
glClearColor (colBackgr.r, colBackgr.g, colBackgr.b, colBackgr.a);
|
||||
|
@ -193,13 +191,12 @@ void Reshape (int w, int h) {
|
|||
far_clip_dist = param.forward_clip_distance + FAR_CLIP_FUDGE_AMOUNT;
|
||||
gluPerspective (param.fov, (double)w/h, NEAR_CLIP_DIST, far_clip_dist );
|
||||
glMatrixMode (GL_MODELVIEW );
|
||||
}
|
||||
|
||||
}
|
||||
// ====================================================================
|
||||
// GL options
|
||||
// ====================================================================
|
||||
|
||||
void set_gl_options (TRenderMode mode)
|
||||
void set_gl_options (TRenderMode mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case GUI:
|
||||
|
@ -219,7 +216,7 @@ void set_gl_options (TRenderMode mode)
|
|||
glDepthFunc (GL_LESS);
|
||||
glDisable (GL_FOG);
|
||||
break;
|
||||
|
||||
|
||||
case GAUGE_BARS:
|
||||
glEnable (GL_TEXTURE_2D);
|
||||
glDisable (GL_DEPTH_TEST);
|
||||
|
@ -256,7 +253,7 @@ void set_gl_options (TRenderMode mode)
|
|||
glShadeModel (GL_SMOOTH);
|
||||
glDepthFunc (GL_LESS);
|
||||
break;
|
||||
|
||||
|
||||
case COURSE:
|
||||
glEnable (GL_TEXTURE_2D);
|
||||
glEnable (GL_DEPTH_TEST);
|
||||
|
@ -295,7 +292,7 @@ void set_gl_options (TRenderMode mode)
|
|||
|
||||
glAlphaFunc (GL_GEQUAL, 0.5);
|
||||
break;
|
||||
|
||||
|
||||
case PARTICLES:
|
||||
glEnable (GL_TEXTURE_2D);
|
||||
glEnable (GL_DEPTH_TEST);
|
||||
|
@ -314,11 +311,11 @@ void set_gl_options (TRenderMode mode)
|
|||
|
||||
glAlphaFunc (GL_GEQUAL, 0.5);
|
||||
break;
|
||||
|
||||
|
||||
case SKY:
|
||||
glEnable (GL_TEXTURE_2D);
|
||||
glDisable (GL_DEPTH_TEST);
|
||||
glDisable (GL_CULL_FACE);
|
||||
glDisable (GL_CULL_FACE);
|
||||
glDisable (GL_LIGHTING);
|
||||
glDisable (GL_NORMALIZE);
|
||||
glDisable (GL_ALPHA_TEST);
|
||||
|
@ -331,11 +328,11 @@ void set_gl_options (TRenderMode mode)
|
|||
glShadeModel (GL_SMOOTH);
|
||||
glDepthFunc (GL_LESS);
|
||||
break;
|
||||
|
||||
|
||||
case FOG_PLANE:
|
||||
glDisable (GL_TEXTURE_2D);
|
||||
glEnable (GL_DEPTH_TEST);
|
||||
glDisable (GL_CULL_FACE);
|
||||
glDisable (GL_CULL_FACE);
|
||||
glDisable (GL_LIGHTING);
|
||||
glDisable (GL_NORMALIZE);
|
||||
glDisable (GL_ALPHA_TEST);
|
||||
|
@ -415,12 +412,11 @@ void set_gl_options (TRenderMode mode)
|
|||
glShadeModel (GL_SMOOTH);
|
||||
glDepthFunc (GL_LEQUAL);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
Message ("not a valid render mode", "");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
/* defined but not used
|
||||
case TEXT:
|
||||
glDisable (GL_TEXTURE_2D);
|
||||
|
|
2
ogl.h
2
ogl.h
|
@ -48,7 +48,7 @@ void init_glfloat_array( int num, GLfloat arr[], ... );
|
|||
void InitOpenglExtensions();
|
||||
void PrintGLInfo();
|
||||
|
||||
void set_material (const TColor& diffuse_colour,
|
||||
void set_material (const TColor& diffuse_colour,
|
||||
const TColor& specular_colour,
|
||||
double specular_exp );
|
||||
|
||||
|
|
12
ogl_test.cpp
12
ogl_test.cpp
|
@ -24,12 +24,17 @@ GNU General Public License for more details.
|
|||
|
||||
COglTest OglTest;
|
||||
|
||||
static const float tedef_amb[] = {0.45, 0.53, 0.75, 1.0};
static const float tedef_diff[] = {1.0, 0.9, 1.0, 1.0};
static const float tedef_spec[] = {0.6, 0.6, 0.6, 1.0};
static const float tedef_pos[] = {1, 2, 2, 0.0};
static TLight testlight;
|
||||
static const float tedef_amb[] = {0.45, 0.53, 0.75, 1.0};
|
||||
static const float tedef_diff[] = {1.0, 0.9, 1.0, 1.0};
|
||||
static const float tedef_spec[] = {0.6, 0.6, 0.6, 1.0};
|
||||
static const float tedef_pos[] = {1, 2, 2, 0.0};
|
||||
static TLight testlight;
|
||||
|
||||
|
||||
void InitTestLight () {
|
||||
testlight.is_on = true;
|
||||
for (int i=0; i<4; i++) {
testlight.ambient[i] = tedef_amb[i];
|
||||
for (int i=0; i<4; i++) {
|
||||
testlight.ambient[i] = tedef_amb[i];
|
||||
testlight.diffuse[i] = tedef_diff[i];
|
||||
testlight.specular[i] = tedef_spec[i];
|
||||
testlight.position[i] = tedef_pos[i];
|
||||
|
@ -71,7 +76,8 @@ void COglTest::Loop(double timestep) {
|
|||
SetTestLight ();
|
||||
|
||||
/*
|
||||
glTranslatef (xposition, yposition, zposition);
glRotatef (xrotation, 1, 0, 0);
|
||||
glTranslatef (xposition, yposition, zposition);
|
||||
glRotatef (xrotation, 1, 0, 0);
|
||||
glRotatef (yrotation, 0, 1, 0);
|
||||
glRotatef (zrotation, 0, 0, 1);
|
||||
*/
|
||||
|
|
203
particles.cpp
203
particles.cpp
|
@ -32,14 +32,18 @@ GNU General Public License for more details.
|
|||
|
||||
#define MAX_num_snowparticles 4000
|
||||
#define BASE_num_snowparticles 1000
|
||||
#define GRAVITY_FACTOR 0.015
#define BASE_VELOCITY 0.05
|
||||
#define GRAVITY_FACTOR 0.015
|
||||
#define BASE_VELOCITY 0.05
|
||||
#define VELOCITY_RANGE 0.02
|
||||
#define PUSH_DECAY_TIME_CONSTANT 0.2
|
||||
#define PUSH_DIST_DECAY 100
#define PUSH_FACTOR 0.5
|
||||
#define PUSH_DIST_DECAY 100
|
||||
#define PUSH_FACTOR 0.5
|
||||
#define MAX_PUSH_FORCE 5
|
||||
#define AIR_DRAG 0.4
|
||||
|
||||
#define PARTICLE_MIN_SIZE 1
#define PARTICLE_SIZE_RANGE 10
|
||||
#define PARTICLE_MIN_SIZE 1
|
||||
#define PARTICLE_SIZE_RANGE 10
|
||||
|
||||
struct TGuiParticle {
|
||||
TVector2 pt;
|
||||
double size;
|
||||
|
@ -69,7 +73,8 @@ TGuiParticle::TGuiParticle(double x, double y) {
|
|||
size = PARTICLE_MIN_SIZE + (1.0 - p_dist) * PARTICLE_SIZE_RANGE;
|
||||
vel.x = 0;
|
||||
vel.y = -BASE_VELOCITY - p_dist * VELOCITY_RANGE;
|
||||
int type = (int) (frand() * (4.0 - EPS));
|
||||
|
||||
int type = (int) (frand() * (4.0 - EPS));
|
||||
if (type == 0) {
|
||||
tex_min = TVector2(0.0, 0.0);
|
||||
tex_max = TVector2(0.5, 0.5);
|
||||
|
@ -107,11 +112,14 @@ void TGuiParticle::Update(double time_step, double push_timestep, const TVector2
|
|||
double dist_from_push = (pow((pt.x - push_position.x), 2) +
|
||||
pow((pt.y - push_position.y), 2));
|
||||
if (push_timestep > 0) {
|
||||
f.x = PUSH_FACTOR * push_vector.x / push_timestep;
f.y = PUSH_FACTOR * push_vector.y / push_timestep;
f.x = MIN (MAX_PUSH_FORCE, f.x);
|
||||
f.x = PUSH_FACTOR * push_vector.x / push_timestep;
|
||||
f.y = PUSH_FACTOR * push_vector.y / push_timestep;
|
||||
f.x = MIN (MAX_PUSH_FORCE, f.x);
|
||||
f.x = MAX (-MAX_PUSH_FORCE, f.x);
|
||||
f.y = MIN (MAX_PUSH_FORCE, f.y);
|
||||
f.y = MAX (-MAX_PUSH_FORCE, f.y);
|
||||
f.x *= 1.0/(PUSH_DIST_DECAY*dist_from_push + 1) *
size/PARTICLE_SIZE_RANGE;
|
||||
f.x *= 1.0/(PUSH_DIST_DECAY*dist_from_push + 1) *
|
||||
size/PARTICLE_SIZE_RANGE;
|
||||
f.y *= 1.0/(PUSH_DIST_DECAY*dist_from_push + 1) *
|
||||
size/PARTICLE_SIZE_RANGE;
|
||||
}
|
||||
|
@ -119,7 +127,8 @@ void TGuiParticle::Update(double time_step, double push_timestep, const TVector2
|
|||
vel.x += (f.x - vel.x * AIR_DRAG) * time_step;
|
||||
vel.y += (f.y - GRAVITY_FACTOR - vel.y * AIR_DRAG) * time_step;
|
||||
|
||||
pt.x += vel.x * time_step * (size / PARTICLE_SIZE_RANGE);
pt.y += vel.y * time_step * (size / PARTICLE_SIZE_RANGE);
|
||||
pt.x += vel.x * time_step * (size / PARTICLE_SIZE_RANGE);
|
||||
pt.y += vel.y * time_step * (size / PARTICLE_SIZE_RANGE);
|
||||
|
||||
if (pt.x < 0) {
|
||||
pt.x = 1;
|
||||
|
@ -136,18 +145,21 @@ void init_ui_snow () {
|
|||
|
||||
void update_ui_snow (double time_step) {
|
||||
double time = Winsys.ClockTime ();
|
||||
TVector2 push_vector;
|
||||
|
||||
TVector2 push_vector;
|
||||
push_vector.x = 0;
|
||||
push_vector.y = 0;
|
||||
double push_timestep = 0;
|
||||
if (push_position_initialized) {
|
||||
|
||||
if (push_position_initialized) {
|
||||
push_vector.x = push_position.x - last_push_position.x;
|
||||
push_vector.y = push_position.y - last_push_position.y;
|
||||
push_timestep = time - last_update_time;
|
||||
}
|
||||
last_push_position = push_position;
|
||||
last_update_time = time;
|
||||
for (list<TGuiParticle>::iterator p = particles_2d.begin(); p != particles_2d.end(); ++p) {
|
||||
|
||||
for (list<TGuiParticle>::iterator p = particles_2d.begin(); p != particles_2d.end(); ++p) {
|
||||
p->Update(time_step, push_timestep, push_vector);
|
||||
}
|
||||
|
||||
|
@ -179,14 +191,16 @@ void update_ui_snow (double time_step) {
|
|||
push_vector.x = 0.0;
|
||||
push_vector.y = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
void draw_ui_snow () {
|
||||
double xres = param.x_resolution;
|
||||
double yres = param.y_resolution;
|
||||
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
|
||||
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
Tex.BindTex (SNOW_PART);
|
||||
glColor4f(part_col[0], part_col[1], part_col[2], part_col[3]);
|
||||
part_col[3] = 0.3;
for (list<TGuiParticle>::const_iterator i = particles_2d.begin(); i != particles_2d.end(); ++i) {
|
||||
part_col[3] = 0.3;
|
||||
for (list<TGuiParticle>::const_iterator i = particles_2d.begin(); i != particles_2d.end(); ++i) {
|
||||
i->Draw(xres, yres);
|
||||
}
|
||||
}
|
||||
|
@ -258,7 +272,9 @@ void Particle::Draw(CControl* ctrl) const {
|
|||
}
|
||||
|
||||
TColor particle_colour = Env.ParticleColor ();
|
||||
glColor4f (particle_colour.r,
particle_colour.g,
particle_colour.b,
|
||||
glColor4f (particle_colour.r,
|
||||
particle_colour.g,
|
||||
particle_colour.b,
|
||||
particle_colour.a * alpha);
|
||||
|
||||
draw_billboard (ctrl, cur_size, cur_size, false, min_tex_coord, max_tex_coord);
|
||||
|
@ -314,7 +330,7 @@ void create_new_particles (const TVector3& loc, TVector3 vel, int num) {
|
|||
|
||||
if (particles.size() + num > MAX_PARTICLES) {
|
||||
Message ("maximum number of particles exceeded", "");
|
||||
}
|
||||
}
|
||||
for (int i=0; i<num; i++) {
|
||||
particles.push_back(Particle());
|
||||
Particle* newp = &particles.back();
|
||||
|
@ -328,10 +344,11 @@ void create_new_particles (const TVector3& loc, TVector3 vel, int num) {
|
|||
newp->death = frand() * MAX_AGE;
|
||||
newp->vel = AddVectors (
|
||||
ScaleVector (speed, vel),
|
||||
TVector3(VARIANCE_FACTOR * (frand() - 0.5) * speed,
VARIANCE_FACTOR * (frand() - 0.5) * speed,
|
||||
TVector3(VARIANCE_FACTOR * (frand() - 0.5) * speed,
|
||||
VARIANCE_FACTOR * (frand() - 0.5) * speed,
|
||||
VARIANCE_FACTOR * (frand() - 0.5) * speed ));
|
||||
}
|
||||
}
|
||||
}
|
||||
void update_particles (double time_step) {
|
||||
for(list<Particle>::iterator p = particles.begin(); p != particles.end();) {
|
||||
p->age += time_step;
|
||||
|
@ -342,16 +359,18 @@ void update_particles (double time_step) {
|
|||
|
||||
p->pt = AddVectors (p->pt, ScaleVector (time_step, p->vel));
|
||||
double ycoord = Course.FindYCoord (p->pt.x, p->pt.z);
|
||||
if (p->pt.y < ycoord - 3) {p->age = p->death + 1;}
if (p->age >= p->death) {
|
||||
if (p->pt.y < ycoord - 3) {p->age = p->death + 1;}
|
||||
if (p->age >= p->death) {
|
||||
p = particles.erase(p);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
p->alpha = (p->death - p->age) / p->death;
|
||||
p->cur_size = NEW_PART_SIZE +
(OLD_PART_SIZE - NEW_PART_SIZE) * (p->age / p->death);
|
||||
p->cur_size = NEW_PART_SIZE +
|
||||
(OLD_PART_SIZE - NEW_PART_SIZE) * (p->age / p->death);
|
||||
p->vel.y += -EARTH_GRAV * time_step;
|
||||
++p;
|
||||
}
|
||||
}
|
||||
}
|
||||
void draw_particles (CControl *ctrl) {
|
||||
set_gl_options (PARTICLES);
|
||||
Tex.BindTex (SNOW_PART);
|
||||
|
@ -363,7 +382,7 @@ void draw_particles (CControl *ctrl) {
|
|||
if (p->age >= 0)
|
||||
p->Draw(ctrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
void clear_particles() {
|
||||
particles.clear();
|
||||
}
|
||||
|
@ -393,23 +412,31 @@ void generate_particles (CControl *ctrl, double dtime, const TVector3& pos, doub
|
|||
right_part_pt = left_part_pt = pos;
|
||||
|
||||
right_part_pt = AddVectors (
|
||||
right_part_pt,
ScaleVector (TUX_WIDTH/2.0, xvec));
|
||||
right_part_pt,
|
||||
ScaleVector (TUX_WIDTH/2.0, xvec));
|
||||
|
||||
left_part_pt = AddVectors (
|
||||
left_part_pt,
ScaleVector (-TUX_WIDTH/2.0, xvec));
|
||||
left_part_pt,
|
||||
ScaleVector (-TUX_WIDTH/2.0, xvec));
|
||||
|
||||
right_part_pt.y = left_part_pt.y = surf_y;
|
||||
|
||||
brake_particles = dtime *
|
||||
BRAKE_PARTICLES * (ctrl->is_braking ? 1.0 : 0.0)
|
||||
* min (speed / PARTICLE_SPEED_FACTOR, 1.0);
|
||||
turn_particles = dtime * MAX_TURN_PARTICLES
* min (speed / PARTICLE_SPEED_FACTOR, 1.0);
|
||||
roll_particles = dtime * MAX_ROLL_PARTICLES
* min (speed / PARTICLE_SPEED_FACTOR, 1.0);
|
||||
turn_particles = dtime * MAX_TURN_PARTICLES
|
||||
* min (speed / PARTICLE_SPEED_FACTOR, 1.0);
|
||||
roll_particles = dtime * MAX_ROLL_PARTICLES
|
||||
* min (speed / PARTICLE_SPEED_FACTOR, 1.0);
|
||||
|
||||
left_particles = turn_particles *
fabs (min(ctrl->turn_fact, 0.)) +
brake_particles +
|
||||
left_particles = turn_particles *
|
||||
fabs (min(ctrl->turn_fact, 0.)) +
|
||||
brake_particles +
|
||||
roll_particles * fabs (min(ctrl->turn_animation, 0.));
|
||||
|
||||
right_particles = turn_particles *
fabs (max(ctrl->turn_fact, 0.)) +
brake_particles +
|
||||
right_particles = turn_particles *
|
||||
fabs (max(ctrl->turn_fact, 0.)) +
|
||||
brake_particles +
|
||||
roll_particles * fabs (max(ctrl->turn_animation, 0.));
|
||||
|
||||
left_particles = adjust_particle_count (left_particles);
|
||||
|
@ -417,21 +444,27 @@ void generate_particles (CControl *ctrl, double dtime, const TVector3& pos, doub
|
|||
|
||||
RotateAboutVectorMatrix(
|
||||
rot_mat, ctrl->cdirection,
|
||||
MAX (-MAX_PARTICLE_ANGLE,
-MAX_PARTICLE_ANGLE * speed / MAX_PARTICLE_ANGLE_SPEED));
|
||||
MAX (-MAX_PARTICLE_ANGLE,
|
||||
-MAX_PARTICLE_ANGLE * speed / MAX_PARTICLE_ANGLE_SPEED));
|
||||
TVector3 left_part_vel = TransformVector (rot_mat, ctrl->plane_nml);
|
||||
left_part_vel = ScaleVector (MIN (MAX_PARTICLE_SPEED,
speed * PARTICLE_SPEED_MULTIPLIER),left_part_vel);
|
||||
left_part_vel = ScaleVector (MIN (MAX_PARTICLE_SPEED,
|
||||
speed * PARTICLE_SPEED_MULTIPLIER),left_part_vel);
|
||||
|
||||
RotateAboutVectorMatrix(
|
||||
rot_mat, ctrl->cdirection,
|
||||
MIN (MAX_PARTICLE_ANGLE,
MAX_PARTICLE_ANGLE * speed / MAX_PARTICLE_ANGLE_SPEED));
|
||||
MIN (MAX_PARTICLE_ANGLE,
|
||||
MAX_PARTICLE_ANGLE * speed / MAX_PARTICLE_ANGLE_SPEED));
|
||||
TVector3 right_part_vel = TransformVector (rot_mat, ctrl->plane_nml);
|
||||
right_part_vel = ScaleVector (MIN (MAX_PARTICLE_SPEED,
|
||||
speed * PARTICLE_SPEED_MULTIPLIER),right_part_vel);
|
||||
|
||||
|
||||
create_new_particles (left_part_pt, left_part_vel,
(int)left_particles);
|
||||
create_new_particles (right_part_pt, right_part_vel,
(int)right_particles);
|
||||
}
}
|
||||
create_new_particles (left_part_pt, left_part_vel,
|
||||
(int)left_particles);
|
||||
create_new_particles (right_part_pt, right_part_vel,
|
||||
(int)right_particles);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// snow flakes
|
||||
|
@ -463,7 +496,8 @@ void TFlake::Draw(const TPlane& lp, const TPlane& rp, bool rotate_flake, float d
|
|||
|
||||
|
||||
TFlakeArea::TFlakeArea (
|
||||
int num_flakes,
float _xrange,
|
||||
int num_flakes,
|
||||
float _xrange,
|
||||
float _ytop,
|
||||
float _yrange,
|
||||
float _zback,
|
||||
|
@ -494,12 +528,14 @@ void TFlakeArea::Draw (CControl *ctrl) const {
|
|||
|
||||
set_gl_options (PARTICLES);
|
||||
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
Tex.BindTex (T_WIDGETS);
TColor particle_colour = Env.ParticleColor ();
|
||||
Tex.BindTex (T_WIDGETS);
|
||||
TColor particle_colour = Env.ParticleColor ();
|
||||
glColor4f (particle_colour.r, particle_colour.g, particle_colour.b, particle_colour.a);
|
||||
|
||||
for (size_t i=0; i < flakes.size(); i++) {
|
||||
flakes[i].Draw(lp, rp, rotate_flake, dir_angle);
|
||||
}
}
|
||||
}
|
||||
}
|
||||
|
||||
void TFlakeArea::Update(float timestep, float xcoeff, float ycoeff, float zcoeff) {
|
||||
for (size_t i=0; i<flakes.size(); i++) {
|
||||
|
@ -528,14 +564,17 @@ void CFlakes::Reset () {
|
|||
}
|
||||
|
||||
void CFlakes::MakeSnowFlake (size_t ar, size_t i) {
|
||||
areas[ar].flakes[i].pt.x = XRandom (areas[ar].left, areas[ar].right);
areas[ar].flakes[i].pt.y = -XRandom (areas[ar].top, areas[ar].bottom);
|
||||
areas[ar].flakes[i].pt.x = XRandom (areas[ar].left, areas[ar].right);
|
||||
areas[ar].flakes[i].pt.y = -XRandom (areas[ar].top, areas[ar].bottom);
|
||||
areas[ar].flakes[i].pt.z = areas[ar].back - FRandom () * (areas[ar].back - areas[ar].front);
|
||||
|
||||
float p_dist = FRandom ();
|
||||
areas[ar].flakes[i].size = XRandom (areas[ar].minSize, areas[ar].maxSize);
|
||||
areas[ar].flakes[i].vel.x = 0;
|
||||
areas[ar].flakes[i].vel.z = 0;
|
||||
areas[ar].flakes[i].vel.y = -areas[ar].flakes[i].size * areas[ar].speed;
int type = (int) (FRandom () * 3.9999);
|
||||
areas[ar].flakes[i].vel.y = -areas[ar].flakes[i].size * areas[ar].speed;
|
||||
|
||||
int type = (int) (FRandom () * 3.9999);
|
||||
|
||||
if (type == 0) {
|
||||
areas[ar].flakes[i].tex_min = TVector2(0.0, 0.875);
|
||||
|
@ -567,7 +606,8 @@ void CFlakes::UpdateAreas (CControl *ctrl) {
|
|||
areas[ar].back = ctrl->cpos.z - areas[ar].zback;
|
||||
areas[ar].front = areas[ar].back - areas[ar].zrange;
|
||||
areas[ar].top = ctrl->cpos.y + areas[ar].ytop;
|
||||
areas[ar].bottom = areas[ar].top - areas[ar].yrange;
}
|
||||
areas[ar].bottom = areas[ar].top - areas[ar].yrange;
|
||||
}
|
||||
}
|
||||
|
||||
#define YDRIFT 0.8
|
||||
|
@ -609,7 +649,8 @@ void CFlakes::Init (int grade, CControl *ctrl) {
|
|||
// areas.push_back(TFlakeArea(800, 12, 5, 9, 2, 8, 0.12, 0.20, 5, false));
|
||||
// areas.push_back(TFlakeArea(800, 30, 6, 15, 10, 15, 0.25, 0.5, 5, false));
|
||||
break;
|
||||
default: break;
}
|
||||
default: break;
|
||||
}
|
||||
|
||||
UpdateAreas (ctrl);
|
||||
GenerateSnowFlakes (ctrl);
|
||||
|
@ -629,7 +670,8 @@ void CFlakes::Update (double timestep, CControl *ctrl) {
|
|||
|
||||
TVector3 winddrift = ScaleVector (SNOW_WIND_DRIFT, Wind.WindDrift ());
|
||||
float xcoeff = winddrift.x * timestep;
|
||||
float ycoeff = (ydiff * YDRIFT) + (winddrift.z * timestep);
float zcoeff = (zdiff * ZDRIFT) + (winddrift.z * timestep);
|
||||
float ycoeff = (ydiff * YDRIFT) + (winddrift.z * timestep);
|
||||
float zcoeff = (zdiff * ZDRIFT) + (winddrift.z * timestep);
|
||||
|
||||
for (size_t ar=0; ar<areas.size(); ar++) {
|
||||
areas[ar].Update(timestep, xcoeff, ycoeff, zcoeff);
|
||||
|
@ -723,7 +765,8 @@ void TCurtain::SetStartParams(CControl* ctrl) {
|
|||
}
|
||||
|
||||
void TCurtain::Draw() const {
|
||||
Tex.BindTex (texture);
float halfsize = size / 2;
|
||||
Tex.BindTex (texture);
|
||||
float halfsize = size / 2;
|
||||
for (unsigned int co=0; co<numCols; co++) {
|
||||
for (unsigned int row=0; row<numRows; row++) {
|
||||
const TVector3* pt = &curtains[co][row].pt;
|
||||
|
@ -768,7 +811,7 @@ void TCurtain::Update(float timestep, const TVector3& drift, CControl* ctrl) {
|
|||
}
|
||||
|
||||
|
||||
static CCurtain Curtain;
|
||||
static CCurtain Curtain;
|
||||
void TCurtain::CurtainVec (float angle, float zdist, float &x, float &z) {
|
||||
x = zdist * sin (angle * 3.14159 / 180);
|
||||
if (angle > 90 || angle < -90) z = sqrt (zdist * zdist - x * x);
|
||||
|
@ -814,7 +857,8 @@ void CCurtain::Init (CControl *ctrl) {
|
|||
Reset ();
|
||||
InitChanges ();
|
||||
switch (g_game.snow_id) {
|
||||
case 1:
// curtains.push_back(TCurtain(3, 60, 10, 3, -100, -10, 1));
|
||||
case 1:
|
||||
// curtains.push_back(TCurtain(3, 60, 10, 3, -100, -10, 1));
|
||||
// curtains.push_back(TCurtain(3, 50, 13, 3, -100, -10, 1));
|
||||
// curtains.push_back(TCurtain(3, 40, 16, 3, -100, -10, 1));
|
||||
curtains.push_back(TCurtain(3, 60, 15, 3, -100, -10, 1));
|
||||
|
@ -824,7 +868,8 @@ void CCurtain::Init (CControl *ctrl) {
|
|||
// curtains.push_back(TCurtain(3, 50, 25, 3, -100, -10, 1));
|
||||
// curtains.push_back(TCurtain(3, 40, 30, 3, -100, -10, 1));
|
||||
break;
|
||||
case 2:
// curtains.push_back(TCurtain(3, 60, 15, 3, -100, -10, 2));
|
||||
case 2:
|
||||
// curtains.push_back(TCurtain(3, 60, 15, 3, -100, -10, 2));
|
||||
// curtains.push_back(TCurtain(3, 50, 17, 3, -100, -10, 2));
|
||||
// curtains.push_back(TCurtain(3, 40, 20, 3, -100, -10, 2));
|
||||
curtains.push_back(TCurtain(3, 60, 22, 3, -100, -10, 2));
|
||||
|
@ -864,7 +909,8 @@ CWind::CWind ()
|
|||
{
|
||||
windy = false;
|
||||
CurrTime = 0.0;
|
||||
SpeedMode = 0;
|
||||
|
||||
SpeedMode = 0;
|
||||
AngleMode = 0;
|
||||
WSpeed = 0;
|
||||
WAngle = 0;
|
||||
|
@ -875,21 +921,27 @@ CWind::CWind ()
|
|||
}
|
||||
|
||||
void CWind::SetParams (int grade) {
|
||||
float min_base_speed = 0;
float max_base_speed = 0;
|
||||
float min_base_speed = 0;
|
||||
float max_base_speed = 0;
|
||||
float min_speed_var = 0;
|
||||
float max_speed_var = 0;
|
||||
float min_base_angle = 0;
float max_base_angle = 0;
float min_angle_var = 0;
|
||||
float min_base_angle = 0;
|
||||
float max_base_angle = 0;
|
||||
float min_angle_var = 0;
|
||||
float max_angle_var = 0;
|
||||
float alt_angle = 0;
|
||||
|
||||
if (grade == 0) {
|
||||
min_base_speed = 20;
max_base_speed = 35;
|
||||
min_base_speed = 20;
|
||||
max_base_speed = 35;
|
||||
min_speed_var = 20;
|
||||
max_speed_var = 20;
|
||||
params.minChange = 0.1;
|
||||
params.maxChange = 0.3;
|
||||
|
||||
min_base_angle = 70;
max_base_angle = 110;
min_angle_var = 0;
|
||||
min_base_angle = 70;
|
||||
max_base_angle = 110;
|
||||
min_angle_var = 0;
|
||||
max_angle_var = 90;
|
||||
params.minAngleChange = 0.1;
|
||||
params.maxAngleChange = 1.0;
|
||||
|
@ -899,13 +951,16 @@ void CWind::SetParams (int grade) {
|
|||
params.nullProbability = 6;
|
||||
alt_angle = 180;
|
||||
} else if (grade == 1) {
|
||||
min_base_speed = 30;
max_base_speed = 60;
|
||||
min_base_speed = 30;
|
||||
max_base_speed = 60;
|
||||
min_speed_var = 40;
|
||||
max_speed_var = 40;
|
||||
params.minChange = 0.1;
|
||||
params.maxChange = 0.5;
|
||||
|
||||
min_base_angle = 70;
max_base_angle = 110;
min_angle_var = 0;
|
||||
min_base_angle = 70;
|
||||
max_base_angle = 110;
|
||||
min_angle_var = 0;
|
||||
max_angle_var = 90;
|
||||
params.minAngleChange = 0.1;
|
||||
params.maxAngleChange = 1.0;
|
||||
|
@ -915,13 +970,16 @@ void CWind::SetParams (int grade) {
|
|||
params.nullProbability = 10;
|
||||
alt_angle = 180;
|
||||
} else {
|
||||
min_base_speed = 40;
max_base_speed = 80;
|
||||
min_base_speed = 40;
|
||||
max_base_speed = 80;
|
||||
min_speed_var = 30;
|
||||
max_speed_var = 60;
|
||||
params.minChange = 0.1;
|
||||
params.maxChange = 1.0;
|
||||
|
||||
min_base_angle = 0;
max_base_angle = 180;
min_angle_var = 180;
|
||||
min_base_angle = 0;
|
||||
max_base_angle = 180;
|
||||
min_angle_var = 180;
|
||||
max_angle_var = 360;
|
||||
params.minAngleChange = 0.1;
|
||||
params.maxAngleChange = 1.0;
|
||||
|
@ -934,18 +992,22 @@ void CWind::SetParams (int grade) {
|
|||
|
||||
float speed, var, angle;
|
||||
|
||||
speed = XRandom (min_base_speed, max_base_speed);
var = XRandom (min_speed_var, max_speed_var) / 2;
|
||||
speed = XRandom (min_base_speed, max_base_speed);
|
||||
var = XRandom (min_speed_var, max_speed_var) / 2;
|
||||
params.minSpeed = speed - var;
|
||||
params.maxSpeed = speed + var;
|
||||
if (params.minSpeed < 0) params.minSpeed = 0;
|
||||
if (params.maxSpeed > 100) params.maxSpeed = 100;
|
||||
|
||||
angle = XRandom (min_base_angle, max_base_angle);
if (XRandom (0, 100) > 50) angle = angle + alt_angle;
var = XRandom (min_angle_var, max_angle_var) / 2;
|
||||
angle = XRandom (min_base_angle, max_base_angle);
|
||||
if (XRandom (0, 100) > 50) angle = angle + alt_angle;
|
||||
var = XRandom (min_angle_var, max_angle_var) / 2;
|
||||
params.minAngle = angle - var;
|
||||
params.maxAngle = angle + var;
|
||||
}
|
||||
|
||||
void CWind::CalcDestSpeed () {
float rand = XRandom (0, 100);
|
||||
void CWind::CalcDestSpeed () {
|
||||
float rand = XRandom (0, 100);
|
||||
if (rand > (100 - params.topProbability)) {
|
||||
DestSpeed = XRandom (params.maxSpeed, params.topSpeed);
|
||||
WindChange = params.maxChange;
|
||||
|
@ -966,20 +1028,30 @@ void CWind::CalcDestAngle () {
|
|||
|
||||
if (DestAngle > WAngle) AngleMode = 1; else AngleMode = 0;
|
||||
}
|
||||
|
||||
|
||||
void CWind::Update (float timestep) {
|
||||
float xx, zz;
|
||||
if (!windy) return;
// the wind needn't be updated in each frame
|
||||
|
||||
if (!windy) return;
|
||||
// the wind needn't be updated in each frame
|
||||
CurrTime = CurrTime + timestep;
|
||||
if (CurrTime > UPDATE_TIME) {
|
||||
CurrTime = 0.0;
|
||||
if (SpeedMode == 1) { // current speed lesser than destination speed
|
||||
|
||||
if (SpeedMode == 1) { // current speed lesser than destination speed
|
||||
if (WSpeed < DestSpeed) {
|
||||
WSpeed = WSpeed + WindChange;
} else CalcDestSpeed ();
} else {
|
||||
WSpeed = WSpeed + WindChange;
|
||||
} else CalcDestSpeed ();
|
||||
} else {
|
||||
if (WSpeed > DestSpeed) {
|
||||
WSpeed = WSpeed - WindChange;
} else CalcDestSpeed ();
}
if (WSpeed > params.topSpeed) WSpeed = params.topSpeed;
|
||||
WSpeed = WSpeed - WindChange;
|
||||
} else CalcDestSpeed ();
|
||||
}
|
||||
if (WSpeed > params.topSpeed) WSpeed = params.topSpeed;
|
||||
if (WSpeed < 0) WSpeed = 0;
|
||||
if (AngleMode == 1) {
|
||||
|
||||
|
||||
if (AngleMode == 1) {
|
||||
if (WAngle < DestAngle) {
|
||||
WAngle = WAngle + AngleChange;
|
||||
} else CalcDestAngle ();
|
||||
|
@ -990,7 +1062,8 @@ void CWind::Update (float timestep) {
|
|||
}
|
||||
if (WAngle > params.maxAngle) WAngle = params.maxAngle;
|
||||
if (WAngle < params.minAngle) WAngle = params.minAngle;
|
||||
xx = sin (WAngle * 3.14159 / 180);
|
||||
|
||||
xx = sin (WAngle * 3.14159 / 180);
|
||||
zz = sqrt (1 - xx * xx);
|
||||
if ((WAngle > 90 && WAngle < 270) || (WAngle > 450 && WAngle < 630)) {
|
||||
zz = -zz;
|
||||
|
|
|
@ -64,7 +64,7 @@ struct TFlakeArea {
|
|||
float maxSize;
|
||||
float speed;
|
||||
bool rotate_flake;
|
||||
|
||||
|
||||
float left;
|
||||
float right;
|
||||
float bottom;
|
||||
|
@ -75,7 +75,7 @@ struct TFlakeArea {
|
|||
vector<TFlake> flakes;
|
||||
|
||||
TFlakeArea(
|
||||
int num_flakes,
|
||||
int num_flakes,
|
||||
float xrange,
|
||||
float ytop,
|
||||
float yrange,
|
||||
|
@ -136,7 +136,7 @@ struct TCurtain {
|
|||
float lastangle;
|
||||
float minheight;
|
||||
int texture;
|
||||
|
||||
|
||||
TCurtain(
|
||||
int num_rows,
|
||||
float z_dist,
|
||||
|
|
|
@ -84,7 +84,8 @@ void CPaused::Loop (double time_step) {
|
|||
if (terr) RenderCourse();
|
||||
DrawTrackmarks ();
|
||||
DrawTrees();
|
||||
UpdateWind (time_step, ctrl);
|
||||
|
||||
UpdateWind (time_step, ctrl);
|
||||
UpdateSnow (time_step, ctrl);
|
||||
DrawSnow (ctrl);
|
||||
|
||||
|
@ -97,4 +98,4 @@ void CPaused::Loop (double time_step) {
|
|||
DrawHud (ctrl);
|
||||
Reshape (width, height);
|
||||
Winsys.SwapBuffers ();
|
||||
}
|
||||
}
|
||||
|
|
125
physics.cpp
125
physics.cpp
|
@ -45,12 +45,12 @@ CControl::CControl () :
|
|||
roll_right = false;
|
||||
roll_factor = 0;
|
||||
flip_factor = 0;
|
||||
|
||||
|
||||
ode_time_step = -1;
|
||||
jump_start_time = 0;
|
||||
begin_jump = false;
|
||||
paddle_time = 0;
|
||||
view_init = false;
|
||||
view_init = false;
|
||||
finish_speed = 0;
|
||||
}
|
||||
|
||||
|
@ -89,23 +89,22 @@ void CControl::Init () {
|
|||
roll_right = false;
|
||||
roll_factor = 0;
|
||||
flip_factor = 0;
|
||||
|
||||
ode_time_step = -1;
|
||||
}
|
||||
|
||||
ode_time_step = -1;
|
||||
}
|
||||
// --------------------------------------------------------------------
|
||||
// collision
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
bool CControl::CheckTreeCollisions (const TVector3& pos, TVector3 *tree_loc, double *tree_diam){
|
||||
CCharShape *shape = Char.GetShape (g_game.char_id);
|
||||
double diam = 0.0;
|
||||
double diam = 0.0;
|
||||
double height;
|
||||
TVector3 loc(0, 0, 0);
|
||||
bool hit = false;
|
||||
TMatrix mat;
|
||||
|
||||
// These variables are used to cache collision detection results
|
||||
|
||||
// These variables are used to cache collision detection results
|
||||
static bool last_collision = false;
|
||||
static TVector3 last_collision_tree_loc(-999, -999, -999);
|
||||
static double last_collision_tree_diam = 0;
|
||||
|
@ -136,7 +135,7 @@ bool CControl::CheckTreeCollisions (const TVector3& pos, TVector3 *tree_loc, dou
|
|||
squared_dist *= squared_dist;
|
||||
if (MAG_SQD(distvec) > squared_dist) continue;
|
||||
|
||||
// have to look at polyhedron - switch to correct one if necessary
|
||||
// have to look at polyhedron - switch to correct one if necessary
|
||||
if (tree_type != trees[i].tree_type) {
|
||||
tree_type = trees[i].tree_type;
|
||||
ph = Course.GetPoly (tree_type);
|
||||
|
@ -147,8 +146,8 @@ bool CControl::CheckTreeCollisions (const TVector3& pos, TVector3 *tree_loc, dou
|
|||
TransPolyhedron (mat, ph2);
|
||||
MakeTranslationMatrix (mat, loc.x, loc.y, loc.z);
|
||||
TransPolyhedron (mat, ph2);
|
||||
// hit = TuxCollision2 (pos, ph2);
|
||||
hit = shape->Collision (pos, ph2);
|
||||
// hit = TuxCollision2 (pos, ph2);
|
||||
hit = shape->Collision (pos, ph2);
|
||||
FreePolyhedron (ph2);
|
||||
|
||||
if (hit == true) {
|
||||
|
@ -156,7 +155,7 @@ bool CControl::CheckTreeCollisions (const TVector3& pos, TVector3 *tree_loc, dou
|
|||
if (tree_diam != NULL) *tree_diam = diam;
|
||||
Sound.Play ("tree_hit", 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
last_collision_tree_loc = loc;
|
||||
|
@ -166,18 +165,17 @@ bool CControl::CheckTreeCollisions (const TVector3& pos, TVector3 *tree_loc, dou
|
|||
if (hit) last_collision = true;
|
||||
else last_collision = false;
|
||||
return hit;
|
||||
}
|
||||
|
||||
}
|
||||
void CControl::AdjustTreeCollision (const TVector3& pos, TVector3 *vel){
|
||||
TVector3 treeNml;
|
||||
TVector3 treeLoc;
|
||||
double tree_diam;
|
||||
double factor;
|
||||
|
||||
|
||||
if (CheckTreeCollisions (pos, &treeLoc, &tree_diam)) {
|
||||
treeNml.x = pos.x - treeLoc.x;
|
||||
treeNml.y = 0;
|
||||
treeNml.z = pos.z - treeLoc.z;
|
||||
treeNml.z = pos.z - treeLoc.z;
|
||||
NormVector (treeNml);
|
||||
|
||||
double speed = NormVector (*vel);
|
||||
|
@ -190,10 +188,10 @@ void CControl::AdjustTreeCollision (const TVector3& pos, TVector3 *vel){
|
|||
//ScaleVector (-2 * DotProduct (*vel, treeNml), treeNml), *vel);
|
||||
ScaleVector (-factor * costheta, treeNml), *vel);
|
||||
NormVector (*vel);
|
||||
}
|
||||
}
|
||||
speed = max (speed, minSpeed);
|
||||
*vel = ScaleVector (speed, *vel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CControl::CheckItemCollection (const TVector3& pos) {
|
||||
|
@ -226,9 +224,8 @@ void CControl::CheckItemCollection (const TVector3& pos) {
|
|||
Sound.Play ("pickup2", 0);
|
||||
Sound.Play ("pickup3", 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// --------------------------------------------------------------------
|
||||
// position and velocity ***
|
||||
// --------------------------------------------------------------------
|
||||
|
@ -261,8 +258,7 @@ void CControl::SetTuxPosition (double speed) {
|
|||
|
||||
Course.GetPlayDimensions (&playWidth, &playLength);
|
||||
Course.GetDimensions (&courseWidth, &courseLength);
|
||||
double boundaryWidth = (courseWidth - playWidth) / 2;
|
||||
|
||||
double boundaryWidth = (courseWidth - playWidth) / 2;
|
||||
if (cpos.x < boundaryWidth) cpos.x = boundaryWidth;
|
||||
if (cpos.x > courseWidth - boundaryWidth) cpos.x = courseWidth - boundaryWidth;
|
||||
if (cpos.z > 0) cpos.z = 0;
|
||||
|
@ -275,14 +271,13 @@ void CControl::SetTuxPosition (double speed) {
|
|||
finish_speed = speed;
|
||||
// SetStationaryCamera (true);
|
||||
} else State::manager.RequestEnterState (GameOver);
|
||||
}
|
||||
}
|
||||
/// -----------------------------------------------------------
|
||||
}
|
||||
double disp_y = cpos.y + TUX_Y_CORR;
|
||||
double disp_y = cpos.y + TUX_Y_CORR;
|
||||
shape->ResetNode (0);
|
||||
shape->TranslateNode (0, TVector3 (cpos.x, disp_y, cpos.z));
|
||||
}
|
||||
|
||||
shape->TranslateNode (0, TVector3 (cpos.x, disp_y, cpos.z));
|
||||
}
|
||||
// --------------------------------------------------------------------
|
||||
// forces ***
|
||||
// --------------------------------------------------------------------
|
||||
|
@ -298,7 +293,7 @@ TVector3 CControl::CalcRollNormal (double speed) {
|
|||
MIN (1.0, MAX (0.0, ff.frict_coeff) / IDEAL_ROLL_FRIC) *
|
||||
MIN (1.0, MAX (0.0, speed - minSpeed) / (IDEAL_ROLL_SPEED - minSpeed));
|
||||
|
||||
TMatrix rot_mat;
|
||||
TMatrix rot_mat;
|
||||
RotateAboutVectorMatrix (rot_mat, vel, angle);
|
||||
return TransformVector (rot_mat, ff.surfnml);
|
||||
}
|
||||
|
@ -310,9 +305,9 @@ TVector3 CControl::CalcAirForce () {
|
|||
TVector3 windvec = ScaleVector (-1, ff.vel);
|
||||
if (g_game.wind_id > 0)
|
||||
windvec = AddVectors (windvec, ScaleVector (WIND_FACTOR, Wind.WindDrift ()));
|
||||
|
||||
|
||||
double windspeed = NormVector (windvec);
|
||||
double re = 34600 * windspeed;
|
||||
double re = 34600 * windspeed;
|
||||
int tablesize = sizeof (airdrag) / sizeof (airdrag[0]);
|
||||
double interpol = LinearInterp (airlog, airdrag, log10 (re), tablesize);
|
||||
double dragcoeff = pow (10.0, interpol);
|
||||
|
@ -332,7 +327,7 @@ TVector3 CControl::CalcSpringForce () {
|
|||
}
|
||||
|
||||
TVector3 CControl::CalcNormalForce () {
|
||||
TVector3 nmlforce(0, 0, 0);
|
||||
TVector3 nmlforce(0, 0, 0);
|
||||
if (ff.surfdistance <= -ff.comp_depth) {
|
||||
ff.compression = -ff.surfdistance - ff.comp_depth;
|
||||
nmlforce = CalcSpringForce ();
|
||||
|
@ -362,10 +357,10 @@ TVector3 CControl::CalcJumpForce () {
|
|||
|
||||
TVector3 CControl::CalcFrictionForce (double speed, const TVector3& nmlforce) {
|
||||
TVector3 frictforce;
|
||||
double fric_f_mag;
|
||||
TMatrix fric_rot_mat;
|
||||
double steer_angle;
|
||||
|
||||
double fric_f_mag;
|
||||
TMatrix fric_rot_mat;
|
||||
double steer_angle;
|
||||
|
||||
if ((cairborne == false && speed > minFrictspeed) || g_game.finish) {
|
||||
TVector3 tmp_nml_f = nmlforce;
|
||||
fric_f_mag = NormVector (tmp_nml_f) * ff.frict_coeff;
|
||||
|
@ -375,13 +370,13 @@ TVector3 CControl::CalcFrictionForce (double speed, const TVector3& nmlforce) {
|
|||
steer_angle = turn_fact * MAX_TURN_ANGLE;
|
||||
|
||||
if (fabs (fric_f_mag * sin (steer_angle * M_PI / 180)) > MAX_TURN_PERP) {
|
||||
steer_angle = RADIANS_TO_ANGLES (asin (MAX_TURN_PERP / fric_f_mag)) *
|
||||
steer_angle = RADIANS_TO_ANGLES (asin (MAX_TURN_PERP / fric_f_mag)) *
|
||||
turn_fact / fabs (turn_fact);
|
||||
}
|
||||
RotateAboutVectorMatrix (fric_rot_mat, ff.surfnml, steer_angle);
|
||||
frictforce = TransformVector (fric_rot_mat, frictforce);
|
||||
frictforce = ScaleVector (1.0 + MAX_TURN_PEN, frictforce);
|
||||
|
||||
|
||||
} else frictforce = TVector3 (0, 0, 0);
|
||||
return frictforce;
|
||||
}
|
||||
|
@ -391,7 +386,7 @@ TVector3 CControl::CalcBrakeForce (double speed) {
|
|||
if (g_game.finish == false) {
|
||||
if (cairborne == false && speed > minFrictspeed) {
|
||||
if (speed > minSpeed && is_braking) {
|
||||
brakeforce = ScaleVector (ff.frict_coeff * BRAKE_FORCE, ff.frictdir);
|
||||
brakeforce = ScaleVector (ff.frict_coeff * BRAKE_FORCE, ff.frictdir);
|
||||
} else brakeforce = TVector3 (0, 0, 0);
|
||||
} else brakeforce = TVector3 (0, 0, 0);
|
||||
|
||||
|
@ -410,7 +405,7 @@ TVector3 CControl::CalcBrakeForce (double speed) {
|
|||
|
||||
TVector3 CControl::CalcPaddleForce (double speed) {
|
||||
TVector3 paddleforce;
|
||||
if (is_paddling)
|
||||
if (is_paddling)
|
||||
if (g_game.time - paddle_time >= PADDLING_DURATION) is_paddling = false;
|
||||
|
||||
if (is_paddling) {
|
||||
|
@ -418,8 +413,8 @@ TVector3 CControl::CalcPaddleForce (double speed) {
|
|||
paddleforce = TVector3 (0, 0, -TUX_MASS * EARTH_GRAV / 4.0);
|
||||
paddleforce = RotateVector (corientation, paddleforce);
|
||||
} else {
|
||||
paddleforce = ScaleVector (-1 * min (MAX_PADD_FORCE, MAX_PADD_FORCE
|
||||
* (MAX_PADDLING_SPEED - speed) / MAX_PADDLING_SPEED
|
||||
paddleforce = ScaleVector (-1 * min (MAX_PADD_FORCE, MAX_PADD_FORCE
|
||||
* (MAX_PADDLING_SPEED - speed) / MAX_PADDLING_SPEED
|
||||
* min(1.0, ff.frict_coeff / IDEAL_PADD_FRIC)), ff.frictdir);
|
||||
}
|
||||
} else paddleforce = TVector3 (0, 0, 0);
|
||||
|
@ -452,7 +447,7 @@ TVector3 CControl::CalcNetForce (const TVector3& pos, const TVector3& vel) {
|
|||
vector<double> surfweights(Course.TerrList.size());
|
||||
Course.GetSurfaceType (ff.pos.x, ff.pos.z, &surfweights[0]);
|
||||
TTerrType *TerrList = &Course.TerrList[0];
|
||||
ff.frict_coeff = ff.comp_depth = 0;
|
||||
ff.frict_coeff = ff.comp_depth = 0;
|
||||
for (size_t i=0; i<Course.TerrList.size(); i++) {
|
||||
ff.frict_coeff += surfweights[i] * TerrList[i].friction;
|
||||
ff.comp_depth += surfweights[i] * TerrList[i].depth;
|
||||
|
@ -473,12 +468,12 @@ TVector3 CControl::CalcNetForce (const TVector3& pos, const TVector3& vel) {
|
|||
TVector3 airforce = CalcAirForce ();
|
||||
TVector3 paddleforce = CalcPaddleForce (speed);
|
||||
|
||||
TVector3 netforce =
|
||||
AddVectors (jumpforce,
|
||||
AddVectors (gravforce,
|
||||
AddVectors (nmlforce,
|
||||
AddVectors (frictforce,
|
||||
AddVectors (airforce,
|
||||
TVector3 netforce =
|
||||
AddVectors (jumpforce,
|
||||
AddVectors (gravforce,
|
||||
AddVectors (nmlforce,
|
||||
AddVectors (frictforce,
|
||||
AddVectors (airforce,
|
||||
AddVectors (brakeforce, paddleforce))))));
|
||||
|
||||
return ScaleVector (1.0, netforce);
|
||||
|
@ -502,7 +497,7 @@ void CControl::SolveOdeSystem (double timestep) {
|
|||
double pos_err[3], vel_err[3], tot_pos_err, tot_vel_err;
|
||||
double err=0, tol=0;
|
||||
|
||||
TOdeSolver solver = NewOdeSolver23 ();
|
||||
TOdeSolver solver = NewOdeSolver23 ();
|
||||
double h = ode_time_step;
|
||||
if (h < 0 || solver.EstimateError == NULL)
|
||||
h = AdjustTimeStep (timestep, cvel);
|
||||
|
@ -524,18 +519,18 @@ void CControl::SolveOdeSystem (double timestep) {
|
|||
while (!done) {
|
||||
if (t >= tfinal) {
|
||||
Message ("t >= tfinal in ode_system()", "");
|
||||
break;
|
||||
break;
|
||||
}
|
||||
if (1.1 * h > tfinal - t) {
|
||||
h = tfinal-t;
|
||||
done = true;
|
||||
done = true;
|
||||
}
|
||||
TVector3 saved_pos = new_pos;
|
||||
TVector3 saved_vel = new_vel;
|
||||
TVector3 saved_f = new_f;
|
||||
|
||||
|
||||
failed = false;
|
||||
for (;;) {
|
||||
for (;;) {
|
||||
solver.InitOdeData (x, new_pos.x, h);
|
||||
solver.InitOdeData (y, new_pos.y, h);
|
||||
solver.InitOdeData (z, new_pos.z, h);
|
||||
|
@ -588,7 +583,7 @@ void CControl::SolveOdeSystem (double timestep) {
|
|||
|
||||
tot_pos_err = 0.;
|
||||
tot_vel_err = 0.;
|
||||
|
||||
|
||||
for (int i=0; i<3; i++) {
|
||||
pos_err[i] *= pos_err[i];
|
||||
tot_pos_err += pos_err[i];
|
||||
|
@ -617,16 +612,16 @@ void CControl::SolveOdeSystem (double timestep) {
|
|||
new_vel = saved_vel;
|
||||
new_f = saved_f;
|
||||
} else break;
|
||||
} else break;
|
||||
}
|
||||
|
||||
} else break;
|
||||
}
|
||||
|
||||
t = t + h;
|
||||
TVector3 tmp_vel = new_vel;
|
||||
TVector3 tmp_vel = new_vel;
|
||||
speed = NormVector (tmp_vel);
|
||||
if (param.perf_level > 2) generate_particles (this, h, new_pos, speed);
|
||||
|
||||
new_f = CalcNetForce (new_pos, new_vel);
|
||||
|
||||
|
||||
if (!failed && solver.EstimateError != NULL) {
|
||||
double temp = 1.25 * pow (err / tol, solver.TimestepExponent());
|
||||
if (temp > 0.2) h = h / temp;
|
||||
|
@ -640,10 +635,10 @@ void CControl::SolveOdeSystem (double timestep) {
|
|||
ode_time_step = h;
|
||||
cnet_force = new_f;
|
||||
|
||||
cvel = new_vel;
|
||||
cvel = new_vel;
|
||||
last_pos = cpos;
|
||||
cpos = new_pos;
|
||||
|
||||
|
||||
float step = VectorLength (SubtractVectors (cpos, last_pos));
|
||||
way += step;
|
||||
|
||||
|
@ -679,7 +674,7 @@ void CControl::UpdatePlayerPos (double timestep) {
|
|||
if (timestep > 2 * EPS) SolveOdeSystem (timestep);
|
||||
|
||||
TPlane surf_plane = Course.GetLocalCoursePlane (cpos);
|
||||
TVector3 surf_nml = surf_plane.nml; // normal vector of terrain
|
||||
TVector3 surf_nml = surf_plane.nml; // normal vector of terrain
|
||||
dist_from_surface = DistanceToPlane (surf_plane, cpos);
|
||||
|
||||
TVector3 temp_vel = cvel;
|
||||
|
@ -704,12 +699,12 @@ void CControl::UpdatePlayerPos (double timestep) {
|
|||
paddling_factor = 0;
|
||||
}
|
||||
|
||||
TVector3 local_force = RotateVector
|
||||
TVector3 local_force = RotateVector
|
||||
(ConjugateQuaternion (corientation), cnet_force);
|
||||
|
||||
if (jumping)
|
||||
flap_factor = (g_game.time - jump_start_time) / JUMP_FORCE_DURATION;
|
||||
|
||||
shape->AdjustJoints (turn_animation, is_braking, paddling_factor, speed,
|
||||
shape->AdjustJoints (turn_animation, is_braking, paddling_factor, speed,
|
||||
local_force, flap_factor);
|
||||
}
|
||||
|
|
|
@ -58,7 +58,8 @@ void SetRaceConditions (void) {
|
|||
g_game.course_id = course->GetValue();
|
||||
g_game.theme_id = CourseList[course->GetValue()].music_theme;
|
||||
g_game.game_type = PRACTICING;
|
||||
State::manager.RequestEnterState (Loading);
}
|
||||
State::manager.RequestEnterState (Loading);
|
||||
}
|
||||
|
||||
void CRaceSelect::Motion (int x, int y) {
|
||||
MouseMoveGUI(x, y);
|
||||
|
@ -89,8 +90,10 @@ void CRaceSelect::Keyb(unsigned int key, bool special, bool release, int x, int
|
|||
case 27: State::manager.RequestEnterState (GameTypeSelect); break;
|
||||
case SDLK_u: param.ui_snow = !param.ui_snow; break;
|
||||
case SDLK_t: g_game.force_treemap = !g_game.force_treemap; break;
|
||||
case SDLK_c: g_game.treesize++;
if (g_game.treesize > 5) g_game.treesize = 1; break;
|
||||
case SDLK_v: g_game.treevar++;
if (g_game.treevar > 5) g_game.treevar = 1; break;
|
||||
case SDLK_c: g_game.treesize++;
|
||||
if (g_game.treesize > 5) g_game.treesize = 1; break;
|
||||
case SDLK_v: g_game.treevar++;
|
||||
if (g_game.treevar > 5) g_game.treevar = 1; break;
|
||||
case 13: if (textbuttons[1]->focussed())
|
||||
State::manager.RequestEnterState (GameTypeSelect);
|
||||
else
|
||||
|
@ -106,13 +109,16 @@ static int icontop, iconsize, iconspace, iconleft, iconsumwidth;
|
|||
static int boxleft, boxwidth;
|
||||
|
||||
void CRaceSelect::Enter() {
|
||||
Winsys.ShowCursor (!param.ice_cursor);
Music.Play (param.menu_music, -1);
|
||||
CourseList = &Course.CourseList[0];
|
||||
Winsys.ShowCursor (!param.ice_cursor);
|
||||
Music.Play (param.menu_music, -1);
|
||||
|
||||
CourseList = &Course.CourseList[0];
|
||||
|
||||
framewidth = 550 * param.scale;
|
||||
frameheight = 50 * param.scale;
|
||||
frametop = AutoYPosN (30);
|
||||
area = AutoAreaN (30, 80, framewidth);
|
||||
|
||||
area = AutoAreaN (30, 80, framewidth);
|
||||
prevtop = AutoYPosN (50);
|
||||
prevheight = 144 * param.scale;
|
||||
prevwidth = 192 * param.scale;
|
||||
|
@ -127,8 +133,12 @@ void CRaceSelect::Enter() {
|
|||
ResetGUI ();
|
||||
|
||||
course = AddUpDown(area.left + framewidth + 8, frametop, 0, (int)Course.CourseList.size() - 1, (int)g_game.course_id);
|
||||
light = AddIconButton (iconleft, icontop, Tex.GetTexture (LIGHT_BUTT), iconsize, 3, (int)g_game.light_id);
|
||||
snow = AddIconButton (iconleft + iconspace, icontop, Tex.GetTexture (SNOW_BUTT), iconsize, 3, g_game.snow_id);
wind = AddIconButton (iconleft + iconspace*2, icontop, Tex.GetTexture (WIND_BUTT), iconsize, 3, g_game.wind_id);
mirror = AddIconButton (iconleft + iconspace*3, icontop, Tex.GetTexture (MIRROR_BUTT), iconsize, 1, (int)g_game.mirror_id);
random_btn = AddIconButton (iconleft + iconspace*4, icontop, Tex.GetTexture (RANDOM_BUTT), iconsize, 1, 0);
|
||||
|
||||
light = AddIconButton (iconleft, icontop, Tex.GetTexture (LIGHT_BUTT), iconsize, 3, (int)g_game.light_id);
|
||||
snow = AddIconButton (iconleft + iconspace, icontop, Tex.GetTexture (SNOW_BUTT), iconsize, 3, g_game.snow_id);
|
||||
wind = AddIconButton (iconleft + iconspace*2, icontop, Tex.GetTexture (WIND_BUTT), iconsize, 3, g_game.wind_id);
|
||||
mirror = AddIconButton (iconleft + iconspace*3, icontop, Tex.GetTexture (MIRROR_BUTT), iconsize, 1, (int)g_game.mirror_id);
|
||||
random_btn = AddIconButton (iconleft + iconspace*4, icontop, Tex.GetTexture (RANDOM_BUTT), iconsize, 1, 0);
|
||||
int siz = FT.AutoSizeN (5);
|
||||
double len1 = FT.GetTextWidth (Trans.Text(13));
|
||||
textbuttons[0] = AddTextButton (Trans.Text(13), area.right-len1-50, AutoYPosN (80), siz);
|
||||
|
@ -141,12 +151,13 @@ void CRaceSelect::Loop(double timestep) {
|
|||
int ww = param.x_resolution;
|
||||
int hh = param.y_resolution;
|
||||
TColor col;
|
||||
check_gl_error();
|
||||
|
||||
check_gl_error();
|
||||
set_gl_options (GUI );
|
||||
ClearRenderContext ();
|
||||
SetupGuiDisplay ();
|
||||
|
||||
Music.Update ();
|
||||
Music.Update ();
|
||||
if (param.ui_snow) {
|
||||
update_ui_snow (timestep);
|
||||
draw_ui_snow ();
|
||||
|
@ -158,7 +169,8 @@ void CRaceSelect::Loop(double timestep) {
|
|||
Tex.Draw (TOP_LEFT, 0, 0, 1);
|
||||
Tex.Draw (TOP_RIGHT, ww-256, 0, 1);
|
||||
|
||||
// DrawFrameX (area.left, area.top, area.right-area.left, area.bottom - area.top,
// 0, colMBackgr, colBlack, 0.2);
|
||||
// DrawFrameX (area.left, area.top, area.right-area.left, area.bottom - area.top,
|
||||
// 0, colMBackgr, colBlack, 0.2);
|
||||
|
||||
// course selection
|
||||
if (course->focussed()) col = colDYell; else col = colWhite;
|
||||
|
@ -177,7 +189,8 @@ void CRaceSelect::Loop(double timestep) {
|
|||
for (size_t i=0; i<CourseList[course->GetValue()].num_lines; i++) {
|
||||
FT.DrawString (boxleft+8, prevtop+i*dist, CourseList[course->GetValue()].desc[i]);
|
||||
}
|
||||
FT.DrawString (CENTER, prevtop + prevheight + 10, "Author: " + CourseList[course->GetValue()].author);
|
||||
|
||||
FT.DrawString (CENTER, prevtop + prevheight + 10, "Author: " + CourseList[course->GetValue()].author);
|
||||
|
||||
FT.AutoSizeN (4);
|
||||
string forcetrees = "Load trees.png";
|
||||
|
@ -188,7 +201,7 @@ void CRaceSelect::Loop(double timestep) {
|
|||
if (g_game.force_treemap) {
|
||||
FT.SetColor (colYellow);
|
||||
FT.DrawString (CENTER, AutoYPosN (85), forcetrees);
|
||||
FT.DrawString (CENTER, AutoYPosN (90), sizevar);
|
||||
FT.DrawString (CENTER, AutoYPosN (90), sizevar);
|
||||
}
|
||||
|
||||
DrawGUI();
|
||||
|
|
|
@ -32,4 +32,4 @@ public:
|
|||
|
||||
extern CRaceSelect RaceSelect;
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
48
racing.cpp
48
racing.cpp
|
@ -63,25 +63,37 @@ static int lastsound = -1;
|
|||
void CRacing::Keyb (unsigned int key, bool special, bool release, int x, int y) {
|
||||
switch (key) {
|
||||
// steering flipflops
|
||||
case 273: key_paddling = !release; break;
case 274: key_braking = !release; break;
case 276: left_turn = !release; break;
case 275: right_turn = !release; break;
case 32: key_charging = !release; break;
|
||||
case SDLK_t: trick_modifier = !release; break;
|
||||
case 273: key_paddling = !release; break;
|
||||
case 274: key_braking = !release; break;
|
||||
case 276: left_turn = !release; break;
|
||||
case 275: right_turn = !release; break;
|
||||
case 32: key_charging = !release; break;
|
||||
case SDLK_t: trick_modifier = !release; break;
|
||||
// mode changing and other actions
|
||||
case 27: if (!release) {
g_game.raceaborted = true;
|
||||
case 27: if (!release) {
|
||||
g_game.raceaborted = true;
|
||||
g_game.race_result = -1;
|
||||
State::manager.RequestEnterState (GameOver);
|
||||
} break;
case SDLK_p: if (!release) State::manager.RequestEnterState (Paused); break;
case SDLK_r: if (!release) State::manager.RequestEnterState (Reset); break;
case SDLK_s: if (!release) ScreenshotN (); break;
|
||||
} break;
|
||||
case SDLK_p: if (!release) State::manager.RequestEnterState (Paused); break;
|
||||
case SDLK_r: if (!release) State::manager.RequestEnterState (Reset); break;
|
||||
case SDLK_s: if (!release) ScreenshotN (); break;
|
||||
|
||||
// view changing
|
||||
case SDLK_1: if (!release) {
|
||||
set_view_mode (Players.GetCtrl (g_game.player_id), ABOVE);
|
||||
param.view_mode = ABOVE;
|
||||
} break;
case SDLK_2: if (!release) {
|
||||
} break;
|
||||
case SDLK_2: if (!release) {
|
||||
set_view_mode (Players.GetCtrl (g_game.player_id), FOLLOW);
|
||||
param.view_mode = FOLLOW;
|
||||
} break;
case SDLK_3: if (!release) {
|
||||
} break;
|
||||
case SDLK_3: if (!release) {
|
||||
set_view_mode (Players.GetCtrl (g_game.player_id), BEHIND);
|
||||
param.view_mode = BEHIND;
|
||||
} break;
// toggle
|
||||
} break;
|
||||
|
||||
// toggle
|
||||
case SDLK_h: if (!release) param.show_hud = !param.show_hud; break;
|
||||
case SDLK_f: if (!release) param.display_fps = !param.display_fps; break;
|
||||
case SDLK_F5: if (!release) sky = !sky; break;
|
||||
|
@ -115,7 +127,8 @@ void CalcJumpEnergy (double time_step){
|
|||
if (ctrl->jump_charging) {
|
||||
ctrl->jump_amt = min (MAX_JUMP_AMT, g_game.time - charge_start_time);
|
||||
} else if (ctrl->jumping) {
|
||||
ctrl->jump_amt *= (1.0 - (g_game.time - ctrl->jump_start_time) /
JUMP_FORCE_DURATION);
|
||||
ctrl->jump_amt *= (1.0 - (g_game.time - ctrl->jump_start_time) /
|
||||
JUMP_FORCE_DURATION);
|
||||
} else {
|
||||
ctrl->jump_amt = 0;
|
||||
}
|
||||
|
@ -161,7 +174,8 @@ void CRacing::Enter (void) {
|
|||
|
||||
SetSoundVolumes ();
|
||||
Music.PlayTheme (g_game.theme_id, MUS_RACING);
|
||||
g_game.finish = false;
|
||||
|
||||
g_game.finish = false;
|
||||
}
|
||||
|
||||
// -------------------- sound -----------------------------------------
|
||||
|
@ -173,7 +187,8 @@ int SlideVolume (CControl *ctrl, double speed, int typ) {
|
|||
(ctrl->is_braking ? 128:0) +
|
||||
(ctrl->jumping ? 128:0) + 20) * (speed / 10), 128));
|
||||
} else { // always
|
||||
return (int)(128 * pow((speed/2),2));
}
|
||||
return (int)(128 * pow((speed/2),2));
|
||||
}
|
||||
}
|
||||
|
||||
void PlayTerrainSound (CControl *ctrl, bool airborne) {
|
||||
|
@ -196,7 +211,8 @@ void PlayTerrainSound (CControl *ctrl, bool airborne) {
|
|||
// ----------------------- controls -----------------------------------
|
||||
void CalcSteeringControls (CControl *ctrl, double time_step) {
|
||||
if (stick_turn) {
|
||||
ctrl->turn_fact = stick_turnfact;
ctrl->turn_animation += ctrl->turn_fact * 2 * time_step;
|
||||
ctrl->turn_fact = stick_turnfact;
|
||||
ctrl->turn_animation += ctrl->turn_fact * 2 * time_step;
|
||||
ctrl->turn_animation = min (1.0, max (-1.0, ctrl->turn_animation));
|
||||
} else if (left_turn ^ right_turn) {
|
||||
if (left_turn) ctrl->turn_fact = -1.0;
|
||||
|
@ -290,7 +306,7 @@ void CRacing::Loop (double time_step){
|
|||
check_gl_error();
|
||||
ClearRenderContext ();
|
||||
Env.SetupFog ();
|
||||
Music.Update ();
|
||||
Music.Update ();
|
||||
CalcTrickControls (ctrl, time_step, airborne);
|
||||
|
||||
if (!g_game.finish) CalcSteeringControls (ctrl, time_step);
|
||||
|
@ -298,7 +314,8 @@ void CRacing::Loop (double time_step){
|
|||
PlayTerrainSound (ctrl, airborne);
|
||||
|
||||
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
ctrl->UpdatePlayerPos (time_step);
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
ctrl->UpdatePlayerPos (time_step);
|
||||
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
if (g_game.finish) IncCameraDistance (time_step);
|
||||
update_view (ctrl, time_step);
|
||||
|
@ -320,10 +337,11 @@ void CRacing::Loop (double time_step){
|
|||
UpdateSnow (time_step, ctrl);
|
||||
DrawSnow (ctrl);
|
||||
DrawHud (ctrl);
|
||||
Reshape (param.x_resolution, param.y_resolution);
|
||||
|
||||
Reshape (param.x_resolution, param.y_resolution);
|
||||
Winsys.SwapBuffers ();
|
||||
if (g_game.finish == false) g_game.time += time_step;
|
||||
}
|
||||
}
|
||||
// ---------------------------------- term ------------------
|
||||
void CRacing::Exit() {
|
||||
Sound.HaltAll ();
|
||||
|
|
|
@ -49,7 +49,8 @@ void CReset::Loop(double time_step) {
|
|||
CControl *ctrl = Players.GetCtrl (g_game.player_id);
|
||||
double elapsed_time = Winsys.ClockTime () - reset_start_time;
|
||||
double course_width, course_length;
|
||||
static bool tux_visible = true;
static int tux_visible_count = 0;
|
||||
static bool tux_visible = true;
|
||||
static int tux_visible_count = 0;
|
||||
TObjectType *object_types;
|
||||
TItem *item_locs;
|
||||
size_t first_reset, last_reset, num_item_types;
|
||||
|
@ -93,7 +94,8 @@ void CReset::Loop(double time_step) {
|
|||
} else {
|
||||
best_loc = -1;
|
||||
for (size_t i = first_reset; i <= last_reset; i++) {
|
||||
if (item_locs[i].pt.z > ctrl->cpos.z) {
if (best_loc == -1 || item_locs[i].pt.z < item_locs[best_loc].pt.z) {
|
||||
if (item_locs[i].pt.z > ctrl->cpos.z) {
|
||||
if (best_loc == -1 || item_locs[i].pt.z < item_locs[best_loc].pt.z) {
|
||||
best_loc = (int)i;
|
||||
} // if
|
||||
} // if
|
||||
|
@ -110,7 +112,8 @@ void CReset::Loop(double time_step) {
|
|||
} else {
|
||||
ctrl->cpos.x = item_locs[best_loc].pt.x;
|
||||
ctrl->cpos.z = item_locs[best_loc].pt.z;
|
||||
} // if
}
|
||||
} // if
|
||||
}
|
||||
|
||||
ctrl->view_init = false;
|
||||
ctrl->Init ();
|
||||
|
|
3
score.h
3
score.h
|
@ -40,7 +40,8 @@ class CScore : public State {
|
|||
private:
|
||||
vector<TScoreList> Scorelist;
|
||||
TScore TempScore;
|
||||
void Enter();
|
||||
|
||||
void Enter();
|
||||
void Loop(double time_step);
|
||||
void Keyb(unsigned int key, bool special, bool release, int x, int y);
|
||||
void Mouse(int button, int state, int x, int y);
|
||||
|
|
|
@ -43,12 +43,16 @@ void CSplashScreen::Keyb(unsigned int key, bool special, bool release, int x, in
|
|||
}
|
||||
|
||||
|
||||
void CSplashScreen::Enter() {
Winsys.ShowCursor (!param.ice_cursor);
init_ui_snow ();
Music.Play (param.menu_music, -1);
|
||||
void CSplashScreen::Enter() {
|
||||
Winsys.ShowCursor (!param.ice_cursor);
|
||||
init_ui_snow ();
|
||||
Music.Play (param.menu_music, -1);
|
||||
g_game.loopdelay = 10;
|
||||
}
|
||||
|
||||
void CSplashScreen::Loop(double timestep) {
|
||||
Music.Update ();
check_gl_error();
|
||||
Music.Update ();
|
||||
check_gl_error();
|
||||
ClearRenderContext ();
|
||||
set_gl_options (GUI);
|
||||
SetupGuiDisplay ();
|
||||
|
@ -69,7 +73,8 @@ void CSplashScreen::Loop(double timestep) {
|
|||
Sound.LoadSoundList ();
|
||||
Credits.LoadCreditList ();
|
||||
Char.LoadCharacterList ();
|
||||
Course.LoadObjectTypes ();
Course.LoadTerrainTypes ();
|
||||
Course.LoadObjectTypes ();
|
||||
Course.LoadTerrainTypes ();
|
||||
Env.LoadEnvironmentList ();
|
||||
Course.LoadCourseList ();
|
||||
Score.LoadHighScore (); // after LoadCourseList !!!
|
||||
|
@ -78,4 +83,4 @@ void CSplashScreen::Loop(double timestep) {
|
|||
Players.LoadPlayers ();
|
||||
|
||||
State::manager.RequestEnterState (Regist);
|
||||
}
|
||||
}
|
||||
|
|
11
states.cpp
11
states.cpp
|
@ -59,13 +59,15 @@ void State::Manager::PollEvent() {
|
|||
switch (event.type) {
|
||||
case SDL_KEYDOWN:
|
||||
SDL_GetMouseState(&x, &y);
|
||||
key = event.key.keysym.sym;
current->Keyb(key, key >= 256, false, x, y);
|
||||
key = event.key.keysym.sym;
|
||||
current->Keyb(key, key >= 256, false, x, y);
|
||||
current->Keyb_spec(event.key.keysym, false);
|
||||
break;
|
||||
|
||||
case SDL_KEYUP:
|
||||
SDL_GetMouseState(&x, &y);
|
||||
key = event.key.keysym.sym;
current->Keyb(key, key >= 256, true, x, y);
|
||||
key = event.key.keysym.sym;
|
||||
current->Keyb(key, key >= 256, true, x, y);
|
||||
current->Keyb_spec(event.key.keysym, true);
|
||||
break;
|
||||
|
||||
|
@ -86,7 +88,7 @@ void State::Manager::PollEvent() {
|
|||
current->Jaxis(axis, val);
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
case SDL_JOYBUTTONUP:
|
||||
if (Winsys.joystick_isActive()) {
|
||||
|
@ -102,7 +104,8 @@ void State::Manager::PollEvent() {
|
|||
Reshape(event.resize.w, event.resize.h);
|
||||
}
|
||||
break;
|
||||
case SDL_QUIT:
|
||||
|
||||
case SDL_QUIT:
|
||||
quit = true;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -53,7 +53,8 @@ static bool moveactive = false;
|
|||
static int comp = 0;
|
||||
|
||||
void InitCharTools () {
|
||||
charbase = (int)((param.y_resolution - 200) / 18);
firstnode = 1;
|
||||
charbase = (int)((param.y_resolution - 200) / 18);
|
||||
firstnode = 1;
|
||||
lastnode = TestChar.GetNumNodes () -1;
|
||||
curr_node = firstnode;
|
||||
curr_act = firstact;
|
||||
|
@ -79,12 +80,19 @@ void RecallAction (TCharAction *act) {
|
|||
void ChangeValue (int type, double fact) {
|
||||
if (type == 0 || type == 4) {
|
||||
if (comp == 0) {
|
||||
action->vec[curr_act].x += 0.02 * fact;
action->vec[curr_act].y += 0.02 * fact;
action->vec[curr_act].z += 0.02 * fact;
} else if (comp == 1) action->vec[curr_act].x += 0.02 * fact;
else if (comp == 2) action->vec[curr_act].y += 0.02 * fact;
else if (comp == 3) action->vec[curr_act].z += 0.02 * fact;
} else if (type > 0 && type < 4) {
|
||||
action->vec[curr_act].x += 0.02 * fact;
|
||||
action->vec[curr_act].y += 0.02 * fact;
|
||||
action->vec[curr_act].z += 0.02 * fact;
|
||||
} else if (comp == 1) action->vec[curr_act].x += 0.02 * fact;
|
||||
else if (comp == 2) action->vec[curr_act].y += 0.02 * fact;
|
||||
else if (comp == 3) action->vec[curr_act].z += 0.02 * fact;
|
||||
} else if (type > 0 && type < 4) {
|
||||
action->dval[curr_act] += 1 * fact;
|
||||
} else if (type == 5) {
|
||||
action->dval[curr_act] += 1 * fact;
|
||||
}
|
||||
TestChar.RefreshNode (curr_node);
SetCharChanged (true);
|
||||
TestChar.RefreshNode (curr_node);
|
||||
SetCharChanged (true);
|
||||
}
|
||||
|
||||
void ChangeNode (int steps) {
|
||||
|
@ -98,7 +106,8 @@ void ChangeNode (int steps) {
|
|||
action = TestChar.GetAction (curr_node);
|
||||
if (action->num > 0 && action->type[0] == 4) comp = 0; else comp = 1;
|
||||
StoreAction (action);
|
||||
}
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetRotation (double x, double y, double z) {
|
||||
xrotation = x;
|
||||
|
@ -126,7 +135,8 @@ void CharKeys (unsigned int key, bool special, bool release, int x, int y) {
|
|||
|
||||
if (release) return;
|
||||
|
||||
int type = action->type[curr_act];
switch (key) {
|
||||
int type = action->type[curr_act];
|
||||
switch (key) {
|
||||
case SDLK_TAB: SetToolMode (1); break;
|
||||
case SDLK_ESCAPE: case SDLK_q: QuitTool (); break;
|
||||
case SDLK_F10: ScreenshotN (); break;
|
||||
|
@ -134,7 +144,9 @@ void CharKeys (unsigned int key, bool special, bool release, int x, int y) {
|
|||
case SDLK_c: ScreenshotN (); break;
|
||||
case SDLK_m: TestChar.useMaterials = !TestChar.useMaterials; break;
|
||||
case SDLK_h: TestChar.useHighlighting = !TestChar.useHighlighting; break;
|
||||
case SDLK_r:
TestChar.Reset ();
ReloadToolCharacter ();
|
||||
case SDLK_r:
|
||||
TestChar.Reset ();
|
||||
ReloadToolCharacter ();
|
||||
Tools.Enter ();
|
||||
break;
|
||||
case SDLK_u: if (action != NULL) {
|
||||
|
@ -163,13 +175,20 @@ void CharKeys (unsigned int key, bool special, bool release, int x, int y) {
|
|||
case SDLK_HOME: ChangeNode (-charbase); break;
|
||||
|
||||
// select action
|
||||
case SDLK_DOWN:
if (curr_act < lastact) curr_act++;
if (action->type[curr_act] == 4) comp = 0; else comp = 1;
|
||||
break;
case SDLK_UP:
if (curr_act > 0) curr_act--;
if (action->type[curr_act] == 4) comp = 0; else comp = 1;
|
||||
break;
case SDLK_LEFT: ChangeValue (type, -1); break;
|
||||
case SDLK_DOWN:
|
||||
if (curr_act < lastact) curr_act++;
|
||||
if (action->type[curr_act] == 4) comp = 0; else comp = 1;
|
||||
break;
|
||||
case SDLK_UP:
|
||||
if (curr_act > 0) curr_act--;
|
||||
if (action->type[curr_act] == 4) comp = 0; else comp = 1;
|
||||
break;
|
||||
case SDLK_LEFT: ChangeValue (type, -1); break;
|
||||
case SDLK_RIGHT: ChangeValue (type, 1); break;
|
||||
|
||||
// select value
|
||||
case SDLK_SPACE:
if (type == 0 || type == 4) {
|
||||
case SDLK_SPACE:
|
||||
if (type == 0 || type == 4) {
|
||||
comp++;
|
||||
if (comp > 3) comp = 0;
|
||||
if (type == 0 && comp == 0) comp = 1;
|
||||
|
@ -274,7 +293,8 @@ void RenderChar (double timestep) {
|
|||
|
||||
TestChar.ResetRoot ();
|
||||
TestChar.ResetJoints ();
|
||||
glTranslatef (xposition, yposition, zposition);
glRotatef (xrotation, 1, 0, 0);
|
||||
glTranslatef (xposition, yposition, zposition);
|
||||
glRotatef (xrotation, 1, 0, 0);
|
||||
glRotatef (yrotation, 0, 1, 0);
|
||||
glRotatef (zrotation, 0, 0, 1);
|
||||
|
||||
|
@ -298,14 +318,16 @@ void RenderChar (double timestep) {
|
|||
int xl, yt;
|
||||
for (size_t i=0; i<=lastnode; i++) {
|
||||
if (i != curr_node) {
|
||||
FT.SetColor (colLGrey);
FT.SetFont ("normal");
|
||||
FT.SetColor (colLGrey);
|
||||
FT.SetFont ("normal");
|
||||
} else {
|
||||
FT.SetColor (colYellow);
|
||||
FT.SetFont ("bold");
|
||||
}
|
||||
xl = ITrunc ((int)i, charbase) * 100 + 20;
|
||||
yt = IFrac ((int)i, charbase) * 18 + 60;
|
||||
FT.DrawString (xl, yt, TestChar.GetNodeJoint (i));
}
|
||||
FT.DrawString (xl, yt, TestChar.GetNodeJoint (i));
|
||||
}
|
||||
|
||||
size_t num = action->num;
|
||||
int type;
|
||||
|
@ -320,7 +342,8 @@ void RenderChar (double timestep) {
|
|||
case 2: DrawActionFloat (i, "y-rot", yt, action->dval[i]); break;
|
||||
case 3: DrawActionFloat (i, "z-rot", yt, action->dval[i]); break;
|
||||
case 4: DrawActionVec (i, "scale", yt, action->vec[i]); break;
|
||||
case 5: DrawActionFloat (i, "vis", yt, action->dval[i]);
is_visible = true; break;
|
||||
case 5: DrawActionFloat (i, "vis", yt, action->dval[i]);
|
||||
is_visible = true; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,5 @@ void CharMotion (int x, int y);
|
|||
void RenderChar (double timestep);
|
||||
void StoreAction (TCharAction *act);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -35,6 +35,5 @@ void SequenceMouse (int button, int state, int x, int y);
|
|||
void SequenceMotion (int x, int y);
|
||||
void RenderSequence (double timestep);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
22
tools.cpp
22
tools.cpp
|
@ -29,7 +29,11 @@ GNU General Public License for more details.
|
|||
CGluCamera GluCamera;
|
||||
|
||||
CCamera::CCamera () {
|
||||
xview = 0;
yview = 0;
zview = 4;
vhead = 0;
vpitch = 0;
|
||||
xview = 0;
|
||||
yview = 0;
|
||||
zview = 4;
|
||||
vhead = 0;
|
||||
vpitch = 0;
|
||||
|
||||
fore = false;
|
||||
back = false;
|
||||
|
@ -66,7 +70,9 @@ void CCamera::RotatePitch (GLfloat step) {
|
|||
}
|
||||
|
||||
void CCamera::Update (float timestep) {
|
||||
if (fore) ZMove (-2 * timestep);
if (back) ZMove (2 * timestep);
if (left) XMove (-1 * timestep);
|
||||
if (fore) ZMove (-2 * timestep);
|
||||
if (back) ZMove (2 * timestep);
|
||||
if (left) XMove (-1 * timestep);
|
||||
if (right) XMove (1 * timestep);
|
||||
if (up) YMove (1 * timestep);
|
||||
if (down) YMove (-1 * timestep);
|
||||
|
@ -78,7 +84,8 @@ void CCamera::Update (float timestep) {
|
|||
glLoadIdentity ();
|
||||
glRotatef (-vpitch, 1.0, 0.0 , 0.0);
|
||||
glRotatef (-vhead, 0.0, 1.0 , 0.0);
|
||||
glTranslatef (-xview, -yview, -zview);
}
|
||||
glTranslatef (-xview, -yview, -zview);
|
||||
}
|
||||
|
||||
|
||||
CGluCamera::CGluCamera () {
|
||||
|
@ -114,7 +121,11 @@ static string char_dir;
|
|||
static string char_file;
|
||||
static string frame_file;
|
||||
|
||||
static float tdef_amb[] = {0.45, 0.53, 0.75, 1.0};
static float tdef_diff[] = {1.0, 0.9, 1.0, 1.0};
static float tdef_spec[] = {0.6, 0.6, 0.6, 1.0};
static float tdef_pos[] = {1, 2, 2, 0.0};
static TLight toollight;
|
||||
static float tdef_amb[] = {0.45, 0.53, 0.75, 1.0};
|
||||
static float tdef_diff[] = {1.0, 0.9, 1.0, 1.0};
|
||||
static float tdef_spec[] = {0.6, 0.6, 0.6, 1.0};
|
||||
static float tdef_pos[] = {1, 2, 2, 0.0};
|
||||
static TLight toollight;
|
||||
static int tool_mode = 0;
|
||||
|
||||
void DrawQuad (float x, float y, float w, float h,
|
||||
|
@ -140,7 +151,8 @@ void DrawChanged () {
|
|||
|
||||
void InitToolLight () {
|
||||
toollight.is_on = true;
|
||||
for (int i=0; i<4; i++) {
toollight.ambient[i] = tdef_amb[i];
|
||||
for (int i=0; i<4; i++) {
|
||||
toollight.ambient[i] = tdef_amb[i];
|
||||
toollight.diffuse[i] = tdef_diff[i];
|
||||
toollight.specular[i] = tdef_spec[i];
|
||||
toollight.position[i] = tdef_pos[i];
|
||||
|
|
3
tools.h
3
tools.h
|
@ -51,7 +51,8 @@ public:
|
|||
};
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// CGluCamera works with gluLookAt but is reduced to a simple
// go-around-camera that ist strictly focused on an object in
|
||||
// CGluCamera works with gluLookAt but is reduced to a simple
|
||||
// go-around-camera that ist strictly focused on an object in
|
||||
// identity position (0,0,0).
|
||||
class CGluCamera {
|
||||
private:
|
||||
|
|
|
@ -15,7 +15,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
GNU General Public License for more details.
|
||||
---------------------------------------------------------------------*/
|
||||
/* --------------------------------------------------------------------
|
||||
An name convention:
|
||||
An name convention:
|
||||
"lang" means the short identifier, e.g. "en_GB"
|
||||
"language" means the language name, e.g. "English"
|
||||
---------------------------------------------------------------------*/
|
||||
|
|
846
view.cpp
846
view.cpp
|
@ -1,424 +1,424 @@
|
|||
/* --------------------------------------------------------------------
|
||||
EXTREME TUXRACER
|
||||
|
||||
Copyright (C) 1999-2001 Jasmin F. Patry (Tuxracer)
|
||||
Copyright (C) 2010 Extreme Tuxracer Team
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
---------------------------------------------------------------------*/
|
||||
|
||||
#include "view.h"
|
||||
#include "course.h"
|
||||
/* --------------------------------------------------------------------
|
||||
EXTREME TUXRACER
|
||||
|
||||
Copyright (C) 1999-2001 Jasmin F. Patry (Tuxracer)
|
||||
Copyright (C) 2010 Extreme Tuxracer Team
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
---------------------------------------------------------------------*/
|
||||
|
||||
#include "view.h"
|
||||
#include "course.h"
|
||||
#include "ogl.h"
|
||||
#include "physics.h"
|
||||
|
||||
#define MIN_CAMERA_HEIGHT 1.5
|
||||
#define ABSOLUTE_MIN_CAMERA_HEIGHT 0.3
|
||||
#define CAMERA_ANGLE_ABOVE_SLOPE 10
|
||||
#define PLAYER_ANGLE_IN_CAMERA 20
|
||||
#define MAX_CAMERA_PITCH 40
|
||||
#define BEHIND_ORBIT_TIME_CONSTANT 0.06
|
||||
#define BEHIND_ORIENT_TIME_CONSTANT 0.06
|
||||
#define FOLLOW_ORBIT_TIME_CONSTANT 0.06
|
||||
#define FOLLOW_ORIENT_TIME_CONSTANT 0.06
|
||||
#define MAX_INTERPOLATION_VALUE 0.3
|
||||
#define BASELINE_INTERPOLATION_SPEED 4.5
|
||||
#define NO_INTERPOLATION_SPEED 2.0
|
||||
#define CAMERA_DISTANCE_INCREMENT 2
|
||||
|
||||
static TMatrix stationary_matrix;
|
||||
static bool is_stationary = false;
|
||||
static bool shall_stationary = false;
|
||||
|
||||
void SetStationaryCamera (bool stat) {
|
||||
if (stat == false) {
|
||||
is_stationary = false;
|
||||
shall_stationary = false;
|
||||
} else {
|
||||
shall_stationary = true;
|
||||
}
|
||||
}
|
||||
|
||||
static double camera_distance = 4.0;
|
||||
void IncCameraDistance (double timestep) {
|
||||
camera_distance += timestep * CAMERA_DISTANCE_INCREMENT;
|
||||
}
|
||||
|
||||
void SetCameraDistance (double val) {camera_distance = val;}
|
||||
|
||||
|
||||
void set_view_mode (CControl *ctrl, TViewMode mode) {ctrl->viewmode = mode;}
|
||||
|
||||
TVector3 interpolate_view_pos (TVector3 ctrl_pos1, TVector3 ctrl_pos2,
|
||||
double max_vec_angle,
|
||||
TVector3 pos1, TVector3 pos2,
|
||||
double dist, double dt,
|
||||
double time_constant)
|
||||
{
|
||||
static TVector3 y_vec(0.0, 1.0, 0.0);
|
||||
|
||||
TVector3 vec1 = SubtractVectors (pos1, ctrl_pos1);
|
||||
TVector3 vec2 = SubtractVectors (pos2, ctrl_pos2);
|
||||
|
||||
NormVector (vec1);
|
||||
NormVector (vec2);
|
||||
|
||||
TQuaternion q1 = MakeRotationQuaternion (y_vec, vec1);
|
||||
TQuaternion q2 = MakeRotationQuaternion (y_vec, vec2);
|
||||
double alpha = min (MAX_INTERPOLATION_VALUE, 1.0 - exp (-dt / time_constant));
|
||||
q2 = InterpolateQuaternions (q1, q2, alpha);
|
||||
|
||||
vec2 = RotateVector (q2, y_vec);
|
||||
double theta = RADIANS_TO_ANGLES (M_PI/2 - acos (DotProduct (vec2, y_vec)));
|
||||
if (theta > max_vec_angle) {
|
||||
TVector3 axis = CrossProduct (y_vec, vec2);
|
||||
NormVector (axis);
|
||||
TMatrix rot_mat;
|
||||
RotateAboutVectorMatrix (rot_mat, axis, theta-max_vec_angle);
|
||||
vec2 = TransformVector (rot_mat, vec2);
|
||||
}
|
||||
return AddVectors (ctrl_pos2, ScaleVector (dist, vec2));
|
||||
}
|
||||
|
||||
void interpolate_view_frame (TVector3 up1, TVector3 dir1,
|
||||
TVector3 *p_up2, TVector3 *p_dir2,
|
||||
double dt, double time_constant)
|
||||
{
|
||||
TMatrix cob_mat1, inv_cob_mat1;
|
||||
TMatrix cob_mat2, inv_cob_mat2;
|
||||
|
||||
TVector3 z1 = ScaleVector (-1.0, dir1);
|
||||
NormVector (z1);
|
||||
TVector3 y1 = ProjectToPlane (z1, up1);
|
||||
NormVector (y1);
|
||||
TVector3 x1 = CrossProduct (y1, z1);
|
||||
|
||||
MakeBasismatrix_Inv (cob_mat1, inv_cob_mat1, x1, y1, z1);
|
||||
TQuaternion q1 = MakeQuaternionFromMatrix (cob_mat1);
|
||||
TVector3 z2 = ScaleVector (-1.0, *p_dir2);
|
||||
NormVector (z2);
|
||||
TVector3 y2 = ProjectToPlane (z2, *p_up2);
|
||||
NormVector (y2);
|
||||
TVector3 x2 = CrossProduct (y2, z2);
|
||||
|
||||
MakeBasismatrix_Inv (cob_mat2, inv_cob_mat2, x2, y2, z2);
|
||||
TQuaternion q2 = MakeQuaternionFromMatrix (cob_mat2);
|
||||
double alpha = min (MAX_INTERPOLATION_VALUE, 1.0 - exp (-dt / time_constant));
|
||||
q2 = InterpolateQuaternions (q1, q2, alpha);
|
||||
MakeMatrixFromQuaternion (cob_mat2, q2);
|
||||
|
||||
p_up2->x = cob_mat2[1][0];
|
||||
p_up2->y = cob_mat2[1][1];
|
||||
p_up2->z = cob_mat2[1][2];
|
||||
|
||||
p_dir2->x = -cob_mat2[2][0];
|
||||
p_dir2->y = -cob_mat2[2][1];
|
||||
p_dir2->z = -cob_mat2[2][2];
|
||||
}
|
||||
|
||||
void setup_view_matrix (CControl *ctrl, bool save_mat) {
|
||||
TMatrix view_mat;
|
||||
|
||||
TVector3 view_z = ScaleVector (-1, ctrl->viewdir);
|
||||
TVector3 view_x = CrossProduct (ctrl->viewup, view_z);
|
||||
TVector3 view_y = CrossProduct (view_z, view_x);
|
||||
NormVector (view_z);
|
||||
NormVector (view_x);
|
||||
NormVector (view_y);
|
||||
|
||||
MakeIdentityMatrix (ctrl->view_mat);
|
||||
|
||||
ctrl->view_mat[0][0] = view_x.x;
|
||||
ctrl->view_mat[0][1] = view_x.y;
|
||||
ctrl->view_mat[0][2] = view_x.z;
|
||||
|
||||
ctrl->view_mat[1][0] = view_y.x;
|
||||
ctrl->view_mat[1][1] = view_y.y;
|
||||
ctrl->view_mat[1][2] = view_y.z;
|
||||
|
||||
ctrl->view_mat[2][0] = view_z.x;
|
||||
ctrl->view_mat[2][1] = view_z.y;
|
||||
ctrl->view_mat[2][2] = view_z.z;
|
||||
|
||||
ctrl->view_mat[3][0] = ctrl->viewpos.x;
|
||||
ctrl->view_mat[3][1] = ctrl->viewpos.y;
|
||||
ctrl->view_mat[3][2] = ctrl->viewpos.z;
|
||||
ctrl->view_mat[3][3] = 1;
|
||||
|
||||
TransposeMatrix (ctrl->view_mat, view_mat);
|
||||
|
||||
view_mat[0][3] = 0;
|
||||
view_mat[1][3] = 0;
|
||||
view_mat[2][3] = 0;
|
||||
|
||||
TVector3 viewpt_in_view_frame = TransformPoint (view_mat, ctrl->viewpos);
|
||||
|
||||
view_mat[3][0] = -viewpt_in_view_frame.x;
|
||||
view_mat[3][1] = -viewpt_in_view_frame.y;
|
||||
view_mat[3][2] = -viewpt_in_view_frame.z;
|
||||
|
||||
if (save_mat) {
|
||||
memcpy(stationary_matrix, view_mat, 16*sizeof(**view_mat));
|
||||
}
|
||||
glLoadIdentity();
|
||||
glMultMatrixd ((double*) view_mat);
|
||||
}
|
||||
|
||||
TVector3 MakeViewVector () {
|
||||
double course_angle = Course.GetCourseAngle();
|
||||
double rad = ANGLES_TO_RADIANS (
|
||||
course_angle -
|
||||
CAMERA_ANGLE_ABOVE_SLOPE +
|
||||
PLAYER_ANGLE_IN_CAMERA);
|
||||
TVector3 res(0, sin(rad), cos(rad));
|
||||
return ScaleVector (camera_distance, res);
|
||||
}
|
||||
|
||||
void update_view (CControl *ctrl, double dt) {
|
||||
if (is_stationary) {
|
||||
glLoadIdentity();
|
||||
glMultMatrixd ((double*) stationary_matrix);
|
||||
return;
|
||||
}
|
||||
|
||||
TVector3 view_pt(0,0,0);
|
||||
TVector3 view_dir;
|
||||
TMatrix rot_mat;
|
||||
|
||||
static const TVector3 y_vec(0.0, 1.0, 0.0);
|
||||
static const TVector3 mz_vec(0.0, 0.0, -1.0);
|
||||
|
||||
TVector3 vel_cpy = ctrl->cvel;
|
||||
double speed = NormVector (vel_cpy);
|
||||
double time_constant_mult = 1.0 /
|
||||
min (1.0, max (0.0,
|
||||
(speed - NO_INTERPOLATION_SPEED) /
|
||||
(BASELINE_INTERPOLATION_SPEED - NO_INTERPOLATION_SPEED)));
|
||||
|
||||
TVector3 vel_dir = ctrl->cvel;
|
||||
NormVector (vel_dir);
|
||||
double course_angle = Course.GetCourseAngle();
|
||||
|
||||
switch (ctrl->viewmode) {
|
||||
case BEHIND: {
|
||||
TVector3 view_vec = MakeViewVector ();
|
||||
|
||||
TVector3 vel_proj = ProjectToPlane (y_vec, vel_dir);
|
||||
NormVector (vel_proj);
|
||||
TQuaternion rot_quat = MakeRotationQuaternion (mz_vec, vel_proj);
|
||||
view_vec = RotateVector (rot_quat, view_vec);
|
||||
view_pt = AddVectors (ctrl->cpos, view_vec);
|
||||
double ycoord = Course.FindYCoord (view_pt.x, view_pt.z);
|
||||
|
||||
if (view_pt.y < ycoord + MIN_CAMERA_HEIGHT) {
|
||||
view_pt.y = ycoord + MIN_CAMERA_HEIGHT;
|
||||
}
|
||||
|
||||
if (ctrl->view_init) {
|
||||
for (int i=0; i<2; i++) {
|
||||
view_pt = interpolate_view_pos (ctrl->cpos, ctrl->cpos,
|
||||
MAX_CAMERA_PITCH, ctrl->viewpos,
|
||||
view_pt, camera_distance, dt,
|
||||
BEHIND_ORBIT_TIME_CONSTANT *
|
||||
time_constant_mult);
|
||||
}
|
||||
}
|
||||
|
||||
ycoord = Course.FindYCoord (view_pt.x, view_pt.z);
|
||||
if (view_pt.y < ycoord + ABSOLUTE_MIN_CAMERA_HEIGHT) {
|
||||
view_pt.y = ycoord + ABSOLUTE_MIN_CAMERA_HEIGHT;
|
||||
}
|
||||
|
||||
view_vec = SubtractVectors (view_pt, ctrl->cpos);
|
||||
TVector3 axis = CrossProduct (y_vec, view_vec);
|
||||
NormVector (axis);
|
||||
RotateAboutVectorMatrix (rot_mat, axis, PLAYER_ANGLE_IN_CAMERA);
|
||||
view_dir = ScaleVector (-1.0, TransformVector (rot_mat, view_vec));
|
||||
|
||||
if (ctrl->view_init) {
|
||||
for (int i=0; i<2; i++) {
|
||||
TVector3 up_dir(0, 1, 0);
|
||||
interpolate_view_frame (ctrl->viewup, ctrl->viewdir,
|
||||
&up_dir, &view_dir, dt,
|
||||
BEHIND_ORIENT_TIME_CONSTANT);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case FOLLOW: { // normale Einstellung
|
||||
TVector3 view_vec = MakeViewVector ();
|
||||
|
||||
TVector3 vel_proj = ProjectToPlane (y_vec, vel_dir);
|
||||
NormVector (vel_proj);
|
||||
TQuaternion rot_quat = MakeRotationQuaternion (mz_vec, vel_proj);
|
||||
view_vec = RotateVector (rot_quat, view_vec);
|
||||
view_pt = AddVectors (ctrl->cpos, view_vec);
|
||||
double ycoord = Course.FindYCoord (view_pt.x, view_pt.z);
|
||||
if (view_pt.y < ycoord + MIN_CAMERA_HEIGHT) {
|
||||
view_pt.y = ycoord + MIN_CAMERA_HEIGHT;
|
||||
}
|
||||
|
||||
if (ctrl->view_init) {
|
||||
for (int i=0; i<2; i++) {
|
||||
view_pt = interpolate_view_pos (ctrl->plyr_pos, ctrl->cpos,
|
||||
MAX_CAMERA_PITCH, ctrl->viewpos,
|
||||
view_pt, camera_distance, dt,
|
||||
FOLLOW_ORBIT_TIME_CONSTANT *
|
||||
time_constant_mult);
|
||||
}
|
||||
}
|
||||
ycoord = Course.FindYCoord (view_pt.x, view_pt.z);
|
||||
if (view_pt.y < ycoord + ABSOLUTE_MIN_CAMERA_HEIGHT) {
|
||||
view_pt.y = ycoord + ABSOLUTE_MIN_CAMERA_HEIGHT;
|
||||
}
|
||||
|
||||
view_vec = SubtractVectors (view_pt, ctrl->cpos);
|
||||
TVector3 axis = CrossProduct (y_vec, view_vec);
|
||||
NormVector (axis);
|
||||
RotateAboutVectorMatrix (rot_mat, axis,
|
||||
PLAYER_ANGLE_IN_CAMERA);
|
||||
view_dir = ScaleVector (-1.0,
|
||||
TransformVector (rot_mat, view_vec));
|
||||
|
||||
if (ctrl->view_init) {
|
||||
for (int i=0; i<2; i++) {
|
||||
TVector3 up_dir(0, 1, 0);
|
||||
interpolate_view_frame (ctrl->viewup, ctrl->viewdir,
|
||||
&up_dir, &view_dir, dt,
|
||||
FOLLOW_ORIENT_TIME_CONSTANT);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ABOVE: {
|
||||
TVector3 view_vec = MakeViewVector ();
|
||||
view_pt = AddVectors (ctrl->cpos, view_vec);
|
||||
double ycoord = Course.FindYCoord (view_pt.x, view_pt.z);
|
||||
if (view_pt.y < ycoord + MIN_CAMERA_HEIGHT) {
|
||||
view_pt.y = ycoord + MIN_CAMERA_HEIGHT;
|
||||
}
|
||||
|
||||
view_vec = SubtractVectors (view_pt, ctrl->cpos);
|
||||
MakeRotationMatrix (rot_mat, PLAYER_ANGLE_IN_CAMERA, 'x');
|
||||
view_dir = ScaleVector (-1.0,
|
||||
TransformVector (rot_mat, view_vec));
|
||||
break;
|
||||
}
|
||||
|
||||
default: Message ("code not reached", ""); return;
|
||||
}
|
||||
|
||||
|
||||
ctrl->viewpos = view_pt;
|
||||
ctrl->viewdir = view_dir;
|
||||
ctrl->viewup = TVector3(0, 1, 0);
|
||||
ctrl->plyr_pos = ctrl->cpos;
|
||||
ctrl->view_init = true;
|
||||
|
||||
if (shall_stationary) {
|
||||
setup_view_matrix (ctrl, true);
|
||||
is_stationary = true;
|
||||
} else {
|
||||
setup_view_matrix (ctrl, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// viewfrustum
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
static TPlane frustum_planes[6];
|
||||
static char p_vertex_code[6];
|
||||
|
||||
|
||||
void SetupViewFrustum (CControl *ctrl) {
|
||||
double aspect = (double) param.x_resolution /param.y_resolution;
|
||||
|
||||
double near_dist = NEAR_CLIP_DIST;
|
||||
double far_dist = param.forward_clip_distance;
|
||||
TVector3 origin(0., 0., 0.);
|
||||
double half_fov = ANGLES_TO_RADIANS (param.fov * 0.5);
|
||||
double half_fov_horiz = atan (tan (half_fov) * aspect);
|
||||
|
||||
frustum_planes[0] = MakePlane (0, 0, 1, near_dist);
|
||||
frustum_planes[1] = MakePlane (0, 0, -1, -far_dist);
|
||||
frustum_planes[2]
|
||||
= MakePlane (-cos(half_fov_horiz), 0, sin(half_fov_horiz), 0);
|
||||
frustum_planes[3]
|
||||
= MakePlane (cos(half_fov_horiz), 0, sin(half_fov_horiz), 0);
|
||||
frustum_planes[4]
|
||||
= MakePlane (0, cos(half_fov), sin(half_fov), 0);
|
||||
frustum_planes[5]
|
||||
= MakePlane (0, -cos(half_fov), sin(half_fov), 0);
|
||||
|
||||
for (int i=0; i<6; i++) {
|
||||
TVector3 pt = TransformPoint (ctrl->view_mat,
|
||||
AddVectors (origin, ScaleVector (
|
||||
-frustum_planes[i].d, frustum_planes[i].nml)));
|
||||
|
||||
frustum_planes[i].nml = TransformVector (
|
||||
ctrl->view_mat, frustum_planes[i].nml);
|
||||
|
||||
frustum_planes[i].d = -DotProduct (
|
||||
frustum_planes[i].nml,
|
||||
SubtractVectors (pt, origin));
|
||||
}
|
||||
|
||||
for (int i=0; i<6; i++) {
|
||||
p_vertex_code[i] = 0;
|
||||
|
||||
if (frustum_planes[i].nml.x > 0) p_vertex_code[i] |= 4;
|
||||
if (frustum_planes[i].nml.y > 0) p_vertex_code[i] |= 2;
|
||||
if (frustum_planes[i].nml.z > 0) p_vertex_code[i] |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
clip_result_t clip_aabb_to_view_frustum (const TVector3& min, const TVector3& max) {
|
||||
bool intersect = false;
|
||||
|
||||
for (int i=0; i<6; i++) {
|
||||
TVector3 p(min.x, min.y, min.z);
|
||||
TVector3 n(max.x, max.y, max.z);
|
||||
|
||||
if (p_vertex_code[i] & 4) {
|
||||
p.x = max.x;
|
||||
n.x = min.x;
|
||||
}
|
||||
|
||||
if (p_vertex_code[i] & 2) {
|
||||
p.y = max.y;
|
||||
n.y = min.y;
|
||||
}
|
||||
|
||||
if (p_vertex_code[i] & 1) {
|
||||
p.z = max.z;
|
||||
n.z = min.z;
|
||||
}
|
||||
|
||||
if (DotProduct (n, frustum_planes[i].nml) + frustum_planes[i].d > 0){
|
||||
return NotVisible;
|
||||
}
|
||||
|
||||
if (DotProduct (p, frustum_planes[i].nml) + frustum_planes[i].d > 0){
|
||||
intersect = true;
|
||||
}
|
||||
}
|
||||
if (intersect) return SomeClip;
|
||||
return NoClip;
|
||||
}
|
||||
|
||||
const TPlane& get_far_clip_plane() {return frustum_planes[1]; }
|
||||
const TPlane& get_left_clip_plane() {return frustum_planes[2]; }
|
||||
const TPlane& get_right_clip_plane() {return frustum_planes[3]; }
|
||||
const TPlane& get_bottom_clip_plane() {return frustum_planes[5]; }
|
||||
#include "physics.h"
|
||||
|
||||
#define MIN_CAMERA_HEIGHT 1.5
|
||||
#define ABSOLUTE_MIN_CAMERA_HEIGHT 0.3
|
||||
#define CAMERA_ANGLE_ABOVE_SLOPE 10
|
||||
#define PLAYER_ANGLE_IN_CAMERA 20
|
||||
#define MAX_CAMERA_PITCH 40
|
||||
#define BEHIND_ORBIT_TIME_CONSTANT 0.06
|
||||
#define BEHIND_ORIENT_TIME_CONSTANT 0.06
|
||||
#define FOLLOW_ORBIT_TIME_CONSTANT 0.06
|
||||
#define FOLLOW_ORIENT_TIME_CONSTANT 0.06
|
||||
#define MAX_INTERPOLATION_VALUE 0.3
|
||||
#define BASELINE_INTERPOLATION_SPEED 4.5
|
||||
#define NO_INTERPOLATION_SPEED 2.0
|
||||
#define CAMERA_DISTANCE_INCREMENT 2
|
||||
|
||||
static TMatrix stationary_matrix;
|
||||
static bool is_stationary = false;
|
||||
static bool shall_stationary = false;
|
||||
|
||||
void SetStationaryCamera (bool stat) {
|
||||
if (stat == false) {
|
||||
is_stationary = false;
|
||||
shall_stationary = false;
|
||||
} else {
|
||||
shall_stationary = true;
|
||||
}
|
||||
}
|
||||
|
||||
static double camera_distance = 4.0;
|
||||
void IncCameraDistance (double timestep) {
|
||||
camera_distance += timestep * CAMERA_DISTANCE_INCREMENT;
|
||||
}
|
||||
|
||||
void SetCameraDistance (double val) {camera_distance = val;}
|
||||
|
||||
|
||||
void set_view_mode (CControl *ctrl, TViewMode mode) {ctrl->viewmode = mode;}
|
||||
|
||||
TVector3 interpolate_view_pos (TVector3 ctrl_pos1, TVector3 ctrl_pos2,
|
||||
double max_vec_angle,
|
||||
TVector3 pos1, TVector3 pos2,
|
||||
double dist, double dt,
|
||||
double time_constant)
|
||||
{
|
||||
static TVector3 y_vec(0.0, 1.0, 0.0);
|
||||
|
||||
TVector3 vec1 = SubtractVectors (pos1, ctrl_pos1);
|
||||
TVector3 vec2 = SubtractVectors (pos2, ctrl_pos2);
|
||||
|
||||
NormVector (vec1);
|
||||
NormVector (vec2);
|
||||
|
||||
TQuaternion q1 = MakeRotationQuaternion (y_vec, vec1);
|
||||
TQuaternion q2 = MakeRotationQuaternion (y_vec, vec2);
|
||||
double alpha = min (MAX_INTERPOLATION_VALUE, 1.0 - exp (-dt / time_constant));
|
||||
q2 = InterpolateQuaternions (q1, q2, alpha);
|
||||
|
||||
vec2 = RotateVector (q2, y_vec);
|
||||
double theta = RADIANS_TO_ANGLES (M_PI/2 - acos (DotProduct (vec2, y_vec)));
|
||||
if (theta > max_vec_angle) {
|
||||
TVector3 axis = CrossProduct (y_vec, vec2);
|
||||
NormVector (axis);
|
||||
TMatrix rot_mat;
|
||||
RotateAboutVectorMatrix (rot_mat, axis, theta-max_vec_angle);
|
||||
vec2 = TransformVector (rot_mat, vec2);
|
||||
}
|
||||
return AddVectors (ctrl_pos2, ScaleVector (dist, vec2));
|
||||
}
|
||||
|
||||
void interpolate_view_frame (TVector3 up1, TVector3 dir1,
|
||||
TVector3 *p_up2, TVector3 *p_dir2,
|
||||
double dt, double time_constant)
|
||||
{
|
||||
TMatrix cob_mat1, inv_cob_mat1;
|
||||
TMatrix cob_mat2, inv_cob_mat2;
|
||||
|
||||
TVector3 z1 = ScaleVector (-1.0, dir1);
|
||||
NormVector (z1);
|
||||
TVector3 y1 = ProjectToPlane (z1, up1);
|
||||
NormVector (y1);
|
||||
TVector3 x1 = CrossProduct (y1, z1);
|
||||
|
||||
MakeBasismatrix_Inv (cob_mat1, inv_cob_mat1, x1, y1, z1);
|
||||
TQuaternion q1 = MakeQuaternionFromMatrix (cob_mat1);
|
||||
TVector3 z2 = ScaleVector (-1.0, *p_dir2);
|
||||
NormVector (z2);
|
||||
TVector3 y2 = ProjectToPlane (z2, *p_up2);
|
||||
NormVector (y2);
|
||||
TVector3 x2 = CrossProduct (y2, z2);
|
||||
|
||||
MakeBasismatrix_Inv (cob_mat2, inv_cob_mat2, x2, y2, z2);
|
||||
TQuaternion q2 = MakeQuaternionFromMatrix (cob_mat2);
|
||||
double alpha = min (MAX_INTERPOLATION_VALUE, 1.0 - exp (-dt / time_constant));
|
||||
q2 = InterpolateQuaternions (q1, q2, alpha);
|
||||
MakeMatrixFromQuaternion (cob_mat2, q2);
|
||||
|
||||
p_up2->x = cob_mat2[1][0];
|
||||
p_up2->y = cob_mat2[1][1];
|
||||
p_up2->z = cob_mat2[1][2];
|
||||
|
||||
p_dir2->x = -cob_mat2[2][0];
|
||||
p_dir2->y = -cob_mat2[2][1];
|
||||
p_dir2->z = -cob_mat2[2][2];
|
||||
}
|
||||
|
||||
void setup_view_matrix (CControl *ctrl, bool save_mat) {
|
||||
TMatrix view_mat;
|
||||
|
||||
TVector3 view_z = ScaleVector (-1, ctrl->viewdir);
|
||||
TVector3 view_x = CrossProduct (ctrl->viewup, view_z);
|
||||
TVector3 view_y = CrossProduct (view_z, view_x);
|
||||
NormVector (view_z);
|
||||
NormVector (view_x);
|
||||
NormVector (view_y);
|
||||
|
||||
MakeIdentityMatrix (ctrl->view_mat);
|
||||
|
||||
ctrl->view_mat[0][0] = view_x.x;
|
||||
ctrl->view_mat[0][1] = view_x.y;
|
||||
ctrl->view_mat[0][2] = view_x.z;
|
||||
|
||||
ctrl->view_mat[1][0] = view_y.x;
|
||||
ctrl->view_mat[1][1] = view_y.y;
|
||||
ctrl->view_mat[1][2] = view_y.z;
|
||||
|
||||
ctrl->view_mat[2][0] = view_z.x;
|
||||
ctrl->view_mat[2][1] = view_z.y;
|
||||
ctrl->view_mat[2][2] = view_z.z;
|
||||
|
||||
ctrl->view_mat[3][0] = ctrl->viewpos.x;
|
||||
ctrl->view_mat[3][1] = ctrl->viewpos.y;
|
||||
ctrl->view_mat[3][2] = ctrl->viewpos.z;
|
||||
ctrl->view_mat[3][3] = 1;
|
||||
|
||||
TransposeMatrix (ctrl->view_mat, view_mat);
|
||||
|
||||
view_mat[0][3] = 0;
|
||||
view_mat[1][3] = 0;
|
||||
view_mat[2][3] = 0;
|
||||
|
||||
TVector3 viewpt_in_view_frame = TransformPoint (view_mat, ctrl->viewpos);
|
||||
|
||||
view_mat[3][0] = -viewpt_in_view_frame.x;
|
||||
view_mat[3][1] = -viewpt_in_view_frame.y;
|
||||
view_mat[3][2] = -viewpt_in_view_frame.z;
|
||||
|
||||
if (save_mat) {
|
||||
memcpy(stationary_matrix, view_mat, 16*sizeof(**view_mat));
|
||||
}
|
||||
glLoadIdentity();
|
||||
glMultMatrixd ((double*) view_mat);
|
||||
}
|
||||
|
||||
TVector3 MakeViewVector () {
|
||||
double course_angle = Course.GetCourseAngle();
|
||||
double rad = ANGLES_TO_RADIANS (
|
||||
course_angle -
|
||||
CAMERA_ANGLE_ABOVE_SLOPE +
|
||||
PLAYER_ANGLE_IN_CAMERA);
|
||||
TVector3 res(0, sin(rad), cos(rad));
|
||||
return ScaleVector (camera_distance, res);
|
||||
}
|
||||
|
||||
void update_view (CControl *ctrl, double dt) {
|
||||
if (is_stationary) {
|
||||
glLoadIdentity();
|
||||
glMultMatrixd ((double*) stationary_matrix);
|
||||
return;
|
||||
}
|
||||
|
||||
TVector3 view_pt(0,0,0);
|
||||
TVector3 view_dir;
|
||||
TMatrix rot_mat;
|
||||
|
||||
static const TVector3 y_vec(0.0, 1.0, 0.0);
|
||||
static const TVector3 mz_vec(0.0, 0.0, -1.0);
|
||||
|
||||
TVector3 vel_cpy = ctrl->cvel;
|
||||
double speed = NormVector (vel_cpy);
|
||||
double time_constant_mult = 1.0 /
|
||||
min (1.0, max (0.0,
|
||||
(speed - NO_INTERPOLATION_SPEED) /
|
||||
(BASELINE_INTERPOLATION_SPEED - NO_INTERPOLATION_SPEED)));
|
||||
|
||||
TVector3 vel_dir = ctrl->cvel;
|
||||
NormVector (vel_dir);
|
||||
double course_angle = Course.GetCourseAngle();
|
||||
|
||||
switch (ctrl->viewmode) {
|
||||
case BEHIND: {
|
||||
TVector3 view_vec = MakeViewVector ();
|
||||
|
||||
TVector3 vel_proj = ProjectToPlane (y_vec, vel_dir);
|
||||
NormVector (vel_proj);
|
||||
TQuaternion rot_quat = MakeRotationQuaternion (mz_vec, vel_proj);
|
||||
view_vec = RotateVector (rot_quat, view_vec);
|
||||
view_pt = AddVectors (ctrl->cpos, view_vec);
|
||||
double ycoord = Course.FindYCoord (view_pt.x, view_pt.z);
|
||||
|
||||
if (view_pt.y < ycoord + MIN_CAMERA_HEIGHT) {
|
||||
view_pt.y = ycoord + MIN_CAMERA_HEIGHT;
|
||||
}
|
||||
|
||||
if (ctrl->view_init) {
|
||||
for (int i=0; i<2; i++) {
|
||||
view_pt = interpolate_view_pos (ctrl->cpos, ctrl->cpos,
|
||||
MAX_CAMERA_PITCH, ctrl->viewpos,
|
||||
view_pt, camera_distance, dt,
|
||||
BEHIND_ORBIT_TIME_CONSTANT *
|
||||
time_constant_mult);
|
||||
}
|
||||
}
|
||||
|
||||
ycoord = Course.FindYCoord (view_pt.x, view_pt.z);
|
||||
if (view_pt.y < ycoord + ABSOLUTE_MIN_CAMERA_HEIGHT) {
|
||||
view_pt.y = ycoord + ABSOLUTE_MIN_CAMERA_HEIGHT;
|
||||
}
|
||||
|
||||
view_vec = SubtractVectors (view_pt, ctrl->cpos);
|
||||
TVector3 axis = CrossProduct (y_vec, view_vec);
|
||||
NormVector (axis);
|
||||
RotateAboutVectorMatrix (rot_mat, axis, PLAYER_ANGLE_IN_CAMERA);
|
||||
view_dir = ScaleVector (-1.0, TransformVector (rot_mat, view_vec));
|
||||
|
||||
if (ctrl->view_init) {
|
||||
for (int i=0; i<2; i++) {
|
||||
TVector3 up_dir(0, 1, 0);
|
||||
interpolate_view_frame (ctrl->viewup, ctrl->viewdir,
|
||||
&up_dir, &view_dir, dt,
|
||||
BEHIND_ORIENT_TIME_CONSTANT);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case FOLLOW: { // normale Einstellung
|
||||
TVector3 view_vec = MakeViewVector ();
|
||||
|
||||
TVector3 vel_proj = ProjectToPlane (y_vec, vel_dir);
|
||||
NormVector (vel_proj);
|
||||
TQuaternion rot_quat = MakeRotationQuaternion (mz_vec, vel_proj);
|
||||
view_vec = RotateVector (rot_quat, view_vec);
|
||||
view_pt = AddVectors (ctrl->cpos, view_vec);
|
||||
double ycoord = Course.FindYCoord (view_pt.x, view_pt.z);
|
||||
if (view_pt.y < ycoord + MIN_CAMERA_HEIGHT) {
|
||||
view_pt.y = ycoord + MIN_CAMERA_HEIGHT;
|
||||
}
|
||||
|
||||
if (ctrl->view_init) {
|
||||
for (int i=0; i<2; i++) {
|
||||
view_pt = interpolate_view_pos (ctrl->plyr_pos, ctrl->cpos,
|
||||
MAX_CAMERA_PITCH, ctrl->viewpos,
|
||||
view_pt, camera_distance, dt,
|
||||
FOLLOW_ORBIT_TIME_CONSTANT *
|
||||
time_constant_mult);
|
||||
}
|
||||
}
|
||||
ycoord = Course.FindYCoord (view_pt.x, view_pt.z);
|
||||
if (view_pt.y < ycoord + ABSOLUTE_MIN_CAMERA_HEIGHT) {
|
||||
view_pt.y = ycoord + ABSOLUTE_MIN_CAMERA_HEIGHT;
|
||||
}
|
||||
|
||||
view_vec = SubtractVectors (view_pt, ctrl->cpos);
|
||||
TVector3 axis = CrossProduct (y_vec, view_vec);
|
||||
NormVector (axis);
|
||||
RotateAboutVectorMatrix (rot_mat, axis,
|
||||
PLAYER_ANGLE_IN_CAMERA);
|
||||
view_dir = ScaleVector (-1.0,
|
||||
TransformVector (rot_mat, view_vec));
|
||||
|
||||
if (ctrl->view_init) {
|
||||
for (int i=0; i<2; i++) {
|
||||
TVector3 up_dir(0, 1, 0);
|
||||
interpolate_view_frame (ctrl->viewup, ctrl->viewdir,
|
||||
&up_dir, &view_dir, dt,
|
||||
FOLLOW_ORIENT_TIME_CONSTANT);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ABOVE: {
|
||||
TVector3 view_vec = MakeViewVector ();
|
||||
view_pt = AddVectors (ctrl->cpos, view_vec);
|
||||
double ycoord = Course.FindYCoord (view_pt.x, view_pt.z);
|
||||
if (view_pt.y < ycoord + MIN_CAMERA_HEIGHT) {
|
||||
view_pt.y = ycoord + MIN_CAMERA_HEIGHT;
|
||||
}
|
||||
|
||||
view_vec = SubtractVectors (view_pt, ctrl->cpos);
|
||||
MakeRotationMatrix (rot_mat, PLAYER_ANGLE_IN_CAMERA, 'x');
|
||||
view_dir = ScaleVector (-1.0,
|
||||
TransformVector (rot_mat, view_vec));
|
||||
break;
|
||||
}
|
||||
|
||||
default: Message ("code not reached", ""); return;
|
||||
}
|
||||
|
||||
|
||||
ctrl->viewpos = view_pt;
|
||||
ctrl->viewdir = view_dir;
|
||||
ctrl->viewup = TVector3(0, 1, 0);
|
||||
ctrl->plyr_pos = ctrl->cpos;
|
||||
ctrl->view_init = true;
|
||||
|
||||
if (shall_stationary) {
|
||||
setup_view_matrix (ctrl, true);
|
||||
is_stationary = true;
|
||||
} else {
|
||||
setup_view_matrix (ctrl, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// viewfrustum
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
static TPlane frustum_planes[6];
|
||||
static char p_vertex_code[6];
|
||||
|
||||
|
||||
void SetupViewFrustum (CControl *ctrl) {
|
||||
double aspect = (double) param.x_resolution /param.y_resolution;
|
||||
|
||||
double near_dist = NEAR_CLIP_DIST;
|
||||
double far_dist = param.forward_clip_distance;
|
||||
TVector3 origin(0., 0., 0.);
|
||||
double half_fov = ANGLES_TO_RADIANS (param.fov * 0.5);
|
||||
double half_fov_horiz = atan (tan (half_fov) * aspect);
|
||||
|
||||
frustum_planes[0] = MakePlane (0, 0, 1, near_dist);
|
||||
frustum_planes[1] = MakePlane (0, 0, -1, -far_dist);
|
||||
frustum_planes[2]
|
||||
= MakePlane (-cos(half_fov_horiz), 0, sin(half_fov_horiz), 0);
|
||||
frustum_planes[3]
|
||||
= MakePlane (cos(half_fov_horiz), 0, sin(half_fov_horiz), 0);
|
||||
frustum_planes[4]
|
||||
= MakePlane (0, cos(half_fov), sin(half_fov), 0);
|
||||
frustum_planes[5]
|
||||
= MakePlane (0, -cos(half_fov), sin(half_fov), 0);
|
||||
|
||||
for (int i=0; i<6; i++) {
|
||||
TVector3 pt = TransformPoint (ctrl->view_mat,
|
||||
AddVectors (origin, ScaleVector (
|
||||
-frustum_planes[i].d, frustum_planes[i].nml)));
|
||||
|
||||
frustum_planes[i].nml = TransformVector (
|
||||
ctrl->view_mat, frustum_planes[i].nml);
|
||||
|
||||
frustum_planes[i].d = -DotProduct (
|
||||
frustum_planes[i].nml,
|
||||
SubtractVectors (pt, origin));
|
||||
}
|
||||
|
||||
for (int i=0; i<6; i++) {
|
||||
p_vertex_code[i] = 0;
|
||||
|
||||
if (frustum_planes[i].nml.x > 0) p_vertex_code[i] |= 4;
|
||||
if (frustum_planes[i].nml.y > 0) p_vertex_code[i] |= 2;
|
||||
if (frustum_planes[i].nml.z > 0) p_vertex_code[i] |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
clip_result_t clip_aabb_to_view_frustum (const TVector3& min, const TVector3& max) {
|
||||
bool intersect = false;
|
||||
|
||||
for (int i=0; i<6; i++) {
|
||||
TVector3 p(min.x, min.y, min.z);
|
||||
TVector3 n(max.x, max.y, max.z);
|
||||
|
||||
if (p_vertex_code[i] & 4) {
|
||||
p.x = max.x;
|
||||
n.x = min.x;
|
||||
}
|
||||
|
||||
if (p_vertex_code[i] & 2) {
|
||||
p.y = max.y;
|
||||
n.y = min.y;
|
||||
}
|
||||
|
||||
if (p_vertex_code[i] & 1) {
|
||||
p.z = max.z;
|
||||
n.z = min.z;
|
||||
}
|
||||
|
||||
if (DotProduct (n, frustum_planes[i].nml) + frustum_planes[i].d > 0){
|
||||
return NotVisible;
|
||||
}
|
||||
|
||||
if (DotProduct (p, frustum_planes[i].nml) + frustum_planes[i].d > 0){
|
||||
intersect = true;
|
||||
}
|
||||
}
|
||||
if (intersect) return SomeClip;
|
||||
return NoClip;
|
||||
}
|
||||
|
||||
const TPlane& get_far_clip_plane() {return frustum_planes[1]; }
|
||||
const TPlane& get_left_clip_plane() {return frustum_planes[2]; }
|
||||
const TPlane& get_right_clip_plane() {return frustum_planes[3]; }
|
||||
const TPlane& get_bottom_clip_plane() {return frustum_planes[5]; }
|
||||
|
|
4
winsys.h
4
winsys.h
|
@ -28,7 +28,7 @@ private:
|
|||
float elapsed_time;
|
||||
|
||||
// joystick
|
||||
SDL_Joystick *joystick;
|
||||
SDL_Joystick *joystick;
|
||||
int numJoysticks;
|
||||
bool joystick_active;
|
||||
|
||||
|
@ -59,7 +59,7 @@ public:
|
|||
void InitJoystick ();
|
||||
void CloseJoystick ();
|
||||
bool joystick_isActive() const { return joystick_active; }
|
||||
double ClockTime () {return SDL_GetTicks() * 1.e-3; }
|
||||
double ClockTime () {return SDL_GetTicks() * 1.e-3; }
|
||||
// SDL_Surface *GetSurfaceData ();
|
||||
unsigned char *GetSurfaceData ();
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue