… | |
… | |
21 | $FOCUS->key_up ($_[0]) if $FOCUS; |
21 | $FOCUS->key_up ($_[0]) if $FOCUS; |
22 | } |
22 | } |
23 | |
23 | |
24 | sub feed_sdl_button_down_event { |
24 | sub feed_sdl_button_down_event { |
25 | my ($ev) = @_; |
25 | my ($ev) = @_; |
26 | my ($x, $y) = ($ev->motion_x, $ev->motion_y); |
26 | my ($x, $y) = ($ev->{x}, $ev->{y}); |
27 | |
27 | |
28 | if (!$BUTTON_STATE) { |
28 | if (!$BUTTON_STATE) { |
29 | my $widget = $ROOT->find_widget ($x, $y); |
29 | my $widget = $ROOT->find_widget ($x, $y); |
30 | |
30 | |
31 | $GRAB = $widget; |
31 | $GRAB = $widget; |
32 | $GRAB->update if $GRAB; |
32 | $GRAB->update if $GRAB; |
33 | } |
33 | } |
34 | |
34 | |
35 | $BUTTON_STATE |= 1 << ($ev->button - 1); |
35 | $BUTTON_STATE |= 1 << ($ev->{button} - 1); |
36 | |
36 | |
37 | $GRAB->button_down ($ev, $GRAB->coord2local ($x, $y)) if $GRAB; |
37 | $GRAB->button_down ($ev, $GRAB->coord2local ($x, $y)) if $GRAB; |
38 | } |
38 | } |
39 | |
39 | |
40 | sub feed_sdl_button_up_event { |
40 | sub feed_sdl_button_up_event { |
41 | my ($ev) = @_; |
41 | my ($ev) = @_; |
42 | my ($x, $y) = ($ev->motion_x, $ev->motion_y); |
42 | my ($x, $y) = ($ev->{x}, $ev->{y}); |
43 | |
43 | |
44 | my $widget = $GRAB || $ROOT->find_widget ($x, $y); |
44 | my $widget = $GRAB || $ROOT->find_widget ($x, $y); |
45 | |
45 | |
46 | $BUTTON_STATE &= ~(1 << ($ev->button - 1)); |
46 | $BUTTON_STATE &= ~(1 << ($ev->{button} - 1)); |
47 | |
47 | |
48 | $GRAB->button_up ($ev, $GRAB->coord2local ($x, $y)) if $GRAB; |
48 | $GRAB->button_up ($ev, $GRAB->coord2local ($x, $y)) if $GRAB; |
49 | |
49 | |
50 | if (!$BUTTON_STATE) { |
50 | if (!$BUTTON_STATE) { |
51 | my $grab = $GRAB; undef $GRAB; |
51 | my $grab = $GRAB; undef $GRAB; |
… | |
… | |
54 | } |
54 | } |
55 | } |
55 | } |
56 | |
56 | |
57 | sub feed_sdl_motion_event { |
57 | sub feed_sdl_motion_event { |
58 | my ($ev) = @_; |
58 | my ($ev) = @_; |
59 | my ($x, $y) = ($ev->motion_x, $ev->motion_y); |
59 | my ($x, $y) = ($ev->{x}, $ev->{y}); |
60 | |
60 | |
61 | my $widget = $GRAB || $ROOT->find_widget ($x, $y); |
61 | my $widget = $GRAB || $ROOT->find_widget ($x, $y); |
62 | |
62 | |
63 | if ($widget != $HOVER) { |
63 | if ($widget != $HOVER) { |
64 | my $hover = $HOVER; $HOVER = $widget; |
64 | my $hover = $HOVER; $HOVER = $widget; |
… | |
… | |
1111 | |
1111 | |
1112 | package CFClient::UI::EntryBase; |
1112 | package CFClient::UI::EntryBase; |
1113 | |
1113 | |
1114 | our @ISA = CFClient::UI::Label::; |
1114 | our @ISA = CFClient::UI::Label::; |
1115 | |
1115 | |
1116 | use SDL; |
|
|
1117 | use SDL::OpenGL; |
1116 | use SDL::OpenGL; |
1118 | |
1117 | |
1119 | sub new { |
1118 | sub new { |
1120 | my $class = shift; |
1119 | my $class = shift; |
1121 | |
1120 | |
… | |
… | |
1176 | } |
1175 | } |
1177 | |
1176 | |
1178 | sub key_down { |
1177 | sub key_down { |
1179 | my ($self, $ev) = @_; |
1178 | my ($self, $ev) = @_; |
1180 | |
1179 | |
1181 | my $mod = $ev->key_mod; |
1180 | my $mod = $ev->{mod}; |
1182 | my $sym = $ev->key_sym; |
1181 | my $sym = $ev->{sym}; |
1183 | |
|
|
1184 | my $uni = $ev->key_unicode; |
1182 | my $uni = $ev->{unicode}; |
1185 | |
1183 | |
1186 | my $text = $self->get_text; |
1184 | my $text = $self->get_text; |
1187 | |
1185 | |
1188 | if ($sym == SDLK_BACKSPACE) { |
1186 | if ($sym == 8) { |
1189 | substr $text, --$self->{cursor}, 1, "" if $self->{cursor}; |
1187 | substr $text, --$self->{cursor}, 1, "" if $self->{cursor}; |
1190 | } elsif ($sym == SDLK_DELETE) { |
1188 | } elsif ($sym == 127) { |
1191 | substr $text, $self->{cursor}, 1, ""; |
1189 | substr $text, $self->{cursor}, 1, ""; |
1192 | } elsif ($sym == SDLK_LEFT) { |
1190 | } elsif ($sym == CFClient::SDLK_LEFT) { |
1193 | --$self->{cursor} if $self->{cursor}; |
1191 | --$self->{cursor} if $self->{cursor}; |
1194 | } elsif ($sym == SDLK_RIGHT) { |
1192 | } elsif ($sym == CFClient::SDLK_RIGHT) { |
1195 | ++$self->{cursor} if $self->{cursor} < length $self->{text}; |
1193 | ++$self->{cursor} if $self->{cursor} < length $self->{text}; |
1196 | } elsif ($sym == SDLK_HOME) { |
1194 | } elsif ($sym == CFClient::SDLK_HOME) { |
1197 | $self->{cursor} = 0; |
1195 | $self->{cursor} = 0; |
1198 | } elsif ($sym == SDLK_END) { |
1196 | } elsif ($sym == CFClient::SDLK_END) { |
1199 | $self->{cursor} = length $text; |
1197 | $self->{cursor} = length $text; |
1200 | } elsif ($sym == SDLK_ESCAPE) { |
1198 | } elsif ($sym == 27) { |
1201 | $self->emit ('escape'); |
1199 | $self->emit ('escape'); |
1202 | } elsif ($uni) { |
1200 | } elsif ($uni) { |
1203 | substr $text, $self->{cursor}++, 0, chr $uni; |
1201 | substr $text, $self->{cursor}++, 0, chr $uni; |
1204 | } |
1202 | } |
1205 | |
1203 | |
… | |
… | |
1280 | |
1278 | |
1281 | package CFClient::UI::Entry; |
1279 | package CFClient::UI::Entry; |
1282 | |
1280 | |
1283 | our @ISA = CFClient::UI::EntryBase::; |
1281 | our @ISA = CFClient::UI::EntryBase::; |
1284 | |
1282 | |
1285 | use SDL; |
|
|
1286 | use SDL::OpenGL; |
1283 | use SDL::OpenGL; |
1287 | |
1284 | |
1288 | sub key_down { |
1285 | sub key_down { |
1289 | my ($self, $ev) = @_; |
1286 | my ($self, $ev) = @_; |
1290 | |
1287 | |
1291 | my $sym = $ev->key_sym; |
1288 | my $sym = $ev->{sym}; |
1292 | |
1289 | |
1293 | if ($sym == SDLK_RETURN) { |
1290 | if ($sym == 13) { |
1294 | $self->emit (activate => $self->get_text); |
1291 | $self->emit (activate => $self->get_text); |
1295 | $self->update; |
1292 | $self->update; |
1296 | |
1293 | |
1297 | } else { |
1294 | } else { |
1298 | $self->SUPER::key_down ($ev); |
1295 | $self->SUPER::key_down ($ev); |
… | |
… | |
1304 | |
1301 | |
1305 | package CFClient::UI::Button; |
1302 | package CFClient::UI::Button; |
1306 | |
1303 | |
1307 | our @ISA = CFClient::UI::Label::; |
1304 | our @ISA = CFClient::UI::Label::; |
1308 | |
1305 | |
1309 | use SDL; |
|
|
1310 | use SDL::OpenGL; |
1306 | use SDL::OpenGL; |
1311 | |
1307 | |
1312 | my @tex = |
1308 | my @tex = |
1313 | map { new_from_file CFClient::Texture CFClient::find_rcfile $_ } |
1309 | map { new_from_file CFClient::Texture CFClient::find_rcfile $_ } |
1314 | qw(b1_button_active.png); |
1310 | qw(b1_button_active.png); |
… | |
… | |
1368 | |
1364 | |
1369 | my @tex = |
1365 | my @tex = |
1370 | map { new_from_file CFClient::Texture CFClient::find_rcfile $_ } |
1366 | map { new_from_file CFClient::Texture CFClient::find_rcfile $_ } |
1371 | qw(c1_checkbox_bg.png c1_checkbox_active.png); |
1367 | qw(c1_checkbox_bg.png c1_checkbox_active.png); |
1372 | |
1368 | |
1373 | use SDL; |
|
|
1374 | use SDL::OpenGL; |
1369 | use SDL::OpenGL; |
1375 | |
1370 | |
1376 | sub new { |
1371 | sub new { |
1377 | my $class = shift; |
1372 | my $class = shift; |
1378 | |
1373 | |
… | |
… | |
1825 | |
1820 | |
1826 | } |
1821 | } |
1827 | |
1822 | |
1828 | ############################################################################# |
1823 | ############################################################################# |
1829 | |
1824 | |
1830 | package CFClient::UI::MapWidget; |
|
|
1831 | |
|
|
1832 | use strict; |
|
|
1833 | |
|
|
1834 | use List::Util qw(min max); |
|
|
1835 | |
|
|
1836 | use SDL; |
|
|
1837 | use SDL::OpenGL; |
|
|
1838 | |
|
|
1839 | our @ISA = CFClient::UI::Base::; |
|
|
1840 | |
|
|
1841 | sub new { |
|
|
1842 | my $class = shift; |
|
|
1843 | |
|
|
1844 | $class->SUPER::new ( |
|
|
1845 | z => -1, |
|
|
1846 | can_focus => 1, |
|
|
1847 | list => (glGenLists 1), |
|
|
1848 | @_ |
|
|
1849 | ) |
|
|
1850 | } |
|
|
1851 | |
|
|
1852 | sub key_down { |
|
|
1853 | print "MAPKEYDOWN\n"; |
|
|
1854 | } |
|
|
1855 | |
|
|
1856 | sub key_up { |
|
|
1857 | } |
|
|
1858 | |
|
|
1859 | sub button_down { |
|
|
1860 | my ($self, $ev, $x, $y) = @_; |
|
|
1861 | |
|
|
1862 | $self->focus_in; |
|
|
1863 | |
|
|
1864 | if ($ev->button == 2) { |
|
|
1865 | my ($ox, $oy) = ($ev->button_x, $ev->button_y); |
|
|
1866 | my ($bw, $bh) = ($::CFG->{map_shift_x}, $::CFG->{map_shift_y}); |
|
|
1867 | |
|
|
1868 | $self->{motion} = sub { |
|
|
1869 | my ($ev, $x, $y) = @_; |
|
|
1870 | |
|
|
1871 | ($x, $y) = ($ev->motion_x, $ev->motion_y); |
|
|
1872 | |
|
|
1873 | $::CFG->{map_shift_x} = $bw + $x - $ox; |
|
|
1874 | $::CFG->{map_shift_y} = $bh + $y - $oy; |
|
|
1875 | |
|
|
1876 | $self->update; |
|
|
1877 | }; |
|
|
1878 | } |
|
|
1879 | } |
|
|
1880 | |
|
|
1881 | sub button_up { |
|
|
1882 | my ($self, $ev, $x, $y) = @_; |
|
|
1883 | |
|
|
1884 | delete $self->{motion}; |
|
|
1885 | } |
|
|
1886 | |
|
|
1887 | sub mouse_motion { |
|
|
1888 | my ($self, $ev, $x, $y) = @_; |
|
|
1889 | |
|
|
1890 | $self->{motion}->($ev, $x, $y) if $self->{motion}; |
|
|
1891 | } |
|
|
1892 | |
|
|
1893 | sub size_request { |
|
|
1894 | ( |
|
|
1895 | 1 + 32 * int $::WIDTH / 32, |
|
|
1896 | 1 + 32 * int $::HEIGHT / 32, |
|
|
1897 | ) |
|
|
1898 | } |
|
|
1899 | |
|
|
1900 | sub update { |
|
|
1901 | my ($self) = @_; |
|
|
1902 | |
|
|
1903 | $self->{need_update} = 1; |
|
|
1904 | $self->SUPER::update; |
|
|
1905 | } |
|
|
1906 | |
|
|
1907 | sub draw { |
|
|
1908 | my ($self) = @_; |
|
|
1909 | |
|
|
1910 | if (delete $self->{need_update}) { |
|
|
1911 | glNewList $self->{list}, GL_COMPILE; |
|
|
1912 | |
|
|
1913 | if ($::MAP) { |
|
|
1914 | my $sw = int $::WIDTH / 32; |
|
|
1915 | my $sh = int $::HEIGHT / 32; |
|
|
1916 | |
|
|
1917 | my $sx = $::CFG->{map_shift_x}; my $sx0 = $sx & 31; $sx = ($sx - $sx0) / 32; |
|
|
1918 | my $sy = $::CFG->{map_shift_y}; my $sy0 = $sy & 31; $sy = ($sy - $sy0) / 32; |
|
|
1919 | |
|
|
1920 | glTranslate $sx0 - 32, $sy0 - 32, 0; |
|
|
1921 | |
|
|
1922 | my ($w, $h, $data) = $::MAP->draw ($sx, $sy, 0, 0, $sw + 1, $sh + 1); |
|
|
1923 | |
|
|
1924 | if ($::CFG->{fow_enable}) { |
|
|
1925 | if ($::CFG->{fow_smooth} && $CFClient::GL_VERSION >= 1.2) { # smooth fog of war |
|
|
1926 | glConvolutionParameter (GL_CONVOLUTION_2D, GL_CONVOLUTION_BORDER_MODE, GL_CONSTANT_BORDER); |
|
|
1927 | glConvolutionFilter2D ( |
|
|
1928 | GL_CONVOLUTION_2D, |
|
|
1929 | GL_ALPHA, |
|
|
1930 | 3, 3, |
|
|
1931 | GL_ALPHA, GL_FLOAT, |
|
|
1932 | pack "f*", |
|
|
1933 | 0.1, 0.1, 0.1, |
|
|
1934 | 0.1, 0.2, 0.1, |
|
|
1935 | 0.1, 0.1, 0.1, |
|
|
1936 | ); |
|
|
1937 | glEnable GL_CONVOLUTION_2D; |
|
|
1938 | } |
|
|
1939 | |
|
|
1940 | $self->{fow_texture} = new CFClient::Texture |
|
|
1941 | w => $w, |
|
|
1942 | h => $h, |
|
|
1943 | data => $data, |
|
|
1944 | internalformat => GL_ALPHA, |
|
|
1945 | format => GL_ALPHA; |
|
|
1946 | |
|
|
1947 | glDisable GL_CONVOLUTION_2D if $::CFG->{fow_smooth}; |
|
|
1948 | |
|
|
1949 | glEnable GL_BLEND; |
|
|
1950 | glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA; |
|
|
1951 | glEnable GL_TEXTURE_2D; |
|
|
1952 | glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE; |
|
|
1953 | |
|
|
1954 | glColor +($::CFG->{fow_intensity}) x 3, 1; |
|
|
1955 | $self->{fow_texture}->draw_quad (0, 0, $w * 32, $h * 32); |
|
|
1956 | |
|
|
1957 | glDisable GL_TEXTURE_2D; |
|
|
1958 | glDisable GL_BLEND; |
|
|
1959 | } |
|
|
1960 | |
|
|
1961 | # HACK BEGIN |
|
|
1962 | { |
|
|
1963 | glTranslate -($sx0 - 32), -($sy0 - 32), 0;#remove |
|
|
1964 | my ($w, $h) = (250, 250); |
|
|
1965 | |
|
|
1966 | glEnable GL_BLEND; |
|
|
1967 | glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA; |
|
|
1968 | glEnable GL_TEXTURE_2D; |
|
|
1969 | glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE; |
|
|
1970 | |
|
|
1971 | $self->{mapmap_texture} = |
|
|
1972 | new CFClient::Texture |
|
|
1973 | w => $w, |
|
|
1974 | h => $h, |
|
|
1975 | data => $::MAP->mapmap ($w, $h), |
|
|
1976 | type => $CFClient::GL_VERSION >= 1.2 ? GL_UNSIGNED_INT_8_8_8_8_REV : GL_UNSIGNED_BYTE; |
|
|
1977 | |
|
|
1978 | $self->{mapmap_texture}->draw_quad (100, 100); |
|
|
1979 | |
|
|
1980 | glDisable GL_TEXTURE_2D; |
|
|
1981 | glDisable GL_BLEND; |
|
|
1982 | } |
|
|
1983 | # HACK END |
|
|
1984 | } |
|
|
1985 | |
|
|
1986 | glEndList; |
|
|
1987 | } |
|
|
1988 | |
|
|
1989 | glPushMatrix; |
|
|
1990 | glCallList $self->{list}; |
|
|
1991 | glPopMatrix; |
|
|
1992 | |
|
|
1993 | if ($FOCUS != $self) { |
|
|
1994 | glColor 64/255, 64/255, 64/255; |
|
|
1995 | glLogicOp GL_AND; |
|
|
1996 | glEnable GL_COLOR_LOGIC_OP; |
|
|
1997 | glBegin GL_QUADS; |
|
|
1998 | glVertex 0, 0; |
|
|
1999 | glVertex 0, $::HEIGHT; |
|
|
2000 | glVertex $::WIDTH, $::HEIGHT; |
|
|
2001 | glVertex $::WIDTH, 0; |
|
|
2002 | glEnd; |
|
|
2003 | glDisable GL_COLOR_LOGIC_OP; |
|
|
2004 | } |
|
|
2005 | } |
|
|
2006 | |
|
|
2007 | my %DIR = ( |
|
|
2008 | SDLK_KP8, [1, "north"], |
|
|
2009 | SDLK_KP9, [2, "northeast"], |
|
|
2010 | SDLK_KP6, [3, "east"], |
|
|
2011 | SDLK_KP3, [4, "southeast"], |
|
|
2012 | SDLK_KP2, [5, "south"], |
|
|
2013 | SDLK_KP1, [6, "southwest"], |
|
|
2014 | SDLK_KP4, [7, "west"], |
|
|
2015 | SDLK_KP7, [8, "northwest"], |
|
|
2016 | |
|
|
2017 | SDLK_UP, [1, "north"], |
|
|
2018 | SDLK_RIGHT, [3, "east"], |
|
|
2019 | SDLK_DOWN, [5, "south"], |
|
|
2020 | SDLK_LEFT, [7, "west"], |
|
|
2021 | ); |
|
|
2022 | |
|
|
2023 | sub key_down { |
|
|
2024 | my ($self, $ev) = @_; |
|
|
2025 | |
|
|
2026 | my $mod = $ev->key_mod; |
|
|
2027 | my $sym = $ev->key_sym; |
|
|
2028 | |
|
|
2029 | if ($sym == SDLK_KP5) { |
|
|
2030 | $::CONN->user_send ("stay fire"); |
|
|
2031 | } elsif ($sym == SDLK_a) { |
|
|
2032 | $::CONN->user_send ("apply"); |
|
|
2033 | } elsif ($sym == SDLK_QUOTE) { |
|
|
2034 | $self->emit ('activate_console'); |
|
|
2035 | } elsif ($sym == SDLK_SLASH) { |
|
|
2036 | $self->emit ('activate_console' => '/'); |
|
|
2037 | } elsif (exists $DIR{$sym}) { |
|
|
2038 | if ($mod & KMOD_SHIFT) { |
|
|
2039 | $self->{shft}++; |
|
|
2040 | $::CONN->user_send ("fire $DIR{$sym}[0]"); |
|
|
2041 | } elsif ($mod & KMOD_CTRL) { |
|
|
2042 | $self->{ctrl}++; |
|
|
2043 | $::CONN->user_send ("run $DIR{$sym}[0]"); |
|
|
2044 | } else { |
|
|
2045 | $::CONN->user_send ("$DIR{$sym}[1]"); |
|
|
2046 | } |
|
|
2047 | } |
|
|
2048 | } |
|
|
2049 | |
|
|
2050 | sub key_up { |
|
|
2051 | my ($self, $ev) = @_; |
|
|
2052 | |
|
|
2053 | my $mod = $ev->key_mod; |
|
|
2054 | my $sym = $ev->key_sym; |
|
|
2055 | |
|
|
2056 | if (!($mod & KMOD_SHIFT) && delete $self->{shft}) { |
|
|
2057 | $::CONN->user_send ("fire_stop"); |
|
|
2058 | } |
|
|
2059 | if (!($mod & KMOD_CTRL ) && delete $self->{ctrl}) { |
|
|
2060 | $::CONN->user_send ("run_stop"); |
|
|
2061 | } |
|
|
2062 | } |
|
|
2063 | |
|
|
2064 | ############################################################################# |
|
|
2065 | |
|
|
2066 | package CFClient::UI::Animator; |
1825 | package CFClient::UI::Animator; |
2067 | |
1826 | |
2068 | use SDL::OpenGL; |
1827 | use SDL::OpenGL; |
2069 | |
1828 | |
2070 | our @ISA = CFClient::UI::Bin::; |
1829 | our @ISA = CFClient::UI::Bin::; |