Initial commit from version 1e-99
[beatscape.git] / game.py
1 import pygame
2 import thread
3
4 from keygraph import *
5 from keyfile import *
6 from bmevent import *
7 from formats import *
8 from chanman import *
9 from keyhandler import *
10 import config
11
12 events = []
13 evlock = thread.allocate_lock()
14 evrun = 1
15 t_orig = 0
16
17 def event_thread():
18         global events,evlock,t_orig
19         while evrun:
20                 e = pygame.event.wait()
21                 t = pygame.time.get_ticks() - t_orig
22                 evlock.acquire()
23                 events.append((t,e))
24                 evlock.release()
25
26 def event_thread_start():
27         global evrun
28         evrun = 1
29         thread.start_new_thread(event_thread,())
30
31 def event_thread_stop():
32         global evrun
33         evrun = 0
34         pygame.event.post(pygame.event.Event(pygame.NOEVENT,{}))
35
36 def get_events():
37         global events,evlock
38         evlock.acquire()
39         eold = events
40         events = []
41         evlock.release()
42         return eold
43
44 def playgame(gameconfig,song):
45         global t_orig
46         k = kf_load(song)
47
48         dm = eval(gameconfig['format'] + '(k)');
49         cm = ChannelManager(k);
50         kh = KeyHandler(gameconfig,k);
51
52         # No background anims? No problem!
53         if not k.bmps:
54                 print "IT'S PEANUT BUTTER JELLY TIME!"
55                 for x in range(0,8):
56                         k.bmps[x] = pygame.transform.scale(pygame.image.load("gfx/banana%d.png" % x).convert(), (256,256))
57                 lastbeat = k.bmelist[-1].beat
58                 i = 0.0
59                 j = 0
60                 while i < lastbeat:
61                         k.add(BMEvent(i,BME_BGA,None,j))
62                         j = (j+1) % 8
63                         i += 0.25
64                 k.sort()
65         
66         li = BMEListIter(k.bmelist)
67         reaper_li = BMEListIter(k.bmelist)
68         t_finish = k.length() + 5000
69
70         t_orig = pygame.time.get_ticks()
71         try:
72                 if k.offset < 0:
73                         t_orig -= int(k.offset * 1000)
74         except NameError:
75                 pass
76         b = b_l = k.eval_beatfunc(t_orig)
77
78         event_thread_start()
79
80         animpic = None
81         while 1:
82                 t = pygame.time.get_ticks() - t_orig
83                 b = k.eval_beatfunc(t)
84                 print t,b,b_l
85                 db = b - b_l
86                 b_l = b
87                 li.goto(b)
88                 bmelist = li.window(db)
89                 dm.draw(t + 45, bmelist)
90                 for bme in bmelist:
91                         if bme.type == BME_BGM:
92                                 cm.play(bme);
93                         if bme.type == BME_TEMPO:
94                                 bpm = bme.dataref
95                                 kh.setproperties({'bpm': bme.dataref})
96
97                 for (t,e) in get_events():
98                         r = kh.handle(e,t)
99                         if r:
100                                 (hitbme, properties) = r
101                                 if hitbme:
102                                         cm.play(hitbme)
103                                 dm.setproperties(properties)
104
105                         if e.type == pygame.KEYDOWN:
106                                 if e.key == pygame.K_ESCAPE:
107                                         event_thread_stop()
108                                         pygame.mixer.stop()
109                                         return False
110                                 elif e.key == pygame.K_PRINT:
111                                         pygame.image.save(screen,"screenshot.bmp")
112
113                 reaper_li.goto(b - 2.0)
114                 bmelist = reaper_li.window(1.0, BME_NOTE1 | BME_NOTE2)
115                 for bme in bmelist:
116                         dm.setproperties({'judgement': JUDGE_POOR})
117                         bme.type = BME_HIT
118
119                 if t > t_finish:
120                         event_thread_stop()
121                         return True
122
123 # Hmm. This is sort of braindead, isn't it?
124 class Game:
125         def __init__(self,song):
126                 self.song = song
127
128         def run(self):
129                 print "Playing",self.song
130                 # IIDX is hardcoded for now
131                 playgame(config.gametypes['IIDX'], self.song)
132                 return ['fileselect']