⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mouse_sim.c

📁 Simple Operating Systems (简称SOS)是一个可以运行在X86平台上(包括QEMU
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************** *   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 + -