#include <graphics.h>
#include <math.h>
#include <dos.h>
#include <malloc.h>
#include <string.h>
#define TIMEINTR 0x1c
#define MARGIN 4
#define BUTTONNUM 2
#define SCROLLBUTTONNUM 1
#define PI 3.1415926535
#define SB_WIDTH 20
#define SB_LENGTH 60
typedef enum bool {false, true}bool;
typedef enum state {OFF = 1, ON}State;
typedef enum mode {UP = 2, DOWN = 1};
typedef struct {
int x,oldx;
int y,oldy;
int but;
} MOUSE;
typedef struct movement
{
double A, W, Angle;
double (*Coordinate)(double Time, struct movement *p);
}MOVE;
typedef struct button
{
int x,y;
char *contents;
void (*Show)(struct button *p, int mode);
bool (*Clicked)(struct button *p);
void (*Function)();
}BUTTON;
typedef struct scrollbutton
{
int x, y;
char *contents;
int place;
bool (*Clicked)(struct scrollbutton *p);
void (*Show)(struct button *p);
int (*Function)(struct button *p);
}SCROLLBUTTON;
/************************declaration***********************/
double CDValue(double, MOVE *);
void show(BUTTON *p, State mode);
bool CheckClicked(BUTTON *p);
void interrupt( *oldhandler)(void);
bool MouseControl();
void Reset();
bool SCheckClicked(SCROLLBUTTON *p);
int MoveBar();
void SB_show(SCROLLBUTTON *p);
void FullScreenPROC();
void G_InitInterface();
/***********************global*****************************/
MOVE Movement[2] = {
3,3,2,CDValue,
2,1,4,CDValue,
};
BUTTON Button[] = {
320,370, "Full Screen",show, CheckClicked,FullScreenPROC,
320,400, "Reset",show,CheckClicked,Reset,
};
SCROLLBUTTON SButton[] = {
20,300, "speed", 50, SCheckClicked, SB_show, MoveBar,
};
double TIME = 0.0;
bool PROC = 1;
int SPEED = 100;
int Radius = 0;
bool IsFullScreen = false;
int count = 0;
int SW_X[2] = {80, 80}, SW_Y[2] = {80, 170};
void * mouse_buf;
MOUSE mouse;
unsigned Cursor[][16]=
{
0x0000, /* 0000000000000000 */
0x4000, /* 0100000000000000 */
0x6000, /* 0110000000000000 */
0x7000, /* 0111000000000000 */
0x7800, /* 0111100000000000 */
0x7C00, /* 0111110000000000 */
0x7E00, /* 0111111000000000 */
0x7F00, /* 0111111100000000 */
0x7F80, /* 0111111110000000 */
0x7FC0, /* 0111111111000000 */
0x6C00, /* 0110110000000000 */
0x4600, /* 0100011000000000 */
0x0600, /* 0000011000000000 */
0x0300, /* 0000001100000000 */
0x0300, /* 0000001100000000 */
0x0180 /* 0000000110000000 */
};
/**********************************************************/
double CDValue(double Time,MOVE *p)
{
return (p->A) * cos( (p->W) * Time + p->Angle);
}
void Set_x_range(int min, int max)
{
union REGS ireg;
ireg.x.ax = 7;
ireg.x.cx = min;
ireg.x.dx = max;
int86(0x33, &ireg, &ireg);
}
int Which_pressed(MOUSE *mouse)
{
union REGS ireg, oreg;
ireg.x.ax = 3;
int86(0x33, &ireg, &oreg);
return(oreg.x.bx);
}
void Get_xy(MOUSE *grmouse)
{
union REGS ireg, oreg;
ireg.x.ax = 3;
int86(0x33, &ireg, &oreg);
grmouse->x = oreg.x.cx;
grmouse->y = oreg.x.dx;
}
void Set_xy(int x, int y)
{
union REGS ireg;
ireg.x.ax = 4;
ireg.x.cx = x;
ireg.x.dx = y;
int86(0x33, &ireg, &ireg);
}
void G_DrawMouse(int X, int Y)
{
int t, i, j, x,y, color = BLACK;
unsigned int token;
y = Y;
for(j = 0; j < 16; j++)
{
x = X;
token = 0x8000;
for(t = 0;t < 10; t++)
{
if( (Cursor[0][j] & token) != 0)
{
putpixel(x, y, color);
}
x++;
token /= 2;
}
y++;
}
}
void InitGraphicsBuf(int x,int y,int xx,int yy,void **p)
{
*p=malloc(imagesize(x,y,xx,yy));
}
void ResumeGraphics(int x,int y,void *p)
{
putimage(x,y,p,COPY_PUT);
}
bool GetBuf(int x,int y,int xx,int yy,void *p) /*给图形指针赋值*/
{
if(!p)return 0;
getimage(x,y,xx,yy,p);
return 1;
}
bool MouseControl()
{
static int FIRST = 0;
if(!FIRST)
{
Get_xy(&mouse);
mouse.oldx = mouse.x;
mouse.oldy = mouse.y;
GetBuf(mouse.oldx,mouse.oldy,mouse.oldx+10,mouse.oldy+16,mouse_buf);
G_DrawMouse(mouse.x, mouse.y);
FIRST = 1;
}
mouse.but = Which_pressed(&mouse);
if(!mouse.but)
{
Get_xy(&mouse);
if(mouse.x != mouse.oldx | mouse.y != mouse.oldy)
{
ResumeGraphics(mouse.oldx, mouse.oldy, mouse_buf);
mouse.oldx = mouse.x;
mouse.oldy = mouse.y;
GetBuf(mouse.x, mouse.y, mouse.x + 10, mouse.y + 16, mouse_buf);
G_DrawMouse(mouse.x, mouse.y);
return 1;
}
else return 0;
}
else
{
Set_xy(mouse.oldx,mouse.oldy);
return 1;
}
}
void CreateREC(int x, int y ,int X, int Y, int mode)
{
int color1,color2;
if(mode == 1){ color1 = DARKGRAY;color2 = WHITE;}
if(mode == 2){ color1 = WHITE;color2 = DARKGRAY;}
setfillstyle(1, LIGHTGRAY);
bar(x, y, X, Y);
setcolor(color1);
line(x,y,X,y);
line(x,y,x,Y);
setcolor(color2);
line(x,Y,X,Y);
line(X,y,X,Y);
}
void G_SubWindow(int x, int y, int mode)
{
CreateREC(x - 5, y - 5, x + 75, y + 75, 1);
setfillstyle(1,BLACK);
bar(x, y, x + 70, y + 70);
line(x + 35, y, x + 35, y + 70);
line(x, y + 35, x + 70, y + 35);
if(mode = 1)
circle(x + 35, y + 35, 30);
if(mode = 2)
{
line(x + 35, y, x + 35, y + 70);
line(x, y + 35, x + 70, y + 35);
}
}
void G_MovementFace()
{
CreateREC(295, 145, 505, 355, 1);
setfillstyle(1,BLACK);
bar(300,150,500,350);
setcolor(WHITE);
line(400,150,400,350);
line(300,250,500,250);
}
double MaxA()
{
return Movement[0].A > Movement[1].A ? Movement[0].A : Movement[1].A;
}
void G_MovementShow(double Time)
{
double X = Movement[0].Coordinate(Time, Movement);
double Y = Movement[1].Coordinate(Time, Movement+1);
X = 400 + X * 90 / MaxA();
Y = 250 - Y * 90 / MaxA();
setcolor(WHITE);
circle(X,Y,Radius);
setfillstyle(1,WHITE);
floodfill(X,Y,WHITE);
}
void show(BUTTON *p, State mode)
{
if(mode != ON && mode != OFF) return;
CreateREC(p->x, p->y, p->x + strlen(p->contents)*8+ MARGIN, p->y + 8 + MARGIN*3, mode);
setcolor(BLUE);
outtextxy(p->x + MARGIN, p->y + MARGIN * 2, p->contents);
}
bool CheckClicked(BUTTON *p)
{
return mouse.x>p->x && mouse.x<p->x + strlen(p->contents) * 8 + MARGIN && mouse.y>p->y && mouse.y<p->y + 8 + MARGIN*2 && mouse.but;
}
bool SCheckClicked(SCROLLBUTTON *p)
{
int x = p->x + strlen(p->contents) * 8 + 3;
return mouse.x > x && mouse.x < x + SB_LENGTH + 3 && mouse.y > p->y && mouse.y < p->y +SB_WIDTH && mouse.but;
}
void Reset()
{
G_MovementFace();
G_SubWindow(SW_X[0],SW_Y[0],1);
G_SubWindow(SW_X[1],SW_Y[1],1);
TIME = 0.0;
}
int SetValue(int i, int place)
{
if(place < 0) place = 0;
switch(i)
{
case 0: SPEED = (double)(SB_LENGTH - 10 - place) / (SB_LENGTH - 10)* 1000;
}
}
void FullScreenShow(double n)
{
double X = Movement[0].Coordinate(n, Movement);
double Y = Movement[1].Coordinate(n, Movement+1);
X = 320 + X * 200 / MaxA();
Y = 240 - Y * 200 / MaxA();
setcolor(WHITE);
circle(X,Y,Radius + 2);
setfillstyle(1,WHITE);
floodfill(X,Y,WHITE);
}
void FullScreenPROC()
{
double n;
int IsFullScreen = 1;
cleardevice();
setcolor(WHITE);
line(0, 240, 639, 240);
line(320, 0, 320, 479);
for(n = 0; n <= TIME; n += 0.005)
FullScreenShow(n);
while(IsFullScreen)
{
if( bioskey(1) ){ getch();IsFullScreen = 0;}
TIME += 0.005;
FullScreenShow(TIME);
delay(SPEED);
}
G_InitInterface();
for(n = 0; n <= TIME; n+= 0.01)
G_MovementShow(n);
}
void G_AddButton()
{
int i;
for(i = 0; i < BUTTONNUM; i++)
Button[i].Show(Button + i, ON);
for(i = 0; i < SCROLLBUTTONNUM; i++)
SButton[i].Show(SButton + i);
}
void G_Bar(SCROLLBUTTON *p, int place)
{
int tx = p->x + strlen(p->contents) * 8 + 3;
CreateREC(tx + place, p->y + 2, tx + place + 10, p->y + 18,UP);
}
void SB_show(SCROLLBUTTON *p)
{
int tx = p->x + strlen(p->contents) * 8 + 2;
setfillstyle(1,LIGHTGRAY); /* first clear the screen */
bar(tx, p->y, tx + SB_WIDTH, p->y + SB_LENGTH);
outtextxy(p->x, p->y + SB_WIDTH /2 - 4, p->contents);
setcolor(BLACK);
line(tx, p->y + SB_WIDTH / 2 - 3, tx, p->y + SB_WIDTH / 2 + 3);
line(tx + SB_LENGTH , p->y + SB_WIDTH / 2 - 3, tx + SB_LENGTH, p->y + SB_WIDTH / 2 + 3);
line(tx, p->y + SB_WIDTH / 2, tx +SB_LENGTH , p->y + SB_WIDTH / 2);
G_Bar(p, p->place);
}
int MoveBar(SCROLLBUTTON *p)
{
int tx = p->x + strlen(p->contents) * 8, oldx,oldy,token = 0;
rectangle(tx +1, p->y, tx + SB_LENGTH + 3, p->y + SB_WIDTH);
oldx = tx + 3 + p->place;
ResumeGraphics(mouse.oldx, mouse.oldy, mouse_buf);
if(mouse.x > tx + 3 + p->place && mouse.x < tx + 3 + p->place + 10 && mouse.y > p->y + 2 && mouse.y < p->y + 18)
{
while(Which_pressed(&mouse) )
{
if(mouse.x != oldx && mouse.x > tx + 2 && mouse.x < tx + 3 + SB_LENGTH - 10 )
{
ResumeGraphics(oldx, mouse.y, mouse_buf);
setfillstyle(1, LIGHTGRAY); /* clear first */
bar(tx + 3 + p->place, p->y +2, tx + 3 + p->place + 10, p->y + 18);
p->place = mouse.x - tx - 3;
setcolor(BLACK);
line(tx + 2, p->y + SB_WIDTH / 2 - 3, tx + 2, p->y + SB_WIDTH / 2 + 3);
line(tx + 2 + SB_LENGTH, p->y + SB_WIDTH / 2 - 3, tx + 2 + SB_LENGTH, p->y + SB_WIDTH / 2 + 3);
line(tx + 2, p->y + SB_WIDTH / 2, tx + 2 +SB_LENGTH , p->y + SB_WIDTH / 2);
G_Bar(p, p->place);
setcolor(WHITE);
rectangle(tx +1, p->y, tx + SB_LENGTH + 3, p->y + SB_WIDTH);
GetBuf(mouse.x, mouse.y, mouse.x + 10, mouse.y +16, mouse_buf);
G_DrawMouse(mouse.x, mouse.y);
oldx = mouse.x;
token = 1;
}
oldy = mouse.y;
Get_xy(&mouse);
mouse.y = oldy;
}
if(token){ResumeGraphics(oldx, mouse.y, mouse_buf);token = 0;}
}
else if(SCheckClicked(p) )
{
if(mouse.x <= tx + SB_LENGTH - 8){
setfillstyle(1, LIGHTGRAY);
bar(tx + 3 + p->place, p->y +2, tx + 3 + p->place + 10, p->y + 18);
p->place = mouse.x - tx - 3;
if(p->place > tx + SB_LENGTH - 12)p->place = tx + SB_LENGTH - 12;
setcolor(BLACK);
line(tx + 2, p->y + SB_WIDTH / 2 - 3, tx + 2, p->y + SB_WIDTH / 2 + 3);
line(tx + 2 + SB_LENGTH, p->y + SB_WIDTH / 2 - 3, tx + 2 + SB_LENGTH, p->y + SB_WIDTH / 2 + 3);
line(tx + 2, p->y + SB_WIDTH / 2, tx + 2 +SB_LENGTH, p->y + SB_WIDTH / 2);
G_Bar(p, p->place);
setcolor(WHITE);
rectangle(tx +1, p->y, tx + SB_LENGTH + 3, p->y + SB_WIDTH);
}
}
setcolor(LIGHTGRAY);
rectangle(tx +1, p->y, tx + SB_LENGTH + 3, p->y + SB_WIDTH);
GetBuf(mouse.x, mouse.y, mouse.x + 10, mouse.y +16, mouse_buf);
mouse.oldx = mouse.x, mouse.oldy = mouse.y;
return p->place;
}
void SubWindowShow()
{
int x,y,i,Token = 0;
for(i = 0;i < 2; i++)
{
if(Token)
{
setcolor(WHITE);
line(SW_X[i] + 35, SW_Y[i], SW_X[i] + 35, SW_Y[i] + 70);
line(SW_X[i], SW_Y[i] + 35, SW_X[i] + 70, SW_Y[i] + 35);
Token = 0;
}
if(TIME)
{
TIME -= 0.01;
x = 30 * cos( (TIME * Movement[i].W + Movement[i].Angle) );
y = 30 * sin( (TIME * Movement[i].W + Movement[i].Angle) );
setcolor(BLACK);
if(x && y)
line(SW_X[i] + 35, SW_Y[i] + 35, SW_X[i] + 35 + x, SW_Y[i] + 35 + y);
circle(SW_X[i] + 35 + x, SW_Y[i] + 35 + y, 2);
TIME += 0.01;
}
x = 30 * cos( (TIME * Movement[i].W + Movement[i].Angle) );
y = 30 * sin( (TIME * Movement[i].W + Movement[i].Angle) );
setcolor(YELLOW);
line(SW_X[i] + 35, SW_Y[i] + 35, SW_X[i] + 35 + x, SW_Y[i] + 35 + y);
circle(SW_X[i] + 35 + x, SW_Y[i] + 35 + y, 2);
setfillstyle(1,BLACK);
floodfill(SW_X[i] + 35 + x, SW_Y[i] + 35 + y, YELLOW);
circle(SW_X[i] + 35, SW_Y[i] + 35, 30);
if(!(x && y))
{
setcolor(WHITE);
line(SW_X[i] + 35, SW_Y[i], SW_X[i] + 35, SW_Y[i] + 70);
line(SW_X[i], SW_Y[i] + 35, SW_X[i] + 70, SW_Y[i] + 35);
Token = 1;
}
}
}
bool init()
{
int driver = VGA, drivermode = VGAHI;
initgraph(&driver, &drivermode, "");
if(graphresult() != 0)
{
printf("can't initgraph");
return false;
}
InitGraphicsBuf(0,0,10,16,&mouse_buf);
cleardevice();
return true;
}
void G_InitInterface()
{
setfillstyle(1,LIGHTGRAY);
bar(0,0,639,479);
G_MovementFace();
G_SubWindow(SW_X[0],SW_Y[0],1);
G_SubWindow(SW_X[1],SW_Y[1],1);
G_AddButton();
}
main()
{
int i;
init();
G_InitInterface();
while(PROC)
{
if(bioskey(1))PROC = false;
for(i = 0; i< BUTTONNUM; i++)
if(Button[i].Clicked(Button + i))
{
Button[i].Show(Button + i, OFF);
delay(10000);
Button[i].Show(Button + i, ON);
Button[i].Function();
break;
}
for(i = 0; i< SCROLLBUTTONNUM; i++)
if(SButton[i].Clicked(SButton + i) )
{
SetValue(i, SButton[i].Function(SButton + i) );
break;
}
MouseControl();
SubWindowShow();
G_MovementShow(TIME);
TIME+=0.01;
delay(SPEED);
}
closegraph();
}
评论