K-Res

OpenWRT下libv4l的编译问题(uClibc++、stdc++相关)

最近研究路由器上的摄像头监控,要用到libv4l2的库,结果用OpenWRT SDK编译时却遇到了问题,路由器cpu是MT7620A,用的SDK是OpenWrt-SDK-ramips-for-linux-x86_64-gcc-4.8-linaro_uClibc-0.9.33.2,用./scripts/feeds安装了libv4l后,直接make报错:

In file included from v4l2-compliance.cpp:37:0:
v4l2-compliance.h:25:18: fatal error: cerrno: No such file or directory
 #include <cerrno>

看了下,是c++写法下的errno头文件找不到,V=s看了详细日志,-I的头文件搜索路径里确实没有cerrno,但是这个文件确实存在于这里:staging_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/usr/include/uClibc++/,也就是说-I少了个带uClibc++的路径,看了半天sdk里的各种.mk,也没找到什么配置参数方面的玄机,可又不想傻加上个-I,或者都改成errno.h,于是开始搜索…
Continue reading…

Android应用图标修改后真机显示不更新的问题及mipmap图标

问题大致就如标题描述的那样,应用图标修改后重新打包安装到设备上时并没有变化,当然,前提是已经排除了人为因素导致的res内图标文件替错等原因。许久以前,在Android的原始时期,1.6、2.2时代时,就曾经在HTC的Sense UI上遇到过类似问题,当时也没太在意,现在在OnePlus One上(CM12s系统)又遇到了同样的问题,决定彻查一下原因。
百度下发现MIUI等也有类似的问题,基本确定是Launcher对应用图标建立了缓存,最直接的破除缓存的方法就是修改应用的Package Name,换包名后重装图标就会显示正确,明显就是没有缓存的特征!然而,应用发布过后一般是不会更换包名的,所以这个方法实际应用意义不大,仅仅是确认了这个图标缓存的机制。
这之后又查到了一些解决方法,如删除 /data/system/customized_icons 路径下的响应图标(这个需要root,且在5.0上没有这个路径,估计是Pre Lollipop用的),再如杀掉Launcher的进程,强制其重启刷新缓存(这个貌似不科学,因为重启Launcher的话应该和重启系统性质是一样的,但是我试过重启机器后图标依然没有刷新,再有就是CM上也没找到明显的Launcher进程,只有个systemui看起来比较像,不过也不敢强制结束,怕玩坏啊,哈哈!),这之后又自己尝试了下别的可能作为缓存key的要素,如改VersionCode,改VersionName,同时改VersionCode和VersionName,改res下的图标文件名等,均无效!
Continue reading…

iOS Android平台下的wchar_t默认size问题

很久以前曾经被wchar的问题在iOS和Android上被坑过,这次是在参研一份有年头的代码时又遇到了宽字符的问题,当然,也是和wchar有关系的,就是这个wchar在各个系统平台下的sizeof问题,关键的是一段UTF-8转UTF-16的代码:

size_t Utf8ToUtf16(const char* src_, wchar_t* dest_, size_t destlen_, size_t srclen_ /*= 0*/) 
{
	if (srclen_ == 0)
		srclen_ = _utf_length(src_);
	size_t destcapacity = destlen_;
	for (size_t idx = 0; ((idx < srclen_) && (destcapacity > 0));)
	{
		wchar_t	cp;
		unsigned char	cu = src_[idx++];
		if (cu < 0x80)
			cp = (wchar_t)(cu);
		else if (cu < 0xE0)
		{
			cp = ((cu & 0x1F) << 6);
			cp |= (src_[idx++] & 0x3F);
		}
		else if (cu < 0xF0)
		{
			cp = ((cu & 0x0F) << 12);
			cp |= ((src_[idx++] & 0x3F) << 6);
			cp |= (src_[idx++] & 0x3F);
		}
		else
		{
			cp = L'?';
		}
		*dest_++ = cp;
		--destcapacity;
	}
	return destlen_ - destcapacity;
}

这段代码在win下可以正常将utf-8的char*转换为utf-16的char*,但在Android, iOS下却不能得到和win下一样的转换结果,刚发现这个问题时,以为又是当年遇到的wchar坑,宽字符函数不支持之类的,但是仔细看了下并没有用到什么字符串函数,转换部分也是自己实现的,最后在各平台调试器的帮助下找到了问题:
Continue reading…

Cocos2d-X lua binding C++类的RTTI

在用Cococs2d-X的lua binding时,遇到了需要RTTI的时候,也就是运行时类型识别,这点对于lua类来说还是很容易做到的,可以参考引擎lua framework中cocos/cocos2d/functions.lua中的function iskindof(obj, classname),不过,这个函数的递归实现函数iskindof_有些小问题,这里是修正方法:

local iskindof_
iskindof_ = function(cls, name)
    local __index = rawget(cls, "__index")
    if type(__index) == "table" and rawget(__index, "__cname") == name then return true end
    
    if rawget(cls, "__cname") == name then return true end
    -- By K-Res: should use __index instead of cls!
--    local __supers = rawget(cls, "__supers")
    local __supers = rawget(__index, "__supers") 
    if not __supers then return false end
    for _, super in ipairs(__supers) do
        if iskindof_(super, name) then return true end
    end
    return false
end

然而,当遇到需要对binding到lua的native class进行RTTI就有些麻烦了,可以看到借助tolua过去的lua对象是usertable挂metatable实现的,而metatable中也没有可以用lua类(确切的说是模拟class行为的table)的RTTI方式,因为需要查找的一些__cname等meta成员并不存在,作为class标识的只有一个.isclass的bool值,看了下binding实现的原生代码,发现在不添加额外元表信息的前提下获取class名称是需要用到LUA_REGISTRYINDEX这个只能由原生代码获取到的lua全局信息注册表,于是放弃了通过lua代码实现绑定类类型识别的想法,转而使用原生函数实现了个简单的获取binding时设置的本类class名方法,暂时实现了本对象所属类识别的功能:
Continue reading…

最近多说评论框架有些不稳定

最近本博用的多说评论框架有些不稳定,先是被各种发广告的骚扰,然后又是本人回复评论后不显示(最近评论中能看见,博文下面的评论看不见),不知是否有来访的朋友们回复时也有类似的情况。去多说论坛看了下都是吐槽的,官方倒是也在修复这个问题,看看最近是否能修好吧。

UPDATE1: 刚发现还是有后台能看到但前台看不到的评论,然后换一下评论展示方式、主题貌似就正常了…

64bit Linux CentOS 7下编译32bit程序的方法

本文记录的方法理论上适用于所有RedHat系Linux发行版!
一般在64位Linux下(安装好gcc等相关编译工具后)编译出的执行程序都是针对64位环境的,如果想编译为针对32位环境的(当然,64位系统环境下也可以兼容运行),只需要在执行gcc时加上-m32编译即可(ld的话也有对应参数-melf_i386),虽然编译时只是加参数即可,但仍然有c、c++标准库等需要首先安装好32位相关版本。
如下,如果直接-m32编译的话,会收到如下错误提示:

[kres@localhost test6432]$ gcc -m32 test.c
In file included from /usr/include/features.h:399:0,
from /usr/include/unistd.h:25,
from /usr/include/usb.h:28,
from test.c:1:
/usr/include/gnu/stubs.h:7:27: 致命错误:gnu/stubs-32.h:没有那个文件或目录
# include ;
^
编译中断。

Continue reading…

PS2 DS2 H柄760020主板BU6370AK主控导电膜替换修复

朋友的两个H柄,其中一个故障严重,除了左右摇杆、L3、R3以外其余按键全部失灵(原因是N年前进了可乐…),另一个L1、L2、十字上左失灵,其余按键正常。打开看了下:

IMG_0756 IMG_0755
后盖看到是H柄、主板左上角有白色丝印的760020,查了下是H柄的第二版型号,按键胶垫下的导电膜上的型号是03-0241,看了下TB有卖相貌型号相近的,2块左右一张。观察了一下主板和导电膜的链接方式,发现如查到资料一样,导电膜插口与插槽是一体的,插槽排针直接焊接在电路板上,打开对比了下自己的A柄,导电膜是直接压在电路板上的。对比了下TB没有卖这种原版带插槽的导电膜的,不过好在有一家卖类似可插拔19pin插槽的。
对着电路板看了下走线,结合之前查到的资料说PS2的DS2手柄是带压感的,导电膜上的触点碳膜会根据按钮下导电胶压力大小改变阻值,再有主控芯片转为对应数字信号发送给主机,仔细看导电膜上触点两边线路的走向,可以看出除选择、开始和analog键外、其余碳膜触点均有一端是互通的,而这一端对应的是排针上左起第9针,于是用万用表一端接第9针,另一端接对应按键的针,可以看到再对应按键按下时,会有0-几k ohm左右电阻值变化(具体数值记不清了,当然,是用大部分按键可用的那支手柄测试的),而量到有故障的按键时,发现是断路状态,再对照导电膜上的走线,可以看出,L1、L2、十字上、左这4个键分别是最左边的几个针脚对应,而没问题的十字下正是十字左的下一端,所以判断应该是那4个键在导电膜上的线路出现老化断路了,另外一支手柄就更别提了,全都没有正常阻值,也不会根据压力而变化,唯有通过导电膜的左右摇杆还可以正常工作,感觉虽然进了可乐,但是主控芯片应该还能正常工作,于是TB进了替换膜和排插,开始更换。
Continue reading…

关于PS2无法识别部分PS1记忆卡问题的深究

之前给吃灰很久的PS2换上了816HD直读后,功能上算是进入了230 BIOS的9W完美状态,PS1游戏也算是可以完美支持了(目前没发现两次reset对功能有什么影响)。在重温一些PS1经典游戏时自然是少不了要存档的,于是翻出了封存15年的PS1记忆卡(当时是拿着记忆卡去游戏厅玩时用):
IMG_0744
插到PS2上发现开机的浏览器中无法识别,于是百度了一下,发现关于这个问题的论坛讨论还真不少,简言之就是说PS2对PS1的记忆卡兼容性不好,对于一些组装卡、杂牌卡无法识别等(很明显我这个就是组装卡,所谓的“牛屎”廉价芯片),但也有网友提到说组装卡没问题反而原装卡不行的。另外还有提到Sony当年出过的带液晶屏的Pocket Station是100%没问题,看了一下TB上还真有不少,当然也有直接卖号称可以在PS2上正常使用的PS1原装记忆卡的。就在差点买个原装PS1记忆卡的时候,我惊讶的发现我这个有年头了的组装记忆卡,虽然在PS2的记忆卡管理界面中不能识别,但是在引导进PS1游戏后是竟然是可以识别的,会提示记忆卡已满,读取存档的时候会提示无可用存档等,于是,猜测这个记忆卡应该没坏,可能是遇到了所谓的“兼容问题”。
再后来偶然玩起汉化的日版生化3时,发现这个记忆卡中居然有一个当年的日版生化3存档,又测试了一下发现读取正常,玩了一会存个档,发现覆盖存入也正常,也就是说这个卡只是不能在PS2的记忆卡管理界面中识别(后来也试过uLaunchElf等工具,也无法识别),在PS2运行PS1游戏时功能时完全正常的!
Continue reading…

关于Cocos2d-x Lua Binding中ActionTimeline的setLastFrameCallFunc不可用问题

在使用Cocos Studio制作游戏UI等元素时,一定会使用到“动画”功能:
QQ截图20150731104206
这种“动画”反应到代码中会被作为Cocos2d-x的ActionTimeline处理,而在应用过程中免不了要进行一些时间轴上的事件监测处理,其中最常用的莫过于动画结束时的侦听。
简单看下源码可以找到很明显的回调设置函数:

    /** Set ActionTimeline's frame event callback function */
    void setFrameEventCallFunc(std::function<void(Frame *)> listener);
    void clearFrameEventCallFunc();

    /** Last frame callback will call when arriving last frame */
    void setLastFrameCallFunc(std::function<void()> listener);
    void clearLastFrameCallFunc();

上面的setFrameEventCallFunc是用来配合编辑器中设置的帧事件用的,可以用来实现比如UI打开到指定位置时播放特定音效等效果,下面的setLastFrameCallFunc则是刚刚提到的更为常用的动画播放结束后的回调函数!
不过,很遗憾,在不使用原生方式开发而使用lua脚本作为主要编程语言时,发现setLastFrameCallFunc的Lua Binding代码并没有实现实际功能(最新3.7版本也是):
Continue reading…