mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2024-12-29 13:03:36 +01:00
Major bopti update (one of the last, I hope). Added comparison with ML as fifth application (hidden).
This commit is contained in:
parent
d122624c56
commit
34dd27d7a3
34 changed files with 808 additions and 343 deletions
160
Makefile
160
Makefile
|
@ -1,11 +1,161 @@
|
||||||
## Temporary things there
|
#! /usr/bin/make -f
|
||||||
|
#---
|
||||||
|
#
|
||||||
|
# gint project Makefile.
|
||||||
|
#
|
||||||
|
#---
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#---
|
||||||
|
# Project variables.
|
||||||
|
#---
|
||||||
|
|
||||||
|
# Modules
|
||||||
|
modules-gint = bopti core display gray keyboard mpu screen tales timer
|
||||||
|
modules-libc = setjmp string
|
||||||
|
|
||||||
|
# Targets
|
||||||
|
target-g1a = gintdemo.g1a
|
||||||
|
target-lib = libgint.a
|
||||||
|
target-std = libc.a
|
||||||
|
|
||||||
|
# Tools
|
||||||
|
cc = sh3eb-elf-gcc
|
||||||
|
as = sh3eb-elf-as
|
||||||
|
ar = sh3eb-elf-ar
|
||||||
|
ob = sh3eb-elf-objcopy
|
||||||
|
wr = g1a-wrapper
|
||||||
|
|
||||||
|
# Flags
|
||||||
|
cflags = -m3 -mb -nostdlib -I include -ffreestanding -std=c11
|
||||||
|
|
||||||
|
# Demo application (could be done better)
|
||||||
|
demo-src = $(notdir $(wildcard demo/*.[cs]))
|
||||||
|
demo-ld = demo/gintdemo.ld
|
||||||
|
demo-icon = demo/icon.bmp
|
||||||
|
demo-res = $(notdir $(wildcard demo/resources/*))
|
||||||
|
demo-obj = $(patsubst %,build/demo_%.o,$(demo-src) $(demo-res))
|
||||||
|
demo-elf = build/gintdemo.elf
|
||||||
|
demo-bin = build/gintdemo.bin
|
||||||
|
demo-libs = -lgcc -L. -lgint -lc
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#---
|
||||||
|
# Automatic variables.
|
||||||
|
#---
|
||||||
|
|
||||||
|
# Modules are subfolders of src/.
|
||||||
|
modules = $(modules-gint) $(modules-libc)
|
||||||
|
|
||||||
|
define n
|
||||||
|
# This is a newline character.
|
||||||
|
|
||||||
|
endef
|
||||||
|
|
||||||
|
# Module-scope variables.
|
||||||
|
$(foreach mod, $(modules), $(eval \
|
||||||
|
mod-$(mod)-c = $(notdir $(wildcard src/$(mod)/*.c)) $n\
|
||||||
|
mod-$(mod)-asm = $(notdir $(wildcard src/$(mod)/*.s)) $n\
|
||||||
|
mod-$(mod)-dep = $(wildcard include/*.h src/$(mod)/*.h) $n\
|
||||||
|
mod-$(mod)-src = $$(mod-$(mod)-c)$$(mod-$(mod)-asm) $n\
|
||||||
|
mod-$(mod)-obj = $$(patsubst %,build/$(mod)_%.o,$$(mod-$(mod)-src)) \
|
||||||
|
))
|
||||||
|
|
||||||
|
# Target-scope variables.
|
||||||
|
obj-std = $(foreach mod,$(modules-libc),$(mod-$(mod)-obj))
|
||||||
|
obj-lib = $(foreach mod,$(modules-gint),$(mod-$(mod)-obj))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#---
|
||||||
|
# Rule templates.
|
||||||
|
#---
|
||||||
|
|
||||||
# C source file template:
|
# C source file template:
|
||||||
# $1 module name
|
# $1 module name
|
||||||
# $2 file base name
|
# $2 filename
|
||||||
define rule-c-source
|
define rule-c-source
|
||||||
build/$1_$2.c.o: src/$1/$2.c
|
build/$1_$2.o: src/$1/$2 $(mod-$1-dep)
|
||||||
$(cc) $(cflags) -c $$< -o $$@
|
$(cc) -c $$< -o $$@ $(cflags) -I src/$1 -O2
|
||||||
endef
|
endef
|
||||||
|
|
||||||
$(eval $(call rule-c-source,display,area))
|
# asm source file template:
|
||||||
|
# $1 module name
|
||||||
|
# $2 filename
|
||||||
|
define rule-asm-source
|
||||||
|
build/$1_$2.o: src/$1/$2
|
||||||
|
$(as) -c $$< -o $$@
|
||||||
|
endef
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#---
|
||||||
|
# Building.
|
||||||
|
#---
|
||||||
|
|
||||||
|
# Generic rules
|
||||||
|
|
||||||
|
all: build $(target-std) $(target-lib) $(target-g1a)
|
||||||
|
@ echo 'All done!'
|
||||||
|
|
||||||
|
build:
|
||||||
|
mkdir -p $@
|
||||||
|
|
||||||
|
$(target-std): $(obj-std)
|
||||||
|
$(ar) rcs $@ $^
|
||||||
|
|
||||||
|
$(target-lib): $(target-std) $(obj-lib)
|
||||||
|
$(ar) rcs $@ $(obj-lib)
|
||||||
|
|
||||||
|
$(target-g1a): $(target-std) $(target-lib) $(demo-obj)
|
||||||
|
$(cc) -o $(demo-elf) $(cflags) -T $(demo-ld) $(demo-obj) $(demo-libs)
|
||||||
|
$(ob) -R .comment -R .bss -O binary $(demo-elf) $(demo-bin)
|
||||||
|
$(wr) $(demo-bin) -o $@ -i $(demo-icon)
|
||||||
|
|
||||||
|
# Automated rules
|
||||||
|
|
||||||
|
$(foreach mod,$(modules), \
|
||||||
|
$(foreach source,$(mod-$(mod)-c), $(eval \
|
||||||
|
$(call rule-c-source,$(mod),$(source)))) \
|
||||||
|
$(foreach source,$(mod-$(mod)-asm), $(eval \
|
||||||
|
$(call rule-asm-source,$(mod),$(source)))) \
|
||||||
|
)
|
||||||
|
|
||||||
|
# This one should not be optimized. It makes __attribute__((interrupt_handler))
|
||||||
|
# buggy... maybe. Anyway there's a bug in this file.
|
||||||
|
build/core_gint.c.o: src/core/gint.c $(mod-core-dep)
|
||||||
|
$(cc) -c $< -o $@ $(cflags) -I src/core
|
||||||
|
|
||||||
|
# Demo application
|
||||||
|
|
||||||
|
build/demo_%.c.o: demo/%.c
|
||||||
|
$(cc) -c $< -o $@ $(cflags)
|
||||||
|
|
||||||
|
build/demo_%.bmp.o: demo/resources/%.bmp
|
||||||
|
fxconv $< -o $@ -n $(patsubst demo/resources/%.bmp,res_%,$<)
|
||||||
|
|
||||||
|
build/demo_font.bmp.o: demo/resources/font.bmp
|
||||||
|
fxconv $< -o $@ --font -n res_font
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#---
|
||||||
|
# Cleaning and others.
|
||||||
|
#---
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@ rm -rf build/*
|
||||||
|
|
||||||
|
mrproper: clean
|
||||||
|
@ rm -f $(target-g1a) $(target-lib) $(target-std)
|
||||||
|
@ rm -rf build
|
||||||
|
|
||||||
|
distclean: mrproper
|
||||||
|
|
||||||
|
install:
|
||||||
|
usb-connector SEND $(target-g1a) $(target-g1a) fls0
|
||||||
|
|
||||||
|
|
||||||
|
.PHONY: all clean mrproper distclean
|
||||||
|
|
14
TODO
14
TODO
|
@ -12,6 +12,7 @@
|
||||||
@ vram overflow
|
@ vram overflow
|
||||||
@ keyboard test threading interface
|
@ keyboard test threading interface
|
||||||
|
|
||||||
|
+ gint vs. ML with 248x124 at (-60, -28)
|
||||||
+ use alloca() for tales
|
+ use alloca() for tales
|
||||||
+ call exit handlers
|
+ call exit handlers
|
||||||
+ compute frequencies
|
+ compute frequencies
|
||||||
|
@ -26,6 +27,7 @@
|
||||||
+ bitmap parts
|
+ bitmap parts
|
||||||
+ bitmap clipping
|
+ bitmap clipping
|
||||||
|
|
||||||
|
- install critical failure handler to prevent failing resets
|
||||||
- write and test gray engine
|
- write and test gray engine
|
||||||
- full rtc driver (time)
|
- full rtc driver (time)
|
||||||
- callbacks and complete user API
|
- callbacks and complete user API
|
||||||
|
@ -34,3 +36,15 @@
|
||||||
~ exhaustive save for setjmp()
|
~ exhaustive save for setjmp()
|
||||||
~ registers that need to be saved when configuring gint
|
~ registers that need to be saved when configuring gint
|
||||||
~ possible bug when -O2 __attribute__((interrupt_handler))
|
~ possible bug when -O2 __attribute__((interrupt_handler))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Some notes
|
||||||
|
----------
|
||||||
|
|
||||||
|
Test cases for bitmap drawing:
|
||||||
|
- aligned 32 / non-aligned 32
|
||||||
|
- monochrome / gray
|
||||||
|
- small / large
|
||||||
|
- does not overflow / overflows
|
||||||
|
# blending modes
|
||||||
|
|
394
demo/gintdemo.c
394
demo/gintdemo.c
|
@ -10,15 +10,14 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <7305.h>
|
#include <7305.h>
|
||||||
|
|
||||||
extern unsigned int bgint, egint;
|
|
||||||
|
|
||||||
//---
|
//---
|
||||||
// A few procedures for displaying text in the system's vram.
|
// A few ugly procedures for displaying text. Will have to enhance this
|
||||||
|
// soon -- which means printf().
|
||||||
//---
|
//---
|
||||||
|
|
||||||
void print(const char *str, int x, int y)
|
void print(const char *str, int x, int y)
|
||||||
{
|
{
|
||||||
print_raw(str, x, y);
|
dtext(str, x, y);
|
||||||
}
|
}
|
||||||
void print_hex(unsigned int n, int x, int y)
|
void print_hex(unsigned int n, int x, int y)
|
||||||
{
|
{
|
||||||
|
@ -60,6 +59,24 @@ 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);
|
||||||
}
|
}
|
||||||
|
void print_int(int n, int x, int y)
|
||||||
|
{
|
||||||
|
char str[20] = { 0 };
|
||||||
|
int i, o = 0;
|
||||||
|
int digits = 0, copy = n;
|
||||||
|
|
||||||
|
if(!n) { str[o++] = '0'; print(str, x, y); return; }
|
||||||
|
if(n < 0) str[o++] = '-', n = -n;
|
||||||
|
while(copy) digits++, copy /= 10;
|
||||||
|
|
||||||
|
for(i = 0; i < digits; i++)
|
||||||
|
{
|
||||||
|
str[o + digits - i - 1] = n % 10 + '0';
|
||||||
|
n /= 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
gtext(str, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -109,14 +126,16 @@ 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);
|
||||||
|
|
||||||
|
dclear();
|
||||||
|
print("Keyboard state:", 0, 0);
|
||||||
|
print("multi-getkey ^^", 50, 55);
|
||||||
|
dupdate();
|
||||||
|
|
||||||
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))
|
||||||
|
|
||||||
|
@ -141,109 +160,73 @@ void keyboard_test(void)
|
||||||
timer_stop(TIMER_USER);
|
timer_stop(TIMER_USER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
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, 7, 159, 0, 0, 1, 192, 0, 0, 0, 0, 0, 121, 240, 0, 0, 0,
|
|
||||||
31, 191, 192, 0, 3, 224, 27, 216, 0, 0, 1, 251, 252, 0, 0, 0, 57, 247, 222,
|
|
||||||
30, 7, 240, 36, 36, 62, 25, 131, 159, 24, 255, 129, 224, 0, 227, 142, 126, 1,
|
|
||||||
192, 45, 172, 127, 127, 192, 14, 1, 255, 199, 224, 0, 227, 140, 240, 1, 192,
|
|
||||||
26, 88, 115, 127, 224, 14, 57, 221, 207, 0, 0, 227, 13, 192, 1, 192, 34, 68,
|
|
||||||
120, 30, 0, 14, 25, 156, 220, 0, 0, 227, 253, 252, 1, 192, 36, 36, 126, 28,
|
|
||||||
0, 14, 219, 156, 223, 192, 0, 227, 253, 252, 1, 192, 36, 36, 31, 12, 0, 46,
|
|
||||||
27, 140, 223, 192, 0, 227, 141, 193, 193, 192, 40, 20, 7, 140, 0, 206, 25, 140,
|
|
||||||
220, 28, 0, 227, 140, 225, 129, 199, 24, 24, 99, 156, 1, 14, 25, 204, 206, 24,
|
|
||||||
0, 227, 142, 127, 1, 195, 39, 228, 255, 156, 2, 14, 24, 237, 199, 240, 1, 247,
|
|
||||||
222, 62, 1, 198, 44, 44, 223, 30, 2, 31, 28, 237, 131, 224, 1, 224, 0, 0, 3,
|
|
||||||
254, 27, 216, 0, 0, 4, 30, 0, 0, 0, 0, 3, 192, 0, 0, 7, 252, 0, 0, 0, 0, 4,
|
|
||||||
60, 1, 249, 240, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 4, 0, 97, 240, 56, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 1, 224, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
4, 0, 47, 192, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 32, 255, 128, 63, 128,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 32, 255, 0, 48, 78, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 15, 176, 255, 0, 112, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 8, 56, 255, 0,
|
|
||||||
96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98, 8, 60, 255, 0, 224, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 130, 56, 126, 255, 3, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 192,
|
|
||||||
62, 255, 15, 224, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 14, 191, 255, 192, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 6, 129, 255, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
1, 0, 0, 6, 0, 255, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 128, 63, 192,
|
|
||||||
1, 0, 96, 1, 224, 1, 0, 0, 0, 2, 0, 0, 7, 0, 31, 192, 0, 0, 95, 1, 11, 68, 88,
|
|
||||||
0, 0, 4, 0, 0, 7, 128, 31, 192, 0, 1, 192, 129, 204, 85, 100, 0, 0, 8, 0, 0,
|
|
||||||
15, 128, 63, 224, 0, 0, 95, 1, 8, 85, 68, 0, 1, 144, 0, 0, 31, 128, 143, 224,
|
|
||||||
64, 0, 96, 1, 232, 41, 68, 0, 2, 96, 0, 31, 255, 129, 7, 248, 96, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 4, 0, 0, 96, 254, 129, 7, 254, 96, 0, 0, 0, 0, 0, 0, 0, 4, 0, 1, 128,
|
|
||||||
254, 131, 135, 255, 224, 0, 0, 1, 192, 64, 16, 0, 8, 0, 7, 0, 254, 131, 255,
|
|
||||||
63, 224, 0, 0, 1, 38, 113, 208, 0, 8, 0, 13, 0, 222, 147, 254, 31, 224, 0, 0,
|
|
||||||
1, 41, 74, 80, 0, 8, 0, 25, 0, 222, 67, 254, 31, 160, 0, 0, 1, 41, 74, 80, 0,
|
|
||||||
12, 0, 49, 0, 222, 19, 254, 62, 48, 0, 0, 1, 198, 113, 208, 0, 2, 0, 32, 128,
|
|
||||||
222, 195, 255, 252, 56, 0, 0, 0, 0, 0, 0, 0, 2, 0, 124, 64, 220, 151, 135, 248,
|
|
||||||
127, 0, 0, 0, 0, 0, 0, 0, 2, 0, 66, 32, 221, 223, 7, 240, 255, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 2, 0, 129, 23, 93, 159, 15, 241, 131, 0, 0, 0, 0, 0, 0, 0, 4, 0, 128,
|
|
||||||
136, 217, 95, 3, 226, 9, 0, 0, 1, 240, 0, 0, 0, 4, 0, 128, 72, 89, 95, 129,
|
|
||||||
228, 18, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0, 72, 73, 127, 128, 224, 36, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 28, 1, 0, 76, 129, 127, 192, 96, 8, 0, 0, 0, 0, 0, 0, 0, 16, 1, 0,
|
|
||||||
231, 203, 124, 96, 64, 0, 0, 0, 0, 0, 0, 0, 0, 16, 1, 1, 28, 123, 240, 12, 64,
|
|
||||||
1, 0, 0, 0, 0, 0, 0, 0, 16, 1, 2, 28, 143, 128, 15, 192, 7, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 16, 1, 4, 17, 143, 24, 15, 192, 14, 0, 0, 0, 0, 0, 0, 0, 28, 1, 4, 1, 135,
|
|
||||||
24, 31, 192, 24, 0, 0, 0, 0, 0, 0, 0, 18, 1, 62, 1, 135, 248, 63, 224, 192,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 35, 1, 195, 1, 135, 128, 254, 126, 1, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 35, 193, 131, 195, 135, 255, 248, 112, 1, 0, 0, 0, 0, 0, 0, 0, 67, 241, 131,
|
|
||||||
14, 207, 255, 192, 224, 3, 0, 0, 0, 0, 0, 0, 3, 67, 15, 143, 56, 255, 7, 1,
|
|
||||||
224, 7, 0, 0, 0, 0, 0, 0, 28, 130, 7, 255, 112, 204, 7, 131, 224, 31, 0, 0,
|
|
||||||
0, 0, 0, 0, 32, 134, 30, 29, 120, 156, 7, 255, 224, 127, 0, 0, 0, 0, 0, 63,
|
|
||||||
197, 206, 60, 56, 192, 248, 15, 255, 248, 255, 0, 0, 0, 0, 0, 120, 5, 227, 248,
|
|
||||||
56, 195, 248, 127, 191, 254, 63, 0, 0, 0, 0, 7, 254, 255, 193, 255, 15, 193,
|
|
||||||
255, 15, 31, 252, 31 };
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
bitmap_test()
|
bitmap_test()
|
||||||
Displays various bitmaps to ensure bopti is working correctly.
|
Displays various bitmaps to ensure bopti is working correctly.
|
||||||
*/
|
*/
|
||||||
void bitmap_test(void)
|
void bitmap_test(void)
|
||||||
{
|
{
|
||||||
extern Image binary_resources_bitmap_opt_start;
|
extern Image res_bitmap_opt_start;
|
||||||
extern Image binary_resources_symbol_start;
|
extern Image res_symbol_start;
|
||||||
extern Image binary_resources_symbol2_start;
|
extern Image res_symbol2_start;
|
||||||
extern Image binary_resources_sprites_start;
|
extern Image res_sprites_start;
|
||||||
|
extern Image res_swords_start;
|
||||||
|
|
||||||
Image *opt = &binary_resources_bitmap_opt_start;
|
Image *opt = &res_bitmap_opt_start;
|
||||||
Image *sprites = &binary_resources_sprites_start;
|
Image *sybl = &res_symbol_start;
|
||||||
Image *sybl = &binary_resources_symbol_start;
|
Image *sybl2 = &res_symbol2_start;
|
||||||
Image *sybl2 = &binary_resources_symbol2_start;
|
Image *sprites = &res_sprites_start;
|
||||||
|
Image *swords = &res_swords_start;
|
||||||
|
|
||||||
// enum BlendingMode blend = Blend_Or;
|
|
||||||
uint32_t a32 = 0xffffffff;
|
uint32_t a32 = 0xffffffff;
|
||||||
int black_bg = 0;
|
int black_bg = 0, gray = 0;
|
||||||
int key;
|
int key;
|
||||||
|
int x = 20, y = 10;
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
|
if(gray)
|
||||||
|
{
|
||||||
|
gray_start();
|
||||||
|
gclear();
|
||||||
|
|
||||||
|
if(black_bg) greverse_area(0, 0, 127, 63);
|
||||||
|
gimage(opt, 0, 57);
|
||||||
|
|
||||||
|
gimage(sprites, x, y);
|
||||||
|
gimage(swords, x, y + 35);
|
||||||
|
|
||||||
|
gupdate();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gray_stop();
|
||||||
dclear();
|
dclear();
|
||||||
|
|
||||||
if(black_bg) dreverse_area(0, 0, 127, 63);
|
if(black_bg) dreverse_area(0, 0, 127, 63);
|
||||||
dimage(opt, 0, 57);
|
dimage(opt, 0, 57);
|
||||||
|
|
||||||
dimage(sprites, 2 & a32, 2);
|
|
||||||
dimage(sybl, 30 & a32, 40);
|
dimage(sybl, 30 & a32, 40);
|
||||||
dimage(sybl2, 62 & a32, 40);
|
dimage(sybl2, 62 & a32, 40);
|
||||||
|
|
||||||
dupdate();
|
dupdate();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
key = getkey();
|
key = getkey();
|
||||||
if(key == KEY_EXIT) break;
|
if(key == KEY_EXIT) break;
|
||||||
|
|
||||||
/*
|
if(key == KEY_F1) gray = !gray;
|
||||||
if(key == KEY_F1) blend = Blend_Or;
|
if(key == KEY_F2) a32 ^= 31;
|
||||||
if(key == KEY_F2) blend = Blend_And;
|
if(key == KEY_F3) black_bg = !black_bg;
|
||||||
if(key == KEY_F3) blend = Blend_Invert;
|
|
||||||
*/
|
|
||||||
|
|
||||||
if(key == KEY_F4) black_bg = !black_bg;
|
if(key == KEY_UP) y--;
|
||||||
if(key == KEY_F5) a32 ^= 31;
|
if(key == KEY_DOWN) y++;
|
||||||
|
if(key == KEY_LEFT) x--;
|
||||||
|
if(key == KEY_RIGHT) x++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gray_stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,10 +239,10 @@ void bitmap_test(void)
|
||||||
|
|
||||||
void text_test(void)
|
void text_test(void)
|
||||||
{
|
{
|
||||||
extern Font binary_resources_font_start;
|
extern Font res_font_start;
|
||||||
Font *font = &binary_resources_font_start;
|
Font *font = &res_font_start;
|
||||||
|
|
||||||
print_configure(font);
|
text_configure(font);
|
||||||
|
|
||||||
dclear();
|
dclear();
|
||||||
|
|
||||||
|
@ -284,31 +267,89 @@ void text_test(void)
|
||||||
|
|
||||||
void gray_test(void)
|
void gray_test(void)
|
||||||
{
|
{
|
||||||
extern Image binary_resources_illustration_start;
|
extern Image res_illustration_start;
|
||||||
Image *illustration = &binary_resources_illustration_start;
|
Image *illustration = &res_illustration_start;
|
||||||
|
|
||||||
int light, dark;
|
int *v1, *v2;
|
||||||
int key;
|
|
||||||
|
|
||||||
gray_getDelays(&light, &dark);
|
int delays[2]; // { light, dark }
|
||||||
|
int key, changed = 1, i;
|
||||||
|
int selected = 0;
|
||||||
|
|
||||||
|
gray_getDelays(delays, delays + 1);
|
||||||
gray_start();
|
gray_start();
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
|
if(changed)
|
||||||
|
{
|
||||||
|
gray_setDelays(delays[0], delays[1]);
|
||||||
gclear();
|
gclear();
|
||||||
dimage(illustration, 0, 0);
|
|
||||||
gclear_area(64, 0, 127, 63);
|
|
||||||
// gupdate();
|
|
||||||
|
|
||||||
key = getkey();
|
v1 = gray_lightVRAM();
|
||||||
|
v2 = gray_darkVRAM();
|
||||||
|
|
||||||
|
for(i = 0; i < 63; i++)
|
||||||
|
{
|
||||||
|
v1[(i << 2)] = v1[(i << 2) + 1] =
|
||||||
|
-((i & 31) < 16);
|
||||||
|
v2[(i << 2)] = v2[(i << 2) + 1] =
|
||||||
|
-(i < 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
// gimage(illustration, 0, 0);
|
||||||
|
// gclear_area(64, 0, 127, 63);
|
||||||
|
|
||||||
|
gtext("light", 78, 6);
|
||||||
|
print_int(delays[0], 103, 6);
|
||||||
|
|
||||||
|
gtext("dark", 78, 15);
|
||||||
|
print_int(delays[1], 103, 15);
|
||||||
|
|
||||||
|
gtext(">", 70, selected ? 15 : 6);
|
||||||
|
gupdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
changed = 0;
|
||||||
|
|
||||||
|
key = getkey_opt(Getkey_RepeatArrowKeys, 1);
|
||||||
if(key == KEY_EXIT) break;
|
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);
|
changed = 1;
|
||||||
if(key == KEY_F6) gray_setDelays(light, ++dark);
|
|
||||||
*/
|
switch(key)
|
||||||
|
{
|
||||||
|
case KEY_F1:
|
||||||
|
delays[0] = 860;
|
||||||
|
delays[1] = 1298;
|
||||||
|
break;
|
||||||
|
case KEY_F2:
|
||||||
|
delays[0] = 912;
|
||||||
|
delays[1] = 1343;
|
||||||
|
break;
|
||||||
|
case KEY_F3:
|
||||||
|
delays[0] = 993;
|
||||||
|
delays[1] = 1609;
|
||||||
|
break;
|
||||||
|
case KEY_F6:
|
||||||
|
selected = !selected;
|
||||||
|
break;
|
||||||
|
case KEY_UP:
|
||||||
|
delays[selected] += 10;
|
||||||
|
break;
|
||||||
|
case KEY_DOWN:
|
||||||
|
if(delays[selected] >= 110) delays[selected] -= 10;
|
||||||
|
break;
|
||||||
|
case KEY_RIGHT:
|
||||||
|
delays[selected]++;
|
||||||
|
break;
|
||||||
|
case KEY_LEFT:
|
||||||
|
if(delays[selected] >= 101) delays[selected]--;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
changed = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gray_stop();
|
gray_stop();
|
||||||
|
@ -322,6 +363,7 @@ void gray_test(void)
|
||||||
*/
|
*/
|
||||||
int main_menu(void)
|
int main_menu(void)
|
||||||
{
|
{
|
||||||
|
extern unsigned int bgint, egint;
|
||||||
const char *mpu_names[] = {
|
const char *mpu_names[] = {
|
||||||
"MPU_Unkown",
|
"MPU_Unkown",
|
||||||
"MPU_SH7337",
|
"MPU_SH7337",
|
||||||
|
@ -358,11 +400,158 @@ int main_menu(void)
|
||||||
if(key == KEY_2) return 2;
|
if(key == KEY_2) return 2;
|
||||||
if(key == KEY_3) return 3;
|
if(key == KEY_3) return 3;
|
||||||
if(key == KEY_4) return 4;
|
if(key == KEY_4) return 4;
|
||||||
|
if(key == KEY_5) return 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const unsigned char screen[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, 7, 159, 0, 0, 1, 192, 0, 0, 0, 0, 0, 121, 240, 0, 0, 0,
|
||||||
|
31, 191, 192, 0, 3, 224, 27, 216, 0, 0, 1, 251, 252, 0, 0, 0, 57, 247, 222,
|
||||||
|
30, 7, 240, 36, 36, 62, 25, 131, 159, 24, 255, 129, 224, 0, 227, 142, 126, 1,
|
||||||
|
192, 45, 172, 127, 127, 192, 14, 1, 255, 199, 224, 0, 227, 140, 240, 1, 192,
|
||||||
|
26, 88, 115, 127, 224, 14, 57, 221, 207, 0, 0, 227, 13, 192, 1, 192, 34, 68,
|
||||||
|
120, 30, 0, 14, 25, 156, 220, 0, 0, 227, 253, 252, 1, 192, 36, 36, 126, 28,
|
||||||
|
0, 14, 219, 156, 223, 192, 0, 227, 253, 252, 1, 192, 36, 36, 31, 12, 0, 46,
|
||||||
|
27, 140, 223, 192, 0, 227, 141, 193, 193, 192, 40, 20, 7, 140, 0, 206, 25, 140,
|
||||||
|
220, 28, 0, 227, 140, 225, 129, 199, 24, 24, 99, 156, 1, 14, 25, 204, 206, 24,
|
||||||
|
0, 227, 142, 127, 1, 195, 39, 228, 255, 156, 2, 14, 24, 237, 199, 240, 1, 247,
|
||||||
|
222, 62, 1, 198, 44, 44, 223, 30, 2, 31, 28, 237, 131, 224, 1, 224, 0, 0, 3,
|
||||||
|
254, 27, 216, 0, 0, 4, 30, 0, 0, 0, 0, 3, 192, 0, 0, 7, 252, 0, 0, 0, 0, 4,
|
||||||
|
60, 1, 249, 240, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 4, 0, 97, 240, 56, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 1, 224, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
4, 0, 47, 192, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 32, 255, 128, 63, 128,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 32, 255, 0, 48, 78, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 15, 176, 255, 0, 112, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 8, 56, 255, 0,
|
||||||
|
96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98, 8, 60, 255, 0, 224, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 130, 56, 126, 255, 3, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 192,
|
||||||
|
62, 255, 15, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 14, 191, 255, 192, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 6, 129, 255, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
1, 0, 0, 6, 0, 255, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 128, 63, 192,
|
||||||
|
0, 0, 96, 1, 224, 1, 0, 0, 0, 2, 0, 0, 7, 0, 31, 192, 0, 0, 95, 1, 11, 68, 88,
|
||||||
|
0, 0, 4, 0, 0, 7, 128, 31, 192, 0, 1, 192, 129, 204, 85, 100, 0, 0, 8, 0, 0,
|
||||||
|
15, 128, 63, 224, 0, 0, 95, 1, 8, 85, 68, 0, 1, 144, 0, 0, 31, 128, 143, 224,
|
||||||
|
64, 0, 96, 1, 232, 41, 68, 0, 2, 96, 0, 31, 255, 129, 7, 248, 96, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 4, 0, 0, 96, 254, 129, 7, 254, 96, 0, 0, 0, 0, 0, 0, 0, 4, 0, 1, 128,
|
||||||
|
254, 131, 135, 255, 224, 0, 0, 1, 192, 64, 16, 0, 8, 0, 7, 0, 254, 131, 255,
|
||||||
|
63, 224, 0, 0, 1, 38, 113, 208, 0, 8, 0, 13, 0, 222, 147, 254, 31, 224, 0, 0,
|
||||||
|
1, 41, 74, 80, 0, 8, 0, 25, 0, 222, 67, 254, 31, 160, 0, 0, 1, 41, 74, 80, 0,
|
||||||
|
12, 0, 49, 0, 222, 19, 254, 62, 48, 0, 0, 1, 198, 113, 208, 0, 2, 0, 32, 128,
|
||||||
|
222, 195, 255, 252, 56, 0, 0, 0, 0, 0, 0, 0, 2, 0, 124, 64, 220, 151, 135, 248,
|
||||||
|
127, 0, 0, 0, 0, 0, 0, 0, 2, 0, 66, 32, 221, 223, 7, 240, 255, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 2, 0, 129, 23, 93, 159, 15, 241, 131, 0, 0, 0, 0, 0, 0, 0, 4, 0, 128,
|
||||||
|
136, 217, 95, 3, 226, 9, 0, 0, 1, 240, 0, 0, 0, 4, 0, 128, 72, 89, 95, 129,
|
||||||
|
228, 18, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0, 72, 73, 127, 128, 224, 36, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 28, 1, 0, 76, 129, 127, 192, 96, 8, 0, 0, 0, 0, 0, 0, 0, 16, 1, 0,
|
||||||
|
231, 203, 124, 96, 64, 0, 0, 0, 0, 0, 0, 0, 0, 16, 1, 1, 28, 123, 240, 12, 64,
|
||||||
|
1, 0, 0, 0, 0, 0, 0, 0, 16, 1, 2, 28, 143, 128, 15, 192, 7, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 16, 1, 4, 17, 143, 24, 15, 192, 14, 0, 0, 0, 0, 0, 0, 0, 28, 1, 4, 1, 135,
|
||||||
|
24, 31, 192, 24, 0, 0, 0, 0, 0, 0, 0, 18, 1, 62, 1, 135, 248, 63, 224, 192,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 35, 1, 195, 1, 135, 128, 254, 126, 1, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 35, 193, 131, 195, 135, 255, 248, 112, 1, 0, 0, 0, 0, 0, 0, 0, 67, 241, 131,
|
||||||
|
14, 207, 255, 192, 224, 3, 0, 0, 0, 0, 0, 0, 3, 67, 15, 143, 56, 255, 7, 1,
|
||||||
|
224, 7, 0, 0, 0, 0, 0, 0, 28, 130, 7, 255, 112, 204, 7, 131, 224, 31, 0, 0,
|
||||||
|
0, 0, 0, 0, 32, 134, 30, 29, 120, 156, 7, 255, 224, 127, 0, 0, 0, 0, 0, 63,
|
||||||
|
197, 206, 60, 56, 192, 248, 15, 255, 248, 255, 0, 0, 0, 0, 0, 120, 5, 227, 248,
|
||||||
|
56, 195, 248, 127, 191, 254, 63, 0, 0, 0, 0, 7, 254, 255, 193, 255, 15, 193,
|
||||||
|
255, 15, 31, 252, 31 };
|
||||||
|
|
||||||
|
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 = display_getCurrentVRAM()+(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 <../src/timer/timer_internals.h>
|
||||||
|
void debug(void)
|
||||||
|
{
|
||||||
|
extern Image res_screen_start;
|
||||||
|
struct mod_tmu *timer;
|
||||||
|
int time1, time2;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
timer_get(TIMER_USER, &timer, NULL);
|
||||||
|
|
||||||
|
dclear();
|
||||||
|
ML_bmp_or_cl(screen, 1, 1, 128, 64);
|
||||||
|
dupdate();
|
||||||
|
getkey();
|
||||||
|
|
||||||
|
dclear();
|
||||||
|
dimage(&res_screen_start, 1, 1);
|
||||||
|
dupdate();
|
||||||
|
getkey();
|
||||||
|
|
||||||
|
dclear();
|
||||||
|
dtext("ML...", 2, 2);
|
||||||
|
dupdate();
|
||||||
|
|
||||||
|
timer_start(TIMER_USER, 0x0fffffff, TIMER_Po_4, NULL, 0);
|
||||||
|
for(i = 0; i < 1000; i++) ML_bmp_or_cl(screen, 1, 1, 128, 64);
|
||||||
|
time1 = timer->TCNT;
|
||||||
|
timer_stop(TIMER_USER);
|
||||||
|
time1 = 0x0fffffff - time1;
|
||||||
|
|
||||||
|
dclear();
|
||||||
|
dtext("gint...", 2, 2);
|
||||||
|
dupdate();
|
||||||
|
|
||||||
|
timer_start(TIMER_USER, 0x0fffffff, TIMER_Po_4, NULL, 0);
|
||||||
|
for(i = 0; i < 1000; i++) dimage(&res_screen_start, 1, 1);
|
||||||
|
time2 = timer->TCNT;
|
||||||
|
timer_stop(TIMER_USER);
|
||||||
|
time2 = 0x0fffffff - time2;
|
||||||
|
|
||||||
|
dclear();
|
||||||
|
print_hex(time1, 2, 2);
|
||||||
|
print_hex(time2, 2, 9);
|
||||||
|
dupdate();
|
||||||
|
while(getkey() != KEY_EXIT);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
main()
|
main()
|
||||||
Handles application calls.
|
Handles application calls.
|
||||||
|
@ -371,10 +560,10 @@ int main_menu(void)
|
||||||
*/
|
*/
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
extern Font binary_resources_font_start;
|
extern Font res_font_start;
|
||||||
Font *font = &binary_resources_font_start;
|
Font *font = &res_font_start;
|
||||||
|
|
||||||
print_configure(font);
|
text_configure(font);
|
||||||
|
|
||||||
int app;
|
int app;
|
||||||
|
|
||||||
|
@ -387,6 +576,7 @@ int main(void)
|
||||||
if(app == 2) bitmap_test();
|
if(app == 2) bitmap_test();
|
||||||
if(app == 3) text_test();
|
if(app == 3) text_test();
|
||||||
if(app == 4) gray_test();
|
if(app == 4) gray_test();
|
||||||
|
if(app == 5) debug();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
BIN
demo/resources/screen.bmp
Normal file
BIN
demo/resources/screen.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
BIN
gintdemo.g1a
Normal file
BIN
gintdemo.g1a
Normal file
Binary file not shown.
|
@ -62,7 +62,7 @@ struct _st_rtc
|
||||||
gap(1);
|
gap(1);
|
||||||
|
|
||||||
union {
|
union {
|
||||||
unsigned char;
|
unsigned char BYTE;
|
||||||
struct {
|
struct {
|
||||||
unsigned :2;
|
unsigned :2;
|
||||||
unsigned TENS :2;
|
unsigned TENS :2;
|
||||||
|
@ -208,7 +208,7 @@ struct _st_rtc
|
||||||
struct {
|
struct {
|
||||||
unsigned ENB :1;
|
unsigned ENB :1;
|
||||||
unsigned :7;
|
unsigned :7;
|
||||||
}
|
};
|
||||||
} RCR3;
|
} RCR3;
|
||||||
|
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
// Heading declarations.
|
// Heading declarations.
|
||||||
//---
|
//---
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
#include <tales.h>
|
#include <tales.h>
|
||||||
|
|
||||||
enum Color
|
enum Color
|
||||||
|
@ -150,4 +151,45 @@ void dimage(struct Image *image, int x, int y);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Rectangle masks.
|
||||||
|
//
|
||||||
|
// The concept of 'rectangle masks' is used several times in this module.
|
||||||
|
// It is based on the fact that an operation that affects a rectangle acts
|
||||||
|
// the same on all its lines. Therefore the behavior of the operation is
|
||||||
|
// determined by its behavior on a single line, which is represented using
|
||||||
|
// 'masks' whose bits indicate whether a pixel is affected (1) or not (0).
|
||||||
|
//
|
||||||
|
// For example when clearing the screen rectangle (16, 16, 112, 48), the
|
||||||
|
// masks will represent information '16 to 112 on x-axis', and will hold
|
||||||
|
// the following values : 0000ffff, ffffffff, ffffffff and ffff0000. These
|
||||||
|
// masks can then be used by setting vram[offset] &= ~masks[i]. This
|
||||||
|
// appears to be very flexible : for instance, vram[offset] ^= masks[i]
|
||||||
|
// will reverse the pixels in the same rectangle.
|
||||||
|
//
|
||||||
|
// This technique can also be used in more subtle cases with more complex
|
||||||
|
// patterns, but within this module it is unlikely to happen.
|
||||||
|
//
|
||||||
|
//---
|
||||||
|
|
||||||
|
/*
|
||||||
|
adjustRectangle()
|
||||||
|
Adjusts the given rectangle coordinates to ensure that :
|
||||||
|
- the rectangle is entirely contained in the screen
|
||||||
|
- x1 < x2
|
||||||
|
- y1 < y2
|
||||||
|
which is needed when working with screen rectangles.
|
||||||
|
*/
|
||||||
|
void adjustRectangle(int *x1, int *y1, int *x2, int *y2);
|
||||||
|
|
||||||
|
/*
|
||||||
|
getMasks()
|
||||||
|
Computes the rectangle masks needed to affect pixels located between x1
|
||||||
|
and x2 (both included). The four masks are stored in the third argument
|
||||||
|
(seen as an array).
|
||||||
|
*/
|
||||||
|
void getMasks(int x1, int x2, uint32_t *masks);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // _DISPLAY_H
|
#endif // _DISPLAY_H
|
||||||
|
|
|
@ -60,6 +60,16 @@ void gray_getDelays(int *light, int *dark);
|
||||||
Finding values that give proper grays is quite the hard part of the
|
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
|
gray engine. Usual values are about 1000, with light being between 75
|
||||||
and 90% of dark.
|
and 90% of dark.
|
||||||
|
|
||||||
|
Typical values:
|
||||||
|
|
||||||
|
values stability stripes colors
|
||||||
|
---------------------------------------------------------
|
||||||
|
860, 1298 excellent worst static good
|
||||||
|
912, 1343 bad none very good
|
||||||
|
993, 1609 medium light fast good (default)
|
||||||
|
---------------------------------------------------------
|
||||||
|
|
||||||
*/
|
*/
|
||||||
void gray_setDelays(int light, int dark);
|
void gray_setDelays(int light, int dark);
|
||||||
|
|
||||||
|
|
|
@ -14,17 +14,12 @@ typedef unsigned int jmp_buf[16];
|
||||||
/*
|
/*
|
||||||
setjmp()
|
setjmp()
|
||||||
Configures a jump by saving data to the given jump buffer.
|
Configures a jump by saving data to the given jump buffer.
|
||||||
|
|
||||||
@arg env Empty jump buffer.
|
|
||||||
*/
|
*/
|
||||||
int setjmp(jmp_buf env);
|
int setjmp(jmp_buf env);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
longjmp()
|
longjmp()
|
||||||
Performs a long jump.
|
Performs a long jump.
|
||||||
|
|
||||||
@arg env Jump buffer configure with setjmp().
|
|
||||||
@arg value setjmp() will return this integer after the jump.
|
|
||||||
*/
|
*/
|
||||||
void longjmp(jmp_buf env, int value);
|
void longjmp(jmp_buf env, int value);
|
||||||
|
|
||||||
|
|
|
@ -34,15 +34,15 @@ void exit(int status);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
malloc()
|
malloc()
|
||||||
Allocs 'size' bytes and returns a pointer to a free memory area.
|
Allocates 'size' bytes and returns a pointer to a free memory area.
|
||||||
Returns NULL on error.
|
Returns NULL on error.
|
||||||
*/
|
*/
|
||||||
void *malloc(size_t size);
|
void *malloc(size_t size);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
calloc()
|
calloc()
|
||||||
Allocs 'n' elements of size 'size' and wipes the memory area. Returns
|
Allocates 'n' elements of size 'size' and wipes the memory area.
|
||||||
NULL on error.
|
Returns NULL on error.
|
||||||
*/
|
*/
|
||||||
void *calloc(size_t n, size_t size);
|
void *calloc(size_t n, size_t size);
|
||||||
|
|
||||||
|
|
|
@ -12,20 +12,12 @@
|
||||||
Copies a memory area. The two areas must not overlap (if they do, use
|
Copies a memory area. The two areas must not overlap (if they do, use
|
||||||
memmove()). A smart copy is performed when possible. To enhance
|
memmove()). A smart copy is performed when possible. To enhance
|
||||||
performance, make sure than destination and source are both 4-aligned.
|
performance, make sure than destination and source are both 4-aligned.
|
||||||
|
|
||||||
@arg destination
|
|
||||||
@arg source
|
|
||||||
@arg byte_number
|
|
||||||
*/
|
*/
|
||||||
void *memcpy(void *destination, const void *source, size_t byte_number);
|
void *memcpy(void *destination, const void *source, size_t byte_number);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
memset()
|
memset()
|
||||||
Sets the contents of a memory area. A smart copy is performed.
|
Sets the contents of a memory area. A smart copy is performed.
|
||||||
|
|
||||||
@arg area
|
|
||||||
@arg byte Byte to write in the area.
|
|
||||||
@arg byte_number
|
|
||||||
*/
|
*/
|
||||||
void *memset(void *destination, int byte, size_t byte_number);
|
void *memset(void *destination, int byte, size_t byte_number);
|
||||||
|
|
||||||
|
|
16
info
16
info
|
@ -1,16 +0,0 @@
|
||||||
|
|
||||||
Experimental power reduction as function of the keyboard analysis frequency.
|
|
||||||
|
|
||||||
SH3
|
|
||||||
None 0 %
|
|
||||||
4 Hz 2.8 %
|
|
||||||
16 Hz 2.8 %
|
|
||||||
64 Hz 2.8 %
|
|
||||||
256 Hz 20.0 %
|
|
||||||
|
|
||||||
SH4
|
|
||||||
None 0 %
|
|
||||||
4 Hz 1.8 %
|
|
||||||
16 Hz 1.8 %
|
|
||||||
64 Hz 1.8 %
|
|
||||||
256 Hz 3.6 %
|
|
BIN
libc.a
BIN
libc.a
Binary file not shown.
BIN
libgint.a
BIN
libgint.a
Binary file not shown.
|
@ -1,18 +1,22 @@
|
||||||
#include <bopti_internals.h>
|
#include <bopti_internals.h>
|
||||||
|
|
||||||
|
// Monochrome video ram, light and dark buffers (in this order).
|
||||||
|
int *vram, *v1, *v2;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
bopti_op()
|
bopti_op()
|
||||||
Operates on a vram long. The operator will often not contain 32 bits of
|
Operates on a vram long. The operator will often not contain 32 bits of
|
||||||
image information. Since neutral bits are not the same for all
|
image information. Since neutral bits are not the same for all
|
||||||
operations, the op_mask argument indicates which bits should be used
|
operations, a mask is used to indicate which bits should be used for
|
||||||
for the operation. Which operation has to be done is determined by the
|
the operation. This mask is taken for the image's rectangle masks (see
|
||||||
channel setting.
|
module display for more information on rectangle masks).
|
||||||
|
Which operation is performed is determined by the channel setting.
|
||||||
*/
|
*/
|
||||||
static void bopti_op_mono(int offset, uint32_t operator, uint32_t op_mask)
|
void bopti_op_mono(int offset, uint32_t operator, struct Command *c)
|
||||||
{
|
{
|
||||||
operator &= op_mask;
|
operator &= c->masks[offset & 3];
|
||||||
|
|
||||||
switch(channel)
|
switch(c->channel)
|
||||||
{
|
{
|
||||||
case Channel_Mono:
|
case Channel_Mono:
|
||||||
vram[offset] |= operator;
|
vram[offset] |= operator;
|
||||||
|
@ -26,11 +30,11 @@ static void bopti_op_mono(int offset, uint32_t operator, uint32_t op_mask)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void bopti_op_gray(int offset, uint32_t operator, uint32_t op_mask)
|
void bopti_op_gray(int offset, uint32_t operator, struct Command *c)
|
||||||
{
|
{
|
||||||
operator &= op_mask;
|
operator &= c->masks[offset & 3];
|
||||||
|
|
||||||
switch(channel)
|
switch(c->channel)
|
||||||
{
|
{
|
||||||
case Channel_Mono:
|
case Channel_Mono:
|
||||||
v1[offset] |= operator;
|
v1[offset] |= operator;
|
||||||
|
@ -66,74 +70,75 @@ static void bopti_op_gray(int offset, uint32_t operator, uint32_t op_mask)
|
||||||
because bopti_grid() will perform a 32-bit shift when x is a multiple
|
because bopti_grid() will perform a 32-bit shift when x is a multiple
|
||||||
of 32, which is undefined behavior.
|
of 32, which is undefined behavior.
|
||||||
*/
|
*/
|
||||||
static void bopti_grid_a32(const uint32_t *layer, int x, int y,
|
void bopti_grid_a32(const uint32_t *layer, int column_count, int height,
|
||||||
int column_count)
|
struct Command *c)
|
||||||
{
|
{
|
||||||
int vram_column_offset = (y << 2) + (x >> 5);
|
int vram_column_offset = (c->y << 2) + (c->x >> 5);
|
||||||
int vram_offset = vram_column_offset;
|
int vram_offset = vram_column_offset;
|
||||||
int column, row;
|
int column, row;
|
||||||
|
|
||||||
for(column = 0; column < column_count; column++)
|
for(column = 0; column < column_count; column++)
|
||||||
{
|
{
|
||||||
for(row = 0; row < height; row++)
|
for(row = c->top; row < c->bottom; row++)
|
||||||
{
|
{
|
||||||
(*op)(vram_offset, *layer, 0xffffffff);
|
(*c->op)(vram_offset, layer[row], c);
|
||||||
layer++;
|
|
||||||
vram_offset += 4;
|
vram_offset += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
vram_column_offset++;
|
vram_column_offset++;
|
||||||
vram_offset = vram_column_offset;
|
vram_offset = vram_column_offset;
|
||||||
|
layer += height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void bopti_grid(const uint32_t *layer, int x, int y, int column_count)
|
void bopti_grid(const uint32_t *layer, int column_count, int height,
|
||||||
|
struct Command *c)
|
||||||
{
|
{
|
||||||
if(!column_count) return;
|
if(!column_count) return;
|
||||||
if(!(x & 31))
|
if(!(c->x & 31))
|
||||||
{
|
{
|
||||||
bopti_grid_a32(layer, x, y, column_count);
|
bopti_grid_a32(layer, column_count, height, c);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t *p1, *p2;
|
const uint32_t *p1, *p2;
|
||||||
uint32_t l1, l2;
|
uint32_t l1, l2, operator;
|
||||||
int right_column, line;
|
int right_column, line;
|
||||||
|
|
||||||
int vram_column_offset = (y << 2) + (x >> 5);
|
int vram_column_offset = (c->y << 2) + (c->x >> 5) + (c->x < 0);
|
||||||
int vram_offset = vram_column_offset;
|
int vram_offset = vram_column_offset;
|
||||||
|
|
||||||
int shift1 = 32 - (x & 31);
|
int shift1 = 32 - (c->x & 31);
|
||||||
int shift2 = (x & 31);
|
int shift2 = (c->x & 31);
|
||||||
|
|
||||||
uint32_t operator, and_mask;
|
// Initializing two pointers. They will read two adjacent columns at
|
||||||
uint32_t and_mask_0 = 0xffffffff >> shift2;
|
// the same time (p2 is column ahead of p1). Since the columns are
|
||||||
uint32_t and_mask_1 = 0xffffffff << shift1;
|
// written one after another, incrementing them will suffice when
|
||||||
|
// reaching the end of two columns, to move them to the next ones.
|
||||||
// Initializing two pointers. Since the columns are written one after
|
|
||||||
// another, they will be updated directly to parse the whole grid.
|
|
||||||
p1 = layer - height;
|
p1 = layer - height;
|
||||||
p2 = layer;
|
p2 = layer;
|
||||||
|
|
||||||
// Drawing vram longwords, using pairs of columns.
|
// We don't want to write the first vram column when x is negative.
|
||||||
for(right_column = 0; right_column <= column_count; right_column++)
|
if(c->x < 0) p1 += height, p2 += height;
|
||||||
{
|
right_column = (c->x < 0);
|
||||||
and_mask = 0xffffffff;
|
|
||||||
if(right_column == 0) and_mask &= and_mask_0;
|
|
||||||
if(right_column == column_count) and_mask &= and_mask_1;
|
|
||||||
|
|
||||||
for(line = 0; line < height; line++)
|
// Drawing vram longwords, using pairs of columns.
|
||||||
|
while(right_column <= column_count)
|
||||||
{
|
{
|
||||||
l1 = (right_column > 0) ? (*p1) : (0);
|
for(line = c->top; line < c->bottom; line++)
|
||||||
l2 = (right_column < column_count) ? (*p2) : (0);
|
{
|
||||||
p1++, p2++;
|
l1 = (right_column > 0) ? p1[line] : (0);
|
||||||
|
l2 = (right_column < column_count) ? p2[line] : (0);
|
||||||
|
|
||||||
operator = (l1 << shift1) | (l2 >> shift2);
|
operator = (l1 << shift1) | (l2 >> shift2);
|
||||||
(*op)(vram_offset, operator, and_mask);
|
(*c->op)(vram_offset, operator, c);
|
||||||
vram_offset += 4;
|
vram_offset += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p1 += height;
|
||||||
|
p2 += height;
|
||||||
vram_column_offset++;
|
vram_column_offset++;
|
||||||
vram_offset = vram_column_offset;
|
vram_offset = vram_column_offset;
|
||||||
|
right_column++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,13 +149,13 @@ static void bopti_grid(const uint32_t *layer, int x, int y, int column_count)
|
||||||
is read and updated so that it points to the next line at the end of
|
is read and updated so that it points to the next line at the end of
|
||||||
the operation.
|
the operation.
|
||||||
*/
|
*/
|
||||||
static uint32_t bopti_end_get1(const unsigned char **data)
|
uint32_t bopti_end_get1(const unsigned char **data)
|
||||||
{
|
{
|
||||||
uint32_t operator = **data;
|
uint32_t operator = **data;
|
||||||
*data += 1;
|
*data += 1;
|
||||||
return operator;
|
return operator;
|
||||||
}
|
}
|
||||||
static uint32_t bopti_end_get2(const unsigned char **data)
|
uint32_t bopti_end_get2(const unsigned char **data)
|
||||||
{
|
{
|
||||||
uint32_t operator = *((uint16_t *)*data);
|
uint32_t operator = *((uint16_t *)*data);
|
||||||
*data += 2;
|
*data += 2;
|
||||||
|
@ -165,63 +170,57 @@ static uint32_t bopti_end_get2(const unsigned char **data)
|
||||||
whose with is lower than 32. (Actually is it lower or equal to 16;
|
whose with is lower than 32. (Actually is it lower or equal to 16;
|
||||||
otherwise it would have been a column and the end would be empty).
|
otherwise it would have been a column and the end would be empty).
|
||||||
*/
|
*/
|
||||||
static void bopti_end_nover(const unsigned char *end, int x, int y, int width)
|
void bopti_end_nover(const unsigned char *end, int size, struct Command *c)
|
||||||
{
|
{
|
||||||
uint32_t (*get)(const unsigned char **data) =
|
uint32_t (*get)(const unsigned char **data) =
|
||||||
(width > 8) ? bopti_end_get2 : bopti_end_get1;
|
(size == 2) ? bopti_end_get2 : bopti_end_get1;
|
||||||
|
|
||||||
int vram_offset = (y << 2) + (x >> 5);
|
|
||||||
int row;
|
|
||||||
|
|
||||||
// We *have* shift >= 0 because of this function's 'no overlap'
|
// We *have* shift >= 0 because of this function's 'no overlap'
|
||||||
// requirement.
|
// requirement.
|
||||||
int shift_base = (width > 8) ? 16 : 24;
|
int shift = (32 - (size << 3)) - (c->x & 31);
|
||||||
int shift = shift_base - (x & 31);
|
int vram_offset = (c->y << 2) + (c->x >> 5);
|
||||||
|
|
||||||
uint32_t and_mask = (0xffffffff << (32 - width)) >> (x & 31);
|
|
||||||
uint32_t operator;
|
uint32_t operator;
|
||||||
|
int row;
|
||||||
|
|
||||||
for(row = 0; row < height; row++)
|
// Skipping c->top lines (because get() function only allows sequential
|
||||||
|
// access).
|
||||||
|
end += c->top * size;
|
||||||
|
|
||||||
|
for(row = c->top; row < c->bottom; row++)
|
||||||
{
|
{
|
||||||
operator = (*get)(&end);
|
operator = (*get)(&end);
|
||||||
operator <<= shift;
|
operator <<= shift;
|
||||||
|
|
||||||
(*op)(vram_offset, operator, and_mask);
|
(*c->op)(vram_offset, operator, c);
|
||||||
vram_offset += 4;
|
vram_offset += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void bopti_end(const unsigned char *end, int x, int y, int width)
|
void bopti_end(const unsigned char *end, int size, struct Command *c)
|
||||||
{
|
{
|
||||||
if((x & 31) + width <= 32)
|
|
||||||
{
|
|
||||||
bopti_end_nover(end, x, y, width);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t (*get)(const unsigned char **data) =
|
uint32_t (*get)(const unsigned char **data) =
|
||||||
(width > 8) ? (bopti_end_get2) : (bopti_end_get1);
|
(size == 2) ? (bopti_end_get2) : (bopti_end_get1);
|
||||||
|
|
||||||
int vram_offset = (y << 2) + (x >> 5);
|
int vram_offset = (c->y << 2) + (c->x >> 5);
|
||||||
|
uint32_t row_data, operator;
|
||||||
int row;
|
int row;
|
||||||
|
|
||||||
int shift_base = (width > 8) ? 16 : 24;
|
int shift_base = (32 - (size << 3));
|
||||||
int shift1 = (x & 31) - shift_base;
|
int shift1 = (c->x & 31) - shift_base;
|
||||||
int shift2 = shift_base + 32 - (x & 31);
|
int shift2 = shift_base + 32 - (c-> x & 31);
|
||||||
|
|
||||||
uint32_t and_mask_0 = 0xffffffff >> (x & 31);
|
// Skipping c->top lines (because get() function only allows sequential
|
||||||
uint32_t and_mask_1 = 0xffffffff << (64 - width - (x & 31));
|
// access).
|
||||||
|
end += c->top * size;
|
||||||
|
|
||||||
uint32_t row_data, operator;
|
for(row = c->top; row < c->bottom; row++)
|
||||||
|
|
||||||
for(row = 0; row < height; row++)
|
|
||||||
{
|
{
|
||||||
row_data = (*get)(&end);
|
row_data = (*get)(&end);
|
||||||
|
|
||||||
operator = row_data >> shift1;
|
operator = row_data >> shift1;
|
||||||
(*op)(vram_offset, operator, and_mask_0);
|
(*c->op)(vram_offset, operator, c);
|
||||||
|
|
||||||
operator = row_data << shift2;
|
operator = row_data << shift2;
|
||||||
(*op)(vram_offset + 1, operator, and_mask_1);
|
(*c->op)(vram_offset + 1, operator, c);
|
||||||
|
|
||||||
vram_offset += 4;
|
vram_offset += 4;
|
||||||
}
|
}
|
||||||
|
@ -237,41 +236,63 @@ static void bopti_end(const unsigned char *end, int x, int y, int width)
|
||||||
bopti()
|
bopti()
|
||||||
Draws a layer in the video ram.
|
Draws a layer in the video ram.
|
||||||
*/
|
*/
|
||||||
static void bopti(const unsigned char *layer, int x, int y, int columns,
|
void bopti(const unsigned char *layer, struct Structure *s, struct Command *c)
|
||||||
int end_size)
|
|
||||||
{
|
{
|
||||||
const unsigned char *end = layer + ((columns * height) << 2);
|
const unsigned char *grid, *end;
|
||||||
int end_x = x + (columns << 5);
|
int grid_columns, has_end;
|
||||||
|
|
||||||
bopti_grid((const uint32_t *)layer, x, y, columns);
|
// Skipping columns at the beginning.
|
||||||
if(end_size) bopti_end(end, end_x, y, end_size);
|
grid = layer + ((c->left * s->height) << 2);
|
||||||
|
|
||||||
|
// Updating the command arguments to eliminate some information about
|
||||||
|
// parts that are not being drawn.
|
||||||
|
c->x += (c->left << 5);
|
||||||
|
c->y += c->top;
|
||||||
|
|
||||||
|
// Columns are identified by ids 0 to s->columns - 1, and the end has
|
||||||
|
// id s->columns. So the end is drawn if this last column is included.
|
||||||
|
has_end = (c->right == s->columns);
|
||||||
|
// Computing number of grid columns to draw.
|
||||||
|
grid_columns = c->right - c->left + 1 - has_end;
|
||||||
|
|
||||||
|
bopti_grid((const uint32_t *)grid, grid_columns, s->height, c);
|
||||||
|
|
||||||
|
if(has_end)
|
||||||
|
{
|
||||||
|
end = layer + ((s->columns * s->height) << 2);
|
||||||
|
c->x += (grid_columns << 5);
|
||||||
|
|
||||||
|
if((c->x & 31) + s->end_size <= 32)
|
||||||
|
bopti_end_nover(end, s->end_bytes, c);
|
||||||
|
else
|
||||||
|
bopti_end(end, s->end_bytes, c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
getStructure()
|
getStructure()
|
||||||
Determines the image size and data pointer.
|
Determines the image size and data pointer.
|
||||||
*/
|
*/
|
||||||
static void getStructure(struct Image *img, int *width, int *height,
|
void getStructure(struct Image *img, struct Structure *s)
|
||||||
int *layer_size, const unsigned char **data, int *columns,
|
|
||||||
int *end_size)
|
|
||||||
{
|
{
|
||||||
int column_count, end, end_bytes, layer;
|
int column_count, end, end_bytes, layer;
|
||||||
|
|
||||||
// Large images.
|
// Large images.
|
||||||
if(!img->width && !img->height)
|
if(!img->width && !img->height)
|
||||||
{
|
{
|
||||||
if(width) *width = (img->data[0] << 8) | img->data[1];
|
s->width = (img->data[0] << 8) | img->data[1];
|
||||||
if(height) *height = (img->data[2] << 8) | img->data[3];
|
s->height = (img->data[2] << 8) | img->data[3];
|
||||||
if(data) *data = img->data + 4;
|
s->data = img->data + 4;
|
||||||
|
|
||||||
column_count = (*width + 31) >> 5;
|
column_count = (s->width + 31) >> 5;
|
||||||
end = end_bytes = 0;
|
end = 0;
|
||||||
|
end_bytes = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(width) *width = img->width;
|
s->width = img->width;
|
||||||
if(height) *height = img->height;
|
s->height = img->height;
|
||||||
if(data) *data = img->data;
|
s->data = img->data;
|
||||||
|
|
||||||
column_count = img->width >> 5;
|
column_count = img->width >> 5;
|
||||||
end = img->width & 31;
|
end = img->width & 31;
|
||||||
|
@ -280,13 +301,21 @@ static void getStructure(struct Image *img, int *width, int *height,
|
||||||
end <= 8 ? 1 :
|
end <= 8 ? 1 :
|
||||||
end <= 16 ? 2 :
|
end <= 16 ? 2 :
|
||||||
4;
|
4;
|
||||||
|
|
||||||
|
if(end_bytes == 4)
|
||||||
|
{
|
||||||
|
column_count++;
|
||||||
|
end = 0;
|
||||||
|
end_bytes = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The layer size must be rounded to a multiple of 4.
|
// The layer size must be rounded to a multiple of 4.
|
||||||
layer = img->height * ((column_count << 2) + end_bytes);
|
layer = img->height * ((column_count << 2) + end_bytes);
|
||||||
if(layer & 3) layer += 4 - (layer & 3);
|
if(layer & 3) layer += 4 - (layer & 3);
|
||||||
|
|
||||||
if(columns) *columns = column_count;
|
s->columns = column_count;
|
||||||
if(end_size) *end_size = end;
|
s->end_bytes = end_bytes;
|
||||||
if(layer_size) *layer_size = layer;
|
s->end_size = end;
|
||||||
|
s->layer_size = layer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#define _BOPTI_INTERNALS_H 1
|
#define _BOPTI_INTERNALS_H 1
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <display.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
enum Channel
|
enum Channel
|
||||||
|
@ -49,15 +50,43 @@ enum Format
|
||||||
Channel_DarkAlpha
|
Channel_DarkAlpha
|
||||||
};
|
};
|
||||||
|
|
||||||
// The following variables refer to parameters that do not change during the
|
/*
|
||||||
// drawing operation (at least for the time of a layer). They could be passed
|
struct Structure
|
||||||
// on by every function from the module, but this would be heavy and useless.
|
Describes an image's structure.
|
||||||
// Using global variables is not really a proper solution but it does simplify
|
*/
|
||||||
// code much.
|
struct Structure
|
||||||
|
{
|
||||||
|
int width, height;
|
||||||
|
int layer_size;
|
||||||
|
|
||||||
|
const unsigned char *data;
|
||||||
|
int columns;
|
||||||
|
int end_size, end_bytes;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
struct Command
|
||||||
|
Contains a drawing operation's parameters.
|
||||||
|
*/
|
||||||
|
struct Command
|
||||||
|
{
|
||||||
|
// Channel being drawn.
|
||||||
|
enum Channel channel;
|
||||||
|
// Operation used (whether bopti_op_mono() or bopti_op_gray()).
|
||||||
|
void (*op)(int offset, uint32_t operator, struct Command *command);
|
||||||
|
// Portion of the bitmap which is drawn. 'top' and 'bottom' refer to
|
||||||
|
// lines where 'left' and 'right' refer to column ids.
|
||||||
|
int left, right, top, bottom;
|
||||||
|
// Position of the bitmap on the screen.
|
||||||
|
int x, y;
|
||||||
|
// Rectangle masks.
|
||||||
|
uint32_t masks[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
// The video ram addresses are set by the public functions and used internally
|
||||||
|
// by the module.
|
||||||
|
// Monochrome video ram, light and dark buffers (in this order).
|
||||||
extern int *vram, *v1, *v2;
|
extern int *vram, *v1, *v2;
|
||||||
extern enum Channel channel;
|
|
||||||
extern int height;
|
|
||||||
extern void (*op)(int offset, uint32_t operator, uint32_t op_mask);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,12 +98,13 @@ extern void (*op)(int offset, uint32_t operator, uint32_t op_mask);
|
||||||
bopti_op()
|
bopti_op()
|
||||||
Operates on a vram long. The operator will often not contain 32 bits of
|
Operates on a vram long. The operator will often not contain 32 bits of
|
||||||
image information. Since neutral bits are not the same for all
|
image information. Since neutral bits are not the same for all
|
||||||
operations, the op_mask argument indicates which bits should be used
|
operations, a mask is used to indicate which bits should be used for
|
||||||
for the operation. Which operation has to be done is determined by the
|
the operation. This mask is taken for the image's rectangle masks (see
|
||||||
channel setting.
|
module display for more information on rectangle masks).
|
||||||
|
Which operation is performed is determined by the channel setting.
|
||||||
*/
|
*/
|
||||||
void bopti_op_mono(int offset, uint32_t operator, uint32_t op_mask);
|
void bopti_op_mono(int offset, uint32_t operator, struct Command *c);
|
||||||
void bopti_op_gray(int offset, uint32_t operator, uint32_t op_mask);
|
void bopti_op_gray(int offset, uint32_t operator, struct Command *c);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
bopti_grid() -- general form
|
bopti_grid() -- general form
|
||||||
|
@ -85,10 +115,12 @@ void bopti_op_gray(int offset, uint32_t operator, uint32_t op_mask);
|
||||||
The need for bopti_grid_a32() is not only linked to optimization,
|
The need for bopti_grid_a32() is not only linked to optimization,
|
||||||
because bopti_grid() will perform a 32-bit shift when x is a multiple
|
because bopti_grid() will perform a 32-bit shift when x is a multiple
|
||||||
of 32, which is undefined behavior.
|
of 32, which is undefined behavior.
|
||||||
|
bopti_grid() calls bopti_grid_32() by default.
|
||||||
*/
|
*/
|
||||||
void bopti_grid_a32(const uint32_t *layer, int x, int y, int column_count);
|
void bopti_grid_a32(const uint32_t *layer, int columns, int height,
|
||||||
void bopti_grid(const uint32_t *layer, int x, int y, int column_count);
|
struct Command *c);
|
||||||
|
void bopti_grid(const uint32_t *layer, int columns, int height,
|
||||||
|
struct Command *c);
|
||||||
/*
|
/*
|
||||||
bopti_end_get()
|
bopti_end_get()
|
||||||
Returns an operator for the end of a line, whose width is lower than 32
|
Returns an operator for the end of a line, whose width is lower than 32
|
||||||
|
@ -105,23 +137,24 @@ uint32_t bopti_end_get2(const unsigned char **data);
|
||||||
|
|
||||||
Draws the end of a layer, which can be considered as a whole layer
|
Draws the end of a layer, which can be considered as a whole layer
|
||||||
whose with is lower than 32. (Actually is it lower or equal to 16;
|
whose with is lower than 32. (Actually is it lower or equal to 16;
|
||||||
otherwise it would have been a column and the end would be empty).
|
otherwise it would have been a column and the end would be empty). The
|
||||||
|
'size' arguments is in bytes.
|
||||||
|
Unlike bopti_grid_a32(), bopti_end_nover() is not called automatically
|
||||||
|
by bopti_end().
|
||||||
*/
|
*/
|
||||||
void bopti_end_nover(const unsigned char *end, int x, int y, int width);
|
void bopti_end_nover(const unsigned char *end, int size, struct Command *c);
|
||||||
void bopti_end(const unsigned char *end, int x, int y, int width);
|
void bopti_end(const unsigned char *end, int size, struct Command *c);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
bopti()
|
bopti()
|
||||||
Draws a layer in the video ram.
|
Draws a layer in the video ram.
|
||||||
*/
|
*/
|
||||||
void bopti(const unsigned char *layer, int x, int y, int columns,
|
void bopti(const unsigned char *layer, struct Structure *s, struct Command *c);
|
||||||
int end_size);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
getStructure()
|
getStructure()
|
||||||
Determines the image size and data pointer.
|
Determines the image size and data pointer.
|
||||||
*/
|
*/
|
||||||
void getStructure(struct Image *img, int *width, int *height, int *layer_size,
|
void getStructure(struct Image *img, struct Structure *structure);
|
||||||
const unsigned char **data, int *columns, int *end_size);
|
|
||||||
|
|
||||||
#endif // _BOPTI_INTERNALS_H
|
#endif // _BOPTI_INTERNALS_H
|
||||||
|
|
|
@ -7,17 +7,33 @@
|
||||||
*/
|
*/
|
||||||
void dimage(struct Image *img, int x, int y)
|
void dimage(struct Image *img, int x, int y)
|
||||||
{
|
{
|
||||||
int width, layer_size, columns, end;
|
|
||||||
int format = img->format, i = 0;
|
|
||||||
const unsigned char *data;
|
|
||||||
|
|
||||||
if(img->magic != 0xb7) return;
|
if(img->magic != 0xb7) return;
|
||||||
if(img->format != Format_Mono && img->format != Format_MonoAlpha)
|
|
||||||
return;
|
|
||||||
op = bopti_op_mono;
|
|
||||||
|
|
||||||
// 'height' refers to a static variable for this file.
|
struct Structure s;
|
||||||
getStructure(img, &width, &height, &layer_size, &data, &columns, &end);
|
struct Command command;
|
||||||
|
int actual_width;
|
||||||
|
int format = img->format, i = 0;
|
||||||
|
|
||||||
|
if(format != Format_Mono && format != Format_MonoAlpha) return;
|
||||||
|
getStructure(img, &s);
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Adjusting image parameters.
|
||||||
|
//---
|
||||||
|
|
||||||
|
if(x + s.width < 0 || x > 127 || y + s.height < 0 || y > 63) return;
|
||||||
|
|
||||||
|
command.top = (y < 0) ? (-y) : (0);
|
||||||
|
command.bottom = (y + s.height > 64) ? (64 - y) : (s.height);
|
||||||
|
command.left = ((x < 0) ? (-x) : (0)) >> 5;
|
||||||
|
actual_width = (x + s.width > 128) ? (128 - x) : (s.width);
|
||||||
|
command.right = ((actual_width + 31) >> 5) - 1;
|
||||||
|
|
||||||
|
command.x = x;
|
||||||
|
command.y = y;
|
||||||
|
command.op = bopti_op_mono;
|
||||||
|
|
||||||
|
getMasks(x, x + actual_width - 1, command.masks);
|
||||||
|
|
||||||
vram = display_getCurrentVRAM();
|
vram = display_getCurrentVRAM();
|
||||||
|
|
||||||
|
@ -26,9 +42,9 @@ void dimage(struct Image *img, int x, int y)
|
||||||
// Drawing every layer, in order of formats.
|
// Drawing every layer, in order of formats.
|
||||||
if(format & 1)
|
if(format & 1)
|
||||||
{
|
{
|
||||||
channel = (1 << i);
|
command.channel = (1 << i);
|
||||||
bopti(data, x, y, columns, end);
|
bopti(s.data, &s, &command);
|
||||||
data += layer_size;
|
s.data += s.layer_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
format >>= 1;
|
format >>= 1;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include <bopti_internals.h>
|
#include <bopti_internals.h>
|
||||||
|
#include <display.h>
|
||||||
#include <gray.h>
|
#include <gray.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -7,15 +8,31 @@
|
||||||
*/
|
*/
|
||||||
void gimage(struct Image *img, int x, int y)
|
void gimage(struct Image *img, int x, int y)
|
||||||
{
|
{
|
||||||
int width, layer_size, columns, end;
|
|
||||||
int format = img->format, i = 0;
|
|
||||||
const unsigned char *data;
|
|
||||||
|
|
||||||
if(img->magic != 0xb7) return;
|
if(img->magic != 0xb7) return;
|
||||||
op = bopti_op_gray;
|
|
||||||
|
|
||||||
// 'height' refers to a static variable for this file.
|
struct Structure s;
|
||||||
getStructure(img, &width, &height, &layer_size, &data, &columns, &end);
|
struct Command command;
|
||||||
|
int actual_width;
|
||||||
|
int format = img->format, i = 0;
|
||||||
|
|
||||||
|
getStructure(img, &s);
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Adjusting image parameters.
|
||||||
|
//---
|
||||||
|
//-65:-68
|
||||||
|
if(x + s.width < 0 || x > 127 || y + s.height < 0 || y > 63) return;
|
||||||
|
|
||||||
|
command.top = (y < 0) ? (-y) : (0);
|
||||||
|
command.bottom = (y + s.height > 64) ? (64 - y) : (s.height);
|
||||||
|
command.left = ((x < 0) ? (-x) : (0)) >> 5;
|
||||||
|
actual_width = (x + s.width > 128) ? (128 - x) : (s.width);
|
||||||
|
command.right = ((actual_width + 31) >> 5) - 1;
|
||||||
|
|
||||||
|
command.op = bopti_op_gray;
|
||||||
|
|
||||||
|
if(x >= 0) getMasks(x, x + actual_width - 1, command.masks);
|
||||||
|
else getMasks(0, actual_width + x - 1, command.masks);
|
||||||
|
|
||||||
v1 = gray_lightVRAM();
|
v1 = gray_lightVRAM();
|
||||||
v2 = gray_darkVRAM();
|
v2 = gray_darkVRAM();
|
||||||
|
@ -25,9 +42,13 @@ void gimage(struct Image *img, int x, int y)
|
||||||
// Drawing every layer, in order of formats.
|
// Drawing every layer, in order of formats.
|
||||||
if(format & 1)
|
if(format & 1)
|
||||||
{
|
{
|
||||||
channel = (1 << i);
|
// These members are modified by bopti()!
|
||||||
bopti(data, x, y, columns, end);
|
command.x = x;
|
||||||
data += layer_size;
|
command.y = y;
|
||||||
|
command.channel = (1 << i);
|
||||||
|
|
||||||
|
bopti(s.data, &s, &command);
|
||||||
|
s.data += s.layer_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
format >>= 1;
|
format >>= 1;
|
||||||
|
|
|
@ -53,8 +53,8 @@ int start(void)
|
||||||
__GLibAddinAplExecutionCheck(0, 1, 1);
|
__GLibAddinAplExecutionCheck(0, 1, 1);
|
||||||
|
|
||||||
// Initializing everything.
|
// Initializing everything.
|
||||||
init();
|
|
||||||
gint_init();
|
gint_init();
|
||||||
|
init();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,8 +69,8 @@ int start(void)
|
||||||
// Remember to flush and close opened streams.
|
// Remember to flush and close opened streams.
|
||||||
|
|
||||||
// Un-initializing everything.
|
// Un-initializing everything.
|
||||||
gint_quit();
|
|
||||||
fini();
|
fini();
|
||||||
|
gint_quit();
|
||||||
|
|
||||||
return exit_code;
|
return exit_code;
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,6 +91,11 @@ void gint_init(void)
|
||||||
unsigned int *ptr = &bgint;
|
unsigned int *ptr = &bgint;
|
||||||
unsigned int *src = &gint_data;
|
unsigned int *src = &gint_data;
|
||||||
|
|
||||||
|
// This initialization routine is usually called before any
|
||||||
|
// constructor. We want to ensure that the MPU type is detected, but
|
||||||
|
// mpu_init() hasn't been called yet.
|
||||||
|
mpu_init();
|
||||||
|
|
||||||
// Loading the interrupt handler into the memory.
|
// Loading the interrupt handler into the memory.
|
||||||
while(ptr < &egint) *ptr++ = *src++;
|
while(ptr < &egint) *ptr++ = *src++;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include <gint.h>
|
#include <gint.h>
|
||||||
#include <mpu.h>
|
#include <mpu.h>
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
static void (*rtc_callback)(void) = NULL;
|
static void (*rtc_callback)(void) = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*/
|
*/
|
||||||
void dclear_area(int x1, int y1, int x2, int y2)
|
void dclear_area(int x1, int y1, int x2, int y2)
|
||||||
{
|
{
|
||||||
unsigned int masks[4];
|
uint32_t masks[4];
|
||||||
adjustRectangle(&x1, &y1, &x2, &y2);
|
adjustRectangle(&x1, &y1, &x2, &y2);
|
||||||
getMasks(x1, x2, masks);
|
getMasks(x1, x2, masks);
|
||||||
|
|
||||||
|
|
|
@ -4,25 +4,6 @@
|
||||||
//
|
//
|
||||||
// Handles vram manipulation and drawing.
|
// Handles vram manipulation and drawing.
|
||||||
//
|
//
|
||||||
//
|
|
||||||
// :: Rectangle masks
|
|
||||||
//
|
|
||||||
// The concept of 'rectangle masks' is used several times in this module.
|
|
||||||
// It is based on the fact that an operation that affects a rectangle acts
|
|
||||||
// the same on all its lines. Therefore the behavior of the operation is
|
|
||||||
// determined by its behavior on a single line, which is represented using
|
|
||||||
// 'masks' whose bits indicate whether a pixel is affected (1) or not (0).
|
|
||||||
//
|
|
||||||
// For example when clearing the screen rectangle (16, 16, 112, 48), the
|
|
||||||
// masks will represent information '16 to 112 on x-axis', and will hold
|
|
||||||
// the following values : 0000ffff, ffffffff, ffffffff and ffff0000. These
|
|
||||||
// masks can then be used by setting vram[offset] &= ~masks[i]. This
|
|
||||||
// appears to be very flexible : for instance, vram[offset] ^= masks[i]
|
|
||||||
// will reverse the pixels in the same rectangle.
|
|
||||||
//
|
|
||||||
// This technique can also be used in more subtle cases with more complex
|
|
||||||
// patterns, but within this module it is unlikely to happen.
|
|
||||||
//
|
|
||||||
//---
|
//---
|
||||||
|
|
||||||
#ifndef _DISPLAY_INTERNALS_H
|
#ifndef _DISPLAY_INTERNALS_H
|
||||||
|
@ -30,23 +11,4 @@
|
||||||
|
|
||||||
extern int *vram;
|
extern int *vram;
|
||||||
|
|
||||||
/*
|
|
||||||
adjustRectangle()
|
|
||||||
Adjusts the given rectangle coordinates to ensure that :
|
|
||||||
- the rectangle is entirely contained in the screen
|
|
||||||
- x1 < x2
|
|
||||||
- y1 < y2
|
|
||||||
which is needed when working with screen rectangles.
|
|
||||||
*/
|
|
||||||
static void adjustRectangle(int *x1, int *y1, int *x2, int *y2);
|
|
||||||
|
|
||||||
/*
|
|
||||||
getMasks()
|
|
||||||
Computes the rectangle masks needed to affect pixels located between x1
|
|
||||||
and x2 (both included). The four masks are stored in the third argument
|
|
||||||
(seen as an array).
|
|
||||||
See this module's internals header file for more information.
|
|
||||||
*/
|
|
||||||
static void getMasks(int x1, int x2, unsigned int *masks);
|
|
||||||
|
|
||||||
#endif // _DISPLAY_INTERNALS_H
|
#endif // _DISPLAY_INTERNALS_H
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
static void dhline(int x1, int x2, int y, enum Color color)
|
static void dhline(int x1, int x2, int y, enum Color color)
|
||||||
{
|
{
|
||||||
unsigned int masks[4];
|
uint32_t masks[4];
|
||||||
int offset = y << 2;
|
int offset = y << 2;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
*/
|
*/
|
||||||
void dreverse_area(int x1, int y1, int x2, int y2)
|
void dreverse_area(int x1, int y1, int x2, int y2)
|
||||||
{
|
{
|
||||||
unsigned int masks[4];
|
uint32_t masks[4];
|
||||||
adjustRectangle(&x1, &y1, &x2, &y2);
|
adjustRectangle(&x1, &y1, &x2, &y2);
|
||||||
getMasks(x1, x2, masks);
|
getMasks(x1, x2, masks);
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
#include <display_internals.h>
|
#include <display.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
getMasks()
|
getMasks()
|
||||||
Computes the rectangle masks needed to affect pixels located between x1
|
Computes the rectangle masks needed to affect pixels located between x1
|
||||||
and x2 (both included). The four masks are stored in the third argument
|
and x2 (both included). The four masks are stored in the third argument
|
||||||
(seen as an array).
|
(seen as an array).
|
||||||
See this module's internals header file for more information.
|
|
||||||
*/
|
*/
|
||||||
void getMasks(int x1, int x2, unsigned int *masks)
|
void getMasks(int x1, int x2, uint32_t *masks)
|
||||||
{
|
{
|
||||||
// Indexes of the first and last longs that are non-blank.
|
// Indexes of the first and last longs that are non-blank.
|
||||||
int l1 = x1 >> 5;
|
int l1 = x1 >> 5;
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include <timer.h>
|
#include <timer.h>
|
||||||
|
|
||||||
static int internal_vrams[3][256];
|
static int internal_vrams[3][256];
|
||||||
const void *vrams[4];
|
static const void *vrams[4];
|
||||||
|
|
||||||
static int current = 0;
|
static int current = 0;
|
||||||
static int delays[2];
|
static int delays[2];
|
||||||
|
@ -33,7 +33,10 @@ static int runs = 0;
|
||||||
*/
|
*/
|
||||||
void gray_start(void)
|
void gray_start(void)
|
||||||
{
|
{
|
||||||
|
if(runs) return;
|
||||||
|
|
||||||
timer_start(TIMER_GRAY, delays[0], GRAY_PRESCALER, gray_interrupt, 0);
|
timer_start(TIMER_GRAY, delays[0], GRAY_PRESCALER, gray_interrupt, 0);
|
||||||
|
current &= 1;
|
||||||
runs = 1;
|
runs = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,6 +47,8 @@ void gray_start(void)
|
||||||
*/
|
*/
|
||||||
void gray_stop(void)
|
void gray_stop(void)
|
||||||
{
|
{
|
||||||
|
if(!runs) return;
|
||||||
|
|
||||||
timer_stop(TIMER_GRAY);
|
timer_stop(TIMER_GRAY);
|
||||||
runs = 0;
|
runs = 0;
|
||||||
|
|
||||||
|
@ -79,18 +84,18 @@ inline int gray_runs(void)
|
||||||
gray_lightVRAM()
|
gray_lightVRAM()
|
||||||
Returns the module's gray vram address.
|
Returns the module's gray vram address.
|
||||||
*/
|
*/
|
||||||
inline void *gray_lightVRAM(void)
|
void *gray_lightVRAM(void)
|
||||||
{
|
{
|
||||||
return (void *)vrams[current & 2];
|
return (void *)vrams[~current & 2];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
gray_lightVRAM()
|
gray_lightVRAM()
|
||||||
Returns the module's dark vram address.
|
Returns the module's dark vram address.
|
||||||
*/
|
*/
|
||||||
inline void *gray_darkVRAM(void)
|
void *gray_darkVRAM(void)
|
||||||
{
|
{
|
||||||
return (void *)vrams[(current & 2) | 1];
|
return (void *)vrams[(~current & 2) | 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -130,7 +135,7 @@ inline void gupdate(void)
|
||||||
*/
|
*/
|
||||||
void gray_interrupt(void)
|
void gray_interrupt(void)
|
||||||
{
|
{
|
||||||
timer_reload(TIMER_GRAY, delays[current & 1]);
|
timer_reload(TIMER_GRAY, delays[(~current) & 1]);
|
||||||
screen_display(vrams[current]);
|
screen_display(vrams[current]);
|
||||||
current ^= 1;
|
current ^= 1;
|
||||||
}
|
}
|
||||||
|
@ -146,6 +151,6 @@ void gray_init(void)
|
||||||
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] = 900;
|
delays[0] = 993;
|
||||||
delays[1] = 1000;
|
delays[1] = 1609;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
// Keyboard variables.
|
// Keyboard variables.
|
||||||
extern volatile unsigned char keyboard_state[10];
|
extern volatile unsigned char keyboard_state[10];
|
||||||
extern volatile int interrupt_flag = 0;
|
extern volatile int interrupt_flag;
|
||||||
|
|
||||||
// Key statistics.
|
// Key statistics.
|
||||||
extern int repeat_first, repeat_next;
|
extern int repeat_first, repeat_next;
|
||||||
|
|
|
@ -42,8 +42,7 @@ void keyboard_interrupt(void)
|
||||||
*/
|
*/
|
||||||
void keyboard_init(void)
|
void keyboard_init(void)
|
||||||
{
|
{
|
||||||
timer_start(TIMER_KEYBOARD, 1700, TIMER_Po_256, keyboard_interrupt,
|
timer_start(TIMER_KEYBOARD, 1700, TIMER_Po_256, keyboard_interrupt, 0);
|
||||||
0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
14
src/tales/gtext.c
Normal file
14
src/tales/gtext.c
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#include <tales.h>
|
||||||
|
#include <gray.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
gtext()
|
||||||
|
Prints the given raw string.
|
||||||
|
*/
|
||||||
|
void gtext(const char *str, int x, int y)
|
||||||
|
{
|
||||||
|
display_useVRAM(gray_lightVRAM());
|
||||||
|
dtext(str, x, y);
|
||||||
|
display_useVRAM(gray_darkVRAM());
|
||||||
|
dtext(str, x, y);
|
||||||
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
text_configure()
|
text_configure()
|
||||||
Sets the font and mode to use for the following print operations.
|
Sets the font and mode to use for the following print operations.
|
||||||
*/
|
*/
|
||||||
void text_configure(struct Font *font)
|
void text_configure(struct Font *next_font)
|
||||||
{
|
{
|
||||||
font = next_font;
|
font = next_font;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include <timer.h>
|
#include <timer.h>
|
||||||
#include <timer_internals.h>
|
#include <timer_internals.h>
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
struct Timer timers[3] = { { NULL, 0 }, { NULL, 0 }, { NULL, 0 } };
|
struct Timer timers[3] = { { NULL, 0 }, { NULL, 0 }, { NULL, 0 } };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -9,7 +11,6 @@ struct Timer timers[3] = { { NULL, 0 }, { NULL, 0 }, { NULL, 0 } };
|
||||||
*/
|
*/
|
||||||
void timer_interrupt(int timer)
|
void timer_interrupt(int timer)
|
||||||
{
|
{
|
||||||
// Getting the timer address.
|
|
||||||
struct mod_tmu *tmu;
|
struct mod_tmu *tmu;
|
||||||
timer_get(timer, &tmu, NULL);
|
timer_get(timer, &tmu, NULL);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include <timer.h>
|
#include <timer.h>
|
||||||
#include <timer_internals.h>
|
#include <timer_internals.h>
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
timer_stop()
|
timer_stop()
|
||||||
Stops the given timer. This function may be called even if the timer is
|
Stops the given timer. This function may be called even if the timer is
|
||||||
|
|
Loading…
Reference in a new issue