平民程序 - linghuye's blog

天下风云出我辈,一入江湖岁月催。皇图霸业谈笑中,不胜人生一场醉。提剑跨骑挥鬼雨,白骨如山鸟惊飞。尘事如潮人如水,只笑江湖几人回。

随笔 - 221, 文章 - 0, 评论 - 680, 引用 - 0
数据加载中……

MyWarCraftStudio 0.88

1. A new m2 model renderer that can show most model skin texture set, add particle system effect, texture animation, npc skin.
2. Add two mpq edit functions in the pop menu by right clicking on the file tree item.
   Import File: Import a single file directly from local file system under the clicking tree node.
   Import Folder: Import all files in a directory from local file system under the clicking tree node.
3. Wow data path config is automaticlly set to where you open your mpq file now, no need to set it manually.

http://www.cnitblog.com/Files/linghuye/MyWarCraftStudio_0.88.rar

Please update,
http://linghuye.googlepages.com/MyWarCraftStudio_0.9.7z

posted @ 2006-07-26 12:57 linghuye 阅读(9579) | 评论 (16)编辑 收藏

我终于站在那辆杂货车上

Phyx.jpg
哈哈,哈哈,在物理引擎研究上总算有了突破,终于可以实用了,PhysX不愧是商业级的物理引擎啊.

我终于知道自己对物理引擎的研究钻到哪个死胡同了,完全没跟上商业主流.
Ageia PhysX收购了物理引擎设计商Novodex,物理加速卡已经诞生,Nvidia和ATI联合Havok物理引擎加入混战.
如同当初显卡的发展和混战,又有好戏看了,最终Havok引擎也会开放API的.
与显卡驱动程序一样,没有物理硬件,物理引擎可以运行在软件模拟下,PhysX Demo的效果cool毙了.

7月15日 -> 7月16日

posted @ 2006-07-16 23:33 linghuye 阅读(1545) | 评论 (3)编辑 收藏

WinRar和7zip 代码备份/程序发布语法备忘

CALL "E:\Program Files\7-zip\7z.exe" a MyWarCraftStudio @Backup.lst -xr@ExcludeFiles.lst
CALL "E:\Program Files\WinRAR\WinRAR.exe" a DmGameSDK @GameSDKFiles.lst -x@ExcludeFiles.lst

Backup.lst为文件列表文本文件
ExcludeFiles.lst为扩展名列表文本文件,Example:

*.log
*.obj
*.ilk
*.ncb
*.7z
*.rar
*.pch
*\Objs

http://www.cnitblog.com/Files/linghuye/PackShell.rar

create a .lst file as a text file with file/director pathname every line, then double click the .lst file in window shell, it will pack the files into a 7z package.

posted @ 2006-07-13 23:40 linghuye 阅读(876) | 评论 (0)编辑 收藏

不知所云

我偷懒没看球,德国队输了,我有责任,以后我就是铁杆德国球迷.

还是沉下心工作研究技术吧,命里有来终须有,命里无时莫强求,我累了.

posted @ 2006-07-05 11:02 linghuye 阅读(620) | 评论 (0)编辑 收藏

MYSQL 存储过程编写低级错误

1.出现PROCEDURE xxx can't return a result set in the given context when execute ...错误,mysql_real_connect连接时没有指定clientflag为CLIENT_MULTI_STATEMENTS!

2. You can create a prepared statement with the PREPARE statement, supplying the SQL text in a session variable.就是说不能是局部变量,或存储过程范围内的变量.

3.syntax sample for memo 

DELIMITER $$;

DROP PROCEDURE IF EXISTS `silvermoney`.`BalanceCashSavings`$$

CREATE PROCEDURE `BalanceCashSavings`(vinCashMoney BIGINT, vinAccountID INT, vinBnCode VARCHAR(
32 ), vinBnProcessor VARCHAR( 32 ), OUT vErrCode INT)
st_main : BEGIN
DECLARE varCurCashMoney BIGINT;
DECLARE varCurBankSaving BIGINT;
SET vErrCode 
=   0 ;
SELECT CashMoney, BankMoney INTO varCurCashMoney, varCurBankSaving FROM SilverAccount WHERE AccountID
= vinAccountID;
IF FOUND_ROWS() 
=   1  THEN
   SET vErrCode 
=   1 ;
   LEAVE st_main;
END IF;
START TRANSACTION;
IF vinCashMoney 
>   0  THEN
    IF varCurBankSaving 
<  vinCashMoney THEN
    SET vErrCode 
=   2 ;
        LEAVE st_main;
    END IF;
    
    UPDATE SilverAccount SET CashMoney
= CashMoney  +  vinCashMoney, BankMoney  =  BankMoney  -  vinCashMoney WHERE AccountID = vinAccountID;
    IF ROW_COUNT() 
!=   1  THEN
        SET vErrCode 
=   3 ;
        LEAVE st_main;
    END IF;
    
    BEGIN
    DECLARE EXIT HANDLER FOR SQLEXCEPTION SET vErrCode 
=   27 ;
    SET @vSQLInsertBn 
=   " INSERT Business_ "   +  CONCAT(CURDATE() + 0 +   "  VALUES(' "   +  vinBnCode  +   " ',  "   +  CONCAT(vinAccountID)  +   " "   +  CONCAT(vinCashMoney)  +   " , 0, ' "   +  CONCAT(CURDATE() + 0 +   " ', 5, ' "   +  vinBnProcessor  +   " ', '') " ;
    PREPARE dynSQL FROM @vSQLInsertBn;
    EXECUTE dynSQL;
    DEALLOCATE PREPARE dynSQL;
    END;     
ELSE
    IF varCurCashMoney 
<   - vinCashMoney THEN
    SET vErrCode 
=   5 ;
        LEAVE st_main;
    END IF;
    UPDATE SilverAccount SET CashMoney
= CashMoney + vinCashMoney, BankMoney = BankMoney - vinCashMoney WHERE AccountID = vinAccountID;
    IF ROW_COUNT() 
!=   1  THEN 
        SET vErrCode 
=   6 ;
        LEAVE st_main;
    END IF;
   
    BEGIN
    DECLARE EXIT HANDLER FOR SQLEXCEPTION SET vErrCode 
=   27 ;
    SET @vSQLInsertBn 
=   " INSERT Business_ "   +  CONCAT(CURDATE() + 0 +   "  VALUES(' "   +  vinBnCode  +   " ',  "   +  CONCAT(vinAccountID)  +   " "   +  CONCAT(vinCashMoney)  +   " , 0, ' "   +  CONCAT(CURDATE() + 0 +   " ', 5, ' "   +  vinBnProcessor  +   " ', '') " ;
    PREPARE dynSQL FROM @vSQLInsertBn;
    EXECUTE dynSQL;
    DEALLOCATE PREPARE dynSQL;
    END;
END IF;        
COMMIT;
END$$

DELIMITER ;$$

 

DELIMITER $$;

DROP PROCEDURE IF EXISTS `silvermoney`.`ChargeSilverCard`$$

CREATE PROCEDURE `ChargeSilverCard`(vinCardID VARCHAR(
32 ), vinPassword VARCHAR( 32 ), vinBnCode VARCHAR( 32 ), vinBnProcessor VARCHAR( 32 ), vinAccountID INT, OUT vErrCode INT)
st_main : BEGIN

DECLARE varCardMoney BIGINT;
DECLARE varOrgBnCode VARCHAR(
32 );
DECLARE varBnTableName VARCHAR(
32 );
DECLARE vSQLInsertBn VARCHAR(
256 );

SELECT Money, BusinessCode INTO varCardMoney, varOrgBnCode From SilverCard WHERE CardID
= vinCardID AND Password = vinPassword;
IF FOUND_ROWS() 
!=   1  THEN
   SET vErrCode 
=   1 ;
   LEAVE st_main;
END IF;
IF varOrgBnCode 
!=  NULL THEN
   SET vErrCode 
=   2 ;
   LEAVE st_main;
END IF;
START TRANSACTION;
          
UPDATE SilverCard SET BusinessCode
= vinBnCode WHERE CardID = vinCardID;
IF ROW_COUNT() 
!=   1  THEN
    SET vErrCode 
=   3 ;
    LEAVE st_main;
END IF;
UPDATE SilverAccount SET CashMoney
= CashMoney + varCardMoney WHERE AccountID = vinAccountID;
IF ROW_COUNT() 
!=   1  THEN
    SET vErrCode 
=   4 ;
    LEAVE st_main;
END IF;
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION SET vErrCode 
=   27 ;
SET @vSQLInsertBn 
=   " INSERT Business_ "   +  CONCAT(CURDATE() + 0 +   "  VALUES(' "   +  vinBnCode  +   " ',  "   +  CONCAT(vinAccountID)  +   " "   +  CONCAT(varCardMoney)  +   " , 0, ' "   +  CONCAT(CURDATE() + 0 +   " ', 6, ' "   +  vinBnProcessor  +   " ', ' "   +  vinCardID  +   " ') " ;
PREPARE dynSQL FROM @vSQLInsertBn;
EXECUTE dynSQL;
DEALLOCATE PREPARE dynSQL;
END;     
    
COMMIT;
END$$

DELIMITER ;$$

 

 

posted @ 2006-07-01 15:38 linghuye 阅读(2004) | 评论 (2)编辑 收藏

M$ SQL的问题

最近用M$ SQL的遇到些问题,总结一下.

1.使用ADO读出的BIGINT字段类型,形成的VARIANT是VT_DECIMAL类型,而非想象中的VT_I8.更要命的是VariantChangeType在Win2000下转换VT_DECIMAL->VT_I8或反之,都出错,该API返回错误的数据类型,而WinXP和Win2003下不会.结论是Win2000内核对VT_I8支持有误,当前SP4仍为解决该问题.Bae, Hyun-jik给出一个hack绕过该问题. Refer to:
http://groups.google.com/group/microsoft.public.data.oledb/browse_thread/thread/3ba6ff6e76186d95/c89a98d77a8fdb52?lnk=st&q=vt_decimal+to+vt_i8&rnum=1&hl=zh-CN#c89a98d77a8fdb52
http://groups.google.com/group/microsoft.public.win32.programmer.ole/browse_thread/thread/ee793c37192460d8/3f3ca1b412620ac6?lnk=st&q=vt_decimal+to+vt_i8&rnum=2&hl=zh-CN#3f3ca1b412620ac6

2.不能在SQL查询分析器下,选择文本的状态下,然后F5执行查询,执行的是选择文本.偶不知道,检查了4个小时的语法后发现的.

3.ADO的Command对象带参数存储过程调用方式真低能,一个一个Parameter对象地创建,设置,赋值,这样的方式写出的都是垃圾代码.
改用adCmdText方式直接进行SQL语法调用EXECUTE procname @varInput,却无法从ADO的Command对象中取得返回值,于是被逼使用SELECT ErrCode = 1记录集返回.这样,对于复杂的存储过程中间多次进行出错返回的,出现多个SELECT语句,此时ADO将返回的一个多数据集对象,其中只有一个为打开,其他均为关闭,(奇怪的逻辑),于是有如下丑陋的代码:
int ExecuteStoreProcedure(const char* szSQL)
{
 try
 { 
  _variant_t vRecords;
  _RecordsetPtr ptrRcs = m_ptrConnection->Execute(_bstr_t(szSQL), &vRecords, adOptionUnspecified);
  while(ptrRcs != NULL)
  { 
   if(ptrRcs->GetState() == adStateOpen)
   {
    return ptrRcs->GetFields()->GetItem("ErrCode")->GetValue();
   }
   ptrRcs = ptrRcs->NextRecordset(&vRecords);
  }
  return ERROR_UNKNOWN;
 }
 catch(_com_error& e)
 { 
  _bstr_t bstrErrMsg = e.Description();
  DUMP_COM_ERROR(e);
  return ERROR_UNKNOWN;
 }
 catch(...)
 {
  return ERROR_UNKNOWN;
 }
}

只是不知有没更简单的方法取回存储过程的return值,在使用直接SQL执行调用的方式下!
推荐大家使用MYSQL.

posted @ 2006-06-29 17:29 linghuye 阅读(2870) | 评论 (2)编辑 收藏

按段落读取RTF富文本格式文件内容

最近写游戏公告服务器,需要按分段落读取RTF格式文本文件内容到内存中,然后下发客户端.
网络上没找到类似功能的代码,费了些功夫研究了一下,感觉在Windows下写些自由度较大的功能都像是在做hack.

// 创建一个临时RichEdit控件
HMODULE hInstRich = ::LoadLibrary("RICHED20.DLL");
ATLASSERT(hInstRich 
!= NULL);

CRichEditCtrl ctrlRichEdit;
ctrlRichEdit.Create(NULL, NULL, NULL, WS_POPUP 
| ES_MULTILINE);

// 取得ITextDocument接口
IRichEditOle* pRichEditOle = ctrlRichEdit.GetOleInterface();
if(!pRichEditOle) return false;

ITextDocument
* pRichDoc = NULL;
pRichEditOle
->QueryInterface(__uuidof(ITextDocument), (LPVOID*)&pRichDoc);
SAFE_RELEASE(pRichEditOle);
if(!pRichDoc) return false;

// 打开RTF文件
CComVariant varFileName = szFileName;
HRESULT hr 
= pRichDoc->Open(&varFileName, tomReadOnly | tomRTF, 0);
if(FAILED(hr))
{
    SAFE_RELEASE(pRichDoc);
    
return false;
}


// 读取RTF文件
CIntArray arrParas;            
arrParas.push_back(
0);

// 分析文章每个段的位置
int lineCount = ctrlRichEdit.GetLineCount();
for(int i = 0; i < lineCount; i++)
{    
    
char szLineText[16= 0 };
    
int nLineBeginCharIndex = ctrlRichEdit.LineIndex(i);// 行首CharIndex
    int nLineLength = ctrlRichEdit.LineLength(nLineBeginCharIndex);
    
if(nLineLength == 0)  continue;
    
int nLineEndCharIndex = nLineBeginCharIndex + nLineLength;// 行末CharIndex
    
    ctrlRichEdit.GetTextRange(nLineEndCharIndex, nLineEndCharIndex 
+ 1, szLineText);
    
    
if(szLineText[0== '\r'
    
{    
        arrParas.push_back(nLineEndCharIndex 
+ 1);
    }

}


// 读取每个段的内容到内存
FORMATETC fmtEtc = { RegisterClipboardFormat(CF_RTF), NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
for(uint32 i = 0; i < arrParas.size() - 1; i++)
{    
    ITextRange
* pTextRange = NULL;
    
if(SUCCEEDED(pRichDoc->Range(arrParas[i], arrParas[i+1], &pTextRange))  &&  pTextRange != NULL)
    
{    
        CComVariant varDataObject;
        IDataObject
* pDataObject = NULL;
        varDataObject.vt 
= VT_UNKNOWN | VT_BYREF;
        varDataObject.ppunkVal 
= (IUnknown**)&pDataObject;
        
        hr 
= pTextRange->Copy(&varDataObject);
        
if(SUCCEEDED(hr)  &&  pDataObject != NULL)
        
{    
            STGMEDIUM stgMedium 
= { TYMED_HGLOBAL, 0 };
            hr 
= pDataObject->GetData(&fmtEtc, &stgMedium);
            
            
if(SUCCEEDED(hr)  &&  stgMedium.hGlobal != NULL)
            
{    
                DWORD nLen 
= ::GlobalSize(stgMedium.hGlobal);
                
                
void* pData = (void*)::GlobalLock(stgMedium.hGlobal);
                
                CMemChunkBase chunk(nLen);
                chunk.WriteData(pData, nLen);
                m_arrSysMsgs.push_back(chunk);
                
                ::GlobalUnlock(pData);
            }

        }

        
        SAFE_RELEASE(pDataObject);
        SAFE_RELEASE(pTextRange);
    }

}


SAFE_RELEASE(pRichDoc);
ctrlRichEdit.DestroyWindow();
FreeLibrary(hInstRich);
hInstRich 
= NULL;

posted @ 2006-06-29 11:14 linghuye 阅读(1636) | 评论 (0)编辑 收藏

用信号量控制程序的进程个数

互斥量可以实现程序在系统内唯一进程,所以,同理,信号量可以用来控制一个程序的进程的个数,获知一个程序当前被运行了几个实例进程.
LONG nPreCount = 0; // 程序当前运行了几个进程实例
HANDLE hSemaphore = ::CreateSemaphore(NULL, 1, 16, "__DM_EASY_TEST_COUNT__");
ReleaseSemaphore(hSemaphore, 1, &nPreCount);

测试网络游戏时,可以用它来生成按程序打开顺序的用户帐号,如测试帐号111,222,333
m_idLocalAccount = nPreCount * 100 + nPreCount * 10 + nPreCount;

posted @ 2006-06-28 21:22 linghuye 阅读(685) | 评论 (0)编辑 收藏

MyWarCraft_0.8

最近没啥好写的,把半成品挖出来充充数.
一直不能解决物理引擎的问题,一切都停滞不前.

http://www.cnitblog.com/linghuye/archive/2005/08/13/1861.aspx
http://www.cnitblog.com/Files/linghuye/MyWarCraftStudio_0.88.rar

Please update,
http://linghuye.googlepages.com/MyWarCraftStudio_0.9.7z

posted @ 2006-06-09 16:12 linghuye 阅读(4674) | 评论 (13)编辑 收藏

抢占IE状态栏

Google Notebook那个在IE状态栏上加的图标很有意思,我研究了一下发现被蒙了,那个按钮根本不是在状态栏上,而是个完全浮动的窗口.于是我学着作了一个.

Source Code:
http://www.cnitblog.com/Files/linghuye/MyNoteBook.rar

使用Release目录里的RegMyNoteBook.bat注册

posted @ 2006-05-25 13:39 linghuye 阅读(531) | 评论 (1)编辑 收藏

仅列出标题
共22页: First 6 7 8 9 10 11 12 13 14 Last