4 from importlib
import import_module
5 from inspect
import isclass
6 from sys
import platform
, argv
7 from logging
import info
, debug
8 from os
.path
import exists
9 from os
import makedirs
10 from panda3d
.core
import Filename
, load_prc_file_data
, AntialiasAttrib
, \
11 Texture
, WindowProperties
, LVector2i
12 from panda3d
.bullet
import BulletWorld
, BulletDebugNode
13 from direct
.showbase
.ShowBase
import ShowBase
14 from direct
.fsm
.FSM
import FSM
15 from pmachines
.music
import MusicMgr
16 from pmachines
.items
.background
import Background
17 from pmachines
.menu
import Menu
18 from pmachines
.scene
import Scene
19 from lib
.dictfile
import DctFile
20 from lib
.lib
.p3d
.p3d
import LibP3d
21 from lib
.engine
.lang
import LangMgr
26 def __init__(self
, pmachines
):
27 super().__init
__('Main FSM')
28 self
._pmachines
= pmachines
31 self
._pmachines
.on_menu_enter()
34 self
._pmachines
.on_menu_exit()
36 def enterScene(self
, cls
):
37 self
._pmachines
.on_scene_enter(cls
)
40 self
._pmachines
.on_scene_exit()
47 self
.base
= ShowBase()
48 info('platform: %s' % platform
)
49 info('exists main.py: %s' % exists('main.py'))
50 args
= self
._parse
_args
()
51 self
._prepare
_window
(args
)
52 self
.updating
= args
.update
53 self
.version
= args
.version
56 self
._music
= MusicMgr(self
._options
['settings']['volume'])
57 self
.lang_mgr
= LangMgr(self
._options
['settings']['language'],
60 self
._fsm
= MainFsm(self
)
61 if self
._options
['development']['auto_start']:
62 mod_name
= 'pmachines.scenes.scene_' + self
._options
['development']['auto_start']
63 for member
in import_module(mod_name
).__dict
__.values():
64 if isclass(member
) and issubclass(member
, Scene
) and \
67 self
._fsm
.demand('Scene', cls
)
69 self
._fsm
.demand('Menu')
71 def on_menu_enter(self
):
72 self
._menu
_bg
= Background()
74 self
._fsm
, self
.lang_mgr
, self
._options
, self
._music
,
78 self
._fsm
.demand('Menu')
80 def on_menu_exit(self
):
81 self
._menu
_bg
.destroy()
84 def on_scene_enter(self
, cls
):
87 self
.world
, self
.on_home
,
88 self
._options
['development']['auto_close_instructions'],
89 self
._options
['development']['debug_items'])
91 def on_scene_exit(self
):
96 load_prc_file_data('', 'window-title pmachines')
97 load_prc_file_data('', 'framebuffer-srgb true')
98 load_prc_file_data('', 'sync-video true')
99 load_prc_file_data('', 'threading-model Cull/Draw')
101 def _parse_args(self
):
102 parser
= argparse
.ArgumentParser()
103 parser
.add_argument('--update', action
='store_true')
104 parser
.add_argument('--version', action
='store_true')
105 parser
.add_argument('--optfile')
106 cmd_line
= [arg
for arg
in iter(argv
[1:]) if not arg
.startswith('-psn_')]
107 args
= parser
.parse_args(cmd_line
)
110 def _prepare_window(self
, args
):
112 if (platform
.startswith('win') or platform
.startswith('linux')) and (
113 not exists('main.py') or __file__
.startswith('/app/bin/')):
114 # it is the deployed version for windows
115 data_path
= str(Filename
.get_user_appdata_directory()) + '/pmachines'
116 home
= '/home/flavio' # we must force this for wine
117 if data_path
.startswith('/c/users/') and exists(home
+ '/.wine/'):
118 data_path
= home
+ '/.wine/drive_' + data_path
[1:]
119 info('creating dirs: %s' % data_path
)
120 makedirs(data_path
, exist_ok
=True)
121 optfile
= args
.optfile
if args
.optfile
else 'options.ini'
122 info('data path: %s' % data_path
)
123 info('option file: %s' % optfile
)
124 info('fixed path: %s' % LibP3d
.fixpath(data_path
+ '/' + optfile
))
138 'auto_close_instructions': 0,
142 opt_path
= LibP3d
.fixpath(data_path
+ '/' + optfile
) if data_path
else optfile
143 opt_exists
= exists(opt_path
)
144 self
._options
= DctFile(
145 LibP3d
.fixpath(data_path
+ '/' + optfile
) if data_path
else optfile
,
148 self
._options
.store()
149 res
= self
._options
['settings']['resolution']
151 res
= LVector2i(*[int(_res
) for _res
in res
.split('x')])
153 d_i
= base
.pipe
.get_display_information()
155 return d_i
.get_display_mode_width(idx
), \
156 d_i
.get_display_mode_height(idx
)
158 _res(idx
) for idx
in range(d_i
.get_total_display_modes())]
159 res
= sorted(resolutions
)[-1]
160 props
= WindowProperties()
162 props
.set_fullscreen(self
._options
['settings']['fullscreen'])
163 props
.set_icon_filename('assets/icon/pmachines.ico')
164 base
.win
.request_properties(props
)
165 gltf
.patch_loader(base
.loader
)
166 if self
._options
['development']['simplepbr']:
167 self
._pipeline
= simplepbr
.init(
168 use_normal_maps
=True,
169 use_emission_maps
=False,
170 use_occlusion_maps
=True,
171 msaa_samples
=4 if self
._options
['settings']['antialiasing'] else 1,
172 enable_shadows
=int(self
._options
['settings']['shadows']))
173 debug(f
'msaa: {self._pipeline.msaa_samples}')
174 debug(f
'shadows: {self._pipeline.enable_shadows}')
175 render
.setAntialias(AntialiasAttrib
.MAuto
)
176 self
.base
.set_background_color(0, 0, 0, 1)
177 self
.base
.disable_mouse()
178 if self
._options
['development']['show_buffers']:
179 base
.bufferViewer
.toggleEnable()
180 if self
._options
['development']['fps']:
181 base
.set_frame_rate_meter(True)
182 #self.base.accept('window-event', self._on_win_evt)
183 self
.base
.accept('aspectRatioChanged', self
._on
_aspect
_ratio
_changed
)
185 def _set_physics(self
):
186 if self
._options
['development']['physics_debug']:
187 debug_node
= BulletDebugNode('Debug')
188 debug_node
.show_wireframe(True)
189 debug_node
.show_constraints(True)
190 debug_node
.show_bounding_boxes(True)
191 debug_node
.show_normals(True)
192 self
._debug
_np
= render
.attach_new_node(debug_node
)
193 self
._debug
_np
.show()
194 self
.world
= BulletWorld()
195 self
.world
.set_gravity((0, 0, -9.81))
196 if self
._options
['development']['physics_debug']:
197 self
.world
.set_debug_node(self
._debug
_np
.node())
199 dt
= globalClock
.get_dt()
200 self
.world
.do_physics(dt
)
202 self
._phys
_tsk
= taskMgr
.add(update
, 'update')
204 def _unset_physics(self
):
205 if self
._options
['development']['physics_debug']:
206 self
._debug
_np
.remove_node()
208 taskMgr
.remove(self
._phys
_tsk
)
210 def _on_aspect_ratio_changed(self
):
211 if self
._fsm
.state
== 'Scene':
212 self
._scene
.on_aspect_ratio_changed()