Ejemplo n.º 1
0
	//--------------------------------------------------------------------------------------
	// Método para crear la ventana de la aplicación.
	//--------------------------------------------------------------------------------------	
	bool Application::CreateAppWnd (HINSTANCE instance, LPCTSTR name, int width, int height,
									bool fullscreen, bool resizable)
	{
		//----------------------------------------------------------------------------------
		// Información de entrada en el fichero de log.
		//----------------------------------------------------------------------------------
		Log * AppLog = Log::GetInstance();

		AppLog->Add("//------------------------------------------------------------");
		AppLog->Add("// Yukino 2.0 log.");
		AppLog->Add("//------------------------------------------------------------\n");

		AppLog->Add("Creando la ventana de la aplicación.");

		//----------------------------------------------------------------------------------
		// Modificamos los últimos puntos que no se podían configurara en el constructor,
		// de la clase ventana que vamos a registrar para nuestra aplicación. Estos son el
		// identificador de instancia y el nombre de la clase a registrar.
		//----------------------------------------------------------------------------------
		this->WndClass.hInstance     = instance;
		this->WndClass.lpszClassName = name;

		//----------------------------------------------------------------------------------
		// Mandamos a registrar la clase, una vez está totalmente configurada.
		//----------------------------------------------------------------------------------
		if(!RegisterClassEx(&this->WndClass))
		{
			AppLog->Add("(-) ¡Error al registrar la clase ventana!", APPERR_REGWNDCLS);
			return false;
		}

		AppLog->Add("(+) Clase ventana registrada correctamente.");

		//----------------------------------------------------------------------------------
		// Si la clase es registrada correctamente, el siguiente paso es modificar el modo
		// de visualización de la pantalla, siempre y cuando la aplicación sea a pantalla
		// completa. Para ello hace falta tener el ancho, el alto, y la profundidad de
		// color. Si no se lograra poder cambiar el modo de pantalla, ejecutamos la
		// aplicación en modo ventana, avisando en el log del problema.
		//----------------------------------------------------------------------------------
		if(fullscreen)
		{
			DEVMODE devModeScreen;
			memset(&devModeScreen, 0, sizeof(devModeScreen));          // Limpiamos la estructura
			devModeScreen.dmSize       = sizeof(devModeScreen);        // Tamaño de la estructura
			devModeScreen.dmPelsWidth  = width;                        // Ancho de la pantalla
			devModeScreen.dmPelsHeight = height;                       // Alto de la pantalla
			devModeScreen.dmBitsPerPel = this->PixelFormat.cColorBits; // Bpp de la pantalla
			devModeScreen.dmFields     = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;

			// Cambiamos el modo de la pantalla, de no lograrlo ponemos fullscreen a falso.
			if(ChangeDisplaySettings(&devModeScreen, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
			{
				AppLog->Add("(-) ¡Error al intentar pasar a modo pantalla completa!");
				fullscreen = false;
			}
		}

		//----------------------------------------------------------------------------------
		// Configuramos las propiedades internas de la clase, justo en este momento, en el
		// que no van a padecer ningún cambio que querramos ver reflejado en el futuro.
		//----------------------------------------------------------------------------------
		this->hInstance  = instance;
		this->Name       = name;
		this->Width      = width;
		this->Height     = height;
		this->FullScreen = fullscreen;
		this->Resizable  = resizable;

		//----------------------------------------------------------------------------------
		// Y ahora pasamos a configurar algunas propiedades del estilo y las dimensiones
		// que tendrá la ventana. En modo pantalla completa solo es necesario cambiar el
		// estilo. Pero en modo ventana, dependiendo de de si queremos que sea
		// redimensionable o no, tendremos que manipular las dimensiones de la ventana,
		// para que el area de pintado sea el que hemos indicado.
		//----------------------------------------------------------------------------------
		DWORD WndStyle;
		DWORD WndStyleEx;

		if(fullscreen)
		{
			WndStyleEx = WS_EX_APPWINDOW;
			WndStyle   = WS_POPUP;
			::ShowCursor(FALSE);
		}
		else
		{
			WndStyleEx = NULL;

			if(resizable)
			{
				width  += WINMODE_INCW;
				height += WINMODE_INCH;

				WndStyle = WS_OVERLAPPEDWINDOW;
			}
			else
			{
				width  += (WINMODE_INCW - WINMODE_FIXED);
				height += (WINMODE_INCH - WINMODE_FIXED);

				WndStyle = WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_VISIBLE;
			}

			::ShowCursor(TRUE);
		}

		//----------------------------------------------------------------------------------
		// Ajustamos la ventana al tamaño indicado.
		//----------------------------------------------------------------------------------
		RECT WindowRect;
		WindowRect.top    = 0;
		WindowRect.left   = 0;
		WindowRect.bottom = height;
		WindowRect.right  = width;

		AdjustWindowRectEx(&WindowRect, WndStyle, FALSE, WndStyleEx);

		//----------------------------------------------------------------------------------
		// Creamos la ventana con todas las propiedades bien configuradas.
		//----------------------------------------------------------------------------------
		this->hWnd = CreateWindow(name,          // Nombre de la Clase
								  name,          // El titulo de la ventana
								  WndStyle,      // Estilo de la ventana
								  CW_USEDEFAULT, // X
								  CW_USEDEFAULT, // Y
								  width,         // Ancho
								  height,        // Alto
								  NULL,          // Ventana padre
								  NULL,          // Menu de la ventana
								  instance,      // La instancia
								  NULL);
		
		//----------------------------------------------------------------------------------
		// Tras mandar a crear la ventana, comprobamos que todo ha ido bien.
		//----------------------------------------------------------------------------------
		if(this->hWnd == NULL)
		{
			AppLog->Add("(-) ¡La ventana no ha podido ser creada!", APPERR_CREATEWND);
			return false;
		}

		AppLog->Add("(+) Ventana creada correctamente.");

		//----------------------------------------------------------------------------------
		// Mandamos mostrar la ventana y que sea actualizado su contenido.
		//----------------------------------------------------------------------------------
		ShowWindow(this->hWnd, SW_SHOW);
		UpdateWindow(this->hWnd);

		//----------------------------------------------------------------------------------
		// Obtenemos el dispositivo de contexto de la aplicación, para escoger un formato
		// de pixel lo más cercano al que queremos. Y lo mandamos seleccionar para que sea
		// usado en nuestra aplicación.
		//----------------------------------------------------------------------------------
		this->hDC = GetDC(this->hWnd);

		int nPixelFormat; // Indice del formato de pixel escogido

		nPixelFormat = ChoosePixelFormat(this->hDC, &this->PixelFormat);

		SetPixelFormat(this->hDC, nPixelFormat, &this->PixelFormat);

		//----------------------------------------------------------------------------------
		// Tras seleccionar el formato creamos el contexto para OpenGL y lo activamos.
		//----------------------------------------------------------------------------------
		this->hRC = wglCreateContext(this->hDC);
		wglMakeCurrent(this->hDC, this->hRC);

		//----------------------------------------------------------------------------------
		// Indicamos que no se tiene que salir de la aplicación y ya está.
		//----------------------------------------------------------------------------------
		this->ExitApp = false;

		//----------------------------------------------------------------------------------
		// Obtenemos los gestores de gráficos, entrada, sonidos, etcétera.
		//----------------------------------------------------------------------------------
		this->Graphics = GraphicsManager::GetInstance();
		//this->Sound = SoundManager::GetInstance();

		return true;
	}
Ejemplo n.º 2
0
	//--------------------------------------------------------------------------------------
	// Método para inicializar el dispositivo de entrada.
	//--------------------------------------------------------------------------------------
	bool InputManager::Init (HWND hwnd, LONG width, LONG height, bool fullscreen,
							 bool resizable)
	{
		//----------------------------------------------------------------------------------
		// Configuramos los flags en base al modo de visualización.
		//----------------------------------------------------------------------------------
		DWORD flags;

		if(fullscreen)
		{
			flags = DISCL_BACKGROUND | DISCL_NONEXCLUSIVE | DISCL_NOWINKEY;
		}
		else
		{
			flags = DISCL_BACKGROUND | DISCL_NONEXCLUSIVE;
		}

		Log * InpLog = Log::GetInstance();

		//----------------------------------------------------------------------------------
		// Creamos la interfaz principal DInput.
		//----------------------------------------------------------------------------------
		if(FAILED(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION,
									 IID_IDirectInput8, (void**) &lpDInput, NULL)))
		{
			InpLog->Add("(-) ¡Fallo al crear la clase DirectInput8!",
						INPERR_DIRECTINPUT8CREATE);
			return false;
		}


		//----------------------------------------------------------------------------------
		// Creación del dispositivo del teclado.
		//----------------------------------------------------------------------------------
		if(FAILED(lpDInput->CreateDevice(GUID_SysKeyboard, &lpKeyb, NULL)))
		{
			InpLog->Add("(-) ¡Fallo al crear el dispositivo del teclado!",
						INPERR_CREATEDEVICE_KEYBOARD);
			return false;
		}
		
		//----------------------------------------------------------------------------------
		// Le indicamos la forma de guardar los datos
		//----------------------------------------------------------------------------------
		if(FAILED(lpKeyb->SetDataFormat(&c_dfDIKeyboard)))
		{
			InpLog->Add("(-) ¡Fallo al configurar el formato de datos del teclado!",
						INPERR_SETDATAFORMAT_KEYBOARD);
			return false;
		}

		//----------------------------------------------------------------------------------
		// Establecemos el nivel coperativo:
		//   DISCL_FOREGROUND   -> El dispositivo solo funciona con la aplicacion activa.
		//   DISCL_BACKGROUND   -> El dispositivo funciona aun sin estar la aplicacion activa.
		//   DISCL_EXCLUSIVE    -> El dispositivo es exclusivo a la aplicacion.
		//   DISCL_NONEXCLUSIVE -> El dispositivo no es exclusivo a la aplicacion.
		//----------------------------------------------------------------------------------
		if(FAILED(lpKeyb->SetCooperativeLevel(hwnd, flags)))
		{
			InpLog->Add("(-) ¡Fallo al indicar el nivel de cooperación del teclado!",
						INPERR_SETCOOPERATIVELEVEL_KEYBOARD);
			return false;
		}
		
		//----------------------------------------------------------------------------------
		// Activamos el teclado.
		//----------------------------------------------------------------------------------
		if(FAILED(lpKeyb->Acquire()))
		{
			InpLog->Add("(-) ¡Fallo al adquirir el teclado!", INPERR_ACQUIRE_KEYBOARD);
			return false;
		}


		//----------------------------------------------------------------------------------
		// Creación del dispositivo del ratón.
		//----------------------------------------------------------------------------------
		if(FAILED(lpDInput->CreateDevice(GUID_SysMouse, &lpMouse, NULL)))
		{
			InpLog->Add("(-) ¡Fallo al crear el dispositivo del ratón!",
						INPERR_CREATEDEVICE_MOUSE);
			return false;
		}
		
		//----------------------------------------------------------------------------------
		// Le indicamos la forma de guardar los datos.
		//----------------------------------------------------------------------------------
		if(FAILED(lpMouse->SetDataFormat(&c_dfDIMouse)))
		{
			InpLog->Add("(-) ¡Fallo al configurar el formato de datos del ratón!",
						INPERR_SETDATAFORMAT_MOUSE);
			return false;
		}
		
		//----------------------------------------------------------------------------------
		// Establecemos el nivel coperativo:
		//   DISCL_FOREGROUND   -> El dispositivo solo funciona con la aplicacion activa.
		//   DISCL_BACKGROUND   -> El dispositivo funciona aun sin estar la aplicacion activa.
		//   DISCL_EXCLUSIVE    -> El dispositivo es exclusivo a la aplicacion.
		//   DISCL_NONEXCLUSIVE -> El dispositivo no es exclusivo a la aplicacion.
		//----------------------------------------------------------------------------------
		if(FAILED(lpMouse->SetCooperativeLevel(hwnd, flags)))
		{
			InpLog->Add("(-) ¡Fallo al indicar el nivel de cooperación del ratón!",
						INPERR_SETCOOPERATIVELEVEL_MOUSE);
			return false;
		}
		
		//----------------------------------------------------------------------------------
		// Activamos el ratón.
		//----------------------------------------------------------------------------------
		if(FAILED(lpMouse->Acquire()))			
		{
			InpLog->Add("(-) ¡Fallo al adquirir el ratón!", INPERR_ACQUIRE_MOUSE);
			return false;
		}

		//----------------------------------------------------------------------------------
		// Guardamos el manejador de la ventana.
		//----------------------------------------------------------------------------------
		this->hWindow    = hwnd;
		this->FullScreen = fullscreen;
		
		this->Width  = 0;
		this->Height = 0;
		
		if(resizable)
		{
			this->WndDecX = WINMODE_INCW;
			this->WndDecY = WINMODE_INCH;
		}
		else
		{
			this->WndDecX = (WINMODE_INCW - WINMODE_FIXED);
			this->WndDecY = (WINMODE_INCH - WINMODE_FIXED);
		}

		//----------------------------------------------------------------------------------
		// Finalente devolvemos que todo ha ido bien.
		//----------------------------------------------------------------------------------
		InpLog->Add("(+) Entrada inicializada correctamente.", EVERYTHING_ALL_RIGHT);

		return true;
	}