
Jag har spenderat en del tid på sistone med att städa upp, refaktorisera och dokumentera min spelmotor Pixie, och bestämde mig för att bryta ut den del som behandlar plattformsabstraktion, så att de som är intresserade kan titta efter hur jag löst saker eller använda det om man har behov. Jag tar givetvis gärna emot synpunkter, kritik och förslag till förbättringar också. Koden är som vanligt public domain, så använd som du vill om du vill
Kan laddas ned hära: PixeLite v 1.0
Systemen använder grundläggande windowsfunktioner för input/time och filhantering, men använder DirectX för ljud och bild. Om inte directx i rätt version finns tillgänglig, faller den tillbaka på standard GDI eller WMM funktionalitet, så det är ett väldigt stabilt system, som hittills verkar funka på allt, från såväl gamla till nya windows-versioner och även under VM's och Wine på linux.
Grundidén är att man initierar systemen i sin Main-funktion såhär:
- // Win32 Platform Includes
- #include "Win32/Platform_Win32_OS.h"
- #include "Win32/Platform_Win32_Time.h"
- #include "Win32/Platform_Win32_Sound.h"
- #include "Win32/Platform_Win32_Input.h"
- #include "Win32/Platform_Win32_Screen.h"
- #include "Win32/Platform_Win32_FileSystem.h"
- //*** WinMain ***
- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
- {
- // Platform abstraction systems - This is where we choose which platform components we want to use
- Platform_Win32_OS* os=new Platform_Win32_OS(hInstance,lpCmdLine);
- Platform::SetPlatform_OS(os);
- Platform::SetPlatform_Time(new Platform_Win32_Time());
- Platform::SetPlatform_Sound(new Platform_Win32_Sound(os));
- Platform::SetPlatform_Input(new Platform_Win32_Input(os));
- Platform::SetPlatform_Screen(new Platform_Win32_Screen(os));
- Platform::SetPlatform_FileSystem(new Platform_Win32_FileSystem());
- // Start the game
- RunGame();
- return 0;
- }
Och sen implementerar resten av sitt spel i RunGame-funktionen. Main-funktionen ser ju lite olika ut beroende på plattform, men för närvarande stöds bara Windows (men så fort jag får råd med en Mac, eller hjälp av en vänlig själ, så blir det stöd för OsX också, och ev. är det en linux-version på väg. eller det var det iallafall, men tror han som höll på med den tröttnade
Egentligen är det ju tänkt att man ska använda de här systemen som en grund att bygga mer användarvänliga system på, så som jag gjort i min Pixie motor, men det går ju att använda direkt också, och tänkte att det nog är lättare att porta om man har ett mer hanterbar mängd kod i projektet.
Jag har gjort en liten test-demo grej som är med i nedladdningen, och som producerar en massa studsande bollar på ful bakgrund:

och koden för det ser ut så här:
- //*** Demo.cpp ***
- // A simple demo to show how to use the PixieLite platform system.
- // In reality, all the platform stuff would be wrapped up in higher
- // level functionality, making it easier and more convenient to use.
- // The Pixie Game Engine provides excellent high level functionality
- // built on top of this platform abstraction system.
- #include "Platform_OS.h"
- #include "Platform_Screen.h"
- #include "Platform_Time.h"
- #include "Platform_Input.h"
- #include "Platform_Input_KeyboardDevice.h"
- // Simple random number generator
- int GetRandomNumber()
- {
- // Seed value
- static long a = (int)(Platform::GetPlatform_Time()->GetTime()*1000);
- // Update number
- a=(a*32719+3)%32749;
- return a;
- }
- void RunDemo()
- {
- // Create our backbuffer, which all drawing will be done to
- unsigned short backbuffer[400*300];
- // Create a simple background with ugly gradient
- unsigned short background[400*300];
- for (int i=0; i<400*300; i++)
- {
- background[i]=(unsigned short)(2+i/4000+((i%400)/7)*32);
- }
- // Define a simple and ugly "ball" sprite
- unsigned short ball[] =
- {
- 0,0,0,1,1,0,0,0,
- 0,1,1,1,1,1,1,0,
- 0,1,1,1,1,1,1,0,
- 1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,
- 0,1,1,1,1,1,1,0,
- 0,1,1,1,1,1,1,0,
- 0,0,0,1,1,0,0,0,
- };
- // Define some variables to track ball position/directions
- const int ballCount=20;
- int posX[ballCount];
- int posY[ballCount];
- int dirX[ballCount];
- int dirY[ballCount];
- // Set initial ball values
- for (int i=0; i<ballCount; i++)
- {
- posX[i]=GetRandomNumber()%392;
- posY[i]=GetRandomNumber()%292;
- dirX[i]=GetRandomNumber()%2;
- if (!dirX[i])
- {
- dirX[i]=-1;
- }
- dirY[i]=GetRandomNumber()%2;
- if (!dirY[i])
- {
- dirY[i]=-1;
- }
- }
- // Flag to keep track of when to exit
- bool running=true;
- // Main loop
- while (running)
- {
- // Copy background to backbuffer
- for (int i=0; i<400*300; i++)
- {
- backbuffer[i]=background[i];
- }
- // Display a few bouncing balls
- for (int i=0; i<ballCount; i++)
- {
- // Draw ball
- for (int y=0; y<8; y++)
- {
- for (int x=0; x<8; x++)
- {
- if (ball[x+y*8])
- {
- backbuffer[(posX[i]+x)+(posY[i]+y)*400]=0xffff;
- }
- }
- }
- // Update X position, bouncing if necessary
- posX[i]+=dirX[i];
- if (posX[i]<0 )
- {
- posX[i]=0;
- dirX[i]=1;
- }
- if (posX[i]>391 )
- {
- posX[i]=391;
- dirX[i]=-1;
- }
- // Update Y position, bouncing if necessary
- posY[i]+=dirY[i];
- if (posY[i]<0 )
- {
- posY[i]=0;
- dirY[i]=1;
- }
- if (posY[i]>291 )
- {
- posY[i]=291;
- dirY[i]=-1;
- }
- }
- // Show backbuffer on the screen
- Platform::GetPlatform_Screen()->Present(backbuffer,400,300);
- // Check if ESCAPE was pressed
- if (Platform::GetPlatform_Input()->GetKeyboardDevice()->IsKeyDown(Platform_Input_KeyboardDevice::KEY_ESCAPE))
- {
- running=false; // Stop running the demo
- }
- // Check if the user closed the window
- if (Platform::GetPlatform_OS()->ExitRequested())
- {
- running=false; // Stop running the demo
- }
- // Allow for OS-specific processing (windows message pump etc)
- Platform::GetPlatform_OS()->OsYield();
- }
- }
