Created
May 6, 2016 04:59
-
-
Save bluebear94/791cc97ec94f6f6270bd0dc19f183bff to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
post-dev comment: | |
This is an image editor for the TI-89 (Titanium) that I worked on from 2012 to 2013. | |
This is its source as of May 4, 2013. | |
(taken from https://www.omnimaga.org/ti-68k-projects/kraphyko-decthyth-and-the-illusiat-12-port/15/) | |
Everything is included in one source file, since TIGCC / GCC4TI on Windows had a bug with finding | |
header files. | |
This will likely still work if you create a new GCC4TI project and apply the sprite routine fix | |
(https://github.com/debrouxl/gcc4ti/wiki/SprtRoutinesFix). | |
Don't listen to TI when they tell you not to run their AMSes on third-party emulators. | |
As indicated in the comment below, I started in 2012 (nearly 4 years ago!) | |
*/ | |
// C Source File | |
// Created 5/29/2012; 8:07:55 PM | |
/* | |
Specifiaction: | |
+------+----|----------- | |
|Offset|Size|Description | |
| 0x00|0x01|Width. | |
| 0x01|0x01|Height. | |
| 0x02| N|Pixel data (0=white, 1=light gray, 2=dark gray, 3=black) | |
Brush types: | |
0 - point | |
1 - 3x3 rect | |
2 - 5x5 rect | |
3 - 7x7 rect | |
4 - horizontal line (len=3) | |
5 - vertical line | |
6 - positively sloping line | |
7 - negatively sloping line | |
8 - 11 - same as 4 - 7, but 5 px long | |
12 - 3x3 diamond | |
13 - 5x5 diamond | |
*/ | |
#include <tigcclib.h> | |
//start | |
const char* errors[]={"DynMemAlloc Error","Failed to allocate memory","File I/O Error","Unable to open file","File Saved","File was successfully saved","Dialog Error","Unable to set up dialog","Cannot draw text","String is out of bounds"}; | |
enum ErrCodes {DMA_ERROR,MEMALLOC_FAIL,FILE_ERROR,FOPEN_FAIL,FILE_SAVED,SAVE_SUCCESS,DLG_ERROR,DLGSETUP_FAIL,DRAWTXT_ERROR,STR_OOB}; | |
enum Colors {WHITE,LGRAY,DGRAY,BLACK}; | |
enum GAttrs {GA_DRAW,GA_ROT,GA_FLIP,GA_ADD}; | |
enum Modes {M_NEW,M_OPEN}; | |
enum DitherModes {D_NONE,D_RANDOM,D_3,D_4a,D_4b}; | |
enum BrushModes {BR_PT,BR_R3,BR_R5,BR_R7,BR_HL3,BR_VL3,BR_PS3,BR_NS3,BR_HL5,BR_VL5,BR_PS5,BR_NS5,BR_D3,BR_D5}; | |
enum LineBrushOffsets {O_H,O_V,O_P,O_N}; | |
#define versString "Kraphyko 0.8_05 \200" | |
#define nameOfProgram "Kraphyko" | |
#define FNR "File name?" | |
#define GA_NORMAL GA_DRAW | |
#define GA_CYCLE GA_ROT | |
#define OPTIONS 15 | |
#define CURSOR_DELAY 900 | |
SCR_RECT* whole_scn=&(SCR_RECT){{0,0,239,127}}; | |
INT_HANDLER I1=0,I5=0; | |
char penWidth=1; | |
typedef struct { | |
void* prevl,*prevd; | |
unsigned int canUndo,isUndone; | |
} UndoInfo; | |
typedef struct { | |
void* lp, *dp; | |
unsigned int w, h; | |
} ClipBoard; | |
UndoInfo ui={NULL,NULL,0,0}; | |
ClipBoard cb={NULL,NULL,0,0}; | |
void delay(int a) //Creates a delay. | |
{ | |
short randNum; | |
// generate random numbers to slow down the program... | |
while (a-- > 0) { | |
randNum = rand() % a; | |
} | |
} | |
double sqr(double x) | |
{ | |
return x*x; | |
} | |
inline void dlgError(int title,int body) | |
{ | |
DlgMessage(errors[title],errors[body],BT_OK,BT_NONE); | |
} | |
inline void fileSaved(void) | |
{ | |
dlgError(FILE_SAVED,SAVE_SUCCESS); | |
} | |
inline void setUpBUB(void* buffer) | |
{ | |
PortSet(buffer,239,127); | |
} | |
inline int picsize(int w,int h) | |
{ | |
return ceil((float)(w*h)/4); | |
} | |
void* allocBUB(void) | |
{ | |
void* buffer=NULL; | |
if (!(buffer=calloc(LCD_SIZE,1))) | |
{ | |
dlgError(DMA_ERROR,MEMALLOC_FAIL); | |
return NULL; | |
} | |
return buffer; | |
} | |
int allocGBUB(void** lbuff,void** dbuff) | |
{ | |
if (!(*lbuff=allocBUB())) | |
{ | |
return 0; | |
} | |
if (!(*dbuff=allocBUB())) | |
{ | |
free(*lbuff); | |
return 0; | |
} | |
return 1; | |
} | |
void enableUndo(UndoInfo* p) { | |
GrayOff(); | |
SetIntVec(AUTO_INT_1,I1); | |
SetIntVec(AUTO_INT_5,I5); | |
//*v | |
p->canUndo=allocGBUB((void**)p,(void**)((char*)p+4)); | |
SetIntVec(AUTO_INT_1,DUMMY_HANDLER); | |
SetIntVec(AUTO_INT_5,DUMMY_HANDLER); | |
GrayOn(); | |
} | |
void disableUndo(UndoInfo* p) { | |
p->canUndo=0; | |
free(p->prevl); | |
free(p->prevd); | |
} | |
void GLCDSave(void* lbuff,void* dbuff) | |
{ | |
memcpy(lbuff,GrayGetPlane(LIGHT_PLANE),LCD_SIZE); | |
memcpy(dbuff,GrayGetPlane(DARK_PLANE),LCD_SIZE); | |
} | |
void GLCDRestore(void* lbuff,void* dbuff) | |
{ | |
memcpy(GrayGetPlane(LIGHT_PLANE),lbuff,LCD_SIZE); | |
memcpy(GrayGetPlane(DARK_PLANE),dbuff,LCD_SIZE); | |
} | |
void undo(UndoInfo* p) { | |
if (!p->isUndone && p->canUndo) { | |
void* l, * d; | |
allocGBUB(&l,&d); | |
GLCDSave(l,d); //save current image | |
GLCDRestore(p->prevl,p->prevd); //restore previous image | |
memcpy(p->prevl,l,LCD_SIZE); //set undo fields to current image | |
memcpy(p->prevd,d,LCD_SIZE); | |
free(l); | |
free(d); | |
p->isUndone=1; | |
} | |
} | |
void redo(UndoInfo* p) { | |
if (p->isUndone && p->canUndo) { | |
void* l, * d; | |
allocGBUB(&l,&d); | |
GLCDSave(l,d); //save previous image | |
GLCDRestore(p->prevl,p->prevd); //restore current image | |
memcpy(p->prevl,l,LCD_SIZE); //set undo fields to previous image | |
memcpy(p->prevd,d,LCD_SIZE); | |
free(l); | |
free(d); | |
p->isUndone=0; | |
} | |
} | |
void refUndo(UndoInfo* p) { | |
if (p->canUndo) { | |
GLCDSave(p->prevl,p->prevd); | |
p->isUndone=0; | |
} | |
} | |
// refUndo(&ui); | |
void resetCB(ClipBoard* c) { // Resets clipboard (clears contents). | |
if (c->lp) free(c->lp); | |
if (c->dp) free(c->dp); | |
c->lp=NULL; | |
c->dp=NULL; | |
c->w=0; | |
c->h=0; | |
} | |
void copy(ClipBoard* c,SCR_RECT* w) { | |
resetCB(c); //we don't want anything in the clipboard | |
BITMAP* b=NULL; | |
long int size=BitmapSize(w); //size of bitmap | |
b=malloc(size); //allocate memory | |
if (!b) return; //error handling | |
int i; | |
for(i=0;i<2;i++) { //for both light and dark planes | |
GraySetAMSPlane(i); | |
BitmapGet(w,b); //get the bitmap | |
void* a=malloc(size-BITMAP_HDR_SIZE); //allocate buffer for ClipBoard structure to refer toi | |
*(((void**) c + i))=a; //if (i) c->lp=a; else c->dp=a; | |
memcpy(a,b->Data,size-BITMAP_HDR_SIZE); | |
} | |
c->w=b->NumCols; | |
c->h=b->NumRows; | |
free(b); | |
} | |
SCR_RECT NormalizeScrRect(SCR_RECT raw) { | |
unsigned char x=raw.xy.x0,y=raw.xy.y0,a=raw.xy.x1,b=raw.xy.y1; | |
return (SCR_RECT){{min(x,a),min(y,b),max(x,a),max(y,b)}}; | |
} | |
void DrawStr2(int x,int y, const char* str,short Attr) | |
{ | |
if (Attr!=A_REVERSE) | |
{ | |
DrawStr(x,y,str,Attr); | |
} | |
else | |
{ | |
ScrRectFill(whole_scn,whole_scn,A_XOR); | |
DrawStr(x,y,str,A_NORMAL); | |
ScrRectFill(whole_scn,whole_scn,A_XOR); | |
} | |
} | |
short GetGPix(short x, short y) | |
{ | |
GraySetAMSPlane(LIGHT_PLANE); | |
int color=GetPix(x,y); | |
GraySetAMSPlane(DARK_PLANE); | |
return color+2*GetPix(x,y); | |
} | |
void DrawClipPixAttr(x,y,attr) | |
{ | |
SetCurAttr(attr); DrawClipPix(x,y); | |
} | |
void DrawGPix(short x, short y, short color, short attr) | |
{ | |
int col; | |
if (attr) | |
col=GetGPix(x,y); | |
switch (attr) | |
{ | |
case GA_DRAW: | |
GraySetAMSPlane(LIGHT_PLANE); | |
DrawClipPixAttr(x,y,(color&1)); | |
GraySetAMSPlane(DARK_PLANE); | |
DrawClipPixAttr(x,y,(color&2)/2); | |
break; | |
case GA_ROT: | |
DrawGPix(x,y,(col+color)%4,GA_DRAW); | |
break; | |
case GA_FLIP: | |
DrawGPix(x,y,3-col,GA_DRAW); | |
} | |
} | |
void DrawGLine(short x0, short y0, short x1, short y1, short color, short attr) | |
{ | |
if (attr==GA_ROT) | |
{ | |
int d=sqrt(sqr(x1-x0)+sqr(y1-y0)); | |
float i; | |
int x,y,a=0,b=0; | |
for(i=0;i<=d;i+=.5) | |
{ | |
x=(float)x0*(1-(float)i/(float)d)+(float)x1*((float)i/(float)d); | |
y=(float)y0*(1-(float)i/(float)d)+(float)y1*((float)i/(float)d); | |
if ((a!=x || b!=y)&&(x>=0&&y>=0&&y<whole_scn->xy.y1&&x<whole_scn->xy.x1)) DrawGPix(x,y,color,GA_ROT); | |
a=x; | |
b=y; | |
} | |
} | |
else | |
{ | |
WIN_RECT line={x0,y0,x1,y1}; | |
switch (attr) | |
{ | |
case GA_ADD: | |
GraySetAMSPlane(LIGHT_PLANE); | |
if (color&1) DrawClipLine(&line,whole_scn,A_NORMAL); | |
GraySetAMSPlane(DARK_PLANE); | |
if (color&2) DrawClipLine(&line,whole_scn,A_NORMAL); | |
break; | |
default: | |
GraySetAMSPlane(LIGHT_PLANE); | |
DrawClipLine(&line,whole_scn,attr?A_XOR:(color&1)); | |
GraySetAMSPlane(DARK_PLANE); | |
DrawClipLine(&line,whole_scn,attr?A_XOR:(color&2)/2); | |
} | |
} | |
} | |
int floord2(int x) { | |
return floor((float) x/2.0); | |
} | |
void DrawGLine2(short x0, short y0, short x1, short y1, short color, short attr) { | |
if (y0==y1) { | |
int it2; | |
for (it2=-(penWidth-1);it2<=(penWidth-1);it2+=2) { | |
DrawGLine(x0,y0+floord2(it2),x1,y1+floord2(it2),color,attr); | |
} | |
return; | |
} | |
float mi=-(float)(x1-x0)/((float)(y1-y0)); | |
float x=1.0/(sqrt(1.0+sqr(mi))); | |
float y=x*mi; | |
int it2; | |
for(it2=-(penWidth-1);it2<=(penWidth-1);it2+=2) { | |
DrawGLine(x0+floord2(it2*x),y0+floord2(it2*y),x1+floord2(it2*x),y1+floord2(it2*y),color,attr); | |
} | |
} | |
void DrawGTriangle(short x0, short y0, short x1, short y1, short x2, short y2, short color, short attr) | |
{ | |
DrawGLine2(x0,y0,x1,y1,color,attr); | |
DrawGLine2(x2,y2,x1,y1,color,attr); | |
DrawGLine2(x0,y0,x2,y2,color,attr); | |
} | |
void DrawGTriangleFill(short x0, short y0, short x1, short y1, short x2, short y2, short color, short attr) | |
{ | |
switch (attr) | |
{ | |
case GA_DRAW: | |
GraySetAMSPlane(LIGHT_PLANE); | |
FillTriangle(x0,y0,x1,y1,x2,y2,whole_scn,(color&1)); | |
GraySetAMSPlane(DARK_PLANE); | |
FillTriangle(x0,y0,x1,y1,x2,y2,whole_scn,(color&2)/2); | |
break; | |
case GA_ROT: | |
case GA_ADD: | |
GraySetAMSPlane(LIGHT_PLANE); | |
if (color&1) FillTriangle(x0,y0,x1,y1,x2,y2,whole_scn,A_NORMAL); | |
GraySetAMSPlane(DARK_PLANE); | |
if (color&2) FillTriangle(x0,y0,x1,y1,x2,y2,whole_scn,A_NORMAL); | |
break; | |
case GA_FLIP: | |
GraySetAMSPlane(LIGHT_PLANE); | |
FillTriangle(x0,y0,x1,y1,x2,y2,whole_scn,A_XOR); | |
GraySetAMSPlane(DARK_PLANE); | |
FillTriangle(x0,y0,x1,y1,x2,y2,whole_scn,A_XOR); | |
break; | |
} | |
} | |
void DrawGRect(short x0, short y0, short x1, short y1, short color, short attr) | |
{ | |
DrawGLine2(x0,y0,x1,y0,color,attr); | |
DrawGLine2(x0,y0,x0,y1,color,attr); | |
DrawGLine2(x1,y0,x1,y1,color,attr); | |
DrawGLine2(x0,y1,x1,y1,color,attr); | |
} | |
void DrawGRectFill(short x0, short y0, short x1, short y1, short color, short attr) | |
{ | |
if (attr==GA_ROT) | |
{ | |
int i; | |
if (x1>x0) | |
{ | |
for(i=x0;i<=x1;i++) | |
{ | |
DrawGLine(i,y0,i,y1,color,attr); | |
} | |
} | |
else | |
{ | |
for(i=x1;i>=x0;i--) | |
{ | |
DrawGLine(i,y0,i,y1,color,attr); | |
} | |
} | |
} | |
else | |
{ | |
SCR_RECT rect={{x0,y0,x1,y1}}; | |
switch (attr) | |
{ | |
case GA_ADD: | |
GraySetAMSPlane(LIGHT_PLANE); | |
if (color&1) ScrRectFill(&rect,whole_scn,A_NORMAL); | |
GraySetAMSPlane(DARK_PLANE); | |
if (color&2) ScrRectFill(&rect,whole_scn,A_NORMAL); | |
break; | |
default: | |
GraySetAMSPlane(LIGHT_PLANE); | |
ScrRectFill(&rect,whole_scn,attr?A_XOR:(color&1)); | |
GraySetAMSPlane(DARK_PLANE); | |
ScrRectFill(&rect,whole_scn,attr?A_XOR:(color&2)/2); | |
} | |
} | |
} | |
void cut(ClipBoard* c, SCR_RECT* w) { | |
copy(c,w); | |
DrawGRectFill(w->xy.x0,w->xy.y0,w->xy.x1,w->xy.y1,0,GA_DRAW); | |
} | |
void paste(ClipBoard* c, unsigned char x, unsigned char y) { | |
if (!c->w) return; | |
BITMAP* b=NULL; | |
int size=BITMAP_HDR_SIZE+c->w*c->h/8; | |
b=malloc(size); | |
if (!b) return; | |
b->NumRows=c->h; | |
b->NumCols=c->w; | |
int i,oldWd; | |
oldWd=penWidth; | |
penWidth=1; | |
for(i=0;i<2;i++) { | |
GraySetAMSPlane(i); | |
memcpy(b->Data,*(((void**) c + i)),size-4); | |
BitmapPut(x,y,b,whole_scn,A_REPLACE); | |
} | |
penWidth=oldWd; | |
free(b); | |
} | |
int sign(int x) { | |
return (x>0)?1:((x<0)?-1:0); | |
} | |
void DrawGEllipse(short x0, short y0, short x1, short y1, short color, short attr) | |
{ | |
int xc,yc,a,b; | |
xc=(x0+x1)/2; | |
yc=(y0+y1)/2; | |
a=abs(x1-xc); | |
b=abs(y1-yc); | |
switch (attr) | |
{ | |
case GA_DRAW: | |
GraySetAMSPlane(LIGHT_PLANE); | |
DrawClipEllipse(xc,yc,a,b,whole_scn,color&1); | |
GraySetAMSPlane(DARK_PLANE); | |
DrawClipEllipse(xc,yc,a,b,whole_scn,(color&2)/2); | |
break; | |
case GA_ROT: | |
case GA_ADD: | |
GraySetAMSPlane(LIGHT_PLANE); | |
if (color&1) DrawClipEllipse(xc,yc,a,b,whole_scn,A_NORMAL); | |
GraySetAMSPlane(DARK_PLANE); | |
if (color&2) DrawClipEllipse(xc,yc,a,b,whole_scn,A_NORMAL); | |
break; | |
case GA_FLIP: | |
GraySetAMSPlane(LIGHT_PLANE); | |
DrawClipEllipse(xc,yc,a,b,whole_scn,A_XOR); | |
GraySetAMSPlane(DARK_PLANE); | |
DrawClipEllipse(xc,yc,a,b,whole_scn,A_XOR); | |
} | |
} | |
void DrawGEllipse2(short x0, short y0, short x1, short y1, short color, short attr) { | |
int it2; | |
int xd=sign(x1-x0); | |
int yd=sign(y1-y0); | |
for (it2=-(penWidth-1);it2<=(penWidth-1);it2+=2) { | |
DrawGEllipse(x0+floord2(xd*it2),y0+floord2(yd*it2),x1-floord2(xd*it2),y1-floord2(yd*it2),color,attr); | |
} | |
} | |
void DrawGEllipseFill(short x0, short y0, short x1, short y1, short color, short attr) | |
{ | |
double i; | |
double h; | |
double xc=(x0+x1)/2,yc=(y0+y1)/2; | |
double a=abs(xc-x0); | |
double b=abs(yc-y0); | |
if (x1>x0) | |
{ | |
for(i=x0;i<=x1;i++) | |
{ | |
h=b*sqrt(1-(sqr(i-xc)/sqr(a))); | |
DrawGLine(i,yc-h,i,yc+h,color,attr); | |
} | |
} | |
else | |
{ | |
for(i=x0;i>=x1;i--) | |
{ | |
h=b*sqrt(1-(sqr(i-xc)/sqr(a))); | |
DrawGLine(i,yc-h,i,yc+h,color,attr); | |
} | |
} | |
} | |
void DrawGCirc(short x,short y, short r, short color, short attr) | |
{ | |
DrawGEllipse(x-r,y-r,x+r,y+r,color,attr); | |
} | |
void DrawGCirc2(short x,short y, short r, short color, short attr) { | |
int it2; | |
for (it2=-(penWidth-1);it2<=(penWidth-1);it2+=2) { | |
DrawGCirc(x,y,r+floord2(it2),color,attr); | |
} | |
} | |
void DrawGCircFill(short x,short y, short r, short color, short attr) | |
{ | |
DrawGEllipseFill(x-r,y-r,x+r,y+r,color,attr); | |
} | |
void DrawGStr(short x0, short y0, const char* string, short color, short attr) | |
{ | |
switch (attr) | |
{ | |
case GA_DRAW: | |
GraySetAMSPlane(LIGHT_PLANE); | |
DrawStr2(x0,y0,string,(color&1)); | |
GraySetAMSPlane(DARK_PLANE); | |
DrawStr2(x0,y0,string,(color&2)/2); | |
break; | |
case GA_ROT: | |
GraySetAMSPlane(LIGHT_PLANE); | |
if (color&1) DrawStr2(x0,y0,string,A_NORMAL); | |
GraySetAMSPlane(DARK_PLANE); | |
if (color&2) DrawStr2(x0,y0,string,A_NORMAL); | |
break; | |
case GA_FLIP: | |
GraySetAMSPlane(LIGHT_PLANE); | |
DrawStr2(x0,y0,string,A_XOR); | |
GraySetAMSPlane(DARK_PLANE); | |
DrawStr2(x0,y0,string,A_XOR); | |
} | |
} | |
int mf=3; | |
int ptcolora(int x,int y) {return (x>=0&&x<whole_scn->xy.x1&&y>=0&&y<whole_scn->xy.y1)?GetGPix(x,y):mf;} | |
typedef struct | |
{ | |
unsigned char x,y; | |
} aaa; | |
void FloodFill(short x,short y,short tcol,short rcol) | |
{ | |
mf=rcol; | |
if (tcol==rcol) return; | |
if (ptcolora(x,y)!=tcol) return; | |
HANDLE sh; | |
aaa* stack; | |
if (!(sh=HeapAlloc(sizeof(aaa)+6))) return; | |
long int size=1; | |
stack=HeapDeref(sh); | |
*stack=(aaa){x,y}; | |
int j,Y; | |
while (size>0) | |
{ | |
aaa N=*stack; | |
Y=N.y; | |
if (ptcolora(N.x,Y)==tcol) | |
{ | |
int e; | |
int w=(e=N.x); | |
while ((ptcolora(--w,Y)==tcol) && w>=0); | |
w++; | |
while ((ptcolora(++e,Y)==tcol) && e<whole_scn->xy.x1); | |
e--; | |
DrawGLine(w,Y,e,Y,rcol,GA_DRAW); | |
for(j=w;j<=e;j++) | |
{ | |
if (ptcolora(j,Y-1)==tcol) | |
{ | |
HeapUnlock(sh); | |
if(!(sh=HeapRealloc(sh,++size*sizeof(aaa)+6))) goto ERROR; | |
stack=HeapDeref(sh); | |
stack[size-1]=(aaa){j,Y-1}; | |
} | |
if (ptcolora(j,Y+1)==tcol) | |
{ | |
HeapUnlock(sh); | |
if(!(sh=HeapRealloc(sh,++size*sizeof(aaa)+6))) goto ERROR2; | |
stack=HeapDeref(sh); | |
stack[size-1]=(aaa){j,Y+1}; | |
} | |
} | |
} | |
memmove(stack,stack+1,sizeof(aaa)*(size-1)); | |
sh=HeapRealloc(sh,--size*sizeof(aaa)+6); | |
stack=HeapDeref(sh); | |
} | |
HeapFree(sh); | |
return; | |
ERROR: | |
HeapFree(sh); | |
FloodFill(j,Y-1,tcol,rcol); | |
return; | |
ERROR2: | |
HeapFree(sh); | |
FloodFill(j,Y+1,tcol,rcol); | |
return; | |
} | |
#define Fill(x,y,col) FloodFill(x,y,GetGPix(x,y),col) | |
void ClrScrAll(void) | |
{ | |
memset(GrayGetPlane(0),0,LCD_SIZE); | |
memset(GrayGetPlane(1),0,LCD_SIZE); | |
} | |
void* GetMemLoc(SYM_STR name) //returns the memory location of the file | |
{ | |
return HeapDeref(DerefSym(SymFind(name))->handle); | |
} | |
//save as KPIC | |
short SaveKPIC(char* fname,unsigned int w,unsigned int h,void* lbuff,void* dbuff) | |
{ | |
FILE* f=fopen(fname,"wb"); | |
if (!f) | |
{ | |
GLCDSave(lbuff,dbuff); | |
GrayOff(); | |
SetIntVec(AUTO_INT_1,I1); | |
SetIntVec(AUTO_INT_5,I5); | |
dlgError(FILE_ERROR,FOPEN_FAIL); | |
SetIntVec(AUTO_INT_1,DUMMY_HANDLER); | |
SetIntVec(AUTO_INT_5,DUMMY_HANDLER); | |
GrayOn(); | |
GLCDRestore(lbuff,dbuff); | |
return 0; | |
} | |
int i,bytes=picsize(w,h); | |
int x=0,y=0,mm; | |
fputc(w,f); | |
fputc(h,f); | |
for (i=0;i<bytes;i++) | |
{ | |
mm=64*GetGPix(x,y); | |
x++; | |
if (x>=w) | |
{ | |
y++; | |
x=0; | |
} | |
mm+=16*GetGPix(x,y); | |
x++; | |
if (x>=w) | |
{ | |
y++; | |
x=0; | |
} | |
mm+=4*GetGPix(x,y); | |
x++; | |
if (x>=w) | |
{ | |
y++; | |
x=0; | |
} | |
fputc(mm+GetGPix(x,y),f); | |
x++; | |
if (x>=w) | |
{ | |
y++; | |
x=0; | |
} | |
} | |
fputc(0,f); | |
fputs("KPIC",f); | |
fputc(0,f); | |
fputc(OTH_TAG,f); | |
fclose(f); | |
return 1; | |
} | |
short SavePIC(const char* fname,int dither) | |
{ | |
/*dither ops*/ | |
if (dither) | |
{ | |
int i,j,h,w; | |
h=whole_scn->xy.y1; | |
w=whole_scn->xy.x1; | |
for(i=0;i<h;i++) | |
{ | |
for(j=0;j<w;j++) | |
{ | |
int col=GetGPix(j,i); | |
switch (dither) | |
{ | |
case D_RANDOM: | |
DrawGPix(j,i,(random(3)<col)?3:0,GA_DRAW); | |
break; | |
case D_3: | |
DrawGPix(j,i,((col==3)||(col&&((i+j)%2)))?3:0,GA_DRAW); | |
break; | |
case D_4a: | |
DrawGPix(j,i,(((i+j)%3)<=col)?3:0,GA_DRAW); | |
break; | |
case D_4b: | |
DrawGPix(j,i,(i%3<=col)?3:0,GA_DRAW); | |
break; | |
} | |
} | |
} | |
} | |
/*save*/ | |
GraySetAMSPlane(DARK_PLANE); | |
char* buff=NULL; | |
if (!(buff=malloc(BitmapSize(whole_scn)))) return 0; | |
BitmapGet(whole_scn,buff); | |
FILE* f=fopen(fname,"wb"); | |
fwrite(buff,BitmapSize(whole_scn),1,f); | |
int i; | |
for(i=0;i<9;i++) fputc(0,f); | |
fputc(PIC_TAG,f); | |
fclose(f); | |
free(buff); | |
return 1; | |
} | |
short show_picvar (SYM_STR SymName, short x, short y, short Attr,int*wl,int*hl) | |
{ | |
SYM_ENTRY *sym_entry = SymFindPtr (SymName, 0); | |
if (!sym_entry) return FALSE; | |
if (peek (HToESI (sym_entry->handle)) != PIC_TAG) return FALSE; | |
short* loc=HeapDeref (sym_entry->handle) + 2; | |
BitmapPut (x, y, loc, ScrRect, Attr); | |
*wl=*((short*)loc); | |
*hl=*((short*)loc+1); | |
return TRUE; | |
} | |
void OpenPIC(const char* fname,int* wl,int* hl) | |
{ | |
ClrScrAll(); | |
int i; | |
for(i=0;i<2;i++) {GraySetAMSPlane(i); show_picvar(SYMSTR(fname),0,0,A_NORMAL,wl,hl);} | |
} | |
short OpenKPIC(const char* fname,int* wl,int* hl) | |
{ | |
FILE* f=fopen(fname,"rb"); | |
if (!f) | |
{ | |
return 0; | |
} | |
unsigned char w=fgetc(f); | |
unsigned char h=fgetc(f); | |
int i,bytes=picsize(w,h); | |
int x=0,y=0,mm,col; | |
for (i=0;i<bytes;i++) | |
{ | |
mm=fgetc(f); | |
col=(mm&0b11000000)>>6; | |
DrawGPix(x,y,col,GA_DRAW); | |
x++; | |
if (x>=w) | |
{ | |
y++; | |
x=0; | |
} | |
col=(mm&0b00110000)>>4; | |
DrawGPix(x,y,col,GA_DRAW); | |
x++; | |
if (x>=w) | |
{ | |
y++; | |
x=0; | |
} | |
col=(mm&0b00001100)>>2; | |
DrawGPix(x,y,col,GA_DRAW); | |
x++; | |
if (x>=w) | |
{ | |
y++; | |
x=0; | |
} | |
col=mm&0b00000011; | |
DrawGPix(x,y,col,GA_DRAW); | |
x++; | |
if (x>=w) | |
{ | |
y++; | |
x=0; | |
} | |
} | |
fclose(f); | |
*wl=w; | |
*hl=h; | |
return 1; | |
} | |
short OpenKPIC2(const char* fname,int* wl,int* hl) | |
{ | |
char* f=GetMemLoc(SYMSTR(fname))+2; | |
if (f==(char*)2) | |
{ | |
return 0; | |
} | |
unsigned char w=*(f++); | |
unsigned char h=*(f++); | |
int i,bytes=picsize(w,h); | |
int x=0,y=0,col; | |
unsigned char mm; | |
for (i=0;i<bytes;i++) | |
{ | |
mm=*(f++); | |
col=(mm&0b11000000)>>6; | |
DrawGPix(x,y,col,GA_DRAW); | |
x++; | |
if (x>=w) | |
{ | |
y++; | |
x=0; | |
} | |
col=(mm&0b00110000)>>4; | |
DrawGPix(x,y,col,GA_DRAW); | |
x++; | |
if (x>=w) | |
{ | |
y++; | |
x=0; | |
} | |
col=(mm&0b00001100)>>2; | |
DrawGPix(x,y,col,GA_DRAW); | |
x++; | |
if (x>=w) | |
{ | |
y++; | |
x=0; | |
} | |
col=mm&0b00000011; | |
DrawGPix(x,y,col,GA_DRAW); | |
x++; | |
if (x>=w) | |
{ | |
y++; | |
x=0; | |
} | |
} | |
*wl=w; | |
*hl=h; | |
return 1; | |
} | |
int requestName(char* fname,short* typeID,int* dither,void* lbuff,void* dbuff) | |
{ | |
GLCDSave(lbuff,dbuff); | |
int buff[]={1,0}; | |
GrayOff(); | |
SetIntVec(AUTO_INT_1,I1); | |
SetIntVec(AUTO_INT_5,I5); | |
HANDLE h=DialogNewSimple(150,50); | |
if (!h) | |
{ | |
dlgError(DLG_ERROR,DLGSETUP_FAIL); | |
return 0; | |
} | |
DialogAddTitle(h,nameOfProgram,BT_OK,BT_NONE); | |
DialogAddRequest(h,7,12,"File name:",0,8,8); | |
HANDLE p=PopupNew("File Type",0); | |
if (!p) | |
{ | |
dlgError(DLG_ERROR,DLGSETUP_FAIL); | |
HeapFree(h); | |
return 0; | |
} | |
PopupAddText(p,-1,"Kraphyko Pic (.KPIC)",1); | |
PopupAddText(p,-1,"TIOS Pic (.PIC)",2); | |
DialogAddPulldown(h,7,20,"File Type:",p,0); | |
HANDLE q=PopupNew("Dither (TI-OS Pics):",0); | |
if (!q) | |
{ | |
dlgError(DLG_ERROR,DLGSETUP_FAIL); | |
HeapFree(h); | |
HeapFree(p); | |
return 0; | |
} | |
PopupAddText(q,-1,"None",1); | |
PopupAddText(q,-1,"Random",2); | |
PopupAddText(q,-1,"3-color",3); | |
PopupAddText(q,-1,"Diagonals",4); | |
PopupAddText(q,-1,"Horizontal",5); | |
DialogAddPulldown(h,7,28,"Dither (TI-OS Pics):",q,1); | |
DialogDo(h,CENTER,CENTER,fname,buff); | |
HeapFree(h); | |
HeapFree(p); | |
HeapFree(q); | |
*typeID=*(buff); | |
*dither=buff[1]-1; | |
SetIntVec(AUTO_INT_1,DUMMY_HANDLER); | |
SetIntVec(AUTO_INT_5,DUMMY_HANDLER); | |
GrayOn(); | |
GLCDRestore(lbuff,dbuff); | |
return 1; | |
} | |
const unsigned char cursorl[8] = { | |
0x80,0xC0,0xA0,0x90,0xB8,0xE0,0x90,0x08 | |
}; | |
const unsigned char cursord[8] = { | |
0x80,0xC0,0xE0,0xF0,0xF8,0xE0,0x90,0x08 | |
}; | |
const unsigned char cursorm[8] = { | |
0x7F,0x3F,0x1F,0x0F,0x07,0x1F,0x6F,0xF7 | |
}; | |
void drawCursor(unsigned int x,unsigned int y) //Draws the cursor | |
{ | |
Sprite8(x,y,8,cursorm,GrayGetPlane(LIGHT_PLANE),SPRT_AND); | |
Sprite8(x,y,8,cursorm,GrayGetPlane(DARK_PLANE),SPRT_AND); | |
Sprite8(x,y,8,cursorl,GrayGetPlane(LIGHT_PLANE),SPRT_OR); | |
Sprite8(x,y,8,cursord,GrayGetPlane(DARK_PLANE),SPRT_OR); | |
} | |
int moveCursor(int* xp,int* yp,void* lbuff,void* dbuff,int w,int h) | |
{ | |
GKeyFlush(); | |
int x=*xp,y=*yp; | |
int k; | |
do | |
{ | |
GLCDSave(lbuff,dbuff); | |
drawCursor(x,y); | |
k=_rowread(~0x0001); | |
x=x-(k&2&&x!=0)+(k&8&&x!=w-1); | |
y=y-(k&1&&y!=0)+(k&4&&y!=h-1); | |
delay(CURSOR_DELAY); | |
GLCDRestore(lbuff,dbuff); | |
if (_rowread(~0x40)) return 0; | |
k=_rowread(~0x0022); | |
} while (!(k&129)); | |
*xp=x; | |
*yp=y; | |
delay(1500); | |
return 1; | |
} | |
char brushstyle=0; | |
void Pencil(int* xp,int* yp,void* lbuff,void* dbuff,int w,int h,int col) | |
{ | |
GKeyFlush(); | |
int x=*xp,y=*yp; | |
int k; | |
do | |
{ | |
GLCDSave(lbuff,dbuff); | |
drawCursor(x,y); | |
k=_rowread(~0x0001); | |
x=x-(k&2&&x!=0)+(k&8&&x!=w-1); | |
y=y-(k&1&&y!=0)+(k&4&&y!=h-1); | |
delay(CURSOR_DELAY); | |
GLCDRestore(lbuff,dbuff); | |
if (k&0xF0) | |
{ | |
int attr=GA_NORMAL+!!(k&96)+!!(k&64); | |
int mat=attr==GA_ROT?GA_DRAW:attr; | |
switch (brushstyle) | |
{ | |
case 0: | |
DrawGPix(x,y,col,attr); | |
break; | |
case 1: | |
case 2: | |
case 3: | |
DrawGRect(x-brushstyle,y-brushstyle,x+brushstyle,y+brushstyle,col,mat); | |
break; | |
case 12: | |
DrawGPix(x,y-1,col,mat); | |
DrawGPix(x,y+1,col,mat); | |
case 4: | |
DrawGLine(x-1,y,x+1,y,col,mat); | |
break; | |
case 5: | |
DrawGLine(x,y-1,x,y+1,col,mat); | |
break; | |
case 6: | |
DrawGLine(x-1,y+1,x+1,y-1,col,mat); | |
break; | |
case 7: | |
DrawGLine(x-1,y-1,x+1,y+1,col,mat); | |
break; | |
case 13: | |
DrawGLine(x-1,y-1,x+1,y-1,col,mat); | |
DrawGLine(x-1,y+1,x+1,y+1,col,mat); | |
DrawGPix(x,y-2,col,mat); | |
DrawGPix(x,y+2,col,mat); | |
case 8: | |
DrawGLine(x-2,y,x+2,y,col,mat); | |
break; | |
case 9: | |
DrawGLine(x,y-2,x,y+2,col,mat); | |
break; | |
case 10: | |
DrawGLine(x-2,y+2,x+2,y-2,col,mat); | |
break; | |
case 11: | |
DrawGLine(x-2,y-2,x+2,y+2,col,mat); | |
break; | |
} | |
} | |
k=_rowread(~0x0042); | |
if (k&128) | |
{ | |
brushstyle=(++brushstyle)%12; | |
GLCDSave(lbuff,dbuff); | |
char buff[14]; | |
sprintf(buff,"Brush style %d",brushstyle); | |
int temp=FontSetSys(F_4x6); | |
DrawGStr(2,92,buff,3,GA_DRAW); | |
FontSetSys(temp); | |
delay(3*CURSOR_DELAY); | |
GLCDRestore(lbuff,dbuff); | |
} | |
} while (!(k&1)); | |
} | |
const char* attrStrings[4]={"Normal","Rotate","Flip","Add"}; | |
const char* yesOrNo[2]={"No","Yes"}; | |
const char* fontSizes[3]={"Small","Normal","Large"}; | |
char* a="1"; | |
void updateSettings(int* col,int* attr,int*fontsize,int*filled,void* lbuff,void*dbuff,int* w,int* h)//char* canUndo,char* lineThickness | |
{ | |
GLCDSave(lbuff,dbuff); | |
int i,n=0,k; | |
for(i=0;i<2;i++) | |
{ | |
GraySetAMSPlane(i); | |
ClrScr(); | |
FontSetSys(F_6x8); | |
DrawStr(0,0,versString,A_NORMAL); | |
DrawLine(0,8,159,8,A_NORMAL); | |
FontSetSys(F_4x6); | |
DrawStr(5,10,"Color:",A_NORMAL); | |
DrawStr(5,16,"Attribute:",A_NORMAL); | |
DrawStr(5,22,"Filled:",A_NORMAL); | |
DrawStr(5,28,"Font Size:",A_NORMAL); | |
DrawStr(5,34,"Resize...",A_NORMAL); | |
DrawStr(5,40,"Pen Width:",A_NORMAL); | |
DrawStr(5,46,"Enable Undo:",A_NORMAL); | |
DrawStr(39,16,attrStrings[*attr],A_XOR); | |
DrawStr(28,22,yesOrNo[*filled],A_XOR); | |
DrawStr(39,28,fontSizes[*fontsize],A_XOR); | |
DrawStr(48,46,yesOrNo[ui.canUndo],A_XOR); | |
DrawStr(40,40,a,A_XOR); | |
} | |
DrawGRectFill(24,10,30,15,*col,GA_DRAW); | |
DrawChar(1,10,'>',A_XOR); | |
do { | |
k=_rowread(~0x0001); | |
DrawChar(1,10+6*n,'>',A_XOR); | |
n=n-(k&1)+!!(k&4); | |
if (n==-1) n=6; | |
if (n==7) n=0; | |
DrawChar(1,10+6*n,'>',A_XOR); | |
if (k&8) | |
{ | |
switch (n) | |
{ | |
case 0: | |
*col=(*col+1)%4; | |
DrawGRectFill(24,10,30,15,*col,GA_DRAW); | |
break; | |
case 1: | |
DrawGStr(39,16,attrStrings[*attr],3,GA_FLIP); | |
*attr=(*attr+1)%4; | |
DrawGStr(39,16,attrStrings[*attr],3,GA_FLIP); | |
break; | |
case 2: | |
DrawGStr(28,22,yesOrNo[*filled],3,GA_FLIP); | |
*filled=!(*filled); | |
DrawGStr(28,22,yesOrNo[*filled],3,GA_FLIP); | |
break; | |
case 3: | |
DrawGStr(39,28,fontSizes[*fontsize],3,GA_FLIP); | |
*fontsize=(*fontsize+1)%3; | |
DrawGStr(39,28,fontSizes[*fontsize],3,GA_FLIP); | |
break; | |
case 4: | |
GrayOff(); | |
SetIntVec(AUTO_INT_1,I1); | |
SetIntVec(AUTO_INT_5,I5); | |
HANDLE hn=H_NULL; | |
if (hn=DialogNewSimple(140,60)) | |
{ | |
char ReqBuff[8]; | |
sprintf(ReqBuff,"%d",*w); | |
sprintf(ReqBuff+4,"%d",*h); | |
DialogAddTitle(hn,nameOfProgram,BT_OK,BT_CANCEL); | |
DialogAddRequest(hn,7,12,"New width:",0,3,3); | |
DialogAddRequest(hn,7,20,"New height:",4,3,3); | |
if ((DialogDo(hn,CENTER,CENTER,ReqBuff,NULL))==KEY_ENTER) | |
{ | |
int a=atoi(ReqBuff); | |
*w=a>0 && a<=160?a:*w; | |
a=atoi(ReqBuff+4); | |
*h=a>0 && a<=100?a:*h; | |
whole_scn->xy.x1=*w-1; | |
whole_scn->xy.y1=*h-1; | |
} | |
} | |
else | |
{ | |
dlgError(DLG_ERROR,DLGSETUP_FAIL); | |
} | |
HeapFree(hn); | |
SetIntVec(AUTO_INT_1,DUMMY_HANDLER); | |
SetIntVec(AUTO_INT_5,DUMMY_HANDLER); | |
GrayOn(); | |
break; | |
case 5: | |
DrawGStr(40,40,a,3,GA_FLIP); | |
penWidth=(penWidth%9)+1; | |
*a='0'+penWidth; | |
DrawGStr(40,40,a,3,GA_FLIP); | |
break; | |
case 6: | |
DrawGStr(48,46,yesOrNo[ui.canUndo],3,GA_FLIP); | |
if (ui.canUndo) | |
disableUndo(&ui); | |
else | |
enableUndo(&ui); | |
memcpy(GrayGetPlane(LIGHT_PLANE),GrayGetPlane(DARK_PLANE),LCD_SIZE); | |
GraySetAMSPlane(LIGHT_PLANE); | |
DrawChar(1,10+6*n,'>',A_XOR); | |
GraySetAMSPlane(DARK_PLANE); | |
DrawGStr(48,46,yesOrNo[ui.canUndo],3,GA_FLIP); | |
} | |
} | |
delay(2700); | |
k=_rowread(~0x0002); | |
}while (!(k&1)); | |
GLCDRestore(lbuff,dbuff); | |
} | |
const char* OptionTips[48]={ | |
"Save (3)","Save As (+)","Quit (Esc)",0,0,0,0,0,0,0,0,0,0,0,0,0, | |
"Undo (Z)","Redo (Y)","Cut (X)","Copy (=)","Paste (0)","Options (-)",0,0,0,0,0,0,0,0,0,0, | |
"Pencil (\026)","Line (4)","Rectangle (2)","Circle ())","Ellipse (/)","Triangle (T)","Text (*)","Fill (|)","Invert (9)","Clear","Polygon (^)",0,0,0,0,0 | |
}; | |
char options[3]={3,6,11}; | |
void DrawMS(char Tab,char* buff,char* fname) { | |
int i; | |
for(i=0;i<2;i++) | |
{ | |
GraySetAMSPlane(i); | |
ClrScr(); | |
FontSetSys(F_6x8); | |
DrawStr(0,0,versString,A_NORMAL); | |
DrawLine(0,8,159,8,A_NORMAL); | |
FontSetSys(F_4x6); | |
DrawStr(5,10,"F1 - Help | F2 - File | F3 - Edit | F4 - Image",A_NORMAL); | |
int j; | |
char** b=OptionTips+16*Tab; | |
for (j=0;j<16;j++,b++) { | |
char* a=*b; | |
DrawStr(5,16+6*j,a,A_NORMAL); | |
} | |
DrawStr(100,20,fname,A_NORMAL); | |
DrawStr(100,26,buff,A_NORMAL); | |
} | |
} | |
int MenuScn(void* lbuff, void* dbuff,int w,int h,char* fname) | |
{ | |
GLCDSave(lbuff,dbuff); | |
char buff[20]; | |
sprintf(buff,"%dX%d",w,h); | |
int Tab=0; //this variable shows which tab is open | |
int k,n=0; | |
DrawMS(Tab,buff,fname); | |
DrawChar(1,16,'>',A_NORMAL); | |
do { | |
k=_rowread(~0x0001); | |
DrawChar(1,16+6*n,'>',A_XOR); | |
n=n-(k&1)+!!(k&4); | |
if (n==-1) n=options[Tab]-1; | |
if (n==options[Tab]) n=0; | |
DrawChar(1,16+6*n,'>',A_XOR); | |
delay(2700); | |
k=_rowread(~0x0004); | |
if (k&2) {Tab=0; n=0; break;} //save | |
if (k&8) {Tab=2; n=8; break;} //invert | |
if (k&32) {Tab=2; n=5; break;} //triangle | |
if (k&128) { | |
Tab=2; | |
if (n>=options[2]) n=options[2]-1; | |
DrawMS(Tab,buff,fname); | |
DrawChar(1,16+6*n,'>',A_NORMAL); | |
} | |
k=_rowread(~0x0008); | |
if (k&2) {Tab=2; n=2; break;} //rectangle | |
//if (k&8) {n=14; break;} //help now is accessed by F1 | |
if (k&16) {Tab=2; n=3; break;} //circle | |
if (k&128) { | |
Tab=1; | |
if (n>=options[1]) n=options[1]-1; | |
DrawMS(Tab,buff,fname); | |
DrawChar(1,16+6*n,'>',A_NORMAL); | |
} | |
k=_rowread(~0x0010); | |
if (k&4) {Tab=2; n=1; break;} //line | |
if (k&128) { | |
Tab=0; | |
if (n>=*options) n=*options-1; | |
DrawMS(Tab,buff,fname); | |
DrawChar(1,16+6*n,'>',A_NORMAL); | |
} | |
k=_rowread(~0x0020); | |
if (k&2) {Tab=2; n=0; break;} //pencil | |
if (k&8) {Tab=2; n=7; break;} //fill | |
if (k&32) {Tab=1; n=2; break;} //cut | |
if (k&128) {Tab=3; n=0; break;} //show help | |
if (_rowread(~0x0040)) {Tab=0; n=2; break;} //quit | |
k=_rowread(~0x0002); | |
if (k&2) {Tab=0; n=2; break;} //save as | |
if (k&4) {Tab=1; n=5; break;} //options | |
if (k&8) {Tab=2; n=6; break;} //text | |
if (k&16) {Tab=2; n=4; break;} //ellipse | |
if (k&64) {Tab=2; n=9; break;} //clear | |
} while (!(k&1)); | |
GLCDRestore(lbuff,dbuff); | |
return 16*Tab+n; | |
} | |
/* | |
Help File Format | |
2 bytes: number of items | |
4*(number of items) bytes: jump table, with (title,body) pairs | |
rest: help contents, using null-terminated strings | |
Left pane should contain the TOC in small font; right pane should have the title in normal font and body in small font. | |
*/ | |
void DrawWrapText(int x,int y,char* s,int attr,int wrapWidth,int maxHeight) | |
{ | |
int font=FontGetSys(); | |
int i; | |
int charHt=2*font+6; | |
int maxRows=maxHeight/charHt; | |
int len=strlen(s); | |
for(i=0;(i<maxRows)&&(len);i++) | |
{ | |
int j=0; | |
char b,c=1; | |
while (c) | |
{ | |
b=s[j]; | |
s[j]=0; | |
c=(DrawStrWidth(s,font)<=wrapWidth)&&(j<len); | |
s[j]=b; | |
if (c) j++; | |
else j--; | |
} | |
b=s[j]; | |
s[j]=0; | |
DrawStr(x,y+charHt*i,s,attr); | |
s[j]=b; | |
s+=j; | |
len-=j; | |
} | |
} | |
//items on left pane shown | |
void UpdateHelpScn(int noOfItems,int* jumpTable,char* start,int active,int top,SCR_RECT rect) | |
{ | |
ClrScr(); | |
DrawLine(60,0,60,159,A_NORMAL); | |
int i; | |
for(i=0;i<16;i++) | |
{ | |
if ((top+i)<noOfItems) | |
DrawStr(0,6*i,start+jumpTable[2*(top+i)],A_NORMAL); | |
} | |
rect.xy.y1=5+(rect.xy.y0=6*(active-top)); | |
ScrRectFill(&rect,whole_scn,A_XOR); | |
FontSetSys(F_6x8); | |
DrawStr(62,2,start+jumpTable[2*(active)],A_NORMAL); | |
FontSetSys(F_4x6); | |
DrawWrapText(62,11,start+jumpTable[2*(active)+1],A_NORMAL,96,86); | |
} | |
void help(void* lbuff, void* dbuff) | |
{ | |
GLCDSave(lbuff,dbuff); | |
GrayOff(); | |
SCR_RECT save=*whole_scn; | |
*whole_scn=(SCR_RECT){{0,0,239,127}}; | |
//initialize ^^^ | |
int noOfItems; | |
int* jumpTable; | |
void* location; | |
char* start; | |
int active=0; | |
int top=0; | |
int flag=0; //this is the update flag | |
location=GetMemLoc(SYMSTR("khelpf"))+2; | |
noOfItems=*(int*)location; | |
jumpTable=(int*)location+1; | |
start=jumpTable+2*noOfItems; | |
SCR_RECT rect={{0,0,59,5}}; | |
int key=0,esc=0; | |
FontSetSys(F_4x6); | |
UpdateHelpScn(noOfItems,jumpTable,start,active,top,rect); | |
while (1) | |
{ | |
while (!((key=_rowread(~0x0001))||(esc=_rowread(~0x0040)))); | |
if (esc&1) break; | |
if ((key&1) && active) active--,flag=1; | |
if ((key&4) && (active<(noOfItems-1))) active++,flag=1; | |
if (active<top) top--; | |
if (active>=(top+16)) top++; | |
if (flag) UpdateHelpScn(noOfItems,jumpTable,start,active,top,rect); | |
} | |
//finalize | |
GrayOn(); | |
GLCDRestore(lbuff,dbuff); | |
*whole_scn=save; | |
} | |
void EditImg(int mode,char* fname,void* lbuff,void* dbuff,int w,int h,short int ftype) | |
{ | |
ClrScrAll(); | |
whole_scn->xy.x1=w-1; | |
whole_scn->xy.y1=h-1; | |
SetCurClip(whole_scn); | |
if (mode==M_OPEN) | |
{ | |
if (ftype==1) OpenKPIC2(fname,&w,&h); | |
else OpenPIC(fname,&w,&h); | |
} | |
int done=0,n; | |
int x=0,y=0,col=3,a=0,b=0,c=0,d=0,attr=0,fontsize=1,filled=0,r=0,dither=0; | |
char shadow[9]; | |
while (!done) | |
{ | |
n=MenuScn(lbuff,dbuff,w,h,fname); | |
delay(1500); | |
done=n==2; | |
switch (n) | |
{ | |
case 32: | |
refUndo(&ui); | |
Pencil(&x,&y,lbuff,dbuff,w,h,col); | |
break; | |
case 33: | |
if (!moveCursor(&a,&b,lbuff,dbuff,w,h)) break; | |
x=a,y=b; | |
if (!moveCursor(&x,&y,lbuff,dbuff,w,h)) break; | |
refUndo(&ui); | |
DrawGLine2(x,y,a,b,col,attr); | |
break; | |
case 34: | |
if (!moveCursor(&a,&b,lbuff,dbuff,w,h)) break; | |
x=a,y=b; | |
if (!moveCursor(&x,&y,lbuff,dbuff,w,h)) break; | |
refUndo(&ui); | |
if (filled) DrawGRectFill(x,y,a,b,col,attr); | |
else DrawGRect(x,y,a,b,col,attr); | |
break; | |
case 35: | |
if (!moveCursor(&x,&y,lbuff,dbuff,w,h)) break; | |
a=x,b=y; | |
if (!moveCursor(&a,&b,lbuff,dbuff,w,h)) break; | |
r=sqrt(sqr(a-x)+sqr(b-y)); | |
refUndo(&ui); | |
if (filled) DrawGCircFill(x,y,r,col,attr); | |
else DrawGCirc2(x,y,r,col,attr); | |
break; | |
case 36: | |
if (!moveCursor(&a,&b,lbuff,dbuff,w,h)) break; | |
x=a,y=b; | |
if (!moveCursor(&x,&y,lbuff,dbuff,w,h)) break; | |
refUndo(&ui); | |
if (filled) DrawGEllipseFill(x,y,a,b,col,attr); | |
else DrawGEllipse2(x,y,a,b,col,attr); | |
break; | |
case 37: | |
if (!moveCursor(&a,&b,lbuff,dbuff,w,h)) break; | |
c=a,d=b; | |
if (!moveCursor(&c,&d,lbuff,dbuff,w,h)) break; | |
x=c,y=d; | |
if (!moveCursor(&x,&y,lbuff,dbuff,w,h)) break; | |
refUndo(&ui); | |
if (filled) DrawGTriangleFill(x,y,a,b,c,d,col,attr); | |
else DrawGTriangle(x,y,a,b,c,d,col,attr); | |
break; | |
case 38: | |
if (!moveCursor(&x,&y,lbuff,dbuff,w,h)) break; | |
GLCDSave(lbuff,dbuff); | |
r=1; | |
GrayOff(); | |
SetIntVec(AUTO_INT_1,I1); | |
SetIntVec(AUTO_INT_5,I5); | |
HANDLE hn=H_NULL; | |
char* buff=NULL; | |
if (!(buff=malloc(100))) break; | |
if (!(hn=DialogNewSimple(150,90))) | |
{free(buff); break;} | |
DialogAddTitle(hn,nameOfProgram,BT_OK,BT_NONE); | |
DialogAddRequest(hn,7,12,"String to Draw:",0,99,20); | |
DialogDo(hn,CENTER,CENTER,buff,NULL); | |
HeapFree(hn); | |
FontSetSys(fontsize); | |
if ((x+DrawStrWidth(buff,fontsize))>w) | |
{dlgError(DRAWTXT_ERROR,STR_OOB);r=0;} | |
SetIntVec(AUTO_INT_1,DUMMY_HANDLER); | |
SetIntVec(AUTO_INT_5,DUMMY_HANDLER); | |
GrayOn(); | |
GLCDRestore(lbuff,dbuff); | |
refUndo(&ui); | |
if (r) DrawGStr(x,y,buff,col,attr); | |
free(buff); | |
break; | |
case 21: | |
updateSettings(&col,&attr,&fontsize,&filled,lbuff,dbuff,&w,&h); | |
break; | |
case 39: | |
if (!moveCursor(&x,&y,lbuff,dbuff,w,h)) break; | |
refUndo(&ui); | |
Fill(x,y,col); | |
break; | |
case 40: | |
refUndo(&ui); | |
GraySetAMSPlane(0),ScrRectFill(whole_scn,whole_scn,A_XOR); | |
GraySetAMSPlane(1),ScrRectFill(whole_scn,whole_scn,A_XOR); | |
break; | |
case 41: | |
refUndo(&ui); | |
ClrScrAll(); | |
break; | |
case 1: | |
strcpy(shadow,fname); | |
requestName(fname,&ftype,&dither,lbuff,dbuff); | |
case 0: | |
if (ftype==1) SaveKPIC(fname,w,h,lbuff,dbuff); | |
else {SavePIC(fname,dither); | |
strcpy(fname,shadow);} | |
*shadow=0; | |
break; | |
case 48: | |
help(lbuff,dbuff); | |
break; | |
case 16: | |
undo(&ui); | |
break; | |
case 17: | |
redo(&ui); | |
break; | |
case 18: | |
if (!moveCursor(&a,&b,lbuff,dbuff,w,h)) break; | |
x=a,y=b; | |
if (!moveCursor(&x,&y,lbuff,dbuff,w,h)) break; | |
SCR_RECT s01=NormalizeScrRect((SCR_RECT){{x,y,a,b}}); | |
cut(&cb,&s01); | |
break; | |
case 19: | |
if (!moveCursor(&a,&b,lbuff,dbuff,w,h)) break; | |
x=a,y=b; | |
if (!moveCursor(&x,&y,lbuff,dbuff,w,h)) break; | |
SCR_RECT s02=NormalizeScrRect((SCR_RECT){{x,y,a,b}}); | |
copy(&cb,&s02); | |
break; | |
case 20: | |
if (!moveCursor(&x,&y,lbuff,dbuff,w,h)) break; | |
paste(&cb,x,y); | |
break; | |
} | |
delay(1500); | |
} | |
} | |
int titleScn(void) | |
{ | |
ClrScrAll(); | |
whole_scn->xy.x1=159; | |
DrawGRectFill(0,0,159,19,1,GA_DRAW); | |
FontSetSys(F_8x10); | |
DrawGStr(5,2,versString,3,GA_DRAW); | |
FontSetSys(F_4x6); | |
DrawGStr(2,92,"\251 2012 Ardtha Productions",3,GA_DRAW); | |
FontSetSys(F_6x8); | |
DrawGStr(12,22,"New",3,GA_DRAW); | |
DrawGStr(12,30,"Open",3,GA_DRAW); | |
DrawGStr(12,38,"Quit",3,GA_DRAW); | |
GraySetAMSPlane(DARK_PLANE); | |
int n=0,k; | |
DrawChar(4,22,127,A_XOR); | |
do | |
{ | |
k=_rowread(~0x0001); | |
DrawChar(4,22+8*n,127,A_XOR); | |
n=n-(k&1)+!!(k&4); | |
if (n==-1) n=2; | |
if (n==3) n=0; | |
DrawChar(4,22+8*n,127,A_XOR); | |
k=_rowread(~0x0002); | |
delay(2700); | |
} while (!(k&1)); | |
return n; | |
} | |
int requestName2(char* fname,short* w,short* ht,void* lbuff,void* dbuff) | |
{ | |
GLCDSave(lbuff,dbuff); | |
char buff[17]; | |
strcpy(buff,fname); | |
sprintf(buff+9,"%d",*w); | |
sprintf(buff+13,"%d",*ht); | |
GrayOff(); | |
SetIntVec(AUTO_INT_1,I1); | |
SetIntVec(AUTO_INT_5,I5); | |
HANDLE h=DialogNewSimple(100,50); | |
if (!h) | |
{ | |
dlgError(DLG_ERROR,DLGSETUP_FAIL); | |
return 0; | |
} | |
DialogAddTitle(h,nameOfProgram,BT_OK,BT_NONE); | |
DialogAddRequest(h,7,12,FNR,0,8,8); | |
DialogAddRequest(h,7,20,"Width:",9,3,3); | |
DialogAddRequest(h,7,28,"Height:",13,3,3); | |
DialogDo(h,CENTER,CENTER,buff,NULL); | |
HeapFree(h); | |
strcpy(buff,fname); | |
*w=atoi(buff+9); | |
*ht=atoi(buff+13); | |
SetIntVec(AUTO_INT_1,DUMMY_HANDLER); | |
SetIntVec(AUTO_INT_5,DUMMY_HANDLER); | |
GrayOn(); | |
GLCDRestore(lbuff,dbuff); | |
return 1; | |
} | |
int requestName3(char* fname,void* lbuff,void* dbuff) | |
{ | |
GLCDSave(lbuff,dbuff); | |
strcpy(fname,"sample"); | |
GrayOff(); | |
SetIntVec(AUTO_INT_1,I1); | |
SetIntVec(AUTO_INT_5,I5); | |
HANDLE h=DialogNewSimple(100,40); | |
if (!h) | |
{ | |
dlgError(DLG_ERROR,DLGSETUP_FAIL); | |
return 0; | |
} | |
DialogAddTitle(h,nameOfProgram,BT_OK,BT_NONE); | |
DialogAddRequest(h,7,12,FNR,0,8,8); | |
DialogDo(h,CENTER,CENTER,fname,NULL); | |
HeapFree(h); | |
SetIntVec(AUTO_INT_1,DUMMY_HANDLER); | |
SetIntVec(AUTO_INT_5,DUMMY_HANDLER); | |
GrayOn(); | |
GLCDRestore(lbuff,dbuff); | |
return 1; | |
} | |
//end | |
// Main Function | |
void _main(void) | |
{ | |
// Place your code here. | |
I1=GetIntVec(AUTO_INT_1); | |
I5=GetIntVec(AUTO_INT_5); | |
SetIntVec(AUTO_INT_1,DUMMY_HANDLER); | |
SetIntVec(AUTO_INT_5,DUMMY_HANDLER); | |
char fname[9]="sample"; | |
void* lbuff=NULL,* dbuff=NULL; | |
if (!allocGBUB(&lbuff,&dbuff)) | |
goto end; | |
short w=64,h=64; | |
if (GrayOn()) | |
{ | |
int n; | |
while ((n=titleScn())!=2) | |
{ | |
int c=1; | |
switch(n) | |
{ | |
case 1: | |
requestName3(fname,lbuff,dbuff); | |
HSym a=SymFind(SYMSTR(fname)); | |
if (a.folder) | |
{ | |
SYM_ENTRY* b=DerefSym(a); | |
int type=peek(HToESI (b->handle)); | |
if (!(type==PIC_TAG || type==OTH_TAG)) | |
n=2; | |
c=1+(type==PIC_TAG); | |
} | |
else n=2; | |
if (n==1) break; | |
case 2: | |
GrayOff(); | |
SetIntVec(AUTO_INT_1,I1); | |
SetIntVec(AUTO_INT_5,I5); | |
if ((DlgMessage("File not found","Create new KPIC?",BT_YES,BT_NO))==KEY_ESC) goto end; | |
SetIntVec(AUTO_INT_1,DUMMY_HANDLER); | |
SetIntVec(AUTO_INT_5,DUMMY_HANDLER); | |
GrayOn(); | |
n=0; | |
case 0: | |
requestName2(fname,&w,&h,lbuff,dbuff); | |
} | |
EditImg(n,fname,lbuff,dbuff,w,h,c); | |
} | |
} | |
end: | |
GKeyFlush(); | |
GrayOff(); | |
free(lbuff); | |
free(dbuff); | |
if (ui.canUndo) disableUndo(&ui); | |
resetCB(&cb); | |
SetIntVec(AUTO_INT_1,I1); | |
SetIntVec(AUTO_INT_5,I5); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment