Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Nur sichtbare Faces + zugehörige Masken
- MusicDisc::RubikGame::Face MusicDisc::RubikGame::faces[MD_RG_FACES] = {
- // data size position normal pointers
- // Stein vorne oben links
- {(uint8_t*)d_rubiks_F_TL, sizeof(d_rubiks_F_TL), -1, -1, -1, 0, 0, -1, NULL, NULL, NULL},
- {(uint8_t*)d_rubiks_T_BL, sizeof(d_rubiks_T_BL), -1, -1, -1, 0, -1, 0, NULL, NULL, NULL},
- // Stein vorne oben rechts
- {(uint8_t*)d_rubiks_F_TR, sizeof(d_rubiks_F_TR), 1, -1, -1, 0, 0, -1, NULL, NULL, NULL},
- {(uint8_t*)d_rubiks_T_BR, sizeof(d_rubiks_T_BR), 1, -1, -1, 0, -1, 0, NULL, NULL, NULL},
- {(uint8_t*)d_rubiks_R_TL, sizeof(d_rubiks_R_TL), 1, -1, -1, 1, 0, 0, NULL, NULL, NULL},
- // Stein vorne unten links
- {(uint8_t*)d_rubiks_F_BL, sizeof(d_rubiks_F_BL), -1, 1, -1, 0, 0, -1, NULL, NULL, NULL},
- // Stein vorne unten rechts
- {(uint8_t*)d_rubiks_F_BR, sizeof(d_rubiks_F_BR), 1, 1, -1, 0, 0, -1, NULL, NULL, NULL},
- {(uint8_t*)d_rubiks_R_BL, sizeof(d_rubiks_R_BL), 1, 1, -1, 1, 0, 0, NULL, NULL, NULL},
- // Stein hinten unten rechts
- {(uint8_t*)d_rubiks_R_BR, sizeof(d_rubiks_R_BR), 1, 1, 1, 1, 0, 0, NULL, NULL, NULL},
- // Stein hinten oben links
- {(uint8_t*)d_rubiks_T_TL, sizeof(d_rubiks_T_TL), -1, -1, 1, 0, -1, 0, NULL, NULL, NULL},
- // Stein hinten oben rechts
- {(uint8_t*)d_rubiks_T_TR, sizeof(d_rubiks_T_TR), 1, -1, 1, 0, -1, 0, NULL, NULL, NULL},
- {(uint8_t*)d_rubiks_R_TR, sizeof(d_rubiks_R_TR), 1, -1, 1, 1, 0, 0, NULL, NULL, NULL}
- };
- // 8 Steine
- MusicDisc::RubikGame::Stone MusicDisc::RubikGame::stones[MD_RG_STONES] = {
- Stein vorne oben links
- MusicDisc::RubikGame::RubikGame(MusicDisc *p_disc) : m_disc(p_disc), m_congrats(0.0f)
- {
- for(int i = 0; i < MD_RG_FACES; i++) {
- faces[i].mask = new Image(Image::BMP, faces[i].data, faces[i].size);
- faces[i].pos = new Vector(faces[i].x, faces[i].y, faces[i].z);
- faces[i].normal = new Vector(faces[i].nx, faces[i].ny, faces[i].nz);
- }
- for(int i = 0; i < MD_RG_STONES; i++) {
- stones[i].pos = new Vector(stones[i].x, stones[i].y, stones[i].z);
- stones[i].face1.normal = new Vector(stones[i].face1.nx, stones[i].face1.ny, stones[i].face1.nz);
- stones[i].face2.normal = new Vector(stones[i].face2.nx, stones[i].face2.ny, stones[i].face2.nz);
- stones[i].face3.normal = new Vector(stones[i].face3.nx, stones[i].face3.ny, stones[i].face3.nz);
- stones[i].sides[0] = &stones[i].face1;
- stones[i].sides[1] = &stones[i].face2;
- stones[i].sides[2] = &stones[i].face3;
- }
- }
- MusicDisc::RubikGame::~RubikGame()
- {
- }
- void
- MusicDisc::RubikGame::Draw(uint32_t *p_screen, uint32_t p_x, uint32_t p_y)
- {
- uint32_t col_sub = 0x777777;
- int mx = m_disc->m_mx - 89, my = m_disc->m_my - 161;
- if(mx < 0 || mx > 12 || my < 0 || my > 11) {
- mx = -1, my = -1;
- }
- for(int i = 0; i < MD_RG_STONES; i++) {
- for(int j = 0; j < 3; j++) {
- for(int k = 0; k < MD_RG_FACES; k++) {
- if(
- (
- stones[i].pos->x != faces[k].pos->x ||
- stones[i].pos->y != faces[k].pos->y ||
- stones[i].pos->z != faces[k].pos->z
- ) || (
- stones[i].sides[j]->normal->x != faces[k].normal->x ||
- stones[i].sides[j]->normal->y != faces[k].normal->y ||
- stones[i].sides[j]->normal->z != faces[k].normal->z
- )
- ) continue;
- // face highlight
- bool highlight = false;
- /*if(mx != -1 && my != -1) {
- uint32_t *ts = faces[k].mask->data;
- for(uint32_t y = 0; y < faces[k].mask->h; y++) {
- for(uint32_t x = 0; x < faces[k].mask->w; x++) {
- if(!EXC(*ts) && mx == x && my == y) {
- highlight = true;
- break;
- }
- ts++;
- }
- }
- }*/
- // draw face
- uint32_t
- *s = faces[k].mask->data,
- *d = p_screen + OFFSET(p_x, p_y);
- for(uint32_t y = 0; y < faces[k].mask->h; y++) {
- for(uint32_t x = 0; x < faces[k].mask->w; x++) {
- if(!EXC(*s)) {
- // mix
- __m128i
- c = _mm_set1_epi32(stones[i].sides[j]->col),
- a = _mm_set1_epi32(col_sub);
- if(!highlight) c = _mm_subs_epu8(c, a);
- // set
- *d = *((uint32_t*)&c);
- }
- s++;
- d++;
- }
- d += NEO_WIDTH - faces[j].mask->w;
- }
- }
- }
- }
- if(m_congrats > 0.0f) {
- int tx = 120, ty = 155;
- uint8_t t[] = "HIDDEN TUNE";
- float
- x = (NEO_WIDTH >> 1) - (m_disc->m_anim_bird_fly->w >> 1) - 5,
- y = (NEO_HEIGHT >> 1) - (m_disc->m_anim_bird_fly->h >> 1) - 20;
- m_disc->m_anim_bird_fly->Draw(p_screen, NEO_WIDTH, x, y, m_congrats * 8.0f);
- for(int i = 0; i < sizeof(t); i++) {
- tx += m_disc->m_font_time->DrawChar(p_screen, NEO_WIDTH, t[i], tx, ty);
- }
- m_congrats -= m_disc->m_time_delta;
- }
- }
- void
- MusicDisc::RubikGame::Click(uint32_t p_x, uint32_t p_y)
- {
- // searched clicked face
- int found = -1;
- for(int k = 0; k < MD_RG_FACES; k++) {
- uint32_t *ts = faces[k].mask->data;
- for(uint32_t y = 0; y < faces[k].mask->h; y++) {
- for(uint32_t x = 0; x < faces[k].mask->w; x++) {
- if(!EXC(*ts) && p_x == x && p_y == y) {
- found = k;
- break;
- }
- ts++;
- }
- }
- }
- if(found != -1) {
- // search stone
- int stone = -1, side = -1;
- for(int i = 0; i < MD_RG_STONES; i++) {
- if(
- faces[found].pos->x != stones[i].pos->x ||
- faces[found].pos->y != stones[i].pos->y ||
- faces[found].pos->z != stones[i].pos->z
- ) continue;
- for(int j = 0; j < 3; j++) {
- if(
- faces[found].normal->x != stones[i].sides[j]->normal->x ||
- faces[found].normal->y != stones[i].sides[j]->normal->y ||
- faces[found].normal->z != stones[i].sides[j]->normal->z
- ) continue;
- side = j;
- break;
- }
- if(side != -1) {
- stone = i;
- break;
- }
- }
- // stone and side found, now get stones to move
- if(stone != -1 && side != -1) {
- // determine rotation
- Matrix m;
- Vector v;
- if(stones[stone].sides[side]->normal->x != 0.0f) { //if side is facing x
- if(stones[stone].pos->y == 1) {
- if(stones[stone].pos->z == -1) { //if stone is top left
- //rotate top layer clockwise
- m = MatrixRotateY(DEG2RAD(90.0f));
- v = Vector(0.0f, 1.0f, 0.0f);
- } else { //if(stones[stone].pos->z == 1) //if stone is top right
- //rotate top layer anticlockwise
- m = MatrixRotateY(DEG2RAD(-90.0f));
- v = Vector(0.0f, 1.0f, 0.0f);
- }
- } else { //if(stones[stone].pos->y == -1)
- if(stones[stone].pos->z == -1) { //if stone is bottom left
- //rotate bottom layer clockwise
- m = MatrixRotateY(DEG2RAD(90.0f));
- v = Vector(0.0f, -1.0f, 0.0f);
- } else { //if(stones[stone].pos->z == 1) //if stone is bottom right
- //rotate bottom layer anticlockwise
- m = MatrixRotateY(DEG2RAD(-90.0f));
- v = Vector(0.0f, -1.0f, 0.0f);
- }
- }
- } else if(stones[stone].sides[side]->normal->y != 0.0f) { //if side is facing y
- if(stones[stone].pos->z == 1) {
- if(stones[stone].pos->x == -1) { //if stone is top left
- //rotate back layer clockwise
- m = MatrixRotateZ(DEG2RAD(90.0f));
- v = Vector(0.0f, 0.0f, 1.0f);
- } else { //if(stones[stone].pos->x == 1) //if stone is top right
- //rotate back layer anticlockwise
- m = MatrixRotateZ(DEG2RAD(-90.0f));
- v = Vector(0.0f, 0.0f, 1.0f);
- }
- } else { //if(stones[stone].pos->z == -1)
- if(stones[stone].pos->x == -1) { //if stone is bottom left
- //rotate front layer clockwise
- m = MatrixRotateZ(DEG2RAD(90.0f));
- v = Vector(0.0f, 0.0f, -1.0f);
- } else { //if(stones[stone].pos->x == 1) //if stone is bottom right
- //rotate front layer anticlockwise
- m = MatrixRotateZ(DEG2RAD(-90.0f));
- v = Vector(0.0f, 0.0f, -1.0f);
- }
- }
- } else if(stones[stone].sides[side]->normal->z != 0.0f) { //if side is facing z
- if(stones[stone].pos->y == 1) {
- if(stones[stone].pos->x == -1) { //if stone is top left
- //rotate left layer clockwise
- m = MatrixRotateX(DEG2RAD(90.0f));
- v = Vector(-1.0f, 0.0f, 0.0f);
- } else { //if(stones[stone].pos->x == 1) //if stone is top right
- //rotate right layer clockwise
- m = MatrixRotateX(DEG2RAD(90.0f));
- v = Vector(1.0f, 0.0f, 0.0f);
- }
- } else { //if(stones[stone].pos->y == -1)
- if(stones[stone].pos->x == -1) { //if stone is bottom left
- //rotate left layer anticlockwise
- m = MatrixRotateX(DEG2RAD(-90.0f));
- v = Vector(-1.0f, 0.0f, 0.0f);
- } else { //if(stones[stone].pos->x == 1) //if stone is bottom right
- //rotate right layer anticlockwise
- m = MatrixRotateX(DEG2RAD(-90.0f));
- v = Vector(1.0f, 0.0f, 0.0f);
- }
- }
- }
- // determine stones which are on the same and searched side
- for(int i = 0; i < MD_RG_STONES; i++) {
- if(stones[i].pos->x == v.x || stones[i].pos->y == v.y || stones[i].pos->z == v.z) {
- for(int j = 0; j < 3; j++) {
- // rotate side
- (*(stones[i].sides[j]->normal)) = m * (*(stones[i].sides[j]->normal));
- stones[i].sides[j]->normal->Round();
- }
- // rotate stone
- (*stones[i].pos) = m * (*stones[i].pos);
- stones[i].pos->Round();
- }
- }
- }
- }
- // search for completed sides
- Vector normals[6] = {
- Vector(-1, 0, 0),
- Vector( 1, 0, 0),
- Vector( 0, -1, 0),
- Vector( 0, 1, 0),
- Vector( 0, 0, -1),
- Vector( 0, 0, 1),
- };
- uint32_t cube[6][4];
- int cube_idx[6] = {0, 0, 0, 0, 0, 0};
- // first collect all colors into cube structure
- for(int i = 0; i < MD_RG_STONES; i++) {
- for(int j = 0; j < 3; j++) {
- for(int k = 0; k < 6; k++) {
- if(
- stones[i].sides[j]->normal->x == normals[k].x &&
- stones[i].sides[j]->normal->y == normals[k].y &&
- stones[i].sides[j]->normal->z == normals[k].z
- ) {
- cube[k][cube_idx[k]++] = stones[i].sides[j]->col;
- }
- }
- }
- }
- // check for puzzle completion
- for(int i = 0; i < 6; i++) {
- int complete = true;
- uint32_t ini_col = cube[i][0];
- for(int j = 1; j < 4; j++) {
- if(ini_col != cube[i][j]) {
- complete = false;
- break;
- }
- }
- if(complete) {
- if(normals[i].x == 0.0f && normals[i].y == 0.0f && normals[i].z == -1.0f) {
- static int hidden_idx = -1;
- m_congrats = 2.0f;
- Player::Instance().Play(m_disc->m_nintendo);
- if(hidden_idx == -1) {
- hidden_idx = Player::Instance().Add((uint8_t*)d_hidden_tune, sizeof(d_hidden_tune));
- }
- Player::Instance().Play(hidden_idx);
- break;
- }
- }
- }
- }
Add Comment
Please, Sign In to add comment