From 0cf9a6c9afe075fc5e9ea07f9d02dfaa8d7ed84a Mon Sep 17 00:00:00 2001 From: Lephenixnoir Date: Sun, 1 Jan 2023 21:32:11 +0100 Subject: [PATCH] merge latest public version from Ninestars --- CMakeLists.txt | 7 +- src/Geometry.cpp | 107 +++ src/Geometry.hpp | 47 + src/camera.cpp | 73 +- src/camera.hpp | 48 +- src/game.cpp | 20 +- src/game.hpp | 1 - src/main.cpp | 170 +++- src/main.hpp | 6 + src/map.cpp | 1630 ++++++-------------------------- src/scene_map.cpp | 214 ++--- src/windmill.cpp | 1790 ------------------------------------ src/windmill.hpp | 218 ++--- src/windmill_clip.cpp | 283 ++++++ src/windmill_draw.cpp | 946 +++++++++++++++++++ src/windmill_load.cpp | 257 ++++++ src/windmill_transform.cpp | 133 +++ src/windmill_utility.cpp | 240 +++++ 18 files changed, 2720 insertions(+), 3470 deletions(-) create mode 100644 src/Geometry.cpp create mode 100644 src/Geometry.hpp delete mode 100644 src/windmill.cpp create mode 100644 src/windmill_clip.cpp create mode 100644 src/windmill_draw.cpp create mode 100644 src/windmill_load.cpp create mode 100644 src/windmill_transform.cpp create mode 100644 src/windmill_utility.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b0b1b1b..9a4fd13 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,8 +10,13 @@ include(Fxconv) find_package(Gint 2.1 REQUIRED) set(SOURCES + src/Geometry.cpp src/main.cpp - src/windmill.cpp + src/windmill_load.cpp + src/windmill_draw.cpp + src/windmill_clip.cpp + src/windmill_transform.cpp + src/windmill_utility.cpp src/map.cpp src/scene_map.cpp src/camera.cpp diff --git a/src/Geometry.cpp b/src/Geometry.cpp new file mode 100644 index 0000000..e5005e9 --- /dev/null +++ b/src/Geometry.cpp @@ -0,0 +1,107 @@ +#include "Geometry.hpp" + +// VECTOR3D +Vector3D::Vector3D() +{ + x = 0; + y = 0; + z = 0; +} + +Vector3D::Vector3D(float _x, float _y, float _z) +{ + x = _x; + y = _y; + z = _z; +} + +Vector3D Vector3D::Add(Vector3D vector) +{ + return Vector3D(x + vector.x, y + vector.y, z + vector.z); +} + +Vector3D Vector3D::Substract(Vector3D vector) +{ + return Vector3D(x - vector.x, y - vector.y, z - vector.z); +} + +Vector3D Vector3D::Multiply(float value) +{ + return Vector3D(x * value, y * value, z * value); +} + +Vector3D Vector3D::Divide(float value) +{ + float inv = 1 / value; + return Vector3D(x * inv, y * inv, z * inv); +} + +float Vector3D::Dot(Vector3D vector) +{ + return x * vector.x + y * vector.y + z * vector.z; +} + +Vector3D Vector3D::Cross(Vector3D vector) +{ + return Vector3D(x * vector.y - y * vector.x, y * vector.z - z * vector.y, z * vector.x - x * vector.z); +} + +Point3D Vector3D::ToPoint3D() +{ + return Point3D(x, y, z); +} + +bool Vector3D::Null() +{ + return (x == 0 and y == 0 and z == 0); +} + + + +// POINT3D +Point3D::Point3D() +{ + x = 0; + y = 0; + z = 0; +} + +Point3D::Point3D(float _x, float _y, float _z) +{ + x = _x; + y = _y; + z = _z; +} + +Point3D Point3D::Add(Vector3D vector) +{ + return Point3D(x + vector.x, y + vector.y, z + vector.z); +} + +Point3D Point3D::Substract(Vector3D vector) +{ + return Point3D(x - vector.x, y - vector.y, z - vector.z); +} + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Geometry.hpp b/src/Geometry.hpp new file mode 100644 index 0000000..7c14a38 --- /dev/null +++ b/src/Geometry.hpp @@ -0,0 +1,47 @@ +#ifndef DEF_GEOMETRY +#define DEF_GEOMETRY + +class Point3D; +class Vector3D; + + +class Vector3D +{ +public: + Vector3D(); + Vector3D(float _x, float _y, float _z); + + Vector3D Add(Vector3D vector); + Vector3D Substract(Vector3D vector); + Vector3D Multiply(float value); + Vector3D Divide(float value); + + float Dot(Vector3D vector); + Vector3D Cross(Vector3D vector); + + Point3D ToPoint3D(); + bool Null(); + + float x; + float y; + float z; + +}; + +class Point3D +{ +public: + Point3D(); + Point3D(float _x, float _y, float _z); + + Point3D Add(Vector3D vector); + Point3D Substract(Vector3D vector); + Point3D Rotate(Vector3D rotation, float angle); + + + float x; + float y; + float z; +}; + +#endif \ No newline at end of file diff --git a/src/camera.cpp b/src/camera.cpp index 515f580..fa6aa18 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -10,19 +10,23 @@ Camera::Camera() z = 0; yaw = 0; pitch = 0; - fov = 50; - near = 1; + + fov = 50; // degrés + near = 5; far = 1000; - float fov_rad = to_rad(fov); - scale_coef = 64 * near * tanf(fov_rad); - cos_fov = SCALE_AI * cosf(fov_rad); + scale_coef = 128 / 2 * tanf(to_rad(fov)); // = 64 * 1 * 1,19 = 76,27 + //scale_coef2 = tanf(to_rad(fov)); // = 1 * 1,19 = 1.19 + + //cos_fov = SCALE_AI * cosf(fov_rad); //sin_fov = SCALE_AI * sinf(fov_rad); - sin_fov = sinf(fov_rad); - cos_fov_square = cosf(fov_rad) * cosf(fov_rad); + //sin_fov = sinf(fov_rad); + //cos_fov_square = cosf(fov_rad) * cosf(fov_rad); //near_coef = - far / float(far - near); //far_coef = - far * near * 128 / (far - near); + + setup_frustrum(); } @@ -52,11 +56,11 @@ void Camera::set(Camera* _camera) //----------------------------------------------------------------------------- void Camera::update() { - if (look_at_duration) + /*if (look_at_duration) { yaw = (yaw * (look_at_duration - 1) + look_at_yaw) / look_at_duration; look_at_duration -= 1; - } + }*/ cos_yaw = cosf(yaw); sin_yaw = sinf(yaw); @@ -86,7 +90,7 @@ void Camera::update() a9 = SCALE_AI * cos_pitch; } - +/* //----------------------------------------------------------------------------- // NORMAL_VECTOR //----------------------------------------------------------------------------- @@ -169,4 +173,53 @@ void Camera::look_at(float look_at_x, float look_at_y, float look_at_z, float du //look_at_pitch = atan2(look_at_z - z, look_at_x - x); // calcule de sqrt ?? look_at_duration = duration; +}*/ + + + +void Camera::setup_frustrum() +{ + float angle_horizontal = to_rad(fov); + float angle_vertical = to_rad(fov / 2); + int sh = sinf(angle_horizontal) * 1000; + int sv = sinf(angle_vertical) * 1000; + int ch = cosf(angle_horizontal) * 1000; + int cv = cosf(angle_vertical) * 1000; + + // z-near clipping plane + frustrum.sides[0].normal_x = 0; + frustrum.sides[0].normal_y = 0; + frustrum.sides[0].normal_z = 1; + frustrum.sides[0].distance = -near * 1000; + // right + frustrum.sides[1].normal_x = -ch; + frustrum.sides[1].normal_y = 0; + frustrum.sides[1].normal_z = sh; + frustrum.sides[1].distance = 0; + // top + frustrum.sides[2].normal_x = 0; + frustrum.sides[2].normal_y = cv; + frustrum.sides[2].normal_z = sv; + frustrum.sides[2].distance = 0; + // left + frustrum.sides[3].normal_x = ch; + frustrum.sides[3].normal_y = 0; + frustrum.sides[3].normal_z = sh; + frustrum.sides[3].distance = 0; + // bottom + frustrum.sides[4].normal_x = 0; + frustrum.sides[4].normal_y = -cv; + frustrum.sides[4].normal_z = sv; + frustrum.sides[4].distance = 0; + + // z-far clipping plane + //frustrum.z_far.normal.x = 0; + //frustrum.z_far.normal.y = 0; + //frustrum.z_far.normal.z = -1; + //frustrum.z_far.distance = 1000; } + + + + + diff --git a/src/camera.hpp b/src/camera.hpp index 5325ffe..a361989 100644 --- a/src/camera.hpp +++ b/src/camera.hpp @@ -43,15 +43,37 @@ #include #include +#include "Geometry.hpp" //#define PI 3.1415 -#define DEG 180.0 -#define to_rad(x) M_PI / DEG * x -#define to_deg(x) DEG / M_PI * x +//#define DEG 180.0 +#define to_rad(x) 3.1415f / 180.0f * x +#define to_deg(x) 180.0f / 3.1415f * x #define SCALE_AI 128 + +class Plane +{ +public: + int id; + //Vector3D normal; + int normal_x; + int normal_y; + int normal_z; + float distance; +}; + +class Frustrum +{ +public: + Plane sides[5]; +}; + + + + class Camera { public: @@ -77,6 +99,8 @@ public: void turn(float _yaw, float _pitch); + void setup_frustrum(); + //int min(int a, int b); //int max(int a, int b); @@ -86,6 +110,9 @@ public: float yaw, pitch; public: + + Frustrum frustrum; + int look_at_type; float look_at_yaw; float look_at_pitch; @@ -98,22 +125,25 @@ public: float cos_pitch, sin_pitch; float fov; - int cos_fov; + //int cos_fov; //int sin_fov; - float sin_fov; - float cos_fov_square; + //float sin_fov; + //float cos_fov_square; int scale_coef; + //float scale_coef2; int near; int far; - float near_coef; - int far_coef; + //float near_coef; + //int far_coef; - float normal_x, normal_y, normal_z; + //float normal_x, normal_y, normal_z; int a1, a2, a3, a4, a5, a6, a7, a8, a9; }; + + #endif diff --git a/src/game.cpp b/src/game.cpp index 941bf19..d5f8f8c 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1,5 +1,8 @@ #include "game.hpp" +extern Map map_exemple; +extern Map map_moulin; + //----------------------------------------------------------------------------- // GAME //----------------------------------------------------------------------------- @@ -15,19 +18,6 @@ Game::Game() void Game::new_game() { // pour exemple - //map = &map_exemple; - //map = &map_interieur_forgeron; // ICI LAUNCH GAME - player.teleport(0,0,0,0,0); - //player.dissociate_camera = true; - //scene_map.camera.set(-14,25,5,90,0); // de face - //player.teleport(25,-50,0,90,0); - //scene_map.camera.set(-14,1,5,-20,0); // de biais - - //map = &map_village; - - //scene_map.load_map(); - //player.teleport(-85.7, -77.5, 0, 40, 0); - //player.teleport(0, -5, 0, 0, 0); - //player.teleport(250.7, -110.7, 0, 26.8, 15.4); // bug chevauchement clip depth - //player.teleport(250.7, -110.7, 0, 319.6, 53.55); + map = &map_moulin; + player.teleport(-100,0,player.height,0,10); } diff --git a/src/game.hpp b/src/game.hpp index 45afddc..018ddf1 100644 --- a/src/game.hpp +++ b/src/game.hpp @@ -71,7 +71,6 @@ public: //Object* get_object(int id); //Collision_flag collision(float* new_x, float* new_y, float* new_z); - //bool CollisionDroiteSeg(Vecteur wall, Vecteur player); Map *map; diff --git a/src/main.cpp b/src/main.cpp index 8fe95e5..f97c9d0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,61 +1,161 @@ -#include "main.hpp" +/* + LISTE DES IDEES +O - objets dynamiques et statics +O - gérer la sphere qui chevauche pas pour simplifier le clipping +O - rotation n'importe quel axe +X - sprite de gint -> pas possible +O - compatibilité couleur + +*/ + +#include "main.hpp" +#include Game game; Windmill windmill; Scene_Map scene_map; + + int main(void) { + __printf_enable_fp(); + // Ecran principal extern bopti_image_t img_windmill; dclear(C_WHITE); dimage(16, 0, &img_windmill); - - int key = 0; - - while(key != KEY_EXE) - { - dupdate(); - - key = getkey().key; - } - - dclear(C_BLACK); + dprint_opt(64, 40, C_BLACK, C_WHITE, DTEXT_MIDDLE, DTEXT_BOTTOM, "Jour 26"); + int key = 0; + while(key != KEY_EXE) + { + dupdate(); + key = getkey().key; + } + dclear(C_BLACK); dupdate(); - - scene_map.launch(); - while(1) - { - /* (LEPHE) */ - clearevents(); - if (keydown(KEY_EXIT)) - break; - if (keydown(KEY_MENU)) - gint_osmenu(); - scene_map.draw(); - scene_map.update(); - } - scene_map.terminate(); + // initialise le moteur de jeu + game.new_game(); + scene_map.launch(); + int timer = timer_configure(TIMER_ANY, 25*1000, GINT_CALL(callback_tick)); + timer_start(timer); + + scene_map.update(); + + // boucle principale + while (1) + { + clearevents(); + if (keydown(KEY_EXIT)) + break; + if (keydown(KEY_MENU)) + gint_osmenu(); + + scene_map.draw(); + } + + timer_stop(timer); + scene_map.terminate(); getkey(); return 1; } + +static int callback_tick() +{ + scene_map.update(); + return TIMER_CONTINUE; +} + + + + + void debug_pop(char const *fmt, ...) { - dclear(C_WHITE); + static int id = 0; + id ++; - va_list args; - va_start(args, fmt); - char str[256]; - vsnprintf(str, 256, fmt, args); - va_end(args); + dclear(C_WHITE); - dtext(1, 1, C_BLACK, str); - dupdate(); - getkey(); + va_list args; + va_start(args, fmt); + char str[256]; + vsnprintf(str, 256, fmt, args); + va_end(args); + + char substr[256]; + + int line = 0; + int i = 0; + int subi = 0; + while (str[i] != '\0') + { + substr[subi] = str[i]; + + if (str[i] == '\n') + { + substr[subi] = '\0'; + dprint(1, 1+9*line, C_BLACK, substr); + line ++; + subi = 0; + } + else + { + subi++; + } + + i++; + } + + substr[subi] = '\0'; + dprint(1, 1+9*line, C_BLACK, substr); + dprint_opt(124, 60, C_BLACK, C_WHITE, DTEXT_RIGHT, DTEXT_BOTTOM, "%i", id); + + dupdate(); + getkey(); } + +void debug_display(char const *fmt, ...) +{ + va_list args; + va_start(args, fmt); + char str[256]; + vsnprintf(str, 256, fmt, args); + va_end(args); + + char substr[256]; + + int line = 0; + int i = 0; + int subi = 0; + while (str[i] != '\0') + { + substr[subi] = str[i]; + + if (str[i] == '\n') + { + substr[subi] = '\0'; + dprint(1, 1+9*line, C_BLACK, substr); + line ++; + subi = 0; + } + else + { + subi++; + } + + i++; + } + + substr[subi] = '\0'; + dprint(1, 1+9*line, C_BLACK, substr); + + dupdate(); +} + diff --git a/src/main.hpp b/src/main.hpp index fa288d3..e7b4d8e 100644 --- a/src/main.hpp +++ b/src/main.hpp @@ -1,9 +1,15 @@ #include #include #include +#include +#include #include #include "game.hpp" #include "windmill.hpp" #include "scene_map.hpp" + + +static int callback_tick(); +void debug_pop(char const *fmt, ...); \ No newline at end of file diff --git a/src/map.cpp b/src/map.cpp index e679fca..1214a06 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -12,445 +12,6 @@ #include "windmill.hpp" // SPRITES -const unsigned char sprite_brique_base[]={ - 0xff,0xff,0xff,0xff, - 0xa0,0x80,0x81,0x80, - 0x80,0x80,0x80,0x80, - 0x80,0x80,0x80,0x80, - 0xff,0xff,0xff,0xff, - 0x08,0x08,0x08,0x08, - 0x0c,0x08,0x08,0x08, - 0x0a,0x08,0x08,0x88, - 0xff,0xff,0xff,0xff, - 0x80,0x80,0x80,0x80, - 0x80,0x80,0x80,0x80, - 0x80,0x80,0x80,0x80, - 0xff,0xff,0xff,0xff, - 0x08,0x08,0x08,0x08, - 0x08,0x08,0x08,0x18, - 0x08,0x08,0x08,0x10, - 0xff,0xff,0xff,0xff, - 0x80,0x80,0x80,0x80, - 0x80,0x80,0x80,0x80, - 0x80,0x88,0x80,0x80, - 0xff,0xf7,0xff,0xff, - 0x08,0x08,0x08,0x08, - 0x08,0x08,0x08,0x0c, - 0x88,0x08,0x08,0x08, - 0xff,0xff,0xff,0xff, - 0x80,0x80,0x80,0x80, - 0x80,0x80,0x80,0x80, - 0x80,0x80,0x80,0x80, - 0xff,0xff,0xff,0xff, - 0xdd,0xdc,0xdd,0xfd, - 0xdd,0xdd,0xdd,0xdd, - 0xff,0xff,0xff,0xff, -}; - -const unsigned char sprite_brique[]={ - 0x80,0x80,0x80,0x80, - 0xa0,0x80,0x80,0x80, - 0x80,0x80,0x80,0x80, - 0xff,0xff,0xff,0xff, - 0x08,0x08,0x08,0x18, - 0x08,0x08,0x08,0x08, - 0x08,0x08,0x08,0x08, - 0xff,0xff,0xff,0xff, - 0x80,0xc0,0x80,0x80, - 0x80,0x80,0x80,0x80, - 0x80,0x80,0x81,0x80, - 0xff,0xff,0xfe,0xff, - 0x08,0x08,0x08,0x08, - 0x08,0x08,0x08,0x18, - 0x08,0x08,0x08,0x28, - 0xff,0xff,0xff,0xff, - 0x81,0x80,0x80,0x80, - 0x80,0x80,0x80,0x80, - 0x80,0x80,0x80,0x80, - 0xff,0xff,0xff,0xff, - 0x08,0x08,0x08,0x08, - 0x08,0x08,0x08,0x08, - 0x08,0x08,0x08,0x18, - 0xff,0xff,0xff,0xff, - 0x80,0x80,0x80,0x80, - 0x80,0x80,0xc0,0x80, - 0x88,0x80,0xa0,0x80, - 0xf7,0xff,0xff,0xff, - 0x08,0x08,0x08,0x08, - 0x08,0x08,0x08,0x18, - 0x08,0x08,0x48,0x08, - 0xff,0xff,0xff,0xff, -}; - -const unsigned char sprite_toit_tuile[]={ - 0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff, - 0x08,0x88,0x84,0x41, - 0x08,0x88,0x84,0x41, - 0x08,0x8c,0x8c,0x41, - 0x09,0x88,0x88,0x41, - 0x19,0x08,0x88,0x41, - 0x1d,0x18,0x8c,0x41, - 0xf7,0xb7,0xf6,0xe3, - 0x22,0xe6,0x33,0xbe, - 0x22,0x42,0x11,0x10, - 0x22,0x42,0x11,0x10, - 0x32,0x46,0x11,0x10, - 0x1e,0x65,0x39,0xd8, - 0xe5,0xdd,0xef,0x7d, - 0x84,0x84,0x44,0x27, - 0x84,0x84,0x44,0x21, - 0x8c,0x84,0x46,0x21, - 0xdc,0xcc,0x66,0x21, - 0x77,0xde,0xf7,0x73, - 0x42,0x73,0x9d,0xde, - 0x42,0x21,0x08,0x88, - 0x42,0x21,0x08,0x88, - 0x42,0x21,0x08,0x88, - 0x47,0x21,0x0d,0xdc, - 0xfd,0xf3,0x15,0x77, - 0x99,0x9e,0xf7,0x21, - 0x08,0x84,0x42,0x21, - 0x08,0x84,0x42,0x21, - 0x88,0x84,0x42,0x21, - 0x8d,0xcc,0xe6,0x73, - 0xff,0xff,0xff,0xff, -}; - -const unsigned char sprite_paille[]={ - 0x5a,0x95, - 0x58,0x95, - 0x5a,0x95, - 0x5e,0xd5, - 0xd2,0xd0, - 0xd3,0x59, - 0x93,0x59, - 0x37,0x49, - 0x36,0x49, - 0x26,0x49, - 0x24,0xcb, - 0xa4,0xeb, - 0xa9,0xaa, - 0xe9,0xaa, - 0x69,0xaa, - 0x49,0x8a, -}; - -const unsigned char sprite_paille_dessus[]={ - 0x88,0x88, - 0x22,0x22, - 0x88,0x88, - 0x22,0x22, - 0x88,0x88, - 0x22,0x22, - 0x88,0x88, - 0x22,0x22, - 0x88,0x88, - 0x22,0x22, - 0x88,0x88, - 0x22,0x22, - 0x88,0x88, - 0x22,0x22, - 0x88,0x88, - 0x22,0x22, -}; - -const unsigned char sprite_mur_moulin[]={ - 0x81,0x02,0x08,0x73, - 0x81,0x02,0x08,0x4d, - 0x81,0x02,0x08,0x41, - 0x81,0x02,0x08,0x41, - 0x81,0x02,0x08,0x41, - 0x81,0x02,0x08,0x41, - 0x81,0x02,0x09,0xc1, - 0x81,0x1e,0x0e,0x41, - 0x81,0xe2,0x08,0x41, - 0x81,0x02,0x08,0x41, - 0x81,0x02,0x08,0x41, - 0x81,0x02,0x48,0x41, - 0x81,0x02,0xa8,0x41, - 0x81,0x03,0x18,0x79, - 0x81,0x02,0x08,0x47, - 0x81,0x02,0x08,0x41, - 0xf9,0x02,0x08,0x41, - 0x87,0x04,0x08,0x21, - 0x81,0x04,0x08,0x21, - 0x81,0x04,0x08,0x21, - 0x81,0x04,0x08,0x21, - 0x81,0x04,0x0e,0x61, - 0x81,0x04,0x09,0xa1, - 0x81,0x04,0x08,0x21, - 0x81,0x04,0x08,0x21, - 0x81,0x3c,0x08,0x21, - 0x81,0xc4,0x08,0x21, - 0x81,0x04,0x08,0x21, - 0x81,0x04,0x08,0x31, - 0x99,0x04,0x08,0x2f, - 0xe7,0x04,0x08,0x21, - 0x81,0x07,0xf8,0x21, -}; - -const unsigned char sprite_pale_moulin[]={ - 0xff,0xff, - 0x87,0xe1, - 0x87,0xe1, - 0x8f,0xf1, - 0x8f,0xf1, - 0x9b,0xd9, - 0x9b,0xd9, - 0xb3,0xcd, - 0xb3,0xcd, - 0xe7,0xe7, - 0xe7,0xe7, - 0xc7,0xe3, - 0xff,0xff, - 0xc7,0xe3, - 0xc7,0xe3, - 0xc7,0xe3, - 0xc7,0xe3, - 0xc7,0xe3, - 0xc5,0xa3, - 0xcd,0xb3, - 0xcd,0xb3, - 0xff,0xff, - 0xcd,0xb3, - 0xcd,0xb3, - 0xcd,0xb3, - 0xcd,0xb3, - 0xcd,0xb3, - 0xd9,0x9b, - 0xff,0xff, - 0xd9,0x9b, - 0xd9,0x9b, - 0xd9,0x9b, - 0xd9,0x9b, - 0xd9,0x9b, - 0xd9,0x9b, - 0xd9,0x9b, - 0xd1,0x8b, - 0xff,0xff, - 0xf1,0x8f, - 0xf1,0x8f, - 0xf1,0x8f, - 0xf1,0x8f, - 0xf1,0x8f, - 0xf1,0x8f, - 0xf1,0x8f, - 0xff,0xff, - 0xe1,0x87, - 0xe1,0x87, - 0xe1,0x87, - 0xe1,0x87, - 0xe1,0x87, - 0xe1,0x87, - 0xe1,0x87, - 0xe1,0x87, - 0xff,0xff, - 0xc1,0x83, - 0xc1,0x83, - 0xc1,0x83, - 0xc1,0x83, - 0xc1,0x83, - 0xc1,0x83, - 0xff,0xff, - 0xff,0xff, - 0xff,0xff, -}; - -const unsigned char sprite_fenetre_simple[]={ - 0xff,0xff, - 0xc1,0x03, - 0xc1,0x03, - 0xc1,0x03, - 0xc1,0x03, - 0xff,0xff, - 0xc1,0x03, - 0xc1,0x03, - 0xc1,0x03, - 0xff,0xff, - 0xc1,0x03, - 0xc1,0x03, - 0xc1,0x03, - 0xc1,0x03, - 0xff,0xff, - 0xff,0xff, -}; - -const unsigned char sprite_porte_simple[]={ - 0xff,0xff, - 0x80,0x01, - 0x80,0x01, - 0xff,0xff, - 0xff,0xff, - 0xe0,0x07, - 0xc9,0x43, - 0xc9,0x4b, - 0xc9,0x4b, - 0xc1,0x0b, - 0xc9,0x0b, - 0xc9,0x4b, - 0xc9,0x43, - 0xc8,0x43, - 0xc8,0x4b, - 0xc9,0x4b, - 0xc1,0x03, - 0xc9,0x3b, - 0xc9,0x3b, - 0xc9,0x2b, - 0xc9,0x13, - 0xc9,0x03, - 0xc8,0x03, - 0xc8,0x43, - 0xc8,0x43, - 0xc9,0x4b, - 0xc1,0x4b, - 0xc9,0x4b, - 0xc9,0x4b, - 0xc9,0x0b, - 0xc0,0x03, - 0xff,0xff, -}; - -const unsigned char sprite_pierre_eglise[]={ - 0xe0,0x00,0x00,0x07, - 0x20,0x00,0x00,0x04, - 0xe0,0x00,0x00,0x07, - 0x40,0x00,0x00,0x02, - 0x40,0x00,0x00,0x02, - 0xe0,0x00,0x00,0x07, - 0x20,0x00,0x00,0x04, - 0xe0,0x00,0x00,0x07, - 0x40,0x00,0x00,0x02, - 0x40,0x00,0x00,0x02, - 0xe0,0x00,0x00,0x07, - 0x20,0x00,0x00,0x04, - 0xe0,0x00,0x00,0x07, - 0x40,0x00,0x00,0x02, - 0x40,0x00,0x00,0x02, - 0x40,0x00,0x00,0x02, -}; - -const unsigned char sprite_pierre_eglise2[]={ - 0x40,0x00,0x00,0x02, - 0x40,0x00,0x00,0x02, - 0x40,0x00,0x00,0x02, - 0xe0,0x00,0x00,0x07, - 0x20,0x00,0x00,0x04, - 0xe0,0x00,0x00,0x07, - 0x40,0x00,0x00,0x02, - 0x40,0x00,0x00,0x02, - 0xe0,0x00,0x00,0x07, - 0x20,0x00,0x00,0x04, - 0xe0,0x00,0x00,0x07, - 0x40,0x00,0x00,0x02, - 0x40,0x00,0x00,0x02, - 0xe0,0x00,0x00,0x07, - 0x20,0x00,0x00,0x04, - 0xe0,0x00,0x00,0x07, -}; - -const unsigned char sprite_horloge[]={ - 0x00,0x7f,0xfe,0x00, - 0x01,0x80,0x01,0x80, - 0x06,0x02,0xc0,0x60, - 0x08,0x82,0x41,0x10, - 0x10,0x02,0x80,0x08, - 0x24,0x02,0xc0,0x24, - 0x20,0x00,0x00,0x04, - 0x40,0x00,0x00,0x02, - 0x50,0x00,0x00,0x0a, - 0x80,0x00,0x00,0x01, - 0x80,0x00,0x00,0x01, - 0x80,0x00,0x00,0x01, - 0x80,0x00,0x00,0x01, - 0x90,0x00,0x00,0x0d, - 0xa8,0x01,0x80,0x05, - 0x98,0x01,0x80,0x0d, - 0x88,0x00,0x00,0x05, - 0x90,0x00,0x00,0x0d, - 0x80,0x00,0x00,0x01, - 0x80,0x00,0x00,0x01, - 0x80,0x00,0x00,0x01, - 0x80,0x00,0x00,0x01, - 0x80,0x00,0x00,0x01, - 0x50,0x00,0x00,0x12, - 0x40,0x00,0x00,0x02, - 0x20,0x01,0x00,0x04, - 0x24,0x02,0x00,0x24, - 0x10,0x03,0x00,0x08, - 0x08,0x82,0x81,0x10, - 0x06,0x01,0x00,0x60, - 0x01,0x80,0x01,0x80, - 0x00,0x7f,0xfe,0x00, -}; - -const unsigned char sprite_porte_eglise[]={ - 0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00, - 0x00,0x3f,0xfc,0x00, - 0x00,0xc0,0x83,0x00, - 0x03,0x05,0x28,0xc0, - 0x04,0x90,0x03,0x20, - 0x0a,0x41,0x20,0x10, - 0x10,0x10,0x0a,0xa8, - 0x23,0x12,0x10,0x04, - 0x24,0x00,0x44,0x24, - 0x50,0xbf,0xfc,0x92, - 0x44,0xff,0xff,0x12, - 0x93,0xc1,0x83,0xc5, - 0xd7,0x01,0x80,0xe1, - 0x9c,0x01,0x80,0x35, - 0xf8,0x01,0x80,0x19, - 0xb0,0x01,0x80,0x0d, - 0xa0,0x01,0x80,0x05, - 0xe0,0x01,0x80,0x07, - 0xc0,0x01,0x80,0x83, - 0xc0,0x81,0x80,0x03, - 0x80,0x01,0x80,0x01, - 0x80,0x01,0x80,0x01, - 0x80,0x01,0x80,0x01, - 0x80,0x01,0x80,0x01, - 0x80,0x01,0x80,0x01, - 0x80,0x01,0x82,0x01, - 0x80,0x01,0x82,0x01, - 0xc0,0x01,0x82,0x03, - 0xc0,0x01,0x80,0x03, - 0x80,0x01,0x80,0x01, - 0x80,0x01,0x80,0x01, - 0x80,0x01,0x80,0x01, - 0x80,0x01,0x80,0x01, - 0x80,0x01,0x80,0x01, - 0x80,0x81,0x80,0x01, - 0x80,0x01,0x80,0x01, - 0x80,0x01,0x80,0x01, - 0x80,0x01,0x80,0x01, - 0x80,0x1d,0xb8,0x01, - 0x80,0x09,0x90,0x01, - 0x80,0x15,0xa8,0x01, - 0x80,0x09,0x90,0x01, - 0x80,0x01,0x80,0x01, - 0x80,0x01,0x80,0xf1, - 0x80,0x01,0x80,0x01, - 0x80,0x01,0x80,0x01, - 0x80,0x01,0x80,0x01, - 0xc0,0x01,0x80,0x03, - 0xc0,0x01,0x80,0x03, - 0x80,0x01,0x80,0x01, - 0x80,0x01,0x80,0x01, - 0x80,0x01,0x80,0x01, - 0x80,0x01,0x80,0x01, - 0xff,0xff,0xff,0xff, -}; - const unsigned char sprite_planche_bois[]={ 0x81,0x04,0x08,0x20, 0xff,0x04,0x08,0x20, @@ -486,942 +47,311 @@ const unsigned char sprite_planche_bois[]={ 0xa5,0x07,0xf8,0x20, }; -const unsigned char sprite_haie[]={ - 0x80,0x01, - 0xff,0xff, - 0x80,0x01, - 0x80,0x01, - 0x80,0x01, - 0xff,0xff, - 0x80,0x01, - 0x80,0x01, -}; - -const unsigned char sprite_epouvantail[]={ - 0x00,0x00, - 0x03,0x8c, - 0x06,0xd0, - 0x04,0x20, - 0x0f,0xf0, - 0x04,0x20, - 0x04,0x20, - 0x06,0x60, - 0x03,0xc0, - 0x01,0x80, - 0xe1,0x80, - 0xff,0xfc, - 0x3f,0xff, - 0x04,0x23, - 0x04,0xa0, - 0x04,0xa0, - 0x04,0x20, - 0x06,0x20, - 0x04,0x20, - 0x04,0x20, - 0x05,0x20, - 0x04,0x20, - 0x04,0x60, - 0x04,0xa0, - 0x07,0xe0, - 0x03,0xc0, - 0x03,0xc0, - 0x03,0xc0, - 0x01,0x80, - 0x01,0x80, - 0x01,0x80, - 0x01,0x80, -}; - -const unsigned char sprite_epouvantail_masque[]={ - 0x00,0x00, - 0x03,0x8c, - 0x07,0xd0, - 0x07,0xe0, - 0x0f,0xf0, - 0x07,0xe0, - 0x07,0xe0, - 0x07,0xe0, - 0x03,0xc0, - 0x01,0x80, - 0xe1,0x80, - 0xff,0xfc, - 0x3f,0xff, - 0x07,0xe3, - 0x07,0xe0, - 0x07,0xe0, - 0x07,0xe0, - 0x07,0xe0, - 0x07,0xe0, - 0x07,0xe0, - 0x07,0xe0, - 0x07,0xe0, - 0x07,0xe0, - 0x07,0xe0, - 0x07,0xe0, - 0x03,0xc0, - 0x03,0xc0, - 0x03,0xc0, - 0x01,0x80, - 0x01,0x80, - 0x01,0x80, - 0x01,0x80, -}; - -const unsigned char sprite_herbe[]={ - 0x08,0x00, - 0x48,0x20, - 0x49,0x22, - 0x44,0x92, - 0x44,0x94, - 0x25,0x15, - 0x25,0x15, - 0x25,0x15, -}; - -const unsigned char sprite_panneau[]={ - 0xff,0xff, - 0x80,0x01, - 0x80,0x01, - 0x80,0x01, - 0x92,0xb1, - 0xb5,0x95, - 0x94,0xb5, - 0x80,0x01, - 0x80,0x01, - 0x95,0x6d, - 0x95,0x45, - 0xa2,0x65, - 0x80,0x01, - 0x80,0x01, - 0x80,0x01, - 0xff,0xff, -}; - -const unsigned char sprite_mur_int_maison[]={ - 0xff,0xff, - 0x98,0x19, - 0xb0,0x0d, - 0xe0,0x07, - 0xc0,0x03, - 0x80,0x01, - 0x80,0x01, - 0x80,0x01, - 0x80,0x01, - 0x80,0x01, - 0x80,0x01, - 0x80,0x01, - 0x80,0x01, - 0x80,0x01, - 0x80,0x01, - 0x80,0x01, - 0x80,0x01, - 0x80,0x01, - 0x80,0x01, - 0x80,0x01, - 0xff,0xff, - 0xff,0xff, - 0x91,0x11, - 0x91,0x11, - 0x91,0x11, - 0x91,0x11, - 0x91,0x11, - 0x91,0x11, - 0x91,0x11, - 0x91,0x11, - 0x91,0x11, - 0xff,0xff, -}; - -const unsigned char sprite_planche[]={ +const unsigned char sprite_toit_tuile[]={ 0xff,0xff,0xff,0xff, - 0x80,0x00,0x00,0x01, - 0x80,0x00,0x00,0x01, - 0x80,0x00,0x00,0x01, - 0x80,0x04,0x00,0x81, - 0x80,0x00,0x00,0x01, - 0x80,0x00,0x00,0x01, - 0x80,0x00,0x80,0x01, - 0x80,0x00,0x00,0x01, - 0x82,0x00,0x00,0x01, - 0x80,0x00,0x00,0x01, - 0x80,0x00,0x00,0x01, - 0x80,0x00,0x00,0x01, - 0x80,0x00,0x00,0x41, - 0x80,0x00,0x00,0x01, 0xff,0xff,0xff,0xff, + 0x08,0x88,0x84,0x41, + 0x08,0x88,0x84,0x41, + 0x08,0x8c,0x8c,0x41, + 0x09,0x88,0x88,0x41, + 0x19,0x08,0x88,0x41, + 0x1d,0x18,0x8c,0x41, + 0xf7,0xb7,0xf6,0xe3, + 0x22,0xe6,0x33,0xbe, + 0x22,0x42,0x11,0x10, + 0x22,0x42,0x11,0x10, + 0x32,0x46,0x11,0x10, + 0x1e,0x65,0x39,0xd8, + 0xe5,0xdd,0xef,0x7d, + 0x84,0x84,0x44,0x27, + 0x84,0x84,0x44,0x21, + 0x8c,0x84,0x46,0x21, + 0xdc,0xcc,0x66,0x21, + 0x77,0xde,0xf7,0x73, + 0x42,0x73,0x9d,0xde, + 0x42,0x21,0x08,0x88, + 0x42,0x21,0x08,0x88, + 0x42,0x21,0x08,0x88, + 0x47,0x21,0x0d,0xdc, + 0xfd,0xf3,0x15,0x77, + 0x99,0x9e,0xf7,0x21, + 0x08,0x84,0x42,0x21, + 0x08,0x84,0x42,0x21, + 0x88,0x84,0x42,0x21, + 0x8d,0xcc,0xe6,0x73, + 0xff,0xff,0xff,0xff }; - -const unsigned char sprite_exemple[]={ +const unsigned char sprite_brique[]={ + 0x80,0x80,0x80,0x80, + 0xa0,0x80,0x80,0x80, + 0x80,0x80,0x80,0x80, 0xff,0xff,0xff,0xff, - 0x87,0xff,0xfc,0x01, - 0xb4,0x00,0x05,0xfd, - 0xb4,0x00,0x05,0xfd, - 0x84,0x00,0x04,0x01, - 0xfc,0x00,0x07,0xff, - 0xc0,0x00,0x00,0x01, - 0xc0,0xfc,0x00,0x01, - 0xc3,0x86,0x00,0x01, - 0xcc,0x03,0x00,0x01, - 0xc9,0x99,0x00,0x01, - 0xc9,0x99,0x07,0xff, - 0xc8,0x01,0x04,0x01, - 0xc8,0x01,0x04,0x01, - 0xc8,0xf1,0x04,0x01, - 0xcc,0x62,0xff,0xff, - 0xc6,0x06,0x80,0x21, - 0xc3,0xfc,0x80,0x21, - 0xc0,0x00,0x80,0x21, - 0xc0,0x00,0xff,0xff, - 0xc0,0x00,0x04,0x01, - 0xc0,0x00,0x04,0x01, - 0xc0,0x00,0x04,0x01, - 0xc0,0x00,0x07,0xff, - 0xc0,0x00,0x00,0x01, - 0xc0,0x00,0x80,0x01, - 0xfc,0x01,0xc0,0x3f, - 0xc4,0x03,0xe0,0x3f, - 0xa4,0x07,0x70,0x33, - 0x94,0x0e,0x38,0x33, - 0x8f,0xff,0xff,0xff, + 0x08,0x08,0x08,0x18, + 0x08,0x08,0x08,0x08, + 0x08,0x08,0x08,0x08, 0xff,0xff,0xff,0xff, -}; - -/* -const unsigned char sprite_mur_colombage[]={ + 0x80,0xc0,0x80,0x80, + 0x80,0x80,0x80,0x80, + 0x80,0x80,0x81,0x80, + 0xff,0xff,0xfe,0xff, + 0x08,0x08,0x08,0x08, + 0x08,0x08,0x08,0x18, + 0x08,0x08,0x08,0x28, 0xff,0xff,0xff,0xff, - 0xc0,0x00,0x00,0x03, - 0xc0,0x00,0x00,0x03, - 0xe0,0x00,0x00,0x07, - 0xe0,0x3f,0xfc,0x07, - 0xe0,0x20,0x84,0x07, - 0xb0,0x20,0x84,0x0d, - 0xb0,0x20,0x84,0x0d, - 0xb0,0x20,0x84,0x0d, - 0x98,0x20,0x84,0x19, - 0x98,0x3f,0xfc,0x19, - 0x98,0x20,0x84,0x19, - 0x8c,0x20,0x84,0x31, - 0x8c,0x20,0x84,0x31, - 0xff,0xe0,0x87,0xff, - 0xff,0xe0,0x87,0xff, - 0x86,0x20,0x84,0x61, - 0x83,0x3f,0xfc,0xe1, - 0x83,0x20,0x84,0xc1, - 0x83,0x20,0x84,0xc1, - 0x81,0xa0,0x85,0x81, - 0x81,0xa0,0x85,0x81, - 0x81,0xbf,0xfd,0x81, - 0x80,0xc0,0x03,0x01, - 0x80,0xc0,0x03,0x01, - 0x80,0xc0,0x03,0x01, - 0x80,0x60,0x06,0x01, - 0x80,0x60,0x06,0x01, - 0x80,0x60,0x06,0x01, - 0x80,0x30,0x0c,0x01, - 0x80,0x30,0x0c,0x01, + 0x81,0x80,0x80,0x80, + 0x80,0x80,0x80,0x80, + 0x80,0x80,0x80,0x80, 0xff,0xff,0xff,0xff, + 0x08,0x08,0x08,0x08, + 0x08,0x08,0x08,0x08, + 0x08,0x08,0x08,0x18, + 0xff,0xff,0xff,0xff, + 0x80,0x80,0x80,0x80, + 0x80,0x80,0xc0,0x80, + 0x88,0x80,0xa0,0x80, + 0xf7,0xff,0xff,0xff, + 0x08,0x08,0x08,0x08, + 0x08,0x08,0x08,0x18, + 0x08,0x08,0x48,0x08, + 0xff,0xff,0xff,0xff }; -const unsigned char sprite_plaque_egout[]={ - 0x07,0xe0, - 0x18,0x18, - 0x21,0x04, - 0x40,0x02, - 0x48,0x82, - 0x80,0x01, - 0x80,0x11, - 0x82,0x21, - 0x84,0x81, - 0x80,0x21, - 0x90,0x01, - 0x41,0x02, - 0x40,0x02, - 0x20,0x04, - 0x18,0x18, - 0x07,0xe0, +const unsigned char sprite_mur_moulin[]={ + 0x81,0x02,0x08,0x73, + 0x81,0x02,0x08,0x4d, + 0x81,0x02,0x08,0x41, + 0x81,0x02,0x08,0x41, + 0x81,0x02,0x08,0x41, + 0x81,0x02,0x08,0x41, + 0x81,0x02,0x09,0xc1, + 0x81,0x1e,0x0e,0x41, + 0x81,0xe2,0x08,0x41, + 0x81,0x02,0x08,0x41, + 0x81,0x02,0x08,0x41, + 0x81,0x02,0x48,0x41, + 0x81,0x02,0xa8,0x41, + 0x81,0x03,0x18,0x79, + 0x81,0x02,0x08,0x47, + 0x81,0x02,0x08,0x41, + 0xf9,0x02,0x08,0x41, + 0x87,0x04,0x08,0x21, + 0x81,0x04,0x08,0x21, + 0x81,0x04,0x08,0x21, + 0x81,0x04,0x08,0x21, + 0x81,0x04,0x0e,0x61, + 0x81,0x04,0x09,0xa1, + 0x81,0x04,0x08,0x21, + 0x81,0x04,0x08,0x21, + 0x81,0x3c,0x08,0x21, + 0x81,0xc4,0x08,0x21, + 0x81,0x04,0x08,0x21, + 0x81,0x04,0x08,0x31, + 0x99,0x04,0x08,0x2f, + 0xe7,0x04,0x08,0x21, + 0x81,0x07,0xf8,0x21 +}; + +const unsigned char sprite_pale_moulin[]={ + 0x3, 0xc0, + 0x7, 0xe0, + 0x7, 0xe0, + 0xf, 0xf0, + 0xf, 0xf0, + 0x19, 0x98, + 0x19, 0x98, + 0x31, 0x8c, + 0x31, 0x8c, + 0x61, 0x86, + 0xe1, 0x87, + 0xc1, 0x83, + 0xff, 0xff, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0xff, 0xff, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0xff, 0xff, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0xff, 0xff, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0xff, 0xff, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0xff, 0xff, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0x80, 0x81, + 0xff, 0xff }; - -const unsigned char sprite_pancarte_forgeron[]={ - 0xff,0xff, - 0x80,0x01, - 0x80,0x01, - 0x80,0x01, - 0xbf,0x81, - 0xbf,0xfd, - 0x9f,0xf9, - 0x87,0xe1, - 0x87,0xe1, - 0x83,0xc1, - 0x83,0xc1, - 0x8f,0xf1, - 0x9f,0xf9, - 0x80,0x01, - 0x80,0x01, - 0xff,0xff, -}; - - - -const unsigned char sprite_comptoire[]={ - 0x88,0x88, - 0x88,0x88, - 0x88,0x88, - 0x88,0x88, - 0xaa,0xaa, - 0x88,0x88, - 0x88,0x88, - 0x88,0x88, -}; - -const unsigned char sprite_trappe[]={ - 0xff,0xff, - 0x88,0x89, - 0x88,0x89, - 0x88,0x89, - 0x88,0x89, - 0x88,0x89, - 0x88,0x89, - 0x88,0x89, - 0x88,0x89, - 0x88,0x89, - 0x88,0x09, - 0x89,0xc9, - 0x89,0x49, - 0x89,0xc9, - 0x88,0x09, - 0xff,0xff, -}; - - - -const unsigned char sprite_arbre1[]={ - 0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00, - 0x00,0x07,0x80,0x00, - 0x00,0x08,0x7c,0x00, - 0x00,0x10,0x04,0x00, - 0x03,0x60,0x0b,0x80, - 0x04,0x80,0x04,0x40, - 0x04,0x00,0x00,0x40, - 0x04,0x00,0x00,0x20, - 0x08,0x78,0x00,0x10, - 0x14,0x07,0xc0,0x08, - 0x12,0x00,0x00,0x04, - 0x20,0x00,0x00,0x04, - 0x40,0x00,0x00,0x06, - 0x40,0x00,0x00,0xc6, - 0x40,0x00,0x03,0x04, - 0xe0,0x01,0x3c,0x04, - 0xa0,0x01,0xc0,0x06, - 0x9e,0x80,0x00,0x02, - 0x83,0x80,0x00,0x02, - 0x80,0x00,0x00,0x02, - 0x80,0x00,0x00,0x02, - 0x80,0x00,0x00,0x03, - 0x80,0x00,0x00,0x05, - 0x80,0x00,0x0c,0x05, - 0x88,0x00,0x0c,0x1d, - 0x88,0x1f,0x00,0x01, - 0x4e,0x08,0x00,0x06, - 0x70,0x00,0x00,0x01, - 0x10,0x00,0x00,0x01, - 0x60,0x00,0x00,0x01, - 0x40,0x00,0x30,0x09, - 0x50,0x00,0xc0,0x05, - 0x50,0x00,0x00,0x0e, - 0x40,0x00,0x00,0x08, - 0x48,0x00,0x00,0x84, - 0x74,0x00,0x00,0x04, - 0x07,0x7f,0x80,0xf8, - 0x00,0x89,0xff,0x80, - 0x00,0x06,0x51,0x00, - 0x00,0x05,0x50,0x80, - 0x00,0x04,0x10,0x00, - 0x00,0x04,0xd0,0x00, - 0x00,0x04,0xd0,0x00, - 0x00,0x04,0x10,0x00, - 0x00,0x04,0x90,0x00, - 0x00,0x05,0x30,0x00, - 0x00,0x05,0x30,0x00, - 0x00,0x05,0x30,0x00, - 0x00,0x05,0x30,0x00, - 0x00,0x04,0x10,0x00, - 0x00,0x04,0x10,0x00, - 0x00,0x06,0x10,0x00, - 0x00,0x05,0x50,0x00, - 0x00,0x04,0x50,0x00, - 0x00,0x04,0x50,0x00, - 0x00,0x04,0x90,0x00, - 0x00,0x04,0x50,0x00, - 0x00,0x04,0x30,0x00, - 0x00,0x05,0x10,0x00, - 0x00,0x05,0x10,0x00, - 0x00,0x0f,0x78,0x00, - 0x00,0x31,0xc4,0x00, - 0x00,0x02,0x20,0x00, -}; - -const unsigned char mask_arbre1[]={ - 0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00, - 0x00,0x07,0x80,0x00, - 0x00,0x0f,0xfc,0x00, - 0x00,0x1f,0xfc,0x00, - 0x03,0x7f,0xfb,0x80, - 0x07,0xff,0xff,0xc0, - 0x07,0xff,0xff,0xc0, - 0x07,0xff,0xff,0xe0, - 0x0f,0xff,0xff,0xf0, - 0x1f,0xff,0xff,0xf8, - 0x1f,0xff,0xff,0xfc, - 0x3f,0xff,0xff,0xfc, - 0x7f,0xff,0xff,0xfe, - 0x7f,0xff,0xff,0xfe, - 0x7f,0xff,0xff,0xfc, - 0xff,0xff,0xff,0xfc, - 0xff,0xff,0xff,0xfe, - 0xff,0xff,0xff,0xfe, - 0xff,0xff,0xff,0xfe, - 0xff,0xff,0xff,0xfe, - 0xff,0xff,0xff,0xfe, - 0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff, - 0x7f,0xff,0xff,0xfe, - 0x7f,0xff,0xff,0xff, - 0x1f,0xff,0xff,0xff, - 0x7f,0xff,0xff,0xff, - 0x7f,0xff,0xff,0xff, - 0x7f,0xff,0xff,0xff, - 0x7f,0xff,0xff,0xfe, - 0x7f,0xff,0xff,0xf8, - 0x7f,0xff,0xff,0xfc, - 0x77,0xff,0xff,0xfc, - 0x07,0xff,0xff,0xf8, - 0x00,0x8f,0xff,0x80, - 0x00,0x07,0xf1,0x00, - 0x00,0x07,0xf0,0x80, - 0x00,0x07,0xf0,0x00, - 0x00,0x07,0xf0,0x00, - 0x00,0x07,0xf0,0x00, - 0x00,0x07,0xf0,0x00, - 0x00,0x07,0xf0,0x00, - 0x00,0x07,0xf0,0x00, - 0x00,0x07,0xf0,0x00, - 0x00,0x07,0xf0,0x00, - 0x00,0x07,0xf0,0x00, - 0x00,0x07,0xf0,0x00, - 0x00,0x07,0xf0,0x00, - 0x00,0x07,0xf0,0x00, - 0x00,0x07,0xf0,0x00, - 0x00,0x07,0xf0,0x00, - 0x00,0x07,0xf0,0x00, - 0x00,0x07,0xf0,0x00, - 0x00,0x07,0xf0,0x00, - 0x00,0x07,0xf0,0x00, - 0x00,0x07,0xf0,0x00, - 0x00,0x07,0xf0,0x00, - 0x00,0x0f,0xf8,0x00, - 0x00,0x31,0xc4,0x00, - 0x00,0x02,0x20,0x00, -}; -*/ -// Personnages -const unsigned char sprite_forgeron[]={ - 0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00, - 0x00,0x07,0xc0,0x00, - 0x00,0x18,0x30,0x00, - 0x00,0x20,0x08,0x00, - 0x00,0x2f,0xe8,0x00, - 0x00,0x24,0x48,0x00, - 0x00,0x25,0x48,0x00, - 0x00,0x21,0x08,0x00, - 0x00,0x20,0x08,0x00, - 0x00,0x23,0x88,0x00, - 0x00,0x30,0x18,0x00, - 0x00,0x3f,0xf8,0x00, - 0x00,0x1f,0xf0,0x00, - 0x03,0xff,0xff,0xc0, - 0x04,0x6f,0xe6,0x20, - 0x08,0x63,0x86,0x10, - 0x08,0x50,0x09,0x10, - 0x08,0x90,0x09,0x10, - 0x08,0x8f,0xf1,0x10, - 0x08,0x80,0x03,0x90, - 0x08,0xe1,0xfe,0x50, - 0x08,0xfe,0x02,0x50, - 0x08,0x80,0x03,0xd0, - 0x08,0x01,0xfe,0x10, - 0x08,0x0f,0xf0,0x10, - 0x07,0xf0,0x0f,0xe0, - 0x01,0x00,0x00,0x80, - 0x01,0x00,0x00,0x80, - 0x01,0x00,0x00,0x80, - 0x01,0x00,0x00,0x80, - 0x01,0x00,0x70,0x80, - 0x01,0x00,0x70,0x80, - 0x01,0x00,0x24,0x80, - 0x01,0x10,0x28,0x80, - 0x01,0x0f,0xf0,0x80, - 0x02,0x00,0x00,0x40, - 0x02,0x00,0x00,0x40, - 0x02,0x00,0x10,0x40, - 0x02,0x0c,0x60,0x40, - 0x02,0x00,0x00,0x40, - 0x03,0xff,0xff,0xc0, - 0x00,0x42,0x42,0x00, - 0x00,0x5a,0x5a,0x00, - 0x00,0x42,0x42,0x00, - 0x00,0x42,0x42,0x00, - 0x00,0x42,0x42,0x00, - 0x00,0x42,0x42,0x00, - 0x00,0x42,0x42,0x00, - 0x00,0x42,0x42,0x00, - 0x00,0x42,0x42,0x00, - 0x00,0x42,0x42,0x00, - 0x00,0x7e,0x7e,0x00, - 0x00,0x42,0x42,0x00, - 0x00,0x5a,0x5a,0x00, - 0x00,0x66,0x66,0x00, - 0x00,0x66,0x66,0x00, - 0x00,0x7e,0x7e,0x00, -}; - -const unsigned char mask_forgeron[]={ - 0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00, - 0x00,0x07,0xc0,0x00, - 0x00,0x1f,0xf0,0x00, - 0x00,0x3f,0xf8,0x00, - 0x00,0x3f,0xf8,0x00, - 0x00,0x3f,0xf8,0x00, - 0x00,0x3f,0xf8,0x00, - 0x00,0x3f,0xf8,0x00, - 0x00,0x3f,0xf8,0x00, - 0x00,0x3f,0xf8,0x00, - 0x00,0x3f,0xf8,0x00, - 0x00,0x3f,0xf8,0x00, - 0x00,0x1f,0xf0,0x00, - 0x03,0xff,0xff,0xc0, - 0x07,0xff,0xff,0xe0, - 0x0f,0xff,0xff,0xf0, - 0x0f,0xff,0xff,0xf0, - 0x0f,0xff,0xff,0xf0, - 0x0f,0xff,0xff,0xf0, - 0x0f,0xff,0xff,0xf0, - 0x0f,0xff,0xff,0xf0, - 0x0f,0xff,0xff,0xf0, - 0x0f,0xff,0xff,0xf0, - 0x0f,0xff,0xff,0xf0, - 0x0f,0xff,0xff,0xf0, - 0x07,0xff,0xff,0xe0, - 0x01,0xff,0xff,0x80, - 0x01,0xff,0xff,0x80, - 0x01,0xff,0xff,0x80, - 0x01,0xff,0xff,0x80, - 0x01,0xff,0xff,0x80, - 0x01,0xff,0xff,0x80, - 0x01,0xff,0xff,0x80, - 0x01,0xff,0xff,0x80, - 0x01,0xff,0xff,0x80, - 0x03,0xff,0xff,0xc0, - 0x03,0xff,0xff,0xc0, - 0x03,0xff,0xff,0xc0, - 0x03,0xff,0xff,0xc0, - 0x03,0xff,0xff,0xc0, - 0x03,0xff,0xff,0xc0, - 0x00,0x7e,0x7e,0x00, - 0x00,0x7e,0x7e,0x00, - 0x00,0x7e,0x7e,0x00, - 0x00,0x7e,0x7e,0x00, - 0x00,0x7e,0x7e,0x00, - 0x00,0x7e,0x7e,0x00, - 0x00,0x7e,0x7e,0x00, - 0x00,0x7e,0x7e,0x00, - 0x00,0x7e,0x7e,0x00, - 0x00,0x7e,0x7e,0x00, - 0x00,0x7e,0x7e,0x00, - 0x00,0x7e,0x7e,0x00, - 0x00,0x7e,0x7e,0x00, - 0x00,0x7e,0x7e,0x00, - 0x00,0x7e,0x7e,0x00, - 0x00,0x7e,0x7e,0x00, -}; - -// TEXTURE Texture tex_white = {}; Texture tex_light = {}; Texture tex_dark = {}; Texture tex_black = {}; -const Texture tex_brique_base = {sprite_brique_base, NULL, 32, 32, 30, 30, 0.5, false, false}; -const Texture tex_brique = {sprite_brique, NULL, 32, 32, 30, 30, 0.5, false, false}; -const Texture tex_toit_tuile = {sprite_toit_tuile, NULL, 32, 32, 15, 15, 0.5, false, false}; -const Texture tex_paille = {sprite_paille, NULL, 16, 16, 10, 10, 0, false, false}; -const Texture tex_paille_dessus = {sprite_paille_dessus, NULL, 16, 16, 10, 10, 0, false, false}; -const Texture tex_mur_moulin = {sprite_planche_bois, NULL, 32, 32, 25, 25, 0.5, false, false}; -const Texture tex_pale_moulin = {sprite_pale_moulin, NULL, 16, 64, 0, 0, 0.5, false, false}; -const Texture tex_fenetre_simple = {sprite_fenetre_simple, NULL, 16, 16, 0, 0, 0, false, true}; -const Texture tex_porte_simple = {sprite_porte_simple, NULL, 16, 32, 0, 0, 0, false, true}; -const Texture tex_porte_entrepot = {sprite_planche_bois, NULL, 32, 32, 25, 25, 0, false, true}; -const Texture tex_pierre_eglise = {sprite_pierre_eglise, NULL, 32, 16, 0, 15, 0, false, false}; -const Texture tex_pierre_eglise2 = {sprite_pierre_eglise2, NULL, 32, 16, 0, 15, 0, false, false}; -const Texture tex_horloge = {sprite_horloge, NULL, 32, 32, 0, 0, 0, false, true, false}; -const Texture tex_porte_eglise = {sprite_porte_eglise, NULL, 32, 64, 0, 0, 0, false, true}; -const Texture tex_planche_bois = {sprite_planche_bois, NULL, 32, 32, 15, 15, 0.5, false, false}; -const Texture tex_haie = {sprite_haie, NULL, 16, 8, 20, 0, 0, true}; -const Texture tex_epouvantail = {sprite_epouvantail, sprite_epouvantail_masque, 16, 32, 0, 0, 0, false}; -const Texture tex_herbe = {sprite_herbe, NULL, 16, 8, 7, 0, 0, true}; -const Texture tex_panneau = {sprite_panneau, NULL, 16, 16, 0, 0, 0, false, true}; -const Texture tex_forgeron = {sprite_forgeron, mask_forgeron, 32, 64, 0, 0}; -const Texture tex_mur_int_maison = {sprite_mur_int_maison, NULL, 16, 32, 15, 0}; -const Texture tex_planche = {sprite_planche, NULL, 32, 16, 0, 0}; - - - - - -// MODELES -#define L1 20 // longueur extension X -#define W1 15 // largueur extension Y -#define H1 30 // hauteur mur Z -#define HT1 45 // hauteur toit nef Z -#define D 5 // decalage toit XY -#define L2 80 // longueur tour X -#define W2 20 // largeur tour X -#define H2 70 // hauteur mur tour Z -#define HT2 90 // hauteur toit tour Z -#define L3 (L1+(L2-L1)/2) // milieu toit tour X -const Modele modele_moulin[] = { - // les murs extension - {RECTANGLE, &tex_white, NULL, L1,W1,0, -L1,W1,0, L1,W1,H1}, - {RECTANGLE, &tex_brique, NULL, -L1,W1,0, -L1,-W1,0, -L1,W1,H1}, - {RECTANGLE, &tex_white, NULL, -L1,-W1,0, L1,-W1,0, -L1,-W1,H1}, - // la tour - {RECTANGLE, &tex_mur_moulin, NULL, L2,-W2,0, L2,W2,0, L2,-W2,H2}, - {RECTANGLE, &tex_mur_moulin, NULL, L2,W2,0, L1,W2,0, L2,W2,H2}, - {RECTANGLE, &tex_mur_moulin, NULL, L1,W2,0, L1,-W2,0, L1,W2,H2}, - {RECTANGLE, &tex_mur_moulin, NULL, L1,-W2,0, L2,-W2,0, L1,-W2,H2}, - // prolongement mur nef jusqu au toit - {TRIANGLE, &tex_brique, NULL, -L1,W1,H1, -L1,-W1,H1, -L1,0,HT1}, - // le toit de l extension - {RECTANGLE, &tex_paille, &tex_black, L1,W1+D,H1-3, -L1-D,W1+D,H1-3, L1,0,HT1}, - {RECTANGLE, &tex_paille, &tex_black, -L1-D,-W1-D,H1-3, L1,-W1-D,H1-3, -L1-D,0,HT1}, - // prolongement mur nef jusqu au toit - {TRIANGLE, &tex_mur_moulin, NULL, L2,W2,H2, L1,W2,H2, L3,W2,HT2}, - {TRIANGLE, &tex_mur_moulin, NULL, L1,-W2,H2, L2,-W2,H2, L3,-W2,HT2}, - // le toit de la tour - {RECTANGLE, &tex_toit_tuile, NULL, L2,-W2,H2, L2,W2,H2, L3,-W2,HT2}, - {RECTANGLE, &tex_toit_tuile, NULL, L1,W2,H2, L1,-W2,H2, L3,W2,HT2}, -}; - -#define A 3 // angle pale -const Modele modele_pale[] = { - {TRIANGLE, &tex_pale_moulin, &tex_pale_moulin, -21,-A,56, 21,A,56, 0,0,0}, - {TRIANGLE, &tex_pale_moulin, &tex_pale_moulin, 47,-A,36, 60,A,-2, 0,0,0}, - {TRIANGLE, &tex_pale_moulin, &tex_pale_moulin, 50,-A,-34, 17,A,-58, 0,0,0}, - {TRIANGLE, &tex_pale_moulin, &tex_pale_moulin, -17,-A,-58, -50,A,-34, 0,0,0}, - {TRIANGLE, &tex_pale_moulin, &tex_pale_moulin, -60,-A,-2, -47,A,37, 0,0,0}, -}; - - -#define L 40 // longueur X -#define W 20 // largueur Y -#define H 30 // hauteur mur Z -#define HT 55 // hauteur toit Z -#define D 5 // decalage toit XY -#define F1 10 // position X fenetre -#define F2 10 // position X fenetre -#define P -20 // position X fporte -const Modele modele_chaumiere[] = { - // les murs - {RECTANGLE, &tex_brique_base, NULL, L,-W,0, L,W,0, L,-W,H}, - {RECTANGLE, &tex_white, NULL, L,W,0, -L,W,0, L,W,H}, - {RECTANGLE, &tex_brique_base, NULL, -L,W,0, -L,-W,0, -L,W,H}, - {RECTANGLE, &tex_white, NULL, -L,-W,0, L,-W,0, -L,-W,H}, - // prolongement mur jusqu au toit - {TRIANGLE, &tex_brique, NULL, L,-W,H, L,W,H, L,0,HT}, - {TRIANGLE, &tex_brique, NULL, -L,W,H, -L,-W,H, -L,0,HT}, - // le toit - {RECTANGLE, &tex_paille, &tex_black, L+D,W+D,H-3, -L-D,W+D,H-3, L+D,0,HT}, - {RECTANGLE, &tex_paille, &tex_black, -L-D,-W-D,H-3, L+D,-W-D,H-3, -L-D,0,HT}, - // fenetre - {RECTANGLE, &tex_fenetre_simple, NULL, F1,W,8, F1-9,W,8, F1,W,25}, - {RECTANGLE, &tex_fenetre_simple, NULL, F2,-W,8, F2+9,-W,8, F2,-W,25}, - // porte - {RECTANGLE, &tex_porte_simple, NULL, P,W,0, P-12,W,0, P,W,25}, -}; - - -#define L 80 // longueur X -#define W 30 // largueur Y -#define H 35 // hauteur mur Z -#define HT 55 // hauteur toit Z -#define P -20 // position X fporte -const Modele modele_entrepot[] = { - // les murs - {RECTANGLE, &tex_brique, NULL, L,-W,0, L,W,0, L,-W,H}, - {RECTANGLE, &tex_white, NULL, L,W,0, -L,W,0, L,W,HT}, - {RECTANGLE, &tex_brique, NULL, -L,W,0, -L,-W,0, -L,W,H}, - {RECTANGLE, &tex_white, NULL, -L,-W,0, L,-W,0, -L,-W,H}, - // prolongement mur jusqu au toit - {TRIANGLE, &tex_white, NULL, L,-W,H, L,W,H, L,W,HT}, - {TRIANGLE, &tex_white, NULL, -L,W,H, -L,-W,H, -L,W,HT}, - // le toit - {RECTANGLE, &tex_paille, &tex_black, -L-D,-W-D,H-3, L+D,-W-D,H-3, -L-D,W+D,HT}, - // porte - {RECTANGLE, &tex_planche_bois, NULL, P,W+2,0, P-35,W+2,0, P,W+1,40}, - // glissiere - {RECTANGLE, &tex_black, NULL, P+35,W+2,0, P-40,W+2,0, P+35,W+1,1}, - {RECTANGLE, &tex_black, NULL, P+35,W+2,40, P-40,W+2,40, P+35,W+1,41}, -}; - - -#define LN 50 // longueur nef X -#define WN 22 // largueur nef Y -#define HN 60 // hauteur mur nef Z -#define HNT 80 // hauteur toit nef Z -#define D 5 // decalage toit XY -#define LT 90 // longueur tour X -#define WT 28 // largeur tour X -#define HT 100 // hauteur mur tour Z -#define HH 70 // hauteur horloge Z -#define HC 120 // hauteur clocher Z -#define HCT 150 // hauteur clocher max Z -const Modele modele_eglise[] = { - // les murs nefs - {RECTANGLE, &tex_white, NULL, LN,WN,0, -LN,WN,0, LN,WN,HN}, - {RECTANGLE, &tex_brique, NULL, -LN,WN,0, -LN,-WN,0, -LN,WN,HN}, - {RECTANGLE, &tex_white, NULL, -LN,-WN,0, LN,-WN,0, -LN,-WN,HN}, - // la tour - {RECTANGLE, &tex_pierre_eglise, NULL, LT,-WT,0, LT,WT,0, LT,-WT,HT}, - {RECTANGLE, &tex_pierre_eglise, NULL, LT,WT,0, LN,WT,0, LT,WT,HT}, - {RECTANGLE, &tex_pierre_eglise, NULL, LN,WT,0, LN,-WT,0, LN,WT,HT}, - {RECTANGLE, &tex_pierre_eglise, NULL, LN,-WT,0, LT,-WT,0, LN,-WT,HT}, - // prolongement mur nef jusqu au toit - {TRIANGLE, &tex_brique, NULL, -LN,WN,HN, -LN,-WN,HN, -LN,0,HNT}, - // le toit de la nef - {RECTANGLE, &tex_toit_tuile, &tex_black, LN,WN+D,HN-3, -LN-D,WN+D,HN-3, LN,0,HNT}, - {RECTANGLE, &tex_toit_tuile, &tex_black, -LN-D,-WN-D,HN-3, LN,-WN-D,HN-3, -LN-D,0,HNT}, - // horloge - {RECTANGLE, &tex_horloge, NULL, LT,-10,HH, LT,10,HH, LT,-10,HH+20}, - // porte - {RECTANGLE, &tex_porte_eglise, NULL, LT,-15,0, LT,15,0, LT,-15,60}, - // clocher - {TRIANGLE, &tex_toit_tuile, NULL, LT,-WT,HT, LT,WT,HT, 70,0,HCT}, - {TRIANGLE, &tex_toit_tuile, NULL, LT,WT,HT, LN,WT,HT, 70,0,HCT}, - {TRIANGLE, &tex_toit_tuile, NULL, LN,WT,HT, LN,-WT,HT, 70,0,HCT}, - {TRIANGLE, &tex_toit_tuile, NULL, LN,-WT,HT, LT,-WT,HT, 70,0,HCT}, -}; - - -#define L 30// longueur X -#define H 10// hauteur Z -const Modele modele_haie1[] = { - {RECTANGLE, &tex_haie, &tex_haie, -L,0,0, L,0,0, -L,0,H} -}; - -#define L 50// longueur X -#define H 10// hauteur Z -const Modele modele_haie2[] = { - {RECTANGLE, &tex_haie, &tex_haie, -L,0,0, L,0,0, -L,0,H} -}; - -#define L 10// longueur X -#define H 19// hauteur Z -const Modele modele_epouventail1[] = { - {RECTANGLE, &tex_epouvantail, &tex_epouvantail, -L,0,0, L,0,0, -L,0,H} -}; - -#define L 60// longueur X -#define H 9// hauteur Z -const Modele modele_herbe1[] = { - {RECTANGLE, &tex_herbe, &tex_herbe, -L,0,0, L,0,0, -L,0,H} -}; - -#define L 60// longueur X -#define H 9// hauteur Z -const Modele modele_herbe2[] = { - {RECTANGLE, &tex_herbe, &tex_herbe, -L,0,0, L,0,0, -L,0,H} -}; - -#define L 4// longueur X -#define H1 13// hauteur Z -#define H2 18// hauteur Z -const Modele modele_panneau1[] = { - {RECTANGLE, &tex_panneau, &tex_panneau, -L,0,H1, L,0,H1, -L,0,H2}, - {RECTANGLE, &tex_black, &tex_black, -L-1,0,0, -L,0,0, -L-1,0,H2}, - {RECTANGLE, &tex_black, &tex_black, L,0,0, L+1,0,0, L,0,H2} -}; - -#define L 7 // longueur X -#define W 7 // largueur Y -#define H 14 // hauteur Z -const Modele modele_botte_paille[] = { - // les cotes - {RECTANGLE, &tex_paille, NULL, L,-W,0, L,W,0, L,-W,H}, - {RECTANGLE, &tex_paille, NULL, L,W,0, -L,W,0, L,W,H}, - {RECTANGLE, &tex_paille, NULL, -L,W,0, -L,-W,0, -L,W,H}, - {RECTANGLE, &tex_paille, NULL, -L,-W,0, L,-W,0, -L,-W,H}, - // dessus - {RECTANGLE, &tex_paille_dessus, NULL, -L,-W,H, L,-W,H, -L,W,H}, -}; - -#define L 50 // longueur X -#define W 25 // largueur Y -#define H 25 // hauteur Z -const Modele modele_murs_maison_forgeron[] = { - // les cotes - {RECTANGLE, NULL, &tex_mur_int_maison, L,-W,0, L,W,0, L,-W,H}, - {RECTANGLE, NULL, &tex_mur_int_maison, L,W,0, -L,W,0, L,W,H}, - {RECTANGLE, NULL, &tex_mur_int_maison, -L,W,0, -L,-W,0, -L,W,H}, - {RECTANGLE, NULL, &tex_mur_int_maison, -L,-W,0, L,-W,0, -L,-W,H}, - //plafond - {RECTANGLE, NULL, &tex_black, -L,-W,H, L,-W,H, -L,W,H}, -}; - -#define L 10 // longueur X -#define W 4 // largueur Y -#define H 7 // hauteur Z -#define D 1 // decalage pied -#define E 1 // epaisseur pied -const Modele modele_table[] = { - // planche - {RECTANGLE, &tex_planche, &tex_black, -L,-W,H, L,-W,H, -L,W,H}, - // pieds - {RECTANGLE, &tex_black, &tex_black, -L+D,-W+D,0, -L+D+E,-W+D+E,0, -L+D,-W+D,H-1}, - {RECTANGLE, &tex_black, &tex_black, L-D,-W+D,0, L-D-E,-W+D+E,0, L-D,-W+D,H-1}, - {RECTANGLE, &tex_black, &tex_black, -L+D,W-D,0, -L+D+E,W-D-E,0, -L+D,W-D,H-1}, - {RECTANGLE, &tex_black, &tex_black, L-D,W-D,0, L-D-E,W-D-E,0, L-D,W-D,H-1}, -}; - -#define W 7 // largueur Y -#define H 20 // hauteur Z -const Modele modele_forgeron[] = { - {RECTANGLE, &tex_forgeron, NULL, 0,-W,0, 0,W,0, 0,-W,H}, -}; - - - -// MAP -// ECRAN TITRE -Object moulin_menu = {0,0,0, 0,N, modele_moulin,14, NONE}; -Object pale_menu = {50,27,70, 0,Y, modele_pale,5, NONE}; - -Object* list_menu[] = { - &moulin_menu, &pale_menu -}; - -Map map_menu = {list_menu, 2, true, true}; - - - - - -// VILLAGE -Object chaumiere1 = {-36,62,0, 0,N, modele_chaumiere,11, ALL}; -Object chaumiere2 = {-153,194,0, 251,Z, modele_chaumiere,11, ALL}; -Object chaumiere3 = {0,257,0, 143,Z, modele_chaumiere,11, ALL}; -Object entrepot = {319,-57,0, 80,Z, modele_entrepot,10, ALL}; -Object eglise1 = {153,253,0, -102,Z, modele_eglise,16, ALL}; -Object moulin1 = {21,-211,0, 0,N, modele_moulin,14, ALL}; -Object pale_moulin1 = {72,-183,70, 0,Y, modele_pale,5, NONE}; -Object haie1 = {0,-102,0, -5,Z, modele_haie1,1, ALL}; -Object haie2 = {-63,-105,0, 9,Z, modele_haie1,1, ALL}; -Object haie3 = {-132,-144,0, 46,Z, modele_haie2,1, ALL}; -Object haie4 = {144,-135,0, -14,Z, modele_haie2,1, ALL}; -Object haie5 = {-117,-264,0, -30,Z, modele_haie2,1, ALL}; -Object epouvantail1 = {-93,-210,0, -28,Z, modele_epouventail1,1, ALL}; -Object herbe1 = {-130,-200,0, 90,Z, modele_herbe1,1, NONE}; -Object herbe2 = {-109,-200,0, 90,Z, modele_herbe1,1, NONE}; -Object herbe3 = {-82,-191,0, 90,Z, modele_herbe1,1, NONE}; -Object herbe4 = {-61,-185,0, 90,Z, modele_herbe1,1, NONE}; -Object herbe5 = {-37,-179,0, 90,Z, modele_herbe1,1, NONE}; -Object herbe6 = {235,119,0, 131,Z, modele_herbe1,1, NONE}; -Object herbe7 = {292,51,0, 94,Z, modele_herbe1,1, NONE}; -Object panneau1 = {91,-117,0, 0,N, modele_panneau1,3, ALL}; -Object botte_paille1 = {269,42,0, 0,N, modele_botte_paille,5, ALL}; -Object botte_paille2 = {269,21,0, 0,N, modele_botte_paille,5, ALL}; -Object botte_paille3 = {272,30,14, 0,N, modele_botte_paille,5, ALL}; - -Object* list_village[] = { - &chaumiere1, &chaumiere2, &chaumiere3, &entrepot, &eglise1, &moulin1, - &pale_moulin1, &haie1, &haie2, &haie3, &haie4, &haie5, &epouvantail1, - &herbe1, &herbe2, &herbe3, &herbe4, &herbe5, &herbe6, &herbe7, &panneau1, - &botte_paille1, &botte_paille2, &botte_paille3 -}; - -Map map_village = {list_village, 24, true, true}; - - - - - -// CHEZ LE FORGERON -Object murs_maison_forgeron1 = {0,0,0, 0,N, modele_murs_maison_forgeron,5, INSIDE}; -Object table1 = {18,17,0, 0,N, modele_table,5, ALL}; -Object table2 = {-23,-7,0, 99,Z, modele_table,5, ALL}; -Object forgeron1 = {-34,-8,0, 0,Z_BILLBOARD, modele_forgeron,1, ALL}; - -Object* liste_interieur_forgeron[] = { - &murs_maison_forgeron1, &table1, &table2, &forgeron1 -}; -Map map_interieur_forgeron = {liste_interieur_forgeron, 4, false, false}; +Texture tex_brique = {sprite_brique, NULL, 32, 32, 0, 0}; +Texture tex_tuile = {sprite_toit_tuile, NULL, 32, 32, 0, 0}; +Texture tex_mur_moulin = {sprite_planche_bois, NULL, 32, 32, 0, 0}; +Texture tex_pale_moulin = {sprite_pale_moulin, NULL, 16, 64, 0, 0}; // EXEMPLE -const Texture tex_exemple = {sprite_exemple, NULL, 32, 32, 0, 0, 1, false, false, false}; -//const Texture tex_exemple_mask = {sprite_forgeron, mask_forgeron, 32, 64, 0, 0, 1, false, false, false}; +const VertexPoint exemple_v[] = { + {0, -30, 0}, + {0, 30, 0}, + {0, -30, 60}, + {0, 30, 60}}; +const TexturePoint exemple_t[] = { + {0, 0}, + {1, 0}, + {0, 1}, + {1, 1}}; +const Face exemple_f[] = { + {&tex_brique, &tex_black, {0, 2, 1}, {0, 2, 1}}, + {&tex_black, &tex_tuile, {1, 2, 3}, {1, 2, 3}}}; +const Mesh exemple_m = {exemple_v, 4, exemple_t, 4, exemple_f, 2}; -#define L 50 // longueur X -#define W 25 // largueur Y -#define W2 12 // largeur divise par deux -#define H 30 // hauteur mur Z -#define HT 40 // hauteur toit -#define F 20 // fenetre -const Modele modele_maison[] = { - // les murs - {RECTANGLE, &tex_white, NULL, 0,0,0, L,0,0, 0,0,H}, - {RECTANGLE, &tex_brique_base, NULL, L,0,0, L,W,0, L,0,H}, - {RECTANGLE, &tex_white, NULL, L,W,0, 0,W,0, L,W,H}, - {RECTANGLE, &tex_brique_base, NULL, 0,W,0, 0,0,0, 0,W,H}, - // prolongement mur jusqu au toit - {TRIANGLE, &tex_brique, NULL, L,0,H, L,W,H, L,W2,HT}, - {TRIANGLE, &tex_brique, NULL, 0,W,H, 0,0,H, 0,W2,HT}, - // le toit - {RECTANGLE, &tex_paille, NULL, L,W,H, 0,W,H, L,W2,HT}, - {RECTANGLE, &tex_paille, NULL, 0,0,H, L,0,H, 0,W2,HT}, - // fenetre - {RECTANGLE, &tex_fenetre_simple, NULL, F,0,7, F+9,0,7, F,0,25}, - {RECTANGLE, &tex_fenetre_simple, NULL, F,W,7, F-9,W,7, F,W,25}, +Object exemple_o1 = {&exemple_m, {0, 0, 0}, N, 0}; + +Object* objects_exemple[] = {&exemple_o1}; +Map map_exemple = {objects_exemple, 1, true, true}; + + + + + + + +// MOULIN +#define L1 30 +#define L2 35 +#define Z1 80 +#define Z2 100 +const VertexPoint moulin_v[] = { + // tour + {L1, L1, 0}, + {-L1, L1, 0}, + {-L1, -L1, 0}, + {L1, -L1, 0}, + {L1, L1, Z1}, + {-L1, L1, Z1}, + {-L1, -L1, Z1}, + {L1, -L1, Z1}, + // toit + {L2, L2, Z1}, + {-L2, L2, Z1}, + {-L2, -L2, Z1}, + {L2, -L2, Z1}, + {L2+10, 0, Z2}, + {-L2-10, 0, Z2}, + {L1, 0, Z2}, + {-L1, 0, Z2} }; - -Object maison1 = { 33,-50, 0, 0, N, modele_maison, 10, ALL}; -Object maison2 = {100, 12, 0, 90, Z, modele_maison, 10, ALL}; - -Object* liste_exemple[] = { - &maison1, &maison2 +const TexturePoint moulin_t[] = { + LB, // 0 + RB, // 1 + RT, // 2 + LT // 3 }; +const Face moulin_f[] = { + // mur moulin + {&tex_mur_moulin, NULL, {0, 4, 7}, {1, 2, 3}}, + {&tex_mur_moulin, NULL, {3, 0, 7}, {0, 1, 3}}, + {&tex_mur_moulin, NULL, {1, 5, 4}, {1, 2, 3}}, + {&tex_mur_moulin, NULL, {0, 1, 4}, {0, 1, 3}}, + {&tex_mur_moulin, NULL, {2, 6, 5}, {1, 2, 3}}, + {&tex_mur_moulin, NULL, {1, 2, 5}, {0, 1, 3}}, + {&tex_mur_moulin, NULL, {3, 7, 6}, {1, 2, 3}}, + {&tex_mur_moulin, NULL, {2, 3, 6}, {0, 1, 3}}, + // toit moulin + {&tex_tuile, &tex_black, {10, 11, 13}, {0, 1, 3}}, + {&tex_tuile, &tex_black, {11, 12, 13}, {1, 2, 3}}, + {&tex_tuile, &tex_black, {8, 9, 12}, {0, 1, 3}}, + {&tex_tuile, &tex_black, {9, 13, 12}, {1, 2, 3}}, + {&tex_white, NULL, {7, 4, 14}}, + {&tex_white, NULL, {5, 6, 15}}, -Map map_exemple = {liste_exemple, 2, true, true}; +}; +const Mesh moulin_m = {moulin_v, 16, moulin_t, 4, moulin_f, 14}; + + +// PALE MOULIN +#define E 7 +#define R1 13 +#define R2 60 +#define P 3 +const VertexPoint pale_moulin_v[] = { + {P, -E-2, -R2}, + {-P, E+2, -R2}, + {0, E, -R1}, + {0, -E, -R1}, + {0, 0, 0} +}; +const TexturePoint pale_moulin_t[] = { + LB, // 0 + RB, // 1 + RT, // 2 + LT, // 3 + {0, 0.19}, + {1, 0.19}, + MT +}; +const Face pale_moulin_f[] = { + {&tex_pale_moulin, &tex_pale_moulin, {0, 1, 2}, {0, 1, 5}}, + {&tex_pale_moulin, &tex_pale_moulin, {0, 2, 3}, {0, 5, 4}}, + {&tex_pale_moulin, &tex_pale_moulin, {4, 3, 2}, {6, 4, 5}} + +}; +const Mesh pale_moulin_m = {pale_moulin_v, 5, pale_moulin_t, 7, pale_moulin_f, 3}; + + + +Object moulin_o1 = {&moulin_m, {0, 0, 0}, N, 0}; +Object pale_moulin_o1 = {&pale_moulin_m, {40, 0, 70}, RX, 0}; +Object pale_moulin_o2 = {&pale_moulin_m, {40, 0, 70}, RX, 1*360/5}; +Object pale_moulin_o3 = {&pale_moulin_m, {40, 0, 70}, RX, 2*360/5}; +Object pale_moulin_o4 = {&pale_moulin_m, {40, 0, 70}, RX, 3*360/5}; +Object pale_moulin_o5 = {&pale_moulin_m, {40, 0, 70}, RX, 4*360/5}; + + +Object* objects_moulin[] = {&moulin_o1, &pale_moulin_o1, &pale_moulin_o2, &pale_moulin_o3, &pale_moulin_o4, &pale_moulin_o5}; +Map map_moulin = {objects_moulin, 6, true, true}; diff --git a/src/scene_map.cpp b/src/scene_map.cpp index 6ee85c5..ec4b0a7 100644 --- a/src/scene_map.cpp +++ b/src/scene_map.cpp @@ -1,18 +1,19 @@ #include "scene_map.hpp" void debug_pop(char const *fmt, ...); +void debug_display(char const *fmt, ...); + extern Game game; extern Windmill windmill; // import des map -extern Map map_village; -extern Map map_interieur_forgeron; +extern Map map_exemple; +extern Map map_moulin; // import des objets -extern Object chaumiere1; -extern Object panneau1; -extern Object forgeron1; + + //---------------------------------------------------------------------------------------------------- // CONSTRUCTOR @@ -20,7 +21,7 @@ extern Object forgeron1; Scene_Map::Scene_Map() { // debug - show_repere = false; + show_repere = true; show_coordinates = false; // histoire vue_horloge = false; @@ -35,6 +36,8 @@ Scene_Map::Scene_Map() //---------------------------------------------------------------------------------------------------- void Scene_Map::launch() { + if (game.map == NULL) return; + time_scene = 0; load_map(); @@ -47,13 +50,11 @@ void Scene_Map::launch() void Scene_Map::load_map() { - // (LEPHE) - game.map = &map_village; - // mise a jour de la map pour la scene - windmill.load_map(game.map); + windmill.set_map(game.map); - // creation des bouding box 3D + /* + // creation des bouding box 3D pour les collisions //delete bbox; free(bbox); //bbox = new Bbox3D[game.map->list_object_length]; @@ -76,12 +77,12 @@ void Scene_Map::load_map() for (int k=0; ktype; k++) { Point point = windmill.get_point(current_modele, k); - current_bbox->x1 = min((int)current_bbox->x1, point.x); - current_bbox->y1 = min((int)current_bbox->y1, point.y); - current_bbox->z1 = min((int)current_bbox->z1, point.z); - current_bbox->x2 = max((int)current_bbox->x2, point.x); - current_bbox->y2 = max((int)current_bbox->y2, point.y); - current_bbox->z2 = max((int)current_bbox->z2, point.z); + current_bbox->x1 = min(current_bbox->x1, point.x); + current_bbox->y1 = min(current_bbox->y1, point.y); + current_bbox->z1 = min(current_bbox->z1, point.z); + current_bbox->x2 = max(current_bbox->x2, point.x); + current_bbox->y2 = max(current_bbox->y2, point.y); + current_bbox->z2 = max(current_bbox->z2, point.z); } } if (current_object->axe == Z_BILLBOARD) @@ -89,7 +90,7 @@ void Scene_Map::load_map() current_bbox->radius = max(current_bbox->y1, current_bbox->y2); } - } + }*/ // mise a zero du temps sur la map time_scene = 0; @@ -101,38 +102,10 @@ void Scene_Map::load_map() //---------------------------------------------------------------------------------------------------- void Scene_Map::draw() { - //ML_clear_vram(); dclear(C_WHITE); windmill.draw(); - // MAP VILLAGE - if (game.map == &map_village) - { - if (vue_panneau_moulin) - { - //ML_rectangle(34, 15, 95, 50, 0, ML_WHITE, ML_WHITE); - //PrintXY(34, 20, "MOULIN DES", 0); - //PrintXY(52, 30, "RIBES", 0); - //PrintMini(45, 45, "NineStars", 0); - } - } - - // MAP INTERIEUR FORGERON - if (game.map == &map_interieur_forgeron) - { - if (parle_avec_forgeron) - { - //Point point_ancrage = windmill.get_point(&forgeron1.modele, 0); - - //ML_rectangle(50, 10, 118, 54, 1, ML_BLACK, ML_WHITE); - } - } - - if (show_repere) windmill.show_repere(); - if (show_coordinates) windmill.show_coordinates(); - - //ML_display_vram(); dupdate(); } @@ -169,6 +142,11 @@ void Scene_Map::update() show_coordinates = !show_coordinates; }*/ + if (keydown(KEY_LOG)) + { + windmill.log = !windmill.log; + } + // action du joueur sur la map player_action(); @@ -186,75 +164,28 @@ void Scene_Map::update() camera.set(game.player.x, game.player.y, game.player.z + game.player.height, game.player.yaw, game.player.pitch); } - //debug_display(id(windmill.object_cursor), 3); - //debug_display(windmill.poly_cursor, 4); } void Scene_Map::player_action() { - // MAP VILLAGE - if (game.map == &map_village) - { - /*if (input_trigger(K_EXE)) - { - if (action_object(object(20))) - { - - if (vue_panneau_moulin) - { - game.player.can_move = true; - game.player.dissociate_camera = false; - windmill.set_camera(&camera); - } else { - game.player.can_move = false; - game.player.dissociate_camera = true; - look(&panneau1, 0, 8, 17, 270, -10); - windmill.set_camera(&camera_look); - } - vue_panneau_moulin = not vue_panneau_moulin; - } - }*/ - } - - // MAP INTERIEUR FORGERON - if (game.map == &map_interieur_forgeron) - { - /*if (input_trigger(K_EXE)) - { - // interaction avec le forgeron - if (parle_avec_forgeron) - { - parle_avec_forgeron = false; - game.player.can_move = true; - game.player.dissociate_camera = false; - } else { - if (action_object(&forgeron1)) - { - parle_avec_forgeron = true; - game.player.can_move = false; - game.player.dissociate_camera = true; - camera.set(-23, 4, game.player.height, 198, 0); - } - } - }*/ - } } void Scene_Map::animation() { - // MAP VILLAGE - if (game.map == &map_village) + if (game.map == &map_moulin) { - object(6)->angle -= 1; + game.map->object[1]->angle += 0.6; + game.map->object[2]->angle += 0.6; + game.map->object[3]->angle += 0.6; + game.map->object[4]->angle += 0.6; + game.map->object[5]->angle += 0.6; } } - - void Scene_Map::player_move() { ///////////// METTRE DANS PLAYER ET RETURN LE FLAG @@ -263,20 +194,15 @@ void Scene_Map::player_move() float new_z = game.player.z; // deplacement - float front, side; - /* (LEPHE) */ - // input_move(&front, &side); - front = 2 * (keydown(KEY_5) != 0); - side = 2 * ((keydown(KEY_6) != 0) - (keydown(KEY_4) != 0)); - - // si des touches sont pressees + int front = (keydown(KEY_5) != 0) - (keydown(KEY_2) != 0); + int side = (keydown(KEY_4) != 0) - (keydown(KEY_6) != 0); if (side != 0 or front != 0) { game.player.moving = true; - //game.player.translation_speed = min(game.player.translation_speed + 0.25, game.player.translation_speed_max); + // acceleration player if (game.player.translation_speed < game.player.translation_speed_max) { - game.player.translation_speed += game.player.translation_acceleration; // acceleration + game.player.translation_speed += game.player.translation_acceleration; } else { game.player.translation_speed = game.player.translation_speed_max; } @@ -291,7 +217,15 @@ void Scene_Map::player_move() game.player.translation_speed = 0; } + // vole + int vertical = (keydown(KEY_PLUS) != 0) - (keydown(KEY_MINUS) != 0); + if (vertical != 0) + { + new_z += vertical; + } + // saut + /* if (keydown(KEY_8) and not game.player.jumping) { game.player.jump_speed = game.player.jump_speed_max; @@ -299,8 +233,9 @@ void Scene_Map::player_move() } else { game.player.jump_speed -= 0.981; // gravite } - new_z += game.player.jump_speed; + new_z += game.player.jump_speed;*/ + /* // collision flag = collision(&new_x, &new_y, &new_z); @@ -314,8 +249,8 @@ void Scene_Map::player_move() // hors terrain if (flag.type == COLLISION_BOUND) { - //debug_display("trop loin", 2); - } + // trop loin + }*/ game.player.x = new_x; game.player.y = new_y; @@ -328,10 +263,10 @@ void Scene_Map::player_turn() float yaw = 0; float pitch = 0; - if (keydown(KEY_RIGHT)) yaw = -1; - if (keydown(KEY_LEFT)) yaw = 1; - if (keydown(KEY_DOWN)) pitch = -0.5; - if (keydown(KEY_UP)) pitch = 0.5; + if (keydown(KEY_RIGHT)) yaw = -0.5; + if (keydown(KEY_LEFT)) yaw = 0.5; + if (keydown(KEY_DOWN)) pitch = -0.25; + if (keydown(KEY_UP)) pitch = 0.25; if (yaw != 0 or pitch != 0) { @@ -367,7 +302,7 @@ void Scene_Map::player_turn() // 4 z_billboard // 5 hors terrain //----------------------------------------------------------------------------- -Collision_flag Scene_Map::collision(float* new_x, float* new_y, float* new_z) +/*Collision_flag Scene_Map::collision(float* new_x, float* new_y, float* new_z) { Collision_flag flag; @@ -383,7 +318,7 @@ Collision_flag Scene_Map::collision(float* new_x, float* new_y, float* new_z) flag.type = COLLISION_GROUND; } - for (int i = 0; ilist_object_length; i++) + for (int i = 0; iobject_length; i++) { Object* current_object = game.map->object[i]; @@ -536,7 +471,9 @@ Collision_flag Scene_Map::collision(float* new_x, float* new_y, float* new_z) } return flag; -} +}*/ + + /*Collision_flag Scene_Map::collision(float* new_x, float* new_y, float* new_z) { Collision_flag flag; @@ -711,7 +648,7 @@ Collision_flag Scene_Map::collision(float* new_x, float* new_y, float* new_z) return flag; }*/ - +/* void Scene_Map::look(Object* object, float x, float y, float z, float yaw, float pitch) { Vertex vertex; @@ -762,9 +699,9 @@ int Scene_Map::id(Object* object) } debug_pop("ERROR object not found"); return -1; -} - +}*/ +/* bool Scene_Map::action_object(Object* object, int poly_id) { if (look_object(object, poly_id) == false) return false; @@ -804,7 +741,7 @@ bool Scene_Map::look_object(Object* object, int poly_id) return (object == windmill.object_cursor and poly_id == windmill.poly_cursor); } -} +}*/ //---------------------------------------------------------------------------------------------------- @@ -821,36 +758,3 @@ Scene_Map::~Scene_Map() { // rien } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/windmill.cpp b/src/windmill.cpp deleted file mode 100644 index 6da3c90..0000000 --- a/src/windmill.cpp +++ /dev/null @@ -1,1790 +0,0 @@ -//---------------------------------------------------------------------------------------------------- -// -// WINDMILL -// -// version : 2.0 -// Moteur de rendu 3D base sur la methode de rasterisation avec buffer de profondeur -// -// Cree par Olivier Lanneau, alias NineStars -// Planet-casio.fr -// -//---------------------------------------------------------------------------------------------------- - - -#include "windmill.hpp" - -void debug_pop(char const *fmt, ...); - -//const Texture tex_black = {}; -//const Texture tex_white = {}; -extern Texture tex_white; -extern Texture tex_light; -extern Texture tex_dark; -extern Texture tex_black; - - -//---------------------------------------------------------------------------------------------------- -// INITIALISATION -//---------------------------------------------------------------------------------------------------- -Windmill::Windmill() -{ - camera2 = NULL; - map = NULL; - object = NULL; - z_buffer = NULL; - set_viewport(0, 0, 128, 64); - - nb_object_on_screen = 0; - temp_object_cursor = NULL; - temp_poly_cursor = -1; -} - - -void Windmill::set_camera(Camera* _camera) -{ - camera2 = _camera; -} - - -void Windmill::set_viewport(int viewport_x1, int viewport_y1, int viewport_x2, int viewport_y2) -{ - viewport.x1 = max(0, viewport_x1); - viewport.y1 = max(0, viewport_y1); - viewport.x2 = min(viewport_x2, DWIDTH); - viewport.y2 = min(viewport_y2, DHEIGHT); - - //if (z_buffer != NULL) free(z_buffer); - free(z_buffer); - shift_x = (viewport.x1 + viewport.x2) / 2; - shift_y = (viewport.y1 + viewport.y2) / 2; - - z_buffer_size = (viewport.x2 - viewport.x1) * (viewport.y2 - viewport.y1); - z_buffer = (unsigned short*) calloc(z_buffer_size, 2); - if (z_buffer == NULL) debug_pop("ERROR ptr z_buffer NULL"); - z_buffer_width = viewport.x2 - viewport.x1; - z_buffer_offset = - viewport.x1 - viewport.y1 * DWIDTH; - clear_z_buffer(); - - cursor_x = shift_x; - cursor_y = shift_y; -} - - -void Windmill::load_map(Map* _map) -{ - loading = true; - - if (map != _map) - { - // attribution de la map - map = _map; - - // enregistrement des objets de la map dans un tableau - // ceci permet de trier les objets pour les afficher du plus - // pres au plus loin - list_object_length = map->list_object_length; - //delete[] object; - free(object); - //object = new Object* [list_object_length]; - object = (Object**) malloc(list_object_length * sizeof(Object)); - if (object == NULL) debug_pop("ERROR ptr object NULL"); - for (int i = 0; iobject[i]; - } - - // generation des spheres englobantes - // pour chaque objet - for (int i = 0; ilist_object_length; i++) - { - Object* current_object = map->object[i]; - int nb_point = 0; - int center_x = 0; - int center_y = 0; - int center_z = 0; - - // pour chaque poly - for (int j = 0; jmodele_size; j++) - { - const Modele* current_poly = ¤t_object->modele[j]; - - // pour chaque point - for (int k = 0; ktype; k++) - { - Point point = get_point(current_poly, k); - center_x += point.x; - center_y += point.y; - center_z += point.z; - - nb_point++; - } - } - // barycentre - center_x /= nb_point; - center_y /= nb_point; - center_z /= nb_point; - - // recherche du point le plus eloigne du centre - int radius_max = 0; - for (int j = 0; jmodele_size; j++) - { - const Modele* current_poly = ¤t_object->modele[j]; - for (int k = 0; ktype; k++) - { - Point point = get_point(current_poly, k); - int dx = point.x - center_x; - int dy = point.y - center_y; - int dz = point.z - center_z; - int radius = dx*dx + dy*dy + dz*dz; - //int rr = sqrtf(radius); - if (radius > radius_max) - { - radius_max = radius; - } - } - } - radius_max = sqrtf(radius_max) + 1; - - current_object->sphere.x = center_x; - current_object->sphere.y = center_y; - current_object->sphere.z = center_z; - current_object->sphere.radius = radius_max; - } - } - - loading = false; -} - - - - - -//---------------------------------------------------------------------------------------------------- -// DESSIN -//---------------------------------------------------------------------------------------------------- -void Windmill::draw() -{ - // quitte si pas de camera, de map, d objet ou de z_buffer - if(camera2 == NULL or map == NULL or object == NULL or z_buffer == NULL) return; - - // mets a jour les variables de la camera - camera2->update(); - - // cree une camera temporaire pour eviter les problemes de desynchronisation - copy_camera(); - - // fonction principale, l'ordre d'appel des fonctions suivantes est important - clear_z_buffer(); - - // trie les objets pour optimiser l affichage - sort_object(); - - // affiche le trait d'horizon - if (map->horizon) draw_horizon(); - - // affiche le sol - if (map->ground) draw_ground(); - - // affiche les objets de la scene - draw_objects(); - - // post traitement pour afficher les angles vifs - draw_post_treatment(); - - // affiche le corps du personnage - draw_body(); - - // affiche des informations - //show_fps(); - //show_coordinates(); - //show_repere(); -} - - -void Windmill::draw_horizon() -{ - Vertex horizon; - char* vram = get_vram_address(); - int distance = 1000; - int hx = camera.x + distance * camera.cos_yaw; - int hy = camera.y + distance * camera.sin_yaw; - - horizon.set_xyz(hx, hy, 0); - - transform_world_to_camera(&horizon, 1); - transform_camera_to_screen(&horizon, 1); - if (inside_viewport(horizon.x, horizon.y)) - { - dline(viewport.x1, horizon.y, viewport.x2, horizon.y, C_BLACK); - //ML_line(viewport.x1, horizon.y, viewport.x2, horizon.y, ML_BLACK); - } -} - - -void Windmill::draw_ground() -{ - Vertex ground; - char* vram = get_vram_address(); - unsigned char mask; - int distance = 50; - int esp = 20; - int nb = 6; - int nb2 = nb * nb; - float cx = camera.x + distance * camera.cos_yaw; - float cy = camera.y + distance * camera.sin_yaw; - int dx = int(cx) - int(cx)%esp; - int dy = int(cy) - int(cy)%esp; - - for (int i=-nb; i 0) - { - transform_camera_to_screen(&ground, 1); - if (inside_viewport(ground.x, ground.y) == true) - { - mask = 128 >> (ground.x & 7); - vram[(ground.y << 4) + (ground.x>>3)] |= mask; - } - } - } - } - } -} - - -void Windmill::draw_objects() -{ - nb_object_on_screen = 0; - temp_object_cursor = NULL; - temp_poly_cursor = -1; - - Vertex vertex[10]; - int vertex_length; - int width, height; - int cosinus, sinus; - - for(i=0; ilist_object_length; i++) - { - //Object* current_object = map->object[i]; - Object* current_object = object[i]; - - if (current_object->hidden == false) - { - // angle de l objet - compute_object_angle(current_object, &cosinus, &sinus); - - // transforme la sphere dans le repere monde - Sphere current_sphere = transform_sphere_to_world(¤t_object->sphere, current_object, cosinus, sinus); - - // verifie si la sphere englobante est dans le champs de vision de la camera - if (sphere_in_cone(¤t_sphere)) - { - temp_nb_object_on_screen ++; - current_object->on_screen = true; - current_object->distance_to_camera = current_sphere.z; - - for(j=0; jmodele_size; j++) - { - const Modele* current_poly = ¤t_object->modele[j]; - - // creation des vertex a partir du poly - extract_vertex_from_poly(current_poly, vertex, &vertex_length, &width, &height); - - // calcul des coordonnees dans le repère monde apres rotation et translation de l objet - transform_model_to_world(vertex, vertex_length, current_object, cosinus, sinus); - - // calcul des coordonnees dans le repère camera apres rotation et translation de la camera - transform_world_to_camera(vertex, vertex_length); - - // verifie si au moins 1 point peut etre visible - if (fast_check(vertex, vertex_length)) - { - // calcul de l'aire du rectangle pour connaitre sa face visible - int visible = visible_face(&vertex[0], &vertex[1], &vertex[2]); - - // choisi la texture visible - const Texture* texture; - texture = (visible == FRONT) ? current_poly->texture_front : current_poly->texture_back; - - // si le rectangle est visible - if (texture != NULL) - { - // si le rectangle a une texture - if (texture != &tex_black && texture != &tex_white) - { - texture_coordinates(current_poly, vertex, texture, visible, width, height); - } - - // tronque le polygon devant le plan avant de la camera - clip_depth(vertex, &vertex_length); - - // calcul des coordonnes apres perspective et decalage au centre de l ecran - transform_camera_to_screen(vertex, vertex_length); - - // tronque le polygon sur les bords de l ecran - clip_viewport(vertex, &vertex_length); - - // calcul des coordonnees de profondeur - transform_camera_to_screen2(vertex, vertex_length); - - // affiche les triangles - if (visible == FRONT) - { - for (int k = 1; k1; k--) - { - render_triangle(&vertex[0], &vertex[k], &vertex[k-1], texture); - } - } - } - } - } - } else { - current_object->on_screen = false; - } - } - } - - nb_object_on_screen = temp_nb_object_on_screen; - object_cursor = temp_object_cursor; - poly_cursor = temp_poly_cursor; -} - - -void Windmill::draw_post_treatment() -{ - char* vram = get_vram_address(); - unsigned char mask; - int current, right, bottom, left; - - for (int y = viewport.y1; y> ((x+1) & 7); - vram[address>>3] |= mask; - - //ML_pixel(x+1, y, ML_BLACK); - } - if (bottom < MAX_DEPTH_Z_BUFFER) - { - dpixel(x, y+1, C_BLACK); - //ML_pixel(x, y+1, ML_BLACK); - } - } else { - if (right == MAX_DEPTH_Z_BUFFER or bottom == MAX_DEPTH_Z_BUFFER) - { - dpixel(x, y+1, C_BLACK); - //ML_pixel(x, y, ML_BLACK); - } - } - } - - } // 21 fps 21,5 fps*/ - - /*left = z_buffer[0]; - for (int i = 1; i> (i & 7); - vram[(i - z_buffer_offset)>>3] |= mask; - } - } else { - if (left < MAX_DEPTH_Z_BUFFER) - { - mask = 128 >> ((i-1) & 7); - vram[(i - 1 - z_buffer_offset)>>3] |= mask; - - } - } - } - // sans rien 28 fps - // avec le i+1 : 24 fps - // avec le i : 25 fps - // calculer left = Z_buffer[i-1] dans if : 24 fps - // avec les deux cote : 24 fps ! */ - - bool flag = false; - for (int i = 0; i> ((i-2) & 7); - vram[(i - 2 - z_buffer_offset)>>3] |= mask; - flag = false; - } else { - // l objet commencait en fait 1 pixel a gauche - mask = 128 >> ((i-1) & 7); - vram[(i - 1 - z_buffer_offset)>>3] |= mask; - flag = false; - } - } - } else { - if (flag == false) - { - if (z_buffer[i-1] == MAX_DEPTH_Z_BUFFER) - { - // il y avait rien juste a gauche - mask = 128 >> (i & 7); - vram[(i - z_buffer_offset)>>3] |= mask; - flag = true; - } else { - // l objet commencait en fait 1 pixel a gauche - mask = 128 >> ((i-1) & 7); - vram[(i - 1 - z_buffer_offset)>>3] |= mask; - flag = true; - } - } - } - } // 24 fps - // avec astuce +=2 : 25 fps - - /*bool flag = false; - char i_mod_8; - for (int i = 0; i> i_mod_8;//((i-1) & 7); - flag = false; - } - } else { - if (flag == false) - { - mask |= 128 >> i_mod_8; - flag = true; - } - } - if (i_mod_8 == 7) - { - //if (mask > 0) - vram[i>>3] |= mask; - mask = 0; - } - }*/ -} - - -void Windmill::draw_body() -{ - /*int x = camera.x; - int y = camera.y; - int z = camera.z; - - Vertex v0, v1, v2, v3; - set_vertex_xyz() - METTRE DIRECT LES VERTEX DANS LE REPERE SCREEN PUIS RENDER... -*/ -} - - - - - -//---------------------------------------------------------------------------------------------------- -// TRANSFORMATION 3D -//---------------------------------------------------------------------------------------------------- -void Windmill::transform_model_to_world(Vertex vertex[], int vertex_length, Object* object, int cosinus, int sinus) -{ - for (int k = 0; kaxe == N) - { - vertex[k].x = vertex_x + object->x; - vertex[k].y = vertex_y + object->y; - vertex[k].z = vertex_z + object->z; - } - if (object->axe == X) - { - vertex[k].x = vertex_x + object->x; - vertex[k].y = ((vertex_y * cosinus - vertex_z * sinus) >> 10) + object->y; - vertex[k].z = ((vertex_y * sinus + vertex_z * cosinus) >> 10) + object->z; - } - if (object->axe == Y) - { - vertex[k].x = ((vertex_x * cosinus - vertex_z * sinus) >> 10) + object->x; - vertex[k].y = vertex_y + object->y; - vertex[k].z = ((vertex_x * sinus + vertex_z * cosinus) >> 10) + object->z; - } - if (object->axe == Z or object->axe == Z_BILLBOARD) - { - vertex[k].x = ((vertex_x * cosinus - vertex_y * sinus) >> 10) + object->x; - vertex[k].y = ((vertex_x * sinus + vertex_y * cosinus) >> 10) + object->y; - vertex[k].z = vertex_z + object->z; - } - - } -} - - -void Windmill::transform_world_to_camera(Vertex vertex[], int vertex_length) -{ - for (int k = 0; kz_normalized = (1<<15) * (vertex->z * camera.far - SCALE_AI * camera.far * camera.near) / (vertex->z * (camera.far - camera.near)); - // precalcul de 1/z - vertex[k].z = (1<<20) / vertex[k].z; - } -} - - - - - -//---------------------------------------------------------------------------------------------------- -// TEST VISIBILITE -//---------------------------------------------------------------------------------------------------- -bool Windmill::fast_check(Vertex vertex[], int vertex_length) -{ - int near = camera.near * SCALE_AI; - int far = camera.far * SCALE_AI; - - for (int i = 0; i= near and vertex[i].z < far) return true; - } - - return false; -} - - -bool Windmill::inside_viewport(int x, int y) -{ - return (x < viewport.x2 and y >= viewport.y1 and x >= viewport.x1 and y < viewport.y2); -} - - -int Windmill::visible_face(Vertex* a, Vertex* b, Vertex* c) -{ - int nx = ((b->y - a->y) * (c->z - a->z) - (b->z - a->z) * (c->y - a->y)) >> 15; - int ny = ((b->z - a->z) * (c->x - a->x) - (b->x - a->x) * (c->z - a->z)) >> 15; - int nz = ((b->x - a->x) * (c->y - a->y) - (b->y - a->y) * (c->x - a->x)) >> 15; - return (nx*a->x + ny*a->y + nz*a->z > 0) ? BACK : FRONT; -} - - - -// Sutherland–Hodgman algorithm -void Windmill::clip_depth(Vertex vertex_input[], int* vertex_input_length) -{ - Vertex vertex_temp; - Vertex vertex_output[10]; - int vertex_output_length = 0; - - int S = *vertex_input_length-1; - - for (int E = 0; E<*vertex_input_length; E++) - { - if (clip_depth_inside_edge(&vertex_input[E]) == true) - { - if (clip_depth_inside_edge(&vertex_input[S]) == false) - { - clip_depth_edge(&vertex_input[E], &vertex_input[S], &vertex_temp); - copy_vertex(&vertex_temp, &vertex_output[vertex_output_length]); - vertex_output_length += 1; - } - copy_vertex(&vertex_input[E], &vertex_output[vertex_output_length]); - vertex_output_length += 1; - - } else if (clip_depth_inside_edge(&vertex_input[S]) == true) - { - clip_depth_edge(&vertex_input[S], &vertex_input[E], &vertex_temp); - copy_vertex(&vertex_temp, &vertex_output[vertex_output_length]); - vertex_output_length += 1; - } - S = E; - - } - - *vertex_input_length = vertex_output_length; - for (int i = 0; i<*vertex_input_length; i++) - { - copy_vertex(&vertex_output[i], &vertex_input[i]); - } -} - - -void Windmill::clip_depth_edge(Vertex* vertex_in, Vertex* vertex_out, Vertex* vertex_set) -{ - int near, x_near, y_near, z_near, w_near, h_near; - float t; - - near = camera.near * SCALE_AI; - t = float(near - vertex_in->z) / float(vertex_out->z - vertex_in->z); - - x_near = (vertex_out->x - vertex_in->x) * t + vertex_in->x; - y_near = (vertex_out->y - vertex_in->y) * t + vertex_in->y; - z_near = near; - - w_near = (vertex_out->w - vertex_in->w) * t + vertex_in->w; - h_near = (vertex_out->h - vertex_in->h) * t + vertex_in->h; - - vertex_set->set_xyz(x_near, y_near, z_near); - vertex_set->set_wh(w_near, h_near); -} - - -bool Windmill::clip_depth_inside_edge(Vertex* vertex) -{ - return (vertex->z >= camera.near * SCALE_AI) ? true : false; -} - - -// Sutherland–Hodgman algorithm -void Windmill::clip_viewport(Vertex vertex_input[], int* vertex_input_length) -{ - Vertex vertex_temp; - - Vertex vertex_output[10]; - int vertex_output_length = *vertex_input_length; - - for (int i = 0; i<*vertex_input_length; i++) - { - copy_vertex(&vertex_input[i], &vertex_output[i]); - } - - for (int edge = 0; edge < 4; edge++) - { - for (int i = 0; ix) / float(vertex_out->x - vertex_in->x); - x_set = viewport.x2-1; - y_set = (vertex_out->y - vertex_in->y) * t + vertex_in->y; - } - if (edge == 1) - { - t = float(viewport.y1 - vertex_in->y) / float(vertex_out->y - vertex_in->y); - x_set = (vertex_out->x - vertex_in->x) * t + vertex_in->x; - y_set = viewport.y1; - } - if (edge == 2) - { - t = float(viewport.x1 - vertex_in->x) / float(vertex_out->x - vertex_in->x); - x_set = viewport.x1; - y_set = (vertex_out->y - vertex_in->y) * t + vertex_in->y; - } - if (edge == 3) - { - t = float(viewport.y2 - 1 - vertex_in->y) / float(vertex_out->y - vertex_in->y); - x_set = (vertex_out->x - vertex_in->x) * t + vertex_in->x; - y_set = viewport.y2-1; - } - - z_set = 0.5 + float(1) / (float(1-t)/float(vertex_in->z) + float(t)/float(vertex_out->z)); - w_set = z_set * ( (1.0-t) * vertex_in->w / float(vertex_in->z) + t * vertex_out->w / float(vertex_out->z) ); - h_set = z_set * ( (1.0-t) * vertex_in->h / float(vertex_in->z) + t * vertex_out->h / float(vertex_out->z) ); - - - vertex_set->set_xyz(x_set, y_set, z_set); - vertex_set->set_wh(w_set, h_set); -} - - -bool Windmill::clip_viewport_inside_edge(Vertex* vertex, int edge) -{ - // 0 : RIGHT 1 : UP 2: LEFT 3 : DOWN - if (edge == 0 and vertex->x < viewport.x2-1) return true; - if (edge == 1 and vertex->y > viewport.y1) return true; - if (edge == 2 and vertex->x > viewport.x1) return true; - if (edge == 3 and vertex->y < viewport.y2-1) return true; - - return false; -} - - - - - -//---------------------------------------------------------------------------------------------------- -// DESSIN DES TRIANGLES -//---------------------------------------------------------------------------------------------------- -void Windmill::render_triangle(Vertex* vertexA, Vertex* vertexB, Vertex* vertexC, const Texture *texture)//, bool billboard) -{ - //render_triangle_black(vertexA, vertexB, vertexC); - if (texture == NULL) return; - if (texture == &tex_black) - { - render_triangle_black(vertexA, vertexB, vertexC); - } - else if (texture == &tex_white) - { - render_triangle_white(vertexA, vertexB, vertexC); - } - else if (texture->transparent == true) - { - render_triangle_transparent(vertexA, vertexB, vertexC, texture); - } - else - { - render_triangle_texture(vertexA, vertexB, vertexC, texture); - } -} - - -void Windmill::render_triangle_texture(Vertex* vertexA, Vertex* vertexB, Vertex* vertexC, const Texture* texture) -{ - // calcul du rectangle circonscrit au triangle - int min_x = max(viewport.x1, min(vertexA->x, min(vertexB->x, vertexC->x))); - int max_x = min(viewport.x2-1, max(vertexA->x, max(vertexB->x, vertexC->x))); - int min_y = max(viewport.y1, min(vertexA->y, min(vertexB->y, vertexC->y))); - int max_y = min(viewport.y2-1, max(vertexA->y, max(vertexB->y, vertexC->y))); - - // calcul de l'aire du triangle - int area = edge(vertexA, vertexB, vertexC); - // determine si la taille du triangle est trop petite - if (area <= MIN_AREA_CLIP) return; - - // pre-calcul des coordonnees de la texture - int w0 = vertexA->w * vertexA->z; int h0 = vertexA->h * vertexA->z; - int w1 = vertexB->w * vertexB->z; int h1 = vertexB->h * vertexB->z; - int w2 = vertexC->w * vertexC->z; int h2 = vertexC->h * vertexC->z; - - // calcul des produits vectoriels - int u0_start = edge_start(vertexB, vertexC, min_x, min_y); - int u0_step_x = edge_step_x(vertexB, vertexC); - int u0_step_y = edge_step_y(vertexB, vertexC); - int u1_start = edge_start(vertexC, vertexA, min_x, min_y); - int u1_step_x = edge_step_x(vertexC, vertexA); - int u1_step_y = edge_step_y(vertexC, vertexA); - int u2_start = edge_start(vertexA, vertexB, min_x, min_y); - int u2_step_x = edge_step_x(vertexA, vertexB); - int u2_step_y = edge_step_y(vertexA, vertexB); - - int z_num_start = (u0_start * vertexA->z_normalized + u1_start * vertexB->z_normalized + u2_start * vertexC->z_normalized) / area; - int z_num_step_x = (u0_step_x * vertexA->z_normalized + u1_step_x * vertexB->z_normalized + u2_step_x * vertexC->z_normalized) / area; - int z_num_step_y = (u0_step_y * vertexA->z_normalized + u1_step_y * vertexB->z_normalized + u2_step_y * vertexC->z_normalized) / area; - - int z_div_start = u0_start * vertexA->z + u1_start * vertexB->z + u2_start * vertexC->z; - int z_div_step_x = u0_step_x * vertexA->z + u1_step_x * vertexB->z + u2_step_x * vertexC->z; - int z_div_step_y = u0_step_y * vertexA->z + u1_step_y * vertexB->z + u2_step_y * vertexC->z; - - // rapprochement artificiel si texture de type decoration - int decoration = (texture->decoration ? DECORATION_OFFSET : 0); - - // acces a la vram - char* vram = get_vram_address(); - unsigned char mask_vram, mask_w; - int offset_vram; - int address; - - int u0, u1, u2; - int z_num, z_div; - int w, h; - - // pre-calcul largeur en octet des tableaux - int nbw_tex = ((texture->pixel_width - 1) >> 3) + 1; - char loop_w_tex = texture->pixel_width-1; - char loop_h_tex = texture->pixel_height-1; - - // parcours en ligne - for(int x=min_x; x<=max_x; x++) - { - u0 = u0_start; u1 = u1_start; u2 = u2_start; - z_num = z_num_start; - z_div = z_div_start; - offset_vram = x >> 3; - mask_vram = 128 >> (x & 7); - // parcours en colonne - for(int y=min_y; y<=max_y; y++) - { - // si le pixel (x;y) est dans le triangle - if ((u0 | u1 | u2) > 0) - { - // addresse du z-buffer - address = x + y * z_buffer_width + z_buffer_offset; - // si le pixel (x;y) est plus proche qu'avant - if (z_num <= z_buffer[address] + decoration) - { - // calcul des coordonnees pour la texture - w = ((u0 * w0 + u1 * w1 + u2 * w2) / z_div) & loop_w_tex; - h = ((u0 * h0 + u1 * h1 + u2 * h2) / z_div) & loop_h_tex; - // calcul du masque pour l'octet - mask_w = 128 >> (w & 7); - if (texture->mask == NULL) - { - // enregistre la profondeur du pixel dans le z buffer - z_buffer[address] = z_num; - if ((texture->sprite[(w >> 3) + (h * nbw_tex)] & mask_w)) - { - // afficher pixel noir - vram[(y << 4) + offset_vram] |= mask_vram; - }else{ - // afficher pixel blanc - vram[(y << 4) + offset_vram] &= ~mask_vram; - } - // curseur - pixel_on_cursor(x, y); - } else { - int alpha = (w >> 3) + (h * nbw_tex); - if ((texture->mask[alpha] & mask_w)) - { - // enregistre la profondeur du pixel dans le z buffer - z_buffer[address] = z_num; - if ((texture->sprite[alpha] & mask_w)) - { - // afficher pixel noir - vram[(y << 4) + offset_vram] |= mask_vram; - }else{ - // afficher pixel blanc - vram[(y << 4) + offset_vram] &= ~mask_vram; - } - // curseur - pixel_on_cursor(x, y); - } - } - - } - } - u0 += u0_step_y; u1 += u1_step_y; u2 += u2_step_y; - z_num += z_num_step_y; - z_div += z_div_step_y; - } - u0_start += u0_step_x; u1_start += u1_step_x; u2_start += u2_step_x; - z_num_start += z_num_step_x; - z_div_start += z_div_step_x; - } -} - - - - -void Windmill::render_triangle_black(Vertex* vertexA, Vertex* vertexB, Vertex* vertexC) -{ - // calcul du rectangle circonscrit au triangle - int min_x = max(viewport.x1, min(vertexA->x, min(vertexB->x, vertexC->x))); - int max_x = min(viewport.x2-1, max(vertexA->x, max(vertexB->x, vertexC->x))); - int min_y = max(viewport.y1, min(vertexA->y, min(vertexB->y, vertexC->y))); - int max_y = min(viewport.y2-1, max(vertexA->y, max(vertexB->y, vertexC->y))); - - // calcul de l'aire du triangle - int area = edge(vertexA, vertexB, vertexC); - // termine si la taille du triangle est trop petite - if (area <= MIN_AREA_CLIP) return; - - // calcul des produits vectoriels - int u0_start = edge_start(vertexB, vertexC, min_x, min_y); - int u0_step_x = edge_step_x(vertexB, vertexC); - int u0_step_y = edge_step_y(vertexB, vertexC); - int u1_start = edge_start(vertexC, vertexA, min_x, min_y); - int u1_step_x = edge_step_x(vertexC, vertexA); - int u1_step_y = edge_step_y(vertexC, vertexA); - int u2_start = edge_start(vertexA, vertexB, min_x, min_y); - int u2_step_x = edge_step_x(vertexA, vertexB); - int u2_step_y = edge_step_y(vertexA, vertexB); - - int z_num_start = (u0_start * vertexA->z_normalized + u1_start * vertexB->z_normalized + u2_start * vertexC->z_normalized) / area; - int z_num_step_x = (u0_step_x * vertexA->z_normalized + u1_step_x * vertexB->z_normalized + u2_step_x * vertexC->z_normalized) / area; - int z_num_step_y = (u0_step_y * vertexA->z_normalized + u1_step_y * vertexB->z_normalized + u2_step_y * vertexC->z_normalized) / area; - - // acces a la vram - char* vram = get_vram_address(); - unsigned char mask_vram; - int offset_vram; - int address; - - int u0, u1, u2; - int z_num; - - // parcours en ligne - for(int x=min_x; x<=max_x; x++) - { - u0 = u0_start; u1 = u1_start; u2 = u2_start; - z_num = z_num_start; - offset_vram = x >> 3; - mask_vram = 128 >> (x & 7); - // parcours en colonne - for(int y=min_y; y<=max_y; y++) - { - // si le pixel (x;y) est dans le triangle - if ((u0 | u1 | u2) > 0) - { - // addresse du z-buffer - address = x + y * z_buffer_width + z_buffer_offset; - // si le pixel (x;y) est plus proche qu'avant - if (z_num <= z_buffer[address]) - { - // enregistre la profondeur du pixel dans le z buffer - z_buffer[address] = z_num; - // afficher pixel noir - vram[(y << 4) + offset_vram] |= mask_vram; - // curseur - pixel_on_cursor(x, y); - } - } - u0 += u0_step_y; u1 += u1_step_y; u2 += u2_step_y; - z_num += z_num_step_y; - } - u0_start += u0_step_x; u1_start += u1_step_x; u2_start += u2_step_x; - z_num_start += z_num_step_x; - } -} - -/* -void Windmill::render_triangle_black(Vertex* vertexA, Vertex* vertexB, Vertex* vertexC) -{ - // calcul du rectangle circonscrit au triangle - int min_x = max(viewport.x1, min(vertexA->x, min(vertexB->x, vertexC->x))); - int max_x = min(viewport.x2-1, max(vertexA->x, max(vertexB->x, vertexC->x))); - int min_y = max(viewport.y1, min(vertexA->y, min(vertexB->y, vertexC->y))); - int max_y = min(viewport.y2-1, max(vertexA->y, max(vertexB->y, vertexC->y))); - - // calcul de l'aire du triangle - int area = edge(vertexA, vertexB, vertexC); - // termine si la taille du triangle est trop petite - if (area <= MIN_AREA_CLIP) return; - - // calcul des produits vectoriels - int u0_start = edge_start(vertexB, vertexC, min_x, min_y); - int u0_step_x = edge_step_x(vertexB, vertexC); - int u0_step_y = edge_step_y(vertexB, vertexC); - int u1_start = edge_start(vertexC, vertexA, min_x, min_y); - int u1_step_x = edge_step_x(vertexC, vertexA); - int u1_step_y = edge_step_y(vertexC, vertexA); - int u2_start = edge_start(vertexA, vertexB, min_x, min_y); - int u2_step_x = edge_step_x(vertexA, vertexB); - int u2_step_y = edge_step_y(vertexA, vertexB); - - int z_num_start = (u0_start * vertexA->z_normalized + u1_start * vertexB->z_normalized + u2_start * vertexC->z_normalized) / area; - int z_num_step_x = (u0_step_x * vertexA->z_normalized + u1_step_x * vertexB->z_normalized + u2_step_x * vertexC->z_normalized) / area; - int z_num_step_y = (u0_step_y * vertexA->z_normalized + u1_step_y * vertexB->z_normalized + u2_step_y * vertexC->z_normalized) / area; - - // acces a la vram -// char* vram = get_vram_address(); - unsigned char mask_vram; - int offset_vram; - int address; - - int u0, u1, u2; - int z_num; - - // parcours en ligne - for(int x=min_x; x<=max_x; x++) - { - u0 = u0_start; u1 = u1_start; u2 = u2_start; - z_num = z_num_start; - offset_vram = x >> 3; - mask_vram = 128 >> (x & 7); - // parcours en colonne - for(int y=min_y; y<=max_y; y++) - { - // si le pixel (x;y) est dans le triangle - if ((u0 | u1 | u2) > 0) - { - // addresse du z-buffer - address = x + y * z_buffer_width + z_buffer_offset; - // si le pixel (x;y) est plus proche qu'avant - if (z_num <= z_buffer[address]) - { - // enregistre la profondeur du pixel dans le z buffer - z_buffer[address] = z_num; - // afficher pixel noir -// vram[(y << 4) + offset_vram] |= mask_vram; - // curseur - pixel_on_cursor(x, y); - } - } - u0 += u0_step_y; u1 += u1_step_y; u2 += u2_step_y; - z_num += z_num_step_y; - } - u0_start += u0_step_x; u1_start += u1_step_x; u2_start += u2_step_x; - z_num_start += z_num_step_x; - } -} -*/ - -void Windmill::render_triangle_white(Vertex* vertexA, Vertex* vertexB, Vertex* vertexC) -{ - // calcul du rectangle circonscrit au triangle - int min_x = max(viewport.x1, min(vertexA->x, min(vertexB->x, vertexC->x))); - int max_x = min(viewport.x2-1, max(vertexA->x, max(vertexB->x, vertexC->x))); - int min_y = max(viewport.y1, min(vertexA->y, min(vertexB->y, vertexC->y))); - int max_y = min(viewport.y2-1, max(vertexA->y, max(vertexB->y, vertexC->y))); - - // calcul de l'aire du triangle - int area = edge(vertexA, vertexB, vertexC); - // termine si la taille du triangle est trop petite - if (area <= MIN_AREA_CLIP) return; - - // calcul des produits vectoriels - int u0_start = edge_start(vertexB, vertexC, min_x, min_y); - int u0_step_x = edge_step_x(vertexB, vertexC); - int u0_step_y = edge_step_y(vertexB, vertexC); - int u1_start = edge_start(vertexC, vertexA, min_x, min_y); - int u1_step_x = edge_step_x(vertexC, vertexA); - int u1_step_y = edge_step_y(vertexC, vertexA); - int u2_start = edge_start(vertexA, vertexB, min_x, min_y); - int u2_step_x = edge_step_x(vertexA, vertexB); - int u2_step_y = edge_step_y(vertexA, vertexB); - - int z_num_start = (u0_start * vertexA->z_normalized + u1_start * vertexB->z_normalized + u2_start * vertexC->z_normalized) / area; - int z_num_step_x = (u0_step_x * vertexA->z_normalized + u1_step_x * vertexB->z_normalized + u2_step_x * vertexC->z_normalized) / area; - int z_num_step_y = (u0_step_y * vertexA->z_normalized + u1_step_y * vertexB->z_normalized + u2_step_y * vertexC->z_normalized) / area; - - // acces a la vram - char* vram = get_vram_address(); - unsigned char mask_vram; - int offset_vram; - int address; - - int u0, u1, u2; - int z_num; - - // parcours en ligne - for(int x=min_x; x<=max_x; x++) - { - u0 = u0_start; u1 = u1_start; u2 = u2_start; - z_num = z_num_start; - offset_vram = x >> 3; - mask_vram = 128 >> (x & 7); - // parcours en colonne - for(int y=min_y; y<=max_y; y++) - { - // si le pixel (x;y) est dans le triangle - if ((u0 | u1 | u2) > 0) - { - // addresse du z-buffer - address = x + y * z_buffer_width + z_buffer_offset; - // si le pixel (x;y) est plus proche qu'avant - if (z_num <= z_buffer[address]) - { - // enregistre la profondeur du pixel dans le z buffer - z_buffer[address] = z_num; - // afficher pixel blanc - vram[(y << 4) + offset_vram] &= ~mask_vram; - // curseur - pixel_on_cursor(x, y); - } - } - u0 += u0_step_y; u1 += u1_step_y; u2 += u2_step_y; - z_num += z_num_step_y; - } - u0_start += u0_step_x; u1_start += u1_step_x; u2_start += u2_step_x; - z_num_start += z_num_step_x; - } -} - - -void Windmill::render_triangle_transparent(Vertex* vertexA, Vertex* vertexB, Vertex* vertexC, const Texture* texture) -{ - // calcul du rectangle circonscrit au triangle - int min_x = max(viewport.x1, min(vertexA->x, min(vertexB->x, vertexC->x))); - int max_x = min(viewport.x2-1, max(vertexA->x, max(vertexB->x, vertexC->x))); - int min_y = max(viewport.y1, min(vertexA->y, min(vertexB->y, vertexC->y))); - int max_y = min(viewport.y2-1, max(vertexA->y, max(vertexB->y, vertexC->y))); - - // calcul de l'aire du triangle - int area = edge(vertexA, vertexB, vertexC); - // termine si la taille du triangle est trop petite - if (area <= MIN_AREA_CLIP) return; - - // pre-calcul des coordonnees de la texture - int w0 = vertexA->w * vertexA->z; int h0 = vertexA->h * vertexA->z; - int w1 = vertexB->w * vertexB->z; int h1 = vertexB->h * vertexB->z; - int w2 = vertexC->w * vertexC->z; int h2 = vertexC->h * vertexC->z; - - // calcul des produits vectoriels - int u0_start = edge_start(vertexB, vertexC, min_x, min_y); - int u0_step_x = edge_step_x(vertexB, vertexC); - int u0_step_y = edge_step_y(vertexB, vertexC); - int u1_start = edge_start(vertexC, vertexA, min_x, min_y); - int u1_step_x = edge_step_x(vertexC, vertexA); - int u1_step_y = edge_step_y(vertexC, vertexA); - int u2_start = edge_start(vertexA, vertexB, min_x, min_y); - int u2_step_x = edge_step_x(vertexA, vertexB); - int u2_step_y = edge_step_y(vertexA, vertexB); - - int z_num_start = (u0_start * vertexA->z_normalized + u1_start * vertexB->z_normalized + u2_start * vertexC->z_normalized) / area; - int z_num_step_x = (u0_step_x * vertexA->z_normalized + u1_step_x * vertexB->z_normalized + u2_step_x * vertexC->z_normalized) / area; - int z_num_step_y = (u0_step_y * vertexA->z_normalized + u1_step_y * vertexB->z_normalized + u2_step_y * vertexC->z_normalized) / area; - - int z_div_start = u0_start * vertexA->z + u1_start * vertexB->z + u2_start * vertexC->z; - int z_div_step_x = u0_step_x * vertexA->z + u1_step_x * vertexB->z + u2_step_x * vertexC->z; - int z_div_step_y = u0_step_y * vertexA->z + u1_step_y * vertexB->z + u2_step_y * vertexC->z; - - // acces a la vram - char* vram = get_vram_address(); - - // pre-calcul largeur en octet des tableaux - int nbw_tex = ((texture->pixel_width - 1) >> 3) + 1; - char loop_w_tex = texture->pixel_width-1; - char loop_h_tex = texture->pixel_height-1; - - // parcours en ligne - for(int x=min_x; x<=max_x; x++) - { - int u0 = u0_start; int u1 = u1_start; int u2 = u2_start; - int z_num = z_num_start; - int z_div = z_div_start; - int offset_vram = x >> 3; - char mask_vram = 128 >> (x & 7); - // parcours en colonne - for(int y=min_y; y<=max_y; y++) - { - // si le pixel (x;y) est dans le triangle - if ((u0 | u1 | u2) > 0) - { - // addresse du z-buffer - int address = x + y * z_buffer_width + z_buffer_offset; - // si le pixel (x;y) est plus proche qu'avant - if (z_num <= z_buffer[address]) - { - // calcul des coordonnees pour la texture - unsigned int w = ((u0 * w0 + u1 * w1 + u2 * w2) / z_div) & loop_w_tex; - unsigned int h = ((u0 * h0 + u1 * h1 + u2 * h2) / z_div) & loop_h_tex; - // calcul du masque pour l'octet - unsigned char mask_w = 128 >> (w & 7); - if ((texture->sprite[(w >> 3) + (h * nbw_tex)] & mask_w)) - { - // afficher pixel noir - vram[(y << 4) + offset_vram] |= mask_vram; - // enregistre la profondeur du pixel dans le z buffer - z_buffer[address] = z_num; - } - } - } - u0 += u0_step_y; u1 += u1_step_y; u2 += u2_step_y; - z_num += z_num_step_y; - z_div += z_div_step_y; - } - u0_start += u0_step_x; u1_start += u1_step_x; u2_start += u2_step_x; - z_num_start += z_num_step_x; - z_div_start += z_div_step_x; - } -} - - - - -/* -//----------------------------------------------------------------------------- -// load_map -// Ritter's bounding sphere -//----------------------------------------------------------------------------- -void Windmill::load_map(Map* _map) -{ - if (map != _map) - { - map = _map; - delete[] sphere; - sphere = new Bounding_Sphere [map->list_object_length]; - for (int i = 0; ilist_object_length; i++) - { - Object* current_object = map->object[i]; - - int nb_point; - for (int j = 0; jmodele_size; j++) - { - nb_point += current_object->modele[j].type; - } - - Point* point = get_point(current_object, 0); - int min_x = point->x; - int min_y = point->y; - int min_z = point->z; - int max_x = min_x; - int max_y = min_y; - int max_z = min_z; - - for (int j = 0; jx < min_x) - min_x = point->x; - if(point->y < min_y) - min_y = point->y; - if(point->z < min_z) - min_z = point->z; - - if(point->x > max_x) - max_x = point->x; - if(point->y > max_y) - max_y = point->y; - if(point->z > max_z) - max_z = point->z; - } - int xdiff = max_x - min_x; - int ydiff = max_y - min_y; - int zdiff = max_z - min_y; - - int diameter = max(xdiff, max(ydiff, zdiff)); //take max as diameter - glm::vec3 centre = (vmax+vmin)*(0.5f); - float radius = diameter/2; - float sq_radius = radius*radius; - - for(int i=0; i sq_radius) - { - float distance = sqrt(sq_distance); - - float difference = distance - radius; - - float new_diameter = 2 * radius + difference; - sq_radius = radius * radius; - - difference /= 2; - - centre += difference * direction; - } - } - - - - } - } -}*/ - - - - - -//---------------------------------------------------------------------------------------------------- -// MANIPULATION -//---------------------------------------------------------------------------------------------------- -Point Windmill::get_point(const Modele* poly, int i) -{ - Point point; - if (i == 0) - { - point.x = poly->x0; point.y = poly->y0; point.z = poly->z0; - } - if (i == 1) - { - point.x = poly->x1; point.y = poly->y1; point.z = poly->z1; - } - if (i == 2) - { - point.x = poly->x2; point.y = poly->y2; point.z = poly->z2; - } - if (i == 3) - { - if (poly->option == PARA) - { - point.x = poly->x2 + poly->x1 - poly->x0; - point.y = poly->y2 + poly->y1 - poly->y0; - point.z = poly->z2 + poly->z1 - poly->z0; - } else if (poly->option == TRAP) - { - point.x = poly->x2 - poly->x1 + poly->x0; - point.y = poly->y2 - poly->y1 + poly->y0; - point.z = poly->z2 - poly->z1 + poly->z0; - } - } - return point; -} - - -Point Windmill::get_center_poly(const Modele* poly) -{ - Point point; - point.x = 0; point.y = 0; point.z = 0; - - for (int i = 0; i < poly->type; i++) - { - point.x += get_point(poly, i).x; - point.y += get_point(poly, i).y; - point.z += get_point(poly, i).z; - } - - point.x /= poly->type; - point.y /= poly->type; - point.z /= poly->type; - - return point; -} - - -void Windmill::compute_object_angle(Object* object, int* cosinus, int* sinus) -{ - if (object->axe == Z_BILLBOARD) - { - float angle_look_at_camera = atan2f(camera.y - object->y, camera.x - object->x); - float angle_rad = angle_look_at_camera + 3.1415 * object->angle / 180.0; - *cosinus = 1024 * cosf(angle_rad); - *sinus = 1024 * sinf(angle_rad); - } - if (object->axe == X or object->axe == Y or object->axe == Z) - { - float angle_rad = 3.1415 * object->angle / 180.0; - *cosinus = 1024 * cosf(angle_rad); - *sinus = 1024 * sinf(angle_rad); - } -} - - -void Windmill::extract_vertex_from_poly(const Modele* poly, Vertex* vertex, int* vertex_length, int* width, int* height) -{ - int x0, y0, z0, x1, y1, z1, x2, y2, z2, x3, y3, z3; - - if (poly->type == TRIANGLE) - { - *vertex_length = 3; - x0 = poly->x0; y0 = poly->y0; z0 = poly->z0; - x1 = poly->x1; y1 = poly->y1; z1 = poly->z1; - x2 = poly->x2; y2 = poly->y2; z2 = poly->z2; - vertex[0].set_xyz(x0, y0, z0); - vertex[1].set_xyz(x1, y1, z1); - vertex[2].set_xyz(x2, y2, z2); - *width = distance(x0-x1, y0-y1, z0-z1); - *height = distance(x0-x2, y0-y2, z0-z2); - } - if (poly->type == RECTANGLE) - { - *vertex_length = 4; - x0 = poly->x0; y0 = poly->y0; z0 = poly->z0; - x1 = poly->x1; y1 = poly->y1; z1 = poly->z1; - x3 = poly->x2; y3 = poly->y2; z3 = poly->z2; - if (poly->option == PARA) - { - x2 = x3 + x1 - x0; y2 = y3 + y1 - y0; z2 = z3 + z1 - z0; - } else if (poly->option == TRAP) - { - //x2 = x3 - x1 + x0; y2 = y3 - y1 + y0; z2 = z3 - z1 + z0; - } - vertex[0].set_xyz(x0, y0, z0); - vertex[1].set_xyz(x1, y1, z1); - vertex[2].set_xyz(x2, y2, z2); - vertex[3].set_xyz(x3, y3, z3); - *width = distance(x0-x1, y0-y1, z0-z1); - *height = distance(x0-x3, y0-y3, z0-z3); - } -} - - -void Windmill::texture_coordinates(const Modele* poly, Vertex* vertex, const Texture* texture, int visible, int width, int height) -{ - int w = (texture->real_width > 0) ? width * texture->pixel_width / texture->real_width : texture->pixel_width; - int h = (texture->real_height > 0) ? height * texture->pixel_height / texture->real_height : texture->pixel_height; - - if (poly->type == TRIANGLE) - { - int offset = w * texture->offset; - if (visible == FRONT or texture->mirror == true) - { - vertex[0].set_wh(0, texture->pixel_height); - vertex[1].set_wh(w, texture->pixel_height); - vertex[2].set_wh(offset, texture->pixel_height-h); - // vertex[0].set_wh(0, h); - // vertex[1].set_wh(w, h); - // vertex[2].set_wh(offset, 0); - } else { - vertex[0].set_wh(w, h); - vertex[1].set_wh(0, h); - vertex[2].set_wh(w-offset, 0); - } - } - else if (poly->type == RECTANGLE) - { - if (visible == FRONT or texture->mirror == true) - { - vertex[0].set_wh(0, texture->pixel_height); - vertex[1].set_wh(w, texture->pixel_height); - vertex[2].set_wh(w, texture->pixel_height-h); - vertex[3].set_wh(0, texture->pixel_height-h); - - // vertex[0].set_wh(0, h); - // vertex[1].set_wh(w, h); - // vertex[2].set_wh(w, 0); - // vertex[3].set_wh(0, 0); - } else { - vertex[0].set_wh(w, h); - vertex[1].set_wh(0, h); - vertex[2].set_wh(0, 0); - vertex[3].set_wh(w, 0); - } - } -} - - -void Windmill::swap_vertex(Vertex* vertexA, Vertex* vertexB) -{ - Vertex vertex_temp; - memcpy(&vertex_temp, vertexA, sizeof(Vertex)); - memcpy(vertexA, vertexB, sizeof(Vertex)); - memcpy(vertexB, &vertex_temp, sizeof(Vertex)); -} - - -void Windmill::copy_vertex(Vertex* vertex_source, Vertex* vertex_dest) -{ - memcpy(vertex_dest, vertex_source, sizeof(Vertex)); -} - - - -//---------------------------------------------------------------------------------------------------- -// SPHERE -//---------------------------------------------------------------------------------------------------- -Sphere Windmill::transform_sphere_to_world(Sphere* sphere_input, Object* object, int cosinus, int sinus) -{ - Vertex vertex; - vertex.set_xyz(sphere_input->x, sphere_input->y, sphere_input->z); - transform_model_to_world(&vertex, 1, object, cosinus, sinus); - transform_world_to_camera(&vertex, 1); - Sphere sphere_output; - sphere_output.x = vertex.x >> 7; - sphere_output.y = vertex.y >> 7; - sphere_output.z = vertex.z >> 7; - sphere_output.radius = sphere_input->radius; - - return sphere_output; -} - -/* -bool Windmill::sphere_in_cone(Sphere* sphere) -{ - //return true; - int cone_offset = sphere->radius * camera.sin_fov; - - int nx = camera.nx; - int ny = camera.ny; - int nz = camera.nz; - - Point cone; - cone.x = int(camera.x) - ((nx * cone_offset) >> 14); - cone.y = int(camera.y) - ((ny * cone_offset) >> 14); - cone.z = int(camera.z) - ((nz * cone_offset) >> 14); - - int sx = sphere->x - cone.x; - int sy = sphere->y - cone.y; - int sz = sphere->z - cone.z; - int ss = sx*sx + sy*sy + sz*sz; - - // si sommet du cone dans la sphere - if (ss <= sphere->radius * sphere->radius) - { - return true; - } - - // si sphere dans le cone - int ns = ((nx * sx) >> 7) + ((ny * sy) >> 7) + ((nz * sz) >> 7); - - if (ns > 0 and ns*ns > camera.cos_fov_square * ss) - { - return true; - } - return false; -}*/ - -bool Windmill::sphere_in_cone(Sphere* sphere) -{ - //return true; - sphere->z += sphere->radius; - if (sphere->z > 0) - { - int sphere_z = int(sphere->z * camera.scale_coef) >> 6; - int xr = 0; - if (sphere->x > 0) xr = sphere->x - sphere->radius; - if (sphere->x < 0) xr = - sphere->x - sphere->radius; - - if (xr <= sphere_z) return true; - } - return false; -} - - - -//---------------------------------------------------------------------------------------------------- -// DIVERS -//---------------------------------------------------------------------------------------------------- -void Windmill::copy_camera() -{ - memcpy(&camera, camera2, sizeof(Camera)); -} - - -void Windmill::sort_object() -{ - //qsort(object, list_object_length, sizeof(Object*), compare_object); -} - - -int compare_object(void const *a, void const *b) -{ - Object* object_a = *(Object **) a; - Object* object_b = *(Object **) b; - return (object_a->distance_to_camera - object_b->distance_to_camera); -} - - -void Windmill::clear_z_buffer() -{ - memset(z_buffer, MAX_DEPTH_Z_BUFFER, z_buffer_size * sizeof(short)); -} - - -int Windmill::edge(Vertex* a, Vertex* b, Vertex* c) -{ - return (c->x - a->x) * (b->y - a->y) - (c->y - a->y) * (b->x - a->x); -} - - -int Windmill::edge_start(Vertex* a, Vertex* b, int px, int py) -{ - return (b->y - a->y) * (px - a->x) - (b->x - a->x) * (py - a->y); -} - - -int Windmill::edge_step_x(Vertex* a, Vertex* b) -{ - return b->y - a->y; -} - - -int Windmill::edge_step_y(Vertex* a, Vertex* b) -{ - return a->x - b->x; -} - - - -//---------------------------------------------------------------------------------------------------- -// UTILITAIRE -//---------------------------------------------------------------------------------------------------- -void Windmill::pixel_on_cursor(int x, int y) -{ - if (x == cursor_x and y == cursor_y) - { - temp_object_cursor = object[i]; - temp_poly_cursor = j; - } -} - - -void Windmill::show_coordinates() -{ - // coordonnees - float tab_coordinates[5] = {camera.x, camera.y, camera.z, to_deg(camera.yaw), to_deg(camera.pitch)}; - for (int i = 0; i < 5; i++) - { - /* - char str[20]; - sprintf(str, "%f", tab_coordinates[i]); - int j; - for(j= 0; j < 16; j++) - { - if (str[j] == '.') - { - str[j+2] = '\0'; - break; - } - } - PrintMini(127-4*(j+2), 1+6*i, (unsigned char*)str, MINI_OVER);*/ - dprint(0, 1+6*i, C_BLACK, "%f", tab_coordinates[i]); // need Gint - } -} - - -void Windmill::show_repere() -{/* - // repere - int repere_x = 112; - int repere_y = 55; - int repere_size = 12; - - float camera_yaw_rad = -camera.yaw;//- 3.1415 * camera.yaw / 180.0; - float camera_pitch_rad = camera.pitch;//3.1415 * camera.pitch / 180.0; - float cos_yaw = cosf(camera_yaw_rad); - float sin_yaw = sinf(camera_yaw_rad); - float cos_pitch = cosf(camera_pitch_rad); - float sin_pitch = sinf(camera_pitch_rad); - float aa4 = sin_yaw; - float aa5 = cos_yaw; - float aa6 = 0; - float aa7 = -sin_pitch * cos_yaw; - float aa8 = sin_pitch * sin_yaw; - float aa9 = cos_pitch; - // repere - Vertex v[3]; - //const unsigned char* cx = "x"; - //const unsigned char* cy = "y"; - //const unsigned char* cz = "z"; - const char* letter[] = {"x", "y", "z"}; - v[0].set_xyz(repere_size, 0 , 0 ); - v[1].set_xyz(0 , repere_size, 0 ); - v[2].set_xyz(0 , 0 , repere_size); - for (int i = 0; i < 3; i++) - { - float y = (aa4 * v[i].x + aa5 * v[i].y + aa6 * v[i].z); - float z = (aa7 * v[i].x + aa8 * v[i].y + aa9 * v[i].z); - v[i].x = -y; - v[i].y = -z; - //ML_line(repere_x, repere_y, v[i].x + repere_x, v[i].y + repere_y, ML_BLACK); - //PrintMini(v[i].x + repere_x, v[i].y + repere_y-2, letter[i], MINI_OVER); - } - */ -} - - -/*void Windmill::show_fps() -{ - char str[20]; - sprintf(str, "%i", time_get_fps()); - PrintMini(1, 58, (unsigned char*)str, MINI_OVER); -}*/ - - - - -//---------------------------------------------------------------------------------------------------- -// DESTRUCTEUR -//---------------------------------------------------------------------------------------------------- -Windmill::~Windmill() -{ - free(z_buffer); - free(object); - //delete[] object; -} - - - - - -float distance(float dx, float dy, float dz) -{ - return sqrtf(dx*dx + dy*dy + dz*dz); -} - -Vertex::Vertex(){} - -void Vertex::set_xyz(int _x, int _y, int _z) -{ - x = _x; - y = _y; - z = _z; -} - -void Vertex::set_wh(float _w, float _h) -{ - w = _w; - h = _h; -} - -float Vertex::length(int x, int y, int z) -{ - return sqrtf(x*x + y*y + z*z); -} diff --git a/src/windmill.hpp b/src/windmill.hpp index b434b82..8b798ee 100644 --- a/src/windmill.hpp +++ b/src/windmill.hpp @@ -7,22 +7,32 @@ #include #include #include "camera.hpp" +#include "Geometry.hpp" +#include #define get_vram_address() ((char *)gint_vram) // parametrage de Windmill #define MIN_AREA_CLIP 5 -#define DECORATION_OFFSET 50 #define MAX_DEPTH_Z_BUFFER 0xffff -enum {N, X, Y, Z, Z_BILLBOARD}; +enum {N, RX, RY, RZ, Z_BILLBOARD}; +//#define N {0, 0, 0} +//#define RX {1, 0, 0} +//#define RY {0, 1, 0} +//#define RZ {0, 0, 1} + +#define LB {0, 1} +#define RB {1, 1} +#define LT {0, 0} +#define RT {1, 0} +#define MB {0.5, 1} +#define MT {0.5, 0} +#define LM {0, 0.5} +#define RM {1, 0.5} + #define FRONT 1 #define BACK -1 -#define RIEN 0 -#define TRIANGLE 3 -#define RECTANGLE 4 -#define PARA 0 -#define TRAP 1 #define INTERIEUR true #define EXTERIEUR false @@ -37,36 +47,22 @@ enum {N, X, Y, Z, Z_BILLBOARD}; // definition des structures -struct Point -{ - int x, y, z; -}; - -class Vecteur -{ -public: - float x1, y1, x2, y2; -}; - struct Sphere { - int x, y, z; - int radius; + int x, y, z; + int radius; + int square_radius; }; -class Vertex +struct VertexPoint { -public: - int x, y, z; - float w, h; - unsigned short z_normalized; - - Vertex(); - void set_xyz(int _x, int _y, int _z); - void set_wh(float _w, float _h); - float length(int x, int y, int z); + int x, y, z; }; +struct TexturePoint +{ + float u, v; +}; struct Texture { @@ -74,49 +70,85 @@ struct Texture const unsigned char* mask; const char pixel_width; const char pixel_height; - const char real_width; - const char real_height; - const float offset; - const bool transparent; - const bool decoration; - const bool mirror; + const int real_height; + const int real_width; }; - -struct Modele +struct Face { - const int type; const Texture* texture_front; const Texture* texture_back; - const short x0, y0, z0; - const short x1, y1, z1; - const short x2, y2, z2; - const char option; + unsigned char v[3]; + unsigned char t[3]; + bool visible = true; }; +class Vertex +{ +public: + int x, y, z; + float u, v; + int inv_z; + unsigned short z_normalized; + + Vertex(); + Vertex(int _x, int _y, int _z); + Vertex(int _x, int _y, int _z, float _u, float _v); + void set_texture(TexturePoint t); + void set_xyz(int _x, int _y, int _z); +}; + +struct Mesh +{ + const VertexPoint* v; + const int v_length; + const TexturePoint* t; + const int t_length; + const Face* f; + const int f_length; +}; + +class WMesh +{ +public: + Vertex* v; + int v_length; + int v_length_allocated; + TexturePoint* t; + int t_length; + int t_length_allocated; + Face* f; + int f_length; + int f_length_allocated; + + void from_mesh(const Mesh* mesh, int margin); + void free_memory(); + void add_vertex(Vertex vertex); +}; struct Object { - short x, y, z; + // bool static = STATIC / DYNAMIC -> transform_model_to_world au chargement + const Mesh* mesh; + Point3D position; + //Vector3D rotation; + //short x, y, z; char axe; float angle; - const Modele* modele; - const int modele_size; - // ajouter ici - const char collision; - //const char for_collision; - //const char type_collision; - bool hidden; - bool on_screen; - Sphere sphere; - int distance_to_camera; -}; + //Vector3D rotation; + char collision = ALL; + bool visible = true; + + Sphere sphere; + WMesh* shadow; + //bool on_screen; +}; struct Map { Object** object; - int list_object_length; + int object_length; bool horizon; bool ground; // ajouter ici @@ -128,65 +160,50 @@ struct Viewport }; -float distance(float dx, float dy, float dz); int compare_object(void const *a, void const *b); class Windmill { public: - // initialisation et parametrage + // initialisation, parametrage et pre calcul Windmill(); void set_camera(Camera* _camera); void set_viewport(int viewport_x1, int viewport_y1, int viewport_x2, int viewport_y2); - void load_map(Map* _map); + void set_map(Map* _map); + void set_objects(); + void compute_bouding_sphere(); + void compute_shadows(); + void compute_shadows_hull(Point3D* points, int points_size); + int compute_shadows_hull_orientation(Point3D a, Point3D b, Point3D c); // dessin void draw(); void draw_horizon(); + void draw_shadows(); void draw_ground(); void draw_objects(); void draw_post_treatment(); void draw_body(); // transformation 3D des vertex - void transform_model_to_world(Vertex vertex[], int vertex_length, Object* object, int cosinus, int sinus); + void transform_model_to_world(Object* object, Vertex vertex[], int vertex_length); void transform_world_to_camera(Vertex vertex[], int vertex_length); void transform_camera_to_screen(Vertex vertex[], int vertex_length); - void transform_camera_to_screen2(Vertex vertex[], int vertex_length); - // text visiblilite - bool fast_check(Vertex vertex_list[], int vertex_list_length); + // test visiblilite + bool object_in_frustrum(Object* object); + void clip_frustrum(WMesh* mesh); + bool inside_frustrum(Vertex vertex, Plane plane, int offset = 0); + Vertex clip_plane(Vertex vertex[], int vertex_length); + Vertex clip_onto_plane(Vertex vertexA, Vertex vertexB, Plane plane); bool inside_viewport(int x, int y); - int visible_face(Vertex* a, Vertex* b, Vertex* c); - - void clip_depth(Vertex vertex_list_input[], int* vertex_list_input_length); - void clip_depth_edge(Vertex* vertex_in, Vertex* vertex_out, Vertex* vertex_set); - bool clip_depth_inside_edge(Vertex* vertex); - - void clip_viewport(Vertex vertex_list_input[], int* vertex_list_input_length); - void clip_viewport_edge(Vertex* vertex_in, Vertex* vertex_out, Vertex* vertex_set, int edge); - bool clip_viewport_inside_edge(Vertex* vertex, int edge); + int get_visible_face(Vertex* a, Vertex* b, Vertex* c); // dessin des triangles - void render_triangle(Vertex* vertex1, Vertex* vertex2, Vertex* vertex3, const Texture *texture); + void render_triangles(WMesh mesh); void render_triangle_texture(Vertex* vertex1, Vertex* vertex2, Vertex* vertex3, const Texture* texture); - void render_triangle_black(Vertex* vertex0, Vertex* vertex1, Vertex* vertex2); - void render_triangle_white(Vertex* vertex0, Vertex* vertex1, Vertex* vertex2); - void render_triangle_transparent(Vertex* vertex1, Vertex* vertex2, Vertex* vertex3, const Texture* texture); - - // manipulation - Point get_point(const Modele* poly, int i); - Point get_center_poly(const Modele* poly); - void compute_object_angle(Object* object, int* cosinus, int* sinus); - void extract_vertex_from_poly(const Modele* poly, Vertex* vertex, int* vertex_length, int* width, int* height); - void texture_coordinates(const Modele* poly, Vertex* vertex, const Texture* texture, int visible, int width, int height); - void swap_vertex(Vertex* vertexA, Vertex* vertexB); - void copy_vertex(Vertex* vertex_source, Vertex* vertex_dest); - - // sphere - Sphere transform_sphere_to_world(Sphere* sphere, Object* object, int cosinus, int sinus); - bool sphere_in_cone(Sphere* sphere); + void render_triangle_color(Vertex* vertex0, Vertex* vertex1, Vertex* vertex2, color_t color); // divers void copy_camera(); @@ -196,14 +213,13 @@ public: int edge_start(Vertex* a, Vertex* b, int px, int py); int edge_step_x(Vertex* a, Vertex* b); int edge_step_y(Vertex* a, Vertex* b); + float distance(float dx, float dy, float dz); // utilitaires - void pixel_on_cursor(int x, int y); void show_coordinates(); void show_repere(); - //void show_fps(); - // destructeurr + // destructeur ~Windmill(); private: @@ -215,8 +231,10 @@ private: Map* map; // liste objets triee - Object** object; - int list_object_length; + Object* objects; + + // ombres + Point3D sun; // z_buffer int shift_x, shift_y; @@ -229,22 +247,14 @@ private: int i; int j; - // variables temporaire pour eviter de lire la valeur en cours de calcul - int temp_nb_object_on_screen; - Object* temp_object_cursor; - int temp_poly_cursor; - public: // fenetre de visualisation Viewport viewport; // utilitaires bool loading; - int nb_object_on_screen; - Object* object_cursor; - int poly_cursor; - int cursor_x; - int cursor_y; + + bool log = false; }; diff --git a/src/windmill_clip.cpp b/src/windmill_clip.cpp new file mode 100644 index 0000000..85a702f --- /dev/null +++ b/src/windmill_clip.cpp @@ -0,0 +1,283 @@ +//---------------------------------------------------------------------------------------------------- +// +// WINDMILL +// +// version : 2.0 +// Moteur de rendu 3D base sur la methode de rasterisation avec buffer de profondeur +// +// Cree par Olivier Lanneau, alias NineStars +// Planet-casio.fr +// +//---------------------------------------------------------------------------------------------------- + + +#include "windmill.hpp" + +void debug_pop(char const *fmt, ...); +void debug_display(char const *fmt, ...); + +extern Texture tex_white; +extern Texture tex_light; +extern Texture tex_dark; +extern Texture tex_black; + + +//---------------------------------------------------------------------------------------------------- +// CLIPPING +//---------------------------------------------------------------------------------------------------- +bool Windmill::object_in_frustrum(Object* object) +{ + Vertex centre(object->sphere.x, object->sphere.y, object->sphere.z); + // calcul des coordonnees dans le repère monde apres rotation et translation du centre de l objet + transform_model_to_world(object, ¢re, 1); + + // calcul des coordonnees du centre dans le repère camera apres rotation et translation de la camera + transform_world_to_camera(¢re, 1); + + // si la camera est dans la sphere + if (centre.x*centre.x + centre.y*centre.y + centre.z*centre.z < object->sphere.square_radius) + { + return true; + } + + // si la sphere est dans le frustrum + for (int p = 0; p<5 ; p++) + { + Plane plane = camera.frustrum.sides[p]; + + if (inside_frustrum(centre, plane, object->sphere.radius) == false) return false; + } + + return true; + + // A GARDER CAR PAS MAL OPTI + /* + int cone_offset = sphere->radius * camera.sin_fov; + + int nx = camera.nx; + int ny = camera.ny; + int nz = camera.nz; + + Point3D cone; + cone.x = int(camera.x) - (nx * cone_offset); + cone.y = int(camera.y) - (ny * cone_offset); + cone.z = int(camera.z) - (nz * cone_offset); + + int sx = sphere->x - cone.x; + int sy = sphere->y - cone.y; + int sz = sphere->z - cone.z; + int ss = sx*sx + sy*sy + sz*sz; + + // si sommet du cone dans la sphere + if (ss <= sphere->radius * sphere->radius) + { + return true; + } + + // si sphere dans le cone + int ns = ((nx * sx) >> 7) + ((ny * sy) >> 7) + ((nz * sz) >> 7); + + if (ns > 0 and ns*ns > camera.cos_fov_square * ss) + { + return true; + } + return false;*/ +} + +void Windmill::clip_frustrum(WMesh* mesh) +{ + for (int p = 0; p<5 ; p++) + { + Plane plane = camera.frustrum.sides[p]; + + int init_f_length = mesh->f_length; // car sinon on va faire du clipping sur des points nouveaux issues du clipping... + + // pour chaque triangle + for (int f=0; ff[f]; + + if (triangle.visible) + { + int S = 3 - 1; + + // indice vertex pour face + int v_ok[4]; + int t_ok[4]; + int ok_indice = 0; + + // pour chaque segment + for (int E = 0; E<3; E++) + { + Vertex vertexE(mesh->v[triangle.v[E]].x, mesh->v[triangle.v[E]].y, mesh->v[triangle.v[E]].z, mesh->t[triangle.t[E]].u,mesh->t[triangle.t[E]].v); + Vertex vertexS(mesh->v[triangle.v[S]].x, mesh->v[triangle.v[S]].y, mesh->v[triangle.v[S]].z, mesh->t[triangle.t[S]].u,mesh->t[triangle.t[S]].v); + + if (inside_frustrum(vertexE, plane) == true) + { + if (inside_frustrum(vertexS, plane) == false) + { + v_ok[ok_indice] = mesh->v_length; + t_ok[ok_indice] = mesh->t_length; + ok_indice++; + + mesh->add_vertex(clip_onto_plane(vertexE, vertexS, plane)); + } + + v_ok[ok_indice] = triangle.v[E]; + t_ok[ok_indice] = triangle.t[E]; + ok_indice++; + } + else if (inside_frustrum(vertexS, plane) == true) + { + v_ok[ok_indice] = mesh->v_length; + t_ok[ok_indice] = mesh->t_length; + ok_indice++; + + mesh->add_vertex(clip_onto_plane(vertexE, vertexS, plane)); + } + + S = E; + } + + // aucun point dans le frustrum + if (ok_indice == 0) + { + mesh->f[f].visible = false; + } + + // soit les 3 points à l'intérieur du triangle, soit 2 point ouside -> on modifie la face en cours + if (ok_indice >= 3) + { + Face edited_triangle; + edited_triangle.texture_front = triangle.texture_front; + edited_triangle.texture_back = triangle.texture_back; + for (int i=0; i<3; i++) + { + edited_triangle.v[i] = v_ok[i]; + edited_triangle.t[i] = t_ok[i]; + } + mesh->f[f] = edited_triangle; // pas de verif d'overflow + } + + // 1 point en dehors = 2 triangles -> on modifie face en cours, et on ajoute une face + if (ok_indice == 4) + { + // ajout triangle + Face new_triangle; + new_triangle.texture_front = triangle.texture_front; + new_triangle.texture_back = triangle.texture_back; + new_triangle.v[0] = v_ok[0]; + new_triangle.t[0] = t_ok[0]; + new_triangle.v[1] = v_ok[2]; + new_triangle.t[1] = t_ok[2]; + new_triangle.v[2] = v_ok[3]; + new_triangle.t[2] = t_ok[3]; + + mesh->f[mesh->f_length] = new_triangle; // pas de verif d'overflow + mesh->f_length++; + } + } + + + /*debug_pop("FIN CYCLE\nplan %i\nil y a %i triangles\nil y a %i vertex", p, mesh->f_length, mesh->v_length); + for (int i=0; if_length; i++) + { + debug_pop("f %i %i %i", mesh->f[i].v[0], mesh->f[i].v[1], mesh->f[i].v[2]); + } + for (int i=0; iv_length; i++) + { + debug_pop("v\nx %i\ny %i\nz %i", mesh->v[i].x, mesh->v[i].y, mesh->v[i].z); + }*/ + + } + + } +} + + + +bool Windmill::inside_frustrum(Vertex vertex, Plane plane, int offset) +{ + /*if (plane.id == NEAR) + { + return vertex.z > camera.near; + } + if (plane.id == RIGHT) + { + return vertex.x * camera.scale_coef2 < vertex.z; // MULT float ! + } + if (plane.id == TOP) + { + return -vertex.y * camera.scale_coef2 / 2.0 < vertex.z; + } + if (plane.id == LEFT) + { + return -vertex.x * camera.scale_coef2 < vertex.z; + } + if (plane.id == BOTTOM) + { + return vertex.y * camera.scale_coef2 / 2.0 < vertex.z; + }*/ + + int dot = vertex.x * plane.normal_x + vertex.y * plane.normal_y + vertex.z * plane.normal_z - plane.distance+ (offset * 1000); + return dot > 0; +} + + + +Vertex Windmill::clip_onto_plane(Vertex vertexA, Vertex vertexB, Plane plane) +{/* + int x, y, z, u, v; + float t; + + if (plane == NEAR) + { + t = float(camera.near - vertexA->z) / float(vertexB->z - vertexA->z); + //x = vertexA->x + t * (vertexB->x - vertexA->x); + //y = vertexA->y + t * (vertexB->y - vertexA->y); + //z = camera.near; + } + + if (plane == RIGHT) + { + t = float(camera.near - vertexA->z) / float(vertexB->z - vertexA->z); + } + + x = vertexA->x + t * (vertexB->x - vertexA->x); + y = vertexA->y + t * (vertexB->y - vertexA->y); + z = vertexA->z + t * (vertexB->z - vertexA->z); + u = vertexA->u + t * (vertexB->u - vertexA->u); + v = vertexA->v + t * (vertexB->v - vertexA->v); + + return Vertex(x, y, z, u, v);*/ + + //return Vertex(0, 0, 0, 0, 0); + + float dotA = vertexA.x * plane.normal_x + vertexA.y * plane.normal_y + vertexA.z * plane.normal_z - plane.distance; + float dotB = vertexB.x * plane.normal_x + vertexB.y * plane.normal_y + vertexB.z * plane.normal_z - plane.distance; + + float t = dotA / (dotA - dotB); // intersection factor (between 0 and 1) + + + int x = vertexA.x + t * (vertexB.x - vertexA.x); + int y = vertexA.y + t * (vertexB.y - vertexA.y); + int z = vertexA.z + t * (vertexB.z - vertexA.z); + float u = vertexA.u + t * (vertexB.u - vertexA.u); + float v = vertexA.v + t * (vertexB.v - vertexA.v); + + return Vertex(x, y, z, u, v); +} + + +bool Windmill::inside_viewport(int x, int y) +{ + return (x < viewport.x2 and y >= viewport.y1 and x >= viewport.x1 and y < viewport.y2); +} + +int Windmill::get_visible_face(Vertex* a, Vertex* b, Vertex* c) +{ + return (c->x - a->x) * (b->y - a->y) - (c->y - a->y) * (b->x - a->x) > 0 ? FRONT : BACK; +} + + diff --git a/src/windmill_draw.cpp b/src/windmill_draw.cpp new file mode 100644 index 0000000..3178cc0 --- /dev/null +++ b/src/windmill_draw.cpp @@ -0,0 +1,946 @@ +//---------------------------------------------------------------------------------------------------- +// +// WINDMILL +// +// version : 2.0 +// Moteur de rendu 3D base sur la methode de rasterisation avec buffer de profondeur +// +// Cree par Olivier Lanneau, alias NineStars +// Planet-casio.fr +// +//---------------------------------------------------------------------------------------------------- + + +#include "windmill.hpp" + +void debug_pop(char const *fmt, ...); +void debug_display(char const *fmt, ...); + +extern Texture tex_white; +extern Texture tex_light; +extern Texture tex_dark; +extern Texture tex_black; + + +//---------------------------------------------------------------------------------------------------- +// DESSIN +//---------------------------------------------------------------------------------------------------- +void Windmill::draw() +{ + // quitte si pas de camera, de map, d objet ou de z_buffer + if(camera2 == NULL or map == NULL or/* object == NULL or */z_buffer == NULL) return; + + // mets a jour les variables de la camera + camera2->update(); + + // cree une camera temporaire pour eviter les problemes de desynchronisation + copy_camera(); + + // fonction principale, l'ordre d'appel des fonctions suivantes est important + clear_z_buffer(); + + // trie les objets pour optimiser l affichage + sort_object(); + + // affiche le trait d'horizon + if (map->horizon) draw_horizon(); + + // affiche les ombres +// draw_shadows(); + + // affiche le sol + if (map->ground) draw_ground(); + + // affiche les objets de la scene + draw_objects(); + + // post traitement pour afficher les angles vifs +// draw_post_treatment(); + + // affiche le corps du personnage + //draw_body(); + + // affiche des informations debug + if (log) + { + //show_fps(); + //show_coordinates(); + show_repere(); + } +} + + +void Windmill::draw_horizon() +{ + int distance = 1000; + int hx = camera.x + distance * camera.cos_yaw; + int hy = camera.y + distance * camera.sin_yaw; + + Vertex horizon = Vertex(hx, hy, 0); + + transform_world_to_camera(&horizon, 1); + transform_camera_to_screen(&horizon, 1); + if (inside_viewport(horizon.x, horizon.y)) + { + dline(viewport.x1, horizon.y, viewport.x2, horizon.y, C_BLACK); + } +} + + +void Windmill::draw_ground() +{ + int distance = 50; + int esp = 20; + int nb = 6; + int nb2 = nb * nb; + float cx = camera.x + distance * camera.cos_yaw; + float cy = camera.y + distance * camera.sin_yaw; + int dx = int(cx) - int(cx)%esp; + int dy = int(cy) - int(cy)%esp; + + for (int i=-nb; i 0) + { + transform_camera_to_screen(&ground, 1); + if (inside_viewport(ground.x, ground.y) == true) + { + dpixel(ground.x, ground.y, C_BLACK); + } + } + } + } + } +} + + +void Windmill::draw_objects() +{ + for(i=0; iobject_length; i++) + { + // récupère l'objet en cours + Object* object = map->object[i]; + //Object* object = objects[i]; + + //int f_visible = 0; + + // si l'objet est totalement ou partie dans le frustrum + if (object-> visible && object_in_frustrum(object)) + { + // copie le mesh avec plus de memoires disponible pour possiblement ajouter des points au clipping + WMesh mesh; mesh.from_mesh(object->mesh, 10); + + // calcul des coordonnees dans le repère monde apres rotation et translation de l objet + transform_model_to_world(object, mesh.v, mesh.v_length); + + // calcul des coordonnees dans le repère camera apres rotation et translation de la camera + transform_world_to_camera(mesh.v, mesh.v_length); + + // coupe 3D selon le frustrum de la camera + clip_frustrum(&mesh); // SI OBJECT IN FRUSTRUM DIT QUE L'OBJET EST PARTEILLEMENT DANS FRUSTRUM + + // calcul des coordonnes apres perspective et decalage au centre de l ecran + transform_camera_to_screen(mesh.v, mesh.v_length); + + if (log) + { + for (int v = 0; v> ((x+1) & 7); + vram[address>>3] |= mask; + + //ML_pixel(x+1, y, ML_BLACK); + } + if (bottom < MAX_DEPTH_Z_BUFFER) + { + dpixel(x, y+1, C_BLACK); + //ML_pixel(x, y+1, ML_BLACK); + } + } else { + if (right == MAX_DEPTH_Z_BUFFER or bottom == MAX_DEPTH_Z_BUFFER) + { + dpixel(x, y+1, C_BLACK); + //ML_pixel(x, y, ML_BLACK); + } + } + } + + } // 21 fps 21,5 fps*/ + + /*left = z_buffer[0]; + for (int i = 1; i> (i & 7); + vram[(i - z_buffer_offset)>>3] |= mask; + } + } else { + if (left < MAX_DEPTH_Z_BUFFER) + { + mask = 128 >> ((i-1) & 7); + vram[(i - 1 - z_buffer_offset)>>3] |= mask; + + } + } + } + // sans rien 28 fps + // avec le i+1 : 24 fps + // avec le i : 25 fps + // calculer left = Z_buffer[i-1] dans if : 24 fps + // avec les deux cote : 24 fps ! */ + + bool flag = false; + for (int i = 0; i> ((i-2) & 7); + vram[(i - 2 - z_buffer_offset)>>3] |= mask; + flag = false; + } else { + // l objet commencait en fait 1 pixel a gauche + mask = 128 >> ((i-1) & 7); + vram[(i - 1 - z_buffer_offset)>>3] |= mask; + flag = false; + } + } + } else { + if (flag == false) + { + if (z_buffer[i-1] == MAX_DEPTH_Z_BUFFER) + { + // il y avait rien juste a gauche + mask = 128 >> (i & 7); + vram[(i - z_buffer_offset)>>3] |= mask; + flag = true; + } else { + // l objet commencait en fait 1 pixel a gauche + mask = 128 >> ((i-1) & 7); + vram[(i - 1 - z_buffer_offset)>>3] |= mask; + flag = true; + } + } + } + } // 24 fps + // avec astuce +=2 : 25 fps + + /*bool flag = false; + char i_mod_8; + for (int i = 0; i> i_mod_8;//((i-1) & 7); + flag = false; + } + } else { + if (flag == false) + { + mask |= 128 >> i_mod_8; + flag = true; + } + } + if (i_mod_8 == 7) + { + //if (mask > 0) + vram[i>>3] |= mask; + mask = 0; + } + }*/ +} + + +void Windmill::draw_body() +{ + /*int x = camera.x; + int y = camera.y; + int z = camera.z; + + Vertex v0, v1, v2, v3; + set_vertex_xyz() + METTRE DIRECT LES VERTEX DANS LE REPERE SCREEN PUIS RENDER... +*/ +} + + +//---------------------------------------------------------------------------------------------------- +// DESSIN DES TRIANGLES +//---------------------------------------------------------------------------------------------------- +void Windmill::render_triangles(WMesh mesh) +{ + for (int f = 0; fx, min(vertexB->x, vertexC->x))); + int max_x = min(viewport.x2-1, max(vertexA->x, max(vertexB->x, vertexC->x))); + int min_y = max(viewport.y1, min(vertexA->y, min(vertexB->y, vertexC->y))); + int max_y = min(viewport.y2-1, max(vertexA->y, max(vertexB->y, vertexC->y))); + + // ajustement des coordonnees des textures a la taille en pixel + vertexA->u *= texture->pixel_width; + vertexA->v *= texture->pixel_height; + vertexB->u *= texture->pixel_width; + vertexB->v *= texture->pixel_height; + vertexC->u *= texture->pixel_width; + vertexC->v *= texture->pixel_height; + + // pre-calcul des coordonnees de la texture << 13 => tex_w * 8192 / x + int w0 = vertexA->u * vertexA->inv_z; int h0 = vertexA->v * vertexA->inv_z; + int w1 = vertexB->u * vertexB->inv_z; int h1 = vertexB->v * vertexB->inv_z; + int w2 = vertexC->u * vertexC->inv_z; int h2 = vertexC->v * vertexC->inv_z; + + // calcul des produits vectoriels + int u0_start = edge_start(vertexB, vertexC, min_x, min_y); + int u0_step_x = edge_step_x(vertexB, vertexC); + int u0_step_y = edge_step_y(vertexB, vertexC); + int u1_start = edge_start(vertexC, vertexA, min_x, min_y); + int u1_step_x = edge_step_x(vertexC, vertexA); + int u1_step_y = edge_step_y(vertexC, vertexA); + int u2_start = edge_start(vertexA, vertexB, min_x, min_y); + int u2_step_x = edge_step_x(vertexA, vertexB); + int u2_step_y = edge_step_y(vertexA, vertexB); + + // << 15 + int z_num_start = (u0_start * vertexA->z_normalized + u1_start * vertexB->z_normalized + u2_start * vertexC->z_normalized) / area; + int z_num_step_x = (u0_step_x * vertexA->z_normalized + u1_step_x * vertexB->z_normalized + u2_step_x * vertexC->z_normalized) / area; + int z_num_step_y = (u0_step_y * vertexA->z_normalized + u1_step_y * vertexB->z_normalized + u2_step_y * vertexC->z_normalized) / area; + + // << 13 + int z_div_start = u0_start * vertexA->inv_z + u1_start * vertexB->inv_z + u2_start * vertexC->inv_z; + int z_div_step_x = u0_step_x * vertexA->inv_z + u1_step_x * vertexB->inv_z + u2_step_x * vertexC->inv_z; + int z_div_step_y = u0_step_y * vertexA->inv_z + u1_step_y * vertexB->inv_z + u2_step_y * vertexC->inv_z; + + // rapprochement artificiel si texture de type decoration + int decoration = 0;//(texture->decoration ? DECORATION_OFFSET : 0); + + // acces a la vram + //char* vram = get_vram_address(); + unsigned char mask_vram, mask_w; + int offset_vram; + int address; + + int u0, u1, u2; + int z_num, z_div; + int w, h; + + // pre-calcul largeur en octet des tableaux + int nbw_tex = ((texture->pixel_width - 1) >> 3) + 1; + char loop_w_tex = texture->pixel_width-1; + char loop_h_tex = texture->pixel_height-1; + + // parcours en ligne + for(int x=min_x; x<=max_x; x++) + { + u0 = u0_start; u1 = u1_start; u2 = u2_start; + z_num = z_num_start; + z_div = z_div_start; + offset_vram = x >> 3; + mask_vram = 128 >> (x & 7); + // parcours en colonne + for(int y=min_y; y<=max_y; y++) + { + // si le pixel (x;y) est dans le triangle + if ((u0 | u1 | u2) > 0) + { + // addresse du z-buffer + address = x + y * z_buffer_width + z_buffer_offset; + // si le pixel (x;y) est plus proche qu'avant + if (z_num <= z_buffer[address] + decoration) + { + // calcul des coordonnees pour la texture + w = ((u0 * w0 + u1 * w1 + u2 * w2) / z_div) & loop_w_tex; + h = ((u0 * h0 + u1 * h1 + u2 * h2) / z_div) & loop_h_tex; + // calcul du masque pour l'octet + mask_w = 128 >> (w & 7); + if (texture->mask == NULL) + { + // enregistre la profondeur du pixel dans le z buffer + z_buffer[address] = z_num; + + if (texture->sprite[(w >> 3) + (h * nbw_tex)] & mask_w) + { + // afficher pixel noir + dpixel(x, y, C_BLACK); + //vram[(y << 4) + offset_vram] |= mask_vram; + }else{ + // afficher pixel blanc + dpixel(x, y, C_WHITE); + //vram[(y << 4) + offset_vram] &= ~mask_vram; + } + // curseur + //pixel_on_cursor(x, y); + }/* else { + int alpha = (w >> 3) + (h * nbw_tex); + if ((texture->mask[alpha] & mask_w)) + { + // enregistre la profondeur du pixel dans le z buffer + z_buffer[address] = z_num; + if ((texture->sprite[alpha] & mask_w)) + { + // afficher pixel noir + vram[(y << 4) + offset_vram] |= mask_vram; + }else{ + // afficher pixel blanc + vram[(y << 4) + offset_vram] &= ~mask_vram; + } + // curseur + //pixel_on_cursor(x, y); + } + }*/ + + } + } + u0 += u0_step_y; u1 += u1_step_y; u2 += u2_step_y; + z_num += z_num_step_y; + z_div += z_div_step_y; + } + u0_start += u0_step_x; u1_start += u1_step_x; u2_start += u2_step_x; + z_num_start += z_num_step_x; + z_div_start += z_div_step_x; + } +} + + + +void Windmill::render_triangle_color(Vertex* vertexA, Vertex* vertexB, Vertex* vertexC, color_t color) +{ + // calcul de l'aire du triangle + int area = edge(vertexA, vertexB, vertexC); + if (area <= MIN_AREA_CLIP) return; + + // calcul du rectangle circonscrit au triangle + int min_x = max(viewport.x1, min(vertexA->x, min(vertexB->x, vertexC->x))); + int max_x = min(viewport.x2-1, max(vertexA->x, max(vertexB->x, vertexC->x))); + int min_y = max(viewport.y1, min(vertexA->y, min(vertexB->y, vertexC->y))); + int max_y = min(viewport.y2-1, max(vertexA->y, max(vertexB->y, vertexC->y))); + + // calcul des produits vectoriels + int u0_start = edge_start(vertexB, vertexC, min_x, min_y); + int u0_step_x = edge_step_x(vertexB, vertexC); + int u0_step_y = edge_step_y(vertexB, vertexC); + int u1_start = edge_start(vertexC, vertexA, min_x, min_y); + int u1_step_x = edge_step_x(vertexC, vertexA); + int u1_step_y = edge_step_y(vertexC, vertexA); + int u2_start = edge_start(vertexA, vertexB, min_x, min_y); + int u2_step_x = edge_step_x(vertexA, vertexB); + int u2_step_y = edge_step_y(vertexA, vertexB); + + int z_num_start = (u0_start * vertexA->z_normalized + u1_start * vertexB->z_normalized + u2_start * vertexC->z_normalized) / area; + int z_num_step_x = (u0_step_x * vertexA->z_normalized + u1_step_x * vertexB->z_normalized + u2_step_x * vertexC->z_normalized) / area; + int z_num_step_y = (u0_step_y * vertexA->z_normalized + u1_step_y * vertexB->z_normalized + u2_step_y * vertexC->z_normalized) / area; + + // acces a la vram + char* vram = get_vram_address(); + + unsigned char mask_vram; + int offset_vram; + int address; + + int u0, u1, u2; + int z_num; + + // parcours en ligne + for(int x=min_x; x<=max_x; x++) + { + u0 = u0_start; u1 = u1_start; u2 = u2_start; + z_num = z_num_start; + offset_vram = x >> 3; + mask_vram = 128 >> (x & 7); + // parcours en colonne + for(int y=min_y; y<=max_y; y++) + { + // si le pixel (x;y) est dans le triangle + if ((u0 | u1 | u2) > 0) + { + // addresse du z-buffer + address = x + y * z_buffer_width + z_buffer_offset; + // si le pixel (x;y) est plus proche qu'avant + if (z_num <= z_buffer[address]) + { + // enregistre la profondeur du pixel dans le z buffer + z_buffer[address] = z_num; + // afficher pixel + dpixel(x, y, color); + } + } + u0 += u0_step_y; u1 += u1_step_y; u2 += u2_step_y; + z_num += z_num_step_y; + } + u0_start += u0_step_x; u1_start += u1_step_x; u2_start += u2_step_x; + z_num_start += z_num_step_x; + } +} + + + /*void Windmill::render_triangle_black(Vertex* vertexA, Vertex* vertexB, Vertex* vertexC) + { + // calcul du rectangle circonscrit au triangle + int min_x = max(viewport.x1, min(vertexA->x, min(vertexB->x, vertexC->x))); + int max_x = min(viewport.x2-1, max(vertexA->x, max(vertexB->x, vertexC->x))); + int min_y = max(viewport.y1, min(vertexA->y, min(vertexB->y, vertexC->y))); + int max_y = min(viewport.y2-1, max(vertexA->y, max(vertexB->y, vertexC->y))); + + // calcul de l'aire du triangle + int area = edge(vertexA, vertexB, vertexC); + // termine si la taille du triangle est trop petite + if (area <= MIN_AREA_CLIP) return; + + // calcul des produits vectoriels + int u0_start = edge_start(vertexB, vertexC, min_x, min_y); + int u0_step_x = edge_step_x(vertexB, vertexC); + int u0_step_y = edge_step_y(vertexB, vertexC); + int u1_start = edge_start(vertexC, vertexA, min_x, min_y); + int u1_step_x = edge_step_x(vertexC, vertexA); + int u1_step_y = edge_step_y(vertexC, vertexA); + int u2_start = edge_start(vertexA, vertexB, min_x, min_y); + int u2_step_x = edge_step_x(vertexA, vertexB); + int u2_step_y = edge_step_y(vertexA, vertexB); + + int z_num_start = (u0_start * vertexA->z_normalized + u1_start * vertexB->z_normalized + u2_start * vertexC->z_normalized) / area; + int z_num_step_x = (u0_step_x * vertexA->z_normalized + u1_step_x * vertexB->z_normalized + u2_step_x * vertexC->z_normalized) / area; + int z_num_step_y = (u0_step_y * vertexA->z_normalized + u1_step_y * vertexB->z_normalized + u2_step_y * vertexC->z_normalized) / area; + + // acces a la vram + char* vram = get_vram_address(); + + unsigned char mask_vram; + int offset_vram; + int address; + + int u0, u1, u2; + int z_num; + + // parcours en ligne + for(int x=min_x; x<=max_x; x++) + { + u0 = u0_start; u1 = u1_start; u2 = u2_start; + z_num = z_num_start; + offset_vram = x >> 3; + mask_vram = 128 >> (x & 7); + // parcours en colonne + for(int y=min_y; y<=max_y; y++) + { + // si le pixel (x;y) est dans le triangle + if ((u0 | u1 | u2) > 0) + { + // addresse du z-buffer + address = x + y * z_buffer_width + z_buffer_offset; + // si le pixel (x;y) est plus proche qu'avant + if (z_num <= z_buffer[address]) + { + // enregistre la profondeur du pixel dans le z buffer + z_buffer[address] = z_num; + // afficher pixel noir + vram[(y << 4) + offset_vram] |= mask_vram; + // curseur + pixel_on_cursor(x, y); + } + } + u0 += u0_step_y; u1 += u1_step_y; u2 += u2_step_y; + z_num += z_num_step_y; + } + u0_start += u0_step_x; u1_start += u1_step_x; u2_start += u2_step_x; + z_num_start += z_num_step_x; + } + }*/ + +/* +void Windmill::render_triangle_black(Vertex* vertexA, Vertex* vertexB, Vertex* vertexC) +{ + // calcul du rectangle circonscrit au triangle + int min_x = max(viewport.x1, min(vertexA->x, min(vertexB->x, vertexC->x))); + int max_x = min(viewport.x2-1, max(vertexA->x, max(vertexB->x, vertexC->x))); + int min_y = max(viewport.y1, min(vertexA->y, min(vertexB->y, vertexC->y))); + int max_y = min(viewport.y2-1, max(vertexA->y, max(vertexB->y, vertexC->y))); + + // calcul de l'aire du triangle + int area = edge(vertexA, vertexB, vertexC); + // termine si la taille du triangle est trop petite + if (area <= MIN_AREA_CLIP) return; + + // calcul des produits vectoriels + int u0_start = edge_start(vertexB, vertexC, min_x, min_y); + int u0_step_x = edge_step_x(vertexB, vertexC); + int u0_step_y = edge_step_y(vertexB, vertexC); + int u1_start = edge_start(vertexC, vertexA, min_x, min_y); + int u1_step_x = edge_step_x(vertexC, vertexA); + int u1_step_y = edge_step_y(vertexC, vertexA); + int u2_start = edge_start(vertexA, vertexB, min_x, min_y); + int u2_step_x = edge_step_x(vertexA, vertexB); + int u2_step_y = edge_step_y(vertexA, vertexB); + + int z_num_start = (u0_start * vertexA->z_normalized + u1_start * vertexB->z_normalized + u2_start * vertexC->z_normalized) / area; + int z_num_step_x = (u0_step_x * vertexA->z_normalized + u1_step_x * vertexB->z_normalized + u2_step_x * vertexC->z_normalized) / area; + int z_num_step_y = (u0_step_y * vertexA->z_normalized + u1_step_y * vertexB->z_normalized + u2_step_y * vertexC->z_normalized) / area; + + // acces a la vram +// char* vram = get_vram_address(); + unsigned char mask_vram; + int offset_vram; + int address; + + int u0, u1, u2; + int z_num; + + // parcours en ligne + for(int x=min_x; x<=max_x; x++) + { + u0 = u0_start; u1 = u1_start; u2 = u2_start; + z_num = z_num_start; + offset_vram = x >> 3; + mask_vram = 128 >> (x & 7); + // parcours en colonne + for(int y=min_y; y<=max_y; y++) + { + // si le pixel (x;y) est dans le triangle + if ((u0 | u1 | u2) > 0) + { + // addresse du z-buffer + address = x + y * z_buffer_width + z_buffer_offset; + // si le pixel (x;y) est plus proche qu'avant + if (z_num <= z_buffer[address]) + { + // enregistre la profondeur du pixel dans le z buffer + z_buffer[address] = z_num; + // afficher pixel noir +// vram[(y << 4) + offset_vram] |= mask_vram; + // curseur + pixel_on_cursor(x, y); + } + } + u0 += u0_step_y; u1 += u1_step_y; u2 += u2_step_y; + z_num += z_num_step_y; + } + u0_start += u0_step_x; u1_start += u1_step_x; u2_start += u2_step_x; + z_num_start += z_num_step_x; + } +} +*/ + +/*void Windmill::render_triangle_white(Vertex* vertexA, Vertex* vertexB, Vertex* vertexC) + { + // calcul du rectangle circonscrit au triangle + int min_x = max(viewport.x1, min(vertexA->x, min(vertexB->x, vertexC->x))); + int max_x = min(viewport.x2-1, max(vertexA->x, max(vertexB->x, vertexC->x))); + int min_y = max(viewport.y1, min(vertexA->y, min(vertexB->y, vertexC->y))); + int max_y = min(viewport.y2-1, max(vertexA->y, max(vertexB->y, vertexC->y))); + + // calcul de l'aire du triangle + int area = edge(vertexA, vertexB, vertexC); + // termine si la taille du triangle est trop petite + if (area <= MIN_AREA_CLIP) return; + + // calcul des produits vectoriels + int u0_start = edge_start(vertexB, vertexC, min_x, min_y); + int u0_step_x = edge_step_x(vertexB, vertexC); + int u0_step_y = edge_step_y(vertexB, vertexC); + int u1_start = edge_start(vertexC, vertexA, min_x, min_y); + int u1_step_x = edge_step_x(vertexC, vertexA); + int u1_step_y = edge_step_y(vertexC, vertexA); + int u2_start = edge_start(vertexA, vertexB, min_x, min_y); + int u2_step_x = edge_step_x(vertexA, vertexB); + int u2_step_y = edge_step_y(vertexA, vertexB); + + int z_num_start = (u0_start * vertexA->z_normalized + u1_start * vertexB->z_normalized + u2_start * vertexC->z_normalized) / area; + int z_num_step_x = (u0_step_x * vertexA->z_normalized + u1_step_x * vertexB->z_normalized + u2_step_x * vertexC->z_normalized) / area; + int z_num_step_y = (u0_step_y * vertexA->z_normalized + u1_step_y * vertexB->z_normalized + u2_step_y * vertexC->z_normalized) / area; + + // acces a la vram + char* vram = get_vram_address(); + unsigned char mask_vram; + int offset_vram; + int address; + + int u0, u1, u2; + int z_num; + + // parcours en ligne + for(int x=min_x; x<=max_x; x++) + { + u0 = u0_start; u1 = u1_start; u2 = u2_start; + z_num = z_num_start; + offset_vram = x >> 3; + mask_vram = 128 >> (x & 7); + // parcours en colonne + for(int y=min_y; y<=max_y; y++) + { + // si le pixel (x;y) est dans le triangle + if ((u0 | u1 | u2) > 0) + { + // addresse du z-buffer + address = x + y * z_buffer_width + z_buffer_offset; + // si le pixel (x;y) est plus proche qu'avant + if (z_num <= z_buffer[address]) + { + // enregistre la profondeur du pixel dans le z buffer + z_buffer[address] = z_num; + // afficher pixel blanc + vram[(y << 4) + offset_vram] &= ~mask_vram; + // curseur + pixel_on_cursor(x, y); + } + } + u0 += u0_step_y; u1 += u1_step_y; u2 += u2_step_y; + z_num += z_num_step_y; + } + u0_start += u0_step_x; u1_start += u1_step_x; u2_start += u2_step_x; + z_num_start += z_num_step_x; + } + }*/ + + +/*void Windmill::render_triangle_transparent(Vertex* vertexA, Vertex* vertexB, Vertex* vertexC, const Texture* texture) +{ + // calcul du rectangle circonscrit au triangle + int min_x = max(viewport.x1, min(vertexA->x, min(vertexB->x, vertexC->x))); + int max_x = min(viewport.x2-1, max(vertexA->x, max(vertexB->x, vertexC->x))); + int min_y = max(viewport.y1, min(vertexA->y, min(vertexB->y, vertexC->y))); + int max_y = min(viewport.y2-1, max(vertexA->y, max(vertexB->y, vertexC->y))); + + // calcul de l'aire du triangle + int area = edge(vertexA, vertexB, vertexC); + // termine si la taille du triangle est trop petite + if (area <= MIN_AREA_CLIP) return; + + // pre-calcul des coordonnees de la texture + int w0 = vertexA->w * vertexA->z; int h0 = vertexA->h * vertexA->z; + int w1 = vertexB->w * vertexB->z; int h1 = vertexB->h * vertexB->z; + int w2 = vertexC->w * vertexC->z; int h2 = vertexC->h * vertexC->z; + + // calcul des produits vectoriels + int u0_start = edge_start(vertexB, vertexC, min_x, min_y); + int u0_step_x = edge_step_x(vertexB, vertexC); + int u0_step_y = edge_step_y(vertexB, vertexC); + int u1_start = edge_start(vertexC, vertexA, min_x, min_y); + int u1_step_x = edge_step_x(vertexC, vertexA); + int u1_step_y = edge_step_y(vertexC, vertexA); + int u2_start = edge_start(vertexA, vertexB, min_x, min_y); + int u2_step_x = edge_step_x(vertexA, vertexB); + int u2_step_y = edge_step_y(vertexA, vertexB); + + int z_num_start = (u0_start * vertexA->z_normalized + u1_start * vertexB->z_normalized + u2_start * vertexC->z_normalized) / area; + int z_num_step_x = (u0_step_x * vertexA->z_normalized + u1_step_x * vertexB->z_normalized + u2_step_x * vertexC->z_normalized) / area; + int z_num_step_y = (u0_step_y * vertexA->z_normalized + u1_step_y * vertexB->z_normalized + u2_step_y * vertexC->z_normalized) / area; + + int z_div_start = u0_start * vertexA->z + u1_start * vertexB->z + u2_start * vertexC->z; + int z_div_step_x = u0_step_x * vertexA->z + u1_step_x * vertexB->z + u2_step_x * vertexC->z; + int z_div_step_y = u0_step_y * vertexA->z + u1_step_y * vertexB->z + u2_step_y * vertexC->z; + + // acces a la vram + char* vram = get_vram_address(); + + // pre-calcul largeur en octet des tableaux + int nbw_tex = ((texture->pixel_width - 1) >> 3) + 1; + char loop_w_tex = texture->pixel_width-1; + char loop_h_tex = texture->pixel_height-1; + + // parcours en ligne + for(int x=min_x; x<=max_x; x++) + { + int u0 = u0_start; int u1 = u1_start; int u2 = u2_start; + int z_num = z_num_start; + int z_div = z_div_start; + int offset_vram = x >> 3; + char mask_vram = 128 >> (x & 7); + // parcours en colonne + for(int y=min_y; y<=max_y; y++) + { + // si le pixel (x;y) est dans le triangle + if ((u0 | u1 | u2) > 0) + { + // addresse du z-buffer + int address = x + y * z_buffer_width + z_buffer_offset; + // si le pixel (x;y) est plus proche qu'avant + if (z_num <= z_buffer[address]) + { + // calcul des coordonnees pour la texture + unsigned int w = ((u0 * w0 + u1 * w1 + u2 * w2) / z_div) & loop_w_tex; + unsigned int h = ((u0 * h0 + u1 * h1 + u2 * h2) / z_div) & loop_h_tex; + // calcul du masque pour l'octet + unsigned char mask_w = 128 >> (w & 7); + if ((texture->sprite[(w >> 3) + (h * nbw_tex)] & mask_w)) + { + // afficher pixel noir + vram[(y << 4) + offset_vram] |= mask_vram; + // enregistre la profondeur du pixel dans le z buffer + z_buffer[address] = z_num; + } + } + } + u0 += u0_step_y; u1 += u1_step_y; u2 += u2_step_y; + z_num += z_num_step_y; + z_div += z_div_step_y; + } + u0_start += u0_step_x; u1_start += u1_step_x; u2_start += u2_step_x; + z_num_start += z_num_step_x; + z_div_start += z_div_step_x; + } +}*/ + + +//---------------------------------------------------------------------------------------------------- +// UTILITAIRES +//---------------------------------------------------------------------------------------------------- + +int Windmill::edge(Vertex* a, Vertex* b, Vertex* c) +{ + return (c->x - a->x) * (b->y - a->y) - (c->y - a->y) * (b->x - a->x); +} + + +int Windmill::edge_start(Vertex* a, Vertex* b, int px, int py) +{ + return (b->y - a->y) * (px - a->x) - (b->x - a->x) * (py - a->y); +} + + +int Windmill::edge_step_x(Vertex* a, Vertex* b) +{ + return b->y - a->y; +} + + +int Windmill::edge_step_y(Vertex* a, Vertex* b) +{ + return a->x - b->x; +} diff --git a/src/windmill_load.cpp b/src/windmill_load.cpp new file mode 100644 index 0000000..5b22c04 --- /dev/null +++ b/src/windmill_load.cpp @@ -0,0 +1,257 @@ +//---------------------------------------------------------------------------------------------------- +// +// WINDMILL +// +// version : 2.0 +// Moteur de rendu 3D base sur la methode de rasterisation avec buffer de profondeur +// +// Cree par Olivier Lanneau, alias NineStars +// Planet-casio.fr +// +//---------------------------------------------------------------------------------------------------- + + +#include "windmill.hpp" + +void debug_pop(char const *fmt, ...); +void debug_display(char const *fmt, ...); + + +extern Texture tex_white; +extern Texture tex_light; +extern Texture tex_dark; +extern Texture tex_black; + + +//---------------------------------------------------------------------------------------------------- +// INITIALISATION +//---------------------------------------------------------------------------------------------------- +Windmill::Windmill() +{ + camera2 = NULL; + map = NULL; + //object = NULL; + z_buffer = NULL; + set_viewport(0, 0, 128, 64); + + sun = {0, 0, 100}; +} + + +Windmill::~Windmill() +{ + free(z_buffer); + //free(object); +} + + +void Windmill::set_camera(Camera* _camera) +{ + camera2 = _camera; +} + + +void Windmill::set_viewport(int viewport_x1, int viewport_y1, int viewport_x2, int viewport_y2) +{ + viewport.x1 = max(0, viewport_x1); + viewport.y1 = max(0, viewport_y1); + viewport.x2 = min(viewport_x2, DWIDTH); + viewport.y2 = min(viewport_y2, DHEIGHT); + + //if (z_buffer != NULL) free(z_buffer); + free(z_buffer); + shift_x = (viewport.x1 + viewport.x2) / 2; + shift_y = (viewport.y1 + viewport.y2) / 2; + + z_buffer_size = (viewport.x2 - viewport.x1) * (viewport.y2 - viewport.y1); + z_buffer = (unsigned short*) calloc(z_buffer_size, 2); + //if (z_buffer == NULL) debug_pop("ERROR ptr z_buffer NULL"); + z_buffer_width = viewport.x2 - viewport.x1; + z_buffer_offset = - viewport.x1 - viewport.y1 * DWIDTH; + clear_z_buffer(); +} + + +void Windmill::set_map(Map* _map) +{ + loading = true; + + if (map != _map) + { + // free les anciennes ombres + // ... + + // attribution de la map + map = _map; + + // enregistrement d'une liste triable + //set_objects(); + + // calcul des spheres englobantes de chaque objet + compute_bouding_sphere(); + + // calcul des ombres projetees au sol par chaque objet + //compute_shadows(); + } + + loading = false; +} + +/*void Windmill::set_objects() +{ + //objects = new Object* [map->object_length]; + objects = (Object**) malloc(map->object_length * sizeof(Object)); + if (objects == NULL) debug_pop("ERROR ptr object NULL"); + + for (int i = 0; iobject_length; i++) + { + objects[i] = map->object[i]; + } +}*/ + + +void Windmill::compute_bouding_sphere() +{ + // calcul des spheres englobantes pour chaque objet + for (int i = 0; iobject_length; i++) + { + Object* object = map->object[i]; + int nb_point = 0; + int barycenter_x = 0; + int barycenter_y = 0; + int barycenter_z = 0; + + // calcul du barycentre + for (int v = 0; vmesh->v_length; v++) + { + VertexPoint vp = object->mesh->v[v]; + barycenter_x += vp.x; + barycenter_y += vp.y; + barycenter_z += vp.z; + + nb_point++; + } + barycenter_x /= nb_point; + barycenter_y /= nb_point; + barycenter_z /= nb_point; + + // recherche du point le plus eloigne du barycentre + int square_radius_max = 0; + for (int v = 0; vmesh->v_length; v++) + { + VertexPoint vp = object->mesh->v[v]; + int dx = vp.x - barycenter_x; + int dy = vp.y - barycenter_y; + int dz = vp.z - barycenter_z; + int square_radius = dx*dx + dy*dy + dz*dz; + if (square_radius > square_radius_max) + { + square_radius_max = square_radius; + } + } + + // enregistrement + object->sphere.x = barycenter_x; + object->sphere.y = barycenter_y; + object->sphere.z = barycenter_z; + object->sphere.radius = sqrtf(square_radius_max) + 1; + object->sphere.square_radius = square_radius_max + 1; + } +} + + +/*WMesh Windmill::compute_shadows() +{ + // pout chaque objet + for (int i = 0; iobject_length; i++) + { + Object* object = map->object[i]; + + list_shadows_length = get_points_size(object; + //debug_pop("sh %i", list_shadows_length); + shadows = (Point*) malloc(list_shadows_length * sizeof(Point)); + int index = 0; + + // pour chaque poly + for (int j = 0; jmodele_size; j++) + { + const Modele* current_poly = &object->modele[j]; + for (int k = 0; ktype; k++) + { + Point point = get_point(current_poly, k); + Point shadow_point = {(sun.x * point.z - sun.z * point.x) / (point.z - sun.z), (sun.y * point.z - sun.z * point.y) / (point.z - sun.z), 0}; + + shadows[index] = shadow_point; + index ++; + //debug_pop("p %i %i %i", point.x, point.y, point.z); + //debug_pop("s %i %i %i", shadow_point.x, shadow_point.y, shadow_point.z); + } + } + + } + + +} + + + +// Gift Wrapping algorithme +void Windmill::compute_shadows_hull(Point3D* points, int points_size) +{ + if (points_size < 3) return; + + Point3D* temp_hull = (Point3D*) malloc(list_shadows_length * sizeof(Point3D)); + int temp_hull_length = 0; + + // commencer par le point le plus a gauche + int left = 0; + for (int i = 1; i 0)? 1 : 2; // clock ou counterclock wise +}*/ diff --git a/src/windmill_transform.cpp b/src/windmill_transform.cpp new file mode 100644 index 0000000..22019a5 --- /dev/null +++ b/src/windmill_transform.cpp @@ -0,0 +1,133 @@ +//---------------------------------------------------------------------------------------------------- +// +// WINDMILL +// +// version : 2.0 +// Moteur de rendu 3D base sur la methode de rasterisation avec buffer de profondeur +// +// Cree par Olivier Lanneau, alias NineStars +// Planet-casio.fr +// +//---------------------------------------------------------------------------------------------------- + + +#include "windmill.hpp" + +void debug_pop(char const *fmt, ...); + +extern Texture tex_white; +extern Texture tex_light; +extern Texture tex_dark; +extern Texture tex_black; + + +//---------------------------------------------------------------------------------------------------- +// TRANSFORMATION 3D +//---------------------------------------------------------------------------------------------------- +void Windmill::transform_model_to_world(Object* object, Vertex vertex[], int vertex_length) +{ + int cos = 0, sin = 0; + + // precalcul de cos et sin + // /!\ CHANGEMENT D'ECHELLE : cos et sin << 10 + /*if (object->axe == Z_BILLBOARD) + { + float angle_look_at_camera = atan2f(camera.y - object->y, camera.x - object->x); + float angle_rad = angle_look_at_camera + 3.1415 * object->angle / 180.0; + cosinus = 1024 * cosf(angle_rad); + sinus = 1024 * sinf(angle_rad); + }*/ + //if (object->rotation.Null() == false) + if (object->axe == N) + { + float angle_rad = 3.1415 * object->angle / 180.0; + cos = 1024 * cosf(angle_rad); + sin = 1024 * sinf(angle_rad); + } + + // transformation de chaque vertex + for (int k = 0; kaxe == N) + { + vertex[k].x = vertex_x + object->position.x; + vertex[k].y = vertex_y + object->position.y; + vertex[k].z = vertex_z + object->position.z; + } + /*else + { + int a1 = object->rotation.x * object->rotation.x * (1024 - cos) + cos; + int a2 = object->rotation.x * object->rotation.y * (1024 - cos) - object->rotation.z * sin; + int a3 = object->rotation.x * object->rotation.y * (1024 - cos) + object->rotation.y * sin; + int a4 = object->rotation.x * object->rotation.y * (1024 - cos) + object->rotation.z * sin; + int a5 = object->rotation.y * object->rotation.y * (1024 - cos) + cos; + int a6 = object->rotation.y * object->rotation.z * (1024 - cos) - object->rotation.x * sin; + int a7 = object->rotation.x * object->rotation.z * (1024 - cos) - object->rotation.y * sin; + int a8 = object->rotation.y * object->rotation.z * (1024 - cos) + object->rotation.x * sin; + int a9 = object->rotation.z * object->rotation.z * (1024 - cos) + cos; + + vertex[k].x = (a1 * vertex_x + a2 * vertex_y + a3 * vertex_z) / 1024 + object->position.x; + vertex[k].y = (a4 * vertex_x + a5 * vertex_y + a6 * vertex_z) / 1024 + object->position.y; + vertex[k].z = (a7 * vertex_x + a8 * vertex_y + a9 * vertex_z) / 1024 + object->position.z; + + //vertex[k].x = ((vertex_x * cosinus - vertex_z * sinus) >> 10) + object->position.x; + //vertex[k].y = ((vertex_y * cosinus - vertex_z * sinus) >> 10) + object->position.y; + //vertex[k].z = ((vertex_y * sinus + vertex_z * cosinus) >> 10) + object->position.z; + }*/ + if (object->axe == RX) + { + vertex[k].x = vertex_x + object->position.x; + vertex[k].y = ((vertex_y * cos - vertex_z * sin) / 1024) + object->position.y; + vertex[k].z = ((vertex_y * sin + vertex_z * cos) / 1024) + object->position.z; + } + if (object->axe == RY) + { + vertex[k].x = ((vertex_x * cos - vertex_z * sin) / 1024) + object->position.x; + vertex[k].y = vertex_y + object->position.y; + vertex[k].z = ((vertex_x * sin + vertex_z * cos) / 1024) + object->position.z; + } + if (object->axe == RZ)// or object->axe == Z_BILLBOARD) + { + vertex[k].x = ((vertex_x * cos - vertex_y * sin) / 1024) + object->position.x; + vertex[k].y = ((vertex_x * sin + vertex_y * cos) / 1024) + object->position.y; + vertex[k].z = vertex_z + object->position.z; + } + + } +} + + +void Windmill::transform_world_to_camera(Vertex vertex[], int vertex_length) +{ + for (int k = 0; kv_length; + v_length_allocated = mesh->v_length * margin; + v = (Vertex*) malloc(v_length_allocated * sizeof(Vertex)); + for (int i = 0; i < mesh->v_length; i++) + { + //v[i].FromVertexPoint(mesh->v[i]) + v[i].x = mesh->v[i].x; + v[i].y = mesh->v[i].y; + v[i].z = mesh->v[i].z; + } + + t_length = mesh->t_length; + t_length_allocated = mesh->t_length * margin; + t = (TexturePoint*) malloc(t_length_allocated * sizeof(TexturePoint)); + memcpy(t, mesh->t, mesh->t_length * sizeof(TexturePoint)); + + f_length = mesh->f_length; + f_length_allocated = mesh->f_length * margin; + f = (Face*) malloc(f_length_allocated * sizeof(Face)); + memcpy(f, mesh->f, mesh->f_length * sizeof(Face)); + + return wmesh; +}*/ + + +/*WMesh Windmill::create_working_mesh(const WMesh* wmesh) +{ + WMesh output_wmesh; + + output_v_length = 0; + output_v_length_allocated = wmesh->v_length_allocated; + output_v = (Vertex*) malloc(output_v_length_allocated * sizeof(Vertex)); + + output_t_length = 0; + output_t_length_allocated = wmesh->t_length_allocated; + output_t = (TexturePoint*) malloc(output_t_length_allocated * sizeof(TexturePoint)); + + output_f_length = 0; + output_f_length_allocated = wmesh->f_length_allocated; + output_f = (Face*) malloc(output_f_length_allocated * sizeof(Face)); + + return output_wmesh; +}*/ + + +void Windmill::copy_camera() +{ + memcpy(&camera, camera2, sizeof(Camera)); // a supprimer cf remarque lephe +} + + +void Windmill::sort_object() +{ + qsort(map->object, map->object_length, sizeof(Object*), compare_object); +} + + +int compare_object(void const *a, void const *b) +{ + Object* object_a = *(Object **) a; + Object* object_b = *(Object **) b; + return (object_a->position.z - object_b->position.z); +} + + +void Windmill::clear_z_buffer() +{ + memset(z_buffer, MAX_DEPTH_Z_BUFFER, z_buffer_size * sizeof(short)); +} + +float Windmill::distance(float dx, float dy, float dz) +{ + return sqrtf(dx*dx + dy*dy + dz*dz); +} + + + + + +//---------------------------------------------------------------------------------------------------- +// DEBUG +//---------------------------------------------------------------------------------------------------- +void Windmill::show_coordinates() +{ + // coordonnees + float tab_coordinates[5] = {camera.x, camera.y, camera.z, to_deg(camera.yaw), to_deg(camera.pitch)}; + + for (int i = 0; i < 5; i++) + { + dprint_opt(1, 1+8*i, C_BLACK, C_WHITE, 0, 0, "%i", (int)(tab_coordinates[i])); + } +} + + +void Windmill::show_repere() +{ + // repere + int repere_x = 112; + int repere_y = 55; + int repere_size = -12; + + // repere + Vertex v[3]; + const char* letter[] = {"x", "y", "z"}; + v[0].set_xyz(repere_size, 0 , 0 ); + v[1].set_xyz(0 , repere_size, 0 ); + v[2].set_xyz(0 , 0 , repere_size); + for (int i = 0; i < 3; i++) + { + float x3D = (camera.a4 * v[i].x + camera.a5 * v[i].y + camera.a6 * v[i].z) / 128; + float y3D = (camera.a7 * v[i].x + camera.a8 * v[i].y + camera.a9 * v[i].z) / 128; + //float z3D = (-(camera.a1 * v[i].x + camera.a2 * v[i].y + camera.a3 * v[i].z)) / 128; + + float x2D = x3D; + float y2D = y3D; + + //int color = (z3D < 0 ? C_BLACK : C_LIGHT); + + dline(repere_x, repere_y, x2D + repere_x, y2D + repere_y, C_BLACK); + dtext(x2D + repere_x, y2D + repere_y-2, C_BLACK, letter[i]); + } + +} + + + + + +//---------------------------------------------------------------------------------------------------- +// VERTEX +//---------------------------------------------------------------------------------------------------- +Vertex::Vertex(){} + +Vertex::Vertex(int _x, int _y, int _z) +{ + x = _x; + y = _y; + z = _z; +} + +Vertex::Vertex(int _x, int _y, int _z, float _u, float _v) +{ + x = _x; + y = _y; + z = _z; + u = _u; + v = _v; +} + +void Vertex::set_texture(TexturePoint t) +{ + u = t.u; + v = t.v; +} + +void Vertex::set_xyz(int _x, int _y, int _z) +{ + x = _x; + y = _y; + z = _z; +} + +//---------------------------------------------------------------------------------------------------- +// WMESH +//---------------------------------------------------------------------------------------------------- + +void WMesh::from_mesh(const Mesh* mesh, int margin) +{ + // Double allocated memory because 3D clipping could generate more vertices and copy mesh into working mesh + v_length = mesh->v_length; + v_length_allocated = mesh->v_length * margin; + v = (Vertex*) malloc(v_length_allocated * sizeof(Vertex)); + for (int i = 0; i < mesh->v_length; i++) + { + //v[i].FromVertexPoint(mesh->v[i]) + v[i].x = mesh->v[i].x; + v[i].y = mesh->v[i].y; + v[i].z = mesh->v[i].z; + } + + t_length = mesh->t_length; + t_length_allocated = mesh->t_length * margin; + t = (TexturePoint*) malloc(t_length_allocated * sizeof(TexturePoint)); + memcpy(t, mesh->t, mesh->t_length * sizeof(TexturePoint)); + + f_length = mesh->f_length; + f_length_allocated = mesh->f_length * margin; + f = (Face*) malloc(f_length_allocated * sizeof(Face)); + memcpy(f, mesh->f, mesh->f_length * sizeof(Face)); +} + +void WMesh::free_memory() +{ + free(v); + free(t); + free(f); +} + +void WMesh::add_vertex(Vertex vertex) +{ + v[v_length].x = vertex.x; + v[v_length].y = vertex.y; + v[v_length].z = vertex.z; + t[t_length].u = vertex.u; + t[t_length].v = vertex.v; + + if (v_length < v_length_allocated) v_length++; + if (t_length < t_length_allocated) t_length++; +}