diff --git a/Client/Audio/Audio.hpp b/Client/Audio/Audio.hpp index e69de29..c7f6250 100644 --- a/Client/Audio/Audio.hpp +++ b/Client/Audio/Audio.hpp @@ -0,0 +1,23 @@ +/* + Niotso - Copyright (C) 2012 Fatbag + + 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 3 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, see . +*/ + +#include "windows/xaudio2.hpp" + +namespace Audio { + DWORD WINAPI ThreadProc(LPVOID lpParameter); + extern HANDLE Thread; +} \ No newline at end of file diff --git a/Client/Audio/Startup.cpp b/Client/Audio/Startup.cpp new file mode 100644 index 0000000..36ce517 --- /dev/null +++ b/Client/Audio/Startup.cpp @@ -0,0 +1,74 @@ +/* + Niotso - Copyright (C) 2012 Fatbag + + 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 3 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, see . +*/ + +#include "../EngineInterface.hpp" + +namespace Audio { + +HANDLE Thread; + +IXAudio2 *pXAudio2 = NULL; +IXAudio2MasteringVoice *MasterVoice = NULL; + +void Shutdown(); + +DWORD WINAPI ThreadProc(LPVOID){ + HRESULT result; + result = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE | COINIT_SPEED_OVER_MEMORY); + if(result != S_OK){ + MessageBox(Window::hWnd, "Failed to initialize Microsoft COM.", NULL, MB_OK | MB_ICONERROR); + Shutdown(); + return ERROR_AUDIO_INIT_COM; + } + + result = XAudio2Create(&pXAudio2, 0, XAUDIO2_DEFAULT_PROCESSOR); + if(result != S_OK){ + MessageBox(Window::hWnd, "Failed to initialize XAudio2. Please download the latest DirectX runtime for your system.", + NULL, MB_OK | MB_ICONERROR); + Shutdown(); + return ERROR_AUDIO_INIT_XAUDIO2; + } + + result = pXAudio2->CreateMasteringVoice(&MasterVoice, 2, 44100, 0, 0, NULL); + if(result != S_OK){ + MessageBox(Window::hWnd, "Failed to create the mastering voice for XAudio2.", NULL, MB_OK | MB_ICONERROR); + Shutdown(); + return ERROR_AUDIO_CREATE_VOICE; + } + + ResetEvent(System::Terminated[HANDLE_AUDIO]); + SetEvent(System::Initialized[HANDLE_AUDIO]); + WaitForSingleObject(System::Shutdown, INFINITE); + + Shutdown(); + return 0; +} + +void Shutdown(){ + if(MasterVoice){ + MasterVoice->DestroyVoice(); + MasterVoice = NULL; + } + if(pXAudio2){ + pXAudio2->Release(); + pXAudio2 = NULL; + } + + SetEvent(System::Terminated[HANDLE_AUDIO]); +} + +} \ No newline at end of file diff --git a/Client/CHANGES b/Client/CHANGES index 509da1e..aacc0cb 100644 --- a/Client/CHANGES +++ b/Client/CHANGES @@ -1 +1,2 @@ -Niotso Technical Preview \ No newline at end of file +Technical Preview 1 + * Initial release \ No newline at end of file diff --git a/Client/CMakeLists.txt b/Client/CMakeLists.txt index e69de29..ebd789e 100644 --- a/Client/CMakeLists.txt +++ b/Client/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 2.6) +project(NiotsoClient) + +if(WIN32) + set(NIOTSOCLIENT_SOURCES + Client.cpp + MessageHandler.cpp + Audio/Startup.cpp + Graphics/Startup.cpp + Graphics/Viewport.cpp + resources/Resource.rc + System/System.cpp + ) + add_executable(TSO WIN32 ${NIOTSOCLIENT_SOURCES}) + target_link_libraries(TSO ole32 opengl32) +endif() \ No newline at end of file diff --git a/Client/Client.cpp b/Client/Client.cpp index e69de29..645304c 100644 --- a/Client/Client.cpp +++ b/Client/Client.cpp @@ -0,0 +1,173 @@ +/* + Niotso - Copyright (C) 2012 Fatbag + + 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 3 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, see . +*/ + +#include "EngineInterface.hpp" + +namespace Window { + unsigned Width, Height; + bool Fullscreen = false; + HWND hWnd = NULL; +} + +int CreateWindowInvisible(HINSTANCE hInst, unsigned Width, unsigned Height, bool Fullscreen); +void Shutdown(); + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int) +{ + int result; + + //Disallow multiple instances of the game from running + CreateMutex(NULL, TRUE, "TSO_NIOTSO_MUTEX"); + if(GetLastError() == ERROR_ALREADY_EXISTS){ + HWND hWnd = FindWindow("TSO_NIOTSO", "The Sims Online"); + if(hWnd != NULL){ + ShowWindowAsync(hWnd, SW_RESTORE); + SetForegroundWindow(hWnd); + SetFocus(hWnd); + } + return ERROR_INIT_ANOTHERINSTRUNNING; + } + + System::Shutdown = CreateEvent(NULL, TRUE, FALSE, NULL); + for(int i=0; i<2; i++){ + System::Initialized[i] = CreateEvent(NULL, TRUE, FALSE, NULL); + System::Terminated[i] = CreateEvent(NULL, TRUE, TRUE, NULL); + } + + result = CreateWindowInvisible(hInstance, 800, 600, false); + if(result != 0){ + Shutdown(); + return ERROR_INIT | ERROR_INIT_WINDOW | result; + } + + Graphics::Thread = CreateThread(NULL, 0, Graphics::ThreadProc, NULL, 0, NULL); + if(Graphics::Thread == NULL){ + Shutdown(); + return ERROR_INIT | ERROR_INIT_GRAPHICS | ERROR_GRAPHICS_CREATE_THREAD; + } + + Audio::Thread = CreateThread(NULL, 0, Audio::ThreadProc, NULL, 0, NULL); + if(Audio::Thread == NULL){ + Shutdown(); + return ERROR_INIT | ERROR_INIT_GRAPHICS | ERROR_GRAPHICS_CREATE_THREAD; + } + + WaitForMultipleObjects(2, System::Initialized, TRUE, INFINITE); + for(int i=0; i<2; i++){ + if(WaitForSingleObject(System::Terminated[i], 0) != WAIT_TIMEOUT){ + /* If Terminated for this thread is signaled, an initialization error occurred */ + Shutdown(); + return ERROR_INIT; + } + } + + MSG msg; + while(GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + Shutdown(); + return 0; +} + +int CreateWindowInvisible(HINSTANCE hInst, unsigned Width, unsigned Height, bool Fullscreen) +{ + const WNDCLASS wc = { + CS_OWNDC, //style + WndProc, //lpfnWndProc + 0, //cbClsExtra + 0, //cbWndExtra + hInst, //hInstance + (HICON) LoadImage(hInst, MAKEINTRESOURCE(IDI_TSO), //hIcon + IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE), + NULL, //hCursor + NULL, //hbrBackground + NULL, //lpszMenuName + "TSO_NIOTSO" //lpszClassName + }; + + if(!RegisterClass(&wc)){ + MessageBox(NULL, "Failed to register the window class.", NULL, MB_OK | MB_ICONERROR); + return ERROR_REGISTER_CLASS; + } + SetCursor(NULL); + + HWND hWnd = NULL; + if(Fullscreen){ + DEVMODE dmScreenSettings; + dmScreenSettings.dmSize = sizeof(dmScreenSettings); + dmScreenSettings.dmFields = DM_PELSWIDTH|DM_PELSHEIGHT|DM_BITSPERPEL; + dmScreenSettings.dmPelsWidth = Width; + dmScreenSettings.dmPelsHeight = Height; + dmScreenSettings.dmBitsPerPel = 32; + + if(ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL){ + MessageBox(NULL, "Fullscreen mode is not supported by your setup. It has been turned off.", NULL, + MB_OK | MB_ICONERROR); + Fullscreen = 0; + }else{ + hWnd = CreateWindowEx(WS_EX_APPWINDOW, "TSO_NIOTSO", "The Sims Online", WS_POPUP, + 0, 0, Width, Height, 0, 0, hInst, NULL); + } + } + if(hWnd == NULL){ + Fullscreen = false; + RECT WindowRect = {0, 0, Width, Height}; + + //Use a style of WS_OVERLAPPEDWINDOW to allow resizing + AdjustWindowRectEx(&WindowRect, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, FALSE, + WS_EX_APPWINDOW); //This finds the dimensions of a window with a client area of our specified dimensions + + //Note: Windows can be positioned anywhere, even outside the visible workspace, + //but their sizes are limited to the size of the workspace on the primary display. + unsigned WindowWidth = WindowRect.right-WindowRect.left, WindowHeight = WindowRect.bottom-WindowRect.top; + RECT WorkspaceRect; + SystemParametersInfo(SPI_GETWORKAREA, 0, &WorkspaceRect, 0); + + hWnd = CreateWindowEx(WS_EX_APPWINDOW, "TSO_NIOTSO", "The Sims Online", + WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, + ((WorkspaceRect.right-WorkspaceRect.left - WindowWidth)>>1) + WorkspaceRect.left, + ((WorkspaceRect.bottom-WorkspaceRect.top - WindowHeight)>>1) + WorkspaceRect.top, + WindowWidth, WindowHeight, 0, 0, hInst, NULL); + } + + if(hWnd == NULL){ + MessageBox(NULL, "Failed to create the window.", NULL, MB_OK | MB_ICONERROR); + return ERROR_CREATE_WINDOW; + } + + Window::hWnd = hWnd; + Window::Width = Width; + Window::Height = Height; + Window::Fullscreen = Fullscreen; + System::hInst = hInst; + return 0; +} + +void Shutdown() +{ + SetEvent(System::Shutdown); + WaitForMultipleObjects(2, System::Terminated, TRUE, INFINITE); + if(Window::hWnd){ + DestroyWindow(Window::hWnd); + Window::hWnd = NULL; + } + + UnregisterClass("TSO_NIOTSO", System::hInst); +} \ No newline at end of file diff --git a/Client/EngineInterface.hpp b/Client/EngineInterface.hpp new file mode 100644 index 0000000..8e1c743 --- /dev/null +++ b/Client/EngineInterface.hpp @@ -0,0 +1,41 @@ +/* + Niotso - Copyright (C) 2012 Fatbag + + 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 3 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, see . +*/ + +#define WINVER 0x0502 +#define _WIN32_WINNT 0x0502 +#define NTDDI_VERSION 0x05010300 +#define _CRT_SECURE_NO_WARNINGS + +#include +#undef NULL +#define NULL 0 + +#include "version.h" +#include "System/System.hpp" +#include "Resources/Resource.h" +#include "Graphics/Graphics.hpp" +#include "Audio/Audio.hpp" + +//IsometricEngine.cpp +namespace Window { + extern unsigned Width, Height; + extern bool Fullscreen; + extern HWND hWnd; +} + +//MessageHandler.cpp +LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); \ No newline at end of file diff --git a/Client/Graphics/Graphics.hpp b/Client/Graphics/Graphics.hpp index e69de29..770a3ae 100644 --- a/Client/Graphics/Graphics.hpp +++ b/Client/Graphics/Graphics.hpp @@ -0,0 +1,30 @@ +/* + Niotso - Copyright (C) 2012 Fatbag + + 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 3 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, see . +*/ + +#include +#include + +//Graphics/Startup.cpp +namespace Graphics { + DWORD WINAPI ThreadProc(LPVOID lpParameter); + extern HANDLE Thread; + extern HDC hDC; + extern HGLRC hRC; + + int InitGL(); + void ResizeViewport(unsigned width, unsigned height); +} \ No newline at end of file diff --git a/Client/Graphics/Startup.cpp b/Client/Graphics/Startup.cpp new file mode 100644 index 0000000..0e76dfa --- /dev/null +++ b/Client/Graphics/Startup.cpp @@ -0,0 +1,127 @@ +/* + Niotso - Copyright (C) 2012 Fatbag + + 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 3 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, see . +*/ + +#include "../EngineInterface.hpp" + +namespace Graphics { + +HANDLE Thread; +HDC hDC; +HGLRC hRC; + +void Shutdown(); + +DWORD WINAPI ThreadProc(LPVOID){ + hDC = GetDC(Window::hWnd); + if(hDC == NULL){ + MessageBox(Window::hWnd, "Failed to obtain the device context.", NULL, MB_OK | MB_ICONERROR); + Shutdown(); + return ERROR_GRAPHICS_OBTAIN_DC; + } + + const PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), 1, //Size and version + PFD_DRAW_TO_WINDOW | //dwFlags + PFD_SUPPORT_OPENGL | + PFD_DOUBLEBUFFER, + PFD_TYPE_RGBA, //iPixelType + 32, //cColorBits + 0, 0, 0, 0, 0, 0, 0, 0, //R,G,B,A bits + 0, 0, 0, 0, 0, //Accumulation buffer bits + 16, //cDepthBits + 0, //cStencilBits + 0, //cAuxBuffers + PFD_MAIN_PLANE, //iLayerType + 0, //Reserved + 0, 0, 0 //Masks + }; + + unsigned PixelFormat = ChoosePixelFormat(hDC, &pfd); + if(!PixelFormat){ + MessageBox(Window::hWnd, "Failed to find a suitable pixel format for the device context.", NULL, MB_OK | MB_ICONERROR); + Shutdown(); + return ERROR_GRAPHICS_FIND_PIXELFORMAT; + } + + if(!SetPixelFormat(hDC, PixelFormat, &pfd)){ + MessageBox(Window::hWnd, "Failed to set the pixel format for the device context.", NULL, MB_OK | MB_ICONERROR); + Shutdown(); + return ERROR_GRAPHICS_SET_PIXELFORMAT; + } + + hRC = wglCreateContext(hDC); + if(!hRC){ + MessageBox(Window::hWnd, "Failed to create an OpenGL rendering context.", NULL, MB_OK | MB_ICONERROR); + Shutdown(); + return ERROR_GRAPHICS_CREATE_GLRC; + } + + if(!wglMakeCurrent(hDC, hRC)){ + MessageBox(Window::hWnd, "Failed to activate the OpenGL device context.", NULL, MB_OK | MB_ICONERROR); + Shutdown(); + return ERROR_GRAPHICS_ACTIVATE_GLRC; + } + + int result = InitGL(); + if(result != 0){ + Shutdown(); + return ERROR_GRAPHICS_INIT_GLSCENE | result; + } + + ResizeViewport(Window::Width, Window::Height); + + ResetEvent(System::Terminated[HANDLE_GRAPHICS]); + SetEvent(System::Initialized[HANDLE_GRAPHICS]); + ShowWindow(Window::hWnd, SW_SHOW); + SetForegroundWindow(Window::hWnd); + SetFocus(Window::hWnd); + + WaitForSingleObject(System::Shutdown, INFINITE); + + Shutdown(); + return 0; +} + +int InitGL(){ + glShadeModel(GL_SMOOTH); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClearDepth(1.0f); + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glEnable(GL_RESCALE_NORMAL); + glDisable(GL_BLEND); + glDepthFunc(GL_LEQUAL); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + return 0; +} + +void Shutdown(){ + ShowWindowAsync(Window::hWnd, SW_HIDE); + if(Graphics::hRC){ + wglMakeCurrent(NULL, NULL); + wglDeleteContext(Graphics::hRC); + Graphics::hRC = NULL; + } + if(Graphics::hDC){ + ReleaseDC(Window::hWnd, Graphics::hDC); + Graphics::hDC = NULL; + } + + SetEvent(System::Terminated[HANDLE_GRAPHICS]); +} + +} \ No newline at end of file diff --git a/Client/Graphics/Viewport.cpp b/Client/Graphics/Viewport.cpp new file mode 100644 index 0000000..ae15159 --- /dev/null +++ b/Client/Graphics/Viewport.cpp @@ -0,0 +1,29 @@ +/* + Niotso - Copyright (C) 2012 Fatbag + + 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 3 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, see . +*/ + +#include "../EngineInterface.hpp" + +void Graphics::ResizeViewport(unsigned width, unsigned height){ + if(width == 0) width++; + if(height == 0) height++; + + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + glOrtho(0, width, 0, height, 0.0, 1.0); +} \ No newline at end of file diff --git a/Client/MessageHandler.cpp b/Client/MessageHandler.cpp new file mode 100644 index 0000000..a6d9db9 --- /dev/null +++ b/Client/MessageHandler.cpp @@ -0,0 +1,52 @@ +/* + Niotso - Copyright (C) 2012 Fatbag + + 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 3 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, see . +*/ + +#include "EngineInterface.hpp" + +/**** + For the sake of performance **all throughout the game**, + order the cases in order from most frequently occurred to less frequently occurred + except making adjustments where tiny response latency is essential +*/ +LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch(uMsg) + { + case WM_SETCURSOR: //Occurs often + SetCursor(NULL); + break; + + case WM_SYSCOMMAND: //Occurs often + switch(wParam){ + case SC_MONITORPOWER: + case SC_SCREENSAVE: + return 0; + } + break; + + case WM_KEYDOWN: + case WM_KEYUP: + System::Keys[wParam] = (uMsg == WM_KEYDOWN); + return 0; + + case WM_CLOSE: + PostQuitMessage(0); + return 0; + } + + return DefWindowProc(hWnd, uMsg, wParam, lParam); +} \ No newline at end of file diff --git a/Client/System/System.cpp b/Client/System/System.cpp new file mode 100644 index 0000000..4dc0c19 --- /dev/null +++ b/Client/System/System.cpp @@ -0,0 +1,31 @@ +/* + Niotso - Copyright (C) 2012 Fatbag + + 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 3 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, see . +*/ + +#include "../EngineInterface.hpp" + +namespace System { + HINSTANCE hInst = NULL; + HANDLE Terminate; + HANDLE Process; + HANDLE ProcessHeap; + LARGE_INTEGER ClockFrequency; + bool Keys[256]; + + //Event objects + HANDLE Shutdown; + HANDLE Initialized[2], Terminated[2]; +} \ No newline at end of file diff --git a/Client/System/System.hpp b/Client/System/System.hpp new file mode 100644 index 0000000..f03761b --- /dev/null +++ b/Client/System/System.hpp @@ -0,0 +1,67 @@ +/* + Niotso - Copyright (C) 2012 Fatbag + + 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 3 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, see . +*/ + +//System/System.cpp +namespace System { + extern HINSTANCE hInst; + extern HANDLE Process; + extern HANDLE ProcessHeap; + extern LARGE_INTEGER ClockFrequency; + extern bool Keys[256]; + + //Event objects + extern HANDLE Shutdown; + extern HANDLE Initialized[2], Terminated[2]; +} + +enum { + HANDLE_GRAPHICS, + HANDLE_AUDIO +}; + +/**** +** Program exit codes +** (Return 0 for success) +*/ + +#define ERROR_INIT 0x1000 +#define ERROR_INIT_ANOTHERINSTRUNNING 0x1001 + +//Engine errors +//Use: return ERROR_INIT | result; +#define ERROR_INIT_WINDOW 0x0100 + enum { + ERROR_REGISTER_CLASS = 1, + ERROR_CREATE_WINDOW + }; +#define ERROR_INIT_GRAPHICS 0x0200 + enum { + ERROR_GRAPHICS_CREATE_THREAD = 1, + ERROR_GRAPHICS_OBTAIN_DC, + ERROR_GRAPHICS_FIND_PIXELFORMAT, + ERROR_GRAPHICS_SET_PIXELFORMAT, + ERROR_GRAPHICS_CREATE_GLRC, + ERROR_GRAPHICS_ACTIVATE_GLRC, + ERROR_GRAPHICS_INIT_GLSCENE + }; +#define ERROR_INIT_AUDIO 0x0300 + enum { + ERROR_AUDIO_INIT_COM = 1, + ERROR_AUDIO_INIT_XAUDIO2, + ERROR_AUDIO_CREATE_VOICE + }; +#define ERROR_INIT_LOGIC 0x0400 \ No newline at end of file diff --git a/Client/TODO b/Client/TODO index 0c49608..fc64ef7 100644 --- a/Client/TODO +++ b/Client/TODO @@ -3,4 +3,16 @@ alpha to beta), this file contains only the things that are worked on currently While anybody is free to work on _anything_ at any point during Niotso's time, this list shall ONLY contain those relevant to complete the criteria for the next development phase, which can be found here: - \ No newline at end of file + + +//----------// + +Development Phase: Planning + +Technical Preview 1 +Schedule: (Not very subject to change) + 1. Implement cst and uis parsers [40%] + 2. Replicate functionality up until the login dialog + 3. Implement the OpenGL-based windowing system + 4. Replicate character selection and creation features and the city selection dialog + 5. Implement the code needed to allow the game to read all necessary files from the TSOClient folder \ No newline at end of file diff --git a/Client/resources/Resource.h b/Client/resources/Resource.h new file mode 100644 index 0000000..04d4a13 --- /dev/null +++ b/Client/resources/Resource.h @@ -0,0 +1,2 @@ +#define ID_VERSIONINFO 1 +#define IDI_TSO 2 diff --git a/Client/resources/Resource.rc b/Client/resources/Resource.rc new file mode 100644 index 0000000..574970b --- /dev/null +++ b/Client/resources/Resource.rc @@ -0,0 +1,32 @@ +#include +#include "../version.h" +#include "Resource.h" + +IDI_TSO ICON "TSO.ico" + +ID_VERSIONINFO VERSIONINFO +FILEVERSION VERSION_A,VERSION_B,VERSION_C,VERSION_D +PRODUCTVERSION VERSION_A,VERSION_B,VERSION_C,VERSION_D +FILEOS 0x00040000L //Windows 32-bit+ +FILETYPE 1 //1 is exe, 2 is dll, and so on. + //The list can be found at +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" + BEGIN + VALUE "CompanyName", "Maxis™" + VALUE "FileDescription", "The Sims Online" + VALUE "FileVersion", VERSIONSTR + VALUE "InternalName", "TSO_NIOTSO" + VALUE "LegalCopyright", "Copyright © 2002-2005 Maxis™" + VALUE "OriginalFilename", "TSO.exe" + VALUE "ProductName", "The Sims Online" + VALUE "ProductVersion", VERSIONSTR + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 0x04B0 + END +END diff --git a/Client/resources/TSO.ico b/Client/resources/TSO.ico new file mode 100644 index 0000000..ee94659 Binary files /dev/null and b/Client/resources/TSO.ico differ diff --git a/Client/version.h b/Client/version.h new file mode 100644 index 0000000..27ce87a --- /dev/null +++ b/Client/version.h @@ -0,0 +1,10 @@ +#define VERSION_A 0 +#define VERSION_B 0 +#define VERSION_C 0 +#define VERSION_D 0 + +//You don't have to touch the following +#define xstr(x) str(x) +#define str(x) #x //Yes, double levels is required. See +#define VERSIONSTR "" \ + xstr(VERSION_A) "." xstr(VERSION_B) "." xstr(VERSION_C) "." xstr(VERSION_D) diff --git a/Libraries/FileHandler/CMakeLists.txt b/Libraries/FileHandler/CMakeLists.txt index ef35be8..27dbc36 100644 --- a/Libraries/FileHandler/CMakeLists.txt +++ b/Libraries/FileHandler/CMakeLists.txt @@ -17,6 +17,7 @@ set(FILEHANDLER_MINOR 0) set(FILEHANDLER_SOURCES File.cpp Image.cpp + cst/cst.c iff/chunks.c iff/iff.c ) diff --git a/Libraries/FileHandler/cst/cst.c b/Libraries/FileHandler/cst/cst.c new file mode 100644 index 0000000..3334308 --- /dev/null +++ b/Libraries/FileHandler/cst/cst.c @@ -0,0 +1,47 @@ +/* + cst.c - Copyright (c) 2012 Fatbag + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#include +#include +#include "cst.h" + +unsigned cst_count_strings(const char * Buffer, size_t FileSize){ + unsigned count = 0; + int instring = 0; + while(FileSize--){ + if(*Buffer == '^' && (instring = !instring) == 0) + count++; + Buffer++; + } + return count; +} + +int cst_read(CSTFile * CSTFileInfo, char * Buffer, size_t FileSize){ + CSTFileInfo->CSTData = Buffer; + CSTFileInfo->StringCount = cst_count_strings(Buffer, FileSize); + if(CSTFileInfo->StringCount != 0){ + unsigned i; + CSTFileInfo->Strings = malloc(CSTFileInfo->StringCount * sizeof(char *)); + if(CSTFileInfo->Strings == NULL) + return 0; + for(i=0; iStringCount; i++){ + CSTFileInfo->Strings[i] = Buffer = strchr(Buffer, '^') + 1; + *(Buffer = strchr(Buffer, '^')) = 0x00; + Buffer++; + } + } + return 1; +} \ No newline at end of file diff --git a/Libraries/FileHandler/cst/cst.h b/Libraries/FileHandler/cst/cst.h new file mode 100644 index 0000000..2305f92 --- /dev/null +++ b/Libraries/FileHandler/cst/cst.h @@ -0,0 +1,21 @@ +/* + cst.h - Copyright (c) 2012 Fatbag + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +typedef struct { + char * CSTData; + unsigned StringCount; + char ** Strings; +} CSTFile; \ No newline at end of file diff --git a/Libraries/FileHandler/iff/iffexport.c b/Libraries/FileHandler/iff/iffexport.c index 8dd485f..96a4a8f 100644 --- a/Libraries/FileHandler/iff/iffexport.c +++ b/Libraries/FileHandler/iff/iffexport.c @@ -32,7 +32,7 @@ int main(int argc, char *argv[]){ IFFChunkNode * ChunkNode; if(argc == 1 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")){ - printf("Usage: iffexport [-f] infile OutDirectory\n" + printf("Usage: iffexport [-f] infile outdirectory\n" "Export the resources of an EA IFF file.\n" "Use -f to force overwriting without confirmation.\n" "\n" diff --git a/Libraries/FileHandler/uis/uis.c b/Libraries/FileHandler/uis/uis.c new file mode 100644 index 0000000..7e88e4d --- /dev/null +++ b/Libraries/FileHandler/uis/uis.c @@ -0,0 +1,15 @@ +/* + uis.c - Copyright (c) 2012 Fatbag + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ \ No newline at end of file diff --git a/Libraries/FileHandler/uis/uis.h b/Libraries/FileHandler/uis/uis.h new file mode 100644 index 0000000..c686335 --- /dev/null +++ b/Libraries/FileHandler/uis/uis.h @@ -0,0 +1,32 @@ +/* + uis.h - Copyright (c) 2012 Fatbag + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +enum UISTagType { + UIS_Type_Button, + UIS_Type_FormattedText, + UIS_Type_ListBox, + UIS_Type_ProgressBar, + UIS_Type_Slider, + UIS_Type_Text, + UIS_Type_TextEdit, + UIS_Type_Image, + UIS_Type_String, + UIS_Type_Custom +}; + +typedef struct { + UISTagType TagType; +} UISTag; \ No newline at end of file diff --git a/Libraries/FileHandler/utk/read_utk.c b/Libraries/FileHandler/utk/read_utk.c index 14650cc..026d6c4 100644 --- a/Libraries/FileHandler/utk/read_utk.c +++ b/Libraries/FileHandler/utk/read_utk.c @@ -49,7 +49,7 @@ uint8_t UTKTable2[512]; const uint8_t UTKTable3[29] = {8,7,8,7,2,2,2,3,3,4,4,3,3,5,5,4,4,6,6,5,5,7,7,6,6,8,8,7,7}; float UTKTable4[29]; -int utk_read_header(utkheader_t * UTKHeader, const uint8_t * Buffer, unsigned FileSize) +int utk_read_header(utkheader_t * UTKHeader, const uint8_t * Buffer, size_t FileSize) { if(FileSize < 28) return 0; memcpy(&UTKHeader->sID, Buffer, 4); diff --git a/Libraries/libvitaboy/Renderer.cpp b/Libraries/libvitaboy/Renderer.cpp index 2dcfc1e..ef401ee 100644 --- a/Libraries/libvitaboy/Renderer.cpp +++ b/Libraries/libvitaboy/Renderer.cpp @@ -45,9 +45,9 @@ */ #include -#include -#include -#include +#include +#include +#include #include #include "libvitaboy.hpp" @@ -538,7 +538,7 @@ BOOL CreateGLWindow(const char * title, int width, int height, int bits, bool fu return false; } - if(!SetPixelFormat(hDC,PixelFormat, &pfd)){ + if(!SetPixelFormat(hDC, PixelFormat, &pfd)){ KillGLWindow(); MessageBox(NULL, "Can't set the PixelFormat.", NULL, MB_OK | MB_ICONERROR); return false; @@ -553,11 +553,11 @@ BOOL CreateGLWindow(const char * title, int width, int height, int bits, bool fu if(!wglMakeCurrent(hDC, hRC)){ KillGLWindow(); - MessageBox(NULL, "Failed to activate an OpenGL device context.", NULL, MB_OK | MB_ICONERROR); + MessageBox(NULL, "Failed to activate the OpenGL device context.", NULL, MB_OK | MB_ICONERROR); return false; } - ShowWindow(hWnd,SW_SHOW); + ShowWindow(hWnd, SW_SHOW); SetForegroundWindow(hWnd); SetFocus(hWnd); ResizeScene(width, height); diff --git a/Tools/FARDive/windows/Startup.cpp b/Tools/FARDive/windows/Startup.cpp index 14dafcc..f8e04de 100644 --- a/Tools/FARDive/windows/Startup.cpp +++ b/Tools/FARDive/windows/Startup.cpp @@ -16,7 +16,7 @@ wchar_t ArchiveOpenFilter[128] = L"", ArchiveAddFilter[128] = L"", ArchiveSaveFi HMENU hMenu, listmenu = 0; -int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int){ +int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int){ hInst = hInstance; WNDCLASS wc = { diff --git a/Tools/TSOSimulatorClient/TSOSimulatorClient.cpp b/Tools/TSOSimulatorClient/TSOSimulatorClient.cpp index 9785031..6bda85e 100644 --- a/Tools/TSOSimulatorClient/TSOSimulatorClient.cpp +++ b/Tools/TSOSimulatorClient/TSOSimulatorClient.cpp @@ -16,6 +16,7 @@ #include #include +#include "TSOSimulatorClient.hpp" int main(){ HMODULE dllmodule = LoadLibrary("TSOSimulatorClientD.dll"); @@ -24,15 +25,18 @@ int main(){ return -1; } - void * (__stdcall *GZDllGetGZCOMDirector)(void) = (void * (__stdcall *)(void)) GetProcAddress(dllmodule, "GZDllGetGZCOMDirector"); + GZCOMDirector * (__stdcall *GZDllGetGZCOMDirector)(void) = + (GZCOMDirector * (__stdcall *)(void)) GetProcAddress(dllmodule, "GZDllGetGZCOMDirector"); if(GZDllGetGZCOMDirector == NULL){ printf("TSOSimulatorClient: Error: Failed to find GZDllGetGZCOMDirector() in TSOSimulatorClientD.dll."); return -1; } printf("TSOSimulatorClient: Calling GZDllGetGZCOMDirector() ...\n"); - void * value = GZDllGetGZCOMDirector(); - printf("TSOSimulatorClient: Finished calling GZDllGetGZCOMDirector().\nThe value returned was: %p.\n", value); + GZCOMDirector * Simulator = GZDllGetGZCOMDirector(); + printf("TSOSimulatorClient: Finished calling GZDllGetGZCOMDirector().\nThe value returned was: %p.\n", (void *) Simulator); + + printf("%s\n%s\n%s\n", Simulator->Object1.Strings1[0], Simulator->Object1.Strings2[0], Simulator->Object1.Strings3[0]); printf("TSOSimulatorClient: Exiting.\n"); FreeLibrary(dllmodule); diff --git a/Tools/TSOSimulatorClient/TSOSimulatorClient.hpp b/Tools/TSOSimulatorClient/TSOSimulatorClient.hpp index 2d46b8a..58ff3a8 100644 --- a/Tools/TSOSimulatorClient/TSOSimulatorClient.hpp +++ b/Tools/TSOSimulatorClient/TSOSimulatorClient.hpp @@ -15,102 +15,52 @@ */ #include +#pragma pack(0) -DECLARE_INTERFACE(IMMDeviceCollection); -DECLARE_INTERFACE(IMMNotificationClient); -DECLARE_INTERFACE(IPropertyStore); - -/* -** IMMDevice -*/ - -DECLARE_INTERFACE_(IMMDevice, IUnknown) +DECLARE_INTERFACE(UnknownObject1_t) { - STDMETHOD(Activate) (REFIID iid, DWORD dwClsCtx, PROPVARIANT *pActivationParams, void **ppInterface); - STDMETHOD(OpenPropertyStore) (DWORD stgmAccess, IPropertyStore **ppProperties); - STDMETHOD(GetId) (LPWSTR *ppstrId); - STDMETHOD(GetState) (DWORD *pdwState); + DWORD Zero1; + DWORD Zero2; + void * vtable5; + char ** Strings1; + char ** Strings2; + char ** Strings3; + DWORD Zero3; + DWORD Zero4; + DWORD Zero5; + void ** Pointer1; //12 bytes + void ** Pointer2; //4 bytes + void ** Pointer3; + DWORD Flags; + DWORD * Pointer4; //4 bytes + void * Pointer5; + void * Pointer6; + DWORD Unknown11; + DWORD Unknown12; }; -/* -** IMMDeviceEnumerator -*/ - -enum EDataFlow +DECLARE_INTERFACE(GZCOMDirector) { - eRender, - eCapture, - eAll -}; - -enum ERole -{ - eConsole, - eMultimedia, - eCommunications -}; - -DECLARE_INTERFACE_(IMMDeviceEnumerator, IUnknown) -{ - STDMETHOD(EnumAudioEndpoints) (EDataFlow dataFlow, DWORD dwStateMask, IMMDeviceCollection **ppDevices); - STDMETHOD(GetDefaultAudioEndpoint) (EDataFlow dataFlow, ERole role, IMMDevice **ppEndpoint); - STDMETHOD(GetDevice) (LPCWSTR pwstrId, IMMDevice **ppDevice); - STDMETHOD(RegisterEndpointNotificationCallback) (IMMNotificationClient *pClient); - STDMETHOD(UnregisterEndpointNotificationCallback) (IMMNotificationClient *pClient); -}; - -/* -** IAudioClient -*/ - -enum AUDCLNT_SHAREMODE -{ - AUDCLNT_SHAREMODE_SHARED, - AUDCLNT_SHAREMODE_EXCLUSIVE -}; - -enum AUDCLNT_STREAMFLAGS -{ - AUDCLNT_STREAMFLAGS_CROSSPROCESS = 0x00010000, - AUDCLNT_STREAMFLAGS_LOOPBACK = 0x00020000, - AUDCLNT_STREAMFLAGS_EVENTCALLBACK = 0x00040000, - AUDCLNT_STREAMFLAGS_NOPERSIST = 0x00080000, - AUDCLNT_STREAMFLAGS_RATEADJUST = 0x00100000, - AUDCLNT_SESSIONFLAGS_EXPIREWHENUNOWNED = 0x10000000, - AUDCLNT_SESSIONFLAGS_DISPLAY_HIDE = 0x20000000, - AUDCLNT_SESSIONFLAGS_DISPLAY_HIDEWHENEXPIRED = 0x40000000 -}; - -DECLARE_INTERFACE_(IAudioClient, IUnknown) -{ - STDMETHOD(Initialize) (AUDCLNT_SHAREMODE ShareMode, DWORD StreamFlags, LONGLONG hnsBufferDuration, - LONGLONG hnsPeriodicity, const WAVEFORMATEX *pFormat, LPCGUID AudioSessionGuid); - STDMETHOD(GetBufferSize) (UINT32 *pNumBufferFrames); - STDMETHOD(GetStreamLatency) (LONGLONG *phnsLatency); - STDMETHOD(GetCurrentPadding) (UINT32 *pNumPaddingFrames); - STDMETHOD(IsFormatSupported) (AUDCLNT_SHAREMODE ShareMode, const WAVEFORMATEX *pFormat, WAVEFORMATEX **ppClosestMatch); - STDMETHOD(GetMixFormat) (WAVEFORMATEX **ppDeviceFormat); - STDMETHOD(GetDevicePeriod) (LONGLONG *phnsDefaultDevicePeriod, LONGLONG *phnsMinimumDevicePeriod); - STDMETHOD(Start) (void); - STDMETHOD(Stop) (void); - STDMETHOD(Reset) (void); - STDMETHOD(SetEventHandle) (HANDLE eventHandle); - STDMETHOD(GetService) (REFIID riid, void **ppv); -}; - -/* -** IAudioRenderClient -*/ - -enum AUDCLNT_BUFFERFLAGS -{ - AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY = 0x1, - AUDCLNT_BUFFERFLAGS_SILENT = 0x2, - AUDCLNT_BUFFERFLAGS_TIMESTAMP_ERROR = 0x4 -}; - -DECLARE_INTERFACE_(IAudioRenderClient, IUnknown) -{ - STDMETHOD(GetBuffer) (UINT32 NumFramesRequested, BYTE **ppData); - STDMETHOD(ReleaseBuffer) (UINT32 NumFramesWritten, DWORD dwFlags); + void * vtable2; + void * vtable1; + UnknownObject1_t Object1; + void * vtable4; + void * vtable3; + UnknownObject1_t Object2; + UnknownObject1_t Object3; + + DWORD Zero1; + DWORD Zero2; + DWORD Zero3; + DWORD Zero4; + DWORD Zero5; + DWORD Zero6; + DWORD Zero7; + DWORD Zero8; + DWORD Zero9; + DWORD Zero10; + DWORD Unknown1; + DWORD Pointer1; + DWORD Pointer2; + DWORD Zero11; }; \ No newline at end of file