309 lines
8.0 KiB
C++
309 lines
8.0 KiB
C++
/* --------------------------------------------------------------------
|
|
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.
|
|
---------------------------------------------------------------------*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <etr_config.h>
|
|
#endif
|
|
|
|
#include "depot.h"
|
|
#include "textures.h"
|
|
#include "spx.h"
|
|
#include "winsys.h"
|
|
#include "ogl.h"
|
|
#include "gui.h"
|
|
#include <cctype>
|
|
|
|
|
|
static const GLshort fullsize_texture[] = {
|
|
0, 1,
|
|
1, 1,
|
|
1, 0,
|
|
0, 0
|
|
};
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
// class TTexture
|
|
// --------------------------------------------------------------------
|
|
|
|
bool TTexture::Load(const std::string& filename, bool repeatable) {
|
|
texture.setSmooth(true);
|
|
texture.setRepeated(repeatable);
|
|
return texture.loadFromFile(filename);
|
|
}
|
|
|
|
bool TTexture::LoadDepot(const std::string &depotpath, bool repeatable) {
|
|
auto path = DepotMustResolveFile(depotpath);
|
|
return Load(path, repeatable);
|
|
}
|
|
|
|
bool TTexture::Load(const std::string& dir, const std::string& filename, bool repeatable) {
|
|
return Load(MakePathStr(dir, filename), repeatable);
|
|
}
|
|
|
|
void TTexture::Bind() {
|
|
sf::Texture::bind(&texture);
|
|
}
|
|
|
|
void TTexture::Draw() {
|
|
GLint w, h;
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
Bind();
|
|
|
|
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
|
|
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
|
|
|
|
glColor4f(1.0, 1.0, 1.0, 1.0);
|
|
const GLint vtx[] = {
|
|
0, 0,
|
|
w, 0,
|
|
w, h,
|
|
0, h
|
|
};
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
|
glVertexPointer(2, GL_INT, 0, vtx);
|
|
glTexCoordPointer(2, GL_SHORT, 0, fullsize_texture);
|
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
|
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
|
}
|
|
|
|
void TTexture::Draw(int x, int y, float size) {
|
|
GLint w, h;
|
|
GLfloat width, height, top, bott, left, right;
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
Bind();
|
|
|
|
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
|
|
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
|
|
|
|
width = w * size;
|
|
height = h * size;
|
|
top = Winsys.resolution.height - y;
|
|
bott = top - height;
|
|
|
|
if (x >= 0) left = x;
|
|
else left = (Winsys.resolution.width - width) / 2;
|
|
right = left + width;
|
|
|
|
glColor4f(1.0, 1.0, 1.0, 1.0);
|
|
const GLfloat vtx[] = {
|
|
left, bott,
|
|
right, bott,
|
|
right, top,
|
|
left, top
|
|
};
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
|
glVertexPointer(2, GL_FLOAT, 0, vtx);
|
|
glTexCoordPointer(2, GL_SHORT, 0, fullsize_texture);
|
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
|
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
|
}
|
|
|
|
void TTexture::Draw(int x, int y, float width, float height) {
|
|
GLfloat top, bott, left, right;
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
Bind();
|
|
|
|
top = Winsys.resolution.height - y;
|
|
bott = top - height;
|
|
if (x >= 0) left = x;
|
|
else left = (Winsys.resolution.width - width) / 2;
|
|
right = left + width;
|
|
|
|
glColor4f(1.0, 1.0, 1.0, 1.0);
|
|
const GLfloat vtx[] = {
|
|
left, bott,
|
|
right, bott,
|
|
right, top,
|
|
left, top
|
|
};
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
|
glVertexPointer(2, GL_FLOAT, 0, vtx);
|
|
glTexCoordPointer(2, GL_SHORT, 0, fullsize_texture);
|
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
|
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
|
}
|
|
|
|
void TTexture::DrawFrame(int x, int y, int w, int h, int frame, const sf::Color& col) {
|
|
if (w < 1) w = texture.getSize().x;
|
|
if (h < 1) h = texture.getSize().y;
|
|
|
|
if (frame > 0)
|
|
DrawFrameX(x - frame, y - frame, w + 2 * frame, h + 2 * frame, frame, colTransp, col, 1.f);
|
|
|
|
sf::Sprite temp(texture);
|
|
temp.setPosition(x, y);
|
|
temp.setScale((float) w / (float) texture.getSize().x, (float) h / (float) texture.getSize().y);
|
|
Winsys.draw(temp);
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
// class CTexture
|
|
// --------------------------------------------------------------------
|
|
|
|
CTexture Tex;
|
|
|
|
CTexture::CTexture() {
|
|
}
|
|
|
|
CTexture::~CTexture() {
|
|
FreeTextureList();
|
|
}
|
|
|
|
bool CTexture::LoadTextureList() {
|
|
FreeTextureList();
|
|
CSPList list;
|
|
if (list.LoadDepot("//data/textures/textures.lst")) {
|
|
for (CSPList::const_iterator line = list.cbegin(); line != list.cend(); ++line) {
|
|
int id = SPIntN(*line, "id", -1);
|
|
CommonTex.resize(std::max(CommonTex.size(), (std::size_t)id+1));
|
|
std::string texfile = SPStrN(*line, "file");
|
|
bool rep = SPBoolN(*line, "repeat", false);
|
|
if (id >= 0) {
|
|
CommonTex[id] = new TTexture();
|
|
CommonTex[id]->LoadDepot(texfile, rep);
|
|
} else Message("wrong texture id in textures.lst");
|
|
}
|
|
} else {
|
|
Message("failed to load common textures");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void CTexture::FreeTextureList() {
|
|
for (std::size_t i=0; i<CommonTex.size(); i++) {
|
|
delete CommonTex[i];
|
|
}
|
|
CommonTex.clear();
|
|
}
|
|
|
|
TTexture* CTexture::GetTexture(std::size_t idx) const {
|
|
if (idx >= CommonTex.size()) return nullptr;
|
|
return CommonTex[idx];
|
|
}
|
|
|
|
const sf::Texture& CTexture::GetSFTexture(std::size_t idx) const {
|
|
return CommonTex[idx]->texture;
|
|
}
|
|
|
|
bool CTexture::BindTex(std::size_t idx) {
|
|
if (idx >= CommonTex.size()) return false;
|
|
CommonTex[idx]->Bind();
|
|
return true;
|
|
}
|
|
|
|
// ---------------------------- Draw ----------------------------------
|
|
|
|
void CTexture::Draw(std::size_t idx) {
|
|
if (CommonTex.size() > idx)
|
|
CommonTex[idx]->Draw();
|
|
}
|
|
|
|
void CTexture::Draw(std::size_t idx, int x, int y, float size) {
|
|
if (CommonTex.size() > idx)
|
|
CommonTex[idx]->Draw(x, y, size);
|
|
}
|
|
|
|
void CTexture::Draw(std::size_t idx, int x, int y, int width, int height) {
|
|
if (CommonTex.size() > idx)
|
|
CommonTex[idx]->Draw(x, y, width, height);
|
|
}
|
|
|
|
void CTexture::DrawFrame(std::size_t idx, int x, int y, double w, double h, int frame, const sf::Color& col) {
|
|
if (CommonTex.size() > idx)
|
|
CommonTex[idx]->DrawFrame(x, y, w, h, frame, col);
|
|
}
|
|
|
|
// -------------------------- numeric strings -------------------------
|
|
|
|
void CTexture::DrawNumChr(char c, int x, int y, int w, int h) {
|
|
int idx;
|
|
if (std::isdigit((unsigned char)c))
|
|
idx = c - '0';
|
|
else if (c == ':')
|
|
idx = 10;
|
|
else if (c == ' ')
|
|
idx = 11;
|
|
else
|
|
return;
|
|
|
|
// texture coords
|
|
float texw = 22.0 / 256.0;
|
|
float texleft = idx * texw;
|
|
float texright = (idx + 1) * texw;
|
|
|
|
const GLfloat tex[] = {
|
|
texleft, 1,
|
|
texright, 1,
|
|
texright, 0,
|
|
texleft, 0
|
|
};
|
|
const GLfloat vtx[] = {
|
|
static_cast<GLfloat>(x),
|
|
static_cast<GLfloat>(Winsys.resolution.height - y - h),
|
|
static_cast<GLfloat>(x + w * 0.9f),
|
|
static_cast<GLfloat>(Winsys.resolution.height - y - h),
|
|
static_cast<GLfloat>(x + w * 0.9f),
|
|
static_cast<GLfloat>(Winsys.resolution.height - y),
|
|
static_cast<GLfloat>(x),
|
|
static_cast<GLfloat>(Winsys.resolution.height - y)
|
|
};
|
|
|
|
glVertexPointer(2, GL_FLOAT, 0, vtx);
|
|
glTexCoordPointer(2, GL_FLOAT, 0, tex);
|
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
|
}
|
|
|
|
void CTexture::DrawNumStr(const std::string& s, int x, int y, float size, const sf::Color& col) {
|
|
if (!BindTex(NUMERIC_FONT)) {
|
|
Message("DrawNumStr: missing texture");
|
|
return;
|
|
}
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
glEnable(GL_TEXTURE_2D);
|
|
int qw = (int)(22 * size);
|
|
int qh = (int)(32 * size);
|
|
|
|
glColor(col);
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
for (std::size_t i=0; i < s.size(); i++) {
|
|
DrawNumChr(s[i], x + (int)i*qw, y, qw, qh);
|
|
}
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
|
}
|