# HG changeset patch # User Michael Pavone # Date 1446848261 28800 # Node ID 1bab7e01ae98ce6bc567731a331bcaf99da77082 # Parent bacd67a82d58e1a731dd0e2824b440dd2c3de4c2 Allow directory navigation in menu. Sort directory entries diff -r bacd67a82d58 -r 1bab7e01ae98 menu.c --- a/menu.c Fri Nov 06 13:44:21 2015 -0800 +++ b/menu.c Fri Nov 06 14:17:41 2015 -0800 @@ -17,6 +17,17 @@ return 0; } +int menu_dir_sort(const void *a, const void *b) +{ + const dir_entry *da, *db; + da = a; + db = b; + if (da->is_dir != db->is_dir) { + return db->is_dir - da->is_dir; + } + return strcasecmp(((dir_entry *)a)->name, ((dir_entry *)b)->name); +} + void * menu_write_w(uint32_t address, void * context, uint16_t value) { m68k_context *m68k = context; @@ -33,9 +44,13 @@ case 0: { size_t num_entries; dir_entry *entries = get_dir_list(menu->curpath, &num_entries); + if (entries) { + qsort(entries, num_entries, sizeof(dir_entry), menu_dir_sort); + } + uint8_t *dest; for (size_t i = 0; i < num_entries; i++) { - uint8_t *dest = get_native_pointer(dst, (void **)m68k->mem_pointers, &m68k->options->gen); + dest = get_native_pointer(dst, (void **)m68k->mem_pointers, &m68k->options->gen); if (!dest) { break; } @@ -69,7 +84,36 @@ dst += 2; } } - free_dir_list(entries, num_entries); + //terminate list + dest = get_native_pointer(dst, (void **)m68k->mem_pointers, &m68k->options->gen); + if (dest) { + *dest = dest[1] = 0; + free_dir_list(entries, num_entries); + } + break; + } + case 1: { + char buf[4096]; + char *cur; + char * dest = NULL; + for (cur = buf; cur < buf+sizeof(buf); cur+=2, dst+=2, dest+=2) + { + if (!dest || !(dst & 0xFFFF)) { + //we may have walked off the end of a memory block, get a fresh native pointer + dest = get_native_pointer(dst, (void **)m68k->mem_pointers, &m68k->options->gen); + if (!dest) { + break; + } + } + *cur = dest[1]; + cur[1] = *dest; + if (!*dest || !dest[1]) { + break; + } + } + char *pieces[] = {menu->curpath, "/", buf}; + menu->curpath = alloc_concat_m(3, pieces); + free(pieces[0]); break; } default: diff -r bacd67a82d58 -r 1bab7e01ae98 menu.s68 --- a/menu.s68 Fri Nov 06 13:44:21 2015 -0800 +++ b/menu.s68 Fri Nov 06 14:17:41 2015 -0800 @@ -172,8 +172,10 @@ x_pos rs.w 1 base_cmd rs.l 1 sprite_list rs.l 160 +page_index rs.l MAX_DISPLAY+1 num_sprites rs.b 1 last_pad rs.b 1 +selected rs.b 1 int_6: dmasrc sprite_list, DMA_SRC_68K @@ -190,6 +192,7 @@ move.l d0, (a1) startdma $C000, VDP_VRAM_WRITE + ;read gamepad in port 1 lea PAD1_DATA, a2 move.b #$40, (a2) move.b (a2), d0 @@ -200,28 +203,69 @@ add.b d1, d1 add.b d1, d1 or.b d1, d0 - not.b d0 + not.b d0 ;button state is inveterted move.b (last_pad).w, d1 eor.b d0, d1 and.b d0, d1 move.b d0, (last_pad).w moveq #16, d2 + ;d0 = SACBRLUD + ;d1 = newly pressed buttons btst #1, d1 bne down btst #0, d1 bne up + btst #7, d1 + bne start_pressed +int_done: rte down: + ;check if we are already at the bottom of the page + moveq #1, d0 + add.b (selected).w, d0 + move.w d0, d1 + add.w d0, d0 + add.w d0, d0 + lea page_index.w, a2 + tst.l (0, a2, d0.w) + beq int_done + move.b d1, (selected).w + add.w d2, (sprite_list).w add.w d2, (sprite_list+8).w rte up: + ;check if we are already at the top of the page + move.b (selected).w, d0 + beq int_done + subq #1, d0 + move.b d0, (selected).w + sub.w d2, (sprite_list).w sub.w d2, (sprite_list+8).w rte +start_pressed: + moveq #0, d0 + move.b (selected).w, d0 + add.w d0, d0 + add.w d0, d0 + lea page_index.w, a2 + lea (-1, a2, d0.w), a2 + tst.b (a2)+ + bne enter_dir + ;regular file + rte +enter_dir: + lea menu_port+4, a3 + move.l (a2), (a3) +.wait_complete + tst.w (a3) + bne .wait_complete + addq #6, a7 + bra menu_start int_4: empty_handler: rte @@ -273,15 +317,7 @@ - ;clear name tables - vdpaccess $8000, VDP_VRAM_WRITE - moveq #32, d0 - swap d0 - move.b #32, d0 - move.w #(64*64-1), d1 -ploop: - move.l d0, (a0) - dbra d1, ploop + ;setup SAT ;;vdpaccess $C000, VDP_VRAM_WRITE @@ -296,6 +332,17 @@ move.l #$887F01AA, (a2)+ move.b #2, num_sprites.w +menu_start: + ;clear name tables + vdpaccess $8000, VDP_VRAM_WRITE + moveq #32, d0 + swap d0 + move.b #32, d0 + move.w #(64*64-1), d1 +ploop: + move.l d0, (a0) + dbra d1, ploop + move.l #$40860002, d3 move.l d3, (a1) move.l d3, base_cmd.w @@ -308,11 +355,14 @@ tst.w (a2) bne wait_complete + lea page_index.w, a3 moveq #MAX_DISPLAY-1, d7 file_loop: tst.b (a6)+ + beq done_files addq #1, a6 ;TODO: Do something with directory flag + ;skip over entries starting with a dot except .. cmp.b #$2E, (a6) bne normal cmp.b #$2E, (1, a6) @@ -325,6 +375,9 @@ move.l a6, d6 bra skip normal: + ;save entry pointer to page index + move.l a6, (a3)+ + ;print name on screen moveq #0, d0 bsr print_string move.l a6, d6 @@ -339,6 +392,11 @@ move.l d6, a6 dbra d7, file_loop +done_files: + + ;null terminate page_index + moveq #0, d0 + move.l d0, (a3) ;setup gamepad in port 1 move.b #$40, PAD1_CTRL