f87bee384159904d193e4a82d8551250886db4e4
5 from importlib
import import_module
6 from inspect
import isclass
7 from sys
import platform
, argv
, exit
8 from logging
import info
, debug
9 from os
.path
import exists
10 from os
import makedirs
11 from panda3d
.core
import Filename
, load_prc_file_data
, AntialiasAttrib
, \
12 Texture
, WindowProperties
, LVector2i
13 from panda3d
.bullet
import BulletWorld
, BulletDebugNode
14 from direct
.showbase
.ShowBase
import ShowBase
15 from direct
.fsm
.FSM
import FSM
16 from pmachines
.music
import MusicMgr
17 from pmachines
.items
.background
import Background
18 from pmachines
.menu
import Menu
19 from pmachines
.scene
import Scene
20 from lib
.dictfile
import DctFile
21 from lib
.lib
.p3d
.p3d
import LibP3d
22 from lib
.engine
.lang
import LangMgr
27 def __init__(self
, pmachines
):
28 super().__init
__('Main FSM')
29 self
._pmachines
= pmachines
32 self
._pmachines
.on_menu_enter()
35 self
._pmachines
.on_menu_exit()
37 def enterScene(self
, cls
):
38 self
._pmachines
.on_scene_enter(cls
)
41 self
._pmachines
.on_scene_exit()
47 info('platform: %s' % platform
)
48 info('exists main.py: %s' % exists('main.py'))
49 args
= self
._parse
_args
()
51 self
.base
= ShowBase()
52 self
._prepare
_window
(args
)
53 self
.updating
= args
.update
54 self
.version
= args
.version
57 self
._music
= MusicMgr(self
._options
['settings']['volume'])
58 self
.lang_mgr
= LangMgr(self
._options
['settings']['language'],
61 self
._fsm
= MainFsm(self
)
64 for _file
in glob('pmachines/scenes/*.py'):
65 _fn
= _file
.replace('.py', '').replace('/', '.')
66 for member
in import_module(_fn
).__dict
__.values():
67 if isclass(member
) and issubclass(member
, Scene
) and \
69 scene_classes
+= [member
]
70 for cls
in scene_classes
:
71 scene
= cls(BulletWorld(), None, True, False)
75 elif self
._options
['development']['auto_start']:
76 mod_name
= 'pmachines.scenes.scene_' + self
._options
['development']['auto_start']
77 for member
in import_module(mod_name
).__dict
__.values():
78 if isclass(member
) and issubclass(member
, Scene
) and \
81 self
._fsm
.demand('Scene', cls
)
83 self
._fsm
.demand('Menu')
85 def on_menu_enter(self
):
86 self
._menu
_bg
= Background()
88 self
._fsm
, self
.lang_mgr
, self
._options
, self
._music
,
92 self
._fsm
.demand('Menu')
94 def on_menu_exit(self
):
95 self
._menu
_bg
.destroy()
98 def on_scene_enter(self
, cls
):
101 self
.world
, self
.on_home
,
102 self
._options
['development']['auto_close_instructions'],
103 self
._options
['development']['debug_items'])
105 def on_scene_exit(self
):
106 self
._unset
_physics
()
107 self
._scene
.destroy()
109 def _configure(self
, args
):
110 load_prc_file_data('', 'window-title pmachines')
111 load_prc_file_data('', 'framebuffer-srgb true')
112 load_prc_file_data('', 'sync-video true')
113 load_prc_file_data('', 'threading-model Cull/Draw')
115 load_prc_file_data('', 'window-type offscreen')
116 load_prc_file_data('', 'audio-library-name null')
118 def _parse_args(self
):
119 parser
= argparse
.ArgumentParser()
120 parser
.add_argument('--update', action
='store_true')
121 parser
.add_argument('--version', action
='store_true')
122 parser
.add_argument('--optfile')
123 parser
.add_argument('--screenshots', action
='store_true')
124 cmd_line
= [arg
for arg
in iter(argv
[1:]) if not arg
.startswith('-psn_')]
125 args
= parser
.parse_args(cmd_line
)
128 def _prepare_window(self
, args
):
130 if (platform
.startswith('win') or platform
.startswith('linux')) and (
131 not exists('main.py') or __file__
.startswith('/app/bin/')):
132 # it is the deployed version for windows
133 data_path
= str(Filename
.get_user_appdata_directory()) + '/pmachines'
134 home
= '/home/flavio' # we must force this for wine
135 if data_path
.startswith('/c/users/') and exists(home
+ '/.wine/'):
136 data_path
= home
+ '/.wine/drive_' + data_path
[1:]
137 info('creating dirs: %s' % data_path
)
138 makedirs(data_path
, exist_ok
=True)
139 optfile
= args
.optfile
if args
.optfile
else 'options.ini'
140 info('data path: %s' % data_path
)
141 info('option file: %s' % optfile
)
142 info('fixed path: %s' % LibP3d
.fixpath(data_path
+ '/' + optfile
))
156 'auto_close_instructions': 0,
160 opt_path
= LibP3d
.fixpath(data_path
+ '/' + optfile
) if data_path
else optfile
161 opt_exists
= exists(opt_path
)
162 self
._options
= DctFile(
163 LibP3d
.fixpath(data_path
+ '/' + optfile
) if data_path
else optfile
,
166 self
._options
.store()
167 res
= self
._options
['settings']['resolution']
169 res
= LVector2i(*[int(_res
) for _res
in res
.split('x')])
171 d_i
= base
.pipe
.get_display_information()
173 return d_i
.get_display_mode_width(idx
), \
174 d_i
.get_display_mode_height(idx
)
176 _res(idx
) for idx
in range(d_i
.get_total_display_modes())]
177 res
= sorted(resolutions
)[-1]
178 props
= WindowProperties()
180 props
.set_fullscreen(self
._options
['settings']['fullscreen'])
181 props
.set_icon_filename('assets/icon/pmachines.ico')
182 if not args
.screenshots
:
183 base
.win
.request_properties(props
)
184 gltf
.patch_loader(base
.loader
)
185 if self
._options
['development']['simplepbr']:
186 self
._pipeline
= simplepbr
.init(
187 use_normal_maps
=True,
188 use_emission_maps
=False,
189 use_occlusion_maps
=True,
190 msaa_samples
=4 if self
._options
['settings']['antialiasing'] else 1,
191 enable_shadows
=int(self
._options
['settings']['shadows']))
192 debug(f
'msaa: {self._pipeline.msaa_samples}')
193 debug(f
'shadows: {self._pipeline.enable_shadows}')
194 render
.setAntialias(AntialiasAttrib
.MAuto
)
195 self
.base
.set_background_color(0, 0, 0, 1)
196 self
.base
.disable_mouse()
197 if self
._options
['development']['show_buffers']:
198 base
.bufferViewer
.toggleEnable()
199 if self
._options
['development']['fps']:
200 base
.set_frame_rate_meter(True)
201 #self.base.accept('window-event', self._on_win_evt)
202 self
.base
.accept('aspectRatioChanged', self
._on
_aspect
_ratio
_changed
)
204 def _set_physics(self
):
205 if self
._options
['development']['physics_debug']:
206 debug_node
= BulletDebugNode('Debug')
207 debug_node
.show_wireframe(True)
208 debug_node
.show_constraints(True)
209 debug_node
.show_bounding_boxes(True)
210 debug_node
.show_normals(True)
211 self
._debug
_np
= render
.attach_new_node(debug_node
)
212 self
._debug
_np
.show()
213 self
.world
= BulletWorld()
214 self
.world
.set_gravity((0, 0, -9.81))
215 if self
._options
['development']['physics_debug']:
216 self
.world
.set_debug_node(self
._debug
_np
.node())
218 dt
= globalClock
.get_dt()
219 self
.world
.do_physics(dt
)
221 self
._phys
_tsk
= taskMgr
.add(update
, 'update')
223 def _unset_physics(self
):
224 if self
._options
['development']['physics_debug']:
225 self
._debug
_np
.remove_node()
227 taskMgr
.remove(self
._phys
_tsk
)
229 def _on_aspect_ratio_changed(self
):
230 if self
._fsm
.state
== 'Scene':
231 self
._scene
.on_aspect_ratio_changed()