1066 lines
23 KiB
C++
1066 lines
23 KiB
C++
#define Use_MsgBase
|
||
|
||
#include <ctype.h>
|
||
#include <string.h>
|
||
#include <stdlib.h>
|
||
#include <tswin.hpp>
|
||
#include <time.h>
|
||
#include <io.h>
|
||
#include <dos.h>
|
||
#include "desqview.hpp"
|
||
#include "proboard.hpp"
|
||
#include "fossil.hpp"
|
||
|
||
static String align_string(char *s , int width , int alignment);
|
||
|
||
static void near
|
||
nocarrier()
|
||
{
|
||
if(ignore_carrier) return;
|
||
|
||
dword ticks = clockticks();
|
||
|
||
for(;clockdiff(ticks)<10;) // Check for 1/2 second
|
||
{
|
||
msleep(100);
|
||
|
||
if(fos_carrier(io.port)) return;
|
||
}
|
||
|
||
LOG("Carrier lost!");
|
||
|
||
exit_proboard();
|
||
}
|
||
|
||
static byte conversion[256];
|
||
|
||
void
|
||
fossilio::init(int p,long b)
|
||
{
|
||
byte baudcode;
|
||
|
||
for(int i=0;i<256;i++) conversion[i]=i;
|
||
|
||
conversion[(byte)'Ú']='+';
|
||
conversion[(byte)'Ã']='+';
|
||
conversion[(byte)'À']='+';
|
||
conversion[(byte)'Â']='+';
|
||
conversion[(byte)'Å']='+';
|
||
conversion[(byte)'Á']='+';
|
||
conversion[(byte)'¿']='+';
|
||
conversion[(byte)'´']='+';
|
||
conversion[(byte)'Ù']='+';
|
||
conversion[(byte)'É']='+';
|
||
conversion[(byte)'Ë']='+';
|
||
conversion[(byte)'»']='+';
|
||
conversion[(byte)'Ì']='+';
|
||
conversion[(byte)'Î']='+';
|
||
conversion[(byte)'¹']='+';
|
||
conversion[(byte)'È']='+';
|
||
conversion[(byte)'Ê']='+';
|
||
conversion[(byte)'¼']='+';
|
||
conversion[(byte)'Ö']='+';
|
||
conversion[(byte)'Ò']='+';
|
||
conversion[(byte)'·']='+';
|
||
conversion[(byte)'Ç']='+';
|
||
conversion[(byte)'×']='+';
|
||
conversion[(byte)'¶']='+';
|
||
conversion[(byte)'Ó']='+';
|
||
conversion[(byte)'Ð']='+';
|
||
conversion[(byte)'½']='+';
|
||
conversion[(byte)'Õ']='+';
|
||
conversion[(byte)'Ñ']='+';
|
||
conversion[(byte)'¸']='+';
|
||
conversion[(byte)'Æ']='+';
|
||
conversion[(byte)'Ø']='+';
|
||
conversion[(byte)'µ']='+';
|
||
conversion[(byte)'Ô']='+';
|
||
conversion[(byte)'Ï']='+';
|
||
conversion[(byte)'¾']='+';
|
||
conversion[(byte)'Í']='-';
|
||
conversion[(byte)'Ä']='-';
|
||
conversion[(byte)'³']='|';
|
||
conversion[(byte)'º']='|';
|
||
conversion[(byte)'Û']='#';
|
||
conversion[(byte)'û']='*';
|
||
conversion[(byte)'']='^';
|
||
conversion[(byte)'']='v';
|
||
conversion[(byte)'°']='#';
|
||
conversion[(byte)'±']='#';
|
||
conversion[(byte)'²']='#';
|
||
|
||
port=p;
|
||
baud=b;
|
||
stopenabled=0;
|
||
show_local = TRUE;
|
||
show_remote = TRUE;
|
||
more_func = NULLFUNC;
|
||
|
||
inputbuffer.clear();
|
||
|
||
if(baud)
|
||
{
|
||
switch(baud)
|
||
{
|
||
case 300L: baudcode=0x43; break;
|
||
case 1200L: baudcode=0x83; break;
|
||
case 2400L: baudcode=0xA3; break;
|
||
case 4800L: baudcode=0xC3; break;
|
||
case 7200L:
|
||
case 9600L: baudcode=0xE3; break;
|
||
case 12000L:
|
||
case 14400L:
|
||
case 16800L:
|
||
case 19200L: baudcode=0x03; break;
|
||
default : baudcode=0x23; break;
|
||
}
|
||
|
||
fos_init(port);
|
||
fos_setbps(port,baudcode);
|
||
fos_flowctl(port,2);
|
||
sleep(1);
|
||
}
|
||
|
||
if(outputBuffer == NULL)
|
||
outputBuffer = new byte[cfg.IObuffersize];
|
||
|
||
bufferPtr = 0;
|
||
|
||
SCREEN.disableCursor();
|
||
}
|
||
|
||
void
|
||
fossilio::clearinput()
|
||
{
|
||
fos_purgeinput(port);
|
||
}
|
||
|
||
fossilio::~fossilio()
|
||
{
|
||
cooldown();
|
||
|
||
if(outputBuffer != NULL)
|
||
delete [] outputBuffer;
|
||
}
|
||
|
||
void fossilio::cooldown()
|
||
{
|
||
if(baud && baud != 65535L)
|
||
{
|
||
fos_purgeoutput(port);
|
||
fos_deinit(port);
|
||
sleep(1);
|
||
}
|
||
}
|
||
|
||
void
|
||
fossilio::heatup()
|
||
{
|
||
if(baud)
|
||
{
|
||
fos_init(port);
|
||
sleep(1);
|
||
}
|
||
|
||
bufferPtr = 0;
|
||
}
|
||
|
||
byte
|
||
fossilio::readkey()
|
||
{
|
||
if(KB.hit())
|
||
{
|
||
KEY key=KB.get();
|
||
if(key>256)
|
||
{
|
||
sysopkey(key);
|
||
return 0;
|
||
}
|
||
else
|
||
{
|
||
external=0;
|
||
return (byte)key;
|
||
}
|
||
}
|
||
|
||
static dword prevticks = 0;
|
||
|
||
if(clockdiff(prevticks)>90)
|
||
{
|
||
static int inchatreq=0;
|
||
|
||
prevticks = clockticks();
|
||
|
||
SCRAMBLE();
|
||
|
||
timer.check();
|
||
|
||
if(!access(form("%sDOWN.%d",syspath,node_number),0))
|
||
{
|
||
io << S_SYSTEM_GOING_DOWN;
|
||
|
||
LOG("Going down on external request");
|
||
|
||
File f;
|
||
f.open(form("%sISDOWN.%d",syspath,node_number),fmode_create|fmode_write);
|
||
f.close();
|
||
|
||
exit_proboard(100);
|
||
}
|
||
|
||
if(!inchatreq && cfg.numnodes>1 && !chatflag)
|
||
{
|
||
user_online uo;
|
||
int cht=uo.check_chat();
|
||
|
||
if(cht)
|
||
{
|
||
inchatreq=1;
|
||
uo.read(cht);
|
||
io << "\n\n" << S_USER_REQUESTS_CHAT(uo.name,form("%d",cht));
|
||
|
||
if(ask(1))
|
||
{
|
||
uo.setstatus(UO_CHATTING);
|
||
|
||
io << "\n\n" << S_MULTILINE_CHAT_STARTED;
|
||
|
||
multilinechat(cht);
|
||
|
||
io << "\n\n" << S_MULTILINE_CHAT_ENDED << "\n\n" << S_PRESS_ENTER_TO_CONTINUE;
|
||
|
||
uo.setstatus(UO_BROWSING);
|
||
}
|
||
else
|
||
{
|
||
uo.setstatus(UO_BUSY);
|
||
}
|
||
|
||
inchatreq=0;
|
||
}
|
||
}
|
||
}
|
||
|
||
if(!baud) return 0;
|
||
|
||
FOS_STATUS status = fos_status(port);
|
||
|
||
if(!status_carrier(status)) nocarrier();
|
||
|
||
if(status_byteready(status))
|
||
{
|
||
external = 1;
|
||
return fos_getch(port);
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
void
|
||
fossilio::flush()
|
||
{
|
||
SCREEN.placeCursor();
|
||
|
||
if(bufferPtr)
|
||
{
|
||
for(;;)
|
||
{
|
||
FOS_STATUS s = fos_status(port);
|
||
|
||
if(!(s & FSTAT_CARRIER)) nocarrier();
|
||
|
||
word x = fos_sendblock(port,outputBuffer,bufferPtr);
|
||
|
||
if(x >= bufferPtr) break;
|
||
|
||
bufferPtr -= x;
|
||
|
||
memmove( outputBuffer , &outputBuffer[x] , bufferPtr);
|
||
}
|
||
|
||
bufferPtr = 0;
|
||
}
|
||
}
|
||
|
||
fossilio&
|
||
fossilio::operator<<(char c)
|
||
{
|
||
if(c=='\f' && !cls_mode && user_recnr>=0 && !SCREEN.inEscape()) return *this;
|
||
|
||
if(c=='\f' && !SCREEN.inEscape())
|
||
{
|
||
color(COLOR_WHITE);
|
||
linecounter(0);
|
||
}
|
||
|
||
if(c=='\n' && !SCREEN.inEscape()) (*this) << '\r';
|
||
|
||
if(no_ibm) c=conversion[(byte)c];
|
||
|
||
if(byte(c) == byte(255))
|
||
{
|
||
flush();
|
||
|
||
return *this;
|
||
}
|
||
|
||
if(baud && show_remote)
|
||
{
|
||
if(cfg.IObuffersize == 1)
|
||
{
|
||
for(;;)
|
||
{
|
||
FOS_STATUS s = fos_status(port);
|
||
|
||
if(!(s & FSTAT_CARRIER)) nocarrier();
|
||
|
||
if(s & FSTAT_BUFEMPTY) break;
|
||
}
|
||
|
||
fos_send(port,c);
|
||
}
|
||
else
|
||
{
|
||
outputBuffer[bufferPtr++] = c;
|
||
|
||
if(bufferPtr == cfg.IObuffersize) flush();
|
||
}
|
||
}
|
||
|
||
if(show_local) SCREEN << c;
|
||
|
||
return *this;
|
||
}
|
||
|
||
fossilio&
|
||
fossilio::operator<<(char *s)
|
||
{
|
||
send(s);
|
||
|
||
return *this;
|
||
}
|
||
|
||
byte
|
||
fossilio::send(char *str,char *hotkeys)
|
||
{
|
||
if(hotkeys)
|
||
strupr(hotkeys);
|
||
|
||
for(;*str;str++)
|
||
{
|
||
byte c=0;
|
||
|
||
if(SCREEN.inEscape())
|
||
{
|
||
(*this) << (*str);
|
||
|
||
continue;
|
||
}
|
||
|
||
if(stopenabled || hotkeys)
|
||
c = toupper(readkey());
|
||
|
||
if(hotkeys && c)
|
||
if(strchr(hotkeys,c))
|
||
{
|
||
return c;
|
||
}
|
||
|
||
if(c=='S')
|
||
{
|
||
stopped = TRUE;
|
||
flush();
|
||
|
||
return 1;
|
||
}
|
||
|
||
if(c=='P')
|
||
wait("P\r");
|
||
|
||
c = *str;
|
||
|
||
if(c=='\t')
|
||
{
|
||
wait('\r');
|
||
|
||
continue;
|
||
}
|
||
|
||
if(c == 26)
|
||
{
|
||
fullcolor(*(++str));
|
||
continue;
|
||
}
|
||
|
||
if(c<8 && c>0)
|
||
{
|
||
color(c);
|
||
|
||
continue;
|
||
}
|
||
|
||
if(c == 24 || c == 25)
|
||
{
|
||
int l = int(*(str+1));
|
||
char *fname = new char[l+1];
|
||
strncpy(fname,str+2,l);
|
||
fname[l] = '\0';
|
||
|
||
if(c == 24)
|
||
run_sdkfile(fname);
|
||
else
|
||
showansasc(fname);
|
||
|
||
str += l+1;
|
||
|
||
delete [] fname;
|
||
|
||
continue;
|
||
}
|
||
|
||
if(c<0x18 && c>0x10 && c!=0x16)
|
||
{
|
||
color((c-0x10)|0x80);
|
||
}
|
||
else
|
||
{
|
||
(*this) << c;
|
||
}
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
#pragma warn -def
|
||
|
||
const int ALIGN_LEFT = 0,
|
||
ALIGN_RIGHT = 1,
|
||
ALIGN_CENTER = 2;
|
||
|
||
byte
|
||
fossilio::sendfile(char *fn,char *hotkeys)
|
||
{
|
||
bool fflag = FALSE,
|
||
kflag = FALSE,
|
||
moreok = TRUE,
|
||
stopok = TRUE,
|
||
avt_compr = FALSE;
|
||
|
||
int alignment = ALIGN_LEFT;
|
||
|
||
String str;
|
||
|
||
if(rip_mode && (!show_local || !show_remote))
|
||
{
|
||
moreok = FALSE;
|
||
stopok = FALSE;
|
||
}
|
||
|
||
static char *on_string = "ON " , *off_string = "OFF";
|
||
|
||
int fieldwidth;
|
||
byte avt_compr_char = '\0';
|
||
|
||
File f(fn,fmode_read,1024);
|
||
if(!f.opened()) return 2;
|
||
|
||
if(hotkeys) strupr(hotkeys);
|
||
|
||
linecounter(0);
|
||
for(;;)
|
||
{
|
||
byte c=toupper(readkey());
|
||
if(hotkeys && c) if(strchr(hotkeys,c))
|
||
{
|
||
return c;
|
||
}
|
||
if(c=='S' && stopok)
|
||
{
|
||
stopped=1;
|
||
flush();
|
||
return 1;
|
||
}
|
||
if(c=='P') wait("\rP");
|
||
|
||
int x=f.readByte();
|
||
if(x<0) break;
|
||
|
||
byte input=(byte)x;
|
||
|
||
if(avt_compr)
|
||
{
|
||
if(fflag || kflag)
|
||
{
|
||
if(!avt_compr_char)
|
||
{
|
||
avt_compr_char = input;
|
||
}
|
||
else
|
||
{
|
||
if(avt_compr_char=='@' || avt_compr_char=='#' || avt_compr_char=='%')
|
||
{
|
||
fieldwidth += input;
|
||
|
||
switch(avt_compr_char)
|
||
{
|
||
case '@': alignment = ALIGN_LEFT; break;
|
||
case '#': alignment = ALIGN_RIGHT; break;
|
||
case '%': alignment = ALIGN_CENTER; break;
|
||
}
|
||
}
|
||
avt_compr = FALSE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
avt_compr = FALSE;
|
||
|
||
(*this) << char(25) << input;
|
||
}
|
||
|
||
continue;
|
||
}
|
||
|
||
if(SCREEN.inEscape())
|
||
{
|
||
(*this) << input;
|
||
continue;
|
||
}
|
||
|
||
if(input == 0x19)
|
||
{
|
||
avt_compr = TRUE;
|
||
avt_compr_char = '\0';
|
||
continue;
|
||
}
|
||
|
||
if((fflag || kflag) && (input=='@' || input=='#' || input=='%'))
|
||
{
|
||
fieldwidth++;
|
||
|
||
switch(input)
|
||
{
|
||
case '@': alignment = ALIGN_LEFT; break;
|
||
case '#': alignment = ALIGN_RIGHT; break;
|
||
case '%': alignment = ALIGN_CENTER; break;
|
||
}
|
||
|
||
continue;
|
||
}
|
||
|
||
if(fflag)
|
||
{
|
||
switch(input)
|
||
{
|
||
case 'A': str = user.name; break;
|
||
case 'B': str = user.city; break;
|
||
case 'C': str = user.passWord; break;
|
||
case 'D': str = user.dataPhone; break;
|
||
case 'E': str = user.voicePhone; break;
|
||
case 'F': str = user.lastDate.format("D MMM CCYY"); break;
|
||
case 'G': str = user.lastTime.format("HH:MM:SS"); break;
|
||
case 'H':
|
||
case 'I':
|
||
case 'J':
|
||
case 'K': {
|
||
char s[33];
|
||
user.aFlags.flagstostr(s);
|
||
str = s;
|
||
} break;
|
||
case 'L': str = form("%d",user.credit); break;
|
||
case 'M': str = form("%lu",user.msgsPosted); break;
|
||
case 'N': str = form("%d",user.highMsgRead); break;
|
||
case 'O': str = form("%u",user.level); break;
|
||
case 'P': str = form("%lu",user.timesCalled); break;
|
||
case 'Q': str = form("%lu",user.numUploads); break;
|
||
case 'R': str = form("%lu",user.kbUploaded); break;
|
||
case 'S': str = form("%lu",user.numDownloads); break;
|
||
case 'T': str = form("%lu",user.kbDownloaded); break;
|
||
case 'U': str = form("%ld",user.timeUsed); break;
|
||
case 'V': str = form("%d",user.screenLength); break;
|
||
case 'W': str = user_firstname; break;
|
||
case 'X': str = (ansi_mode? on_string:off_string); break;
|
||
case 'Y': str = (pause_mode? on_string:off_string); break;
|
||
case 'Z': str = (cls_mode? on_string:off_string); break;
|
||
case '0': str = (fsed_mode? on_string:off_string); break;
|
||
case '1': str = user.alias; break;
|
||
case '2': str = (stack_mode? off_string:on_string); break;
|
||
case '3': str = (no_ibm? off_string:on_string); break;
|
||
case '4': str = user.state; break;
|
||
case '5': str = user.birthDate.format("D MMM CCYY"); break;
|
||
case '6': str = user.expDate.format("D MMM CCYY"); break;
|
||
case '7': str = form("%d",int(user.expDate - Date(TODAY))); break;
|
||
case '8': str = (avatar? on_string:off_string); break;
|
||
case '9': str = (avtplus? on_string:off_string); break;
|
||
case '>': str = user.forwardTo; break;
|
||
case '<': str = date_formats_long[user.dateFormat]; break;
|
||
case '[': str = form("%ld",long(download_limit)-user.kbToday); break;
|
||
case '!': if(timer.online()<download_delay) str = form("%d",download_delay-timer.online());
|
||
else str = "0";
|
||
break;
|
||
case '$': str = user.address1; break;
|
||
case '\'': str = user.address2; break;
|
||
case '&': str = user.address3; break;
|
||
case '`': switch(user.sex)
|
||
{
|
||
case 1: str = S_MALE; break;
|
||
case 2: str = S_FEMALE; break;
|
||
default: str = S_UNKNOWN; break;
|
||
}
|
||
break;
|
||
|
||
case '~': str = form("%d",download_delay); break;
|
||
case ':': str = user.firstDate.format("D MMM CCYY"); break;
|
||
case '\"': str = user.country; break;
|
||
case '*': str = form("%d",user.fileGroup); break;
|
||
case '+': str = form("%d",user.msgGroup); break;
|
||
case '(': {
|
||
AreaGroup group;
|
||
File f(FileName(syspath,"FGROUPS.PB"));
|
||
f.seek(long(user.fileGroup-1) * sizeof(AreaGroup));
|
||
if(f.read(&group,sizeof(AreaGroup)) != sizeof(AreaGroup))
|
||
str = "";
|
||
else
|
||
str = group.name;
|
||
}
|
||
break;
|
||
case ')': {
|
||
AreaGroup group;
|
||
File f(FileName(syspath,"MGROUPS.PB"));
|
||
f.seek(long(user.msgGroup-1) * sizeof(AreaGroup));
|
||
if(f.read(&group,sizeof(AreaGroup)) != sizeof(AreaGroup))
|
||
str = "";
|
||
else
|
||
str = group.name;
|
||
}
|
||
break;
|
||
case '=' : str = user.faxPhone; break;
|
||
case '\\': str = user.language; break;
|
||
case '^' : break;
|
||
|
||
|
||
//------------
|
||
// New in v2.2
|
||
//------------
|
||
|
||
case ';':
|
||
|
||
if ( cfg.hidePassword )
|
||
{
|
||
str = String( cfg.pwdchar, strlen( user.passWord ) );
|
||
}
|
||
else
|
||
{
|
||
str = user.passWord;
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
(*this) << align_string(str, fieldwidth , alignment);
|
||
|
||
fflag=0;
|
||
continue;
|
||
}
|
||
|
||
if(kflag)
|
||
{
|
||
Date dd(TODAY);
|
||
Time tt(NOW);
|
||
|
||
str.clear();
|
||
|
||
switch(input)
|
||
{
|
||
case 'A': str = form("%ld",totalcalls); break;
|
||
case 'B': str = lastcaller.name; break;
|
||
case 'C': str = form("%ld",msgbase.totalMsgs()); break;
|
||
case 'D': str = form("%d",0/*minfo.low*/); break;
|
||
case 'E': str = form("%d",0/*minfo.high*/); break;
|
||
case 'F': str = form("%d",num_yells); break;
|
||
case 'G': str = days_full[dd.weekDay()]; break;
|
||
case 'H': str = form("%d",num_users); break;
|
||
case 'I': str = tt.format("HH:MM"); break;
|
||
case 'J': str = dd.format("DD MMM CCYY");break;
|
||
case 'K': str = form("%d",timer.online()); break;
|
||
case 'L': str = "0"; break;
|
||
case 'M': str = form("%ld",user.timeUsed); break;
|
||
case 'N': str = "0"; break;
|
||
case 'O': str = form("%d",timer.left()); break;
|
||
case 'P': str = VERSION; break;
|
||
case 'Q': str = form("%d",time_limit); break;
|
||
case 'R': str = form("%ld",io.baud); break;
|
||
case 'S': str = days_short[dd.weekDay()]; break;
|
||
case 'T': str = form("%d",download_limit); break;
|
||
case 'U': str = form("%d",nextevent.minutesleft()); break;
|
||
case 'V': str = form("%02d:%02d",nextevent.start[0],nextevent.start[1]); break;
|
||
case 'W': str = form("%d",node_number); break;
|
||
case 'X': LOG("Hangup from text file");
|
||
io.flush();
|
||
sleep(2);
|
||
exit_proboard();
|
||
case 'Y': {
|
||
MsgArea ma;
|
||
if(ma.read(user.msgArea))
|
||
str = ma.name;
|
||
else
|
||
str = "* None *";
|
||
} break;
|
||
case 'Z': {
|
||
FileArea fa;
|
||
if(fa.read(user.fileArea))
|
||
str = fa.name;
|
||
else
|
||
str = "* None *";
|
||
} break;
|
||
case '0': {
|
||
MsgArea ma;
|
||
ma.read(user.msgArea);
|
||
str = form("%ld",ma.numMsgs());
|
||
}
|
||
break;
|
||
case '1': str = form("%d",user.msgArea); break;
|
||
case '2': str = form("%d",user.fileArea); break;
|
||
}
|
||
|
||
(*this) << align_string(str, fieldwidth , alignment);
|
||
|
||
kflag=0;
|
||
continue;
|
||
}
|
||
fflag=kflag=fieldwidth=0;
|
||
if(input<27)
|
||
{
|
||
switch(input)
|
||
{
|
||
case 1: wait('\r');
|
||
break;
|
||
case 2: stopok = FALSE;
|
||
break;
|
||
case 3: stopok = TRUE ;
|
||
break;
|
||
case 4: moreok = TRUE ;
|
||
break;
|
||
case 5: moreok = FALSE;
|
||
break;
|
||
case 6: fflag = 1;
|
||
fieldwidth = 2;
|
||
break;
|
||
case 10: (*this) << input;
|
||
if(moreok)
|
||
if(linecounter())
|
||
{
|
||
flush();
|
||
return 1;
|
||
}
|
||
break;
|
||
case 11: kflag=1;
|
||
fieldwidth=2;
|
||
break;
|
||
//case 12: cls();
|
||
// break;
|
||
case 17: break; // XON/XOFF
|
||
case 19: break; // XON/XOFF
|
||
case 23: sleep(1);
|
||
break;
|
||
case 24: break;
|
||
case 26: break; // EOF
|
||
default: kflag = fflag = FALSE;
|
||
(*this) << input;
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
(*this) << input;
|
||
}
|
||
|
||
flush();
|
||
|
||
return 0;
|
||
}
|
||
|
||
#pragma warn .def
|
||
|
||
byte
|
||
fossilio::wait()
|
||
{
|
||
SCREEN.placeCursor();
|
||
|
||
timer.check();
|
||
timer.clearinactivity();
|
||
|
||
flush();
|
||
|
||
byte c;
|
||
|
||
if(comstack.pollnext()) return comstack.getnext();
|
||
|
||
redo:
|
||
|
||
c = inputbuffer.getnext();
|
||
|
||
if(c)
|
||
{
|
||
external = 0;
|
||
return c;
|
||
}
|
||
|
||
while(!(c=readkey()))
|
||
{
|
||
static unsigned long ticks = clockticks();
|
||
|
||
if(clockdiff(ticks)>90) // Update info-window every 5 seconds.
|
||
{
|
||
update_display();
|
||
ticks = clockticks();
|
||
}
|
||
|
||
if(inputbuffer.pollnext()) goto redo;
|
||
timer.checkinactivity();
|
||
DV_timeslice();
|
||
}
|
||
|
||
return c;
|
||
}
|
||
|
||
void
|
||
fossilio::wait(char c)
|
||
{
|
||
while(toupper(wait())!=toupper(c)) {}
|
||
}
|
||
|
||
byte
|
||
fossilio::wait(char *s)
|
||
{
|
||
strupr(s);
|
||
|
||
for(;;)
|
||
{
|
||
char k = toupper(wait());
|
||
|
||
if(strchr(s,k)) return k;
|
||
}
|
||
}
|
||
|
||
void
|
||
fossilio::drawfield(int max)
|
||
{
|
||
int i;
|
||
|
||
if(ansi_mode || avatar)
|
||
{
|
||
fullcolor((SCREEN.attrib()) & (0xF) | (cfg.promptColor<<4));
|
||
|
||
if(!avatar)
|
||
{
|
||
for(i=0;i<max;i++) (*this) << ' ';
|
||
(*this) << form("\x1b[%dD",max);
|
||
}
|
||
else
|
||
{
|
||
(*this) << char(25) << ' ' << char(max);
|
||
|
||
if(avtplus)
|
||
{
|
||
(*this) << char(22) << char(25) << char(2)
|
||
<< char(22) << char(5) << char(max);
|
||
}
|
||
else
|
||
for(i=0;i<max;i++) (*this) << '\b';
|
||
}
|
||
}
|
||
}
|
||
|
||
void
|
||
fossilio::read(char *s,int max,byte mode)
|
||
{
|
||
char k;
|
||
int i=0;
|
||
|
||
if(!(mode&READMODE_NOFIELD))
|
||
drawfield(max);
|
||
|
||
|
||
i=0;
|
||
while((k=wait())!=13)
|
||
{
|
||
if(k==27 || k==10 || k==9) continue;
|
||
if(k==8)
|
||
{
|
||
if(i>0)
|
||
{
|
||
i--;
|
||
(*this) << "\b \b";
|
||
}
|
||
}
|
||
else if(i<max && (isprint(k) || (k & 0x80)))
|
||
{
|
||
switch(mode & 7)
|
||
{
|
||
case READMODE_ALL : break;
|
||
case READMODE_DIGITS : if(!isdigit(k)) continue;
|
||
break;
|
||
case READMODE_UPFIRST: if(s[i-1]=='.' || s[i-1]==' ' || s[i-1]=='-' || i==0)
|
||
k=toupper(k);
|
||
else k=tolower(k);
|
||
break;
|
||
case READMODE_UPALL : k=toupper(k);
|
||
}
|
||
s[i++]=k;
|
||
if(mode & READMODE_PWD) (*this) << cfg.pwdchar;
|
||
else (*this) << k;
|
||
}
|
||
}
|
||
|
||
io << '\r';
|
||
s[i]='\0';
|
||
|
||
if(avatar)
|
||
(*this) << char(22) << char(1) << char(SCREEN.attrib()&0x0F);
|
||
else
|
||
if(ansi_mode) (*this) << "\x1b[40m";
|
||
|
||
flush();
|
||
}
|
||
|
||
int
|
||
fossilio::read(int& i,int len)
|
||
{
|
||
long l;
|
||
int ret = read(l,(len<5)?len:5);
|
||
|
||
if(ret >= 0) i = int(l);
|
||
|
||
return ret;
|
||
}
|
||
|
||
int
|
||
fossilio::read(long& i,int len)
|
||
{
|
||
char s[10];
|
||
|
||
read(s,(len<10)?len:10,READMODE_DIGITS);
|
||
if(!s[0]) return -1;
|
||
|
||
i = atol(s);
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
void
|
||
fossilio::hangup()
|
||
{
|
||
if(baud) fos_setdtr(port,0);
|
||
}
|
||
|
||
int
|
||
fossilio::ask(int def)
|
||
{
|
||
int ret;
|
||
String keys;
|
||
|
||
if(def)
|
||
{
|
||
io << S_ASK_YES_NO;
|
||
keys = K_ASK_YES_NO;
|
||
}
|
||
else
|
||
{
|
||
io << S_ASK_NO_YES;
|
||
keys = K_ASK_NO_YES;
|
||
}
|
||
|
||
keys << '\r';
|
||
|
||
char k = wait(keys);
|
||
|
||
if(k == keys[0])
|
||
ret = TRUE;
|
||
if(k == keys[1])
|
||
ret = FALSE;
|
||
if(k == keys[2])
|
||
ret = def;
|
||
|
||
if(ret)
|
||
(*this) << S_YES;
|
||
else
|
||
(*this) << S_NO;
|
||
|
||
(*this) << char(0xFF);
|
||
|
||
return ret;
|
||
}
|
||
|
||
void
|
||
fossilio::color(byte c)
|
||
{
|
||
current_color=c;
|
||
|
||
int blink=(int)(c & 0x80);
|
||
c &= 0x7;
|
||
|
||
if(avatar)
|
||
{
|
||
static char colors[] = { 0,4,2,6,1,5,3,7 };
|
||
|
||
(*this) << char(22) << char(1);
|
||
(*this) << char(colors[c]|8);
|
||
if(blink) (*this) << char(22) << char(2);
|
||
return;
|
||
}
|
||
|
||
if(!ansi_mode) return;
|
||
|
||
String s("\x1b[0;1;3");
|
||
|
||
s << (char)(c+'0');
|
||
if(blink) s << ";5";
|
||
s << 'm';
|
||
|
||
for(int i=0;s[i];i++) (*this) << s[i];
|
||
}
|
||
|
||
void
|
||
fossilio::cls()
|
||
{
|
||
(*this) << '\f' << char(0xFF);
|
||
}
|
||
|
||
|
||
void
|
||
fossilio::enablestop()
|
||
{
|
||
stopenabled = 1;
|
||
stopped = 0;
|
||
}
|
||
|
||
void
|
||
fossilio::disablestop()
|
||
{
|
||
stopenabled = stopped = 0;
|
||
}
|
||
|
||
static
|
||
String
|
||
align_string(char *s , int width , int alignment)
|
||
{
|
||
String ret_s;
|
||
int i,j = width-strlen(s);
|
||
|
||
if(strlen(s) >= width) return String(s);
|
||
|
||
switch(alignment)
|
||
{
|
||
case ALIGN_LEFT : for(i=0;i<width && s[i];i++) ret_s << s[i];
|
||
for( ;i<width;i++) ret_s << ' ';
|
||
break;
|
||
case ALIGN_CENTER : j = (width-strlen(s))/2;
|
||
case ALIGN_RIGHT : for(i=0 ; i<j ; i++) ret_s << ' ';
|
||
for( ; i<width && s[i-j] ; i++) ret_s << s[i-j];
|
||
for( ; i<width ; i++) ret_s << ' ';
|
||
}
|
||
|
||
return ret_s;
|
||
}
|