This commit is contained in:
Miloslav Číž 2018-09-17 17:55:33 +02:00
parent e91fb33a89
commit 6b9de75174
5 changed files with 184 additions and 181 deletions

View file

@ -15,10 +15,10 @@
// redefine some parameters
#define FPS 60
#define GRAVITY_ACCELERATION (UNITS_PER_SQUARE * 3)
#define GRAVITY_ACCELERATION (RCL_UNITS_PER_SQUARE * 3)
#define PLAYER_JUMP_SPEED 700
#define CAMERA_COLL_HEIGHT_BELOW ((3 * UNITS_PER_SQUARE) / 2)
#define HORIZONTAL_FOV (UNITS_PER_SQUARE / 5)
#define RCL_CAMERA_COLL_HEIGHT_BELOW ((3 * RCL_UNITS_PER_SQUARE) / 2)
#define RCL_HORIZONTAL_FOV (RCL_UNITS_PER_SQUARE / 5)
//#define USE_DIST_APPROX 1
// ^ This turns on distance approximation, which is a bit uglier and faster.
@ -31,7 +31,7 @@
Player player;
#define SPRITES 17
#define SPRITE_MAX_DISTANCE 5 * UNITS_PER_SQUARE
#define SPRITE_MAX_DISTANCE 5 * RCL_UNITS_PER_SQUARE
Sprite sprites[SPRITES];
@ -961,24 +961,24 @@ const unsigned char *textures[] = {texture1, texture2, texture3, texture4};
else\
return (whatElse);
Unit textureAt(int16_t x, int16_t y)
RCL_Unit textureAt(int16_t x, int16_t y)
{
withinMapReturn(levelTexture[index],0)
}
Unit floorHeightAt(int16_t x, int16_t y)
RCL_Unit floorHeightAt(int16_t x, int16_t y)
{
if (x == 6 && (y == 13 || y == 14)) // moving lift
return
((absVal(-1 * (pokitto.frameCount % 64) + 32)) * UNITS_PER_SQUARE) / 8;
((RCL_absVal(-1 * (pokitto.frameCount % 64) + 32)) * RCL_UNITS_PER_SQUARE) / 8;
withinMapReturn((levelFloor[index] * UNITS_PER_SQUARE) / 8,0)
withinMapReturn((levelFloor[index] * RCL_UNITS_PER_SQUARE) / 8,0)
}
Unit ceilingHeightAt(int16_t x, int16_t y)
RCL_Unit ceilingHeightAt(int16_t x, int16_t y)
{
withinMapReturn(levelCeiling[index] * UNITS_PER_SQUARE / 8,
127 * UNITS_PER_SQUARE / 8)
withinMapReturn(levelCeiling[index] * RCL_UNITS_PER_SQUARE / 8,
127 * RCL_UNITS_PER_SQUARE / 8)
}
#undef withinMapReturn
@ -987,17 +987,17 @@ Unit ceilingHeightAt(int16_t x, int16_t y)
Function for drawing a single pixel (like fragment shader). Bottleneck =>
should be as fast as possible.
*/
inline void pixelFunc(PixelInfo *pixel)
inline void pixelFunc(RCL_PixelInfo *pixel)
{
if (pixel->position.y == MIDDLE_ROW)
zBuffer[pixel->position.x] = pixel->depth;
uint8_t c;
Unit depth = pixel->depth - UNITS_PER_SQUARE * 3;
RCL_Unit depth = pixel->depth - RCL_UNITS_PER_SQUARE * 3;
depth = depth > 0 ? depth : 1;
int intensity = 7 - (depth * 7) / (UNITS_PER_SQUARE * 5);
int intensity = 7 - (depth * 7) / (RCL_UNITS_PER_SQUARE * 5);
if (intensity < 0)
intensity = 0;
@ -1010,7 +1010,7 @@ inline void pixelFunc(PixelInfo *pixel)
if (intensity < 0)
intensity = 0;
#if COMPUTE_WALL_TEXCOORDS == 1
#if RCL_COMPUTE_WALL_TEXCOORDS == 1
c = sampleImage(textures[pixel->hit.type],pixel->texCoords.x,pixel->texCoords.y);
#else
c = textures[pixel->hit.type][2];
@ -1028,27 +1028,27 @@ inline void pixelFunc(PixelInfo *pixel)
void draw()
{
RayConstraints c;
RCL_RayConstraints c;
c.maxHits = 8;
c.maxSteps = 10;
render(player.mCamera,floorHeightAt,ceilingHeightAt,textureAt,c);
RCL_render(player.mCamera,floorHeightAt,ceilingHeightAt,textureAt,c);
Unit previousDepth;
RCL_Unit previousDepth;
// draw sprites
for (uint8_t i = 0; i < SPRITES; ++i)
{
// use Chebyshew distance instead Euclidean, it's faster
if (absVal(sprites[i].mPosition.x - player.mCamera.position.x) > SPRITE_MAX_DISTANCE)
if (RCL_absVal(sprites[i].mPosition.x - player.mCamera.position.x) > SPRITE_MAX_DISTANCE)
continue;
if (absVal(sprites[i].mPosition.y - player.mCamera.position.y) > SPRITE_MAX_DISTANCE)
if (RCL_absVal(sprites[i].mPosition.y - player.mCamera.position.y) > SPRITE_MAX_DISTANCE)
continue;
PixelInfo pos = mapToScreen(sprites[i].mPosition,sprites[i].mHeight,player.mCamera);
RCL_PixelInfo pos = RCL_mapToScreen(sprites[i].mPosition,sprites[i].mHeight,player.mCamera);
if (pos.depth > 0)
{
@ -1060,7 +1060,7 @@ void draw()
drawSpriteSquare(image,pos.position.x * SUBSAMPLE,
pos.position.y, pos.depth,
perspectiveScale(sprites[i].mPixelSize,pos.depth));
RCL_perspectiveScale(sprites[i].mPixelSize,pos.depth));
}
/* trick: sort the sprites by distance with bubble sort as we draw - the
@ -1102,7 +1102,7 @@ int main()
sprites[1] = Sprite(spriteStatue,14,5,1,100);
sprites[2] = Sprite(spriteNPC,15,19,1,200);
sprites[3] = Sprite(spriteTree,8,2,1,300);
sprites[3].mPosition.y -= UNITS_PER_SQUARE / 2;
sprites[3].mPosition.y -= RCL_UNITS_PER_SQUARE / 2;
sprites[4] = Sprite(spriteTree,20,5,1,300);
sprites[5] = Sprite(spriteTree,26,18,1,300);
sprites[6] = Sprite(spriteTree,16,12,1,300);
@ -1113,13 +1113,13 @@ int main()
sprites[11] = Sprite(spriteBarrel,12,16,0,120);
sprites[12] = Sprite(spriteBarrel,27,5,0,120);
sprites[13] = Sprite(spriteTorch1,11,9,2,120);
sprites[13].mPosition.y += UNITS_PER_SQUARE / 3;
sprites[13].mPosition.y += RCL_UNITS_PER_SQUARE / 3;
sprites[14] = Sprite(spriteTorch1,13,9,2,120);
sprites[14].mPosition.y += UNITS_PER_SQUARE / 3;
sprites[14].mPosition.y += RCL_UNITS_PER_SQUARE / 3;
sprites[15] = Sprite(spriteTorch1,14,19,2,120);
sprites[15].mPosition.y += UNITS_PER_SQUARE / 3;
sprites[15].mPosition.y += RCL_UNITS_PER_SQUARE / 3;
sprites[16] = Sprite(spriteTorch1,1,19,3,120);
sprites[16].mPosition.y += UNITS_PER_SQUARE / 3;
sprites[16].mPosition.y += RCL_UNITS_PER_SQUARE / 3;
uint32_t previousTime = 0;
uint32_t dt;

View file

@ -34,12 +34,12 @@
//#define NO_MIRROR
/* ^ Turns off the floor mirror effect, which should increase FPS. */
//#define USE_DIST_APPROX 1
//#define RCL_USE_DIST_APPROX 1
/* ^ Turns on distance approximation, which won't compute exact distances but
only approximations - this should increase performance a little, but
results in slightly distorted walls. */
//#define USE_COS_LUT 2
//#define RCL_USE_COS_LUT 2
/* ^ Turns on cos look up tables (128 items, USE_COS_LUT 1 will use only 64
items), which should theoretically be faster, but will take additional
memory and turning can be less precise (can be seen a lot with 64 item
@ -50,13 +50,13 @@
right, 0 to both. */
#ifdef NO_TEXTURES
#define COMPUTE_WALL_TEXCOORDS 0
#define RCL_COMPUTE_WALL_TEXCOORDS 0
#endif
#define FPS 256
#define HEAD_BOB_HEIGHT 200
#define HEAD_BOB_STEP 20
#define PLAYER_SPEED (5 * UNITS_PER_SQUARE)
#define PLAYER_SPEED (5 * RCL_UNITS_PER_SQUARE)
#include "general.hpp"
@ -65,9 +65,9 @@
Player player;
#define SHOT_SPEED 10 * UNITS_PER_SQUARE
#define SHOT_SPEED 10 * RCL_UNITS_PER_SQUARE
#define INFO_BAR_START 70
#define TEXTURE_MAX_DISTANCE (UNITS_PER_SQUARE * 6)
#define TEXTURE_MAX_DISTANCE (RCL_UNITS_PER_SQUARE * 6)
// temporary defines for better visibility of walls and floors below
#define D 6
@ -875,34 +875,34 @@ const unsigned char *textures[TEXTURES] =
unsigned char textureAverageColors[TEXTURES];
Unit floorHeightAt(int16_t x, int16_t y)
RCL_Unit floorHeightAt(int16_t x, int16_t y)
{
if (x < 0 || x >= LEVEL_X_RES || y < 0 || y >= LEVEL_Y_RES)
return UNITS_PER_SQUARE * 2;
return RCL_UNITS_PER_SQUARE * 2;
Unit square = level[(LEVEL_Y_RES - y -1) * LEVEL_X_RES + x];
RCL_Unit square = level[(LEVEL_Y_RES - y -1) * LEVEL_X_RES + x];
#ifdef RENDER_PRECISE
/* algorithm used with this version doesn't support rolling doors, so give
door square zero height */
return square == 0 || square == 6 ? 0 : UNITS_PER_SQUARE * 2;
return square == 0 || square == 6 ? 0 : RCL_UNITS_PER_SQUARE * 2;
#else
return square == 0 ? 0 : UNITS_PER_SQUARE * 2;
return square == 0 ? 0 : RCL_UNITS_PER_SQUARE * 2;
#endif
}
Unit collisionAt(int16_t x, int16_t y)
RCL_Unit collisionAt(int16_t x, int16_t y)
{
if (x < 0 || x >= LEVEL_X_RES || y < 0 || y >= LEVEL_Y_RES)
return UNITS_PER_SQUARE;
return RCL_UNITS_PER_SQUARE;
Unit square = level[(LEVEL_Y_RES - y -1) * LEVEL_X_RES + x];
return square == 0 || square == 6 ? 0 : UNITS_PER_SQUARE;
RCL_Unit square = level[(LEVEL_Y_RES - y -1) * LEVEL_X_RES + x];
return square == 0 || square == 6 ? 0 : RCL_UNITS_PER_SQUARE;
}
Unit textureAt(int16_t x, int16_t y)
RCL_Unit textureAt(int16_t x, int16_t y)
{
Unit t = 0;
RCL_Unit t = 0;
if (x >= 0 && x < LEVEL_X_RES && y >= 0 && y < LEVEL_Y_RES)
t = max(level[(LEVEL_Y_RES - y -1) * LEVEL_X_RES + x] - 1,0);
@ -910,19 +910,19 @@ Unit textureAt(int16_t x, int16_t y)
return t;
}
Unit rollAt(int16_t x, int16_t y)
RCL_Unit rollAt(int16_t x, int16_t y)
{
if (x >= 0 && x < LEVEL_X_RES && y >= 0 && y < LEVEL_Y_RES &&
level[(LEVEL_Y_RES - y -1) * LEVEL_X_RES + x] == 6)
return sinInt(pokitto.frameCount * 10) + DOOR_ROLL_SIGN * UNITS_PER_SQUARE;
return RCL_sinInt(pokitto.frameCount * 10) + DOOR_ROLL_SIGN * RCL_UNITS_PER_SQUARE;
return 0;
}
uint8_t cFloor, cCeiling;
Vector2D shotPosition;
Vector2D shotDirection;
RCL_Vector2D shotPosition;
RCL_Vector2D shotDirection;
bool shotFired = false;
uint8_t previousColumn = 255; ///< Helper for pixelIntensity.
@ -933,7 +933,7 @@ int16_t mirror = 0;
/**
Function for drawing a single pixel (like fragment shader).
*/
inline void pixelFunc(PixelInfo *pixel)
inline void pixelFunc(RCL_PixelInfo *pixel)
{
if (pixel->position.y == MIDDLE_ROW)
zBuffer[pixel->position.x] = pixel->depth;
@ -951,9 +951,9 @@ inline void pixelFunc(PixelInfo *pixel)
#ifndef NO_MIRROR
int16_t intensity = pixel->isFloor ?
-1 * (pixel->depth - mirror * 64) / UNITS_PER_SQUARE : 0;
-1 * (pixel->depth - mirror * 64) / RCL_UNITS_PER_SQUARE : 0;
#else
int16_t intensity = -1 * pixel->depth / (UNITS_PER_SQUARE * 2);
int16_t intensity = -1 * pixel->depth / (RCL_UNITS_PER_SQUARE * 2);
#endif
c = addIntensity(c,intensity);
@ -962,7 +962,7 @@ inline void pixelFunc(PixelInfo *pixel)
}
else
{
Unit textureScroll = pixel->hit.type != 4 ? 0 : 16 * pokitto.frameCount;
RCL_Unit textureScroll = pixel->hit.type != 4 ? 0 : 16 * pokitto.frameCount;
#ifdef NO_TEXTURES
c = textureAverageColors[pixel->hit.type];
@ -980,7 +980,7 @@ inline void pixelFunc(PixelInfo *pixel)
else
{
// optimization: precompute intensity for the whole column
pixelIntensity = 1 - pixel->depth / (UNITS_PER_SQUARE * 2) + (pixel->hit.direction % 2 == 0 ? 2 : 0);
pixelIntensity = 1 - pixel->depth / (RCL_UNITS_PER_SQUARE * 2) + (pixel->hit.direction % 2 == 0 ? 2 : 0);
previousColumn = pixel->position.x;
c = addIntensity(c,pixelIntensity);
}
@ -993,7 +993,7 @@ inline void pixelFunc(PixelInfo *pixel)
void draw()
{
RayConstraints c;
RCL_RayConstraints c;
c.maxHits = 1;
c.maxSteps = 20;
@ -1001,20 +1001,20 @@ void draw()
player.mCamera.height += player.mHeadBob;
#ifdef RENDER_PRECISE
render(player.mCamera,floorHeightAt,0,textureAt,c);
RCL_render(player.mCamera,floorHeightAt,0,textureAt,c);
#else
renderSimple(player.mCamera,floorHeightAt,textureAt,rollAt,c);
RCL_renderSimple(player.mCamera,floorHeightAt,textureAt,rollAt,c);
#endif
player.mCamera.height -= player.mHeadBob;
if (shotFired)
{
PixelInfo pos = mapToScreen(shotPosition,UNITS_PER_SQUARE,player.mCamera);
RCL_PixelInfo pos = RCL_mapToScreen(shotPosition,RCL_UNITS_PER_SQUARE,player.mCamera);
drawSpriteSquare(spritePlasma,pos.position.x * SUBSAMPLE,
pos.position.y,pos.depth,
perspectiveScale(64,pos.depth));
RCL_perspectiveScale(64,pos.depth));
}
drawImage(imageBar,0,INFO_BAR_START - 3);
@ -1031,7 +1031,7 @@ int main()
cCeiling = rgbToIndex(3,2,0);
player.setPositionSquare(6,5);
player.mCamera.height = CAMERA_COLL_HEIGHT_BELOW;
player.mCamera.height = RCL_CAMERA_COLL_HEIGHT_BELOW;
player.mCamera.resolution.y = INFO_BAR_START + 1;
@ -1058,22 +1058,22 @@ int main()
{
// update the shot
Unit shotStep = (dt * SHOT_SPEED) / 1000;
RCL_Unit shotStep = (dt * SHOT_SPEED) / 1000;
shotPosition.x += (shotStep * shotDirection.x) / UNITS_PER_SQUARE;
shotPosition.y += (shotStep * shotDirection.y) / UNITS_PER_SQUARE;
shotPosition.x += (shotStep * shotDirection.x) / RCL_UNITS_PER_SQUARE;
shotPosition.y += (shotStep * shotDirection.y) / RCL_UNITS_PER_SQUARE;
if (
absVal(shotPosition.x - player.mCamera.position.x) > UNITS_PER_SQUARE * 5 ||
absVal(shotPosition.y - player.mCamera.position.y) > UNITS_PER_SQUARE * 5 ||
(textureAt(shotPosition.x / UNITS_PER_SQUARE,shotPosition.y / UNITS_PER_SQUARE) != 0)
RCL_absVal(shotPosition.x - player.mCamera.position.x) > RCL_UNITS_PER_SQUARE * 5 ||
RCL_absVal(shotPosition.y - player.mCamera.position.y) > RCL_UNITS_PER_SQUARE * 5 ||
(textureAt(shotPosition.x / RCL_UNITS_PER_SQUARE,shotPosition.y / RCL_UNITS_PER_SQUARE) != 0)
)
shotFired = false;
}
else if (pokitto.bBtn())
{
shotPosition = player.mCamera.position;
shotDirection = angleToDirection(player.mCamera.direction);
shotDirection = RCL_angleToDirection(player.mCamera.direction);
shotFired = true;
}

View file

@ -11,15 +11,15 @@
*/
// redefine player's height
#define PLAYER_SPEED (UNITS_PER_SQUARE * 6)
#define HORIZONTAL_FOV ((3 * UNITS_PER_SQUARE) / 10)
#define GRAVITY_ACCELERATION (UNITS_PER_SQUARE * 2)
#define CAMERA_COLL_HEIGHT_BELOW ((3 * UNITS_PER_SQUARE) / 2)
#define PLAYER_SPEED (RCL_UNITS_PER_SQUARE * 6)
#define RCL_HORIZONTAL_FOV ((3 * RCL_UNITS_PER_SQUARE) / 10)
#define GRAVITY_ACCELERATION (RCL_UNITS_PER_SQUARE * 2)
#define RCL_CAMERA_COLL_HEIGHT_BELOW ((3 * RCL_UNITS_PER_SQUARE) / 2)
#define FPS 40
#define HEAD_BOB_HEIGHT 150
#define HEAD_BOB_STEP 20
#define COMPUTE_WALL_TEXCOORDS 0 // we won't be using textures, so turn them off
#define RCL_COMPUTE_WALL_TEXCOORDS 0 // we won't be using textures, so turn them off
#include "general.hpp"
@ -28,12 +28,12 @@
Player player;
#define SPRITE_MAX_DISTANCE 5 * UNITS_PER_SQUARE
#define SPRITE_MAX_DISTANCE 5 * RCL_UNITS_PER_SQUARE
#define JUMP_SPEED 500
char floorColor = 0;
Vector2D selectedSquare; ///< Coords of a square selected for editing.
RCL_Vector2D selectedSquare; ///< Coords of a square selected for editing.
/**
Represents one terrain change against the implicit terrain.
@ -41,8 +41,8 @@ Vector2D selectedSquare; ///< Coords of a square selected for editing.
class Change
{
public:
Vector2D mCoords;
Unit mHeight;
RCL_Vector2D mCoords;
RCL_Unit mHeight;
int8_t mColor;
};
@ -423,7 +423,7 @@ const unsigned char imageBackground[] =
,0xc1,0x29,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38
};
Unit floorHeightAt(int16_t x, int16_t y)
RCL_Unit floorHeightAt(int16_t x, int16_t y)
{
/*
This for loop may become a bottleneck, since this function is called
@ -434,19 +434,19 @@ Unit floorHeightAt(int16_t x, int16_t y)
if (changes[i].mCoords.x == x && changes[i].mCoords.y == y)
return changes[i].mHeight;
return (heightProfile[absVal(x) % HEIGHT_PROFILE_LENGTH] +
heightProfile[absVal(y + 20) % HEIGHT_PROFILE_LENGTH]) *
UNITS_PER_SQUARE;
return (heightProfile[RCL_absVal(x) % HEIGHT_PROFILE_LENGTH] +
heightProfile[RCL_absVal(y + 20) % HEIGHT_PROFILE_LENGTH]) *
RCL_UNITS_PER_SQUARE;
}
Unit colorAt(int16_t x, int16_t y)
RCL_Unit colorAt(int16_t x, int16_t y)
{
for (uint16_t i = 0; i < MAX_CHANGES; ++i)
if (changes[i].mCoords.x == x && changes[i].mCoords.y == y)
return changes[i].mColor;
return min((heightProfile[absVal(x * 2) % HEIGHT_PROFILE_LENGTH] +
heightProfile[absVal(y) % HEIGHT_PROFILE_LENGTH]) / 10,3);
return min((heightProfile[RCL_absVal(x * 2) % HEIGHT_PROFILE_LENGTH] +
heightProfile[RCL_absVal(y) % HEIGHT_PROFILE_LENGTH]) / 10,3);
}
uint16_t previousColumn = 255; ///< Helper for precomputing background.
@ -455,7 +455,7 @@ uint16_t backgroundColumn = 0; ///< Precomputed background column.
/**
Function for drawing a single pixel (like fragment shader).
*/
inline void pixelFunc(PixelInfo *pixel)
inline void pixelFunc(RCL_PixelInfo *pixel)
{
uint8_t c = 0;
int16_t intensity = 0;
@ -465,7 +465,7 @@ inline void pixelFunc(PixelInfo *pixel)
c = pixel->hit.square.x != selectedSquare.x || pixel->hit.square.y != selectedSquare.y || (editing && pokitto.frameCount % 2) == 0 ?
squareColors[pixel->hit.type] : 30;
intensity = pixel->depth / (UNITS_PER_SQUARE * 3);
intensity = pixel->depth / (RCL_UNITS_PER_SQUARE * 3);
intensity += pixel->hit.direction % 2 == 0 ? 2 : 0;
}
else if (pixel->isFloor)
@ -473,17 +473,17 @@ inline void pixelFunc(PixelInfo *pixel)
c = floorColor;
if (!pixel->isHorizon)
intensity = pixel->depth / (UNITS_PER_SQUARE * 3);
intensity = pixel->depth / (RCL_UNITS_PER_SQUARE * 3);
}
else
{
if (previousColumn == pixel->position.x)
{
c = imageBackground[2 + backgroundColumn * 44 + clamp(pixel->position.y - player.mCamera.shear,0,43)];
c = imageBackground[2 + backgroundColumn * 44 + RCL_clamp(pixel->position.y - player.mCamera.shear,0,43)];
}
else
{
backgroundColumn = absVal(pixel->position.x + (110 * player.mCamera.direction) / UNITS_PER_SQUARE) % 110;
backgroundColumn = RCL_absVal(pixel->position.x + (110 * player.mCamera.direction) / RCL_UNITS_PER_SQUARE) % 110;
previousColumn = pixel->position.x;
}
}
@ -498,13 +498,13 @@ bool flyBy = true;
void draw()
{
RayConstraints c;
RCL_RayConstraints c;
c.maxHits = 6;
c.maxSteps = 20;
player.mCamera.height += player.mHeadBob;
render(player.mCamera,floorHeightAt,0,colorAt,c);
RCL_render(player.mCamera,floorHeightAt,0,colorAt,c);
player.mCamera.height -= player.mHeadBob;
if (flyBy && (pokitto.frameCount >> 3) % 3 != 0)
@ -520,23 +520,23 @@ void draw()
void cameraFlyBy(uint32_t dt)
{
Unit height = floorHeightAt(
divRoundDown(player.mCamera.position.x,UNITS_PER_SQUARE),
divRoundDown(player.mCamera.position.y,UNITS_PER_SQUARE)) + UNITS_PER_SQUARE * 3;
RCL_Unit height = floorHeightAt(
RCL_divRoundDown(player.mCamera.position.x,RCL_UNITS_PER_SQUARE),
RCL_divRoundDown(player.mCamera.position.y,RCL_UNITS_PER_SQUARE)) + RCL_UNITS_PER_SQUARE * 3;
Unit heightDiff = player.mCamera.height - height;
RCL_Unit heightDiff = player.mCamera.height - height;
Unit step = (200 * dt) / 1000;
RCL_Unit step = (200 * dt) / 1000;
if (heightDiff > UNITS_PER_SQUARE * 2)
if (heightDiff > RCL_UNITS_PER_SQUARE * 2)
{
player.mCamera.height -= step * heightDiff / 200;
player.mCamera.shear = max(player.mCamera.shear - 1,-80);
}
else
{
if (heightDiff < UNITS_PER_SQUARE)
player.mCamera.height += step * absVal(heightDiff / 70);
if (heightDiff < RCL_UNITS_PER_SQUARE)
player.mCamera.height += step * RCL_absVal(heightDiff / 70);
if (player.mCamera.shear < 0 && pokitto.frameCount % 2 == 0)
player.mCamera.shear++;
@ -544,7 +544,7 @@ void cameraFlyBy(uint32_t dt)
player.mCamera.position.x += step * 30;
player.mCamera.position.y += step * 15;
player.mCamera.direction = sinInt(pokitto.frameCount / 8);
player.mCamera.direction = RCL_sinInt(pokitto.frameCount / 8);
}
int main()
@ -615,30 +615,30 @@ int main()
if (editing)
{
Vector2D facingOffset;
RCL_Vector2D facingOffset;
facingOffset.x = 0;
facingOffset.y = 0;
if (player.mCamera.direction > (4 * UNITS_PER_SQUARE / 12) &&
player.mCamera.direction <= (8 * UNITS_PER_SQUARE / 12))
if (player.mCamera.direction > (4 * RCL_UNITS_PER_SQUARE / 12) &&
player.mCamera.direction <= (8 * RCL_UNITS_PER_SQUARE / 12))
facingOffset.x = -1;
else if (player.mCamera.direction < (2 * UNITS_PER_SQUARE / 12) ||
player.mCamera.direction >= (10 * UNITS_PER_SQUARE / 12))
else if (player.mCamera.direction < (2 * RCL_UNITS_PER_SQUARE / 12) ||
player.mCamera.direction >= (10 * RCL_UNITS_PER_SQUARE / 12))
facingOffset.x = 1;
else
facingOffset.x = 0;
if (player.mCamera.direction > (UNITS_PER_SQUARE / 12) &&
player.mCamera.direction <= (5 * UNITS_PER_SQUARE / 12))
if (player.mCamera.direction > (RCL_UNITS_PER_SQUARE / 12) &&
player.mCamera.direction <= (5 * RCL_UNITS_PER_SQUARE / 12))
facingOffset.y = -1;
else if (player.mCamera.direction > (6 * UNITS_PER_SQUARE / 12) &&
player.mCamera.direction <= (11 * UNITS_PER_SQUARE / 12))
else if (player.mCamera.direction > (6 * RCL_UNITS_PER_SQUARE / 12) &&
player.mCamera.direction <= (11 * RCL_UNITS_PER_SQUARE / 12))
facingOffset.y = 1;
else
facingOffset.y = 0;
selectedSquare.x = divRoundDown(player.mCamera.position.x,UNITS_PER_SQUARE) + facingOffset.x;
selectedSquare.y = divRoundDown(player.mCamera.position.y,UNITS_PER_SQUARE) + facingOffset.y;
selectedSquare.x = RCL_divRoundDown(player.mCamera.position.x,RCL_UNITS_PER_SQUARE) + facingOffset.x;
selectedSquare.y = RCL_divRoundDown(player.mCamera.position.y,RCL_UNITS_PER_SQUARE) + facingOffset.y;
changeIndex = (changeIndex + 1) % MAX_CHANGES;
@ -669,7 +669,7 @@ int main()
{
if (editCounter == 0)
{
changes[changeIndex].mHeight += UNITS_PER_SQUARE / 4;
changes[changeIndex].mHeight += RCL_UNITS_PER_SQUARE / 4;
editCounter = 4;
}
}
@ -684,7 +684,7 @@ int main()
{
if (editCounter == 0)
{
changes[changeIndex].mHeight -= UNITS_PER_SQUARE / 4;
changes[changeIndex].mHeight -= RCL_UNITS_PER_SQUARE / 4;
editCounter = 4;
}
}
@ -719,14 +719,14 @@ int main()
{
int16_t heightDiff = changes[changeIndex].mHeight - player.mCamera.height;
if (heightDiff > UNITS_PER_SQUARE / 2)
if (heightDiff > RCL_UNITS_PER_SQUARE / 2)
shearDirection = 1;
else if (heightDiff < -1 * UNITS_PER_SQUARE / 2)
else if (heightDiff < -1 * RCL_UNITS_PER_SQUARE / 2)
shearDirection = -1;
if (editCounter == 0 && colorAddition != 0)
{
changes[changeIndex].mColor = wrap(changes[changeIndex].mColor + colorAddition,SQUARE_COLORS);
changes[changeIndex].mColor = RCL_wrap(changes[changeIndex].mColor + colorAddition,SQUARE_COLORS);
editCounter = 4;
}
}

View file

@ -14,9 +14,12 @@
#include "stdio.h" // for debugging raycastlibg
#define VERTICAL_FOV UNITS_PER_SQUARE // redefine camera vertical FOV
#define PIXEL_FUNCTION pixelFunc
#define RCL_VERTICAL_FOV RCL_UNITS_PER_SQUARE /* redefine camera vertical FOV:
RCL_UNITS_PER_SQUARE would normally mean
360 degrees, but it's not an actual
angle, just linear approximation, so
this is okay */
#define RCL_PIXEL_FUNCTION pixelFunc
/* ^ This has to be defined to the name of the function that will render
pixels. */
@ -30,11 +33,11 @@ Pokitto::Core pokitto;
#endif
#ifndef PLAYER_SPEED
#define PLAYER_SPEED (4 * UNITS_PER_SQUARE)
#define PLAYER_SPEED (4 * RCL_UNITS_PER_SQUARE)
#endif
#ifndef PLAYER_ROTATION_SPEED
#define PLAYER_ROTATION_SPEED (UNITS_PER_SQUARE / 2)
#define PLAYER_ROTATION_SPEED (RCL_UNITS_PER_SQUARE / 2)
#endif
#ifndef PLAYER_JUMP_SPEED
@ -50,7 +53,7 @@ Pokitto::Core pokitto;
#endif
#ifndef GRAVITY_ACCELERATION
#define GRAVITY_ACCELERATION ((3 * UNITS_PER_SQUARE) / 2)
#define GRAVITY_ACCELERATION ((3 * RCL_UNITS_PER_SQUARE) / 2)
#endif
#define SCREEN_WIDTH 110
@ -67,7 +70,7 @@ Pokitto::Core pokitto;
#define TRANSPARENT_COLOR 0b00000111 /// Transparent color for sprites and GUI.
Unit zBuffer[SUBSAMPLED_WIDTH]; ///< 1D z-buffer for visibility determination.
RCL_Unit zBuffer[SUBSAMPLED_WIDTH]; ///< 1D z-buffer for visibility determination.
unsigned short palette[256];
@ -156,27 +159,27 @@ inline uint8_t addRGB(uint8_t color, int16_t red, int16_t green, int16_t blue)
int8_t g = (color & 0b00111000) >> 3;
int8_t b = (color & 0b11000000) >> 6;
r = clamp(r + red,0,7);
g = clamp(g + green,0,7);
b = clamp(b + blue,0,3);
r = RCL_clamp(r + red,0,7);
g = RCL_clamp(g + green,0,7);
b = RCL_clamp(b + blue,0,3);
return rgbToIndex(r,g,b);
}
/**
Samples an image by normalized coordinates - each coordinate is in range
0 to UNITS_PER_SQUARE (from raycastlib).
0 to RCL_UNITS_PER_SQUARE (from raycastlib).
*/
inline uint8_t sampleImage(const unsigned char *image, Unit x, Unit y)
inline uint8_t sampleImage(const unsigned char *image, RCL_Unit x, RCL_Unit y)
{
// TODO: optimize
x = wrap(x,UNITS_PER_SQUARE);
y = wrap(y,UNITS_PER_SQUARE);
x = RCL_wrap(x,RCL_UNITS_PER_SQUARE);
y = RCL_wrap(y,RCL_UNITS_PER_SQUARE);
int32_t index =
image[1] * ((image[0] * x) / UNITS_PER_SQUARE) + (image[0] * y) /
UNITS_PER_SQUARE;
image[1] * ((image[0] * x) / RCL_UNITS_PER_SQUARE) + (image[0] * y) /
RCL_UNITS_PER_SQUARE;
return image[2 + index];
}
@ -185,7 +188,7 @@ inline uint8_t sampleImage(const unsigned char *image, Unit x, Unit y)
Draws a scaled sprite on screen in an optimized way. The sprite has to be
square in resolution.
*/
void inline drawSpriteSquare(const unsigned char *sprite, int16_t x, int16_t y, Unit depth, int16_t size)
void inline drawSpriteSquare(const unsigned char *sprite, int16_t x, int16_t y, RCL_Unit depth, int16_t size)
{
if (size < 0 || size > 200 || // let's not mess up with the incoming array
sprite[0] != sprite[1]) // only draw square sprites
@ -195,7 +198,7 @@ void inline drawSpriteSquare(const unsigned char *sprite, int16_t x, int16_t y,
// optimization: precompute the indices
for (Unit i = 0; i < size; ++i)
for (RCL_Unit i = 0; i < size; ++i)
samplingIndices[i] = (i * sprite[0]) / size;
x -= size / 2;
@ -206,7 +209,7 @@ void inline drawSpriteSquare(const unsigned char *sprite, int16_t x, int16_t y,
int16_t jTo = size - max(0,y + size - 88);
int16_t iTo = size - max(0,x + size - 110);
for (Unit i = max(-1 * x,0); i < iTo; ++i)
for (RCL_Unit i = max(-1 * x,0); i < iTo; ++i)
{
int16_t xPos = x + i;
@ -215,7 +218,7 @@ void inline drawSpriteSquare(const unsigned char *sprite, int16_t x, int16_t y,
int16_t columnLocation = 2 + samplingIndices[i] * sprite[0];
for (Unit j = max(-1 * y,0); j < jTo; ++j)
for (RCL_Unit j = max(-1 * y,0); j < jTo; ++j)
{
c = sprite[columnLocation + samplingIndices[j]];
@ -248,20 +251,20 @@ void drawImage(const unsigned char *image, int16_t x, int16_t y)
class Player
{
public:
Camera mCamera;
Unit mVericalSpeed;
RCL_Camera mCamera;
RCL_Unit mVericalSpeed;
bool mRunning;
Unit mHeadBob;
RCL_Unit mHeadBob;
bool mHeadBobUp;
Player()
{
initCamera(&mCamera);
RCL_initCamera(&mCamera);
mCamera.position.x = 0;
mCamera.position.y = 0;
mCamera.direction = 0;
mCamera.height = UNITS_PER_SQUARE * 3;
mCamera.height = RCL_UNITS_PER_SQUARE * 3;
mCamera.resolution.x = SCREEN_WIDTH / SUBSAMPLE;
mCamera.resolution.y = SCREEN_HEIGHT;
mCamera.shear = 0;
@ -271,13 +274,13 @@ public:
mHeadBobUp = true;
}
void setPosition(Unit x, Unit y)
void setPosition(RCL_Unit x, RCL_Unit y)
{
mCamera.position.x = x;
mCamera.position.y = y;
}
void setPosition(Unit x, Unit y, Unit z, Unit direction)
void setPosition(RCL_Unit x, RCL_Unit y, RCL_Unit z, RCL_Unit direction)
{
mCamera.position.x = x;
mCamera.position.y = y;
@ -288,15 +291,15 @@ public:
void setPositionSquare(int16_t squareX, int16_t squareY)
{
setPosition(
squareX * UNITS_PER_SQUARE + UNITS_PER_SQUARE / 2,
squareY * UNITS_PER_SQUARE + UNITS_PER_SQUARE / 2);
squareX * RCL_UNITS_PER_SQUARE + RCL_UNITS_PER_SQUARE / 2,
squareY * RCL_UNITS_PER_SQUARE + RCL_UNITS_PER_SQUARE / 2);
}
void update(int16_t moveDirection, bool strafe, int16_t turnDirection, bool jump,
int16_t shearDirection, ArrayFunction floorHeightFunction,
ArrayFunction ceilingHeightFunction, bool computeHeight, uint32_t dt)
int16_t shearDirection, RCL_ArrayFunction floorHeightFunction,
RCL_ArrayFunction ceilingHeightFunction, bool computeHeight, uint32_t dt)
{
Vector2D moveOffset;
RCL_Vector2D moveOffset;
moveOffset.x = 0;
moveOffset.y = 0;
@ -306,10 +309,10 @@ public:
int16_t horizontalStep = (dt * PLAYER_SPEED * (mRunning ? 2 : 1)) / 1000 *
(moveDirection > 0 ? 1 : -1);
moveOffset = angleToDirection(mCamera.direction + (strafe ? UNITS_PER_SQUARE / 4 : 0));
moveOffset = RCL_angleToDirection(mCamera.direction + (strafe ? RCL_UNITS_PER_SQUARE / 4 : 0));
moveOffset.x = (moveOffset.x * horizontalStep) / UNITS_PER_SQUARE;
moveOffset.y = (moveOffset.y * horizontalStep) / UNITS_PER_SQUARE;
moveOffset.x = (moveOffset.x * horizontalStep) / RCL_UNITS_PER_SQUARE;
moveOffset.y = (moveOffset.y * horizontalStep) / RCL_UNITS_PER_SQUARE;
mHeadBob += mHeadBobUp ? HEAD_BOB_STEP : -HEAD_BOB_STEP;
@ -324,31 +327,31 @@ public:
if (turnDirection != 0)
{
int16_t rotationStep = (dt * PLAYER_ROTATION_SPEED) / 1000;
mCamera.direction = wrap(mCamera.direction + turnDirection * rotationStep,UNITS_PER_SQUARE);
mCamera.direction = RCL_wrap(mCamera.direction + turnDirection * rotationStep,RCL_UNITS_PER_SQUARE);
}
Unit prevHeight = mCamera.height;
RCL_Unit prevHeight = mCamera.height;
moveCameraWithCollision(&mCamera,moveOffset,mVericalSpeed,
RCL_moveCameraWithCollision(&mCamera,moveOffset,mVericalSpeed,
floorHeightFunction, ceilingHeightFunction, computeHeight ? 1 : 0, 0);
Unit heightDiff = mCamera.height - prevHeight;
RCL_Unit heightDiff = mCamera.height - prevHeight;
if (heightDiff == 0)
mVericalSpeed = 0; // hit floor/ceiling
if (jump && mVericalSpeed == 0)
{
int16_t camX = divRoundDown(mCamera.position.x,UNITS_PER_SQUARE);
int16_t camY = divRoundDown(mCamera.position.y,UNITS_PER_SQUARE);
int16_t camX = RCL_divRoundDown(mCamera.position.x,RCL_UNITS_PER_SQUARE);
int16_t camY = RCL_divRoundDown(mCamera.position.y,RCL_UNITS_PER_SQUARE);
if (mCamera.height - CAMERA_COLL_HEIGHT_BELOW -
if (mCamera.height - RCL_CAMERA_COLL_HEIGHT_BELOW -
floorHeightFunction(camX,camY) < 2)
mVericalSpeed = PLAYER_JUMP_SPEED; // jump
}
if (shearDirection != 0)
mCamera.shear = clamp(mCamera.shear + shearDirection * 10,
mCamera.shear = RCL_clamp(mCamera.shear + shearDirection * 10,
-1 * mCamera.resolution.y, mCamera.resolution.y);
else
mCamera.shear /= 2;
@ -362,18 +365,18 @@ class Sprite
{
public:
const unsigned char *mImage;
Vector2D mPosition;
Unit mHeight;
Unit mPixelSize;
RCL_Vector2D mPosition;
RCL_Unit mHeight;
RCL_Unit mPixelSize;
Sprite(const unsigned char *image, int16_t squareX, int16_t squareY, Unit z,
Unit pixelSize):
Sprite(const unsigned char *image, int16_t squareX, int16_t squareY, RCL_Unit z,
RCL_Unit pixelSize):
mImage(image),
mPixelSize(pixelSize)
{
mPosition.x = squareX * UNITS_PER_SQUARE + UNITS_PER_SQUARE / 2;
mPosition.y = squareY * UNITS_PER_SQUARE + UNITS_PER_SQUARE / 2;
mHeight = z * UNITS_PER_SQUARE + UNITS_PER_SQUARE / 2;
mPosition.x = squareX * RCL_UNITS_PER_SQUARE + RCL_UNITS_PER_SQUARE / 2;
mPosition.y = squareY * RCL_UNITS_PER_SQUARE + RCL_UNITS_PER_SQUARE / 2;
mHeight = z * RCL_UNITS_PER_SQUARE + RCL_UNITS_PER_SQUARE / 2;
}
Sprite():

View file

@ -5,7 +5,7 @@
license: CC0 1.0
*/
#define PIXEL_FUNCTION pixelFunc
#define RCL_PIXEL_FUNCTION pixelFunc
/* ^ Before including raycastlib, this has to be set to the name of the
function that will render pixels. It allows super performance. */
@ -17,18 +17,19 @@
Pokitto::Core pokitto;
Camera camera; // Defines a view that will be rendered.
RCL_Camera camera; // Defines a view that will be rendered.
RCL_RayConstraints constraints;
// Function that for given square coordinates returns height of the floor.
Unit floorHeightAt(int16_t x, int16_t y)
RCL_Unit floorHeightAt(int16_t x, int16_t y)
{
return x < 0 || x >= 10 || y < 0 || y >= 10 ?
UNITS_PER_SQUARE * 2 : 0;
// ^ UNITS_PER_SQUARE is the length of one side of the game world square.
RCL_UNITS_PER_SQUARE * 2 : 0;
// ^ RCL_UNITS_PER_SQUARE is the length of one side of the game world square.
}
// Function which the library will call to draw indivifual pixels.
void pixelFunc(PixelInfo *pixel)
void pixelFunc(RCL_PixelInfo *pixel)
{
uint8_t color;
@ -45,14 +46,9 @@ void pixelFunc(PixelInfo *pixel)
void draw()
{
RayConstraints c;
c.maxHits = 1;
c.maxSteps = 20;
/* This triggers the rendering, which will keep calling pixelFunc to render
the camera view. */
renderSimple(camera,floorHeightAt,0,0,c);
RCL_renderSimple(camera,floorHeightAt,0,0,constraints);
}
int main()
@ -60,18 +56,22 @@ int main()
pokitto.begin();
pokitto.setFrameRate(60);
initCamera(&camera);
RCL_initCamera(&camera);
// Set the camera position to square [4;6].
camera.position.x = 4 * UNITS_PER_SQUARE;
camera.position.y = 6 * UNITS_PER_SQUARE;
camera.position.x = 4 * RCL_UNITS_PER_SQUARE;
camera.position.y = 6 * RCL_UNITS_PER_SQUARE;
camera.height = UNITS_PER_SQUARE;
camera.height = RCL_UNITS_PER_SQUARE;
// Set the camera resolution to Pokitto display resolution.
camera.resolution.x = 110;
camera.resolution.y = 88;
// This specifies the ray behavior.
constraints.maxHits = 1;
constraints.maxSteps = 20;
while (pokitto.isRunning())
{
if (pokitto.update())