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,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;
}