1
0
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:
Wei-ju Wu
2016-01-21 07:19:50 -08:00
parent 3573e7b9a0
commit 907e05c7bc
7 changed files with 160 additions and 121 deletions

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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];
}; };

View File

@ -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, &micros);
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, &micros);
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)) {