summaryrefslogtreecommitdiff
path: root/sos-code-article6.5/sos/mouse_sim.c
diff options
context:
space:
mode:
authorAlex AUVOLAT <alex.auvolat@ens.fr>2014-03-28 17:09:15 +0100
committerAlex AUVOLAT <alex.auvolat@ens.fr>2014-03-28 17:09:15 +0100
commita8968330aff45e0b8cf278f49fa337d5fcb9bfd8 (patch)
treededf697b1a5c3c96e77f77e551e9e6af8785a51c /sos-code-article6.5/sos/mouse_sim.c
parent8d9e22df8afa4c3339e52c7b3b77388ca0e69fac (diff)
downloadSOS-a8968330aff45e0b8cf278f49fa337d5fcb9bfd8.tar.gz
SOS-a8968330aff45e0b8cf278f49fa337d5fcb9bfd8.zip
Import and compile code for article 6.5
Diffstat (limited to 'sos-code-article6.5/sos/mouse_sim.c')
-rw-r--r--sos-code-article6.5/sos/mouse_sim.c803
1 files changed, 803 insertions, 0 deletions
diff --git a/sos-code-article6.5/sos/mouse_sim.c b/sos-code-article6.5/sos/mouse_sim.c
new file mode 100644
index 0000000..c5eb6bf
--- /dev/null
+++ b/sos-code-article6.5/sos/mouse_sim.c
@@ -0,0 +1,803 @@
+/***************************************************************************
+ * Copyright (C) 2004 by cyril dupuit *
+ * cyrildupuit@hotmail.com *
+ * http://perso.wanadoo.fr/koalys/ *
+ * (Adaptation for SOS by d2 -- 2004/12/20) *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+//*****************************************************************************
+// Nom du module : MouseSim.c
+// Description : Creation et destruction de souris mangeuse de fromages
+//*****************************************************************************
+
+#include <sos/assert.h>
+#include <sos/klibc.h>
+#include <sos/thread.h>
+#include <sos/ksynch.h>
+#include <sos/kmalloc.h>
+#include <drivers/x86_videomem.h>
+
+// Historique :
+// 20/12/04 : Suppr DestroyMap et suppr handler kbd dans version LM (d2)
+// 26/11/04 : Bug trouve et resolu dans la fonction DestroyMap
+// 21/11/04 : Creation du module V1.0
+
+//*****************************************************************************
+// Definition des equivalences :
+//*****************************************************************************
+#define MAP_X 76
+#define MAP_Y 12
+#define MAP_SIZE MAP_X * MAP_Y
+
+#define MOUSE 0x01
+#define CHEESE 0x02
+#define OBSTACLE 0x04
+#define INPUT 0x08
+#define OUTPUT 0x10
+
+#define OBSTACLE_COUNT 100
+#define CHEESE_COUNT 650
+
+#define MOUSE_FULL 0x01
+#define MOUSE_EMPTY 0x02
+#define CHEESE_FOUND 0x04
+#define MOUSE_EXITED 0x08
+
+#define MOUSE_SPEED_MAX 1000
+#define MOUSE_SPEED_MIN 4
+
+typedef unsigned int Color_t;
+
+struct Point{
+ int X;
+ int Y;
+ };
+
+typedef struct Point Point_t;
+
+#define Set(Reg, Flag) Reg = (Reg | Flag)
+#define Reset(Reg, Flag) Reg = (Reg &(~Flag))
+#define IsSet(Reg, Flag) (Reg & Flag)
+
+
+//*****************************************************************************
+// Structure de gestion d'un element
+//*****************************************************************************
+struct Element{
+ sos_ui32_t Type;//Type d'element
+ sos_ui32_t Status;
+ Color_t Color;//Couleur de l'element
+ Point_t P;//Coordonnees de l'element
+ struct sos_thread * ThreadID;//Thread associe a la souris
+ int Way;//Direction de la souris
+ };
+
+typedef struct Element Element_t;
+
+//*****************************************************************************
+// Prototypes des fonctions/procedures :
+//*****************************************************************************
+static void MouseCommander(void);
+static void DrawMap(void);
+static sos_ret_t CreateMap(void);
+static sos_ret_t InitMapInput(Element_t * * pMap);
+static sos_ret_t InitMapOutput(Element_t * * pMap);
+static sos_ret_t ElementInit(Element_t * * pMap, unsigned int Type);
+static void Mouse(unsigned long Param);
+static void MouseMove(Point_t * P);
+static Point_t ChoosePosition(Element_t * pMouse, int Positions[], int Count);
+static int EvaluatePositions(Point_t Org, int Positions[], Point_t * Cheese);
+static sos_bool_t IsCollision(Point_t Org, Point_t p, Point_t *Cheese);
+static sos_bool_t AffectMovement(Point_t Org, Point_t p);
+static void MouseCreator(void);
+static sos_ret_t CreateMouse(void);
+
+//*****************************************************************************
+// Variables globales de ce module :
+//*****************************************************************************
+
+static Element_t * * pMap;
+static struct sos_ksema SemMap;
+static struct sos_ksema SemMouse;
+static int MouseCount = 0;
+static int CheeseCount = 0;
+static int ObstacleCount = 0;
+static int MouseSpeed = 100;
+
+//*****************************************************************************
+// Koalys Glue
+//*****************************************************************************
+void DrawPixel(int x, int y, Color_t color)
+{
+ sos_x86_videomem_putchar(y+3, x+2, color, 219);
+}
+
+
+
+//*****************************************************************************
+// Point d'entre de la 'simulation'
+//*****************************************************************************
+void MouseSim(void)
+{
+ //Creation du semaphore de protection de la carte
+ SOS_ASSERT_FATAL(SOS_OK == sos_ksema_init(& SemMap, "SemMap", 1));
+
+ //Creation du semaphore de creation de souris
+ SOS_ASSERT_FATAL(SOS_OK == sos_ksema_init(& SemMouse, "SemMouse", 2));
+
+ //Creation de la carte
+ SOS_ASSERT_FATAL(SOS_OK == CreateMap());
+
+ //Creation du thread createur de souris
+ SOS_ASSERT_FATAL(sos_create_kernel_thread("MouseCreator",
+ (sos_kernel_thread_start_routine_t)MouseCreator,
+ 0) != NULL);
+
+}
+
+
+//*****************************************************************************
+// But de la fonction : Creer et initialiser la carte
+// Entree : Aucune
+// Parametre retourne : ERROR si la memoire est insuffisante, TRUE sinon
+//*****************************************************************************
+static sos_ret_t CreateMap(void)
+{
+ pMap = (Element_t * *)sos_kmalloc(MAP_SIZE * sizeof(Element_t *), 0);
+ if(pMap == NULL) return -SOS_ENOMEM;
+
+ //Mettre la carte a 0
+ memset(pMap, 0, MAP_SIZE * sizeof(Element_t *));
+
+ //Initialisation de l'entree de la carte
+ if(SOS_OK != InitMapInput(pMap))
+ {//Memoire insuffisante
+ return -SOS_EFATAL;
+ }
+
+ //Initialisation de la sortie de la carte
+ if(InitMapOutput(pMap) != SOS_OK)
+ {//Memoire insuffisante
+ return -SOS_EFATAL;
+ }
+
+ //Initialisation du fromage
+ if(ElementInit(pMap, CHEESE) != SOS_OK)
+ {//Memoire insuffisante
+ return -SOS_EFATAL;
+ }
+
+ //Initialisation des obstacles
+ if(ElementInit(pMap, OBSTACLE) != SOS_OK)
+ {//Memoire insuffisante
+ return -SOS_EFATAL;
+ }
+
+ DrawMap();//Afficher la carte creee
+
+ return SOS_OK;
+}
+
+//*****************************************************************************
+// But de la procedure : Dessiner la carte a l'ecran
+// Entree : Aucune
+// Sortie : Aucune
+//*****************************************************************************
+static void DrawMap(void)
+{
+ unsigned int I;
+
+ for(I = 0; I < MAP_SIZE; I++)
+ {
+ if(pMap[I] != NULL)
+ {
+ DrawPixel(I % MAP_X, I/MAP_X, pMap[I]->Color);
+ }
+ else DrawPixel(I % MAP_X, I/MAP_X, SOS_X86_VIDEO_FG_BLACK);
+ }
+ sos_x86_videomem_printf(23, 0, SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
+ "Souris = %d; Fromages = %d; Obstacles = %d ",
+ MouseCount, CheeseCount, ObstacleCount);
+}
+
+//*****************************************************************************
+// But de la fonction : Initialiser l'entree de la carte
+// Entree :
+// pMap : Pointeur sur la carte
+// Parametre retourne : ERROR si memoire insuffisante, TRUE sinon
+//*****************************************************************************
+static sos_ret_t InitMapInput(Element_t * * pMap)
+{
+ Element_t * pElement;
+
+ //Definir le point d'entree
+ pElement = (Element_t *)sos_kmalloc(sizeof(Element_t), 0);
+ if(pElement == NULL) return -SOS_ENOMEM;
+
+ //Initialiser l'entree
+ pElement->Type = INPUT;
+ pElement->Status = 0;
+ pElement->Color = SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE;
+ pElement->P.X = 0;
+ pElement->P.Y = MAP_Y / 2;
+ pElement->ThreadID = 0;
+
+ pMap[(pElement->P.Y * MAP_X) + pElement->P.X] = pElement;
+
+ return SOS_OK;
+}
+
+//*****************************************************************************
+// But de la fonction : Initialiser la sortie de la carte
+// Entree :
+// pMap : Pointeur sur la carte
+// Parametre retourne : ERROR si memoire insuffisante, TRUE sinon
+//*****************************************************************************
+static sos_ret_t InitMapOutput(Element_t * * pMap)
+{
+ Element_t * pElement;
+
+ //Definir le point de sortie
+ pElement = (Element_t *)sos_kmalloc(sizeof(Element_t), 0);
+ if(pElement == NULL) return -SOS_ENOMEM;
+
+ //Initialiser l'entree
+ pElement->Type = OUTPUT;
+ pElement->Status = 0;
+ pElement->Color = SOS_X86_VIDEO_FG_LTBLUE;
+ pElement->P.X = MAP_X - 1;
+ pElement->P.Y = MAP_Y / 2;
+ pElement->ThreadID = 0;
+
+ pMap[(pElement->P.Y * MAP_X) + pElement->P.X] = pElement;
+
+ return SOS_OK;
+}
+
+//*****************************************************************************
+// But de la fonction : Initialiser un type d'objet sur la carte
+// Entree :
+// pMap : Pointeur sur la carte
+// Type : Type d'objet a initialiser
+// Parametre retourne : ERROR si memoire insuffisante, TRUE sinon
+//*****************************************************************************
+static sos_ret_t ElementInit(Element_t * * pMap, unsigned int Type)
+{
+ unsigned int I, J;
+ unsigned int Max;
+ Color_t Color;
+
+ if(Type == CHEESE)
+ {//Type d'element = fromage
+ Max = CHEESE_COUNT;
+ Color = SOS_X86_VIDEO_FG_YELLOW;
+ }
+ else if(Type == OBSTACLE)
+ {//Type d'element = Obstacle
+ Max = OBSTACLE_COUNT;
+ Color = SOS_X86_VIDEO_FG_GREEN;
+ }
+ else
+ {//Aucune autre type reconnu
+ return -SOS_EINVAL;
+ }
+
+ for(I = 0; I < Max; I++)
+ {//Tirer les fromages
+ J = random();
+ J += random();
+ J %= MAP_SIZE;
+ if(pMap[J] == NULL)
+ {//Si l'emplacement est libre
+ pMap[J] = (Element_t *)sos_kmalloc(sizeof(Element_t),
+ 0);
+ if(pMap[J] == NULL) return -SOS_ENOMEM;
+
+ pMap[J]->Type = Type;
+ //Initialiser l'element
+ if(Type == CHEESE)
+ {//Type d'element = fromage
+ CheeseCount++;
+ }
+ else if(Type == OBSTACLE)
+ {//Type d'element = Obstacle
+ ObstacleCount++;
+ }
+
+ pMap[J]->Color = Color;
+ pMap[J]->Status = 0;
+ pMap[J]->Color = Color;
+ pMap[J]->P.X = J % MAP_X;
+ pMap[J]->P.Y = J / MAP_X;
+ pMap[J]->ThreadID = 0;
+ }
+ }
+
+ return SOS_OK;
+}
+
+
+//*****************************************************************************
+// But du thread : Deplacer la souris sur la carte selon les regles etablies.
+// Regles :
+// - La souris doit se placer devant l'entree puis commence a recolter du
+// fromage.
+// - Des que la souris a ramasse un morceau de fromage, elle doit aller en
+// entree de la carte afin de deposer sa recolte.
+// - Si une souris a prouve sa recolte, une autre souris est creee.
+// - Si une souris prend la sortie, elle est eliminee.
+//*****************************************************************************
+static void Mouse(unsigned long Param)
+{
+ Element_t * pMouse = (Element_t *)Param;
+ Point_t P;
+
+ SOS_ASSERT_FATAL(pMouse != NULL);
+
+ //Position de depart de la souris
+ P = pMouse->P;
+ P = pMouse->P;
+
+ while(1)
+ {
+ int delay_ms;
+ struct sos_time delay;
+
+ //La souris doit se deplacer
+ sos_ksema_down(& SemMap, NULL);
+
+ MouseMove(&P);
+
+ sos_ksema_up(& SemMap);
+
+ // Est-ce que la souris est sortie ?
+ if (IsSet(pMouse->Status, MOUSE_EXITED))
+ // Oui => on sort
+ break;
+
+ // Delai entre MOUSE_SPEED_MIN et MouseSpeed - 1
+ delay_ms = MOUSE_SPEED_MIN + (random() % MouseSpeed);
+ delay.sec = delay_ms / 1000;
+ delay.nanosec = (delay_ms % 1000) * 1000000;
+ sos_thread_sleep(& delay);
+ }
+
+ // Libere la structure associee
+ sos_kfree((sos_vaddr_t)pMouse);
+}
+
+//*****************************************************************************
+// But de la procedure : Deplacer la souris de maniere aleatoire sur la carte
+// Entrees :
+// P : Position courante de la souris
+// Sorties :
+// P : Position suivante de la souris
+//*****************************************************************************
+static void MouseMove(Point_t * P)
+{
+ Point_t Org;
+ Point_t p;
+ Point_t Cheese;
+ int Positions[8];
+ int Count = 0;
+ Element_t * pMouse;
+
+ Org = *P;
+
+ pMouse = pMap[Org.X + (Org.Y * MAP_X)];
+
+ Count = EvaluatePositions(Org, Positions, &Cheese);
+
+ if(Count == 0) return;
+
+ p = Org;
+
+ if(IsSet(pMouse->Status, CHEESE_FOUND))
+ {//Prendre le fromage
+ Reset(pMouse->Status, CHEESE_FOUND);
+ p = Cheese;
+ }
+ else
+ {//Choisir une position au hasard
+ p = ChoosePosition(pMouse, Positions, Count);
+ }
+ if(AffectMovement(Org, p) == FALSE) return;
+ //Deplacer la souris
+ pMap[Org.X + (Org.Y * MAP_X)] = NULL;
+ pMap[p.X + (p.Y * MAP_X)] = pMouse;
+ pMouse->P = p;
+ //Mettre a jour l'affichage
+ DrawPixel(Org.X, Org.Y, SOS_X86_VIDEO_FG_BLACK);
+ DrawPixel(p.X, p.Y, pMouse->Color);
+ sos_x86_videomem_printf( 23,0, SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE, "Souris = %d; Fromages = %d; Obstacles = %d ", MouseCount, CheeseCount, ObstacleCount);
+ //Mettre a jour les coordonnees
+ *P = p;
+}
+
+//*****************************************************************************
+// But de la fonction : Choisir un mouvement
+// Entree :
+// pMouse : Pointeur sur la souris
+// Positions : Tableau de position possible
+// Count :Nombre de positions valides
+// Sortie : Aucune
+// Parametre retourne : Position choisie
+//*****************************************************************************
+static Point_t ChoosePosition(Element_t * pMouse, int Positions[], int Count)
+{
+ int I, J;
+ Point_t p;
+
+ for(J = 0; J < Count; J++)
+ {//Chercher dans le tableau si cette position est disponible
+ I = Positions[J];
+ if(I == pMouse->Way)
+ {//Poursuivre ce sens d'avance
+ p = pMouse->P;
+ switch(I)
+ {
+ case 0:
+ p.Y++;
+ break;
+ case 1:
+ p.X++;
+ p.Y++;
+ break;
+ case 2:
+ p.X++;
+ break;
+ case 3:
+ p.Y--;
+ p.X++;
+ break;
+ case 4:
+ p.Y--;
+ break;
+ case 5:
+ p.Y--;
+ p.X--;
+ break;
+ case 6:
+ p.X--;
+ break;
+ case 7:
+ p.X--;
+ p.Y++;
+ break;
+ }
+ return p;
+ }
+ }
+
+ J = random() % Count;
+ I = Positions[J];
+ if(((I + 4) % 8) == pMouse->Way)
+ {//Eviter le sens inverse
+ J = (J + 1) % Count;
+ I = Positions[J];
+ }
+
+ p = pMouse->P;
+ switch(I)
+ {//Repere le deplacement
+ case 0:
+ p.Y++;
+ break;
+ case 1:
+ p.X++;
+ p.Y++;
+ break;
+ case 2:
+ p.X++;
+ break;
+ case 3:
+ p.Y--;
+ p.X++;
+ break;
+ case 4:
+ p.Y--;
+ break;
+ case 5:
+ p.Y--;
+ p.X--;
+ break;
+ case 6:
+ p.X--;
+ break;
+ case 7:
+ p.X--;
+ p.Y++;
+ break;
+ }
+
+ pMouse->Way = I;//Memoriser la direction selectionnee
+
+ return p;
+}
+
+//*****************************************************************************
+// But de la fonction : Evaluer les positions possibles et les memoriser dans
+// un tableau de positions si aucun fromage n'a ete detecte. Si du fromage a
+// ete detecte, il sera selectionne en premier. La presence d'un fromage est
+// indiquee par le drapeau CHEESE_FOUND
+// Entree :
+// Org : Position de la souris
+// Sorties :
+// Positions : Tableau de positions valides
+// Cheese : Position du fromage
+// Parametre retourne : Nombre de positions valides
+//*****************************************************************************
+static int EvaluatePositions(Point_t Org, int Positions[], Point_t * Cheese)
+{
+ int I;
+ int Count = 0;
+ Point_t p;
+ Point_t CheesePos;
+
+ for(I = 0; I < 8; I++)
+ {//Explorer toute les directions
+ p = Org;
+ switch(I)
+ {//Repere le deplacement
+ case 0:
+ p.Y++;
+ break;
+ case 1:
+ p.X++;
+ p.Y++;
+ break;
+ case 2:
+ p.X++;
+ break;
+ case 3:
+ p.Y--;
+ p.X++;
+ break;
+ case 4:
+ p.Y--;
+ break;
+ case 5:
+ p.Y--;
+ p.X--;
+ break;
+ case 6:
+ p.X--;
+ break;
+ case 7:
+ p.X--;
+ p.Y++;
+ break;
+ }
+ //Tester la collision
+ if(IsCollision(Org, p, &CheesePos) == FALSE)
+ {//La souris n'a rencontre aucun obstacle
+ Positions[Count] = I;
+ Count++;
+ }
+ }
+
+ *Cheese = CheesePos;
+
+ return Count;
+}
+
+//*****************************************************************************
+// But de la fonction : Affecter un mouvement a la souris
+// Entrees :
+// Org : Coordonnees de la souris
+// p : Coordonnees voulu par la souris
+// Parametre retourne : TRUE si le mouvement a eu lieu, FALSE sinon
+//*****************************************************************************
+static sos_bool_t AffectMovement(Point_t Org, Point_t p)
+{
+ Element_t * pMouse = pMap[Org.X + (Org.Y * MAP_X)];
+ Element_t * pElement;
+
+ pElement = pMap[p.X + (p.Y * MAP_X)];
+
+ //La place est libre
+ if(pElement == NULL) return TRUE;//Autoriser le mouvement
+
+ switch(pElement->Type)
+ {
+ case CHEESE:
+ // Liberer l'emplacement memoire du fromage
+ sos_kfree((sos_vaddr_t)pElement);
+ pMap[p.X + (p.Y * MAP_X)] = NULL;
+
+ //Donner le fromage a la souris
+ Set(pMouse->Status, MOUSE_FULL);
+ Reset(pMouse->Status, MOUSE_EMPTY);
+ pMouse->Color = SOS_X86_VIDEO_FG_MAGENTA;
+ CheeseCount--;
+ return TRUE;
+ case OUTPUT:
+ //Supprimer la souris
+ pMap[Org.X + (Org.Y * MAP_X)] = NULL;
+ MouseCount--;
+ DrawPixel(Org.X, Org.Y, SOS_X86_VIDEO_FG_BLACK);
+ sos_x86_videomem_printf( 23,0, SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
+ "Souris = %d; Fromages = %d; Obstacles = %d ",
+ MouseCount, CheeseCount,
+ ObstacleCount);
+ Set(pMouse->Status, MOUSE_EXITED);
+ return FALSE;
+ default :
+ return FALSE;
+ }
+
+ return FALSE;
+}
+
+//*****************************************************************************
+// But de la fonction : Tester si une collision a eu lieu avec un obstacle
+// Entrees :
+// Org : Coordonnees de la souris
+// p : coordonnees desirees par la souris
+// Sortie :
+// Cheese : Coordonnees du fromage
+// Parametre retourne : TRUE si une collision a eu lieu, FALSE sinon
+//*****************************************************************************
+static sos_bool_t IsCollision(Point_t Org, Point_t p, Point_t *Cheese)
+{
+ Element_t * pMouse = pMap[Org.X + (Org.Y * MAP_X)];
+ Element_t * pElement;
+
+ //Tester les bordures de la map
+ if((p.X < 0)||(p.Y < 0)) return TRUE;
+
+ if((p.Y >= MAP_Y)||(p.X >= MAP_X)) return TRUE;
+
+ pElement = pMap[p.X + (p.Y * MAP_X)];
+
+ //L'element est vide
+ if(pElement == NULL) return FALSE;
+
+ //Si du fromage a ete trouve, stopper la recherche
+ if(IsSet(pMouse->Status, CHEESE_FOUND)) return FALSE;
+
+ switch(pElement->Type)
+ {
+ case CHEESE:
+ if(IsSet(pMouse->Status, MOUSE_FULL)) return TRUE;
+ //Indiquer que du fromage a ete trouve
+ Set(pMouse->Status, CHEESE_FOUND);
+ //Retenir la position du fromage
+ (*Cheese).X = p.X;
+ (*Cheese).Y = p.Y;
+ break;
+ case INPUT:
+ if(IsSet(pMouse->Status, MOUSE_EMPTY)) return TRUE;
+ //Remplir les reserves de fromage
+ Set(pMouse->Status, MOUSE_EMPTY);
+ Reset(pMouse->Status, MOUSE_FULL);
+ pMouse->Color = SOS_X86_VIDEO_FG_LTRED;
+ //Autoriser la creation d'une autre souris
+ sos_ksema_up(& SemMouse);
+ return TRUE;
+ case OUTPUT:
+ break;
+ default :
+ return TRUE;
+ }
+
+ return FALSE;//Aucune collision
+}
+
+//*****************************************************************************
+// But du thread : Creer une souris et la placer autour de l'entree
+//*****************************************************************************
+static void MouseCreator(void)
+{
+ while(1)
+ {
+ sos_ksema_down(& SemMouse, NULL);
+ sos_ksema_down(& SemMap, NULL);
+ CreateMouse();
+ sos_ksema_up(& SemMap);
+ }
+}
+
+//*****************************************************************************
+// But de la fonction : Creer une souris et l'inserer dans la carte
+// Entree : Aucune
+// Parametre retourne : ERROR si memoire insuffisante, FALSE si souris non
+// cree, TRUE sinon
+//*****************************************************************************
+static sos_ret_t CreateMouse(void)
+{
+ Element_t * pElement;
+ unsigned int I;
+
+ Point_t p;
+
+ for(I = 0; I < 8; I++)
+ {//Explorer tous les emplacements
+ p.X = 0;
+ p.Y = MAP_Y / 2;
+ switch(I)
+ {//Repere le deplacement
+ case 0:
+ p.Y++;
+ break;
+ case 1:
+ p.X++;
+ p.Y++;
+ break;
+ case 2:
+ p.X++;
+ break;
+ case 3:
+ p.Y--;
+ p.X++;
+ break;
+ case 4:
+ p.Y--;
+ break;
+ case 5:
+ p.Y--;
+ p.X--;
+ break;
+ case 6:
+ p.X--;
+ break;
+ case 7:
+ p.X--;
+ p.Y++;
+ break;
+ }
+ if((p.X >= 0)&&(p.Y >= 0)&&(p.X < MAP_X)&&(p.Y < MAP_Y))
+ {//L'emplacement est valide
+ pElement = pMap[p.X + (p.Y * MAP_X)];
+ if(pElement == NULL)
+ {//Creer la souris
+ pElement = (Element_t *)sos_kmalloc(sizeof(Element_t), 0);
+ if(pElement != NULL)
+ {//Initialiser l'entree
+ pElement->Type = MOUSE;
+ Set(pElement->Status, MOUSE_EMPTY);
+ pElement->Color = SOS_X86_VIDEO_FG_LTRED;
+ pElement->P = p;
+ pElement->Way = 0;
+ pElement->ThreadID
+ = sos_create_kernel_thread("Mouse",
+ (sos_kernel_thread_start_routine_t)Mouse,
+ pElement);
+ if(pElement->ThreadID == 0)
+ {
+ sos_kfree((sos_vaddr_t)pElement);
+ pElement = NULL;
+ return -SOS_ENOMEM;
+ }
+ pMap[p.X + (p.Y * MAP_X)] = pElement;
+ MouseCount++;
+
+ DrawPixel(p.X, p.Y, pElement->Color);
+ sos_x86_videomem_printf(23, 0, SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE, "Souris = %d; Fromages = %d; Obstacles = %d ", MouseCount, CheeseCount, ObstacleCount);
+
+ return SOS_OK;
+ }
+ }
+ }
+ }
+ return -SOS_EBUSY;
+}
+
+//*****************************************************************************
+// C'est fini !!!!
+//*****************************************************************************