feat: commentaires dans matrix, réarrangement de 2d.c dans video.c & création de 3d.c : première version cube en point dans test3d

This commit is contained in:
Nicolas Hordé 2018-10-26 14:09:43 +02:00
parent f705b5fe3d
commit c4e4462313
13 changed files with 858 additions and 611 deletions

View File

@ -1,13 +0,0 @@
/*******************************************************************************/
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
/* */
#include "types.h"
typedef struct vertex2d{
u16 x;
u16 y;
} vertex2d __attribute__ ((packed));
void linev(vertex2d *A, vertex2d *B, u32 color);
void trianglefilled(vertex2d *A, vertex2d *B, vertex2d *C, u32 color);
void triangle(vertex2d *A, vertex2d *B, vertex2d *C, u32 color);

View File

@ -2,3 +2,19 @@
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */ /* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
/* */ /* */
#include "types.h" #include "types.h"
#include "matrix.h"
#include "video.h"
typedef struct vertex3d{
union {
struct {
float x;
float y;
float z;
};
float v[3];
};
} vertex3d __attribute__ ((packed));
void proj(vector4 list[], vertex2d plane[], vector4 origin[], u16 number, float factor);
void cube(vector4 list[], vector4 *origin, u16 size);

View File

@ -9,6 +9,10 @@
#define degtorad(deg) (deg * PI / 180.0) #define degtorad(deg) (deg * PI / 180.0)
#define radtodeg(rad) (rad * 180.0 / PI) #define radtodeg(rad) (rad * 180.0 / PI)
double cos(double x);
double sin(double x);
float cosf(float x);
float sinf(float x);
float fabsf(float n); float fabsf(float n);
double fabs(double n); double fabs(double n);
float sqrtf(float n); float sqrtf(float n);

View File

@ -2,26 +2,29 @@
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */ /* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
/* */ /* */
typedef struct vector4 #ifndef MATRIX
{ # define MATRIX
float x, y, z, w;
} vector4;
typedef struct vector3 typedef struct vector4{
{ union {
float x, y, z; struct {
} vector3; float x;
float y;
float z;
float w;
};
float v[4];
};
} vector4 __attribute__ ((packed));
typedef struct vector2 typedef struct matrix44{
{ union {
float x, y; struct {
} vector2; vector4 V[4];
};
float v[16];
typedef struct matrix44 };
{ } matrix44 __attribute__ ((packed));
vector4 V[4];
} matrix44;
void vector4_show(vector4 src); void vector4_show(vector4 src);
void vector4_create(float x, float y, float z, float w, vector4 *dst); void vector4_create(float x, float y, float z, float w, vector4 *dst);
@ -63,12 +66,9 @@ void matrix44_invert(matrix44 *matrix);
void matrix44_transpose(matrix44 *matrix); void matrix44_transpose(matrix44 *matrix);
void matrix44_lookat(vector4 eye, vector4 dst, vector4 up, matrix44 *matrix); void matrix44_lookat(vector4 eye, vector4 dst, vector4 up, matrix44 *matrix);
int matrix44_isequals(matrix44 *m1, matrix44 *m2); int matrix44_isequals(matrix44 *m1, matrix44 *m2);
void toarray(matrix44 *m, float *array); float *toarray(matrix44 *m);
#endif

View File

@ -10,6 +10,7 @@ int (*function)()
int rebootnow(); int rebootnow();
int test2d(); int test2d();
int test3d();
int readidt(); int readidt();
int readgdt(); int readgdt();
int detectcpu(); int detectcpu();

View File

@ -10,6 +10,11 @@
#define MAXDRIVERS 10 #define MAXDRIVERS 10
#define MAXFONTS 10 #define MAXFONTS 10
typedef struct vertex2d{
u16 x;
u16 y;
} vertex2d __attribute__ ((packed));
typedef struct rgbcolor { typedef struct rgbcolor {
u8 R; u8 R;
u8 G; u8 G;
@ -101,12 +106,16 @@ void scroll_disable(void);
void showchar (u16 coordx, u16 coordy, u8 thechar, u8 attrib); void showchar (u16 coordx, u16 coordy, u8 thechar, u8 attrib);
u8 getchar (u16 coordx, u16 coordy); u8 getchar (u16 coordx, u16 coordy);
u8 getattrib (u16 coordx, u16 coordy); u8 getattrib (u16 coordx, u16 coordy);
void v_writepxl (vertex2d *A, u32 color);
void writepxl (u16 x, u16 y, u32 color); void writepxl (u16 x, u16 y, u32 color);
void line(u32 x1, u32 y1, u32 x2, u32 y2, u32 color); void line(u32 x1, u32 y1, u32 x2, u32 y2, u32 color);
void hline(u16 x1, u16 x2, u16 y, u32 color); void hline(u16 x1, u16 x2, u16 y, u32 color);
void changemode(u8 mode); void changemode(u8 mode);
u32 egatorgb(u8 ega); u32 egatorgb(u8 ega);
u8 egatovga(u8 ega); u8 egatovga(u8 ega);
void v_line(vertex2d *A, vertex2d *B, u32 color);
void trianglefilled(vertex2d *A, vertex2d *B, vertex2d *C, u32 color);
void triangle(vertex2d *A, vertex2d *B, vertex2d *C, u32 color);
/* Fonctions de console */ /* Fonctions de console */
void changevc(u8 vc); void changevc(u8 vc);

142
lib/2d.c
View File

@ -1,142 +0,0 @@
/*******************************************************************************/
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
/* */
#include "types.h"
#include "vga.h"
#include "video.h"
#include "2d.h"
#include "math.h"
/******************************************************************************/
/* Affiche une ligne entre les points spécifiés */
void linev(vertex2d * A, vertex2d * B, u32 color)
{
line(A->x, A->y, B->x, B->y, color);
}
void line(u32 x1, u32 y1, u32 x2, u32 y2, u32 color)
{
s32 dx, dy, sdx, sdy;
u32 i, dxabs, dyabs, x, y, px, py;
dx = x2 - x1; /* distance horizontale de la line */
dy = y2 - y1; /* distance verticale de la line * */
dxabs = abs(dx);
dyabs = abs(dy);
sdx = sgn(dx);
sdy = sgn(dy);
x = dyabs >> 1;
y = dxabs >> 1;
px = x1;
py = y1;
writepxl(px, py, color);
if (dxabs >= dyabs) { /* la ligne est plus horizontale que verticale */
for (i = 0; i < dxabs; i++) {
y += dyabs;
if (y >= dxabs) {
y -= dxabs;
py += sdy;
}
px += sdx;
writepxl(px, py, color);
}
} else { /* la ligne est plus verticale que horizontale */
for (i = 0; i < dyabs; i++) {
x += dxabs;
if (x >= dyabs) {
x -= dyabs;
px += sdx;
}
py += sdy;
writepxl(px, py, color);
}
}
}
/******************************************************************************/
/* Affiche un triangle rempli entre les points spécifiés */
void trianglefilled(vertex2d * AA, vertex2d * BB, vertex2d * CC, u32 color)
{
vertex2d *A, *B, *C, *TEMP;
u32 a, b, y, last;
int dx1, dx2, dx3, dy1, dy2, dy3, sa, sb;
A = AA;
B = BB;
C = CC;
while (A->y > B->y || B->y > C->y || A->y == C->y) {
if (A->y > B->y)
swapvertex(A, B);
if (B->y > C->y)
swapvertex(B, C);
if (A->y > C->y)
swapvertex(A, C);
}
if (A->y == C->y) { //meme ligne
a = b = A->x;
if (B->x < a)
a = B->x;
else if (B->x > b)
b = B->x;
if (C->x < a)
a = C->x;
else if (C->x > b)
b = C->x;
hline(a, b, A->y, color);
return;
}
dx1 = B->x - A->x;
dy1 = B->y - A->y;
dx2 = C->x - A->x;
dy2 = C->y - A->y;
dx3 = C->x - B->x;
dy3 = C->y - B->y;
sa = 0;
sb = 0;
if (B->y == C->y)
last = B->y;
else
last = B->y - 1;
for (y = A->y; y <= last; y++) {
a = A->x + sa / dy1;
b = A->x + sb / dy2;
sa += dx1;
sb += dx2;
hline(a, b, y, color);
}
sa = dx3 * (y - B->y);
sb = dx2 * (y - A->y);
for (; y <= C->y; y++) {
a = B->x + sa / dy3;
b = A->x + sb / dy2;
sa += dx3;
sb += dx2;
hline(a, b, y, color);
}
}
void swapvertex(vertex2d * A, vertex2d * B)
{
vertex2d temp = *A;
*A = *B;
*B = temp;
}
/******************************************************************************/
/* Affiche un triangle entre les points spécifiés */
void triangle(vertex2d * AA, vertex2d * BB, vertex2d * CC, u32 color)
{
line(AA->x, AA->y, BB->x, BB->y, color);
line(BB->x, BB->y, CC->x, CC->y, color);
line(CC->x, CC->y, AA->x, AA->y, color);
}

View File

@ -2,8 +2,55 @@
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */ /* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
/* */ /* */
#include "3d.h" #include "3d.h"
#include "2d.h"
#include "vga.h"
#include "types.h" #include "types.h"
#include "video.h" #include "video.h"
/*******************************************************************************/
/* Crée une projection simple pour test */
void proj(vector4 list[], vertex2d plane[], vector4 origin[], u16 number, float factor)
{
for (u32 i=0;i<number;i++)
{
plane[i].x=(int)((list[i].x*factor)/(list[i].z+origin->z)+origin->x);
plane[i].y=(int)((list[i].y*factor)/(list[i].z+origin->z)+origin->y);
}
}
/*******************************************************************************/
/* Crée une liste de vertex3D pour un cube */
void cube(vector4 list[], vector4 *origin, u16 size)
{
list[0].x=origin->x;
list[0].y=origin->y;
list[0].z=origin->z;
list[0].w=1.0f;
list[1].x=origin->x+size;
list[1].y=origin->y;
list[1].z=origin->z;
list[1].w=1.0f;
list[2].x=origin->x;
list[2].y=origin->y+size;
list[2].z=origin->z;
list[2].w=1.0f;
list[3].x=origin->x+size;
list[3].y=origin->y+size;
list[3].z=origin->z;
list[3].w=1.0f;
list[4].x=origin->x;
list[4].y=origin->y;
list[4].z=origin->z+size;
list[4].w=1.0f;
list[5].x=origin->x+size;
list[5].y=origin->y;
list[5].z=origin->z+size;
list[5].w=1.0f;
list[6].x=origin->x;
list[6].y=origin->y+size;
list[6].z=origin->z+size;
list[6].w=1.0f;
list[7].x=origin->x+size;
list[7].y=origin->y+size;
list[7].z=origin->z+size;
list[7].w=1.0f;
}

View File

@ -55,7 +55,8 @@ double cos(double x){
x = -x; x = -x;
while( M_PI < x ) while( M_PI < x )
x -= M_2_PI; x -= M_2_PI;
return 1.0 - (x*x/2.0)*( 1.0 - (x*x/12.0) * ( 1.0 - (x*x/30.0) * (1.0 - x*x/56.0 ))); double result=1.0 - (x*x/2.0)*( 1.0 - (x*x/12.0) * ( 1.0 - (x*x/30.0) * (1.0 - x*x/56.0 )));
return result;
} }
double sin(double x){ double sin(double x){
@ -67,11 +68,12 @@ float cosf(float x){
x = -x; x = -x;
while( M_PI < x ) while( M_PI < x )
x -= M_2_PI; x -= M_2_PI;
return 1.0f - (x*x/2.0f)*( 1.0f - (x*x/12.0f) * ( 1.0f - (x*x/30.0f) * (1.0f - x*x/56.0f ))); float result=1.0f - (x*x/2.0f)*( 1.0f - (x*x/12.0f) * ( 1.0f - (x*x/30.0f) * (1.0f - x*x/56.0f )));
return result;
} }
float sinf(float x){ float sinf(float x){
return cos(x-M_PI_2); return cosf(x-M_PI_2);
} }
/******************************************************************************/ /******************************************************************************/

View File

@ -5,11 +5,17 @@
#include "types.h" #include "types.h"
#include "math.h" #include "math.h"
/*******************************************************************************/
/* Affiche un vecteur de 4 composantes */
void vector4_show(vector4 src) void vector4_show(vector4 src)
{ {
printf("vecteur: X=%f Y=%f Z=%f W=%f \r\n", src.x, src.y, src.z, src.w); printf("vecteur: X=%f Y=%f Z=%f W=%f \r\n", src.x, src.y, src.z, src.w);
} }
/*******************************************************************************/
/* Créé un vecteur de 4 composantes */
void vector4_create(float x, float y, float z, float w, vector4 *dst) void vector4_create(float x, float y, float z, float w, vector4 *dst)
{ {
dst->x = x; dst->x = x;
@ -18,11 +24,17 @@ void vector4_create(float x, float y, float z, float w, vector4 *dst)
dst->w = w; dst->w = w;
} }
/*******************************************************************************/
/* Copie un vecteur de 4 composantes */
void vector4_copy(vector4 src, vector4 *dst) void vector4_copy(vector4 src, vector4 *dst)
{ {
vector4_create(src.x, src.y, src.z, src.w, dst); vector4_create(src.x, src.y, src.z, src.w, dst);
} }
/*******************************************************************************/
/* Ajoute deux vecteurs de 4 composantes */
void vector4_add(vector4 v1, vector4 v2, vector4 *dst) void vector4_add(vector4 v1, vector4 v2, vector4 *dst)
{ {
dst->x = v1.x + v2.x; dst->x = v1.x + v2.x;
@ -30,6 +42,9 @@ void vector4_add(vector4 v1, vector4 v2, vector4 *dst)
dst->z = v1.z + v2.z; dst->z = v1.z + v2.z;
} }
/*******************************************************************************/
/* Soustrait un vecteur de 4 composantes depuis un autre*/
void vector4_sub(vector4 v1, vector4 v2, vector4 *dst) void vector4_sub(vector4 v1, vector4 v2, vector4 *dst)
{ {
dst->x = v1.x - v2.x; dst->x = v1.x - v2.x;
@ -37,6 +52,9 @@ void vector4_sub(vector4 v1, vector4 v2, vector4 *dst)
dst->z = v1.z - v2.z; dst->z = v1.z - v2.z;
} }
/*******************************************************************************/
/* Redimensionne un vecteur de 4 composantes */
void vector4_scale(vector4 *dst, float factor) void vector4_scale(vector4 *dst, float factor)
{ {
dst->x *= factor; dst->x *= factor;
@ -45,6 +63,9 @@ void vector4_scale(vector4 *dst, float factor)
dst->w *= factor; dst->w *= factor;
} }
/*******************************************************************************/
/* Calcule le produit vectoriel de deux vecteurs de 4 composantes */
void vector4_crossproduct(vector4 v1, vector4 v2, vector4 *dst) void vector4_crossproduct(vector4 v1, vector4 v2, vector4 *dst)
{ {
dst->x = v1.y * v2.z - v1.z * v2.y; dst->x = v1.y * v2.z - v1.z * v2.y;
@ -52,6 +73,9 @@ void vector4_crossproduct(vector4 v1, vector4 v2, vector4 *dst)
dst->z = v1.x * v2.y - v1.y * v2.x; dst->z = v1.x * v2.y - v1.y * v2.x;
} }
/*******************************************************************************/
/* Normalise un vecteur de 4 composantes */
void vector4_normalize(vector4 *dst) void vector4_normalize(vector4 *dst)
{ {
float len; float len;
@ -67,6 +91,9 @@ void vector4_normalize(vector4 *dst)
} }
} }
/*******************************************************************************/
/* Divise un vecteur de 4 composantes depuis un autre*/
void vector4_divide(vector4 *v1, vector4 v2, vector4 *dst) void vector4_divide(vector4 *v1, vector4 v2, vector4 *dst)
{ {
dst->x = v1->x / v2.x; dst->x = v1->x / v2.x;
@ -74,6 +101,9 @@ void vector4_divide(vector4 *v1, vector4 v2, vector4 *dst)
dst->z = v1->z / v2.z; dst->z = v1->z / v2.z;
} }
/*******************************************************************************/
/* Détermine le 3ème vecteur perpendiculaire au 2 autres */
void vector4_perpendicular(vector4 v1, vector4 v2, vector4 *dst) void vector4_perpendicular(vector4 v1, vector4 v2, vector4 *dst)
{ {
float dot = vector4_dotproduct(v1, v2); float dot = vector4_dotproduct(v1, v2);
@ -82,12 +112,15 @@ void vector4_perpendicular(vector4 v1, vector4 v2, vector4 *dst)
dst->z = v1.z - dot * v2.z; dst->z = v1.z - dot * v2.z;
} }
/*******************************************************************************/
/* Tourne un vecteur à 4 composantes autour de X */
void vector4_rotate_x(vector4 *dst, float angle) void vector4_rotate_x(vector4 *dst, float angle)
{ {
vector4 origin; vector4 origin;
float sinus, cosinus; float sinus, cosinus;
sinus = sin(angle); sinus = sinf(angle);
cosinus = cos(angle); cosinus = cosf(angle);
origin.x = dst->x; origin.x = dst->x;
origin.y = dst->y; origin.y = dst->y;
origin.z = dst->z; origin.z = dst->z;
@ -95,12 +128,15 @@ void vector4_rotate_x(vector4 *dst, float angle)
dst->z = cosinus * origin.z - sinus * origin.y; dst->z = cosinus * origin.z - sinus * origin.y;
} }
/*******************************************************************************/
/* Tourne un vecteur à 4 composantes autour de Y */
void vector4_rotate_y(vector4 *dst, float angle) void vector4_rotate_y(vector4 *dst, float angle)
{ {
vector4 origin; vector4 origin;
float sinus, cosinus; float sinus, cosinus;
sinus = sin(angle); sinus = sinf(angle);
cosinus = cos(angle); cosinus = cosf(angle);
origin.x = dst->x; origin.x = dst->x;
origin.y = dst->y; origin.y = dst->y;
origin.z = dst->z; origin.z = dst->z;
@ -108,12 +144,15 @@ void vector4_rotate_y(vector4 *dst, float angle)
dst->z = cosinus * origin.z - sinus * origin.x; dst->z = cosinus * origin.z - sinus * origin.x;
} }
/*******************************************************************************/
/* Tourne un vecteur à 4 composantes autour de Z */
void vector4_rotate_z(vector4 *dst, float angle) void vector4_rotate_z(vector4 *dst, float angle)
{ {
vector4 origin; vector4 origin;
float sinus, cosinus; float sinus, cosinus;
sinus = sin(angle); sinus = sinf(angle);
cosinus = cos(angle); cosinus = cosf(angle);
origin.x = dst->x; origin.x = dst->x;
origin.y = dst->y; origin.y = dst->y;
origin.z = dst->z; origin.z = dst->z;
@ -121,6 +160,9 @@ void vector4_rotate_z(vector4 *dst, float angle)
dst->y = cosinus * origin.y - sinus * origin.x; dst->y = cosinus * origin.y - sinus * origin.x;
} }
/*******************************************************************************/
/* Donne la longueur d'un vecteur à 4 composantes */
float vector4_len(vector4 src) float vector4_len(vector4 src)
{ {
return sqrtf((src.x * src.x) + return sqrtf((src.x * src.x) +
@ -128,11 +170,17 @@ float vector4_len(vector4 src)
(src.z * src.z)); (src.z * src.z));
} }
/*******************************************************************************/
/* Retourne le produit scalaire de deux vecteurs à 4 composantes */
float vector4_dotproduct(vector4 v1, vector4 v2) float vector4_dotproduct(vector4 v1, vector4 v2)
{ {
return (v1.x * v2.x) + (v1.y * v2.y) + (v1.z * v2.z); return (v1.x * v2.x) + (v1.y * v2.y) + (v1.z * v2.z);
} }
/*******************************************************************************/
/* Retourne la norme d'un vecteur à 4 composantes */
float vector4_norm(vector4 src) float vector4_norm(vector4 src)
{ {
return sqrtf((src.x * src.x) + return sqrtf((src.x * src.x) +
@ -140,6 +188,9 @@ float vector4_norm(vector4 src)
(src.z * src.z)); (src.z * src.z));
} }
/*******************************************************************************/
/* Retourne la distance de deux vecteurs à 4 composantes */
float vector4_distance(vector4 v1, vector4 v2) float vector4_distance(vector4 v1, vector4 v2)
{ {
return sqrt(pow(v2.x - v1.x, 2) + return sqrt(pow(v2.x - v1.x, 2) +
@ -147,6 +198,9 @@ float vector4_distance(vector4 v1, vector4 v2)
pow(v2.z - v1.z, 2)); pow(v2.z - v1.z, 2));
} }
/*******************************************************************************/
/* Compare deux vecteurs à 4 composantes */
int vector4_isequals(vector4 v1, vector4 v2) int vector4_isequals(vector4 v1, vector4 v2)
{ {
float x, y, z; float x, y, z;
@ -156,6 +210,9 @@ int vector4_isequals(vector4 v1, vector4 v2)
return (x < 0.000001 && y < 0.000001 && z < 0.000001); return (x < 0.000001 && y < 0.000001 && z < 0.000001);
} }
/*******************************************************************************/
/* Définie le plan normal à 3 vecteurs à 4 composantes */
void vector4_planenormal(vector4 v1, vector4 v2, vector4 v3, vector4 *dst) void vector4_planenormal(vector4 v1, vector4 v2, vector4 v3, vector4 *dst)
{ {
vector4 temp1, temp2; vector4 temp1, temp2;
@ -165,6 +222,9 @@ void vector4_planenormal(vector4 v1, vector4 v2, vector4 v3, vector4 *dst)
vector4_normalize(dst); vector4_normalize(dst);
} }
/*******************************************************************************/
/* Créé une matrice d'identité */
void matrix44_homogen(matrix44 *matrix) void matrix44_homogen(matrix44 *matrix)
{ {
vector4_create(1, 0, 0, 0, &matrix->V[0]); vector4_create(1, 0, 0, 0, &matrix->V[0]);
@ -173,6 +233,9 @@ void matrix44_homogen(matrix44 *matrix)
vector4_create(0, 0, 0, 1, &matrix->V[3]); vector4_create(0, 0, 0, 1, &matrix->V[3]);
} }
/*******************************************************************************/
/* Créé une matrice vide */
void matrix44_empty(matrix44 *matrix) void matrix44_empty(matrix44 *matrix)
{ {
vector4_create(0, 0, 0, 0, &matrix->V[0]); vector4_create(0, 0, 0, 0, &matrix->V[0]);
@ -181,6 +244,9 @@ void matrix44_empty(matrix44 *matrix)
vector4_create(0, 0, 0, 0, &matrix->V[3]); vector4_create(0, 0, 0, 0, &matrix->V[3]);
} }
/*******************************************************************************/
/* Créé une matrice de redimensionnement (par un vecteur) */
void matrix44_scaling(vector4 v, matrix44 *dst) void matrix44_scaling(vector4 v, matrix44 *dst)
{ {
matrix44_homogen(dst); matrix44_homogen(dst);
@ -189,6 +255,9 @@ void matrix44_scaling(vector4 v, matrix44 *dst)
dst->V[2].z = v.z; dst->V[2].z = v.z;
} }
/*******************************************************************************/
/* Créé une matrice de déplacement */
void matrix44_translation(vector4 v, matrix44 *dst) void matrix44_translation(vector4 v, matrix44 *dst)
{ {
matrix44_homogen(dst); matrix44_homogen(dst);
@ -197,6 +266,9 @@ void matrix44_translation(vector4 v, matrix44 *dst)
dst->V[2].z = v.z; dst->V[2].z = v.z;
} }
/*******************************************************************************/
/* Créé une matrice de redimensionnement (par un facteur) */
void matrix44_scale(matrix44 *dst, float factor) void matrix44_scale(matrix44 *dst, float factor)
{ {
vector4_scale(&dst->V[0], factor); vector4_scale(&dst->V[0], factor);
@ -205,6 +277,9 @@ void matrix44_scale(matrix44 *dst, float factor)
vector4_scale(&dst->V[3], factor); vector4_scale(&dst->V[3], factor);
} }
/*******************************************************************************/
/* Créé une matrice de redimensionnement et de déplacement */
void matrix44_scale_translation(vector4 scale, vector4 translation, matrix44 *dst) void matrix44_scale_translation(vector4 scale, vector4 translation, matrix44 *dst)
{ {
matrix44_homogen(dst); matrix44_homogen(dst);
@ -216,11 +291,14 @@ void matrix44_scale_translation(vector4 scale, vector4 translation, matrix44 *ds
dst->V[3].z = translation.z; dst->V[3].z = translation.z;
} }
/*******************************************************************************/
/* Créé une matrice de rotation autour de X */
void matrix44_rotation_x(float angle, matrix44 *dst) void matrix44_rotation_x(float angle, matrix44 *dst)
{ {
float sinus,cosinus; float sinus,cosinus;
cosinus = cos(angle); cosinus = cosf(angle);
sinus = sin(angle); sinus = sinf(angle);
matrix44_empty(dst); matrix44_empty(dst);
dst->V[0].x = 1; dst->V[0].x = 1;
dst->V[1].y = cosinus; dst->V[1].y = cosinus;
@ -230,11 +308,14 @@ void matrix44_rotation_x(float angle, matrix44 *dst)
dst->V[3].w = 1; dst->V[3].w = 1;
} }
/*******************************************************************************/
/* Créé une matrice de rotation autour de Y */
void matrix44_rotation_y(float angle, matrix44 *dst) void matrix44_rotation_y(float angle, matrix44 *dst)
{ {
float sinus,cosinus; float sinus,cosinus;
cosinus = cos(angle); cosinus = cosf(angle);
sinus = sin(angle); sinus = sinf(angle);
matrix44_empty(dst); matrix44_empty(dst);
dst->V[0].x = cosinus; dst->V[0].x = cosinus;
dst->V[0].z = -1 * sinus; dst->V[0].z = -1 * sinus;
@ -244,11 +325,14 @@ void matrix44_rotation_y(float angle, matrix44 *dst)
dst->V[3].w = 1; dst->V[3].w = 1;
} }
/*******************************************************************************/
/* Créé une matrice de rotation autour de Z */
void matrix44_rotation_z(float angle, matrix44 *dst) void matrix44_rotation_z(float angle, matrix44 *dst)
{ {
float sinus,cosinus; float sinus,cosinus;
cosinus = cos(angle); cosinus = cosf(angle);
sinus = sin(angle); sinus = sinf(angle);
matrix44_empty(dst); matrix44_empty(dst);
dst->V[0].x = cosinus; dst->V[0].x = cosinus;
dst->V[0].y = sinus; dst->V[0].y = sinus;
@ -258,6 +342,9 @@ void matrix44_rotation_z(float angle, matrix44 *dst)
dst->V[3].w = 1; dst->V[3].w = 1;
} }
/*******************************************************************************/
/* Créé une matrice de rotation multiple */
void matrix44_rotation(vector4 axis, float angle, matrix44 *dst) void matrix44_rotation(vector4 axis, float angle, matrix44 *dst)
{ {
float cosinus, sinus, minuscos; float cosinus, sinus, minuscos;
@ -287,6 +374,9 @@ void matrix44_rotation(vector4 axis, float angle, matrix44 *dst)
dst->V[3].w = 1; dst->V[3].w = 1;
} }
/*******************************************************************************/
/* Multiplie deux matrices */
void matrix44_multiply(matrix44 *m1, matrix44 *m2, matrix44 *dst) void matrix44_multiply(matrix44 *m1, matrix44 *m2, matrix44 *dst)
{ {
dst->V[0].x = (m1->V[0].x * m2->V[0].x + m1->V[0].y * m2->V[1].x + dst->V[0].x = (m1->V[0].x * m2->V[0].x + m1->V[0].y * m2->V[1].x +
@ -323,6 +413,9 @@ void matrix44_multiply(matrix44 *m1, matrix44 *m2, matrix44 *dst)
m1->V[3].z * m2->V[2].w + m1->V[3].w * m2->V[3].w); m1->V[3].z * m2->V[2].w + m1->V[3].w * m2->V[3].w);
} }
/*******************************************************************************/
/* Transforme une matrice avec un vecteur à 4 composantes */
void matrix44_transform(matrix44 *matrix, vector4 *dst) void matrix44_transform(matrix44 *matrix, vector4 *dst)
{ {
vector4 origin; vector4 origin;
@ -336,6 +429,9 @@ void matrix44_transform(matrix44 *matrix, vector4 *dst)
dst->w = origin.x * matrix->V[0].w + origin.y * matrix->V[1].w + origin.z * matrix->V[2].w + origin.w * matrix->V[3].w; dst->w = origin.x * matrix->V[0].w + origin.y * matrix->V[1].w + origin.z * matrix->V[2].w + origin.w * matrix->V[3].w;
} }
/*******************************************************************************/
/* Calcule le déterminant d'une matrice */
float matrix44_determinant(matrix44 *matrix) float matrix44_determinant(matrix44 *matrix)
{ {
float a, b, c, d; float a, b, c, d;
@ -359,6 +455,9 @@ float todeterminant(float a1, float a2, float a3, float b1, float b2, float b3,
return (a1 * ((b2 * c3) - (b3 * c2))) - (b1 * ((a2 * c3) - (a3 * c2))) + (c1 * ((a2 * b3) - (a3 * b2))); return (a1 * ((b2 * c3) - (b3 * c2))) - (b1 * ((a2 * c3) - (a3 * c2))) + (c1 * ((a2 * b3) - (a3 * b2)));
} }
/*******************************************************************************/
/* Crée une matrice adjointe */
void matrix44_adjoint(matrix44 *matrix) void matrix44_adjoint(matrix44 *matrix)
{ {
float a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4, d1, d2, d3, d4; float a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4, d1, d2, d3, d4;
@ -403,6 +502,9 @@ void matrix44_adjoint(matrix44 *matrix)
matrix->V[3].w = todeterminant(a1, a2, a3, b1, b2, b3, c1, c2, c3); matrix->V[3].w = todeterminant(a1, a2, a3, b1, b2, b3, c1, c2, c3);
} }
/*******************************************************************************/
/* Affiche une matrice */
void matrix44_show(matrix44 *matrix) void matrix44_show(matrix44 *matrix)
{ {
printf("Matrice: X=%f Y=%f Z=%f W=%f \r\n", matrix->V[0].x, matrix->V[1].y, matrix->V[2].z, matrix->V[3].w); printf("Matrice: X=%f Y=%f Z=%f W=%f \r\n", matrix->V[0].x, matrix->V[1].y, matrix->V[2].z, matrix->V[3].w);
@ -410,6 +512,9 @@ void matrix44_show(matrix44 *matrix)
printf(" X=%f Y=%f Z=%f W=%f \r\n", matrix->V[0].x, matrix->V[1].y, matrix->V[2].z, matrix->V[3].w); printf(" X=%f Y=%f Z=%f W=%f \r\n", matrix->V[0].x, matrix->V[1].y, matrix->V[2].z, matrix->V[3].w);
} }
/*******************************************************************************/
/* Inverse une matrice */
void matrix44_invert(matrix44 *matrix) void matrix44_invert(matrix44 *matrix)
{ {
float det; float det;
@ -425,6 +530,9 @@ void matrix44_invert(matrix44 *matrix)
} }
} }
/*******************************************************************************/
/* Transpose une matrice */
void matrix44_transpose(matrix44 *matrix) void matrix44_transpose(matrix44 *matrix)
{ {
float f; float f;
@ -453,6 +561,9 @@ void matrix44_transpose(matrix44 *matrix)
matrix->V[3].z = f; matrix->V[3].z = f;
} }
/*******************************************************************************/
/* Crée une matrice de camera */
void matrix44_lookat(vector4 eye, vector4 dst, vector4 up, matrix44 *matrix) void matrix44_lookat(vector4 eye, vector4 dst, vector4 up, matrix44 *matrix)
{ {
vector4 xaxis, yaxis, zaxis, negeye; vector4 xaxis, yaxis, zaxis, negeye;
@ -481,28 +592,19 @@ void matrix44_lookat(vector4 eye, vector4 dst, vector4 up, matrix44 *matrix)
vector4_copy(negeye, &matrix->V[3]); vector4_copy(negeye, &matrix->V[3]);
} }
/*******************************************************************************/
/* Vérifie que deux matrices sont égales */
int matrix44_isequals(matrix44 *m1, matrix44 *m2) int matrix44_isequals(matrix44 *m1, matrix44 *m2)
{ {
return vector4_isequals(m1->V[0], m2->V[0]) && vector4_isequals(m1->V[1], m2->V[1]) && return vector4_isequals(m1->V[0], m2->V[0]) && vector4_isequals(m1->V[1], m2->V[1]) &&
vector4_isequals(m1->V[2], m2->V[2]) && vector4_isequals(m1->V[3], m2->V[3]); vector4_isequals(m1->V[2], m2->V[2]) && vector4_isequals(m1->V[3], m2->V[3]);
} }
void toarray(matrix44 *m, float *array) /*******************************************************************************/
/* Transforme une matrice en tableau */
float *toarray(matrix44 *m)
{ {
array[0] = m->V[0].x; return &m->v;
array[1] = m->V[0].y;
array[2] = m->V[0].z;
array[3] = m->V[0].w;
array[4] = m->V[1].x;
array[5] = m->V[1].y;
array[6] = m->V[1].z;
array[7] = m->V[1].w;
array[8] = m->V[2].x;
array[9] = m->V[2].y;
array[10] = m->V[2].z;
array[11] = m->V[2].w;
array[12] = m->V[3].x;
array[13] = m->V[3].y;
array[14] = m->V[3].z;
array[15] = m->V[3].w;
} }

View File

@ -2,12 +2,13 @@
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */ /* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
/* */ /* */
#include "vga.h" #include "vga.h"
#include "3d.h"
#include "matrix.h"
#include "video.h" #include "video.h"
#include "interrupts.h" #include "interrupts.h"
#include "asm.h" #include "asm.h"
#include "cpu.h" #include "cpu.h"
#include "string.h" #include "string.h"
#include "2d.h"
#include "gdt.h" #include "gdt.h"
#include "shell.h" #include "shell.h"
#include "multiboot2.h" #include "multiboot2.h"
@ -34,6 +35,7 @@ static command commands[] = {
{"help" , "", &help}, {"help" , "", &help},
{"logo" , "", &logo}, {"logo" , "", &logo},
{"font" , "", &sfont}, {"font" , "", &sfont},
{"test3d" , "", &test3d},
}; };
/*******************************************************************************/ /*******************************************************************************/
@ -416,7 +418,73 @@ int rebootnow()
} }
/*******************************************************************************/ /*******************************************************************************/
/* Test les fonctionnalité 2D graphiques */ /* Teste les fonctionnalités 3D */
int test3d()
{
videoinfos *vinfo=getvideo_info();
if (!vinfo->isgraphic) {
print("Mode graphique necessaire afin de lancer ce programme\r\n");
return 1;
}
vector4 list3d[8];
vertex2d list2d[8];
matrix44 rotatex,rotatey,rotatez,mrotatex,mrotatey,mrotatez;
matrix44* transformation;
matrix44_rotation_x(0.1f, &rotatex);
matrix44_rotation_y(0.1f, &rotatey);
matrix44_rotation_z(0.1f, &rotatez);
matrix44_rotation_x(-0.1f, &mrotatex);
matrix44_rotation_y(-0.1f, &mrotatey);
matrix44_rotation_z(-0.1f, &mrotatez);
vector4 origin={0.0f,0.0f,0.0f,0.0f};
vector4 cubeorigin={0.0f,0.0f,0.0f,0.0f};
origin.x=vinfo->currentwidth/2.0f;
origin.y=vinfo->currentheight/2.0f;
origin.z=70.0f;
cube(&list3d, &cubeorigin, 35.0f);
u8 achar=' ';
u8 i;
while(achar!='a')
{
clearscreen();
proj(&list3d, &list2d, &origin, 8, 100.0f);
for (i = 0; i < 8; i++)
{
v_writepxl(&list2d[i], egatorgb(4));
}
achar=waitascii();
switch(achar) {
case 17:
transformation=&rotatex;
break;
case 18:
transformation=&mrotatex;
break;
case 19:
transformation=&rotatey;
break;
case 20:
transformation=&mrotatey;
break;
case 2:
transformation=&rotatez;
break;
case 3:
transformation=&mrotatez;
break;
}
for (i = 0; i < 8; i++)
{
matrix44_transform(transformation, &list3d[i]);
}
}
return 0;
}
/*******************************************************************************/
/* Teste les fonctionnalités 2D graphiques */
int test2d() int test2d()
{ {
@ -439,7 +507,7 @@ int test2d()
color=random(0,63); color=random(0,63);
else else
color=random(0,16); color=random(0,16);
linev(&a,&b,color); v_line(&a,&b,color);
} }
waitascii(); waitascii();
for (int i = 0; i < 2000; i++) { for (int i = 0; i < 2000; i++) {

View File

@ -2,12 +2,16 @@
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */ /* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
/* */ /* */
#include "asm.h" #include "asm.h"
#include "math.h"
#include "video.h" #include "video.h"
#include "stdarg.h" #include "stdarg.h"
#include "string.h" #include "string.h"
#include "VGA/8x8fnt.c" #include "VGA/8x8fnt.c"
#include "VGA/8x16fnt.c" #include "VGA/8x16fnt.c"
/******************************************************************************/
/* VARIABLES */
static drivers registred[MAXDRIVERS]; static drivers registred[MAXDRIVERS];
static font fonts[MAXFONTS]; static font fonts[MAXFONTS];
@ -31,6 +35,9 @@ static console vc[8] = {
static u8 usedvc = 0; static u8 usedvc = 0;
/******************************************************************************/
/* FONCTIONS CONSOLE */
/*******************************************************************************/ /*******************************************************************************/
/* Fixe l'attribut courant */ /* Fixe l'attribut courant */
@ -200,65 +207,6 @@ bool makeansi(u8 c)
return 0; /* Ansi fini ;) */ return 0; /* Ansi fini ;) */
} }
/*******************************************************************************/
/* Change de mode video */
void changemode(u8 mode)
{
setvideo_mode(mode);
vinfo=getvideo_info();
if (!vinfo->isgraphic) {
width=vinfo->currentwidth;
height=vinfo->currentheight;
}
else
{
width=(vinfo->currentwidth>>3);
height=(vinfo->currentheight>>3);
}
for(u32 i=0;i<MAXFONTS;i++)
fonts[i].nom[0]=NULL;
loadfont("BIOS1",font8x8,8,8);
loadfont("BIOS0",font8x16,8,16);
setfont("BIOS1");
clearscreen();
}
/*******************************************************************************/
/* Renvoie la taille horizontale */
u16 getwidth(void)
{
return width;
}
/*******************************************************************************/
/* Renvoie la taille verticale */
u16 getheight(void)
{
return height;
}
/*******************************************************************************/
/* Efface la console en cours d'utilisation */
void clearscreen(void)
{
fill(vc[usedvc].attrib);
vc[usedvc].cursX=0;
vc[usedvc].cursY=0;
cursor_set(0,0);
}
/*******************************************************************************/
/* Change la console en cours d'utilisation */
void changevc(u8 avc)
{
usedvc = avc;
page_show(usedvc);
page_set(usedvc);
cursor_set(vc[usedvc].cursX, vc[usedvc].cursY);
}
/*******************************************************************************/ /*******************************************************************************/
/* affiche un caractère a l'écran */ /* affiche un caractère a l'écran */
@ -336,6 +284,547 @@ void putchar(u8 thechar)
cursor_set(vc[usedvc].cursX, vc[usedvc].cursY); cursor_set(vc[usedvc].cursX, vc[usedvc].cursY);
} }
/*******************************************************************************/
/* Change la console en cours d'utilisation */
void changevc(u8 avc)
{
usedvc = avc;
page_show(usedvc);
page_set(usedvc);
cursor_set(vc[usedvc].cursX, vc[usedvc].cursY);
}
/*******************************************************************************/
/* Renvoie la taille horizontale */
u16 getwidth(void)
{
return width;
}
/*******************************************************************************/
/* Renvoie la taille verticale */
u16 getheight(void)
{
return height;
}
/*******************************************************************************/
/* Efface la console en cours d'utilisation */
void clearscreen(void)
{
fill(vc[usedvc].attrib);
vc[usedvc].cursX=0;
vc[usedvc].cursY=0;
cursor_set(0,0);
}
/******************************************************************************/
/* Active le scrolling */
void scroll_enable(void)
{
vc[usedvc].scroll=true;
}
/******************************************************************************/
/* Désactive le scrolling */
void scroll_disable(void)
{
vc[usedvc].scroll=false;
}
/******************************************************************************/
/* FONCTIONS VIDEO BASIQUES */
/*******************************************************************************/
/* initialise le tableau des pilotes vidéo */
void initdriver() {
for(u32 i=0;i<MAXDRIVERS;i++)
registred[i].nom=NULL;
}
/*******************************************************************************/
/* Enregistre un pilote dans le tableau des pilotes vidéo */
void registerdriver(videofonction *pointer)
{
u32 i;
for(i=0;i<MAXDRIVERS;i++)
if (registred[i].pointer==pointer)
return;
i=0;
while (registred[i].nom!=NULL && i<MAXDRIVERS)
i++;
if (pointer->detect_hardware()!=NULL)
{
registred[i].pointer=pointer;
registred[i].nom=pointer->getvideo_drivername();
}
}
/*******************************************************************************/
/* Choisi le meilleur driver en terme d'affichage */
void apply_bestdriver(void) {
u32 i=0,j=0;
u8 bestdepth=0x0;
u8 bestresol=0x0;
u8 bestmode=0x0;
u8* bestdriver=NULL;
capabilities *cap;
while (registred[i].nom!=NULL && i<MAXDRIVERS) {
cap=registred[i].pointer->getvideo_capabilities();
while(cap[j].modenumber!=0xFF) {
if (cap[j].depth>bestdepth && (cap[j].width*cap[j].height)>=bestresol)
{
bestdepth=cap[j].depth;
bestresol=cap[j].width*cap[j].height;
bestmode=cap[j].modenumber;
bestdriver=registred[i].pointer->getvideo_drivername();
}
j++;
}
i++;
}
if (bestdriver!=NULL) apply_driver(bestdriver);
setvideo_mode(bestmode);
}
/*******************************************************************************/
/* Choisi le meilleur driver spécifié par le nom */
void apply_driver(u8* name)
{
u32 i=0;
while (registred[i].nom!=NULL && i<MAXDRIVERS) {
if (strcmp(name,registred[i].nom)==0) {
detect_hardware=registred[i].pointer->detect_hardware;
setvideo_mode=registred[i].pointer->setvideo_mode;
getvideo_drivername=registred[i].pointer->getvideo_drivername;
getvideo_capabilities=registred[i].pointer->getvideo_capabilities;
getvideo_info=registred[i].pointer->getvideo_info;
mem_to_video=registred[i].pointer->mem_to_video;
video_to_mem=registred[i].pointer->video_to_mem;
video_to_video=registred[i].pointer->video_to_video;
wait_vretrace=registred[i].pointer->wait_vretrace;
wait_hretrace=registred[i].pointer->wait_hretrace;
page_set=registred[i].pointer->page_set;
page_show=registred[i].pointer->page_show;
page_split=registred[i].pointer->page_split;
cursor_enable=registred[i].pointer->cursor_enable;
cursor_disable=registred[i].pointer->cursor_disable;
cursor_set=registred[i].pointer->cursor_set;
font_load=registred[i].pointer->font_load;
font1_set=registred[i].pointer->font1_set;
font2_set=registred[i].pointer->font2_set;
blink_enable=registred[i].pointer->blink_enable;
blink_disable=registred[i].pointer->blink_disable;
changemode(0x0);
return;
}
i++;
}
}
/*******************************************************************************/
/* Applique le driver suivant */
void apply_nextdriver(void) {
u32 i=0;
while (registred[i].nom!=NULL && i<MAXDRIVERS)
if (strcmp(getvideo_drivername(),registred[i].nom)==0) {
i++;
if (registred[i].nom!=NULL) i=0;
apply_driver(registred[i].nom);
return;
}
i++;
}
/*******************************************************************************/
/* Applique le mode suivant (le driver suivant si dernier mode) */
void apply_nextvideomode(void) {
capabilities *cap=getvideo_capabilities();
videoinfos *info=getvideo_info();
u32 mode=info->currentmode;
u8 index=0;
while(cap[index].modenumber!=0xFF) {
if (cap[index].modenumber==mode) {
index++;
if (cap[index].modenumber==0xFF)
apply_nextdriver();
else
changemode(cap[index].modenumber);
return;
}
index++;
}
}
/*******************************************************************************/
/* Change de mode video */
void changemode(u8 mode)
{
setvideo_mode(mode);
vinfo=getvideo_info();
if (!vinfo->isgraphic) {
width=vinfo->currentwidth;
height=vinfo->currentheight;
}
else
{
width=(vinfo->currentwidth>>3);
height=(vinfo->currentheight>>3);
}
for(u32 i=0;i<MAXFONTS;i++)
fonts[i].nom[0]=NULL;
loadfont("BIOS1",font8x8,8,8);
loadfont("BIOS0",font8x16,8,16);
setfont("BIOS1");
clearscreen();
}
/******************************************************************************/
/* Rempli l'écran avec un attribut donné et des espaces vides */
static u8 space=' ';
void fill(u8 attrib)
{
if (!vinfo->isgraphic)
{
mem_to_video(space ,0,vinfo->pagesize>>1, false);
mem_to_video(attrib,1,vinfo->pagesize>>1, false);
}
else
{
mem_to_video(0x0,0,vinfo->pagesize, false);
}
}
/******************************************************************************/
/* Défile l'écran de N ligne si le scrolling est activé */
void scroll (u8 lines, u8 attrib)
{
if (vc[usedvc].scroll) {
if (!vinfo->isgraphic)
{
u32 gain=vinfo->currentpitch*lines;
video_to_video(gain,0,vinfo->pagesize-gain);
mem_to_video(space ,vinfo->pagesize-gain-2,gain, false);
mem_to_video(attrib,vinfo->pagesize-gain-1,gain, false);
}
else
{
u32 gain=vinfo->currentpitch*(lines<<3);
video_to_video(gain,0,vinfo->pagesize-gain);
mem_to_video(0x0 ,vinfo->pagesize-gain-2,gain, false);
}
}
else
{
clearscreen();
}
}
/******************************************************************************/
/* Retourne une couleur RGB 32 bits depuis une couleur EGA/VGA */
static convertega[]={0,1,2,3,4,5,20,7,56,57,58,59,60,61,62,63};
u8 egatovga(u8 ega)
{
return convertega[ega & 0xF];
}
/******************************************************************************/
/* Retourne une couleur RGB 32 bits depuis une couleur EGA/VGA */
static convertrgb[]={0x000000,0x0000AA,0x00AA00,0x00AAAA,0xAA0000,0xAA00AA,0xAA5500,0xAAAAAA,0x555555,0x5555FF,0x55FF55,0x55FFFF,0xFF5555,0xFF55FF,0xFFFF55,0xFFFFFF};
u32 egatorgb(u8 vga)
{
return convertrgb[vga & 0xF];
}
/******************************************************************************/
/* Retourne le caractère du mode texte aux coordonnées spécifiées */
u8 getchar (u16 coordx, u16 coordy)
{
u8 thechar=0;
if (!vinfo->isgraphic)
{
u32 addr=(coordx<<1)+vinfo->currentpitch*coordy;
video_to_mem(addr,&thechar,1);
}
return thechar;
}
/******************************************************************************/
/* Retourne l'attribut du mode texte aux coordonnées spécifiées */
u8 getattrib (u16 coordx, u16 coordy)
{
u8 attrib=0;
if (!vinfo->isgraphic)
{
u32 addr=(coordx<<1)+vinfo->currentpitch*coordy;
video_to_mem(addr+1,&attrib,1);
}
return attrib;
}
/******************************************************************************/
/* Chargement d'une police de caractère */
void loadfont(u8 *name,font* pointer,u8 width, u8 height)
{
u32 i;
for(i=0;i<MAXFONTS;i++)
if (fonts[i].nom[0]!=NULL && fonts[i].pointer==pointer)
return;
i=0;
while (fonts[i].nom[0]!=NULL && i<MAXFONTS)
i++;
fonts[i].pointer=pointer;
strcpy(name,fonts[i].nom);
fonts[i].width=width;
fonts[i].height=height;
if (fonts[i].nom[0]=='B' && fonts[i].nom[1]=='I' && fonts[i].nom[2]=='O' && fonts[i].nom[3]=='S')
{
u8 number=(fonts[i].nom[4]-'0');
font_load(pointer, height, number);
}
}
/******************************************************************************/
/* Changement de la police */
void setfont(u8 *fontname)
{
u32 i=0;
while (fonts[i].nom!=NULL && i<MAXFONTS) {
if (strcmp(fontname,fonts[i].nom)==0) {
currentfont=&fonts[i];
return;
}
i++;
}
}
/******************************************************************************/
/* FONCTIONS VIDEO GRAPHIQUES */
/******************************************************************************/
/* Affiche un caractère */
void showchar(u16 coordx, u16 coordy, u8 thechar, u8 attrib)
{
u8 x, y, pattern, set;
u32 color;
if (!vinfo->isgraphic)
{
u32 addr=(coordx<<1)+vinfo->currentpitch*coordy;
mem_to_video(thechar,addr , 1, false);
mem_to_video(attrib, addr+1, 1, false);
}
else
{
for (y = 0; y < currentfont->height; y++)
{
pattern = currentfont->pointer[currentfont->height*thechar + y];
for (x = 0; x < currentfont->width; x++)
{
rol(pattern);
set = pattern & 0x1;
if (set == 0)
if (vinfo->currentdepth==32)
color = egatorgb((attrib & 0xF0) >> 4);
else
color = egatovga((attrib & 0xF0) >> 4);
else
if (vinfo->currentdepth==32)
color = egatorgb(attrib & 0x0F);
else
color = egatovga(attrib & 0x0F);
writepxl(currentfont->width*coordx + x, currentfont->height*coordy + y, color);
}
}
}
}
/******************************************************************************/
/* Affiche une ligne horizontale entre les points spécifiés */
void hline(u16 x1, u16 x2, u16 y, u32 color)
{
if (vinfo->isgraphic)
{
if (x2 > x1)
mem_to_video(color,(vinfo->currentdepth>>3)*x1+vinfo->currentpitch*y,x2-x1,false);
else
mem_to_video(color,(vinfo->currentdepth>>3)*x2+vinfo->currentpitch*y,x1-x2,false);
}
}
/******************************************************************************/
/* Affiche un pixel à l'écran */
void v_writepxl(vertex2d *A, u32 color)
{
writepxl(A->x, A->y, color);
}
void writepxl(u16 x, u16 y, u32 color)
{
if (vinfo->isgraphic)
{
u32 addr=(vinfo->currentdepth>>3)*x+vinfo->currentpitch*y;
mem_to_video(color,addr,1,false);
}
}
/******************************************************************************/
/* Affiche une ligne entre les points spécifiés */
void v_line(vertex2d *A, vertex2d *B, u32 color)
{
line(A->x, A->y, B->x, B->y, color);
}
void line(u32 x1, u32 y1, u32 x2, u32 y2, u32 color)
{
s32 dx, dy, sdx, sdy;
u32 i, dxabs, dyabs, x, y, px, py;
dx = x2 - x1; /* distance horizontale de la line */
dy = y2 - y1; /* distance verticale de la line * */
dxabs = abs(dx);
dyabs = abs(dy);
sdx = sgn(dx);
sdy = sgn(dy);
x = dyabs >> 1;
y = dxabs >> 1;
px = x1;
py = y1;
writepxl(px, py, color);
if (dxabs >= dyabs) { /* la ligne est plus horizontale que verticale */
for (i = 0; i < dxabs; i++) {
y += dyabs;
if (y >= dxabs) {
y -= dxabs;
py += sdy;
}
px += sdx;
writepxl(px, py, color);
}
} else { /* la ligne est plus verticale que horizontale */
for (i = 0; i < dyabs; i++) {
x += dxabs;
if (x >= dyabs) {
x -= dyabs;
px += sdx;
}
py += sdy;
writepxl(px, py, color);
}
}
}
/******************************************************************************/
/* Affiche un triangle rempli entre les points spécifiés */
void trianglefilled(vertex2d * AA, vertex2d * BB, vertex2d * CC, u32 color)
{
vertex2d *A, *B, *C, *TEMP;
u32 a, b, y, last;
int dx1, dx2, dx3, dy1, dy2, dy3, sa, sb;
A = AA;
B = BB;
C = CC;
while (A->y > B->y || B->y > C->y || A->y == C->y) {
if (A->y > B->y)
swapvertex(A, B);
if (B->y > C->y)
swapvertex(B, C);
if (A->y > C->y)
swapvertex(A, C);
}
if (A->y == C->y) { //meme ligne
a = b = A->x;
if (B->x < a)
a = B->x;
else if (B->x > b)
b = B->x;
if (C->x < a)
a = C->x;
else if (C->x > b)
b = C->x;
hline(a, b, A->y, color);
return;
}
dx1 = B->x - A->x;
dy1 = B->y - A->y;
dx2 = C->x - A->x;
dy2 = C->y - A->y;
dx3 = C->x - B->x;
dy3 = C->y - B->y;
sa = 0;
sb = 0;
if (B->y == C->y)
last = B->y;
else
last = B->y - 1;
for (y = A->y; y <= last; y++) {
a = A->x + sa / dy1;
b = A->x + sb / dy2;
sa += dx1;
sb += dx2;
hline(a, b, y, color);
}
sa = dx3 * (y - B->y);
sb = dx2 * (y - A->y);
for (; y <= C->y; y++) {
a = B->x + sa / dy3;
b = A->x + sb / dy2;
sa += dx3;
sb += dx2;
hline(a, b, y, color);
}
}
void swapvertex(vertex2d * A, vertex2d * B)
{
vertex2d temp = *A;
*A = *B;
*B = temp;
}
/******************************************************************************/
/* Affiche un triangle entre les points spécifiés */
void triangle(vertex2d * AA, vertex2d * BB, vertex2d * CC, u32 color)
{
v_line(AA, BB, color);
v_line(BB, CC, color);
v_line(CC, AA, color);
}
/******************************************************************************/
/* FONCTIONS VIDEO TEXTE AFFICHAGE */
/*******************************************************************************/ /*******************************************************************************/
/* affiche une chaine de caractère a l'écran */ /* affiche une chaine de caractère a l'écran */
@ -858,338 +1347,3 @@ u8 *sitoa(u64 num, u8 * str, u64 dim)
strinvert(str); strinvert(str);
return pointer; return pointer;
} }
/*******************************************************************************/
/* initialise le tableau des pilotes vidéo */
void initdriver() {
for(u32 i=0;i<MAXDRIVERS;i++)
registred[i].nom=NULL;
}
/*******************************************************************************/
/* Enregistre un pilote dans le tableau des pilotes vidéo */
void registerdriver(videofonction *pointer)
{
u32 i;
for(i=0;i<MAXDRIVERS;i++)
if (registred[i].pointer==pointer)
return;
i=0;
while (registred[i].nom!=NULL && i<MAXDRIVERS)
i++;
if (pointer->detect_hardware()!=NULL)
{
registred[i].pointer=pointer;
registred[i].nom=pointer->getvideo_drivername();
}
}
/*******************************************************************************/
/* Choisi le meilleur driver en terme d'affichage */
void apply_bestdriver(void) {
u32 i=0,j=0;
u8 bestdepth=0x0;
u8 bestresol=0x0;
u8 bestmode=0x0;
u8* bestdriver=NULL;
capabilities *cap;
while (registred[i].nom!=NULL && i<MAXDRIVERS) {
cap=registred[i].pointer->getvideo_capabilities();
while(cap[j].modenumber!=0xFF) {
if (cap[j].depth>bestdepth && (cap[j].width*cap[j].height)>=bestresol)
{
bestdepth=cap[j].depth;
bestresol=cap[j].width*cap[j].height;
bestmode=cap[j].modenumber;
bestdriver=registred[i].pointer->getvideo_drivername();
}
j++;
}
i++;
}
if (bestdriver!=NULL) apply_driver(bestdriver);
setvideo_mode(bestmode);
}
/*******************************************************************************/
/* Choisi le meilleur driver spécifié par le nom */
void apply_driver(u8* name)
{
u32 i=0;
while (registred[i].nom!=NULL && i<MAXDRIVERS) {
if (strcmp(name,registred[i].nom)==0) {
detect_hardware=registred[i].pointer->detect_hardware;
setvideo_mode=registred[i].pointer->setvideo_mode;
getvideo_drivername=registred[i].pointer->getvideo_drivername;
getvideo_capabilities=registred[i].pointer->getvideo_capabilities;
getvideo_info=registred[i].pointer->getvideo_info;
mem_to_video=registred[i].pointer->mem_to_video;
video_to_mem=registred[i].pointer->video_to_mem;
video_to_video=registred[i].pointer->video_to_video;
wait_vretrace=registred[i].pointer->wait_vretrace;
wait_hretrace=registred[i].pointer->wait_hretrace;
page_set=registred[i].pointer->page_set;
page_show=registred[i].pointer->page_show;
page_split=registred[i].pointer->page_split;
cursor_enable=registred[i].pointer->cursor_enable;
cursor_disable=registred[i].pointer->cursor_disable;
cursor_set=registred[i].pointer->cursor_set;
font_load=registred[i].pointer->font_load;
font1_set=registred[i].pointer->font1_set;
font2_set=registred[i].pointer->font2_set;
blink_enable=registred[i].pointer->blink_enable;
blink_disable=registred[i].pointer->blink_disable;
changemode(0x0);
return;
}
i++;
}
}
/*******************************************************************************/
/* Applique le driver suivant */
void apply_nextdriver(void) {
u32 i=0;
while (registred[i].nom!=NULL && i<MAXDRIVERS)
if (strcmp(getvideo_drivername(),registred[i].nom)==0) {
i++;
if (registred[i].nom!=NULL) i=0;
apply_driver(registred[i].nom);
return;
}
i++;
}
/*******************************************************************************/
/* Applique le mode suivant (le driver suivant si dernier mode) */
void apply_nextvideomode(void) {
capabilities *cap=getvideo_capabilities();
videoinfos *info=getvideo_info();
u32 mode=info->currentmode;
u8 index=0;
while(cap[index].modenumber!=0xFF) {
if (cap[index].modenumber==mode) {
index++;
if (cap[index].modenumber==0xFF)
apply_nextdriver();
else
changemode(cap[index].modenumber);
return;
}
index++;
}
}
/******************************************************************************/
/* Rempli l'écran avec un attribut donné et des espaces vides */
static u8 space=' ';
void fill(u8 attrib)
{
if (!vinfo->isgraphic)
{
mem_to_video(space ,0,vinfo->pagesize>>1, false);
mem_to_video(attrib,1,vinfo->pagesize>>1, false);
}
else
{
mem_to_video(0x0,0,vinfo->pagesize, false);
}
}
/******************************************************************************/
/* Défile l'écran de N ligne si le scrolling est activé */
void scroll (u8 lines, u8 attrib)
{
if (vc[usedvc].scroll) {
if (!vinfo->isgraphic)
{
u32 gain=vinfo->currentpitch*lines;
video_to_video(gain,0,vinfo->pagesize-gain);
mem_to_video(space ,vinfo->pagesize-gain-2,gain, false);
mem_to_video(attrib,vinfo->pagesize-gain-1,gain, false);
}
else
{
u32 gain=vinfo->currentpitch*(lines<<3);
video_to_video(gain,0,vinfo->pagesize-gain);
mem_to_video(0x0 ,vinfo->pagesize-gain-2,gain, false);
}
}
else
{
clearscreen();
}
}
/******************************************************************************/
/* Active le scrolling */
void scroll_enable(void)
{
vc[usedvc].scroll=true;
}
/******************************************************************************/
/* Désactive le scrolling */
void scroll_disable(void)
{
vc[usedvc].scroll=false;
}
/******************************************************************************/
/* Affiche un caractère */
void showchar(u16 coordx, u16 coordy, u8 thechar, u8 attrib)
{
u8 x, y, pattern, set;
u32 color;
if (!vinfo->isgraphic)
{
u32 addr=(coordx<<1)+vinfo->currentpitch*coordy;
mem_to_video(thechar,addr , 1, false);
mem_to_video(attrib, addr+1, 1, false);
}
else
{
for (y = 0; y < currentfont->height; y++)
{
pattern = currentfont->pointer[currentfont->height*thechar + y];
for (x = 0; x < currentfont->width; x++)
{
rol(pattern);
set = pattern & 0x1;
if (set == 0)
if (vinfo->currentdepth==32)
color = egatorgb((attrib & 0xF0) >> 4);
else
color = egatovga((attrib & 0xF0) >> 4);
else
if (vinfo->currentdepth==32)
color = egatorgb(attrib & 0x0F);
else
color = egatovga(attrib & 0x0F);
writepxl(currentfont->width*coordx + x, currentfont->height*coordy + y, color);
}
}
}
}
/******************************************************************************/
/* Retourne une couleur RGB 32 bits depuis une couleur EGA/VGA */
static convertega[]={0,1,2,3,4,5,20,7,56,57,58,59,60,61,62,63};
u8 egatovga(u8 ega)
{
return convertega[ega & 0xF];
}
/******************************************************************************/
/* Retourne une couleur RGB 32 bits depuis une couleur EGA/VGA */
static convertrgb[]={0x000000,0x0000AA,0x00AA00,0x00AAAA,0xAA0000,0xAA00AA,0xAA5500,0xAAAAAA,0x555555,0x5555FF,0x55FF55,0x55FFFF,0xFF5555,0xFF55FF,0xFFFF55,0xFFFFFF};
u32 egatorgb(u8 vga)
{
return convertrgb[vga & 0xF];
}
/******************************************************************************/
/* Retourne le caractère du mode texte aux coordonnées spécifiées */
u8 getchar (u16 coordx, u16 coordy)
{
u8 thechar=0;
if (!vinfo->isgraphic)
{
u32 addr=(coordx<<1)+vinfo->currentpitch*coordy;
video_to_mem(addr,&thechar,1);
}
return thechar;
}
/******************************************************************************/
/* Retourne l'attribut du mode texte aux coordonnées spécifiées */
u8 getattrib (u16 coordx, u16 coordy)
{
u8 attrib=0;
if (!vinfo->isgraphic)
{
u32 addr=(coordx<<1)+vinfo->currentpitch*coordy;
video_to_mem(addr+1,&attrib,1);
}
return attrib;
}
/******************************************************************************/
/* Affiche une ligne horizontale entre les points spécifiés */
void hline(u16 x1, u16 x2, u16 y, u32 color)
{
if (vinfo->isgraphic)
{
if (x2 > x1)
mem_to_video(color,(vinfo->currentdepth>>3)*x1+vinfo->currentpitch*y,x2-x1,false);
else
mem_to_video(color,(vinfo->currentdepth>>3)*x2+vinfo->currentpitch*y,x1-x2,false);
}
}
/******************************************************************************/
/* Affiche un pixel à l'écran */
void writepxl (u16 x, u16 y, u32 color)
{
if (vinfo->isgraphic)
{
u32 addr=(vinfo->currentdepth>>3)*x+vinfo->currentpitch*y;
mem_to_video(color,addr,1,false);
}
}
/******************************************************************************/
/* Chargement d'une police de caractère */
void loadfont(u8 *name,font* pointer,u8 width, u8 height)
{
u32 i;
for(i=0;i<MAXFONTS;i++)
if (fonts[i].nom[0]!=NULL && fonts[i].pointer==pointer)
return;
i=0;
while (fonts[i].nom[0]!=NULL && i<MAXFONTS)
i++;
fonts[i].pointer=pointer;
strcpy(name,fonts[i].nom);
fonts[i].width=width;
fonts[i].height=height;
if (fonts[i].nom[0]=='B' && fonts[i].nom[1]=='I' && fonts[i].nom[2]=='O' && fonts[i].nom[3]=='S')
{
u8 number=(fonts[i].nom[4]-'0');
font_load(pointer, height, number);
}
}
/******************************************************************************/
/* Changement de la police */
void setfont(u8 *fontname)
{
u32 i=0;
while (fonts[i].nom!=NULL && i<MAXFONTS) {
if (strcmp(fontname,fonts[i].nom)==0) {
currentfont=&fonts[i];
return;
}
i++;
}
}

View File

@ -11,7 +11,6 @@
#include "asm.h" #include "asm.h"
#include "cpu.h" #include "cpu.h"
#include "string.h" #include "string.h"
#include "2d.h"
#include "gdt.h" #include "gdt.h"
#include "shell.h" #include "shell.h"
#include "syscall.h" #include "syscall.h"