⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vid.cpp

📁 日本的手持pda源码.wince下使用,完全开源
💻 CPP
字号:
#include "PocketGnuboy.h"
#include "wce.h"
#include "gx.h"

extern "C" {

#include "defs.h"
#include "fb.h"
#include "lcd.h"

void joy_init();
void joy_close();
void joy_poll();

/*
 * process graphics
 */

int gapi = 1;
int screenmode = 0;
int screenchanged = 0;

unsigned char* screenvram;
int screenpitchx;
int screenpitchy;

HDC screendc = 0;
HBITMAP screenbmp = 0;
byte* screenbuf = 0;

static GXDisplayProperties gxdp;
static int frameskip = -1;
struct fb fb = {0};

static int initok = 0;
static int sleep_mod = 0;

static int fps_reset = 1;
static int fps_count = 0;
static int fps_last_count = 0;
static int fps_frame_count = 0;
static int fps_time = 0;

#define MAX_FRAME_SKIP			5
#define FRAME_PERIOD			16742
static int auto_skip = 0;
static int auto_skip_count = 0;
static _int64 auto_start_time = 0;
static int reset_timer = 0;

static int old_timer = 0;
static _int64 start_time = 0;
static double millisecs_per_tick;

void timer_init()
{
	_int64 ticks_per_sec;
	double secs_per_tick;

	if (!QueryPerformanceFrequency((LARGE_INTEGER*)&ticks_per_sec)) {
		// old machine, no performance counter available
		start_time = GetTickCount();
		old_timer = 1;
	}
	else {
		// newer machine, use performance counter
		QueryPerformanceCounter((LARGE_INTEGER *)&start_time);
		secs_per_tick = ((double)1.0) / ((double)ticks_per_sec);
		millisecs_per_tick = ((double)1000.0) / ((double)ticks_per_sec);
		old_timer = 0;
	}
}

DWORD timer_time_in_msec()
{
	if (old_timer)
	{
		// fall back to GetTickCount();
		return (DWORD)(GetTickCount() - start_time);
	}
	else
	{
		// use performance counter
		_int64 temptime;
		QueryPerformanceCounter((LARGE_INTEGER*)&temptime);
		return (DWORD)(((float)(temptime - start_time)) * millisecs_per_tick);
	}
}

void vid_preinit()
{
	/* do nothing; only needed on systems where we must drop perms */
}

void vid_create_screenbmp()
{
	DWORD* quad;
	BITMAPINFOHEADER* pbi;

	HDC hdc = GetDC(g_hwndMain);
	screendc = CreateCompatibleDC(hdc);
	pbi = (BITMAPINFOHEADER*)new byte[sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD)];
	pbi = pbi;
	memset(pbi, 0, sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD));
	pbi->biSize = sizeof(BITMAPINFOHEADER);
	pbi->biWidth = SCREENBMP_WIDTH;
	pbi->biHeight = -SCREENBMP_HEIGHT;
	pbi->biPlanes = 1;
	pbi->biBitCount = 16;
	pbi->biCompression = BI_BITFIELDS;

	quad = (DWORD*)&((LPBITMAPINFO)pbi)->bmiColors[0];
	quad[0] = 0xF800; quad[1] = 0x07E0; quad[2] = 0x001F; // RGB565
	screenbmp = CreateDIBSection(NULL, (LPBITMAPINFO)pbi, DIB_RGB_COLORS, (void**)&screenbuf, NULL, 0);

	if (screenbuf) {
		memset(screenbuf, 0, 240 * 216 * 2);
		SelectObject(screendc, screenbmp);
	}
	ReleaseDC(g_hwndMain, hdc);
	delete pbi;
}

void vid_init()
{
	if (initok) return;
	
	joy_init();
	timer_init();
	vid_create_screenbmp();

	if (gapi) {
		if (!GXOpenDisplay(g_hwndMain, GX_FULLSCREEN))
			return;
		gxdp = GXGetDisplayProperties();

		screenpitchx = gxdp.cbxPitch >> 1;
		screenpitchy = gxdp.cbyPitch;

		fb.w = gxdp.cxWidth;
		fb.h = 144;
		fb.pitch = screenpitchx;
		fb.ptr = NULL;
	}
	else {
		screenpitchx = 1;
		screenpitchy = SCREENBMP_WIDTH * 2;

		fb.w = SCREENBMP_WIDTH;
		fb.h = SCREENBMP_HEIGHT;
		fb.pitch = SCREENBMP_WIDTH;
		fb.ptr = NULL;
	}
	fb.pelsize = 2;
	fb.indexed = 0;
	fb.cc[0].r = 3;
	fb.cc[0].l = 11;
	fb.cc[1].r = 2;
	fb.cc[1].l = 5;
	fb.cc[2].r = 3;
	fb.cc[2].l = 0;
	fb.cc[3].r = 0;
	fb.cc[3].l = 0;
	fb.yuv = 0;
	fb.enabled = 1;
	fb.dirty = 1;

	initok = 1;
	reset_timer = 1;
	fps_reset = 1;
}

void vid_close()
{
	if (screendc) {
		DeleteDC(screendc);
		screendc = 0;
	}
	if (screenbmp) {
		DeleteObject(screenbmp);
		screenbmp = 0;
		screenbuf = 0;
	}

	if (!initok) return;

	joy_close();
	if (gapi) {
		GXResume();
		GXCloseDisplay();
	}
	initok = 0;
}

void ev_poll()
{
	joy_poll();
}

void vid_settitle(char *title)
{
}

void vid_setpal(int i, int r, int g, int b)
{
}

void vid_begin()
{
	static int skip = 0;

	if (frameskip < 0) {
		if (pcm_get_enable()) {
			skip = (skip + 1) % (auto_skip > 0 ? auto_skip + 1 : 1);
			fb.enabled = skip == 0;
		}
		else fb.enabled = auto_skip == 0;
	}
	else {
		skip = (skip + 1) % (frameskip > 0 ? frameskip + 1 : 1);
		fb.enabled = skip == 0;
	}

	if (!fb.enabled) 
		return;

	if (!initok) {
		fb.enabled = 0;
		return;
	}

	fps_frame_count++;

	if (gapi) {
		screenvram = (unsigned char *) GXBeginDraw();
		if (!screenvram) {
			fb.enabled = 0;
			return;
		}

		fb.ptr = screenvram;
		if (screenmode) {
			if (g_fVPad)
				screenvram += 26 * gxdp.cbyPitch;
			else
				screenvram += 52 * gxdp.cbyPitch;
			fb.pitch = fb.w * 4;
		}
		else {
			screenvram += 40 * gxdp.cbxPitch;
			if (g_fVPad)
				screenvram += 62 * gxdp.cbyPitch;
			else
				screenvram += 88 * gxdp.cbyPitch;
			fb.pitch = fb.w * 2;
		}	
	}
	else {
		if (!screenbuf) {
			fb.enabled = 0;
			return;
		}
		screenvram = screenbuf;
		fb.ptr = screenvram;
		if (!screenmode) {
			screenvram += 40 * 2;
			screenvram += SCREENBMP_WIDTH * 36 * 2;
		}
	}
}

void vid_end()
{	
	if (!initok || !fb.enabled) return;

	if (gapi)
		GXEndDraw();
	else {
		int top = g_fVPad ? 0 : 52 - MENU_HEIGHT;
		HDC hdc = GetDC(g_hwndMain);
		if (screenmode)
			BitBlt(hdc, 0, top, SCREENBMP_WIDTH, SCREENBMP_HEIGHT, vid_get_screen_dc(), 0, 0, SRCCOPY);
		else
			BitBlt(hdc, 40, top + 36, 160, 144, vid_get_screen_dc(), 40, 36, SRCCOPY);
		ReleaseDC(g_hwndMain, hdc);
	}
}

void vid_suspend()
{
	int top;
	word *src, *dst, *vram;

	if (!initok) return;

	if (gapi) {
		vram = (word *) GXBeginDraw();
		if (vram && screenbuf) {
			top = g_fVPad ? 26 : 52;
			for (int y = 0; y < 216; y++) {
				src = vram + (top + y) * (gxdp.cbyPitch >> 1);
				dst = (word*)(screenbuf + 240 * y * 2);
				for (int x = 0; x < 240; x++) {
					*dst = *src;
					dst++; src += (gxdp.cbxPitch >> 1);
				}
			}
		}
		GXEndDraw();
		GXSuspend();
	}
	else if (!g_fDrawScreen && screenbuf) {
		memset(screenbuf, 0, SCREENBMP_WIDTH * SCREENBMP_HEIGHT * 2);
		InvalidateRect(g_hwndMain, NULL, TRUE);
		UpdateWindow(g_hwndMain);
	}
}

void vid_resume()
{
	if (!initok) {
		vid_init();
		return;
	}

	if (gapi) GXResume();
	reset_timer = 1;
	fps_reset = 1;

	if (screenchanged) {
		if (screenbuf) memset(screenbuf, 0, SCREENBMP_WIDTH * SCREENBMP_HEIGHT * 2);
		screenchanged = 0;

		InvalidateRect(g_hwndMain, NULL, TRUE);
		UpdateWindow(g_hwndMain);
	}
}

int vid_get_thread_time()
{
	FILETIME ftCreate, ftExit, ftKernel, ftUser;
	GetThreadTimes(GetCurrentThread(), &ftCreate, &ftExit, &ftKernel, &ftUser);
	return (int)((((LARGE_INTEGER*)&ftKernel)->QuadPart / 10000) + (((LARGE_INTEGER*)&ftUser)->QuadPart) / 10000);
}

void vid_start_frame()
{
	if (!initok) return;

	fps_count++;
	if (g_fShowFPS) {
		if (fps_reset) {
			fps_reset = 0;
			fps_count = 0;
			fps_frame_count = 0;
			fps_time = timer_time_in_msec();
		}
		else if (fps_count > 120) {
			int cur = timer_time_in_msec();
			int fps = (double)fps_frame_count / (cur - fps_time) * 100000;
			
			fps_count = 0;
			fps_frame_count = 0;
			fps_time = cur;

			PostMessage(g_hwndMain, WM_UPDATEFPS, fps, 0);
		}
	}

	if (pcm_get_enable()) {
		if (frameskip < 0) {
			if (g_fThrottling) {
				if (reset_timer) {
					reset_timer = 0;
					auto_skip = 0;
					auto_start_time = timer_time_in_msec() * 1000;
					fb.frames = 0;
				}
				else if (fb.frames > auto_skip) {
#if 1
					_int64 cur = timer_time_in_msec() * 1000;
					_int64 buffering = pcm_get_buffering_time();
					_int64 wait = pcm_get_last_wait_time();
					_int64 time_per_frame = (cur - auto_start_time - wait) / fb.frames;

					if (buffering < time_per_frame * 2)
						auto_skip = min(auto_skip + 1, MAX_FRAME_SKIP);
					else if (buffering > pcm_get_buffer_count() * time_per_frame / 2)
						auto_skip = max(auto_skip - 1, 0);

					auto_start_time = cur;
#else
					_int64 buffering = pcm_get_buffering_time();

					if (buffering < FRAME_PERIOD * 2)
						auto_skip = min(auto_skip + 1, MAX_FRAME_SKIP);
					else if (buffering > pcm_get_buffer_count() * FRAME_PERIOD / 2)
						auto_skip = max(auto_skip - 1, 0);
#endif
					fb.frames = 0;
				}
			}
			else auto_skip = 0;
		}
	}
	else {
		if (reset_timer) {
			fb.frames = 0;
			reset_timer = 0;
			auto_skip_count = 0;
			auto_start_time = timer_time_in_msec() * 1000;
		}
		else if (fb.frames) {
			_int64 cur = timer_time_in_msec() * 1000;
			if (cur - auto_start_time < (_int64)FRAME_PERIOD * fb.frames) {
				auto_skip = 0;
				auto_skip_count = 0;
			}
			else auto_skip = 1;
			if (auto_skip && ++auto_skip_count > MAX_FRAME_SKIP)
				reset_timer = 1;

			if (g_fThrottling) {
				if (cur - auto_start_time < (_int64)FRAME_PERIOD * fb.frames) {
					UINT sleep = ((_int64)FRAME_PERIOD * fb.frames - (cur - auto_start_time)) / 1000;
					Sleep(sleep);
				}
			}
		}
	}
}

void vid_end_frame()
{	
}

int vid_get_frameskip()
{
	return frameskip;
}

void vid_set_frameskip(int skip)
{
	frameskip = skip;
}

int vid_get_screenmode()
{
	return screenmode;
}

void vid_set_screenmode(int mode)
{
	screenmode = mode;
	screenchanged = 1;
}

int vid_get_gapi()
{
	return gapi;
}

void vid_set_gapi(int mode)
{
	vid_close();
	gapi = mode;
}

HDC vid_get_screen_dc()
{
	return screendc;
}

} // extern "C"

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -