… | |
… | |
58 | $self->connect_ext (capabilities => sub { |
58 | $self->connect_ext (capabilities => sub { |
59 | my (%cap) = @_; |
59 | my (%cap) = @_; |
60 | |
60 | |
61 | #$self->send ("setup sound 0"); # we use a different protocol |
61 | #$self->send ("setup sound 0"); # we use a different protocol |
62 | $self->update_fx_want; |
62 | $self->update_fx_want; |
|
|
63 | |
|
|
64 | $self->send_exti_req (resource => "exp_table", sub { |
|
|
65 | my ($exp_table) = @_; |
|
|
66 | |
|
|
67 | $self->register_face_handler ($exp_table, sub { |
|
|
68 | my ($face) = @_; |
|
|
69 | |
|
|
70 | $self->{exp_table} = $self->{json_coder}->decode (delete $face->{data}); |
|
|
71 | |
|
|
72 | #TODO: update all interested parties |
|
|
73 | }); |
|
|
74 | |
|
|
75 | () |
|
|
76 | }); |
63 | |
77 | |
64 | if (my $ts = $cap{tileset}) { |
78 | if (my $ts = $cap{tileset}) { |
65 | if (my ($default) = grep $_->[2] & 1, @$ts) { |
79 | if (my ($default) = grep $_->[2] & 1, @$ts) { |
66 | $self->{tileset} = $default; |
80 | $self->{tileset} = $default; |
67 | $self->{tilesize} = $default->[3]; |
81 | $self->{tilesize} = $default->[3]; |
… | |
… | |
284 | my ($self) = @_; |
298 | my ($self) = @_; |
285 | |
299 | |
286 | $self->send_exti_msg (fx_want => { |
300 | $self->send_exti_msg (fx_want => { |
287 | 3 => !!$::CFG->{bgm_enable}, # FT_MUSIC |
301 | 3 => !!$::CFG->{bgm_enable}, # FT_MUSIC |
288 | 5 => !!$::CFG->{audio_enable}, # FT_SOUND |
302 | 5 => !!$::CFG->{audio_enable}, # FT_SOUND |
|
|
303 | 6 => 1, # FT_RSRC |
289 | }); |
304 | }); |
290 | } |
305 | } |
291 | |
306 | |
292 | sub logprint { |
307 | sub logprint { |
293 | my ($self, @a) = @_; |
308 | my ($self, @a) = @_; |
… | |
… | |
579 | $tex->upload; |
594 | $tex->upload; |
580 | } else { |
595 | } else { |
581 | $self->{delay}{$tile} = 1; |
596 | $self->{delay}{$tile} = 1; |
582 | |
597 | |
583 | # we assume the face is in-flight and will eventually come |
598 | # we assume the face is in-flight and will eventually come |
584 | push @{$self->{face_cb}{$tile}}, sub { |
599 | push @{$self->{tile_cb}{$tile}}, sub { |
585 | delete $self->{delay}{$tile}; |
600 | delete $self->{delay}{$tile}; |
586 | $_[0]->upload; |
601 | $_[0]->upload; |
587 | }; |
602 | }; |
588 | } |
603 | } |
589 | } |
604 | } |
… | |
… | |
629 | } |
644 | } |
630 | |
645 | |
631 | sub bg_fetch { |
646 | sub bg_fetch { |
632 | my ($self) = @_; |
647 | my ($self) = @_; |
633 | |
648 | |
634 | my $id; |
649 | my $tile; |
635 | |
650 | |
636 | do { |
651 | do { |
637 | $id = pop @{$self->{bg_fetch}} |
652 | $tile = pop @{$self->{bg_fetch}} |
638 | or return; |
653 | or return; |
639 | } while $self->{texture}[$id]; |
654 | } while $self->{texture}[$tile]; |
640 | |
655 | |
641 | CFPlus::DB::exists tilecache => $id, sub { |
656 | CFPlus::DB::get tilecache => $tile, sub { |
642 | my ($exists) = @_; |
657 | my ($data) = @_; |
643 | |
658 | |
644 | return unless $self->{map}; # stop when destroyed |
659 | return unless $self->{map}; # stop when destroyed |
645 | |
660 | |
646 | if ($exists) { |
661 | if (defined $data) { |
647 | $self->have_tile ($id); |
662 | $self->have_tile ($tile, $data); |
648 | $self->{texture}[$id]->upload; |
663 | $self->{texture}[$tile]->upload; |
649 | } |
664 | } |
650 | |
665 | |
651 | $self->bg_fetch; |
666 | $self->bg_fetch; |
652 | }; |
667 | }; |
653 | } |
668 | } |
… | |
… | |
810 | my ($self, $facenum, $face, $cb) = @_; |
825 | my ($self, $facenum, $face, $cb) = @_; |
811 | |
826 | |
812 | if ($face->{type} == 0) { # FT_FACE |
827 | if ($face->{type} == 0) { # FT_FACE |
813 | my $id = CFPlus::DB::get_tile_id_sync $face->{name}; |
828 | my $id = CFPlus::DB::get_tile_id_sync $face->{name}; |
814 | |
829 | |
815 | $face->{id} = $id; |
830 | $face->{id} = $id; |
816 | $self->{faceid}[$facenum] = $id; |
|
|
817 | |
|
|
818 | $self->{map}->set_tileid ($facenum => $id); |
831 | $self->{map}->set_tileid ($facenum => $id); |
819 | |
832 | |
820 | CFPlus::DB::get tilecache => $id, $cb; |
833 | CFPlus::DB::get tilecache => $id, $cb; |
821 | |
834 | |
822 | } elsif ($face->{type} & 1) { # with metadata |
835 | } elsif ($face->{type} & 1) { # with metadata |
823 | CFPlus::DB::get res_meta => $face->{name}, $cb; |
836 | CFPlus::DB::get res_meta => $face->{name}, $cb; |
|
|
837 | |
|
|
838 | } else { # no metadata |
|
|
839 | CFPlus::DB::get res_data => $face->{name}, $cb; |
824 | } |
840 | } |
825 | } |
841 | } |
826 | |
842 | |
827 | sub face_update { |
843 | sub face_update { |
828 | my ($self, $facenum, $face, $changed) = @_; |
844 | my ($self, $facenum, $face, $changed) = @_; |
829 | |
845 | |
830 | if ($face->{type} == 0) { # FT_FACE |
846 | if ($face->{type} == 0) { |
|
|
847 | # image, FT_FACE |
831 | CFPlus::DB::put tilecache => $face->{id} => $face->{data}, sub { } |
848 | CFPlus::DB::put tilecache => $face->{id} => $face->{data}, sub { } |
832 | if $changed; |
849 | if $changed; |
833 | |
850 | |
834 | $self->have_tile ($face->{id}); |
851 | $self->have_tile ($face->{id}, delete $face->{data}); |
835 | |
852 | |
836 | } elsif ($face->{type} & 1) { # split metadata |
853 | } elsif ($face->{type} & 1) { |
|
|
854 | # split metadata case, FT_MUSIC, FT_SOUND |
837 | if ($changed) { # new data |
855 | if ($changed) { # new data |
838 | my ($meta_json, $data) = unpack "(w/a*)*", delete $face->{data}; |
856 | my ($meta, $data) = unpack "(w/a*)*", $face->{data}; |
839 | $face->{meta} = $self->{json_coder}->decode ($meta_json); |
857 | $face->{data} = $meta; |
840 | |
858 | |
841 | CFPlus::DB::put res_data => $face->{name} => $data, sub { }; |
859 | CFPlus::DB::put res_data => $face->{name} => $data, sub { }; |
842 | CFPlus::DB::put res_meta => $face->{name} => $meta_json, sub { }; |
860 | CFPlus::DB::put res_meta => $face->{name} => $meta, sub { }; |
843 | } else { |
861 | } |
|
|
862 | |
844 | $face->{meta} = $self->{json_coder}->decode (delete $face->{data}); |
863 | $face->{data} = $self->{json_coder}->decode ($face->{data}); |
845 | } |
|
|
846 | |
864 | |
847 | ::add_license ($face); |
865 | ::add_license ($face); |
848 | |
866 | |
849 | if ($face->{type} == 3) { # FT_MUSIC |
867 | if ($face->{type} == 3) { # FT_MUSIC |
850 | $self->{music_meta}{$facenum} = $face; |
|
|
851 | |
|
|
852 | ::message ({ markup => "downloaded song #$facenum" }) |
868 | ::message ({ markup => "downloaded song #$facenum" }) |
853 | if $changed; |
869 | if $changed; |
854 | |
870 | |
855 | &::audio_music_push ($facenum); |
871 | &::audio_music_push ($facenum); |
856 | } elsif ($face->{type} == 5) { # FT_SOUND |
872 | } elsif ($face->{type} == 5) { # FT_SOUND |
857 | $self->{sound_meta}{$facenum} = $face; |
|
|
858 | |
|
|
859 | ::message ({ markup => "downloaded sound #$facenum" }) |
873 | ::message ({ markup => "downloaded sound #$facenum" }) |
860 | if $changed; |
874 | if $changed; |
861 | |
875 | |
862 | &::audio_sound_push ($facenum); |
876 | &::audio_sound_push ($facenum); |
863 | } |
877 | } |
864 | |
878 | |
|
|
879 | } else { |
|
|
880 | # flat resource case, FT_RSRC |
|
|
881 | CFPlus::DB::put res_data => $face->{name} => $face->{data}, sub { } |
|
|
882 | if $changed; |
|
|
883 | } |
|
|
884 | |
|
|
885 | if (my $cbs = $self->{face_cb}{$facenum}) { |
|
|
886 | $_->($face, $changed) for @$cbs; |
865 | } |
887 | } |
866 | } |
888 | } |
867 | |
889 | |
868 | sub smooth_update { |
890 | sub smooth_update { |
869 | my ($self, $facenum, $face) = @_; |
891 | my ($self, $facenum, $face) = @_; |
870 | |
892 | |
871 | $self->{map}->set_smooth ($facenum, $face->{smoothface}, $face->{smoothlevel}); |
893 | $self->{map}->set_smooth ($facenum, $face->{smoothface}, $face->{smoothlevel}); |
872 | } |
894 | } |
873 | |
895 | |
874 | sub have_tile { |
896 | sub have_tile { |
875 | my ($self, $tile) = @_; |
897 | my ($self, $tile, $data) = @_; |
876 | |
898 | |
877 | return unless $self->{map}; |
899 | return unless $self->{map}; |
878 | |
900 | |
879 | my $tex = $self->{texture}[$tile] ||= |
901 | my $tex = $self->{texture}[$tile] ||= |
880 | new CFPlus::Texture |
902 | new CFPlus::Texture |
881 | tile => $tile, minify => 1, mipmap => 1, delay => 1; |
903 | tile => $tile, |
|
|
904 | image => $data, delete_image => 1, |
|
|
905 | minify => 1, mipmap => 1; |
882 | |
906 | |
883 | $_->($tex) for @{(delete $self->{face_cb}{$tile}) || []}; |
907 | if (my $cbs = delete $self->{tile_cb}{$tile}) { |
|
|
908 | $_->($tex) for @$cbs; |
|
|
909 | } |
884 | } |
910 | } |
885 | |
911 | |
886 | sub connect_face_update { |
912 | # call in non-void context registers a temporary |
|
|
913 | # hook with handle, otherwise its permanent |
|
|
914 | sub on_face_change { |
887 | my ($self, $id, $cb) = @_; |
915 | my ($self, $num, $cb) = @_; |
888 | |
916 | |
889 | push @{$self->{face_cb}{$id}}, $cb; |
917 | push @{$self->{face_cb}{$num}}, $cb; |
890 | |
918 | |
|
|
919 | defined wantarray |
891 | CFPlus::guard { |
920 | ? CFPlus::guard { |
892 | @{$self->{face_cb}{$id}} |
921 | @{$self->{face_cb}{$num}} |
893 | = grep $_ != $cb, |
922 | = grep $_ != $cb, |
894 | @{$self->{face_cb}{$id}}; |
923 | @{$self->{face_cb}{$num}}; |
895 | } |
924 | } |
|
|
925 | : () |
|
|
926 | } |
|
|
927 | |
|
|
928 | # call in non-void context registers a temporary |
|
|
929 | # hook with handle, otherwise its permanent |
|
|
930 | sub register_face_handler { |
|
|
931 | my ($self, $num, $cb) = @_; |
|
|
932 | |
|
|
933 | # invoke if available right now |
|
|
934 | $cb->($self->{face}[$num], 0) |
|
|
935 | unless exists $self->{face}[$num]{loading}; |
|
|
936 | |
|
|
937 | # future changes |
|
|
938 | $self->on_face_change ($num => $cb) |
896 | } |
939 | } |
897 | |
940 | |
898 | sub sound_play { |
941 | sub sound_play { |
899 | my ($self, $type, $face, $dx, $dy, $vol) = @_; |
942 | my ($self, $type, $face, $dx, $dy, $vol) = @_; |
900 | |
943 | |