最近研究Directx9.0做的游戲,發覺就是標準的前后臺,呵呵。
//-----------------------------------------------------------------------------
//Name:WinMain()
//Desc:Theapplication'sentrypoint
//-----------------------------------------------------------------------------
INTWINAPIWinMain(HINSTANCEhInst,HINSTANCE,LPSTR,INT)
{
//Registerthewindowclass
WNDCLASSEXwc={sizeof(WNDCLASSEX),CS_CLASSDC,MsgProc,0L,0L,
GetModuleHandle(NULL),NULL,NULL,NULL,NULL,
"D3DTutorial",NULL};
RegisterClassEx(&wc);
//Createtheapplication'swindow
HWNDhWnd=CreateWindow("D3DTutorial","D3DTutorial02:Vertices",
WS_OVERLAPPEDWINDOW,100,100,300,300,
GetDesktopWindow(),NULL,wc.hInstance,NULL);
//InitializeDirect3D
if(SUCCEEDED(InitD3D(hWnd)))
{
//Createthevertexbuffer
if(SUCCEEDED(InitVB()))
{
//Showthewindow
ShowWindow(hWnd,SW_SHOWDEFAULT);
UpdateWindow(hWnd);
//Enterthemessageloop
MSGmsg;
ZeroMemory(&msg,sizeof(msg));
while(msg.message!=WM_QUIT)//此處循環,包含WINDOW系統使用的消息處理和游戲的主循環
{
if(PeekMessage(&msg,NULL,0U,0U,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
Render();//此處就是游戲的主循環處,單片機中的main主循環
}
}
}
UnregisterClass("D3DTutorial",wc.hInstance);
return0;
}
網友評論:俺發覺相似點真的多。
游戲和前后臺的原理幾乎一樣。
WINDOW的操作方式,又和嵌入OS一樣,比如播放音樂,還可以打開
計算器,各干各的事情。
照樣不感冒嵌入OS,做產品就象做游戲,單一的環境。
網友評論:TheGetMessagefunctionretrievesamessagefromthecallingthread'smessagequeue.Thefunctiondispatchesincomingsentmessagesuntilapostedmessageisavailableforretrieval.
UnlikeGetMessage,thePeekMessagefunctiondoesnotwaitforamessagetobepostedbeforereturning.
單核是100%,雙核是50%,四合就會是25%
Label1->Caption=i++;沒有必要,因為人眼以及屏幕刷新的速度有限,而且不出讓cpu,label1也不會更新。
網友評論:佩服所長技術,更佩服所長把自己經驗拿出來分享的精神,頂。。。。。!
網友評論:而且更新的飛快,轉眼就成百上千了。
俺是為讓WINDOW一直忙著,沒別的。
俺猜測:開一線程,WINDOW就開始使用另外一個核。
一個核管主程序,其它管線程。
亂猜。
網友評論:讓系統可以處理wm_paint事件.
在循環中加入一個Sleep(1)---出讓cpu,可以把cpu占用率降下來.
網友評論:TranslateMessage(&msg);
DispatchMessage(&msg);
網友評論:真的不錯
學習中
網友評論:給你一個封裝好的class,轉到c++builder下很容易
#pragmaonce
#include"Delegate.h"
classCExThread
{
CWinThread*m_pThread;
BOOLm_bThreadAlive;
BOOLm_bStopThread;
staticUINTStart(LPVOIDpParam);
public:
CDelegatem_Delegate;
CExThread(void);
~CExThread(void);
boolRun();
voidStop();
};
#include"stdafx.h"
#include"exthread.h"
CExThread::CExThread(void)
{
m_pThread=NULL;
m_bThreadAlive=FALSE;
m_bStopThread=FALSE;
}
CExThread::~CExThread(void)
{
Stop();
}
boolCExThread::Run()
{
m_pThread=::AfxBeginThread(Start,this);
m_bThreadAlive=TRUE;
returnm_pThread!=NULL;
}
voidCExThread::Stop()
{
if(m_pThread==NULL)return;
do{
m_bStopThread=TRUE;
}
while(m_bThreadAlive);
}
UINTCExThread::Start(LPVOIDpParam)
{
CExThread*me=(CExThread*)pParam;
me->m_bThreadAlive=TRUE;
me->m_Delegate.Invoke(NULL,0);
me->m_bThreadAlive=FALSE;
return0;
}
DELEGATE.H
#if!defined(_Class_Delegate_)
#define_Class_Delegate_
#pragmaonce
/*************************************************************************************************
Warning:UnsafeCode!!!
*************************************************************************************************/
#defineHANDLER(function)reinterpret_cast<PTR_CALLBACK>(function)
#defineSetEventHandler(instance,function)_SetEventHandler((instance),HANDLER(function))
classCDelegate;
typedefvoid(CDelegate::*PTR_CALLBACK)(void*sender,DWORDpara);
classCDelegate
{
PTR_CALLBACKm_pCallBack;
CDelegate*m_pInstance;
public:
CDelegate()
{
m_pCallBack=NULL;
m_pInstance=NULL;
}
void_SetEventHandler(void*pInstance,PTR_CALLBACKpCallBack)
{
m_pInstance=(CDelegate*)pInstance;
m_pCallBack=pCallBack;
}
voidInvoke(void*sender,DWORDpara)
{
if(m_pInstance!=NULL&&m_pCallBack!=NULL)
(m_pInstance->*m_pCallBack)(sender,para);
}
};
#endif
網友評論:就看你在哪一層,有時你能控制這個循環,有時則不能。
網友評論:LS的明白了嗎?
網友評論:用TTIMER做的真的不行,用回調函數方式做,發現TTIMER不是直接調用,還是通過消息才去回調的,20MS誤差太大,1分鐘差個十幾秒。用多媒體定時器很準,就是消耗資源大:多媒體定時器==一個線程。
沒辦法,就用多媒體定時器了。
內存管理也搞定,直接先用8M的數組固定,再內部在這個數組中分配。
網友評論:直接替換驅動就可以了。
串口:用PCOMM封裝成隊列驅動方式,直接替換嵌入裸奔的串口驅動的隊列驅動
定時器:系統20MS,弱實時處理5MS,用多媒體定時器搞定。
LCD畫波形的速度控制,開線程查詢精密定時器(因為多媒體定時器只到MS,速度控制要到0.1ms),這樣可以搞定,相當0.1ms的定時器器。
LCD:用BITMAP,BCB里面可以直接對內存操作,可以按FrameBuffer處理,只要窗口刷新函數將上下顛倒下處理(BCB中圖形對FrameBuffer是上下顛倒的)。
NANDFLASH存儲,有想法,還有待實踐。
其它,更簡單,只要上面幾個搞定,嵌入裸奔的程序就移植到WINDOW上了。
單片機程序,寫到能移植到WINDOW的程度的份上,俺認為應該作為一個設計標準考核,高手低手之分。
網友評論:可以認為WINDOW的線程就是中斷,MCU
開關中斷,相當線程的同步,用臨界方式可以保證低層函數不重入。
又一心得
網友評論:然后打開機箱,拔下網卡,把EPROM插到網卡上的ROM插座中,把網卡重新插回主板,然后開機。或者把主板上的BIOS芯片拔下來,把自己的ROM換上。干嘛要啟動個WINDOWS?
網友評論:感覺就像一個倔強的鄉鎮企業企業家接管了聯想。
網友評論:通過研究,進一步確定基于前后臺的嵌入裸奔做控制產品比嵌入OS的理論先進性,從根子上找到WINDOW這個大樹做依靠。
通過研究,MCU上做的、WINDOW做的,都是一套體系的程序(除驅動不同),便于維護和管理。
通過研究,發現游戲設計秘密,改天MMCU混不下去,改行做游戲設計混口飯吃。
展望七十歲,準備設計MCU的虛擬機。
網友評論:半天時間。
網友評論:把石頭當寶貝了
網友評論:估計你眼里沒幾個能成寶貝,高手。
網友評論:樓主不在MCU的福地里舒坦,跑到WINDOWS這片大鹽堿地來做甚?玩歸玩,可別亂了陣腳。
網友評論:無聊貼
網友評論:你也完全可以移植到嵌入式os上
何必呢~~~~~~~~~
何苦呢~~~~~~~~~
網友評論:觀察串口打開、關閉、發送、接收,可以使用串口偵聽軟件,比如:http://www.sudt.com的SerialTrace,這個不錯。
完全按照裸奔方式設計的仿MCU的WINDOW程序,以后可能只要會MCU就可設計WINDOW程序,可能......
有關MCU部分,RainLib_Base.lib,RainLib_Unsiversal.lib,RainLib_Driver.lib被封裝好,按MCU玩WINDOW游戲程序,很簡單了。
代碼:main.cpp
//---------------------------------------------------------------------------
#include<vcl.h>
#pragmahdrstop
#include"Main.h"
#include"..\WinTools\RainLib_WinTools.h"
#include"..\Base\RainLib_Base.h"
#include"..\Unsiversal\RainLib_Unsiversal.h"
#include"..\Driver\RainLib_Driver.h"
//---------------------------------------------------------------------------
#pragmapackage(smart_init)
#pragmaresource"*.dfm"
TForm1*Form1;
structCommunicateQueue*psCommunicateQueue_Uart8;//串口1
//---------------------------------------------------------------------------
__fastcallTForm1::TForm1(TComponent*Owner)
:TForm(Owner)
{
}
//---------------------------------------------------------------------------
//main.c必須提供
void_stdcallCallBack_5msInterrupt(void)
{
}
//main.c必須提供
void_stdcallCallBack_20msInterrupt(void)
{
}
//---------------------------------------------------------------------------
//窗口初始化
//---------------------------------------------------------------------------
void__fastcallTForm1::MainFormInit(void)
{
this->ClientWidth=Ini_Read("LCD","ScreenWidth",640);
this->ClientHeight=Ini_Read("LCD","ScreenHeight",480);
}
//---------------------------------------------------------------------------
//主初始化
//---------------------------------------------------------------------------
void__fastcallTForm1::MainInit(void)
{
WinToolsLib_Init("RainLib.ini");//INI文件名
this->MainFormInit();
BaseLib_Init(Ini_Read("MSG","BufferMax",5000));//消息隊列大小
UnsiversalLib_Init(Ini_Read("PACKAGE","PackageMax",2));//使用包解析的任務數
DriverLib_Init(this->ClientWidth,this->ClientHeight);
psCommunicateQueue_Uart8=CommunicateQueue_Register(200,200,NULL);
if(Uart8_Setup(1,psCommunicateQueue_Uart8,B38400,BIT_8|STOP_1|P_NONE)==false)
{
Application->MessageBoxA("打開串口錯誤","程序中斷退出!",MB_OK);
Application->Terminate();
}
//lcd
U8*p=DrvLcd_FramePagePoint(1);
for(inti=0;i<this->ClientHeight*2;i++)
{
for(intj=0;j<this->ClientWidth;j++)
{
*p++=i;
}
}
//開始運行程序
Msg_RunInit();
this->Show();
}
//---------------------------------------------------------------------------
//析構
//---------------------------------------------------------------------------
void__fastcallTForm1::MainDestory(void)
{
DriverLib_Destory();
UnsiversalLib_Destory();
BaseLib_Destory();
WinToolsLib_Destory();
}
//---------------------------------------------------------------------------
//主循環
//---------------------------------------------------------------------------
void__fastcallTForm1::MainLoop(void)
{
staticboolbTestLcdMove=false;
staticU8mCounter=0;
staticintmy=0;
BaseLib_MainLoop();
UnsiversalLib_MainLoop();
DriverLib_MainLoop();
WinToolsLib_MainLoop();
if(sSysTimer.bSysTouch)
{
if(++mCounter>=2)
{
//20ms*2時間進入
mCounter=0;
if(bTestLcdMove)
{
my--;
if(my==0)
{
bTestLcdMove=false;
}
}
else{
my++;
if(my==(this->ClientHeight-1))
{
bTestLcdMove=true;
}
}
DrvLcd_FrameOffset(my);
DrvLcd_RefreshToForm(this->Canvas,Rect(0,0,this->ClientWidth,this->ClientHeight));
//向串口發送my位置
CommunicateQueue_Push(psCommunicateQueue_Uart8,(U8)my);
CommunicateQueue_Push(psCommunicateQueue_Uart8,(U8)(my/256));
}
}
}
RainLibMain.cpp:WINDOW調用
//---------------------------------------------------------------------------
#include<vcl.h>
#include"Main.h"
#pragmahdrstop
//---------------------------------------------------------------------------
USEFORM("Main.cpp",Form1);
//---------------------------------------------------------------------------
WINAPIWinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
try
{
Application->Initialize();
Application->CreateForm(__classid(TForm1),&Form1);
Form1->MainInit();//主初始化
MSGmsg;
ZeroMemory(&msg,sizeof(msg));
while(msg.message!=WM_QUIT)
{
if(PeekMessage(&msg,NULL,0U,0U,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
Form1->MainLoop();//主循環
}
}
Form1->MainDestory();
}
catch(Exception&exception)
{
Application->ShowException(&exception);
}
catch(...)
{
try
{
throwException("");
}
catch(Exception&exception)
{
Application->ShowException(&exception);
}
}
return0;
}
//---------------------------------------------------------------------------
網友評論:總空間:10240KB
已使用:10610KB
剩余:-370KB
網友評論:歡迎加入單片機交流群13883121
讓我們在交流中成長吧`````````長期聘請高手
網友評論:實時內核自己作,其他的功能調用windows的。
個人感覺所長這種做法不可取。
呵呵
網友評論:建議所長看看候杰的《深入淺出MFC》,李維的《INSIDEVCL》。
多線程的建議候杰的翻譯的一本,名字記不清楚了。
肯定有收獲。
所言不妥之處,敬請諒解
網友評論:還深入淺出,俺都深入深出。什么人都有,比如LS的,連俺在做什么都沒搞明白亂發言。
網友評論:所長要干嗎?
要做說相聲里的最好的縣長?
還是要做縣長里的最好的說相聲的?
網友評論:研究太拔高了吧?
網友評論:MCU、WINDOW設計,可以做到極其相似地步,俺要證明這一點。
網友評論:嵌入裸奔比嵌入OS更適合移植:嵌入OS移植到WINDOW上,可能性太小了。
網友評論:我也可以提供一些思路,供大家參考。正好這段時間有空。
網友評論:有什么意義?
網友評論:真有時間啊!
網友評論:下列是利用WINDOW資源實現MCU功能:
串口pcomm實現MCU的串口功能
線程實現MCU精密定時器、中斷
窗口實現LCD顯示
BITMAP實現LCD的FrameBuffer驅動方式
多媒體定時器實現低等級定時器中斷
RTCRTC
其它就是MCU功能,包括程序框架,在WINDOW上運行:
裸奔GUI
消息管理
庫函數
串口功能
裸奔數據庫(數據管理)
NANDFLASH存儲
EEPROM存儲
以后可以增加IO功能,使用并口。大家測試按鍵或做什么簡單控制,直接用。
可以請圈圈做個USB模擬功能,接AD、DC什么的。
俺的口號:做到會MCU,就會WINDOW的控制產品設計。
網友評論:用USB口擴展出一個總線或者幾個IO不難。軟核跑在PC上,外面有幾個IO,那不就是有點象
硬件仿真器嘛,不同的地方在于CPU是軟的...
網友評論:很值得一試。
主要是現在有裸奔程序要移植到WINDOW,所以在干這種大家認為不值得干的事情,呵呵。
通過這件不值得,不劃算的移植,可以驗證嵌入裸奔架構的科學性和完整性,同時也發現一些缺陷。
網友評論:現在看不懂,占個位置先。希望有一天能讀懂。
網友評論:支持所長裸奔,
我也想移植裸奔的GUI到windows上,
所長有啥好的思路么?
網友評論:原來做個兩份,一個在mega128上跑480*234的TFT顯示,一個是S3C2410上跑800*600,1024*768,兩者結構相同,細節不同,俺要整理一下。
網友評論:建立通用的處理程序在那兒能找到啊
網友評論:就是看不太動