2009年12月15日 星期二

XNA Checker - 在 XNA 遊戲啟動時檢測 Windows 內的XNA Framework 版本的小軟件

小弟無聊時寫的Win32程式,
可以在XNA遊戲啟動時檢測XNA版本,
版本不符就放棄遊戲啟動.

源代碼

檢測Windows內的XNA Framework 版本

在發現.NET Framework 安裝在 Windows 之下是會把版本號寫入 Regedit 內,
我就由此得到啟示,想試試研究檢測Windows內的XNA Framework 版本方法,
剛巧發現可以用接近的方法去知道的XNA Framework 版本

記載XNA Framework 版本的路徑 :
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\XNA\Framework

註1: XNA Framework 2.0以前的版本安裝以後是沒有 Installed 參數的,
哪裡只找到 NativeLibraryPath 參數

2009年12月14日 星期一

檢測Windows內的.NET Framework 版本

.NET Framework 安裝在 Windows 之下是會把版本號寫入 Regedit 內的,
所以要檢測Windows內的.NET Framework 版本就由此入手.

記載.NET Framework 版本的路徑 :
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP

網上還有人寫了一個 C 版本的檢測程式而且是開源的
下載地址

2009年10月13日 星期二

中文常用編碼轉換

中文XP分為繁體XP(BIG5)和簡體XP(GB2312),這裡簡單的說一下我們常見的編碼轉換,GB2312,BIG5,UTF8,Unicode.這四種編碼的是怎麼轉換的。
以下code在VC6上調試過,應該沒有問題。因為有兩個函數的參數不好設置MultiByteToWideChar和WideCharToMultiByte,所以自己就在VC6上調試,把自己的結論寫下來。(這裡隻是簡單的code中間有一些申請空間,釋放空間,都沒有寫,但是總的原則是,有這兩個函數MultiByteToWideChar和WideCharToMultiByte先計算要幾個空閒,再申請,使用,釋放)

這個參數設置說明:
(一) GB2312,BIG5到Unicode
DWORD num = MultiByteToWideChar(CP_ACP,0,cword,-1,NULL,0);
//計算這個GB2312, BIG5實際有幾個字組成
MultiByteToWideChar(CP_ACP,0, cword, -1, wword, num);
//GB2312 BIG5轉變為Unicode

(二) UTF-8到Unicode
DWORD num = MultiByteToWideChar(CP_UTF8,0,buffer,-1,NULL,0);
//計算這個UTF-8實際有幾個字組成
MultiByteToWideChar(CP_ACP ,0, buffer, -1, wword, num);
//UTF8轉變為Unicode

(三) UTF-8到GB2312,BIG5
方法一:UTF-8到Unicode 再從Unicode到GB2312,BIG5
DWORD num = MultiByteToWideChar(CP_UTF8,0,buffer,-1,NULL,0);
//計算這個UTF-8實際有幾個字組成
MultiByteToWideChar(CP_ACP ,0, buffer, -1, wword, num);
//UTF8轉變為Unicode
DWORD num = WideCharToMultiByte(CP_ACP,0,wword,-1,NULL,0,NULL,0);
//計算這個UNICODE實際有幾個GB2312 BIG5字組成
WideCharToMultiByte(CP_ACP,0, wword, -1, cword, num,NULL,0);
//Unicode轉變為GB2312 BIG5

(四) Unicode到GB2312,BIG5
DWORD num = WideCharToMultiByte(CP_ACP,0,wword,-1,NULL,0,NULL,0);
//計算這個UNICODE實際有幾個GB2312 BIG5字組成
WideCharToMultiByte(CP_ACP,0, wword, -1, cword, num,NULL,0);
//Unicode轉變為GB2312 BIG5

(五) Unicode到UTF-8
DWORDnum=WideCharToMultiByte(CP_UTF8,0,wword,-1,NULL,0,NULL,NULL);
//計算這個UNICODE實際有幾個UTF-8字組成
WideCharToMultiByte(CP_ACP,0, wword, -1, cword, num,NULL,NULL);
//Unicode轉變為UTF-8

(六) GB2312 BIG5到UTF-8
方法一:GB2312,BIG5到Unicode 再從Unicode到UTF-8
DWORD num = MultiByteToWideChar(CP_ACP,0,cword,-1,NULL,0);
//計算這個GB2312, BIG5實際有幾個字組成
MultiByteToWideChar(CP_ACP,0, cword, -1, wword, num);
//GB2312 BIG5轉變為Unicode
DWORDnum=WideCharToMultiByte(CP_UTF8,0,wword,-1,NULL,0,NULL,NULL);
//計算這個UNICODE實際有幾個UTF-8字組成
WideCharToMultiByte(CP_ACP,0, wword, -1, cword, num,NULL,NULL);
//Unicode轉變為UTF-8

轉自 波周的BLOG

Unicode轉UTF-16

一 UTF-16

UTF-16是Unicode的其中一個使用方式。 UTF是 Unicode/UCS Transformation Format,即把Unicode轉做某種格式的意思。但是萬萬不要說UTF-16編碼就是Unicode,這是不對的,因為Unicode他是由2個byte組成的,但是大多數UTF-16也是2個byte組成的,也有4個byte組成的,如:中國文字大部份是兩位元組,有的是四位元組(很多人可能沒見過,方正楷體S-超大字元集(SIP)這個字體裏面存放的都是四位元組的字模,可以從http://wyx.nbtvu.net.cn/jmm/Computing/indexComputing.htm下載相關字體)。

二 UTF-16編碼

1.Unicode值小於0x10000的用等於該值的16位元整數來表示。
2.Unicode值介於0x10000和0x10FFFF之間的,用一個值介於0xD800和0xDBFF(在所謂的高8位區)的16位元整數和值介於0xDC00和0xDFFF(在所謂的低8位區)的16位元整數來表示。
3.Unicode值大於0x10FFFF不能按照UTF-16進行編碼。




注意:在0xD800和0xDFFF間的值是特別為UTF-16預留,所以不應該將任何字元的值指定為這個區間內的數值.UTF-16比起UTF-8,好處在於大部分字元都以固定長度的位元組(2位元組)儲存,但UTF-16卻無法相容於ASCII編碼。

三 Unicode轉UTF-16

將某個字元的Unicode值轉換為UTF-16的編碼按照以下步驟進行。假設U是給Unicode值,小於x10FFFF。
1) 如果U < 0x10000,U的編碼就是無符號的十六位元整數,值和其本身的值一樣,處理結束。 2) 如果U等於或者小於0x10FFFF,則設U' = U - 0x10000。此時,U'一定小於或者等於0xFFFFF,也就是說,U'的值不會超過20位。 3) 分別初始化2個16位元無符號的整數,W1和W2為0xD800和0xDC00。每個整數都有10位元可以用來對字元進行編碼,正好能容納U'的20位。 4) 將U'的高10位分配給W1的低10位,將U'的低10位分配給W2的低10位,處理結束。用數字來表示,第2步到第4步如下所示: U' = yyyyyyyyyyxxxxxxxxxx W1 = 110110yyyyyyyyyy W2 = 110111xxxxxxxxxx 四 Code 下面的code是簡單的實現一個Unicode轉成UTF-16的功能。沒有實現一批批字元的轉,把這段code改進一下就可以了。

#include
int main()
{
FILE *out ;
long unicode = 74565; //在這裏只拿一個值做個演示0x12345
//U+12345表示為 D8 08 DF 45(UTF-16BE),或者08 D8 45 DF(UTF-16LE)。
long h , l ;
out = fopen("out.txt","wb");
fputwc(L'\xFEFF', out);
if (unicode < 0 unicode >0x10ffff)
{
printf("error!");
}
else
{
if (unicode <0x10000) { fwprintf(out,L"%c", unicode); } else { unicode = unicode - 0x10000 ; long vh = (unicode & 0xFFC00) >> 10 ;
long vl = unicode & 0x3ff;
h = 0xD800 vh;
l = 0xDC00 vl;
fwprintf(out,L"%c",h);
fwprintf(out,L"%c",l);
}
}
}

轉自 波周的BLOG

UTF-16轉Unicode

一 UTF-16轉Unicode

首先值得說明的是UTF-16到Unicode和UTF-8到Unicode是不一樣的,不可以用Windows的API函數MultiByteToWideChar,因為他只支持UTF-8不支持UTF-16.所以我們必須按編碼規則來轉。
將單個字元從UTF-16解碼為Unicode值的步驟如下。設W1為待解碼文字中第一個16位元的整數,設W2為跟在W1後的整數(如果有的話)。
1) 如果W1小於0xD800或者W1大於0xDFFF,字元的值U就是W1的值,處理結束。
2) 判斷W1的值是否介於0xD800和0xDBFF之間。如果不是,那麼順序有誤,而且用W1將不能解碼出任何合法字元。處理結束。
3) 如果沒有W2(也就是說,以W1結尾),或者雖然有W2,但不是介於0xDC00和0xDFFF之間,那麼順序同樣有錯。處理結束。
4) 建立一個20位元的無符號整數U',將W1的低10位作為U'的高10位,將W2的低10位作為U'的低10位。
5) 將U'的值加上0x10000以得到字元U的值,處理結束。

二 code
#include
#include
int main()
{
FILE *out;
long sour[] = {0xfeff , 0xd808 , 0xdf45};
//由兩個UTF-16字元,一個是XFFEF,一個是xd808 , 0xdf45
long i = 0 ;
long len = 2 ;
out = fopen("out2.txt","wb");
while(i < len) { if (sour[i]<0xD800 || sour[i]>0xDFFF)
{
printf("%x\n",sour[i] , sour[i]);
i = i + 1;
}
if (sour[i]>0xd800 && sour[i] < 0xdbff) { sour[i] = sour[i] - 0xD800; long h = sour[i] ; i = i + 1 ; if (i > len)
{
printf("not have W2 error!\n");
}
else if (sour[i]>0xDC00 && sour[i] < 0xdfff) { sour[i] = sour[i] - 0xDC00; long l = sour[i]; i = i + 1 ; long unicode = (h << 10) | l + 0x10000 ; printf("%x", unicode); } else { printf("error W2\n"); } } else { printf("error w1 \n"); } } }

轉自 波周的BLOG

2009年10月11日 星期日

Irrlicht 引擎的偽隨機數產生公式

int seed = 0x0f0f0f0f;

//! generates a pseudo random number
int rand()
{
const int m = 2147483399; // a non-Mersenne prime
const int a = 40692; // another spectral success story
const int q = m/a;
const int r = m%a; // again less than q

seed = a * (seed%q) - r* (seed/q);
if (seed<0) seed += m; return seed; }

2009年10月6日 星期二

PHP 中獲取使用者的 IP

Get user IP in PHP

一般在取得使用者 IP 都是利用 $_SERVER['REMOTE_ADDR'] 這個環境變數,但是此變數只會紀錄最後一個主機 IP,所以當使用者瀏覽器有設定 Proxy 時,就無法取得他的真實 IP。

這時可以使用另一個環境變數 $_SERVER['HTTP_X_FORWARDED_FOR'] ,它會紀錄所經過的主機 IP,但是只有在使用者有透過 Proxy 時才會產生,所以可以像以下這樣寫來取得使用者真實 IP。

<?php
if (empty($_SERVER['HTTP_X_FORWARDED_FOR']))
{
$myip = $_SERVER['REMOTE_ADDR'];
}
else
{
$myip = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
$myip = $myip[0];
}
?>

2009年9月29日 星期二

PHP 獲取 MySQL UTF-8 文字亂碼解決方法

最近寫網頁,
發覺用PHP獲取 MySQL UTF-8 文字時,
總是亂碼或問號,
最後在朋友的幫助下才解決

以下是解決方法 :

"連結MySQL PHP文件內"
<?php
$db = mysql_connect($dbAddr, $dbAcc, $dbPass)
or die('Could not connect: ' . mysql_error());
mysql_select_db($dbName, $db);
mysql_query("SET NAMES 'utf8'");
mysql_query("SET CHARACTER_SET_CLIENT=utf8");
mysql_query("SET CHARACTER_SET_RESULTS=utf8");
?>


"html / PHP 文件內"




"MySQL 內設定"
MySQL 文字編碼: UTF-8 Unicode (utf8)

Table內的Charset可以不同

"html / PHP 文件內有PHP String還要加入以下代碼"
<?php
header ('Content-type: text/html;
charset=big5');
?>


2009年9月7日 星期一

Migd2DX Game Engine

最近生出了一個念頭,
想由頭到尾自己去開發一個2D遊戲,
於是我決定由GAME ENGINE做起.

本來想用現成的,不過沒有一個合我心水,
想不太依賴DLL的,找到了,FPS又慢得很....
FPS快了,又太多版權信息走出來,
又沒有自定義檔案格式的功能,

太多不方便了,都是自己動手做最好

雖然開BLOGGER的日子是今天,
不過我都已經開發了1個月,
用了一個月時間開發了基本的RENDER功能,
加入了SOCKET同自定義的加密檔案格式(當然加密用了少計其他的SDK)

先來發表一下成果
Ver. 0.70
- 完成 M2DXAniObject
- FPS 定義為 60
- 修正 M2DXObject rotate錯誤
- 使用專用的font sprite作 M2DXFont 繪制
- 加入 M2DXSpriteZiper 工具,用於圖片檔案加密成m2s格式
- M2DXVector2, M2DXColor 歸納於 M2DXUnit
- 完成 M2DXVector2
- 完成 M2DXObject

Ver. 0.69
- 加入開發用 Log
- 修正 M2DXFont 字體範圍計算的公式錯誤

Ver. 0.68
- 完成 M2DXGame
- 完成 M2DXColor
- 完成 M2DXTexture
- 完成 M2DXFile
- 完成 M2DXSprFile
- 完成 M2DXFont
- 完成 M2DXSocket
- 完成 M2DXSocket2