Skip to content

Commit d100818

Browse files
committed
Long filename scrolling on CoCo
1 parent 1013871 commit d100818

File tree

6 files changed

+159
-13
lines changed

6 files changed

+159
-13
lines changed

makefiles/toolchains/cmoc.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ include $(MWD)/tc-common.mk
77

88
CFLAGS += --intdir=$(OBJ_DIR)
99
ASFLAGS +=
10-
LDFLAGS +=
10+
LDFLAGS += --org=0E00 --limit=7C00
1111

1212
CFLAGS += -DGIT_VERSION='"$(GIT_VERSION)"'
1313

src/coco/input.c

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "../select_file.h"
1717
#include "../set_wifi.h"
1818
#include "../select_slot.h"
19+
#include "scroll.h"
1920

2021
unsigned char selected_network;
2122
extern bool copy_mode;
@@ -367,16 +368,20 @@ SFSubState input_select_file_choose(void)
367368
char k;
368369
unsigned entryType = 0;
369370

371+
scroll_reset(true);
372+
370373
locate(31, 15);
371374

372375
while (true)
373376
{
374-
k = waitkey(true);
377+
word now = getTimer();
378+
k = inkey();
375379

376380
switch (k)
377381
{
378382
case 'C':
379383
case 'c':
384+
scroll_reset(false);
380385
if (copy_mode == true)
381386
{
382387
return SF_DONE;
@@ -411,6 +416,7 @@ SFSubState input_select_file_choose(void)
411416
else
412417
return SF_DONE;
413418
case KEY_UP_ARROW: // up arrow
419+
scroll_reset(false);
414420
if ((bar_get() == 0) && (pos > 0))
415421
return SF_PREV_PAGE;
416422
else
@@ -422,10 +428,12 @@ SFSubState input_select_file_choose(void)
422428
return SF_CHOOSE;
423429
}
424430
case KEY_SHIFT_UP_ARROW: // shifted up arrow
431+
scroll_reset(false);
425432
if (pos > 0)
426433
return SF_PREV_PAGE;
427434
break;
428435
case KEY_DOWN_ARROW: // down arrow
436+
scroll_reset(false);
429437
if ((bar_get() == 9) && (dir_eof == false))
430438
return SF_NEXT_PAGE;
431439
else
@@ -438,11 +446,25 @@ SFSubState input_select_file_choose(void)
438446
}
439447
break;
440448
case KEY_SHIFT_DOWN_ARROW: // shifted down arrow
449+
scroll_reset(false);
441450
if (dir_eof == false)
442451
return SF_NEXT_PAGE;
443452
break;
444-
default:
445-
return SF_CHOOSE;
453+
}
454+
455+
// Handle idle countdown + timed scroll
456+
if ((word)(now - lastTimer) >= SCROLL_DELAY_TICKS)
457+
{
458+
lastTimer = now;
459+
460+
if (idleCounter > 0)
461+
{
462+
idleCounter--;
463+
}
464+
else
465+
{
466+
scroll_step();
467+
}
446468
}
447469
}
448470

src/coco/scroll.c

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#include <cmoc.h>
2+
#include <coco.h>
3+
#include <fujinet-fuji.h>
4+
#include "../constants.h"
5+
#include "../globals.h"
6+
#include "../screen.h"
7+
#include "scroll.h"
8+
9+
word lastTimer;
10+
word idleCounter = IDLE_TIMEOUT_COUNT;
11+
int scrollOffset = 0;
12+
int scrollDir = 1; // 1 = right, -1 = left
13+
byte got_scrolltext;
14+
15+
16+
// Draw one line of up to 32 chars from given offset (bounce mode)
17+
void scroll_draw_line_at_y(const char *line, byte y, int offset)
18+
{
19+
char buf[SCREEN_WIDTH + 1];
20+
int len = strlen(line);
21+
22+
memset(buf, ' ', SCREEN_WIDTH);
23+
buf[SCREEN_WIDTH] = 0;
24+
25+
if (offset < len)
26+
{
27+
int copyLen = len - offset;
28+
if (copyLen > SCREEN_WIDTH)
29+
copyLen = SCREEN_WIDTH;
30+
memcpy(buf, line + offset, copyLen);
31+
}
32+
33+
locate(0, y+3); // Need to add offset for file choice screen
34+
putstr(buf, SCREEN_WIDTH);
35+
bar_draw(y+3, false);
36+
}
37+
38+
39+
// Scroll the currently highlighted line by 1 character (bounce mode)
40+
void scroll_step(void)
41+
{
42+
byte y = (byte) bar_get();
43+
if (!got_scrolltext)
44+
{
45+
// Get the full text to scroll
46+
select_get_filename(255);
47+
got_scrolltext = true;
48+
}
49+
50+
int len = strlen(response);
51+
52+
if (len <= SCREEN_WIDTH)
53+
return; // no need to scroll
54+
55+
scrollOffset += scrollDir;
56+
if (scrollOffset < 0)
57+
{
58+
scrollOffset = 0;
59+
scrollDir = 1;
60+
}
61+
else if (scrollOffset > len - SCREEN_WIDTH)
62+
{
63+
scrollOffset = len - SCREEN_WIDTH;
64+
scrollDir = -1;
65+
}
66+
67+
scroll_draw_line_at_y(response, y, scrollOffset);
68+
}
69+
70+
// Reset scrolling when user interacts,
71+
// Or initial zetup
72+
void scroll_reset(bool init)
73+
{
74+
byte y = (byte)bar_get();
75+
scrollOffset = 0;
76+
scrollDir = 1;
77+
idleCounter = IDLE_TIMEOUT_COUNT;
78+
if (init)
79+
{
80+
lastTimer = 0;
81+
}
82+
else
83+
{
84+
if (got_scrolltext && strlen(response) > SCREEN_WIDTH)
85+
{
86+
// Get the short version of the text again
87+
select_get_filename(DIR_MAX_LEN);
88+
89+
screen_select_file_display_entry(y, response, 0);
90+
}
91+
}
92+
got_scrolltext = false;
93+
}

src/coco/scroll.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#ifndef SCROLL_H
2+
#define SCROLL_H
3+
#include <cmoc.h>
4+
#include <coco.h>
5+
// Timer runs at 60 Hz
6+
#define SCROLL_DELAY_TICKS 30 // 30 ticks = ~0.5 sec
7+
#define IDLE_TIMEOUT_COUNT 10 // 10 × 0.5s = ~5 sec
8+
#define SCREEN_WIDTH 32
9+
10+
extern word lastTimer;
11+
extern word idleCounter;
12+
extern int scrollOffset;
13+
extern int scrollDir; // 1 = right, -1 = left
14+
15+
static void scroll_draw_line_at_y(const char *line, byte y, int offset);
16+
static void scroll_step(void);
17+
void scroll_reset(bool init);
18+
19+
#endif

src/select_file.c

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
* Select file from Host Slot
33
*/
44

5+
#include <fujinet-fuji.h>
56
#include "select_file.h"
67
#include "screen.h"
78
#include "constants.h"
@@ -150,18 +151,11 @@ void select_display_long_filename(void)
150151
#else
151152
if ((entry_size[bar_get()] > 30) && (entry_timer == 0))
152153
#endif
153-
{
154+
{
154155
if (long_entry_displayed == false)
155156
{
156-
fuji_open_directory2(selected_host_slot, path, filter);
157-
#ifdef BUILD_ATARI
158-
fuji_set_directory_position(pos + bar_get() - FILES_START_Y);
159-
#else
160-
fuji_set_directory_position(pos + bar_get());
161-
#endif
162-
fuji_read_directory(64, 0, response);
157+
select_get_filename(64);
163158
screen_select_file_display_long_filename(response);
164-
fuji_close_directory();
165159
long_entry_displayed = true;
166160
}
167161
}
@@ -172,6 +166,21 @@ void select_display_long_filename(void)
172166
}
173167
}
174168

169+
void select_get_filename(uint8_t len)
170+
{
171+
fuji_mount_host_slot(selected_host_slot);
172+
173+
fuji_open_directory2(selected_host_slot, path, filter);
174+
175+
#ifdef BUILD_ATARI
176+
fuji_set_directory_position(pos + bar_get() - FILES_START_Y);
177+
#else
178+
fuji_set_directory_position(pos + bar_get());
179+
#endif
180+
fuji_read_directory(len, 0, response);
181+
fuji_close_directory();
182+
}
183+
175184
void select_next_page(void)
176185
{
177186
bar_clear(false);

src/select_file.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@
55
#ifndef SELECT_FILE_H
66
#define SELECT_FILE_H
77

8+
#include <fujinet-fuji.h>
9+
810
#define ENTRY_TIMER_DUR 128
911

1012
void select_file(void);
1113
void select_display_long_filename(void);
14+
void select_get_filename(uint8_t len);
1215
void select_file_set_source_filename(void);
1316
unsigned char select_file_is_folder(void);
1417
unsigned select_file_entry_type(void);

0 commit comments

Comments
 (0)