Merge with upstream

pull/2/head
Stelios Bounanos 2008-05-16 01:29:34 +01:00
commit a96e72abcf
19 zmienionych plików z 158 dodań i 45 usunięć

Wyświetl plik

@ -78,6 +78,8 @@ Change Log:
33) Changed DominoEX-FEC secondary char lookup to a std::map type.
34) Corrected two coding errors which produced compile warnings in
dominoex.cxx and mt63base.cxx
35) Bug fixes for the FM Hell modes
36) Changed the way that the video text / id is generated.
2.10.3)
1) Corrected memory leak bug.

Wyświetl plik

@ -9,7 +9,7 @@ dnl major and minor must be integers; patch may
dnl contain other characters or be empty
m4_define(FLDIGI_MAJOR, [2])
m4_define(FLDIGI_MINOR, [11])
m4_define(FLDIGI_PATCH, [AC])
m4_define(FLDIGI_PATCH, [AG])
AC_INIT([fldigi], FLDIGI_MAJOR.FLDIGI_MINOR[FLDIGI_PATCH], [w1hkj AT w1hkj DOT com])

Wyświetl plik

@ -63,6 +63,7 @@ void dex::rx_init()
met2 = 0.0;
counter = 0;
phase[0] = 0.0;
currmag = prev1mag = prev2mag = 0.0;
for (int i = 0; i < DEXMAXFFTS; i++)
phase[i+1] = 0.0;
put_MODEstatus(mode);
@ -141,6 +142,12 @@ dex::dex(trx_mode md)
samplerate = 11025;
break;
case MODE_DSX11:
symlen = 1024;
doublespaced = 1;
samplerate = 11025;
break;
case MODE_DEX22:
symlen = 512;
doublespaced = 0;
@ -157,14 +164,12 @@ dex::dex(trx_mode md)
symlen = 1024;
doublespaced = 1;
samplerate = 8000;
break;
case MODE_DEX16:
default:
symlen = 512;
doublespaced = 0;
samplerate = 8000;
break;
}
@ -321,7 +326,29 @@ void dex::decodesymbol()
c = (int)floor(fdiff + .5) - 2;
if (c < 0) c += DEXNUMMTONES;
decodeEX(c);
// decodeEX(c);
unsigned char symbols[4];
double avg = (currmag + prev1mag + prev2mag) / 3.0;
if (avg == 0.0) avg = 1e-20;
double softmag = currmag / avg;
for (int i = 0; i < 4; i++) {
// hard symbol decode
if (progdefaults.DEX_SOFT == false) {
if ((c & 1) == 1) symbols[3-i] = 255;
else symbols[3-i] = 1;
// soft symbol decode
} else
symbols[3-i] = (unsigned char)clamp(256.0 * (c & 1) * softmag, 1, 255);
c = c / 2;
}
Rxinlv->symbols(symbols);
for (int i = 0; i < 4; i++) decodePairs(symbols[i]);
}
int dex::harddecode()
@ -416,7 +443,8 @@ void dex::eval_s2n()
}
noise /= (paths * DEXNUMMTONES * 2 * (doublespaced?2:1) - 1);
s2n = decayavg( s2n, sig / noise, 8);
if (noise)
s2n = decayavg( s2n, sig / noise, 8);
metric = 3*(20*log10(s2n) - 9.0);
@ -463,12 +491,15 @@ int dex::rx_process(const double *buf, int len)
if (--synccounter <= 0) {
synccounter = symlen;
currsymbol = harddecode();
currmag = pipe[pipeptr].vector[currsymbol].mag();
eval_s2n();
decodesymbol();
synchronize();
update_syncscope();
eval_s2n();
prev2symbol = prev1symbol;
prev1symbol = currsymbol;
prev2mag = prev1mag;
prev1mag = currmag;
}
pipeptr++;
if (pipeptr >= twosym)
@ -497,7 +528,7 @@ int dex::get_secondary_char()
void dex::sendtone(int tone, int duration)
{
double f, phaseincr;
f = tone * tonespacing + get_txfreq_woffset() - bandwidth / 2;
f = (tone + 0.5) * tonespacing + get_txfreq_woffset() - bandwidth / 2;
phaseincr = twopi * f / samplerate;
for (int j = 0; j < duration; j++) {
for (int i = 0; i < symlen; i++) {

Wyświetl plik

@ -916,6 +916,13 @@ static void cb_valDEX_PATHS(Fl_Counter* o, void*) {
progdefaults.changed = true;
}
Fl_Check_Button *valDEX_SOFT=(Fl_Check_Button *)0;
static void cb_valDEX_SOFT(Fl_Check_Button* o, void*) {
progdefaults.DEX_SOFT = o->value();
progdefaults.changed = true;
}
Fl_Group *tabDomEX=(Fl_Group *)0;
Fl_Input *txtSecondary=(Fl_Input *)0;
@ -2096,7 +2103,6 @@ l with your sound hardware.");
{ tabDEX = new Fl_Group(0, 44, 400, 170, "Dex");
tabDEX->color((Fl_Color)51);
tabDEX->selection_color((Fl_Color)51);
tabDEX->hide();
{ txtDEXSecondary = new Fl_Input(20, 75, 360, 44, "Secondary Text");
txtDEXSecondary->type(4);
txtDEXSecondary->callback((Fl_Callback*)cb_txtDEXSecondary);
@ -2127,6 +2133,11 @@ l with your sound hardware.");
valDEX_PATHS->callback((Fl_Callback*)cb_valDEX_PATHS);
o->value(progdefaults.DEX_PATHS);
} // Fl_Counter* valDEX_PATHS
{ Fl_Check_Button* o = valDEX_SOFT = new Fl_Check_Button(110, 177, 70, 15, "Soft decode");
valDEX_SOFT->down_box(FL_DOWN_BOX);
valDEX_SOFT->callback((Fl_Callback*)cb_valDEX_SOFT);
o->value(progdefaults.DEX_SOFT);
} // Fl_Check_Button* valDEX_SOFT
tabDEX->end();
} // Fl_Group* tabDEX
{ tabDomEX = new Fl_Group(0, 50, 400, 170, "Dom");
@ -2173,6 +2184,7 @@ l with your sound hardware.");
{ tabFeld = new Fl_Group(0, 50, 400, 170, "Feld");
tabFeld->color((Fl_Color)51);
tabFeld->selection_color((Fl_Color)51);
tabFeld->hide();
{ Fl_Choice* o = selHellFont = new Fl_Choice(175, 62, 122, 20, "Feld Hell Font:");
selHellFont->down_box(FL_BORDER_BOX);
selHellFont->labelfont(4);

Wyświetl plik

@ -1056,7 +1056,7 @@ progdefaults.changed = true;}
}
Fl_Group tabDEX {
label Dex open
xywh {0 44 400 170} color 51 selection_color 51 hide
xywh {0 44 400 170} color 51 selection_color 51
} {
Fl_Input txtDEXSecondary {
label {Secondary Text}
@ -1087,6 +1087,13 @@ progdefaults.changed = true;}
xywh {20 174 63 21} type Simple minimum 4 maximum 8 step 1 value 5
code0 {o->value(progdefaults.DEX_PATHS);}
}
Fl_Check_Button valDEX_SOFT {
label {Soft decode}
callback {progdefaults.DEX_SOFT = o->value();
progdefaults.changed = true;} selected
xywh {110 177 70 15} down_box DOWN_BOX
code0 {o->value(progdefaults.DEX_SOFT);}
}
}
Fl_Group tabDomEX {
label Dom open
@ -1131,7 +1138,7 @@ progdefaults.changed = true;}
}
Fl_Group tabFeld {
label Feld open
xywh {0 50 400 170} color 51 selection_color 51
xywh {0 50 400 170} color 51 selection_color 51 hide
} {
Fl_Choice selHellFont {
label {Feld Hell Font:}
@ -1144,7 +1151,7 @@ progdefaults.changed = true;} open
} {}
Fl_Value_Slider sldrHellBW {
label {Filter BW}
callback {progdefaults.HELL_BW = sldrHellBW->value();} selected
callback {progdefaults.HELL_BW = sldrHellBW->value();}
xywh {30 190 345 20} type Horizontal color 215 align 5 minimum 10 maximum 2400 step 5 value 400 textsize 14
code0 {o->value(progdefaults.HELL_BW);}
}

Wyświetl plik

@ -207,6 +207,7 @@ Fl_Menu_Item quick_change_dex[] = {
{ mode_info[MODE_DEX5].name, 0, cb_init_mode, (void *)MODE_DEX5 },
{ mode_info[MODE_DEX8].name, 0, cb_init_mode, (void *)MODE_DEX8 },
{ mode_info[MODE_DEX11].name, 0, cb_init_mode, (void *)MODE_DEX11 },
{ mode_info[MODE_DSX11].name, 0, cb_init_mode, (void *)MODE_DSX11 },
{ mode_info[MODE_DEX16].name, 0, cb_init_mode, (void *)MODE_DEX16 },
{ mode_info[MODE_DEX22].name, 0, cb_init_mode, (void *)MODE_DEX22 },
{ 0 }
@ -403,7 +404,7 @@ void init_modem(trx_mode mode)
break;
case MODE_DEX4: case MODE_DEX5: case MODE_DEX8:
case MODE_DEX11: case MODE_DEX16: case MODE_DEX22:
case MODE_DEX11: case MODE_DSX11: case MODE_DEX16: case MODE_DEX22:
startup_modem(*mode_info[mode].modem ? *mode_info[mode].modem :
*mode_info[mode].modem = new dex(mode));
quick_change = quick_change_dex;
@ -1045,6 +1046,7 @@ Fl_Menu_Item menu_[] = {
{ mode_info[MODE_DEX5].name, 0, cb_init_mode, (void *)MODE_DEX5, 0, FL_NORMAL_LABEL, 0, 14, 0},
{ mode_info[MODE_DEX8].name, 0, cb_init_mode, (void *)MODE_DEX8, 0, FL_NORMAL_LABEL, 0, 14, 0},
{ mode_info[MODE_DEX11].name, 0, cb_init_mode, (void *)MODE_DEX11, 0, FL_NORMAL_LABEL, 0, 14, 0},
{ mode_info[MODE_DSX11].name, 0, cb_init_mode, (void *)MODE_DSX11, 0, FL_NORMAL_LABEL, 0, 14, 0},
{ mode_info[MODE_DEX16].name, 0, cb_init_mode, (void *)MODE_DEX16, 0, FL_NORMAL_LABEL, 0, 14, 0},
{ mode_info[MODE_DEX22].name, 0, cb_init_mode, (void *)MODE_DEX22, 0, FL_NORMAL_LABEL, 0, 14, 0},
{0,0,0,0,0,0,0,0,0},
@ -1964,6 +1966,7 @@ void resetDEX() {
md == MODE_DEX5 ||
md == MODE_DEX8 ||
md == MODE_DEX11 ||
md == MODE_DSX11 ||
md == MODE_DEX16 ||
md == MODE_DEX22 ) {
active_modem->restart();

Wyświetl plik

@ -529,7 +529,7 @@ int dominoex::get_secondary_char()
void dominoex::sendtone(int tone, int duration)
{
double f, phaseincr;
f = tone * tonespacing + get_txfreq_woffset() - bandwidth / 2;
f = (tone + 0.5) * tonespacing + get_txfreq_woffset() - bandwidth / 2.0;
phaseincr = twopi * f / samplerate;
for (int j = 0; j < duration; j++) {
for (int i = 0; i < symlen; i++) {

Wyświetl plik

@ -114,7 +114,7 @@ feld::feld(trx_mode m)
feldcolumnrate = 17.5;
break;
case MODE_FSKH105:
feldcolumnrate = 17.5;
feldcolumnrate = 7.5;//17.5;
break;
case MODE_HELL80:
feldcolumnrate = 35;
@ -132,15 +132,19 @@ feld::feld(trx_mode m)
hell_bandwidth = txpixrate;
if (hell_bandwidth != progdefaults.HELL_BW) {
progdefaults.HELL_BW = hell_bandwidth;
set_bandwidth(hell_bandwidth);
}
set_bandwidth(hell_bandwidth);
hilbert = new C_FIR_filter();
hilbert->init_hilbert(37, 1);
filter_bandwidth = hell_bandwidth;
if (filter_bandwidth != progdefaults.HELL_BW)
progdefaults.HELL_BW = filter_bandwidth;
std::cout << hell_bandwidth << ", " << progdefaults.HELL_BW << std::endl;
lp = 1.5 * hell_bandwidth / samplerate;
lp = 1.5 * filter_bandwidth / samplerate;
bpfilt = new fftfilt(0, lp, 1024);
@ -276,11 +280,10 @@ int feld::rx_process(const double *buf, int len)
blackboard = btnBlackboard->value();
FL_UNLOCK_D();
if (progdefaults.HELL_BW != hell_bandwidth) {
if (progdefaults.HELL_BW != filter_bandwidth) {
double lp;
hell_bandwidth = progdefaults.HELL_BW;
set_bandwidth(hell_bandwidth);
lp = 1.5 * hell_bandwidth / 2.0 / samplerate;
filter_bandwidth = progdefaults.HELL_BW;
lp = 1.5 * filter_bandwidth / 2.0 / samplerate;
bpfilt->create_filter(0, lp);
}
@ -387,6 +390,8 @@ void feld::send_symbol(int currsymb, int nextsymb)
Amp = 1.0;
switch (mode) {
case MODE_FSKHELL :
tone = midtone + (reverse ? -1 : 1) * (currsymb ? -1 : 1) * txpixrate / 2.0;
break;
case MODE_FSKH105 :
tone = midtone + (reverse ? -1 : 1) * (currsymb ? -1 : 1) * txpixrate / 2.0;
break;

Wyświetl plik

@ -52,6 +52,7 @@ const struct mode_info_t mode_info[NUM_MODES] = {
{ MODE_DEX5, &dex5_modem, "DEX5", "DEX 5", "DEX5", "DEX" },
{ MODE_DEX8, &dex8_modem, "DEX8", "DEX 8", "DEX8", "DEX" },
{ MODE_DEX11, &dex11_modem, "DEX11", "DEX 11", "DEX11", "DEX" },
{ MODE_DSX11, &dsx11_modem, "DSX11", "DSX 11", "DSX11", "DEX" },
{ MODE_DEX16, &dex16_modem, "DEX16", "DEX 16", "DEX16", "DEX" },
{ MODE_DEX22, &dex22_modem, "DEX22", "DEX 22", "DEX22", "DEX" },

Wyświetl plik

@ -142,6 +142,7 @@ extern Fl_Input *txtDEXSecondary;
extern Fl_Counter *valDEX_BW;
extern Fl_Check_Button *valDEX_FILTER;
extern Fl_Counter *valDEX_PATHS;
extern Fl_Check_Button *valDEX_SOFT;
extern Fl_Group *tabDomEX;
extern Fl_Input *txtSecondary;
extern Fl_Counter *valDominoEX_BW;

Wyświetl plik

@ -79,6 +79,7 @@ struct configuration {
bool DEX_FILTER;
string DEXsecText;
int DEX_PATHS;
bool DEX_SOFT;
// DOMINOEX
double DOMINOEX_BW;
bool DOMINOEX_FILTER;

Wyświetl plik

@ -93,6 +93,10 @@ protected:
int currsymbol;
int prev1symbol;
int prev2symbol;
double currmag;
double prev1mag;
double prev2mag;
double met1;
double met2;

Wyświetl plik

@ -70,6 +70,7 @@ protected:
double txphacc;
double txcounter;
double hell_bandwidth;
double filter_bandwidth;
int depth;
int dxmode;

Wyświetl plik

@ -37,7 +37,7 @@
//=====================================================================
class C_FIR_filter {
#define FIRBufferLen 1024
#define FIRBufferLen 4096
private:
int length;
int decimateratio;

Wyświetl plik

@ -55,6 +55,7 @@ enum {
MODE_DEX5,
MODE_DEX8,
MODE_DEX11,
MODE_DSX11,
MODE_DEX16,
MODE_DEX22,

Wyświetl plik

@ -198,6 +198,7 @@ extern modem *dex4_modem;
extern modem *dex5_modem;
extern modem *dex8_modem;
extern modem *dex11_modem;
extern modem *dsx11_modem;
extern modem *dex16_modem;
extern modem *dex22_modem;
extern modem *dominoex4_modem;

Wyświetl plik

@ -84,6 +84,7 @@ configuration progdefaults = {
true, // bool DEX_FILTER;
"fldigi-dex ", // string DEXsecText;
5, // int DEX_PATHS;
false, // bool DEX_SOFT;
// DOMINOEX
2.0, // double DOMINOEX_BW;
true, // bool DOMINOEX_FILTER
@ -251,7 +252,7 @@ enum TAG { \
CWTRACK, CWRISETIME, CWDASH2DOT,
XQSK, CWPRE, CWPOST, CWID, CWIDWPM,
OLIVIATONES, OLIVIABW, OLIVIASMARGIN, OLIVIASINTEG, OLIVIA8BIT,
DEXBW, DEXFILTER, DEXSECTEXT, DEXPATHS,
DEXBW, DEXFILTER, DEXSECTEXT, DEXPATHS, DEXSOFT,
DOMINOEXBW, DOMINOEXFILTER, DOMINOEXFEC, DOMINOEXPATHS,
FELDFONTNBR, FELDIDLE,
WFPREFILTER, LATENCY,
@ -396,6 +397,7 @@ void configuration::writeDefaultsXML()
writeXMLbool(f, "DEXFILTER", DEX_FILTER);
writeXMLstr(f, "DEXSECTEXT", DEXsecText);
writeXMLint(f, "DEXPATHS", DEX_PATHS);
writeXMLbool(f, "DEXSOFT", DEX_SOFT);
writeXMLdbl(f, "DOMINOEXBW", DOMINOEX_BW);
writeXMLbool(f, "DOMINOEXFILTER", DOMINOEX_FILTER);
@ -701,6 +703,9 @@ bool configuration::readDefaultsXML()
case DEXPATHS :
DEX_PATHS = atoi(xml->getNodeData());
break;
case DEXSOFT :
DEX_SOFT = atoi(xml->getNodeData());
break;
case DOMINOEXBW :
DOMINOEX_BW = atof(xml->getNodeData());
break;
@ -1067,6 +1072,7 @@ bool configuration::readDefaultsXML()
else if (!strcmp("DEXFILTER", nodeName)) tag = DEXFILTER;
else if (!strcmp("DEXSECTEXT", nodeName)) tag = DEXSECTEXT;
else if (!strcmp("DEXPATHS", nodeName)) tag = DEXPATHS;
else if (!strcmp("DEXSOFT", nodeName)) tag = DEXSOFT;
else if (!strcmp("DOMINOEXBW", nodeName)) tag = DOMINOEXBW;
else if (!strcmp("DOMINOEXFILTER", nodeName)) tag = DOMINOEXFILTER;
else if (!strcmp("DOMINOEXFEC", nodeName)) tag = DOMINOEXFEC;
@ -1285,6 +1291,7 @@ int configuration::setDefaults() {
valDEX_BW->value(DEX_BW);
valDEX_FILTER->value(DEX_FILTER);
valDEX_PATHS->value(DEX_PATHS);
valDEX_SOFT->value(DEX_SOFT);
valDominoEX_BW->value(DOMINOEX_BW);
valDominoEX_FILTER->value(DOMINOEX_FILTER);

Wyświetl plik

@ -3,6 +3,8 @@
#include <config.h>
#include "filters.h"
#include "confdialog.h"
#include "modem.h"
#include "configuration.h"
@ -39,6 +41,7 @@ modem *dex4_modem = 0;
modem *dex5_modem = 0;
modem *dex8_modem = 0;
modem *dex11_modem = 0;
modem *dsx11_modem = 0;
modem *dex16_modem = 0;
modem *dex22_modem = 0;
modem *dominoex4_modem = 0;
@ -278,19 +281,21 @@ void modem::videoText()
//=====================================================================
// transmit processing of waterfall video id
//=====================================================================
//#define progdefaults.videowidth 3
#define MAXCHARS 4
#define NUMCOLS 8
#define MAXBITS 7
#define NUMROWS 14
#define CHARSPACE 2
#define TONESPACING 8
#define IDSYMLEN 4096
#define IDSYMLEN 2048
#define RISETIME 20
struct mfntchr { char c; int byte[NUMROWS]; };
struct mfntchr { char c; int byte[14];};//NUMROWS]; };
extern mfntchr idch[];
C_FIR_filter vidfilt;
void modem::wfid_make_pulse()
{
double risetime = (samplerate / 1000) * RISETIME;
@ -303,34 +308,47 @@ void modem::wfid_make_pulse()
void modem::wfid_make_tones()
{
double f;
f = frequency + TONESPACING * ( progdefaults.videowidth * ((NUMCOLS - 1)) / 2.0 + (progdefaults.videowidth - 1) * CHARSPACE);
double f, flo, fhi;
f = TONESPACING * ( progdefaults.videowidth * (NUMCOLS - 1) + (progdefaults.videowidth) * CHARSPACE) / 2.0;
f = 2.0 * floor((frequency + f)/2.0);
fhi = f + 2 * TONESPACING;
flo = f - (progdefaults.videowidth * (NUMCOLS + CHARSPACE) + 2) * TONESPACING;
for (int i = 0; i < NUMCOLS * progdefaults.videowidth; i++) {
wfid_w[i] = f * 2.0 * M_PI / samplerate;
f -= TONESPACING;
if ( (i > 0) && (i % NUMCOLS == 0) )
f -= TONESPACING * CHARSPACE;
}
vidfilt.init_bandpass( 1024, 1, flo/samplerate, fhi/samplerate) ;
}
void modem::wfid_send(long int symbol)
{
int i, j;
int sym;
int msk = 0;
double val;
for (i = 0; i < IDSYMLEN; i++) {
wfid_outbuf[i] = 0.0;
val = 0.0;
sym = symbol;
for (j = 0; j < NUMCOLS * progdefaults.videowidth; j++) {
if ((sym & 1) == 1)
wfid_outbuf[i] += ((msk & 1) == 1 ? -1 : 1 ) * sin(wfid_w[j] * i)* wfid_txpulse[i];
val += sin(wfid_w[j] * i);
sym = sym >> 1;
msk = msk >> 1;
}
// soft limit the signal
wfid_outbuf[i] = 0.707 * (1.0 - exp(fabs(val)/-3.0)) * (val >= 0.0 ? 1 : -1);
}
for (i = 0; i < IDSYMLEN; i++)
wfid_outbuf[i] = wfid_outbuf[i] / (MAXBITS * progdefaults.videowidth);
// band pass filter the hard limited signal
for (i = 0; i < IDSYMLEN; i++) {
val = wfid_outbuf[i];
vidfilt.Irun (val, val);
wfid_outbuf[i] = val * wfid_txpulse[i];
}
ModulateXmtr(wfid_outbuf, IDSYMLEN);
}
@ -342,7 +360,7 @@ void modem::wfid_sendchar(char c)
if (c < ' ' || c > '~') return;
n = c - ' ';
for (int row = 0; row < NUMROWS; row++) {
symbol = (idch[n].byte[NUMROWS - 1 -row]) >> (16 - NUMCOLS);
symbol = (idch[n].byte[NUMROWS - 1 - row]) >> (16 - NUMCOLS);
wfid_send (symbol);
if (stopflag)
return;
@ -352,25 +370,32 @@ void modem::wfid_sendchar(char c)
void modem::wfid_sendchars(string s)
{
long int symbol;
int len = s.length();
int len;
unsigned int n[progdefaults.videowidth];
int c;
while (len++ < progdefaults.videowidth) s.insert(0," ");
while (s[0] == ' ') s.erase(0);
len = s.length();
for (int i = 0; i < progdefaults.videowidth; i++) {
for (int i = 0; i < len; i++) { //progdefaults.videowidth; i++) {
c = s[i];
if (c > '~' || c < ' ') c = ' ';
c -= ' ';
n[i] = c;
}
// send rows from bottom to top so they appear to scroll down the waterfall correctly
for (int row = 0; row < NUMROWS; row++) {
symbol = 0;
for (int i = 0; i < progdefaults.videowidth; i++) {
for (int i = 0; i < len; i++) {//progdefaults.videowidth; i++) {
symbol |= (idch[n[i]].byte[NUMROWS - 1 -row] >> (16 - NUMCOLS));
if (i != (progdefaults.videowidth - 1) )
if (i != (len - 1) )
symbol = symbol << NUMCOLS;
}
if (len < progdefaults.videowidth)
symbol = symbol << NUMCOLS * (progdefaults.videowidth - len) / 2;
wfid_send (symbol);
if (stopflag)
return;
@ -430,7 +455,7 @@ mfntchr idch[] = {
{'.', { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xC000, 0xC000, 0xC000, 0x0000, 0x0000 }, },
{'/', { 0x0000, 0x0800, 0x0800, 0x1800, 0x1000, 0x3000, 0x2000, 0x6000, 0x4000, 0xC000, 0x8000, 0x8000, 0x0000, 0x0000 }, },
{'0', { 0x0000, 0x0000, 0x7800, 0xFC00, 0x8C00, 0x9C00, 0xB400, 0xE400, 0xC400, 0x8400, 0xFC00, 0x7800, 0x0000, 0x0000 }, },
{'1', { 0x0000, 0x0000, 0x2000, 0x6000, 0xE000, 0xA000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x0000, 0x0000 }, },
{'1', { 0x0000, 0x0000, 0x1000, 0x3000, 0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000 }, },
{'2', { 0x0000, 0x0000, 0x7800, 0xFC00, 0x8400, 0x0C00, 0x1800, 0x3000, 0x6000, 0xC000, 0xFC00, 0xFC00, 0x0000, 0x0000 }, },
{'3', { 0x0000, 0x0000, 0xFC00, 0xFC00, 0x0400, 0x0C00, 0x1800, 0x1C00, 0x0400, 0x8400, 0xFC00, 0x7800, 0x0000, 0x0000 }, },
{'4', { 0x0000, 0x0000, 0x3800, 0x7800, 0x4800, 0xC800, 0x8800, 0xFC00, 0xFC00, 0x0800, 0x0800, 0x0800, 0x0000, 0x0000 }, },

Wyświetl plik

@ -187,7 +187,18 @@ void FTextBase::readFile(void)
{
const char *fn = file_select("Append text", "Text\t*.txt");
if (fn) {
#ifdef WIN32
string text;
ifstream tfile(fn);
char ch;
while (tfile) {
tfile.get(ch);
if (ch != '\r') text += ch;
}
tbuf->append(text.c_str());
#else
tbuf->appendfile(fn);
#endif
insert_position(tbuf->length());
show_insert_position();
}