??xml version="1.0" encoding="utf-8" standalone="yes"?> 通过阅读ConsoleWindow代码Q想C(jin)一个解x\Q自己实现OnOpenAssetQ通过获取ConsoleWindow中的ListView得到当前选中的rowQ然后在LogEntries中取得该行对应的LogEntryQ其中的condition字段保存?jin)StackTrace字符Ԍ最后过滤掉包装的日志类后拿到脚本文件名和代码行Q用OpenFileAtLineExternal直接打开。在实现q程中发玎ͼ完全没有必要拿到LogEntryQ因为ConsoleWindow中的m_ActiveText是StackTrace字符Ԍ直接处理好?jin)?/p> 在想到该Ҏ(gu)之前Q看q两个解x法:(x)1Q将日志cȝ译成DLLQ?Q输出日志时自己记录StackFrameQ通过一pd手段在OnOpenAsset查找LogEntry中对应的StackFrame。不q这两种Ҏ(gu)都不能满个人的完美M情节Q方?失去?jin)预~译宏的灉|Q一旦日志系l改动需要重~DLL和处理依赖,Ҏ(gu)2低效且过于复杂?/p> 最后摘Z码供参考,实现环境为:(x)Unity 4.7.5f1, UnityVS+Visual Studio 2015 Pro?/p> 从A*到Navmesh都是完备的寻路方案,能满Q意距ȝ路径搜烦(ch)。它们都需要根据场景预先生成相x据(A*是规整的2D格子数据QNavmesh则是mesh数据Q,在场景尺寸确定的情况下,Navmesh法的网格数?x)随障碍的复杂程度改变,而A*是固定的。就时空复杂度而言Q通常情况下Navmesh要优于A*Q但一些优化的变种A*法Q如QHierarchy A*Q在长距d路上要优于Navmesh。然而对于动态改变的场景障碍Q在使用以上两种法旉?x)有性能和设计上的限制。在实际目中,我们通常战斗约束在一定区域内Q而且q些区域有可能是诸如Udq_之类的,此时A*和Navmesh可能?x)面临无法用的境地。下面这个方案是在洗澡时H然惛_的,切点应该称之ؓ(f)遉K法Q因为它源自之前做智能避障小车时的经验?/p> 设,角色到目标点的方向向量ؓ(f)D0Q投线长度为LQ探间隙角为θ,N = 180 / θQ算法流E如下:(x) 法通过优先搜烦(ch)目标方向左右无障空_(d)减少(g)次敎ͼ通过讄θ和L可以控制(g)精度和范围。此外,讄合适的Collision Matrix和检频率可以约束RayCast的性能开销?/p> 团队在用UGUIӞ发现其Outline实现是将文字的顶点在上下左右方向上做偏移生成?jin)新的顶点,所以顶点和三角面数量都增加?倍。受Glow中Gaussian Filter可实现边界外扩效果的启发Q做?jin)个实验Q在W一个pass中用Filter对Font Texture的Alphaq行4或?方向采样Q第二个pass正常渲染字体Q然后将两者进行Alpha blend?/p> No Outline Tow-Pass Outline with Four-Direction Sampling Outline in UGUI 从结果上来看Q在一定范围的U理坐标偏移下可以接受,但限制也很明显,下图是偏U过大导致失?/p> 不管使用那种方式Q都需要将L点进行插|interpolationQ以便得到^滑\径。这里就牉|C|插值和朝向插倹{? 从插值函C可分Zc:(x)1Q线性;2Q多式Q?Q样条。顾名思义Q线性插值采用线性函敎ͼ多项式插值采用多式Q而样条插值则采用?jin)一l多式l成的分D函数。由于摄像机的关键\径点通常都会(x)大于2个,所以插值方法上必选取hҎ(gu)? 一、位|插?/strong> 1.1 hcd选择 在这里我们仅考虑三次h插|因ؓ(f)它们可达到C2q箋。三ơ样条中主要以Bezier、Catmull-Rom、均匀Bh查对象Q它们都h计算开销的优点。可以通过下面公式来定义它们:(x) 化ؓ(f)Q? 下面表格列出?jin)三U插值曲U对应的G和MQ? 如下图所C,?个点q行Bezier插值得到的曲线只会(x)有两个点被曲U穿q,而B-Spline插值得到的曲线不会(x)l过控制点,只有Catmull-Rom Spline可以得到I过除v点和l点之间的所有控制点。正因ؓ(f)Catmull-Romhq个Ҏ(gu),使得它被q泛地应用在关键帧^滑插gQ因此我们选择?jin)Catmull-Romh作ؓ(f)摄像Z|点的插值算法? 1.2 实现 参考:(x) [1] Mathematics for 3D Game Programming and Computer Graphics 3e by Eric Lengyel [2] http://en.wikipedia.org/wiki/Catmull-Rom_spline#Catmull.E2.80.93Rom_spline [3] http://www.codeproject.com/Articles/30838/Overhauser-Catmull-Rom-Splines-for-Camera-Animatio 二、朝向(旋{Q插?/strong> 2.1 Euler Angles VS Quaternion 三维I间中描q旋转的主要Ҏ(gu)有Euler Angles和Quaternion。Euler Angles有三个明昄问题Q?Q三轴上的旋转顺序敏感;2QGimbal Lock现象D旋{自由度丢失;3Q独立地对三个旋转分量进行插|忽略?jin)三轴之间的依赖关系Q导致插值结果不理想。与Euler Angles不同的是QQuaternion没有旋转分解到三个轴向上,而是用一个旋转u和绕该u的旋转角度来描述Q所以从Ҏ(gu)上消除了(jin)Euler Angles的三大问题。有关Quaternion的详l描q可参考[1]Q在此不再篏q? 2.2 LERP VS SLERP 四元数线性插|Linear Quaternion interpolationQ的计算公式为:(x) 四元数球面线性插|Spherical Linear Quaternion interpolationQ的计算公式为:(x) 其中Qؓ(f)两个四元数的夹角? Z(jin)方便展示Q我们考虑?D情况对角度Vq行两次插|两种法在插值效果上存在的差异,如下图(b为LERP、c为SLERPQ:(x) 从图中可以看出LERP其实是对两四元数在圆上的弦进行了(jin){分Q而SLERP则是对圆弧进行等分。由此得出的l论是,SLERP得到?jin)比LERP更^滑的插值结果? Z(jin)保证插值曲U的C2q箋性,需要用球面四边Ş插|Spherical Quadrangle interpolationQ方法。例如,对q1和q2插|首先要用q0、q1、q2、q3计算Z个控制点QInner Quadrangle PointQ,公式如下Q? 然后通过下式得到最l插值结果:(x) 2.3 实现 上面代码没有考虑两个四元C间夹角大?80的情c(din)例如,考虑q1->q2的插D度?gt;180Q我们可以让q1->q2反向旋{2π-θQ即旋{-(2π-θ)Q根据四元数的定义[v*sin(θ/2) , cos(θ/2)]Q那么对q2q行处理变ؓ(f)[-v*sin(θ/2) , -cos(θ/2)]。这个处理可以放在AddSplinePoint中来做:(x) 参考:(x) [1] Quaternions, Interpolation and Animation by EB Dam - 1998 内存泄漏(g)的基本步骤是:(x)1Q包装(重蝲Q内存分?释放APIQ?Q进行内存分配时C相关信息Q地址、大、调用栈Q?Q释放时清除之前记录的对应信息;4Q程序退出时Q确保在所有内存释放操作完成之后)(j)Q输出剩下的记录。其中,对进行分配操作是的调用栈回溯是个重点信息Q它能够帮助我们扑և内存泄漏代码? Windows中的Dbghelp库提供了(jin)丰富的调试API。StackWalk应该是进行栈回溯最直接的一U接口了(jin)Q但是它不够快。如果能先记录下调用栈上的CALL指o(h)地址Q然后在输出日志时解析出W号Q将?x)大大降低检机制对E序本n性能的媄(jing)响。Dbghelp库中提供?jin)Sym*FromAddrpdAPIQ可以通过指o(h)地址获取函数W号Q那么剩下的是如何记录指o(h)地址的问题了(jin)。从|上借了(jin)一张x86调用栈示意图Q如下:(x) 从图中可以看出,Callee的EBP始终指向Caller的EBPQEBP下面是指向Caller下一条指令(注意x86体系下栈的增长方向是地址Q,因此通过EBP可以回溯整个调用栈?jin)。通过下面代码可以实现此功能:(x) 宏参数frame是个void*指针数组Q数l的大小取决于想要回溯的栈深度。内存分配和回收的包装代码如下:(x) 我们看到Q内存管理系l内部终I还是要使用语言提供的内存分?释放APIQ只要配对实C(jin)分配与释攄理,pȝ内部的无泄漏是很Ҏ(gu)保证的。在q里着重讲解原理,׃重蝲new/delete operator?jin)。最后看一下调用栈函数W号的回溯代码:(x) 我们用下面代码做试用例Q? 泄漏(g)结果:(x) 参考:(x) [1] Using DbgHelp 我想?jin)两U方案,最初的Ҏ(gu)灉|来自光线反射Q如下图所C? 因ؓ(f)L格子是u寚w的,通过法向量n可以得到b点的反射向量e'-oQ将|e'-o|限定在一个固定|此时如果e'不在L里面Q就它作ؓ(f)新的l点。该Ҏ(gu)的实验结果不太o(h)人满意,当角色离L较近时断l感太明显,因ؓ(f)|e' - b|的长度较短。另外它不能处理e'在阻挡里的情况,被卡住不动的概率依然较大? W二U方案是Ҏ(gu)Ud向在一个u向找一个可达试探点Q然后用限制?jin)搜索空_(d)搜烦(ch)节点?0以内Q的A*法扑ֈ一条到试探点的路径Q如下图? 设diff_x = l点x - L(fng)xQdiff_y = l点y - L(fng)yQ当diff_x > diff_yQ认定ؓ(f)向x方向上移动,在这U情况下在终点y轴向上?0个格子内LC个最接近l点的无L点(U它为可达试探点Q。由于试探点与玩家当前点极有可能是直U不q通的Q而且它们不可能太q,所以用了(jin)一个将搜烦(ch)节点个数限制?0以内A*来得C条\径。该Ҏ(gu)大部分情况都能在边缘扑ֈ合理点,但如果玩家垂直面朝阻挡内Ud且不能在限制搜烦(ch)范围内找到可辄Q角色就?x)卡住不动,q种情况只能让玩家自己调整一下朝向了(jin)? 需要注意的是,如果是多个参敎ͼLua的压栈顺序是object pointer、参C左到叻I所以栈元素是函数{最双的参数?/p> 一、扩展Lua Lua核心(j)很小Q主要包含一个解释器Q其他功能可以通过动态库的Ş式作为插件来扩展Qio、string、math、table{内|库都是通过此方式来实现Q只是他们被集成C(jin)一个lua.dll中Ş?jin)。制作一个动态库形式的moduleQ需要在代码中通过luaL_Reg数组指定lua function到c function的映,接着实现c functionQ最后在luaopen_xxx(xxx为module name)注册q个luaL_Reg。这里给Z个非常简单的例子Q它使用VC++创徏一个Console DLLQ?/p> ~译成dll后放到l(f)ua解释器目录下。Lua test codeQ?/p>
require "mymathlib" local a = mymathlib.sin(0.5) 二、作本系l?/strong> Lua应用最多的领域当属游戏开发,W(xu)OW的UI和插件让它名声大噪。在q种应用中,Lua作ؓ(f)应用E序的一个子pȝQ用作配|或者业务处理。在Lua与应用集成v来时Q必ȝ到Lua C APIQ根据其规范Q你需要写一pd的static函数Q作为Lua与应用程序的_合代码。如果要在Lua使用C++对象Q可其作ؓ(f)userdataQؓ(f)它创Z个metatableQƈ粘合函数放入其中,关键是要让__index指向metatable自nQ这样当Lua讉Kuserdata的fieldӞ__index?x)引导它L索metatable自nQ从而获得注册的_合函数?/p>
有很多开源的_合代码生成器,他们都是在precompile时做?jin)一些工作,因而不是用macro是templateQ这两种Ҏ(gu)的代表是toLua++和luaBind。个人更們使用toLua++Q一斚wq种方式比较直白Q另一斚w本h׃使用template。在WGAME中也原来写得不是很好的bind代码替换成了(jin)toLua++Q目前UI和关卡逻辑重度使用?jin)LuaQ生的bind代码?x)有几万行,׃目采用事g驱动的方式,在profile时看到对游戏整体性能影响非常。luaBind大概?jin)解q,没有在实际项目中用过Q在此就不做评论?jin)?/p>
在用toLua++时我最好奇的是它对C++关键Ҏ(gu)是如何支持的。除?jin)上面说的成员函数外Q对于多态的支持Q它是通过在static函数后加~号Q调用时判断参数是否对应来遍历找到正static函数的;对于复杂成员变量Q它?x)自动生成get/setҎ(gu)Q而承关p,则是通过子类父cM为metatable来实现。秉着重新发明车轮的精,我试着写了(jin)一个简化的自动生成器[我在github?/a>]。我定义?jin)几个关键字作?f)cMҎ(gu)的导出标识:(x) {module_begin = "LUACBIND_MODULE_BEGIN" , module_end = "LUACBIND_MODULE_END" , method_begin = "LUACBIND_METHOD_BEGIN" , method_end = "LUACBIND_METHOD_END"} util.h定义?jin)生bind代码需要的宏,parser.luaҎ(gu)定的.h文gq行扫描产生bind代码Q在main函数中register后,可以在lua中用了(jin)?/p>
三、调试器 Lua的C API和Debug库提供了(jin)实现调试器的必要Ҏ(gu)Q对应了(jin)两种实现方式Q一U是Remdebug所采用的,直接用lua实现Q另外一U是使用C API。不哪U方式,使用HOOK都是必须的,但用Lua debug库会(x)比C API更方便,因ؓ(f)不用考虑栈^衡问题。在用C API实现调试器时Q可用lua_newthread创徏一个coroutineQ之后yield/resume/getstack/getlocal都作用它上面Qbreakpoint通常?x)采用在hook中yield的方式来实现Q但不能{hookq回之后去进行栈回溯Q因为traceexecҎ(gu)hook mask调用对应hook函数后,如果state是ؓ(f)LUA_YIELD状态,会(x)调用luaD_throwQ最l用longjmpD无法q行回溯?/p>
利用春节值班两天清闲时光Q基于lua 5.2实现?jin)一个命令行调试器[我在github?/a>]Q目前仅有几个简单的功能Q加?q行lua脚本、设|?清除断点、单步、查看简单类型变量|命o(h)格式可参考README?/p> 核心(j)数据l构我采用链表数l,相同颜色且L的(chng)泡串成一个链表。采用这U数据结构,是基于下面考虑Q?Q通过颜色划分~小搜烦(ch)区域Q?Q没有排序,没有中间插入节点的需求;3Q节省内存。当?dng)游戏界面中的泡?chng)q是把它对应C个二l数l中Q每个元素存储一个(chng)泡对象的指针Q该对象中至包含:(x)颜色、坐标,分倹{如下图所C:(x) 剩下需要考虑的是发射泡(chng)颜色如何产生Q如果从I关卡开始,前面可以用随机,后面p使用l计信息?jin)。在每个链表头可以统计该堆(chng)泡开闭性、数量等Q利用这些信息可以决定发(chng)泡的颜色? 准备: 1QUSB DOS启动盘; 2QHDDHackr 1.3?60 320 GBZgQ? 3Q一台支持SATA接口的电(sh)脑。(我有一台SATAIII接口的PC和一台支持SATAII的ThinkPad X200W记本)(j) 在PC上运行失败了(jin),出现不能写入的问题,在X200W记本上成功?jin)。在此过E中,只需要选择写入Zg,E序?x)帮你自动备份原Zg。需要妥善保原ZgQ以便后面需要用做数据硬盘的时候可以恢复?/p> 然后q入BIOSQ将SATA模式从AHCI改ؓ(f)Enhanced IDEQ在我的?sh)脑上也不能用Compatible IDEQ不然会(x)出现可以识别不能d的问题)(j)。至于XBOX何时启动的问题,我给出的l论是无所谓,如果XBOX后启动,则需要进讑֤理器扫瞄一下新讑֤。在整个操作q程中,虽然在设备管理器中看不到光驱Q但是进入JF的DVDKey 32늭是可以看到的Q注意选择I/O PortQ。如果是W一ơ提取光qKEYQDVD KEY一会(x)昄not foundQ这是正常的Q因为程序找不到与已知KEY匚w的。最后点击SlimKeyQ过E中不要unlock? 接下来就是去|上?504Q将0225上提取的KEY合入其中? 被骗?jin),拿到的还?225Q值得?jin)幸的是光驱?2q?月䆾的MXIC版,具体用什么方法破解的Q我也难的去拆开l究。问?jin)LTL(fng)是哪个版本,回答?.0。在|上又买?jin)两张LT3.0和一张不分版本的Q应该就是低于AP2.5的吧Q。结果是3.0可以安装Q运行提C"此光盘不支援Q,另外一张不?.0q是3.0的可以运行,于是开始怀疑光驱刷的是2.0。ؓ(f)?jin)验证自q怀疑,军_自己动手刷LT plus 3.0Q另一斚w也验证一下破解是否完(不用拆板焊线可以反复刷Q,l果决定是否退掉光驱? 在Win7下试?jin)Nơ,SATA1,6都试?jin),是写入不?jin)Qstatus 0x051Q,但是可以识别和读KEY。没办法Q改变策略:(x)1)先用JF拿前面提取的KEY和LT+3.0合成ZgQ?)用U盘启动,到纯DOS下用dosflash来写入固件。这个方案很奏效Q成功写入固Ӟ到win7下用JF查看光驱KEY的状态是verified。启?60Q买的LT3.0子都能玩了(jin)? |上的资料繁杂而难以L别真伪,所以凡事都要自己实c(din)补充一下:(x) 1Qdashboard版本与刷光驱Zg有没有关p?没有。光q甉|接口提供三种?sh)?3.3?.0?2Q、出舱控制、托盘状态外其余都是地线Q所以刷机时的数据通讯只会(x)通过SATAU传输,因此360无法q预hq程。我用u盘离U从13599更新C(jin)最新的15574Q能玩「黑色行?」、「极?7」、「忍?」? 2Q验证光盘是否是LT3.0Q用abgx加蝲光盘信息Q如果出?strong>Topology data is currently verifiedp明是LT3.0Q注意对于超ȝ,普通光驱无法识别,或者读取出错)(j)? 3Qdosflash使用注意事项Q将SATAU接在第一个口上。进入dos后先别启?60Q运行dosflash一ơ,保所有sata接口没有错误提示。然后执行dosflashQ正常情况下应该没有错误提示Q最后选w直接选合好的Zg写入? 试代码需要做一些调_(d)才能更好C现出GPU的^行计优势,q其中牵涉到支持CUDA的GPU架构知识Q在q里做一下梳理? 在Nvidia推出Fermi架构之前Q支持CUDA的Nvidia昄芯片都是由多个Streaming MultiprocessorQ简USMQ组成,每个SM包含?jin)八个Stream ProcessorQ简USPQ,每四个SPl成一个组Q也是说SM实际上可以看成包含两l?D的SIMD处理器。此外,每个SMq包含Register、share memory、texture cache以及(qing)constant cache。在执行 CUDA E序的时候,每个SM对应一?blockQ而每个SP是对应一?thread。虽然一个SM只有八个SPQ但是由于SPq行各种q算都有延迟Q更不用提内存存取的延迟?jin),因?CUDA 在执行程序的时候,实际是以 warp 为单位。目前的支持CUDA昑֍Q一?warp 里面?2?threadsQ分成两l?6 threads的half-warp。由于SP的运至有4个时钟周期的延迟Q因此对一?D的SP来说Q一ơ至执?6?threads(?half-warp)才能有效覆盖掉各U运的延迟[1]? ?1 在GeForce GTX 400pd上,Nvidia采用?jin)全新的Fermi架构[2]Q之后的昑֍的Compute Capability也从1.3跃升?.0。SP改名为CUDA CoreQ提升到?2?SM[3]。图2为Fermi核心(j)演变Q从GF104和由其发展v来的GF114、GF106、GF108的CUDA Core都上升到?8?SMQ支?.1的Compute CapabilityQ而GF100和GF110依旧?2个。最新基于Kepler架构的GeForce GTX 680支持3.0的Compute CapabilityQCUDA Core数量辑ֈ?92?SM? ?2 ׃试q_采用的是GTX 560 TiQ所以需要分析一下它的架构。GTX 560 Ti?个SMl成Q下图中Q左Ҏ(gu)从程序获取的讑֤属性,双为单个SM内部l构CZ图。可以看刎ͼGTX 560 Ti的每个SM配备?jin)两个Warp调度器,因此每个周期对两个包?2个线E的Warpq行分发。另外,对于一个二l图像,为kernel指定2D的grid和block可代码更加直观。ؓ(f)此,block采用Q?6,16Q,d分配256个(64*4Qthreads在一个SM上执行,如果需要?024*1024的Julia分Ş图,则需要grid为(64,64Q? ?3 试q_为:(x) 试代码说明Q?/strong> 1Q代码分为CPU实现和CUDA实现Q? 2Q均采用CPU计时Ҏ(gu)Q? 3Q只针对计算部分试Q不包括内存分配、传输以?qing)文件写入? 下面列出main函数代码Q左边ؓ(f)CPU实现Q右边ؓ(f)CUDA实现Q均~译为release版本? 试l论Q?/strong>CPU版本耗时244msQCUDA版本耗时2.1087ms。这可是100倍的效率提升啊。不qCPU版本没有l过多核优化Q所以这栯样对比实在不公^Q但q却凸显出CUDA Cƈ行思想融入语言规则的优ѝ? 在惊讶GPU用作通用计算的执行效率时Q别忘了(jin)它还是有诸多应用上的问题Q? 1)初始化耗时Q需要在昑֭分配I间Q然后将数据从内存copy到显存; 5)CPU法到适合GPU架构法的移植; 最后,GPUg设计本n已l决定了(jin)它的强项是密集数据处理(如:(x)U学计算、医疗图像处理)(j)Q在逻辑处理斚wq是CPU的天下,所以它们是互补的,只会(x)有整合而非替代的趋ѝ? [1] http://www2.kimicat.com/gpu%E7%9A%84%E7%A1%AC%E9%AB%94%E6%9E%B6%E6%A7%8B [3] http://www.geeks3d.com/20100606/gpu-computing-nvidia-cuda-compute-capability-comparative-table 有时候,你会(x)H然Ҏ(gu)事很感兴,但理性思维?x)让你冷静(rn)一下,看是不是一时冲动。Nq前Q对摄媄(jing)的需求仅满于旅游记录,所以一般DCp够。一个多月前Q想要提升照片品质的需求突然串?jin)出来,让这U想法发酵了(jin)几天后,发现可能是该入一台DSLR的时候了(jin)。在Nikon D7000/Pentax K-5/Canon 60D中选择?jin)K5Q就成像效果D7000与K5是同一次Q喜ƢK5的手感和味道Q小巧是个很重要的因素,q样同样喜欢摄媄(jing)的Rain也可以用得很好。宾得的对焦pȝ和镜头群一向都被CN饭喷Q不q个为K5的对焦在日常拍摄中已l够用,镜头但全。对于刚使用DSLR不久的我来说QDA 18-55mm F/3.5-5.6 AL虽然在成像锐度方面弱?jin)点Q但日常的风景h像还是够了(jin)。DA 55-300mm F/4-5.8 EDq端大光圈拍人像的虚化效果和q端打鸟的远摄效果都q比较满意,׃55-110光圈可以恒定?Q?10-200最大光圈恒定在4.5Q所以两者组合v来在性h(hun)比上要比DA 18-135mm F/3.5-5.6 ED高。凤?0mm F/1.7手动_(d)在成像效果方面真?j)对得v315RMBQ有兴趣的同学可以看q里?/p> 摄媄(jing)技术的提高是个漫长的过E,对初U阶D需要掌握的知识Q我ȝ如下Q?/p> 1Q器材的熟?zhn)到精通:(x)阅读使用手册Q熟知各个按钮及(qing)选项的意义?/p> 2Q保证对焦点Q想拍摄物)(j)清晰?/p> 3Q相机的基本原理Q快门、光圈、感光度对媄(jing)像的影响?/p> 4Q构图:(x)左右对称、三{分、曲Uѝ对角线、T/L型、明暗对比?/p> 5Q光U感知:(x)如何才能做到合适的曝光?/p> 6Q利用学到的新知识,不断l习(fn)Q让相机成ؓ(f)你的另一只眼睛?/p> 在参考书斚wQ虽然反感“宝典”之,但《数码单反摄影完全宝典》还是本不错的入门书了(jin)Q涵盖了(jin)DSLR的基知识Q加上配图(包括拍摄参数Q,可以提升对好照片的认知?/p> 写此文的同时Q快门数也近3k?jin),遂将一些习(fn)作(没有后期Q整理了(jin)攑օflickr上,IDp一点吧?a target="_blank">Pentax的小眼睛』?/p> 彼得的《理解曝光》是我学?fn)的W二本书Q对掌握光技巧从而正曝光有很大帮助Q距L惛_所得的目标有近?jin)一步。此书还涉及(qing)?jin)快门速度、光圈对拍摄效果产生的媄(jing)响,应该是入门者必ȝ一本经怹作?/p> 国庆(jin)M(jin)厦门Q经q一个月的准备,拍出的片较之前有很大q步Q感觉生zd多了(jin)些乐?/p> 从大学到现在配过两台PCQ第一台Celeron的机器从大二用到研究生毕业,之后开始用W记本。第二台PC?9q入手的Q那阵子玩超频,但心(j)气w,胡ؕ试一下就尝辄止?jin),q一些基本原理都没有弄清楚。最q刚搞好新房安顿下来Q有?jin)自q工作_(d)在重新组装PC和设|BIOS的时候又惌频了(jin)Q但q次我期望做到知其所以然Q故在网上查阅了(jin)一些资料恶补了(jin)一下硬件知识,权当作学?fn)笔记。由于网l上关于gQ特别是内存部分Q知识很杂,仅以自己认ؓ(f)比较靠谱的内容ؓ(f)依据Q如有不准确之处Q欢q指正。由于用的是Intel CPUQ本文限于Intel架构Q且不适用Ipd架构?
ȝ概览
二、术?/font>
L芯片l:(x)北桥芯片和南桥芯片?
北桥QNorthbridgeQ:(x)PCL芯片l其中之一Q设计用来处理高速信P与CPU、内存、AGP/PCIE、南桥芯片进行通信?
南桥QSouthbridgeQ:(x)PCL芯片l其中之一Q设计用来处理低俗信P通过北桥和CPU通信Q与大多数I/O控制讑֤接口Q如PCI控制器、ATA控制器、USB控制器、网l控制器、音效控制器。各个芯片厂商对南桥芯片的命名有所不同QIntel其UCؓ(f)ICHQnVidiaUCؓ(f)MCPQATIUCؓ(f)IXP/SB?
前端ȝQF(tun)SB, Front Side BusQ:(x)指CPU与北桥芯片之间的数据传输通道?
锁相环(PLL, Phase-Locked LoopQ:(x)一个闭环的反馈控制pȝQ它可以使PLL的输出可以与一个参考信号保持固定的怽关系?
旉频率Q?/strong>切Ҏ(gu)晶振频率Q与锁相环电(sh)路配合用ؓ(f)PC提供定时信号Q通过倍频/分频产生不同频率的基准信P用以同步pȝ的每一步操作。对于CPU主频Q它是由晶振提供的频率通过CPU内部的PLL?sh)\倍频而来?
CPU外频Q?/strong>pȝȝ的工作频率,体现?jin)CPU与芯片组之间的ȝ速度?
前端ȝ频率Q?/strong>CPU与北桥芯片之间的ȝ工作频率。之所以将CPU外频与前端ȝ频率区分开来,是因为Intel在Pentium 4中加入了(jin)Quad Pumped Bus架构Q得系lȝ在一个时钟周期内传输4ơ数据,也就相当于工作频率ؓ(f)CPU外频?倍?
CPU倍频Q?/strong>为倍频pL的简Uͼ是指CPU主频与CPU外频之间的相Ҏ(gu)例关pR在PC发展初期Q由于CPU速度不高Q大部分元g旉均保持同步,直到80486时代Q在CPU制程持箋q步下,CPU的速度也加速增长,当时׃其他外部元g受电(sh)气结构所限,无法跟进成长Q因此Intel首次在CPU中加入了(jin)倍频设计。它的作用是使系lȝ工作在相对较低的频率上,而CPU速度可以通过倍频来提升?
双倍数据速率QDDR, Double Data RateQ:(x)使SDRAM在一个时钟周期内q行两次数据传输的技术,具体地说它在信号的上升沿和下降沿传输数据一ơ,数据传输率是之前仅利用上升沿q行数据传输的SDRAM的两倍?
内存频率Q?/strong>分ؓ(f)核心(j)频率(Internal rate)和I/Oȝ频率(Bus clock)。每条内存都是由内存芯片l成Q内存芯片的频率是核心(j)频率。I/Oȝ频率是指北桥与内存之间的ȝ频率。通常内存条标U的实际上是最大数据传输频率:(x)I/Oȝ频率X2。其实,从DDR到DDR3Q其内存颗粒的频率没有怎么提升Q提升的是ȝ频率。JEDEC制定的DDR三代参数对照如下表所C:(x)
双通道Q?/strong>是在北桥芯片里设计两个内存控制器,q两个内存控制器可相互独立工作,每个控制器控制一个内存通道。在q两个内存通道上CPU可分别寻址、读取数据,从而内存的带宽增加一倍,数据存取速度也相应增加一倍(理论上)(j)。流行的双通道内存构架是由两个64bit DDR内存控制器构{而成的,其带宽可?28bit。因为双通道体系的两个内存控制器是独立的、具备互补性的内存控制器,因此二者能实现彼此间零{待旉Q同时运作。两个内存控制器的这U互?#8220;天?#8221;可让有效{待旉~减50%Q从而内存的带宽翻倍。双通道内存技术是解决CPUȝ带宽与内存带宽的矛盾的低仗高性能的方案?
三、原?/font>
CPU主频=外频×倍频 从公式可以看出,要提升CPU主频可以从提高外频和倍频两方面着手。然而在实际操作q程中,两者都?x)受CPU本n?qing)外部硬Ӟ主要是主板?j)体质的限Ӟ如:(x)锁倍频、主板FSB Frequency上限?
1Q提高外?
因ؓ(f)CPU外频的设|直接媄(jing)响系lȝ工作频率Q所以通过提升外频和搭配合适的内存Q可以在L支持的前端ȝ频率上限内有效提升系l的整体性能。之所以要搭配合适的内存Q是因ؓ(f)前端ȝ频率提高Q最大的受媄(jing)响者就是内存,所以内存能够支持的最高工作频率也需要考虑。虽然GPU数据也要通过前端ȝ由CPUl过北桥到达昑֍Q但是在仅针对CPU频的情况下Q一般会(x)CPU与显卡之间通信的频率锁定在100MHz。D个例子:(x)有一块前端ȝ上限频率?600MHz的主板,假如搭配一块上限ؓ(f)1600MT/s的DDRIII内存Q?:2分频比的前提下,需要将CPU的外频提升到接近400MHzQ整个系l才?x)比较^衡?
2Q提高倍频
通过倍频的定义,可以看出Q在外频一定的情况下,提高倍频Q只能单U地提高CPU工作频率。虽?dng)CPU的计能力除?jin)跟工作频率有关外,q与g架构和指令集有关Q成倍提高工作频率肯定不{于成倍提高了(jin)计算能力Q但可以肯定的是频率提高肯定?x)在一定程度上提高计算能力?
四、实?/font>
五电(sh)容版E5200h很强的超频空_(d)在倍频定在X8的情况下Q?.2V便可以轻松上370MHz。主板在不超频情况下FSB已l支?600MHz?jin),Corsair在用XMP时支?600Q在整体考量Q散热、CPU寿命Q后军_CPU外频定在350MHz、倍频设ؓ(f)x10Q这样FSB可工作在1400MHzQ内存按?1:2分频比I/Oȝ工作?00MHz下(数据传输频率?400MT/sQ。BIOS讄如下Q?
内存CL、tRCD{D其自动读取SPD配置?
参考:(x)
[1] 前端ȝ http://zh.wikipedia.org/wiki/%E5%89%8D%E7%AB%AF%E6%80%BB%E7%BA%BF
[2] 晶振?qing)其选用指南 http://www.naiteli.com.cn/Info/Detail_50139_7547.html
[3] 倍频 http://baike.baidu.com/view/25647.htm
[4] DDR SDRAM http://en.wikipedia.org/wiki/DDR_SDRAM
[5] DDR2 SDRAM http://en.wikipedia.org/wiki/DDR2_SDRAM
[6] DDR3 SDRAM http://en.wikipedia.org/wiki/DDR3_SDRAM
[7] 五电(sh)容E5200 http://tech.163.com/digi/09/0316/08/54H0RJNT001618J7.html 1. 建立源代码烦(ch)?/font> WinDbg提供?jin)一套用于管理pdb对应的源代码的工P位于其安装目录的srcsrv下,对VSS、SVN、CVS、Perforce提供?jin)支持,分别对应vssindex.cmd、svnindex.cmd、cvsindex.cmd、p4index.cmdq四个perl脚本。其实,ssindex.cmd才是具体实现Q它Ҏ(gu)传入的版本控制系l标识,调用对应的perl module? svnindex.cmd通过/source?symbols参数来指定源代码目录和PDB目录Q?debug可输出处理的详细信息Q?user?pass提供svn账户和密码。PDB文g中有一节专门用于存放源代码文g列表?qing)处理命令,可通过pdbstr -r -p:PdbFileName -s:srcsrv查看? svnindex.cmd /debug /source="E:\CodeBase_SVN\Client\trunk\tools\CutSceneEditor" /symbols="E:\CodeBase_SVN\Client\trunk\bin\Release\CutSceneEditor" /user="user" /pass="pwd" 在执行上面命令前Q确保Perl和Subversion已经被安装且讄?jin)PATH环境变量。该命o(h)提取source code的服务器路径和当前RevisionQ然后写入PDB。下面是通过pdbstr获取的信息:(x) 上面输出是经q格式化的,原始信息可以通过srctool -n查看Q? 可以看出Q原始代码\径后面跟?jin)一条svn cat指o(h)Q由于没有指定sourcepathQ所?targ%~省为当前\径("C:\Program Files\Debugging Tools for Windows (x64)\srcsrv"Q?nbsp; 2. 创徏W号服务?/font> 所谓符h务器Q最单的形式是文g׃n服务器。我们?a target="_blank">symstore命o(h)Q将1中生的pdbdC个文件共享服务器上,如:(x) symstore.exe add /f "E:\CodeBase_SVN\Client\trunk\bin\Release\CutSceneEditor\*.pdb" /s "\\server.com\pub\Symbols" /t "CutSceneEditor" /v "Build 4171" /c "fix memory leak" 该命令会(x)Ҏ(gu)PDB的signature和age产生一个GUIDQƈPDB攄于以改GUID为名字的目录下:(x) 当debugӞUNC路径d到_NT_SYMBOL_PATH中(如:(x)_NT_SYMBOL_PATH=CACHE*F:\Symbols;SRV*http://msdl.microsoft.com/download/symbols;SRV*\\server.com\pub\SymbolsQ,调试器会(x)自动到指定的W号服务器上L索对应的pdb文g? symstore大大化了(jin)W号的版本管理问题,关于它的详细介绍可参?a target="_blank">symstore介绍? 值得注意的是Qsymstore没有锁机Ӟq不支持多h同时操作。实际情况中Q也只有自动构徏时才?x)做此操作? 3. 使用WinDbg分析Dump文g 我们在代码中加入发生异常写MiniDump的功能,在程序崩溃时产生dump文g。在使用WinDbg分析dump文gӞ需要设|Symbol File Path和Source File PathQ也可以直接讄环境变量_NT_SYMBOL_PATH和_NT_SOURCE_PATH。在讄_NT_SOURCE_PATH时?SRV*CachePath"表C启用代码提取功能,执行svn cat写入到CachePath指定的目录,否则用原始\径。此后,通过点击Call Stack中的函数调用便会(x)触发从svnd对应代码的操作(通常?x)有一个安全警告窗口弹出)(j)? 对于使用WinDbgq行调试在此׃多讲?jin),推荐一本不错的书《Advanced Windows Debugging》? 参考资?/strong> [1] Source Indexing and Symbol Servers: A Guide to Easier Debugging [2] Source Server Helps You Kill Bugs Dead In Visual Studio 2005 首先要介l一下USB Host Shield[1]。它是Oleg?009q春开始设计的Arduino ShieldQ采用MAX3421E控制芯片Q目前最新版本ؓ(f)2.0Q旨在让Arduino能够与USB讑֤Q如Q键盘、鼠标、游戏手柄、相机、GPS、手机)(j)q行通讯Q当然也能完成ADK的功能。在软g斚wQOleg也在github上开放了(jin)驱动代码和例子程序[2]Q此后又有hZ前者的代码l出?jin)更为方便简z的USB蓝牙适配器与PS3手柄通讯的示例代码[3,4]?/p> PS3手柄只能与具有相同蓝牙地址的主机配对,所以需要先USB蓝牙适配器的地址写入PS3手柄。可以用[3]中的PS3Pair代码Q将BDADDRg改ؓ(f)蓝牙适配器的地址。[4]中提供的PS3BT例子Q将蓝牙地址修改和通讯功能整合C(jin)一P省了(jin)一ơsketch的uploadQ注意也需要将代码中的my_bdaddr修改为适配器的地址。配Ҏ(gu)需要将PS3手柄q接U与USB Host Shield相连Q待完成后将蓝牙适配器接上,打开手柄Q可从Serial Monitor看到日志Q注意L特率的一_(d)(j)?/p> USB Host Shield占用?jin)SPI、P9、P10Q注意不要冲H了(jin)?/p> Reference: [1] http://www.circuitsathome.com/arduino_usb_host_shield_projects [2] https://github.com/felis/USB_Host_Shield_2.0 [3] https://github.com/Lauszus/PS3-Controller-BT-Library-for-Arduino [4] https://github.com/TKJElectronics/USB_Host_Shield_2.0 手上的ShenZhen Tong和HongKong Octopus均是SONY?a >Felica CardQ与ISO/IEC 18092QNFCQ用类似的调制Ҏ(gu)Q采用曼切斯特编码,?3.56MHZ?12kbit/sq行通讯。用动态密钥,加密法为DES?-DES、AESQ攻击难度较大,但是从动态密钥的交换q程入手Q还是有Z(x)的。目前,有些手机刉商QNOKIA,SAMSUNG,BLACKBERRYQ将NFC Reader集成到手ZQ未来RFID的应用将比现在更q,安全问题也会(x)来受到关注?/p>
References: http://cq.cx/proxmark3.pl http://www.libnfc.org/documentation/introduction http://www.cs.ru.nl/~flaviog/publications/Pickpocketing.Mifare.pdf http://www.sos.cs.ru.nl/applications/rfid/2008-esorics.pdf
]]>
]]>
]]>#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
#include <math.h>
int mysin (lua_State* L);
static const struct luaL_Reg mymathlib [] =
{
{ "sin" , mysin } ,
{ NULL , NULL }
};
static int mysin( lua_State* L )
{
double d = luaL_checknumber( L , 1);
lua_pushnumber(L , sin( d));
return 1;
}
__declspec(dllexport) int luaopen_mymathlib(lua_State * L)
{
luaL_register(L , "mymathlib" , mymathlib);
return 1;
}
print(a)
]]>
2)数据量受GPU昑֭限制Q?br> 3)Ҏ(gu)w就需要GPU参与q算的程序,如:(x)3D游戏Q通用计算?x)争夺GPU资源Q如果做qQ?br> 4)计算数据之间的不相关性限制了(jin)GPU通用计算的应用范_(d)
]]>
]]>
]]>
]]>
]]>
http://www.proxmark.org/
]]>
rm /root/.kde/cache-root/plasma_theme_Volatile.kcache
rm /root/.kde/cache-bt/icon-cache.kcache
rm /root/.kde/cache-bt/plasma_theme_Volatile.kcache
一、A* Path-Finding
A*法׃多讲?jin),可参考:(x)
二、预处理
每个盔R区块QC1和C2Q都有一条由公共边,该边两侧格l成L1和L2Q则q通点集E满下列条gQ?
对上面得到的位于同一区块的点集合使用local A*做连通性测试,下图用直U连接来表示两点互通:(x)
三、寻?/font> 使用区块q通信息,q行区块UA*Q得到区块之间的q接点,如果在预处理时保存了(jin)区块内互通点的\径,׃必再q行区块内的local A*?jin)? 实验l果表明Q在未采用区块内预存路径的情况下Q中长距d路用层ơA*后的q_效率是普通A*?倍以上,距离长效率Ҏ(gu)明显? A* 93ms HPA* 15ms 从上图中可以看出QHPA*得到的\径ƈ不是最优的Q它是在最优和效率上的折中Q适合作ؓ(f)长距d路的一U优化方案? 四、优化点 一个改q的Ҏ(gu)是对q长的边界再做划分:(x)
]]>
void D3DXQuaternionSquadSetup( __out D3DXQUATERNION *pAOut, __out D3DXQUATERNION *pBOut, __out D3DXQUATERNION *pCOut, __in const D3DXQUATERNION *pQ0, __in const D3DXQUATERNION *pQ1, __in const D3DXQUATERNION *pQ2, __in const D3DXQUATERNION *pQ3 );
D3DXQUATERNION* D3DXQuaternionSquad( __inout D3DXQUATERNION *pOut, __in const D3DXQUATERNION *pQ1, __in const D3DXQUATERNION *pA, __in const D3DXQUATERNION *pB, __in const D3DXQUATERNION *pC, __in FLOAT t );
其中QD3DXQuaternionSquadSetup用于q回内插的控制点。它们具体的实现公式和用法,有兴的同学可以参考MSDN。在此需要说明的是,
D3DXQuaternionSquad使用?jin)Slerp作ؓ(f)内部实现Q会(x)D在两个夹角ؓ(f)180左右的Quaternion之间插g(x)出现断裂的问题。下面代码通过
实现一个考虑?jin)上q情늚Slerp版本Q在q1和q2夹角?或?80Ӟ使用U性内插而非球面Q来解决该问题?/pre>
- Quaternion QuatSlerpNoInvert(const Quaternion& q1 , const Quaternion& q2 , float t)
- {
- float cosAngle = DotProduct(q1, q2);
- float c1, c2;
- // Linear interpolation for close orientations
- if ((1.0f - fabs(cosAngle)) < 1e-5f)
- {
- c1 = 1.0f - t;
- c2 = t;
- }
- else
- {
- // Spherical interpolation
- float angle = acos(fabs(cosAngle));
- float sinAngle = sin(angle);
- c1 = sin(angle * (1.0f - t)) / sinAngle;
- c2 = sin(angle * t) / sinAngle;
- }
- Quaternion q = q1 * c1 + q2 * c2;
- q.Normalize();
- return q;
- }
- Quaternion QuatSquad(const Quaternion& p1 , const Quaternion& p2 , const Quaternion& p3 , const Quaternion& p4 , float t)
- {
- static Quaternion a , b , c;
- D3DXQuaternionSquadSetup((D3DXQUATERNION*)&a , (D3DXQUATERNION*)&b , (D3DXQUATERNION*)&c ,
- (D3DXQUATERNION*)&p1 , (D3DXQUATERNION*)&p2 , (D3DXQUATERNION*)&p3 , (D3DXQUATERNION*)&p4);
- return QuatSlerpNoInvert(QuatSlerpNoInvert(p2 , c , t) , QuatSlerpNoInvert(a , b , t) , 2 * t * (1-t));
- }
参考:(x)
[1] http://msdn.microsoft.com/en-us/library/bb205419(v=vs.85).aspx
[2] http://msdn.microsoft.com/en-us/library/bb205420(v=vs.85).aspx
]]>
在_hash_fun.h中有针对各种cd的哈希D特化版本,下面仅摘录针对C字符串的代码Q?/p>
__stl_hash_string实现?jin)一个简单的哈希法Q因为算法中使用?jin)字W的ASCII码,Z(jin)辑ֈ大小写不敏感的目的,可将每个字符转换成小?大写来计。对于hash functorQ我们也需要一个string的特化版?/p>
在_function_base.h中定义了(jin)equal_to functorQ?/p>
通过定制一个string版本的equal_toQ用stricmpq行字符串比较。下面列出实现及(qing)试代码Q?/p>
1、search时程序死?/p>
2、debug旉住pdb不释放,下次build时出现文件写错误
对于W一个问题,在devenv.exe属性的Compatibility的Settings中勾选“Disable visual themes”,或者停用Aero主题Q用Basic themes?/p>
对于W二个问题,可用sysinternals工具handle来释攑֯pdb的引用,在此不列出handle的用,有兴可以自qI。下面给Z个批处理Q关闭指定名U的pdb文g占用Q?/p>
@echo off cd /d "%~dp0" for /f "tokens=2-3 skip=5 delims=:" %%a in ('handle -p devenv.exe "%1.pdb"') do ( for /f "tokens=1,4" %%c in ("%%a%%b") do ( handle.exe -c %%d -y -p %%c ) ) @echo on
其保存C个文Ӟ攑֜project的pre-build event。当?dng)q需要一个参数来喂批处理中的%1?/p>
前段旉遇到q这L(fng)问题Q已知一2D地图格子的长宽(w、hQ及(qing)每个格子的边长(aQ格子ؓ(f)正方形)(j)Q给定物体的2D坐标Qpos[x , y]Q及(qing)半径QrQ,求解物体?D地图格子中所占的格子Q仅考虑n*n的情c(din)大概的求解q程如下Q?
1Q根据半径,定n*n中的n。假定计公式ؓ(f)Qn = Round(2*r / a)
2Q根?D坐标得到物体的“中?j)格子”。根据n的奇Ӟ计算公式不同Q如下图所C?
n为偶数[1] n为奇数[2]
[1]Qgrid(x , y) = Round(pos / a)
[2]Qgrid(x , y) = Floor(pos / a)
其中Q格子坐标x >= 0 , y >= 0?
3Q以“中?j)格子”ؓ(f)基础Q求出物体占据的其他格子。这L(fng)描述Q让人容易想到递归Q就像用深度优先Ҏ(gu)遍历?wi)那P伪代码算法如下:(x)
if n is even { get the index of 'center grid' (row , col) ExtendHeldGrid(row , col , n) ExtendHeldGrid(row - 1 , col , n) ExtendHeldGrid(row - 1 , col - 1 , n) ExtendHeldGrid(row , col - 1 , n) } else { get the index of 'center grid' (row , col) ExtendHeldGrid(row , col , n) } function ExtendHeldGrid(row , col , level) { if(level <= 0) return if((row >= 0 and row < MaxGridWidth) and (col >= 0 and col < MaxGridHeight)) { mark the grid(row , col) ExtendHeldGrid(row , col , level - 2) if(level - 2 > 0) { ExtendHeldGrid(row + 1 , col , level - 2) ExtendHeldGrid(row - 1 , col , level - 2) ExtendHeldGrid(row , col + 1 , level - 2) ExtendHeldGrid(row , col - 1 , level - 2) ExtendHeldGrid(row + 1 , col + 1 , level - 2) ExtendHeldGrid(row - 1 , col + 1 , level - 2) ExtendHeldGrid(row + 1 , col - 1 , level - 2) ExtendHeldGrid(row - 1 , col - 1 , level - 2) } } }
虽然Q该法得到?jin)正的求解l果Q但是由于每个格子都?x)标记周围?个格子,所以存在大量的重复Q再者如果上面的q程每都进行的话,函数调用开销也是相当可观?/p>
循环自然是不可避免的Q消除重复便成了(jin)优化的目标。分析格子图和n??的情况,试图扑և用@环代曉K归的方法,我发C(jin)下面一个有的规律Q?/p>
从“中?j)格子”出发,时针(或逆时针)(j)以上图方式可以走遍所求解的每个格子而不重复。在实现上,每个转角也是有规律的Q可以通过一?*2的{角矩阉|控制Q?/p>
[1 , 0][0 , -1]
[0 , 1][-1 , 0]
时针方式的转角?/p>
矩阵中的每个元素代表从当前格子走C个格子在row和col上的变化。加之,在{角之间的路长Q以格子个数计)(j)有每转两ơ递增单位1的规律,法׃隑־C(jin)Q下面同样以伪代码示Q?/p>
conerMat = { {0 , -1} , {-1 , 0} , {0 , 1} , {1 , 0} } dir = 0 /// 转角控制Q四个{角顺旉0~3 span = 1 /// 转角间的跨度 count = 1 /// 每两ơ增加一个跨? rin = 1 /// 下一个{角的循环索引 if n is even get the index of 'center grid' (row , col) else get the index of 'center grid' (row , col) for(i = 0; i < n * n; ++i) { if((row >= 0 and row < MaxGridWidth) and (col >= 0 and col < MaxGridHeight)) mark the grid(row , col) if(i == rin) { dir = (dir + 1) % 4 if(count == 2) { ++span count = 1 } else ++count rin = i + span } row = row + conerMat[dir][0] col = col + conerMat[dir][1] }
用MFCE序验证?jin)一下算法的正确性,标号展示?jin)@环的路线Q注意GDI的坐标系中Y的正方向朝下Q:(x)
首先惛_的是用TSVN的hook script(client side)Q但仔细研究后发C入script的参C有操作\径,且通过script也不可能讉K/修改Notify对话框中的信息和字体颜色。唯一的办法就是修Ҏ(gu)代码重新~译Q从TSVN官方代码库获取到?jin)trunk source code后,按照根\径下的build.txt文档q行构徏Qdoc\build-zh_CN.txt有些q时?jin),不要按照该文进行构建?j)Q最C码需要用到VC++10.0~译Q过E中除了(jin)hunspell下affixmgr.cxx、hashmgr.cxx和hunspell.cxx三个文g׃svn的编码{换导致文件内容异常外Q没什么大问题?/p>
TSVN的代码写得很beautifulQ这个要赞一下。在清晰的结构下很快对source codeq行?jin)分析,发现TSVN的操作处理代码位于src\TortoiseProc下面Q而对各种操作的UI反馈主要攑֜SVNProgressDlg中。找到要修改的地方,d?jin)几行代码,用NAnt构徏后,替换现装版中的对应文Ӟ出现subversion too old问题Q点开TortoiseProc.exe发现最C码中的subversion版本已经用到?.7.2Q而TSVN对外发布的最新版却还?.6.15Q可能是开发者认MinorVersionqtoo old?jin)吧。算?jin),不折腾?jin)Q直接拉发布?.6.12的tag来修改吧?/p>
1.6.12版的source code用VC++9.0~译Q按照build文档调整一下与前面构徏有差异的地方Q值得注意的是TSVN用到?jin)RibbonQ所以必d安装一下vs2008 sp1补丁。在构徏TortoiseProcӞ有个头文件中重复声明?jin)MFC中已l定义了(jin)的类型,D构徏p|Q需要将重复定义之处注释掉。TortoiseProc一出,我的目的pC(jin)Q由于构建的版本与我安装的一_(d)所以只需替换TortoiseProc.exeQ经试一切OK?/p>
个h觉得Q对TSVN的扩展还是麻?ch)?jin)一点,整个构徏q程p?jin)大量时_(d)增强hook script?/p>
Commtivia Z71 - 0.3.1 3.7 MiB - 55 hits - December 21, 2010
HTC Aria - 0.3.1 3.8 MiB - 35 hits - December 21, 2010
HTC Desire (CDMA) - 0.3.1 3.4 MiB - 74 hits - December 21, 2010
HTC Desire (GSM) - 0.3.1 3.4 MiB - 381 hits - December 21, 2010
HTC Desire HD - 0.3.1 4.2 MiB - 166 hits - December 21, 2010
HTC Desire Z (G2) - 0.3.1 4.3 MiB - 55 hits - December 21, 2010
HTC Dream/Sapphire (32B) - 0.3.1 3.3 MiB - 156 hits - December 21, 2010
HTC Droid Eris - 0.3.1 3.4 MiB - 39 hits - December 21, 2010
HTC Droid Incredible - 0.3.2 3.6 MiB - 75 hits - December 21, 2010
HTC Evo 4G - 0.3.1 3.4 MiB - 109 hits - December 21, 2010
HTC Hero (CDMA) - 0.3.1 3.4 MiB - 75 hits - December 21, 2010
HTC Hero (GSM) - 0.3.1 3.4 MiB - 94 hits - December 21, 2010
HTC Magic/Sapphire (32A) - 0.3.1 3.4 MiB - 73 hits - December 21, 2010
HTC Tattoo - 0.3.1 3.2 MiB - 77 hits - December 21, 2010
HTC Wildfire - 0.3.1 3.6 MiB - 140 hits - December 21, 2010
Motorola Droid - 0.3.1 3.4 MiB - 132 hits - December 21, 2010
Nexus One - 0.3.1 3.4 MiB - 122 hits - December 21, 2010
T-Mobile myTouch 3G Slide - 0.3.1 3.8 MiB - 34 hits - December 21, 2010
T-Mobile myTouch 4G - 0.3.1 4.3 MiB - 30 hits - December 21, 2010
W者用的HTC Magic(32A)也在其中Q于是用fastboot的USB方式Q关机后按Power+Returnq入后接上USB至PCQ当然PC必须安装DriverQ刷?jin)Recovery。进入Recovery模式Q关机后按Power+HomeQ,断开USBq接Q选择"PSFreedom settings"q入发现用于DG?Put PS3 in Service Mode"、用于JB?Jailbreak FW 3.41"、以?qing)从SD卡加载Payload的功能项一应俱全?/p>
剩下的就和用Dog一L(fng)操作方式来DG&JB?jin),值得注意的是操作旉需要接在右边USB口上QJB操作提示是接在左边)(j)Q?/p>
1Q关闭PS3q切断电(sh)源,选择"Put PS3 in Service Mode"q入Q?/p>
2Q将手机q接至PS3双USB口;
3Q打开PS3甉|Q按开机键后迅速按Z键;
4Q手柄连接主机重新配对后QPS3q入Factory/Service ModeQ关闭PS3Q?/p>
5Q找一个U盘(只要是PS3识别的FAT/FAT32格式Q未必需格式化)(j)插上PCQ解?.41修改版固Ӟ有三个文件夹Q“Lv2diag.self FILE 1”,“Lv2diag.self FILE 2”和“Modified 3.41 PUP”?Lv2diag.self FILE 1中的Lv2diag.self以及(qing)Modified 3.41 PUP中的PS3UPDAT.PUP拯到U盘根目录Q?/p>
6Q拔下U盘插入PS3双的USB口,打开PS3Q屏q没有Q何显C,PS3L的硬盘灯和U盘的指示灯会(x)闪烁Q等待大U?分钟直到PS3甉|l灯闪烁q自动关机;
7Q拔下U盘,PS3正常开机,仍在服务模式Q确认系l信息已l变?.41。(如需l箋降到更低系l版本,勿删除U盘上的Lv2diag.selfQ将其它pȝ版本PS3UPDATE.PUP攑օU盘,重新执行一遍步?Q。若不需l箋降Q关闭PS3甉|Q?/p>
8Q在PC上,删除U盘中的Lv2diag.self和PS3UPDAT.PUP两个文gQ把Lv2diag.self FILE 2文g夹中的Lv2diag.self拯到U盘根目录。将U盘插上PS3q开机,仍然黑屏Q等?0U后?x)自动关机。再开机,?x)出现重新连接手柄、新建用L(fng)初始开机画面,完成讄后进入系l信息查看,已是普通的3.41pȝ?jin),降步骤全部完成?/p>
1Q关闭PS3q切断电(sh)源,选择"Jailbreak FW 3.41"q入Q?/p>
2Q将手机q接至PS3双USB口;
3Q打开PS3甉|Q按开机键后迅速按Z键;
4Q确认JB成功与否Q查看Game下面是否多了(jin)两个新菜单项Q?/p>
5Q之后就可以?a target="_blank">PS3-HacksM载BackupManager/OpenManager?jin)?/p>
其实JB是让PS3q入Debug模式Q一旦进入后便可U除JB讑֤。PS3刚JB那会(x)儿,BackupManager是必备工P后面出的Manager都是在其基础上增强,OpenManager比BackupManager多了(jin)从外接硬盘copy/play game的功能。此外Gaia manager也是个很受欢q的ManagerQ除?jin)在UI上比OpenManager好看之外Q还加入?jin)Direct Boot/FTP Server{功能,但Direct Bootq不是那么好使,比如《忍者龙剑传 Sigma2》用Gaiap屏死机,用OM׃?x),M感觉q是OM更稳定?/p>
Reference
[3] Simple Tutorial on How to Downgrade and Jailbreak your PS3 with PsfServiceMod
[4] http://ps3.cngba.com/ps3_xw/20101215119290.shtml
一、系l调?/p>
通过使用WinExec、ShellExecute或systemQ如Q?/p>
_snprintf(cmdbuf , 1024 , "p4 -c %s add \"%s\"" , argv[1] , ANSIToUTF8(path.c_str())); system(cmdbuf);
此方法的虽然单,但存在效率问题,因ؓ(f)有创E的巨大开销。此外不同版本的Perforce也会(x)出现不同的执行结果,针对特定的中文会(x)出现操作p|的诡异问题?/p>
二、Perforce SDK
Perforce提供有SDK用以扩展或集成到其他应用中,虽然没有详细的文,但可以通过学习(fn)SDK中的sample文g来学?fn),此方法最E_?/p>
下面代码展示?jin)通过SDK中ClientAPI来递归d指定文g夹下的所有文Ӟ(x)
# include "clientapi.h" # include "i18napi.h" # include "CharSetConvertUtil.h" # include <string> # include <vector> # include <list> # include <io.h> using namespace std; // structure to hold a directory and all its filenames. struct FILELIST { string path; vector<string> theList; }; void TransverseDirectory(string path, list<FILELIST>& theList) { struct _finddatai64_t data; string fname = path + "\\*.*"; long h = _findfirsti64(fname.c_str(),&data); if(h >= 0) { FILELIST thisList; theList.push_back(thisList); list<FILELIST>::iterator it = theList.end(); it--; (*it).path = path; do { if( (data.attrib & _A_SUBDIR) ) { // make sure we skip "." and "..". Have to use strcmp here because // some file names can start with a dot, so just testing for the // first dot is not suffient. if( strcmp(data.name,".") != 0 &&strcmp(data.name,"..") != 0) { // We found a sub-directory, so get the files in it too fname = path + "\\" + data.name; // recurrsion here! TransverseDirectory(fname,theList); } } else { // this is just a normal filename. So just add it to our vector (*it).theList.push_back(data.name); } }while( _findnexti64(h,&data) == 0); _findclose(h); } } int main( int argc, char **argv ) { list<FILELIST> MyList; string path; ClientUser ui; ClientApi client; StrBuf msg; Error e; if(argc < 4) { fprintf( stderr , "P4 Transverse Add: Arguments Error!\n"); return -1; } client.SetPort(argv[1]); client.SetClient(argv[2]); client.SetTrans(CharSetApi::UTF_8 , CharSetApi::UTF_8 , CharSetApi::UTF_8, CharSetApi::UTF_8); TransverseDirectory(argv[3],MyList); // Connect to server client.Init( &e ); if( e.Test() ) { e.Fmt( &msg ); fprintf( stderr, "%s\n", msg.Text() ); return -1; } list<FILELIST>::iterator it; for(it = MyList.begin(); it != MyList.end(); it++) { vector<string>::iterator its; for(its = (*it).theList.begin(); its != (*it).theList.end(); its++) { path = (*it).path + "\\" + (*its); char* pText = ANSIToUTF8(path.c_str()); client.SetArgv( 1 , &pText); client.Run( "add" , &ui ); } } // Close connection client.Final( &e ); if( e.Test() ) { e.Fmt( &msg ); fprintf( stderr, "%s\n", msg.Text() ); return -1; } return 0; }
此方法省M(jin)创徏p4q程的开销QQ务执行效率会(x)提高不少Q而且也不?x)出现执行结果不E_的问题?nbsp;
附一QSDK下蝲地址
ftp://ftp.perforce.com/perforce/
附二Q附上ANSI转UTF-8代码
wchar_t* ANSIToUnicode( const char* str ) { int textlen ; wchar_t * result; textlen = MultiByteToWideChar( CP_ACP, 0, str,-1, NULL,0 ); result = (wchar_t *)malloc((textlen+1)*sizeof(wchar_t)); memset(result,0,(textlen+1)*sizeof(wchar_t)); MultiByteToWideChar(CP_ACP, 0,str,-1,(LPWSTR)result,textlen ); return result; } char* UnicodeToANSI( const wchar_t *str ) { char * result; int textlen; // wide char to multi char textlen = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL ); result =(char *)malloc((textlen+1)*sizeof(char)); memset( result, 0, sizeof(char) * ( textlen + 1 ) ); WideCharToMultiByte( CP_ACP, 0, str, -1, result, textlen, NULL, NULL ); return result; } wchar_t* UTF8ToUnicode( const char* str ) { int textlen ; wchar_t * result; textlen = MultiByteToWideChar( CP_UTF8, 0, str,-1, NULL,0 ); result = (wchar_t *)malloc((textlen+1)*sizeof(wchar_t)); memset(result,0,(textlen+1)*sizeof(wchar_t)); MultiByteToWideChar(CP_UTF8, 0,str,-1,(LPWSTR)result,textlen ); return result; } char* UnicodeToUTF8( const wchar_t *str ) { char * result; int textlen; // wide char to multi char textlen = WideCharToMultiByte( CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL ); result =(char *)malloc((textlen+1)*sizeof(char)); memset(result, 0, sizeof(char) * ( textlen + 1 ) ); WideCharToMultiByte( CP_UTF8, 0, str, -1, result, textlen, NULL, NULL ); return result; } char* ANSIToUTF8(const char* str) { wchar_t* pUnicodeBuff = ANSIToUnicode(str); char* pUtf8Buff = UnicodeToUTF8(pUnicodeBuff); free(pUnicodeBuff); return pUtf8Buff; }
?j)理学?f)该媄(jing)片了(jin)理论基础Q盗梦的目的是Z(jin)H探目标埋藏在心(j)里的U密Q因为梦是伪装得最的潜意识表现。而作入目标梦境的工具Q导演却是一W带q,不得不说是一个遗憾,因而该q也就成了(jin)一部纯U?sh)?jing)?/p>
观媄(jing)毕,个h感觉Dream Design应该也和Game Design怼吧:(x)故事、h物、时间、场景的设计。Programmer也深d温习(fn)?jin)一下递归吧?/p>
B.T.W. 多年以来Q能够撼动我思想的媄(jing)片仅有两部:(x)"The Matrix"?Inception"?/p>
1QFree 3G速度快,看新L便;
2Q分辨率高,字体清晰Q?/p>
2QNative PDF SupportQ翻速度已经很快?jin),对于内嵌中文字体也有很好地支持。看PDF文档Ӟ9.7寸屏?寸屏更易于阅诅RZoom功能q乎鸡肋Q因为很不喜Ƣ拉着滚动条阅读,看扫描书的时候顶多用一下横屏。此外,׃Kindle?x)把颜色转换为灰度,所以对于非U色的文字,?x)显得很淡?/p>
3Q由于AmazonMobipocket收归旗下的缘故,所以对mobi/prc文g格式的支持和azw格式一样好Q提供指译、字体羃放、注?W记{功能;
4Q通过Gift Card的方式购买电(sh)子书也挺方便Q免M(jin)买纸质书的运费和q输延迟。不q技术书的电(sh)子版本很,且h(hun)格昂贵;
5Q待机时间长Q这是E-INK阅读器的一大优势;
6Q加上原装皮套,重量和一本A4 600左右的书差不多?/p>
对于?sh)子书{换工P个h推荐QMobipocket和CalibreQ仅Mac OSQ。后者是开源的Q功能和输出文g质量胜于前者?/p>
1Q灵zR高可配|性,如:(x)多重l合条g触发、多d队列{略Q?
2Q兼容目前几乎所有的行SCM工具Q得多U异构系l能够由CruiseControl.NETl一监控和管理;
3Q完善的使用文Q上手和维护变得容易;
而该目引以自豪的代码check in触发构徏的功能通过CC.NET也很Ҏ(gu)实现。之前用过HudsonQ该pȝ采用M式架构,使用者通过|页让Master控制Slave动作Q由于Master由别的部门管理,出问题后需要联pȝ关h解决Q会(x)有一定的处理延迟Q而且安装在构建机上的Slave服务l常崩溃。而CC.NET直接安装在构建机上,配置IIS后可通过|页直接讉KQ操作维护都较前者容易。由于之前的构徏脚本是用VisualBuild实现的,所以不可能再花旉用CC.NET再写一遍。而通过实验得知Q其实CC.NET能够以ExecutableTask的Ş式很好地与VisualBuild集成Q目前每时定时构徏、NightBuild和构建成功后触发的自动测试都已经攑ֈ?jin)CC.NET上了(jin)?
ccnet.config Example:
<cruisecontrol xmlns:cb="urn:ccnet.config.builder"> <queue name="Q1" duplicates="ApplyForceBuildsReAdd" /> <queue name="Q2" duplicates="ApplyForceBuildsReAdd" /> <project name="AgileBuild" queue="Q1" queuePriority="1"> <category>AutoBuild</category> <triggers> <filterTrigger startTime="18:00" endTime="10:00"> <trigger type="intervalTrigger" name="Continuous" seconds="1800" buildCondition="ForceBuild" /> <weekDays> <weekDay>Monday</weekDay> <weekDay>Tuesday</weekDay> <weekDay>Wednesday</weekDay> <weekDay>Thursday</weekDay> <weekDay>Friday</weekDay> </weekDays> </filterTrigger> </triggers> <tasks> <exec> <executable>VisBuildCmd.exe</executable> <buildArgs>E:\GAMEDev\AgileBuilder.bld</buildArgs> <baseDirectory>D:\VisBuildPro7</baseDirectory> <buildTimeoutSeconds>3000</buildTimeoutSeconds> </exec> </tasks> </project> <project name="NightBuild" queue="Q2" queuePriority="1"> <category>AutoBuild</category> <triggers> <scheduleTrigger time="23:00" buildCondition="ForceBuild" name="Scheduled"> <weekDays> <weekDay>Monday</weekDay> <weekDay>Tuesday</weekDay> <weekDay>Wednesday</weekDay> <weekDay>Thursday</weekDay> <weekDay>Friday</weekDay> </weekDays> </scheduleTrigger> </triggers> <tasks> <exec> <executable>VisBuildCmd.exe</executable> <buildArgs>"BUILD_OPTION=clientworldeffect" "PACK_TYPE=RAR" E:\GAMEDev\NightBuilder.bld</buildArgs> <baseDirectory>D:\VisBuildPro7</baseDirectory> <buildTimeoutSeconds>0</buildTimeoutSeconds> </exec> </tasks> </project> <project name="NightAutoTest" queue="Q2" queuePriority="2"> <category>AutoTest</category> <triggers> <projectTrigger serverUri="tcp://heath-builder:21234/CruiseManager.rem" project="NightBuild"> <triggerStatus>Success</triggerStatus> <innerTrigger type="intervalTrigger" seconds="60" buildCondition="ForceBuild" /> </projectTrigger> </triggers> <tasks> <exec> <executable>VisBuildCmd.exe</executable> <buildArgs>E:\GAMEDev\AutoTest.bld</buildArgs> <baseDirectory>D:\VisBuildPro7</baseDirectory> <buildTimeoutSeconds>0</buildTimeoutSeconds> </exec> </tasks> </project> </cruisecontrol>
References
[1] http://cruisecontrol.sourceforge.net/
[2] http://www.kinook.com/VisBuildPro/
Table实际上是数组和哈希表的合体。当保存以连l整Cؓ(f)索引的内Ҏ(gu)Q用数l结构;而对于离散烦(ch)引及(qing)键值对Q则使用哈希表存储。这样做对于I间节省和查找效率都是有好处的,举例Q?/p>
tt = {"a" , "b" , "c"} print(#tt) --> 3 tt[100] = "d" print(#tt) --> 3 (100-"d"键值对攑օ哈希? tt[4] = "e" print(#tt) --> 4
二、Closure
Lua的变量引用规则造成?jin)闭包的出现Q在Lua中一个复杂数据结构(table、functionQ被赋予一个变量时Q变量仅仅拿取其引用。试考虑下面代码片段Q?/p>
local f1 = function() ... end local f2 = function() ... end local f3 = f1
判断f1与f2是否相等Q得到的l果为假Q而f3与f1则ؓ(f)真。这是因为f1与f2引用?jin)两个不同的函数chunkQ也可称为“定义”)(j)Q而f1直接其引用Q可以看成C/C++中的地址Q赋lf3Q故而相{?br>理解?jin)上面问题,再看看下面的一个函敎ͼ(x)
function createCounter() local x = 0 return function() x = x + 1 print(x) end end
那么Q下面c1与c2相等吗?
c1 = createCounter() c2 = createCounter()
׃createCounter中的return部分创徏?jin)一个新函数Q因此c1和c2引用的函数ƈ不相同。因为return的匿名函C使用C(jin)外部函数(即createCounter)的局部变量xQ所以Lua必须要在某个地方保存q个变量Q又因ؓ(f)每次q回的都是一个新函数Q所以Lua不能׃ncreateCounter中的xQ进而Lua必须为每个新函数分配一个保存x的地方,q个问题D?jin)闭包概늚产生?br> 通过上面分析Q可以明白是语言机制D?jin)闭包,而绝非Lua作者故意制造出q么一个看似有点神U的东西?br> 下面l出闭包的定义:(x)一个保留了(jin)创徏时上下文的函数。而upvalue的定义是Q被闭包讉K的保留变量。实际上所有在Lua中创建的函数都是闭包Q在许多情况下仅有一个原型的闭包存在Q因为函数块只执行了(jin)一ơ(也可以说定义?jin)一ơ)(j)?
下面代码用闭包实C(jin)一个对象工厂:(x)
local function CounterFactory() local x = 0 return { Increase = function() x = x + 1 end , Decrease = function() x = x - 1 end , GetValue = function() return x end } end local c1 = CounterFactory() local c2 = CounterFactory() c1.Increase() c1.Increase() print(c1.GetValue())
三、Tail Call
首先需要明What is ‘Tail Call?——其形式为“return f(?”,return语句中的函数调用仅限于单一调用Q涉?qing)函数返回D的复合表达式不是尾调用Q如Qreturn i * f(i - 1)。由定义可以看出调用实际上是对位于q回语句中的函数调用的优化。通常调用一个函数都需要将其上下文入栈Q然后再q入被调函数。在Lua中执行符合尾调用形式的函数时Q因函数已经没有代码需要执行了(jin)Q故作者作?jin)不保存上下文的优化。这样带来的好处是:(x)对于_ֿ(j)构徏的递归调用Q不需要有栈的消耗,因而绝对不?x)出现overflowQ看看下面递归调用产生的死循环Q?/p>
local function f(n) local i = n + 1 print(i) return f(i) -- tail call end f(0)
四、Metatable
Metatable常用来扩展table的行为,通过setmetatable(table , metatable)metatable挂接到table上,很多开发者用该特性来实现面向对象的设计。Metatable中提供了(jin)MetamethodsQ这些方法都以双下划U__开_(d)如:(x)
__add , __call , __concat , __div , __eq , __index...
以上Metamethods中,__index被调用的条g是:(x)key不在对应的table中。利用该Ҏ(gu)可以实现类-对象、承等面向对象概念Q下面是个简单例子:(x)
local Actor = {} Actor.name = "unnamed" Actor.hp = 100 Actor.dead = false Actor.level = 1 Actor.type = "unknown" function Actor:Say(text) print(self.name..":"..text) end function Actor:IsDead() return self.dead end local AttackableActor = setmetatable({ } , { __index = Actor }) AttackableActor.damage = 20 function AttackableActor:ReceiveHit(attacker) self:Say("I'm being attacked by "..attacker.name) self.hp = self.hp - attacker.damage if self.hp <= 0 then self:Say("I'm died :(") self.dead = true else self:Say("My HP is "..self.hp) end end function AttackableActor:Attack(target) if target.dead == true then self:Say("Oh, "..target.name.." has been dead!") else self:Say("I'm is attacking "..target.name) target:ReceiveHit(self) end end function CreateMonster(name , damage) local m = setmetatable({ } , { __index = AttackableActor}) m.name = name m.damage = damage m.type = "monster" return m end function CreatePlayer(name , damage) local p = setmetatable({ } , { __index = AttackableActor}) p.name = name p.damage = damage p.type = "player" return p end math.randomseed(os.time()) local boss = CreateMonster("Kerrigan" , math.floor(100 * math.random())) local player = CreatePlayer("Raynor" , math.floor(100 * math.random())) while player:IsDead() == false and boss:IsDead() == false do player:Attack(boss) boss:Attack(player) end
五、Performance Tips
请参?a target="_blank">Lua Performance Tips
六、ȝ
Lua是一门语法简z,用法灉|的动态语a。在全面掌握之后Q需(zhn)心(j)使用乃可构造出z高效的代码?/p>
Jason Gregory在他的引擎架构设计一书中也用“To SLERP or Not to SLERP (That’s Still the Question)”一节介绍?jin)开发者对Slerp的争论,q介l他在Naughty Dog的同事针对PS3的优化方法,使Slerp可达?0周期/兌Q相比Lerp?6.25周期/兌已经很不错了(jin)?/p>
之前实没对Slerp的效率问题作q多的考虑Q引擎的Slerp直接使用的是D3DXQuaternionSlerpQMS应该对其做了(jin)优化Q效率怎么栯一下才知道?jin)?/p>