diff options
Diffstat (limited to 'src/level.c')
-rw-r--r-- | src/level.c | 467 |
1 files changed, 235 insertions, 232 deletions
diff --git a/src/level.c b/src/level.c index 80df73f..b65dbe2 100644 --- a/src/level.c +++ b/src/level.c @@ -1,36 +1,18 @@ /* - Example program for small3dlib, showing a Quake-like level. + work in progress game made using small3dlib, based on Miloslav Ciz's + quake-like level - author: Miloslav Ciz - license: CC0 1.0 */ -#define TEXTURES 1 // whether to use textures for the level -#define FOG 1 +#include <SDL2/SDL_events.h> +#include <SDL2/SDL_mouse.h> +#include <SDL2/SDL_stdinc.h> #include <SDL2/SDL.h> #include <stdio.h> #include <time.h> -#define S3L_NEAR_CROSS_STRATEGY 3 - -#if TEXTURES - #define S3L_PERSPECTIVE_CORRECTION 2 -#else - #define S3L_PERSPECTIVE_CORRECTION 0 -#endif - -#define S3L_NEAR (S3L_FRACTIONS_PER_UNIT / 5) - -#define S3L_USE_WIDER_TYPES 0 -#define S3L_FLAT 0 -#define S3L_SORT 0 -#define S3L_Z_BUFFER 1 -#define S3L_MAX_TRIANGES_DRAWN 512 - -#define S3L_PIXEL_FUNCTION drawPixel - -#define S3L_MAX_PIXELS (1024 * 1024) +#include "leveldefines.h" #include "small3dlib.h" @@ -44,137 +26,151 @@ S3L_Vec4 teleportPoint; uint32_t pixels[S3L_MAX_PIXELS]; uint32_t frame = 0; -uint8_t *texture = 0; +uint8_t* texture = 0; uint32_t previousTriangle = 1000; S3L_Vec4 uv0, uv1, uv2; -void clearScreen() -{ - memset(pixels,255,S3L_MAX_PIXELS * sizeof(uint32_t)); -} +typedef struct mouse { + int x, y; + // In this case: the position where the mouse is held at + short trap; // flag for holding mouse at one place +} t_mouse; -static inline void setPixel(int x, int y, uint8_t red, uint8_t green, uint8_t blue) -{ - uint8_t *p = ((uint8_t *) pixels) + (y * S3L_resolutionX + x) * 4 + 1; +static t_mouse mouse; + +void clearScreen() { + memset(pixels, 255, S3L_MAX_PIXELS * sizeof(uint32_t)); +} - *p = blue; - ++p; - *p = green; - ++p; - *p = red; +static inline void setPixel(int x, + int y, + uint8_t red, + uint8_t green, + uint8_t blue) { + uint8_t* p = ((uint8_t*)pixels) + (y * S3L_resolutionX + x) * 4 + 1; + + *p = blue; + ++p; + *p = green; + ++p; + *p = red; } -void sampleTexture(S3L_Unit u, S3L_Unit v, uint8_t *r, uint8_t *g, uint8_t *b) -{ - u = (u * LEVEL_TEXTURE_WIDTH) / S3L_FRACTIONS_PER_UNIT; - v = (v * LEVEL_TEXTURE_HEIGHT) / S3L_FRACTIONS_PER_UNIT; +void sampleTexture(S3L_Unit u, S3L_Unit v, uint8_t* r, uint8_t* g, uint8_t* b) { + u = (u * LEVEL_TEXTURE_WIDTH) / S3L_FRACTIONS_PER_UNIT; + v = (v * LEVEL_TEXTURE_HEIGHT) / S3L_FRACTIONS_PER_UNIT; - u = S3L_wrap(u,LEVEL_TEXTURE_WIDTH); - v = S3L_wrap(v,LEVEL_TEXTURE_HEIGHT); + u = S3L_wrap(u, LEVEL_TEXTURE_WIDTH); + v = S3L_wrap(v, LEVEL_TEXTURE_HEIGHT); - const uint8_t *t = texture + (v * LEVEL_TEXTURE_WIDTH + u) * 3; + const uint8_t* t = texture + (v * LEVEL_TEXTURE_WIDTH + u) * 3; - *r = *t; - t++; - *g = *t; - t++; - *b = *t; + *r = *t; + t++; + *g = *t; + t++; + *b = *t; } -void drawTeleport(int16_t x, int16_t y, S3L_ScreenCoord size) -{ - int16_t halfSize = size / 2; +void drawTeleport(int16_t x, int16_t y, S3L_ScreenCoord size) { + int16_t halfSize = size / 2; - S3L_ScreenCoord x0 = S3L_max(0,x - halfSize); - S3L_ScreenCoord x1 = S3L_min(S3L_resolutionX,x + halfSize); - S3L_ScreenCoord y0 = S3L_max(0,y - halfSize); - S3L_ScreenCoord y1 = S3L_min(S3L_resolutionY,y + halfSize); + S3L_ScreenCoord x0 = S3L_max(0, x - halfSize); + S3L_ScreenCoord x1 = S3L_min(S3L_resolutionX, x + halfSize); + S3L_ScreenCoord y0 = S3L_max(0, y - halfSize); + S3L_ScreenCoord y1 = S3L_min(S3L_resolutionY, y + halfSize); - S3L_ScreenCoord row = y0 - (y - halfSize); + S3L_ScreenCoord row = y0 - (y - halfSize); - for (S3L_ScreenCoord j = y0; j < y1; ++j) - { - S3L_ScreenCoord i0, i1; + for (S3L_ScreenCoord j = y0; j < y1; ++j) { + S3L_ScreenCoord i0, i1; - if (row <= halfSize) - { - i0 = S3L_max(x0,x - row); - i1 = S3L_min(x1,x + row); - } - else - { - i0 = S3L_max(x0,x - size + row); - i1 = S3L_min(x1,x + size - row); - } + if (row <= halfSize) { + i0 = S3L_max(x0, x - row); + i1 = S3L_min(x1, x + row); + } else { + i0 = S3L_max(x0, x - size + row); + i1 = S3L_min(x1, x + size - row); + } - for (S3L_ScreenCoord i = i0; i < i1; ++i) - if (rand() % 8 == 0) - setPixel(i,j,255,0,0); + for (S3L_ScreenCoord i = i0; i < i1; ++i) + if (rand() % 8 == 0) + setPixel(i, j, 255, 0, 0); - row++; - } + row++; + } } -void drawPixel(S3L_PixelInfo *p) -{ - uint8_t r, g, b; +void drawPixel(S3L_PixelInfo* p) { + uint8_t r, g, b; #if TEXTURES - if (p->triangleID != previousTriangle) - { - uint8_t material = levelMaterials[p->triangleIndex]; - - switch (material) - { - case 0: - texture = level1Texture; - break; - - case 1: - texture = level2Texture; - break; - - case 2: - default: - texture = level3Texture; - break; + if (p->triangleID != previousTriangle) { + uint8_t material = levelMaterials[p->triangleIndex]; + + switch (material) { + case 0: + texture = level1Texture; + break; + + case 1: + texture = level2Texture; + break; + + case 2: + default: + texture = level3Texture; + break; + } + + S3L_getIndexedTriangleValues(p->triangleIndex, levelUVIndices, levelUVs, + 2, &uv0, &uv1, &uv2); + previousTriangle = p->triangleID; } - S3L_getIndexedTriangleValues(p->triangleIndex,levelUVIndices,levelUVs,2,&uv0,&uv1,&uv2); - previousTriangle = p->triangleID; - } + S3L_Unit uv[2]; - S3L_Unit uv[2]; + uv[0] = S3L_interpolateBarycentric(uv0.x, uv1.x, uv2.x, p->barycentric); + uv[1] = S3L_interpolateBarycentric(uv0.y, uv1.y, uv2.y, p->barycentric); - uv[0] = S3L_interpolateBarycentric(uv0.x,uv1.x,uv2.x,p->barycentric); - uv[1] = S3L_interpolateBarycentric(uv0.y,uv1.y,uv2.y,p->barycentric); - - sampleTexture(uv[0],uv[1],&r,&g,&b); + sampleTexture(uv[0], uv[1], &r, &g, &b); #else - switch (p->modelIndex) - { - case 0: r = 255; g = 0; b = 0; break; - case 1: r = 0; g = 255; b = 0; break; - case 2: - default: r = 0; g = 0; b = 255; break; - } + switch (p->modelIndex) { + case 0: + r = 255; + g = 0; + b = 0; + break; + case 1: + r = 0; + g = 255; + b = 0; + break; + case 2: + default: + r = 0; + g = 0; + b = 255; + break; + } #endif #if FOG - S3L_Unit fog = (p->depth * + S3L_Unit fog = (p->depth * #if TEXTURES - 8 + 8 #else - 16 + 16 #endif - ) / S3L_FRACTIONS_PER_UNIT; + ) / + S3L_FRACTIONS_PER_UNIT; - r = S3L_clamp(((S3L_Unit) r) - fog,0,255); - g = S3L_clamp(((S3L_Unit) g) - fog,0,255); - b = S3L_clamp(((S3L_Unit) b) - fog,0,255); + r = S3L_clamp(((S3L_Unit)r) - fog, 0, 255); + g = S3L_clamp(((S3L_Unit)g) - fog, 0, 255); + b = S3L_clamp(((S3L_Unit)b) - fog, 0, 255); #endif - setPixel(p->x,p->y,r,g,b); + setPixel(p->x, p->y, r, g, b); } S3L_Transform3D modelTransform; @@ -184,134 +180,141 @@ clock_t nextT; int fps = 0; -void draw() -{ - S3L_newFrame(); +void draw() { + S3L_newFrame(); - clearScreen(); + clearScreen(); - S3L_drawScene(scene); + S3L_drawScene(scene); - S3L_Vec4 screenPoint; + S3L_Vec4 screenPoint; - project3DPointToScreen(teleportPoint,scene.camera,&screenPoint); + project3DPointToScreen(teleportPoint, scene.camera, &screenPoint); - if (screenPoint.w > 0 && - screenPoint.x >= 0 && screenPoint.x < S3L_resolutionX && - screenPoint.y >= 0 && screenPoint.y < S3L_resolutionY && - screenPoint.z < S3L_zBufferRead(screenPoint.x,screenPoint.y)) - drawTeleport(screenPoint.x,screenPoint.y,screenPoint.w); + if (screenPoint.w > 0 && screenPoint.x >= 0 && + screenPoint.x < S3L_resolutionX && screenPoint.y >= 0 && + screenPoint.y < S3L_resolutionY && + screenPoint.z < S3L_zBufferRead(screenPoint.x, screenPoint.y)) + drawTeleport(screenPoint.x, screenPoint.y, screenPoint.w); - clock_t nowT = clock(); + clock_t nowT = clock(); - double timeDiff = ((double) (nowT - nextT)) / CLOCKS_PER_SEC; + double timeDiff = ((double)(nowT - nextT)) / CLOCKS_PER_SEC; - fps++; + fps++; - if (timeDiff >= 1.0) - { - nextT = nowT; - printf("FPS: %d\n",fps); + if (timeDiff >= 1.0) { + nextT = nowT; + printf("FPS: %d\n", fps); - printf("camera: "); - S3L_logTransform3D(scene.camera.transform); - fps = 0; - } + printf("camera: "); + S3L_logTransform3D(scene.camera.transform); + fps = 0; + } } -int main() -{ - S3L_resolutionX = 1000; - S3L_resolutionY = 600; - - SDL_Window *window = SDL_CreateWindow("level demo", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, S3L_resolutionX, S3L_resolutionY, SDL_WINDOW_SHOWN); - SDL_Renderer *renderer = SDL_CreateRenderer(window,-1,0); - SDL_Texture *texture = SDL_CreateTexture(renderer,SDL_PIXELFORMAT_RGBX8888, SDL_TEXTUREACCESS_STATIC, S3L_resolutionX, S3L_resolutionY); - SDL_Surface *screenSurface = SDL_GetWindowSurface(window); - SDL_Event event; - - teleportPoint.x = 6 * S3L_FRACTIONS_PER_UNIT; - teleportPoint.y = -3 * S3L_FRACTIONS_PER_UNIT; - teleportPoint.z = 3 * S3L_FRACTIONS_PER_UNIT / 2; - teleportPoint.w = S3L_FRACTIONS_PER_UNIT; - - nextT = clock(); - - levelModelInit(); - - S3L_sceneInit(&levelModel,1,&scene); - - int running = 1; - - while (running) // main loop - { - int newWidth = -1, newHeight = -1; - - draw(); - SDL_UpdateTexture(texture,NULL,pixels,S3L_resolutionX * sizeof(uint32_t)); - - while (SDL_PollEvent(&event)) - if (event.type == SDL_QUIT) - running = 0; - - S3L_Vec4 camF, camR; - - S3L_rotationToDirections(scene.camera.transform.rotation,20,&camF,&camR,0); - - const uint8_t *state = SDL_GetKeyboardState(NULL); - - if (state[SDL_SCANCODE_A]) - scene.camera.transform.rotation.y += 1; - else if (state[SDL_SCANCODE_D]) - scene.camera.transform.rotation.y -= 1; - else if (state[SDL_SCANCODE_W]) - scene.camera.transform.rotation.x += 1; - else if (state[SDL_SCANCODE_S]) - scene.camera.transform.rotation.x -= 1; - - if (state[SDL_SCANCODE_UP]) - S3L_vec3Add(&scene.camera.transform.translation,camF); - else if (state[SDL_SCANCODE_DOWN]) - S3L_vec3Sub(&scene.camera.transform.translation,camF); - else if (state[SDL_SCANCODE_LEFT]) - S3L_vec3Sub(&scene.camera.transform.translation,camR); - else if (state[SDL_SCANCODE_RIGHT]) - S3L_vec3Add(&scene.camera.transform.translation,camR); - - if (state[SDL_SCANCODE_K]) - newHeight = S3L_resolutionY + 4; - else if (state[SDL_SCANCODE_I]) - newHeight = S3L_resolutionY - 4; - else if (state[SDL_SCANCODE_J]) - newWidth = S3L_resolutionX - 4; - else if (state[SDL_SCANCODE_L]) - newWidth = S3L_resolutionX + 4; - - if ( - ( - (newWidth != -1 && newWidth > 0) || - (newHeight != -1 && newHeight > 0) - ) && - (newWidth * S3L_resolutionY <= S3L_MAX_PIXELS) && - (newHeight * S3L_resolutionX <= S3L_MAX_PIXELS)) - { - if (newWidth != -1) - S3L_resolutionX = newWidth; +int main() { + S3L_resolutionX = 1000; + S3L_resolutionY = 600; + SDL_WarpMouseGlobal(HALF_SCREEN_WIDTH, HALF_SCREEN_HEIGHT); - if (newHeight != -1) - S3L_resolutionY = newHeight; + SDL_Window* window = SDL_CreateWindow( + "level demo", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, + S3L_resolutionX, S3L_resolutionY, SDL_WINDOW_SHOWN); + SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 0); + SDL_Texture* texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBX8888, + SDL_TEXTUREACCESS_STATIC, + S3L_resolutionX, S3L_resolutionY); + SDL_Surface* screenSurface = SDL_GetWindowSurface(window); + SDL_Event event; + SDL_SetRelativeMouseMode(SDL_TRUE); - SDL_DestroyTexture(texture); - texture = SDL_CreateTexture(renderer,SDL_PIXELFORMAT_RGBX8888, SDL_TEXTUREACCESS_STATIC, S3L_resolutionX, S3L_resolutionY); - SDL_SetWindowSize(window,S3L_resolutionX,S3L_resolutionY); - } + teleportPoint.x = 6 * S3L_FRACTIONS_PER_UNIT; + teleportPoint.y = -3 * S3L_FRACTIONS_PER_UNIT; + teleportPoint.z = 3 * S3L_FRACTIONS_PER_UNIT / 2; + teleportPoint.w = S3L_FRACTIONS_PER_UNIT; + + nextT = clock(); + + levelModelInit(); - SDL_RenderClear(renderer); - SDL_RenderCopy(renderer,texture,NULL,NULL); - SDL_RenderPresent(renderer); + S3L_sceneInit(&levelModel, 1, &scene); - frame++; - } + int running = 1; + + while (running) // main loop + { + int newWidth = -1, newHeight = -1; + + draw(); + SDL_UpdateTexture(texture, NULL, pixels, + S3L_resolutionX * sizeof(uint32_t)); + + while (SDL_PollEvent(&event)) { + if (event.type == SDL_QUIT) { + running = 0; + } else if (event.type == SDL_MOUSEMOTION) { + /* Set x and y to the current mouse position */ + int x, y; + SDL_GetMouseState(&x, &y); + int xdiff = x - mouse.x; // Calculate difference in x + int ydiff = y - mouse.y; // Calculate difference in y + /* rotate camera relative to what it was before */ + scene.camera.transform.rotation.x -= ydiff; + scene.camera.transform.rotation.y -= xdiff; + mouse.x = x; + mouse.y = y; + } + } + + S3L_Vec4 camF, camR; + + S3L_rotationToDirections(scene.camera.transform.rotation, 20, &camF, + &camR, 0); + + const uint8_t* state = SDL_GetKeyboardState(NULL); + + if (state[SDL_SCANCODE_UP]) + S3L_vec3Add(&scene.camera.transform.translation, camF); + else if (state[SDL_SCANCODE_DOWN]) + S3L_vec3Sub(&scene.camera.transform.translation, camF); + else if (state[SDL_SCANCODE_LEFT]) + S3L_vec3Sub(&scene.camera.transform.translation, camR); + else if (state[SDL_SCANCODE_RIGHT]) + S3L_vec3Add(&scene.camera.transform.translation, camR); + + if (state[SDL_SCANCODE_K]) + newHeight = S3L_resolutionY + 4; + else if (state[SDL_SCANCODE_I]) + newHeight = S3L_resolutionY - 4; + else if (state[SDL_SCANCODE_J]) + newWidth = S3L_resolutionX - 4; + else if (state[SDL_SCANCODE_L]) + newWidth = S3L_resolutionX + 4; + + if (((newWidth != -1 && newWidth > 0) || + (newHeight != -1 && newHeight > 0)) && + (newWidth * S3L_resolutionY <= S3L_MAX_PIXELS) && + (newHeight * S3L_resolutionX <= S3L_MAX_PIXELS)) { + if (newWidth != -1) + S3L_resolutionX = newWidth; + + if (newHeight != -1) + S3L_resolutionY = newHeight; + + SDL_DestroyTexture(texture); + texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBX8888, + SDL_TEXTUREACCESS_STATIC, + S3L_resolutionX, S3L_resolutionY); + SDL_SetWindowSize(window, S3L_resolutionX, S3L_resolutionY); + } + + SDL_RenderClear(renderer); + SDL_RenderCopy(renderer, texture, NULL, NULL); + SDL_RenderPresent(renderer); + + frame++; + } - return 0; + return 0; } |