Compare commits
17 Commits
ddecd84081
...
3edb80018c
Author | SHA1 | Date |
---|---|---|
Lephe | 3edb80018c | |
Sylvain PILLOT | 2e5f99a996 | |
Sylvain PILLOT | f4e5b0f91c | |
Sylvain PILLOT | 9fdd203dbf | |
Sylvain PILLOT | 56fe0dd29c | |
Sylvain PILLOT | e5ca6c0fe5 | |
Sylvain PILLOT | 0f3c0ba803 | |
Sylvain PILLOT | dceaa2e9cf | |
Sylvain PILLOT | 87ccadecfd | |
Sylvain PILLOT | 836706b4dc | |
Sylvain PILLOT | ff587b6e90 | |
Sylvain PILLOT | e9ad4e2a79 | |
Lephe | b2b1f00d04 | |
Lephe | 5ff6a518f6 | |
Lephe | bc74586a2c | |
Lephenixnoir | e0ac25fbb0 | |
Sylvain PILLOT | b802e8edef |
|
@ -104,10 +104,10 @@ set(SOURCES_COMMON
|
|||
# Rendering
|
||||
src/render/dcircle.c
|
||||
src/render/dellipse.c
|
||||
src/render/dpoly.c
|
||||
src/render/dhline.c
|
||||
src/render/dimage.c
|
||||
src/render/dline.c
|
||||
src/render/dpoly.c
|
||||
src/render/dprint.c
|
||||
src/render/drect_border.c
|
||||
src/render/dtext.c
|
||||
|
@ -312,14 +312,14 @@ if("${FXSDK_PLATFORM_LONG}" STREQUAL fxCG50)
|
|||
${LINKER_SCRIPTS})
|
||||
endif()
|
||||
|
||||
if("${FXSDK_PLATFORM_LONG}" STREQUAL fx9860G_AS_CG)
|
||||
if("${FXSDK_PLATFORM_LONG}" STREQUAL fx9860G_G3A)
|
||||
add_compile_options(-DFXCG50)
|
||||
add_compile_definitions(FX9860G_AS_CG)
|
||||
set(NAME "gint-fxascg")
|
||||
set(NAME "gint-fxg3a")
|
||||
set(LINKER_SCRIPTS
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/fxcg50.ld"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/fxcg50_fastload.ld")
|
||||
add_library(gint-fxascg STATIC ${SOURCES_COMMON} ${SOURCES_FXASCG} ${ASSETS_FX}
|
||||
add_library(gint-fxg3a STATIC ${SOURCES_COMMON} ${SOURCES_FXASCG} ${ASSETS_FX}
|
||||
${LINKER_SCRIPTS})
|
||||
endif()
|
||||
|
||||
|
|
|
@ -16,6 +16,20 @@
|
|||
0x03f7c0a0 = Commit 3f7c0a0 */
|
||||
#define GINT_HASH 0x@GINT_GIT_HASH@
|
||||
|
||||
/* GINT_HW_{FX,CG}: Identifies the type of hardware running the program. */
|
||||
#if defined(FX9860G)
|
||||
# define GINT_HW_FX 1
|
||||
# define GINT_HW_CG 0
|
||||
#elif defined(FXCG50) || defined(FX9860G_AS_CG)
|
||||
# define GINT_HW_FX 0
|
||||
# define GINT_HW_CG 1
|
||||
#endif
|
||||
|
||||
/* GINT_OS_{FX,CG}: Identifies the type of OS API we're assuming. Currently I
|
||||
see no reason this would be different from hardware, but who knows. */
|
||||
#define GINT_OS_FX GINT_HW_FX
|
||||
#define GINT_OS_CG GINT_HW_CG
|
||||
|
||||
/* GINT_NO_OS_STACK: Disables using a chunk of the OS stack as a heap. The top
|
||||
section covering 355/512 ko is otherwise used. (fx-CG 50) */
|
||||
#cmakedefine GINT_NO_OS_STACK
|
||||
|
@ -41,4 +55,12 @@
|
|||
/* GINT_USB_DEBUG: Selects whether USB debug functions are enabled */
|
||||
#cmakedefine GINT_USB_DEBUG
|
||||
|
||||
/* GINT_RENDER_DMODE: Selects whether the dmode override is available on
|
||||
rendering functions. */
|
||||
#if defined(FX9860G_AS_CG)
|
||||
# define GINT_RENDER_DMODE 1
|
||||
#else
|
||||
# define GINT_RENDER_DMODE GINT_HW_FX
|
||||
#endif
|
||||
|
||||
#endif /* GINT_CONFIG */
|
||||
|
|
|
@ -15,9 +15,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include "attributes.h"
|
||||
|
||||
/* gint_call_arg_t: All types of arguments allowed in an indirect call
|
||||
|
||||
Because a function call cannot be easily pieced together, there are
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <gint/defs/call.h>
|
||||
#include <gint/defs/types.h>
|
||||
#include <gint/defs/call.h>
|
||||
|
||||
/* Platform-specific functions include VRAM management and the definition of
|
||||
the color_t type. */
|
||||
|
@ -23,7 +23,7 @@ extern "C" {
|
|||
#include <gint/display-fx.h>
|
||||
#endif
|
||||
|
||||
#if defined(FXCG50) && !defined(FX9860G_AS_CG)
|
||||
#if defined(FXCG50) && ! defined(FX9860G_AS_CG)
|
||||
#include <gint/display-cg.h>
|
||||
#endif
|
||||
|
||||
|
@ -90,8 +90,8 @@ gint_call_t dupdate_get_hook(void);
|
|||
to the rectangle spanning from (left,top) included, to (right,bottom)
|
||||
excluded. The default is from (0,0) to (DWIDTH,DHEIGHT). */
|
||||
struct dwindow {
|
||||
int left, top;
|
||||
int right, bottom;
|
||||
int left, top;
|
||||
int right, bottom;
|
||||
};
|
||||
extern struct dwindow dwindow;
|
||||
|
||||
|
@ -149,8 +149,8 @@ void drect(int x1, int y1, int x2, int y2, int color);
|
|||
@fill_color Center color (same values as drect() are allowed)
|
||||
@border_width Amount of pixels reserved for the border on each side
|
||||
@border_color Border color (same values as drect() are allowed) */
|
||||
void drect_border(int x1, int y1, int x2, int y2, int fill_color,
|
||||
int border_width, int border_color);
|
||||
void drect_border(int x1, int y1, int x2, int y2,
|
||||
int fill_color, int border_width, int border_color);
|
||||
|
||||
//---
|
||||
// Point drawing functions
|
||||
|
@ -241,78 +241,84 @@ void dcircle(int xm, int ym, int r, int fill_color, int border_color);
|
|||
@x1 @y1 @x2 @y2 Ellipse's bounding box (both bounds included, like drect())
|
||||
@fill_color Color of the surface inside the ellipse, C_NONE to disable
|
||||
@border_color Color of the ellipse itself, C_NONE to disable */
|
||||
void dellipse(int x1, int y1, int x2, int y2, int fill_color, int border_color);
|
||||
void dellipse(int x1, int y1, int x2, int y2, int fill_color,
|
||||
int border_color);
|
||||
|
||||
/* dpoly(): Polygone with border
|
||||
/* dpoly(): Render an arbitrary polygon
|
||||
|
||||
This function renders a closed-polygone defined by its vertices coordinates.
|
||||
Renders the polygon defined by vertices (x[i], y[i]) for 0 < i < N. A fill
|
||||
color and border color can be specified separately. For filling, N must be
|
||||
at least 3. For border, N must be at least 2.
|
||||
|
||||
@x @y Pointer to arrays containing the x / y coordinates of each
|
||||
individual vertex
|
||||
@nbvertices Number of vertices
|
||||
@fill_color Color of the surface inside the polygone, C_NONE to disable
|
||||
@border_color Color of the polygon itself, C_NONE to disable */
|
||||
void dpoly(int *x, int *y, int nbvertices, int fill_color, int border_color);
|
||||
Note: this is a fairly slow function, not designed for rendering triangles
|
||||
in 3D games. There are faster methods for that.
|
||||
|
||||
@x @y Arrays of vertex coordinates
|
||||
@N Number of vertices (length of x and y)
|
||||
@fill_color Color of the polygon's interior, C_NONE to disable
|
||||
@border_color Color of the polygon's border, C_NONE to disable */
|
||||
void dpoly(int const *x, int const *y, int N, int fill_color, int border_color);
|
||||
|
||||
//---
|
||||
// Text rendering (topti)
|
||||
//---
|
||||
|
||||
/* font_t: Font data encoded for topti */
|
||||
typedef struct {
|
||||
/* Font name (NUL-terminated), NULL if no title */
|
||||
char const *name;
|
||||
typedef struct
|
||||
{
|
||||
/* Font name (NUL-terminated), NULL if no title */
|
||||
char const *name;
|
||||
|
||||
/* Font shape flags */
|
||||
uint bold : 1;
|
||||
uint italic : 1;
|
||||
uint serif : 1;
|
||||
uint mono : 1;
|
||||
uint : 3;
|
||||
/* Whether data is variable-length (proportional font) */
|
||||
uint prop : 1;
|
||||
/* Font shape flags */
|
||||
uint bold :1;
|
||||
uint italic :1;
|
||||
uint serif :1;
|
||||
uint mono :1;
|
||||
uint :3;
|
||||
/* Whether data is variable-length (proportional font) */
|
||||
uint prop :1;
|
||||
|
||||
/* Line height */
|
||||
uint8_t line_height;
|
||||
/* Storage height */
|
||||
uint8_t data_height;
|
||||
/* Line height */
|
||||
uint8_t line_height;
|
||||
/* Storage height */
|
||||
uint8_t data_height;
|
||||
|
||||
/* Number of Unicode blocks */
|
||||
uint8_t block_count;
|
||||
/* Number of total glyphs */
|
||||
uint32_t glyph_count;
|
||||
/* Number of Unicode blocks */
|
||||
uint8_t block_count;
|
||||
/* Number of total glyphs */
|
||||
uint32_t glyph_count;
|
||||
|
||||
/* Character spacing (usually 1) */
|
||||
uint8_t char_spacing;
|
||||
/* Character spacing (usually 1) */
|
||||
uint8_t char_spacing;
|
||||
|
||||
uint : 24;
|
||||
uint :24;
|
||||
|
||||
struct {
|
||||
/* Unicode point of first character in block */
|
||||
uint start : 20;
|
||||
/* Length of block */
|
||||
uint length : 12;
|
||||
} * blocks;
|
||||
struct {
|
||||
/* Unicode point of first character in block */
|
||||
uint start :20;
|
||||
/* Length of block */
|
||||
uint length :12;
|
||||
} *blocks;
|
||||
|
||||
/* Raw glyph data */
|
||||
uint32_t *data;
|
||||
/* Raw glyph data */
|
||||
uint32_t *data;
|
||||
|
||||
union {
|
||||
/* For monospaced fonts */
|
||||
struct {
|
||||
/* Width of glyphs */
|
||||
uint16_t width;
|
||||
/* Storage size, in longwords, of each glyph */
|
||||
uint16_t storage_size;
|
||||
};
|
||||
/* For proportional fonts */
|
||||
struct {
|
||||
/* Storage index to find glyphs quickly */
|
||||
uint16_t *glyph_index;
|
||||
/* Width of each individual glyph */
|
||||
uint8_t *glyph_width;
|
||||
};
|
||||
};
|
||||
union {
|
||||
/* For monospaced fonts */
|
||||
struct {
|
||||
/* Width of glyphs */
|
||||
uint16_t width;
|
||||
/* Storage size, in longwords, of each glyph */
|
||||
uint16_t storage_size;
|
||||
};
|
||||
/* For proportional fonts */
|
||||
struct {
|
||||
/* Storage index to find glyphs quickly */
|
||||
uint16_t *glyph_index;
|
||||
/* Width of each individual glyph */
|
||||
uint8_t *glyph_width;
|
||||
};
|
||||
};
|
||||
|
||||
} GPACKED(4) font_t;
|
||||
|
||||
|
@ -390,14 +396,14 @@ char const *drsize(char const *str, font_t const *font, int width, int *w);
|
|||
and a horizontal alignment option specifies where a given point (x,y) should
|
||||
be relative to the rendered string. */
|
||||
enum {
|
||||
/* Horizontal settings: default in dtext() is DTEXT_LEFT */
|
||||
DTEXT_LEFT = 0,
|
||||
DTEXT_CENTER = 1,
|
||||
DTEXT_RIGHT = 2,
|
||||
/* Vertical settings: default in dtext() is DTEXT_TOP */
|
||||
DTEXT_TOP = 0,
|
||||
DTEXT_MIDDLE = 1,
|
||||
DTEXT_BOTTOM = 2,
|
||||
/* Horizontal settings: default in dtext() is DTEXT_LEFT */
|
||||
DTEXT_LEFT = 0,
|
||||
DTEXT_CENTER = 1,
|
||||
DTEXT_RIGHT = 2,
|
||||
/* Vertical settings: default in dtext() is DTEXT_TOP */
|
||||
DTEXT_TOP = 0,
|
||||
DTEXT_MIDDLE = 1,
|
||||
DTEXT_BOTTOM = 2,
|
||||
};
|
||||
|
||||
/* dtext_opt(): Display a string of text
|
||||
|
@ -428,13 +434,12 @@ enum {
|
|||
@str String to display
|
||||
@size Maximum number of bytes to display (negative for no limit) */
|
||||
void dtext_opt(int x, int y, int fg, int bg, int halign, int valign,
|
||||
char const *str, int size);
|
||||
char const *str, int size);
|
||||
|
||||
/* The last parameter @size was added in gint 2.4; this macro will add it
|
||||
automatically with a value of -1 if the call is made with only 7 parameters.
|
||||
This is for backwards compatibility. */
|
||||
#define dtext_opt8(x, y, fg, bg, h, v, str, sz, ...) \
|
||||
dtext_opt(x, y, fg, bg, h, v, str, sz)
|
||||
#define dtext_opt8(x,y,fg,bg,h,v,str,sz,...) dtext_opt(x,y,fg,bg,h,v,str,sz)
|
||||
#define dtext_opt(...) dtext_opt8(__VA_ARGS__, -1)
|
||||
|
||||
/* dtext(): Simple version of dtext_opt() with defaults
|
||||
|
@ -449,7 +454,7 @@ void dtext(int x, int y, int fg, char const *str);
|
|||
|
||||
dprint_opt(x, y, fg, bg, halign, valign, "A=%d B=%d", A, B); */
|
||||
void dprint_opt(int x, int y, int fg, int bg, int halign, int valign,
|
||||
char const *format, ...);
|
||||
char const *format, ...);
|
||||
|
||||
/* dprint(): Simple version of dprint_op() with defaults
|
||||
Calls dprint_opt() with bg=C_NONE, halign=DTEXT_LEFT and valign=DTEXT_TOP */
|
||||
|
@ -494,12 +499,12 @@ void dimage(int x, int y, bopti_image_t const *image);
|
|||
|
||||
/* Option values for dsubimage() */
|
||||
enum {
|
||||
/* No option */
|
||||
DIMAGE_NONE = 0x00,
|
||||
/* Disable clipping, ie. adjustments to the specified subrectangle and
|
||||
screen location such that any part that overflows from the image or
|
||||
the screen is ignored. Slightly faster. */
|
||||
DIMAGE_NOCLIP = 0x01,
|
||||
/* No option */
|
||||
DIMAGE_NONE = 0x00,
|
||||
/* Disable clipping, ie. adjustments to the specified subrectangle and
|
||||
screen location such that any part that overflows from the image or
|
||||
the screen is ignored. Slightly faster. */
|
||||
DIMAGE_NOCLIP = 0x01,
|
||||
};
|
||||
|
||||
/* dsubimage(): Render a section of an image
|
||||
|
@ -512,7 +517,7 @@ enum {
|
|||
@width @height Subrectangle dimensions
|
||||
@flags OR-combination of DIMAGE_* flags */
|
||||
void dsubimage(int x, int y, bopti_image_t const *image, int left, int top,
|
||||
int width, int height, int flags);
|
||||
int width, int height, int flags);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -158,7 +158,7 @@ typedef struct {
|
|||
int8_t queue_next;
|
||||
int8_t queue_end;
|
||||
/* Number of events lost because of missing queue space */
|
||||
uint events_lost;
|
||||
uint16_t events_lost;
|
||||
|
||||
/* Event transforms */
|
||||
keydev_transform_t tr;
|
||||
|
@ -183,9 +183,9 @@ typedef struct {
|
|||
// <Repeats>
|
||||
|
||||
/* Candidate key for repeats (or 0 if no key is candidate yet) */
|
||||
int rep_key;
|
||||
int16_t rep_key;
|
||||
/* Number of repeats already sent */
|
||||
int rep_count;
|
||||
int16_t rep_count;
|
||||
/* Time since key was first pressed (us) */
|
||||
int rep_time;
|
||||
/* Delay until next repeat, set by the repeat planner (us) */
|
||||
|
|
|
@ -78,7 +78,7 @@ void fs_free_descriptor(int fd);
|
|||
exact file descriptor reuse_fd is used. (This is useful to reopen standard
|
||||
streams.) In this case, the only possible return values are -1 and reuse_fd
|
||||
itself. */
|
||||
int open_generic(fs_descriptor_type_t *type, void *data, int reuse_fd);
|
||||
int open_generic(fs_descriptor_type_t const *type, void *data, int reuse_fd);
|
||||
|
||||
/* fs_path_normalize(): Normalize a path to eliminate ., .. and redundant /
|
||||
|
||||
|
|
|
@ -44,12 +44,6 @@ extern usb_interface_t const usb_ff_bulk;
|
|||
// Sending standard messages
|
||||
//---
|
||||
|
||||
/* usb_fxlink_text(): Send raw text
|
||||
Send a string; fxlink will display it in the terminal. This can be used to
|
||||
back stdout/stderr. Sending lots of small messages can be slow; if that's a
|
||||
problem, fill in message manually. If size is 0, uses strlen(text). */
|
||||
void usb_fxlink_text(char const *text, int size);
|
||||
|
||||
/* usb_fxlink_screenshot(): Take a screenshot
|
||||
|
||||
This function sends a copy of the VRAM to fxlink. This is best used just
|
||||
|
@ -63,6 +57,27 @@ void usb_fxlink_text(char const *text, int size);
|
|||
display (it's usually slow and currently not even implemented). */
|
||||
void usb_fxlink_screenshot(bool onscreen);
|
||||
|
||||
#if defined(FX9860G) || defined(FX9860G_AS_CG)
|
||||
/* usb_fxlink_screenshot_gray(): Take a gray screenshot on fx-9860G
|
||||
|
||||
This function is similar to usb_fxlink_screenshot(), but it takes a gray
|
||||
screenshot. It depends on the gray engine so if you use your add-in will
|
||||
automatically have the gray engine, that's why it's separate. */
|
||||
void usb_fxlink_screenshot_gray(bool onscreen);
|
||||
#endif
|
||||
|
||||
/* usb_fxlink_text(): Send raw text
|
||||
|
||||
This function sends a string with the "text" type, which fxlink prints on
|
||||
the terminal. It will send a full fxlink message (with a commit), which is
|
||||
inefficient if there is a lot of text to send. For better speed, send the
|
||||
message manually by filling the header and doing the writes and commit
|
||||
manually.
|
||||
|
||||
This function sends the text by blocks of 4 bytes or 2 bytes when alignment
|
||||
and size allow, and 1 byte otherwise. If size is 0, strlen(text) is used. */
|
||||
void usb_fxlink_text(char const *text, int size);
|
||||
|
||||
/* usb_fxlink_videocapture(): Send a frame for a video recording
|
||||
|
||||
This function is essentially the same as usb_fxlink_screenshot(). It sends a
|
||||
|
@ -74,12 +89,9 @@ void usb_fxlink_screenshot(bool onscreen);
|
|||
automatically send new frames to fxlink. */
|
||||
void usb_fxlink_videocapture(bool onscreen);
|
||||
|
||||
#ifdef FX9860G
|
||||
/* Similar to usb_fxlink_screenshot(), but takes a gray screenshot if the gray
|
||||
engine is currently running. */
|
||||
void usb_fxlink_screenshot_gray(bool onscreen);
|
||||
|
||||
/* Like usb_fxlink_videocapture(), but uses VRAM data from the gray engine. */
|
||||
#if defined(FX9860G) || defined(FX9860G_AS_CG)
|
||||
/* usb_fxlink_videocapture_gray(): Send a gray frame for a video recording
|
||||
Like usb_fxlink_videocapture(), but uses VRAM data from the gray engine. */
|
||||
void usb_fxlink_videocapture_gray(bool onscreen);
|
||||
#endif
|
||||
|
||||
|
@ -156,16 +168,17 @@ int usb_ff_bulk_input(void);
|
|||
The size of the data to be transferred must be specified upfront, but this
|
||||
restriction might be lifted in the future. As with the rest of the USB
|
||||
protocol, all the integer are encoded as *little-endian*. */
|
||||
typedef struct usb_fxlink_header {
|
||||
/* Protocol version = 0x00000100 */
|
||||
uint32_t version;
|
||||
/* Size of the data to transfer (excluding this header) */
|
||||
uint32_t size;
|
||||
/* Size of individual transfers (related to the size of the FIFO) */
|
||||
uint32_t transfer_size;
|
||||
/* Application name and message type, UTF-8 (need not be zero-terminated) */
|
||||
char application[16];
|
||||
char type[16];
|
||||
typedef struct usb_fxlink_header
|
||||
{
|
||||
/* Protocol version = 0x00000100 */
|
||||
uint32_t version;
|
||||
/* Size of the data to transfer (excluding this header) */
|
||||
uint32_t size;
|
||||
/* Size of individual transfers (related to the size of the FIFO) */
|
||||
uint32_t transfer_size;
|
||||
/* Application name and message type, UTF-8 (need not be zero-terminated) */
|
||||
char application[16];
|
||||
char type[16];
|
||||
|
||||
} usb_fxlink_header_t;
|
||||
|
||||
|
@ -175,88 +188,28 @@ typedef struct usb_fxlink_header {
|
|||
exact amount of data that the fxlink message will contain. Returns false if
|
||||
parameters are invalid or don't fit the fields. */
|
||||
bool usb_fxlink_fill_header(usb_fxlink_header_t *header,
|
||||
char const *application, char const *type,
|
||||
uint32_t data_size);
|
||||
char const *application, char const *type, uint32_t data_size);
|
||||
|
||||
/* Subheader for the fxlink built-in "image" type */
|
||||
typedef struct {
|
||||
/* Image size; storage is row-major */
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
/* Pixel format, see below */
|
||||
int pixel_format;
|
||||
typedef struct
|
||||
{
|
||||
/* Image size; storage is row-major */
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
/* Pixel format, see below */
|
||||
int pixel_format;
|
||||
|
||||
} usb_fxlink_image_t;
|
||||
|
||||
/* Pixel formats */
|
||||
enum {
|
||||
/* Image is an array of *big-endian* uint16_t with RGB565 format */
|
||||
USB_FXLINK_IMAGE_RGB565 = 0,
|
||||
/* Image is an array of bits in mono format */
|
||||
USB_FXLINK_IMAGE_MONO,
|
||||
/* Image is two consecutive mono arrays, one for light, one for dark */
|
||||
USB_FXLINK_IMAGE_GRAY,
|
||||
|
||||
} usb_fxlink_image_format_t;
|
||||
|
||||
/* usb_fxlink_screenshot(): Take a screenshot
|
||||
|
||||
This function takes a screenshot. If (onscreen = false), it sends the
|
||||
contents of the VRAM. This mode is best used just before dupdate(), since
|
||||
the VRAM contents are exactly as they will appear on screen a moment later.
|
||||
However, this is somewhat unintuitive for interactive GUI as the user has to
|
||||
press a button after the option is present on-screen, therefore the contents
|
||||
of the *next* frame are captured.
|
||||
|
||||
If (onscreen = true), this function tries to send the pixels that are
|
||||
currently visible on-screen, with the following heuristic:
|
||||
|
||||
* If there is only one VRAM, the VRAM contents are used in the hope they
|
||||
haven't changed since the last frame was presented with dupdate().
|
||||
* If there are two VRAMs (on fx-CG 50 or using the gray engine) the contents
|
||||
of the VRAM not currently being draw to are sent.
|
||||
|
||||
This function does not read pixels directly from the display, as this is
|
||||
usually slow and currently not even implemented. */
|
||||
void usb_fxlink_screenshot(bool onscreen);
|
||||
|
||||
#ifdef FX9860G
|
||||
/* usb_fxlink_screenshot_gray(): Take a gray screenshot on fx-9860G
|
||||
|
||||
This function is similar to usb_fxlink_screenshot(), but it takes a gray
|
||||
screenshot. It depends on the gray engine so if you use your add-in will
|
||||
automatically have the gray engine, that's why it's separate. */
|
||||
void usb_fxlink_screenshot_gray(bool onscreen);
|
||||
#endif
|
||||
|
||||
/* usb_fxlink_text(): Send raw text
|
||||
|
||||
This function sends a string with the "text" type, which fxlink prints on
|
||||
the terminal. It will send a full fxlink message (with a commit), which is
|
||||
inefficient if there is a lot of text to send. For better speed, send the
|
||||
message manually by filling the header and doing the writes and commit
|
||||
manually.
|
||||
|
||||
This function sends the text by blocks of 4 bytes or 2 bytes when alignment
|
||||
and size allow, and 1 byte otherwise. If size is 0, strlen(text) is used. */
|
||||
void usb_fxlink_text(char const *text, int size);
|
||||
|
||||
/* usb_fxlink_videocapture(): Send a frame for a video recording
|
||||
|
||||
This function is essentially the same as usb_fxlink_screenshot(). It sends a
|
||||
capture of the VRAM to fxlink but uses the "video" type, which fxlink
|
||||
displays in real-time or saves as a video file. The meaning of the onscreen
|
||||
setting is identical to usb_fxlink_screenshot().
|
||||
|
||||
This function can be called with onscreen=false as a dupdate() hook to
|
||||
automatically send new frames to fxlink. */
|
||||
void usb_fxlink_videocapture(bool onscreen);
|
||||
|
||||
#ifdef FX9860G
|
||||
/* usb_fxlink_videocapture_gray(): Send a gray frame for a video recording
|
||||
Like usb_fxlink_videocapture(), but uses VRAM data from the gray engine. */
|
||||
void usb_fxlink_videocapture_gray(bool onscreen);
|
||||
#endif
|
||||
/* Image is an array of *big-endian* uint16_t with RGB565 format */
|
||||
USB_FXLINK_IMAGE_RGB565 = 0,
|
||||
/* Image is an array of bits in mono format */
|
||||
USB_FXLINK_IMAGE_MONO,
|
||||
/* Image is two consecutive mono arrays, one for light, one for dark */
|
||||
USB_FXLINK_IMAGE_GRAY,
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ void fs_free_descriptor(int fd)
|
|||
fdtable[fd].data = NULL;
|
||||
}
|
||||
|
||||
int open_generic(fs_descriptor_type_t *type, void *data, int fd)
|
||||
int open_generic(fs_descriptor_type_t const *type, void *data, int fd)
|
||||
{
|
||||
if(!fdtable) {
|
||||
errno = ENOMEM;
|
||||
|
@ -79,7 +79,7 @@ int open_generic(fs_descriptor_type_t *type, void *data, int fd)
|
|||
|
||||
/* Standard streams */
|
||||
|
||||
static fs_descriptor_type_t devnull = {
|
||||
static fs_descriptor_type_t const devnull = {
|
||||
.read = NULL,
|
||||
.write = NULL,
|
||||
.lseek = NULL,
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "../render-fx/render-fx.h"
|
||||
#include "../render/render.h"
|
||||
|
||||
/* Three additional video RAMS, allocated statically if --static-gray was set
|
||||
at configure time, or with malloc() otherwise. */
|
||||
|
|
|
@ -40,19 +40,19 @@ extern void (*bdtors)(void), (*edtors)(void);
|
|||
int main(int isappli, int optnum);
|
||||
|
||||
/* Whether to restart main through the OS menu rather than returning */
|
||||
int gint_restart = 0;
|
||||
int8_t gint_restart = 0;
|
||||
|
||||
/* gint_setrestart(): Set whether to restart the add-in after exiting */
|
||||
void gint_setrestart(int restart)
|
||||
{
|
||||
gint_restart = restart;
|
||||
gint_restart = !!restart;
|
||||
}
|
||||
|
||||
/* Return value of main() */
|
||||
static int8_t gint_exitcode;
|
||||
/* Jumping there will properly unwind and leave the add-in (CASIOWIN does not
|
||||
have an exit syscall and simply wants you to return from main()) */
|
||||
jmp_buf gint_exitbuf;
|
||||
/* Return value of main() */
|
||||
static int gint_exitcode;
|
||||
|
||||
/* regcpy(): Copy a memory region using symbol information
|
||||
@l Source pointer (load address)
|
||||
|
|
|
@ -17,18 +17,18 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Keyboard input device for this Key Scan Interface */
|
||||
static keydev_t keysc_dev;
|
||||
/* Keyboard scanner timer */
|
||||
int16_t keysc_tid = -1;
|
||||
|
||||
/* Keyboard scan frequency in Hertz. Start with 128 Hz, this frequency *must
|
||||
be high* for the keyboard to work! Reading at low frequencies produces a lot
|
||||
of artifacts. See https://www.casiopeia.net/forum/viewtopic.php?p=20592. */
|
||||
int keysc_scan_Hz = 128;
|
||||
int16_t keysc_scan_Hz = 128;
|
||||
/* Approximation in microseconds, used by the timer and repeat delays */
|
||||
uint32_t keysc_scan_us = 7812; /* 1000000 / keysc_scan_Hz */
|
||||
|
||||
/* Keyboard scanner timer */
|
||||
int keysc_tid = -1;
|
||||
/* Keyboard input device for this Key Scan Interface */
|
||||
static keydev_t keysc_dev;
|
||||
|
||||
/* keydev_std(): Standard keyboard input device */
|
||||
keydev_t *keydev_std(void)
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <gint/display.h>
|
||||
#include "render-fx.h"
|
||||
#include "../render/render.h"
|
||||
|
||||
/* dclear() - fill the screen with a single color */
|
||||
void dclear(color_t color)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include <gint/display.h>
|
||||
#include <gint/defs/types.h>
|
||||
#include "render-fx.h"
|
||||
#include "../render/render.h"
|
||||
|
||||
int dgetpixel(int x, int y)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include <gint/display.h>
|
||||
#include <gint/defs/types.h>
|
||||
#include "render-fx.h"
|
||||
#include "../render/render.h"
|
||||
|
||||
/* dpixel() - change a pixel's color */
|
||||
void dpixel(int x, int y, int color)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <gint/defs/util.h>
|
||||
#include <gint/display.h>
|
||||
#include "../render/render.h"
|
||||
#include "render-fx.h"
|
||||
|
||||
void drect(int x1, int y1, int x2, int y2, int color)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <gint/display.h>
|
||||
#include "../render/render.h"
|
||||
#include "render-fx.h"
|
||||
#include "bopti-asm.h"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include <gint/display.h>
|
||||
#include <gint/drivers/t6k11.h>
|
||||
#include "render-fx.h"
|
||||
#include "../render/render.h"
|
||||
|
||||
/* Standard video RAM for fx9860g is 1 bit per pixel */
|
||||
GSECTION(".bss") GALIGNED(32) static uint32_t fx_vram[256];
|
||||
|
|
|
@ -50,38 +50,10 @@ void bopti_render_scsp(bopti_image_t const *img, struct rbox *rbox,
|
|||
uint32_t *v1, uint32_t *v2);
|
||||
|
||||
//---
|
||||
// Alternate rendering modes
|
||||
// Gray rendering functions for dmode
|
||||
//---
|
||||
|
||||
/* The gray engine overrides the rendering functions by specifying a set of
|
||||
alternate primitives that are suited to work with two VRAMs. To avoid
|
||||
linking with them when the gray engine is not used, the display module
|
||||
exposes a global state in the form of a struct rendering_mode and the gray
|
||||
engine modifies that state when it runs. */
|
||||
struct rendering_mode
|
||||
{
|
||||
/* Because the gray engine still has business to do after the call to
|
||||
dgray(DGRAY_OFF), the original dupdate() is made to execute after
|
||||
the replacement one if the replacement one returns 1. */
|
||||
int (*dupdate)(void);
|
||||
/* Area rendering */
|
||||
void (*dclear)(color_t color);
|
||||
void (*drect)(int x1, int y1, int x2, int y2, color_t color);
|
||||
/* Point rendering */
|
||||
void (*dpixel)(int x, int y, color_t color);
|
||||
int (*dgetpixel)(int x, int y);
|
||||
void (*gint_dhline)(int x1, int x2, int y, int color);
|
||||
void (*gint_dvline)(int y1, int y2, int x, int color);
|
||||
/* Text and image rendering */
|
||||
void (*dtext_opt)
|
||||
(int x, int y, int fg, int bg, int halign, int valign,
|
||||
char const *str, int size);
|
||||
void (*dsubimage)
|
||||
(bopti_image_t const *image, struct rbox *r, int flags);
|
||||
};
|
||||
|
||||
/* The alternate rendering mode pointer (initially NULL)*/
|
||||
extern struct rendering_mode const *dmode;
|
||||
struct rbox;
|
||||
|
||||
/* These are the corresponding gray rendering functions */
|
||||
int gupdate(void);
|
||||
|
@ -95,9 +67,4 @@ void gtext_opt(int x, int y, int fg, int bg, int halign, int valign,
|
|||
char const *str, int size);
|
||||
void gsubimage(bopti_image_t const *image, struct rbox *r, int flags);
|
||||
|
||||
/* Short macro to call the alternate rendering function when available */
|
||||
#define DMODE_OVERRIDE(func, ...) \
|
||||
if(dmode && dmode->func) { \
|
||||
return dmode->func(__VA_ARGS__); \
|
||||
}
|
||||
#endif /* RENDER_FX */
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include <gint/kmalloc.h>
|
||||
#include <gint/config.h>
|
||||
#include <gint/drivers/r61524.h>
|
||||
#include "../render-fx/render-fx.h"
|
||||
#include "../render/render.h"
|
||||
|
||||
/* The destination VRAM for upscaling + centering + conversion B&W --> 16bits RGB565 */
|
||||
uint16_t *cg_vram; // set to 0 at initialisation
|
||||
|
@ -48,11 +48,11 @@ bool dvram_init( void )
|
|||
|
||||
void dgetvram(uint16_t **ptr_vram_1, uint16_t **ptr_vram_2)
|
||||
{
|
||||
if(ptr_vram_1) *ptr_vram_1 = &cg_vram;
|
||||
if(ptr_vram_2) *ptr_vram_2 = &cg_vram;
|
||||
if(ptr_vram_1) *ptr_vram_1 = cg_vram;
|
||||
if(ptr_vram_2) *ptr_vram_2 = cg_vram;
|
||||
}
|
||||
|
||||
inline drawupscale( int x, int y, int color )
|
||||
void drawupscale( int x, int y, int color )
|
||||
{
|
||||
int u=y*396*3;
|
||||
int v=x*3;
|
||||
|
@ -134,4 +134,4 @@ void dupdate(void)
|
|||
gint_call(dupdate_get_hook());
|
||||
}
|
||||
__attribute__((alias("dupdate")))
|
||||
void _WEAK_dupdate(void);
|
||||
void _WEAK_dupdate(void);
|
||||
|
|
|
@ -6,9 +6,11 @@
|
|||
#include <gint/drivers/r61524.h>
|
||||
#include <gint/gray.h>
|
||||
#include <gint/display.h>
|
||||
#include <gint/kmalloc.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../render/render.h"
|
||||
#include "../render-fx/render-fx.h"
|
||||
|
||||
/* Three additional video RAMS, allocated statically if --static-gray was set
|
||||
|
@ -63,7 +65,7 @@ static void gray_quit(void);
|
|||
static int gray_isinit(void)
|
||||
{
|
||||
//return (vrams[0] && vrams[1] && vrams[2] && vrams[3] && timer >= 0);
|
||||
return (vrams[0] && vrams[1] >= 0);
|
||||
return (vrams[0] && vrams[1]);
|
||||
}
|
||||
|
||||
|
||||
|
@ -192,7 +194,7 @@ int dgray(int mode)
|
|||
}
|
||||
|
||||
/* convert the gray scale into RGB565 and draw in the virutal VRAMthe 3x3 pixels upscaled and centered */
|
||||
inline gdrawupscale( int x, int y, int color_fx )
|
||||
void gdrawupscale( int x, int y, int color_fx )
|
||||
{
|
||||
int u=y*396*3;
|
||||
int v=x*3;
|
||||
|
|
|
@ -2,9 +2,6 @@
|
|||
#include <gint/defs/util.h>
|
||||
|
||||
#include "../render/render.h"
|
||||
#if defined(FX9860G) || defined(FX9860G_AS_CG)
|
||||
#include "../render-fx/render-fx.h"
|
||||
#endif
|
||||
|
||||
/* dline(): Bresenham line drawing algorithm
|
||||
Remotely adapted from MonochromeLib code by Pierre "PerriotLL" Le Gall.
|
||||
|
@ -18,19 +15,13 @@ void dline(int x1, int y1, int x2, int y2, int color)
|
|||
/* Possible optimizations */
|
||||
if(y1 == y2)
|
||||
{
|
||||
#if defined(FX9860G) || defined(FX9860G_AS_CG)
|
||||
DMODE_OVERRIDE(gint_dhline, x1, x2, y1, color);
|
||||
#endif
|
||||
|
||||
gint_dhline(x1, x2, y1, color);
|
||||
return;
|
||||
}
|
||||
if(x1 == x2)
|
||||
{
|
||||
#if defined(FX9860G) || defined(FX9860G_AS_CG)
|
||||
DMODE_OVERRIDE(gint_dvline, y1, y2, x1, color);
|
||||
#endif
|
||||
|
||||
gint_dvline(y1, y2, x1, color);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,67 +1,67 @@
|
|||
#include <gint/defs/util.h>
|
||||
#include <gint/display.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void dpoly(int *polyX, int *polyY, int polyCorners, int fill_color, int border_color){
|
||||
static int compare(void const *ptr1, void const *ptr2)
|
||||
{
|
||||
return *(int const *)ptr1 - *(int const *)ptr2;
|
||||
}
|
||||
|
||||
if (polyCorners<=2) return;
|
||||
static void dpoly_fill(int const *x, int const *y, int N, int color)
|
||||
{
|
||||
int *nodeX = malloc(N * sizeof *nodeX);
|
||||
|
||||
if (fill_color == C_NONE && border_color == C_NONE)
|
||||
return;
|
||||
/* Find vertical bounds */
|
||||
int ymin = y[0], ymax = y[0];
|
||||
for(int i = 1; i < N; i++)
|
||||
{
|
||||
ymin = min(ymin, y[i]);
|
||||
ymax = max(ymax, y[i]);
|
||||
}
|
||||
ymin = max(ymin, dwindow.top);
|
||||
ymax = min(ymax, dwindow.bottom);
|
||||
|
||||
if (fill_color != C_NONE) {
|
||||
|
||||
float *nodeX, pixelX, pixelY, swap ;
|
||||
int i, j, nodes;
|
||||
|
||||
nodeX = malloc( polyCorners * sizeof(float));
|
||||
|
||||
// Loop through the rows of the image.
|
||||
for (pixelY=0; pixelY<DHEIGHT; pixelY++) {
|
||||
|
||||
// Build a list of nodes.
|
||||
nodes=0; j=polyCorners-1;
|
||||
for (i=0; i<polyCorners; i++) {
|
||||
if ((polyY[i]<(float) pixelY && polyY[j]>=(float) pixelY)
|
||||
|| (polyY[j]<(float) pixelY && polyY[i]>=(float) pixelY)) {
|
||||
nodeX[nodes++]=(int) (polyX[i]+(pixelY-polyY[i])/(polyY[j]-polyY[i])*(polyX[j]-polyX[i]));
|
||||
}
|
||||
j=i;
|
||||
}
|
||||
/* For each row, find vertical cuts from the segments and fill in-between
|
||||
the cuts. */
|
||||
for(int pixelY = ymin; pixelY <= ymax; pixelY++) {
|
||||
|
||||
// Sort the nodes, via a simple “Bubble” sort.
|
||||
i=0;
|
||||
while (i<nodes-1) {
|
||||
if (nodeX[i]>nodeX[i+1]) {
|
||||
swap=nodeX[i]; nodeX[i]=nodeX[i+1]; nodeX[i+1]=swap; if (i) i--;
|
||||
}
|
||||
else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
/* Build a list of nodes */
|
||||
int nodes = 0;
|
||||
int j = N - 1;
|
||||
for(int i = 0; i < N; i++)
|
||||
{
|
||||
if((y[i] < pixelY) != (y[j] < pixelY))
|
||||
nodeX[nodes++] = x[i]+(pixelY-y[i])*(x[j]-x[i])/(y[j]-y[i]);
|
||||
j = i;
|
||||
}
|
||||
|
||||
// Fill the pixels between node pairs.
|
||||
for (i=0; i<nodes; i+=2) {
|
||||
if (nodeX[i ]>=DWIDTH) break;
|
||||
if (nodeX[i+1]<= 0 ) break;
|
||||
if (nodeX[i ]< 0 ) nodeX[i ]=0 ;
|
||||
if (nodeX[i+1]> DWIDTH) nodeX[i+1]=DWIDTH;
|
||||
//for (pixelX=nodeX[i]; pixelX<nodeX[i+1]; pixelX++) fillPixel(pixelX,pixelY);
|
||||
dline(nodeX[i], pixelY, nodeX[i+1], pixelY, fill_color);
|
||||
}
|
||||
}
|
||||
/* Sort the cuts' positions */
|
||||
qsort(nodeX, nodes, sizeof nodeX[0], compare);
|
||||
|
||||
free(nodeX);
|
||||
}
|
||||
/* Fill the pixels between cut pairs */
|
||||
for(int i = 0; i < nodes; i += 2)
|
||||
{
|
||||
if(nodeX[i] >= dwindow.right || nodeX[i+1] < dwindow.left) break;
|
||||
nodeX[i] = max(nodeX[i], dwindow.left);
|
||||
nodeX[i+1] = min(nodeX[i+1], dwindow.right);
|
||||
dline(nodeX[i], pixelY, nodeX[i+1], pixelY, color);
|
||||
}
|
||||
}
|
||||
|
||||
if (border_color != C_NONE) {
|
||||
for (int i = 0; i < polyCorners; i++) {
|
||||
int px = polyX[i];
|
||||
int py = polyY[i];
|
||||
int px2 = polyX[(i + 1) % polyCorners];
|
||||
int py2 = polyY[(i + 1) % polyCorners];
|
||||
dline(px, py, px2, py2, border_color);
|
||||
}
|
||||
}
|
||||
free(nodeX);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
static void dpoly_border(int const *x, int const *y, int N, int color)
|
||||
{
|
||||
for(int i = 0; i < N - 1; i++)
|
||||
dline(x[i], y[i], x[i+1], y[i+1], color);
|
||||
dline(x[N-1], y[N-1], x[0], y[0], color);
|
||||
}
|
||||
|
||||
void dpoly(int const *x, int const *y, int N, int fill_color, int border_color)
|
||||
{
|
||||
if(N > 2 && fill_color != C_NONE)
|
||||
dpoly_fill(x, y, N, fill_color);
|
||||
if(N >= 2 && border_color != C_NONE)
|
||||
dpoly_border(x, y, N, border_color);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#ifndef RENDER_COMMON
|
||||
#define RENDER_COMMON
|
||||
|
||||
#include <gint/config.h>
|
||||
#include <gint/display.h>
|
||||
|
||||
/* gint_dhline(): Optimized horizontal line
|
||||
|
@ -26,4 +27,51 @@ extern font_t const *topti_font;
|
|||
/* Default font */
|
||||
extern font_t const *gint_default_font;
|
||||
|
||||
//---
|
||||
// Alternate rendering modes
|
||||
//---
|
||||
|
||||
#if GINT_RENDER_DMODE
|
||||
|
||||
/* The gray engine overrides the rendering functions by specifying a set of
|
||||
alternate primitives that are suited to work with two VRAMs. To avoid
|
||||
linking with them when the gray engine is not used, the display module
|
||||
exposes a global state in the form of a struct rendering_mode and the gray
|
||||
engine modifies that state when it runs. */
|
||||
struct rbox;
|
||||
struct rendering_mode
|
||||
{
|
||||
/* Because the gray engine still has business to do after the call to
|
||||
dgray(DGRAY_OFF), the original dupdate() is made to execute after
|
||||
the replacement one if the replacement one returns 1. */
|
||||
int (*dupdate)(void);
|
||||
/* Area rendering */
|
||||
void (*dclear)(color_t color);
|
||||
void (*drect)(int x1, int y1, int x2, int y2, color_t color);
|
||||
/* Point rendering */
|
||||
void (*dpixel)(int x, int y, color_t color);
|
||||
int (*dgetpixel)(int x, int y);
|
||||
void (*gint_dhline)(int x1, int x2, int y, int color);
|
||||
void (*gint_dvline)(int y1, int y2, int x, int color);
|
||||
/* Text and image rendering */
|
||||
void (*dtext_opt)
|
||||
(int x, int y, int fg, int bg, int halign, int valign,
|
||||
char const *str, int size);
|
||||
void (*dsubimage)
|
||||
(bopti_image_t const *image, struct rbox *r, int flags);
|
||||
};
|
||||
|
||||
/* The alternate rendering mode pointer (initially NULL)*/
|
||||
extern struct rendering_mode const *dmode;
|
||||
|
||||
/* Short macro to call the alternate rendering function when available */
|
||||
#define DMODE_OVERRIDE(func, ...) \
|
||||
if(dmode && dmode->func) { \
|
||||
return dmode->func(__VA_ARGS__); \
|
||||
}
|
||||
|
||||
#else
|
||||
#define DMODE_OVERRIDE(func, ...)
|
||||
#endif /* GINT_RENDER_DMODE */
|
||||
|
||||
#endif /* RENDER_COMMON */
|
||||
|
|
Loading…
Reference in New Issue