parent
d027bff0bf
commit
04ac7cdf40
|
@ -21,6 +21,7 @@ set(SOURCES
|
|||
src/polarity.c
|
||||
src/time.c
|
||||
src/missile.c
|
||||
src/filedialog.c
|
||||
)
|
||||
|
||||
set(ASSETS
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
|
||||
int filedialog_open(char *buf, int n);
|
||||
int filedialog_save(char *buf, int n);
|
|
@ -0,0 +1,189 @@
|
|||
#include "filedialog.h"
|
||||
#include <dirent.h>
|
||||
#include <gint/display.h>
|
||||
#include <gint/gint.h>
|
||||
#include <gint/keyboard.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static void
|
||||
path_append(char **path, char const *folder)
|
||||
{
|
||||
char *newpath = malloc(strlen(*path) + strlen(folder) + 2);
|
||||
strcpy(newpath, *path);
|
||||
if (strcmp(*path, "/") != 0) strcat(newpath, "/");
|
||||
strcat(newpath, folder);
|
||||
free(*path);
|
||||
*path = newpath;
|
||||
}
|
||||
|
||||
static void
|
||||
path_remove(char **path)
|
||||
{
|
||||
if (!strcmp(*path, "/")) return;
|
||||
*strrchr(*path, '/') = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
accept_entry(struct dirent *ent)
|
||||
{
|
||||
if (!strcmp(ent->d_name, "@MainMem")) return 0;
|
||||
if (!strcmp(ent->d_name, "SAVE-F")) return 0;
|
||||
if (!strcmp(ent->d_name, ".")) return 0;
|
||||
if (!strcmp(ent->d_name, "..")) return 0;
|
||||
/* here we could filter based on suffix */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
load_folder(char const *path, DIR **dp, int *total, int allow_new_file)
|
||||
{
|
||||
struct dirent *ent;
|
||||
|
||||
if (*dp) closedir(*dp);
|
||||
*dp = (DIR *)gint_world_switch(GINT_CALL(opendir, path));
|
||||
*total = allow_new_file;
|
||||
|
||||
while ((ent = readdir(*dp)))
|
||||
*total += accept_entry(ent);
|
||||
}
|
||||
|
||||
static int
|
||||
letter_for_key(int key, int alpha)
|
||||
{
|
||||
if (alpha) {
|
||||
int row = 6 - (key >> 4);
|
||||
int col = (key & 0x0f) - 1;
|
||||
int i = 6 * row + col;
|
||||
return "abcdefghijklmno\0\0\0pqrst\0uvwxy\0z \"\0\0\0"[i];
|
||||
}
|
||||
|
||||
int digit = keycode_digit(key);
|
||||
if (digit >= 0) return digit + '0';
|
||||
|
||||
if (key == KEY_DOT) return '.';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
do_dialog(char *buf, int n, int allow_new_file)
|
||||
{
|
||||
char *path = strdup("/"), *entry_name, *selected_name;
|
||||
DIR *dp = NULL;
|
||||
struct dirent *ent, *selected_ent;
|
||||
int total = 0, cursor = 0, scroll = 0, edit = -1, isfolder = 0, rc = 0;
|
||||
/* both sizes below can be changed */
|
||||
const int visible = 13;
|
||||
char new_name[32];
|
||||
|
||||
load_folder(path, &dp, &total, allow_new_file);
|
||||
|
||||
for (;;) {
|
||||
rewinddir(dp);
|
||||
dclear(C_BLACK);
|
||||
dprint(1, 1, C_WHITE, "Browsing: %s", path);
|
||||
|
||||
selected_name = NULL;
|
||||
selected_ent = NULL;
|
||||
|
||||
for (int i = -scroll; i < visible;) {
|
||||
int selected = (cursor == scroll + i);
|
||||
|
||||
/* when editing is enabled offer an entry "new file" */
|
||||
if (i == -scroll && allow_new_file) {
|
||||
entry_name = edit >= 0 ? new_name
|
||||
: "<Create a new file>";
|
||||
isfolder = 0;
|
||||
} else {
|
||||
ent = readdir(dp);
|
||||
if (!ent) break;
|
||||
if (!accept_entry(ent)) continue;
|
||||
entry_name = ent->d_name;
|
||||
isfolder = (ent->d_type == DT_DIR);
|
||||
if (selected) selected_ent = ent;
|
||||
}
|
||||
if (i < 0) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
int y = 20 + 15 * i;
|
||||
if (selected) {
|
||||
selected_name = entry_name;
|
||||
drect(0, y - 1, DWIDTH - 1, y + 13, C_WHITE);
|
||||
}
|
||||
dprint(1, y, selected ? C_BLACK : C_WHITE, "%s%s",
|
||||
entry_name,
|
||||
isfolder ? "/"
|
||||
: entry_name == new_name ? "|"
|
||||
: "");
|
||||
i++;
|
||||
}
|
||||
|
||||
dupdate();
|
||||
|
||||
key_event_t ev = getkey();
|
||||
int key = ev.key;
|
||||
if (key == KEY_UP && cursor > 0) cursor--;
|
||||
if (key == KEY_DOWN && cursor < total - 1) cursor++;
|
||||
|
||||
if (scroll > 0 && cursor <= scroll) scroll = cursor - 1;
|
||||
if (scroll + visible < total && cursor >= scroll + visible - 2)
|
||||
scroll = cursor - visible + 2;
|
||||
|
||||
int changed_path = 0;
|
||||
if (key == KEY_EXIT && edit >= 0) {
|
||||
edit = -1;
|
||||
} else if (key == KEY_EXIT) {
|
||||
if (!strcmp(path, "/")) goto end;
|
||||
path_remove(&path);
|
||||
changed_path = 1;
|
||||
} else if (key == KEY_EXE && edit > 0) {
|
||||
break;
|
||||
} else if (key == KEY_EXE && !selected_ent) {
|
||||
memset(new_name, 0, sizeof new_name);
|
||||
edit = 0;
|
||||
} else if (key == KEY_EXE && selected_ent->d_type == DT_DIR) {
|
||||
path_append(&path, selected_ent->d_name);
|
||||
changed_path = 1;
|
||||
} else if (key == KEY_EXE && selected_ent->d_type != DT_DIR) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (edit > 0 && key == KEY_DEL) {
|
||||
new_name[--edit] = 0;
|
||||
} else if (edit >= 0 && new_name[sizeof new_name - 2] == 0) {
|
||||
int letter = letter_for_key(key, ev.alpha);
|
||||
if (letter) new_name[edit++] = letter;
|
||||
}
|
||||
|
||||
if (changed_path) {
|
||||
load_folder(path, &dp, &total, allow_new_file);
|
||||
cursor = scroll = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ((size_t)n >= strlen(path) + strlen(selected_name) + 2) {
|
||||
strcpy(buf, path);
|
||||
if (strcmp(path, "/") != 0) strcat(buf, "/");
|
||||
strcat(buf, selected_name);
|
||||
} else
|
||||
rc = 1;
|
||||
|
||||
end:
|
||||
free(path);
|
||||
closedir(dp);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
filedialog_open(char *buf, int n)
|
||||
{
|
||||
return do_dialog(buf, n, 0);
|
||||
}
|
||||
|
||||
int
|
||||
filedialog_save(char *buf, int n)
|
||||
{
|
||||
return do_dialog(buf, n, 1);
|
||||
}
|
15
src/main.c
15
src/main.c
|
@ -1,5 +1,6 @@
|
|||
#include "conf.h"
|
||||
#include "editor.h"
|
||||
#include "filedialog.h"
|
||||
#include "input.h"
|
||||
#include "level.h"
|
||||
#include "missile.h"
|
||||
|
@ -9,6 +10,7 @@
|
|||
#include <gint/cpu.h>
|
||||
#include <gint/display.h>
|
||||
#include <gint/gint.h>
|
||||
#include <gint/keyboard.h>
|
||||
#include <gint/timer.h>
|
||||
|
||||
static struct Player player;
|
||||
|
@ -28,6 +30,19 @@ main(void)
|
|||
int frameskip = 1;
|
||||
|
||||
init();
|
||||
|
||||
//-
|
||||
char path[128];
|
||||
int rc = filedialog_save(path, 128);
|
||||
has_ticked = 0;
|
||||
dclear(C_BLACK);
|
||||
dprint(1, 1, C_WHITE, "%s (%d)", *path ? path : "(null)", rc);
|
||||
dupdate();
|
||||
getkey();
|
||||
input_update();
|
||||
input_update();
|
||||
//-
|
||||
|
||||
level_load(0);
|
||||
|
||||
for (;;) {
|
||||
|
|
Loading…
Reference in New Issue