initial commit
|
@ -0,0 +1,14 @@
|
|||
# Build files
|
||||
/build-fx
|
||||
/build-cg
|
||||
/build-cg-push
|
||||
/*.g1a
|
||||
/*.g3a
|
||||
|
||||
# Python bytecode
|
||||
__pycache__/
|
||||
|
||||
# Common IDE files
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
.vscode
|
|
@ -0,0 +1,44 @@
|
|||
# Configure with [fxsdk build-fx] or [fxsdk build-cg], which provide the
|
||||
# toolchain file and module path of the fxSDK
|
||||
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
project(ScreenSaver VERSION 1.0 LANGUAGES CXX C ASM)
|
||||
|
||||
include(GenerateG3A)
|
||||
include(Fxconv)
|
||||
|
||||
find_package(Gint 2.9 REQUIRED)
|
||||
find_package(LibProf 2.4 REQUIRED)
|
||||
|
||||
|
||||
set(SOURCES
|
||||
src/main.cpp
|
||||
|
||||
src/utilities/fast_trig.cpp
|
||||
src/utilities/extrakeyboard.cpp
|
||||
src/utilities/utilities.cpp
|
||||
src/utilities/vector2D.cpp
|
||||
|
||||
src/effects/plasma.cpp
|
||||
src/effects/morph.cpp
|
||||
)
|
||||
|
||||
set(ASSETS_cg
|
||||
assets-cg/fontmatrix.png
|
||||
assets-cg/fontFantasy.png
|
||||
|
||||
assets-cg/SlyVTT.png
|
||||
assets-cg/Selection.png
|
||||
)
|
||||
|
||||
fxconv_declare_assets(${ASSETS_cg} WITH_METADATA)
|
||||
|
||||
add_executable(ssaver ${SOURCES} ${ASSETS} ${ASSETS_${FXSDK_PLATFORM}})
|
||||
target_compile_options(ssaver PRIVATE -Wall -Wextra -O3 -std=c++20)
|
||||
target_link_options(ssaver PRIVATE -Wl,-Map=Build_Addin.map -Wl,--print-memory-usage -fno-use-cxa-atexit -fpermissive)
|
||||
target_link_libraries(ssaver -lnum LibProf::LibProf Gint::Gint -lstdc++)
|
||||
|
||||
if("${FXSDK_PLATFORM_LONG}" STREQUAL fxCG50)
|
||||
generate_g3a(TARGET ssaver OUTPUT "SSaver.g3a"
|
||||
NAME " " ICONS assets-cg/icon-uns.png assets-cg/icon-sel.png)
|
||||
endif()
|
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 62 KiB |
After Width: | Height: | Size: 181 KiB |
After Width: | Height: | Size: 140 KiB |
After Width: | Height: | Size: 173 KiB |
After Width: | Height: | Size: 164 KiB |
|
@ -0,0 +1,3 @@
|
|||
from make_grid import *
|
||||
|
||||
make_grid(5, 5)
|
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 19 KiB |
|
@ -0,0 +1,44 @@
|
|||
bglens3.png:
|
||||
type: bopti-image
|
||||
profile: p8
|
||||
name: bglens
|
||||
|
||||
bglens4.png:
|
||||
type: bopti-image
|
||||
profile: p8
|
||||
name: bglens2
|
||||
|
||||
fontmatrix.png:
|
||||
name: matrix
|
||||
type: font
|
||||
charset: print
|
||||
grid.size: 9x14
|
||||
|
||||
bglens.png:
|
||||
type: bopti-image
|
||||
profile: p8
|
||||
name: bglens3
|
||||
|
||||
eye.png:
|
||||
type: bopti-image
|
||||
profile: p4
|
||||
name: eye
|
||||
|
||||
SlyVTT.png:
|
||||
type: bopti-image
|
||||
profile: p8
|
||||
name: SlyVTT
|
||||
|
||||
Selection.png:
|
||||
type: bopti-image
|
||||
profile: p8
|
||||
name: Selection
|
||||
|
||||
fontFantasy.png:
|
||||
type: font
|
||||
charset: print
|
||||
name: font_fantasy
|
||||
grid.size: 8x8
|
||||
grid.padding: 1
|
||||
proportional: true
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
#!/usr/bin/env python3
|
||||
from math import ceil
|
||||
from sys import argv
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
|
||||
if (len(argv) < 4):
|
||||
raise BaseException("At least three arguments expected: " + \
|
||||
"<font path> <font size> <output image> " + \
|
||||
"[initial char index] [char range]")
|
||||
|
||||
font_path = argv[1]
|
||||
font_size = int(argv[2])
|
||||
image_out = argv[3]
|
||||
initial_char_index = int(argv[4]) if len(argv) > 4 else 0x20
|
||||
char_range = int(argv[5]) if len(argv) > 5 else 96
|
||||
line_count = ceil(char_range / 16)
|
||||
scan_index = 0x20 if len(argv) > 4 else initial_char_index
|
||||
scan_range = 0x30ff - 0x20 if len(argv) > 4 else char_range
|
||||
|
||||
assert char_range > 1
|
||||
|
||||
mode = '1' # 1-bit depth
|
||||
background_color = (1) # white
|
||||
foreground_color = (0) # black
|
||||
|
||||
# load font
|
||||
font = ImageFont.truetype(font_path, font_size)
|
||||
|
||||
# find max char size
|
||||
char_width = 0
|
||||
char_height = 0
|
||||
for i in range(scan_range):
|
||||
bbox = list(font.getbbox(chr(scan_index + i)))
|
||||
# don't you dare overlap
|
||||
if (bbox[0] < 0):
|
||||
bbox[2] = -bbox[0]
|
||||
if (bbox[1] < 0):
|
||||
bbox[3] -= bbox[1]
|
||||
if bbox[2] > char_width:
|
||||
char_width = bbox[2]
|
||||
if bbox[3] > char_height:
|
||||
char_height = bbox[3]
|
||||
|
||||
image_out_width = char_width * 16
|
||||
image_out_height = char_height * line_count
|
||||
|
||||
# fxconv metadata
|
||||
print(f"{image_out.split('/')[-1]}:")
|
||||
print(" type: font")
|
||||
print(" charset: print")
|
||||
print(f" grid.size: {char_width}x{char_height}")
|
||||
|
||||
# create image
|
||||
im = Image.new(mode, (image_out_width, image_out_height))
|
||||
|
||||
# draw
|
||||
draw = ImageDraw.Draw(im)
|
||||
draw.rectangle((0, 0, image_out_width, image_out_height), fill=background_color)
|
||||
|
||||
x = -char_width
|
||||
y = 0
|
||||
for i in range(char_range):
|
||||
x += char_width
|
||||
char = chr(initial_char_index + i)
|
||||
bbox = font.getbbox(char)
|
||||
x_mod = 0
|
||||
y_mod = 0
|
||||
# don't you dare overlap
|
||||
if (bbox[0] < 0):
|
||||
x_mod = -bbox[0]
|
||||
if (bbox[1] < 0):
|
||||
y_mod = -bbox[1]
|
||||
if i != 0 and i % 16 == 0:
|
||||
x = 0
|
||||
y += char_height
|
||||
draw.text((x + x_mod, y + y_mod), char, fill=foreground_color, font=font)
|
||||
|
||||
# save
|
||||
im.save(image_out)
|
||||
|
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 18 KiB |
|
@ -0,0 +1,28 @@
|
|||
from PIL import Image, ImageDraw
|
||||
|
||||
|
||||
def make_grid(char_w, char_h):
|
||||
"""
|
||||
Arguments
|
||||
char_w : character's width (int)
|
||||
char_h : character's height (int)
|
||||
|
||||
Description
|
||||
Make a grid with 1 pxl of padding and boxes around each character in order to make easier the font creation.
|
||||
|
||||
Usage
|
||||
Just enter :
|
||||
>>> make_grid(char_width, char_height)
|
||||
An image will be create in the same folder that this programm in *.png format and the name starts by : 'grid_'.
|
||||
"""
|
||||
width, height = 16 * (char_w + 2), 6 * (char_h + 2)
|
||||
grid = Image.new('RGB', (width, height), 'white')
|
||||
draw = ImageDraw.Draw(grid)
|
||||
|
||||
for x in range(0, width, char_w + 2):
|
||||
for y in range(0, height, char_h + 2):
|
||||
if (x // (char_w + 2) - y // (char_h + 2)) % 2: color = 'blue'
|
||||
else: color = 'orange'
|
||||
draw.rectangle((x, y, x + char_w + 1, y + char_h + 1), fill=None, outline=color)
|
||||
|
||||
grid.save(f"grid_{char_w}—{char_h}.png")
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
|
||||
#define MAXHEIGHT 224
|
||||
|
||||
|
||||
#define MORE_RAM 1
|
||||
|
||||
#endif
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef EFFECTS_H
|
||||
#define EFFECTS_H
|
||||
|
||||
#include "../config.h"
|
||||
|
||||
#include <gint/display.h>
|
||||
#include <gint/image.h>
|
||||
|
||||
|
||||
/* EFFECT #1 : PLASMA EFFECT */
|
||||
|
||||
void plasma_init( bopti_image_t *screen );
|
||||
void plasma_update( bopti_image_t *screen, float dt );
|
||||
void plasma_render( bopti_image_t *screen );
|
||||
void plasma_deinit( bopti_image_t *screen );
|
||||
|
||||
|
||||
/* EFFECT #2 : MORPHING EFFECT : FROM SPHERE TO TORUS */
|
||||
|
||||
void morph_init( bopti_image_t *screen );
|
||||
void morph_update( bopti_image_t *screen, float dt );
|
||||
void morph_render( bopti_image_t *screen );
|
||||
void morph_deinit( bopti_image_t *screen );
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,165 @@
|
|||
#include "effects.h"
|
||||
|
||||
#include <num/num.h>
|
||||
#include "../utilities/fast_trig.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
/********************************\
|
||||
* MOPRHING EFFECT - MODULE 2 *
|
||||
* Specific data and structures *
|
||||
\********************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
libnum::num32 x;
|
||||
libnum::num32 y;
|
||||
libnum::num32 z;
|
||||
libnum::num32 rx;
|
||||
libnum::num32 ry;
|
||||
libnum::num32 rz;
|
||||
int16_t sx;
|
||||
int16_t sy;
|
||||
} Vertex3D;
|
||||
|
||||
#define NB_POINTS 2048
|
||||
#define SCALE 80
|
||||
|
||||
Vertex3D Sphere[NB_POINTS];
|
||||
Vertex3D Torus[NB_POINTS];
|
||||
Vertex3D Morph[NB_POINTS];
|
||||
|
||||
libnum::num32 scale;
|
||||
libnum::num32 eye;
|
||||
libnum::num32 eyescale;
|
||||
int centerx, centery;
|
||||
|
||||
static float anglef = 0.0;
|
||||
static int angle = 0;
|
||||
|
||||
static double frame_counter = 0;
|
||||
|
||||
void ProjectVertex( Vertex3D *vertex )
|
||||
{
|
||||
libnum::num32 divisor = libnum::num32(1) / (scale * vertex->rz + eye);
|
||||
|
||||
vertex->sx = centerx + (int) ((eyescale * vertex->rx) * divisor );
|
||||
vertex->sy = centery + (int) ((eyescale * vertex->ry) * divisor );
|
||||
}
|
||||
|
||||
|
||||
void RotateVertex( Vertex3D *vertex, int ax, int ay, int az )
|
||||
{
|
||||
// Rotate around x axis
|
||||
vertex->ry = vertex->y * FastCosInt(ax) - vertex->z * FastSinInt(ax);
|
||||
vertex->rz = vertex->y * FastSinInt(ax) + vertex->z * FastCosInt(ax);
|
||||
|
||||
// Rotate around y axis
|
||||
vertex->rx = vertex->x * FastCosInt(ay) + vertex->rz * FastSinInt(ay);
|
||||
vertex->rz = vertex->x * -FastSinInt(ay) + vertex->rz * FastCosInt(ay);
|
||||
|
||||
// Rotate around z axis
|
||||
libnum::num32 tmpx = vertex->rx * FastCosInt(az) - vertex->ry * FastSinInt(az);
|
||||
vertex->ry = vertex->rx * FastSinInt(az) + vertex->ry * FastCosInt(az);
|
||||
vertex->rx = tmpx;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void morph_init( bopti_image_t *screen )
|
||||
{
|
||||
uint16_t palette[256];
|
||||
size_t palette_size = 512;
|
||||
|
||||
for(int i=0; i<256; ++i)
|
||||
palette[i] = C_RGB( 0, 0, 0 );
|
||||
|
||||
palette[255] = C_WHITE;
|
||||
|
||||
memcpy(screen->palette, palette, palette_size);
|
||||
|
||||
|
||||
eye = libnum::num32( 250 );
|
||||
scale = libnum::num32( SCALE );
|
||||
eyescale = eye*scale;
|
||||
|
||||
centerx = (DWIDTH / 2);
|
||||
centery = (MAXHEIGHT / 2);
|
||||
|
||||
// Create Sphere
|
||||
for (int i = 0; i < NB_POINTS; i++)
|
||||
{
|
||||
int theta = rand() % 360;
|
||||
int phi = rand() % 360 ;
|
||||
Sphere[i].x = FastCosInt(phi) * FastSinInt(theta);
|
||||
Sphere[i].y = FastSinInt(phi) * FastSinInt(theta);
|
||||
Sphere[i].z = FastCosInt(theta);
|
||||
}
|
||||
|
||||
// Create torus
|
||||
for (int i = 0; i < NB_POINTS; i++)
|
||||
{
|
||||
int theta = rand() % 360;
|
||||
int phi = rand() % 360 ;
|
||||
Torus[i].x = (libnum::num32(0.8) + libnum::num32(0.4) * FastCosInt(theta)) * FastCosInt(phi);
|
||||
Torus[i].y = (libnum::num32(0.8) + libnum::num32(0.4) * FastCosInt(theta)) * FastSinInt(phi);
|
||||
Torus[i].z = libnum::num32(0.4) * FastSinInt(theta);
|
||||
}
|
||||
|
||||
//data = (int8_t*) malloc( DWIDTH*MAXHEIGHT );
|
||||
}
|
||||
|
||||
|
||||
void morph_update( bopti_image_t *screen, [[Maybe_unused]] float dt )
|
||||
{
|
||||
anglef += dt / 10000.0;
|
||||
angle = (int) anglef;
|
||||
|
||||
frame_counter += dt / 10000.0;
|
||||
int frame = (int)frame_counter % 1024;
|
||||
|
||||
|
||||
// Transform the torus into a sphere
|
||||
if (frame < 256) {
|
||||
int key = frame;
|
||||
for (int i = 0; i < NB_POINTS; i++) {
|
||||
Morph[i].x = (libnum::num32(key) * Sphere[i].x + libnum::num32(256 - key) * Torus[i].x) / libnum::num32(256);
|
||||
Morph[i].y = (libnum::num32(key) * Sphere[i].y + libnum::num32(256 - key) * Torus[i].y) / libnum::num32(256);
|
||||
Morph[i].z = (libnum::num32(key) * Sphere[i].z + libnum::num32(256 - key) * Torus[i].z) / libnum::num32(256);
|
||||
}
|
||||
}
|
||||
|
||||
// Transform the sphere into a torus
|
||||
if (frame > 512 && frame <= 768) {
|
||||
int key = frame - 512;
|
||||
for (int i = 0; i < NB_POINTS; i++) {
|
||||
Morph[i].x = (libnum::num32(key) * Torus[i].x + libnum::num32(256 - key) * Sphere[i].x) / libnum::num32(256);
|
||||
Morph[i].y = (libnum::num32(key) * Torus[i].y + libnum::num32(256 - key) * Sphere[i].y) / libnum::num32(256);
|
||||
Morph[i].z = (libnum::num32(key) * Torus[i].z + libnum::num32(256 - key) * Sphere[i].z) / libnum::num32(256);
|
||||
}
|
||||
}
|
||||
|
||||
memset( screen->data, -128, DWIDTH*MAXHEIGHT );
|
||||
|
||||
int8_t *data = (int8_t *) screen->data;
|
||||
|
||||
for (int i = 0; i < NB_POINTS; i++)
|
||||
{
|
||||
RotateVertex(&Morph[i], 0, angle, angle);
|
||||
ProjectVertex(&Morph[i]);
|
||||
data[ Morph[i].sx + Morph[i].sy * DWIDTH ] = 127;
|
||||
}
|
||||
|
||||
memcpy( screen->data, data, DWIDTH*MAXHEIGHT );
|
||||
}
|
||||
|
||||
|
||||
void morph_render( bopti_image_t *screen )
|
||||
{
|
||||
dimage(0,0,screen);
|
||||
}
|
||||
|
||||
void morph_deinit( bopti_image_t *screen )
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
#include "effects.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
|
||||
/********************************\
|
||||
* PLASMA EFFECT - MODULE 1 *
|
||||
* Specific data and structures *
|
||||
\********************************/
|
||||
|
||||
static int aSin[512];
|
||||
uint8_t index;
|
||||
static uint16_t pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0, tpos1, tpos2, tpos3, tpos4;
|
||||
uint16_t x;
|
||||
|
||||
|
||||
void plasma_init( bopti_image_t *screen )
|
||||
{
|
||||
uint16_t palette[256];
|
||||
size_t palette_size = 512;
|
||||
|
||||
for(int i=0; i<64; ++i)
|
||||
{
|
||||
palette[i] = C_RGB( i<<2, 255 - ((i << 2) + 1), 0 );
|
||||
palette[i+64] = C_RGB( 255, (i << 2) + 1, 0 );
|
||||
palette[i+128] = C_RGB( 255 - ((i << 2) + 1), 255 - ((i << 2) + 1), 0 );
|
||||
palette[i+192] = C_RGB( 0, (i << 2) + 1, 0 );
|
||||
}
|
||||
|
||||
memcpy(screen->palette, palette, palette_size);
|
||||
|
||||
for (int i = 0; i < 512; i++)
|
||||
{
|
||||
float rad = ((float)i * 0.703125) * 0.0174532; /* 360 / 512 * degree to rad, 360 degrees spread over 512 values to be able to use AND 512-1 instead of using modulo 360*/
|
||||
aSin[i] = sin(rad) * 1024; /*using fixed point math with 1024 as base*/
|
||||
}
|
||||
}
|
||||
|
||||
void plasma_update( bopti_image_t *screen, [[Maybe_unused]] float dt )
|
||||
{
|
||||
uint8_t *image = (uint8_t *) screen->data;
|
||||
|
||||
tpos4 = pos4;
|
||||
tpos3 = pos3;
|
||||
|
||||
for (int i = 0; i < MAXHEIGHT; ++i)
|
||||
{
|
||||
tpos1 = pos1 + 5;
|
||||
tpos2 = pos2 + 3;
|
||||
|
||||
tpos3 &= 511;
|
||||
tpos4 &= 511;
|
||||
|
||||
for (int j = 0; j < DWIDTH; ++j)
|
||||
{
|
||||
tpos1 &= 511;
|
||||
tpos2 &= 511;
|
||||
|
||||
x = aSin[tpos1] + aSin[tpos2] + aSin[tpos3] + aSin[tpos4]; /*actual plasma calculation*/
|
||||
|
||||
index = 128 + (x >> 4); /*fixed point multiplication but optimized so basically it says (x * (64 * 1024) / (1024 * 1024)), x is already multiplied by 1024*/
|
||||
|
||||
*image++ = index;
|
||||
|
||||
tpos1 += 5;
|
||||
tpos2 += 3;
|
||||
}
|
||||
|
||||
tpos4 += 3;
|
||||
tpos3 += 1;
|
||||
}
|
||||
|
||||
pos1 +=9;
|
||||
pos3 +=8;
|
||||
}
|
||||
|
||||
|
||||
void plasma_render( bopti_image_t *screen )
|
||||
{
|
||||
dimage(0,0,screen);
|
||||
}
|
||||
|
||||
void plasma_deinit( bopti_image_t *screen )
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,313 @@
|
|||
#include <gint/display.h>
|
||||
#include <gint/keyboard.h>
|
||||
#include <gint/dma.h>
|
||||
#include <gint/rtc.h>
|
||||
#include <gint/clock.h>
|
||||
|
||||
#include <fxlibc/printf.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <libprof.h>
|
||||
#include <gint/kmalloc.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "utilities/fast_trig.h"
|
||||
#include "utilities/extrakeyboard.h"
|
||||
#include "utilities/utilities.h"
|
||||
|
||||
|
||||
#include "effects/effects.h"
|
||||
|
||||
|
||||
|
||||
|
||||
#define TOTAL_NB_EFFECT 2
|
||||
typedef void (*PtrToFunc)( bopti_image_t * );
|
||||
typedef void (*PtrToFuncDt)( bopti_image_t *, float );
|
||||
|
||||
PtrToFunc Effects_Init[] = { &plasma_init, &morph_init };
|
||||
PtrToFuncDt Effects_Update[] = { &plasma_update, &morph_update };
|
||||
PtrToFunc Effects_Render[] = { &plasma_render, &morph_render };
|
||||
PtrToFunc Effects_DeInit[] = { &plasma_deinit, &morph_deinit };
|
||||
int current_effect = 1;
|
||||
|
||||
|
||||
#if(MORE_RAM)
|
||||
static kmalloc_arena_t extended_ram = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0,0,0,0,0,0 };
|
||||
static kmalloc_arena_t *_uram;
|
||||
kmalloc_gint_stats_t *_uram_stats;
|
||||
kmalloc_gint_stats_t *extram_stats;
|
||||
#else
|
||||
static kmalloc_arena_t *_uram;
|
||||
kmalloc_gint_stats_t *_uram_stats;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
bool exitToOS = false;
|
||||
bool skip_intro = false;
|
||||
bool screenshot = false;
|
||||
bool record = false;
|
||||
|
||||
|
||||
KeyboardExtra Keyboard;
|
||||
|
||||
|
||||
float elapsedTime = 0.0f;
|
||||
uint32_t time_update=0, time_render=0;
|
||||
prof_t perf_update, perf_render;
|
||||
|
||||
|
||||
extern font_t font_fantasy;
|
||||
extern font_t matrix;
|
||||
|
||||
|
||||
|
||||
bopti_image_t *screen;
|
||||
uint16_t palette[256];
|
||||
size_t palette_size = 512;
|
||||
uint8_t imagedata[DWIDTH*MAXHEIGHT];
|
||||
|
||||
|
||||
|
||||
int get_pixel(bopti_image_t const *img, int x, int y)
|
||||
{
|
||||
return image_get_pixel(img, x, y);
|
||||
}
|
||||
|
||||
void set_pixel(bopti_image_t *img, int x, int y, int color)
|
||||
{
|
||||
image_set_pixel(img, x, y, color);
|
||||
}
|
||||
|
||||
|
||||
/********************************\
|
||||
* INTRODUCING THE CCJ DEMOS *
|
||||
* Specific data and structures *
|
||||
\********************************/
|
||||
|
||||
extern bopti_image_t SlyVTT, Selection;
|
||||
static char text[] = "CHILL CASIO JAM 2022";
|
||||
void run_intro( void )
|
||||
{
|
||||
dclear( C_BLACK );
|
||||
dimage(0, 12, &SlyVTT );
|
||||
dprint( 175, 25, C_WHITE, "%s", text);
|
||||
dimage( 175, 50, &Selection );
|
||||
dprint( 175, 180, C_WHITE, "PRESS EXE TO SELECT" );
|
||||
dprint( 175, 200, C_WHITE, "OLDSCHOOL DEMO EFFECTS" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool AddMoreRAM( void )
|
||||
{
|
||||
#if(MORE_RAM && !CALCEMU)
|
||||
|
||||
/* allow more RAM */
|
||||
char const *osv = (char*) 0x80020020;
|
||||
|
||||
if((!strncmp(osv, "03.", 3) && osv[3] <= '6') && gint[HWCALC] == HWCALC_FXCG50) // CG-50
|
||||
{
|
||||
extended_ram.name = "extram";
|
||||
extended_ram.is_default = true;
|
||||
extended_ram.start = (void *)0x8c200000;
|
||||
extended_ram.end = (void *)0x8c4e0000 ;
|
||||
|
||||
kmalloc_init_arena(&extended_ram, true);
|
||||
kmalloc_add_arena(&extended_ram );
|
||||
return true;
|
||||
}
|
||||
else if (gint[HWCALC] == HWCALC_PRIZM) // CG-10/20
|
||||
{
|
||||
|
||||
extended_ram.name = "extram";
|
||||
extended_ram.is_default = true;
|
||||
|
||||
uint16_t *vram1, *vram2;
|
||||
dgetvram(&vram1, &vram2);
|
||||
dsetvram(vram1, vram1);
|
||||
|
||||
extended_ram.start = vram2;
|
||||
extended_ram.end = (char *)vram2 + 396*224*2;
|
||||
|
||||
kmalloc_init_arena(&extended_ram, true);
|
||||
kmalloc_add_arena(&extended_ram );
|
||||
return false;
|
||||
|
||||
}
|
||||
else if (gint[HWCALC] == HWCALC_FXCG_MANAGER) // CG-50 EMULATOR
|
||||
{
|
||||
|
||||
extended_ram.name = "extram";
|
||||
extended_ram.is_default = true;
|
||||
extended_ram.start = (void *)0x88200000;
|
||||
extended_ram.end = (void *)0x884e0000 ;
|
||||
|
||||
kmalloc_init_arena(&extended_ram, true);
|
||||
kmalloc_add_arena(&extended_ram );
|
||||
return true;
|
||||
}
|
||||
#elif (MORE_RAM && CALCEMU)
|
||||
|
||||
extended_ram.name = "extram";
|
||||
extended_ram.is_default = true;
|
||||
extended_ram.start = (void *)0x8c200000;
|
||||
extended_ram.end = (void *)0x8c4e0000 ;
|
||||
|
||||
kmalloc_init_arena(&extended_ram, true);
|
||||
kmalloc_add_arena(&extended_ram );
|
||||
return true;
|
||||
|
||||
#else
|
||||
|
||||
return false;
|
||||
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void FreeMoreRAM( void )
|
||||
{
|
||||
#if(MORE_RAM)
|
||||
memset(extended_ram.start, 0, (char *)extended_ram.end - (char *)extended_ram.start);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void Initialise( void )
|
||||
{
|
||||
(*Effects_Init[ current_effect ])( screen );
|
||||
}
|
||||
|
||||
static void Render( void )
|
||||
{
|
||||
(*Effects_Render[ current_effect ])( screen );
|
||||
}
|
||||
|
||||
static void Update( [[maybe_unused]] float dt )
|
||||
{
|
||||
(*Effects_Update[ current_effect ])( screen, dt );
|
||||
}
|
||||
|
||||
static void Close( void )
|
||||
{
|
||||
(*Effects_DeInit[ current_effect ])( screen );
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void GetInputs( [[maybe_unused]] float dt )
|
||||
{
|
||||
if (Keyboard.IsKeyPressed(MYKEY_EXIT)) {exitToOS = true; };
|
||||
|
||||
if (Keyboard.IsKeyPressed(MYKEY_F1) && current_effect>=1)
|
||||
{
|
||||
// close the current effect by calling its DeInitFunction
|
||||
Close();
|
||||
// switch to new effect
|
||||
current_effect--;
|
||||
// initialise the current effect
|
||||
Initialise();
|
||||
}
|
||||
|
||||
if (Keyboard.IsKeyPressed(MYKEY_F6) && current_effect<=TOTAL_NB_EFFECT-2)
|
||||
{
|
||||
// close the current effect by calling its DeInitFunction
|
||||
Close();
|
||||
// switch to new effect
|
||||
current_effect++;
|
||||
// initialise the current effect
|
||||
Initialise();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
||||
_uram = kmalloc_get_arena("_uram");
|
||||
#if(MORE_RAM)
|
||||
bool canWeAllocateMoreRam = AddMoreRAM();
|
||||
#endif
|
||||
|
||||
|
||||
int EntryClockLevel;
|
||||
EntryClockLevel = clock_get_speed();
|
||||
clock_set_speed( CLOCK_SPEED_F4 );
|
||||
|
||||
srand( rtc_ticks() );
|
||||
|
||||
screen = image_alloc( DWIDTH, MAXHEIGHT, IMAGE_P8_RGB565A );
|
||||
screen->width = DWIDTH;
|
||||
screen->height = MAXHEIGHT;
|
||||
|
||||
exitToOS = false;
|
||||
|
||||
Initialise();
|
||||
|
||||
__printf_enable_fp();
|
||||
__printf_enable_fixed();
|
||||
|
||||
prof_init();
|
||||
|
||||
do
|
||||
{
|
||||
perf_update = prof_make();
|
||||
prof_enter(perf_update);
|
||||
{
|
||||
// all the stuff to be update should be put here
|
||||
Keyboard.Update( elapsedTime );
|
||||
|
||||
// read inputs from the player
|
||||
GetInputs( elapsedTime );
|
||||
|
||||
// update as per the time spend to do the loop
|
||||
Update( elapsedTime );
|
||||
|
||||
// update the RAM consumption status
|
||||
_uram_stats = kmalloc_get_gint_stats(_uram);
|
||||
#if(MORE_RAM)
|
||||
extram_stats = kmalloc_get_gint_stats(&extended_ram);
|
||||
#endif
|
||||
}
|
||||
prof_leave(perf_update);
|
||||
time_update = prof_time(perf_update);
|
||||
|
||||
perf_render = prof_make();
|
||||
prof_enter(perf_render);
|
||||
{
|
||||
// all the stuff to be rendered should be put here
|
||||
dclear( C_BLACK );
|
||||
|
||||
Render();
|
||||
|
||||
dupdate();
|
||||
}
|
||||
prof_leave(perf_render);
|
||||
time_render = prof_time(perf_render);
|
||||
|
||||
elapsedTime = ((float) (time_update+time_render));
|
||||
}
|
||||
while (exitToOS==false);
|
||||
|
||||
|
||||
prof_quit();
|
||||
|
||||
clock_set_speed( EntryClockLevel );
|
||||
|
||||
image_free( screen );
|
||||
|
||||
#if(MORE_RAM)
|
||||
if (canWeAllocateMoreRam) FreeMoreRAM( );
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
#include "../config.h"
|
||||
|
||||
#include "extrakeyboard.h"
|
||||
#include <gint/keyboard.h>
|
||||
#include <gint/rtc.h>
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool pressed;
|
||||
uint32_t since = 0;
|
||||
} keyinfo;
|
||||
|
||||
|
||||
keyinfo MyKeyMapper[MYKEY_LASTENUM+1];
|
||||
|
||||
|
||||
KeyboardExtra::KeyboardExtra()
|
||||
{
|
||||
uint32_t timer = rtc_ticks();
|
||||
now = timer;
|
||||
for(int i=0; i<=MYKEY_LASTENUM; i++) MyKeyMapper[i] = { .pressed = false, .since = timer };
|
||||
}
|
||||
|
||||
|
||||
KeyboardExtra::~KeyboardExtra()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void KeyboardExtra::Update( [[maybe_unused]] float dt )
|
||||
{
|
||||
uint32_t timer = rtc_ticks();
|
||||
|
||||
now = timer;
|
||||
|
||||
key_event_t ev;
|
||||
|
||||
int keycode = -1;
|
||||
|
||||
while((ev = pollevent()).type != KEYEV_NONE)
|
||||
{
|
||||
if (ev.key == KEY_F1) keycode = MYKEY_F1;
|
||||
else if(ev.key == KEY_F2) keycode = MYKEY_F2;
|
||||
else if(ev.key == KEY_F3) keycode = MYKEY_F3;
|
||||
else if(ev.key == KEY_F4) keycode = MYKEY_F4;
|
||||
else if(ev.key == KEY_F5) keycode = MYKEY_F5;
|
||||
else if(ev.key == KEY_F6) keycode = MYKEY_F6;
|
||||
|
||||
else if(ev.key == KEY_SHIFT) keycode = MYKEY_SHIFT;
|
||||
else if(ev.key == KEY_OPTN) keycode = MYKEY_OPTN;
|
||||
else if(ev.key == KEY_VARS) keycode = MYKEY_VARS;
|
||||
else if(ev.key == KEY_MENU) keycode = MYKEY_MENU;
|
||||
else if(ev.key == KEY_LEFT) keycode = MYKEY_LEFT;
|
||||
else if(ev.key == KEY_UP) keycode = MYKEY_UP;
|
||||
|
||||
else if(ev.key == KEY_ALPHA) keycode = MYKEY_ALPHA;
|
||||
else if(ev.key == KEY_SQUARE) keycode = MYKEY_SQUARE;
|
||||
else if(ev.key == KEY_POWER) keycode = MYKEY_POWER;
|
||||
else if(ev.key == KEY_EXIT) keycode = MYKEY_EXIT;
|
||||
else if(ev.key == KEY_DOWN) keycode = MYKEY_DOWN;
|
||||
else if(ev.key == KEY_RIGHT) keycode = MYKEY_RIGHT;
|
||||
|
||||
else if(ev.key == KEY_XOT) keycode = MYKEY_XOT;
|
||||
else if(ev.key == KEY_LOG) keycode = MYKEY_LOG;
|
||||
else if(ev.key == KEY_LN) keycode = MYKEY_LN;
|
||||
else if(ev.key == KEY_SIN) keycode = MYKEY_SIN;
|
||||
else if(ev.key == KEY_COS) keycode = MYKEY_COS;
|
||||
else if(ev.key == KEY_TAN) keycode = MYKEY_TAN;
|
||||
|
||||
else if(ev.key == KEY_FRAC) keycode = MYKEY_FRAC;
|
||||
else if(ev.key == KEY_FD) keycode = MYKEY_FD;
|
||||
else if(ev.key == KEY_LEFTP) keycode = MYKEY_LEFTP;
|
||||
else if(ev.key == KEY_RIGHTP) keycode = MYKEY_RIGHTP;
|
||||
else if(ev.key == KEY_COMMA) keycode = MYKEY_COMMA;
|
||||
else if(ev.key == KEY_ARROW) keycode = MYKEY_ARROW;
|
||||
|
||||
else if(ev.key == KEY_7) keycode = MYKEY_7;
|
||||
else if(ev.key == KEY_8) keycode = MYKEY_8;
|
||||
else if(ev.key == KEY_9) keycode = MYKEY_9;
|
||||
else if(ev.key == KEY_DEL) keycode = MYKEY_DEL;
|
||||
|
||||
else if(ev.key == KEY_4) keycode = MYKEY_4;
|
||||
else if(ev.key == KEY_5) keycode = MYKEY_5;
|
||||
else if(ev.key == KEY_6) keycode = MYKEY_6;
|
||||
else if(ev.key == KEY_MUL) keycode = MYKEY_MUL;
|
||||
else if(ev.key == KEY_DIV) keycode = MYKEY_DIV;
|
||||
|
||||
else if(ev.key == KEY_1) keycode = MYKEY_1;
|
||||
else if(ev.key == KEY_2) keycode = MYKEY_2;
|
||||
else if(ev.key == KEY_3) keycode = MYKEY_3;
|
||||
else if(ev.key == KEY_ADD) keycode = MYKEY_ADD;
|
||||
else if(ev.key == KEY_SUB) keycode = MYKEY_SUB;
|
||||
|
||||
else if(ev.key == KEY_0) keycode = MYKEY_0;
|
||||
else if(ev.key == KEY_DOT) keycode = MYKEY_DOT;
|
||||
else if(ev.key == KEY_EXP) keycode = MYKEY_EXP;
|
||||
else if(ev.key == KEY_NEG) keycode = MYKEY_NEG;
|
||||
else if(ev.key == KEY_EXE) keycode = MYKEY_EXE;
|
||||
|
||||
else if(ev.key == KEY_ACON) keycode = MYKEY_ACON;
|
||||
|
||||
|
||||
if(keycode!=-1)
|
||||
{
|
||||
if (ev.type == KEYEV_DOWN) MyKeyMapper[keycode] = { .pressed = true, .since = timer };
|
||||
else if (ev.type == KEYEV_UP) MyKeyMapper[keycode] = { .pressed = false, .since = timer };
|
||||
else if (ev.type == KEYEV_HOLD) {}
|
||||
}
|
||||
else
|
||||
{
|
||||
// do nothing, just unstack the event from the events queue
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool KeyboardExtra::IsKeyPressedEvent( int key )
|
||||
{
|
||||
return (MyKeyMapper[key].pressed && MyKeyMapper[key].since == now);
|
||||
}
|
||||
|
||||
|
||||
bool KeyboardExtra::IsKeyReleasedEvent( int key )
|
||||
{
|
||||
return (!MyKeyMapper[key].pressed && MyKeyMapper[key].since == now);
|
||||
}
|
||||
|
||||
|
||||
bool KeyboardExtra::IsKeyPressed( int key )
|
||||
{
|
||||
return MyKeyMapper[key].pressed;
|
||||
}
|
||||
|
||||
|
||||
bool KeyboardExtra::IsKeyReleased( int key )
|
||||
{
|
||||
return (!MyKeyMapper[key].pressed);
|
||||
}
|
||||
|
||||
|
||||
uint32_t KeyboardExtra::IsKeyHoldPressed( int key )
|
||||
{
|
||||
if (MyKeyMapper[key].pressed && MyKeyMapper[key].since < now)
|
||||
return (uint32_t) (now-MyKeyMapper[key].since);
|
||||
else return 0;
|
||||
}
|
||||
|
||||
|
||||
uint32_t KeyboardExtra::IsKeyHoldReleased( int key )
|
||||
{
|
||||
if (!MyKeyMapper[key].pressed && MyKeyMapper[key].since < now)
|
||||
return (uint32_t) (now-MyKeyMapper[key].since);
|
||||
else return 0;
|
||||
}
|
||||
|
||||
uint32_t KeyboardExtra::GetLastTickKeyEvent( int key )
|
||||
{
|
||||
return (uint32_t) MyKeyMapper[key].since;
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
#ifndef EXTRAKEYBOARD_H
|
||||
#define EXTRAKEYBOARD_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
MYKEY_F1=0,
|
||||
MYKEY_F2,
|
||||
MYKEY_F3,
|
||||
MYKEY_F4,
|
||||
MYKEY_F5,
|
||||
MYKEY_F6,
|
||||
|
||||
MYKEY_SHIFT,
|
||||
MYKEY_OPTN,
|
||||
MYKEY_VARS,
|
||||
MYKEY_MENU,
|
||||
MYKEY_LEFT,
|
||||
MYKEY_UP,
|
||||
|
||||
MYKEY_ALPHA,
|
||||
MYKEY_SQUARE,
|
||||
MYKEY_POWER,
|
||||
MYKEY_EXIT,
|
||||
MYKEY_DOWN,
|
||||
MYKEY_RIGHT,
|
||||
|
||||
MYKEY_XOT,
|
||||
MYKEY_LOG,
|
||||
MYKEY_LN,
|
||||
MYKEY_SIN,
|
||||
MYKEY_COS,
|
||||
MYKEY_TAN,
|
||||
|
||||
MYKEY_FRAC,
|
||||
MYKEY_FD,
|
||||
MYKEY_LEFTP,
|
||||
MYKEY_RIGHTP,
|
||||
MYKEY_COMMA,
|
||||
MYKEY_ARROW,
|
||||
|
||||
MYKEY_7,
|
||||
MYKEY_8,
|
||||
MYKEY_9,
|
||||
MYKEY_DEL,
|
||||
|
||||
MYKEY_4,
|
||||
MYKEY_5,
|
||||
MYKEY_6,
|
||||
MYKEY_MUL,
|
||||
MYKEY_DIV,
|
||||
|
||||
MYKEY_1,
|
||||
MYKEY_2,
|
||||
MYKEY_3,
|
||||
MYKEY_ADD,
|
||||
MYKEY_SUB,
|
||||
|
||||
MYKEY_0,
|
||||
MYKEY_DOT,
|
||||
MYKEY_EXP,
|
||||
MYKEY_NEG,
|
||||
MYKEY_EXE,
|
||||
|
||||
MYKEY_ACON,
|
||||
|
||||
MYKEY_LASTENUM,
|
||||
};
|
||||
|
||||
|
||||
|
||||
class KeyboardExtra
|
||||
{
|
||||
public:
|
||||
KeyboardExtra();
|
||||
~KeyboardExtra();
|
||||
|
||||
void Update( float dt );
|
||||
bool IsKeyPressedEvent( int key );
|
||||
bool IsKeyReleasedEvent( int key );
|
||||
bool IsKeyPressed( int key );
|
||||
bool IsKeyReleased( int key );
|
||||
uint32_t IsKeyHoldPressed( int key );
|
||||
uint32_t IsKeyHoldReleased( int key );
|
||||
uint32_t GetLastTickKeyEvent( int key );
|
||||
|
||||
private:
|
||||
uint32_t now;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,183 @@
|
|||
#include "fast_trig.h"
|
||||
#include "num/num.h"
|
||||
|
||||
static libnum::num cosTable[360];
|
||||
static libnum::num sinTable[360];
|
||||
static bool is_fast_trig_initialised = false;
|
||||
|
||||
void Fast_Trig_Init( void )
|
||||
{
|
||||
for(int u=0; u<360; u++)
|
||||
{
|
||||
cosTable[u] = libnum::num( cos( u * PI / 180 ) );
|
||||
sinTable[u] = libnum::num( sin( u * PI / 180 ) );
|
||||
}
|
||||
is_fast_trig_initialised = true;
|
||||
}
|
||||
|
||||
|
||||
libnum::num FastCosInt( int16_t angle )
|
||||
{
|
||||
if (!is_fast_trig_initialised) Fast_Trig_Init();
|
||||
|
||||
if (angle>=0 and angle<360) return cosTable[ angle ];
|
||||
else
|
||||
{
|
||||
int16_t input = angle;
|
||||
if (input<0)
|
||||
{
|
||||
while (input<0) input+=360;
|
||||
return cosTable[ input ];
|
||||
}
|
||||
else
|
||||
{
|
||||
while (input>=360) input-=360;
|
||||
return cosTable[ input ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
libnum::num FastSinInt( int16_t angle )
|
||||
{
|
||||
if (!is_fast_trig_initialised) Fast_Trig_Init();
|
||||
|
||||
if (angle>=0 and angle<360) return sinTable[ angle ];
|
||||
else
|
||||
{
|
||||
int16_t input = angle;
|
||||
if (input<0)
|
||||
{
|
||||
while (input<0) input+=360;
|
||||
return sinTable[ input ];
|
||||
}
|
||||
else
|
||||
{
|
||||
while (input>=360) input-=360;
|
||||
return sinTable[ input ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
libnum::num FastTanInt( int16_t angle )
|
||||
{
|
||||
if (!is_fast_trig_initialised) Fast_Trig_Init();
|
||||
|
||||
int16_t input = angle;
|
||||
|
||||
if (input<0)
|
||||
{
|
||||
while (input<0) input+=360;
|
||||
}
|
||||
else if (input>=360)
|
||||
{
|
||||
while (input>=360) input-=360;
|
||||
}
|
||||
|
||||
libnum::num value;
|
||||
|
||||
if (input==90)
|
||||
{
|
||||
value.v = INT32_MAX;
|
||||
return value;
|
||||
}
|
||||
else if (input==270)
|
||||
{
|
||||
value.v = INT32_MIN;
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = FastSinInt(input) / FastCosInt(input);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
libnum::num32 sqrt_num32(libnum::num32 v) {
|
||||
uint32_t t, q, b, r;
|
||||
r = v.v;
|
||||
b = 0x40000000;
|
||||
q = 0;
|
||||
while (b > 0x40) {
|
||||
t = q + b;
|
||||
if (r >= t) {
|
||||
r -= t;
|
||||
q = t + b;
|
||||
}
|
||||
r <<= 1;
|
||||
b >>= 1;
|
||||
}
|
||||
q >>= 8;
|
||||
libnum::num32 ret;
|
||||
ret.v = q;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* TO DO : rework these functions for sine and cosine calculation */
|
||||
|
||||
libnum::num32 cos_num32(libnum::num32 angle) {
|
||||
// Taylor serie for cos(x) = 1 - x²/2! + x⁴/4! + x⁶/6! + x⁸/8! + ...
|
||||
|
||||
// Cosine function is even
|
||||
if (angle < libnum::num32(0))
|
||||
return cos_num32(-angle);
|
||||
|
||||
// Look for an angle in the range [0, 2*pi [
|
||||
libnum::num32 anglereduced = angle;
|
||||
while (anglereduced >= libnum::num32(2 * PI))
|
||||
anglereduced -= libnum::num32(2 * PI);
|
||||
|
||||
// Exploit the symetry for angle and angle+Pi to reduce the order of the
|
||||
// limited developpement
|
||||
if (anglereduced >= libnum::num(PI))
|
||||
return -cos_num32(anglereduced - libnum::num(PI));
|
||||
|
||||
libnum::num32 sum = libnum::num32(1);
|
||||
libnum::num32 angle2 = anglereduced * anglereduced;
|
||||
|
||||
// set first value of the Taylor serie : x⁰/0! = 1/1
|
||||
libnum::num32 numerator = libnum::num32(1);
|
||||
libnum::num32 denominator = libnum::num32(1);
|
||||
|
||||
for (int i = 2; i <= 8; i += 2) {
|
||||
numerator *= (-angle2);
|
||||
denominator *= libnum::num32(i - 1) * libnum::num32(i);
|
||||
sum += (numerator / denominator);
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
libnum::num32 sin_num32(libnum::num32 angle) {
|
||||
// Taylor serie for cos(x) = x/1! - x³/3! + x⁵/5! - x⁷/7! + x⁹/9! + ...
|
||||
|
||||
// Sine function is odd
|
||||
if (angle < libnum::num32(0))
|
||||
return -sin_num32(-angle);
|
||||
|
||||
// Look for an angle in the range [0, 2*pi [
|
||||
libnum::num32 anglereduced = angle;
|
||||
while (anglereduced >= libnum::num32(2 * PI))
|
||||
anglereduced -= libnum::num32(2 * PI);
|
||||
|
||||
// Exploit the symetry for angle and angle+Pi to reduce the order of the
|
||||
// limited developpement
|
||||
if (anglereduced >= libnum::num(PI))
|
||||
return -sin_num32(anglereduced - libnum::num(PI));
|
||||
|
||||
libnum::num32 sum = anglereduced;
|
||||
libnum::num32 angle2 = anglereduced * anglereduced;
|
||||
|
||||
// set first value of the Taylor serie : x¹/1! = x/1
|
||||
libnum::num32 numerator = anglereduced;
|
||||
libnum::num32 denominator = libnum::num32(1);
|
||||
|
||||
for (int i = 2; i <= 8; i += 2) {
|
||||
numerator *= (-angle2);
|
||||
denominator *= libnum::num32(i) * libnum::num32(i + 1);
|
||||
sum += (numerator / denominator);
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef FAST_TRIG_H
|
||||
#define FAST_TRIG_H
|
||||
|
||||
|
||||
#include <cmath>
|
||||
#include <num/num.h>
|
||||
|
||||
#define PI 3.14159265
|
||||
|
||||
void Fast_Trig_Init( void );
|
||||
|
||||
libnum::num FastCosInt( int16_t angle );
|
||||
libnum::num FastSinInt( int16_t angle );
|
||||
libnum::num FastTanInt( int16_t angle );
|
||||
|
||||
libnum::num32 sqrt_num32(libnum::num32 v);
|
||||
libnum::num32 cos_num32(libnum::num32 angle);
|
||||
libnum::num32 sin_num32(libnum::num32 angle);
|
||||
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,17 @@
|
|||
#include "../config.h"
|
||||
|
||||
#include <azur/azur.h>
|
||||
#include <azur/gint/render.h>
|
||||
|
||||
#include "utilities.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <fxlibc/printf.h>
|
||||
#include <sys/types.h>
|
||||
#include "vector2D.h"
|
||||
#include <num/num.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
#ifndef UTILITIES_H
|
||||
#define UTILITIES_H
|
||||
|
||||
|
||||
#include <cstdint>
|
||||
#include "vector2D.h"
|
||||
|
||||
|
||||
#define ABS(a) ((a) < 0 ? -(a) : (a))
|
||||
#define FLOOR(a) ((a) < 0 ? (int)((a)-1.0) : (int)(a))
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,111 @@
|
|||
#include "vector2D.h"
|
||||
#include "fast_trig.h"
|
||||
|
||||
Vector2D::Vector2D() {
|
||||
this->x = libnum::num32(0);
|
||||
this->y = libnum::num32(0);
|
||||
}
|
||||
|
||||
Vector2D::Vector2D(float x, float y) {
|
||||
this->x = libnum::num32(x);
|
||||
this->y = libnum::num32(y);
|
||||
}
|
||||
|
||||
Vector2D::Vector2D(libnum::num32 x, libnum::num32 y) {
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
}
|
||||
|
||||
Vector2D::Vector2D(const Vector2D &v) {
|
||||
this->x = v.x;
|
||||
this->y = v.y;
|
||||
}
|
||||
|
||||
Vector2D::~Vector2D() {}
|
||||
|
||||
void Vector2D::Set(Vector2D v) {
|
||||
this->x = v.x;
|
||||
this->y = v.y;
|
||||
}
|
||||
|
||||
void Vector2D::Normalise(void) {
|
||||
libnum::num32 len = this->Length();
|
||||
this->x /= len;
|
||||
this->y /= len;
|
||||
}
|
||||
|
||||
Vector2D Vector2D::Clone(void) {
|
||||
Vector2D NewVector(this->x, this->y);
|
||||
return NewVector;
|
||||
}
|
||||
|
||||
Vector2D Vector2D::MakeVector(Vector2D A, Vector2D B) {
|
||||
Vector2D NewVector(B.x - A.x, B.y - A.y);
|
||||
return NewVector;
|
||||
}
|
||||
|
||||
void Vector2D::AddVectors(Vector2D a, Vector2D b) {
|
||||
this->x = a.x + b.x;
|
||||
this->y = a.y + b.y;
|
||||
}
|
||||
|
||||
void Vector2D::Add(Vector2D v, libnum::num32 scale) {
|
||||
this->x += v.x * scale;
|
||||
this->y += v.y * scale;
|
||||
}
|
||||
|
||||
void Vector2D::SubtractVectors(Vector2D a, Vector2D b) {
|
||||
this->x = a.x - b.x;
|
||||
this->y = a.y - b.y;
|
||||
}
|
||||
|
||||
void Vector2D::Subtract(Vector2D v, libnum::num32 scale) {
|
||||
this->x -= v.x * scale;
|
||||
this->y -= v.y * scale;
|
||||
}
|
||||
|
||||
libnum::num32 Vector2D::Length(void) {
|
||||
return sqrt_num32(this->x * this->x + this->y * this->y);
|
||||
}
|
||||
|
||||
void Vector2D::Scale(libnum::num32 scale) {
|
||||
this->x *= scale;
|
||||
this->y *= scale;
|
||||
}
|
||||
|
||||
libnum::num32 Vector2D::Dot(Vector2D v) { return (this->x * v.x + this->y * v.y); }
|
||||
|
||||
libnum::num32 Vector2D::Det(Vector2D v) { return (this->x * v.y - this->y * v.x); }
|
||||
|
||||
Vector2D Vector2D::PerpCW(void) {
|
||||
Vector2D temp(-this->y, this->x);
|
||||
return temp;
|
||||
}
|
||||
|
||||
Vector2D Vector2D::PerpCCW(void) {
|
||||
Vector2D temp(this->y, -this->x);
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Vector2D ClosestPointOnSegment(Vector2D P, Vector2D A, Vector2D B) {
|
||||
Vector2D AB = B - A;
|
||||
|
||||
libnum::num32 t = AB.Dot(AB);
|
||||
|
||||
if (t == 0)
|
||||
return A;
|
||||
|
||||
libnum::num32 t2 = (P.Dot(AB) - A.Dot(AB)) / t;
|
||||
|
||||
if (t2 < libnum::num32(0))
|
||||
t2 = libnum::num32(0);
|
||||
if (t2 > libnum::num32(1))
|
||||
t2 = libnum::num32(1);
|
||||
|
||||
Vector2D C = A.Clone();
|
||||
C.Add(AB, t2);
|
||||
|
||||
return C;
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
#ifndef VECTOR2D_H
|
||||
#define VECTOR2D_H
|
||||
|
||||
#include <num/num.h>
|
||||
#include <stdint.h>
|
||||
#include "fast_trig.h"
|
||||
|
||||
|
||||
class Vector2D {
|
||||
public:
|
||||
Vector2D();
|
||||
Vector2D(float x, float y);
|
||||
Vector2D(libnum::num32 x, libnum::num32 y);
|
||||
Vector2D(const Vector2D &v);
|
||||
~Vector2D();
|
||||
|
||||
void Set(Vector2D v);
|
||||
|
||||
void Normalise(void);
|
||||
|
||||
Vector2D Clone(void);
|
||||
Vector2D MakeVector(Vector2D A, Vector2D B);
|
||||
|
||||
void AddVectors(Vector2D a, Vector2D b);
|
||||
void Add(Vector2D v, libnum::num32 scale);
|
||||
void SubtractVectors(Vector2D a, Vector2D b);
|
||||
void Subtract(Vector2D v, libnum::num32 scale);
|
||||
|
||||
libnum::num32 Length(void);
|
||||
void Scale(libnum::num32 scale);
|
||||
|
||||
libnum::num32 Dot(Vector2D v);
|
||||
libnum::num32 Det(Vector2D v);
|
||||
|
||||
Vector2D PerpCW(void);
|
||||
Vector2D PerpCCW(void);
|
||||
|
||||
/* overloading of most interesting operators */
|
||||
libnum::num32 operator[](uint8_t pos) { return pos == 0 ? x : y; }
|
||||
|
||||
Vector2D &operator=(const Vector2D &v) {
|
||||
this->x = v.x;
|
||||
this->y = v.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vector2D operator+(const Vector2D &v) const {
|
||||
return Vector2D(x + v.x, y + v.y);
|
||||
}
|
||||
|
||||
Vector2D operator-(const Vector2D &v) const {
|
||||
return Vector2D(x - v.x, y - v.y);
|
||||
}
|
||||
|
||||
Vector2D &operator+=(Vector2D const &other) {
|
||||
this->x += other.x;
|
||||
this->y += other.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vector2D operator-() const { return (Vector2D(-x, -y)); }
|
||||
|
||||
Vector2D operator+() const { return *this; }
|
||||
|
||||
Vector2D &operator-=(Vector2D const &other) {
|
||||
this->x -= other.x;
|
||||
this->y -= other.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vector2D &operator*=(libnum::num32 scale) {
|
||||
this->x *= scale;
|
||||
this->y *= scale;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vector2D &operator/=(libnum::num32 scale) {
|
||||
this->x /= scale;
|
||||
this->y /= scale;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend Vector2D operator*(libnum::num32 scale, Vector2D const &v) {
|
||||
Vector2D r;
|
||||
r.x = v.x * scale;
|
||||
r.y = v.y * scale;
|
||||
return r;
|
||||
}
|
||||
|
||||
friend Vector2D operator*(Vector2D const &v, libnum::num32 scale) {
|
||||
Vector2D r;
|
||||
r.x = v.x * scale;
|
||||
r.y = v.y * scale;
|
||||
return r;
|
||||
}
|
||||
|
||||
friend Vector2D operator/(Vector2D const &v, libnum::num32 scale) {
|
||||
Vector2D r;
|
||||
r.x = v.x / scale;
|
||||
r.y = v.y / scale;
|
||||
return r;
|
||||
}
|
||||
|
||||
libnum::num32 x;
|
||||
libnum::num32 y;
|
||||
};
|
||||
|
||||
|
||||
Vector2D ClosestPointOnSegment(Vector2D P, Vector2D A, Vector2D B);
|
||||
|
||||
|
||||
#endif
|