SDL2.0例子代码分析-----CheckKeys Project
SDL简介SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成。SDL提供了数种控制图像、声音、输出入的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台(Linux、Windows、Mac OS X等)的应用软件。目前SDL多用于开发游戏、模拟器、媒体播放器等多媒体应用领域。SDL1.2和SDL2的差别SDK
·
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);
}
更多推荐
已为社区贡献2条内容
所有评论(0)