1250 lines
30 KiB
C++
1250 lines
30 KiB
C++
|
|
/*
|
||
|
|
* TIAH -- an advanced HEX-Editor
|
||
|
|
* Copyright (C) 1999 by Joerg Tretter
|
||
|
|
*
|
||
|
|
* This program is free software; you can redistribute it and/or modify
|
||
|
|
* it under the terms of the GNU General Public License as published by
|
||
|
|
* the Free Software Foundation; either version 2 of the License, or
|
||
|
|
* (at your option) any later version.
|
||
|
|
*
|
||
|
|
* This program is distributed in the hope that it will be useful,
|
||
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
|
* GNU General Public License for more details.
|
||
|
|
*
|
||
|
|
* You should have received a copy of the GNU General Public License
|
||
|
|
* along with this program; if not, write to the Free Software
|
||
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||
|
|
*/
|
||
|
|
|
||
|
|
#include <curses.h>
|
||
|
|
#include <stdio.h>
|
||
|
|
#include <stdlib.h>
|
||
|
|
#include <string.h>
|
||
|
|
#include <math.h>
|
||
|
|
#include <ctype.h>
|
||
|
|
|
||
|
|
struct data // one line in Memory
|
||
|
|
{
|
||
|
|
struct data* plast;
|
||
|
|
struct data* pnext;
|
||
|
|
unsigned char vals[16];
|
||
|
|
unsigned long line;
|
||
|
|
char len;
|
||
|
|
};
|
||
|
|
|
||
|
|
struct cpos // Cursor-Position
|
||
|
|
{
|
||
|
|
char x,y;
|
||
|
|
}pos;
|
||
|
|
|
||
|
|
char insovr='O'; // Isert/Override-Mode
|
||
|
|
int mode=1;
|
||
|
|
WINDOW *stdscr,*woffs,*whex, *wascii, *wtop, *wbot;
|
||
|
|
const char *topline= " Offset Hex ASCII ";
|
||
|
|
char xoffs[] = "12345678",*soffs;
|
||
|
|
char xhex[] = " 14 15 16 32 32 34 20 54 61 67 65 73 61 6D 74 0D ",*shex;
|
||
|
|
char xascii[] = "1234567890123456",*sascii;
|
||
|
|
char empty78[]=" ";
|
||
|
|
int result;
|
||
|
|
char *filename;
|
||
|
|
char *ptv="12345678";
|
||
|
|
FILE *fp;
|
||
|
|
int ipoint;
|
||
|
|
data datas, *pdatas, *pfirst, *phelp, *pmax;
|
||
|
|
|
||
|
|
/***************************************************************************
|
||
|
|
* FUNCTION: void initvar() *
|
||
|
|
* GOOD FOR: Initialization of basic-variables *
|
||
|
|
***************************************************************************/
|
||
|
|
void initvar()
|
||
|
|
{
|
||
|
|
pfirst=&datas;
|
||
|
|
(*pfirst).plast=NULL;
|
||
|
|
(*pfirst).pnext=NULL;
|
||
|
|
(*pfirst).line=0;
|
||
|
|
(*pfirst).len=0;
|
||
|
|
soffs=xoffs;
|
||
|
|
shex=xhex;
|
||
|
|
sascii=xascii;
|
||
|
|
}
|
||
|
|
|
||
|
|
/***************************************************************************
|
||
|
|
* FUNCTION: void miniinit() *
|
||
|
|
* GOOD FOR: Initialization of frequent used variables *
|
||
|
|
***************************************************************************/
|
||
|
|
void miniinit()
|
||
|
|
{
|
||
|
|
strncpy(xoffs, " ",9);
|
||
|
|
strncpy(xhex, " ",51);
|
||
|
|
strncpy(xascii, " ",17);
|
||
|
|
}
|
||
|
|
|
||
|
|
/***************************************************************************
|
||
|
|
* FUNCTION: int screeninit() *
|
||
|
|
* GOOD FOR: Initialization of the n-curses-screen *
|
||
|
|
* RESULTS : 1:There was an error / 2:Everything ok. *
|
||
|
|
***************************************************************************/
|
||
|
|
int screeninit()
|
||
|
|
{
|
||
|
|
int retval=0;
|
||
|
|
|
||
|
|
stdscr= initscr();
|
||
|
|
if(start_color()) retval=1;
|
||
|
|
nonl();
|
||
|
|
intrflush(stdscr, FALSE);
|
||
|
|
keypad(stdscr, TRUE);
|
||
|
|
|
||
|
|
// Create Curses-space for the windows
|
||
|
|
//TODO: check whether creation was fine.
|
||
|
|
woffs =newwin(18,10,3 ,0 );
|
||
|
|
whex =newwin(18,52,3 ,10);
|
||
|
|
wascii=newwin(18,18,3 ,62);
|
||
|
|
wtop =newwin(3 ,80,0 ,0 );
|
||
|
|
wbot =newwin(4 ,80,21,0 );
|
||
|
|
|
||
|
|
// enable scrolling
|
||
|
|
scrollok(woffs,1);
|
||
|
|
scrollok(whex,1);
|
||
|
|
scrollok(wascii,1);
|
||
|
|
|
||
|
|
// enable Keyboard-control
|
||
|
|
keypad(stdscr,1);
|
||
|
|
keypad(whex,1);
|
||
|
|
keypad(wascii,1);
|
||
|
|
|
||
|
|
// disable echoing of input
|
||
|
|
noecho();
|
||
|
|
|
||
|
|
// swich cursor to big size
|
||
|
|
// TODO: check why this not works in most cases
|
||
|
|
// if(curs_set(2)==ERR) retval=1 ;
|
||
|
|
|
||
|
|
// creation of curses "Color-Pairs"
|
||
|
|
if(init_pair(1,COLOR_BLUE,COLOR_BLACK)) retval=1;
|
||
|
|
if(init_pair(2,COLOR_CYAN,COLOR_BLACK)) retval=1;
|
||
|
|
if(init_pair(3,COLOR_MAGENTA,COLOR_BLACK)) retval=1;
|
||
|
|
|
||
|
|
// join the windows with the color-pairs
|
||
|
|
wattrset(woffs,COLOR_PAIR(1));
|
||
|
|
wattrset(whex,COLOR_PAIR(1));
|
||
|
|
wattrset(wascii,COLOR_PAIR(1));
|
||
|
|
wattrset(wbot,COLOR_PAIR(1));
|
||
|
|
wattrset(wtop,COLOR_PAIR(1));
|
||
|
|
|
||
|
|
// paint the boxes around the windows (in fact it's inside)
|
||
|
|
box(woffs,0,0);
|
||
|
|
box(whex,0,0);
|
||
|
|
box(wascii,0,0);
|
||
|
|
box(wtop,0,0);
|
||
|
|
box(wbot,0,0);
|
||
|
|
|
||
|
|
// change the color-pairs of the windows again.
|
||
|
|
wattrset(woffs,COLOR_PAIR(2));
|
||
|
|
wattrset(whex,COLOR_PAIR(2));
|
||
|
|
wattrset(wascii,COLOR_PAIR(2));
|
||
|
|
wattrset(wtop,COLOR_PAIR(3));
|
||
|
|
wattrset(wbot,COLOR_PAIR(2));
|
||
|
|
|
||
|
|
return(retval);
|
||
|
|
}
|
||
|
|
|
||
|
|
/***************************************************************************
|
||
|
|
* FUNCTION: char* tonumsysx() *
|
||
|
|
* GOOD FOR: Shift a number to another numbering system *
|
||
|
|
* INPUTS : - int base10 -The number in decimal system *
|
||
|
|
* - int newbase -The new system (16->Hex,2->Bin,...) *
|
||
|
|
* RESULTS : The number in the new system as a pointer of char *
|
||
|
|
***************************************************************************/
|
||
|
|
char* tonumsysx(int base10,int newbase)
|
||
|
|
{
|
||
|
|
int erg;
|
||
|
|
int rest=0;
|
||
|
|
int pos=0;
|
||
|
|
int i;
|
||
|
|
static char swap[9];
|
||
|
|
char c[9];
|
||
|
|
|
||
|
|
strncpy(swap,"********",9);
|
||
|
|
c[pos]='0'+rest;
|
||
|
|
while (base10 > 0)
|
||
|
|
{
|
||
|
|
erg=base10/newbase;
|
||
|
|
rest=base10%newbase;
|
||
|
|
if (rest <= 9)
|
||
|
|
c[pos]='0'+rest;
|
||
|
|
else
|
||
|
|
c[pos]='A'+(rest-10);
|
||
|
|
|
||
|
|
base10=erg;
|
||
|
|
pos++;
|
||
|
|
c[pos]='\0';
|
||
|
|
}
|
||
|
|
while(pos < 8)
|
||
|
|
{
|
||
|
|
c[pos]='0';
|
||
|
|
pos++;
|
||
|
|
}
|
||
|
|
pos--;
|
||
|
|
for (i=0;i<=pos;i++)
|
||
|
|
{
|
||
|
|
swap[i]=c[pos-i];
|
||
|
|
}
|
||
|
|
|
||
|
|
return(swap);
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
/***************************************************************************
|
||
|
|
* FUNCTION: unsigned long xto10(char *c, int oldbase) *
|
||
|
|
* GOOD FOR: Shift a number from a foreign numbering system to decimal *
|
||
|
|
* INPUTS : - char* c -The number in foreign system *
|
||
|
|
* - int oldbase -The old system (16->Hex,2->Bin,...) *
|
||
|
|
* RESULTS : The number in decimal system as a unsigned long *
|
||
|
|
***************************************************************************/
|
||
|
|
unsigned long xto10(char *c, int oldbase)
|
||
|
|
{
|
||
|
|
unsigned long base10=0;
|
||
|
|
int pos=0;
|
||
|
|
int i;
|
||
|
|
for (i=0;c[i];i++, c[i]=toupper(c[i]));
|
||
|
|
while(c[pos++]);
|
||
|
|
pos--;
|
||
|
|
int len=pos-1;
|
||
|
|
while(pos--)
|
||
|
|
{
|
||
|
|
if(isdigit(c[len-pos]))
|
||
|
|
{
|
||
|
|
base10 = base10 + (unsigned long)( (double)(c[len-pos]-'0') * ( pow( (double)oldbase,(double)pos ) ) ) ;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
base10 = base10 + (unsigned long)( ((double)(c[len-pos]-'A')+10) * ( pow( (double)oldbase,(double)pos ) ) );
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return(base10);
|
||
|
|
}
|
||
|
|
|
||
|
|
/***************************************************************************
|
||
|
|
* FUNCTION: int loadcontents() *
|
||
|
|
* GOOD FOR: Loading the contents of a file into the memory *
|
||
|
|
* RESULTS : The status of the loading (not used yet) *
|
||
|
|
***************************************************************************/
|
||
|
|
int loadcontents()
|
||
|
|
{
|
||
|
|
int retval=0;
|
||
|
|
int x;
|
||
|
|
char ch;
|
||
|
|
unsigned long line=0;
|
||
|
|
|
||
|
|
|
||
|
|
pdatas=pfirst;
|
||
|
|
ch=fgetc(fp);
|
||
|
|
// Zero-byte-file.
|
||
|
|
if(feof(fp))
|
||
|
|
{
|
||
|
|
fprintf(stderr,"T.I.A.H - Tiah Is A Hex-editor. - opening 0-Byte file");
|
||
|
|
pfirst=pmax=pdatas=(data*)(malloc(sizeof(datas)));
|
||
|
|
(*pdatas).pnext=NULL;
|
||
|
|
(*pdatas).plast=NULL;
|
||
|
|
(*pdatas).line=0;
|
||
|
|
(*pdatas).len=0;
|
||
|
|
|
||
|
|
}
|
||
|
|
// TODO: how to flush the buffer of stdout???
|
||
|
|
printf("Printing hashmark for every 8 Kbytes.\n");
|
||
|
|
while (!(feof(fp)))
|
||
|
|
{
|
||
|
|
for(x=0;x<16;x++)
|
||
|
|
{
|
||
|
|
((*pdatas).vals[x])=ch;
|
||
|
|
if (feof(fp)) //(*pdatas).vals[x]==EOF)
|
||
|
|
{
|
||
|
|
(*pdatas).vals[x]=0;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
(*pdatas).len=x+1;
|
||
|
|
ch=fgetc(fp);
|
||
|
|
}
|
||
|
|
(*pdatas).line=line++;
|
||
|
|
if(!(feof(fp)))
|
||
|
|
{
|
||
|
|
phelp=pdatas;
|
||
|
|
if (!(line%500)) {printf("%c",'#');}
|
||
|
|
pdatas=((*pdatas).pnext)=(data*)(malloc(sizeof(datas)));
|
||
|
|
// BUG: Check for Memory-Full does not work.
|
||
|
|
if(!pdatas) {abort();}
|
||
|
|
(*pdatas).plast=phelp;
|
||
|
|
(*pdatas).pnext=NULL;
|
||
|
|
}
|
||
|
|
pmax=pdatas;
|
||
|
|
|
||
|
|
}
|
||
|
|
return (retval);
|
||
|
|
}
|
||
|
|
|
||
|
|
/***************************************************************************
|
||
|
|
* FUNCTION: void endscr() *
|
||
|
|
* GOOD FOR: End the scrren session on curses-level *
|
||
|
|
***************************************************************************/
|
||
|
|
void endscr()
|
||
|
|
{
|
||
|
|
delwin(woffs);
|
||
|
|
delwin(whex);
|
||
|
|
delwin(wascii);
|
||
|
|
delwin(wtop);
|
||
|
|
delwin(wbot);
|
||
|
|
endwin();
|
||
|
|
}
|
||
|
|
|
||
|
|
/***************************************************************************
|
||
|
|
* FUNCTION: void unallocmem(int save, char* filename) *
|
||
|
|
* GOOD FOR: Free the memory from the bits & bytes *
|
||
|
|
* INPUTS : int save: flag (save Y/else key) *
|
||
|
|
* : cahr* filename: the name of the save-file *
|
||
|
|
***************************************************************************/
|
||
|
|
void unallocmem(int save, char *filename)
|
||
|
|
{
|
||
|
|
int pos;
|
||
|
|
save=toupper(save);
|
||
|
|
if (save=='Y')
|
||
|
|
{
|
||
|
|
pdatas=pfirst;
|
||
|
|
fp=fopen(filename,"w");
|
||
|
|
while((*pdatas).pnext)
|
||
|
|
{
|
||
|
|
for (pos=0;pos <(*pdatas).len;pos++)
|
||
|
|
{
|
||
|
|
fputc((*pdatas).vals[pos],fp);
|
||
|
|
}
|
||
|
|
pdatas=(*pdatas).pnext;
|
||
|
|
}
|
||
|
|
for (pos=0;pos <(*pdatas).len;pos++) fputc((*pdatas).vals[pos],fp);
|
||
|
|
fclose(fp);
|
||
|
|
}
|
||
|
|
{
|
||
|
|
pdatas=pmax;
|
||
|
|
}
|
||
|
|
while((*pdatas).plast)
|
||
|
|
{
|
||
|
|
phelp=(*pdatas).plast;
|
||
|
|
free(pdatas);
|
||
|
|
pdatas=phelp;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/***************************************************************************
|
||
|
|
* FUNCTION: void scrrefresh() *
|
||
|
|
* GOOD FOR: Refreah the basic-screen-elements (not the contents) *
|
||
|
|
***************************************************************************/
|
||
|
|
void scrrefresh()
|
||
|
|
{
|
||
|
|
wattrset(woffs,COLOR_PAIR(1));
|
||
|
|
wattrset(whex,COLOR_PAIR(1));
|
||
|
|
wattrset(wascii,COLOR_PAIR(1));
|
||
|
|
wattrset(wbot,COLOR_PAIR(1));
|
||
|
|
wattrset(wtop,COLOR_PAIR(1));
|
||
|
|
|
||
|
|
box(woffs,0,0);
|
||
|
|
box(whex,0,0);
|
||
|
|
box(wascii,0,0);
|
||
|
|
box(wtop,0,0);
|
||
|
|
box(wbot,0,0);
|
||
|
|
|
||
|
|
wattrset(woffs,COLOR_PAIR(2));
|
||
|
|
wattrset(whex,COLOR_PAIR(2));
|
||
|
|
wattrset(wascii,COLOR_PAIR(2));
|
||
|
|
wattrset(wtop,COLOR_PAIR(3));
|
||
|
|
wattrset(wbot,COLOR_PAIR(2));
|
||
|
|
|
||
|
|
// depending on the mode (ascii/hex) set the cursor-position
|
||
|
|
!mode?wmove(whex,pos.y,pos.x):wmove(wascii,pos.y,pos.x);
|
||
|
|
|
||
|
|
wrefresh(woffs);
|
||
|
|
wrefresh(wtop);
|
||
|
|
wrefresh(wbot);
|
||
|
|
// the order is given by the mode (ascii/hex). the last window refreshed
|
||
|
|
// it the one, in which the cursor appears and the input-focus is.
|
||
|
|
!mode?wrefresh(wascii):wrefresh(whex);
|
||
|
|
mode?wrefresh(wascii):wrefresh(whex);
|
||
|
|
}
|
||
|
|
|
||
|
|
/***************************************************************************
|
||
|
|
* FUNCTION: void emplineout(unsigned long line) *
|
||
|
|
* GOOD FOR: Writing one empty line to the scrren *
|
||
|
|
***************************************************************************/
|
||
|
|
void emplineout(unsigned long line)
|
||
|
|
{
|
||
|
|
mvwaddstr(woffs,line,1," ");
|
||
|
|
mvwaddstr(whex,line,1," ");
|
||
|
|
mvwaddstr(wascii,line,1," ");
|
||
|
|
}
|
||
|
|
|
||
|
|
/***************************************************************************
|
||
|
|
* FUNCTION: void lineout(unsigned long line) *
|
||
|
|
* GOOD FOR: Writing one line (the actual one) from the memory to screen *
|
||
|
|
***************************************************************************/
|
||
|
|
void lineout(unsigned long line)
|
||
|
|
{
|
||
|
|
int z;
|
||
|
|
|
||
|
|
miniinit();
|
||
|
|
|
||
|
|
ptv = tonumsysx((*pdatas).line*16,16);
|
||
|
|
for(z=0;z<9;z++)
|
||
|
|
{
|
||
|
|
xoffs[z] = *(ptv+z);
|
||
|
|
}
|
||
|
|
mvwaddstr(woffs,line,1,soffs);
|
||
|
|
for (z=0;z<(*pdatas).len;z++)
|
||
|
|
{
|
||
|
|
ptv = tonumsysx((*pdatas).vals[z],16);
|
||
|
|
xhex[z*3+1] = *(ptv+6);
|
||
|
|
xhex[z*3+2] = *(ptv+7);
|
||
|
|
}
|
||
|
|
mvwaddstr(whex,line,1,shex);
|
||
|
|
for (z=0;z<(*pdatas).len;z++)
|
||
|
|
{
|
||
|
|
// TODO: There are many other characters that are displayable.
|
||
|
|
xascii[z] = (isgraph((*pdatas).vals[z]))?((*pdatas).vals[z]):'.';
|
||
|
|
}
|
||
|
|
mvwaddstr(wascii,line,1,sascii);
|
||
|
|
}
|
||
|
|
|
||
|
|
/***************************************************************************
|
||
|
|
* FUNCTION: void initout() *
|
||
|
|
* GOOD FOR: First output after loading the file // home-Key *
|
||
|
|
***************************************************************************/
|
||
|
|
void initout()
|
||
|
|
{
|
||
|
|
//Initial output (All)
|
||
|
|
int i,z;
|
||
|
|
bool toggleswitch=false;
|
||
|
|
pdatas=pfirst;
|
||
|
|
|
||
|
|
if ((*pdatas).pnext == NULL) toggleswitch=true;
|
||
|
|
for(i=0;i<16;i++)
|
||
|
|
{
|
||
|
|
lineout(i+1);
|
||
|
|
if (toggleswitch) break;
|
||
|
|
pdatas=(*pdatas).pnext;
|
||
|
|
if ((*pdatas).pnext == NULL) toggleswitch=true;
|
||
|
|
}
|
||
|
|
scrrefresh();
|
||
|
|
|
||
|
|
if(i>15) pdatas=(*pdatas).plast;
|
||
|
|
}
|
||
|
|
|
||
|
|
/***************************************************************************
|
||
|
|
* FUNCTION: int scrolld() *
|
||
|
|
* GOOD FOR: Scrolling the scrren one line down *
|
||
|
|
* RESULTS : 1: no more elements // 0: everything was nice *
|
||
|
|
***************************************************************************/
|
||
|
|
int scrolld()
|
||
|
|
{
|
||
|
|
int resval;
|
||
|
|
if ((*pdatas).pnext != NULL)
|
||
|
|
{
|
||
|
|
pdatas=(*pdatas).pnext;
|
||
|
|
wscrl(woffs,1);
|
||
|
|
wscrl(whex,1);
|
||
|
|
wscrl(wascii,1);
|
||
|
|
|
||
|
|
miniinit();
|
||
|
|
|
||
|
|
lineout(16);
|
||
|
|
resval=1;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
resval=0;
|
||
|
|
}
|
||
|
|
return(resval);
|
||
|
|
}
|
||
|
|
|
||
|
|
/***************************************************************************
|
||
|
|
* FUNCTION: int scrollu() *
|
||
|
|
* GOOD FOR: Scrolling the scrren one line up *
|
||
|
|
* RESULTS : 1: at first element // 0: everything was nice *
|
||
|
|
***************************************************************************/
|
||
|
|
int scrollu()
|
||
|
|
{
|
||
|
|
int z=0;
|
||
|
|
int result;
|
||
|
|
while(((*pdatas).plast != NULL)&&(z < 16))
|
||
|
|
{
|
||
|
|
pdatas=(*pdatas).plast;
|
||
|
|
z++;
|
||
|
|
}
|
||
|
|
result= (z!=15)?1:0;
|
||
|
|
if(z>15)
|
||
|
|
{
|
||
|
|
z--;
|
||
|
|
wscrl(woffs,-1);
|
||
|
|
wscrl(whex,-1);
|
||
|
|
wscrl(wascii,-1);
|
||
|
|
|
||
|
|
miniinit();
|
||
|
|
|
||
|
|
lineout(1);
|
||
|
|
}
|
||
|
|
while(z--)
|
||
|
|
{
|
||
|
|
if ((*pdatas).pnext != NULL)
|
||
|
|
{
|
||
|
|
pdatas=(*pdatas).pnext;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return(result);
|
||
|
|
}
|
||
|
|
|
||
|
|
/***************************************************************************
|
||
|
|
* FUNCTION: void switchmode() *
|
||
|
|
* GOOD FOR: recalculation of cursor-position ascii<->hex *
|
||
|
|
***************************************************************************/
|
||
|
|
void switchmode()
|
||
|
|
{
|
||
|
|
if(mode==0)
|
||
|
|
{
|
||
|
|
mode=1; // mode-toggle:Hex->Ascii
|
||
|
|
// recalculate cursor-position
|
||
|
|
pos.x=((pos.x+1)/3);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
mode=0; // mode-toggle:ascii->Hex
|
||
|
|
// recalculate cursor-position
|
||
|
|
pos.x=((pos.x*3)-1);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/***************************************************************************
|
||
|
|
* FUNCTION: void moveleft() *
|
||
|
|
* GOOD FOR: move the cursor one position to the left *
|
||
|
|
***************************************************************************/
|
||
|
|
void moveleft()
|
||
|
|
{
|
||
|
|
if(mode==0)
|
||
|
|
{
|
||
|
|
if(pos.x > 2)
|
||
|
|
{
|
||
|
|
(pos.x%3)?pos.x-=2:pos.x--;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if(pos.y >1)
|
||
|
|
{
|
||
|
|
pos.y--;
|
||
|
|
pos.x=48;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if(scrollu())pos.x=48;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if(pos.x > 1)
|
||
|
|
{
|
||
|
|
pos.x--;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if(pos.y >1)
|
||
|
|
{
|
||
|
|
pos.y--;
|
||
|
|
pos.x=16;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if(scrollu())pos.x=16;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/***************************************************************************
|
||
|
|
* FUNCTION: void moveright() *
|
||
|
|
* GOOD FOR: move the cursor one position to the right *
|
||
|
|
***************************************************************************/
|
||
|
|
void moveright()
|
||
|
|
{
|
||
|
|
if(mode==0)
|
||
|
|
{
|
||
|
|
if(pos.x < 48)
|
||
|
|
{
|
||
|
|
(pos.x%3)?pos.x++:pos.x+=2;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if(pos.y < 16)
|
||
|
|
{
|
||
|
|
pos.x=2;
|
||
|
|
pos.y++;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if(scrolld()) pos.x=2;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if((pos.x < 16))
|
||
|
|
{
|
||
|
|
pos.x++;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if(pos.y < 16)
|
||
|
|
{
|
||
|
|
pos.x=1;
|
||
|
|
pos.y++;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if(scrolld()) pos.x=1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/***************************************************************************
|
||
|
|
* FUNCTION: unsigned long getactpos() *
|
||
|
|
* GOOD FOR: get the acutal cursor-position as a file-offset *
|
||
|
|
* RESULTS : The file-offset on the cursor-position as unsigned long *
|
||
|
|
***************************************************************************/
|
||
|
|
unsigned long getactpos()
|
||
|
|
{
|
||
|
|
int i=0;
|
||
|
|
unsigned long actpos;
|
||
|
|
int distance;
|
||
|
|
int posxsave=9999;
|
||
|
|
if (!mode)
|
||
|
|
{
|
||
|
|
posxsave=pos.x;
|
||
|
|
switchmode();
|
||
|
|
}
|
||
|
|
// move in Memory to the cursor-position
|
||
|
|
if((pdatas==pmax) && ((*pdatas).line<15))
|
||
|
|
{
|
||
|
|
distance=(*pdatas).line-pos.y+1;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
distance=16-pos.y;
|
||
|
|
}
|
||
|
|
while(i<(distance)&&((*pdatas).plast))
|
||
|
|
{
|
||
|
|
i++;
|
||
|
|
pdatas=(*pdatas).plast;
|
||
|
|
}
|
||
|
|
// get the position
|
||
|
|
actpos=((*pdatas).line*16)+pos.x-1;
|
||
|
|
// and move back
|
||
|
|
while(i--)
|
||
|
|
{
|
||
|
|
pdatas=(*pdatas).pnext;
|
||
|
|
}
|
||
|
|
if (posxsave!=9999)
|
||
|
|
{
|
||
|
|
switchmode();
|
||
|
|
pos.x=posxsave;
|
||
|
|
}
|
||
|
|
|
||
|
|
return(actpos);
|
||
|
|
}
|
||
|
|
|
||
|
|
/***************************************************************************
|
||
|
|
* FUNCTION: void charin(char ch, int realmode, int realxpos) *
|
||
|
|
* GOOD FOR: insert/override one character in the memory *
|
||
|
|
* INPUTS : - char ch -the char to insert *
|
||
|
|
* - int realmode -the real mode (hex/ascii) *
|
||
|
|
* - int realxpos -the real x-position of the cursor *
|
||
|
|
***************************************************************************/
|
||
|
|
void charin(char ch, int realmode, int realxpos)
|
||
|
|
{
|
||
|
|
int i=0;
|
||
|
|
int z=0;
|
||
|
|
int distance=0;
|
||
|
|
bool toggleswitch;
|
||
|
|
data *phelp2;
|
||
|
|
char rbmode; //rollbackmode (if file < 255 chars = 1 else 2)
|
||
|
|
unsigned long zhelp;
|
||
|
|
// move to the cursor-position in memory
|
||
|
|
// Is the file smaller then one page, it has to be handled in another way.
|
||
|
|
if((pdatas==pmax) && ((*pdatas).line<15))
|
||
|
|
{
|
||
|
|
distance=(*pdatas).line-pos.y+1;
|
||
|
|
rbmode=1;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
distance=16-pos.y;
|
||
|
|
rbmode=2;
|
||
|
|
}
|
||
|
|
while(i<(distance)&&((*pdatas).plast))
|
||
|
|
{
|
||
|
|
i++;
|
||
|
|
pdatas=(*pdatas).plast;
|
||
|
|
}
|
||
|
|
// For the insert-mode
|
||
|
|
if (((insovr=='I') && (realmode==1))||((insovr=='I') && (realmode==0) && (realxpos%3==2)) && (realmode!=3))
|
||
|
|
{
|
||
|
|
phelp=pdatas;
|
||
|
|
pdatas=pmax;
|
||
|
|
if ((*pdatas).len < 16)
|
||
|
|
{
|
||
|
|
(*pdatas).len++;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
// allocate new element
|
||
|
|
phelp2=pmax;
|
||
|
|
zhelp=(*pmax).line+1;
|
||
|
|
pdatas=pmax=((*pdatas).pnext)=(data*)(malloc(sizeof(datas)));
|
||
|
|
if(!pmax) {abort();}
|
||
|
|
(*pmax).plast=phelp2;
|
||
|
|
(*pmax).pnext=NULL;
|
||
|
|
(*pmax).len=1;
|
||
|
|
(*pmax).line=zhelp;
|
||
|
|
if (rbmode == 1) phelp=pmax;
|
||
|
|
}
|
||
|
|
while(pdatas!=phelp)
|
||
|
|
{
|
||
|
|
for(z=(*pdatas).len-1;z>=0;z--)
|
||
|
|
{
|
||
|
|
(*pdatas).vals[z]=(*pdatas).vals[z-1];
|
||
|
|
}
|
||
|
|
(*pdatas).vals[0]=(*(*pdatas).plast).vals[15];
|
||
|
|
pdatas=(*pdatas).plast;
|
||
|
|
}
|
||
|
|
|
||
|
|
for(z=(*pdatas).len-1;z+1>pos.x;z--)
|
||
|
|
{
|
||
|
|
(*pdatas).vals[z]=(*pdatas).vals[z-1];
|
||
|
|
}
|
||
|
|
pdatas=phelp;
|
||
|
|
}
|
||
|
|
// Write value
|
||
|
|
(*pdatas).vals[pos.x-1]=ch;
|
||
|
|
// refresh output of current line (not needed, I think)
|
||
|
|
lineout(pos.y);
|
||
|
|
// moving backwards again and print the lines immediate.
|
||
|
|
if (rbmode==1)
|
||
|
|
{
|
||
|
|
initout();
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
while(i--)
|
||
|
|
{
|
||
|
|
if((*pdatas).pnext)
|
||
|
|
{
|
||
|
|
pdatas=(*pdatas).pnext;
|
||
|
|
lineout(16-i);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/***************************************************************************
|
||
|
|
* FUNCTION: int charout() *
|
||
|
|
* GOOD FOR: get the char at the actual cursor-position *
|
||
|
|
* RESULTS : the char as an integer (char should work too normaly) *
|
||
|
|
***************************************************************************/
|
||
|
|
int charout()
|
||
|
|
{
|
||
|
|
int i=0;
|
||
|
|
int distance;
|
||
|
|
int posxsave;
|
||
|
|
int ch;
|
||
|
|
// Move in memory to cursor-position
|
||
|
|
if (!mode)
|
||
|
|
{
|
||
|
|
posxsave=pos.x;
|
||
|
|
switchmode();
|
||
|
|
}
|
||
|
|
// move in Memory to the cursor-position
|
||
|
|
if((pdatas==pmax) && ((*pdatas).line<15))
|
||
|
|
{
|
||
|
|
distance=(*pdatas).line-pos.y+1;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
distance=16-pos.y;
|
||
|
|
}
|
||
|
|
while(i<(distance)&&((*pdatas).plast))
|
||
|
|
{
|
||
|
|
i++;
|
||
|
|
pdatas=(*pdatas).plast;
|
||
|
|
}
|
||
|
|
// get the value
|
||
|
|
ch=((*pdatas).vals[pos.x-1]);
|
||
|
|
// move back
|
||
|
|
while(i--)
|
||
|
|
{
|
||
|
|
pdatas=(*pdatas).pnext;
|
||
|
|
}
|
||
|
|
return(ch);
|
||
|
|
}
|
||
|
|
|
||
|
|
/***************************************************************************
|
||
|
|
* FUNCTION: void bottomout() *
|
||
|
|
* GOOD FOR: refreshing the output of the bottom-window *
|
||
|
|
***************************************************************************/
|
||
|
|
void bottomout()
|
||
|
|
{
|
||
|
|
int realmode,realposx;
|
||
|
|
realmode=mode;
|
||
|
|
|
||
|
|
if (realmode == 0)
|
||
|
|
{
|
||
|
|
realposx=pos.x;
|
||
|
|
switchmode();
|
||
|
|
}
|
||
|
|
mvwaddstr(wbot,1,1,empty78);
|
||
|
|
mvwaddstr(wbot,2,1,empty78);
|
||
|
|
wattrset(wbot,COLOR_PAIR(3));
|
||
|
|
mvwaddstr(wbot,1,1,"CHR:");
|
||
|
|
wattrset(wbot,COLOR_PAIR(2));
|
||
|
|
mvwaddch(wbot,1,6,32);
|
||
|
|
mvwaddch(wbot,1,5,(isgraph(charout()))?charout():'.');
|
||
|
|
|
||
|
|
wattrset(wbot,COLOR_PAIR(3));
|
||
|
|
mvwaddstr(wbot,1,9,"HEX:");
|
||
|
|
wattrset(wbot,COLOR_PAIR(2));
|
||
|
|
mvwaddstr(wbot,1,13,(tonumsysx(charout(),16))+6);
|
||
|
|
mvwaddch(wbot,1,15,'h');
|
||
|
|
|
||
|
|
wattrset(wbot,COLOR_PAIR(3));
|
||
|
|
mvwaddstr(wbot,1,18,"DEC:");
|
||
|
|
wattrset(wbot,COLOR_PAIR(2));
|
||
|
|
mvwaddstr(wbot,1,22,(tonumsysx(charout(),10))+5);
|
||
|
|
|
||
|
|
wattrset(wbot,COLOR_PAIR(3));
|
||
|
|
mvwaddstr(wbot,1,27,"OCT:");
|
||
|
|
wattrset(wbot,COLOR_PAIR(2));
|
||
|
|
mvwaddstr(wbot,1,31,(tonumsysx(charout(),8))+4);
|
||
|
|
|
||
|
|
wattrset(wbot,COLOR_PAIR(3));
|
||
|
|
mvwaddstr(wbot,1,37,"BIN:");
|
||
|
|
wattrset(wbot,COLOR_PAIR(2));
|
||
|
|
mvwaddstr(wbot,1,41,tonumsysx(charout(),2));
|
||
|
|
|
||
|
|
wattrset(wbot,COLOR_PAIR(3));
|
||
|
|
mvwaddstr(wbot,1,52,"Offset:");
|
||
|
|
wattrset(wbot,COLOR_PAIR(2));
|
||
|
|
mvwaddstr(wbot,1,59,tonumsysx(getactpos(),16));
|
||
|
|
wattrset(wbot,COLOR_PAIR(3));
|
||
|
|
mvwaddstr(wbot,1,67,"h -");
|
||
|
|
wattrset(wbot,COLOR_PAIR(2));
|
||
|
|
mvwaddstr(wbot,1,71,tonumsysx(getactpos(),10));
|
||
|
|
|
||
|
|
mvwaddstr(wbot,2,1,filename);
|
||
|
|
mvwaddstr(wbot,2,76,(insovr=='O')?"OVR":"INS");
|
||
|
|
if (realmode == 0)
|
||
|
|
{
|
||
|
|
switchmode();
|
||
|
|
pos.x=realposx;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/***************************************************************************
|
||
|
|
* FUNCTION: void swapbits() *
|
||
|
|
* GOOD FOR: toggle the bit [par1] an the actual position *
|
||
|
|
* INPUTS : - char bit the number (1-8) of the bit to toggle *
|
||
|
|
***************************************************************************/
|
||
|
|
void swapbits(char bit)
|
||
|
|
{
|
||
|
|
char bin[]="12345678",*pbin; // for the Bits
|
||
|
|
pbin=bin;
|
||
|
|
int realposx, realmode;
|
||
|
|
realmode=mode;
|
||
|
|
if (realmode==0)
|
||
|
|
{
|
||
|
|
realposx=pos.x;
|
||
|
|
switchmode();
|
||
|
|
}
|
||
|
|
pbin=tonumsysx(charout(),2);
|
||
|
|
pbin[bit]= (pbin[bit]=='0')?'1':'0';
|
||
|
|
charin(xto10(pbin,2),3,pos.x);
|
||
|
|
if (realmode==0)
|
||
|
|
{
|
||
|
|
switchmode();
|
||
|
|
pos.x=realposx;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/***************************************************************************
|
||
|
|
* FUNCTION: void delactchar(char ch, int realmode, int realxpos) *
|
||
|
|
* GOOD FOR: delete the char under the actual cursor-position *
|
||
|
|
* INPUTS : - int realmode -the real mode (hex/ascii) *
|
||
|
|
* - int realxpos -the real x-position of the cursor *
|
||
|
|
***************************************************************************/
|
||
|
|
void delactchar(int realmode, int realxpos)
|
||
|
|
{
|
||
|
|
//BUG: after deletion the last char in the last line it gives me a segfault.
|
||
|
|
int i=0;
|
||
|
|
int z=0;
|
||
|
|
int distance=0;
|
||
|
|
bool endflag=FALSE;
|
||
|
|
bool toggleswitch;
|
||
|
|
char rbmode; //rollbackmode (if file < 255 chars = 1 else 2)
|
||
|
|
|
||
|
|
// move to the cursor-position in memory
|
||
|
|
// Is the file smaller then one page, it has to be handled in another way.
|
||
|
|
if((pdatas==pmax) && ((*pdatas).line<15))
|
||
|
|
{
|
||
|
|
distance=(*pdatas).line-pos.y+1;
|
||
|
|
rbmode=1;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
distance=16-pos.y;
|
||
|
|
rbmode=2;
|
||
|
|
}
|
||
|
|
while(i<(distance)&&((*pdatas).plast))
|
||
|
|
{
|
||
|
|
i++;
|
||
|
|
pdatas=(*pdatas).plast;
|
||
|
|
}
|
||
|
|
// For the insert-mode
|
||
|
|
if (((insovr=='I') && (realmode==1))||((insovr=='I') && (realmode==0) && (realxpos%3==2)) && (realmode!=3))
|
||
|
|
{
|
||
|
|
phelp=pdatas;
|
||
|
|
for(z=realxpos-1;z<15;z++)
|
||
|
|
{
|
||
|
|
(*pdatas).vals[z]=(*pdatas).vals[z+1];
|
||
|
|
}
|
||
|
|
if((*pdatas).pnext)
|
||
|
|
{
|
||
|
|
(*pdatas).vals[15]=(*(*pdatas).pnext).vals[0];
|
||
|
|
pdatas=(*pdatas).pnext;
|
||
|
|
}
|
||
|
|
while(pdatas!=pmax)
|
||
|
|
{
|
||
|
|
for(z=0;z<15;z++)
|
||
|
|
{
|
||
|
|
(*pdatas).vals[z]=(*pdatas).vals[z+1];
|
||
|
|
}
|
||
|
|
(*pdatas).vals[15]=(*(*pdatas).pnext).vals[0];
|
||
|
|
pdatas=(*pdatas).pnext;
|
||
|
|
}
|
||
|
|
// check here for last char in last element
|
||
|
|
(*pdatas).len--;
|
||
|
|
if((*pdatas).len <= 0)
|
||
|
|
{
|
||
|
|
if(phelp==pmax)
|
||
|
|
{
|
||
|
|
if((*phelp).plast)
|
||
|
|
{
|
||
|
|
phelp=(*phelp).plast;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if(pfirst!=pmax) // is when pfirst!=pmax
|
||
|
|
{
|
||
|
|
pdatas=(*pdatas).plast;
|
||
|
|
free((*pdatas).pnext);
|
||
|
|
(*pdatas).pnext=NULL;
|
||
|
|
pmax=pdatas;
|
||
|
|
// TODO: there is one line less now, when we are at the last screen
|
||
|
|
// we should decrease i by one (only cosmetic)
|
||
|
|
endflag=TRUE;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
(*pdatas).len=0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if (phelp!=pmax) for(z=0;z<(*pdatas).len;z++)
|
||
|
|
{
|
||
|
|
(*pdatas).vals[z]=(*pdatas).vals[z+1];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
pdatas=phelp;
|
||
|
|
}
|
||
|
|
// refresh output of current line (not needed, I think)
|
||
|
|
lineout(pos.y);
|
||
|
|
// moving backwards again and print the lines immediate.
|
||
|
|
if (rbmode==1)
|
||
|
|
{
|
||
|
|
// first delete the screen
|
||
|
|
for(z=0;z<16;z++)
|
||
|
|
{
|
||
|
|
emplineout(z+1);
|
||
|
|
}
|
||
|
|
// then do an initial output
|
||
|
|
initout();
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
while(i--)
|
||
|
|
{
|
||
|
|
if((*pdatas).pnext)
|
||
|
|
{
|
||
|
|
pdatas=(*pdatas).pnext;
|
||
|
|
lineout(16-i);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
// The rest is only a dirty workaround for the las (no longer needed) line
|
||
|
|
// because it was not possible for me to determine out, whether i am really
|
||
|
|
// at the end.
|
||
|
|
if (endflag)
|
||
|
|
{
|
||
|
|
for(i=0;i<16;i++)
|
||
|
|
{
|
||
|
|
if(!scrollu()) endflag=FALSE;
|
||
|
|
}
|
||
|
|
if (endflag)
|
||
|
|
{
|
||
|
|
if((pos.y < 16) && ((*pmax).line > 15)) pos.y++;
|
||
|
|
for(i=0;i<16;i++)
|
||
|
|
{
|
||
|
|
scrolld();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
int main(int argc, char *argv[])
|
||
|
|
{
|
||
|
|
//Variables
|
||
|
|
unsigned int i; // Public counter
|
||
|
|
int inpch; // The char of input
|
||
|
|
|
||
|
|
//Preperation
|
||
|
|
printf("T.I.A.H - Tiah Is A Hex-editor. Version 0.5a (C) Joerg Tretter 1999\n");
|
||
|
|
//Is there a param?
|
||
|
|
if(argc < 2)
|
||
|
|
{
|
||
|
|
fprintf(stderr,"T.I.A.H -MESSAGE:\n\nUSAGE: %s <filename> \n",argv[0]);
|
||
|
|
exit(1);
|
||
|
|
}
|
||
|
|
//open the file
|
||
|
|
fp=fopen(argv[1],"r");
|
||
|
|
if (fp == NULL)
|
||
|
|
{
|
||
|
|
fprintf(stderr,"T.I.A.H -MESSAGE:\n\nERROR opening file: %s \n",argv[1]);
|
||
|
|
exit(2);
|
||
|
|
}
|
||
|
|
// set the pointers
|
||
|
|
initvar();
|
||
|
|
// init of other useful varibles
|
||
|
|
pos.x = pos.y = 1;
|
||
|
|
filename=argv[1];
|
||
|
|
//file -> ram
|
||
|
|
if(loadcontents())
|
||
|
|
{
|
||
|
|
fprintf(stderr,"T.I.A.H -MESSAGE:\n\nERROR reading %s (too less RAM?)\n",argv[1]);
|
||
|
|
exit(3);
|
||
|
|
}
|
||
|
|
// init of terminal
|
||
|
|
if(screeninit())
|
||
|
|
{
|
||
|
|
endscr();
|
||
|
|
fprintf(stderr,"T.I.A.H -MESSAGE; !!!Terminal not supported!!! -> Abort \n");
|
||
|
|
exit(5);
|
||
|
|
}
|
||
|
|
mvwaddstr(wtop,1,1,topline);
|
||
|
|
|
||
|
|
|
||
|
|
//Main-procedure
|
||
|
|
initout();
|
||
|
|
bottomout();
|
||
|
|
scrrefresh();
|
||
|
|
|
||
|
|
//Event-loop
|
||
|
|
while(inpch!=KEY_F(10))
|
||
|
|
{
|
||
|
|
if (mode==0)
|
||
|
|
{
|
||
|
|
inpch=wgetch(whex);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
inpch=wgetch(wascii);
|
||
|
|
}
|
||
|
|
switch(inpch)
|
||
|
|
{
|
||
|
|
// The Keys F1-F8 (bit-setting)
|
||
|
|
case KEY_F(9): switchmode();
|
||
|
|
break;
|
||
|
|
|
||
|
|
case KEY_F(1): swapbits(0);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case KEY_F(2): swapbits(1);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case KEY_F(3): swapbits(2);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case KEY_F(4): swapbits(3);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case KEY_F(5): swapbits(4);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case KEY_F(6): swapbits(5);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case KEY_F(7): swapbits(6);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case KEY_F(8): swapbits(7);
|
||
|
|
break;
|
||
|
|
|
||
|
|
//the delete character-key
|
||
|
|
case KEY_DC : if (mode == 1)
|
||
|
|
{
|
||
|
|
delactchar(1,pos.x);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
switchmode();
|
||
|
|
delactchar(1,pos.x);
|
||
|
|
switchmode();
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
//the insert-key, switch insert mode
|
||
|
|
case KEY_EIC: //fallthru
|
||
|
|
case KEY_IC : if (insovr=='O')
|
||
|
|
{
|
||
|
|
insovr='I';
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
insovr='O';
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
//Cursor-movement
|
||
|
|
case KEY_LEFT: moveleft();
|
||
|
|
break;
|
||
|
|
|
||
|
|
case KEY_RIGHT:moveright();
|
||
|
|
break;
|
||
|
|
|
||
|
|
case KEY_DOWN: if(pos.y>15)
|
||
|
|
{
|
||
|
|
scrolld();
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
pos.y++;
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case KEY_UP: if(pos.y<2)
|
||
|
|
{
|
||
|
|
scrollu();
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
pos.y--;
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case KEY_NPAGE:for(i=0;i<16;i++)
|
||
|
|
{
|
||
|
|
scrolld();
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case KEY_PPAGE:for(i=0;i<16;i++)
|
||
|
|
{
|
||
|
|
scrollu();
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case KEY_HOME: initout();
|
||
|
|
break;
|
||
|
|
|
||
|
|
case KEY_END: if((*pmax).line > 15)
|
||
|
|
{
|
||
|
|
pdatas=pmax;
|
||
|
|
for(i=0;((*pdatas).plast) && (i < 16);i++)
|
||
|
|
{
|
||
|
|
pdatas=(*pdatas).plast;
|
||
|
|
}
|
||
|
|
while((*pdatas).pnext)
|
||
|
|
{
|
||
|
|
scrolld();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
// input characters
|
||
|
|
default: if(mode==0)
|
||
|
|
{
|
||
|
|
if(isdigit(inpch) || (toupper(inpch)>='A' && toupper(inpch)<='F') )
|
||
|
|
{
|
||
|
|
waddch(whex,toupper(inpch));
|
||
|
|
char hch[]="00";
|
||
|
|
// fill hch correct (old values)
|
||
|
|
int xpos=pos.x; // save position
|
||
|
|
switchmode(); // recalc. coordinates
|
||
|
|
ptv=tonumsysx(charout(),16); // actual char in Hex.
|
||
|
|
//* --- DEBUG ONLY
|
||
|
|
mvwaddstr(wbot,2,30,tonumsysx(charout(),16));
|
||
|
|
// --- END DEBUG
|
||
|
|
switchmode(); // recalc coordinates
|
||
|
|
pos.x=xpos; // restore coorinates
|
||
|
|
if (insovr=='O') // Predef. only in Override!
|
||
|
|
{
|
||
|
|
hch[0] = *(ptv+6);
|
||
|
|
hch[1] = *(ptv+7);
|
||
|
|
}
|
||
|
|
else // In Insert only first char
|
||
|
|
{
|
||
|
|
if(pos.x%3==0)
|
||
|
|
hch[0] = *(ptv+6);
|
||
|
|
}
|
||
|
|
//* --- DEBUG ONLY
|
||
|
|
mvwaddstr(wbot,2,1,hch);
|
||
|
|
mvwaddstr(wbot,2,20,ptv);
|
||
|
|
// --- END DEBUG
|
||
|
|
hch[(pos.x%3)?0:1]=inpch;
|
||
|
|
switchmode(); // recalc coordinates
|
||
|
|
charin(xto10(hch,16),0,xpos); // calc Hex -> Ascii+charin
|
||
|
|
switchmode(); // and back
|
||
|
|
pos.x=xpos; // restore positions
|
||
|
|
moveright();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if((inpch < 256))
|
||
|
|
{
|
||
|
|
waddch(wascii,inpch);
|
||
|
|
charin(inpch,1,pos.x);
|
||
|
|
moveright();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
bottomout();
|
||
|
|
scrrefresh();
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
WINDOW* s=derwin(whex,3,17,7,17);
|
||
|
|
wattrset(s,COLOR_PAIR(1));
|
||
|
|
box(s,0,0);
|
||
|
|
wattrset(s,COLOR_PAIR(3));
|
||
|
|
mvwaddstr(s,1,1,"SAVE FILE (Y/N)");
|
||
|
|
wrefresh(s);
|
||
|
|
int saveit= wgetch(s);
|
||
|
|
endscr();
|
||
|
|
unallocmem(saveit,argv[1]);
|
||
|
|
|
||
|
|
return (fclose(fp));
|
||
|
|
}
|