//-------------------------------------------------------------------------------------- // 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; }
//-------------------------------------------------------------------------------------- // 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; }