/* * ---------------------------------------------------------------------------- * "THE BEER-WARE LICENSE" (Revision 42): * wrote this file. As long as you retain this notice you * can do whatever you want with this stuff. If we meet some day, and you think * this stuff is worth it, you can buy me a beer in return. * (c) 2014 Stefan Rupp * ---------------------------------------------------------------------------- */ #include "rgbyteclock.h" #include "timer.h" #include "ledcontroller.h" #include "util.h" #define SEED_RNG 0 #define INIT 1 #define INTRO 2 #define INTRODUCE_COLORS 3 #define SHOW_SEQUENCE 4 #define GET_USER_SEQUENCE 5 #define USER_GUESS_OK 6 #define USER_GUESS_NOK 7 #define EXTEND_SEQUENCE 8 #define WIN 9 int8_t show_anim_sequence( uint32_t now, uint32_t animation_start ); int8_t show_intro( uint32_t now, uint32_t animation_start ); int8_t show_introduce_colors( uint32_t now, uint32_t animation_start ); void show_anim_wait_seed( uint32_t now, uint32_t animation_start ); int8_t show_anim_ok( uint32_t now, uint32_t animation_start ); int8_t show_anim_nok( uint32_t now, uint32_t animation_start ); int8_t get_sequence( uint32_t now, uint32_t animation_start ); int8_t show_anim_win( uint32_t now, uint32_t animation_start ); static uint8_t sequence[12]; static uint8_t sequence_index; static uint8_t input_sequence_index; static uint8_t colorScheme[2]; void rgbyteclock(void) { uint32_t now, t1; int8_t end; uint8_t button = BUTTON_NONE; uint8_t gameState = SEED_RNG; ledcontroller_turn_all_on(); DDRC &= ~(1<= 12) { gameState = WIN; continue; } else { gameState = SHOW_SEQUENCE; } if( random()&1 ) { sequence[sequence_index] = colorScheme[0]; } else { sequence[sequence_index] = colorScheme[1]; } sequence_index++; break; case WIN: end = show_anim_win( now, t1 ); if( end ) { gameState = INIT; t1 = now; } break; } led_flush( ); } } int8_t get_sequence( uint32_t now, uint32_t animation_start ) { uint16_t r,g,b; uint8_t button; uint8_t color; uint8_t guessOK; button = get_button( ); color = sequence[input_sequence_index]; guessOK = 0; if( button == BUTTON_RO ) { if( color == colorScheme[0] ) { guessOK = 1; } } else if( button == BUTTON_LO ) { if( color == colorScheme[1] ) { guessOK = 1; } } else { return 0; } if( guessOK ) { // draw what user entered until now get_color( &r, &g, &b, color ); led_set( input_sequence_index, r, g, b ); input_sequence_index++; if( input_sequence_index >= sequence_index) { input_sequence_index = 0; return 2; // entire sequence right } return 0; // right but not finished } return 1; // user guessed wrong } /* ############## # ANIMATIONS # ############## */ int8_t show_anim_sequence( uint32_t now, uint32_t animation_start ) { uint32_t t_diff = now - animation_start; uint16_t r,g,b; uint8_t tmp_index; const uint16_t holdTime=1000 /*ms*/, stepSpeed=500 /*ms*/; tmp_index = (t_diff/stepSpeed) +1; if( tmp_index > sequence_index ) { tmp_index = sequence_index; } for( int i=0; i (sequence_index * stepSpeed)+holdTime ) { // hide sequence for( int i=0; i<12; i++ ) { get_color( &r, &g, &b, COLOR_BLACK ); led_set( i, r, g, b); } return 1; } return 0; } int8_t show_introduce_colors( uint32_t now, uint32_t animation_start ) { uint32_t t_diff = now - animation_start; uint16_t r,g,b; // all ring LEDs off for( int i=0; i<12; i++ ) { led_set( i, 0,0,0 ); } if( t_diff%100 < 50 ) { // put gamecolors on the buttons get_color( &r, &g, &b, colorScheme[0] ); led_set( 12, r, g, b); // RO get_color( &r, &g, &b, colorScheme[1] ); led_set( 13, r, g, b); // LO } else { for( int i=12; i<14; i++ ) { get_color( &r, &g, &b, COLOR_BLACK ); led_set( i, r,g,b ); } } if( t_diff > 1000 ) { return 1; } return 0; } void show_anim_wait_seed( uint32_t now, uint32_t animation_start ) { uint32_t t_diff = (now - animation_start)%1000; uint16_t w; if( t_diff < 500 ) { // fade up w = (MAX_BRIGHTNESS/500) * t_diff; for( int i=0; i<12; i++ ) { led_set( i, w, w, w); } } else { // fade down w = MAX_BRIGHTNESS - (MAX_BRIGHTNESS/500) * (t_diff-500); for( int i=0; i<12; i++ ) { led_set( i, w, w, w); } } } int8_t show_intro( uint32_t now, uint32_t animation_start ) { // Animation: rotate a single LED once across the circle uint32_t t_diff = now - animation_start; uint16_t r,g,b; uint8_t index; static uint8_t tmp_sequence[12], tmp; static uint8_t step = 0; if( step == 0) { for( int i=0; i<12; i++) { tmp_sequence[i] = (random()%6)+1; } step = 1; } index = (t_diff%1200)/100; // print a chain of random colors if( !(t_diff % 100) && (step == 1) ) { PORTC ^=(1< 1200 ) { step = 2; } } // rotate chain 180 degrees if( !(t_diff % 100) && (step == 2) ) { // barrelshift every 100ms tmp = tmp_sequence[11]; for( int i=10; i>=0; i-- ) { tmp_sequence[i+1] = tmp_sequence[i]; } tmp_sequence[0] = tmp; // update all at once for(int i=0; i<12; i++ ) { get_color( &r, &g, &b, tmp_sequence[i] ); led_set( i, r, g, b ); } } //led_set( index, r, g, b ); if( (now - animation_start) > 2400 ) { step = 0; return 1; } return 0; } int8_t show_anim_ok( uint32_t now, uint32_t animation_start ) { uint32_t t_diff = now - animation_start; uint16_t g; if( t_diff < 500 ) { g = (MAX_BRIGHTNESS/500) * t_diff; for( int i=0; i<12; i++ ) { led_set( i, 0x00, g, 0x00); } } else { g = MAX_BRIGHTNESS - (MAX_BRIGHTNESS/500) * (t_diff-500); for( int i=0; i<12; i++ ) { led_set( i, 0x00, g, 0x00); } } if( t_diff > 1000 ) { for( int i=0; i<12; i++ ) { led_set( i, 0x00, 0x00, 0x00); } return 1; } return 0; } int8_t show_anim_nok( uint32_t now, uint32_t animation_start ) { uint32_t t_diff = now - animation_start; uint16_t r,g,b; if( t_diff%100 < 50 ) { for( int i=0; i<12; i++ ) { get_color( &r, &g, &b, COLOR_RED ); led_set( i, r,g,b ); } } else { for( int i=0; i<12; i++ ) { get_color( &r, &g, &b, COLOR_BLACK ); led_set( i, r,g,b ); } } if( t_diff > 1000 ) { for( int i=0; i<12; i++ ) { led_set( i, 0x00, 0x00, 0x00); } return 1; } return 0; } int8_t show_anim_win( uint32_t now, uint32_t animation_start ) { uint32_t t_diff = now - animation_start; uint16_t b; if( t_diff < 1000 ) { b = (MAX_BRIGHTNESS/1000) * t_diff; for( int i=0; i<12; i++ ) { led_set( i, 0x00, 0x00, b); } } else { b = MAX_BRIGHTNESS - (MAX_BRIGHTNESS/1000) * (t_diff-1000); for( int i=0; i<12; i++ ) { led_set( i, 0x00, 0x00, b); } } if( t_diff > 2000 ) { for( int i=0; i<12; i++ ) { led_set( i, 0x00, 0x00, 0x00); } return 1; } return 0; }