Пример #1
0
void MoSyncThread::start(int (SDLCALL * func)(void*), void* arg) {
	mThread = SDL_CreateThread(func, arg);
	_ASSERT(mThread);
}
int video_thr(LPVOID lpParam)
{
	int iRet = -1;
	AVFormatContext		*	pFmtCtx				= NULL;
	AVFormatContext		*	pRtmpFmtCtx			= NULL;
	AVInputFormat		*	pVideoInputFmt		= NULL;
	AVOutputFormat		*	pVideoOutfmt		= NULL;
	struct_stream_info	*	strct_streaminfo	= NULL;
	AVCodecContext		*	pCodecContext		= NULL;
	AVCodec				*	pCodec				= NULL;
	int						iVideoIndex			= -1;
	int						iVideo_Height		= 0;
	int						iVideo_Width		= 0;
	int						iVideoPic			= 0;
	int64_t					start_time			= 0;
	int						frame_index			= 0;
	SDL_Event				event;

	CLS_DlgStreamPusher* pThis = (CLS_DlgStreamPusher*)lpParam;
	if (pThis == NULL){
		TRACE("video_thr--pThis == NULL\n");
		return iRet;
	}
	pVideoInputFmt = av_find_input_format("dshow");
	if (pVideoInputFmt == NULL){
		TRACE("pVideoInputFmt == NULL\n");
		return iRet;
	}

	char* psDevName = pThis->GetDeviceName(n_Video);
	if (psDevName == NULL){
		TRACE("video_thr--psDevName == NULL");
		return iRet;
	}

	while (1){
		if (pThis->m_cstrPushAddr != ""){
			break;
		}
	}

	//根据推流地址获取到AVFormatContext
	avformat_alloc_output_context2(&pRtmpFmtCtx, NULL, "flv", pThis->m_cstrPushAddr);

	if (NULL == pRtmpFmtCtx){
		TRACE("NULL == pRtmpFmtCtx");
		return iRet;
	}
	pVideoOutfmt = pRtmpFmtCtx->oformat;

	strct_streaminfo = pThis->m_pStreamInfo;
	if (NULL == strct_streaminfo){
		TRACE("NULL == strct_streaminfo");
		return iRet;
	}

	FILE *fp_yuv = fopen("output.yuv", "wb+");

	pFmtCtx = avformat_alloc_context();
	if (avformat_open_input(&pFmtCtx, psDevName, pVideoInputFmt, NULL) != 0){
		TRACE("avformat_open_input err!\n");
		goto END;
	}
	if (avformat_find_stream_info(pFmtCtx, NULL) < 0){
		TRACE("avformat_find_stream_info(pFmtCtx, NULL) < 0\n");
		goto END;
	}

	for (int i = 0; i < pFmtCtx->nb_streams; i++){
		if (pFmtCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO){
			iVideoIndex = i;
			break;
		}
	}

	if (iVideoIndex < 0){
		TRACE("iVideoIndex < 0\n");
		goto END;
	}

	pCodecContext = pFmtCtx->streams[iVideoIndex]->codec;
	if (NULL == pCodecContext){
		TRACE("NULL == pCodecContext");
		goto END;
	}
	pCodec = avcodec_find_decoder(pCodecContext->codec_id);
	if (pCodec == NULL){
		TRACE("avcodec_find_decoder<0");
		goto END;
	}
	if (avcodec_open2(pCodecContext, pCodec, NULL)<0){
		TRACE("avcodec_open2<0");
		goto END;
	}

	for (int i = 0; i < pFmtCtx->nb_streams; i++) {
		//根据输入流创建输出流(Create output AVStream according to input AVStream)  
		AVStream *in_stream = pFmtCtx->streams[i];
		AVStream *out_stream = avformat_new_stream(pRtmpFmtCtx, in_stream->codec->codec);
		if (!out_stream) {
			printf("Failed allocating output stream\n");
			iRet = AVERROR_UNKNOWN;
			goto END;
		}
		//复制AVCodecContext的设置(Copy the settings of AVCodecContext)  
		iRet = avcodec_copy_context(out_stream->codec, in_stream->codec);
		if (iRet < 0) {
			TRACE("Failed to copy context from input to output stream codec context\n");
			goto END;
		}
		out_stream->codec->codec_tag = 0;
		if (pRtmpFmtCtx->oformat->flags & AVFMT_GLOBALHEADER)
			out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
	}

	if (!(pVideoOutfmt->flags & AVFMT_NOFILE)) {
		iRet = avio_open(&pRtmpFmtCtx->pb, pThis->m_cstrPushAddr, AVIO_FLAG_WRITE);
		if (iRet < 0) {
			TRACE("Could not open output URL '%s'", pThis->m_cstrPushAddr);
			goto END;
		}
	}

	iRet = avformat_write_header(pRtmpFmtCtx, NULL);
	if (iRet < 0) {
		TRACE("Error occurred when opening output URL\n");
		goto END;
	}

	start_time = av_gettime();

	//获取视频的宽与高
	iVideo_Height = pCodecContext->height;//strct_streaminfo->m_height;//
	iVideo_Width = pCodecContext->width;//strct_streaminfo->m_width;//
	TRACE("video_thr--video_height[%d],video_width[%d]", iVideo_Height
	, iVideo_Width);

	strct_streaminfo->m_pVideoPacket = (AVPacket*)av_malloc(sizeof(AVPacket));

	strct_streaminfo->m_pVideoFrame = av_frame_alloc();
	strct_streaminfo->m_pVideoFrameYUV = av_frame_alloc();
	strct_streaminfo->m_pVideoOutBuffer = (uint8_t *)av_malloc(avpicture_get_size(AV_PIX_FMT_YUV420P, iVideo_Width, iVideo_Height));
	avpicture_fill((AVPicture *)strct_streaminfo->m_pVideoFrameYUV, strct_streaminfo->m_pVideoOutBuffer, AV_PIX_FMT_YUV420P, iVideo_Width, iVideo_Height);
	strct_streaminfo->m_video_sws_ctx = sws_getContext(iVideo_Width, iVideo_Height, pCodecContext->pix_fmt,
		iVideo_Width, iVideo_Height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
	if (NULL == strct_streaminfo->m_video_sws_ctx){
		TRACE("NULL == strct_streaminfo->m_video_sws_ctx\n");
		goto END;
	}

	strct_streaminfo->m_video_refresh_tid = SDL_CreateThread(video_refresh_thread, NULL, strct_streaminfo);

	//从摄像头获取数据
	for (;;){
		AVStream *in_stream, *out_stream;
		SDL_WaitEvent(&event);
		if (event.type == FF_VIDEO_REFRESH_EVENT){
			if (av_read_frame(pFmtCtx, strct_streaminfo->m_pVideoPacket) >= 0){
				if (strct_streaminfo->m_pVideoPacket->pts == AV_NOPTS_VALUE){
					//Write PTS  
					AVRational time_base1 = pFmtCtx->streams[iVideoIndex]->time_base;
					//Duration between 2 frames (us)  
					int64_t calc_duration = (double)AV_TIME_BASE / av_q2d(pFmtCtx->streams[iVideoIndex]->r_frame_rate);
					//Parameters  
					strct_streaminfo->m_pVideoPacket->pts = (double)(frame_index*calc_duration) / (double)(av_q2d(time_base1)*AV_TIME_BASE);
					strct_streaminfo->m_pVideoPacket->dts = strct_streaminfo->m_pVideoPacket->pts;
					strct_streaminfo->m_pVideoPacket->duration = (double)calc_duration / (double)(av_q2d(time_base1)*AV_TIME_BASE);
				}

				if (strct_streaminfo->m_pVideoPacket->stream_index == iVideoIndex){

					AVRational time_base = pFmtCtx->streams[iVideoIndex]->time_base;
					AVRational time_base_q = { 1, AV_TIME_BASE };
					int64_t pts_time = av_rescale_q(strct_streaminfo->m_pVideoPacket->dts, time_base, time_base_q);
					int64_t now_time = av_gettime() - start_time;
					if (pts_time > now_time)
						av_usleep(pts_time - now_time);

					in_stream = pFmtCtx->streams[strct_streaminfo->m_pVideoPacket->stream_index];
					out_stream = pRtmpFmtCtx->streams[strct_streaminfo->m_pVideoPacket->stream_index];
					/* copy packet */
					//转换PTS/DTS(Convert PTS/DTS)  
					strct_streaminfo->m_pVideoPacket->pts = av_rescale_q_rnd(strct_streaminfo->m_pVideoPacket->pts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
					strct_streaminfo->m_pVideoPacket->dts = av_rescale_q_rnd(strct_streaminfo->m_pVideoPacket->dts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
					strct_streaminfo->m_pVideoPacket->duration = av_rescale_q(strct_streaminfo->m_pVideoPacket->duration, in_stream->time_base, out_stream->time_base);
					strct_streaminfo->m_pVideoPacket->pos = -1;
					TRACE("Send %8d video frames to output URL\n", frame_index);

					frame_index++;

					iRet = av_interleaved_write_frame(pRtmpFmtCtx, strct_streaminfo->m_pVideoPacket);

					if (iRet < 0) {
						TRACE("Error muxing packet\n");
						break;
					}

					if (pThis->m_blVideoShow){

						//解码显示
						iRet = avcodec_decode_video2(pCodecContext, strct_streaminfo->m_pVideoFrame, &iVideoPic, strct_streaminfo->m_pVideoPacket);
						if (iRet < 0){
							TRACE("Decode Error.\n");
							av_free_packet(strct_streaminfo->m_pVideoPacket);
							goto END;
						}
						if (iVideoPic <= 0){
							TRACE("iVideoPic <= 0");
							av_free_packet(strct_streaminfo->m_pVideoPacket);
							goto END;
						}

						if (sws_scale(strct_streaminfo->m_video_sws_ctx, (const uint8_t* const*)strct_streaminfo->m_pVideoFrame->data, strct_streaminfo->m_pVideoFrame->linesize, 0, /*strct_streaminfo->m_height*/iVideo_Height,
							strct_streaminfo->m_pVideoFrameYUV->data, strct_streaminfo->m_pVideoFrameYUV->linesize) < 0){
							TRACE("sws_scale < 0");
							av_free_packet(strct_streaminfo->m_pVideoPacket);
							goto END;
						}

						if (pThis->m_blPushStream){
							//进行推流操作
							if (pThis->push_stream() < 0){
								TRACE("pThis->push_stream() < 0");
								goto END;
							}
						}


						if (SDL_UpdateTexture(strct_streaminfo->m_sdlTexture, NULL, strct_streaminfo->m_pVideoFrameYUV->data[0], strct_streaminfo->m_pVideoFrameYUV->linesize[0]) < 0){
							TRACE("SDL_UpdateTexture < 0\n");
							goto END;
						}

						if (SDL_RenderClear(strct_streaminfo->m_sdlRenderer) < 0){
							TRACE("SDL_RenderClear<0\n");
							goto END;
						}
						
						if (SDL_RenderCopy(strct_streaminfo->m_sdlRenderer, strct_streaminfo->m_sdlTexture, NULL, NULL) < 0){
							TRACE("SDL_RenderCopy<0\n");
							goto END;
						}

						SDL_RenderPresent(strct_streaminfo->m_sdlRenderer);
					}
				}
				av_free_packet(strct_streaminfo->m_pVideoPacket);
			}
		}
		else if (event.type == FF_BREAK_EVENT){
			break;
		}
	}
	av_write_trailer(pRtmpFmtCtx);

	iRet = 1;
END:
	//fclose(fp_yuv);
	if (strct_streaminfo->m_video_sws_ctx){
		sws_freeContext(strct_streaminfo->m_video_sws_ctx);
	}
	if (strct_streaminfo->m_pVideoFrameYUV){
		av_frame_free(&strct_streaminfo->m_pVideoFrameYUV);
	}
	avformat_close_input(&pFmtCtx);
	avformat_free_context(pRtmpFmtCtx);
	return iRet;
}
Пример #3
0
int main( int argc, char* argv[] )
{
    SDL_Event event;
    Uint32 u;
    Uint32 v;
    int i;
    int w = W;
    int h = H;
    int multis = MULTIS;
    int threads = THREADS;
    int photons = PHOTONS;
    unsigned seed = (unsigned)-1;
    bool preview = true;

    NICEME;

    // Process cmd line args
    for(i=1; i<argc; i++)
    {
        if( argv[i][0]=='-' ) switch( argv[i][1] )
            {
            case 'w':
                w = atoi(argv[i]+2);
                break;
            case 'h':
                h = atoi(argv[i]+2);
                break;
            case 'm':
                multis = atoi(argv[i]+2);
                break;
            case 't':
                threads = atoi(argv[i]+2);
                break;
            case 'p':
                photons = atoi(argv[i]+2);
                break;
            case '-':
                printf( "Usage: [OPTION]... [SEED]\nRender ray-traced 3D images generated randomly with seed number SEED.\n\n  option default description\n  -wNUM  %7d Set image output width to NUM\n  -hNUM  %7d Set image output height to NUM\n  -mNUM  %7d Set multisampling level to NUM (level 2 recommended)\n  -tNUM  %7d Parallelize with NUM threads\n  -pNUM  %7d Simulate lighting with NUM million photons!\n",W,H,MULTIS,THREADS,PHOTONS ), exit(0);
            default:
                fprintf( stderr, "Halt! -%c isn't one of my options!\nUse --help for help.\n", argv[i][1] ), exit(-1);
            }
        else if( seed==(unsigned)-1 )
        {
            seed = atoi(argv[i]);
            if( !seed )
                fprintf( stderr, "Halt! SEED ought to be a positive number, not %s\n", argv[i] ), exit(-1);
        }
        else
            fprintf( stderr, "Halt! I'm confused by cmd line argument #%d: %s\n", i, argv[i] ), exit(-1);
    }
    if( w<1 ) w=W;
    if( h<1 ) h=H;
    if( multis<1 ) multis=MULTIS;
    if( threads<1 ) threads=THREADS;
    if( photons<1 ) photons=PHOTONS;

    // Use time as seed if not otherwise specified
    if( seed==(unsigned)-1 )
        seed = (unsigned)time(NULL);

    // Init SDL
    if( SDL_Init( SDL_INIT_TIMER|SDL_INIT_AUDIO|SDL_INIT_VIDEO ) < 0 || !SDL_GetVideoInfo() )
        return 0;

    // Create Window
    SetVideo( w, h );
    SDL_WM_SetCaption("PixelMachine", NULL);

    pinfo = SDL_GetVideoInfo();

    // font init
    SJF_Init(pinfo);

    //ui setup
    ui.init();
    h_menu = ui.new_control(0,0,0,0);
    h_render = ui.new_control(h_menu,80,15,SJUIF_EXTENDSV);
    ui.set_caption(h_menu,"Click to render...");
    ui.set_caption(h_render,"Loading");

    //pm preview render setup
    pixelmachine = new PIXELMACHINE;
    pixelmachine->init(seed,100,75,1,threads,(photons?1:0));
    thread = SDL_CreateThread(run_pixel_machine,NULL);

    // MAIN LOOP
    while( 1 )
    {
        while( SDL_PollEvent(&event) ) switch(event.type)
            {
            case SDL_VIDEOEXPOSE:
                ;
                break;
            case SDL_VIDEORESIZE:
                SetVideo( event.resize.w, event.resize.h );
                break;
            case SDL_MOUSEBUTTONDOWN:
                if( preview )
                {
                    //pm full render go!
                    preview = false;
                    pixelmachine->cancel = true;
                    SDL_WaitThread(thread,NULL); //BUG: thread may not be valid?
                    delete pixelmachine;
                    pixelmachine = new PIXELMACHINE;
                    pixelmachine->init(seed,w,h,multis,threads,photons);
                    thread = SDL_CreateThread(run_pixel_machine,NULL);
                }
                break;
            case SDL_KEYDOWN:
                ;
                break;
            case SDL_QUIT:
                pixelmachine->cancel = true;
                SDL_WaitThread(thread,NULL); //BUG: thread may not be valid?
                delete pixelmachine;
                Cleanup();
                break;
            }

        gutimenow = SDL_GetTicks();
        if( (Uint32)(gutimenow-gutime)>50 )
        {
            Render();
            gutime = gutimenow;
        }

        // chill out for a bit
        SDL_Delay(10);
    }

    return 0;
}
Пример #4
0
int main(int argc, char *argv[])
{
    enum { GAME_COMPUTER, GAME_NETWORK, GAME_UNKNOWN } game_type = GAME_UNKNOWN;
    char *remote_address = NULL;
    int remote_port;
    int i;
	
    if (argc < 2) {
	printf("Penguin Warrior\n");
	printf("Usage: pw [ mode ] [ option ... ]\n");
	printf("  Game modes (choose one):\n");
	printf("    --computer\n");
	printf("    --client <remote ip address>\n");
	printf("    --server <port number>\n");
	printf("  Display options, for tweaking and experimenting:\n");
	printf("    --fullscreen\n");
	printf("    --hwsurface  (use an SDL hardware surface if possible)\n");
	printf("    --doublebuf  (use SDL double buffering if possible)\n");
	printf("  The display options default to a windowed, software buffer.\n");
	exit(EXIT_FAILURE);
    }

    /* Process command line arguments. There are plenty of libraries for command
       line processing, but our needs are simple in this case. */
    for (i = 0; i < argc; i++) {

	/* Networked or scripted opponent? */
	if (!strcmp(argv[i], "--computer")) {
	    game_type = GAME_COMPUTER;
	    continue;
	} else if (!strcmp(argv[i], "--client")) {
	    game_type = GAME_NETWORK;
	    if (i + 2 >= argc) {
		printf("You must supply an IP address "\
		       "and port number for network games.\n");
		exit(EXIT_FAILURE);
	    }
	    remote_address = argv[i+1];
	    remote_port = atoi(argv[i+2]);
	    i++;
	    continue;

	} else if (!strcmp(argv[i], "--server")) {
	    game_type = GAME_NETWORK;
	    if (++i >= argc) {
		printf("You must supply a port number "\
		       "for --server.\n");
		exit(EXIT_FAILURE);
	    }
	    remote_port = atoi(argv[i]);
	    continue;
			
	    /* Display-related options */
	} else if (!strcmp(argv[i], "--hwsurface")) {
	    hwsurface = 1;
	} else if (!strcmp(argv[i], "--doublebuf")) {
	    doublebuf = 1;
	} else if (!strcmp(argv[i], "--fullscreen")) {
	    fullscreen = 1;
	}
    }

    /* If this is a network game, make a connection. */
    if (game_type == GAME_NETWORK) {

	/* If there's no remote address, the user selected
	   server mode. */
	if (remote_address == NULL) {
	    if (WaitNetgameConnection(remote_port,
				      &netlink) != 0) {
		printf("Unable to receive connection.\n");
		exit(EXIT_FAILURE);
	    }
	} else {
	    if (ConnectToNetgame(remote_address, remote_port,
				 &netlink) != 0) {
		printf("Unable to connect.\n");
		exit(EXIT_FAILURE);
	    }
	}

	opponent_type = OPP_NETWORK;
	printf("Playing in network game against %s.\n", netlink.dotted_ip);

    } else if (game_type == GAME_COMPUTER) {

	opponent_type = OPP_COMPUTER;
	printf("Playing against the computer.\n");

    } else {

	printf("No game type selected.\n");
	exit(EXIT_FAILURE);

    }
	
    /* Initialize our random number generator. */
    initrandom();

    /* Create a mutex to protect the player data. */
    player_mutex = SDL_CreateMutex();
    if (player_mutex == NULL) {
	fprintf(stderr, "Unable to create mutex: %s\n",
		SDL_GetError());
    }

    /* Start our scripting engine. */
    InitScripting();
    if (LoadGameScript("pw.tcl") != 0) {
	fprintf(stderr, "Exiting due to script error.\n");
	exit(EXIT_FAILURE);
    }

    /* Fire up SDL. */
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
	printf("Unable to initialize SDL: %s\n", SDL_GetError());
	exit(EXIT_FAILURE);
    }
    atexit(SDL_Quit);
	
    /* Set an appropriate 16-bit video mode. */
    if (SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 16,
			 (hwsurface ? SDL_HWSURFACE : SDL_SWSURFACE) |
			 (doublebuf ? SDL_DOUBLEBUF : 0) |
			 (fullscreen ? SDL_FULLSCREEN : 0)) == NULL) {
	printf("Unable to set video mode: %s\n", SDL_GetError());
	exit(EXIT_FAILURE);
    }
	
    /* Save the screen pointer for later use. */
    screen = SDL_GetVideoSurface();
	
    /* Set the window caption to the name of the game. */
    SDL_WM_SetCaption("Penguin Warrior", "Penguin Warrior");
	
    /* Hide the mouse pointer. */
    SDL_ShowCursor(0);

    /* Initialize the status display. */
    if (InitStatusDisplay() < 0) {
	printf("Unable to initialize status display.\n");
	exit(EXIT_FAILURE);
    }
		
    /* Start the OpenAL-based audio system. */
    InitAudio();

    /* Initialize music and give the music system a file. */
    InitMusic();
    if (LoadMusic("reflux.ogg") < 0) {
	/* If that failed, don't worry about it. */
	printf("Unable to load reflux.ogg.\n");
    }

    /* Load the game's data into globals. */
    LoadGameData();

    /* Initialize the background starfield. */
    InitBackground();

    /* Start the network thread. */
    if (game_type == GAME_NETWORK) {
	network_thread = SDL_CreateThread(NetworkThread, NULL);
	if (network_thread == NULL) {
	    printf("Unable to start network thread: %s\n",
		   SDL_GetError());
	    exit(EXIT_FAILURE);
	}
    }
	
    /* Play! */
    InitPlayer(&player);
    InitPlayer(&opponent);
    PlayGame();

    /* Kill the network thread. */
    if (game_type == GAME_NETWORK) {
	SDL_KillThread(network_thread);
    }

    /* Close the network connection. */
    if (game_type == GAME_NETWORK)
	CloseNetgameLink(&netlink);

    /* Unhide the mouse pointer. */
    SDL_ShowCursor(1);
	
    /* Clean up the status display. */
    CleanupStatusDisplay();

    /* Unload data. */
    UnloadGameData();
	
    /* Shut down our scripting engine. */
    CleanupScripting();

    /* Get rid of the mutex. */
    SDL_DestroyMutex(player_mutex);

    /* Shut down audio. */
    CleanupMusic();
    CleanupAudio();

    return 0;
}
Пример #5
0
		Thread *CreateThread(int (*fn)(void *), void *data)
		{
			return SDL_CreateThread(fn, data);
		}
void GameScreen::Update(int delta)
{
    if (!caseIsReady && gCaseFilePath.length() > 0)
    {
        SDL_CreateThread(GameScreen::LoadCaseStatic, "LoadCaseThread", new LoadCaseParameters(gCaseFilePath));
        gCaseFilePath = "";
    }

    if (isFinishing)
    {
        if (Case::GetInstance()->GetIsUnloaded())
        {
            ResourceLoader::GetInstance()->SnapLoadStepQueue();

            while (ResourceLoader::GetInstance()->HasLoadStep())
            {
                ResourceLoader::GetInstance()->TryRunOneLoadStep();
            }

            ResourceLoader::GetInstance()->UnloadCase();
            Case::DestroyInstance();
            caseIsReady = false;
            isFinishing = false;

            // If the case file path contains a path, then we're loading a new case,
            // so we only want to do go back to the title screen if it doesn't.
            if (gCaseFilePath.length() == 0)
            {
                Game::GetInstance()->PrepareMenuMode();
                isFinished = true;
                nextScreenId = TITLE_SCREEN_ID;
            }
        }

        return;
    }

    if (!caseIsReady)
    {
        timeSinceLastLoadingDotsUpdate += delta;

        while (timeSinceLastLoadingDotsUpdate > LoadingDotsUpdateDelayMs)
        {
            timeSinceLastLoadingDotsUpdate -= LoadingDotsUpdateDelayMs;
            numLoadingDots++;

            if (numLoadingDots > 3)
            {
                numLoadingDots = 1;
            }
        }

        return;
    }
    else if (Case::GetInstance()->IsLoading())
    {
        if (Case::GetInstance()->GetWantsToLoadResources())
        {
            Case::GetInstance()->LoadResources();
            startedLoadingResources = true;
        }
        else if (startedLoadingResources && !ResourceLoader::GetInstance()->HasLoadStep() && !ResourceLoader::GetInstance()->HasImageTexturesToLoad())
        {
            Case::GetInstance()->SetIsLoadingSprites(false);
            startedLoadingResources = false;
        }

        return;
    }

    if (caseNeedsReset)
    {
        Case::GetInstance()->Reset();
        Case::GetInstance()->Begin();
        caseNeedsReset = false;
    }

    if (Case::GetInstance()->GetIsFinished())
    {
        stopMusic();
        isFinishing = true;
        SDL_CreateThread(GameScreen::UnloadCaseStatic, "UnloadCaseThread", this);
        return;
    }

    Case::GetInstance()->Update(delta);
}
Пример #7
0
/*
===============
GLimp_SpawnRenderThread
===============
*/
qboolean GLimp_SpawnRenderThread(void (*function) (void))
{
	static qboolean warned = qfalse;

	if(!warned)
	{
		Com_Printf("WARNING: You enable r_smp at your own risk!\n");
		warned = qtrue;
	}

#if !defined(MACOS_X) && !defined(WIN32) && !defined (SDL_VIDEO_DRIVER_X11)
	return qfalse;				/* better safe than sorry for now. */
#endif

	if(renderThread != NULL)	/* hopefully just a zombie at this point... */
	{
		Com_Printf("Already a render thread? Trying to clean it up...\n");
		GLimp_ShutdownRenderThread();
	}

	smpMutex = SDL_CreateMutex();
	if(smpMutex == NULL)
	{
		Com_Printf("smpMutex creation failed: %s\n", SDL_GetError());
		GLimp_ShutdownRenderThread();
		return qfalse;
	}

	renderCommandsEvent = SDL_CreateCond();
	if(renderCommandsEvent == NULL)
	{
		Com_Printf("renderCommandsEvent creation failed: %s\n", SDL_GetError());
		GLimp_ShutdownRenderThread();
		return qfalse;
	}

	renderCompletedEvent = SDL_CreateCond();
	if(renderCompletedEvent == NULL)
	{
		Com_Printf("renderCompletedEvent creation failed: %s\n", SDL_GetError());
		GLimp_ShutdownRenderThread();
		return qfalse;
	}

	renderThreadFunction = function;
	renderThread = SDL_CreateThread(GLimp_RenderThreadWrapper, NULL);
	if(renderThread == NULL)
	{
		ri.Printf(PRINT_ALL, "SDL_CreateThread() returned %s", SDL_GetError());
		GLimp_ShutdownRenderThread();
		return qfalse;
	}
	else
	{
		// tma 01/09/07: don't think this is necessary anyway?
		//
		// !!! FIXME: No detach API available in SDL!
		//ret = pthread_detach( renderThread );
		//if ( ret ) {
		//ri.Printf( PRINT_ALL, "pthread_detach returned %d: %s", ret, strerror( ret ) );
		//}
	}

	return qtrue;
}
void CImageClient::run(CRawImage *im)
{
    image  = im;
    codec = new CDecoder(imageSem,im);
    thread = SDL_CreateThread(StartThread,static_cast<void*>(this));
}
Пример #9
0
thread::thread(const std::string& name, boost::function<void()> fn) 
	: fn_(fn), thread_(SDL_CreateThread(call_boost_function, name.c_str(), new boost::function<void()>(fn_)))
{}
Пример #10
0
void Personaje::caminar(unsigned int destX, unsigned int destY){
  if ( thrAccion ) SDL_KillThread(thrAccion);
  this->destX=destX;
  this->destY=destY;
  this->thrAccion = SDL_CreateThread(Personaje::entCaminar,this);
}
Пример #11
0
int
main(int argc, char *argv[])
{
    int success;

	/* Enable standard application logging */
    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);

    success = SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
                "Simple MessageBox",
                "This is a simple error MessageBox",
                NULL);
    if (success == -1) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error Presenting MessageBox: %s\n", SDL_GetError());
        quit(1);
    }

    success = SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
                "Simple MessageBox",
                "This is a simple MessageBox with a newline:\r\nHello world!",
                NULL);
    if (success == -1) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error Presenting MessageBox: %s\n", SDL_GetError());
        quit(1);
    }

    /* Google says this is Traditional Chinese for "beef with broccoli" */
    success = SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
                "UTF-8 Simple MessageBox",
                "Unicode text: '牛肉西蘭花' ...",
                NULL);
    if (success == -1) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error Presenting MessageBox: %s\n", SDL_GetError());
        quit(1);
    }

    /* Google says this is Traditional Chinese for "beef with broccoli" */
    success = SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
                "UTF-8 Simple MessageBox",
                "Unicode text and newline:\r\n'牛肉西蘭花'\n'牛肉西蘭花'",
                NULL);
    if (success == -1) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error Presenting MessageBox: %s\n", SDL_GetError());
        quit(1);
    }

    button_messagebox(NULL);

    /* Test showing a message box from a background thread.

       On Mac OS X, the video subsystem needs to be initialized for this
       to work, since the message box events are dispatched by the Cocoa
       subsystem on the main thread.
     */
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL video subsystem: %s\n", SDL_GetError());
        return (1);
    }
    {
        int status = 0;
        SDL_Event event;
        intptr_t eventNumber = SDL_RegisterEvents(1);
        SDL_Thread* thread = SDL_CreateThread(&button_messagebox, "MessageBox", (void*)eventNumber);

        while (SDL_WaitEvent(&event))
        {
            if (event.type == eventNumber) {
                break;
            }
        }

        SDL_WaitThread(thread, &status);

        SDL_Log("Message box thread return %i\n", status);
    }

    /* Test showing a message box with a parent window */
    {
        SDL_Event event;
        SDL_Window *window = SDL_CreateWindow("Test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, 0);

        success = SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
                    "Simple MessageBox",
                    "This is a simple error MessageBox with a parent window",
                    window);
        if (success == -1) {
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error Presenting MessageBox: %s\n", SDL_GetError());
            quit(1);
        }

        while (SDL_WaitEvent(&event))
        {
            if (event.type == SDL_QUIT || event.type == SDL_KEYUP) {
                break;
            }
        }
    }

    SDL_Quit();
    return (0);
}
Пример #12
0
void Drawing::nonBlockingShowWindow() {
	SDL_Thread * thread = SDL_CreateThread( Drawing::showWindowThread, "show window", this);
}
Пример #13
0
void Drawing::nonBlockRayTracingWorld(World * world_ptr) {
	SDL_Thread * thread = SDL_CreateThread( Drawing::realRayTracingThread, "ray tracing", world_ptr);
}
Пример #14
0
void Drawing::nonBlockingRayTracing() {
	SDL_Thread * thread = SDL_CreateThread( Drawing::rayTracingThread, "ray tracing", this);
}
Пример #15
0
int stream_component_open(VideoState *is, int stream_index)
{
    AVFormatContext *pFormatCtx = is->pFormatCtx;
    AVCodecContext *codecCtx;
    AVCodec *codec;
    SDL_AudioSpec wanted_spec, spec;

    if(stream_index < 0 || stream_index >= pFormatCtx->nb_streams)
    {
        return -1;
    }

    // Get a pointer to the codec context for the video stream
    codecCtx = pFormatCtx->streams[stream_index]->codec;

    if(codecCtx->codec_type == CODEC_TYPE_AUDIO)
    {
        // Set audio settings from codec info
        wanted_spec.freq = codecCtx->sample_rate;
        wanted_spec.format = AUDIO_S16SYS;
        wanted_spec.channels = codecCtx->channels;
        wanted_spec.silence = 0;
        wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
        wanted_spec.callback = audio_callback;
        wanted_spec.userdata = is;

        if(SDL_OpenAudio(&wanted_spec, &spec) < 0)
        {
            fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
            return -1;
        }
        is->audio_hw_buf_size = spec.size;
    }
    codec = avcodec_find_decoder(codecCtx->codec_id);

    if(!codec || (avcodec_open(codecCtx, codec) < 0))
    {
        fprintf(stderr, "Unsupported codec!\n");
        return -1;
    }

    switch(codecCtx->codec_type)
    {
    case CODEC_TYPE_AUDIO:
        is->audioStream = stream_index;
        is->audio_st = pFormatCtx->streams[stream_index];
        is->audio_buf_size = 0;
        is->audio_buf_index = 0;
        memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
        packet_queue_init(&is->audioq);
        SDL_PauseAudio(0);
        break;
    case CODEC_TYPE_VIDEO:
        is->videoStream = stream_index;
        is->video_st = pFormatCtx->streams[stream_index];

        is->frame_timer = (double)av_gettime() / 1000000.0;
        is->frame_last_delay = 40e-3;
        is->video_current_pts_time = av_gettime();

        packet_queue_init(&is->videoq);
        is->video_tid = SDL_CreateThread(video_thread, is);
        codecCtx->get_buffer = our_get_buffer;
        codecCtx->release_buffer = our_release_buffer;
        break;
    default:
        break;
    }
    return 0;
}
Пример #16
0
thread::thread(boost::function<void()> fn) 
	: fn_(fn), thread_(SDL_CreateThread(call_boost_function, new boost::function<void()>(fn_)))
{}
Пример #17
0
/*
 * This thread will read the buttons in an interrupt like fashion, and
 * also initializes SDL_INIT_VIDEO and the surfaces
 *
 * it must be done in the same thread (at least on windows) because events only
 * work in the thread which called SDL_Init(SubSystem) with SDL_INIT_VIDEO
 *
 * This is an SDL thread and relies on preemptive behavoir of the host
 **/
static int sdl_event_thread(void * param)
{
    SDL_InitSubSystem(SDL_INIT_VIDEO);

#if (CONFIG_PLATFORM & PLATFORM_MAEMO)
    SDL_sem *wait_for_maemo_startup;
#endif
    SDL_Surface *picture_surface = NULL;
    int width, height;
    int depth;
    Uint32 flags;

    /* Try and load the background image. If it fails go without */
    if (background) {
        picture_surface = SDL_LoadBMP("UI256.bmp");
        if (picture_surface == NULL) {
            background = false;
            DEBUGF("warn: %s\n", SDL_GetError());
        }
    }
    
    /* Set things up */
    if (background)
    {
        width = UI_WIDTH;
        height = UI_HEIGHT;
    } 
    else 
    {
#ifdef HAVE_REMOTE_LCD
        if (showremote)
        {
            width = SIM_LCD_WIDTH > SIM_REMOTE_WIDTH ? SIM_LCD_WIDTH : SIM_REMOTE_WIDTH;
            height = SIM_LCD_HEIGHT + SIM_REMOTE_HEIGHT;
        }
        else
#endif
        {
            width = SIM_LCD_WIDTH;
            height = SIM_LCD_HEIGHT;
        }
    }

    depth = LCD_DEPTH;
    if (depth < 8)
        depth = 16;

    flags = SDL_HWSURFACE|SDL_DOUBLEBUF;
#if (CONFIG_PLATFORM & (PLATFORM_MAEMO|PLATFORM_PANDORA))
    /* Fullscreen mode for maemo app */
    flags |= SDL_FULLSCREEN;
#endif

    if ((gui_surface = SDL_SetVideoMode(width * display_zoom, height * display_zoom, depth, flags)) == NULL) {
        panicf("%s", SDL_GetError());
    }

#if (CONFIG_PLATFORM & (PLATFORM_MAEMO|PLATFORM_PANDORA))
    /* Hide mouse cursor on real touchscreen device */
    SDL_ShowCursor(SDL_DISABLE);
#endif

    SDL_WM_SetCaption(UI_TITLE, NULL);

    if (background && picture_surface != NULL)
        SDL_BlitSurface(picture_surface, NULL, gui_surface, NULL);

    /* let system_init proceed */
    SDL_SemPost((SDL_sem *)param);

#if (CONFIG_PLATFORM & PLATFORM_MAEMO)
    /* Start maemo thread: Listen to display on/off events and battery monitoring */
    wait_for_maemo_startup = SDL_CreateSemaphore(0); /* 0-count so it blocks */
    SDL_Thread *maemo_thread = SDL_CreateThread(maemo_thread_func, wait_for_maemo_startup);
#endif

    /*
     * finally enter the button loop */
    gui_message_loop();

#if (CONFIG_PLATFORM & PLATFORM_MAEMO)
    /* Ensure maemo thread is up and running */
    SDL_SemWait(wait_for_maemo_startup);
    SDL_DestroySemaphore(wait_for_maemo_startup);

#if (CONFIG_PLATFORM & PLATFORM_MAEMO5)
    pcm_shutdown_gstreamer();
#endif

    g_main_loop_quit (maemo_main_loop);
    g_main_loop_unref(maemo_main_loop);
    SDL_WaitThread(maemo_thread, NULL);
#endif

    if(picture_surface)
        SDL_FreeSurface(picture_surface);

    /* Order here is relevent to prevent deadlocks and use of destroyed
       sync primitives by kernel threads */
#ifdef HAVE_SDL_THREADS
    sim_thread_shutdown(); /* not needed for native threads */
#endif
    return 0;
}
Пример #18
0
int main(int argc, char **argv)
{
	optproc(argc, argv, &opts); if(audio_init(&opts) < 0) exit(1);
	SDL_Surface *screen = sdl_setup(&opts, IM_SIZE);
	im_w = screen->w - screen->w%16; im_h = screen->h - screen->h%16;
	printf("running with %dx%d bufs\n", im_w, im_h);

	if(strcmp(opts.map_name, "rational") == 0) {
		map_func = soft_map_rational_interp;
		if(opts.quality >= 1)  map_func = soft_map_rational;
	}
	else if(strcmp(opts.map_name, "butterfly") == 0) {
//		map_func = soft_map_butterfly_interp;
//		if(opts.quality >= 1)
			map_func = soft_map_butterfly;
	}
	else if(opts.quality >= 1)  map_func = soft_map;

	maxsrc = maxsrc_new(im_w, im_h);
	struct pal_ctx *pal_ctx = pal_ctx_new(screen->format->BitsPerPixel == 8);

	uint16_t *map_surf[3];
	void *map_surf_mem = aligned_alloc(64, 3 * im_w * im_h * sizeof(uint16_t));
	for(int i=0; i<3; i++)
		map_surf[i] = map_surf_mem + i * im_w * im_h * sizeof(uint16_t);
	memset(map_surf_mem, 0, 3 * im_w * im_h * sizeof(uint16_t));

	tribuf *map_tb = tribuf_new((void **)map_surf, 1);

	int beats = 0;
	int frmcnt = 0;
	int lastdrawn=0;

	SDL_Thread *map_thread = SDL_CreateThread((void *)&run_map_thread, map_tb);
	SDL_Delay(100);

	uint32_t frametimes[FPS_HIST_LEN]; for(int i=1; i<FPS_HIST_LEN; i++) frametimes[i] = 0;
	uint32_t totframetime = frametimes[0] = MIN(1000/opts.draw_rate, 1);

	Uint32 tick0 = SDL_GetTicks();
	Uint32 lastpalstep, lastupdate, fps_oldtime; fps_oldtime = lastpalstep = lastupdate = tick0;
	SDL_Event event;
	while(SDL_PollEvent(&event) >= 0)
	{
		if(event.type == SDL_QUIT || (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_ESCAPE)) {
			break;
		} else if(tribuf_check_fresh(map_tb)) {
			Uint32 now = SDL_GetTicks();
			if(now - lastpalstep >= 2048/256) { // want pallet switch to take ~2 seconds
				pal_ctx_step(pal_ctx, IMIN((now - lastpalstep)*256/2048, 64));
				lastpalstep = now;
			}

			pallet_blit_SDL(screen, tribuf_get_read(map_tb), im_w, im_h, pal_ctx_get_active(pal_ctx));
			tribuf_finish_read(map_tb);

			char buf[64];
			sprintf(buf,"%6.1f FPS %6.1f UPS %6.1f", map_fps, FPS_HIST_LEN*1000.0f/totframetime, maxfrms*1000.0f/(now-tick0));
			DrawText(screen, buf);
			SDL_Flip(screen);

			int newbeat = beat_get_count();
			if(newbeat != beats) pal_ctx_start_switch(pal_ctx, newbeat);
			beats = newbeat;

			now = SDL_GetTicks();
			int delay =  (tick0 + frmcnt*1000/opts.draw_rate) - now;
			if(delay > 0) SDL_Delay(delay);

			totframetime -= frametimes[frmcnt%FPS_HIST_LEN];
			totframetime += (frametimes[frmcnt%FPS_HIST_LEN] = now - fps_oldtime);
			fps_oldtime = now;
			frmcnt++;
		} else {
			SDL_Delay(1000/opts.draw_rate/2); // wait half a frame and hope we get a new buffer
		}
	}
	running = 0;

	int status;
	SDL_WaitThread(map_thread, &status);
	aligned_free(map_surf_mem);
	audio_shutdown();
	SDL_Quit();
    return 0;
}
Пример #19
0
WZ_THREAD *wzThreadCreate(int (*threadFunc)(void *), void *data)
{
	return (WZ_THREAD *)SDL_CreateThread(threadFunc, "wzThread", data);
}
Пример #20
0
bool GameManager::init()
{
	// success flag
	auto success = true;

	// init SDL video and audio
	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0)
	{
		printf("SDL could not initialize SDL ERROR: %s\n", SDL_GetError());
		success = false;
	}
	else
	{
		//Set texture filtering to linear
		if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"))
		{
			printf("Warning: Linear texture filtering not enabled!");
		}

		// create the window
		window.window = SDL_CreateWindow("Breakout",
			SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
			SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN
			);

		if (window.window == nullptr) {
			printf("Window could not be created SDL ERROR: %s\n", SDL_GetError());
			success = false;

		}
		else
		{
			// create the renderer for the window
			gRenderer = SDL_CreateRenderer(window.window, -1, SDL_RENDERER_ACCELERATED);

			if (gRenderer == nullptr)
			{
				printf("Renderer could not be created SDL ERROR %s\n", SDL_GetError());
				success = false;
			}
			else
			{
				// init png loading
				int imgFlags = IMG_INIT_PNG;

				if (!(IMG_Init(imgFlags) & imgFlags))
				{
					printf("SDL_Image could not be initalized, SDL_Image ERROR: %s\n", IMG_GetError());
					success = false;
				}
				else {
					// init SDL_mixer
					success = bgMusic.init();
				}
			}
		}
	}

	//Initialize SDL_ttf
	if (TTF_Init() == -1)
	{
		printf("SDL_ttf could not initialize! SDL_ttf Error: %s\n", TTF_GetError());
		success = false;
	}

	// Initalizing default constructor of pieces, utilizing copy and move constructors
	Piece defaultInit;
	for (auto i = 0; i < PIECES; i++)
	{
		pieces.push_back(defaultInit);
	}

	// initialize the pieces level 0
	initBlocks(pieces, level);

	threadID = SDL_CreateThread(threading_.threadedFunction, "PrintingThread", static_cast<void*>(&ball));
	threadRunning = true;

	return success;
}
Пример #21
0
static void PlayGame()
{
    Uint8 *keystate;
    int quit = 0;
    int turn;
    int prev_ticks = 0, cur_ticks = 0; /* for keeping track of timing */
    int awaiting_respawn = 0;

    /* framerate counter variables */
    int start_time, end_time;
    int frames_drawn = 0;

    /* respawn timer */
    int respawn_timer = -1;
	
    prev_ticks = SDL_GetTicks();
	
    start_time = time(NULL);

    /* Reset the score counters. */
    player.score = 0;
    opponent.score = 0;

    /* Start sound playback. */
    StartAudio();
    StartMusic();

    /* Start the music update thread. */
    music_update_thread = SDL_CreateThread(UpdateMusicThread, NULL);
    if (music_update_thread == NULL) {
	printf("Unable to start music update thread.\n");
    }

    /* Start the game! */
    while ((quit == 0) && network_ok) {

	/* Determine how many milliseconds have passed since
	   the last frame, and update our motion scaling. */
	prev_ticks = cur_ticks;
	cur_ticks = SDL_GetTicks();
	time_scale = (double)(cur_ticks-prev_ticks)/30.0;
				
	/* Update SDL's internal input state information. */
	SDL_PumpEvents();
		
	/* Grab a snapshot of the keyboard. */
	keystate = SDL_GetKeyState(NULL);

	/* Lock the mutex so we can access the player's data. */
	SDL_LockMutex(player_mutex);
		
	/* If this is a network game, take note of variables
	   set by the network thread. These are handled differently
	   for a scripted opponent. */
	if (opponent_type == OPP_NETWORK) {

	    /* Has the opponent respawned? */
	    if (network_opponent_respawn) {
		printf("Remote player has respawned.\n");
		opponent.shields = 100;
		network_opponent_respawn = 0;
		awaiting_respawn = 0;
	    }
		
	    /* Has the local player been hit? */
	    if (local_player_hit) {
		local_player_hit--;
		player.shields -= PHASER_DAMAGE;
		ShowPhaserHit(&player);
				/* No need to check for death, the
				   other computer will tell us. */
	    }
		}

	/* Update phasers. */
	player.firing -= time_scale;
	if (player.firing < 0) player.firing = 0;
	opponent.firing -= time_scale;
	if (opponent.firing < 0) opponent.firing = 0;
	ChargePhasers(&player);

	/* If the local player is destroyed, the respawn timer will
	   start counting. During this time the controls are disabled
	   and explosion sequence occurs. */
	if (respawn_timer >= 0) {
	    respawn_timer++;

	    if (respawn_timer >= ((double)RESPAWN_TIME / time_scale)) {
		respawn_timer = -1;
		InitPlayer(&player);

				/* Set the local_player_respawn flag so the
				   network thread will notify the opponent
				   of the respawn. */
		local_player_respawn = 1;

		SetStatusMessage("GOOD LUCK, WARRIOR!");
	    }
	}

	/* Respond to input and network events, but not if we're in a respawn. */
	if (respawn_timer == -1) {
	    if (keystate[SDLK_q] || keystate[SDLK_ESCAPE]) quit = 1;
			
	    /* Left and right arrow keys control turning. */
	    turn = 0;
	    if (keystate[SDLK_LEFT]) turn += 10;
	    if (keystate[SDLK_RIGHT]) turn -= 10;
			
	    /* Forward and back arrow keys activate thrusters. */
	    player.accel = 0;
	    if (keystate[SDLK_UP]) player.accel = PLAYER_FORWARD_THRUST;
	    if (keystate[SDLK_DOWN]) player.accel = PLAYER_REVERSE_THRUST;
			
	    /* Spacebar fires phasers. */
	    if (keystate[SDLK_SPACE]) {

		if (CanPlayerFire(&player)) {

		    FirePhasers(&player);

		    /* If it's a hit, either notify the opponent
		       or exact the damage. Create a satisfying particle
		       burst. */
		    if (!awaiting_respawn &&
			CheckPhaserHit(&player,&opponent)) {

			ShowPhaserHit(&opponent);
			DamageOpponent();

			/* If that killed the opponent, set the
			   "awaiting respawn" state, to prevent multiple
			   kills. */
			if (opponent.shields <= 0 &&
			    opponent_type == OPP_NETWORK)
			    awaiting_respawn = 1;
       		    }
		}
	    }
			
	    /* Turn. */
	    player.angle += turn * time_scale;
	    if (player.angle < 0) player.angle += 360;
	    if (player.angle >= 360) player.angle -= 360;

	    /* If this is a network game, the remote player will
	       tell us if we've died. Otherwise we have to check
	       for failed shields. */
	    if (((opponent_type == OPP_NETWORK) && local_player_dead) ||
		(player.shields <= 0))
	    {
		printf("Local player has been destroyed.\n");
		local_player_dead = 0;
				
		/* Kaboom! */
		KillPlayer();
				
		/* Respawn. */
		respawn_timer = 0;
	    }
	}

	/* If this is a player vs. computer game, give the computer a chance. */
	if (opponent_type == OPP_COMPUTER) {
	    if (RunGameScript() != 0) {
		fprintf(stderr, "Ending game due to script error.\n");
		quit = 1;
	    }
			
	    /* Check for phaser hits against the player. */
	    if (opponent.firing) {
		if (CheckPhaserHit(&opponent,&player)) {
					
		    ShowPhaserHit(&player);
		    player.shields -= PHASER_DAMAGE;

		    /* Did that destroy the player? */
		    if (respawn_timer < 0 && player.shields <= 0) {
			KillPlayer();
			respawn_timer = 0;
		    }
		}
	    }

	    ChargePhasers(&opponent);
	    UpdatePlayer(&opponent);
	}

	/* Update the player's position. */
	UpdatePlayer(&player);

	/* Update the status information. */
	SetPlayerStatusInfo(player.score, player.shields, player.charge);
	SetOpponentStatusInfo(opponent.score, opponent.shields);

	/* Make the camera follow the player (but impose limits). */
	camera_x = player.world_x - SCREEN_WIDTH/2;
	camera_y = player.world_y - SCREEN_HEIGHT/2;
		
	if (camera_x < 0) camera_x = 0;
	if (camera_x >= WORLD_WIDTH-SCREEN_WIDTH)
	    camera_x = WORLD_WIDTH-SCREEN_WIDTH-1;
	if (camera_y < 0) camera_y = 0;
	if (camera_y >= WORLD_HEIGHT-SCREEN_HEIGHT)
	    camera_y = WORLD_HEIGHT-SCREEN_HEIGHT-1;

	/* Update the particle system. */
	UpdateParticles();

	/* Keep OpenAL happy. */
	UpdateAudio(&player, &opponent);
				
	/* Redraw everything. */
	DrawBackground(screen, camera_x, camera_y);
	DrawParallax(screen, camera_x, camera_y);
	DrawParticles(screen, camera_x, camera_y);
	if (opponent.firing)
	    DrawPhaserBeam(&opponent, screen, camera_x, camera_y);
	if (player.firing)
	    DrawPhaserBeam(&player, screen, camera_x, camera_y);

	if (respawn_timer < 0)
	    DrawPlayer(&player);
	if (!awaiting_respawn)
	    DrawPlayer(&opponent);
	UpdateStatusDisplay(screen);
		
	/* Release the mutex so the networking system can get it.
	   It doesn't stay unlocked for very long, but the networking
	   system should still have plenty of time. */
	SDL_UnlockMutex(player_mutex);
	
	/* Flip the page. */
	SDL_Flip(screen);

	frames_drawn++;
    }

    end_time = time(NULL);
    if (start_time == end_time) end_time++;

    /* Display the average framerate. */
    printf("Drew %i frames in %i seconds, for a framerate of %.2f fps.\n",
	   frames_drawn,
	   end_time-start_time,
	   (float)frames_drawn/(float)(end_time-start_time));


    /* Terminate the music update thread. */
    if (music_update_thread != NULL) {
	SDL_KillThread(music_update_thread);
	music_update_thread = NULL;
    }
	
    /* Stop audio playback. */
    StopAudio();
    StopMusic();
}
Пример #22
0
int NET2_Init()
{
  if (initialized)
  {
    return 0;
  }

#ifndef WIN32

  // SIGPIPE has to be ignored so that NET2 can handle broken
  // connections without raising a program wide exception. SDL_net
  // "should" do this so that it can handle exception properly, but it
  // doesn't.

  signal(SIGPIPE, SIG_IGN); // work around for bug in SDL_net
#endif

  error = 0;
  errorSocket = -1;

  doneYet = 0;

  dataLock = SDL_CreateMutex();
  if (NULL == dataLock)
  {
    setError("NET2: can't create a mutex", -1);
    return -1;
  }

  sdlNetLock = SDL_CreateMutex();
  if (NULL == sdlNetLock)
  {
    setError("NET2: can't create a mutex", -1);
    return -1;
  }

  dataWait = SDL_CreateCond();
  if (NULL == dataWait)
  {
    setError("NET2: can't create a condition variable", -1);
    return -1;
  }

  InitSockets(maxSockets);

  udpSendSocket = snUDPOpen(0);
  if (NULL == udpSendSocket)
  {
    setError("NET2: can't open the UDP send socket", -1);
    return -1;
  }

  processSockets = SDL_CreateThread(PumpNetworkEvents, NULL);
  if (NULL == processSockets)
  {
    setError("NET2: can't start the network thread", -1);
    return -1;
  }
  //printf("root=%d thread=%d\n", SDL_ThreadID(), SDL_GetThreadID(processSockets)); fflush(NULL);

  initialized = 1;
  return 0;
}
Пример #23
0
bool Movie::Setup()
{
    if (!IsRecording())
        return false;
    if (!av)
        return false;

    bool success = true;
    std::string err_msg;
    
	alephone::Screen *scr = alephone::Screen::instance();
	view_rect = scr->window_rect();
	
	if (MainScreenIsOpenGL())
		view_rect.y = scr->height() - (view_rect.y + view_rect.h);
	
	view_rect.x *= scr->pixel_scale();
	view_rect.y *= scr->pixel_scale();
	view_rect.w *= scr->pixel_scale();
	view_rect.h *= scr->pixel_scale();

	temp_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, view_rect.w, view_rect.h, 32,
										0x00ff0000, 0x0000ff00, 0x000000ff,
										0);
	success = (temp_surface != NULL);
	if (!success) err_msg = "Could not create SDL surface";

    Mixer *mx = Mixer::instance();
    
    av_register_all();
    avcodec_register_all();
    
    // Open output file
    AVOutputFormat *fmt;
    if (success)
    {
        fmt = av_guess_format("webm", NULL, NULL);
        success = fmt;
        if (!success) err_msg = "Could not find output format";
    }
    if (success)
    {
        av->fmt_ctx = avformat_alloc_context();
        success = av->fmt_ctx;
        if (!success) err_msg = "Could not allocate movie format context";
    }
    if (success)
    {
        av->fmt_ctx->oformat = fmt;
        strncpy(av->fmt_ctx->filename, moviefile.c_str(), 1024);
        success = (0 <= avio_open(&av->fmt_ctx->pb, av->fmt_ctx->filename, AVIO_FLAG_WRITE));
        if (!success) err_msg = "Could not open movie file for writing";
    }
    
    // Open output video stream
    AVCodec *video_codec;
    AVStream *video_stream;
    if (success)
    {
        video_codec = avcodec_find_encoder(AV_CODEC_ID_VP8);
        success = video_codec;
        if (!success) err_msg = "Could not find VP8 encoder";
    }
    if (success)
    {
        video_stream = avformat_new_stream(av->fmt_ctx, video_codec);
        success = video_stream;
        if (!success) err_msg = "Could not open output video stream";
    }
    if (success)
    {
        video_stream->codec->codec_id = video_codec->id;
        video_stream->codec->codec_type = AVMEDIA_TYPE_VIDEO;
        video_stream->codec->width = view_rect.w;
        video_stream->codec->height = view_rect.h;
        video_stream->codec->time_base = (AVRational){1, TICKS_PER_SECOND};
        video_stream->codec->pix_fmt = AV_PIX_FMT_YUV420P;
        video_stream->codec->flags |= CODEC_FLAG_CLOSED_GOP;
        video_stream->codec->thread_count = get_cpu_count();
        
        if (av->fmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
            video_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
        
        av->video_stream_idx = video_stream->index;
        
        // tuning options
        int vq = graphics_preferences->movie_export_video_quality;
        video_stream->codec->bit_rate = ScaleQuality(vq, 100*1024, 1024*1024, 10*1024*1024);
        video_stream->codec->qmin = ScaleQuality(vq, 10, 4, 0);
        video_stream->codec->qmax = ScaleQuality(vq, 63, 63, 50);
        std::string crf = boost::lexical_cast<std::string>(ScaleQuality(vq, 63, 10, 4));
        av_opt_set(video_stream->codec->priv_data, "crf", crf.c_str(), 0);
        
        success = (0 <= avcodec_open2(video_stream->codec, video_codec, NULL));
        if (!success) err_msg = "Could not open video codec";
    }
    if (success)
    {
        av->video_bufsize = view_rect.w * view_rect.h * 4 + 10000;
        av->video_buf = static_cast<uint8_t *>(av_malloc(av->video_bufsize));
        success = av->video_buf;
        if (!success) err_msg = "Could not allocate video buffer";
    }
    if (success)
    {
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,28,0)
        av->video_frame = avcodec_alloc_frame();
#else
        av->video_frame = av_frame_alloc();
#endif
        success = av->video_frame;
        if (!success) err_msg = "Could not allocate video frame";
    }
    if (success)
    {
        int numbytes = avpicture_get_size(video_stream->codec->pix_fmt, view_rect.w, view_rect.h);
        av->video_data = static_cast<uint8_t *>(av_malloc(numbytes));
        success = av->video_data;
        if (!success) err_msg = "Could not allocate video data buffer";
    }
    if (success)
    {
        avpicture_fill(reinterpret_cast<AVPicture *>(av->video_frame), av->video_data, video_stream->codec->pix_fmt, view_rect.w, view_rect.h);
    }
    
    // Open output audio stream
    AVCodec *audio_codec;
    AVStream *audio_stream;
    if (success)
    {
        audio_codec = avcodec_find_encoder(AV_CODEC_ID_VORBIS);
        success = audio_codec;
        if (!success) err_msg = "Could not find Vorbis encoder";
    }
    if (success)
    {
        audio_stream = avformat_new_stream(av->fmt_ctx, audio_codec);
        success = audio_stream;
        if (!success) err_msg = "Could not open output audio stream";
    }
    if (success)
    {
        audio_stream->codec->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
        audio_stream->codec->codec_id = audio_codec->id;
        audio_stream->codec->codec_type = AVMEDIA_TYPE_AUDIO;
        audio_stream->codec->sample_rate = mx->obtained.freq;
        audio_stream->codec->time_base = (AVRational){1, mx->obtained.freq};
        audio_stream->codec->channels = 2;
        
        if (av->fmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
            audio_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
        
        av->audio_stream_idx = audio_stream->index;
        
        // tuning options
        int aq = graphics_preferences->movie_export_audio_quality;
        audio_stream->codec->global_quality = FF_QP2LAMBDA * (aq / 10);
        audio_stream->codec->flags |= CODEC_FLAG_QSCALE;
        
        audio_stream->codec->sample_fmt = AV_SAMPLE_FMT_FLTP;
        success = (0 <= avcodec_open2(audio_stream->codec, audio_codec, NULL));
        if (!success) err_msg = "Could not open audio codec";
    }
    if (success)
    {
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,28,0)
        av->audio_frame = avcodec_alloc_frame();
#else
        av->audio_frame = av_frame_alloc();
#endif
        success = av->audio_frame;
        if (!success) err_msg = "Could not allocate audio frame";
    }
    if (success)
    {
        av->audio_fifo = av_fifo_alloc(262144);
        success = av->audio_fifo;
        if (!success) err_msg = "Could not allocate audio fifo";
    }
    if (success)
    {
        av->audio_data = reinterpret_cast<uint8_t *>(av_malloc(524288));
        success = av->audio_data;
        if (!success) err_msg = "Could not allocate audio data buffer";
    }
    if (success)
    {
        av->audio_data_conv = reinterpret_cast<uint8_t *>(av_malloc(524288));
        success = av->audio_data_conv;
        if (!success) err_msg = "Could not allocate audio conversion buffer";
    }
    
    // initialize conversion context
    if (success)
    {
        av->sws_ctx = sws_getContext(temp_surface->w, temp_surface->h, AV_PIX_FMT_RGB32,
                                     video_stream->codec->width,
                                     video_stream->codec->height,
                                     video_stream->codec->pix_fmt,
                                     SWS_BILINEAR,
                                     NULL, NULL, NULL);
        success = av->sws_ctx;
        if (!success) err_msg = "Could not create video conversion context";
    }
    
    // Start movie file
    if (success)
    {
        video_stream->time_base = (AVRational){1, TICKS_PER_SECOND};
        audio_stream->time_base = (AVRational){1, mx->obtained.freq};
        avformat_write_header(av->fmt_ctx, NULL);
    }
    
    // set up our threads and intermediate storage
    if (success)
    {
        videobuf.resize(av->video_bufsize);
        audiobuf.resize(2 * 2 * mx->obtained.freq / 30);
	}
	if (success)
	{
		encodeReady = SDL_CreateSemaphore(0);
		fillReady = SDL_CreateSemaphore(1);
		stillEncoding = true;
		success = encodeReady && fillReady;
		if (!success) err_msg = "Could not create movie thread semaphores";
	}
	if (success)
	{
		encodeThread = SDL_CreateThread(Movie_EncodeThread, "MovieSetup_encodeThread", this);
		success = encodeThread;
		if (!success) err_msg = "Could not create movie encoding thread";
	}
	
	if (!success)
	{
		StopRecording();
		std::string full_msg = "Your movie could not be exported. (";
		full_msg += err_msg;
		full_msg += ".)";
        logError(full_msg.c_str());
		alert_user(full_msg.c_str());
	}
    av->inited = success;
	return success;
}
Пример #24
0
	//! starts the thread
	void ThreadSDL::Start(ThreadFunc threadFunc, void* pParam /*= 0*/)
	{
		typedef int SDLThreadFunc(void* pParam);
		m_pThread = SDL_CreateThread((SDLThreadFunc*)threadFunc, 0, pParam);
	}
Пример #25
0
int main(int argn, char** args) {
	srandom(time(NULL));
	printf("main: STARTED\n");

	printf("main: init SDL\n");
	if(SDL_Init(SDL_INIT_EVENTTHREAD)!=0) {
		fprintf(stderr, "main: FATAL ERROR: SDL_Init fails: %s\n", SDL_GetError());
		exit(EXIT_FAILURE);
		}

	if(atexit(SDL_Quit)!=0) {
		fprintf(stderr, "main: FATAL ERROR: couldn't set exit function.\n");
		exit(EXIT_FAILURE);
		}

	if(SDLNet_Init()!=0) {
		fprintf(stderr, "main: FATAL ERROR: SDLNet_Init fails: %s\n", SDLNet_GetError());
		exit(EXIT_FAILURE);
		}

	FILE* file;
	char* path=new char[100];

/*
//	cyberspace_server_data.version_major=0;
//	cyberspace_server_data.version_minor=1;
	cyberspace_server_data.accounts=0;
	int filed;
	sprintf(path, "server_data.now");
	if((file=fopen(path, "w+"))==NULL) {
		perror("perror:\n");
		fprintf(stderr, "FATAL ERROR: unable to fopen file \"%s\"\n", path);
		exit(EXIT_FAILURE);
		}
	if(fwrite(&cyberspace_server_data, sizeof(cyberspace_server_data), 1, file)!=1) {
		fprintf(stderr, "FATAL ERROR: unable to fwrite file \"%s\"\n", path);
		exit(EXIT_FAILURE);
		}
	if((filed=fileno(file))==-1) {
		fprintf(stderr, "FATAL ERROR: unable to fileno file \"%s\"\n", path);
		exit(EXIT_FAILURE);
		}
	if(fdatasync(filed)!=0) {
		fprintf(stderr, "FATAL ERROR: unable to fdatasync file \"%s\"\n", path);
		exit(EXIT_FAILURE);
		}
	if(fclose(file)!=0) {
		fprintf(stderr, "FATAL ERROR: unable to fclose file \"%s\"\n", path);
		exit(EXIT_FAILURE);
		}
	printf("main: ONCE DONE\n");
	exit(EXIT_FAILURE);
*/

	sprintf(path, "server_data.now");
	if((file=fopen(path, "r+"))==NULL) {
		perror("perror:\n");
		fprintf(stderr, "FATAL ERROR: unable to fopen file \"%s\"\n", path);
		exit(EXIT_FAILURE);
		}
	if(fread(&cyberspace_server_data, sizeof(cyberspace_server_data), 1, file)!=1) {
		fprintf(stderr, "FATAL ERROR: unable to fread file \"%s\"\n", path);
		exit(EXIT_FAILURE);
		}
	if(fclose(file)!=0) {
		fprintf(stderr, "FATAL ERROR: unable to fclose file \"%s\"\n", path);
		exit(EXIT_FAILURE);
		}
	printf("main: server_data read\n");

	delete[] path;

	cyberspace_mutex_server_data_sdl=SDL_CreateMutex();

/*
	pthread_attr_t thread_detached;
	pthread_attr_init(&thread_detached);
	pthread_attr_setdetachstate(&thread_detached, PTHREAD_CREATE_DETACHED);
*/


/*
	pthread_t physical_engine;
	if(pthread_create(&physical_engine, &thread_detached, cyberspace_physical_engine_tf, NULL)!=0) {
		fprintf(stderr, "FATAL ERROR: physical_engine thread creation fails.\n");
		exit(EXIT_FAILURE);
		}
*/
	SDL_Thread* physical_engine_thread_sdl;
	physical_engine_thread_sdl=SDL_CreateThread(cyberspace_physical_engine_tf_sdl, NULL);
	if(physical_engine_thread_sdl==NULL) {
		fprintf(stderr, "FATAL ERROR: physical_engine thread creation fails: %s.\n", SDL_GetError());
		exit(EXIT_FAILURE);
		}


/*
	pthread_t frontdoor;
	if(pthread_create(&frontdoor, &thread_detached, cyberspace_frontdoor_tf, NULL)!=0) {
		fprintf(stderr, "FATAL ERROR: frontdoor thread creation fails.\n");
		exit(EXIT_FAILURE);
		}
*/
	SDL_Thread* frontdoor_thread_sdl;
	frontdoor_thread_sdl=SDL_CreateThread(cyberspace_frontdoor_tf_sdl, NULL);
	if(frontdoor_thread_sdl==NULL) {
		fprintf(stderr, "FATAL ERROR: frontdoor thread creation fails: %s.\n", SDL_GetError());
		exit(EXIT_FAILURE);
		}


/*
	pthread_t frontdoor_inputchannel;
	if(pthread_create(&frontdoor_inputchannel, &thread_detached, cyberspace_frontdoor_inputchannel_tf, NULL)!=0) {
		fprintf(stderr, "FATAL ERROR: frontdoor_inputchannel thread creation fails.\n");
		exit(EXIT_FAILURE);
		}
*/
	SDL_Thread* frontdoor_inputchannel_thread_sdl;
	frontdoor_inputchannel_thread_sdl=SDL_CreateThread(cyberspace_frontdoor_inputchannel_tf_sdl, NULL);
	if(frontdoor_inputchannel_thread_sdl==NULL) {
		fprintf(stderr, "FATAL ERROR: frontdoor_inputchannel thread creation fails: %s.\n", SDL_GetError());
		exit(EXIT_FAILURE);
		}

/*
	pthread_t statistics;
	if(pthread_create(&statistics, &thread_detached, cyberspace_statistics_tf, NULL)!=0) {
		fprintf(stderr, "FATAL ERROR: statistics thread creation fails.\n");
		exit(EXIT_FAILURE);
		}
*/
	SDL_Thread* statistics_thread_sdl;
	statistics_thread_sdl=SDL_CreateThread(cyberspace_statistics_tf_sdl, NULL);
	if(statistics_thread_sdl==NULL) {
		fprintf(stderr, "FATAL ERROR: statistics thread creation fails: %s.\n", SDL_GetError());
		exit(EXIT_FAILURE);
		}

	SDL_WaitThread(physical_engine_thread_sdl, NULL);
	SDL_WaitThread(frontdoor_thread_sdl, NULL);
	SDL_WaitThread(frontdoor_inputchannel_thread_sdl, NULL);
	SDL_WaitThread(statistics_thread_sdl, NULL);

	printf("main: ENDING\n");
//	pthread_exit(NULL);
	exit(EXIT_SUCCESS);
	}
Пример #26
0
int main(int argc, char *argv[])
{
    if(pthread_mutex_init(&SimParams::Lock, NULL) != 0)
        Bug(true, "Failed to make mutex");
    SimParams &params = Initialize();

    StartInfo *info = new StartInfo(argc, argv, params);
    SDL_Thread *guiThread = SDL_CreateThread(&StartGUI, info);

    TGRender render(0,0);
    TGResourceManager rec;
    TGResource vs = rec.CreateResource(TGResourceType::Shader, "water.vs");
    TGResource fs = rec.CreateResource(TGResourceType::Shader, "water.fs");
    TGResource bfs = rec.CreateResource(TGResourceType::Shader, "black.fs");
    TGResource envvs = rec.CreateResource(TGResourceType::Shader, "envshader.vs");
    TGResource envfs = rec.CreateResource(TGResourceType::Shader, "envshader.fs");
    TGResource colvs = rec.CreateResource(TGResourceType::Shader, "colors.vs");
    TGResource colfs = rec.CreateResource(TGResourceType::Shader, "colors.fs");
    TGResource cvs = rec.CreateResource(TGResourceType::Shader, "cube.vs");
    TGResource cfs = rec.CreateResource(TGResourceType::Shader, "cube.fs");
    Debug("Got shaders");
    Create(rec.GetData(vs).c_str(), rec.GetData(fs).c_str(), rec.GetData(bfs).c_str(), rec.GetData(envvs).c_str(), rec.GetData(envfs).c_str(),
            rec.GetData(colvs).c_str(), rec.GetData(colfs).c_str(), rec.GetData(cvs).c_str(), rec.GetData(cfs).c_str());

    ChangeSize(render.GetSize().Width, render.GetSize().Height);
    bool running = true;
    
    bool mouse1Down = false;
    int clickMovement = 0;

    while(running)
    {
        SDL_Event event;
        while(SDL_PollEvent(&event))
        {
            switch(event.type)
            {
                case SDL_QUIT:
                    running = false;
                    break;
                case SDL_VIDEORESIZE:
                    render.Resize(event.resize.w, event.resize.h);
                    ChangeSize(event.resize.w, event.resize.h);
                    break;
                case SDL_MOUSEMOTION:
                    clickMovement += abs(event.motion.xrel) + abs(event.motion.yrel);
                    //Debug("Got mouse move with dx=%d, dy=%d", event.motion.xrel, event.motion.yrel);
                    if(mouse1Down)
                        Orbit(event.motion.xrel, event.motion.yrel);
                    break;
                case SDL_MOUSEBUTTONDOWN:
                    Debug("Got mouse down on button %d", event.button.button);
                    if(event.button.button == 1)
                    {
                        clickMovement = 0;
                        mouse1Down = true;
                    }
                    break;
                case SDL_MOUSEBUTTONUP:
                    //Debug("Got mouse up on button %d", event.button.button);
                    if(event.button.button == 1)
                    {
                        if(clickMovement < 5)
                        {
                            Touch(event.button.x, event.button.y);
                        }
                        mouse1Down = false;
                    }
                    break;
                default:
                    break;
            }
        }
        Draw();
        
        render.Present();
    }

    if(pthread_mutex_destroy(&SimParams::Lock) != 0)
        Bug(true, "Failed to destroy mutex");
    return 0;
}
int audio_thr(LPVOID lpParam)
{
	int iRet = -1;
	//音频测试,播放文件显示波形
	AVFormatContext		*	pFmtCtx = NULL;
	AVFormatContext		*	pFOutmtCtx = NULL;
	AVInputFormat		*	pAudioInputFmt = NULL;
	AVOutputFormat		*	pAudioOutputFmt = NULL;
	AVCodecContext		*	pOutputCodecCtx = NULL;
	AVPacket				*	pAudioPacket = NULL;
	int						iAudioIndex = -1;
	int						data_size = 0;
	int						resampled_data_size = 0;
	uint8_t				*	out_buffer = 0;
	int64_t					dec_channel_layout = 0;
	double					pts;

	CLS_DlgStreamPusher* pThis = (CLS_DlgStreamPusher*)lpParam;
	if (pThis == NULL || pThis->m_pStreamInfo == NULL){
		TRACE("audio_thr--pThis == NULL || pThis->m_pStreamInfo == NULL\n");
		return iRet;
	}

	struct_stream_info* strct_stream_info = pThis->m_pStreamInfo;

	pAudioInputFmt = av_find_input_format("dshow");
	if (pAudioInputFmt == NULL){
		TRACE("pAudioInputFmt == NULL\n");
		return iRet;
	}

	char* psDevName = pThis->GetDeviceName(n_Audio);
	if (psDevName == NULL){
		TRACE("audio_thr--psDevName == NULL");
		return iRet;
	}

	if (avformat_open_input(&pFmtCtx, psDevName, pAudioInputFmt, NULL) != 0){
		TRACE("avformat_open_input err!\n");
		goto END;
	}
	if (avformat_find_stream_info(pFmtCtx, NULL) < 0){
		TRACE("avformat_find_stream_info(pFmtCtx, NULL) < 0\n");
		goto END;
	}

	for (int i = 0; i < pFmtCtx->nb_streams; i++){
		if (pFmtCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO){
			iAudioIndex = i;
			AVCodec *tmpCodec = avcodec_find_decoder(pFmtCtx->streams[i]->codec->codec_id);
			if (0 > avcodec_open2(pFmtCtx->streams[i]->codec, tmpCodec, NULL)){
				TRACE("can not find or open decoder!\n");
			}
			break;
		}
	}

	//找到音频流信息
	strct_stream_info->m_pAudioStream = pFmtCtx->streams[iAudioIndex];
	if (strct_stream_info->m_pAudioStream == NULL){
		TRACE("strct_stream_info->m_pAudioStream == NULL\n");
		goto END;
	}

	AVCodecContext *pAudioDec = strct_stream_info->m_pAudioStream->codec;
	if (NULL == pAudioDec){
		TRACE("NULL == pAudioDec\n");
		goto END;
	}

	AVCodec* audio_encoder = avcodec_find_encoder(AV_CODEC_ID_AAC);
	if (audio_encoder == NULL){
		TRACE("audio_encoder == NULL\r\n");
		goto END;
	}

	pOutputCodecCtx = avcodec_alloc_context3(audio_encoder);
	if (pOutputCodecCtx == NULL){
		TRACE("pOutputCodecCtx == NULL");
		goto END;
	}

	pOutputCodecCtx->sample_rate = pFmtCtx->streams[0]->codec->sample_rate;
	pOutputCodecCtx->channel_layout = AV_CH_LAYOUT_STEREO;
	pOutputCodecCtx->channels = av_get_channel_layout_nb_channels(pOutputCodecCtx->channel_layout);
	pOutputCodecCtx->sample_fmt = audio_encoder->sample_fmts[0];
	pOutputCodecCtx->codec = audio_encoder;
	pOutputCodecCtx->codec_tag = 0;
	if (avcodec_open2(pOutputCodecCtx, pOutputCodecCtx->codec, 0) < 0){
		//编码器打开失败,退出程序
		TRACE("音频编码器打开失败!\n");
		goto END;
	}

	//SDL_AudioSpec
	int out_nb_samples = AUDIO_BUF_SIZE;
	AVSampleFormat out_sample_fmt = AV_SAMPLE_FMT_S16;
	int out_buffer_size = av_samples_get_buffer_size(NULL, pOutputCodecCtx->channels, out_nb_samples, out_sample_fmt, 1);
	SDL_AudioSpec wanted_spec, spec;
	wanted_spec.freq = pOutputCodecCtx->sample_rate;
	wanted_spec.format = AUDIO_S16SYS;
	wanted_spec.channels = pOutputCodecCtx->channels;
	wanted_spec.silence = 0;
	wanted_spec.samples = out_nb_samples;
	wanted_spec.callback = fill_audio;//&CLS_DlgStreamPusher::
	wanted_spec.userdata = strct_stream_info;
	strct_stream_info->m_content_out_channels = pOutputCodecCtx->channels;

	if (SDL_OpenAudio(&wanted_spec, &spec)<0){
		TRACE("can't open audio.\n");
		goto END;
	}

	int audio_hw_buf_size = spec.size;
	if (audio_hw_buf_size < 0){
		TRACE("audio_hw_buf_size < 0\n");
		return -1;
	}
	strct_stream_info->m_audio_src.fmt = AV_SAMPLE_FMT_S16;
	strct_stream_info->m_audio_src.freq = spec.freq;
	strct_stream_info->m_audio_src.channel_layout = pOutputCodecCtx->channel_layout;
	strct_stream_info->m_audio_src.channels = spec.channels;
	strct_stream_info->m_audio_hw_buf_size = audio_hw_buf_size;
	strct_stream_info->m_audio_tgt = strct_stream_info->m_audio_src;

	AVPacket pkt;
	out_buffer = (uint8_t *)av_malloc(MAX_AUDIO_FRAME_SIZE * 2);

	strct_stream_info->m_audio_refresh_tid = SDL_CreateThread(audio_refresh_thread, NULL, strct_stream_info);

	while (av_read_frame(pFmtCtx, &pkt) == 0 && _kbhit() == 0){
		if (!pThis->m_blAudioShow){
			break;
		}
		if (pkt.stream_index != iAudioIndex){
			continue;
		}
		if (!strct_stream_info->m_pAudioFrame) {
			if (!(strct_stream_info->m_pAudioFrame = avcodec_alloc_frame())){
				TRACE("!(strct_stream_info->m_pAudioFrame = avcodec_alloc_frame())\n");
				goto END;
			}
		}
		else{
			avcodec_get_frame_defaults(strct_stream_info->m_pAudioFrame);
		}

		int gotframe = -1;
		strct_stream_info->m_pAudioFrame = av_frame_alloc();
		if (avcodec_decode_audio4(pAudioDec, strct_stream_info->m_pAudioFrame, &gotframe, &pkt) < 0){
			av_frame_free(&strct_stream_info->m_pAudioFrame);
			TRACE("can not decoder a frame\n");
			break;
		}
		av_free_packet(&pkt);

		if (!gotframe){
			//没有获取到数据,继续下一次
			continue;
		}
		strct_stream_info->m_pAudioFrame->nb_samples = 1024;//这里暂时写死值
		data_size = av_samples_get_buffer_size(NULL, pOutputCodecCtx->channels,
			strct_stream_info->m_pAudioFrame->nb_samples,
			pOutputCodecCtx->sample_fmt, 1);

		dec_channel_layout =
			(pOutputCodecCtx->channel_layout && pOutputCodecCtx->channels == av_get_channel_layout_nb_channels(pOutputCodecCtx->channel_layout)) ?
			pOutputCodecCtx->channel_layout : av_get_default_channel_layout(pOutputCodecCtx->channels);
		//wanted_nb_samples = SynAudio(strct_stream_info, strct_stream_info->m_pAudioFrame->nb_samples);

		/*if (pOutputCodecCtx->sample_fmt != strct_stream_info->m_audio_src.fmt ||
			dec_channel_layout != strct_stream_info->m_audio_src.channel_layout ||
			pOutputCodecCtx->sample_rate != strct_stream_info->m_audio_src.freq){*/
		swr_free(&strct_stream_info->m_audio_swr_ctx);
		strct_stream_info->m_audio_swr_ctx = swr_alloc_set_opts(NULL,
				strct_stream_info->m_audio_tgt.channel_layout, strct_stream_info->m_audio_tgt.fmt, strct_stream_info->m_audio_tgt.freq,
				dec_channel_layout, pOutputCodecCtx->sample_fmt, pOutputCodecCtx->sample_rate,
				0, NULL);
		if (!strct_stream_info->m_audio_swr_ctx || swr_init(strct_stream_info->m_audio_swr_ctx) < 0){
				TRACE("!pThis->m_pStreamInfstrct_stream_infoo->m_audio_swr_ctx || swr_init(strct_stream_info->m_audio_swr_ctx) < 0");
				break;
			}

			strct_stream_info->m_audio_src.channel_layout = dec_channel_layout;
			strct_stream_info->m_audio_src.channels = pOutputCodecCtx->channels;
			strct_stream_info->m_audio_src.freq = pOutputCodecCtx->sample_rate;
			strct_stream_info->m_audio_src.fmt = pOutputCodecCtx->sample_fmt;
		//}
			if (NULL != strct_stream_info->m_audio_swr_ctx){
			const uint8_t **in = (const uint8_t **)strct_stream_info->m_pAudioFrame->extended_data;
			uint8_t *out[] = { strct_stream_info->m_audio_buf2 };
			int out_count = sizeof(strct_stream_info->m_audio_buf2) / strct_stream_info->m_audio_tgt.channels / av_get_bytes_per_sample(strct_stream_info->m_audio_tgt.fmt);
			int iRet = swr_convert(strct_stream_info->m_audio_swr_ctx, out, out_count, in, strct_stream_info->m_pAudioFrame->nb_samples);
			if (iRet < 0){
				TRACE("swr_convert < 0\n");
				break;
			}
			if (iRet == out_count) {
				TRACE("warning: audio buffer is probably too small\n");
				swr_init(strct_stream_info->m_audio_swr_ctx);
			}
			strct_stream_info->m_audio_buf = strct_stream_info->m_audio_buf2;
			resampled_data_size = iRet * strct_stream_info->m_audio_tgt.channels * av_get_bytes_per_sample(strct_stream_info->m_audio_tgt.fmt);
		}
		else{
			strct_stream_info->m_audio_buf = strct_stream_info->m_pAudioFrame->data[0];
			resampled_data_size = data_size;
		}

		/* if no pts, then compute it */
		pts = strct_stream_info->m_audio_clock;
		//*pts_ptr = pts;
		strct_stream_info->m_audio_clock += (double)data_size /
			(pAudioDec->channels * pAudioDec->sample_rate * av_get_bytes_per_sample(pAudioDec->sample_fmt));
#ifdef DEBUG
		{
			static double last_clock;
			/*printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
				is->audio_clock - last_clock,
				is->audio_clock, pts);*/
			last_clock = strct_stream_info->m_audio_clock;
		}
#endif

		//FIX:FLAC,MP3,AAC Different number of samples
		/*if (wanted_spec.samples != strct_stream_info->m_pAudioFrame->nb_samples){
			SDL_CloseAudio();
			out_nb_samples = strct_stream_info->m_pAudioFrame->nb_samples;
			out_buffer_size = av_samples_get_buffer_size(NULL, pOutputCodecCtx->channels, out_nb_samples, out_sample_fmt, 1);
			wanted_spec.samples = out_nb_samples;
			SDL_OpenAudio(&wanted_spec, NULL);
		}*/

		//设置PCM数据
		TRACE("----out_buffer_size---is [%ld]\n",out_buffer_size);
		audio_chunk = (Uint8 *)out_buffer;
		audio_len = out_buffer_size;
		audio_pos = audio_chunk;

		strct_stream_info->m_aduio_pkt_size = resampled_data_size;//audio_len;//

		av_free_packet(&pkt);

		//写PCM进行test
		if (1){
			FILE *p = NULL;
			fopen_s(&p, "test.pcm", "a+b");
			if (p == NULL){
				continue;
			}
			int tempLenght = 2 * strct_stream_info->m_pAudioFrame->nb_samples;//由于实验中知道这是16位深,所以才这么写
			uint8_t *tmpPtr = strct_stream_info->m_pAudioFrame->data[0];
			if (NULL != p)
			{
				while (tempLenght > 0)
				{
					size_t temp = fwrite(tmpPtr, 1, tempLenght, p);
					tmpPtr += temp;
					tempLenght = tempLenght - temp;
				}
				fclose(p);
			}
		}

		SDL_PauseAudio(0);
		//while (audio_len > 0){
		//	//Wait until finish
		//	SDL_Delay(1);
		//}

		//if (pFmtCtx->streams[iAudioIndex]->codec->sample_fmt != pOutputCodecCtx->sample_fmt
		//	|| pFmtCtx->streams[iAudioIndex]->codec->channels != pOutputCodecCtx->channels
		//	|| pFmtCtx->streams[iAudioIndex]->codec->sample_rate != pOutputCodecCtx->sample_rate){
		//	//TODO如果输入和输出的音频格式不一样 需要重采样,这里是一样的就没做
		//}

		//av_audio_fifo_realloc(fifo, av_audio_fifo_size(fifo) + frame->nb_samples);
		//av_audio_fifo_write(fifo, (void **)frame->data, frame->nb_samples);

		////循环读取数据,直到buf里数据采样数不够
		//while (av_audio_fifo_size(fifo) >= (pOutputCodecCtx->frame_size > 0 ? pOutputCodecCtx->frame_size : AUDIO_BUF_SIZE))
		//{
		//	av_frame_free(&frame);
		//	frame = av_frame_alloc();
		//	frame->nb_samples = pOutputCodecCtx->frame_size>0 ? pOutputCodecCtx->frame_size : AUDIO_BUF_SIZE;
		//	frame->channel_layout = pOutputCodecCtx->channel_layout;
		//	frame->format = pOutputCodecCtx->sample_fmt;
		//	frame->sample_rate = pOutputCodecCtx->sample_rate;
		//	av_frame_get_buffer(frame, 0);

		//	av_audio_fifo_read(fifo, (void **)frame->data, (pOutputCodecCtx->frame_size > 0 ? pOutputCodecCtx->frame_size : AUDIO_BUF_SIZE));
		//	av_init_packet(&pkt_out);
		//	//frame->pts = pFrame->pts;
		//	int got_picture = -1;
		//	pkt_out.data = NULL;
		//	pkt_out.size = 0;
		//	if (avcodec_encode_audio2(pOutputCodecCtx, &pkt_out, frame, &got_picture) < 0){
		//		printf("can not decoder a frame");
		//	}
		//	av_frame_free(&frame);
		//	if (got_picture)
		//	{
		//		pkt_out.pts = frameIndex * pOutputCodecCtx->frame_size;
		//		pkt_out.dts = frameIndex * pOutputCodecCtx->frame_size;
		//		pkt_out.duration = pOutputCodecCtx->frame_size;

		//		//TODO将编码结果后续做合成处理[pkt_out]
		//		if (pFile != NULL){
		//			/*fwrite((uint8_t *)pDlg->m_streamstate->audio_buf + pDlg->m_streamstate->audio_buf_index, 1, len1, pFile);*/
		//		}
		//		frameIndex++;
		//	}
		//}
	}
	iRet = 1;

END:
	//swr_free(&au_convert_ctx);
	SDL_CloseAudio();
	SDL_Quit();
	av_free(out_buffer);
	avcodec_close(pOutputCodecCtx);

	return iRet;
}
Пример #28
0
int main(int argc, char *argv[])
{
    SDL_Event       event;
    VideoState      *is;
    is = (VideoState *)av_mallocz(sizeof(VideoState));
    if(argc < 2)
    {
        fprintf(stderr, "Usage: test <file>\n");
        exit(1);
    }
    // Register all formats and codecs
    av_register_all();
    if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER))
    {
        fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
        exit(1);
    }

    // Make a screen to put our video
#ifndef __DARWIN__
    screen = SDL_SetVideoMode(1280, 720, 0, 0);
#else
    screen = SDL_SetVideoMode(640, 480, 24, 0);
#endif
    if(!screen)
    {
        fprintf(stderr, "SDL: could not set video mode - exiting\n");
        exit(1);
    }

    //pstrcpy(is->filename, sizeof(is->filename), argv[1]);
    strcpy(is->filename,argv[1]);
    is->pictq_mutex = SDL_CreateMutex();
    is->pictq_cond = SDL_CreateCond();

    schedule_refresh(is, 40);
    is->av_sync_type = DEFAULT_AV_SYNC_TYPE;

    is->parse_tid = SDL_CreateThread(decode_thread, is);
    if(!is->parse_tid)
    {
        av_free(is);
        return -1;
    }
    for(;;)
    {
        double incr, pos;
        SDL_WaitEvent(&event);
        switch(event.type)
        {
        case SDL_KEYDOWN:
            switch(event.key.keysym.sym)
            {
            case SDLK_LEFT:
                incr = -10.0;
                goto do_seek;
            case SDLK_RIGHT:
                incr = 10.0;
                goto do_seek;
            case SDLK_UP:
                incr = 60.0;
                goto do_seek;
            case SDLK_DOWN:
                incr = -60.0;
                goto do_seek;
do_seek:
                if(global_video_state)
                {
                    pos = get_master_clock(global_video_state);
                    pos += incr;
                    stream_seek(global_video_state, (int64_t)(pos * AV_TIME_BASE), incr);
                }
                break;
            default:
                break;
            }
            break;
        case FF_QUIT_EVENT:
        case SDL_QUIT:
            is->quit = 1;
            SDL_Quit();
            exit(0);
            break;
        case FF_ALLOC_EVENT:
            alloc_picture(event.user.data1);
            break;
        case FF_REFRESH_EVENT:
            video_refresh_timer(event.user.data1);
            break;
        default:
            break;
        }
    }
    return 0;
}
Пример #29
0
// For performance, we're using multiple threads so that the game state can
// be updating in the background while openGL renders.
// The general plan is:
// 1. Vsync happens.  Everything begins.
// 2. Renderthread activates.  (The update thread is currently blocked.)
// 3. Renderthread dumps everything into opengl, via RenderAllEntities.  (And
//    any other similar calls, such as calls to IMGUI)  Updatethread is
//    still blocked.  When this is complete, OpenGL now has its own copy of
//    everything, and we can safely change world state data.
// 4. Renderthread signals updatethread to wake up.
// 5a.Renderthread calls gl_flush, (via Renderer.advanceframe) and waits for
//    everything render.  Once complete, it goes to sleep and waits for the
//    next vsync event.
// 5b.Updatethread goes and updates the game state and gets us all ready for
//    next frame.  Once complete, it also goes to sleep and waits for the next
//    vsync event.
void Game::Run() {
  // Start the update thread:
  UpdateThreadData rt_data(&game_exiting_, &world_, &state_machine_, &renderer_,
                           &input_, &audio_engine_, &sync_);

  input_.AdvanceFrame(&renderer_.window_size());
  state_machine_.AdvanceFrame(16);

  SDL_Thread* update_thread =
      SDL_CreateThread(UpdateThread, "Zooshi Update Thread", &rt_data);
  if (!update_thread) {
    LogError("Error creating update thread.");
    assert(false);
  }

#if DISPLAY_FRAMERATE_HISTOGRAM
  for (int i = 0; i < kHistogramSize; i++) {
    histogram[i] = 0;
  }
  last_printout = 0;
#endif  // DISPLAY_FRAMERATE_HISTOGRAM

  // variables used for regulating our framerate:
  // Total size of our history, in frames:
  const int kHistorySize = 60 * 5;
  // Max number of frames we can have dropped in our history, before we
  // switch to queue-stuffing mode, and ignore vsync pauses.
  const int kMaxDroppedFrames = 3;
  // Variable
  bool missed_frame_history[kHistorySize];
  for (int i = 0; i < kHistorySize; i++) {
    missed_frame_history[i] = false;
  }
  int history_index = 0;
  int total_dropped_frames = 0;

  global_vsync_context = &sync_;
#ifdef __ANDROID__
  fplbase::RegisterVsyncCallback(HandleVsync);
#else
  // We don't need this on android because we'll just get vsync events directly.
  SDL_Thread* vsync_simulator_thread = SDL_CreateThread(
      VsyncSimulatorThread, "Zooshi Simulated Vsync Thread", nullptr);
  if (!vsync_simulator_thread) {
    LogError("Error creating vsync simulator thread.");
    assert(false);
  }
#endif  // __ANDROID__
  int last_frame_id = 0;

  // We basically own the lock all the time, except when we're waiting
  // for a vsync event.
  SDL_LockMutex(sync_.renderthread_mutex_);
  while (!game_exiting_) {
#ifdef __ANDROID__
    int current_frame_id = fplbase::GetVsyncFrameId();
#else
    int current_frame_id = 0;
#endif  // __ANDROID__
    // Update our framerate history:
    // The oldest value falls off and is replaced with the most recent frame.
    // Also, we update our counts.
    if (missed_frame_history[history_index]) {
      total_dropped_frames--;
    }
    // We count it as a dropped frame if more than one vsync event passed since
    // we started rendering it.  The check is implemented via equality
    // comparisons because current_frame_id will eventually wrap.)
    missed_frame_history[history_index] =
        (current_frame_id != last_frame_id + 1) &&
        (current_frame_id != last_frame_id);
    if (missed_frame_history[history_index]) {
      total_dropped_frames++;
    }
    history_index = (history_index + 1) % kHistorySize;
    last_frame_id = current_frame_id;

    // -------------------------------------------
    // Steps 1, 2.
    // Wait for start of frame.  (triggered at vsync start on android.)
    // For performance, we only wait if we're not dropping frames.  Otherwise,
    // we just keep rendering as fast as we can and stuff the render queue.
    if (total_dropped_frames <= kMaxDroppedFrames) {
      SDL_CondWait(sync_.start_render_cv_, sync_.renderthread_mutex_);
    }

    // Grab the lock to make sure the game isn't still updating.
    SDL_LockMutex(sync_.gameupdate_mutex_);

    SystraceBegin("RenderFrame");

    // Input update must happen from the render thread.
    // From the SDL documentation on SDL_PollEvent(),
    // https://wiki.libsdl.org/SDL_PollEvent):
    // "As this function implicitly calls SDL_PumpEvents(), you can only call
    // this function in the thread that set the video mode."
    SystraceBegin("Input::AdvanceFrame()");
    input_.AdvanceFrame(&renderer_.window_size());
    game_exiting_ |= input_.exit_requested();
    SystraceEnd();

    // Milliseconds elapsed since last update.
    rt_data.frame_start = CurrentWorldTimeSubFrame(input_);

    // -------------------------------------------
    // Step 3.
    // Render everything.
    // -------------------------------------------
    SystraceBegin("StateMachine::Render()");

    fplbase::RenderTarget::ScreenRenderTarget(renderer_).SetAsRenderTarget();
    renderer_.ClearDepthBuffer();
    renderer_.SetCulling(fplbase::Renderer::kCullBack);

    state_machine_.Render(&renderer_);
    SystraceEnd();

    SDL_UnlockMutex(sync_.gameupdate_mutex_);

    SystraceBegin("StateMachine::HandleUI()");
    state_machine_.HandleUI(&renderer_);
    SystraceEnd();

    // -------------------------------------------
    // Step 4.
    // Signal the update thread that it is safe to start messing with
    // data, now that we've already handed it all off to openGL.
    // -------------------------------------------
    SDL_CondBroadcast(sync_.start_update_cv_);

    // -------------------------------------------
    // Step 5a.
    // Start openGL actually rendering.  AdvanceFrame will (among other things)
    // trigger a gl_flush.  This thread will block until it is completed,
    // but that's ok because the update thread is humming in the background
    // preparing the worlds tate for next frame.
    // -------------------------------------------
    SystraceBegin("AdvanceFrame");
    renderer_.AdvanceFrame(input_.minimized(), input_.Time());
    SystraceEnd();  // AdvanceFrame

    SystraceEnd();  // RenderFrame

    gpg_manager_.Update();

    // Process input device messages since the last game loop.
    // Update render window size.
    if (input_.GetButton(fplbase::FPLK_BACKQUOTE).went_down()) {
      ToggleRelativeMouseMode();
    }

    int new_time = CurrentWorldTimeSubFrame(input_);
    int frame_time = new_time - rt_data.frame_start;
#if DISPLAY_FRAMERATE_HISTOGRAM
    UpdateProfiling(frame_time);
#endif  // DISPLAY_FRAMERATE_HISTOGRAM

    SystraceCounter("FrameTime", frame_time);
  }
  SDL_UnlockMutex(sync_.renderthread_mutex_);
// Clean up asynchronous callbacks to prevent crashing on garbage data.
#ifdef __ANDROID__
  fplbase::RegisterVsyncCallback(nullptr);
#endif  // __ANDROID__
  input_.AddAppEventCallback(nullptr);
}
Пример #30
0
int XyEngine::CreateWindow(int width, int height, char* title, float frameRate)
{
	double StartTime = Time::GetTime();
	Log("XyEngine is Loading...");
	
	this->m_windowWidth = width;
	this->m_windowHeight = height;

	this->m_middleWidth = m_windowWidth / 2;
	this->m_middleHeight = m_windowHeight / 2;

	this->m_FrameRate = frameRate;
	this->m_frameTime = 1.0 / this->m_FrameRate;

	if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
		return ReturnWithError("SDL Failed To Init!");

	m_Window = SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, m_windowWidth, m_windowHeight, SDL_WINDOW_OPENGL);

	if (m_Window == NULL)
	{
		SDL_Quit();
		return ReturnWithError("SDL Failed To Create the Window!");
	}

	glcontext = SDL_GL_CreateContext(m_Window);

	if (glewInit() != GLEW_OK)
		return ReturnWithError("GLEW Failed to Init!");

	if (TTF_Init() != 0)
		return ReturnWithError("TTF Failed to Init!");

	if (!IMG_Init(IMG_INIT_JPG | IMG_INIT_PNG))
		return ReturnWithError("IMG Failed to Init!");

	m_running = true;

	double lastTime = Time::GetTime();
	double unprocessedTime = 0;
	double frameCounter = 0;
	frames = 0;

	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glEnable(GL_MULTISAMPLE_ARB);

	m_InitFunc();

	m_pPhysicsThread = SDL_CreateThread(StaticPhysicsThread, "PhysicsThread", this);

	if (NULL == m_pPhysicsThread) {
		ReturnWithError("Physics Thread Failed to create");
	}
	else
	{
		Log("Physics Thread Created");
	}

	double EndTime = Time::GetTime() - StartTime;
	std::cout << "Time Taken to load XyEngine: " << EndTime << std::endl;

	SDL_Event event;

	while (m_running)
	{
		bool render = false;

		double startTime = Time::GetTime();
		double passedTime = startTime - lastTime;
		lastTime = startTime;

		unprocessedTime += passedTime;
		frameCounter += passedTime;

		if (frameCounter >= 1.0)
		{
			fpsRate = frames;
			frames = 0;
			frameCounter = 0;
		}

		while (unprocessedTime > m_frameTime)
		{
			render = true;

			while (SDL_PollEvent(&event))
			{
				m_InputFunc(event);

				switch (event.type)
				{

				case SDL_QUIT:
					m_running = false;
					break;

				case SDL_MOUSEBUTTONDOWN:
					mousein = true;
					SDL_ShowCursor(SDL_DISABLE);
					break;

				case SDL_KEYDOWN:
					switch (event.key.keysym.sym)
					{
					case SDLK_ESCAPE:
						mousein = false;
						SDL_ShowCursor(SDL_ENABLE);
						break;
					}
				}
			}

			unprocessedTime -= m_frameTime;
		}

		if (render)
		{
			if (mousein)
				SDL_WarpMouseInWindow(m_Window, m_middleWidth, m_middleHeight);

			m_RenderFunc();
			SDL_GL_SwapWindow(m_Window);
			frames++;
		}
		else
		{
			SDL_Delay(1);
		}
	}


	return EXIT_SUCCESS;
}