#!/usr/bin/perl -w use strict; use warnings; use OpenGL qw(:all); use OpenGL::Image; use Math::Trig; my $WIDTH = 1024; my $HEIGHT = 768; my $sfactor = 1.0; glutInit(); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); glutInitWindowSize($WIDTH, $HEIGHT); glutInitWindowPosition(100, 100); sub bin2hex { return sprintf("%02x", $_[0]); } my @steps_types = qw(Hard Soft none); my @weather_types = qw(None Rain SandStorm Snow); my @spawn_types = qw(General Alpha Bravo Charlie Delta AlphaFlag BravoFlag Grenades Medkits Clusters Vest Flamer Berserker Predator YellowFlag RamboBow StatGun); my @poly_types = qw(Normal OnlyBulletsCollide OnlyPlayersCollide NoCollide Ice Deadly BloodyDeadly Hurts Regenerates Lava); my @scenery_types = qw(BehindAll BehindMap BehindNone); my @polygons; my @scenery; my %scenery_tex; my @props; my $buff; my $file = "SummerShower.PMS"; if ($#ARGV > -1 ) { $file = $ARGV[0]; } #open HANDLE, " $v1_x, v1_y => $v1_y, v1_z => $v1_z, v1_rhw => $v1_rhw, v1_blue => $v1_blue, v1_green => $v1_green, v1_red => $v1_red, v1_alpha => $v1_alpha, v1_tu => $v1_tu, v1_tv => $v1_tv, v2_x => $v2_x, v2_y => $v2_y, v2_z => $v2_z, v2_rhw => $v2_rhw, v2_blue => $v2_blue, v2_green => $v2_green, v2_red => $v2_red, v2_alpha => $v2_alpha, v2_tu => $v2_tu, v2_tv => $v2_tv, v3_x => $v3_x, v3_y => $v3_y, v3_z => $v3_z, v3_rhw => $v3_rhw, v3_blue => $v3_blue, v3_green => $v3_green, v3_red => $v3_red, v3_alpha => $v3_alpha, v3_tu => $v3_tu, v3_tv => $v3_tv, p1_x => $p1_x, p1_y => $p1_y, p1_z => $p1_z, p2_x => $p2_x, p2_y => $p2_y, p2_z => $p2_z, p3_x => $p3_x, p3_y => $p3_y, p3_z => $p3_z, type => $type ); push @polygons, \%poly; } # Sector division read HANDLE, $buff, 4; my ($sector_division) = unpack("l", $buff); # Num sectors read HANDLE, $buff, 4; my ($num_sectors) = unpack("l", $buff); my $topoffs = $sector_division * $num_sectors; my $bottomoffs = $sector_division * -$num_sectors; my $rightoffs = $sector_division * $num_sectors; my $leftoffs = $sector_division * -$num_sectors; # Get sectors my $sector_count = (($num_sectors*2)+1) * (($num_sectors*2)+1); for (my $i = 0; $i < $sector_count; $i++) { read HANDLE, $buff, 2; my ($poly_count) = unpack("S", $buff); for (my $j = 0; $j < $poly_count; $j++) { read HANDLE, $buff, 2; } } # Num props read HANDLE, $buff, 4; my ($num_props) = unpack("l", $buff); # get props for (my $i = 0; $i < $num_props; $i++) { read HANDLE, $buff, 44; my ( $p_act, $p_filler1, $p_style, $p_width, $p_height, $p_x, $p_y, $p_rot, $p_scaleX, $p_scaleY, $p_alpha, $p_filler2_1, $p_filler2_2, $p_filler2_3, $p_blue, $p_green, $p_red, $p_alpha2, $p_drawbehind, $p_filler3_1, $p_filler3_2, $p_filler3_3 ) = unpack("c c S l l ff f ff c ccc cccc c ccc", $buff); my %prop = ( p_style => $p_style, p_height => $p_height, p_width => $p_width, p_x => $p_x, p_y => $p_y, p_rot => $p_rot, p_scaleX => $p_scaleX, p_scaleY => $p_scaleY, p_red => $p_red, p_blue => $p_blue, p_green => $p_green, p_alpha => $p_alpha, p_drawbehind => $scenery_types[$p_drawbehind] ); push @props, \%prop; } # num sceneries read HANDLE, $buff, 4; my ($num_sceneries) = unpack("l", $buff); # get scenery list for (my $i = 0; $i < $num_sceneries; $i++) { read HANDLE, $buff, 55; my ($scen_name) = unpack("c/A", $buff); push @scenery, $scen_name; my $scen_path = "Scenery-gfx/$scen_name"; if (-f $scen_path) { my $scen_tex = new OpenGL::Image(source => $scen_path); if ($scen_tex) { my($s_tw,$s_th) = $scen_tex->Get('width','height'); print "Loaded $scen_path ($s_tw x $s_th)\n"; $scenery_tex{$scen_name} = $scen_tex; } } else { print "Couldnt find $scen_name\n"; } } # num colliders read HANDLE, $buff, 4; my ($num_colliders) = unpack("l", $buff); # Get colliders for (my $i = 0; $i < $num_colliders; $i++) { read HANDLE, $buff, 16; my ($c_active, $c_filler1, $c_filler2, $c_filler3, $c_x, $c_y, $c_rad ) = unpack("c ccc fff", $buff); } # num spawnpoints read HANDLE, $buff, 4; my ($num_spawnpoints) = unpack("l", $buff); # Get spawn points for (my $i = 0; $i < $num_spawnpoints; $i++) { read HANDLE, $buff, 16; my ($sp_active, $sp_f1, $sp_f2, $sp_f3, $sp_x, $sp_y, $sp_team ) = unpack("c ccc ll c", $buff); } # num waypoints read HANDLE, $buff, 4; my ($num_waypoints) = unpack("l", $buff); # Murder handle close HANDLE; print "\n--------------------\n"; # Debug print "Name: $name\n"; print "Version: $ver\n"; print "Texture: $tex\n"; print "Top color: ".bin2hex($top_blue).bin2hex($top_green).bin2hex($top_red)." $top_alpha%\n"; print "Bottom color: ".bin2hex($bottom_blue).bin2hex($bottom_green).bin2hex($bottom_red)." $bottom_alpha%\n"; print "Jets: $jets \n"; print "Nades: $nades\n"; print "Medkits: $medkits\n"; print "Weather: ".$weather_types[$weather]."\n"; print "Steps: ".$steps_types[$steps]."\n"; print "RandID: $randid\n"; print "Polycount: $num_polys\n"; print "Sector Division: $sector_division\n"; print "Sectorcount: $num_sectors\n"; print "Propcount: $num_props\n"; print "Scenery count: $num_sceneries\n"; print "Collider count: $num_colliders\n"; print "Spawnpoint count: $num_spawnpoints\n"; print "Waypoint count: $num_waypoints\n"; my $tex_path = "Textures/$tex"; my $show_tex = 0; my ($tex_r, $ifmt, $fmt, $type, $tw, $th); if ( -f $tex_path) { $show_tex = 1; } else { print "$tex_path not found\n"; } $tex_r = new OpenGL::Image(source => $tex_path); if ($tex_r) { ($ifmt,$fmt,$type) = $tex_r->Get('gl_internalformat','gl_format','gl_type'); ($tw,$th) = $tex_r->Get('width','height'); } # do polygon shit here sub displayFunc { glClear(GL_COLOR_BUFFER_BIT); glDisable(GL_TEXTURE_2D); # background gradient glBegin(GL_POLYGON); glColor4f($top_red/255.0, $top_green/255.0, $top_blue/255.0, $top_alpha/255.0); glVertex2f($leftoffs, -$topoffs); glVertex2f($rightoffs, -$topoffs); glColor4f($bottom_red/255.0, $bottom_green/255.0, $bottom_blue/255.0, $bottom_alpha/255.0); glVertex2f($rightoffs, -$bottomoffs); glVertex2f($leftoffs, -$bottomoffs); glEnd(); glEnable(GL_TEXTURE_2D); # bg scenery foreach my $p (@props) { next if $p->{"p_drawbehind"} eq 'BehindNone'; unless (exists $scenery[$p->{"p_style"}]) { next; } else { } my $scen_name = $scenery[$p->{"p_style"}]; my $scen_tex; my $go = 0; if (exists $scenery_tex{$scen_name}) { $scen_tex = $scenery_tex{$scen_name}; $go = 1; } if ($go) { glPushMatrix(); glTranslatef($p->{"p_x"}, $p->{"p_y"}, 0.0); glRotatef($p->{"p_rot"} * (180.0/pi), 0.0, 0.0, 1.0); glScalef($p->{"p_scaleX"}, $p->{"p_scaleY"}, 0.0); my($s_ifmt,$s_fmt,$s_type) = $scen_tex->Get('gl_internalformat','gl_format','gl_type'); my($s_tw,$s_th) = $scen_tex->Get('width','height'); glTexImage2D_c(GL_TEXTURE_2D, 0, $s_ifmt, $s_tw, $s_th, 0, $s_fmt, $s_type, $scen_tex->Ptr()); #glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); #glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glBegin(GL_QUADS); #glColor4f($p->{"p_red"}/255.0, $p->{"p_green"}/255.0, $p->{"p_blue"}/255.0, $p->{"p_alpha"}/255.0); glTexCoord3f(0.0, 1.0, 0.0); glVertex3f(0.0, 0.0, 0.0); glTexCoord3f(1.0, 1.0, 0.0); glVertex3f($p->{"p_width"}, 0.0, 0.0); glTexCoord3f(1.0, 0.0, 0.0); glVertex3f($p->{"p_width"}, -$p->{"p_height"}, 0.0); glTexCoord3f(0.0, 0.0, 0.0); glVertex3f(0.0, -$p->{"p_height"}, 0.0); glEnd(); glPopMatrix(); } } # textures glEnable(GL_TEXTURE_2D); if ($show_tex && $tex_r) { glBindTexture(GL_TEXTURE_2D, $tex_r); glTexImage2D_c(GL_TEXTURE_2D, 0, $ifmt, $tw, $th, 0, $fmt, $type, $tex_r->Ptr()); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } # polygons glBegin(GL_TRIANGLES); foreach my $p (@polygons) { for (my $i = 1; $i <= 3; $i++) { glColor4f( $p->{"v".$i."_red"}/255.0, $p->{"v".$i."_green"}/255.0, $p->{"v".$i."_blue"}/255.0, $p->{"v".$i."_alpha"}/255.0 ); glTexCoord3f( $p->{"v".$i."_tu"}, -$p->{"v".$i."_tv"}, 1.0 / $p->{"v".$i."_rhw"}, ); glVertex3f( $p->{"v".$i."_x"}, $p->{"v".$i."_y"}, 0.0 ); } } glEnd(); glLoadIdentity(); gluOrtho2D($leftoffs * $sfactor, $rightoffs * $sfactor, $topoffs * $sfactor, $bottomoffs * $sfactor); glTranslatef(0.0, 0.0, 0.0); glFlush(); glutSwapBuffers(); } glutCreateWindow($name); glClearColor(0.0, 0.0, 0.0, 0.0); glColor3f(0.0, 0.0, 1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluOrtho2D(-3000.0, 3000.0, 3000.0, -3000.0); glEnable(GL_BLEND); glEnable(GL_TEXTURE_2D); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glutDisplayFunc(\&displayFunc); #glutIdleFunc(\&displayFunc); #glutReshapeFunc(reshape); #glutKeyboardFunc(keyboard); glutMainLoop();