mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2025-05-18 23:39:17 +02:00
fygue: merge dev branch that add FXCP400 file IO support
This commit is contained in:
commit
8156c8437b
18 changed files with 404 additions and 81 deletions
|
@ -64,8 +64,13 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <gint/config.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// BFile has a different interface on CP-400, which is not exposed by gint
|
||||||
|
// because the standard API is always available.
|
||||||
|
#if !GINT_OS_CP
|
||||||
|
|
||||||
//---
|
//---
|
||||||
// Common file access functions
|
// Common file access functions
|
||||||
//---
|
//---
|
||||||
|
@ -308,6 +313,8 @@ int BFile_FindClose(int shandle);
|
||||||
/* BFile_Ext_Stat(): Stat an entry for type and size */
|
/* BFile_Ext_Stat(): Stat an entry for type and size */
|
||||||
int BFile_Ext_Stat(uint16_t const *path, int *type, int *size);
|
int BFile_Ext_Stat(uint16_t const *path, int *type, int *size);
|
||||||
|
|
||||||
|
#endif /* !GINT_OS_CP */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -23,6 +23,9 @@ void r61523_display_rect(
|
||||||
/* r61523_win_set(): Set the display window */
|
/* r61523_win_set(): Set the display window */
|
||||||
void r61523_win_set(int x1, int x2, int y1, int y2);
|
void r61523_win_set(int x1, int x2, int y1, int y2);
|
||||||
|
|
||||||
|
/* r61523_set_pixel(): Write a pixel directly to DD (slow) */
|
||||||
|
void r61523_set_pixel(int x, int y, int color);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
#include <gint/bfile.h>
|
#include <gint/bfile.h>
|
||||||
#include <gint/gint.h>
|
#include <gint/gint.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "bfilecp.h"
|
||||||
|
|
||||||
|
// TODO: BFile_Ext_Stat: Use native stat function on CP-400?
|
||||||
|
// Unlike find functions, it doesn't provide type, as per documented API at
|
||||||
|
// least, and stat really needs it. So for now I'm sticking to the find check.
|
||||||
int BFile_Ext_Stat(uint16_t const *path, int *type, int *size)
|
int BFile_Ext_Stat(uint16_t const *path, int *type, int *size)
|
||||||
{
|
{
|
||||||
int search_handle, rc;
|
int search_handle, rc;
|
||||||
|
|
121
src/fs/fugue/bfilecp.h
Normal file
121
src/fs/fugue/bfilecp.h
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
// CP version of the BFile interface, which is much closer to POSIX.
|
||||||
|
// Functions not available elsewhere that could be useful for optimization:
|
||||||
|
// fstat, getAddr
|
||||||
|
|
||||||
|
#ifndef GINT_FS_BFILECP_H
|
||||||
|
#define GINT_FS_BFILECP_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <gint/config.h>
|
||||||
|
|
||||||
|
// Only for CP, obviously.
|
||||||
|
#if GINT_OS_CP
|
||||||
|
|
||||||
|
#define BFileCP_ENOMEM -1
|
||||||
|
#define BFileCP_EINVAL -2
|
||||||
|
#define BFileCP_EDEVFAIL -3
|
||||||
|
#define BFileCP_EMOUNTED -4
|
||||||
|
#define BFileCP_EACCES -5
|
||||||
|
#define BFileCP_EBADFSID -6
|
||||||
|
#define BFileCP_ENOVOLUME -7
|
||||||
|
#define BFileCP_ENOPATH -8
|
||||||
|
#define BFileCP_EEXIST -9
|
||||||
|
#define BFileCP_ENAMETOOLONG -10
|
||||||
|
#define BFileCP_EOUTOFBOUND -11
|
||||||
|
#define BFileCP_EUNFORMAT -12
|
||||||
|
#define BFileCP_ENOSPC -13
|
||||||
|
#define BFileCP_ENOENT -14
|
||||||
|
#define BFileCP_EISDIRECTORY -15
|
||||||
|
#define BFileCP_ESHARE -16
|
||||||
|
#define BFileCP_EMFILE -17
|
||||||
|
#define BFileCP_EBADF -18
|
||||||
|
#define BFileCP_EEOF -19
|
||||||
|
#define BFileCP_ENOTEMPTY -20
|
||||||
|
#define BFileCP_ECLUSTERSIZEMISMATCH -40
|
||||||
|
#define BFileCP_ESYSTEM -99
|
||||||
|
|
||||||
|
#define BFile_ReadOnly 0x01
|
||||||
|
#define BFile_WriteOnly 0x02
|
||||||
|
#define BFile_ReadWrite (BFile_ReadOnly | BFile_WriteOnly)
|
||||||
|
#define BFile_CreateFlag 0x04
|
||||||
|
#define BFile_AppendFlag 0x10
|
||||||
|
|
||||||
|
int BFile_Open(const char *path, int flags);
|
||||||
|
|
||||||
|
int BFile_Read(int fd, void *buf, int size);
|
||||||
|
int BFile_Write(int fd, void const *buf, int size);
|
||||||
|
|
||||||
|
#define BFileCP_SEEK_SET 0
|
||||||
|
#define BFileCP_SEEK_CUR 1
|
||||||
|
#define BFileCP_SEEK_END 2
|
||||||
|
int BFile_Seek(int fd, int offset, int whence);
|
||||||
|
|
||||||
|
int BFile_Close(int fd);
|
||||||
|
|
||||||
|
int BFile_Remove(char const *path);
|
||||||
|
int BFile_Rename(char const *oldpath, char const *newpath);
|
||||||
|
int BFile_Mkdir(char const *path);
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Metadata API
|
||||||
|
//---
|
||||||
|
|
||||||
|
// Dates are bitfields { year-1980: 8; month-1-12: 4; day-1-31: 4; }
|
||||||
|
// Times are bitfields { hour: 5; minute: 6; seconds_div2: 5; }
|
||||||
|
struct BFile_Statbuf {
|
||||||
|
u32 _1;
|
||||||
|
u32 size; // file size in bytes
|
||||||
|
u16 creationDate;
|
||||||
|
u16 creationTime;
|
||||||
|
u16 lastModifiedDate;
|
||||||
|
u16 lastModifiedTime;
|
||||||
|
u16 _2;
|
||||||
|
u16 lastAccessDate;
|
||||||
|
};
|
||||||
|
|
||||||
|
int BFile_FStat(int fd, struct BFile_Statbuf *statbuf);
|
||||||
|
|
||||||
|
// For API compatibility with older models.
|
||||||
|
static inline int BFile_Size(int fd) {
|
||||||
|
struct BFile_Statbuf statbuf;
|
||||||
|
int rc = BFile_FStat(fd, &statbuf);
|
||||||
|
return (rc >= 0) ? (int)statbuf.size : rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int BFile_Stat(const char *path, struct BFile_Statbuf *statbuf);
|
||||||
|
|
||||||
|
// Same as legacy, uses find API.
|
||||||
|
int BFile_Ext_Stat(uint16_t const *path, int *type, int *size);
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Search API
|
||||||
|
//---
|
||||||
|
|
||||||
|
#define BFile_Type_File 1
|
||||||
|
#define BFile_Type_Directory 5
|
||||||
|
|
||||||
|
struct BFile_FileInfo {
|
||||||
|
u32 _1;
|
||||||
|
u16 type; /* 1=File, 5=Directory */
|
||||||
|
u16 _2;
|
||||||
|
u32 file_size; /* in bytes; 0 for folders */
|
||||||
|
u32 _3, _4;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Same as legacy.
|
||||||
|
int BFile_FindFirst(u16 const *pattern, int *shandle, u16 *foundfile,
|
||||||
|
struct BFile_FileInfo *fileinfo);
|
||||||
|
int BFile_FindNext(
|
||||||
|
int shandle, u16 *foundfile, struct BFile_FileInfo *fileinfo);
|
||||||
|
int BFile_FindClose(int shandle);
|
||||||
|
|
||||||
|
#endif /* GINT_OS_CP */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* GINT_FS_BFILECP_H */
|
|
@ -9,6 +9,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "fugue.h"
|
#include "fugue.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "bfilecp.h"
|
||||||
|
|
||||||
ssize_t fugue_read(void *data0, void *buf, size_t size)
|
ssize_t fugue_read(void *data0, void *buf, size_t size)
|
||||||
{
|
{
|
||||||
|
@ -22,7 +23,11 @@ ssize_t fugue_read(void *data0, void *buf, size_t size)
|
||||||
if(data->pos + (int)size > filesize)
|
if(data->pos + (int)size > filesize)
|
||||||
size = filesize - data->pos;
|
size = filesize - data->pos;
|
||||||
|
|
||||||
|
#if GINT_OS_CP
|
||||||
|
int rc = BFile_Read(fugue_fd, buf, size);
|
||||||
|
#else
|
||||||
int rc = BFile_Read(fugue_fd, buf, size, -1);
|
int rc = BFile_Read(fugue_fd, buf, size, -1);
|
||||||
|
#endif
|
||||||
if(rc < 0) {
|
if(rc < 0) {
|
||||||
errno = bfile_error_to_errno(rc);
|
errno = bfile_error_to_errno(rc);
|
||||||
size = -1;
|
size = -1;
|
||||||
|
@ -109,11 +114,26 @@ ssize_t fugue_write(void *data0, const void *buf, size_t size)
|
||||||
|
|
||||||
off_t fugue_lseek(void *data0, off_t offset, int whence)
|
off_t fugue_lseek(void *data0, off_t offset, int whence)
|
||||||
{
|
{
|
||||||
gint_world_enter(GINT_WORLD_OS);
|
|
||||||
|
|
||||||
fugue_fd_t *data = data0;
|
fugue_fd_t *data = data0;
|
||||||
int fugue_fd = data->fd;
|
int fugue_fd = data->fd;
|
||||||
|
|
||||||
|
// TODO: fugue_lseek: CP400 optimization with native whence?
|
||||||
|
#if GINT_OS_CP
|
||||||
|
whence = (whence == SEEK_SET) ? BFileCP_SEEK_SET :
|
||||||
|
(whence == SEEK_CUR) ? BFileCP_SEEK_CUR :
|
||||||
|
BFileCP_SEEK_END;
|
||||||
|
gint_world_enter(GINT_WORLD_OS);
|
||||||
|
int rc = BFile_Seek(fugue_fd, offset, whence);
|
||||||
|
if(rc < 0) {
|
||||||
|
errno = bfile_error_to_errno(rc);
|
||||||
|
rc = -1;
|
||||||
|
} else {
|
||||||
|
data->pos = rc;
|
||||||
|
}
|
||||||
|
gint_world_leave();
|
||||||
|
return rc;
|
||||||
|
#else
|
||||||
|
gint_world_enter(GINT_WORLD_OS);
|
||||||
int filesize = BFile_Size(fugue_fd);
|
int filesize = BFile_Size(fugue_fd);
|
||||||
|
|
||||||
if(whence == SEEK_CUR)
|
if(whence == SEEK_CUR)
|
||||||
|
@ -138,6 +158,7 @@ off_t fugue_lseek(void *data0, off_t offset, int whence)
|
||||||
/* rc is the amount of space left in the file (including pre-allocated
|
/* rc is the amount of space left in the file (including pre-allocated
|
||||||
space), so instead just return offset directly */
|
space), so instead just return offset directly */
|
||||||
return offset;
|
return offset;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int fugue_close(void *data0)
|
int fugue_close(void *data0)
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "fugue.h"
|
#include "fugue.h"
|
||||||
|
#include "bfilecp.h"
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -119,7 +120,11 @@ void *fugue_dir_explore(char const *path)
|
||||||
|
|
||||||
rc = BFile_FindFirst(search, &sd, fc_path, &info);
|
rc = BFile_FindFirst(search, &sd, fc_path, &info);
|
||||||
if(rc < 0) {
|
if(rc < 0) {
|
||||||
|
#if GINT_OS_CP
|
||||||
|
if(rc != BFileCP_ENOENT) // BFileCP_EOUTOFBOUND?
|
||||||
|
#else
|
||||||
if(rc != BFile_EntryNotFound)
|
if(rc != BFile_EntryNotFound)
|
||||||
|
#endif
|
||||||
errno = bfile_error_to_errno(rc);
|
errno = bfile_error_to_errno(rc);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,24 @@
|
||||||
#include <gint/fs.h>
|
#include <gint/fs.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "bfilecp.h"
|
||||||
|
|
||||||
int fugue_mkdir(char const *path, GUNUSED mode_t mode)
|
int fugue_mkdir(char const *path, GUNUSED mode_t mode)
|
||||||
{
|
{
|
||||||
ENOTSUP_IF_NOT_FUGUE(-1);
|
ENOTSUP_IF_NOT_FUGUE(-1);
|
||||||
|
|
||||||
|
#if GINT_OS_CP
|
||||||
|
char *normpath = fs_path_normalize_opt(path, "\\fls0\\", '\\');
|
||||||
|
if(!normpath) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
gint_world_enter(GINT_WORLD_OS);
|
||||||
|
int rc = BFile_Mkdir(normpath);
|
||||||
|
gint_world_leave();
|
||||||
|
free(normpath);
|
||||||
|
#else
|
||||||
uint16_t *fcpath = fs_path_normalize_fc(path);
|
uint16_t *fcpath = fs_path_normalize_fc(path);
|
||||||
if(!fcpath) {
|
if(!fcpath) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
|
@ -17,15 +30,13 @@ int fugue_mkdir(char const *path, GUNUSED mode_t mode)
|
||||||
|
|
||||||
gint_world_enter(GINT_WORLD_OS);
|
gint_world_enter(GINT_WORLD_OS);
|
||||||
int rc = BFile_Create(fcpath, BFile_Folder, NULL);
|
int rc = BFile_Create(fcpath, BFile_Folder, NULL);
|
||||||
|
gint_world_leave();
|
||||||
|
free(fcpath);
|
||||||
|
#endif
|
||||||
|
|
||||||
if(rc < 0) {
|
if(rc < 0) {
|
||||||
errno = bfile_error_to_errno(rc);
|
errno = bfile_error_to_errno(rc);
|
||||||
free(fcpath);
|
return -1;
|
||||||
rc = -1;
|
|
||||||
} else {
|
|
||||||
rc = 0;
|
|
||||||
}
|
}
|
||||||
gint_world_leave();
|
|
||||||
|
|
||||||
free(fcpath);
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,32 +6,44 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "fugue.h"
|
#include "fugue.h"
|
||||||
|
#include "bfilecp.h"
|
||||||
|
|
||||||
static int new_file_size;
|
GUNUSED static int new_file_size;
|
||||||
|
|
||||||
int fugue_open(char const *path, int flags, GUNUSED mode_t mode)
|
int fugue_open(char const *path, int flags, GUNUSED mode_t mode)
|
||||||
{
|
{
|
||||||
ENOTSUP_IF_NOT_FUGUE(-1);
|
ENOTSUP_IF_NOT_FUGUE(-1);
|
||||||
|
|
||||||
uint16_t *fcpath = fs_path_normalize_fc(path);
|
uint16_t *fcpath = fs_path_normalize_fc(path);
|
||||||
int fugue_fd, err, rc=-1, type, fd=-1;
|
int fugue_fd, rc=-1, type, fd=-1;
|
||||||
|
|
||||||
if(!fcpath) {
|
if(!fcpath) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if GINT_OS_CP
|
||||||
|
char *normpath = fs_path_normalize_opt(path, "\\fls0\\", '\\');
|
||||||
|
if(!normpath) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
free(fcpath);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
# define NORMALIZED_PATH normpath
|
||||||
|
#else
|
||||||
|
# define NORMALIZED_PATH fcpath
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Open mode */
|
/* Open mode */
|
||||||
int bfile_mode = BFile_ReadOnly;
|
int bfile_mode = BFile_ReadOnly;
|
||||||
if(flags & O_WRONLY)
|
if(flags & O_WRONLY)
|
||||||
bfile_mode = BFile_WriteOnly;
|
bfile_mode = BFile_WriteOnly;
|
||||||
else if(flags & O_RDWR)
|
else if(flags & O_RDWR)
|
||||||
bfile_mode = BFile_ReadWrite;
|
bfile_mode = BFile_ReadWrite;
|
||||||
|
#if GINT_OS_CP
|
||||||
/* Exclusive open means no sense unless creation is also requested */
|
if(flags & O_APPEND)
|
||||||
bool excl = (flags & O_EXCL) && (flags & O_CREAT);
|
bfile_mode |= BFile_AppendFlag;
|
||||||
/* Truncation requires the file to be removed/recreated */
|
#endif
|
||||||
bool trunc = (flags & O_TRUNC) && (flags & O_CREAT);
|
|
||||||
|
|
||||||
gint_world_enter(GINT_WORLD_OS);
|
gint_world_enter(GINT_WORLD_OS);
|
||||||
|
|
||||||
|
@ -39,7 +51,11 @@ int fugue_open(char const *path, int flags, GUNUSED mode_t mode)
|
||||||
respond well. fs_path_normalize_fc() normalizes the path so we just
|
respond well. fs_path_normalize_fc() normalizes the path so we just
|
||||||
have to check for the fixed string "\\fls0\". */
|
have to check for the fixed string "\\fls0\". */
|
||||||
bool exists;
|
bool exists;
|
||||||
|
#if GINT_OS_CP
|
||||||
|
if(!memcmp(fcpath, u"\\fls0\\", 14)) {
|
||||||
|
#else
|
||||||
if(!memcmp(fcpath, u"\\\\fls0\\", 16)) {
|
if(!memcmp(fcpath, u"\\\\fls0\\", 16)) {
|
||||||
|
#endif
|
||||||
exists = true;
|
exists = true;
|
||||||
type = BFile_Type_Directory;
|
type = BFile_Type_Directory;
|
||||||
}
|
}
|
||||||
|
@ -48,8 +64,9 @@ int fugue_open(char const *path, int flags, GUNUSED mode_t mode)
|
||||||
if(!exists) type = -1;
|
if(!exists) type = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the entry exists and O_EXCL was requested, fail. */
|
/* O_EXCL: Succeed *only* if we're creating the file. Only has an
|
||||||
if(exists && excl) {
|
effect when combined with O_CREAT, unsurprisingly. */
|
||||||
|
if(exists && (flags & O_EXCL) && (flags & O_CREAT)) {
|
||||||
errno = EEXIST;
|
errno = EEXIST;
|
||||||
rc = -1;
|
rc = -1;
|
||||||
goto end;
|
goto end;
|
||||||
|
@ -79,48 +96,57 @@ int fugue_open(char const *path, int flags, GUNUSED mode_t mode)
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try and open the file normally, unless O_TRUNC is specified without
|
/* We now have a regular file. Before opening it, we may need to:
|
||||||
O_EXCL, in which case we simply delete and recreate the file. */
|
1. Delete it to truncate it (BFile never truncates AFAIK)
|
||||||
if(trunc)
|
- If O_TRUNC and the file exists (obviously).
|
||||||
fugue_fd = BFile_EntryNotFound;
|
- Deleting and recreating for truncation purposes is allowed when
|
||||||
else
|
not setting O_CREAT. In case of error midway, good luck.
|
||||||
fugue_fd = BFile_Open(fcpath, bfile_mode);
|
2. Create it (except fx-CP 400 which can create in BFile_Open())
|
||||||
|
- If it didn't exist and O_CREAT was allowed; or
|
||||||
|
- if it did exist but was removed for truncation in step 1.
|
||||||
|
3. Finally, open the file. */
|
||||||
|
|
||||||
/* If O_TRUNC is requested and either the file exists or we can create
|
/* Delete for truncation. */
|
||||||
it, remove it. (If fugue_fd < 0 an opening error might still have
|
if((flags & O_TRUNC) && exists) {
|
||||||
occurred so we delete it just in case.) */
|
BFile_Remove(NORMALIZED_PATH);
|
||||||
if((flags & O_TRUNC) && (fugue_fd >= 0 || (flags & O_CREAT))) {
|
/* Whatever happens now, allow recreating the file. */
|
||||||
if(fugue_fd >= 0)
|
exists = false;
|
||||||
BFile_Close(fugue_fd);
|
flags |= O_CREAT;
|
||||||
BFile_Remove(fcpath);
|
|
||||||
fugue_fd = BFile_EntryNotFound;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the file does not exist and O_CREAT is set, create it */
|
/* Create the file now, either directly with BFile_Create(), or with
|
||||||
if((flags & O_CREAT) && ((flags & O_TRUNC) || fugue_fd < 0)) {
|
the appropriate flag on fx-CP 400. */
|
||||||
new_file_size = 0;
|
if((flags & O_CREAT) && !exists) {
|
||||||
err = BFile_Create(fcpath, BFile_File, &new_file_size);
|
#if GINT_OS_CP
|
||||||
|
bfile_mode |= BFile_CreateFlag;
|
||||||
|
#else
|
||||||
|
int err = BFile_Create(fcpath, BFile_File, &new_file_size);
|
||||||
if(err < 0) {
|
if(err < 0) {
|
||||||
errno = bfile_error_to_errno(err);
|
errno = bfile_error_to_errno(err);
|
||||||
rc = -1;
|
rc = -1;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
fugue_fd = BFile_Open(fcpath, bfile_mode);
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Proceed with the final BFile_Open() call. */
|
||||||
|
fugue_fd = BFile_Open(NORMALIZED_PATH, bfile_mode);
|
||||||
|
|
||||||
if(fugue_fd < 0) {
|
if(fugue_fd < 0) {
|
||||||
errno = bfile_error_to_errno(fugue_fd);
|
errno = bfile_error_to_errno(fugue_fd);
|
||||||
rc = fugue_fd;
|
rc = -1;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If O_APPEND is set, move to the end of the file */
|
/* If O_APPEND is set, move to the end of the file */
|
||||||
// TODO: O_APPEND should move the cursor before *each* write
|
// TODO: O_APPEND should move the cursor before *each* write
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
#if !GINT_OS_CP
|
||||||
if((flags & O_APPEND)) {
|
if((flags & O_APPEND)) {
|
||||||
pos = BFile_Size(fugue_fd);
|
pos = BFile_Size(fugue_fd);
|
||||||
BFile_Seek(fugue_fd, pos);
|
BFile_Seek(fugue_fd, pos);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Return the now-open file descriptor */
|
/* Return the now-open file descriptor */
|
||||||
fugue_fd_t *data = malloc(sizeof *data);
|
fugue_fd_t *data = malloc(sizeof *data);
|
||||||
|
@ -146,6 +172,9 @@ int fugue_open(char const *path, int flags, GUNUSED mode_t mode)
|
||||||
|
|
||||||
end:
|
end:
|
||||||
gint_world_leave();
|
gint_world_leave();
|
||||||
|
#if GINT_OS_CP
|
||||||
|
free(normpath);
|
||||||
|
#endif
|
||||||
free(fcpath);
|
free(fcpath);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,38 +5,38 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "bfilecp.h"
|
||||||
|
|
||||||
int fugue_rename(char const *oldpath, char const *newpath)
|
int fugue_rename(char const *oldpath, char const *newpath)
|
||||||
{
|
{
|
||||||
ENOTSUP_IF_NOT_FUGUE(-1);
|
ENOTSUP_IF_NOT_FUGUE(-1);
|
||||||
int rc = -1;
|
|
||||||
|
|
||||||
uint16_t *fcpath_1 = NULL;
|
#if GINT_OS_CP
|
||||||
uint16_t *fcpath_2 = NULL;
|
gint_world_enter(GINT_WORLD_OS);
|
||||||
|
int rc = BFile_Rename(oldpath, newpath);
|
||||||
fcpath_1 = fs_path_normalize_fc(oldpath);
|
gint_world_leave();
|
||||||
|
#else
|
||||||
|
u16 *fcpath_1 = fs_path_normalize_fc(oldpath);
|
||||||
if(!fcpath_1) {
|
if(!fcpath_1) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
goto end;
|
return -1;
|
||||||
}
|
}
|
||||||
fcpath_2 = fs_path_normalize_fc(newpath);
|
u16 *fcpath_2 = fs_path_normalize_fc(newpath);
|
||||||
if(!fcpath_2) {
|
if(!fcpath_2) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
goto end;
|
free(fcpath_1);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
gint_world_enter(GINT_WORLD_OS);
|
gint_world_enter(GINT_WORLD_OS);
|
||||||
rc = BFile_Rename(fcpath_1, fcpath_2);
|
int rc = BFile_Rename(fcpath_1, fcpath_2);
|
||||||
if(rc < 0) {
|
|
||||||
errno = bfile_error_to_errno(rc);
|
|
||||||
rc = -1;
|
|
||||||
} else {
|
|
||||||
rc = 0;
|
|
||||||
}
|
|
||||||
gint_world_leave();
|
gint_world_leave();
|
||||||
|
|
||||||
end:
|
|
||||||
free(fcpath_1);
|
free(fcpath_1);
|
||||||
free(fcpath_2);
|
free(fcpath_2);
|
||||||
return rc;
|
#endif
|
||||||
|
|
||||||
|
if(rc < 0) {
|
||||||
|
errno = bfile_error_to_errno(rc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "fugue.h"
|
#include "fugue.h"
|
||||||
|
#include "bfilecp.h"
|
||||||
|
|
||||||
int fugue_rmdir(char const *path)
|
int fugue_rmdir(char const *path)
|
||||||
{
|
{
|
||||||
|
@ -34,6 +35,11 @@ int fugue_rmdir(char const *path)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if GINT_OS_CP
|
||||||
|
gint_world_enter(GINT_WORLD_OS);
|
||||||
|
int rc = BFile_Remove(path);
|
||||||
|
gint_world_leave();
|
||||||
|
#else
|
||||||
uint16_t *fcpath = fs_path_normalize_fc(path);
|
uint16_t *fcpath = fs_path_normalize_fc(path);
|
||||||
if(!fcpath) {
|
if(!fcpath) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
|
@ -42,14 +48,13 @@ int fugue_rmdir(char const *path)
|
||||||
|
|
||||||
gint_world_enter(GINT_WORLD_OS);
|
gint_world_enter(GINT_WORLD_OS);
|
||||||
int rc = BFile_Remove(fcpath);
|
int rc = BFile_Remove(fcpath);
|
||||||
|
gint_world_leave();
|
||||||
|
free(fcpath);
|
||||||
|
#endif
|
||||||
|
|
||||||
if(rc < 0) {
|
if(rc < 0) {
|
||||||
errno = bfile_error_to_errno(rc);
|
errno = bfile_error_to_errno(rc);
|
||||||
rc = -1;
|
return -1;
|
||||||
} else {
|
}
|
||||||
rc = 0;
|
return 0;
|
||||||
}
|
|
||||||
gint_world_leave();
|
|
||||||
|
|
||||||
free(fcpath);
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "bfilecp.h"
|
||||||
|
|
||||||
int fugue_stat(char const * restrict path, struct stat * restrict statbuf)
|
int fugue_stat(char const * restrict path, struct stat * restrict statbuf)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "bfilecp.h"
|
||||||
|
|
||||||
int fugue_unlink(char const *path)
|
int fugue_unlink(char const *path)
|
||||||
{
|
{
|
||||||
|
@ -16,6 +17,15 @@ int fugue_unlink(char const *path)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if GINT_OS_CP
|
||||||
|
char *normpath = fs_path_normalize_opt(path, "\\fls0\\", '\\');
|
||||||
|
if(!normpath) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
free(fcpath);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
gint_world_enter(GINT_WORLD_OS);
|
gint_world_enter(GINT_WORLD_OS);
|
||||||
|
|
||||||
int type, size, rc;
|
int type, size, rc;
|
||||||
|
@ -31,15 +41,23 @@ int fugue_unlink(char const *path)
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if GINT_OS_CP
|
||||||
|
rc = BFile_Remove(normpath);
|
||||||
|
#else
|
||||||
rc = BFile_Remove(fcpath);
|
rc = BFile_Remove(fcpath);
|
||||||
|
#endif
|
||||||
|
|
||||||
if(rc < 0) {
|
if(rc < 0) {
|
||||||
errno = bfile_error_to_errno(rc);
|
errno = bfile_error_to_errno(rc);
|
||||||
rc = -1;
|
rc = -1;
|
||||||
}
|
}
|
||||||
else rc = 0;
|
rc = 0;
|
||||||
|
|
||||||
end:
|
end:
|
||||||
gint_world_leave();
|
gint_world_leave();
|
||||||
free(fcpath);
|
free(fcpath);
|
||||||
|
#if GINT_OS_CP
|
||||||
|
free(normpath);
|
||||||
|
#endif
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "bfilecp.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -9,6 +10,33 @@
|
||||||
|
|
||||||
int bfile_error_to_errno(int e)
|
int bfile_error_to_errno(int e)
|
||||||
{
|
{
|
||||||
|
#if GINT_OS_CP
|
||||||
|
switch(e) {
|
||||||
|
case BFileCP_ENOMEM: return ENOENT;
|
||||||
|
case BFileCP_EINVAL: return EINVAL;
|
||||||
|
case BFileCP_EDEVFAIL: return EIO;
|
||||||
|
case BFileCP_EMOUNTED: return ENODEV;
|
||||||
|
case BFileCP_EACCES: return EACCES;
|
||||||
|
case BFileCP_EBADFSID: return ENODEV;
|
||||||
|
case BFileCP_ENOVOLUME: return ENODEV;
|
||||||
|
case BFileCP_ENOPATH: return ENOENT;
|
||||||
|
case BFileCP_EEXIST: return EEXIST;
|
||||||
|
case BFileCP_ENAMETOOLONG: return EINVAL;
|
||||||
|
case BFileCP_EOUTOFBOUND: return EINVAL;
|
||||||
|
case BFileCP_EUNFORMAT: return EINVAL;
|
||||||
|
case BFileCP_ENOSPC: return ENOSPC;
|
||||||
|
case BFileCP_ENOENT: return ENOENT;
|
||||||
|
case BFileCP_EISDIRECTORY: return EISDIR;
|
||||||
|
case BFileCP_ESHARE: return EINVAL;
|
||||||
|
case BFileCP_EMFILE: return EMFILE;
|
||||||
|
case BFileCP_EBADF: return EBADF;
|
||||||
|
case BFileCP_EEOF: return EINVAL;
|
||||||
|
case BFileCP_ENOTEMPTY: return EINVAL;
|
||||||
|
case BFileCP_ECLUSTERSIZEMISMATCH: return EINVAL;
|
||||||
|
case BFileCP_ESYSTEM: return EINVAL;
|
||||||
|
default: return errno;
|
||||||
|
}
|
||||||
|
#else
|
||||||
/* TODO: Find BFile code for too many fds and map it to ENFILE. */
|
/* TODO: Find BFile code for too many fds and map it to ENFILE. */
|
||||||
switch(e) {
|
switch(e) {
|
||||||
case BFile_EntryNotFound: return ENOENT;
|
case BFile_EntryNotFound: return ENOENT;
|
||||||
|
@ -26,20 +54,28 @@ int bfile_error_to_errno(int e)
|
||||||
case BFile_DeviceNotFound: return ENOENT;
|
case BFile_DeviceNotFound: return ENOENT;
|
||||||
default: return errno;
|
default: return errno;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int bfile_type_to_mode_t(int bfile_type)
|
int bfile_type_to_mode_t(int bfile_type)
|
||||||
{
|
{
|
||||||
|
#if GINT_OS_CP
|
||||||
|
return bfile_type == BFile_Type_Directory ? S_IFDIR : S_IFREG;
|
||||||
|
#else
|
||||||
switch(bfile_type) {
|
switch(bfile_type) {
|
||||||
case BFile_Type_Directory: return S_IFDIR;
|
case BFile_Type_Directory: return S_IFDIR;
|
||||||
case BFile_Type_Dot: return S_IFDIR;
|
case BFile_Type_Dot: return S_IFDIR;
|
||||||
case BFile_Type_DotDot: return S_IFDIR;
|
case BFile_Type_DotDot: return S_IFDIR;
|
||||||
default: return S_IFREG;
|
default: return S_IFREG;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int bfile_type_to_dirent(int bfile_type)
|
int bfile_type_to_dirent(int bfile_type)
|
||||||
{
|
{
|
||||||
|
#if GINT_OS_CP
|
||||||
|
return bfile_type == BFile_Type_Directory ? DT_DIR : DT_REG;
|
||||||
|
#else
|
||||||
switch(bfile_type) {
|
switch(bfile_type) {
|
||||||
case BFile_Type_Directory: return DT_DIR;
|
case BFile_Type_Directory: return DT_DIR;
|
||||||
case BFile_Type_Dot: return DT_DIR;
|
case BFile_Type_Dot: return DT_DIR;
|
||||||
|
@ -54,6 +90,7 @@ int bfile_type_to_dirent(int bfile_type)
|
||||||
case BFile_Type_Archived: return DT_REG;
|
case BFile_Type_Archived: return DT_REG;
|
||||||
default: return DT_UNKNOWN;
|
default: return DT_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Length of FONTCHARACTER and UTF-8 strings, counting only ASCII characters */
|
/* Length of FONTCHARACTER and UTF-8 strings, counting only ASCII characters */
|
||||||
|
@ -169,8 +206,12 @@ char **fs_split_components(char *path, int *count)
|
||||||
|
|
||||||
/* Generalization of fs_path_normalize(). Returns a [char *] if use_fc=false,
|
/* Generalization of fs_path_normalize(). Returns a [char *] if use_fc=false,
|
||||||
otherwise returns an [uint16_t *]. */
|
otherwise returns an [uint16_t *]. */
|
||||||
static void *path_normalize(char const *path, bool use_fc)
|
static void *path_normalize(
|
||||||
|
char const *path, bool use_fc, char const *prefix8, int dirsep)
|
||||||
{
|
{
|
||||||
|
if(!prefix8)
|
||||||
|
prefix8 = "/";
|
||||||
|
|
||||||
char *path_dup = strdup(path);
|
char *path_dup = strdup(path);
|
||||||
if(!path_dup) return NULL;
|
if(!path_dup) return NULL;
|
||||||
|
|
||||||
|
@ -194,7 +235,8 @@ static void *path_normalize(char const *path, bool use_fc)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Count total length */
|
/* Count total length */
|
||||||
int length = (use_fc ? 7 : 1) + (wr >= 1 ? wr - 1 : 0);
|
int prefix8_len = strlen(prefix8);
|
||||||
|
int length = (use_fc ? 7 : prefix8_len) + (wr >= 1 ? wr - 1 : 0);
|
||||||
for(int i = 0; i < wr; i++) {
|
for(int i = 0; i < wr; i++) {
|
||||||
length += utf8_len(comps[i]);
|
length += utf8_len(comps[i]);
|
||||||
}
|
}
|
||||||
|
@ -204,11 +246,16 @@ static void *path_normalize(char const *path, bool use_fc)
|
||||||
uint16_t *fc = malloc((length + 1) * sizeof *fc);
|
uint16_t *fc = malloc((length + 1) * sizeof *fc);
|
||||||
uint16_t *fc_init = fc;
|
uint16_t *fc_init = fc;
|
||||||
|
|
||||||
|
#if GINT_OS_CP
|
||||||
|
memcpy(fc, u"\\fls0\\", 6*2);
|
||||||
|
fc += 6;
|
||||||
|
#else
|
||||||
memcpy(fc, u"\\\\fls0\\", 7*2);
|
memcpy(fc, u"\\\\fls0\\", 7*2);
|
||||||
fc += 7;
|
fc += 7;
|
||||||
|
#endif
|
||||||
|
|
||||||
for(int i = 0; i < wr; i++) {
|
for(int i = 0; i < wr; i++) {
|
||||||
if(i > 0) *fc++ = '\\';
|
if(i > 0) *fc++ = dirsep;
|
||||||
utf8_to_fc(fc, comps[i], (size_t)-1);
|
utf8_to_fc(fc, comps[i], (size_t)-1);
|
||||||
fc += utf8_len(comps[i]);
|
fc += utf8_len(comps[i]);
|
||||||
}
|
}
|
||||||
|
@ -221,10 +268,11 @@ static void *path_normalize(char const *path, bool use_fc)
|
||||||
else {
|
else {
|
||||||
char *utf8 = malloc(length + 1);
|
char *utf8 = malloc(length + 1);
|
||||||
char *utf8_init = utf8;
|
char *utf8_init = utf8;
|
||||||
*utf8++ = '/';
|
memcpy(utf8, prefix8, prefix8_len);
|
||||||
|
utf8 += prefix8_len;
|
||||||
|
|
||||||
for(int i = 0; i < wr; i++) {
|
for(int i = 0; i < wr; i++) {
|
||||||
if(i > 0) *utf8++ = '/';
|
if(i > 0) *utf8++ = dirsep;
|
||||||
strcpy(utf8, comps[i]);
|
strcpy(utf8, comps[i]);
|
||||||
utf8 += utf8_len(comps[i]);
|
utf8 += utf8_len(comps[i]);
|
||||||
}
|
}
|
||||||
|
@ -236,12 +284,17 @@ static void *path_normalize(char const *path, bool use_fc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char *fs_path_normalize(char const *path)
|
char *fs_path_normalize(char const *path)
|
||||||
{
|
{
|
||||||
return path_normalize(path, false);
|
return path_normalize(path, false, NULL, '/');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *fs_path_normalize_opt(char const *path, char const *prefix, int dirsep)
|
||||||
|
{
|
||||||
|
return path_normalize(path, false, prefix, dirsep);
|
||||||
|
}
|
||||||
uint16_t *fs_path_normalize_fc(char const *path)
|
uint16_t *fs_path_normalize_fc(char const *path)
|
||||||
{
|
{
|
||||||
return path_normalize(path, true);
|
return path_normalize(path, true, NULL, '\\');
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,9 @@ uint16_t *utf8_to_fc_alloc(uint16_t *prefix, char const *utf8,
|
||||||
/* Same as fc_to_utf8() but allocates a string with malloc(). */
|
/* Same as fc_to_utf8() but allocates a string with malloc(). */
|
||||||
char *fc_to_utf8_alloc(uint16_t const *fc);
|
char *fc_to_utf8_alloc(uint16_t const *fc);
|
||||||
|
|
||||||
|
/* Same as fs_path_normalize() but with a prefix. If NULL, "/". */
|
||||||
|
char *fs_path_normalize_opt(char const *path, char const *prefix, int dirsep);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -19,6 +19,6 @@ ssize_t pread(int fd, void *buf, size_t size, off_t offset)
|
||||||
|
|
||||||
end:
|
end:
|
||||||
/* At the end, always try to restore the current position */
|
/* At the end, always try to restore the current position */
|
||||||
lseek(fd, current, SEEK_CUR);
|
lseek(fd, current, SEEK_SET);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,6 @@ ssize_t pwrite(int fd, const void *buf, size_t size, off_t offset)
|
||||||
|
|
||||||
end:
|
end:
|
||||||
/* At the end, always try to restore the current position */
|
/* At the end, always try to restore the current position */
|
||||||
lseek(fd, current, SEEK_CUR);
|
lseek(fd, current, SEEK_SET);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,8 @@
|
||||||
.global _BFile_FindFirst
|
.global _BFile_FindFirst
|
||||||
.global _BFile_FindNext
|
.global _BFile_FindNext
|
||||||
.global _BFile_FindClose
|
.global _BFile_FindClose
|
||||||
|
.global _BFile_FStat // fx-CP
|
||||||
|
.global _BFile_Mkdir // fx-CP
|
||||||
|
|
||||||
/* Return to menu */
|
/* Return to menu */
|
||||||
.global ___Timer_Install
|
.global ___Timer_Install
|
||||||
|
@ -289,13 +291,41 @@ ___VRAMRestore:
|
||||||
___Reset:
|
___Reset:
|
||||||
fixed(0xa0000000)
|
fixed(0xa0000000)
|
||||||
|
|
||||||
_BFile_Size:
|
|
||||||
_BFile_Read:
|
|
||||||
_BFile_Seek:
|
|
||||||
_BFile_Write:
|
|
||||||
_BFile_Close:
|
|
||||||
_BFile_FindFirst:
|
_BFile_FindFirst:
|
||||||
|
fixed(0x8005a2ac)
|
||||||
|
_BFile_FindNext:
|
||||||
|
fixed(0x8005a5f0)
|
||||||
_BFile_FindClose:
|
_BFile_FindClose:
|
||||||
fixed(0xa0000000)
|
fixed(0x8005a8ba)
|
||||||
|
_BFile_Remove:
|
||||||
|
fixed(0x80057fc8)
|
||||||
|
_BFile_Open:
|
||||||
|
fixed(0x80057f1c)
|
||||||
|
_BFile_Write:
|
||||||
|
fixed(0x80057f74)
|
||||||
|
_BFile_Close:
|
||||||
|
fixed(0x80057fa2)
|
||||||
|
_BFile_Read:
|
||||||
|
fixed(0x80057f46)
|
||||||
|
// _BFile_Flush:
|
||||||
|
// fixed(0x8005809a)
|
||||||
|
_BFile_Mkdir:
|
||||||
|
fixed(0x80057ef6)
|
||||||
|
// _BFile_Mount:
|
||||||
|
// fixed(0x80057e7c)
|
||||||
|
_BFile_Stat:
|
||||||
|
fixed(0x80057fee)
|
||||||
|
// _BFile_Reclaim:
|
||||||
|
// fixed(0x80058114)
|
||||||
|
// _BFile_FsInfo:
|
||||||
|
// fixed(0x800580ea)
|
||||||
|
// _BFile_Salvage:
|
||||||
|
// fixed(0x8005813e)
|
||||||
|
_BFile_Rename:
|
||||||
|
fixed(0x80058042)
|
||||||
|
_BFile_FStat:
|
||||||
|
fixed(0x80057fee)
|
||||||
|
_BFile_Seek:
|
||||||
|
fixed(0x8005806c)
|
||||||
|
|
||||||
#endif /* GINT_OS_CP */
|
#endif /* GINT_OS_CP */
|
||||||
|
|
|
@ -172,6 +172,18 @@ void r61523_display_rect(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void r61523_set_pixel(int x, int y, int color)
|
||||||
|
{
|
||||||
|
if((unsigned)x >= 320 || (unsigned)y >= 528)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// dma_transfer_wait(0);
|
||||||
|
r61523_win_set(x, x, y, y);
|
||||||
|
select(44);
|
||||||
|
uint16_t volatile *DISPLAY = (void *)0xb4000000;
|
||||||
|
*DISPLAY = color;
|
||||||
|
}
|
||||||
|
|
||||||
static bool r61523_update(int x, int y, image_t const *fb, int flags)
|
static bool r61523_update(int x, int y, image_t const *fb, int flags)
|
||||||
{
|
{
|
||||||
if(fb->format != IMAGE_RGB565)
|
if(fb->format != IMAGE_RGB565)
|
||||||
|
|
Loading…
Add table
Reference in a new issue