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

[复制链接]

该用户从未签到

2380

主题

2433

帖子

9139

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
9139
QQ
跳转到指定楼层
楼主
发表于 2017-12-18 17:37:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

想要查看内容赶紧注册登陆吧!

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
SDL简介SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成。SDL提供了数种控制图像、声音、输出入的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台(Linux、Windows、Mac OS X等)的应用软件。目前SDL多用于开发游戏、模拟器、媒体播放器等多媒体应用领域。
SDL1.2和SDL2的差别
SDK1.2和SDL2.1系列的API接口变动的不小,当然功能也大大增强,支持多线程窗口。
下面是 SDL2.0 例子代码的 事件CheckKeys代码的分析 +注释
SDK2.0例子代码分析-检测键盘按下状态

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

  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>

  8. #include "SDL.h"

  9. /*退出程序之前先清理 SDL subsystem */
  10. static void
  11. quit(int rc)
  12. {  
  13.     SDL_Quit();
  14.     exit(rc);
  15. }

  16. //格式化 可变参数 到 buffer
  17. static void
  18. print_string(char **text, size_t *maxlen, const char *fmt, ...)
  19. {
  20.     int len;
  21.     //定义可变参数列表
  22.     va_list ap;
  23.     ///初始化可变参数列表
  24.     va_start(ap, fmt);
  25.     //格式化所有参数到text二维数组 并且返回字符长度
  26.     len = SDL_vsnprintf(*text, *maxlen, fmt, ap);
  27.     //如果返回>0 字符指针后移
  28.     if (len > 0) {
  29.         //
  30.         *text += len;
  31.         //如果len<最大尺寸那么 减少最大尺寸  否则置零
  32.         if (((size_t)len) < *maxlen) {
  33.             *maxlen -= (size_t)len;
  34.         }
  35.         else {
  36.             *maxlen = 0;
  37.         }
  38.     }
  39.     va_end(ap);
  40. }

  41. static void
  42. print_modifiers(char **text, size_t *maxlen)
  43. {
  44.     int mod;
  45.     print_string(text, maxlen, " modifiers:");
  46.     //获取当前键盘状态判断 SHIFT等是否按下
  47.     mod = SDL_GetModState();
  48.     if (!mod) {
  49.         print_string(text, maxlen, " (none)");
  50.         return;
  51.     }
  52.     if (mod & KMOD_LSHIFT)
  53.         print_string(text, maxlen, " LSHIFT");
  54.     if (mod & KMOD_RSHIFT)
  55.         print_string(text, maxlen, " RSHIFT");
  56.     if (mod & KMOD_LCTRL)
  57.         print_string(text, maxlen, " LCTRL");
  58.     if (mod & KMOD_RCTRL)
  59.         print_string(text, maxlen, " RCTRL");
  60.     if (mod & KMOD_LALT)
  61.         print_string(text, maxlen, " LALT");
  62.     if (mod & KMOD_RALT)
  63.         print_string(text, maxlen, " RALT");
  64.     if (mod & KMOD_LGUI)
  65.         print_string(text, maxlen, " LGUI");
  66.     if (mod & KMOD_RGUI)
  67.         print_string(text, maxlen, " RGUI");
  68.     if (mod & KMOD_NUM)
  69.         print_string(text, maxlen, " NUM");
  70.     if (mod & KMOD_CAPS)
  71.         print_string(text, maxlen, " CAPS");
  72.     if (mod & KMOD_MODE)
  73.         print_string(text, maxlen, " MODE");
  74. }

  75. static void
  76. //SDL_Keysym系统键 被SDL_EVENT所使用
  77. PrintKey(SDL_Keysym * sym, SDL_bool pressed, SDL_bool repeat)
  78. {   
  79.     //存放消息
  80.     char message[512];
  81.     //指向message的指针
  82.     char *spot;
  83.     size_t left;

  84.     spot = message;
  85.     //left初始化=512
  86.     left = sizeof(message);

  87.     /*打印键盘码  状态  名字 */
  88.     if (sym->sym) {
  89.         print_string(&spot, &left,
  90.             "Key %s:  scancode %d = %s, keycode 0x%08X = %s ",
  91.             pressed ? "pressed " : "released",
  92.            ///扫描码
  93.             sym->scancode,
  94.             //获取扫描码名字
  95.             SDL_GetScancodeName(sym->scancode),
  96.              //获取key name
  97.             sym->sym, SDL_GetKeyName(sym->sym));
  98.     }
  99.     else {
  100.         print_string(&spot, &left,
  101.             "Unknown Key (scancode %d = %s) %s ",
  102.             sym->scancode,
  103.             //获取键盘扫描码名字
  104.             SDL_GetScancodeName(sym->scancode),
  105.             pressed ? "pressed " : "released");
  106.     }
  107.     //打印当前键盘是否有系统键被按下
  108.     print_modifiers(&spot, &left);
  109.     if (repeat) {
  110.         //如果重复按下 那么格式化字符串到 buffer  message
  111.         print_string(&spot, &left, " (repeat)");
  112.     }
  113.     SDL_Log("%s\n", message);
  114. }

  115. //
  116. static void
  117. PrintText(char *text)
  118. {
  119.     char *spot, expanded[1024];

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

  131. int
  132. main(int argc, char *argv[])
  133. {
  134.     //创建SDLwindow
  135.     SDL_Window *window;

  136.     //sdl事件处理
  137.     SDL_Event event;
  138.     int done;

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

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

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

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

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

  162.     /* 监视键盘点击次数*/
  163.     done = 0;
  164.     //类似与 windows 消息循环 实际上底层在windows平台也是封装的 windows消息循环机制
  165.     while (!done)
  166.     {
  167.         /* 事件监测循环检测 事件 */
  168.         SDL_WaitEvent(&event);
  169.         //event.type存储了当前的事件类型
  170.         //如果无键盘鼠标 触摸点击 那么 默认是 0x200
  171.         switch (event.type)
  172.         {
  173.         case SDL_KEYDOWN:
  174.         case SDL_KEYUP:
  175.             //打印系统键信息
  176.             PrintKey(&event.key.keysym, (event.key.state == SDL_PRESSED) ? SDL_TRUE : SDL_FALSE, (event.key.repeat) ? SDL_TRUE : SDL_FALSE);
  177.             break;
  178.         case SDL_TEXTINPUT:
  179.             //如果是文本输入 输出文本
  180.             PrintText(event.text.text);
  181.             break;
  182.         case SDL_MOUSEBUTTONDOWN:
  183.             /* 如果有任何鼠标点击消息 或者SDL_QUIT消息 那么将退出窗口 */
  184.         case SDL_QUIT:
  185.             done = 1;
  186.             break;
  187.         default:
  188.             break;
  189.         }
  190.     }
  191.     //清除已经初始化的子系统 你应该在程序退出的时候调用
  192.     SDL_Quit();
  193.     return (0);
  194. }
复制代码




分享到:  QQ好友和群QQ好友和群
收藏收藏
回复

使用道具 举报

快速回复高级模式
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表