[WIP] support of 'build-fx-as-cg' targeting the conversion of fx9860g based code to fxCGs prizm #25
|
@ -245,8 +245,47 @@ set(SOURCES_CG
|
|||
src/render-cg/image/image_p4_dye.c
|
||||
)
|
||||
|
||||
set(ASSETS_FX src/font5x7.png)
|
||||
set(ASSETS_CG src/font8x9.png)
|
||||
set(SOURCES_FXASCG
|
||||
# Gray engine
|
||||
src/gray/gclear.c
|
||||
src/gray/ggetpixel.c
|
||||
src/gray/gint_gline.c
|
||||
src/gray/gpixel.c
|
||||
src/gray/grect.c
|
||||
src/gray/gsubimage.c
|
||||
src/gray/gtext.c
|
||||
# Rendering
|
||||
src/render-fx/bopti-asm-gray-scsp.s
|
||||
src/render-fx/bopti-asm-gray.s
|
||||
src/render-fx/bopti-asm-mono-scsp.s
|
||||
src/render-fx/bopti-asm.s
|
||||
src/render-fx/bopti.c
|
||||
src/render-fx/dclear.c
|
||||
src/render-fx/dgetpixel.c
|
||||
src/render-fx/dpixel.c
|
||||
src/render-fx/drect.c
|
||||
src/render-fx/dsubimage.c
|
||||
src/render-fx/gint_dline.c
|
||||
src/render-fx/masks.c
|
||||
src/render-fx/topti-asm.s
|
||||
src/render-fx/topti.c
|
||||
#special dupdate functions to treat a FX VRAM and convert to a CG VRAM
|
||||
src/render-fxascg/dupdate.c
|
||||
src/render-fxascg/engine_fxascg.c
|
||||
# R61524 driver as we are working with a CG50
|
||||
src/r61524/r61524.c
|
||||
|
||||
src/usb/classes/ff-bulk-gray.c
|
||||
)
|
||||
|
||||
set(ASSETS_FX
|
||||
src/font5x7.png
|
||||
)
|
||||
|
||||
set(ASSETS_CG
|
||||
src/font8x9.png
|
||||
)
|
||||
|
||||
fxconv_declare_assets(${ASSETS_FX} ${ASSETS_CG})
|
||||
|
||||
include_directories(
|
||||
|
@ -273,6 +312,17 @@ if("${FXSDK_PLATFORM_LONG}" STREQUAL fxCG50)
|
|||
${LINKER_SCRIPTS})
|
||||
endif()
|
||||
|
||||
if("${FXSDK_PLATFORM_LONG}" STREQUAL fx9860G_G3A)
|
||||
add_compile_options(-DFXCG50)
|
||||
add_compile_definitions(FX9860G_AS_CG)
|
||||
set(NAME "gint-fxg3a")
|
||||
set(LINKER_SCRIPTS
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/fxcg50.ld"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/fxcg50_fastload.ld")
|
||||
add_library(gint-fxg3a STATIC ${SOURCES_COMMON} ${SOURCES_FXASCG} ${ASSETS_FX}
|
||||
${LINKER_SCRIPTS})
|
||||
endif()
|
||||
|
||||
set_target_properties("${NAME}" PROPERTIES OUTPUT_NAME "${NAME}")
|
||||
|
||||
# Generate linker scripts
|
||||
|
|
20
README.md
20
README.md
|
@ -105,6 +105,22 @@ The available options are:
|
|||
% fxsdk build-cg install
|
||||
```
|
||||
|
||||
**"Cross-Building" a fx-9860G II project for fx-CG 50**
|
||||
|
||||
fx-9860G II sources can be automatically converted to run on fx-CG 50, provided no
|
||||
low level function/specific hardware manipulation/or syscall is used by the program.
|
||||
|
||||
The command is very similar to fx-9860G II one, except it is `fxsdk build-fx-as-cg`
|
||||
instead of `fxsdk build-fx`.
|
||||
|
||||
The available options are:
|
||||
|
||||
```
|
||||
% fxsdk build-fx-as-cg
|
||||
% fxsdk build-fx-as-cg install
|
||||
```
|
||||
|
||||
|
||||
## Using in CMake-based add-ins
|
||||
|
||||
Find the `Gint` module and link against `Gint::Gint`. gint declares the include
|
||||
|
@ -125,6 +141,10 @@ using the fxSDK, you will need to:
|
|||
* Link with `-T fx9860g.ld -lgint-fx -lopenlibm -lc` on fx-9860G;
|
||||
* Link with `-T fxcg50.ld -lgint-cg -lopenlibm -lc` on fx-CG 50.
|
||||
|
||||
Manually building a fx-9860G project to run on a fx-CG50 can be done :
|
||||
* Build with `-m4-nofpu -mb -DFXCG50 -DFX9860G_AS_CG`;
|
||||
* Link with `-T fxcg50.ld -lgint-fxascg -lopenlibm -lc`.
|
||||
|
||||
If you don't have a standard library such as
|
||||
[Memallox's port of newlib](/PlaneteCasio/libc), you also need `-nostdlib`. I
|
||||
typically use `-m3 -mb` or `-m4-nofpu -mb` to specify the platform, but that
|
||||
|
|
|
@ -7,6 +7,10 @@ elseif("${FXSDK_PLATFORM_LONG}" STREQUAL fx9860G)
|
|||
set(PC fx)
|
||||
set(INTF_DEFN FX9860G)
|
||||
set(INTF_LINK "-T;fx9860g.ld")
|
||||
elseif("${FXSDK_PLATFORM_LONG}" STREQUAL fx9860G_AS_CG)
|
||||
set(PC fxascg)
|
||||
set(INTF_DEFN FX9860G_AS_CG)
|
||||
set(INTF_LINK "-T;fxcg50.ld")
|
||||
else()
|
||||
message(FATAL_ERROR "gint: unknown fxSDK platform '${FXSDK_PLATFORM}'")
|
||||
endif()
|
||||
|
|
|
@ -5,14 +5,17 @@
|
|||
configure:
|
||||
@ fxsdk build-fx -c $(GINT_CMAKE_OPTIONS)
|
||||
@ fxsdk build-cg -c $(GINT_CMAKE_OPTIONS)
|
||||
@ fxsdk build-fx-as-cg -c $(GINT_CMAKE_OPTIONS)
|
||||
|
||||
build:
|
||||
@ fxsdk build-fx
|
||||
@ fxsdk build-cg
|
||||
@ fxsdk build-fx-as-cg
|
||||
|
||||
install:
|
||||
@ fxsdk build-fx install
|
||||
@ fxsdk build-cg install
|
||||
@ fxsdk build-fx-as-cg install
|
||||
|
||||
uninstall:
|
||||
@ if [ -e build-fx/install_manifest.txt ]; then \
|
||||
|
@ -21,5 +24,8 @@ uninstall:
|
|||
@ if [ -e build-cg/install_manifest.txt ]; then \
|
||||
xargs rm -f < build-cg/install_manifest.txt; \
|
||||
fi
|
||||
@ if [ -e build-fx-as-cg/install_manifest.txt ]; then \
|
||||
xargs rm -f < build-fxascg/install_manifest.txt; \
|
||||
fi
|
||||
|
||||
.PHONY: configure build install uninstall
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#if defined(FX9860G)
|
||||
# define GINT_HW_FX 1
|
||||
# define GINT_HW_CG 0
|
||||
#elif defined(FXCG50)
|
||||
#elif defined(FXCG50) || defined(FX9860G_AS_CG)
|
||||
# define GINT_HW_FX 0
|
||||
# define GINT_HW_CG 1
|
||||
#endif
|
||||
|
@ -57,6 +57,10 @@
|
|||
|
||||
/* GINT_RENDER_DMODE: Selects whether the dmode override is available on
|
||||
rendering functions. */
|
||||
#define GINT_RENDER_DMODE GINT_HW_FX
|
||||
#if defined(FX9860G_AS_CG)
|
||||
# define GINT_RENDER_DMODE 1
|
||||
#else
|
||||
# define GINT_RENDER_DMODE GINT_HW_FX
|
||||
#endif
|
||||
|
||||
#endif /* GINT_CONFIG */
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#ifndef GINT_DISPLAY_CG
|
||||
#define GINT_DISPLAY_CG
|
||||
|
||||
#ifdef FXCG50
|
||||
#if defined(FXCG50) && !defined(FX9860G_AS_CG)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#ifndef GINT_DISPLAY_FX
|
||||
#define GINT_DISPLAY_FX
|
||||
|
||||
#ifdef FX9860G
|
||||
#if defined(FX9860G) || defined(FX9860G_AS_CG)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
@ -19,11 +19,11 @@ extern "C" {
|
|||
/* Platform-specific functions include VRAM management and the definition of
|
||||
the color_t type. */
|
||||
|
||||
#ifdef FX9860G
|
||||
#if defined(FX9860G) || defined(FX9860G_AS_CG)
|
||||
#include <gint/display-fx.h>
|
||||
#endif
|
||||
|
||||
#ifdef FXCG50
|
||||
#if defined(FXCG50) && ! defined(FX9860G_AS_CG)
|
||||
#include <gint/display-cg.h>
|
||||
#endif
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
//---
|
||||
// Interrupt controllers
|
||||
//---
|
||||
|
||||
GRODATA3 sh7705_intc_t const SH7705_INTC = {
|
||||
.IPR = {
|
||||
(void *)0xfffffee2, (void *)0xfffffee4,
|
||||
|
|
|
@ -26,7 +26,7 @@ extern uint32_t
|
|||
lilram, silram, rilram, /* IL memory section */
|
||||
lxyram, sxyram, rxyram, /* X and Y memory section */
|
||||
sbss, rbss; /* User's BSS section */
|
||||
#ifdef FX9860G
|
||||
#if defined(FX9860G) && !defined(FX9860G_AS_CG)
|
||||
extern uint32_t
|
||||
lgmapped, sgmapped, /* Permanently mapped functions */
|
||||
lreloc, sreloc; /* Relocatable references */
|
||||
|
@ -136,7 +136,7 @@ static int start2(int isappli, int optnum)
|
|||
1.00 and the fx-9860G emulator) is not clear yet, so gint can't load
|
||||
pages dynamically. Load everything preventively (works only if the
|
||||
add-in is small enough) */
|
||||
#ifdef FX9860G
|
||||
#if defined(FX9860G) && !defined(FX9860G_AS_CG)
|
||||
if(isSH3())
|
||||
{
|
||||
/* Try to map every ROM address up to _srom */
|
||||
|
@ -159,7 +159,7 @@ static int start2(int isappli, int optnum)
|
|||
|
||||
gint_load_onchip_sections();
|
||||
|
||||
#ifdef FX9860G
|
||||
#if defined(FX9860G) && !defined(FX9860G_AS_CG)
|
||||
/* Copy permanently-mapped code to start of user RAM (on fx-CG 50 it
|
||||
is loaded along ILRAM contents) */
|
||||
void *rgmapped = mmu_uram();
|
||||
|
|
|
@ -9,9 +9,16 @@
|
|||
#include "topti-asm.h"
|
||||
|
||||
/* Default font */
|
||||
extern font_t gint_font8x9;
|
||||
font_t const * gint_default_font = &gint_font8x9;
|
||||
font_t const * topti_font = &gint_font8x9;
|
||||
#if(FX9860G_AS_CG)
|
||||
extern font_t gint_font5x7;
|
||||
font_t const * gint_default_font = &gint_font5x7;
|
||||
font_t const * topti_font = &gint_font5x7;
|
||||
#else
|
||||
extern font_t gint_font8x9;
|
||||
font_t const * gint_default_font = &gint_font8x9;
|
||||
font_t const * topti_font = &gint_font8x9;
|
||||
#endif
|
||||
|
||||
|
||||
/* topti_glyph(): Render a glyph on the VRAM
|
||||
Prints a glyph naively using word accesses, because for most fonts with a
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
#include <gint/display.h>
|
||||
#include <gint/kmalloc.h>
|
||||
#include <gint/config.h>
|
||||
#include <gint/drivers/r61524.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
|
||||
|
||||
/* Standard video RAM for fx9860g is 1 bit per pixel */
|
||||
GALIGNED(32) static uint32_t fx_vram[256];
|
||||
|
||||
/* Here is the definition of the VRAM pointer, exposed in <gint/display.h> */
|
||||
uint32_t *gint_vram = fx_vram;
|
||||
|
||||
/* The current rendering mode */
|
||||
struct rendering_mode const *dmode = NULL;
|
||||
|
||||
|
||||
bool dvram_init( void )
|
||||
{
|
||||
int const MARGIN = 32;
|
||||
|
||||
/* Leave MARGIN bytes on each side of the region; this enables some
|
||||
important optimizations in the image renderer. We also add another
|
||||
32 bytes so we can manually 32-align the region */
|
||||
uint32_t region = (uint32_t)kmalloc(DWIDTH*DHEIGHT*2 + MARGIN*2 + 32,
|
||||
#if !defined(GINT_NO_OS_STACK)
|
||||
"_ostk"
|
||||
#else
|
||||
NULL
|
||||
#endif
|
||||
);
|
||||
if(region == 0)
|
||||
return false;
|
||||
|
||||
/* 32-align the region */
|
||||
region = (region + 31) & -32;
|
||||
/* Skip a MARGIN */
|
||||
region += MARGIN;
|
||||
/* Use an uncached address */
|
||||
region = (region & 0x1fffffff) | 0xa0000000;
|
||||
|
||||
/* Don't enable triple buffering by default */
|
||||
cg_vram = (void *)region;
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void drawupscale( int x, int y, int color )
|
||||
{
|
||||
int u=y*396*3;
|
||||
int v=x*3;
|
||||
|
||||
uint16_t colorcg;
|
||||
|
||||
if (color==C_WHITE) colorcg=0xFFFF;
|
||||
else colorcg=0x0000;
|
||||
|
||||
int baseindex = (396*16+6+v+u); // 16 lines on top/bottom remain black and 6 columns on left/right remain black
|
||||
cg_vram[baseindex] = colorcg;
|
||||
cg_vram[baseindex+1] = colorcg;
|
||||
cg_vram[baseindex+2] = colorcg;
|
||||
|
||||
baseindex+=396;
|
||||
cg_vram[baseindex] = colorcg;
|
||||
cg_vram[baseindex+1] = colorcg;
|
||||
cg_vram[baseindex+2] = colorcg;
|
||||
|
||||
baseindex+=396;
|
||||
cg_vram[baseindex] = colorcg;
|
||||
cg_vram[baseindex+1] = colorcg;
|
||||
cg_vram[baseindex+2] = colorcg;
|
||||
}
|
||||
|
||||
/* dupdate(): Push the video RAM to the display driver */
|
||||
void dupdate(void)
|
||||
{
|
||||
bool run_default = true;
|
||||
|
||||
if(dmode && dmode->dupdate)
|
||||
{
|
||||
/* Call the overridden dupdate(), but continue if it returns
|
||||
non-zero (this is used when stopping the gray engine) */
|
||||
int rc = dmode->dupdate();
|
||||
run_default = (rc != 0);
|
||||
}
|
||||
|
||||
if(run_default)
|
||||
{
|
||||
for( int j=0; j<DHEIGHT; j++ ) // 64 lines
|
||||
{
|
||||
for( int i=0; i<DWIDTH; i++ ) // 128 column
|
||||
{
|
||||
drawupscale( i, j, dgetpixel(i,j) ); // really not optimised; just to check if OK
|
||||
}
|
||||
}
|
||||
|
||||
//draw a black layer around the screen
|
||||
int base1 = 0;
|
||||
int base2 = (64*3+16)*396;
|
||||
for(int u = 0; u<16; u++)
|
||||
{
|
||||
for(int v = 0; v<396; v++)
|
||||
{
|
||||
cg_vram[base1+v] = 0;
|
||||
cg_vram[base2+v] = 0;
|
||||
}
|
||||
base1+=396;
|
||||
base2+=396;
|
||||
}
|
||||
|
||||
base1 = 16*396;
|
||||
base2 = 16*396+6+128*3;
|
||||
for(int u = 0; u<64*3; u++)
|
||||
{
|
||||
for(int v = 0; v<6; v++)
|
||||
{
|
||||
cg_vram[base1+v] = 0;
|
||||
cg_vram[base2+v] = 0;
|
||||
}
|
||||
base1+=396;
|
||||
base2+=396;
|
||||
}
|
||||
|
||||
r61524_display(cg_vram, 0, 224, R61524_DMA_WAIT );
|
||||
}
|
||||
|
||||
gint_call(dupdate_get_hook());
|
||||
}
|
||||
__attribute__((alias("dupdate")))
|
||||
void _WEAK_dupdate(void);
|
|
@ -0,0 +1,342 @@
|
|||
//---
|
||||
// gint:gray:engine - Core gray engine
|
||||
//---
|
||||
|
||||
#include <gint/defs/types.h>
|
||||
#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
|
||||
at configure time, or with malloc() otherwise. */
|
||||
#ifdef GINT_STATIC_GRAY
|
||||
GBSS static uint32_t gvrams[1][256];
|
||||
#endif
|
||||
|
||||
uint16_t *cg_vram_gray;
|
||||
|
||||
/* two VRAMs: two to draw and two to display */
|
||||
static uint32_t *vrams[2] = { NULL, NULL };
|
||||
|
||||
/* Whether the engine is scheduled to run at the next frame */
|
||||
static int runs = 0;
|
||||
|
||||
extern struct rendering_mode const *dmode;
|
||||
|
||||
|
||||
/* The alternate rendering mode structure used to override d*() */
|
||||
static struct rendering_mode const gray_mode = {
|
||||
.dupdate = gupdate,
|
||||
.dclear = gclear,
|
||||
.drect = grect,
|
||||
.dpixel = gpixel,
|
||||
.dgetpixel = ggetpixel,
|
||||
.gint_dhline = gint_ghline,
|
||||
.gint_dvline = gint_gvline,
|
||||
.dtext_opt = gtext_opt,
|
||||
.dsubimage = gsubimage,
|
||||
};
|
||||
static struct rendering_mode const gray_exit_mode = {
|
||||
.dupdate = gupdate,
|
||||
.dclear = NULL,
|
||||
.drect = NULL,
|
||||
.dpixel = NULL,
|
||||
.dgetpixel = NULL,
|
||||
.gint_dhline = NULL,
|
||||
.gint_dvline = NULL,
|
||||
.dtext_opt = NULL,
|
||||
.dsubimage = NULL,
|
||||
};
|
||||
|
||||
//---
|
||||
// Engine control (init/quit and start/stop)
|
||||
//---
|
||||
|
||||
//static int gray_int(void);
|
||||
static void gray_quit(void);
|
||||
|
||||
/* gray_isinit(): Check whether the engine is initialized and ready to run */
|
||||
static int gray_isinit(void)
|
||||
{
|
||||
//return (vrams[0] && vrams[1] && vrams[2] && vrams[3] && timer >= 0);
|
||||
return (vrams[0] && vrams[1]);
|
||||
}
|
||||
|
||||
|
||||
bool dvram_init_gray( void )
|
||||
{
|
||||
int const MARGIN = 32;
|
||||
|
||||
/* Leave MARGIN bytes on each side of the region; this enables some
|
||||
important optimizations in the image renderer. We also add another
|
||||
32 bytes so we can manually 32-align the region */
|
||||
uint32_t region = (uint32_t)kmalloc(DWIDTH*DHEIGHT*2 + MARGIN*2 + 32,
|
||||
#if !defined(GINT_NO_OS_STACK)
|
||||
"_ostk"
|
||||
#else
|
||||
NULL
|
||||
#endif
|
||||
);
|
||||
if(region == 0)
|
||||
return false;
|
||||
|
||||
/* 32-align the region */
|
||||
region = (region + 31) & -32;
|
||||
/* Skip a MARGIN */
|
||||
region += MARGIN;
|
||||
/* Use an uncached address */
|
||||
region = (region & 0x1fffffff) | 0xa0000000;
|
||||
|
||||
/* Don't enable triple buffering by default */
|
||||
cg_vram_gray = (void *)region;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* gray_init(): Initialize the engine
|
||||
This is done at startup so that memory can be reserved very early from the
|
||||
heap (because not having enough memory is unrecoverable for the engine). */
|
||||
GCONSTRUCTOR static void gray_init(void)
|
||||
{
|
||||
/* We need four VRAMs. First use the standard monochrome one */
|
||||
vrams[0] = gint_vram;
|
||||
|
||||
#ifdef GINT_STATIC_GRAY
|
||||
vrams[1] = gvrams[0];
|
||||
#else
|
||||
vrams[1] = malloc(1024);
|
||||
#endif /* GINT_STATIC_GRAY */
|
||||
|
||||
dvram_init_gray();
|
||||
|
||||
/* On failure, release the resources that we obtained */
|
||||
if(!gray_isinit()) gray_quit();
|
||||
}
|
||||
|
||||
/* gray_quit(): Free engine resources */
|
||||
GDESTRUCTOR static void gray_quit(void)
|
||||
{
|
||||
#ifndef GINT_STATIC_GRAY
|
||||
if(vrams[1]) free(vrams[1]);
|
||||
vrams[1] = NULL;
|
||||
#endif /* GINT_STATIC_GRAY */
|
||||
}
|
||||
|
||||
/* gray_start(): Start the gray engine */
|
||||
static void gray_start(void)
|
||||
{
|
||||
runs = 1;
|
||||
}
|
||||
|
||||
/* gray_stop(): Stop the gray engine */
|
||||
static void gray_stop(void)
|
||||
{
|
||||
runs = 0;
|
||||
}
|
||||
|
||||
//---
|
||||
// Dynamic udpate and rendering mode
|
||||
//---
|
||||
|
||||
/* dgray(): Start or stop the gray engine at the next dupdate() */
|
||||
int dgray(int mode)
|
||||
{
|
||||
/* Stack of states for the push modes */
|
||||
static uint8_t states[32] = { 0 };
|
||||
static uint8_t current = 0;
|
||||
|
||||
if(mode == DGRAY_ON)
|
||||
{
|
||||
if(!gray_isinit()) return 1;
|
||||
|
||||
/* Set the display module's alternate rendering mode to
|
||||
override rendering functions to use their g*() variant */
|
||||
if(!dgray_enabled()) dmode = &gray_mode;
|
||||
}
|
||||
else if(mode == DGRAY_OFF)
|
||||
{
|
||||
/* Set the mode to a temporary one that only overrides
|
||||
dupdate() so that we can stop the engine next frame */
|
||||
if(dgray_enabled()) dmode = &gray_exit_mode;
|
||||
}
|
||||
else if(mode == DGRAY_PUSH_ON)
|
||||
{
|
||||
if(current >= 32) return 1;
|
||||
states[current++] = dgray_enabled() ? DGRAY_ON : DGRAY_OFF;
|
||||
|
||||
return dgray(DGRAY_ON);
|
||||
}
|
||||
else if(mode == DGRAY_PUSH_OFF)
|
||||
{
|
||||
if(current >= 32) return 1;
|
||||
states[current++] = dgray_enabled() ? DGRAY_ON : DGRAY_OFF;
|
||||
|
||||
return dgray(DGRAY_OFF);
|
||||
}
|
||||
else if(mode == DGRAY_POP)
|
||||
{
|
||||
/* Stay at 0 if the user's push/pop logic is broken */
|
||||
if(current > 0) current--;
|
||||
|
||||
/* Switch to previous state */
|
||||
return dgray(states[current]);
|
||||
}
|
||||
else return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* convert the gray scale into RGB565 and draw in the virutal VRAMthe 3x3 pixels upscaled and centered */
|
||||
void gdrawupscale( int x, int y, int color_fx )
|
||||
{
|
||||
int u=y*396*3;
|
||||
int v=x*3;
|
||||
|
||||
uint16_t color_cg;
|
||||
|
||||
if (color_fx==C_WHITE) color_cg=0xFFFF;
|
||||
else if (color_fx==C_LIGHT) color_cg=0xAD55;
|
||||
else if (color_fx==C_DARK) color_cg=0x528A;
|
||||
else color_cg=0x0000;
|
||||
|
||||
int baseindex = (396*16+6+v+u); // 16 lines on top/bottom remain black and 6 columns on left/right remain black
|
||||
cg_vram_gray[baseindex] = color_cg; // draw 3 pixels side by side
|
||||
cg_vram_gray[baseindex+1] = color_cg;
|
||||
cg_vram_gray[baseindex+2] = color_cg;
|
||||
|
||||
baseindex+=396; // same for the line below (line #2)
|
||||
cg_vram_gray[baseindex] = color_cg;
|
||||
cg_vram_gray[baseindex+1] = color_cg;
|
||||
cg_vram_gray[baseindex+2] = color_cg;
|
||||
|
||||
baseindex+=396; // same for the line below (line #3)
|
||||
cg_vram_gray[baseindex] = color_cg;
|
||||
cg_vram_gray[baseindex+1] = color_cg;
|
||||
cg_vram_gray[baseindex+2] = color_cg;
|
||||
}
|
||||
|
||||
|
||||
/* gray_int(): Interrupt handler */
|
||||
//int gray_int(void)
|
||||
//{
|
||||
// //t6k11_display(vrams[st ^ 2], 0, 64, 16);
|
||||
// timer_reload(GRAY_TIMER, delays[(st ^ 3) & 1]);
|
||||
//
|
||||
// st ^= 1;
|
||||
//
|
||||
// return TIMER_CONTINUE;
|
||||
//}
|
||||
|
||||
/* gupdate(): Push the current VRAMs to the screen */
|
||||
int gupdate(void)
|
||||
{
|
||||
/* At the first gupdate(), start the engine */
|
||||
if(dmode == &gray_mode && !runs)
|
||||
{
|
||||
gray_start();
|
||||
}
|
||||
/* At the last gupdate(), stop the engine */
|
||||
else if(dmode == &gray_exit_mode)
|
||||
{
|
||||
gray_stop();
|
||||
dmode = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
uint32_t *light, *dark;
|
||||
dgray_getscreen(&light, &dark);
|
||||
|
||||
for( int j=0; j<DHEIGHT; j++ ) // 64 lines
|
||||
{
|
||||
for( int i=0; i<DWIDTH; i++ ) // 128 column
|
||||
{
|
||||
int offset = (j << 2) + (i >> 5);
|
||||
uint32_t mask = 1 << (~i & 31);
|
||||
int l = (light[offset] & mask) !=0 ? 1 : 0;
|
||||
int d = (dark [offset] & mask) !=0 ? 1 : 0;
|
||||
|
||||
int color_fx = (d << 1) | l;
|
||||
|
||||
gdrawupscale( i, j, color_fx ); // really not optimised; just to check if OK
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//draw a black layer around the screen
|
||||
int base1 = 0;
|
||||
int base2 = (64*3+16)*396;
|
||||
for(int u = 0; u<16; u++)
|
||||
{
|
||||
for(int v = 0; v<396; v++)
|
||||
{
|
||||
cg_vram_gray[base1+v] = 0;
|
||||
cg_vram_gray[base2+v] = 0;
|
||||
}
|
||||
base1+=396;
|
||||
base2+=396;
|
||||
}
|
||||
|
||||
base1 = 16*396;
|
||||
base2 = 16*396+6+128*3;
|
||||
for(int u = 0; u<64*3; u++)
|
||||
{
|
||||
for(int v = 0; v<6; v++)
|
||||
{
|
||||
cg_vram_gray[base1+v] = 0;
|
||||
cg_vram_gray[base2+v] = 0;
|
||||
}
|
||||
base1+=396;
|
||||
base2+=396;
|
||||
}
|
||||
|
||||
r61524_display(cg_vram_gray, 0, 224, R61524_DMA_WAIT );
|
||||
|
||||
/* When the engine is running, swap frames */
|
||||
return 0;
|
||||
}
|
||||
|
||||
//---
|
||||
// Query and configuration functions
|
||||
//---
|
||||
|
||||
/* dgray_enabled(): Check whether gray mode is enabled */
|
||||
int dgray_enabled(void)
|
||||
{
|
||||
return (dmode == &gray_mode);
|
||||
}
|
||||
|
||||
/* dgray_setdelays(): Set the gray engine delays */
|
||||
void dgray_setdelays(uint32_t light, uint32_t dark)
|
||||
{
|
||||
// delays[0] = light;
|
||||
// delays[1] = dark;
|
||||
}
|
||||
|
||||
/* dgray_getdelays(): Get the gray engine delays */
|
||||
void dgray_getdelays(uint32_t *light, uint32_t *dark)
|
||||
{
|
||||
// if(light) *light = delays[0];
|
||||
// if(dark) *dark = delays[1];
|
||||
}
|
||||
|
||||
/* dgray_getvram(): Get the current VRAM pointers */
|
||||
void dgray_getvram(uint32_t **light, uint32_t **dark)
|
||||
{
|
||||
if(light) *light = vrams[0];
|
||||
if(dark) *dark = vrams[1];
|
||||
}
|
||||
|
||||
/* dgray_getscreen(): Get the current screen pointers */
|
||||
void dgray_getscreen(uint32_t **light, uint32_t **dark)
|
||||
{
|
||||
if(light) *light = vrams[0];
|
||||
if(dark) *dark = vrams[1];
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
#ifdef FX9860G
|
||||
#if defined(FX9860G) || defined(FX9860G_AS_CG)
|
||||
|
||||
#include <gint/usb.h>
|
||||
#include <gint/usb-ff-bulk.h>
|
||||
|
|
|
@ -104,12 +104,12 @@ static void capture_vram(GUNUSED bool onscreen, char const *type)
|
|||
void *source = gint_vram;
|
||||
int size, format;
|
||||
|
||||
#ifdef FX9860G
|
||||
#if defined(FX9860G) || defined(FX9860G_AS_CG)
|
||||
size = 1024;
|
||||
format = USB_FXLINK_IMAGE_MONO;
|
||||
#endif
|
||||
|
||||
#ifdef FXCG50
|
||||
#if defined(FXCG50) && !defined(FX9860G_AS_CG)
|
||||
if(onscreen) {
|
||||
uint16_t *main, *secondary;
|
||||
dgetvram(&main, &secondary);
|
||||
|
|
Loading…
Reference in New Issue