📄 winball.c
字号:
#include <ugl/uglWin.h>
/* This structure is used to store data used by the bouncing ball window */
typedef struct ball_win_data
{
UGL_TASK_ID taskId;
WIN_ID winId;
UGL_BITMAP_ID ballBitmapId;
UGL_POINT ballPosition;
UGL_VECTOR ballSpeed;
} BALL_WIN_DATA;
/* forward declaration of callbacks */
UGL_LOCAL UGL_STATUS cbAppCreate (WIN_APP_ID appId, WIN_MSG * pMsg,
void * pData, void * pParam);
UGL_LOCAL UGL_STATUS cbWinDraw (WIN_ID winId, WIN_MSG * pMsg,
BALL_WIN_DATA * pData, void * pParam);
UGL_LOCAL UGL_STATUS cbWinManage (WIN_ID winId, WIN_MSG * pMsg,
BALL_WIN_DATA * pData, void * pParam);
UGL_LOCAL UGL_STATUS cbWinUnmanage (WIN_ID winId, WIN_MSG * pMsg,
BALL_WIN_DATA * pData, void * pParam);
UGL_LOCAL UGL_STATUS cbWinDestroy (WIN_ID winId, WIN_MSG * pMsg,
BALL_WIN_DATA * pData, void * pParam);
/* Callbacks used by the ball application */
WIN_APP_CB_ITEM ballAppCallbacks [] =
{
{ MSG_APP_CREATE, 0, cbAppCreate, UGL_NULL },
{ 0, 0, UGL_NULL, UGL_NULL }
};
/* Callbacks used by the ball window */
WIN_CB_ITEM ballWinCallbacks [] =
{
{ MSG_DRAW, 0, (WIN_CB *)cbWinDraw, UGL_NULL },
{ MSG_MANAGE, 0, (WIN_CB *)cbWinManage, UGL_NULL },
{ MSG_UNMANAGE, 0, (WIN_CB *)cbWinUnmanage, UGL_NULL },
{ MSG_DESTROY, 0, (WIN_CB *)cbWinDestroy, UGL_NULL },
{ 0, 0, UGL_NULL, UGL_NULL }
};
/***************************************************************************
* winBall - run the bouncing ball example
*
* This routine starts the bouncing ball example by creating its
* application context.
*
*/
void winBall (void)
{
/* create the bouncing ball application context */
winAppCreate ("winBall", 0, 0, 0, ballAppCallbacks);
}
/***************************************************************************
* ballMoveTask - make the bouncing ball bounce
*
* This routine runs in its own task and continually moves the bouncing ball.
*
*/
void ballMoveTask (BALL_WIN_DATA * pData)
{
WIN_ID winId = pData->winId;
pData->taskId = uglOSGetTaskIdSelf ();
/* window ends task by setting pData->winId to NULL */
while (pData->winId != UGL_NULL_ID)
{
UGL_RECT winRect;
UGL_RECT ballRect;
/* get the window rectangle */
winDrawRectGet (winId, &winRect);
/* save old ball position */
ballRect.left = pData->ballPosition.x;
ballRect.right = pData->ballPosition.x + 31;
ballRect.top = pData->ballPosition.y;
ballRect.bottom = pData->ballPosition.y + 31;
/* move the ball */
pData->ballPosition.x += pData->ballSpeed.x;
pData->ballPosition.y += pData->ballSpeed.y;
/* test for bounce (direction change) */
if (pData->ballPosition.x < winRect.left)
{
pData->ballPosition.x = winRect.left;
pData->ballSpeed.x *= -1;
}
else if (pData->ballPosition.x > winRect.right - 31)
{
pData->ballPosition.x = winRect.right - 31;
pData->ballSpeed.x *= -1;
}
if (pData->ballPosition.y < winRect.top)
{
pData->ballPosition.y = winRect.top;
pData->ballSpeed.y *= -1;
}
else if (pData->ballPosition.y > winRect.bottom - 31)
{
pData->ballPosition.y = winRect.bottom - 31;
pData->ballSpeed.y *= -1;
}
/* ----- invalidate the window to cause ball to redraw ----- */
/* lock window so it won't redraw until invalidation is complete */
winLock (winId);
/* invalidate the old ball position */
winRectInvalidate (winId, &ballRect);
/* invalidate the new ball position */
ballRect.left = pData->ballPosition.x;
ballRect.right = pData->ballPosition.x + 31;
ballRect.top = pData->ballPosition.y;
ballRect.bottom = pData->ballPosition.y + 31;
winRectInvalidate (winId, &ballRect);
/* unlock the window */
winUnlock (winId);
/* wait a clock tick */
uglOSTaskDelay (1);
}
/* signal that task is finished and window can be destroyed */
pData->taskId = UGL_NULL_ID;
}
/***************************************************************************
*
* cbAppCreate - initialize the application
*
* This callback routine initializes the bouncing ball application by creating
* the bouncing ball window and attaching it to the default display.
*
*/
UGL_LOCAL UGL_STATUS cbAppCreate
(
WIN_APP_ID appId, /* application ID */
WIN_MSG * pMsg, /* message */
void * pData, /* message queue associated with application */
void * pParam /* parameter passed to winAppCbAdd() */
)
{
WIN_ID winId;
/* create the bouncing ball window */
winId = winCreate (appId, UGL_NULL, WIN_ATTRIB_FRAMED | WIN_ATTRIB_VISIBLE,
50, 50, 150, 200, UGL_NULL, sizeof (BALL_WIN_DATA),
ballWinCallbacks);
/* !!! should use attribute !!! */
winDrawModeSet (winId, WIN_DRAW_MODE_OFF_SCREEN, UGL_NULL);
winAttach (winId, UGL_NULL_ID, UGL_NULL_ID);
return (UGL_STATUS_OK);
}
/***************************************************************************
*
* cbWinDraw - draw the ball window
*
* This callback routine draws the ball window in response to MSG_DRAW
* messages. (MSG_DRAW messages are sent when the window is exposed or otherwise
* invalidated.)
*
*/
UGL_LOCAL UGL_STATUS cbWinDraw
(
WIN_ID winId, /* window ID */
WIN_MSG * pMsg, /* message */
BALL_WIN_DATA * pData, /* data passed to winCreate() */
void * pParam /* parameter to winAppCbAdd() */
)
{
/* draw the background */
uglLineWidthSet (pMsg->data.draw.gcId, 0);
uglBackgroundColorSet (pMsg->data.draw.gcId, WIN_GREEN);
uglRectangle (pMsg->data.draw.gcId,
pMsg->data.draw.rect.left,
pMsg->data.draw.rect.top,
pMsg->data.draw.rect.right,
pMsg->data.draw.rect.bottom);
/* draw the ball */
uglBitmapBlt (pMsg->data.draw.gcId, pData->ballBitmapId, 0, 0, 31, 31,
UGL_DEFAULT_ID, pData->ballPosition.x,
pData->ballPosition.y);
return (UGL_STATUS_FINISHED);
}
/***************************************************************************
*
* cbWinManage - create resources used by bouncing ball window
*
* This callback routine creates the resources (ball bitmap) used by the
* bouncing ball window. By waiting for the MSG_MANAGE message, the window
* knows its associated display. (MSG_MANAGE is sent when a window is
* attached to a display.)
*
*/
UGL_LOCAL UGL_STATUS cbWinManage
(
WIN_ID winId, /* window ID */
WIN_MSG * pMsg, /* message */
BALL_WIN_DATA * pData, /* data associated with window */
void * pParam /* parameter assicuated with callback */
)
{
UGL_DEVICE_ID displayId;
UGL_GC_ID gcId;
UGL_DIB ballDib;
/* get display associated with window */
displayId = winDisplayGet (winId);
/* create the ball bitmap */
ballDib.width = 32;
ballDib.height = 32;
pData->ballBitmapId = uglBitmapCreate (displayId, &ballDib,
UGL_DIB_INIT_NONE, 0, UGL_NULL);
/* draw a ball in the ballBitmap */
gcId = uglGcCreate (displayId);
uglDefaultBitmapSet (gcId, pData->ballBitmapId);
uglLineWidthSet (gcId, 0);
uglBackgroundColorSet (gcId, WIN_GREEN);
uglRectangle (gcId, 0, 0, 31, 31);
uglLineWidthSet (gcId, 1);
uglForegroundColorSet (gcId, WIN_BLACK);
uglBackgroundColorSet (gcId, WIN_YELLOW);
uglEllipse (gcId, 0, 0, 31, 31, 0, 0, 0, 0);
uglGcDestroy (gcId);
/* initialize ball window data */
pData->winId = winId;
pData->ballPosition.x = 0;
pData->ballPosition.y = 0;
pData->ballSpeed.x = 3;
pData->ballSpeed.y = 3;
/* start task to move bouncing ball */
uglOSTaskCreate ("tBallMove", (UGL_FPTR)ballMoveTask, 250, 0, 0x1000,
(int)pData, 0, 0, 0, 0);
return (UGL_STATUS_OK);
}
/***************************************************************************
*
* cbWinUnmanage - free resources used by bouncing ball window
*
* This callback routine frees the resources (ball bitmap) used by the
* bouncing ball window.
*
*/
UGL_LOCAL UGL_STATUS cbWinUnmanage
(
WIN_ID winId, /* window ID */
WIN_MSG * pMsg, /* message */
BALL_WIN_DATA * pData, /* data associated with window */
void * pParam /* parameter assicuated with callback */
)
{
/* signal ball move task to exit */
pData->winId = UGL_NULL_ID;
/* clean up */
uglBitmapDestroy (winDisplayGet (winId), pData->ballBitmapId);
return (UGL_STATUS_OK);
}
/***************************************************************************
*
* cbWinUnmanage - free resources used by bouncing ball window
*
* This callback routine frees the resources (ball bitmap) used by the
* bouncing ball window.
*
*/
UGL_LOCAL UGL_STATUS cbWinDestroy
(
WIN_ID winId, /* window ID */
WIN_MSG * pMsg, /* message */
BALL_WIN_DATA * pData, /* data associated with window */
void * pParam /* parameter assicuated with callback */
)
{
/* wait for ball move task to exit */
while (pData->taskId != UGL_NULL_ID)
uglOSTaskDelay (100);
return (UGL_STATUS_OK);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -