From 781d36bc91c99cb6f475350ec4918b3f53813d8e Mon Sep 17 00:00:00 2001 From: "Kirill Lipatov (Leency)" Date: Wed, 27 Mar 2019 13:23:24 +0000 Subject: [PATCH] upload graph which is using table libraries git-svn-id: svn://kolibrios.org@7618 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/other/graph/build.bat | 9 + .../other/graph/graph_tablelib/KosFile.cpp | 132 +++ programs/other/graph/graph_tablelib/KosFile.h | 26 + programs/other/graph/graph_tablelib/MCSMEMM.H | 28 + .../other/graph/graph_tablelib/Tupfile.lua | 5 + programs/other/graph/graph_tablelib/build.bat | 9 + programs/other/graph/graph_tablelib/calc.h | 24 + programs/other/graph/graph_tablelib/func.cpp | 527 ++++++++++ programs/other/graph/graph_tablelib/func.h | 133 +++ programs/other/graph/graph_tablelib/graph.cpp | 622 +++++++++++ .../other/graph/graph_tablelib/kosSyst.cpp | 978 ++++++++++++++++++ programs/other/graph/graph_tablelib/kosSyst.h | 324 ++++++ programs/other/graph/graph_tablelib/math2.cpp | 84 ++ .../other/graph/graph_tablelib/mcsmemm.cpp | 354 +++++++ .../other/graph/graph_tablelib/parser.cpp | 942 +++++++++++++++++ programs/other/graph/graph_tablelib/parser.h | 72 ++ .../other/graph/graph_tablelib/stdafx.cpp | 8 + programs/other/graph/graph_tablelib/stdafx.h | 11 + .../other/graph/graph_tablelib/use_library.h | 144 +++ 19 files changed, 4432 insertions(+) create mode 100644 programs/other/graph/build.bat create mode 100644 programs/other/graph/graph_tablelib/KosFile.cpp create mode 100644 programs/other/graph/graph_tablelib/KosFile.h create mode 100644 programs/other/graph/graph_tablelib/MCSMEMM.H create mode 100644 programs/other/graph/graph_tablelib/Tupfile.lua create mode 100644 programs/other/graph/graph_tablelib/build.bat create mode 100644 programs/other/graph/graph_tablelib/calc.h create mode 100644 programs/other/graph/graph_tablelib/func.cpp create mode 100644 programs/other/graph/graph_tablelib/func.h create mode 100644 programs/other/graph/graph_tablelib/graph.cpp create mode 100644 programs/other/graph/graph_tablelib/kosSyst.cpp create mode 100644 programs/other/graph/graph_tablelib/kosSyst.h create mode 100644 programs/other/graph/graph_tablelib/math2.cpp create mode 100644 programs/other/graph/graph_tablelib/mcsmemm.cpp create mode 100644 programs/other/graph/graph_tablelib/parser.cpp create mode 100644 programs/other/graph/graph_tablelib/parser.h create mode 100644 programs/other/graph/graph_tablelib/stdafx.cpp create mode 100644 programs/other/graph/graph_tablelib/stdafx.h create mode 100644 programs/other/graph/graph_tablelib/use_library.h diff --git a/programs/other/graph/build.bat b/programs/other/graph/build.bat new file mode 100644 index 0000000000..9f67cb2bfb --- /dev/null +++ b/programs/other/graph/build.bat @@ -0,0 +1,9 @@ +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 \ No newline at end of file diff --git a/programs/other/graph/graph_tablelib/KosFile.cpp b/programs/other/graph/graph_tablelib/KosFile.cpp new file mode 100644 index 0000000000..ab7c2d4d75 --- /dev/null +++ b/programs/other/graph/graph_tablelib/KosFile.cpp @@ -0,0 +1,132 @@ +#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; +} + diff --git a/programs/other/graph/graph_tablelib/KosFile.h b/programs/other/graph/graph_tablelib/KosFile.h new file mode 100644 index 0000000000..5f7c18e9bc --- /dev/null +++ b/programs/other/graph/graph_tablelib/KosFile.h @@ -0,0 +1,26 @@ +#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); +}; diff --git a/programs/other/graph/graph_tablelib/MCSMEMM.H b/programs/other/graph/graph_tablelib/MCSMEMM.H new file mode 100644 index 0000000000..42d61eaadb --- /dev/null +++ b/programs/other/graph/graph_tablelib/MCSMEMM.H @@ -0,0 +1,28 @@ +// + +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 ); + + + diff --git a/programs/other/graph/graph_tablelib/Tupfile.lua b/programs/other/graph/graph_tablelib/Tupfile.lua new file mode 100644 index 0000000000..cab645c260 --- /dev/null +++ b/programs/other/graph/graph_tablelib/Tupfile.lua @@ -0,0 +1,5 @@ +if tup.getconfig("NO_MSVC") ~= "" then return end +HELPERDIR = (tup.getconfig("HELPERDIR") == "") and "../.." or tup.getconfig("HELPERDIR") +tup.include(HELPERDIR .. "/use_msvc.lua") +compile_msvc{"*.cpp"} +link_msvc("graph") diff --git a/programs/other/graph/graph_tablelib/build.bat b/programs/other/graph/graph_tablelib/build.bat new file mode 100644 index 0000000000..7ac2e47441 --- /dev/null +++ b/programs/other/graph/graph_tablelib/build.bat @@ -0,0 +1,9 @@ +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 graph.obj *.obj +@del graph +@pe2kos graph.exe graph +@del graph.exe +@del *.obj +pause \ No newline at end of file diff --git a/programs/other/graph/graph_tablelib/calc.h b/programs/other/graph/graph_tablelib/calc.h new file mode 100644 index 0000000000..0ac460c2aa --- /dev/null +++ b/programs/other/graph/graph_tablelib/calc.h @@ -0,0 +1,24 @@ + +#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(); \ No newline at end of file diff --git a/programs/other/graph/graph_tablelib/func.cpp b/programs/other/graph/graph_tablelib/func.cpp new file mode 100644 index 0000000000..782f061eb5 --- /dev/null +++ b/programs/other/graph/graph_tablelib/func.cpp @@ -0,0 +1,527 @@ + + +#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 (*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_1[]={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_1[k]) + break; + + if (val < 1.0) + { + Str[j++] = '0'; + } + + for (p = 1; p < k + 1; p++) + { + Str[j++] = '0' + di(val / double_tab_1[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; +} diff --git a/programs/other/graph/graph_tablelib/func.h b/programs/other/graph/graph_tablelib/func.h new file mode 100644 index 0000000000..d8674ee707 --- /dev/null +++ b/programs/other/graph/graph_tablelib/func.h @@ -0,0 +1,133 @@ + +#pragma once + +#include "kosSyst.h" +#include "kosFile.h" +#include "MCSMEMM.H" + +#include + + +#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); diff --git a/programs/other/graph/graph_tablelib/graph.cpp b/programs/other/graph/graph_tablelib/graph.cpp new file mode 100644 index 0000000000..b983e64ac9 --- /dev/null +++ b/programs/other/graph/graph_tablelib/graph.cpp @@ -0,0 +1,622 @@ +#include "func.h" +#include "parser.h" +#include "use_library.h" + +#ifdef AUTOBUILD +extern char params[1024]; +#endif +char params[1024];// = "/sys/1.grf"; + +const char header[] = "Graph"; +const char empty_text[] = "No function loaded. Type file name and press Enter. "; +const char er_file_not_found[] = "Cannot open file. "; +const char str_filename[]="Filename:"; +const char str_editfile[]="Edit"; + +// начальные размеры +#define WND_W 600 +#define WND_H 470 + +#define LIGHTGREEN 0xff0000 +#define WHITE 0xffffff +#define BLACK 0x0 +#define LIGHTBLUE 0x0000ff +#define LIGHTRED 0xff0000 + +// font colors +#define BIGFONTCOLOR BLACK +#define SMALLFONTCOLOR BLACK + +#define THREE 3.0 +// minimum space: 3 pixels + +#define BIG_HEIGHT 4.0 +#define SMALL_HEIGHT 2.0 +#define TEXT_X 15.0 +// numeric format for output +#define FORMAT "%f" +// format for two coords +#define FORMAT_COORD "(%f,%f)" +// special value to text if enough space +#define FORMAT_TEST "0.00" + +#define DELTA_BIG 1.0 +#define DELTA_SMALL 0.1 + +double *points; +Dword point_count = 0; +double x1,y1,x2,y2; +char *funct = NULL; + +char *full_head; + +char *HugeBuf = NULL; + +char edit_path[256]; +edit_box mybox = {0,92,WND_H-16-32,0xffffff,0x94AECE,0,0x808080,0x10000000, + sizeof(edit_path)-1,0,(dword)&edit_path, 0, 0}; + +// constructor of TCoord +TCoord coord(double x, double y) +{ + TCoord r; + r.x = x; + r.y = y; + return r; +} + +// move and scale mathematical coords to fit screen coords +TCoord mat2Graf(TCoord c, TCoord scrMin, TCoord scrMax, TCoord mMin, TCoord mMax) +{ + TCoord r; + if (c.x > mMax.x) + c.x = mMax.x; + if (c.x < mMin.x) + c.x = mMin.x; + if (c.y > mMax.y) + c.y = mMax.y; + if (c.y < mMin.y) + c.y = mMin.y; + r.x = (scrMax.x - scrMin.x) / (mMax.x - mMin.x) * (c.x - mMin.x) + scrMin.x; + r.y = (scrMax.y - scrMin.y) / (mMax.y - mMin.y) * (mMax.y - c.y) + scrMin.y; + + return r; +} + +// double-обертки +void line_d( double x1, double y1, double x2, double y2) +{ + line(di(x1), di(y1), di(x2), di(y2)); +} + +void outtextxy_d( double x, double y, char * text, int len) +{ + outtextxy(di(x), di(y), text, len); +} + +// huge function to draw all the stuff except the function itself +void drawAxis( TCoord scrMin, TCoord scrMax, TCoord mMin, TCoord mMax) +{ + TCoord cZero={0.0,0.0}, + gMin, gMax, gZero, step; + TCoord from, to; + double i=0.0; + int j; + double xmin, xmin2, ymin, ymin2; + char buf[30]=""; + + +// scr means Screen(bounding rect) +// m means Mathematical +// g means Graphic(real screen position) + + //rtlDebugOutString("draw axis called\n"); + + //format(debuf, 30, "test: %f,%f,%f,%f\n", 123.45, 1.0, -0.9, 12.57); + //rtlDebugOutString(debuf); + + gMin = mat2Graf(mMin, scrMin, scrMax, mMin, mMax); + gMax = mat2Graf(mMax, scrMin, scrMax, mMin, mMax); + gZero = mat2Graf(cZero, scrMin, scrMax, mMin, mMax); + + // clear + // setcolor(WHITE); + //rectangle(di(gMin.x), di(gMin.y), di(gMax.x), di(gMax.y)); + // ftopku + + setcolor(BLACK); + // osy X + line_d(gMin.x, gZero.y ,gMax.x, gZero.y); + // osy Y + line_d(gZero.x, gMin.y, gZero.x, gMax.y); + // bounding rect + line_d(gMin.x, gMin.y, gMax.x, gMin.y); + line_d(gMin.x, gMax.y, gMax.x, gMax.y); + + line_d(gMin.x, gMin.y, gMin.x, gMax.y); + line_d(gMax.x, gMin.y, gMax.x, gMax.y); + + // coords of the rect : lower left + format(buf, 30, FORMAT_COORD, x1, y1); + //rtlDebugOutString(buf); + outtextxy_d(gMin.x, gMin.y + textheight(buf, 20), buf, 20); + // upper left + format(buf, 30, FORMAT_COORD, x1, y2); + outtextxy_d(gMin.x, gMax.y - textheight(buf, 20), buf, 20); + // lower right + format(buf, 30, FORMAT_COORD, x2, y1); + outtextxy_d(gMax.x - textwidth(buf, 20), gMin.y + textheight(buf, 20), buf, 20); + // upper right + format(buf, 30, FORMAT_COORD, x2, y2); + outtextxy_d(gMax.x - textwidth(buf, 20), gMax.y - textheight(buf, 20), buf, 20); + + //rtlDebugOutString("some lines painted\n"); + + step.x = (mMax.x - mMin.x) / (scrMax.x - scrMin.x); + step.y = (mMax.y - mMin.y) / (scrMax.y - scrMin.y); + +// round values + xmin = id(di((mMin.x / DELTA_BIG) * DELTA_BIG)); + ymin = id(di((mMin.y / DELTA_BIG) * DELTA_BIG)); + + // (0,0) + + if ((x1 * x2 <= 0.0) && (y1 * y2 <= 0.0)) + { + from.x=0.0; + from.y=0.0; + from = mat2Graf(from, scrMin, scrMax, mMin, mMax); + setcolor(BLACK); + format(buf, 30, FORMAT, 0.0); + outtextxy_d(from.x - textwidth(buf, 20), from.y + textheight(buf, 20), buf, 20); + } + + + // big marks on X + //settextstyle(0, 0, 1); + if (DELTA_BIG / step.x > THREE) + { + for (i = xmin; i <= mMax.x; i += DELTA_BIG) + { + if (i != 0.0) + { + from.x = i; + to.x = from.x; + from.y = -BIG_HEIGHT * step.y; + to.y = BIG_HEIGHT * step.y; + from = mat2Graf(from, scrMin, scrMax, mMin, mMax); + to = mat2Graf(to, scrMin, scrMax, mMin, mMax); + setcolor(BLACK); + line_d(from.x, from.y, to.x, to.y); + // write number + format(buf, 30, FORMAT, i); + // if it fits in the GAP, then write it + if (from.y > scrMin.y && (DELTA_BIG > (textwidth(buf, 20) + 1.0) * step.x)) + { + setcolor(BIGFONTCOLOR); + outtextxy_d(from.x - textwidth(buf, 20) / 2.0, to.y - textheight(buf, 20), buf, 20); + } + } + } + } + //rtlDebugOutString("big marks x painted\n"); + + // big marks on Y + if (DELTA_BIG / step.y > THREE) + { + for (i = ymin; i <= mMax.y; i += DELTA_BIG) + { + if (i != 0.0) + { + from.y = i; + to.y = from.y; + from.x = -BIG_HEIGHT * step.x; + to.x = BIG_HEIGHT * step.x; + from = mat2Graf(from, scrMin, scrMax, mMin, mMax); + to = mat2Graf(to, scrMin, scrMax, mMin, mMax); + setcolor(BLACK); + line_d(from.x, from.y, to.x, to.y); + format(buf, 30, FORMAT, i); + if (from.x > scrMin.x && (DELTA_BIG > textheight(buf, 20) * step.y)) + { + setcolor(BIGFONTCOLOR); + outtextxy_d(from.x + TEXT_X, to.y - textheight(buf, 20) / 2.0, buf, 20); + } + } + } + } + + xmin2 = id(di(mMin.x / DELTA_SMALL)) * DELTA_SMALL; + ymin2 = id(di(mMin.y / DELTA_SMALL)) * DELTA_SMALL; + + if (DELTA_SMALL / step.x > THREE) + { + j = di((( - xmin + xmin2 ) / DELTA_SMALL)); + for (i = xmin2; i <= mMax.x; i += DELTA_SMALL, j++) + { + if (j % 10 == 0) + { + // we need to skip every tenth mark, to avoid overwriting big marks + j = 0; + continue; + } + from.x = i; + to.x = from.x; + from.y = -SMALL_HEIGHT * step.y; + to.y = SMALL_HEIGHT * step.y; + from = mat2Graf(from, scrMin, scrMax, mMin, mMax); + to = mat2Graf(to, scrMin, scrMax, mMin, mMax); + setcolor(BLACK); + line_d(from.x, from.y, to.x, to.y); + format(buf, 30, FORMAT, i); + + if (from.y > scrMin.y && (DELTA_SMALL > textwidth(buf, 20) * step.x)) + { + setcolor(SMALLFONTCOLOR); + outtextxy_d(from.x - textwidth(buf, 20) / 2.0, to.y - textheight(buf, 20), buf, 20); + } + + + } + + } + + // finally small marks on Y + if (DELTA_SMALL / step.y > THREE) + { + //rtlDebugOutString("really small marks y painted\n"); + j = di((( - ymin + ymin2) / DELTA_SMALL)); + for (i = ymin2; i <= mMax.y; i += DELTA_SMALL, j++) + { + if (j % 10 == 0) + { + // we need to skip every tenth, to avoid overwriting + j = 0; + continue; + } + from.y = i; + to.y = from.y; + from.x = -SMALL_HEIGHT * step.x; + to.x = SMALL_HEIGHT * step.x; + from = mat2Graf(from, scrMin, scrMax, mMin, mMax); + to = mat2Graf(to, scrMin, scrMax, mMin, mMax); + setcolor(BLACK); + line_d(from.x, from.y, to.x, to.y); + format(buf, 30, FORMAT, i); + if (from.x > scrMin.x && (DELTA_SMALL > textheight(buf, 20) * step.y)) + { + setcolor(SMALLFONTCOLOR); + outtextxy_d(from.x + TEXT_X, from.y - textheight(buf, 20) / 2.0, buf, 20); + } + } + } + +} + +/* + ends fucking piece of shit +*/ + +void drawFunction( function_t fi, TCoord scrMin, TCoord scrMax, + TCoord mMin, TCoord mMax, DWORD color) +{ + double x; + double y; + int firstPoint = 1; + TCoord p, p0 = {0.0, 0.0}, step; + + drawAxis(scrMin, scrMax, mMin, mMax); + + setcolor(color); + step.x = (mMax.x - mMin.x) / (scrMax.x - scrMin.x); + + for (x = mMin.x; x < mMax.x; x += step.x) + { + y = fi(x); +// function is defined here and gets in the range + if (1) // тут было условие, что функция правильно вычислена + { + if ((y > mMin.y) && (y < mMax.y)) + { + p = mat2Graf(coord(x, y), scrMin, scrMax, mMin, mMax); + // if it's our first point, only remember its coords + // otherwise, draw a line_d from prev to current + if (firstPoint == 0) + { + line_d(p0.x, p0.y, p.x, p.y); + } + else + firstPoint = 0; + + p0 = p; + } + else // too big/small + { + firstPoint = 1; + } + } + else // no value + { + firstPoint = 1; + } + } +} + +// итоговая версия читалки текстовых файлов +int load_points3() +{ + kosFileInfo fileInfo; + kosBDVK bdvk; + int filePointer = 0; + + int i,j,k; + double d; + Dword filesize, num_number; + + double *p2=0; + + // get file size + strcpy(fileInfo.fileURL,edit_path); + fileInfo.OffsetLow = 0; + fileInfo.OffsetHigh = 0; + fileInfo.dataCount = 0; + fileInfo.rwMode = 5; + fileInfo.bufferPtr = (Byte *)&bdvk; + Dword rr = kos_FileSystemAccess( &(fileInfo) ); // в CKosFile нет определения размера + sprintf(debuf, "getsize: %U\n", rr); + rtlDebugOutString(debuf); + if (rr != 0) + { + kos_WriteTextToWindow(10,10,0x90,0xFF0000,(char*)er_file_not_found,strlen(er_file_not_found)); + return 0; + } + + filesize = bdvk.size_low; + num_number = filesize / 2; + + HugeBuf = (char *)allocmem(filesize + 1); // разбираем как строку, отсюда терминатор \0 + + for (i=0;i= points[(point_count-1) * 2]) + return points[(point_count-1) * 2 + 1]; + + for (i = 0; i < point_count; i++) + { + if ((x >= points[2 * i]) && (x < points[2 * (i + 1)])) + break; + } + + return (x - points[2 * i]) / (points[2 * (i + 1)] - points[2 * i]) + * (points[2 * (i + 1) + 1] - points[2 * i + 1]) + points[2 * i + 1]; + +} + +void draw_window(void) +{ + double xx0=0.0, yy0=0.0; + + kos_WindowRedrawStatus(1); + kos_DefineAndDrawWindow(100,80,WND_W,WND_H, 0x33,0xFFFFFF,0,0,(Dword)full_head); + kos_WindowRedrawStatus(2); + + sProcessInfo info; + kos_ProcessInfo(&info, 0xFFFFFFFF); + int cWidth = info.processInfo.width - 9; + int cHeight = info.processInfo.height - kos_GetSkinHeight() - 4; + + mybox.top = cHeight - 50; + mybox.width = cWidth - mybox.left - 80; + + if (info.processInfo.status_window&0x04) return; //draw nothing if window is rolled-up + + if (point_count == 0 && funct == NULL) + { + kos_WriteTextToWindow((cWidth - 8 * strlen(empty_text))/2,cHeight/2-25,0x90, + 0x000000,(char *)empty_text,strlen(empty_text)); + } + else + { + drawFunction(&fu, coord(10, 20), coord(id(cWidth - 20), id(cHeight - 70)), + coord(x1,y1), coord(x2,y2), 0x00ff0000); + + } + + kos_WriteTextToWindow(15, mybox.top + 4, 0x90, 0x000000, (char*)str_filename, strlen(str_filename)); + + edit_box_draw((DWORD)&mybox); + + kos_DefineButton(cWidth - 70, mybox.top, 50, 21, 5, 0xc0c0c0); + kos_WriteTextToWindow(cWidth - 60, mybox.top + 4, 0x90, 0x000000, (char*)str_editfile,0); +} + +void kos_Main() +{ + kos_InitHeap(); + load_edit_box(); + full_head = (char*)allocmem(300); + strcpy(full_head, header); + if (params[0]) + { + rtlDebugOutString("launched with params"); + rtlDebugOutString((char*)params); + strcpy(edit_path, params); + mybox.size=mybox.pos=strlen(edit_path); + load_points3(); + rtlDebugOutString("data loaded.\n"); + } + mybox.flags += ed_focus; + kos_SetMaskForEvents(EVM_REDRAW + EVM_KEY + EVM_BUTTON + EVM_MOUSE + EVM_MOUSE_FILTER); + for (;;) + { + switch (kos_WaitForEvent()) + { + case EM_MOUSE_EVENT: + edit_box_mouse((dword)&mybox); + break; + case EM_KEY_PRESS: + // key pressed, read it + Dword ckeys, shift, ctrl; + dword key_editbox; + Byte key_ascii, key_scancode; + kos_GetKeys(key_editbox, key_ascii, key_scancode); + + if (SCAN_CODE_ENTER == key_scancode) + { + if (HugeBuf!=NULL) + { + //sprintf(debuf, "freemem: HugeBuf = %X", HugeBuf); + //rtlDebugOutString(debuf); + freemem((void*)HugeBuf); // что за баг - понять не могу. + HugeBuf = NULL; + funct = NULL; + } + if (points!=NULL) + { + //sprintf(debuf, "freemem: points = %X", points); + //rtlDebugOutString(debuf); + freemem((void*)points); // и тут. ну не обращаюсь я к этому указателю, только память в него + // потом снова выделяю + points = NULL; + } + point_count = 0; + kos_DrawBar(10,10,200,20,0xFFFFFF); // background for error messages + if (load_points3()) + draw_window(); + rtlDebugOutString("Enter"); + } + else + { + __asm + { + mov eax, key_editbox + } + edit_box_key((dword)&mybox); + } + break; + + case EM_BUTTON_CLICK: + Dword button; + kos_GetButtonID(button); + if (button == 1) kos_ExitApp(); + if (button == 5) { + kos_AppRun("/sys/tinypad", edit_path); + } + break; + + case EM_WINDOW_REDRAW: + draw_window(); + break; + } + } +} + diff --git a/programs/other/graph/graph_tablelib/kosSyst.cpp b/programs/other/graph/graph_tablelib/kosSyst.cpp new file mode 100644 index 0000000000..74e5a0d9a4 --- /dev/null +++ b/programs/other/graph/graph_tablelib/kosSyst.cpp @@ -0,0 +1,978 @@ +#include "kosSyst.h" +#include "func.h" +#include + +#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_2[]={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_2[k]) + break; + + if (val < 1.0) + { + Str[j++] = '0'; + } + + for (p = 1; p < k + 1; p++) + { + int d = (int)di(val / double_tab_2[k - p] - HALF) % 10; + Str[j++] = '0' + d; + val -= d * double_tab_2[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(); +} + + diff --git a/programs/other/graph/graph_tablelib/kosSyst.h b/programs/other/graph/graph_tablelib/kosSyst.h new file mode 100644 index 0000000000..0b4fc89dca --- /dev/null +++ b/programs/other/graph/graph_tablelib/kosSyst.h @@ -0,0 +1,324 @@ + +#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 \ No newline at end of file diff --git a/programs/other/graph/graph_tablelib/math2.cpp b/programs/other/graph/graph_tablelib/math2.cpp new file mode 100644 index 0000000000..dead28c58f --- /dev/null +++ b/programs/other/graph/graph_tablelib/math2.cpp @@ -0,0 +1,84 @@ +#include +#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 + } +} diff --git a/programs/other/graph/graph_tablelib/mcsmemm.cpp b/programs/other/graph/graph_tablelib/mcsmemm.cpp new file mode 100644 index 0000000000..8073a0e703 --- /dev/null +++ b/programs/other/graph/graph_tablelib/mcsmemm.cpp @@ -0,0 +1,354 @@ +// 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; +} + +*/ \ No newline at end of file diff --git a/programs/other/graph/graph_tablelib/parser.cpp b/programs/other/graph/graph_tablelib/parser.cpp new file mode 100644 index 0000000000..d11cbdbece --- /dev/null +++ b/programs/other/graph/graph_tablelib/parser.cpp @@ -0,0 +1,942 @@ + + +#include "func.h" +#include "parser.h" +//#include +//#include +//#include + +// 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