Beispiel #1
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)
Beispiel #2
0
class GOPLike(Object):
    """
    类GOP.MKF的存储格式的mkf文件的解码器
    GOP文件结构:(gop.mkf)
    图元集,GOP属于子包结构,其中有226个图元包,其内每个图元均为RLE,形状是菱形,而且其大小为32*15像素
    """
    def __init__(self, path):
        self.data = {}
        self.mkf = MKFDecoder(path)

    def __getitem__(self, key):
        if key in self.data:
            return self.data[key]
        elif 0 <= key <= self.mkf.count:
            data = self.mkf.read(key)
            if len(data):
                self[key] = SubPlace(data)
                return self[key]
            else:
                return None
        else:
            raise KeyError(key)

    def __setitem__(self, key, item):
        self.data[key] = item
Beispiel #3
0
 def load(self, index):
     try:
         name = open('./Musics/%.3d.mid' % index, 'rb')
         self.midifile = mido.MidiFile(file=name)
         return True
     except (FileNotFoundError, ValueError):
         try:
             midi_mkf = MKFDecoder('midi.mkf', yj1=False)
             data = midi_mkf.read(index, True)
         except Exception:
             data = ''
         if len(data):
             name = BytesIO(data)
             self.midifile = mido.MidiFile(file=name)
             return True
         else:
             self.midifile = mido.MidiFile()
             return False
Beispiel #4
0
class RNG(MKFDecoder):
    """
    过场动画(RNG.mkf)
    RNG文件经过MKF解开后,每个子文件仍然是一个经过MKF压缩的文件,
    然后再次经过MKF解开后,其子文件是一个YJ1压缩的文件(够复杂吧,
    大量的解压缩需要高的CPU资源,仙剑在386时代就能很好的完成,呵呵,厉害)。

    以第一次解开的MKF文件为例子,假如该文件为1.RNG,
    对该文件再次进行MKF解压后,会得到若干个小的文件
    (1_01,1_02,1_03……),这些小文件中(需要再次经过DEYJ1解压),
    第一个文件通过比较大,而其后的文件比较小,这是由于其第一个文件是描述动画的第一帧,
    而以后的文件只描述在第一帧上进行变化的数据。

    在描述变化信息的文件中,由于不包含变化位置的坐标信息,
    因此也总是从动画位置的左上角(0,0)开始的,依次描述变化,
    直至无变化可描述以止则结束(因此如果当前帧和前一帧变化较大,
    则描述文件会比较大)。

    RNG图片也是320×200的
    """
    def __init__(self):
        super(RNG, self).__init__('rng.mkf', yj1=False)

    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 finish_current_video(self):
        del self.pxarray
        del self.video
        del self.frame_index
        del self.image

    def has_next_frame(self):
        return self.frame_index < self.video.count

    def read_byte(self):
        return self.data.popleft()

    def read_short(self):
        return self.data.popleft() | (self.data.popleft() << 8)

    def set_byte(self, color=None):
        y, x = divmod(self.dst_ptr, 320)
        color = self.read_byte() if color is None else color
        self.pxarray[x, y] = color
        self.dst_ptr += 1

    def render(self):
        """
        解开帧动画
        @param data: 字符串形式的数据
        """
        self.dst_ptr = 0
        bdata = wdata = ddata = 0

        while True:
            bdata = self.read_byte()
            if bdata in {0x00, 0x13} or not len(self.data):
                return
            elif bdata == 0x02:
                self.dst_ptr += 2
            elif bdata == 0x03:
                bdata = self.read_byte()
                self.dst_ptr += (bdata + 1) << 1
            elif bdata == 0x04:
                wdata = self.read_short()
                self.dst_ptr += (wdata + 1) << 1
            elif 0x06 <= bdata <= 0x0a:
                for _ in range(bdata, 0x05, -1):
                    self.set_byte()
                    self.set_byte()
            elif bdata == 0x0b:
                bdata = self.read_byte()
                for _ in range(bdata + 1):
                    self.set_byte()
                    self.set_byte()
            elif bdata == 0x0c:
                ddata = self.read_short()
                for _ in range(ddata + 1):
                    self.set_byte()
                    self.set_byte()
            elif 0x0d <= bdata <= 0x10:
                color1, color2 = self.read_byte(), self.read_byte()
                for _ in range(bdata - 0x0b):
                    self.set_byte(color1)
                    self.set_byte(color2)
            elif bdata == 0x11:
                bdata = self.read_byte()
                color1, color2 = self.read_byte(), self.read_byte()
                for _ in range(bdata + 1):
                    self.set_byte(color1)
                    self.set_byte(color2)
            elif bdata == 0x12:
                ddata = self.read_short()
                color1, color2 = self.read_byte(), self.read_byte()
                for _ in range(ddata + 1):
                    self.set_byte(color1)
                    self.set_byte(color2)

    def get_next_frame(self):
        """
        @member data: 两次MKFDecoder加上YJ_1Decoder解析之后得到的帧信息(字符串)
        @member info: self.data经过blit处理以后的数据(Byte数组)
        """
        self.data = deque(self.video.read(self.frame_index))

        if self.data:
            self.render()
            self.image.unlock()
        if self.has_next_frame():
            self.frame_index += 1
        return self.image
Beispiel #5
0
 def __init__(self):
     MKFDecoder.__init__(self, 'rgm.mkf', yj1=False)
Beispiel #6
0
 def __init__(self, path):
     self.data = {}
     self.mkf = MKFDecoder(path)
Beispiel #7
0
 def __init__(self):
     self.sounds = MKFDecoder('sounds.mkf' if is_win95 else 'voc.mkf',
                              yj1=False)