http://www.apkbus.com/forum.php?mod=viewthread&tid=1989

SDL(Simple DirectMedia Layer)是一套开放源码的跨平台多媒体开发库,使用C语言写成。SDL提供了多种图像、声音、键盘等的实现,可配置性与移植性非常高,开发者可以开发出跨多个平台(Linux、Windows、Mac OS X、Symbian、Widnows Mobiel等嵌入式系统,当然也包括今天要移植的平台:Android)的应用,目前SDL多用于开发游戏、模拟器、媒体播放器等多媒体应用。
目前,SDL的稳定版本是 1.2.13,1.3还在开发中,可以通过SVN得到最新的代码,本次移植以 1.2.13为准,没有测试 1.3版的源码。请从 SDL 的官方网站下载 1.2.13 的源码,文件名为:SDL-1.2.13.zip,并解压,将得到一个 SDL-1.2.13 目录。
在Native编译SDL之前,要先装 Code Sourcery公司的arm交叉编译器,如果是用Windows操作系统,则一定要装 Cygwin(一个在windows上模拟linux的软件),因为在编译时要用到一些 linux命令,具体的步骤请参见:Port SDL/TinySDGL to android with native C,或自已在网上搜一些资料。
因为SDL是用纯C写的一套类库,所以移植性非常好,官方支持的系统有:Linux, Windows, Windows CE, BeOS, MacOS, Mac OS X, FreeBSD, NetBSD, OpenBSD, BSD/OS, Solaris, IRIX, and QNX,非官方支持的有:AmigaOS, Dreamcast, Atari, AIX, OSF/Tru64, RISC OS, SymbianOS, and OS/2,而且网上也有人将SDL移植到很多其他嵌入式系统,甚至有人将SDL移植到 Moto A1200,如此强大的可移植性,其架构真是值得好好学习。
现在切入正题,如何为Android量身定做一个 SDL,下面就从视频,音频,输入事件,定时器(video,audio,events[key,mouse],timer),多线程等几个方面来分析:
1.首先讲视频方面,Android是一个定制的Linux操作系统,Linux显示要么用 X11,要么用framebuffer技术,很显然Android并没有集成 X11(也许Android的软件界面是基于X11的?!),那只有唯一的选择:framebuffer!
打开$SDL/src/video目录,可以发现SDL支持多达30多种的视频显示技术,其中包括我们想要的fbcon及directfb,directfb我没有做测试,也许显示效果会比linux自带的fbcon好,有兴趣的朋友可以试一下,成功了别忘了告诉我;
2.再来谈音频,记得一个广告词:没有声音,再好的戏也出不来!可见音频对多媒体应用的重要性。
这次用的是OSS的driver,但用的是dsp及dma的实现,但在打开Android指定的音频文件 /dev/eac 时有误,所以音频这一块只是能编译通过,不能正常运行,正在考虑用ALSA (Advanced Linux Sound Architecture) 替代;
关于OSS大家可以参看IBM的文章: OSS--跨平台的音频接口简介,写得比较详细。
3.输入事件(键盘,鼠标)中的键盘事件不需要任何更改,就能正常处理,用的设备文件是 /dev/tty0,
但鼠标事件却不能正常处理,加上DEBUG_MOUSE发现用的是PS2的鼠标,但其实Android用的不是PS2的鼠标,用的应该是触摸屏(TouchScreen)鼠标,设备文件是 /dev/input/event0,
详情请参见本人的blog:Android原生(Native)C开发之三:鼠标事件篇(捕鼠记)
,经过改动后,基本能实现鼠标的处理;
4.定时器用的是unix的实现;
5.多线程用的是pthread的实现,unix系统都是用pthread来实现多线程的,在 ln demo时别忘了加 -lpthread;
6.加载动态库用的是unix 的 dl库,同样,在ln demo时别忘了加 -ldl。
SDL提供了一个最小化的Makefile:Makefile.minimal,所有的实现都是 dummy,就是一个空的实现,编译能通过,但运行时什么都不能做,根据上面的分析,将 Makefile.minimal 的内容改成如下:
  1. # Makefile to build the SDL libraryINCLUDE = -I./include
  2. CFLAGS  = -g -s -O2 $(INCLUDE)
  3. CC  = arm-none-linux-gnueabi-gcc
  4. AR  = arm-none-linux-gnueabi-ar
  5. RANLIB = arm-none-linux-gnueabi-ranlibCONFIG_H = include/SDL_config.h
  6. TARGET  = libSDL.a
  7. SOURCES = \
  8. src/*.c \
  9. src/audio/*.c \
  10. src/cdrom/*.c \
  11. src/cpuinfo/*.c \
  12. src/events/*.c \
  13. src/file/*.c \
  14. src/joystick/*.c \
  15. src/stdlib/*.c \
  16. src/thread/*.c \
  17. src/timer/*.c \
  18. src/video/*.c \
  19. src/audio/dsp/*.c \
  20. src/audio/dma/*.c \
  21. src/video/fbcon/*.c \
  22. src/joystick/dummy/*.c \
  23. src/cdrom/dummy/*.c \
  24. src/thread/pthread/*.c \
  25. src/timer/unix/*.c \
  26. src/loadso/dlopen/*.c \OBJECTS = $(shell echo $(SOURCES) | sed -e 's,\.c,\.o,g')all: $(TARGET)$(TARGET): $(CONFIG_H) $(OBJECTS)
  27. $(AR) crv $@ $^
  28. $(RANLIB) $@$(CONFIG_H):
  29. cp $(CONFIG_H).default $(CONFIG_H)clean:
  30. rm -f $(TARGET) $(OBJECTS)

复制代码

最后将$SDL\include\SDL_config_minimal.h的内容改成如下:

  1. #ifndef _SDL_config_minimal_h
  2. #define _SDL_config_minimal_h#include "SDL_platform.h" #include <stdarg.h>typedef signed char int8_t;
  3. typedef unsigned char uint8_t;
  4. typedef signed short int16_t;
  5. typedef unsigned short uint16_t;
  6. typedef signed int int32_t;
  7. typedef unsigned int uint32_t;
  8. typedef unsigned int size_t;
  9. //typedef unsigned long uintptr_t;#define HAVE_LIBC 1#ifdef  HAVE_LIBC
  10. #define HAVE_ALLOCA_H  1
  11. #define HAVE_SYS_TYPES_H 1
  12. #define HAVE_STDIO_H  1
  13. #define STDC_HEADERS  1
  14. #define HAVE_STDLIB_H  1
  15. #define HAVE_STDARG_H  1
  16. #define HAVE_MALLOC_H  1
  17. #define HAVE_MEMORY_H  1
  18. //#define HAVE_STRING_H   1
  19. //#define HAVE_STRINGS_H  1
  20. #define HAVE_INTTYPES_H  1
  21. #define HAVE_STDINT_H  1
  22. #define HAVE_CTYPE_H  1
  23. #define HAVE_MATH_H   1
  24. //#define HAVE_ICONV_H   1
  25. #define HAVE_SIGNAL_H  1
  26. #define HAVE_ALTIVEC_H  1
  27. #define HAVE_MALLOC   1
  28. #define HAVE_CALLOC   1
  29. #define HAVE_REALLOC  1
  30. #define HAVE_FREE   1
  31. #define HAVE_ALLOCA   1
  32. #define HAVE_GETENV   1
  33. #define HAVE_PUTENV   1
  34. #define HAVE_UNSETENV  1
  35. #define HAVE_QSORT   1
  36. #define HAVE_ABS   1
  37. //#define HAVE_BCOPY   1
  38. //#define HAVE_MEMSET   1
  39. //#define HAVE_MEMCPY   1
  40. //#define HAVE_MEMMOVE   1
  41. //#define HAVE_MEMCMP   1
  42. //#define HAVE_STRLEN   1
  43. //#define HAVE_STRLCPY   1
  44. //#define HAVE_STRLCAT   1
  45. //#define HAVE_STRDUP   1
  46. #define HAVE__STRREV  1
  47. #define HAVE__STRUPR  1
  48. #define HAVE__STRLWR  1
  49. //#define HAVE_INDEX   1
  50. #define HAVE_RINDEX   1
  51. //#define HAVE_STRCHR   1
  52. #define HAVE_STRRCHR  1
  53. #define HAVE_STRSTR   1
  54. #define HAVE_ITOA   1
  55. #define HAVE__LTOA   1
  56. #define HAVE__UITOA   1
  57. #define HAVE__ULTOA   1
  58. #define HAVE_STRTOL   1
  59. #define HAVE_STRTOUL  1
  60. #define HAVE__I64TOA  1
  61. #define HAVE__UI64TOA  1
  62. #define HAVE_STRTOLL  1
  63. #define HAVE_STRTOULL  1
  64. #define HAVE_STRTOD   1
  65. #define HAVE_ATOI   1
  66. #define HAVE_ATOF   1
  67. #define HAVE_STRCMP   1
  68. #define HAVE_STRNCMP  1
  69. #define HAVE__STRICMP  1
  70. #define HAVE_STRCASECMP  1
  71. #define HAVE__STRNICMP  1
  72. #define HAVE_STRNCASECMP 1
  73. #define HAVE_SSCANF   1
  74. #define HAVE_SNPRINTF  1
  75. #define HAVE_VSNPRINTF  1
  76. //#define HAVE_ICONV
  77. #define HAVE_SIGACTION  1
  78. #define HAVE_SETJMP   1
  79. #define HAVE_NANOSLEEP  1
  80. //#define HAVE_CLOCK_GETTIME 1
  81. #define HAVE_DLVSYM   1
  82. #define HAVE_GETPAGESIZE 1
  83. #define HAVE_MPROTECT  1
  84. #else
  85. #include <stdarg.h>
  86. #endif
  87. //#define HAVE_STDIO_H 1
  88. //#define HAVE_STDINT_H 1//#define SDL_INPUT_TSLIB 1 //touch screen input
  89. #define SDL_AUDIO_DRIVER_OSS 1 // SDL_AUDIO_DRIVER_DUMMY
  90. #define SDL_CDROM_DISABLED  1
  91. #define SDL_JOYSTICK_DISABLED 1
  92. #define SDL_LOADSO_DLOPEN  1
  93. //SDL_LOADSO_DISABLED 1 //#undef
  94. #define SDL_THREAD_PTHREAD  1 //SDL_THREADS_DISABLED  //SDL_TIMERS_DISABLED
  95. #define SDL_TIMER_UNIX   1// SDL_VIDEO_DRIVER_DUMMY
  96. #define SDL_VIDEO_DRIVER_FBCON 1#endif

复制代码

注意黑体部分,其实就是打开一些宏定义,将SDL的实现一一打开。
改完了这些以后,还需要改一些代码,主要是video方面的,因为Android Linux的framebuffer设备文件与标准Linux不同,Linux的fb设备文件一般是 /dev/fb0,但Android的设备文件是 /dev/graphics/fb0,打开 $SDL/src/video/fbcon/SDL_fbvideo.c,将191、499行的 "/dev/fb0" 替换成 "/dev/graphics/fb0",保存即可。
再修改 $SDL/src/thread/pthread/SDL_sysmutex.c,将第30行改成: #define FAKE_RECURSIVE_MUTEX 1,就是在后面加一个“1”子,这可能是编译器的一个bug,define默认应该就是“1”的。
现在可以开始编译libSDL.a了,在cygwin或Linux下,进入SDL目录,输入:
make -f Makefile.minimal
视情况面定,一般几分钟后能顺利编译 Android版的 SDL,编译成功后,就需要编译几个SDL的test demo来测试一下 SDL的性能。
进入 test目录,复制 Makefile.in 文件,并改名为 Makefile,将前面一点内容改为:
  1. # Makefile to build the SDL testssrcdir  = .
  2. INCLUDE = -I../include
  3. CC      = arm-none-linux-gnueabi-gcc
  4. EXE     =
  5. CFLAGS  = -g -s -O2 $(INCLUDE) -static
  6. LIBS    = -L.. -lSDL -lpthread
  7. MATHLIB = -lm

复制代码

并将所有的 @MATHLIB@ 替换成 $(MATHLIB),保存后,先编译一个testsprite demo,在命令行输入:
make testsprite
编译成功后,启动Android模拟器,将编译出来的testsprite及icon.bmp上传至一个目录,如 /dev/sample,命令如下:

  1. adb push testspirte /dev/sample/testspriteadb push icon.bmp /dev/sample/icon.bmp

复制代码

最后进入 android 的shell: adb shell,再进入 /dev/sample目录,执行testsprite demo即可:

  1. #cd /dev/sample#chmod 755 testsprite#./testsprite -width 320 -height 480 -bpp 32

复制代码

可以根据模拟器的设置调整 width 及 height,因为程序默认的是 640x480的,初始化时会失败,如果一切正常的话,模拟器就会出现很多黄色的笑脸!按任意键退出,在本人机器上能达到 60 FPS左右,效果图如下:
其他的 demo有兴趣的朋友可以自己编译测试。
 
 
 

Android原生(Native)C开发之四:SDL移植笔记的更多相关文章

  1. Android原生(Native)C开发之一:环境搭建篇

    引用:http://blog.sina.com.cn/s/blog_4a0a39c30100auh9.html Android是基于Linux的操作系统,处理器是ARM的,所以要在Linux或Wind ...

  2. react native ios 开发,基础配置笔记。

    一.获取硬件信息,使用react-native-device-info插件,配置说明: 1.首先需要安装组件:npm install react-native-device-info --save 2 ...

  3. 《React Native 精解与实战》书籍连载「Android 平台与 React Native 混合开发」

    此文是我的出版书籍<React Native 精解与实战>连载分享,此书由机械工业出版社出版,书中详解了 React Native 框架底层原理.React Native 组件布局.组件与 ...

  4. React Native Android原生模块开发实战|教程|心得|怎样创建React Native Android原生模块

    尊重版权,未经授权不得转载 本文出自:贾鹏辉的技术博客(http://blog.csdn.net/fengyuzhengfan/article/details/54691503) 告诉大家一个好消息. ...

  5. React Native之原生模块的开发(Android)学习笔记

      目录 1.为什么我们需要原生模块开发 2.开发Android原生模块的主要流程 3.原生模块开发实战   1.为什么我们需要原生模块开发? 我们在用RN开发App的时候,有时候需要用到一些原生模块 ...

  6. Android平台Native开发与JNI机制详解

    源文链接: http://mysuperbaby.iteye.com/blog/915425 一个Native Method就是一个Java调用非Java代码的接口.一个Native Method是这 ...

  7. Android原生嵌入React Native

    1.首先集成的项目目录 我使用的是直接按照react-native init Project 的格式来导入的,也就是说,我的Android项目目录是跟node_modules是在一个目录下的. 我们i ...

  8. 将React Native集成至Android原生应用

    将React Native集成至Android原生应用 Android Studio 2.1 Preview 4生成的空项目 react-native 环境 0.22.2 初次编译后apk有1.1M, ...

  9. Android原生游戏开发:使用JustWeEngine开发微信打飞机

    使用JustWeEngine开发微信打飞机: 作者博客: 博客园 引擎地址:JustWeEngine 示例代码:EngineDemo JustWeEngine? JustWeEngine是托管在Git ...

随机推荐

  1. vue 过滤器基本使用

    Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化,例如时间戳格式化. 过滤器可以用在: 双花括号插值 v-bind 表达式 (2.1.0+ 开始支持). 过滤器应该被添加在 JavaSc ...

  2. Elasticsearch5.5.1插件开发指南

    Elasticsearch5.5.1插件开发指南 原文地址: https://www.elastic.co/guide/en/elasticsearch/plugins/5.5/plugin-auth ...

  3. Lustre文件系统部署和应用探索

    1. Lustre文件系统概述 2. Lustre文件系统部署 2.1 基本环境 本篇博客将在KVM虚拟机中部署Lustre文件系统. 操作系统版本为CentOS6.5_x86_64.Lustre软件 ...

  4. kvm虚拟化关闭虚拟网卡virbr0的方法

    我们知道:kvm虚拟化环境安装好后,ifconfig会发现多了一个虚拟网卡virbr0这是由于安装和启用了libvirt服务后生成的,libvirt在服务器(host)上生成一个 virtual ne ...

  5. PHP从入门到精通(五)

    字符串三种声明方式 1."":双引号中可以解析变量"{$a}",双引号中可以使用任何转义字符:2.'':单引号中不可以解析变量,单引号中不可以使用转义字符(但是 ...

  6. Python-str-操作-6

    #字符串的索引与切片 s = 'ABCDLSESRF' #索引 s1 = s[0] print(s1) s2 = s[2] print(s2) s3 = s[-1] print(s3) s4 = s[ ...

  7. 使用eclipse利用Junit4进行程序模块的测试

    一.题目简介 通过用户输入年份和月份,然后在控制台显示该年该月的日历. 二.源码的github链接. https://github.com/zhangxinn/test/blob/master/Pri ...

  8. 程序设计第三次作业---C++计算器雏形

    Github链接:https://github.com/Wasdns/object-oriented 题目:程序设计第三次作业 程序设计第三次作业附加 我的程序设计第三次作业附加 代码规范 更新时间: ...

  9. 《软件工程》小组团队项目-小学生四则运算APP(First Sprint)

    <软件工程>团队项目我们小组选择了小学生四则运算APP,在上学期原有的项目基础上进行更新升级.(自我感觉我们团队上学期的小学生四则运算APP是较为成功且实用的,不过这学期学习到了新的知识, ...

  10. HDOJ2099_整数的尾数

    一道我以为不会这么简单,然后暴力盲打竟然给过了的题. HDOJ2099_整数的尾数 #include<stdio.h> #include<stdlib.h> #include& ...