From 907e05c7bc57270296d38f80206255d0b0ae8e33 Mon Sep 17 00:00:00 2001 From: Wei-ju Wu Date: Thu, 21 Jan 2016 07:19:50 -0800 Subject: [PATCH] scrolling works somewhat the indexes are not entirely correct --- iffview/Makefile | 2 +- iffview/ilbm.c | 14 +-- iffview/ilbm.h | 8 +- requesters/Makefile | 2 +- requesters/dos13.c | 1 + requesters/dos13.h | 1 + requesters/filereq.c | 253 +++++++++++++++++++++++++------------------ 7 files changed, 160 insertions(+), 121 deletions(-) diff --git a/iffview/Makefile b/iffview/Makefile index 9b42f1e..ddbeabe 100644 --- a/iffview/Makefile +++ b/iffview/Makefile @@ -14,4 +14,4 @@ iffview: iffview.o ilbm.o # interestingly, when defining std=c99, LITTLE_ENDIAN disappears as a definition # in gcc, so we define it explicitly ilbm: ilbm.c - gcc -o $@ $< -DSTANDALONE -DDEBUG -std=c99 -DLITTLE_ENDIAN + gcc -o $@ $< -DSTANDALONE -DDEBUG -std=c99 -pedantic -DLITTLE_ENDIAN diff --git a/iffview/ilbm.c b/iffview/ilbm.c index 868d7aa..b8c022a 100644 --- a/iffview/ilbm.c +++ b/iffview/ilbm.c @@ -102,7 +102,7 @@ void read_CRNG(FILE *fp, int datasize) UBYTE *read_BODY(FILE *fp, int datasize, BitMapHeader *bmheader, int *data_bytes) { ULONG bytes_read; - BYTE *buffer, *dst_buffer; + UBYTE *buffer, *dst_buffer; int src_i = 0, dst_i = 0, dst_size; buffer = malloc(datasize); @@ -153,11 +153,11 @@ ILBMData *read_chunks(FILE *fp, int filesize, int total_read) #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, &result->num_colors); - else if (!strncmp("CRNG", buffer, 4)) read_CRNG(fp, datasize); - else if (!strncmp("CAMG", buffer, 4)) bmheader->camgFlags = read_CAMG(fp, datasize); - else if (!strncmp("BODY", buffer, 4)) imgdata = read_BODY(fp, datasize, bmheader, &imgdata_size); + if (!strncmp("BMHD", (const char *) buffer, 4)) bmheader = read_BMHD(fp, datasize); + else if (!strncmp("CMAP", (const char *) buffer, 4)) colors = read_CMAP(fp, datasize, &result->num_colors); + else if (!strncmp("CRNG", (const char *) buffer, 4)) read_CRNG(fp, datasize); + else if (!strncmp("CAMG", (const char *) buffer, 4)) bmheader->camgFlags = read_CAMG(fp, datasize); + else if (!strncmp("BODY", (const char *) buffer, 4)) imgdata = read_BODY(fp, datasize, bmheader, &imgdata_size); else { #ifdef DEBUG 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 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 row_data_size = num_planes * src_bytes_per_row; diff --git a/iffview/ilbm.h b/iffview/ilbm.h index a0f6a1c..e4fcaa8 100644 --- a/iffview/ilbm.h +++ b/iffview/ilbm.h @@ -26,10 +26,10 @@ #else -#include -#define ULONG u_int32_t -#define UWORD u_int16_t -#define UBYTE u_int8_t +#include +#define ULONG uint32_t +#define UWORD uint16_t +#define UBYTE uint8_t #define LONG int32_t #define WORD int16_t diff --git a/requesters/Makefile b/requesters/Makefile index abf4508..d5f02f1 100644 --- a/requesters/Makefile +++ b/requesters/Makefile @@ -1,6 +1,6 @@ #CC=vc +aos68k CC=vc +kick13 -CFLAGS=-c99 -I$(NDK_INC) -DDEBUG +CFLAGS=-c99 -I$(NDK_INC) -DDEBUG -O2 all: main diff --git a/requesters/dos13.c b/requesters/dos13.c index a9b96d6..6989d5e 100644 --- a/requesters/dos13.c +++ b/requesters/dos13.c @@ -41,6 +41,7 @@ struct FileListEntry *scan_dir(const char *dirpath, int *num_entries) if (current->dvi_Type != DLT_DEVICE) { tmp = calloc(1, sizeof(struct FileListEntry)); tmp->file_type = FILETYPE_VOLUME; + tmp->index = n; strncpy(tmp->name, ((char *) BADDR(current->dvi_Name)) + 1, MAX_FILENAME_LEN); fname_len = strlen(tmp->name); // add the colon character to point out that we have a logical volume diff --git a/requesters/dos13.h b/requesters/dos13.h index 02119b7..a74db00 100644 --- a/requesters/dos13.h +++ b/requesters/dos13.h @@ -20,6 +20,7 @@ struct FileListEntry { struct FileListEntry *next, *prev; UWORD file_type; + UWORD index; // index in the list char name[MAX_FILENAME_LEN + 1]; }; diff --git a/requesters/filereq.c b/requesters/filereq.c index a22f825..75c656e 100644 --- a/requesters/filereq.c +++ b/requesters/filereq.c @@ -25,7 +25,6 @@ #define NUM_FILE_ENTRIES 10 -// some of these variables don't need to be static static int filelist_width; static int filelist_height; static int filelist_bm_width; @@ -133,14 +132,14 @@ static struct PropInfo propinfo = {AUTOKNOB | FREEVERT, 0, 0, MAXBODY, MAXBODY, #define WIN_TITLE "Open File..." static struct NewWindow newwin = { - 0, 0, 0, REQWIN_HEIGHT, 0, 1, - IDCMP_GADGETUP | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE, - WFLG_CLOSEGADGET | WFLG_SMART_REFRESH | WFLG_ACTIVATE | WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_NOCAREREFRESH, - NULL, NULL, WIN_TITLE, - NULL, NULL, - 0, REQWIN_HEIGHT, - 0, REQWIN_HEIGHT, - WBENCHSCREEN + 0, 0, 0, REQWIN_HEIGHT, 0, 1, + IDCMP_GADGETUP | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE, + WFLG_CLOSEGADGET | WFLG_SMART_REFRESH | WFLG_ACTIVATE | WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_NOCAREREFRESH, + NULL, NULL, WIN_TITLE, + NULL, NULL, + 0, REQWIN_HEIGHT, + 0, REQWIN_HEIGHT, + WBENCHSCREEN }; static struct Gadget list_down = {NULL, 0, 0, @@ -249,6 +248,17 @@ int file_index(int mx, int my) { 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() { 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); } -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() { for (int i = 0; i < filelist_bm_depth; i++) { @@ -405,6 +317,132 @@ static void draw_list() 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 screen resolutions. The window parameter is used to determine the font and the parent window position. @@ -473,7 +511,6 @@ void init_sizes(struct Window *window, struct Requester *requester) void open_file(struct Window *window) { - BOOL result; InitRequester(&requester); init_sizes(window, &requester); if (req_window = OpenWindow(&newwin)) {