Advertisement
pipe0481

3DS Physics Sandbox

Jul 30th, 2016
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.34 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <time.h>
  5. #include <math.h>
  6. #include <3ds.h>
  7. #include <sf2d.h>
  8. //#include "physobject.cpp";
  9.  
  10. #define CONFIG_3D_SLIDERSTATE (*(float *)0x1FF81080)
  11. #define debug
  12.  
  13. #define rw 50
  14. #define rh 50
  15. #define count 10
  16.  
  17. //forward declarations
  18. char* get_mod_val_id(u8);
  19.  
  20. float gravity_y = -10.0f;
  21. float gravity_x = 0.0f;
  22.  
  23. int sel = 0;
  24.  
  25. char* f[10] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
  26.  
  27. bool global = true;
  28.  
  29. class physobject {
  30. public:
  31.     float rect_x = 320 / 2;
  32.     float rect_y = 240 / 2;
  33.     u8 mov_rect = 0.0f;
  34.     float vel_x = 0.0f;
  35.     float vel_y = 0.0f;
  36.     float elasticity = .5f;
  37.     float friction = .5f;
  38.     int kind = 0; //0 = rectangle 1 = circle 2 = triangle
  39.     u32 color;
  40. };
  41.  
  42. int main()
  43. {
  44.     // Set the random seed based on the time
  45.     srand(time(NULL));
  46.  
  47.     //init screen background to white
  48.     sf2d_init();
  49.     sf2d_set_clear_color(RGBA8(0xFF, 0xFF, 0xFF, 0xFF));
  50.     sf2d_set_3D(0);
  51.     sf2d_set_vblank_wait(1);
  52.    
  53.     physobject arr[count];
  54.  
  55.     for (size_t i = 0; i < count; i++)
  56.     {
  57.         arr[i].rect_x = rand() % 320;
  58.         arr[i].rect_y = rand() % 240;
  59.         arr[i].color = RGBA8(rand() % 255, rand() % 255, rand() % 255, 255);
  60.         arr[i].kind = rand() % 3;
  61.     }
  62.  
  63.     //Variables
  64.  
  65.     //Represents the current modifiable value: gravity_y, gravity_x, friction, elasticity
  66.     u8 mod_val = 0;
  67.  
  68.     //coordinates of screen touch
  69.     u16 touch_x = 320/2;
  70.     u16 touch_y = 240/2;
  71.  
  72.     //increment - determines how much is added or subtracted to mod_val - is always power of 10
  73.     double inc = 1.0f;
  74.    
  75.     //boolean to determine if touch screen is currently dictating the square's location
  76.     u8 mov_rect = 0.0f;
  77.  
  78.     //records where the user tapped on the square e.g. if the top right corner is tapped, it will stay at top right corner
  79.     s8 offset_x = 0.0f;
  80.     s8 offset_y = 0.0f;
  81.  
  82.     //HID variables
  83.     touchPosition touch;
  84.     circlePosition circle;
  85.     u32 held;
  86.     u32 pressed;
  87.     u32 released;
  88.  
  89.     //physobject objects;
  90.  
  91.     consoleInit(GFX_TOP, NULL);
  92.  
  93.     printf("\x1b[0;0HPhysics Sandbox v0.1 by PieFace");
  94.     printf("\x1b[23;0HControls:");
  95.     printf("\x1b[24;0HTap and drag square to move it");
  96.     printf("\x1b[25;0HX - Reset Square");
  97.     printf("\x1b[26;0HDPad L&R - Change between mod_vals");
  98.     printf("\x1b[27;0HDPad U&D - Increment and decrement mod_val");
  99.     printf("\x1b[28;0HL&R - Change increment (pow of 10)");
  100.     printf("\x1b[29;0HStart - Exit");
  101.     while (aptMainLoop()) {
  102.  
  103.         //gather inputs
  104.         hidScanInput();
  105.         hidCircleRead(&circle);
  106.         held = hidKeysHeld();
  107.         pressed = hidKeysDown();
  108.         released = hidKeysUp();
  109.        
  110.  
  111.         //check button presses
  112.  
  113.         //Press Start to Exit
  114.         if (held & KEY_START)
  115.         {
  116.             break;
  117.         }
  118.        
  119.         //Read touch values if the screen is pressed
  120.         if (held & KEY_TOUCH)
  121.         {
  122.             hidTouchRead(&touch);
  123.             touch_x = touch.px;
  124.             touch_y = touch.py;
  125.             if(mov_rect)
  126.             {
  127.                 arr[sel].vel_x = (touch_x + offset_x - arr[sel].rect_x)*60.0f;
  128.                 arr[sel].vel_y = (touch_y + offset_y - arr[sel].rect_y)*60.0f;
  129.             }
  130.         }
  131.  
  132.         //DPAD up - Increment current mod_val
  133.         if(pressed & KEY_DUP)
  134.         {
  135.             if(mod_val == 0)
  136.             {
  137.                 gravity_y += inc;
  138.             }
  139.            
  140.             if(mod_val == 1)
  141.             {
  142.                 gravity_x += inc;
  143.             }
  144.  
  145.             if(mod_val == 2)
  146.             {
  147.                 if (global)
  148.                 {
  149.                     for (size_t i = 0; i < count; i++)
  150.                     {
  151.                         arr[i].elasticity += inc;
  152.                         if (arr[i].elasticity > 1) arr[i].elasticity = 1;
  153.                     }
  154.                 }
  155.                 else
  156.                 {
  157.                     arr[sel].elasticity += inc;
  158.                     if (arr[sel].elasticity > 1) arr[sel].elasticity = 1;
  159.                 }
  160.             }
  161.  
  162.             if(mod_val == 3)
  163.             {
  164.                 if (global)
  165.                 {
  166.                     for (size_t i = 0; i < count; i++)
  167.                     {
  168.                         arr[i].friction += inc;
  169.                         if (arr[i].friction > 1) arr[i].friction = 0;
  170.                     }
  171.                 }
  172.                 else
  173.                 {
  174.                     arr[sel].friction += inc;
  175.                     if (arr[sel].friction > 1) arr[sel].friction = 0;
  176.                 }
  177.             }
  178.         }
  179.        
  180.         //DPAD down - decrement current mod_val
  181.         if(pressed & KEY_DDOWN)
  182.         {
  183.             if(mod_val == 0)
  184.             {
  185.                 gravity_y -= inc;
  186.             }
  187.            
  188.             if(mod_val == 1)
  189.             {
  190.                 gravity_x -= inc;
  191.             }
  192.  
  193.             if(mod_val == 2)
  194.             {
  195.                 if (global)
  196.                 {
  197.                     for (size_t i = 0; i < count; i++)
  198.                     {
  199.                         arr[i].elasticity -= inc;
  200.                         if (arr[i].elasticity < 0) arr[i].elasticity = 0;
  201.                     }
  202.                 }
  203.                 else
  204.                 {
  205.                     arr[sel].elasticity -= inc;
  206.                     if (arr[sel].elasticity < 0) arr[sel].elasticity = 0;
  207.                 }
  208.             }
  209.  
  210.             if(mod_val == 3)
  211.             {
  212.                 if (global)
  213.                 {
  214.                     for (size_t i = 0; i < count; i++)
  215.                     {
  216.                         arr[i].friction -= inc;
  217.                         if (arr[i].friction < 0) arr[i].friction = 0;
  218.                     }
  219.                 }
  220.                 else
  221.                 {
  222.                     arr[sel].friction -= inc;
  223.                     if (arr[sel].friction < 0) arr[sel].friction = 0;
  224.                 }
  225.             }
  226.         }
  227.  
  228.         //DPAD Left and Right - Change mod_val
  229.         if(pressed & KEY_DLEFT)
  230.         {
  231.             mod_val--;
  232.             if (mod_val > 3) mod_val = 3;
  233.         }
  234.        
  235.         if(pressed & KEY_DRIGHT)
  236.         {
  237.             mod_val++;
  238.             if (mod_val > 3) mod_val = 0;
  239.         }
  240.        
  241.  
  242.         //L and R - Multiply and divide increment by 10
  243.         if(pressed & KEY_L) inc *= 10;
  244.         if(pressed & KEY_R) inc /= 10;     
  245.  
  246.  
  247.         //Collisions and Friction
  248.         //Detects collision with edge of the screen
  249.         //Inverts velocity perpendicular to collision and gradually reduces velocity parallel to collision
  250.         for (size_t i = 0; i < count; i++)
  251.         {
  252.             //Collision and friction with top or bottom edge
  253.             if (arr[i].rect_x - rw / 2 <= 1 || arr[i].rect_x + rw / 2 >= 319)
  254.             {
  255.                 arr[i].vel_x = -arr[i].vel_x * arr[i].elasticity;
  256.                
  257.                 if (arr[i].rect_x < rw / 2) arr[i].rect_x = rw / 2;
  258.                 if (arr[i].rect_x > 320 - rw / 2) arr[i].rect_x = 320 - rw / 2;
  259.                
  260.                 arr[i].vel_y += (arr[i].vel_y > 0 ? -fmin(arr[i].friction, arr[i].vel_y) : -fmax(-arr[i].friction, arr[i].vel_y));
  261.             }
  262.  
  263.             //Collision and friction with left and right edge
  264.             if (arr[i].rect_y - rh / 2 <= 1 || arr[i].rect_y + rh / 2 >= 239)
  265.             {
  266.                 arr[i].vel_y = -arr[i].vel_y * arr[i].elasticity;
  267.  
  268.                 if (arr[i].rect_y < rh / 2) arr[i].rect_y = rh / 2;
  269.                 if (arr[i].rect_y > 240 - rh / 2) arr[i].rect_y = 240 - rh / 2;
  270.  
  271.                 arr[i].vel_x += (arr[i].vel_x > 0 ? -fmin(arr[i].friction, arr[i].vel_x) : -fmax(-arr[i].friction, arr[i].vel_x));
  272.             }
  273.         }
  274.  
  275.         //If the coordinates of the screen tap are inside the square, allow movement of the square
  276.         if (pressed & KEY_TOUCH)
  277.         {
  278.             for (size_t i = 0; i < count; i++)
  279.             {
  280.                 if ((touch_x > arr[i].rect_x - rw / 2) && (touch_x < arr[i].rect_x + rw / 2) && (touch_y > arr[i].rect_y - rh / 2) && (touch_y < arr[i].rect_y + rh / 2))
  281.                 {
  282.                     sel = i;
  283.                     mov_rect = 1;
  284.                     offset_x = arr[i].rect_x - touch_x;
  285.                     offset_y = arr[i].rect_y - touch_y;
  286.                     break;
  287.                 }
  288.             }
  289.         }
  290.  
  291.         //If the screen is let go, stop allowing screen to control square
  292.         if ((released & KEY_TOUCH))
  293.         {
  294.             mov_rect = 0;
  295.             offset_x = 0;
  296.             offset_y = 0;
  297.         }
  298.  
  299.         //Press x to reset all values
  300.         if(pressed & KEY_X)
  301.         {
  302.             for (size_t i = 0; i < count; i++)
  303.             {
  304.                 arr[i].rect_x = rand() % 320;
  305.                 arr[i].rect_y = rand() % 240;
  306.                 arr[i].color = RGBA8(rand() % 255, rand() % 255, rand() % 255, 255);
  307.                 arr[i].vel_x = 0.0f;
  308.                 arr[i].vel_y = 0.0f;
  309.                 arr[i].elasticity = .5f;
  310.                 arr[i].friction = .5f;
  311.             }
  312.         }
  313.  
  314.         if (pressed & KEY_Y)
  315.         {
  316.             global = !global;
  317.         }
  318.  
  319.         //Determines how to move the square
  320.         //If the touch screen is not dictating the square's location, apply gravity and velocity
  321.         //Else move square to where screen is touched
  322.         for (size_t i = 0; i < count; i++)
  323.         {
  324.             if (!mov_rect)
  325.             {
  326.                 arr[i].vel_y -= gravity_y;
  327.                 arr[i].vel_x += gravity_x;
  328.  
  329.                 arr[i].rect_x += arr[i].vel_x / 60.0f;
  330.                 arr[i].rect_y += arr[i].vel_y / 60.0f;
  331.             }
  332.             else if (i == sel)
  333.             {
  334.                 arr[sel].rect_x = touch_x + offset_x;
  335.                 arr[sel].rect_y = touch_y + offset_y;
  336.             }
  337.         }
  338.  
  339.         //Live printing of important values
  340.         #ifdef debug
  341.         printf("\x1b[0;41H%s:%5.2f","fps",sf2d_get_fps());
  342.         printf("\x1b[1;0H%s:%03d,%03d","touch_coord",touch_x,touch_y);
  343.         printf("\x1b[2;0H%s:%03.0f,%03.0f","rect_coord", arr[sel].rect_x, arr[sel].rect_y);
  344.         printf("\x1b[3;0H%s:%03d,%03d","offset",offset_x,offset_y);
  345.         printf("\x1b[4;0H%s:%010.3f,%010.3f","velocity", arr[sel].vel_x, -arr[sel].vel_y);
  346.         printf("\x1b[5;0H%s:%f,%f","gravity", gravity_x, gravity_y);
  347.         printf("\x1b[6;0H%s:%f","elasticity", arr[sel].elasticity);
  348.         printf("\x1b[7;0H%s:%f","friction", arr[sel].friction);
  349.         printf("\x1b[8;0H%s:%f","increment", inc);     
  350.         printf("\x1b[9;0H%s:%s","mod_val", get_mod_val_id(mod_val));
  351.         printf("\x1b[10;0H%s:%s", "sel", f[sel]);
  352.         printf("\x1b[11;0H%s:%s", "global", global ? "true" : "false");
  353.         #endif
  354.  
  355.         //draw frame
  356.         sf2d_start_frame(GFX_BOTTOM, GFX_LEFT);
  357.  
  358.         for (size_t i = count; i-- > 0;)
  359.         {
  360.             if (arr[i].kind == 0)
  361.             {
  362.                 sf2d_draw_rectangle((int)arr[i].rect_x - rw / 2, (int)arr[i].rect_y - rh / 2, 50, 50, arr[i].color);
  363.             }
  364.             else if (arr[i].kind == 1)
  365.             {
  366.                 sf2d_draw_fill_circle((int)arr[i].rect_x, (int)arr[i].rect_y, rw / 2, arr[i].color);
  367.             }
  368.             else if (arr[i].kind == 2)
  369.             {
  370.                 int x = (int)arr[i].rect_x;
  371.                 int y = (int)arr[i].rect_y;
  372.                 sf2d_draw_triangle(x, y - rh / 2, x - rw / 2, y + rh / 2, x + rw / 2, y + rh / 2, arr[i].color);
  373.             }
  374.         }
  375.  
  376.         sf2d_end_frame();
  377.  
  378.         sf2d_swapbuffers();
  379.     }
  380.  
  381.    
  382.     sf2d_fini();
  383.     return 0;
  384. }
  385.  
  386. //returns string of mod_val from id
  387. char* get_mod_val_id(u8 id)
  388. {
  389.     if(id==0) return "gravity_y ";
  390.     if(id==1) return "gravity_x ";
  391.     if(id==2) return "elasticity";
  392.     if(id==3) return "friction  ";
  393.     return "err_bad_id";
  394. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement