def loop(self, choke): frame_no = 0 last_loop_ts = last_animflip_ts = sdltimer.get_ticks() - 1 render_choke = 1000/choke if choke > 0 else 0 # ala G_FPS_CAP anim_period = 1000/self.anim_fps paused = False finished = False panning = False scrolldict = { SDLK_LEFT: ( 1, 0), SDLK_RIGHT: ( -1, 0), SDLK_UP: ( 0, 1), SDLK_DOWN: ( 0, -1), SDLK_HOME: ( 1, 1), SDLK_PAGEUP: ( -1, 1), SDLK_END: ( 1, -1), SDLK_PAGEDOWN: ( -1, -1), } def had_input(): if not self.had_input: self.had_input = True self.hp_cheat.active = False while not finished: loop_start = sdltimer.get_ticks() self.last_loop_time = loop_start - last_loop_ts last_loop_ts = loop_start if not paused: if loop_start - last_animflip_ts > anim_period: frame_no += 1 last_animflip_ts = loop_start if frame_no > self.gamedata.maxframes-1: frame_no = 0 self.render(frame_no) while not finished: # hang around in case fps is user-limited while True: # eat events ev = sdlevents.poll_event(True) kmodstate = sdlkeyboard.get_mod_state() if ev is None: break elif ev.type == SDL_KEYDOWN: kcode = ev.key.keysym.sym if kcode == SDLK_SPACE: paused = not paused elif kcode == SDLK_F1: self.hp_cheat.active = not self.hp_cheat.active elif kcode == SDLK_F2: self.dump_fbos() elif kcode == SDLK_ESCAPE: if self.had_input: finished = True break else: self.hp_cheat.active = False elif kcode == SDLK_KP_MULTIPLY: self.show_hidden = False if self.show_hidden else True elif kcode in (SDLK_KP_DIVIDE, SDLK_BACKQUOTE): self.hp_debug.active = False if self.hp_debug.active else True elif kcode == SDLK_PERIOD and ev.mod & KMOD_SHIFT: self.zpan(-1) elif kcode == SDLK_COMMA and ev.mod & KMOD_SHIFT: self.zpan(1) elif kcode in scrolldict: boost = 10 if kmodstate & KMOD_SHIFT else 1 self.pan(Coord2(scrolldict[kcode][0] * boost * self.psz.x, scrolldict[kcode][1] * boost * self.psz.y)) elif kcode == SDLK_BACKSPACE: self.render_origin = self.gamedata.window elif kcode == SDLK_KP_PLUS: if self.anim_fps > 1: self.anim_fps += 1 elif self.anim_fps > 0.5: self.anim_fps = 1 else: self.anim_fps *= 2 anim_period = 1000.0 / self.anim_fps elif kcode == SDLK_KP_MINUS: if self.anim_fps > 1: self.anim_fps -= 1 else: self.anim_fps /= 2 anim_period = 1000.0 / self.anim_fps elif kcode == SDLK_MINUS: if self.zeddown > 1: self.zeddown -= 1 elif kcode == SDLK_EQUALS: if self.zeddown < self.gamedata.dim.z - 1: self.zeddown += 1 had_input() elif ev.type == SDL_QUIT: finished = True break elif ev.type == SDL_WINDOWEVENT: if ev.window.event == sdlvideo.SDL_WINDOWEVENT_RESIZED: self.reshape(Size2(ev.window.data1, ev.window.data2)) elif ev.type == SDL_MOUSEBUTTONDOWN: had_input() if ev.button.button == SDL_BUTTON_RIGHT: # RMB panning = True elif ev.button.button == SDL_BUTTON_LEFT: paused = not paused elif ev.type == SDL_MOUSEBUTTONUP: if ev.button.button == SDL_BUTTON_RIGHT: panning = False elif ev.type == SDL_MOUSEMOTION: if panning: self.pan(Coord2(ev.motion.xrel, ev.motion.yrel)) elif ev.type == SDL_MOUSEWHEEL: had_input() amount = -ev.wheel.y mpos = Coord2._make(sdlmouse.get_mouse_state()[1:]) if kmodstate & KMOD_CTRL: if amount > 0: self.zoom("zoom_in", mpos) else: self.zoom("zoom_out", mpos) elif kmodstate & KMOD_SHIFT: self.zpan(10 * amount) else: self.zpan(1 * amount) elapsed_time = sdltimer.get_ticks() - last_loop_ts if elapsed_time > render_choke: break sdltimer.delay(10)
def render(self, frame_no): bgc = GLColor( 0.0, 0.5, 0.0, 1 ) t_render_enter = sdltimer.get_ticks() win_mouse_pos = Coord2._make(sdlmouse.get_mouse_state()[1:]) fbo_mouse_pos = self.win2glfb(win_mouse_pos) grid_mouse_pos_f = self.win2dffb(win_mouse_pos) grid_mouse_pos = Coord2(int(grid_mouse_pos_f.x), int(grid_mouse_pos_f.y)) map_mouse_pos = Coord3(self.render_origin.x + grid_mouse_pos.x, self.render_origin.y + grid_mouse_pos.y, self.render_origin.z) mc = abs( 2*(t_render_enter - math.floor(t_render_enter)) - 1) mouse_color = ( mc, mc, mc, 1.0) if self.hp_debug.active: # todo: render debug data in single pass instead of what's below # outputting a second color output to a separate fbo black = (0,0,0,1) fbosz = Size2(self.fbo.size.w, self.fbo.size.h) self.debug_fbo.resize(fbosz) self.debug_fbo.bind(clear = black) nomouse = Coord2(-1, -1) self._render_one_grid(self.render_origin, nomouse, black, 1.0, frame_no, debug = True) # the tile under the mouse trect = Rect((fbo_mouse_pos.x//self.psz.x) * self.psz.x, (fbo_mouse_pos.y//self.psz.y) * self.psz.y, self.psz.x, self.psz.y) # read it back pixels = self.debug_fbo.readpixels(trect) self.hp_debug.update(self.winsize, pixels, self.psz, trect) self.fbo.bind(clear = bgc) zed = self.render_origin.z zeddown = min(self.zeddown, zed+1) zd = list((zeddown-z)/zeddown for z in range(zeddown)) # linear darkening for i in range(1-len(zd), 1): # draw starting from -zeddown zlevels and up # draw the map. if i + zed < 0: continue render_origin = self.render_origin._replace(z = i + zed) darken = zd[-i] self._render_one_grid(render_origin, grid_mouse_pos, mouse_color, darken, frame_no, hidden = self.show_hidden) self.fbo.blit(self.map_viewport) t_hud_start = sdltimer.get_ticks() panels = [ self.hp_renderer, self.hp_mouse, self.hp_cheat, self.hp_debug ] self.hp_renderer.update(self.winsize, self.map_viewport, hud_time = self.last_hud_time, loop_time = self.last_loop_time, zeddown = zeddown, anim_fps = self.anim_fps, frame_no = frame_no, origin = self.render_origin, grid = self.grid.size, map = self.gamedata.dim, pszar = self.Pszar, psz = self.psz, winsize = self.winsize, fbosize = self.fbo.size, show_hidden = self.show_hidden) self.hp_mouse.update(self.winsize, self.hp_renderer, self, win_mouse_pos, fbo_mouse_pos, grid_mouse_pos, grid_mouse_pos_f, map_mouse_pos) self.hp_cheat.update(self.winsize) self.hud.reshape(self.winsize) self.hud.render(panels) self.last_hud_time = sdltimer.get_ticks() - t_hud_start sdl_flip(self.window) self.last_render_time = sdltimer.get_ticks() - t_render_enter