def apply_wave(self, surface): save = self.apply_wave.__dict__ wave = [0] * 32 self.screen_wave += self.wave_progression self.screen_wave &= 0xFFFF if self.screen_wave == 0 or self.screen_wave >= 256: self.screen_wave = self.wave_progression = 0 return a = 0 b = 60 + 8 for i in range(16): b -= 8 a += b wave[i] = a * self.screen_wave // 256 wave[i + 16] = 320 - wave[i] a = save['index'] pxarray = pg.PixelArray(surface) for p in range(200): b = wave[a] if b > 0: pxarray[:320 - b, p], pxarray[320 - b:320, p] = pxarray[b:320, p], pxarray[:b, p] a = (a + 1) % 32 save['index'] = (save['index'] + 1) % 32 del pxarray surface.unlock()
def fade_to_red(self): palette = self.get_palette() new_palette = copy.deepcopy(palette) pxarray = pg.PixelArray(self.screen) for x in range(self.screen.get_width()): for y in range(self.screen.get_height()): if pxarray[x, y] == 0x4F: pxarray[x, y] = 0x4E del pxarray self.screen.unlock() self.update_screen() for _ in range(32): for j in range(256): if j == 0x4F: continue color = (palette[j].r + palette[j].g + palette[j].b) // 4 + 64 if new_palette[j].r > color: new_palette[j].r -= min(new_palette[j].r - color, 8) elif new_palette[j].r < color: new_palette[j].r += min(color - new_palette[j].r, 8) if new_palette[j].g > 0: new_palette[j].g -= min(new_palette[j].g, 8) if new_palette[j].b > 0: new_palette[j].b -= min(new_palette[j].b, 8) self.set_screen_palette(new_palette) self.delay(75)
def show_fbp(self, chunk_num, fade): index = [0, 3, 1, 5, 2, 4] if self.cur_effect_sprite != 0: buf_sprite = self.mgo[self.cur_effect_sprite] buf = partial(self.fbp.render, chunk_num) if fade: p = self.create_compatible_surface(self.screen) fade = (fade + 1) * 10 buf(p) self.screen_bak.blit(self.screen, (0, 0)) for i in range(16): for j in range(6): self.screen_bak.lock() y = 0 x = index[j] buf_screen = pg.PixelArray(p) buf_bak = pg.PixelArray(self.screen_bak) while y < 200: a = buf_screen[x, y] b = buf_bak[x, y] if i > 0: if (a & 0x0F) > (b & 0x0F): b += 1 elif (a & 0x0F) < (b & 0x0F): b -= 1 buf_bak[x, y] = (a & 0xF0) | (b & 0x0F) x += 6 if x >= 320: x -= 320 y += 1 del buf_bak del buf_screen self.screen_bak.unlock() self.blit(self.screen_bak, (0, 0)) if self.cur_effect_sprite != 0: f = pg.time.get_ticks() // 150 buf_sprite[f % len(buf_sprite)].blit_to( self.screen, (0, 0)) self.update_screen() self.delay(fade) del p if chunk_num != (68 if is_win95 else 49): buf(self.screen) self.update_screen()
def start_video(self, index, surface): """ 开始一段录像,返回录像的帧数 """ videodata = self.read(index) self.video = MKFDecoder(data=videodata) self.frame_index = 0 self.image = surface self.pxarray = pg.PixelArray(self.image) return len(self.video)
def draw_char_on_surface(self, char, pos, color, use_8x8_font, surface=None): if surface is None: surface = self.screen x, y = pos if ord(char) >= 0x80: if config['use_embedded_font']: if char in char_data: index = char_data.index(char) char_ptr = index * 30 for i in range(30): dx = x + ((i & 1) << 3) char_byte = font_data[char_ptr + i] for j in range(8): if char_byte & (1 << (7 - j)): surface.set_at((dx, y), color) dx += 1 y += i & 1 return else: if config['use_iso_font'] and use_8x8_font: char_ptr = (ord(char) & 0x7f) * 15 for i in range(15): dx = x char_byte = iso_font[char_ptr + i] for j in range(8): if char_byte & (1 << j): surface.set_at((dx, y), color) dx += 1 y += (i & 1) return surf, rect = unicode_font.render(char) if use_8x8_font: rect.y += rect.y % 2 rect.y //= 2 rect.h += rect.h % 2 rect.h //= 2 surf = pg.transform.scale(surf, rect.size) pxarray = pg.PixelArray(surf) x += rect.x if use_8x8_font: y += 5 - rect.y else: y += 12 - rect.y for i in range(rect.w): for j in range(rect.h): has_color = pxarray[i, j] if has_color: surface.set_at((x + i + 1, y + j + 1), color)
def render(self, index, surface): width, height = 320, 200 pxarray = pg.PixelArray(surface) try: data = self.read(index) for y in range(height): for x in range(width): pxarray[x, y] = data[x + y * width] except AssertionError: pass del pxarray surface.unlock()
def blit_mono_color(self, dst_surface, pos, color_shift, color=None): pxarray = pg.PixelArray(dst_surface) max_w, max_h = dst_surface.get_size() ui_width, ui_height = self.size offset = 4 i = 0 if color is not None: color &= 0xF0 while i < ui_width * ui_height: num = self.data[offset] offset += 1 if (num & 0x80) and num <= 0x80 + ui_width: i += num - 0x80 else: j = -1 while j < num - 1: j += 1 y = (i + j) // ui_width + pal_y(pos) x = (i + j) % ui_width + pal_x(pos) if x < 0: j += -x - 1 continue elif x >= max_w: j += x - max_w continue if y < 0: j += -y * ui_width - 1 continue elif y >= max_h: return b = self.data[offset + j] & 0x0F if b + color_shift > 0x0F: b = 0x0F elif b + color_shift < 0: b = 0 else: b += color_shift if color is None: pxarray[x, y] = b | (self.data[offset + j] & 0xF0) else: pxarray[x, y] = b | color offset += num i += num
def blit_to_with_shadow(self, dst_surface, pos, shadow, pxarray=None): if pxarray is None: pxarray = pg.PixelArray(dst_surface) max_w, max_h = dst_surface.get_size() ui_width, ui_height = self.size if isinstance(pos, tuple): pos = pg.Rect(pos, self.size) offset = 4 i = 0 while i < ui_width * ui_height: num = self.data[offset] offset += 1 if (num & 0x80) and num <= 0x80 + ui_width: i += num - 0x80 else: y = i // ui_width + pos.y if y >= (pos.h + pos.y) or y >= max_h: return elif y < 0: j = -y * ui_width - 1 y = (i + j) // ui_width + pos.y x = (i + j) % ui_width + pos.x else: x = i % ui_width + pos.x if x < 0: if num + x >= max(pos.x, 0) and pos.w + pos.x >= 0: w = min(max_w, pos.w + pos.x, num + x) pxarray[:w, y] = ((calc_shadow_color(color) for color in pxarray[:w, y]) if shadow else self.data[offset - x:offset - x + w]) elif x <= max_w: w = min(max_w - x, num) pxarray[x:x + w, y] = ((calc_shadow_color(color) for color in pxarray[x:x + w, y]) if shadow else self.data[offset:offset + w]) offset += num i += num
def blit_to(self, surface, rect, layer): pxarray = pg.PixelArray(surface) dst_rect = surface.get_rect().inflate(32, 16) sy = rect.y // 16 - 1 sx = rect.x // 32 - 1 dy = (rect.y + rect.h) // 16 + 2 dx = (rect.x + rect.w) // 32 + 2 y_pos = sy * 16 - 8 - rect.y for y in range(sy, dy): for h in range(2): x_pos = sx * 32 + h * 16 - 16 - rect.x for x in range(sx, dx): if dst_rect.collidepoint(x_pos, y_pos): bitmap = self.get_tile_bitmap(x, y, h, layer) if bitmap is None: if layer: continue bitmap = self.get_tile_bitmap(0, 0, 0, layer) bitmap.blit_to(surface, (x_pos, y_pos), pxarray=pxarray) x_pos += 32 y_pos += 8