From 8bb608d5ceceea1b25b24f816965a88bced2482c Mon Sep 17 00:00:00 2001 From: Fatbag Date: Sun, 18 Mar 2012 23:06:08 -0500 Subject: [PATCH] Fully functional cst parser. New client code for Windows. The window does not appear until the OpenGL rendering context has completely initialized and (one day) has the first frame ready to draw. --- Client/Audio/Audio.hpp | 23 +++ Client/Audio/Startup.cpp | 74 ++++++++ Client/CHANGES | 3 +- Client/CMakeLists.txt | 16 ++ Client/Client.cpp | 173 ++++++++++++++++++ Client/EngineInterface.hpp | 41 +++++ Client/Graphics/Graphics.hpp | 30 +++ Client/Graphics/Startup.cpp | 127 +++++++++++++ Client/Graphics/Viewport.cpp | 29 +++ Client/MessageHandler.cpp | 52 ++++++ Client/System/System.cpp | 31 ++++ Client/System/System.hpp | 67 +++++++ Client/TODO | 14 +- Client/resources/Resource.h | 2 + Client/resources/Resource.rc | 32 ++++ Client/resources/TSO.ico | Bin 0 -> 62118 bytes Client/version.h | 10 + Libraries/FileHandler/CMakeLists.txt | 1 + Libraries/FileHandler/cst/cst.c | 47 +++++ Libraries/FileHandler/cst/cst.h | 21 +++ Libraries/FileHandler/iff/iffexport.c | 2 +- Libraries/FileHandler/uis/uis.c | 15 ++ Libraries/FileHandler/uis/uis.h | 32 ++++ Libraries/FileHandler/utk/read_utk.c | 2 +- Libraries/libvitaboy/Renderer.cpp | 12 +- Tools/FARDive/windows/Startup.cpp | 2 +- .../TSOSimulatorClient/TSOSimulatorClient.cpp | 10 +- .../TSOSimulatorClient/TSOSimulatorClient.hpp | 136 +++++--------- 28 files changed, 897 insertions(+), 107 deletions(-) create mode 100644 Client/Audio/Startup.cpp create mode 100644 Client/EngineInterface.hpp create mode 100644 Client/Graphics/Startup.cpp create mode 100644 Client/Graphics/Viewport.cpp create mode 100644 Client/MessageHandler.cpp create mode 100644 Client/System/System.cpp create mode 100644 Client/System/System.hpp create mode 100644 Client/resources/Resource.h create mode 100644 Client/resources/Resource.rc create mode 100644 Client/resources/TSO.ico create mode 100644 Client/version.h create mode 100644 Libraries/FileHandler/cst/cst.c create mode 100644 Libraries/FileHandler/cst/cst.h create mode 100644 Libraries/FileHandler/uis/uis.c create mode 100644 Libraries/FileHandler/uis/uis.h 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 0000000000000000000000000000000000000000..ee94659a35dd739b4f21c9c5cdcc151e96c6ab79 GIT binary patch literal 62118 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 literal 0 HcmV?d00001 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