mirror of
https://github.com/GayPizzaSpecifications/padlab.git
synced 2025-08-03 05:10:56 +00:00
255 lines
6.1 KiB
C
255 lines
6.1 KiB
C
#include "maths.h"
|
|
#include "draw.h"
|
|
#include "stick.h"
|
|
#include <SDL.h>
|
|
#include <stdio.h>
|
|
#include <stdbool.h>
|
|
|
|
#define CAPTION "PadLab"
|
|
#define WINDOW_WIDTH 512
|
|
#define WINDOW_HEIGHT 288
|
|
|
|
SDL_Window* window = NULL;
|
|
SDL_JoystickID joyid = -1;
|
|
SDL_GameController* pad = NULL;
|
|
|
|
bool UseGamepad(int aJoyid)
|
|
{
|
|
pad = SDL_GameControllerOpen(aJoyid);
|
|
joyid = SDL_JoystickGetDeviceInstanceID(aJoyid);
|
|
if (pad != NULL)
|
|
{
|
|
printf("using gamepad #%d, \"%s\"\n", aJoyid, SDL_GameControllerName(pad));
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
#define FATAL(CONDITION, RETURN) if (CONDITION) { res = (RETURN); goto error; }
|
|
int main(int argc, char** argv)
|
|
{
|
|
int res;
|
|
|
|
res = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER);
|
|
if (res < 0)
|
|
goto error;
|
|
|
|
const int winpos = SDL_WINDOWPOS_CENTERED;
|
|
const int winflg = SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI;
|
|
int winw = WINDOW_WIDTH;
|
|
int winh = WINDOW_HEIGHT;
|
|
window = SDL_CreateWindow(CAPTION, winpos, winpos, winw, winh, winflg);
|
|
FATAL(window == NULL, -1)
|
|
|
|
FATAL(InitDraw(window), -1)
|
|
size rendSize = GetDrawSizeInPixels();
|
|
|
|
if ((res = SDL_GameControllerAddMappingsFromFile("gamecontrollerdb.txt")) != -1)
|
|
printf("read %d mappings from gamecontrollerdb.txt\n", res);
|
|
for (int i = 0; i < SDL_NumJoysticks(); ++i)
|
|
{
|
|
if (SDL_IsGameController(i))
|
|
{
|
|
if (UseGamepad(i))
|
|
break;
|
|
}
|
|
}
|
|
|
|
vector plrpos = {10.0, 10.0};
|
|
StickState stickl, stickr;
|
|
InitDefaults(&stickl);
|
|
InitDefaults(&stickr);
|
|
|
|
bool running = true;
|
|
bool repaint = true;
|
|
bool showavatar = false;
|
|
uint32_t tickslast = SDL_GetTicks();
|
|
int side = 0;
|
|
|
|
while (running)
|
|
{
|
|
//FIXME: probably doesn't matter but this isn't very precise
|
|
const uint32_t ticks = SDL_GetTicks();
|
|
const double framedelta = (double)(ticks - tickslast);
|
|
tickslast = ticks;
|
|
|
|
SDL_Event event;
|
|
bool onevent = false;
|
|
if (!showavatar || (stickl.compos.x == 0.0 && stickl.compos.y == 0.0))
|
|
{
|
|
onevent = SDL_WaitEvent(&event) != 0;
|
|
}
|
|
else
|
|
{
|
|
onevent = SDL_PollEvent(&event) > 0;
|
|
repaint = true;
|
|
}
|
|
if (onevent)
|
|
{
|
|
do
|
|
{
|
|
switch (event.type)
|
|
{
|
|
case (SDL_KEYDOWN):
|
|
if (event.key.keysym.sym == SDLK_ESCAPE)
|
|
{
|
|
running = false;
|
|
}
|
|
else if (event.key.keysym.sym == SDLK_e)
|
|
{
|
|
showavatar = !showavatar;
|
|
repaint = true;
|
|
}
|
|
break;
|
|
|
|
case (SDL_CONTROLLERBUTTONDOWN):
|
|
if (event.cbutton.button == SDL_CONTROLLER_BUTTON_BACK)
|
|
{
|
|
showavatar = !showavatar;
|
|
repaint = true;
|
|
}
|
|
break;
|
|
|
|
case (SDL_QUIT):
|
|
running = false;
|
|
break;
|
|
|
|
case (SDL_WINDOWEVENT):
|
|
if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
|
|
{
|
|
winw = event.window.data1;
|
|
winh = event.window.data2;
|
|
rendSize = GetDrawSizeInPixels();
|
|
repaint = true;
|
|
}
|
|
else if (event.window.event == SDL_WINDOWEVENT_EXPOSED)
|
|
{
|
|
repaint = true;
|
|
}
|
|
break;
|
|
|
|
case (SDL_CONTROLLERAXISMOTION):
|
|
if (event.caxis.which == joyid)
|
|
{
|
|
if (event.caxis.axis == SDL_CONTROLLER_AXIS_LEFTX)
|
|
{
|
|
stickl.rawpos.x = (vec_t)event.caxis.value / (vec_t)0x7FFF;
|
|
repaint = stickl.recalc = true;
|
|
}
|
|
else if (event.caxis.axis == SDL_CONTROLLER_AXIS_LEFTY)
|
|
{
|
|
stickl.rawpos.y = (vec_t)event.caxis.value / (vec_t)0x7FFF;
|
|
repaint = stickl.recalc = true;
|
|
}
|
|
else if (event.caxis.axis == SDL_CONTROLLER_AXIS_RIGHTX)
|
|
{
|
|
stickr.rawpos.x = (vec_t)event.caxis.value / (vec_t)0x7FFF;
|
|
repaint = stickr.recalc = true;
|
|
}
|
|
else if (event.caxis.axis == SDL_CONTROLLER_AXIS_RIGHTY)
|
|
{
|
|
stickr.rawpos.y = (vec_t)event.caxis.value / (vec_t)0x7FFF;
|
|
repaint = stickr.recalc = true;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case (SDL_MOUSEBUTTONDOWN):
|
|
if (event.button.state & (SDL_BUTTON_LMASK | SDL_BUTTON_RMASK ))
|
|
{
|
|
side = (event.button.x > winw / 2) ? 1 : 0;
|
|
}
|
|
break;
|
|
|
|
case (SDL_MOUSEMOTION):
|
|
if (event.motion.state & SDL_BUTTON_LMASK)
|
|
{
|
|
const double hwinw = winw / 2.0;
|
|
const double dispscale = 1.0 / (((hwinw > winh) ? winh : hwinw) * DISPLAY_SCALE / 2.0);
|
|
const vector newpos = {
|
|
CLAMP(((double)event.motion.x - hwinw / 2.0 - hwinw * side) * dispscale, -1.0, 1.0),
|
|
CLAMP(((double)event.motion.y - winh / 2.0) * dispscale, -1.0, 1.0) };
|
|
|
|
StickState* stick = side ? &stickr : &stickl;
|
|
stick->rawpos = newpos;
|
|
repaint = stick->recalc = true;
|
|
}
|
|
else if (event.motion.state & SDL_BUTTON_RMASK)
|
|
{
|
|
const double hwinw = winw / 2.0;
|
|
const double valx = SATURATE(1.0 - (double)event.motion.x / (double)hwinw);
|
|
const double valy = SATURATE(1.0 - (double)event.motion.y / (double)winh);
|
|
|
|
if (side == 0)
|
|
{
|
|
stickl.digiangle = valx;
|
|
stickl.digideadzone = valy;
|
|
repaint = stickl.recalc = true;
|
|
}
|
|
else
|
|
{
|
|
//p2.accelpow = valy * valy * valy * 32;
|
|
stickr.accelpow = pow(valy * 3, 1.0 + valy * 3);
|
|
repaint = stickr.recalc = true;
|
|
}
|
|
}
|
|
|
|
case (SDL_CONTROLLERDEVICEADDED):
|
|
if (pad == NULL)
|
|
UseGamepad(event.cdevice.which);
|
|
break;
|
|
case (SDL_CONTROLLERDEVICEREMOVED):
|
|
if (pad != NULL && event.cdevice.which == joyid)
|
|
{
|
|
SDL_GameControllerClose(pad);
|
|
pad = NULL;
|
|
printf("active gamepad was removed\n");
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
while (SDL_PollEvent(&event) > 0);
|
|
}
|
|
|
|
if (repaint)
|
|
{
|
|
// background
|
|
SetDrawColour(0x1F1F1FFF);
|
|
DrawClear();
|
|
|
|
const int hrw = rendSize.w / 2;
|
|
DrawDigital(&(rect){ 0, 0, hrw, rendSize.h}, &stickl);
|
|
DrawAnalogue(&(rect){ hrw, 0, hrw, rendSize.h}, &stickr);
|
|
|
|
// test player thingo
|
|
if (showavatar)
|
|
{
|
|
plrpos = VecAdd(plrpos, VecScale(stickl.compos, framedelta * 0.5));
|
|
plrpos.x = pfmod(plrpos.x, rendSize.w);
|
|
plrpos.y = pfmod(plrpos.y, rendSize.h);
|
|
|
|
SetDrawColour(0xFF0000FF);
|
|
const int plrSz = 32;
|
|
DrawRect(
|
|
(int)plrpos.x - plrSz / 2,
|
|
(int)plrpos.y - plrSz / 2,
|
|
plrSz, plrSz);
|
|
}
|
|
|
|
DrawPresent();
|
|
repaint = false;
|
|
}
|
|
}
|
|
|
|
res = 0;
|
|
error:
|
|
SDL_GameControllerClose(pad);
|
|
QuitDraw();
|
|
SDL_DestroyWindow(window);
|
|
SDL_Quit();
|
|
return res;
|
|
}
|