Android原生(Native)C開發



  1. 轉載: Android原生(Native)C開發之一 環境搭建篇
  2. 轉載: Android原生(Native)C開發之二 framebuffer篇
  3. 轉載: Android原生(Native)C開發之三 鼠標事件篇(捕鼠記)
  4. 轉載: Android原生(Native)C開發之四 SDL移植筆記
  5. 轉載: Android原生(Native)C開發之五 zlib移植筆記
  6. 轉載: Android原生(Native)C開發之六 libpng移植筆記


轉載: Android原生(Native)C開發之一 環境搭建篇 php

2009年02月25日,星期三

Android是基於Linux的操做系統,處理器是ARM的,因此要在Linux或Windows等x86系統上編譯Android能運行的程序,你須要一個交叉編譯器。 html

在Linux下面,你能夠自已編譯一個交叉編譯環境,但Windows下面,就比較複雜(也能夠在cygwin中編譯一個),但你能夠選擇下載一個現成的交叉編譯環境: linux

http://www.codesourcery.com/gnu_toolchains/arm/download.html android

Windows: http://www.codesourcery.com/gnu_toolchains/arm/portal/package3400/public/arm-none-linux-gnueabi/arm-2008q3-41-arm-none-linux-gnueabi.exe web

Linux: http://www.codesourcery.com/gnu_toolchains/arm/portal/package3399/public/arm-none-linux-gnueabi/arm-2008q3-41-arm-none-linux-gnueabi.bin 算法

安裝好了以後,將 CodeSourcery編譯器的bin目錄 (個人是D:\Program Files\CodeSourcery\Sourcery G++ Lite\bin)加入你的PATH環境變量中,就能夠開始你的Android Native C開發之旅了,寫好一個簡單的C程序: shell

#include windows

int main(int argc, char** argv) {
printf(」hello android!\nI’m %s!\nI like android very much!!!\n」, 「Martin Foo」); api

return 0;
} 網絡

另存成hello.c,進入命令行模式,確保交叉編譯器的bin目錄,及Android SDK的tools目錄在你的系統環境變量的path裏面,用以下命令編譯:

arm-none-linux-gnueabi-gcc -static hello.c -o hello

注意,必定要加上static參數,不然編譯好的可能會在Android上不能運行。

啓動Android模擬器,用以下命令將文件push到Android模擬器上:

adb shell mkdir /dev/sample
adb push hello /dev/sample/hello

adb shell chmod 777 /dev/sample/hello

先建立 /dev/sample目錄,再將編譯好的hello上傳上去,最後將hello改爲可執行的。

再進入命令行模式,進入Android的shell環境:

adb shell

#cd /dev/sample

#./hello

進入 /dev/sample目錄,執行hello,運行結果以下圖:

Android Native編譯環境

Android Native編譯環境

標籤:Androidlib
發佈在 Gphone | 一條評論 »

轉載: Android原生(Native)C開發之二 framebuffer篇

2009年02月25日,星期三

如對Android原生(Natvie)C開發還任何疑問,請參閱http://emck.avaw.com/?p=205

雖然如今能經過交叉環境編譯程序,並push到Android上執行,但那只是console臺程序,是否是有些單調呢?下面就要看如何經過Linux的 framebuffer 技術在Android上畫圖形,關於Linux的framebuffer技術,這裏就再也不詳細講解了,請你們google一下。

操做framebuffer的主要步驟以下:

一、打開一個可用的FrameBuffer設備;
二、經過mmap調用把顯卡的物理內存空間映射到用戶空間;
三、更改內存空間裏的像素數據並顯示;

四、退出時關閉framebuffer設備。

下面的這個例子簡單地用framebuffer畫了一個漸變的進度條,代碼 framebuf.c 以下:

#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>

inline static unsigned short int make16color(unsigned char r, unsigned char g, unsigned char b)
{
return (
(((r >> 3) & 31) << 11) |
(((g >> 2) & 63) << 5) |
((b >> 3) & 31) );
}

int main() {
int fbfd = 0;
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
long int screensize = 0;
char *fbp = 0;
int x = 0, y = 0;
int guage_height = 20, step = 10;
long int location = 0;

// Open the file for reading and writing
fbfd = open(」/dev/graphics/fb0″, O_RDWR);
if (!fbfd) {
printf(」Error: cannot open framebuffer device.\n」);
exit(1);
}
printf(」The framebuffer device was opened successfully.\n」);

// Get fixed screen information
if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {
printf(」Error reading fixed information.\n」);
exit(2);
}

// Get variable screen information
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
printf(」Error reading variable information.\n」);
exit(3);
}

printf(」sizeof(unsigned short) = %d\n」, sizeof(unsigned short));
printf(」%dx%d, %dbpp\n」, vinfo.xres, vinfo.yres, vinfo.bits_per_pixel );
printf(」xoffset:%d, yoffset:%d, line_length: %d\n」, vinfo.xoffset, vinfo.yoffset, finfo.line_length );

// Figure out the size of the screen in bytes
screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;;

// Map the device to memory
fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
fbfd, 0);

if ((int)fbp == -1) {
printf(」Error: failed to map framebuffer device to memory.\n」);
exit(4);
}
printf(」The framebuffer device was mapped to memory successfully.\n」);

//set to black color first
memset(fbp, 0, screensize);
//draw rectangle
y = (vinfo.yres – guage_height) / 2 – 2; // Where we are going to put the pixel
for (x = step – 2; x < vinfo.xres – step + 2; x++) {
location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
(y+vinfo.yoffset) * finfo.line_length;

*((unsigned short int*)(fbp + location)) = 255;
}

y = (vinfo.yres + guage_height) / 2 + 2; // Where we are going to put the pixel
for (x = step – 2; x < vinfo.xres – step + 2; x++) {
location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
(y+vinfo.yoffset) * finfo.line_length;

*((unsigned short int*)(fbp + location)) = 255;
}

x = step – 2;
for (y = (vinfo.yres – guage_height) / 2 – 2; y < (vinfo.yres + guage_height) / 2 + 2; y++) {
location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
(y+vinfo.yoffset) * finfo.line_length;

*((unsigned short int*)(fbp + location)) = 255;
}

x = vinfo.xres – step + 2;
for (y = (vinfo.yres – guage_height) / 2 – 2; y < (vinfo.yres + guage_height) / 2 + 2; y++) {
location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
(y+vinfo.yoffset) * finfo.line_length;

*((unsigned short int*)(fbp + location)) = 255;
}

// Figure out where in memory to put the pixel
for ( x = step; x < vinfo.xres – step; x++ ) {
for ( y = (vinfo.yres – guage_height) / 2; y < (vinfo.yres + guage_height) / 2; y++ ) {
location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
(y+vinfo.yoffset) * finfo.line_length;

if ( vinfo.bits_per_pixel == 32 ) {
*(fbp + location) = 100; // Some blue
*(fbp + location + 1) = 15+(x-100)/2; // A little green
*(fbp + location + 2) = 200-(y-100)/5; // A lot of red
*(fbp + location + 3) = 0; // No transparency
} else { //assume 16bpp
unsigned char b = 255 * x / (vinfo.xres – step);
unsigned char g = 255; // (x – 100)/6 A little green
unsigned char r = 255; // A lot of red
unsigned short int t = make16color(r, g, b);
*((unsigned short int*)(fbp + location)) = t;
}
}
//printf(」x = %d, temp = %d\n」, x, temp);
//sleep to see it
usleep(200);
}
//clean framebuffer
munmap(fbp, screensize);
close(fbfd);

return 0;
}

注意,在Android環境,framebuffer設備不是象linux同樣的 /dev/fb0,而是 /dev/graphics/fb0 

fbfd = open(」/dev/graphics/fb0″, O_RDWR);

打開framebuffer設備,

fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
fbfd, 0);

將設備map到一塊內存,而後就能夠操做這塊內存空間來顯示你想畫的圖形了。

最後別忘了關閉設備:

munmap(fbp, screensize);
close(fbfd);

效果圖以下:

Android framebuffer截圖

Android framebuffer截圖

標籤:Androidframebufferlib
發佈在 Gphone | 評論關閉

轉載: Android原生(Native)C開發之三 鼠標事件篇(捕鼠記)

2009年02月25日,星期三

在作SDL至Android的移植時,鍵盤事件是能正常捕獲到,看了SLD的源碼,發現用的device是 /dev/tty0,可是鼠標叫是不能成功捕獲,老是獲得 0,運行命令查看devices時,顯示以下:

cat /proc/bus/input/devices
cat /proc/bus/input/devices
I: Bus=0000 Vendor=0000 Product=0000 Version=0000
N: Name=」qwerty」
P: Phys=
S: Sysfs=/class/input/input0
U: Uniq=
H: Handlers=kbd mouse0 event0
B: EV=2f
B: KEY=ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff f
fffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe
B: REL=3
B: ABS=7
B: SW=1

進入 /dev/input 目錄,發如今3個device文件:mice,mouse0,event0,分別 cat這3個文件,發現只有 event0 有反應,以下圖:

Android Native 鼠標事件截圖1

Android Native 鼠標事件截圖1

並且不論是點擊鼠標仍是按鍵,都有反應,但顯示的是一堆亂碼,並且點擊鼠標出來的東西要多一點,難道這就是傳說是的 touchscreen ?!

爲了分析 event0 的返回值,寫了一段代碼 testmice.c,以下:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <linux/input.h>

static int event0_fd = -1;
struct input_event ev0[64];

//for handling event0, mouse/key/ts
static int handle_event0() {
int button = 0, realx = 0, realy = 0, i, rd;

rd = read(event0_fd, ev0, sizeof(struct input_event) * 64);
if ( rd < sizeof(struct input_event) ) return 0;

for (i = 0; i < rd / sizeof(struct input_event); i++) {
printf(」", ev0[i].type, ev0[i].code, ev0[i].value);
if (ev0[i].type == 3 && ev0[i].code == 0)
realx = ev0[i].value;
else if (ev0[i].type == 3 && ev0[i].code == 1)
realy = ev0[i].value;
else if (ev0[i].type == 1) {
if (ev0[i].code == 158) {
//if key esc then exit
return 0;
}
} else if (ev0[i].type == 0 && ev0[i].code == 0 && ev0[i].value == 0) {
realx = 0, realy = 0;
}
printf(」event(%d): type: %d; code: %3d; value: %3d; realx: %3d; realy: %3d\n」, i,
ev0[i].type, ev0[i].code, ev0[i].value, realx, realy);
}

return 1;
}

int main(void) {
int done = 1;
printf(」sizeof(struct input_event) = %d\n」, sizeof(struct input_event));

event0_fd = open(」/dev/input/event0″, O_RDWR);

if ( event0_fd < 0 )
return -1;

while ( done ) {
printf(」begin handel_event0…\n」);
done = handle_event0();
printf(」end handel_event0…\n」);
}

if ( event0_fd > 0 ) {
close(event0_fd);
event0_fd = -1;
}

return 0;

}

用交叉編譯器編譯好後(編譯過程就再也不詳述,請參見 blog:Android原生(Native)C開發之一:環境搭建篇),push至 emulator後執行後,切換到android 模擬器,在模擬器上點幾下mouse,程序就會打出你點擊的信息,效果以下,果真能正確獲得點擊的 mouse pos,以下圖:

Android Native 鼠標事件截圖2

Android Native 鼠標事件截圖2

分析上面的返回值,發現當按下 mouse left button 時,會獲得4個事件,2個 type = 3 的事件返回了 pos x, pos y 的值,即mouse click pos, 另外1個 type = 1 的事件是按鍵事件(keydown),value就是按下的鍵的key,爲0的應該就是 key的release事件,當鬆開 mouse時,也會獲得兩個 type = 1, 0 的事件,沒有仔細去看它們的返回值,反正已經正確獲得了 mosue的事件,下一步就是改SDL的事件驅動源碼了…

參考連接: USB Mouse and Touch Screen ( TS ) Input(EN)[http://www.webkinesia.com/games/embedded.php]

標籤:Androidevent mouselib
發佈在 Gphone | 評論關閉

轉載: Android原生(Native)C開發之四 SDL移植筆記

2009年02月25日,星期三

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 的內容改爲以下:

# Makefile to build the SDL library

INCLUDE = -I./include
CFLAGS = -g -s -O2 $(INCLUDE)
CC = arm-none-linux-gnueabi-gcc
AR = arm-none-linux-gnueabi-ar
RANLIB = arm-none-linux-gnueabi-ranlib

CONFIG_H = include/SDL_config.h
TARGET = libSDL.a
SOURCES = \
src/*.c \
src/audio/*.c \
src/cdrom/*.c \
src/cpuinfo/*.c \
src/events/*.c \
src/file/*.c \
src/joystick/*.c \
src/stdlib/*.c \
src/thread/*.c \
src/timer/*.c \
src/video/*.c \
src/audio/dsp/*.c \
src/audio/dma/*.c \
src/video/fbcon/*.c \
src/joystick/dummy/*.c \
src/cdrom/dummy/*.c \
src/thread/pthread/*.c \
src/timer/unix/*.c \
src/loadso/dlopen/*.c \

OBJECTS = $(shell echo $(SOURCES) | sed -e ’s,\.c,\.o,g’)

all: $(TARGET)

$(TARGET): $(CONFIG_H) $(OBJECTS)
$(AR) crv $@ $^
$(RANLIB) $@

$(CONFIG_H):
cp $(CONFIG_H).default $(CONFIG_H)

clean:
rm -f $(TARGET) $(OBJECTS)

最後將$SDL\include\SDL_config_minimal.h的內容改爲以下:

#ifndef _SDL_config_minimal_h
#define _SDL_config_minimal_h

#include 「SDL_platform.h」

#include <stdarg.h>

typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef signed short int16_t;
typedef unsigned short uint16_t;
typedef signed int int32_t;
typedef unsigned int uint32_t;
typedef unsigned int size_t;
//typedef unsigned long uintptr_t;

#define HAVE_LIBC 1

#ifdef HAVE_LIBC

#define HAVE_ALLOCA_H 1
#define HAVE_SYS_TYPES_H 1
#define HAVE_STDIO_H 1
#define STDC_HEADERS 1
#define HAVE_STDLIB_H 1
#define HAVE_STDARG_H 1
#define HAVE_MALLOC_H 1
#define HAVE_MEMORY_H 1
//#define HAVE_STRING_H 1
//#define HAVE_STRINGS_H 1
#define HAVE_INTTYPES_H 1
#define HAVE_STDINT_H 1
#define HAVE_CTYPE_H 1
#define HAVE_MATH_H 1
//#define HAVE_ICONV_H 1
#define HAVE_SIGNAL_H 1
#define HAVE_ALTIVEC_H 1
#define HAVE_MALLOC 1
#define HAVE_CALLOC 1
#define HAVE_REALLOC 1
#define HAVE_FREE 1
#define HAVE_ALLOCA 1
#define HAVE_GETENV 1
#define HAVE_PUTENV 1
#define HAVE_UNSETENV 1
#define HAVE_QSORT 1
#define HAVE_ABS 1
//#define HAVE_BCOPY 1
//#define HAVE_MEMSET 1
//#define HAVE_MEMCPY 1
//#define HAVE_MEMMOVE 1
//#define HAVE_MEMCMP 1
//#define HAVE_STRLEN 1
//#define HAVE_STRLCPY 1
//#define HAVE_STRLCAT 1
//#define HAVE_STRDUP 1
#define HAVE__STRREV 1
#define HAVE__STRUPR 1
#define HAVE__STRLWR 1
//#define HAVE_INDEX 1
#define HAVE_RINDEX 1
//#define HAVE_STRCHR 1
#define HAVE_STRRCHR 1
#define HAVE_STRSTR 1
#define HAVE_ITOA 1
#define HAVE__LTOA 1
#define HAVE__UITOA 1
#define HAVE__ULTOA 1
#define HAVE_STRTOL 1
#define HAVE_STRTOUL 1
#define HAVE__I64TOA 1
#define HAVE__UI64TOA 1
#define HAVE_STRTOLL 1
#define HAVE_STRTOULL 1
#define HAVE_STRTOD 1
#define HAVE_ATOI 1
#define HAVE_ATOF 1
#define HAVE_STRCMP 1
#define HAVE_STRNCMP 1
#define HAVE__STRICMP 1
#define HAVE_STRCASECMP 1
#define HAVE__STRNICMP 1
#define HAVE_STRNCASECMP 1
#define HAVE_SSCANF 1
#define HAVE_SNPRINTF 1
#define HAVE_VSNPRINTF 1
//#define HAVE_ICONV
#define HAVE_SIGACTION 1
#define HAVE_SETJMP 1
#define HAVE_NANOSLEEP 1
//#define HAVE_CLOCK_GETTIME 1
#define HAVE_DLVSYM 1
#define HAVE_GETPAGESIZE 1
#define HAVE_MPROTECT 1
#else

#include <stdarg.h>
#endif
//#define HAVE_STDIO_H 1
//#define HAVE_STDINT_H 1

//#define SDL_INPUT_TSLIB 1 //touch screen input
#define SDL_AUDIO_DRIVER_OSS 1 // SDL_AUDIO_DRIVER_DUMMY
#define SDL_CDROM_DISABLED 1
#define SDL_JOYSTICK_DISABLED 1
#define SDL_LOADSO_DLOPEN 1
//SDL_LOADSO_DISABLED 1 //#undef
#define SDL_THREAD_PTHREAD 1 //SDL_THREADS_DISABLED

//SDL_TIMERS_DISABLED
#define SDL_TIMER_UNIX 1

// SDL_VIDEO_DRIVER_DUMMY
#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,將19一、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,將前面一點內容改成:

# Makefile to build the SDL tests

srcdir = .
INCLUDE = -I../include
CC = arm-none-linux-gnueabi-gcc
EXE =
CFLAGS = -g -s -O2 $(INCLUDE) -static
LIBS = -L.. -lSDL -lpthread
MATHLIB = -lm

並將全部的 @MATHLIB@ 替換成 $(MATHLIB),保存後,先編譯一個testsprite demo,在命令行輸入:

make testsprite

編譯成功後,啓動Android模擬器,將編譯出來的testsprite及icon.bmp上傳至一個目錄,如 /dev/sample,命令以下:

adb push testspirte /dev/sample/testsprite

adb push icon.bmp /dev/sample/icon.bmp

最後進入 android 的shell: adb shell,再進入 /dev/sample目錄,執行testsprite demo便可:

#cd /dev/sample

#chmod 755 testsprite

#./testsprite -width 320 -height 480 -bpp 32

能夠根據模擬器的設置調整 width 及 height,由於程序默認的是 640×480的,初始化時會失敗,若是一切正常的話,模擬器就會出現不少黃色的笑臉!按任意鍵退出,在本人機器上能達到 60 FPS左右,效果圖以下:

Android Native SDL截圖

Android Native SDL截圖

其餘的 demo有興趣的朋友能夠本身編譯測試。

標籤:Androidlibsdl
發佈在 Gphone | 評論關閉

轉載: Android原生(Native)C開發之五 zlib移植筆記

2009年02月25日,星期三
Android zlib 截圖

Android zlib 截圖

zlib(http://www.zlib.net)是一套很是流行的且開源的壓縮、解壓縮庫,由Jean-loup Gailly與Mark Adler所開發,第一版0.9版在1995年5月1日發表。zlib使用DEFLATE演算法,最初是爲libpng函式庫所寫的,後來廣泛爲許多軟體所使用。

zlib當前版本是 1.2.3,其移植性很是好,本人已經在Windows、Linux、WinCE、Symbian等平臺成功地移植了zlib,固然也包括今天要移植的平臺:Android。

首先,從zlib 的官方網站下載zlib的源代碼:zlib123.zip,解壓後獲得一個目錄zlib-1.2.3,zib已經提供好了一個Makefile,改動幾行(1九、20、2七、3六、37)就能夠動手編譯了,改動以下:

……
CC = arm-none-linux-gnueabi-gcc

CFLAGS = -O2
……
LDFLAGS=libz.a -s -static
……
AR = arm-none-linux-gnueabi-ar rc
RANLIB = arm-none-linux-gnueabi-ranlib

……

進入zlib-1.2.3目錄,在命令行輸入:make 便可。

最後會生成兩個可Android可執行文件: example 、minigzip 。

運行Android模擬器, 進入命令行,將兩個可執行文件 push 至Android模擬器,再執行,命令以下:

$adb push example /dev/sample/example
$adb push minigzip /dev/sample/minigzip
$adb shell chmod 777 /dev/sample/*
$adb shell
#cd /dev/sample
#./example

zlib version 1.2.3 = 0×1230, compile flags = 0×55

uncompress(): hello, hello!

gzread(): hello, hello!

gzgets() after gzseek: hello!

inflate(): hello, hello!

large_inflate(): OK

after inflateSync(): hello, hello!

inflate with dictionary: hello, hello!

#ls -l

ls -l
-rwxrwxrwx root root 513228 2008-11-10 04:18 minigzip
-rwxrwxrwx root root 517640 2008-11-10 04:18 example
-rwxrwxrwx root root 31 2008-11-10 04:28 foo.gz

#exit

$adb pull /dev/sample/foo.gz d:/foo.gz

其中,「$」是Linux或Cygwin命令行的提示符,#是Android命令行的提示符。

最後,用 ls -l 命令查看當前目錄,會發現一個 foo.gz的文件,這個文件就是example生成的,退出adb shell,用命令: adb pull /dev/sample/foo.gz d:/foo.gz 可將模擬器上生成的文件 foo.gz pull至D盤根目錄,用winrar或7zip可查看這個文件的內容,正是代碼中所寫的「hello, hello! 」!

至此,zlib移植Android平臺運行成功!

標籤:Androidlib
發佈在 Gphone | 一條評論 »

轉載: Android原生(Native)C開發之六 libpng移植筆記

2009年02月25日,星期三

libpng(http://www.libpng.org/)是讀取PNG(Portable Network Graphic Format)文件的最官方的函數庫,因此在介紹libpng以前,有必要先介紹下PNG文件。

PNG是20世紀90年代中期開始開發的圖像文件存儲格式,其目的是企圖替代GIF和TIFF文件格式,同時增長一些GIF文件格式所不具有的特性。流式網絡圖形格式(Portable Network Graphic Format,PNG)名稱來源於非官方的「PNG’s Not GIF」,是一種位圖文件(bitmap file)存儲格式,讀成「ping」。PNG用來存儲灰度圖像時,灰度圖像的深度可多到16位,存儲彩色圖像時,彩色圖像的深度可多到48位,而且還可存儲多到16位的α通道數據。PNG使用從LZ77派生的無損數據壓縮算法。

PNG用了無損數據壓縮算法,用的壓縮庫上是上一篇介紹的zlib,編譯libpng前,要先編譯zlib(請參見上一篇:Android原生(Native)C開發之五:zlib移植筆記)。

先從sourceforge下載libpng的最新版本:1.2.33,請選擇without config script版本:bz2格式zip格式,這個版本沒有configure文件,由於基本上不須要改動libpng的設置,就能編譯經過。

將下載的源碼包解開,獲得時一個名爲 libpng-1.2.33 的目錄,將 scripts\makefile.gcc 複製到 libpng-1.2.33\Makefile,將此文件的 8 – 27 行改爲以下便可(粗體爲增長部分):


ZLIBINC = ../zlib-1.2.3
ZLIBLIB = ../zlib-1.2.3

# Compiler, linker, lib and other tools
CC = arm-none-linux-gnueabi-gcc
LD = $(CC)
AR_RC = arm-none-linux-gnueabi-ar rcs
RANLIB = arm-none-linux-gnueabi-ranlib
RM_F = rm -f

CDEBUG = -g -DPNG_DEBUG=5
LDDEBUG =
CRELEASE = -O2
LDRELEASE = -s -static
#CFLAGS = -W -Wall $(CDEBUG)
CFLAGS = -W -Wall $(CRELEASE)
#LDFLAGS = $(LDDEBUG)
LDFLAGS = $(LDRELEASE)
LIBS = -lz -lm

在Cygwin或Linux命令行方式進入libpng-1.2.33目錄,輸入: make 便可成功編譯libpng,獲得時的靜態庫libpng.a及可執行文件 pngtest。

用 emulator -noskin 命令啓動 Android 模擬器,將pngtest上傳到模擬器,便可測試pngtest:

$adb shell mkdir /dev/sample
$adb push pngtest /dev/sample
$adb push pngtest.png /dev/sample
$adb shell chmod 777 /dev/sample/pngtest
$adb shell
#cd /dev/sample
#./pngtest pngtest.png
Testing libpng version 1.2.33
with zlib version 1.2.3

libpng version 1.2.33 – October 31, 2008
Copyright (c) 1998-2008 Glenn Randers-Pehrson
Copyright (c) 1996-1997 Andreas Dilger
Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
library (10233): libpng version 1.2.33 – October 31, 2008

pngtest (10233): libpng version 1.2.33 – October 31, 2008
sizeof(png_struct)=984, sizeof(png_info)=288
Testing pngtest.png:
Pass 0: rwrwrwrwrwrwrwrwrw
Pass 1: rwrwrwrwrwrwrwrwrw
Pass 2: rwrwrwrwrwrwrwrw
Pass 3: rwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrw
Pass 4: rwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrw
Pass 5: rwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrw
rwrwrwrw
Pass 6: rwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrw
rwrwrwrwrw
PASS (9782 zero samples)
Filter 0 was used 21 times
Filter 1 was used 15 times
Filter 2 was used 52 times
Filter 3 was used 10 times
Filter 4 was used 33 times
tIME = 7 Jun 1996 17:58:08 +0000
libpng passes test

其中」$」爲cygwin的命令提示符,」#」爲 adb shell的命令提示符,測試以下圖所示:

Google libpng截圖

Google libpng截圖

相關文章
相關標籤/搜索