first commit

This commit is contained in:
valeh
2020-12-22 14:30:09 +02:00
commit 26b0ba5954
1832 changed files with 17777948 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) main.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

View File

@@ -0,0 +1,243 @@
#include "u8x8.h"
u8x8_t u8x8;
char *s = "ABC defg";
int main(void)
{
u8x8_Setup_SDL_128x64(&u8x8);
u8x8_InitDisplay(&u8x8);
puts("u8x8_font_px437wyse700b_2x2_r, u8x8_font_px437wyse700a_2x2_r");
u8x8_SetFont(&u8x8, u8x8_font_px437wyse700b_2x2_r);
u8x8_SetInverseFont(&u8x8, 0);
u8x8_DrawString(&u8x8, 0, 0, s);
u8x8_SetInverseFont(&u8x8, 1);
u8x8_DrawString(&u8x8, 0, 2, s);
u8x8_SetFont(&u8x8, u8x8_font_px437wyse700a_2x2_r);
u8x8_SetInverseFont(&u8x8, 0);
u8x8_DrawString(&u8x8, 0, 4, s);
u8x8_SetInverseFont(&u8x8, 1);
u8x8_DrawString(&u8x8, 0, 6, s);
while( u8g_sdl_get_key() < 0 )
;
puts("u8x8_font_lucasarts_scumm_subtitle_o_2x2_r, u8x8_font_lucasarts_scumm_subtitle_r_2x2_r");
u8x8_ClearDisplay(&u8x8);
u8x8_SetFont(&u8x8, u8x8_font_lucasarts_scumm_subtitle_o_2x2_r);
u8x8_SetInverseFont(&u8x8, 0);
u8x8_DrawString(&u8x8, 0, 0, s);
u8x8_SetInverseFont(&u8x8, 1);
u8x8_DrawString(&u8x8, 0, 2, s);
u8x8_SetFont(&u8x8, u8x8_font_lucasarts_scumm_subtitle_r_2x2_r);
u8x8_SetInverseFont(&u8x8, 0);
u8x8_DrawString(&u8x8, 0, 4, s);
u8x8_SetInverseFont(&u8x8, 1);
u8x8_DrawString(&u8x8, 0, 6, s);
while( u8g_sdl_get_key() < 0 )
;
puts("u8x8_font_courB18_2x3_r");
u8x8_ClearDisplay(&u8x8);
u8x8_SetFont(&u8x8, u8x8_font_courB18_2x3_r);
u8x8_SetInverseFont(&u8x8, 0);
u8x8_DrawString(&u8x8, 0, 0, s);
u8x8_SetInverseFont(&u8x8, 1);
u8x8_DrawString(&u8x8, 0, 3, s);
while( u8g_sdl_get_key() < 0 )
;
puts("u8x8_font_courR18_2x3_r");
u8x8_ClearDisplay(&u8x8);
u8x8_SetFont(&u8x8, u8x8_font_courR18_2x3_r);
u8x8_SetInverseFont(&u8x8, 0);
u8x8_DrawString(&u8x8, 0, 0, s);
u8x8_SetInverseFont(&u8x8, 1);
u8x8_DrawString(&u8x8, 0, 3, s);
while( u8g_sdl_get_key() < 0 )
;
puts("u8x8_font_courB24_3x4_r");
u8x8_ClearDisplay(&u8x8);
u8x8_SetFont(&u8x8, u8x8_font_courB24_3x4_r);
u8x8_SetInverseFont(&u8x8, 0);
u8x8_DrawString(&u8x8, 0, 0, "AB fg");
u8x8_SetInverseFont(&u8x8, 1);
u8x8_DrawString(&u8x8, 0, 4, "AB fg");
while( u8g_sdl_get_key() < 0 )
;
puts("u8x8_font_courR24_3x4_r");
u8x8_ClearDisplay(&u8x8);
u8x8_SetFont(&u8x8, u8x8_font_courR24_3x4_r);
u8x8_SetInverseFont(&u8x8, 0);
u8x8_DrawString(&u8x8, 0, 0, "AB fg");
u8x8_SetInverseFont(&u8x8, 1);
u8x8_DrawString(&u8x8, 0, 4, "AB fg");
while( u8g_sdl_get_key() < 0 )
;
puts("u8x8_font_profont29_2x3_r");
u8x8_ClearDisplay(&u8x8);
u8x8_SetFont(&u8x8, u8x8_font_profont29_2x3_r);
u8x8_SetInverseFont(&u8x8, 0);
u8x8_DrawString(&u8x8, 0, 0, s);
u8x8_SetInverseFont(&u8x8, 1);
u8x8_DrawString(&u8x8, 0, 3, s);
while( u8g_sdl_get_key() < 0 )
;
puts("u8x8_font_7x14_1x2_r, u8x8_font_7x14B_1x2_r");
u8x8_ClearDisplay(&u8x8);
u8x8_SetFont(&u8x8, u8x8_font_7x14_1x2_r);
u8x8_SetInverseFont(&u8x8, 0);
u8x8_DrawString(&u8x8, 0, 0, s);
u8x8_SetInverseFont(&u8x8, 1);
u8x8_DrawString(&u8x8, 0, 2, s);
u8x8_SetFont(&u8x8, u8x8_font_7x14B_1x2_r);
u8x8_SetInverseFont(&u8x8, 0);
u8x8_DrawString(&u8x8, 0, 4, s);
u8x8_SetInverseFont(&u8x8, 1);
u8x8_DrawString(&u8x8, 0, 6, s);
while( u8g_sdl_get_key() < 0 )
;
puts("u8x8_font_8x13_1x2_r, u8x8_font_8x13B_1x2_r");
u8x8_ClearDisplay(&u8x8);
u8x8_SetFont(&u8x8, u8x8_font_8x13_1x2_r);
u8x8_SetInverseFont(&u8x8, 0);
u8x8_DrawString(&u8x8, 0, 0, s);
u8x8_SetInverseFont(&u8x8, 1);
u8x8_DrawString(&u8x8, 0, 2, s);
u8x8_SetFont(&u8x8, u8x8_font_8x13B_1x2_r);
u8x8_SetInverseFont(&u8x8, 0);
u8x8_DrawString(&u8x8, 0, 4, s);
u8x8_SetInverseFont(&u8x8, 1);
u8x8_DrawString(&u8x8, 0, 6, s);
while( u8g_sdl_get_key() < 0 )
;
puts("u8x8_font_shylock_nbp_1x2_r");
u8x8_ClearDisplay(&u8x8);
u8x8_SetFont(&u8x8, u8x8_font_shylock_nbp_1x2_r);
u8x8_SetInverseFont(&u8x8, 0);
u8x8_DrawString(&u8x8, 0, 0, s);
u8x8_SetInverseFont(&u8x8, 1);
u8x8_DrawString(&u8x8, 0, 2, s);
while( u8g_sdl_get_key() < 0 )
;
puts("u8x8_font_inr21_2x4_r");
u8x8_ClearDisplay(&u8x8);
u8x8_SetFont(&u8x8, u8x8_font_inr21_2x4_r);
u8x8_SetInverseFont(&u8x8, 0);
u8x8_DrawString(&u8x8, 0, 0, s);
u8x8_SetInverseFont(&u8x8, 1);
u8x8_DrawString(&u8x8, 0, 4, s);
while( u8g_sdl_get_key() < 0 )
;
puts("u8x8_font_inr33_3x6_r");
u8x8_ClearDisplay(&u8x8);
u8x8_SetFont(&u8x8, u8x8_font_inr33_3x6_r);
u8x8_SetInverseFont(&u8x8, 1);
u8x8_DrawString(&u8x8, 0, 0, "058fg");
while( u8g_sdl_get_key() < 0 )
;
puts("u8x8_font_inr46_4x8_r");
u8x8_ClearDisplay(&u8x8);
u8x8_SetFont(&u8x8, u8x8_font_inr46_4x8_r);
u8x8_SetInverseFont(&u8x8, 1);
u8x8_DrawString(&u8x8, 0, 0, "08fg");
while( u8g_sdl_get_key() < 0 )
;
puts("u8x8_font_inb21_2x4_r");
u8x8_ClearDisplay(&u8x8);
u8x8_SetFont(&u8x8, u8x8_font_inb21_2x4_r);
u8x8_SetInverseFont(&u8x8, 0);
u8x8_DrawString(&u8x8, 0, 0, s);
u8x8_SetInverseFont(&u8x8, 1);
u8x8_DrawString(&u8x8, 0, 4, s);
while( u8g_sdl_get_key() < 0 )
;
puts("u8x8_font_inb33_3x6_r");
u8x8_ClearDisplay(&u8x8);
u8x8_SetFont(&u8x8, u8x8_font_inb33_3x6_r);
u8x8_SetInverseFont(&u8x8, 1);
u8x8_DrawString(&u8x8, 0, 0, "058fg");
while( u8g_sdl_get_key() < 0 )
;
puts("u8x8_font_inb46_4x8_r");
u8x8_ClearDisplay(&u8x8);
u8x8_SetFont(&u8x8, u8x8_font_inb46_4x8_r);
u8x8_SetInverseFont(&u8x8, 1);
u8x8_DrawString(&u8x8, 0, 0, "08fg");
while( u8g_sdl_get_key() < 0 )
;
puts("u8x8_font_open_iconic_weather_2x2");
u8x8_ClearDisplay(&u8x8);
u8x8_SetFont(&u8x8, u8x8_font_open_iconic_weather_2x2);
u8x8_SetInverseFont(&u8x8, 0);
u8x8_DrawString(&u8x8, 0, 0, "@ABC");
u8x8_SetInverseFont(&u8x8, 1);
u8x8_DrawString(&u8x8, 0, 2, "@ABC");
while( u8g_sdl_get_key() < 0 )
;
puts("u8x8_font_open_iconic_weather_4x4");
u8x8_ClearDisplay(&u8x8);
u8x8_SetFont(&u8x8, u8x8_font_open_iconic_weather_4x4);
u8x8_SetInverseFont(&u8x8, 0);
u8x8_DrawString(&u8x8, 0, 0, "@ABC");
u8x8_SetInverseFont(&u8x8, 1);
u8x8_DrawString(&u8x8, 0, 4, "@ABC");
while( u8g_sdl_get_key() < 0 )
;
puts("u8x8_font_open_iconic_weather_8x8");
u8x8_ClearDisplay(&u8x8);
u8x8_SetFont(&u8x8, u8x8_font_open_iconic_weather_8x8);
u8x8_SetInverseFont(&u8x8, 0);
u8x8_DrawString(&u8x8, 0, 0, "@A");
while( u8g_sdl_get_key() < 0 )
;
return 0;
}

View File

@@ -0,0 +1,12 @@
CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) main.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

View File

@@ -0,0 +1,105 @@
#include "u8g2.h"
#include <stdio.h>
u8g2_t u8g2;
int main(void)
{
int x, y;
int k;
int i;
u8g2_SetupBuffer_SDL_128x64_4(&u8g2, &u8g2_cb_r0);
u8x8_InitDisplay(u8g2_GetU8x8(&u8g2));
u8x8_SetPowerSave(u8g2_GetU8x8(&u8g2), 0);
u8g2_SetFont(&u8g2, u8g2_font_6x10_tf);
x = 30;
y = 31-7;
for(;;)
{
#ifdef U8G2_WITH_HVLINE_COUNT
u8g2.hv_cnt = 0UL;
#endif /* U8G2_WITH_HVLINE_COUNT */
/*
u8g2_ClearBuffer(&u8g2);
u8g2_SetFontDirection(&u8g2, 0);
u8g2_DrawStr(&u8g2, x, y, "ABC");
u8g2_SetFontDirection(&u8g2, 1);
u8g2_DrawStr(&u8g2, x, y, "abc");
u8g2_SetFontDirection(&u8g2, 2);
u8g2_DrawStr(&u8g2, x, y, "abc");
u8g2_SetFontDirection(&u8g2, 3);
u8g2_DrawStr(&u8g2, x, y, "abc");
u8g2_SendBuffer(&u8g2);
*/
u8g2_FirstPage(&u8g2);
i = 0;
do
{
u8g2_SetFontPosTop(&u8g2);
u8g2_SetFontDirection(&u8g2, 2);
u8g2_DrawStr(&u8g2, x, y, "270");
u8g2_SetFontDirection(&u8g2, 3);
u8g2_DrawStr(&u8g2, x, y, "270");
if ( i == 1 )
{
u8g2_DrawHVLine(&u8g2, u8g2.user_x0, u8g2.user_y0, 1, 0);
u8g2_DrawHVLine(&u8g2, u8g2.user_x0, u8g2.user_y1-1, 1, 0);
u8g2_DrawHVLine(&u8g2, u8g2.user_x1-1, u8g2.user_y1-1, 1, 0);
u8g2_DrawHVLine(&u8g2, u8g2.user_x1-1, u8g2.user_y0, 1, 0);
}
i++;
} while( u8g2_NextPage(&u8g2) );
#ifdef U8G2_WITH_HVLINE_COUNT
printf("hv cnt: %ld\n", u8g2.hv_cnt);
#endif /* U8G2_WITH_HVLINE_COUNT */
do
{
k = u8g_sdl_get_key();
} while( k < 0 );
if ( k == 273 ) y -= 1;
if ( k == 274 ) y += 1;
if ( k == 276 ) x -= 1;
if ( k == 275 ) x += 1;
if ( k == 'e' ) y -= 1;
if ( k == 'x' ) y += 1;
if ( k == 's' ) x -= 1;
if ( k == 'd' ) x += 1;
if ( k == 'q' ) break;
}
//u8x8_Set8x8Font(u8g2_GetU8x8(&u8g2), bdf_font);
//u8x8_Draw8x8String(u8g2_GetU8x8(&u8g2), 0, 0, "Hello World!");
return 0;
}

View File

@@ -0,0 +1,10 @@
TOPTARGETS := all clean
NOWANTS=common/. text_kerning/.
SUBDIRS := $(filter-out $(NOWANTS), $(wildcard */.))
$(TOPTARGETS): $(SUBDIRS)
$(SUBDIRS):
$(MAKE) -C $@ $(MAKECMDGOALS)
.PHONY: $(TOPTARGETS) $(SUBDIRS)

View File

@@ -0,0 +1,12 @@
CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) main.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

View File

@@ -0,0 +1,239 @@
/* Shennong */
#include "u8g2.h"
#include <stdio.h>
u8g2_t u8g2;
/*
The Farmer God Shen Nong Tastes All the Plants
http://chinesereadingpractice.com/2012/08/22/the-farmer-god-shen-nong-tastes-all-the-plants/
All his life, Shen Nong had a crystal abdomen, and one could
clearly see all of his internal organs. At that time, humans were
often getting sick and even dying because they ate things
indiscriminately [not knowing if they were good or bad]. Shen
Nong determinedly tasted everything everywhere; the
good-tasting things he put in a bag on his left side, those were
for people to eat; the bad-tasting things he put in a bag on his
right side, and those were used for medicine.
The first time, Shen Nong tasted a small fresh leaf. As this leaf
fell into his stomach, it cleaned every inch of his insides so that
every organ top and bottom was fresh and cool, as if [the leaf]
was somehow on patrol [making the rounds], so Shen Nong
called it “chá” [to investigate / check], and later generations of
men called it “chá” [tea]. Shen Nong put it in the bag on the
right. The second time, Shen Nong tasted a little light red flower
that looked like a butterfly, which was sweet and delicious, with
an exotic smell that filled his nostrils, so he called it “licorice”. He
put it in the bag on the left. In this way, Shen Nong diligently
tasted all manner of flora, and every time he was poisoned, he
used tea to rescue himself. Before long, the bag on his left
contained 47,000 kinds of flowers, grasses, roots and leaves,
and the right side had 398,000 kinds.
But one day, Shen Nong tasted “heartbreak grass”, and this
poison was too terrible, so there wasnt enough time to eat the
tea leaves to detoxify and he died. He sacrificed himself to save
humanity, so people call him the “Bodhisattva of Medicine”, and
people forever commemorate him through this story.
*/
/* The Farmer God Shen Nong Tastes All the Plants */
const char c_str[] =
"Shen Nong\n\n"
"神农一生下来就是\n"
"个水晶肚子,五脏\n"
"六腑全都能看得一\n"
"清二楚。那时侯,\n"
"人们经常因为乱吃\n"
"东西而生病,甚至\n"
"丧命。神农决心尝\n"
"遍所有的东西,好\n"
"吃的放在身边左边\n"
"的袋子里,给人吃\n"
"\n"
"不好吃的就放在身\n"
"子右边的袋子里,\n"
"作药用。\n"
"第一次,神农尝了\n"
"一片小嫩叶。这叶\n"
"片一落进肚里,就\n"
"上上下下地把里面\n"
"各器官擦洗得清清\n"
"爽爽,\n"
"象巡查似的,\n"
"神农把它叫做\n"
"“查”,\n"
"就是后人所称的\n"
"“茶”。\n"
"神农将它放进右边\n"
"袋子里。第二次,\n"
"神农尝了朵蝴蝶样\n"
"的淡红小花,甜津\n"
"津的,香味扑鼻,\n"
"这是“甘草”。他把\n"
"它放进了左边袋子\n"
"里。就这样,神农\n"
"辛苦地尝遍百草,\n"
"每次中毒,都靠茶\n"
"来解救。后来,\n"
"他左边的袋子里花\n"
"草根叶有四万七千\n"
"种,右边有三十九\n"
"万八千种。\n"
"但有一天,神农尝\n"
"到了“断肠草”,这\n"
"种毒草太厉害了,\n"
"他还来不及吃茶解\n"
"毒就死了。\n"
"他是为了拯救人们\n"
"而牺牲的,人们称\n"
"他为“药王菩萨”,\n"
"人间以这个神话故\n"
"事永远地纪念他。\n";
#define SCROLL_DELTA 4
/* return number of unkown glyphs */
/*
uint16_t check_str(const char *str)
{
uint16_t e, cnt;
u8g2.u8x8.next_cb = u8x8_utf8_next;
u8x8_utf8_init(u8g2_GetU8x8(&u8g2));
cnt = 0;
for(;;)
{
e = u8g2.u8x8.next_cb(u8g2_GetU8x8(&u8g2), (uint8_t)*str);
if ( e == 0x0ffff )
break;
str++;
if ( e != 0x0fffe )
{
if ( u8g2_IsGlyph(&u8g2, e) != 0 )
{
cnt++;
}
}
}
return cnt;
}
*/
int main(void)
{
int k;
static char buf[128];
uint8_t total_lines; // the total number of lines in the story
uint8_t i; // loop variable for the lines
uint8_t line_cnt; // number of lines to draw, usually equal to lines_per_draw
uint8_t start_line; // topmost visible line, derived from top_window_pos
uint8_t lines_per_draw; // how many lines to draw on the screen, derived from font and display height
uint16_t glyph_height; // height of the glyphs
uint16_t top_window_pos; // defines the display position in pixel within the text
uint16_t total_height; // total height in pixel, derived from font height and total_lines
u8g2_uint_t top_offset; // offset between the first visible line and the display
u8g2_SetupBuffer_SDL_128x64_4(&u8g2, &u8g2_cb_r0);
u8x8_InitDisplay(u8g2_GetU8x8(&u8g2));
u8x8_SetPowerSave(u8g2_GetU8x8(&u8g2), 0);
u8g2_SetFont(&u8g2, u8g2_font_wqy12_t_chinese1); // two unknown glyphs
//u8g2_SetFont(&u8g2, u8g2_font_wqy12_t_chinese3); // two unknown glyphs
//u8g2_SetFont(&u8g2, u8g2_font_wqy12_t_gb2312a); // ";" is missing
//u8g2_SetFont(&u8g2, u8g2_font_wqy12_t_gb2312b); // all glyphs available
/* calculate the length of the text in lines */
total_lines = u8x8_GetStringLineCnt(c_str);
/* get the height of the glyphs */
glyph_height = u8g2_GetMaxCharHeight(&u8g2);
/* calculate the height of the text in pixel */
total_height = (uint16_t)total_lines * (uint16_t)glyph_height;
/* calculate how many lines must be drawn on the screen */
lines_per_draw = u8g2_GetDisplayHeight(&u8g2) / glyph_height;
lines_per_draw += 2;
printf("Total lines: %d\n", (int)total_lines);
printf("Glyph height: %d\n", (int)glyph_height);
printf("Number of lines to draw: %d\n", (int)lines_per_draw);
top_window_pos = 0;
for(;;)
{
printf("Pos: %d\n", (int)top_window_pos);
start_line = top_window_pos / glyph_height;
top_offset = top_window_pos % glyph_height;
line_cnt = total_lines - start_line;
if ( line_cnt > lines_per_draw )
line_cnt = lines_per_draw;
u8g2_FirstPage(&u8g2);
do
{
u8g2_SetFontDirection(&u8g2, 0);
for( i = 0; i < line_cnt; i++ )
{
u8x8_CopyStringLine(buf, i+start_line, c_str);
u8g2_DrawUTF8(&u8g2, 0, i*glyph_height-top_offset +glyph_height, buf);
}
} while( u8g2_NextPage(&u8g2) );
do
{
k = u8g_sdl_get_key();
} while( k < 0 );
/* up */
if ( k == 273 )
{
if ( top_window_pos > 0 )
{
top_window_pos-=SCROLL_DELTA;
}
}
/* down */
if ( k == 274 )
{
if ( top_window_pos < total_height )
{
top_window_pos+=SCROLL_DELTA;
}
else
{
top_window_pos = 0;
}
}
if ( k == 'q' ) break;
}
return 0;
}

View File

@@ -0,0 +1,15 @@
CC = gcc-4.8
# CFLAGS = -g -pg -Wall -I../../../csrc/. -DNO_SDL
CFLAGS = -g -pg -Wall -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) main.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
# $(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) -o u8g2_sdl
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

View File

@@ -0,0 +1,219 @@
/* Shennong */
#include "u8g2.h"
#include <stdio.h>
u8g2_t u8g2;
/*
The Farmer God Shen Nong Tastes All the Plants
http://chinesereadingpractice.com/2012/08/22/the-farmer-god-shen-nong-tastes-all-the-plants/
All his life, Shen Nong had a crystal abdomen, and one could
clearly see all of his internal organs. At that time, humans were
often getting sick and even dying because they ate things
indiscriminately [not knowing if they were good or bad]. Shen
Nong determinedly tasted everything everywhere; the
good-tasting things he put in a bag on his left side, those were
for people to eat; the bad-tasting things he put in a bag on his
right side, and those were used for medicine.
The first time, Shen Nong tasted a small fresh leaf. As this leaf
fell into his stomach, it cleaned every inch of his insides so that
every organ top and bottom was fresh and cool, as if [the leaf]
was somehow on patrol [making the rounds], so Shen Nong
called it “chá” [to investigate / check], and later generations of
men called it “chá” [tea]. Shen Nong put it in the bag on the
right. The second time, Shen Nong tasted a little light red flower
that looked like a butterfly, which was sweet and delicious, with
an exotic smell that filled his nostrils, so he called it “licorice”. He
put it in the bag on the left. In this way, Shen Nong diligently
tasted all manner of flora, and every time he was poisoned, he
used tea to rescue himself. Before long, the bag on his left
contained 47,000 kinds of flowers, grasses, roots and leaves,
and the right side had 398,000 kinds.
But one day, Shen Nong tasted “heartbreak grass”, and this
poison was too terrible, so there wasnt enough time to eat the
tea leaves to detoxify and he died. He sacrificed himself to save
humanity, so people call him the “Bodhisattva of Medicine”, and
people forever commemorate him through this story.
*/
/* The Farmer God Shen Nong Tastes All the Plants */
const char c_str[] =
"Shen Nong\n\n"
"神农一生下来就是\n"
"个水晶肚子,五脏\n"
"六腑全都能看得一\n"
"清二楚。那时侯,\n"
"人们经常因为乱吃\n"
"东西而生病,甚至\n"
"丧命。神农决心尝\n"
"遍所有的东西,好\n"
"吃的放在身边左边\n"
"的袋子里,给人吃\n"
"\n"
"不好吃的就放在身\n"
"子右边的袋子里,\n"
"作药用。\n"
"第一次,神农尝了\n"
"一片小嫩叶。这叶\n"
"片一落进肚里,就\n"
"上上下下地把里面\n"
"各器官擦洗得清清\n"
"爽爽,\n"
"象巡查似的,\n"
"神农把它叫做\n"
"“查”,\n"
"就是后人所称的\n"
"“茶”。\n"
"神农将它放进右边\n"
"袋子里。第二次,\n"
"神农尝了朵蝴蝶样\n"
"的淡红小花,甜津\n"
"津的,香味扑鼻,\n"
"这是“甘草”。他把\n"
"它放进了左边袋子\n"
"里。就这样,神农\n"
"辛苦地尝遍百草,\n"
"每次中毒,都靠茶\n"
"来解救。后来,\n"
"他左边的袋子里花\n"
"草根叶有四万七千\n"
"种,右边有三十九\n"
"万八千种。\n"
"但有一天,神农尝\n"
"到了“断肠草”,这\n"
"种毒草太厉害了,\n"
"他还来不及吃茶解\n"
"毒就死了。\n"
"他是为了拯救人们\n"
"而牺牲的,人们称\n"
"他为“药王菩萨”,\n"
"人间以这个神话故\n"
"事永远地纪念他。\n";
#define SCROLL_DELTA 1
/* return number of unkown glyphs */
/*
uint16_t check_str(const char *str)
{
uint16_t e, cnt;
u8g2.u8x8.next_cb = u8x8_utf8_next;
u8x8_utf8_init(u8g2_GetU8x8(&u8g2));
cnt = 0;
for(;;)
{
e = u8g2.u8x8.next_cb(u8g2_GetU8x8(&u8g2), (uint8_t)*str);
if ( e == 0x0ffff )
break;
str++;
if ( e != 0x0fffe )
{
if ( u8g2_IsGlyph(&u8g2, e) != 0 )
{
cnt++;
}
}
}
return cnt;
}
*/
int main(void)
{
static char buf[128];
uint8_t total_lines; // the total number of lines in the story
uint8_t i; // loop variable for the lines
uint8_t line_cnt; // number of lines to draw, usually equal to lines_per_draw
uint8_t start_line; // topmost visible line, derived from top_window_pos
uint8_t lines_per_draw; // how many lines to draw on the screen, derived from font and display height
uint16_t glyph_height; // height of the glyphs
uint16_t top_window_pos; // defines the display position in pixel within the text
uint16_t total_height; // total height in pixel, derived from font height and total_lines
u8g2_uint_t top_offset; // offset between the first visible line and the display
u8g2_SetupBuffer_SDL_128x64_4(&u8g2, &u8g2_cb_r0);
u8x8_InitDisplay(u8g2_GetU8x8(&u8g2));
u8x8_SetPowerSave(u8g2_GetU8x8(&u8g2), 0);
//u8g2_SetFont(&u8g2, u8g2_font_wqy12_t_chinese1); // two unknown glyphs
//u8g2_SetFont(&u8g2, u8g2_font_wqy12_t_chinese3); // two unknown glyphs
//u8g2_SetFont(&u8g2, u8g2_font_wqy12_t_gb2312a); // ";" is missing
u8g2_SetFont(&u8g2, u8g2_font_wqy12_t_gb2312b); // all glyphs available
/* calculate the length of the text in lines */
total_lines = u8x8_GetStringLineCnt(c_str);
/* get the height of the glyphs */
glyph_height = u8g2_GetMaxCharHeight(&u8g2);
/* calculate the height of the text in pixel */
total_height = (uint16_t)total_lines * (uint16_t)glyph_height;
/* calculate how many lines must be drawn on the screen */
lines_per_draw = u8g2_GetDisplayHeight(&u8g2) / glyph_height;
lines_per_draw += 2;
printf("Total lines: %d\n", (int)total_lines);
printf("Glyph height: %d\n", (int)glyph_height);
printf("Number of lines to draw: %d\n", (int)lines_per_draw);
top_window_pos = 0;
for(;;)
{
//printf("Pos: %d\n", (int)top_window_pos);
start_line = top_window_pos / glyph_height;
top_offset = top_window_pos % glyph_height;
line_cnt = total_lines - start_line;
if ( line_cnt > lines_per_draw )
line_cnt = lines_per_draw;
u8g2_FirstPage(&u8g2);
do
{
u8g2_SetFontDirection(&u8g2, 0);
for( i = 0; i < line_cnt; i++ )
{
u8x8_CopyStringLine(buf, i+start_line, c_str);
u8g2_DrawUTF8(&u8g2, 0, i*glyph_height-top_offset +glyph_height, buf);
}
} while( u8g2_NextPage(&u8g2) );
if ( top_window_pos < total_height )
{
top_window_pos+=SCROLL_DELTA;
}
else
{
break;
}
}
return 0;
}

View File

@@ -0,0 +1,12 @@
CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) $(shell ls *.c)
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

View File

@@ -0,0 +1,367 @@
/*
datecalc.c
Written 1996/96 by Oliver Kraus
Published by Heinz Heise Verlag 1997 (c't 15/97)
Completly rewritten and put under GPL 2011 by Oliver Kraus
(c) 2011 by Oliver Kraus (olikraus@gmail.com)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Development goals:
- English version
- Optimized for 8 bit microcontroller
Definitions:
Short Name: y
Long Name: year
Range: 2000...
Short Name: ydn
Long Name: year day number
Range: 1..366
Short Name: cdn
Long Name: century day number
Range: 1...65535
Short Name: ymd
Long Name: Year, Month, Day
Range: 2000...65535, 1..12, 1..31
Conversions
ymd --> y, ydn
get_year_day_number()
y, ydn --> ymd
get_month_by_year_day_number()
get_day_by_year_day_number()
y, ydn --> cdn
to_century_day_number();
cdn --> y, ydn
from_century_day_number();
*/
#include <stdint.h>
/*
Prototype:
uint8_t is_leap_year(uint16_t y)
Description:
Calculate leap year
Arguments:
y year, e.g. 2011 for year 2011
Result:
0 not a leap year
1 leap year
*/
uint8_t is_leap_year(uint16_t y)
{
if (
((y % 4 == 0) && (y % 100 != 0)) ||
(y % 400 == 0)
)
return 1;
return 0;
}
/*
Prototype:
uint16_t get_year_day_number(uint16_t y, uint8_t m, uint8_t d)
Description:
Calculate the day number within a year. 1st of Jan has the number 1.
"Robertson" Algorithm IDAY (CACM Vol 15/#10/Oct 1972)
Arguments:
y year, e.g. 2011 for year 2011
m month with 1 = january to 12 = december
d day starting with 1
Result:
The "day number" within the year: 1 for the 1st of Jan.
See also:
get_month_by_day_number()
*/
uint16_t get_year_day_number(uint16_t y, uint8_t m, uint8_t d)
{
uint8_t tmp1;
uint16_t tmp2;
tmp1 = 0;
if ( m >= 3 )
tmp1++;
tmp2 = m;
tmp2 +=2;
tmp2 *=611;
tmp2 /= 20;
tmp2 += d;
tmp2 -= 91;
tmp1 <<=1;
tmp2 -= tmp1;
if ( tmp1 != 0 )
tmp2 += is_leap_year(y);
return tmp2;
}
/*
Prototype:
uint8_t get_month_by_year_day_number(uint16_t y, uint16_t ydn)
Description:
Get the month from year and day number within a year.
"R. A. Stone" Algorithm (CACM Vol 13/#10/Oct 1970)
Arguments:
y year, e.g. 2011 for year 2011
ydn year day number (1st of Jan has the number 1)
Result:
The month within the year: 1 for January.
See also:
get_year_day_number()
*/
static uint16_t corrected_year_day_number(uint16_t y, uint16_t ydn)
{
uint8_t a;
a = is_leap_year(y);
if ( ydn > 59+a )
{
ydn += 2;
ydn -= a;
}
ydn += 91;
return ydn;
}
uint8_t get_month_by_year_day_number(uint16_t y, uint16_t ydn)
{
uint8_t a;
ydn = corrected_year_day_number(y, ydn);
ydn *= 20;
ydn /= 611;
a = ydn;
a -= 2;
return a;
}
/*
Prototype:
uint8_t get_day_by_year_day_number(uint16_t y, uint16_t ydn)
Description:
Get the day within month from year and day number within a year.
"R. A. Stone" Algorithm (CACM Vol 13/#10/Oct 1970)
Arguments:
y year, e.g. 2011 for year 2011
ydn year day number (1st of Jan has the number 1)
Result:
The day within a month: 1 for the first day of a month.
See also:
get_year_day_number()
*/
uint8_t get_day_by_year_day_number(uint16_t y, uint16_t ydn)
{
uint8_t m;
uint16_t tmp;
m = get_month_by_year_day_number(y, ydn);
m += 2;
ydn = corrected_year_day_number(y, ydn);
tmp = 611;
tmp *= m;
tmp /= 20;
ydn -= tmp;
return ydn;
}
/*
Prototype:
uint8_t get_weekday_by_year_day_number(uint16_t y, uint16_t ydn)
Description:
Get the day within week from year and day number within a year.
"Zeller" Algorithm
https://de.wikisource.org/wiki/Index:Acta_Mathematica_vol._009_(1886)
https://ia801407.us.archive.org/8/items/actamathematica09upps/actamathematica09upps.pdf
Arguments:
y year, e.g. 2011 for year 2011
ydn year day number (1st of Jan has the number 1)
Result:
The day within a week: 0..6 with 0 = Sunday, 1 = Monday, ...
See also:
get_year_day_number()
*/
uint8_t get_weekday_by_year_day_number(uint16_t y, uint16_t ydn)
{
uint8_t j, c, tmp8;
uint16_t tmp16;
y--;
j = y % 100;
c = y / 100;
tmp16 = c;
tmp16 *= 5;
tmp16 += ydn;
tmp8 = j;
j >>= 2;
c >>= 2;
tmp8 += j;
tmp8 += c;
tmp8 += 28;
tmp16 += tmp8;
tmp16 %= 7;
return tmp16;
}
/*
Prototype:
uint16_t to_century_day_number(uint16_t y, uint16_t ydn)
Description:
Calculate days since January, 1st, 2000
Arguments:
y year, e.g. 2011 for year 2011
ydn year day number (1st of Jan has the number 1)
*/
uint16_t to_century_day_number(uint16_t y, uint16_t ydn)
{
uint16_t cdn;
cdn = ydn;
cdn--;
while( y > 2000 )
{
y--;
cdn += 365;
cdn += is_leap_year(y);
}
return cdn;
}
void from_century_day_number(uint16_t cdn, uint16_t *year, uint16_t *ydn)
{
uint16_t y, days_per_year;
y = 2000;
for(;;)
{
days_per_year = 365;
days_per_year += is_leap_year(y);
if ( cdn >= days_per_year )
{
cdn -= days_per_year;
y++;
}
else
break;
}
cdn++;
*year = y;
*ydn = cdn;
}
/*
Calculate the seconds after 2000-01-01 00:00. The largest possible
time is 2136-02-07 06:28:15
*/
uint32_t to_time(uint16_t cdn, uint8_t h, uint8_t m, uint8_t s)
{
uint32_t t;
t = cdn;
t *= 24;
t += h;
t *= 60;
t += m;
t *= 60;
t += s;
return t;
}
void from_time(uint32_t t, uint16_t *cdn, uint8_t *h, uint8_t *m, uint8_t *s)
{
*s = t % 60;
t /= 60;
*m = t % 60;
t /= 60;
*h = t % 24;
t /= 24;
*cdn = t;
}
uint32_t to_sec_since_2000(uint16_t y, uint8_t mo, uint8_t d, uint8_t h, uint8_t mi, uint8_t s)
{
uint16_t ydn = get_year_day_number(y, mo, d);
uint16_t cdn = to_century_day_number(y, ydn);
return to_time(cdn, h, mi, s);
}
/*
Calculate the minutes after 2000-01-01 00:00.
*/
uint32_t to_minutes(uint16_t cdn, uint8_t h, uint8_t m)
{
uint32_t t;
t = cdn;
t *= 24;
t += h;
t *= 60;
t += m;
return t;
}
void from_minutes(uint32_t t, uint16_t *cdn, uint8_t *h, uint8_t *m)
{
*m = t % 60;
t /= 60;
*h = t % 24;
t /= 24;
*cdn = t;
}
uint32_t to_minutes_since_2000(uint16_t y, uint8_t mo, uint8_t d, uint8_t h, uint8_t mi)
{
uint16_t ydn = get_year_day_number(y, mo, d);
uint16_t cdn = to_century_day_number(y, ydn);
return to_minutes(cdn, h, mi);
}
/*
Eingabe: Jahr
Ausgabe: Tagesnummer des Ostersonntag,
rel. zum Jahresanfang.
Algorithmus "Computus ecclesiasticus"
325 n.Chr. wurde Ostern auf den Sonntag nach
dem ersten Fruehlingsvollmond festgelegt. Damit
liegt Ostern zwischen dem 22. Maerz und
dem 25. April.
*/
/*
int ostersonntag(int jahr)
{
int gz, jhd, ksj, korr, so, epakte, n;
gz = (jahr%19)+1;
jhd = jahr/100+1;
ksj = (3*jhd)/4-12;
korr = (8*jhd+5)/25-5;
so = (5*jahr)/4-ksj-10;
epakte = (11*gz+20+korr-ksj) % 30;
if ( (epakte == 25 && gz > 11) || epakte == 24 )
epakte++;
n = 44-epakte;
if ( n < 21 )
n = n + 30;
n = n + 7 - (so+n) % 7;
n += schaltjahr(jahr);
return n+59;
}
*/

View File

@@ -0,0 +1,83 @@
/*
datecalc.c
Written 1996/96 by Oliver Kraus
Published by Heinz Heise Verlag 1997 (c't 15/97)
Completly rewritten and put under GPL 2011 by Oliver Kraus
(c) 2011 by Oliver Kraus (olikraus@gmail.com)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Development goals:
- English version
- Optimized for 8 bit microcontroller
Definitions:
Short Name: y
Long Name: year
Range: 2000...
Short Name: ydn
Long Name: year day number
Range: 1..366
Short Name: cdn
Long Name: century day number
Range: 1...65535
Short Name: ymd
Long Name: Year, Month, Day
Range: 2000...65535, 1..12, 1..31
Conversions
ymd --> y, ydn
get_year_day_number()
y, ydn --> ymd
get_month_by_year_day_number()
get_day_by_year_day_number()
y, ydn --> cdn
to_century_day_number();
cdn --> y, ydn
from_century_day_number();
*/
#ifndef _DATECALC_H
#define _DATECALC_H
#include <stdint.h>
uint8_t is_leap_year(uint16_t y);
uint16_t get_year_day_number(uint16_t y, uint8_t m, uint8_t d);
uint8_t get_month_by_year_day_number(uint16_t y, uint16_t ydn);
uint8_t get_day_by_year_day_number(uint16_t y, uint16_t ydn);
uint8_t get_weekday_by_year_day_number(uint16_t y, uint16_t ydn); /* returns day within a week: 0..6 with 0 = Sunday, 1 = Monday, ... */
uint16_t to_century_day_number(uint16_t y, uint16_t ydn);
void from_century_day_number(uint16_t cdn, uint16_t *year, uint16_t *ydn);
uint32_t to_time(uint16_t cdn, uint8_t h, uint8_t m, uint8_t s);
void from_time(uint32_t t, uint16_t *cdn, uint8_t *h, uint8_t *m, uint8_t *s);
uint32_t to_sec_since_2000(uint16_t y, uint8_t mo, uint8_t d, uint8_t h, uint8_t mi, uint8_t s);
uint32_t to_minutes(uint16_t cdn, uint8_t h, uint8_t m);
void from_minutes(uint32_t t, uint16_t *cdn, uint8_t *h, uint8_t *m);
uint32_t to_minutes_since_2000(uint16_t y, uint8_t mo, uint8_t d, uint8_t h, uint8_t mi);
#endif

View File

@@ -0,0 +1,128 @@
/*
gui.h
*/
#ifndef _GUI_H
#define _GUI_H
#include "menu.h"
extern u8g2_t u8g2;
#define GUI_STATE_STOP 0
#define GUI_STATE_SIGNAL_ALARM 1
#define GUI_STATE_DISPLAY_TIME 2
#define GUI_STATE_MENU 3
#define GUI_ALARM_CNT 4
#define SNOOZE_MINUTES 5
#define ALLOW_SKIP_HOURS 10
struct _gui_data
{
uint16_t uptime; /* uptime in days, 10 bits, counts from 0 to 999, this value will be stored in the backup register */
uint16_t week_time; /* calculated: derived from h, mt, mo and weekday */
uint8_t gui_state; /* global running state, see guistate.c, defaults to 0 (GUI_STATE_STOP) */
uint8_t h, mt, mo, st, so; /* input: current time */
uint8_t day; /* input: 1 .. 31 current day in month */
uint8_t last_day; /* last day. This is used to check, whether the day has changed. Required for uptime calc. This is also stored in the backup register. */
uint8_t month; /* input: 1..12 */
uint8_t year_t, year_o; /* input: current year */
uint8_t weekday; /* calculated: 0 = Monday */
uint8_t next_alarm_index; /* calculated: index for the next alarm or GUI_ALARM_CNT if there is no next alarm */
uint8_t is_skip_possible; /* calculated: whether the next alarm (next_alarm_index) can be skipped */
uint8_t is_equal; /* calculated: whether the current time matches any alarm, will be set to 0 automatically */
uint8_t equal_h;
uint8_t equal_mt;
uint8_t equal_mo;
uint8_t is_alarm; /* input/calculated: set by the software, has to be reset by the user */
uint8_t active_alarm_idx; /* input/calculated: set by the software, has to be reset by the user */
uint8_t contrast; /* value 1..7, 0 is default (do not set) */
uint8_t display_voltage;
char s[16]; /* string buffer */
};
typedef struct _gui_data gui_data_t;
struct _gui_alarm_struct
{
/* next alarm, all na_ fields are derived from the alarm information */
uint16_t na_week_time_in_minutes;
uint16_t na_minutes_diff; /* calculated: time in minutes until next alarm, 0x0ffff = no alarm */
uint8_t na_h; /* calculated */
uint8_t na_m; /* calculated */
uint8_t na_wd; /* calculated: 0...7, 0=monday, 7=no alarm */
/* alarm information */
uint8_t snooze_count; /* input, 1 bit*/
volatile uint8_t enable; /* input, 1 bit */
uint8_t skip_wd; /* input 0 = no skip, 1 = Monday, ... 3 bits*/
uint8_t h; /* input 5 bits */
uint8_t m; /* input 6 bits */
uint8_t wd[7]; /* input: 0 or 1, 0=weekday not selected, 7 bits */
};
typedef struct _gui_alarm_struct gui_alarm_t;
/* guimenu.c */
extern const me_t melist_setup_time[];
extern const me_t melist_display_time[];
extern const me_t melist_setup_date[];
extern const me_t melist_setup_alarm[];
extern const me_t melist_alarm_menu[];
extern const me_t melist_setup_menu[];
extern const me_t melist_active_alarm_menu[];
extern const me_t melist_top_menu[];
/* guifn.c */
extern gui_alarm_t gui_alarm_list[GUI_ALARM_CNT];
extern char gui_alarm_str[GUI_ALARM_CNT][8];
extern gui_data_t gui_data;
extern menu_t gui_menu;
void gui_date_adjust(void);
void gui_LoadData(void);
void gui_Recalculate(void);
void gui_SignalTimeChange(void);
void gui_Init(u8g2_t *u8g2, uint8_t is_por);
void gui_Draw(void);
void gui_Next(void);
void gui_Select(void);
/* guihal.c */
void do_reset(void);
void store_gui_data(uint32_t *data);
void load_gui_data(uint32_t *data);
int is_por_reset(void);
int is_button_reset(void);
uint32_t get_boot_status_register(void);
uint32_t get_pwr_status_register(void);
uint32_t get_reset_reason(void);
uint32_t get_wakeup_count(void);
uint32_t get_dst_by_date(void);
uint32_t get_dst_by_RTC(void);
void enable_alarm(void);
void disable_alarm(void);
void set_time(uint8_t ht, uint8_t ho, uint8_t mt, uint8_t mo, uint8_t st, uint8_t so);
void set_date(uint8_t yt, uint8_t yo, uint8_t mt, uint8_t mo, uint8_t dayt, uint8_t dayo, uint8_t weekday);
void set_contrast(void); /* set contrast to gui_data.contrast, value 1..7, 0 is default (do not set) */
#endif

View File

@@ -0,0 +1,453 @@
/*
guifn.c
*/
#include "gui.h"
#include "datecalc.h"
#include <string.h>
/*============================================*/
gui_alarm_t gui_alarm_list[GUI_ALARM_CNT];
char gui_alarm_str[GUI_ALARM_CNT][8];
uint32_t gui_backup_array[5];
gui_data_t gui_data;
menu_t gui_menu;
/*============================================*/
/* local functions */
uint32_t get_u32_by_alarm_data(gui_alarm_t *alarm);
void set_alarm_data_by_u32(gui_alarm_t *alarm, uint32_t u);
void gui_alarm_calc_next_wd_alarm(uint8_t idx, uint16_t current_week_time_in_minutes);
void gui_alarm_calc_str_time(uint8_t idx) U8G2_NOINLINE;
void gui_date_adjust(void) U8G2_NOINLINE;
void gui_calc_week_time(void);
void gui_calc_next_alarm(void);
/*============================================*/
uint32_t get_u32_by_alarm_data(gui_alarm_t *alarm)
{
uint32_t u;
int i;
u = 0;
for( i = 0; i < 7; i++ )
{
if ( alarm->wd[i] )
{
u |= 1<<i;
}
}
/* 17 Sep 2017: fixed 32 bit handling for the next statements */
u |= ((uint32_t)alarm->m&63) << (7);
u |= ((uint32_t)alarm->h&31) << (7+6);
u |= ((uint32_t)alarm->skip_wd&7) << (7+6+5);
u |= ((uint32_t)alarm->enable&1) << (7+6+5+3);
u |= ((uint32_t)alarm->snooze_count&1) << (7+6+5+3+1);
return u;
}
void set_alarm_data_by_u32(gui_alarm_t *alarm, uint32_t u)
{
int i;
for( i = 0; i < 7; i++ )
{
if ( (u & (1<<i)) != 0 )
alarm->wd[i] = 1;
else
alarm->wd[i] = 0;
}
u>>=7;
alarm->m = u & 63;
u>>=6;
alarm->h = u & 31;
u>>=5;
alarm->skip_wd = u & 7;
u>>=3;
alarm->enable = u & 1;
u>>=1;
alarm->snooze_count = u & 1;
}
/*============================================*/
void gui_alarm_calc_next_wd_alarm(uint8_t idx, uint16_t current_week_time_in_minutes)
{
uint8_t i;
uint16_t week_time_abs;
uint16_t week_time_diff; /* difference to current_week_time_in_minutes */
uint16_t best_diff = 0x0ffff;
gui_alarm_list[idx].na_week_time_in_minutes = 0x0ffff; /* not found */
gui_alarm_list[idx].na_minutes_diff = 0x0ffff; /* not found */
gui_alarm_list[idx].na_wd = 7; /* not found */
//printf("gui_alarm_calc_next_wd_alarm: %d\n", idx);
if ( gui_alarm_list[idx].enable != 0 )
{
//printf("gui_alarm_calc_next_wd_alarm: %d enabled\n", idx);
for( i = 0; i < 7; i++ )
{
if ( gui_alarm_list[idx].wd[i] != 0 )
{
//printf("gui_alarm_calc_next_wd_alarm: %d i=%d gui_alarm_list[idx].skip_wd=%d \n", idx, i, gui_alarm_list[idx].skip_wd);
if ( gui_alarm_list[idx].skip_wd != i+1 )
{
week_time_abs = i;
week_time_abs *= 24;
week_time_abs += gui_alarm_list[idx].h;
week_time_abs *= 60;
week_time_abs += gui_alarm_list[idx].m;
week_time_abs += gui_alarm_list[idx].snooze_count*(uint16_t)SNOOZE_MINUTES;
if ( current_week_time_in_minutes <= week_time_abs )
week_time_diff = week_time_abs - current_week_time_in_minutes;
else
week_time_diff = week_time_abs + 7*24*60 - current_week_time_in_minutes;
//printf("gui_alarm_calc_next_wd_alarm: %d week_time_abs=%d current_week_time_in_minutes=%d week_time_diff=%d\n", idx, week_time_abs, current_week_time_in_minutes,week_time_diff);
if ( best_diff > week_time_diff )
{
best_diff = week_time_diff;
/* found for this alarm */
gui_alarm_list[idx].na_minutes_diff = week_time_diff;
gui_alarm_list[idx].na_week_time_in_minutes = week_time_abs;
gui_alarm_list[idx].na_h = gui_alarm_list[idx].h;
gui_alarm_list[idx].na_m = gui_alarm_list[idx].m;
gui_alarm_list[idx].na_wd = i;
}
}
}
}
}
//printf("gui_alarm_calc_next_wd_alarm: %d na_minutes_diff=%d\n", idx, gui_alarm_list[idx].na_minutes_diff);
//printf("gui_alarm_calc_next_wd_alarm: %d na_wd=%d\n", idx, gui_alarm_list[idx].na_wd);
}
void gui_alarm_calc_str_time(uint8_t idx)
{
gui_alarm_str[idx][0] = ' ';
strcpy(gui_alarm_str[idx]+1, u8x8_u8toa(gui_alarm_list[idx].h, 2));
strcpy(gui_alarm_str[idx]+4, u8x8_u8toa(gui_alarm_list[idx].m, 2));
gui_alarm_str[idx][3] = ':';
if ( gui_alarm_list[idx].enable == 0 )
{
gui_alarm_str[idx][0] = '(';
gui_alarm_str[idx][6] = ')';
gui_alarm_str[idx][7] = '\0';
}
}
/* adjust day/month and calculates the weekday */
/* this function must be called after reading from RTC or after setting the input vars by the user */
void gui_date_adjust(void)
{
uint16_t ydn;
uint16_t year;
//uint16_t cdn;
//uint32_t minutes_since_2000;
if ( gui_data.month == 0 )
gui_data.month++;
if ( gui_data.day == 0 )
gui_data.day++;
year = 2000+gui_data.year_t*10 + gui_data.year_o;
ydn = get_year_day_number(year, gui_data.month, gui_data.day);
//cdn = to_century_day_number(year, ydn);
//minutes_since_2000 = to_minutes(cdn, gui_data.h, gui_data.mt*10+gui_data.mo);
// maybe adjust time by +/- 1h based on argument given to gui_date_adjust... but then it should be renamed also
gui_data.month = get_month_by_year_day_number(year, ydn);
gui_data.day = get_day_by_year_day_number(year, ydn);
gui_data.weekday = get_weekday_by_year_day_number(year, ydn); /* 0 = Sunday */
/* adjust the weekday so that 0 will be Monday */
gui_data.weekday += 6;
if ( gui_data.weekday >= 7 )
gui_data.weekday -= 7;
if ( gui_data.day != gui_data.last_day )
{
gui_data.uptime++;
gui_data.last_day = gui_data.day;
}
}
/*
calculate the minute within the week.
this must be called after gui_date_adjust(), because the weekday is used here
*/
void gui_calc_week_time(void)
{
gui_data.week_time = gui_data.weekday;
gui_data.week_time *= 24;
gui_data.week_time += gui_data.h;
gui_data.week_time *= 60;
gui_data.week_time += gui_data.mt * 10 + gui_data.mo;
}
/*
calculate the next alarm.
this must be called after gui_calc_week_time() because, we need week_time
*/
void gui_calc_next_alarm(void)
{
uint8_t i;
uint8_t lowest_i;
uint16_t lowest_diff;
uint8_t redo;
do
{
redo = 0;
/* step 1: Calculate the difference to current weektime for each alarm */
/* result is stored in gui_alarm_list[i].na_minutes_diff */
for( i = 0; i < GUI_ALARM_CNT; i++ )
gui_alarm_calc_next_wd_alarm(i, gui_data.week_time+(uint16_t)gui_data.is_equal); /* is_equal flag is used as a offset */
/* step 2: find the index with the lowest difference */
lowest_diff = 0x0ffff;
lowest_i = GUI_ALARM_CNT;
for( i = 0; i < GUI_ALARM_CNT; i++ )
{
if ( lowest_diff > gui_alarm_list[i].na_minutes_diff )
{
lowest_diff = gui_alarm_list[i].na_minutes_diff;
lowest_i = i;
}
}
/* step 3: store the result */
gui_data.next_alarm_index = lowest_i; /* this can be GUI_ALARM_CNT */
//printf("gui_calc_next_alarm gui_data.next_alarm_index=%d\n", gui_data.next_alarm_index);
/* calculate the is_skip_possible and the is_alarm flag */
gui_data.is_skip_possible = 0;
if ( lowest_i < GUI_ALARM_CNT )
{
if ( gui_alarm_list[lowest_i].na_minutes_diff == 0 )
{
if ( gui_data.is_equal == 0 )
{
gui_data.is_alarm = 1;
gui_data.is_equal = 1;
gui_data.active_alarm_idx = lowest_i;
//gui_data.active_equal_idx = lowest_i;
gui_data.equal_h = gui_data.h;
gui_data.equal_mt = gui_data.mt;
gui_data.equal_mo = gui_data.mo;
redo = 1;
}
}
else
{
/* valid next alarm time */
if ( gui_alarm_list[lowest_i].skip_wd == 0 )
{
/* skip flag not yet set */
if ( gui_alarm_list[lowest_i].na_minutes_diff <= (uint16_t)60*(uint16_t)ALLOW_SKIP_HOURS )
{
/* within the limit before alarm */
gui_data.is_skip_possible = 1;
}
}
}
}
} while( redo );
/* reset the equal flag */
if ( gui_data.is_equal != 0 )
{
if ( gui_data.equal_h != gui_data.h ||
gui_data.equal_mt != gui_data.mt ||
gui_data.equal_mo != gui_data.mo )
{
gui_data.is_equal = 0;
}
}
}
/*============================================*/
void gui_LoadData(void)
{
uint32_t data[5];
int i;
//printf("Load Data\n");
load_gui_data(data);
for( i = 0; i < GUI_ALARM_CNT; i++ )
{
set_alarm_data_by_u32(gui_alarm_list+i, data[i]);
}
gui_data.uptime = data[4] & (uint32_t)0x03ff;
gui_data.last_day = (data[4]>>10) & (uint32_t)31;
gui_data.contrast = (data[4]>>15) & (uint32_t)7;
gui_data.display_voltage = (data[4]>>16) & (uint32_t)1;
}
void gui_StoreData(void)
{
uint32_t data[5];
int i;
for( i = 0; i < GUI_ALARM_CNT; i++ )
{
data[i] = get_u32_by_alarm_data(gui_alarm_list+i);
//printf("%d: %08lx\n", i, data[i]);
}
data[4] = 0;
data[4] |= gui_data.uptime & (uint32_t)0x03ff; /* 0...1023 */
data[4] |= (gui_data.last_day & (uint32_t)31)<<10;
data[4] |= (gui_data.contrast & (uint32_t)7)<<15;
data[4] |= (gui_data.display_voltage & (uint32_t)1)<<16;
store_gui_data(data);
}
/* recalculate all internal data */
void gui_Recalculate(void)
{
int i;
gui_date_adjust();
gui_calc_week_time();
gui_calc_next_alarm();
for ( i = 0; i < GUI_ALARM_CNT; i++ )
{
gui_alarm_calc_str_time(i);
}
gui_StoreData();
}
/* minute and/or hour has changed */
/* additionally the active alarm menu might be set by this function */
void gui_SignalTimeChange(void)
{
/* recalculate dependent values */
gui_Recalculate();
/* setup menu */
menu_SetMEList(&gui_menu, melist_display_time, 0);
/* enable alarm */
if ( gui_data.is_alarm != 0 )
{
menu_SetMEList(&gui_menu, melist_active_alarm_menu, 0);
enable_alarm();
}
}
void gui_Init(u8g2_t *u8g2, uint8_t is_por)
{
if ( is_por == 0 )
{
/* not a POR reset, so load current values */
gui_LoadData();
/* do NOT init the display, otherwise there will be some flicker visible */
/* however, the GPIO subsystem still has to be setup, so call the other init procedures */
/* this acts like a warm start for the display */
/* the display setup code for the display is NOT send */
u8x8_gpio_Init(u8g2_GetU8x8(u8g2));
u8x8_cad_Init(u8g2_GetU8x8(u8g2));
u8x8_gpio_SetReset(u8g2_GetU8x8(u8g2), 1);
//u8g2_InitDisplay(u8g2);
//u8x8_d_helper_display_init(u8g2_GetU8x8(u8g2));
// u8g2_SetPowerSave(u8g2, 0); // this will be done later
}
else
{
/* POR reset, so do NOT load any values (they will be 0 in the best case) */
/* instead do a proper reset of the display */
// u8x8_InitDisplay(u8g2_GetU8x8(&u8g2));
u8g2_InitDisplay(u8g2);
// u8x8_SetPowerSave(u8g2_GetU8x8(&u8g2), 0);
u8g2_SetPowerSave(u8g2, 0);
}
menu_Init(&gui_menu, u8g2);
gui_SignalTimeChange();
}
void gui_Draw(void)
{
menu_Draw(&gui_menu);
}
void gui_Next(void)
{
if ( gui_menu.me_list == melist_active_alarm_menu )
{
disable_alarm();
if ( gui_alarm_list[gui_data.active_alarm_idx].snooze_count != 0 )
{
int i;
/* this is already the snooze alarm, so clear all and behave like the normal alarm off */
for( i = 0; i < GUI_ALARM_CNT; i++ )
gui_alarm_list[i].snooze_count = 0;
}
else
{
/* enable snooze */
gui_alarm_list[gui_data.active_alarm_idx].snooze_count = 1;
}
gui_data.is_alarm = 0;
gui_Recalculate();
menu_SetMEList(&gui_menu, melist_display_time, 0);
}
else
{
menu_NextFocus(&gui_menu);
}
}
void gui_Select(void)
{
if ( gui_menu.me_list == melist_active_alarm_menu )
{
int i;
disable_alarm();
for( i = 0; i < GUI_ALARM_CNT; i++ )
gui_alarm_list[i].snooze_count = 0;
gui_data.is_alarm = 0;
gui_Recalculate();
menu_SetMEList(&gui_menu, melist_display_time, 0);
}
else
{
menu_Select(&gui_menu);
}
}

View File

@@ -0,0 +1,120 @@
/*
guihal.c
*/
#include "gui.h"
#include <stdio.h>
/*============================================*/
/* reset */
void do_reset(void)
{
}
/*============================================*/
/* load & store from/to permanent memory */
/* 5x 32bit */
void store_gui_data(uint32_t *data)
{
FILE *fp;
fp = fopen("clock.dat", "w");
if ( fp != NULL )
{
fwrite(data, sizeof(uint32_t), 5, fp);
fclose(fp);
}
}
void load_gui_data(uint32_t *data)
{
FILE *fp;
int i;
for( i = 0; i < GUI_ALARM_CNT; i++ )
data[i] = 0;
fp = fopen("clock.dat", "r");
if ( fp != NULL )
{
fread(data, sizeof(uint32_t), 5, fp);
fclose(fp);
}
}
/*============================================*/
/* input */
int is_por_reset(void)
{
return 1;
}
int is_button_reset(void)
{
return 0;
}
uint32_t get_boot_status_register(void)
{
return 0;
}
uint32_t get_pwr_status_register(void)
{
return 0;
}
uint32_t get_reset_reason(void)
{
return 0;
}
uint32_t get_wakeup_count(void)
{
return 0;
}
uint32_t get_dst_by_date(void)
{
return -1;
}
uint32_t get_dst_by_RTC(void)
{
return 0;
}
/*============================================*/
/* output */
void enable_alarm(void)
{
}
void disable_alarm(void)
{
}
void set_time(uint8_t ht, uint8_t ho, uint8_t mt, uint8_t mo, uint8_t st, uint8_t so)
{
}
void set_date(uint8_t yt, uint8_t yo, uint8_t mt, uint8_t mo, uint8_t dayt, uint8_t dayo, uint8_t weekday)
{
}
/* set contrast to gui_data.contrast, value 1..7, 0 is default (do not set) */
void set_contrast(void)
{
}

View File

@@ -0,0 +1,864 @@
/*
guimenu.c
*/
#include "gui.h"
#include <string.h>
/*============================================*/
/* global variable for the gui menues */
uint8_t gui_alarm_index = 0;
gui_alarm_t gui_alarm_current;
const char weekdaystr[7][4] = {
"Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"
};
/*============================================*/
const static uint8_t ok_xbm[] = { /* 16x16 */
0xfe, 0x7f, 0x03, 0xc0, 0x01, 0x80, 0x01, 0xb8, 0x01, 0x9c, 0x01, 0x8e,
0x01, 0x87, 0x01, 0x87, 0x9d, 0x83, 0xb9, 0x83, 0xf1, 0x81, 0xe1, 0x81,
0xc1, 0x80, 0x01, 0x80, 0x03, 0xc0, 0xfe, 0x7f };
const static uint8_t alarm_xbm[] = { /* 12x12 */
0x00, 0x00, 0x0c, 0x06, 0xf6, 0x0d, 0x1a, 0x0b, 0x4c, 0x06, 0x44, 0x04,
0xc4, 0x05, 0x04, 0x04, 0x0c, 0x06, 0x18, 0x03, 0xf0, 0x01, 0x00, 0x00 };
int me_action_to_top_menu(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
menu_SetMEList(menu, melist_top_menu, 0);
return 1;
}
return 0;
}
int me_action_to_setup_menu(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
menu_SetMEList(menu, melist_setup_menu, 0);
return 1;
}
return 0;
}
int me_action_save_time(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
set_time(gui_data.h / 10, gui_data.h % 10, gui_data.mt, gui_data.mo, gui_data.st, gui_data.so);
//menu_SetMEList(menu, melist_top_menu, 0); /* first set the normal menu */
menu_SetMEList(menu, melist_setup_menu, 0);
gui_Recalculate(); /* because it might be overwritten with the alarm menu */
return 1;
}
return 0;
}
#ifdef D12832
#define ME_TIME_Y 19
#endif
#ifdef D12864
#define ME_TIME_Y 26
#endif
#ifdef D12832
#define ME_TIME_XO 11
const me_t melist_setup_time[] =
{
{ me_cb_0_23, &gui_data.h, NULL, ME_TIME_XO+2,ME_TIME_Y },
{ me_cb_num_label, NULL, ":", ME_TIME_XO+30,ME_TIME_Y-3 },
{ me_cb_0_5, &gui_data.mt, NULL, ME_TIME_XO+39,ME_TIME_Y },
{ me_cb_0_9, &gui_data.mo, NULL, ME_TIME_XO+52,ME_TIME_Y },
{ me_cb_num_label, NULL, ":", ME_TIME_XO+67,ME_TIME_Y-3 },
{ me_cb_0_5, &gui_data.st, NULL, ME_TIME_XO+67+9,ME_TIME_Y },
{ me_cb_0_9, &gui_data.so, NULL, ME_TIME_XO+80+9,ME_TIME_Y },
{ me_cb_button_half_line, (void *)me_action_to_setup_menu, "Abbrechen", 0,30 },
{ me_cb_button_half_line, (void *)me_action_save_time, "Speichern", 64,30 },
//{ me_cb_button_full_line, (void *)me_action_save_time, "Speichern", 40,30 },
{ me_cb_null, NULL, NULL, 0, 0 },
};
#endif
#ifdef D12864
#define ME_TIME_XO 11
const me_t melist_setup_time[] =
{
{ me_cb_0_23, &gui_data.h, NULL, 1,ME_TIME_Y },
{ me_cb_num_label, NULL, ":", 37,ME_TIME_Y-3 },
{ me_cb_0_5, &gui_data.mt, NULL, 45,ME_TIME_Y },
{ me_cb_0_9, &gui_data.mo, NULL, 63,ME_TIME_Y },
{ me_cb_num_label, NULL, ":", 81,ME_TIME_Y-3 },
{ me_cb_0_5, &gui_data.st, NULL, 89,ME_TIME_Y },
{ me_cb_0_9, &gui_data.so, NULL, 107,ME_TIME_Y },
{ me_cb_button_half_line, (void *)me_action_to_setup_menu, "Abbrechen", 0,42 },
{ me_cb_button_half_line, (void *)me_action_save_time, "Speichern", 64,42 },
//{ me_cb_button_full_line, (void *)me_action_save_time, "Speichern", 40,42 },
{ me_cb_null, NULL, NULL, 0, 0 },
};
#endif
/*============================================*/
/* Display Time */
void gui_alarm_to_str(uint8_t idx)
{
strcpy(gui_data.s, weekdaystr[gui_alarm_list[gui_data.next_alarm_index].na_wd]);
gui_data.s[2] = ',';
gui_data.s[3] = ' ';
strcpy(gui_data.s+4, u8x8_u8toa(gui_alarm_list[gui_data.next_alarm_index].na_h, 2));
gui_data.s[6] = ':';
strcpy(gui_data.s+7, u8x8_u8toa(gui_alarm_list[gui_data.next_alarm_index].na_m, 2));
if ( gui_alarm_list[gui_data.next_alarm_index].snooze_count != 0 )
{
gui_data.s[9] = '+';
gui_data.s[10] = '\0';
}
else
{
gui_data.s[9] = '\0';
}
}
int me_action_handle_display_time(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_DRAW )
{
char s[14];
u8g2_uint_t w;
#ifdef D12832
u8g2_uint_t x = 4;
u8g2_uint_t y = 30;
u8g2_SetFont(menu->u8g2, MENU_LARGE_FONT);
if ( gui_data.next_alarm_index < GUI_ALARM_CNT )
{
u8g2_DrawXBM(menu->u8g2, 67, y-11, 12, 12, (const uint8_t *)(alarm_xbm));
gui_alarm_to_str(gui_data.next_alarm_index);
u8g2_DrawUTF8(menu->u8g2, 81, y, gui_data.s);
}
else
{
x= 34;
}
strcpy(s, weekdaystr[gui_data.weekday]);
s[2] = ',';
s[3] = ' ';
strcpy(s+4, u8x8_u8toa(gui_data.day, 2));
s[6] = '.';
strcpy(s+7, u8x8_u8toa(gui_data.month, 2));
s[9] = '.';
s[10] = gui_data.year_t+'0';
s[11] = gui_data.year_o+'0';
s[12] = '\0';
u8g2_DrawUTF8(menu->u8g2, x, y, s);
#endif
#ifdef D12864
u8g2_uint_t x = 27;
u8g2_uint_t y = 61;
u8g2_SetFont(menu->u8g2, MENU_LARGE_FONT);
if ( gui_data.next_alarm_index < GUI_ALARM_CNT )
{
gui_alarm_to_str(gui_data.next_alarm_index);
w = u8g2_GetUTF8Width(menu->u8g2, gui_data.s)+14;
//u8g2_DrawUTF8(menu->u8g2, x+14, y, gui_data.s);
u8g2_DrawXBM(menu->u8g2, (128-w)/2, y-11, 12, 12, (const uint8_t *)(alarm_xbm));
u8g2_DrawUTF8(menu->u8g2, (128-w)/2+14, y, gui_data.s);
}
y -= 17;
x -= 3;
strcpy(s, weekdaystr[gui_data.weekday]);
s[2] = ',';
s[3] = ' ';
strcpy(s+4, u8x8_u8toa(gui_data.day, 2));
s[6] = '.';
strcpy(s+7, u8x8_u8toa(gui_data.month, 2));
s[9] = '.';
s[10] = gui_data.year_t+'0';
s[11] = gui_data.year_o+'0';
s[12] = '\0';
w = u8g2_GetUTF8Width(menu->u8g2, s);
u8g2_DrawUTF8(menu->u8g2, (128-w)/2, y, s);
#endif
return 1;
}
else if ( msg == ME_MSG_SELECT )
{
menu_SetMEList(menu, melist_top_menu, 0);
return 1;
}
return 0;
}
#ifdef D12832
#define ME_TIME_DXO 30
const me_t melist_display_time[] =
{
{ me_cb_0_23_ro, &gui_data.h, NULL, ME_TIME_DXO+2,ME_TIME_Y },
{ me_cb_num_label, NULL, ":", ME_TIME_DXO+30,ME_TIME_Y-3 },
{ me_cb_0_9_ro, &gui_data.mt, NULL, ME_TIME_DXO+39,ME_TIME_Y },
{ me_cb_0_9_ro, &gui_data.mo, NULL, ME_TIME_DXO+52,ME_TIME_Y },
{ me_cb_0_9_small_ro, &gui_data.st, NULL, 118,ME_TIME_Y },
{ me_cb_0_9_small_ro, &gui_data.so, NULL, 123,ME_TIME_Y },
{ me_cb_button_empty, (void *)me_action_handle_display_time, NULL, 0, 0 },
{ me_cb_null, NULL, NULL, 0, 0 },
};
#endif
#ifdef D12864
#define ME_TIME_DXO 29
const me_t melist_display_time[] =
{
{ me_cb_0_23_ro, &gui_data.h, NULL, ME_TIME_DXO-7,ME_TIME_Y },
{ me_cb_num_label, NULL, ":", ME_TIME_DXO+30,ME_TIME_Y-3 },
{ me_cb_0_9_ro, &gui_data.mt, NULL, ME_TIME_DXO+39,ME_TIME_Y },
{ me_cb_0_9_ro, &gui_data.mo, NULL, ME_TIME_DXO+57,ME_TIME_Y },
{ me_cb_0_9_small_ro, &gui_data.st, NULL, 118,ME_TIME_Y },
{ me_cb_0_9_small_ro, &gui_data.so, NULL, 123,ME_TIME_Y },
{ me_cb_button_empty, (void *)me_action_handle_display_time, NULL, 0, 0 },
{ me_cb_null, NULL, NULL, 0, 0 },
};
#endif
/*============================================*/
/* Date Edit Dialog */
int me_action_save_date(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
gui_date_adjust(); /* calculate the weekday */
set_date(gui_data.year_t, gui_data.year_o, gui_data.month / 10, gui_data.month % 10, gui_data.day / 10 , gui_data.day % 10, gui_data.weekday);
menu_SetMEList(menu, melist_setup_menu, 0); /* first set the normal menu */
gui_Recalculate(); /* because it might be overwritten with the alarm menu */
return 1;
}
return 0;
}
#ifdef D12832
const me_t melist_setup_date[] =
{
{ me_cb_1_31, &gui_data.day, NULL, ME_TIME_XO+2,ME_TIME_Y },
{ me_cb_num_label, NULL, ".", ME_TIME_XO+30,ME_TIME_Y },
{ me_cb_1_12, &gui_data.month, NULL, ME_TIME_XO+39,ME_TIME_Y },
{ me_cb_num_label, NULL, ".", ME_TIME_XO+67,ME_TIME_Y },
{ me_cb_0_9, &gui_data.year_t, NULL, ME_TIME_XO+67+9,ME_TIME_Y },
{ me_cb_0_9, &gui_data.year_o, NULL, ME_TIME_XO+80+9,ME_TIME_Y },
{ me_cb_button_full_line, (void *)me_action_save_date, "Speichern", 40,30 },
{ me_cb_null, NULL, NULL, 0, 0 },
};
#endif
#ifdef D12864
const me_t melist_setup_date[] =
{
{ me_cb_1_31, &gui_data.day, NULL, 1,ME_TIME_Y },
{ me_cb_num_label, NULL, ".", 37,ME_TIME_Y },
{ me_cb_1_12, &gui_data.month, NULL, 45,ME_TIME_Y },
{ me_cb_num_label, NULL, ".", 81,ME_TIME_Y },
{ me_cb_0_9, &gui_data.year_t, NULL, 89,ME_TIME_Y },
{ me_cb_0_9, &gui_data.year_o, NULL, 107,ME_TIME_Y },
//{ me_cb_button_full_line, (void *)me_action_save_date, "Speichern", 40,42 },
{ me_cb_button_half_line, (void *)me_action_to_setup_menu, "Abbrechen", 0,42 },
{ me_cb_button_half_line, (void *)me_action_save_date, "Speichern", 64,42 },
{ me_cb_null, NULL, NULL, 0, 0 },
};
#endif
/*============================================*/
/* Alarm Edit Dialog */
int me_action_alarm_done(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
gui_alarm_list[gui_alarm_index] = gui_alarm_current;
gui_alarm_list[gui_alarm_index].skip_wd = 0; /* clear the skip alarm (if any) */
gui_alarm_list[gui_alarm_index].snooze_count = 0; /* clear snooze (if any) */
//gui_alarm_calc_str_time(gui_alarm_index);
menu_SetMEList(menu, melist_alarm_menu, gui_alarm_index); /* first set the normal menu */
gui_Recalculate(); /* because it might be overwritten with the alarm menu */
return 1;
}
return 0;
}
#ifdef D12832
#define ME_ALARM_TIME_XO 28
#define ME_ALARM_TIME_Y 20
#define ME_ALARM_WD_Y 29
#define ME_ALARM_WD_XO 8
const me_t melist_setup_alarm[] =
{
{ me_cb_big_toggle, &(gui_alarm_current.enable), NULL, 4 , 6},
{ me_cb_0_23, &(gui_alarm_current.h), NULL, ME_ALARM_TIME_XO+2,ME_ALARM_TIME_Y },
{ me_cb_num_label, NULL, ":", ME_ALARM_TIME_XO+30,ME_ALARM_TIME_Y-3 },
{ me_cb_0_55, &(gui_alarm_current.m), NULL, ME_ALARM_TIME_XO+39,ME_ALARM_TIME_Y },
{ me_cb_wd_toggle, &(gui_alarm_current.wd[0]), (void *)weekdaystr[0], ME_ALARM_WD_XO+17*0, ME_ALARM_WD_Y},
{ me_cb_wd_toggle, &(gui_alarm_current.wd[1]), (void *)weekdaystr[1], ME_ALARM_WD_XO+17*1, ME_ALARM_WD_Y},
{ me_cb_wd_toggle, &(gui_alarm_current.wd[2]), (void *)weekdaystr[2], ME_ALARM_WD_XO+17*2, ME_ALARM_WD_Y},
{ me_cb_wd_toggle, &(gui_alarm_current.wd[3]), (void *)weekdaystr[3], ME_ALARM_WD_XO+17*3, ME_ALARM_WD_Y},
{ me_cb_wd_toggle, &(gui_alarm_current.wd[4]), (void *)weekdaystr[4], ME_ALARM_WD_XO+17*4, ME_ALARM_WD_Y},
{ me_cb_wd_toggle, &(gui_alarm_current.wd[5]), (void *)weekdaystr[5], ME_ALARM_WD_XO+17*5, ME_ALARM_WD_Y},
{ me_cb_wd_toggle, &(gui_alarm_current.wd[6]), (void *)weekdaystr[6], ME_ALARM_WD_XO+17*6, ME_ALARM_WD_Y},
{ me_cb_16x16_bitmap_button, (void *)me_action_alarm_done, (void *)ok_xbm, ME_ALARM_TIME_XO+80,ME_ALARM_TIME_Y-17 },
{ me_cb_null, NULL, NULL, 0, 0 },
};
#endif
#ifdef D12864
#define ME_ALARM_TIME_XO 28
#define ME_ALARM_TIME_Y 26
#define ME_ALARM_WD_Y 36
#define ME_ALARM_WD_XO 8
const me_t melist_setup_alarm[] =
{
{ me_cb_0_23, &(gui_alarm_current.h), NULL, ME_ALARM_TIME_XO-7,ME_ALARM_TIME_Y },
{ me_cb_num_label, NULL, ":", ME_ALARM_TIME_XO+30,ME_ALARM_TIME_Y-3 },
{ me_cb_0_55, &(gui_alarm_current.m), NULL, ME_ALARM_TIME_XO+39,ME_ALARM_TIME_Y },
{ me_cb_wd_toggle, &(gui_alarm_current.wd[0]), (void *)weekdaystr[0], ME_ALARM_WD_XO+17*0, ME_ALARM_WD_Y},
{ me_cb_wd_toggle, &(gui_alarm_current.wd[1]), (void *)weekdaystr[1], ME_ALARM_WD_XO+17*1, ME_ALARM_WD_Y},
{ me_cb_wd_toggle, &(gui_alarm_current.wd[2]), (void *)weekdaystr[2], ME_ALARM_WD_XO+17*2, ME_ALARM_WD_Y},
{ me_cb_wd_toggle, &(gui_alarm_current.wd[3]), (void *)weekdaystr[3], ME_ALARM_WD_XO+17*3, ME_ALARM_WD_Y},
{ me_cb_wd_toggle, &(gui_alarm_current.wd[4]), (void *)weekdaystr[4], ME_ALARM_WD_XO+17*4, ME_ALARM_WD_Y},
{ me_cb_wd_toggle, &(gui_alarm_current.wd[5]), (void *)weekdaystr[5], ME_ALARM_WD_XO+17*5, ME_ALARM_WD_Y},
{ me_cb_wd_toggle, &(gui_alarm_current.wd[6]), (void *)weekdaystr[6], ME_ALARM_WD_XO+17*6, ME_ALARM_WD_Y},
{ me_cb_big_toggle, (void *)&(gui_alarm_current.enable), NULL, 28, 47},
{ me_cb_16x16_bitmap_button, (void *)me_action_alarm_done, (void *)ok_xbm, 80, 44 },
{ me_cb_null, NULL, NULL, 0, 0 },
};
#endif
/*============================================*/
/* Alarm Setup Menu */
static int me_action_alarm_common(menu_t *menu, const me_t *me, uint8_t msg) U8G2_NOINLINE;
static int me_action_alarm_common(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
gui_alarm_current = gui_alarm_list[gui_alarm_index];
menu_SetMEList(menu, melist_setup_alarm, 0);
return 1;
}
return 0;
}
int me_action_alarm1(menu_t *menu, const me_t *me, uint8_t msg)
{
gui_alarm_index = 0;
return me_action_alarm_common(menu, me, msg);
}
int me_action_alarm2(menu_t *menu, const me_t *me, uint8_t msg)
{
gui_alarm_index = 1;
return me_action_alarm_common(menu, me, msg);
}
int me_action_alarm3(menu_t *menu, const me_t *me, uint8_t msg)
{
gui_alarm_index = 2;
return me_action_alarm_common(menu, me, msg);
}
int me_action_alarm4(menu_t *menu, const me_t *me, uint8_t msg)
{
gui_alarm_index = 3;
return me_action_alarm_common(menu, me, msg);
}
int me_action_handle_alarm_list(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_DRAW )
{
uint8_t y, x;
uint8_t ym;
u8g2_SetFont(menu->u8g2, MENU_SMALL_FONT);
for( y = 0; y < 4; y++ )
{
ym = y*8+7;
for( x = 0; x < 7; x++ )
{
u8g2_DrawGlyph(menu->u8g2, 0, ym, y+'1');
u8g2_DrawGlyph(menu->u8g2, 5, ym, ':');
u8g2_DrawStr(menu->u8g2, 9, ym, gui_alarm_str[y]);
if ( gui_alarm_list[y].wd[x] )
{
u8g2_DrawStr(menu->u8g2, 40+x*12, ym, weekdaystr[x]);
}
}
}
}
else if ( msg == ME_MSG_SELECT )
{
menu_SetMEList(menu, melist_alarm_menu, 4);
return 1;
}
return 0;
}
const me_t melist_alarm_list_menu[] =
{
{ me_cb_button_empty, (void *)me_action_handle_alarm_list, NULL, 0, 0 },
{ me_cb_null, NULL, NULL, 0, 0 },
};
int me_action_goto_alarm_list(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
menu_SetMEList(menu, melist_alarm_list_menu, 0);
return 1;
}
return 0;
}
#ifdef D12832
const me_t melist_alarm_menu[] =
{
{ me_cb_button_half_line, (void *)me_action_alarm1, gui_alarm_str[0], 0,10 },
{ me_cb_button_half_line, (void *)me_action_alarm2, gui_alarm_str[1], 64,10 },
{ me_cb_button_half_line, (void *)me_action_alarm3, gui_alarm_str[2], 0,20 },
{ me_cb_button_half_line, (void *)me_action_alarm4, gui_alarm_str[3], 64,20 },
{ me_cb_button_half_line, (void *)me_action_goto_alarm_list, "Liste", 0,30 },
{ me_cb_button_half_line, (void *)me_action_to_top_menu, "Zurück", 64,30 },
{ me_cb_null, NULL, NULL, 0, 0 },
};
#endif
#ifdef D12864
const me_t melist_alarm_menu[] =
{
{ me_cb_button_half_line, (void *)me_action_alarm1, gui_alarm_str[0], 0,12 },
{ me_cb_button_half_line, (void *)me_action_alarm2, gui_alarm_str[1], 64,12 },
{ me_cb_button_half_line, (void *)me_action_alarm3, gui_alarm_str[2], 0,24 },
{ me_cb_button_half_line, (void *)me_action_alarm4, gui_alarm_str[3], 64,24 },
{ me_cb_button_half_line, (void *)me_action_goto_alarm_list, "Liste", 0,36 },
{ me_cb_button_half_line, (void *)me_action_to_top_menu, "Zurück", 64,36 },
{ me_cb_null, NULL, NULL, 0, 0 },
};
#endif
/*============================================*/
/* Reset Menu */
int me_action_reset_no(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
menu_SetMEList(menu, melist_setup_menu, 0);
return 1;
}
return 0;
}
int me_action_reset_yes(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
do_reset();
return 1;
}
return 0;
}
const me_t melist_reset_menu[] =
{
{ me_cb_label, NULL, "Reset?", 44, 13},
{ me_cb_button_half_line, (void *)me_action_reset_no, "Nein", 0,30 },
{ me_cb_button_half_line, (void *)me_action_reset_yes, "Ja", 64,30 },
{ me_cb_null, NULL, NULL, 0, 0 },
};
/*============================================*/
/* Boot Info */
const char *bitstr(uint32_t v, int bitcnt)
{
static char s[34];
char *t = s;
uint32_t mask;
mask = 1<<(bitcnt-1);
while( mask > 0 )
{
*t = ((v & mask) == 0 ? '0' : '1');
t++;
mask >>= 1;
}
*t = '\0';
return s;
}
static const char *reset_reason_str[] = { "POR", "NVIC", "T2", "T3", "WUF" };
int me_action_handle_boot_info(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_DRAW )
{
u8g2_SetFont(menu->u8g2, MENU_SMALL_FONT);
u8g2_DrawStr(menu->u8g2, 0, 8-1, "RCC_CSR 31..24");
u8g2_DrawStr(menu->u8g2, 64, 8-1, bitstr(get_boot_status_register(), 8));
u8g2_DrawStr(menu->u8g2, 0, 16-1, "PWR_CSR 7..0");
u8g2_DrawStr(menu->u8g2, 64, 16-1, bitstr(get_pwr_status_register(), 8));
u8g2_DrawStr(menu->u8g2, 0, 24-1, "ResetReason");
u8g2_DrawStr(menu->u8g2, 64, 24-1, reset_reason_str[get_reset_reason()]);
u8g2_DrawStr(menu->u8g2, 0, 32-1, "Uptime");
u8g2_DrawStr(menu->u8g2, 64, 32-1, u8x8_u16toa(gui_data.uptime, 3));
u8g2_DrawStr(menu->u8g2, 0, 40-1, "Wakeups");
u8g2_DrawStr(menu->u8g2, 64, 40-1, u8x8_u16toa(get_wakeup_count(), 5));
u8g2_DrawStr(menu->u8g2, 0, 48-1, "DST by Date:");
u8g2_DrawStr(menu->u8g2, 50, 48-1, u8x8_u16toa(get_dst_by_date(), 2));
u8g2_DrawStr(menu->u8g2, 64, 48-1, "by RTC:");
u8g2_DrawStr(menu->u8g2, 95, 48-1, u8x8_u16toa(get_dst_by_RTC(), 1));
}
else if ( msg == ME_MSG_SELECT )
{
menu_SetMEList(menu, melist_display_time, 4);
return 1;
}
return 0;
}
const me_t melist_boot_info_menu[] =
{
{ me_cb_button_empty, (void *)me_action_handle_boot_info, NULL, 0, 0 },
{ me_cb_null, NULL, NULL, 0, 0 },
};
/*============================================*/
/* System Menu */
const me_t melist_system_menu[] =
{
{ me_cb_label, NULL, "Helligkeit:", 0, 10},
{ me_cb_scale_1_7, &(gui_data.contrast), NULL, 103-10, 8},
{ me_cb_label, NULL, "Batteriespannung:", 0, 10+12},
{ me_cb_big_toggle, &(gui_data.display_voltage), NULL, 100-7, 10+12-8},
{ me_cb_button_full_line, (void *)me_action_to_setup_menu, "Speichern", 40,10+2*12 },
{ me_cb_null, NULL, NULL, 0, 0 },
};
/*============================================*/
/* System 2 Menu */
int me_action_goto_boot_info(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
menu_SetMEList(menu, melist_boot_info_menu, 0);
return 1;
}
return 0;
}
int me_action_goto_reset(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
menu_SetMEList(menu, melist_reset_menu, 0);
return 1;
}
return 0;
}
const me_t melist_system_2_menu[] =
{
//{ me_cb_button_half_line, (void *)me_action_setup_time, "Uhrzeit", 0,10 },
//{ me_cb_button_half_line, (void *)me_action_setup_date, "Datum", 64,10 },
{ me_cb_button_half_line, (void *)me_action_goto_boot_info, "Info", 0,20 },
{ me_cb_button_half_line, (void *)me_action_goto_reset, "Reset", 64,20 },
{ me_cb_button_full_line, (void *)me_action_to_setup_menu, "Zurück", 40,30 },
{ me_cb_null, NULL, NULL, 0, 0 },
};
/*============================================*/
/* Setup Menu */
int me_action_setup_time(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
menu_SetMEList(menu, melist_setup_time, 0);
return 1;
}
return 0;
}
int me_action_setup_date(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
menu_SetMEList(menu, melist_setup_date, 0);
return 1;
}
return 0;
}
int me_action_goto_system(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
menu_SetMEList(menu, melist_system_menu, 0);
return 1;
}
return 0;
}
int me_action_goto_system_2(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
//menu_SetMEList(menu, melist_reset_menu, 0);
menu_SetMEList(menu, melist_system_2_menu, 0);
return 1;
}
return 0;
}
const me_t melist_setup_menu[] =
{
{ me_cb_button_half_line, (void *)me_action_setup_time, "Uhrzeit", 0,10 },
{ me_cb_button_half_line, (void *)me_action_setup_date, "Datum", 64,10 },
{ me_cb_button_half_line, (void *)me_action_goto_system, "Anzeige", 0,20 },
{ me_cb_button_half_line, (void *)me_action_goto_system_2, "System", 64,20 },
{ me_cb_button_full_line, (void *)me_action_to_top_menu, "Zurück", 40,31 },
{ me_cb_null, NULL, NULL, 0, 0 },
};
/*============================================*/
/* Alarm Menu */
int me_action_deactivate_alarm(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
menu_SetMEList(menu, melist_display_time, 0);
return 1;
}
return 0;
}
int me_action_do_snooze(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
menu_SetMEList(menu, melist_display_time, 0);
return 1;
}
return 0;
}
int me_cb_cond_inv_label(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( gui_data.is_alarm == 0 )
return me_cb_inv_label(menu, me, msg);
if ( gui_alarm_list[gui_data.active_alarm_idx].snooze_count == 0 )
return me_cb_inv_label(menu, me, msg);
return 0;
}
#ifdef D12832
const me_t melist_active_alarm_menu[] =
{
{ me_cb_label, NULL, "Alarm", 2, 13},
{ me_cb_0_23_ro, &gui_data.h, NULL, ME_TIME_DXO+2+20,ME_TIME_Y },
{ me_cb_num_label, NULL, ":", ME_TIME_DXO+30+20,ME_TIME_Y-3 },
{ me_cb_0_9_ro, &gui_data.mt, NULL, ME_TIME_DXO+39+20,ME_TIME_Y },
{ me_cb_0_9_ro, &gui_data.mo, NULL, ME_TIME_DXO+52+20,ME_TIME_Y },
{ me_cb_button_empty, (void *)me_action_deactivate_alarm, NULL, 0,0 },
//{ me_cb_button_half_line, (void *)me_action_deactivate_alarm, "Alarm aus", 0,30 },
//{ me_cb_button_half_line, (void *)me_action_do_snooze, "+5 Min ", 64,30 },
{ me_cb_inv_label, NULL, "Alarm aus", 4,30 },
{ me_cb_cond_inv_label, NULL, "+5 Min", 76,30 },
{ me_cb_null, NULL, NULL, 0, 0 },
};
#endif
#ifdef D12864
const me_t melist_active_alarm_menu[] =
{
{ me_cb_label, NULL, "Alarm", 2, 13},
{ me_cb_0_23_ro, &gui_data.h, NULL, ME_TIME_DXO+2+12,ME_TIME_Y },
{ me_cb_num_label, NULL, ":", ME_TIME_DXO+30+20,ME_TIME_Y-3 },
{ me_cb_0_9_ro, &gui_data.mt, NULL, ME_TIME_DXO+39+19,ME_TIME_Y },
{ me_cb_0_9_ro, &gui_data.mo, NULL, ME_TIME_DXO+52+24,ME_TIME_Y },
{ me_cb_button_empty, (void *)me_action_deactivate_alarm, NULL, 0,0 },
//{ me_cb_button_half_line, (void *)me_action_deactivate_alarm, "Alarm aus", 0,30 },
//{ me_cb_button_half_line, (void *)me_action_do_snooze, "+5 Min ", 64,30 },
{ me_cb_inv_label, NULL, "Alarm aus", 4,40 },
{ me_cb_cond_inv_label, NULL, "+5 Min", 76,40 },
{ me_cb_null, NULL, NULL, 0, 0 },
};
#endif
/*============================================*/
/* toplevel menu */
int me_action_to_display_time(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
menu_SetMEList(menu, melist_display_time, 0);
return 1;
}
return 0;
}
int me_action_to_alarm_menu(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
menu_SetMEList(menu, melist_alarm_menu, 0);
return 1;
}
return 0;
}
int me_cb_button_skip_alarm(menu_t *menu, const me_t *me, uint8_t msg)
{
int r = 0;
u8g2_uint_t x;
switch(msg)
{
case ME_MSG_IS_FOCUS:
return gui_data.is_skip_possible;
case ME_MSG_DRAW_FOCUS:
u8g2_SetFont(menu->u8g2, MENU_NORMAL_FONT);
menu_DrawBoxFocus(menu,
0,
me->y - u8g2_GetAscent(menu->u8g2)-1,
u8g2_GetDisplayWidth(menu->u8g2) ,
u8g2_GetAscent(menu->u8g2) - u8g2_GetDescent(menu->u8g2) +1);
r = 1;
break;
case ME_MSG_DRAW:
if ( gui_data.is_skip_possible )
{
u8g2_SetFont(menu->u8g2, MENU_NORMAL_FONT);
gui_alarm_to_str(gui_data.next_alarm_index);
x = u8g2_DrawUTF8(menu->u8g2, me->x, me->y, gui_data.s );
u8g2_DrawUTF8(menu->u8g2, me->x+x, me->y, " deaktvieren" );
}
r = 1;
break;
case ME_MSG_SELECT:
//printf("me_cb_button_skip_alarm ME_MSG_SELECT\n");
gui_alarm_list[gui_data.next_alarm_index].skip_wd =
gui_alarm_list[gui_data.next_alarm_index].na_wd + 1;
gui_alarm_list[gui_data.next_alarm_index].snooze_count = 0; /* clear snooze (if any) */
menu_SetMEList(menu, melist_display_time, 0); /* first set the normal menu */
gui_Recalculate(); /* it might be changed here to the alarm menu */
r = 1;
break;
}
return r;
}
#ifdef D12832
const me_t melist_top_menu[] =
{
{ me_cb_button_half_line, (void *)me_action_to_display_time, "Zurück", 0,10 },
{ me_cb_button_half_line, (void *)me_action_to_alarm_menu, "Alarm", 64,10 },
{ me_cb_button_skip_alarm, NULL, NULL, 3,20 },
{ me_cb_button_full_line, (void *)me_action_to_setup_menu, "Weitere Funktionen", 3,30 },
{ me_cb_null, NULL, NULL, 0, 0 },
};
#endif
#ifdef D12864
const me_t melist_top_menu[] =
{
{ me_cb_button_full_line, (void *)me_action_to_display_time, "Zurück", 3,12 },
{ me_cb_button_full_line, (void *)me_action_to_alarm_menu, "Alarm", 3,24 },
{ me_cb_button_skip_alarm, NULL, NULL, 3,36 },
{ me_cb_button_full_line, (void *)me_action_to_setup_menu, "Weitere Funktionen", 3,48 },
{ me_cb_null, NULL, NULL, 0, 0 },
};
#endif

View File

@@ -0,0 +1,103 @@
/*
main.c
*/
#include "gui.h"
#include <stdio.h>
u8g2_t u8g2;
int main(void)
{
int x, y;
int k;
int i;
u8g2_SetupBuffer_SDL_128x64_4(&u8g2, &u8g2_cb_r0);
gui_Init(&u8g2, 0);
x = 50;
y = 50;
for(;;)
{
u8g2_FirstPage(&u8g2);
i = 0;
do
{
gui_Draw();
i++;
} while( u8g2_NextPage(&u8g2) );
do
{
k = u8g_sdl_get_key();
} while( k < 0 );
if ( k == 'n' )
gui_Next();
if ( k == 's' )
gui_Select();
if ( k == 'm' )
{
gui_data.mo++;
if ( gui_data.mo >= 10 )
{
gui_data.mo = 0;
gui_data.mt++;
if ( gui_data.mt >= 60 )
{
gui_data.h++;
if ( gui_data.h >= 24 )
{
gui_data.h = 0;
gui_data.day++;
}
}
}
gui_SignalTimeChange();
}
if ( k == 'h' )
{
gui_data.h++;
if ( gui_data.h >= 24 )
{
gui_data.h = 0;
gui_data.day++;
}
gui_SignalTimeChange();
}
if ( k == 273 ) y -= 1;
if ( k == 274 ) y += 1;
if ( k == 276 ) x -= 1;
if ( k == 275 ) x += 1;
if ( k == 'q' ) break;
}
//u8x8_Set8x8Font(u8g2_GetU8x8(&u8g2), bdf_font);
//u8x8_Draw8x8String(u8g2_GetU8x8(&u8g2), 0, 0, "Hello World!");
return 0;
}

View File

@@ -0,0 +1,677 @@
/*
menu.c
*/
#include "menu.h"
/*================================================*/
void menu_DrawEdgePixel(menu_t *menu, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h)
{
w--;
h--;
u8g2_DrawPixel(menu->u8g2, x,y);
u8g2_DrawPixel(menu->u8g2, x+w,y);
u8g2_DrawPixel(menu->u8g2, x,y+h);
u8g2_DrawPixel(menu->u8g2, x+w,y+h);
}
void menu_ClearEdgePixel(menu_t *menu, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h)
{
u8g2_SetDrawColor(menu->u8g2, 0);
menu_DrawEdgePixel(menu, x, y, w, h);
u8g2_SetDrawColor(menu->u8g2, 1);
}
void menu_DrawBoxFocus(menu_t *menu, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h)
{
u8g2_SetDrawColor(menu->u8g2, 2);
u8g2_DrawBox(menu->u8g2, x, y, w, h);
menu_ClearEdgePixel(menu, x, y, w, h);
}
void menu_DrawFrameFocus(menu_t *menu, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h)
{
menu_DrawEdgePixel(menu, x, y, w, h);
x--;
y--;
w+=2;
h+=2;
u8g2_DrawFrame(menu->u8g2, x, y, w, h);
menu_ClearEdgePixel(menu, x, y, w, h);
}
/*================================================*/
/* this function must be the last function in the list. it also marks the end of a list */
int me_cb_null(menu_t *menu, const me_t *me, uint8_t msg)
{
return 0;
}
/*
Name: me_cb_big_toggle
Val: uint8_t *
Arg: Not used
*/
int me_cb_big_toggle(menu_t *menu, const me_t *me, uint8_t msg)
{
uint8_t val = *(uint8_t *)(me->val);
u8g2_uint_t x, y, w, h, w2;
w = 16;
w2 = 6;
h = 10;
x = me->x;
y = me->y;
switch(msg)
{
case ME_MSG_IS_FOCUS:
return 1;
case ME_MSG_DRAW_FOCUS:
//menu_DrawFrameFocus(menu, x-1, y-1, w+2, h+2);
menu_DrawFrameFocus(menu, x, y, w, h);
return 1;
case ME_MSG_SELECT:
{
val++;
if ( val > 1 )
val = 0;
*(uint8_t *)(me->val) = val;
}
return 1;
case ME_MSG_DRAW:
menu_DrawFrameFocus(menu, x+1,y+1,w-2,h-2);
if ( val == 0 )
{
menu_DrawFrameFocus(menu, x+3,y+3,w2-2,h-6);
}
else
{
menu_DrawBoxFocus(menu, x+w/2,y+2,w2,h-4);
}
return 1;
}
return 0;
}
/*
Name: me_cb_wd_toggle
Val: uint8_t *
Arg: char *
*/
int me_cb_wd_toggle(menu_t *menu, const me_t *me, uint8_t msg)
{
uint8_t val = *(uint8_t *)(me->val);
u8g2_uint_t x, y, w, h;
u8g2_SetFont(menu->u8g2, MENU_SMALL_FONT);
w = 13;
h = u8g2_GetAscent(menu->u8g2)+2;
x = me->x-2;
y = me->y - u8g2_GetAscent(menu->u8g2)-1;
switch(msg)
{
case ME_MSG_IS_FOCUS:
return 1;
case ME_MSG_DRAW_FOCUS:
menu_DrawFrameFocus(menu, x, y, w, h);
return 1;
case ME_MSG_SELECT:
{
val++;
if ( val > 1 )
val = 0;
*(uint8_t *)(me->val) = val;
}
return 1;
case ME_MSG_DRAW:
u8g2_DrawUTF8(menu->u8g2, me->x, me->y, (const char *)(me->arg));
if ( val > 0 )
{
menu_DrawBoxFocus(menu, x,y,w,h);
}
//u8g2_DrawRFrame(menu->u8g2, x, y, w, h, 1);
return 1;
}
return 0;
}
/*
Name: me_cb_0_9
Val: uint8_t *
*/
int me_cb_0_9(menu_t *menu, const me_t *me, uint8_t msg)
{
switch(msg)
{
case ME_MSG_IS_FOCUS:
return 1;
case ME_MSG_DRAW_FOCUS:
u8g2_SetFont(menu->u8g2, MENU_BIG_NUM);
menu_DrawBoxFocus(menu,
me->x+MENU_BIG_NUM_FOCUS_XO,
me->y - u8g2_GetAscent(menu->u8g2)-1,
u8g2_GetGlyphWidth(menu->u8g2, '0')+MENU_BIG_NUM_FOCUS_EXTRAX,
u8g2_GetAscent(menu->u8g2) + 2);
return 1;
case ME_MSG_SELECT:
{
uint8_t val = *(uint8_t *)(me->val);
val++;
if ( val > 9 )
val = 0;
*(uint8_t *)(me->val) = val;
}
return 1;
case ME_MSG_DRAW:
u8g2_SetFont(menu->u8g2, MENU_BIG_NUM);
u8g2_DrawGlyph(menu->u8g2, me->x, me->y, *(uint8_t *)(me->val) + '0');
return 1;
}
return 0;
}
int me_cb_0_9_ro(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_IS_FOCUS )
return 0;
return me_cb_0_9(menu, me, msg);
}
/*
Name: me_cb_0_5
Val: uint8_t *
*/
int me_cb_0_5(menu_t *menu, const me_t *me, uint8_t msg)
{
switch(msg)
{
case ME_MSG_SELECT:
{
uint8_t val = *(uint8_t *)(me->val);
val++;
if ( val > 5 )
val = 0;
*(uint8_t *)(me->val) = val;
}
return 1;
}
return me_cb_0_9(menu, me, msg);
}
/*
Name: me_cb_0_23
Val: uint8_t *
*/
int me_cb_0_23(menu_t *menu, const me_t *me, uint8_t msg)
{
char s[4];
switch(msg)
{
case ME_MSG_IS_FOCUS:
return 1;
case ME_MSG_DRAW_FOCUS:
u8g2_SetFont(menu->u8g2, MENU_BIG_NUM);
menu_DrawBoxFocus(menu,
me->x+MENU_BIG_NUM_FOCUS_XO,
me->y - u8g2_GetAscent(menu->u8g2)-1,
u8g2_GetGlyphWidth(menu->u8g2, '0')*2+MENU_BIG_NUM_FOCUS_EXTRAX,
u8g2_GetAscent(menu->u8g2) + 2);
return 1;
case ME_MSG_SELECT:
{
uint8_t val = *(uint8_t *)(me->val);
val++;
if ( val > 23 )
val = 0;
*(uint8_t *)(me->val) = val;
}
return 1;
case ME_MSG_DRAW:
u8g2_SetFont(menu->u8g2, MENU_BIG_NUM);
s[0] = *(uint8_t *)(me->val);
s[1] = s[0];
s[1] %= 10;
s[1] += '0';
s[0] /= 10;
s[0] += '0';
s[2] = '\0';
u8g2_DrawUTF8(menu->u8g2, me->x, me->y, s);
return 1;
}
return 0;
}
int me_cb_0_23_ro(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_IS_FOCUS )
return 0;
return me_cb_0_23(menu, me, msg);
}
int me_cb_0_9_small_ro(menu_t *menu, const me_t *me, uint8_t msg)
{
switch(msg)
{
case ME_MSG_IS_FOCUS:
return 0;
case ME_MSG_DRAW_FOCUS:
return 1;
case ME_MSG_SELECT:
return 1;
case ME_MSG_DRAW:
u8g2_SetFont(menu->u8g2, MENU_SMALL_FONT);
u8g2_DrawGlyph(menu->u8g2, me->x, me->y, *(uint8_t *)(me->val) + '0');
return 1;
}
return 0;
}
/*
Name: me_cb_0_55
Val: uint8_t *
*/
int me_cb_0_55(menu_t *menu, const me_t *me, uint8_t msg)
{
switch(msg)
{
case ME_MSG_SELECT:
{
uint8_t val = *(uint8_t *)(me->val);
val+=5;
if ( val > 55 )
val = 0;
*(uint8_t *)(me->val) = val;
}
return 1;
}
return me_cb_0_23(menu, me, msg);
}
/*
Name: me_cb_1_12
Val: uint8_t *
*/
int me_cb_1_12(menu_t *menu, const me_t *me, uint8_t msg)
{
switch(msg)
{
case ME_MSG_SELECT:
{
uint8_t val = *(uint8_t *)(me->val);
val++;
if ( val > 12 )
val = 1;
*(uint8_t *)(me->val) = val;
}
return 1;
}
return me_cb_0_23(menu, me, msg);
}
/*
Name: me_cb_1_31
Val: uint8_t *
*/
int me_cb_1_31(menu_t *menu, const me_t *me, uint8_t msg)
{
switch(msg)
{
case ME_MSG_SELECT:
{
uint8_t val = *(uint8_t *)(me->val);
val++;
if ( val > 31 )
val = 1;
*(uint8_t *)(me->val) = val;
}
return 1;
}
return me_cb_0_23(menu, me, msg);
}
/*
Name: me_cb_num_label
can not get focus
Arg: char *
*/
int me_cb_num_label(menu_t *menu, const me_t *me, uint8_t msg)
{
switch(msg)
{
case ME_MSG_IS_FOCUS:
case ME_MSG_DRAW_FOCUS:
case ME_MSG_SELECT:
break;
case ME_MSG_DRAW:
u8g2_SetFont(menu->u8g2, MENU_BIG_NUM);
u8g2_DrawUTF8(menu->u8g2, me->x, me->y, (char *)(me->arg) );
return 1;
}
return 0;
}
/*
Name: me_cb_button_full_line
Val: callback function
Arg: char *
*/
int me_cb_button_full_line(menu_t *menu, const me_t *me, uint8_t msg)
{
int r = 0;
switch(msg)
{
case ME_MSG_IS_FOCUS:
return 1;
case ME_MSG_DRAW_FOCUS:
menu_DrawBoxFocus(menu,
0,
me->y - u8g2_GetAscent(menu->u8g2)-1,
u8g2_GetDisplayWidth(menu->u8g2) ,
u8g2_GetAscent(menu->u8g2) - u8g2_GetDescent(menu->u8g2) +1);
r = 1;
break;
case ME_MSG_DRAW:
u8g2_SetFont(menu->u8g2, MENU_NORMAL_FONT);
u8g2_DrawUTF8(menu->u8g2, me->x, me->y, (char *)(me->arg) );
r = 1;
break;
}
/* pass all messages except for the IS_FOCUS also to the callback function */
if ( me->val != NULL )
return ((me_cb)(me->val))(menu, me, msg) | r;
return r;
}
/*
Name: me_cb_button_full_line
Val: callback function
Arg: char *
*/
int me_cb_button_half_line(menu_t *menu, const me_t *me, uint8_t msg)
{
int r = 0;
switch(msg)
{
case ME_MSG_IS_FOCUS:
return 1;
case ME_MSG_DRAW_FOCUS:
menu_DrawBoxFocus(menu,
me->x,
me->y - u8g2_GetAscent(menu->u8g2)-1,
u8g2_GetDisplayWidth(menu->u8g2)/2,
u8g2_GetAscent(menu->u8g2) - u8g2_GetDescent(menu->u8g2) +1);
r = 1;
break;
case ME_MSG_DRAW:
u8g2_SetFont(menu->u8g2, MENU_NORMAL_FONT);
u8g2_DrawUTF8(menu->u8g2, me->x+4, me->y, (char *)(me->arg) );
r = 1;
break;
}
/* pass all messages except for the IS_FOCUS also to the callback function */
if ( me->val != NULL )
return ((me_cb)(me->val))(menu, me, msg) | r;
return r;
}
/*
Name: me_cb_button_empty
Val: callback function
Arg: not used
*/
int me_cb_button_empty(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_IS_FOCUS )
return 1;
if ( me->val != NULL )
return ((me_cb)(me->val))(menu, me, msg);
return 0;
}
/*
Name: me_cb_scale_1_7
Val: uint8_t *
*/
void set_contrast(void);
int me_cb_scale_1_7(menu_t *menu, const me_t *me, uint8_t msg)
{
u8g2_uint_t x;
uint8_t val = *(uint8_t *)(me->val);
if ( val <= 0 )
val = 1;
x = me->x+(val-1)*5;
switch(msg)
{
case ME_MSG_IS_FOCUS:
return 1;
case ME_MSG_DRAW_FOCUS:
/*
u8g2_SetFont(menu->u8g2, MENU_BIG_NUM);
menu_DrawBoxFocus(menu,
me->x+MENU_BIG_NUM_FOCUS_XO,
me->y - u8g2_GetAscent(menu->u8g2)-1,
u8g2_GetGlyphWidth(menu->u8g2, '0')+MENU_BIG_NUM_FOCUS_EXTRAX,
u8g2_GetAscent(menu->u8g2) + 2);
*/
u8g2_DrawBox(menu->u8g2, x-2 , me->y-2, 5, 5);
return 1;
case ME_MSG_SELECT:
{
val++;
if ( val > 7 )
val = 1;
*(uint8_t *)(me->val) = val;
}
return 1;
case ME_MSG_DRAW:
set_contrast(); /* give user feedback... not so nice: We assume *(uint8_t *)(me->val) points to gui_data.contrast */
//u8g2_SetFont(menu->u8g2, MENU_NORMAL_FONT);
//u8g2_DrawGlyph(menu->u8g2, me->x, me->y-2, *(uint8_t *)(me->val) + '0');
u8g2_DrawHLine(menu->u8g2, me->x, me->y, 6*5+1);
u8g2_DrawVLine(menu->u8g2, me->x, me->y-2, 5);
//u8g2_DrawVLine(menu->u8g2, me->x+1*5, me->y-1, 3);
//u8g2_DrawVLine(menu->u8g2, me->x+2*5, me->y-1, 3);
u8g2_DrawVLine(menu->u8g2, me->x+3*5, me->y-2, 5);
//u8g2_DrawVLine(menu->u8g2, me->x+4*5, me->y-1, 3);
//u8g2_DrawVLine(menu->u8g2, me->x+5*5, me->y-1, 3);
u8g2_DrawVLine(menu->u8g2, me->x+6*5, me->y-2, 5);
u8g2_DrawFrame(menu->u8g2, x-3 , me->y-3, 7, 7);
u8g2_SetDrawColor(menu->u8g2, 0);
u8g2_DrawBox(menu->u8g2, x-2 , me->y-2, 5, 5);
/* draw color is set to 1 in the following function */
menu_ClearEdgePixel(menu, x-3 , me->y-3, 7, 7);
menu_DrawEdgePixel(menu, x-2 , me->y-3+1, 5, 5);
return 1;
}
return 0;
}
/*
Name: me_cb_label
can not get focus
Arg: char *
*/
int me_cb_label(menu_t *menu, const me_t *me, uint8_t msg)
{
switch(msg)
{
case ME_MSG_IS_FOCUS:
case ME_MSG_DRAW_FOCUS:
case ME_MSG_SELECT:
break;
case ME_MSG_DRAW:
u8g2_SetFont(menu->u8g2, MENU_NORMAL_FONT);
u8g2_DrawUTF8(menu->u8g2, me->x, me->y, (char *)(me->arg) );
return 1;
}
return 0;
}
int me_cb_inv_label(menu_t *menu, const me_t *me, uint8_t msg)
{
int r = me_cb_label(menu, me, msg);
if ( msg == ME_MSG_DRAW )
{
menu_DrawBoxFocus(menu,
me->x-1,
me->y - u8g2_GetAscent(menu->u8g2)-1,
u8g2_GetUTF8Width(menu->u8g2, (char *)(me->arg))+2,
u8g2_GetAscent(menu->u8g2) + 2);
}
return r;
}
/*
Name: me_cb_button_full_line
Val: callback function
Arg: bitmap
*/
int me_cb_16x16_bitmap_button(menu_t *menu, const me_t *me, uint8_t msg)
{
int r = 0;
switch(msg)
{
case ME_MSG_IS_FOCUS:
return 1;
case ME_MSG_DRAW_FOCUS:
/*
menu_DrawFrameFocus(menu,
me->x-1,
me->y-1,
16+2,
16+2);
*/
menu_DrawFrameFocus(menu,
me->x,
me->y,
16,
16);
r = 1;
break;
case ME_MSG_DRAW:
u8g2_DrawXBM(menu->u8g2, me->x, me->y, 16, 16, (const uint8_t *)(me->arg));
r = 1;
break;
}
/* pass all messages except for the IS_FOCUS also to the callback function */
if ( me->val != NULL )
return ((me_cb)(me->val))(menu, me, msg) | r;
return r;
}
/*================================================*/
/* call menu element from menu->current_index */
int menu_CallME(menu_t *menu, uint8_t msg)
{
const me_t *me;
me = menu->me_list+menu->current_index;
return me->cb(menu, me, msg);
}
/* stay on current focus if valid, move to next valid focus */
static void menu_CalcNextValidFocus(menu_t *menu) U8G2_NOINLINE;
static void menu_CalcNextValidFocus(menu_t *menu)
{
for(;;)
{
menu->current_index = menu->focus_index;
if ( menu->current_index >= menu->me_count )
break;
if ( menu_CallME(menu, ME_MSG_IS_FOCUS) != 0 )
break;
menu->focus_index++;
}
}
/* advance current focus to the next element */
void menu_NextFocus(menu_t *menu)
{
menu->focus_index++;
if ( menu->focus_index >= menu->me_count )
menu->focus_index = 0;
menu_CalcNextValidFocus(menu);
}
/* send select message to the element which has the current focus */
void menu_Select(menu_t *menu)
{
menu->current_index = menu->focus_index;
menu_CallME(menu, ME_MSG_SELECT);
}
void menu_SetMEList(menu_t *menu, const me_t *me_list, uint16_t initial_focus)
{
menu->me_list = me_list;
menu->me_count = 0;
while( me_list[menu->me_count].cb != me_cb_null )
menu->me_count++;
menu->focus_index = 0;
menu_CalcNextValidFocus(menu);
while( initial_focus > 0 )
{
menu_NextFocus(menu);
initial_focus--;
}
menu->radio_index = menu->me_count;
}
me_t melist_emty[] =
{
{ me_cb_null, NULL, 0, 0 }
};
void menu_Init(menu_t *menu, u8g2_t *u8g2)
{
menu->u8g2 = u8g2;
menu_SetMEList(menu, melist_emty, 0);
}
void menu_Draw(menu_t *menu)
{
for( menu->current_index = 0; menu->current_index < menu->me_count; menu->current_index++ )
{
menu_CallME(menu, ME_MSG_DRAW);
if ( menu->current_index == menu->focus_index )
{
menu_CallME(menu, ME_MSG_DRAW_FOCUS);
}
}
// u8g2_DrawHLine(menu->u8g2, 0, 32, 128);
}

View File

@@ -0,0 +1,110 @@
#ifndef _MENU_H
#define _MENU_H
#include "u8g2.h"
//#define D12832
#define D12864
#ifdef D12832
#define MENU_SMALL_FONT u8g2_font_baby_tr
#define MENU_NORMAL_FONT u8g2_font_ncenR08_tf
#define MENU_LARGE_FONT u8g2_font_ncenR08_tf
#define MENU_BIG_NUM u8g2_font_ncenR18_tn
#define MENU_BIG_NUM_FOCUS_XO 0
#define MENU_BIG_NUM_FOCUS_EXTRAX 0
#endif
#ifdef D12864
#define MENU_SMALL_FONT u8g2_font_baby_tr
#define MENU_NORMAL_FONT u8g2_font_ncenR08_tf
#define MENU_LARGE_FONT u8g2_font_ncenR10_tf
#define MENU_BIG_NUM u8g2_font_ncenR24_tn
#define MENU_BIG_NUM_FOCUS_XO 0
#define MENU_BIG_NUM_FOCUS_EXTRAX 1
#endif
typedef struct _menu_struct menu_t;
typedef struct _me_struct me_t;
typedef int (*me_cb)(menu_t *menu, const me_t *me, uint8_t msg);
struct _me_struct
{
me_cb cb;
void *val;
void *arg;
u8g2_uint_t x;
u8g2_uint_t y;
};
/* return 1, if this element can have focus */
#define ME_MSG_IS_FOCUS 1
/* draw focus graphics for the element */
#define ME_MSG_DRAW_FOCUS 2
/* user has pressed the select key */
#define ME_MSG_SELECT 3
/* advice for drawing */
#define ME_MSG_DRAW 4
struct _menu_struct
{
u8g2_t *u8g2;
volatile uint16_t current_index; /* element which is processed right now */
uint16_t focus_index; /* element which has the focus at the moment */
uint16_t radio_index; /* if elements for a radio selection, then this is set by the cb */
uint16_t me_count; /* total number of elements in the list */
/* pointer to the list of menu elements */
const me_t *me_list;
};
void menu_SetEdgePixel(menu_t *menu, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h) U8G2_NOINLINE;
void menu_ClearEdgePixel(menu_t *menu, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h) U8G2_NOINLINE;
void menu_DrawBoxFocus(menu_t *menu, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h) U8G2_NOINLINE;
void menu_DrawFrameFocus(menu_t *menu, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h) U8G2_NOINLINE;
void menu_Init(menu_t *menu, u8g2_t *u8g2);
void menu_SetMEList(menu_t *menu, const me_t *me_list, uint16_t initial_focus);
void menu_Draw(menu_t *menu);
void menu_NextFocus(menu_t *menu);
void menu_Select(menu_t *menu);
int me_cb_null(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_big_toggle(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_wd_toggle(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_0_5(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_0_9(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_0_9_ro(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_0_23(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_0_23_ro(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_0_9_small_ro(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_0_55(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_1_12(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_1_31(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_num_label(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_button_full_line(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_button_half_line(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_button_empty(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_scale_1_7(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_label(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_inv_label(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_16x16_bitmap_button(menu_t *menu, const me_t *me, uint8_t msg);
#endif

View File

@@ -0,0 +1,425 @@
/*
u8x8_d_sdl_128x64.c
*/
#include "u8g2.h"
#ifndef NO_SDL
#include "SDL.h"
#endif
#include <assert.h>
//#define HEIGHT (64)
//#define WIDTH 128
#define W(x,w) (((x)*(w))/100)
#ifndef NO_SDL
SDL_Window *u8g_sdl_window;
SDL_Surface *u8g_sdl_screen;
#endif
int u8g_sdl_multiple = 3;
uint32_t u8g_sdl_color[256];
int u8g_sdl_height, u8g_sdl_width;
static void u8g_sdl_set_pixel(int x, int y, int idx)
{
uint32_t *ptr;
uint32_t offset;
int i, j;
if ( y >= u8g_sdl_height )
return;
if ( y < 0 )
return;
if ( x >= u8g_sdl_width )
return;
if ( x < 0 )
return;
for( i = 0; i < u8g_sdl_multiple; i++ )
for( j = 0; j < u8g_sdl_multiple; j++ )
{
#ifndef NO_SDL
offset = (
((y * u8g_sdl_multiple) + i) * (u8g_sdl_width * u8g_sdl_multiple) +
((x * u8g_sdl_multiple) + j)) * u8g_sdl_screen->format->BytesPerPixel;
assert( offset < (Uint32)(u8g_sdl_width * u8g_sdl_multiple * u8g_sdl_height * u8g_sdl_multiple * u8g_sdl_screen->format->BytesPerPixel) );
ptr = u8g_sdl_screen->pixels + offset;
*ptr = u8g_sdl_color[idx];
#endif
}
}
static void u8g_sdl_set_8pixel(int x, int y, uint8_t pixel)
{
int cnt = 8;
int bg = 0;
if ( (x/8 + y/8) & 1 )
bg = 4;
while( cnt > 0 )
{
if ( (pixel & 1) == 0 )
{
u8g_sdl_set_pixel(x,y,bg);
}
else
{
u8g_sdl_set_pixel(x,y,3);
}
pixel >>= 1;
y++;
cnt--;
}
}
static void u8g_sdl_set_multiple_8pixel(int x, int y, int cnt, uint8_t *pixel)
{
uint8_t b;
while( cnt > 0 )
{
b = *pixel;
u8g_sdl_set_8pixel(x, y, b);
x++;
pixel++;
cnt--;
}
}
static void u8g_sdl_init(int width, int height)
{
u8g_sdl_height = height;
u8g_sdl_width = width;
#ifndef NO_SDL
if (SDL_Init(SDL_INIT_VIDEO) != 0)
{
printf("Unable to initialize SDL: %s\n", SDL_GetError());
exit(1);
}
u8g_sdl_window = SDL_CreateWindow("U8g2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, u8g_sdl_width * u8g_sdl_multiple, u8g_sdl_height * u8g_sdl_multiple, 0);
if ( u8g_sdl_window == NULL )
{
printf("Couldn't create window: %s\n", SDL_GetError());
exit(1);
}
u8g_sdl_screen = SDL_GetWindowSurface(u8g_sdl_window);
if ( u8g_sdl_screen == NULL )
{
printf("Couldn't create screen: %s\n", SDL_GetError());
exit(1);
}
printf("%d bits-per-pixel mode\n", u8g_sdl_screen->format->BitsPerPixel);
printf("%d bytes-per-pixel mode\n", u8g_sdl_screen->format->BytesPerPixel);
u8g_sdl_color[0] = SDL_MapRGB( u8g_sdl_screen->format, 0, 0, 0 );
u8g_sdl_color[1] = SDL_MapRGB( u8g_sdl_screen->format, W(100, 50), W(255,50), 0 );
u8g_sdl_color[2] = SDL_MapRGB( u8g_sdl_screen->format, W(100, 80), W(255,80), 0 );
u8g_sdl_color[3] = SDL_MapRGB( u8g_sdl_screen->format, 100, 255, 0 );
u8g_sdl_color[4] = SDL_MapRGB( u8g_sdl_screen->format, 30, 30, 30 );
/*
u8g_sdl_set_pixel(0,0);
u8g_sdl_set_pixel(1,1);
u8g_sdl_set_pixel(2,2);
*/
/* update all */
SDL_UpdateWindowSurface(u8g_sdl_window);
atexit(SDL_Quit);
#endif
return;
}
/*
void main(void)
{
u8g_sdl_init();
u8g_sdl_set_pixel(0,0,3);
u8g_sdl_set_pixel(0,1,3);
u8g_sdl_set_pixel(0,2,3);
u8g_sdl_set_pixel(1,1,3);
u8g_sdl_set_pixel(2,2,3);
while( u8g_sdl_get_key() < 0 )
;
}
*/
static const u8x8_display_info_t u8x8_sdl_128x64_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 0,
/* pre_chip_disable_wait_ns = */ 0,
/* reset_pulse_width_ms = */ 0,
/* post_reset_wait_ms = */ 0,
/* sda_setup_time_ns = */ 0,
/* sck_pulse_width_ns = */ 0,
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 1,
/* i2c_bus_clock_100kHz = */ 0,
/* data_setup_time_ns = */ 0,
/* write_pulse_width_ns = */ 0,
/* tile_width = */ 16,
/* tile_hight = */ 8,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 128,
/* pixel_height = */ 64
};
static const u8x8_display_info_t u8x8_sdl_240x160_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 0,
/* pre_chip_disable_wait_ns = */ 0,
/* reset_pulse_width_ms = */ 0,
/* post_reset_wait_ms = */ 0,
/* sda_setup_time_ns = */ 0,
/* sck_pulse_width_ns = */ 0,
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 1,
/* i2c_bus_clock_100kHz = */ 0,
/* data_setup_time_ns = */ 0,
/* write_pulse_width_ns = */ 0,
/* tile_width = */ 30, /* width of 30*8=240 pixel */
/* tile_hight = */ 20, /* height: 160 pixel */
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 240,
/* pixel_height = */ 160
};
static uint8_t u8x8_d_sdl_gpio(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
static int debounce_cnt = 0;
static int curr_msg = 0;
static int db_cnt = 10;
int event;
if ( curr_msg > 0 )
{
if ( msg == curr_msg )
{
u8x8_SetGPIOResult(u8x8, 0);
if ( debounce_cnt == 0 )
curr_msg = 0;
else
debounce_cnt--;
return 1;
}
}
else
{
event = u8g_sdl_get_key();
switch(event)
{
case 273:
curr_msg = U8X8_MSG_GPIO_MENU_UP;
debounce_cnt = db_cnt;
break;
case 274:
curr_msg = U8X8_MSG_GPIO_MENU_DOWN;
debounce_cnt = db_cnt;
break;
case 275:
curr_msg = U8X8_MSG_GPIO_MENU_NEXT;
debounce_cnt = db_cnt;
break;
case 276:
curr_msg = U8X8_MSG_GPIO_MENU_PREV;
debounce_cnt = db_cnt;
break;
case 's':
curr_msg = U8X8_MSG_GPIO_MENU_SELECT;
debounce_cnt = db_cnt;
break;
case 'q':
curr_msg = U8X8_MSG_GPIO_MENU_HOME;
debounce_cnt = db_cnt;
break;
}
}
u8x8_SetGPIOResult(u8x8, 1);
return 1;
}
uint8_t u8x8_d_sdl_128x64(u8x8_t *u8g2, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, y, c;
uint8_t *ptr;
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8g2, &u8x8_sdl_128x64_info);
u8g_sdl_init(128, 64);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8g2);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
break;
case U8X8_MSG_DISPLAY_SET_CONTRAST:
break;
case U8X8_MSG_DISPLAY_DRAW_TILE:
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8g2->x_offset;
y = ((u8x8_tile_t *)arg_ptr)->y_pos;
y *= 8;
do
{
c = ((u8x8_tile_t *)arg_ptr)->cnt;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
u8g_sdl_set_multiple_8pixel(x, y, c*8, ptr);
arg_int--;
x+=c*8;
} while( arg_int > 0 );
/* update all */
#ifndef NO_SDL
SDL_UpdateWindowSurface(u8g_sdl_window);
#endif
break;
default:
return 0;
}
return 1;
}
uint8_t u8x8_d_sdl_240x160(u8x8_t *u8g2, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, y, c;
uint8_t *ptr;
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8g2, &u8x8_sdl_240x160_info);
u8g_sdl_init(240, 160);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8g2);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
break;
case U8X8_MSG_DISPLAY_SET_CONTRAST:
break;
case U8X8_MSG_DISPLAY_DRAW_TILE:
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8g2->x_offset;
y = ((u8x8_tile_t *)arg_ptr)->y_pos;
y *= 8;
do
{
c = ((u8x8_tile_t *)arg_ptr)->cnt;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
u8g_sdl_set_multiple_8pixel(x, y, c*8, ptr);
arg_int--;
} while( arg_int > 0 );
#ifndef NO_SDL
/* update all */
SDL_UpdateWindowSurface(u8g_sdl_window);
#endif
break;
default:
return 0;
}
return 1;
}
void u8x8_Setup_SDL_128x64(u8x8_t *u8x8)
{
/* setup defaults */
u8x8_SetupDefaults(u8x8);
/* setup specific callbacks */
u8x8->display_cb = u8x8_d_sdl_128x64;
u8x8->gpio_and_delay_cb = u8x8_d_sdl_gpio;
/* setup display info */
u8x8_SetupMemory(u8x8);
}
void u8g2_SetupBuffer_SDL_128x64(u8g2_t *u8g2, const u8g2_cb_t *u8g2_cb)
{
static uint8_t buf[128*8];
u8x8_Setup_SDL_128x64(u8g2_GetU8x8(u8g2));
u8g2_SetupBuffer(u8g2, buf, 8, u8g2_ll_hvline_vertical_top_lsb, u8g2_cb);
}
void u8g2_SetupBuffer_SDL_128x64_4(u8g2_t *u8g2, const u8g2_cb_t *u8g2_cb)
{
static uint8_t buf[128*3];
u8x8_Setup_SDL_128x64(u8g2_GetU8x8(u8g2));
u8g2_SetupBuffer(u8g2, buf, 3, u8g2_ll_hvline_vertical_top_lsb, u8g2_cb);
}
void u8g2_SetupBuffer_SDL_128x64_1(u8g2_t *u8g2, const u8g2_cb_t *u8g2_cb)
{
static uint8_t buf[128];
u8x8_Setup_SDL_128x64(u8g2_GetU8x8(u8g2));
u8g2_SetupBuffer(u8g2, buf, 1, u8g2_ll_hvline_vertical_top_lsb, u8g2_cb);
}
void u8x8_Setup_SDL_240x160(u8x8_t *u8x8)
{
/* setup defaults */
u8x8_SetupDefaults(u8x8);
/* setup specific callbacks */
u8x8->display_cb = u8x8_d_sdl_240x160;
u8x8->gpio_and_delay_cb = u8x8_d_sdl_gpio;
/* setup display info */
u8x8_SetupMemory(u8x8);
}
void u8g2_SetupBuffer_SDL_240x160(u8g2_t *u8g2, const u8g2_cb_t *u8g2_cb)
{
static uint8_t buf[240*20];
u8x8_Setup_SDL_240x160(u8g2_GetU8x8(u8g2));
u8g2_SetupBuffer(u8g2, buf, 20, u8g2_ll_hvline_vertical_top_lsb, u8g2_cb);
}

View File

@@ -0,0 +1,62 @@
#ifndef NO_SDL
#include "SDL.h"
#endif
/* return ascii key value or -1 */
int u8g_sdl_get_key(void)
{
#ifndef NO_SDL
SDL_Event event;
/* http://www.libsdl.org/cgi/docwiki.cgi/SDL_PollEvent */
if ( SDL_PollEvent(&event) != 0 )
{
switch (event.type)
{
case SDL_QUIT:
exit(0);
break;
case SDL_KEYDOWN:
switch( event.key.keysym.sym )
{
/* /usr/include/SDL/SDL_keysym.h */
case SDLK_a: return 'a';
case SDLK_b: return 'b';
case SDLK_c: return 'c';
case SDLK_d: return 'd';
case SDLK_e: return 'e';
case SDLK_f: return 'f';
case SDLK_g: return 'g';
case SDLK_h: return 'h';
case SDLK_i: return 'i';
case SDLK_j: return 'j';
case SDLK_k: return 'k';
case SDLK_l: return 'l';
case SDLK_m: return 'm';
case SDLK_n: return 'n';
case SDLK_o: return 'o';
case SDLK_p: return 'p';
case SDLK_q: return 'q';
case SDLK_r: return 'r';
case SDLK_s: return 's';
case SDLK_t: return 't';
case SDLK_u: return 'u';
case SDLK_v: return 'v';
case SDLK_w: return 'w';
case SDLK_x: return 'x';
case SDLK_y: return 'y';
case SDLK_z: return 'z';
case SDLK_SPACE: return ' ';
case SDLK_UP: return 273;
case SDLK_DOWN: return 274;
case SDLK_RIGHT: return 275;
case SDLK_LEFT: return 276;
default: return 0;
}
}
}
#endif
return -1;
}

View File

@@ -0,0 +1,12 @@
CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) main.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

View File

@@ -0,0 +1,148 @@
#include "u8g2.h"
#include <stdio.h>
u8g2_t u8g2;
/*
draw unicode for https://en.wikipedia.org/wiki/Devanagari
Adjust the glyph position as good as possible for the unicode font.
Report missing or wrong glyph adjustments here:
https://github.com/olikraus/u8g2/issues/584
precondition:
u8g2_SetFont(&u8g2, u8g2_font_unifont_t_devanagari);
u8g2_SetFontMode(&u8g2, 1);
Font direction command is NOT supported
*/
u8g2_uint_t u8g2_draw_unifont_devanagari(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *str)
{
uint16_t e;
u8g2_uint_t delta, sum;
u8g2->u8x8.next_cb = u8x8_utf8_next;
u8x8_utf8_init(u8g2_GetU8x8(u8g2));
sum = 0;
for(;;)
{
e = u8g2->u8x8.next_cb(u8g2_GetU8x8(u8g2), (uint8_t)*str);
if ( e == 0x0ffff )
break;
str++;
if ( e != 0x0fffe )
{
switch(e)
{
case 0x093e: x-= 12; break;
case 0x093f: x-= 19; break;
case 0x0941: x-= 14; break;
case 0x0947: x-= 12; break;
case 0x094d: x-= 10; break;
}
delta = u8g2_DrawGlyph(u8g2, x, y, e);
switch(e)
{
case 0x094d: x-= 8; break;
}
x += delta;
sum += delta;
}
}
return sum;
}
int main(void)
{
int x, y, o;
int k;
int i;
u8g2_SetupBuffer_SDL_128x64_4(&u8g2, &u8g2_cb_r0);
u8x8_InitDisplay(u8g2_GetU8x8(&u8g2));
u8x8_SetPowerSave(u8g2_GetU8x8(&u8g2), 0);
//u8g2_SetFont(&u8g2, u8g2_font_helvB18_tr);
u8g2_SetFont(&u8g2, u8g2_font_unifont_t_devanagari);
u8g2_SetFontMode(&u8g2, 1);
x = 50;
y = 30;
o = 0;
for(;;)
{
#ifdef U8G2_WITH_HVLINE_COUNT
u8g2.hv_cnt = 0UL;
#endif /* U8G2_WITH_HVLINE_COUNT */
u8g2_FirstPage(&u8g2);
i = 0;
do
{
u8g2_SetFontDirection(&u8g2, 0);
/* अविनाश */
/* &#x0905;&#x0935;&#x093F;&#x0928;&#x093E;&#x0936; */
/*
o = 0;
o += u8g2_DrawGlyph(&u8g2, x+o, y, 0x0905);
o += u8g2_DrawGlyph(&u8g2, x+o, y, 0x0935);
o -=19; // offset 19 for 0x093F S
o += u8g2_DrawGlyph(&u8g2, x+o, y, 0x093F);
o += u8g2_DrawGlyph(&u8g2, x+o, y, 0x0928);
o -=12; // offset 19 for 0x093e
o += u8g2_DrawGlyph(&u8g2, x+o, y, 0x093e);
o += u8g2_DrawGlyph(&u8g2, x+o, y, 0x0936);
*/
//u8g2_draw_devanagari(&u8g2, x, y+16, "अविनाश");
/* नमस्ते दुनिया Hello World */
/*
&#x0928;&#x092E;&#x0938;&#x094D;&#x0924;&#x0947;
&#x0926;&#x0941;&#x0928;&#x093F;&#x092F;&#x093E;
*/
u8g2_draw_unifont_devanagari(&u8g2, x, y+16, "नमस्ते दुनिया");
i++;
} while( u8g2_NextPage(&u8g2) );
#ifdef U8G2_WITH_HVLINE_COUNT
printf("hv cnt: %ld\n", u8g2.hv_cnt);
#endif /* U8G2_WITH_HVLINE_COUNT */
do
{
k = u8g_sdl_get_key();
} while( k < 0 );
if ( k == 273 ) y -= 7;
if ( k == 274 ) y += 7;
if ( k == 276 ) x -= 7;
if ( k == 275 ) x += 7;
if ( k == 'e' ) y -= 1;
if ( k == 'x' ) y += 1;
if ( k == 's' ) x -= 1;
if ( k == 'd' ) x += 1;
if ( k == 'q' ) break;
}
//u8x8_Set8x8Font(u8g2_GetU8x8(&u8g2), bdf_font);
//u8x8_Draw8x8String(u8g2_GetU8x8(&u8g2), 0, 0, "Hello World!");
return 0;
}

View File

@@ -0,0 +1,12 @@
CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) main.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

View File

@@ -0,0 +1,45 @@
#include "u8x8.h"
u8x8_t u8x8;
uint8_t tile_list[] =
{
0x0f0,
0x0f0,
0x0f0,
0x0f0,
0x0f0,
0x0f0,
0x0f0,
0x0f0,
0x0f0,
0x0f0,
0x0f0,
0x0f0,
0x0f0,
0x0f0,
0x0f0,
0x0f0
};
int main(void)
{
u8x8_Setup_SDL_128x64(&u8x8);
u8x8_InitDisplay(&u8x8);
u8x8_SetFont(&u8x8, u8x8_font_amstrad_cpc_extended_f);
u8x8_DrawString(&u8x8, 0, 0, "draw tile");
u8x8_DrawTile(&u8x8, 0, 1, 2, tile_list);
while( u8g_sdl_get_key() < 0 )
;
return 0;
}

View File

@@ -0,0 +1,12 @@
CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) ../../bitmap/common/u8x8_d_bitmap.c $(shell ls ../common/*.c ) main.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

View File

@@ -0,0 +1,163 @@
#include "u8g2.h"
#include <stdio.h>
u8g2_t u8g2;
/*
Limitations:
- Tile positions and sizes (pixel position divided by 8)
- Any display rotation/mirror is ignored
- Only works with displays, which support U8x8 API
- Only available in full buffer mode
- Will not send the e-paper refresh message
*/
u8g2_SendTileSubBuffer(u8g2_t *u8g2, uint8_t x, uint8_t y, uint8_t w, uint8_t h)
{
uint16_t page_size;
uint8_t *ptr;
page_size = u8g2->pixel_buf_width; /* 8*u8g2->u8g2_GetU8x8(u8g2)->display_info->tile_width */
ptr = u8g2_GetBufferPtr(u8g2);
ptr += x*8;
ptr += page_size*y;
while( h > 0 )
{
u8x8_DrawTile( u8g2_GetU8x8(u8g2), x, y, w, ptr );
ptr += page_size;
y++;
h--;
}
}
/*
sub buffer window in pixel coordinates
lower left corner is NOT included, this means the transfer range is from
x0..x1-1
y0..y1-1
*/
void u8g2_SendWindow(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t x1, u8g2_uint_t y1)
{
x0 /= 8;
y0 /= 8;
x1 += 7;
x1 /= 8;
y1 +=7;
y1 /= 8;
u8g2_SendTileSubBuffer(u8g2, x0, y0, x1-x0, y1-y0);
}
int main(void)
{
int x, y;
int k;
//u8g2_SetupBuffer_SDL_240x160(&u8g2, &u8g2_cb_r0);
u8g2_SetupBuffer_SDL_128x64(&u8g2, &u8g2_cb_r0);
//u8x8_ConnectBitmapToU8x8(u8g2_GetU8x8(&u8g2)); /* connect to bitmap */
u8x8_InitDisplay(u8g2_GetU8x8(&u8g2));
u8x8_SetPowerSave(u8g2_GetU8x8(&u8g2), 0);
u8g2_SetFont(&u8g2, u8g2_font_helvB18_tr);
x = 30;
y = 35;
for(;;)
{
#ifdef U8G2_WITH_HVLINE_COUNT
u8g2.hv_cnt = 0UL;
#endif /* U8G2_WITH_HVLINE_COUNT */
u8g2_ClearBuffer(&u8g2);
u8g2_SetFontDirection(&u8g2, 0);
u8g2_DrawStr(&u8g2, x, y, "A");
u8g2_SetFontDirection(&u8g2, 1);
u8g2_DrawStr(&u8g2, x, y, "a");
u8g2_SetFontDirection(&u8g2, 2);
u8g2_DrawStr(&u8g2, x, y, "a");
u8g2_SetFontDirection(&u8g2, 3);
u8g2_DrawStr(&u8g2, x, y, "a");
u8g2_DrawHVLine(&u8g2, u8g2.user_x0, u8g2.user_y0, 1, 0);
u8g2_DrawHVLine(&u8g2, u8g2.user_x0, u8g2.user_y1-1, 1, 0);
u8g2_DrawHVLine(&u8g2, u8g2.user_x1-1, u8g2.user_y1-1, 1, 0);
u8g2_DrawHVLine(&u8g2, u8g2.user_x1-1, u8g2.user_y0, 1, 0);
//u8g2_SendBuffer(&u8g2);
//u8g2_SendTileSubBuffer(&u8g2, 2, 2, 12, 3);
u8g2_SendWindow(&u8g2, 9, 17, 120, 42);
//u8g2_SendTileWindow(&u8g2, 0, 0, 16, 8);
/*
u8g2_FirstPage(&u8g2);
i = 0;
do
{
u8g2_SetFontDirection(&u8g2, 0);
u8g2_DrawStr(&u8g2, x, y, "ABC");
u8g2_SetFontDirection(&u8g2, 1);
u8g2_DrawStr(&u8g2, x, y, "abc");
u8g2_SetFontDirection(&u8g2, 2);
u8g2_DrawStr(&u8g2, x, y, "abc");
u8g2_SetFontDirection(&u8g2, 3);
u8g2_DrawStr(&u8g2, x, y, "abc");
if ( i == 1 )
{
u8g2_DrawHVLine(&u8g2, u8g2.user_x0, u8g2.user_y0, 1, 0);
u8g2_DrawHVLine(&u8g2, u8g2.user_x0, u8g2.user_y1-1, 1, 0);
u8g2_DrawHVLine(&u8g2, u8g2.user_x1-1, u8g2.user_y1-1, 1, 0);
u8g2_DrawHVLine(&u8g2, u8g2.user_x1-1, u8g2.user_y0, 1, 0);
}
i++;
} while( u8g2_NextPage(&u8g2) );
*/
#ifdef U8G2_WITH_HVLINE_COUNT
printf("hv cnt: %ld\n", u8g2.hv_cnt);
#endif /* U8G2_WITH_HVLINE_COUNT */
do
{
k = u8g_sdl_get_key();
} while( k < 0 );
if ( k == 273 ) y -= 7;
if ( k == 274 ) y += 7;
if ( k == 276 ) x -= 7;
if ( k == 275 ) x += 7;
if ( k == 'e' ) y -= 1;
if ( k == 'x' ) y += 1;
if ( k == 's' ) x -= 1;
if ( k == 'd' ) x += 1;
if ( k == 'q' ) break;
//if ( k == 't' )
// u8x8_SaveBitmapTGA(u8g2_GetU8x8(&u8g2), "screenshot.tga");
}
//u8x8_Set8x8Font(u8g2_GetU8x8(&u8g2), bdf_font);
//u8x8_Draw8x8String(u8g2_GetU8x8(&u8g2), 0, 0, "Hello World!");
return 0;
}

View File

@@ -0,0 +1,34 @@
CFLAGS = -g -Wall -Wpointer-arith -I. -I../../../csrc/. -I../../tga/mapgen/. `sdl2-config --cflags`
GMSRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c )
GMSRC += map.c main.c item.c
#GMSRC += ../../../tools/ugl/ugl_bc.c
GMSRC += ugl_bc.c
GMOBJ = $(GMSRC:.c=.o)
MAPGENSRC = $(shell ls ../../../csrc/*.c) mapgen.c u8g2_d_tga.c
MAPGENSRC += ugl_arrays.c ugl_error.c ugl_parse.c
MAPGENOBJ = $(MAPGENSRC:.c=.o)
UGLSRC = ugl_arrays.c ugl_error.c ugl_parse.c ugl_bc.c ugl_main.c item.c map.c
UGLOBJ = $(UGLSRC:.c=.o)
gm: $(GMOBJ) map.c
$(CC) $(CFLAGS) $(LDFLAGS) $(GMOBJ) `sdl2-config --libs` -o gm
mapgen: $(MAPGENOBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(MAPGENOBJ) -o mapgen
map.c: mapgen gm.map
./mapgen -o map.c gm.map
ugl: $(UGLOBJ) map.c
$(CC) $(CFLAGS) $(LDFLAGS) $(UGLOBJ) -o ugl
clean:
-rm $(GMOBJ) $(MAPGENOBJ) $(UGLOBJ) gm mapgen ugl map.c

View File

@@ -0,0 +1,214 @@
#
# gm.map
#
# Syntax:
# 'hash' introduces a comment
# tile <ascii> <mapto> <top> <right> <bottom> <left>
# map the <ascii> code to the specified <mapto> code, if the other for tiles match
# If one of the other four tiles is 0, then ignore this tile (wildcard)
# thing ... same as tile, but can be redefined at any time, should redefine to char
# itemkey <iname> <ascii> <bg-tile> ... similar thing, but will connect to an item and assign the <backgroundmapto> instead
#
# summery:
# tile: static fixed thing for all maps
# thing: static thing for some maps
# itemkey: dynamic objects like changing doors, boxes or monsters
#
# item <iname> <foregroundmapto>
# defines a global template for an object.
# anyting on the map, which might disappear, move or change has to be an item
# itemuse <iname> <ascii>
# only within active map. <mapto> will be the background tile for the char
# the current foreground tile might still be differrent and is set during iteminit
# connects the ascii char with the given ascii char on the map to get the xy pos.
# iteminit <iname>
# <procedure>
# endproc
# procedure, which is called, when the item is created,
# receives position, where it should be created on the map
# itemhit <iname>
# procedure, which is called, when the item is hit by something
# - returns 0 if the item hitting item has to be stopped
# - may move itself
# - may change its own shape (tile)
# - may modify its status
# endproc
#
# example "normal door, status=closed"
# 1. hit: status=open, change tile to open door, return 0
# 2. hit: return 1 (hero can pass)
# example "creature, status=5 life"
# 1. hit: get hitting obj attac damage, reduce life --> status=2, apply attack damage hitting object, return 0
# 2. hit: get hitting obj attac damage, reduce life --> status=0, remove object from map, return 0
# 3. hero can continue
#
# itemstep <iname>
# executed every step
# - moving items can move towards hero or others
# endproc
# mapinit
# executed during map init
# endproc
#
#
# map <name> <width> <height>
# Create a map with the given name and size. this must be followed by :
# endmap
# Finish the current map
#
tile 32 32 # map space to space
tile '+ $80 0 '- '| 0
tile '+ $80 0 '- '+ 0
tile '+ $80 0 '+ '| 0
tile '+ $80 0 '+ '+ 0
tile '+ $81 0 0 '| '-
tile '+ $81 0 0 '+ '-
tile '+ $81 0 0 '| '+
tile '+ $81 0 0 '+ '+
tile '+ $82 '| '- 0 0
tile '+ $82 '+ '- 0 0
tile '+ $82 '| '+ 0 0
tile '+ $82 '+ '+ 0 0
tile '+ $83 '| 0 0 '-
tile '+ $83 '+ 0 0 '-
tile '+ $83 '| 0 0 '+
tile '+ $83 '+ 0 0 '+
tile '+ $84 '| '- '| 0
tile '+ $84 '+ '- '| 0
tile '+ $84 '| '+ '| 0
tile '+ $84 '+ '+ '| 0
tile '+ $84 '| '- '+ 0
tile '+ $84 '+ '- '+ 0
tile '+ $84 '| '+ '+ 0
tile '+ $84 '+ '+ '+ 0
tile '+ $85 '| 0 '| '-
tile '+ $85 '+ 0 '| '-
tile '+ $85 '| 0 '+ '-
tile '+ $85 '+ 0 '+ '-
tile '+ $85 '| 0 '| '+
tile '+ $85 '+ 0 '| '+
tile '+ $85 '| 0 '+ '+
tile '+ $85 '+ 0 '+ '+
tile '+ $86 0 '- '| '-
tile '+ $86 0 '+ '| '-
tile '+ $86 0 '- '+ '-
tile '+ $86 0 '+ '+ '-
tile '+ $86 0 '- '| '+
tile '+ $86 0 '+ '| '+
tile '+ $86 0 '- '+ '+
tile '+ $86 0 '+ '+ '+
tile '+ $87 '| '- 0 '-
tile '+ $87 '+ '- 0 '-
tile '+ $87 '| '+ 0 '-
tile '+ $87 '+ '+ 0 '-
tile '+ $87 '| '- 0 '+
tile '+ $87 '+ '- 0 '+
tile '+ $87 '| '+ 0 '+
tile '+ $87 '+ '+ 0 '+
tile '+ $88 '| '- '| '-
tile '+ $88 '+ '- '| '-
tile '+ $88 '| '+ '| '-
tile '+ $88 '+ '+ '| '-
tile '+ $88 '| '- '+ '-
tile '+ $88 '+ '- '+ '-
tile '+ $88 '| '+ '+ '-
tile '+ $88 '+ '+ '+ '-
tile '+ $88 '| '- '| '+
tile '+ $88 '+ '- '| '+
tile '+ $88 '| '+ '| '+
tile '+ $88 '+ '+ '| '+
tile '+ $88 '| '- '+ '+
tile '+ $88 '+ '- '+ '+
tile '+ $88 '| '+ '+ '+
tile '+ $88 '+ '+ '+ '+
tile '| $7e 0 0 '| 0
tile '| $7e 0 0 '+ 0
tile '| $7f 0 0 0 0
tile '- $7d 0 0 0 0
tile '. $6a # stone 2
tile ': $6b # stone 3
thing 'f $74 # fire
thing '^ $73 # door open
thing 'C $79 # cupboard
thing 'b $7a # bookshelf
thing 'c $78 # chair
thing 't $7b # table
thing 'T $7c # throne
thing 'h $9c # chest
thing 'H $92 # hut
thing 'K $93 # kingdom
item normal_door $72 # $72 = door closed --> inital tile
itemkey normal_door 'x $73 # $73 = door open --> this will be placed on the map, the item can destroy itself, but this tile will stay
iteminit normal_door
print(add(1,2))
print(add(3,4))
print(add(1234,5678))
endproc
itemhit normal_door
endproc
itemstep normal_door
endproc
item spider $54
itemkey spider 'S 32 # use blank as background under 'S'
iteminit spider
endproc
itemhit spider
endproc
itemstep spider
endproc
map test 20 9
mapinit
setPos(3,2)
setItemPos(0)
endproc
: K H
: . .
: ...........
: . .
:+-----^--x--C--b---+
:| T f|
:|ctc h S |
:| c S |
:+-----^-----x------+
endmap
#thing 'S $54 # Spider
thing 'k $a0 # key
map first 12 12
:+---+ +---+
:| | | |
:+-+ +--+ | |
: | +-+ |
: | | |
: | |
: +-+ -----+
: | Sk|
: +------+
endmap

View File

@@ -0,0 +1,5 @@
14 Jul 17
- introduce position struct (rewrite pos.h/c)
- use position struct in the code itself
- write hero movement code

View File

@@ -0,0 +1,258 @@
/*
item.c
during level setup, the item pool is filled with items from the
onmap list.
*/
#include <stddef.h>
#include "ugl_bc.h"
#include "item.h"
#include "map.h"
/* max number of items in the pool */
#define ITEM_MAX 32
/* current number of items in the pool */
uint8_t item_cnt;
/* current level */
uint8_t current_level;
/* the pool with all dynamic created items */
item_t item_pool[ITEM_MAX];
item_t *item_under_pos; /* set by getMapTile() */
bc_t bc;
/*===============================================*/
void execute(uint16_t pos)
{
bc_exec(&bc, map_code, pos);
}
/*===============================================*/
void posStep(pos_t *pos, uint8_t dir)
{
switch( dir )
{
case 0:
pos->x+=1;
break;
case 1:
pos->y+=1;
break;
case 2:
pos->x-=1;
break;
case 3:
pos->y-=1;
break;
default:
break;
}
}
/*===============================================*/
void pool_Clear(void)
{
item_cnt = 0;
}
uint8_t pool_NewItem(void)
{
if ( item_cnt >= ITEM_MAX )
return ITEM_MAX;
item_pool[item_cnt].dir = 4; /* no move */
item_cnt++;
return item_cnt-1;
}
item_t *pool_GetItem(uint8_t idx)
{
return item_pool+idx;
}
/*
Based on the dir attribute, all items, including hero are moved
*/
void moveAllItems(void)
{
uint8_t i;
item_t *item;
i = item_cnt;
item = item_pool;
do
{
posStep(&(item->pos), item->dir);
item->dir = 4; /* no move */
item++;
i--;
} while( i != 0);
}
void callStepAllItems(void)
{
uint8_t i;
item_t *item;
i = item_cnt;
item = item_pool;
do
{
execute(item_template_list[item->template_index].step_proc);
item++;
i--;
} while( i != 0);
}
/*===============================================*/
/*
void item_SetDefaultTile(uint8_t idx)
{
item_t *item = pool_GetItem((idx);
item->tile = item_template_list[item->template_index].fg_tile;
}
*/
/*===============================================*/
void setupLevel(uint8_t level)
{
uint8_t i, cnt;
item_t *item;
item_onmap_t *onmap_ptr;
current_level = level;
cnt = map_list[level].onmap_cnt;
/* build the pool */
pool_Clear();
/* first item always is our hero (index 0) */
item = pool_GetItem(pool_NewItem());
item->pos.x = 0;
item->pos.y = 0;
item->tile = 0x04e;
item->template_index = 0; /* not used, but still template index should be reserverd then */
onmap_ptr = map_list[level].onmap_list;
for( i = 0; i < cnt; i++ )
{
/* no check of pool_NewItem() here, this should always succeed */
item = pool_GetItem(pool_NewItem());
item->pos.x = onmap_ptr->x;
item->pos.y = onmap_ptr->y;
item->template_index = onmap_ptr->template_index;
item->tile = item_template_list[item->template_index].fg_tile;
onmap_ptr++;
}
execute(map_list[level].init_proc);
}
/*
return a tile on the map.
as a side effect,
item_under_pos
is set if the tile is from an item. Otherwise item_under_pos is set to NULL
*/
uint8_t getMapTile(uint8_t x, uint8_t y)
{
item_t *item;
uint16_t offset;
uint8_t i, cnt;
cnt = item_cnt;
for( i = 0; i < cnt; i++ )
{
item = pool_GetItem(i);
if ( item->pos.x == x && item->pos.y == y )
{
return item->tile;
item_under_pos = item;
}
}
item_under_pos = NULL;
offset = y;
offset *= map_list[current_level].width;
offset += x;
return map_list[current_level].data[offset];
}
/*
sideeffect: will set item_under_pos
*/
uint8_t getMapTileByPos(pos_t *pos)
{
return getMapTile(pos->x, pos->y);
}
/*
Check whether a tile is solid by definition.
The case, when hitting a tile and it became wakable (because it disapears
or moves away) is not considered.
*/
uint8_t isSolidTile(uint8_t tile)
{
if ( tile >= 0x07d && tile <= 0x088 )
return 1;
return 0;
}
/*
sideeffect: will set item_under_pos
*/
uint8_t canWalkTo(pos_t *pos)
{
uint8_t tile;
tile = getMapTileByPos(pos);
/*
if ( item_under_pos != NULL )
...
*/
if ( isSolidTile(tile) != 0 )
return 0;
return 1;
}
/*
0: not moved
1: moved
sideeffect: will set item_under_pos
*/
uint8_t moveItem(uint8_t item_index, uint8_t dir)
{
item_t *item;
pos_t pos;
item = pool_GetItem(item_index);
pos = item->pos;
posStep(&pos, dir);
if ( canWalkTo(&pos) != 0 )
{
item->dir = dir;
return 1;
}
return 0;
}

View File

@@ -0,0 +1,43 @@
/*
item.h
*/
#ifndef _ITEM_H
#define _ITEM_H
#include <stdint.h>
struct _pos_struct
{
uint8_t x;
uint8_t y;
};
typedef struct _pos_struct pos_t;
struct _item_struct
{
pos_t pos;
uint8_t dir; /* movement has two parts: 1. dir is set, then 2. dir is executed */
uint8_t tile; /* current foreground tile, defaults to the value from the template list */
uint8_t template_index; /* index into item_template_list[] */
};
typedef struct _item_struct item_t;
item_t *pool_GetItem(uint8_t idx);
void posStep(pos_t *pos, uint8_t dir);
void moveAllItems(void);
void callStepAllItems(void);
uint8_t getMapTileByPos(pos_t *pos);
void setupLevel(uint8_t level);
uint8_t getMapTile(uint8_t x, uint8_t y);
uint8_t moveItem(uint8_t item_index, uint8_t dir);
#endif /* _ITEM_H */

View File

@@ -0,0 +1,399 @@
/*
golem master
*/
#include "u8g2.h"
#include "map.h"
#include "item.h"
#include <stdio.h>
#include <unistd.h>
const uint8_t scrollosprites[6642] U8G2_FONT_SECTION("scrollosprites") =
"\323\0\3\3\5\5\5\6\6\20\20\0\0\17\0\17\1\4\11U\31\331 \6\0@\30\6!$\316"
"\305\20>\60\16\211\243\320A\326\220,\16\220H\342\0ID<\31\217cs\330\60:\207\315\201r("
"\0\42$\316\305\20>,\16\212\243\320A\223\304\220(\16\212\305\1\21:$\34\245\203f\341\71l\16"
"\233\3\345P\0#\37\255\305\20>\240\16\70\213\344\0\221\34B\11\207\250\223\324\71h\16\232\203\346\240"
"\71L\16\4$\35\214I\21\236\65\34\213\320\42\21\233\304&\261\211(!\361D\226\24\11\306\222\243\66"
"\0%\32\314\311\20&\35`\16\206Eb;\200xx\30\22'\224!\35BG&\2&\27kI\21"
"\26E\26y\70XB\262\231p$,YD\304\362$\12'$\316\305\20\346A\30:\304\42\7Y\34"
"|\220\306\1\321\203T\365 \215\3\242\7\221D*\12\35d\207\31\0((\316\305\20N\344\20\211L"
"\16\221P\344\20I\307!\16\210\36\244q@\364 G\214\34\42\221\311!\22\212\34\42\351P\0)\35"
"\313\315\20>@\16\240\332H\242\241H\70\22U\16\223C\314J\7H.\222K\344\60*\34\316\305\20"
"\306C\34*\71X\16\226\203\345`\71<\324\21\336QBJ\241C\345p+%\356E\20\246Y-\16"
"\213\304DA\71($\225F\342\260HD,\221\331\346\60\363\341@\71TB\207PX\14,'\316\305"
"\20F\70\32\211\303\302uH\64\34\7\4c\304H(\30\15e\11\305d\301\70$\32\216\3\254qX"
"$\32\16-&\316\305\20>\60\35\22:\330\342\220`$\30\11\206\62\246\5c\301\244\214\221`$\30"
"\207\304\16\246\70$\30\7\2.*\316\305\20F\34\32\11Fb\321H:(\222\16\212d\7D\262\211"
"\42Y\204\307\220L\32\221D\304\63\71\340\30+E\342\320\0/&\316\305\20.\35\42\233\6c\211\321"
"P\60\32\211F\307\261\210\34\60\222\311\1\221\220\70\24\207\245C\242B\71\204\12\60\36\314I\20\236\365"
"\20<\4#\224\340!\250x\210Z\303\261\303Db\241Xd\42q\60\6\61)\317A\20\256\35r\210"
"\3\16q@\204\222z\10\5\225d\207\220\320$\11\205)\221\303Pb\13IlQ\221,%\30\212\0"
"\62*\317E\20\246\35r\10\5\17\241`\204\22\12\36BA\245\340!\24.\235e\222\310A\42\211\324"
"\42\222HY\42\222\203\202Q\0\63+\356I\20>\64h\32\35B\261C(\26\241\204b\207PL("
"\212\35BA\223,L:T$\23\251D\226\70\221\305\16\241\10\0\64(\356I\20\226\35d\7\34\302"
"\251\221\210$\61b\11\206H\321p\34`\7\204c\221\303\204bI\221X\244\42\71$\30\5\65*\16"
"J\20>L\16\225\32C\207\360!\24\213P\62\35B\61\241(v\10\5M\262\60\211d\221X%\42"
"\71D$\7\10\205\0\66%\315I\20\236\371\20=\204R(\241\320!\24\22\212B\207P\314$\12S"
"H\207\210Q\16\10\305l\241C(\0\67%\354I\20\316D\62;\304\221\16\61\11Et\30\261D\16"
"\221\230mBY\221L\224$\24\221D&\222\12E\0\70\25hQ\20\26\315\24\221\204Lj\224\304\203"
"$B$\206B\0\71\42\255I\20V\34*\36\35\206\207h\204\22=\204B\63Q$\62\21\316a\207"
"\350!*J\215\205\202\0:\34\314I\20\236\365\20\264\4#\306\71H\221\22\244X\224e\207\250\365\70"
"\223\303\202\0;#\316E\20\246\35p\10\37\302\22\345Cx\64\215Xb\343\311\341 \71DD\61Y"
"\360\60<L\205\62\0<,\356E\20\246\35\20\216\306!\301\70$\30\11F\202qH\60\16\11\306!"
"A\261\60b\211\305a\221P\70$\12\207J\42Z\204\22\3=$\316E\20\246\35p\210\36\206\22\212"
"\360\60\212\220(\21\211EL\207\10\245\207\231\304\42\265CDrP*\0>)\317A\20\256\35r\10"
"\37\304\22J\342A\24\211\220F\22\211MJ\223\304\202\244\320!\24:\310B\22[T$KJ\213\0"
"?+\317E\20\246\35r\10\305\16\223\230\204\42\211\35&)$JHbI\246]g\222\310A\42\211"
"\324\42\222HY\42\222\303Ba\0@+\357E\20>\70j\232\35B\261\303$&\241Hb\207I\12"
"\211\22\222X\222iBa\355\60\224LdQY\352D\26<\204\42\0A'\356I\20\226\35d\7\34"
"\302\251\221\210$\61b\11\206H\321p\34`\7\204c\221\303\204bI\264HErP\62\0B)\17"
"F\20>P\16\26\33c\207\360a\22\223P\62\35&)$JHbI\246\11\205\65\22Qb\7\251"
"\203\324!B!\0C%\316E\20\246\35p\210\36&!\11E\22:L$$JDbI\245)\226"
"\330$\266\70,\24\264\305\16\241\0D'\356E\20V$\42I=\304Q\17C\11Ev(\65I,"
"\42\21I\22\22\212B\303\231\304\42\265C\354\200C\14\0E\30\212M\20\216P\22\42\205\214\21I\320"
"(\222Rb\301X\204\314j\2F \253I\20^\70&\224\35D\207H\12%\205\62\211L\42*\246"
"\71\344\20;\304DiI!\0G#\316E\20\246\35p\210^\204\222ci\42\241\221$\42\71\210$"
"\24\16\17B\211\35b\207\210\344\240T\0H%\316E\20\246\35p\210\36F\221\211d\22\71\24G\323"
"\210%\66\236\34\16\222CD\24\223\5\17\303\303T(\3I.\360A\20\256\35\24\216\3\342\220h\34"
"\26\14\5C\241\71\214\22\207E\222\302\241\30\221\32\42E\343\260\244p(D\246\206DqPD\22\5"
"J\42\255E\20\246\371\20=D\17\321\220(z\10FD\222\220\304\205R\211\260E$\221\231$-$"
"\24\1K\36\314I\20\236\65T\34I#\243`)(\33\36\242F\261\344p\261P,\62\221\70\30\3"
"L\64\17F\20>\70\16\220FM\263C\34p\10\5C\242\304p(\70\32\205C\243\10%\244\42\11"
"GT\42\24\231$R\213HB\322\210$I\26\222\4c\21\0M&\354I\20\246\325\22;\4\303\261"
"\70$\24\42\245\210$\261\10%\32\14\256\204\224(\241\10%)\222\30\12\13E\0N\63\16F\20\206"
"\34*\264\305\16\241\220)\22:\204D\341X$\16\11EB\244\224\210H\22\22\31)\224\30\205\42\216"
"H\42\222\230$E\22\233\10C\207\30\0O+\356I\20\246\35`\7\34\302\251qH\60D\12FD"
"\222h\204\22\7\4\343\200\10%\26\71L(\226\24\211E*\222C\202Q\0P%\317E\20\246\35r"
"\10\37\246\22\212\360@,\21%\226\240\210\22\14\11\305\207PLR\223\216B\303\203\34`\4Q!\216"
"E\20\226P,\224\3\312\221\210\362A\26\7\214\242\227\340!\22\213\134\242\227\350%\30\241\210\0R\36"
"N\305\21V\34\22\13\5C\21\221\22I\251\42\222\34\36\42\222C\304B\11e\221C\3S \314\311"
"\20\16)j\12\36C\226X\250|\210\34D\7I\304\134\212EL\301cH\222\32\251\0T,\356E"
"\20V\210\24\214Xb!S\222)\26\42\205$!Qdr\230\304$\212\23\312$\24\22\205$\241,"
"\241\34\343\220h\70\33\0U'\356E\20\336\34V\7E\346\240h\34\22\222\243\304AtH\70\16\260"
"C\254\24\11\227\212X\42\12\207\42\311\221\10\0V\37\216E\20\356\371 =\10G\61\212\312\212J>"
"I\262EF\242\231\251R\212\215#I\26\0W%\356E\20> \16\252\3\346\260\203\345p:\324!"
"\346C\360 \214P\302\207p$\24\11\247\3\202q\20\25\0X)\356E\20\246X\30\11F\202\207\351"
"!\24\223h;D\244\64\311$\24\211\34E\207\322\241\64\222Md\341H\60\16\11\306\1Y-\356E"
"\20\246X\30\261\4\17\223X\204\222x\210\204\210\222\310D$\212\220D\241\12%d\24\35\42#\311l"
"$\21\216B\62RH\26IZ&\356E\20\226\304\42\212\34\42\261\303\354P\232PF\207Jd\70Y"
"\232\224H\347\203\360\360P\241,\221$\243H\2[(\357E\20\266$\16\272\3&\325\303\324$\225\314"
"A\242Ix\224\26\42\311b\345\330\241h\207D\330&\223\234\242\221\24\0\134,\357E\20Fd\42\11"
"\305$\7\351\304xI\264C\326\202#J\220\24\13EJ\243\220\71t\60\35\342\240\12MB\311\42\211"
"FR\0]*\15J\20f(\16\241C&r\300!x\20N\306Ca\35r\20\36\42\241\203D\22"
"\271Hb!\321,\65\24\213CbA\0^+\356E\20>,\216\42\207\312\16Q[\354\20\13\35b"
"\241H\61\24\7\204\222\304\241\210\34\20\212\206\42\241\70,T\216\320$\241\0_*\356E\20N\34\22"
"\15\247\312\42qXDH\212\310L\243\342\210B\31I\316\244\10K\344\62\221\204(\321Hd$\212h"
"\231\0`*\356E\20\246\371\60;\224\206\225\221\350\20\11E\16\221P\344\20\11E\16!\321Ah\71"
"\224H\262\230\34\64\213\210$*\23\2a \216E\20\256\35`\211\36\302Bq$\24\11\247F\202\221"
"\330\204\62\42R$\207\210L(N\3b-\356E\20n\60\16\20\305A!\71\220\16\261\3&\21i"
"$e\32\7\10#\261\210\60\16\220\206\203\222`D\222R\212\10kqX\14\0c(\316E\20\346$"
"\62\215\3\344PY\60&\207\226&\222\310!\42\211\34\42\21\311!B\71D(\207\10\35\61\34\25\213"
"\0d(\356E\20> \216\315\16\70Dd\21JDv\10\305\302\241\210\34\42\11\35b\241CLr"
"\210I\16q\14\321\260p\4e!\356E\20\246\35b\207\330a\342\211\213H\342K\311\64\12\207&\207"
"\10\345\20\221\35\302B\351p\4f\22\20B\20\206\344\377RG\262\374\377%\216$\371Rg\32\20B"
"\20\206\344\377RG\222L.+\227\225\313\34<\331\377\22G\222|)h\33\20B\20\206\344\377RG"
"\262\203N\226\223\345d\71YN\226\223%\216$\371Ri-\20B\20\206($\241\210E\242\70\262H"
"\34\32\251\312\1r\320\70Z\34E*\241a\35:\7\211e\21\222DJ\222\203\304\62\71\204\4j-"
"\20B\20\206($\241\210E\242\330\34Z\224Ej\304\32u*\13VG\307\311!\16\71D\244\207\310"
"$t\10\11\357\260\222L\16!\1k-\20B\20\206\244D\221\134(\221\203\355 \21\36dB\243d"
"B\232\215+\223\226\320\205v\220\10\17\63\311a\64:\210\204\27\231\34B\2l'\20B\20\306\303\34"
"Ar\250H\16\25u\210v\210\246\212\246\212\246\212\246\212\246\212v\210\312\241\42\71T\344\10\17\3m"
":\20B\20\306\303\34Ar\250H\342\260\210$\16\213Hb\221\244\210$\24\311E\22\213$E$\241"
"H.\222X$)\42\11Er\221\304\42I\21I\34\26\221\34*r\204\207\1n'\20B\20\306\303"
"\34Ar\250\210\16#\331!&\64J\251b]CQa\242,\34\23\305!!I\34\26\221#<\14"
"o\61\20B\20\306\303\34Ar\250H\306\23\311\322D\62I\232H&I\23\311$i\42\231$M$"
"\223\244\211di\42\31O$\343\211\344P\221#<\14p!\316\305\20\306C\34*\207\312\241rP\35"
"T\7\25)EJ\221r\210P\16\21\312!B\71\34\10q#\356\305\20>\214\16\243\303\250\24*\205"
"J\71D(\207\10\345\20!V\210uP\35$\207\312\241\207C\0r%\316\305\20^\204\22\234P&"
",\207\10\345\20\241\34\42\224C\204R:P\344\300P\204r\210P\16\21v\204\7s\15\304\355\20\216"
"\344P\341\213$)\30t&\354I\20V\60\16\11\311\1\242\60\35b\225D\206\223Lr@H,\211"
"\34\42r\330\301r\230\304a\221\303\4\0u)\320\301\20\346!\16\210C\242Aa,\30\12F\204\254"
"R:\264\16\243\310!\222\311a\242r\210\310\344\20\351a\16\70\4\1v\24\212M\21\226\355\20\71\30"
"\17\207\360\341\17\22IE$\11w\31\316\305\20\266\370\360A\16;\34\352\220\303\37\346\310r\250\34*"
"\207\212\1x\17\350P\22\216\345p\220\330a\42\211P\0y\22\216E\21\306\377\357\10\17\221IJ\313"
"\245r\207\6z$\356E\20\306?\304\241\222t\210$Ez\70\310\241\22I\312D%er\70\310\241"
"\22J\26\11%\313\341\20{\32\316\305\20\316\241r\370\377r\250\304\241\221C\35I\16\21\311!\42\71"
"D\2|\32\314\311\20\236Mb\241X\346\260\310ar\370\203\35z\250C\345\20:D\0}\26\220A"
"\21\306\377\37\352h\221|\221\344\247H\276H\362S$?~\12\10R\20\306\377\377\203\0\23\310Q"
"\21\306\377!\16\212\244H\62ER$\231\42\31\200\32\314Q\20\306\377\207\341!\22\71\210\42\207H\344"
" \212\34\42\221\203\360\20\4\201\33\314A\20\306\377\203\360\20\11\35$\221C$t\220D\16\221\320!"
"x\10\36\2\202\31\314Q\21\306!x\10\36\376\17rp$\27I\236\42\271H\362\24\311\3\203\27\314"
"A\21\346!x\370\230\203#\271H\362\24\311E\222\247H\36\204\37\14R\20\306!x\10\36\376\37"
"\206\207H\344 \212\34\42\221\203(r\210D\16\302C\20\0\205\36\14B\20\346!x\370\30\36\42"
"\241\203$r\210\204\16\222\310!\22:\4\17\301C\0\206\42\320A\20\306\377\37\212\207h\350\20\211H"
"\42\207P\322!\22\221D\16\241\244C$\361\20\207\34\202\0\207\33\320A\21\346!\16\71\4\17\377?"
"\324\321\42\371\42\311O\221|\221\344\247H~\210'\20B\20\346!\16\71\4\17\377?\24\17\321\320!"
"\22\221D\16\241\244C$\42\211\34BI\207H\342!\16\71\4\1\211\13g\320\23V\70\22\221\205\0"
"\212\16\307\320\22\246,\62\235CD!\31\0\213\16\246T\23\226(\42\31IB\61\21\0\214 \316\305"
"\20.\35r\210\36f\207\322\241r\370P\254LB\221\241D\35$\207\312\241r \25\0\215\32\314\311"
"\20\256\34D\7\330\21\255\207\330a\216r\210\35&\207:\232\34&\5\216\42\256\305\20^$\24\211\3"
"\202\341\341\70\30\7\245RB\21J\310\24\246\3\345P\71T\16\225\3\251\0\217\24\214I\21\226\22I"
"\35\257\42\21I\35\257\42\21I\11\0\220!\316\305\20\246\35p\10\37\204\207!\35\66\61J\16\341C"
"Lr\220P\16\227\203\205t\231H\214\4\221\23\212\315\20\36\325v\10\35\42\207\323\321\213dF\65\1"
"\222\36\214\311\20\256(\34\212D#\212\21J,bI\71D\42\207Q\376\64\221L\351\0\33\0\223\35"
"\214\311\20FD\313\341\201\16>\214\42\226PD$\11\15G\303\321D\62\245\3l\0\224\34\216\305\20"
"\306;\70\26\7\305\342\240\70\370p\210\261M\326\230#\351\240X\34\66\4\225#\256E\21n$\16\225"
"\3\347\60:@B\11\212H\261\330\60\24\23\317\302\22alb)\35\210\7!\0\226 \314\305\20>"
"$\16\224\4Ct\10\35`\12\215\204\243a\214\32\241Z\345 \71H\16\222\303\0\227!\256E\21."
"\35\26\212\203\42\222\70@(\214\34\42Q;\242\310$\264C\254\221\10%Q\35`\4\230$\316\305\20"
">L\16\215\304\201\241\70\250\16\231\303\346\200\320\34\60\221\3\350\240;\340\20\276\3\354\220:\10\0\231"
"#\316\305\20^\35J\221\203\352\260\71t\16\21\311\1\63\351P\70\216\315\1\241\71$\62\207\315\201r"
"(\0\232#\314\305\20>\200\16\10J\203\221`J\64\224J\212\12c\21R:$\224\227`H\24\14"
"\7\343\0\12\0\233\37\254I\21>D\16J\226\305!\241X-D\212\235b\246Xd\226\16\210\305\1"
"\301h\270\12\234\30-\305\21\316!\42\71DN\23Z\34D\231\234&\207\312\241r\250\20\235#n\305"
"\21\346$\62\215\3\204q\200\60\16\20\306\1\245\11\345\20\241\34\42\224C\204r\210P\16\21\12\0\236"
"#\316\305\20\246\35\20N\22E\305\62\211EB>\34(\207J\344\60\221\331\42\311\221\20EB;\214"
"\215\0\237 \216\305\20\356\34\32\31\206B\264\71H(\26E$\61:\350\30:\204(\242QUr\7"
"\24\1\240\27\14I\22\316\34R\7\304\342\200\330Av\220\5\17\301Hd\16\1\241\30\15E\22\246\34"
"\26\212\3F\341\320\201t\230\214b\263P,\22\224\3\242\27k\311\20^U&\214M\253i\222\10e"
"\22\71\204\16\17\246\33\0\243\37\256\305\20^\35r\7\330A\224Z\360\66\271C\352\220h\34R\252D"
"\17\221\312\35R\207\0\244\26J\315\21\226\315\22\71D,\22\312h\351&\21\245\204c&\0\245\27J"
"\315\21\246-R\212PRH\22\232d(\21F\302\241h\314\10\246\27J\315\21\226-\62\212DJ\222"
"\222\244$)\211frHr\314\4\247\30\214I\21n\371,\22\213\244\21\362XQ$\207\310!\42\331"
"\270\16\21\250\17\314\310\22>\214\16\71\230\16v\10\35\6\251\27k\311\21V\365v\20\225D\224\210\210"
"\62\211\20\17\17\224\303\354\2\252\30K\311\21\216QV\21\306h\242\310\201\26I\241C(Y\16\224\303"
"\0\253$\316\305\20>L\16\245\303\350 \71P\16\242C(\322\211\34\20!EMQ\211(L\213\3"
"dq\20\35\2\254#\316\305\20\16\35\24\224\3\302\322\70D\26\207\205b\323H,\24\25N\345\320\71"
"\354\360Ar\250\35F\0\255%\316\305\20>\70\16\231\304!u\350x&-\311!\223\340LZ\22\306"
"&\321\240\34\24\222CbqHH\16\2\256\37\216\305\20>L,\222\10%\25Y\304\32\261\36\244\7"
"aez\220\306(\62\321DJ\7\1\257\37\254\311\20&\371\20\223\225\42\42\212\322uB\233D\16\25"
"\313\350\24;D\202\222X\34\26\1\260&\316\305\20.\35&\221C\354\200\203\220b\212X\16\222\203\344"
"\20\23\31#!Ih\26\22\305\1\301\70(\35(\7\261\27\212M\21\36\325v\10Z&\241\313Ar"
"\230\34$\207\313!f\2\262\31L\311\21\336\34\62\221\36D\207\213\354 ;\310&\241C$t\70\214"
"\4\263\26\212M\21\226\34\62\207\210%\25\222\371\360\201r\10\35b&\0\264\31\256E\21>@\16\224"
"C\345 \241pBY\361\277L$\26\251\35D\5\265\42\314\311\20fl$\221\214F\21I\204|\70"
"D*\7\213\344\60\233\220\351 \71H\22\207d\7E\1\266\33n\305\21>\70\16\230\210)b\312\224"
"B\235P\17\322C\364\20\266\3\352 \0\267\37\314\311\20\356\34R\224T$\323\221TZ\207\314\61\204"
"e\341I\34\42\211\303\342\300\70\4\0\270\27kI\21\336\351\360\60\246\211$\222\211t\16\231\3\350\0"
":D\12\271\42\315\305\20>H\16\234\3$T\312\320|\10^\202\21R\60$\213\3c\323 -<"
"\221C\344 \0\272$\314\311\20> \16\222\203\310\207\330D\222\242t\270H&\222I\344\20I\207\204"
"&I\241IRL\222\325\6\273(\316\305\20F\34\355|\20\36&\241\303\360@<DD\61Y$\64"
"\13EB\223\244Hh\222$\233$\205$\322\240\304\10\274\32\214\311\20\236U\250\355\60\221X\312\207\7"
"\313a\22\71D\322!\261C\10\0\275#\316\305\20.\35\244\16\261N(\223\242\351\20\22\35B\223C"
"Dr\250\35\246\207\70\204\16\12\306AT\0\276\22h\321\20\26M$\262\321\202\221!\307H\60F\2"
"\277\35\254\311\20&\35 \22\333\1t@\60:\214\215#t\0\35B\207\314A\21\261\320\6\300\32\314"
"\311\20&\35 \22\33%\24I\34F\207\230\257_#\65\241H\16\221\2\301\27J\315\21>D\246\66"
"\211\3\304\22!E\64\211H&QIx\16\302&\316\305\20>\214\16\252C(q\0)L\12\223\302"
"\244\240d\24\225\210\342\0\311\34$\7F\346\0\231\34 \207\2\303 \216E\21>,\16\215\304a\351"
"\220\240\34\20\233FBSId*\242\312\246B\251\34*\207\2\304$\316\305\20\366!l\211\3Hq"
"\210,\16\212\305\1\241\344Q$:\24\316as\330\34\66\207\315\201r(\0\305 \316\305\20>T\16"
"\234\303\346\260\71P\16\213C\347\260\71P\16\213C\347\260\71l\16\224C\1\306\27\214I\21v\371z"
",\5i\61\232l\64\273\226\351\200\71H\16\3\307 \316\305\20>@\16\14E\304\301i\70u\34+"
"G\354\0\253\210:\223\316as\330\34(\207\2\310\35\214I\21\326!v\230\34D\7\231\271\42\254\10"
"\353\0:d\16\212\304!\261C\10\0\311\27\314\311\20\206\34b<\230\256\257\25aEh\276\276Fj"
"B\33\0\312&\316\305\20\206\34v\230FI\261\340$\32\214\304\1\301\210\70\24\241\3b\343\250\64\24"
"\314\26\207\205\342\300\210\34*\313(\316\305\20>H\42\207\205\342\220P\34\224\42\16\305\242\241\344P\252"
"(U\42\212J&q\310$\16\213\310\201rh\34\4\314\23J\315\21\226\355\20\71|\20\12c\352\220"
"\261D(\1\315\27L\311\21\326!v\30\35F\207\321a\24\207\204\342\220\20/D\2\316\31N\305\21"
">L\16\233\304!\224\70\240\16\261\3\316\207\70\200L$\23\5\317&\316\305\20>(\22\7F\322A"
"\221\244H(bI:D\322\202\226\20\345\61d\241\5o\24;$\30\7\321A\0\320%\216E\21>"
"(\42\7M\344\20\311$\42\233TD\222\312hR\21\5'\243 EF\11\306!\301\70\210\16\2\321"
"\27N\305\21N\251;\32\211H\42\213\244\223Pdb:\224\16\304\2\322\32LI\22\6EB\207F"
"\16\21\311!\22\71L\210\207\340!x\10\36\202\4\323\30\356D\22\316\241\22\207V(\207H(r\210"
"H\42\224I(\62\246\2\324\33nE\21\236P*\241\310\306\223\342\201t(\331Fs\200\35\20\216\222"
"\210K\0\325\31L\311\21\6\361\20\221\34\202\224\341l\64\213\311B\207\321a\216r\10\1\326\32l\311"
"\21&\35\20\214\21/\241\310Er\20\35\16\23\22Y|\230\35B\0\327\37\314\311\20\246\325z\10\206"
"cqH(\16\11\305!\261p\64\30\234H&\304C\360\134\207\10\330\30kM\21\316\32\205D\251L"
"d\252e:\200\16\210\210c\302h\15\0\331\37\254\311\20\216X\22\62\311ar\330\34\242B\21\216\242"
"\245`)X\12Fd\321`\34@\4\332\20\214H\23FP\70\42M\222\42)\207\11\0\333\21\256\304"
"\22\316\341\60\233\211b\263,\261\340l\2\334\33\216E\21\246YM\16Q\233\204HJ$%\222\22I"
"\211\66!\311\301\312F\0\335\32\214I\21\256\34D\7X\17\261\303\344P\244C\350\20:\204\16\241C"
"\210\0\336\26kI\21\326Av\10^\215\267C\250\62\251]#sP\34\2\337\15J\315\21\36\231\355"
"\360C\215\314\6\340\22J\315\21\206\270\70\31\315\254d\252m\64\31\226\5\341\23L\311\21\16\211r\370"
"\203\345\60;D\355\0:H\12\342\35\256E\21\266\34*\7\322a\324\303\345P;L\17\321\303\360\60"
"+\225\306\23\71L\0\343%\316\305\20\266\34 \207\210B\246\340!z\30\36F\221\303Dr\230\204\16"
"\303\303\364\20\14\231Br\210\34 \6\344\21\212M\21N\361\20\265\226\253\35\213\226C\254\10\345 \316"
"\305\20.\35r\210\36fD\322x\62\223\231H&\222M\66\31\217\210\264\303\364\20\207P\1\346\35\256"
"E\21\266\34H\207\321Av\210H\16\30\215GS\22\221D;\224ZL\207\203\1\347\35\253I\21>"
"H\16\240\332\16\261Rl\30\13\307b\222X\314\22;\4%t\210\34\2\350%\316\305\20v\34\24\23"
"\5E\24\231\350\20\12\35\204\7\312\341@\222\234b\22J\34`\7I\344\240\230Xl\4\351#\256\305"
"\20VT\30I\223\316a\221\344`\70\222\16\233\303\42\351\300\70$\16\214\244\303\346\260H:\60\16\352"
"\35\312\315\20\246\34\20\12\207\242\243\340(V\12\225\42\266\233d(\207\310!\311\61\23\0\353\23\252\315"
"\20\336\315\261\365p\240\222\327\1r\200\34\22\7\354!\316\305\20.\35r\210\36fD\322x\62\223\231"
"\222L\21\221IF\221\235f\305\71t\16\236\4\1\355$\316\305\20>\240\16\71\37\244\7i\244\22\215"
"\3\42\243h\244T\232\304A\261\70l&\7\322a\241\70P\12\356\36\316\305\20\366!|\210\303\346\260"
"Qm\34\33\307\16\221\340\301\216\3\35\32\207\306\241T\0\357\33\312\315\20\226\355\20\71<\204D\63m"
"\221\321\220\30\221$\205C\22\65+\15\0\360 \316\305\20\306\34r>\10+\245\332\250\32\252C\352\220"
":\244\24\64\221\332\206\263\210P\222\16\15\361$\314\311\20\316a\22\207I\250\22\252\204*\241J\250\22"
"\252\204\32\211\14c\21Y\64\22\212\3Bq\220\24\0\362\35\312\315\20\306\203%\34\12\207\302\261`\64"
"\24\16E\203\261\220(\205\22:D\16\7\3\0\0\0";
#define MAP_DISPLAY_WIDTH 8
#define MAP_DISPLAY_HEIGHT 4
/*===============================================*/
u8g2_t u8g2;
pos_t window_upper_left_pos;
/*===============================================*/
void map_draw(uint8_t map_idx, uint8_t x0, uint8_t y0)
{
uint8_t x, y;
for( y = 0; y < MAP_DISPLAY_HEIGHT; y++ )
{
for( x = 0; x < MAP_DISPLAY_WIDTH; x++ )
{
if ( (uint8_t)(x+x0) < (uint8_t)map_list[map_idx].width )
{
if ( (uint8_t)(y+y0) < (uint8_t)map_list[map_idx].height )
{
u8g2_DrawGlyph(&u8g2, x*16, 16+y*16, getMapTile(x+x0, y+y0));
}
}
}
}
}
uint8_t is_inside(pos_t *p, pos_t *upper_left, uint8_t w, uint8_t h)
{
if ( p->x < upper_left->x )
return 0;
if ( p->y < upper_left->y )
return 0;
if ( p->x >= upper_left->x+w )
return 0;
if ( p->y >= upper_left->y+h )
return 0;
return 1;
}
/* assumes, that the direction of the item is set, but not yet executed */
void setWindowPosByItem(uint8_t item_index)
{
item_t *item;
pos_t tmp;
uint8_t window_dir = 5;
item = pool_GetItem(item_index);
tmp = window_upper_left_pos;
tmp.x++;
tmp.y++;
if ( is_inside(&(item->pos), &tmp, MAP_DISPLAY_WIDTH-2, MAP_DISPLAY_HEIGHT-2 ) == 0 )
{
printf("center\n");
window_upper_left_pos.x = item->pos.x;
window_upper_left_pos.x -= MAP_DISPLAY_WIDTH/2;
window_upper_left_pos.y = item->pos.y;
window_upper_left_pos.y -= MAP_DISPLAY_HEIGHT/2;
window_dir = item->dir;
}
else
{
if ( item->dir == 0 )
{
if ( item->pos.x == window_upper_left_pos.x + MAP_DISPLAY_WIDTH -2 )
window_dir = item->dir;
}
else if ( item->dir == 1 )
{
if ( item->pos.y == window_upper_left_pos.y+MAP_DISPLAY_HEIGHT-2 )
window_dir = item->dir;
}
else if ( item->dir == 2 )
{
if ( item->pos.x == window_upper_left_pos.x+1 )
window_dir = item->dir;
}
else if ( item->dir == 3 )
{
if ( item->pos.y == window_upper_left_pos.y+1 )
window_dir = item->dir;
}
}
posStep(&window_upper_left_pos, window_dir);
}
void moveHero(uint8_t dir)
{
/* hero move/action */
moveItem(0, dir);
/* other monster actions */
callStepAllItems();
/* recalculate window position */
setWindowPosByItem(0);
/* execute any movements */
moveAllItems();
}
int main(void)
{
int k;
uint8_t x, y;
x = 0;
y = 0;
u8g2_SetupBuffer_SDL_128x64_4(&u8g2, &u8g2_cb_r0);
u8x8_InitDisplay(u8g2_GetU8x8(&u8g2));
u8x8_SetPowerSave(u8g2_GetU8x8(&u8g2), 0);
u8g2_SetFont(&u8g2, scrollosprites);
setupLevel(0);
/* recalculate window position */
setWindowPosByItem(0);
for(;;)
{
printf("%d %d\n",window_upper_left_pos.x ,window_upper_left_pos.y);
u8g2_FirstPage(&u8g2);
do
{
map_draw(0, window_upper_left_pos.x, window_upper_left_pos.y);
} while( u8g2_NextPage(&u8g2) );
do
{
//usleep(100000);
k = u8g_sdl_get_key();
} while( k < 0 );
if ( k == 'q' ) break;
switch( k )
{
case 273: y--;
moveHero(3);
break;
case 274: y++;
moveHero(1);
break;
case 276: x--;
moveHero(2);
break;
case 275: x++;
moveHero(0);
break;
default: break;
}
}
return 0;
}

View File

@@ -0,0 +1,43 @@
#ifndef _MAP_H
#define _MAP_H
#include <stdint.h>
struct _item_onmap_struct
{
uint8_t x;
uint8_t y;
uint8_t template_index;
uint8_t option;
};
typedef struct _item_onmap_struct item_onmap_t;
struct _map_struct
{
unsigned char *data;
item_onmap_t *onmap_list;
uint16_t init_proc;
uint8_t onmap_cnt;
uint8_t width;
uint8_t height;
};
typedef struct _map_struct map_t;
struct _item_template_struct
{
uint16_t init_proc;
uint16_t hit_proc;
uint16_t step_proc;
uint8_t fg_tile; /* for tga output and inital tile */
};
typedef struct _item_template_struct item_template_t;
extern unsigned char map_code[] ;
extern item_template_t item_template_list[];
extern map_t map_list[];
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,22 @@
proc main
if print(0)
print(123)
else
print(999)
endif
print(test(777))
print(add(3,4))
endproc
# expects one argument, which has to be removed with the pop function
# procedures always have to ensure to remove their args
# test expects one argument a(1)
proc test
locals 1
a(2, a(1)) # store a(1) in local var a(2)
print(a(2)) # print local var a(2)
print(a(1)) # print argument a(1)
print(a(0)) # print return value a(0) (should be zero)
return(888)
endproc

View File

@@ -0,0 +1,271 @@
#include "u8g2.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#define FACTOR 3
//#define XOFFSET (FACTOR*32)
//#define YOFFSET (FACTOR*32)
#define DEFAULT_WIDTH (512+512)
#define DEFAULT_HEIGHT (1024+512+256)
uint16_t tga_max_x;
uint16_t tga_max_y;
size_t tga_max_offset = 0;
static uint16_t tga_width;
static uint16_t tga_height;
static uint8_t *tga_data = NULL;
uint8_t tga_r = 0;
uint8_t tga_g = 0;
uint8_t tga_b = 0;
uint8_t tga_desc_r = 0;
uint8_t tga_desc_g = 0;
uint8_t tga_desc_b = 0;
int tga_init(uint16_t w, uint16_t h)
{
tga_max_x = 0;
tga_max_y = 0;
tga_width = 0;
tga_height = 0;
tga_max_offset = 0;
if ( tga_data != NULL )
{
tga_data = (uint8_t *)realloc(tga_data, w*h*3);
}
else
{
tga_data = (uint8_t *)malloc(w*h*3);
}
if ( tga_data == NULL )
return 0;
memset(tga_data, 255, (long)w*(long)h*3L);
tga_width = w;
tga_height = h;
return 1;
}
void tga_set_pixel(uint16_t x, uint16_t y, uint16_t f)
{
uint8_t *p;
uint16_t xx,yy;
size_t offset;
for( yy = y; yy < y+f; yy++ )
{
for( xx = x; xx < x+f; xx++ )
{
if ( yy < tga_height && xx < tga_width )
{
//printf ("(%d %d) ", xx, yy);
offset = (tga_height-yy-1)*tga_width*3 + xx*3;
p = tga_data + offset;
if ( tga_max_offset < offset )
tga_max_offset = offset;
*p++ = tga_b;
*p++ = tga_g;
*p++ = tga_r;
}
}
}
}
void tga_clr_pixel(uint16_t x, uint16_t y, uint16_t f)
{
uint8_t *p;
size_t offset;
uint16_t xx,yy;
for( yy = y; yy < y+f; yy++ )
{
for( xx = x; xx < x+f; xx++ )
{
offset = (tga_height-yy-1)*tga_width*3 + xx*3;
p = tga_data + offset;
*p++ = 255;
*p++ = 255;
*p++ = 255;
}
}
}
void tga_set_8pixel(int x, int y, uint8_t pixel, uint16_t f)
{
int cnt = 8;
while( cnt > 0 )
{
if ( (pixel & 1) != 0 )
{
tga_set_pixel(x,y, f);
}
else
{
tga_clr_pixel(x,y, f);
}
pixel >>= 1;
y+=f;
cnt--;
}
}
void tga_set_multiple_8pixel(int x, int y, int cnt, uint8_t *pixel, uint16_t f)
{
uint8_t b;
while( cnt > 0 )
{
b = *pixel;
tga_set_8pixel(x, y, b, f);
x+=f;
pixel++;
cnt--;
}
}
void tga_write_byte(FILE *fp, uint8_t byte)
{
fputc(byte, fp);
}
void tga_write_word(FILE *fp, uint16_t word)
{
tga_write_byte(fp, word&255);
tga_write_byte(fp, word>>8);
}
void tga_save(const char *name)
{
FILE *fp;
if ( tga_data == NULL )
return;
//printf("tga_save: File %s with %dx%d pixel\n", name, tga_width, tga_height);
fp = fopen(name, "wb");
if ( fp != NULL )
{
tga_write_byte(fp, 0); /* no ID */
tga_write_byte(fp, 0); /* no color map */
tga_write_byte(fp, 2); /* uncompressed true color */
tga_write_word(fp, 0);
tga_write_word(fp, 0);
tga_write_byte(fp, 0);
tga_write_word(fp, 0); /* x origin */
tga_write_word(fp, 0); /* y origin */
tga_write_word(fp, tga_width); /* width */
tga_write_word(fp, tga_height); /* height */
tga_write_byte(fp, 24); /* color depth */
tga_write_byte(fp, 0);
fwrite(tga_data, tga_width*tga_height*3, 1, fp);
tga_write_word(fp, 0);
tga_write_word(fp, 0);
tga_write_word(fp, 0);
tga_write_word(fp, 0);
fwrite("TRUEVISION-XFILE.", 18, 1, fp);
fclose(fp);
}
}
/*==========================================*/
/* tga procedures */
u8x8_display_info_t u8x8_tga_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 0,
/* pre_chip_disable_wait_ns = */ 0,
/* reset_pulse_width_ms = */ 0,
/* post_reset_wait_ms = */ 0,
/* sda_setup_time_ns = */ 0,
/* sck_pulse_width_ns = */ 0,
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 1,
/* i2c_bus_clock_100kHz = */ 0,
/* data_setup_time_ns = */ 0,
/* write_pulse_width_ns = */ 0,
/* tile_width = */ (DEFAULT_WIDTH)/8,
/* tile_hight = */ (DEFAULT_HEIGHT)/8,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
DEFAULT_WIDTH,
DEFAULT_HEIGHT
};
uint8_t u8x8_d_tga(u8x8_t *u8g2, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
u8g2_uint_t x, y, c;
uint8_t *ptr;
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8g2, &u8x8_tga_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8g2);
//if ( tga_data == NULL )
tga_init(u8x8_tga_info.pixel_width, u8x8_tga_info.pixel_height);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
break;
case U8X8_MSG_DISPLAY_SET_CONTRAST:
break;
case U8X8_MSG_DISPLAY_DRAW_TILE:
tga_r = tga_desc_r;
tga_g = tga_desc_g;
tga_b = tga_desc_b;
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
//printf("U8X8_MSG_DISPLAY_DRAW_TILE x=%d, ", x);
x *= 8;
x += u8g2->x_offset;
y = ((u8x8_tile_t *)arg_ptr)->y_pos;
//printf("y=%d, c=%d\n", y, ((u8x8_tile_t *)arg_ptr)->cnt);
y *= 8;
do
{
c = ((u8x8_tile_t *)arg_ptr)->cnt;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
tga_set_multiple_8pixel(x, y, c*8, ptr, 1);
arg_int--;
} while( arg_int > 0 );
break;
default:
return 0;
}
return 1;
}
void u8x8_Setup_TGA(u8x8_t *u8x8)
{
/* setup defaults */
u8x8_SetupDefaults(u8x8);
/* setup specific callbacks */
u8x8->display_cb = u8x8_d_tga;
/* setup display info */
u8x8_SetupMemory(u8x8);
}
void u8g2_SetupBuffer_TGA(u8g2_t *u8g2, const u8g2_cb_t *u8g2_cb)
{
static uint8_t buf[(DEFAULT_WIDTH)*8*8];
u8x8_Setup_TGA(u8g2_GetU8x8(u8g2));
u8g2_SetupBuffer(u8g2, buf, 8, u8g2_ll_hvline_vertical_top_lsb, u8g2_cb);
}

View File

@@ -0,0 +1,57 @@
/*
proc <name>
*/
#ifndef _UGL_H
#define _UGL_H
#include <stdint.h>
#include <stdarg.h>
#include <stdio.h>
#define UGL_MAX_IDENTIFIER_LEN 63
/* ugl_error.c */
extern int ugl_current_input_line;
extern int ugl_is_suppress_log;
void ugl_err(const char *fmt, ...) __attribute__ ((noreturn));
void ugl_plog(const char *fmt, ...);
void ugl_glog(const char *fmt, ...);
/* ugl_arrays.c */
extern uint16_t ugl_bytecode_len;
void ugl_InitBytecode(void);
void ugl_AddBytecode(uint8_t x);
void ugl_ExecBytecode(void);
void ugl_ResolveSymbols(void);
void ugl_WriteBytecodeCArray(FILE *fp, const char *name);
int ugl_GetLabel(const char *name);
void ugl_SetLabelBytecodePos(const char *name, uint16_t bytecode_pos);
uint16_t ugl_GetLabelBytecodePos(int idx);
/* ugl_parse.c */
uint16_t uglStartNamelessProc(int args);
int ugl_read_line(const char **s);
int uglReadLine(const char **s);
/* ugl_main.c */
int ugl_read_fp(void);
int ugl_read_filename(const char *name);
#endif

View File

@@ -0,0 +1,247 @@
#include "ugl.h"
#include "ugl_bc.h"
#include <string.h>
#include <stdio.h>
/* arrays & variables */
#define UGL_MAX_BYTECODE_LEN (63*1024)
uint8_t ugl_bytecode_array[UGL_MAX_BYTECODE_LEN];
uint16_t ugl_bytecode_len;
#define UGL_MAX_LABEL_CNT 128
char ugl_label_name[UGL_MAX_LABEL_CNT][UGL_MAX_IDENTIFIER_LEN+1];
uint16_t ugl_label_bytecode_pos[UGL_MAX_LABEL_CNT]; /* position in the bytecode array */
int ugl_label_cnt;
/* procedures */
void ugl_AddBytecode(uint8_t x)
{
ugl_bytecode_array[ugl_bytecode_len] = x;
ugl_bytecode_len++;
}
void ugl_InitBytecode(void)
{
ugl_bytecode_len = 0;
ugl_AddBytecode(BC_CMD_RETURN_FROM_PROCEDURE);
}
/*
extern uint8_t ugl_bytecode_array[];
void ugl_ExecBytecode(void)
{
bc_t bc;
bc_exec(&bc, ugl_bytecode_array, 0);
}
*/
void ugl_CheckForAllLabelsDefined(void)
{
int i;
for( i = 0; i < ugl_label_cnt; i++ )
{
if ( ugl_label_bytecode_pos[ugl_label_cnt] == 0x0ffff )
{
ugl_err("undefined label '%s'", ugl_label_name[i] );
}
}
}
void ugl_ResolveSymbols(void)
{
uint8_t *code = ugl_bytecode_array;
uint8_t *dest = ugl_bytecode_array+ugl_bytecode_len;
uint16_t val;
uint8_t cmd;
ugl_CheckForAllLabelsDefined();
ugl_glog("Resolve start=%p, end=%p", code, dest);
ugl_glog("Resolve bytecode len=%d", ugl_bytecode_len);
while( code < dest )
{
cmd = *code;
ugl_glog("Resolve pos=%p, cmd=%02x", code, cmd);
code++;
val = cmd;
val &=0x0f0; /* put upper four bit as upper 4bit of the 12bit value into val */
val <<= 4;
switch(cmd&15)
{
case BC_CMD_LOAD_12BIT:
code++;
break;
case BC_CMD_CALL_BUILDIN:
code++;
break;
case BC_CMD_CALL_BUILDIN_POP_STACK:
code++;
break;
case BC_CMD_BRANCH:
val |= *code;
code++;
ugl_glog("Resolve BRANCH '%s' (idx=%d)", ugl_label_name[val], val);
val = ugl_GetLabelBytecodePos(val);
val = (val - (uint16_t)(code - ugl_bytecode_array));
ugl_glog("Resolve BRANCH delta=0x%03x", val);
*(code-2) &= 0x0f;
*(code-2) |= (val >> 4) & 0x0f0;
*(code-1) = val & 255;
break;
case BC_CMD_POP_ARG_STACK:
break;
case BC_CMD_PUSH_ARG_STACK:
break;
case BC_CMD_CALL_PROCEDURE:
val = code[0];
val <<= 8;
val |= code[1];
ugl_glog("Resolve CALL Procedre '%s' pos=%u", ugl_label_name[val], ugl_GetLabelBytecodePos(val));
val = ugl_GetLabelBytecodePos(val);
*code = val>>8;
code++;
*code = val&255;
code++;
break;
default: /* assume 0x0f, extended command */
switch( cmd )
{
case BC_CMD_LOAD_0:
break;
case BC_CMD_LOAD_1:
break;
case BC_CMD_LOAD_16BIT:
code++;
code++;
break;
case BC_CMD_RETURN_FROM_PROCEDURE:
break;
case BC_CMD_JUMP_NOT_ZERO:
case BC_CMD_JUMP_ZERO:
val = code[0];
val <<= 8;
val |= code[1];
ugl_glog("Resolve JUMP '%s'", ugl_label_name[val]);
val = ugl_GetLabelBytecodePos(val);
*code = val>>8;
code++;
*code = val&255;
code++;
break;
#ifdef NOT_USED
case BC_CMD_CALL_PROCEDURE:
val = code[0];
val <<= 8;
val |= code[1];
ugl_glog("Resolve CALL Procedre '%s' pos=%u", ugl_label_name[val], ugl_GetLabelBytecodePos(val));
val = ugl_GetLabelBytecodePos(val);
*code = val>>8;
code++;
*code = val&255;
code++;
break;
#endif
/*
case BC_CMD_POP_ARG_STACK:
break;
*/
default:
ugl_err("Resolve: Unexpected command");
break;
}
break;
} /* switch() */
} /* while */
}
static int ugl_FindLabel(const char *name)
{
int i;
for( i = 0; i < ugl_label_cnt; i++ )
{
if (strcmp(name, ugl_label_name[i] ) == 0 )
return i;
}
return -1;
}
static int ugl_AddLabel(const char *name)
{
strcpy(ugl_label_name[ugl_label_cnt], name);
ugl_label_bytecode_pos[ugl_label_cnt] = 0x0ffff;
ugl_label_cnt++;
if ( ugl_label_cnt >= UGL_MAX_LABEL_CNT )
ugl_err("max number of labels reached, label=%s", name);
return ugl_label_cnt-1;
}
int ugl_GetLabel(const char *name)
{
int idx;
idx = ugl_FindLabel(name);
if ( idx >= 0 )
return idx;
return ugl_AddLabel(name);
}
void ugl_SetLabelBytecodePos(const char *name, uint16_t bytecode_pos)
{
int idx;
idx = ugl_GetLabel(name);
if ( ugl_label_bytecode_pos[idx] != 0x0ffff )
ugl_err("double definition of label '%s'", name);
ugl_label_bytecode_pos[idx] = bytecode_pos;
}
uint16_t ugl_GetLabelBytecodePos(int idx)
{
if ( ugl_label_bytecode_pos[idx] == 0x0ffff )
ugl_err("undefined label '%s'", ugl_label_name[idx]);
return ugl_label_bytecode_pos[idx];
}
void ugl_WriteBytecodeCArray(FILE *fp, const char *name)
{
uint16_t i;
fprintf(fp, "unsigned char %s[] =\n \"", name);
i = 0;
while ( i < ugl_bytecode_len )
{
fprintf(fp, "\\x%02x", ugl_bytecode_array[i]);
if ( i+1 == ugl_bytecode_len )
{
break;
}
if ( (i & 0x0f) == 0x0f )
{
fprintf(fp, "\"\n \"");
}
i++;
}
fprintf(fp, "\";\n\n");
}

View File

@@ -0,0 +1,428 @@
/*
ugl_bc.c
items can be at three places
1) map
2) inventory
3) hero
map --> inventory take
inventory --> map drop
inventory --> hero equip
hero --> inventory unequip
hero --> map drop
inputs:
hDir() // direction into which the hero wants to walk, had waked or looks
iDir() // direction into which the item/creatue/missel wants to go, went or looks
hX() // hero X position
hY() // hero Y position
posByH // set current position to the position of the hero
posByI // set current position to the position of the current item
posAppyDir(dir) // change the possition going one step into the specified direction
*/
#include "ugl_bc.h"
#include <stdio.h>
#include <assert.h>
#ifndef UGL_TEST
#include "item.h"
#include "map.h"
#endif
void bc_push_on_arg_stack(bc_t *bc, uint16_t val)
{
bc->arg_stack[bc->arg_stack_pointer] = val;
bc->arg_stack_pointer++;
}
uint16_t bc_pop_from_arg_stack(bc_t *bc)
{
assert( bc->arg_stack_pointer > 0 );
bc->arg_stack_pointer--;
return bc->arg_stack[bc->arg_stack_pointer] ;
}
void bc_duplicate_arg_stack_top_value(bc_t *bc)
{
bc->arg_stack[bc->arg_stack_pointer] = bc->arg_stack[bc->arg_stack_pointer-1];
bc->arg_stack_pointer++;
}
void bc_push_on_return_stack(bc_t *bc, uint16_t val)
{
bc->return_stack[bc->return_stack_pointer] = val;
bc->return_stack_pointer++;
}
uint16_t bc_pop_from_return_stack(bc_t *bc)
{
assert( bc->return_stack_pointer > 0 );
bc->return_stack_pointer--;
return bc->return_stack[bc->return_stack_pointer];
}
uint16_t bc_get_value(uint8_t *code)
{
uint16_t val;
val = *code;
code++;
val <<= 8;
val |= *code;
code++;
return val;
}
void bc_init(bc_t *bc)
{
bc->arg_stack_pointer = 0;
bc->return_stack_pointer = 0;
}
#define BC_DBG_OUT_POS(pos) printf("%05d ", (int)(pos))
#define BC_DBG_OUT_HEX(c) printf("0x%02x ", (int)(c))
#define BC_DBG_OUT_STR(str) printf("%s ", (str))
#define BC_DBG_OUT_NUM(n) printf("%d ", (int)(n))
#define BC_DBG_OUT_NUM3(n) printf("%03d ", (int)(n))
#define BC_DBG_OUT_CR() printf("\n")
void bc_exec(bc_t *bc, uint8_t *code, uint16_t pos)
{
uint16_t val;
uint8_t cmd;
bc_init(bc);
bc->code = code;
bc->code_pos = pos;
for(;;)
{
cmd = bc->code[bc->code_pos];
BC_DBG_OUT_POS(bc->code_pos);
BC_DBG_OUT_NUM3(bc->arg_stack_pointer);
BC_DBG_OUT_HEX(cmd);
bc->code_pos++;
val = cmd;
val &=0x0f0; /* put upper four bit as upper 4bit of the 12bit value into val */
val <<= 4;
switch(cmd&15)
{
case BC_CMD_LOAD_12BIT:
BC_DBG_OUT_STR("LOAD12");
val |= bc->code[bc->code_pos];
BC_DBG_OUT_NUM(val);
bc->code_pos++;
bc_push_on_arg_stack(bc, val);
BC_DBG_OUT_CR();
break;
case BC_CMD_CALL_BUILDIN:
BC_DBG_OUT_STR("CALL BUILDIN");
val |= bc->code[bc->code_pos];
BC_DBG_OUT_NUM(val);
bc->code_pos++;
BC_DBG_OUT_CR();
bc_buildin_list[val](bc);
break;
case BC_CMD_CALL_BUILDIN_POP_STACK:
BC_DBG_OUT_STR("CALL BUILDIN POP ARG STACK");
val |= bc->code[bc->code_pos];
BC_DBG_OUT_NUM(val);
bc->code_pos++;
BC_DBG_OUT_CR();
bc_buildin_list[val](bc);
bc_pop_from_arg_stack(bc);
break;
case BC_CMD_BRANCH:
BC_DBG_OUT_STR("BRANCH");
val |= bc->code[bc->code_pos];
bc->code_pos++;
if ( val < 0x0800 )
{
bc->code_pos += val;
}
else
{
val = 0x1000 - val;
bc->code_pos -= val;
}
BC_DBG_OUT_POS(bc->code_pos);
BC_DBG_OUT_CR();
case BC_CMD_POP_ARG_STACK:
cmd >>= 4; /* in this case we need the lower 4 bit */
BC_DBG_OUT_STR("POP ARG STACK");
cmd++; /* cmd is reused as a counter for the number of stack pops */
BC_DBG_OUT_NUM(cmd);
do
{
bc_pop_from_arg_stack(bc);
cmd--;
} while( cmd > 0 );
BC_DBG_OUT_CR();
break;
case BC_CMD_PUSH_ARG_STACK:
cmd >>= 4; /* in this case we need the lower 4 bit */
BC_DBG_OUT_STR("PUSH ARG STACK");
cmd++; /* cmd is reused as a counter for the number of stack pops */
BC_DBG_OUT_NUM(cmd);
do
{
bc_push_on_arg_stack(bc, 0);
cmd--;
} while( cmd > 0 );
BC_DBG_OUT_CR();
break;
case BC_CMD_CALL_PROCEDURE:
BC_DBG_OUT_STR("CALL PROC");
cmd >>= 4; /* in this case we need the lower 4 bit--> number of args */
BC_DBG_OUT_NUM(cmd); /* output number of args */
val = bc->code[bc->code_pos];
bc->code_pos++;
val <<= 8;
val |= bc->code[bc->code_pos];
bc->code_pos++;
bc_push_on_return_stack(bc, bc->code_pos); /* return position */
bc_push_on_return_stack(bc, bc->arg_stack_pointer - cmd -1); /* store the start pos of the return value and the args */
bc->code_pos = val;
BC_DBG_OUT_NUM(bc->code_pos);
BC_DBG_OUT_CR();
break;
default: /* assume 0x0f, extended command */
switch( cmd )
{
case BC_CMD_LOAD_0:
BC_DBG_OUT_STR("LOAD#0");
bc_push_on_arg_stack(bc, 0);
BC_DBG_OUT_CR();
break;
case BC_CMD_LOAD_1:
BC_DBG_OUT_STR("LOAD#1");
bc_push_on_arg_stack(bc, 1);
BC_DBG_OUT_CR();
break;
case BC_CMD_LOAD_16BIT:
BC_DBG_OUT_STR("LOAD16");
val = bc->code[bc->code_pos];
bc->code_pos++;
val <<= 8;
val |= bc->code[bc->code_pos];
bc->code_pos++;
bc_push_on_arg_stack(bc, val);
BC_DBG_OUT_NUM(val);
BC_DBG_OUT_CR();
break;
case BC_CMD_RETURN_FROM_PROCEDURE:
BC_DBG_OUT_STR("RETURN to");
if ( bc->return_stack_pointer == 0 )
{
BC_DBG_OUT_STR("exit");
BC_DBG_OUT_CR();
BC_DBG_OUT_STR("arg stack: ");
BC_DBG_OUT_NUM(bc->arg_stack_pointer);
BC_DBG_OUT_CR();
BC_DBG_OUT_STR("return stack: ");
BC_DBG_OUT_NUM(bc->return_stack_pointer);
BC_DBG_OUT_CR();
return; /* stop execution */
}
//bc_push_on_arg_stack(bc, bc_pop_from_return_stack(bc)); /* copy return value on arg stack */
bc->arg_stack_pointer = bc_pop_from_return_stack(bc) + 1; /* restore the arg stack pointer, leave return value on stack */
bc->code_pos = bc_pop_from_return_stack(bc);
BC_DBG_OUT_NUM(bc->code_pos);
BC_DBG_OUT_CR();
break;
case BC_CMD_JUMP_NOT_ZERO:
BC_DBG_OUT_STR("JUMP NZ");
val = bc->code[bc->code_pos];
bc->code_pos++;
val <<= 8;
val |= bc->code[bc->code_pos];
bc->code_pos++;
if ( bc_pop_from_arg_stack(bc) != 0 )
bc->code_pos = val;
break;
BC_DBG_OUT_NUM(bc->code_pos);
BC_DBG_OUT_CR();
case BC_CMD_JUMP_ZERO:
BC_DBG_OUT_STR("JUMP Z");
val = bc->code[bc->code_pos];
bc->code_pos++;
val <<= 8;
val |= bc->code[bc->code_pos];
bc->code_pos++;
if ( bc_pop_from_arg_stack(bc) == 0 )
bc->code_pos = val;
BC_DBG_OUT_NUM(bc->code_pos);
BC_DBG_OUT_CR();
break;
case BC_CMD_CALL_PROCEDURE:
BC_DBG_OUT_STR("CALL PROC");
val = bc->code[bc->code_pos];
bc->code_pos++;
val <<= 8;
val |= bc->code[bc->code_pos];
bc->code_pos++;
bc_push_on_return_stack(bc, bc->code_pos); /* return position */
bc_push_on_return_stack(bc, 0); /* return value */
bc->code_pos = val;
BC_DBG_OUT_NUM(bc->code_pos);
BC_DBG_OUT_CR();
break;
/*
case BC_CMD_POP_ARG_STACK:
BC_DBG_OUT_STR("POP ARG STACK");
BC_DBG_OUT_CR();
bc_pop_from_arg_stack(bc);
break;
*/
default:
break;
}
break;
} /* switch() */
} /* for(;;) */
}
/*======================================================*/
/* put top of stack into register a, reduce stack */
//void bc_pop_a(bc_t *bc)
//{
// bc->stack_pointer--;
// bc->a = bc->stack[bc->stack_pointer];
//}
/*======================================================*/
/* return a pointer to a variable on the arg stack within the current stack frame */
/* pos = 0 is the return value of a user function, pos = 1... are the args for that function */
uint16_t *bc_get_stack_frame_address(bc_t *bc, uint8_t pos)
{
return bc->arg_stack + bc->return_stack[bc->return_stack_pointer-1] + pos ;
}
void bc_fn_nop(bc_t *bc)
{
bc_push_on_arg_stack(bc, 0);
}
/* description: "return" sets the return value of a procedure. If used inside an expresion, it returns its argument */
/* assign return value for a user defined function */
/* identical to arg(0) */
void bc_fn_return(bc_t *bc)
{
bc_duplicate_arg_stack_top_value(bc); /* goal is to leave a value on the stack */
*bc_get_stack_frame_address(bc, 0) = bc_pop_from_arg_stack(bc);
/*
v = bc_pop_from_arg_stack(bc);
bc_push_on_arg_stack(bc, v);
bc_pop_from_return_stack(bc);
bc_push_on_return_stack(bc, v);
*/
}
void bc_fn_print(bc_t *bc)
{
bc_duplicate_arg_stack_top_value(bc); /* goal is to leave a value on the stack */
printf("%u\n", bc_pop_from_arg_stack(bc));
}
/* return an argument of a user defined procedure */
void bc_fn_arg1(bc_t *bc)
{
bc_push_on_arg_stack(bc, *bc_get_stack_frame_address(bc, bc_pop_from_arg_stack(bc)));
}
/* remove the top element from the stack and return the same */
void bc_fn_arg2(bc_t *bc)
{
uint16_t v = bc_pop_from_arg_stack(bc); /* the value, which should be assigned */
*bc_get_stack_frame_address(bc, bc_pop_from_arg_stack(bc)) = v;
bc_push_on_arg_stack(bc, v); /* push the value back on the stack */
}
void bc_fn_add(bc_t *bc)
{
uint16_t v;
v = bc_pop_from_arg_stack(bc);
v += bc_pop_from_arg_stack(bc);
bc_push_on_arg_stack(bc, v);
}
#ifndef UGL_TEST
pos_t bc_pos;
#endif
void bc_fn_setPos(bc_t *bc)
{
uint8_t x, y;
y = bc_pop_from_arg_stack(bc);
x = bc_pop_from_arg_stack(bc);
#ifndef UGL_TEST
bc_pos.x = x;
bc_pos.y = y;
#endif
bc_push_on_arg_stack(bc, 0);
}
void bc_fn_setItemPos(bc_t *bc)
{
uint8_t i;
i = bc_pop_from_arg_stack(bc);
#ifndef UGL_TEST
pool_GetItem(i)->pos = bc_pos;
printf("item %d new x=%d y=%d\n", i, bc_pos.x, bc_pos.y);
#endif
bc_push_on_arg_stack(bc, i);
}
void bc_fn_setItemDir(bc_t *bc)
{
uint8_t i;
uint8_t dir;
dir = bc_pop_from_arg_stack(bc);
i = bc_pop_from_arg_stack(bc);
#ifndef UGL_TEST
pool_GetItem(i)->dir = dir;
printf("item %d dir=%d\n", i, dir);
#endif
bc_push_on_arg_stack(bc, i);
}
/*======================================================*/
bc_buildin_fn bc_buildin_list[] =
{
/* 0 */ bc_fn_nop,
/* 1 */ bc_fn_return,
/* 2 */ bc_fn_arg1, /* one argument */
/* 3 */ bc_fn_arg2, /* two arguments */
/* 4 */ bc_fn_add,
/* 5 */ bc_fn_print,
/* 6 */ bc_fn_setPos, /* two args: x & y: assign x/y to the pos temp var */
/* 7 */ bc_fn_setItemPos, /* one args: item, assign pos temp var to item */
/* 8 */ bc_fn_setItemDir, /* two args, item and dir */
};

View File

@@ -0,0 +1,85 @@
/*
ugl_bc.h
bytecode interpreter
*/
#ifndef _UGL_BC_H
#define _UGL_BC_H
#include <stdint.h>
#define BC_STACK_SIZE 64
#define BC_RETURN_STACK_SIZE 6
struct bc_struct
{
uint8_t *code;
uint16_t code_pos;
uint8_t arg_stack_pointer; /* starts at 0 and grows */
uint8_t return_stack_pointer; /* starts at 0 and grows */
uint16_t arg_stack[BC_STACK_SIZE]; /* parameter and return value stack */
uint16_t return_stack[BC_RETURN_STACK_SIZE]; /* return from procedure stack */
};
typedef struct bc_struct bc_t;
typedef void (*bc_buildin_fn)(bc_t *bc);
extern bc_buildin_fn bc_buildin_list[];
/* lower 4 bit: 0, upper 4 bit + next byte --> 12 bit value */
#define BC_CMD_LOAD_12BIT (0x00)
/* lower 4 bit: 1, upper 4 bit + next byte --> 12 bit value */
#define BC_CMD_CALL_BUILDIN (0x01)
/* lower 4 bit: 2, upper 4 bit + next byte --> 12 bit value (toplevel call, return value will be removed) */
#define BC_CMD_CALL_BUILDIN_POP_STACK (0x02)
/* lower 4 bit: 3, upper 4 bit + next byte --> 12 bit relative adr */
#define BC_CMD_BRANCH (0x03)
/* lower 4 bit: 4, upper 4 bit: 0..15, pop 1..16 bytes from the arg stack */
/* only used to remove one byte, so could be moved to different section */
#define BC_CMD_POP_ARG_STACK (0x04)
/* lower 4 bit: 5, upper 4 bit: 0..15, push 1..16 bytes on the arg stack */
/* not used any more */
#define BC_CMD_PUSH_ARG_STACK (0x05)
/* lower 4 bit: 5, upper 4 bit: 0..15, push 1..16 arguments, then two bytes for destination adr*/
#define BC_CMD_CALL_PROCEDURE (0x06)
/* lower 4 bit: 15, upper 4 bit: 0 --> put 0 on stack */
#define BC_CMD_LOAD_0 (0x0f)
/* lower 4 bit: 15, upper 4 bit: 1 --> put 1 on stack */
#define BC_CMD_LOAD_1 (0x1f)
/* lower 4 bit: 15, upper 4 bit: 2 --> but 16 bit value on stack, order: high byte, low byte */
#define BC_CMD_LOAD_16BIT (0x2f)
/* lower 4 bit: 15, upper 4 bit: 3 */
#define BC_CMD_RETURN_FROM_PROCEDURE (0x3f)
/* lower 4 bit: 15, upper 4 bit: 4 --> adr are next 16 bit*/
#define BC_CMD_JUMP_NOT_ZERO (0x4f)
/* lower 4 bit: 15, upper 4 bit: 5 --> adr are next 16 bit*/
#define BC_CMD_JUMP_ZERO (0x05f)
/* lower 4 bit: 15, upper 4 bit: 6 --> adr are next 16 bit */
//#define BC_CMD_CALL_PROCEDURE (0x06f)
/* lower 4 bit: 15, upper 4 bit: 7 --> adr are next 16 bit, third byte are the number of arguments */
//#define BC_CMD_POP_ARG_STACK (0x07f)
void bc_exec(bc_t *bc, uint8_t *code, uint16_t pos);
/*======================================================*/
#endif

View File

@@ -0,0 +1,43 @@
#include "ugl.h"
#include <stdio.h>
#include <stdlib.h>
int ugl_current_input_line;
int ugl_is_suppress_log = 0;
void ugl_err(const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
vprintf(fmt, va);
printf("\n");
va_end(va);
exit(1);
}
void ugl_plog(const char *fmt, ...)
{
va_list va;
if ( ugl_is_suppress_log != 0 )
return;
va_start(va, fmt);
printf("%d: ", ugl_current_input_line);
vprintf(fmt, va);
printf("\n");
va_end(va);
}
/* generic log */
void ugl_glog(const char *fmt, ...)
{
va_list va;
if ( ugl_is_suppress_log != 0 )
return;
va_start(va, fmt);
vprintf(fmt, va);
printf("\n");
va_end(va);
}

View File

@@ -0,0 +1,55 @@
#include "ugl.h"
#include "ugl_bc.h"
#include <stdio.h>
#define UGL_MAX_INPUT_LINE_LEN 1024
FILE *ugl_input_fp;
char ugl_input_line[UGL_MAX_INPUT_LINE_LEN];
int ugl_read_fp(void)
{
const char *s;
ugl_current_input_line = 0;
for(;;)
{
if ( fgets(ugl_input_line, UGL_MAX_INPUT_LINE_LEN, ugl_input_fp) == NULL )
break;
ugl_current_input_line++;
s = &(ugl_input_line[0]);
if ( ugl_read_line(&s) == 0 )
return 0;
}
return 1;
}
int ugl_read_filename(const char *name)
{
ugl_input_fp = fopen(name, "r");
if ( ugl_input_fp == NULL )
return 0;
printf("file '%s'\n", name);
if ( ugl_read_fp() == 0 )
return fclose(ugl_input_fp), 0;
fclose(ugl_input_fp);
return 1;
}
extern uint8_t ugl_bytecode_array[];
void ugl_ExecBytecode(void)
{
bc_t bc;
bc_exec(&bc, ugl_bytecode_array, 0);
}
int main(void)
{
ugl_InitBytecode();
ugl_read_filename("test.ugl");
ugl_ResolveSymbols();
ugl_ExecBytecode();
ugl_WriteBytecodeCArray(stdout, "code");
}

View File

@@ -0,0 +1,529 @@
/*
ugl_file.c
microcontroller game language
bytecode
return from procedure... all procedure leave a 16 bit value on the stack
jump probably only for if/loop
pop stack and jump on zero
pop stack and jump on not zero
call buildin procedure
call bytecode procedure
call toplevel buildin procedure
call toplevel bytecode procedure
push constant 16 bit value on stack
pop constant value from stack
proc <name> Starts a new procedure. Procedures must be terminated with "endproc"
endproc End a procedure
locals <num> Define the specified number of local variables, acces with arg(n), where n is between no_of_args+1 and no_of_args+<num>
*/
#include <stdio.h>
#include <string.h>
#include "ugl.h"
#include "ugl_bc.h"
long ugl_current_local_variables = 0;
long ugl_current_args = 0;
#define UGL_MAX_INDENT 64
#define UGL_INDENT_TYPE_PROC 0
#define UGL_INDENT_TYPE_IF 1
#define UGL_INDENT_TYPE_LOOP 2
int ugl_indent_level;
int ugl_indent_type[UGL_MAX_INDENT];
char ugl_indent_identifier[UGL_MAX_INDENT][UGL_MAX_IDENTIFIER_LEN+1];
struct ugl_buildin_cmd_struct
{
int code;
const char *name;
int args;
};
struct ugl_buildin_cmd_struct ugl_buildin_cmd_list[] = {
{ /* code=*/ 0, /* name=*/ "nop", /* args=*/ 0},
{ /* code=*/ 1, /* name=*/ "return", /* args=*/ 1 }, /* assign the return value of a user defined function */
{ /* code=*/ 2, /* name=*/ "a", /* args=*/ 1 }, /* return the value of the n-th argument of a user defined function */
{ /* code=*/ 3, /* name=*/ "a", /* args=*/ 2 }, /* reassign the value of the n-th argument of a user defined function */
{ /* code=*/ 4, /* name=*/ "add", /* args=*/ 2 },
{ /* code=*/ 5, /* name=*/ "print", /* args=*/ 1 },
{ /* code=*/ 6, /* name=*/ "setPos", /* args=*/ 2 },
{ /* code=*/ 7, /* name=*/ "setItemPos", /* args=*/ 1 },
{ /* code=*/ 8, /* name=*/ "setItemDir", /* args=*/ 2 },
};
void ugl_IncIndent(int type)
{
if ( ugl_indent_level > UGL_MAX_INDENT )
ugl_err("max indent level reached");
ugl_indent_type[ugl_indent_level] = type;
ugl_indent_level++;
}
void ugl_DecIndent(int type)
{
if ( ugl_indent_level == 0 )
ugl_err("can not decrement indent level, requested type = %d", type);
ugl_indent_level--;
if (ugl_indent_type[ugl_indent_level] != type )
ugl_err("block end mismatch, %d != %d", ugl_indent_type[ugl_indent_level] , type );
}
static void skip_space(const char **s)
{
for(;;)
{
if ( **s == '#' )
{
while( **s != '\0' )
(*s)++;
break;
}
if ( **s == '\0' )
break;
if ( **s > ' ' )
break;
(*s)++;
}
}
static long get_dec(const char **s)
{
long v = 0;
for(;;)
{
if ( (**s) >= '0' && (**s) <= '9' )
{
v*=10;
v+= (**s)-'0';
(*s)++;
}
else
{
break;
}
}
skip_space(s);
return v;
}
static long get_hex(const char **s)
{
long v = 0;
for(;;)
{
if ( (**s) >= '0' && (**s) <= '9' )
{
v*=16;
v+= (**s)-'0';
(*s)++;
}
else if ( (**s) >= 'a' && (**s) <= 'f' )
{
v*=16;
v+= (**s)-'a'+10;
(*s)++;
}
else if ( (**s) >= 'A' && (**s) <= 'F' )
{
v*=16;
v+= (**s)-'A'+10;
(*s)++;
}
else
{
break;
}
}
skip_space(s);
return v;
}
static long get_ascii(const char **s)
{
long v = 0;
v = **s;
(*s)++;
skip_space(s);
return v;
}
static long get_num(const char **s)
{
if ( (**s) == '$' )
{
(*s)++;
return get_hex(s);
}
if ( (**s) == '\'' )
{
(*s)++;
return get_ascii(s);
}
return get_dec(s);
}
static const char *get_identifier(const char **s)
{
static char buf[UGL_MAX_IDENTIFIER_LEN+1];
int c;
int i = 0;
buf[0] = '\0';
for(;;)
{
c = **s;
if ( c < 'A' )
break;
if ( i > UGL_MAX_IDENTIFIER_LEN )
break;
buf[i++] = c;
buf[i] = '\0';
(*s)++;
}
skip_space(s);
return buf;
}
/*======================================================*/
/* code generator sub procedures */
void ugl_bytecode_buildin_procedure(const char *name, int idx, int is_toplevel)
{
ugl_plog("BC %scall buildin '%s'", is_toplevel?"toplevel ":"", name);
if ( is_toplevel == 0 )
{
ugl_AddBytecode(BC_CMD_CALL_BUILDIN | ((idx&0x0f00)>>4));
ugl_AddBytecode(idx&0xff);
}
else
{
ugl_AddBytecode(BC_CMD_CALL_BUILDIN_POP_STACK | ((idx&0x0f00)>>4));
ugl_AddBytecode(idx&0xff);
}
}
void ugl_bytecode_call_procedure(const char *name, int is_toplevel, int arg_cnt)
{
uint16_t idx;
ugl_plog("BC call %sbytecode '%s' with %d arg(s)", is_toplevel?"toplevel ":"", name, arg_cnt);
idx = ugl_GetLabel(name);
ugl_AddBytecode(BC_CMD_CALL_PROCEDURE | (arg_cnt<<4));
ugl_AddBytecode(idx>>8);
ugl_AddBytecode(idx&0x0ff);
if ( is_toplevel != 0 )
{
ugl_AddBytecode(BC_CMD_POP_ARG_STACK ); // remove the return value from the stack
}
#ifdef NOTUSED
if ( is_toplevel != 0 )
{
arg_cnt++; // one more element on the stack (return value) has to be removed, if this is called from top level
}
while( arg_cnt > 16 )
{
ugl_AddBytecode(BC_CMD_POP_ARG_STACK | 0x0f0);
arg_cnt -= 16;
}
if ( arg_cnt > 0 )
{
arg_cnt--;
ugl_AddBytecode(BC_CMD_POP_ARG_STACK | (arg_cnt<<4));
}
#endif
}
void ugl_bytecode_reserve_arg_stack(int arg_cnt)
{
while( arg_cnt > 16 )
{
ugl_AddBytecode(BC_CMD_PUSH_ARG_STACK | 0x0f0);
arg_cnt -= 16;
}
if ( arg_cnt > 0 )
{
arg_cnt--;
ugl_AddBytecode(BC_CMD_PUSH_ARG_STACK | (arg_cnt<<4));
}
}
void ugl_bytecode_remove_arg_stack(int arg_cnt)
{
while( arg_cnt > 16 )
{
ugl_AddBytecode(BC_CMD_POP_ARG_STACK | 0x0f0);
arg_cnt -= 16;
}
if ( arg_cnt > 0 )
{
arg_cnt--;
ugl_AddBytecode(BC_CMD_POP_ARG_STACK | (arg_cnt<<4));
}
}
void ugl_bytecode_constant_value(long num)
{
ugl_plog("BC constant value %ld", num);
if ( num == 0 )
{
ugl_AddBytecode(BC_CMD_LOAD_0);
}
else if ( num == 1 )
{
ugl_AddBytecode(BC_CMD_LOAD_1);
}
else if ( num <= 0x0fff )
{
ugl_AddBytecode(BC_CMD_LOAD_12BIT | ((num&0x0f00)>>4));
ugl_AddBytecode(num&0xff);
}
else
{
ugl_AddBytecode(BC_CMD_LOAD_16BIT );
ugl_AddBytecode(num>>8);
ugl_AddBytecode(num&0x0ff);
}
}
void ugl_bytecode_return_from_procedure(void)
{
ugl_plog("BC return from procedure");
ugl_AddBytecode(BC_CMD_RETURN_FROM_PROCEDURE );
}
void ugl_bytecode_branch(const char *s)
{
int idx;
idx = ugl_GetLabel(s);
ugl_plog("BC branch, label %s, idx=%d", s, idx);
ugl_AddBytecode(BC_CMD_BRANCH | ((idx&0x0f00)>>4));
ugl_AddBytecode(idx&0xff);
}
void ugl_bytecode_jmp_no_zero(const char *s)
{
int idx;
idx = ugl_GetLabel(s);
ugl_plog("BC jump on not zero, label idx=%d", idx);
ugl_AddBytecode(BC_CMD_JUMP_NOT_ZERO );
ugl_AddBytecode(idx>>8);
ugl_AddBytecode(idx&0x0ff);
}
void ugl_bytecode_jmp_zero(const char *s)
{
int idx;
idx = ugl_GetLabel(s);
ugl_plog("BC jump on zero, label idx=%d", idx);
ugl_AddBytecode(BC_CMD_JUMP_ZERO );
ugl_AddBytecode(idx>>8);
ugl_AddBytecode(idx&0x0ff);
}
/*======================================================*/
int ugl_is_buildin_cmd(const char *name)
{
int i, cnt;
cnt = sizeof(ugl_buildin_cmd_list)/sizeof(*ugl_buildin_cmd_list);
for( i = 0; i < cnt; i++ )
{
if ( strcmp(ugl_buildin_cmd_list[i].name, name) == 0 )
return 1;
}
return 0;
}
void ugl_call_proc(const char *name, int is_toplevel, int arg_cnt)
{
int i, cnt;
int ii;
cnt = sizeof(ugl_buildin_cmd_list)/sizeof(*ugl_buildin_cmd_list);
ii = cnt;
for( i = 0; i < cnt; i++ )
{
if ( strcmp(ugl_buildin_cmd_list[i].name, name) == 0 )
ii = i;
if ( strcmp(ugl_buildin_cmd_list[i].name, name) == 0 && ugl_buildin_cmd_list[i].args == arg_cnt)
break;
}
if ( i < cnt )
{
ugl_bytecode_buildin_procedure(name, i, is_toplevel);
}
else
{
if ( ii != cnt )
{
ugl_err("Buildin procedure '%s' expects differnt number of args", name);
}
else
{
ugl_bytecode_call_procedure(name, is_toplevel, arg_cnt);
}
}
}
void ugl_parse_proc(const char **s, const char *id, int is_toplevel)
{
char procname[UGL_MAX_IDENTIFIER_LEN];
int arg_cnt = 0;
ugl_plog("parse procedure '%s'", id);
strcpy(procname, id);
if ( ugl_is_buildin_cmd(id) == 0 )
{
/* if this is a buildin cmd, then do nothing: buildin code takes care on the return value */
/* for custom procedures push a value on the arg stack for the return value, but do this only if this is not a toplevel procedure */
ugl_bytecode_constant_value(0); /* return value will be 0 by default */
}
if ( **s == '(' )
{
const char *name;
for(;;)
{
(*s)++;
skip_space(s);
if ( **s == ')' )
break;
if ( (**s >= '0' && **s <= '9') || **s == '$' || **s == '\'' )
{
ugl_bytecode_constant_value(get_num(s));
}
else
{
name = get_identifier(s);
ugl_parse_proc(s, name, 0);
}
arg_cnt++;
if ( **s != ',' )
break;
}
if ( **s != ')' )
ugl_err("missing ')'");
(*s)++;
skip_space(s);
ugl_call_proc(procname, is_toplevel, arg_cnt);
}
else
{
ugl_call_proc(procname, is_toplevel, 0);
}
}
uint16_t uglStartNamelessProc(int args)
{
ugl_current_local_variables = 0;
ugl_current_args = args;
if ( ugl_indent_level != 0 )
ugl_err("nested procedures not allowed");
ugl_IncIndent(UGL_INDENT_TYPE_PROC);
return ugl_bytecode_len;
}
int ugl_read_line(const char **s)
{
const char *id;
skip_space(s);
if ( **s == '\0' )
return 1;
id = get_identifier(s);
if ( strcmp(id, "proc") == 0 )
{
const char *name = get_identifier(s);
long args = get_num(s);
ugl_plog("start procedure '%s' (args=%ld)", name, args);
ugl_GetLabel(name); /* create a label for the procedure name */
ugl_SetLabelBytecodePos(name, uglStartNamelessProc(args)); /* and set the label for it */
}
else if ( strcmp(id, "endproc") == 0 )
{
//ugl_bytecode_remove_arg_stack(ugl_current_local_variables);
ugl_DecIndent(UGL_INDENT_TYPE_PROC);
ugl_bytecode_return_from_procedure();
ugl_current_local_variables = 0;
ugl_current_args = 0;
}
else if ( strcmp(id, "locals") == 0 )
{
long n = get_num(s);
if ( ugl_current_local_variables != 0 )
ugl_err("only one 'locals' command allowed");
if ( ugl_indent_level != 1 )
ugl_err("'locals': only toplevel call allowed"); /* it must not be inside loops or ifs */
ugl_current_local_variables = n;
ugl_bytecode_reserve_arg_stack(ugl_current_local_variables);
}
else if ( strcmp(id, "if" ) == 0 )
{
ugl_parse_proc(s, get_identifier(s), 0);
sprintf(ugl_indent_identifier[ugl_indent_level], ".if%d", ugl_bytecode_len); /* use the current bytecode position as unique identifier */
ugl_bytecode_jmp_zero(ugl_indent_identifier[ugl_indent_level]);
ugl_IncIndent(UGL_INDENT_TYPE_IF);
}
else if ( strcmp(id, "else" ) == 0 )
{
char s[UGL_MAX_IDENTIFIER_LEN+1];
sprintf(s, ".else%d", ugl_bytecode_len); /* use the current bytecode position as unique identifier */
ugl_bytecode_branch(s);
ugl_SetLabelBytecodePos(ugl_indent_identifier[ugl_indent_level-1], ugl_bytecode_len);
strcpy(ugl_indent_identifier[ugl_indent_level-1], s);
}
else if ( strcmp(id, "endif" ) == 0 )
{
ugl_DecIndent(UGL_INDENT_TYPE_IF);
ugl_SetLabelBytecodePos(ugl_indent_identifier[ugl_indent_level], ugl_bytecode_len);
}
else
{
ugl_parse_proc(s, id, 1);
}
return 1;
}
/* returns 0 if "endproc" is found */
int uglReadLine(const char **s)
{
ugl_read_line(s);
if ( ugl_indent_level == 0 )
return 0;
return 1;
}

View File

@@ -0,0 +1,16 @@
CFLAGS = -g -Wall -Wpointer-arith -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) main.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
mapgen: mapgen.c
$(CC) $(CFLAGS) $(LDFLAGS) mapgen.c -o mapgen
clean:
-rm $(OBJ) u8g2_sdl

View File

@@ -0,0 +1,108 @@
#
# gm.map
#
# Syntax:
# 'hash' introduces a comment
# tile <ascii> <mapto> <top> <right> <bottom> <left>
# map the <ascii> code to the specified <mapto> code, if the other for tiles match
# If one of the other four tiles is 0, then ignore this tile (wildcard)
# map <name> <width> <height>
# Create a map with the given name and size. this must be followed by :
# endmap
# Finish the current map
#
tile 32 32 # map space to space
tile '+ $80 0 '- '| 0
tile '+ $80 0 '- '+ 0
tile '+ $80 0 '+ '| 0
tile '+ $80 0 '+ '+ 0
tile '+ $81 0 0 '| '-
tile '+ $81 0 0 '+ '-
tile '+ $81 0 0 '| '+
tile '+ $81 0 0 '+ '+
tile '+ $82 '| '- 0 0
tile '+ $82 '+ '- 0 0
tile '+ $82 '| '+ 0 0
tile '+ $82 '+ '+ 0 0
tile '+ $83 '| 0 0 '-
tile '+ $83 '+ 0 0 '-
tile '+ $83 '| 0 0 '+
tile '+ $83 '+ 0 0 '+
tile '+ $84 '| '- '| 0
tile '+ $84 '+ '- '| 0
tile '+ $84 '| '+ '| 0
tile '+ $84 '+ '+ '| 0
tile '+ $84 '| '- '+ 0
tile '+ $84 '+ '- '+ 0
tile '+ $84 '| '+ '+ 0
tile '+ $84 '+ '+ '+ 0
tile '+ $85 '| 0 '| '-
tile '+ $85 '+ 0 '| '-
tile '+ $85 '| 0 '+ '-
tile '+ $85 '+ 0 '+ '-
tile '+ $85 '| 0 '| '+
tile '+ $85 '+ 0 '| '+
tile '+ $85 '| 0 '+ '+
tile '+ $85 '+ 0 '+ '+
tile '+ $86 0 '- '| '-
tile '+ $86 0 '+ '| '-
tile '+ $86 0 '- '+ '-
tile '+ $86 0 '+ '+ '-
tile '+ $86 0 '- '| '+
tile '+ $86 0 '+ '| '+
tile '+ $86 0 '- '+ '+
tile '+ $86 0 '+ '+ '+
tile '+ $87 '| '- 0 '-
tile '+ $87 '+ '- 0 '-
tile '+ $87 '| '+ 0 '-
tile '+ $87 '+ '+ 0 '-
tile '+ $87 '| '- 0 '+
tile '+ $87 '+ '- 0 '+
tile '+ $87 '| '+ 0 '+
tile '+ $87 '+ '+ 0 '+
tile '+ $88 '| '- '| '-
tile '+ $88 '+ '- '| '-
tile '+ $88 '| '+ '| '-
tile '+ $88 '+ '+ '| '-
tile '+ $88 '| '- '+ '-
tile '+ $88 '+ '- '+ '-
tile '+ $88 '| '+ '+ '-
tile '+ $88 '+ '+ '+ '-
tile '+ $88 '| '- '| '+
tile '+ $88 '+ '- '| '+
tile '+ $88 '| '+ '| '+
tile '+ $88 '+ '+ '| '+
tile '+ $88 '| '- '+ '+
tile '+ $88 '+ '- '+ '+
tile '+ $88 '| '+ '+ '+
tile '+ $88 '+ '+ '+ '+
tile '| $7e 0 0 '| 0
tile '| $7e 0 0 '+ 0
tile '| $7f 0 0 0 0
tile '- $7d 0 0 0 0
tile 'S $54
tile 'k $a0
map first 12 12
:+---+ +---+
:| | | |
:+-+ +--+ | |
: | +-+ |
: | | |
: | |
: +-+ -----+
: | Sk|
: +------+
endmap

View File

@@ -0,0 +1,936 @@
/*
golem master
event language
if cond then action
if obj in [equip, inventory, map] move to [hand, shoe, body, head, inventory, map]
cond:
1. part:
enter tile $01 (!BLOCKABLE, !MOVEABLE)
leave tile $02 (!BLOCKABLE, !MOVEABLE)
hit tile $03 (BLOCKABLE, MOVEABLE)
use tile (only for inventory) $04
2. AND part
flag is clear $01 $xx
flag is set $02 $xx
item part of inventory $03 $xx
item not part of inventory $04 $xx
action
set flag to zero $01 $xx
set flag to one $02 $xx
add item to inventory $03 $xx
delete item from inventory $04 $xx
create obj $06 <objnum>
remove obj $07 <objnum>
add curr obj to Y $1y y=0: gold, y=1:health, y=2: attack, y=3:defense
equip curr obj to z $2z z=0:right hand, z=1:left hand z=2:shoe, 4: body 5:head
message $0f <len>
object
obj base info $01 <objnum> <tile> <mode>
default position $02 <x> <y>
when equiped add X to Y $1y X y=2: attack, y=3:defense
for each action of the player,there is a procedure
enter tile on map
leave tile on map
hit tile on map
use tile from inventory to tile on map
equip tile from inventory
if cond cond cond ... then action action ... else action action action... endif
if $f0
then $f1
else $f2
endif $f3
condition
flag is set
flag is clear
target map obj is equal to <num>
action
*/
#include "u8g2.h"
#include <stdio.h>
#include <unistd.h>
const uint8_t scrollosprites[6642] U8G2_FONT_SECTION("scrollosprites") =
"\323\0\3\3\5\5\5\6\6\20\20\0\0\17\0\17\1\4\11U\31\331 \6\0@\30\6!$\316"
"\305\20>\60\16\211\243\320A\326\220,\16\220H\342\0ID<\31\217cs\330\60:\207\315\201r("
"\0\42$\316\305\20>,\16\212\243\320A\223\304\220(\16\212\305\1\21:$\34\245\203f\341\71l\16"
"\233\3\345P\0#\37\255\305\20>\240\16\70\213\344\0\221\34B\11\207\250\223\324\71h\16\232\203\346\240"
"\71L\16\4$\35\214I\21\236\65\34\213\320\42\21\233\304&\261\211(!\361D\226\24\11\306\222\243\66"
"\0%\32\314\311\20&\35`\16\206Eb;\200xx\30\22'\224!\35BG&\2&\27kI\21"
"\26E\26y\70XB\262\231p$,YD\304\362$\12'$\316\305\20\346A\30:\304\42\7Y\34"
"|\220\306\1\321\203T\365 \215\3\242\7\221D*\12\35d\207\31\0((\316\305\20N\344\20\211L"
"\16\221P\344\20I\307!\16\210\36\244q@\364 G\214\34\42\221\311!\22\212\34\42\351P\0)\35"
"\313\315\20>@\16\240\332H\242\241H\70\22U\16\223C\314J\7H.\222K\344\60*\34\316\305\20"
"\306C\34*\71X\16\226\203\345`\71<\324\21\336QBJ\241C\345p+%\356E\20\246Y-\16"
"\213\304DA\71($\225F\342\260HD,\221\331\346\60\363\341@\71TB\207PX\14,'\316\305"
"\20F\70\32\211\303\302uH\64\34\7\4c\304H(\30\15e\11\305d\301\70$\32\216\3\254qX"
"$\32\16-&\316\305\20>\60\35\22:\330\342\220`$\30\11\206\62\246\5c\301\244\214\221`$\30"
"\207\304\16\246\70$\30\7\2.*\316\305\20F\34\32\11Fb\321H:(\222\16\212d\7D\262\211"
"\42Y\204\307\220L\32\221D\304\63\71\340\30+E\342\320\0/&\316\305\20.\35\42\233\6c\211\321"
"P\60\32\211F\307\261\210\34\60\222\311\1\221\220\70\24\207\245C\242B\71\204\12\60\36\314I\20\236\365"
"\20<\4#\224\340!\250x\210Z\303\261\303Db\241Xd\42q\60\6\61)\317A\20\256\35r\210"
"\3\16q@\204\222z\10\5\225d\207\220\320$\11\205)\221\303Pb\13IlQ\221,%\30\212\0"
"\62*\317E\20\246\35r\10\5\17\241`\204\22\12\36BA\245\340!\24.\235e\222\310A\42\211\324"
"\42\222HY\42\222\203\202Q\0\63+\356I\20>\64h\32\35B\261C(\26\241\204b\207PL("
"\212\35BA\223,L:T$\23\251D\226\70\221\305\16\241\10\0\64(\356I\20\226\35d\7\34\302"
"\251\221\210$\61b\11\206H\321p\34`\7\204c\221\303\204bI\221X\244\42\71$\30\5\65*\16"
"J\20>L\16\225\32C\207\360!\24\213P\62\35B\61\241(v\10\5M\262\60\211d\221X%\42"
"\71D$\7\10\205\0\66%\315I\20\236\371\20=\204R(\241\320!\24\22\212B\207P\314$\12S"
"H\207\210Q\16\10\305l\241C(\0\67%\354I\20\316D\62;\304\221\16\61\11Et\30\261D\16"
"\221\230mBY\221L\224$\24\221D&\222\12E\0\70\25hQ\20\26\315\24\221\204Lj\224\304\203"
"$B$\206B\0\71\42\255I\20V\34*\36\35\206\207h\204\22=\204B\63Q$\62\21\316a\207"
"\350!*J\215\205\202\0:\34\314I\20\236\365\20\264\4#\306\71H\221\22\244X\224e\207\250\365\70"
"\223\303\202\0;#\316E\20\246\35p\10\37\302\22\345Cx\64\215Xb\343\311\341 \71DD\61Y"
"\360\60<L\205\62\0<,\356E\20\246\35\20\216\306!\301\70$\30\11F\202qH\60\16\11\306!"
"A\261\60b\211\305a\221P\70$\12\207J\42Z\204\22\3=$\316E\20\246\35p\210\36\206\22\212"
"\360\60\212\220(\21\211EL\207\10\245\207\231\304\42\265CDrP*\0>)\317A\20\256\35r\10"
"\37\304\22J\342A\24\211\220F\22\211MJ\223\304\202\244\320!\24:\310B\22[T$KJ\213\0"
"?+\317E\20\246\35r\10\305\16\223\230\204\42\211\35&)$JHbI\246]g\222\310A\42\211"
"\324\42\222HY\42\222\303Ba\0@+\357E\20>\70j\232\35B\261\303$&\241Hb\207I\12"
"\211\22\222X\222iBa\355\60\224LdQY\352D\26<\204\42\0A'\356I\20\226\35d\7\34"
"\302\251\221\210$\61b\11\206H\321p\34`\7\204c\221\303\204bI\264HErP\62\0B)\17"
"F\20>P\16\26\33c\207\360a\22\223P\62\35&)$JHbI\246\11\205\65\22Qb\7\251"
"\203\324!B!\0C%\316E\20\246\35p\210\36&!\11E\22:L$$JDbI\245)\226"
"\330$\266\70,\24\264\305\16\241\0D'\356E\20V$\42I=\304Q\17C\11Ev(\65I,"
"\42\21I\22\22\212B\303\231\304\42\265C\354\200C\14\0E\30\212M\20\216P\22\42\205\214\21I\320"
"(\222Rb\301X\204\314j\2F \253I\20^\70&\224\35D\207H\12%\205\62\211L\42*\246"
"\71\344\20;\304DiI!\0G#\316E\20\246\35p\210^\204\222ci\42\241\221$\42\71\210$"
"\24\16\17B\211\35b\207\210\344\240T\0H%\316E\20\246\35p\210\36F\221\211d\22\71\24G\323"
"\210%\66\236\34\16\222CD\24\223\5\17\303\303T(\3I.\360A\20\256\35\24\216\3\342\220h\34"
"\26\14\5C\241\71\214\22\207E\222\302\241\30\221\32\42E\343\260\244p(D\246\206DqPD\22\5"
"J\42\255E\20\246\371\20=D\17\321\220(z\10FD\222\220\304\205R\211\260E$\221\231$-$"
"\24\1K\36\314I\20\236\65T\34I#\243`)(\33\36\242F\261\344p\261P,\62\221\70\30\3"
"L\64\17F\20>\70\16\220FM\263C\34p\10\5C\242\304p(\70\32\205C\243\10%\244\42\11"
"GT\42\24\231$R\213HB\322\210$I\26\222\4c\21\0M&\354I\20\246\325\22;\4\303\261"
"\70$\24\42\245\210$\261\10%\32\14\256\204\224(\241\10%)\222\30\12\13E\0N\63\16F\20\206"
"\34*\264\305\16\241\220)\22:\204D\341X$\16\11EB\244\224\210H\22\22\31)\224\30\205\42\216"
"H\42\222\230$E\22\233\10C\207\30\0O+\356I\20\246\35`\7\34\302\251qH\60D\12FD"
"\222h\204\22\7\4\343\200\10%\26\71L(\226\24\211E*\222C\202Q\0P%\317E\20\246\35r"
"\10\37\246\22\212\360@,\21%\226\240\210\22\14\11\305\207PLR\223\216B\303\203\34`\4Q!\216"
"E\20\226P,\224\3\312\221\210\362A\26\7\214\242\227\340!\22\213\134\242\227\350%\30\241\210\0R\36"
"N\305\21V\34\22\13\5C\21\221\22I\251\42\222\34\36\42\222C\304B\11e\221C\3S \314\311"
"\20\16)j\12\36C\226X\250|\210\34D\7I\304\134\212EL\301cH\222\32\251\0T,\356E"
"\20V\210\24\214Xb!S\222)\26\42\205$!Qdr\230\304$\212\23\312$\24\22\205$\241,"
"\241\34\343\220h\70\33\0U'\356E\20\336\34V\7E\346\240h\34\22\222\243\304AtH\70\16\260"
"C\254\24\11\227\212X\42\12\207\42\311\221\10\0V\37\216E\20\356\371 =\10G\61\212\312\212J>"
"I\262EF\242\231\251R\212\215#I\26\0W%\356E\20> \16\252\3\346\260\203\345p:\324!"
"\346C\360 \214P\302\207p$\24\11\247\3\202q\20\25\0X)\356E\20\246X\30\11F\202\207\351"
"!\24\223h;D\244\64\311$\24\211\34E\207\322\241\64\222Md\341H\60\16\11\306\1Y-\356E"
"\20\246X\30\261\4\17\223X\204\222x\210\204\210\222\310D$\212\220D\241\12%d\24\35\42#\311l"
"$\21\216B\62RH\26IZ&\356E\20\226\304\42\212\34\42\261\303\354P\232PF\207Jd\70Y"
"\232\224H\347\203\360\360P\241,\221$\243H\2[(\357E\20\266$\16\272\3&\325\303\324$\225\314"
"A\242Ix\224\26\42\311b\345\330\241h\207D\330&\223\234\242\221\24\0\134,\357E\20Fd\42\11"
"\305$\7\351\304xI\264C\326\202#J\220\24\13EJ\243\220\71t\60\35\342\240\12MB\311\42\211"
"FR\0]*\15J\20f(\16\241C&r\300!x\20N\306Ca\35r\20\36\42\241\203D\22"
"\271Hb!\321,\65\24\213CbA\0^+\356E\20>,\216\42\207\312\16Q[\354\20\13\35b"
"\241H\61\24\7\204\222\304\241\210\34\20\212\206\42\241\70,T\216\320$\241\0_*\356E\20N\34\22"
"\15\247\312\42qXDH\212\310L\243\342\210B\31I\316\244\10K\344\62\221\204(\321Hd$\212h"
"\231\0`*\356E\20\246\371\60;\224\206\225\221\350\20\11E\16\221P\344\20\11E\16!\321Ah\71"
"\224H\262\230\34\64\213\210$*\23\2a \216E\20\256\35`\211\36\302Bq$\24\11\247F\202\221"
"\330\204\62\42R$\207\210L(N\3b-\356E\20n\60\16\20\305A!\71\220\16\261\3&\21i"
"$e\32\7\10#\261\210\60\16\220\206\203\222`D\222R\212\10kqX\14\0c(\316E\20\346$"
"\62\215\3\344PY\60&\207\226&\222\310!\42\211\34\42\21\311!B\71D(\207\10\35\61\34\25\213"
"\0d(\356E\20> \216\315\16\70Dd\21JDv\10\305\302\241\210\34\42\11\35b\241CLr"
"\210I\16q\14\321\260p\4e!\356E\20\246\35b\207\330a\342\211\213H\342K\311\64\12\207&\207"
"\10\345\20\221\35\302B\351p\4f\22\20B\20\206\344\377RG\262\374\377%\216$\371Rg\32\20B"
"\20\206\344\377RG\222L.+\227\225\313\34<\331\377\22G\222|)h\33\20B\20\206\344\377RG"
"\262\203N\226\223\345d\71YN\226\223%\216$\371Ri-\20B\20\206($\241\210E\242\70\262H"
"\34\32\251\312\1r\320\70Z\34E*\241a\35:\7\211e\21\222DJ\222\203\304\62\71\204\4j-"
"\20B\20\206($\241\210E\242\330\34Z\224Ej\304\32u*\13VG\307\311!\16\71D\244\207\310"
"$t\10\11\357\260\222L\16!\1k-\20B\20\206\244D\221\134(\221\203\355 \21\36dB\243d"
"B\232\215+\223\226\320\205v\220\10\17\63\311a\64:\210\204\27\231\34B\2l'\20B\20\306\303\34"
"Ar\250H\16\25u\210v\210\246\212\246\212\246\212\246\212\246\212v\210\312\241\42\71T\344\10\17\3m"
":\20B\20\306\303\34Ar\250H\342\260\210$\16\213Hb\221\244\210$\24\311E\22\213$E$\241"
"H.\222X$)\42\11Er\221\304\42I\21I\34\26\221\34*r\204\207\1n'\20B\20\306\303"
"\34Ar\250\210\16#\331!&\64J\251b]CQa\242,\34\23\305!!I\34\26\221#<\14"
"o\61\20B\20\306\303\34Ar\250H\306\23\311\322D\62I\232H&I\23\311$i\42\231$M$"
"\223\244\211di\42\31O$\343\211\344P\221#<\14p!\316\305\20\306C\34*\207\312\241rP\35"
"T\7\25)EJ\221r\210P\16\21\312!B\71\34\10q#\356\305\20>\214\16\243\303\250\24*\205"
"J\71D(\207\10\345\20!V\210uP\35$\207\312\241\207C\0r%\316\305\20^\204\22\234P&"
",\207\10\345\20\241\34\42\224C\204R:P\344\300P\204r\210P\16\21v\204\7s\15\304\355\20\216"
"\344P\341\213$)\30t&\354I\20V\60\16\11\311\1\242\60\35b\225D\206\223Lr@H,\211"
"\34\42r\330\301r\230\304a\221\303\4\0u)\320\301\20\346!\16\210C\242Aa,\30\12F\204\254"
"R:\264\16\243\310!\222\311a\242r\210\310\344\20\351a\16\70\4\1v\24\212M\21\226\355\20\71\30"
"\17\207\360\341\17\22IE$\11w\31\316\305\20\266\370\360A\16;\34\352\220\303\37\346\310r\250\34*"
"\207\212\1x\17\350P\22\216\345p\220\330a\42\211P\0y\22\216E\21\306\377\357\10\17\221IJ\313"
"\245r\207\6z$\356E\20\306?\304\241\222t\210$Ez\70\310\241\22I\312D%er\70\310\241"
"\22J\26\11%\313\341\20{\32\316\305\20\316\241r\370\377r\250\304\241\221C\35I\16\21\311!\42\71"
"D\2|\32\314\311\20\236Mb\241X\346\260\310ar\370\203\35z\250C\345\20:D\0}\26\220A"
"\21\306\377\37\352h\221|\221\344\247H\276H\362S$?~\12\10R\20\306\377\377\203\0\23\310Q"
"\21\306\377!\16\212\244H\62ER$\231\42\31\200\32\314Q\20\306\377\207\341!\22\71\210\42\207H\344"
" \212\34\42\221\203\360\20\4\201\33\314A\20\306\377\203\360\20\11\35$\221C$t\220D\16\221\320!"
"x\10\36\2\202\31\314Q\21\306!x\10\36\376\17rp$\27I\236\42\271H\362\24\311\3\203\27\314"
"A\21\346!x\370\230\203#\271H\362\24\311E\222\247H\36\204\37\14R\20\306!x\10\36\376\37"
"\206\207H\344 \212\34\42\221\203(r\210D\16\302C\20\0\205\36\14B\20\346!x\370\30\36\42"
"\241\203$r\210\204\16\222\310!\22:\4\17\301C\0\206\42\320A\20\306\377\37\212\207h\350\20\211H"
"\42\207P\322!\22\221D\16\241\244C$\361\20\207\34\202\0\207\33\320A\21\346!\16\71\4\17\377?"
"\324\321\42\371\42\311O\221|\221\344\247H~\210'\20B\20\346!\16\71\4\17\377?\24\17\321\320!"
"\22\221D\16\241\244C$\42\211\34BI\207H\342!\16\71\4\1\211\13g\320\23V\70\22\221\205\0"
"\212\16\307\320\22\246,\62\235CD!\31\0\213\16\246T\23\226(\42\31IB\61\21\0\214 \316\305"
"\20.\35r\210\36f\207\322\241r\370P\254LB\221\241D\35$\207\312\241r \25\0\215\32\314\311"
"\20\256\34D\7\330\21\255\207\330a\216r\210\35&\207:\232\34&\5\216\42\256\305\20^$\24\211\3"
"\202\341\341\70\30\7\245RB\21J\310\24\246\3\345P\71T\16\225\3\251\0\217\24\214I\21\226\22I"
"\35\257\42\21I\35\257\42\21I\11\0\220!\316\305\20\246\35p\10\37\204\207!\35\66\61J\16\341C"
"Lr\220P\16\227\203\205t\231H\214\4\221\23\212\315\20\36\325v\10\35\42\207\323\321\213dF\65\1"
"\222\36\214\311\20\256(\34\212D#\212\21J,bI\71D\42\207Q\376\64\221L\351\0\33\0\223\35"
"\214\311\20FD\313\341\201\16>\214\42\226PD$\11\15G\303\321D\62\245\3l\0\224\34\216\305\20"
"\306;\70\26\7\305\342\240\70\370p\210\261M\326\230#\351\240X\34\66\4\225#\256E\21n$\16\225"
"\3\347\60:@B\11\212H\261\330\60\24\23\317\302\22alb)\35\210\7!\0\226 \314\305\20>"
"$\16\224\4Ct\10\35`\12\215\204\243a\214\32\241Z\345 \71H\16\222\303\0\227!\256E\21."
"\35\26\212\203\42\222\70@(\214\34\42Q;\242\310$\264C\254\221\10%Q\35`\4\230$\316\305\20"
">L\16\215\304\201\241\70\250\16\231\303\346\200\320\34\60\221\3\350\240;\340\20\276\3\354\220:\10\0\231"
"#\316\305\20^\35J\221\203\352\260\71t\16\21\311\1\63\351P\70\216\315\1\241\71$\62\207\315\201r"
"(\0\232#\314\305\20>\200\16\10J\203\221`J\64\224J\212\12c\21R:$\224\227`H\24\14"
"\7\343\0\12\0\233\37\254I\21>D\16J\226\305!\241X-D\212\235b\246Xd\226\16\210\305\1"
"\301h\270\12\234\30-\305\21\316!\42\71DN\23Z\34D\231\234&\207\312\241r\250\20\235#n\305"
"\21\346$\62\215\3\204q\200\60\16\20\306\1\245\11\345\20\241\34\42\224C\204r\210P\16\21\12\0\236"
"#\316\305\20\246\35\20N\22E\305\62\211EB>\34(\207J\344\60\221\331\42\311\221\20EB;\214"
"\215\0\237 \216\305\20\356\34\32\31\206B\264\71H(\26E$\61:\350\30:\204(\242QUr\7"
"\24\1\240\27\14I\22\316\34R\7\304\342\200\330Av\220\5\17\301Hd\16\1\241\30\15E\22\246\34"
"\26\212\3F\341\320\201t\230\214b\263P,\22\224\3\242\27k\311\20^U&\214M\253i\222\10e"
"\22\71\204\16\17\246\33\0\243\37\256\305\20^\35r\7\330A\224Z\360\66\271C\352\220h\34R\252D"
"\17\221\312\35R\207\0\244\26J\315\21\226\315\22\71D,\22\312h\351&\21\245\204c&\0\245\27J"
"\315\21\246-R\212PRH\22\232d(\21F\302\241h\314\10\246\27J\315\21\226-\62\212DJ\222"
"\222\244$)\211frHr\314\4\247\30\214I\21n\371,\22\213\244\21\362XQ$\207\310!\42\331"
"\270\16\21\250\17\314\310\22>\214\16\71\230\16v\10\35\6\251\27k\311\21V\365v\20\225D\224\210\210"
"\62\211\20\17\17\224\303\354\2\252\30K\311\21\216QV\21\306h\242\310\201\26I\241C(Y\16\224\303"
"\0\253$\316\305\20>L\16\245\303\350 \71P\16\242C(\322\211\34\20!EMQ\211(L\213\3"
"dq\20\35\2\254#\316\305\20\16\35\24\224\3\302\322\70D\26\207\205b\323H,\24\25N\345\320\71"
"\354\360Ar\250\35F\0\255%\316\305\20>\70\16\231\304!u\350x&-\311!\223\340LZ\22\306"
"&\321\240\34\24\222CbqHH\16\2\256\37\216\305\20>L,\222\10%\25Y\304\32\261\36\244\7"
"aez\220\306(\62\321DJ\7\1\257\37\254\311\20&\371\20\223\225\42\42\212\322uB\233D\16\25"
"\313\350\24;D\202\222X\34\26\1\260&\316\305\20.\35&\221C\354\200\203\220b\212X\16\222\203\344"
"\20\23\31#!Ih\26\22\305\1\301\70(\35(\7\261\27\212M\21\36\325v\10Z&\241\313Ar"
"\230\34$\207\313!f\2\262\31L\311\21\336\34\62\221\36D\207\213\354 ;\310&\241C$t\70\214"
"\4\263\26\212M\21\226\34\62\207\210%\25\222\371\360\201r\10\35b&\0\264\31\256E\21>@\16\224"
"C\345 \241pBY\361\277L$\26\251\35D\5\265\42\314\311\20fl$\221\214F\21I\204|\70"
"D*\7\213\344\60\233\220\351 \71H\22\207d\7E\1\266\33n\305\21>\70\16\230\210)b\312\224"
"B\235P\17\322C\364\20\266\3\352 \0\267\37\314\311\20\356\34R\224T$\323\221TZ\207\314\61\204"
"e\341I\34\42\211\303\342\300\70\4\0\270\27kI\21\336\351\360\60\246\211$\222\211t\16\231\3\350\0"
":D\12\271\42\315\305\20>H\16\234\3$T\312\320|\10^\202\21R\60$\213\3c\323 -<"
"\221C\344 \0\272$\314\311\20> \16\222\203\310\207\330D\222\242t\270H&\222I\344\20I\207\204"
"&I\241IRL\222\325\6\273(\316\305\20F\34\355|\20\36&\241\303\360@<DD\61Y$\64"
"\13EB\223\244Hh\222$\233$\205$\322\240\304\10\274\32\214\311\20\236U\250\355\60\221X\312\207\7"
"\313a\22\71D\322!\261C\10\0\275#\316\305\20.\35\244\16\261N(\223\242\351\20\22\35B\223C"
"Dr\250\35\246\207\70\204\16\12\306AT\0\276\22h\321\20\26M$\262\321\202\221!\307H\60F\2"
"\277\35\254\311\20&\35 \22\333\1t@\60:\214\215#t\0\35B\207\314A\21\261\320\6\300\32\314"
"\311\20&\35 \22\33%\24I\34F\207\230\257_#\65\241H\16\221\2\301\27J\315\21>D\246\66"
"\211\3\304\22!E\64\211H&QIx\16\302&\316\305\20>\214\16\252C(q\0)L\12\223\302"
"\244\240d\24\225\210\342\0\311\34$\7F\346\0\231\34 \207\2\303 \216E\21>,\16\215\304a\351"
"\220\240\34\20\233FBSId*\242\312\246B\251\34*\207\2\304$\316\305\20\366!l\211\3Hq"
"\210,\16\212\305\1\241\344Q$:\24\316as\330\34\66\207\315\201r(\0\305 \316\305\20>T\16"
"\234\303\346\260\71P\16\213C\347\260\71P\16\213C\347\260\71l\16\224C\1\306\27\214I\21v\371z"
",\5i\61\232l\64\273\226\351\200\71H\16\3\307 \316\305\20>@\16\14E\304\301i\70u\34+"
"G\354\0\253\210:\223\316as\330\34(\207\2\310\35\214I\21\326!v\230\34D\7\231\271\42\254\10"
"\353\0:d\16\212\304!\261C\10\0\311\27\314\311\20\206\34b<\230\256\257\25aEh\276\276Fj"
"B\33\0\312&\316\305\20\206\34v\230FI\261\340$\32\214\304\1\301\210\70\24\241\3b\343\250\64\24"
"\314\26\207\205\342\300\210\34*\313(\316\305\20>H\42\207\205\342\220P\34\224\42\16\305\242\241\344P\252"
"(U\42\212J&q\310$\16\213\310\201rh\34\4\314\23J\315\21\226\355\20\71|\20\12c\352\220"
"\261D(\1\315\27L\311\21\326!v\30\35F\207\321a\24\207\204\342\220\20/D\2\316\31N\305\21"
">L\16\233\304!\224\70\240\16\261\3\316\207\70\200L$\23\5\317&\316\305\20>(\22\7F\322A"
"\221\244H(bI:D\322\202\226\20\345\61d\241\5o\24;$\30\7\321A\0\320%\216E\21>"
"(\42\7M\344\20\311$\42\233TD\222\312hR\21\5'\243 EF\11\306!\301\70\210\16\2\321"
"\27N\305\21N\251;\32\211H\42\213\244\223Pdb:\224\16\304\2\322\32LI\22\6EB\207F"
"\16\21\311!\22\71L\210\207\340!x\10\36\202\4\323\30\356D\22\316\241\22\207V(\207H(r\210"
"H\42\224I(\62\246\2\324\33nE\21\236P*\241\310\306\223\342\201t(\331Fs\200\35\20\216\222"
"\210K\0\325\31L\311\21\6\361\20\221\34\202\224\341l\64\213\311B\207\321a\216r\10\1\326\32l\311"
"\21&\35\20\214\21/\241\310Er\20\35\16\23\22Y|\230\35B\0\327\37\314\311\20\246\325z\10\206"
"cqH(\16\11\305!\261p\64\30\234H&\304C\360\134\207\10\330\30kM\21\316\32\205D\251L"
"d\252e:\200\16\210\210c\302h\15\0\331\37\254\311\20\216X\22\62\311ar\330\34\242B\21\216\242"
"\245`)X\12Fd\321`\34@\4\332\20\214H\23FP\70\42M\222\42)\207\11\0\333\21\256\304"
"\22\316\341\60\233\211b\263,\261\340l\2\334\33\216E\21\246YM\16Q\233\204HJ$%\222\22I"
"\211\66!\311\301\312F\0\335\32\214I\21\256\34D\7X\17\261\303\344P\244C\350\20:\204\16\241C"
"\210\0\336\26kI\21\326Av\10^\215\267C\250\62\251]#sP\34\2\337\15J\315\21\36\231\355"
"\360C\215\314\6\340\22J\315\21\206\270\70\31\315\254d\252m\64\31\226\5\341\23L\311\21\16\211r\370"
"\203\345\60;D\355\0:H\12\342\35\256E\21\266\34*\7\322a\324\303\345P;L\17\321\303\360\60"
"+\225\306\23\71L\0\343%\316\305\20\266\34 \207\210B\246\340!z\30\36F\221\303Dr\230\204\16"
"\303\303\364\20\14\231Br\210\34 \6\344\21\212M\21N\361\20\265\226\253\35\213\226C\254\10\345 \316"
"\305\20.\35r\210\36fD\322x\62\223\231H&\222M\66\31\217\210\264\303\364\20\207P\1\346\35\256"
"E\21\266\34H\207\321Av\210H\16\30\215GS\22\221D;\224ZL\207\203\1\347\35\253I\21>"
"H\16\240\332\16\261Rl\30\13\307b\222X\314\22;\4%t\210\34\2\350%\316\305\20v\34\24\23"
"\5E\24\231\350\20\12\35\204\7\312\341@\222\234b\22J\34`\7I\344\240\230Xl\4\351#\256\305"
"\20VT\30I\223\316a\221\344`\70\222\16\233\303\42\351\300\70$\16\214\244\303\346\260H:\60\16\352"
"\35\312\315\20\246\34\20\12\207\242\243\340(V\12\225\42\266\233d(\207\310!\311\61\23\0\353\23\252\315"
"\20\336\315\261\365p\240\222\327\1r\200\34\22\7\354!\316\305\20.\35r\210\36fD\322x\62\223\231"
"\222L\21\221IF\221\235f\305\71t\16\236\4\1\355$\316\305\20>\240\16\71\37\244\7i\244\22\215"
"\3\42\243h\244T\232\304A\261\70l&\7\322a\241\70P\12\356\36\316\305\20\366!|\210\303\346\260"
"Qm\34\33\307\16\221\340\301\216\3\35\32\207\306\241T\0\357\33\312\315\20\226\355\20\71<\204D\63m"
"\221\321\220\30\221$\205C\22\65+\15\0\360 \316\305\20\306\34r>\10+\245\332\250\32\252C\352\220"
":\244\24\64\221\332\206\263\210P\222\16\15\361$\314\311\20\316a\22\207I\250\22\252\204*\241J\250\22"
"\252\204\32\211\14c\21Y\64\22\212\3Bq\220\24\0\362\35\312\315\20\306\203%\34\12\207\302\261`\64"
"\24\16E\203\261\220(\205\22:D\16\7\3\0\0\0";
/*
maze_Redraw()
maze_SetData()
maze->px upper left corner (pixel pos)
maze->py
maze_SetPixelPos()
maze_GetTile(tx, ty)
gm_SetTilePos(tx, ty)
gm_GetCurrTile()
gm_GetNeighborTile(dir) dir=0,1,2,3
gm->state
gm->tx, ty
gm->walk_dir
gm->px_delta, py_delta
*/
struct v16_struct
{
uint16_t v[2];
};
typedef struct v16_struct v16_t;
/*=================================================*/
struct map_struct
{
/* input: upper left corner of the visible area in the map */
/* visible window position in pixel coordinates (vwpp) */
v16_t vwpp;
/* input: dimensions of the visible window (pixel) */
uint8_t pdw;
uint8_t pdh;
/* input: offset for the visible window on the display from the upper left display corner */
v16_t vis_win_disp_pos_pix;
/* upper left visible tile of the visible window, derived from vwpp.v[0], vwpp.v[1] */
/* visible window position in tile coordinats (vwpt) */
v16_t vwpt;
/* visible area in tiles, derived from pdw/pdh */
uint8_t tmw;
uint8_t tmh;
/* offset from the upper left tile corner to vwpp.v[0]/vwpp.v[1] */
v16_t dtwp;
};
typedef struct map_struct map_t;
/*=================================================*/
struct gm_struct
{
/* tile position of golem master (upper left corner) */
v16_t pt;
uint8_t state;
uint8_t dir; /* for GM_STATE_READY_FOR_WALK */
/* target offset of the visible window in map pixel */
v16_t twop;
/* this is the current offset, which follows the target offset */
v16_t cwop; /* current window offset in pixel */
/* golem master offset pixel */
v16_t gmop;
};
typedef struct gm_struct gm_t;
#define GM_STATE_CENTER 0
#define GM_STATE_READY_FOR_WALK 1
#define GM_OFFSET (0x040)
/*=================================================*/
struct obj_struct
{
v16_t pos_t; /* tile position of the object */
v16_t offset_p; /* pixel offset of the object, used for animation, this will decrease to 0 */
uint8_t tile; /* glyph index, shape of the tile, 0 means empty */
uint8_t health; /* current health of the object */
uint8_t attack; /* attack value of the object, 0 if it does not attack */
uint8_t defense;
uint8_t mode;
};
typedef struct obj_struct obj_t;
#define OBJ_MODE_INIT_AT_MAPSTARTUP 1
#define OBJ_MODE_ATTACK_PLAYER 2
#define OBJ_MODE_ATTACK_MONSTER 4
#define OBJ_MODE_MOVABLE 8
#define OBJ_MODE_BLOCKABLE 16
/*=================================================*/
#define OBJ_LIST_MAX 16
obj_t obj_list[OBJ_LIST_MAX];
uint8_t obj_cnt = 0;
void obj_list_Init(void)
{
uint8_t i;
for( i = 0; i < OBJ_LIST_MAX; i++ )
obj_list[i].tile = 0; /* mark as empty */
}
/* 255 means "not found" */
uint8_t obj_list_GetEmpty(void)
{
uint8_t i;
for( i = 0; i < OBJ_LIST_MAX; i++ )
if ( obj_list[i].tile == 0 )
return i;
return 255;
}
/*=================================================*/
void v16_SetByConstant(v16_t *v, uint16_t x, uint16_t y )
{
v->v[0] = x;
v->v[1] = y;
}
void v16_SetByV16(v16_t *v, v16_t *w )
{
v->v[0] = w->v[0];
v->v[1] = w->v[1];
}
void v16_RightShift(v16_t *v, uint8_t s )
{
v->v[0]>>=s;
v->v[1]>>=s;
}
void v16_LeftShift(v16_t *v, uint8_t s )
{
v->v[0]<<=s;
v->v[1]<<=s;
}
void v16_Add(v16_t *v, v16_t *w )
{
v->v[0]+=w->v[0];
v->v[1]+=w->v[1];
}
void v16_AddConstant(v16_t *v, uint16_t c )
{
v->v[0]+=c;
v->v[1]+=c;
}
void v16_SubConstant(v16_t *v, uint16_t c )
{
v->v[0]-=c;
v->v[1]-=c;
}
void v16_Sub(v16_t *v, v16_t *w )
{
v->v[0]-=w->v[0];
v->v[1]-=w->v[1];
}
void v16_SetByConstantByOneConstant(v16_t *v, uint16_t w)
{
v->v[0] = w;
v->v[1] = w;
}
void v16_AverageByConstant(v16_t *v, uint16_t x, uint16_t y)
{
v->v[0] = (v->v[0] + x + 1)/2;
v->v[1] = (v->v[1] + y +1)/2;
}
void v16_AverageByV16(v16_t *v, v16_t *vv)
{
v->v[0] = (v->v[0] + vv->v[0] + 1)/2;
v->v[1] = (v->v[1] + vv->v[1] +1)/2;
}
void v16_AddDir(v16_t *v, uint8_t dir, uint16_t w)
{
switch(dir)
{
case 0:
v->v[0] += w;
break;
case 1:
v->v[1] += w;
break;
case 2:
v->v[0] -= w;
break;
case 3:
v->v[1] -= w;
break;
}
}
/*=================================================*/
void map_Init(map_t *m)
{
/* constants */
m->pdw = 128;
m->pdh = 64;
m->vis_win_disp_pos_pix.v[0] = 0;
m->vis_win_disp_pos_pix.v[1] = 0;
/* the visible area in tiles is a little bit bigger than the pixel size of the area in pixel */
m->tmw = (m->pdw + 15)/16 + 1;
m->tmh = (m->pdh + 15)/16 + 1;
}
/* set the position of the visible window in the map */
void map_SetWindowPos(map_t *m, v16_t *newpos)
{
v16_t v;
v16_SetByV16(&(m->vwpp), newpos );
v16_SetByV16(&(m->vwpt), newpos );
v16_RightShift(&(m->vwpt), 4);
v16_SetByV16(&v, &(m->vwpt));
v16_LeftShift(&v, 4);
v16_SetByV16(&(m->dtwp), &(m->vwpp));
v16_Sub(&(m->dtwp), &v);
//printf("vwpp.v[0]=%u vwpt.v[0]=%u delta-x=%u tmw=%u\n", m->vwpp.v[0], m->vwpt.v[0], m->dtwp.v[0], m->tmw);
//printf("vwpp.v[1]=%u vwpt.v[1]=%u delta-y=%u tmh=%u\n", m->vwpp.v[1], m->vwpt.v[1], m->dtwp.v[1], m->tmh);
}
uint8_t map_GetTile(map_t *m, uint16_t tx, uint16_t ty)
{
/*
static uint8_t map[12][12+1] =
{
"\x80\x7d\x7d\x7d\x7d\x7d\x7d\x7d\x7d\x7d\x7d\x81",
"\x7e\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x7e",
"\x7e\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x7e",
"\x7e\x20\x43\x20\x20\x20\x20\x20\x20\x4e\x20\x7e",
"\x7e\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x7e",
"\x7e\x20\x20\x20\x20\x20\x45\x20\x20\x20\x20\x7e",
"\x7e\x20\x20\x20\x20\x20\x20\x20\x20\x20\x93\x7e",
"\x7e\x20\x20\x20\x20\x20\x20\xa0\x20\x20\x20\x7e",
"\x7e\x20\x50\x20\x20\x20\x20\x20\x20\x20\x20\x7e",
"\x7e\x20\x20\x20\x91\x20\x20\x20\x20\x92\x20\x7e",
"\x7e\x54\x20\x20\x20\x20\x20\x20\x20\x20\x20\x7e",
"\x82\x7d\x7d\x7d\x7d\x7d\x7d\x7d\x7d\x7d\x7d\x83"
};
*/
static uint8_t map[12][12+1] =
{
"\x80\x7d\x7d\x7d\x81\x20\x20\x80\x7d\x7d\x7d\x81",
"\x7e\x20\x20\x20\x7e\x20\x20\x7e\x20\x20\x20\x7e",
"\x82\x7d\x81\x20\x82\x7d\x7d\x85\x20\x7e\x20\x7e",
"\x20\x20\x7e\x20\x20\x20\x20\x84\x7d\x83\x20\x7e",
"\x20\x20\x7e\x20\x20\x20\x20\x7f\x20\x20\x20\x7e",
"\x20\x20\x7e\x20\x20\x20\x20\x20\x20\x20\x20\x7e",
"\x20\x20\x82\x7d\x81\x20\x7d\x7d\x7d\x7d\x7d\x85",
"\x20\x20\x20\x20\x7e\x20\x20\x20\x20\x54\xa0\x7e",
"\x20\x20\x20\x20\x82\x7d\x7d\x7d\x7d\x7d\x7d\x83",
"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20",
"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20",
"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
};
/* pixel dimensions are 2^16 * 2^16, this means tile dimension is 4096x4096 */
/* as a consequence, wrap around at 4096 */
/* am not sure to do this here, maybe it should be done outside this proc */
tx &= 0x0fff;
ty &= 0x0fff;
if ( tx > 12 )
return 32;
if ( ty > 12 )
return 32;
return map[ty][tx];
}
/* check whether the target object is occupied */
int map_IsOccupied(map_t *m, v16_t *pos_t)
{
uint8_t tile;
tile = map_GetTile(m, pos_t->v[0], pos_t->v[1]);
if ( tile == 32 )
return 0;
return 1;
}
/* check whether tile in direction dir is occpied */
int map_isOccupiedInDir(map_t *m, v16_t *pos_t, uint8_t dir)
{
v16_t tmp;
v16_SetByV16(&tmp, pos_t);
v16_AddDir(&tmp, dir, 1);
return map_IsOccupied(m, &tmp);
}
/* for a position on the map (tile coordinates) return pixel pos on display */
void map_GetDisplayPosByTileMapPos(map_t *m, v16_t *dest_pos_pix, v16_t *src_tile_pos)
{
v16_SetByV16(dest_pos_pix, src_tile_pos );
v16_Sub(dest_pos_pix, &(m->vwpt)); /* upper left tile corner of the visible area */
v16_LeftShift(dest_pos_pix, 4); /* convert to pixel */
v16_Sub(dest_pos_pix, &(m->dtwp)); /* add the offset of the upper left tile corner */
v16_Add(dest_pos_pix, &(m->vis_win_disp_pos_pix)); /* add display offset */
}
/*x,y: tile position */
uint8_t map_IsTileVisible(map_t *m, uint16_t x, uint16_t y)
{
uint16_t ux, uy;
/* calculate the lower left corner (ux/uy) of the visible window in tiles */
ux = m->vwpt.v[0]+m->tmw;
ux &=0x0fff; /* wrap around mask for tiles */
uy = m->vwpt.v[1]+m->tmh;
uy &=0x0fff; /* wrap around mask for tiles */
if ( m->vwpt.v[0] < ux )
{
if ( x < m->vwpt.v[0] )
return 0;
if ( x >= ux )
return 0;
}
else
{
if ( x < ux && x >= m->vwpt.v[0] )
return 0;
}
if ( m->vwpt.v[1] < uy )
{
if ( y < m->vwpt.v[1] )
return 0;
if ( y >= uy )
return 0;
}
else
{
if ( y < uy && y >= m->vwpt.v[1] )
return 0;
}
return 1;
}
void map_Draw(map_t *m, u8g2_t *u8g2)
{
uint16_t tx;
uint16_t ty;
u8g2_uint_t px, ppx;
u8g2_uint_t py;
/* offset for the visible window on the display from the upper left display corner */
px = m->vis_win_disp_pos_pix.v[0];
px -= m->dtwp.v[0];
py = m->vis_win_disp_pos_pix.v[1];
py -= m->dtwp.v[1];
for( ty = 0; ty < m->tmh; ty++ )
{
ppx = px;
for( tx = 0; tx < m->tmw; tx++ )
{
/* py+16 is there because reference point for the tiles is lower left (baseline) */
u8g2_DrawGlyph(u8g2, ppx, py+16, map_GetTile(m, tx+m->vwpt.v[0], ty+m->vwpt.v[1]));
ppx += 16;
}
py += 16;
}
}
/*=================================================*/
void gm_Init(gm_t *gm)
{
gm->pt.v[0] = 1;
gm->pt.v[1] = 1;
gm->state = GM_STATE_CENTER;
gm->dir = 0;
v16_SetByConstantByOneConstant(&(gm->twop), GM_OFFSET);
v16_SetByConstantByOneConstant(&(gm->cwop), GM_OFFSET);
v16_SetByConstantByOneConstant(&(gm->gmop), GM_OFFSET);
}
void gm_SetWindowPosByGolemMasterPos(gm_t *gm, map_t *map)
{
v16_t v, w;
v16_SetByV16(&v, &(gm->pt));
v16_LeftShift(&v, 4);
//v16_SetByV16(&w, &(map->pdw));
w.v[0] = map->pdw;
w.v[1] = map->pdh;
v16_RightShift(&w, 1);
v16_Sub(&v, &w);
v16_AddConstant(&v, 8); /* adjust half tile to center exaktly */
v16_Add(&v, &(gm->cwop));
v16_SubConstant(&v, GM_OFFSET);
map_SetWindowPos(map, &v);
}
void gm_Draw(gm_t *gm, map_t *map, u8g2_t *u8g2)
{
v16_t dest_pos_pix;
map_GetDisplayPosByTileMapPos(map, &dest_pos_pix, &(gm->pt));
v16_Add(&dest_pos_pix, &(gm->gmop) );
v16_SubConstant(&dest_pos_pix, GM_OFFSET);
if ( map_IsTileVisible(map, gm->pt.v[0], gm->pt.v[1]) )
{
// puts("visible!");
u8g2_DrawGlyph(u8g2,
dest_pos_pix.v[0],
dest_pos_pix.v[1]+16,
0x4e);
}
else
{
// puts("not visible");
}
}
/* returns 1 if gm made a step */
int8_t gm_Walk(gm_t *gm, map_t *map, uint8_t dir)
{
uint8_t gm_made_step;
gm_made_step = 0; /* so far gm did not walk */
printf("input dir=%d, curr state = %d\n", dir, gm->state);
if ( gm->state == GM_STATE_CENTER )
{
gm->state = GM_STATE_READY_FOR_WALK;
gm->dir = dir;
v16_SetByConstantByOneConstant(&(gm->twop), GM_OFFSET);
v16_AddDir(&(gm->twop), dir, (uint16_t)16);
}
else if ( gm->state == GM_STATE_READY_FOR_WALK )
{
if ( gm->dir != dir )
{
gm->state = GM_STATE_CENTER;
gm->dir = 0;
v16_SetByConstantByOneConstant(&(gm->twop), GM_OFFSET);
printf("reset state=%d dir=%d\n", gm->state, gm->dir);
}
else
{
uint8_t dest_tile;
/* try to walk into the requested direction */
v16_AddDir(&(gm->pt), dir, 1);
/* check whether the dest tile is valid. if not, go back */
dest_tile = map_GetTile(map, gm->pt.v[0], gm->pt.v[1]);
if ( dest_tile == 32 )
{
/* destination tile is valid, gm did a step */
gm_made_step = 1;
v16_SetByConstantByOneConstant(&(gm->gmop), GM_OFFSET);
v16_AddDir(&(gm->gmop), dir, (uint16_t)-16);
v16_SetByV16(&(gm->cwop), &(gm->twop));
v16_AddDir(&(gm->cwop), dir, (uint16_t)-16);
printf("walk state=%d dir=%d\n", gm->state, gm->dir);
}
else
{
v16_AddDir(&(gm->pt), (dir+2)&3, 1);
printf("blocked\n");
}
}
}
return gm_made_step;
}
void gm_Step(gm_t *gm, map_t *map)
{
v16_AverageByV16(&(gm->cwop), &(gm->twop));
v16_AverageByConstant(&(gm->gmop), GM_OFFSET, GM_OFFSET);
gm_SetWindowPosByGolemMasterPos(gm, map);
}
/*=================================================*/
void obj_Init(obj_t *o)
{
o->tile = 0xe0;
v16_SetByConstant(&(o->pos_t), 4, 3);
v16_SetByConstant(&(o->offset_p), 0, 0);
o->health = 10;
o->attack = 2;
o->defense = 2;
o->mode = OBJ_MODE_ATTACK_PLAYER;
}
/* try to walk towards destination */
void obj_WalkTo(obj_t *o, map_t *map, v16_t *dest_t)
{
uint8_t dir;
/* which direction should the object move? */
if ( dest_t->v[0] < o->pos_t.v[0] && !map_isOccupiedInDir(map, &(o->pos_t), 2) )
dir = 2;
else if ( dest_t->v[0] > o->pos_t.v[0] && !map_isOccupiedInDir(map, &(o->pos_t), 0) )
dir = 0;
else if ( dest_t->v[1] > o->pos_t.v[1] && !map_isOccupiedInDir(map, &(o->pos_t), 1) )
dir = 1;
else if ( dest_t->v[1] < o->pos_t.v[1] && !map_isOccupiedInDir(map, &(o->pos_t), 3) )
dir = 3;
else
/* no move */
return;
v16_AddDir(&(o->pos_t), dir, 1);
}
void obj_Draw(obj_t *o, map_t *map, u8g2_t *u8g2)
{
v16_t dest_pos_pix;
map_GetDisplayPosByTileMapPos(map, &dest_pos_pix, &(o->pos_t));
if ( map_IsTileVisible(map, o->pos_t.v[0], o->pos_t.v[1]) )
{
// puts("visible!");
u8g2_DrawGlyph(u8g2,
dest_pos_pix.v[0],
dest_pos_pix.v[1]+16,
o->tile);
}
else
{
puts("Spinne nicht sichtbar!!!");
}
}
void obj_list_Draw(map_t *map, u8g2_t *u8g2)
{
uint8_t i;
for( i = 0; i < OBJ_LIST_MAX; i++ )
obj_Draw(obj_list+i, map, u8g2);
}
/*=================================================*/
u8g2_t u8g2;
map_t map;
gm_t gm;
obj_t spider;
int main(void)
{
int k;
int8_t walk_direction;
u8g2_SetupBuffer_SDL_128x64_4(&u8g2, &u8g2_cb_r0);
u8x8_InitDisplay(u8g2_GetU8x8(&u8g2));
u8x8_SetPowerSave(u8g2_GetU8x8(&u8g2), 0);
u8g2_SetFont(&u8g2, scrollosprites);
obj_Init(&spider);
spider.tile = 0x54;
obj_list_Init();
map_Init(&map);
gm_Init(&gm);
for(;;)
{
gm_SetWindowPosByGolemMasterPos(&gm, &map);
do
{
u8g2_FirstPage(&u8g2);
do
{
u8g2_SetFontDirection(&u8g2, 0);
map_Draw(&map, &u8g2);
gm_Draw(&gm, &map, &u8g2);
obj_Draw(&spider, &map,&u8g2);
} while( u8g2_NextPage(&u8g2) );
gm_Step(&gm, &map);
usleep(100000);
k = u8g_sdl_get_key();
} while( k < 0 );
if ( k == 'q' ) break;
switch( k )
{
case 273: walk_direction = 3; break;
case 274: walk_direction = 1; break;
case 276: walk_direction = 2; break;
case 275: walk_direction = 0; break;
default: walk_direction = -1; break;
}
if ( walk_direction >= 0 )
{
if ( gm_Walk(&gm,&map, walk_direction) != 0 )
{
obj_WalkTo(&spider, &map, &(gm.pt));
}
}
}
return 0;
}

View File

@@ -0,0 +1,431 @@
/*
mapgen.c
tile <ascii> <mapto> <top> <right> <bottom> <left>
":"<mapline>
num := <hexnum> | <decnum> | <asciinum>
asciinum := "'" <char>
hexnum := "$" <hexdigit> { <hexdigit> }
decnum := <decdigit> { <decdigit> }
decdigit := "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
hexdigit := "a" | "b" | "c" | "d" | "e" | "f" | "A" | "B" | "C" | "D" | "E" | "F" | <decdigit>
The value 0 for "top", "right", "bottom" or "left" means match any.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
struct tile_struct
{
int ascii;
int map_to;
int condition[4];
};
#define TILE_MAX 4096
struct tile_struct tile_list[TILE_MAX];
int tile_cnt = 0;
#define MAP_SIZE_X 1024
#define MAP_SIZE_Y 1024
#define MAP_LINE_MAX 4096
uint8_t map[MAP_SIZE_Y][MAP_SIZE_X];
uint8_t map2[MAP_SIZE_Y][MAP_SIZE_X];
int map_curr_line = 0;
char map_name[MAP_LINE_MAX];
long map_width = 0;
long map_height = 0;
FILE *map_fp;
char map_line[MAP_LINE_MAX];
static void skip_space(const char **s)
{
for(;;)
{
if ( **s == '#' )
{
while( **s != '\0' )
(*s)++;
break;
}
if ( **s == '\0' )
break;
if ( **s > ' ' )
break;
(*s)++;
}
}
static long get_dec(const char **s)
{
long v = 0;
for(;;)
{
if ( (**s) >= '0' && (**s) <= '9' )
{
v*=10;
v+= (**s)-'0';
(*s)++;
}
else
{
break;
}
}
skip_space(s);
return v;
}
static long get_hex(const char **s)
{
long v = 0;
for(;;)
{
if ( (**s) >= '0' && (**s) <= '9' )
{
v*=16;
v+= (**s)-'0';
(*s)++;
}
else if ( (**s) >= 'a' && (**s) <= 'f' )
{
v*=16;
v+= (**s)-'a'+10;
(*s)++;
}
else if ( (**s) >= 'A' && (**s) <= 'F' )
{
v*=16;
v+= (**s)-'A'+10;
(*s)++;
}
else
{
break;
}
}
skip_space(s);
return v;
}
static long get_ascii(const char **s)
{
long v = 0;
v = **s;
(*s)++;
skip_space(s);
return v;
}
static long get_num(const char **s)
{
if ( (**s) == '$' )
{
(*s)++;
return get_hex(s);
}
if ( (**s) == '\'' )
{
(*s)++;
return get_ascii(s);
}
return get_dec(s);
}
static const char *get_identifier(const char **s)
{
static char buf[MAP_LINE_MAX];
int c;
int i = 0;
buf[0] = '\0';
for(;;)
{
c = **s;
if ( c < 'A' )
break;
if ( i >= MAP_LINE_MAX-2 )
break;
buf[i++] = c;
buf[i] = '\0';
(*s)++;
}
skip_space(s);
return buf;
}
/*============================================*/
int get_tile_idx_by_ascii(int ascii)
{
int i;
for( i = 0; i < tile_cnt; i++ )
{
if ( tile_list[i].ascii == ascii )
return i;
}
return -1;
}
/* map a tile from map[][] to map2[][] */
/* called by map_all_tile */
int map_tile(int x, int y)
{
int ascii, i, j;
int cond[4];
int is_condition_match;
//int is_simple_match;
int condition_match_cnt;
int condition_match_max;
int i_best;
/* get the ascii version */
ascii = map[y][x];
cond[0] = 32;
cond[1] = 32;
cond[2] = 32;
cond[3] = 32;
if ( y > 0 ) cond[0] = map[y-1][x];
if ( x+1 < map_width ) cond[1] = map[y][x+1];
if ( y+1 < map_height ) cond[2] = map[y+1][x];
if ( x > 0 ) cond[3] = map[y][x-1];
/* find matching tile */
condition_match_max = -1;
i_best = -1;
for( i = 0; i < tile_cnt; i++ )
{
if ( tile_list[i].ascii == ascii )
{
is_condition_match = 1;
//is_simple_match = 1;
condition_match_cnt = 0;
for( j = 0; j < 4; j++ )
{
if ( tile_list[i].condition[j] != 0 )
{
//is_simple_match = 0;
if ( tile_list[i].condition[j] != cond[j] )
{
is_condition_match = 0;
}
else
{
condition_match_cnt++;
}
}
}
if ( is_condition_match )
{
if ( condition_match_max < condition_match_cnt )
{
condition_match_max = condition_match_cnt;
i_best = i;
}
}
}
}
if ( i_best < 0 )
{
printf("no tile mapping found for '%c' (x=%d, y=%d)\n", ascii, x, y);
return 0;
}
//printf("tile mapping '%c' --> $%02x (x=%d, y=%d)\n", ascii, tile_list[i_best].map_to, x, y);
map2[y][x] = tile_list[i_best].map_to;
return 1;
}
int map_all_tiles(void)
{
int x, y;
for( y = 0; y < map_height; y++ )
for( x = 0; x < map_width; x++ )
if ( map_tile(x,y) == 0 )
return 0;
return 1;
}
void clear_map(void)
{
int x, y;
for( y = 0; y < MAP_SIZE_Y; y++ )
for( x = 0; x < MAP_SIZE_X; x++ )
map[y][x] =32;
map_curr_line = 0;
}
void write_map(const char *filename)
{
int x, y;
FILE *fp;
fp = fopen(filename, "w");
for( y = 0; y < map_height; y++ )
{
fprintf(fp, " \"");
for( x = 0; x < map_width; x++ )
{
fprintf(fp, "\\x%02x", map2[y][x]);
}
fprintf(fp, "\"");
if ( y+1 < map_height )
fprintf(fp, ",");
fprintf(fp, "\n");
}
fclose(fp);
}
int map_read_tile(const char **s)
{
long ascii;
int idx, i;
ascii = get_num(s);
if ( tile_cnt >= TILE_MAX )
{
printf("max number of tiles reached\n");
return 0;
}
idx = tile_cnt;
tile_list[idx].ascii = ascii;
tile_cnt++;
tile_list[idx].map_to = get_num(s);
for( i = 0; i < 4; i++ )
{
tile_list[idx].condition[i] = get_num(s);
}
//printf("[%d] tile %c: ", idx, (int)ascii);
//printf("map to $%02x\n", tile_list[idx].map_to);
return 1;
}
int map_read_row(const char **s)
{
int x = 0;
//printf("line %d\n", map_curr_line);
while ( **s >= ' ' )
{
if ( x > map_width )
{
printf("map '%s': Row '%d' too long\n", map_name, map_curr_line);
return 0;
}
//printf("%d ", **s);
map[map_curr_line][x] = **s;
(*s)++;
x++;
}
map_curr_line++;
return 1;
}
int map_read_map_cmd(const char **s)
{
/* get new map */
strcpy(map_name, get_identifier(s));
map_width = get_num(s);
map_height = get_num(s);
printf("map '%s' (%ld x %ld)\n", map_name, map_width, map_height);
clear_map();
return 1;
}
int map_read_line(const char **s)
{
const char *id;
skip_space(s);
if ( **s == '#' ) /* comment (hmm handled by skip_space) */
return 1;
if ( **s == '\0' ) /* empty line */
return 1;
if ( **s == ':' )
{
(*s)++;
return map_read_row(s);
}
id = get_identifier(s);
if ( strcmp(id, "tile") == 0 )
{
return map_read_tile(s);
}
else if ( strcmp(id, "map") == 0 )
{
return map_read_map_cmd(s);
}
else if ( strcmp(id, "endmap") == 0 )
{
/* write existing map */
if ( map_width > 0 && map_height > 0 )
{
if ( map_all_tiles() )
write_map("gm.c");
}
return 1;
}
else
{
printf("line %d: unkown command '%s'\n", map_curr_line, id);
}
return 1;
}
int map_read_fp(void)
{
const char *s;
for(;;)
{
if ( fgets(map_line, MAP_LINE_MAX, map_fp) == NULL )
break;
s = &(map_line[0]);
if ( map_read_line(&s) == 0 )
return 0;
}
return 1;
}
int map_read_filename(const char *name)
{
map_fp = fopen(name, "r");
if ( map_fp == NULL )
return 0;
printf("file '%s'\n", name);
if ( map_read_fp() == 0 )
return fclose(map_fp), 0;
fclose(map_fp);
return 1;
}
int main(void)
{
clear_map();
map_read_filename("gm.map");
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

@@ -0,0 +1,12 @@
CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) main.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

View File

@@ -0,0 +1,102 @@
#include "u8g2.h"
#include <stdio.h>
u8g2_t u8g2;
int main(void)
{
int x, y;
int k;
int i;
u8g2_SetupBuffer_SDL_128x64_4(&u8g2, &u8g2_cb_r0);
u8x8_InitDisplay(u8g2_GetU8x8(&u8g2));
u8x8_SetPowerSave(u8g2_GetU8x8(&u8g2), 0);
u8g2_SetFont(&u8g2, u8g2_font_helvB18_tn);
x = 50;
y = 30;
for(;;)
{
#ifdef U8G2_WITH_HVLINE_COUNT
u8g2.hv_cnt = 0UL;
#endif /* U8G2_WITH_HVLINE_COUNT */
/*
u8g2_ClearBuffer(&u8g2);
u8g2_SetFontDirection(&u8g2, 0);
u8g2_DrawStr(&u8g2, x, y, "ABC");
u8g2_SetFontDirection(&u8g2, 1);
u8g2_DrawStr(&u8g2, x, y, "abc");
u8g2_SetFontDirection(&u8g2, 2);
u8g2_DrawStr(&u8g2, x, y, "abc");
u8g2_SetFontDirection(&u8g2, 3);
u8g2_DrawStr(&u8g2, x, y, "abc");
u8g2_SendBuffer(&u8g2);
*/
u8g2_FirstPage(&u8g2);
i = 0;
do
{
u8g2_SetFontDirection(&u8g2, 0);
u8g2_DrawStr(&u8g2, x, y, "123");
u8g2_SetFontDirection(&u8g2, 1);
u8g2_DrawStr(&u8g2, x, y, "123");
u8g2_SetFontDirection(&u8g2, 2);
u8g2_DrawStr(&u8g2, x, y, "123");
u8g2_SetFontDirection(&u8g2, 3);
u8g2_DrawStr(&u8g2, x, y, "123");
if ( i == 1 )
{
u8g2_DrawHVLine(&u8g2, u8g2.user_x0, u8g2.user_y0, 1, 0);
u8g2_DrawHVLine(&u8g2, u8g2.user_x0, u8g2.user_y1-1, 1, 0);
u8g2_DrawHVLine(&u8g2, u8g2.user_x1-1, u8g2.user_y1-1, 1, 0);
u8g2_DrawHVLine(&u8g2, u8g2.user_x1-1, u8g2.user_y0, 1, 0);
}
i++;
} while( u8g2_NextPage(&u8g2) );
#ifdef U8G2_WITH_HVLINE_COUNT
printf("hv cnt: %ld\n", u8g2.hv_cnt);
#endif /* U8G2_WITH_HVLINE_COUNT */
do
{
k = u8g_sdl_get_key();
} while( k < 0 );
if ( k == 273 ) y -= 7;
if ( k == 274 ) y += 7;
if ( k == 276 ) x -= 7;
if ( k == 275 ) x += 7;
if ( k == 'e' ) y -= 1;
if ( k == 'x' ) y += 1;
if ( k == 's' ) x -= 1;
if ( k == 'd' ) x += 1;
if ( k == 'q' ) break;
}
//u8x8_Set8x8Font(u8g2_GetU8x8(&u8g2), bdf_font);
//u8x8_Draw8x8String(u8g2_GetU8x8(&u8g2), 0, 0, "Hello World!");
return 0;
}

View File

@@ -0,0 +1,12 @@
CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) main.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

View File

@@ -0,0 +1,33 @@
#include "u8x8.h"
u8x8_t u8x8;
int main(void)
{
u8x8_Setup_SDL_128x64(&u8x8);
u8x8_InitDisplay(&u8x8);
u8x8_SetFont(&u8x8, u8x8_font_amstrad_cpc_extended_f);
u8x8_DrawString(&u8x8, 0, 0, "Hello World!");
u8x8_Draw1x2String(&u8x8, 0, 1, "Hello World!");
u8x8_Draw2x2String(&u8x8, 0, 3, "Hello World!");
while( u8g_sdl_get_key() < 0 )
;
u8x8_ClearDisplay(&u8x8);
u8x8_SetFont(&u8x8, u8x8_font_7x14_1x2_f );
u8x8_Draw1x2String(&u8x8, 0, 0, "Hello World!");
u8x8_Draw2x2String(&u8x8, 0, 4, "Hello World!");
while( u8g_sdl_get_key() < 0 )
;
return 0;
}

View File

@@ -0,0 +1,12 @@
CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) main.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

View File

@@ -0,0 +1,105 @@
#include "u8g2.h"
const uint8_t bdf_font[762] U8X8_FONT_SECTION("bdf_font") = {
32,126,0,0,0,0,0,0,0,0,0,0,0,95,95,0,
0,0,0,7,7,0,7,7,0,0,20,127,127,28,127,127,
20,0,0,36,42,127,127,42,18,0,70,102,48,24,12,102,
98,0,48,122,79,93,55,122,72,0,0,0,0,7,7,0,
0,0,0,0,28,62,99,65,0,0,0,0,65,99,62,28,
0,0,0,0,0,0,0,0,0,0,0,8,8,62,62,8,
8,0,0,0,128,224,96,0,0,0,0,8,8,8,8,8,
8,0,0,0,0,96,96,0,0,0,96,48,24,12,6,3,
1,0,62,127,81,73,69,127,62,0,0,64,66,127,127,64,
64,0,0,114,123,73,73,111,102,0,0,34,97,73,73,127,
54,0,24,20,82,127,127,80,16,0,0,39,111,73,73,121,
51,0,0,62,127,73,73,123,50,0,0,3,1,113,125,15,
7,0,0,54,127,73,73,127,54,0,0,38,111,73,73,127,
62,0,0,0,0,108,108,0,0,0,0,0,128,236,108,0,
0,0,0,8,28,54,99,65,0,0,0,36,36,36,36,36,
36,0,0,65,99,54,28,8,0,0,0,2,3,81,89,15,
6,0,62,127,65,93,93,95,30,0,0,124,126,19,19,126,
124,0,65,127,127,73,73,127,54,0,28,62,99,65,65,99,
34,0,65,127,127,65,99,62,28,0,65,127,127,73,93,65,
99,0,65,127,127,73,29,1,3,0,60,126,67,65,81,115,
114,0,0,127,127,8,8,127,127,0,0,65,65,127,127,65,
65,0,48,112,64,65,127,63,1,0,65,127,127,8,28,119,
99,0,65,127,127,65,64,96,112,0,127,127,14,28,14,127,
127,0,127,127,6,12,24,127,127,0,28,62,99,65,99,62,
28,0,65,127,127,73,9,7,6,0,60,126,67,81,51,110,
92,0,65,127,127,9,25,63,102,0,0,38,111,73,73,123,
50,0,0,3,65,127,127,65,3,0,0,63,127,64,64,127,
63,0,0,31,63,96,96,63,31,0,127,127,48,24,48,127,
127,0,97,115,30,12,30,115,97,0,0,7,79,120,120,79,
7,0,71,99,113,89,77,103,115,0,0,0,127,127,65,65,
0,0,1,3,6,12,24,48,96,0,0,0,65,65,127,127,
0,0,8,12,6,3,6,12,8,0,0,0,0,0,0,0,
0,0,0,0,2,6,12,8,0,0,32,116,84,84,60,120,
64,0,67,63,127,68,68,124,56,0,0,56,124,68,68,108,
40,0,56,124,68,69,63,127,64,0,0,56,124,84,84,92,
24,0,0,72,126,127,73,3,2,0,0,152,188,164,164,252,
124,0,65,127,127,8,4,124,120,0,0,0,68,125,125,64,
0,0,0,96,224,128,132,252,125,0,65,127,127,16,56,108,
68,0,0,0,65,127,127,64,0,0,120,124,12,56,12,124,
120,0,4,124,120,4,4,120,120,0,0,56,124,68,68,124,
56,0,132,252,248,164,36,60,24,0,24,60,36,164,248,252,
132,0,68,124,120,68,12,8,0,0,0,72,92,84,84,116,
32,0,0,4,63,127,68,100,32,0,0,60,124,64,64,124,
124,0,0,28,60,96,96,60,28,0,60,124,96,56,96,124,
60,0,68,108,56,16,56,108,68,0,0,156,188,160,160,252,
124,0,0,76,100,116,92,76,68,0,0,65,65,119,62,8,
8,0,0,0,0,127,127,0,0,0,0,8,8,62,119,65,
65,0,2,3,1,3,2,1,1,0};
u8g2_t u8g2;
int main(void)
{
u8g2_SetupBuffer_SDL_128x64(&u8g2, &u8g2_cb_r0);
u8x8_InitDisplay(u8g2_GetU8x8(&u8g2));
u8x8_SetPowerSave(u8g2_GetU8x8(&u8g2), 0);
u8g2_DrawHVLine(&u8g2, 5, 20, 40, 0);
u8g2_DrawHVLine(&u8g2, 5, 22, 40, 0);
u8g2_DrawHVLine(&u8g2, 5, 24, 40, 0);
u8g2_DrawHVLine(&u8g2, 5, 24, 40, 1);
/* clipping tests */
u8g2_DrawHVLine(&u8g2, 60000, 10000, 39, 0);
u8g2_DrawHVLine(&u8g2, 140, 40, 40, 0);
u8g2_DrawHVLine(&u8g2, 120, 41, 40, 0);
u8g2_DrawHVLine(&u8g2, 120, 42, 0xff8f, 0); /* rare case */
u8g2_DrawHVLine(&u8g2, 120, 43, 6, 0);
u8g2_DrawHVLine(&u8g2, 0, 40, 10, 0);
u8g2_DrawHVLine(&u8g2, -2, 41, 5, 0);
u8g2_DrawHVLine(&u8g2, -3, 42, 5, 0);
u8g2_DrawHVLine(&u8g2, -8, 43, 5, 0);
u8g2_DrawHVLine(&u8g2, 0, 44, 10, 0);
u8g2_DrawHVLine(&u8g2, 99, 70, 40, 1);
u8g2_DrawHVLine(&u8g2, 98, 60, 40, 1);
u8g2_DrawHVLine(&u8g2, 97, 60, 0xfff0, 1); /* rare case */
u8g2_DrawHVLine(&u8g2, 96, 60, 3, 1);
u8g2_SendBuffer(&u8g2);
u8x8_SetFont(u8g2_GetU8x8(&u8g2), bdf_font);
u8x8_DrawString(u8g2_GetU8x8(&u8g2), 0, 0, "Hello World!");
while( u8g_sdl_get_key() < 0 )
;
return 0;
}

View File

@@ -0,0 +1,12 @@
CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) main.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

View File

@@ -0,0 +1,49 @@
#include "u8g2.h"
#include <stdio.h>
u8g2_t u8g2;
int main(void)
{
uint8_t value = 0;
uint8_t r;
u8g2_SetupBuffer_SDL_128x64_4(&u8g2, &u8g2_cb_r0);
u8x8_InitDisplay(u8g2_GetU8x8(&u8g2));
u8x8_SetPowerSave(u8g2_GetU8x8(&u8g2), 0);
//u8g2_SetFont(&u8g2, u8g2_font_helvB08_tr);
u8g2_SetFont(&u8g2, u8g2_font_6x10_tr);
u8g2_SetFontDirection(&u8g2, 0);
u8g2_SetFontRefHeightAll(&u8g2);
r = u8g2_UserInterfaceInputValue(&u8g2, "Title\n-----\n", "X=", &value, 0, 19, 2, "m");
printf("r= %d\n", r);
printf("value= %d\n", value);
/*
do
{
k = u8g_sdl_get_key();
} while( k < 0 );
if ( k == 273 ) y -= 7;
if ( k == 274 ) y += 7;
if ( k == 276 ) x -= 7;
if ( k == 275 ) x += 7;
if ( k == 'e' ) y -= 1;
if ( k == 'x' ) y += 1;
if ( k == 's' ) x -= 1;
if ( k == 'd' ) x += 1;
if ( k == 'q' ) break;
*/
return 0;
}

View File

@@ -0,0 +1,12 @@
CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) main.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

View File

@@ -0,0 +1,26 @@
/*
Example for the
u8x8_UserInterfaceInputValue
procedure.
*/
#include "u8x8.h"
u8x8_t u8x8;
int main(void)
{
uint8_t value = 0;
u8x8_Setup_SDL_128x64(&u8x8);
u8x8_InitDisplay(&u8x8);
u8x8_SetFont(&u8x8, u8x8_font_amstrad_cpc_extended_f);
u8x8_UserInterfaceInputValue(&u8x8, "Title\n-----\n", "X=", &value, 0, 19, 2, "m");
return 0;
}

View File

@@ -0,0 +1,12 @@
CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) main.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

View File

@@ -0,0 +1,65 @@
#include "u8g2.h"
#include <stdio.h>
#include <string.h>
char str1[100];
char str2[100];
u8g2_t u8g2;
int main(void)
{
int x, y;
int k;
int len1, len2;
u8g2_SetupBuffer_SDL_128x64_4(&u8g2, &u8g2_cb_r0);
u8x8_InitDisplay(u8g2_GetU8x8(&u8g2));
u8x8_SetPowerSave(u8g2_GetU8x8(&u8g2), 0);
u8g2_SetFont(&u8g2, u8g2_font_helvB18_tn);
strcpy(str1,"Супердискотека 90х");
strcpy(str2,"Virgin Radio New");
u8g2_SetFont(&u8g2, u8g2_font_6x13_t_cyrillic);
len1 = u8g2_GetUTF8Width(&u8g2,str1);
len2 = u8g2_GetUTF8Width(&u8g2,str2);
printf("len1: %d, str1: %s\n",len1,str1);
printf("len2: %d, str2: %s\n",len2,str2);
x = 10;
y = 30;
for(;;)
{
u8g2_FirstPage(&u8g2);
do
{
u8g2_DrawUTF8(&u8g2, x, y, str1);
u8g2_DrawUTF8(&u8g2, x, y+15, str2);
} while( u8g2_NextPage(&u8g2) );
do
{
k = u8g_sdl_get_key();
} while( k < 0 );
if ( k == 273 ) y -= 7;
if ( k == 274 ) y += 7;
if ( k == 276 ) x -= 7;
if ( k == 275 ) x += 7;
if ( k == 'e' ) y -= 1;
if ( k == 'x' ) y += 1;
if ( k == 's' ) x -= 1;
if ( k == 'd' ) x += 1;
if ( k == 'q' ) break;
}
return 0;
}

View File

@@ -0,0 +1,12 @@
CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) main.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,12 @@
CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) main.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

View File

@@ -0,0 +1,276 @@
#include "u8g2.h"
#include <stdio.h>
#define LUT_ARRAY_LEN 20
#define LUT_WAVE_CNT 4
/*
level
0: neutral, middle
1: upper line
2: lower line
*/
uint8_t lut_level[LUT_WAVE_CNT][LUT_ARRAY_LEN];
uint8_t lut_time[LUT_ARRAY_LEN];
#define LUT_DY 3
uint8_t lut_time_to_width[16] =
{
2, // 0
2, // 1
2, // 2
2, // 3
3, // 4
3, // 5
3, // 6
3, // 7
4, // 8
4, // 9
4, // 10
4, // 11
5, // 12
5, // 13
5, // 14
5, // 15
};
u8g2_uint_t get_dx(uint8_t i)
{
//return 5;
return lut_time_to_width[lut_time[i]];
}
void read_lut(const uint8_t *lut)
{
uint8_t i;
for ( i = 0; i < LUT_ARRAY_LEN; i++ )
{
lut_level[0][i] = lut[i] & 3;
lut_level[1][i] = (lut[i]>>2) & 3;
lut_level[2][i] = (lut[i]>>4) & 3;
lut_level[3][i] = (lut[i]>>6) & 3;
}
for ( i = 0; i < LUT_ARRAY_LEN/2; i++ )
{
lut_time[i*2 + 0] = lut[LUT_ARRAY_LEN+i] & 15;
lut_time[i*2 + 1] = (lut[LUT_ARRAY_LEN+i]>>4) & 15;
}
}
void draw_lut_wave(u8g2_t *u8g2, uint8_t w, uint8_t cx, u8g2_uint_t y)
{
uint8_t i;
u8g2_uint_t x1, y1;
u8g2_uint_t x2, y2;
x1 = 18;
y1 = y;
u8g2_DrawGlyph(u8g2, 2,y+2, (w&2)?'1':'0');
u8g2_DrawGlyph(u8g2, 8,y+2, (w&1)?'1':'0');
for( i = 0; i < LUT_ARRAY_LEN; i++ )
{
x2 = x1 + get_dx(i);
y2 = y;
if ( lut_level[w][i] == 1)
y2 -= LUT_DY-1;
else if ( lut_level[w][i] == 2 )
y2 += LUT_DY-1;
if ( y1 != y2 )
u8g2_DrawLine(u8g2, x1, y1, x1, y2);
u8g2_DrawHLine(u8g2, x1, y2, x2-x1+1);
if ( i == cx )
{
u8g2_DrawHLine(u8g2, x1, y-LUT_DY-1, x2-x1+1);
u8g2_DrawHLine(u8g2, x1, y+LUT_DY+1, x2-x1+1);
}
x1 = x2;
y1 = y2;
}
}
void draw_all_lut(u8g2_t *u8g2, uint8_t cx, uint8_t cy)
{
uint8_t i;
uint16_t total;
u8g2_uint_t x, y;
u8g2_uint_t xs = 1;
y = LUT_DY +1;
for( i = 0; i < LUT_WAVE_CNT; i++ )
{
if ( i == cy )
draw_lut_wave(u8g2, i, cx, y);
else
draw_lut_wave(u8g2, i, 255, y); // 255: no cursor
y += (LUT_DY+2)*2;
}
total = 0;
for( i = 0; i < LUT_ARRAY_LEN; i++ )
total += lut_time[i];
y+=1;
if ( cy == LUT_WAVE_CNT )
{
u8g2_SetDrawColor(u8g2, 0);
}
else
{
u8g2_SetDrawColor(u8g2, 1);
}
x = u8g2_DrawStr(u8g2, xs, y, " TP[");
x += u8g2_DrawStr(u8g2, x, y, u8x8_u8toa( cx, 2));
x += u8g2_DrawStr(u8g2, x, y, "]=");
x += u8g2_DrawStr(u8g2, x, y, u8x8_u8toa( lut_time[cx], 2));
x += u8g2_DrawStr(u8g2, x, y, " ");
x += u8g2_DrawStr(u8g2, x, y, " total=");
x += u8g2_DrawStr(u8g2, x, y, u8x8_u16toa( total, 3));
x += u8g2_DrawStr(u8g2, x, y, " ");
y+=8;
if ( cy == LUT_WAVE_CNT+1 )
{
u8g2_SetDrawColor(u8g2, 0);
}
else
{
u8g2_SetDrawColor(u8g2, 1);
}
x = u8g2_DrawStr(u8g2, xs, y, " Test ");
y+=8;
if ( cy == LUT_WAVE_CNT+2 )
{
u8g2_SetDrawColor(u8g2, 0);
}
else
{
u8g2_SetDrawColor(u8g2, 1);
}
x = u8g2_DrawStr(u8g2, xs, y, " Print ");
u8g2_SetDrawColor(u8g2, 1);
}
void init_lut(void)
{
uint8_t i, j;
for( i = 0; i < LUT_ARRAY_LEN; i++ )
{
for( j = 0; j < LUT_WAVE_CNT; j++ )
lut_level[j][i] = 0;
lut_time[i] = 0;
}
}
uint8_t edit_lut(u8g2_t *u8g2)
{
uint8_t event;
uint8_t cx, cy;
u8g2_SetFont(u8g2, u8g2_font_5x7_mr);
u8g2_SetFontMode(u8g2, 0);
u8g2_SetFontDirection(u8g2, 0);
cx = 0;
cy = 0;
for(;;)
{
u8g2_FirstPage(u8g2);
do
{
draw_all_lut(u8g2, cx, cy);
} while( u8g2_NextPage(u8g2) );
for(;;)
{
event = u8x8_GetMenuEvent(u8g2_GetU8x8(u8g2));
if ( event == U8X8_MSG_GPIO_MENU_SELECT )
{
if ( cx < LUT_ARRAY_LEN && cy < LUT_WAVE_CNT )
{
lut_level[cy][cx]++;
if ( lut_level[cy][cx] >= 3 )
lut_level[cy][cx] = 0;
}
else
{
if ( cy == LUT_WAVE_CNT )
{
lut_time[cx]++;
if ( lut_time[cx] >= 16 )
lut_time[cx] = 0;
}
}
break;
}
else if ( event == U8X8_MSG_GPIO_MENU_HOME )
return 0;
else if ( event == U8X8_MSG_GPIO_MENU_NEXT )
{
cx++;
if ( cx >= LUT_ARRAY_LEN )
cx = 0;
break;
}
else if ( event == U8X8_MSG_GPIO_MENU_DOWN )
{
cy++;
if ( cy >= LUT_WAVE_CNT+3 )
cy = 0;
break;
}
else if ( event == U8X8_MSG_GPIO_MENU_PREV )
{
if ( cx == 0 )
cx = LUT_ARRAY_LEN;
cx--;
break;
}
else if ( event == U8X8_MSG_GPIO_MENU_UP )
{
if ( cy == 0 )
cy = LUT_WAVE_CNT+3;
cy--;
break;
}
}
}
return 0;
}
u8g2_t u8g2;
const uint8_t LUTDefault_full[31] =
{
0x50, 0xAA, 0x55, 0xAA, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
int main(void)
{
u8g2_SetupBuffer_SDL_128x64_4(&u8g2, &u8g2_cb_r0);
u8x8_InitDisplay(u8g2_GetU8x8(&u8g2));
u8x8_SetPowerSave(u8g2_GetU8x8(&u8g2), 0);
init_lut();
read_lut(LUTDefault_full);
edit_lut(&u8g2);
return 0;
}

View File

@@ -0,0 +1,12 @@
CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) main.c menu.c gui.c datecalc.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

View File

@@ -0,0 +1,330 @@
/*
datecalc.c
Written 1996/96 by Oliver Kraus
Published by Heinz Heise Verlag 1997 (c't 15/97)
Completly rewritten and put under GPL 2011 by Oliver Kraus
(c) 2011 by Oliver Kraus (olikraus@gmail.com)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Development goals:
- English version
- Optimized for 8 bit microcontroller
Definitions:
Short Name: y
Long Name: year
Range: 2000...
Short Name: ydn
Long Name: year day number
Range: 1..366
Short Name: cdn
Long Name: century day number
Range: 1...65535
Short Name: ymd
Long Name: Year, Month, Day
Range: 2000...65535, 1..12, 1..31
Conversions
ymd --> y, ydn
get_year_day_number()
y, ydn --> ymd
get_month_by_year_day_number()
get_day_by_year_day_number()
y, ydn --> cdn
to_century_day_number();
cdn --> y, ydn
from_century_day_number();
*/
#include <stdint.h>
/*
Prototype:
uint8_t is_leap_year(uint16_t y)
Description:
Calculate leap year
Arguments:
y year, e.g. 2011 for year 2011
Result:
0 not a leap year
1 leap year
*/
static uint8_t is_leap_year(uint16_t y)
{
if (
((y % 4 == 0) && (y % 100 != 0)) ||
(y % 400 == 0)
)
return 1;
return 0;
}
/*
Prototype:
uint16_t get_year_day_number(uint16_t y, uint8_t m, uint8_t d)
Description:
Calculate the day number within a year. 1st of Jan has the number 1.
"Robertson" Algorithm
Arguments:
y year, e.g. 2011 for year 2011
m month with 1 = january to 12 = december
d day starting with 1
Result:
The "day number" within the year: 1 for the 1st of Jan.
See also:
get_month_by_day_number()
*/
uint16_t get_year_day_number(uint16_t y, uint8_t m, uint8_t d)
{
uint8_t tmp1;
uint16_t tmp2;
tmp1 = 0;
if ( m >= 3 )
tmp1++;
tmp2 = m;
tmp2 +=2;
tmp2 *=611;
tmp2 /= 20;
tmp2 += d;
tmp2 -= 91;
tmp1 <<=1;
tmp2 -= tmp1;
if ( tmp1 != 0 )
tmp2 += is_leap_year(y);
return tmp2;
}
/*
Prototype:
uint8_t get_month_by_year_day_number(uint16_t y, uint16_t ydn)
Description:
Get the month from year and day number within a year.
"R. A. Stone" Algorithm
Arguments:
y year, e.g. 2011 for year 2011
ydn year day number (1st of Jan has the number 1)
Result:
The month within the year: 1 for January.
See also:
get_year_day_number()
*/
static uint16_t corrected_year_day_number(uint16_t y, uint16_t ydn)
{
uint8_t a;
a = is_leap_year(y);
if ( ydn > 59+a )
{
ydn += 2;
ydn -= a;
}
ydn += 91;
return ydn;
}
uint8_t get_month_by_year_day_number(uint16_t y, uint16_t ydn)
{
uint8_t a;
ydn = corrected_year_day_number(y, ydn);
ydn *= 20;
ydn /= 611;
a = ydn;
a -= 2;
return a;
}
/*
Prototype:
uint8_t get_day_by_year_day_number(uint16_t y, uint16_t ydn)
Description:
Get the day within month from year and day number within a year.
"R. A. Stone" Algorithm
Arguments:
y year, e.g. 2011 for year 2011
ydn year day number (1st of Jan has the number 1)
Result:
The day within a month: 1 for the first day of a month.
See also:
get_year_day_number()
*/
uint8_t get_day_by_year_day_number(uint16_t y, uint16_t ydn)
{
uint8_t m;
uint16_t tmp;
m = get_month_by_year_day_number(y, ydn);
m += 2;
ydn = corrected_year_day_number(y, ydn);
tmp = 611;
tmp *= m;
tmp /= 20;
ydn -= tmp;
return ydn;
}
/*
Prototype:
uint8_t get_weekday_by_year_day_number(uint16_t y, uint16_t ydn)
Description:
Get the day within week from year and day number within a year.
"Zeller" Algorithm
Arguments:
y year, e.g. 2011 for year 2011
ydn year day number (1st of Jan has the number 1)
Result:
The day within a week: 0..6 with 0 = Sunday, 1 = Monday, ...
See also:
get_year_day_number()
*/
uint8_t get_weekday_by_year_day_number(uint16_t y, uint16_t ydn)
{
uint8_t j, c, tmp8;
uint16_t tmp16;
y--;
j = y % 100;
c = y / 100;
tmp16 = c;
tmp16 *= 5;
tmp16 += ydn;
tmp8 = j;
j >>= 2;
c >>= 2;
tmp8 += j;
tmp8 += c;
tmp8 += 28;
tmp16 += tmp8;
tmp16 %= 7;
return tmp16;
}
/*
Prototype:
uint16_t to_century_day_number(uint16_t y, uint16_t ydn)
Description:
Calculate days since January, 1st, 2000
Arguments:
y year, e.g. 2011 for year 2011
ydn year day number (1st of Jan has the number 1)
*/
uint16_t to_century_day_number(uint16_t y, uint16_t ydn)
{
uint16_t cdn;
cdn = ydn;
cdn--;
while( y > 2000 )
{
y--;
cdn += 365;
cdn += is_leap_year(y);
}
return cdn;
}
void from_century_day_number(uint16_t cdn, uint16_t *year, uint16_t *ydn)
{
uint16_t y, days_per_year;
y = 2000;
for(;;)
{
days_per_year = 365;
days_per_year += is_leap_year(y);
if ( cdn >= days_per_year )
{
cdn -= days_per_year;
y++;
}
else
break;
}
cdn++;
*year = y;
*ydn = cdn;
}
/*
Calculate the seconds after 2000-01-01 00:00. The largest possible
time is 2136-02-07 06:28:15
*/
uint32_t to_time(uint16_t cdn, uint8_t h, uint8_t m, uint8_t s)
{
uint32_t t;
t = cdn;
t *= 24;
t += h;
t *= 60;
t += m;
t *= 60;
t += s;
return t;
}
void from_time(uint32_t t, uint16_t *cdn, uint8_t *h, uint8_t *m, uint8_t *s)
{
*s = t % 60;
t /= 60;
*m = t % 60;
t /= 60;
*h = t % 24;
t /= 24;
*cdn = t;
}
uint32_t to_sec_since_2000(uint16_t y, uint8_t mo, uint8_t d, uint8_t h, uint8_t mi, uint8_t s)
{
uint16_t ydn = get_year_day_number(y, mo, d);
uint16_t cdn = to_century_day_number(y, ydn);
return to_time(cdn, h, mi, s);
}
/*
Calculate the minutes after 2000-01-01 00:00.
*/
uint32_t to_minutes(uint16_t cdn, uint8_t h, uint8_t m)
{
uint32_t t;
t = cdn;
t *= 24;
t += h;
t *= 60;
t += m;
return t;
}
void from_minutes(uint32_t t, uint16_t *cdn, uint8_t *h, uint8_t *m)
{
*m = t % 60;
t /= 60;
*h = t % 24;
t /= 24;
*cdn = t;
}
uint32_t to_minutes_since_2000(uint16_t y, uint8_t mo, uint8_t d, uint8_t h, uint8_t mi)
{
uint16_t ydn = get_year_day_number(y, mo, d);
uint16_t cdn = to_century_day_number(y, ydn);
return to_minutes(cdn, h, mi);
}

View File

@@ -0,0 +1,82 @@
/*
datecalc.c
Written 1996/96 by Oliver Kraus
Published by Heinz Heise Verlag 1997 (c't 15/97)
Completly rewritten and put under GPL 2011 by Oliver Kraus
(c) 2011 by Oliver Kraus (olikraus@gmail.com)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Development goals:
- English version
- Optimized for 8 bit microcontroller
Definitions:
Short Name: y
Long Name: year
Range: 2000...
Short Name: ydn
Long Name: year day number
Range: 1..366
Short Name: cdn
Long Name: century day number
Range: 1...65535
Short Name: ymd
Long Name: Year, Month, Day
Range: 2000...65535, 1..12, 1..31
Conversions
ymd --> y, ydn
get_year_day_number()
y, ydn --> ymd
get_month_by_year_day_number()
get_day_by_year_day_number()
y, ydn --> cdn
to_century_day_number();
cdn --> y, ydn
from_century_day_number();
*/
#ifndef _DATECALC_H
#define _DATECALC_H
#include <stdint.h>
uint16_t get_year_day_number(uint16_t y, uint8_t m, uint8_t d);
uint8_t get_month_by_year_day_number(uint16_t y, uint16_t ydn);
uint8_t get_day_by_year_day_number(uint16_t y, uint16_t ydn);
uint8_t get_weekday_by_year_day_number(uint16_t y, uint16_t ydn);
uint16_t to_century_day_number(uint16_t y, uint16_t ydn);
void from_century_day_number(uint16_t cdn, uint16_t *year, uint16_t *ydn);
uint32_t to_time(uint16_t cdn, uint8_t h, uint8_t m, uint8_t s);
void from_time(uint32_t t, uint16_t *cdn, uint8_t *h, uint8_t *m, uint8_t *s);
uint32_t to_sec_since_2000(uint16_t y, uint8_t mo, uint8_t d, uint8_t h, uint8_t mi, uint8_t s);
uint32_t to_minutes(uint16_t cdn, uint8_t h, uint8_t m);
void from_minutes(uint32_t t, uint16_t *cdn, uint8_t *h, uint8_t *m);
uint32_t to_minutes_since_2000(uint16_t y, uint8_t mo, uint8_t d, uint8_t h, uint8_t mi);
#endif

View File

@@ -0,0 +1,684 @@
/*
gui.c
*/
#include "gui.h"
#include "datecalc.h"
#include <string.h>
/*============================================*/
extern const me_t melist_display_time[];
extern const me_t melist_top_menu[];
extern const me_t melist_active_alarm_menu[];
extern const me_t melist_setup_menu[];
extern const me_t melist_alarm_menu[];
/*============================================*/
uint8_t gui_alarm_index = 0;
gui_alarm_t gui_alarm_current;
gui_alarm_t gui_alarm_list[GUI_ALARM_CNT];
char gui_alarm_str[GUI_ALARM_CNT][8];
const char weekdaystr[7][4] = {
"Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"
};
gui_data_t gui_data;
menu_t gui_menu;
/*============================================*/
void gui_alarm_calc_next_wd_alarm(uint8_t idx, uint16_t current_week_time_in_minutes)
{
uint8_t i;
uint16_t week_time_abs;
uint16_t week_time_diff; /* difference to current_week_time_in_minutes */
uint16_t best_diff = 0x0ffff;
gui_alarm_list[idx].na_week_time_in_minutes = 0x0ffff; /* not found */
gui_alarm_list[idx].na_minutes_diff = 0x0ffff; /* not found */
gui_alarm_list[idx].na_wd = 7; /* not found */
//printf("gui_alarm_calc_next_wd_alarm: %d\n", idx);
if ( gui_alarm_list[idx].enable != 0 )
{
//printf("gui_alarm_calc_next_wd_alarm: %d enabled\n", idx);
for( i = 0; i < 7; i++ )
{
if ( gui_alarm_list[idx].wd[i] != 0 )
{
//printf("gui_alarm_calc_next_wd_alarm: %d i=%d gui_alarm_list[idx].skip_wd=%d \n", idx, i, gui_alarm_list[idx].skip_wd);
if ( gui_alarm_list[idx].skip_wd != i+1 )
{
week_time_abs = i;
week_time_abs *= 24;
week_time_abs += gui_alarm_list[idx].h;
week_time_abs *= 60;
week_time_abs += gui_alarm_list[idx].m;
week_time_abs += gui_alarm_list[idx].snooze_count*(uint16_t)SNOOZE_MINUTES;
if ( current_week_time_in_minutes <= week_time_abs )
week_time_diff = week_time_abs - current_week_time_in_minutes;
else
week_time_diff = week_time_abs + 7*24*60 - current_week_time_in_minutes;
//printf("gui_alarm_calc_next_wd_alarm: %d week_time_abs=%d current_week_time_in_minutes=%d week_time_diff=%d\n", idx, week_time_abs, current_week_time_in_minutes,week_time_diff);
if ( best_diff > week_time_diff )
{
best_diff = week_time_diff;
/* found for this alarm */
gui_alarm_list[idx].na_minutes_diff = week_time_diff;
gui_alarm_list[idx].na_week_time_in_minutes = week_time_abs;
gui_alarm_list[idx].na_h = gui_alarm_list[idx].h;
gui_alarm_list[idx].na_m = gui_alarm_list[idx].m;
gui_alarm_list[idx].na_wd = i;
}
}
}
}
}
//printf("gui_alarm_calc_next_wd_alarm: %d na_minutes_diff=%d\n", idx, gui_alarm_list[idx].na_minutes_diff);
//printf("gui_alarm_calc_next_wd_alarm: %d na_wd=%d\n", idx, gui_alarm_list[idx].na_wd);
}
void gui_alarm_calc_str_time(uint8_t idx) U8G2_NOINLINE;
void gui_alarm_calc_str_time(uint8_t idx)
{
gui_alarm_str[idx][0] = ' ';
strcpy(gui_alarm_str[idx]+1, u8x8_u8toa(gui_alarm_list[idx].h, 2));
strcpy(gui_alarm_str[idx]+4, u8x8_u8toa(gui_alarm_list[idx].m, 2));
gui_alarm_str[idx][3] = ':';
if ( gui_alarm_list[idx].enable == 0 )
{
gui_alarm_str[idx][0] = '(';
gui_alarm_str[idx][6] = ')';
gui_alarm_str[idx][7] = '\0';
}
}
/* adjust day/month and calculates the weekday */
void gui_date_adjust(void) U8G2_NOINLINE;
void gui_date_adjust(void)
{
uint16_t ydn;
//uint16_t cdn;
uint16_t year;
if ( gui_data.month == 0 )
gui_data.month++;
if ( gui_data.day == 0 )
gui_data.day++;
year = 2000+gui_data.year_t*10 + gui_data.year_o;
ydn = get_year_day_number(year, gui_data.month, gui_data.day);
gui_data.month = get_month_by_year_day_number(year, ydn);
gui_data.day = get_day_by_year_day_number(year, ydn);
gui_data.weekday = get_weekday_by_year_day_number(year, ydn); /* 0 = Sunday */
/* adjust the weekday so that 0 will be Monday */
gui_data.weekday += 6;
if ( gui_data.weekday >= 7 )
gui_data.weekday -= 7;
//cdn = to_century_day_number(y, ydn);
//to_minutes(cdn, h, m);
}
/*
calculate the minute within the week.
this must be called after gui_date_adjust(), because the weekday is used here
*/
void gui_calc_week_time(void)
{
gui_data.week_time = gui_data.weekday;
gui_data.week_time *= 24;
gui_data.week_time += gui_data.h;
gui_data.week_time *= 60;
gui_data.week_time += gui_data.mt * 10 + gui_data.mo;
}
/*
calculate the next alarm.
this must be called after gui_calc_week_time() because, we need week_time
*/
void gui_calc_next_alarm(void)
{
uint8_t i;
uint8_t lowest_i;
uint16_t lowest_diff;
/* step 1: Calculate the difference to current weektime for each alarm */
/* result is stored in gui_alarm_list[i].na_minutes_diff */
for( i = 0; i < GUI_ALARM_CNT; i++ )
gui_alarm_calc_next_wd_alarm(i, gui_data.week_time);
/* step 2: find the index with the lowest difference */
lowest_diff = 0x0ffff;
lowest_i = GUI_ALARM_CNT;
for( i = 0; i < GUI_ALARM_CNT; i++ )
{
if ( lowest_diff > gui_alarm_list[i].na_minutes_diff )
{
lowest_diff = gui_alarm_list[i].na_minutes_diff;
lowest_i = i;
}
}
/* step 3: store the result */
gui_data.next_alarm_index = lowest_i; /* this can be GUI_ALARM_CNT */
//printf("gui_calc_next_alarm gui_data.next_alarm_index=%d\n", gui_data.next_alarm_index);
/* calculate the is_skip_possible and the is_alarm flag */
gui_data.is_skip_possible = 0;
if ( lowest_i < GUI_ALARM_CNT )
{
if ( gui_alarm_list[lowest_i].na_minutes_diff <= 1 )
{
if ( gui_data.is_alarm == 0 )
{
gui_data.is_alarm = 1;
gui_data.active_alarm_idx = lowest_i;
menu_SetMEList(&gui_menu, melist_active_alarm_menu, 0);
}
}
else
{
/* valid next alarm time */
if ( gui_alarm_list[lowest_i].skip_wd == 0 )
{
/* skip flag not yet set */
if ( gui_alarm_list[lowest_i].na_minutes_diff <= (uint16_t)60*(uint16_t)ALLOW_SKIP_HOURS )
{
/* within the limit before alarm */
gui_data.is_skip_possible = 1;
}
}
}
}
}
/* recalculate all internal data */
/* additionally the active alarm menu might be set by this function */
void gui_Recalculate(void)
{
int i;
gui_date_adjust();
gui_calc_week_time();
gui_calc_next_alarm();
for ( i = 0; i < GUI_ALARM_CNT; i++ )
{
gui_alarm_calc_str_time(i);
}
}
void gui_Init(u8g2_t *u8g2)
{
menu_Init(&gui_menu, u8g2);
menu_SetMEList(&gui_menu, melist_display_time, 0);
gui_Recalculate();
}
void gui_Draw(void)
{
menu_Draw(&gui_menu);
}
void gui_Next(void)
{
menu_NextFocus(&gui_menu);
}
void gui_Select(void)
{
menu_Select(&gui_menu);
}
/*============================================*/
const static uint8_t ok_xbm[] = { /* 16x16 */
0xfe, 0x7f, 0x03, 0xc0, 0x01, 0x80, 0x01, 0xb8, 0x01, 0x9c, 0x01, 0x8e,
0x01, 0x87, 0x01, 0x87, 0x9d, 0x83, 0xb9, 0x83, 0xf1, 0x81, 0xe1, 0x81,
0xc1, 0x80, 0x01, 0x80, 0x03, 0xc0, 0xfe, 0x7f };
const static uint8_t alarm_xbm[] = { /* 12x12 */
0x00, 0x00, 0x0c, 0x06, 0xf6, 0x0d, 0x1a, 0x0b, 0x4c, 0x06, 0x44, 0x04,
0xc4, 0x05, 0x04, 0x04, 0x0c, 0x06, 0x18, 0x03, 0xf0, 0x01, 0x00, 0x00 };
int me_action_to_top_menu(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
menu_SetMEList(menu, melist_top_menu, 0);
return 1;
}
return 0;
}
int me_action_save_time(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
menu_SetMEList(menu, melist_top_menu, 0); /* first set the normal menu */
gui_Recalculate(); /* because it might be overwritten with the alarm menu */
return 1;
}
return 0;
}
#define ME_TIME_Y 19
#define ME_TIME_XO 11
const me_t melist_setup_time[] =
{
{ me_cb_0_23, &gui_data.h, NULL, ME_TIME_XO+2,ME_TIME_Y },
{ me_cb_num_label, NULL, ":", ME_TIME_XO+30,ME_TIME_Y-3 },
{ me_cb_0_5, &gui_data.mt, NULL, ME_TIME_XO+39,ME_TIME_Y },
{ me_cb_0_9, &gui_data.mo, NULL, ME_TIME_XO+52,ME_TIME_Y },
{ me_cb_num_label, NULL, ":", ME_TIME_XO+67,ME_TIME_Y-3 },
{ me_cb_0_5, &gui_data.st, NULL, ME_TIME_XO+67+9,ME_TIME_Y },
{ me_cb_0_9, &gui_data.so, NULL, ME_TIME_XO+80+9,ME_TIME_Y },
{ me_cb_button_full_line, (void *)me_action_save_time, "Speichern", 40,30 },
{ me_cb_null, NULL, NULL, 0, 0 },
};
/*============================================*/
/* Display Time */
void gui_alarm_to_str(uint8_t idx)
{
strcpy(gui_data.s, weekdaystr[gui_alarm_list[gui_data.next_alarm_index].na_wd]);
gui_data.s[2] = ',';
gui_data.s[3] = ' ';
strcpy(gui_data.s+4, u8x8_u8toa(gui_alarm_list[gui_data.next_alarm_index].na_h, 2));
gui_data.s[6] = ':';
strcpy(gui_data.s+7, u8x8_u8toa(gui_alarm_list[gui_data.next_alarm_index].na_m, 2));
gui_data.s[9] = '\0';
}
int me_action_handle_display_time(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_DRAW )
{
char s[14];
u8g2_uint_t x = 4;
u8g2_SetFont(menu->u8g2, MENU_NORMAL_FONT);
if ( gui_data.next_alarm_index < GUI_ALARM_CNT )
{
u8g2_DrawXBM(menu->u8g2, 67, 20, 12, 12, (const uint8_t *)(alarm_xbm));
gui_alarm_to_str(gui_data.next_alarm_index);
u8g2_DrawUTF8(menu->u8g2, 81, 30, gui_data.s);
}
else
{
x= 34;
}
strcpy(s, weekdaystr[gui_data.weekday]);
s[2] = ',';
s[3] = ' ';
strcpy(s+4, u8x8_u8toa(gui_data.day, 2));
s[6] = '.';
strcpy(s+7, u8x8_u8toa(gui_data.month, 2));
s[9] = '.';
s[10] = gui_data.year_t+'0';
s[11] = gui_data.year_o+'0';
s[12] = '\0';
u8g2_DrawUTF8(menu->u8g2, x, 30, s);
return 1;
}
else if ( msg == ME_MSG_SELECT )
{
menu_SetMEList(menu, melist_top_menu, 0);
return 1;
}
return 0;
}
#define ME_TIME_DXO 30
const me_t melist_display_time[] =
{
{ me_cb_0_23_ro, &gui_data.h, NULL, ME_TIME_DXO+2,ME_TIME_Y },
{ me_cb_num_label, NULL, ":", ME_TIME_DXO+30,ME_TIME_Y-3 },
{ me_cb_0_9_ro, &gui_data.mt, NULL, ME_TIME_DXO+39,ME_TIME_Y },
{ me_cb_0_9_ro, &gui_data.mo, NULL, ME_TIME_DXO+52,ME_TIME_Y },
{ me_cb_button_empty, (void *)me_action_handle_display_time, NULL, 0, 0 },
{ me_cb_null, NULL, NULL, 0, 0 },
};
/*============================================*/
/* Date Edit Dialog */
int me_action_save_date(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
menu_SetMEList(menu, melist_top_menu, 0); /* first set the normal menu */
gui_Recalculate(); /* because it might be overwritten with the alarm menu */
return 1;
}
return 0;
}
const me_t melist_setup_date[] =
{
{ me_cb_1_31, &gui_data.day, NULL, ME_TIME_XO+2,ME_TIME_Y },
{ me_cb_num_label, NULL, ".", ME_TIME_XO+30,ME_TIME_Y },
{ me_cb_1_12, &gui_data.month, NULL, ME_TIME_XO+39,ME_TIME_Y },
{ me_cb_num_label, NULL, ".", ME_TIME_XO+67,ME_TIME_Y },
{ me_cb_0_9, &gui_data.year_t, NULL, ME_TIME_XO+67+9,ME_TIME_Y },
{ me_cb_0_9, &gui_data.year_o, NULL, ME_TIME_XO+80+9,ME_TIME_Y },
{ me_cb_button_full_line, (void *)me_action_save_date, "Speichern", 40,30 },
{ me_cb_null, NULL, NULL, 0, 0 },
};
/*============================================*/
/* Alarm Edit Dialog */
#define ME_ALARM_TIME_XO 28
#define ME_ALARM_TIME_Y 20
#define ME_ALARM_WD_Y 29
#define ME_ALARM_WD_XO 8
int me_action_alarm_done(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
gui_alarm_list[gui_alarm_index] = gui_alarm_current;
gui_alarm_list[gui_alarm_index].skip_wd = 0; /* clear the skip alarm (if any) */
gui_alarm_list[gui_alarm_index].snooze_count = 0; /* clear snooze (if any) */
//gui_alarm_calc_str_time(gui_alarm_index);
menu_SetMEList(menu, melist_alarm_menu, gui_alarm_index); /* first set the normal menu */
gui_Recalculate(); /* because it might be overwritten with the alarm menu */
return 1;
}
return 0;
}
const me_t melist_setup_alarm[] =
{
{ me_cb_big_toggle, &(gui_alarm_current.enable), NULL, 4 , 6},
{ me_cb_0_23, &(gui_alarm_current.h), NULL, ME_ALARM_TIME_XO+2,ME_ALARM_TIME_Y },
{ me_cb_num_label, NULL, ":", ME_ALARM_TIME_XO+30,ME_ALARM_TIME_Y-3 },
{ me_cb_0_55, &(gui_alarm_current.m), NULL, ME_ALARM_TIME_XO+39,ME_ALARM_TIME_Y },
{ me_cb_wd_toggle, &(gui_alarm_current.wd[0]), (void *)weekdaystr[0], ME_ALARM_WD_XO+17*0, ME_ALARM_WD_Y},
{ me_cb_wd_toggle, &(gui_alarm_current.wd[1]), (void *)weekdaystr[1], ME_ALARM_WD_XO+17*1, ME_ALARM_WD_Y},
{ me_cb_wd_toggle, &(gui_alarm_current.wd[2]), (void *)weekdaystr[2], ME_ALARM_WD_XO+17*2, ME_ALARM_WD_Y},
{ me_cb_wd_toggle, &(gui_alarm_current.wd[3]), (void *)weekdaystr[3], ME_ALARM_WD_XO+17*3, ME_ALARM_WD_Y},
{ me_cb_wd_toggle, &(gui_alarm_current.wd[4]), (void *)weekdaystr[4], ME_ALARM_WD_XO+17*4, ME_ALARM_WD_Y},
{ me_cb_wd_toggle, &(gui_alarm_current.wd[5]), (void *)weekdaystr[5], ME_ALARM_WD_XO+17*5, ME_ALARM_WD_Y},
{ me_cb_wd_toggle, &(gui_alarm_current.wd[6]), (void *)weekdaystr[6], ME_ALARM_WD_XO+17*6, ME_ALARM_WD_Y},
{ me_cb_16x16_bitmap_button, (void *)me_action_alarm_done, (void *)ok_xbm, ME_ALARM_TIME_XO+80,ME_ALARM_TIME_Y-17 },
{ me_cb_null, NULL, NULL, 0, 0 },
};
/*============================================*/
/* Alarm Setup Menu */
static int me_action_alarm_common(menu_t *menu, const me_t *me, uint8_t msg) U8G2_NOINLINE;
static int me_action_alarm_common(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
gui_alarm_current = gui_alarm_list[gui_alarm_index];
menu_SetMEList(menu, melist_setup_alarm, 0);
return 1;
}
return 0;
}
int me_action_alarm1(menu_t *menu, const me_t *me, uint8_t msg)
{
gui_alarm_index = 0;
return me_action_alarm_common(menu, me, msg);
}
int me_action_alarm2(menu_t *menu, const me_t *me, uint8_t msg)
{
gui_alarm_index = 1;
return me_action_alarm_common(menu, me, msg);
}
int me_action_alarm3(menu_t *menu, const me_t *me, uint8_t msg)
{
gui_alarm_index = 2;
return me_action_alarm_common(menu, me, msg);
}
int me_action_alarm4(menu_t *menu, const me_t *me, uint8_t msg)
{
gui_alarm_index = 3;
return me_action_alarm_common(menu, me, msg);
}
int me_action_handle_alarm_list(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_DRAW )
{
uint8_t y, x;
uint8_t ym;
u8g2_SetFont(menu->u8g2, MENU_SMALL_FONT);
for( y = 0; y < 4; y++ )
{
ym = y*8+7;
for( x = 0; x < 7; x++ )
{
u8g2_DrawGlyph(menu->u8g2, 0, ym, y+'1');
u8g2_DrawGlyph(menu->u8g2, 5, ym, ':');
u8g2_DrawStr(menu->u8g2, 9, ym, gui_alarm_str[y]);
if ( gui_alarm_list[y].wd[x] )
{
u8g2_DrawStr(menu->u8g2, 40+x*12, ym, weekdaystr[x]);
}
}
}
}
else if ( msg == ME_MSG_SELECT )
{
menu_SetMEList(menu, melist_alarm_menu, 4);
return 1;
}
return 0;
}
const me_t melist_alarm_list_menu[] =
{
{ me_cb_button_empty, (void *)me_action_handle_alarm_list, NULL, 0, 0 },
{ me_cb_null, NULL, NULL, 0, 0 },
};
int me_action_goto_alarm_list(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
menu_SetMEList(menu, melist_alarm_list_menu, 0);
return 1;
}
return 0;
}
const me_t melist_alarm_menu[] =
{
{ me_cb_button_half_line, (void *)me_action_alarm1, gui_alarm_str[0], 0,10 },
{ me_cb_button_half_line, (void *)me_action_alarm2, gui_alarm_str[1], 64,10 },
{ me_cb_button_half_line, (void *)me_action_alarm3, gui_alarm_str[2], 0,20 },
{ me_cb_button_half_line, (void *)me_action_alarm4, gui_alarm_str[3], 64,20 },
{ me_cb_button_half_line, (void *)me_action_goto_alarm_list, "Liste", 0,30 },
{ me_cb_button_half_line, (void *)me_action_to_top_menu, "Zurück", 64,30 },
{ me_cb_null, NULL, NULL, 0, 0 },
};
/*============================================*/
/* Setup Menu */
int me_action_setup_time(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
menu_SetMEList(menu, melist_setup_time, 0);
return 1;
}
return 0;
}
int me_action_setup_date(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
menu_SetMEList(menu, melist_setup_date, 0);
return 1;
}
return 0;
}
const me_t melist_setup_menu[] =
{
{ me_cb_button_half_line, (void *)me_action_setup_time, "Uhrzeit", 0,10 },
{ me_cb_button_half_line, (void *)me_action_setup_date, "Datum", 64,10 },
{ me_cb_button_half_line, (void *)NULL, "Power", 0,20 },
{ me_cb_button_half_line, (void *)me_action_goto_alarm_list, "Alarme", 64,20 },
{ me_cb_button_full_line, (void *)me_action_to_top_menu, "Zurück", 40,30 },
{ me_cb_null, NULL, NULL, 0, 0 },
};
/*============================================*/
/* Alarm Menu */
int me_action_deactivate_alarm(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
menu_SetMEList(menu, melist_display_time, 0);
return 1;
}
return 0;
}
int me_action_do_snooze(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
menu_SetMEList(menu, melist_display_time, 0);
return 1;
}
return 0;
}
const me_t melist_active_alarm_menu[] =
{
{ me_cb_button_full_line, (void *)0, "", 3,10 },
{ me_cb_button_full_line, (void *)me_action_deactivate_alarm, "Alarm abschalten", 3,20 },
{ me_cb_button_full_line, (void *)me_action_do_snooze, "5 Min schlummern", 3,30 },
{ me_cb_null, NULL, NULL, 0, 0 },
};
/*============================================*/
/* toplevel menu */
int me_action_to_display_time(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
menu_SetMEList(menu, melist_display_time, 0);
return 1;
}
return 0;
}
int me_action_to_alarm_menu(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
menu_SetMEList(menu, melist_alarm_menu, 0);
return 1;
}
return 0;
}
int me_action_to_setup_menu(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_SELECT )
{
menu_SetMEList(menu, melist_setup_menu, 0);
return 1;
}
return 0;
}
int me_cb_button_skip_alarm(menu_t *menu, const me_t *me, uint8_t msg)
{
int r = 0;
u8g2_uint_t x;
switch(msg)
{
case ME_MSG_IS_FOCUS:
return gui_data.is_skip_possible;
case ME_MSG_DRAW_FOCUS:
menu_DrawBoxFocus(menu,
0,
me->y - u8g2_GetAscent(menu->u8g2)-1,
u8g2_GetDisplayWidth(menu->u8g2) ,
u8g2_GetAscent(menu->u8g2) - u8g2_GetDescent(menu->u8g2) +1);
r = 1;
break;
case ME_MSG_DRAW:
if ( gui_data.is_skip_possible )
{
u8g2_SetFont(menu->u8g2, MENU_NORMAL_FONT);
gui_alarm_to_str(gui_data.next_alarm_index);
x = u8g2_DrawUTF8(menu->u8g2, me->x, me->y, gui_data.s );
u8g2_DrawUTF8(menu->u8g2, me->x+x, me->y, " deaktvieren" );
}
r = 1;
break;
case ME_MSG_SELECT:
//printf("me_cb_button_skip_alarm ME_MSG_SELECT\n");
gui_alarm_list[gui_data.next_alarm_index].skip_wd =
gui_alarm_list[gui_data.next_alarm_index].na_wd + 1;
gui_alarm_list[gui_data.next_alarm_index].snooze_count = 0; /* clear snooze (if any) */
menu_SetMEList(menu, melist_display_time, 0); /* first set the normal menu */
gui_Recalculate(); /* it might be changed here to the alarm menu */
r = 1;
break;
}
return r;
}
const me_t melist_top_menu[] =
{
{ me_cb_button_half_line, (void *)me_action_to_display_time, "Zurück", 0,10 },
{ me_cb_button_half_line, (void *)me_action_to_alarm_menu, "Alarm", 64,10 },
{ me_cb_button_skip_alarm, NULL, NULL, 3,20 },
{ me_cb_button_full_line, (void *)me_action_to_setup_menu, "Weitere Funktionen", 3,30 },
{ me_cb_null, NULL, NULL, 0, 0 },
};

View File

@@ -0,0 +1,70 @@
/*
gui.h
*/
#ifndef _GUI_H
#define _GUI_H
#include "menu.h"
#define GUI_ALARM_CNT 4
#define SNOOZE_MINUTES 10
#define ALLOW_SKIP_HOURS 4
struct _gui_data
{
uint16_t week_time; /* calculated: derived from h, mt, mo and weekday */
uint8_t h, mt, mo, st, so; /* input: current time */
uint8_t day; /* input: 1 .. 31 current day in month */
uint8_t month; /* input: 1..12 */
uint8_t year_t, year_o; /* input: current year */
uint8_t weekday; /* calculated: 0 = Monday */
uint8_t next_alarm_index; /* calculated: index for the next alarm or GUI_ALARM_CNT if there is no next alarm */
uint8_t is_skip_possible; /* calculated: whether the next alarm (next_alarm_index) can be skipped */
uint8_t is_alarm; /* input/calculated: set by the software, has to be reset by the user */
uint8_t active_alarm_idx; /* input/calculated: set by the software, has to be reset by the user */
char s[16]; /* string buffer */
};
typedef struct _gui_data gui_data_t;
struct _gui_alarm_struct
{
/* next alarm, all na_ fields are derived from the alarm information */
uint16_t na_week_time_in_minutes;
uint16_t na_minutes_diff; /* calculated: time in minutes until next alarm, 0x0ffff = no alarm */
uint8_t na_h; /* calculated */
uint8_t na_m; /* calculated */
uint8_t na_wd; /* calculated: 0...7, 0=monday, 7=no alarm */
/* alarm information */
uint8_t enable; /* input */
uint8_t snooze_count; /* input */
uint8_t skip_wd; /* input 0 = no skip, 1 = Monday, ...*/
uint8_t h; /* input */
uint8_t m; /* input */
uint8_t wd[7]; /* input: 0 or 1, 0=weekday not selected */
};
typedef struct _gui_alarm_struct gui_alarm_t;
extern const me_t melist_display_time[];
extern const me_t melist_top_menu[];
extern const me_t melist_active_alarm_menu[];
extern const me_t melist_setup_menu[];
extern const me_t melist_alarm_menu[];
extern gui_data_t gui_data;
void gui_Recalculate(void);
void gui_Init(u8g2_t *u8g2);
void gui_Draw(void);
void gui_Next(void);
void gui_Select(void);
#endif

View File

@@ -0,0 +1,108 @@
/*
main.c
*/
#include "gui.h"
#include <stdio.h>
u8g2_t u8g2;
int main(void)
{
int x, y;
int k;
int i;
u8g2_SetupBuffer_SDL_128x64_4(&u8g2, &u8g2_cb_r0);
u8x8_InitDisplay(u8g2_GetU8x8(&u8g2));
u8x8_SetPowerSave(u8g2_GetU8x8(&u8g2), 0);
//u8g2_SetFont(&u8g2, u8g2_font_helvB18_tf);
u8g2_SetFont(&u8g2, u8g2_font_ncenR08_tf);
gui_Init(&u8g2);
x = 50;
y = 50;
for(;;)
{
u8g2_FirstPage(&u8g2);
i = 0;
do
{
gui_Draw();
u8g2_SetFontDirection(&u8g2, 0);
u8g2_SetFont(&u8g2, u8g2_font_ncenR08_tf);
u8g2_DrawStr(&u8g2, x, y, "-- 123");
i++;
} while( u8g2_NextPage(&u8g2) );
do
{
k = u8g_sdl_get_key();
} while( k < 0 );
if ( k == 'n' )
gui_Next();
if ( k == 's' )
gui_Select();
if ( k == 'm' )
{
gui_data.mo++;
if ( gui_data.mo >= 10 )
{
gui_data.mo = 0;
gui_data.mt++;
if ( gui_data.mt >= 60 )
{
gui_data.h++;
if ( gui_data.h >= 24 )
{
gui_data.h = 0;
gui_data.day++;
}
}
}
gui_Recalculate();
}
if ( k == 'h' )
{
gui_data.h++;
if ( gui_data.h >= 24 )
{
gui_data.h = 0;
gui_data.day++;
}
gui_Recalculate();
}
if ( k == 273 ) y -= 1;
if ( k == 274 ) y += 1;
if ( k == 276 ) x -= 1;
if ( k == 275 ) x += 1;
if ( k == 'q' ) break;
}
//u8x8_Set8x8Font(u8g2_GetU8x8(&u8g2), bdf_font);
//u8x8_Draw8x8String(u8g2_GetU8x8(&u8g2), 0, 0, "Hello World!");
return 0;
}

View File

@@ -0,0 +1,566 @@
/*
menu.c
*/
#include "menu.h"
/*================================================*/
void menu_DrawEdgePixel(menu_t *menu, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h)
{
w--;
h--;
u8g2_DrawPixel(menu->u8g2, x,y);
u8g2_DrawPixel(menu->u8g2, x+w,y);
u8g2_DrawPixel(menu->u8g2, x,y+h);
u8g2_DrawPixel(menu->u8g2, x+w,y+h);
}
void menu_ClearEdgePixel(menu_t *menu, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h)
{
u8g2_SetDrawColor(menu->u8g2, 0);
menu_DrawEdgePixel(menu, x, y, w, h);
u8g2_SetDrawColor(menu->u8g2, 1);
}
void menu_DrawBoxFocus(menu_t *menu, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h)
{
u8g2_SetDrawColor(menu->u8g2, 2);
u8g2_DrawBox(menu->u8g2, x, y, w, h);
menu_ClearEdgePixel(menu, x, y, w, h);
}
void menu_DrawFrameFocus(menu_t *menu, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h)
{
menu_DrawEdgePixel(menu, x, y, w, h);
x--;
y--;
w+=2;
h+=2;
u8g2_DrawFrame(menu->u8g2, x, y, w, h);
menu_ClearEdgePixel(menu, x, y, w, h);
}
/*================================================*/
/* this function must be the last function in the list. it also marks the end of a list */
int me_cb_null(menu_t *menu, const me_t *me, uint8_t msg)
{
return 0;
}
/*
Name: me_cb_wd_toggle
Val: uint8_t *
Arg: Not used
*/
int me_cb_big_toggle(menu_t *menu, const me_t *me, uint8_t msg)
{
uint8_t val = *(uint8_t *)(me->val);
u8g2_uint_t x, y, w, h, w2;
w = 16;
w2 = 6;
h = 10;
x = me->x;
y = me->y;
switch(msg)
{
case ME_MSG_IS_FOCUS:
return 1;
case ME_MSG_DRAW_FOCUS:
menu_DrawFrameFocus(menu, x-1, y-1, w+2, h+2);
return 1;
case ME_MSG_SELECT:
{
val++;
if ( val > 1 )
val = 0;
*(uint8_t *)(me->val) = val;
}
return 1;
case ME_MSG_DRAW:
menu_DrawFrameFocus(menu, x+1,y+1,w-2,h-2);
if ( val == 0 )
{
menu_DrawFrameFocus(menu, x+3,y+3,w2-2,h-6);
}
else
{
menu_DrawBoxFocus(menu, x+w/2,y+2,w2,h-4);
}
return 1;
}
return 0;
}
/*
Name: me_cb_wd_toggle
Val: uint8_t *
Arg: char *
*/
int me_cb_wd_toggle(menu_t *menu, const me_t *me, uint8_t msg)
{
uint8_t val = *(uint8_t *)(me->val);
u8g2_uint_t x, y, w, h;
u8g2_SetFont(menu->u8g2, MENU_SMALL_FONT);
w = 13;
h = u8g2_GetAscent(menu->u8g2)+2;
x = me->x-2;
y = me->y - u8g2_GetAscent(menu->u8g2)-1;
switch(msg)
{
case ME_MSG_IS_FOCUS:
return 1;
case ME_MSG_DRAW_FOCUS:
menu_DrawFrameFocus(menu, x, y, w, h);
return 1;
case ME_MSG_SELECT:
{
val++;
if ( val > 1 )
val = 0;
*(uint8_t *)(me->val) = val;
}
return 1;
case ME_MSG_DRAW:
u8g2_DrawUTF8(menu->u8g2, me->x, me->y, (const char *)(me->arg));
if ( val > 0 )
{
menu_DrawBoxFocus(menu, x,y,w,h);
}
//u8g2_DrawRFrame(menu->u8g2, x, y, w, h, 1);
return 1;
}
return 0;
}
/*
Name: me_cb_0_9
Val: uint8_t *
*/
int me_cb_0_9(menu_t *menu, const me_t *me, uint8_t msg)
{
switch(msg)
{
case ME_MSG_IS_FOCUS:
return 1;
case ME_MSG_DRAW_FOCUS:
menu_DrawBoxFocus(menu,
me->x,
me->y - u8g2_GetAscent(menu->u8g2)-1,
u8g2_GetGlyphWidth(menu->u8g2, '0'),
u8g2_GetAscent(menu->u8g2) + 2);
return 1;
case ME_MSG_SELECT:
{
uint8_t val = *(uint8_t *)(me->val);
val++;
if ( val > 9 )
val = 0;
*(uint8_t *)(me->val) = val;
}
return 1;
case ME_MSG_DRAW:
u8g2_SetFont(menu->u8g2, MENU_BIG_NUM);
u8g2_DrawGlyph(menu->u8g2, me->x, me->y, *(uint8_t *)(me->val) + '0');
return 1;
}
return 0;
}
int me_cb_0_9_ro(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_IS_FOCUS )
return 0;
return me_cb_0_9(menu, me, msg);
}
/*
Name: me_cb_0_5
Val: uint8_t *
*/
int me_cb_0_5(menu_t *menu, const me_t *me, uint8_t msg)
{
switch(msg)
{
case ME_MSG_SELECT:
{
uint8_t val = *(uint8_t *)(me->val);
val++;
if ( val > 5 )
val = 0;
*(uint8_t *)(me->val) = val;
}
return 1;
}
return me_cb_0_9(menu, me, msg);
}
/*
Name: me_cb_0_23
Val: uint8_t *
*/
int me_cb_0_23(menu_t *menu, const me_t *me, uint8_t msg)
{
char s[4];
switch(msg)
{
case ME_MSG_IS_FOCUS:
return 1;
case ME_MSG_DRAW_FOCUS:
menu_DrawBoxFocus(menu,
me->x,
me->y - u8g2_GetAscent(menu->u8g2)-1,
u8g2_GetGlyphWidth(menu->u8g2, '0')*2,
u8g2_GetAscent(menu->u8g2) + 2);
return 1;
case ME_MSG_SELECT:
{
uint8_t val = *(uint8_t *)(me->val);
val++;
if ( val > 23 )
val = 0;
*(uint8_t *)(me->val) = val;
}
return 1;
case ME_MSG_DRAW:
u8g2_SetFont(menu->u8g2, MENU_BIG_NUM);
s[0] = *(uint8_t *)(me->val);
s[1] = s[0];
s[1] %= 10;
s[1] += '0';
s[0] /= 10;
s[0] += '0';
s[2] = '\0';
u8g2_DrawUTF8(menu->u8g2, me->x, me->y, s);
return 1;
}
return 0;
}
int me_cb_0_23_ro(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_IS_FOCUS )
return 0;
return me_cb_0_23(menu, me, msg);
}
/*
Name: me_cb_0_55
Val: uint8_t *
*/
int me_cb_0_55(menu_t *menu, const me_t *me, uint8_t msg)
{
switch(msg)
{
case ME_MSG_SELECT:
{
uint8_t val = *(uint8_t *)(me->val);
val+=5;
if ( val > 55 )
val = 0;
*(uint8_t *)(me->val) = val;
}
return 1;
}
return me_cb_0_23(menu, me, msg);
}
/*
Name: me_cb_1_12
Val: uint8_t *
*/
int me_cb_1_12(menu_t *menu, const me_t *me, uint8_t msg)
{
switch(msg)
{
case ME_MSG_SELECT:
{
uint8_t val = *(uint8_t *)(me->val);
val++;
if ( val > 12 )
val = 1;
*(uint8_t *)(me->val) = val;
}
return 1;
}
return me_cb_0_23(menu, me, msg);
}
/*
Name: me_cb_1_31
Val: uint8_t *
*/
int me_cb_1_31(menu_t *menu, const me_t *me, uint8_t msg)
{
switch(msg)
{
case ME_MSG_SELECT:
{
uint8_t val = *(uint8_t *)(me->val);
val++;
if ( val > 31 )
val = 1;
*(uint8_t *)(me->val) = val;
}
return 1;
}
return me_cb_0_23(menu, me, msg);
}
/*
Name: me_cb_label
can not get focus
Arg: char *
*/
int me_cb_num_label(menu_t *menu, const me_t *me, uint8_t msg)
{
switch(msg)
{
case ME_MSG_IS_FOCUS:
case ME_MSG_DRAW_FOCUS:
case ME_MSG_SELECT:
break;
case ME_MSG_DRAW:
u8g2_SetFont(menu->u8g2, MENU_BIG_NUM);
u8g2_DrawUTF8(menu->u8g2, me->x, me->y, (char *)(me->arg) );
return 1;
}
return 0;
}
/*
Name: me_cb_button_full_line
Val: callback function
Arg: char *
*/
int me_cb_button_full_line(menu_t *menu, const me_t *me, uint8_t msg)
{
int r = 0;
switch(msg)
{
case ME_MSG_IS_FOCUS:
return 1;
case ME_MSG_DRAW_FOCUS:
menu_DrawBoxFocus(menu,
0,
me->y - u8g2_GetAscent(menu->u8g2)-1,
u8g2_GetDisplayWidth(menu->u8g2) ,
u8g2_GetAscent(menu->u8g2) - u8g2_GetDescent(menu->u8g2) +1);
r = 1;
break;
case ME_MSG_DRAW:
u8g2_SetFont(menu->u8g2, MENU_NORMAL_FONT);
u8g2_DrawUTF8(menu->u8g2, me->x, me->y, (char *)(me->arg) );
r = 1;
break;
}
/* pass all messages except for the IS_FOCUS also to the callback function */
if ( me->val != NULL )
return ((me_cb)(me->val))(menu, me, msg) | r;
return r;
}
/*
Name: me_cb_button_full_line
Val: callback function
Arg: char *
*/
int me_cb_button_half_line(menu_t *menu, const me_t *me, uint8_t msg)
{
int r = 0;
switch(msg)
{
case ME_MSG_IS_FOCUS:
return 1;
case ME_MSG_DRAW_FOCUS:
menu_DrawBoxFocus(menu,
me->x,
me->y - u8g2_GetAscent(menu->u8g2)-1,
u8g2_GetDisplayWidth(menu->u8g2)/2,
u8g2_GetAscent(menu->u8g2) - u8g2_GetDescent(menu->u8g2) +1);
r = 1;
break;
case ME_MSG_DRAW:
u8g2_SetFont(menu->u8g2, MENU_NORMAL_FONT);
u8g2_DrawUTF8(menu->u8g2, me->x+4, me->y, (char *)(me->arg) );
r = 1;
break;
}
/* pass all messages except for the IS_FOCUS also to the callback function */
if ( me->val != NULL )
return ((me_cb)(me->val))(menu, me, msg) | r;
return r;
}
/*
Name: me_cb_button_empty
Val: callback function
Arg: not used
*/
int me_cb_button_empty(menu_t *menu, const me_t *me, uint8_t msg)
{
if ( msg == ME_MSG_IS_FOCUS )
return 1;
if ( me->val != NULL )
return ((me_cb)(me->val))(menu, me, msg);
return 0;
}
/*
Name: me_cb_label
can not get focus
Arg: char *
*/
int me_cb_label(menu_t *menu, const me_t *me, uint8_t msg)
{
switch(msg)
{
case ME_MSG_IS_FOCUS:
case ME_MSG_DRAW_FOCUS:
case ME_MSG_SELECT:
break;
case ME_MSG_DRAW:
u8g2_SetFont(menu->u8g2, MENU_NORMAL_FONT);
u8g2_DrawUTF8(menu->u8g2, me->x, me->y, (char *)(me->arg) );
return 1;
}
return 0;
}
/*
Name: me_cb_button_full_line
Val: callback function
Arg: bitmap
*/
int me_cb_16x16_bitmap_button(menu_t *menu, const me_t *me, uint8_t msg)
{
int r = 0;
switch(msg)
{
case ME_MSG_IS_FOCUS:
return 1;
case ME_MSG_DRAW_FOCUS:
menu_DrawFrameFocus(menu,
me->x-1,
me->y-1,
16+2,
16+2);
r = 1;
break;
case ME_MSG_DRAW:
u8g2_DrawXBM(menu->u8g2, me->x, me->y, 16, 16, (const uint8_t *)(me->arg));
r = 1;
break;
}
/* pass all messages except for the IS_FOCUS also to the callback function */
if ( me->val != NULL )
return ((me_cb)(me->val))(menu, me, msg) | r;
return r;
}
/*================================================*/
/* call menu element from menu->current_index */
int menu_CallME(menu_t *menu, uint8_t msg)
{
const me_t *me;
me = menu->me_list+menu->current_index;
return me->cb(menu, me, msg);
}
/* stay on current focus if valid, move to next valid focus */
static void menu_CalcNextValidFocus(menu_t *menu) U8G2_NOINLINE;
static void menu_CalcNextValidFocus(menu_t *menu)
{
for(;;)
{
menu->current_index = menu->focus_index;
if ( menu->current_index >= menu->me_count )
break;
if ( menu_CallME(menu, ME_MSG_IS_FOCUS) != 0 )
break;
menu->focus_index++;
}
}
/* advance current focus to the next element */
void menu_NextFocus(menu_t *menu)
{
menu->focus_index++;
if ( menu->focus_index >= menu->me_count )
menu->focus_index = 0;
menu_CalcNextValidFocus(menu);
}
/* send select message to the element which has the current focus */
void menu_Select(menu_t *menu)
{
menu->current_index = menu->focus_index;
menu_CallME(menu, ME_MSG_SELECT);
}
void menu_SetMEList(menu_t *menu, const me_t *me_list, uint16_t initial_focus)
{
menu->me_list = me_list;
menu->me_count = 0;
while( me_list[menu->me_count].cb != me_cb_null )
menu->me_count++;
menu->focus_index = 0;
menu_CalcNextValidFocus(menu);
while( initial_focus > 0 )
{
menu_NextFocus(menu);
initial_focus--;
}
menu->radio_index = menu->me_count;
}
me_t melist_emty[] =
{
{ me_cb_null, NULL, 0, 0 }
};
void menu_Init(menu_t *menu, u8g2_t *u8g2)
{
menu->u8g2 = u8g2;
menu_SetMEList(menu, melist_emty, 0);
}
void menu_Draw(menu_t *menu)
{
for( menu->current_index = 0; menu->current_index < menu->me_count; menu->current_index++ )
{
menu_CallME(menu, ME_MSG_DRAW);
if ( menu->current_index == menu->focus_index )
{
menu_CallME(menu, ME_MSG_DRAW_FOCUS);
}
}
u8g2_DrawHLine(menu->u8g2, 0, 32, 128);
}

View File

@@ -0,0 +1,87 @@
#ifndef _MENU_H
#define _MENU_H
#include "u8g2.h"
#define MENU_SMALL_FONT u8g2_font_baby_tr
#define MENU_NORMAL_FONT u8g2_font_ncenR08_tf
#define MENU_BIG_NUM u8g2_font_ncenR18_tf
typedef struct _menu_struct menu_t;
typedef struct _me_struct me_t;
typedef int (*me_cb)(menu_t *menu, const me_t *me, uint8_t msg);
struct _me_struct
{
me_cb cb;
void *val;
void *arg;
u8g2_uint_t x;
u8g2_uint_t y;
};
/* return 1, if this element can have focus */
#define ME_MSG_IS_FOCUS 1
/* draw focus graphics for the element */
#define ME_MSG_DRAW_FOCUS 2
/* user has pressed the select key */
#define ME_MSG_SELECT 3
/* advice for drawing */
#define ME_MSG_DRAW 4
struct _menu_struct
{
u8g2_t *u8g2;
volatile uint16_t current_index; /* element which is processed right now */
uint16_t focus_index; /* element which has the focus at the moment */
uint16_t radio_index; /* if elements for a radio selection, then this is set by the cb */
uint16_t me_count; /* total number of elements in the list */
/* pointer to the list of menu elements */
const me_t *me_list;
};
void menu_SetEdgePixel(menu_t *menu, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h) U8G2_NOINLINE;
void menu_ClearEdgePixel(menu_t *menu, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h) U8G2_NOINLINE;
void menu_DrawBoxFocus(menu_t *menu, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h) U8G2_NOINLINE;
void menu_DrawFrameFocus(menu_t *menu, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h) U8G2_NOINLINE;
void menu_Init(menu_t *menu, u8g2_t *u8g2);
void menu_SetMEList(menu_t *menu, const me_t *me_list, uint16_t initial_focus);
void menu_Draw(menu_t *menu);
void menu_NextFocus(menu_t *menu);
void menu_Select(menu_t *menu);
int me_cb_null(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_big_toggle(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_wd_toggle(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_0_5(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_0_9(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_0_9_ro(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_0_23(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_0_23_ro(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_0_55(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_1_12(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_1_31(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_num_label(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_button_full_line(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_button_half_line(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_button_empty(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_label(menu_t *menu, const me_t *me, uint8_t msg);
int me_cb_16x16_bitmap_button(menu_t *menu, const me_t *me, uint8_t msg);
#endif

View File

@@ -0,0 +1,12 @@
CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) main.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

View File

@@ -0,0 +1,44 @@
#include "u8g2.h"
#include <stdio.h>
u8g2_t u8g2;
int main(void)
{
u8g2_SetupBuffer_SDL_128x64_4(&u8g2, &u8g2_cb_r0);
u8x8_InitDisplay(u8g2_GetU8x8(&u8g2));
u8x8_SetPowerSave(u8g2_GetU8x8(&u8g2), 0);
//u8g2_SetFont(&u8g2, u8g2_font_helvB08_tr);
u8g2_SetFont(&u8g2, u8g2_font_6x10_tr);
u8g2_SetFontDirection(&u8g2, 0);
u8g2_SetFontRefHeightAll(&u8g2);
u8g2_UserInterfaceMessage(&u8g2, "title1", "title2", "title3", " Yes \n No ");
/*
do
{
k = u8g_sdl_get_key();
} while( k < 0 );
if ( k == 273 ) y -= 7;
if ( k == 274 ) y += 7;
if ( k == 276 ) x -= 7;
if ( k == 275 ) x += 7;
if ( k == 'e' ) y -= 1;
if ( k == 'x' ) y += 1;
if ( k == 's' ) x -= 1;
if ( k == 'd' ) x += 1;
if ( k == 'q' ) break;
*/
return 0;
}

View File

@@ -0,0 +1,12 @@
CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) main.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

View File

@@ -0,0 +1,25 @@
/*
Example for the
u8x8_UserInterfaceMessage
procedure.
*/
#include "u8x8.h"
u8x8_t u8x8;
int main(void)
{
u8x8_Setup_SDL_128x64(&u8x8);
u8x8_InitDisplay(&u8x8);
u8x8_SetFont(&u8x8, u8x8_font_amstrad_cpc_extended_f);
u8x8_UserInterfaceMessage(&u8x8, "title1", "title2", "title3", "Yes\nNo");
return 0;
}

View File

@@ -0,0 +1,12 @@
CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) main.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

View File

@@ -0,0 +1,45 @@
#include "u8g2.h"
#include <stdio.h>
u8g2_t u8g2;
int main(void)
{
//u8g2_SetupBuffer_SDL_128x64_4(&u8g2, &u8g2_cb_r0);
u8g2_SetupBuffer_SDL_240x160(&u8g2, &u8g2_cb_r0);
u8x8_InitDisplay(u8g2_GetU8x8(&u8g2));
u8x8_SetPowerSave(u8g2_GetU8x8(&u8g2), 0);
u8g2_SetFont(&u8g2, u8g2_font_helvB08_tr);
u8g2_SetFontDirection(&u8g2, 0);
u8g2_SetFontRefHeightAll(&u8g2);
u8g2_UserInterfaceSelectionList(&u8g2, "Title", 0, "abc\ndef\nghi\njkl\n12345\n67890\nabcdefg\nxyz\n111\n222\n333\n444");
/*
do
{
k = u8g_sdl_get_key();
} while( k < 0 );
if ( k == 273 ) y -= 7;
if ( k == 274 ) y += 7;
if ( k == 276 ) x -= 7;
if ( k == 275 ) x += 7;
if ( k == 'e' ) y -= 1;
if ( k == 'x' ) y += 1;
if ( k == 's' ) x -= 1;
if ( k == 'd' ) x += 1;
if ( k == 'q' ) break;
*/
return 0;
}

View File

@@ -0,0 +1,12 @@
CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) main.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

View File

@@ -0,0 +1,25 @@
/*
Example for the
u8x8_UserInterfaceSelectionList
procedure.
*/
#include "u8x8.h"
u8x8_t u8x8;
int main(void)
{
u8x8_Setup_SDL_128x64(&u8x8);
u8x8_InitDisplay(&u8x8);
u8x8_SetFont(&u8x8, u8x8_font_amstrad_cpc_extended_f);
u8x8_UserInterfaceSelectionList(&u8x8, "Title", 1, "abc\ndef\nghi\njkl\nmno");
return 0;
}

View File

@@ -0,0 +1,12 @@
CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) main.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,12 @@
CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) main.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

View File

@@ -0,0 +1,88 @@
#include "u8g2.h"
#include <stdio.h>
u8g2_t u8g2;
int main(void)
{
int x, y;
int k;
int i;
u8g2_SetupBuffer_SDL_128x64_4(&u8g2, &u8g2_cb_r0);
u8x8_InitDisplay(u8g2_GetU8x8(&u8g2));
u8x8_SetPowerSave(u8g2_GetU8x8(&u8g2), 0);
u8g2_SetFont(&u8g2, u8g2_font_helvB18_tr);
x = 50;
y = 30;
for(;;)
{
#ifdef U8G2_WITH_HVLINE_COUNT
u8g2.hv_cnt = 0UL;
#endif /* U8G2_WITH_HVLINE_COUNT */
/*
u8g2_ClearBuffer(&u8g2);
u8g2_SetFontDirection(&u8g2, 0);
u8g2_DrawStr(&u8g2, x, y, "ABC");
u8g2_SetFontDirection(&u8g2, 1);
u8g2_DrawStr(&u8g2, x, y, "abc");
u8g2_SetFontDirection(&u8g2, 2);
u8g2_DrawStr(&u8g2, x, y, "abc");
u8g2_SetFontDirection(&u8g2, 3);
u8g2_DrawStr(&u8g2, x, y, "abc");
u8g2_SendBuffer(&u8g2);
*/
u8g2_FirstPage(&u8g2);
i = 0;
do
{
u8g2_SetFontDirection(&u8g2, 0);
u8g2_DrawUTF8(&u8g2, x, y, "AB");
u8g2_DrawUTF8(&u8g2, x+u8g2_GetUTF8Width(&u8g2, "AB"), y, "cde");
i++;
} while( u8g2_NextPage(&u8g2) );
#ifdef U8G2_WITH_HVLINE_COUNT
printf("hv cnt: %ld\n", u8g2.hv_cnt);
#endif /* U8G2_WITH_HVLINE_COUNT */
do
{
k = u8g_sdl_get_key();
} while( k < 0 );
if ( k == 273 ) y -= 7;
if ( k == 274 ) y += 7;
if ( k == 276 ) x -= 7;
if ( k == 275 ) x += 7;
if ( k == 'e' ) y -= 1;
if ( k == 'x' ) y += 1;
if ( k == 's' ) x -= 1;
if ( k == 'd' ) x += 1;
if ( k == 'q' ) break;
}
//u8x8_Set8x8Font(u8g2_GetU8x8(&u8g2), bdf_font);
//u8x8_Draw8x8String(u8g2_GetU8x8(&u8g2), 0, 0, "Hello World!");
return 0;
}

View File

@@ -0,0 +1,12 @@
CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) main.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

View File

@@ -0,0 +1,26 @@
#include "u8x8.h"
u8x8_t u8x8;
int main(void)
{
u8x8_Setup_SDL_128x64(&u8x8);
u8x8_InitDisplay(&u8x8);
u8x8_SetFont(&u8x8, u8x8_font_px437wyse700a_2x2_r);
u8x8_SetFont(&u8x8, u8x8_font_courB24_3x4_f);
//u8x8_DrawString(&u8x8, 0, 0, "abc");
//u8x8_Draw1x2String(&u8x8, 0, 4, "abc");
u8x8_Draw2x2String(&u8x8, 0, 0, "Abcd");
while( u8g_sdl_get_key() < 0 )
;
return 0;
}

View File

@@ -0,0 +1,12 @@
CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) ../../bitmap/common/u8x8_d_bitmap.c $(shell ls ../common/*.c ) main.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

View File

@@ -0,0 +1,124 @@
#include "u8g2.h"
#include <stdio.h>
u8g2_t u8g2;
void stdout_string(const char *s)
{
printf("%s", s);
}
int main(void)
{
int x, y;
int k;
//u8g2_SetupBuffer_SDL_240x160(&u8g2, &u8g2_cb_r0);
u8g2_SetupBuffer_SDL_128x64(&u8g2, &u8g2_cb_r0);
//u8x8_ConnectBitmapToU8x8(u8g2_GetU8x8(&u8g2)); /* connect to bitmap */
u8x8_InitDisplay(u8g2_GetU8x8(&u8g2));
u8x8_SetPowerSave(u8g2_GetU8x8(&u8g2), 0);
u8g2_SetFont(&u8g2, u8g2_font_helvB18_tr);
x = 30;
y = 35;
for(;;)
{
#ifdef U8G2_WITH_HVLINE_COUNT
u8g2.hv_cnt = 0UL;
#endif /* U8G2_WITH_HVLINE_COUNT */
u8g2_ClearBuffer(&u8g2);
u8g2_SetFontDirection(&u8g2, 0);
u8g2_DrawStr(&u8g2, x, y, "A");
u8g2_SetFontDirection(&u8g2, 1);
u8g2_DrawStr(&u8g2, x, y, "a");
u8g2_SetFontDirection(&u8g2, 2);
u8g2_DrawStr(&u8g2, x, y, "a");
u8g2_SetFontDirection(&u8g2, 3);
u8g2_DrawStr(&u8g2, x, y, "a");
u8g2_DrawHVLine(&u8g2, u8g2.user_x0, u8g2.user_y0, 1, 0);
u8g2_DrawHVLine(&u8g2, u8g2.user_x0, u8g2.user_y1-1, 1, 0);
u8g2_DrawHVLine(&u8g2, u8g2.user_x1-1, u8g2.user_y1-1, 1, 0);
u8g2_DrawHVLine(&u8g2, u8g2.user_x1-1, u8g2.user_y0, 1, 0);
//u8g2_DrawFilledEllipse(&u8g2, x, y, 23, 27, U8G2_DRAW_UPPER_LEFT | U8G2_DRAW_LOWER_LEFT);
u8g2_SendBuffer(&u8g2);
/*
u8g2_FirstPage(&u8g2);
i = 0;
do
{
u8g2_SetFontDirection(&u8g2, 0);
u8g2_DrawStr(&u8g2, x, y, "ABC");
u8g2_SetFontDirection(&u8g2, 1);
u8g2_DrawStr(&u8g2, x, y, "abc");
u8g2_SetFontDirection(&u8g2, 2);
u8g2_DrawStr(&u8g2, x, y, "abc");
u8g2_SetFontDirection(&u8g2, 3);
u8g2_DrawStr(&u8g2, x, y, "abc");
if ( i == 1 )
{
u8g2_DrawHVLine(&u8g2, u8g2.user_x0, u8g2.user_y0, 1, 0);
u8g2_DrawHVLine(&u8g2, u8g2.user_x0, u8g2.user_y1-1, 1, 0);
u8g2_DrawHVLine(&u8g2, u8g2.user_x1-1, u8g2.user_y1-1, 1, 0);
u8g2_DrawHVLine(&u8g2, u8g2.user_x1-1, u8g2.user_y0, 1, 0);
}
i++;
} while( u8g2_NextPage(&u8g2) );
*/
#ifdef U8G2_WITH_HVLINE_COUNT
printf("hv cnt: %ld\n", u8g2.hv_cnt);
#endif /* U8G2_WITH_HVLINE_COUNT */
do
{
k = u8g_sdl_get_key();
} while( k < 0 );
if ( k == 273 ) y -= 7;
if ( k == 274 ) y += 7;
if ( k == 276 ) x -= 7;
if ( k == 275 ) x += 7;
if ( k == 'e' ) y -= 1;
if ( k == 'x' ) y += 1;
if ( k == 's' ) x -= 1;
if ( k == 'd' ) x += 1;
if ( k == 'q' ) break;
if ( k == 'c' )
u8g2_WriteBufferPBM(&u8g2, stdout_string);
if ( k == 'b' )
u8g2_WriteBufferXBM(&u8g2, stdout_string);
//if ( k == 't' )
// u8x8_SaveBitmapTGA(u8g2_GetU8x8(&u8g2), "screenshot.tga");
}
//u8x8_Set8x8Font(u8g2_GetU8x8(&u8g2), bdf_font);
//u8x8_Draw8x8String(u8g2_GetU8x8(&u8g2), 0, 0, "Hello World!");
return 0;
}

View File

@@ -0,0 +1,12 @@
CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) main.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

View File

@@ -0,0 +1,158 @@
#include "u8g2.h"
#include <stdio.h>
u8g2_t u8g2;
static const uint16_t helv_first_encoding_table[50] = {
65, 67, 70, 75, 76, 80, 84, 86, 87, 88, 89, 97, 98, 99, 101, 103, 104,
107, 109, 110, 111, 112, 113, 114, 115, 117, 118, 119, 120, 121, 122, 192, 193,
194, 195, 196, 197, 199, 215, 221, 222, 224, 230, 231, 232, 242, 248, 249, 254,
65535};
static const uint16_t helv_index_to_second_table[50] = {
0, 7, 9, 19, 39, 47, 56, 92, 101, 109, 112, 135, 138, 141, 142, 145, 146,
150, 151, 154, 158, 161, 164, 165, 169, 172, 173, 176, 177, 178, 181, 182, 189,
196, 203, 210, 217, 224, 226, 229, 252, 255, 258, 261, 262, 265, 268, 269, 270,
273};
static const uint16_t helv_second_encoding_table[273] = {
84, 86, 87, 89, 121, 221, 253, 121, 253, 65, 74, 122, 192, 193, 194, 195, 196,
197, 198, 67, 71, 79, 81, 116, 117, 118, 119, 121, 199, 210, 211, 212, 213,
214, 249, 250, 251, 252, 253, 84, 86, 87, 89, 118, 121, 221, 253, 65, 74,
192, 193, 194, 195, 196, 197, 198, 65, 74, 97, 99, 100, 101, 103, 109, 110,
111, 112, 113, 114, 115, 117, 118, 119, 120, 121, 122, 192, 193, 194, 195, 196,
197, 198, 215, 225, 230, 231, 233, 243, 248, 250, 253, 65, 74, 192, 193, 194,
195, 196, 197, 198, 65, 192, 193, 194, 195, 196, 197, 198, 118, 121, 253, 65,
74, 97, 99, 100, 101, 103, 111, 113, 192, 193, 194, 195, 196, 197, 198, 225,
229, 230, 231, 233, 243, 248, 84, 89, 221, 84, 89, 221, 84, 84, 89, 221,
84, 84, 86, 89, 221, 84, 84, 89, 221, 84, 86, 89, 221, 84, 89, 221,
84, 89, 221, 84, 74, 84, 88, 90, 84, 89, 221, 84, 84, 88, 90, 84,
84, 84, 88, 90, 84, 84, 86, 87, 89, 121, 221, 253, 84, 86, 87, 89,
121, 221, 253, 84, 86, 87, 89, 121, 221, 253, 84, 86, 87, 89, 121, 221,
253, 84, 86, 87, 89, 121, 221, 253, 84, 86, 87, 89, 121, 221, 253, 121,
253, 84, 89, 221, 65, 74, 97, 99, 100, 101, 103, 111, 113, 192, 193, 194,
195, 196, 197, 198, 225, 229, 230, 231, 233, 243, 248, 84, 88, 90, 84, 89,
221, 84, 89, 221, 84, 84, 89, 221, 84, 89, 221, 84, 84, 84, 89, 221};
static const uint8_t helv_kerning_values[273] = {
2, 2, 1, 3, 1, 3, 1, 1, 1, 1, 5, 3, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 3, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 3, 2, 3, 1, 3, 1, 3, 3, 3, 1, 5,
1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3,
2, 3, 2, 3, 2, 3, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2,
2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
3, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 1,
1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 1,
3, 3, 1, 2, 2, 2, 3, 1, 1, 3, 1, 2, 2, 2, 1, 1,
2, 1, 1, 3, 1, 2, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1,
2, 2, 1, 1, 2, 2, 2, 1, 3, 1, 3, 1, 2, 2, 1, 3,
1, 3, 1, 2, 2, 1, 3, 1, 3, 1, 2, 2, 1, 3, 1, 3,
1, 2, 2, 1, 3, 1, 3, 1, 2, 2, 1, 3, 1, 3, 1, 1,
1, 3, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3,
3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1,
1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1};
u8g2_kerning_t helv = {
50, 273,
helv_first_encoding_table,
helv_index_to_second_table,
helv_second_encoding_table,
helv_kerning_values};
int main(void)
{
int x, y;
int k;
int i;
u8g2_SetupBuffer_SDL_128x64_4(&u8g2, &u8g2_cb_r0);
u8x8_InitDisplay(u8g2_GetU8x8(&u8g2));
u8x8_SetPowerSave(u8g2_GetU8x8(&u8g2), 0);
//u8g2_SetFont(&u8g2, u8g2_font_helvB18_tr);
u8g2_SetFont(&u8g2, u8g2_font_helvB18_tf);
x = 50;
y = 30;
for(;;)
{
#ifdef U8G2_WITH_HVLINE_COUNT
u8g2.hv_cnt = 0UL;
#endif /* U8G2_WITH_HVLINE_COUNT */
/*
u8g2_ClearBuffer(&u8g2);
u8g2_SetFontDirection(&u8g2, 0);
u8g2_DrawStr(&u8g2, x, y, "ABC");
u8g2_SetFontDirection(&u8g2, 1);
u8g2_DrawStr(&u8g2, x, y, "abc");
u8g2_SetFontDirection(&u8g2, 2);
u8g2_DrawStr(&u8g2, x, y, "abc");
u8g2_SetFontDirection(&u8g2, 3);
u8g2_DrawStr(&u8g2, x, y, "abc");
u8g2_SendBuffer(&u8g2);
*/
u8g2.kerning = &helv;
u8g2.get_kerning_cb = u8g2_GetKerning;
u8g2_FirstPage(&u8g2);
i = 0;
do
{
u8g2_SetFontDirection(&u8g2, 0);
u8g2_DrawUTF8(&u8g2, x, y, "WAV");
u8g2_SetFontDirection(&u8g2, 1);
u8g2_DrawUTF8(&u8g2, x, y, "WAV");
u8g2_SetFontDirection(&u8g2, 2);
u8g2_DrawUTF8(&u8g2, x, y, "WAV");
u8g2_SetFontDirection(&u8g2, 3);
u8g2_DrawUTF8(&u8g2, x, y, "WAV");
if ( i == 1 )
{
u8g2_DrawHVLine(&u8g2, u8g2.user_x0, u8g2.user_y0, 1, 0);
u8g2_DrawHVLine(&u8g2, u8g2.user_x0, u8g2.user_y1-1, 1, 0);
u8g2_DrawHVLine(&u8g2, u8g2.user_x1-1, u8g2.user_y1-1, 1, 0);
u8g2_DrawHVLine(&u8g2, u8g2.user_x1-1, u8g2.user_y0, 1, 0);
}
i++;
} while( u8g2_NextPage(&u8g2) );
#ifdef U8G2_WITH_HVLINE_COUNT
printf("hv cnt: %ld\n", u8g2.hv_cnt);
#endif /* U8G2_WITH_HVLINE_COUNT */
do
{
k = u8g_sdl_get_key();
} while( k < 0 );
if ( k == 273 ) y -= 7;
if ( k == 274 ) y += 7;
if ( k == 276 ) x -= 7;
if ( k == 275 ) x += 7;
if ( k == 'e' ) y -= 1;
if ( k == 'x' ) y += 1;
if ( k == 's' ) x -= 1;
if ( k == 'd' ) x += 1;
if ( k == 'q' ) break;
}
//u8x8_Set8x8Font(u8g2_GetU8x8(&u8g2), bdf_font);
//u8x8_Draw8x8String(u8g2_GetU8x8(&u8g2), 0, 0, "Hello World!");
return 0;
}

View File

@@ -0,0 +1,12 @@
CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) main.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,12 @@
CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) main.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

View File

@@ -0,0 +1,106 @@
#include "u8g2.h"
#include <stdio.h>
u8g2_t u8g2;
const uint16_t my_kerning_table[] =
{
/* first char, second char, gap reduction value */
0x646, 0x627, 4, /* ن and ا */
0x627, 0x647, 5, /* ا and ه */
0x647, 0x62C, 6, /* ه and ج */
0x645, 0x627, 3, /* م and ا */
0x627, 0x644, 4, /* ا and ل */
0x644, 0x633, 2, /* ل and س */
/* this line terminates the table */
0xffff, 0xffff, 0xffff
};
int main(void)
{
int x, y;
int k;
int i;
u8g2_SetupBuffer_SDL_128x64_4(&u8g2, &u8g2_cb_r0);
u8x8_InitDisplay(u8g2_GetU8x8(&u8g2));
u8x8_SetPowerSave(u8g2_GetU8x8(&u8g2), 0);
//u8g2_SetFont(&u8g2, u8g2_font_helvB18_tr);
x = 50;
y = 30;
for(;;)
{
#ifdef U8G2_WITH_HVLINE_COUNT
u8g2.hv_cnt = 0UL;
#endif /* U8G2_WITH_HVLINE_COUNT */
/*
u8g2_ClearBuffer(&u8g2);
u8g2_SetFontDirection(&u8g2, 0);
u8g2_DrawStr(&u8g2, x, y, "ABC");
u8g2_SetFontDirection(&u8g2, 1);
u8g2_DrawStr(&u8g2, x, y, "abc");
u8g2_SetFontDirection(&u8g2, 2);
u8g2_DrawStr(&u8g2, x, y, "abc");
u8g2_SetFontDirection(&u8g2, 3);
u8g2_DrawStr(&u8g2, x, y, "abc");
u8g2_SendBuffer(&u8g2);
*/
//u8g2_SetFont(&u8g2, u8g2_font_cu12_t_arabic);
u8g2_SetFont(&u8g2, u8g2_font_unifont_t_arabic);
u8g2_FirstPage(&u8g2);
i = 0;
do
{
u8g2_SetFontDirection(&u8g2, 0);
u8g2_DrawExtUTF8(&u8g2, x, y, 1, NULL, "سلام جهان");
u8g2_DrawExtUTF8(&u8g2, x, y+20, 1, my_kerning_table, "سلام جهان");
i++;
} while( u8g2_NextPage(&u8g2) );
#ifdef U8G2_WITH_HVLINE_COUNT
printf("hv cnt: %ld\n", u8g2.hv_cnt);
#endif /* U8G2_WITH_HVLINE_COUNT */
do
{
k = u8g_sdl_get_key();
} while( k < 0 );
if ( k == 273 ) y -= 7;
if ( k == 274 ) y += 7;
if ( k == 276 ) x -= 7;
if ( k == 275 ) x += 7;
if ( k == 'e' ) y -= 1;
if ( k == 'x' ) y += 1;
if ( k == 's' ) x -= 1;
if ( k == 'd' ) x += 1;
if ( k == 'q' ) break;
}
//u8x8_Set8x8Font(u8g2_GetU8x8(&u8g2), bdf_font);
//u8x8_Draw8x8String(u8g2_GetU8x8(&u8g2), 0, 0, "Hello World!");
return 0;
}

View File

@@ -0,0 +1,12 @@
CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) main.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

View File

@@ -0,0 +1,100 @@
#include "u8g2.h"
#include <stdio.h>
u8g2_t u8g2;
const uint16_t my_kerning_table[] =
{
/* first char, second char, gap reduction value */
0x0E17, 0x0E34, 14, /* ท and ิ */
/* add more pairs here... */
/* this line terminates the table */
0xffff, 0xffff, 0xffff
};
int main(void)
{
int x, y;
int k;
int i;
u8g2_SetupBuffer_SDL_128x64_4(&u8g2, &u8g2_cb_r0);
u8x8_InitDisplay(u8g2_GetU8x8(&u8g2));
u8x8_SetPowerSave(u8g2_GetU8x8(&u8g2), 0);
//u8g2_SetFont(&u8g2, u8g2_font_helvB18_tr);
x = 50;
y = 30;
for(;;)
{
#ifdef U8G2_WITH_HVLINE_COUNT
u8g2.hv_cnt = 0UL;
#endif /* U8G2_WITH_HVLINE_COUNT */
/*
u8g2_ClearBuffer(&u8g2);
u8g2_SetFontDirection(&u8g2, 0);
u8g2_DrawStr(&u8g2, x, y, "ABC");
u8g2_SetFontDirection(&u8g2, 1);
u8g2_DrawStr(&u8g2, x, y, "abc");
u8g2_SetFontDirection(&u8g2, 2);
u8g2_DrawStr(&u8g2, x, y, "abc");
u8g2_SetFontDirection(&u8g2, 3);
u8g2_DrawStr(&u8g2, x, y, "abc");
u8g2_SendBuffer(&u8g2);
*/
u8g2_SetFont(&u8g2, u8g2_font_etl24thai_t);
u8g2_FirstPage(&u8g2);
i = 0;
do
{
u8g2_SetFontDirection(&u8g2, 0);
u8g2_DrawExtUTF8(&u8g2, x, y, 0, NULL, "[ทิ]");
u8g2_DrawExtUTF8(&u8g2, x, y+20, 0, my_kerning_table, "[ทิ]");
i++;
} while( u8g2_NextPage(&u8g2) );
#ifdef U8G2_WITH_HVLINE_COUNT
printf("hv cnt: %ld\n", u8g2.hv_cnt);
#endif /* U8G2_WITH_HVLINE_COUNT */
do
{
k = u8g_sdl_get_key();
} while( k < 0 );
if ( k == 273 ) y -= 7;
if ( k == 274 ) y += 7;
if ( k == 276 ) x -= 7;
if ( k == 275 ) x += 7;
if ( k == 'e' ) y -= 1;
if ( k == 'x' ) y += 1;
if ( k == 's' ) x -= 1;
if ( k == 'd' ) x += 1;
if ( k == 'q' ) break;
}
//u8x8_Set8x8Font(u8g2_GetU8x8(&u8g2), bdf_font);
//u8x8_Draw8x8String(u8g2_GetU8x8(&u8g2), 0, 0, "Hello World!");
return 0;
}

View File

@@ -0,0 +1,12 @@
CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags` -fsanitize=address -fsanitize=undefined -fsanitize=bounds-strict -fsanitize=object-size
SRC = $(shell ls ../../../csrc/*.c) ../../bitmap/common/u8x8_d_bitmap.c $(shell ls ../common/*.c ) main.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

View File

@@ -0,0 +1,105 @@
#include "u8g2.h"
#include <stdio.h>
u8g2_t u8g2;
int main(void)
{
int x, y;
int k;
int i;
u8g2_SetupBuffer_SDL_128x64_4(&u8g2, &u8g2_cb_r0);
u8x8_ConnectBitmapToU8x8(u8g2_GetU8x8(&u8g2)); /* connect to bitmap */
u8x8_InitDisplay(u8g2_GetU8x8(&u8g2));
u8x8_SetPowerSave(u8g2_GetU8x8(&u8g2), 0);
u8g2_SetFont(&u8g2, u8g2_font_helvB12_tr);
x = 50;
y = 30;
for(;;)
{
#ifdef U8G2_WITH_HVLINE_COUNT
u8g2.hv_cnt = 0UL;
#endif /* U8G2_WITH_HVLINE_COUNT */
/*
u8g2_ClearBuffer(&u8g2);
u8g2_SetFontDirection(&u8g2, 0);
u8g2_DrawStr(&u8g2, x, y, "ABC");
u8g2_SetFontDirection(&u8g2, 1);
u8g2_DrawStr(&u8g2, x, y, "abc");
u8g2_SetFontDirection(&u8g2, 2);
u8g2_DrawStr(&u8g2, x, y, "abc");
u8g2_SetFontDirection(&u8g2, 3);
u8g2_DrawStr(&u8g2, x, y, "abc");
u8g2_SendBuffer(&u8g2);
*/
u8g2_FirstPage(&u8g2);
i = 0;
do
{
u8g2_SetFontDirection(&u8g2, 0);
u8g2_DrawStr(&u8g2, x, y, "ABC");
u8g2_SetFontDirection(&u8g2, 1);
u8g2_DrawStr(&u8g2, x, y, "abc");
u8g2_SetFontDirection(&u8g2, 2);
u8g2_DrawStr(&u8g2, x, y, "abc");
u8g2_SetFontDirection(&u8g2, 3);
u8g2_DrawStr(&u8g2, x, y, "abc");
if ( i == 1 )
{
u8g2_DrawHVLine(&u8g2, u8g2.user_x0, u8g2.user_y0, 1, 0);
u8g2_DrawHVLine(&u8g2, u8g2.user_x0, u8g2.user_y1-1, 1, 0);
u8g2_DrawHVLine(&u8g2, u8g2.user_x1-1, u8g2.user_y1-1, 1, 0);
u8g2_DrawHVLine(&u8g2, u8g2.user_x1-1, u8g2.user_y0, 1, 0);
}
i++;
} while( u8g2_NextPage(&u8g2) );
#ifdef U8G2_WITH_HVLINE_COUNT
printf("hv cnt: %ld\n", u8g2.hv_cnt);
#endif /* U8G2_WITH_HVLINE_COUNT */
do
{
k = u8g_sdl_get_key();
} while( k < 0 );
if ( k == 273 ) y -= 7;
if ( k == 274 ) y += 7;
if ( k == 276 ) x -= 7;
if ( k == 275 ) x += 7;
if ( k == 'e' ) y -= 1;
if ( k == 'x' ) y += 1;
if ( k == 's' ) x -= 1;
if ( k == 'd' ) x += 1;
if ( k == 'q' ) break;
if ( k == 't' )
u8x8_SaveBitmapTGA(u8g2_GetU8x8(&u8g2), "screenshot.tga");
}
//u8x8_Set8x8Font(u8g2_GetU8x8(&u8g2), bdf_font);
//u8x8_Draw8x8String(u8g2_GetU8x8(&u8g2), 0, 0, "Hello World!");
return 0;
}

View File

@@ -0,0 +1,12 @@
CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags`
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) main.c
OBJ = $(SRC:.c=.o)
helloworld: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl
clean:
-rm $(OBJ) u8g2_sdl

Some files were not shown because too many files have changed in this diff Show More