Tentatives d'occlusion et corrections

This commit is contained in:
attilavs2 2023-12-29 19:28:51 +01:00
parent 92a846aefd
commit 132b8a8250
5 changed files with 135 additions and 159 deletions

View File

@ -1,23 +1,21 @@
# Raycaster_G90
Raycaster texturé écrit en C pour G90+E/FX-CG50 avec gint et PC (Linux) avec SDL2
Touches :
- PC :
- Echap pour quitter
- Zqsd pour se déplacer
- PC :
- Echap pour quitter
- Zqsd pour se déplacer
- F pour intéragir
- G90+E/FC-CGxx :
- G90+E/FC-CGxx :
- F6 pour quitter
- Dpad pour se déplacer
- Shift pour intéragir
- Dpad pour se déplacer
- Shift pour intéragir
## Build
- Dépendances :
- Pour Linux (Port non finalisé) :
- une lib `sdl2` de dev
- [SDL_image](https://github.com/libsdl-org/SDL_image) (Version SDL2)
- [SDL_TTF](https://github.com/libsdl-org/SDL_ttf) (Version SDL2)
- `cmake`
- `build-essential` sur dérivés de Debian,
- `base-devel` sur Arch et dérivés
- les lib `sdl2`, `sdl2-image` et `sdl2-tty` de dev
- `cmake`
- `build-essential` sur dérivés de Debian,
- `base-devel` sur Arch et dérivés
- Pour G90+E/FX-CGxx :
- Le [fxsdk](https://gitea.planet-casio.com/Lephenixnoir/fxsdk)
- [Gint](https://gitea.planet-casio.com/Lephenixnoir/gint)
@ -36,13 +34,12 @@ Touches :
- Installez les dépendances
Ce qui pour Debian, Ubuntu et dérivés ressemblerait à
`sudo apt install git libsdl2-dev build-essential cmake`
et pour Arch et dérivés
`sudo apt install git libsdl2-dev libsdl2-image-dev libsdl-ttf2.0-dev build-essential cmake`
et pour Arch et dérivés (Pour SDL_image et SDL_TTF, allez voir dans leurs pages respectives)
`sudo pacman -S git sdl2 cmake base-devel`
Pour SDL_image et SDL_TTF, allez voir dans leurs pages respectives.
- Clonez le repo dans le dossier de votre choix avec
`git clone https://gitea.planet-casio.com/Fcalva/Raycaster_G90`
- Allez dans le dossier et configurez
- Allez dans le dossier et configurez le dossier de build
`cd Raycaster_G90`
`mkdir build`
`cd build`

Binary file not shown.

View File

@ -28,7 +28,7 @@
#define viewport_h 224
#define max_dist fix(16) //en tuiles
#define max_sprite_dist 0x140000 //en tuiles << 16, 20
#define max_sprite_dist fix(20) //en tuiles << 16, 20
#define max_sprite_search 24
#define max_sprite_display 16

View File

@ -1,52 +1,52 @@
// Tout les #include extérieurs au projet
#ifndef includes__h
#define includes__h
#include "config.h"
#include "fixed.h"
#include <stdlib.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
//SDL2 is defined by CMake
#ifdef FXCG50
#ifdef debug
#include <gint/kmalloc.h>
#endif
#include <gint/display.h>
#include <gint/keyboard.h>
#include <gint/image.h>
#include <libprof.h>
#endif
#ifdef SDL2
#include <unistd.h>
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include "sdl_image.h"
#endif
#ifdef USB
#include <gint/usb.h>
#include <gint/usb-ff-bulk.h>
#endif
#endif //includes__h
// Tout les #include extérieurs au projet
#ifndef includes__h
#define includes__h
#include "config.h"
#include "fixed.h"
#include <stdlib.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
//SDL2 is defined by CMake
#ifdef FXCG50
#ifdef debug
#include <gint/kmalloc.h>
#endif
#include <gint/display.h>
#include <gint/keyboard.h>
#include <gint/image.h>
#include <libprof.h>
#endif
#ifdef SDL2
#include <unistd.h>
#include <SDL.h>
#include <SDL_image.h>
#include <SDL-ttf2.h>
#include "sdl_image.h"
#endif
#ifdef USB
#include <gint/usb.h>
#include <gint/usb-ff-bulk.h>
#endif
#endif //includes__h

View File

@ -33,14 +33,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//
int armax(int *a){
int i, ra = -0xFFFFFFFF;
for(i = 0; i < map_d; i++){
if(a[i]>ra) ra = a[i];
}
return ra;
}
image_t *tex_index[tindex_size];
int8_t on_solid_ground(ShooterMap *ShooterLevel, Vector3d pos) {
@ -176,7 +168,7 @@ void draw_walls(Game *game, image_t *vram){
fixed_t deltaDistY;
fixed_t perpWallDist;
fixed_t texSize;
uint8_t walls[map_d + 1];
uint8_t hwall[map_d];
int x;
int i;
int mapX;
@ -207,10 +199,6 @@ void draw_walls(Game *game, image_t *vram){
for(x = 0; x < viewport_w; x++) {
prof_enter(rayscat);
int occl1 = viewport_h / 2;
int occl2 = viewport_h / 2;
int toccl1[map_d], toccl2[map_d];
debug_func();
//calculate ray position and direction
@ -259,7 +247,7 @@ void draw_walls(Game *game, image_t *vram){
sideDistY = fmul( fix(mapY + 1) - player->pos.y, deltaDistY);
}
walls[0] = 0; walls[1] = 0; walls[2] = 0;
hwall[0] = 0; hwall[1] = 0; hwall[2] = 0;
//perform DDA
while(1) {
@ -269,103 +257,94 @@ void draw_walls(Game *game, image_t *vram){
}
//Otherwise check if ray has hit walls, and draw them
else if(shooterLevel->wall[0][mapX][mapY] != 255){
for(i = 0; i <3; i++){
if(has_collision(shooterLevel->wall[i][mapX][mapY])) {
walls[i] = 1;
walls[map_d] = 1;
}
}
if (walls[map_d] > 0) {
prof_leave(rayscat);
prof_enter(img_drw);
prof_leave(rayscat);
prof_enter(img_drw);
//Calculate distance projected on camera direction. This is the shortest distance from the point where the wall is
//hit to the camera plane. Euclidean to center camera point would give fisheye effect!
//This can be computed as (mapX - posX + (1 - stepX) / 2) / rayDirX for side == 0, or same formula with Y
//for size == 1, but can be simplified to the code below thanks to how sideDist and deltaDist are computed:
//because they were left scaled to |rayDir|. sideDist is the entire length of the ray above after the multiple
//steps, but we subtract deltaDist once because one step more into the wall was taken above.
//Calculate distance projected on camera direction. This is the shortest distance from the point where the wall is
//hit to the camera plane. Euclidean to center camera point would give fisheye effect!
//This can be computed as (mapX - posX + (1 - stepX) / 2) / rayDirX for side == 0, or same formula with Y
//for size == 1, but can be simplified to the code below thanks to how sideDist and deltaDist are computed:
//because they were left scaled to |rayDir|. sideDist is the entire length of the ray above after the multiple
//steps, but we subtract deltaDist once because one step more into the wall was taken above.
if (side == 0) perpWallDist = (sideDistX - deltaDistX);
else perpWallDist = (sideDistY - deltaDistY);
if (side == 0) perpWallDist = (sideDistX - deltaDistX);
else perpWallDist = (sideDistY - deltaDistY);
//texturing calculation
//calculate value of wallX
fixed_t wallX; //where exactly the wall was hit
if (side == 0) wallX = player->pos.y + fmul(perpWallDist, rayDirY);
else wallX = player->pos.x + fmul(perpWallDist, rayDirX);
wallX -= fix(ffloor(wallX));
//texturing calculation
//calculate value of wallX
fixed_t wallX; //where exactly the wall was hit
if (side == 0) wallX = player->pos.y + fmul(perpWallDist, rayDirY);
else wallX = player->pos.x + fmul(perpWallDist, rayDirX);
wallX -= fix(ffloor(wallX));
//x coordinate on the texture
texX = fround(wallX * tsize);
texX = fround(wallX * tsize);
if(side == 0 && rayDirX > 0) texX = tsize - texX - 1;
if(side == 1 && rayDirY < 0) texX = tsize - texX - 1;
if(side == 0 && rayDirX > 0) texX = tsize - texX - 1;
if(side == 1 && rayDirY < 0) texX = tsize - texX - 1;
perpWallDist = perpWallDist < 1 ? 1 : perpWallDist;
perpWallDist = perpWallDist < 1 ? 1 : perpWallDist;
lineHeight = fround(fdiv(fix(viewport_h), perpWallDist)); //Taille en px de la ligne
if (lineHeight < 1) lineHeight = 1;
if (lineHeight > viewport_h-1) lineHeight = viewport_h-1;
lineHeight = fround(fdiv(fix(viewport_h), perpWallDist)); //Taille en px de la ligne
if (lineHeight < 1) lineHeight = 1;
if (lineHeight > viewport_h-1) lineHeight = viewport_h-1;
int glinePos = viewport_h/2 - lineHeight/2;
int glinePos = viewport_h/2 - lineHeight/2;
fixed_t texSize = fix(lineHeight) / tsize; //taille proportionelle de la ligne a la tex
fixed_t texSize = fix(lineHeight) / tsize; //taille proportionelle de la ligne a la tex
for(i = 0; i < map_d; i++){
if(walls[i] < 1) continue;
for(i = 0; i < map_d; i++) {
//Rough clipping based on layer
if(hwall[i]==1) continue;
int zOffset = player->pos.z - fix(i);
if(!has_collision(shooterLevel->wall[i][mapX][mapY])) continue;
// The reasoning here is to offset the wall slice vertically from the center of the screen,
// depending on the offset between the wall and the player
int linePos = glinePos + fround(zOffset*lineHeight);
hwall[i] = 1;
if(linePos < occl1) toccl1[i] = linePos;
else continue;
if(linePos+lineHeight > occl2) toccl2[i] = linePos;
else continue;
int zOffset = player->pos.z - fix(i);
if(linePos >= viewport_h) continue;
// The reasoning here is to offset the wall slice vertically from the center of the screen,
// depending on the offset between the wall and the player
int linePos = glinePos + fround(zOffset*lineHeight);
if(linePos+lineHeight < 1) continue;
uint8_t tex = 0; //ShooterLevel->wall[mapX][mapY][i];
if(linePos >= viewport_h) continue;
if (linePos < 1) {
texSampleY = texSize*abs(linePos);
texSample = tsize - texSampleY;
linePos = 2;
}
else if (linePos > viewport_h) {
texSampleY = texSize*abs(linePos);
texSample = tsize - texSampleY;
linePos = viewport_h;
}
else {
texSampleY = 0;
}
if(linePos+lineHeight < 1) continue;
//image_sub(tex_index[tex], texX, texSampleY, 1, texSample, tex_stripe);
uint8_t tex = 0; //ShooterLevel->wall[mapX][mapY][i];
//image_scale(tex_stripe, 0xFFFF, texSize, &temp);
//image_linear(tex_stripe, image_at(vram, x, linePos), &temp);
uint16_t color;
switch(i){
case 0 : {color = C_PINK; break;}
case 1 : {color = C_BLACK; break;}
case 2 : {color = C_BSKY; break;}
}
gint_dvline(linePos, linePos+1, x, color);
//prof_leave(img_drw);
//prof_enter(rayscat);
if (linePos < 1) {
texSampleY = texSize*abs(linePos);
texSample = tsize - texSampleY;
linePos = 2;
}
occl1 = armax(&toccl1);
occl2 = armax(&toccl2);
else if (linePos > viewport_h) {
texSampleY = texSize*abs(linePos);
texSample = tsize - texSampleY;
linePos = viewport_h;
}
else {
texSampleY = 0;
}
//image_sub(tex_index[tex], texX, texSampleY, 1, texSample, tex_stripe);
//image_scale(tex_stripe, 0xFFFF, texSize, &temp);
//image_linear(tex_stripe, image_at(vram, x, linePos), &temp);
uint16_t color;
switch(i){
case 0 : {color = C_PINK; break;}
case 1 : {color = C_BLACK; break;}
case 2 : {color = C_BSKY; break;}
}
gint_dvline(linePos, linePos+lineHeight, x, color);
//prof_leave(img_drw);
//prof_enter(rayscat);
}
}
//jump to next map square, either in x-direction, or in y-direction