예제 #1
0
 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()
예제 #2
0
 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)
예제 #3
0
 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()
예제 #4
0
 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)
예제 #5
0
 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)
예제 #6
0
 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()
예제 #7
0
    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
예제 #8
0
    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
예제 #9
0
    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