| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518 |
- /*
- spacetrash
-
- A game, which should runs on all displays.
- Copyright (c) 2012, olikraus@gmail.com
- Copyright (c) 2018, olikraus@gmail.com
- All rights reserved.
- Redistribution and use in source and binary forms, with or without modification,
- are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this list
- of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright notice, this
- list of conditions and the following disclaimer in the documentation and/or other
- materials provided with the distribution.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #include "u8g2.h"
- #include <stdlib.h> // rand
- #include <unistd.h> // usleep
- #define ST_FP 4
- /* object types */
- struct _st_ot_struct
- {
- /*
- missle and hit:
- bit 0: player missle and trash
- bit 1: trash, which might hit the player
- */
-
- uint8_t missle_mask; /* this object is a missle: it might destroy something if the target is_hit_fn says so */
- uint8_t hit_mask; /* if missle_mask & hit_mask is != 0 then the object can be destroyed */
- uint8_t points;
- uint8_t draw_fn;
- uint8_t move_fn;
- /* ST_MOVE_FN_NONE, ST_MOVE_FN_X_SLOW */
- uint8_t destroy_fn; /* object can be destroyed by a missle (e.g. a missle from the space ship) */
- /* ST_DESTROY_FN_NONE, ST_DESTROY_FN_SPLIT */
- uint8_t is_hit_fn; /* is hit procedure */
- /* ST_IS_HIT_FN_NONE, ST_IS_HIT_BBOX */
- uint8_t fire_fn;
- /* ST_FIRE_FN_NONE, ST_FIRE_FN_X_LEFT */
-
- };
- typedef struct _st_ot_struct st_ot;
- /*
- objects, which are visible at the play area
- */
- struct _st_obj_struct
- {
- uint8_t ot; /* object type: zero means, object is not used */
- int8_t tmp; /* generic value, used by ST_MOVE_IMPLODE */
- /* absolute position */
- /* LCD pixel position is x>>ST_FP and y>>ST_FP */
- int16_t x, y;
- int8_t x0,y0,x1,y1; /* object outline in pixel, reference point is at 0,0 */
- };
- typedef struct _st_obj_struct st_obj;
- #define ST_DRAW_NONE 0
- #define ST_DRAW_BBOX 1
- #define ST_DRAW_TRASH1 2
- #define ST_DRAW_PLAYER1 3
- #define ST_DRAW_TRASH2 4
- #define ST_DRAW_PLAYER2 5
- #define ST_DRAW_PLAYER3 6
- #define ST_DRAW_GADGET 7
- #define ST_DRAW_BACKSLASH 8
- #define ST_DRAW_SLASH 9
- #define ST_DRAW_BIG_TRASH 10
- #define ST_MOVE_NONE 0
- #define ST_MOVE_X_SLOW 1
- #define ST_MOVE_PX_NORMAL 2
- #define ST_MOVE_PX_FAST 3
- #define ST_MOVE_PLAYER 4
- #define ST_MOVE_PY 5
- #define ST_MOVE_NY 6
- #define ST_MOVE_IMPLODE 7
- #define ST_MOVE_X_FAST 8
- #define ST_MOVE_WALL 9
- #define ST_MOVE_NXPY 10
- #define ST_MOVE_NXNY 11
- #define ST_IS_HIT_NONE 0
- #define ST_IS_HIT_BBOX 1
- #define ST_IS_HIT_WALL 2
- #define ST_DESTROY_NONE 0
- #define ST_DESTROY_DISAPPEAR 1
- #define ST_DESTROY_TO_DUST 2
- #define ST_DESTROY_GADGET 3
- #define ST_DESTROY_PLAYER 4
- #define ST_DESTROY_PLAYER_GADGETS 5
- #define ST_DESTROY_BIG_TRASH 6
- #define ST_FIRE_NONE 0
- #define ST_FIRE_PLAYER1 1
- #define ST_FIRE_PLAYER2 2
- #define ST_FIRE_PLAYER3 3
- #define ST_OT_WALL_SOLID 1
- #define ST_OT_BIG_TRASH 2
- #define ST_OT_MISSLE 3
- #define ST_OT_TRASH1 4
- #define ST_OT_PLAYER 5
- #define ST_OT_DUST_PY 6
- #define ST_OT_DUST_NY 7
- #define ST_OT_TRASH_IMPLODE 8
- #define ST_OT_TRASH2 9
- #define ST_OT_PLAYER2 10
- #define ST_OT_PLAYER3 11
- #define ST_OT_GADGET 12
- #define ST_OT_GADGET_IMPLODE 13
- #define ST_OT_DUST_NXPY 14
- #define ST_OT_DUST_NXNY 15
- /*================================================================*/
- /* graphics object */
- /*================================================================*/
- u8g2_t *st_u8g2;
- u8g2_uint_t u8g_height_minus_one;
- #define ST_AREA_HEIGHT (st_u8g2->height - 8)
- #define ST_AREA_WIDTH (st_u8g2->width)
- /*================================================================*/
- /* object types */
- /*================================================================*/
- st_ot st_object_types[] U8X8_PROGMEM =
- {
- /* 0: empty object type */
- { 0, 0, 0, ST_DRAW_NONE, ST_MOVE_NONE, ST_DESTROY_DISAPPEAR, ST_IS_HIT_NONE, ST_FIRE_NONE },
- /* 1: wall, player will be destroyed */
- { 2, 1, 30, ST_DRAW_BBOX, ST_MOVE_WALL, ST_DESTROY_DISAPPEAR, ST_IS_HIT_WALL, ST_FIRE_NONE },
- /* ST_OT_BIG_TRASH (2) */
- { 2, 1, 0, ST_DRAW_BIG_TRASH, ST_MOVE_X_SLOW, ST_DESTROY_BIG_TRASH, ST_IS_HIT_BBOX, ST_FIRE_NONE },
- /* 3: simple space ship (player) missle */
- { 1, 0, 0, ST_DRAW_BBOX, ST_MOVE_PX_FAST, ST_DESTROY_DISAPPEAR, ST_IS_HIT_NONE, ST_FIRE_NONE },
- /* ST_OT_TRASH1 (4): trash */
- { 2, 1, 0, ST_DRAW_TRASH1, ST_MOVE_X_SLOW, ST_DESTROY_TO_DUST, ST_IS_HIT_BBOX, ST_FIRE_NONE },
- /* ST_OT_PLAYER (5): player space ship */
- { 0, 2, 0, ST_DRAW_PLAYER1, ST_MOVE_PLAYER, ST_DESTROY_PLAYER, ST_IS_HIT_BBOX, ST_FIRE_PLAYER1 },
- /* ST_OT_DUST_PY (6): Last part of trash */
- { 0, 0, 0, ST_DRAW_BBOX, ST_MOVE_PY, ST_DESTROY_NONE, ST_IS_HIT_NONE, ST_FIRE_NONE },
- /* ST_OT_DUST_NY (7): Last part of trash */
- { 0, 0, 0, ST_DRAW_BBOX, ST_MOVE_NY, ST_DESTROY_NONE, ST_IS_HIT_NONE, ST_FIRE_NONE },
- /* ST_OT_TRASH_IMPLODE (8): trash was hit */
- { 0, 0, 5, ST_DRAW_TRASH1, ST_MOVE_IMPLODE, ST_DESTROY_NONE, ST_IS_HIT_NONE, ST_FIRE_NONE },
- /* ST_OT_TRASH2 (9): trash */
- { 2, 1, 0, ST_DRAW_TRASH2, ST_MOVE_X_SLOW, ST_DESTROY_TO_DUST, ST_IS_HIT_BBOX, ST_FIRE_NONE },
- /* ST_OT_PLAYER2 (10): player space ship+1x enhancement */
- { 0, 2, 0, ST_DRAW_PLAYER2, ST_MOVE_PLAYER, ST_DESTROY_PLAYER_GADGETS, ST_IS_HIT_BBOX, ST_FIRE_PLAYER2 },
- /* ST_OT_PLAYER3 (11): player space ship+2x enhancement */
- { 0, 2, 0, ST_DRAW_PLAYER3, ST_MOVE_PLAYER, ST_DESTROY_PLAYER_GADGETS, ST_IS_HIT_BBOX, ST_FIRE_PLAYER3 },
- /* ST_OT_GADGET (12): adds enhancements */
- { 0, 1, 0, ST_DRAW_GADGET, ST_MOVE_X_FAST, ST_DESTROY_GADGET, ST_IS_HIT_BBOX, ST_FIRE_NONE },
- /* ST_OT_GADGET_IMPLODE (13) */
- { 0, 0, 20, ST_DRAW_GADGET, ST_MOVE_IMPLODE, ST_DESTROY_NONE, ST_IS_HIT_NONE, ST_FIRE_NONE },
- /* ST_OT_DUST_NXPY (14): Last part of trash */
- { 0, 0, 0, ST_DRAW_BACKSLASH, ST_MOVE_NXPY, ST_DESTROY_NONE, ST_IS_HIT_NONE, ST_FIRE_NONE },
- /* ST_OT_DUST_NXNY (15): Last part of trash */
- { 0, 0, 0, ST_DRAW_SLASH, ST_MOVE_NXNY, ST_DESTROY_NONE, ST_IS_HIT_NONE, ST_FIRE_NONE },
-
- };
- /*================================================================*/
- /* list of all objects on the screen */
- /*================================================================*/
- /* use AVR RAMEND constant to derive the number of allowed objects */
- #if RAMEND < 0x300
- #define ST_OBJ_CNT 25
- #else
- #define ST_OBJ_CNT 45
- #endif
- st_obj st_objects[ST_OBJ_CNT];
- /*================================================================*/
- /* about players space ship*/
- /*================================================================*/
- /* player position */
- uint8_t st_player_pos;
- /* points */
- #define ST_POINTS_PER_LEVEL 25
- uint16_t st_player_points;
- uint16_t st_player_points_delayed;
- uint16_t st_highscore = 0;
- /*================================================================*/
- /* overall game state */
- /*================================================================*/
- #define ST_STATE_PREPARE 0
- #define ST_STATE_IPREPARE 1
- #define ST_STATE_GAME 2
- #define ST_STATE_END 3
- #define ST_STATE_IEND 4
- uint8_t st_state = ST_STATE_PREPARE;
- /*================================================================*/
- /* game difficulty */
- /*================================================================*/
- uint8_t st_difficulty = 1;
- #define ST_DIFF_VIS_LEN 30
- #define ST_DIFF_FP 5
- uint16_t st_to_diff_cnt = 0;
- /*================================================================*/
- /* bitmaps */
- /*================================================================*/
- const uint8_t st_bitmap_player1[] =
- {
- /* 01100000 */ 0x060,
- /* 11111000 */ 0x0f8,
- /* 01111110 */ 0x07e,
- /* 11111000 */ 0x0f8,
- /* 01100000 */ 0x060
- };
- const uint8_t st_bitmap_player2[] =
- {
- /* 01100000 */ 0x060,
- /* 01111100 */ 0x078,
- /* 01100000 */ 0x060,
- /* 11100000 */ 0x0e0,
- /* 11111000 */ 0x0f8,
- /* 01111110 */ 0x07e,
- /* 11111000 */ 0x0f8,
- /* 01100000 */ 0x060
- };
- const uint8_t st_bitmap_player3[] =
- {
- /* 01100000 */ 0x060,
- /* 01111100 */ 0x078,
- /* 01100000 */ 0x060,
- /* 11100000 */ 0x0e0,
- /* 11111000 */ 0x0f8,
- /* 01111110 */ 0x07e,
- /* 11111000 */ 0x0f8,
- /* 11100000 */ 0x0e0,
- /* 01100000 */ 0x060,
- /* 01111100 */ 0x078,
- /* 01100000 */ 0x060
- };
- const uint8_t st_bitmap_trash_5x5_1[] =
- {
- /* 01110000 */ 0x070,
- /* 11110000 */ 0x0f0,
- /* 11111000 */ 0x0f8,
- /* 01111000 */ 0x078,
- /* 00110000 */ 0x030,
- };
- const uint8_t st_bitmap_trash_5x5_2[] =
- {
- /* 00110000 */ 0x030,
- /* 11111000 */ 0x0f8,
- /* 11111000 */ 0x0f8,
- /* 11110000 */ 0x0f0,
- /* 01110000 */ 0x070,
- };
- const uint8_t st_bitmap_trash_7x7[] =
- {
- /* 00111000 */ 0x038,
- /* 01111100 */ 0x07c,
- /* 11111100 */ 0x0fc,
- /* 11111110 */ 0x0fe,
- /* 11111110 */ 0x0fe,
- /* 01111110 */ 0x07e,
- /* 01111000 */ 0x078,
- };
- const uint8_t st_bitmap_gadget[] =
- {
- /* 01110000 */ 0x070,
- /* 11011000 */ 0x0d8,
- /* 10001000 */ 0x088,
- /* 11011000 */ 0x0d8,
- /* 01110000 */ 0x070,
- };
- /*================================================================*/
- /* forward definitions */
- /*================================================================*/
- uint8_t st_rnd(void) U8X8_NOINLINE;
- static st_obj *st_GetObj(uint8_t objnr) U8X8_NOINLINE;
- uint8_t st_GetMissleMask(uint8_t objnr);
- uint8_t st_GetHitMask(uint8_t objnr);
- int8_t st_FindObj(uint8_t ot) U8X8_NOINLINE;
- void st_ClrObjs(void) U8X8_NOINLINE;
- int8_t st_NewObj(void) U8X8_NOINLINE;
- uint8_t st_CntObj(uint8_t ot);
- uint8_t st_CalcXY(st_obj *o) U8X8_NOINLINE;
- void st_SetXY(st_obj *o, uint8_t x, uint8_t y) U8X8_NOINLINE;
- void st_FireStep(uint8_t is_auto_fire, uint8_t is_fire) U8X8_NOINLINE;
- void st_InitTrash(uint8_t x, uint8_t y, int8_t dir);
- void st_NewGadget(uint8_t x, uint8_t y);
- void st_NewPlayerMissle(uint8_t x, uint8_t y) ;
- void st_NewTrashDust(uint8_t x, uint8_t y, int ot);
- void st_NewTrashDustAreaArgs(int16_t x, int16_t y, int ot);
- void st_SetupPlayer(uint8_t objnr, uint8_t ot);
- /*================================================================*/
- /* utility functions */
- /*================================================================*/
- char st_itoa_buf[12];
- char *st_itoa(unsigned long v)
- {
- volatile unsigned char i = 11;
- st_itoa_buf[11] = '\0';
- while( i > 0)
- {
- i--;
- st_itoa_buf[i] = (v % 10)+'0';
- v /= 10;
- if ( v == 0 )
- break;
- }
- return st_itoa_buf+i;
- }
- uint8_t st_rnd(void)
- {
- return rand();
- }
- /*
- for the specified index number, return the object
- */
- static st_obj *st_GetObj(uint8_t objnr)
- {
- return st_objects+objnr;
- }
- /*
- check, if this is a missle-like object (that is, can this object destroy something else)
- */
- uint8_t st_GetMissleMask(uint8_t objnr)
- {
- st_obj *o = st_GetObj(objnr);
- return u8x8_pgm_read(&(st_object_types[o->ot].missle_mask));
- }
- /*
- check, if this is a missle-like object (that is, can this object destroy something else)
- */
- uint8_t st_GetHitMask(uint8_t objnr)
- {
- st_obj *o = st_GetObj(objnr);
- return u8x8_pgm_read(&(st_object_types[o->ot].hit_mask));
- }
- /*
- search an empty object
- */
- int8_t st_FindObj(uint8_t ot)
- {
- int8_t i;
- for( i = 0; i < ST_OBJ_CNT; i++ )
- {
- if ( st_objects[i].ot == ot )
- return i;
- }
- return -1;
- }
- /*
- delete all objects
- */
- void st_ClrObjs(void)
- {
- int8_t i;
- for( i = 0; i < ST_OBJ_CNT; i++ )
- st_objects[i].ot = 0;
- }
- /*
- search an empty object
- */
- int8_t st_NewObj(void)
- {
- int8_t i;
- for( i = 0; i < ST_OBJ_CNT; i++ )
- {
- if ( st_objects[i].ot == 0 )
- return i;
- }
- return -1;
- }
- /*
- count number of objectes of the provided type
- st_CntObj(0) will return the number of empty objects, that means if
- st_CntObj(0) > 0 then st_NewObj() will return a valid index
- */
- uint8_t st_CntObj(uint8_t ot)
- {
- uint8_t i;
- uint8_t cnt = 0;
- for( i = 0; i < ST_OBJ_CNT; i++ )
- {
- if ( st_objects[i].ot == ot )
- cnt++;
- }
- return cnt;
- }
- /*
- calculate the pixel coordinates of the reference point of an object
- return rhe x value
- */
- uint8_t st_px_x, st_px_y; /* pixel within area */
- uint8_t st_CalcXY(st_obj *o)
- {
- //st_obj *o = st_GetObj(objnr);
- st_px_y = o->y>>ST_FP;
- st_px_x = o->x>>ST_FP;
- return st_px_x;
- }
- void st_SetXY(st_obj *o, uint8_t x, uint8_t y)
- {
- o->x = ((int16_t)x) << ST_FP;
- o->y = ((int16_t)y) << ST_FP;
- }
- /*
- calculate the object bounding box and place it into some global variables
- */
- int16_t st_bbox_x0, st_bbox_y0, st_bbox_x1, st_bbox_y1;
- void st_CalcBBOX(uint8_t objnr)
- {
- st_obj *o = st_GetObj(objnr);
-
- st_bbox_x0 = (uint16_t)(o->x>>ST_FP);
- st_bbox_x1 = st_bbox_x0;
- st_bbox_x0 += o->x0;
- st_bbox_x1 += o->x1;
- st_bbox_y0 = (uint16_t)(o->y>>ST_FP);
- st_bbox_y1 = st_bbox_y0;
- st_bbox_y0 += o->y0;
- st_bbox_y1 += o->y1;
- }
- /*
- clip bbox with the view window. requires a call to st_CalcBBOX
- return 0, if the bbox is totally outside the window
- */
- uint8_t st_cbbox_x0, st_cbbox_y0, st_cbbox_x1, st_cbbox_y1;
- uint8_t st_ClipBBOX(void)
- {
- if ( st_bbox_x0 >= ST_AREA_WIDTH )
- return 0;
- if ( st_bbox_x0 >= 0 )
- st_cbbox_x0 = (uint16_t)st_bbox_x0;
- else
- st_cbbox_x0 = 0;
- if ( st_bbox_x1 < 0 )
- return 0;
- if ( st_bbox_x1 < ST_AREA_WIDTH )
- st_cbbox_x1 = (uint16_t)st_bbox_x1;
- else
- st_cbbox_x1 = ST_AREA_WIDTH-1;
- if ( st_bbox_y0 >= ST_AREA_HEIGHT )
- return 0;
- if ( st_bbox_y0 >= 0 )
- st_cbbox_y0 = (uint16_t)st_bbox_y0;
- else
- st_cbbox_y0 = 0;
- if ( st_bbox_y1 < 0 )
- return 0;
- if ( st_bbox_y1 < ST_AREA_HEIGHT )
- st_cbbox_y1 = (uint16_t)st_bbox_y1;
- else
- st_cbbox_y1 = ST_AREA_HEIGHT-1;
-
- return 1;
- }
- /*================================================================*/
- /* universal member functions */
- /*================================================================*/
- uint8_t st_IsOut(uint8_t objnr)
- {
- st_CalcBBOX(objnr);
- if ( st_bbox_x0 >= ST_AREA_WIDTH )
- return 1;
- if ( st_bbox_x1 < 0 )
- return 1;
- if ( st_bbox_y0 >= ST_AREA_HEIGHT )
- return 1;
- if ( st_bbox_y1 < 0 )
- return 1;
- return 0;
- }
- void st_Disappear(uint8_t objnr)
- {
- st_obj *o = st_GetObj(objnr);
- st_player_points += u8x8_pgm_read(&(st_object_types[o->ot].points));
- o->ot = 0;
- }
- /*================================================================*/
- /* type dependent member functions */
- /*================================================================*/
- void st_Move(uint8_t objnr)
- {
- st_obj *o = st_GetObj(objnr);
- switch(u8x8_pgm_read(&(st_object_types[o->ot].move_fn)))
- {
- case ST_MOVE_NONE:
- break;
- case ST_MOVE_X_SLOW:
- o->x -= (1<<ST_FP)/8;
- o->x -= st_difficulty;
- o->y += (int16_t)o->tmp;
- if ( o->y >= ((ST_AREA_HEIGHT-1) << ST_FP) || o->y <= 0 )
- o->tmp = - o->tmp;
- break;
- case ST_MOVE_X_FAST:
- o->x -= (1<<ST_FP)/2;
- o->y += (int16_t)o->tmp;
- if ( o->y >= ((ST_AREA_HEIGHT-1) << ST_FP) || o->y <= 0 )
- o->tmp = - o->tmp;
- break;
- case ST_MOVE_PX_NORMAL:
- o->x += (1<<ST_FP)/4;
- break;
- case ST_MOVE_PX_FAST:
- o->x += (1<<ST_FP);
- break;
- case ST_MOVE_PLAYER:
- o->y = st_player_pos<<ST_FP;
- break;
- case ST_MOVE_PY:
- o->y += 3*ST_FP;
- break;
- case ST_MOVE_NY:
- o->y -= 3*ST_FP;
- break;
- case ST_MOVE_NXPY:
- o->y += 3*ST_FP;
- o->x -= 3*ST_FP;
- break;
- case ST_MOVE_NXNY:
- o->y -= 3*ST_FP;
- o->x -= 3*ST_FP;
- break;
- case ST_MOVE_IMPLODE:
- o->tmp++;
- if ( (o->tmp & 0x03) == 0 )
- {
- if ( o->x0 != o->x1 )
- o->x0++;
- else
- st_Disappear(objnr);
- }
- break;
- case ST_MOVE_WALL:
- o->x -= 1;
- o->x -= (st_difficulty>>1);
- break;
- }
- }
- void st_DrawBBOX(uint8_t objnr)
- {
- uint8_t y0, y1;
- /*st_obj *o = st_GetObj(objnr);*/
- st_CalcBBOX(objnr);
- if ( st_ClipBBOX() == 0 )
- return;
- /* st_cbbox_x0, st_cbbox_y0, st_cbbox_x1, st_cbbox_y1; */
-
- // w = st_cbbox_x1-st_cbbox_x0;
- // w++;
- // h = st_cbbox_y1-st_cbbox_y0;
- // h++;
-
-
- //dog_SetVLine(st_cbbox_x0, st_cbbox_y0, st_cbbox_y1);
- //dog_SetVLine(st_cbbox_x1, st_cbbox_y0, st_cbbox_y1);
- //dog_SetHLine(st_cbbox_x0, st_cbbox_x1, st_cbbox_y0);
- //dog_SetHLine(st_cbbox_x0, st_cbbox_x1, st_cbbox_y1);
- u8g2_SetDrawColor(st_u8g2, 1);
- y0 = u8g_height_minus_one - st_cbbox_y0;
- y1 = u8g_height_minus_one - st_cbbox_y1;
-
- u8g2_DrawFrame(st_u8g2, st_cbbox_x0, y1, st_cbbox_x1-st_cbbox_x0+1, y0-y1+1);
-
- //dog_SetBox(st_cbbox_x0, st_cbbox_y0, st_cbbox_x1, st_cbbox_y1);
- /*
- if ( o->ot == ST_OT_PLAYER )
- {
- dog_DrawStr(0, 26, font_4x6, st_itoa(st_cbbox_y0));
- dog_DrawStr(10, 26, font_4x6, st_itoa(st_cbbox_y1));
- }
- */
- }
- #ifdef FN_IS_NOT_IN_USE
- void st_DrawFilledBox(uint8_t objnr)
- {
- st_CalcBBOX(objnr);
- if ( st_ClipBBOX() == 0 )
- return;
- /* st_cbbox_x0, st_cbbox_y0, st_cbbox_x1, st_cbbox_y1; */
- dog_SetBox(st_cbbox_x0, st_cbbox_y0, st_cbbox_x1, st_cbbox_y1);
- }
- #endif
- void st_DrawBitmap(uint8_t objnr, const uint8_t * bm, uint8_t w, uint8_t h)
- {
- /* st_obj *o = st_GetObj(objnr); */
- st_CalcBBOX(objnr);
- /* result is here: int16_t st_bbox_x0, st_bbox_y0, st_bbox_x1, st_bbox_y1 */
- //dog_SetBitmapP(st_bbox_x0,st_bbox_y1,bm,w,h);
-
- u8g2_DrawBitmap(st_u8g2, st_bbox_x0, u8g_height_minus_one - st_bbox_y1, (w+7)/8, h, bm);
-
- }
- void st_DrawObj(uint8_t objnr)
- {
- st_obj *o = st_GetObj(objnr);
- switch(u8x8_pgm_read(&(st_object_types[o->ot].draw_fn)))
- {
- case ST_DRAW_NONE:
- break;
- case ST_DRAW_BBOX:
- st_DrawBBOX(objnr);
- break;
- case ST_DRAW_TRASH1:
- st_DrawBitmap(objnr, st_bitmap_trash_5x5_1,o->x1-o->x0+1, 5);
- break;
- case ST_DRAW_TRASH2:
- st_DrawBitmap(objnr, st_bitmap_trash_5x5_2,o->x1-o->x0+1, 5);
- break;
- case ST_DRAW_BIG_TRASH:
- st_DrawBitmap(objnr, st_bitmap_trash_7x7,o->x1-o->x0+1, 7);
- break;
- case ST_DRAW_PLAYER1:
- st_DrawBitmap(objnr, st_bitmap_player1,7,5);
- break;
- case ST_DRAW_PLAYER2:
- st_DrawBitmap(objnr, st_bitmap_player2,7,8);
- break;
- case ST_DRAW_PLAYER3:
- st_DrawBitmap(objnr, st_bitmap_player3,7,11);
- break;
- case ST_DRAW_GADGET:
- /* could use this proc, but... */
- /* st_DrawBitmap(objnr, st_bitmap_gadget,o->x1-o->x0+1, 5); */
- /* ... this one looks also funny. */
- st_DrawBitmap(objnr, st_bitmap_gadget,5,5);
- break;
- case ST_DRAW_BACKSLASH:
- {
- uint8_t x;
- uint8_t y;
- x = st_CalcXY(o);
- y = st_px_y;
-
- // dog_SetPixel(x,y);
- // x++; y--;
- // dog_SetPixel(x,y);
- // x++; y--;
- // dog_SetPixel(x,y);
-
- u8g2_SetDrawColor(st_u8g2, 1);
- u8g2_DrawPixel(st_u8g2, x, u8g_height_minus_one - y);
- x++; y--;
- u8g2_DrawPixel(st_u8g2, x, u8g_height_minus_one - y);
- x++; y--;
- u8g2_DrawPixel(st_u8g2, x, u8g_height_minus_one - y);
- }
- break;
- case ST_DRAW_SLASH:
- {
- uint8_t x;
- uint8_t y;
- x = st_CalcXY(o);
- y = st_px_y;
-
- // dog_SetPixel(x,y);
- // x++; y++;
- // dog_SetPixel(x,y);
- // x++; y++;
- // dog_SetPixel(x,y);
-
- u8g2_SetDrawColor(st_u8g2, 1);
- u8g2_DrawPixel(st_u8g2, x, u8g_height_minus_one - y);
- x++; y++;
- u8g2_DrawPixel(st_u8g2, x, u8g_height_minus_one - y);
- x++; y++;
- u8g2_DrawPixel(st_u8g2, x, u8g_height_minus_one - y);
- }
- break;
- }
- }
- uint8_t st_IsHitBBOX(uint8_t objnr, uint8_t x, uint8_t y)
- {
- st_CalcBBOX(objnr);
- if ( st_ClipBBOX() == 0 )
- return 0; /* obj is outside (not visible) */
- if ( x < st_cbbox_x0 )
- return 0;
- if ( x > st_cbbox_x1 )
- return 0;
- if ( y < st_cbbox_y0 )
- return 0;
- if ( y > st_cbbox_y1 )
- return 0;
- return 1;
- }
- void st_Destroy(uint8_t objnr)
- {
- int8_t nr;
- st_obj *o = st_GetObj(objnr);
- switch(u8x8_pgm_read(&(st_object_types[o->ot].destroy_fn)))
- {
- case ST_DESTROY_NONE: /* only usefull for missels or walls which stay alife */
- break;
- case ST_DESTROY_DISAPPEAR: /* this should be the default operation */
- st_Disappear(objnr);
- break;
- case ST_DESTROY_GADGET:
- nr = st_FindObj(ST_OT_PLAYER2);
- if ( nr >= 0 )
- st_SetupPlayer(nr, ST_OT_PLAYER3);
- else
- {
- nr = st_FindObj(ST_OT_PLAYER);
- if ( nr >= 0 )
- st_SetupPlayer(nr, ST_OT_PLAYER2);
- }
- st_NewTrashDustAreaArgs(o->x, o->y, ST_OT_DUST_PY);
- st_NewTrashDustAreaArgs(o->x, o->y, ST_OT_DUST_NY);
- o->ot = ST_OT_GADGET_IMPLODE;
- o->tmp = 0;
- break;
- case ST_DESTROY_TO_DUST:
- st_NewTrashDustAreaArgs(o->x, o->y, ST_OT_DUST_PY);
- st_NewTrashDustAreaArgs(o->x, o->y, ST_OT_DUST_NY);
- o->ot = ST_OT_TRASH_IMPLODE;
- o->tmp = 0;
- break;
- case ST_DESTROY_BIG_TRASH:
- st_NewTrashDustAreaArgs(o->x, o->y, ST_OT_DUST_PY);
- st_NewTrashDustAreaArgs(o->x, o->y, ST_OT_DUST_NY);
- st_InitTrash((o->x>>ST_FP)-1, (o->y>>ST_FP)+3, 2+(st_rnd()&3));
- st_InitTrash((o->x>>ST_FP)-2, (o->y>>ST_FP)-3, -2-(st_rnd()&3));
- st_Disappear(objnr);
- break;
- case ST_DESTROY_PLAYER:
- st_Disappear(objnr);
- st_state = ST_STATE_END;
- o->tmp = 0;
- break;
- case ST_DESTROY_PLAYER_GADGETS:
- /* o->ot = ST_OT_PLAYER; */
- st_SetupPlayer(objnr, ST_OT_PLAYER);
- break;
- }
- }
- /*
- check if the target (objnr) has been hit.
- st_IsHit() must also destroy the target.
- return value:
- 0: do not destroy the missle
- 1: destroy the missle
- */
- uint8_t st_IsHit(uint8_t objnr, uint8_t x, uint8_t y, uint8_t missle_mask)
- {
- uint8_t hit_mask = st_GetHitMask(objnr);
- st_obj *o;
-
- if ( (hit_mask & missle_mask) == 0 )
- return 0;
-
- o = st_GetObj(objnr);
-
- switch(u8x8_pgm_read(&(st_object_types[o->ot].is_hit_fn)))
- {
- case ST_IS_HIT_NONE:
- break;
- case ST_IS_HIT_BBOX:
- if ( st_IsHitBBOX(objnr, x, y) != 0 )
- {
- st_Destroy(objnr);
- return 1;
- }
- break;
- case ST_IS_HIT_WALL:
- if ( st_IsHitBBOX(objnr, x, y) != 0 )
- {
- o->x0++;
- if ( o->x0 < o->x1 )
- {
- st_NewTrashDust(x, y, ST_OT_DUST_NXPY);
- st_NewTrashDust(x, y, ST_OT_DUST_NXNY);
- }
- else
- {
- st_Destroy(objnr);
- st_NewTrashDust(x, y, ST_OT_DUST_NXPY);
- st_NewTrashDust(x, y, ST_OT_DUST_NXNY);
- st_NewTrashDust(x, y, ST_OT_DUST_NY);
- st_NewTrashDust(x, y, ST_OT_DUST_PY);
- }
- return 1;
- }
- break;
- }
- return 0;
- }
- /* update all fire counters */
- uint8_t st_fire_player = 0;
- uint8_t st_fire_period = 51;
- uint8_t st_manual_fire_delay = 20;
- uint8_t st_is_fire_last_value = 0;
- /*
- is_auto_fire == 1
- is_fire will be ignored, autofire enabled
- is_auto_fire == 0
- a transition from 1 to 0 on the is_fire variable will issue a missle
- */
- void st_FireStep(uint8_t is_auto_fire, uint8_t is_fire)
- {
- if ( is_auto_fire != 0 )
- {
- st_fire_player++;
- if ( st_fire_player >= st_fire_period )
- st_fire_player = 0;
- }
- else
- {
- if ( st_fire_player < st_manual_fire_delay )
- {
- st_fire_player++;
- }
- else
- {
- if ( st_is_fire_last_value == 0 )
- if ( is_fire != 0 )
- st_fire_player = 0;
- }
- st_is_fire_last_value = is_fire;
- }
- }
- void st_Fire(uint8_t objnr)
- {
- st_obj *o = st_GetObj(objnr);
- uint8_t x;
- uint8_t y;
-
- switch(u8x8_pgm_read(&(st_object_types[o->ot].fire_fn)))
- {
- case ST_FIRE_NONE:
- break;
- case ST_FIRE_PLAYER1:
- if ( st_fire_player == 0 )
- {
- /* create missle at st_px_x and st_px_y */
- x = st_CalcXY(o);
- y = st_px_y;
- st_NewPlayerMissle(x , y );
- }
- break;
- case ST_FIRE_PLAYER2:
- if ( st_fire_player == 0 )
- {
- /* create missle at st_px_x and st_px_y */
- x = st_CalcXY(o);
- y = st_px_y;
- st_NewPlayerMissle(x , y );
- st_NewPlayerMissle(x , y+4 );
- }
- break;
- case ST_FIRE_PLAYER3:
- if ( st_fire_player == 0 )
- {
- /* create missle at st_px_x and st_px_y */
- x = st_CalcXY(o);
- y = st_px_y;
- st_NewPlayerMissle(x , y );
- st_NewPlayerMissle(x , y+4 );
- st_NewPlayerMissle(x , y-4 );
- }
- break;
- }
- }
- /*================================================================*/
- /* object init functions */
- /*================================================================*/
- /*
- x,y are pixel coordinats within the play arey
- */
- void st_NewGadget(uint8_t x, uint8_t y)
- {
- st_obj *o;
- int8_t objnr = st_NewObj();
- if ( objnr < 0 )
- return;
- o = st_GetObj(objnr);
- st_SetXY(o, x, y);
- o->ot = ST_OT_GADGET;
- o->tmp = 8;
- //o->x = (x)<<ST_FP;
- //o->y = (y)<<ST_FP;
- o->x0 = -3;
- o->x1 = 1;
- o->y0 = -2;
- o->y1 = 2;
- }
- /*
- x,y are pixel coordinats within the play arey
- dir: direction
- 0: random
- != 0 --> assigned
- */
- void st_InitTrash(uint8_t x, uint8_t y, int8_t dir)
- {
- st_obj *o;
- int8_t objnr = st_NewObj();
- if ( objnr < 0 )
- return;
- o = st_GetObj(objnr);
- if ( (st_rnd() & 1) == 0 )
- o->ot = ST_OT_TRASH1;
- else
- o->ot = ST_OT_TRASH2;
- if ( dir == 0 )
- {
- o->tmp = 0;
- if ( st_rnd() & 1 )
- {
- if ( st_rnd() & 1 )
- o->tmp++;
- else
- o->tmp--;
- }
- }
- else
- {
- o->tmp = dir;
- }
- st_SetXY(o, x, y);
- //o->x = (x)<<ST_FP;
- //o->y = (y)<<ST_FP;
- o->x0 = -3;
- o->x1 = 1;
- o->y0 = -2;
- o->y1 = 2;
- if ( st_difficulty >= 5 )
- {
- if ( (st_rnd() & 3) == 0 )
- {
- o->ot = ST_OT_BIG_TRASH;
- o->y0--;
- o->y1++;
- o->x0--;
- o->x1++;
- }
- }
- }
- /*
- x,y are pixel coordinats within the play arey
- */
- void st_NewTrashDust(uint8_t x, uint8_t y, int ot)
- {
- st_obj *o;
- int8_t objnr = st_NewObj();
- if ( objnr < 0 )
- return;
- o = st_GetObj(objnr);
- o->ot = ot;
- st_SetXY(o, x, y);
- //o->x = (x)<<ST_FP;
- //o->y = (y)<<ST_FP;
- o->x0 = 0;
- o->x1 = 0;
- o->y0 = -2;
- o->y1 = 2;
- }
- void st_NewTrashDustAreaArgs(int16_t x, int16_t y, int ot)
- {
- st_NewTrashDust(x>>ST_FP, y>>ST_FP, ot);
- }
- void st_NewWall(void)
- {
- st_obj *o;
- int8_t objnr = st_NewObj();
- int8_t h;
- if ( objnr < 0 )
- return;
- o = st_GetObj(objnr);
- o->ot = ST_OT_WALL_SOLID;
- h = st_rnd();
- h &= 63;
- h = (int8_t)(((int16_t)h*(int16_t)(ST_AREA_HEIGHT/4))>>6);
- h += ST_AREA_HEIGHT/6;
- o->x0 = 0;
- o->x1 = 5;
- o->x = (ST_AREA_WIDTH-1)<<ST_FP;
-
- if ( (st_rnd() & 1) == 0 )
- {
- o->y = (ST_AREA_HEIGHT-1)<<ST_FP;
-
- o->y0 = -h;
- o->y1 = 0;
- }
- else
- {
- o->y = (0)<<ST_FP;
- o->y0 = 0;
- o->y1 = h;
- }
- }
- void st_NewPlayerMissle(uint8_t x, uint8_t y)
- {
- st_obj *o;
- int8_t objnr = st_NewObj();
- if ( objnr < 0 )
- return;
- o = st_GetObj(objnr);
- o->ot = ST_OT_MISSLE;
- st_SetXY(o, x, y);
- //o->x = x<<ST_FP;
- //o->y = y<<ST_FP;
- o->x0 = -4;
- o->x1 = 1;
- o->y0 = 0;
- o->y1 = 0;
- }
- void st_SetupPlayer(uint8_t objnr, uint8_t ot)
- {
- st_obj *o = st_GetObj(objnr);
- switch(ot)
- {
- case ST_OT_PLAYER:
- o->ot = ot;
- o->y0 = -2;
- o->y1 = 2;
- break;
- case ST_OT_PLAYER2:
- o->ot = ot;
- o->y0 = -2;
- o->y1 = 5;
- break;
- case ST_OT_PLAYER3:
- o->ot = ot;
- o->y0 = -5;
- o->y1 = 5;
- break;
- }
- }
- void st_NewPlayer(void)
- {
- st_obj *o;
- int8_t objnr = st_NewObj();
- if ( objnr < 0 )
- return;
- o = st_GetObj(objnr);
- o->x = 6<<ST_FP;
- o->y = (ST_AREA_HEIGHT/2)<<ST_FP;
- o->x0 = -6;
- o->x1 = 0;
- st_SetupPlayer(objnr, ST_OT_PLAYER);
- }
- /*================================================================*/
- /* trash creation */
- /*================================================================*/
- void st_InitDeltaWall(void)
- {
- uint8_t i;
- uint8_t cnt = 0;
- uint8_t max_x = 0;
- uint8_t max_l;
-
- uint8_t min_dist_for_new = 40;
- uint8_t my_difficulty = st_difficulty;
-
- if ( st_difficulty >= 2 )
- {
-
- max_l = ST_AREA_WIDTH;
- max_l -= min_dist_for_new;
-
- if ( my_difficulty > 30 )
- my_difficulty = 30;
- min_dist_for_new -= my_difficulty;
-
- for( i = 0; i < ST_OBJ_CNT; i++ )
- {
- if ( st_objects[i].ot == ST_OT_WALL_SOLID )
- {
- cnt++;
- if ( max_x < (st_objects[i].x>>ST_FP) )
- max_x = (st_objects[i].x>>ST_FP);
- }
- }
- /* if ( cnt < upper_trash_limit ) */
- if ( max_x < max_l )
- {
- st_NewWall();
- }
- }
- }
- void st_InitDeltaTrash(void)
- {
- uint8_t i;
- uint8_t cnt = 0;
- uint8_t max_x = 0;
- uint8_t max_l;
-
- uint8_t upper_trash_limit = ST_OBJ_CNT-7;
- uint8_t min_dist_for_new = 20;
- uint8_t my_difficulty = st_difficulty;
-
- if ( my_difficulty > 14 )
- my_difficulty = 14;
- min_dist_for_new -= my_difficulty;
-
- for( i = 0; i < ST_OBJ_CNT; i++ )
- {
- if ( st_objects[i].ot == ST_OT_TRASH1 || st_objects[i].ot == ST_OT_TRASH2 || st_objects[i].ot == ST_OT_GADGET || st_objects[i].ot == ST_OT_BIG_TRASH )
- {
- cnt++;
- if ( max_x < (st_objects[i].x>>ST_FP) )
- max_x = (st_objects[i].x>>ST_FP);
- }
- }
-
- max_l = ST_AREA_WIDTH;
- max_l -= min_dist_for_new;
-
- if ( cnt < upper_trash_limit )
- if ( max_x < max_l )
- {
- if ( (st_difficulty >= 3) && ((st_rnd() & 7) == 0) )
- st_NewGadget(ST_AREA_WIDTH-1, rand() & (ST_AREA_HEIGHT-1));
- else
- st_InitTrash(ST_AREA_WIDTH-1, rand() & (ST_AREA_HEIGHT-1),0 );
- }
- }
- void st_InitDelta(void)
- {
- st_InitDeltaTrash();
- st_InitDeltaWall();
- /*
- uint8_t cnt;
- cnt = st_CntObj(2);
- if ( cnt == 0 )
- st_InitBrick1();
- */
- }
- /*================================================================*/
- /* API: game draw procedure */
- /*================================================================*/
- void st_DrawInGame(uint8_t fps)
- {
- uint8_t i;
- /* draw all objects */
- for( i = 0; i < ST_OBJ_CNT; i++ )
- st_DrawObj(i);
-
- //dog_ClrBox(0, ST_AREA_HEIGHT, st_u8g2->width-1, ST_AREA_HEIGHT+3);
- u8g2_SetDrawColor(st_u8g2, 0);
- u8g2_DrawBox(st_u8g2, 0, u8g_height_minus_one - ST_AREA_HEIGHT-3, st_u8g2->width, 4);
-
- u8g2_SetDrawColor(st_u8g2, 1);
- u8g2_DrawHLine(st_u8g2, 0, u8g_height_minus_one - ST_AREA_HEIGHT+1, ST_AREA_WIDTH);
- u8g2_DrawHLine(st_u8g2, 0, u8g_height_minus_one, ST_AREA_WIDTH);
- u8g2_SetFont(st_u8g2, u8g_font_4x6r);
- u8g2_DrawStr(st_u8g2, 0, u8g_height_minus_one - ST_AREA_HEIGHT, st_itoa(st_difficulty));
- u8g2_DrawHLine(st_u8g2, 10, u8g_height_minus_one - ST_AREA_HEIGHT-3, (st_to_diff_cnt>>ST_DIFF_FP)+1);
- u8g2_DrawVLine(st_u8g2, 10, u8g_height_minus_one - ST_AREA_HEIGHT-4, 3);
- u8g2_DrawVLine(st_u8g2, 10+ST_DIFF_VIS_LEN, u8g_height_minus_one - ST_AREA_HEIGHT-4, 3);
-
-
- /* player points */
- u8g2_DrawStr(st_u8g2, ST_AREA_WIDTH-5*4-2, u8g_height_minus_one - ST_AREA_HEIGHT, st_itoa(st_player_points_delayed));
-
-
- /* FPS output */
- if ( fps > 0 )
- {
- //i = dog_DrawStr(ST_AREA_WIDTH-5*4-2-7*4, ST_AREA_HEIGHT, font_4x6, "FPS:");
- i = u8g2_DrawStr(st_u8g2, ST_AREA_WIDTH-5*4-2-7*4, u8g_height_minus_one - ST_AREA_HEIGHT, "FPS:");
- //dog_DrawStr(ST_AREA_WIDTH-5*4-2-7*4+i, ST_AREA_HEIGHT, font_4x6, st_itoa(fps));
- u8g2_DrawStr(st_u8g2, ST_AREA_WIDTH-5*4-2-7*4+i, u8g_height_minus_one - ST_AREA_HEIGHT, st_itoa(fps));
- }
- /*dog_DrawStr(60+i, ST_AREA_HEIGHT, font_4x6, st_itoa(st_CntObj(0)));*/
- }
- void st_Draw(uint8_t fps)
- {
- switch(st_state)
- {
- case ST_STATE_PREPARE:
- case ST_STATE_IPREPARE:
- //dog_DrawStr(0, (st_u8g2->height-6)/2, font_4x6, "SpaceTrash");
- u8g2_SetFont(st_u8g2, u8g_font_4x6r);
- u8g2_SetDrawColor(st_u8g2, 1);
- //dog_DrawStrP(0, (st_u8g2->height-6)/2, font_4x6, DOG_PSTR("SpaceTrash"));
- u8g2_DrawStr(st_u8g2, 0, u8g_height_minus_one - (st_u8g2->height-6)/2, "SpaceTrash");
- //dog_SetHLine(st_u8g2->width-st_to_diff_cnt-10, st_u8g2->width-st_to_diff_cnt, (st_u8g2->height-6)/2-1);
- u8g2_DrawHLine(st_u8g2, st_u8g2->width-st_to_diff_cnt-10, u8g_height_minus_one - (st_u8g2->height-6)/2+1, 11);
- break;
- case ST_STATE_GAME:
- st_DrawInGame(fps);
- break;
- case ST_STATE_END:
- case ST_STATE_IEND:
- u8g2_SetFont(st_u8g2, u8g_font_4x6r);
- u8g2_SetDrawColor(st_u8g2, 1);
- //dog_DrawStr(0, (st_u8g2->height-6)/2, font_4x6, "Game Over");
- //dog_DrawStrP(0, (st_u8g2->height-6)/2, font_4x6, DOG_PSTR("Game Over"));
- u8g2_DrawStr(st_u8g2, 0, u8g_height_minus_one - (st_u8g2->height-6)/2, "Game Over");
- //dog_DrawStr(50, (st_u8g2->height-6)/2, font_4x6, st_itoa(st_player_points));
- u8g2_DrawStr(st_u8g2, 50, u8g_height_minus_one - (st_u8g2->height-6)/2, st_itoa(st_player_points));
- //dog_DrawStr(75, (st_u8g2->height-6)/2, font_4x6, st_itoa(st_highscore));
- u8g2_DrawStr(st_u8g2, 75, u8g_height_minus_one - (st_u8g2->height-6)/2, st_itoa(st_highscore));
- //dog_SetHLine(st_to_diff_cnt, st_to_diff_cnt+10, (st_u8g2->height-6)/2-1);
- u8g2_DrawHLine(st_u8g2, st_to_diff_cnt, u8g_height_minus_one - (st_u8g2->height-6)/2+1, 11);
- break;
- }
- }
- void st_SetupInGame(void)
- {
- st_player_points = 0;
- st_player_points_delayed = 0;
- st_difficulty = 1;
- st_to_diff_cnt = 0;
- st_ClrObjs();
- st_NewPlayer();
- /* st_InitBrick1(); */
- }
- /*================================================================*/
- /* API: game setup */
- /*================================================================*/
- void st_Setup(u8g2_t *u8g)
- {
- st_u8g2 = u8g;
- u8g2_SetBitmapMode(u8g, 1);
- u8g_height_minus_one = u8g->height;
- u8g_height_minus_one--;
- }
- /*================================================================*/
- /* API: game step execution */
- /*================================================================*/
- /*
- player_pos: 0..255
- */
- void st_StepInGame(uint8_t player_pos, uint8_t is_auto_fire, uint8_t is_fire)
- {
- uint8_t i, j;
- uint8_t missle_mask;
-
- /* rescale player pos */
- //st_player_pos = ((uint16_t)player_pos * (uint16_t)ST_AREA_HEIGHT)/256;
- if ( player_pos < 64 )
- st_player_pos = 0;
- else if ( player_pos >= 192 )
- st_player_pos = ST_AREA_HEIGHT-2-1;
- else
- st_player_pos = ((uint16_t)((player_pos-64)) * (uint16_t)(ST_AREA_HEIGHT-2))/128;
- st_player_pos+=1;
- /* move all objects */
- for( i = 0; i < ST_OBJ_CNT; i++ )
- st_Move(i);
-
- /* check for objects which left the play area */
- for( i = 0; i < ST_OBJ_CNT; i++ )
- if ( st_objects[i].ot != 0 )
- if ( st_IsOut(i) != 0 )
- st_Disappear(i);
-
- /* missle and destruction handling */
- for( i = 0; i < ST_OBJ_CNT; i++ )
- {
- missle_mask = st_GetMissleMask(i);
- if ( missle_mask != 0 ) /* should we apply missle handling? */
- if ( st_CalcXY(st_objects+i) != 0 ) /* yes: calculate pixel reference point (st_px_x, st_px_y) */
- for( j = 0; j < ST_OBJ_CNT; j++ ) /* has any other object been hit? */
- if ( i != j ) /* except missle itself... */
- if ( st_IsHit(j, st_px_x, st_px_y, missle_mask) != 0 ) /* let the member function decide */
- { /* let the member function destroy the object if required */
- st_Destroy(i);
- }
- }
-
- /* handle fire counter */
- st_FireStep(is_auto_fire, is_fire);
-
- /* fire */
- for( i = 0; i < ST_OBJ_CNT; i++ )
- st_Fire(i);
-
- /* create new objects */
- st_InitDelta();
-
- /* increase difficulty */
-
- st_to_diff_cnt++;
- if ( st_to_diff_cnt == (ST_DIFF_VIS_LEN<<ST_DIFF_FP) )
- {
- st_to_diff_cnt = 0;
- st_difficulty++;
- st_player_points += ST_POINTS_PER_LEVEL;
- }
-
- /* update visible player points */
- if ( st_player_points_delayed < st_player_points )
- st_player_points_delayed++;
- }
-
- void st_Step(uint8_t player_pos, uint8_t is_auto_fire, uint8_t is_fire)
- {
- switch(st_state)
- {
- case ST_STATE_PREPARE:
- st_to_diff_cnt = st_u8g2->width-10; /* reuse st_to_diff_cnt */
- st_state = ST_STATE_IPREPARE;
- break;
- case ST_STATE_IPREPARE:
- st_to_diff_cnt--;
- if ( st_to_diff_cnt == 0 )
- {
- st_state = ST_STATE_GAME;
- st_SetupInGame();
- }
- break;
- case ST_STATE_GAME:
- st_StepInGame(player_pos, is_auto_fire, is_fire);
- break;
- case ST_STATE_END:
- st_to_diff_cnt = st_u8g2->width-10; /* reuse st_to_diff_cnt */
- if ( st_highscore < st_player_points)
- st_highscore = st_player_points;
- st_state = ST_STATE_IEND;
- break;
- case ST_STATE_IEND:
- st_to_diff_cnt--;
- if ( st_to_diff_cnt == 0 )
- st_state = ST_STATE_PREPARE;
- break;
- }
- }
-
- u8g2_t u8g2;
- int main(void)
- {
- uint8_t y, k;
-
- 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);
- st_Setup(&u8g2);
-
- y = 128;
-
- for(;;)
- {
- do
- {
- k = u8g_sdl_get_key();
- //printf("Step %d\n", y);
-
- st_Step(y, /* is_auto_fire */ 1, /* is_fire */ 0);
-
- u8g2_FirstPage(&u8g2);
- do
- {
- st_Draw(0);
- } while( u8g2_NextPage(&u8g2) );
- usleep(10000);
-
- k = u8x8_GetMenuEvent(u8g2_GetU8x8(&u8g2));
-
- } while( k == 0 );
-
- if ( k == U8X8_MSG_GPIO_MENU_UP )
- y += ST_FP;
-
- if ( k == U8X8_MSG_GPIO_MENU_DOWN )
- y -= ST_FP;
-
- if ( k == U8X8_MSG_GPIO_MENU_HOME )
- break;
-
- //if ( k == 273 ) y -= 1;
- //if ( k == 274 ) y += 1;
- //if ( k == 276 ) x -= 7;
- //if ( k == 275 ) x += 7;
-
- //if ( k == 'x' ) y -= ST_FP;
- //if ( k == 'e' ) y += ST_FP;
- //if ( k == 's' ) x -= 1;
- //if ( k == 'd' ) x += 1;
- //if ( k == 'q' ) break;
- }
-
- return 0;
- }
|