예제 #1
0
파일: game.cpp 프로젝트: obono/ArduboyWorks
bool updateGame(void)
{
    /*  In cas of pausing  */
    if (state == STATE_PAUSE) {
        if (arduboy.buttonDown(A_BUTTON | B_BUTTON)) {
            state = STATE_GAME;
            ignoreCnt = 30; // 1/2 sec
            toDraw = true;
            dprintln("Resume");
        }
        return false;
    }

    /*  Move objects  */
    int scrollX = -playerX / 4;
    int scrollY = -playerY / 4;
    playerX += scrollX;
    playerY += scrollY;
    playerRotate += playerTorque;
    if (playerJump > -64) {
        if (--playerJump == 0) {
            pFloorBlur = NULL;
            if (state == STATE_CLEAR) {
                initLevel(false);
            }
        }
    }
    if (state != STATE_OVER) {
        moveFloors(scrollX, scrollY, playerJump);
    }
    moveChips(scrollX, scrollY, playerJump);

    /*  Player interaction  */
    if (state == STATE_GAME || state == STATE_OVER) {
        movePlayer();
        if (state == STATE_GAME) {
            gameFrames++;
            if (floorAry[floorIdxFirst].z < 0) {
                state = STATE_OVER;
                isHiscore = (setLastScore(score, gameFrames) == 0);
                counter = 480; // 8 secs
                arduboy.playScore2(soundOver, 1);
                dprint("Game Over: score=");
                dprintln(score);
            } else if (ignoreCnt == 0 && arduboy.buttonDown(A_BUTTON | B_BUTTON)) {
                state = STATE_PAUSE;
                dprintln("Pause");
            }
        } else {
            counter--;
            if (ignoreCnt == 0 && arduboy.buttonDown(A_BUTTON | B_BUTTON)) {
                initLevel(true);
            }
        }
    }
    if (ignoreCnt > 0) ignoreCnt--;
    toDraw = true;

    return (state == STATE_OVER && counter == 0);
}
예제 #2
0
파일: menu.cpp 프로젝트: obono/ArduboyWorks
void handleMenu(void)
{
    if (arduboy.buttonDown(UP_BUTTON) && menuItemPos > 0) {
        menuItemPos--;
        playSoundTick();
        isInvalidMenu = true;
        dprint(F("menuItemPos="));
        dprintln(menuItemPos);
    }
    if (arduboy.buttonDown(DOWN_BUTTON) && menuItemPos < menuItemCount - 1) {
        menuItemPos++;
        playSoundTick();
        isInvalidMenu = true;
        dprint(F("menuItemPos="));
        dprintln(menuItemPos);
    }
    if (isControlSound && arduboy.buttonDown(A_BUTTON)) {
        setSound(!arduboy.isAudioEnabled());
        playSoundClick();
        isInvalidMenu = true;
    }
    if (arduboy.buttonDown(B_BUTTON)) {
        menuItemAry[menuItemPos].func();
    }
}
예제 #3
0
파일: game.cpp 프로젝트: obono/ArduboyWorks
static void judgeVanish(int x, int y)
{
    memset(vanishFlg, 0, FIELD_H);
    OBJ_T die = field[y][x];
    if (die.type == OBJ_TYPE_1) {
        if (judgeHappyOne(x, y)) {
            int link = vanishHappyOne();
            setVanishEffect(OBJ_TYPE_1);
            score += link;
            dprint(F("Happy one "));
            dprintln(link);
        }
    } else {
        uint16_t chain;
        int link = judgeLinkedDice(x, y, die.type, &chain);
        if (link >= die.type) {
            if (chain < CHAIN_MAX) chain++;
            vanishLinkedDice(chain);
            setVanishEffect(die.type);
            score += (uint32_t) die.type * link * chain;
            maxChain = max(maxChain, chain);
            dprint(F("Valnish "));
            dprint(die.type * link);
            dprint(F(" x "));
            dprintln(chain);
        }
    }
    score = min(score, SCORE_MAX);
}
예제 #4
0
파일: game.cpp 프로젝트: obono/ArduboyWorks
static bool isGameOver(void)
{
#ifdef DEBUG
    if (dbgRecvChar == 'o') {
        pLargeLabel = F("DEBUG");
        return true;
    }
#endif
    switch (gameMode) {
    case GAME_MODE_ENDLESS:
        if (countValidDice >= FIELD_H * FIELD_W) {
            pLargeLabel = F("GAME OVER");
            if (record.endlessHiscore < score) {
                record.endlessHiscore = score;
                record.endlessMaxLevel = level;
                dprintln(F("New record! (Endless)"));
            }
            arduboy.playScore2(soundOver, 1);
            return true;
        }
        return false;
    case GAME_MODE_LIMITED:
        if (gameFrames >= FRAMES_3MINUTES) {
            pLargeLabel = F("TIME UP");
            if (record.limitedHiscore < score) {
                record.limitedHiscore = score;
                record.limitedMaxChain = maxChain;
                dprintln(F("New record! (Time Limited)"));
            }
            arduboy.playScore2(soundOver, 1);
            return true;
        }
        return false;
    case GAME_MODE_PUZZLE:
        if (step <= 0 || countValidDice == 0) {
            if (countValidDice == 0) {
                pLargeLabel = F("CLEAR");
                int idx = issue / 8;
                uint8_t bit = 1 << issue % 8;
                if ((record.puzzleClearFlag[idx] & bit) == 0) {
                    record.puzzleClearFlag[idx] |= bit;
                    record.puzzleClearCount++;
                    dprint(F("Clear puzzle issue "));
                    dprintln(issue);
                    if (issue < COUNT_ISSUES - 1) issue++;
                }
                arduboy.playScore2(soundClear, 1);
            } else {
                pLargeLabel = F("AGAIN");
                arduboy.playScore2(soundAgain, 1);
            }
            return true;
        }
        return false;
    }
}
예제 #5
0
파일: game.cpp 프로젝트: obono/ArduboyWorks
static void moveFloors(int scrollX, int scrollY, int scrollZ)
{
    FLOOR *pFloor;
    for (int i = 0; i < FLOORS_MANAGE; i++) {
        pFloor = &floorAry[i];
        if (pFloor->type != FLRTYPE_NONE) {
            pFloor->x += scrollX + pFloor->vx;
            pFloor->y += scrollY + pFloor->vy;
            pFloor->z += scrollZ;
            int z = pFloor->z;
            if (pFloor->type == FLRTYPE_VANISH) {
                if (z < 0) {
                    pFloor->size = pFloor->sizeBack;
                } else if (pFloor->size != pFloor->sizeBack && pFloor->size > 0) {
                    pFloor->size--;
                }
            }
            if (scrollZ <= 0 && z >= 0 && z + scrollZ - 1 < 0) {
                int diff = max(abs(pFloor->x - playerX), abs(pFloor->y - playerY));
                if (diff < pFloor->size * 128) {
                    springPlayer(pFloor, diff);
                    dprint("Spring floor ");
                    dprintln(i);
                }
            }
        }
    }

    pFloor = &floorAry[floorIdxFirst];
    if (pFloor->z > FLOOR_Z_MAX) {
        pFloor->type = FLRTYPE_NONE;
        floorIdxFirst = nextFloorIdx(floorIdxFirst);
        dprint("floorIdxFirst=");
        dprintln(floorIdxFirst);
    }

    pFloor = &floorAry[floorIdxLast];
    int z = pFloor->z;
    if (state == STATE_GAME && z >= 0 && pFloor->type != FLRTYPE_GOAL) {
        uint8_t pos = pFloor->pos + 1;
        uint8_t type = (pos == FLOORS_LEVEL) ? FLRTYPE_GOAL : flrTypes[random(flrTypesNum)];
        floorIdxLast = nextFloorIdx(floorIdxLast);
        addFloor(type, pos, rand() * 2, rand() * 2, z - (512 + level * 32));
        dprint("floorIdxLast=");
        dprintln(floorIdxLast);
    }

#ifdef DEBUG
    if (dbgRecvChar == 'z') {
        pFloor->type = FLRTYPE_GOAL;
        springPlayer(pFloor, 0);
    }
#endif
}
예제 #6
0
파일: game.cpp 프로젝트: obono/ArduboyWorks
static void initLevel(bool isStart) {
    if (isStart) {
        state = STATE_START;
        gameFrames = 0;
        score = 0;
        level = 0;
        arduboy.playScore2(soundStart, 0);
    } else {
        level++;
        arduboy.tunes.stopScore();
    }
    dprint("Init Level ");
    dprintln(level);

    flrTypesNum = 0;
    if (level < 6) flrTypes[flrTypesNum++] = FLRTYPE_NORMAL;
    if (level ==1) flrTypes[flrTypesNum++] = FLRTYPE_NORMAL;
    if (level & 1) flrTypes[flrTypesNum++] = FLRTYPE_MOVE;
    if (level & 2) flrTypes[flrTypesNum++] = FLRTYPE_VANISH;
    if (level & 4 || level == 8) flrTypes[flrTypesNum++] = FLRTYPE_SMALL;

    for (int i = 0; i < FLOORS_MANAGE; i++) {
        floorAry[i].type = FLRTYPE_NONE;
    }
    floorIdxFirst = 0;
    floorIdxLast = 0;
    addFloor(FLRTYPE_NORMAL, 0, playerX, playerY, FLOOR_Z_MAX);
}
예제 #7
0
파일: menu.cpp 프로젝트: obono/ArduboyWorks
void setMenuItemPos(int8_t pos)
{
    menuItemPos = pos;
    isInvalidMenu = true;
    dprint(F("menuItemPos="));
    dprintln(menuItemPos);
}
예제 #8
0
uint8_t matrix_scan(void)
{
    for (uint8_t col = 0; col < MATRIX_COLS; col++) {
        select_col(col);    
        _delay_us(3); // TODO: Determine the correct value needed here.
        uint8_t rows = read_rows();
        if((col == 0 && !LAYOUT_MINI) || (col == 2 && LAYOUT_MINI) ) {
            rows |= read_caps();
        }
        
        for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
            bool prev_bit = matrix_debouncing[row] & ((matrix_row_t)1<<col);
            bool curr_bit = rows & (1<<row);
            if (prev_bit != curr_bit) {
                matrix_debouncing[row] ^= ((matrix_row_t)1<<col);
                if (debouncing) {
                    dprint("bounce!: "); dprintf("%02X", debouncing); dprintln();
                }
                debouncing = DEBOUNCE;
            }
        }
        unselect_cols();
    }

    if (debouncing) {
        if (--debouncing) {
            _delay_ms(1);
        } else {
            for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
                matrix[i] = matrix_debouncing[i];
            }
        }
    }
    return 1;
}
예제 #9
0
파일: matrix.c 프로젝트: lmorchard/modelm
uint8_t matrix_scan(void)
{
    for (uint8_t col = 0; col < MATRIX_COLS; col++) {  // 0-16
        select_col(col);
        _delay_us(30);       // without this wait it won't read stable value.
        uint16_t rows = read_rows();
        for (uint8_t row = 0; row < MATRIX_ROWS; row++) {  // 0-5
            bool prev_bit = matrix_debouncing[row] & ((matrix_row_t)1<<col);
            bool curr_bit = rows & (1<<row);
            if (prev_bit != curr_bit) {
                matrix_debouncing[row] ^= ((matrix_row_t)1<<col);
                if (debouncing) {
                    dprint("bounce!: "); dprintf("%02X", debouncing); dprintln();
                }
                debouncing = DEBOUNCE;
            }
        }
        unselect_cols();
    }

    if (debouncing) {
        if (--debouncing) {
            _delay_ms(1);
        } else {
            for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
                matrix[i] = matrix_debouncing[i];
            }
        }
    }

    return 1;
}
예제 #10
0
static void moveCursor(int8_t vx, int8_t vy)
{
    if (cursorX + vx < 0 || cursorX + vx >= BOARD_W) vx = 0;
    if (cursorY + vy < 0 || cursorY + vy >= BOARD_H) vy = 0;
    if (vx != 0 || vy != 0) {
        cursorX += vx;
        cursorY += vy;
        focusPiece(cursorX, cursorY);
        toDrawAll = true;
    }
    if (arduboy.buttonDown(B_BUTTON) && focusPieceIdx >= 0) {
        arduboy.playScore2(soundPick, 2);
        state = STATE_PICKED;
        toDrawAll = true;
        dprint(F("Pick piece="));
        dprintln(focusPieceIdx);
    } else if (arduboy.buttonDown(A_BUTTON)) {
        playSoundClick();
        if (isDirty && creepFrames >= FRAMES_30SECS) {
            saveAndResetCreep();
        }
        state = STATE_LEAVE;
        toDrawAll = true;
    }
}
예제 #11
0
MODE_T updatePuzzle(void)
{
    handleDPad();
    if (state == STATE_FREE) {
        moveCursor(padX, padY);
        playFrames++;
    } else if (state == STATE_PICKED) {
        movePiece(padX, padY);
        playFrames++;
    } else if (state == STATE_CLEAR) {
        clearEffectCount--;
        if (clearEffectCount == 0) {
            arduboy.stopScore2();
            state = STATE_FREE;
            helpY = HEIGHT;
            toDrawAll = true;
        }
    }
    adjustHelpPosition();

    if (creepFrames < FRAMES_2MINS) {
        creepFrames++;
    }
    if (padRepeatCount == 0) {
        if (quietFrames < FRAMES_5SECS) {
            quietFrames++;
        } else if (isDirty && creepFrames >= FRAMES_2MINS) {
            saveAndResetCreep();
            dprintln(F("Auto save"));
        }
    } else {
        quietFrames = 0;
    }
    return (state == STATE_LEAVE) ? MODE_MENU : MODE_PUZZLE;
}
예제 #12
0
/** \brief Called to execute an action.
 *
 * FIXME: Needs documentation.
 */
void action_exec(keyevent_t event)
{
    if (!IS_NOEVENT(event)) {
        dprint("\n---- action_exec: start -----\n");
        dprint("EVENT: "); debug_event(event); dprintln();
#ifdef RETRO_TAPPING
        retro_tapping_counter++;
#endif
    }

#ifdef FAUXCLICKY_ENABLE
    if (IS_PRESSED(event)) {
        FAUXCLICKY_ACTION_PRESS;
    }
    if (IS_RELEASED(event)) {
        FAUXCLICKY_ACTION_RELEASE;
    }
    fauxclicky_check();
#endif

#ifdef SWAP_HANDS_ENABLE
    if (!IS_NOEVENT(event)) {
        process_hand_swap(&event);
    }
#endif

    keyrecord_t record = { .event = event };

#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
    if (has_oneshot_layer_timed_out()) {
        clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
    }
    if (has_oneshot_mods_timed_out()) {
        clear_oneshot_mods();
    }
#endif

#ifndef NO_ACTION_TAPPING
    action_tapping_process(record);
#else
    process_record(&record);
    if (!IS_NOEVENT(record.event)) {
        dprint("processed: "); debug_record(record); dprintln();
    }
#endif
}
예제 #13
0
static void layer_state_set(uint32_t state)
{
    dprint("layer_state: ");
    layer_debug(); dprint(" to ");
    layer_state = state;
    layer_debug(); dprintln();
    clear_keyboard_but_mods(); // To avoid stuck keys
}
예제 #14
0
void action_exec(keyevent_t event)
{
    if (!IS_NOEVENT(event)) {
        dprint("\n---- action_exec: start -----\n");
        dprint("EVENT: "); debug_event(event); dprintln();
    }

    keyrecord_t record = { .event = event };

#ifndef NO_ACTION_TAPPING
    action_tapping_process(record);
#else
    process_action(&record);
    if (!IS_NOEVENT(record.event)) {
        dprint("processed: "); debug_record(record); dprintln();
    }
#endif
}
예제 #15
0
파일: menu.cpp 프로젝트: obono/ArduboyWorks
void addMenuItem(const __FlashStringHelper *label, void (*func)(void))
{
    if (menuItemCount >= MENU_COUNT_MAX) return;
    ITEM_T *pItem = &menuItemAry[menuItemCount];
    pItem->label = label;
    pItem->func = func;
    menuItemCount++;
    dprint(F("Add menu items: "));
    dprintln(label);
}
예제 #16
0
파일: game.cpp 프로젝트: obono/ArduboyWorks
static void setLevel(int newLevel)
{
    level = newLevel;
    if (level == 1) norm = 0;

    uint8_t grade = level / 5;
    uint8_t gradeStep = level % 5;
    countDiceMin = min(12 + grade + gradeStep, 28);
    countDiceUsual = min(18 + grade * 2, 29) + gradeStep;
    countDiceMax = 35;
    intervalDieUsual = max(FPS * 4 - grade * 12 - gradeStep * 16, FPS / 2);
    intervalDieMax = FPS * 6 - grade * 5;
    norm += grade * 2 + 6;
    elaspedFrames = min(FPS * (grade - 10) / 2, 0);
    if (gradeStep == 0) elaspedFrames -= FPS * 4;
    blinkFrameFrames = BLINK_FRAME_FRAMES_MAX;
    blinkLevelFrames = BLINK_LEVEL_FRAMES_MAX;
    dprint(F("Level "));
    dprintln(level);
    dprintln(countDiceMin);
    dprintln(countDiceUsual);
    dprintln(intervalDieUsual);
    dprintln(intervalDieMax);
    dprintln(elaspedFrames);
}
예제 #17
0
파일: game.cpp 프로젝트: obono/ArduboyWorks
static void initPuzzleField(void)
{
    countDice = 0;
    const uint8_t *p = puzzleData + issue * BYTES_PER_ISSUE;
#ifdef DEBUG
    p = puzzleData;
#endif
    uint16_t buffer = 0, bits = 0;
    for (int y = 0; y < FIELD_H; y++) {
        for (int x = 0; x < FIELD_W; x++) {
            if (bits < 5) {
                buffer += pgm_read_byte(p++) << bits;
                bits += 8;
            }
            OBJ_T *pObj = &field[y][x];
            uint16_t data = buffer & 0x1F;
            if (data < 30) {
                if (data < 24) {
                    pObj->type = data / 4 + OBJ_TYPE_1;
                    pObj->rotate = data % 4;
                    pObj->mode = OBJ_MODE_NORMAL;
                } else {
                    pObj->type = data - 24 + OBJ_TYPE_1;
                    pObj->rotate = 0;
                    pObj->mode = OBJ_MODE_FIXED;
                }
                pObj->chain = 0;
                pObj->depth = 0;
                countDice++;
            } else {
                pObj->type = (data == 30) ? OBJ_TYPE_BLANK : OBJ_TYPE_FLOOR;
                pObj->rotate = 0;
                pObj->depth = DEPTH_MAX;
            }
            buffer >>= 5;
            bits -= 5;
        }
    }
    for (int y = 1; y < FIELD_H - 1; y++) {
        for (int x = 1; x < FIELD_W - 1; x++) {
            if (field[y][x].type == OBJ_TYPE_BLANK &&
                field[y - 1][x].type != OBJ_TYPE_BLANK && field[y + 1][x].type != OBJ_TYPE_BLANK &&
                field[y][x - 1].type != OBJ_TYPE_BLANK && field[y][x + 1].type != OBJ_TYPE_BLANK) {
                field[y][x].rotate = 1;
            }
        }
    }
    countValidDice = countDice;
    step = pgm_read_byte(p);
    dprint(F("Puzzle initialized "));
    dprintln(issue);
}
예제 #18
0
static void layer_state_set(uint32_t state)
{
    dprint("layer_state: ");
    layer_debug(); dprint(" to ");
    layer_state = state;
    layer_debug(); dprintln();
    clear_keyboard_but_mods(); // To avoid stuck keys

    // find highest set bit and set LED color appropriately
    uint8_t active_layer = 32 - __builtin_clzl(layer_state | default_layer_state) - 1;

    on_layer_change(active_layer);
}
예제 #19
0
static void encodePieces(CODE_T *pCode)
{
    PIECE_T pieceWorkAry[PIECES];
    memcpy(pieceWorkAry, pieceAry, sizeof(PIECE_T) * PIECES);
    uint8_t rot = pieceWorkAry[0].rot;
    PIECE_T *p = pieceWorkAry;
    rotatePieces(p, 0);
    pieceWorkAry[0].rot = rot;
    for (int i = 0; i < PIECES; i++, p++, pCode++) {
        pCode->xy = (p->x - 4) / 2 + p->y / 2 * 5;
        pCode->rot = p->rot;
    }
    dprintln(F("Encoded pieces"));
}
예제 #20
0
파일: game.cpp 프로젝트: obono/ArduboyWorks
static void initTrialField(void)
{
    for (int y = 0; y < FIELD_H; y++) {
        for (int x = 0; x < FIELD_W; x++) {
            OBJ_T *pObj = &field[y][x];
            pObj->type = OBJ_TYPE_FLOOR;
            pObj->depth = DEPTH_MAX;
        }
    }
    countDice = countValidDice = 0;
    for (int i = 0; i < COUNT_DICE_INITIAL; i++) {
        setDie(pickFloorObject(), OBJ_MODE_NORMAL);
    }
    dprintln(F("Field initialized"));
}
예제 #21
0
static uint8_t checkAndRegisterPieces(void)
{
    CODE_T code[PIECES], work[PIECES];
    encodePieces(code);
    dprintln(F("Checking history..."));
    for (int i = -1; i < clearCount; i++) {
        uint8_t idx = (i == -1) ? lastPatternIdx : i;
        if (idx < clearCount && i != lastPatternIdx) {
            readEncodedPieces(idx, work);
            if (code[0].xy == work[0].xy && memcmp(code + 1, work + 1, PIECES - 1) == 0) {
                return idx;
            }
        }
    }
    writeEncodedPieces(clearCount, code);
    return clearCount;
}
예제 #22
0
/** \brief Take a key event (key press or key release) and processes it.
 *
 * FIXME: Needs documentation.
 */
void process_record(keyrecord_t *record)
{
    if (IS_NOEVENT(record->event)) { return; }

    if(!process_record_quantum(record))
        return;

    action_t action = store_or_get_action(record->event.pressed, record->event.key);
    dprint("ACTION: "); debug_action(action);
#ifndef NO_ACTION_LAYER
    dprint(" layer_state: "); layer_debug();
    dprint(" default_layer_state: "); default_layer_debug();
#endif
    dprintln();

    process_action(record, action);
}
예제 #23
0
파일: game.cpp 프로젝트: obono/ArduboyWorks
static void updateGamePlaying(void)
{
#ifdef DEBUG
    if (dbgRecvChar == 'a') initTrialField();
    if (dbgRecvChar == 'l') norm = 0;
    if (dbgRecvChar == 'q') field[cursorY][cursorX].chain = CHAIN_MAX;
#endif
    if (vanishFlashFrames > 0) vanishFlashFrames--;
    if (blinkFrameFrames > 0) blinkFrameFrames--;
    if (blinkChainFrames > 0) blinkChainFrames--;
    if (blinkLevelFrames > 0) blinkLevelFrames--;
    handleDPad();
    updateField();
    moveCursor();
    if (gameMode == GAME_MODE_ENDLESS) {
        if (level < LEVEL_MAX && norm <= 0) {
            setLevel(level + 1);
            arduboy.playScore2(soundLevelUp, 2);
        }
    } else if (gameMode == GAME_MODE_LIMITED) {
        if (isTimeToBlinkFrame()) {
            arduboy.playScore2(soundTimeToBlink, 2);
            blinkFrameFrames = BLINK_FRAME_FRAMES_MAX;
        }
    }
    gameFrames++;
    record.playFrames++;
    blinkFlg = !blinkFlg;
    if (isGameOver()) {
        state = STATE_OVER;
        writeRecord();
        blinkFlg = false;
        overAnimFrames = OVER_ANIM_FRAMES_MAX;
        dprintln(F("Game over"));
    } else if (arduboy.buttonDown(A_BUTTON)) {
        setupMenu();
    }
    isInvalid = true;
}
예제 #24
0
파일: game.cpp 프로젝트: obono/ArduboyWorks
static void addFloor(uint8_t type, uint8_t pos, int16_t x, int16_t y, int16_t z)
{
    FLOOR *pFloor = &floorAry[floorIdxLast];
    pFloor->type = type;
    pFloor->pos = pos;
    pFloor->x = x;
    pFloor->y = y;
    pFloor->z = z;

    double vd = random(256) * PI / 128.0;
    int vr = (type == FLRTYPE_MOVE) ? 256 + level * 16 : 0;
    pFloor->vx = cos(vd) * vr;
    pFloor->vy = sin(vd) * vr;

    uint8_t size = (type == FLRTYPE_SMALL) ? 36 - level : 64 - level * 3;
    pFloor->size = max(size, 16);
    pFloor->sizeBack = pFloor->size;

    dprint("New Floor: type=");
    dprint(type);
    dprint(" size=");
    dprintln(size);
}
예제 #25
0
uint8_t matrix_scan(void) {
  for (uint8_t col = 0; col < MATRIX_COLS; col++) {
    select_col(col);
    _delay_us(3);

    uint8_t rows = read_rows();
    if(col == 0) {
      rows |= read_fwkey();
    }
    for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
      bool prev_bit = matrix_debouncing[row] & ((matrix_row_t)1<<col);
      bool curr_bit = rows & (1<<row);
      if (prev_bit != curr_bit) {
        matrix_debouncing[row] ^= ((matrix_row_t)1<<col);
        if (debouncing) {
            dprint("bounce!: "); dprintf("%02X", debouncing); dprintln();
        }        
        debouncing = DEBOUNCING_DELAY;
      }
    }
    unselect_cols();
  }

  if (debouncing) {
    if (--debouncing) {
      _delay_ms(1);
    } else {
      for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
        matrix[i] = matrix_debouncing[i];
      }
    }
  }

  matrix_scan_quantum();
  return 1;
}
예제 #26
0
void initPuzzle(void)
{
    if (state == STATE_INIT) {
        for (int i = 0; i < PIECES; i++) {
            pieceOrder[i] = i;
        }
        cursorX = 8;
        cursorY = 4;
        helpX = HELP_RIGHT_POS;
        creepFrames = 0;
        lastPatternIdx = 255; // trick!
        dprintln(F("Initialize puzzle"));
    }

    putPieces();
    focusPiece(cursorX, cursorY);
    state = STATE_FREE;
    padRepeatCount = 0;
    helpY = HEIGHT;
    if (!isDirty) {
        creepFrames = 0;
    }
    quietFrames = 0;
}
예제 #27
0
void decodePieces(CODE_T *pCode)
{
    PIECE_T *p = pieceAry;
    for (int i = 0; i < PIECES; i++, p++, pCode++) {
        p->x = pCode->xy % 5 * 2 + 4;
        p->y = pCode->xy / 5 * 2;
        p->rot = pCode->rot;
        if (i <= 1) { // white, green
            if (p->rot & 1) {
                p->y++;
            } else {
                p->x++;
            }
        } else if (i >= 3 && i <= 7) { // orange, red, pink, gray, blue
            p->x++;
            p->y++;
        }

    }
    uint8_t rot = pieceAry[0].rot;
    pieceAry[0].rot = 0;
    rotatePieces(pieceAry, rot);
    dprintln(F("Decoded pieces"));
}
static inline void bluefruit_trace_footer()
{
    dprintln();
}
예제 #29
0
void process_action(keyrecord_t *record)
{
    keyevent_t event = record->event;
#ifndef NO_ACTION_TAPPING
    uint8_t tap_count = record->tap.count;
#endif

    if (IS_NOEVENT(event)) { return; }

    action_t action = layer_switch_get_action(event.key);
    dprint("ACTION: "); debug_action(action);
#ifndef NO_ACTION_LAYER
    dprint(" layer_state: "); layer_debug();
    dprint(" default_layer_state: "); default_layer_debug();
#endif
    dprintln();

    switch (action.kind.id) {
        /* Key and Mods */
        case ACT_LMODS:
        case ACT_RMODS:
            {
                uint8_t mods = (action.kind.id == ACT_LMODS) ?  action.key.mods :
                                                                action.key.mods<<4;
                if (event.pressed) {
                    if (mods) {
                        add_weak_mods(mods);
                        send_keyboard_report();
                    }
                    register_code(action.key.code);
                } else {
                    unregister_code(action.key.code);
                    if (mods) {
                        del_weak_mods(mods);
                        send_keyboard_report();
                    }
                }
            }
            break;
#ifndef NO_ACTION_TAPPING
        case ACT_LMODS_TAP:
        case ACT_RMODS_TAP:
            {
                uint8_t mods = (action.kind.id == ACT_LMODS_TAP) ?  action.key.mods :
                                                                    action.key.mods<<4;
                switch (action.layer_tap.code) {
    #ifndef NO_ACTION_ONESHOT
                    case MODS_ONESHOT:
                        // Oneshot modifier
                        if (event.pressed) {
                            if (tap_count == 0) {
                                register_mods(mods);
                            }
                            else if (tap_count == 1) {
                                dprint("MODS_TAP: Oneshot: start\n");
                                set_oneshot_mods(mods);
                            }
                            else {
                                register_mods(mods);
                            }
                        } else {
                            if (tap_count == 0) {
                                clear_oneshot_mods();
                                unregister_mods(mods);
                            }
                            else if (tap_count == 1) {
                                // Retain Oneshot mods
                            }
                            else {
                                clear_oneshot_mods();
                                unregister_mods(mods);
                            }
                        }
                        break;
    #endif
                    case MODS_TAP_TOGGLE:
                        if (event.pressed) {
                            if (tap_count <= TAPPING_TOGGLE) {
                                register_mods(mods);
                            }
                        } else {
                            if (tap_count < TAPPING_TOGGLE) {
                                unregister_mods(mods);
                            }
                        }
                        break;
                    default:
                        if (event.pressed) {
                            if (tap_count > 0) {
                                if (record->tap.interrupted) {
                                    dprint("MODS_TAP: Tap: Cancel: add_mods\n");
                                    // ad hoc: set 0 to cancel tap
                                    record->tap.count = 0;
                                    register_mods(mods);
                                } else {
                                    dprint("MODS_TAP: Tap: register_code\n");
                                    register_code(action.key.code);
                                }
                            } else {
                                dprint("MODS_TAP: No tap: add_mods\n");
                                register_mods(mods);
                            }
                        } else {
                            if (tap_count > 0) {
                                dprint("MODS_TAP: Tap: unregister_code\n");
                                unregister_code(action.key.code);
                            } else {
                                dprint("MODS_TAP: No tap: add_mods\n");
                                unregister_mods(mods);
                            }
                        }
                        break;
                }
            }
            break;
#endif
#ifdef EXTRAKEY_ENABLE
        /* other HID usage */
        case ACT_USAGE:
            switch (action.usage.page) {
                case PAGE_SYSTEM:
                    if (event.pressed) {
                        host_system_send(action.usage.code);
                    } else {
                        host_system_send(0);
                    }
                    break;
                case PAGE_CONSUMER:
                    if (event.pressed) {
                        host_consumer_send(action.usage.code);
                    } else {
                        host_consumer_send(0);
                    }
                    break;
            }
            break;
#endif
#ifdef MOUSEKEY_ENABLE
        /* Mouse key */
        case ACT_MOUSEKEY:
            if (event.pressed) {
                mousekey_on(action.key.code);
                mousekey_send();
            } else {
                mousekey_off(action.key.code);
                mousekey_send();
            }
            break;
#endif
#ifndef NO_ACTION_LAYER
        case ACT_LAYER:
            if (action.layer_bitop.on == 0) {
                /* Default Layer Bitwise Operation */
                if (!event.pressed) {
                    uint8_t shift = action.layer_bitop.part*4;
                    uint32_t bits = ((uint32_t)action.layer_bitop.bits)<<shift;
                    uint32_t mask = (action.layer_bitop.xbit) ? ~(((uint32_t)0xf)<<shift) : 0;
                    switch (action.layer_bitop.op) {
                        case OP_BIT_AND: default_layer_and(bits | mask); break;
                        case OP_BIT_OR:  default_layer_or(bits | mask);  break;
                        case OP_BIT_XOR: default_layer_xor(bits | mask); break;
                        case OP_BIT_SET: default_layer_and(mask); default_layer_or(bits); break;
                    }
                }
            } else {
                /* Layer Bitwise Operation */
                if (event.pressed ? (action.layer_bitop.on & ON_PRESS) :
                                    (action.layer_bitop.on & ON_RELEASE)) {
                    uint8_t shift = action.layer_bitop.part*4;
                    uint32_t bits = ((uint32_t)action.layer_bitop.bits)<<shift;
                    uint32_t mask = (action.layer_bitop.xbit) ? ~(((uint32_t)0xf)<<shift) : 0;
                    switch (action.layer_bitop.op) {
                        case OP_BIT_AND: layer_and(bits | mask); break;
                        case OP_BIT_OR:  layer_or(bits | mask);  break;
                        case OP_BIT_XOR: layer_xor(bits | mask); break;
                        case OP_BIT_SET: layer_and(mask); layer_or(bits); break;
                    }
                }
            }
            break;
    #ifndef NO_ACTION_TAPPING
        case ACT_LAYER_TAP:
        case ACT_LAYER_TAP_EXT:
            switch (action.layer_tap.code) {
                case 0xe0 ... 0xef:
                    /* layer On/Off with modifiers(left only) */
                    if (event.pressed) {
                        layer_on(action.layer_tap.val);
                        register_mods(action.layer_tap.code & 0x0f);
                    } else {
                        layer_off(action.layer_tap.val);
                        unregister_mods(action.layer_tap.code & 0x0f);
                    }
                    break;
                case OP_TAP_TOGGLE:
                    /* tap toggle */
                    if (event.pressed) {
                        if (tap_count < TAPPING_TOGGLE) {
                            layer_invert(action.layer_tap.val);
                        }
                    } else {
                        if (tap_count <= TAPPING_TOGGLE) {
                            layer_invert(action.layer_tap.val);
                        }
                    }
                    break;
                case OP_ON_OFF:
                    event.pressed ? layer_on(action.layer_tap.val) :
                                    layer_off(action.layer_tap.val);
                    break;
                case OP_OFF_ON:
                    event.pressed ? layer_off(action.layer_tap.val) :
                                    layer_on(action.layer_tap.val);
                    break;
                case OP_SET_CLEAR:
                    event.pressed ? layer_move(action.layer_tap.val) :
                                    layer_clear();
                    break;
                default:
                    /* tap key */
                    if (event.pressed) {
                        if (tap_count > 0) {
                            dprint("KEYMAP_TAP_KEY: Tap: register_code\n");
                            register_code(action.layer_tap.code);
                        } else {
                            dprint("KEYMAP_TAP_KEY: No tap: On on press\n");
                            layer_on(action.layer_tap.val);
                        }
                    } else {
                        if (tap_count > 0) {
                            dprint("KEYMAP_TAP_KEY: Tap: unregister_code\n");
                            unregister_code(action.layer_tap.code);
                        } else {
                            dprint("KEYMAP_TAP_KEY: No tap: Off on release\n");
                            layer_off(action.layer_tap.val);
                        }
                    }
                    break;
            }
            break;
    #endif
#endif
        /* Extentions */
#ifndef NO_ACTION_MACRO
        case ACT_MACRO:
            action_macro_play(action_get_macro(record, action.func.id, action.func.opt));
            break;
#endif
#ifdef BACKLIGHT_ENABLE
        case ACT_BACKLIGHT:
            if (!event.pressed) {
                switch (action.backlight.opt) {
                    case BACKLIGHT_INCREASE:
                        backlight_increase();
                        break;
                    case BACKLIGHT_DECREASE:
                        backlight_decrease();
                        break;
                    case BACKLIGHT_TOGGLE:
                        backlight_toggle();
                        break;
                    case BACKLIGHT_STEP:
                        backlight_step();
                        break;
                    case BACKLIGHT_LEVEL:
                        backlight_level(action.backlight.level);
                        break;
                }
            }
            break;
#endif
        case ACT_COMMAND:
            break;
#ifndef NO_ACTION_FUNCTION
        case ACT_FUNCTION:
            action_function(record, action.func.id, action.func.opt);
            break;
#endif
        default:
            break;
    }
}
예제 #30
0
static void movePiece(int8_t vx, int8_t vy)
{
    PIECE_T *p = &pieceAry[focusPieceIdx];
    if (arduboy.buttonPressed(A_BUTTON)) {
        int vr = 0;
        if (arduboy.buttonDown(LEFT_BUTTON))  vr--;
        if (arduboy.buttonDown(RIGHT_BUTTON)) vr++;
        if (vr != 0) {
            arduboy.playScore2(soundRotate, 3);
            p->rot = rotatePiece(focusPieceIdx, p->rot, vr);
            isDirty = true;
            toDrawAll = true;
        } else if (arduboy.buttonDown(UP_BUTTON | DOWN_BUTTON)) {
            arduboy.playScore2(soundFlip, 3);
            p->rot = flipPiece(focusPieceIdx, p->rot);
            isDirty = true;
            toDrawAll = true;
        }
        if (toDrawAll) {
            dprint(F("Rotate rot="));
            dprintln(p->rot);
        }
    } else {
        int g = (focusPieceIdx < 3) ? 0 : 1;
        if (p->x + vx < g || p->x + vx >= BOARD_W - g) vx = 0;
        if (p->y + vy < g || p->y + vy >= BOARD_H - g) vy = 0;
        if (vx != 0 || vy != 0) {
            playSoundTick();
            p->x += vx;
            p->y += vy;
            isDirty = true; 
            toDrawAll = true;
        }
        if (arduboy.buttonDown(B_BUTTON)) {
            if (putPieces()) {
                arduboy.playScore2(soundPut, 2);
                state = STATE_FREE;
                dprintln(F("Release"));
            } else {
                uint8_t idx = checkAndRegisterPieces();
                isNew = (idx == clearCount);
                if (idx == lastPatternIdx) {
                    arduboy.playScore2(soundPut, 2);
                    state = STATE_FREE;
                } else {
                    lastPatternIdx = idx;
                    if (isNew) {
                        arduboy.playScore2(soundNewPattern, 1);
                        clearCount++;
                        saveAndResetCreep();
                        setGalleryIndex(idx);
                        clearEffectCount = 120;
                    } else {
                        arduboy.playScore2(soundExistedPattern, 1);
                        clearEffectCount = 60;
                    }
                    state = STATE_CLEAR;
                }
                dprint(F("Completed! isNew="));
                dprintln(isNew);
            }
            cursorX = p->x;
            cursorY = p->y;
            if (board[p->y][p->x].idx != focusPieceIdx) {
                cursorY += (board[p->y - 1][p->x].idx == focusPieceIdx) ? -1 : 1;
            }
            toDrawAll = true;
        }
    }
}