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-35b55e6d67a3
master
pkeus 2013-06-11 18:07:30 +00:00
parent 2ba849018f
commit a10cdbd9ba
36 changed files with 1001 additions and 809 deletions

View File

@ -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);

View File

@ -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));

View File

@ -32,4 +32,4 @@ public:
extern CGameConfig GameConfig;
#endif
#endif

View File

@ -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();
} }
}
}

View File

@ -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
View File

@ -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*

View File

@ -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];

View File

@ -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

View File

@ -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;
}
}

View File

@ -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
View File

@ -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);

View File

@ -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) {

View File

@ -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;
}

View File

@ -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
View File

@ -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
View File

@ -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 );

View File

@ -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);
*/

View File

@ -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;

View File

@ -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,

View File

@ -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 ();
}
}

View File

@ -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);
}

View File

@ -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();

View File

@ -32,4 +32,4 @@ public:
extern CRaceSelect RaceSelect;
#endif
#endif

View File

@ -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 ();

View File

@ -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 ();

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -29,6 +29,5 @@ void CharMotion (int x, int y);
void RenderChar (double timestep);
void StoreAction (TCharAction *act);
#endif
#endif

View File

@ -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

View File

@ -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];

View File

@ -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:

View File

@ -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
View File

@ -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]; }

View File

@ -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 ();
};