mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2024-12-28 20:43:36 +01:00
First gray tests. Added text module, 'tales'.
This commit is contained in:
parent
f27ba1129a
commit
aa0f4b7285
24 changed files with 765 additions and 198 deletions
15
Makefile
15
Makefile
|
@ -37,23 +37,25 @@ lib = -lgcc -L. -lgint -lc
|
||||||
# Gint library.
|
# Gint library.
|
||||||
src-lib = crt0.c syscalls.s \
|
src-lib = crt0.c syscalls.s \
|
||||||
gint.c gint_vbr.s gint_7705.c gint_7305.c \
|
gint.c gint_vbr.s gint_7705.c gint_7305.c \
|
||||||
mpu.c keyboard.c screen.c display.c bopti.c gray.c timer.c
|
mpu.c keyboard.c screen.c display.c gray.c timer.c tales.c \
|
||||||
|
bopti.c
|
||||||
hea-lib = 7305.h 7705.h gint.h \
|
hea-lib = 7305.h 7705.h gint.h \
|
||||||
stdlib.h \
|
stdlib.h \
|
||||||
mpu.h keyboard.h screen.h display.h gray.h timer.h
|
mpu.h keyboard.h screen.h display.h gray.h timer.h tales.h
|
||||||
obj-lib = $(addprefix build/, $(addsuffix .o, $(src-lib)))
|
obj-lib = $(addprefix build/, $(addsuffix .o, $(src-lib)))
|
||||||
hdr-lib = $(addprefix include/, $(hea-lib))
|
hdr-lib = $(addprefix include/, $(hea-lib))
|
||||||
|
|
||||||
# Standard library.
|
# Standard library.
|
||||||
src-std = setjmp.s string.c
|
src-std = setjmp.s string.c
|
||||||
hea-std = setjmp.h string.h
|
hea-std = setjmp.h string.h ctype.h
|
||||||
obj-std = $(addprefix build/, $(addsuffix .o, $(src-std)))
|
obj-std = $(addprefix build/, $(addsuffix .o, $(src-std)))
|
||||||
hdr-std = $(addprefix include/, $(hea-std))
|
hdr-std = $(addprefix include/, $(hea-std))
|
||||||
|
|
||||||
# Test application.
|
# Test application.
|
||||||
src-app = ginttest.c
|
src-app = ginttest.c
|
||||||
img-app = bitmap_opt.bmp swords.bmp sprites.bmp symbol.bmp symbol2.bmp
|
img-app = bitmap_opt.bmp swords.bmp sprites.bmp symbol.bmp symbol2.bmp \
|
||||||
res-app = $(addprefix build/, $(addsuffix .o, $(img-app)))
|
illustration.bmp
|
||||||
|
res-app = build/font.o $(addprefix build/, $(addsuffix .o, $(img-app)))
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -97,6 +99,9 @@ build/%.s.o: src/%.s
|
||||||
build/%.bmp.o: resources/%.bmp
|
build/%.bmp.o: resources/%.bmp
|
||||||
fxconv $^ -o $@
|
fxconv $^ -o $@
|
||||||
|
|
||||||
|
build/font.o: resources/font.bmp
|
||||||
|
fxconv --font $^ -o $@
|
||||||
|
|
||||||
# File gint.c should not be optimized... looks like attribute((interrupt_
|
# File gint.c should not be optimized... looks like attribute((interrupt_
|
||||||
# handler)) doesn't like it. (It could be a gint bug also, I should check.)
|
# handler)) doesn't like it. (It could be a gint bug also, I should check.)
|
||||||
build/gint.c.o: src/gint.c $(hdr-lib) $(hdr-std)
|
build/gint.c.o: src/gint.c $(hdr-lib) $(hdr-std)
|
||||||
|
|
16
TODO
16
TODO
|
@ -1,3 +1,15 @@
|
||||||
|
@ vram overflow
|
||||||
|
@ keyboard interface
|
||||||
|
|
||||||
|
- upgraded blending modes
|
||||||
|
- blending modes for text
|
||||||
|
- information masks for text
|
||||||
|
- test all font encodings
|
||||||
|
- font clipping
|
||||||
|
|
||||||
|
- bitmap parts
|
||||||
|
- bitmap clipping
|
||||||
|
|
||||||
- multi-getkey repeats (if possible, which doesn't seem likely)
|
- multi-getkey repeats (if possible, which doesn't seem likely)
|
||||||
- it appears that multi-getkey does not always trigger rectangle effects on
|
- it appears that multi-getkey does not always trigger rectangle effects on
|
||||||
sh7305
|
sh7305
|
||||||
|
@ -11,5 +23,5 @@
|
||||||
|
|
||||||
- check possible bug for optimization of __attribute__((interrupt_handler))
|
- check possible bug for optimization of __attribute__((interrupt_handler))
|
||||||
|
|
||||||
_ 7305.h
|
- 7305.h
|
||||||
_ libc
|
- libc
|
||||||
|
|
318
ginttest.c
318
ginttest.c
|
@ -4,6 +4,11 @@
|
||||||
#include <keyboard.h>
|
#include <keyboard.h>
|
||||||
#include <display.h>
|
#include <display.h>
|
||||||
#include <timer.h>
|
#include <timer.h>
|
||||||
|
#include <gray.h>
|
||||||
|
#include <tales.h>
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <7305.h>
|
||||||
|
|
||||||
extern unsigned int bgint, egint;
|
extern unsigned int bgint, egint;
|
||||||
|
|
||||||
|
@ -11,17 +16,9 @@ extern unsigned int bgint, egint;
|
||||||
// A few procedures for displaying text in the system's vram.
|
// A few procedures for displaying text in the system's vram.
|
||||||
//---
|
//---
|
||||||
|
|
||||||
extern void __Print(const char *msg, int x, int y);
|
|
||||||
|
|
||||||
void print_clear(void)
|
|
||||||
{
|
|
||||||
char *empty_line = " ";
|
|
||||||
int i = 0;
|
|
||||||
while(i < 8) __Print(empty_line, 0, i++);
|
|
||||||
}
|
|
||||||
void print(const char *str, int x, int y)
|
void print(const char *str, int x, int y)
|
||||||
{
|
{
|
||||||
__Print(str, x, y);
|
print_raw(str, x, y);
|
||||||
}
|
}
|
||||||
void print_hex(unsigned int n, int x, int y)
|
void print_hex(unsigned int n, int x, int y)
|
||||||
{
|
{
|
||||||
|
@ -34,7 +31,7 @@ void print_hex(unsigned int n, int x, int y)
|
||||||
n >>= 4;
|
n >>= 4;
|
||||||
}
|
}
|
||||||
ch[10] = 0;
|
ch[10] = 0;
|
||||||
__Print(ch, x, y);
|
print(ch, x, y);
|
||||||
}
|
}
|
||||||
void print_bin(unsigned char n, int x, int y)
|
void print_bin(unsigned char n, int x, int y)
|
||||||
{
|
{
|
||||||
|
@ -47,7 +44,7 @@ void print_bin(unsigned char n, int x, int y)
|
||||||
n >>= 1;
|
n >>= 1;
|
||||||
}
|
}
|
||||||
ch[8] = 0;
|
ch[8] = 0;
|
||||||
__Print(ch, x, y);
|
print(ch, x, y);
|
||||||
}
|
}
|
||||||
void print_hexa(unsigned int n, int digits, int x, int y)
|
void print_hexa(unsigned int n, int digits, int x, int y)
|
||||||
{
|
{
|
||||||
|
@ -61,31 +58,48 @@ void print_hexa(unsigned int n, int digits, int x, int y)
|
||||||
}
|
}
|
||||||
|
|
||||||
ch[digits] = 0;
|
ch[digits] = 0;
|
||||||
__Print(ch, x, y);
|
print(ch, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Keyboard tests.
|
|
||||||
The user timer reproduces the parameters of the keyboard timer.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Test applications.
|
||||||
|
//---
|
||||||
|
|
||||||
|
/*
|
||||||
|
keyboard_test_timer()
|
||||||
|
Displays a keyboard test. The keyboard state is displayed as well, but
|
||||||
|
there is a timer artifact. The keyboard state timer uses the same
|
||||||
|
period as the (internal) keyboard analysis timer, but there is a time
|
||||||
|
gap between a keyboard analysis and an update on the screen.
|
||||||
|
*/
|
||||||
void keyboard_test_timer(void)
|
void keyboard_test_timer(void)
|
||||||
{
|
{
|
||||||
volatile unsigned char *state = keystate();
|
volatile unsigned char *state = keystate();
|
||||||
|
|
||||||
print_bin(state[0], 0, 1);
|
dclear_area(5, 10, 71, 34);
|
||||||
print_bin(state[1], 0, 2);
|
|
||||||
print_bin(state[2], 0, 3);
|
|
||||||
print_bin(state[3], 0, 4);
|
|
||||||
print_bin(state[4], 0, 5);
|
|
||||||
|
|
||||||
print_bin(state[5], 9, 1);
|
print_bin(state[0], 5, 10);
|
||||||
print_bin(state[6], 9, 2);
|
print_bin(state[1], 5, 16);
|
||||||
print_bin(state[7], 9, 3);
|
print_bin(state[2], 5, 22);
|
||||||
print_bin(state[8], 9, 4);
|
print_bin(state[3], 5, 28);
|
||||||
print_bin(state[9], 9, 5);
|
print_bin(state[4], 5, 34);
|
||||||
|
|
||||||
|
print_bin(state[5], 40, 10);
|
||||||
|
print_bin(state[6], 40, 16);
|
||||||
|
print_bin(state[7], 40, 22);
|
||||||
|
print_bin(state[8], 40, 28);
|
||||||
|
print_bin(state[9], 40, 34);
|
||||||
|
|
||||||
|
dupdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
keyboard_test()
|
||||||
|
Displays a multi-getkey test as well as the keyboard state in real
|
||||||
|
time.
|
||||||
|
*/
|
||||||
void keyboard_test(void)
|
void keyboard_test(void)
|
||||||
{
|
{
|
||||||
int x = 0;
|
int x = 0;
|
||||||
|
@ -95,37 +109,40 @@ void keyboard_test(void)
|
||||||
|
|
||||||
timer_start(TIMER_USER, 1700, TIMER_Po_256, keyboard_test_timer, 0);
|
timer_start(TIMER_USER, 1700, TIMER_Po_256, keyboard_test_timer, 0);
|
||||||
|
|
||||||
print_clear();
|
|
||||||
print("Keyboard state:", 0, 0);
|
|
||||||
print("multi-getkey ^^", 6, 7);
|
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
multigetkey(keys, 4, 0);
|
multigetkey(keys, 4, 0);
|
||||||
|
|
||||||
if(keys[0] == KEY_EXIT && keys[1] == KEY_NONE) break;
|
if(keys[0] == KEY_EXIT && keys[1] == KEY_NONE) break;
|
||||||
|
|
||||||
|
dclear();
|
||||||
|
print("Keyboard state:", 0, 0);
|
||||||
|
print("multi-getkey ^^", 50, 55);
|
||||||
|
|
||||||
#define hexa(h) ('0' + (h) + 39 * ((h) > 9))
|
#define hexa(h) ('0' + (h) + 39 * ((h) > 9))
|
||||||
|
|
||||||
x = (x + 1) & 15;
|
x = (x + 1) & 15;
|
||||||
str[0] = hexa(x);
|
str[0] = hexa(x);
|
||||||
str[1] = 0;
|
str[1] = 0;
|
||||||
print(str, 20, 0);
|
print(str, 100, 0);
|
||||||
|
|
||||||
for(i = 0; i < 4; i++)
|
for(i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
str[0] = hexa((keys[i] >> 4) & 0x0f);
|
str[0] = hexa((keys[i] >> 4) & 0x0f);
|
||||||
str[1] = hexa(keys[i] & 0x0f);
|
str[1] = hexa(keys[i] & 0x0f);
|
||||||
str[2] = 0;
|
str[2] = 0;
|
||||||
print(str, 19, i + 3);
|
print(str, 100, 16 + 10 * i);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef hexa
|
#undef hexa
|
||||||
|
|
||||||
|
dupdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
timer_stop(TIMER_USER);
|
timer_stop(TIMER_USER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
const unsigned char data[1024] = {
|
const unsigned char data[1024] = {
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
@ -180,114 +197,16 @@ const unsigned char data[1024] = {
|
||||||
255, 15, 31, 252, 31 };
|
255, 15, 31, 252, 31 };
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
static const unsigned char icon[76] = {
|
bitmap_test()
|
||||||
0, 0, 0, 0, 51, 156, 10, 68, 74, 82, 11, 68, 74, 82, 234, 196, 122, 82, 10,
|
Displays various bitmaps to ensure bopti is working correctly.
|
||||||
68, 75, 156, 10, 68, 0, 0, 0, 4, 0, 254, 0, 4, 0, 130, 124, 4, 0, 130, 68, 4,
|
|
||||||
0, 2, 4, 4, 3, 238, 196, 4, 2, 170, 93, 252, 0, 254, 65, 252, 7, 40, 65, 252,
|
|
||||||
5, 232, 65, 252, 7, 15, 193, 252, 0, 0, 1, 252, 127, 255, 255, 252 };
|
|
||||||
|
|
||||||
char *ML_vram_adress(void)
|
|
||||||
{
|
|
||||||
return display_getVRAM();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ML_bmp_or_cl(const unsigned char *bmp, int x, int y, int width, int height)
|
|
||||||
{
|
|
||||||
unsigned short line;
|
|
||||||
char shift, *screen, *p;
|
|
||||||
int i, j, real_width, begin_x, end_x, begin_y, end_y;
|
|
||||||
char bool1=1, bool2=1, bool3;
|
|
||||||
if(!bmp || x<1-width || x>127 || y<1-height || y>63 || height<1 || width<1) return;
|
|
||||||
p = (char*)&line;
|
|
||||||
real_width = (width-1>>3<<3)+8;
|
|
||||||
if(y < 0) begin_y = -y;
|
|
||||||
else begin_y = 0;
|
|
||||||
if(y+height > 64) end_y = 64-y;
|
|
||||||
else end_y = height;
|
|
||||||
shift = 8-(x&7);
|
|
||||||
if(x<0)
|
|
||||||
{
|
|
||||||
begin_x = -x>>3;
|
|
||||||
if(shift != 8) bool1 = 0;
|
|
||||||
} else begin_x = 0;
|
|
||||||
if(x+real_width > 128) end_x = 15-(x>>3), bool2 = 0;
|
|
||||||
else end_x = real_width-1>>3;
|
|
||||||
bool3 = (end_x == real_width-1>>3);
|
|
||||||
screen = ML_vram_adress()+(y+begin_y<<4)+(x>>3);
|
|
||||||
|
|
||||||
for(i=begin_y ; i<end_y ; i++)
|
|
||||||
{
|
|
||||||
if(begin_x < end_x)
|
|
||||||
{
|
|
||||||
line = bmp[i*(real_width>>3)+begin_x] << shift;
|
|
||||||
if(bool1) screen[begin_x] |= *p;
|
|
||||||
if(shift!=8) screen[begin_x+1] |= *(p+1);
|
|
||||||
for(j=begin_x+1 ; j<end_x ; j++)
|
|
||||||
{
|
|
||||||
line = bmp[i*(real_width>>3)+j] << shift;
|
|
||||||
screen[j] |= *p;
|
|
||||||
if(shift!=8) screen[j+1] |= *(p+1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
line = bmp[i*(real_width>>3)+end_x];
|
|
||||||
if(bool3) line &= -1<<real_width-width;
|
|
||||||
line <<= shift;
|
|
||||||
if(begin_x < end_x || bool1) screen[end_x] |= *p;
|
|
||||||
if(bool2) screen[end_x+1] |= *(p+1);
|
|
||||||
screen += 16;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <7305.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
unsigned int exec(void (*f)(void))
|
|
||||||
{
|
|
||||||
int t, s, dt, ds;
|
|
||||||
|
|
||||||
t = (int)RTC.R64CNT;
|
|
||||||
s = 10 * (RTC.RSECCNT.TENS) + RTC.RSECCNT.ONES;
|
|
||||||
|
|
||||||
(*f)();
|
|
||||||
|
|
||||||
dt = (int)RTC.R64CNT - t;
|
|
||||||
ds = (10 * (RTC.RSECCNT.TENS) + RTC.RSECCNT.ONES) - s;
|
|
||||||
if(dt < 0) ds--, dt += 64;
|
|
||||||
|
|
||||||
return (ds << 8) | dt;
|
|
||||||
}
|
|
||||||
|
|
||||||
void btest_ml_icon(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < 5000; i++)
|
|
||||||
{
|
|
||||||
ML_bmp_or_cl(icon, 0, 30, 30, 19);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void btest_gint_icon(void)
|
|
||||||
{
|
|
||||||
extern Image binary_icon_start;
|
|
||||||
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < 5000; i++)
|
|
||||||
{
|
|
||||||
dimage(&binary_icon_start, 0, 0, Blend_Or);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void bitmap_test(void)
|
void bitmap_test(void)
|
||||||
{
|
{
|
||||||
extern Image binary_resources_bitmap_opt_start;
|
extern Image binary_resources_bitmap_opt_start;
|
||||||
extern Image binary_resources_symbol_start;
|
extern Image binary_resources_symbol_start;
|
||||||
extern Image binary_resources_symbol2_start;
|
extern Image binary_resources_symbol2_start;
|
||||||
extern Image binary_resources_sprites_start;
|
extern Image binary_resources_sprites_start;
|
||||||
extern Image binary_resources_swords_start;
|
|
||||||
|
|
||||||
Image *opt = &binary_resources_bitmap_opt_start;
|
Image *opt = &binary_resources_bitmap_opt_start;
|
||||||
Image *sprites = &binary_resources_sprites_start;
|
Image *sprites = &binary_resources_sprites_start;
|
||||||
|
@ -324,64 +243,78 @@ void bitmap_test(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
dclear();
|
|
||||||
dreverse_area(0, 0, 127, 30);
|
|
||||||
|
|
||||||
dimage(sybl, 0, 0, Blend_Or);
|
|
||||||
dimage(sybl, 20, 0, Blend_And);
|
|
||||||
dimage(sybl, 40, 0, Blend_Or | Blend_And);
|
|
||||||
dimage(sybl, 90, 0, Blend_Or | Blend_Invert);
|
|
||||||
|
|
||||||
dimage(sybl2, 0, 20, Blend_Or);
|
|
||||||
dimage(sybl2, 20, 20, Blend_And);
|
|
||||||
dimage(sybl2, 28, 20, Blend_And);
|
|
||||||
dimage(sybl2, 40, 20, Blend_Or | Blend_And);
|
|
||||||
dimage(sybl2, 90, 20, Blend_Or | Blend_Invert);
|
|
||||||
|
|
||||||
dreverse_area(35, 31, 127, 63);
|
|
||||||
dimage(&binary_resources_sprites_start, 50, 31, Blend_And);
|
|
||||||
|
|
||||||
dupdate();
|
|
||||||
/*
|
/*
|
||||||
do key = getkey();
|
text_test()
|
||||||
while(key != KEY_EXE && key != KEY_EXIT);
|
Renders text.
|
||||||
if(key == KEY_EXIT) return 0;
|
|
||||||
|
|
||||||
print("h'sszz 64z=1s", 0, 0);
|
|
||||||
print("ML", 14, 0);
|
|
||||||
print("gint", 17, 0);
|
|
||||||
print("---------------------", 0, 1);
|
|
||||||
|
|
||||||
print("30*19 icon", 0, 2);
|
|
||||||
print(wait, 12, 2);
|
|
||||||
print_hexa(exec(btest_ml_icon), 4, 12, 2);
|
|
||||||
print(wait, 17, 2);
|
|
||||||
print_hexa(exec(btest_gint_icon), 4, 17, 2);
|
|
||||||
*/
|
*/
|
||||||
while(getkey() != KEY_EXE);
|
|
||||||
|
void text_test(void)
|
||||||
|
{
|
||||||
|
extern Font binary_resources_font_start;
|
||||||
|
Font *font = &binary_resources_font_start;
|
||||||
|
|
||||||
|
print_configure(font, Blend_Or);
|
||||||
|
|
||||||
dclear();
|
dclear();
|
||||||
dimage(&binary_resources_swords_start, 20, 20, Blend_Or);
|
|
||||||
|
print(" !\"#$%&'()*+,-./", 10, 10);
|
||||||
|
print("0123456789:;<=>?", 10, 16);
|
||||||
|
print("@ABCDEFGHIJKLMNO", 10, 22);
|
||||||
|
print("PQRSTUVWXYZ[\\]^_", 10, 28);
|
||||||
|
print("`abcdefghijklmno", 10, 34);
|
||||||
|
print("pqrstuvwxyz{|}~", 10, 40);
|
||||||
|
|
||||||
dupdate();
|
dupdate();
|
||||||
|
|
||||||
while(getkey() != KEY_EXE);
|
while(getkey() != KEY_EXIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test(void)
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
gray_test()
|
||||||
|
Runs the gray engine.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void gray_test(void)
|
||||||
{
|
{
|
||||||
static int x = 0;
|
extern Image binary_resources_illustration_start;
|
||||||
x++;
|
Image *illustration = &binary_resources_illustration_start;
|
||||||
|
|
||||||
print_hex(x, 0, 0);
|
int light, dark;
|
||||||
|
int key;
|
||||||
|
|
||||||
|
gray_getDelays(&light, &dark);
|
||||||
|
gray_start();
|
||||||
|
dimage(illustration, 0, 0, Blend_Or);
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
key = getkey();
|
||||||
|
if(key == KEY_EXIT) break;
|
||||||
|
|
||||||
|
if(key == KEY_F1) gray_setDelays(--light, dark);
|
||||||
|
if(key == KEY_F2) gray_setDelays(++light, dark);
|
||||||
|
|
||||||
|
if(key == KEY_F5) gray_setDelays(light, --dark);
|
||||||
|
if(key == KEY_F6) gray_setDelays(light, ++dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
gray_stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
main_menu()
|
||||||
|
Displays the main menu and returns user's choice.
|
||||||
|
|
||||||
|
@return User choice. 0 means EXIT, other numbers are applications.
|
||||||
|
*/
|
||||||
int main_menu(void)
|
int main_menu(void)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
Main menu.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const char *mpu_names[] = {
|
const char *mpu_names[] = {
|
||||||
"MPU_Unkown",
|
"MPU_Unkown",
|
||||||
"MPU_SH7337",
|
"MPU_SH7337",
|
||||||
|
@ -392,18 +325,22 @@ int main_menu(void)
|
||||||
};
|
};
|
||||||
int key;
|
int key;
|
||||||
|
|
||||||
print_clear();
|
dclear();
|
||||||
|
|
||||||
print("gint test application", 0, 0);
|
print("gint test application", 19, 1);
|
||||||
print("---------------------", 0, 1);
|
dline(19, 8, 107, 8, Color_Black);
|
||||||
|
|
||||||
print("[1] Keyboard test", 2, 3);
|
print("[1] Keyboard", 10, 17);
|
||||||
print("[2] Drawing test", 2, 4);
|
print("[2] Bitmap drawing", 10, 24);
|
||||||
|
print("[3] Text rendering", 10, 31);
|
||||||
|
print("[4] Gray engine", 10, 38);
|
||||||
|
|
||||||
print("mpu type:", 0, 6);
|
print("mpu type:", 2, 49);
|
||||||
print(mpu_names[MPU_CURRENT < 5 ? MPU_CURRENT : 5], 11, 6);
|
print(mpu_names[MPU_CURRENT < 5 ? MPU_CURRENT : 5], 50, 48);
|
||||||
print("gint size:", 0, 7);
|
print("gint size:", 2, 56);
|
||||||
print_hex(&egint - &bgint, 11, 7);
|
print_hex(&egint - &bgint, 50, 56);
|
||||||
|
|
||||||
|
dupdate();
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
|
@ -412,13 +349,26 @@ int main_menu(void)
|
||||||
|
|
||||||
if(key == KEY_1) return 1;
|
if(key == KEY_1) return 1;
|
||||||
if(key == KEY_2) return 2;
|
if(key == KEY_2) return 2;
|
||||||
|
if(key == KEY_3) return 3;
|
||||||
|
if(key == KEY_4) return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
main()
|
||||||
|
Handles application calls.
|
||||||
|
|
||||||
|
@return 0.
|
||||||
|
*/
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
extern Font binary_resources_font_start;
|
||||||
|
Font *font = &binary_resources_font_start;
|
||||||
|
|
||||||
|
print_configure(font, Blend_Or);
|
||||||
|
|
||||||
int app;
|
int app;
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
|
@ -428,6 +378,8 @@ int main(void)
|
||||||
|
|
||||||
if(app == 1) keyboard_test();
|
if(app == 1) keyboard_test();
|
||||||
if(app == 2) bitmap_test();
|
if(app == 2) bitmap_test();
|
||||||
|
if(app == 3) text_test();
|
||||||
|
if(app == 4) gray_test();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
BIN
ginttest.g1a
BIN
ginttest.g1a
Binary file not shown.
27
include/ctype.h
Normal file
27
include/ctype.h
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#ifndef _CTYPE_H
|
||||||
|
#define _CTYPE_H 1
|
||||||
|
|
||||||
|
// Character definition macros.
|
||||||
|
#define isalnum(c) (isdigit(c) || isalpha(c))
|
||||||
|
#define isalpha(c) (islower(c) || isupper(c))
|
||||||
|
|
||||||
|
#define iscntrl(c) ((c) <= 0x1f || (c) == 0x7f)
|
||||||
|
#define isdigit(c) ((c) >= '0' && (c) <= '9')
|
||||||
|
#define isgraph(c) ((c) > ' ' && (c) < 0x7f)
|
||||||
|
#define islower(c) ((c) >= 'a' && (c) <= 'z')
|
||||||
|
#define isprint(c) ((c) >= ' ' && (c) < 0x7f)
|
||||||
|
#define ispunct(c) (((c) >= '!' && (c) <= '/') || \
|
||||||
|
((c) >= ':' && (c) <= '@') || \
|
||||||
|
((c) >= '[' && (c) <= '`') || \
|
||||||
|
((c) >= '{' && (c) <= '~'))
|
||||||
|
#define isspace(c) (((c) >= '\t' && (c) <= '\r') || (c) == ' ')
|
||||||
|
#define isupper(c) ((c) >= 'A' && (c) <= 'Z')
|
||||||
|
#define isxdigit(c) (((c) >= '0' && (c) <= '9') || \
|
||||||
|
((c) >= 'A' && (c) <= 'F') || \
|
||||||
|
((c) >= 'a' && (c) <= 'f'))
|
||||||
|
|
||||||
|
// Character manipulation macros.
|
||||||
|
#define tolower(c) (isupper(c) ? (c)|32 : (c))
|
||||||
|
#define toupper(c) (islower(c) ? (c)&~32 : (c))
|
||||||
|
|
||||||
|
#endif // _CTYPE_H
|
|
@ -1,6 +1,14 @@
|
||||||
#ifndef _DISPLAY_H
|
#ifndef _DISPLAY_H
|
||||||
#define _DISPLAY_H 1
|
#define _DISPLAY_H 1
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Included submodules.
|
||||||
|
//---
|
||||||
|
|
||||||
|
#include <tales.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---
|
//---
|
||||||
// Types and constants.
|
// Types and constants.
|
||||||
//---
|
//---
|
||||||
|
@ -60,13 +68,12 @@ enum ImageFormat
|
||||||
*/
|
*/
|
||||||
struct Image
|
struct Image
|
||||||
{
|
{
|
||||||
|
unsigned char magic;
|
||||||
|
|
||||||
unsigned char width;
|
unsigned char width;
|
||||||
unsigned char height;
|
unsigned char height;
|
||||||
unsigned char format;
|
unsigned char format;
|
||||||
|
|
||||||
// Ensures data is 4-aligned.
|
|
||||||
unsigned char gap;
|
|
||||||
|
|
||||||
const unsigned char __attribute__((aligned(4))) data[];
|
const unsigned char __attribute__((aligned(4))) data[];
|
||||||
|
|
||||||
} __attribute__((aligned(4)));
|
} __attribute__((aligned(4)));
|
||||||
|
@ -205,4 +212,6 @@ void dline(int x1, int y1, int x2, int y2, enum Color color);
|
||||||
*/
|
*/
|
||||||
void dimage(struct Image *image, int x, int y, enum BlendingMode mode);
|
void dimage(struct Image *image, int x, int y, enum BlendingMode mode);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // _DISPLAY_H
|
#endif // _DISPLAY_H
|
||||||
|
|
|
@ -31,6 +31,28 @@ void *gray_lightVRAM(void);
|
||||||
*/
|
*/
|
||||||
void *gray_darkVRAM(void);
|
void *gray_darkVRAM(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
gray_getDelays()
|
||||||
|
Returns the gray engine delays.
|
||||||
|
|
||||||
|
@arg light Will be set if non-NULL.
|
||||||
|
@arg dark Will be set if non-NULL.
|
||||||
|
*/
|
||||||
|
void gray_getDelays(int *light, int *dark);
|
||||||
|
|
||||||
|
/*
|
||||||
|
gray_setDelays()
|
||||||
|
Changes the gray engine delays. Usually you don't need to call this,
|
||||||
|
because the engine has its default values.
|
||||||
|
Finding values that give proper grays is quite the hard part of the
|
||||||
|
gray engine. Usual values are about 1000, with light being between 75
|
||||||
|
and 90% of dark.
|
||||||
|
|
||||||
|
@arg light Light gray duration (the lower).
|
||||||
|
@arg dark Dark gray duration (the higher).
|
||||||
|
*/
|
||||||
|
void gray_setDelays(int light, int dark);
|
||||||
|
|
||||||
//---
|
//---
|
||||||
// Internal API.
|
// Internal API.
|
||||||
// Referenced here for documentation purposes only. Do not call.
|
// Referenced here for documentation purposes only. Do not call.
|
||||||
|
|
|
@ -148,6 +148,7 @@ enum GetkeyOpt
|
||||||
non-NULL, it is set to the number of repetitions.
|
non-NULL, it is set to the number of repetitions.
|
||||||
|
|
||||||
@arg repeat_count
|
@arg repeat_count
|
||||||
|
|
||||||
@return Key matrix code.
|
@return Key matrix code.
|
||||||
*/
|
*/
|
||||||
int keylast(int *repeat_count);
|
int keylast(int *repeat_count);
|
||||||
|
@ -223,6 +224,7 @@ enum KeyType
|
||||||
Ignores modifiers.
|
Ignores modifiers.
|
||||||
|
|
||||||
@arg key
|
@arg key
|
||||||
|
|
||||||
@return Modified keycode.
|
@return Modified keycode.
|
||||||
*/
|
*/
|
||||||
int keyid(int key);
|
int keyid(int key);
|
||||||
|
@ -233,7 +235,8 @@ int keyid(int key);
|
||||||
other keys.
|
other keys.
|
||||||
|
|
||||||
@arg key
|
@arg key
|
||||||
@return Key character.
|
|
||||||
|
@return Associated character.
|
||||||
*/
|
*/
|
||||||
int keychar(int key);
|
int keychar(int key);
|
||||||
|
|
||||||
|
@ -242,6 +245,7 @@ int keychar(int key);
|
||||||
Returns a key's type. Ignores modifiers.
|
Returns a key's type. Ignores modifiers.
|
||||||
|
|
||||||
@arg key
|
@arg key
|
||||||
|
|
||||||
@return Key type.
|
@return Key type.
|
||||||
*/
|
*/
|
||||||
enum KeyType keytype(int key);
|
enum KeyType keytype(int key);
|
||||||
|
|
|
@ -28,4 +28,43 @@ void abort(void);
|
||||||
*/
|
*/
|
||||||
void exit(int status);
|
void exit(int status);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Dynamic storage allocation.
|
||||||
|
//---
|
||||||
|
|
||||||
|
/*
|
||||||
|
malloc()
|
||||||
|
Allocs 'size' bytes and returns a pointer to a free memory area.
|
||||||
|
Returns NULL on error.
|
||||||
|
|
||||||
|
@arg size Size to allocate, in bytes.
|
||||||
|
|
||||||
|
@return Memory area address, or NULL.
|
||||||
|
*/
|
||||||
|
void *malloc(size_t size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
calloc()
|
||||||
|
Allocs 'n' elements of size 'size' and wipes the memory area. Returns
|
||||||
|
NULL on error.
|
||||||
|
|
||||||
|
@arg n Element number.
|
||||||
|
@arg size Element size.
|
||||||
|
|
||||||
|
@return Memory area address, or NULL.
|
||||||
|
*/
|
||||||
|
void *calloc(size_t n, size_t size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
free()
|
||||||
|
Frees a memory block allocated with malloc().
|
||||||
|
|
||||||
|
@arg ptr Pointer to free.
|
||||||
|
*/
|
||||||
|
void free(void *ptr);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // _STDLIB_H
|
#endif // _STDLIB_H
|
||||||
|
|
105
include/tales.h
Normal file
105
include/tales.h
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
#ifndef _TALES_H
|
||||||
|
#define _TALES_H 1
|
||||||
|
|
||||||
|
#include <display.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Types and constants.
|
||||||
|
//---
|
||||||
|
|
||||||
|
enum BlendingMode;
|
||||||
|
|
||||||
|
/*
|
||||||
|
enum ImageFormat
|
||||||
|
This type holds information about the characters in the font. Each bit
|
||||||
|
represents various characters, and the type itself is a combination of
|
||||||
|
several of those bits.
|
||||||
|
Bits represent the following characters (lsb right):
|
||||||
|
-- -- -- non-print | special capitals lower numbers
|
||||||
|
*/
|
||||||
|
enum FontFormat
|
||||||
|
{
|
||||||
|
FontFormat_Unknown = 0x00,
|
||||||
|
FontFormat_Numeric = 0x01,
|
||||||
|
FontFormat_LowerCase = 0x02,
|
||||||
|
FontFormat_UpperCase = 0x04,
|
||||||
|
FontFormat_Letters = 0x06,
|
||||||
|
FontFormat_Common = 0x07,
|
||||||
|
FontFormat_Print = 0x0f,
|
||||||
|
FontFormat_Ascii = 0x1f,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
struct FontGlyph
|
||||||
|
Holds a glyph's data. The width is used for spacing, and the raw data
|
||||||
|
is encoded line after line, from to to bottom, by appending bits
|
||||||
|
without consideration of the byte boundaries.
|
||||||
|
This structure is actually never used, because data is read directly
|
||||||
|
as a longword array (hence the 4-byte alignment).
|
||||||
|
*/
|
||||||
|
struct FontGlyph
|
||||||
|
{
|
||||||
|
unsigned char width;
|
||||||
|
|
||||||
|
const unsigned char data[];
|
||||||
|
} __attribute__((aligned(4)));
|
||||||
|
|
||||||
|
/*
|
||||||
|
struct Font
|
||||||
|
Holds a font's data. Data is accessed using longword operations, hence
|
||||||
|
the 4-alignment attributes. The line height is the one given in the
|
||||||
|
font image header line, which may be used by applications that write
|
||||||
|
strings on several lines. The data height is the height of the biggest
|
||||||
|
glyph. Every glyph is encoded on 'data_height' lines, for optimization
|
||||||
|
considerations.
|
||||||
|
The index field is used to reduce character access time.
|
||||||
|
The name field may not be NUL-terminated when the name contains 28
|
||||||
|
characters. When the name is shorter, the field is padded with zeros.
|
||||||
|
*/
|
||||||
|
struct Font
|
||||||
|
{
|
||||||
|
unsigned char magic;
|
||||||
|
|
||||||
|
unsigned char format;
|
||||||
|
unsigned char line_height;
|
||||||
|
unsigned char data_height;
|
||||||
|
|
||||||
|
// Warning : this field may not be NUL-terminated.
|
||||||
|
char name[28];
|
||||||
|
|
||||||
|
uint16_t index[16];
|
||||||
|
|
||||||
|
__attribute__((aligned(4))) const struct FontGlyph glyphs[];
|
||||||
|
|
||||||
|
} __attribute__((aligned(4)));
|
||||||
|
// Useful shorthand for user code.
|
||||||
|
typedef struct Font Font;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Generic functions.
|
||||||
|
//---
|
||||||
|
|
||||||
|
/*
|
||||||
|
print_configure()
|
||||||
|
Sets the font and mode to use for the following print operations.
|
||||||
|
|
||||||
|
@arg font
|
||||||
|
@arg mode
|
||||||
|
*/
|
||||||
|
void print_configure(struct Font *font, enum BlendingMode mode);
|
||||||
|
|
||||||
|
/*
|
||||||
|
print_raw()
|
||||||
|
Prints the given string, without any analysis.
|
||||||
|
|
||||||
|
@arg str
|
||||||
|
@arg x
|
||||||
|
@arg y
|
||||||
|
*/
|
||||||
|
void print_raw(const char *str, int x, int y);
|
||||||
|
|
||||||
|
#endif // _TALES_H
|
|
@ -56,6 +56,16 @@ void timer_start(int timer, int delay, int prescaler, void (*callback)(void),
|
||||||
*/
|
*/
|
||||||
void timer_stop(int timer);
|
void timer_stop(int timer);
|
||||||
|
|
||||||
|
/*
|
||||||
|
timer_reload()
|
||||||
|
Reloads the given timer with the given constant. Starts the timer if
|
||||||
|
it was stopped.
|
||||||
|
|
||||||
|
@arg timer Timer identifier.
|
||||||
|
@arg new_delay
|
||||||
|
*/
|
||||||
|
void timer_reload(int timer, int new_delay);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---
|
//---
|
||||||
|
|
BIN
libc.a
BIN
libc.a
Binary file not shown.
BIN
libgint.a
BIN
libgint.a
Binary file not shown.
BIN
resources/font.bmp
Normal file
BIN
resources/font.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
BIN
resources/illustration.bmp
Normal file
BIN
resources/illustration.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
Binary file not shown.
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
|
@ -286,6 +286,8 @@ void dimage(struct Image *image, int x, int y, enum BlendingMode mode)
|
||||||
int height = image->height;
|
int height = image->height;
|
||||||
const unsigned char *data = (const unsigned char *)&(image->data);
|
const unsigned char *data = (const unsigned char *)&(image->data);
|
||||||
|
|
||||||
|
if(image->magic != 0xb7) return;
|
||||||
|
|
||||||
// Computing the layer size.
|
// Computing the layer size.
|
||||||
int columns = image->width >> 5;
|
int columns = image->width >> 5;
|
||||||
int rest = image->width & 31;
|
int rest = image->width & 31;
|
||||||
|
|
|
@ -93,6 +93,7 @@ static void kdelay(void)
|
||||||
more details.
|
more details.
|
||||||
|
|
||||||
@arg row Row to check (0 <= row <= 9).
|
@arg row Row to check (0 <= row <= 9).
|
||||||
|
|
||||||
@return Bit-based representation of pressed keys in the checked row.
|
@return Bit-based representation of pressed keys in the checked row.
|
||||||
*/
|
*/
|
||||||
static int krow(int row)
|
static int krow(int row)
|
||||||
|
|
|
@ -100,6 +100,7 @@ static void kdelay(void)
|
||||||
Reads a keyboard row.
|
Reads a keyboard row.
|
||||||
|
|
||||||
@arg row Row to check (0 <= row <= 9).
|
@arg row Row to check (0 <= row <= 9).
|
||||||
|
|
||||||
@return Bit-based representation of pressed keys in the checked row.
|
@return Bit-based representation of pressed keys in the checked row.
|
||||||
*/
|
*/
|
||||||
static int krow(int row)
|
static int krow(int row)
|
||||||
|
|
44
src/gray.c
44
src/gray.c
|
@ -1,11 +1,15 @@
|
||||||
#include <display.h>
|
#include <display.h>
|
||||||
#include <gray.h>
|
#include <gray.h>
|
||||||
#include <screen.h>
|
#include <screen.h>
|
||||||
|
#include <timer.h>
|
||||||
|
|
||||||
static int internal_vrams[3][256];
|
static int internal_vrams[3][256];
|
||||||
const void *vrams[4];
|
const void *vrams[4];
|
||||||
|
|
||||||
static int current = 0;
|
static int current = 0;
|
||||||
|
static int delays[2];
|
||||||
|
|
||||||
|
#define GRAY_PRESCALER TIMER_Po_64
|
||||||
|
|
||||||
/*
|
/*
|
||||||
gray_start()
|
gray_start()
|
||||||
|
@ -14,6 +18,7 @@ static int current = 0;
|
||||||
*/
|
*/
|
||||||
void gray_start(void)
|
void gray_start(void)
|
||||||
{
|
{
|
||||||
|
timer_start(TIMER_GRAY, delays[0], GRAY_PRESCALER, gray_interrupt, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -23,6 +28,7 @@ void gray_start(void)
|
||||||
*/
|
*/
|
||||||
void gray_stop(void)
|
void gray_stop(void)
|
||||||
{
|
{
|
||||||
|
timer_stop(TIMER_GRAY);
|
||||||
display_useVRAM(display_getLocalVRAM());
|
display_useVRAM(display_getLocalVRAM());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,6 +50,38 @@ void *gray_darkVRAM(void)
|
||||||
return (void *)vrams[current + 1];
|
return (void *)vrams[current + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
gray_getDelays()
|
||||||
|
Returns the gray engine delays.
|
||||||
|
|
||||||
|
@arg light Will be set if non-NULL.
|
||||||
|
@arg dark Will be set if non-NULL.
|
||||||
|
*/
|
||||||
|
void gray_getDelays(int *light, int *dark)
|
||||||
|
{
|
||||||
|
if(light) *light = delays[0];
|
||||||
|
if(dark) *dark = delays[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
gray_setDelays()
|
||||||
|
Changes the gray engine delays.
|
||||||
|
|
||||||
|
@arg light Light gray duration (the lower).
|
||||||
|
@arg dark Dark gray duration (the higher).
|
||||||
|
*/
|
||||||
|
void gray_setDelays(int light, int dark)
|
||||||
|
{
|
||||||
|
delays[0] = light;
|
||||||
|
delays[1] = dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Internal API.
|
||||||
|
//---
|
||||||
|
|
||||||
/*
|
/*
|
||||||
gray_swap()
|
gray_swap()
|
||||||
Swaps the vram buffers.
|
Swaps the vram buffers.
|
||||||
|
@ -55,10 +93,11 @@ void gray_swap(void)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
gray_interrupt()
|
gray_interrupt()
|
||||||
Answers a timer interrupt. Swaps the two buffers.
|
Answers a timer interrupt. Swaps the buffers.
|
||||||
*/
|
*/
|
||||||
void gray_interrupt(void)
|
void gray_interrupt(void)
|
||||||
{
|
{
|
||||||
|
timer_reload(TIMER_GRAY, delays[current & 1]);
|
||||||
screen_display(vrams[current]);
|
screen_display(vrams[current]);
|
||||||
current ^= 1;
|
current ^= 1;
|
||||||
}
|
}
|
||||||
|
@ -73,4 +112,7 @@ void gray_init(void)
|
||||||
vrams[1] = (const void *)internal_vrams[0];
|
vrams[1] = (const void *)internal_vrams[0];
|
||||||
vrams[2] = (const void *)internal_vrams[1];
|
vrams[2] = (const void *)internal_vrams[1];
|
||||||
vrams[3] = (const void *)internal_vrams[2];
|
vrams[3] = (const void *)internal_vrams[2];
|
||||||
|
|
||||||
|
delays[0] = 3269;
|
||||||
|
delays[1] = 6987;
|
||||||
}
|
}
|
||||||
|
|
|
@ -201,6 +201,7 @@ void keyboard_setRepeatRate(int first, int next)
|
||||||
non-NULL, it is set to the number of repetitions.
|
non-NULL, it is set to the number of repetitions.
|
||||||
|
|
||||||
@arg repeat_count
|
@arg repeat_count
|
||||||
|
|
||||||
@return Key matrix code.
|
@return Key matrix code.
|
||||||
*/
|
*/
|
||||||
int keylast(int *repeat_count)
|
int keylast(int *repeat_count)
|
||||||
|
@ -426,6 +427,7 @@ void multigetkey(int *keys, int count, int max_cycles)
|
||||||
Ignores modifiers.
|
Ignores modifiers.
|
||||||
|
|
||||||
@arg key
|
@arg key
|
||||||
|
|
||||||
@return Modified keycode.
|
@return Modified keycode.
|
||||||
*/
|
*/
|
||||||
int keyid(int key)
|
int keyid(int key)
|
||||||
|
@ -445,6 +447,8 @@ int keyid(int key)
|
||||||
keys.
|
keys.
|
||||||
|
|
||||||
@arg key
|
@arg key
|
||||||
|
|
||||||
|
@return Associated character.
|
||||||
*/
|
*/
|
||||||
int keychar(int key)
|
int keychar(int key)
|
||||||
{
|
{
|
||||||
|
@ -482,6 +486,7 @@ int keychar(int key)
|
||||||
Returns a key's type. Ignores modifiers.
|
Returns a key's type. Ignores modifiers.
|
||||||
|
|
||||||
@arg key
|
@arg key
|
||||||
|
|
||||||
@return Key type.
|
@return Key type.
|
||||||
*/
|
*/
|
||||||
enum KeyType keytype(int key)
|
enum KeyType keytype(int key)
|
||||||
|
|
|
@ -5,7 +5,9 @@
|
||||||
|
|
||||||
.global ___Hmem_SetMMU
|
.global ___Hmem_SetMMU
|
||||||
.global ___GLibAddinAplExecutionCheck
|
.global ___GLibAddinAplExecutionCheck
|
||||||
.global ___Print
|
.global _malloc
|
||||||
|
.global _calloc
|
||||||
|
.global _free
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,12 +24,26 @@ ___GLibAddinAplExecutionCheck:
|
||||||
jmp @r2
|
jmp @r2
|
||||||
nop
|
nop
|
||||||
|
|
||||||
___Print:
|
_malloc:
|
||||||
mov.l syscall_table, r2
|
mov.l syscall_table, r2
|
||||||
mov.l 1f, r0
|
mov.l 1f, r0
|
||||||
jmp @r2
|
jmp @r2
|
||||||
nop
|
nop
|
||||||
1: .long 0x15d
|
1: .long 0xacd
|
||||||
|
|
||||||
|
_calloc:
|
||||||
|
mov.l syscall_table, r2
|
||||||
|
mov.l 1f, r0
|
||||||
|
jmp @r2
|
||||||
|
nop
|
||||||
|
1: .long 0xe6b
|
||||||
|
|
||||||
|
_free:
|
||||||
|
mov.l syscall_table, r2
|
||||||
|
mov.l 1f, r0
|
||||||
|
jmp @r2
|
||||||
|
nop
|
||||||
|
1: .long 0xacc
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
292
src/tales.c
Normal file
292
src/tales.c
Normal file
|
@ -0,0 +1,292 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <tales.h>
|
||||||
|
|
||||||
|
static struct Font *font;
|
||||||
|
static enum BlendingMode mode;
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Local functions.
|
||||||
|
//---
|
||||||
|
|
||||||
|
/*
|
||||||
|
getCharacterIndex()
|
||||||
|
Returns the index of a character in a font data area depending on the
|
||||||
|
font format and the size of the characters.
|
||||||
|
|
||||||
|
@arg character
|
||||||
|
|
||||||
|
@return Index in data area (as long array). Returns -1 when the
|
||||||
|
character does not belong to the font format set.
|
||||||
|
*/
|
||||||
|
static int getCharacterIndex(int c)
|
||||||
|
{
|
||||||
|
const char *data = (const char *)&font->glyphs;
|
||||||
|
int index, current;
|
||||||
|
int offset;
|
||||||
|
int width, bits;
|
||||||
|
|
||||||
|
c &= 0x7f;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Getting the character index in the glyph array.
|
||||||
|
|
||||||
|
if(font->format == FontFormat_Ascii) index = c;
|
||||||
|
else if(font->format == FontFormat_Print) index = c - 32;
|
||||||
|
|
||||||
|
else switch(font->format)
|
||||||
|
{
|
||||||
|
case FontFormat_Numeric:
|
||||||
|
if(!isdigit(c)) return -1;
|
||||||
|
index = c - '0';
|
||||||
|
break;
|
||||||
|
case FontFormat_LowerCase:
|
||||||
|
if(!islower(c)) return -1;
|
||||||
|
index = c - 'a';
|
||||||
|
break;
|
||||||
|
case FontFormat_UpperCase:
|
||||||
|
if(!isupper(c)) return -1;
|
||||||
|
index = c - 'A';
|
||||||
|
break;
|
||||||
|
case FontFormat_Letters:
|
||||||
|
if(!isalpha(c)) return -1;
|
||||||
|
index = c - 'A' - ('a' - 'z') * (c >= 'a');
|
||||||
|
break;
|
||||||
|
case FontFormat_Common:
|
||||||
|
if(!isalnum(c)) return -1;
|
||||||
|
index = c - '0' - ('A' - '9') * (c >= 'A') -
|
||||||
|
('a' - 'z') * (c >= 'a');
|
||||||
|
break;
|
||||||
|
case FontFormat_Unknown:
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Reaching the character offset.
|
||||||
|
|
||||||
|
current = index & ~7;
|
||||||
|
offset = font->index[current >> 3];
|
||||||
|
|
||||||
|
while(current < index)
|
||||||
|
{
|
||||||
|
width = data[offset << 2];
|
||||||
|
bits = font->data_height * width + 8;
|
||||||
|
|
||||||
|
offset += (bits + 31) >> 5;
|
||||||
|
current++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
operate()
|
||||||
|
Operates on the vram using the given operators. The x-coordinate should
|
||||||
|
be a multiple of 32.
|
||||||
|
|
||||||
|
@arg operators Operator array.
|
||||||
|
@arg height Number of operators (height of text).
|
||||||
|
@arg x
|
||||||
|
@arg y
|
||||||
|
*/
|
||||||
|
static void operate(uint32_t *operators, int height, int x, int y)
|
||||||
|
{
|
||||||
|
int *vram = display_getCurrentVRAM();
|
||||||
|
int vram_offset = (x >> 5) + (y << 2);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < height; i++)
|
||||||
|
{
|
||||||
|
// TODO BLENDING MODES //
|
||||||
|
vram[vram_offset] |= operators[i];
|
||||||
|
|
||||||
|
vram_offset += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
update()
|
||||||
|
Updates the operators using the given glyph. The operation will not be
|
||||||
|
complete if there are not enough bits available in the operator data.
|
||||||
|
In this case the offset will become negative, which means that the
|
||||||
|
calling procedure has to call operate() and re-call update().
|
||||||
|
|
||||||
|
@arg operators Operator array.
|
||||||
|
@arg height Number of operators.
|
||||||
|
@arg available Number of free bits in the operators (lower
|
||||||
|
bits).
|
||||||
|
@arg glyph Glyph data, including meta-data.
|
||||||
|
|
||||||
|
@return Number of bits available after the operation. May be negative:
|
||||||
|
in this case, call operate() and update() again.
|
||||||
|
*/
|
||||||
|
static int update(uint32_t *operators, int height, int available,
|
||||||
|
uint32_t *glyph)
|
||||||
|
{
|
||||||
|
// Glyph width.
|
||||||
|
int width = glyph[0] >> 24;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// The glyph mask extracts 'width' bits at the left. The partial mask
|
||||||
|
// is used when there are less than 'width' bits available in the
|
||||||
|
// current data longword.
|
||||||
|
uint32_t glyph_mask = 0xffffffff << (32 - width);
|
||||||
|
uint32_t partial_mask;
|
||||||
|
|
||||||
|
int shift;
|
||||||
|
uint32_t line;
|
||||||
|
|
||||||
|
// Current data longword, next data array index, and number of bits
|
||||||
|
// still available in 'data'.
|
||||||
|
uint32_t data = glyph[0] << 8;
|
||||||
|
int data_index = 1;
|
||||||
|
int bits_available = 24;
|
||||||
|
|
||||||
|
for(i = 0; i < height; i++)
|
||||||
|
{
|
||||||
|
shift = 32 - available;
|
||||||
|
|
||||||
|
// Getting the next 'width' bits. In some cases these bits will
|
||||||
|
// intersect two different longs.
|
||||||
|
line = data & glyph_mask;
|
||||||
|
line = (shift >= 0) ? (line >> shift) : (line << -shift);
|
||||||
|
operators[i] |= line;
|
||||||
|
|
||||||
|
data <<= width;
|
||||||
|
bits_available -= width;
|
||||||
|
|
||||||
|
// Continue until they do.
|
||||||
|
if(bits_available >= 0) continue;
|
||||||
|
|
||||||
|
// Computing a special mask that extracts just the number of
|
||||||
|
// bits missing, and loading a new data longword.
|
||||||
|
partial_mask = 0xffffffff << (32 + bits_available);
|
||||||
|
data = glyph[data_index++];
|
||||||
|
shift += width + bits_available;
|
||||||
|
|
||||||
|
if(shift <= 31)
|
||||||
|
{
|
||||||
|
line = data & partial_mask;
|
||||||
|
line = (shift >= 0) ? (line >> shift) :
|
||||||
|
(line << -shift);
|
||||||
|
operators[i] |= line;
|
||||||
|
}
|
||||||
|
|
||||||
|
data <<= -bits_available;
|
||||||
|
bits_available += 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
return available - width;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Public API.
|
||||||
|
//---
|
||||||
|
|
||||||
|
/*
|
||||||
|
print_configure()
|
||||||
|
Sets the font and mode to use for the following print operations.
|
||||||
|
|
||||||
|
@arg font
|
||||||
|
@arg mode
|
||||||
|
*/
|
||||||
|
void print_configure(struct Font *next_font, enum BlendingMode next_mode)
|
||||||
|
{
|
||||||
|
font = next_font;
|
||||||
|
mode = next_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
print_raw()
|
||||||
|
Prints the given string, without any analysis.
|
||||||
|
|
||||||
|
@arg str
|
||||||
|
@arg x
|
||||||
|
@arg y
|
||||||
|
*/
|
||||||
|
void print_raw(const char *str, int x, int y)
|
||||||
|
{
|
||||||
|
// Operator data, and number of available bits in the operators (which
|
||||||
|
// is the same for all operators, since they are treated equally).
|
||||||
|
uint32_t *operators;
|
||||||
|
int available;
|
||||||
|
|
||||||
|
// Raw glyph data, each glyph being represented by one or several
|
||||||
|
// longwords, and an index in this array.
|
||||||
|
uint32_t *data = (uint32_t *)font->glyphs;
|
||||||
|
int index;
|
||||||
|
|
||||||
|
// Height of each glyph. This value is constant because the storage
|
||||||
|
// format requires it: it allows greater optimization.
|
||||||
|
int height;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(!font) return;
|
||||||
|
|
||||||
|
// Allocating data. There will be one operator for each line.
|
||||||
|
height = font->data_height;
|
||||||
|
if(x > 127 || y > 63 || y <= -height) return;
|
||||||
|
|
||||||
|
operators = calloc(height, sizeof(uint32_t));
|
||||||
|
if(!operators) return;
|
||||||
|
|
||||||
|
// Computing the initial operator offset to have 32-aligned operators.
|
||||||
|
// This allows to write directly video ram longs instead of having to
|
||||||
|
// shift operators, and do all the vram operation twice.
|
||||||
|
available = 32 - (x & 31);
|
||||||
|
x &= ~31;
|
||||||
|
|
||||||
|
// Displaying character after another.
|
||||||
|
while(*str)
|
||||||
|
{
|
||||||
|
index = getCharacterIndex(*str++);
|
||||||
|
if(index < 0) continue;
|
||||||
|
|
||||||
|
// Updating the operators.
|
||||||
|
available = update(operators, height, available, data + index);
|
||||||
|
|
||||||
|
// Continue until operators are full (this includes an
|
||||||
|
// additional bit to add a space between each character).
|
||||||
|
if(available > 1)
|
||||||
|
{
|
||||||
|
available--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When operators are full, updating the video ram and
|
||||||
|
// preparing the operators for another row.
|
||||||
|
|
||||||
|
operate(operators, height, x, y);
|
||||||
|
x += 32;
|
||||||
|
if(x > 96) break;
|
||||||
|
|
||||||
|
memset(operators, 0, height << 2);
|
||||||
|
if(available >= 0)
|
||||||
|
{
|
||||||
|
available = 31 + available;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finishing update, in case it has been only partially done,
|
||||||
|
// because there was not enough bits available to fit all the
|
||||||
|
// information. Also adding a space, assuming that characters
|
||||||
|
// aren't more than 30 bits wide.
|
||||||
|
available += 32 + (data[index] >> 24);
|
||||||
|
available = update(operators, height, available, data + index);
|
||||||
|
available--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Final operation.
|
||||||
|
if(x <= 96 && available < 32) operate(operators, height, x, y);
|
||||||
|
|
||||||
|
free(operators);
|
||||||
|
}
|
23
src/timer.c
23
src/timer.c
|
@ -176,3 +176,26 @@ void timer_stop(int timer)
|
||||||
// Stopping the timer.
|
// Stopping the timer.
|
||||||
*tstr &= ~byte;
|
*tstr &= ~byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
timer_reload()
|
||||||
|
Reloads the given timer with the given constant. Starts the timer if
|
||||||
|
it was stopped.
|
||||||
|
|
||||||
|
@arg timer Timer identifier.
|
||||||
|
@arg new_delay
|
||||||
|
*/
|
||||||
|
void timer_reload(int timer, int new_delay)
|
||||||
|
{
|
||||||
|
struct mod_tmu *tmu;
|
||||||
|
unsigned char *tstr;
|
||||||
|
int byte = (1 << timer);
|
||||||
|
timer_get(timer, &tmu, &tstr);
|
||||||
|
|
||||||
|
// Setting the constant and the delay.
|
||||||
|
(*tmu).TCOR = new_delay;
|
||||||
|
(*tmu).TCNT = new_delay;
|
||||||
|
|
||||||
|
// Starting the timer.
|
||||||
|
*tstr |= byte;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue