Rafraichissement raycast(), commentaires et ffloor en macro
This commit is contained in:
parent
8b825add63
commit
d69a379121
Binary file not shown.
|
@ -10,6 +10,9 @@
|
|||
typedef int32_t fixed_t;
|
||||
/* Standard arithmetic. */
|
||||
|
||||
//GCC complained when in inline functions
|
||||
#define ffloor(f) ((f) >> 16)
|
||||
|
||||
static inline fixed_t fmul(fixed_t left, fixed_t right)
|
||||
{
|
||||
/* Generally optimized by the compiler to use dmuls.l and xtrct */
|
||||
|
@ -41,11 +44,6 @@ static inline fixed_t fdec(fixed_t f)
|
|||
return f & 0xffff;
|
||||
}
|
||||
|
||||
static inline int ffloor(fixed_t f)
|
||||
{
|
||||
return f >> 16;
|
||||
}
|
||||
|
||||
static inline int fceil(fixed_t f)
|
||||
{
|
||||
return (f + 0xffff) >> 16;
|
||||
|
|
|
@ -103,14 +103,14 @@ void rc_pollevent(){
|
|||
|
||||
SDL_PumpEvents();
|
||||
}
|
||||
|
||||
//All the following is to redo
|
||||
uint8_t rc_keydown(enum keys key){
|
||||
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
//To reimplement
|
||||
|
||||
uint8_t rc_getkey(enum keys key) {
|
||||
dupdate();
|
||||
|
||||
|
|
30
src/moteur.c
30
src/moteur.c
|
@ -150,7 +150,7 @@ void move(Game *game, uint32_t keys) {
|
|||
if (player->dir.x < -0xFFFF) player->dir.x = -0xFFFF;
|
||||
if (player->dir.y < -0xFFFF) player->dir.y = -0xFFFF;
|
||||
}
|
||||
|
||||
/*
|
||||
void draw_background(int back_id){ //a refaire
|
||||
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ void logic(){
|
|||
|
||||
void draw_f(image_t *vram){ //a refaire
|
||||
|
||||
}
|
||||
}*/
|
||||
|
||||
inline void dstripe(image_t *stripe, image_t *vram, int x, int linePos, int lineHeight, int ymin, int ymax){
|
||||
uint16_t *strpdat = stripe->data;
|
||||
|
@ -177,24 +177,26 @@ inline void dstripe(image_t *stripe, image_t *vram, int x, int linePos, int line
|
|||
|
||||
if(ymax-ymin < lineHeight){
|
||||
texSample = ffloor((ymax-ymin) * texScale);
|
||||
texSampleY = ffloor((linePos - ymin) * texScale);
|
||||
texSampleY = ffloor((linePos - ymin) * texScale) < 0 ? 0:ffloor((linePos - ymin) * texScale);
|
||||
}
|
||||
if(keydown(KEY_F5)){
|
||||
dclear(C_WHITE);
|
||||
dprint(1,1,C_BLACK, "x : %d linePos : %d texSampleY : %d", x, linePos, texSampleY);
|
||||
dupdate(); getkey();
|
||||
}
|
||||
dclear(C_WHITE);
|
||||
dprint(1,1,C_BLACK, "x : %d linePos : %d lineHeight : %d ymin : %d ymax : %d", x, linePos, lineHeight, ymin, ymax);
|
||||
dupdate(); getkey();
|
||||
|
||||
if(lineHeight < tsize){
|
||||
cpixel = fix(texSampleY);
|
||||
for(cy = ymin; cy < ymax && cpixel < texSampleY+texSample; cy++){
|
||||
if(cy < 0 || cy >= viewport_h) break;
|
||||
//vramdat[screen_w*cy + x] = strpdat[ffloor(cpixel*2)];
|
||||
//vramdat[screen_w*cy + x+1] = strpdat[ffloor(cpixel*2)+1];
|
||||
vramdat[screen_w*cy + x] = strpdat[ffloor(cpixel*2)];
|
||||
vramdat[screen_w*cy + x+1] = strpdat[ffloor(cpixel*2)+1];
|
||||
cpixel += texScale;
|
||||
}
|
||||
} else {
|
||||
//This part doesn't seem to work
|
||||
for(cpixel = texSampleY; cpixel < texSampleY+texSample && cy < ymax; cpixel++){
|
||||
for(i = 0; i < ffloor(texScale); i++){
|
||||
//vramdat[screen_w*cy + x] = strpdat[ffloor(cpixel*2)];
|
||||
vramdat[screen_w*cy + x] = strpdat[ffloor(cpixel*2)];
|
||||
vramdat[screen_w*cy + x+1] = strpdat[ffloor(cpixel*2)+1];
|
||||
cy++;
|
||||
}
|
||||
|
@ -381,14 +383,14 @@ void draw_walls(Game *game, image_t *vram){
|
|||
|
||||
if(ymin >= ymax) continue;
|
||||
|
||||
gint_dvline(ymin, ymax, x, perpWallDist >> 16);
|
||||
//gint_dvline(ymin, ymax, x, perpWallDist >> 16);
|
||||
//gint_dvline(ymin, ymax, x+1, perpWallDist>>16);
|
||||
|
||||
//image_t tex_stripe;
|
||||
image_t tex_stripe;
|
||||
|
||||
//image_sub(tex_index[tex], texX, 0, 2, tsize, &tex_stripe);
|
||||
image_sub(tex_index[tex], texX, 0, 2, tsize, &tex_stripe);
|
||||
|
||||
//dstripe(&tex_stripe, vram, x, linePos, lineHeight, ymin, ymax);
|
||||
dstripe(&tex_stripe, vram, x, linePos, lineHeight, ymin, ymax);
|
||||
|
||||
//prof_leave(img_drw);
|
||||
//prof_enter(rayscat);
|
||||
|
|
|
@ -5,15 +5,6 @@
|
|||
#ifndef moteur_h
|
||||
#define moteur_h
|
||||
|
||||
static inline uint8_t has_collision(uint8_t tile){
|
||||
switch(tile){
|
||||
case 0: return 0;
|
||||
case 254: return 0;
|
||||
case 255: return 0;
|
||||
default: return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void draw_background(int back_id);
|
||||
void logic();
|
||||
void draw_f(image_t *vram);
|
||||
|
|
176
src/utils.c
176
src/utils.c
|
@ -129,141 +129,73 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// Function using the same raycast logic returning distance (and without the same comments)
|
||||
// Returns -1 if it didn't hit anything, -2 if incorrect type input
|
||||
// Type 0 = Mobs & Walls; Type 1 = Mobs; Type 2 = Walls
|
||||
// A refactoriser
|
||||
inline int sml_v3d(Vector3d *a){
|
||||
if(a->x < a->y){
|
||||
if(a->x < a->z) return 0;
|
||||
//if x<y && z<x then z<x<y
|
||||
return 2;
|
||||
}
|
||||
if(a->y < a->z){
|
||||
return 1;
|
||||
}
|
||||
//if y<x && z<y then z<y<x
|
||||
return 2;
|
||||
}
|
||||
|
||||
fixed_t raycast(ShooterMap *ShooterLevel, fixed_t posX, fixed_t posY, fixed_t rayDirX, fixed_t rayDirY, fixed_t dist, char type){
|
||||
// 3D raycast function based on Permadi's'
|
||||
// Returns -1 if it didn't hit anything within dist, else distance to hit
|
||||
|
||||
fixed_t sideDistX;
|
||||
fixed_t sideDistY;
|
||||
fixed_t deltaDistX;
|
||||
fixed_t deltaDistY;
|
||||
fixed_t wallDist;
|
||||
fixed_t raycast(ShooterMap *ShooterLevel, Vector3d pos, Vector3d rayDir, fixed_t dist){
|
||||
|
||||
char side;
|
||||
|
||||
int mapX;
|
||||
int mapY;
|
||||
int stepX;
|
||||
|
||||
int stepY;
|
||||
Vector3d sideDist;
|
||||
Vector3d deltaDist;
|
||||
Vector3d map;
|
||||
Vector3d step;
|
||||
int hit = 0;
|
||||
int *sideDistp = (int*)&sideDist;
|
||||
int *deltaDistp = (int*)&deltaDist;
|
||||
int *rayDirp = (int*)&deltaDist;
|
||||
int *mapp = (int*)↦
|
||||
int *stepp = (int*)&step;
|
||||
int *posp = (int*)&pos;
|
||||
|
||||
int side;
|
||||
|
||||
mapX = f2int(posX);
|
||||
mapY = f2int(posY);
|
||||
map.x = f2int(pos.x);
|
||||
map.y = f2int(pos.y);
|
||||
map.z = f2int(pos.z);
|
||||
|
||||
deltaDistX = abs(fdiv(0xFFFF, rayDirX));
|
||||
deltaDistY = abs(fdiv(0xFFFF, rayDirY));
|
||||
deltaDist.x = abs(fdiv(0xFFFF, rayDir.x));
|
||||
deltaDist.y = abs(fdiv(0xFFFF, rayDir.y));
|
||||
deltaDist.z = abs(fdiv(0xFFFF, rayDir.z));
|
||||
|
||||
if (rayDirX <= 0) {
|
||||
stepX = -1;
|
||||
sideDistX = fmul(posX - fix(mapX), deltaDistX);
|
||||
}
|
||||
else {
|
||||
stepX = 1;
|
||||
sideDistX = fmul( fix(mapX + 1) - posX, deltaDistX);
|
||||
}
|
||||
|
||||
if (rayDirY <= 0) {
|
||||
stepY = -1;
|
||||
sideDistY = fmul(posY - fix(mapY), deltaDistY);
|
||||
}
|
||||
else {
|
||||
stepY = 1;
|
||||
sideDistY = fmul( fix(mapY + 1) - posY, deltaDistY);
|
||||
for(int i = 0; i < 3; i++){
|
||||
if(rayDirp[i] < 0){
|
||||
stepp[i] = -1;
|
||||
sideDistp[i] = fmul(posp[i] - fix(mapp[i]), deltaDistp[i]);
|
||||
} else {
|
||||
stepp[i] = 1;
|
||||
sideDistp[i] = fmul(fix(mapp[i] + 1) - posp[i], deltaDistp[i]);
|
||||
}
|
||||
}
|
||||
//perform DDA
|
||||
switch(type){
|
||||
//Walls and mobs raycast
|
||||
case 0 : {
|
||||
while(1) {
|
||||
//Check if the ray is out of range/bounds
|
||||
if (sideDistX >= dist || sideDistY >= dist || mapX < 0 || mapY < 0) {
|
||||
hit = 0;
|
||||
break;
|
||||
}
|
||||
//Otherwise check if ray has hit a wall/mob
|
||||
else if (ShooterLevel->wall[mapX][mapY] != 0 || 0 != 0) {
|
||||
hit = 1;
|
||||
break;
|
||||
}
|
||||
if (sideDistX < sideDistY) {
|
||||
sideDistX += deltaDistX;
|
||||
mapX += stepX;
|
||||
side = 0;
|
||||
}
|
||||
else {
|
||||
sideDistY += deltaDistY;
|
||||
mapY += stepY;
|
||||
side = 1;
|
||||
}
|
||||
|
||||
}
|
||||
while(1) {
|
||||
//Check if the ray is out of range/bounds
|
||||
if (sideDist.x > dist || sideDist.y > dist || sideDist.z > dist|| map.x < 0 || map.y < 0 || map.z < 0) {
|
||||
hit = 0;
|
||||
break;
|
||||
}
|
||||
//Mobs only
|
||||
case 1 : {
|
||||
while(1) {
|
||||
//Check if the ray is out of range/bounds
|
||||
if (sideDistX >= dist || sideDistY >= dist || mapX < 0 || mapY < 0) {
|
||||
hit = 0;
|
||||
break;
|
||||
}
|
||||
//Otherwise check if ray has hit a wall
|
||||
else if (ShooterLevel->wall[mapX][mapY] != 0) {
|
||||
hit = 1;
|
||||
break;
|
||||
}
|
||||
if (sideDistX < sideDistY) {
|
||||
sideDistX += deltaDistX;
|
||||
mapX += stepX;
|
||||
side = 0;
|
||||
}
|
||||
else {
|
||||
sideDistY += deltaDistY;
|
||||
mapY += stepY;
|
||||
side = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
//Walls only
|
||||
case 2 : {
|
||||
while(1) {
|
||||
//Check if the ray is out of range/bounds
|
||||
if (sideDistX >= dist || sideDistY >= dist || mapX < 0 || mapY < 0) {
|
||||
hit = 0;
|
||||
break;
|
||||
}
|
||||
//Otherwise check if ray has hit a mob
|
||||
else if (0 != 0) {
|
||||
hit = 1;
|
||||
break;
|
||||
}
|
||||
if (sideDistX < sideDistY) {
|
||||
sideDistX += deltaDistX;
|
||||
mapX += stepX;
|
||||
side = 0;
|
||||
}
|
||||
else {
|
||||
sideDistY += deltaDistY;
|
||||
mapY += stepY;
|
||||
side = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default : {
|
||||
return -2;
|
||||
//Otherwise check if ray has hit a wall
|
||||
else if (has_collision(ShooterLevel->wall[map.z][map.x][map.y])) {
|
||||
hit = 1;
|
||||
break;
|
||||
}
|
||||
side = sml_v3d(&sideDist);
|
||||
sideDistp[side] += deltaDistp[side];
|
||||
mapp[side] += stepp[side];
|
||||
}
|
||||
|
||||
if (hit == 0) wallDist = -1;
|
||||
else if (side == 0) wallDist = (sideDistX - deltaDistX);
|
||||
else wallDist = (sideDistY - deltaDistY);
|
||||
|
||||
return wallDist;
|
||||
if (hit == 0) return -1;
|
||||
|
||||
return sideDistp[side] - deltaDistp[side];
|
||||
}
|
||||
|
|
11
src/utils.h
11
src/utils.h
|
@ -8,6 +8,15 @@
|
|||
#define sq(x) (x*x)
|
||||
#define fsq(x) (fmul(x,x))
|
||||
|
||||
static inline uint8_t has_collision(uint8_t tile){
|
||||
switch(tile){
|
||||
case 0: return 0;
|
||||
case 254: return 0;
|
||||
case 255: return 0;
|
||||
default: return 1;
|
||||
}
|
||||
}
|
||||
|
||||
//Provient de
|
||||
//https://stackoverflow.com/questions/31117497/fastest-integer-square-root-in-the-least-amount-of-instructions
|
||||
//, njuffa
|
||||
|
@ -93,7 +102,7 @@ static inline Vector2d fix2DNorml(Vector2d a) {
|
|||
|
||||
int cmpfunc(const void *, const void *);
|
||||
|
||||
fixed_t raycast(ShooterMap*, fixed_t, fixed_t, fixed_t, fixed_t, fixed_t, char);
|
||||
fixed_t raycast(ShooterMap *ShooterLevel, Vector3d pos, Vector3d rayDir, fixed_t dist);
|
||||
|
||||
#ifdef FXCG50
|
||||
|
||||
|
|
Loading…
Reference in New Issue