182 lines
6.3 KiB
C++
182 lines
6.3 KiB
C++
/* _______________ ,----------------------------------------------------------------.
|
|
//`````````````\\ \ \
|
|
//~~~~~~~~~~~~~~~\\ \ by @ohsqueezy & @sleepin \
|
|
//=================\\ \ [ohsqueezy.itch.io] [sleepin.itch.io] \
|
|
// \\ \ \
|
|
// \\ \ code released under the zlib license [git.nugget.fun/pudding] \
|
|
// ☆ GUNKISS ☆ \\ \ \
|
|
//_________________________\\ `---------------------------------------------------------------*/
|
|
|
|
#ifndef Pudding_h_
|
|
#define Pudding_h_
|
|
|
|
#include <stdlib.h>
|
|
#include <string>
|
|
#include <iostream>
|
|
#include <algorithm>
|
|
#include <thread>
|
|
#include <memory>
|
|
#include <stdexcept>
|
|
#include <curl/curl.h>
|
|
#include "SDL.h"
|
|
#include "SDL_image.h"
|
|
#include "sdl2-gfx/SDL2_gfxPrimitives.h"
|
|
#include "json/json.hpp"
|
|
#include "glm/glm.hpp"
|
|
#include "opencv2/core.hpp"
|
|
#include "opencv2/videoio.hpp"
|
|
#include "opencv2/highgui.hpp"
|
|
#include "opencv2/imgproc.hpp"
|
|
#include "zbar.h"
|
|
#include "Game.hpp"
|
|
#include "Color.hpp"
|
|
#include "extension.hpp"
|
|
#include "filesystem.hpp"
|
|
#include "Animation.hpp"
|
|
#include "Texture.hpp"
|
|
#include "GLObject.hpp"
|
|
#include "Log.hpp"
|
|
#include "Attributes.hpp"
|
|
#include "VBO.hpp"
|
|
#include "Item.hpp"
|
|
#include "Model.hpp"
|
|
|
|
class Pudding : public Game
|
|
{
|
|
|
|
private:
|
|
|
|
/* Defines for effect IDs that will be passed to the shader program. Since COUNT is last and every value
|
|
* is the default integer, it will define the number of effects available */
|
|
enum Effect
|
|
{
|
|
EFFECT_NONE,
|
|
EFFECT_SNAKE,
|
|
EFFECT_WOBBLE,
|
|
EFFECT_COUNT
|
|
};
|
|
|
|
/* Defines for UV transformations available in the fragment shader program */
|
|
enum UVTransformation
|
|
{
|
|
UV_NONE,
|
|
UV_SQUIRCLE
|
|
};
|
|
|
|
typedef Game super;
|
|
const std::string OPEN_FOOD_API_URL = "https://world.openfoodfacts.org/api/v0/product/";
|
|
const std::string NUTRONIX_API_URL = "https://trackapi.nutritionix.com/v2/search/item?upc=";
|
|
const std::string BARCODE_MONSTER_API_URL = "https://barcode.monster/api/";
|
|
const std::string BEST_BUY_API_URL_1 = "https://api.bestbuy.com/v1/products(upc=";
|
|
const std::string BEST_BUY_API_URL_2 = ")?format=json&apiKey=";
|
|
const std::string NUTRONIX_NOT_FOUND = "resource not found";
|
|
const std::string GIANTBOMB_API_URL = "https://www.giantbomb.com/api/release/?api_key=";
|
|
const glm::vec3 ZERO_VECTOR_3D = glm::vec3(0, 0, 0);
|
|
const glm::vec3 Y_UNIT_NORMAL_3D = glm::vec3(0, 1, 0);
|
|
const glm::mat4 VIEW_MATRIX = glm::lookAt(glm::vec3(4, 2, 1), glm::vec3(0, -0.325, 0), Y_UNIT_NORMAL_3D);
|
|
const glm::vec3 PUDDING_BROWN = glm::vec3(0.713f, 0.359f, 0.224f);
|
|
const glm::vec3 PUDDING_YELLOW = glm::vec3(0.878f, 0.859f, 0.122f);
|
|
std::string current_barcode, previous_barcode, current_config_barcode, current_camera_barcode;
|
|
std::vector<Item> items;
|
|
int current_item_index = 0, effect_id = EFFECT_NONE, pudding_triangle_vertex_count = 0, pudding_fan_vertex_count = 0;
|
|
cv::VideoCapture capture;
|
|
zbar::ImageScanner image_scanner;
|
|
std::map<std::string, std::map<std::string, GLuint>> uniform;
|
|
GLuint flat_program, mvp_program;
|
|
glm::mat4 projection, model = glm::mat4(1.0f), mvp;
|
|
Model pudding_model;
|
|
Plane plane;
|
|
Background background;
|
|
CameraView camera_view;
|
|
bool show_item = false, reading_capture_frame = false;
|
|
SDL_GLContext capture_frame_thread_context = nullptr;
|
|
sb::VAO vao;
|
|
sb::VBO vbo;
|
|
|
|
void set_pudding_model(float, float, int, int = 1, float = -1, float = 1, float = 0.3f);
|
|
void load_gl_context();
|
|
void load_tiles();
|
|
void initialize_camera();
|
|
void incorporate_open_food_api(Item&);
|
|
void incorporate_nutronix_api(Item&);
|
|
void incorporate_edamam_api(Item&);
|
|
void incorporate_best_buy_api(Item&);
|
|
void save_item_json(const nlohmann::json&, const Item&, const std::string&) const;
|
|
nlohmann::json json_from_url(const std::string&, const std::vector<std::string>& = {});
|
|
void curl_get_bytes(const std::string& url, std::vector<std::uint8_t>&, const std::vector<std::string>& = {}) const;
|
|
static size_t curl_write_response(std::uint8_t*, size_t, size_t, std::vector<std::uint8_t>*);
|
|
sb::Texture texture_from_image_url(const std::string&) const;
|
|
static void destroy_texture(GLuint*);
|
|
bool item_display_active() const;
|
|
static int capture_frame(void*);
|
|
|
|
public:
|
|
|
|
Pudding();
|
|
void respond(SDL_Event&);
|
|
void add_item(const std::string&);
|
|
void increment_item_index(int = 1);
|
|
Item& current_item();
|
|
void update();
|
|
virtual std::string class_name() const { return "Pudding"; }
|
|
|
|
};
|
|
|
|
/* Apply force until reaching a threshold. Use a connection object to run user functions
|
|
* when force reaches threshold and when force goes below threshold.
|
|
*
|
|
* - shares single Plane (vertices in VBO and UV in VBO)
|
|
* - each has different Texture
|
|
* - each has different response to click
|
|
* - shares collision with mouse code
|
|
* - each has different position
|
|
*/
|
|
class Button
|
|
{
|
|
/* threshold */
|
|
/* force */
|
|
/* close */
|
|
/* open */
|
|
/* apply */
|
|
/* remove */
|
|
/* weighted depression rate */
|
|
/* Animation (?) */
|
|
};
|
|
|
|
class Pad
|
|
{
|
|
};
|
|
|
|
/* An abstract base class of an object in a state of either connected or not connected.
|
|
* When the state changes, functions that must be overriden by a derived class are run,
|
|
* one for each state change: from on to off, and from off to on. */
|
|
class Connection
|
|
{
|
|
|
|
private:
|
|
|
|
enum State
|
|
{
|
|
STATE_DISCONNECTED,
|
|
STATE_CONNECTED
|
|
};
|
|
State connection_state = STATE_DISCONNECTED;
|
|
|
|
protected:
|
|
|
|
virtual void on_connect() = 0;
|
|
virtual void on_disconnect() = 0;
|
|
|
|
public:
|
|
|
|
Connection() {}
|
|
State state() { return connection_state; }
|
|
void connect() { if (state() != STATE_CONNECTED) { connection_state = STATE_CONNECTED; on_connect(); } }
|
|
void disconnect() { if (state() != STATE_DISCONNECTED) { connection_state = STATE_DISCONNECTED; on_disconnect(); } }
|
|
void toggle() { if (state() == STATE_CONNECTED) disconnect(); else connect(); }
|
|
bool connected() { return connection_state == STATE_DISCONNECTED ? false : true; }
|
|
|
|
};
|
|
|
|
#endif
|