1from arcade.glui.dialog import Dialog 2from arcade.glui.gamecenterrunner import GameCenterRunner 3from arcade.glui.input import InputHandler 4from arcade.glui.menu import Menu 5from arcade.glui.opengl import gl, fs_emu_texturing, fs_emu_blending 6from arcade.glui.render import Render 7from arcade.glui.state import State 8from arcade.glui.texture import Texture 9from arcade.glui.topmenu import GameCenterItem 10from arcade.glui.window import set_current_menu, render_fade 11from arcade.glui.window import set_ingame_status, back_to_menu_from_game 12 13STATE_STARTING = 0 14STATE_PREPARING = 1 15STATE_WAITRUN = 2 16STATE_RUNNING = 3 17STATE_STOPPING = 4 18STATE_ABORTING = 5 19STATE_ABORTED = 6 20 21FADE_TIME = 0.5 22 23 24class LaunchMenu(Menu): 25 def __init__(self, item, controller): 26 Menu.__init__(self) 27 # self.top_menu_transition = 0.0 28 self.items.append(item) 29 if self.use_game_center_item(): 30 self.top.left.append(GameCenterItem()) 31 # self.top.left.append(HomeItem()) 32 # self.top.left.append(MenuItem(item.title)) 33 self.top.set_selected_index( 34 len(self.top.left) + len(self.top.right) - 1 35 ) 36 self.state = STATE_STARTING 37 self.gc_runner = None 38 self.controller = controller 39 self.throbber = Throbber() 40 self.wait_run_time = 0 41 42 # noinspection PyMethodMayBeStatic 43 def on_status(self, status): 44 print("received status", status) 45 46 def update_state(self): 47 if self.state == STATE_STARTING: 48 self.gc_runner = GameCenterRunner(controller=self.controller) 49 # prepare will unpack the game and prepare game files 50 self.gc_runner.prepare() 51 self.state = STATE_PREPARING 52 self.throbber.throbber_start_time = 0 53 54 elif self.state == STATE_PREPARING: 55 if self.gc_runner.error: 56 pass 57 elif self.gc_runner.done: 58 self.wait_run_time = State.get().time 59 FadeDialog(self.wait_run_time).show() 60 self.state = STATE_WAITRUN 61 62 elif self.state == STATE_WAITRUN: 63 if State.get().time - self.wait_run_time > FADE_TIME: 64 set_ingame_status() 65 self.gc_runner.run() 66 self.state = STATE_RUNNING 67 68 elif self.state == STATE_RUNNING: 69 InputHandler.set_inhibited(True) 70 if self.gc_runner.error: 71 pass 72 elif self.gc_runner.done: 73 self.state = STATE_STOPPING 74 75 elif self.state == STATE_STOPPING: 76 InputHandler.set_inhibited(False) 77 State.get().history.pop() 78 State.get().history.pop() 79 State.get().history.pop() 80 set_current_menu(State.get().history[-1]) 81 back_to_menu_from_game() 82 Dialog.get_current().close() 83 84 from arcade.glui.window import main_window 85 86 main_window.restore_window_if_necessary() 87 88 elif self.state == STATE_ABORTING: 89 pass 90 91 def go_back(self): 92 print("LaunchMenu.go_back") 93 if self.state in [STATE_STARTING, STATE_PREPARING]: 94 if self.gc_runner: 95 self.gc_runner.abort() 96 self.state = STATE_ABORTING 97 if self.state in [STATE_ABORTED]: 98 State.get().history.pop() 99 set_current_menu(State.get().history[-1]) 100 101 def activate(self): 102 print("LaunchMenu.activate") 103 104 def update(self): 105 self.update_state() 106 107 def render(self): 108 Render.get().hd_perspective() 109 fs_emu_texturing(True) 110 fs_emu_blending(False) 111 Texture.sidebar_background.render( 112 0, 0, 1920, Texture.sidebar_background.h 113 ) 114 115 if self.state in [STATE_PREPARING, STATE_WAITRUN]: 116 self.throbber.render() 117 # elif self.state in [STATE_RUNNING, STATE_STOPPING]: 118 # pass 119 # gl.glDisable(gl.GL_DEPTH_TEST) 120 # render_fade(0.0, 0.0, 0.0, 1.0) 121 # gl.glEnable(gl.GL_DEPTH_TEST) 122 123 124class FadeDialog(Dialog): 125 def __init__(self, wait_run_time): 126 super().__init__() 127 self.wait_run_time = wait_run_time 128 129 def render(self): 130 gl.glDisable(gl.GL_DEPTH_TEST) 131 alpha = (State.get().time - self.wait_run_time) / FADE_TIME 132 render_fade(0.0, 0.0, 0.0, alpha) 133 gl.glEnable(gl.GL_DEPTH_TEST) 134 135 136class Throbber: 137 def __init__(self): 138 self.throbber_colors = [1.0, 0.8, 0.6, 0.2, 0.2, 0.2, 0.2, 0.2] 139 self.throbber_start_time = 0 140 self.throbber_progress = 0 141 self.throbber_opacity = 1.0 142 # self.start_time = 0 143 144 def render(self): 145 Render.get().hd_perspective() 146 if self.throbber_start_time == 0: 147 self.throbber_start_time = State.get().time 148 dt = State.get().time - self.throbber_start_time 149 # run animation with 15 fps 150 self.throbber_progress = int(dt * 15) 151 152 # bg_fade = (State.get().time - State.get().dialog_time) / 0.5 153 # if bg_fade > 1.0: 154 # bg_fade = 1.0 155 # elif bg_fade < 0.0: 156 # bg_fade = 0.0 157 fs_emu_texturing(False) 158 fs_emu_blending(True) 159 gl.glDisable(gl.GL_DEPTH_TEST) 160 gl.glDepthMask(False) 161 162 # gl.glBegin(gl.GL_QUADS) 163 # gl.glColor4f(0.0, 0.0, 0.0, bg_fade) 164 # gl.glVertex2f(0, 0) 165 # gl.glVertex2f(1920, 0) 166 # gl.glVertex2f(1920, 1020) 167 # gl.glVertex2f(0, 1020) 168 # gl.glEnd() 169 170 # gl.glBegin(gl.GL_QUADS) 171 # gl.glColor4f(0.0, 0.0, 0.0, bg_fade * 0.5) 172 # gl.glVertex2f(0, 1020) 173 # gl.glVertex2f(1920, 1020) 174 # gl.glVertex2f(1920, 1080) 175 # gl.glVertex2f(0, 1080) 176 # gl.glEnd() 177 178 # y = 0.0 179 # tw, th = Render.get().text("LAUNCHING GAME", self.title_font, 180 # 0.0, y, w=32 / 9, h=self.height, 181 # color=(1.0, 1.0, 1.0, 1.0), halign=0.0) 182 # 183 fs_emu_blending(True) 184 # if bg_fade > 0.5: 185 # self.throbber_opacity = (bg_fade - 0.5) / 0.5 186 # #self.throbber_opacity = bg_fade 187 # self.render_throbber() 188 # if bg_fade == 1.0: 189 # if State.get().time - State.get().dialog_time > 1.0: 190 # # gradually show over 1/4 second 191 # self.throbber_opacity = ( 192 # (State.get().time - State.get().dialog_time - 1.0) * 4) 193 # if self.throbber_opacity > 1.0: 194 # self.throbber_opacity = 1.0 195 # self.render_throbber() 196 if State.get().time - self.throbber_start_time > 0.25: 197 # gradually show over 1/3 second 198 self.throbber_opacity = ( 199 State.get().time - self.throbber_start_time - 0.25 200 ) * 4 201 if self.throbber_opacity > 1.0: 202 self.throbber_opacity = 1.0 203 self.render_throbber() 204 205 gl.glEnable(gl.GL_DEPTH_TEST) 206 gl.glDepthMask(True) 207 # fs_emu_texturing(1) 208 # fs_emu_blending(0) 209 # print("Setting dirty..") 210 Render.get().dirty = True 211 212 def render_throbber(self): 213 cell_width = 32 214 cell_spacing = 16 215 throbber_width = 3 * cell_width + 2 * cell_spacing 216 # throbber_height = throbber_width 217 left = (1920 - throbber_width) / 2 218 bottom = (1080 - throbber_width) / 2 219 220 self.render_cell(0, left, bottom) 221 self.render_cell(1, left + 1 * cell_width + 1 * cell_spacing, bottom) 222 self.render_cell(2, left + 2 * cell_width + 2 * cell_spacing, bottom) 223 self.render_cell( 224 3, 225 left + 2 * cell_width + 2 * cell_spacing, 226 bottom + 1 * cell_width + 1 * cell_spacing, 227 ) 228 self.render_cell( 229 4, 230 left + 2 * cell_width + 2 * cell_spacing, 231 bottom + 2 * cell_width + 2 * cell_spacing, 232 ) 233 self.render_cell( 234 5, 235 left + 1 * cell_width + 1 * cell_spacing, 236 bottom + 2 * cell_width + 2 * cell_spacing, 237 ) 238 self.render_cell(6, left, bottom + 2 * cell_width + 2 * cell_spacing) 239 self.render_cell(7, left, bottom + 1 * cell_width + 1 * cell_spacing) 240 241 def render_cell(self, index, x, y): 242 color = self.throbber_colors[(self.throbber_progress + index) % 8] 243 color *= self.throbber_opacity 244 gl.glColor4f(color, color, color, self.throbber_opacity) 245 gl.glBegin(gl.GL_QUADS) 246 gl.glVertex2f(x, y) 247 gl.glVertex2f(x + 32, y) 248 gl.glVertex2f(x + 32, y + 32) 249 gl.glVertex2f(x, y + 32) 250 gl.glEnd() 251