Main.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. /******************************************************************************/
  4. /******************************************************************************
  5. Objects must use lock/unlock before modifying its elements (because background-thread-world-building loads area object 'Object.phys' read-only)
  6. Meshes must use lock/unlock before modifying its elements (because background-thread-world-building accesses mesh data read-only)
  7. PhysBodies must use lock/unlock before modifying its elements (because background-thread-world-building accesses phys bodies data read-only)
  8. /******************************************************************************/
  9. bool Initialized=false;
  10. Str SettingsPath, RunAtExit;
  11. Environment DefaultEnvironment;
  12. Threads WorkerThreads, BuilderThreads, BackgroundThreads;
  13. Str CmdLine;
  14. /******************************************************************************/
  15. void ScreenChanged(flt old_width, flt old_height)
  16. {
  17. VidOpt .setScale();
  18. VidOpt .resize();
  19. Misc .resize();
  20. Proj .resize();
  21. Projs .resize();
  22. Mode .resize();
  23. MtrlEdit.resize(); WaterMtrlEdit.resize(); // resize after 'Proj'
  24. ObjEdit.resize();
  25. AnimEdit.resize();
  26. WorldEdit.resize();
  27. GuiSkinEdit.resize();
  28. GuiEdit.resize();
  29. CodeEdit.resize();
  30. CopyElms.resize();
  31. GameScreenChanged();
  32. ResizeInstall();
  33. }
  34. bool DisplayReset()
  35. {
  36. SetKbExclusive(); // call because it depends on fullscreen mode
  37. return true;
  38. }
  39. void SetShader()
  40. {
  41. Game::World.setShader();
  42. WorldEdit.setShader();
  43. ObjEdit.setShader();
  44. TexDownsize.setShader();
  45. }
  46. void Drop(Memc<Str> &names, GuiObj *obj, C Vec2 &screen_pos)
  47. {
  48. AppStore.drop(names, obj, screen_pos); // process this before CopyElms, so it can be uploaded to the Store
  49. CopyElms.drop(names, obj, screen_pos); // process this first so it will handle importing EsenthelProject's
  50. Proj.drop(names, obj, screen_pos);
  51. MtrlEdit.drop(names, obj, screen_pos);
  52. WaterMtrlEdit.drop(names, obj, screen_pos);
  53. ObjEdit.drop(names, obj, screen_pos);
  54. ImportTerrain.drop(names, obj, screen_pos);
  55. ImageEdit.drop(names, obj, screen_pos);
  56. Brush.drop(names, obj, screen_pos);
  57. AppPropsEdit.drop(names, obj, screen_pos);
  58. SplitAnim.drop(names, obj, screen_pos);
  59. CodeEdit.drop(names, obj, screen_pos);
  60. CreateMtrls.drop(names, obj, screen_pos);
  61. if(obj && obj->type()==GO_TEXTLINE && names.elms())obj->asTextLine().set(names[0]);
  62. }
  63. bool SaveChanges(void (*after_save_close)(bool all_saved, ptr user), ptr user)
  64. {
  65. Memc<Edit::SaveChanges::Elm> elms;
  66. CodeEdit.saveChanges(elms);
  67. CodeEdit.saveChanges(elms, after_save_close, user);
  68. return !elms.elms();
  69. }
  70. void SetExit(bool all_saved, ptr) {if(all_saved)StateExit.set();}
  71. void Quit() {if(StateActive==&StatePublish)PublishCancel();else SaveChanges(SetExit);}
  72. void Resumed()
  73. {
  74. if(StateActive==&StateProjectList
  75. && !(Projs.proj_list.contains(Gui.ms()) && Gui.ms()->type()==GO_CHECKBOX)) // if we're activating application by clicking on a project list checkbox, then don't refresh, because it would lose focus and don't get toggled, or worse (another project would be toggled due to refresh)
  76. Projs.refresh(); // refresh list of project when window gets focused in case we've copied some projects to the Editor
  77. }
  78. void ReceiveData(cptr data, int size, ptr hwnd_sender)
  79. {
  80. File f; f.readMem(data, size);
  81. Str s=f.getStr();
  82. if(GetExt(s)==EsenthelProjectExt)CopyElms.display(s);
  83. }
  84. void SetTitle()
  85. {
  86. Str title;
  87. if(Mode()==MODE_CODE)title=CodeEdit.title();
  88. if(title.is())title=S+AppName+" - "+title;else title=AppName;
  89. WindowSetText(title);
  90. }
  91. void SetKbExclusive()
  92. {
  93. Kb.exclusive(D.full() || StateActive==&StateGame || (StateActive==&StateProject && (Mode()==MODE_OBJ || Mode()==MODE_ANIM || Mode()==MODE_WORLD || Mode()==MODE_TEX_DOWN)) || Theater.visible());
  94. }
  95. void SetProjectState()
  96. {
  97. (Proj.valid() ? Proj.needUpdate() ? StateProjectUpdate : StateProject : StateProjectList).set(StateFadeTime); // if there's a project opened then go back to its editing, otherwise go to project list
  98. }
  99. Rect EditRect(bool modes)
  100. {
  101. Rect r(-D.w(), -D.h(), D.w(), D.h());
  102. if(modes && Mode.visibleTabs())MIN(r.max.y, Mode.rect().min.y+D.pixelToScreenSize(Vec2(0, 0.5f)).y);
  103. if( Proj.visible ())MAX(r.min.x, Proj.rect().max.x-D.pixelToScreenSize(Vec2(0.5f, 0)).x);
  104. if( MtrlEdit.visible ())MIN(r.max.x, MtrlEdit.rect().min.x);
  105. if(WaterMtrlEdit.visible ())MIN(r.max.x, WaterMtrlEdit.rect().min.x);
  106. return r;
  107. }
  108. Environment& CurrentEnvironment() {if(Environment *env=EnvEdit.cur())return *env; return DefaultEnvironment;}
  109. /******************************************************************************/
  110. void InitPre()
  111. {
  112. if(App.cmdLine().is()) // if given command line param
  113. {
  114. Memc<uint> proc; ProcList(proc);
  115. REPA(proc)if(proc[i]!=App.processID())
  116. {
  117. Str proc_name=GetBase(ProcName(proc[i]));
  118. if(proc_name=="Esenthel.exe" || proc_name=="Esenthel 32 DX9.exe")
  119. if(ptr hwnd=ProcWindow(proc[i]))
  120. {
  121. File f; f.writeMem().putStr(RemoveQuotes(App.cmdLine())).pos(0);
  122. Memt<byte> temp; temp.setNum(f.left()); f.get(temp.data(), temp.elms());
  123. WindowSendData(temp.data(), temp.elms(), hwnd);
  124. App.flag=APP_EXIT_IMMEDIATELY;
  125. return;
  126. }
  127. }
  128. }
  129. ASSERT(ELM_NUM==(int)Edit::ELM_NUM); // they must match exactly
  130. Str path=GetPath(App.exe()).tailSlash(true);
  131. InstallerMode=(STEAM ? false : !(FExistSystem(path+"Bin/Code Editor.dat") && FExistSystem(path+"Bin/Engine.pak") && FExistSystem(path+"Bin/Editor.pak") && FExistSystem(path+"Bin/Mobile/Engine.pak") && FExistSystem(path+"Bin/EsenthelEngine/EsenthelEngine.h") && FExistSystem(path+"Bin/Android/Ant")));
  132. App.x=App.y=0;
  133. App.receive_data=ReceiveData;
  134. D.screen_changed=ScreenChanged;
  135. App.flag|=APP_MINIMIZABLE|APP_MAXIMIZABLE|APP_NO_PAUSE_ON_WINDOW_MOVE_SIZE|APP_WORK_IN_BACKGROUND|APP_RESIZABLE;
  136. EE_INIT(false, false);
  137. #if DEBUG
  138. App.flag|=APP_BREAKPOINT_ON_ERROR|APP_MEM_LEAKS|APP_CALLSTACK_ON_ERROR;
  139. Paks.add(EE_ENGINE_PATH);
  140. Paks.add(GetPath(EE_ENGINE_PATH).tailSlash(true)+"Editor.pak");
  141. if(ForceInstaller<0)InstallerMode=false;else if(ForceInstaller>0)InstallerMode=true;
  142. SetFbxDllPath(GetPath(EE_ENGINE_PATH).tailSlash(true)+"FBX32.dll", GetPath(EE_ENGINE_PATH).tailSlash(true)+"FBX64.dll");
  143. #endif
  144. if(InstallerMode)
  145. {
  146. App.name(InstallerName);
  147. #if WINDOWS
  148. App.flag|=APP_ALLOW_NO_GPU;
  149. #endif
  150. D.mode(App.desktopW()*0.4f, App.desktopH()*0.6f);
  151. Renderer.type(RT_SIMPLE);
  152. }else
  153. {
  154. SupportCompressAll();
  155. #if LINUX
  156. SettingsPath=SystemPath(SP_APP_DATA).tailSlash(true)+".esenthel\\Editor\\";
  157. #elif DESKTOP
  158. SettingsPath=SystemPath(SP_APP_DATA).tailSlash(true)+"Esenthel\\Editor\\";
  159. #else
  160. SettingsPath=SystemPath(SP_APP_DATA).tailSlash(true);
  161. #endif
  162. FCreateDirs(SettingsPath);
  163. ProjectsPath=MakeFullPath("Projects\\"); CodeEdit.projectsBuildPath(ProjectsPath+ProjectsBuildPath);
  164. App.name(AppName);
  165. App.flag|=APP_FULL_TOGGLE;
  166. App.drop=Drop;
  167. App.quit=Quit;
  168. App.resumed=Resumed;
  169. D.secondaryOpenGLContexts(Cpu.threads()*3); // worker threads + importer threads + manually called threads
  170. D.drawNullMaterials(true);
  171. D.set_shader=SetShader;
  172. D.reset=DisplayReset;
  173. D.mode(App.desktopW()*0.8f, App.desktopH()*0.8f);
  174. D.highPrecNrmCalc(true);
  175. #if !DEBUG
  176. Paks.add("Bin/Engine.pak");
  177. Paks.add("Bin/Editor.pak");
  178. #endif
  179. Sky.atmospheric();
  180. InitElmOrder();
  181. LoadSettings();
  182. VidOpt.ctor(); // init before applying video settings
  183. ApplyVideoSettings();
  184. }
  185. WorkerThreads.create(true);
  186. BuilderThreads.create(false);
  187. BackgroundThreads.create(false, Cpu.threads()-1);
  188. }
  189. /******************************************************************************/
  190. bool Init()
  191. {
  192. if(InstallerMode)StateInstall.set();else
  193. {
  194. Updater .create();
  195. UpdateWindow.create();
  196. if(!Physics.created())Physics.create(EE_PHYSX_DLL_PATH).timestep(PHYS_TIMESTEP_VARIABLE);
  197. const flt delay_remove=10;
  198. Meshes .delayRemove(delay_remove);
  199. PhysBodies .delayRemove(delay_remove);
  200. WaterMtrls .delayRemove(delay_remove);
  201. Materials .delayRemove(delay_remove);
  202. Fonts .delayRemove(delay_remove);
  203. ImageAtlases.delayRemove(delay_remove);
  204. Images .delayRemove(delay_remove);
  205. PanelImages .delayRemove(delay_remove);
  206. Panels .delayRemove(delay_remove);
  207. TextStyles .delayRemove(delay_remove);
  208. GuiSkins .delayRemove(delay_remove);
  209. Objects .delayRemove(delay_remove);
  210. EditObjects .delayRemove(delay_remove);
  211. Environments.delayRemove(delay_remove);
  212. Images .mode(CACHE_DUMMY);
  213. ImageAtlases .mode(CACHE_DUMMY);
  214. Materials .mode(CACHE_DUMMY);
  215. Meshes .mode(CACHE_DUMMY);
  216. PhysMtrls .mode(CACHE_DUMMY);
  217. PhysBodies .mode(CACHE_DUMMY);
  218. Skeletons .mode(CACHE_DUMMY);
  219. Animations .mode(CACHE_DUMMY);
  220. ParticlesCache.mode(CACHE_DUMMY);
  221. Objects .mode(CACHE_DUMMY);
  222. EditObjects .mode(CACHE_DUMMY);
  223. Fonts .mode(CACHE_DUMMY);
  224. Enums .mode(CACHE_DUMMY);
  225. WaterMtrls .mode(CACHE_DUMMY);
  226. PanelImages .mode(CACHE_DUMMY);
  227. Panels .mode(CACHE_DUMMY);
  228. TextStyles .mode(CACHE_DUMMY);
  229. GuiSkins .mode(CACHE_DUMMY);
  230. Environments .mode(CACHE_DUMMY);
  231. InitGui();
  232. #if 0
  233. LicenseCheck.create(); // create before 'Buy'
  234. Buy.create(); // create after 'LicenseCheck'
  235. #endif
  236. ReloadElm.create();
  237. SplitAnim.create();
  238. CopyElms.create();
  239. SizeStats.create();
  240. CompareProjs.create();
  241. ProjSettings.create();
  242. Publish.create();
  243. EraseRemoved.create();
  244. ElmProps.create();
  245. ObjClassEdit.create();
  246. RenameSlot.create();
  247. RenameBone.create();
  248. RenameEvent.create();
  249. NewWorld.create();
  250. Projs.create();
  251. Importer.create();
  252. ImportTerrain.create();
  253. EnumEdit.create();
  254. FontEdit.create();
  255. PanelImageEdit.create();
  256. PhysMtrlEdit.create();
  257. TextStyleEdit.create();
  258. AppPropsEdit.create();
  259. SoundEdit.create();
  260. VideoEdit.create();
  261. ImageEdit.create();
  262. ImageAtlasEdit.create();
  263. MiniMapEdit.create();
  264. IconSettsEdit.create();
  265. IconEdit.create();
  266. PanelEdit.create();
  267. EnvEdit.create();
  268. SetMtrlColor.create();
  269. MulSoundVolume.create();
  270. Gui+=Calculator.create(Rect_C(0, 0, 1.0f, 0.235f)).hide();
  271. AppStore.create();
  272. MSM.create();
  273. DST.create();
  274. CreateMtrls.create();
  275. ConvertToAtlas.create();
  276. ConvertToDeAtlas.create();
  277. MtrlEdit.create(); WaterMtrlEdit.create(); // create before 'Mode' so it's below Code Editor ouput
  278. Theater.create(); // create before 'Mode' so it's below Code Editor ouput
  279. Proj.create(); // create before 'Mode'
  280. Mode.create(); // create after 'MtrlEdit'
  281. Misc.create(); // create after 'MtrlEdit' so 'preview_big' doesn't overlap
  282. Preview.create(); // create after all elements to display preview on top
  283. RenameElm.create(); // create after 'Preview'
  284. ReplaceName.create();
  285. Proj.outer_region.moveAbove(Mode.close); // put above Mode so it's above obj/world/code edit (but below code editor output), so project region resize can be detected better (so it's on top of fullscreen editors)
  286. MtrlEdit.preview_big.moveAbove(Mode.close); WaterMtrlEdit.preview_big.moveAbove(Mode.close); Theater.moveAbove(Mode.close); // put above Mode so it's above obj/world/code edit (but below code editor output)
  287. StateProjectList.set();
  288. Sun.image="Gui/Misc/sun.img"; DefaultEnvironment.get(); // before 'ApplySettings'
  289. ApplySettings(); // !! after 'DefaultEnvironment' !!
  290. VidOpt.create(); // !! after 'ApplySettings' !!
  291. SetKbExclusive();
  292. AssociateFileType(EsenthelProjectExt, App.exe(), "Esenthel.Editor", "Esenthel Project", App.exe());
  293. CmdLine=RemoveQuotes(App.cmdLine());
  294. Initialized=true;
  295. }
  296. ScreenChanged();
  297. return true;
  298. }
  299. void Shut()
  300. {
  301. // delete threaded objects
  302. NewLod.del();
  303. MeshAO.del();
  304. FontEdit.del();
  305. PanelImageEdit.del();
  306. ShutGui();
  307. Proj.close();
  308. if(Initialized)SaveSettings(); // save before deletion
  309. CodeEdit .del();
  310. Updater .del();
  311. WorkerThreads.del();
  312. BuilderThreads.del();
  313. BackgroundThreads.del();
  314. if(RunAtExit.is())Run(RunAtExit, S, false, App.elevated());
  315. }
  316. /******************************************************************************/
  317. bool Update() {return false;}
  318. void Draw () {}
  319. /******************************************************************************/
  320. /******************************************************************************/