Compare commits

...

19 Commits

21 changed files with 772 additions and 865 deletions
Split View
  1. BIN
      1v13D.g1a
  2. +582
    -709
      build-fx/map
  3. BIN
      build-fx/src/1v13D.bin
  4. BIN
      build-fx/src/1v13D.elf
  5. BIN
      build-fx/src/FxEngine/FxEngine.o
  6. BIN
      build-fx/src/FxEngine/coord.o
  7. BIN
      build-fx/src/FxEngine/face.o
  8. BIN
      build-fx/src/FxEngine/texture.o
  9. BIN
      build-fx/src/FxEngine/zbuffer.o
  10. +4
    -1
      build-fx/src/controls.d
  11. BIN
      build-fx/src/controls.o
  12. +4
    -4
      build-fx/src/main.d
  13. +10
    -10
      src/FxEngine/FxEngine.c
  14. +5
    -4
      src/FxEngine/FxEngine.h
  15. +16
    -16
      src/FxEngine/coord.c
  16. +4
    -4
      src/FxEngine/coord.h
  17. +61
    -42
      src/FxEngine/face.c
  18. +4
    -5
      src/FxEngine/face.h
  19. +50
    -44
      src/FxEngine/zbuffer.c
  20. +8
    -2
      src/FxEngine/zbuffer.h
  21. +24
    -24
      src/main.c

BIN
1v13D.g1a View File


+ 582
- 709
build-fx/map
File diff suppressed because it is too large
View File


BIN
build-fx/src/1v13D.bin View File


BIN
build-fx/src/1v13D.elf View File


BIN
build-fx/src/FxEngine/FxEngine.o View File


BIN
build-fx/src/FxEngine/coord.o View File


BIN
build-fx/src/FxEngine/face.o View File


BIN
build-fx/src/FxEngine/texture.o View File


BIN
build-fx/src/FxEngine/zbuffer.o View File


+ 4
- 1
build-fx/src/controls.d View File

@@ -1,5 +1,6 @@
build-fx/src/controls.o: src/controls.c src/controls.h \
src/FxEngine/FxEngine.h src/FxEngine/coord.h src/FxEngine/zbuffer.h
src/FxEngine/FxEngine.h src/FxEngine/coord.h src/FxEngine/FxEngine.h \
src/FxEngine/zbuffer.h

src/controls.h:

@@ -7,4 +8,6 @@ src/FxEngine/FxEngine.h:

src/FxEngine/coord.h:

src/FxEngine/FxEngine.h:

src/FxEngine/zbuffer.h:

BIN
build-fx/src/controls.o View File


+ 4
- 4
build-fx/src/main.d View File

@@ -1,15 +1,15 @@
build-fx/src/main.o: src/main.c src/FxEngine/FxEngine.h \
src/FxEngine/coord.h src/FxEngine/zbuffer.h src/FxEngine/face.h \
src/FxEngine/FxEngine.h src/controls.h
src/FxEngine/coord.h src/FxEngine/FxEngine.h src/FxEngine/zbuffer.h \
src/FxEngine/face.h src/controls.h

src/FxEngine/FxEngine.h:

src/FxEngine/coord.h:

src/FxEngine/FxEngine.h:

src/FxEngine/zbuffer.h:

src/FxEngine/face.h:

src/FxEngine/FxEngine.h:

src/controls.h:

+ 10
- 10
src/FxEngine/FxEngine.c View File

@@ -41,18 +41,18 @@ static void FE_move()
}
if (event.key==KEY_5)
{
py += FE_cos(FE_dh + pi);
px += FE_sin(FE_dh + pi);
py += FE_cos(FE_dh + FE_PI);
px += FE_sin(FE_dh + FE_PI);
}
if (event.key==KEY_4)
{
py += FE_cos(FE_dh - pi_sur2);
px += FE_sin(FE_dh - pi_sur2);
py += FE_cos(FE_dh - FE_PI_SUR_2);
px += FE_sin(FE_dh - FE_PI_SUR_2);
}
if (event.key==KEY_6)
{
py += FE_cos(FE_dh + pi_sur2);
px += FE_sin(FE_dh + pi_sur2);
py += FE_cos(FE_dh + FE_PI_SUR_2);
px += FE_sin(FE_dh + FE_PI_SUR_2);
}

@@ -99,17 +99,17 @@ void FE_new_frame()

#define MICROSECOND 1000000
unsigned uint32_t FE_get_fps_current()
uint32_t FE_get_fps_current()
{
return MICROSECOND / frame_interval;
}

unsigned uint32_t FE_get_fps_min()
uint32_t FE_get_fps_min()
{
return MICROSECOND / frame_interval_max;
}

unsigned uint32_t FE_get_fps_max()
uint32_t FE_get_fps_max()
{
return MICROSECOND / frame_interval_min;
}
@@ -121,4 +121,4 @@ char* FE_get_fps_history()
{
sprintf(fps_history, "%d/%d/%d", FE_get_fps_min(), FE_get_fps_current(), FE_get_fps_max());
return fps_history;
}
}

+ 5
- 4
src/FxEngine/FxEngine.h View File

@@ -1,6 +1,7 @@
#ifndef FENG_H
#define FENG_H

#include <stdint.h>
#include "coord.h"
#include "zbuffer.h"
#include <libprof.h>
@@ -36,15 +37,15 @@ void FE_new_frame(void); // calls move function

/* FE_get_fps_current():
obtient le nombre d'Images Par Seconde (IPS) calculé à partir du dernier cycle */
unsigned int FE_get_fps_current(void);
uint32_t FE_get_fps_current(void);

/* FE_get_fps_min():
obtient le nombre d'images par seconde le plus bas ayant existé depuis le démarrage du moteur 3d */
unsigned int FE_get_fps_min(void);
uint32_t FE_get_fps_min(void);

/* FE_get_fps_max():
obtient le nombre d'images par seconde le plus haut ayant existé depuis le démarrage du moteur 3d */
unsigned int FE_get_fps_max(void);
uint32_t FE_get_fps_max(void);

/* FE_get_fps_history():
renvoie, dans une version compactée, les nombres minimum, actuel et maximum d'images par seconde
@@ -59,4 +60,4 @@ unsigned int FE_get_fps_max(void);
char* FE_get_fps_history(void);


#endif
#endif

+ 16
- 16
src/FxEngine/coord.c View File

@@ -19,10 +19,10 @@ static double reducted_cos(const double a)
// return a with -pi<=a<pi
double FE_modulo_2pi(double a)
{
while (a<=-pi)
a += pi2;
while (a>pi)
a -= pi2;
while (a<=-FE_PI)
a += FE_2_PI;
while (a>FE_PI)
a -= FE_2_PI;
return a;
}

@@ -31,7 +31,7 @@ static double cos_recursive(double angle)
if (angle<0)
return cos_recursive(-angle);
if (angle>=FE_PI_SUR_2)
return -reducted_cos(angle - pi);
return -reducted_cos(angle - FE_PI);
return reducted_cos(angle); // OK
}

@@ -43,7 +43,7 @@ double FE_cos(double angle)

double FE_sin(double angle)
{
return FE_cos(angle - pi_sur2);
return FE_cos(angle - FE_PI_SUR_2);
}


@@ -69,21 +69,21 @@ void FE_calc(FE_point* point)

//point->translated.x*=10;
//point->translated.y*=10;
point->rotated.x*=64;
point->rotated.y*=64;
point->translated.z=point->rotated.z;
point->rotated.x *= 64;
point->rotated.y *= 64;
point->translated.z = point->rotated.z;
if (point->translated.z>0)
{
point->translated.x=point->rotated.x/point->translated.z;
point->translated.y=point->rotated.y/point->translated.z;
point->translated.x = point->rotated.x / point->translated.z;
point->translated.y = point->rotated.y / point->translated.z;
}
else
{
point->translated.x=point->rotated.x*10000*sgn(point->translated.z);
point->translated.y=point->rotated.y*10000*sgn(point->translated.z);
point->translated.x = point->rotated.x * 10000 * sgn(point->translated.z);
point->translated.y = point->rotated.y * 10000 * sgn(point->translated.z);
}
(point->translated.x*1000)/point->translated.z;
(point->translated.y*1000)/point->translated.z;
// (point->translated.x*1000)/point->translated.z;
// (point->translated.y*1000)/point->translated.z;

point->translated.x+=63;
point->translated.y+=31;
@@ -111,4 +111,4 @@ void FE_set_matrice(void)
matrice[2][1]=AD*F+B*E;
matrice[2][2]=A*C;

}
}

+ 4
- 4
src/FxEngine/coord.h View File

@@ -1,13 +1,11 @@
#ifndef FE_COORD_H
#define FE_COORD_H

#include "FxEngine.h"

/* FE_position:
notion de point dans l'espace simple */
typedef struct FE_position FE_position;
struct FE_position
{int32_t x,y,z;};
{int x,y,z;};

/* FE_point:
notion de point dans l'espace destiné à etre utilisé dans l'affichage
@@ -18,6 +16,8 @@ typedef struct FE_point FE_point;
struct FE_point
{FE_position real,translated,rotated};

#include "FxEngine.h"

/* FE_calc():
applique la matrice de rotation sur les coordonnées d'un point
@@ -58,4 +58,4 @@ double FE_cos(double angle);
double FE_sin(const double angle);


#endif
#endif

+ 61
- 42
src/FxEngine/face.c View File

@@ -1,25 +1,22 @@
#include "face.h"
#include "texture.h"
#include "zbuffer.h"
#include <stdbool.h>
#include <gint/display.h>

#define min(x,y) (x<y?x:y)
#define max(x,y) (x>y?x:y)
#define abs(x) (x>0?x:-x)

#include <stdbool.h>
static bool sens_horaire(FE_face const * face)
{
int area = 0;

area+=face->s1->translated.x*face->s2->translated.y;
area-=face->s2->translated.x*face->s1->translated.y;
area += face->s1->translated.x * face->s2->translated.y;
area -= face->s2->translated.x * face->s1->translated.y;

area+=face->s2->translated.x*face->s3->translated.y;
area-=face->s3->translated.x*face->s2->translated.y;
area += face->s2->translated.x * face->s3->translated.y;
area -= face->s3->translated.x * face->s2->translated.y;

area+=face->s3->translated.x*face->s1->translated.y;
area-=face->s1->translated.x*face->s3->translated.y;
area += face->s3->translated.x * face->s1->translated.y;
area -= face->s1->translated.x * face->s3->translated.y;

return (area < 0);
}
@@ -32,6 +29,7 @@ struct line
int dx,dy,dz;
bool no_line; // si les deux points sont confondus
};

static void set_line(line* segment,FE_point const * s1, FE_point const * s2)
{
segment->x=s1->translated.x;
@@ -42,6 +40,7 @@ static void set_line(line* segment,FE_point const * s1, FE_point const * s2)
segment->dz=s2->translated.z-s1->translated.z;
segment->no_line=(segment->dx==0&&segment->dy==0);
}

static bool get_x(int y, line const * segment, int * x)
{
y-=segment->y;
@@ -61,11 +60,16 @@ static bool get_x(int y, line const * segment, int * x)
return true;
}


#include "texture.h"
#include "zbuffer.h"
#include <gint/display.h>
void FE_draw_face(FE_face const * face)
{
// élimination des faces cachées
if (sens_horaire(face)!=face->visible)
return;

// cas particuliers où la face n'est pas dans l'écran
if (face->s1->translated.x<0 && face->s2->translated.x<0 && face->s3->translated.x<0)
return;
if (face->s1->translated.x>127 && face->s2->translated.x>127 && face->s3->translated.x>127)
@@ -77,50 +81,65 @@ void FE_draw_face(FE_face const * face)
if (face->s1->translated.z<=0 && face->s2->translated.z<=0 && face->s3->translated.z<=0)
return;
// cas où un côté est nul
line cotes[3];
set_line(&cotes[0],face->s1,face->s2);
set_line(&cotes[1],face->s1,face->s3);
set_line(&cotes[2],face->s2,face->s3);

if (cotes[0].no_line||cotes[1].no_line||cotes[2].no_line)
set_line(&cotes[0], face->s1,face->s2);
set_line(&cotes[1], face->s1,face->s3);
set_line(&cotes[2], face->s2,face->s3);
if (cotes[0].no_line || cotes[1].no_line || cotes[2].no_line)
return;

const int ymin=max(min(face->s1->translated.y,min(face->s2->translated.y,face->s3->translated.y)),0);
const int ymax=min(max(face->s1->translated.y,max(face->s2->translated.y,face->s3->translated.y)),63);

const int xAB=face->s2->translated.x-face->s1->translated.x, yAB=face->s2->translated.y-face->s1->translated.y, zAB=face->s2->translated.z-face->s1->translated.z;
const int xAC=face->s3->translated.x-face->s1->translated.x, yAC=face->s3->translated.y-face->s1->translated.y, zAC=face->s3->translated.z-face->s1->translated.z;
const int diviseur_commun=(xAB*yAC-yAB*xAC); //(multiplier par 10000)

const int fact_1=(10000*yAC)/diviseur_commun, fact_2=(10000*xAC)/diviseur_commun;
const int fact_3=(10000*xAB)/diviseur_commun, fact_4=(10000*yAB)/diviseur_commun;
const int32_t y1 = max(min(face->s1->translated.y, min(face->s2->translated.y, face->s3->translated.y)), 0);
const int32_t y2 = min(max(face->s1->translated.y, max(face->s2->translated.y, face->s3->translated.y)), 63);

// ressources pour déformer les textures
const int32_t xAB = face->s2->translated.x-face->s1->translated.x,
yAB = face->s2->translated.y-face->s1->translated.y,
zAB=face->s2->translated.z-face->s1->translated.z;
const int32_t xAC = face->s3->translated.x-face->s1->translated.x,
yAC = face->s3->translated.y-face->s1->translated.y,
zAC=face->s3->translated.z-face->s1->translated.z;
const int32_t diviseur_commun=(xAB*yAC-yAB*xAC);
const int fact_1=(1024*yAC)/diviseur_commun, fact_2=(1024*xAC)/diviseur_commun;
const int fact_3=(1024*xAB)/diviseur_commun, fact_4=(1024*yAB)/diviseur_commun;
for (int y=ymin; y<=ymax; y++)
for (int y=y1; y<=y2; y++)
{
// détermination du xmin et du xmax de la ligne
int tx1,tx2;
int tx1, tx2;
for (int t=0;t<3;t++)
{if (get_x(y,&cotes[t],&tx1)) break;}
if (get_x(y,&cotes[t],&tx1))
break;
for (int t=0;t<3;t++)
{if (get_x(y,&cotes[t],&tx2)&&tx1!=tx2) break;}
if (get_x(y,&cotes[t],&tx2)&&tx1!=tx2)
break;
const int txmin=max(min(tx1,tx2),0), txmax=min(max(tx1,tx2),127);
for (int x=txmin; x<=txmax; x++)
{
double vx, vy, z;
// vx et vy coordonnées transformées pour l'accès à la texture
// z distance du point visible (distance non transformée)
int32_t vx, vy, z;
// calcul de vx, vy
vx=(xcalc*fact_1-ycalc*fact_2); // 0 <vx< 10_000
const int32_t xcalc = x-face->s1->translated.x, ycalc = y-face->s1->translated.y;
vx=(xcalc*fact_1-ycalc*fact_2); // 0 <vx< 10_000
vy=(ycalc*fact_3-xcalc*fact_4); // idem
z=face->s1->translated.z + (vx*zAB+vy*zAC)/10000;
vx/=10000;
vy/=10000;

vx /= (double)face->s2->translated.z / ((1-vx) / face->s1->translated.z + vx / (double)face->s2->translated.z);
vy /= (double)face->s3->translated.z / ((1-vy) / face->s1->translated.z + vy / (double)face->s3->translated.z);
// Affichage du point
if (FE_zbuffer_set_dist(x,y,z))
dpixel(x, y, 3*FE_get_pixel(face->texturenum, 8*vx, 8*vy)); // 3* means cast to black and white, and vx,and vy casted between 0 and 7

z=face->s1->translated.z + (vx*zAB+vy*zAC)/1024; // calcul de z non corrigé >> fonctionnel
if (z>0)
{
vx = (8 * vx * face->s1->translated.z)
/
(1024 * face->s1->translated.z + (1024 - vx) * face->s2->translated.z);

vy = (8 * vy * face->s1->translated.z)
/
(1024 * face->s1->translated.z + (1024 - vy) * face->s3->translated.z);
// Affichage du point
if (FE_zbuffer_set_dist(x,y,z))
dpixel(x, y, 3*FE_get_pixel(face->texturenum, vx, vy)); // 3* means cast to black and white, and vx,and vy casted between 0 and 7
}
}
}

@@ -132,4 +151,4 @@ void FE_draw_face(FE_face const * face)
// soit diviseur_commun = (xAB*yAC-yAB*xAC)
// x=xAM*yAC/diviseur_commun-yAM*xAC/diviseur_commun
// y=yAM*xAB/diviseur_commun-xAM*yAB/diciseur_commun
}
}

+ 4
- 5
src/FxEngine/face.h View File

@@ -2,14 +2,13 @@
#define FE_FACE_H

#include "coord.h"
#include "FxEngine.h"

#include <stdbool.h>
typedef struct FE_face FE_face;
struct FE_face
{
FE_point *s1,*s2,*s3;
bool visible; // true => clockwised
int texturenum;
FE_point *s1,*s2,*s3;
bool visible; // true => clockwised
int texturenum;
};

void FE_draw_face(FE_face const * face);


+ 50
- 44
src/FxEngine/zbuffer.c View File

@@ -1,60 +1,66 @@
#include "zbuffer.h"

#include <stdint.h>
#include <stdbool.h>
#include <gint/display.h>
#include <gint/std/stdio.h>
#include <gint/std/stdlib.h>
#include <gint/keyboard.h>
#include <gint/dma.h>
#include <gint/hardware.h>

/** size_uint32
* taille du zbuffer exprimée en uint32_t
* utile pour l'effacement du zbuffer sur sh3
**/
static const int size_uint32 = FE_ZB_SIZE_X*FE_ZB_SIZE_X;
/* size_uint32
taille du zbuffer exprimée en uint32_t
utile pour l'effacement du zbuffer sur sh3 */
static const uint32_t size_int32 = FE_ZB_SIZE_X*FE_ZB_SIZE_Y;

/** size_char
* taille du zbuffer exprimée en octets
* sera utile pour le DMA Controller
**/
static const int size_char = size_uint32*sizeof(uint32_t);
/* size_char
taille du zbuffer exprimée en octets
utile pour malloc */
static const uint32_t size_char = size_int32*sizeof(int32_t);

/** address
* addresse du zbuffer
**/
static uint32_t* address=0;
/* size_char
taille du zbuffer exprimée en octets
utile pour le DMA */
static const uint32_t size_blocks = size_char/32;

// buffer situe a la fin de la RAM
static const int32_t *address = (void *)0x88080000 - size_char;

#include <gint/defs/attributes.h>
GALIGNED(32) GSECTION(".rodata") static const int32_t clearval[8]={3000,3000,3000,3000,3000,3000,3000,3000};

void FE_zbuffer_clear()
{
while (address==0)
{
address = malloc(size_octets);
if (address==0) // cas de figure où il n'y a plus assez de RAM
{
dclear(C_WHITE);
dtext(1, 1, "Not enough RAM...", C_BLACK, C_NONE);
}
}
// TODO déterminer le type d'effacement
// effacement fait par le CPU
uint32_t indice = 0;
for (indice = 0; indice < size_uint32; indice ++)
address[indice] = 3000;
// effacement fait par le DMA
// TODO
if (isSH3())
{ // effacement CPU
uint_fast16_t indice;
for (indice = 0; indice < size_int32; indice ++)
address[indice] = clearval[0];
}
else
{ // effacement DMA
dma_transfer(0, DMA_32B, size_blocks, &clearval, DMA_FIXED, address, DMA_INC);
}
}

bool FE_zbuffer_set_dist(int x, int y, int dist)
void FE_start_rendering()
{
x %= FE_ZB_SIZE_X;
y %= FE_ZB_SIZE_Y;
const int indice = x * 64 + y;
if (address[indice]>dist && dist>0)
{
address[indice] = dist;
return true;
}
else
return false;
}
if (!isSH3())
dma_transfer_wait(0);

}

bool FE_zbuffer_set_dist(int32_t x, int32_t y, int32_t dist)
{
x %= FE_ZB_SIZE_X;
y %= FE_ZB_SIZE_Y;
const uint32_t indice = x * 64 + y;
if (address[indice]>dist && dist>0)
{
address[indice] = dist;
return true;
}
else
return false;
}

+ 8
- 2
src/FxEngine/zbuffer.h View File

@@ -12,11 +12,17 @@
void FE_zbuffer_clear();

#include <stdbool.h>
#include <stdint.h>
/** FE_zbuffer_set_dist
* change la distance d'un pixel du zbuffer
* retourne true si il faut dessiner le pixel
* retourne false si le pixel est déjà existant
**/
bool FE_zbuffer_set_dist(int x, int y, int dist); // if you are allowed to draw the pixel on vram
bool FE_zbuffer_set_dist(int32_t x, int32_t y, int32_t dist); // if you are allowed to draw the pixel on vram

#endif
/* FE_zbuffer_set_dist
doit être appelée avant l'affichage
attend la fin du transfert dma effaçant le zbuffer
**/
void FE_start_rendering();
#endif

+ 24
- 24
src/main.c View File

@@ -10,29 +10,29 @@

int main(void)
{
init_controls();
dclear(C_WHITE);
FE_point point[4]={{{10,0,0},{0,0,0}},{{10,10,0},{0,0,0}},{{10,0,10},{0,0,0}},{{10,10,10},{0,0,0}}};
FE_face face={&point[0],&point[1],&point[2],1,2};
FE_face face2={&point[3],&point[1],&point[2],0,2};
init_controls();
dclear(C_WHITE);
FE_point point[4]={{{10,0,0},{0,0,0}},{{10,10,0},{0,0,0}},{{10,0,10},{0,0,0}},{{10,10,10},{0,0,0}}};
FE_face face={&point[0],&point[1],&point[2],1,2};
FE_face face2={&point[3],&point[1],&point[2],0,2};

while (1)
{
FE_new_frame();
reload_fps_displaying();
for (int i=0;i<4;i++)
{
FE_calc(&point[i]);
if (point[i].translated.z>0)
{
dpixel(point[i].translated.x,point[i].translated.y,C_BLACK);
}
}
FE_draw_face(&face);
FE_draw_face(&face2);
display_fps(100,56);
}
getkey();
return 1;
while (1)
{
FE_new_frame();
reload_fps_displaying();
display_fps(100,56);
for (int i=0;i<4;i++)
{
FE_calc(&point[i]);
if (point[i].translated.z>0)
{
dpixel(point[i].translated.x,point[i].translated.y,C_BLACK);
}
}
FE_start_rendering();
FE_draw_face(&face);
FE_draw_face(&face2);
}
getkey();
return 1;
}

Loading…
Cancel
Save