📄 mouse_sim.c
字号:
/*************************************************************************** * 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 4typedef 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 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, SOS_KWQ_ORDER_FIFO)); //Creation du semaphore de creation de souris SOS_ASSERT_FATAL(SOS_OK == sos_ksema_init(& SemMouse, "SemMouse", 2, SOS_KWQ_ORDER_FIFO)); //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, SOS_SCHED_PRIO_TS_LOWEST-1) != 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)];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -