added 30years repository code here

This commit is contained in:
Wei-ju Wu
2015-11-30 15:19:37 -08:00
parent 28848bf25d
commit bbc0d4d5c8
11 changed files with 970 additions and 0 deletions
+41
View File
@@ -0,0 +1,41 @@
## Description
To celebrate the 30th anniversary of the Amiga, I decided to write a couple of
small applications that run on classic Amiga computers. The point ? Does there
need to be one ? The Amiga was a fun machine, programming it was fun and
it still is.
Another goal is to practice Amiga OS development using only free software tools and
libraries (the exception being the OS itself) and gain a deeper understanding
of the system.
## System Requirements
The software was developed on a GNU/Linux system with VBCC and GNU make.
It was mostly deployed and tested on FS-UAE.
I am certain it can be built on different systems, however this will
require modifications.
## Building
The software was developed on VBCC and apart from VBCC and NDK, there are no other
dependencies.
Currently, on a correctly set up development system typing
```
make
```
should just work.
### Status
In progress :)
## Current applications
* intuitoy1 - experiments with Intuition (Kickstart 1.x)
* iffview - a simple IFF viewer
+3
View File
@@ -0,0 +1,3 @@
iffview
ilbm
examples
+15
View File
@@ -0,0 +1,15 @@
#CC=vc +aos68k
CC=vc +kick13
CFLAGS=-c99 -I$(NDK_INC)
all: iffview
clean:
rm -f *.o iffview ilbm
iffview: iffview.o ilbm.o
$(CC) $(CFLAGS) $< -lamiga -lauto -o $@
# Mostly for testing
ilbm: ilbm.c
gcc -o $@ $< -DSTANDALONE -DDEBUG
+23
View File
@@ -0,0 +1,23 @@
## iffview - A simple IFF viewer application
### Description
Writing a simple IFF viewing tool. The learning purpose is to see how to use the
different available display modes and screens on Intuition
### Building
Developed with VBCC, on your system type
```
make
```
### Running
Open the command line interface on your real Amiga or emulator and type
```
iffview <your image>
```
+208
View File
@@ -0,0 +1,208 @@
/* iffview.c - IFF ILBM viewer application for Amiga OS >= 1.3
This file is part of amiga30yrs.
amiga30yrs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
amiga30yrs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with amiga30yrs. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include <exec/libraries.h>
#include <intuition/intuition.h>
#include <clib/alib_protos.h>
#include <clib/exec_protos.h>
#include <clib/graphics_protos.h>
#include <clib/intuition_protos.h>
#ifdef __VBCC__
#include <clib/alib_stdio_protos.h>
#endif
#define WIN_LEFT 10
#define WIN_TOP 10
#define WIN_WIDTH 320
#define WIN_HEIGHT 200
#define WIN_TITLE "IFF Viewer"
#define WIN_MIN_WIDTH 10
#define WIN_MIN_HEIGHT 10
#define WIN_MAX_WIDTH 200
#define WIN_MAX_HEIGHT 200
#define FILE_MENU_NUM 0
#define NUM_FILE_MENU_ITEMS 2
#define OPEN_MENU_ITEM_NUM 0
#define QUIT_MENU_ITEM_NUM 1
struct NewWindow newwin = {
WIN_LEFT, WIN_TOP, WIN_WIDTH, WIN_HEIGHT, 0, 1,
IDCMP_CLOSEWINDOW | IDCMP_MENUPICK,
WINDOWCLOSE | SMART_REFRESH | ACTIVATE | WINDOWSIZING | WINDOWDRAG | WINDOWDEPTH | NOCAREREFRESH,
NULL, NULL, WIN_TITLE,
NULL, NULL,
WIN_MIN_WIDTH, WIN_MIN_HEIGHT,
WIN_MAX_WIDTH, WIN_MAX_HEIGHT,
WBENCHSCREEN
};
struct IntuiText menutext[] = {
{0, 1, JAM2, 0, 1, NULL, "Open...", NULL},
{0, 1, JAM2, 0, 1, NULL, "Quit", NULL}
};
struct MenuItem fileMenuItems[] = {
{&fileMenuItems[1], 0, 0, 0, 0, ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ, 0,
&menutext[0], NULL, 'O', NULL, 0},
{NULL, 0, 0, 0, 0, ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ, 0,
&menutext[1], NULL, 'Q', NULL, 0}
};
struct Menu menus[] = {
{NULL, 20, 0, 0, 0, MENUENABLED | MIDRAWN, "File", &fileMenuItems[0], 0, 0, 0, 0}
};
struct Window *window;
void cleanup()
{
if (window) {
ClearMenuStrip(window);
CloseWindow(window);
}
}
#define OK_BUTTON_WIDTH 40
#define OK_BUTTON_HEIGHT 24
#define REQ_WIDTH 200
#define REQ_HEIGHT 100
#define TOPAZ_BASELINE 8
void open_file()
{
struct Requester requester;
struct IntuiText button_text = {1, 0, JAM2, 0, TOPAZ_BASELINE, NULL, "Ok", NULL};
WORD button_border_points[] = {
0, 0, OK_BUTTON_WIDTH, 0, OK_BUTTON_WIDTH, OK_BUTTON_HEIGHT, 0, OK_BUTTON_HEIGHT, 0, 0
};
struct Border button_border = {0, 0, 1, 0, JAM1, 5, button_border_points, NULL};
WORD req_border_points[] = {
0, 0, REQ_WIDTH, 0, REQ_WIDTH, REQ_HEIGHT, 0, REQ_HEIGHT, 0, 0
};
struct Border req_border = {0, 0, 1, 0, JAM1, 5, req_border_points, NULL};
BOOL result;
struct Gadget button1 = {
NULL, 10, 10, OK_BUTTON_WIDTH, OK_BUTTON_HEIGHT,
GFLG_GADGHCOMP, 0, GTYP_BOOLGADGET | GTYP_REQGADGET,
&button_border, NULL, &button_text,
0, NULL, 0, NULL
};
InitRequester(&requester);
requester.LeftEdge = 20;
requester.TopEdge = 20;
requester.Width = REQ_WIDTH;
requester.Height = REQ_HEIGHT;
requester.Flags = 0;
requester.BackFill = 0;
requester.ReqGadget = &button1;
requester.ReqBorder = &req_border;
result = Request(&requester, window);
if (result) puts("Requester could be opened");
else puts("Requester could not be opened");
}
BOOL handle_menu(UWORD menuNum, UWORD itemNum, UWORD subItemNum)
{
printf("menu, menu num: %d, item num: %d, sub item num: %d\n",
(int) menuNum, (int) itemNum, (int) subItemNum);
if (menuNum == FILE_MENU_NUM && itemNum == QUIT_MENU_ITEM_NUM) {
/* quit */
return TRUE;
}
if (menuNum == FILE_MENU_NUM && itemNum == OPEN_MENU_ITEM_NUM) {
open_file();
}
return FALSE;
}
void handle_events() {
BOOL done = FALSE;
struct IntuiMessage *msg;
ULONG msgClass;
UWORD menuCode;
while (!done) {
Wait(1 << window->UserPort->mp_SigBit);
if (msg = (struct IntuiMessage *) GetMsg(window->UserPort)) {
msgClass = msg->Class;
switch (msgClass) {
case IDCMP_CLOSEWINDOW:
done = TRUE;
break;
case IDCMP_MENUPICK:
menuCode = msg->Code;
done = handle_menu(MENUNUM(menuCode), ITEMNUM(menuCode), SUBNUM(menuCode));
break;
default:
break;
}
ReplyMsg((struct Message *) msg);
}
}
}
void setup_menu()
{
UWORD txWidth, txHeight, txBaseline, txSpacing, itemWidth, itemHeight, numItems;
struct RastPort *rp = &window->WScreen->RastPort;
int i;
txWidth = rp->TxWidth;
txHeight = rp->TxHeight;
txBaseline = rp->TxBaseline;
txSpacing = rp->TxSpacing;
printf("TxWidth: %d, TxHeight: %d, TxBaseline: %d, TxSpacing: %d\n",
(int) txWidth, (int) txHeight, (int) txBaseline, (int) txSpacing);
/* Set file menu bounds */
menus[0].Width = TextLength(rp, "File", strlen("File")) + txWidth;
menus[0].Height = txHeight;
/* Set file menu items bounds */
/* We actually need to know what the command uses up */
itemWidth = txWidth * strlen("Open...") + 50;
itemHeight = txHeight + 2; /* 2 pixels adjustment */
numItems = sizeof(fileMenuItems) / sizeof(struct MenuItem);
printf("# file items: %d\n", (int) numItems);
for (i = 0; i < numItems; i++) {
fileMenuItems[i].TopEdge = i * itemHeight;
fileMenuItems[i].Height = itemHeight;
fileMenuItems[i].Width = itemWidth;
}
SetMenuStrip(window, &menus[0]);
}
int main(int argc, char **argv)
{
if (window = OpenWindow(&newwin)) {
setup_menu();
handle_events();
}
cleanup();
return 1;
}
+220
View File
@@ -0,0 +1,220 @@
/* ilbm.c - Universal IFF ILBM handling module
This file is part of amiga30yrs.
amiga30yrs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
amiga30yrs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with amiga30yrs. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ilbm.h"
#ifdef LITTLE_ENDIAN
#include <byteswap.h>
#endif
#define IFF_HEADER_SIZE 12
#define CHUNK_HEADER_SIZE 8
BitMapHeader *read_BMHD(FILE *fp, int datasize)
{
BitMapHeader *header;
int bytes_read;
header = malloc(sizeof(BitMapHeader));
bytes_read = fread(header, sizeof(char), datasize, fp);
#ifdef LITTLE_ENDIAN
header->x = __bswap_16(header->x);
header->y = __bswap_16(header->y);
header->w = __bswap_16(header->w);
header->h = __bswap_16(header->h);
header->transparentColor = __bswap_16(header->transparentColor);
header->pageWidth = __bswap_16(header->pageWidth);
header->pageHeight = __bswap_16(header->pageHeight);
#endif
/*
printf("x: %d y: %d w: %d h: %d\n",
header.x, header.y, header.w, header.h);
printf("# planes: %d\n", header.nPlanes);
printf("# transp col: %d\n", header.transparentColor);
printf("pagewidth: %d pageheight: %d\n", header.pageWidth, header.pageHeight);
*/
if (header->compression == cmpNone) puts("no compression");
else if (header->compression == cmpByteRun1) puts("Byte Run 1 compression");
else puts("unknown compression");
return header;
}
ColorRegister *read_CMAP(FILE *fp, int datasize)
{
int num_colors = datasize / 3, bytes_read;
ColorRegister *colors;
colors = malloc(datasize);
bytes_read = fread(colors, sizeof(ColorRegister), num_colors, fp);
return colors;
}
ULONG read_CAMG(FILE *fp, int datasize)
{
ULONG flags, bytes_read;
bytes_read = fread(&flags, sizeof(ULONG), 1, fp);
#ifdef LITTLE_ENDIAN
flags = __bswap_32(flags);
#endif
if (flags & HAM) puts("HAM mode !");
else if (flags & EXTRA_HALFBRITE) puts("Extra Halfbrite mode !");
return flags;
}
void read_CRNG(FILE *fp, int datasize)
{
ULONG bytes_read;
CRange color_reg_range;
bytes_read = fread(&color_reg_range, sizeof(CRange), 1, fp);
#ifdef LITTLE_ENDIAN
color_reg_range.rate = __bswap_16(color_reg_range.rate);
color_reg_range.flags = __bswap_16(color_reg_range.flags);
#endif
#ifdef DEBUG
printf("CRange, rate: %d, flags: %04x, low: %d, high: %d\n",
(int) color_reg_range.rate, (int) color_reg_range.flags,
(int) color_reg_range.low, (int) color_reg_range.high);
#endif
}
UBYTE *read_BODY(FILE *fp, int datasize, BitMapHeader *bmheader)
{
ULONG bytes_read;
BYTE *buffer = malloc(datasize), *dst_buffer;
int src_i = 0, dst_i = 0, dst_size;
dst_size = bmheader->w * bmheader->h * bmheader->nPlanes / 8;
printf("target size: %d, data size: %d\n", dst_size, datasize);
bytes_read = fread(buffer, sizeof(char), datasize, fp);
if (bmheader->compression == cmpByteRun1) {
BYTE b0, b1;
int i;
/* decompress data */
dst_buffer = malloc(dst_size);
while (src_i < datasize) {
b0 = buffer[src_i++];
if (b0 >= 0) {
for (i = 0; i < b0 + 1; i++) dst_buffer[dst_i++] = buffer[src_i++];
} else {
b1 = buffer[src_i++];
for (i = 0; i < -b0 + 1; i++) dst_buffer[dst_i++] = b1;
}
}
free(buffer);
return dst_buffer;
}
return buffer;
}
#define skip_chunk(fp, datasize) fseek(fp, datasize, SEEK_CUR)
void read_chunks(FILE *fp, int filesize, int total_read)
{
char id[5], buffer[CHUNK_HEADER_SIZE];
int i, bytes_read, datasize;
BitMapHeader *bmheader = NULL;
ColorRegister *colors = NULL;
UBYTE *imgdata = NULL;
while (total_read < filesize) {
bytes_read = fread(buffer, sizeof(char), 8, fp);
for (i = 0; i < 4; i++) id[i] = buffer[i];
id[4] = 0;
#ifdef LITTLE_ENDIAN
datasize = __bswap_32(*((ULONG *) &buffer[4]));
#else
datasize = *((ULONG *) &buffer[4]);
#endif
if (!strncmp("BMHD", buffer, 4)) bmheader = read_BMHD(fp, datasize);
else if (!strncmp("CMAP", buffer, 4)) colors = read_CMAP(fp, datasize);
else if (!strncmp("CRNG", buffer, 4)) read_CRNG(fp, datasize);
else if (!strncmp("CAMG", buffer, 4)) read_CAMG(fp, datasize);
else if (!strncmp("BODY", buffer, 4)) imgdata = read_BODY(fp, datasize, bmheader);
else {
#ifdef DEBUG
printf("WARNING - Unsupported chunk '%s', size: %d\n", id, datasize);
#endif
skip_chunk(fp, datasize);
}
/* Padding to even if necessary */
if (datasize % 2) {
fseek(fp, 1, SEEK_CUR);
datasize++;
}
total_read += datasize + CHUNK_HEADER_SIZE;
}
if (imgdata) free(imgdata);
if (colors) free(colors);
if (bmheader) free(bmheader);
}
void parse_file(const char *path)
{
FILE *fp;
char buffer[IFF_HEADER_SIZE];
size_t bytes_read;
ULONG filesize, total_read = 0;
fp = fopen(path, "rb");
/* need to check whether we actually can read this much*/
bytes_read = fread(buffer, sizeof(char), IFF_HEADER_SIZE, fp);
total_read += bytes_read;
if (!strncmp("FORM", buffer, 4)) {
#ifdef LITTLE_ENDIAN
filesize = __bswap_32(*((ULONG *) &buffer[4])) + CHUNK_HEADER_SIZE;
#else
filesize = *((ULONG *) &buffer[4]) + CHUNK_HEADER_SIZE;
#endif
if (!strncmp("ILBM", &buffer[8], 4)) {
#ifdef DEBUG
printf("IFF/ILBM file, file size: %d\n", (int) filesize);
#endif
read_chunks(fp, filesize, total_read);
} else {
puts("not an IFF ILBM file");
}
} else {
puts("not an IFF file");
}
}
#ifdef STANDALONE
int main(int argc, char **argv)
{
if (argc <= 1) {
puts("usage: ilbm <image-file>");
} else {
parse_file(argv[1]);
}
}
#endif
+80
View File
@@ -0,0 +1,80 @@
/* ilbm.h - Definitions for IFF ILBM handling module
This file is part of amiga30yrs.
amiga30yrs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
amiga30yrs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with amiga30yrs. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __ILBM_H__
#define __ILBM_H__
#ifdef __VBCC__
#include <exec/types.h>
#include <graphics/view.h>
#else
#include <sys/types.h>
#define ULONG u_int32_t
#define UWORD u_int16_t
#define UBYTE u_int8_t
#define LONG int32_t
#define WORD int16_t
#define BYTE int8_t
#define HAM 0x800
#define EXTRA_HALFBRITE 0x80
#endif
/*
* From the specification
*/
typedef UBYTE Masking; /* Choice of masking technique. */
#define mskNone 0
#define mskHasMask 1
#define mskHasTransparentColor 2
#define mskLasso 3
typedef UBYTE Compression;
#define cmpNone 0
#define cmpByteRun1 1
typedef struct {
UWORD w, h;
WORD x, y;
UBYTE nPlanes;
Masking masking;
Compression compression;
UBYTE pad1;
UWORD transparentColor;
UBYTE xAspect, yAspect;
WORD pageWidth, pageHeight;
} BitMapHeader;
typedef struct {
UBYTE red, green, blue;
} ColorRegister;
typedef struct {
WORD pad1;
WORD rate;
WORD flags;
UBYTE low, high;
} CRange;
#endif /* __ILBM_H__ */
+1
View File
@@ -0,0 +1 @@
intuitoy1
+10
View File
@@ -0,0 +1,10 @@
CC=vc +kick13
CFLAGS=-c99 -I$(NDK_INC)
all: intuitoy1
clean:
rm -f *.o intuitoy1
intuitoy1: intuitoy1.c
$(CC) $(CFLAGS) $^ -lamiga -lauto -o $@
+23
View File
@@ -0,0 +1,23 @@
## intuitoy1 - Experiments with Intuition on Amiga OS 1.x
### Description
Trying out to create the available elements that Intuition provides to use them effectively
in an application. Besides being a learning tool for Amiga 1.x UI programming, it is completely
and utterly useless.
### Building
```
make
```
### Running
On an Amiga system (emulator or real), open the command line interface and
enter
```
intuitoy1
```
+346
View File
@@ -0,0 +1,346 @@
/* intuitoy1.c - Intuition experiments for Amiga OS 1.x
This file is part of amiga30yrs.
amiga30yrs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
amiga30yrs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with amiga30yrs. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include <exec/libraries.h>
#include <intuition/intuition.h>
#include <clib/alib_protos.h>
#include <clib/exec_protos.h>
#include <clib/graphics_protos.h>
#include <clib/intuition_protos.h>
#ifdef __VBCC__
#include <clib/alib_stdio_protos.h>
#endif
#define WIN_LEFT 10
#define WIN_TOP 10
#define WIN_WIDTH 320
#define WIN_HEIGHT 200
#define WIN_TITLE "IntuiToy 1"
#define WIN_MIN_WIDTH 10
#define WIN_MIN_HEIGHT 10
#define WIN_MAX_WIDTH 200
#define WIN_MAX_HEIGHT 200
#define BUTTON_HEIGHT 20
#define BUTTON_TEXT_XOFFSET 4
#define TOPAZ_BASELINE 6
#define FILE_MENU_NUM 0
#define NUM_FILE_MENU_ITEMS 2
#define OPEN_MENU_ITEM_NUM 0
#define QUIT_MENU_ITEM_NUM 1
struct NewWindow newwin = {
WIN_LEFT, WIN_TOP, WIN_WIDTH, WIN_HEIGHT, 0, 1,
IDCMP_CLOSEWINDOW | IDCMP_MENUPICK | IDCMP_GADGETUP,
WINDOWCLOSE | SMART_REFRESH | ACTIVATE | WINDOWSIZING | WINDOWDRAG | WINDOWDEPTH | NOCAREREFRESH,
NULL, NULL, WIN_TITLE,
NULL, NULL,
WIN_MIN_WIDTH, WIN_MIN_HEIGHT,
WIN_MAX_WIDTH, WIN_MAX_HEIGHT,
WBENCHSCREEN
};
struct IntuiText menutext[] = {
{0, 1, JAM2, 0, 1, NULL, "Open...", NULL},
{0, 1, JAM2, 0, 1, NULL, "Quit", NULL}
};
struct MenuItem fileMenuItems[] = {
{&fileMenuItems[1], 0, 0, 0, 0, ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ, 0,
&menutext[0], NULL, 'O', NULL, 0},
{NULL, 0, 0, 0, 0, ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ, 0,
&menutext[1], NULL, 'Q', NULL, 0}
};
struct Menu menus[] = {
{NULL, 20, 0, 0, 0, MENUENABLED | MIDRAWN, "File", &fileMenuItems[0], 0, 0, 0, 0}
};
struct Window *window;
void cleanup()
{
if (window) {
ClearMenuStrip(window);
CloseWindow(window);
}
}
#define REQ_WIDTH 180
#define REQ_HEIGHT 70
#define REQ_TEXT_XOFFSET 10
#define OK_BUTTON_X 10
#define OK_BUTTON_Y 40
#define OK_BUTTON_WIDTH 24
#define CANCEL_BUTTON_X 120
#define CANCEL_BUTTON_Y 40
#define CANCEL_BUTTON_WIDTH 54
#define PATH_GADGET_WIDTH 160
/*
* This opens a very rudimentary file dialog, that demonstrates a true requester, which
* is dependent on the parent window.
*/
void open_file()
{
/* Note that all data here is static.
The reason is that Intuition expects the data to still exist for the lifetime of the
requester. If it's gone, the Guru will greet you.
*/
static struct Requester requester;
static WORD req_border_points[] = {
0, 0, REQ_WIDTH - 1, 0, REQ_WIDTH - 1, REQ_HEIGHT - 1, 0, REQ_HEIGHT - 1, 0, 0
};
static struct Border req_border = {0, 0, 1, 0, JAM1, 5, req_border_points, NULL};
static struct IntuiText labels[] = {
{1, 0, JAM2, REQ_TEXT_XOFFSET, TOPAZ_BASELINE, NULL, "Enter file path", NULL},
{1, 0, JAM2, BUTTON_TEXT_XOFFSET, TOPAZ_BASELINE, NULL, "Ok", NULL},
{1, 0, JAM2, BUTTON_TEXT_XOFFSET, TOPAZ_BASELINE, NULL, "Cancel", NULL}
};
static WORD gadget_border_points[3][10] = {
{0, 0, OK_BUTTON_WIDTH, 0, OK_BUTTON_WIDTH, BUTTON_HEIGHT, 0, BUTTON_HEIGHT, 0, 0},
{0, 0, CANCEL_BUTTON_WIDTH, 0, CANCEL_BUTTON_WIDTH, BUTTON_HEIGHT, 0, BUTTON_HEIGHT, 0, 0},
{-2, -2, PATH_GADGET_WIDTH, -2, PATH_GADGET_WIDTH, 10, -2, 10, -2, -2}
};
static struct Border gadget_borders[] = {
{0, 0, 1, 0, JAM1, 5, gadget_border_points[0], NULL},
{0, 0, 1, 0, JAM1, 5, gadget_border_points[1], NULL},
{0, 0, 1, 0, JAM1, 5, gadget_border_points[2], NULL}
};
static UBYTE buffer[81], undobuffer[81];
static struct StringInfo strinfo = {buffer, undobuffer, 0, 80, 0, 0, 0, 0, 0, 0, NULL, 0, NULL};
static struct Gadget gadgets[] = {
{&gadgets[1], OK_BUTTON_X, OK_BUTTON_Y, OK_BUTTON_WIDTH, BUTTON_HEIGHT, GFLG_GADGHCOMP,
GACT_RELVERIFY | GACT_ENDGADGET, GTYP_BOOLGADGET | GTYP_REQGADGET,
&gadget_borders[0], NULL, &labels[1], 0, NULL, 101, NULL},
{&gadgets[2], CANCEL_BUTTON_X, CANCEL_BUTTON_Y, CANCEL_BUTTON_WIDTH, BUTTON_HEIGHT, GFLG_GADGHCOMP,
GACT_RELVERIFY | GACT_ENDGADGET, GTYP_BOOLGADGET | GTYP_REQGADGET,
&gadget_borders[1], NULL, &labels[2], 0, NULL, 102, NULL},
{NULL, OK_BUTTON_X, 20, PATH_GADGET_WIDTH, 10,
GFLG_GADGHCOMP, GACT_RELVERIFY, GTYP_STRGADGET, &gadget_borders[2], NULL, &labels[3],
0, &strinfo, 103, NULL},
};
BOOL result;
InitRequester(&requester);
requester.LeftEdge = 50;
requester.TopEdge = 50;
requester.Width = REQ_WIDTH;
requester.Height = REQ_HEIGHT;
requester.Flags = 0;
requester.BackFill = 0;
requester.ReqGadget = &gadgets[0];
requester.ReqBorder = &req_border;
requester.ReqText = &labels[0];
result = Request(&requester, window);
if (result) puts("Requester could be opened");
else puts("Requester could not be opened");
}
BOOL handle_menu(UWORD menuNum, UWORD itemNum, UWORD subItemNum)
{
printf("menu, menu num: %d, item num: %d, sub item num: %d\n",
(int) menuNum, (int) itemNum, (int) subItemNum);
if (menuNum == FILE_MENU_NUM && itemNum == QUIT_MENU_ITEM_NUM) {
/* quit */
return TRUE;
}
if (menuNum == FILE_MENU_NUM && itemNum == OPEN_MENU_ITEM_NUM) {
open_file();
}
return FALSE;
}
/*
* The main event loop.
*/
void handle_events() {
BOOL done = FALSE;
struct IntuiMessage *msg;
ULONG msgClass;
UWORD menuCode;
while (!done) {
Wait(1 << window->UserPort->mp_SigBit);
if (msg = (struct IntuiMessage *) GetMsg(window->UserPort)) {
msgClass = msg->Class;
switch (msgClass) {
case IDCMP_CLOSEWINDOW:
done = TRUE;
break;
case IDCMP_MENUPICK:
menuCode = msg->Code;
done = handle_menu(MENUNUM(menuCode), ITEMNUM(menuCode), SUBNUM(menuCode));
break;
case IDCMP_GADGETUP:
printf("Click me clicked, id: %d\n", (int) ((struct Gadget *) (msg->IAddress))->GadgetID);
break;
default:
break;
}
ReplyMsg((struct Message *) msg);
}
}
}
/*
* Laying out the pulldown menu strip.
* The menu is also the invocation point to test out requester types.
*/
void setup_menu()
{
UWORD txWidth, txHeight, txBaseline, txSpacing, itemWidth, itemHeight, numItems;
struct RastPort *rp = &window->WScreen->RastPort;
int i;
txWidth = rp->TxWidth;
txHeight = rp->TxHeight;
txBaseline = rp->TxBaseline;
txSpacing = rp->TxSpacing;
printf("TxWidth: %d, TxHeight: %d, TxBaseline: %d, TxSpacing: %d\n",
(int) txWidth, (int) txHeight, (int) txBaseline, (int) txSpacing);
/* Set file menu bounds */
menus[0].Width = TextLength(rp, "File", strlen("File")) + txWidth;
menus[0].Height = txHeight;
/* Set file menu items bounds */
/* We actually need to know what the command uses up */
itemWidth = txWidth * strlen("Open...") + 50;
itemHeight = txHeight + 2; /* 2 pixels adjustment */
numItems = sizeof(fileMenuItems) / sizeof(struct MenuItem);
printf("# file items: %d\n", (int) numItems);
for (i = 0; i < numItems; i++) {
fileMenuItems[i].TopEdge = i * itemHeight;
fileMenuItems[i].Height = itemHeight;
fileMenuItems[i].Width = itemWidth;
}
SetMenuStrip(window, &menus[0]);
}
/*
* Create some application gadgets inside the window here. Playing around with
* settings, events and layout.
*/
#define CLICKME_BUTTON_WIDTH 90
#define CLICKME_BUTTON_X 10
#define CLICKME_BUTTON_Y 20
#define CLICKME2_BUTTON_WIDTH 120
#define CLICKME2_BUTTON_X 110
#define CLICKME2_BUTTON_Y 20
#define SLIDER_WIDTH 200
#define SLIDER_HEIGHT 10
#define SLIDER_LABEL_YOFFSET -10
#define SLIDER_X 10
#define SLIDER_Y 65
#define STRING_X 12
#define STRING_Y 94
#define STRING_WIDTH 80
#define STRING_HEIGHT 10
#define STRING_LABEL_YOFFSET -14
#define STRING_BORDER_X -2
#define STRING_BORDER_Y -2
#define INTEGER_X 12
#define INTEGER_Y 124
#define INTEGER_WIDTH 80
#define INTEGER_HEIGHT 10
struct Gadget *setup_gadgets()
{
static struct IntuiText gadget_labels[] = {
{1, 0, JAM2, BUTTON_TEXT_XOFFSET, TOPAZ_BASELINE, NULL, "Click me !", NULL},
{1, 0, JAM2, BUTTON_TEXT_XOFFSET, TOPAZ_BASELINE, NULL, "Click me too !", NULL},
{1, 0, JAM2, BUTTON_TEXT_XOFFSET, SLIDER_LABEL_YOFFSET, NULL, "A slider", NULL},
{1, 0, JAM2, BUTTON_TEXT_XOFFSET, STRING_LABEL_YOFFSET, NULL, "A string gadget", NULL},
{1, 0, JAM2, BUTTON_TEXT_XOFFSET, STRING_LABEL_YOFFSET, NULL, "An integer gadget", NULL}
};
static WORD gadget_border_points[3][10] = {
{0, 0, CLICKME_BUTTON_WIDTH, 0, CLICKME_BUTTON_WIDTH, BUTTON_HEIGHT,
0, BUTTON_HEIGHT, 0, 0},
{0, 0, CLICKME2_BUTTON_WIDTH, 0, CLICKME2_BUTTON_WIDTH, BUTTON_HEIGHT,
0, BUTTON_HEIGHT, 0, 0},
{STRING_BORDER_X, STRING_BORDER_Y, STRING_WIDTH, STRING_BORDER_Y,
STRING_WIDTH, STRING_HEIGHT, STRING_BORDER_X, STRING_HEIGHT,
STRING_BORDER_X, STRING_BORDER_Y}
};
static struct Border gadget_border[] = {
{0, 0, 1, 0, JAM1, 5, gadget_border_points[0], NULL},
{0, 0, 1, 0, JAM1, 5, gadget_border_points[1], NULL},
{0, 0, 1, 0, JAM1, 5, gadget_border_points[2], NULL}
};
static struct PropInfo propinfos[] = {
{AUTOKNOB | FREEHORIZ, 0, 0, 10, MAXBODY, 0, 0, 0, 0, 0, 0}
};
static struct Image slider_image;
static UBYTE buffer[11], undobuffer[11], buffer2[11], undobuffer2[11];
static struct StringInfo strinfos[] = {
{buffer, undobuffer, 0, 10, 0, 0, 0, 0, 0, 0, NULL, 0, NULL},
{buffer2, undobuffer2, 0, 10, 0, 0, 0, 0, 0, 0, NULL, 0, NULL}
};
static struct Gadget gadgets[] = {
{&gadgets[1], CLICKME_BUTTON_X, CLICKME_BUTTON_Y, CLICKME_BUTTON_WIDTH, BUTTON_HEIGHT,
GFLG_GADGHBOX, GACT_RELVERIFY, GTYP_BOOLGADGET, &gadget_border[0], NULL, &gadget_labels[0],
0, NULL, 1, NULL},
{&gadgets[2], CLICKME2_BUTTON_X, CLICKME2_BUTTON_Y, CLICKME2_BUTTON_WIDTH, BUTTON_HEIGHT,
GFLG_GADGHCOMP, GACT_RELVERIFY, GTYP_BOOLGADGET, &gadget_border[1], NULL, &gadget_labels[1],
0, NULL, 2, NULL},
{&gadgets[3], SLIDER_X, SLIDER_Y, SLIDER_WIDTH, SLIDER_HEIGHT,
GFLG_GADGHCOMP, GACT_RELVERIFY, GTYP_PROPGADGET, &slider_image, NULL, &gadget_labels[2],
0, &propinfos[0], 3, NULL},
{&gadgets[4], STRING_X, STRING_Y, STRING_WIDTH, STRING_HEIGHT,
GFLG_GADGHCOMP, GACT_RELVERIFY, GTYP_STRGADGET, &gadget_border[2], NULL, &gadget_labels[3],
0, &strinfos[0], 3, NULL},
{NULL, INTEGER_X, INTEGER_Y, INTEGER_WIDTH, INTEGER_HEIGHT,
GFLG_GADGHCOMP, GACT_LONGINT, GTYP_STRGADGET, &gadget_border[2], NULL, &gadget_labels[4],
0, &strinfos[1], 3, NULL},
};
buffer[0] = 0;
undobuffer[0] = 0;
buffer2[0] = 0;
undobuffer2[0] = 0;
strcpy(buffer2, "0");
return &gadgets[0];
}
int main(int argc, char **argv)
{
newwin.FirstGadget = setup_gadgets();
if (window = OpenWindow(&newwin)) {
setup_menu();
handle_events();
}
cleanup();
return 1;
}