SDL2.0例子代码分析-----CheckKeys Project

SDL简介

SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成。SDL提供了数种控制图像、声音、输出入的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台(Linux、Windows、Mac OS X等)的应用软件。目前SDL多用于开发游戏、模拟器、媒体播放器等多媒体应用领域。

SDL1.2和SDL2的差别

SDK1.2和SDL2.1系列的API接口变动的不小,当然功能也大大增强,支持多线程窗口。

具体的change 请看

http://blog.csdn.net/yue7603835/article/details/42030667  我转载的 官方的 文章。

下面是 SDL2.0 例子代码的 事件CheckKeys代码的分析 +注释

SDK2.0例子代码分析-检测键盘按下状态

/* 监听键盘按下次数
你需要调用  SDL_PollEvent() or SDL_WaitEvent() to
   推动事件循环和 监视
   */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "SDL.h"

/*退出程序之前先清理 SDL subsystem */
static void
quit(int rc)
{
	SDL_Quit();
	exit(rc);
}

//格式化 可变参数 到 buffer
static void
print_string(char **text, size_t *maxlen, const char *fmt, ...)
{
	int len;
	//定义可变参数列表
	va_list ap;
	///初始化可变参数列表
	va_start(ap, fmt);
	//格式化所有参数到text二维数组 并且返回字符长度
	len = SDL_vsnprintf(*text, *maxlen, fmt, ap);
	//如果返回>0 字符指针后移
	if (len > 0) {
		//
		*text += len;
		//如果len<最大尺寸那么 减少最大尺寸  否则置零
		if (((size_t)len) < *maxlen) {
			*maxlen -= (size_t)len;
		}
		else {
			*maxlen = 0;
		}
	}
	va_end(ap);
}

static void
print_modifiers(char **text, size_t *maxlen)
{
	int mod;
	print_string(text, maxlen, " modifiers:");
	//获取当前键盘状态判断 SHIFT等是否按下
	mod = SDL_GetModState();
	if (!mod) {
		print_string(text, maxlen, " (none)");
		return;
	}
	if (mod & KMOD_LSHIFT)
		print_string(text, maxlen, " LSHIFT");
	if (mod & KMOD_RSHIFT)
		print_string(text, maxlen, " RSHIFT");
	if (mod & KMOD_LCTRL)
		print_string(text, maxlen, " LCTRL");
	if (mod & KMOD_RCTRL)
		print_string(text, maxlen, " RCTRL");
	if (mod & KMOD_LALT)
		print_string(text, maxlen, " LALT");
	if (mod & KMOD_RALT)
		print_string(text, maxlen, " RALT");
	if (mod & KMOD_LGUI)
		print_string(text, maxlen, " LGUI");
	if (mod & KMOD_RGUI)
		print_string(text, maxlen, " RGUI");
	if (mod & KMOD_NUM)
		print_string(text, maxlen, " NUM");
	if (mod & KMOD_CAPS)
		print_string(text, maxlen, " CAPS");
	if (mod & KMOD_MODE)
		print_string(text, maxlen, " MODE");
}

static void
//SDL_Keysym系统键 被SDL_EVENT所使用
PrintKey(SDL_Keysym * sym, SDL_bool pressed, SDL_bool repeat)
{
	//存放消息
	char message[512];
	//指向message的指针
	char *spot;
	size_t left;

	spot = message;
	//left初始化=512
	left = sizeof(message);

	/*打印键盘码  状态  名字 */
	if (sym->sym) {
		print_string(&spot, &left,
			"Key %s:  scancode %d = %s, keycode 0x%08X = %s ",
			pressed ? "pressed " : "released",
           ///扫描码
			sym->scancode,
			//获取扫描码名字
			SDL_GetScancodeName(sym->scancode),
			 //获取key name
			sym->sym, SDL_GetKeyName(sym->sym));
	}
	else {
		print_string(&spot, &left,
			"Unknown Key (scancode %d = %s) %s ",
			sym->scancode,
			//获取键盘扫描码名字
			SDL_GetScancodeName(sym->scancode),
			pressed ? "pressed " : "released");
	}
	//打印当前键盘是否有系统键被按下
	print_modifiers(&spot, &left);
	if (repeat) {
		//如果重复按下 那么格式化字符串到 buffer  message
		print_string(&spot, &left, " (repeat)");
	}
	SDL_Log("%s\n", message);
}

//
static void
PrintText(char *text)
{
	char *spot, expanded[1024];

	expanded[0] = '\0';
	for (spot = text; *spot; ++spot)
	{
		//格式化
		size_t length = SDL_strlen(expanded);
		//将字符串格式化到buffer
		SDL_snprintf(expanded + length, sizeof(expanded) - length, "\\x%.2x", (unsigned char)*spot);
	}
	//打印日志
	SDL_Log("Text (%s): \"%s%s\"\n", expanded, *text == '"' ? "\\" : "", text);
}

int
main(int argc, char *argv[])
{
	//创建SDLwindow
	SDL_Window *window;

	//sdl事件处理
	SDL_Event event;
	int done;

	/* 设置应用程序日志级别*/
	SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);

	/* 初始化SDL子系统*/
	if (SDL_Init(SDL_INIT_VIDEO) < 0) {
		SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
		return (1);
	}

	/* 创建SDL 2d渲染窗口 */
	window = SDL_CreateWindow("CheckKeys Test",
		SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,

		640, 480, 0);
	//sdl 2d渲染窗口创建失败
	if (!window) {
		SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create 640x480 window: %s\n",
			SDL_GetError());
		quit(2);
	}

	//如果是IPHONE下创建一个OpenGL渲染上下文并使其成为当前窗口
#if __IPHONEOS__
	SDL_GL_CreateContext(window);
#endif
	//开始接受Unicode文本输入事件  如果支持的话将会显示屏幕键盘
	SDL_StartTextInput();

	/* 监视键盘点击次数*/
	done = 0;
	//类似与 windows 消息循环 实际上底层在windows平台也是封装的 windows消息循环机制
	while (!done)
	{
		/* 事件监测循环检测 事件 */
		SDL_WaitEvent(&event);
		//event.type存储了当前的事件类型
		//如果无键盘鼠标 触摸点击 那么 默认是 0x200
		switch (event.type)
		{
		case SDL_KEYDOWN:
		case SDL_KEYUP:
			//打印系统键信息
			PrintKey(&event.key.keysym, (event.key.state == SDL_PRESSED) ? SDL_TRUE : SDL_FALSE, (event.key.repeat) ? SDL_TRUE : SDL_FALSE);
			break;
		case SDL_TEXTINPUT:
			//如果是文本输入 输出文本
			PrintText(event.text.text);
			break;
		case SDL_MOUSEBUTTONDOWN:
			/* 如果有任何鼠标点击消息 或者SDL_QUIT消息 那么将退出窗口 */
		case SDL_QUIT:
			done = 1;
			break;
		default:
			break;
		}
	}
	//清除已经初始化的子系统 你应该在程序退出的时候调用
	SDL_Quit();
	return (0);
}
时间: 2024-07-30 03:23:37

SDL2.0例子代码分析-----CheckKeys Project的相关文章

SDL2.0例子代码分析---循环播放wav loopwav

SDL2.0中循环播放一段声音文件 ,并且添加上注释. /* 加载并且循环播放一个WAV文件*/ /* loopwaves.c is much more robust in handling WAVE files -- This is only for simple WAVEs */ #include "SDL_config.h" #include <stdio.h> #include <stdlib.h> #if HAVE_SIGNAL_H #include

(原创)cocos2d-x 3.0 示例代码分析1:AppDelegate

星月最近在用3.0做类似刀塔游戏,第一次用3.0,之前一直只是查查资料,最近发现做一些特定行为需要对3.0一些新的特性了解.所以趁这个机会,把3.0的测试代码过一遍,同时增加注释,希望能对大家有帮助~ 因为项目原因,所以不定期更新~~(小白:借口,继续找借口!) 星月倾心贡献~~~ // AppDelegate.cpp /**************************************************************************** Copyright (

apollo2.0 radar代码分析

从apollo2.0的代码上看,百度是想做lidar和radar融合的先看传感器输出数据定义class SensorRawFrame{public:SensorType sensortype;double timestamp;Eigen::Matrix4d pose;};// lidar输出数据定义,用的是Velodyne的产品,包含了一块点云,pcl库格式class Velodyne的产品RawFrame : public SensorRawFrame {public:VelodyneRawF

基于&lt;最简单的基于FFMPEG+SDL的视频播放器 ver2 (采用SDL2.0)&gt;的一些个人总结

最近因为项目接近收尾阶段,所以变的没有之前那么忙了,所以最近重新拿起了之前的一些FFMPEG和SDL的相关流媒体播放器的例子在看. 同时自己也用FFMPEG2.01,SDL2.01结合MFC以及网上罗列的一些资料,打算打造一款自己的简易播放器. 最先开始是阅读了<An ffmpeg and SDL Tutorial>以及来源与(http://blog.csdn.net/love4mario/article/details/17652355)中的中文资料,同时认真对tutorial01-08中的

Android4.0图库Gallery2代码分析(二) 数据管理和数据加载

Android4.0图库Gallery2代码分析(二) 数据管理和数据加载 2012-09-07 11:19 8152人阅读 评论(12) 收藏 举报 代码分析android相册优化工作 Android4.0图库Gallery2代码分析(二) 数据管理和数据加载 一 图库数据管理 Gallery2的数据管理 DataManager(职责:管理数据源)- MediaSource(职责:管理数据集) - MediaSet(职责:管理数据项).DataManager中初始化所有的数据源(LocalSo

阅读代码分析工具Understand 2.0试用

Understand 2.0是一款源码阅读分析软件,功能强大.试用过一段时间后,感觉相当不错,确实能够大大提高代码阅读效率. 因为Understand功能十分强大,本文不可能详尽地介绍它的全部功能,所以仅仅列举本人觉得比較重要或有特色的功能,以做抛砖引玉之举. Understand 2.0能够从http://www.scitools.com/下载到,安装后能够试用15天. 使用Understand阅读代码前.要先创建一个Project,然后把全部的源码文件增加到这个Project里.这里我创建了

(转)基于FFPMEG2.0版本的ffplay代码分析

ref:http://zzhhui.blog.sohu.com/304810230.html 背景说明 FFmpeg是一个开源,免费,跨平台的视频和音频流方案,它提供了一套完整的录制.转换以及流化音视频的解决方案.而ffplay是有ffmpeg官方提供的一个基于ffmpeg的简单播放器.学习ffplay对于播放器流程.ffmpeg的调用等等是一个非常好的例子.本文就是对ffplay的一个基本的流程剖析,很多细节内容还需要继续钻研. 注:本文师基于ffmpeg-2.0版本进行分析,具体代码行还请对

Lua1.0 代码分析 table.c

转载出处:http://my.oschina.net/xhan/blog/307961 table.c 代码分析 全局符号,常量,字符串,关联数组,文件列表的定义. 全局符号: 初始有 5 个基本的符号,Lua 预设的函数和库函数都注册在里面. 常量: 初始的几个常量是 Lua 中 type 的名字. 字符串表,关联数组表,文件列表 所有的这些在 table.c 中定义的这些数组可以认为是 Lua 的全局注册表空间,Lua 的环境. 函数分析 ? 1 2 3 4 5 6 7 8 9 10 11

Lua1.0 代码分析 inout.c

inout.c 代码分析 主要看下对于文件的处理 /* ** Function to open a file to be input unit. ** Return 0 on success or 1 on error. */ int lua_openfile (char *fn) {  lua_linenumber = 1;  lua_setinput (fileinput);  lua_setunput (fileunput);  fp = fopen (fn, "r");  if