// MFC Gos.cpp : Defines the class behaviors for the application. // // Note: // Unresolved Problems: // Imagehlp.dll Not Found on Load from Double Click // Wire only works on Scenes #include "stdafx.h" #include "MFC Gos.h" #include "MainFrm.h" #include "MFC GosDoc.h" #include "MFC GosView.h" #include HGOSHEAP client; extern DWORD _stdcall RunGameOSLogic(); #define DEBUGPOINT(x) MessageBox(NULL,x,"Test Point",MB_OK) #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "LightListDlg.h" extern DWORD gCurrentHeapStackLevel; BumpAnime bumpAnime; int animeCounter = 0; // // Global variables // const char* Command_Line=NULL; int UpdateLevel=0; ElementRenderer::GroupElement *Scene=NULL; ElementRenderer::Element *ErfElement=NULL; ElementRenderer::CameraElement *Camera=NULL; ElementRenderer::StateChange *LightState=NULL; CLightListDlg *LightDlg; Stuff::Point3D Camera_Pivot(Stuff::Point3D::Identity); Stuff::YawPitchRange Camera_Direction(0.0f, 0.0f, -10.0f); Stuff::Vector2DOf Camera_Shift(0.0f, 0.0f); //Stuff::Point3D Camera_Loc(0.0f,100.0f,-100.0f), Stuff::Point3D Camera_LookAt(0.0f,0.0f,0.0f); //Bump Map Test ElementRenderer::StateChange *Camera_State=NULL; Stuff::RGBAColor fogColor(0.3f, 0.3f, 0.3f, 1.0f); bool Window3DOpen=false; bool drawPointsYes = false; bool drawNormalsYes = false; MidLevelRenderer::DrawEffectInformation *drawEffectInfo[2]; unsigned Point_Count=MidLevelRenderer::Limits::Max_Number_Vertices_Per_Mesh; Stuff::RGBAColor Color_Data[2][2*MidLevelRenderer::Limits::Max_Number_Vertices_Per_Mesh]; Stuff::MString *erf_texture_path,*erf_effects_path; CList m_pErf_Name_List; #undef SHADOW_TEST #ifdef SHADOW_TEST MidLevelRenderer::MLRTexture *shadowTexture; MidLevelRenderer::MLRShape *shadowShape; MidLevelRenderer::DrawShapeInformation drawShapeInfo; Stuff::LinearMatrix4D shadowMatrix; extern void _stdcall End3DScene(); #endif #define APPNAME "3dViewTest" extern DWORD _stdcall RunGameOSLogic(); extern bool DebuggerActive; ///////////////////////////////////////////////////////////////////////////// // CMFCGosApp BEGIN_MESSAGE_MAP(CMFCGosApp, CWinApp) //{{AFX_MSG_MAP(CMFCGosApp) ON_COMMAND(ID_APP_ABOUT, OnAppAbout) ON_COMMAND(ID_OPTIONS_TEXTUREPATH, OnOptionsTexturepath) ON_COMMAND(ID_VIEW_3DVIEWWINDOW, OnView3dviewwindow) ON_UPDATE_COMMAND_UI(ID_VIEW_3DVIEWWINDOW, OnUpdateView3dviewwindow) ON_COMMAND(ID_VIEW_UPDATEONIDLE, OnViewUpdateonidle) ON_UPDATE_COMMAND_UI(ID_VIEW_UPDATEONIDLE, OnUpdateViewUpdateonidle) ON_COMMAND(ID_WINDOWS_LIGHTLIST, OnWindowsLightlist) ON_UPDATE_COMMAND_UI(ID_WINDOWS_LIGHTLIST, OnUpdateWindowsLightlist) //}}AFX_MSG_MAP // Standard file based document commands ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew) ON_COMMAND(ID_FILE_OPEN,OnFileOpen) ON_COMMAND(ID_VIEW_EXPANDALL, OnExpandAll) ON_COMMAND(ID_VIEW_COLLAPSEALL, OnCollapseAll) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CMFCGosApp construction CMFCGosApp::CMFCGosApp() { GOSActive=false; DrawOnIdle=true; m_pFileSet_List.RemoveAll(); m_phashErfNameMapping = NULL; } ///////////////////////////////////////////////////////////////////////////// // The one and only CMFCGosApp object CMFCGosApp theApp; ///////////////////////////////////////////////////////////////////////////// // CMFCGosApp initialization BOOL CMFCGosApp::InitInstance() { AfxEnableControlContainer(); // Standard initialization #ifdef _AFXDLL Enable3dControls(); // Call this when using MFC in a shared DLL #else Enable3dControlsStatic(); // Call this when linking to MFC statically #endif // Change the registry key under which our settings are stored. // jcem - SetRegistryKey(_T("Local AppWizard-Generated Applications")); LoadStdProfileSettings(); // Load standard INI file options (including MRU) // Register document templates CString mutexstr; mutexstr.LoadString(AFX_IDS_APP_TITLE); CreateMutex(NULL,TRUE,mutexstr); if(ERROR_ALREADY_EXISTS==GetLastError()) { MessageBox(NULL,"Another Instance of this Application is Currently Running","Error...",MB_OK); exit(1); } CSingleDocTemplate* pDocTemplate; pDocTemplate = new CSingleDocTemplate( IDR_MAINFRAME, RUNTIME_CLASS(CMFCGosDoc), RUNTIME_CLASS(CMainFrame), // main SDI frame window RUNTIME_CLASS(CMFCGosView)); AddDocTemplate(pDocTemplate); // Parse command line for standard shell commands, DDE, file open CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo); // Dispatch commands specified on the command line if (!ProcessShellCommandNoLoad(cmdInfo)) return FALSE; m_pMainWnd->ShowWindow(SW_SHOW); m_pMainWnd->UpdateWindow(); Window3D = new ViewWnd3D; Window3D->Create(NULL, "3D View Window", WS_OVERLAPPED|WS_CAPTION, //|WS_MINIMIZEBOX|WS_SYSMENU, Window3D->rectDefault, // m_pMainWnd, //This Will make The render Window Stay ontop of the main window NULL, MAKEINTRESOURCE(IDR_RENDERMENU), NULL); CRect rct; rct.top=rct.left=0; rct.right=640; rct.bottom=480+18; Window3D->ShowWindow(SW_SHOW); Window3D->CalcWindowRect(&rct,CWnd::adjustOutside); Window3D->SetWindowPos(NULL,rct.left,rct.top,rct.Width(),rct.Height(),SWP_SHOWWINDOW|SWP_NOOWNERZORDER|SWP_NOMOVE); Window3D->SetIcon(LoadIcon(IDI_ICON3D),TRUE); Command_Line = m_lpCmdLine; InitGameOS( m_hInstance , Window3D->m_hWnd, m_lpCmdLine ); // client=gos_CreateMemoryHeap("PixelProHeap"); // gos_PushCurrentHeap(client); theApp.Window3D->GOSActive=true; theApp.Window3D->GOSInit=true; theApp.Window3D->Fix3DView(); DrawScreen(); GOSActive=true; LightDlg=new CLightListDlg; LightDlg->Create( CLightListDlg::IDD,m_pMainWnd); LightDlg->ShowWindow(SW_HIDE); // has to be initialized in InitializeGameEngine() // m_pstrErfNameMapping = new CMap; // //----------------------- // Parse the command line //----------------------- // const char* space = strchr(Command_Line, ' '); if (!space || space == Command_Line) { // Abort_Program("Need both ERF file and texture path"); // GetTexturePath(); } else { MString * tmp = new MString(Command_Line); m_pErf_Name_List.AddHead(tmp); // ((LPCSTR)(erf_name))[space - Command_Line] = '\0'; // erf_name.SetAt(space - Command_Line],'\0'); static_cast(*(m_pErf_Name_List.GetHead()))[space - Command_Line] = '\0'; (*(theApp.m_phashErfNameMapping)).DeletePlugs(); (*(theApp.m_phashErfNameMapping)).AddValue(new Stuff::PlugOf (tmp), 0); // this is only a copy... while (*space == ' ') ++space; if (!*space) { STOP(( "Need both ERF file and texture path" )); } else { *erf_texture_path = space; } } // CG: The following block was inserted by the 'Document Registration' component. { // Enable DDE Execute open EnableShellOpen(); RegisterShellFileTypes(TRUE); m_pMainWnd->DragAcceptFiles(); } if (!ProcessShellCommandOnlyLoad(cmdInfo)) return FALSE; return TRUE; } ///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) // No message handlers //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP END_MESSAGE_MAP() // App command to run the dialog void CMFCGosApp::OnAppAbout() { CAboutDlg aboutDlg; aboutDlg.DoModal(); } ///////////////////////////////////////////////////////////////////////////// // CMFCGosApp message handlers BOOL CMFCGosApp::OnIdle(LONG lCount) { DWORD level = gCurrentHeapStackLevel; if(DrawOnIdle || DebuggerActive) { DrawScreen(); Verify(level == gCurrentHeapStackLevel); return 1; } else { Verify(level == gCurrentHeapStackLevel); return CWinApp::OnIdle(lCount); } } int CMFCGosApp::ExitInstance() { ExitGameOS(); if(Window3D) { //delete Window3D; Window3D=NULL; } return CWinApp::ExitInstance(); } void _stdcall InitializeGameEngine() { // //--------------------- // Initialize libraries //--------------------- // Stuff::InitializeClasses(); MidLevelRenderer::InitializeClasses(NULL, 8192, 1024*64); gosFX::InitializeClasses(); ElementRenderer::InitializeClasses(); if (!theApp.m_phashErfNameMapping) { // BYTE * memory = new BYTE[sizeof(CMap)]; //theApp.m_pstrErfNameMapping = new(memory) (CMap); theApp.m_phashErfNameMapping = new Stuff::HashOf*,DWORD>(67, NULL, true); } while (m_pErf_Name_List.GetCount() && m_pErf_Name_List.GetHead()) {Unregister_Object(m_pErf_Name_List.GetHead()); delete m_pErf_Name_List.GetHead(); m_pErf_Name_List.RemoveHead();} (*(theApp.m_phashErfNameMapping)).DeletePlugs(); m_pErf_Name_List.AddHead(new Stuff::MString); Register_Object(m_pErf_Name_List.GetHead()); (*(theApp.m_phashErfNameMapping)).AddValue(new Stuff::PlugOf (m_pErf_Name_List.GetHead()), 0); erf_texture_path = new Stuff::MString; Register_Object(erf_texture_path); erf_effects_path = new Stuff::MString; Register_Object(erf_effects_path); // //--------------------- // Build the scene root //--------------------- // theApp.GetTexturePath(); theApp.GetEffectsPath(); Scene = new ElementRenderer::GroupElement; Register_Object(Scene); Scene->SetRootMode(); Scene->LockBounds(); LightState = new ElementRenderer::StateChange; Register_Object(LightState); for(int li=0;lim_lights[li]=NULL; Scene->AdoptStateChange(LightState); // //------------------------ // Set up the texture pool //------------------------ // if(erf_texture_path->GetLength()) { gos_PushCurrentHeap(MidLevelRenderer::TexturePoolHeap); MidLevelRenderer::TGAFilePool *pool = new MidLevelRenderer::TGAFilePool(*erf_texture_path, "textures.hint"); Register_Object(pool); MidLevelRenderer::MLRTexturePool::Instance = new MidLevelRenderer::MLRTexturePool(pool); Check_Object(MidLevelRenderer::MLRTexturePool::Instance); Register_Object(MidLevelRenderer::MLRTexturePool::Instance); gos_PopCurrentHeap(); #if 0 Stuff::MString effects_name = *erf_texture_path; int content_root_length = effects_name.GetLength() - 9; Verify(!_stricmp(&((char*)effects_name)[content_root_length], "Textures\\")); ((char*)effects_name)[content_root_length] = '\0'; effects_name.SetLength(content_root_length); effects_name += "Effects\\mw.effects"; Stuff::FileStream *stream = Stuff::FileStream::MakeFileStream(effects_name); Register_Object(stream); gosFX::EffectLibrary::Instance = new gosFX::EffectLibrary; Register_Object(gosFX::EffectLibrary::Instance); gosFX::EffectLibrary::Instance->Load(stream); Unregister_Object(stream); delete stream; #endif } else { // fatal warning } // //---------------------------------------------- // Load the .ERF file and attach it to the scene //---------------------------------------------- // //if(erf_name->GetLength()) /* if (erf_name) { theApp.m_perf_file = new Stuff::FileStream(*erf_name); ErfElement = ElementRenderer::Element::Create( theApp.m_perf_file, ElementRenderer::ReadERFVersion(theApp.m_perf_file) ); Scene->AttachChild(ErfElement); }*/ //--------------- // Build a camera //--------------- // gos_PushCurrentHeap(ElementRenderer::g_Heap); Camera_State = new ElementRenderer::StateChange(); Register_Object(Camera_State); Camera_State->EnableBackfaceCulling(); Camera_State->EnableDithering(); Camera_State->EnablePerspectiveCorrection(); Camera_State->EnableZBufferWrite(); Camera_State->EnableZBufferCompare(); Camera_State->SetFogColor(fogColor); Camera_State->SetFogMode(ElementRenderer::StateChange::DisableFogMode); Camera = new ElementRenderer::CameraElement(Camera_State); Register_Object(Camera); Scene->AttachChild(Camera); Camera->SetPerspective(1.0f, 1000.0f, Stuff::Pi_Over_3); Camera->SetViewport(1.0f, 1.0f, 0.0f, 0.0f); Camera->SetScene(Scene); Stuff::LinearMatrix4D origin; origin.BuildRotation( Stuff::EulerAngles(Camera_Direction.pitch, Camera_Direction.yaw, 0.0f) ); origin.BuildTranslation(Stuff::Point3D(Camera_Direction)); Camera->SetLocalToParent(origin); CString strWindowTitle; strWindowTitle.Format("%s = %f", "Camera Distance", Camera_Direction.range); theApp.Window3D->SetWindowText((LPCSTR)strWindowTitle); gos_PopCurrentHeap(); // Camera->SetFogColor(fogColor); #if 0 //Make a Point Cloud drawEffectInfo = new MidLevelRenderer::DrawEffectInformation; Register_Pointer(drawEffectInfo); drawEffectInfo->effect = new MidLevelRenderer::MLRPointCloud(Point_Count, 4); Register_Object(drawEffectInfo->effect); drawEffectInfo->clippingFlags.SetClippingState(0x3f); drawEffectInfo->effectToWorld = NULL; drawEffectInfo->effect->TurnAllOn(); drawEffectInfo->state.SetFogMode(MidLevelRenderer::MLRState::DisableFogMode); drawEffectInfo->state.SetZBufferWriteOff(); drawEffectInfo->state.SetZBufferCompareOff(); unsigned i; for (i=0; ieffect = new MidLevelRenderer::MLRPointCloud(Point_Count, 4); Register_Object(drawEffectInfo[0]->effect); gos_PopCurrentHeap(); drawEffectInfo[0]->clippingFlags.SetClippingState(0x3f); drawEffectInfo[0]->effectToWorld = NULL; drawEffectInfo[0]->effect->TurnAllOn(); // drawEffectInfo[0]->state.SetFogMode(MidLevelRenderer::MLRState::DisableFogMode); drawEffectInfo[0]->state.SetFogMode(0); drawEffectInfo[0]->state.SetZBufferWriteOff(); drawEffectInfo[0]->state.SetZBufferCompareOff(); drawEffectInfo[0]->state.SetPriority(15); unsigned i; for (i=0; ieffect = new MidLevelRenderer::MLRLineCloud(Point_Count, 4); Register_Object(drawEffectInfo[1]->effect); gos_PopCurrentHeap(); drawEffectInfo[1]->clippingFlags.SetClippingState(0x3f); drawEffectInfo[1]->effectToWorld = NULL; drawEffectInfo[1]->effect->TurnAllOn(); // drawEffectInfo[1]->state.SetFogMode(MidLevelRenderer::MLRState::DisableFogMode); drawEffectInfo[1]->state.SetFogMode(0); drawEffectInfo[1]->state.SetZBufferWriteOff(); drawEffectInfo[1]->state.SetZBufferCompareOn(); drawEffectInfo[1]->state.SetFilterMode(MidLevelRenderer::MLRState::BiLinearFilterMode); drawEffectInfo[1]->state.SetPriority(15); for (i=0; iSync(); #ifdef SHADOW_TEST gos_PushCurrentHeap(MidLevelRenderer::LightsHeap); DWORD hints = gosHint_DisableMipmap | gosHint_DontShrink; shadowTexture = MLRTexturePool::Instance->Add("Shadow Test", gos_Texture_Keyed, 256, (gos_TextureHints)hints); MidLevelRenderer::MLR_I_TMesh *shadowMesh = new MidLevelRenderer::MLR_I_TMesh; Register_Object(shadowMesh); shadowMesh->AttachReference(); shadowMesh->dataStore->coords.SetLength(4); shadowMesh->dataStore->coords[0] = Point3D(-5.0f, 0.0f, 0.0f); shadowMesh->dataStore->coords[1] = Point3D(-5.0f, 0.0f, 10.0f); shadowMesh->dataStore->coords[2] = Point3D(5.0f, 0.0f, 10.0f); shadowMesh->dataStore->coords[3] = Point3D(5.0f, 0.0f, 0.0f); shadowMesh->SetCoordData(shadowMesh->dataStore->coords.GetData(), 4); shadowMesh->dataStore->texCoords.SetLength(4); shadowMesh->dataStore->texCoords[0] = Vector2DScalar(0.0f, 0.0f); shadowMesh->dataStore->texCoords[1] = Vector2DScalar(0.0f, 1.0f); shadowMesh->dataStore->texCoords[2] = Vector2DScalar(1.0f, 1.0f); shadowMesh->dataStore->texCoords[3] = Vector2DScalar(1.0f, 0.0f); shadowMesh->SetTexCoordData(shadowMesh->dataStore->texCoords.GetData(), 4); shadowMesh->dataStore->index.SetLength(6); shadowMesh->dataStore->index[0] = 0; shadowMesh->dataStore->index[1] = 1; shadowMesh->dataStore->index[2] = 2; shadowMesh->dataStore->index[3] = 0; shadowMesh->dataStore->index[4] = 2; shadowMesh->dataStore->index[5] = 3; shadowMesh->SetIndexData(shadowMesh->dataStore->index.GetData(), 6); shadowMesh->SetSubprimitiveLengths(NULL, 2); MLRState state; state.SetTextureHandle(shadowTexture->GetTextureHandle()); state.SetZBufferCompareOn(); shadowMesh->SetReferenceState(state); gos_PopCurrentHeap(); gos_PushCurrentHeap(MidLevelRenderer::ShapesHeap); shadowShape = new MidLevelRenderer::MLRShape(1); Register_Object(shadowShape); shadowShape->Add(shadowMesh); shadowMatrix = Stuff::LinearMatrix4D::Identity; shadowMatrix.BuildTranslation(Point3D(0.0f, -10.0f, 5.0)); drawShapeInfo.shape = shadowShape; drawShapeInfo.nrOfActiveLights = 0; drawShapeInfo.clippingFlags.SetClippingState(0x3f); drawShapeInfo.shapeToWorld = &shadowMatrix; drawShapeInfo.worldToShape = &shadowMatrix; drawShapeInfo.paintMeColor = &RGBAColor::White; gos_PopCurrentHeap(); #endif MidLevelRenderer::MLRTexturePool::Instance->LoadImages(); } #ifdef SHADOW_TEST void TraversErfBranch(ElementRenderer::Element *elmt) { if(elmt->GetClassID() == ElementRenderer::CameraElementClassID) { return; } switch(elmt->GetClassID()) { case ElementRenderer::GroupElementClassID: { ElementRenderer::GroupElement *group = Cast_Pointer(ElementRenderer::GroupElement *, elmt); Stuff::ChainIteratorOf *children = group->MakeIterator(); Register_Object(children); ElementRenderer::Element *child = NULL; while ((child = children->ReadAndNext()) != NULL) { TraversErfBranch( child); } Unregister_Object(children); delete children; } break; case ElementRenderer::ListElementClassID: { ElementRenderer::ListElement *group = Cast_Pointer(ElementRenderer::ListElement *, elmt); for(int i=0;iGetActiveCount();i++) { TraversErfBranch(group->GetIndexedElement(i)); } } break; case ElementRenderer::GridElementClassID: { ElementRenderer::GridElement *group = Cast_Pointer(ElementRenderer::GridElement *, elmt); unsigned xSize, zSize; group->GetSize(&xSize, &zSize); for(int i=0;iGetIndexedElement(i, j)); } } break; case ElementRenderer::LODElementClassID: { ElementRenderer::ListElement *group = Cast_Pointer(ElementRenderer::ListElement *, elmt); for(int i=0;iGetActiveCount();i++) { TraversErfBranch(group->GetIndexedElement(i)); } } break; case ElementRenderer::PointCloudElementClassID: { } break; case ElementRenderer::ScalableShapeElementClassID: { ElementRenderer::ShapeElement *group = Cast_Pointer(ElementRenderer::ShapeElement *, elmt); MidLevelRenderer::MLRShape *shape=group->GetMLRShape(); UnitVector3D uvec; uvec.Normalize(UnitVector3D(0.0f, -1.0f, 1.0f)); shape->DrawMyShadow(shadowMatrix, uvec); } break; case ElementRenderer::ScreenQuadsElementClassID: { } break; case ElementRenderer::ShapeElementClassID: { ElementRenderer::ShapeElement *group = Cast_Pointer(ElementRenderer::ShapeElement *, elmt); MidLevelRenderer::MLRShape *shape = group->GetMLRShape(); UnitVector3D uvec; uvec.Normalize(UnitVector3D(0.0f, -1.0f, 1.0f)); shape->DrawMyShadow(shadowMatrix, uvec); } break; case ElementRenderer::SwitchElementClassID: { ElementRenderer::ListElement *group = Cast_Pointer(ElementRenderer::ListElement *, elmt); for(int i=0;iGetActiveCount();i++) { TraversErfBranch(group->GetIndexedElement(i)); } } break; case ElementRenderer::TriangleCloudElementClassID: { } break; } } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void _stdcall DoGameLogic() { DWORD level = gCurrentHeapStackLevel; // //----------------------------------------------- // Read the keyboard to see how to set the switch //----------------------------------------------- // if(!Camera_State) { Verify(gCurrentHeapStackLevel == level); return; } Check_Object(Camera_State); MidLevelRenderer::MLRState mlr_state = Camera_State->GetMLRState(); // //--------------- // Read the mouse //--------------- // int x_delta, y_delta; Stuff::Scalar n_xdelta, n_ydelta; DWORD buttons; gos_GetMouseInfo(NULL, NULL, &x_delta, &y_delta, NULL, &buttons); Stuff::Scalar x_speed = x_delta * 0.01f, y_speed = y_delta * 0.01f; n_xdelta=(Stuff::Scalar)x_delta/Environment.screenWidth; n_ydelta=(Stuff::Scalar)y_delta/Environment.screenHeight; // //------------------------------------------------------ // If the left Ctrl button is held down, move the camera //------------------------------------------------------ // gosEnum_KeyStatus status = gos_GetKeyStatus(KEY_LCONTROL); if (status != KEY_FREE && status != KEY_RELEASED) { Camera_Direction.pitch += y_speed; Camera_Direction.yaw -= x_speed; if(theApp.Window3D) theApp.Window3D->SetCapture(); } // //------------------------------------------------------ // If the left Shift button is held down, pan the camera //------------------------------------------------------ // status = gos_GetKeyStatus(KEY_LSHIFT); if (status != KEY_FREE && status != KEY_RELEASED) { Camera_Shift.x += n_xdelta*Camera_Direction.range; Camera_Shift.y += n_ydelta*Camera_Direction.range; if(theApp.Window3D) theApp.Window3D->SetCapture(); } // //----------------------------------------------------- // If the left Alt button is held down, zoom the camera //----------------------------------------------------- // status = gos_GetKeyStatus(KEY_LMENU); if (status != KEY_FREE && status != KEY_RELEASED) { Camera_Direction.range *=(Stuff::Scalar)pow(2, n_ydelta); if(theApp.Window3D) theApp.Window3D->SetCapture(); } Stuff::LinearMatrix4D ZTrans(true); Stuff::LinearMatrix4D LookAtTrans(true); Stuff::LinearMatrix4D RotMat(true); Stuff::LinearMatrix4D PanMat(true); Stuff::LinearMatrix4D TempMat1(true),TempMat2(true),CameraMatrix(true); ZTrans.BuildTranslation(Stuff::Point3D(0.0f,0.0f,-Camera_Direction.range)); RotMat.BuildRotation(Stuff::EulerAngles(Camera_Direction.pitch,Camera_Direction.yaw , 0.0f)); LookAtTrans.BuildTranslation(Camera_LookAt); PanMat.BuildTranslation(Stuff::Point3D(Camera_Shift.x,Camera_Shift.y,0.0f)); TempMat1.Multiply(PanMat,ZTrans); TempMat2.Multiply(TempMat1,RotMat); CameraMatrix.Multiply(TempMat2,LookAtTrans); Camera->SetLocalToParent(CameraMatrix); CString strWindowTitle; static Stuff::Scalar old_camera_range = 0.0f; if (old_camera_range != Camera_Direction.range) { strWindowTitle.Format("%s = %f", "Camera Distance", Camera_Direction.range); theApp.Window3D->SetWindowText((LPCSTR)strWindowTitle); old_camera_range = Camera_Direction.range; } // //------------------------------------------------------- // Now that we have moved everything, update the matrices //------------------------------------------------------- // Camera->Sync(); MidLevelRenderer::MLRTexturePool::Instance->LoadImages(); Verify(gCurrentHeapStackLevel == level); #ifdef SHADOW_TEST MidLevelRenderer::MLRState dState; Camera->GetClipper()->StartDraw( Stuff::LinearMatrix4D::Identity, Stuff::LinearMatrix4D::Identity, Stuff::RGBAColor::White, &Stuff::RGBAColor::White, dState, NULL ); gos_StartRenderToTexture( shadowTexture->GetImage()->GetHandle() ); TraversErfBranch(Scene); gos_EndRenderToTexture(); End3DScene(); #endif } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void _stdcall UpdateDisplay() { DWORD level = gCurrentHeapStackLevel; Camera->SetViewport(1.0f, 1.0f, 0.0f, 0.0f); Camera->DrawScene(); MidLevelRenderer::MLRState dState; Camera->GetClipper()->ResetSorter(dState); if(drawPointsYes == true) { Camera->GetClipper()->DrawEffect(drawEffectInfo[0]); } if(drawNormalsYes == true) { Camera->GetClipper()->DrawEffect(drawEffectInfo[1]); } #ifdef SHADOW_TEST Camera->GetClipper()->DrawShape(&drawShapeInfo); #endif if(drawPointsYes == true || drawNormalsYes == true) { Camera->GetClipper()->RenderNow(); } MLRTexture *tex = NULL; if(bumpAnime.water>0 && (tex = (*MidLevelRenderer::MLRTexturePool::Instance)[bumpAnime.water])!=NULL) { Stuff::AffineMatrix4D *texture_matrix = tex->GetTextureMatrix(); texture_matrix->entries[3] = bumpAnime.wu*animeCounter; texture_matrix->entries[7] = bumpAnime.wv*animeCounter; } tex = NULL; if(bumpAnime.bump>0 && (tex = (*MidLevelRenderer::MLRTexturePool::Instance)[bumpAnime.bump])!=NULL) { Stuff::AffineMatrix4D *texture_matrix = tex->GetTextureMatrix(); texture_matrix->entries[3] = bumpAnime.bu*animeCounter; texture_matrix->entries[7] = bumpAnime.bv*animeCounter; } tex = NULL; if(bumpAnime.normal>0 && (tex = (*MidLevelRenderer::MLRTexturePool::Instance)[bumpAnime.normal])!=NULL) { Stuff::AffineMatrix4D *texture_matrix = tex->GetTextureMatrix(); texture_matrix->entries[3] = bumpAnime.nu*animeCounter; texture_matrix->entries[7] = bumpAnime.nv*animeCounter; } animeCounter++; static float lasttime=(float)gos_GetElapsedTime(); float thistime=(float)gos_GetElapsedTime(); float timepast=(thistime-lasttime); YawPitchRoll ypr(thistime*Stuff::Pi_Over_2/5.0f,Stuff::Pi_Over_4,0.0f); LinearMatrix4D mat(ypr); Vector3D vect(0,0,1),v2; v2.Multiply(vect,mat); v2.Normalize(v2); MLR_BumpyWater::SetSunLight(UnitVector3D(v2)); //MLR_Water::SetSunLight(UnitVector3D(v2)); lasttime=thistime; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void _stdcall TerminateGameEngine() { while (m_pErf_Name_List.GetCount() && m_pErf_Name_List.GetHead()) {Unregister_Object(m_pErf_Name_List.GetHead()); delete m_pErf_Name_List.GetHead(); m_pErf_Name_List.RemoveHead();} (*(theApp.m_phashErfNameMapping)).DeletePlugs(); delete theApp.m_phashErfNameMapping; Unregister_Object(erf_texture_path); delete erf_texture_path; Unregister_Object(drawEffectInfo[0]->effect); delete drawEffectInfo[0]->effect; Unregister_Pointer(drawEffectInfo[0]); delete drawEffectInfo[0]; Unregister_Object(drawEffectInfo[1]->effect); delete drawEffectInfo[1]->effect; Unregister_Pointer(drawEffectInfo[1]); delete drawEffectInfo[1]; // //------------------- // Turn off libraries //------------------- // ElementRenderer::TerminateClasses(); gosFX::TerminateClasses(); MidLevelRenderer::TerminateClasses(); Stuff::TerminateClasses(); Camera_State=NULL; } // // Setup the GameOS structure // void __stdcall GetGameOSEnvironment( char* CommandLine ) { // Command_Line=CommandLine; Environment.applicationName = "ERFViewer"; Environment.screenWidth = 640; Environment.screenHeight = 480; Environment.fullScreen = FALSE; Environment.bitDepth = 16; Environment.debugLog = "ErfViewer.txt"; Environment.spew = ""; //"GameOS*"; Environment.UpdateRenderers = UpdateDisplay; Environment.DoGameLogic = DoGameLogic; Environment.InitializeGameEngine = InitializeGameEngine; Environment.TerminateGameEngine = TerminateGameEngine; Environment.Renderer = 0; Environment.FullScreenDevice = 0; Environment.AntiAlias = 0; // true/false - Enable full screen antialiasing // // Texture infomation // Environment.Texture_S_256 = 13; Environment.Texture_S_128 = 12; Environment.Texture_S_64 = 1; Environment.Texture_S_32 = 1; Environment.Texture_S_16 = 1; Environment.Texture_K_256 = 1; Environment.Texture_K_128 = 1; Environment.Texture_K_64 = 1; Environment.Texture_K_32 = 1; Environment.Texture_K_16 = 1; Environment.Texture_A_256 = 1; Environment.Texture_A_128 = 1; Environment.Texture_A_64 = 1; Environment.Texture_A_32 = 1; Environment.Texture_A_16 = 1; Environment.dontClearRegistry = true; } void __stdcall ILFree(LPITEMIDLIST pidl); void CMFCGosApp::OnOptionsTexturepath() { NewTexturePath(); MessageBox(NULL,"These changes will not take effect until the program is restarted","Warning!!!",MB_OK|MB_ICONEXCLAMATION); } void __stdcall ILFree(LPITEMIDLIST pidl) { LPMALLOC pMalloc; if (pidl) { #ifdef DEBUG UINT cbSize = ILGetSize(pidl); VALIDATE_PIDL(pidl); // Fill the memory with some bad value... _fmemset(pidl, 0xE5, cbSize); // If large enough try to save the call return address of who // freed us in the 3-6 byte of the structure. if (cbSize >= 6) *((UINT*)((LPSTR)pidl + 2)) = *(((UINT*)&pidl) - 1); #endif SHGetMalloc(&pMalloc); pMalloc->Free( pidl); pMalloc->Release(); } } void CMFCGosApp::GetTexturePath() { TexturePath=GetProfileString("ERF Viewer MFC","TexturePath"); if(TexturePath.GetLength()==0) { NewTexturePath(); } // end if string in Registry *erf_texture_path = Stuff::MString((LPCSTR)TexturePath); if(erf_texture_path->GetLength()) { if(MidLevelRenderer::MLRTexturePool::Instance) { MidLevelRenderer::TGAFilePool *pool = new MidLevelRenderer::TGAFilePool(*erf_texture_path, "textures.hint"); Register_Object(pool); MidLevelRenderer::MLRTexturePool::Instance = new MidLevelRenderer::MLRTexturePool(pool); Check_Object(MidLevelRenderer::MLRTexturePool::Instance); Register_Object(MidLevelRenderer::MLRTexturePool::Instance); } } } void CMFCGosApp::NewTexturePath() { char pname[MAX_PATH]; BROWSEINFO bi; if(m_pMainWnd==NULL) bi.hwndOwner =NULL; else bi.hwndOwner = m_pMainWnd->m_hWnd; bi.pidlRoot = NULL; bi.pszDisplayName = NULL; bi.lpszTitle = "Choose Texture Path..."; bi.ulFlags = BIF_RETURNONLYFSDIRS; bi.lpfn = NULL; bi.lParam = (LPARAM)this; LPITEMIDLIST pidl = SHBrowseForFolder(&bi); if (SHGetPathFromIDList(pidl,pname)) { TexturePath=pname; TexturePath+="\\"; WriteProfileString("ERF Viewer MFC","TexturePath",TexturePath); } if (bi.pidlRoot) { ILFree( const_cast< ITEMIDLIST* >( bi.pidlRoot ) ); } } void CMFCGosApp::GetEffectsPath() { EffectsPath=GetProfileString("ERF Viewer MFC","EffectsPath"); if(EffectsPath.GetLength()==0) { NewEffectsPath(); } // end if string in Registry *erf_effects_path = Stuff::MString((LPCSTR)EffectsPath); if(erf_effects_path->GetLength()) { } } void CMFCGosApp::NewEffectsPath() { char pname[MAX_PATH]; BROWSEINFO bi; if(m_pMainWnd==NULL) bi.hwndOwner =NULL; else bi.hwndOwner = m_pMainWnd->m_hWnd; bi.pidlRoot = NULL; bi.pszDisplayName = NULL; bi.lpszTitle = "Choose effects Path..."; bi.ulFlags = BIF_RETURNONLYFSDIRS; bi.lpfn = NULL; bi.lParam = (LPARAM)this; LPITEMIDLIST pidl = SHBrowseForFolder(&bi); if (SHGetPathFromIDList(pidl,pname)) { EffectsPath=pname; EffectsPath+="\\"; WriteProfileString("ERF Viewer MFC","EffectsPath",EffectsPath); } if (bi.pidlRoot) { ILFree( const_cast< ITEMIDLIST* >( bi.pidlRoot ) ); } } BOOL CMFCGosApp::ProcessShellCommandNoLoad(CCommandLineInfo &rCmdInfo) { BOOL bResult = TRUE; switch (rCmdInfo.m_nShellCommand) { case CCommandLineInfo::FileNew: case CCommandLineInfo::FileOpen: if (!AfxGetApp()->OnCmdMsg(ID_FILE_NEW, 0, NULL, NULL)) OnFileNew(); if (m_pMainWnd == NULL) bResult = FALSE; break; case CCommandLineInfo::FilePrintTo: case CCommandLineInfo::FilePrint: m_nCmdShow = SW_HIDE; ASSERT(m_pCmdInfo == NULL); OpenDocumentFile(rCmdInfo.m_strFileName); m_pCmdInfo = &rCmdInfo; m_pMainWnd->SendMessage(WM_COMMAND, ID_FILE_PRINT_DIRECT); m_pCmdInfo = NULL; bResult = FALSE; break; // If we're doing DDE, hide ourselves case CCommandLineInfo::FileDDE: m_pCmdInfo = (CCommandLineInfo*)m_nCmdShow; m_nCmdShow = SW_HIDE; break; // If we've been asked to unregister, unregister and then terminate case CCommandLineInfo::AppUnregister: { UnregisterShellFileTypes(); BOOL bUnregistered = Unregister(); // if you specify /EMBEDDED, we won't make an success/failure box // this use of /EMBEDDED is not related to OLE if (!rCmdInfo.m_bRunEmbedded) { if (bUnregistered) AfxMessageBox(AFX_IDP_UNREG_DONE); else AfxMessageBox(AFX_IDP_UNREG_FAILURE); } bResult = FALSE; // that's all we do // If nobody is using it already, we can use it. // We'll flag that we're unregistering and not save our state // on the way out. This new object gets deleted by the // app object destructor. if (m_pCmdInfo == NULL) { m_pCmdInfo = new CCommandLineInfo; m_pCmdInfo->m_nShellCommand = CCommandLineInfo::AppUnregister; } } break; } return bResult; } BOOL CMFCGosApp::ProcessShellCommandOnlyLoad(CCommandLineInfo &rCmdInfo) { BOOL bResult = TRUE; switch (rCmdInfo.m_nShellCommand) { // If we've been asked to open a file, call OpenDocumentFile() case CCommandLineInfo::FileOpen: if (!OpenDocumentFile(rCmdInfo.m_strFileName)) bResult = FALSE; break; } return bResult; } void CMFCGosApp::OnView3dviewwindow() { // TODO: Add your command handler code here if(Window3D) Window3D->ShowWindow(Window3D->IsWindowVisible( )?SW_HIDE:SW_SHOW); } void CMFCGosApp::OnUpdateView3dviewwindow(CCmdUI* pCmdUI) { // TODO: Add your command update UI handler code here if(Window3D) pCmdUI->SetCheck( Window3D->IsWindowVisible( )); } void CMFCGosApp::GosShutDown() { theApp.Window3D->PreGosCleanUp(); if(Scene) { Unregister_Object(Scene); delete Scene; } Stuff::FileStream * pFile; while (theApp.m_pFileSet_List.GetCount() && ((pFile = theApp.m_pFileSet_List.GetHead()) != NULL)) { delete pFile; theApp.m_pFileSet_List.RemoveHead(); } TerminateGameEngine(); // gos_PopCurrentHeap(); // gos_DestroyMemoryHeap(client); ExitGameOS(); theApp.Window3D->GOSActive=false; GOSActive=false; } void CMFCGosApp::DrawScreen() { DWORD level = gCurrentHeapStackLevel; Verify(UpdateLevel>=0); if(UpdateLevel==0) { UpdateLevel++; if(RunGameOSLogic()) PostQuitMessage(0); if(Window3DOpen==true) Window3D->UpdateMenu(); UpdateLevel--; } Verify(gCurrentHeapStackLevel == level); } void CMFCGosApp::OnViewUpdateonidle() { DrawOnIdle=!DrawOnIdle; } void CMFCGosApp::OnUpdateViewUpdateonidle(CCmdUI* pCmdUI) { pCmdUI->SetCheck(DrawOnIdle?1:0); } void CMFCGosApp::UpdateLightList() { int i,idx; LightDlg->m_LightList.ResetContent(); for(i=0;im_lights[i];i++) { switch(LightState->m_lights[i]->GetLightType()) { case MidLevelRenderer::MLRLight::AmbientLight: idx=LightDlg->m_LightList.AddString("Ambient Light"); break; case MidLevelRenderer::MLRLight::InfiniteLight: idx=LightDlg->m_LightList.AddString("Infinite Light"); break; case MidLevelRenderer::MLRLight::PointLight: idx=LightDlg->m_LightList.AddString("Point Light"); break; case MidLevelRenderer::MLRLight::SpotLight: idx=LightDlg->m_LightList.AddString("Spot Light"); break; case MidLevelRenderer::MLRLight::ProjectLight: idx=LightDlg->m_LightList.AddString("Project Light"); break; } LightDlg->m_LightList.SetItemDataPtr(idx,LightState->m_lights[i]); } } void CMFCGosApp::OnWindowsLightlist() { if(LightDlg) LightDlg->ShowWindow(LightDlg->IsWindowVisible()?SW_HIDE:SW_SHOW); } void CMFCGosApp::OnUpdateWindowsLightlist(CCmdUI* pCmdUI) { if(LightDlg) pCmdUI->SetCheck(LightDlg->IsWindowVisible()?1:0); } void CMFCGosApp::OnFileOpen() { CFileDialog dlg(true,"*.erf",NULL,OFN_ALLOWMULTISELECT | OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_SHAREAWARE,"MLR Files (*.erf;*.mlr)|*.erf;*.mlr||"); char szFileListOriginal[64*1024 +1] = ""; char szFileList[64*1024 +1] = ""; char *tmp= szFileList; dlg.m_ofn.lpstrFile = szFileListOriginal; dlg.m_ofn.nMaxFile = 64 * 1024 - 1; if (IDOK==dlg.DoModal()) { int count = 00; POSITION pos = dlg.GetStartPosition(); CString strFileName; while (pos) { count++; if (count >= 64) { MessageBox(NULL, "Too many files. Files > 64.", "Error", MB_OK); return; } strFileName = dlg.GetNextPathName(pos); strcpy(tmp, (LPCSTR) strFileName); if (pos) // there are more { tmp += strFileName.GetLength(); *tmp = '/'; tmp++; } } CMFCGosDoc * pDoc = GetActiveErfDocument(); if (!pDoc) return; CWinApp::OnFileNew(); pDoc->OnOpenDocument(szFileList); } else { DWORD dwTemp = CommDlgExtendedError(); } } void CMFCGosApp::OnExpandAll() { CFrameWnd * pWnd = (CFrameWnd *)this->GetMainWnd(); CMFCGosView * pView = (CMFCGosView *)pWnd->GetActiveView(); pView->OnExpandAll(); } void CMFCGosApp::OnCollapseAll() { CFrameWnd * pWnd = (CFrameWnd *)this->GetMainWnd(); CMFCGosView * pView = (CMFCGosView *)pWnd->GetActiveView(); pView->OnCollapseAll(); } #define CAMERA_KEY_SPEED (1.0f) void CMFCGosApp::UpdateCameraFromKeyMessage(UINT message, WPARAM wParam, LPARAM lParam) { #define HIGHBITON(M_X) ((M_X & (1<<((sizeof(SHORT)*8)-1))) != 0) BOOL controlDown = HIGHBITON(GetKeyState(VK_CONTROL)); BOOL shiftDown = HIGHBITON(GetKeyState(VK_SHIFT)); BOOL altDown = controlDown && shiftDown;//HIGHBITON(GetKeyState(VK_MENU)); if (altDown) { controlDown = shiftDown = false; } switch (wParam) { case VK_UP: if (controlDown) Camera_Direction.pitch -= CAMERA_KEY_SPEED * .05f; if (shiftDown) Camera_Shift.y += CAMERA_KEY_SPEED; if (altDown) Camera_Direction.range -= CAMERA_KEY_SPEED; break; case VK_DOWN: if (controlDown) Camera_Direction.pitch += CAMERA_KEY_SPEED * .05f; if (shiftDown) Camera_Shift.y -= CAMERA_KEY_SPEED; if (altDown) Camera_Direction.range += CAMERA_KEY_SPEED; break; case VK_LEFT: if (controlDown) Camera_Direction.yaw -= CAMERA_KEY_SPEED * .05f; if (shiftDown) Camera_Shift.x += CAMERA_KEY_SPEED; break; case VK_RIGHT: if (controlDown) Camera_Direction.yaw += CAMERA_KEY_SPEED * .05f; if (shiftDown) Camera_Shift.x -= CAMERA_KEY_SPEED; break; } }