Merged revision(s) 478-482 from branches/SFML2:

Refactorizations:
- Avoid duplicating object properties
- Avoid adding literals - apparently this is not optimized by some compilers
- Use STL containern to store vertices in TPolygon
- Formatted with AStyle 2.04
........
Use STL in Polyhedrons, reduced redundant data storage in game_ctrl
........
Use pointers instead of indices in several places
........
Code and data cleanup:
- Cleaned up textures: Keept only those in /data/textures that are currently needed by the game. Resized several textures to remove empty space
- Refactored HUD, fixed bug in wind display when racing upwards the hill
- Removed apparently unnecessary environment box rendering in quadtree code, improving framerate during race
........
Added perf_level 4: Use High resolution textures for skybox.
........



git-svn-id: https://svn.code.sf.net/p/extremetuxracer/code/trunk@483 0420edf4-82e4-42fc-9478-35b55e6d67a3
master
pkeus 2013-11-27 20:45:32 +00:00
parent 5f56174c44
commit f6e2bf399a
82 changed files with 455 additions and 643 deletions

View File

@ -1,2 +1,2 @@
[location] etr [sunny] 1 [cloudy] 1 [evening] 1 [night] 1
[location] tuxracer [sunny] 1 [cloudy] 1 [evening] 1 [night] 1
[location] etr [high_res] true [sunny] 1 [cloudy] 1 [evening] 1 [night] 1
[location] tuxracer [high_res] false [sunny] 1 [cloudy] 1 [evening] 1 [night] 1

View File

Before

Width:  |  Height:  |  Size: 658 KiB

After

Width:  |  Height:  |  Size: 658 KiB

View File

Before

Width:  |  Height:  |  Size: 888 KiB

After

Width:  |  Height:  |  Size: 888 KiB

View File

Before

Width:  |  Height:  |  Size: 601 KiB

After

Width:  |  Height:  |  Size: 601 KiB

View File

Before

Width:  |  Height:  |  Size: 575 KiB

After

Width:  |  Height:  |  Size: 575 KiB

View File

Before

Width:  |  Height:  |  Size: 609 KiB

After

Width:  |  Height:  |  Size: 609 KiB

View File

Before

Width:  |  Height:  |  Size: 423 KiB

After

Width:  |  Height:  |  Size: 423 KiB

View File

Before

Width:  |  Height:  |  Size: 643 KiB

After

Width:  |  Height:  |  Size: 643 KiB

View File

Before

Width:  |  Height:  |  Size: 904 KiB

After

Width:  |  Height:  |  Size: 904 KiB

View File

Before

Width:  |  Height:  |  Size: 572 KiB

After

Width:  |  Height:  |  Size: 572 KiB

View File

Before

Width:  |  Height:  |  Size: 480 KiB

After

Width:  |  Height:  |  Size: 480 KiB

View File

Before

Width:  |  Height:  |  Size: 603 KiB

After

Width:  |  Height:  |  Size: 603 KiB

View File

Before

Width:  |  Height:  |  Size: 467 KiB

After

Width:  |  Height:  |  Size: 467 KiB

View File

Before

Width:  |  Height:  |  Size: 746 KiB

After

Width:  |  Height:  |  Size: 746 KiB

View File

Before

Width:  |  Height:  |  Size: 760 KiB

After

Width:  |  Height:  |  Size: 760 KiB

View File

Before

Width:  |  Height:  |  Size: 738 KiB

After

Width:  |  Height:  |  Size: 738 KiB

View File

Before

Width:  |  Height:  |  Size: 660 KiB

After

Width:  |  Height:  |  Size: 660 KiB

View File

Before

Width:  |  Height:  |  Size: 730 KiB

After

Width:  |  Height:  |  Size: 730 KiB

View File

Before

Width:  |  Height:  |  Size: 665 KiB

After

Width:  |  Height:  |  Size: 665 KiB

View File

Before

Width:  |  Height:  |  Size: 674 KiB

After

Width:  |  Height:  |  Size: 674 KiB

View File

Before

Width:  |  Height:  |  Size: 954 KiB

After

Width:  |  Height:  |  Size: 954 KiB

View File

Before

Width:  |  Height:  |  Size: 604 KiB

After

Width:  |  Height:  |  Size: 604 KiB

View File

Before

Width:  |  Height:  |  Size: 575 KiB

After

Width:  |  Height:  |  Size: 575 KiB

View File

Before

Width:  |  Height:  |  Size: 627 KiB

After

Width:  |  Height:  |  Size: 627 KiB

View File

Before

Width:  |  Height:  |  Size: 547 KiB

After

Width:  |  Height:  |  Size: 547 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 520 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 KiB

View File

@ -3,7 +3,7 @@
# Do not change the id
# -------------------------------------------------------------
* [id] 0 [name] logo [file] splash_small.png
* [id] 0 [name] logo [file] splash_1.png
* [id] 1 [name] snow_start [file] snowstart.png [repeat] 1
* [id] 2 [name] snow_track [file] snowtrack.png [repeat] 1
@ -28,24 +28,24 @@
* [id] 21 [name] tuxbonus [file] tuxbonus.png [repeat] 0
* [id] 22 [name] mouse_cursor [file] mouse_cursor.png [repeat] 0
* [id] 23 [name] snow_particle [file] snowparticles.png [repeat] 0
* [id] 24 [name] terrain_envmap [file] envmap.png [repeat] 0
* [id] 25 [name] energy_mask [file] energymask2.png [repeat] 0
* [id] 26 [name] mask_outline [file] mask_outline2.png [repeat] 0
* [id] 27 [name] ziff032 [file] ziff032.png [repeat] 1
* [id] 27 [name] ziff032 [file] ziff032.png [repeat] 0
* [id] 28 [name] mirror_butt [file] mirror_butt.png [repeat] 0
* [id] 30 [name] random_butt [file] random_butt.png [repeat] 0
* [id] 31 [name] herring_icon2 [file] herringicon3.png [repeat] 0
* [id] 32 [name] time_icon [file] timeicon.png [repeat] 0
* [id] 33 [name] stars [file] stars.png [repeat] 0
* [id] 35 [name] speedknob [file] speedknob2.png
* [id] 36 [name] cupicon [file] cupicon.png
* [id] 37 [name] checkbox [file] checkbox.png
* [id] 38 [name] checkmark_small [file] checkmark_small.png
* [id] 39 [name] checkmark [file] checkmark.png
* [id] 40 [name] widgets [file] widgets.png [repeat] 0
* [id] 41 [name] snow1 [file] snow1.png [repeat] 0
* [id] 42 [name] snow2 [file] snow2.png [repeat] 0
* [id] 43 [name] snow3 [file] snow3.png [repeat] 0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

View File

Before

Width:  |  Height:  |  Size: 282 B

After

Width:  |  Height:  |  Size: 282 B

View File

Before

Width:  |  Height:  |  Size: 554 B

After

Width:  |  Height:  |  Size: 554 B

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 77 KiB

View File

@ -79,10 +79,10 @@ public:
// --------------------------------------------------------------------
enum ESituation {
MUS_RACING = 0,
MUS_WONRACE = 1,
MUS_LOSTRACE = 2,
SITUATION_COUNT
MUS_RACING = 0,
MUS_WONRACE = 1,
MUS_LOSTRACE = 2,
SITUATION_COUNT
};
class CMusic {

View File

@ -56,7 +56,6 @@ Then edit the below functions:
CGameConfig GameConfig;
static string res_names[NUM_RESOLUTIONS];
static TLang *LangList;
static TCheckbox* fullscreen;
static TUpDown* language;
static TUpDown* resolution;
@ -156,8 +155,6 @@ void CGameConfig::Enter() {
Winsys.ShowCursor (!param.ice_cursor);
Winsys.KeyRepeat (true);
LangList = &Trans.languages[0];
for (int i=0; i<NUM_RESOLUTIONS; i++) res_names[i] = Winsys.GetResName (i);
int framewidth = 550 * Winsys.scale;
@ -174,7 +171,7 @@ void CGameConfig::Enter() {
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);
detail_level = AddUpDown(rightpos, area.top+dd*4, 1, 4, param.perf_level);
language = AddUpDown(rightpos, area.top+dd*5, 0, (int)Trans.languages.size() - 1, (int)param.language);
int siz = FT.AutoSizeN (5);
@ -234,7 +231,7 @@ void CGameConfig::Loop (double time_step) {
FT.DrawString (area.left+240, area.top + dd*2, Int_StrN (mus_vol->GetValue()));
FT.DrawString (area.left+240, area.top + dd*3, Int_StrN (sound_vol->GetValue()));
FT.DrawString (area.left+240, area.top + dd*4, Int_StrN (detail_level->GetValue()));
FT.DrawString (area.left+240, area.top + dd*5, LangList[language->GetValue()].language);
FT.DrawString (area.left+240, area.top + dd*5, Trans.languages[language->GetValue()].language);
#if defined (_WIN32)
if (fullscreen->checked != param.fullscreen) {

View File

@ -48,12 +48,6 @@ CCourse::CCourse () {
}
CCourse::~CCourse() {
for (size_t i = 0; i < PolyArr.size(); i++) {
for (size_t j = 0; j < PolyArr[i].num_polygons; j++)
delete[] PolyArr[i].polygons[j].vertices;
delete[] PolyArr[i].polygons;
FreePolyhedron(PolyArr[i]);
}
FreeCourseList ();
ResetCourse ();
}
@ -80,8 +74,15 @@ const TPolyhedron& CCourse::GetPoly (size_t type) const {
return PolyArr[ObjTypes[type].poly];
}
size_t CCourse::GetCourseIdx (const string& dir) const {
return CourseIndex.at(dir);
TCourse* CCourse::GetCourse(const string& dir) {
return &CourseList[CourseIndex.at(dir)];
}
size_t CCourse::GetCourseIdx(const TCourse* course) const {
size_t idx = (course - &CourseList[0]) / sizeof(TCourse);
if (idx >= CourseList.size())
return -1;
return idx;
}
void CCourse::CalcNormals () {
@ -264,14 +265,9 @@ void CCourse::MakeStandardPolyhedrons () {
PolyArr.resize(2);
// polyhedron "none"
PolyArr[0].num_vertices = 0;
PolyArr[0].num_polygons = 0;
PolyArr[0].vertices = NULL;
PolyArr[0].polygons = NULL;
// poyhedron "tree"
PolyArr[1].num_vertices = 6;
PolyArr[1].vertices = new TVector3d[6];
PolyArr[1].vertices.resize(6);
PolyArr[1].vertices[0] = TVector3d(0, 0, 0);
PolyArr[1].vertices[1] = TVector3d(0, 0.15, 0.5);
PolyArr[1].vertices[2] = TVector3d(0.5, 0.15, 0);
@ -279,11 +275,9 @@ void CCourse::MakeStandardPolyhedrons () {
PolyArr[1].vertices[4] = TVector3d(-0.5, 0.15, 0);
PolyArr[1].vertices[5] = TVector3d(0, 1, 0);
PolyArr[1].num_polygons = 8;
PolyArr[1].polygons = new TPolygon[8];
for (size_t i=0; i<PolyArr[1].num_polygons; i++) {
PolyArr[1].polygons[i].num_vertices = 3;
PolyArr[1].polygons[i].vertices = new int[3];
PolyArr[1].polygons.resize(8);
for (size_t i = 0; i < 8; i++) {
PolyArr[1].polygons[i].vertices.resize(3);
}
PolyArr[1].polygons[0].vertices[0] = 0;
PolyArr[1].polygons[0].vertices[1] = 1;
@ -339,8 +333,7 @@ void CCourse::FreeObjectTextures () {
bool CCourse::LoadElevMap () {
CImage img;
if (!img.LoadPng (CourseDir.c_str(), "elev.png", true)) {
Message ("unable to open elev.png");
if (!img.LoadPng (CourseDir.c_str(), "elev.png", true)) { Message ("unable to open elev.png");
return false;
}
@ -397,27 +390,11 @@ void CCourse::LoadItemList () {
ObjTypes[type].texture = new TTexture();
ObjTypes[type].texture->LoadMipmap(terrpath, false);
}
bool coll = ObjTypes[type].collidable;
if (coll == 1) {
CollArr.push_back(TCollidable());
CollArr.back().pt.x = xx;
CollArr.back().pt.z = zz;
CollArr.back().pt.y = FindYCoord (xx, zz);
CollArr.back().height = height;
CollArr.back().diam = diam;
CollArr.back().tree_type = type;
} else if (coll == 0) {
NocollArr.push_back(TItem());
NocollArr.back().pt.x = xx;
NocollArr.back().pt.z = zz;
NocollArr.back().pt.y = FindYCoord (xx, zz);
NocollArr.back().height = height;
NocollArr.back().diam = diam;
NocollArr.back().item_type = type;
NocollArr.back().collectable = ObjTypes[type].collectable;
NocollArr.back().drawable = ObjTypes[type].drawable;
ObjTypes[type].num_items++;
}
if (ObjTypes[type].collidable)
CollArr.push_back(TCollidable(xx, FindYCoord(xx, zz), zz, height, diam, type));
else
NocollArr.push_back(TItem(xx, FindYCoord(xx, zz), zz, height, diam, ObjTypes[type]));
}
}
@ -462,8 +439,7 @@ static void CalcRandomTrees (double baseheight, double basediam, double &height,
bool CCourse::LoadAndConvertObjectMap () {
CImage treeImg;
if (!treeImg.LoadPng (CourseDir.c_str(), "trees.png", true)) {
Message ("unable to open trees.png");
if (!treeImg.LoadPng (CourseDir.c_str(), "trees.png", true)) { Message ("unable to open trees.png");
return false;
}
@ -512,27 +488,10 @@ bool CCourse::LoadAndConvertObjectMap () {
break;
}
bool coll = ObjTypes[type].collidable;
if (coll == 1) {
CollArr.push_back(TCollidable());
CollArr.back().pt.x = xx;
CollArr.back().pt.z = zz;
CollArr.back().pt.y = FindYCoord (xx, zz);
CollArr.back().height = height;
CollArr.back().diam = diam;
CollArr.back().tree_type = type;
} else if (coll == 0) {
NocollArr.push_back(TItem());
NocollArr.back().pt.x = xx;
NocollArr.back().pt.z = zz;
NocollArr.back().pt.y = FindYCoord (xx, zz);
NocollArr.back().height = height;
NocollArr.back().diam = diam;
NocollArr.back().item_type = type;
NocollArr.back().collectable = ObjTypes[type].collectable;
NocollArr.back().drawable = ObjTypes[type].drawable;
ObjTypes[type].num_items++;
}
if (ObjTypes[type].collidable)
CollArr.push_back(TCollidable(xx, FindYCoord(xx, zz), zz, height, diam, type));
else
NocollArr.push_back(TItem(xx, FindYCoord(xx, zz), zz, height, diam, ObjTypes[type]));
string line = "*[name]";
line += ObjTypes[type].name;
@ -545,7 +504,7 @@ bool CCourse::LoadAndConvertObjectMap () {
}
pad += (nx * treeImg.depth) % 4;
}
string itemfile = CourseDir + SEP + "items.lst";
string itemfile = CourseDir + SEP "items.lst";
savelist.Save (itemfile); // Convert trees.png to items.lst
return true;
}
@ -647,8 +606,7 @@ bool CCourse::LoadTerrainTypes () {
bool CCourse::LoadTerrainMap () {
CImage terrImage;
if (!terrImage.LoadPng (CourseDir.c_str(), "terrain.png", true)) {
Message ("unable to open terrain.png");
if (!terrImage.LoadPng (CourseDir.c_str(), "terrain.png", true)) { Message ("unable to open terrain.png");
return false;
}
if (nx != terrImage.nx || ny != terrImage.ny) {
@ -709,7 +667,7 @@ bool CCourse::LoadCourseList () {
string coursepath = param.common_course_dir + SEP + CourseList[i].dir;
if (DirExists (coursepath.c_str())) {
// preview
string previewfile = coursepath + SEP + "preview.png";
string previewfile = coursepath + SEP "preview.png";
CourseList[i].preview = new TTexture();
if (!CourseList[i].preview->LoadMipmap(previewfile, false)) {
Message ("couldn't load previewfile");
@ -717,7 +675,7 @@ bool CCourse::LoadCourseList () {
}
// params
string paramfile = coursepath + SEP + "course.dim";
string paramfile = coursepath + SEP "course.dim";
if (!paramlist.Load (paramfile)) {
Message ("could not load course.dim");
}
@ -767,24 +725,18 @@ void CCourse::ResetCourse () {
mirrored = false;
}
bool CCourse::LoadCourse (size_t idx) {
if (idx >= CourseList.size()) {
Message ("wrong course index");
curr_course = NULL;
return false;
}
if (&CourseList[idx] != curr_course || g_game.force_treemap) {
bool CCourse::LoadCourse (TCourse* course) {
if (course != curr_course || g_game.force_treemap) {
ResetCourse ();
curr_course = &CourseList[idx];
curr_course = course;
CourseDir = param.common_course_dir + SEP + curr_course->dir;
start_pt.x = CourseList[idx].start.x;
start_pt.y = -CourseList[idx].start.y;
start_pt.x = course->start.x;
start_pt.y = -course->start.y;
base_height_value = 127;
g_game.use_keyframe = CourseList[idx].use_keyframe;
g_game.finish_brake = CourseList[idx].finish_brake;
g_game.use_keyframe = course->use_keyframe;
g_game.finish_brake = course->finish_brake;
if (!LoadElevMap ()) {
Message ("could not load course elev map");
@ -800,9 +752,9 @@ bool CCourse::LoadCourse (size_t idx) {
}
// ................................................................
string itemfile = CourseDir + SEP + "items.lst";
string itemfile = CourseDir + SEP "items.lst";
bool itemsexists = FileExists (itemfile);
const CControl *ctrl = Players.GetCtrl (g_game.player_id);
const CControl *ctrl = g_game.player->ctrl;
if (itemsexists && !g_game.force_treemap)
LoadItemList ();
@ -820,9 +772,9 @@ bool CCourse::LoadCourse (size_t idx) {
param.course_detail_level);
}
if (g_game.mirror_id != mirrored) {
if (g_game.mirrorred != mirrored) {
MirrorCourse ();
mirrored = g_game.mirror_id;
mirrored = g_game.mirrorred;
}
return true;
}
@ -868,7 +820,7 @@ void CCourse::MirrorCourseData () {
ResetQuadtree ();
if (nx > 0 && ny > 0) {
const CControl *ctrl = Players.GetCtrl (g_game.player_id);
const CControl *ctrl = g_game.player->ctrl;
InitQuadtree (elevation, nx, ny, curr_course->size.x/(nx-1),
- curr_course->size.y/(ny-1), ctrl->viewpos, param.course_detail_level);
}

View File

@ -41,39 +41,6 @@ GNU General Public License for more details.
class TTexture;
struct TCollidable {
TVector3d pt;
double height;
double diam;
size_t tree_type;
};
struct TItem {
TVector3d pt;
double height;
double diam;
size_t item_type;
int collectable;
bool drawable;
};
struct TCourse {
string name;
string dir;
string author;
string desc[MAX_DESCRIPTION_LINES];
size_t num_lines;
TTexture* preview;
TVector2d size;
TVector2d play_size;
double angle;
double scale;
TVector2d start;
size_t env;
size_t music_theme;
bool use_keyframe;
double finish_brake;
};
struct TTerrType {
string textureFile;
@ -106,6 +73,45 @@ struct TObjectType {
int poly;
};
struct TCollidable {
TVector3d pt;
double height;
double diam;
size_t tree_type;
TCollidable(double x, double y, double z, double height_, double diam_, size_t type)
: pt(x, y, z), height(height_), diam(diam_), tree_type(type)
{}
};
struct TItem {
TVector3d pt;
double height;
double diam;
int collectable;
const TObjectType& type;
TItem(double x, double y, double z, double height_, double diam_, const TObjectType& type_)
: pt(x, y, z), height(height_), diam(diam_), collectable(type_.collectable), type(type_)
{}
};
struct TCourse {
string name;
string dir;
string author;
string desc[MAX_DESCRIPTION_LINES];
size_t num_lines;
TTexture* preview;
TVector2d size;
TVector2d play_size;
double angle;
double scale;
TVector2d start;
size_t env;
size_t music_theme;
bool use_keyframe;
double finish_brake;
};
class CCourse {
private:
const TCourse* curr_course;
@ -147,10 +153,11 @@ public:
GLubyte *vnc_array;
void ResetCourse ();
size_t GetCourseIdx (const string& dir) const;
TCourse* GetCourse (const string& dir);
size_t GetCourseIdx(const TCourse* course) const;
bool LoadCourseList ();
void FreeCourseList ();
bool LoadCourse (size_t idx);
bool LoadCourse(TCourse* course);
bool LoadTerrainTypes ();
bool LoadObjectTypes ();
void MakeStandardPolyhedrons ();

View File

@ -47,7 +47,7 @@ void RenderCourse () {
setup_course_tex_gen ();
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
set_material (colWhite, colBlack, 1.0);
const CControl *ctrl = Players.GetCtrl (g_game.player_id);
const CControl *ctrl = g_game.player->ctrl;
UpdateQuadtree (ctrl->viewpos, param.course_detail_level);
RenderQuadtree ();
}
@ -57,9 +57,8 @@ void RenderCourse () {
// --------------------------------------------------------------------
void DrawTrees() {
size_t tree_type = -1;
size_t item_type = -1;
TObjectType* object_types = &Course.ObjTypes[0];
const CControl* ctrl = Players.GetCtrl (g_game.player_id);
const CControl* ctrl = g_game.player->ctrl;
ScopedRenderMode rm(TREES);
double fwd_clip_limit = param.forward_clip_distance;
@ -130,17 +129,18 @@ void DrawTrees() {
// items -----------------------------
TItem* itemLocs = &Course.NocollArr[0];
size_t numItems = Course.NocollArr.size();
const TObjectType* item_type = NULL;
for (size_t i = 0; i< numItems; i++) {
if (itemLocs[i].collectable == 0 || itemLocs[i].drawable == false) continue;
if (itemLocs[i].collectable == 0 || itemLocs[i].type.drawable == false) continue;
if (clip_course) {
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) {
item_type = itemLocs[i].item_type;
object_types[item_type].texture->Bind();
if (&itemLocs[i].type != item_type) {
item_type = &itemLocs[i].type;
item_type->texture->Bind();
}
glPushMatrix();
@ -149,8 +149,8 @@ void DrawTrees() {
double itemHeight = itemLocs[i].height;
TVector3d normal;
if (object_types[item_type].use_normal) {
normal = object_types[item_type].normal;
if (item_type->use_normal) {
normal = item_type->normal;
} else {
normal = ctrl->viewpos - itemLocs[i].pt;
normal.Norm();

View File

@ -135,7 +135,8 @@ bool CEnvironment::LoadEnvironmentList () {
locs.resize(list.Count());
for (size_t i=0; i<list.Count(); i++) {
const string& line = list.Line(i);
locs[i] = SPStrN (line, "location");
locs[i].name = SPStrN(line, "location");
locs[i].high_res = SPBoolN(line, "high_res", false);
}
list.MakeIndex (EnvIndex, "location");
return true;
@ -146,19 +147,28 @@ string CEnvironment::GetDir (size_t location, size_t light) const {
if (light >= 4) return "";
string res =
param.env_dir2 + SEP +
locs[location] + SEP + lightcond[light];
locs[location].name + SEP + lightcond[light];
return res;
}
void CEnvironment::LoadSkybox (const string& EnvDir) {
Skybox = new TTexture[param.full_skybox?6:3];
Skybox[0].Load(EnvDir, "front.png");
Skybox[1].Load(EnvDir, "left.png");
Skybox[2].Load(EnvDir, "right.png");
void CEnvironment::LoadSkyboxSide(size_t index, const string& EnvDir, const string& name, bool high_res) {
bool loaded = false;
if (param.perf_level > 3 && high_res)
loaded = Skybox[index].Load(EnvDir, name + "H.png");
if (!loaded)
Skybox[index].Load(EnvDir, name + ".png");
}
void CEnvironment::LoadSkybox (const string& EnvDir, bool high_res) {
Skybox = new TTexture[param.full_skybox ? 6 : 3];
LoadSkyboxSide(0, EnvDir, "front", high_res);
LoadSkyboxSide(1, EnvDir, "left", high_res);
LoadSkyboxSide(2, EnvDir, "right", high_res);
if (param.full_skybox) {
Skybox[3].Load(EnvDir, "top.png");
Skybox[4].Load(EnvDir, "bottom.png");
Skybox[5].Load(EnvDir, "back.png");
LoadSkyboxSide(3, EnvDir, "top", high_res);
LoadSkyboxSide(4, EnvDir, "bottom", high_res);
LoadSkyboxSide(5, EnvDir, "back", high_res);
}
}
@ -393,7 +403,7 @@ void CEnvironment::LoadEnvironment (size_t loc, size_t light) {
// texture id's are set to 0 and the sky will not be drawn.
// There is no error handling, you see the result on the screen.
ResetSkybox ();
LoadSkybox (EnvDir);
LoadSkybox(EnvDir, locs[loc].high_res);
// Load light conditions.
ResetFog ();

View File

@ -45,11 +45,16 @@ struct TLight {
void Enable(GLenum num) const;
};
struct TEnvironment {
string name;
bool high_res;
};
class CEnvironment {
private:
size_t EnvID;
TTexture* Skybox;
vector<string> locs;
vector<TEnvironment> locs;
string lightcond[4];
TLight default_light;
TLight lights[4];
@ -60,7 +65,8 @@ private:
map<string, size_t> LightIndex;
void ResetSkybox ();
void LoadSkybox (const string& EnvDir);
void LoadSkybox(const string& EnvDir, bool high_res);
void LoadSkyboxSide(size_t index, const string& EnvDir, const string& name, bool high_res);
void ResetLight ();
void LoadLight (const string& EnvDir);
void ResetFog ();

View File

@ -21,8 +21,8 @@ GNU General Public License for more details.
#include "vectors.h"
enum Orientation {
OR_TOP = 0, // top-orientated menu widgets
OR_BOTTOM = 1 // bottom-orientated
OR_TOP = 0, // top-orientated menu widgets
OR_BOTTOM = 1 // bottom-orientated
};
struct TColor3 {
@ -39,26 +39,30 @@ struct TColor : public TColor3 {
};
enum TToolMode {
NONE,
TUXSHAPE,
KEYFRAME,
TREEGEN,
LEARN,
NONE,
TUXSHAPE,
KEYFRAME,
TREEGEN,
LEARN,
};
enum TGameType {
PRACTICING,
CUPRACING
PRACTICING,
CUPRACING
};
enum TViewMode {
BEHIND,
FOLLOW,
ABOVE,
NUM_VIEW_MODES
BEHIND,
FOLLOW,
ABOVE,
NUM_VIEW_MODES
};
struct TCup2;
struct TCup;
struct TPlayer;
struct TCourse;
struct TRace;
struct TCharacter;
struct TGameData {
TToolMode toolmode;
@ -73,22 +77,18 @@ struct TGameData {
double finish_brake;
// course and race params
size_t player_id;
TPlayer* player;
size_t start_player;
TCup2* cup;
size_t race_id;
bool mirror_id;
size_t char_id;
size_t course_id;
TCup* cup;
bool mirrorred;
TCharacter* character;
TCourse* course;
size_t location_id;
size_t light_id;
int snow_id;
int wind_id;
size_t theme_id;
// requirements
TVector3i herring_req; // 3 levels of needed herrings
TVector3d time_req; // 3 levels of allowed time
TRace* race; // Only valid if not in practice mode
// race results (better in player.ctrl ?)
double time; // reached time

View File

@ -41,7 +41,7 @@ CEvent Event;
// ready: 0 - racing 1 - ready with success 2 - ready with failure
static int ready = 0; // indicates if last race is done
static TWidget* curr_focus = 0;
static TCup2 *ecup = 0;
static TCup *ecup = 0;
static size_t curr_race = 0;
static size_t curr_bonus = 0;
static TWidget* textbuttons[3];
@ -51,14 +51,13 @@ void StartRace () {
State::manager.RequestEnterState (EventSelect);
return;
}
g_game.mirror_id = false;
g_game.course_id = ecup->races[curr_race]->course;
g_game.mirrorred = false;
g_game.course = ecup->races[curr_race]->course;
g_game.theme_id = ecup->races[curr_race]->music_theme;
g_game.light_id = ecup->races[curr_race]->light;
g_game.snow_id = ecup->races[curr_race]->snow;
g_game.wind_id = ecup->races[curr_race]->wind;
g_game.herring_req = ecup->races[curr_race]->herrings;
g_game.time_req = ecup->races[curr_race]->time;
g_game.race = ecup->races[curr_race];
g_game.game_type = CUPRACING;
State::manager.RequestEnterState (Loading);
}
@ -217,9 +216,9 @@ void CEvent::Loop (double timestep) {
FT.SetColor (colDYell);
else
FT.SetColor (colWhite);
FT.DrawString (area.left + 29, y, Course.CourseList[ecup->races[i]->course].name);
FT.DrawString (area.left + 29, y, ecup->races[i]->course->name);
Tex.Draw (CHECKBOX, area.right -54, y, texsize, texsize);
if (curr_race > i) Tex.Draw (CHECKMARK, area.right-50, y + 4, 0.8);
if (curr_race > i) Tex.Draw (CHECKMARK_SMALL, area.right-50, y + 4, 0.8);
}
FT.AutoSizeN (3);

View File

@ -34,16 +34,14 @@ GNU General Public License for more details.
CEventSelect EventSelect;
static TEvent2 *EventList;
static TEvent *EventList;
static TUpDown* event;
static TUpDown* cup;
static TWidget* textbuttons[2];
static TCup2 *CupList;
void EnterEvent () {
g_game.game_type = CUPRACING;
g_game.cup = EventList[event->GetValue()].cups[cup->GetValue()];
g_game.race_id = 0;
State::manager.RequestEnterState(Event);
}
@ -92,7 +90,6 @@ static int framewidth, frameheight, frametop1, frametop2;
void CEventSelect::Enter () {
Winsys.ShowCursor (!param.ice_cursor);
EventList = &Events.EventList[0];
CupList = &Events.CupList[0];
framewidth = 500 * Winsys.scale;
frameheight = 50 * Winsys.scale;
@ -102,7 +99,7 @@ void CEventSelect::Enter () {
ResetGUI();
event = AddUpDown(area.right+8, frametop1, 0, (int)Events.EventList.size() - 1, 0);
cup = AddUpDown(area.right+8, frametop2, 0, (int)EventList[0].cups.size() - 1, 0);
cup = AddUpDown(area.right + 8, frametop2, 0, (int)Events.EventList[0].cups.size() - 1, 0);
int siz = FT.AutoSizeN (5);
@ -111,7 +108,7 @@ void CEventSelect::Enter () {
textbuttons[1] = AddTextButton (Trans.Text(8), area.left+50, AutoYPosN (70), siz);
SetFocus(textbuttons[1]);
Events.MakeUnlockList (Players.GetCurrUnlocked());
Events.MakeUnlockList (g_game.player->funlocked);
Music.Play (param.menu_music, -1);
}

View File

@ -59,7 +59,7 @@ void LoadConfigFile () {
param.fullscreen = SPBoolN (line, "fullscreen", false);
param.res_type = SPIntN (line, "res_type", 0);
param.framerate = SPIntN (line, "framerate", 60);
param.perf_level = SPIntN (line, "detail_level", 0);
param.perf_level = SPIntN (line, "detail_level", 3);
param.language = SPIntN (line, "language", 0);
param.sound_volume = SPIntN (line, "sound_volume", 100);
param.music_volume = SPIntN (line, "music_volume", 20);
@ -283,7 +283,7 @@ void InitConfig (const char *arg0) {
// the progdir is always the current dir
param.config_dir = "config";
param.data_dir = "data";
param.configfile = param.config_dir + SEP + "options.txt";
param.configfile = param.config_dir + SEP "options.txt";
#else
#if 0
@ -306,28 +306,28 @@ void InitConfig (const char *arg0) {
param.config_dir = pwent->pw_dir;
param.config_dir += SEP;
param.config_dir += CONFIG_DIR;
// or: param.config_dir = param.prog_dir + SEP + "config";
// or: param.config_dir = param.prog_dir + SEP "config";
if (!DirExists (param.config_dir.c_str()))
mkdir (param.config_dir.c_str(), 0775);
param.data_dir = ETR_DATA_DIR;
param.data_dir += SEP;
param.data_dir += "etr";
// param.data_dir = param.prog_dir + SEP + "data";
param.configfile = param.config_dir + SEP + "options";
// param.data_dir = param.prog_dir + SEP "data";
param.configfile = param.config_dir + SEP "options";
#endif
param.screenshot_dir = param.data_dir + SEP + "screenshots";
param.obj_dir = param.data_dir + SEP + "objects";
param.env_dir2 = param.data_dir + SEP + "env";
param.char_dir = param.data_dir + SEP + "char";
param.terr_dir = param.data_dir + SEP + "terrains";
param.tex_dir = param.data_dir + SEP + "textures";
param.common_course_dir = param.data_dir + SEP + "courses";
param.sounds_dir = param.data_dir + SEP + "sounds";
param.music_dir = param.data_dir + SEP + "music";
param.font_dir = param.data_dir + SEP + "fonts";
param.trans_dir = param.data_dir + SEP + "translations";
param.player_dir = param.data_dir + SEP + "players";
param.screenshot_dir = param.data_dir + SEP "screenshots";
param.obj_dir = param.data_dir + SEP "objects";
param.env_dir2 = param.data_dir + SEP "env";
param.char_dir = param.data_dir + SEP "char";
param.terr_dir = param.data_dir + SEP "terrains";
param.tex_dir = param.data_dir + SEP "textures";
param.common_course_dir = param.data_dir + SEP "courses";
param.sounds_dir = param.data_dir + SEP "sounds";
param.music_dir = param.data_dir + SEP "music";
param.font_dir = param.data_dir + SEP "fonts";
param.trans_dir = param.data_dir + SEP "translations";
param.player_dir = param.data_dir + SEP "players";
param.ui_snow = true;
param.view_mode = FOLLOW;
@ -340,8 +340,4 @@ void InitConfig (const char *arg0) {
SetConfigDefaults ();
SaveConfigFile ();
}
/*string playerfile = param.config_dir + SEP + PLAYER_FILE;
if (FileExists (playerfile)) {
} else {
}*/
}

View File

@ -46,16 +46,14 @@ bool CEvents::LoadEventList () {
const string& line = list.Line(i);
int type = SPIntN (line, "struct", -1);
if (type == 0) {
RaceList.push_back(TRace2());
string item = SPStrN (line, "course");
RaceList.back().course = Course.GetCourseIdx (item);
item = SPStrN (line, "light");
RaceList.back().light = Env.GetLightIdx (item);
RaceList.back().snow = SPIntN (line, "snow", 0);
RaceList.back().wind = SPIntN (line, "wind", 0);
RaceList.back().time = SPVector3d(line, "time");
RaceList.back().herrings = SPVector3i(line, "herring");
RaceList.back().music_theme = Music.GetThemeIdx (SPStrN (line, "theme", "normal"));
RaceList.push_back(TRace(
Course.GetCourse(SPStrN(line, "course")),
Env.GetLightIdx(SPStrN(line, "light")),
SPIntN(line, "snow", 0),
SPIntN(line, "wind", 0),
SPVector3i(line, "herring"),
SPVector3d(line, "time"),
Music.GetThemeIdx(SPStrN(line, "theme", "normal"))));
}
}
list.MakeIndex (RaceIndex, "race");
@ -65,10 +63,10 @@ bool CEvents::LoadEventList () {
const string& line = list.Line(i);
int type = SPIntN (line, "struct", -1);
if (type == 1) {
CupList.push_back(TCup2());
CupList.back().cup = SPStrN (line, "cup", errorString);
CupList.back().name = SPStrN (line, "name", "unknown");
CupList.back().desc = SPStrN (line, "desc", "unknown");
CupList.push_back(TCup(
SPStrN(line, "cup", errorString),
SPStrN(line, "name", "unknown"),
SPStrN(line, "desc", "unknown")));
int num = SPIntN (line, "num", 0);
CupList.back().races.resize(num);
for (int ii=0; ii<num; ii++) {
@ -84,8 +82,7 @@ bool CEvents::LoadEventList () {
const string& line = list.Line(i);
int type = SPIntN (line, "struct", -1);
if (type == 2) {
EventList.push_back(TEvent2());
EventList.back().name = SPStrN (line, "name", "unknown");
EventList.push_back(TEvent(SPStrN(line, "name", "unknown")));
int num = SPIntN (line, "num", 0);
EventList.back().cups.resize(num);
for (int ii=0; ii<num; ii++) {
@ -162,41 +159,25 @@ CPlayers::~CPlayers() {
}
void CPlayers::AddPlayer (const string& name, const string& avatar) {
plyr.push_back(TPlayer());
plyr.back().name = name;
plyr.back().avatar = avatar;
plyr.back().texture = GetAvatarTexture(AvatarIndex[plyr.back().avatar]);
plyr.back().funlocked = "";
plyr.back().ctrl = NULL;
plyr.push_back(TPlayer(name, FindAvatar(avatar)));
}
void CPlayers::SetDefaultPlayers () {
plyr.resize(2);
plyr[0].funlocked = "";
plyr[0].name = "Racer";
plyr[0].avatar = "avatar01.png";
plyr[0].texture = GetAvatarTexture(AvatarIndex[plyr[0].avatar]);
plyr[0].ctrl = NULL;
plyr[1].funlocked = "";
plyr[1].name = "Bunny";
plyr[1].avatar = "avatar02.png";
plyr[1].texture = GetAvatarTexture(AvatarIndex[plyr[1].avatar]);
plyr[1].ctrl = NULL;
plyr.push_back(TPlayer("Racer", FindAvatar("avatar01.png")));
plyr.push_back(TPlayer("Bunny", FindAvatar("avatar02.png")));
}
bool CPlayers::LoadPlayers () {
CSPList list(MAX_PLAYERS);
if (FileExists (param.config_dir, "players") == false) {
SetDefaultPlayers ();
Message ("file 'players' does not exist, set default players");
return false;
}
CSPList list(MAX_PLAYERS);
if (list.Load (param.config_dir, "players") == false) {
SetDefaultPlayers ();
Message ("coule not load players list, set default players");
Message ("could not load players list, set default players");
return false;
}
@ -206,8 +187,7 @@ bool CPlayers::LoadPlayers () {
const string& line = list.Line(i);
plyr[i].name = SPStrN (line, "name", "unknown");
plyr[i].funlocked = SPStrN (line, "unlocked");
plyr[i].avatar = SPStrN (line, "avatar");
plyr[i].texture = GetAvatarTexture(AvatarIndex[plyr[i].avatar]);
plyr[i].avatar = FindAvatar(SPStrN(line, "avatar"));
plyr[i].ctrl = NULL;
int active = SPIntN (line, "active", 0);
if (active > 0) g_game.start_player = plyr.size()-1;
@ -221,51 +201,36 @@ bool CPlayers::LoadPlayers () {
}
void CPlayers::SavePlayers () const {
string playerfile = param.config_dir + SEP + "players";
CSPList list(MAX_PLAYERS);
string item = "";
string playerfile = param.config_dir + SEP "players";
CSPList list(plyr.size());
for (size_t i=0; i<plyr.size(); i++) {
item = "*[name]" + plyr[i].name;
item +="[avatar]" + plyr[i].avatar;
string item = "*[name]" + plyr[i].name;
item +="[avatar]" + plyr[i].avatar->filename;
item += "[unlocked]" + plyr[i].funlocked;
if (i == g_game.player_id) item += "[active]1";
if (&plyr[i] == g_game.player) item += "[active]1";
else item += "[active]0";
list.Add (item);
}
list.Save (playerfile);
}
const string& CPlayers::GetCurrUnlocked () const {
return plyr[g_game.player_id].funlocked;
const TAvatar* CPlayers::FindAvatar(const string& name) {
for (size_t i = 0; i < avatars.size(); i++)
if (avatars[i].filename == name)
return &avatars[i];
return 0;
}
void CPlayers::AddPassedCup (const string& cup) {
if (SPIntN (plyr[g_game.player_id].funlocked, cup, -1) > 0) return;
plyr[g_game.player_id].funlocked += " ";
plyr[g_game.player_id].funlocked += cup;
}
CControl *CPlayers::GetCtrl (size_t player) {
if (player >= plyr.size()) return NULL;
return plyr[player].ctrl;
}
const CControl *CPlayers::GetCtrl (size_t player) const {
if (player >= plyr.size()) return NULL;
return plyr[player].ctrl;
}
const string& CPlayers::GetName (size_t player) const {
if (player >= plyr.size()) return emptyString;
return plyr[player].name;
if (SPIntN (g_game.player->funlocked, cup, -1) > 0) return;
g_game.player->funlocked += " ";
g_game.player->funlocked += cup;
}
void CPlayers::ResetControls () {
for (size_t i=0; i<plyr.size(); i++) {
if (plyr[i].ctrl != NULL) {
delete plyr[i].ctrl;
plyr[i].ctrl = NULL;
}
delete plyr[i].ctrl;
plyr[i].ctrl = NULL;
}
}
@ -286,16 +251,12 @@ void CPlayers::LoadAvatars () {
return;
}
AvatarIndex.clear();
for (size_t i=0; i<list.Count(); i++) {
const string& line = list.Line(i);
string filename = SPStrN (line, "file", "unknown");
TTexture* texture = new TTexture();
if (texture && texture->Load(param.player_dir, filename)) {
avatars.push_back(TAvatar());
avatars.back().filename = filename;
avatars.back().texture = texture;
AvatarIndex[filename] = avatars.size()-1;
avatars.push_back(TAvatar(filename, texture));
} else
delete texture;
}
@ -315,6 +276,12 @@ const string& CPlayers::GetDirectAvatarName (size_t avatar) const {
// Character Administration
// ********************************************************************
CKeyframe* TCharacter::GetKeyframe(TFrameType type) {
if (type < 0 || type >= NUM_FRAME_TYPES) return NULL;
return &frames[type];
}
CCharacter Char;
static const string char_type_index = "[spheres]0[3d]1";
@ -344,7 +311,7 @@ void CCharacter::LoadCharacterList () {
string charpath = param.char_dir + SEP + CharList[i].dir;
if (DirExists (charpath.c_str())) {
string previewfile = charpath + SEP + "preview.png";
string previewfile = charpath + SEP "preview.png";
TCharacter* ch = &CharList[i];
ch->preview = new TTexture();
@ -373,24 +340,9 @@ void CCharacter::LoadCharacterList () {
}
}
void CCharacter::FreeCharacterPreviews () {
void CCharacter::FreeCharacterPreviews() {
for (size_t i=0; i<CharList.size(); i++) {
delete CharList[i].preview;
CharList[i].preview = 0;
}
}
void CCharacter::Draw (size_t idx) {
if (idx >= CharList.size()) return;
CharList[idx].shape->Draw ();
}
CCharShape *CCharacter::GetShape (size_t idx) {
if (idx >= CharList.size()) return NULL;
return CharList[idx].shape;
}
CKeyframe *CCharacter::GetKeyframe (size_t idx, TFrameType type) {
if (type < 0 || type >= NUM_FRAME_TYPES) return NULL;
if (idx >= CharList.size()) return NULL;
return &CharList[idx].frames[type];
}

View File

@ -19,41 +19,54 @@ GNU General Public License for more details.
#include "bh.h"
#include "keyframe.h"
#include "spx.h"
#include <map>
enum TFrameType {
START,
FINISH,
WONRACE,
LOSTRACE,
NUM_FRAME_TYPES
START,
FINISH,
WONRACE,
LOSTRACE,
NUM_FRAME_TYPES
};
class TTexture;
struct TRace2 {
size_t course;
struct TRace {
TCourse* course;
size_t light;
int snow;
int wind;
TVector3i herrings;
TVector3d time;
size_t music_theme;
TRace(TCourse* course_, size_t light_, int snow_, int wind_, const TVector3i& herrings_, const TVector3d& time_, size_t music_theme_)
: course(course_), light(light_), snow(snow_), wind(wind_), herrings(herrings_), time(time_), music_theme(music_theme_)
{}
};
struct TCup2 {
struct TCup {
string cup;
string name;
string desc;
vector<TRace2*> races;
vector<TRace*> races;
bool Unlocked;
TCup(const string& cup_, const string& name_, const string& desc_)
: cup(cup_), name(name_), desc(desc_), Unlocked(false)
{}
};
struct TEvent2 {
struct TEvent {
string name;
vector<TCup2*> cups;
vector<TCup*> cups;
TEvent(const string& name_)
: name(name_)
{}
};
class CEvents {
@ -62,9 +75,9 @@ private:
map<string, size_t> CupIndex;
map<string, size_t> EventIndex;
public:
vector<TRace2> RaceList;
vector<TCup2> CupList;
vector<TEvent2> EventList;
vector<TRace> RaceList;
vector<TCup> CupList;
vector<TEvent> EventList;
bool LoadEventList ();
size_t GetRaceIdx (const string& race) const;
size_t GetCupIdx (const string& cup) const;
@ -88,33 +101,38 @@ extern CEvents Events;
struct TAvatar {
string filename;
TTexture* texture;
TAvatar(const string& filename_, TTexture* texture_)
: filename(filename_), texture(texture_)
{}
};
struct TPlayer {
string name;
CControl *ctrl;
string funlocked;
TTexture* texture;
string avatar;
const TAvatar* avatar;
TPlayer(const string& name_ = emptyString, const TAvatar* avatar_ = NULL)
: name(name_), ctrl(NULL), avatar(avatar_)
{}
};
class CPlayers {
private:
vector<TPlayer> plyr;
void SetDefaultPlayers ();
map<string, size_t> AvatarIndex;
vector<TAvatar> avatars;
const TAvatar* FindAvatar(const string& name);
public:
~CPlayers();
const string& GetCurrUnlocked () const;
TPlayer* GetPlayer(size_t index) { return &plyr[index]; }
void AddPassedCup (const string& cup);
void AddPlayer (const string& name, const string& avatar);
bool LoadPlayers ();
void SavePlayers () const;
CControl *GetCtrl (size_t player);
const CControl *GetCtrl (size_t player) const;
const string& GetName (size_t player) const;
void ResetControls ();
void AllocControl (size_t player);
void LoadAvatars ();
@ -122,7 +140,7 @@ public:
size_t numPlayers() const { return plyr.size(); }
TTexture* GetAvatarTexture (size_t avatar) const;
const string& GetDirectAvatarName (size_t avatar) const;
const string& GetDirectAvatarName(size_t avatar) const;
};
extern CPlayers Players;
@ -130,8 +148,6 @@ extern CPlayers Players;
// -------------------------------- characters ------------------------
#define MAX_CHARACTERS 16
class CCharShape;
struct TCharacter {
int type;
string name;
@ -140,6 +156,8 @@ struct TCharacter {
CCharShape *shape;
CKeyframe frames[NUM_FRAME_TYPES];
bool finishframesok;
CKeyframe* GetKeyframe(TFrameType type);
};
class CCharacter {
@ -148,12 +166,8 @@ public:
~CCharacter();
void Draw (size_t idx);
CCharShape *GetShape (size_t idx);
void LoadCharacterList ();
void FreeCharacterPreviews ();
CKeyframe *GetKeyframe (size_t idx, TFrameType type);
};
extern CCharacter Char;

View File

@ -38,6 +38,7 @@ GNU General Public License for more details.
#include "event.h"
#include "winsys.h"
#include "physics.h"
#include "tux.h"
CGameOver GameOver;
@ -96,7 +97,7 @@ void GameOverMessage (const CControl *ctrl) {
line = Int_StrN (g_game.herring);
if (g_game.game_type == CUPRACING) {
line += " (";
line += Int_StrN (g_game.herring_req.x);
line += Int_StrN (g_game.race->herrings.x);
line += ")";
}
FT.DrawString (leftframe+240, topframe+40, line);
@ -107,7 +108,7 @@ void GameOverMessage (const CControl *ctrl) {
line += " s";
if (g_game.game_type == CUPRACING) {
line += " (";
line += Float_StrN (g_game.time_req.x, 2);
line += Float_StrN (g_game.race->time.x, 2);
line += ")";
}
FT.DrawString (leftframe+240, topframe+65, line);
@ -177,13 +178,13 @@ void CGameOver::Enter() {
final_frame = NULL;
} else {
if (g_game.game_type == CUPRACING) {
if (g_game.race_result < 0) final_frame =
Char.GetKeyframe (g_game.char_id, LOSTRACE);
else final_frame = Char.GetKeyframe (g_game.char_id, WONRACE);
} else final_frame = Char.GetKeyframe (g_game.char_id, FINISH);
if (g_game.race_result < 0)
final_frame = g_game.character->GetKeyframe(LOSTRACE);
else final_frame = g_game.character->GetKeyframe(WONRACE);
} else final_frame = g_game.character->GetKeyframe( FINISH);
if (!g_game.raceaborted) {
const CControl *ctrl = Players.GetCtrl (g_game.player_id);
const CControl *ctrl = g_game.player->ctrl;
final_frame->Init (ctrl->cpos, -0.18);
}
}
@ -192,7 +193,7 @@ void CGameOver::Enter() {
void CGameOver::Loop(double time_step) {
CControl *ctrl = Players.GetCtrl (g_game.player_id);
CControl *ctrl = g_game.player->ctrl;
int width = Winsys.resolution.width;
int height = Winsys.resolution.height;
check_gl_error();
@ -219,7 +220,7 @@ void CGameOver::Loop(double time_step) {
UpdateSnow (time_step, ctrl);
DrawSnow (ctrl);
Char.Draw (g_game.char_id);
g_game.character->shape->Draw();
ScopedRenderMode rm(GUI);
SetupGuiDisplay ();

View File

@ -482,40 +482,6 @@ void DrawFrameX (int x, int y, int w, int h, int line, const TColor& backcol, co
glPopMatrix();
}
void DrawLevel (int x, int y, int level, double fact) {
static const float lev[4] = {0.0, 0.75, 0.5, 0.25};
float bott = lev[level];
float top = bott + 0.25;
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable (GL_TEXTURE_2D);
Tex.BindTex (STARS);
glColor4f (1.0, 1.0, 1.0, 1.0);
const GLfloat tex[] = {
0, bott,
0.75, bott,
0.75, top,
0, top
};
const GLshort vtx[] = {
x, Winsys.resolution.height - y - 32,
x + 95, Winsys.resolution.height - y - 32,
x + 95, Winsys.resolution.height - y,
x, Winsys.resolution.height - y
};
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_SHORT, 0, vtx);
glTexCoordPointer(2, GL_FLOAT, 0, tex);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
}
void DrawBonusExt (int y, size_t numraces, size_t num) {
size_t maxtux = numraces * 3;
if (num > maxtux) return;

View File

@ -173,7 +173,6 @@ void ResetGUI();
void DrawFrameX (int x, int y, int w, int h, int line,
const TColor& backcol, const TColor& framecol, double transp);
void DrawLevel (int x, int y, int level, double fact);
void DrawBonusExt (int y, size_t numraces, size_t num);
void DrawCursor ();

View File

@ -78,7 +78,7 @@ static void draw_time() {
*/
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
Tex.Draw (T_TIME, 10, 12, 1);
Tex.Draw (T_TIME, 16, 20, 1);
FT.SetColor (colDYell);
FT.SetSize (32);
FT.DrawString (160, 6, hundrstr);
@ -247,29 +247,7 @@ void DrawSpeed (double speed) {
}
}
void DrawWind(float dir, float speed) {
Tex.Draw (SPEEDMETER, 10, Winsys.resolution.height - 150, 1.0);
glPushMatrix ();
glDisable (GL_TEXTURE_2D);
glColor4f (1, 0, 0, 0.5);
glTranslatef (82, 77, 0);
glRotatef (dir, 0, 0, 1);
const GLfloat vtx[] = {
-2, 0.0,
2, 0.0,
2, -speed,
-2, -speed
};
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, vtx);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glDisableClientState(GL_VERTEX_ARRAY);
glPopMatrix ();
Tex.Draw (SPEED_KNOB, 74, Winsys.resolution.height - 84, 1.0);
}
void DrawWind2 (float dir, float speed, const CControl *ctrl) {
void DrawWind(float dir, float speed, const CControl *ctrl) {
if (g_game.wind_id < 1) return;
Tex.Draw (SPEEDMETER, 0, Winsys.resolution.height-140, 1.0);
@ -302,12 +280,10 @@ void DrawWind2 (float dir, float speed, const CControl *ctrl) {
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
// direction indicator
TVector3d movdir = ctrl->cvel;
movdir.Norm();
float dir_angle = atan (movdir.x / movdir.z) * 57.3;
float dir_angle = RADIANS_TO_ANGLES(atan2(ctrl->cvel.x, ctrl->cvel.z));
glColor4f (0, 0.5, 0, 1.0);
glRotatef (dir_angle + 180 - dir, 0, 0, 1);
glRotatef (dir_angle - dir, 0, 0, 1);
static const GLshort vtx2 [] = {
-2, 0,
2, 0,
@ -331,12 +307,15 @@ void DrawWind2 (float dir, float speed, const CControl *ctrl) {
}
}
const int maxFrames = 50;
static int numFrames = 0;
static float averagefps = 0;
static float sumTime = 0;
void DrawFps() {
const int maxFrames = 50;
static int numFrames = 0;
static float averagefps = 0;
static float sumTime = 0;
if (!param.display_fps)
return;
void DrawFps () {
if (numFrames >= maxFrames) {
averagefps = 1 / sumTime * maxFrames;
numFrames = 0;
@ -347,17 +326,15 @@ void DrawFps () {
}
if (averagefps < 1) return;
if (param.display_fps) {
string fpsstr = Float_StrN (averagefps, 0);
if (param.use_papercut_font < 2) {
Tex.DrawNumStr (fpsstr, (Winsys.resolution.width - 60) / 2, 10, 1, colWhite);
} else {
if (averagefps >= 35)
FT.SetColor (colWhite);
else
FT.SetColor (colRed);
FT.DrawString ((Winsys.resolution.width - 60) / 2, 10, fpsstr);
}
string fpsstr = Int_StrN((int)averagefps);
if (param.use_papercut_font < 2) {
Tex.DrawNumStr (fpsstr, (Winsys.resolution.width - 60) / 2, 10, 1, colWhite);
} else {
if (averagefps >= 35)
FT.SetColor (colWhite);
else
FT.SetColor (colRed);
FT.DrawString ((Winsys.resolution.width - 60) / 2, 10, fpsstr);
}
}
@ -412,5 +389,5 @@ void DrawHud (const CControl *ctrl) {
DrawSpeed (speed * 3.6);
DrawFps ();
DrawCoursePosition (ctrl);
DrawWind2 (Wind.Angle (), Wind.Speed (), ctrl);
DrawWind (Wind.Angle (), Wind.Speed (), ctrl);
}

View File

@ -33,6 +33,7 @@ GNU General Public License for more details.
#include "racing.h"
#include "winsys.h"
#include "physics.h"
#include "tux.h"
CIntro Intro;
static CKeyframe *startframe;
@ -48,18 +49,16 @@ void abort_intro (CControl *ctrl) {
// =================================================================
void CIntro::Enter() {
CControl *ctrl = Players.GetCtrl (g_game.player_id);
CControl *ctrl = g_game.player->ctrl;
TVector2d start_pt = Course.GetStartPoint ();
ctrl->orientation_initialized = false;
ctrl->view_init = false;
ctrl->cpos.x = start_pt.x;
ctrl->cpos.z = start_pt.y;
startframe = Char.GetKeyframe (g_game.char_id, START);
startframe = g_game.character->GetKeyframe(START);
if (startframe->loaded) {
// startframe->Init (ctrl->cpos, -0.05);
CCharShape *sh = Char.GetShape (g_game.char_id);
startframe->Init (ctrl->cpos, -0.05, sh);
startframe->Init(ctrl->cpos, -0.05, g_game.character->shape);
}
// reset of result values
@ -93,7 +92,7 @@ void CIntro::Enter() {
}
void CIntro::Loop (double time_step) {
CControl *ctrl = Players.GetCtrl (g_game.player_id);
CControl *ctrl = g_game.player->ctrl;
int width = Winsys.resolution.width;
int height = Winsys.resolution.height;
check_gl_error();
@ -121,7 +120,7 @@ void CIntro::Loop (double time_step) {
UpdateSnow (time_step, ctrl);
DrawSnow (ctrl);
Char.Draw (g_game.char_id);
g_game.character->shape->Draw();
DrawHud (ctrl);
Reshape (width, height);
@ -131,7 +130,7 @@ void CIntro::Loop (double time_step) {
// -----------------------------------------------------------------------
void CIntro::Keyb (unsigned int key, bool special, bool release, int x, int y) {
CControl *ctrl = Players.GetCtrl (g_game.player_id);
CControl *ctrl = g_game.player->ctrl;
if (release) return;
abort_intro (ctrl);
}

View File

@ -62,9 +62,8 @@ double CKeyframe::interp (double frac, double v1, double v2) {
void CKeyframe::Init (const TVector3d& ref_position, double height_correction) {
if (!loaded) return;
CCharShape *shape = Char.GetShape (g_game.char_id);
shape->ResetNode ("head");
shape->ResetNode ("neck");
g_game.character->shape->ResetNode("head");
g_game.character->shape->ResetNode("neck");
refpos = ref_position;
heightcorr = height_correction;
active = true;
@ -273,7 +272,7 @@ void CKeyframe::Update (double timestep) {
double frac;
TVector3d pos;
CCharShape *shape = Char.GetShape (g_game.char_id);
CCharShape *shape = g_game.character->shape;
if (fabs (frames[keyidx].val[0]) < 0.0001) frac = 1.0;
else frac = (frames[keyidx].val[0] - keytime) / frames[keyidx].val[0];
@ -286,7 +285,7 @@ void CKeyframe::Update (double timestep) {
shape->ResetRoot ();
shape->ResetJoints ();
Players.GetCtrl (g_game.player_id)->cpos = pos;
g_game.player->ctrl->cpos = pos;
double disp_y = pos.y + TUX_Y_CORR + heightcorr;
shape->ResetNode (0);
shape->TranslateNode (0, TVector3d(pos.x, disp_y, pos.z));
@ -356,36 +355,36 @@ void CKeyframe::SaveTest (const string& dir, const string& filename) {
line += " [pos] " + Float_StrN (frame->val[1], 2);
line += " " + Float_StrN (frame->val[2], 2);
line += " " + Float_StrN (frame->val[3], 2);
if (frame->val[4] != 0) line += " [yaw] " + Float_StrN (frame->val[4], 0);
if (frame->val[5] != 0) line += " [pitch] " + Float_StrN (frame->val[5], 0);
if (frame->val[6] != 0) line += " [roll] " + Float_StrN (frame->val[6], 0);
if (frame->val[7] != 0) line += " [neck] " + Float_StrN (frame->val[7], 0);
if (frame->val[8] != 0) line += " [head] " + Float_StrN (frame->val[8], 0);
if (frame->val[4] != 0) line += " [yaw] " + Int_StrN((int)frame->val[4]);
if (frame->val[5] != 0) line += " [pitch] " + Int_StrN((int)frame->val[5]);
if (frame->val[6] != 0) line += " [roll] " + Int_StrN((int)frame->val[6]);
if (frame->val[7] != 0) line += " [neck] " + Int_StrN((int)frame->val[7]);
if (frame->val[8] != 0) line += " [head] " + Int_StrN((int)frame->val[8]);
double ll = frame->val[9];
double rr = frame->val[10];
if (ll != 0 || rr != 0)
line += " [sh] " + Float_StrN (ll, 0) + " " + Float_StrN (rr, 0);
line += " [sh] " + Int_StrN((int) ll) + " " + Int_StrN((int)rr);
ll = frame->val[11];
rr = frame->val[12];
if (ll != 0 || rr != 0)
line += " [arm] " + Float_StrN (ll, 0) + " " + Float_StrN (rr, 0);
line += " [arm] " + Int_StrN((int)ll) + " " + Int_StrN((int)rr);
ll = frame->val[13];
rr = frame->val[14];
if (ll != 0 || rr != 0)
line += " [hip] " + Float_StrN (ll, 0) + " " + Float_StrN (rr, 0);
line += " [hip] " + Int_StrN((int)ll) + " " + Int_StrN((int)rr);
ll = frame->val[15];
rr = frame->val[16];
if (ll != 0 || rr != 0)
line += " [knee] " + Float_StrN (ll, 0) + " " + Float_StrN (rr, 0);
line += " [knee] " + Int_StrN((int)ll) + " " + Int_StrN((int)rr);
ll = frame->val[17];
rr = frame->val[18];
if (ll != 0 || rr != 0)
line += " [ankle] " + Float_StrN (ll, 0) + " " + Float_StrN (rr, 0);
line += " [ankle] " + Int_StrN((int)ll) + " " + Int_StrN((int)rr);
list.Add (line);
}

View File

@ -42,11 +42,10 @@ void CLoading::Enter() {
void CLoading::Loop(double time_step) {
TCourse *CourseList = &Course.CourseList[0];
int ww = Winsys.resolution.width;
int hh = Winsys.resolution.height;
string msg = Trans.Text(29);
msg += " " + CourseList[g_game.course_id].name;
string msg = Trans.Text(29) + " " + g_game.course->name;
check_gl_error ();
ScopedRenderMode rm(GUI);
ClearRenderContext ();
@ -70,7 +69,7 @@ void CLoading::Loop(double time_step) {
FT.DrawString (CENTER, AutoYPosN (70), Trans.Text (30));
Winsys.SwapBuffers ();
Course.LoadCourse (g_game.course_id);
Course.LoadCourse (g_game.course);
g_game.location_id = Course.GetEnv ();
Env.LoadEnvironment (g_game.location_id, g_game.light_id);
State::manager.RequestEnterState (Intro);

View File

@ -45,16 +45,15 @@ void InitGame (int argc, char **argv) {
if (group_arg == "9") g_game.argument = 9;
}
g_game.player_id = 0;
g_game.player = NULL;
g_game.start_player = 0;
g_game.course_id = 0;
g_game.mirror_id = false;
g_game.char_id = 0;
g_game.course = NULL;
g_game.mirrorred = false;
g_game.character = NULL;
g_game.location_id = 0;
g_game.light_id = 0;
g_game.snow_id = 0;
g_game.cup = 0;
g_game.race_id = 0;
g_game.theme_id = 0;
g_game.force_treemap = 0;
g_game.treesize = 3;

View File

@ -359,12 +359,12 @@ void backsb (double *matrix, int n, double *soln) {
// ***************************************************************************
// ***************************************************************************
bool IntersectPolygon (const TPolygon& p, TVector3d *v) {
bool IntersectPolygon(const TPolygon& p, vector<TVector3d>& v) {
TRay ray;
double d, s, nuDotProd;
double distsq;
TVector3d nml = MakeNormal (p, v);
TVector3d nml = MakeNormal (p, &v[0]);
ray.pt = TVector3d(0., 0., 0.);
ray.vec = nml;
@ -376,11 +376,11 @@ bool IntersectPolygon (const TPolygon& p, TVector3d *v) {
if (fabs (d) > 1) return false;
for (int i=0; i < p.num_vertices; i++) {
for (size_t i=0; i < p.vertices.size(); i++) {
TVector3d *v0, *v1;
v0 = &v[p.vertices[i]];
v1 = &v[p.vertices[ (i+1) % p.num_vertices ]];
v1 = &v[p.vertices[(i + 1) % p.vertices.size()]];
TVector3d edge_vec = *v1 - *v0;
double edge_len = edge_vec.Norm();
@ -402,9 +402,9 @@ bool IntersectPolygon (const TPolygon& p, TVector3d *v) {
s = - (d + DotProduct (nml, ray.pt)) / nuDotProd;
TVector3d pt = ray.pt + s * ray.vec;
for (int i=0; i < p.num_vertices; i++) {
for (size_t i = 0; i < p.vertices.size(); i++) {
TVector3d edge_nml = CrossProduct (nml,
v[p.vertices[ (i+1) % p.num_vertices ]] - v[p.vertices[i]]);
v[p.vertices[(i + 1) % p.vertices.size()]] - v[p.vertices[i]]);
double wec = DotProduct (pt - v[p.vertices[i]], edge_nml);
if (wec < 0) return false;
@ -412,18 +412,18 @@ bool IntersectPolygon (const TPolygon& p, TVector3d *v) {
return true;
}
bool IntersectPolyhedron (const TPolyhedron& p) {
bool IntersectPolyhedron(TPolyhedron& p) {
bool hit = false;
for (size_t i=0; i<p.num_polygons; i++) {
for (size_t i = 0; i < p.polygons.size(); i++) {
hit = IntersectPolygon (p.polygons[i], p.vertices);
if (hit == true) break;
}
return hit;
}
TVector3d MakeNormal (const TPolygon& p, TVector3d *v) {
TVector3d MakeNormal (const TPolygon& p, const TVector3d *v) {
TVector3d v1 = v[p.vertices[1]] - v[p.vertices[0]];
TVector3d v2 = v[p.vertices[p.num_vertices-1]] - v[p.vertices[0]];
TVector3d v2 = v[p.vertices[p.vertices.size() - 1]] - v[p.vertices[0]];
TVector3d normal = CrossProduct (v1, v2);
normal.Norm();
@ -431,19 +431,8 @@ TVector3d MakeNormal (const TPolygon& p, TVector3d *v) {
}
TPolyhedron CopyPolyhedron (const TPolyhedron& ph) {
TPolyhedron newph = ph;
newph.vertices = new TVector3d[ph.num_vertices];
copy_n(ph.vertices, ph.num_vertices, newph.vertices);
return newph;
}
void FreePolyhedron (const TPolyhedron& ph) {
delete[] ph.vertices;
}
void TransPolyhedron (const TMatrix<4, 4>& mat, const TPolyhedron& ph) {
for (size_t i=0; i<ph.num_vertices; i++)
void TransPolyhedron (const TMatrix<4, 4>& mat, TPolyhedron& ph) {
for (size_t i = 0; i < ph.vertices.size(); i++)
ph.vertices[i] = TransformPoint (mat, ph.vertices[i]);
}

View File

@ -21,6 +21,7 @@ GNU General Public License for more details.
#include "bh.h"
#include "matrices.h"
#include <vector>
static const TVector3d GravVec(0.0, -1.0, 0.0);
@ -36,15 +37,13 @@ struct TPlane {
{}
};
struct TPolygon { int num_vertices; int *vertices; };
struct TPolygon { vector<int> vertices; };
struct TSphere { double radius; int divisions; };
struct TRay { TVector3d pt; TVector3d vec; };
struct TPolyhedron {
size_t num_vertices;
size_t num_polygons;
TVector3d *vertices;
TPolygon *polygons;
vector<TVector3d> vertices;
vector<TPolygon> polygons;
};
TVector3d ProjectToPlane(const TVector3d& nml, const TVector3d& v);
@ -64,12 +63,10 @@ TQuaternion MakeRotationQuaternion (const TVector3d& s, const TVector3d& t);
TQuaternion InterpolateQuaternions (const TQuaternion& q, TQuaternion r, double t);
TVector3d RotateVector (const TQuaternion& q, const TVector3d& v);
bool IntersectPolygon (const TPolygon& p, TVector3d *v);
bool IntersectPolyhedron (const TPolyhedron& p);
TVector3d MakeNormal (const TPolygon& p, TVector3d *v);
TPolyhedron CopyPolyhedron (const TPolyhedron& ph);
void FreePolyhedron (const TPolyhedron& ph);
void TransPolyhedron(const TMatrix<4, 4>& mat, const TPolyhedron& ph);
bool IntersectPolygon (const TPolygon& p, vector<TVector3d>& v);
bool IntersectPolyhedron (TPolyhedron& p);
TVector3d MakeNormal (const TPolygon& p, const TVector3d *v);
void TransPolyhedron(const TMatrix<4, 4>& mat, TPolyhedron& ph);
// --------------------------------------------------------------------
// ode solver

View File

@ -24,18 +24,18 @@ GNU General Public License for more details.
#define NEAR_CLIP_DIST 0.1
enum TRenderMode {
GUI,
GAUGE_BARS,
TEXFONT,
COURSE,
TREES,
PARTICLES,
TUX,
TUX_SHADOW,
SKY,
FOG_PLANE,
TRACK_MARKS,
RM_UNINITIALIZED = -1
GUI,
GAUGE_BARS,
TEXFONT,
COURSE,
TREES,
PARTICLES,
TUX,
TUX_SHADOW,
SKY,
FOG_PLANE,
TRACK_MARKS,
RM_UNINITIALIZED = -1
};

View File

@ -528,7 +528,7 @@ void TFlakeArea::Draw (const CControl *ctrl) const {
ScopedRenderMode rm(PARTICLES);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
Tex.BindTex (T_WIDGETS);
Tex.BindTex(SNOW_PART);
const TColor& particle_colour = Env.ParticleColor ();
glColor(particle_colour);
@ -581,25 +581,25 @@ void CFlakes::MakeSnowFlake (size_t ar, size_t i) {
static const GLfloat tex_coords[4][8] = {
{
0.0, 0.875,
0.125, 0.875,
0.125, 1.0,
0.0, 1.0
0.0, 0.5,
0.5, 0.5,
0.5, 0.0,
0.0, 0.0
}, {
0.125, 0.875,
0.25, 0.875,
0.25, 1.0,
0.125, 1.0
0.5, 0.5,
1.0, 0.5,
1.0, 0.0,
0.5, 0.0
}, {
0.0, 0.75,
0.125, 0.75,
0.125, 0.875,
0.0, 0.875
0.0, 1.0,
0.5, 1.0,
0.5, 0.5,
0.0, 0.5
}, {
0.125, 0.75,
0.25, 0.75,
0.25, 0.875,
0.125, 0.875
0.5, 1.0,
1.0, 1.0,
1.0, 0.5,
0.5, 0.5
}
};

View File

@ -30,6 +30,7 @@ GNU General Public License for more details.
#include "particles.h"
#include "textures.h"
#include "game_ctrl.h"
#include "tux.h"
#include "racing.h"
#include "winsys.h"
#include "physics.h"
@ -71,7 +72,7 @@ void CPaused::Mouse (int button, int state, int x, int y) {
// ====================================================================
void CPaused::Loop (double time_step) {
CControl *ctrl = Players.GetCtrl (g_game.player_id);
CControl *ctrl = g_game.player->ctrl;
int width = Winsys.resolution.width;
int height = Winsys.resolution.height;
check_gl_error();
@ -92,7 +93,7 @@ void CPaused::Loop (double time_step) {
DrawSnow (ctrl);
if (param.perf_level > 2) draw_particles (ctrl);
Char.Draw (g_game.char_id);
g_game.character->shape->Draw();
DrawHud (ctrl);
Reshape (width, height);

View File

@ -116,7 +116,6 @@ bool CControl::CheckTreeCollisions (const TVector3d& pos, TVector3d *tree_loc, d
} else return false;
}
CCharShape *shape = Char.GetShape (g_game.char_id);
double diam = 0.0;
TVector3d loc(0, 0, 0);
bool hit = false;
@ -125,7 +124,7 @@ bool CControl::CheckTreeCollisions (const TVector3d& pos, TVector3d *tree_loc, d
TCollidable *trees = &Course.CollArr[0];
size_t num_trees = Course.CollArr.size();
size_t tree_type = trees[0].tree_type;
TPolyhedron ph = Course.GetPoly (tree_type);
const TPolyhedron* ph = &Course.GetPoly (tree_type);
for (size_t i=0; i<num_trees; i++) {
diam = trees[i].diam;
@ -141,17 +140,16 @@ bool CControl::CheckTreeCollisions (const TVector3d& pos, TVector3d *tree_loc, d
// 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);
ph = &Course.GetPoly (tree_type);
}
TPolyhedron ph2 = CopyPolyhedron (ph);
TPolyhedron ph2 = *ph;
mat.SetScalingMatrix(diam, height, diam);
TransPolyhedron (mat, ph2);
mat.SetTranslationMatrix(loc.x, loc.y, loc.z);
TransPolyhedron (mat, ph2);
// hit = TuxCollision2 (pos, ph2);
hit = shape->Collision (pos, ph2);
FreePolyhedron (ph2);
hit = g_game.character->shape->Collision(pos, ph2);
if (hit == true) {
if (tree_loc != NULL) *tree_loc = loc;
@ -253,7 +251,7 @@ void CControl::AdjustPosition (const TPlane& surf_plane, double dist_from_surfac
}
void CControl::SetTuxPosition (double speed) {
CCharShape *shape = Char.GetShape (g_game.char_id);
CCharShape *shape = g_game.character->shape;
TVector2d playSize = Course.GetPlayDimensions();
TVector2d courseSize = Course.GetDimensions();
@ -624,7 +622,7 @@ void CControl::SolveOdeSystem (double timestep) {
// --------------------------------------------------------------------
void CControl::UpdatePlayerPos (double timestep) {
CCharShape *shape = Char.GetShape (g_game.char_id);
CCharShape *shape = g_game.character->shape;
double paddling_factor;
double flap_factor;
double dist_from_surface;

View File

@ -56,7 +56,6 @@ static void make_tri_list(void(*tri_func)(int, int, int, int), unsigned char Ena
}
}
TTexture* quadsquare::EnvmapTexture = NULL;
GLuint *quadsquare::VertexArrayIndices = NULL;
GLuint quadsquare::VertexArrayCounter;
GLuint quadsquare::VertexArrayMinIdx;
@ -96,10 +95,6 @@ quadsquare::quadsquare (quadcornerdata* pcd) {
if (y < MinY) MinY = y;
if (y > MaxY) MaxY = y;
}
if (pcd->Parent == NULL) {
EnvmapTexture = Tex.GetTexture (ENV_MAP);
}
}
quadsquare::~quadsquare() {
@ -741,20 +736,6 @@ void quadsquare::DrawTris() {
if (glUnlockArraysEXT_p) glUnlockArraysEXT_p();
}
void quadsquare::DrawEnvmapTris() {
if (VertexArrayCounter > 0 && EnvmapTexture != NULL) {
glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
EnvmapTexture->Bind();
DrawTris();
glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
}
}
void quadsquare::InitArrayCounters() {
VertexArrayCounter = 0;
VertexArrayMinIdx = INT_MAX;
@ -779,14 +760,6 @@ void quadsquare::Render (const quadcornerdata& cd, GLubyte *vnc_array) {
Course.TerrList[j].texture->Bind();
DrawTris ();
if (TerrList[j].shiny && param.perf_level > 1) {
glDisableClientState (GL_COLOR_ARRAY);
glColor4f (1.0, 1.0, 1.0, ENV_MAP_ALPHA / 255.0);
DrawEnvmapTris();
glEnableClientState (GL_COLOR_ARRAY);
}
}
}
@ -823,18 +796,6 @@ void quadsquare::Render (const quadcornerdata& cd, GLubyte *vnc_array) {
DrawTris();
}
}
/*
if (param.perf_level > 1) {
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
for (i=0; i<VertexArrayCounter; i++) {
colorval (VertexArrayIndices[i], 3) =
(TerrList[Terrain[VertexArrayIndices[i]]].shiny) ?
ENV_MAP_ALPHA : 0;
}
DrawEnvmapTris();
}
*/
}
}
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

View File

@ -25,13 +25,11 @@ algorithm should be replaced with a more convenient quadtree algorithm.
#include "bh.h"
#include "view.h"
class TTexture;
enum vertex_loc_t {
East,
South,
Center
East,
South,
Center
};
struct HeightMapInfo {
@ -73,7 +71,6 @@ struct quadsquare {
static double ScaleX, ScaleZ;
static int RowSize, NumRows;
static char *Terrain;
static TTexture* EnvmapTexture;
static GLuint *VertexArrayIndices;
static GLuint VertexArrayCounter;
@ -85,7 +82,6 @@ struct quadsquare {
static void MakeNoBlendTri( int a, int b, int c, int terrain );
static void DrawTris();
static void DrawEnvmapTris();
static void InitArrayCounters();
quadsquare (quadcornerdata* pcd);

View File

@ -63,12 +63,12 @@ static void UpdateInfo() {
}
void SetRaceConditions() {
g_game.mirror_id = mirror->GetValue() != 0;
g_game.mirrorred = mirror->GetValue() != 0;
g_game.light_id = light->GetValue();
g_game.snow_id = snow->GetValue();
g_game.wind_id = wind->GetValue();
g_game.course_id = course->GetValue();
g_game.course = &Course.CourseList[course->GetValue()];
g_game.theme_id = CourseList[course->GetValue()].music_theme;
g_game.game_type = PRACTICING;
State::manager.RequestEnterState (Loading);
@ -162,14 +162,14 @@ void CRaceSelect::Enter() {
ResetGUI ();
course = AddUpDown(area.left + framewidth + 8, frametop, 0, (int)Course.CourseList.size() - 1, (int)g_game.course_id);
course = AddUpDown(area.left + framewidth + 8, frametop, 0, (int)Course.CourseList.size() - 1, g_game.course?(int)Course.GetCourseIdx(g_game.course):0);
random_btn = AddIconButton(iconleft + iconspace * 4, icontop, Tex.GetTexture(RANDOM_BUTT), iconsize, 0, 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, 0, 0);
int siz = FT.AutoSizeN (5);
mirror = AddIconButton (iconleft + iconspace*3, icontop, Tex.GetTexture (MIRROR_BUTT), iconsize, 1, (int)g_game.mirrorred);
random_btn = AddIconButton (iconleft + iconspace*4, icontop, Tex.GetTexture (RANDOM_BUTT), iconsize, 0, 0); int siz = FT.AutoSizeN (5);
int len1 = FT.GetTextWidth (Trans.Text(13));
textbuttons[0] = AddTextButton (Trans.Text(13), area.right-len1-50, AutoYPosN (80), siz);
textbuttons[1] = AddTextButton (Trans.Text(8), area.left + 50, AutoYPosN (80), siz);

View File

@ -36,6 +36,7 @@ GNU General Public License for more details.
#include "reset.h"
#include "winsys.h"
#include "physics.h"
#include "tux.h"
#include <algorithm>
#define MAX_JUMP_AMT 1.0
@ -67,7 +68,7 @@ static int lastsound = -1;
void CRacing::Keyb (unsigned int key, bool special, bool release, int x, int y) {
switch (key) {
// steering flipflops
// steering flipflops
case SDLK_UP:
key_paddling = !release;
break;
@ -86,7 +87,7 @@ void CRacing::Keyb (unsigned int key, bool special, bool release, int x, int y)
case SDLK_t:
trick_modifier = !release;
break;
// mode changing and other actions
// mode changing and other actions
case SDLK_ESCAPE:
if (!release) {
g_game.raceaborted = true;
@ -104,27 +105,27 @@ void CRacing::Keyb (unsigned int key, bool special, bool release, int x, int y)
if (!release) ScreenshotN ();
break;
// view changing
// view changing
case SDLK_1:
if (!release) {
set_view_mode (Players.GetCtrl (g_game.player_id), ABOVE);
set_view_mode (g_game.player->ctrl, ABOVE);
param.view_mode = ABOVE;
}
break;
case SDLK_2:
if (!release) {
set_view_mode (Players.GetCtrl (g_game.player_id), FOLLOW);
set_view_mode (g_game.player->ctrl, FOLLOW);
param.view_mode = FOLLOW;
}
break;
case SDLK_3:
if (!release) {
set_view_mode (Players.GetCtrl (g_game.player_id), BEHIND);
set_view_mode (g_game.player->ctrl, BEHIND);
param.view_mode = BEHIND;
}
break;
// toggle
// toggle
case SDLK_h:
if (!release) param.show_hud = !param.show_hud;
break;
@ -166,7 +167,7 @@ void CRacing::Jbutt (int button, int state) {
}
void CalcJumpEnergy (double time_step) {
CControl *ctrl = Players.GetCtrl (g_game.player_id);
CControl *ctrl = g_game.player->ctrl;
if (ctrl->jump_charging) {
ctrl->jump_amt = min (MAX_JUMP_AMT, g_game.time - charge_start_time);
@ -195,7 +196,7 @@ void SetSoundVolumes () {
// ---------------------------- init ----------------------------------
void CRacing::Enter() {
CControl *ctrl = Players.GetCtrl (g_game.player_id);
CControl *ctrl = g_game.player->ctrl;
if (param.view_mode < 0 || param.view_mode >= NUM_VIEW_MODES) {
param.view_mode = ABOVE;
@ -292,7 +293,7 @@ void CalcSteeringControls (CControl *ctrl, double time_step) {
void CalcFinishControls (CControl *ctrl, double timestep, bool airborne) {
double speed = ctrl->cvel.Length();
double dir_angle = atan(ctrl->cvel.x / ctrl->cvel.z) * 57.3;
double dir_angle = RADIANS_TO_ANGLES(atan(ctrl->cvel.x / ctrl->cvel.z));
if (fabs (dir_angle) > 5 && speed > 5) {
ctrl->turn_fact = dir_angle / 20;
@ -338,7 +339,7 @@ void CalcTrickControls (CControl *ctrl, double time_step, bool airborne) {
// ====================================================================
void CRacing::Loop (double time_step) {
CControl *ctrl = Players.GetCtrl (g_game.player_id);
CControl *ctrl = g_game.player->ctrl;
double ycoord = Course.FindYCoord (ctrl->cpos.x, ctrl->cpos.z);
bool airborne = (bool) (ctrl->cpos.y > (ycoord + JUMP_MAX_START_HEIGHT));
@ -371,7 +372,7 @@ void CRacing::Loop (double time_step) {
update_particles (time_step);
draw_particles (ctrl);
}
Char.Draw (g_game.char_id);
g_game.character->shape->Draw();
UpdateWind (time_step);
UpdateSnow (time_step, ctrl);
DrawSnow (ctrl);

View File

@ -41,9 +41,10 @@ static TUpDown* character;
void QuitRegistration () {
Players.ResetControls ();
Players.AllocControl (player->GetValue());
g_game.player_id = player->GetValue();
g_game.player = Players.GetPlayer(player->GetValue());
g_game.char_id = character->GetValue();
g_game.character = &Char.CharList[character->GetValue()];
Char.FreeCharacterPreviews(); // From here on, character previews are no longer required
State::manager.RequestEnterState (GameTypeSelect);
}
@ -56,7 +57,7 @@ void CRegist::Keyb (unsigned int key, bool special, bool release, int x, int y)
break;
case SDLK_RETURN:
if (focussed == textbuttons[1]) {
g_game.player_id = player->GetValue();
g_game.player = Players.GetPlayer(player->GetValue());
State::manager.RequestEnterState (NewPlayer);
} else QuitRegistration ();
break;
@ -69,7 +70,7 @@ void CRegist::Mouse (int button, int state, int x, int y) {
if (focussed == textbuttons[0])
QuitRegistration ();
else if (focussed == textbuttons[1]) {
g_game.player_id = player->GetValue();
g_game.player = Players.GetPlayer(player->GetValue());
State::manager.RequestEnterState (NewPlayer);
}
}
@ -128,8 +129,6 @@ void CRegist::Loop (double timestep) {
Tex.Draw (TOP_RIGHT, ww-256, 0, 1);
Tex.Draw(T_TITLE_SMALL, CENTER, AutoYPosN(5), Winsys.scale);
// DrawFrameX (area.left, area.top, area.right-area.left, area.bottom - area.top,
// 0, colMBackgr, col, 0.2);
FT.AutoSizeN (3);
FT.SetColor (colWhite);
@ -142,7 +141,7 @@ void CRegist::Loop (double timestep) {
else col = colWhite;
DrawFrameX (area.left, area.top, framewidth, frameheight, 3, colMBackgr, col, 1.0);
FT.SetColor (col);
FT.DrawString (area.left + 20, area.top, Players.GetName (player->GetValue()));
FT.DrawString(area.left + 20, area.top, Players.GetPlayer(player->GetValue())->name);
Players.GetAvatarTexture(player->GetValue())->DrawFrame(
area.left + 60, AutoYPosN (40), texsize, texsize, 3, colWhite);

View File

@ -29,6 +29,7 @@ GNU General Public License for more details.
#include "course.h"
#include "track_marks.h"
#include "game_ctrl.h"
#include "tux.h"
#include "racing.h"
#include "winsys.h"
#include "physics.h"
@ -49,7 +50,7 @@ void CReset::Enter() {
}
void CReset::Loop(double time_step) {
CControl *ctrl = Players.GetCtrl (g_game.player_id);
CControl *ctrl = g_game.player->ctrl;
double elapsed_time = Winsys.ClockTime () - reset_start_time;
static bool tux_visible = true;
static int tux_visible_count = 0;
@ -112,7 +113,7 @@ void CReset::Loop(double time_step) {
position_reset = true;
} // if elapsed time
if (tux_visible) Char.Draw (g_game.char_id);
if (tux_visible) g_game.character->shape->Draw();
if (++tux_visible_count > 3) {
tux_visible = (bool) !tux_visible;

View File

@ -34,7 +34,8 @@ GNU General Public License for more details.
CScore Score;
int CScore::AddScore (size_t list_idx, const TScore& score) {
int CScore::AddScore(const TCourse* course, const TScore& score) {
size_t list_idx = Course.GetCourseIdx(course);
if (list_idx >= Scorelist.size()) return 999;
if (score.points < 1) return 999;
@ -127,7 +128,7 @@ bool CScore::LoadHighScore () {
for (size_t i=0; i<list.Count(); i++) {
const string& line = list.Line(i);
string course = SPStrN (line, "course", "unknown");
size_t cidx = Course.GetCourseIdx (course);
TCourse* cidx = Course.GetCourse(course);
TScore score;
score.player = SPStrN (line, "plyr", "unknown");
@ -140,14 +141,16 @@ bool CScore::LoadHighScore () {
return true;
}
int CScore::CalcRaceResult () {
int CScore::CalcRaceResult() {
g_game.race_result = -1;
if (g_game.time <= g_game.time_req.x &&
g_game.herring >= g_game.herring_req.x) g_game.race_result = 0;
if (g_game.time <= g_game.time_req.y &&
g_game.herring >= g_game.herring_req.y) g_game.race_result = 1;
if (g_game.time <= g_game.time_req.z &&
g_game.herring >= g_game.herring_req.z) g_game.race_result = 2;
if (g_game.game_type == CUPRACING) {
if (g_game.time <= g_game.race->time.x &&
g_game.herring >= g_game.race->herrings.x) g_game.race_result = 0;
if (g_game.time <= g_game.race->time.y &&
g_game.herring >= g_game.race->herrings.y) g_game.race_result = 1;
if (g_game.time <= g_game.race->time.z &&
g_game.herring >= g_game.race->herrings.z) g_game.race_result = 2;
}
int herringpt = g_game.herring * 10;
double timept = Course.GetDimensions().y - (g_game.time * 10);
@ -158,9 +161,9 @@ int CScore::CalcRaceResult () {
TempScore.points = g_game.score;
TempScore.herrings = g_game.herring;
TempScore.time = g_game.time;
TempScore.player = Players.GetName (g_game.player_id);
TempScore.player = g_game.player->name;
return AddScore (g_game.course_id, TempScore);
return AddScore (g_game.course, TempScore);
}
// --------------------------------------------------------------------

View File

@ -46,7 +46,7 @@ private:
void Mouse(int button, int state, int x, int y);
void Motion(int x, int y);
public:
int AddScore (size_t list_idx, const TScore& score);
int AddScore(const TCourse* course, const TScore& score);
const TScoreList *GetScorelist (size_t list_idx) const;
void PrintScorelist (size_t list_idx) const;
bool SaveHighScore () const;

View File

@ -66,12 +66,11 @@ void CSplashScreen::Loop(double timestep) {
Trans.LoadLanguages ();
Trans.LoadTranslations (param.language); // Before first texts are being displayed
// FT.SetFont ("normal");
Tex.Draw (TEXLOGO, CENTER, 60, Winsys.scale);
FT.SetColor (colDYell);
FT.AutoSizeN (6);
int top = AutoYPosN (60);
int dist = FT.AutoDistanceN (3);
int top = AutoYPosN (60); int dist = FT.AutoDistanceN (3);
FT.DrawString (CENTER, top, Trans.Text(67));
FT.DrawString (CENTER, top+dist, Trans.Text(68));

View File

@ -700,7 +700,7 @@ void ScreenshotN () {
CImage image;
string path = param.screenshot_dir;
path += SEP;
path += Course.CourseList[g_game.course_id].dir;
path += g_game.course->dir;
path += "_";
path += GetTimeString();
int type = SCREENSHOT_PROC;

View File

@ -44,7 +44,7 @@ GNU General Public License for more details.
#define TUXBONUS 21
#define MOUSECURSOR 22
#define SNOW_PART 23
#define ENV_MAP 24
#define T_ENERGY_MASK 25
#define T_MASK_OUTLINE 26
#define NUMERIC_FONT 27
@ -53,14 +53,13 @@ GNU General Public License for more details.
#define RANDOM_BUTT 30
#define T_YELLHERRING 31
#define T_TIME 32
#define STARS 33
#define HERRING_ICON2 34
#define SPEED_KNOB 35
#define CUPICON 36
#define CHECKBOX 37
#define CHECKMARK_SMALL 38
#define CHECKMARK 39
#define T_WIDGETS 40
#define T_SNOW1 41
#define T_SNOW2 42
#define T_SNOW3 43

View File

@ -183,7 +183,7 @@ void CharKeys (unsigned int key, bool special, bool release, int x, int y) {
xposition += 0.03;
break;
// set rotations for view
// set rotations for view
case SDLK_1:
SetRotation (0, 0, 0);
break;
@ -197,7 +197,7 @@ void CharKeys (unsigned int key, bool special, bool release, int x, int y) {
SetRotation (0, -80, 0);
break;
// select node
// select node
case SDLK_PAGEUP:
ChangeNode (-1);
break;
@ -211,7 +211,7 @@ void CharKeys (unsigned int key, bool special, bool release, int x, int y) {
ChangeNode (-charbase);
break;
// select action
// select action
case SDLK_DOWN:
if (curr_act < lastact) curr_act++;
if (action->type[curr_act] == 4) comp = 0;
@ -229,7 +229,7 @@ void CharKeys (unsigned int key, bool special, bool release, int x, int y) {
ChangeValue (type, 1);
break;
// select value
// select value
case SDLK_SPACE:
if (type == 0 || type == 4) {
comp++;

View File

@ -34,10 +34,10 @@ GNU General Public License for more details.
enum track_types_t {
TRACK_HEAD,
TRACK_MARK,
TRACK_TAIL,
NUM_TRACK_TYPES
TRACK_HEAD,
TRACK_MARK,
TRACK_TAIL,
NUM_TRACK_TYPES
};
struct track_quad_t {

View File

@ -608,10 +608,9 @@ bool CCharShape::CheckPolyhedronCollision(const TCharNode *node, const TMatrix<4
TMatrix<4, 4> newInvModelMatrix = node->invtrans * invModelMatrix;
if (node->visible) {
TPolyhedron newph = CopyPolyhedron (ph);
TPolyhedron newph = ph;
TransPolyhedron (newInvModelMatrix, newph);
hit = IntersectPolyhedron (newph);
FreePolyhedron (newph);
}
if (hit == true) return hit;

View File

@ -31,9 +31,9 @@ void SetCameraDistance (double val);
// ------------- viewfrustum ------------------------------------------
enum clip_result_t {
NoClip,
SomeClip,
NotVisible
NoClip,
SomeClip,
NotVisible
};
void SetupViewFrustum (const CControl *ctrl);