ArtBrowser

This commit is contained in:
y4my4my4m 2023-05-13 21:58:07 +09:00
parent 1e68c497f2
commit a2b920f84f
6 changed files with 879 additions and 615 deletions

View file

@ -0,0 +1,133 @@
 
   
  ÜÜ ÜÜ ÜÜ 
 bisounours presents his first ansi under the fire label. Û²±Ü²ÛÛÜܱ²²°Ü
original art: gen13    ßÞßÛßÛ²ÜÛ²±°ß 
huhu to all members of fire, tiny toons, telepathy, aegis ÜÜÜÜÜßÛÛÛ²ÜÛ°
 btw, if you wonderÞwhere my handle comÝes from, it means Þ²ÛÜÞÛ²±ÜÛ²±Ý °
 carebear Þin frenchÝ° ÝÞÝ  ß°ßܲßܲ±°ÜÜÜÞ
ÝÞÝ Þ°ÛÝ ÞÝÞÛÞÜÜÜ°Ü°ÜÛÛ²±ÜÛÛÛ²°Ü ÞÝ
ÞÝ Ý° ÛÞ°Û Ý  °°Ý Ý° Ý ÝÞ²²ÛßÞß°ß ßÛ²ßÜÜÛ²° °°
 Û° ÝÞ°Ý ÞÝÝ °ÛÛÝ ÞÞÝÞ° ÞÝÞ  ÞÝ ÞÝß²ß޲ܲ±°Ü۲ܰßßßß Þ°Ý
Þ°ÞÝÝ°±° ÛÝÞ ÞÛ°ÛÝ °Û°° Û° ²Û Û ÞÛ°Û²  ܲÛÜßÛÜÛÛß°²²±°±² °±
°°ÛÛÛ°Þ°°ÞÛ²Û °°ÛÝÞÛÛ Þ±Ý²Û°Ý ÛÛÝÛÝ°Û°²ÛÝ °ÝÞ±ÛÛ²±°°ßÞ±²²±°±²ßÞ±Ý
Þ°Þ²ÛÝÝ  °±±²ÛÛÝÝ ÞÛ±Û  Û²ÛÝ  °±Þ° Û°ÞÛÛ²°ÛÞ°ÞÛÛÛ ²ÛÜß²²±°ß()ß±°²²ß °±²±Ü
ÛÛ±ßß°  Þ°°ÛßÛ²°ÛÜÛÛß ßß Þ°±°ÝßÛÛÛ°ßß°ÛÛÛÛÛß²ÛßÛ°±Û Þ±²±°Ý
ß²ßßßßßßß²°ßßß ß²ßßßßßß²ßß   ßß° ß±²ß 
 °
 ÜÜÜÜÜ 
Û Ü°°° ÛÛ°±²²ÜÜ 
 °°±²±° ÛÛ°±²ÛÛÛ²ÜÜ 
  °ÜÜÜÜÜ Þ°±²Û²±° ÛÛ°±²²ÛÛÛÛ²Ü 
 ÜÛÛ²²±±°°°± °±²ÛÛ²±° ÛÛÛ°°±²²ÛÛÛÛ²Ü °ÜÜÜÜÜ 
  ±²²ÛÛÛ²²±±±±Þ°±²ÛÛÛ²±° °°±²²ÛÛÛÛ²Ü ±Üܲ۲²ßÛ°° 
  ܱ±°°°Ü°±±²²²ÛÛÛÛ²²²Ý°±²ÛÛÛ²±°ÛÛÛÛÛÛÛ°°±±²ÛÛÛÛ²Ü °²²ÛÛÛÛ²ßÛ °±°° 
 ÜÛ°²Û²²±°°°Ü°±±²²²²ÛÛ²²°±²ÛÛÛÛ²±±°ÛÛÛÛÛÛÛÛ°°°±±²²²±°Üß°±±²ßßÛÛÛÛ°±±°° 
  ÜÛÛ °±²ÛÛÛÛ²±°°ÜÜ°±±²²²±°±²²ÛÛÛÛÛ²±±°° ÛÛÛÛÛÛÛ°°°±±±±°° ÛÛÛÛÛÛÛÛÛÛ°±±°Ý
 ÜÛÛ °°°±±²²ÛÛ²±°°Ü°±±±°±²²ÛÛÛÛÛÛÛ²²±±±²ÜÜ°   ÛÛ°±±°
 ÜÛ°° °°°°±±²²Û²°°ÛÛ °²²ÛÛÛÛÛßßÛÛÛ²²²ÛÛ²ßß±° °±ßß²ÛÛÛÛÛÛ²ÜÜÜ° °±±
 ÜÛ°±±°° °°°°±±²²° °±²²ÜܲßÛ²ÛÜܲßß²±° Ü° °ÜÜÜ°°°°°°°°±ßß²²ÛÛ²ÜÜ° °°
Þ°±²²²±°°  °°°°±±²²°ÛÛÛ±ÜÞ°°²±°ÜÜÜ °°° °ßßß°°°Ü±²Ü±±°° ° °°±ß²²Û²Ü°  ß°±²²²²±°°  °±²²²ß°ÛÛ²±°°ßÛ° ß°Ü ßßÜÜßßÛ°°°Üܰ߰ܲ۲²Û۲ܲÜܱ°°°ß²²
 ß°±²Û²²±±° °±±²²²ßÞ°²Û²°ß Þ° ßßÜÛßßܲÜßßÜß°°Ü°ßݱ²ÛÛÛÛÛÛÛÛ²Û²²Ü±°
  Üܲ°±²ÛÛ²²±±±°  °±±²²Û²°Üß°°±²° ÛÝÛÛ ß  °ÞÛÛÝÝÛ Ü°ß°ÜÞ°±²ÛÛÛÛÛÛÛÛÛÛ²²ß°
Ü°±±°ß°±²ÛÛÛ²²²±±±±²²Û²°°ÞÝ ²°Û±ÝÛÛÛÛÛÛ°°°ß°ÜÜßÛÝÞ°°ÛÞÝÛÜßÜ ß° °±²ÛÛÛ²Û²²±±° 
 °±±±ßܱ²ÛÛÛÛ²²²²ÛÛ²°ÜßÜß°Üß²ÛÜ° ÛÛÛ°±²± ÜÞ±þ²ßÜÛ²±°Û°°° Þ  °° °²Û²²±±°° 
ÛÛÛ°°±±ßܱ²ÛÛÛÛÛÛÛ²°Üß°Ü° Üß²ÛÛÛßÝÛ°±²²ÛÝÜÝßßÜÜÛÛÛÛ²±ÝÜ °°Ý°°Ü ݱ²²±°° 
°°°ÛÛ°°±°Ý°²ÛÛÛÛ²° ß ÛÞÝ ß°°ß° ßßß²²°±±²ÛÛÛÛÛÛÛÛÛ²±°°° ÞÝޱ߰ܲ±°  
±±±°°°Û°°Þ°±ÛÛ²²°ÜßÜ° Û°  Ûß ÞÝ°þÜ  ß±°±±²ÛÛÛÛÛÛÛÛ²±°±±Ý°°Þ²± °Û°  
²²²±±±°°Û° ²²²°°Û°Û±ÝÞÝ  °ÛÜÜßßßÜÜÛÛ²°±±±²ÛÛÛÛÛÛÛ²±Ý±±° ÞÞ²²°Þ°Û  
ÛÛÛ²²²±±°Û Û°°Û°°°²°°ÛÝ  Û°±±±²ÛÛÛ²±°±ßÜÛÛÛÛÛÛ²±°Þ±±±Ý°²ÛÛ²Þ°°Ý 
²²²ÛÛÛ²²± ²±°Û°°°²Û±Þ°Ý °ÜÞ ß°°±±²²ÛÛ²ÜÜÛÛßßß ÛÛ²±ÝÝ°±±° Þ²ÛÝÞ°°° 
±±±²²²ß²Û²± Þ°Ý°±Û²ÝÞ°Û° ÞÝ °°ÝßÛ°±±²²²ß Üܱ°ÞÛ²±°ÞÛÞ°±° °±²ÝÛ°°° 
ÜÜÜÜ°°°²²± °Þ°°°²Û²Ý°²°Û° ÛÞ°° ÛÜ ßÛ°±±Ü  ßß±°ÜÛ²±° ²Û °°ÝÞ°°±°Û° Ý 
°°°°°°²²±°°° ÛÝ°²ÛÝÝÛ±±°Ý°ÛÞ°°° Ü ßßÛ°°±ßÜܱ²²±ßܱ±²Û°ß°Û°°ÝÞ°°°  
°°°°°²²±Ü°°°ÛÛ°²ÛÛ±ÞÛÛ°°Ý ÞÝÛ°°±° °   ßßÛÛ°°ßßܲ°±²Ûß±°ÜÜÛßÜ°°ÜÜÛÛÛÛÛÛÜÜ 
Û°°°²²±Û°°°Û°±°±ß°ÝÛ °Û°° °ÛÜÛ°°²Ü²°Ü   °Ü² °±Ûß±±°°Û°±±Û°±²ÛÛÛÛÛÛÛÛÛÛÜ 
°°±²²±Þ°°ÝÛ±²²Ü°°²Þ°Ü±Û°° Û°Ü۲߱ÛܱÜ°±ÜÜÜÛÛÛÛßß±±°°°ÛÛ°°°±Þ°±²²ÛÛÛÛÛÛÛÛÛÛÛ 
°±²²° °°ÛÛ±²ÛÛ²±²Þ°²ÛÝ°°Ý °ß°±ܲßß²²Ü°Ü°±±±±±±±°°°°ÛÛÛ°° °°±Þ°±±²²ÛÛÛÛÛÛÛÛÛÛ 
±²²° °°°Û±²ÛÛÛÝ°Þ°²ÛÛ²°Ý° ÜÜÜÜÜ߲ܰÜßßÛ²°Û °°°°°°°ÛÛ Û°°  °°±Þ°°±²²²ÛÛÛÛÛÛÛÛÝ
²²° Þ°°Û±²ÛÛÛ²°Û°²ÛÛÛ²°ÜÛÛÛÛÛÛÛÛÝÛ²±°Üßß²°Þ° Û°° ÛÛ°°±ÞÛ°°±²²²²ÛÛÛÛÛÛ
²° °°°°ÞÛÛÛ²° °²ÛÛ²±±ÞÛÛÛÛÛÛÛÛÛ±±°Û±°°°Þ²°Û° Û°° ÛÛÛ°°±ÞÛ °°±±±²²²ÛÛÛ
°()°°Û ²ÛÛ²°Û°²ÛÛÛ±°°ÛÛÛÛÛÛÛÛÛ±±°°²°Ý°±°Þ±ÝÛ° Üß°° °°±ÞÛ °°°±±²²²
 °Ü°Û°²ÛÛÝ °²ÛÛ²±°ÛÛ²ÛÛÛÛÛÛÛݱ°°Þ±°ÛÞ±²Þ°°°ßܲÜß°°   °°±ÞÛ °°°
 Û±ÝÛ°ÞÛ²°ÞÞÛÛ±°°ÜÛ°±²ÛÛÛÛÛݱ°°Ü±°Û°Û²ÛÝÛ  ÜÜßÜÜ  °° Û°°±ÞÛ Ý
 °±²°ÝÛÛ±²±ÝÛ²²±°ÛÜÛÛ°±±²²ÛÛݱ°°Ü°Û°ÝÞÞÛÛ²ÝÛÛ° ß  Û° °ÛÛÛ°°±±±°° Û°°±ÞÛ ÛÛ 
°±²ÛÜÝÛÛ°±ÛÞÞ²±°ÛÝÞÛÛÛ°°±²²Ý±°ÜÛßÜ°Û °²Û²± Û°ßÜ Üß°ÛÛÛ°°°±²²²²²±±°°Û°±Þ ÛÛ± 
°ÞÛÛ²ÝÛÛ°°ÝÛ±±°Ûß °²ÛÛÛ °°Û±Üß°°°Ûܱ ÞÛ²±Ý°°ÛÛÛß°ßß°°°±±²²²ÛÛÛÛ²²²±°Û°±Þ² Û²° 
±²ÛÛÝ°Þ°±°Þ°°Ûß°  °²ÛÛÛÛÛÝß°°Üܲ²ßÛ°²ß°ß°Üß°ÛÛ° °Û°±²²²ÛÛÛÛÛÛÛÛÛ²²±°Û°°Þ²Û²± 
ÞÛÛ²°Û°±²°Þ°ÛÞ  °²²ÛÛÛ±°Üܲ²²ÝÛ°²°Û²±°°°Üß°Ý°Û°±²²ÛÛÛÛÛÛÛÛÛÛÛÛ²²°Û°±°±²±° 
±²ß°ÛÛ±²ÛÝÝÛÝÛÝ  °°²²Û°Þ²²²ÛÛÛ°±°ÛÛÛ²±°°Û°ÞÞ°Û°±²²ÛÛÛÛÛÛÛÛÛÛÛÛ²²°°°±±Ý±° 
°±°ÛÛ°ÞÛÛ²°ÞÞ°Û  °°°°°Þ²ÛÛÛÝ°°°ÛÛÛÛÛ²±°° Ý°°°Û°±²²ÛÛÛÛÛÛÛÛÛÛ²²±°°°±±Ý° 
°°ÛÛÞ±²ÛÛÛÝÝ°°°Û °Þ°°°±²ÛÛÛÛ°°ÛÛÛÛÛ²²±°°°²Þ±°°Û°°±²²ÛÛÛÛÛÛ²²²±°Û°°±± ° 
°° ÛÞ°²ÛÛÛ²Þ °°ÛÜ °±°°°±²²ÛÛ °ÞÛÛÛ²²±°°°°Ý°±±±°°Û°°±²²²²²²±°°Û°°°±±Ý 
Û° ÛÝ°±²Û²±ÝÝ °ß°°ÛÜ  °±°°°°±±²²Ý°ÛÛ²²²±°°°±°°°°°±±±°°°Û°°°±±±°°°°°°±±Ý 
Û° ÛÝÛ°±²±°ÛÞ  ß°°ÛÜ Þ°±°°Û°°±±±Û²²±±°°°°±°Ý°°±°ß±±±±±°°°°°°°°°°±±±°ß 
ÛÛ°ÛÛ°Û°°±°ÛÝßÜ °ß°°°ÜÛ°±±°°°°°°Þ°°°°°°±±°ß°°±±±°°ßß°±±±±±±±±±±±±°ß  
ÞÛ° ÛÛ°Û°°° Û ßÜ ßÜß°°±±±±°°°°°±±±±°ß°°°±±±²²²±±°°ßßß°±±±±°ßß°   
°ÛÛ°ÛÛÛ°Û°°°ÛÝ ßßÜÜ ß°°°±±±±±±±°ßß°°°±±±±²²²Û²²²±±±°°°°°°°°°   
 °ÛÛÛÛÛÛ°ßÛ°°ÛÜ ° °±±ßßßßßß°°°±±±±±²²²²ÛÛÛÛÛÛÛ²²²±±±±±°°   
   ß°°ÛÛ² °ßÛ°°ÛÜ  ° °±°°°°°°±±±±²²²²²ÛÛÛÛÛÛÛÛÛÛÛÛÛÛ²²²²²² 
 °ß°°°Ü  ßÛÛÛÛÜÜ Þ° ²ÜÜÜÜÜÛÛÛÛ°°±°°ÛÛÛÛÛ°°±°° ÛÛÛÛÛ°°°° ° 
 ßß°°ÜÜ °ßßß°°°Þ±° °°ÛÛÛÛÛÛ°°±²±°ÛÛÛÛ°°±²±±°ÛÛÛÛ°°°° °± 
 ßßß Û±° Þ°°ÛÛÛÛ°°±²Û²°ÛÛÛ°°±²ÛÛ²±°ÛÛ°°°° °±² 
 ÞÛ²±°  °°ÛÛÛÛ°°²ÛÛ²±°ÛÛ°±²ÛÛÛ²±°Û°°°° °±²ÛÝ 
 ÛÛ²±±° °°ÛÛÛÛ°°±²ÛÛ²±°Û°°±²ÛÛ²±°ÛÛ°°°Ý °±²Û°° 
 ÞÛÛÛ²±°° Ü°°ÛÛÛÛ °°±²ÛÛ²±°Û°±²ÛÛÛ²±°Û°°°° °°±²ÛÛ °Ý 
 ÛÛÛÛÛßܲ² ÛÛÛÛÛÛ°°±²ÛÛÛ²±°Û°±²ÛÛ²±°°Û°°°° °±±²ÛÛÛ °° 
 ÛÛÛßܲ²²²² ÛÛÛÛ°°±²²ÛÛ²±°°Û°±²ÛÛ²±°°Û°°°° °±²ÛÛÛÛÛ °° 
 ÛßÜ°°Þ²±±±± ÛÛ°°±²²ÛÛÛ²±°°ÛÛ°±²ÛÛ²±°° °°°Ý °±²ÛÛÛ ÛÛÛ°Ý 
 Ü°°±°°±±±°°°Û°°±±²ÛÛÛ²±°°°Û°±±²ÛÛ²±°°Û°°°Ý °²Û°°°ÛÛÛÛ°Ý 
 Ü°°±±°°°Þ°°°°°°°°±²ÛÛÛÛ²±°°ÛÛ°±²ÛÛÛ²±°°Û°°°° ÞÛ°°±±°ÛÛÛ° 
 Ü°°±±°°°Û °°°°°±Ý±²ÛÛÛÛ²±°°°ÛÛ°±²ÛÛÛ²±°°Û °°° Þ°°±²±±°ÛÛ  
  °°±±°°°° °°Þ°°±±²²°²ÛÛÛ²±°°°ÛÛÛÛ°±²ÛÛ²±°°ÛÛÛß²Ý °°±²²±°°ÛÝ 
  Ü°°±±°°° °°°±Þ±±²²ÛÛݲ²²²±°°°ÛÛ ÛÛÛ°±²Û²±°Ûܱ±²²² °°±²Û²±°ÛÝ 
 Ü°°±±°°°Û °°°±±²±²²ÛÛ²²²°²±±°°°ÛÛ ÛÛÛÛ°±²±ÜÛ°°°±±²² °°±²Û²±°ÛÝ 
  Ü°±±°°°°Û°°°±±²²Û²ÛÛ²²±±±°°°°°°Û ÛÛÛÛ Ü±±°Û°°°±²² Þ°±²Û²±±°Ý 
 Ü°±±°°°ÛÛ°°±±²²ÛÛÛ²²²±±±°°°Ý°°ÛÛÛ ÛÛÜ°°±±±±°°°°ßÛÝ Û°±²Û²±° 
 °°±±°°°ÛÛ°°±²²ÛÛÛÛÛÛÞ±±°°°°°±ÛÛÛÛ Ü±±°°°°±±±°ßßÛÛÛ Þ°±²Û²±± 
 °°±±°°°ÛÛ°°±²²ÛÛÛÛÛÛ²Þ°°°ÛÛÛ°°±ÛÛÛ Üܱ±°°°ÛÛ°°±±ß°°°°ÛÝ °°±Û²±° 
 °°±±°°°ÛÛ°°±²²ÛÛÛÛÛÛ²±Þ°ÛÛÛÛÛÛ°°±Ü±±°°°ÛÛÛ°°°°ß °°°°ÛÛÛ Þ°°±±°° 
 °°±±°°°ÛÛ°°±²²ÛÛÛÛÛÛ²±°°ÛÛÛÛÛÛÛÛÛ°°°ÛÛÛÛÛ°°±ß °°°°°°ÛÛÛÝ  Û°°±°²ÛÛÜ Ü
 °°±±°°°ÛÛ°°±²²ÛÛÛÛÛÛ²±° ±°ÛÛÛÛÛÛÛÛÛÛÛÛÛÛ°°±ß °°±±²±°°ÛÛÛÝ ÞÛ°°ÝÛ°±²ÛÛÛ
 Þ°±±°°°ÛÛ°°±²²ÛÛÛÛÛÛ²±° Þ°°ÛÛÛÛÛÛÛÛÛÛÛÛÛ°°Ü Û°±±²²²±°ÛÛÛÛ ÛÛÛÞÛÛ°±²²Û
 °°±°°°ÛÛ°°±²²ÛÛÛÛÛÛ²±°°ÛÞ°°ÛÛÛÛÛÛÛÛÛÛ°°±± ÛÛ°±²²²²±°°ÛÛÛÛ ßÛÛÛÛÛÛ°±±
 Þ°±±°°°Û°°±²²ÛÛÛÛÛÛ²²±°ÛÛÞ°°ÛÛÛÛÛÛÛÛÛ°°±ßÛÛÛ°±²²Û²²±° ÛÛÛ° ßÛÛÛÛÛ 
 °°±°°°ÛÛ°°±²ÛÛÛÛÛÛÛ²±°°ÛÛ ±°°ÛÛÛÛÛÛ°°±ß ÛÛÛ°±²²ÛÛ²²±°ÛÛÛ°Ý ßßßßß
  °±±°°°Û°°±²²ÛÛÛÛÛÛ²²±° Û ±°°ÛÛÛÛ°°±ß°°ÛÛ °±²²ÛÛÛ²±°° Û°± 
 Þ°±±°°ÛÛ°°±²ÛÛÛÛÛÛÛ²±±°ÛÛÛ Þ°°ÛÛ°°±ß°±°ÛÛÛ°±²²ÛÛÛ²²±° Û°±° 
 °°±°°°Û°°±²²ÛÛÛÛÛÛÛ²±°ÛÛÛÛ° ±°°°±ß°±±° ÛÛ°±²²ÛÛÛÛ²²±°Û°±°Ý 
 °°±°°ÛÛ°°±²ÛÛÛÛÛÛÛ²²±°ÛÛÛ°°°Þ°±ß°°±±°ÛÛÛÛ°±²ÛÛÛÛÛ²±°°Û°°° 
Þ°±±°°Û°°±²²ÛÛÛÛÛÛÛ²±°°ÛÛÛ°±° Þ°±±±°ÛÛÛ °±²ÛÛÛÛÛ²²±°Û°±°Ý  
Þ°±±°°Û°°±²ÛÛÛÛÛÛÛÛ²±°ÛÛÛÛ°±° °±±±° ÛÛÛ°±²ÛÛÛÛÛÛ²²±°Û°±°Ý 
°±±±°°Û°°±²ÛÛÛÛÛÛÛÛ²±°ÛÛÛÛ°±°ÝÞ±±±°° ÛÛ°±²²ÛÛÛÛÛÛ²±°°°±°° 
°±±°°°Û°°±²ÛÛÛÛÛÛÛÛ²±°ÛÛÛÛ°±°Ý°±±°° ÛÛÛ°±²ÛÛÛÛÛÛ²²±° °±°Ý 
°±±°°°Û°°±²²ÛÛÛÛÛÛÛ²±°°ÛÛÛÛ°±°Þ±±° ÛÛ°±²²ÛÛÛÛÛÛ²²±°Û°±°Ý  °±±°°°ÛÛ°°±²ÛÛÛÛÛÛÛ²²±°ÛÛÛÛ°±°Þ±°°ÛÛÛ °±²ÛÛÛÛÛÛ²²±°°°±°°    
°±±±°°°Û°°±²²ÛÛÛÛÛÛÛ²±°ÛÛÛÛ°±°Þ°°ÛÛÛÛ°±²ÛÛÛÛÛÛÛ²²±°Û°±°Ý  
Þ°±±°°°ÛÛ°°±²ÛÛÛÛÛÛÛ²±°°ÛÛÛ°±°Þ°°ÛÛÛ°±²ÛÛÛÛÛÛÛ²²±°°°±°°  
Þ°±±°°°ÛÛ°°±²ÛÛÛÛÛÛÛ²²±°ÛÛÛ°±°Þ°ÛÛÛ°±²²ÛÛÛÛÛÛ²²±°°Û°±°Ý 
 °±±°°°ÛÛ°°±²Ûß²ßßßÛÛ²±°ÛÛÛÛ°±ÝÛÛÛÛ°±²ÛÛÛÛÛÛ²²±°°Û°±°ß  
 °±±°°°ßßßÛ²ÛÛ±ÛÛ° Û° ß°ßßßÛ°±ÝÛÛÛ°±²ÛÛÛÛÛÛÛ²±°ß°Û°°²ÛÛÛÜÜÜÜ°
ÜÞ°ßß²°°ÛÛ°ÛÛÛÛÛ°°°ÛÛÛÛÛ²ÛÛ°ÛÛÛßßßß²ÛÛÛÛßßß²ÛÛÛ°Û°°ÛÛÛÛÛÛ°ÛÛÛÛÛ²ÛÜÜÜ ÜÜ²Ü Ü ÜÜÜ ß°ßß²ßß°°°Û°ÛÛÛÛß°ßß±ßßß ²° ßßß²ßßÛÛÛÛÛÛ²ßßß °  
 °ß²ßß°° ÜÜ ÜÜÜÜÛÛ°±ÛܲÜÜÜÜÜ Ü °°  
 °ßß²ßßßß
²Ü°
Û²ÛÜ°
ÛÛÛÛ²Ü 
ÛÛÛÛÛÛÛÜ
ÛÛÛ۲߰  
 ÜÜÜÜÜÜÜÜÜ ²ÛÛß ÜÜܲÜÜÜÜÜÜ °ÜÜÜÜÜÜÜÜÜÜ
 ²ÛÛÛÛÛ²ßßßÛÛ²ßßÛ ±ßÛÛÜ Ü°n°ßßßßßÛÜÜ° Ü þßßßßß°ß²ÛÛÛ
 ÞÛÛ²Ûß²°ßßÛ²°Ü ° ²ÛÛÜ ß±°ß²ÛÜÜ e°ß±ßÞÛÛÝ
 °ÛÛÛÝ ± °ßÛ Ý ÞÛ²ÛÝ °ÞÛÛ² °±° °Û² 
 ²Û °Þ Þ °°ÛÛÛÛÞÛÛÝ °ÞÛ² 
  °ÛÝ Þ  °°Û²ÛÞ²ÛÛ ÜÛß° °
 °ÜÛ  ²   d° °ÞÞÛÛÝÛÛÛÛÜ²ß  ²Ü°
 ÜÛÛ²Û°  ß °Ü Ü  °Ý°Üu²ÛßÝÞ²ÛÛÝÜ° ßß ° ²ÛÛÛÜ
  ܲÛÛÛÛÛÛÜÜ° ÜÜÜÜÜÜß°° þÜÜ  ÜÛÜÛß°ÜÜ  Û۲߰þÜÜÜÜÜ   °ÜܲÛÛÛÛ²ÛÜ
ܲÛÛÛÛÛÛÛÛ²ÛÛÛÛÛÛÛÛÛ²ßß° ßß± ßß Û°ßß°ßßÛÛÛÜ°Üܲßß ßß°ßß²ÜÜÜܲÛÛÛÛÛÛ²ÛÛÛÛ²Ü
 a world  °far beyond ÛÛÛ²ÛÜ  your°dreams  ±
²ÛÛÛÛ۲߰
 +33-1-4879o422 ÛÛÛÛÛß sysops gizmo & bisounours ÛÛ²ß ²ß  ° SAUCE00Dune Bisounours Fire 19960527þqP

Binary file not shown.

View file

@ -16,28 +16,11 @@ Cd(__DIR__);;
#define MAX_ANSI_PARAMS 32 #define MAX_ANSI_PARAMS 32
#include "TelnetNegotiation" #include "TelnetClass"
#include "TelnetHelpers" #include "TelnetHelpers"
Bool force_disconnect = FALSE; Bool force_disconnect = FALSE;
class Terminal {
I64 sock;
Bool sock_ready;
I64 window_width;
I64 window_height;
CDoc *doc;
CTask *task;
I64 current_color;
I64 current_bgcolor;
I64 cursor_x;
I64 cursor_y;
U8 buffer[BUF_SIZE];
I64 buffer_len;
} term;
I64 TelnetOpen(U8 *host, U16 port) { I64 TelnetOpen(U8 *host, U16 port) {
I64 sock; I64 sock;
@ -143,52 +126,6 @@ U0 HandleControlCodes(U8 ch) {
} }
} }
I64 LoadSplashScreen(U8 *filename) {
CFile *file = FOpen(filename, "rb");
if (!file) {
PrintErr("Failed to open file");
return -1;
}
// Ensure that the file size isn't larger than the buffer
if (file->de.size > BUF_SIZE) {
PrintErr("File is too large for the buffer.");
FClose(file);
return -1;
}
// Calculate the number of full blocks to read based on file size and block size
I64 full_blocks = file->de.size / BLK_SIZE;
I64 remaining_bytes = file->de.size % BLK_SIZE;
SysLog("File size: %d, Number of full blocks: %d, Remaining bytes: %d\n", file->de.size, full_blocks, remaining_bytes);
// Read the full blocks into the buffer
I64 i, blocks_read = 0;
for (i = 0; i < full_blocks; i++) {
blocks_read += FBlkRead(file, term.buffer + i * BLK_SIZE, i, 1);
}
// Check if there are any remaining bytes in the last block
if (remaining_bytes != 0) {
// Read the remaining bytes
U8 temp_buffer[BLK_SIZE];
if (FBlkRead(file, temp_buffer, full_blocks, 1)) {
blocks_read++;
MemCopy(term.buffer + full_blocks * BLK_SIZE, temp_buffer, remaining_bytes);
}
}
FClose(file);
if (blocks_read != (full_blocks + (remaining_bytes != 0))) {
PrintErr("Failed to read all the blocks");
return -1;
}
return file->de.size; // Return the number of bytes read
}
U0 ANSIParse() U0 ANSIParse()
{ {
// Basic Telnet protocol parser // Basic Telnet protocol parser
@ -247,8 +184,7 @@ U0 ANSIParse()
deviceStatusResponse[2] = 0x30; // '0' deviceStatusResponse[2] = 0x30; // '0'
deviceStatusResponse[3] = 0x6E; // 'n' deviceStatusResponse[3] = 0x6E; // 'n'
deviceStatusResponse[4] = 0x00; // Null-terminator deviceStatusResponse[4] = 0x00; // Null-terminator
TCPSocketSend(term.sock, deviceStatusResponse, 4); if (term.sock_ready) TCPSocketSend(term.sock, deviceStatusResponse, 4);
// TCPSocketSendString(term.sock, "\x1B[0n");
} }
else if (ansi_code[0] == 6) { else if (ansi_code[0] == 6) {
// Respond with cursor position // Respond with cursor position
@ -264,8 +200,7 @@ U0 ANSIParse()
cursorResponse[6] = 0x30; cursorResponse[6] = 0x30;
cursorResponse[6] = 0x52; cursorResponse[6] = 0x52;
cursorResponse[7] = 0x00; cursorResponse[7] = 0x00;
TCPSocketSend(term.sock, cursorResponse, 7); if (term.sock_ready) TCPSocketSend(term.sock, cursorResponse, 7);
// TCPSocketSendString(term.sock, "\x1B\[25;80R");
} }
else if (ansi_code[0] == 255) { else if (ansi_code[0] == 255) {
// https://github.com/NuSkooler/enigma-bbs/blob/97cd0c3063b0c9f93a0fa4a44a85318ca81aef43/core/ansi_term.js#L140 // https://github.com/NuSkooler/enigma-bbs/blob/97cd0c3063b0c9f93a0fa4a44a85318ca81aef43/core/ansi_term.js#L140
@ -277,7 +212,6 @@ U0 ANSIParse()
case 'c': case 'c':
// Respond with device attributes // Respond with device attributes
SysLog("reported device attributes\n"); SysLog("reported device attributes\n");
// TCPSocketSendString(term.sock, "\x1B[?1;0c");
// Reports at VT101 (not sure why though) // Reports at VT101 (not sure why though)
U8 deviceAttributesResponse[8]; U8 deviceAttributesResponse[8];
deviceAttributesResponse[0] = ANSI_ESC; deviceAttributesResponse[0] = ANSI_ESC;
@ -288,7 +222,7 @@ U0 ANSIParse()
deviceAttributesResponse[5] = 0x32; // '0' deviceAttributesResponse[5] = 0x32; // '0'
deviceAttributesResponse[6] = 0x63; // 'c' deviceAttributesResponse[6] = 0x63; // 'c'
deviceAttributesResponse[7] = 0x00; // Null-terminator deviceAttributesResponse[7] = 0x00; // Null-terminator
TCPSocketSend(term.sock, deviceAttributesResponse, 7); if (term.sock_ready) TCPSocketSend(term.sock, deviceAttributesResponse, 7);
ptr++; ptr++;
break; break;
case 'm': case 'm':
@ -687,11 +621,13 @@ U0 TerminalTask() {
} }
U0 Telnet(U8 *host=NULL, U16 port=TELNET_PORT) { U0 Telnet(U8 *host=NULL, U16 port=TELNET_PORT) {
I64 sc; CHostForm form;
term.window_width = 80; term.window_width = 80;
term.window_height = 25; term.window_height = 25;
term.doc = Fs->display_doc; term.doc = Fs->display_doc;
term.waiting_for_input = TRUE;
term.sock_ready = 0;
I64 art_path = "Art/TelnetSplash.ans";
StrCopy(Fs->task_title, "TELNET"); StrCopy(Fs->task_title, "TELNET");
Fs->border_src = BDS_CONST; Fs->border_src = BDS_CONST;
@ -712,8 +648,11 @@ U0 Telnet(U8 *host=NULL, U16 port=TELNET_PORT) {
Fs); Fs);
DocClear; DocClear;
show_splash:
// SplashScreen // SplashScreen
term.buffer_len = LoadSplashScreen("Art/TelnetSplash.ans"); // I64 buffer_size = sizeof(term.buffer);
term.buffer_len = ANSIArtLoad(art_path, term.buffer);
if (term.buffer_len > 0) { if (term.buffer_len > 0) {
term.buffer[term.buffer_len] = '\0'; term.buffer[term.buffer_len] = '\0';
// parse the buffer // parse the buffer
@ -723,22 +662,12 @@ U0 Telnet(U8 *host=NULL, U16 port=TELNET_PORT) {
"Error: Could not load splash screen.\n"; "Error: Could not load splash screen.\n";
} }
// PopUp if no host is specified
if (host == NULL) { init_connection:
try while (!term.waiting_for_input || host != NULL)
{ {
while (host == NULL) { // if(term.sock != NULL) TCPSocketClose(term.sock);
CHostForm form; // TODO: should probably kill the task if it already exists too?
TelnetPrompt(&form);
host = form.host;
port = form.port;
DocClear;
break;
}
}
catch
PutExcept;
}
// Spawn a task to receive data from the socket // Spawn a task to receive data from the socket
term.task = Spawn(&TerminalTask, NULL, "Telnet"); term.task = Spawn(&TerminalTask, NULL, "Telnet");
@ -747,17 +676,21 @@ U0 Telnet(U8 *host=NULL, U16 port=TELNET_PORT) {
DocPrint(, "$$WW,1$$"); DocPrint(, "$$WW,1$$");
DocCursor(OFF); DocCursor(OFF);
term.sock_ready = 0; // Initialize the semaphore
term.sock = TelnetOpen(host, port); term.sock = TelnetOpen(host, port);
if (term.sock <= 0) { if (term.sock <= 0) {
return; return;
} }
term.sock_ready = 1; // Signal that the socket is ready term.sock_ready = 1; // Signal that the socket is ready
term.waiting_for_input = FALSE;
"$$BG,GREEN$$$$WHITE$$Connected$$FG$$$$BG$$\n"; "$$BG,GREEN$$$$WHITE$$Connected$$FG$$$$BG$$\n";
Sleep(1000); Sleep(1000);
DocClear; DocClear;
break;
}
I64 sc;
try try
{ {
while (!force_disconnect) { while (!force_disconnect) {
@ -768,19 +701,19 @@ U0 Telnet(U8 *host=NULL, U16 port=TELNET_PORT) {
switch (sc.u8[0]) switch (sc.u8[0])
{ {
case SC_CURSOR_LEFT: case SC_CURSOR_LEFT:
TCPSocketSendString(term.sock, "\x1B[D"); if (term.sock_ready) TCPSocketSendString(term.sock, "\x1B[D");
break; break;
case SC_CURSOR_RIGHT: case SC_CURSOR_RIGHT:
TCPSocketSendString(term.sock, "\x1B[C"); if (term.sock_ready) TCPSocketSendString(term.sock, "\x1B[C");
break; break;
case SC_CURSOR_UP: case SC_CURSOR_UP:
TCPSocketSendString(term.sock, "\x1B[A"); if (term.sock_ready) TCPSocketSendString(term.sock, "\x1B[A");
break; break;
case SC_CURSOR_DOWN: case SC_CURSOR_DOWN:
TCPSocketSendString(term.sock, "\x1B[B"); if (term.sock_ready) TCPSocketSendString(term.sock, "\x1B[B");
break; break;
default: default:
break; break;
@ -790,24 +723,43 @@ U0 Telnet(U8 *host=NULL, U16 port=TELNET_PORT) {
switch (sc.u8[0]) switch (sc.u8[0])
{ {
case SC_TAB: case SC_TAB:
TCPSocketSendString(term.sock, "\x09"); if (term.sock_ready) TCPSocketSendString(term.sock, "\x09");
break; break;
default: default:
break; break;
} }
case CH_BACKSPACE: case CH_BACKSPACE:
TCPSocketSendString(term.sock, "\x08"); if (term.sock_ready) TCPSocketSendString(term.sock, "\x08");
break; break;
case CH_ESC: case CH_ESC:
TCPSocketSendString(term.sock, "\x1B"); if (term.sock_ready) TCPSocketSendString(term.sock, "\x1B");
break; break;
case CH_SHIFT_ESC: case CH_SHIFT_ESC:
force_disconnect = TRUE; force_disconnect = TRUE;
break; break;
// send buffer on enter // send buffer on enter
case '\n': case '\n':
TCPSocketSendString(term.sock, "\r\n"); if (term.sock_ready) TCPSocketSendString(term.sock, "\r\n");
break;
case CH_CTRLN:
TelnetPrompt(&form);
host = form.host;
port = form.port;
DocClear;
term.waiting_for_input = FALSE;
goto init_connection;
break;
case CH_CTRLO:
art_path = ANSIArtBrowser;
if (art_path != NULL) {
term.sock_ready = 0;
term.waiting_for_input = TRUE;
SysLog("%s\n", art_path);
goto show_splash;
}
else {
"Error: Could not load art.\n";
}
break; break;
default: default:
if (key >= ' ' && key <= '~') { if (key >= ' ' && key <= '~') {
@ -815,7 +767,7 @@ U0 Telnet(U8 *host=NULL, U16 port=TELNET_PORT) {
U8 input_buf[2]; U8 input_buf[2];
input_buf[0] = key; input_buf[0] = key;
input_buf[1] = '\0'; input_buf[1] = '\0';
TCPSocketSend(term.sock, input_buf, 1); if (term.sock_ready) TCPSocketSend(term.sock, input_buf, 1);
} }
break; break;
} }
@ -830,5 +782,5 @@ U0 Telnet(U8 *host=NULL, U16 port=TELNET_PORT) {
// dev server // dev server
Telnet("localhost", 8888); // Telnet("localhost", 8888);
// Telnet; Telnet;

View file

@ -0,0 +1,17 @@
class Terminal {
I64 sock;
Bool sock_ready;
Bool waiting_for_input;
I64 window_width;
I64 window_height;
CDoc *doc;
CTask *task;
I64 current_color;
I64 current_bgcolor;
I64 cursor_x;
I64 cursor_y;
U8 buffer[BUF_SIZE];
I64 buffer_len;
} term;

View file

@ -177,11 +177,58 @@ U0 HandleControlCodes(U8 ch) {
} }
I64 LoadSplashScreen(U8 *filename) {
CFile *file = FOpen(filename, "rb");
if (!file) {
PrintErr("Failed to open file");
return -1;
}
// Ensure that the file size isn't larger than the buffer
if (file->de.size > BUF_SIZE) {
PrintErr("File is too large for the buffer.");
FClose(file);
return -1;
}
// Calculate the number of full blocks to read based on file size and block size
I64 full_blocks = file->de.size / BLK_SIZE;
I64 remaining_bytes = file->de.size % BLK_SIZE;
SysLog("File size: %d, Number of full blocks: %d, Remaining bytes: %d\n", file->de.size, full_blocks, remaining_bytes);
// Read the full blocks into the buffer
I64 i, blocks_read = 0;
for (i = 0; i < full_blocks; i++) {
blocks_read += FBlkRead(file, term.buffer + i * BLK_SIZE, i, 1);
}
// Check if there are any remaining bytes in the last block
if (remaining_bytes != 0) {
// Read the remaining bytes
U8 temp_buffer[BLK_SIZE];
if (FBlkRead(file, temp_buffer, full_blocks, 1)) {
blocks_read++;
MemCopy(term.buffer + full_blocks * BLK_SIZE, temp_buffer, remaining_bytes);
}
}
FClose(file);
if (blocks_read != (full_blocks + (remaining_bytes != 0))) {
PrintErr("Failed to read all the blocks");
return -1;
}
return file->de.size; // Return the number of bytes read
}
U0 TerminalDrawIt(CTask *task, CDC *dc) U0 TerminalDrawIt(CTask *task, CDC *dc)
{ {
// Clear the document // Clear the document
// DocClear(term.doc); // DocClear(term.doc);
DCFill(dc,BLUE); Sleep(100);
DCFill;
I64 row, col; I64 row, col;
// Loop over the screen array and draw each character // Loop over the screen array and draw each character
@ -204,21 +251,12 @@ U0 TerminalDrawIt(CTask *task, CDC *dc)
// Draw the curso // Draw the curso
// Note: this draws the cursor as a white rectangle. You may want to customize this. // Note: this draws the cursor as a white rectangle. You may want to customize this.
// dc->color = WHITE; // dc->color = WHITE;
// GrRect(dc, term.cursor_x * 8, term.cursor_y * 8, // GrRect(term.dc, term.cursor_x * 8, term.cursor_y * 8,
// (term.cursor_x + 1) * 8 - 1, (term.cursor_y + 1) * 8 - 1); // (term.cursor_x + 1) * 8 - 1, (term.cursor_y + 1) * 8 - 1);
} }
U0 TerminalTask() { U0 ANSIParse()
while (!term.sock_ready) {
Sleep(100); // Avoid busy waiting
}
// This task receives data from the socket and fills the buffer
while (!force_disconnect)
{ {
term.buffer_len = TCPSocketReceive(term.sock, term.buffer, BUF_SIZE - 1);
if (term.buffer_len > 0) {
redraw_needed = TRUE;
term.buffer[term.buffer_len] = '\0';
// Parse the buffer and draw the contents // Parse the buffer and draw the contents
U8 *ptr = term.buffer; U8 *ptr = term.buffer;
while (ptr < term.buffer + term.buffer_len) { while (ptr < term.buffer + term.buffer_len) {
@ -581,7 +619,7 @@ U0 TerminalTask() {
} else if (ansi_code[0] == 2) { } else if (ansi_code[0] == 2) {
// Erase entire display // Erase entire display
// DocClear(term.doc); // DocClear(term.doc);
// DCFill(dc,BLACK); DCFill(term.dc,BLACK);
// term.cursor_x = 0; // term.cursor_x = 0;
// term.cursor_y = 0; // term.cursor_y = 0;
// redraw_needed = TRUE; // redraw_needed = TRUE;
@ -703,6 +741,20 @@ U0 TerminalTask() {
// term.cursor_y = 0; // term.cursor_y = 0;
redraw_needed = FALSE; redraw_needed = FALSE;
} }
}
U0 TerminalTask() {
while (!term.sock_ready) {
Sleep(100); // Avoid busy waiting
}
// This task receives data from the socket and fills the buffer
while (!force_disconnect)
{
term.buffer_len = TCPSocketReceive(term.sock, term.buffer, BUF_SIZE - 1);
if (term.buffer_len > 0) {
redraw_needed = TRUE;
term.buffer[term.buffer_len] = '\0';
ANSIParse;
} else { } else {
"Error: Connection closed by the remote host.\n"; "Error: Connection closed by the remote host.\n";
break; break;
@ -720,7 +772,8 @@ U0 Telnet(U8 *host, U16 port=TELNET_PORT) {
return; return;
} }
term.sock_ready = 1; // Signal that the socket is ready term.sock_ready = 1; // Signal that the socket is ready
term.doc = Fs->display_doc; term.dc = DCNew(term.window_width, term.window_height);
term.doc = Fs->put_doc;
// Spawn a task to receive data from the socket // Spawn a task to receive data from the socket
term.task = Spawn(&TerminalTask, NULL, "Telnet"); term.task = Spawn(&TerminalTask, NULL, "Telnet");
@ -746,14 +799,38 @@ U0 Telnet(U8 *host, U16 port=TELNET_PORT) {
(Fs->win_height - 1), (Fs->win_height - 1),
Fs); Fs);
DocClear; DocClear;
// WinFocus(term.task);
// DocClear(Fs->border_doc, TRUE);
// probably should use word wrap? // SplashScreen
// DocPrint(, "$$WW,1$$"); term.buffer_len = LoadSplashScreen("Art/TelnetSplash.ans");
// DocCursor(OFF); if (term.buffer_len > 0) {
// term.dc = DCAlias; term.buffer[term.buffer_len] = '\0';
// parse the buffer
ANSIParse;
}
else {
"Error: Could not load splash screen.\n";
}
// PopUp if no host is specified
if (host == NULL) {
try
{
while (host == NULL) {
CHostForm form;
TelnetPrompt(&form);
host = form.host;
port = form.port;
DocClear;
break;
}
}
catch
PutExcept;
}
"$$BG,GREEN$$$$WHITE$$Connected$$FG$$$$BG$$\n"; "$$BG,GREEN$$$$WHITE$$Connected$$FG$$$$BG$$\n";
Sleep(1000);
DocClear;
I64 sc; I64 sc;
// https://theasciicode.com.ar/ascii-control-characters/escape-ascii-code-27.html // https://theasciicode.com.ar/ascii-control-characters/escape-ascii-code-27.html

View file

@ -1,3 +1,7 @@
Cd(__DIR__);
#include "TelnetClass"
#include "TelnetNegotiation"
U8 IsDigit(U8 ch) { U8 IsDigit(U8 ch) {
return '0' <= ch <= '9'; return '0' <= ch <= '9';
} }
@ -13,6 +17,87 @@ U0 TelnetPrompt(CHostForm *form) {
PopUpForm(form); PopUpForm(form);
} }
I64 ANSIArtLoad(U8 *filename, U8 *buffer) {
CFile *file = FOpen(filename, "rb");
if (!file) {
PrintErr("Failed to open file");
return -1;
}
// Allocate memory for the buffer based on file size
*buffer = MAlloc(file->de.size);
if (!(*buffer)) {
PrintErr("Failed to allocate memory for the buffer");
FClose(file);
return -1;
}
// Calculate the number of full blocks to read based on file size and block size
I64 full_blocks = file->de.size / BLK_SIZE;
I64 remaining_bytes = file->de.size % BLK_SIZE;
SysLog("File size: %d, Number of full blocks: %d, Remaining bytes: %d\n", file->de.size, full_blocks, remaining_bytes);
// Read the full blocks into the buffer
I64 i, blocks_read = 0;
for (i = 0; i < full_blocks; i++) {
blocks_read += FBlkRead(file, buffer + i * BLK_SIZE, i, 1);
}
// Check if there are any remaining bytes in the last block
if (remaining_bytes != 0) {
// Read the remaining bytes
U8 temp_buffer[BLK_SIZE];
if (FBlkRead(file, temp_buffer, full_blocks, 1)) {
blocks_read++;
MemCopy(buffer + full_blocks * BLK_SIZE, temp_buffer, remaining_bytes);
}
}
FClose(file);
if (blocks_read != (full_blocks + (remaining_bytes != 0))) {
PrintErr("Failed to read all the blocks");
return -1;
}
return file->de.size; // Return the number of bytes read
}
public I64 ANSIArtBrowser()
{
CDirEntry *tmpde1 = NULL, *tmpde2;
CDoc *doc = DocNew;
I64 res = 0;
I64 res2 = 0;
DocPrint(doc, "$$LTBLUE$$\n\n");
tmpde1 = FilesFind("Art/*.ans");
if (tmpde1)
{
while (tmpde1)
{
tmpde2 = tmpde1->next;
res++;
DocPrint(doc, " $$MU,\"%d.%s\",LE=0x%X$$\n", res, tmpde1->name, tmpde1->name);
DirEntryDel(tmpde1);
tmpde1 = tmpde2;
}
}
DocPrint(doc, "\n\n$$BT+CX,\"CANCEL\",LE=0$$\n\n");
res2 = PopUpMenu(doc);
DocDel(doc);
return MStrPrint("%Q%Q", "Art/", res2);
}
// Placeholder for the full ANSI text styling // Placeholder for the full ANSI text styling
// if (ansi_code[m] <= 10) { // if (ansi_code[m] <= 10) {