diff --git a/game.cpp b/demo1.cpp similarity index 93% rename from game.cpp rename to demo1.cpp index 6dbdf26..8af5fdd 100644 --- a/game.cpp +++ b/demo1.cpp @@ -4,33 +4,16 @@ Don't forget to compile with -O3! author: Miloslav "drummyfish" Ciz - license: CC0 - */ + license: CC0 1.0 +*/ -//#define RAYCAST_TINY - -#include -#define VERTICAL_FOV UNITS_PER_SQUARE // for raycastlib -#include "raycastlib.h" -#include "Pokitto.h" - -#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) +#include "general.hpp" #define SPRITES 3 #define SPRITE_MAX_DISTANCE 5 * UNITS_PER_SQUARE -Pokitto::Core p; - -Unit zBuffer[SUBSAMPLED_WIDTH]; +#define SUBSAMPLE 2 +#define SUBSAMPLED_WIDTH (SCREEN_WIDTH / SUBSAMPLE) #define LEVEL_X_RES 29 #define LEVEL_Y_RES 21 @@ -580,88 +563,6 @@ const unsigned char sprite2[] = const unsigned char *textures[] = {texture1, texture2, texture3, texture4}; -inline uint8_t sampleImage(const unsigned char *image, Unit x, Unit y) -{ - // TODO: optimize - - x = wrap(x,UNITS_PER_SQUARE); - y = wrap(y,UNITS_PER_SQUARE); - - int32_t index = - image[1] * ((image[1] * x) / UNITS_PER_SQUARE) + (image[0] * y) / - UNITS_PER_SQUARE; - - return image[2 + index]; -} - -unsigned char translaprentColor; - -void drawSprite(const unsigned char *sprite, int16_t x, int16_t y, Unit depth, int16_t size) -{ - // TODO: optimize - - x -= size / 2; - y -= size / 2; - - Unit step = UNITS_PER_SQUARE / size; - - uint8_t c; - - 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) - { - int16_t xPos = x + i; - - if (zBuffer[xPos / SUBSAMPLE] <= depth) - continue; - - for (Unit j = max(-1 * y,0); j < jTo; ++j) - { - c = sampleImage(sprite,(i * UNITS_PER_SQUARE) / size,(j * UNITS_PER_SQUARE) / size); - - if (c != translaprentColor) - p.display.drawPixel(xPos,y + j,c); - } - } -} - -// r: 3 bits, g: 3 bits, b: 2 bits -inline uint8_t rgbToIndex(uint8_t r, uint8_t g, uint8_t b) -{ - return (r & 0b00000111) | ((g & 0b00000111) << 3) | ((b & 0b00000011) << 6); -} - -inline uint8_t addIntensity(uint8_t color, int intensity) -{ - uint8_t r = color & 0b00000111; - uint8_t g = (color & 0b00111000) >> 3; - uint8_t b = (color & 0b11000000) >> 6; - - if (intensity >= 0) - { - r += intensity; - r = r > 7 ? 7 : r; - - g += intensity; - g = g > 7 ? 7 : g; - - b += intensity / 2; - b = b > 3 ? 3 : b; - } - else - { - intensity *= -1; - r = (intensity > r) ? 0 : r - intensity; - g = (intensity > g) ? 0 : g - intensity; - intensity /= 2; - b = intensity > b ? 0 : b - intensity; - } - - return rgbToIndex(r,g,b); -} - class Sprite { public: @@ -751,10 +652,10 @@ inline void pixelFunc(PixelInfo pixel) rgbToIndex(intensity,intensity/2,0); - uint8_t *buf = p.display.screenbuffer; + uint8_t *buf = pokitto.display.screenbuffer; buf += pixel.position.x * SUBSAMPLE; - buf += pixel.position.y * p.display.width; + buf += pixel.position.y * pokitto.display.width; for (uint8_t i = 0; i < SUBSAMPLE - 1; ++i) *buf++ = c; @@ -798,21 +699,19 @@ void draw() previousDepth = 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); - +/* +pokitto.display.setColor(rgbToIndex(7,7,3)); +pokitto.display.setCursor(1,1); +pokitto.display.print(player.mCamera.position.x); +pokitto.display.print(" "); +pokitto.display.print(player.mCamera.position.y); +pokitto.display.print(" "); +pokitto.display.print(player.mCamera.direction); +*/ } int main() { - translaprentColor = rgbToIndex(7,0,0); - #define placeSprite(S,I,X,Y,Z,P)\ sprites[I].mImage = S;\ sprites[I].mPosition.x = X * UNITS_PER_SQUARE + UNITS_PER_SQUARE / 2;\ @@ -826,21 +725,21 @@ int main() #undef placeSprite - p.begin(); + pokitto.begin(); for (uint8_t r = 0; r < 8; ++r) for (uint8_t g = 0; g < 8; ++g) for (uint8_t b = 0; b < 4; ++b) - pal[rgbToIndex(r,g,b)] = p.display.RGBto565(36 * r, 36 * g, 85 * b); + pal[rgbToIndex(r,g,b)] = pokitto.display.RGBto565(36 * r, 36 * g, 85 * b); - p.display.load565Palette(&pal[0]); // load a palette the same way as any other palette in any other screen mode - p.display.persistence = 1; - p.setFrameRate(25); - p.display.setFont(fontTiny); + pokitto.display.load565Palette(&pal[0]); // load a palette the same way as any other palette in any other screen mode + pokitto.display.persistence = 1; + pokitto.setFrameRate(30); + pokitto.display.setFont(fontTiny); - while (p.isRunning()) + while (pokitto.isRunning()) { - if (p.update()) + if (pokitto.update()) { draw(); @@ -863,17 +762,17 @@ int main() d.y = d.y > 0 ? step : -step; } - bool strafe = p.aBtn(); - bool lookUpDown = p.cBtn(); + bool strafe = pokitto.aBtn(); + bool lookUpDown = pokitto.cBtn(); - if (p.upBtn()) + if (pokitto.upBtn()) { if (lookUpDown) player.mCamera.shear = min(player.mCamera.shear + 10,60); else moveOffset = d; } - else if (p.downBtn()) + else if (pokitto.downBtn()) { if (lookUpDown) player.mCamera.shear = max(player.mCamera.shear - 10,-60); @@ -891,9 +790,9 @@ int main() int addition = 0; - if (p.rightBtn()) + if (pokitto.rightBtn()) addition = 1; - else if (p.leftBtn()) + else if (pokitto.leftBtn()) addition = -1; if (strafe) @@ -917,14 +816,14 @@ int main() if (heightDiff == 0) player.mVericalSpeed = 0; // hit floor/ceiling - if (player.mVericalSpeed == 0 && p.bBtn()) + if (player.mVericalSpeed == 0 && pokitto.bBtn()) { int16_t camX = divRoundDown(player.mCamera.position.x,UNITS_PER_SQUARE); int16_t camY = divRoundDown(player.mCamera.position.y,UNITS_PER_SQUARE); if (player.mCamera.height - CAMERA_COLL_HEIGHT_BELOW - floorHeightAt(camX,camY) < 2) - player.mVericalSpeed = 400; // jump + player.mVericalSpeed = 500; // jump } player.mVericalSpeed -= 80; // gravity diff --git a/general.hpp b/general.hpp new file mode 100644 index 0000000..ae77c2f --- /dev/null +++ b/general.hpp @@ -0,0 +1,134 @@ +/** + General definitions for Pokitto raycasting demos. + + author: Miloslav "drummyfish" Ciz + license: CC0 1.0 +*/ + +#ifndef RAYCAST_DEMO_GENERAL_HPP +#define RAYCAST_DEMO_GENERAL_HPP + +#include "stdio.h" // for debugging raycastlibg + +#define VERTICAL_FOV UNITS_PER_SQUARE // redefine camera vertical FOV + +#include "raycastlib.h" +#include "Pokitto.h" + +Pokitto::Core pokitto; + +#define SCREEN_WIDTH 110 +#define SCREEN_HEIGHT 88 + +#define MIDDLE_ROW (SCREEN_HEIGHT / 2) +#define MIDDLE_COLUMN (SCREEN_WIDTH / 2) + +#ifndef SUBSAMPLE +#define SUBSAMPLE 2 +#endif + +#define SUBSAMPLED_WIDTH (SCREEN_WIDTH / SUBSAMPLE) + +#define TRANSPARENT_COLOR 0b00000111 + +Unit zBuffer[SUBSAMPLED_WIDTH]; ///< 1D z-buffer for visibility determination. + +/** + Gets (the index of) color by specified RGB components. + + @param r red, 3 bits (0 to 7) + @param g green, 3 bits (0 to 7) + @param b blue, 2 bits (0 to 3) + @return palette index of the color +*/ +inline uint8_t rgbToIndex(uint8_t r, uint8_t g, uint8_t b) +{ + return (r & 0b00000111) | ((g & 0b00000111) << 3) | ((b & 0b00000011) << 6); +} + +/** + Adds given intensity to a color. + + @param color input color + @param intensity intensity to add, 3 bit (0 to 7) + @return new color +*/ +inline uint8_t addIntensity(uint8_t color, int intensity) +{ + uint8_t r = color & 0b00000111; + uint8_t g = (color & 0b00111000) >> 3; + uint8_t b = (color & 0b11000000) >> 6; + + if (intensity >= 0) + { + r += intensity; + r = r > 7 ? 7 : r; + + g += intensity; + g = g > 7 ? 7 : g; + + b += intensity / 2; + b = b > 3 ? 3 : b; + } + else + { + intensity *= -1; + r = (intensity > r) ? 0 : r - intensity; + g = (intensity > g) ? 0 : g - intensity; + intensity /= 2; + b = intensity > b ? 0 : b - intensity; + } + + return rgbToIndex(r,g,b); +} + +/** + Samples an image by normalized coordinates - each coordinate is in range + 0 to UNITS_PER_SQUARE (from raycastlib). +*/ +inline uint8_t sampleImage(const unsigned char *image, Unit x, Unit y) +{ + // TODO: optimize + + x = wrap(x,UNITS_PER_SQUARE); + y = wrap(y,UNITS_PER_SQUARE); + + int32_t index = + image[1] * ((image[1] * x) / UNITS_PER_SQUARE) + (image[0] * y) / + UNITS_PER_SQUARE; + + return image[2 + index]; +} + +void inline drawSprite(const unsigned char *sprite, int16_t x, int16_t y, Unit depth, int16_t size) +{ + // TODO: optimize + + x -= size / 2; + y -= size / 2; + + Unit step = UNITS_PER_SQUARE / size; + + uint8_t c; + + 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) + { + int16_t xPos = x + i; + + if (zBuffer[xPos / SUBSAMPLE] <= depth) + continue; + + for (Unit j = max(-1 * y,0); j < jTo; ++j) + { + c = sampleImage(sprite,(i * UNITS_PER_SQUARE) / size,(j * UNITS_PER_SQUARE) / size); + + if (c != TRANSPARENT_COLOR) + pokitto.display.drawPixel(xPos,y + j,c); + } + } +} + +#endif