mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-14 00:54:05 +02:00
This commit is contained in:
21
src/camera.h
21
src/camera.h
@@ -143,22 +143,19 @@ struct Camera : ICamera {
|
||||
if (state == STATE_CUTSCENE) {
|
||||
timer += Core::deltaTime * 30.0f;
|
||||
float t = timer - int(timer);
|
||||
int indexA = int(timer) % level->cameraFramesCount;
|
||||
int indexB = (indexA + 1) % level->cameraFramesCount;
|
||||
TR::CameraFrame *frameA = &level->cameraFrames[indexA];
|
||||
TR::CameraFrame *frameB = &level->cameraFrames[indexB];
|
||||
int indexA = min(int(timer), level->cameraFramesCount - 1);
|
||||
int indexB = min((indexA + 1), level->cameraFramesCount - 1);
|
||||
|
||||
if (indexB < indexA) {
|
||||
indexB = indexA;
|
||||
timer = 0.0f;
|
||||
if (level->cutEntity != -1) {
|
||||
// TODO: level end
|
||||
level->initCutscene();
|
||||
game->playTrack(0, true);
|
||||
} else
|
||||
if (indexA == level->cameraFramesCount - 1) {
|
||||
if (level->cutEntity != -1)
|
||||
game->loadLevel(TR::LevelID(level->id + 1));
|
||||
else
|
||||
state = STATE_FOLLOW;
|
||||
}
|
||||
|
||||
TR::CameraFrame *frameA = &level->cameraFrames[indexA];
|
||||
TR::CameraFrame *frameB = &level->cameraFrames[indexB];
|
||||
|
||||
const int eps = 512;
|
||||
|
||||
if (abs(frameA->pos.x - frameB->pos.x) > eps || abs(frameA->pos.y - frameB->pos.y) > eps || abs(frameA->pos.z - frameB->pos.z) > eps) {
|
||||
|
@@ -28,6 +28,7 @@ struct ICamera {
|
||||
|
||||
struct IGame {
|
||||
virtual ~IGame() {}
|
||||
virtual void loadLevel(TR::LevelID id) {}
|
||||
virtual TR::Level* getLevel() { return NULL; }
|
||||
virtual MeshBuilder* getMesh() { return NULL; }
|
||||
virtual ICamera* getCamera() { return NULL; }
|
||||
|
24
src/game.h
24
src/game.h
@@ -8,7 +8,18 @@
|
||||
|
||||
namespace Game {
|
||||
Level *level;
|
||||
Stream *nextLevel;
|
||||
}
|
||||
|
||||
void loadAsync(Stream *stream, void *userData) {
|
||||
if (!stream) {
|
||||
if (Game::level) Game::level->isEnded = false;
|
||||
return;
|
||||
}
|
||||
Game::nextLevel = stream;
|
||||
}
|
||||
|
||||
namespace Game {
|
||||
void startLevel(Stream *lvl) {
|
||||
delete level;
|
||||
level = new Level(*lvl);
|
||||
@@ -21,6 +32,8 @@ namespace Game {
|
||||
}
|
||||
|
||||
void init(Stream *lvl) {
|
||||
nextLevel = NULL;
|
||||
|
||||
Core::init();
|
||||
UI::init(level);
|
||||
|
||||
@@ -43,7 +56,7 @@ namespace Game {
|
||||
}
|
||||
|
||||
void init(char *lvlName = NULL, char *sndName = NULL) {
|
||||
if (!lvlName) lvlName = (char*)"level/LEVEL2.PSX";
|
||||
if (!lvlName) lvlName = (char*)"level/TITLE.PSX";
|
||||
init(new Stream(lvlName));
|
||||
}
|
||||
|
||||
@@ -69,6 +82,15 @@ namespace Game {
|
||||
|
||||
void update(float delta) {
|
||||
PROFILE_MARKER("UPDATE");
|
||||
|
||||
if (nextLevel) {
|
||||
startLevel(nextLevel);
|
||||
nextLevel = NULL;
|
||||
}
|
||||
|
||||
if (level->isEnded)
|
||||
return;
|
||||
|
||||
Input::update();
|
||||
|
||||
if (Input::down[ikV]) { // third <-> first person view
|
||||
|
275
src/inventory.h
275
src/inventory.h
@@ -29,58 +29,62 @@ struct Inventory {
|
||||
Page page, targetPage;
|
||||
int itemsCount;
|
||||
|
||||
TR::LevelID nextLevel; // toggle result
|
||||
|
||||
struct Item {
|
||||
TR::Entity::Type type;
|
||||
int count;
|
||||
float angle;
|
||||
Animation *anim;
|
||||
|
||||
int value;
|
||||
|
||||
struct Desc {
|
||||
const char *name;
|
||||
StringID str;
|
||||
Page page;
|
||||
int model;
|
||||
} desc;
|
||||
|
||||
Item() : anim(NULL) {}
|
||||
|
||||
Item(TR::Level *level, TR::Entity::Type type, int count = 1) : type(type), count(count), angle(0.0f) {
|
||||
Item(TR::Level *level, TR::Entity::Type type, int count = 1) : type(type), count(count), angle(0.0f), value(0) {
|
||||
switch (type) {
|
||||
case TR::Entity::INV_PASSPORT : desc = { "Game", PAGE_OPTION, level->extra.inv.passport }; break;
|
||||
case TR::Entity::INV_PASSPORT_CLOSED : desc = { "Game", PAGE_OPTION, level->extra.inv.passport_closed }; break;
|
||||
case TR::Entity::INV_MAP : desc = { "Map", PAGE_INVENTORY, level->extra.inv.map }; break;
|
||||
case TR::Entity::INV_COMPASS : desc = { "Compass", PAGE_INVENTORY, level->extra.inv.compass }; break;
|
||||
case TR::Entity::INV_HOME : desc = { "Lara's Home", PAGE_OPTION, level->extra.inv.home }; break;
|
||||
case TR::Entity::INV_DETAIL : desc = { "Detail Levels", PAGE_OPTION, level->extra.inv.detail }; break;
|
||||
case TR::Entity::INV_SOUND : desc = { "Sound", PAGE_OPTION, level->extra.inv.sound }; break;
|
||||
case TR::Entity::INV_CONTROLS : desc = { "Controls", PAGE_OPTION, level->extra.inv.controls }; break;
|
||||
case TR::Entity::INV_GAMMA : desc = { "Gamma", PAGE_OPTION, level->extra.inv.gamma }; break;
|
||||
case TR::Entity::INV_PASSPORT : desc = { STR_GAME, PAGE_OPTION, level->extra.inv.passport }; break;
|
||||
case TR::Entity::INV_PASSPORT_CLOSED : desc = { STR_GAME, PAGE_OPTION, level->extra.inv.passport_closed }; break;
|
||||
case TR::Entity::INV_MAP : desc = { STR_MAP, PAGE_INVENTORY, level->extra.inv.map }; break;
|
||||
case TR::Entity::INV_COMPASS : desc = { STR_COMPASS, PAGE_INVENTORY, level->extra.inv.compass }; break;
|
||||
case TR::Entity::INV_HOME : desc = { STR_HOME, PAGE_OPTION, level->extra.inv.home }; break;
|
||||
case TR::Entity::INV_DETAIL : desc = { STR_DETAIL, PAGE_OPTION, level->extra.inv.detail }; break;
|
||||
case TR::Entity::INV_SOUND : desc = { STR_SOUND, PAGE_OPTION, level->extra.inv.sound }; break;
|
||||
case TR::Entity::INV_CONTROLS : desc = { STR_CONTROLS, PAGE_OPTION, level->extra.inv.controls }; break;
|
||||
case TR::Entity::INV_GAMMA : desc = { STR_GAMMA, PAGE_OPTION, level->extra.inv.gamma }; break;
|
||||
|
||||
case TR::Entity::INV_PISTOLS : desc = { "Pistols", PAGE_INVENTORY, level->extra.inv.weapon[0] }; break;
|
||||
case TR::Entity::INV_SHOTGUN : desc = { "Shotgun", PAGE_INVENTORY, level->extra.inv.weapon[1] }; break;
|
||||
case TR::Entity::INV_MAGNUMS : desc = { "Magnums", PAGE_INVENTORY, level->extra.inv.weapon[2] }; break;
|
||||
case TR::Entity::INV_UZIS : desc = { "Uzis", PAGE_INVENTORY, level->extra.inv.weapon[3] }; break;
|
||||
case TR::Entity::INV_PISTOLS : desc = { STR_PISTOLS, PAGE_INVENTORY, level->extra.inv.weapon[0] }; break;
|
||||
case TR::Entity::INV_SHOTGUN : desc = { STR_SHOTGUN, PAGE_INVENTORY, level->extra.inv.weapon[1] }; break;
|
||||
case TR::Entity::INV_MAGNUMS : desc = { STR_MAGNUMS, PAGE_INVENTORY, level->extra.inv.weapon[2] }; break;
|
||||
case TR::Entity::INV_UZIS : desc = { STR_UZIS, PAGE_INVENTORY, level->extra.inv.weapon[3] }; break;
|
||||
|
||||
case TR::Entity::INV_AMMO_PISTOLS : desc = { "Pistol Clips", PAGE_INVENTORY, level->extra.inv.ammo[0] }; break;
|
||||
case TR::Entity::INV_AMMO_SHOTGUN : desc = { "Shotgun Shells", PAGE_INVENTORY, level->extra.inv.ammo[1] }; break;
|
||||
case TR::Entity::INV_AMMO_MAGNUMS : desc = { "Magnum Clips", PAGE_INVENTORY, level->extra.inv.ammo[2] }; break;
|
||||
case TR::Entity::INV_AMMO_UZIS : desc = { "Uzi Clips", PAGE_INVENTORY, level->extra.inv.ammo[3] }; break;
|
||||
case TR::Entity::INV_AMMO_PISTOLS : desc = { STR_AMMO_PISTOLS, PAGE_INVENTORY, level->extra.inv.ammo[0] }; break;
|
||||
case TR::Entity::INV_AMMO_SHOTGUN : desc = { STR_AMMO_SHOTGUN, PAGE_INVENTORY, level->extra.inv.ammo[1] }; break;
|
||||
case TR::Entity::INV_AMMO_MAGNUMS : desc = { STR_AMMO_MAGNUMS, PAGE_INVENTORY, level->extra.inv.ammo[2] }; break;
|
||||
case TR::Entity::INV_AMMO_UZIS : desc = { STR_AMMO_UZIS, PAGE_INVENTORY, level->extra.inv.ammo[3] }; break;
|
||||
|
||||
case TR::Entity::INV_MEDIKIT_SMALL : desc = { "Small Medi Pack", PAGE_INVENTORY, level->extra.inv.medikit[0] }; break;
|
||||
case TR::Entity::INV_MEDIKIT_BIG : desc = { "Large Medi Pack", PAGE_INVENTORY, level->extra.inv.medikit[1] }; break;
|
||||
case TR::Entity::INV_MEDIKIT_SMALL : desc = { STR_MEDI_SMALL, PAGE_INVENTORY, level->extra.inv.medikit[0] }; break;
|
||||
case TR::Entity::INV_MEDIKIT_BIG : desc = { STR_MEDI_BIG, PAGE_INVENTORY, level->extra.inv.medikit[1] }; break;
|
||||
|
||||
case TR::Entity::INV_PUZZLE_1 : desc = { "Puzzle", PAGE_ITEMS, level->extra.inv.puzzle[0] }; break;
|
||||
case TR::Entity::INV_PUZZLE_2 : desc = { "Puzzle", PAGE_ITEMS, level->extra.inv.puzzle[1] }; break;
|
||||
case TR::Entity::INV_PUZZLE_3 : desc = { "Puzzle", PAGE_ITEMS, level->extra.inv.puzzle[2] }; break;
|
||||
case TR::Entity::INV_PUZZLE_4 : desc = { "Puzzle", PAGE_ITEMS, level->extra.inv.puzzle[3] }; break;
|
||||
case TR::Entity::INV_PUZZLE_1 : desc = { STR_PUZZLE, PAGE_ITEMS, level->extra.inv.puzzle[0] }; break;
|
||||
case TR::Entity::INV_PUZZLE_2 : desc = { STR_PUZZLE, PAGE_ITEMS, level->extra.inv.puzzle[1] }; break;
|
||||
case TR::Entity::INV_PUZZLE_3 : desc = { STR_PUZZLE, PAGE_ITEMS, level->extra.inv.puzzle[2] }; break;
|
||||
case TR::Entity::INV_PUZZLE_4 : desc = { STR_PUZZLE, PAGE_ITEMS, level->extra.inv.puzzle[3] }; break;
|
||||
|
||||
case TR::Entity::INV_KEY_1 : desc = { "Key", PAGE_ITEMS, level->extra.inv.key[0] }; break;
|
||||
case TR::Entity::INV_KEY_2 : desc = { "Key", PAGE_ITEMS, level->extra.inv.key[1] }; break;
|
||||
case TR::Entity::INV_KEY_3 : desc = { "Key", PAGE_ITEMS, level->extra.inv.key[2] }; break;
|
||||
case TR::Entity::INV_KEY_4 : desc = { "Key", PAGE_ITEMS, level->extra.inv.key[3] }; break;
|
||||
case TR::Entity::INV_KEY_1 : desc = { STR_KEY, PAGE_ITEMS, level->extra.inv.key[0] }; break;
|
||||
case TR::Entity::INV_KEY_2 : desc = { STR_KEY, PAGE_ITEMS, level->extra.inv.key[1] }; break;
|
||||
case TR::Entity::INV_KEY_3 : desc = { STR_KEY, PAGE_ITEMS, level->extra.inv.key[2] }; break;
|
||||
case TR::Entity::INV_KEY_4 : desc = { STR_KEY, PAGE_ITEMS, level->extra.inv.key[3] }; break;
|
||||
|
||||
case TR::Entity::INV_LEADBAR : desc = { "Lead Bar", PAGE_ITEMS, level->extra.inv.leadbar }; break;
|
||||
case TR::Entity::INV_SCION : desc = { "Scion", PAGE_ITEMS, level->extra.inv.scion }; break;
|
||||
default : desc = { "unknown", PAGE_ITEMS, -1 }; break;
|
||||
case TR::Entity::INV_LEADBAR : desc = { STR_LEAD_BAR, PAGE_ITEMS, level->extra.inv.leadbar }; break;
|
||||
case TR::Entity::INV_SCION : desc = { STR_SCION, PAGE_ITEMS, level->extra.inv.scion }; break;
|
||||
default : desc = { STR_UNKNOWN, PAGE_ITEMS, -1 }; break;
|
||||
}
|
||||
|
||||
if (desc.model > -1) {
|
||||
@@ -108,7 +112,19 @@ struct Inventory {
|
||||
}
|
||||
|
||||
void update() {
|
||||
if (anim) anim->update();
|
||||
if (!anim) return;
|
||||
anim->update();
|
||||
|
||||
if (type == TR::Entity::INV_PASSPORT) {
|
||||
float t = (14 + value * 5) / 30.0f;
|
||||
|
||||
if ( (anim->dir > 0.0f && anim->time > t) ||
|
||||
(anim->dir < 0.0f && anim->time < t)) {
|
||||
anim->dir = 0.0f;
|
||||
anim->time = t;
|
||||
anim->updateInfo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void render(IGame *game, const Basis &basis) {
|
||||
@@ -126,7 +142,8 @@ struct Inventory {
|
||||
}
|
||||
|
||||
void choose() {
|
||||
if (anim) anim->setAnim(0, 0, false);
|
||||
if (!anim) return;
|
||||
anim->setAnim(0, 0, false);
|
||||
}
|
||||
|
||||
} *items[INVENTORY_MAX_ITEMS];
|
||||
@@ -139,7 +156,7 @@ struct Inventory {
|
||||
delete stream;
|
||||
}
|
||||
|
||||
Inventory(IGame *game) : game(game), active(false), chosen(false), index(0), targetIndex(0), page(PAGE_OPTION), targetPage(PAGE_OPTION), itemsCount(0) {
|
||||
Inventory(IGame *game) : game(game), active(false), chosen(false), index(0), targetIndex(0), page(PAGE_OPTION), targetPage(PAGE_OPTION), itemsCount(0), nextLevel(TR::LEVEL_MAX) {
|
||||
TR::LevelID id = game->getLevel()->id;
|
||||
|
||||
add(TR::Entity::INV_PASSPORT);
|
||||
@@ -147,9 +164,8 @@ struct Inventory {
|
||||
add(TR::Entity::INV_SOUND);
|
||||
add(TR::Entity::INV_CONTROLS);
|
||||
|
||||
if (id != TR::TITLE) {
|
||||
if (id != TR::TITLE && id != TR::GYM) {
|
||||
/*
|
||||
add(TR::Entity::INV_COMPASS);
|
||||
if (level->extra.inv.map != -1)
|
||||
add(TR::Entity::INV_MAP);
|
||||
if (level->extra.inv.gamma != -1)
|
||||
@@ -164,15 +180,19 @@ struct Inventory {
|
||||
// add(TR::Entity::INV_SCION, 1);
|
||||
// add(TR::Entity::INV_KEY_1, 1);
|
||||
// add(TR::Entity::INV_PUZZLE_1, 1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < COUNT(background); i++)
|
||||
background[i] = new Texture(INVENTORY_BG_SIZE, INVENTORY_BG_SIZE, Texture::RGBA, false);
|
||||
} else {
|
||||
if (id == TR::TITLE) {
|
||||
add(TR::Entity::INV_HOME);
|
||||
|
||||
memset(background, 0, sizeof(background));
|
||||
|
||||
new Stream("level/TITLEH.PCX", loadTitleBG, this);
|
||||
} else {
|
||||
add(TR::Entity::INV_COMPASS);
|
||||
|
||||
for (int i = 0; i < COUNT(background); i++)
|
||||
background[i] = new Texture(INVENTORY_BG_SIZE, INVENTORY_BG_SIZE, Texture::RGBA, false);
|
||||
}
|
||||
|
||||
phaseRing = phasePage = phaseChoose = phaseSelect = 0.0f;
|
||||
@@ -308,6 +328,7 @@ struct Inventory {
|
||||
for (int i = 0; i < itemsCount; i++)
|
||||
items[i]->reset();
|
||||
|
||||
nextLevel = TR::LEVEL_MAX;
|
||||
phasePage = 1.0f;
|
||||
phaseSelect = 1.0f;
|
||||
page = targetPage = curPage;
|
||||
@@ -381,13 +402,29 @@ struct Inventory {
|
||||
return active && phaseRing == 1.0f && index == targetIndex && phasePage == 1.0f && (type == TR::Entity::INV_MEDIKIT_SMALL || type == TR::Entity::INV_MEDIKIT_BIG);
|
||||
}
|
||||
|
||||
void onChoose(Item *item) {
|
||||
if (item->type == TR::Entity::INV_PASSPORT) {
|
||||
game->playSound(TR::SND_INV_PAGE, vec3(), 0, 0);
|
||||
item->value = 1;
|
||||
passportSlot = 0;
|
||||
passportSlotCount = 2;
|
||||
passportSlots[0] = TR::LEVEL_1;
|
||||
passportSlots[1] = TR::LEVEL_2;
|
||||
}
|
||||
}
|
||||
|
||||
void update() {
|
||||
float lastChoose = phaseChoose;
|
||||
|
||||
if (phaseChoose == 0.0f)
|
||||
doPhase(active, 2.0f, phaseRing);
|
||||
doPhase(true, 1.6f, phasePage);
|
||||
doPhase(chosen, 4.0f, phaseChoose);
|
||||
doPhase(true, 2.5f, phaseSelect);
|
||||
|
||||
if (phaseChoose == 1.0f && lastChoose != 1.0f)
|
||||
onChoose(items[getGlobalIndex(page, index)]);
|
||||
|
||||
if (page != targetPage && phasePage == 1.0f) {
|
||||
page = targetPage;
|
||||
index = targetIndex = pageItemIndex[page];
|
||||
@@ -400,18 +437,82 @@ struct Inventory {
|
||||
|
||||
bool ready = active && phaseRing == 1.0f && phasePage == 1.0f;
|
||||
|
||||
if (index == targetIndex && targetPage == page && ready && !chosen) {
|
||||
if (Input::state[cLeft] || Input::joy.L.x < -0.5f || Input::joy.R.x > 0.5f) { phaseSelect = 0.0f; targetIndex = (targetIndex - 1 + count) % count; }
|
||||
if (Input::state[cRight] || Input::joy.L.x > 0.5f || Input::joy.R.x < -0.5f) { phaseSelect = 0.0f; targetIndex = (targetIndex + 1) % count; }
|
||||
if ((Input::state[cUp] || Input::joy.L.y < -0.5f || Input::joy.R.y > 0.5f) && page < PAGE_ITEMS && getItemsCount(page + 1)) { phasePage = 0.0f; targetPage = Page(page + 1); }
|
||||
if ((Input::state[cDown] || Input::joy.L.y > 0.5f || Input::joy.R.y < -0.5f) && page > PAGE_OPTION && getItemsCount(page - 1)) { phasePage = 0.0f; targetPage = Page(page - 1); }
|
||||
enum KeyDir { NONE, LEFT, RIGHT, UP, DOWN } dir;
|
||||
|
||||
if (Input::state[cLeft] || Input::joy.L.x < -0.5f || Input::joy.R.x > 0.5f)
|
||||
dir = LEFT;
|
||||
else if (Input::state[cRight] || Input::joy.L.x > 0.5f || Input::joy.R.x < -0.5f)
|
||||
dir = RIGHT;
|
||||
else if (Input::state[cUp] || Input::joy.L.y < -0.5f || Input::joy.R.y > 0.5f)
|
||||
dir = UP;
|
||||
else if (Input::state[cDown] || Input::joy.L.y > 0.5f || Input::joy.R.y < -0.5f)
|
||||
dir = DOWN;
|
||||
else
|
||||
dir = NONE;
|
||||
|
||||
static KeyDir lastDir = NONE;
|
||||
|
||||
if (index == targetIndex && targetPage == page && ready) {
|
||||
if (!chosen) {
|
||||
if (dir == UP && !(page < PAGE_ITEMS && getItemsCount(page + 1))) dir = NONE;
|
||||
if (dir == DOWN && !(page > PAGE_OPTION && getItemsCount(page - 1))) dir = NONE;
|
||||
|
||||
switch (dir) {
|
||||
case LEFT : { phaseSelect = 0.0f; targetIndex = (targetIndex - 1 + count) % count; } break;
|
||||
case RIGHT : { phaseSelect = 0.0f; targetIndex = (targetIndex + 1) % count; } break;
|
||||
case UP : { phasePage = 0.0f; targetPage = Page(page + 1); } break;
|
||||
case DOWN : { phasePage = 0.0f; targetPage = Page(page - 1); } break;
|
||||
default : ;
|
||||
}
|
||||
|
||||
if (index != targetIndex) {
|
||||
vec3 p;
|
||||
game->playSound(TR::SND_INV_SPIN, p, 0, 0);
|
||||
}
|
||||
} else {
|
||||
Item *item = items[getGlobalIndex(page, index)];
|
||||
|
||||
if (item->type == TR::Entity::INV_PASSPORT && passportSlotCount) {
|
||||
if (lastDir != dir) {
|
||||
// passport slots
|
||||
if (item->value == 0 && item->anim->dir == 0.0f) { // slot select
|
||||
if (dir == UP) { passportSlot = (passportSlot - 1 + passportSlotCount) % passportSlotCount; };
|
||||
if (dir == DOWN) { passportSlot = (passportSlot + 1) % passportSlotCount; };
|
||||
}
|
||||
// passport pages
|
||||
if (dir == LEFT && item->value > 0) { item->value--; item->anim->dir = -1.0f; game->playSound(TR::SND_INV_PAGE, vec3(), 0, 0); }
|
||||
if (dir == RIGHT && item->value < 2) { item->value++; item->anim->dir = 1.0f; game->playSound(TR::SND_INV_PAGE, vec3(), 0, 0); }
|
||||
lastDir = dir;
|
||||
}
|
||||
|
||||
if (Input::state[cAction] && phaseChoose == 1.0f) {
|
||||
TR::LevelID id = game->getLevel()->id;
|
||||
switch (item->value) {
|
||||
case 0 : nextLevel = passportSlots[passportSlot]; break;
|
||||
case 1 : nextLevel = (id == TR::TITLE) ? TR::LEVEL_1 : game->getLevel()->id; break;
|
||||
case 2 : nextLevel = (id == TR::TITLE) ? TR::LEVEL_MAX : TR::TITLE; break;
|
||||
}
|
||||
|
||||
if (nextLevel != TR::LEVEL_MAX) {
|
||||
item->anim->dir = -1.0f;
|
||||
item->value = -100;
|
||||
toggle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (item->type == TR::Entity::INV_HOME) {
|
||||
if (Input::state[cAction] && phaseChoose == 1.0f) {
|
||||
nextLevel = TR::GYM;
|
||||
toggle();
|
||||
}
|
||||
}
|
||||
|
||||
if (index != targetIndex) {
|
||||
vec3 p;
|
||||
game->playSound(TR::SND_INV_SPIN, p, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
ready = active && phaseRing == 1.0f && phasePage == 1.0f;
|
||||
|
||||
vec3 p;
|
||||
|
||||
Item *item = items[getGlobalIndex(page, index)];
|
||||
@@ -485,6 +586,9 @@ struct Inventory {
|
||||
toggle();
|
||||
}
|
||||
}
|
||||
|
||||
if (!isActive() && nextLevel != TR::LEVEL_MAX)
|
||||
game->loadLevel(nextLevel);
|
||||
}
|
||||
|
||||
void prepareBackground() {
|
||||
@@ -534,21 +638,66 @@ struct Inventory {
|
||||
}
|
||||
}
|
||||
|
||||
void renderItemText(const Item *item, float width) {
|
||||
UI::textOut(vec2(0, 480 - 16), item->desc.name, UI::aCenter, width);
|
||||
renderItemCount(item, vec2(width / 2 - 160, 480 - 96), 320);
|
||||
int passportSlot, passportSlotCount;
|
||||
TR::LevelID passportSlots[32];
|
||||
|
||||
void renderPassport(Item *item) {
|
||||
if (item->value != 0 || item->anim->dir != 0.0f) return; // check for "Load Game" page
|
||||
|
||||
float y = 120.0f;
|
||||
float h = 20.0f;
|
||||
float w = 320.0f;
|
||||
|
||||
// background
|
||||
UI::renderBar(UI::BAR_OPTION, vec2((UI::width - w - 16.0f) * 0.5f, y - 16.0f), vec2(w + 16.0f, h * 16.0f), 0.0f, 0, 0xC0000000);
|
||||
// title
|
||||
UI::renderBar(UI::BAR_OPTION, vec2((UI::width - w) * 0.5f, y - h + 6), vec2(w, h - 6), 1.0f, 0x802288FF, 0, 0, 0);
|
||||
UI::textOut(vec2(0, y), STR_SELECT_LEVEL, UI::aCenter, UI::width);
|
||||
|
||||
y += h * 2;
|
||||
UI::renderBar(UI::BAR_OPTION, vec2((UI::width - w) * 0.5f, y + passportSlot * h + 6 - h), vec2(w, h - 6), 1.0f, 0xFFD8377C, 0);
|
||||
|
||||
for (int i = 0; i < passportSlotCount; i++)
|
||||
if (passportSlots[i] == TR::LEVEL_MAX)
|
||||
UI::textOut(vec2(0, y + i * h), STR_AUTOSAVE, UI::aCenter, UI::width);
|
||||
else
|
||||
UI::textOut(vec2(0, y + i * h), TR::LEVEL_INFO[passportSlots[i]].title, UI::aCenter, UI::width);
|
||||
}
|
||||
|
||||
void renderItemText(Item *item) {
|
||||
if (item->type == TR::Entity::INV_PASSPORT && phaseChoose == 1.0f) {
|
||||
StringID str = STR_LOAD_GAME;
|
||||
|
||||
if (game->getLevel()->id == TR::TITLE) {
|
||||
if (item->value == 1) str = STR_START_GAME;
|
||||
if (item->value == 2) str = STR_EXIT_GAME;
|
||||
} else {
|
||||
if (item->value == 1) str = STR_RESTART_LEVEL;
|
||||
if (item->value == 2) str = STR_EXIT_TO_TITLE;
|
||||
}
|
||||
|
||||
UI::textOut(vec2(0, 480 - 16), str, UI::aCenter, UI::width);
|
||||
} else
|
||||
UI::textOut(vec2(0, 480 - 16), item->desc.str, UI::aCenter, UI::width);
|
||||
|
||||
renderItemCount(item, vec2(UI::width / 2 - 160, 480 - 96), 320);
|
||||
|
||||
if (phaseChoose == 1.0f) {
|
||||
if (item->type == TR::Entity::INV_PASSPORT ||
|
||||
item->type == TR::Entity::INV_MAP ||
|
||||
item->type == TR::Entity::INV_COMPASS ||
|
||||
item->type == TR::Entity::INV_HOME ||
|
||||
item->type == TR::Entity::INV_DETAIL ||
|
||||
item->type == TR::Entity::INV_SOUND ||
|
||||
item->type == TR::Entity::INV_CONTROLS ||
|
||||
item->type == TR::Entity::INV_GAMMA)
|
||||
{
|
||||
UI::textOut(vec2(0, 240), "Not implemented yet!", UI::aCenter, width);
|
||||
switch (item->type) {
|
||||
case TR::Entity::INV_PASSPORT :
|
||||
renderPassport(item);
|
||||
break;
|
||||
case TR::Entity::INV_HOME :
|
||||
break;
|
||||
case TR::Entity::INV_COMPASS :
|
||||
case TR::Entity::INV_MAP :
|
||||
case TR::Entity::INV_DETAIL :
|
||||
case TR::Entity::INV_SOUND :
|
||||
case TR::Entity::INV_CONTROLS :
|
||||
case TR::Entity::INV_GAMMA :
|
||||
UI::textOut(vec2(0, 240), STR_NOT_IMPLEMENTED, UI::aCenter, UI::width);
|
||||
break;
|
||||
default : ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -674,7 +823,7 @@ struct Inventory {
|
||||
void renderUI() {
|
||||
if (!active || phaseRing < 1.0f) return;
|
||||
|
||||
static const char* pageTitle[PAGE_MAX] = { "OPTION", "INVENTORY", "ITEMS" };
|
||||
static const StringID pageTitle[PAGE_MAX] = { STR_OPTION, STR_INVENTORY, STR_ITEMS };
|
||||
|
||||
if (game->getLevel()->id != TR::TITLE)
|
||||
UI::textOut(vec2( 0, 32), pageTitle[page], UI::aCenter, UI::width);
|
||||
@@ -690,7 +839,7 @@ struct Inventory {
|
||||
}
|
||||
|
||||
if (index == targetIndex)
|
||||
renderItemText(items[getGlobalIndex(page, index)], UI::width);
|
||||
renderItemText(items[getGlobalIndex(page, index)]);
|
||||
}
|
||||
};
|
||||
|
||||
|
10
src/lara.h
10
src/lara.h
@@ -1480,10 +1480,14 @@ struct Lara : Character {
|
||||
case 49 : if (state != STATE_SURF_TREAD) return 0; break;
|
||||
case 50 : // end of GYM
|
||||
if (level->tracks[track].once) {
|
||||
// back to title
|
||||
} else
|
||||
timer += Core::deltaTime;
|
||||
if (timer > 3.0f)
|
||||
game->loadLevel(TR::TITLE);
|
||||
} else {
|
||||
if (state != STATE_WATER_OUT)
|
||||
return 0;
|
||||
timer = 0.0f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return track;
|
||||
@@ -1713,7 +1717,7 @@ struct Lara : Character {
|
||||
((Camera*)level->cameraController)->viewTarget = (Controller*)level->entities[cmd.args].controller;
|
||||
break;
|
||||
case TR::Action::END :
|
||||
LOG("END\n");
|
||||
game->loadLevel(level->id == TR::LEVEL_10C ? TR::TITLE : TR::LevelID(level->id + 1));
|
||||
break;
|
||||
case TR::Action::SOUNDTRACK : {
|
||||
int track = doTutorial(cmd.args);
|
||||
|
76
src/level.h
76
src/level.h
@@ -15,6 +15,8 @@
|
||||
#include "debug.h"
|
||||
#endif
|
||||
|
||||
extern void loadAsync(Stream *stream, void *userData);
|
||||
|
||||
struct Level : IGame {
|
||||
TR::Level level;
|
||||
Inventory inventory;
|
||||
@@ -44,12 +46,25 @@ struct Level : IGame {
|
||||
|
||||
int curTrack;
|
||||
bool lastTitle;
|
||||
bool isEnded;
|
||||
|
||||
TR::Effect effect;
|
||||
float effectTimer;
|
||||
int flickerIdx;
|
||||
|
||||
// IGame implementation ========
|
||||
virtual void loadLevel(TR::LevelID id) {
|
||||
if (isEnded) return;
|
||||
|
||||
isEnded = true;
|
||||
char buf[64];
|
||||
buf[0] = 0;
|
||||
strcat(buf, "level/");
|
||||
strcat(buf, TR::LEVEL_INFO[id].name);
|
||||
strcat(buf, ".PSX");
|
||||
new Stream(buf, loadAsync);
|
||||
}
|
||||
|
||||
virtual TR::Level* getLevel() {
|
||||
return &level;
|
||||
}
|
||||
@@ -233,7 +248,7 @@ struct Level : IGame {
|
||||
}
|
||||
//==============================
|
||||
|
||||
Level(Stream &stream) : level(stream), inventory(this), lara(NULL) {
|
||||
Level(Stream &stream) : level(stream), inventory(this), lara(NULL), isEnded(false) {
|
||||
params->time = 0.0f;
|
||||
|
||||
#ifdef _DEBUG
|
||||
@@ -439,8 +454,18 @@ struct Level : IGame {
|
||||
|
||||
static void fillCallback(int id, int width, int height, int tileX, int tileY, void *userData, void *data) {
|
||||
static const uint32 whiteColor = 0xFFFFFFFF;
|
||||
static const uint32 healthColor[5] = { 0xFF2C5D71, 0xFF5E81AE, 0xFF2C5D71, 0xFF1B4557, 0xFF16304F };
|
||||
static const uint32 oxygenColor[5] = { 0xFF647464, 0xFFA47848, 0xFF647464, 0xFF4C504C, 0xFF303030 };
|
||||
static const uint32 barColor[UI::BAR_MAX][25] = {
|
||||
// health bar
|
||||
{ 0xFF2C5D71, 0xFF5E81AE, 0xFF2C5D71, 0xFF1B4557, 0xFF16304F },
|
||||
// oxygen bar
|
||||
{ 0xFF647464, 0xFFA47848, 0xFF647464, 0xFF4C504C, 0xFF303030 },
|
||||
// option bar
|
||||
{ 0x00FFFFFF, 0x20FFFFFF, 0x20FFFFFF, 0x20FFFFFF, 0x00FFFFFF,
|
||||
0x00FFFFFF, 0x60FFFFFF, 0x60FFFFFF, 0x60FFFFFF, 0x00FFFFFF,
|
||||
0x00FFFFFF, 0x80FFFFFF, 0x80FFFFFF, 0x80FFFFFF, 0x00FFFFFF,
|
||||
0x00FFFFFF, 0x60FFFFFF, 0x60FFFFFF, 0x60FFFFFF, 0x00FFFFFF,
|
||||
0x00FFFFFF, 0x20FFFFFF, 0x20FFFFFF, 0x20FFFFFF, 0x00FFFFFF },
|
||||
};
|
||||
|
||||
int stride = 256, uvCount;
|
||||
short2 *uv = NULL;
|
||||
@@ -472,20 +497,21 @@ struct Level : IGame {
|
||||
uvCount = 4;
|
||||
|
||||
switch (id) {
|
||||
case 0 : // white color
|
||||
case UI::BAR_HEALTH :
|
||||
case UI::BAR_OXYGEN :
|
||||
case UI::BAR_OPTION :
|
||||
src = (TR::Color32*)&barColor[id][0];
|
||||
tex = &barTile[id];
|
||||
mm.w = 4; // height - 1
|
||||
if (id == UI::BAR_OPTION) {
|
||||
stride = 5;
|
||||
mm.z = 4;
|
||||
}
|
||||
break;
|
||||
case 3 : // white color
|
||||
src = (TR::Color32*)&whiteColor;
|
||||
tex = &whiteTile;
|
||||
break;
|
||||
case 1 : // health bar
|
||||
src = (TR::Color32*)&healthColor[0];
|
||||
tex = &healthTile;
|
||||
mm.w = 4; // height - 1
|
||||
break;
|
||||
case 2 : // oxygen bar
|
||||
src = (TR::Color32*)&oxygenColor[0];
|
||||
tex = &oxygenTile;
|
||||
mm.w = 4; // height - 1
|
||||
break;
|
||||
default : return;
|
||||
}
|
||||
|
||||
@@ -493,6 +519,8 @@ struct Level : IGame {
|
||||
uv = tex->texCoord;
|
||||
uv[2].y += mm.w;
|
||||
uv[3].y += mm.w;
|
||||
uv[1].x += mm.z;
|
||||
uv[2].x += mm.z;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -583,12 +611,14 @@ struct Level : IGame {
|
||||
|
||||
tiles->add(uv, texIdx++);
|
||||
}
|
||||
// add white color
|
||||
tiles->add(short4(2048, 2048, 2048, 2048), texIdx++);
|
||||
// add health bar
|
||||
tiles->add(short4(2048, 2048, 2048, 2048 + 4), texIdx++);
|
||||
// add oxygen bar
|
||||
tiles->add(short4(4096, 4096, 4096, 4096 + 4), texIdx++);
|
||||
// add option bar
|
||||
tiles->add(short4(8192, 8192, 8192 + 4, 8192 + 4), texIdx++);
|
||||
// add white color
|
||||
tiles->add(short4(2048, 2048, 2048, 2048), texIdx++);
|
||||
// get result texture
|
||||
atlas = tiles->pack();
|
||||
|
||||
@@ -1390,7 +1420,7 @@ struct Level : IGame {
|
||||
}
|
||||
|
||||
if (inventory.showHealthBar() || (!inventory.active && (!lara->emptyHands() || lara->damageTime > 0.0f || health <= 0.2f))) {
|
||||
UI::renderBar(0, vec2(UI::width - 32 - size.x, 32), size, health);
|
||||
UI::renderBar(UI::BAR_HEALTH, vec2(UI::width - 32 - size.x, 32), size, health);
|
||||
|
||||
if (!inventory.active && !lara->emptyHands()) { // ammo
|
||||
int index = inventory.contains(lara->getCurrentWeaponInv());
|
||||
@@ -1400,7 +1430,7 @@ struct Level : IGame {
|
||||
}
|
||||
|
||||
if (!lara->dozy && (lara->stand == Lara::STAND_ONWATER || lara->stand == Character::STAND_UNDERWATER))
|
||||
UI::renderBar(1, vec2(32, 32), size, oxygen);
|
||||
UI::renderBar(UI::BAR_OXYGEN, vec2(32, 32), size, oxygen);
|
||||
}
|
||||
|
||||
inventory.renderUI();
|
||||
@@ -1414,6 +1444,14 @@ struct Level : IGame {
|
||||
void render() {
|
||||
bool title = inventory.isActive() || level.id == TR::TITLE;
|
||||
bool copyBg = title && lastTitle != title;
|
||||
lastTitle = title;
|
||||
|
||||
if (isEnded) {
|
||||
UI::begin();
|
||||
UI::textOut(vec2(0, 480 - 16), STR_LOADING, UI::aCenter, UI::width);
|
||||
UI::end();
|
||||
return;
|
||||
}
|
||||
|
||||
if (copyBg) {
|
||||
Core::defaultTarget = inventory.background[0];
|
||||
@@ -1430,8 +1468,6 @@ struct Level : IGame {
|
||||
renderInventory();
|
||||
|
||||
renderUI();
|
||||
|
||||
lastTitle = title;
|
||||
}
|
||||
|
||||
};
|
||||
|
@@ -5,7 +5,7 @@
|
||||
#include "format.h"
|
||||
|
||||
|
||||
TR::ObjectTexture whiteTile, healthTile, oxygenTile;
|
||||
TR::ObjectTexture whiteTile, barTile[3];
|
||||
|
||||
struct MeshRange {
|
||||
int iStart;
|
||||
@@ -906,7 +906,7 @@ struct MeshBuilder {
|
||||
vCount += 4;
|
||||
}
|
||||
|
||||
void addBar(Index *indices, Vertex *vertices, int &iCount, int &vCount, int type, const vec2 &pos, const vec2 &size, uint32 color) {
|
||||
void addBar(Index *indices, Vertex *vertices, int &iCount, int &vCount, const TR::ObjectTexture &tile, const vec2 &pos, const vec2 &size, uint32 color) {
|
||||
addQuad(indices, iCount, vCount, 0, vertices, NULL);
|
||||
|
||||
int16 minX = int16(pos.x);
|
||||
@@ -924,7 +924,7 @@ struct MeshBuilder {
|
||||
v.normal = { 0, 0, 0, 0 };
|
||||
v.color = *((ubyte4*)&color);
|
||||
|
||||
short2 uv = type == 0 ? healthTile.texCoord[i] : oxygenTile.texCoord[i];
|
||||
short2 uv = tile.texCoord[i];
|
||||
|
||||
v.texCoord = { uv.x, uv.y, 32767, 32767 };
|
||||
v.param = { 0, 0, 0, 0 };
|
||||
|
@@ -3,7 +3,7 @@ cls
|
||||
set SRC=main.cpp ../../libs/stb_vorbis/stb_vorbis.c
|
||||
set PROJ=OpenLara
|
||||
set FLAGS=-O3 -Wno-deprecated-register --llvm-opts 2 -fmax-type-align=2 -std=c++11 -Wall -I../../
|
||||
set PRELOAD=./level/LEVEL2.PSX
|
||||
set PRELOAD=./level/TITLE.PSX;./level/TITLEH.PCX
|
||||
echo.
|
||||
call em++ %SRC% %FLAGS% -o %PROJ%.js --preload-file %PRELOAD%
|
||||
gzip.exe -9 -f %PROJ%.data %PROJ%.js %PROJ%.js.mem
|
@@ -107,7 +107,7 @@
|
||||
<input type="button" value="Browse Level" onclick="document.getElementById('browseFile').click();" /> (.PHD, .PSX)
|
||||
<p style="margin:8px">
|
||||
OpenLara on <a target="_blank" href="https://github.com/XProger/OpenLara">github</a> & <a target="_blank" href="https://www.facebook.com/OpenLaraTR">facebook</a><br>
|
||||
<br><i>last update: 12.09.2017</i><br>
|
||||
<br><i>last update: 13.09.2017</i><br>
|
||||
</p>
|
||||
</span>
|
||||
|
||||
|
@@ -18,7 +18,7 @@ varying vec4 vColor;
|
||||
|
||||
void main() {
|
||||
vTexCoord = aTexCoord.xy;
|
||||
vColor = aColor * uMaterial;
|
||||
vColor = aColor;
|
||||
gl_Position = uViewProj * vec4(aCoord.xy * uPosScale.zw + uPosScale.xy, 0.0, 1.0);
|
||||
}
|
||||
#else
|
||||
|
173
src/ui.h
173
src/ui.h
@@ -4,6 +4,125 @@
|
||||
#include "core.h"
|
||||
#include "controller.h"
|
||||
|
||||
enum StringID {
|
||||
STR_NOT_IMPLEMENTED
|
||||
// help
|
||||
, STR_LOADING
|
||||
, STR_HELP_PRESS
|
||||
, STR_HELP_TEXT
|
||||
// inventory pages
|
||||
, STR_OPTION
|
||||
, STR_INVENTORY
|
||||
, STR_ITEMS
|
||||
// inventory option
|
||||
, STR_GAME
|
||||
, STR_MAP
|
||||
, STR_COMPASS
|
||||
, STR_HOME
|
||||
, STR_DETAIL
|
||||
, STR_SOUND
|
||||
, STR_CONTROLS
|
||||
, STR_GAMMA
|
||||
// passport menu
|
||||
, STR_AUTOSAVE
|
||||
, STR_LOAD_GAME
|
||||
, STR_START_GAME
|
||||
, STR_RESTART_LEVEL
|
||||
, STR_EXIT_TO_TITLE
|
||||
, STR_EXIT_GAME
|
||||
, STR_SELECT_LEVEL
|
||||
// inventory items
|
||||
, STR_UNKNOWN
|
||||
, STR_PISTOLS
|
||||
, STR_SHOTGUN
|
||||
, STR_MAGNUMS
|
||||
, STR_UZIS
|
||||
, STR_AMMO_PISTOLS
|
||||
, STR_AMMO_SHOTGUN
|
||||
, STR_AMMO_MAGNUMS
|
||||
, STR_AMMO_UZIS
|
||||
, STR_MEDI_SMALL
|
||||
, STR_MEDI_BIG
|
||||
, STR_PUZZLE
|
||||
, STR_KEY
|
||||
, STR_LEAD_BAR
|
||||
, STR_SCION
|
||||
, STR_MAX
|
||||
};
|
||||
|
||||
const char *helpText =
|
||||
"Controls gamepad, touch and keyboard:@"
|
||||
" H - Show or hide this help@"
|
||||
" TAB - Inventory@"
|
||||
" LEFT - Left@"
|
||||
" RIGHT - Right@"
|
||||
" UP - Run@"
|
||||
" DOWN - Back@"
|
||||
" SHIFT - Walk@"
|
||||
" SPACE - Draw Weapon@"
|
||||
" CTRL - Action@"
|
||||
" D - Jump@"
|
||||
" Z - Step Left@"
|
||||
" X - Step Right@"
|
||||
" A - Roll@"
|
||||
" C - Look # not implemented #@"
|
||||
" V - First Person View@"
|
||||
" R - slow motion@"
|
||||
" T - fast motion@"
|
||||
" ALT + ENTER - Fullscreen@@"
|
||||
"Actions:@"
|
||||
" Out of water - Run + Action@"
|
||||
" Handstand - Run + Walk@"
|
||||
" Swan dive - Run + Walk + jump@"
|
||||
" DOZY on - Look + Step Right + Action + Jump@"
|
||||
" DOZY off - Walk@";
|
||||
|
||||
|
||||
const char *STR[STR_MAX] = {
|
||||
"Not implemented yet!"
|
||||
// help
|
||||
, "Loading..."
|
||||
, "Press H for help"
|
||||
, helpText
|
||||
// inventory pages
|
||||
, "OPTION"
|
||||
, "INVENTORY"
|
||||
, "ITEMS"
|
||||
// inventory option
|
||||
, "Game"
|
||||
, "Map"
|
||||
, "Compass"
|
||||
, "Lara's Home"
|
||||
, "Detail Levels"
|
||||
, "Sound"
|
||||
, "Controls"
|
||||
, "Gamma"
|
||||
// passport options
|
||||
, "Autosave"
|
||||
, "Load Game"
|
||||
, "Start Game"
|
||||
, "Restart Level"
|
||||
, "Exit to Title"
|
||||
, "Exit Game"
|
||||
, "Select Level"
|
||||
// inventory items
|
||||
, "Unknown"
|
||||
, "Pistols"
|
||||
, "Shotgun"
|
||||
, "Magnums"
|
||||
, "Uzis"
|
||||
, "Pistol Clips"
|
||||
, "Shotgun Shells"
|
||||
, "Magnum Clips"
|
||||
, "Uzi Clips"
|
||||
, "Small Medi Pack"
|
||||
, "Large Medi Pack"
|
||||
, "Puzzle"
|
||||
, "Key"
|
||||
, "Lead Bar"
|
||||
, "Scion"
|
||||
};
|
||||
|
||||
namespace UI {
|
||||
IGame *game;
|
||||
float width;
|
||||
@@ -48,6 +167,13 @@ namespace UI {
|
||||
|
||||
#define MAX_CHARS DYN_MESH_QUADS
|
||||
|
||||
enum BarType {
|
||||
BAR_HEALTH,
|
||||
BAR_OXYGEN,
|
||||
BAR_OPTION,
|
||||
BAR_MAX,
|
||||
};
|
||||
|
||||
struct {
|
||||
Vertex vertices[MAX_CHARS * 4];
|
||||
Index indices[MAX_CHARS * 6];
|
||||
@@ -129,6 +255,10 @@ namespace UI {
|
||||
}
|
||||
}
|
||||
|
||||
void textOut(const vec2 &pos, StringID str, Align align = aLeft, float width = 0) {
|
||||
textOut(pos, STR[str], align, width);
|
||||
}
|
||||
|
||||
#undef MAX_CHARS
|
||||
/*
|
||||
Texture *texInv, *texAction;
|
||||
@@ -204,48 +334,23 @@ namespace UI {
|
||||
Core::setDepthTest(true);
|
||||
}
|
||||
|
||||
void renderBar(int type, const vec2 &pos, const vec2 &size, float value) {
|
||||
void renderBar(BarType type, const vec2 &pos, const vec2 &size, float value, uint32 fgColor = 0xFFFFFFFF, uint32 bgColor = 0x80000000, uint32 brColor1 = 0xFF4C504C, uint32 brColor2 = 0xFF748474) {
|
||||
MeshBuilder *mesh = game->getMesh();
|
||||
|
||||
mesh->addFrame(buffer.indices, buffer.vertices, buffer.iCount, buffer.vCount, pos - 2.0f, size + 4.0f, 0xFF4C504C, 0xFF748474);
|
||||
mesh->addBar(buffer.indices, buffer.vertices, buffer.iCount, buffer.vCount, type, pos - 1.0f, size + 2.0f, 0x80000000);
|
||||
if (value > 0.0f)
|
||||
mesh->addBar(buffer.indices, buffer.vertices, buffer.iCount, buffer.vCount, type, pos, vec2(size.x * value, size.y), 0xFFFFFFFF);
|
||||
if (brColor1 != 0 || brColor2 != 0)
|
||||
mesh->addFrame(buffer.indices, buffer.vertices, buffer.iCount, buffer.vCount, pos - 2.0f, size + 4.0f, brColor1, brColor2);
|
||||
if (bgColor != 0)
|
||||
mesh->addBar(buffer.indices, buffer.vertices, buffer.iCount, buffer.vCount, whiteTile, pos - 1.0f, size + 2.0f, bgColor);
|
||||
if (fgColor != 0 && value > 0.0f)
|
||||
mesh->addBar(buffer.indices, buffer.vertices, buffer.iCount, buffer.vCount, barTile[type], pos, vec2(size.x * value, size.y), fgColor);
|
||||
}
|
||||
|
||||
const char *helpText =
|
||||
"Controls gamepad, touch and keyboard:@"
|
||||
" H - Show or hide this help@"
|
||||
" TAB - Inventory@"
|
||||
" LEFT - Left@"
|
||||
" RIGHT - Right@"
|
||||
" UP - Run@"
|
||||
" DOWN - Back@"
|
||||
" SHIFT - Walk@"
|
||||
" SPACE - Draw Weapon@"
|
||||
" CTRL - Action@"
|
||||
" D - Jump@"
|
||||
" Z - Step Left@"
|
||||
" X - Step Right@"
|
||||
" A - Roll@"
|
||||
" C - Look # not implemented #@"
|
||||
" V - First Person View@"
|
||||
" R - slow motion@"
|
||||
" T - fast motion@"
|
||||
" ALT + ENTER - Fullscreen@@"
|
||||
"Actions:@"
|
||||
" Out of water - Run + Action@"
|
||||
" Handstand - Run + Walk@"
|
||||
" Swan dive - Run + Walk + jump@"
|
||||
" DOZY on - Look + Step Right + Action + Jump@"
|
||||
" DOZY off - Walk@";
|
||||
|
||||
void renderHelp() {
|
||||
if (showHelp)
|
||||
textOut(vec2(0, 64), helpText, aRight, width - 32);
|
||||
textOut(vec2(0, 64), STR_HELP_TEXT, aRight, width - 32);
|
||||
else
|
||||
if (helpTipTime > 0.0f)
|
||||
textOut(vec2(0, 480 - 32), "Press H for help", aCenter, width);
|
||||
textOut(vec2(0, 480 - 32), STR_HELP_PRESS, aCenter, width);
|
||||
}
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user