quake3源码分析(五)

来源:互联网 发布:网络配线架的作用 编辑:程序博客网 时间:2024/05/30 23:43

quake3源码分析(五)

启动主菜单

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {

              Sys_CreateConsole();//创建一个用一输出的窗口

              Com_Init( sys_cmdline );//相关的初始化操作,加载动态库(opengl32.dll

              NET_Init();//网络初始化

              while( 1 ) { //主循环

              if ( g_wv.isMinimized || ( com_dedicated && com_dedicated->integer ) ) {

                     Sleep( 5 );

              }

              // make sure mouse and joystick are only called once a frame

              IN_Frame();

              // run the game

              Com_Frame();

       }

}

void Com_Frame( void )

{

       // we may want to spin here if things are going too fast

       if ( !com_dedicated->integer && com_maxfps->integer > 0 && !com_timedemo->integer ) {

              minMsec = 1000 / com_maxfps->integer;

       } else {

              minMsec = 1;

       }

       do {

              com_frameTime = Com_EventLoop();

              if ( lastTime > com_frameTime ) {

                     lastTime = com_frameTime;         // possible on first frame

              }

              msec = com_frameTime - lastTime;

       } while ( msec < minMsec );

       Cbuf_Execute ();

       …..

              SV_Frame( msec );//server side

       ……

              //client system

              Com_EventLoop();

              Cbuf_Execute ();

              CL_Frame( msec );

 

}

 

int Com_EventLoop( void )

{

while ( 1 )

{

              ev = Com_GetEvent();//从缓冲区中得到一个event,(缓冲区的event从键盘,mouse,控制台及网络中得到)

 

              // if no more events are available

              if ( ev.evType == SE_NONE ) {

                     // manually send packet events for the loopback channel

                     while ( NET_GetLoopPacket( NS_CLIENT, &evFrom, &buf ) ) {

                            CL_PacketEvent( evFrom, &buf );

                     }

                     while ( NET_GetLoopPacket( NS_SERVER, &evFrom, &buf ) ) {

                            // if the server just shut down, flush the events

                            if ( com_sv_running->integer ) {

                                   Com_RunAndTimeServerPacket( &evFrom, &buf );

                            }

                     }

                     return ev.evTime;

              }

              //根据event的类型进行处理

              switch ( ev.evType ) {

              default:

                // bk001129 - was ev.evTime

                     Com_Error( ERR_FATAL, "Com_EventLoop: bad event type %i", ev.evType );

                     break;

        case SE_NONE:

            break;

              case SE_KEY://键盘事件,一个键按下放开共分3event,一个SE_KEY按下,一个SE_CHAR,一个SE_KEY没按下

                     CL_KeyEvent( ev.evValue, ev.evValue2, ev.evTime );

                     break;

              case SE_CHAR:

                     CL_CharEvent( ev.evValue );

                     break;

              case SE_MOUSE:

                     CL_MouseEvent( ev.evValue, ev.evValue2, ev.evTime );

                     break;

              }

       }

}

 

void CL_KeyEvent (int key, qboolean down, unsigned time)

{

       //当第一次进行游戏,按下”ESC”键之后,会调下面这个函数

       VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_MAIN );vm.c文件)

}

int   QDECL VM_Call( vm_t *vm, int callnum, ... )

{

       //如果vm已经加载了DLL动态库,调用:vm.name=”ui”àvu_main.c(vmMain);

       //vm.name=”cgame”àcg_main.c(vmMain)

       r = vm->entryPoint( callnum,  args[0],  args[1],  args[2], args[3],

                            args[4],  args[5],  args[6], args[7],

                            args[8],  args[9], args[10], args[11],

                            args[12], args[13], args[14], args[15]);

}