4,12 → 4,12 |
#include <sys/ksys.h> |
#include <clayer/boxlib.h> |
#include <conio.h> |
#include <math.h> |
|
#include "func.h" |
#include "parser.h" |
|
#define nullptr 0 |
#define dword unsigned int |
|
enum BUTTONS { |
BTN_QUIT = 1, |
18,9 → 18,12 |
|
const char STR_PROGRAM_TITLENAME[] = "Graph"; |
const char empty_text[] = "No function loaded. Type file name and press Enter. "; |
const char er_file_not_found[] = "Cannot open file. "; |
const char er_file_not_found[] = "Couldn't open file."; |
const char er_wrong_syntax[] = "Syntax error in file: at line %d, at byte %d."; |
const char er_invalid_graph_size[] = "Invalid graph size (look at passed x1,x2,y1,y2 graph's border coords)."; |
const char str_filename[] = "Filename:"; |
const char str_editfile[] = "Edit"; |
const char f_str[] = ". Function y="; |
const char STR_ERR_CONSOLEINIT[] = "Unable to initialize console."; |
const char STR_MSG_HELP_USAGE[] = "Usage: %s [OPTION] [FILENAME]...\n"; |
const char* STR_MSG_HELP[] = { |
55,26 → 58,39 |
#define FORMAT "%.2f%c" |
// format for two coords |
#define FORMAT_COORD "(%.2f, %.2f)%c" |
// special value to text if enough space |
#define FORMAT_TEST "0.00" |
|
#define DELTA_BIG 1.0 |
#define DELTA_SMALL 0.1 |
|
int SysColor = 0; |
double grx1, gry1, grx2, gry2; |
|
#define FUNCTS_MAXLEN_INITIAL 1 |
void** functs; // Array of addresses, first byte of struct always should describe its type |
unsigned int functs_maxlen = 0; |
unsigned int functs_count = 0; |
|
#define FUNCTS_PTYPE 0 |
#define PFUNCT_POINTS_MAXLEN_INITIAL 16 |
typedef struct { |
char type; |
double* points; |
dword point_count = 0; |
double x1, y1, x2, y2; |
char* funct = nullptr; |
unsigned int points_maxlen; |
unsigned int points_count; |
} PFunct; |
|
#define FUNCTS_ETYPE 1 |
typedef struct { |
char type; |
char* expr; |
} EFunct; |
|
char edit_path[256]; |
edit_box mybox = { 200, 92, WND_H-16-32, 0xffffff, 0x94AECE, 0, 0x808080, 0x10000000, |
sizeof(edit_path)-1, (void*)&edit_path, 0, 0, 0 }; |
|
int full_head_size; |
char* full_head; |
|
char* HugeBuf = nullptr; |
char* lasterror_text = nullptr; |
int lasterror_color; |
|
// constructor of TCoord |
TCoord coord(double x, double y) { |
101,65 → 117,74 |
return r; |
} |
|
//just for rounding... |
void DrawLine(double xs, double ys, double xe, double ye, ksys_color_t color) { |
_ksys_draw_line(roundi(xs), roundi(ys), roundi(xe), roundi(ye), color); |
} |
void DrawText(const char* text, double x, double y, uint32_t len, ksys_color_t color) { |
_ksys_draw_text(text, roundi(x), roundi(y), len, color); |
} |
|
double delta_getoptsize(int n) { |
return pow(2, n % 3) * pow(10, n / 3); |
} |
//Returns res: delta_getoptsize(res) <= size < delta_getoptsize(res+1) |
int delta_getn(double size) { |
int res = floor(log10(size) * 3); |
double t = delta_getoptsize(res + 1); |
if (t < size || isequal(t, size)) ++res; |
return res; |
} |
|
// huge function to draw all the stuff except the function itself |
void drawAxis(TCoord scrMin, TCoord scrMax, TCoord mMin, TCoord mMax) { |
TCoord cZero={0.0,0.0}, |
gMin, gMax, gZero, step; |
TCoord cZero = {0.0,0.0}, gMin, gMax, gZero, step; |
TCoord from, to; |
double i=0.0; |
int j; |
double xmin, xmin2, ymin, ymin2; |
char buf[30]=""; |
int strlentemp; |
|
double deltaBigX = delta_getoptsize(delta_getn(mMax.x - mMin.x)) / 20; |
double deltaBigY = delta_getoptsize(delta_getn(mMax.y - mMin.y)) / 20; |
double deltaSmallX = deltaBigX / 5; |
double deltaSmallY = deltaBigY / 5; |
|
// scr means Screen(bounding rect) |
// m means Mathematical |
// g means Graphic(real screen position) |
|
//_ksys_debug_puts("draw axis called\n"); |
|
//sprintf(debuf, "test: %f,%f,%f,%f\n", 123.45, 1.0, -0.9, 12.57); |
//_ksys_debug_puts(debuf); |
|
gMin = mat2Graf(mMin, scrMin, scrMax, mMin, mMax); |
gMax = mat2Graf(mMax, scrMin, scrMax, mMin, mMax); |
gZero = mat2Graf(cZero, scrMin, scrMax, mMin, mMax); |
|
// clear |
// SysColor = WHITE; |
//rectangle(di(gMin.x), di(gMin.y), di(gMax.x), di(gMax.y)); |
// ftopku |
SysColor = BLACK; |
|
SysColor = BLACK; |
// osy X |
_ksys_draw_line(gMin.x, gZero.y ,gMax.x, gZero.y, SysColor); |
// osy Y |
_ksys_draw_line(gZero.x, gMin.y, gZero.x, gMax.y, SysColor); |
DrawLine(gMin.x, gZero.y ,gMax.x, gZero.y, SysColor); // osy X |
DrawLine(gZero.x, gMin.y, gZero.x, gMax.y, SysColor); // osy Y |
|
// bounding rect |
_ksys_draw_line(gMin.x, gMin.y, gMax.x, gMin.y, SysColor); |
_ksys_draw_line(gMin.x, gMax.y, gMax.x, gMax.y, SysColor); |
DrawLine(gMin.x, gMin.y, gMax.x, gMin.y, SysColor); |
DrawLine(gMin.x, gMax.y, gMax.x, gMax.y, SysColor); |
DrawLine(gMin.x, gMin.y, gMin.x, gMax.y, SysColor); |
DrawLine(gMax.x, gMin.y, gMax.x, gMax.y, SysColor); |
|
_ksys_draw_line(gMin.x, gMin.y, gMin.x, gMax.y, SysColor); |
_ksys_draw_line(gMax.x, gMin.y, gMax.x, gMax.y, SysColor); |
|
// coords of the rect : lower left |
sprintf(buf, FORMAT_COORD, x1, y1, '\0'); |
sprintf(buf, FORMAT_COORD, grx1, gry1, '\0'); |
//_ksys_debug_puts(buf); |
strlentemp = strlen(buf); |
_ksys_draw_text(buf, gMin.x, gMin.y + textheight(buf, strlentemp), strlentemp, SysColor); |
DrawText(buf, gMin.x, gMin.y + textheight(buf, strlentemp), strlentemp, SysColor); |
// upper left |
sprintf(buf, FORMAT_COORD, x1, y2, '\0'); |
sprintf(buf, FORMAT_COORD, grx1, gry2, '\0'); |
strlentemp = strlen(buf); |
_ksys_draw_text(buf, gMin.x, gMax.y - textheight(buf, strlentemp), strlentemp, SysColor); |
DrawText(buf, gMin.x, gMax.y - textheight(buf, strlentemp), strlentemp, SysColor); |
// lower right |
sprintf(buf, FORMAT_COORD, x2, y1, '\0'); |
sprintf(buf, FORMAT_COORD, grx2, gry1, '\0'); |
strlentemp = strlen(buf); |
_ksys_draw_text(buf, gMax.x - textwidth(buf, strlentemp), gMin.y + textheight(buf, strlentemp), strlentemp, SysColor); |
DrawText(buf, gMax.x - textwidth(buf, strlentemp), gMin.y + textheight(buf, strlentemp), strlentemp, SysColor); |
// upper right |
sprintf(buf, FORMAT_COORD, x2, y2, '\0'); |
sprintf(buf, FORMAT_COORD, grx2, gry2, '\0'); |
strlentemp = strlen(buf); |
_ksys_draw_text(buf, gMax.x - textwidth(buf, strlentemp), gMax.y - textheight(buf, strlentemp), strlentemp, SysColor); |
DrawText(buf, gMax.x - textwidth(buf, strlentemp), gMax.y - textheight(buf, strlentemp), strlentemp, SysColor); |
|
//_ksys_debug_puts("some lines painted\n"); |
|
167,13 → 192,13 |
step.x = (mMax.x - mMin.x) / (scrMax.x - scrMin.x); |
step.y = (mMax.y - mMin.y) / (scrMax.y - scrMin.y); |
|
// round values |
xmin = (int)((mMin.x / DELTA_BIG) * DELTA_BIG); |
ymin = (int)((mMin.y / DELTA_BIG) * DELTA_BIG); |
//roundi values |
double xmin = round(mMin.x / deltaBigX) * deltaBigX; |
double ymin = round(mMin.y / deltaBigY) * deltaBigY; |
|
// (0,0) |
|
if ((x1 * x2 <= 0.0) && (y1 * y2 <= 0.0)) |
if ((grx1 * grx2 <= 0.0) && (gry1 * gry2 <= 0.0)) |
{ |
from.x=0.0; |
from.y=0.0; |
181,14 → 206,14 |
SysColor = BLACK; |
sprintf(buf, FORMAT, 0.0, '\0'); |
strlentemp = strlen(buf); |
_ksys_draw_text(buf, from.x - textwidth(buf, strlentemp), from.y + textheight(buf, strlentemp), strlentemp, SysColor); |
DrawText(buf, from.x - textwidth(buf, strlentemp), from.y + textheight(buf, strlentemp), strlentemp, SysColor); |
} |
|
|
// big marks on X |
//settextstyle(0, 0, 1); |
if (DELTA_BIG / step.x > THREE) { |
for (i = xmin; i <= mMax.x; i += DELTA_BIG) { |
if (deltaBigX / step.x > THREE) { |
for (i = xmin; i <= mMax.x; i += deltaBigX) { |
if (i != 0.0) { |
from.x = i; |
to.x = from.x; |
197,23 → 222,22 |
from = mat2Graf(from, scrMin, scrMax, mMin, mMax); |
to = mat2Graf(to, scrMin, scrMax, mMin, mMax); |
SysColor = BLACK; |
_ksys_draw_line(from.x, from.y, to.x, to.y, SysColor); |
DrawLine(from.x, from.y, to.x, to.y, SysColor); |
// write number |
sprintf(buf, FORMAT, i, '\0'); |
strlentemp = strlen(buf); |
// if it fits in the GAP, then write it |
if (from.y > scrMin.y && (DELTA_BIG > (textwidth(buf, strlentemp) + 1.0) * step.x)) { |
if (from.y > scrMin.y && (deltaBigX > (textwidth(buf, strlentemp) + 1.0) * step.x)) { |
SysColor = BIGFONTCOLOR; |
_ksys_draw_text(buf, from.x - textwidth(buf, strlentemp) / 2.0, to.y - textheight(buf, strlentemp), strlentemp, SysColor); |
DrawText(buf, from.x - textwidth(buf, strlentemp) / 2.0, to.y - textheight(buf, strlentemp), strlentemp, SysColor); |
} |
} |
} |
} |
//_ksys_debug_puts("big marks x painted\n"); |
|
// big marks on Y |
if (DELTA_BIG / step.y > THREE) { |
for (i = ymin; i <= mMax.y; i += DELTA_BIG) { |
if (deltaBigY / step.y > THREE) { |
for (i = ymin; i <= mMax.y; i += deltaBigY) { |
if (i != 0.0) { |
from.y = i; |
to.y = from.y; |
222,23 → 246,23 |
from = mat2Graf(from, scrMin, scrMax, mMin, mMax); |
to = mat2Graf(to, scrMin, scrMax, mMin, mMax); |
SysColor = BLACK; |
_ksys_draw_line(from.x, from.y, to.x, to.y, SysColor); |
DrawLine(from.x, from.y, to.x, to.y, SysColor); |
sprintf(buf, FORMAT, i, '\0'); |
strlentemp = strlen(buf); |
if (from.x > scrMin.x && (DELTA_BIG > textheight(buf, strlentemp) * step.y)) { |
if (from.x > scrMin.x && (deltaBigY > textheight(buf, strlentemp) * step.y)) { |
SysColor = BIGFONTCOLOR; |
_ksys_draw_text(buf, from.x + TEXT_X, to.y - textheight(buf, strlentemp) / 2.0, strlentemp, SysColor); |
DrawText(buf, from.x + TEXT_X, to.y - textheight(buf, strlentemp) / 2.0, strlentemp, SysColor); |
} |
} |
} |
} |
|
xmin2 = (int)(mMin.x / DELTA_SMALL) * DELTA_SMALL; |
ymin2 = (int)(mMin.y / DELTA_SMALL) * DELTA_SMALL; |
double xmin2 = round(mMin.x / deltaSmallX) * deltaSmallX; |
double ymin2 = round(mMin.y / deltaSmallY) * deltaSmallY; |
|
if (DELTA_SMALL / step.x > THREE) { |
j = (int)(( - xmin + xmin2 ) / DELTA_SMALL); |
for (i = xmin2; i <= mMax.x; i += DELTA_SMALL, j++) { |
if (deltaSmallX / step.x > THREE) { |
int j = roundi((-xmin + xmin2) / deltaSmallX); |
for (i = xmin2; i <= mMax.x; i += deltaSmallX, j++) { |
if (j % 10 == 0) { |
// we need to skip every tenth mark, to avoid overwriting big marks |
j = 0; |
251,12 → 275,12 |
from = mat2Graf(from, scrMin, scrMax, mMin, mMax); |
to = mat2Graf(to, scrMin, scrMax, mMin, mMax); |
SysColor = BLACK; |
_ksys_draw_line(from.x, from.y, to.x, to.y, SysColor); |
DrawLine(from.x, from.y, to.x, to.y, SysColor); |
sprintf(buf, FORMAT, i, '\0'); |
strlentemp = strlen(buf); |
if (from.y > scrMin.y && (DELTA_SMALL > textwidth(buf, strlentemp) * step.x)) { |
if (from.y > scrMin.y && (deltaSmallX > textwidth(buf, strlentemp) * step.x)) { |
SysColor = SMALLFONTCOLOR; |
_ksys_draw_text(buf, from.x - textwidth(buf, strlentemp) / 2.0, to.y - textheight(buf, strlentemp), strlentemp, SysColor); |
DrawText(buf, from.x - textwidth(buf, strlentemp) / 2.0, to.y - textheight(buf, strlentemp), strlentemp, SysColor); |
} |
|
|
265,10 → 289,10 |
} |
|
// finally small marks on Y |
if (DELTA_SMALL / step.y > THREE) { |
if (deltaSmallY / step.y > THREE) { |
//_ksys_debug_puts("really small marks y painted\n"); |
j = (int)(( - ymin + ymin2) / DELTA_SMALL); |
for (i = ymin2; i <= mMax.y; i += DELTA_SMALL, j++) { |
int j = roundi((-ymin + ymin2) / deltaSmallY); |
for (i = ymin2; i <= mMax.y; i += deltaSmallY, j++) { |
if (j % 10 == 0) { |
// we need to skip every tenth, to avoid overwriting |
j = 0; |
281,12 → 305,12 |
from = mat2Graf(from, scrMin, scrMax, mMin, mMax); |
to = mat2Graf(to, scrMin, scrMax, mMin, mMax); |
SysColor = BLACK; |
_ksys_draw_line(from.x, from.y, to.x, to.y, SysColor); |
DrawLine(from.x, from.y, to.x, to.y, SysColor); |
sprintf(buf, FORMAT, i, '\0'); |
strlentemp = strlen(buf); |
if (from.x > scrMin.x && (DELTA_SMALL > textheight(buf, strlentemp) * step.y)) { |
if (from.x > scrMin.x && (deltaSmallY > textheight(buf, strlentemp) * step.y)) { |
SysColor = SMALLFONTCOLOR; |
_ksys_draw_text(buf, from.x + TEXT_X, from.y - textheight(buf, strlentemp) / 2.0, strlentemp, SysColor); |
DrawText(buf, from.x + TEXT_X, from.y - textheight(buf, strlentemp) / 2.0, strlentemp, SysColor); |
} |
} |
} |
293,186 → 317,306 |
|
} |
|
/* |
ends fucking piece of shit |
*/ |
// returns idx: a[idx] <= x element; -1 can be returned |
int binsearchRB_xInPoints(double* a, int a_size, double x) { |
int L = -1; |
int R = a_size; |
while (R - L > 1) { |
int M = (R + L) / 2; |
if (a[2*M] <= x) // 2*M because in points array there are 2 coords: x and y |
L = M; |
else |
R = M; |
} |
return L; |
} |
|
void drawFunction( function_t fi, TCoord scrMin, TCoord scrMax, |
TCoord mMin, TCoord mMax, int color) { |
double x; |
double y; |
int firstPoint = 1; |
TCoord p, p0 = {0.0, 0.0}, step; |
int calcFunct_idx; |
|
drawAxis(scrMin, scrMax, mMin, mMax); |
int calcFunct(double x, double* res) { |
if (*(char*)functs[calcFunct_idx] == FUNCTS_ETYPE) { |
set_exp(((EFunct*)functs[calcFunct_idx])->expr, x); |
get_exp(res); // ïàðñèòü äëÿ êàæäîãî çíà÷åíèÿ õ? äà ÿ ñ óìà ñîøåë. |
return 0; |
} |
|
PFunct* pf = functs[calcFunct_idx]; |
|
if (x <= pf->points[0]) { |
return 1; // Or it better return something?? |
//*res = pf->points[1]; |
} |
if (x >= pf->points[(pf->points_count - 1) * 2]) { |
return 1; // Or it better return something?? |
//*res = pf->points[(pf->points_count - 1) * 2 + 1]; |
} |
|
int i = binsearchRB_xInPoints(pf->points, pf->points_count, x); |
*res = (x - pf->points[2 * i]) / (pf->points[2 * (i + 1)] - pf->points[2 * i]) |
* (pf->points[2 * (i + 1) + 1] - pf->points[2 * i + 1]) + pf->points[2 * i + 1]; |
return 0; |
} |
|
void drawFunction(TCoord scrMin, TCoord scrMax, TCoord mMin, TCoord mMax, int color) { |
SysColor = color; |
TCoord p, p0 = {0.0, 0.0}, step; |
step.x = (mMax.x - mMin.x) / (scrMax.x - scrMin.x); |
|
for (x = mMin.x; x < mMax.x; x += step.x) { |
y = fi(x); |
// function is defined here and gets in the range |
if (1) { // òóò áûëî óñëîâèå, ÷òî ôóíêöèÿ ïðàâèëüíî âû÷èñëåíà |
if ((y > mMin.y) && (y < mMax.y)) { |
int firstPoint = 1; |
double y; |
for (double x = mMin.x; x < mMax.x; x += step.x) { // function is defined here and gets in the range |
if (!calcFunct(x, &y)) { // óñëîâèå, ÷òî ôóíêöèÿ ïðàâèëüíî âû÷èñëåíà |
if (y > mMin.y && y < mMax.y) { |
p = mat2Graf(coord(x, y), scrMin, scrMax, mMin, mMax); |
// if it's our first point, only remember its coords |
// otherwise, draw a line from prev to current |
if (firstPoint == 0) { |
_ksys_draw_line(p0.x, p0.y, p.x, p.y, SysColor); |
DrawLine(p0.x, p0.y, p.x, p.y, SysColor); |
} else firstPoint = 0; |
p0 = p; |
} else {// too big/small |
firstPoint = 1; |
} |
else {// too big/small |
} else { // no value |
firstPoint = 1; |
} |
} |
else { // no value |
firstPoint = 1; |
} |
|
int pointsCompare(const void* a, const void* b) { |
const double aval = *(const double*)a; // first element of a |
const double bval = *(const double*)b; // first element of b |
if (isequal(aval, bval)) return 0; |
if (aval < bval) return -1; |
return 1; |
} |
|
void freeMemoryForGraphs() { |
if (functs_count) { |
for (int i = 0; i < functs_count; ++i) { |
switch (*(char*)functs[i]) { |
case FUNCTS_PTYPE: |
free(((PFunct*)functs[i])->points); |
break; |
case FUNCTS_ETYPE: |
free(((EFunct*)functs[i])->expr); |
break; |
} |
free(functs[i]); |
} |
free(functs); |
functs = nullptr; |
functs_maxlen = 0; |
functs_count = 0; |
} |
} |
|
void functsSizeChecker() { |
if (functs_maxlen <= functs_count + 1) { |
if (!functs_maxlen) { |
functs_maxlen = FUNCTS_MAXLEN_INITIAL; |
functs = (void**)malloc(sizeof(void*) * functs_maxlen); |
} else { |
functs_maxlen *= 2; |
functs = (void**)realloc(functs, sizeof(void*) * functs_maxlen); |
} |
if (!functs) exit(3); |
} |
} |
|
// èòîãîâàÿ âåðñèÿ ÷èòàëêè òåêñòîâûõ ôàéëîâ |
// NOTICE for devs: full_head must be resetted after fail of this function (on 0 ret. code) |
int load_points3() { |
ksys_bdfe_t bdfe; |
int filePointer = 0; |
freeMemoryForGraphs(); |
|
int i,j,k; |
double d; |
dword filesize, num_number; |
|
double* p2=0; |
|
// get file size |
ksys_bdfe_t bdfe; |
int rr = _ksys_file_get_info(edit_path, &bdfe); |
sprintf(debuf, "getsize: %d\n", rr); |
_ksys_debug_puts(debuf); |
if (rr != 0) { |
_ksys_draw_text((char*)er_file_not_found, 10, 10, strlen(er_file_not_found), 0x90FF0000); |
if (rr) { |
if (lasterror_text) free(lasterror_text); |
lasterror_text = (char*)malloc(sizeof(er_file_not_found)); |
if (!lasterror_text) exit(3); |
strcpy(lasterror_text, er_file_not_found); |
lasterror_color = 0x90000000; |
return 0; |
} |
unsigned int filesize = bdfe.size; |
|
filesize = bdfe.size; |
num_number = filesize / 2; |
char* HugeBuf = (char*)malloc(filesize + 1); // ðàçáèðàåì êàê ñòðîêó, îòñþäà òåðìèíàòîð '\0' |
if (!HugeBuf) exit(3); |
unsigned int countRead; |
rr = _ksys_file_read_file(edit_path, 0, filesize, HugeBuf, &countRead); |
if (countRead != filesize) exit(4); // in case if something corrupted |
HugeBuf[filesize] = '\0'; |
|
HugeBuf = (char*)malloc(filesize + 1); // ðàçáèðàåì êàê ñòðîêó, îòñþäà òåðìèíàòîð \0 |
int lineNum = 1; |
int lineStartIdx = 0; |
int borderNextCoord = 0; |
int funct_status = 0; // 0 - empty, 1 - points (can be filled), 2 - expr. (definitely finished) |
int i = 0; |
while (i < filesize) { |
if (isalpha(HugeBuf[i])) { |
if (HugeBuf[i] == '\n') { |
++lineNum; |
lineStartIdx = i + 1; |
} |
++i; |
continue; |
} |
|
for (i=0;i<filesize+1;i++) |
HugeBuf[i] = 0; |
if (HugeBuf[i] == ';') { |
if (funct_status) { |
++functs_count; |
funct_status = 0; |
} |
++i; |
continue; |
} |
|
rr = _ksys_file_read_file(edit_path, 0, filesize, HugeBuf, nullptr); |
sprintf(debuf, "read3: %d\n", rr); |
_ksys_debug_puts(debuf); |
if (borderNextCoord == 4 && HugeBuf[i] == '=' && !funct_status) { |
functsSizeChecker(); |
funct_status = 2; |
functs[functs_count] = malloc(sizeof(EFunct)); |
if (!functs[functs_count]) exit(3); |
*(char*)functs[functs_count] = FUNCTS_ETYPE; |
|
strcpy(full_head, STR_PROGRAM_TITLENAME); |
strcpy(full_head+strlen(full_head), " - "); |
strcpy(full_head+strlen(full_head), edit_path); // bad code |
|
// à òåïåðü ðàçîáðàòüñÿ â ýòîì |
|
i=0; |
k=0; |
while (i < filesize) { |
|
while (isalpha(HugeBuf[i]) && i<filesize) i++; |
if (i == filesize) break; |
if (k==4 && HugeBuf[i] == '=') { |
//sprintf(debuf,"function: %S",HugeBuf + i); |
//_ksys_debug_puts(debuf); |
// we have a function here |
//HugeBuf[0] = ' '; |
funct = HugeBuf + i + 1; |
strcpy(full_head+strlen(full_head), ". Function y="); |
strcpy(full_head+strlen(full_head), funct); |
return 1; |
EFunct* ef = functs[functs_count]; |
int efunct_len; |
for (efunct_len = 0; HugeBuf[i + 1 + efunct_len] != ';' && HugeBuf[i + 1 + efunct_len] != '\0'; ++efunct_len) {} |
ef->expr = (char*)malloc(efunct_len+1); |
if (!ef->expr) exit(3); |
strncpy(ef->expr, HugeBuf + i + 1, efunct_len); |
ef->expr[efunct_len] = '\0'; |
i += efunct_len + 1; |
continue; |
} |
|
d = convert(HugeBuf+i, &j); |
int j; |
double d = convert(HugeBuf + i, &j); |
if (d == ERROR) { |
sprintf(debuf, "Error in input file, byte %d, count %d\n", i, k); |
_ksys_debug_puts(debuf); |
_ksys_draw_text((char*)debuf, 10, 10, strlen(debuf), 0x000000); |
sprintf(debuf, er_wrong_syntax, lineNum, i-lineStartIdx+1); |
if (lasterror_text) free(lasterror_text); |
lasterror_text = (char*)malloc(strlen(debuf)+1); |
if (!lasterror_text) exit(3); |
strcpy(lasterror_text, debuf); |
lasterror_color = 0x90FF0000; |
free(HugeBuf); |
freeMemoryForGraphs(); |
return 0; |
} |
if (d == ERROR_END) { |
_ksys_debug_puts("EOF :)!\n"); |
_ksys_debug_puts("["); |
_ksys_debug_puts(STR_PROGRAM_TITLENAME); |
_ksys_debug_puts("] EOF reached.\n"); |
break; |
} |
i += j; |
|
i+=j; |
switch (k) { |
if (borderNextCoord < 4) { |
switch (borderNextCoord) { |
case 0: |
x1=d; |
grx1 = d; |
break; |
case 1: |
x2=d; |
grx2 = d; |
break; |
case 2: |
y1=d; |
gry1 = d; |
break; |
case 3: |
y2=d; |
gry2 = d; |
if (grx1 > grx2 || isequal(grx1, grx2) || gry1 > gry2 || isequal(gry1, gry2)) { |
if (lasterror_text) free(lasterror_text); |
lasterror_text = (char*)malloc(sizeof(er_invalid_graph_size)); |
if (!lasterror_text) exit(3); |
strcpy(lasterror_text, er_invalid_graph_size); |
lasterror_color = 0x90FF0000; |
free(HugeBuf); |
return 0; |
} |
break; |
default: { |
if (p2 == NULL) |
p2 = (double*)malloc(num_number * 8); |
p2[k-4]=d; |
} |
++borderNextCoord; |
} else { |
if (!funct_status) { |
functsSizeChecker(); |
funct_status = 1; |
functs[functs_count] = malloc(sizeof(PFunct)); |
if (!functs[functs_count]) exit(3); |
*(char*)functs[functs_count] = FUNCTS_PTYPE; |
((PFunct*)functs[functs_count])->points = nullptr; |
((PFunct*)functs[functs_count])->points_maxlen = 0; |
((PFunct*)functs[functs_count])->points_count = 0; |
} |
k++; |
|
PFunct* pf = functs[functs_count]; |
if (pf->points_maxlen <= pf->points_count + 1) { |
if (!pf->points_maxlen) { |
pf->points_maxlen = PFUNCT_POINTS_MAXLEN_INITIAL; |
pf->points = (double*)malloc(sizeof(double) * pf->points_maxlen); |
} else { |
pf->points_maxlen *= 2; |
pf->points = (double*)realloc(pf->points, sizeof(double) * pf->points_maxlen); |
} |
// sprintf(debuf, "(%f,%f)-(%f,%f)",x1,y1,x2,y2); |
// _ksys_debug_puts(debuf); |
point_count=(k - 4)/2; |
|
// |
points = (double*)malloc(point_count * 2 * 8); |
for (i = 0; i < point_count * 2; i++) |
points[i] = p2[i]; |
free(p2); |
// sprintf(debuf, "count: %d\n", point_count); |
// _ksys_debug_puts(debuf); |
sprintf(debuf, ". Number of points: %u.", point_count); |
strcpy(full_head+strlen(full_head), debuf); |
if (!pf->points) exit(3); |
} |
pf->points[pf->points_count++] = d; |
} |
} |
free(HugeBuf); |
HugeBuf = NULL; |
return 1; |
} |
if (funct_status) ++functs_count; |
|
// âû÷èñëèòü çàäàííóþ ôóíêöèþ èëè êóñî÷íî-ëèíåéíóþ ìåæäó òî÷êàìè |
double fu(double x) { |
int i; |
double res; |
|
if (funct) { |
set_exp(funct,x); |
get_exp(&res); // ïàðñèòü äëÿ êàæäîãî çíà÷åíèÿ õ? äà ÿ ñ óìà ñîøåë. |
return res; |
for (int f_idx = 0; f_idx < functs_count; ++f_idx) { |
if (*(char*)functs[f_idx] != FUNCTS_PTYPE) continue; |
PFunct* pf = functs[f_idx]; |
pf->points_count /= 2; |
qsort(pf->points, pf->points_count, sizeof(double)*2, pointsCompare); |
} |
|
if (point_count == 0) { |
return 0.0; |
int full_head_new_size = sizeof(STR_PROGRAM_TITLENAME)-1 + 3 + strlen(edit_path) + 1; // 3 = strlen(" - ") |
if (functs_count == 1) { |
if (*(char*)functs[0] == FUNCTS_PTYPE) { |
sprintf(debuf, ". Number of points: %u.", ((PFunct*)functs[0])->points_count); |
full_head_new_size += strlen(debuf); |
} else |
full_head_new_size += sizeof(f_str)-1 + strlen(((EFunct*)functs[0])->expr); |
} else { |
sprintf(debuf, ". Functions loaded: %u.", functs_count); |
full_head_new_size += strlen(debuf); |
} |
|
if (x <= points[0]) |
return points[1]; |
if (x >= points[(point_count-1) * 2]) |
return points[(point_count-1) * 2 + 1]; |
|
for (i = 0; i < point_count; i++) { |
if ((x >= points[2 * i]) && (x < points[2 * (i + 1)])) |
break; |
if (full_head_new_size > full_head_size) { |
free(full_head); |
full_head_size = full_head_new_size; |
full_head = (char*)malloc(full_head_size); |
if (!full_head) exit(3); |
} |
char* full_head_addr = full_head; |
strcpy(full_head_addr, STR_PROGRAM_TITLENAME); |
full_head_addr += sizeof(STR_PROGRAM_TITLENAME)-1; |
strcpy(full_head_addr, " - "); |
full_head_addr += 3; // 3 = strlen(" - ") |
strcpy(full_head_addr, edit_path); |
full_head_addr += strlen(edit_path); |
if (functs_count == 1) { |
if (*(char*)functs[0] == FUNCTS_PTYPE) |
strcpy(full_head_addr, debuf); |
else { |
strcpy(full_head_addr, f_str); |
full_head_addr += sizeof(f_str)-1; |
strcpy(full_head_addr, ((EFunct*)functs[0])->expr); |
} |
} else { |
strcpy(full_head_addr, debuf); |
} |
|
return (x - points[2 * i]) / (points[2 * (i + 1)] - points[2 * i]) |
* (points[2 * (i + 1) + 1] - points[2 * i + 1]) + points[2 * i + 1]; |
|
if (lasterror_text) { |
free(lasterror_text); |
lasterror_text = nullptr; |
} |
return 1; |
} |
|
void draw_window(void) { |
double xx0=0.0, yy0=0.0; |
|
void draw_window() { |
_ksys_start_draw(); |
_ksys_create_window(100, 80, WND_W, WND_H, full_head, 0xFFFFFF, 0x33); |
_ksys_end_draw(); |
487,10 → 631,16 |
|
if (info.window_state&0x04) return; //draw nothing if window is rolled-up |
|
if (point_count == 0 && funct == NULL) { |
_ksys_draw_text((char *)empty_text, (cWidth - 8 * strlen(empty_text))/2,cHeight/2-25, strlen(empty_text), 0x90000000); |
if (!functs_count) { |
_ksys_draw_text(empty_text, (cWidth - 8 * strlen(empty_text)) / 2, cHeight / 2 - 25, sizeof(empty_text)-1, 0x90000000); |
} else { |
drawFunction(&fu, coord(10, 20), coord(cWidth - 20, cHeight - 70), coord(x1,y1), coord(x2,y2), 0x00ff0000); |
TCoord scrMin = coord(10, 20), |
scrMax = coord(cWidth - 20, cHeight - 70), |
mMin = coord(grx1, gry1), |
mMax = coord(grx2, gry2); |
drawAxis(scrMin, scrMax, mMin, mMax); |
for (calcFunct_idx = 0; calcFunct_idx < functs_count; ++calcFunct_idx) |
drawFunction(scrMin, scrMax, mMin, mMax, 0x00ff0000); |
} |
|
_ksys_draw_text((char*)str_filename, 15, mybox.top + 4, strlen(str_filename), 0x90000000); |
499,7 → 649,12 |
|
_ksys_define_button(cWidth - 70, mybox.top, 50, 21, BTN_EDIT, 0xc0c0c0); |
_ksys_draw_text((char*)str_editfile, cWidth - 60, mybox.top + 4, 0, 0x90000000); |
|
if (lasterror_text) { |
_ksys_draw_bar(10, 10, 200, 20, 0xFFFFFF); // ôîí äëÿ ñîîáùåíèé îá îøèáêàõ |
_ksys_draw_text(lasterror_text, 10, 10, strlen(lasterror_text), lasterror_color); |
} |
} |
|
void consoleInit() { |
if (con_init()) { // Init fail |
518,7 → 673,9 |
} |
|
int main(int argc, char** argv) { |
full_head = (char*)malloc(300); |
full_head_size = sizeof(STR_PROGRAM_TITLENAME); // also with '\0' |
full_head = (char*)malloc(full_head_size); |
if (!full_head) return 3; |
strcpy(full_head, STR_PROGRAM_TITLENAME); |
|
if (argc == 2) { |
530,8 → 687,8 |
return 0; |
} else { |
strcpy(edit_path, argv[1]); |
if (load_points3()) |
draw_window(); |
mybox.size = mybox.pos = strlen(edit_path); |
load_points3(); |
} |
} else if (argc > 2) { |
consoleInit(); |
552,25 → 709,12 |
case KSYS_EVENT_KEY: { |
ksys_oskey_t kc = _ksys_get_key(); |
switch (kc.code) { |
case 0x0D: |
if (HugeBuf) { |
//sprintf(debuf, "freemem: HugeBuf = %X", HugeBuf); |
//_ksys_debug_puts(debuf); |
free(HugeBuf); // ÷òî çà áàã - ïîíÿòü íå ìîãó. |
HugeBuf = nullptr; |
funct = nullptr; |
} |
if (points) { |
//sprintf(debuf, "freemem: points = %X", points); |
//_ksys_debug_puts(debuf); |
free(points); // è òóò. íó íå îáðàùàþñü ÿ ê ýòîìó óêàçàòåëþ, òîëüêî ïàìÿòü â íåãî, ïîòîì ñíîâà âûäåëÿþ |
points = nullptr; |
} |
point_count = 0; |
_ksys_draw_bar(10, 10, 200, 20, 0xFFFFFF); // ôîí äëÿ ñîîáùåíèé îá îøèáêàõ |
if (load_points3()) |
case 0x0D: { |
int res = load_points3(); |
if (!res) strcpy(full_head, STR_PROGRAM_TITLENAME); |
draw_window(); |
break; |
} |
default: |
edit_box_key_safe(&mybox, kc); |
} |