comparison eclviewer.py @ 18:ca26a84916cb

Add preliminary ECL viewer/interpreter.
author Thibaut Girka <thib@sitedethib.com>
date Tue, 09 Aug 2011 11:40:48 +0200
parents
children ca7886296d4a
comparison
equal deleted inserted replaced
17:d940d004b840 18:ca26a84916cb
1 #!/usr/bin/env python
2
3 import sys
4 import os
5
6 import struct
7 from math import degrees, radians
8 from io import BytesIO
9 from itertools import chain
10
11 import pygame
12
13 from pytouhou.formats.pbg3 import PBG3
14 from pytouhou.formats.std import Stage
15 from pytouhou.formats.ecl import ECL
16 from pytouhou.formats.anm0 import Animations
17 from pytouhou.game.background import Background
18 from pytouhou.game.enemymanager import EnemyManager
19 from pytouhou.opengl.texture import TextureManager
20
21 import OpenGL
22 OpenGL.FORWARD_COMPATIBLE_ONLY = True
23 from OpenGL.GL import *
24 from OpenGL.GLU import *
25
26
27 def main(path, stage_num):
28 # Initialize pygame
29 pygame.init()
30 window = pygame.display.set_mode((384, 448), pygame.OPENGL | pygame.DOUBLEBUF)
31
32 # Initialize OpenGL
33 glMatrixMode(GL_PROJECTION)
34 glLoadIdentity()
35 gluPerspective(30, float(window.get_width())/window.get_height(), 101010101./2010101., 101010101./10101.)
36
37 glEnable(GL_BLEND)
38 glEnable(GL_TEXTURE_2D)
39 glEnable(GL_FOG)
40 glHint(GL_FOG_HINT, GL_NICEST)
41 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
42 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
43 glEnableClientState(GL_VERTEX_ARRAY)
44 glEnableClientState(GL_TEXTURE_COORD_ARRAY)
45
46 # Load data
47 with open(path, 'rb') as file:
48 archive = PBG3.read(file)
49 texture_manager = TextureManager(archive)
50
51 stage = Stage.read(BytesIO(archive.extract('stage%d.std' % stage_num)), stage_num)
52
53 ecl = ECL.read(BytesIO(archive.extract('ecldata%d.ecl' % stage_num)))
54 enemies_anim = Animations.read(BytesIO(archive.extract('stg%denm.anm' % stage_num)))
55 anims = [enemies_anim]
56 try:
57 enemies2_anim = Animations.read(BytesIO(archive.extract('stg%denm2.anm' % stage_num)))
58 except KeyError:
59 pass
60 else:
61 anims.append(enemies_anim)
62 enemy_manager = EnemyManager(stage, anims, ecl)
63
64 background_anim = Animations.read(BytesIO(archive.extract('stg%dbg.anm' % stage_num)))
65 background = Background(stage, background_anim)
66
67 print(enemy_manager.stage.name)
68
69 frame = 0
70
71 # Main loop
72 clock = pygame.time.Clock()
73 while True:
74 # Check events
75 for event in pygame.event.get():
76 if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key in (pygame.K_ESCAPE, pygame.K_q)):
77 sys.exit(0)
78 elif event.type == pygame.KEYDOWN:
79 if event.key == pygame.K_RETURN and event.mod & pygame.KMOD_ALT:
80 pygame.display.toggle_fullscreen()
81
82 # Update game
83 enemy_manager.update(frame)
84 background.update(frame)
85
86 # Draw everything
87 glClear(GL_COLOR_BUFFER_BIT)
88
89 fog_b, fog_g, fog_r, _, fog_start, fog_end = background.fog_interpolator.values
90 x, y, z = background.position_interpolator.values
91 unknownx, dy, dz = background.position2_interpolator.values
92
93 glFogi(GL_FOG_MODE, GL_LINEAR)
94 glFogf(GL_FOG_START, fog_start)
95 glFogf(GL_FOG_END, fog_end)
96 glFogfv(GL_FOG_COLOR, (fog_r / 255., fog_g / 255., fog_b / 255., 1.))
97
98 #TODO
99 glMatrixMode(GL_MODELVIEW)
100 glLoadIdentity()
101 # Some explanations on the magic constants:
102 # 192. = 384. / 2. = width / 2.
103 # 224. = 448. / 2. = height / 2.
104 # 835.979370 = 224./math.tan(math.radians(15)) = (height/2.)/math.tan(math.radians(fov/2))
105 # This is so that objects on the (O, x, y) plane use pixel coordinates
106 gluLookAt(192., 224., - 835.979370 * dz,
107 192., 224. - dy, 750 - 835.979370 * dz, 0., -1., 0.) #TODO: 750 might not be accurate
108 #print(glGetFloat(GL_MODELVIEW_MATRIX))
109 glTranslatef(-x, -y, -z)
110
111 for texture_key, (nb_vertices, vertices, uvs) in background.objects_by_texture.items():
112 glBindTexture(GL_TEXTURE_2D, texture_manager[texture_key])
113 glVertexPointer(3, GL_FLOAT, 0, vertices)
114 glTexCoordPointer(2, GL_FLOAT, 0, uvs)
115 glDrawArrays(GL_QUADS, 0, nb_vertices)
116
117 #TODO
118 glMatrixMode(GL_MODELVIEW)
119 glLoadIdentity()
120 # Some explanations on the magic constants:
121 # 192. = 384. / 2. = width / 2.
122 # 224. = 448. / 2. = height / 2.
123 # 835.979370 = 224./math.tan(math.radians(15)) = (height/2.)/math.tan(math.radians(fov/2))
124 # This is so that objects on the (O, x, y) plane use pixel coordinates
125 gluLookAt(192., 224., - 835.979370,
126 192., 224., 750 - 835.979370, 0., -1., 0.) #TODO: 750 might not be accurate
127
128 glDisable(GL_FOG)
129 for texture_key, (nb_vertices, vertices, uvs) in enemy_manager.objects_by_texture.items():
130 glBindTexture(GL_TEXTURE_2D, texture_manager[texture_key])
131 glVertexPointer(3, GL_FLOAT, 0, vertices)
132 glTexCoordPointer(2, GL_FLOAT, 0, uvs)
133 glDrawArrays(GL_QUADS, 0, nb_vertices)
134 glEnable(GL_FOG)
135
136 pygame.display.flip()
137 clock.tick(120)
138 frame += 1
139
140
141
142 try:
143 file_path, stage_num = sys.argv[1:]
144 stage_num = int(stage_num)
145 except ValueError:
146 print('Usage: %s std_dat_path stage_num' % sys.argv[0])
147 else:
148 main(file_path, stage_num)
149