Compare commits

...
Author SHA1 Message Date
Burer 9e6d43bc62 apps/table: draw via ksys.h wrappers instead of raw int 0x40
Test PR / Build (ru_RU) (pull_request) Successful in 1m49s
Test PR / Build (es_ES) (pull_request) Successful in 1m58s
Test PR / Build (en_US) (pull_request) Successful in 2m2s
The fn4 font flag and the fn38 XOR-line flag are just values the kernel
reads from ecx/edx, which _ksys_draw_text/_ksys_draw_line already load
from their color argument. Pack the flag into that argument and call the
wrappers, dropping the hand-written syscalls. No inline asm remains in
the program.
2026-07-23 19:48:01 +03:00
Burer 1e540592d0 apps/table: dissolve the func.c grab-bag into the right modules
Test PR / Build (ru_RU) (pull_request) Successful in 1m53s
Test PR / Build (en_US) (pull_request) Successful in 1m58s
Test PR / Build (es_ES) (pull_request) Successful in 2m5s
func.c mixed number-parsing helpers with KOS drawing helpers. Split them
by concern: convert() (+convert_error/ERROR) moves to the parser engine
(parser.c/.h, used by parser and calc); ftoa()/strnicmp() become static
in calc.c (their only user); the draw_* wrappers become static in
table.c (UI only). Drawing still needs raw syscalls (fn4 font flags, fn38
invert) that ksys.h does not wrap. Delete func.c/func.h and drop it from
the Tupfile. Also fix EventLoadFile, mangled by the LoadFile rename.
2026-07-23 19:43:22 +03:00
Burer 062896bac5 apps/table: wrap the cell model in a Table struct
Test PR / Build (ru_RU) (pull_request) Successful in 1m51s
Test PR / Build (en_US) (pull_request) Successful in 2m0s
Test PR / Build (es_ES) (pull_request) Successful in 2m3s
Group the scattered model globals (col_count/row_count/cell_w/cell_h/
cell_x/cell_y/cells/values) into a single `Table tbl`, declared in
calc.h and shared between table.c (UI) and calc.c (engine). Rename the
public model operations to table_* methods: init->table_init,
reinit->table_reset, calculate_values->table_recalc, SaveFile->table_save,
LoadFile->table_load, fill_cells->table_fill,
change_formula->table_shift_formula.
2026-07-23 19:35:17 +03:00
Burer 98c8a791c3 apps/table: order the file into clear sections
Test PR / Build (es_ES) (pull_request) Successful in 2m29s
Test PR / Build (en_US) (pull_request) Successful in 2m36s
Test PR / Build (ru_RU) (pull_request) Successful in 2m42s
The declarations were a mix of #defines, variables and structs
interleaved. Group them: constants first, then the cell model (shared
with calc.c), then UI state, then the box_lib widgets. Mark the
table-only globals static; keep the model globals extern-visible.
2026-07-23 19:21:31 +03:00
Burer 86f1f992f9 apps/table: drop dead selection-redraw state
sel_moved / sel_end_move / prev_x / prev_y / was_single_selection drove
the old partial-redraw fast path, which is gone - they were written all
over but never read. Remove them and their assignments, and fold the
now-trivial check_sel() into move_selection().
2026-07-23 19:15:38 +03:00
Burer 6d06c2abb1 apps/table: reach the last row/column and keep header dividers
Test PR / Build (ru_RU) (pull_request) Successful in 2m0s
Test PR / Build (en_US) (pull_request) Successful in 2m5s
Test PR / Build (es_ES) (pull_request) Successful in 2m9s
- Arrow keys used >= against the last index, blocking entry into the
  last column/row; use > so CZ / row 100 are reachable.
- Mouse cell hit-test scanned 0..count-1 (missing the last cell) and the
  click branch required mouse_x <= cell_x[nx-1] (the last column's left
  edge, excluding the column itself). Scan the visible range firstx..nx /
  firsty..ny and gate on the data area, so the last cell is clickable
  (also stops matching scrolled-off columns).
- The header/table divider lines were only the first cell's grid line, so
  they vanished once the first row/column scrolled under the header. Draw
  fixed dividers at x=cell_w[0] and y=cell_h[0] every frame.
2026-07-23 17:41:01 +03:00
Burer 81ed5b56c6 apps/table: make pixel scroll the primary state (fix clamp bounce)
Test PR / Build (es_ES) (pull_request) Successful in 1m55s
Test PR / Build (ru_RU) (pull_request) Successful in 2m6s
Test PR / Build (en_US) (pull_request) Successful in 2m11s
Scrolling was stored as a whole-cell index and only converted to pixels
inside clamp_view, so the scrollbar/arrows set an index the clamp then
snapped back to the flush position - the thumb bounced and the last
row/column could not be reached exactly.

Store the scroll as pixels (scroll_x/scroll_y); clamp_view clamps that
and derives grid.firstx/firsty + off_x/off_y for drawing. The scrollbar,
wheel and ensure_visible (used by selection/edit) all work in pixels, so
selecting the last cell scrolls it flush and the scrollbar no longer
rebounds.
2026-07-23 17:30:17 +03:00
Burer 00a1ead9b4 apps/table: drop dead trailing-strip clear
Test PR / Build (en_US) (pull_request) Successful in 3m2s
Test PR / Build (es_ES) (pull_request) Successful in 3m6s
Test PR / Build (ru_RU) (pull_request) Successful in 1m59s
The table is always larger than the viewport (min ~1590x1521 px vs a
smaller grid), so the cells always tile the whole data area and the
"table smaller than viewport" strip clear can never run. Remove it.
2026-07-23 17:12:10 +03:00
Burer 815235ee25 apps/table: drop the full-viewport clear to avoid redraw flicker
Test PR / Build (es_ES) (pull_request) Successful in 2m42s
Test PR / Build (en_US) (pull_request) Successful in 2m59s
Test PR / Build (ru_RU) (pull_request) Successful in 3m8s
The cells already tile the whole data area (bars + grid lines cover it),
so clearing the entire grid to white every frame only caused a visible
flash on selection moves. Redraw cells in place instead and blank just
the strip past the last cell (needed only when the table is smaller than
the viewport). Typing in a cell still touches only the edit box.
2026-07-23 17:11:21 +03:00
Burer dbbae23af5 apps/table: pixel-level scroll so the viewport sticks flush to the table
Test PR / Build (en_US) (pull_request) Successful in 2m21s
Test PR / Build (ru_RU) (pull_request) Successful in 2m27s
Test PR / Build (es_ES) (pull_request) Successful in 2m31s
Index-based scrolling could only align whole cells, leaving a gap or a
clipped last cell. Add a sub-cell pixel offset (off_x/off_y): clamp_view
now clamps the scroll in pixels and splits it into (first visible cell,
offset), so the last row/column ends exactly at the viewport edge.

draw_grid redrawn accordingly: cell bars are clipped to the data area and
the half-scrolled first row/column spills under the headers, which are
painted on top; grid lines drawn once per row/column. Drops the
now-unused DrawCell / clear_cell_slow / sel_moved fast-path.
2026-07-23 17:07:34 +03:00
Burer 05b057f9d8 apps/table: fix scroll reaching the last cell and blank trailing strips
Test PR / Build (ru_RU) (pull_request) Successful in 1m59s
Test PR / Build (es_ES) (pull_request) Successful in 2m10s
Test PR / Build (en_US) (pull_request) Successful in 2m11s
- Scrollbar max_area was count-2, one short of the clamp limit, so the
  last column/row stayed clipped at max scroll. Use count-1 so the
  scrollbar can reach the clamped end (last cell fully visible).
- Paint the strip past the last visible column/row so no stale pixels
  ("holes") show when the table is narrower/shorter than the viewport or
  the last cell does not divide the area evenly.
2026-07-23 16:48:27 +03:00
Burer 7b7a79184d apps/table: fix viewport clamp, mouse coords, save, row-100 labels
Test PR / Build (es_ES) (pull_request) Successful in 1m58s
Test PR / Build (ru_RU) (pull_request) Successful in 2m6s
Test PR / Build (en_US) (pull_request) Successful in 2m11s
- Clamp the scroll viewport to the real table bounds so the last
  row/column is reachable and enlarging the window at the scroll end no
  longer reveals empty cells past the end (bugs 1, 2).
- Mouse: fn37.1 already returns work-area coordinates, so drop the extra
  -5 / -skin_height that shifted every click up and to the left (bug 3).
- Save: stop using _ksys_file_create() - it leaves the fn70 p20
  separator byte uninitialized, corrupting the request; create/truncate
  via fn70.2 with p20=0 (bug 4).
- Render 3-digit row captions and size the grid to columns A..CZ x
  rows 1..100 (A1..CZ100).
2026-07-23 16:29:02 +03:00
Burer e62e58f520 apps/table: port from MSVC C++ to C for kos32-tcc
Test PR / Build (es_ES) (pull_request) Successful in 1m57s
Test PR / Build (ru_RU) (pull_request) Successful in 2m5s
Test PR / Build (en_US) (pull_request) Successful in 2m12s
The Linux autobuild has no MSVC and builds with CONFIG_NO_MSVC=full, so
the table (spreadsheet) app was silently skipped. Rewrite it in clean C
against the KolibriOS TCC toolchain so it builds in CI again.

- KOS API -> <sys/ksys.h> wrappers; box_lib -> <clayer/boxlib.h> with
  LIBS="-lbox_lib"; file I/O -> fn70 wrappers; strings/math/alloc -> libc.
- Split the old plumbing out: kosSyst/mcsmemm/KosFile/math2/stdafx/
  use_library.h and all *.cpp removed; new func/parser/calc/table .c/.h.
- Entry crtStartUp/kos_Main -> main(argc, argv); MSVC __asm and Windows
  type aliases dropped; clean C types (int/uint32_t) throughout.
- Tupfile.lua now uses use_tcc.lua (link_tcc + box_lib), gated on
  NO_TCC/NO_FASM. data/Tupfile.lua: TABLE moved from the NO_MSVC block
  to the TCC(+FASM) block.
- Fix latent bugs surfaced by the switch to libc malloc/strcmp: values[]
  relied on zeroed allocation; make_cell_name malloc-size precedence and
  caption leak; LoadCSV line leak; calc_callback index-0 NULL access;
  str[i-1] out-of-bounds guards; parser null-guards (if/min/max/avg) and
  divide-by-zero (rand, '/'); logic_or 1.1 -> 1.0. arctg now real (atan).
2026-07-23 16:09:55 +03:00
23 changed files with 2801 additions and 6468 deletions

No files matched your search

+1 -1
View File
@@ -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, {
-132
View File
@@ -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;
}
-26
View File
@@ -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);
};
-28
View File
@@ -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 );
+6 -4
View File
@@ -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")
-9
View File
@@ -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
View File
@@ -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);
-524
View File
@@ -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;
}
-133
View File
@@ -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
-978
View File
@@ -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();
}
-324
View File
@@ -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
-84
View File
@@ -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
}
}
-354
View File
@@ -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;
}
*/
+716
View File
@@ -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;
}
-942
View File
@@ -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;
}
+34 -72
View File
@@ -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);
-8
View File
@@ -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
-11
View 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
+993
View File
@@ -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;
}
-144
View File
@@ -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!");
}