pykiss

Python Kisekae set viewer
git clone https://code.literati.org/pykiss.git
Log | Files | Refs | LICENSE

pykiss (8777B)


      1 #!/usr/bin/python
      2 # Copyright (C) 2003 Sean R. Lynch <seanl@chaosring.org>
      3 #
      4 # This program is free software; you can redistribute it and/or modify
      5 # it under the terms of the GNU General Public License as published by
      6 # the Free Software Foundation; either version 2 of the License, or
      7 # (at your option) any later version.
      8 #
      9 # This program is distributed in the hope that it will be useful,
     10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 # GNU General Public License for more details.
     13 #
     14 # You should have received a copy of the GNU General Public License
     15 # along with this program; if not, write to the Free Software
     16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     17 
     18 import sys
     19 import pygame #, pygame.image, pygame.font, pygame.mixer
     20 from pygame.locals import *
     21 from Numeric import *
     22 import kiss
     23 
     24 LHACMD = "lha x"
     25 
     26 
     27 class Cel(kiss.Cel):
     28     def convert(self, mode, data):
     29         self.mode = mode
     30         if mode == "P":
     31             self.palsurf = pygame.image.fromstring(data, (self.width,
     32                                                           self.height), 'P')
     33             self.palsurf.set_colorkey(0, RLEACCEL)
     34             self.surface = self.palsurf.convert_alpha()
     35         else:
     36             self.surface = pygame.image.fromstring(data, (self.width,
     37                                                           self.height),
     38                                                    'RGBA').convert_alpha()
     39 
     40         self.alpha = pygame.surfarray.array_alpha(self.surface)
     41 
     42     def set_transparent(self, reloffset):
     43         kiss.Cel.set_transparent(self, reloffset)
     44         a = pygame.surfarray.pixels_alpha(self.surface)
     45         a[:] = (self.alpha * (255 - self.transparent) / 255).astype(UInt8)
     46 
     47     def set_palette(self, palette):
     48         kiss.Cel.set_palette(self, palette)
     49         self.palsurf.set_palette(palette)
     50         self.palsurf.set_alpha(255 - self.transparent)
     51         self.surface = self.palsurf.convert_alpha()
     52 
     53     def pixcollide(self, other, (x1, y1), (x2, y2), (w, h)):
     54         if self.alpha[x1:x1+w, y1:y1+h] & other.alpha[x2:x2+w, y2:y2+h]:
     55             return 1
     56         else: return 0
     57 
     58     def is_pixel_set(self, (x, y)):
     59         return self.alpha[x, y]
     60 
     61         
     62 class KissViewer:
     63     def __init__(self, cnf):
     64         self.kiss = kiss.KiSS(cnf, self, cel_class=Cel)
     65         self.surface = pygame.display.set_mode((self.kiss.width,
     66                                                 self.kiss.height))
     67         self.viewport_pos = (0, 0)
     68         #self.rects = []
     69 
     70     # Methods called by the KiSS instance
     71     def draw(self, cels):
     72         l, t = self.viewport_pos
     73         surface = self.surface
     74         surface.fill(self.kiss.get_bordercol())
     75         for cel in cels:
     76             x, y = cel.get_pos()
     77             if cel.mapped: surface.blit(cel.surface, (x-l, y-t))
     78 
     79         pygame.display.flip()
     80 
     81     def start_drag(self):
     82         self.dragging = 1
     83 
     84     def end_drag(self):
     85         self.dragging = 0
     86 
     87     def sound(self, filename):
     88         sound = pygame.mixer.Sound(filename)
     89         sound.play()
     90 
     91     def windowsize(self, size):
     92         self.surface = self.display.set_mode(size)
     93 
     94     def viewport(self, pos):
     95         self.viewport_pos = pos
     96         
     97     def get_mousepos(self):
     98         return pygame.mouse.get_pos()
     99 
    100     def music(self, filename):
    101         pygame.mixer.music.load(filename)
    102         pygame.mixer.music.play(-1)
    103         
    104     # External methods
    105     def run(self):
    106         self.dragging = 0
    107         
    108         self.kiss.start()
    109         pygame.time.set_timer(USEREVENT, 10)
    110         while 1:
    111             event = pygame.event.wait()
    112             if event.type == USEREVENT:
    113                 # Eat all timer events from the queue
    114                 pygame.event.get(USEREVENT)
    115                 self.kiss.pulse()
    116             elif event.type == QUIT:
    117                 self.kiss.end()
    118                 return
    119             elif event.type == MOUSEMOTION:
    120                 if self.dragging:
    121                     # Only process the last one in the queue
    122                     events = pygame.event.get(MOUSEMOTION)
    123                     if events: event = events[-1]
    124                     self.kiss.drag(event.pos)
    125             elif event.type == MOUSEBUTTONDOWN:
    126                 self.kiss.press(event.pos)
    127             elif event.type == MOUSEBUTTONUP:
    128                 self.kiss.release(event.pos)
    129             elif event.type == KEYDOWN:
    130                 if event.key == K_ESCAPE:
    131                     self.kiss.end()
    132                     return
    133                 elif event.key == K_f:
    134                     pygame.display.toggle_fullscreen()
    135                 elif event.key == K_u:
    136                     self.kiss.unfix(pygame.mouse.get_pos())
    137                 elif event.key == K_t:
    138                     self.kiss.make_transparent(pygame.mouse.get_pos())
    139                 elif event.key == K_0:
    140                     if event.mod & KMOD_CTRL:
    141                         self.kiss.changecol(0)
    142                     else: self.kiss.changeset(0)
    143                 elif event.key == K_1:
    144                     if event.mod & KMOD_CTRL:
    145                         self.kiss.changecol(1)
    146                     else: self.kiss.changeset(1)
    147                 elif event.key == K_2:
    148                     if event.mod & KMOD_CTRL:
    149                         self.kiss.changecol(2)
    150                     else: self.kiss.changeset(2)
    151                 elif event.key == K_3:
    152                     if event.mod & KMOD_CTRL:
    153                         self.kiss.changecol(3)
    154                     else: self.kiss.changeset(3)
    155                 elif event.key == K_4:
    156                     if event.mod & KMOD_CTRL:
    157                         self.kiss.changecol(4)
    158                     else: self.kiss.changeset(4)
    159                 elif event.key == K_5:
    160                     if event.mod & KMOD_CTRL:
    161                         self.kiss.changecol(5)
    162                     else: self.kiss.changeset(5)
    163                 elif event.key == K_6:
    164                     if event.mod & KMOD_CTRL:
    165                         self.kiss.changecol(6)
    166                     else: self.kiss.changeset(6)
    167                 elif event.key == K_7:
    168                     if event.mod & KMOD_CTRL:
    169                         self.kiss.changecol(7)
    170                     else: self.kiss.changeset(7)
    171                 elif event.key == K_8:
    172                     if event.mod & KMOD_CTRL:
    173                         self.kiss.changecol(8)
    174                     else: self.kiss.changeset(8)
    175                 elif event.key == K_9:
    176                     if event.mod & KMOD_CTRL:
    177                         self.kiss.changecol(9)
    178                     else: self.kiss.changeset(9)
    179         
    180 
    181 def choose(surface, items):
    182     """Choose from a list of choices. Return the choice."""
    183 
    184     choices = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    185     font = pygame.font.Font(None, 12)
    186     linesize = font.get_linesize()
    187     y = linesize
    188     i = 0
    189     for item in items:
    190         s = font.render("%s) %s" % (choices[i], item), 1, (255, 255, 255, 255))
    191         surface.blit(s, (0, y))
    192         y += linesize
    193         i += 1
    194 
    195     pygame.display.update()
    196 
    197     while 1:
    198         event = pygame.event.wait()
    199         if event.type == KEYDOWN:
    200             if event.key == K_ESCAPE: sys.exit()
    201             key = str(event.unicode)
    202             choice = choices.find(key)
    203             if choice > -1: return items[choice]
    204         
    205 
    206 if __name__ == '__main__':
    207     import os
    208     if len(sys.argv) < 2 or len(sys.argv) > 3:
    209         print >> sys.stderr, """
    210 Usage: %s (<archive.lzh> [<cnffile>] | <cnffile>)
    211 
    212 Use number keys to change sets, and ctrl+number to change palette.
    213 """ % sys.argv[0]
    214         sys.exit(1)
    215         
    216     filename = os.path.abspath(sys.argv[1])
    217     tempdir = None
    218 
    219     # Set up the display in case we need to ask about the cnf file
    220     pygame.init()
    221     surface = pygame.display.set_mode((640, 480), HWSURFACE|DOUBLEBUF)
    222 
    223     base, ext = os.path.splitext(filename)
    224     try:
    225         if ext.lower() == ".lzh":
    226             # It's a lzh archive
    227             import tempfile
    228             tempdir = tempfile.mktemp()
    229             os.mkdir(tempdir)
    230             os.chdir(tempdir)
    231             os.system(LHACMD + " " + filename)
    232             if len(sys.argv) >= 3: cnf = sys.argv[2]
    233             else:
    234                 import glob
    235                 cnffiles = glob.glob("*.cnf") + glob.glob("*.CNF")
    236                 if len(cnffiles) == 1: cnf = cnffiles[0]
    237                 else: cnf = choose(surface, cnffiles)
    238         else:
    239             dirname, cnf = os.path.split(filename)
    240             if dirname: os.chdir(dirname)
    241     
    242             
    243         k = KissViewer(cnf)
    244         k.run()
    245     finally:
    246         if tempdir:
    247             import shutil
    248             shutil.rmtree(tempdir)
    249         
    250 
    251