Public feed #381719

Mine

public cpp v1 · immutable
Raw Edit
·published 2007-03-05 00:59 UTC
rendered paste body
/*************************************************************************** *   Copyright (C) 2007 by Cyle Riggs   * *   cyleriggs@gmail.com   * *                                                                         * *   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 2 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, write to the                         * *   Free Software Foundation, Inc.,                                       * *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             * ***************************************************************************/#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <iostream>#include <cstdlib>#include <map>#include <vector>#include <SDL.h>#include <SDL_image.h>#include <SDL_thread.h>#include <GL/gl.h>#include <GL/glu.h>#define WINDOW_WIDTH 1280#define WINDOW_HEIGHT 1024#define TARGET_FPS 24using namespace std;class CSDLError {	public:			CSDLError( string doingWhat ) {			cerr << "SDL error while "+doingWhat+": " << SDL_GetError() << endl;			SDL_Quit();		}};class CShot {	public:		CShot( float x ) {			CShot::x = x;			framesDrawn = 0;			y = -1.0;		}				~CShot() {		}				void draw() {			glLoadIdentity();			glBegin( GL_LINES );			glVertex3f( x, y, -0.1 );			glVertex3f( x, y+0.1, -0.1 );			glEnd();		}				float move( float amount ) {			y += amount;			return y;		}				static int sdlThread( void* obj ) {			CShot* shot = reinterpret_cast<CShot*>(obj);			shot->move( 0.1 );		}				float x;		float y;		unsigned long framesDrawn;				static SDL_mutex* instanceMutex;		static vector<CShot*> instances;};SDL_mutex* CShot::instanceMutex = NULL;vector<CShot*> CShot::instances;//Global variablesGLfloat mousex = 0;GLfloat mousey = 0;void DrawImage(SDL_Surface *srcimg, int sx, int sy, int sw, int sh, SDL_Surface *dstimg, int dx, int dy, int alpha = 255) {  if ((srcimg == NULL) || (alpha == 0)) return; //If theres no image, or its 100% transparent.  SDL_Rect src, dst;    src.x = sx;  src.y = sy;  src.w = sw;  src.h = sh;  dst.x = dx;  dst.y = dy;  dst.w = src.w;  dst.h = src.h;  if (alpha != 255) SDL_SetAlpha(srcimg, SDL_SRCALPHA, alpha);  SDL_BlitSurface(srcimg, &src, dstimg, &dst);}void drawOutline() {	glLoadIdentity();	glBegin( GL_LINES );	glColor3f( 0, 0.9, 0 );		//Horizontal line	glVertex3f( -1.0, 0, 0 );	glVertex3f( 1.0, 0, 0 );		//Vertical line	glVertex3f( 0, 1.0, 0 );	glVertex3f( 0, -1.0, 0 );		float lineLength = 0.015;	for( float x = -1.0; x<1.0; x += 0.05 ) {		glVertex3f( x, lineLength, 0 );		glVertex3f( x, -lineLength, 0 );	}		for( float y = -1.0; y<1.0; y+= 0.05 ) {		glVertex3f( lineLength, y, 0 );		glVertex3f( -lineLength, y, 0 );	}		glEnd();}void drawCursor() {	static float rotX = 0;	static float rotY = 0;	static float rotZ = 0;	static const float cursorDiameter = 0.05;	// 	rotX -= 0.4;// 	rotY += 0.1;// 	rotZ += 0.2;		glLoadIdentity();	glTranslatef( mousex, mousey, 0 );	// 	glRotatef( rotX, 1.0f, 0, 0 );// 	glRotatef( rotY, 0, 1.0f, 0 );// 	glRotatef( rotZ, 0, 0, 1.0f );		glBegin( GL_LINES );	glColor3f( 1.0, 1.0, 1.0 );	glVertex3f( -cursorDiameter, 0, 0 );	glVertex3f( cursorDiameter, 0, 0 );	glVertex3f( 0, -cursorDiameter, 0 );	glVertex3f( 0, cursorDiameter, 0 );	glVertex3f( 0, 0, -cursorDiameter );	glVertex3f( 0, 0, cursorDiameter );	glEnd();}void drawShots() {	SDL_mutexP( CShot::instanceMutex );		for( vector<CShot*>::iterator it = CShot::instances.begin(); it != CShot::instances.end(); it++ ) {		if( (*it) == NULL ) {			continue;		}				(*it)->draw();		(*it)->framesDrawn++;	}		SDL_mutexV( CShot::instanceMutex );}void drawFrame() { 	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );		drawOutline();	drawCursor();	drawShots();	//Done drawing	SDL_GL_SwapBuffers();	return;}int drawThreadFn(void*) {	int frameStart = 0;	int frameEnd = 0;	int waitTime = 0;	const int frameLength = (1000/TARGET_FPS);	while( true ) {		frameStart = SDL_GetTicks();		drawFrame();		frameEnd = SDL_GetTicks();				waitTime = frameLength - (frameEnd-frameStart);				if( waitTime > 0 ) {			SDL_Delay(waitTime);		}	}}int eventThreadFn(void*) {	mousex = mousey = 0;		SDL_Event event;	while( SDL_WaitEvent(&event) >= 0 ) {		switch( event.type ) {			case SDL_QUIT:				return 0;				break;							case SDL_MOUSEBUTTONDOWN:				cout << "Button down!" << endl;// 				if( event.button.state == SDL_RELEASED ) {					cout << "Created shot!" << endl;										SDL_mutexP( CShot::instanceMutex );					CShot::instances.push_back( new CShot(mousex) );					SDL_mutexV( CShot::instanceMutex );					// 				}				break;							case SDL_MOUSEMOTION:				mousex = ((event.motion.x-(WINDOW_WIDTH/2))*(float)(2.0/(float)WINDOW_WIDTH));				mousey = -((event.motion.y-(WINDOW_HEIGHT/2))*(float)(2.0/(float)WINDOW_HEIGHT));				break;		}	}	}int moveShotsThreadFn(void* obj) {	while(true) {			SDL_mutexP( CShot::instanceMutex );				for( vector<CShot*>::iterator it = CShot::instances.begin(); it != CShot::instances.end(); it++ ) {			if( (*it) == NULL ) {				cerr << "skipping null shot pointer" << endl;				continue;			}						if( (*it)->framesDrawn > 0 && (*it)->move(0.1) >= 1.0 ) {				cerr << "deleting shot" << endl;				delete (*it);				cerr << "nullifying shot" << endl;				(*it) = NULL;			}		}				cerr << "# of shots = " << CShot::instances.size() << endl;				SDL_mutexV( CShot::instanceMutex );				SDL_Delay( 1000/50 );	}}void initGL() {	glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );	glHint( GL_LINE_SMOOTH_HINT, GL_NICEST );	glEnable( GL_DEPTH_TEST );	return;}int main(int argc, char *argv[]){		SDL_Surface *screen = NULL;	CShot::instanceMutex = SDL_CreateMutex();		cout <<"Initializing SDL." << endl;	if(SDL_Init(SDL_INIT_VIDEO)< 0) { CSDLError( "Initializing SDL" ); }		SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );    SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );    SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );    SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );	screen = SDL_SetVideoMode(WINDOW_WIDTH,WINDOW_HEIGHT,16,SDL_OPENGL);	if( screen == NULL ) { CSDLError( "Initializing Video" ); }			initGL();		SDL_WarpMouse( WINDOW_WIDTH/2, WINDOW_HEIGHT/2 );		SDL_Thread *eventThread = SDL_CreateThread( &eventThreadFn, NULL );	SDL_Thread *drawThread = SDL_CreateThread( &drawThreadFn, NULL );	SDL_Thread *shotsThread = SDL_CreateThread( &moveShotsThreadFn, NULL );		SDL_WaitThread( eventThread, NULL );	SDL_KillThread( drawThread );	SDL_KillThread( shotsThread );	SDL_DestroyMutex( CShot::instanceMutex );		SDL_Quit();	return 0;}