 |
Cheat Engine The Official Site of Cheat Engine
|
| View previous topic :: View next topic |
| Author |
Message |
oib111 I post too much
Reputation: 0
Joined: 02 Apr 2007 Posts: 2947 Location: you wanna know why?
|
Posted: Tue Oct 09, 2007 8:29 am Post subject: OpenGL |
|
|
I got a very nice tutorial on it. And I'm getting all the drawing stuff. But I don't get this code just to make a simple window =.=" I get some of it because I know how to make regular windows in C++, but can anyone help me analyze. I mean the comments help but I still don't completely understand it.
| Code: |
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")
#pragma comment(lib, "glaux.lib")
#include "windows.h" // Header File For Windows
#include "gl\gl.h" // Header File For The OpenGL32 Library
#include "gl\glu.h" // Header File For The GLu32 Library
#include "gl\glaux.h" // Header File For The Glaux Library
HDC hDC=NULL; // Private GDI Device Context
HGLRC hRC=NULL; // Permanent Rendering Context
HWND hWnd=NULL; // Holds Our Window Handle
HINSTANCE hInstance; // Holds The Instance Of The Application
bool keys[256]; // Array Used For The Keyboard Routine
bool active=TRUE; // Window Active Flag Set To TRUE By Default
bool fullscreen=TRUE; // Set To Fullscreen Mode By Default
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc
GLvoid ReSizeGLScene(GLsizei width, GLsizei height)
{
if (height==0) // Prevent A Divide By Zero By
{
height=1; // Making Height Equal One
}
glViewport(0,0,width,height); // Reset The Current Viewport
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
// Calculate The Aspect Ratio Of The Window
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
}
int InitGL(GLvoid) // All Setup For OpenGL Goes Here
{
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
// Really Nice Perspective Calculations
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
return TRUE; // Initialization Went OK
}
int DrawGLScene(GLvoid) // Here's Where We Do All The Drawing
{
// Clear Screen And Depth Buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Reset The Current Modelview Matrix
glLoadIdentity();
// Place your code here!
return TRUE; // Keep Going
}
GLvoid KillGLWindow(GLvoid) // Properly Kill The Window
{
if (fullscreen) // Are We In Fullscreen Mode?
{
ChangeDisplaySettings(NULL,0); // witch Back To Desktop
ShowCursor(TRUE); // Show Mouse Pointer
if (hRC) // Do We Have A Rendering Context?
{
if (!wglMakeCurrent(NULL,NULL)) // Able To Release DC And RC?
{
MessageBox(NULL,"Release Of DC And RC Failed.",
"SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
}
if (!wglDeleteContext(hRC)) // Able To Delete The RC?
{
MessageBox(NULL,"Release Rendering Context Failed.",
"SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
}
hRC=NULL; // Set RC To NULL
}
if (hDC && !ReleaseDC(hWnd,hDC)) // Are We Able To Release The DC
{
MessageBox(NULL,"Release Device Context Failed.",
"SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hDC=NULL; // Set DC To NULL
}
if (hWnd && !DestroyWindow(hWnd)) // Able To Destroy The Window?
{
MessageBox(NULL,"Could Not Release hWnd.",
"SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hWnd=NULL; // Set hWnd To NULL
}
if (!UnregisterClass("OpenGL",hInstance))// Able To Unregister Class?
{
MessageBox(NULL,"Could Not Unregister Class.",
"SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hInstance=NULL; // Set hInstance To NULL
}
}
BOOL CreateGLWindow(char* title, int width, int height,
int bits, bool fullscreenflag)
{
// First some standard Win32 window creating
GLuint PixelFormat;
WNDCLASS wc;
DWORD dwExStyle;
DWORD dwStyle;
RECT WindowRect;
WindowRect.left=(long)0;
WindowRect.right=(long)width;
WindowRect.top=(long)0;
WindowRect.bottom=(long)height;
// fullscreen variable
fullscreen=fullscreenflag;
hInstance = GetModuleHandle(NULL);
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = "OpenGL";
// Register the window class
if (!RegisterClass(&wc))
{
MessageBox(NULL,"Failed To Register The Window Class.",
"ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
// If fullscreen flag is set
if (fullscreen)
{
DEVMODE dmScreenSettings;
memset(&dmScreenSettings,0,sizeof(dmScreenSettings));
dmScreenSettings.dmSize=sizeof(dmScreenSettings);
dmScreenSettings.dmPelsWidth = width;
dmScreenSettings.dmPelsHeight = height;
dmScreenSettings.dmBitsPerPel = bits;
dmScreenSettings.dmFields=DM_BITSPERPEL|
DM_PELSWIDTH | DM_PELSHEIGHT;
// Try To Set Selected Mode And Get Results.
if (ChangeDisplaySettings(&dmScreenSettings,
CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
{
if (MessageBox(NULL,"The Requested
Fullscreen Mode Is Not Supported
By\nYour Video Card. Use Windowed
Mode Instead?",
"OPENGL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
{
fullscreen=FALSE;
}
else
{
MessageBox(NULL,"Program Will Now Close.",
"ERROR",MB_OK|MB_ICONSTOP);
return FALSE;
}
}
}
if (fullscreen)
{
dwExStyle=WS_EX_APPWINDOW;
dwStyle=WS_POPUP;
ShowCursor(FALSE);
}
else
{
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
dwStyle=WS_OVERLAPPEDWINDOW;
}
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);
// Create The Window
if (!(hWnd=CreateWindowEx( dwExStyle,
"OpenGL",
title,
dwStyle |
WS_CLIPSIBLINGS |
WS_CLIPCHILDREN,
0, 0,
WindowRect.right-WindowRect.left,
WindowRect.bottom-WindowRect.top,
NULL,
NULL,
hInstance,
NULL)))
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Window Creation Error.",
"ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
// Tell the window how we want things to be..
static PIXELFORMATDESCRIPTOR pfd=
{
sizeof(PIXELFORMATDESCRIPTOR),
1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_DOUBLEBUFFER, // Double Buffering
PFD_TYPE_RGBA, // Request An RGBA Format
bits, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored
0, // No Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
16, // 16Bit Z-Buffer (Depth Buffer)
0, // No Stencil Buffer
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 // Layer Masks Ignored
};
// Did We Get A Device Context?
if (!(hDC=GetDC(hWnd)))
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Can't Create A GL Device Context.",
"ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
// Did Windows Find A Matching Pixel Format?
if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd)))
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Can't Find A Suitable PixelFormat.",
"ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
// Are We Able To Set The Pixel Format?
if(!SetPixelFormat(hDC,PixelFormat,&pfd))
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Can't Set The PixelFormat.",
"ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
// Are We Able To Get A Rendering Context?
if (!(hRC=wglCreateContext(hDC)))
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Can't Create A GL Rendering Context.",
"ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
// Try To Activate The Rendering Context
if(!wglMakeCurrent(hDC,hRC))
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Can't Activate The GL Rendering Context.",
"ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
ShowWindow(hWnd,SW_SHOW); // Show The Window
SetForegroundWindow(hWnd); // Slightly Higher Priority
SetFocus(hWnd); // Sets Focus To The Window
ReSizeGLScene(width, height); // Set Up Our Perspective GL Screen
// Initialize Our Newly Created GL Window
if (!InitGL())
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Initialization Failed.",
"ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
return TRUE; // Success
}
LRESULT CALLBACK WndProc( HWND hWnd, // Handle For This Window
UINT uMsg, // Message For This Window
WPARAM wParam, // Additional Message Information
LPARAM lParam) // Additional Message Information
{
switch (uMsg) // Check For Windows Messages
{
case WM_ACTIVATE: // Watch For Window Activate Message
{
if (!HIWORD(wParam))// Check Minimization State
active=TRUE;// Program Is Active
}
else
{
active=FALSE;// Program Is No Longer Active
}
return 0; // Return To The Message Loop
}
case WM_SYSCOMMAND: // Intercept System Commands
{
switch (wParam) // Check System Calls
{
// Screensaver Trying To Start?
case SC_SCREENSAVE:
// Monitor Trying To Enter Powersave?
case SC_MONITORPOWER:
return 0; // Prevent From Happening
}
break; // Exit
}
case WM_CLOSE: // Did We Receive A Close Message?
{
PostQuitMessage(0);// Send A Quit Message
return 0; // Jump Back
}
case WM_KEYDOWN: // Is A Key Being Held Down?
{
keys[wParam] = TRUE;// If So, Mark It As TRUE
return 0; // Jump Back
}
case WM_KEYUP: // Has A Key Been Released?
{
keys[wParam] = FALSE;// If So, Mark It As FALSE
return 0; // Jump Back
}
case WM_SIZE: // Resize The OpenGL Window
{
// LoWord=Width, HiWord=Height
ReSizeGLScene(LOWORD(lParam),HIWORD(lParam));
return 0; // Jump Back
}
}
// Pass All Unhandled Messages To DefWindowProc
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
int WINAPI WinMain( HINSTANCE hInstance, // Instance
HINSTANCE hPrevInstance, // Previous Instance
LPSTR lpCmdLine, // Command Line Parameters
int nCmdShow) // Window Show State
{
MSG msg; // Windows Message Structure
BOOL done=FALSE; // Bool Variable To Exit Loop
// Ask The User Which Screen Mode They Prefer
if (MessageBox(NULL,"Would You Like To Run In Fullscreen Mode?",
"Start FullScreen?",MB_YESNO|MB_ICONQUESTION)==IDNO)
{
fullscreen=FALSE; // Windowed Mode
}
// Create Our OpenGL Window
if (!CreateGLWindow("APRON TUTORIALS",640,480,16,fullscreen))
{
return 0; // Quit If Window Was Not Created
}
while(!done) // Loop That Runs While done=FALSE
{
// Is There A Message Waiting?
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
// Have We Received A Quit Message?
if (msg.message==WM_QUIT)
{
done=TRUE;// If So done=TRUE
}
else // If Not, Deal With Window Messages
{
// Translate The Message
TranslateMessage(&msg);
// Dispatch The Message
DispatchMessage(&msg);
}
}
else // If There Are No Messages
{
// Draw The Scene.
// Active? Was There A Quit Received?
if ((active && !DrawGLScene()) || keys[VK_ESCAPE])
{
// ESC or DrawGLScene Signalled A Quit
done=TRUE;
}
else // Not Time To Quit, Update Screen
{
// Swap Buffers (Double Buffering)
SwapBuffers(hDC);
}
if (keys[VK_F1]) // Is F1 Being Pressed?
{
keys[VK_F1]=FALSE;// If So Make Key FALSE
KillGLWindow(); // Kill Our Current Window
// Toggle Fullscreen / Windowed Mode
fullscreen=!fullscreen;
// Recreate Our OpenGL Window
if (!CreateGLWindow("APRON TUTORIALS",
640,480,16,fullscreen))
{
// Quit If Window Was Not Created
return 0;
}
}
}
}
// Shutdown
KillGLWindow(); // Kill The Window
return (msg.wParam); // Exit The Program
}
|
_________________
| 8D wrote: |
cigs dont make people high, which weed does, which causes them to do bad stuff. like killing |
Last edited by oib111 on Tue Oct 09, 2007 4:09 pm; edited 1 time in total |
|
| Back to top |
|
 |
Noz3001 I'm a spammer
Reputation: 26
Joined: 29 May 2006 Posts: 6220 Location: /dev/null
|
Posted: Tue Oct 09, 2007 10:22 am Post subject: |
|
|
| Link to tut please
|
|
| Back to top |
|
 |
hcavolsdsadgadsg I'm a spammer
Reputation: 26
Joined: 11 Jun 2007 Posts: 5801
|
|
| Back to top |
|
 |
oib111 I post too much
Reputation: 0
Joined: 02 Apr 2007 Posts: 2947 Location: you wanna know why?
|
Posted: Tue Oct 09, 2007 4:10 pm Post subject: |
|
|
| noz3001 wrote: | | Link to tut please |
http://www.morrowland.com/apron/tutorials/gl/gl_window.php
And I like these tutorials, but if they get too copmlicated and I can't understand them I'll switch to that site.
_________________
| 8D wrote: |
cigs dont make people high, which weed does, which causes them to do bad stuff. like killing |
|
|
| Back to top |
|
 |
TerryDonahugh Master Cheater
Reputation: 0
Joined: 12 Sep 2007 Posts: 412 Location: .nl
|
Posted: Tue Oct 09, 2007 4:38 pm Post subject: |
|
|
| Just let libSDL create your GL context. Only takes 2 or 3 lines of code.
|
|
| Back to top |
|
 |
oib111 I post too much
Reputation: 0
Joined: 02 Apr 2007 Posts: 2947 Location: you wanna know why?
|
Posted: Tue Oct 09, 2007 8:08 pm Post subject: |
|
|
libSDL? What is that? And would you care to show those lines of code?
_________________
| 8D wrote: |
cigs dont make people high, which weed does, which causes them to do bad stuff. like killing |
|
|
| Back to top |
|
 |
atom0s Moderator
Reputation: 205
Joined: 25 Jan 2006 Posts: 8587 Location: 127.0.0.1
|
Posted: Tue Oct 09, 2007 10:47 pm Post subject: |
|
|
libSDL can be found here: http://www.libsdl.org/
Description from their site:
| Quote: |
Simple DirectMedia Layer is a cross-platform multimedia library designed to provide low level access to audio, keyboard, mouse, joystick, 3D hardware via OpenGL, and 2D video framebuffer. It is used by MPEG playback software, emulators, and many popular games, including the award winning Linux port of "Civilization: Call To Power."
SDL supports Linux, Windows, Windows CE, BeOS, MacOS, Mac OS X, FreeBSD, NetBSD, OpenBSD, BSD/OS, Solaris, IRIX, and QNX. The code contains support for AmigaOS, Dreamcast, Atari, AIX, OSF/Tru64, RISC OS, SymbianOS, and OS/2, but these are not officially supported.
SDL is written in C, but works with C++ natively, and has bindings to several other languages, including Ada, C#, Eiffel, Erlang, Euphoria, Guile, Haskell, Java, Lisp, Lua, ML, Objective C, Pascal, Perl, PHP, Pike, Pliant, Python, Ruby, and Smalltalk.
SDL is distributed under GNU LGPL version 2. This license allows you to use SDL freely in commercial programs as long as you link with the dynamic library. |
Some SDL tutorials:
http://lazyfoo.net/SDL_tutorials/index.php
SDL+OGL: http://lazyfoo.net/SDL_tutorials/lesson36/index.php
|
|
| Back to top |
|
 |
oib111 I post too much
Reputation: 0
Joined: 02 Apr 2007 Posts: 2947 Location: you wanna know why?
|
Posted: Fri Oct 12, 2007 11:45 pm Post subject: |
|
|
| TerryDonahugh wrote: | | Just let libSDL create your GL context. Only takes 2 or 3 lines of code. |
Only 3 lines of code T.T And thats just to load a hello world image on a blit background T.T
| Code: |
/*This source code copyrighted by Lazy Foo' Productions (2004-2007) and may not be redestributed without written permission.*/
//The headers
#include "SDL/SDL.h"
#include <string>
//The attributes of the screen
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;
//The surfaces that will be used
SDL_Surface *message = NULL;
SDL_Surface *background = NULL;
SDL_Surface *screen = NULL;
SDL_Surface *load_image( std::string filename )
{
//Temporary storage for the image that's loaded
SDL_Surface* loadedImage = NULL;
//The optimized image that will be used
SDL_Surface* optimizedImage = NULL;
//Load the image
loadedImage = SDL_LoadBMP( filename.c_str() );
//If nothing went wrong in loading the image
if( loadedImage != NULL )
{
//Create an optimized image
optimizedImage = SDL_DisplayFormat( loadedImage );
//Free the old image
SDL_FreeSurface( loadedImage );
}
//Return the optimized image
return optimizedImage;
}
void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination )
{
//Make a temporary rectangle to hold the offsets
SDL_Rect offset;
//Give the offsets to the rectangle
offset.x = x;
offset.y = y;
//Blit the surface
SDL_BlitSurface( source, NULL, destination, &offset );
}
int main( int argc, char* args[] )
{
//Initialize all SDL subsystems
if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
{
return 1;
}
//Set up the screen
screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );
//If there was an error in setting up the screen
if( screen == NULL )
{
return 1;
}
//Set the window caption
SDL_WM_SetCaption( "Hello World", NULL );
//Load the images
message = load_image( "hello_world.bmp" );
background = load_image( "background.bmp" );
//Apply the background to the screen
apply_surface( 0, 0, background, screen );
//Apply the message to the screen
apply_surface( 180, 140, message, screen );
//Update the screen
if( SDL_Flip( screen ) == -1 )
{
return 1;
}
//Wait 2 seconds
SDL_Delay( 2000 );
//Free the surfaces
SDL_FreeSurface( message );
SDL_FreeSurface( background );
//Quit SDL
SDL_Quit();
return 0;
}
|
_________________
| 8D wrote: |
cigs dont make people high, which weed does, which causes them to do bad stuff. like killing |
|
|
| Back to top |
|
 |
Symbol I'm a spammer
Reputation: 0
Joined: 18 Apr 2007 Posts: 5094 Location: Israel.
|
Posted: Sat Oct 13, 2007 1:07 am Post subject: |
|
|
Such a long script just to make a form?
Use Visual C++, it makes it all automaticlly+auto xpmainfest+toolbox and easy to use, you don't have to write hundreds of code lines just to make a form...
|
|
| Back to top |
|
 |
oib111 I post too much
Reputation: 0
Joined: 02 Apr 2007 Posts: 2947 Location: you wanna know why?
|
Posted: Sat Oct 13, 2007 8:36 am Post subject: |
|
|
Symbol I must laugh at you *laughs* Anyway this is libSDL which is kind of like OpenGL. And as far as I know there are no compilers that automatically generate your SDL/OpenGL/DirectX code. But when I think about it. This is probably less code then it would have been for OpenGL.
_________________
| 8D wrote: |
cigs dont make people high, which weed does, which causes them to do bad stuff. like killing |
|
|
| Back to top |
|
 |
TerryDonahugh Master Cheater
Reputation: 0
Joined: 12 Sep 2007 Posts: 412 Location: .nl
|
Posted: Sat Oct 13, 2007 9:19 am Post subject: |
|
|
| oib111 wrote: | | TerryDonahugh wrote: | | Just let libSDL create your GL context. Only takes 2 or 3 lines of code. |
Only 3 lines of code T.T And thats just to load a hello world image on a blit background T.T
| Code: |
/*This source code copyrighted by Lazy Foo' Productions (2004-2007) and may not be redestributed without written permission.*/
[...]
return 0;
}
|
|
The code you pasted there is not using opengl.
This is what a very simple program that initializes a gl-context and clears the background to green looks like:
| Code: |
// include sdl and opengl headerfiles here
int main() {
SDL_Init(SDL_INIT_VIDEO);
// I think the default GL attribute values suffice, but just to be sure.
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_Surface *screen = 0;
if ((screen=SDL_SetVideoMode( 1024, 768, 0, SDL_OPENGL)) == 0) {
SDL_Quit();
return 1;
}
// do the actual rendering here instead of this :)
glClearColor(1,0,0,0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
SDL_GL_SwapBuffers();
SDL_Quit();
return 0;
}
|
|
|
| Back to top |
|
 |
oib111 I post too much
Reputation: 0
Joined: 02 Apr 2007 Posts: 2947 Location: you wanna know why?
|
Posted: Sat Oct 13, 2007 10:12 am Post subject: |
|
|
oh you meant SDL+GL?
_________________
| 8D wrote: |
cigs dont make people high, which weed does, which causes them to do bad stuff. like killing |
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
|
|