… | |
… | |
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 | |
… | |
… | |
1183 | |
1182 | |
1184 | my $uni = $ev->key_unicode; |
1183 | my $uni = $ev->key_unicode; |
1185 | |
1184 | |
1186 | my $text = $self->get_text; |
1185 | my $text = $self->get_text; |
1187 | |
1186 | |
1188 | if ($sym == SDLK_BACKSPACE) { |
1187 | if ($sym == 8) { |
1189 | substr $text, --$self->{cursor}, 1, "" if $self->{cursor}; |
1188 | substr $text, --$self->{cursor}, 1, "" if $self->{cursor}; |
1190 | } elsif ($sym == SDLK_DELETE) { |
1189 | } elsif ($sym == 127) { |
1191 | substr $text, $self->{cursor}, 1, ""; |
1190 | substr $text, $self->{cursor}, 1, ""; |
1192 | } elsif ($sym == SDLK_LEFT) { |
1191 | } elsif ($sym == CFClient::SDLK_LEFT) { |
1193 | --$self->{cursor} if $self->{cursor}; |
1192 | --$self->{cursor} if $self->{cursor}; |
1194 | } elsif ($sym == SDLK_RIGHT) { |
1193 | } elsif ($sym == CFClient::SDLK_RIGHT) { |
1195 | ++$self->{cursor} if $self->{cursor} < length $self->{text}; |
1194 | ++$self->{cursor} if $self->{cursor} < length $self->{text}; |
1196 | } elsif ($sym == SDLK_HOME) { |
1195 | } elsif ($sym == CFClient::SDLK_HOME) { |
1197 | $self->{cursor} = 0; |
1196 | $self->{cursor} = 0; |
1198 | } elsif ($sym == SDLK_END) { |
1197 | } elsif ($sym == CFClient::SDLK_END) { |
1199 | $self->{cursor} = length $text; |
1198 | $self->{cursor} = length $text; |
1200 | } elsif ($sym == SDLK_ESCAPE) { |
1199 | } elsif ($sym == 27) { |
1201 | $self->emit ('escape'); |
1200 | $self->emit ('escape'); |
1202 | } elsif ($uni) { |
1201 | } elsif ($uni) { |
1203 | substr $text, $self->{cursor}++, 0, chr $uni; |
1202 | substr $text, $self->{cursor}++, 0, chr $uni; |
1204 | } |
1203 | } |
1205 | |
1204 | |
… | |
… | |
1280 | |
1279 | |
1281 | package CFClient::UI::Entry; |
1280 | package CFClient::UI::Entry; |
1282 | |
1281 | |
1283 | our @ISA = CFClient::UI::EntryBase::; |
1282 | our @ISA = CFClient::UI::EntryBase::; |
1284 | |
1283 | |
1285 | use SDL; |
|
|
1286 | use SDL::OpenGL; |
1284 | use SDL::OpenGL; |
1287 | |
1285 | |
1288 | sub key_down { |
1286 | sub key_down { |
1289 | my ($self, $ev) = @_; |
1287 | my ($self, $ev) = @_; |
1290 | |
1288 | |
1291 | my $sym = $ev->key_sym; |
1289 | my $sym = $ev->key_sym; |
1292 | |
1290 | |
1293 | if ($sym == SDLK_RETURN) { |
1291 | if ($sym == 13) { |
1294 | $self->emit (activate => $self->get_text); |
1292 | $self->emit (activate => $self->get_text); |
1295 | $self->update; |
1293 | $self->update; |
1296 | |
1294 | |
1297 | } else { |
1295 | } else { |
1298 | $self->SUPER::key_down ($ev); |
1296 | $self->SUPER::key_down ($ev); |
… | |
… | |
1304 | |
1302 | |
1305 | package CFClient::UI::Button; |
1303 | package CFClient::UI::Button; |
1306 | |
1304 | |
1307 | our @ISA = CFClient::UI::Label::; |
1305 | our @ISA = CFClient::UI::Label::; |
1308 | |
1306 | |
1309 | use SDL; |
|
|
1310 | use SDL::OpenGL; |
1307 | use SDL::OpenGL; |
1311 | |
1308 | |
1312 | my @tex = |
1309 | my @tex = |
1313 | map { new_from_file CFClient::Texture CFClient::find_rcfile $_ } |
1310 | map { new_from_file CFClient::Texture CFClient::find_rcfile $_ } |
1314 | qw(b1_button_active.png); |
1311 | qw(b1_button_active.png); |
… | |
… | |
1368 | |
1365 | |
1369 | my @tex = |
1366 | my @tex = |
1370 | map { new_from_file CFClient::Texture CFClient::find_rcfile $_ } |
1367 | map { new_from_file CFClient::Texture CFClient::find_rcfile $_ } |
1371 | qw(c1_checkbox_bg.png c1_checkbox_active.png); |
1368 | qw(c1_checkbox_bg.png c1_checkbox_active.png); |
1372 | |
1369 | |
1373 | use SDL; |
|
|
1374 | use SDL::OpenGL; |
1370 | use SDL::OpenGL; |
1375 | |
1371 | |
1376 | sub new { |
1372 | sub new { |
1377 | my $class = shift; |
1373 | my $class = shift; |
1378 | |
1374 | |
… | |
… | |
1825 | |
1821 | |
1826 | } |
1822 | } |
1827 | |
1823 | |
1828 | ############################################################################# |
1824 | ############################################################################# |
1829 | |
1825 | |
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; |
1826 | package CFClient::UI::Animator; |
2067 | |
1827 | |
2068 | use SDL::OpenGL; |
1828 | use SDL::OpenGL; |
2069 | |
1829 | |
2070 | our @ISA = CFClient::UI::Bin::; |
1830 | our @ISA = CFClient::UI::Bin::; |