|
@@ -16,6 +16,7 @@
|
|
|
#include <log.h>
|
|
|
#include <display.h>
|
|
|
#include <texture.h>
|
|
|
+#include <fpmath.h>
|
|
|
|
|
|
bool isRunning = false;
|
|
|
int previousFrameTime = 0;
|
|
@@ -24,6 +25,17 @@ double deltaTime = 0;
|
|
|
static double updateTime, renderTime, waitTime;
|
|
|
static int windowHeight;
|
|
|
static int windowWidth;
|
|
|
+static texture_t heightMap;
|
|
|
+static texture_t colourMap;
|
|
|
+static fp_num_t *yBuffer;
|
|
|
+
|
|
|
+static fp_num_t playerHeight = FP_SET_INT(70);
|
|
|
+static fp_num_t playerX = FP_SET_INT(444);
|
|
|
+static fp_num_t playerY = FP_SET_INT(299);
|
|
|
+static fp_num_t playerRot = FP_SET_INT(0);
|
|
|
+static fp_num_t cameraHorizon = FP_SET_INT(55);
|
|
|
+static fp_num_t scaleFactor = FP_SET_INT(90);
|
|
|
+static fp_num_t renderDistance = FP_SET_INT(300);
|
|
|
|
|
|
uint32_t getMicroSecTime()
|
|
|
{
|
|
@@ -35,6 +47,9 @@ uint32_t getMicroSecTime()
|
|
|
void processInput()
|
|
|
{
|
|
|
SDL_Event event;
|
|
|
+ double direction = 1;
|
|
|
+ double dx, dy;
|
|
|
+
|
|
|
while(SDL_PollEvent(&event))
|
|
|
{
|
|
|
switch (event.type)
|
|
@@ -48,13 +63,31 @@ void processInput()
|
|
|
{
|
|
|
case SDLK_ESCAPE: isRunning = false; break;
|
|
|
|
|
|
- case SDLK_LEFT: break;
|
|
|
- case SDLK_RIGHT: break;
|
|
|
- case SDLK_UP: break;
|
|
|
- case SDLK_DOWN: break;
|
|
|
+ case SDLK_LEFT: playerRot = playerRot + 90 * deltaTime; break;
|
|
|
+ case SDLK_RIGHT: playerRot = playerRot - 90 * deltaTime; break;
|
|
|
+
|
|
|
+ case SDLK_DOWN:
|
|
|
+ direction = -1;
|
|
|
+ /* fall-trough */
|
|
|
+
|
|
|
+ case SDLK_UP:
|
|
|
+ dx = cos(playerRot) * 75 * deltaTime;
|
|
|
+ dy = sin(playerRot) * 75 * deltaTime;
|
|
|
+ playerX += (dx * direction);
|
|
|
+ playerY += (dy * direction);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SDLK_PAGEUP: playerHeight = playerHeight + 50 * deltaTime; break;
|
|
|
+ case SDLK_PAGEDOWN: playerHeight = playerHeight - 50 * deltaTime; break;
|
|
|
|
|
|
- case SDLK_PAGEUP: break;
|
|
|
- case SDLK_PAGEDOWN: break;
|
|
|
+ case SDLK_HOME: cameraHorizon = cameraHorizon + 50 * deltaTime; break;
|
|
|
+ case SDLK_END: cameraHorizon = cameraHorizon - 50 * deltaTime; break;
|
|
|
+
|
|
|
+ case SDLK_KP_MULTIPLY: scaleFactor = scaleFactor + 30 * deltaTime; break;
|
|
|
+ case SDLK_KP_DIVIDE: scaleFactor = scaleFactor - 30 * deltaTime; break;
|
|
|
+
|
|
|
+ case SDLK_KP_PLUS: renderDistance = renderDistance + 30 * deltaTime; break;
|
|
|
+ case SDLK_KP_MINUS: renderDistance = renderDistance - 30 * deltaTime; break;
|
|
|
}
|
|
|
break;
|
|
|
|
|
@@ -66,13 +99,16 @@ void processInput()
|
|
|
|
|
|
void setup()
|
|
|
{
|
|
|
+ loadTextureDateFromPng(&heightMap, "assets/D1.png");
|
|
|
+ loadTextureDateFromPng(&colourMap, "assets/C1W.png");
|
|
|
+
|
|
|
+ yBuffer = (fp_num_t *)calloc(windowWidth, sizeof(fp_num_t));
|
|
|
|
|
|
isRunning = true;
|
|
|
}
|
|
|
|
|
|
void update()
|
|
|
{
|
|
|
- int i;
|
|
|
uint32_t timeToWait = FRAME_TARGET_TIME - (SDL_GetTicks() - previousFrameTime);
|
|
|
uint32_t ticks = getMicroSecTime();
|
|
|
|
|
@@ -91,10 +127,67 @@ void update()
|
|
|
updateTime = (updateTime + (getMicroSecTime() - ticks) / 1000.) / 2.0;
|
|
|
}
|
|
|
|
|
|
+void renderVoxels(tex2_t *p, fp_num_t angle, fp_num_t height, fp_num_t horizon, fp_num_t scaleHeight, fp_num_t renderDistance)
|
|
|
+{
|
|
|
+ fp_num_t angleSin = fpsin(angle);
|
|
|
+ fp_num_t angleCos = fpcos(angle);
|
|
|
+ fp_num_t dz = FP_SET_INT(1), z = FP_SET_INT(1);
|
|
|
+ int i;
|
|
|
+
|
|
|
+ for(i = 0; i < windowWidth; i++)
|
|
|
+ {
|
|
|
+ yBuffer[i] = FP_SET_INT(windowHeight);
|
|
|
+ }
|
|
|
+
|
|
|
+ while(z < renderDistance)
|
|
|
+ {
|
|
|
+ tex2_t pleft;
|
|
|
+ pleft.u = -FP_MUL(angleCos, z) - FP_MUL(angleSin, z) + p->u;
|
|
|
+ pleft.v = FP_MUL(angleSin, z) - FP_MUL(angleCos, z) + p->v;
|
|
|
+ tex2_t pright;
|
|
|
+ pright.u = FP_MUL(angleCos, z) - FP_MUL(angleSin, z) + p->u;
|
|
|
+ pright.v = -FP_MUL(angleSin, z) - FP_MUL(angleCos, z) + p->v;
|
|
|
+
|
|
|
+ fp_num_t dx = (pright.u - pleft.u);
|
|
|
+ dx = FP_DIV(dx, FP_SET_INT(windowWidth));
|
|
|
+ fp_num_t dy = (pright.v - pleft.v);
|
|
|
+ dy = FP_DIV(dy, FP_SET_INT(windowWidth));
|
|
|
+
|
|
|
+ for(i = 0; i < windowWidth; i++)
|
|
|
+ {
|
|
|
+ fp_num_t voxelHeight = height - FP_SET_INT(getTextureColour(&heightMap, &pleft));
|
|
|
+ voxelHeight = FP_DIV(voxelHeight, z);
|
|
|
+ voxelHeight = FP_MUL(voxelHeight, scaleHeight);
|
|
|
+
|
|
|
+ fp_num_t heightOnScreen = voxelHeight + horizon;
|
|
|
+ colour_t voxelColour = getTextureColour(&colourMap, &pleft);
|
|
|
+ if (heightOnScreen < yBuffer[i])
|
|
|
+ {
|
|
|
+ drawVLine(i, FP_GET_INT(yBuffer[i]), FP_GET_INT(heightOnScreen), voxelColour);
|
|
|
+ yBuffer[i] = heightOnScreen;
|
|
|
+ }
|
|
|
+ pleft.u += dx;
|
|
|
+ pleft.v += dy;
|
|
|
+ }
|
|
|
+
|
|
|
+ z += dz;
|
|
|
+#ifdef USE_FLOATING_POINT
|
|
|
+ dz += 0.01;
|
|
|
+#else
|
|
|
+ dz += (fp_num_t)(0.05 * FP_DIVISOR);
|
|
|
+#endif
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
void render()
|
|
|
{
|
|
|
uint32_t ticks = getMicroSecTime();
|
|
|
+ tex2_t origin = { .u = playerX, .v = playerY };
|
|
|
+
|
|
|
+ clearFrameBuffer(MAKE_RGB(0, 0, 0));
|
|
|
+ drawGrid(20, MAKE_RGB(27, 2, 27));
|
|
|
|
|
|
+ renderVoxels(& origin, playerRot, playerHeight, cameraHorizon, scaleFactor, renderDistance);
|
|
|
|
|
|
renderFrameBuffer();
|
|
|
|
|
@@ -104,20 +197,30 @@ void render()
|
|
|
drawText(5, 17, 0x11FF22, "Update time: %02.2f ms", updateTime);
|
|
|
drawText(5, 29, 0x11FF22, "Render time: %02.2f ms", renderTime);
|
|
|
drawText(5, 41, 0x11FF22, "FPS: %.1f | dT: %.3f", 1000 / (waitTime + updateTime + renderTime), deltaTime);
|
|
|
+#ifdef USE_FLOATING_POINT
|
|
|
+ drawText(5, 53, 0x11FF22, "P: (%.1f;%.1f) | PH: %.1f | CH: %.1f | SF: %.1f | RD: %.1f", playerX, playerY, playerHeight, cameraHorizon, scaleFactor, renderDistance);
|
|
|
+#else
|
|
|
+ drawText(5, 53, 0x11FF22, "P: (%d;%d) | PH: %d | CH: %d | SF: %d | RD: %d", FP_GET_INT(playerX),
|
|
|
+ FP_GET_INT(playerY),
|
|
|
+ FP_GET_INT(playerHeight),
|
|
|
+ FP_GET_INT(cameraHorizon),
|
|
|
+ FP_GET_INT(scaleFactor),
|
|
|
+ FP_GET_INT(renderDistance));
|
|
|
+#endif
|
|
|
|
|
|
displayWindowRender();
|
|
|
}
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
|
{
|
|
|
- int param_i, i;
|
|
|
+ int param_i;
|
|
|
bool fullScreen = false;
|
|
|
MAX_DEBUG_LEVEL = TLOG_DEBUG;
|
|
|
|
|
|
Log(TLOG_ALWAYS, NULL, "Starting Voxel Engine (version %s)!", VERSION);
|
|
|
|
|
|
- windowWidth = 320;
|
|
|
- windowHeight = 240;
|
|
|
+ windowWidth = 800;
|
|
|
+ windowHeight = 600;
|
|
|
|
|
|
for (param_i = 1 ; (param_i < argc) && (argv[param_i][0] == '-') ; param_i++)
|
|
|
{
|