<?xml version="1.0" encoding="UTF-8" ?><rss version="2.0">
<channel>
 <title>Skywind Inside</title> 
  <link>http://www.joynb.net/blog/index.php</link> 
  <description>Inside Here</description> 
<language>zh-cn</language> 
  <copyright>Powered by Bo-Blog V1.7.0108.2</copyright>
  <image>
 <title>Skywind Inside</title> 
 <url>http://</url>
 <link>http://www.joynb.net/blog</link>
 <description>Inside Here</description>
 </image><item>
<link>http://www.joynb.net/blog/index.php?job=art&amp;articleid=a_20080910_234015</link>
<title>我的鼠标动作游戏 - Final Weapon</title> 
<author>skywind &lt;skywind3000@163.com&gt;</author>
<category>Skywind Inside</category>
<pubDate>Wed, 10 Sep 2008 23:40:15 +0800</pubDate> 
 <guid>http://www.joynb.net/blog/index.php?job=art&amp;articleid=a_20080910_234015</guid> 
<description>
<![CDATA[ 
	<p>学习AS3的入门程序，前段时间学了两个星期的AS3，觉得挺有意思的，又画了两个星期写了这个WEB游戏：</p><p><a href="http://www.joynb.net/resource/weapon/"><a href="http://www.joynb.net/resource/weapon/" target="_blank">http://www.joynb.net/resource/weapon/</a></a></p>
	<br>   (<a href=http://www.joynb.net/blog/index.php?job=art&amp;articleid=a_20080910_234015 target=_blank> 网页浏览 </a>)
  ]]> 
</description>
</item><item>
<link>http://www.joynb.net/blog/index.php?job=art&amp;articleid=a_20080910_233812</link>
<title>自动地图生成算法</title> 
<author>skywind &lt;skywind3000@163.com&gt;</author>
<category>Skywind Inside</category>
<pubDate>Wed, 10 Sep 2008 23:38:12 +0800</pubDate> 
 <guid>http://www.joynb.net/blog/index.php?job=art&amp;articleid=a_20080910_233812</guid> 
<description>
<![CDATA[ 
	<p>让MMO玩家每次进入副本都有全新的体验，百玩不厌！让部分地图制作从手工制作中解放出来，开发成本大大降低！！</p><p><img src="http://www.joynb.net/blog/up/1221061051.jpg" /></p><p>运行地址：<a href="http://218.107.55.250:89/mazemap/cavemake.php"><font color="#4590ea"><a href="http://218.107.55.250:89/mazemap/cavemake.php" target="_blank">http://218.107.55.250:89/mazemap/cavemake.php</a></font></a></p>
	<br>   (<a href=http://www.joynb.net/blog/index.php?job=art&amp;articleid=a_20080910_233812 target=_blank> 网页浏览 </a>)
  ]]> 
</description>
</item><item>
<link>http://www.joynb.net/blog/index.php?job=art&amp;articleid=a_20071123_155530</link>
<title>HASH 表优化试验</title> 
<author>skywind &lt;skywind3000@163.com&gt;</author>
<category>Skywind Inside</category>
<pubDate>Fri, 23 Nov 2007 15:55:30 +0800</pubDate> 
 <guid>http://www.joynb.net/blog/index.php?job=art&amp;articleid=a_20071123_155530</guid> 
<description>
<![CDATA[ 
	最近用纯C作了一个dict，根据试验，比 stl的 map快 2.3-2.5倍，比 hash_map快 1.3倍，主要用到的优化策略如下：<br /><br />1. skiplist：<br />传统hash-bucket中，使用链表靠 next, 指针记录同一个 bucket中的各个节点，查找时候 需要一个一个的搜索，而改进以后的 bucket节点，使用 next, next4, next8三级指针，分别指向后一个节点，后四个节点，后八个节点，如此保证链表有序的情况下，如果要搜索，就直接考虑 next8的值和当前值大小，如果小于当前值，直接跳过八个节点，如果大于那再一次判断 next4与next。如此有序链表的遍历速度提高了 8倍。<br /><br />2. 双hash：<br />使用两次hash，开辟一个长度为 64的 LRU数组，记录最近访问过的节点，使用 hash2来定位 LRU数组的位置，当搜索发生时，首先根据 hash2在 LRU数组中查找是否最近访问过该节点，如果访问过就直接返回，如果没有访问过则继续用 hash1在 bucket中查找，如果查找到的话，就按照 hash2的值覆盖一下 LRU中该位置的数据。<br /><br />再加上一些内存管理方面的优化，以及一些编码方式的改进，对 key/value分别取 string或 int，四种情况下，平均比 stl的 map快 2.3-2.5倍，比 hash_map快 1.3倍。<br /><br /><br /><br /><br /><br/>
	<br>   (<a href=http://www.joynb.net/blog/index.php?job=art&amp;articleid=a_20071123_155530 target=_blank> 网页浏览 </a>)
  ]]> 
</description>
</item><item>
<link>http://www.joynb.net/blog/index.php?job=art&amp;articleid=a_20071101_203307</link>
<title>断点 C语言</title> 
<author>skywind &lt;skywind3000@163.com&gt;</author>
<category>Skywind Inside</category>
<pubDate>Thu, 01 Nov 2007 20:33:07 +0800</pubDate> 
 <guid>http://www.joynb.net/blog/index.php?job=art&amp;articleid=a_20071101_203307</guid> 
<description>
<![CDATA[ 
	<p>看着那密密麻麻的反汇编，连眼睛红了都没有发现，<br />听到你说错误很难重现，人数还一点一点再往下减，</p><p>我转过我的脸，不和你争辩，<br />未释放指针肯定，非常的危险，</p><p>发誓从今天，不再用C语言，<br />我真想改用脚本重构好几遍，</p><p>我走在你后面，冲进二号会议室里面，<br />呼唤着版本不能随便顺延，</p><p>打开的源文件，设满很多断点，<br />只想在睡前让程序能够，撑到明天。<br /></p>
	<br>   (<a href=http://www.joynb.net/blog/index.php?job=art&amp;articleid=a_20071101_203307 target=_blank> 网页浏览 </a>)
  ]]> 
</description>
</item><item>
<link>http://www.joynb.net/blog/index.php?job=art&amp;articleid=a_20070920_050014</link>
<title>ASCII Art Algorithm</title> 
<author>skywind &lt;skywind3000@163.com&gt;</author>
<category>Skywind Inside</category>
<pubDate>Thu, 20 Sep 2007 05:00:14 +0800</pubDate> 
 <guid>http://www.joynb.net/blog/index.php?job=art&amp;articleid=a_20070920_050014</guid> 
<description>
<![CDATA[ 
	<p>因为希望将图片转换成字符以后可以方便的帖到论坛或者BBS上，所以画时间写了这个算法。现有很多算法都是将一个点匹配成一个字符，这样转换工作只是简单的将点亮度查表后换成ASCII字符而已，但是其实这样做的效果并不十分好，首先80x25的字符屏幕就只能表示80x25个点，无法充分发挥单个字符的字形特点，而且图片很多精度和细节都丢失了。比如下面这个连接：</p><p><a href="http://www.sebastian-r.de/asciiart/exe.php?image=http%3A%2F%2Fwww.sebastian-r.de%2Fasciiart%2Fpng%2Fcatherine.png&resolution=3&mode=1&color=%23000000&font-size=11&line-height=9&letter-spacing=0&fixed_char=W&new_window=on"><a href="http://www.sebastian-r.de/asciiart/exe.php?image=http%3A%2F%2Fwww.sebastian-r.de%2Fasciiart%2Fpng%2Fcatherine.png&amp;resolution=3&amp;mode=1&amp;color=%23000000&amp;font-size=11&amp;line-height=9&amp;letter-spacing=0&amp;fixed_char=W&amp;new_window=on" target="_blank">http://www.sebastian-r.de......</a></a></p><p>所以我的算法主要是匹配周围一部分点到ASCII字符，这样斜线能够顺利匹配成“/”，其他形状的东西也能够顺利按照字形特点进行匹配，因此同样80x25个点，但是后者所能够表达的像素点更多，细节度更加丰富：</p><p></p><p><table style="WIDTH: 100%" cellspacing="1" cellpadding="1" align="top" border="0"><tbody><tr><td valign="top"><a href="http://www.joynb.net/blog/up/1190235321.gif" target="_blank"><img style="WIDTH: 364px; HEIGHT: 450px" height="450" src="http://www.joynb.net/blog/up/1190235321.gif" width="364" align="top" /></a></td><td valign="top"><img src="http://www.joynb.net/blog/up/1190235453.png" align="top" /></td></tr></tbody></table></p><p>上面的效果是作了误差扩散的，其实转换成ASCII字符时不做也可以，只是说希望转换前的局部/整体亮度等于转换后亮度，能量守恒一些而已。其实如果用同一种颜色的64个常见字符表达精度和细节度很高，对比度不高的图片还是比较困难的。</p><p>可以进一步优化的方法也有几种，其一是对照片作拉普拉斯变换，将噪声过滤掉再取出轮廓，这样转换出来的就是仅仅包含轮廓的对比度很高的图片了。或者将图片频谱中能量不高的，比较弱的频率去掉，留下能量高的频率，这样图片看起来更干净一些，只是后面这两种方法就无法保证实时渲染了。 </p><p />
	<br>   (<a href=http://www.joynb.net/blog/index.php?job=art&amp;articleid=a_20070920_050014 target=_blank> 网页浏览 </a>)
  ]]> 
</description>
</item><item>
<link>http://www.joynb.net/blog/index.php?job=art&amp;articleid=a_20070502_221314</link>
<title>牌上的花色－MUD中的玩家 （Bartle玩家分类理论翻译）</title> 
<author>skywind &lt;skywind3000@163.com&gt;</author>
<category>Skywind Inside</category>
<pubDate>Wed, 02 May 2007 22:13:14 +0800</pubDate> 
 <guid>http://www.joynb.net/blog/index.php?job=art&amp;articleid=a_20070502_221314</guid> 
<description>
<![CDATA[ 
	<p>游戏设计需要基础性理论，Richard A. Bartle，第一款MUD（被称为MUD1）的开发者，该文章起于1990年，经作者多次整理而成。在游戏设计“难有统一理论”的情况下，该文论点受到了决大多数开发者的一致接受和好评。可见基础性理论不但有利于我们的分析与设计，更重要的是大家能在同一层面上用同样的术语进行更有效的沟通：</p><p><a href="http://www.joynb.net/resource/hcdsc.htm"><a href="http://www.joynb.net/resource/hcdsc.htm" target="_blank">http://www.joynb.net/resource/hcdsc.htm</a></a> </p><p>最近在阅读 XBOX360 Live方面的文档，作为其中提及的一个重要概念“Bartle's player type”的论文，似乎影响了整个第四代Live的设计，恰巧最近我也在整理一些Live相关资料，就顺带将这个基础理论进行了翻译。</p><p />
	<br>   (<a href=http://www.joynb.net/blog/index.php?job=art&amp;articleid=a_20070502_221314 target=_blank> 网页浏览 </a>)
  ]]> 
</description>
</item><item>
<link>http://www.joynb.net/blog/index.php?job=art&amp;articleid=a_20070302_233450</link>
<title>现代主义题材游戏需要拯救</title> 
<author>skywind &lt;skywind3000@163.com&gt;</author>
<category>Skywind Inside</category>
<pubDate>Fri, 02 Mar 2007 23:34:50 +0800</pubDate> 
 <guid>http://www.joynb.net/blog/index.php?job=art&amp;articleid=a_20070302_233450</guid> 
<description>
<![CDATA[ 
	<p><strong>1. 参考游戏 vs 参考生活：</strong><br /> <br />以前人做游戏，参考的是生活；现在人做游戏，参考的是游戏。前者作出来的游戏属于创新，后者作出来的游戏最多属于“综合+改良”，这还是比较好的了，最差的情况还有抄袭的嫌疑，感觉作者设计出来的内容宏大而没有主题，似乎只是个“游戏大杂烩”是个把自己记忆中好玩的游戏全部杂凑在一起的“六十四合一”。<br /> <br />艺术的本源来自于生活，不管电影、文学、还是游戏，这点在我玩ndsl游戏时候特别有感触，最近国外出了个很火的游戏InkLink--画图猜词，就有点象我们年会上的游戏，一个人描述一个人猜成语，只不过该游戏用画画的方式进行，界面就像一个带聊天框的画板，万家轮流在上面用图画描述系统给他的单词，然后所有玩家根据他正在画的内容猜，越快猜出来的得分越高。这个游戏不大，但是的确让人眼前一亮的感觉。<br /> <br /><strong>2. 电影选材 vs 游戏选材：</strong><br /> <br />前段时间王朔跳出来还说：“只写自己经历过的事情”，刘欢在回答自己为什么很长时间不出专辑以及评价现在流行音乐不成熟的时候说：“成熟的行业，绝不做前人做过的事情”。参考电影和音乐我们可以简单的画出一个发展脉络：<br />  <br />   创新阶段 -&gt; 改良阶段（商业化阶段） -&gt; 抄袭阶段（泛滥阶段） -&gt; 枯竭阶段 <br /> <br />目前游戏选材是第二到第三阶段的过度，而电影选材早在95年就出现了选材枯竭现象，但是经历了10年的沉淀与反思，相信下一个电影创作高峰不会太远，而游戏也会象电影一样，过几年将进入一个题材休眠期。<br /> <br /><strong>3. 创新 vs 改良：</strong><br /> <br />之前读到姚壮宪一篇文章，文中主张不要轻提“创新”因为游戏历史已经有三十多年，“今后大部分制作都是一边看着前人的游戏，一边想着自己的设计”“人類既是依賴習慣的動物，也是追求新鮮感的動物”认为“综合+改良”是上乘功夫，若只是混合属于一般功夫，“若学其形而无其实，乃摸象之流”。。。<br /> <br />姚壮宪这个话放在《仙剑奇侠》的单机游戏时代，是很正确的，当时创新太多，意再规劝人们“改良”，而放在现在改良期已经进入尾声再来说这个话的时候，便会适得其反，因为现在的人太习惯改良了，再劝说他们改良，只能禁锢思想，因为习惯改良的成功就代表害怕新的设计。<br /> <br /><strong>4. 现代题材 vs 古典题材：</strong><br /> <br />国内那批六十年代电影学院毕业的第四代导演们被评价位“中国电影创作的主力军”，那我们的游戏设计者究竟还要经过几代，才能迎来一个崭新的全盛时期？<br /> <br />问题之一是古典游戏题材泛滥了，为什么古典题材会放浪呢？抛开审批问题，因为做古典题材相对容易，太多东西可以参考了，几大名著，二十六史，各类神怪传说全部是现成的；而相对来讲作现实题材确难的多，因为游戏设计者的思路会受到文学和电影发展束缚，不是需不需要避讳的问题，而是没有现成资料需要游戏设计者自己挖掘的问题。<br /> <br /><strong>5. 五千年的文化成为包袱：<br /></strong> <br />现实的情况是，很多人对古代史的熟悉程度似乎超过了现代史。说起诸子百家，三教九流，四大名著很多人都口若悬河，然而说起五四后的现代史，说起建国后的各个历史阶段，社会生活，却都知其一不知其二，能顺利的说出战国四公子是谁谁谁，却不能数出北洋政府执政过的几大军阀；数得出隋唐时期的十路烟尘，却连新中国的十大元帅都记不全；唐宋元明清的皇帝全能背诵却根本不知道七十年代初到八十年代末的几阶政治局常委是谁；知道古代军队的布阵却又不知现代军队的编制。<br /> <br />文化太悠久，名著太多，是好事，也是包袱，做不做现代题材，不是内容需不需要避讳的问题，也不是审批同步通过的问题，而是不愿花时间从现实生活中挖掘一手资料的问题。如果一不愿体查挖掘现实生活，二不能查资料作考证，那就只能做成科幻或者玄幻。国外游戏只有三到四成是古典题材，而国内游戏却有八九成徘徊在古典题材上，这是个不正常的比例。<br /> <br /><strong>6. 现代题材才是更加贴近生活的东西：<br /></strong> <br />现代题材的发掘过程应该是先从作家们开始（八十年代初已经开始了），然后再到导演们（八十年代末已经开始了），然后再到游戏（似乎没有开始）。不得不说现在的游戏制作者更偏爱历史而疏于现实，日本的养成游戏《心跳回忆》作到中国来却只能做成《金陵十二钗》或者《金瓶梅》，Westwood的即时战略游戏《C&amp;C》作来中国却只能做成：《官渡》《战国风云》《赤壁》等，这就是一个怪圈。<br /> <br /><strong>7. 反思：</strong><br /> <br />为什么会有如此的怪圈？归根结底一句话，从94-95年开始几款成功经典的国产游戏都是古典题材的。国内似乎难以找到成功的现代题材游戏，中关村启示录失败，地雷战失败，非常男女失败，铁甲风暴失败，似乎形成了思维惯性，思维定点于古代其实导致我们对很多现代题材缺乏敏感，比如《劲舞团》（似乎和大部分设计者不熟悉音乐不喜爱跳舞有关）比如《街头篮球》，再比如超现代的《第二人生》。<br /> <br /><strong>8. 拯救：</strong><br /> <br />张艺谋在八十年代时就曾经下决心要拯救现代主义题材的电影，王朔前段时间也说过类似的话，而反观游戏，今天的确需要我们回到生活中去，重新思考并挖掘题材，这样从题材上或许可以绕开目前游戏同类化严重的怪圈，重新进入一个新的原创阶段。<br /> </p><p>PS: “做中国文化特色的游戏来避免国外竞争”的说法我觉得值得商权，两点：</p><p>1) 中国文化特色不等于古典文化，更多的应该是现代文化，很多人似乎把它们划了等号<br />2) 这个观点的意思是会让人潜移默化的习惯“守住”而不是去“开拓”<br /> <br />更实际的情况是，如果一味想守，是守不住的，八国联军只需要本地化一下招聘本地员工开发本地游戏，什么问题都解决了。之前wps就是个教训，97年求伯君全国循讲他卖别墅做wps97时就说，金山的优势在于金山了解中国人的习惯，几年之后仍然抵挡不住微软本地化的策略，office2000迅速普及，所以说希望靠守住本地文化来抵御竞争是不明智的做法，归根结底是要有新的好的设计。</p><p><br /></p>
	<br>   (<a href=http://www.joynb.net/blog/index.php?job=art&amp;articleid=a_20070302_233450 target=_blank> 网页浏览 </a>)
  ]]> 
</description>
</item><item>
<link>http://www.joynb.net/blog/index.php?job=art&amp;articleid=a_20070102_232655</link>
<title>比尔·云风传奇</title> 
<author>skywind &lt;skywind3000@163.com&gt;</author>
<category>Skywind Inside</category>
<pubDate>Tue, 02 Jan 2007 23:26:55 +0800</pubDate> 
 <guid>http://www.joynb.net/blog/index.php?job=art&amp;articleid=a_20070102_232655</guid> 
<description>
<![CDATA[ 
	<p>1. 比尔·云风刚出生便会说话，邻居描述，刚落地时他就向东南方向走了七步，每走一步地上就出现一个“ at ”符号，只见他七步之后，伸左手指天，伸右手指地，开口说道：“2D/3D唯我独尊”。。。。</p><p>2 dot  《徐庶走马荐比尔，刘玄德三顾茅庐》：徐庶：“主公不必难过，五步之内必有芳草，远来的和尚，未必念得了真经，蜀国如要上市，庶愿保举一人”，刘备：“知道是你好朋友诸葛孔明，这人人品不行，我面试过。他要我联伊抗美，与基地组织共出奇兵占领NASDAQ机房，奉股市而令不臣，控制所有上市公司。靠！备乃仁义之团队，向来讲求信誉，强调共赢，怎忍心做此等伤天害理之事”，徐庶：“是是是，主公是讲求信誉，力主双赢的仁义团队，但是我要推荐的另有其人”，“哦，应届生？现在何处？开口多少？”，“这人复姓比尔，双名云风，家住荆州长沙郡，现在幽州雪碧九游戏当差。”，备：“哦，没听过”，庶：“这位好汉十八般语言门门精通，上能构架操作系统；下能设计嵌入芯片！”，备：“有这种怪人？”，庶：“不当如此，比尔·云风左手提一百二十斤混铁鼠标，右手抱三百五十斤工学键盘，竞争对手虽有千军万马，近不得他办公桌前一步！三十六小时持续编码依旧气定神闲，体力耐力无人能及。”，刘备：“赞！是块加班的好料，想起来了，水镜先生也向我推荐过，说他‘手握设计无数种，胸中代码千万行’，备若得此一人，何患《汉室》30万在线！他在雪碧九拿多少？”徐庶：“XXX”，刘备：“大伯如何？”徐庶：“至少再多500元”，刘备：“恩，只要他证明他的能力，再多600都不在乎，我们向来尊重人才，QQ，MSN，MAIL统统给我”，徐庶：“听说他最近ADSL欠费，手机停机，就连email都发不出去，主公要见，恐怕只有亲自前往”，刘备：“如此说来，备当前往看看”。。。。</p><p>（未完，待续）</p><p /><p />
	<br>   (<a href=http://www.joynb.net/blog/index.php?job=art&amp;articleid=a_20070102_232655 target=_blank> 网页浏览 </a>)
  ]]> 
</description>
</item><item>
<link>http://www.joynb.net/blog/index.php?job=art&amp;articleid=a_20061224_164558</link>
<title>Winamp Tiny Implemention - using ctypes</title> 
<author>skywind &lt;skywind3000@163.com&gt;</author>
<category>Skywind Inside</category>
<pubDate>Sun, 24 Dec 2006 16:45:58 +0800</pubDate> 
 <guid>http://www.joynb.net/blog/index.php?job=art&amp;articleid=a_20061224_164558</guid> 
<description>
<![CDATA[ 
	<p>This module is a tiny winamp implemention using ctypes, which presents mp3/wav/mid/ogg... playback in python by calling winamp plugins. Treating it as a little example for advanced ctypes usage. You can download the full demo (in_mp3.dll, out_wave.dll, sample.mp3 included) from: <a href="http://www.joynb.net/blog/up/1166948100.rar" target="_blank"><a href="http://www.joynb.net/blog/up/1166948100.rar" target="_blank">http://www.joynb.net/blog/up/1166948100.rar</a></a> -- by skywind3000 at hotmail dot com<br /><br /></p><p><b>Source:</b> <a href="http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/499341/index_txt">Text Source</a></p><pre class="code"><span class="syntaxcomment">#======================================================================</span><br /><span class="syntaxcomment"># </span><br /><span class="syntaxcomment"># winamp.py - winamp control interface</span><br /><span class="syntaxcomment"># copyright 2006 (c) skywind3000 at hotmail dot com</span><br /><span class="syntaxcomment">#</span><br /><span class="syntaxcomment"># NOTE: </span><br /><span class="syntaxcomment">#</span><br /><span class="syntaxcomment"># This module is a tiny winamp implemention using ctypes, which</span><br /><span class="syntaxcomment"># presents mp3/wav/mid/ogg... playback in python by calling winamp</span><br /><span class="syntaxcomment"># plugins. Treating it as a little example for advanced ctypes usage</span><br /><span class="syntaxcomment">#</span><br /><span class="syntaxcomment"># most of common plugins in winamp5 or above need a shared dll named </span><br /><span class="syntaxcomment"># nscrt.dll, you need copy it to current dir from %winamp%/plugins/</span><br /><span class="syntaxcomment">#</span><br /><span class="syntaxcomment"># the plugins in winamp4.0/2.0 do not need it, you can only copy </span><br /><span class="syntaxcomment"># in_*.dll or out_*.dll to current dir </span><br /><span class="syntaxcomment">#</span><br /><span class="syntaxcomment"># for more information, please see <a href="http://www.winamp.com/nsdn/winamp/" target="_blank">http://www.winamp.com/nsdn/winamp/</a></span><br /><span class="syntaxcomment"># to get full example (in_mp3.dll, out_wave.dll, sample.mp3 include): </span><br /><span class="syntaxcomment"># <a href="http://www.joynb.net/blog/up/1166948100.rar" target="_blank">http://www.joynb.net/blog/up/1166948100.rar</a></span><br /><span class="syntaxcomment">#</span><br /><span class="syntaxcomment">#======================================================================</span><br /><br /><span class="syntaxkeyword">import</span> sys, os, time<br /><span class="syntaxkeyword">import</span> ctypes<br /><span class="syntaxkeyword">from</span> ctypes <span class="syntaxkeyword">import</span> c_long, c_char_p, c_voidp, c_int, c_short, c_byte<br /><span class="syntaxkeyword">from</span> ctypes <span class="syntaxkeyword">import</span> POINTER, CFUNCTYPE, pointer, byref<br /><span class="syntaxkeyword">from</span> ctypes <span class="syntaxkeyword">import</span> cast, addressof, cdll, windll<br /><span class="syntaxkeyword">from</span> ctypes.wintypes <span class="syntaxkeyword">import</span> *<br /><br /><br /><span class="syntaxcomment">#----------------------------------------------------------------------</span><br /><span class="syntaxcomment"># struct OutModule definition</span><br /><span class="syntaxcomment">#----------------------------------------------------------------------</span><br /><span class="syntaxkeyword">class</span> <span class="syntaxname">OutModule</span>(ctypes.Structure):<br />    _fields_ = [<br />    (<span class="syntaxstring">&quot;version&quot;</span>, c_long), <br />    (<span class="syntaxstring">&quot;description&quot;</span>, c_char_p),<br />    (<span class="syntaxstring">&quot;id&quot;</span>, c_int),<br />    (<span class="syntaxstring">&quot;hMainWindow&quot;</span>, c_voidp),<br />    (<span class="syntaxstring">&quot;hDllInstance&quot;</span>, c_voidp),<br />    (<span class="syntaxstring">&quot;config&quot;</span>, CFUNCTYPE(None, c_voidp)),<br />    (<span class="syntaxstring">&quot;about&quot;</span>, CFUNCTYPE(None, c_voidp)),<br />    (<span class="syntaxstring">&quot;init&quot;</span>, CFUNCTYPE(None,)),<br />    (<span class="syntaxstring">&quot;quit&quot;</span>, CFUNCTYPE(None,)),<br />    (<span class="syntaxstring">&quot;open&quot;</span>, CFUNCTYPE(c_int, c_int, c_int, c_int, c_int, c_int)),<br />    (<span class="syntaxstring">&quot;close&quot;</span>, CFUNCTYPE(None,)),<br />    (<span class="syntaxstring">&quot;write&quot;</span>, CFUNCTYPE(c_int, c_voidp, c_int)),<br />    (<span class="syntaxstring">&quot;canwrite&quot;</span>, CFUNCTYPE(c_int,)),<br />    (<span class="syntaxstring">&quot;isplaying&quot;</span>, CFUNCTYPE(c_int,)),<br />    (<span class="syntaxstring">&quot;pause&quot;</span>, CFUNCTYPE(c_int, c_int)),<br />    (<span class="syntaxstring">&quot;setvol&quot;</span>, CFUNCTYPE(None, c_int)),<br />    (<span class="syntaxstring">&quot;setpan&quot;</span>, CFUNCTYPE(None, c_int)),<br />    (<span class="syntaxstring">&quot;flush&quot;</span>, CFUNCTYPE(None, c_int)),<br />    (<span class="syntaxstring">&quot;getoutputtime&quot;</span>, CFUNCTYPE(c_int,)),<br />    (<span class="syntaxstring">&quot;getwrittentime&quot;</span>, CFUNCTYPE(c_int,))<br />  ]<br /><br /><br /><span class="syntaxcomment">#----------------------------------------------------------------------</span><br /><span class="syntaxcomment"># struct InModule definition</span><br /><span class="syntaxcomment">#----------------------------------------------------------------------</span><br /><span class="syntaxkeyword">class</span> <span class="syntaxname">InModule</span>(ctypes.Structure):<br />    _fields_ = [<br />    (<span class="syntaxstring">&quot;version&quot;</span>, c_long), <br />    (<span class="syntaxstring">&quot;description&quot;</span>, c_char_p),<br />    (<span class="syntaxstring">&quot;hMainWindow&quot;</span>, c_voidp),<br />    (<span class="syntaxstring">&quot;hDllInstance&quot;</span>, c_long),<br />    (<span class="syntaxstring">&quot;FileExtensions&quot;</span>, c_char_p),<br />    (<span class="syntaxstring">&quot;is_seekable&quot;</span>, c_int),<br />    (<span class="syntaxstring">&quot;UsesOutputPlug&quot;</span>, c_int),<br />    (<span class="syntaxstring">&quot;config&quot;</span>, CFUNCTYPE(None, c_voidp)),  <span class="syntaxcomment"># 7</span><br />    (<span class="syntaxstring">&quot;about&quot;</span>, CFUNCTYPE(None, c_voidp)),<br />    (<span class="syntaxstring">&quot;init&quot;</span>, CFUNCTYPE(None,)),<br />    (<span class="syntaxstring">&quot;quit&quot;</span>, CFUNCTYPE(None,)),<br />    (<span class="syntaxstring">&quot;getfileinfo&quot;</span>, CFUNCTYPE(None, c_char_p, c_char_p, POINTER(c_int))),<br />    (<span class="syntaxstring">&quot;infobox&quot;</span>, CFUNCTYPE(c_int, c_char_p, c_voidp)),<br />    (<span class="syntaxstring">&quot;isourfile&quot;</span>, CFUNCTYPE(c_int, c_char_p)),<br />    (<span class="syntaxstring">&quot;play&quot;</span>, CFUNCTYPE(c_int, c_char_p)), <span class="syntaxcomment"># 14</span><br />    (<span class="syntaxstring">&quot;pause&quot;</span>, CFUNCTYPE(None, )),<br />    (<span class="syntaxstring">&quot;unpause&quot;</span>, CFUNCTYPE(None, )),<br />    (<span class="syntaxstring">&quot;ispaused&quot;</span>, CFUNCTYPE(c_int, )),<br />    (<span class="syntaxstring">&quot;stop&quot;</span>, CFUNCTYPE(None, )),<br />    (<span class="syntaxstring">&quot;getlength&quot;</span>, CFUNCTYPE(c_int, )),<br />    (<span class="syntaxstring">&quot;getoutputtime&quot;</span>, CFUNCTYPE(c_int, )),<br />    (<span class="syntaxstring">&quot;setoutputtime&quot;</span>, CFUNCTYPE(None, c_int)),<br />    (<span class="syntaxstring">&quot;setvol&quot;</span>, CFUNCTYPE(None, c_int)),<br />    (<span class="syntaxstring">&quot;setpan&quot;</span>, CFUNCTYPE(None, c_int)), <span class="syntaxcomment"># 23</span><br />    (<span class="syntaxstring">&quot;SAVSAInit&quot;</span>, CFUNCTYPE(None, c_int, c_int)),<br />    (<span class="syntaxstring">&quot;SAVSADeInit&quot;</span>, CFUNCTYPE(None, )),<br />    (<span class="syntaxstring">&quot;SAAddPCMData&quot;</span>, CFUNCTYPE(None, c_voidp, c_int, c_int, c_int)),<br />    (<span class="syntaxstring">&quot;SAGetMode&quot;</span>, CFUNCTYPE(c_int,)),<br />    (<span class="syntaxstring">&quot;SAAdd&quot;</span>, CFUNCTYPE(None, c_voidp, c_int, c_int)),<br />    (<span class="syntaxstring">&quot;VSAAddPCMData&quot;</span>, CFUNCTYPE(None, c_voidp, c_int, c_int, c_int)),<br />    (<span class="syntaxstring">&quot;VSAGetMode&quot;</span>, CFUNCTYPE(c_int, POINTER(c_int), POINTER(c_int))),<br />    (<span class="syntaxstring">&quot;VSAAdd&quot;</span>, CFUNCTYPE(None, c_voidp, c_int)),<br />    (<span class="syntaxstring">&quot;VSASetInfo&quot;</span>, CFUNCTYPE(None, c_int, c_int)),<br />    (<span class="syntaxstring">&quot;dsp_isactive&quot;</span>, CFUNCTYPE(c_int, )),<br />    (<span class="syntaxstring">&quot;dsp_dosamples&quot;</span>, CFUNCTYPE(c_int, c_voidp, c_int, c_int, c_int, c_int)),<br />    (<span class="syntaxstring">&quot;eqset&quot;</span>, CFUNCTYPE(None, c_int, c_char_p, c_int)),<br />    (<span class="syntaxstring">&quot;setinfo&quot;</span>, CFUNCTYPE(None, c_int, c_int, c_int, c_int)),<br />    (<span class="syntaxstring">&quot;outmod&quot;</span>, POINTER(OutModule))<br />  ]<br /><br /><br /><span class="syntaxcomment"># export OutModule from dll</span><br /><span class="syntaxkeyword">def</span> load_outmod(dllname):<br />  outdll = ctypes.cdll.LoadLibrary(dllname)<br />  getaddr = outdll.winampGetOutModule<br />  getaddr.restype = c_voidp<br />  <span class="syntaxcomment"># outmod = (OutModule*)(getaddr())</span><br />  outmod = cast(getaddr(), POINTER(OutModule))[0]<br />  <span class="syntaxkeyword">return</span> outmod<br /><br /><span class="syntaxcomment"># export InModule from dll</span><br /><span class="syntaxkeyword">def</span> load_inmod(dllname):<br />  indll = ctypes.cdll.LoadLibrary(dllname)<br />  getaddr = indll.winampGetInModule2<br />  getaddr.restype = c_voidp<br />  <span class="syntaxcomment"># inmod = (InModule*)(getaddr())</span><br />  inmod = cast(getaddr(), POINTER(InModule))[0]<br />  <span class="syntaxkeyword">return</span> inmod<br /><br /><span class="syntaxcomment"># init inmod/outmod together</span><br /><span class="syntaxkeyword">def</span> init_modules(inmod, outmod):<br />  <span class="syntaxkeyword">def</span> _SAVSAInit(n1, n2): <span class="syntaxkeyword">pass</span><br />  <span class="syntaxkeyword">def</span> _SAVSADeInit(): <span class="syntaxkeyword">pass</span><br />  <span class="syntaxkeyword">def</span> _SAAddPCMData(n1, n2, n3, n4): <span class="syntaxkeyword">pass</span><br />  <span class="syntaxkeyword">def</span> _SAGetMode(): <span class="syntaxkeyword">return</span> 0;<br />  <span class="syntaxkeyword">def</span> _SAAdd(n1, n2, n3): <span class="syntaxkeyword">pass</span><br />  <span class="syntaxkeyword">def</span> _VSAAdd(n1, n2): <span class="syntaxkeyword">pass</span><br />  <span class="syntaxkeyword">def</span> _VSAAddPCMData(n1, n2, n3, n4): <span class="syntaxkeyword">pass</span><br />  <span class="syntaxkeyword">def</span> _VSAGetMode(n1, n2): <span class="syntaxkeyword">return</span> 0<br />  <span class="syntaxkeyword">def</span> _VSASetInfo(n1, n2): <span class="syntaxkeyword">pass</span><br />  <span class="syntaxkeyword">def</span> _dspisactive(): <span class="syntaxkeyword">return</span> 0<br />  <span class="syntaxkeyword">def</span> _dspyesactive(): <span class="syntaxkeyword">return</span> 1<br />  <span class="syntaxkeyword">def</span> _dspdo(n1, n2, n3, n4, n5): <span class="syntaxkeyword">return</span> 0<br />  <span class="syntaxkeyword">def</span> _setinfo(n1, n2, n3, n4): <span class="syntaxkeyword">pass</span><br />  <span class="syntaxkeyword">def</span> _eqset(n1, n2, n3): <span class="syntaxkeyword">pass</span><br /><br />  <span class="syntaxcomment"># setting up default dummy functions</span><br />  inmod.SAVSAInit = CFUNCTYPE(None, c_int, c_int)(_SAVSAInit)<br />  inmod.SAVSADeInit = CFUNCTYPE(None, )(_SAVSADeInit)<br />  inmod.SAAddPCMData = CFUNCTYPE(None, c_voidp, c_int, c_int, c_int)(_SAAddPCMData)<br />  inmod.SAGetMode = CFUNCTYPE(c_int,)(_SAGetMode)<br />  inmod.SAAdd = CFUNCTYPE(None, c_voidp, c_int, c_int)(_SAAdd)<br />  inmod.VSAAdd = CFUNCTYPE(None, c_voidp, c_int)(_VSAAdd)<br />  inmod.VSAAddPCMData = CFUNCTYPE(None, c_voidp, c_int, c_int, c_int)(_VSAAddPCMData)<br />  inmod.VSAGetMode = CFUNCTYPE(c_int, POINTER(c_int), POINTER(c_int))(_VSAGetMode)<br />  inmod.VSASetInfo = CFUNCTYPE(None, c_int, c_int)(_VSASetInfo)<br />  inmod.dsp_isactive = CFUNCTYPE(c_int, )(_dspisactive)<br />  inmod.dsp_dosamples = CFUNCTYPE(c_int, c_voidp, c_int, c_int, c_int, c_int)(_dspdo)<br />  inmod.setinfo = CFUNCTYPE(None, c_int, c_int, c_int, c_int)(_setinfo)<br />  inmod.eqset = CFUNCTYPE(None, c_int, c_char_p, c_int)(_eqset)<br /><br />  <span class="syntaxcomment"># setting up other members</span><br />  inmod.outmod = pointer(outmod)<br />  GetActiveWindow = windll.user32.GetActiveWindow<br />  inmod.hMainWindow = GetActiveWindow()<br />  inmod.hDllInstance = 0<br />  outmod.hMainWindow = GetActiveWindow()<br />  outmod.hDllInstance = 0<br /><br />  <span class="syntaxkeyword">return</span>  0  <br /><br /><br /><span class="syntaxcomment">#----------------------------------------------------------------------</span><br /><span class="syntaxcomment"># Global Variables</span><br /><span class="syntaxcomment">#----------------------------------------------------------------------</span><br />__in_module = None<br />__out_module = None<br /><br /><span class="syntaxcomment">#----------------------------------------------------------------------</span><br /><span class="syntaxcomment"># Winamp Main Interface</span><br /><span class="syntaxcomment">#----------------------------------------------------------------------</span><br /><span class="syntaxkeyword">def</span> init(indll, outdll):<br />  <span class="syntaxkeyword">global</span> __in_module, __out_module<br />  quit()<br />  <span class="syntaxkeyword">try</span>:<br />    __in_module  = load_inmod(indll)<br />    __out_module = load_outmod(outdll)<br />  <span class="syntaxkeyword">except</span>: <span class="syntaxkeyword">return</span> -1<br />  init_modules(__in_module, __out_module)<br />  __out_module.init()<br />  __in_module.init()<br />  <span class="syntaxkeyword">return</span> 0<br /><br /><span class="syntaxkeyword">def</span> quit():<br />  <span class="syntaxkeyword">global</span> __in_module, __out_module<br />  <span class="syntaxkeyword">if</span> __in_module: <br />    __in_module.stop()<br />    __in_module.quit()<br />  <span class="syntaxkeyword">if</span> __out_module: __out_module.quit()<br />  __in_module = None<br />  __out_module = None<br /><br /><span class="syntaxkeyword">def</span> play(name):<br />  <span class="syntaxkeyword">return</span> __in_module.play(name)<br /><br /><span class="syntaxkeyword">def</span> stop():<br />  __in_module.stop()<br /><br /><span class="syntaxkeyword">def</span> pause(status = True):<br />  <span class="syntaxkeyword">if</span> status: __in_module.pause()<br />  <span class="syntaxkeyword">else</span>: __in_module.unpause()<br /><br /><span class="syntaxkeyword">def</span> ispaused():<br />  <span class="syntaxkeyword">return</span> __in_module.ispaused()<br /><br /><span class="syntaxkeyword">def</span> getlength():<br />  <span class="syntaxkeyword">return</span> __in_module.getlength()<br /><br /><span class="syntaxkeyword">def</span> gettime():<br />  <span class="syntaxkeyword">return</span> __in_module.getoutputtime()<br /><br /><span class="syntaxkeyword">def</span> settime(timems):<br />  __in_module.setoutputtime(timems)<br /><br /><span class="syntaxkeyword">def</span> setvol(vol = 1.0):<br />  __in_module.setvolume(int(vol * 255))<br /><br /><span class="syntaxkeyword">def</span> setpan(pan = 0.0):<br />  __in_module.setpan(int(pan * 127))<br /><br /><span class="syntaxkeyword">def</span> fileinfo(name):<br />  i = ctypes.c_int()<br />  s = ctypes.create_string_buffer(<span class="syntaxstring">'\000'</span> * 256)<br />  __in_module.getfileinfo(name, s, pointer(i))<br />  <span class="syntaxkeyword">return</span> (s.value, i.value)<br /><br /><br /><span class="syntaxcomment">#----------------------------------------------------------------------</span><br /><span class="syntaxcomment"># Testing Code</span><br /><span class="syntaxcomment">#----------------------------------------------------------------------</span><br /><span class="syntaxkeyword">if</span> __name__ == <span class="syntaxstring">'__main__'</span>:<br />  indll = <span class="syntaxstring">'in_mp3.dll'</span><br />  outdll = <span class="syntaxstring">'out_wave.dll'</span><br />  <span class="syntaxkeyword">if</span> init(indll, outdll):<br />    <span class="syntaxkeyword">print</span> <span class="syntaxstring">'cannot load plugins'</span><br />    sys.exit(0)<br />  name = <span class="syntaxstring">'sample.mp3'</span><br />  info = fileinfo(name)<br /><br />  <span class="syntaxkeyword">def</span> ms2time(ms):<br />    <span class="syntaxkeyword">if</span> ms &lt;= 0: <span class="syntaxkeyword">return</span> <span class="syntaxstring">'00:00:000'</span><br />    time_sec, ms = ms / 1000, ms % 1000<br />    time_min, time_sec = time_sec / 60, time_sec % 60<br />    time_hor, time_min = time_min / 60, time_min % 60<br />    <span class="syntaxkeyword">if</span> time_hor == 0: <span class="syntaxkeyword">return</span> <span class="syntaxstring">'%02d:%02d:%03d'</span>%(time_min, time_sec, ms)<br />    <span class="syntaxkeyword">return</span> <span class="syntaxstring">'%02d:%02d:%02d:%03d'</span>%(time_hor, time_min, time_sec, ms)<br /><br />  <span class="syntaxkeyword">print</span> <span class="syntaxstring">'Playing &quot;%s&quot; (%s), press \'q\' to exit ....'</span>%(info[0], name)<br />  play(name)<br />  user32 = ctypes.windll.user32<br />  <span class="syntaxkeyword">while</span> 1:<br />    user32.GetAsyncKeyState.restype = WORD<br />    user32.GetAsyncKeyState.argtypes = [ ctypes.c_char ]<br />    <span class="syntaxkeyword">if</span> user32.GetAsyncKeyState(<span class="syntaxstring">'Q'</span>): <span class="syntaxkeyword">break</span><br />    time.sleep(0.1)<br />    <span class="syntaxkeyword">print</span> <span class="syntaxstring">'[%s / %s]\r'</span>%(ms2time(gettime()), ms2time(getlength())),<br />    <span class="syntaxkeyword">if</span> (gettime() &gt; 0) <span class="syntaxkeyword">and</span> (gettime() &gt; getlength() - 3000):<br />      settime(0)<br />  <span class="syntaxkeyword">print</span> <span class="syntaxstring">'\nstopped'</span><br />  quit()</pre><p><br /></p><p><b>Discussion:</b></p><p>As ctypes has become the standard module in python2.5, a interface reform happened in my projects. Because most of beginner don't know how powerful is it and how far can it go, I am thinking to give a example to show how we can use ctypes better in c/python interface delegating.<br /><br />Thanks for winamp sdk (<a href="http://www.winamp.com/nsdn/winamp/" target="_blank">http://www.winamp.com/nsdn/winamp/</a>), I got the way to writing / calling winamp plugins from my program. That is I translate the plugin interface to python by referencing winamp-sdk, and thinking it would be a funny example for ctypes usage.</p>
	<br>   (<a href=http://www.joynb.net/blog/index.php?job=art&amp;articleid=a_20061224_164558 target=_blank> 网页浏览 </a>)
  ]]> 
</description>
</item><item>
<link>http://www.joynb.net/blog/index.php?job=art&amp;articleid=a_20061021_012356</link>
<title>据说：有程序员是这样工作的</title> 
<author>skywind &lt;skywind3000@163.com&gt;</author>
<category>Skywind Inside</category>
<pubDate>Sat, 21 Oct 2006 01:23:56 +0800</pubDate> 
 <guid>http://www.joynb.net/blog/index.php?job=art&amp;articleid=a_20061021_012356</guid> 
<description>
<![CDATA[ 
	<img src="http://www.joynb.net/blog/up/1161364976.gif" />
	<br>   (<a href=http://www.joynb.net/blog/index.php?job=art&amp;articleid=a_20061021_012356 target=_blank> 网页浏览 </a>)
  ]]> 
</description>
</item></channel>
</rss>