From ca954725aeda6bbd8641156fbe98117ca0a64234 Mon Sep 17 00:00:00 2001
From: salaaad2 <arthurdurant263@gmail.com>
Date: Mon, 30 May 2022 21:57:49 +0200
Subject: cool

---
 CMakeLists.txt     |   4 -
 src/level.c        | 467 +++++++++++++++++++++++++++--------------------------
 src/leveldefines.h |  35 ++++
 3 files changed, 270 insertions(+), 236 deletions(-)
 create mode 100644 src/leveldefines.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
index b12ff73..6a2edc8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -12,10 +12,6 @@ set (CMAKE_CXX_STANDARD 17)
 add_executable(${PROJECT_NAME}
     src/level.c)
 
-target_compile_options(${PROJECT_NAME}
-    PRIVATE "-O3"
-    PRIVATE "-march=native"
-)
 
 target_link_libraries(${PROJECT_NAME} ${SDL2_LIBRARIES})
 
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;
 }
diff --git a/src/leveldefines.h b/src/leveldefines.h
new file mode 100644
index 0000000..1d2506b
--- /dev/null
+++ b/src/leveldefines.h
@@ -0,0 +1,35 @@
+#pragma once
+
+// game
+# define TEXTURES 1  // whether to use textures for the level
+# define FOG 1
+
+// S3L
+# 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)
+
+// Screen
+#ifndef SCREEN_MEASURMENTS
+  # define SCREEN_WIDTH 1920
+  # define SCREEN_HEIGHT 1080
+#endif
+
+# define HALF_SCREEN_WIDTH SCREEN_WIDTH/2
+# define HALF_SCREEN_HEIGHT SCREEN_HEIGHT/2
-- 
cgit v1.2.3