I cleaned it up example and made it geared towards OS4 and Reaction oriented for compiling straight with GCC.
Code: Select all
/* SuperBitmap Example
gcc -o lines lines.c
*/
/**
** lines.c-- Window Super bitmap example.
**
**
**/
#include <dos/dos.h>
#include <intuition/icclass.h>
#include <classes/window.h>
#include <gadgets/scroller.h>
#include <gadgets/layout.h>
#include <proto/intuition.h>
#include <proto/exec.h>
#include <proto/utility.h>
#include <proto/layers.h>
#include <proto/graphics.h>
#define WIDTH_SUPER (800)
#define HEIGHT_SUPER (600)
#define MINWIDTH (150)
#define MINHEIGHT (150)
#define LAYERXOFFSET(x) (x->RPort->Layer->Scroll_X)
#define LAYERYOFFSET(x) (x->RPort->Layer->Scroll_Y)
enum
{
WID_MAIN = 0,
WID_LAST
};
enum
{
OID_MAIN = 0,
OID_VPROP,
OID_HPROP,
OID_LAST
};
struct IntuitionIFace *IIntuition;
struct GraphicsIFace *IGraphics;
struct LayersIFace *ILayers;
static struct Window *windows[WID_LAST];
static Object *objects[OID_LAST];
static struct Hook idcmphook;
/* Prototypes for our functions */
void initBorderProps(struct Screen *screen);
void doNewSize();
void doDrawStuff();
void doMsgLoop();
void superWindow(struct Screen *screen);
void slideBitMap(struct Window *win, int16 dX, int16 dY);
int main()
{
struct Screen* screen;
struct Library* IntuitionBase = IExec->OpenLibrary("intuition.library", 50);
IIntuition = (struct IntuitionIFace*)IExec->GetInterface(IntuitionBase,
"main", 1, NULL);
struct Library* GfxBase = IExec->OpenLibrary("graphics.library", 50);
IGraphics = (struct GraphicsIFace*)IExec->GetInterface(GfxBase, "main", 1, NULL);
struct Library* LayersBase = IExec->OpenLibrary("layers.library", 50);
ILayers = (struct LayersIFace*)IExec->GetInterface(LayersBase, "main", 1, NULL);
if (IIntuition != NULL && IGraphics != NULL && ILayers != NULL) {
if ((screen = IIntuition->LockPubScreen(NULL)) != NULL) {
superWindow(screen);
IIntuition->UnlockPubScreen(NULL, screen);
}
}
IExec->DropInterface((struct Interface*)ILayers);
IExec->CloseLibrary(LayersBase);
IExec->DropInterface((struct Interface*)IGraphics);
IExec->CloseLibrary(GfxBase);
IExec->DropInterface((struct Interface*)IIntuition);
IExec->CloseLibrary(IntuitionBase);
return 0;
}
void IDCMPHook(struct Hook *hook,Object *object, struct IntuiMessage *msg)
{
if (msg->Class == IDCMP_IDCMPUPDATE) {
int16 dX = 0;
int16 dY = 0;
int32 pos;
struct Window *win = windows[WID_MAIN];
if (win != NULL) {
uint32 gadgetid = IUtility->GetTagData(GA_ID, 0,(struct TagItem *)msg->IAddress);
if (IIntuition->GetAttr(SCROLLER_Top, objects[gadgetid],(uint32 *)&pos)) {
switch (gadgetid) {
case OID_VPROP:
dY = pos - LAYERYOFFSET(win);
break;
case OID_HPROP:
dX = pos - LAYERXOFFSET(win);
break;
}
if (dX || dY) {
slideBitMap(win, dX, dY);
}
}
}
}
}
void superWindow(struct Screen *myscreen)
{
struct BitMap* bigBitMap = IGraphics->AllocBitMapTags(WIDTH_SUPER, HEIGHT_SUPER,myscreen->BitMap.Depth,
BMATags_Friend, myscreen->BitMap, BMATags_Displayable,TRUE, BMATags_Clear,0, TAG_END);
if (bigBitMap != NULL) {
struct MsgPort *AppPort = IExec->AllocSysObjectTags(ASOT_PORT, TAG_DONE);
if ( AppPort != NULL )
{
idcmphook.h_Entry = (uint32 (*)())IDCMPHook;
idcmphook.h_SubEntry = NULL;
if ((objects[OID_MAIN] = IIntuition->NewObject(NULL, "window.class",
WA_ScreenTitle, "SuperBitmap",
WA_Title, "Lines",
WA_Activate, TRUE,
WA_DepthGadget, TRUE,
WA_DragBar, TRUE,
WA_CloseGadget, TRUE,
WA_SizeGadget, TRUE,
WA_Top, 10,
WA_Left, 10,
WA_MinWidth, MINWIDTH,
WA_MinHeight, MINHEIGHT,
WA_Width, MINWIDTH,
WA_Height, MINHEIGHT,
WA_IDCMP, IDCMP_NEWSIZE | IDCMP_IDCMPUPDATE,
WA_PubScreen, myscreen, WA_SuperBitMap, bigBitMap,
WA_NoCareRefresh, TRUE,
WA_GimmeZeroZero, TRUE,
WINDOW_IDCMPHook,&idcmphook,
WINDOW_IDCMPHookBits, IDCMP_IDCMPUPDATE,
WINDOW_HorizProp, 1,
WINDOW_VertProp, 1,
WINDOW_AppPort, AppPort, TAG_DONE))!= NULL) {
// Open the window.
if (windows[WID_MAIN] = (struct Window *)IIntuition->IDoMethod(objects[OID_MAIN], WM_OPEN)) {
/* adjust props to represent portion visible */
doNewSize();
doDrawStuff();
/* process the window, return on IDCMP_CLOSEWINDOW */
doMsgLoop();
}
IIntuition->DisposeObject(objects[OID_MAIN]);
}
IExec->FreeSysObject(ASOT_PORT, AppPort);
}
IGraphics->FreeBitMap(bigBitMap);
}
}
void slideBitMap(struct Window *win, int16 Dx, int16 Dy)
{
ILayers->ScrollLayer(0, win->RPort->Layer, Dx, Dy);
}
/*
** Update the prop gadgets and bitmap positioning when the size changes.
*/
void doNewSize()
{
struct Window *win = windows[WID_MAIN];
if (win != NULL) {
IIntuition->GetAttr(WINDOW_HorizObject, objects[OID_MAIN],(uint32 *)&objects[OID_HPROP]);
if (objects[OID_HPROP]) {
if (win->GZZWidth >= WIDTH_SUPER)
slideBitMap(win, -LAYERXOFFSET(win), 0);
IIntuition->RefreshSetGadgetAttrs((APTR)objects[OID_HPROP], win,NULL,
GA_ID, OID_HPROP,
SCROLLER_Top, LAYERXOFFSET(win),
SCROLLER_Total, WIDTH_SUPER,
SCROLLER_Visible, win->GZZWidth,
ICA_TARGET, ICTARGET_IDCMP,
TAG_DONE);
}
IIntuition->GetAttr(WINDOW_VertObject, objects[OID_MAIN],(uint32 *)&objects[OID_VPROP]);
if (objects[OID_VPROP]) {
if (win->GZZHeight >= HEIGHT_SUPER)
slideBitMap(win, 0, -LAYERYOFFSET(win));
IIntuition->RefreshSetGadgetAttrs((APTR)objects[OID_VPROP], win,NULL,
GA_ID, OID_VPROP,
SCROLLER_Top, LAYERYOFFSET(win),
SCROLLER_Total, HEIGHT_SUPER,
SCROLLER_Visible, win->GZZHeight,
ICA_TARGET, ICTARGET_IDCMP,
TAG_DONE);
}
}
}
int16 RangeRand(uint32 maxValue)
{
static struct RandomState range = {0xFFFF,0};
return IUtility->Random(&range) % maxValue;
}
void doDrawStuff()
{
struct Window *win = windows[WID_MAIN];
if (win != NULL) {
/* clear the bitplanes */
IGraphics->SetRast(win->RPort, 0);
IGraphics->SetDrMd(win->RPort, JAM1);
int16 x1, y1, x2, y2;
int16 pen, ncolors, deltx, delty;
ncolors = 1 << win->WScreen->BitMap.Depth;
deltx = RangeRand(6) + 2;
delty = RangeRand(6) + 2;
pen = RangeRand(ncolors - 1) + 1;
IGraphics->SetAPen(win->RPort, pen);
for (x1 = 0, y1 = 0, x2 = WIDTH_SUPER - 1, y2 = HEIGHT_SUPER - 1;
x1 < WIDTH_SUPER; x1 += deltx, x2 -= deltx) {
IGraphics->Move(win->RPort, x1, y1);
IGraphics->Draw(win->RPort, x2, y2);
}
pen = RangeRand(ncolors - 1) + 1;
IGraphics->SetAPen(win->RPort, pen);
for (x1 = 0, y1 = 0, x2 = WIDTH_SUPER - 1, y2 = HEIGHT_SUPER - 1;
y1 < HEIGHT_SUPER; y1 += delty, y2 -= delty) {
IGraphics->Move(win->RPort, x1, y1);
IGraphics->Draw(win->RPort, x2, y2);
}
}
}
void doMsgLoop()
{
// Obtain the window wait signal mask.
uint32 signal = 0;
IIntuition->GetAttr(WINDOW_SigMask, objects[OID_MAIN], &signal);
// Input Event Loop
BOOL done = FALSE;
while (!done){
uint32 wait = IExec->Wait(signal | SIGBREAKF_CTRL_C);
if ( wait & SIGBREAKF_CTRL_C ){
done = TRUE;
break;
}
if ( wait & signal ) {
uint32 result = WMHI_LASTMSG;
int16 code = 0;
while ((result = IIntuition->IDoMethod(objects[OID_MAIN], WM_HANDLEINPUT, &code)) != WMHI_LASTMSG){
switch (result & WMHI_CLASSMASK) {
case WMHI_NEWSIZE:
doNewSize();
doDrawStuff();
break;
case WMHI_CLOSEWINDOW:
windows[WID_MAIN] = NULL;
done = TRUE;
break;
case WMHI_ICONIFY:
IIntuition->IDoMethod(objects[OID_MAIN], WM_ICONIFY);
windows[WID_MAIN] = NULL;
break;
case WMHI_UNICONIFY:
windows[WID_MAIN] = (struct Window *)IIntuition->IDoMethod(objects[OID_MAIN], WM_OPEN);
doNewSize();
doDrawStuff();
break;
}
}
}
}
}