hacking away at this
This commit is contained in:
commit
3c6cc29c52
|
@ -0,0 +1 @@
|
||||||
|
*.o
|
|
@ -0,0 +1,423 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
// this is the manual for the original intuition stuff.
|
||||||
|
// not much here is different: https://ia801905.us.archive.org/33/items/Amiga_Intuition_Reference_Manaual_1985_Adn-Wesley_Publishing_Company/Amiga_Intuition_Reference_Manaual_1985_Addison-Wesley_Publishing_Company.pdf
|
||||||
|
#include <proto/intuition.h>
|
||||||
|
#include <proto/dos.h>
|
||||||
|
#include <proto/exec.h>
|
||||||
|
#include <proto/diskfont.h>
|
||||||
|
|
||||||
|
#include <clib/timer_protos.h>
|
||||||
|
#include <intuition/gadgetclass.h>
|
||||||
|
|
||||||
|
// gadtools gives a proper set of components for building UIs.
|
||||||
|
// http://amigadev.elowar.com/read/ADCD_2.1/Libraries_Manual_guide/node0278.html
|
||||||
|
#include <proto/gadtools.h>
|
||||||
|
#include <proto/graphics.h>
|
||||||
|
|
||||||
|
#define WINDOW_WIDTH (240)
|
||||||
|
#define WINDOW_HEIGHT (100)
|
||||||
|
#define WINDOW_TITLE "Topaz Timer"
|
||||||
|
|
||||||
|
#define WINDOW_CHROME_WIDTH (4)
|
||||||
|
|
||||||
|
struct NewWindow winlayout = {
|
||||||
|
20, 20, // x, y
|
||||||
|
WINDOW_WIDTH, WINDOW_HEIGHT, // w, h
|
||||||
|
0, 1, // detailpen, blockpen,
|
||||||
|
// you have to add the different gadget types you're looking for
|
||||||
|
// http://amigadev.elowar.com/read/ADCD_2.1/Includes_and_Autodocs_2._guide/node0106.html
|
||||||
|
IDCMP_CLOSEWINDOW | BUTTONIDCMP | SLIDERIDCMP, // IDCMP flags
|
||||||
|
WFLG_SMART_REFRESH | WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET | WFLG_ACTIVATE, // window flag from Window struct
|
||||||
|
NULL, // FirstGadget
|
||||||
|
NULL, // menu checkmark
|
||||||
|
WINDOW_TITLE, // title
|
||||||
|
NULL, // default screen
|
||||||
|
NULL, // bitmap
|
||||||
|
WINDOW_WIDTH, WINDOW_HEIGHT, // min size
|
||||||
|
WINDOW_WIDTH, WINDOW_HEIGHT, // max size,
|
||||||
|
WBENCHSCREEN // screen where you want the window to open
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TextAttr Topaz80 = { "topaz.font", 8, 0, 0 };
|
||||||
|
|
||||||
|
// There's no native 16 pixel Topaz font so we'll use
|
||||||
|
// diskfont.library to make one.
|
||||||
|
struct TextAttr Topaz160 = { "topaz.font", 16, 0, 0 };
|
||||||
|
|
||||||
|
#define START_STOP_BUTTON_ID 0
|
||||||
|
#define RESET_BUTTON_ID 1
|
||||||
|
#define HOURS_SLIDER_ID 2
|
||||||
|
#define MINUTES_SLIDER_ID 3
|
||||||
|
#define SECONDS_SLIDER_ID 5
|
||||||
|
|
||||||
|
#define TIMER_COUNTDOWN_COUNT 3
|
||||||
|
|
||||||
|
struct Window *window;
|
||||||
|
struct TextFont *topaz80Font;
|
||||||
|
struct TextFont *topaz160Font;
|
||||||
|
struct Screen *screen;
|
||||||
|
void *visualInfo;
|
||||||
|
|
||||||
|
struct Gadget *timerGadget;
|
||||||
|
|
||||||
|
unsigned int uiHours = 0;
|
||||||
|
unsigned int uiMinutes = 12;
|
||||||
|
unsigned int uiSeconds = 0;
|
||||||
|
|
||||||
|
unsigned int activeHours;
|
||||||
|
unsigned int activeMinutes;
|
||||||
|
unsigned int activeSeconds;
|
||||||
|
|
||||||
|
char timerText[9];
|
||||||
|
|
||||||
|
BOOL timerIsRunning;
|
||||||
|
|
||||||
|
struct Device *TimerBase;
|
||||||
|
static struct IORequest timereq;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize system stuff.
|
||||||
|
*/
|
||||||
|
int setup() {
|
||||||
|
// http://amigadev.elowar.com/read/ADCD_2.1/Includes_and_Autodocs_3._guide/node0308.html
|
||||||
|
// make sure the font exists on the computer
|
||||||
|
if (NULL == (topaz80Font = OpenFont(&Topaz80))) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NULL == (topaz160Font = OpenDiskFont(&Topaz160))) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NULL == (screen = LockPubScreen(NULL))) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NULL == (visualInfo = GetVisualInfo(screen, TAG_END))) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 != (OpenDevice("timer.device", 0, &timereq, 0))) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TimerBase = timereq.io_Device;
|
||||||
|
|
||||||
|
activeHours = uiHours;
|
||||||
|
activeMinutes = uiMinutes;
|
||||||
|
activeSeconds = uiSeconds;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tear down system stuff.
|
||||||
|
*/
|
||||||
|
void teardown() {
|
||||||
|
if (visualInfo) FreeVisualInfo(visualInfo);
|
||||||
|
if (screen) UnlockPubScreen(NULL, screen);
|
||||||
|
if (topaz80Font) CloseFont(topaz80Font);
|
||||||
|
if (topaz160Font) CloseFont(topaz160Font);
|
||||||
|
if (timereq.io_Device) CloseDevice(&timereq);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Gadget *buildUI() {
|
||||||
|
struct NewGadget ng;
|
||||||
|
struct Gadget *currentGadget;
|
||||||
|
struct Gadget *glist;
|
||||||
|
|
||||||
|
currentGadget = CreateContext(&glist);
|
||||||
|
|
||||||
|
ng.ng_LeftEdge = WINDOW_CHROME_WIDTH;
|
||||||
|
// TODO: constantize these
|
||||||
|
ng.ng_TopEdge = 11;
|
||||||
|
ng.ng_Height = 12;
|
||||||
|
|
||||||
|
ng.ng_Width = 0;
|
||||||
|
ng.ng_GadgetText = NULL;
|
||||||
|
ng.ng_TextAttr = &Topaz80;
|
||||||
|
ng.ng_VisualInfo = visualInfo;
|
||||||
|
|
||||||
|
// TODO: use constants to indicate which gadget is which
|
||||||
|
ng.ng_GadgetID = NULL;
|
||||||
|
ng.ng_Flags = PLACETEXT_IN;
|
||||||
|
|
||||||
|
// Timer display
|
||||||
|
ng.ng_Width = WINDOW_WIDTH - WINDOW_CHROME_WIDTH * 2;
|
||||||
|
ng.ng_TextAttr = &Topaz160;
|
||||||
|
ng.ng_Height = 20;
|
||||||
|
|
||||||
|
timerGadget = currentGadget = CreateGadget(
|
||||||
|
TEXT_KIND,
|
||||||
|
currentGadget,
|
||||||
|
&ng,
|
||||||
|
GTTX_Text, "",
|
||||||
|
GTTX_Justification, GTJ_CENTER,
|
||||||
|
GTTX_Border, TRUE,
|
||||||
|
TAG_END
|
||||||
|
);
|
||||||
|
|
||||||
|
ng.ng_TextAttr = &Topaz80;
|
||||||
|
ng.ng_Height = 12;
|
||||||
|
|
||||||
|
ng.ng_Width = (WINDOW_WIDTH - WINDOW_CHROME_WIDTH * 2) / 2;
|
||||||
|
ng.ng_TopEdge += 18;
|
||||||
|
if (timerIsRunning) {
|
||||||
|
ng.ng_GadgetText = "_Stop";
|
||||||
|
} else {
|
||||||
|
ng.ng_GadgetText = "_Start";
|
||||||
|
}
|
||||||
|
|
||||||
|
ng.ng_GadgetID = START_STOP_BUTTON_ID;
|
||||||
|
|
||||||
|
currentGadget = CreateGadget(
|
||||||
|
BUTTON_KIND,
|
||||||
|
currentGadget,
|
||||||
|
&ng,
|
||||||
|
GT_Underscore, '_',
|
||||||
|
TAG_END
|
||||||
|
);
|
||||||
|
|
||||||
|
ng.ng_LeftEdge += (WINDOW_WIDTH - WINDOW_CHROME_WIDTH * 2) / 2;
|
||||||
|
ng.ng_GadgetText = "_Reset";
|
||||||
|
ng.ng_GadgetID = RESET_BUTTON_ID;
|
||||||
|
|
||||||
|
currentGadget = CreateGadget(
|
||||||
|
BUTTON_KIND,
|
||||||
|
currentGadget,
|
||||||
|
&ng,
|
||||||
|
GT_Underscore, '_',
|
||||||
|
GA_Disabled, timerIsRunning,
|
||||||
|
TAG_END
|
||||||
|
);
|
||||||
|
|
||||||
|
ng.ng_LeftEdge = 85;
|
||||||
|
ng.ng_Width = (WINDOW_WIDTH - WINDOW_CHROME_WIDTH * 2) - 85 + 4;
|
||||||
|
ng.ng_TopEdge += 12;
|
||||||
|
ng.ng_GadgetText = "Hours: ";
|
||||||
|
ng.ng_Flags = PLACETEXT_LEFT;
|
||||||
|
ng.ng_GadgetID = HOURS_SLIDER_ID;
|
||||||
|
|
||||||
|
currentGadget = CreateGadget(
|
||||||
|
SLIDER_KIND,
|
||||||
|
currentGadget,
|
||||||
|
&ng,
|
||||||
|
GT_Underscore, '_',
|
||||||
|
GTSL_Min, 0,
|
||||||
|
GTSL_Max, 23,
|
||||||
|
GTSL_Level, uiHours,
|
||||||
|
GTSL_MaxLevelLen, 2,
|
||||||
|
GTSL_LevelFormat, "%2ld",
|
||||||
|
GA_Disabled, timerIsRunning,
|
||||||
|
TAG_END
|
||||||
|
);
|
||||||
|
|
||||||
|
ng.ng_TopEdge += 12;
|
||||||
|
ng.ng_GadgetText = "Mins: ";
|
||||||
|
ng.ng_GadgetID = MINUTES_SLIDER_ID;
|
||||||
|
|
||||||
|
currentGadget = CreateGadget(
|
||||||
|
SLIDER_KIND,
|
||||||
|
currentGadget,
|
||||||
|
&ng,
|
||||||
|
GT_Underscore, '_',
|
||||||
|
GTSL_Min, 0,
|
||||||
|
GTSL_Max, 59,
|
||||||
|
GTSL_Level, uiMinutes,
|
||||||
|
GTSL_MaxLevelLen, 2,
|
||||||
|
GTSL_LevelFormat, "%2ld",
|
||||||
|
GA_Disabled, timerIsRunning,
|
||||||
|
TAG_END
|
||||||
|
);
|
||||||
|
|
||||||
|
ng.ng_TopEdge += 12;
|
||||||
|
ng.ng_GadgetText = "Secs: ";
|
||||||
|
ng.ng_GadgetID = SECONDS_SLIDER_ID;
|
||||||
|
|
||||||
|
currentGadget = CreateGadget(
|
||||||
|
SLIDER_KIND,
|
||||||
|
currentGadget,
|
||||||
|
&ng,
|
||||||
|
GT_Underscore, '_',
|
||||||
|
GTSL_Min, 0,
|
||||||
|
GTSL_Max, 59,
|
||||||
|
GTSL_Level, uiSeconds,
|
||||||
|
GTSL_MaxLevelLen, 2,
|
||||||
|
GTSL_LevelFormat, "%2ld",
|
||||||
|
GA_Disabled, timerIsRunning,
|
||||||
|
TAG_END
|
||||||
|
);
|
||||||
|
|
||||||
|
return glist;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setTimerText() {
|
||||||
|
// TODO: don't rerender if the time hasn't changed
|
||||||
|
sprintf(timerText, "%02d:%02d:%02d", activeHours, activeMinutes, activeSeconds);
|
||||||
|
GT_SetGadgetAttrs(
|
||||||
|
timerGadget,
|
||||||
|
window,
|
||||||
|
NULL,
|
||||||
|
GTTX_Text, &timerText,
|
||||||
|
TAG_DONE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
struct Gadget *gad;
|
||||||
|
|
||||||
|
BOOL terminated = FALSE;
|
||||||
|
BOOL rerenderTimer = FALSE;
|
||||||
|
|
||||||
|
struct IntuiMessage *iMessage;
|
||||||
|
struct Gadget *targetGadget;
|
||||||
|
struct timeval currentSystemTime;
|
||||||
|
|
||||||
|
unsigned int timerRerenderCountdown = 0;
|
||||||
|
|
||||||
|
// timeval tv_secs is ULONG and that will let us have accurate
|
||||||
|
// time counting via timer.device.
|
||||||
|
ULONG timerStartTime, timerDistance, timerBuild;
|
||||||
|
|
||||||
|
timerIsRunning = FALSE;
|
||||||
|
|
||||||
|
if (0 == setup()) {
|
||||||
|
teardown();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetSysTime(¤tSystemTime);
|
||||||
|
timerStartTime = currentSystemTime.tv_secs;
|
||||||
|
|
||||||
|
window = OpenWindow(&winlayout);
|
||||||
|
|
||||||
|
gad = buildUI();
|
||||||
|
|
||||||
|
// use -1 for working with all gadgets
|
||||||
|
AddGList(window, gad, -1, -1, NULL);
|
||||||
|
RefreshGList(gad, window, NULL, -1);
|
||||||
|
GT_RefreshWindow(window, NULL);
|
||||||
|
|
||||||
|
setTimerText();
|
||||||
|
|
||||||
|
// what the fuck, you have to set the labels afterwards?
|
||||||
|
// you know what, it's better if it's explicit rather than the
|
||||||
|
// pointer shit it was trying to do before.
|
||||||
|
//GT_SetGadgetAttrs(one, window, NULL, GTTX_Text, "wow", TAG_DONE);
|
||||||
|
|
||||||
|
// after doing anything with gadgets, you need to refresh them
|
||||||
|
//RefreshGList(gad, window, NULL, 3);
|
||||||
|
|
||||||
|
// you son of a bitch, this is what you need
|
||||||
|
printf("sig signal %d\n", window->UserPort->mp_SigBit);
|
||||||
|
while (!terminated) {
|
||||||
|
// what is a userport on a window
|
||||||
|
// http://amigadev.elowar.com/read/ADCD_2.1/Libraries_Manual_guide/node02EB.html
|
||||||
|
// http://www.amigadev.elowar.com/read/ADCD_2.1/Includes_and_Autodocs_2._guide/node038A.html
|
||||||
|
//WaitPort(window->UserPort);
|
||||||
|
// but we need a timer
|
||||||
|
|
||||||
|
// this shoud be responsive enoug
|
||||||
|
Delay(4);
|
||||||
|
|
||||||
|
if (timerIsRunning) {
|
||||||
|
timerRerenderCountdown += 1;
|
||||||
|
if (timerRerenderCountdown > TIMER_COUNTDOWN_COUNT) {
|
||||||
|
timerRerenderCountdown = 0;
|
||||||
|
|
||||||
|
GetSysTime(¤tSystemTime);
|
||||||
|
|
||||||
|
timerDistance = currentSystemTime.tv_secs - timerStartTime;
|
||||||
|
|
||||||
|
timerBuild = (uiHours * 3600 + uiMinutes * 60 + uiSeconds) - timerDistance;
|
||||||
|
|
||||||
|
activeHours = timerBuild / 3600;
|
||||||
|
activeMinutes = timerBuild / 60 % 60;
|
||||||
|
activeSeconds = timerBuild % 60;
|
||||||
|
|
||||||
|
setTimerText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((!terminated) && (iMessage = GT_GetIMsg(window->UserPort))) {
|
||||||
|
switch (iMessage->Class) {
|
||||||
|
case IDCMP_GADGETUP:
|
||||||
|
targetGadget = (struct Gadget *)iMessage->IAddress;
|
||||||
|
|
||||||
|
switch (targetGadget->GadgetID) {
|
||||||
|
case START_STOP_BUTTON_ID:
|
||||||
|
timerIsRunning = !timerIsRunning;
|
||||||
|
|
||||||
|
if (timerIsRunning) {
|
||||||
|
GetSysTime(¤tSystemTime);
|
||||||
|
|
||||||
|
timerStartTime = currentSystemTime.tv_secs;
|
||||||
|
timerRerenderCountdown = 0;
|
||||||
|
rerenderTimer = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
RemoveGList(window, gad, -1);
|
||||||
|
FreeGadgets(gad);
|
||||||
|
|
||||||
|
gad = buildUI();
|
||||||
|
AddGList(window, gad, -1, -1, NULL);
|
||||||
|
RefreshGList(gad, window, NULL, -1);
|
||||||
|
GT_RefreshWindow(window, NULL);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case RESET_BUTTON_ID:
|
||||||
|
rerenderTimer = TRUE;
|
||||||
|
activeHours = uiHours;
|
||||||
|
activeMinutes = uiMinutes;
|
||||||
|
activeSeconds = uiSeconds;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case IDCMP_MOUSEMOVE:
|
||||||
|
targetGadget = (struct Gadget *)iMessage->IAddress;
|
||||||
|
|
||||||
|
switch (targetGadget->GadgetID) {
|
||||||
|
case HOURS_SLIDER_ID:
|
||||||
|
activeHours = uiHours = iMessage->Code;
|
||||||
|
rerenderTimer = TRUE;
|
||||||
|
break;
|
||||||
|
case MINUTES_SLIDER_ID:
|
||||||
|
activeMinutes = uiMinutes = iMessage->Code;
|
||||||
|
rerenderTimer = TRUE;
|
||||||
|
break;
|
||||||
|
case SECONDS_SLIDER_ID:
|
||||||
|
activeSeconds = uiSeconds = iMessage->Code;
|
||||||
|
rerenderTimer = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IDCMP_CLOSEWINDOW:
|
||||||
|
terminated = TRUE;
|
||||||
|
break;
|
||||||
|
case IDCMP_REFRESHWINDOW:
|
||||||
|
GT_BeginRefresh(window);
|
||||||
|
GT_EndRefresh(window, TRUE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rerenderTimer) {
|
||||||
|
setTimerText();
|
||||||
|
rerenderTimer = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RemoveGList(window, gad, -1);
|
||||||
|
FreeGadgets(gad);
|
||||||
|
|
||||||
|
if (window) {
|
||||||
|
CloseWindow(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
teardown();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue