Add z buffer
This commit is contained in:
parent
d24bf31d6e
commit
86d2334a52
1 changed files with 106 additions and 36 deletions
122
game.cpp
122
game.cpp
|
@ -15,8 +15,21 @@
|
||||||
|
|
||||||
#define SUBSAMPLE 2
|
#define SUBSAMPLE 2
|
||||||
|
|
||||||
|
#define SCREEN_WIDTH 110
|
||||||
|
#define SCREEN_HEIGHT 88
|
||||||
|
|
||||||
|
#define SUBSAMPLED_WIDTH (SCREEN_WIDTH / SUBSAMPLE)
|
||||||
|
#define SUBSAMPLED_HEIGHT (SCREEN_HEIGHT / SUBSAMPLE)
|
||||||
|
|
||||||
|
#define MIDDLE_ROW (SCREEN_HEIGHT / 2)
|
||||||
|
#define MIDDLE_COLUMN (SCREEN_WIDTH / 2)
|
||||||
|
|
||||||
|
#define SPRITES 6
|
||||||
|
|
||||||
Pokitto::Core p;
|
Pokitto::Core p;
|
||||||
|
|
||||||
|
Unit zBuffer[SUBSAMPLED_WIDTH];
|
||||||
|
|
||||||
const unsigned char image[] =
|
const unsigned char image[] =
|
||||||
{ 32, 32 // width, height
|
{ 32, 32 // width, height
|
||||||
,0x12,0x12,0x12,0x12,0x12,0x12,0x00,0x09,0x00,0x12,0x12,0x12,0x12,0x12
|
,0x12,0x12,0x12,0x12,0x12,0x12,0x00,0x09,0x00,0x12,0x12,0x12,0x12,0x12
|
||||||
|
@ -331,15 +344,19 @@ const unsigned char sprite[] =
|
||||||
|
|
||||||
inline uint8_t sampleImage(const unsigned char *image, Unit x, Unit y)
|
inline uint8_t sampleImage(const unsigned char *image, Unit x, Unit y)
|
||||||
{
|
{
|
||||||
int32_t index = clamp(
|
// TODO: optimize
|
||||||
image[1] * ((image[1] * y) / UNITS_PER_SQUARE) +
|
|
||||||
(image[0] * x) / UNITS_PER_SQUARE,
|
x = wrap(x,UNITS_PER_SQUARE);
|
||||||
0, image[0] * image[1] - 1);
|
y = wrap(y,UNITS_PER_SQUARE);
|
||||||
|
|
||||||
|
int32_t index =
|
||||||
|
image[1] * ((image[1] * y) / UNITS_PER_SQUARE) + (image[0] * x) /
|
||||||
|
UNITS_PER_SQUARE;
|
||||||
|
|
||||||
return image[2 + index];
|
return image[2 + index];
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawSprite(const unsigned char *sprite, int16_t x, int16_t y, int16_t size)
|
void drawSprite(const unsigned char *sprite, int16_t x, int16_t y, Unit depth, int16_t size)
|
||||||
{
|
{
|
||||||
// TODO: optimize
|
// TODO: optimize
|
||||||
|
|
||||||
|
@ -350,10 +367,21 @@ void drawSprite(const unsigned char *sprite, int16_t x, int16_t y, int16_t size)
|
||||||
|
|
||||||
uint8_t c;
|
uint8_t c;
|
||||||
|
|
||||||
for (Unit j = 0; j < size; ++j)
|
int16_t jTo = size - max(0,y + size - 88);
|
||||||
|
int16_t iTo = size - max(0,x + size - 110);
|
||||||
|
|
||||||
|
bool mask[SUBSAMPLED_WIDTH];
|
||||||
|
|
||||||
|
for (int i = 0; i < SUBSAMPLED_WIDTH; ++i)
|
||||||
|
mask[i] = zBuffer[i] > depth;
|
||||||
|
|
||||||
|
for (Unit j = max(-1 * y,0); j < jTo; ++j)
|
||||||
{
|
{
|
||||||
for (Unit i = 0; i < size; ++i)
|
for (Unit i = max(-1 * x,0); i < iTo; ++i)
|
||||||
{
|
{
|
||||||
|
if (!mask[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
c = sampleImage(sprite,(i * UNITS_PER_SQUARE) / size,(j * UNITS_PER_SQUARE) / size);
|
c = sampleImage(sprite,(i * UNITS_PER_SQUARE) / size,(j * UNITS_PER_SQUARE) / size);
|
||||||
|
|
||||||
if (c != 0xff)
|
if (c != 0xff)
|
||||||
|
@ -414,6 +442,13 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Sprite
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Vector2D mPosition;
|
||||||
|
Unit mHeight;
|
||||||
|
};
|
||||||
|
|
||||||
class Character
|
class Character
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -433,6 +468,7 @@ public:
|
||||||
|
|
||||||
Character player;
|
Character player;
|
||||||
Level level;
|
Level level;
|
||||||
|
Sprite sprites[SPRITES];
|
||||||
|
|
||||||
Unit heightFunc(int16_t x, int16_t y)
|
Unit heightFunc(int16_t x, int16_t y)
|
||||||
{
|
{
|
||||||
|
@ -441,6 +477,9 @@ Unit heightFunc(int16_t x, int16_t y)
|
||||||
|
|
||||||
inline void pixelFunc(PixelInfo pixel)
|
inline void pixelFunc(PixelInfo pixel)
|
||||||
{
|
{
|
||||||
|
if (pixel.position.y == MIDDLE_ROW)
|
||||||
|
zBuffer[pixel.position.x] = pixel.depth;
|
||||||
|
|
||||||
uint8_t c;
|
uint8_t c;
|
||||||
|
|
||||||
Unit depth = pixel.depth - UNITS_PER_SQUARE;
|
Unit depth = pixel.depth - UNITS_PER_SQUARE;
|
||||||
|
@ -489,25 +528,32 @@ void draw()
|
||||||
|
|
||||||
render(player.mCamera,heightFunc,pixelFunc,c);
|
render(player.mCamera,heightFunc,pixelFunc,c);
|
||||||
|
|
||||||
Vector2D v;
|
for (uint8_t i = 0; i < SPRITES; ++i)
|
||||||
v.x = 5 * UNITS_PER_SQUARE;
|
{
|
||||||
v.y = 7 * UNITS_PER_SQUARE;
|
PixelInfo pos = mapToScreen(sprites[i].mPosition,sprites[i].mHeight,player.mCamera);
|
||||||
PixelInfo pos = mapToScreen(v,UNITS_PER_SQUARE / 4,player.mCamera);
|
|
||||||
|
|
||||||
if (pos.depth > 0)
|
if (pos.depth > 0)
|
||||||
drawSprite(sprite,pos.position.x * SUBSAMPLE,pos.position.y,perspectiveScale(32,pos.depth));
|
drawSprite(sprite,pos.position.x * SUBSAMPLE,pos.position.y,
|
||||||
|
pos.depth,perspectiveScale(32,pos.depth));
|
||||||
p.display.setColor(rgbToIndex(7,7,3));
|
}
|
||||||
p.display.setCursor(1,1);
|
|
||||||
p.display.print(player.mCamera.position.x);
|
|
||||||
p.display.print(" ");
|
|
||||||
p.display.print(player.mCamera.position.y);
|
|
||||||
p.display.print(" ");
|
|
||||||
p.display.print(player.mCamera.direction);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
#define placeSprite(I,X,Y,Z)\
|
||||||
|
sprites[I].mPosition.x = X * UNITS_PER_SQUARE + UNITS_PER_SQUARE / 2;\
|
||||||
|
sprites[I].mPosition.y = Y * UNITS_PER_SQUARE + UNITS_PER_SQUARE / 2;\
|
||||||
|
sprites[I].mHeight = Z * UNITS_PER_SQUARE + UNITS_PER_SQUARE / 2;
|
||||||
|
|
||||||
|
placeSprite(0,5,7,0)
|
||||||
|
placeSprite(1,6,7,0)
|
||||||
|
placeSprite(2,5,8,0)
|
||||||
|
placeSprite(3,6,8,0)
|
||||||
|
placeSprite(4,-1,-2,1)
|
||||||
|
placeSprite(5,1,11,1)
|
||||||
|
|
||||||
|
#undef placeSprite
|
||||||
|
|
||||||
p.begin();
|
p.begin();
|
||||||
|
|
||||||
for (uint8_t r = 0; r < 8; ++r)
|
for (uint8_t r = 0; r < 8; ++r)
|
||||||
|
@ -541,26 +587,50 @@ int main()
|
||||||
d.y = d.y > 0 ? step : -step;
|
d.y = d.y > 0 ? step : -step;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool strafe = p.aBtn();
|
||||||
|
|
||||||
if (p.upBtn())
|
if (p.upBtn())
|
||||||
|
{
|
||||||
|
if (strafe)
|
||||||
|
player.mCamera.height += step;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
player.mCamera.position.x += d.x;
|
player.mCamera.position.x += d.x;
|
||||||
player.mCamera.position.y += d.y;
|
player.mCamera.position.y += d.y;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (p.downBtn())
|
else if (p.downBtn())
|
||||||
|
{
|
||||||
|
if (strafe)
|
||||||
|
player.mCamera.height -= step;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
player.mCamera.position.x -= d.x;
|
player.mCamera.position.x -= d.x;
|
||||||
player.mCamera.position.y -= d.y;
|
player.mCamera.position.y -= d.y;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strafe)
|
||||||
|
{
|
||||||
|
d = angleToDirection(player.mCamera.direction + UNITS_PER_SQUARE / 4);
|
||||||
|
d.x = (d.x * step) / UNITS_PER_SQUARE;
|
||||||
|
d.y = (d.y * step) / UNITS_PER_SQUARE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int addition = 0;
|
||||||
|
|
||||||
if (p.rightBtn())
|
if (p.rightBtn())
|
||||||
player.mCamera.direction += step2;
|
addition = 1;
|
||||||
else if (p.leftBtn())
|
else if (p.leftBtn())
|
||||||
player.mCamera.direction -= step2;
|
addition = -1;
|
||||||
|
|
||||||
if (p.aBtn())
|
if (strafe)
|
||||||
player.mCamera.height += step;
|
{
|
||||||
else if (p.bBtn())
|
player.mCamera.position.x += addition * d.x;
|
||||||
player.mCamera.height -= step;
|
player.mCamera.position.y += addition * d.y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
player.mCamera.direction += addition * step2;
|
||||||
|
|
||||||
player.mCamera.height =
|
player.mCamera.height =
|
||||||
max(heightFunc(player.mCamera.position.x / UNITS_PER_SQUARE,player.mCamera.position.y / UNITS_PER_SQUARE) + UNITS_PER_SQUARE / 2,player.mCamera.height);
|
max(heightFunc(player.mCamera.position.x / UNITS_PER_SQUARE,player.mCamera.position.y / UNITS_PER_SQUARE) + UNITS_PER_SQUARE / 2,player.mCamera.height);
|
||||||
|
|
Loading…
Reference in a new issue