Compare commits
13
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9e6d43bc62 | ||
|
|
1e540592d0 | ||
|
|
062896bac5 | ||
|
|
98c8a791c3 | ||
|
|
86f1f992f9 | ||
|
|
6d06c2abb1 | ||
|
|
81ed5b56c6 | ||
|
|
00a1ead9b4 | ||
|
|
815235ee25 | ||
|
|
dbbae23af5 | ||
|
|
05b057f9d8 | ||
|
|
7b7a79184d | ||
|
|
e62e58f520 |
No files matched your search
+1
-1
@@ -722,7 +722,6 @@ end -- tup.getconfig('NO_CMM') ~= 'full'
|
||||
if tup.getconfig('NO_MSVC') ~= 'full' then
|
||||
tup.append_table(img_files, {
|
||||
{"GRAPH", VAR_PROGS .. "/other/graph/graph"},
|
||||
{"TABLE", VAR_PROGS .. "/other/table/table"},
|
||||
{"GAMES/KOSILKA", VAR_PROGS .. "/games/kosilka/kosilka"},
|
||||
{"GAMES/RFORCES", VAR_PROGS .. "/games/rforces/rforces"},
|
||||
{"GAMES/XONIX", VAR_PROGS .. "/games/xonix/xonix"},
|
||||
@@ -743,6 +742,7 @@ tup.append_table(img_files, {
|
||||
{"SHELL", VAR_PROGS .. "/system/shell/shell"},
|
||||
{"GAMES/DINO", VAR_PROGS .. "/games/dino/dino"},
|
||||
{"GAMES/FLPYBIRD", VAR_PROGS .. "/games/flpybird/flpybird"},
|
||||
{"TABLE", VAR_PROGS .. "/other/table/table"},
|
||||
})
|
||||
end -- tup.getconfig('NO_FASM') ~= 'full'
|
||||
tup.append_table(img_files, {
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
#include "kosSyst.h"
|
||||
#include "kosfile.h"
|
||||
//#include "string.h"
|
||||
|
||||
|
||||
CKosFile::CKosFile(char *fileName)
|
||||
{
|
||||
//
|
||||
this->fileInfo.bufferPtr = new Byte[FILE_BUFFER_SIZE];
|
||||
//
|
||||
this->filePointer = 0;
|
||||
this->bufferPointer = 0;
|
||||
this->validBuffer = false;
|
||||
//
|
||||
strcpy( this->fileInfo.fileURL, fileName );
|
||||
}
|
||||
|
||||
|
||||
CKosFile::~CKosFile(void)
|
||||
{
|
||||
//
|
||||
delete this->fileInfo.bufferPtr;
|
||||
}
|
||||
|
||||
|
||||
void CKosFile::ValidateBuffer()
|
||||
{
|
||||
//
|
||||
if ( this->validBuffer )
|
||||
{
|
||||
//
|
||||
if ( this->filePointer < this->bufferPointer
|
||||
|| this->filePointer >= (this->bufferPointer + FILE_BUFFER_SIZE) )
|
||||
{
|
||||
//
|
||||
this->validBuffer = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CKosFile::UpdateBuffer(void)
|
||||
{
|
||||
//
|
||||
if ( ! this->validBuffer )
|
||||
{
|
||||
//
|
||||
this->fileInfo.OffsetLow = this->filePointer / OS_BLOCK_SIZE;
|
||||
this->fileInfo.OffsetHigh = 0;
|
||||
//
|
||||
this->bufferPointer = this->fileInfo.OffsetLow * OS_BLOCK_SIZE;
|
||||
//
|
||||
this->fileInfo.dataCount = FILE_BUFFER_BLOCKS;
|
||||
//
|
||||
this->fileInfo.rwMode = 0;
|
||||
//
|
||||
Dword rr = kos_FileSystemAccess( &(this->fileInfo) );
|
||||
this->validBuffer = ( rr == 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int CKosFile::Seek(int seekFrom, int seekStep)
|
||||
{
|
||||
//
|
||||
switch ( seekFrom )
|
||||
{
|
||||
//
|
||||
case SEEK_SET:
|
||||
//
|
||||
this->filePointer = seekStep;
|
||||
break;
|
||||
//
|
||||
case SEEK_CUR:
|
||||
//
|
||||
this->filePointer += seekStep;
|
||||
break;
|
||||
}
|
||||
//
|
||||
this->ValidateBuffer();
|
||||
//
|
||||
return this->filePointer;
|
||||
}
|
||||
|
||||
|
||||
int CKosFile::Read(Byte *targetPtr, int readCount)
|
||||
{
|
||||
int bufferLeast, result;
|
||||
|
||||
//
|
||||
result = 0;
|
||||
//
|
||||
do
|
||||
{
|
||||
//
|
||||
this->UpdateBuffer();
|
||||
//
|
||||
if ( ! this->validBuffer ) return result;
|
||||
//
|
||||
bufferLeast = FILE_BUFFER_SIZE - (this->filePointer - this->bufferPointer);
|
||||
//
|
||||
if ( bufferLeast > readCount ) bufferLeast = readCount;
|
||||
//
|
||||
if ( bufferLeast )
|
||||
{
|
||||
//
|
||||
memcpy(
|
||||
targetPtr,
|
||||
this->fileInfo.bufferPtr + (this->filePointer - this->bufferPointer),
|
||||
bufferLeast
|
||||
);
|
||||
//
|
||||
targetPtr += bufferLeast;
|
||||
readCount -= bufferLeast;
|
||||
this->filePointer += bufferLeast;
|
||||
//
|
||||
result += bufferLeast;
|
||||
}
|
||||
//
|
||||
this->ValidateBuffer();
|
||||
}
|
||||
while ( readCount > 0 );
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int CKosFile::Write(Byte *sourcePtr, int writeCount)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#define SEEK_SET 0
|
||||
#define SEEK_CUR 1
|
||||
|
||||
#define FILE_BUFFER_SIZE 512
|
||||
#define OS_BLOCK_SIZE 1
|
||||
#define FILE_BUFFER_BLOCKS (FILE_BUFFER_SIZE / OS_BLOCK_SIZE)
|
||||
|
||||
|
||||
class CKosFile
|
||||
{
|
||||
public:
|
||||
CKosFile(char *fileName);
|
||||
virtual ~CKosFile(void);
|
||||
virtual int Read(Byte *targetPtr, int readCount);
|
||||
virtual int Write(Byte *sourcePtr, int writeCount);
|
||||
virtual int Seek(int seekFrom, int seekStep);
|
||||
protected:
|
||||
int filePointer;
|
||||
int bufferPointer;
|
||||
bool validBuffer;
|
||||
kosFileInfo fileInfo;
|
||||
virtual void ValidateBuffer(void);
|
||||
virtual void UpdateBuffer(void);
|
||||
};
|
||||
@@ -1,28 +0,0 @@
|
||||
//
|
||||
|
||||
struct MemBlock
|
||||
{
|
||||
Dword Size;
|
||||
Dword Addr;
|
||||
MemBlock *Next;
|
||||
MemBlock *Previous;
|
||||
};
|
||||
|
||||
|
||||
#define INITIALQUEUESIZE (32 * 4)
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE -1
|
||||
|
||||
#define MB_FREE 0
|
||||
#define MB_USER 1
|
||||
|
||||
#define SIZE_ALIGN 4
|
||||
|
||||
|
||||
|
||||
Byte *allocmem( Dword reqsize );
|
||||
Dword freemem( void *vaddress );
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
if tup.getconfig("NO_MSVC") ~= "" then return end
|
||||
if tup.getconfig("NO_TCC") ~= "" or tup.getconfig("NO_FASM") ~= "" then return end
|
||||
HELPERDIR = (tup.getconfig("HELPERDIR") == "") and "../.." or tup.getconfig("HELPERDIR")
|
||||
tup.include(HELPERDIR .. "/use_msvc.lua")
|
||||
compile_msvc{"*.cpp"}
|
||||
link_msvc("table")
|
||||
tup.include(HELPERDIR .. "/use_tcc.lua")
|
||||
|
||||
LIBS = "-lbox_lib"
|
||||
|
||||
link_tcc({"table.c", "calc.c", "parser.c"}, "table")
|
||||
@@ -1,9 +0,0 @@
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"
|
||||
|
||||
@cl /c /O2 /nologo /GS- /GR- /fp:fast *.cpp
|
||||
@link /nologo /manifest:no /entry:crtStartUp /subsystem:native /base:0 /fixed /align:16 /nodefaultlib hello.obj *.obj
|
||||
@del table
|
||||
@pe2kos hello.exe table
|
||||
@del hello.exe
|
||||
@del *.obj
|
||||
pause
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
+25
-24
@@ -1,24 +1,25 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "KosSyst.h"
|
||||
|
||||
extern int cf_x0, cf_x1, cf_y0, cf_y1;
|
||||
|
||||
void calculate_values();
|
||||
int get_x(int x);
|
||||
int get_y(int y);
|
||||
char *make_col_cap(int i);
|
||||
char *make_row_cap(int i);
|
||||
void init();
|
||||
void reinit();
|
||||
int SaveFile(char *fname);
|
||||
int LoadFile(char *fname);
|
||||
int SaveCSV(char *fname);
|
||||
int LoadCSV(char *fname);
|
||||
void fill_cells(int sel_x, int sel_y, int sel_end_x, int sel_end_y, int old_end_x, int old_end_y);
|
||||
int parse_cell_name(char *str, int *px, int *py, int *xd = NULL, int *yd = NULL);
|
||||
char *make_cell_name(int x, int y, int xd, int yd);
|
||||
char *change_formula(char *name, int sx, int sy);
|
||||
|
||||
void freeBuffer();
|
||||
#pragma once
|
||||
|
||||
// The spreadsheet model. Row/column 0 hold the headers, so the usable range
|
||||
// is 1..cols-1 by 1..rows-1 (columns A..CZ, rows 1..100).
|
||||
typedef struct {
|
||||
int cols, rows; // dimensions, including the header index 0
|
||||
int *w, *h; // column widths / row heights
|
||||
int *x, *y; // on-screen position of each column/row (set every redraw)
|
||||
char ***cells; // cell source text
|
||||
char ***values; // computed cell values
|
||||
} Table;
|
||||
|
||||
extern Table tbl;
|
||||
|
||||
// formula-relative rectangle: table_shift_formula() shifts only refs inside it
|
||||
extern int cf_x0, cf_x1, cf_y0, cf_y1;
|
||||
|
||||
void table_init(void);
|
||||
void table_reset(void);
|
||||
void table_recalc(void);
|
||||
int table_save(char *fname);
|
||||
int table_load(char *fname);
|
||||
void table_fill(int sel_x, int sel_y, int sel_end_x, int sel_end_y, int old_end_x, int old_end_y);
|
||||
char *table_shift_formula(char *name, int sx, int sy);
|
||||
void freeBuffer(void);
|
||||
@@ -1,524 +0,0 @@
|
||||
|
||||
|
||||
#include "func.h"
|
||||
|
||||
int convert_error = 0;
|
||||
int SysColor = 0;
|
||||
char debuf[50] = "";
|
||||
|
||||
|
||||
void kos_DrawRegion(Word x, Word y,Word width, Word height, Dword color1, Word invert)
|
||||
{
|
||||
kos_DrawLine(x,y,x+width-2,y,color1,invert);
|
||||
kos_DrawLine(x,y+1,x,y+height-1,color1,invert);
|
||||
kos_DrawLine(x+width-1,y,x+width-1,y+height-2,color1,invert);
|
||||
kos_DrawLine(x+1,y+height-1,x+width-1,y+height-1,color1,invert);
|
||||
}
|
||||
|
||||
void kos_DrawCutTextSmall(Word x, Word y, int areaWidth, Dword textColour, char *textPtr)
|
||||
{
|
||||
if (textPtr) {
|
||||
int textLen = strlen(textPtr);
|
||||
if (textLen*8 > areaWidth) textLen = areaWidth / 8;
|
||||
kos_WriteTextToWindow(x,y,0x10,textColour,textPtr,textLen);
|
||||
}
|
||||
}
|
||||
|
||||
// фр, ¤Єю ср э
|
||||
int atoi(const char* string)
|
||||
{
|
||||
int res=0;
|
||||
int sign=0;
|
||||
const char* ptr;
|
||||
for (ptr=string; *ptr && *ptr<=' ';ptr++);
|
||||
if (*ptr=='-') {sign=1;++ptr;}
|
||||
while (*ptr >= '0' && *ptr <= '9')
|
||||
{
|
||||
res = res*10 + *ptr++ - '0';
|
||||
}
|
||||
if (sign) res = -res;
|
||||
return res;
|
||||
}
|
||||
|
||||
int toupper(int c)
|
||||
{
|
||||
if ( (c >= 97) && (c <= 122) ) return c-32 ;
|
||||
if ( (c >= 160) && (c <= 175) ) return c-32 ;
|
||||
if ( (c >= 224) && (c <= 239) ) return c-80 ;
|
||||
if ( (c == 241) || (c == 243) || (c == 245) || (c == 247) ) return c-1;
|
||||
return c;
|
||||
}
|
||||
|
||||
int strnicmp(const char* string1, const char* string2, unsigned count)
|
||||
{
|
||||
int pc = 0;
|
||||
while (1)
|
||||
{
|
||||
if (toupper(*string1)<toupper(*string2)) return -1;
|
||||
if (toupper(*string1)>toupper(*string2)) return 1;
|
||||
if (*string1=='\0' || pc == count) return 0;
|
||||
string1++;
|
||||
string2++;
|
||||
pc++;
|
||||
}
|
||||
}
|
||||
|
||||
/*int abs(int n)
|
||||
{
|
||||
return (n<0)?-n:n;
|
||||
}*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
double fabs(double x)
|
||||
{
|
||||
__asm fld x
|
||||
__asm fabs
|
||||
}
|
||||
#define M_PI 3.14159265358979323846
|
||||
double cos(double x)
|
||||
{
|
||||
__asm fld x
|
||||
__asm fcos
|
||||
}
|
||||
double sin(double x)
|
||||
{
|
||||
__asm fld x
|
||||
__asm fsin
|
||||
}
|
||||
|
||||
bool isalpha(char c)
|
||||
{
|
||||
return (c==' ' || c=='\n' || c=='\t' || c=='\r');
|
||||
}
|
||||
|
||||
// ¤Єр ЇєэъЎш - тхыюёшяхф. эю яЁю∙х с√ыю эряшёрЄ№ ўхь эрщЄш.
|
||||
double convert(char *s, int *len)
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
|
||||
double sign,res, tail, div;
|
||||
|
||||
convert_error = 0;
|
||||
|
||||
res = 0.0;
|
||||
|
||||
i=0;
|
||||
while (s[i] && isalpha(s[i])) i++;
|
||||
if (len) *len=i;
|
||||
if (s[i] == '\0')
|
||||
{
|
||||
convert_error = ERROR_END;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
sign=1.0;
|
||||
if (s[i] == '-')
|
||||
{
|
||||
sign=-1.0;
|
||||
i++;
|
||||
}
|
||||
while (s[i] && s[i] >= '0' && s[i] <= '9')
|
||||
{
|
||||
res *= 10.0;
|
||||
res += id(s[i] - '0');
|
||||
i++;
|
||||
}
|
||||
if (len) *len=i;
|
||||
if (!s[i] || isalpha(s[i]))
|
||||
return sign*res;
|
||||
if (s[i] != '.' && s[i] != ',')
|
||||
{
|
||||
convert_error = ERROR;
|
||||
return 0;
|
||||
}
|
||||
i++;
|
||||
if (len) *len=i;
|
||||
if (!s[i])
|
||||
return sign*res;
|
||||
|
||||
div = 1.0;
|
||||
tail = 0.0;
|
||||
while (s[i] && s[i] >= '0' && s[i] <= '9')
|
||||
{
|
||||
tail *= 10.0;
|
||||
tail += id(s[i] - '0');
|
||||
div *= 10.0;
|
||||
i++;
|
||||
}
|
||||
res += tail/div;
|
||||
if (len) *len=i;
|
||||
return sign*res;
|
||||
}
|
||||
|
||||
/*
|
||||
#define PREC 2
|
||||
|
||||
double double_tab[]={1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15};
|
||||
|
||||
// ¤Єю sprintf, єьх■∙шщ ЇюЁьрЄшЁютрЄ№ _Єюы№ъю_ тх∙хёЄтхээ√х ўшёыр (double) %f
|
||||
void format( char *Str, int len, char* Format, ... )
|
||||
{
|
||||
int i, fmtlinesize, j, k, flag;
|
||||
char c;
|
||||
va_list arglist;
|
||||
//
|
||||
va_start(arglist, Format);
|
||||
|
||||
//
|
||||
fmtlinesize = strlen( Format );
|
||||
//
|
||||
if( fmtlinesize == 0 ) return;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
Str[i] = 0;
|
||||
|
||||
//
|
||||
for( i = 0, j = 0; i < fmtlinesize; i++ )
|
||||
{
|
||||
//
|
||||
c = Format[i];
|
||||
//
|
||||
if( c != '%' )
|
||||
{
|
||||
Str[j++] = c;
|
||||
continue;
|
||||
}
|
||||
//
|
||||
i++;
|
||||
//
|
||||
if( i >= fmtlinesize ) break;
|
||||
|
||||
//
|
||||
flag = 0;
|
||||
//
|
||||
c = Format[i];
|
||||
//
|
||||
switch( c )
|
||||
{
|
||||
//
|
||||
case '%':
|
||||
Str[j++] = c;
|
||||
break;
|
||||
// auaia aauanoaaiiiai ?enea
|
||||
case 'f':
|
||||
// ii?aaaeeou ?enei oeo? ai oi?ee
|
||||
double val, w;
|
||||
int p;
|
||||
val = va_arg(arglist, double);
|
||||
if (val < 0.0)
|
||||
{
|
||||
Str[j++] = '-';
|
||||
val = -val;
|
||||
}
|
||||
for (k = 0; k < 15; k++)
|
||||
if (val < double_tab[k])
|
||||
break;
|
||||
|
||||
if (val < 1.0)
|
||||
{
|
||||
Str[j++] = '0';
|
||||
}
|
||||
|
||||
for (p = 1; p < k + 1; p++)
|
||||
{
|
||||
Str[j++] = '0' + di(val / double_tab[k - p] - 0.499) % 10;
|
||||
}
|
||||
Str[j++] = '.';
|
||||
w = 0.1;
|
||||
for (p = 0; p < 2; p++)
|
||||
{
|
||||
val-=floor(val);
|
||||
Str[j++] = '0' + di(val / w - 0.499) % 10;
|
||||
w /= 10.0;
|
||||
}
|
||||
|
||||
//
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
//
|
||||
Str[j] = 0;
|
||||
}
|
||||
|
||||
void *memcpy2(void *dst, const void *src, unsigned size)
|
||||
{
|
||||
while (size--)
|
||||
*((char*)dst+size) = *((char*)src+size);
|
||||
return dst;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
int strcmp(const char *s1, const char *s2)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (s1 == NULL)
|
||||
if (s2 == NULL)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
else
|
||||
if (s2 == NULL)
|
||||
return 1;
|
||||
|
||||
for (i = 0;;i++)
|
||||
{
|
||||
if (s1[i] == '\0')
|
||||
if (s2[i] == '\0')
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
else
|
||||
if (s2[i] == '\0')
|
||||
return 1;
|
||||
else
|
||||
{
|
||||
if (s1[i] != s2[i])
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
kol_struct_import* kol_cofflib_load(char *name)
|
||||
{
|
||||
//asm ("int $0x40"::"a"(68), "b"(19), "c"(name));
|
||||
__asm
|
||||
{
|
||||
mov eax, 68
|
||||
mov ebx, 19
|
||||
mov ecx, name
|
||||
int 0x40
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void* kol_cofflib_procload (kol_struct_import *imp, char *name)
|
||||
{
|
||||
|
||||
int i;
|
||||
for (i=0;;i++)
|
||||
if ( NULL == ((imp+i) -> name))
|
||||
break;
|
||||
else
|
||||
if ( 0 == strcmp(name, (imp+i)->name) )
|
||||
return (imp+i)->data;
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
|
||||
unsigned kol_cofflib_procnum (kol_struct_import *imp)
|
||||
{
|
||||
|
||||
unsigned i, n;
|
||||
|
||||
for (i=n=0;;i++)
|
||||
if ( NULL == ((imp+i) -> name))
|
||||
break;
|
||||
else
|
||||
n++;
|
||||
|
||||
return n;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void kol_cofflib_procname (kol_struct_import *imp, char *name, unsigned n)
|
||||
{
|
||||
|
||||
unsigned i;
|
||||
*name = 0;
|
||||
|
||||
for (i=0;;i++)
|
||||
if ( NULL == ((imp+i) -> name))
|
||||
break;
|
||||
else
|
||||
if ( i == n )
|
||||
{
|
||||
strcpy(name, ((imp+i)->name));
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
end of system part
|
||||
*/
|
||||
|
||||
|
||||
// яюёъюы№ъє яюЁЄшЁютры ё фЁхтэхую фюёр...
|
||||
void line( int x1, int y1, int x2, int y2)
|
||||
{
|
||||
kos_DrawLine(x1,y1,x2,y2,SysColor,0);
|
||||
}
|
||||
|
||||
void outtextxy( int x, int y, char *s, int len)
|
||||
{
|
||||
kos_WriteTextToWindow(x,y,0,SysColor,s,len);
|
||||
}
|
||||
|
||||
double textwidth( char *s, int len)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < len; i++)
|
||||
if (s[i] == 0)
|
||||
break;
|
||||
return id(i * 6);
|
||||
}
|
||||
|
||||
double textheight( char *s, int len)
|
||||
{
|
||||
return 8.0;
|
||||
}
|
||||
|
||||
void setcolor( DWORD color)
|
||||
{
|
||||
SysColor = color;
|
||||
}
|
||||
|
||||
void rectangle( int x1, int y1, int x2, int y2)
|
||||
{
|
||||
kos_DrawBar(x1,y1,x2-x1,y2-y1,SysColor);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Dword kos_GetSkinHeight()
|
||||
{
|
||||
__asm{
|
||||
mov eax, 48
|
||||
mov ebx, 4
|
||||
int 0x40
|
||||
}
|
||||
}
|
||||
|
||||
Dword kos_GetSpecialKeyState()
|
||||
{
|
||||
__asm{
|
||||
mov eax, 66
|
||||
mov ebx, 3
|
||||
int 0x40
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Dword kos_GetSlotByPID(Dword PID)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
push ebx
|
||||
push ecx
|
||||
mov eax, 18
|
||||
mov ebx, 21
|
||||
mov ecx, PID
|
||||
int 0x40
|
||||
pop ecx
|
||||
pop ebx
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Dword kos_GetActiveSlot()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
push ebx
|
||||
mov eax, 18
|
||||
mov ebx, 7
|
||||
int 0x40
|
||||
pop ebx
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void kos_GetScrollInfo(int &vert, int &hor)
|
||||
{
|
||||
short v, h;
|
||||
__asm
|
||||
{
|
||||
mov eax, 37
|
||||
mov ebx, 7
|
||||
int 0x40
|
||||
mov ebx, eax
|
||||
and eax, 0xffff
|
||||
mov v, ax
|
||||
shr ebx, 16
|
||||
mov h, bx
|
||||
}
|
||||
vert = v;
|
||||
hor = h;
|
||||
}
|
||||
|
||||
|
||||
// яюыєўхэшх шэЇюЁьрЎшш ю ёюёЄю эшш "ь√°ш" ЇєэъЎш 37/1
|
||||
void kos_GetMouseStateWnd( Dword & buttons, int & cursorX, int & cursorY )
|
||||
{
|
||||
Dword mB;
|
||||
Word curX;
|
||||
Word curY;
|
||||
sProcessInfo sPI;
|
||||
|
||||
//
|
||||
__asm{
|
||||
mov eax, 37
|
||||
mov ebx, 1
|
||||
int 0x40
|
||||
mov curY, ax
|
||||
shr eax, 16
|
||||
mov curX, ax
|
||||
mov eax, 37
|
||||
mov ebx, 2
|
||||
int 0x40
|
||||
mov mB, eax
|
||||
}
|
||||
//
|
||||
kos_ProcessInfo( &sPI );
|
||||
//
|
||||
buttons = mB;
|
||||
cursorX = curX - sPI.processInfo.x_start;
|
||||
cursorY = curY - sPI.processInfo.y_start;
|
||||
}
|
||||
|
||||
char *ftoa(double d)
|
||||
{
|
||||
char buffer[256], *p;
|
||||
sprintf(buffer, "%f", d);
|
||||
p = (char*)allocmem(strlen(buffer)+1);
|
||||
strcpy(p, buffer);
|
||||
return p;
|
||||
}
|
||||
|
||||
double atof(char *s)
|
||||
{
|
||||
return convert(s, NULL);
|
||||
}
|
||||
|
||||
|
||||
int di(double x)
|
||||
{
|
||||
int a;
|
||||
__asm fld x
|
||||
__asm fistp a
|
||||
return a;
|
||||
}
|
||||
|
||||
double id(int x)
|
||||
{
|
||||
double a;
|
||||
__asm fild x
|
||||
__asm fstp a
|
||||
return a;
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "kosSyst.h"
|
||||
#include "kosFile.h"
|
||||
#include "MCSMEMM.H"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
#define min(a,b) (((a)<(b))?(a):(b))
|
||||
#define max(a,b) (((a)>(b))?(a):(b))
|
||||
|
||||
|
||||
#define ERROR -1
|
||||
#define ERROR_END -2
|
||||
|
||||
extern int convert_error;
|
||||
|
||||
#define PREC 2
|
||||
|
||||
typedef int HDC;
|
||||
typedef int DWORD;
|
||||
|
||||
extern int SysColor;
|
||||
extern char debuf[50];
|
||||
|
||||
typedef double (*function_t)(double);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double x, y;
|
||||
} TCoord;
|
||||
|
||||
struct kosBDVK
|
||||
{
|
||||
Dword attrib;
|
||||
Dword name_type;
|
||||
Dword create_time;
|
||||
Dword create_date;
|
||||
Dword access_time;
|
||||
Dword access_date;
|
||||
Dword modify_time;
|
||||
Dword modify_date;
|
||||
Dword size_low;
|
||||
Dword size_high;
|
||||
};
|
||||
|
||||
Dword kos_GetSlotByPID(Dword PID);
|
||||
Dword kos_GetActiveSlot();
|
||||
Dword kos_GetSkinHeight();
|
||||
Dword kos_GetSpecialKeyState();
|
||||
void kos_GetMouseStateWnd( Dword & buttons, int & cursorX, int & cursorY );
|
||||
void kos_DrawRegion(Word x, Word y,Word width, Word height, Dword color1, Word invert);
|
||||
void kos_DrawCutTextSmall(Word x, Word y, int areaWidth, Dword textColour, char *textPtr);
|
||||
int atoi(const char* string);
|
||||
int toupper(int c);
|
||||
int strnicmp(const char* string1, const char* string2, unsigned count);
|
||||
void kos_GetScrollInfo(int &vert, int &hor);
|
||||
|
||||
|
||||
Dword kos_GetSlotByPID(Dword PID);
|
||||
Dword kos_GetActiveSlot();
|
||||
Dword kos_GetSkinHeight();
|
||||
Dword kos_GetSpecialKeyState();
|
||||
|
||||
|
||||
double fabs(double x);
|
||||
double cos(double x);
|
||||
double sin(double x);
|
||||
bool isalpha(char c);
|
||||
double convert(char *s, int *len=NULL);
|
||||
void format( char *Str, int len, char* Format, ... );
|
||||
|
||||
void line( int x1, int y1, int x2, int y2);
|
||||
|
||||
void outtextxy( int x, int y, char *s, int len);
|
||||
void settextstyle( int a1, int a2, int a3);
|
||||
|
||||
|
||||
double textwidth( char *s, int len);
|
||||
double textheight( char *s, int len);
|
||||
void setcolor( DWORD color);
|
||||
void unsetcolor(HDC hdc);
|
||||
void rectangle( int x1, int y1, int x2, int y2);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned p00 ;
|
||||
unsigned p04 ;
|
||||
unsigned p08 ;
|
||||
unsigned p12 ;
|
||||
unsigned p16 ;
|
||||
char p20 ;
|
||||
char *p21 ;
|
||||
} kol_struct70 ;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned p00 ;
|
||||
char p04 ;
|
||||
char p05[3] ;
|
||||
unsigned p08 ;
|
||||
unsigned p12 ;
|
||||
unsigned p16 ;
|
||||
unsigned p20 ;
|
||||
unsigned p24 ;
|
||||
unsigned p28 ;
|
||||
unsigned p32[2] ;
|
||||
unsigned p40 ;
|
||||
} kol_struct_BDVK ;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *name ;
|
||||
void *data ;
|
||||
} kol_struct_import ;
|
||||
|
||||
|
||||
|
||||
kol_struct_import* kol_cofflib_load(char *name);
|
||||
void* kol_cofflib_procload (kol_struct_import *imp, char *name);
|
||||
unsigned kol_cofflib_procnum (kol_struct_import *imp);
|
||||
void kol_cofflib_procname (kol_struct_import *imp, char *name, unsigned n);
|
||||
int strcmp(const char* string1, const char* string2);
|
||||
|
||||
char *ftoa(double d);
|
||||
double atof(char *s);
|
||||
|
||||
|
||||
int di(double x);
|
||||
double id(int x);
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,978 +0,0 @@
|
||||
#include "kosSyst.h"
|
||||
#include "func.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
#define atexitBufferSize 32
|
||||
|
||||
// Autobuild uses FASM method for exe->kos,
|
||||
// MENUET01 header should be present in EXE.
|
||||
#ifdef AUTOBUILD
|
||||
char kosExePath[1024];
|
||||
char exeStack[16384];
|
||||
extern char params[1024];
|
||||
// must be alphabetically first in the image
|
||||
#pragma data_seg(".1seg")
|
||||
extern "C" struct
|
||||
{
|
||||
char header[8];
|
||||
int headerver;
|
||||
void* entry;
|
||||
void* i_end;
|
||||
void* memsize;
|
||||
void* stack;
|
||||
void* params;
|
||||
void* icon;
|
||||
} header = {
|
||||
{'M', 'E', 'N', 'U', 'E', 'T', '0', '1'},
|
||||
1,
|
||||
&crtStartUp,
|
||||
0, // filled by doexe2.asm
|
||||
0, // filled by doexe2.asm
|
||||
exeStack + sizeof(exeStack),
|
||||
params,
|
||||
kosExePath
|
||||
};
|
||||
#pragma data_seg()
|
||||
#else
|
||||
char *kosExePath = NULL;
|
||||
#endif
|
||||
|
||||
char pureCallMessage[] = "PURE function call!";
|
||||
|
||||
//
|
||||
void (__cdecl *atExitList[atexitBufferSize])();
|
||||
int atExitFnNum = 0;
|
||||
//
|
||||
int __cdecl atexit( void (__cdecl *func )( void ))
|
||||
{
|
||||
//
|
||||
if ( atExitFnNum < atexitBufferSize )
|
||||
{
|
||||
//
|
||||
atExitList[atExitFnNum++] = func;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
Dword RandomSeed = 1;
|
||||
//
|
||||
void rtlSrand( Dword seed )
|
||||
{
|
||||
RandomSeed = seed;
|
||||
}
|
||||
//
|
||||
Dword rtlRand( void )
|
||||
{
|
||||
//ьрёър 0x80000776
|
||||
|
||||
Dword dwi, i;
|
||||
|
||||
for ( i = 0; i < 32; i++ )
|
||||
{
|
||||
|
||||
dwi = RandomSeed & 0x80000776;
|
||||
|
||||
__asm{
|
||||
mov eax, dwi
|
||||
mov edx, eax
|
||||
bswap eax
|
||||
xor eax, edx
|
||||
xor al, ah
|
||||
setpo al
|
||||
movzx eax, al
|
||||
mov dwi, eax
|
||||
}
|
||||
|
||||
RandomSeed = ( RandomSeed << 1 ) | ( dwi & 1 );
|
||||
}
|
||||
|
||||
return RandomSeed;
|
||||
}
|
||||
|
||||
//#ifdef AUTOBUILD
|
||||
// Well, not really related to auto-build, but some compilation issue
|
||||
void memcpy( void *dst, const void *src, size_t bytesCount )
|
||||
{
|
||||
__asm{
|
||||
mov edi, dst
|
||||
// mov eax, dst
|
||||
mov esi, src
|
||||
mov ecx, bytesCount
|
||||
rep movsb
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void memset( Byte *dst, Byte filler, Dword count )
|
||||
{
|
||||
//
|
||||
__asm{
|
||||
mov edi, dst
|
||||
mov al, filler
|
||||
mov ecx, count
|
||||
rep stosb
|
||||
}
|
||||
}
|
||||
//#endif
|
||||
|
||||
|
||||
//
|
||||
Dword rtlInterlockedExchange( Dword *target, Dword value )
|
||||
{
|
||||
// Dword result;
|
||||
|
||||
//
|
||||
__asm{
|
||||
mov eax, value
|
||||
mov ebx, target
|
||||
xchg eax, [ebx]
|
||||
// mov result, eax
|
||||
}
|
||||
//
|
||||
// return result;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ъюяшЁютрэшх ёЄЁюъш
|
||||
//
|
||||
|
||||
char * __cdecl strcpy( char *target, const char *source )
|
||||
{
|
||||
char *result = target;
|
||||
|
||||
while( target[0] = source[0] )
|
||||
{
|
||||
target++;
|
||||
source++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ЁхтхЁёштэ√щ яюшёъ ёшьтюыр
|
||||
//
|
||||
|
||||
char * __cdecl strrchr( const char * string, int c )
|
||||
{
|
||||
char *cPtr;
|
||||
|
||||
//
|
||||
for ( cPtr = (char *)string + strlen( string ); cPtr >= string; cPtr-- )
|
||||
{
|
||||
//
|
||||
if ( *cPtr == c ) return cPtr;
|
||||
}
|
||||
//
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// юяЁхфхыхэшх фышэ√ ёЄЁюъш
|
||||
//
|
||||
|
||||
int __cdecl strlen( const char *line )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i=0; line[i] != 0; i++ );
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// яхЁхтюф °хёЄэрфЎрЄшЁшўэюую ўшёыр т ёшьтюы
|
||||
//
|
||||
|
||||
unsigned int num2hex( unsigned int num )
|
||||
{
|
||||
if( num < 10 )
|
||||
return num + '0';
|
||||
return num - 10 + 'A';
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// т√тюф ёЄЁюъш эр яхўрЄ№. barsuk фюсртшы %f
|
||||
|
||||
//#define PREC 2
|
||||
//#define HALF 0.499
|
||||
#define PREC 6
|
||||
#define HALF 0.4999999
|
||||
|
||||
double double_tab[]={1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15,
|
||||
1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29, 1e30};
|
||||
|
||||
|
||||
//
|
||||
|
||||
Dword dectab[] = { 1000000000, 100000000, 10000000, 1000000, 100000,
|
||||
10000, 1000, 100, 10, 0 };
|
||||
|
||||
//
|
||||
void sprintf( char *Str, char* Format, ... )
|
||||
{
|
||||
int i, fmtlinesize, j, k, flag;
|
||||
Dword head, tail;
|
||||
char c;
|
||||
va_list arglist;
|
||||
//
|
||||
va_start(arglist, Format);
|
||||
|
||||
//
|
||||
fmtlinesize = strlen( Format );
|
||||
//
|
||||
if( fmtlinesize == 0 ) return;
|
||||
|
||||
//
|
||||
for( i = 0, j = 0; i < fmtlinesize; i++ )
|
||||
{
|
||||
//
|
||||
c = Format[i];
|
||||
//
|
||||
if( c != '%' )
|
||||
{
|
||||
Str[j++] = c;
|
||||
continue;
|
||||
}
|
||||
//
|
||||
i++;
|
||||
//
|
||||
if( i >= fmtlinesize ) break;
|
||||
|
||||
//
|
||||
flag = 0;
|
||||
//
|
||||
c = Format[i];
|
||||
//
|
||||
switch( c )
|
||||
{
|
||||
//
|
||||
case '%':
|
||||
Str[j++] = c;
|
||||
break;
|
||||
// т√тюф ёЄЁюъш
|
||||
case 'S':
|
||||
Byte* str;
|
||||
str = va_arg(arglist, Byte*);
|
||||
for( k = 0; ( c = str[k] ) != 0; k++ )
|
||||
{
|
||||
Str[j++] = c;
|
||||
}
|
||||
break;
|
||||
// т√тюф срщЄр
|
||||
case 'B':
|
||||
k = va_arg(arglist, int) & 0xFF;
|
||||
Str[j++] = num2hex( ( k >> 4 ) & 0xF );
|
||||
Str[j++] = num2hex( k & 0xF );
|
||||
break;
|
||||
// т√тюф ёшьтюыр
|
||||
case 'C':
|
||||
Str[j++] = va_arg(arglist, int) & 0xFF;
|
||||
break;
|
||||
// т√тюф фтющэюую ёыютр т °хёЄэрфЎрЄшЁшўэюь тшфх
|
||||
case 'X':
|
||||
Dword val;
|
||||
val = va_arg(arglist, Dword);
|
||||
for( k = 7; k >= 0; k-- )
|
||||
{
|
||||
//
|
||||
c = num2hex ( ( val >> (k * 4) ) & 0xF );
|
||||
//
|
||||
if( c == '0' )
|
||||
{
|
||||
if( flag ) Str[j++] = c;
|
||||
}
|
||||
else
|
||||
{
|
||||
flag++;
|
||||
Str[j++] = c;
|
||||
}
|
||||
}
|
||||
//
|
||||
if( flag == 0 ) Str[j++] = '0';
|
||||
break;
|
||||
// т√тюф фтющэюую ёыютр т фхё Єшўэюь тшфх
|
||||
case 'U':
|
||||
head = va_arg(arglist, Dword);
|
||||
tail = 0;
|
||||
for( k = 0; dectab[k] != 0; k++ )
|
||||
{
|
||||
tail = head % dectab[k];
|
||||
head /= dectab[k];
|
||||
c = head + '0';
|
||||
if( c == '0' )
|
||||
{
|
||||
if( flag ) Str[j++] = c;
|
||||
}
|
||||
else
|
||||
{
|
||||
flag++;
|
||||
Str[j++] = c;
|
||||
}
|
||||
//
|
||||
head = tail;
|
||||
}
|
||||
//
|
||||
c = head + '0';
|
||||
Str[j++] = c;
|
||||
break;
|
||||
// тх∙хёЄтхээюх ўшёыю т ЇюЁьрЄх 7.2
|
||||
case 'f':
|
||||
case 'F':
|
||||
case 'g':
|
||||
case 'G':
|
||||
{
|
||||
double val, w;
|
||||
int p;
|
||||
val = va_arg(arglist, double);
|
||||
if (val < 0.0)
|
||||
{
|
||||
Str[j++] = '-';
|
||||
val = -val;
|
||||
}
|
||||
for (k = 0; k < 30; k++)
|
||||
if (val < double_tab[k])
|
||||
break;
|
||||
|
||||
if (val < 1.0)
|
||||
{
|
||||
Str[j++] = '0';
|
||||
}
|
||||
|
||||
for (p = 1; p < k + 1; p++)
|
||||
{
|
||||
int d = (int)di(val / double_tab[k - p] - HALF) % 10;
|
||||
Str[j++] = '0' + d;
|
||||
val -= d * double_tab[k - p];
|
||||
}
|
||||
Str[j++] = '.';
|
||||
w = 0.1;
|
||||
for (p = 0; p < PREC - 1; p++)
|
||||
{
|
||||
val-=floor(val);
|
||||
Str[j++] = '0' + di(val / w - HALF) % 10;
|
||||
w /= 10.0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// т√тюф 64-сшЄэюую ёыютр т °хёЄэрфЎрЄшЁшўэюь тшфх
|
||||
case 'Q':
|
||||
unsigned int low_dword, high_dword;
|
||||
low_dword = va_arg(arglist, unsigned int);
|
||||
high_dword = va_arg(arglist, unsigned int);
|
||||
for( k = 7; k >= 0; k-- )
|
||||
{
|
||||
//
|
||||
c = num2hex ( ( ( high_dword + 1) >> (k * 4) ) & 0xF );
|
||||
//
|
||||
if( c == '0' )
|
||||
{
|
||||
if( flag ) Str[j++] = c;
|
||||
}
|
||||
else
|
||||
{
|
||||
flag++;
|
||||
Str[j++] = c;
|
||||
}
|
||||
}
|
||||
//
|
||||
for( k=7; k >= 0; k-- )
|
||||
{
|
||||
//
|
||||
c = num2hex ( ( low_dword >> (k * 4) ) & 0xF );
|
||||
//
|
||||
if( c == '0' )
|
||||
{
|
||||
if( flag ) Str[j++] = c;
|
||||
}
|
||||
else
|
||||
{
|
||||
flag++;
|
||||
Str[j++] = c;
|
||||
}
|
||||
}
|
||||
//
|
||||
if( flag == 0 ) Str[j++] = '0';
|
||||
//
|
||||
break;
|
||||
//
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
//
|
||||
Str[j] = 0;
|
||||
}
|
||||
|
||||
|
||||
// function -1 чртхЁ°хэш яЁюЎхёёр
|
||||
void kos_ExitApp()
|
||||
{
|
||||
int i;
|
||||
|
||||
//
|
||||
for ( i = atExitFnNum - 1; i >= 0; i-- )
|
||||
{
|
||||
//
|
||||
atExitList[i]();
|
||||
}
|
||||
//
|
||||
__asm{
|
||||
mov eax, -1
|
||||
int 0x40
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// function 0
|
||||
void kos_DefineAndDrawWindow(
|
||||
Word x, Word y,
|
||||
Word sizeX, Word sizeY,
|
||||
Byte mainAreaType,
|
||||
Dword mainAreaColour,
|
||||
Byte headerType,
|
||||
Dword headerColour,
|
||||
Dword borderColour
|
||||
)
|
||||
{
|
||||
Dword arg1, arg2, arg3, arg4;
|
||||
|
||||
//
|
||||
arg1 = ( x << 16 ) + sizeX;
|
||||
arg2 = ( y << 16 ) + sizeY;
|
||||
arg3 = ( mainAreaType << 24 ) | mainAreaColour;
|
||||
arg4 = ( headerType << 24 ) | headerColour;
|
||||
//
|
||||
__asm{
|
||||
mov eax, 0
|
||||
mov ebx, arg1
|
||||
mov ecx, arg2
|
||||
mov edx, arg3
|
||||
mov esi, arg4
|
||||
mov edi, borderColour
|
||||
int 0x40
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// function 1 яюёЄртшЄ№ Єюўъє
|
||||
void kos_PutPixel( Dword x, Dword y, Dword colour )
|
||||
{
|
||||
//
|
||||
__asm{
|
||||
mov eax, 1
|
||||
mov ebx, x
|
||||
mov ecx, y
|
||||
mov edx, colour
|
||||
int 0x40
|
||||
}
|
||||
}
|
||||
|
||||
bool kos_GetKeys( Dword &key_editbox, Byte &key_ascii, Byte &key_scancode )
|
||||
{
|
||||
Dword result;
|
||||
__asm{
|
||||
mov eax, 2
|
||||
int 0x40
|
||||
mov result, eax
|
||||
}
|
||||
key_editbox = result;
|
||||
key_ascii = result >> 8;
|
||||
key_scancode = result >> 16;
|
||||
return ( key_ascii ) == 0;
|
||||
}
|
||||
|
||||
// function 3 яюыєўшЄ№ тЁхь
|
||||
Dword kos_GetSystemClock()
|
||||
{
|
||||
// Dword result;
|
||||
|
||||
//
|
||||
__asm{
|
||||
mov eax, 3
|
||||
int 0x40
|
||||
// mov result, eax
|
||||
}
|
||||
//
|
||||
// return result;
|
||||
}
|
||||
|
||||
|
||||
// function 4
|
||||
void kos_WriteTextToWindow(
|
||||
Word x,
|
||||
Word y,
|
||||
Byte fontType,
|
||||
Dword textColour,
|
||||
char *textPtr,
|
||||
Dword textLen
|
||||
)
|
||||
{
|
||||
Dword arg1, arg2;
|
||||
|
||||
//
|
||||
arg1 = ( x << 16 ) | y;
|
||||
arg2 = ( fontType << 24 ) | textColour;
|
||||
//
|
||||
__asm{
|
||||
mov eax, 4
|
||||
mov ebx, arg1
|
||||
mov ecx, arg2
|
||||
mov edx, textPtr
|
||||
mov esi, textLen
|
||||
int 0x40
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// function 5 ярєчр, т ёюЄ√ї фюы ї ёхъєэф√
|
||||
void kos_Pause( Dword value )
|
||||
{
|
||||
//
|
||||
__asm{
|
||||
mov eax, 5
|
||||
mov ebx, value
|
||||
int 0x40
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// function 7 эрЁшёютрЄ№ шчюсЁрцхэшх
|
||||
void kos_PutImage( RGB * imagePtr, Word sizeX, Word sizeY, Word x, Word y )
|
||||
{
|
||||
Dword arg1, arg2;
|
||||
|
||||
//
|
||||
arg1 = ( sizeX << 16 ) | sizeY;
|
||||
arg2 = ( x << 16 ) | y;
|
||||
//
|
||||
__asm{
|
||||
mov eax, 7
|
||||
mov ebx, imagePtr
|
||||
mov ecx, arg1
|
||||
mov edx, arg2
|
||||
int 0x40
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// function 8 юяЁхфхышЄ№ ъэюяъє
|
||||
void kos_DefineButton( Word x, Word y, Word sizeX, Word sizeY, Dword buttonID, Dword colour )
|
||||
{
|
||||
kos_UnsaveDefineButton(NULL, NULL, NULL, NULL, buttonID+BT_DEL, NULL);
|
||||
kos_UnsaveDefineButton(x, y, sizeX, sizeY, buttonID, colour);
|
||||
}
|
||||
|
||||
//
|
||||
void kos_UnsaveDefineButton( Word x, Word y, Word sizeX, Word sizeY, Dword buttonID, Dword colour )
|
||||
{
|
||||
Dword arg1, arg2;
|
||||
|
||||
//
|
||||
arg1 = ( x << 16 ) | sizeX;
|
||||
arg2 = ( y << 16 ) | sizeY;
|
||||
//
|
||||
__asm{
|
||||
mov eax, 8
|
||||
mov ebx, arg1
|
||||
mov ecx, arg2
|
||||
mov edx, buttonID
|
||||
mov esi, colour
|
||||
int 0x40
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// function 9 - шэЇюЁьрЎш ю яЁюЎхёёх
|
||||
Dword kos_ProcessInfo( sProcessInfo *targetPtr, Dword processID )
|
||||
{
|
||||
// Dword result;
|
||||
|
||||
//
|
||||
__asm{
|
||||
mov eax, 9
|
||||
mov ebx, targetPtr
|
||||
mov ecx, processID
|
||||
int 0x40
|
||||
// mov result, eax
|
||||
}
|
||||
//
|
||||
// return result;
|
||||
}
|
||||
|
||||
|
||||
// function 10
|
||||
Dword kos_WaitForEvent()
|
||||
{
|
||||
// Dword result;
|
||||
|
||||
__asm{
|
||||
mov eax, 10
|
||||
int 0x40
|
||||
// mov result, eax
|
||||
}
|
||||
|
||||
// return result;
|
||||
}
|
||||
|
||||
|
||||
// function 11
|
||||
Dword kos_CheckForEvent()
|
||||
{
|
||||
// Dword result;
|
||||
|
||||
__asm{
|
||||
mov eax, 11
|
||||
int 0x40
|
||||
// mov result, eax
|
||||
}
|
||||
|
||||
// return result;
|
||||
}
|
||||
|
||||
|
||||
// function 12
|
||||
void kos_WindowRedrawStatus( Dword status )
|
||||
{
|
||||
__asm{
|
||||
mov eax, 12
|
||||
mov ebx, status
|
||||
int 0x40
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// function 13 эрЁшёютрЄ№ яюыюёє
|
||||
void kos_DrawBar( Word x, Word y, Word sizeX, Word sizeY, Dword colour )
|
||||
{
|
||||
Dword arg1, arg2;
|
||||
|
||||
//
|
||||
arg1 = ( x << 16 ) | sizeX;
|
||||
arg2 = ( y << 16 ) | sizeY;
|
||||
//
|
||||
__asm{
|
||||
mov eax, 13
|
||||
mov ebx, arg1
|
||||
mov ecx, arg2
|
||||
mov edx, colour
|
||||
int 0x40
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// function 17
|
||||
bool kos_GetButtonID( Dword &buttonID )
|
||||
{
|
||||
Dword result;
|
||||
|
||||
//
|
||||
__asm{
|
||||
mov eax, 17
|
||||
int 0x40
|
||||
mov result, eax
|
||||
}
|
||||
//
|
||||
buttonID = result >> 8;
|
||||
//
|
||||
return (result & 0xFF) == 0;
|
||||
}
|
||||
|
||||
|
||||
// function 23
|
||||
Dword kos_WaitForEventTimeout( Dword timeOut )
|
||||
{
|
||||
// Dword result;
|
||||
|
||||
__asm{
|
||||
mov eax, 23
|
||||
mov ebx, timeOut
|
||||
int 0x40
|
||||
// mov result, eax
|
||||
}
|
||||
|
||||
// return result;
|
||||
}
|
||||
|
||||
|
||||
// яюыєўхэшх шэЇюЁьрЎшш ю ёюёЄю эшш "ь√°ш" function 37
|
||||
void kos_GetMouseState( Dword & buttons, int & cursorX, int & cursorY )
|
||||
{
|
||||
Dword mB;
|
||||
Word curX;
|
||||
Word curY;
|
||||
sProcessInfo sPI;
|
||||
|
||||
//
|
||||
__asm{
|
||||
mov eax, 37
|
||||
mov ebx, 0
|
||||
int 0x40
|
||||
mov curY, ax
|
||||
shr eax, 16
|
||||
mov curX, ax
|
||||
mov eax, 37
|
||||
mov ebx, 2
|
||||
int 0x40
|
||||
mov mB, eax
|
||||
}
|
||||
//
|
||||
kos_ProcessInfo( &sPI );
|
||||
//
|
||||
buttons = mB;
|
||||
cursorX = curX - sPI.processInfo.x_start;
|
||||
cursorY = curY - sPI.processInfo.y_start;
|
||||
}
|
||||
|
||||
// function 38
|
||||
void kos_DrawLine( Word x1, Word y1, Word x2, Word y2, Dword colour, Dword invert )
|
||||
{
|
||||
Dword arg1, arg2, arg3;
|
||||
|
||||
//
|
||||
arg1 = ( x1 << 16 ) | x2;
|
||||
arg2 = ( y1 << 16 ) | y2;
|
||||
arg3 = (invert)?0x01000000:colour;
|
||||
//
|
||||
__asm{
|
||||
mov eax, 38
|
||||
mov ebx, arg1
|
||||
mov ecx, arg2
|
||||
mov edx, arg3
|
||||
int 0x40
|
||||
}
|
||||
}
|
||||
|
||||
// function 40 єёЄрэютшЄ№ ьрёъє ёюс√Єшщ
|
||||
void kos_SetMaskForEvents( Dword mask )
|
||||
{
|
||||
//
|
||||
__asm{
|
||||
mov eax, 40
|
||||
mov ebx, mask
|
||||
int 0x40
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// function 47 т√тхёЄш т юъэю яЁшыюцхэш ўшёыю
|
||||
void kos_DisplayNumberToWindow(
|
||||
Dword value,
|
||||
Dword digitsNum,
|
||||
Word x,
|
||||
Word y,
|
||||
Dword colour,
|
||||
eNumberBase nBase,
|
||||
bool valueIsPointer
|
||||
)
|
||||
{
|
||||
Dword arg1, arg2;
|
||||
|
||||
//
|
||||
arg1 = ( valueIsPointer ? 1 : 0 ) |
|
||||
( ((Byte)nBase) << 8 ) |
|
||||
( ( digitsNum & 0x1F ) << 16 );
|
||||
arg2 = ( x << 16 ) | y;
|
||||
//
|
||||
__asm{
|
||||
mov eax, 47
|
||||
mov ebx, arg1
|
||||
mov ecx, value
|
||||
mov edx, arg2
|
||||
mov esi, colour
|
||||
int 0x40
|
||||
}
|
||||
}
|
||||
|
||||
// 48.3: get system colors
|
||||
bool kos_GetSystemColors( kosSysColors *sc )
|
||||
{
|
||||
__asm{
|
||||
mov eax, 48
|
||||
mov ebx, 3
|
||||
mov ecx, sc
|
||||
mov edx, 40
|
||||
int 0x40
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// function 63 т√тюф ёшьтюы т юъэю юЄырфъш
|
||||
void kos_DebugOutChar( char ccc )
|
||||
{
|
||||
__asm{
|
||||
mov eax, 63
|
||||
mov ebx, 1
|
||||
mov cl, ccc
|
||||
int 0x40
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// function 66 Ёхцшь яюыєўхэш фрээ√ї юЄ ъыртшрЄєЁ√
|
||||
void kos_SetKeyboardDataMode( Dword mode )
|
||||
{
|
||||
//
|
||||
__asm{
|
||||
mov eax, 66
|
||||
mov ebx, 1
|
||||
mov ecx, mode
|
||||
int 0x40
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// т√тюф ёЄЁюъш т юъэю юЄырфъш
|
||||
void rtlDebugOutString( char *str )
|
||||
{
|
||||
//
|
||||
for ( ; str[0] != 0; str++ )
|
||||
{
|
||||
kos_DebugOutChar( str[0] );
|
||||
}
|
||||
//
|
||||
kos_DebugOutChar( 13 );
|
||||
kos_DebugOutChar( 10 );
|
||||
}
|
||||
|
||||
void kos_DebugValue(char *str, int n)
|
||||
{
|
||||
char debuf[50];
|
||||
sprintf(debuf, "%S: %U", str, n);
|
||||
rtlDebugOutString(debuf);
|
||||
}
|
||||
|
||||
|
||||
// function 64 шчьхэхэшх ъюышўхёЄтр ярь Єш, т√фхыхээющ фы яЁюуЁрьь√
|
||||
bool kos_ApplicationMemoryResize( Dword targetSize )
|
||||
{
|
||||
Dword result;
|
||||
|
||||
//
|
||||
__asm{
|
||||
mov eax, 64
|
||||
mov ebx, 1
|
||||
mov ecx, targetSize
|
||||
int 0x40
|
||||
mov result, eax
|
||||
}
|
||||
//
|
||||
return result == 0;
|
||||
}
|
||||
|
||||
|
||||
// function 67 шчьхэшЄ№ ярЁрьхЄЁ√ юъэр, ярЁрьхЄЁ == -1 эх ьхэ хЄё
|
||||
void kos_ChangeWindow( Dword x, Dword y, Dword sizeX, Dword sizeY )
|
||||
{
|
||||
//
|
||||
__asm{
|
||||
mov eax, 67
|
||||
mov ebx, x
|
||||
mov ecx, y
|
||||
mov edx, sizeX
|
||||
mov esi, sizeY
|
||||
int 0x40
|
||||
}
|
||||
}
|
||||
|
||||
// 68.11: init heap
|
||||
void kos_InitHeap()
|
||||
{
|
||||
__asm{
|
||||
mov eax, 68
|
||||
mov ebx, 11
|
||||
int 0x40
|
||||
}
|
||||
}
|
||||
|
||||
// function 70 фюёЄєя ъ Їрщыютющ ёшёЄхьх
|
||||
Dword kos_FileSystemAccess( kosFileInfo *fileInfo )
|
||||
{
|
||||
__asm{
|
||||
mov eax, 70
|
||||
mov ebx, fileInfo
|
||||
int 0x40
|
||||
}
|
||||
}
|
||||
|
||||
// 70.7: run Kolibri application with param
|
||||
int kos_AppRun(char* app_path, char* param)
|
||||
{
|
||||
kosFileInfo fileInfo;
|
||||
fileInfo.rwMode = 7;
|
||||
fileInfo.OffsetLow = 0;
|
||||
fileInfo.OffsetHigh = param;
|
||||
fileInfo.dataCount = 0;
|
||||
fileInfo.bufferPtr = 0;
|
||||
strcpy(fileInfo.fileURL, app_path);
|
||||
return kos_FileSystemAccess(&fileInfo);
|
||||
}
|
||||
|
||||
|
||||
// т√чют рсёЄЁръЄэюую ьхЄюфр
|
||||
int __cdecl _purecall()
|
||||
{
|
||||
rtlDebugOutString( pureCallMessage );
|
||||
kos_ExitApp();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// т√чют ёЄрЄшўхёъшї шэшЎшрышчрЄюЁют
|
||||
// чрюфэю шэшЎшрышчрЎш ухэхЁрЄюЁр ёыєўрщэ√ї ўшёхы
|
||||
//#pragma section(".CRT$XCA",long,read,write)
|
||||
//#pragma section(".CRT$XCZ",long,read,write)
|
||||
#pragma data_seg(".CRT$XCA")
|
||||
#pragma data_seg(".CRT$XCZ")
|
||||
typedef void (__cdecl *_PVFV)(void);
|
||||
//__declspec(allocate(".CRT$XCA")) _PVFV __xc_a[1] = { NULL };
|
||||
//__declspec(allocate(".CRT$XCZ")) _PVFV __xc_z[1] = { NULL };
|
||||
//
|
||||
extern void ALMOST_HALF_init();
|
||||
#pragma comment(linker, "/merge:.CRT=.rdata")
|
||||
//
|
||||
void crtStartUp()
|
||||
{
|
||||
#ifdef AUTOBUILD
|
||||
// linker will try to remove unused variables; force header to be included
|
||||
header.header;
|
||||
#endif
|
||||
// т√ч√трхь шэшЎшрышчрЄюЁ√ яю ёяшёъє, NULL'√ шуэюЁшЁєхь
|
||||
/*for ( _PVFV *pbegin = __xc_a; pbegin < __xc_z; pbegin++ )
|
||||
{
|
||||
//
|
||||
if ( *pbegin != NULL )
|
||||
(**pbegin)();
|
||||
}*/
|
||||
ALMOST_HALF_init();
|
||||
// шэшЎшрышчшЁєхь ухэхЁрЄюЁ ёыєўрщэ√ї ўшёхы
|
||||
rtlSrand( kos_GetSystemClock() );
|
||||
#ifndef AUTOBUILD
|
||||
// яєЄ№ ъ Їрщыє яЁюЎхёёр
|
||||
kosExePath = *((char **)0x20);
|
||||
#endif
|
||||
// т√чют уыртэющ ЇєэъЎшш яЁшыюцхэш
|
||||
kos_Main();
|
||||
// т√їюф
|
||||
kos_ExitApp();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,324 +0,0 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef unsigned __int32 Dword;
|
||||
typedef unsigned __int16 Word;
|
||||
typedef unsigned __int8 Byte;
|
||||
//typedef unsigned __int32 size_t;
|
||||
|
||||
#define NULL 0
|
||||
|
||||
#define MAX_PATH 256
|
||||
|
||||
#define FO_READ 0
|
||||
#define FO_WRITE 2
|
||||
|
||||
//Process Events
|
||||
#define EM_WINDOW_REDRAW 1
|
||||
#define EM_KEY_PRESS 2
|
||||
#define EM_BUTTON_CLICK 3
|
||||
#define EM_APP_CLOSE 4
|
||||
#define EM_DRAW_BACKGROUND 5
|
||||
#define EM_MOUSE_EVENT 6
|
||||
#define EM_IPC 7
|
||||
#define EM_NETWORK 8
|
||||
#define EM_DEBUG 9
|
||||
|
||||
//Event mask bits for function 40
|
||||
#define EVM_REDRAW 1
|
||||
#define EVM_KEY 2
|
||||
#define EVM_BUTTON 4
|
||||
#define EVM_EXIT 8
|
||||
#define EVM_BACKGROUND 16
|
||||
#define EVM_MOUSE 32
|
||||
#define EVM_IPC 64
|
||||
#define EVM_STACK 128
|
||||
#define EVM_DEBUG 256
|
||||
#define EVM_STACK2 512
|
||||
#define EVM_MOUSE_FILTER 0x80000000
|
||||
#define EVM_CURSOR_FILTER 0x40000000
|
||||
|
||||
//Button options
|
||||
#define BT_DEL 0x80000000
|
||||
#define BT_HIDE 0x40000000
|
||||
#define BT_NOFRAME 0x20000000
|
||||
#define BT_NODRAW BT_HIDE+BT_NOFRAME
|
||||
|
||||
#define KM_CHARS 0
|
||||
#define KM_SCANS 1
|
||||
|
||||
#define WRS_BEGIN 1
|
||||
#define WRS_END 2
|
||||
|
||||
#define PROCESS_ID_SELF -1
|
||||
|
||||
#define abs(a) (a<0?0-a:a)
|
||||
|
||||
extern "C" double __cdecl acos(double x);
|
||||
extern "C" double __cdecl asin(double x);
|
||||
extern "C" double __cdecl floor(double x);
|
||||
extern "C" double __cdecl round(double x);
|
||||
#pragma function(acos,asin)
|
||||
#if _MSC_VER > 1200
|
||||
#pragma function(floor)
|
||||
#endif
|
||||
|
||||
|
||||
struct kosFileInfo
|
||||
{
|
||||
Dword rwMode;
|
||||
Dword OffsetLow;
|
||||
char* OffsetHigh;
|
||||
Dword dataCount;
|
||||
Byte *bufferPtr;
|
||||
char fileURL[MAX_PATH];
|
||||
};
|
||||
|
||||
|
||||
struct kosSysColors {
|
||||
Dword nonset1;
|
||||
Dword nonset2;
|
||||
Dword work_dark;
|
||||
Dword work_light;
|
||||
Dword window_title;
|
||||
Dword work;
|
||||
Dword work_button;
|
||||
Dword work_button_text;
|
||||
Dword work_text;
|
||||
Dword work_graph;
|
||||
};
|
||||
|
||||
|
||||
struct RGB
|
||||
{
|
||||
Byte b;
|
||||
Byte g;
|
||||
Byte r;
|
||||
//
|
||||
RGB() {};
|
||||
//
|
||||
RGB( Dword value )
|
||||
{
|
||||
r = (Byte)(value >> 16);
|
||||
g = (Byte)(value >> 8);
|
||||
b = (Byte)value;
|
||||
};
|
||||
//
|
||||
bool operator != ( RGB &another )
|
||||
{
|
||||
return this->b != another.b || this->g != another.g || this->r != another.r;
|
||||
};
|
||||
//
|
||||
bool operator == ( RGB &another )
|
||||
{
|
||||
return this->b == another.b && this->g == another.g && this->r == another.r;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#pragma pack(push, 1)
|
||||
union sProcessInfo
|
||||
{
|
||||
Byte rawData[1024];
|
||||
struct
|
||||
{
|
||||
Dword cpu_usage;
|
||||
Word window_stack_position;
|
||||
Word window_slot; //slot
|
||||
Word reserved1;
|
||||
char process_name[12];
|
||||
Dword memory_start;
|
||||
Dword used_memory;
|
||||
Dword PID;
|
||||
Dword x_start;
|
||||
Dword y_start;
|
||||
Dword width;
|
||||
Dword height;
|
||||
Word slot_state;
|
||||
Word reserved3;
|
||||
Dword work_left;
|
||||
Dword work_top;
|
||||
Dword work_width;
|
||||
Dword work_height;
|
||||
char status_window;
|
||||
Dword cwidth;
|
||||
Dword cheight;
|
||||
} processInfo;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#ifndef AUTOBUILD
|
||||
//
|
||||
extern char *kosExePath;
|
||||
#endif
|
||||
|
||||
//
|
||||
void crtStartUp();
|
||||
//
|
||||
int __cdecl _purecall();
|
||||
//
|
||||
int __cdecl atexit( void (__cdecl *func )( void ));
|
||||
//
|
||||
void rtlSrand( Dword seed );
|
||||
Dword rtlRand( void );
|
||||
//
|
||||
char * __cdecl strcpy( char *target, const char *source );
|
||||
int __cdecl strlen( const char *line );
|
||||
char * __cdecl strrchr( const char * string, int c );
|
||||
//
|
||||
// if you have trouble here look at old SVN revisions for alternatives
|
||||
void memcpy( void *dst, const void *src, size_t bytesCount );
|
||||
void memset( Byte *dst, Byte filler, Dword count );
|
||||
//
|
||||
void sprintf( char *Str, char* Format, ... );
|
||||
//
|
||||
Dword rtlInterlockedExchange( Dword *target, Dword value );
|
||||
// function -1 чртхЁ°хэш яЁюЎхёёр
|
||||
void kos_ExitApp();
|
||||
// function 0
|
||||
void kos_DefineAndDrawWindow(
|
||||
Word x, Word y,
|
||||
Word sizeX, Word sizeY,
|
||||
Byte mainAreaType, Dword mainAreaColour,
|
||||
Byte headerType, Dword headerColour,
|
||||
Dword borderColour
|
||||
);
|
||||
// function 1 яюёЄртшЄ№ Єюўъє
|
||||
void kos_PutPixel( Dword x, Dword y, Dword colour );
|
||||
// function 2 яюыєўшЄ№ ъюф эрцрЄющ ъыртш°ш
|
||||
bool kos_GetKey( Byte &keyCode );
|
||||
bool kos_GetKeys( Dword &key_editbox, Byte &key_ascii, Byte &key_scancode );
|
||||
// function 3 яюыєўшЄ№ тЁхь
|
||||
Dword kos_GetSystemClock();
|
||||
// function 4
|
||||
void __declspec(noinline) kos_WriteTextToWindow(
|
||||
Word x, Word y,
|
||||
Byte fontType,
|
||||
Dword textColour,
|
||||
char *textPtr,
|
||||
Dword textLen
|
||||
);
|
||||
// function 7 эрЁшёютрЄ№ шчюсЁрцхэшх
|
||||
void kos_PutImage( RGB * imagePtr, Word sizeX, Word sizeY, Word x, Word y );
|
||||
// function 8 юяЁхфхышЄ№ ъэюяъє
|
||||
void __declspec(noinline) kos_DefineButton( Word x, Word y, Word sizeX, Word sizeY, Dword buttonID, Dword colour );
|
||||
//
|
||||
void __declspec(noinline) kos_UnsaveDefineButton( Word x, Word y, Word sizeX, Word sizeY, Dword buttonID, Dword colour );
|
||||
// function 5 ярєчр, т ёюЄ√ї фюы ї ёхъєэф√
|
||||
void kos_Pause( Dword value );
|
||||
// function 9 - шэЇюЁьрЎш ю яЁюЎхёёх
|
||||
Dword kos_ProcessInfo( sProcessInfo *targetPtr, Dword processID = PROCESS_ID_SELF );
|
||||
// function 10
|
||||
Dword kos_WaitForEvent();
|
||||
// function 11
|
||||
Dword kos_CheckForEvent();
|
||||
// function 12
|
||||
void kos_WindowRedrawStatus( Dword status );
|
||||
// function 13 эрЁшёютрЄ№ яюыюёє
|
||||
void __declspec(noinline) kos_DrawBar( Word x, Word y, Word sizeX, Word sizeY, Dword colour );
|
||||
// function 17
|
||||
bool kos_GetButtonID( Dword &buttonID );
|
||||
// function 23
|
||||
Dword kos_WaitForEventTimeout( Dword timeOut );
|
||||
//
|
||||
enum eNumberBase
|
||||
{
|
||||
nbDecimal = 0,
|
||||
nbHex,
|
||||
nbBin
|
||||
};
|
||||
// яюыєўхэшх шэЇюЁьрЎшш ю ёюёЄю эшш "ь√°ш" function 37
|
||||
void kos_GetMouseState( Dword & buttons, int & cursorX, int & cursorY );
|
||||
// function 38
|
||||
void kos_DrawLine( Word x1, Word y1, Word x2, Word y2, Dword colour, Dword invert );
|
||||
// function 40 єёЄрэютшЄ№ ьрёъє ёюс√Єшщ
|
||||
void kos_SetMaskForEvents( Dword mask );
|
||||
// function 47 т√тхёЄш т юъэю яЁшыюцхэш ўшёыю
|
||||
void kos_DisplayNumberToWindow(
|
||||
Dword value,
|
||||
Dword digitsNum,
|
||||
Word x,
|
||||
Word y,
|
||||
Dword colour,
|
||||
eNumberBase nBase = nbDecimal,
|
||||
bool valueIsPointer = false
|
||||
);
|
||||
// 48.3: get system colors
|
||||
bool kos_GetSystemColors( kosSysColors *sc );
|
||||
// function 63
|
||||
void kos_DebugOutChar( char ccc );
|
||||
//
|
||||
void rtlDebugOutString( char *str );
|
||||
//
|
||||
void kos_DebugValue(char *str, int n);
|
||||
// function 64 шчьхэшЄ№ ярЁрьхЄЁ√ юъэр, ярЁрьхЄЁ == -1 эх ьхэ хЄё
|
||||
void kos_ChangeWindow( Dword x, Dword y, Dword sizeX, Dword sizeY );
|
||||
// function 67 шчьхэхэшх ъюышўхёЄтр ярь Єш, т√фхыхээющ фы яЁюуЁрьь√
|
||||
bool kos_ApplicationMemoryResize( Dword targetSize );
|
||||
// function 66 Ёхцшь яюыєўхэш фрээ√ї юЄ ъыртшрЄєЁ√
|
||||
void kos_SetKeyboardDataMode( Dword mode );
|
||||
// 68.11: init heap
|
||||
void kos_InitHeap();
|
||||
// function 70 фюёЄєя ъ Їрщыютющ ёшёЄхьх
|
||||
Dword kos_FileSystemAccess( kosFileInfo *fileInfo );
|
||||
// 70.7: run Kolibri application with param
|
||||
int kos_AppRun(char* app_path, char* param);
|
||||
//
|
||||
void kos_Main();
|
||||
|
||||
//SCAN CODE KEYS
|
||||
#define SCAN_CODE_BS 14
|
||||
#define SCAN_CODE_TAB 15
|
||||
#define SCAN_CODE_ENTER 28
|
||||
#define SCAN_CODE_ESC 1
|
||||
#define SCAN_CODE_DEL 83
|
||||
#define SCAN_CODE_INS 82
|
||||
#define SCAN_CODE_SPACE 57
|
||||
#define SCAN_CODE_MENU 93
|
||||
|
||||
#define SCAN_CODE_LEFT 75
|
||||
#define SCAN_CODE_RIGHT 77
|
||||
#define SCAN_CODE_DOWN 80
|
||||
#define SCAN_CODE_UP 72
|
||||
#define SCAN_CODE_HOME 71
|
||||
#define SCAN_CODE_END 79
|
||||
#define SCAN_CODE_PGDN 81
|
||||
#define SCAN_CODE_PGUP 73
|
||||
|
||||
#define SCAN_CODE_MINUS 12
|
||||
#define SCAN_CODE_PLUS 13
|
||||
|
||||
#define SCAN_CODE_F1 59
|
||||
#define SCAN_CODE_F2 60
|
||||
#define SCAN_CODE_F3 61
|
||||
#define SCAN_CODE_F4 62
|
||||
#define SCAN_CODE_F5 63
|
||||
#define SCAN_CODE_F6 64
|
||||
#define SCAN_CODE_F7 65
|
||||
#define SCAN_CODE_F8 66
|
||||
#define SCAN_CODE_F9 67
|
||||
#define SCAN_CODE_F10 68
|
||||
#define SCAN_CODE_F11 87
|
||||
#define SCAN_CODE_F12 88
|
||||
|
||||
#define SCAN_CODE_KEY_A 30
|
||||
#define SCAN_CODE_KEY_B 48
|
||||
#define SCAN_CODE_KEY_C 46
|
||||
#define SCAN_CODE_KEY_D 32
|
||||
#define SCAN_CODE_KEY_E 18
|
||||
#define SCAN_CODE_KEY_F 33
|
||||
#define SCAN_CODE_KEY_H 35
|
||||
#define SCAN_CODE_KEY_I 23
|
||||
#define SCAN_CODE_KEY_L 38
|
||||
#define SCAN_CODE_KEY_M 50
|
||||
#define SCAN_CODE_KEY_N 49
|
||||
#define SCAN_CODE_KEY_O 24
|
||||
#define SCAN_CODE_KEY_P 25
|
||||
#define SCAN_CODE_KEY_R 19
|
||||
#define SCAN_CODE_KEY_S 31
|
||||
#define SCAN_CODE_KEY_T 20
|
||||
#define SCAN_CODE_KEY_U 22
|
||||
#define SCAN_CODE_KEY_V 47
|
||||
#define SCAN_CODE_KEY_X 45
|
||||
#define SCAN_CODE_KEY_Y 21
|
||||
#define SCAN_CODE_KEY_Z 44
|
||||
@@ -1,84 +0,0 @@
|
||||
#include <math.h>
|
||||
#include "kosSyst.h"
|
||||
extern "C" int _fltused = 0;
|
||||
double __cdecl acos(double x)
|
||||
{
|
||||
__asm {
|
||||
fld qword ptr [esp+4]
|
||||
fld1
|
||||
fadd st, st(1)
|
||||
fld1
|
||||
fsub st, st(2)
|
||||
fmulp st(1), st
|
||||
fsqrt
|
||||
fxch st(1)
|
||||
fpatan
|
||||
}
|
||||
}
|
||||
double __cdecl asin(double x)
|
||||
{
|
||||
__asm {
|
||||
fld qword ptr [esp+4]
|
||||
fld1
|
||||
fadd st, st(1)
|
||||
fld1
|
||||
fsub st, st(2)
|
||||
fmulp st(1), st
|
||||
fsqrt
|
||||
fpatan
|
||||
ret
|
||||
}
|
||||
}
|
||||
#if _MSC_VER <= 1200
|
||||
extern "C" double _ftol(double x)
|
||||
{
|
||||
__asm {
|
||||
fld qword ptr [esp+4]
|
||||
push 1F3Fh
|
||||
fstcw word ptr [esp+2]
|
||||
fldcw word ptr [esp]
|
||||
frndint
|
||||
fldcw word ptr [esp+2]
|
||||
add esp, 4
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#pragma function(ceil)
|
||||
double __cdecl ceil(double x)
|
||||
{
|
||||
__asm {
|
||||
fld qword ptr [esp+4]
|
||||
push 1B3Fh
|
||||
fstcw word ptr [esp+2]
|
||||
fldcw word ptr [esp]
|
||||
frndint
|
||||
fldcw word ptr [esp+2]
|
||||
add esp, 4
|
||||
}
|
||||
}
|
||||
|
||||
double __cdecl floor(double x)
|
||||
{
|
||||
__asm {
|
||||
fld qword ptr [esp+4]
|
||||
push 173Fh
|
||||
fstcw word ptr [esp+2]
|
||||
fldcw word ptr [esp]
|
||||
frndint
|
||||
fldcw word ptr [esp+2]
|
||||
add esp, 4
|
||||
}
|
||||
}
|
||||
|
||||
double __cdecl round(double x)
|
||||
{
|
||||
__asm {
|
||||
fld qword ptr [esp+4]
|
||||
push 133Fh
|
||||
fstcw word ptr [esp+2]
|
||||
fldcw word ptr [esp]
|
||||
frndint
|
||||
fldcw word ptr [esp+2]
|
||||
add esp, 4
|
||||
}
|
||||
}
|
||||
@@ -1,354 +0,0 @@
|
||||
// memman.cpp : Defines the entry point for the console application.
|
||||
//
|
||||
|
||||
#include "kosSyst.h"
|
||||
#include "mcsmemm.h"
|
||||
|
||||
|
||||
void * __cdecl operator new ( size_t count, size_t element_size )
|
||||
{
|
||||
return allocmem( (Dword)(count * element_size) );
|
||||
}
|
||||
|
||||
void * __cdecl operator new [] ( size_t amount )
|
||||
{
|
||||
return allocmem( (Dword)amount );
|
||||
}
|
||||
|
||||
void * __cdecl operator new ( size_t amount )
|
||||
{
|
||||
return allocmem( (Dword)amount );
|
||||
}
|
||||
|
||||
void __cdecl operator delete ( void *pointer )
|
||||
{
|
||||
if ( pointer != NULL ) freemem( pointer );
|
||||
}
|
||||
|
||||
void __cdecl operator delete [] ( void *pointer )
|
||||
{
|
||||
if ( pointer != NULL ) freemem( pointer );
|
||||
}
|
||||
|
||||
Byte *allocmem( Dword reqsize )
|
||||
{
|
||||
__asm
|
||||
{
|
||||
mov eax, 68
|
||||
mov ebx, 12
|
||||
mov ecx, reqsize
|
||||
int 0x40
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Dword freemem( void *vaddress )
|
||||
{
|
||||
__asm
|
||||
{
|
||||
mov eax, 68
|
||||
mov ebx, 13
|
||||
mov ecx, vaddress
|
||||
int 0x40
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
|
||||
//
|
||||
Dword mmMutex = FALSE;
|
||||
MemBlock *rootfree = NULL;
|
||||
MemBlock *rootuser = NULL;
|
||||
bool mmInitialized = false;
|
||||
Byte *mmHeapTop = NULL;
|
||||
|
||||
|
||||
//
|
||||
Byte * AllocMemFromSystem( Dword reqSize )
|
||||
{
|
||||
Byte *result;
|
||||
sProcessInfo pInfo;
|
||||
|
||||
//
|
||||
if ( mmInitialized )
|
||||
{
|
||||
result = mmHeapTop;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
kos_ProcessInfo( &pInfo );
|
||||
//
|
||||
result = (Byte *)(pInfo.processInfo.used_memory + 1);
|
||||
//
|
||||
mmInitialized = true;
|
||||
}
|
||||
//
|
||||
if ( ! kos_ApplicationMemoryResize( ((Dword)result) + reqSize ) )
|
||||
{
|
||||
result = NULL;
|
||||
}
|
||||
//
|
||||
mmHeapTop = result + reqSize;
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
Byte *allocmem( Dword reqsize )
|
||||
{
|
||||
MemBlock *BlockForCheck;
|
||||
MemBlock *LastKnownGood;
|
||||
Dword tail;
|
||||
Byte *address;
|
||||
|
||||
//яюфЁютэ хь ЁрчьхЁ
|
||||
if( ( tail = reqsize % SIZE_ALIGN ) != 0 )
|
||||
{
|
||||
reqsize += SIZE_ALIGN - tail;
|
||||
}
|
||||
|
||||
LastKnownGood = NULL;
|
||||
|
||||
// цф╕ь юётюсюцфхэш ь№■Єхъёр
|
||||
while ( rtlInterlockedExchange( &mmMutex, TRUE ) )
|
||||
{
|
||||
//
|
||||
kos_Pause( 1 );
|
||||
}
|
||||
|
||||
//ш∙хь яюфїюф ∙шщ ётюсюфэ√щ сыюъ
|
||||
if( rootfree != NULL )
|
||||
{
|
||||
for ( BlockForCheck = rootfree; ; BlockForCheck = BlockForCheck->Next )
|
||||
{
|
||||
if ( BlockForCheck->Size >= reqsize )
|
||||
{
|
||||
//эр°ыш
|
||||
if ( LastKnownGood != NULL )
|
||||
{
|
||||
if ( LastKnownGood->Size >= BlockForCheck->Size )
|
||||
LastKnownGood = BlockForCheck;
|
||||
}
|
||||
else
|
||||
LastKnownGood = BlockForCheck;
|
||||
if ( LastKnownGood->Size == reqsize )
|
||||
break;
|
||||
}
|
||||
if ( BlockForCheck->Next == NULL )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( LastKnownGood != NULL )
|
||||
{
|
||||
//яЁютхЁшь эрщфхээ√щ сыюъ эр тючьюцэюёЄ№ фхыхэш
|
||||
tail = LastKnownGood->Size - reqsize;
|
||||
if ( tail >= ( sizeof(MemBlock) + SIZE_ALIGN ) )
|
||||
{
|
||||
//сєфхь ЁрчсштрЄ№
|
||||
BlockForCheck = (MemBlock *)( ( (Byte *)LastKnownGood ) + tail );
|
||||
BlockForCheck->Size = reqsize;
|
||||
//тёЄртшь чрэ Є√щ сыюъ т эрўрыю ёяшёър чрэрЄ√ї сыюъют
|
||||
if( rootuser != NULL )
|
||||
{
|
||||
BlockForCheck->Next = rootuser;
|
||||
rootuser->Previous = BlockForCheck;
|
||||
BlockForCheck->Previous = NULL;
|
||||
rootuser = BlockForCheck;
|
||||
}
|
||||
else
|
||||
{
|
||||
rootuser = BlockForCheck;
|
||||
BlockForCheck->Next = NULL;
|
||||
BlockForCheck->Previous = NULL;
|
||||
}
|
||||
|
||||
//шчьхэшь ЁрчьхЁ юёЄрт°хщё ўрёЄш
|
||||
LastKnownGood->Size = tail - sizeof(MemBlock);
|
||||
address = ( (Byte *)BlockForCheck ) + sizeof(MemBlock);
|
||||
|
||||
// юЄяєёЄшь ь№■Єхъё
|
||||
rtlInterlockedExchange( &mmMutex, FALSE );
|
||||
|
||||
return address;
|
||||
}
|
||||
else
|
||||
{
|
||||
//яхЁхьхёЄш сыюъ шч юўхЁхфш ётюсюфэ√ї т эрўрыю юўхЁхфш чрэ Є√ї
|
||||
//ёэрўрыр т√ъшэхь хую шч юўхЁхфш ётюсюфэ√ї
|
||||
if ( LastKnownGood->Previous != NULL )
|
||||
{
|
||||
LastKnownGood->Previous->Next = LastKnownGood->Next;
|
||||
}
|
||||
else
|
||||
{
|
||||
//сыюъ ёЄюшЄ т эрўрых юўхЁхфш
|
||||
rootfree = LastKnownGood->Next;
|
||||
}
|
||||
if( LastKnownGood->Next != NULL )
|
||||
{
|
||||
LastKnownGood->Next->Previous = LastKnownGood->Previous;
|
||||
}
|
||||
//ЄхяхЁ№ тёЄртшь хую т юўхЁхф№ чрэ Є√ї
|
||||
if( rootuser != NULL )
|
||||
{
|
||||
LastKnownGood->Next = rootuser;
|
||||
rootuser->Previous = LastKnownGood;
|
||||
LastKnownGood->Previous = NULL;
|
||||
rootuser = LastKnownGood;
|
||||
}
|
||||
else
|
||||
{
|
||||
rootuser = LastKnownGood;
|
||||
LastKnownGood->Next = NULL;
|
||||
LastKnownGood->Previous = NULL;
|
||||
}
|
||||
//
|
||||
address = ( (Byte *)LastKnownGood ) + sizeof(MemBlock);
|
||||
|
||||
// юЄяєёЄшь ь№■Єхъё
|
||||
rtlInterlockedExchange( &mmMutex, FALSE );
|
||||
|
||||
return address;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//эрфю яюыєўшЄ№ х∙╕ ъєёюўхъ ярь Єш
|
||||
LastKnownGood = (MemBlock *)AllocMemFromSystem( reqsize + sizeof(MemBlock) );
|
||||
//
|
||||
if( LastKnownGood != NULL )
|
||||
{
|
||||
LastKnownGood->Size = reqsize;
|
||||
//ЄхяхЁ№ тёЄртшь хую т юўхЁхф№ чрэ Є√ї
|
||||
if( rootuser != NULL )
|
||||
{
|
||||
LastKnownGood->Next = rootuser;
|
||||
rootuser->Previous = LastKnownGood;
|
||||
LastKnownGood->Previous = NULL;
|
||||
rootuser = LastKnownGood;
|
||||
}
|
||||
else
|
||||
{
|
||||
rootuser = LastKnownGood;
|
||||
LastKnownGood->Next = NULL;
|
||||
LastKnownGood->Previous = NULL;
|
||||
}
|
||||
address = ( (Byte *)LastKnownGood ) + sizeof(MemBlock);
|
||||
|
||||
// юЄяєёЄшь ь№■Єхъё
|
||||
rtlInterlockedExchange( &mmMutex, FALSE );
|
||||
|
||||
return address;
|
||||
}
|
||||
}
|
||||
|
||||
// юЄяєёЄшь ь№■Єхъё
|
||||
rtlInterlockedExchange( &mmMutex, FALSE );
|
||||
|
||||
//
|
||||
rtlDebugOutString( "allocmem failed." );
|
||||
kos_ExitApp();
|
||||
//
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
Dword freemem( void *vaddress )
|
||||
{
|
||||
Dword result;
|
||||
|
||||
Byte *checknext, *address = (Byte *)vaddress;
|
||||
|
||||
// цф╕ь юётюсюцфхэш ь№■Єхъёр
|
||||
while ( rtlInterlockedExchange( &mmMutex, TRUE ) )
|
||||
{
|
||||
//
|
||||
kos_Pause( 1 );
|
||||
}
|
||||
|
||||
MemBlock *released = (MemBlock *)( address - sizeof(MemBlock) );
|
||||
|
||||
result = released->Size;
|
||||
|
||||
//єсшЁрхь сыюъ шч ёяшёър чрэ Є√ї
|
||||
if ( released->Previous != NULL )
|
||||
{
|
||||
released->Previous->Next = released->Next;
|
||||
}
|
||||
else
|
||||
{
|
||||
rootuser = released->Next;
|
||||
}
|
||||
if ( released->Next != NULL )
|
||||
{
|
||||
released->Next->Previous = released->Previous;
|
||||
}
|
||||
//чръшэхь ЄхяхЁ№ ¤ЄюЄ сыюъ т ёяшёюъ ётюсюфэ√ї
|
||||
released->Next = rootfree;
|
||||
released->Previous = NULL;
|
||||
rootfree = released;
|
||||
if ( released->Next != NULL )
|
||||
{
|
||||
released->Next->Previous = released;
|
||||
}
|
||||
|
||||
//ЄхяхЁ№ яюш∙хь ёьхцэ√х ётюсюфэ√х сыюъш
|
||||
checknext = (Byte *)(rootfree) + ( rootfree->Size + sizeof(MemBlock) );
|
||||
//
|
||||
for ( released = rootfree->Next; released != NULL; released = released->Next )
|
||||
{
|
||||
if ( checknext == (Byte *)released )
|
||||
{
|
||||
//ёюсшЁрхь сыюъш тьхёЄх
|
||||
//ёэрўрыр т√ъшэхь шч юўхЁхфш ётюсюфэ√ї
|
||||
released->Previous->Next = released->Next;
|
||||
if( released->Next != NULL )
|
||||
{
|
||||
released->Next->Previous = released->Previous;
|
||||
}
|
||||
//ЄхяхЁ№ єтхышўшь ЁрчьхЁ ъюЁэхтюую сыюър
|
||||
rootfree->Size += released->Size + sizeof(MemBlock);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//хёыш эрфю, яюш∙хь сыюъш яхЁхф Єхъ∙шь.
|
||||
checknext = (Byte *)(rootfree);
|
||||
//
|
||||
if ( released == NULL )
|
||||
{
|
||||
for ( released = rootfree->Next; released != NULL; released = released->Next )
|
||||
{
|
||||
if ( checknext == (Byte *)released + ( released->Size + sizeof(MemBlock) ) )
|
||||
{
|
||||
//ёюсшЁрхь сыюъш тьхёЄх
|
||||
//єтхышўшь ЁрчьхЁ сыюър
|
||||
released->Size += rootfree->Size + sizeof(MemBlock);
|
||||
//ЄхяхЁ№ т√ъшэхь шч юўхЁхфш ётюсюфэ√ї
|
||||
released->Previous->Next = released->Next;
|
||||
if ( released->Next != NULL )
|
||||
{
|
||||
released->Next->Previous = released->Previous;
|
||||
}
|
||||
//ш чръшэхь хую т эрўрыю юўхЁхфш тьхёЄю яЁшёюхфшэ╕ээюую сыюър шч ъюЁэ ёяшёър
|
||||
if ( rootfree->Next != NULL )
|
||||
{
|
||||
rootfree->Next->Previous = released;
|
||||
}
|
||||
released->Next = rootfree->Next;
|
||||
released->Previous = NULL;
|
||||
rootfree = released;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// юЄяєёЄшь ь№■Єхъё
|
||||
rtlInterlockedExchange( &mmMutex, FALSE );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,716 @@
|
||||
#include "parser.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// set by convert(): 0 ok, ERROR bad char, ERROR_END empty/no number
|
||||
int convert_error = 0;
|
||||
|
||||
// parse a leading number; accepts '.' or ',' as the decimal point and stores
|
||||
// the count of consumed characters in *len when non-NULL
|
||||
double convert(char *s, int *len)
|
||||
{
|
||||
int i = 0;
|
||||
double sign, res = 0.0, tail, div;
|
||||
|
||||
convert_error = 0;
|
||||
|
||||
while (s[i] && isspace((unsigned char)s[i]))
|
||||
i++;
|
||||
if (len)
|
||||
*len = i;
|
||||
if (s[i] == '\0') {
|
||||
convert_error = ERROR_END;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
sign = 1.0;
|
||||
if (s[i] == '-') {
|
||||
sign = -1.0;
|
||||
i++;
|
||||
}
|
||||
|
||||
while (s[i] >= '0' && s[i] <= '9') {
|
||||
res = res * 10.0 + (double)(s[i] - '0');
|
||||
i++;
|
||||
}
|
||||
if (len)
|
||||
*len = i;
|
||||
if (!s[i] || isspace((unsigned char)s[i]))
|
||||
return sign * res;
|
||||
if (s[i] != '.' && s[i] != ',') {
|
||||
convert_error = ERROR;
|
||||
return 0;
|
||||
}
|
||||
i++;
|
||||
if (len)
|
||||
*len = i;
|
||||
if (!s[i])
|
||||
return sign * res;
|
||||
|
||||
div = 1.0;
|
||||
tail = 0.0;
|
||||
while (s[i] >= '0' && s[i] <= '9') {
|
||||
tail = tail * 10.0 + (double)(s[i] - '0');
|
||||
div *= 10.0;
|
||||
i++;
|
||||
}
|
||||
res += tail / div;
|
||||
if (len)
|
||||
*len = i;
|
||||
return sign * res;
|
||||
}
|
||||
|
||||
// token types
|
||||
#define DELIMITER 1
|
||||
#define VARIABLE 2
|
||||
#define NUMBER 3
|
||||
#define FUNCTION 4
|
||||
|
||||
static double epsilon = 1e-6;
|
||||
|
||||
// parser state
|
||||
static char token[80];
|
||||
static int token_type;
|
||||
static char *prog;
|
||||
static int code; // error code
|
||||
|
||||
variable_callback *find_var;
|
||||
|
||||
typedef struct double_list {
|
||||
double val;
|
||||
int code; // error code of this argument
|
||||
struct double_list *next;
|
||||
} double_list;
|
||||
|
||||
// forward declarations for the internal recursive-descent evaluator
|
||||
static int get_token(void);
|
||||
static int look_up(char *s);
|
||||
static void level1(double *hold);
|
||||
static void level1_5(double *hold);
|
||||
static void level2(double *hold);
|
||||
static void level3(double *hold);
|
||||
static void level4(double *hold);
|
||||
static void level5(double *hold);
|
||||
static void level6(double *hold);
|
||||
static void primitive(double *hold);
|
||||
static void calc_function(double *hold);
|
||||
static void arith(char op, double *r, double *h);
|
||||
static void logic(char *op, double *r, double *h);
|
||||
static void unary(char op, double *r);
|
||||
static void putback(void);
|
||||
static int isdelim(char c);
|
||||
static int iswhite(char c);
|
||||
|
||||
/* ===== math functions exposed to formulas ===== */
|
||||
|
||||
// division that flags overflow when the divisor is ~0
|
||||
static double safediv(double num, double den)
|
||||
{
|
||||
if (fabs(den) < epsilon) {
|
||||
serror(ERR_OVERFLOW);
|
||||
return 0.0;
|
||||
}
|
||||
return num / den;
|
||||
}
|
||||
|
||||
static double tg(double d)
|
||||
{
|
||||
return safediv(sin(d), cos(d));
|
||||
}
|
||||
|
||||
static double ctg(double d)
|
||||
{
|
||||
return safediv(cos(d), sin(d));
|
||||
}
|
||||
|
||||
// log with a domain check (libc log would return -inf)
|
||||
static double f_log(double x)
|
||||
{
|
||||
if (x <= 0) {
|
||||
serror(ERR_OVERFLOW);
|
||||
return 0.0;
|
||||
}
|
||||
return log(x);
|
||||
}
|
||||
|
||||
// sqrt with a domain check (libc sqrt would return nan)
|
||||
static double f_sqrt(double x)
|
||||
{
|
||||
if (x < 0) {
|
||||
serror(ERR_BADPARAM);
|
||||
return 0.0;
|
||||
}
|
||||
return sqrt(x);
|
||||
}
|
||||
|
||||
static double func_pi(void)
|
||||
{
|
||||
return M_PI;
|
||||
}
|
||||
|
||||
static double func_eps(void)
|
||||
{
|
||||
return epsilon;
|
||||
}
|
||||
|
||||
static double func_if(double_list *p)
|
||||
{
|
||||
double_list *a, *b, *c;
|
||||
if (!p) {
|
||||
serror(ERR_BADPARAM);
|
||||
return 0.0;
|
||||
}
|
||||
a = p;
|
||||
b = a->next;
|
||||
if (!b) {
|
||||
serror(ERR_BADPARAM);
|
||||
return 0.0;
|
||||
}
|
||||
c = b->next;
|
||||
if (!c || c->next) {
|
||||
serror(ERR_BADPARAM);
|
||||
return 0.0;
|
||||
}
|
||||
if (a->val != 0.0) {
|
||||
if (b->code)
|
||||
code = b->code;
|
||||
return b->val;
|
||||
} else {
|
||||
if (c->code)
|
||||
code = c->code;
|
||||
return c->val;
|
||||
}
|
||||
}
|
||||
|
||||
static double sum(double_list *p)
|
||||
{
|
||||
double res = 0.0;
|
||||
while (p) {
|
||||
res += p->val;
|
||||
if (p->code)
|
||||
code = p->code;
|
||||
p = p->next;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// shared reducer for min()/max()
|
||||
static double minmax(double_list *p, int want_max)
|
||||
{
|
||||
double res;
|
||||
if (!p) {
|
||||
serror(ERR_BADPARAM);
|
||||
return 0.0;
|
||||
}
|
||||
res = p->val;
|
||||
for (p = p->next; p; p = p->next) {
|
||||
if (p->code)
|
||||
code = p->code;
|
||||
if (want_max ? p->val > res : p->val < res)
|
||||
res = p->val;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static double func_min(double_list *p)
|
||||
{
|
||||
return minmax(p, 0);
|
||||
}
|
||||
|
||||
static double func_max(double_list *p)
|
||||
{
|
||||
return minmax(p, 1);
|
||||
}
|
||||
|
||||
static double avg(double_list *p)
|
||||
{
|
||||
double res = 0.0;
|
||||
int count = 0;
|
||||
while (p) {
|
||||
if (p->code)
|
||||
code = p->code;
|
||||
res += p->val;
|
||||
count++;
|
||||
p = p->next;
|
||||
}
|
||||
if (count == 0)
|
||||
return 0.0;
|
||||
return res / count;
|
||||
}
|
||||
|
||||
static double func_isnull(char *str)
|
||||
{
|
||||
int c;
|
||||
if (code != 0)
|
||||
return 0.0;
|
||||
find_var(str); // called for its side effect on 'code'
|
||||
c = code;
|
||||
code = 0;
|
||||
return c != 0 ? 1.0 : 0.0;
|
||||
}
|
||||
|
||||
static double logic_xor(double a, double b)
|
||||
{
|
||||
if (a == 0.0)
|
||||
return (b == 0.0) ? 0.0 : 1.0;
|
||||
return (b == 0.0) ? 1.0 : 0.0;
|
||||
}
|
||||
|
||||
static double logic_and(double a, double b)
|
||||
{
|
||||
if (a == 0.0)
|
||||
return 0.0;
|
||||
return (b == 0.0) ? 0.0 : 1.0;
|
||||
}
|
||||
|
||||
static double logic_or(double a, double b)
|
||||
{
|
||||
if (a == 0.0)
|
||||
return (b == 0.0) ? 0.0 : 1.0;
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
static double rand_seed;
|
||||
static double func_rand(double max)
|
||||
{
|
||||
double q = (257.0 * rand_seed + 739.0);
|
||||
rand_seed = q - 65536.0 * floor(q / 65536.0);
|
||||
if (max == 0.0)
|
||||
return 0.0;
|
||||
return q - max * floor(q / max);
|
||||
}
|
||||
|
||||
#define INF_ARGS -1
|
||||
#define STR_ARG -2
|
||||
|
||||
// pointer flavours for the different function arities
|
||||
typedef double (*matfunc0)(void);
|
||||
typedef double (*matfunc)(double);
|
||||
typedef double (*matfunc2)(double, double);
|
||||
typedef double (*matfunc_inf)(double_list *);
|
||||
typedef double (*matfunc_str)(char *);
|
||||
|
||||
// links a function name to its implementation
|
||||
typedef struct {
|
||||
char name[10];
|
||||
int args;
|
||||
void *f;
|
||||
} func;
|
||||
|
||||
#define MAX_FUNC 28
|
||||
static const func functions[MAX_FUNC] = {
|
||||
{ "", 1, NULL }, // empty name marks "not found"
|
||||
{ "sin", 1, &sin },
|
||||
{ "cos", 1, &cos },
|
||||
{ "exp", 1, &exp },
|
||||
{ "sqrt", 1, &f_sqrt },
|
||||
{ "log", 1, &f_log },
|
||||
{ "tg", 1, &tg },
|
||||
{ "ctg", 1, &ctg },
|
||||
{ "arcsin", 1, &asin },
|
||||
{ "arccos", 1, &acos },
|
||||
{ "arctg", 1, &atan },
|
||||
{ "abs", 1, &fabs },
|
||||
{ "pow", 2, &pow },
|
||||
{ "if", INF_ARGS, &func_if },
|
||||
{ "sum", INF_ARGS, &sum },
|
||||
{ "isnull", STR_ARG, &func_isnull },
|
||||
{ "min", INF_ARGS, &func_min },
|
||||
{ "max", INF_ARGS, &func_max },
|
||||
{ "avg", INF_ARGS, &avg },
|
||||
{ "ceil", 1, &ceil },
|
||||
{ "round", 1, &round },
|
||||
{ "floor", 1, &floor },
|
||||
{ "and", 2, &logic_and },
|
||||
{ "or", 2, &logic_or },
|
||||
{ "xor", 2, &logic_xor },
|
||||
{ "rand", 1, &func_rand },
|
||||
{ "pi", 0, &func_pi },
|
||||
{ "eps", 0, &func_eps }
|
||||
};
|
||||
|
||||
#define MAXDELIM 17
|
||||
static const char delim[MAXDELIM] = "+-*^/%=;(),><#! ";
|
||||
|
||||
static int isdelim(char c)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < MAXDELIM; i++)
|
||||
if (c == delim[i])
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int isdigit2(char c)
|
||||
{
|
||||
return (c >= '0' && c <= '9');
|
||||
}
|
||||
|
||||
int isalpha2(char c)
|
||||
{
|
||||
return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '$'));
|
||||
}
|
||||
|
||||
static int iswhite(char c)
|
||||
{
|
||||
return (c == ' ' || c == '\t');
|
||||
}
|
||||
|
||||
void serror(int acode)
|
||||
{
|
||||
if (acode != 0)
|
||||
code = acode;
|
||||
}
|
||||
|
||||
void set_exp(char *exp)
|
||||
{
|
||||
prog = exp;
|
||||
}
|
||||
|
||||
static int get_token(void)
|
||||
{
|
||||
char *temp;
|
||||
token_type = 0;
|
||||
temp = token;
|
||||
|
||||
if (*prog == '\0') {
|
||||
*token = 0;
|
||||
return (token_type = DELIMITER);
|
||||
}
|
||||
while (iswhite(*prog))
|
||||
++prog;
|
||||
if (isdelim(*prog)) {
|
||||
char t = *temp = *prog;
|
||||
prog++;
|
||||
temp++;
|
||||
if ((t == '>' || t == '<' || t == '!') && (*prog) && (*prog == '=')) {
|
||||
*temp = *prog;
|
||||
prog++;
|
||||
temp++;
|
||||
}
|
||||
*temp = 0;
|
||||
return (token_type = DELIMITER);
|
||||
}
|
||||
if (isdigit2(*prog)) {
|
||||
while (!isdelim(*prog))
|
||||
*temp++ = *prog++;
|
||||
*temp = '\0';
|
||||
return (token_type = NUMBER);
|
||||
}
|
||||
if (isalpha2(*prog)) {
|
||||
while (!isdelim(*prog))
|
||||
*temp++ = *prog++;
|
||||
token_type = VARIABLE;
|
||||
}
|
||||
*temp = '\0';
|
||||
if (token_type == VARIABLE) {
|
||||
if (look_up(token))
|
||||
token_type = FUNCTION;
|
||||
}
|
||||
return token_type;
|
||||
}
|
||||
|
||||
static void putback(void)
|
||||
{
|
||||
char *t;
|
||||
t = token;
|
||||
for (; *t; t++)
|
||||
prog--;
|
||||
}
|
||||
|
||||
int get_exp(double *hold)
|
||||
{
|
||||
code = 0;
|
||||
|
||||
get_token();
|
||||
if (!*token)
|
||||
return 0;
|
||||
level1(hold);
|
||||
putback();
|
||||
return code == 0;
|
||||
}
|
||||
|
||||
static void level1(double *hold)
|
||||
{
|
||||
char op[2];
|
||||
double h;
|
||||
|
||||
level1_5(hold);
|
||||
while (op[0] = *token, op[1] = (*(token + 1)) ? *(token + 1) : 0,
|
||||
*op == '<' || *op == '>' || *op == '=' || *op == '#' || *op == '!') {
|
||||
get_token();
|
||||
level1_5(&h);
|
||||
logic(op, hold, &h);
|
||||
}
|
||||
}
|
||||
|
||||
static void level1_5(double *hold)
|
||||
{
|
||||
char op;
|
||||
|
||||
op = 0;
|
||||
if ((token_type == DELIMITER) && *token == '!') {
|
||||
op = *token;
|
||||
get_token();
|
||||
}
|
||||
level2(hold);
|
||||
|
||||
if (op)
|
||||
*hold = (*hold == 0.0) ? 1.0 : 0.0;
|
||||
}
|
||||
|
||||
static void level2(double *hold)
|
||||
{
|
||||
char op;
|
||||
double h;
|
||||
|
||||
level3(hold);
|
||||
while ((op = *token) == '+' || op == '-') {
|
||||
get_token();
|
||||
level3(&h);
|
||||
arith(op, hold, &h);
|
||||
}
|
||||
}
|
||||
|
||||
static void level3(double *hold)
|
||||
{
|
||||
char op;
|
||||
double h;
|
||||
|
||||
level4(hold);
|
||||
while ((op = *token) == '*' || op == '/' || op == '%') {
|
||||
get_token();
|
||||
level4(&h);
|
||||
arith(op, hold, &h);
|
||||
}
|
||||
}
|
||||
|
||||
static void level4(double *hold)
|
||||
{
|
||||
double h;
|
||||
level5(hold);
|
||||
|
||||
if (*token == '^') {
|
||||
get_token();
|
||||
level5(&h);
|
||||
arith('^', hold, &h);
|
||||
}
|
||||
}
|
||||
|
||||
static void level5(double *hold)
|
||||
{
|
||||
char op;
|
||||
|
||||
op = 0;
|
||||
if ((token_type == DELIMITER) && (*token == '+' || *token == '-')) {
|
||||
op = *token;
|
||||
get_token();
|
||||
}
|
||||
level6(hold);
|
||||
|
||||
if (op)
|
||||
unary(op, hold);
|
||||
}
|
||||
|
||||
static void level6(double *hold)
|
||||
{
|
||||
if ((*token == '(') && (token_type == DELIMITER)) {
|
||||
get_token();
|
||||
level1(hold);
|
||||
if (*token != ')')
|
||||
serror(ERR_NOBRACKET);
|
||||
get_token();
|
||||
} else
|
||||
primitive(hold);
|
||||
}
|
||||
|
||||
static void calc_function(double *hold)
|
||||
{
|
||||
double_list *args = NULL, *last = NULL, *t;
|
||||
double d = 0.0; // stays 0 on the arg-count-mismatch path
|
||||
int i, argc = 0, save_code;
|
||||
|
||||
save_code = code;
|
||||
code = 0;
|
||||
i = look_up(token);
|
||||
|
||||
if (i == 0)
|
||||
serror(ERR_BADFUNCTION);
|
||||
|
||||
get_token();
|
||||
if (*token != '(')
|
||||
serror(ERR_NOBRACKET);
|
||||
if (functions[i].args == STR_ARG) {
|
||||
get_token();
|
||||
d = ((matfunc_str)(functions[i].f))(token);
|
||||
*hold = d;
|
||||
get_token();
|
||||
if (save_code)
|
||||
code = save_code;
|
||||
return;
|
||||
}
|
||||
|
||||
argc = 0;
|
||||
do {
|
||||
get_token();
|
||||
if (*token == ')')
|
||||
break;
|
||||
t = (double_list *)malloc(sizeof(double_list));
|
||||
code = 0;
|
||||
level1(&t->val);
|
||||
t->code = code;
|
||||
t->next = NULL;
|
||||
if (last)
|
||||
last->next = t;
|
||||
else
|
||||
args = t;
|
||||
last = t;
|
||||
argc++;
|
||||
} while (*token == ',');
|
||||
|
||||
code = save_code;
|
||||
|
||||
if (argc != functions[i].args && functions[i].args >= 0) {
|
||||
serror(ERR_BADPARAM);
|
||||
} else {
|
||||
switch (functions[i].args) {
|
||||
case 0:
|
||||
d = ((matfunc0)(functions[i].f))();
|
||||
break;
|
||||
case 1:
|
||||
d = ((matfunc)(functions[i].f))(args->val);
|
||||
break;
|
||||
case 2:
|
||||
d = ((matfunc2)(functions[i].f))(args->val, args->next->val);
|
||||
break;
|
||||
case INF_ARGS:
|
||||
d = ((matfunc_inf)(functions[i].f))(args);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
t = args;
|
||||
while (t) {
|
||||
args = t->next;
|
||||
free(t);
|
||||
t = args;
|
||||
}
|
||||
|
||||
*hold = d;
|
||||
}
|
||||
|
||||
static void primitive(double *hold)
|
||||
{
|
||||
switch (token_type) {
|
||||
case VARIABLE:
|
||||
*hold = find_var(token);
|
||||
get_token();
|
||||
return;
|
||||
case NUMBER:
|
||||
*hold = convert(token, NULL);
|
||||
if (convert_error == ERROR)
|
||||
serror(ERR_BADNUMER);
|
||||
get_token();
|
||||
return;
|
||||
case FUNCTION:
|
||||
calc_function(hold);
|
||||
if (*token != ')')
|
||||
serror(ERR_NOBRACKET);
|
||||
get_token();
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void arith(char op, double *r, double *h)
|
||||
{
|
||||
double t;
|
||||
switch (op) {
|
||||
case '-':
|
||||
*r = *r - *h;
|
||||
break;
|
||||
case '+':
|
||||
*r = *r + *h;
|
||||
break;
|
||||
case '*':
|
||||
*r = *r * *h;
|
||||
break;
|
||||
case '/':
|
||||
*r = safediv(*r, *h);
|
||||
break;
|
||||
case '%':
|
||||
if (fabs(*h) < epsilon)
|
||||
serror(ERR_OVERFLOW);
|
||||
else {
|
||||
t = floor((*r) / (*h));
|
||||
*r = *r - (t * (*h));
|
||||
}
|
||||
break;
|
||||
case '^':
|
||||
*r = pow(*r, *h);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void logic(char *op, double *r, double *h)
|
||||
{
|
||||
double t = 0.0;
|
||||
switch (*op) {
|
||||
case '<':
|
||||
if (*(op + 1) && *(op + 1) == '=')
|
||||
t = *r <= *h + epsilon ? 1.0 : 0.0;
|
||||
else
|
||||
t = *r < *h - epsilon ? 1.0 : 0.0;
|
||||
break;
|
||||
case '>':
|
||||
if (*(op + 1) && *(op + 1) == '=')
|
||||
t = *r >= *h - epsilon ? 1.0 : 0.0;
|
||||
else
|
||||
t = *r > *h + epsilon ? 1.0 : 0.0;
|
||||
break;
|
||||
case '=':
|
||||
t = fabs(*r - *h) <= epsilon ? 1.0 : 0.0;
|
||||
break;
|
||||
case '#':
|
||||
t = fabs(*r - *h) > epsilon ? 1.0 : 0.0;
|
||||
break;
|
||||
case '!':
|
||||
if (*(op + 1) && *(op + 1) == '=')
|
||||
t = fabs(*r - *h) > epsilon ? 1.0 : 0.0;
|
||||
else
|
||||
serror(ERR_GENERAL);
|
||||
break;
|
||||
}
|
||||
*r = t;
|
||||
}
|
||||
|
||||
static void unary(char op, double *r)
|
||||
{
|
||||
if (op == '-')
|
||||
*r = -(*r);
|
||||
}
|
||||
|
||||
static int look_up(char *s)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < MAX_FUNC; i++)
|
||||
if (strcmp(s, functions[i].name) == 0)
|
||||
return i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int chrnum(char *text, char symbol)
|
||||
{
|
||||
int num = 0;
|
||||
int i = 0;
|
||||
while (text[i]) {
|
||||
if (text[i] == symbol)
|
||||
num++;
|
||||
i++;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
@@ -1,942 +0,0 @@
|
||||
|
||||
|
||||
#include "func.h"
|
||||
#include "parser.h"
|
||||
//#include <math.h>
|
||||
//#include <stdlib.h>
|
||||
//#include <stdio.h>
|
||||
|
||||
// token types
|
||||
#define DELIMITER 1
|
||||
#define VARIABLE 2
|
||||
#define NUMBER 3
|
||||
#define FUNCTION 4
|
||||
#define FINISHED 10
|
||||
|
||||
//#define allocmem(x) malloc(x)
|
||||
//#define freemem(x) free(x)
|
||||
|
||||
double epsilon = 1e-6;
|
||||
|
||||
// structure for most parser functions
|
||||
|
||||
char token[80];
|
||||
int token_type;
|
||||
char *prog;
|
||||
|
||||
int code; // error code
|
||||
|
||||
|
||||
variable_callback *find_var;
|
||||
|
||||
struct double_list
|
||||
{
|
||||
double val;
|
||||
int code; // ъюф ю°шсъш
|
||||
double_list *next;
|
||||
};
|
||||
|
||||
double tg(double d)
|
||||
{
|
||||
double cosd = cos(d);
|
||||
if (fabs(cosd) < epsilon)
|
||||
{
|
||||
serror(ERR_OVERFLOW);
|
||||
return 0.0;
|
||||
}
|
||||
return sin(d) / cosd;
|
||||
}
|
||||
|
||||
double ctg(double d)
|
||||
{
|
||||
double sind = sin(d);
|
||||
if (fabs(sind) < epsilon)
|
||||
{
|
||||
serror(ERR_OVERFLOW);
|
||||
return 0.0;
|
||||
}
|
||||
return cos(d) / sind;
|
||||
}
|
||||
|
||||
double exp(double x)
|
||||
{
|
||||
__asm {
|
||||
fld x
|
||||
FLDL2E
|
||||
FMUL
|
||||
|
||||
FLD st(0)
|
||||
|
||||
FLD1
|
||||
|
||||
FXCH
|
||||
FPREM
|
||||
F2XM1
|
||||
fadd
|
||||
FSCALE
|
||||
FSTP st(1)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
double log(double x)
|
||||
{
|
||||
//return 0.0;
|
||||
if (x <= 0)
|
||||
{
|
||||
serror(ERR_OVERFLOW);
|
||||
//return 0.0;
|
||||
__asm {
|
||||
fldz
|
||||
}
|
||||
}
|
||||
__asm {
|
||||
FLD1
|
||||
FLD x
|
||||
FYL2X
|
||||
FLDLN2
|
||||
FMUL
|
||||
}
|
||||
}
|
||||
|
||||
double sqrt(double x)
|
||||
{
|
||||
if (x < 0)
|
||||
{
|
||||
serror(ERR_BADPARAM);
|
||||
__asm {
|
||||
fldz
|
||||
}
|
||||
}
|
||||
__asm {
|
||||
fld x
|
||||
fsqrt
|
||||
}
|
||||
}
|
||||
|
||||
double atan(double x)
|
||||
{
|
||||
serror(ERR_GENERAL);
|
||||
return 0.0; // т ыюь
|
||||
}
|
||||
|
||||
double pow(double x, double y)
|
||||
{
|
||||
return exp(y * log(x)); //
|
||||
}
|
||||
|
||||
double func_pi()
|
||||
{
|
||||
return 3.14159265358979;
|
||||
}
|
||||
|
||||
double func_eps()
|
||||
{
|
||||
return epsilon;
|
||||
}
|
||||
|
||||
double func_if(double_list *p)
|
||||
{
|
||||
double_list *a, *b, *c;
|
||||
a = p;
|
||||
b = a->next;
|
||||
if (!b)
|
||||
{
|
||||
serror(ERR_BADPARAM);
|
||||
return 0.0;
|
||||
}
|
||||
c = b->next;
|
||||
if (!c || c->next)
|
||||
{
|
||||
serror(ERR_BADPARAM);
|
||||
return 0.0;
|
||||
}
|
||||
if (a->val != 0.0)
|
||||
{
|
||||
if (b->code)
|
||||
code = b->code;
|
||||
return b->val;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (c->code)
|
||||
code = c->code;
|
||||
return c->val;
|
||||
}
|
||||
}
|
||||
|
||||
double sum(double_list *p)
|
||||
{
|
||||
double res = 0.0;
|
||||
while (p)
|
||||
{
|
||||
res += p->val;
|
||||
if (p->code)
|
||||
code = p->code;
|
||||
p = p->next;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
double func_min(double_list *p)
|
||||
{
|
||||
if (!p)
|
||||
serror(ERR_BADPARAM);
|
||||
double res = p->val;
|
||||
p = p->next;
|
||||
while (p)
|
||||
{
|
||||
if (p->code)
|
||||
code = p->code;
|
||||
if (p->val < res)
|
||||
res = p->val;
|
||||
p = p->next;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
double func_max(double_list *p)
|
||||
{
|
||||
if (!p)
|
||||
serror(ERR_BADPARAM);
|
||||
double res = p->val;
|
||||
p = p->next;
|
||||
while (p)
|
||||
{
|
||||
if (p->code)
|
||||
code = p->code;
|
||||
if (p->val > res)
|
||||
res = p->val;
|
||||
p = p->next;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
double avg(double_list *p)
|
||||
{
|
||||
double res = 0.0;
|
||||
int count = 0;
|
||||
while (p)
|
||||
{
|
||||
if (p->code)
|
||||
code = p->code;
|
||||
res += p->val;
|
||||
count++;
|
||||
p = p->next;
|
||||
}
|
||||
return res / count;
|
||||
}
|
||||
|
||||
double func_isnull(char *str)
|
||||
{
|
||||
if (code != 0)
|
||||
return 0.0;
|
||||
double tmp = find_var(str);
|
||||
int c = code;
|
||||
code = 0;
|
||||
if (c != 0)
|
||||
return 1.0;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
const double HALF = 0.5;
|
||||
double func_ceil(double val) // їюЄхы round, р яюыєўшыё ceil...
|
||||
{
|
||||
int x;
|
||||
__asm fld val
|
||||
__asm fld HALF // фр, ъЁштюЁєъю ^_^
|
||||
__asm fadd
|
||||
__asm fistp x
|
||||
__asm fild x
|
||||
}
|
||||
|
||||
double func_round(double val)
|
||||
{
|
||||
int x;
|
||||
__asm fld val
|
||||
__asm fld epsilon
|
||||
__asm fadd
|
||||
__asm fistp x
|
||||
__asm fild x
|
||||
}
|
||||
|
||||
//const double ALMOST_HALF = 0.5 - epsilon;
|
||||
double ALMOST_HALF;
|
||||
extern void ALMOST_HALF_init(void)
|
||||
{ ALMOST_HALF = 0.5 - epsilon; }
|
||||
double func_floor(double val)
|
||||
{
|
||||
int x;
|
||||
__asm fld val
|
||||
__asm fld ALMOST_HALF
|
||||
__asm fsub
|
||||
__asm fistp x
|
||||
__asm fild x
|
||||
}
|
||||
|
||||
double logic_xor(double a, double b)
|
||||
{
|
||||
if (a == 0.0)
|
||||
if (b == 0.0)
|
||||
return 0.0;
|
||||
else
|
||||
return 1.0;
|
||||
else
|
||||
if (b == 0.0)
|
||||
return 1.0;
|
||||
else
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
double logic_and(double a, double b)
|
||||
{
|
||||
if (a == 0.0)
|
||||
return 0.0;
|
||||
else
|
||||
if (b == 0.0)
|
||||
return 0.0;
|
||||
else
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
double logic_or(double a, double b)
|
||||
{
|
||||
if (a == 0.0)
|
||||
if (b == 0.0)
|
||||
return 0.0;
|
||||
else
|
||||
return 1.1;
|
||||
else
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
double rand_seed;
|
||||
double func_rand(double max)
|
||||
{
|
||||
double q = (257.0 * rand_seed + 739.0); // ўшёыр юЄ срыф√. эрфю тёЄртшЄ№ яЁртшы№э√х.
|
||||
rand_seed = q - 65536.0 * func_floor(q / 65536.0); // фы їюЁю°хую ЁрёяЁхфхыхэш
|
||||
return q - max * func_floor(q / max); // фы ьюфєы
|
||||
}
|
||||
|
||||
/*
|
||||
double func_case(double_list *p)
|
||||
{
|
||||
if (!p || !p->next)
|
||||
{
|
||||
serror(ERR_BADPARAM);
|
||||
return 0.0;
|
||||
}
|
||||
double x = p->val;
|
||||
int count = (int)p->next->val;
|
||||
int i, k;
|
||||
|
||||
double_list *cur = p->next->next;
|
||||
k = count;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (!cur)
|
||||
{
|
||||
serror(ERR_BADPARAM);
|
||||
return 0.0;
|
||||
}
|
||||
if (fabs(x - cur->val) < epsilon)
|
||||
{
|
||||
if (k != count + 1)
|
||||
{
|
||||
serror(ERR_GENERAL);
|
||||
return 0.0;
|
||||
}
|
||||
k = i;
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
for (i = 0; i < k; i++)
|
||||
{
|
||||
if (!cur)
|
||||
{
|
||||
serror(ERR_BADPARAM);
|
||||
return 0.0;
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
if (!cur) // яЁютхЁъш сшя. фюёЄрыш сшя.
|
||||
{
|
||||
serror(ERR_BADPARAM);
|
||||
return 0.0;
|
||||
}
|
||||
if (cur->code)
|
||||
code = cur->code;
|
||||
return cur->val;
|
||||
}
|
||||
*/
|
||||
|
||||
#define INF_ARGS -1
|
||||
#define STR_ARG -2
|
||||
|
||||
// represents general mathematical function
|
||||
typedef double(*matfunc0)();
|
||||
typedef double(*matfunc)(double);
|
||||
typedef double(*matfunc2)(double,double);
|
||||
typedef double(*matfunc3)(double,double,double);
|
||||
typedef double(*matfunc_inf)(double_list*);
|
||||
typedef double(*matfunc_str)(char*);
|
||||
|
||||
// used to link function name to the function
|
||||
typedef struct
|
||||
{
|
||||
char name[10];
|
||||
int args;
|
||||
void * f;
|
||||
} func;
|
||||
|
||||
// the list of functions
|
||||
const int max_func = 28;
|
||||
func functions[max_func] =
|
||||
{
|
||||
"", 1, NULL, // эх яюьэ■, ё ъръющ Ўхы№■
|
||||
"sin", 1, &sin,
|
||||
"cos", 1, &cos,
|
||||
"exp", 1, &exp,
|
||||
"sqrt", 1, &sqrt,
|
||||
"log", 1, &log,
|
||||
"tg", 1, &tg,
|
||||
"ctg", 1, &ctg,
|
||||
"arcsin", 1, &asin,
|
||||
"arccos", 1, &acos,
|
||||
"arctg", 1, &atan, // эх Ёхрышчютрэю. тючтЁр∙рхЄ ю°шсъє ERR_GENERAL
|
||||
"abs", 1, &fabs,
|
||||
"pow", 2, &pow,
|
||||
"if", INF_ARGS, &func_if,
|
||||
"sum",INF_ARGS,&sum,
|
||||
"isnull",STR_ARG,&func_isnull, // ёыхуър ў/ц
|
||||
"min",INF_ARGS,&func_min,
|
||||
"max",INF_ARGS,&func_max,
|
||||
"avg",INF_ARGS,&avg,
|
||||
"ceil",1,&func_ceil,
|
||||
"round",1,&func_round,
|
||||
"floor",1,&func_floor,
|
||||
"and",2,&logic_and,
|
||||
"or",2,&logic_or,
|
||||
"xor",2,&logic_xor,
|
||||
"rand",1,&func_rand,
|
||||
//"case",INF_ARGS,&func_case,
|
||||
"pi",0,&func_pi,
|
||||
"eps",0,&func_eps
|
||||
};
|
||||
|
||||
// all delimiters
|
||||
#define MAXDELIM 17
|
||||
const char delim[MAXDELIM]="+-*^/%=;(),><#! "; // not bad words
|
||||
|
||||
|
||||
int isdelim(char c)
|
||||
{
|
||||
//return strchr(delim, c) != 0;
|
||||
for (int i = 0; i < MAXDELIM; i++)
|
||||
if (c == delim[i])
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int isdigit(char c)
|
||||
{
|
||||
return (c >= '0' && c <= '9');
|
||||
}
|
||||
|
||||
int isalpha2(char c)
|
||||
{
|
||||
return ((c >= 'a' && c <= 'z')
|
||||
|| (c >= 'A' && c <= 'Z') || (c=='$'));
|
||||
}
|
||||
|
||||
int iswhite(char c)
|
||||
{
|
||||
return (c==' ' || c=='\t');
|
||||
}
|
||||
|
||||
|
||||
void serror(int acode)
|
||||
{
|
||||
if (acode != 0)
|
||||
code = acode;
|
||||
}
|
||||
|
||||
void set_exp(char *exp)
|
||||
{
|
||||
prog = exp;
|
||||
}
|
||||
|
||||
int get_token()
|
||||
{
|
||||
int tok;
|
||||
char *temp;
|
||||
(token_type) = 0;
|
||||
tok = 0;
|
||||
temp = (token);
|
||||
|
||||
if (*(prog) == '\0')
|
||||
{
|
||||
*(token) = 0;
|
||||
tok = FINISHED;
|
||||
return ((token_type) = DELIMITER);
|
||||
}
|
||||
while (iswhite(*(prog))) ++(prog);
|
||||
if (isdelim(*(prog)))
|
||||
{
|
||||
char t=*temp = *(prog);
|
||||
(prog)++;
|
||||
temp++;
|
||||
if ((t == '>' || t == '<' || t == '!') && (*prog) && (*prog == '='))
|
||||
{
|
||||
*temp = *(prog);
|
||||
(prog)++;
|
||||
temp++;
|
||||
}
|
||||
*temp = 0;
|
||||
return ((token_type) = DELIMITER);
|
||||
}
|
||||
if (isdigit(*(prog)))
|
||||
{
|
||||
while (!isdelim(*(prog)))
|
||||
*temp++=*(prog)++;
|
||||
*temp = '\0';
|
||||
return ((token_type) = NUMBER);
|
||||
}
|
||||
if (isalpha2(*(prog)))
|
||||
{
|
||||
while (!isdelim(*(prog)))
|
||||
*temp++=*(prog)++;
|
||||
(token_type) = VARIABLE;
|
||||
}
|
||||
*temp = '\0';
|
||||
if ((token_type) == VARIABLE)
|
||||
{
|
||||
tok = look_up((token));
|
||||
if (tok)
|
||||
(token_type) = FUNCTION;
|
||||
}
|
||||
return (token_type);
|
||||
}
|
||||
|
||||
double sign(double d)
|
||||
{
|
||||
if (d > 0.0)
|
||||
return 1.0;
|
||||
if (d < 0.0)
|
||||
return -1.0;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
void putback()
|
||||
{
|
||||
char *t;
|
||||
t = (token);
|
||||
for (;*t;t++)
|
||||
(prog)--;
|
||||
}
|
||||
|
||||
int get_exp(double *hold)
|
||||
{
|
||||
code = 0;
|
||||
|
||||
get_token();
|
||||
if (!*(token))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
level1( hold);
|
||||
putback();
|
||||
return code==0;
|
||||
}
|
||||
|
||||
void level1(double *hold)
|
||||
{
|
||||
char op[2];
|
||||
double h;
|
||||
|
||||
level1_5( hold);
|
||||
while (op[0] = *token, op[1] = (*(token+1)) ? *(token + 1) : 0,
|
||||
*op == '<' || *op == '>' || *op == '=' || *op == '#' || *op == '!')
|
||||
{
|
||||
get_token();
|
||||
level1_5( &h);
|
||||
logic(op, hold, &h);
|
||||
}
|
||||
}
|
||||
|
||||
void level1_5(double *hold)
|
||||
{
|
||||
char op;
|
||||
|
||||
op = 0;
|
||||
if (((token_type) == DELIMITER) && *(token) == '!')
|
||||
{
|
||||
op = *(token);
|
||||
get_token();
|
||||
}
|
||||
level2( hold);
|
||||
|
||||
if (op)
|
||||
{
|
||||
if (*hold == 0.0)
|
||||
*hold = 1.0;
|
||||
else
|
||||
*hold = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
void level2(double *hold)
|
||||
{
|
||||
char op;
|
||||
double h;
|
||||
|
||||
level3( hold);
|
||||
while ((op=*(token)) == '+' || op == '-')
|
||||
{
|
||||
get_token();
|
||||
level3( &h);
|
||||
arith(op, hold, &h);
|
||||
}
|
||||
}
|
||||
|
||||
void level3(double *hold)
|
||||
{
|
||||
char op;
|
||||
double h;
|
||||
|
||||
level4( hold);
|
||||
while ((op=*(token)) == '*' || op == '/' || op == '%')
|
||||
{
|
||||
get_token();
|
||||
level4( &h);
|
||||
arith( op, hold, &h);
|
||||
}
|
||||
}
|
||||
|
||||
void level4(double *hold)
|
||||
{
|
||||
double h;
|
||||
level5( hold);
|
||||
|
||||
if (*(token) == '^')
|
||||
{
|
||||
get_token();
|
||||
level5( &h);
|
||||
arith( '^', hold, &h);
|
||||
}
|
||||
}
|
||||
|
||||
void level5(double *hold)
|
||||
{
|
||||
char op;
|
||||
|
||||
op = 0;
|
||||
if (((token_type) == DELIMITER) && *(token) == '+' || *(token) == '-')
|
||||
{
|
||||
op = *(token);
|
||||
get_token();
|
||||
}
|
||||
level6( hold);
|
||||
|
||||
if (op)
|
||||
unary(op, hold);
|
||||
}
|
||||
|
||||
void level6(double *hold)
|
||||
{
|
||||
if ((*(token) == '(') && ((token_type) == DELIMITER))
|
||||
{
|
||||
get_token();
|
||||
level1( hold);
|
||||
if (*(token) != ')')
|
||||
serror( ERR_NOBRACKET);
|
||||
get_token();
|
||||
}
|
||||
else
|
||||
primitive( hold);
|
||||
}
|
||||
|
||||
void calc_function(double *hold)
|
||||
{
|
||||
double_list *args = NULL, *last = NULL, *t;
|
||||
double d;
|
||||
int i,argc=0,save_code;
|
||||
|
||||
save_code = code;
|
||||
code = 0;
|
||||
i = look_up(token);
|
||||
|
||||
if (i == 0)
|
||||
serror(ERR_BADFUNCTION); // error
|
||||
|
||||
get_token();
|
||||
if (*(token) != '(')
|
||||
serror(ERR_NOBRACKET); // error
|
||||
//get_token();
|
||||
if (functions[i].args == STR_ARG)
|
||||
{
|
||||
get_token();
|
||||
d = ((matfunc_str)(functions[i].f))(token);
|
||||
*hold = d;
|
||||
get_token();
|
||||
if (save_code)
|
||||
code = save_code;
|
||||
return;
|
||||
}
|
||||
|
||||
//last = args = (double_list*)malloc(sizeof(double_list));
|
||||
//args->next = NULL;
|
||||
//level1(&args->val);
|
||||
//get_token();
|
||||
argc=0;
|
||||
do
|
||||
{
|
||||
get_token();
|
||||
if (*token == ')')
|
||||
break;
|
||||
t = (double_list*)allocmem(sizeof(double_list));
|
||||
code = 0;
|
||||
level1(&t->val);
|
||||
t->code = code;
|
||||
t->next = NULL;
|
||||
if (last)
|
||||
last->next = t;
|
||||
else
|
||||
args = t;
|
||||
last = t;
|
||||
argc++;
|
||||
} while (*token == ',');
|
||||
|
||||
code = save_code;
|
||||
|
||||
if (argc != functions[i].args && functions[i].args >= 0)
|
||||
{
|
||||
serror(ERR_BADPARAM);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (functions[i].args)
|
||||
{
|
||||
case 0:
|
||||
d = ((matfunc0)(functions[i].f))();
|
||||
break;
|
||||
case 1:
|
||||
d = ((matfunc)(functions[i].f))(args->val);
|
||||
break;
|
||||
case 2:
|
||||
d = ((matfunc2)(functions[i].f))(args->val,args->next->val);
|
||||
break;
|
||||
case 3:
|
||||
d = ((matfunc3)(functions[i].f))(args->val,args->next->val,args->next->next->val);
|
||||
break;
|
||||
case INF_ARGS:
|
||||
d = ((matfunc_inf)(functions[i].f))(args);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
t = args;
|
||||
while (t)
|
||||
{
|
||||
args = t->next;
|
||||
freemem(t);
|
||||
t = args;
|
||||
}
|
||||
|
||||
*hold = d;
|
||||
// else
|
||||
// serror( ERR_OVERFLOW);
|
||||
|
||||
}
|
||||
|
||||
void primitive(double *hold)
|
||||
{
|
||||
switch (token_type)
|
||||
{
|
||||
case VARIABLE:
|
||||
*hold = find_var(token);
|
||||
get_token();
|
||||
return;
|
||||
case NUMBER:
|
||||
//
|
||||
*hold = atof((token));
|
||||
//if (sscanf(token, "%lf", hold) != 1)
|
||||
*hold = convert(token);
|
||||
if (convert_error == ERROR)
|
||||
serror( ERR_BADNUMER);
|
||||
get_token();
|
||||
return;
|
||||
case FUNCTION:
|
||||
calc_function( hold);
|
||||
if (*token != ')')
|
||||
serror(ERR_NOBRACKET);
|
||||
get_token();
|
||||
return;
|
||||
default: // error
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void arith(char op, double *r, double *h)
|
||||
{
|
||||
double t;
|
||||
switch(op)
|
||||
{
|
||||
case '-':
|
||||
*r = *r - *h;
|
||||
break;
|
||||
case '+':
|
||||
*r = *r + *h;
|
||||
break;
|
||||
case '*':
|
||||
*r = *r * *h;
|
||||
break;
|
||||
case '/':
|
||||
if (fabs(*h) < epsilon)
|
||||
serror( ERR_OVERFLOW);
|
||||
else
|
||||
*r = (*r) / (*h);
|
||||
break;
|
||||
case '%':
|
||||
if (fabs(*h) < epsilon)
|
||||
serror( ERR_OVERFLOW);
|
||||
else
|
||||
{
|
||||
t = func_floor ((*r) / (*h));
|
||||
*r = *r - (t * (*h));
|
||||
}
|
||||
break;
|
||||
case '^':
|
||||
*r = pow(*r, *h);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void logic(char *op, double *r, double *h)
|
||||
{
|
||||
double t;
|
||||
switch (*op)
|
||||
{
|
||||
case '<':
|
||||
if (*(op+1) && *(op+1) == '=')
|
||||
t = *r <= *h + epsilon ? 1.0 : 0.0;
|
||||
else
|
||||
t = *r < *h - epsilon? 1.0 : 0.0;
|
||||
break;
|
||||
case '>':
|
||||
if (*(op+1) && *(op+1) == '=')
|
||||
t = *r >= *h - epsilon ? 1.0 : 0.0;
|
||||
else
|
||||
t = *r > *h + epsilon ? 1.0 : 0.0;
|
||||
break;
|
||||
case '=':
|
||||
t = fabs(*r - *h) <= epsilon ? 1.0 : 0.0;
|
||||
break;
|
||||
case '#':
|
||||
t = fabs(*r - *h) > epsilon ? 1.0 : 0.0;
|
||||
break;
|
||||
case '!':
|
||||
if (*(op+1) && *(op+1) == '=')
|
||||
t = fabs(*r - *h) > epsilon ? 1.0 : 0.0;
|
||||
else
|
||||
serror(ERR_GENERAL);
|
||||
break;
|
||||
}
|
||||
*r = t;
|
||||
}
|
||||
|
||||
|
||||
void unary(char op, double *r)
|
||||
{
|
||||
if (op == '-')
|
||||
*r = -(*r);
|
||||
}
|
||||
|
||||
bool strcmp(char *s1, char *s2)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (s1 == NULL)
|
||||
if (s2 == NULL)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
else
|
||||
if (s2 == NULL)
|
||||
return 1;
|
||||
|
||||
for (i = 0;;i++)
|
||||
{
|
||||
if (s1[i] == '\0')
|
||||
if (s2[i] == '\0')
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
else
|
||||
if (s2[i] == '\0')
|
||||
return 1;
|
||||
else
|
||||
{
|
||||
if (s1[i] != s2[i])
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool strncmp(char *s1, char *s2, int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (s1 == NULL)
|
||||
if (s2 == NULL)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
else
|
||||
if (s2 == NULL)
|
||||
return 1;
|
||||
|
||||
for (i = 0;i<n;i++)
|
||||
{
|
||||
if (s1[i] == '\0')
|
||||
if (s2[i] == '\0')
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
else
|
||||
if (s2[i] == '\0')
|
||||
return 1;
|
||||
else
|
||||
{
|
||||
if (s1[i] != s2[i])
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int look_up(char *s)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < max_func; i++)
|
||||
if (strcmp(s, functions[i].name) == 0)
|
||||
return i;
|
||||
return 0; // search command/function name
|
||||
}
|
||||
|
||||
unsigned int chrnum(char* text, char symbol)
|
||||
{
|
||||
int num = 0;
|
||||
int i = 0;
|
||||
while(text[i])
|
||||
{
|
||||
if (text[i] == symbol) num++;
|
||||
i++;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
@@ -1,72 +1,34 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
// error codes
|
||||
#define ERR_BADFUNCTION -1
|
||||
#define ERR_BADNUMER -2
|
||||
#define ERR_GENERAL -3
|
||||
#define ERR_NOBRACKET -4
|
||||
#define ERR_BADVARIABLE -5
|
||||
#define ERR_OVERFLOW -6
|
||||
#define ERR_BADPARAM -7
|
||||
|
||||
typedef double variable_callback(char *s);
|
||||
|
||||
void set_exp(char *exp);
|
||||
// puts the token back to line
|
||||
void putback(double *hold);
|
||||
// gets the expression. This function is used externally
|
||||
int get_exp(double *hold);
|
||||
|
||||
// logic binary
|
||||
void level1(double *hold);
|
||||
|
||||
// unary !
|
||||
void level1_5(double *hold);
|
||||
|
||||
// works with +-
|
||||
void level2(double *hold);
|
||||
// works with */%
|
||||
void level3(double *hold);
|
||||
// works with ^
|
||||
void level4(double *hold);
|
||||
// works with ()
|
||||
void level5(double *hold);
|
||||
// works with elementary tokens
|
||||
void level6(double *hold);
|
||||
// gets value of number, function or variable
|
||||
void primitive(double *hold);
|
||||
// performs arithmetical operation
|
||||
void arith(char op, double *r, double *h);
|
||||
|
||||
void logic(char *op, double *r, double *h);
|
||||
|
||||
|
||||
// performs unary (one-operand) operation
|
||||
void unary(char op, double *r);
|
||||
// gets variable value by name
|
||||
extern variable_callback *find_var;
|
||||
|
||||
extern double rand_seed;
|
||||
|
||||
// stops execution of parser and return error code
|
||||
void serror(int code);
|
||||
// checks the function table to see if such a function exists
|
||||
int look_up(char *s);
|
||||
|
||||
bool strcmp(char *s1, char *s2);
|
||||
bool strncmp(char *s1, char *s2, int n);
|
||||
|
||||
unsigned int chrnum(char* text, char symbol);
|
||||
|
||||
extern double epsilon;
|
||||
|
||||
|
||||
int isdelim(char c);
|
||||
int isdigit(char c);
|
||||
int isalpha2(char c);
|
||||
int iswhite(char c);
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
// error codes
|
||||
#define ERR_BADFUNCTION -1
|
||||
#define ERR_BADNUMER -2
|
||||
#define ERR_GENERAL -3
|
||||
#define ERR_NOBRACKET -4
|
||||
#define ERR_BADVARIABLE -5
|
||||
#define ERR_OVERFLOW -6
|
||||
#define ERR_BADPARAM -7
|
||||
|
||||
// number parser, shared with calc.c (accepts '.' or ',' as the decimal point)
|
||||
#define ERROR -1 // convert(): bad character
|
||||
#define ERROR_END -2 // convert(): empty / no number
|
||||
extern int convert_error;
|
||||
double convert(char *s, int *len);
|
||||
|
||||
typedef double variable_callback(char *s);
|
||||
|
||||
// resolves a variable name to its value; set by the host before get_exp()
|
||||
extern variable_callback *find_var;
|
||||
|
||||
// set the expression to evaluate
|
||||
void set_exp(char *exp);
|
||||
// evaluate it; writes result to *hold, returns nonzero on success
|
||||
int get_exp(double *hold);
|
||||
// raise a parser error (stores the code)
|
||||
void serror(int code);
|
||||
|
||||
// count occurrences of symbol in text
|
||||
unsigned int chrnum(char *text, char symbol);
|
||||
// char classifiers (named to avoid clashing with <ctype.h> macros)
|
||||
int isdigit2(char c);
|
||||
int isalpha2(char c);
|
||||
@@ -1,8 +0,0 @@
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// FixedPoint.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// TODO: reference any additional headers you need in STDAFX.H
|
||||
// and not in this file
|
||||
@@ -1,11 +0,0 @@
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently, but
|
||||
// are changed infrequently
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
|
||||
// TODO: reference additional headers your program requires here
|
||||
@@ -0,0 +1,993 @@
|
||||
#include "calc.h"
|
||||
|
||||
#include <clayer/boxlib.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/ksys.h>
|
||||
|
||||
/* ============================ constants =========================== */
|
||||
|
||||
#define TABLE_VERSION "1.0"
|
||||
|
||||
// window
|
||||
#define WND_W 718
|
||||
#define WND_H 514
|
||||
#define MENU_PANEL_HEIGHT 40
|
||||
#define SCROLL_SIZE 16
|
||||
|
||||
// interface colors
|
||||
#define GRID_COLOR 0xa0a0a0
|
||||
#define TEXT_COLOR 0x000000
|
||||
#define CELL_COLOR 0xffffff
|
||||
#define CELL_COLOR_ACTIVE 0xe0e0ff
|
||||
#define HEADER_CELL_COLOR 0xE9E7E3
|
||||
#define HEADER_CELL_COLOR_ACTIVE 0xC4C5BA
|
||||
|
||||
// button IDs
|
||||
#define SAVE_BUTTON 100
|
||||
#define LOAD_BUTTON 101
|
||||
#define NEW_BUTTON 102
|
||||
#define SELECT_ALL_BUTTON 103
|
||||
#define COL_HEAD_BUTTON 0x300
|
||||
#define ROW_HEAD_BUTTON 0x400
|
||||
#define CELL_BUTTON 0x500
|
||||
|
||||
// draw-less clickable button (BT_HIDE | BT_NOFRAME)
|
||||
#define BT_NODRAW 0x60000000
|
||||
|
||||
// size_state values (cell resize / range select-drag)
|
||||
#define SIZE_X 1
|
||||
#define SIZE_Y 2
|
||||
#define SIZE_SELECT 3
|
||||
#define SIZE_DRAG 4
|
||||
|
||||
/* ======================= cell model (calc.c) ====================== */
|
||||
// Defined here, shared with calc.c via extern. Bounds: columns A..CZ,
|
||||
// rows 1..100; index 0 is the header row/column, so counts are one larger.
|
||||
|
||||
Table tbl = { 105, 101 }; // columns A..CZ, rows 1..100 (index 0 = headers)
|
||||
const char *sFileSign = "KolibriTable File\n";
|
||||
|
||||
// clipboard
|
||||
char ***buffer = NULL;
|
||||
int buf_col, buf_row;
|
||||
|
||||
/* ============================= UI state =========================== */
|
||||
|
||||
static int buf_old_x, buf_old_y; // origin of the copied block
|
||||
|
||||
// selection
|
||||
static int sel_x = 1, sel_y = 1;
|
||||
static int sel_end_x = 1, sel_end_y = 1;
|
||||
static int nx = 0, ny = 0; // one past the last visible column/row
|
||||
static int display_formulas = 0;
|
||||
|
||||
// pixel scroll is the primary state; grid.firstx/firsty (first visible cell)
|
||||
// and off_x/off_y (pixels of it hidden past the top-left edge) are derived
|
||||
// from it in clamp_view()
|
||||
static int scroll_x = 0, scroll_y = 0;
|
||||
static int off_x = 0, off_y = 0;
|
||||
|
||||
// window work area + skin colors
|
||||
static int cWidth, cHeight;
|
||||
static ksys_colors_table_t sc;
|
||||
|
||||
// resize / range-drag state
|
||||
static int size_mouse_x, size_mouse_y, size_id, size_state = 0;
|
||||
static int drag_x, drag_y;
|
||||
static int old_end_x, old_end_y;
|
||||
|
||||
// grid geometry: pixel rect of the table area + first visible cell
|
||||
static struct GRID {
|
||||
int x, y, w, h;
|
||||
int firstx, firsty;
|
||||
} grid = { 0, 0, 0, 0, 1, 1 };
|
||||
|
||||
// labels
|
||||
static const char sFilename[] = "Filename:";
|
||||
static const char sSave[] = "Save";
|
||||
static const char sLoad[] = "Load";
|
||||
static const char er_file_not_found[] = "'Cannot open file' -E";
|
||||
static const char er_format[] = "'Error: bad format' -E";
|
||||
static const char msg_save[] = "'File saved' -O";
|
||||
static const char msg_save_error[] = "'Error saving file' -E";
|
||||
|
||||
// box_lib widgets
|
||||
static char edit_text[256];
|
||||
static edit_box cell_box = { 0, 9 * 8 - 6, WND_H - 16 - 32, 0xffffff, 0x94AECE, 0,
|
||||
0x808080, 0x10000000, sizeof(edit_text) - 1, edit_text, 0, 0 };
|
||||
|
||||
static char fname[256];
|
||||
static edit_box file_box = { 160, 9 * 8 + 12, WND_H - 16 - 32, 0xffffff, 0x94AECE,
|
||||
0, 0x808080, 0x10000000, sizeof(fname) - 1, fname, 0, 0 };
|
||||
|
||||
static scrollbar scroll_v = { SCROLL_SIZE, 200, 398, 0, SCROLL_SIZE, 0, 115,
|
||||
15, 0, 0xeeeeee, 0xD2CED0, 0x555555, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 };
|
||||
static scrollbar scroll_h = { 200, 0, SCROLL_SIZE, 0, SCROLL_SIZE, 0, 115,
|
||||
15, 0, 0xeeeeee, 0xD2CED0, 0x555555, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 };
|
||||
|
||||
#define is_edit (cell_box.flags & ed_focus)
|
||||
|
||||
/* ============================= functions ========================== */
|
||||
|
||||
static void draw_grid(void);
|
||||
static void EventGridSelectAll(void);
|
||||
static int col_left(int j);
|
||||
static int row_top(int i);
|
||||
|
||||
// scroll the minimum amount so cell (cx,cy) is fully inside the viewport
|
||||
static void ensure_visible(int cx, int cy)
|
||||
{
|
||||
int aw = grid.w - tbl.w[0], ah = grid.h - tbl.h[0];
|
||||
int l = col_left(cx), r = l + tbl.w[cx];
|
||||
int t = row_top(cy), b = t + tbl.h[cy];
|
||||
if (l < scroll_x)
|
||||
scroll_x = l;
|
||||
else if (r > scroll_x + aw)
|
||||
scroll_x = r - aw;
|
||||
if (t < scroll_y)
|
||||
scroll_y = t;
|
||||
else if (b > scroll_y + ah)
|
||||
scroll_y = b - ah;
|
||||
}
|
||||
|
||||
// button define that first clears the previous one with the same id
|
||||
static void def_button(int x, int y, int w, int h, uint32_t id, uint32_t color)
|
||||
{
|
||||
_ksys_delete_button(id);
|
||||
_ksys_define_button(x, y, w, h, id, color);
|
||||
}
|
||||
|
||||
// text with a KolibriOS fn4 font flag (0x10 small, 0x90 big). The flag lives
|
||||
// in the high byte of the color argument (ecx), so just pack and pass it.
|
||||
static void draw_text(int x, int y, unsigned font, uint32_t color, const char *s, int len)
|
||||
{
|
||||
_ksys_draw_text(s, x, y, len, (font << 24) | (color & 0xFFFFFF));
|
||||
}
|
||||
|
||||
// line; invert=1 draws an XOR (rubber-band) line - fn38 reads that from the
|
||||
// color (edx), value 0x01000000.
|
||||
static void draw_line(int x1, int y1, int x2, int y2, uint32_t color, int invert)
|
||||
{
|
||||
_ksys_draw_line(x1, y1, x2, y2, invert ? 0x01000000 : color);
|
||||
}
|
||||
|
||||
// rectangle outline
|
||||
static void draw_region(int x, int y, int w, int h, uint32_t color)
|
||||
{
|
||||
_ksys_draw_line(x, y, x + w - 2, y, color);
|
||||
_ksys_draw_line(x, y + 1, x, y + h - 1, color);
|
||||
_ksys_draw_line(x + w - 1, y, x + w - 1, y + h - 2, color);
|
||||
_ksys_draw_line(x + 1, y + h - 1, x + w - 1, y + h - 1, color);
|
||||
}
|
||||
|
||||
// text clipped to area_w pixels (small font)
|
||||
static void draw_cut_text(int x, int y, int area_w, uint32_t color, const char *s)
|
||||
{
|
||||
int len;
|
||||
if (!s)
|
||||
return;
|
||||
len = strlen(s);
|
||||
if (len * 8 > area_w)
|
||||
len = area_w / 8;
|
||||
draw_text(x, y, 0x10, color, s, len);
|
||||
}
|
||||
|
||||
static void DrawSelectedFrame(int x, int y, int w, int h, uint32_t col)
|
||||
{
|
||||
_ksys_draw_bar(x, y, w, 2, col); // up
|
||||
_ksys_draw_bar(x, y, 2, h, col); // left
|
||||
_ksys_draw_bar(x, y + h - 2, w - 2 - 3, 2, col); // bottom
|
||||
_ksys_draw_bar(x + w - 2, y, 2, h - 2 - 3, col); // right
|
||||
_ksys_draw_bar(x + w - 4, y + h - 4, 4, 4, col);
|
||||
}
|
||||
|
||||
static void DrawScrolls(void)
|
||||
{
|
||||
// horizontal
|
||||
scroll_h.xpos = 0;
|
||||
scroll_h.ypos = grid.y + grid.h;
|
||||
scroll_h.xsize = grid.w + SCROLL_SIZE + 1;
|
||||
scroll_h.all_redraw = 1;
|
||||
scroll_h.max_area = col_left(tbl.cols); // total content width, px
|
||||
scroll_h.cur_area = grid.w - tbl.w[0]; // viewport width, px
|
||||
scroll_h.position = scroll_x;
|
||||
scrollbar_h_draw(&scroll_h);
|
||||
|
||||
// vertical
|
||||
scroll_v.xpos = grid.x + grid.w;
|
||||
scroll_v.ypos = 0;
|
||||
scroll_v.ysize = grid.h + 1;
|
||||
scroll_v.all_redraw = 1;
|
||||
scroll_v.max_area = row_top(tbl.rows); // total content height, px
|
||||
scroll_v.cur_area = grid.h - tbl.h[0]; // viewport height, px
|
||||
scroll_v.position = scroll_y;
|
||||
scrollbar_v_draw(&scroll_v);
|
||||
}
|
||||
|
||||
static void start_edit(int x, int y)
|
||||
{
|
||||
int sx0 = scroll_x, sy0 = scroll_y;
|
||||
ensure_visible(x, y);
|
||||
if (scroll_x != sx0 || scroll_y != sy0)
|
||||
draw_grid();
|
||||
|
||||
file_box.flags &= ~ed_focus;
|
||||
|
||||
cell_box.flags = ed_focus;
|
||||
cell_box.left = tbl.x[x] + 1;
|
||||
cell_box.top = tbl.y[y];
|
||||
cell_box.width = tbl.w[x] - 2;
|
||||
memset(edit_text, 0, sizeof(edit_text));
|
||||
if (tbl.cells[x][y])
|
||||
strcpy(edit_text, tbl.cells[x][y]);
|
||||
cell_box.offset = cell_box.shift = cell_box.shift_old = 0;
|
||||
cell_box.pos = cell_box.size = strlen(edit_text);
|
||||
|
||||
edit_box_draw(&cell_box);
|
||||
edit_box_draw(&file_box);
|
||||
}
|
||||
|
||||
static void stop_edit(void)
|
||||
{
|
||||
if (is_edit) {
|
||||
cell_box.flags &= ~ed_focus;
|
||||
if (tbl.cells[sel_x][sel_y])
|
||||
free(tbl.cells[sel_x][sel_y]);
|
||||
if (strlen(edit_text) > 0) {
|
||||
tbl.cells[sel_x][sel_y] = malloc(strlen(edit_text) + 1);
|
||||
strcpy(tbl.cells[sel_x][sel_y], edit_text);
|
||||
} else
|
||||
tbl.cells[sel_x][sel_y] = NULL;
|
||||
table_recalc();
|
||||
}
|
||||
}
|
||||
|
||||
static void cancel_edit(void)
|
||||
{
|
||||
if (!is_edit)
|
||||
return;
|
||||
cell_box.flags &= ~ed_focus;
|
||||
memset(edit_text, 0, 256);
|
||||
draw_grid();
|
||||
}
|
||||
|
||||
static void move_selection(int new_x, int new_y)
|
||||
{
|
||||
stop_edit();
|
||||
sel_x = new_x;
|
||||
if (sel_x < 1)
|
||||
sel_x = 1;
|
||||
if (sel_x > tbl.cols - 1)
|
||||
sel_x = tbl.cols - 1;
|
||||
sel_end_x = sel_x;
|
||||
sel_y = new_y;
|
||||
if (sel_y < 1)
|
||||
sel_y = 1;
|
||||
if (sel_y > tbl.rows - 1)
|
||||
sel_y = tbl.rows - 1;
|
||||
sel_end_y = sel_y;
|
||||
ensure_visible(sel_x, sel_y);
|
||||
draw_grid();
|
||||
}
|
||||
|
||||
// x within [low, high] (order-independent)
|
||||
static int is_between(int x, int low, int high)
|
||||
{
|
||||
return ((low < high) ? (x >= low && x <= high) : (x >= high && x <= low));
|
||||
}
|
||||
|
||||
// pixel offset of data column j / row i from the start of the data area
|
||||
static int col_left(int j) { int i, s = 0; for (i = 1; i < j; i++) s += tbl.w[i]; return s; }
|
||||
static int row_top(int i) { int k, s = 0; for (k = 1; k < i; k++) s += tbl.h[k]; return s; }
|
||||
|
||||
// fill a bar, clipped to the rectangle [cx0,cx1) x [cy0,cy1)
|
||||
static void bar_clip(int x, int y, int w, int h, int cx0, int cy0, int cx1, int cy1, uint32_t c)
|
||||
{
|
||||
if (x < cx0) { w -= cx0 - x; x = cx0; }
|
||||
if (y < cy0) { h -= cy0 - y; y = cy0; }
|
||||
if (x + w > cx1) w = cx1 - x;
|
||||
if (y + h > cy1) h = cy1 - y;
|
||||
if (w > 0 && h > 0)
|
||||
_ksys_draw_bar(x, y, w, h, c);
|
||||
}
|
||||
|
||||
// clamp scrolling to the real table bounds in pixels, then split back into
|
||||
// (first visible cell, sub-cell offset) so the last cell sits exactly flush
|
||||
static void clamp_view(void)
|
||||
{
|
||||
int max;
|
||||
|
||||
max = col_left(tbl.cols) - (grid.w - tbl.w[0]); // content - viewport
|
||||
if (max < 0) max = 0;
|
||||
if (scroll_x > max) scroll_x = max;
|
||||
if (scroll_x < 0) scroll_x = 0;
|
||||
grid.firstx = 1;
|
||||
while (grid.firstx < tbl.cols - 1 && col_left(grid.firstx + 1) <= scroll_x)
|
||||
grid.firstx++;
|
||||
off_x = scroll_x - col_left(grid.firstx);
|
||||
|
||||
max = row_top(tbl.rows) - (grid.h - tbl.h[0]);
|
||||
if (max < 0) max = 0;
|
||||
if (scroll_y > max) scroll_y = max;
|
||||
if (scroll_y < 0) scroll_y = 0;
|
||||
grid.firsty = 1;
|
||||
while (grid.firsty < tbl.rows - 1 && row_top(grid.firsty + 1) <= scroll_y)
|
||||
grid.firsty++;
|
||||
off_y = scroll_y - row_top(grid.firsty);
|
||||
}
|
||||
|
||||
static void draw_grid(void)
|
||||
{
|
||||
int i, j, sx, sy;
|
||||
int W = grid.w, H = grid.h, cw0 = tbl.w[0], ch0 = tbl.h[0];
|
||||
uint32_t bg;
|
||||
|
||||
clamp_view();
|
||||
|
||||
// screen x/y of every column/row left/top edge (-1 if off-screen).
|
||||
// off_x/off_y shift the first visible cell partly under the headers.
|
||||
sx = cw0 - off_x;
|
||||
nx = 1;
|
||||
tbl.x[0] = 0;
|
||||
for (j = 1; j < tbl.cols; j++) {
|
||||
tbl.x[j] = (j >= grid.firstx && sx < W) ? sx : -1;
|
||||
if (tbl.x[j] >= 0)
|
||||
nx = j + 1;
|
||||
if (j >= grid.firstx)
|
||||
sx += tbl.w[j];
|
||||
}
|
||||
sy = ch0 - off_y;
|
||||
ny = 1;
|
||||
tbl.y[0] = 0;
|
||||
for (i = 1; i < tbl.rows; i++) {
|
||||
tbl.y[i] = (i >= grid.firsty && sy < H) ? sy : -1;
|
||||
if (tbl.y[i] >= 0)
|
||||
ny = i + 1;
|
||||
if (i >= grid.firsty)
|
||||
sy += tbl.h[i];
|
||||
}
|
||||
|
||||
// cells (bars clipped to the data area; a half-scrolled first row/column
|
||||
// spills under the headers, which are painted on top afterwards)
|
||||
for (i = grid.firsty; i < ny; i++) {
|
||||
int cy = tbl.y[i], h = tbl.h[i];
|
||||
if (cy < 0)
|
||||
continue;
|
||||
for (j = grid.firstx; j < nx; j++) {
|
||||
int cx = tbl.x[j], w = tbl.w[j];
|
||||
char *text;
|
||||
if (cx < 0)
|
||||
continue;
|
||||
bg = CELL_COLOR;
|
||||
if (is_between(j, sel_x, sel_end_x) && is_between(i, sel_y, sel_end_y)) {
|
||||
if (i == sel_y && j == sel_x) {
|
||||
drag_x = cx + w - 4;
|
||||
drag_y = cy + h - 4;
|
||||
} else
|
||||
bg = CELL_COLOR_ACTIVE;
|
||||
}
|
||||
text = (tbl.values[j][i] && tbl.values[j][i][0] == '#') ? tbl.cells[j][i]
|
||||
: (tbl.values[j][i] && !display_formulas ? tbl.values[j][i] : tbl.cells[j][i]);
|
||||
bar_clip(cx + 1, cy + 1, w - 1, h - 1, cw0, ch0, W, H, bg);
|
||||
if (cx >= cw0 && cy >= ch0) {
|
||||
if (text)
|
||||
draw_cut_text(cx + 3, cy + h / 2 - 7, w - 7, TEXT_COLOR, text);
|
||||
if (i == sel_y && j == sel_x)
|
||||
DrawSelectedFrame(cx + 1, cy, w - 1, h + 1, TEXT_COLOR);
|
||||
else if (tbl.values[j][i] && tbl.values[j][i][0] == '#')
|
||||
draw_region(cx + 1, cy + 1, w - 1, h - 1, 0xff0000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// column headers (top band)
|
||||
_ksys_draw_bar(cw0, 0, W - cw0, ch0, HEADER_CELL_COLOR);
|
||||
for (j = grid.firstx; j < nx; j++) {
|
||||
int cx = tbl.x[j], w = tbl.w[j];
|
||||
if (cx < 0)
|
||||
continue;
|
||||
bg = is_between(j, sel_x, sel_end_x) ? HEADER_CELL_COLOR_ACTIVE : HEADER_CELL_COLOR;
|
||||
bar_clip(cx, 0, w, ch0, cw0, 0, W, ch0, bg);
|
||||
if (cx >= cw0)
|
||||
_ksys_draw_bar(cx, 0, 1, H, GRID_COLOR); // full-height column line
|
||||
def_button(cx + 5, 0, w - 10, ch0 - 1, j + COL_HEAD_BUTTON + BT_NODRAW, 0);
|
||||
if (tbl.cells[j][0] && cx + w / 2 - (int)strlen(tbl.cells[j][0]) * 4 >= cw0)
|
||||
draw_text(cx + w / 2 - strlen(tbl.cells[j][0]) * 4, ch0 / 2 - 7, 0x90, TEXT_COLOR, tbl.cells[j][0], 0);
|
||||
}
|
||||
|
||||
// row headers (left band)
|
||||
_ksys_draw_bar(0, ch0, cw0, H - ch0, HEADER_CELL_COLOR);
|
||||
for (i = grid.firsty; i < ny; i++) {
|
||||
int cy = tbl.y[i], h = tbl.h[i];
|
||||
if (cy < 0)
|
||||
continue;
|
||||
bg = is_between(i, sel_y, sel_end_y) ? HEADER_CELL_COLOR_ACTIVE : HEADER_CELL_COLOR;
|
||||
bar_clip(0, cy, cw0, h, 0, ch0, cw0, H, bg);
|
||||
if (cy >= ch0)
|
||||
_ksys_draw_bar(0, cy, W, 1, GRID_COLOR); // full-width row line
|
||||
def_button(5, cy, cw0 - 10, h - 1, i + ROW_HEAD_BUTTON + BT_NODRAW, 0);
|
||||
if (tbl.cells[0][i] && cy + h / 2 - 7 >= ch0)
|
||||
draw_text(cw0 / 2 - (int)strlen(tbl.cells[0][i]) * 4, cy + h / 2 - 7, 0x90, TEXT_COLOR, tbl.cells[0][i], 0);
|
||||
}
|
||||
|
||||
// corner
|
||||
_ksys_draw_bar(0, 0, cw0, ch0, HEADER_CELL_COLOR);
|
||||
def_button(0, 0, cw0 - 4, ch0 - 4, SELECT_ALL_BUTTON + BT_NODRAW, 0);
|
||||
|
||||
// fixed dividers between the headers and the table (independent of scroll)
|
||||
_ksys_draw_bar(cw0, 0, 1, H, GRID_COLOR);
|
||||
_ksys_draw_bar(0, ch0, W, 1, GRID_COLOR);
|
||||
|
||||
DrawScrolls();
|
||||
}
|
||||
|
||||
// very fast grid draw while resizing cells (XOR lines)
|
||||
static void draw_size_grid(void)
|
||||
{
|
||||
if (size_state == SIZE_X) {
|
||||
int x, x0, i;
|
||||
x = tbl.w[0];
|
||||
x0 = 0;
|
||||
for (i = 1; i < tbl.cols && x - x0 + tbl.w[i] < grid.w - 10; i++) {
|
||||
if (i >= grid.firstx) {
|
||||
if (i >= size_id)
|
||||
draw_line(x - x0, 0, x - x0, grid.h, 0, 1);
|
||||
} else
|
||||
x0 += tbl.w[i];
|
||||
x += tbl.w[i];
|
||||
}
|
||||
draw_line(x - x0, 0, x - x0, grid.h, 0, 1);
|
||||
} else {
|
||||
int y, y0, i;
|
||||
y = tbl.h[0];
|
||||
y0 = 0;
|
||||
for (i = 1; i < tbl.cols && y - y0 + tbl.h[i] < grid.h - 10; i++) {
|
||||
if (i >= grid.firsty) {
|
||||
if (i >= size_id)
|
||||
draw_line(0, y - y0, grid.w, y - y0, 0, 1);
|
||||
} else
|
||||
y0 += tbl.h[i];
|
||||
y += tbl.h[i];
|
||||
}
|
||||
draw_line(0, y - y0, grid.w, y - y0, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// fast draw of the selected area while dragging with the mouse
|
||||
#define DCOLOR 0
|
||||
#define DINVERT 1
|
||||
static void draw_drag(void)
|
||||
{
|
||||
int k0 = min(sel_x, sel_end_x);
|
||||
int k1 = max(sel_x, sel_end_x);
|
||||
int n0 = min(sel_y, sel_end_y);
|
||||
int n1 = max(sel_y, sel_end_y);
|
||||
|
||||
int x0 = tbl.x[k0] - 1;
|
||||
int x1 = tbl.x[k1] + tbl.w[k1] + 1;
|
||||
int y0 = tbl.y[n0] - 1;
|
||||
int y1 = tbl.y[n1] + tbl.h[n1] + 1;
|
||||
if (x0 > grid.w - 1)
|
||||
x0 = grid.w - 1;
|
||||
if (x1 > grid.w - 1)
|
||||
x1 = grid.w - 1;
|
||||
if (y0 > grid.h - 1)
|
||||
y0 = grid.h - 1;
|
||||
if (y1 > grid.h - 1)
|
||||
y1 = grid.h - 1;
|
||||
|
||||
draw_line(x0, y0, x0, y1, DCOLOR, DINVERT);
|
||||
draw_line(x0, y0, x1, y0, DCOLOR, DINVERT);
|
||||
draw_line(x1, y0, x1, y1, DCOLOR, DINVERT);
|
||||
draw_line(x0, y1, x1, y1, DCOLOR, DINVERT);
|
||||
}
|
||||
|
||||
static void draw_window(void)
|
||||
{
|
||||
ksys_thread_t info;
|
||||
int panel_y, BTX;
|
||||
|
||||
_ksys_start_draw();
|
||||
_ksys_create_window(110, 40, WND_W, WND_H, "Table " TABLE_VERSION, 0x40FFFFFF, 0x73);
|
||||
_ksys_end_draw();
|
||||
|
||||
_ksys_get_system_colors(&sc);
|
||||
|
||||
_ksys_thread_info(&info, KSYS_THIS_SLOT);
|
||||
cWidth = info.winx_size - 9;
|
||||
cHeight = info.winy_size - _ksys_get_skin_height() - 4;
|
||||
|
||||
grid.x = 0;
|
||||
grid.y = 0;
|
||||
grid.w = cWidth - SCROLL_SIZE - 1;
|
||||
grid.h = cHeight - MENU_PANEL_HEIGHT - SCROLL_SIZE;
|
||||
|
||||
if (info.window_state & 0x04)
|
||||
return; // rolled up
|
||||
|
||||
if (cWidth < 430) {
|
||||
_ksys_change_window(-1, -1, 450, -1);
|
||||
return;
|
||||
}
|
||||
if (cHeight < 250) {
|
||||
_ksys_change_window(-1, -1, -1, 300);
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_edit)
|
||||
stop_edit();
|
||||
|
||||
panel_y = cHeight - MENU_PANEL_HEIGHT + 1;
|
||||
_ksys_draw_bar(0, panel_y, cWidth, MENU_PANEL_HEIGHT - 1, sc.work_area);
|
||||
draw_text(3 + 1, panel_y + 14, 0x90, sc.work_text, sFilename, 0);
|
||||
|
||||
file_box.top = panel_y + 10;
|
||||
file_box.width = cWidth - 265;
|
||||
BTX = cWidth - 190;
|
||||
#define BTW 70
|
||||
def_button(BTX + 25, file_box.top, BTW, 21, SAVE_BUTTON, sc.work_area);
|
||||
draw_text(BTX + 25 + (BTW - (int)strlen(sSave) * 8) / 2, panel_y + 14, 0x90, sc.work_text, sSave, 0);
|
||||
def_button(BTX + 25 + BTW + 5, file_box.top, BTW, 21, LOAD_BUTTON, sc.work_area);
|
||||
draw_text(BTX + 25 + BTW + 5 + (BTW - (int)strlen(sLoad) * 8) / 2, panel_y + 14, 0x90, sc.work_text, sLoad, 0);
|
||||
|
||||
draw_grid();
|
||||
|
||||
if (is_edit)
|
||||
edit_box_draw(&cell_box);
|
||||
edit_box_draw(&file_box);
|
||||
}
|
||||
|
||||
static void process_mouse(void)
|
||||
{
|
||||
int mouse_btn, ckeys, shift;
|
||||
int mouse_x, mouse_y, i;
|
||||
ksys_pos_t mp;
|
||||
int vert = (int16_t)(_ksys_get_mouse_wheels() & 0xFFFF);
|
||||
|
||||
if (vert != 0) {
|
||||
stop_edit();
|
||||
scroll_y += vert * 60; // ~3 rows per wheel notch
|
||||
draw_grid(); // clamp_view() clamps scroll_y
|
||||
return;
|
||||
}
|
||||
|
||||
if (!size_state) { // do not handle scrollbars while selecting cells
|
||||
if (!scroll_h.delta2)
|
||||
scrollbar_v_mouse(&scroll_v);
|
||||
if (scroll_v.position != scroll_y) {
|
||||
stop_edit();
|
||||
scroll_y = scroll_v.position;
|
||||
draw_grid();
|
||||
}
|
||||
|
||||
if (!scroll_v.delta2)
|
||||
scrollbar_h_mouse(&scroll_h);
|
||||
if (scroll_h.position != scroll_x) {
|
||||
stop_edit();
|
||||
scroll_x = scroll_h.position;
|
||||
draw_grid();
|
||||
}
|
||||
}
|
||||
if (scroll_v.delta2 || scroll_h.delta2)
|
||||
return;
|
||||
|
||||
if (is_edit)
|
||||
edit_box_mouse(&cell_box);
|
||||
edit_box_mouse(&file_box);
|
||||
|
||||
mp = _ksys_get_mouse_pos(KSYS_MOUSE_WINDOW_POS);
|
||||
mouse_btn = _ksys_get_mouse_buttons();
|
||||
mouse_x = mp.x; // fn37.1 is already work-area relative
|
||||
mouse_y = mp.y;
|
||||
|
||||
if (is_edit && mouse_x >= (int)cell_box.left && mouse_x <= (int)cell_box.left + (int)cell_box.width
|
||||
&& mouse_y >= (int)cell_box.top && mouse_y <= (int)cell_box.top + 22)
|
||||
return;
|
||||
|
||||
mouse_btn &= 0x0001;
|
||||
|
||||
if (mouse_btn) {
|
||||
if (mouse_y < 0)
|
||||
return; // over header
|
||||
if (mouse_y > grid.y + grid.h)
|
||||
return;
|
||||
}
|
||||
|
||||
ckeys = _ksys_get_control_key_state();
|
||||
shift = ckeys & 0x3;
|
||||
|
||||
if (!size_state && !mouse_btn)
|
||||
return;
|
||||
if (mouse_btn && !size_state) { // LMB down
|
||||
if (mouse_x >= drag_x && mouse_x <= drag_x + 4 && mouse_y >= drag_y && mouse_y <= drag_y + 4) {
|
||||
size_state = SIZE_DRAG;
|
||||
old_end_x = sel_end_x;
|
||||
old_end_y = sel_end_y;
|
||||
} else if (mouse_y <= tbl.h[0]) {
|
||||
int kx = -1;
|
||||
for (i = 0; i < tbl.cols - 1; i++)
|
||||
if (mouse_x >= tbl.x[i] + tbl.w[i] - 5 && mouse_x <= tbl.x[i + 1] + 5) {
|
||||
kx = i;
|
||||
break;
|
||||
}
|
||||
if (kx != -1) {
|
||||
size_id = kx;
|
||||
size_state = SIZE_X;
|
||||
}
|
||||
} else if (mouse_x <= tbl.w[0]) {
|
||||
int ky = -1;
|
||||
for (i = 0; i < tbl.rows - 1; i++)
|
||||
if (mouse_y >= tbl.y[i] + tbl.h[i] - 5 && mouse_y <= tbl.y[i + 1] + 5) {
|
||||
ky = i;
|
||||
break;
|
||||
}
|
||||
if (ky != -1) {
|
||||
size_id = ky;
|
||||
size_state = SIZE_Y;
|
||||
}
|
||||
} else if (mouse_x < grid.w && mouse_y < grid.h) { // click on cell
|
||||
int kx = -1, ky = -1;
|
||||
for (i = grid.firstx; i < nx; i++)
|
||||
if (tbl.x[i] >= 0 && mouse_x >= tbl.x[i] && mouse_x <= tbl.x[i] + tbl.w[i]) {
|
||||
kx = i;
|
||||
break;
|
||||
}
|
||||
for (i = grid.firsty; i < ny; i++)
|
||||
if (tbl.y[i] >= 0 && mouse_y >= tbl.y[i] && mouse_y <= tbl.y[i] + tbl.h[i]) {
|
||||
ky = i;
|
||||
break;
|
||||
}
|
||||
if (kx != -1 && ky != -1) {
|
||||
if (!shift)
|
||||
move_selection(kx, ky);
|
||||
else {
|
||||
sel_end_x = kx;
|
||||
sel_end_y = ky;
|
||||
}
|
||||
size_state = SIZE_SELECT;
|
||||
}
|
||||
}
|
||||
if (size_state) {
|
||||
size_mouse_x = mouse_x;
|
||||
size_mouse_y = mouse_y;
|
||||
}
|
||||
return;
|
||||
} else if (!mouse_btn && size_state) {
|
||||
if (size_state == SIZE_DRAG)
|
||||
table_fill(sel_x, sel_y, sel_end_x, sel_end_y, old_end_x, old_end_y);
|
||||
|
||||
size_state = 0;
|
||||
draw_grid(); // everything shifted - refresh
|
||||
return;
|
||||
}
|
||||
if (size_state == SIZE_X && mouse_x != size_mouse_x) {
|
||||
draw_size_grid();
|
||||
tbl.w[size_id] += mouse_x - size_mouse_x;
|
||||
if (tbl.w[size_id] < 15)
|
||||
tbl.w[size_id] = 15;
|
||||
else if (tbl.w[size_id] > grid.w / 2)
|
||||
tbl.w[size_id] = grid.w / 2;
|
||||
draw_size_grid();
|
||||
}
|
||||
if (size_state == SIZE_Y && mouse_y != size_mouse_y) {
|
||||
draw_size_grid();
|
||||
tbl.h[size_id] += mouse_y - size_mouse_y;
|
||||
if (tbl.h[size_id] < 15)
|
||||
tbl.h[size_id] = 15;
|
||||
else if (tbl.h[size_id] > grid.h / 2)
|
||||
tbl.h[size_id] = grid.h / 2;
|
||||
draw_size_grid();
|
||||
}
|
||||
if ((size_state == SIZE_SELECT || size_state == SIZE_DRAG) && (mouse_x != size_mouse_x || mouse_y != size_mouse_y)) {
|
||||
int kx = -1, ky = -1;
|
||||
draw_drag();
|
||||
for (i = grid.firstx; i < nx; i++)
|
||||
if (tbl.x[i] >= 0 && mouse_x <= tbl.x[i] + tbl.w[i]) {
|
||||
kx = i;
|
||||
break;
|
||||
}
|
||||
for (i = grid.firsty; i < ny; i++)
|
||||
if (tbl.y[i] >= 0 && mouse_y <= tbl.y[i] + tbl.h[i]) {
|
||||
ky = i;
|
||||
break;
|
||||
}
|
||||
if (kx != -1)
|
||||
sel_end_x = kx;
|
||||
if (ky != -1)
|
||||
sel_end_y = ky;
|
||||
if (size_state == SIZE_DRAG) {
|
||||
if (abs(sel_end_x - sel_x) > 0)
|
||||
sel_end_y = old_end_y;
|
||||
else if (abs(sel_end_y - sel_y) > 0)
|
||||
sel_end_x = old_end_x;
|
||||
}
|
||||
draw_drag();
|
||||
}
|
||||
size_mouse_x = mouse_x;
|
||||
size_mouse_y = mouse_y;
|
||||
}
|
||||
|
||||
static void shift_selection(int dx, int dy, int shift)
|
||||
{
|
||||
if (dx != 0 && shift) {
|
||||
sel_end_x += dx;
|
||||
if (sel_end_x <= 1)
|
||||
sel_end_x = 1;
|
||||
else if (sel_end_x >= tbl.cols)
|
||||
sel_end_x = tbl.cols - 1;
|
||||
}
|
||||
if (dy != 0 && shift) {
|
||||
sel_end_y += dy;
|
||||
if (sel_end_y <= 1)
|
||||
sel_end_y = 1;
|
||||
else if (sel_end_y >= tbl.rows)
|
||||
sel_end_y = tbl.rows - 1;
|
||||
}
|
||||
if (dx || dy) {
|
||||
if (!shift) {
|
||||
if ((sel_end_x + dx) > (tbl.cols - 1)) {
|
||||
dx = 0;
|
||||
} else if ((sel_end_y + dy) > (tbl.rows - 1)) {
|
||||
dy = 0;
|
||||
} else
|
||||
move_selection(sel_x + dx, sel_y + dy);
|
||||
} else {
|
||||
stop_edit();
|
||||
draw_grid();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void process_key(void)
|
||||
{
|
||||
int ckeys, shift, ctrl;
|
||||
ksys_oskey_t k;
|
||||
int key_ascii, key_scancode;
|
||||
|
||||
ckeys = _ksys_get_control_key_state();
|
||||
shift = ckeys & 0x3;
|
||||
ctrl = ckeys & 0x0c;
|
||||
|
||||
k = _ksys_get_key();
|
||||
key_ascii = k.code;
|
||||
key_scancode = k.ctrl_key;
|
||||
|
||||
if (cell_box.flags & ed_focus) {
|
||||
if (KSYS_SCANCODE_ENTER == key_scancode) {
|
||||
stop_edit();
|
||||
draw_grid();
|
||||
} else if (KSYS_SCANCODE_ESC == key_scancode)
|
||||
cancel_edit();
|
||||
else
|
||||
edit_box_key_safe(&cell_box, k);
|
||||
} else if (file_box.flags & ed_focus) {
|
||||
edit_box_key_safe(&file_box, k);
|
||||
return;
|
||||
} else if (ctrl) {
|
||||
switch (key_scancode) {
|
||||
case KSYS_SCANCODE_A:
|
||||
EventGridSelectAll();
|
||||
break;
|
||||
case KSYS_SCANCODE_V: {
|
||||
int i, j, x0, y0, delta_x, delta_y;
|
||||
x0 = min(sel_x, sel_end_x);
|
||||
y0 = min(sel_y, sel_end_y);
|
||||
delta_x = x0 - buf_old_x;
|
||||
delta_y = y0 - buf_old_y;
|
||||
|
||||
for (i = 0; i < buf_col; i++)
|
||||
for (j = 0; j < buf_row; j++) {
|
||||
if (i + x0 >= tbl.cols || j + y0 >= tbl.rows)
|
||||
continue;
|
||||
if (tbl.cells[i + x0][j + y0])
|
||||
free(tbl.cells[i + x0][j + y0]);
|
||||
if (buffer[i][j]) {
|
||||
cf_x0 = buf_old_x;
|
||||
cf_y0 = buf_old_y;
|
||||
cf_x1 = buf_old_x + buf_col;
|
||||
cf_y1 = buf_old_y + buf_row;
|
||||
tbl.cells[i + x0][j + y0] = table_shift_formula(buffer[i][j], delta_x, delta_y);
|
||||
} else
|
||||
tbl.cells[i + x0][j + y0] = NULL;
|
||||
}
|
||||
|
||||
table_recalc();
|
||||
draw_grid();
|
||||
break;
|
||||
}
|
||||
case KSYS_SCANCODE_X:
|
||||
case KSYS_SCANCODE_C: {
|
||||
int i, j, x0, y0;
|
||||
|
||||
freeBuffer();
|
||||
|
||||
buf_col = abs(sel_end_x - sel_x) + 1;
|
||||
buf_row = abs(sel_end_y - sel_y) + 1;
|
||||
x0 = min(sel_x, sel_end_x);
|
||||
y0 = min(sel_y, sel_end_y);
|
||||
buf_old_x = x0;
|
||||
buf_old_y = y0;
|
||||
|
||||
buffer = malloc(buf_col * sizeof(char **));
|
||||
for (i = 0; i < buf_col; i++) {
|
||||
buffer[i] = malloc(buf_row * sizeof(char *));
|
||||
for (j = 0; j < buf_row; j++) {
|
||||
if (tbl.cells[i + x0][j + y0]) {
|
||||
if (KSYS_SCANCODE_C == key_scancode) {
|
||||
buffer[i][j] = malloc(strlen(tbl.cells[i + x0][j + y0]) + 1);
|
||||
strcpy(buffer[i][j], tbl.cells[i + x0][j + y0]);
|
||||
} else {
|
||||
buffer[i][j] = tbl.cells[i + x0][j + y0];
|
||||
tbl.cells[i + x0][j + y0] = NULL;
|
||||
}
|
||||
} else
|
||||
buffer[i][j] = NULL;
|
||||
}
|
||||
}
|
||||
if (key_ascii == 24)
|
||||
table_recalc();
|
||||
draw_grid();
|
||||
break;
|
||||
}
|
||||
case KSYS_SCANCODE_F:
|
||||
display_formulas = !display_formulas;
|
||||
draw_grid();
|
||||
break;
|
||||
}
|
||||
} else
|
||||
switch (key_scancode) {
|
||||
case KSYS_SCANCODE_EXT_UP:
|
||||
shift_selection(0, -1, shift);
|
||||
break;
|
||||
case KSYS_SCANCODE_EXT_LEFT:
|
||||
shift_selection(-1, 0, shift);
|
||||
break;
|
||||
case KSYS_SCANCODE_EXT_RIGHT:
|
||||
shift_selection(1, 0, shift);
|
||||
break;
|
||||
case KSYS_SCANCODE_EXT_DOWN:
|
||||
shift_selection(0, 1, shift);
|
||||
break;
|
||||
case KSYS_SCANCODE_EXT_PGDOWN:
|
||||
shift_selection(0, ny - grid.firsty - 1, shift);
|
||||
break;
|
||||
case KSYS_SCANCODE_EXT_PGUP:
|
||||
shift_selection(0, -(ny - grid.firsty), shift);
|
||||
break;
|
||||
case KSYS_SCANCODE_EXT_HOME:
|
||||
shift_selection(-sel_x + 1, 0, shift);
|
||||
break;
|
||||
case KSYS_SCANCODE_EXT_END:
|
||||
shift_selection(tbl.cols - (nx - grid.firstx) - 1 - sel_x, 0, shift);
|
||||
break;
|
||||
case KSYS_SCANCODE_EXT_DELETE: {
|
||||
int i, j;
|
||||
int n0 = min(sel_x, sel_end_x);
|
||||
int n1 = max(sel_x, sel_end_x);
|
||||
int k0 = min(sel_y, sel_end_y);
|
||||
int k1 = max(sel_y, sel_end_y);
|
||||
|
||||
for (i = n0; i <= n1; i++)
|
||||
for (j = k0; j <= k1; j++)
|
||||
if (tbl.cells[i][j]) {
|
||||
free(tbl.cells[i][j]);
|
||||
tbl.cells[i][j] = NULL;
|
||||
}
|
||||
table_recalc();
|
||||
draw_grid();
|
||||
break;
|
||||
}
|
||||
case KSYS_SCANCODE_F2:
|
||||
start_edit(sel_x, sel_y);
|
||||
break;
|
||||
case KSYS_SCANCODE_F5:
|
||||
draw_grid();
|
||||
break;
|
||||
default:
|
||||
start_edit(sel_x, sel_y);
|
||||
edit_box_key_safe(&cell_box, k);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void EventLoadFile(void)
|
||||
{
|
||||
int r;
|
||||
stop_edit();
|
||||
r = table_load(fname);
|
||||
if (r > 0) {
|
||||
table_recalc();
|
||||
draw_grid();
|
||||
} else {
|
||||
const char *result = NULL;
|
||||
if (r == -1)
|
||||
result = er_file_not_found;
|
||||
else if (r == -2)
|
||||
result = er_format;
|
||||
_ksys_exec("/sys/@notify", (char *)result);
|
||||
}
|
||||
}
|
||||
|
||||
static void EventGridSelectAll(void)
|
||||
{
|
||||
sel_y = 1;
|
||||
sel_x = 1;
|
||||
sel_end_x = tbl.cols - 1;
|
||||
sel_end_y = tbl.rows - 1;
|
||||
stop_edit();
|
||||
draw_grid();
|
||||
}
|
||||
|
||||
static void process_button(void)
|
||||
{
|
||||
uint32_t button = _ksys_get_button();
|
||||
switch (button) {
|
||||
case 1:
|
||||
_ksys_exit();
|
||||
|
||||
case NEW_BUTTON:
|
||||
table_reset();
|
||||
draw_grid();
|
||||
break;
|
||||
|
||||
case SAVE_BUTTON:
|
||||
stop_edit();
|
||||
if (table_save(fname))
|
||||
_ksys_exec("/sys/@notify", (char *)msg_save);
|
||||
else
|
||||
_ksys_exec("/sys/@notify", (char *)msg_save_error);
|
||||
break;
|
||||
|
||||
case LOAD_BUTTON:
|
||||
EventLoadFile();
|
||||
break;
|
||||
|
||||
case SELECT_ALL_BUTTON:
|
||||
EventGridSelectAll();
|
||||
break;
|
||||
}
|
||||
if (button >= COL_HEAD_BUTTON && button < ROW_HEAD_BUTTON) {
|
||||
sel_end_x = sel_x = button - COL_HEAD_BUTTON;
|
||||
sel_y = 1;
|
||||
sel_end_y = tbl.rows - 1;
|
||||
stop_edit();
|
||||
draw_grid();
|
||||
return;
|
||||
} else if (button >= ROW_HEAD_BUTTON && button < CELL_BUTTON) {
|
||||
sel_end_y = sel_y = button - ROW_HEAD_BUTTON;
|
||||
sel_x = 1;
|
||||
sel_end_x = tbl.cols - 1;
|
||||
stop_edit();
|
||||
draw_grid();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
table_init();
|
||||
if (argc > 1) {
|
||||
strcpy(fname, argv[1]);
|
||||
file_box.size = file_box.pos = strlen(fname);
|
||||
EventLoadFile();
|
||||
}
|
||||
_ksys_set_event_mask(KSYS_EVM_REDRAW | KSYS_EVM_KEY | KSYS_EVM_BUTTON | KSYS_EVM_MOUSE | KSYS_EVM_MOUSE_FILTER);
|
||||
for (;;) {
|
||||
switch (_ksys_wait_event()) {
|
||||
case KSYS_EVENT_MOUSE:
|
||||
process_mouse();
|
||||
break;
|
||||
case KSYS_EVENT_KEY:
|
||||
process_key();
|
||||
break;
|
||||
case KSYS_EVENT_BUTTON:
|
||||
process_button();
|
||||
break;
|
||||
case KSYS_EVENT_REDRAW:
|
||||
draw_window();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
|
||||
//BOX_LIB
|
||||
|
||||
typedef Dword dword;
|
||||
typedef unsigned short word;
|
||||
typedef dword __stdcall dword_func(dword);
|
||||
//typedef dword __stdcall dword3_func(dword,dword,dword);
|
||||
|
||||
dword am__ = 0x0;
|
||||
dword bm__ = 0x0;
|
||||
|
||||
char aEdit_box_draw[] = "edit_box";
|
||||
char aEdit_box_key[] = "edit_box_key";
|
||||
char aEdit_box_mouse[] = "edit_box_mouse";
|
||||
char aVersion_ed[] = "version_ed";
|
||||
|
||||
char aCheck_box_draw[] = "check_box_draw";
|
||||
char aCheck_box_mouse[] = "check_box_mouse";
|
||||
char aVersion_ch[] = "version_ch";
|
||||
|
||||
char aOption_box_draw[] = "option_box_draw";
|
||||
char aVersion_op[] = "version_op" ;
|
||||
|
||||
char aScrollbar_v_draw [] = "scrollbar_v_draw";
|
||||
char aScrollbar_v_mouse[] = "scrollbar_v_mouse";
|
||||
char aScrollbar_h_draw [] = "scrollbar_h_draw";
|
||||
char aScrollbar_h_mouse[] = "scrollbar_h_mouse";
|
||||
char aVersion_scrollbar[] = "version_scrollbar";
|
||||
|
||||
dword_func *edit_box_draw =(dword_func*) &aEdit_box_draw;
|
||||
dword_func *edit_box_key =(dword_func*) &aEdit_box_key;
|
||||
dword_func *edit_box_mouse =(dword_func*) &aEdit_box_mouse;
|
||||
|
||||
dword_func *scrollbar_v_draw = (dword_func*) &aScrollbar_v_draw;
|
||||
dword_func *scrollbar_v_mouse = (dword_func*) &aScrollbar_v_mouse;
|
||||
dword_func *scrollbar_h_draw = (dword_func*) &aScrollbar_h_draw;
|
||||
dword_func *scrollbar_h_mouse = (dword_func*) &aScrollbar_h_mouse;
|
||||
|
||||
|
||||
char lib_path[] = "/sys/lib/box_lib.obj";
|
||||
dword lib_path_addr = (dword)lib_path;
|
||||
dword dummy = 0;
|
||||
|
||||
//editbox flags
|
||||
#define ed_pass 1
|
||||
#define ed_focus 2 //focused
|
||||
#define ed_shift 4 //flag is set when Shift is pressed
|
||||
#define ed_shift_on 8
|
||||
#define ed_shift_bac 16 //bit for Shift reset, if set the smth is selected
|
||||
#define ed_left_fl 32
|
||||
#define ed_offset_fl 64
|
||||
#define ed_insert 128
|
||||
#define ed_mouse_on 256
|
||||
#define ed_mouse_adn_b 280
|
||||
#define ed_disabled 2048
|
||||
#define ed_always_focus 16384
|
||||
#define ed_figure_only 32768 //numbers only
|
||||
#define ed_shift_cl 65507
|
||||
#define ed_shift_mcl 65531
|
||||
#define ed_shift_off 65531
|
||||
#define ed_shift_on_off 65527
|
||||
#define ed_shift_bac_cl 65519
|
||||
#define ed_right_fl 65503
|
||||
#define ed_offset_cl 65471
|
||||
#define ed_insert_cl 65407
|
||||
#define ed_mouse_on_off 65279
|
||||
|
||||
struct edit_box{
|
||||
dword width,
|
||||
left,
|
||||
top,
|
||||
color,
|
||||
shift_color,
|
||||
focus_border_color,
|
||||
blur_border_color,
|
||||
text_color,
|
||||
max,
|
||||
text,
|
||||
mouse_variable,
|
||||
flags,
|
||||
size,
|
||||
pos,
|
||||
offset,
|
||||
cl_curs_x,
|
||||
cl_curs_y,
|
||||
shift,
|
||||
shift_old,
|
||||
height,
|
||||
ed_char_width;
|
||||
};
|
||||
|
||||
struct scroll_bar{
|
||||
word w,
|
||||
x,
|
||||
h,
|
||||
y;
|
||||
dword btn_height,
|
||||
type,
|
||||
max_area,
|
||||
cur_area,
|
||||
position,
|
||||
bckg_col,
|
||||
frnt_col,
|
||||
line_col,
|
||||
redraw;
|
||||
word delta,
|
||||
delta2,
|
||||
r_size_x,
|
||||
r_start_x,
|
||||
r_size_y,
|
||||
r_start_y;
|
||||
dword m_pos,
|
||||
m_pos_2,
|
||||
m_keys,
|
||||
run_size,
|
||||
position2,
|
||||
work_size,
|
||||
all_redraw,
|
||||
ar_offset;
|
||||
};
|
||||
|
||||
void load_edit_box()
|
||||
{
|
||||
kol_struct_import *k = kol_cofflib_load(lib_path);
|
||||
|
||||
if (k == NULL)
|
||||
{
|
||||
sprintf(debuf, "cannot load library %S", lib_path);
|
||||
rtlDebugOutString(debuf);
|
||||
return;
|
||||
}
|
||||
|
||||
edit_box_draw = (dword_func*)kol_cofflib_procload(k, aEdit_box_draw);
|
||||
edit_box_key = (dword_func*)kol_cofflib_procload(k, aEdit_box_key);
|
||||
edit_box_mouse = (dword_func*)kol_cofflib_procload(k, aEdit_box_mouse);
|
||||
|
||||
scrollbar_v_draw = (dword_func*)kol_cofflib_procload(k, aScrollbar_v_draw);
|
||||
scrollbar_v_mouse = (dword_func*)kol_cofflib_procload(k, aScrollbar_v_mouse);
|
||||
scrollbar_h_draw = (dword_func*)kol_cofflib_procload(k, aScrollbar_h_draw);
|
||||
scrollbar_h_mouse = (dword_func*)kol_cofflib_procload(k, aScrollbar_h_mouse);
|
||||
|
||||
if (edit_box_draw == NULL || scrollbar_v_draw == NULL || scrollbar_h_draw == NULL)
|
||||
rtlDebugOutString("Some of EDITBOX functions have not been loaded!");
|
||||
}
|
||||
Reference in new issue
Block a user