Skip to content

Commit

Permalink
#3 add water surface states, fix moving speed while roll, #4 add cont…
Browse files Browse the repository at this point in the history
…roller height for collisions, #8 add camera rotation (right mouse button), #10 add color dodge for caustics, #15 fix mouse buttons check for Windows, change canvas size of 1280x720 for HTML5
  • Loading branch information
XProger committed Sep 12, 2016
1 parent e47f8c5 commit dbd2a45
Show file tree
Hide file tree
Showing 10 changed files with 321 additions and 155 deletions.
Binary file modified bin/OpenLara.exe
Binary file not shown.
47 changes: 28 additions & 19 deletions src/camera.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,26 +137,26 @@ struct Camera : Controller {
Frustum *frustum;

float fov, znear, zfar;
vec3 target, destPos, lastDest;
vec3 target, destPos, lastDest, angleAdv;

int room;
int room;

Camera(TR::Level *level, Controller *owner) : Controller(level, owner->entity), owner(owner), frustum(new Frustum()) {
fov = 75.0f;
znear = 0.1f * 2048.0f;
zfar = 1000.0f * 2048.0f;
angle.y += PI;
fov = 75.0f;
znear = 0.1f * 2048.0f;
zfar = 1000.0f * 2048.0f;
angleAdv = vec3(0.0f);

room = owner->getEntity().room;
pos = pos - getDir() * 1024.0f;
pos = pos - owner->getDir() * 1024.0f;
}

~Camera() {
delete frustum;
}

virtual TR::Room& getRoom() const {
return level->rooms[room];
virtual int getRoomIndex() const {
return room;
}

virtual void update() {
Expand All @@ -170,24 +170,33 @@ struct Camera : Controller {
if (Input::down[ikA]) v = v - dir.cross(vec3(0, 1, 0));
pos = pos + v.normal() * (Core::deltaTime * 2048.0f);
#endif
if (Input::down[ikMouseL]) {
if (Input::down[ikMouseR]) {
vec2 delta = Input::mouse.pos - Input::mouse.start.L;
angle.x += delta.y * 0.01f;
// angle.y -= delta.x * 0.01f;
angleAdv.x += delta.y * 0.01f;
angleAdv.y += delta.x * 0.01f;
Input::mouse.start.L = Input::mouse.pos;
}

angle.y = PI - owner->angle.y;
angle.z = 0.0f;

angle.x = min(max(angle.x, -80 * DEG2RAD), 80 * DEG2RAD);

vec3 dir = getDir();
float height = 0.0f;
switch (owner->stand) {
case Controller::STAND_AIR :
case Controller::STAND_GROUND :
height = 768.0f;
break;
case Controller::STAND_UNDERWATER :
case Controller::STAND_ONWATER :
height = 256.0f;
break;
}

float height = owner->stand == Controller::STAND_UNDERWATER ? 256.0f : 768.0f;
angle = owner->angle + angleAdv;
angle.z = 0.0f;
//angle.x = min(max(angle.x, -80 * DEG2RAD), 80 * DEG2RAD);

target = vec3(owner->pos.x, owner->pos.y - height, owner->pos.z);

vec3 dir = getDir();

if (owner->state != Lara::STATE_BACK_JUMP) {
destPos = target - dir * 1024.0f;
lastDest = destPos;
Expand Down
121 changes: 68 additions & 53 deletions src/controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,19 @@ struct Controller {
return level->models[0];
}

virtual TR::Room& getRoom() const {
int index = getEntity().room;
TR::Room& getRoom() const {
int index = getRoomIndex();
ASSERT(index >= 0 && index < level->roomsCount);
return level->rooms[index];
}

TR::Room::Sector& getSector(int x, int z, int &dx, int &dz) const {
TR::Room &room = getRoom();
virtual int getRoomIndex() const {
return getEntity().room;
}

TR::Room::Sector& getSector(int roomIndex, int x, int z, int &dx, int &dz) const {
ASSERT(roomIndex >= 0 && roomIndex < level->roomsCount);
TR::Room &room = level->rooms[roomIndex];

int sx = x - room.info.x;
int sz = z - room.info.z;
Expand All @@ -105,7 +110,7 @@ struct Controller {

TR::Room::Sector& getSector(int &dx, int &dz) const {
TR::Entity &entity = getEntity();
return getSector(entity.x, entity.z, dx, dz);
return getSector(entity.room, entity.x, entity.z, dx, dz);
}

int setAnimation(int index, int frame = -1) {
Expand Down Expand Up @@ -145,7 +150,7 @@ struct Controller {

int getOverlap(int fromX, int fromY, int fromZ, int toX, int toZ, int &delta) const {
int dx, dz;
TR::Room::Sector &s = getSector(fromX, fromZ, dx, dz);
TR::Room::Sector &s = getSector(getEntity().room, fromX, fromZ, dx, dz);

if (s.boxIndex == 0xFFFF) return NO_OVERLAP;

Expand All @@ -157,12 +162,12 @@ struct Controller {

int floor = NO_OVERLAP;
delta = floor;

TR::Overlap *o = &level->overlaps[b.overlap & 0x7FFF];
do {
TR::Box &ob = level->boxes[o->boxIndex];
if (ob.contains(toX, toZ)) { // get min delta
int d = abs(ob.floor - b.floor);
int d = abs(ob.floor - fromY);
if (d < delta) {
floor = ob.floor;
delta = d;
Expand All @@ -177,18 +182,24 @@ struct Controller {
struct FloorInfo {
int floor, ceiling;
int roomNext, roomBelow, roomAbove;
int floorIndex;
};

FloorInfo getFloorInfo(int x, int z) {
return getFloorInfo(getRoomIndex(), x, z);
}

FloorInfo getFloorInfo(int roomIndex, int x, int z) {
int dx, dz;
TR::Room::Sector &s = getSector(x, z, dx, dz);
TR::Room::Sector &s = getSector(roomIndex, x, z, dx, dz);

FloorInfo info;
info.floor = 256 * (int)s.floor;
info.ceiling = 256 * (int)s.ceiling;
info.roomNext = 255;
info.roomBelow = s.roomBelow;
info.roomAbove = s.roomAbove;
info.floorIndex = s.floorIndex;

if (!s.floorIndex) return info;

Expand Down Expand Up @@ -282,22 +293,29 @@ struct Controller {
}

vec3 getDir() const {
return vec3(sinf(PI - angle.y) * cosf(-angle.x), -sinf(-angle.x), cosf(PI - angle.y) * cosf(-angle.x));
return vec3(angle.x, angle.y);
}

void turnToWall() {
float fx = pos.x / 1024.0f;
float fz = pos.z / 1024.0f;
fx -= (int)fx;
fz -= (int)fz;

float k;
if (fx > 1.0f - fz)
k = fx < fz ? 0 : 1;
else
k = fx < fz ? 3 : 2;

angle.y = k * PI * 0.5f; // clamp angle to n*PI/2
}

void collide() {
TR::Entity &entity = getEntity();

FloorInfo info = getFloorInfo(entity.x, entity.z);

/*
float hmin = 0.0f, hmax = -768.0f;
if (inWater) {
hmin = 256.0f + 128.0f;
hmax = -256.0f - 128.0f;
}
*/

if (info.roomNext != 0xFF)
entity.room = info.roomNext;

Expand All @@ -309,38 +327,28 @@ struct Controller {
} else
entity.room = info.roomBelow;
}

if (entity.y <= info.ceiling) {

int height = getHeight();
if (entity.y - getHeight() < info.ceiling) {
if (info.roomAbove == 0xFF) {
entity.y = info.ceiling;
pos.y = entity.y;
velocity.y = -velocity.y;
} else
entity.room = info.roomAbove;
}

/*
if (pos.y + hmin >= floor) {
if (s.roomBelow == 0xFF) {
pos.y = floor - hmin;
velocity.y = 0.0f;
} else
entity.room = s.roomBelow;
}
if (pos.y + hmax <= ceiling) {
if (s.roomAbove == 0xFF) {
pos.y = ceiling - hmax;
velocity.y = -velocity.y;
} else
entity.room = s.roomAbove;
pos.y = entity.y = info.ceiling + height;
velocity.y = fabsf(velocity.y);
} else {
if (stand == STAND_UNDERWATER && !(level->rooms[info.roomAbove].flags & TR::ROOM_FLAG_WATER)) {
stand = STAND_ONWATER;
velocity.y = 0;
pos.y = info.ceiling;
} else
if (stand != STAND_ONWATER && entity.y < info.ceiling)
entity.room = info.roomAbove;
}
}
*/
}

virtual void updateVelocity() {}
virtual void move() {}
virtual Stand getStand() { return STAND_AIR; }
virtual int getHeight() { return 0; }
virtual int getStateAir() { return state; }
virtual int getStateGround() { return state; }
virtual int getStateUnderwater() { return state; }
Expand Down Expand Up @@ -389,31 +397,34 @@ struct Controller {
for (int i = 0; i < anim->acCount; i++) {
int cmd = *ptr++;
switch (cmd) {
case 0x01 : { // cmd position
case TR::ANIM_CMD_MOVE : { // cmd position
int16 sx = *ptr++;
int16 sy = *ptr++;
int16 sz = *ptr++;
LOG("move: %d %d %d\n", (int)sx, (int)sy, (int)sz);
if (endFrame) {
pos = pos + vec3(sx, sy, sz).rotateY(angle.y);
updateEntity();
LOG("move: %d %d %d\n", (int)sx, (int)sy, (int)sz);
}
break;
}
case 0x02 : { // cmd jump speed
case TR::ANIM_CMD_SPEED : { // cmd jump speed
int16 sy = *ptr++;
int16 sz = *ptr++;
if (endFrame) {
LOG("jump: %d %d\n", (int)sy, (int)sz);
velocity.x = sinf(angleExt) * sz;
velocity.y = sy;
velocity.z = cosf(angleExt) * sz;
LOG("speed: %f\n", velocity.length());
stand = STAND_AIR;
}
break;
}
case 0x03 : // empty hands
case TR::ANIM_CMD_EMPTY : // empty hands
break;
case 0x04 : // kill
case TR::ANIM_CMD_KILL : // kill
break;
case 0x05 : { // play sound
case TR::ANIM_CMD_SOUND : { // play sound
int frame = (*ptr++);
int id = (*ptr++) & 0x3FFF;
int idx = frame - anim->frameStart;
Expand All @@ -424,10 +435,14 @@ struct Controller {
}
break;
}
case 0x06 : // effect
case TR::ANIM_CMD_SPECIAL : // special commands
if (frameIndex != animPrevFrame && frameIndex + anim->frameStart == ptr[0]) {
if (ptr[1] == 0) // rolling
angle.y = angle.y + PI;
switch (ptr[1]) {
case TR::ANIM_CMD_SPECIAL_FLIP : angle.y = angle.y + PI; break;
case TR::ANIM_CMD_SPECIAL_BUBBLE : /* playSound(TR::SND_BUBBLE); */ break;
case TR::ANIM_CMD_SPECIAL_CTRL : LOG("water out ?\n"); break;
default : LOG("unknown special cmd %d\n", (int)ptr[1]);
}
}
ptr += 2;
break;
Expand Down
2 changes: 1 addition & 1 deletion src/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ namespace Debug {

for (int z = 0; z < room.zSectors; z++)
for (int x = 0; x < room.xSectors; x++) {
auto &s = room.sectors[x * room.zSectors + z];
TR::Room::Sector &s = room.sectors[x * room.zSectors + z];
float floor = s.floor * 256;
/*
if (s.boxIndex < 0xFFFF) {
Expand Down
20 changes: 20 additions & 0 deletions src/format.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,25 @@ namespace TR {
FD_KILL = 5,
};

enum {
ANIM_CMD_MOVE = 1,
ANIM_CMD_SPEED = 2,
ANIM_CMD_EMPTY = 3,
ANIM_CMD_KILL = 4,
ANIM_CMD_SOUND = 5,
ANIM_CMD_SPECIAL = 6,
};

enum {
ANIM_CMD_SPECIAL_FLIP = 0,
ANIM_CMD_SPECIAL_BUBBLE = 3,
ANIM_CMD_SPECIAL_CTRL = 12,
};

enum {
SND_BUBBLE = 37,
};

#define DATA_PORTAL 0x01
#define DATA_FLOOR 0x02
#define DATA_CEILING 0x03
Expand All @@ -30,6 +49,7 @@ namespace TR {
#define ENTITY_FLAG_MASK 0x3E00

#define ENTITY_LARA 0
#define ENTITY_LARA_CUT 77

#define ENTITY_ENEMY_TWIN 6
#define ENTITY_ENEMY_WOLF 7
Expand Down
Loading

0 comments on commit dbd2a45

Please sign in to comment.