forked from KolibriOS/kolibrios
Graph (branch: tcc_current):
- Code refactoring - Optimization of code (for example, log2(n) searching) and memory usage - Some possible memory corruption fixed - Previous graph will be erased from window if error occured - Fixed bug with provided array of non-sorted points: so now you can pass points in any order - Fixed important bug with graphic rendering (big thanks to turbocat for asm rounding function) - Changed error messages; now you can see line/byte of file where syntax error is; added checking if provided frame of graph is invalid - Autochoosing of an optimal single step for both axises - Added support for reading any number of different functions. You will have to end previous function with ';' if you want to pass another one. They will be rendered on a graph in order you passed them. git-svn-id: svn://kolibrios.org@9778 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
c5ebb23061
commit
d02111da4f
@ -1,4 +1,5 @@
|
|||||||
#include "func.h"
|
#include "func.h"
|
||||||
|
#include <math.h> // For fabs()
|
||||||
|
|
||||||
char debuf[50] = "";
|
char debuf[50] = "";
|
||||||
|
|
||||||
@ -61,3 +62,7 @@ double convert(const char* s, int* len) {
|
|||||||
if (len) *len=i;
|
if (len) *len=i;
|
||||||
return sign*res;
|
return sign*res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int isequal(double a, double b) {
|
||||||
|
return fabs(a-b) < EQUALITY_VAL;
|
||||||
|
}
|
@ -13,8 +13,15 @@ typedef struct {
|
|||||||
double textwidth(const char* s, int len);
|
double textwidth(const char* s, int len);
|
||||||
double textheight(const char* s, int len);
|
double textheight(const char* s, int len);
|
||||||
|
|
||||||
typedef double (*function_t)(double);
|
|
||||||
int isalpha(char c);
|
int isalpha(char c);
|
||||||
double convert(const char* s, int* len);
|
double convert(const char* s, int* len);
|
||||||
|
|
||||||
|
static inline
|
||||||
|
int roundi(double a) {
|
||||||
|
return round(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define EQUALITY_VAL 0.000001
|
||||||
|
int isequal(double a, double b);
|
||||||
|
|
||||||
#endif /* FUNC_H */
|
#endif /* FUNC_H */
|
||||||
|
@ -4,12 +4,12 @@
|
|||||||
#include <sys/ksys.h>
|
#include <sys/ksys.h>
|
||||||
#include <clayer/boxlib.h>
|
#include <clayer/boxlib.h>
|
||||||
#include <conio.h>
|
#include <conio.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include "func.h"
|
#include "func.h"
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
|
|
||||||
#define nullptr 0
|
#define nullptr 0
|
||||||
#define dword unsigned int
|
|
||||||
|
|
||||||
enum BUTTONS {
|
enum BUTTONS {
|
||||||
BTN_QUIT = 1,
|
BTN_QUIT = 1,
|
||||||
@ -18,9 +18,12 @@ enum BUTTONS {
|
|||||||
|
|
||||||
const char STR_PROGRAM_TITLENAME[] = "Graph";
|
const char STR_PROGRAM_TITLENAME[] = "Graph";
|
||||||
const char empty_text[] = "No function loaded. Type file name and press Enter. ";
|
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_filename[] = "Filename:";
|
||||||
const char str_editfile[] = "Edit";
|
const char str_editfile[] = "Edit";
|
||||||
|
const char f_str[] = ". Function y=";
|
||||||
const char STR_ERR_CONSOLEINIT[] = "Unable to initialize console.";
|
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_USAGE[] = "Usage: %s [OPTION] [FILENAME]...\n";
|
||||||
const char* STR_MSG_HELP[] = {
|
const char* STR_MSG_HELP[] = {
|
||||||
@ -55,26 +58,39 @@ const char* STR_MSG_HELP[] = {
|
|||||||
#define FORMAT "%.2f%c"
|
#define FORMAT "%.2f%c"
|
||||||
// format for two coords
|
// format for two coords
|
||||||
#define FORMAT_COORD "(%.2f, %.2f)%c"
|
#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;
|
int SysColor = 0;
|
||||||
|
double grx1, gry1, grx2, gry2;
|
||||||
|
|
||||||
double* points;
|
#define FUNCTS_MAXLEN_INITIAL 1
|
||||||
dword point_count = 0;
|
void** functs; // Array of addresses, first byte of struct always should describe its type
|
||||||
double x1, y1, x2, y2;
|
unsigned int functs_maxlen = 0;
|
||||||
char* funct = nullptr;
|
unsigned int functs_count = 0;
|
||||||
|
|
||||||
|
#define FUNCTS_PTYPE 0
|
||||||
|
#define PFUNCT_POINTS_MAXLEN_INITIAL 16
|
||||||
|
typedef struct {
|
||||||
|
char type;
|
||||||
|
double* points;
|
||||||
|
unsigned int points_maxlen;
|
||||||
|
unsigned int points_count;
|
||||||
|
} PFunct;
|
||||||
|
|
||||||
|
#define FUNCTS_ETYPE 1
|
||||||
|
typedef struct {
|
||||||
|
char type;
|
||||||
|
char* expr;
|
||||||
|
} EFunct;
|
||||||
|
|
||||||
char edit_path[256];
|
char edit_path[256];
|
||||||
edit_box mybox = { 200, 92, WND_H-16-32, 0xffffff, 0x94AECE, 0, 0x808080, 0x10000000,
|
edit_box mybox = { 200, 92, WND_H-16-32, 0xffffff, 0x94AECE, 0, 0x808080, 0x10000000,
|
||||||
sizeof(edit_path)-1, (void*)&edit_path, 0, 0, 0 };
|
sizeof(edit_path)-1, (void*)&edit_path, 0, 0, 0 };
|
||||||
|
|
||||||
|
int full_head_size;
|
||||||
char* full_head;
|
char* full_head;
|
||||||
|
|
||||||
char* HugeBuf = nullptr;
|
char* lasterror_text = nullptr;
|
||||||
|
int lasterror_color;
|
||||||
|
|
||||||
// constructor of TCoord
|
// constructor of TCoord
|
||||||
TCoord coord(double x, double y) {
|
TCoord coord(double x, double y) {
|
||||||
@ -101,65 +117,74 @@ TCoord mat2Graf(TCoord c, TCoord scrMin, TCoord scrMax, TCoord mMin, TCoord mMax
|
|||||||
return r;
|
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
|
// huge function to draw all the stuff except the function itself
|
||||||
void drawAxis(TCoord scrMin, TCoord scrMax, TCoord mMin, TCoord mMax) {
|
void drawAxis(TCoord scrMin, TCoord scrMax, TCoord mMin, TCoord mMax) {
|
||||||
TCoord cZero={0.0,0.0},
|
TCoord cZero = {0.0,0.0}, gMin, gMax, gZero, step;
|
||||||
gMin, gMax, gZero, step;
|
|
||||||
TCoord from, to;
|
TCoord from, to;
|
||||||
double i=0.0;
|
double i = 0.0;
|
||||||
int j;
|
|
||||||
double xmin, xmin2, ymin, ymin2;
|
|
||||||
char buf[30]="";
|
char buf[30]="";
|
||||||
int strlentemp;
|
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)
|
// scr means Screen(bounding rect)
|
||||||
// m means Mathematical
|
// m means Mathematical
|
||||||
// g means Graphic(real screen position)
|
// 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);
|
gMin = mat2Graf(mMin, scrMin, scrMax, mMin, mMax);
|
||||||
gMax = mat2Graf(mMax, scrMin, scrMax, mMin, mMax);
|
gMax = mat2Graf(mMax, scrMin, scrMax, mMin, mMax);
|
||||||
gZero = mat2Graf(cZero, 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);
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
_ksys_draw_line(gMin.x, gMin.y, gMin.x, gMax.y, SysColor);
|
DrawLine(gMin.x, gZero.y ,gMax.x, gZero.y, SysColor); // osy X
|
||||||
_ksys_draw_line(gMax.x, gMin.y, gMax.x, gMax.y, SysColor);
|
DrawLine(gZero.x, gMin.y, gZero.x, gMax.y, SysColor); // osy Y
|
||||||
|
|
||||||
|
// bounding rect
|
||||||
|
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);
|
||||||
|
|
||||||
// coords of the rect : lower left
|
// coords of the rect : lower left
|
||||||
sprintf(buf, FORMAT_COORD, x1, y1, '\0');
|
sprintf(buf, FORMAT_COORD, grx1, gry1, '\0');
|
||||||
//_ksys_debug_puts(buf);
|
//_ksys_debug_puts(buf);
|
||||||
strlentemp = strlen(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
|
// upper left
|
||||||
sprintf(buf, FORMAT_COORD, x1, y2, '\0');
|
sprintf(buf, FORMAT_COORD, grx1, gry2, '\0');
|
||||||
strlentemp = strlen(buf);
|
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
|
// lower right
|
||||||
sprintf(buf, FORMAT_COORD, x2, y1, '\0');
|
sprintf(buf, FORMAT_COORD, grx2, gry1, '\0');
|
||||||
strlentemp = strlen(buf);
|
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
|
// upper right
|
||||||
sprintf(buf, FORMAT_COORD, x2, y2, '\0');
|
sprintf(buf, FORMAT_COORD, grx2, gry2, '\0');
|
||||||
strlentemp = strlen(buf);
|
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");
|
//_ksys_debug_puts("some lines painted\n");
|
||||||
|
|
||||||
@ -167,13 +192,13 @@ void drawAxis(TCoord scrMin, TCoord scrMax, TCoord mMin, TCoord mMax) {
|
|||||||
step.x = (mMax.x - mMin.x) / (scrMax.x - scrMin.x);
|
step.x = (mMax.x - mMin.x) / (scrMax.x - scrMin.x);
|
||||||
step.y = (mMax.y - mMin.y) / (scrMax.y - scrMin.y);
|
step.y = (mMax.y - mMin.y) / (scrMax.y - scrMin.y);
|
||||||
|
|
||||||
// round values
|
//roundi values
|
||||||
xmin = (int)((mMin.x / DELTA_BIG) * DELTA_BIG);
|
double xmin = round(mMin.x / deltaBigX) * deltaBigX;
|
||||||
ymin = (int)((mMin.y / DELTA_BIG) * DELTA_BIG);
|
double ymin = round(mMin.y / deltaBigY) * deltaBigY;
|
||||||
|
|
||||||
// (0,0)
|
// (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.x=0.0;
|
||||||
from.y=0.0;
|
from.y=0.0;
|
||||||
@ -181,14 +206,14 @@ void drawAxis(TCoord scrMin, TCoord scrMax, TCoord mMin, TCoord mMax) {
|
|||||||
SysColor = BLACK;
|
SysColor = BLACK;
|
||||||
sprintf(buf, FORMAT, 0.0, '\0');
|
sprintf(buf, FORMAT, 0.0, '\0');
|
||||||
strlentemp = strlen(buf);
|
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
|
// big marks on X
|
||||||
//settextstyle(0, 0, 1);
|
//settextstyle(0, 0, 1);
|
||||||
if (DELTA_BIG / step.x > THREE) {
|
if (deltaBigX / step.x > THREE) {
|
||||||
for (i = xmin; i <= mMax.x; i += DELTA_BIG) {
|
for (i = xmin; i <= mMax.x; i += deltaBigX) {
|
||||||
if (i != 0.0) {
|
if (i != 0.0) {
|
||||||
from.x = i;
|
from.x = i;
|
||||||
to.x = from.x;
|
to.x = from.x;
|
||||||
@ -197,23 +222,22 @@ void drawAxis(TCoord scrMin, TCoord scrMax, TCoord mMin, TCoord mMax) {
|
|||||||
from = mat2Graf(from, scrMin, scrMax, mMin, mMax);
|
from = mat2Graf(from, scrMin, scrMax, mMin, mMax);
|
||||||
to = mat2Graf(to, scrMin, scrMax, mMin, mMax);
|
to = mat2Graf(to, scrMin, scrMax, mMin, mMax);
|
||||||
SysColor = BLACK;
|
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
|
// write number
|
||||||
sprintf(buf, FORMAT, i, '\0');
|
sprintf(buf, FORMAT, i, '\0');
|
||||||
strlentemp = strlen(buf);
|
strlentemp = strlen(buf);
|
||||||
// if it fits in the GAP, then write it
|
// 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;
|
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
|
// big marks on Y
|
||||||
if (DELTA_BIG / step.y > THREE) {
|
if (deltaBigY / step.y > THREE) {
|
||||||
for (i = ymin; i <= mMax.y; i += DELTA_BIG) {
|
for (i = ymin; i <= mMax.y; i += deltaBigY) {
|
||||||
if (i != 0.0) {
|
if (i != 0.0) {
|
||||||
from.y = i;
|
from.y = i;
|
||||||
to.y = from.y;
|
to.y = from.y;
|
||||||
@ -222,23 +246,23 @@ void drawAxis(TCoord scrMin, TCoord scrMax, TCoord mMin, TCoord mMax) {
|
|||||||
from = mat2Graf(from, scrMin, scrMax, mMin, mMax);
|
from = mat2Graf(from, scrMin, scrMax, mMin, mMax);
|
||||||
to = mat2Graf(to, scrMin, scrMax, mMin, mMax);
|
to = mat2Graf(to, scrMin, scrMax, mMin, mMax);
|
||||||
SysColor = BLACK;
|
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');
|
sprintf(buf, FORMAT, i, '\0');
|
||||||
strlentemp = strlen(buf);
|
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;
|
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;
|
double xmin2 = round(mMin.x / deltaSmallX) * deltaSmallX;
|
||||||
ymin2 = (int)(mMin.y / DELTA_SMALL) * DELTA_SMALL;
|
double ymin2 = round(mMin.y / deltaSmallY) * deltaSmallY;
|
||||||
|
|
||||||
if (DELTA_SMALL / step.x > THREE) {
|
if (deltaSmallX / step.x > THREE) {
|
||||||
j = (int)(( - xmin + xmin2 ) / DELTA_SMALL);
|
int j = roundi((-xmin + xmin2) / deltaSmallX);
|
||||||
for (i = xmin2; i <= mMax.x; i += DELTA_SMALL, j++) {
|
for (i = xmin2; i <= mMax.x; i += deltaSmallX, j++) {
|
||||||
if (j % 10 == 0) {
|
if (j % 10 == 0) {
|
||||||
// we need to skip every tenth mark, to avoid overwriting big marks
|
// we need to skip every tenth mark, to avoid overwriting big marks
|
||||||
j = 0;
|
j = 0;
|
||||||
@ -251,12 +275,12 @@ void drawAxis(TCoord scrMin, TCoord scrMax, TCoord mMin, TCoord mMax) {
|
|||||||
from = mat2Graf(from, scrMin, scrMax, mMin, mMax);
|
from = mat2Graf(from, scrMin, scrMax, mMin, mMax);
|
||||||
to = mat2Graf(to, scrMin, scrMax, mMin, mMax);
|
to = mat2Graf(to, scrMin, scrMax, mMin, mMax);
|
||||||
SysColor = BLACK;
|
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');
|
sprintf(buf, FORMAT, i, '\0');
|
||||||
strlentemp = strlen(buf);
|
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;
|
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 @@ void drawAxis(TCoord scrMin, TCoord scrMax, TCoord mMin, TCoord mMax) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// finally small marks on Y
|
// 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");
|
//_ksys_debug_puts("really small marks y painted\n");
|
||||||
j = (int)(( - ymin + ymin2) / DELTA_SMALL);
|
int j = roundi((-ymin + ymin2) / deltaSmallY);
|
||||||
for (i = ymin2; i <= mMax.y; i += DELTA_SMALL, j++) {
|
for (i = ymin2; i <= mMax.y; i += deltaSmallY, j++) {
|
||||||
if (j % 10 == 0) {
|
if (j % 10 == 0) {
|
||||||
// we need to skip every tenth, to avoid overwriting
|
// we need to skip every tenth, to avoid overwriting
|
||||||
j = 0;
|
j = 0;
|
||||||
@ -281,198 +305,318 @@ void drawAxis(TCoord scrMin, TCoord scrMax, TCoord mMin, TCoord mMax) {
|
|||||||
from = mat2Graf(from, scrMin, scrMax, mMin, mMax);
|
from = mat2Graf(from, scrMin, scrMax, mMin, mMax);
|
||||||
to = mat2Graf(to, scrMin, scrMax, mMin, mMax);
|
to = mat2Graf(to, scrMin, scrMax, mMin, mMax);
|
||||||
SysColor = BLACK;
|
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');
|
sprintf(buf, FORMAT, i, '\0');
|
||||||
strlentemp = strlen(buf);
|
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;
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// returns idx: a[idx] <= x element; -1 can be returned
|
||||||
ends fucking piece of shit
|
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,
|
int calcFunct_idx;
|
||||||
TCoord mMin, TCoord mMax, int color) {
|
|
||||||
double x;
|
|
||||||
double y;
|
|
||||||
int firstPoint = 1;
|
|
||||||
TCoord p, p0 = {0.0, 0.0}, step;
|
|
||||||
|
|
||||||
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;
|
SysColor = color;
|
||||||
|
TCoord p, p0 = {0.0, 0.0}, step;
|
||||||
step.x = (mMax.x - mMin.x) / (scrMax.x - scrMin.x);
|
step.x = (mMax.x - mMin.x) / (scrMax.x - scrMin.x);
|
||||||
|
int firstPoint = 1;
|
||||||
for (x = mMin.x; x < mMax.x; x += step.x) {
|
double y;
|
||||||
y = fi(x);
|
for (double x = mMin.x; x < mMax.x; x += step.x) { // function is defined here and gets in the range
|
||||||
// function is defined here and gets in the range
|
if (!calcFunct(x, &y)) { // óñëîâèå, ÷òî ôóíêöèÿ ïðàâèëüíî âû÷èñëåíà
|
||||||
if (1) { // òóò áûëî óñëîâèå, ÷òî ôóíêöèÿ ïðàâèëüíî âû÷èñëåíà
|
if (y > mMin.y && y < mMax.y) {
|
||||||
if ((y > mMin.y) && (y < mMax.y)) {
|
|
||||||
p = mat2Graf(coord(x, y), scrMin, scrMax, mMin, mMax);
|
p = mat2Graf(coord(x, y), scrMin, scrMax, mMin, mMax);
|
||||||
// if it's our first point, only remember its coords
|
// if it's our first point, only remember its coords
|
||||||
// otherwise, draw a line from prev to current
|
// otherwise, draw a line from prev to current
|
||||||
if (firstPoint == 0) {
|
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;
|
} else firstPoint = 0;
|
||||||
p0 = p;
|
p0 = p;
|
||||||
|
} else {// too big/small
|
||||||
|
firstPoint = 1;
|
||||||
}
|
}
|
||||||
else {// too big/small
|
} else { // no value
|
||||||
firstPoint = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else { // no value
|
|
||||||
firstPoint = 1;
|
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() {
|
int load_points3() {
|
||||||
ksys_bdfe_t bdfe;
|
freeMemoryForGraphs();
|
||||||
int filePointer = 0;
|
|
||||||
|
|
||||||
int i,j,k;
|
|
||||||
double d;
|
|
||||||
dword filesize, num_number;
|
|
||||||
|
|
||||||
double* p2=0;
|
|
||||||
|
|
||||||
// get file size
|
// get file size
|
||||||
|
ksys_bdfe_t bdfe;
|
||||||
int rr = _ksys_file_get_info(edit_path, &bdfe);
|
int rr = _ksys_file_get_info(edit_path, &bdfe);
|
||||||
sprintf(debuf, "getsize: %d\n", rr);
|
if (rr) {
|
||||||
_ksys_debug_puts(debuf);
|
if (lasterror_text) free(lasterror_text);
|
||||||
if (rr != 0) {
|
lasterror_text = (char*)malloc(sizeof(er_file_not_found));
|
||||||
_ksys_draw_text((char*)er_file_not_found, 10, 10, strlen(er_file_not_found), 0x90FF0000);
|
if (!lasterror_text) exit(3);
|
||||||
|
strcpy(lasterror_text, er_file_not_found);
|
||||||
|
lasterror_color = 0x90000000;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
unsigned int filesize = bdfe.size;
|
||||||
|
|
||||||
filesize = bdfe.size;
|
char* HugeBuf = (char*)malloc(filesize + 1); // ðàçáèðàåì êàê ñòðîêó, îòñþäà òåðìèíàòîð '\0'
|
||||||
num_number = filesize / 2;
|
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;
|
||||||
for (i=0;i<filesize+1;i++)
|
int borderNextCoord = 0;
|
||||||
HugeBuf[i] = 0;
|
int funct_status = 0; // 0 - empty, 1 - points (can be filled), 2 - expr. (definitely finished)
|
||||||
|
int i = 0;
|
||||||
rr = _ksys_file_read_file(edit_path, 0, filesize, HugeBuf, nullptr);
|
|
||||||
sprintf(debuf, "read3: %d\n", rr);
|
|
||||||
_ksys_debug_puts(debuf);
|
|
||||||
|
|
||||||
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 (i < filesize) {
|
||||||
|
if (isalpha(HugeBuf[i])) {
|
||||||
while (isalpha(HugeBuf[i]) && i<filesize) i++;
|
if (HugeBuf[i] == '\n') {
|
||||||
if (i == filesize) break;
|
++lineNum;
|
||||||
if (k==4 && HugeBuf[i] == '=') {
|
lineStartIdx = i + 1;
|
||||||
//sprintf(debuf,"function: %S",HugeBuf + i);
|
}
|
||||||
//_ksys_debug_puts(debuf);
|
++i;
|
||||||
// we have a function here
|
continue;
|
||||||
//HugeBuf[0] = ' ';
|
|
||||||
funct = HugeBuf + i + 1;
|
|
||||||
strcpy(full_head+strlen(full_head), ". Function y=");
|
|
||||||
strcpy(full_head+strlen(full_head), funct);
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
d = convert(HugeBuf+i, &j);
|
if (HugeBuf[i] == ';') {
|
||||||
|
if (funct_status) {
|
||||||
|
++functs_count;
|
||||||
|
funct_status = 0;
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
int j;
|
||||||
|
double d = convert(HugeBuf + i, &j);
|
||||||
if (d == ERROR) {
|
if (d == ERROR) {
|
||||||
sprintf(debuf, "Error in input file, byte %d, count %d\n", i, k);
|
sprintf(debuf, er_wrong_syntax, lineNum, i-lineStartIdx+1);
|
||||||
_ksys_debug_puts(debuf);
|
if (lasterror_text) free(lasterror_text);
|
||||||
_ksys_draw_text((char*)debuf, 10, 10, strlen(debuf), 0x000000);
|
lasterror_text = (char*)malloc(strlen(debuf)+1);
|
||||||
|
if (!lasterror_text) exit(3);
|
||||||
|
strcpy(lasterror_text, debuf);
|
||||||
|
lasterror_color = 0x90FF0000;
|
||||||
|
free(HugeBuf);
|
||||||
|
freeMemoryForGraphs();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (d == ERROR_END) {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
i += j;
|
||||||
|
|
||||||
i+=j;
|
if (borderNextCoord < 4) {
|
||||||
switch (k) {
|
switch (borderNextCoord) {
|
||||||
case 0:
|
case 0:
|
||||||
x1=d;
|
grx1 = d;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
x2=d;
|
grx2 = d;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
y1=d;
|
gry1 = d;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
y2=d;
|
gry2 = d;
|
||||||
break;
|
if (grx1 > grx2 || isequal(grx1, grx2) || gry1 > gry2 || isequal(gry1, gry2)) {
|
||||||
default: {
|
if (lasterror_text) free(lasterror_text);
|
||||||
if (p2 == NULL)
|
lasterror_text = (char*)malloc(sizeof(er_invalid_graph_size));
|
||||||
p2 = (double*)malloc(num_number * 8);
|
if (!lasterror_text) exit(3);
|
||||||
p2[k-4]=d;
|
strcpy(lasterror_text, er_invalid_graph_size);
|
||||||
}
|
lasterror_color = 0x90FF0000;
|
||||||
}
|
|
||||||
k++;
|
|
||||||
}
|
|
||||||
// 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);
|
|
||||||
free(HugeBuf);
|
free(HugeBuf);
|
||||||
HugeBuf = NULL;
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
if (!pf->points) exit(3);
|
||||||
|
}
|
||||||
|
pf->points[pf->points_count++] = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(HugeBuf);
|
||||||
|
if (funct_status) ++functs_count;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (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);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lasterror_text) {
|
||||||
|
free(lasterror_text);
|
||||||
|
lasterror_text = nullptr;
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// âû÷èñëèòü çàäàííóþ ôóíêöèþ èëè êóñî÷íî-ëèíåéíóþ ìåæäó òî÷êàìè
|
void draw_window() {
|
||||||
double fu(double x) {
|
|
||||||
int i;
|
|
||||||
double res;
|
|
||||||
|
|
||||||
if (funct) {
|
|
||||||
set_exp(funct,x);
|
|
||||||
get_exp(&res); // ïàðñèòü äëÿ êàæäîãî çíà÷åíèÿ õ? äà ÿ ñ óìà ñîøåë.
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (point_count == 0) {
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (x - points[2 * i]) / (points[2 * (i + 1)] - points[2 * i])
|
|
||||||
* (points[2 * (i + 1) + 1] - points[2 * i + 1]) + points[2 * i + 1];
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw_window(void) {
|
|
||||||
double xx0=0.0, yy0=0.0;
|
|
||||||
|
|
||||||
_ksys_start_draw();
|
_ksys_start_draw();
|
||||||
_ksys_create_window(100, 80, WND_W, WND_H, full_head, 0xFFFFFF, 0x33);
|
_ksys_create_window(100, 80, WND_W, WND_H, full_head, 0xFFFFFF, 0x33);
|
||||||
_ksys_end_draw();
|
_ksys_end_draw();
|
||||||
@ -485,12 +629,18 @@ void draw_window(void) {
|
|||||||
mybox.top = cHeight - 50;
|
mybox.top = cHeight - 50;
|
||||||
mybox.width = cWidth - mybox.left - 80;
|
mybox.width = cWidth - mybox.left - 80;
|
||||||
|
|
||||||
if (info.window_state&0x04) return; //draw nothing if window is rolled-up
|
if (info.window_state & 0x04) return; //draw nothing if window is rolled-up
|
||||||
|
|
||||||
if (point_count == 0 && funct == NULL) {
|
if (!functs_count) {
|
||||||
_ksys_draw_text((char *)empty_text, (cWidth - 8 * strlen(empty_text))/2,cHeight/2-25, strlen(empty_text), 0x90000000);
|
_ksys_draw_text(empty_text, (cWidth - 8 * strlen(empty_text)) / 2, cHeight / 2 - 25, sizeof(empty_text)-1, 0x90000000);
|
||||||
} else {
|
} 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);
|
_ksys_draw_text((char*)str_filename, 15, mybox.top + 4, strlen(str_filename), 0x90000000);
|
||||||
@ -499,6 +649,11 @@ void draw_window(void) {
|
|||||||
|
|
||||||
_ksys_define_button(cWidth - 70, mybox.top, 50, 21, BTN_EDIT, 0xc0c0c0);
|
_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);
|
_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() {
|
void consoleInit() {
|
||||||
@ -518,7 +673,9 @@ void consoleExit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
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);
|
strcpy(full_head, STR_PROGRAM_TITLENAME);
|
||||||
|
|
||||||
if (argc == 2) {
|
if (argc == 2) {
|
||||||
@ -530,8 +687,8 @@ int main(int argc, char** argv) {
|
|||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
strcpy(edit_path, argv[1]);
|
strcpy(edit_path, argv[1]);
|
||||||
if (load_points3())
|
mybox.size = mybox.pos = strlen(edit_path);
|
||||||
draw_window();
|
load_points3();
|
||||||
}
|
}
|
||||||
} else if (argc > 2) {
|
} else if (argc > 2) {
|
||||||
consoleInit();
|
consoleInit();
|
||||||
@ -552,25 +709,12 @@ int main(int argc, char** argv) {
|
|||||||
case KSYS_EVENT_KEY: {
|
case KSYS_EVENT_KEY: {
|
||||||
ksys_oskey_t kc = _ksys_get_key();
|
ksys_oskey_t kc = _ksys_get_key();
|
||||||
switch (kc.code) {
|
switch (kc.code) {
|
||||||
case 0x0D:
|
case 0x0D: {
|
||||||
if (HugeBuf) {
|
int res = load_points3();
|
||||||
//sprintf(debuf, "freemem: HugeBuf = %X", HugeBuf);
|
if (!res) strcpy(full_head, STR_PROGRAM_TITLENAME);
|
||||||
//_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())
|
|
||||||
draw_window();
|
draw_window();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
edit_box_key_safe(&mybox, kc);
|
edit_box_key_safe(&mybox, kc);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <sys/ksys.h>
|
||||||
|
|
||||||
#include "func.h"
|
#include "func.h"
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
|
|
||||||
@ -15,7 +17,7 @@
|
|||||||
|
|
||||||
// error codes
|
// error codes
|
||||||
#define ERR_BADFUNCTION -1
|
#define ERR_BADFUNCTION -1
|
||||||
#define ERR_BADNUMER -2
|
#define ERR_BADNUMBER -2
|
||||||
#define ERR_GENERAL -3
|
#define ERR_GENERAL -3
|
||||||
#define ERR_NOBRACKET -4
|
#define ERR_NOBRACKET -4
|
||||||
#define ERR_BADVARIABLE -5
|
#define ERR_BADVARIABLE -5
|
||||||
@ -84,11 +86,11 @@ double cosec(double d) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
double log2_p(double d) {
|
double log2_p(double d) {
|
||||||
return log(d) / log(2);
|
return log2(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
double log10_p(double d) {
|
double log10_p(double d) {
|
||||||
return log(d) / log(10);
|
return log10(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
double log3(double d) {
|
double log3(double d) {
|
||||||
@ -167,6 +169,23 @@ int iswhite(char c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void serror(int code) {
|
void serror(int code) {
|
||||||
|
/*switch (code) {
|
||||||
|
case ERR_BADFUNCTION:
|
||||||
|
_ksys_debug_puts("ERR_BADFUNCTION\n");
|
||||||
|
break;
|
||||||
|
case ERR_BADNUMBER:
|
||||||
|
_ksys_debug_puts("ERR_BADNUMBER\n");
|
||||||
|
break;
|
||||||
|
case ERR_NOBRACKET:
|
||||||
|
_ksys_debug_puts("ERR_NOBRACKET\n");
|
||||||
|
break;
|
||||||
|
case ERR_BADVARIABLE:
|
||||||
|
_ksys_debug_puts("ERR_BADVARIABLE\n");
|
||||||
|
break;
|
||||||
|
case ERR_OVERFLOW:
|
||||||
|
_ksys_debug_puts("ERR_OVERFLOW\n");
|
||||||
|
break;
|
||||||
|
}*/
|
||||||
//TODO (vitalkrilov): for what?: "::code = code;"
|
//TODO (vitalkrilov): for what?: "::code = code;"
|
||||||
// longjmp(j, code);
|
// longjmp(j, code);
|
||||||
}
|
}
|
||||||
@ -339,7 +358,7 @@ void primitive(double* hold) {
|
|||||||
//if (sscanf(token, "%lf", hold) != 1)
|
//if (sscanf(token, "%lf", hold) != 1)
|
||||||
*hold = convert(token, nullptr);
|
*hold = convert(token, nullptr);
|
||||||
if (*hold == ERROR)
|
if (*hold == ERROR)
|
||||||
serror( ERR_BADNUMER);
|
serror( ERR_BADNUMBER);
|
||||||
get_token();
|
get_token();
|
||||||
return;
|
return;
|
||||||
case FUNCTION:
|
case FUNCTION:
|
||||||
|
Loading…
Reference in New Issue
Block a user