1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-04-22 03:51:58 +02:00

#3 fix lookAt; #11 fix PCX loader for NPOT and async load; #15 async data loading for Web version

This commit is contained in:
XProger 2017-09-01 08:02:08 +03:00
parent 953e020a14
commit a6aafee45b
10 changed files with 118 additions and 38 deletions

View File

@ -203,7 +203,8 @@ struct Camera : Controller {
owner->lookAt(lookAt = owner->viewTarget);
else
owner->lookAt(lookAt = viewTarget);
}
} else
owner->lookAt(NULL);
vec3 viewPoint = getViewPoint();

View File

@ -45,7 +45,7 @@ struct Character : Controller {
Collision collision;
Character(IGame *game, int entity, float health) : Controller(game, entity), health(health), tilt(0.0f), stand(STAND_GROUND), lastInput(0), viewTarget(NULL), jointChest(-1), jointHead(-1), velocity(0.0f), angleExt(0.0f) {
Character(IGame *game, int entity, float health) : Controller(game, entity), health(health), tilt(0.0f), stand(STAND_GROUND), lastInput(0), viewTarget(NULL), jointChest(-1), jointHead(-1), velocity(0.0f), angleExt(0.0f), speed(0.0f) {
stepHeight = 256;
dropHeight = -256;

View File

@ -131,6 +131,14 @@ struct Inventory {
} *items[INVENTORY_MAX_ITEMS];
static void loadTitleBG(Stream *stream, void *userData) {
if (!stream) return;
Inventory *inv = (Inventory*)userData;
inv->background[0] = Texture::LoadPCX(*stream);
delete stream;
}
Inventory(IGame *game) : game(game), active(false), chosen(false), index(0), targetIndex(0), page(PAGE_OPTION), targetPage(PAGE_OPTION), itemsCount(0) {
TR::LevelID id = game->getLevel()->id;
@ -163,7 +171,8 @@ struct Inventory {
add(TR::Entity::INV_HOME);
memset(background, 0, sizeof(background));
background[0] = Texture::LoadPCX("data/TITLEH.PCX");
new Stream("data/TITLEH.PCX", loadTitleBG, this);
}
phaseRing = phasePage = phaseChoose = phaseSelect = 0.0f;
@ -596,19 +605,21 @@ struct Inventory {
// background
Core::setDepthTest(false);
background[0]->bind(sDiffuse); // orignal image
if (background[1]) {
game->setShader(Core::passFilter, Shader::FILTER_MIXER, false, false);
Core::active.shader->setParam(uParam, vec4(phaseRing, 1.0f - phaseRing * 0.4f, 0, 0));;
background[1]->bind(sNormal); // blured grayscale image
} else {
game->setShader(Core::passFilter, Shader::DEFAULT, false, false);
if (background[0]) {
background[0]->bind(sDiffuse); // orignal image
if (background[1]) {
game->setShader(Core::passFilter, Shader::FILTER_MIXER, false, false);
Core::active.shader->setParam(uParam, vec4(phaseRing, 1.0f - phaseRing * 0.4f, 0, 0));;
background[1]->bind(sNormal); // blured grayscale image
} else {
game->setShader(Core::passFilter, Shader::DEFAULT, false, false);
float aspect1 = float(background[0]->width) / float(background[0]->height);
float aspect2 = float(Core::width) / float(Core::height);
Core::active.shader->setParam(uParam, vec4(aspect2 / aspect1, -1.0f, 0, 0));;
float aspect1 = float(background[0]->width) / float(background[0]->height);
float aspect2 = float(Core::width) / float(Core::height);
Core::active.shader->setParam(uParam, vec4(aspect2 / aspect1, -1.0f, 0, 0));
}
game->getMesh()->renderQuad();
}
game->getMesh()->renderQuad();
Core::setDepthTest(true);
Core::setBlending(bmAlpha);

View File

@ -191,10 +191,16 @@ struct Level : IGame {
}
}
static void playAsync(Stream *stream, void *userData) {
if (!stream) return;
Level *level = (Level*)userData;
level->sndSoundtrack = Sound::play(stream, vec3(0.0f), 0.01f, 1.0f, 0);
if (level->sndSoundtrack)
level->sndSoundtrack->setVolume(1.0f, 0.2f);
}
virtual void playTrack(int track, bool restart = false) {
#ifndef WIN32
return;
#endif
if (track == 0)
track = TR::LEVEL_INFO[level.id].ambientTrack;
@ -219,9 +225,7 @@ struct Level : IGame {
char title[32];
sprintf(title, "audio/track_%02d.ogg", track);
sndSoundtrack = Sound::play(new Stream(title), vec3(0.0f), 0.01f, 1.0f, track == TR::LEVEL_INFO[level.id].ambientTrack ? Sound::Flags::LOOP : 0);
if (sndSoundtrack)
sndSoundtrack->setVolume(1.0f, 0.2f);
new Stream(title, playAsync, this);
}
virtual void stopTrack() {

View File

@ -1,6 +1,6 @@
@echo off
cls
set SRC=main.cpp
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=./LEVEL2.PSX

View File

@ -101,8 +101,6 @@
};
</script>
<audio autoplay loop><source src="05.ogg" type="audio/ogg"></audio>
<span id="info">
<input type="file" id="browseFile" style="display:none" accept=".phd,.psx" onchange="readLevel(event)" />
<!-- <label for="browseFile">Browse Level</label> -->

View File

@ -233,6 +233,35 @@ EM_BOOL mouseCallback(int eventType, const EmscriptenMouseEvent *e, void *userDa
return 1;
}
const char *IDB = "db";
void onError(void *str) {
LOG("! IDB error: %s\n", str);
}
void onLoad(void *arg, void *data, int size) {
Stream *stream = (Stream*)arg;
stream->data = (char*)data;
stream->size = size;
stream->callback(stream, stream->userData);
}
void onLoadAndStore(void *arg, void *data, int size) {
onLoad(arg, data, size);
emscripten_idb_async_store(IDB, ((Stream*)arg)->name, data, size, NULL, NULL, onError);
}
void onExists(void *arg, int exists) {
if (exists)
emscripten_idb_async_load(IDB, ((Stream*)arg)->name, arg, onLoad, onError);
else
emscripten_async_wget_data(((Stream*)arg)->name, arg, onLoadAndStore, onError);
}
void osDownload(Stream *stream) {
emscripten_idb_async_exists(IDB, stream->name, stream, onExists, onError);
}
char Stream::cacheDir[255];
char Stream::contentDir[255];

View File

@ -8,7 +8,6 @@
#ifdef __EMSCRIPTEN__ // TODO: http streaming
#undef DECODE_MP3
#undef DECODE_OGG
#endif
#include "utils.h"

View File

@ -126,9 +126,7 @@ struct Texture {
}
}
static Texture* LoadPCX(const char *fileName) {
Stream stream(fileName);
static Texture* LoadPCX(Stream &stream) {
struct Color24 {
uint8 r, g, b;
};
@ -155,7 +153,10 @@ struct Texture {
int i = 0;
int size = pcx.width * pcx.height;
uint8 *buffer = new uint8[size + 256 * 3 + size * 4];
int dw = Core::support.texNPOT ? pcx.width : nextPow2(pcx.width);
int dh = Core::support.texNPOT ? pcx.height : nextPow2(pcx.height);
uint8 *buffer = new uint8[size + 256 * 3 + dw * dh * 4];
while (i < size) {
uint8 n;
@ -177,15 +178,32 @@ struct Texture {
stream.raw(palette, 256 * 3);
Color32 *data = (Color32*)&palette[256];
for (i = 0; i < size; i++) {
memset(data, 0, dw * dh * 4);
Color32 *ptr = data;
/*
for (i = 0; i < pcx.height * pcx.width; i++) {
Color24 &c = palette[buffer[i]];
data[i].r = c.r;
data[i].g = c.g;
data[i].b = c.b;
data[i].a = 255;
ptr[i].r = c.r;
ptr[i].g = c.g;
ptr[i].b = c.b;
ptr[i].a = 255;
}
*/
i = 0;
for (int y = 0; y < pcx.height; y++) {
for (int x = 0; x < pcx.width; x++) {
Color24 &c = palette[buffer[i++]];
ptr[x].r = c.r;
ptr[x].g = c.g;
ptr[x].b = c.b;
ptr[x].a = 255;
}
ptr += dw;
}
Texture *tex = new Texture(pcx.width, pcx.height, Texture::RGBA, false, data);
Texture *tex = new Texture(dw, dh, Texture::RGBA, false, data);
delete[] buffer;
return tex;

View File

@ -967,13 +967,18 @@ struct Stream {
static char cacheDir[255];
static char contentDir[255];
typedef void (Callback)(Stream *stream, void *userData);
Callback *callback;
void *userData;
FILE *f;
const char *data;
char *data;
int size, pos;
char *name;
Stream(const void *data, int size) : f(NULL), data((char*)data), size(size), pos(0) {}
Stream(const void *data, int size) : callback(NULL), userData(NULL), f(NULL), data((char*)data), size(size), pos(0), name(NULL) {}
Stream(const char *name) : data(NULL), size(-1), pos(0) {
Stream(const char *name, Callback *callback = NULL, void *userData = NULL) : callback(callback), userData(userData), data(NULL), size(-1), pos(0), name(NULL) {
if (contentDir[0]) {
char path[255];
path[0] = 0;
@ -983,15 +988,30 @@ struct Stream {
} else
f = fopen(name, "rb");
if (!f) LOG("error loading file \"%s\"\n", name);
if (!f) {
#ifdef __EMSCRIPTEN__
this->name = new char[64];
strcpy(this->name, name);
extern void osDownload(Stream *stream);
osDownload(this);
return;
#else
LOG("error loading file \"%s\"\n", name);
#endif
}
ASSERT(f != NULL);
fseek(f, 0, SEEK_END);
size = ftell(f);
fseek(f, 0, SEEK_SET);
if (callback)
callback(this, userData);
}
~Stream() {
delete[] name;
if (f) fclose(f);
}