mirror of
https://github.com/weiju/amiga-stuff
synced 2025-11-21 09:19:45 +00:00
scrolling works somewhat
the indexes are not entirely correct
This commit is contained in:
@ -14,4 +14,4 @@ iffview: iffview.o ilbm.o
|
|||||||
# interestingly, when defining std=c99, LITTLE_ENDIAN disappears as a definition
|
# interestingly, when defining std=c99, LITTLE_ENDIAN disappears as a definition
|
||||||
# in gcc, so we define it explicitly
|
# in gcc, so we define it explicitly
|
||||||
ilbm: ilbm.c
|
ilbm: ilbm.c
|
||||||
gcc -o $@ $< -DSTANDALONE -DDEBUG -std=c99 -DLITTLE_ENDIAN
|
gcc -o $@ $< -DSTANDALONE -DDEBUG -std=c99 -pedantic -DLITTLE_ENDIAN
|
||||||
|
|||||||
@ -102,7 +102,7 @@ void read_CRNG(FILE *fp, int datasize)
|
|||||||
UBYTE *read_BODY(FILE *fp, int datasize, BitMapHeader *bmheader, int *data_bytes)
|
UBYTE *read_BODY(FILE *fp, int datasize, BitMapHeader *bmheader, int *data_bytes)
|
||||||
{
|
{
|
||||||
ULONG bytes_read;
|
ULONG bytes_read;
|
||||||
BYTE *buffer, *dst_buffer;
|
UBYTE *buffer, *dst_buffer;
|
||||||
int src_i = 0, dst_i = 0, dst_size;
|
int src_i = 0, dst_i = 0, dst_size;
|
||||||
|
|
||||||
buffer = malloc(datasize);
|
buffer = malloc(datasize);
|
||||||
@ -153,11 +153,11 @@ ILBMData *read_chunks(FILE *fp, int filesize, int total_read)
|
|||||||
#else
|
#else
|
||||||
datasize = *((ULONG *) &buffer[4]);
|
datasize = *((ULONG *) &buffer[4]);
|
||||||
#endif
|
#endif
|
||||||
if (!strncmp("BMHD", buffer, 4)) bmheader = read_BMHD(fp, datasize);
|
if (!strncmp("BMHD", (const char *) buffer, 4)) bmheader = read_BMHD(fp, datasize);
|
||||||
else if (!strncmp("CMAP", buffer, 4)) colors = read_CMAP(fp, datasize, &result->num_colors);
|
else if (!strncmp("CMAP", (const char *) buffer, 4)) colors = read_CMAP(fp, datasize, &result->num_colors);
|
||||||
else if (!strncmp("CRNG", buffer, 4)) read_CRNG(fp, datasize);
|
else if (!strncmp("CRNG", (const char *) buffer, 4)) read_CRNG(fp, datasize);
|
||||||
else if (!strncmp("CAMG", buffer, 4)) bmheader->camgFlags = read_CAMG(fp, datasize);
|
else if (!strncmp("CAMG", (const char *) buffer, 4)) bmheader->camgFlags = read_CAMG(fp, datasize);
|
||||||
else if (!strncmp("BODY", buffer, 4)) imgdata = read_BODY(fp, datasize, bmheader, &imgdata_size);
|
else if (!strncmp("BODY", (const char *) buffer, 4)) imgdata = read_BODY(fp, datasize, bmheader, &imgdata_size);
|
||||||
else {
|
else {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("WARNING - Unsupported chunk '%s', size: %d\n", id, datasize);
|
printf("WARNING - Unsupported chunk '%s', size: %d\n", id, datasize);
|
||||||
@ -263,7 +263,7 @@ void ilbm_to_image_data(char *dest, ILBMData *data, int dest_width, int dest_hei
|
|||||||
}
|
}
|
||||||
int src_bytes_per_row = data->bmheader->w / 8;
|
int src_bytes_per_row = data->bmheader->w / 8;
|
||||||
int dest_bytes_per_row = dest_width / 8;
|
int dest_bytes_per_row = dest_width / 8;
|
||||||
char *src_ptr = data->imgdata;
|
UBYTE *src_ptr = data->imgdata;
|
||||||
int src_offset, img_height = data->bmheader->h, num_planes = data->bmheader->nPlanes;
|
int src_offset, img_height = data->bmheader->h, num_planes = data->bmheader->nPlanes;
|
||||||
int row_data_size = num_planes * src_bytes_per_row;
|
int row_data_size = num_planes * src_bytes_per_row;
|
||||||
|
|
||||||
|
|||||||
@ -26,10 +26,10 @@
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <stdint.h>
|
||||||
#define ULONG u_int32_t
|
#define ULONG uint32_t
|
||||||
#define UWORD u_int16_t
|
#define UWORD uint16_t
|
||||||
#define UBYTE u_int8_t
|
#define UBYTE uint8_t
|
||||||
|
|
||||||
#define LONG int32_t
|
#define LONG int32_t
|
||||||
#define WORD int16_t
|
#define WORD int16_t
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#CC=vc +aos68k
|
#CC=vc +aos68k
|
||||||
CC=vc +kick13
|
CC=vc +kick13
|
||||||
CFLAGS=-c99 -I$(NDK_INC) -DDEBUG
|
CFLAGS=-c99 -I$(NDK_INC) -DDEBUG -O2
|
||||||
|
|
||||||
all: main
|
all: main
|
||||||
|
|
||||||
|
|||||||
@ -41,6 +41,7 @@ struct FileListEntry *scan_dir(const char *dirpath, int *num_entries)
|
|||||||
if (current->dvi_Type != DLT_DEVICE) {
|
if (current->dvi_Type != DLT_DEVICE) {
|
||||||
tmp = calloc(1, sizeof(struct FileListEntry));
|
tmp = calloc(1, sizeof(struct FileListEntry));
|
||||||
tmp->file_type = FILETYPE_VOLUME;
|
tmp->file_type = FILETYPE_VOLUME;
|
||||||
|
tmp->index = n;
|
||||||
strncpy(tmp->name, ((char *) BADDR(current->dvi_Name)) + 1, MAX_FILENAME_LEN);
|
strncpy(tmp->name, ((char *) BADDR(current->dvi_Name)) + 1, MAX_FILENAME_LEN);
|
||||||
fname_len = strlen(tmp->name);
|
fname_len = strlen(tmp->name);
|
||||||
// add the colon character to point out that we have a logical volume
|
// add the colon character to point out that we have a logical volume
|
||||||
|
|||||||
@ -20,6 +20,7 @@
|
|||||||
struct FileListEntry {
|
struct FileListEntry {
|
||||||
struct FileListEntry *next, *prev;
|
struct FileListEntry *next, *prev;
|
||||||
UWORD file_type;
|
UWORD file_type;
|
||||||
|
UWORD index; // index in the list
|
||||||
char name[MAX_FILENAME_LEN + 1];
|
char name[MAX_FILENAME_LEN + 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
#define NUM_FILE_ENTRIES 10
|
#define NUM_FILE_ENTRIES 10
|
||||||
|
|
||||||
// some of these variables don't need to be static
|
|
||||||
static int filelist_width;
|
static int filelist_width;
|
||||||
static int filelist_height;
|
static int filelist_height;
|
||||||
static int filelist_bm_width;
|
static int filelist_bm_width;
|
||||||
@ -133,14 +132,14 @@ static struct PropInfo propinfo = {AUTOKNOB | FREEVERT, 0, 0, MAXBODY, MAXBODY,
|
|||||||
#define WIN_TITLE "Open File..."
|
#define WIN_TITLE "Open File..."
|
||||||
|
|
||||||
static struct NewWindow newwin = {
|
static struct NewWindow newwin = {
|
||||||
0, 0, 0, REQWIN_HEIGHT, 0, 1,
|
0, 0, 0, REQWIN_HEIGHT, 0, 1,
|
||||||
IDCMP_GADGETUP | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE,
|
IDCMP_GADGETUP | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE,
|
||||||
WFLG_CLOSEGADGET | WFLG_SMART_REFRESH | WFLG_ACTIVATE | WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_NOCAREREFRESH,
|
WFLG_CLOSEGADGET | WFLG_SMART_REFRESH | WFLG_ACTIVATE | WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_NOCAREREFRESH,
|
||||||
NULL, NULL, WIN_TITLE,
|
NULL, NULL, WIN_TITLE,
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
0, REQWIN_HEIGHT,
|
0, REQWIN_HEIGHT,
|
||||||
0, REQWIN_HEIGHT,
|
0, REQWIN_HEIGHT,
|
||||||
WBENCHSCREEN
|
WBENCHSCREEN
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct Gadget list_down = {NULL, 0, 0,
|
static struct Gadget list_down = {NULL, 0, 0,
|
||||||
@ -249,6 +248,17 @@ int file_index(int mx, int my) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int vertpot2entry(int vertpot)
|
||||||
|
{
|
||||||
|
int index = vertpot / slider_increment, final_index = index;
|
||||||
|
if (index < 0 || num_current_files < NUM_FILE_ENTRIES) final_index = 0;
|
||||||
|
else if ((num_current_files - index) < NUM_FILE_ENTRIES) {
|
||||||
|
final_index = num_current_files - NUM_FILE_ENTRIES;
|
||||||
|
}
|
||||||
|
printf("computed index: %d, final index: %d\n", index, final_index);
|
||||||
|
return final_index;
|
||||||
|
}
|
||||||
|
|
||||||
static void render_list_backbuffer()
|
static void render_list_backbuffer()
|
||||||
{
|
{
|
||||||
ClipBlit(&filelist_rastport, 0, 0, requester.ReqLayer->rp,
|
ClipBlit(&filelist_rastport, 0, 0, requester.ReqLayer->rp,
|
||||||
@ -265,104 +275,6 @@ static void draw_selection(struct RastPort *src_rp)
|
|||||||
RectFill(src_rp, 0, y1, filelist_bm_width, y2);
|
RectFill(src_rp, 0, y1, filelist_bm_width, y2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_events()
|
|
||||||
{
|
|
||||||
BOOL done = FALSE;
|
|
||||||
struct IntuiMessage *msg;
|
|
||||||
ULONG msgClass;
|
|
||||||
UWORD menuCode;
|
|
||||||
int buttonId;
|
|
||||||
ULONG last_seconds, last_micros, seconds, micros;
|
|
||||||
int idx;
|
|
||||||
BOOL movestart = FALSE;
|
|
||||||
|
|
||||||
while (!done) {
|
|
||||||
Wait(1 << req_window->UserPort->mp_SigBit);
|
|
||||||
// since we expect mouse move operations, we need to process all events until
|
|
||||||
// the message queue is empty, otherwise we'll get funny effects by processing
|
|
||||||
// the queued up mouse move events when we actually were notified about a different
|
|
||||||
// event
|
|
||||||
while (msg = (struct IntuiMessage *) GetMsg(req_window->UserPort)) {
|
|
||||||
msgClass = msg->Class;
|
|
||||||
switch (msgClass) {
|
|
||||||
case IDCMP_MOUSEMOVE:
|
|
||||||
if (!movestart) {
|
|
||||||
CurrentTime(&last_seconds, &last_micros);
|
|
||||||
movestart = TRUE;
|
|
||||||
} else {
|
|
||||||
CurrentTime(&seconds, µs);
|
|
||||||
ULONG diff = (seconds - last_seconds) * 1000 + (micros - last_micros) / 1000;
|
|
||||||
if (diff > 300) {
|
|
||||||
// update the list, but ignore most of the move events,
|
|
||||||
// otherwise the we need to process too many events and
|
|
||||||
// refresh too often
|
|
||||||
idx = propinfo.VertPot / slider_increment;
|
|
||||||
printf("gadget up, vslider, vertpot: %d, incr: %d, idx: %d\n",
|
|
||||||
(int) propinfo.VertPot, slider_increment, idx);
|
|
||||||
last_seconds = seconds;
|
|
||||||
last_micros = micros;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ReplyMsg((struct Message *) msg);
|
|
||||||
break;
|
|
||||||
case IDCMP_MOUSEBUTTONS:
|
|
||||||
if (msg->Code == SELECTUP) {
|
|
||||||
// TODO: map to virtual file list indexes
|
|
||||||
WORD mx = msg->MouseX, my = msg->MouseY, file_i = file_index(mx, my);
|
|
||||||
if (file_i >= 0 && file_i != select_index) {
|
|
||||||
draw_selection(&filelist_rastport);
|
|
||||||
select_index = file_i;
|
|
||||||
draw_selection(&filelist_rastport);
|
|
||||||
render_list_backbuffer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ReplyMsg((struct Message *) msg);
|
|
||||||
break;
|
|
||||||
case IDCMP_GADGETUP:
|
|
||||||
buttonId = (int) ((struct Gadget *) (msg->IAddress))->GadgetID;
|
|
||||||
ReplyMsg((struct Message *) msg);
|
|
||||||
switch (buttonId) {
|
|
||||||
case REQ_OK_BUTTON_ID:
|
|
||||||
close_requester();
|
|
||||||
done = TRUE;
|
|
||||||
break;
|
|
||||||
case REQ_CANCEL_BUTTON_ID:
|
|
||||||
close_requester();
|
|
||||||
done = TRUE;
|
|
||||||
break;
|
|
||||||
case LIST_UP_ID:
|
|
||||||
// TODO: adjust the vertpot by the increment
|
|
||||||
// update first_visible_entry and
|
|
||||||
break;
|
|
||||||
case LIST_DOWN_ID:
|
|
||||||
break;
|
|
||||||
case VSLIDER_ID:
|
|
||||||
// determine the portion to be displayed
|
|
||||||
idx = propinfo.VertPot / slider_increment;
|
|
||||||
printf("gadget up, vslider, vertpot: %d, incr: %d, idx: %d\n",
|
|
||||||
(int) propinfo.VertPot, slider_increment, idx);
|
|
||||||
movestart = FALSE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cleanup()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < filelist_bm_depth; i++) {
|
|
||||||
if (filelist_bitmap.Planes[i]) FreeRaster(filelist_bitmap.Planes[i],
|
|
||||||
filelist_width,
|
|
||||||
filelist_height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void clear_list()
|
static void clear_list()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < filelist_bm_depth; i++) {
|
for (int i = 0; i < filelist_bm_depth; i++) {
|
||||||
@ -405,6 +317,132 @@ static void draw_list()
|
|||||||
render_list_backbuffer();
|
render_list_backbuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void update_list(int new_first_index)
|
||||||
|
{
|
||||||
|
struct FileListEntry *cur = first_visible_entry;
|
||||||
|
int current_index = cur->index;
|
||||||
|
if (new_first_index < current_index) {
|
||||||
|
while (cur->index > new_first_index) cur = cur->prev;
|
||||||
|
} else if (new_first_index > current_index) {
|
||||||
|
while (cur->index < new_first_index) cur = cur->next;
|
||||||
|
}
|
||||||
|
first_visible_entry = cur;
|
||||||
|
clear_list();
|
||||||
|
draw_list();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_events()
|
||||||
|
{
|
||||||
|
BOOL done = FALSE;
|
||||||
|
struct IntuiMessage *msg;
|
||||||
|
ULONG msgClass;
|
||||||
|
UWORD menuCode;
|
||||||
|
int buttonId;
|
||||||
|
ULONG last_seconds, last_micros, seconds, micros;
|
||||||
|
int idx;
|
||||||
|
BOOL movestart = FALSE;
|
||||||
|
|
||||||
|
while (!done) {
|
||||||
|
Wait(1 << req_window->UserPort->mp_SigBit);
|
||||||
|
// since we expect mouse move operations, we need to process all events until
|
||||||
|
// the message queue is empty, otherwise we'll get funny effects by processing
|
||||||
|
// the queued up mouse move events when we actually were notified about a different
|
||||||
|
// event
|
||||||
|
while (msg = (struct IntuiMessage *) GetMsg(req_window->UserPort)) {
|
||||||
|
msgClass = msg->Class;
|
||||||
|
switch (msgClass) {
|
||||||
|
case IDCMP_MOUSEMOVE:
|
||||||
|
if (!movestart) {
|
||||||
|
CurrentTime(&last_seconds, &last_micros);
|
||||||
|
movestart = TRUE;
|
||||||
|
} else {
|
||||||
|
CurrentTime(&seconds, µs);
|
||||||
|
ULONG diff = (seconds - last_seconds) * 1000 + (micros - last_micros) / 1000;
|
||||||
|
if (diff > 300) {
|
||||||
|
// update the list, but ignore most of the move events,
|
||||||
|
// otherwise the we need to process too many events and
|
||||||
|
// refresh too often
|
||||||
|
idx = vertpot2entry(propinfo.VertPot);
|
||||||
|
last_seconds = seconds;
|
||||||
|
last_micros = micros;
|
||||||
|
update_list(idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ReplyMsg((struct Message *) msg);
|
||||||
|
break;
|
||||||
|
case IDCMP_MOUSEBUTTONS:
|
||||||
|
if (msg->Code == SELECTUP) {
|
||||||
|
// TODO: map to virtual file list indexes
|
||||||
|
WORD mx = msg->MouseX, my = msg->MouseY, file_i = file_index(mx, my);
|
||||||
|
if (file_i >= 0 && file_i != select_index) {
|
||||||
|
draw_selection(&filelist_rastport);
|
||||||
|
select_index = file_i;
|
||||||
|
draw_selection(&filelist_rastport);
|
||||||
|
render_list_backbuffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ReplyMsg((struct Message *) msg);
|
||||||
|
break;
|
||||||
|
case IDCMP_GADGETUP:
|
||||||
|
buttonId = (int) ((struct Gadget *) (msg->IAddress))->GadgetID;
|
||||||
|
ReplyMsg((struct Message *) msg);
|
||||||
|
switch (buttonId) {
|
||||||
|
case REQ_OK_BUTTON_ID:
|
||||||
|
close_requester();
|
||||||
|
done = TRUE;
|
||||||
|
break;
|
||||||
|
case REQ_CANCEL_BUTTON_ID:
|
||||||
|
close_requester();
|
||||||
|
done = TRUE;
|
||||||
|
break;
|
||||||
|
case LIST_UP_ID:
|
||||||
|
{
|
||||||
|
int newpot = propinfo.VertPot - slider_increment;
|
||||||
|
if (newpot < 0) newpot = 0;
|
||||||
|
NewModifyProp(&list_vslider, req_window, &requester, AUTOKNOB | FREEVERT,
|
||||||
|
0, newpot, MAXBODY, propinfo.VertBody, 1);
|
||||||
|
int idx = vertpot2entry(newpot);
|
||||||
|
update_list(idx);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LIST_DOWN_ID:
|
||||||
|
{
|
||||||
|
int newpot = propinfo.VertPot + slider_increment;
|
||||||
|
if (newpot > MAXBODY) newpot = MAXBODY;
|
||||||
|
NewModifyProp(&list_vslider, req_window, &requester, AUTOKNOB | FREEVERT,
|
||||||
|
0, newpot, MAXBODY, propinfo.VertBody, 1);
|
||||||
|
int idx = vertpot2entry(newpot);
|
||||||
|
update_list(idx);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case VSLIDER_ID:
|
||||||
|
// determine the portion to be displayed
|
||||||
|
idx = vertpot2entry(propinfo.VertPot);
|
||||||
|
printf("gadget up, vslider, vertpot: %d, incr: %d, idx: %d\n",
|
||||||
|
(int) propinfo.VertPot, slider_increment, idx);
|
||||||
|
movestart = FALSE;
|
||||||
|
update_list(idx);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cleanup()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < filelist_bm_depth; i++) {
|
||||||
|
if (filelist_bitmap.Planes[i]) FreeRaster(filelist_bitmap.Planes[i],
|
||||||
|
filelist_width,
|
||||||
|
filelist_height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize the requester window and gadget sizes according to the current font and
|
/* Initialize the requester window and gadget sizes according to the current font and
|
||||||
screen resolutions. The window parameter is used to determine the font and the parent
|
screen resolutions. The window parameter is used to determine the font and the parent
|
||||||
window position.
|
window position.
|
||||||
@ -473,7 +511,6 @@ void init_sizes(struct Window *window, struct Requester *requester)
|
|||||||
|
|
||||||
void open_file(struct Window *window)
|
void open_file(struct Window *window)
|
||||||
{
|
{
|
||||||
BOOL result;
|
|
||||||
InitRequester(&requester);
|
InitRequester(&requester);
|
||||||
init_sizes(window, &requester);
|
init_sizes(window, &requester);
|
||||||
if (req_window = OpenWindow(&newwin)) {
|
if (req_window = OpenWindow(&newwin)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user