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 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;
|
||||
|
||||
Unit zBuffer[SUBSAMPLED_WIDTH];
|
||||
|
||||
const unsigned char image[] =
|
||||
{ 32, 32 // width, height
|
||||
,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)
|
||||
{
|
||||
int32_t index = clamp(
|
||||
image[1] * ((image[1] * y) / UNITS_PER_SQUARE) +
|
||||
(image[0] * x) / UNITS_PER_SQUARE,
|
||||
0, image[0] * image[1] - 1);
|
||||
// TODO: optimize
|
||||
|
||||
x = wrap(x,UNITS_PER_SQUARE);
|
||||
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];
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
|
@ -350,10 +367,21 @@ void drawSprite(const unsigned char *sprite, int16_t x, int16_t y, int16_t size)
|
|||
|
||||
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);
|
||||
|
||||
if (c != 0xff)
|
||||
|
@ -414,6 +442,13 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class Sprite
|
||||
{
|
||||
public:
|
||||
Vector2D mPosition;
|
||||
Unit mHeight;
|
||||
};
|
||||
|
||||
class Character
|
||||
{
|
||||
public:
|
||||
|
@ -433,6 +468,7 @@ public:
|
|||
|
||||
Character player;
|
||||
Level level;
|
||||
Sprite sprites[SPRITES];
|
||||
|
||||
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)
|
||||
{
|
||||
if (pixel.position.y == MIDDLE_ROW)
|
||||
zBuffer[pixel.position.x] = pixel.depth;
|
||||
|
||||
uint8_t c;
|
||||
|
||||
Unit depth = pixel.depth - UNITS_PER_SQUARE;
|
||||
|
@ -489,25 +528,32 @@ void draw()
|
|||
|
||||
render(player.mCamera,heightFunc,pixelFunc,c);
|
||||
|
||||
Vector2D v;
|
||||
v.x = 5 * UNITS_PER_SQUARE;
|
||||
v.y = 7 * UNITS_PER_SQUARE;
|
||||
PixelInfo pos = mapToScreen(v,UNITS_PER_SQUARE / 4,player.mCamera);
|
||||
for (uint8_t i = 0; i < SPRITES; ++i)
|
||||
{
|
||||
PixelInfo pos = mapToScreen(sprites[i].mPosition,sprites[i].mHeight,player.mCamera);
|
||||
|
||||
if (pos.depth > 0)
|
||||
drawSprite(sprite,pos.position.x * SUBSAMPLE,pos.position.y,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);
|
||||
drawSprite(sprite,pos.position.x * SUBSAMPLE,pos.position.y,
|
||||
pos.depth,perspectiveScale(32,pos.depth));
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
for (uint8_t r = 0; r < 8; ++r)
|
||||
|
@ -541,26 +587,50 @@ int main()
|
|||
d.y = d.y > 0 ? step : -step;
|
||||
}
|
||||
|
||||
bool strafe = p.aBtn();
|
||||
|
||||
if (p.upBtn())
|
||||
{
|
||||
if (strafe)
|
||||
player.mCamera.height += step;
|
||||
else
|
||||
{
|
||||
player.mCamera.position.x += d.x;
|
||||
player.mCamera.position.y += d.y;
|
||||
}
|
||||
}
|
||||
else if (p.downBtn())
|
||||
{
|
||||
if (strafe)
|
||||
player.mCamera.height -= step;
|
||||
else
|
||||
{
|
||||
player.mCamera.position.x -= d.x;
|
||||
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())
|
||||
player.mCamera.direction += step2;
|
||||
addition = 1;
|
||||
else if (p.leftBtn())
|
||||
player.mCamera.direction -= step2;
|
||||
addition = -1;
|
||||
|
||||
if (p.aBtn())
|
||||
player.mCamera.height += step;
|
||||
else if (p.bBtn())
|
||||
player.mCamera.height -= step;
|
||||
if (strafe)
|
||||
{
|
||||
player.mCamera.position.x += addition * d.x;
|
||||
player.mCamera.position.y += addition * d.y;
|
||||
}
|
||||
else
|
||||
player.mCamera.direction += addition * step2;
|
||||
|
||||
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