예제 #1
0
qtsdl2::qtsdl2(QWidget *parent, Qt::WFlags flags)
	: QWidget(parent, flags)
{
	
	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) {
		puts("# error initializing SDL");
		puts(SDL_GetError());
		return ;
	}
	ui.setupUi(this);
	resize(600, 400);
 	m_Cap = new CvCapture_FFMPEG;
	//m_Cap->open("rtsp://159.99.251.194/");
	m_Cap->open("r.mp4");
	m_SdlWin = SDL_CreateWindowFrom((void *)this->winId());
	/*  0 stand for direct3d */
	m_SdlRender = SDL_CreateRenderer(m_SdlWin, 0, 
		0);
	int w = width();
	int h = height();
	m_pTex = SDL_CreateTexture(m_SdlRender, SDL_PIXELFORMAT_RGB24, 
		SDL_TEXTUREACCESS_STREAMING, width(), height());


	m_UpdateSize = false;
	m_SdlThread = new tthread::thread(qtsdl2::Run, (void *)this);
}
예제 #2
0
WindowContext::WindowContext(const unsigned int windowID,
              void *windowHandle)
    : m_windowID(windowID)
    , m_readerThreads(4)
    , m_decoderThreads(4)
{
    m_sdlWindow = SDL_CreateWindowFrom(windowHandle);
    m_sdlRenderer = SDL_CreateRenderer(m_sdlWindow, -1, SDL_RENDERER_ACCELERATED);
}
예제 #3
0
bool ffplayer::CreateRender()
{
	std::lock_guard<std::recursive_mutex> lock(g_mutexSDL);
	m_sdlWindow = SDL_CreateWindowFrom((void*)m_hwnd);

	//	SDL_ShowWindow(sdlWindow);
		//获取当前可用画图驱动 window中有3个,第一个为d3d,第二个为opengl,第三个为software
		//创建渲染器,第二个参数为选用的画图驱动,0代表d3d
	if (m_sdlWindow)
	 m_pRender = SDL_CreateRenderer(m_sdlWindow, 0, SDL_RENDERER_ACCELERATED);

   return true;
}
예제 #4
0
	static int lua_SDL_CreateWindowFrom(State & state){
		Stack * stack = state.stack;
		Window * interfaceWindow = state.getInterface<Window>("LuaSDL_Window");
		if (stack->is<LUA_TLIGHTUSERDATA>(1)){
			void * data = stack->to<void*>(1);
			if (data){
				SDL_Window * window = SDL_CreateWindowFrom(data);
				if (window){
					interfaceWindow->push(window);
					return 1;
				}
			}
		}
		return 0;
	}
int
main(int argc, char *argv[])
{
    int i, done;
    const char *driver;
    SDL_Window *window;
    SDL_Texture *sprite;
    int window_w, window_h;
    int sprite_w, sprite_h;
    SDL_Event event;

    if (SDL_VideoInit(NULL, 0) < 0) {
        fprintf(stderr, "Couldn't initialize SDL video: %s\n",
                SDL_GetError());
        exit(1);
    }
    driver = SDL_GetCurrentVideoDriver();

    /* Find a native window driver and create a native window */
    for (i = 0; factories[i]; ++i) {
        if (SDL_strcmp(driver, factories[i]->tag) == 0) {
            factory = factories[i];
            break;
        }
    }
    if (!factory) {
        fprintf(stderr, "Couldn't find native window code for %s driver\n",
                driver);
        quit(2);
    }
    printf("Creating native window for %s driver\n", driver);
    native_window = factory->CreateNativeWindow(WINDOW_W, WINDOW_H);
    if (!native_window) {
        fprintf(stderr, "Couldn't create native window\n");
        quit(3);
    }
    window = SDL_CreateWindowFrom(native_window);
    if (!window) {
        fprintf(stderr, "Couldn't create SDL window: %s\n", SDL_GetError());
        quit(4);
    }
    SDL_SetWindowTitle(window, "SDL Native Window Test");

    /* Create the renderer */
    if (SDL_CreateRenderer(window, -1, 0) < 0) {
        fprintf(stderr, "Couldn't create renderer: %s\n", SDL_GetError());
        quit(5);
    }

    /* Clear the window, load the sprite and go! */
    SDL_SelectRenderer(window);
    SDL_SetRenderDrawColor(0xA0, 0xA0, 0xA0, 0xFF);
    SDL_RenderClear();

    sprite = LoadSprite(window, "icon.bmp");
    if (!sprite) {
        quit(6);
    }

    /* Allocate memory for the sprite info */
    SDL_GetWindowSize(window, &window_w, &window_h);
    SDL_QueryTexture(sprite, NULL, NULL, &sprite_w, &sprite_h);
    positions = (SDL_Rect *) SDL_malloc(NUM_SPRITES * sizeof(SDL_Rect));
    velocities = (SDL_Rect *) SDL_malloc(NUM_SPRITES * sizeof(SDL_Rect));
    if (!positions || !velocities) {
        fprintf(stderr, "Out of memory!\n");
        quit(2);
    }
    srand(time(NULL));
    for (i = 0; i < NUM_SPRITES; ++i) {
        positions[i].x = rand() % (window_w - sprite_w);
        positions[i].y = rand() % (window_h - sprite_h);
        positions[i].w = sprite_w;
        positions[i].h = sprite_h;
        velocities[i].x = 0;
        velocities[i].y = 0;
        while (!velocities[i].x && !velocities[i].y) {
            velocities[i].x = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED;
            velocities[i].y = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED;
        }
    }

    /* Main render loop */
    done = 0;
    while (!done) {
        /* Check for events */
        while (SDL_PollEvent(&event)) {
            switch (event.type) {
            case SDL_WINDOWEVENT:
                switch (event.window.event) {
                case SDL_WINDOWEVENT_EXPOSED:
                    SDL_SelectRenderer(event.window.windowID);
                    SDL_SetRenderDrawColor(0xA0, 0xA0, 0xA0, 0xFF);
                    SDL_RenderClear();
                    break;
                }
                break;
            case SDL_QUIT:
                done = 1;
                break;
            default:
                break;
            }
        }
        MoveSprites(window, sprite);
    }

    quit(0);
}
예제 #6
0
int CVideoDecoder::open(void)
{
	int ret = 0;
	bOpen = true;
	pFormatCtx = avformat_alloc_context();
	const int BUF_LEN = (1024 * 200);
	iobuffer = (unsigned char *)av_malloc(BUF_LEN);
	avio = avio_alloc_context(iobuffer, BUF_LEN, 0, this, fill_iobuffer, NULL, NULL);
	pFormatCtx->pb = avio;
	if (avformat_open_input(&pFormatCtx, NULL, NULL, NULL) != 0){
		bOpen = false;
		return -1; // Couldn't open file
	}

	// Retrieve stream information
	if (avformat_find_stream_info(pFormatCtx, NULL)<0){
		bOpen = false;
		return -1; // Couldn't find stream information
	}

	// Find the first video stream
	videoStream = -1;
	unsigned int i;
	for (i = 0; i<pFormatCtx->nb_streams; i++)
	if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
		videoStream = i;
		break;
	}
	if (videoStream == -1){
		bOpen = false;
		return -1; // Didn't find a video stream
	}
	/*AV_SAMPLE_FMT_S16;*/
	// Get a pointer to the codec context for the video stream
	pCodecCtxOrig = pFormatCtx->streams[videoStream]->codec;
	if (!pCodecCtxOrig){
		fprintf(stderr, "Unsupported codec!\n");
		bOpen = false;
		return -1; // Codec not found
	}
	// Find the decoder for the video stream
	pCodec = avcodec_find_decoder(pCodecCtxOrig->codec_id);
	if (pCodec == NULL) {
		fprintf(stderr, "Unsupported codec!\n");
		bOpen = false;
		return -1; // Codec not found
	}

	// Copy context
	pCodecCtx = avcodec_alloc_context3(pCodec);
	if (avcodec_copy_context(pCodecCtx, pCodecCtxOrig) != 0) {
		fprintf(stderr, "Couldn't copy codec context");
		bOpen = false;
		return -1; // Error copying codec context
	}

	// Open codec
	if (avcodec_open2(pCodecCtx, pCodec, NULL)<0){
		bOpen = false;
		return -1; // Could not open codec
	}

	// Allocate video frame
	pFrame = av_frame_alloc();
	pFrameYUV = av_frame_alloc();

	// Make a screen to put our video
	if (hWin){
		screen = SDL_CreateWindowFrom(hWin);
		RECT rc;
		GetClientRect(hWin, &rc);
		SDL_SetWindowSize(screen, rc.right - rc.left, rc.bottom - rc.top);
		rect_dst.x = rect_dst.y = 0;
		rect_dst.w = rc.right - rc.left;
		rect_dst.h = rc.bottom - rc.top;
	} else
		screen = SDL_CreateWindow("",
			SDL_WINDOWPOS_UNDEFINED,
			SDL_WINDOWPOS_UNDEFINED,
			pCodecCtx->width, pCodecCtx->height,
			0);
	renderer = SDL_CreateRenderer(screen, -1, 0);
	if (!screen) {
		fprintf(stderr, "SDL: could not set video mode - exiting\n");
		bOpen = false;
		return -1;;
	}

	// Allocate a place to put our YUV image on that screen
	texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_IYUV /*SDL_PIXELFORMAT_YV12*/,
		SDL_TEXTUREACCESS_STREAMING,
		pCodecCtx->width, pCodecCtx->height);

	// initialize SWS context for software scaling
	sws_ctx = sws_getContext(pCodecCtx->width,
		pCodecCtx->height,
		pCodecCtx->pix_fmt,
		pCodecCtx->width,
		pCodecCtx->height,
		PIX_FMT_YUV420P,
		SWS_BILINEAR,
		NULL,
		NULL,
		NULL
		);

	int numBytes = avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width,
		pCodecCtx->height);
	uint8_t* buffer = (uint8_t *)av_malloc(numBytes*sizeof(uint8_t));

	avpicture_fill((AVPicture *)pFrameYUV, buffer, PIX_FMT_YUV420P,
		pCodecCtx->width, pCodecCtx->height);

	bOpen = true;
	//bStop = false;
	//start();
	return ret;
}
void CLS_DlgStreamPusher::InitDlgItem()
{
	//进行界面信息的初始化操作
	//默认是网络流推送
	m_chkSrcType.SetCheck(1);

	m_blUrl = TRUE;
	m_edtLocalFilePath.EnableWindow(FALSE);
	m_btnOpenLocalFile.EnableWindow(FALSE);

	if (NULL == m_bkBrush)
	{
		m_bkBrush = CreateSolidBrush(COLOR_BLACK);
	}

	//初始化网络库
	av_register_all();
	avformat_network_init();
	avdevice_register_all();

	//初始化directshow库
	if (FAILED(CoInitialize(NULL))){
		TRACE("CoInitialize Failed!\r\n");
		return;
	}

	//获取当前连接的视频设备
	int iRet= GetDeviceInfo(n_Video);
	if (iRet < 0){
		TRACE("获取视频设备失败!");
		return;
	}

	//获取当前连接输入的音频设备
	iRet = GetDeviceInfo(n_Audio);
	if (iRet < 0){
		TRACE("获取音频设备失败!");
		return;
	}

	//将获取到的设备信息插入下拉框中
	std::map<int, std::vector<std::string>>::iterator iter = m_mapDeviceInfo.begin();
	for (; iter != m_mapDeviceInfo.end(); iter ++){
		if (n_Video == iter->first){
			//视频设备
			for (int i = 0; i < iter->second.size(); i ++){
				int iCount = m_cboDeviceVideo.GetCount();
				m_cboDeviceVideo.InsertString(iCount, iter->second[i].c_str());
			}
			m_cboDeviceVideo.SetCurSel(0);
		}
		else if (n_Audio == iter->first){
			//音频设备
			for (int i = 0; i < iter->second.size(); i ++){
				int iCount = m_cboDeviceAudio.GetCount();
				m_cboDeviceAudio.InsertString(iCount, iter->second[i].c_str());
			}
			m_cboDeviceAudio.SetCurSel(0);
		}
	}

	//SDL初始化
	int flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
	int  sdlinit = SDL_Init(flags);
	if (sdlinit)
	{
		char * sss = (char*)SDL_GetError();
		fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
		fprintf(stderr, "(Did you set the DISPLAY variable?)\n");
		return;
	}

	//将CSTATIC控件和sdl显示窗口关联 
	HWND hWnd = this->GetDlgItem(IDC_STC_PREVIEW)->GetSafeHwnd();
	if (hWnd != NULL)
	{
		if (m_pStreamInfo != NULL){
			m_pStreamInfo->m_show_screen = SDL_CreateWindowFrom((void*)hWnd);
			if (m_pStreamInfo->m_show_screen == NULL){
				TRACE("SDL_CreateWindowFrom ERR(%d)\n", SDL_GetError());
				return;
			}

			RECT rectDisPlay;
			this->GetDlgItem(IDC_STC_PREVIEW)->GetWindowRect(&rectDisPlay);
			m_pStreamInfo->m_xleft = rectDisPlay.left;
			m_pStreamInfo->m_ytop = rectDisPlay.top;
			m_pStreamInfo->m_width = rectDisPlay.right - rectDisPlay.left;
			m_pStreamInfo->m_height = rectDisPlay.bottom - rectDisPlay.top;

			//处理显示区域
			FillDisplayRect();

			m_pStreamInfo->m_sdlRenderer = SDL_CreateRenderer(m_pStreamInfo->m_show_screen, -1, 0);
			if (m_pStreamInfo->m_sdlRenderer == NULL){
				TRACE("SDL_CreateRenderer--sdlRenderer == NULL err(%d)\n", SDL_GetError());
				return;
			}
		} 
	}

	//设置SDL事件状态
	SDL_EventState(SDL_WINDOWEVENT, SDL_IGNORE);
	SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
	SDL_EventState(SDL_USEREVENT, SDL_IGNORE);

	if (m_pThreadEvent == NULL){
		m_pThreadEvent = AfxBeginThread(Thread_Event, this);//开启线程
	}

	m_edtPusherAddr.SetWindowText("rtmp://5380.lsspublish.aodianyun.com/Young/stream");

	return;
}
예제 #8
0
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
	static int width;
	static int height;
	static int open = 0;

	static TCHAR fullPath[MAX_PATH];
	static TCHAR fileName[MAX_PATH];
	static char u8FullPath[MAX_PATH];

	static RECT windowRect;
	static RECT deskRect;
	static HWND deskHwnd;

	static int fullScreen = 0;
	static long windowStyle;

	static SDL_Window *sdlWindow = 0;
	static SDL_Renderer *sdlRenderer = 0;
	static SDL_Surface *sdlSurface = 0;
	static SDL_Texture *sdlTexture = 0;
	static SDL_Rect sdlShowRect;	//窗口中显示图像的具体区域

	switch (message) {
	case WM_CREATE:
		sdlWindow = SDL_CreateWindowFrom(hwnd);
		sdlRenderer = SDL_CreateRenderer(sdlWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
		sdlSurface = SDL_LoadBMP("PictureViewer.bmp");
		sdlTexture = SDL_CreateTextureFromSurface(sdlRenderer, sdlSurface);
		SDL_FreeSurface(sdlSurface);
		break;
	case WM_SIZE:
		if (open == 0) {
			SDL_RenderClear(sdlRenderer);
			SDL_RenderCopy(sdlRenderer, sdlTexture, 0, 0);
			SDL_RenderPresent(sdlRenderer);
		}
		else {
			sdlShowRect = SetShowRect(hwnd, width, height);
			SDL_RenderClear(sdlRenderer);
			SDL_RenderCopy(sdlRenderer, sdlTexture, 0, &sdlShowRect);
			SDL_RenderPresent(sdlRenderer);
		}
		break;
	case WM_LBUTTONDBLCLK:
		if (!fullScreen) {
			windowStyle = GetWindowLong(hwnd, GWL_STYLE);
			GetWindowRect(hwnd, &windowRect);
			deskHwnd = GetDesktopWindow();
			GetWindowRect(deskHwnd, &deskRect);
			SetWindowLong(hwnd, GWL_STYLE, WS_CHILD);
			SetWindowPos(hwnd, HWND_TOP, 0, 0, deskRect.right, deskRect.bottom, SWP_SHOWWINDOW);
			fullScreen = 1;
		}
		else {
			SetWindowLong(hwnd, GWL_STYLE, windowStyle);
			MoveWindow(hwnd, windowRect.left, windowRect.top, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, true);
			fullScreen = 0;
		}
		break;
	case WM_LBUTTONDOWN:
		open = 1;
		SDL_DestroyTexture(sdlTexture);
		if (!OpenFile(hwnd, fullPath, fileName,&sdlShowRect)) {
			return -1;
		}
		WideCharToMultiByte(CP_UTF8,0, fullPath,-1, u8FullPath, sizeof(u8FullPath),0,0);
		sdlSurface = IMG_Load(u8FullPath);
		width = sdlSurface->w;
		height = sdlSurface->h;
		sdlShowRect = SetShowRect(hwnd, width, height);
		sdlTexture = SDL_CreateTextureFromSurface(sdlRenderer, sdlSurface);
		SDL_FreeSurface(sdlSurface);
		SDL_RenderClear(sdlRenderer);
		SDL_RenderCopy(sdlRenderer, sdlTexture, 0, &sdlShowRect);
		SDL_RenderPresent(sdlRenderer);
		break;
	case WM_CLOSE:
		SDL_DestroyTexture(sdlTexture);
		SDL_DestroyRenderer(sdlRenderer);
		SDL_DestroyWindow(sdlWindow);
		DestroyWindow(hwnd);
		break;
	case WM_DESTROY:
		SDL_Quit();
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hwnd, message, wParam, lParam);
	}
	return 0;
}
예제 #9
0
/**
    \fn init
*/
bool sdlRenderImpl::init( GUI_WindowInfo * window, uint32_t w, uint32_t h,renderZoom zoom)
{
    ADM_info("[SDL] Initializing video subsystem\n");

    int bpp;
    int flags;
    baseInit(w,h,zoom);

    if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
    {
        ADM_warning("[SDL] FAILED initialising video subsystem\n");
        ADM_warning("[SDL] ERROR: %s\n", SDL_GetError());
        return false;
    }
    ADM_info("[SDL] Video subsystem init ok\n");

    sdl_running=true;
    ADM_info("[SDL] Creating window (at %x,%d)\n",window->x,window->y);
    
    int nbDriver=listOfSDLDrivers.size();
    if(!nbDriver)
    {
        ADM_warning("[SDL] No driver loaded\n");
        return false;
    }
    if(sdlDriverIndex==-1 || sdlDriverIndex>=nbDriver)
    {
        ADM_warning("[SDL] No available driver found\n");
        return false;
    }
    
#if 0
    sdl_window = SDL_CreateWindow("avidemux_sdl2",
                          SDL_WINDOWPOS_UNDEFINED,
                          SDL_WINDOWPOS_UNDEFINED,
                          w, h,
                          SDL_WINDOW_BORDERLESS | SDL_WINDOW_FOREIGN*1);    
    SDL_SetWindowPosition(sdl_window,window->x,window->y);
#else
    sdl_window=SDL_CreateWindowFrom((void*)window->systemWindowId);
#endif    
    
    if(!sdl_window)
    {
        ADM_info("[SDL] Creating window failed!\n");
        ADM_warning("[SDL] ERROR: %s\n", SDL_GetError());
        cleanup();
        return false;
    }
    
    sdl_renderer = SDL_CreateRenderer(sdl_window, sdlDriverIndex, SDL_RENDERER_ACCELERATED |  SDL_RENDERER_PRESENTVSYNC);
    if(!sdl_renderer)
        sdl_renderer = SDL_CreateRenderer(sdl_window, sdlDriverIndex, 0);
    if(!sdl_renderer)
    {
        ADM_warning("[SDL] FAILED to create a renderer\n");
        cleanup();
        return false;
    }
    
    sdl_texture = SDL_CreateTexture(sdl_renderer,
                               SDL_PIXELFORMAT_YV12,
                               SDL_TEXTUREACCESS_STREAMING,
                               w, h);
    if(sdl_texture)
    {
        useYV12=true;
    }else
    {
        useYV12=false;
        sdl_texture = SDL_CreateTexture(sdl_renderer,
                               SDL_PIXELFORMAT_ARGB8888,
                               SDL_TEXTUREACCESS_STREAMING,
                               w, h);
        if(!sdl_texture)
        {
            ADM_warning("[SDL] FAILED to create a texture (rgb)\n");
            cleanup();
            return false;
        }
    }
    ADM_info("[SDL] Setting final size\n");
    changeZoom(zoom);
    ADM_info("[SDL] All init done.\n");
    return true;
}
예제 #10
0
파일: sdl-video.cpp 프로젝트: Plombo/fceux
int InitVideo(FCEUGI *gi)
{
	// This is a big TODO.  Stubbing this off into its own function,
	// as the SDL surface routines have changed drastically in SDL2
	// TODO - SDL2
	const char * window_name;
	int error, flags = 0;
	int doublebuf, xstretch, ystretch, xres, yres, show_fps;
	uint32_t  Amask, Rmask, Gmask, Bmask;
	int   bpp;

	FCEUI_printf("Initializing video (SDL2.x) ...");

	// load the relevant configuration variables
	g_config->getOption("SDL.Fullscreen", &s_fullscreen);
	g_config->getOption("SDL.DoubleBuffering", &doublebuf);
#ifdef OPENGL
	g_config->getOption("SDL.OpenGL", &s_useOpenGL);
#endif
	g_config->getOption("SDL.SpecialFilter", &s_sponge);
	g_config->getOption("SDL.XStretch", &xstretch);
	g_config->getOption("SDL.YStretch", &ystretch);
	g_config->getOption("SDL.LastXRes", &xres);
	g_config->getOption("SDL.LastYRes", &yres);
	g_config->getOption("SDL.ClipSides", &s_clipSides);
	g_config->getOption("SDL.NoFrame", &noframe);
	g_config->getOption("SDL.ShowFPS", &show_fps);

	// check the starting, ending, and total scan lines
	FCEUI_GetCurrentVidSystem(&s_srendline, &s_erendline);
	s_tlines = s_erendline - s_srendline + 1;

#if OPENGL
	if( !s_useOpenGL || s_sponge )
	{
		FCEUD_PrintError("SDL2 Does not support non-OpenGL rendering or special filters\n");
		KillVideo();
		return -1;
	}
#endif

	// initialize the SDL video subsystem if it is not already active
	if(!SDL_WasInit(SDL_INIT_VIDEO)) {
		error = SDL_InitSubSystem(SDL_INIT_VIDEO);
		if(error) {
			FCEUD_PrintError(SDL_GetError());
			return -1;
		}
	}
	s_inited = 1;

	// For simplicity, hard-code this to 32bpp for now...
	s_curbpp = 32;

	// If game is running, set window name accordingly
	if( gi )
	{
		window_name = (const char *) gi->name;
	}
	else
	{
		window_name = "FCE Ultra";
	}

	s_exs = 1.0;
	s_eys = 1.0;
	if(s_fullscreen) {
		s_window = SDL_CreateWindow( window_name,
		                             SDL_WINDOWPOS_UNDEFINED,
		                             SDL_WINDOWPOS_UNDEFINED,
		                             0, 0,  // Res not specified in full-screen mode
		                             SDL_WINDOW_FULLSCREEN_DESKTOP);
	} else {
#if defined(_GTK) && defined(SDL_VIDEO_DRIVER_X11)
		if(noGui == 0 && strcmp(SDL_GetCurrentVideoDriver(), "x11") == 0) {
			s_window = SDL_CreateWindowFrom((void*)GDK_WINDOW_XID (gtk_widget_get_window(evbox)));
		}
		else
#endif
			s_window = SDL_CreateWindow( window_name,
				                         SDL_WINDOWPOS_UNDEFINED,
				                         SDL_WINDOWPOS_UNDEFINED,
				                         xres, yres,
				                         0);
	}

	// This stuff all applies regardless of full-screen vs windowed mode.
	s_renderer =  SDL_CreateRenderer(s_window, -1, 0);

	// Set logical rendering size & specify scaling mode.  All rendering is
	// now done to the renderer rather than directly to the screen surface.
	// The renderer takes care of any scaling necessary.
	//
	// NOTE: setting scale quality to "nearest" will result in a blown-up but
	// pixelated while "linear" will tend to blur everything.
	SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest");
	SDL_RenderSetLogicalSize(s_renderer, xres, yres);


	//
	// Create the texture that will ultimately be rendered.
	// s_screen is used to build up an image, then the texture will be updated
	// all at once when it's ready
	s_texture = SDL_CreateTexture(s_renderer,
	                              SDL_PIXELFORMAT_ARGB8888,
	                              SDL_TEXTUREACCESS_STREAMING,
	                              xres, yres);
	//
	// Create a surface to draw pixels onto
	//
	SDL_PixelFormatEnumToMasks(SDL_PIXELFORMAT_ARGB8888, &bpp, &Rmask, &Gmask, &Bmask, &Amask);
	s_screen = SDL_CreateRGBSurface(0, xres, yres, bpp,
	                                Rmask, Gmask, Bmask, Amask);

	if( !s_screen )
	{
		FCEUD_PrintError(SDL_GetError());
		return -1;
	}

	//
	// Setup Icon surface
	//
#ifdef LSB_FIRST
	s_IconSurface = SDL_CreateRGBSurfaceFrom((void *)fceu_playicon.pixel_data,
	                32, 32, 24, 32 * 3,
	                0xFF, 0xFF00, 0xFF0000, 0x00);
#else
	s_IconSurface = SDL_CreateRGBSurfaceFrom((void *)fceu_playicon.pixel_data,
	                32, 32, 24, 32 * 3,
	                0xFF0000, 0xFF00, 0xFF, 0x00);
#endif

	SDL_SetWindowIcon(s_window, s_IconSurface);

	s_paletterefresh = 1;   // Force palette refresh

	// always init blit to high since bpp forced to 32 for now.
	InitBlitToHigh(s_curbpp >> 3,
	               s_screen->format->Rmask,
	               s_screen->format->Gmask,
	               s_screen->format->Bmask,
	               0, //s_eefx,  Hard-code SFX off
	               0, //s_sponge,  Hard-code special filters off.
	               0);

	return 0;
}
예제 #11
0
// WINDOWS MAIN FUNCTION
// hInst = current instance of the program
// hPrevInst = previous instance which is not used anymore.
// cmdLine = holds command line arguments to be passed in to the program
// cmdShow = holds an integer to specify if we want to show this window.
int CALLBACK WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR cmdLine, int cmdShow)
{
    WNDCLASS wc = {0};
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.hInstance = hInst;
    wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
    wc.lpszClassName = wndClassName;
    wc.hCursor = 0; //TODO: Add cursors and icons to this program.
    wc.hIcon = 0;
    wc.lpfnWndProc = (WNDPROC)wndProc;

    RegisterClass(&wc);

    HWND window = CreateWindow(wndClassName, wndTitle,
                               WS_OVERLAPPEDWINDOW,
                               CW_USEDEFAULT, CW_USEDEFAULT,
                               wndWidth, wndHeight,
                               0, 0, hInst, 0);
    
    if(window)
    {
        ShowWindow(window, SW_SHOW);
        UpdateWindow(window);

        // NOTE: Initializing SDL
        if(SDL_Init(SDL_INIT_VIDEO) != 0 )
        {
            DestroyWindow(window);
            return -2;
        }

        IMG_Init(IMG_INIT_JPG | IMG_INIT_PNG);
        
        sdlWindow = SDL_CreateWindowFrom((void*)window);

        char error[MAX_PATH];
        stringCopy(error, SDL_GetError());
        OutputDebugStringA(error);

        if(!sdlWindow)
        {
            SDL_Quit();
            DestroyWindow(window);
            return -3;
        }
        
        renderer = SDL_CreateRenderer(sdlWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);

        if(!renderer)
        {
            SDL_DestroyWindow(sdlWindow);
            SDL_Quit();
            DestroyWindow(window);
            return -4;
        }

        i32 RefreshRate = 0;
        HDC dc = GetDC(window);
        i32 winRefreshRate = GetDeviceCaps(dc, VREFRESH);

        if( winRefreshRate > 1 )
        {
            RefreshRate = winRefreshRate / 2;
        }
        else
        {
            RefreshRate = 30;
        }

        r32 targetSecsPerFrame = 1.0f / RefreshRate;

        GameMemory memory = {};
        memory.permanentSize = Megabytes(64);
        memory.transientSize = Megabytes(64);
        memory.totalSize = memory.permanentSize + memory.transientSize;
        
        gameMemoryBlock = VirtualAlloc( 0, memory.totalSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

        if(!gameMemoryBlock)
        {
            SDL_DestroyRenderer(renderer);
            SDL_DestroyWindow(sdlWindow);
            SDL_Quit();
            DestroyWindow(window);
            return -5;
        }

        memory.permanentBlock = gameMemoryBlock;
        memory.transientBlock = (i8*)gameMemoryBlock + memory.permanentSize;
        memory.readEntireFile = ReadEntireFile;
        memory.freeFile = FreeFile;
        memory.writeEntireFile = WriteEntireFile;

        Win32Dims windowDims = GetWindowDimensions(window);
        
        Render render = {};
        render.renderer = renderer;
        render.screenW = windowDims.width;
        render.screenH = windowDims.height;
        
        GameController input = {0};
        input.dt = targetSecsPerFrame;
        
        Win32State state = {0};
        state.memoryBlock = gameMemoryBlock;
        state.memorySize = memory.totalSize;

        GameCodeDLL gameCode =  Win32LoadGameCode("Game.dll", "Game_temp.dll", "lock.tmp");
        
        isRunning = true;

        r32 sleepIsGranular = (timeBeginPeriod(1) == TIMERR_NOERROR);
        
        LARGE_INTEGER lastCounter = Win32GetClock();

        i64 lastCycles = __rdtsc();
        
        LARGE_INTEGER performanceFreqPerSecRes;
        QueryPerformanceFrequency(&performanceFreqPerSecRes);
        globalPerformanceCountFreq = performanceFreqPerSecRes.QuadPart;
        
        // NOTE: PROGRAM LOOP!!
        while(isRunning)
        {
            // NOTE: compare File times for us to be able to reload the new game code
            FILETIME currentFileTime = Win32GetLastWriteTime("Game.dll");
            if(CompareFileTime(&currentFileTime, &gameCode.lastWriteTime) != 0)
            {
                Win32UnloadGameCode(&gameCode);
                gameCode = Win32LoadGameCode("Game.dll", "Game_temp.dll", "lock.tmp");
            }
            
            MSG msg = {0};
            while(PeekMessage(&msg, window, 0, 0, PM_REMOVE))
            {
                switch(msg.message)
                {
                    case WM_CLOSE:
                    {
                        isRunning = false;
                    }break;

                    case WM_KEYUP:
                    case WM_KEYDOWN:
                    case WM_SYSKEYUP:
                    case WM_SYSKEYDOWN:
                    {
                        u32 vkCode = (u32)msg.wParam;   // This contains the keycode for the key that the user pressed.
                        bool isDown = ((msg.lParam & (1 << 31)) == 0);  // Check to see if the key is down now.
                        bool wasDown = ((msg.lParam & (1 << 30)) != 0); // Check to see if the key was down previously.

                        if(isDown != wasDown)
                        {
                            if(vkCode == 'W')
                            {
                                input.moveUp.isDown = isDown;
                            }
                            else if(vkCode == 'S')
                            {
                                input.moveDown.isDown = isDown;
                            }
                            else if(vkCode == 'A')
                            {
                                input.moveLeft.isDown = isDown;
                            }
                            else if(vkCode == 'D')
                            {
                                input.moveRight.isDown = isDown;
                            }
                            if(vkCode == VK_UP)
                            {
                                input.actionUp.isDown = isDown;
                            }
                            else if(vkCode == VK_DOWN)
                            {
                                input.actionDown.isDown = isDown;
                            }
                            else if(vkCode == VK_LEFT)
                            {
                                input.actionLeft.isDown = isDown;
                            }
                            else if(vkCode == VK_RIGHT)
                            {
                                input.actionRight.isDown = isDown;
                            }
                            else if(vkCode == VK_ESCAPE)
                            {
                                input.back.isDown = isDown;
                            }
                            else if(vkCode == 'O')
                            {
                                if(isDown)
                                {
                                    if(state.recordingIndex == 0)
                                    {
                                        BeginRecording(&state, 1);
                                    }
                                    else
                                    {
                                        EndRecording(&state);
                                        BeginPlayback(&state, 1);
                                    }
                                }
                            }
                            else if(vkCode == 'P')
                            {
                                if(isDown)
                                {
                                    if(state.playbackIndex > 0)
                                    {
                                        EndPlayback(&state);
                                        ZeroMemory(&input, sizeof(input));
                                    }
                                }
                            }
                        }

                        if(isDown)
                        {
                            bool AltKeyWasDown = ((msg.lParam & (1 << 29)) != 0);
                            if(vkCode == VK_RETURN && AltKeyWasDown)
                            {
                                if(msg.hwnd)
                                {
                                    isFullscreen = !isFullscreen;
                                    Win32FullscreenToggle(msg.hwnd);
                                }
                            }
                        }

                    }break;

                    default:
                    {
                        TranslateMessage(&msg);
                        DispatchMessage(&msg);
                    }
                }
            }

            if(input.back.isDown)
            {
                isRunning = false;
                PostQuitMessage(0);
            }

            if(state.recordingIndex > 0)
            {
                RecordingInput(&state, &input);
            }
            else if(state.playbackIndex > 0)
            {
                PlaybackInput(&state, &input);
            }

            Win32Dims windowDims = GetWindowDimensions(window);
            Win32UpdateWindow(windowDims, (i32*)&render.screenW, (i32*)&render.screenH);
            
            if(gameCode.UpdateRender)
            {
                gameCode.UpdateRender(&memory, &input, &render);
            }

            LARGE_INTEGER workCounter = Win32GetClock();
            r32 workSecsElapsed = Win32GetSecondsElapsed(lastCounter, workCounter);

            r32 secondsElapsed = workSecsElapsed;
            if(secondsElapsed < targetSecsPerFrame)
            {
                if(sleepIsGranular)
                {
                    DWORD sleepMS = (DWORD)(1000.0f * (targetSecsPerFrame - secondsElapsed));
                    if(sleepMS > 0)
                    {
                        Sleep(sleepMS);
                    }
                }

                r32 testSecsElapsed = Win32GetSecondsElapsed(lastCounter, Win32GetClock());
                if(testSecsElapsed < targetSecsPerFrame)
                {
                    //TODO: LOG MISSED SLEEP HERE!!
                }

                while(secondsElapsed < targetSecsPerFrame)
                {
                    secondsElapsed = Win32GetSecondsElapsed(lastCounter, Win32GetClock());
                }
            }
            else
            {
                //TODO: MISSED FRAME RATE!!
            }
            
            LARGE_INTEGER endCounter = Win32GetClock();

            i64 endCycles = __rdtsc();
            
            r64 elapsedCounts = (r64)(endCounter.QuadPart - lastCounter.QuadPart);
            r64 elapsedCycles = (r64)(endCycles - lastCycles);

            r32 MSperFrame = ((1000.0f * Win32GetSecondsElapsed(lastCounter, endCounter)));
            r32 FPS = (r32)(globalPerformanceCountFreq / elapsedCounts);
            r32 MegaCyclesPerFrame = (r32)(elapsedCycles / (1000.0f * 1000.0f));
            
            char buffer[256];
            sprintf_s(buffer, "%.02fms, %.02ffps, %.02fmcpf\n", MSperFrame, FPS, MegaCyclesPerFrame);            
            OutputDebugStringA(buffer);
            
            lastCounter = endCounter;
            lastCycles = endCycles;
            
        } // NOTE: END OF WHILE LOOP

        //IMPORTANT: Unload this when we exit the program.
        Win32UnloadGameCode(&gameCode);        
    }
    else
    {
        // TODO: Handle Error Loggin here!!
        return -1;
    }

    if(gameMemoryBlock)
    {
        VirtualFree(gameMemoryBlock, 0, MEM_RELEASE);
    }
    
    //Close
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(sdlWindow);
    IMG_Quit();
    SDL_Quit();
    DestroyWindow(window);

    return 0;
}