SDL2.0例子代码分析---代码运行平台检测

简介: 简介 SDL2.0例子程序中的 testplatform项目代码分析 ,针对不同的平台 检测字节序 CPU支持的指令集 类型宽度 以及断言 代码+注释 #include #include "SDL.

简介

SDL2.0例子程序中的 testplatform项目代码分析 ,针对不同的平台 检测字节序 CPU支持的指令集 类型宽度 以及断言

代码+注释

#include <stdio.h>

#include "SDL.h"
#include "SDL_endian.h"
#include "SDL_cpuinfo.h"
#include "SDL_assert.h"

/*
 *  该例子代码检测运行平台
 */
//判断变量占用字节数 是否等于 hardcodetype
static int
badsize(size_t sizeoftype, size_t hardcodetype)
{
	return sizeoftype != hardcodetype;
}


//检测系统是否出现错误类型   貌似用处不大这段坑爹代码 
//如果平台类型错误 返回1 否则返回  0
int
TestTypes(SDL_bool verbose)
{
	int error = 0;

	//如果Uint8占用一个字节
	if (badsize(sizeof(Uint8), 1))
	{
		//如果Uint8不等于1那么输出 实际占用尺寸 
		if (verbose)
			SDL_Log("sizeof(Uint8) != 1, instead = %u\n",
			(unsigned int)sizeof(Uint8));
		//错误次数++
		++error;
	}
	//如如下类似 上述 
	if (badsize(sizeof(Uint16), 2)) {
		if (verbose)
			SDL_Log("sizeof(Uint16) != 2, instead = %u\n",
			(unsigned int)sizeof(Uint16));
		++error;
	}
	if (badsize(sizeof(Uint32), 4)) {
		if (verbose)
			SDL_Log("sizeof(Uint32) != 4, instead = %u\n",
			(unsigned int)sizeof(Uint32));
		++error;
	}
	if (badsize(sizeof(Uint64), 8)) {
		if (verbose)
			SDL_Log("sizeof(Uint64) != 8, instead = %u\n",
			(unsigned int)sizeof(Uint64));
		++error;
	}
	if (verbose && !error)
		SDL_Log("All data types are the expected size.\n");

	return (error ? 1 : 0);
}

//测试尾数  也就是机器的字节序  
//windows默认是小端模式 
//也就是 低位先存 原因是 堆栈是 由高地址向低地址扩展
int
TestEndian(SDL_bool verbose)
{
	int error = 0;
	Uint16 value = 0x1234;
	int real_byteorder;
	Uint16 value16 = 0xCDAB;
	Uint16 swapped16 = 0xABCD;
	Uint32 value32 = 0xEFBEADDE;
	Uint32 swapped32 = 0xDEADBEEF;
	Uint64 value64, swapped64;

   //定义64位置 也就是 0x00000000EFBEADDE
	value64 = 0xEFBEADDE;
	//右移动32位  也就是四个字节
	value64 <<= 32;
	//将低位置为0xCDAB3412
	value64 |= 0xCDAB3412; 
	//如下操作和value64雷同 
	swapped64 = 0x1234ABCD;
	swapped64 <<= 32;
	swapped64 |= 0xDEADBEEF;
	//打印机器字节序 是大端模式还是小端模式 
	if (verbose) {
		SDL_Log("Detected a %s endian machine.\n",
			(SDL_BYTEORDER == SDL_LIL_ENDIAN) ? "little" : "big");
	}
	//我们自己判断字节序 将value转换为 char类型之后 由于数据丢失 变成了0x34 在windows下低位先存 
	//所以 左移4位后变成了0x3了  也就是小端口模式
	if ((*((char *)&value) >> 4) == 0x1) {
		real_byteorder = SDL_BIG_ENDIAN;
	}
	else {
		real_byteorder = SDL_LIL_ENDIAN;
	}
	//如果我们分析的 真正的字节序不等于 SDL给出的字节序 那么 输出真正的字节序 error++
	if (real_byteorder != SDL_BYTEORDER) {
		if (verbose) {
			SDL_Log("Actually a %s endian machine!\n",
				(real_byteorder == SDL_LIL_ENDIAN) ? "little" : "big");
		}
		++error;
	}
	//交换字节序 输出 
	if (verbose) {
		SDL_Log("Value 16 = 0x%X, swapped = 0x%X\n", value16,
			SDL_Swap16(value16));
	}
	//如果交换后的值不等于 0xABCD 
	if (SDL_Swap16(value16) != swapped16) {
		if (verbose) {
			SDL_Log("16 bit value swapped incorrectly!\n");
		}
		++error;
	}
	//交换32位高度字节序 
	if (verbose) {
		SDL_Log("Value 32 = 0x%X, swapped = 0x%X\n", value32,
			SDL_Swap32(value32));
	}
	if (SDL_Swap32(value32) != swapped32) {
		if (verbose) {
			SDL_Log("32 bit value swapped incorrectly!\n");
		}
		++error;
	}
	if (verbose) {  
		//如果是微软的编译器 也就是VC下 打印出64位的交换字节序之后的值
#ifdef _MSC_VER
		SDL_Log("Value 64 = 0x%I64X, swapped = 0x%I64X\n", value64,
			SDL_Swap64(value64));
#else  
		//如果是其他编译器 那么  64位置 ULONG 就需要定义为 unsigned long long 来代表 64位无符号 Integer
		SDL_Log("Value 64 = 0x%llX, swapped = 0x%llX\n",
			(unsigned long long) value64,
			(unsigned long long) SDL_Swap64(value64));
#endif
	}
	//判断交换后的值是否等于 0x1234ABCDDEADBEEF;
	if (SDL_Swap64(value64) != swapped64) {
		if (verbose) {
			SDL_Log("64 bit value swapped incorrectly!\n");
		}
		++error;
	}
	//返回错误状态
	return (error ? 1 : 0);
}


//检测CPU 的特性
int
TestCPUInfo(SDL_bool verbose)
{  
	if (verbose) {  
		//打印CPU数量
		SDL_Log("CPU count: %d\n", SDL_GetCPUCount()); 
		//获取CPU Cache LIne的大小 即CPU 一次从主存Copy的内存大小
		SDL_Log("CPU cache line size: %d\n", SDL_GetCPUCacheLineSize());
        //CPU是否支持RDTSC指令 读取时间标签计数器
		SDL_Log("RDTSC %s\n", SDL_HasRDTSC() ? "detected" : "not detected");
		///cpu 是否支持 Altivec  AltiVec提供了32个128比特向量暂存器,与之相比,SSE和SSE2只提供了8个
		SDL_Log("AltiVec %s\n", SDL_HasAltiVec() ? "detected" : "not detected");
		//cpu是否支持 MMX指令 
		SDL_Log("MMX %s\n", SDL_HasMMX() ? "detected" : "not detected"); 
		//CPU是否支持SIMD , 由AMD开发的一套SIMD多媒体指令集,支持单精度浮点数的矢量运算,用于增强x86架构的计算机在三维图像处理上的性能
		SDL_Log("3DNow! %s\n", SDL_Has3DNow() ? "detected" : "not detected"); 
		//cpu是否支持SSE
		SDL_Log("SSE %s\n", SDL_HasSSE() ? "detected" : "not detected");
		//SSE2是否支持 如下都是判断CPU是否支持一下加速指令集 
		SDL_Log("SSE2 %s\n", SDL_HasSSE2() ? "detected" : "not detected");
		SDL_Log("SSE3 %s\n", SDL_HasSSE3() ? "detected" : "not detected");
		SDL_Log("SSE4.1 %s\n", SDL_HasSSE41() ? "detected" : "not detected");
		SDL_Log("SSE4.2 %s\n", SDL_HasSSE42() ? "detected" : "not detected");
		SDL_Log("AVX %s\n", SDL_HasAVX() ? "detected" : "not detected");
		//获取系统RAM大小 也就是内存大小
		SDL_Log("System RAM %d MB\n", SDL_GetSystemRAM());
	}
	return (0);
}

int
TestAssertions(SDL_bool verbose)
{  
	//sdl断言
	SDL_assert(0);
	SDL_assert_release(1);
	SDL_assert_paranoid(1);
	SDL_assert(0 || 1);
	SDL_assert_release(0 || 1);
	SDL_assert_paranoid(0 || 1);

#if 0   /* enable this to test assertion failures. */
	SDL_assert_release(1 == 2);
	SDL_assert_release(5 < 4);
	SDL_assert_release(0 && "This is a test");
#endif

	{  
		//获取所有的断言 链表  在调用SDL_GetAssertionReport 之前 
		/************************************************************************/
/*
			typedef struct SDL_assert_data
			{
			int always_ignore;
			unsigned int trigger_count;
			const char *condition;
			const char *filename;
			int linenum;
			const char *function;
			const struct SDL_assert_data *next;
			} SDL_assert_data;                                                                     */
		/************************************************************************/
		const SDL_assert_data *item = SDL_GetAssertionReport(); 
		//我们发现就是取出所有的 断言结果 输出
		while (item) {
			SDL_Log("'%s', %s (%s:%d), triggered %u times, always ignore: %s.\n",
				item->condition, item->function, item->filename,
				item->linenum, item->trigger_count,
				item->always_ignore ? "yes" : "no");
			item = item->next;
		}
	}
	return (0);
}

int
main(int argc, char *argv[])
{
	SDL_bool verbose = SDL_TRUE;
	int status = 0;

	/* 设置特定日志的优先级 这里是应用程序日志  */
	SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
	//如果参数1= -q 那么设置 verbose=faslse
	if (argv[1] && (SDL_strcmp(argv[1], "-q") == 0)) {
		verbose = SDL_TRUE;
	}
	if (verbose) {
		SDL_Log("This system is running %s\n", SDL_GetPlatform());
	}
	//测试变量尺寸
	status += TestTypes(verbose);
	//测试尾数  也就是测试机器的字节序
	status += TestEndian(verbose);
	//测试CPU信息
	status += TestCPUInfo(verbose);
	//测试断言
	status += TestAssertions(verbose);

	return status;
}
<img src="http://img.blog.csdn.net/20141220011403769?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveXVlNzYwMzgzNQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />


目录
相关文章
|
4月前
|
C++
c cpp 代码 数据竞争 分析, 以及 内存泄露 分析 工具 使用 demo
c cpp 代码 数据竞争 分析, 以及 内存泄露 分析 工具 使用 demo
30 0
|
前端开发
前端hook项目pc总结笔记-打印实现局部打印
前端hook项目pc总结笔记-打印实现局部打印
70 0
|
Java
JDK绘制文字的流程与代码分析
JDK绘制文字的流程与代码分析
84 0
|
开发框架 Java 开发者
Hello World细节-自动配置|学习笔记
快速学习Hello World细节-自动配置
82 0
Hello World细节-自动配置|学习笔记
|
Python
Python 技术篇-在cmd命令提示行里模拟动态下载进度条实例演示,cmd清除日志、打印动态内容方法
Python 技术篇-在cmd命令提示行里模拟动态下载进度条实例演示,cmd清除日志、打印动态内容方法
475 0
Python 技术篇-在cmd命令提示行里模拟动态下载进度条实例演示,cmd清除日志、打印动态内容方法
|
Web App开发 JavaScript 前端开发
通过一个简单的例子,了解 Cypress 的运行原理
Cypress 是 SAP Spartacus 前端 e2e 测试使用的框架。 Cypress 并不是广义上的 web 自动化工具,并不适合编写脚本来测试已经处于生产状态下的不受测试者控制的网站。 Cypress is not a general purpose web automation tool. It is poorly suited for scripting live, production websites not under your control.
199 0
通过一个简单的例子,了解 Cypress 的运行原理
|
Web App开发 前端开发 JavaScript
小程序学习---初识小程序
小程序已经公测一年多了,最近闲来无事,开始着手学习一下小程序,来博客做一下记录吧。。。 一、张小龙对小程序的定义:        1、不需要下载安装即可应用(tips:安装包小于2M)。
1085 0