Guest User

Untitled

a guest
Jul 18th, 2018
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.10 KB | None | 0 0
  1. // Nur sichtbare Faces + zugehörige Masken
  2. MusicDisc::RubikGame::Face MusicDisc::RubikGame::faces[MD_RG_FACES] = {
  3.     // data                   size                   position    normal      pointers
  4.     // Stein vorne oben links
  5.     {(uint8_t*)d_rubiks_F_TL, sizeof(d_rubiks_F_TL), -1, -1, -1,  0,  0, -1, NULL, NULL, NULL},
  6.     {(uint8_t*)d_rubiks_T_BL, sizeof(d_rubiks_T_BL), -1, -1, -1,  0, -1,  0, NULL, NULL, NULL},
  7.     // Stein vorne oben rechts
  8.     {(uint8_t*)d_rubiks_F_TR, sizeof(d_rubiks_F_TR),  1, -1, -1,  0,  0, -1, NULL, NULL, NULL},
  9.     {(uint8_t*)d_rubiks_T_BR, sizeof(d_rubiks_T_BR),  1, -1, -1,  0, -1,  0, NULL, NULL, NULL},
  10.     {(uint8_t*)d_rubiks_R_TL, sizeof(d_rubiks_R_TL),  1, -1, -1,  1,  0,  0, NULL, NULL, NULL},
  11.     // Stein vorne unten links
  12.     {(uint8_t*)d_rubiks_F_BL, sizeof(d_rubiks_F_BL), -1,  1, -1,  0,  0, -1, NULL, NULL, NULL},
  13.     // Stein vorne unten rechts
  14.     {(uint8_t*)d_rubiks_F_BR, sizeof(d_rubiks_F_BR),  1,  1, -1,  0,  0, -1, NULL, NULL, NULL},
  15.     {(uint8_t*)d_rubiks_R_BL, sizeof(d_rubiks_R_BL),  1,  1, -1,  1,  0,  0, NULL, NULL, NULL},
  16.     // Stein hinten unten rechts
  17.     {(uint8_t*)d_rubiks_R_BR, sizeof(d_rubiks_R_BR),  1,  1,  1,  1,  0,  0, NULL, NULL, NULL},
  18.     // Stein hinten oben links
  19.     {(uint8_t*)d_rubiks_T_TL, sizeof(d_rubiks_T_TL), -1, -1,  1,  0, -1,  0, NULL, NULL, NULL},
  20.     // Stein hinten oben rechts
  21.     {(uint8_t*)d_rubiks_T_TR, sizeof(d_rubiks_T_TR),  1, -1,  1,  0, -1,  0, NULL, NULL, NULL},
  22.     {(uint8_t*)d_rubiks_R_TR, sizeof(d_rubiks_R_TR),  1, -1,  1,  1,  0,  0, NULL, NULL, NULL}
  23. };
  24.  
  25. // 8 Steine
  26. MusicDisc::RubikGame::Stone MusicDisc::RubikGame::stones[MD_RG_STONES] = {
  27. Stein vorne oben links
  28.  
  29. MusicDisc::RubikGame::RubikGame(MusicDisc *p_disc) : m_disc(p_disc), m_congrats(0.0f)
  30. {
  31.     for(int i = 0; i < MD_RG_FACES; i++) {
  32.         faces[i].mask   = new Image(Image::BMP, faces[i].data, faces[i].size);
  33.         faces[i].pos    = new Vector(faces[i].x,  faces[i].y,  faces[i].z);
  34.         faces[i].normal = new Vector(faces[i].nx, faces[i].ny, faces[i].nz);
  35.     }
  36.  
  37.     for(int i = 0; i < MD_RG_STONES; i++) {
  38.         stones[i].pos          = new Vector(stones[i].x,        stones[i].y,        stones[i].z);
  39.         stones[i].face1.normal = new Vector(stones[i].face1.nx, stones[i].face1.ny, stones[i].face1.nz);
  40.         stones[i].face2.normal = new Vector(stones[i].face2.nx, stones[i].face2.ny, stones[i].face2.nz);
  41.         stones[i].face3.normal = new Vector(stones[i].face3.nx, stones[i].face3.ny, stones[i].face3.nz);
  42.         stones[i].sides[0] = &stones[i].face1;
  43.         stones[i].sides[1] = &stones[i].face2;
  44.         stones[i].sides[2] = &stones[i].face3;
  45.     }
  46. }
  47.  
  48. MusicDisc::RubikGame::~RubikGame()
  49. {
  50. }
  51.  
  52. void
  53. MusicDisc::RubikGame::Draw(uint32_t *p_screen, uint32_t p_x, uint32_t p_y)
  54. {
  55.     uint32_t col_sub = 0x777777;
  56.     int mx = m_disc->m_mx - 89, my = m_disc->m_my - 161;
  57.     if(mx < 0 || mx > 12 || my < 0 || my > 11) {
  58.         mx = -1, my = -1;
  59.     }
  60.  
  61.     for(int i = 0; i < MD_RG_STONES; i++) {
  62.         for(int j = 0; j < 3; j++) {
  63.             for(int k = 0; k < MD_RG_FACES; k++) {
  64.                 if(
  65.                     (
  66.                         stones[i].pos->x != faces[k].pos->x ||
  67.                         stones[i].pos->y != faces[k].pos->y ||
  68.                         stones[i].pos->z != faces[k].pos->z
  69.                     ) || (
  70.                         stones[i].sides[j]->normal->x != faces[k].normal->x ||
  71.                         stones[i].sides[j]->normal->y != faces[k].normal->y ||
  72.                         stones[i].sides[j]->normal->z != faces[k].normal->z
  73.                     )
  74.                 ) continue;
  75.                
  76.                 // face highlight
  77.                 bool highlight = false;
  78.                 /*if(mx != -1 && my != -1) {
  79.                     uint32_t *ts = faces[k].mask->data;
  80.                     for(uint32_t y = 0; y < faces[k].mask->h; y++) {
  81.                         for(uint32_t x = 0; x < faces[k].mask->w; x++) {
  82.                             if(!EXC(*ts) && mx == x && my == y) {
  83.                                 highlight = true;
  84.                                 break;
  85.                             }
  86.                             ts++;
  87.                         }
  88.                     }
  89.                 }*/
  90.  
  91.                 // draw face
  92.                 uint32_t
  93.                     *s = faces[k].mask->data,
  94.                     *d = p_screen + OFFSET(p_x, p_y);
  95.                 for(uint32_t y = 0; y < faces[k].mask->h; y++) {
  96.                     for(uint32_t x = 0; x < faces[k].mask->w; x++) {
  97.                         if(!EXC(*s)) {
  98.                             // mix
  99.                             __m128i
  100.                                 c = _mm_set1_epi32(stones[i].sides[j]->col),
  101.                                 a = _mm_set1_epi32(col_sub);
  102.  
  103.                             if(!highlight) c = _mm_subs_epu8(c, a);
  104.  
  105.                             // set
  106.                             *d = *((uint32_t*)&c);
  107.                         }
  108.                         s++;
  109.                         d++;
  110.                     }
  111.                     d += NEO_WIDTH - faces[j].mask->w;
  112.                 }              
  113.             }
  114.         }
  115.     }
  116.  
  117.     if(m_congrats > 0.0f) {
  118.         int tx = 120, ty = 155;
  119.         uint8_t t[] = "HIDDEN TUNE";
  120.         float
  121.             x = (NEO_WIDTH  >> 1) - (m_disc->m_anim_bird_fly->w >> 1) - 5,
  122.             y = (NEO_HEIGHT >> 1) - (m_disc->m_anim_bird_fly->h >> 1) - 20;
  123.         m_disc->m_anim_bird_fly->Draw(p_screen, NEO_WIDTH, x, y, m_congrats * 8.0f);
  124.         for(int i = 0; i < sizeof(t); i++) {
  125.             tx += m_disc->m_font_time->DrawChar(p_screen, NEO_WIDTH, t[i], tx, ty);
  126.         }      
  127.         m_congrats -= m_disc->m_time_delta;
  128.     }
  129. }
  130.  
  131. void
  132. MusicDisc::RubikGame::Click(uint32_t p_x, uint32_t p_y)
  133. {
  134.     // searched clicked face
  135.     int found = -1;
  136.     for(int k = 0; k < MD_RG_FACES; k++) {
  137.         uint32_t *ts = faces[k].mask->data;
  138.         for(uint32_t y = 0; y < faces[k].mask->h; y++) {
  139.             for(uint32_t x = 0; x < faces[k].mask->w; x++) {
  140.                 if(!EXC(*ts) && p_x == x && p_y == y) {
  141.                     found = k;
  142.                     break;
  143.                 }
  144.                 ts++;
  145.             }
  146.         }
  147.     }
  148.    
  149.     if(found != -1) {
  150.         // search stone
  151.         int stone = -1, side = -1;
  152.  
  153.         for(int i = 0; i < MD_RG_STONES; i++) {
  154.             if(
  155.                 faces[found].pos->x != stones[i].pos->x ||
  156.                 faces[found].pos->y != stones[i].pos->y ||
  157.                 faces[found].pos->z != stones[i].pos->z
  158.             ) continue;
  159.  
  160.             for(int j = 0; j < 3; j++) {
  161.                 if(
  162.                     faces[found].normal->x != stones[i].sides[j]->normal->x ||
  163.                     faces[found].normal->y != stones[i].sides[j]->normal->y ||
  164.                     faces[found].normal->z != stones[i].sides[j]->normal->z
  165.                 ) continue;
  166.                
  167.                 side = j;
  168.                 break;
  169.             }
  170.  
  171.             if(side != -1) {
  172.                 stone = i;
  173.                 break;
  174.             }
  175.         }
  176.        
  177.         // stone and side found, now get stones to move
  178.         if(stone != -1 && side != -1) {
  179.  
  180.             // determine rotation
  181.             Matrix m;
  182.             Vector v;
  183.        
  184.             if(stones[stone].sides[side]->normal->x != 0.0f) {  //if side is facing x
  185.                 if(stones[stone].pos->y == 1) {
  186.                     if(stones[stone].pos->z == -1) {            //if stone is top left
  187.                                                                     //rotate top layer clockwise
  188.                         m = MatrixRotateY(DEG2RAD(90.0f));
  189.                         v = Vector(0.0f, 1.0f, 0.0f);
  190.                     } else { //if(stones[stone].pos->z == 1)    //if stone is top right
  191.                                                                     //rotate top layer anticlockwise
  192.                         m = MatrixRotateY(DEG2RAD(-90.0f));
  193.                         v = Vector(0.0f, 1.0f, 0.0f);
  194.                     }
  195.                 } else { //if(stones[stone].pos->y == -1)
  196.                     if(stones[stone].pos->z == -1) {            //if stone is bottom left
  197.                                                                     //rotate bottom layer clockwise
  198.                         m = MatrixRotateY(DEG2RAD(90.0f));
  199.                         v = Vector(0.0f, -1.0f, 0.0f);
  200.                     } else { //if(stones[stone].pos->z == 1)    //if stone is bottom right
  201.                                                                     //rotate bottom layer anticlockwise
  202.                         m = MatrixRotateY(DEG2RAD(-90.0f));
  203.                         v = Vector(0.0f, -1.0f, 0.0f);
  204.                     }                
  205.                 }                
  206.             } else if(stones[stone].sides[side]->normal->y != 0.0f) {  //if side is facing y
  207.                 if(stones[stone].pos->z == 1) {
  208.                     if(stones[stone].pos->x == -1) {            //if stone is top left
  209.                                                                     //rotate back layer clockwise
  210.                         m = MatrixRotateZ(DEG2RAD(90.0f));
  211.                         v = Vector(0.0f, 0.0f, 1.0f);
  212.                     } else { //if(stones[stone].pos->x == 1)    //if stone is top right
  213.                                                                     //rotate back layer anticlockwise
  214.                         m = MatrixRotateZ(DEG2RAD(-90.0f));
  215.                         v = Vector(0.0f, 0.0f, 1.0f);
  216.                     }
  217.                 } else { //if(stones[stone].pos->z == -1)
  218.                     if(stones[stone].pos->x == -1) {            //if stone is bottom left
  219.                                                                     //rotate front layer clockwise
  220.                         m = MatrixRotateZ(DEG2RAD(90.0f));
  221.                         v = Vector(0.0f, 0.0f, -1.0f);
  222.                     } else { //if(stones[stone].pos->x == 1)    //if stone is bottom right
  223.                                                                     //rotate front layer anticlockwise
  224.                         m = MatrixRotateZ(DEG2RAD(-90.0f));
  225.                         v = Vector(0.0f, 0.0f, -1.0f);
  226.                     }                
  227.                 }              
  228.             } else if(stones[stone].sides[side]->normal->z != 0.0f) { //if side is facing z
  229.                 if(stones[stone].pos->y == 1) {
  230.                     if(stones[stone].pos->x == -1) {            //if stone is top left
  231.                                                                     //rotate left layer clockwise
  232.                         m = MatrixRotateX(DEG2RAD(90.0f));
  233.                         v = Vector(-1.0f, 0.0f, 0.0f);
  234.                     } else { //if(stones[stone].pos->x == 1)    //if stone is top right
  235.                                                                     //rotate right layer clockwise
  236.                         m = MatrixRotateX(DEG2RAD(90.0f));
  237.                         v = Vector(1.0f, 0.0f, 0.0f);
  238.                     }
  239.                 } else { //if(stones[stone].pos->y == -1)
  240.                     if(stones[stone].pos->x == -1) {            //if stone is bottom left
  241.                                                                     //rotate left layer anticlockwise
  242.                         m = MatrixRotateX(DEG2RAD(-90.0f));
  243.                         v = Vector(-1.0f, 0.0f, 0.0f);
  244.                     } else { //if(stones[stone].pos->x == 1)    //if stone is bottom right
  245.                                                                     //rotate right layer anticlockwise
  246.                         m = MatrixRotateX(DEG2RAD(-90.0f));
  247.                         v = Vector(1.0f, 0.0f, 0.0f);
  248.                     }                
  249.                 }              
  250.             }
  251.            
  252.             // determine stones which are on the same and searched side
  253.             for(int i = 0; i < MD_RG_STONES; i++) {
  254.                 if(stones[i].pos->x == v.x || stones[i].pos->y == v.y || stones[i].pos->z == v.z) {
  255.                     for(int j = 0; j < 3; j++) {
  256.                         // rotate side
  257.                         (*(stones[i].sides[j]->normal)) = m * (*(stones[i].sides[j]->normal));
  258.                         stones[i].sides[j]->normal->Round();
  259.                     }
  260.  
  261.                     // rotate stone
  262.                     (*stones[i].pos) = m * (*stones[i].pos);
  263.                     stones[i].pos->Round();
  264.                 }
  265.             }
  266.         }
  267.     }
  268.  
  269.     // search for completed sides
  270.     Vector normals[6] = {
  271.         Vector(-1,  0,  0),
  272.         Vector( 1,  0,  0),
  273.         Vector( 0, -1,  0),
  274.         Vector( 0,  1,  0),
  275.         Vector( 0,  0, -1),
  276.         Vector( 0,  0,  1),
  277.     };
  278.     uint32_t cube[6][4];
  279.     int cube_idx[6] = {0, 0, 0, 0, 0, 0};
  280.  
  281.     // first collect all colors into cube structure
  282.     for(int i = 0; i < MD_RG_STONES; i++) {
  283.         for(int j = 0; j < 3; j++) {
  284.             for(int k = 0; k < 6; k++) {
  285.                 if(
  286.                     stones[i].sides[j]->normal->x == normals[k].x &&
  287.                     stones[i].sides[j]->normal->y == normals[k].y &&
  288.                     stones[i].sides[j]->normal->z == normals[k].z
  289.                 ) {
  290.                     cube[k][cube_idx[k]++] = stones[i].sides[j]->col;
  291.                 }
  292.             }
  293.         }
  294.     }
  295.  
  296.     // check for puzzle completion
  297.     for(int i = 0; i < 6; i++) {
  298.         int complete = true;
  299.         uint32_t ini_col = cube[i][0];
  300.  
  301.         for(int j = 1; j < 4; j++) {
  302.             if(ini_col != cube[i][j]) {
  303.                 complete = false;
  304.                 break;
  305.             }
  306.         }
  307.  
  308.         if(complete) {
  309.             if(normals[i].x == 0.0f && normals[i].y == 0.0f && normals[i].z == -1.0f) {
  310.                 static int hidden_idx = -1;
  311.  
  312.                 m_congrats = 2.0f;
  313.                 Player::Instance().Play(m_disc->m_nintendo);
  314.                
  315.                 if(hidden_idx == -1) {
  316.                     hidden_idx = Player::Instance().Add((uint8_t*)d_hidden_tune, sizeof(d_hidden_tune));
  317.                 }
  318.                 Player::Instance().Play(hidden_idx);
  319.                 break;
  320.             }
  321.         }
  322.     }
  323. }
Add Comment
Please, Sign In to add comment