… | |
… | |
1019 | $fps = $fps * 0.95 + 1 / (($NOW - $LAST_REFRESH) || 0.1) * 0.05; |
1019 | $fps = $fps * 0.95 + 1 / (($NOW - $LAST_REFRESH) || 0.1) * 0.05; |
1020 | debug sprintf "%3.2f", $fps; |
1020 | debug sprintf "%3.2f", $fps; |
1021 | |
1021 | |
1022 | $CFClient::UI::ROOT->draw; |
1022 | $CFClient::UI::ROOT->draw; |
1023 | |
1023 | |
|
|
1024 | $WANT_REFRESH = 0; |
|
|
1025 | $CAN_REFRESH = 0; |
|
|
1026 | $LAST_REFRESH = $NOW; |
|
|
1027 | |
1024 | 0 && do { |
1028 | 0 && do { |
1025 | # some weird model-drawing code, just a joke right now |
1029 | # some weird model-drawing code, just a joke right now |
1026 | use CFClient::OpenGL; |
1030 | use CFClient::OpenGL; |
1027 | |
1031 | |
1028 | $demo{t}{eye_auv} ||= new_from_file CFClient::Texture "eye2.png" or die; |
1032 | $demo{t}{eye_auv} ||= new_from_file CFClient::Texture "eye2.png" or die; |
… | |
… | |
1039 | |
1043 | |
1040 | glDepthMask 1; |
1044 | glDepthMask 1; |
1041 | glClear GL_DEPTH_BUFFER_BIT; |
1045 | glClear GL_DEPTH_BUFFER_BIT; |
1042 | glEnable GL_TEXTURE_2D; |
1046 | glEnable GL_TEXTURE_2D; |
1043 | glEnable GL_DEPTH_TEST; |
1047 | glEnable GL_DEPTH_TEST; |
1044 | glDisable GL_CULL_FACE; |
1048 | glEnable GL_CULL_FACE; |
1045 | glShadeModel GL_SMOOTH; |
1049 | glShadeModel $::FAST ? GL_FLAT : GL_SMOOTH; |
1046 | |
1050 | |
1047 | glMatrixMode GL_PROJECTION; |
1051 | glMatrixMode GL_PROJECTION; |
1048 | glLoadIdentity; |
1052 | glLoadIdentity; |
|
|
1053 | glFrustum -1 * ($::WIDTH / $::HEIGHT), 1 * ($::WIDTH / $::HEIGHT), 1, -1, 1, 10000; |
1049 | glOrtho 0, $::WIDTH, 0, $::HEIGHT, -10000, 10000; |
1054 | #glOrtho 0, $::WIDTH, 0, $::HEIGHT, -10000, 10000; |
1050 | glMatrixMode GL_MODELVIEW; |
1055 | glMatrixMode GL_MODELVIEW; |
1051 | glLoadIdentity; |
1056 | glLoadIdentity; |
1052 | |
1057 | |
1053 | glPushMatrix; |
1058 | glPushMatrix; |
1054 | glTranslate $::WIDTH * 0.5, $::HEIGHT * 0.5; |
1059 | glTranslate 0, 0, -800; |
|
|
1060 | glScale 1, -1, 1; |
1055 | glRotate $NOW * 1000 % 36000 / 20, 0, 1, 0; |
1061 | glRotate $NOW * 1000 % 36000 / 5, 0, 1, 0; |
|
|
1062 | glRotate $NOW * 1000 % 36000 / 6, 1, 0, 0; |
|
|
1063 | glRotate $NOW * 1000 % 36000 / 7, 0, 0, 1; |
1056 | glScale 50, 50, 50; |
1064 | glScale 50, 50, 50; |
1057 | |
1065 | |
1058 | glInterleavedArrays GL_T2F_N3F_V3F, 0, $r->{v}; |
1066 | glInterleavedArrays GL_T2F_N3F_V3F, 0, $r->{v}; |
1059 | while (my ($k, $v) = each %{$r->{g}}) { |
1067 | while (my ($k, $v) = each %{$r->{g}}) { |
1060 | glBindTexture GL_TEXTURE_2D, ($demo{t}{$k}{name} or die); |
1068 | glBindTexture GL_TEXTURE_2D, ($demo{t}{$k}{name} or die); |
1061 | glDrawElements GL_TRIANGLES, $v->[0], GL_UNSIGNED_SHORT, $v->[1]; |
1069 | glDrawElements GL_TRIANGLES, $v->[0], GL_UNSIGNED_SHORT, $v->[1]; |
1062 | } |
1070 | } |
|
|
1071 | |
1063 | glPopMatrix; |
1072 | glPopMatrix; |
1064 | |
1073 | |
1065 | glShadeModel GL_FLAT; |
1074 | glShadeModel GL_FLAT; |
1066 | glDisable GL_DEPTH_TEST; |
1075 | glDisable GL_DEPTH_TEST; |
1067 | glDisable GL_TEXTURE_2D; |
1076 | glDisable GL_TEXTURE_2D; |
… | |
… | |
1069 | |
1078 | |
1070 | $WANT_REFRESH++; |
1079 | $WANT_REFRESH++; |
1071 | }; |
1080 | }; |
1072 | |
1081 | |
1073 | CFClient::SDL_GL_SwapBuffers; |
1082 | CFClient::SDL_GL_SwapBuffers; |
1074 | |
|
|
1075 | $WANT_REFRESH = 0; |
|
|
1076 | $CAN_REFRESH = 0; |
|
|
1077 | $LAST_REFRESH = $NOW; |
|
|
1078 | } |
1083 | } |
1079 | |
1084 | |
1080 | my $refresh_watcher = Event->timer (after => 0, hard => 1, interval => 1 / $MAX_FPS, cb => sub { |
1085 | my $refresh_watcher = Event->timer (after => 0, hard => 1, interval => 1 / $MAX_FPS, cb => sub { |
1081 | $NOW = time; |
1086 | $NOW = time; |
1082 | |
1087 | |
… | |
… | |
1208 | $self->set_texture ($id => $data); |
1213 | $self->set_texture ($id => $data); |
1209 | } |
1214 | } |
1210 | } |
1215 | } |
1211 | } |
1216 | } |
1212 | |
1217 | |
|
|
1218 | # hardcode /world/world_xxx_xxx map names, the savings are enourmous, |
|
|
1219 | # (server resource,s latency, bandwidth), so this hack is warranted. |
|
|
1220 | # the right fix is to make real tiled maps with an overview file |
|
|
1221 | sub conn::send_mapinfo { |
|
|
1222 | my ($self, $data, $cb) = @_; |
|
|
1223 | |
|
|
1224 | if ($self->{map_info}[0] =~ m%^/world/world_(\d\d\d)_(\d\d\d)$%) { |
|
|
1225 | my ($wx, $wy) = ($1, $2); |
|
|
1226 | |
|
|
1227 | if ($data =~ /^spatial ([1-4]+)$/) { |
|
|
1228 | my @dx = (0, 0, 1, 0, -1); |
|
|
1229 | my @dy = (0, -1, 0, 1, 0); |
|
|
1230 | my ($dx, $dy); |
|
|
1231 | |
|
|
1232 | for (split //, $1) { |
|
|
1233 | $dx += $dx[$_]; |
|
|
1234 | $dy += $dy[$_]; |
|
|
1235 | } |
|
|
1236 | |
|
|
1237 | $cb->(spatial => 15, |
|
|
1238 | $self->{map_info}[1] - $MAP->ox + $dx * 50, |
|
|
1239 | $self->{map_info}[2] - $MAP->oy + $dy * 50, |
|
|
1240 | 50, 50, |
|
|
1241 | sprintf "/world/world_%03d_%03d", $wx + $dx, $wy + $dy |
|
|
1242 | ); |
|
|
1243 | |
|
|
1244 | return; |
|
|
1245 | } |
|
|
1246 | } |
|
|
1247 | |
|
|
1248 | $self->SUPER::send_mapinfo ($data, $cb); |
|
|
1249 | } |
|
|
1250 | |
1213 | # this method does a "flood fill" into every tile direction |
1251 | # this method does a "flood fill" into every tile direction |
1214 | # it assumes that tiles are arranged in a rectangular grid, |
1252 | # it assumes that tiles are arranged in a rectangular grid, |
1215 | # i.e. a map is the same as the left of the right map etc. |
1253 | # i.e. a map is the same as the left of the right map etc. |
1216 | # failure to comply are harmless and result in display errors |
1254 | # failure to comply are harmless and result in display errors |
1217 | # at worst. |
1255 | # at worst. |
1218 | sub conn::flood_fill { |
1256 | sub conn::flood_fill { |
1219 | my ($self, $gx, $gy, $path, $hash, $flags) = @_; |
1257 | my ($self, $block, $gx, $gy, $path, $hash, $flags) = @_; |
1220 | |
1258 | |
1221 | # the server does not allow map paths > 6 |
1259 | # the server does not allow map paths > 6 |
1222 | return if 7 <= length $path; |
1260 | return if 7 <= length $path; |
1223 | |
1261 | |
1224 | my ($x0, $y0, $x1, $y1) = @{$self->{neigh_rect}}; |
1262 | my ($x0, $y0, $x1, $y1) = @{$self->{neigh_rect}}; |
1225 | |
1263 | |
1226 | for ( |
1264 | for ( |
1227 | [1, 0, -1], |
1265 | [1, 3, 0, -1], |
1228 | [2, 1, 0], |
1266 | [2, 4, 1, 0], |
1229 | [3, 0, 1], |
1267 | [3, 1, 0, 1], |
1230 | [4, -1, 0], |
1268 | [4, 2, -1, 0], |
1231 | ) { |
1269 | ) { |
1232 | my ($tile, $dx, $dy) = @$_; |
1270 | my ($tile, $tile2, $dx, $dy) = @$_; |
|
|
1271 | |
|
|
1272 | next if $block & (1 << $tile); |
|
|
1273 | my $block = $block | (1 << $tile2); |
1233 | |
1274 | |
1234 | my $gx = $gx + $dx; |
1275 | my $gx = $gx + $dx; |
1235 | my $gy = $gy + $dy; |
1276 | my $gy = $gy + $dy; |
1236 | |
1277 | |
1237 | next unless $flags & (1 << ($tile - 1)); |
1278 | next unless $flags & (1 << ($tile - 1)); |
… | |
… | |
1239 | |
1280 | |
1240 | my $neigh = $self->{neigh_map}{$hash} ||= []; |
1281 | my $neigh = $self->{neigh_map}{$hash} ||= []; |
1241 | if (my $info = $neigh->[$tile]) { |
1282 | if (my $info = $neigh->[$tile]) { |
1242 | my ($flags, $x, $y, $w, $h, $hash) = @$info; |
1283 | my ($flags, $x, $y, $w, $h, $hash) = @$info; |
1243 | |
1284 | |
1244 | $self->flood_fill ($gx, $gy, "$path$tile", $hash, $flags) |
1285 | $self->flood_fill ($block, $gx, $gy, "$path$tile", $hash, $flags) |
1245 | if $x >= $x0 && $x + $w < $x1 && $y >= $y0 && $y + $h < $y1; |
1286 | if $x >= $x0 && $x + $w < $x1 && $y >= $y0 && $y + $h < $y1; |
1246 | |
1287 | |
1247 | } else { |
1288 | } else { |
1248 | $self->send_mapinfo ("spatial $path$tile", sub { |
1289 | $self->send_mapinfo ("spatial $path$tile", sub { |
1249 | my ($mode, $flags, $x, $y, $w, $h, $hash) = @_; |
1290 | my ($mode, $flags, $x, $y, $w, $h, $hash) = @_; |
1250 | |
1291 | |
1251 | return if $mode ne "spatial"; |
1292 | return if $mode ne "spatial"; |
1252 | |
1293 | |
1253 | $x += $MAP->ox; |
1294 | $x += $MAP->ox; |
1254 | $y += $MAP->oy; |
1295 | $y += $MAP->oy; |
1255 | |
1296 | |
1256 | $self->load_map ($hash, $x, $y) |
1297 | $self->load_map ($hash, $x, $y) |
1257 | unless $self->{neigh_map}{$hash}[5]++;#d# |
1298 | unless $self->{neigh_map}{$hash}[5]++;#d# |
1258 | |
1299 | |
1259 | $neigh->[$tile] = [$flags, $x, $y, $w, $h, $hash]; |
1300 | $neigh->[$tile] = [$flags, $x, $y, $w, $h, $hash]; |
1260 | |
1301 | |
1261 | $self->flood_fill ($gx, $gy, "$path$tile", $hash, $flags) |
1302 | $self->flood_fill ($block, $gx, $gy, "$path$tile", $hash, $flags) |
1262 | if $x >= $x0 && $x + $w < $x1 && $y >= $y0 && $y + $h < $y1; |
1303 | if $x >= $x0 && $x + $w < $x1 && $y >= $y0 && $y + $h < $y1; |
1263 | }); |
1304 | }); |
1264 | } |
1305 | } |
1265 | } |
1306 | } |
1266 | } |
1307 | } |
… | |
… | |
1279 | $ox - $mapmapw * 0.5, $oy - $mapmapw * 0.5, |
1320 | $ox - $mapmapw * 0.5, $oy - $mapmapw * 0.5, |
1280 | $ox + $mapmapw * 0.5 + $w, $oy + $mapmapw * 0.5 + $h, |
1321 | $ox + $mapmapw * 0.5 + $w, $oy + $mapmapw * 0.5 + $h, |
1281 | ]; |
1322 | ]; |
1282 | |
1323 | |
1283 | delete $self->{neigh_grid}; |
1324 | delete $self->{neigh_grid}; |
1284 | $self->flood_fill (0, 0, "", $hash, $flags); |
|
|
1285 | |
1325 | |
1286 | $x += $ox; |
1326 | $x += $ox; |
1287 | $y += $oy; |
1327 | $y += $oy; |
1288 | |
1328 | |
1289 | $self->{map_info} = [$hash, $x, $y, $w, $h]; |
1329 | $self->{map_info} = [$hash, $x, $y, $w, $h]; |
1290 | |
1330 | |
1291 | my $map = $self->{map_info}[0]; |
|
|
1292 | $map =~ s/^.*?\/([^\/]+)$/\1/; |
1331 | (my $map = $hash) =~ s/^.*?\/([^\/]+)$/\1/; |
1293 | $STATWIDS->{map}->set_text ("Map: " . $map); |
1332 | $STATWIDS->{map}->set_text ("Map: " . $map); |
1294 | |
1333 | |
1295 | $self->load_map ($hash, $x, $y); |
1334 | $self->load_map ($hash, $x, $y); |
|
|
1335 | $self->flood_fill (0, 0, 0, "", $hash, $flags); |
1296 | } |
1336 | } |
1297 | |
1337 | |
1298 | sub conn::face_find { |
1338 | sub conn::face_find { |
1299 | my ($self, $facenum, $face) = @_; |
1339 | my ($self, $facenum, $face) = @_; |
1300 | |
1340 | |