Skip to content

Commit

Permalink
Add pinball to the attic
Browse files Browse the repository at this point in the history
But get a few nice things along the way
  • Loading branch information
AEFeinstein authored Sep 19, 2024
1 parent 9c9db12 commit 69615ad
Show file tree
Hide file tree
Showing 46 changed files with 3,282 additions and 1,649 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,19 @@
#include <esp_heap_caps.h>

#include "mode_pinball.h"
#include "pinball_zones.h"
#include "pinball_game.h"
#include "pinball_physics.h"
#include "pinball_draw.h"
#include "pinball_test.h"

//==============================================================================
// Structs
//==============================================================================

typedef struct
{
pbScene_t scene;
font_t ibm;
} pinball_t;

//==============================================================================
// Function Prototypes
Expand Down Expand Up @@ -60,38 +69,10 @@ static void pinEnterMode(void)
// Allocate all the memory
pinball = calloc(sizeof(pinball_t), 1);

pinball->balls = heap_caps_calloc(MAX_NUM_BALLS, sizeof(pbCircle_t), MALLOC_CAP_SPIRAM);
pinball->bumpers = heap_caps_calloc(MAX_NUM_BUMPERS, sizeof(pbCircle_t), MALLOC_CAP_SPIRAM);
pinball->walls = heap_caps_calloc(MAX_NUM_WALLS, sizeof(pbLine_t), MALLOC_CAP_SPIRAM);
pinball->flippers = heap_caps_calloc(MAX_NUM_FLIPPERS, sizeof(pbFlipper_t), MALLOC_CAP_SPIRAM);

pinball->ballsTouching = heap_caps_calloc(MAX_NUM_BALLS, sizeof(pbTouchRef_t*), MALLOC_CAP_SPIRAM);
for (uint32_t i = 0; i < MAX_NUM_BALLS; i++)
{
pinball->ballsTouching[i] = heap_caps_calloc(MAX_NUM_TOUCHES, sizeof(pbTouchRef_t), MALLOC_CAP_SPIRAM);
}

// Split the table into zones
createTableZones(pinball);

// Create random balls
createRandomBalls(pinball, 0);
pbCreateBall(pinball, 6, 114);
pbCreateBall(pinball, 274, 114);
pbCreateBall(pinball, 135, 10);
loadFont("ibm_vga8.font", &pinball->ibm, false);

// Create random bumpers
createRandomBumpers(pinball, 0);

// Create random walls
createRandomWalls(pinball, 0);

// Create flippers
createFlipper(pinball, TFT_WIDTH / 2 - 50, 200, true);
createFlipper(pinball, TFT_WIDTH / 2 + 50, 200, false);

// Load font
loadFont("ibm_vga8.font", &pinball->ibm_vga8, false);
pbSceneInit(&pinball->scene);
pbStartBall(&pinball->scene);
}

/**
Expand All @@ -100,19 +81,8 @@ static void pinEnterMode(void)
*/
static void pinExitMode(void)
{
for (uint32_t i = 0; i < MAX_NUM_BALLS; i++)
{
free(pinball->ballsTouching[i]);
}
free(pinball->ballsTouching);

free(pinball->balls);
free(pinball->walls);
free(pinball->bumpers);
free(pinball->flippers);
// Free font
freeFont(&pinball->ibm_vga8);
// Free the rest of the state
freeFont(&pinball->ibm);
pbSceneDestroy(&pinball->scene);
free(pinball);
}

Expand All @@ -123,37 +93,25 @@ static void pinExitMode(void)
*/
static void pinMainLoop(int64_t elapsedUs)
{
// Make a local copy for speed
pinball_t* p = pinball;

// Check all queued button events
buttonEvt_t evt;
// Handle inputs
buttonEvt_t evt = {0};
while (checkButtonQueueWrapper(&evt))
{
if (PB_RIGHT == evt.button)
if (evt.down && PB_START == evt.button)
{
p->flippers[1].buttonHeld = evt.down;
pbSceneDestroy(&pinball->scene);
pbSceneInit(&pinball->scene);
}
else if (PB_LEFT == evt.button)
else
{
p->flippers[0].buttonHeld = evt.down;
pbButtonPressed(&pinball->scene, &evt);
}
}

// Only check physics once per frame
p->frameTimer += elapsedUs;
while (p->frameTimer >= PIN_US_PER_FRAME)
{
p->frameTimer -= PIN_US_PER_FRAME;
updatePinballPhysicsFrame(pinball);
}

// Always draw foreground to prevent flicker
pinballDrawForeground(pinball);

// Log frame time for FPS
p->frameTimesIdx = (p->frameTimesIdx + 1) % NUM_FRAME_TIMES;
p->frameTimes[p->frameTimesIdx] = esp_timer_get_time();
pbSimulate(&pinball->scene, elapsedUs);
pbGameTimers(&pinball->scene, elapsedUs);
pbAdjustCamera(&pinball->scene);
pbSceneDraw(&pinball->scene, &pinball->ibm);
}

/**
Expand All @@ -168,5 +126,4 @@ static void pinMainLoop(int64_t elapsedUs)
*/
static void pinBackgroundDrawCallback(int16_t x, int16_t y, int16_t w, int16_t h, int16_t up, int16_t upNum)
{
pinballDrawBackground(pinball, x, y, w, h);
}
28 changes: 28 additions & 0 deletions attic/pinball/mode_pinball.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#pragma once

//==============================================================================
// Includes
//==============================================================================

#include <esp_random.h>
#include "swadge2024.h"

//==============================================================================
// Defines
//==============================================================================

#define PIN_US_PER_FRAME 16667

//==============================================================================
// Enums
//==============================================================================

//==============================================================================
// Structs
//==============================================================================

//==============================================================================
// Extern variables
//==============================================================================

extern swadgeMode_t pinballMode;
80 changes: 80 additions & 0 deletions attic/pinball/pinball_circle.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#include "pinball_circle.h"
#include "pinball_rectangle.h"

/**
* @brief TODO doc
*
* @param tableData
* @param scene
* @return uint32_t
*/
uint32_t readCircleFromFile(uint8_t* tableData, pbScene_t* scene)
{
pbCircle_t* circle = &scene->circles[scene->numCircles++];

uint32_t dIdx = 0;
circle->id = readInt16(tableData, &dIdx);
circle->groupId = readInt8(tableData, &dIdx);
circle->group = addToGroup(scene, circle, circle->groupId);
circle->pos.x = readInt16(tableData, &dIdx);
circle->pos.y = readInt16(tableData, &dIdx);
circle->radius = readInt8(tableData, &dIdx);
circle->type = readInt8(tableData, &dIdx);
circle->pushVel = readInt8(tableData, &dIdx);

return dIdx;
}

/**
* @brief Simulate a ball's motion
*
* @param ball
* @param dt
* @param scene
*/
void pbBallSimulate(pbBall_t* ball, int32_t elapsedUs, float dt, pbScene_t* scene)
{
if (ball->scoopTimer <= 0)
{
ball->vel = addVecFl2d(ball->vel, mulVecFl2d(scene->gravity, dt));
ball->pos = addVecFl2d(ball->pos, mulVecFl2d(ball->vel, dt));
}
else
{
ball->scoopTimer -= elapsedUs;

if (ball->scoopTimer <= 0)
{
// Respawn in the launch tube
for (int32_t pIdx = 0; pIdx < scene->numPoints; pIdx++)
{
pbPoint_t* point = &scene->points[pIdx];
if (PB_BALL_SPAWN == point->type)
{
ball->pos = point->pos;
break;
}
}

pbOpenLaunchTube(scene, true);

// Give the ball initial velocity
ball->vel.x = 0;
ball->vel.y = MAX_LAUNCHER_VELOCITY;
}
}
}

/**
* @brief TODO
*
* @param circle
* @param elapsedUs
*/
void pbCircleTimer(pbCircle_t* circle, int32_t elapsedUs)
{
if (circle->litTimer > 0)
{
circle->litTimer -= elapsedUs;
}
}
10 changes: 10 additions & 0 deletions attic/pinball/pinball_circle.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once

#include "pinball_typedef.h"
#include "pinball_game.h"

#define PINBALL_RADIUS 8

uint32_t readCircleFromFile(uint8_t* tableData, pbScene_t* scene);
void pbBallSimulate(pbBall_t* ball, int32_t elapsedUs, float dt, pbScene_t* scene);
void pbCircleTimer(pbCircle_t* circle, int32_t elapsedUs);
Loading

0 comments on commit 69615ad

Please sign in to comment.