2018-01-24 10:20:05 +01:00
|
|
|
#include "main.h"
|
|
|
|
#include "studio.h"
|
|
|
|
|
|
|
|
#define STUDIO_UI_SCALE 3
|
|
|
|
#define STUDIO_PIXEL_FORMAT SDL_PIXELFORMAT_ARGB8888
|
|
|
|
#define TEXTURE_SIZE (TIC80_FULLWIDTH)
|
|
|
|
#define OFFSET_LEFT ((TIC80_FULLWIDTH-TIC80_WIDTH)/2)
|
|
|
|
#define OFFSET_TOP ((TIC80_FULLHEIGHT-TIC80_HEIGHT)/2)
|
|
|
|
|
|
|
|
static struct
|
|
|
|
{
|
2018-01-24 12:01:19 +01:00
|
|
|
Studio* studio;
|
|
|
|
|
2018-01-24 10:20:05 +01:00
|
|
|
SDL_Window* window;
|
|
|
|
SDL_Renderer* renderer;
|
|
|
|
SDL_Texture* texture;
|
|
|
|
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
SDL_AudioSpec spec;
|
|
|
|
SDL_AudioDeviceID device;
|
|
|
|
SDL_AudioCVT cvt;
|
|
|
|
} audio;
|
|
|
|
|
2018-01-24 15:56:55 +01:00
|
|
|
SDL_Joystick* joysticks[TIC_GAMEPADS];
|
|
|
|
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
// tic80_gamepads keyboard;
|
|
|
|
tic80_gamepads touch;
|
|
|
|
tic80_gamepads joystick;
|
|
|
|
|
|
|
|
SDL_Texture* texture;
|
|
|
|
|
|
|
|
bool show;
|
|
|
|
s32 counter;
|
|
|
|
s32 alpha;
|
|
|
|
bool backProcessed;
|
|
|
|
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
s32 size;
|
|
|
|
SDL_Point axis;
|
|
|
|
SDL_Point a;
|
|
|
|
SDL_Point b;
|
|
|
|
SDL_Point x;
|
|
|
|
SDL_Point y;
|
|
|
|
} part;
|
|
|
|
} gamepad;
|
|
|
|
|
2018-01-24 10:20:05 +01:00
|
|
|
bool quitFlag;
|
|
|
|
bool missedFrame;
|
|
|
|
} platform;
|
|
|
|
|
|
|
|
static void initSound()
|
|
|
|
{
|
|
|
|
SDL_AudioSpec want =
|
|
|
|
{
|
|
|
|
.freq = 44100,
|
|
|
|
.format = AUDIO_S16,
|
|
|
|
.channels = 1,
|
|
|
|
.userdata = NULL,
|
|
|
|
};
|
|
|
|
|
|
|
|
platform.audio.device = SDL_OpenAudioDevice(NULL, 0, &want, &platform.audio.spec, SDL_AUDIO_ALLOW_ANY_CHANGE);
|
|
|
|
|
|
|
|
SDL_BuildAudioCVT(&platform.audio.cvt, want.format, want.channels, platform.audio.spec.freq, platform.audio.spec.format, platform.audio.spec.channels, platform.audio.spec.freq);
|
|
|
|
|
|
|
|
if(platform.audio.cvt.needed)
|
|
|
|
{
|
|
|
|
platform.audio.cvt.len = platform.audio.spec.freq * sizeof(s16) / TIC_FRAMERATE;
|
|
|
|
platform.audio.cvt.buf = SDL_malloc(platform.audio.cvt.len * platform.audio.cvt.len_mult);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void setWindowIcon()
|
|
|
|
{
|
|
|
|
// enum{ Size = 64, TileSize = 16, ColorKey = 14, Cols = TileSize / TIC_SPRITESIZE, Scale = Size/TileSize};
|
2018-01-24 15:56:55 +01:00
|
|
|
// platform.studio->tic->api.clear(platform.studio->tic, 0);
|
2018-01-24 10:20:05 +01:00
|
|
|
|
|
|
|
// u32* pixels = SDL_malloc(Size * Size * sizeof(u32));
|
|
|
|
|
2018-01-24 15:56:55 +01:00
|
|
|
// const u32* pal = tic_palette_blit(&platform.studio->tic->config.palette);
|
2018-01-24 10:20:05 +01:00
|
|
|
|
|
|
|
// for(s32 j = 0, index = 0; j < Size; j++)
|
|
|
|
// for(s32 i = 0; i < Size; i++, index++)
|
|
|
|
// {
|
2018-01-24 15:56:55 +01:00
|
|
|
// u8 color = getSpritePixel(platform.studio->tic->config.bank0.tiles.data, i/Scale, j/Scale);
|
2018-01-24 10:20:05 +01:00
|
|
|
// pixels[index] = color == ColorKey ? 0 : pal[color];
|
|
|
|
// }
|
|
|
|
|
|
|
|
// SDL_Surface* surface = SDL_CreateRGBSurfaceFrom(pixels, Size, Size,
|
|
|
|
// sizeof(s32) * BITS_IN_BYTE, Size * sizeof(s32),
|
|
|
|
// 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
|
|
|
|
|
|
|
|
// SDL_SetWindowIcon(platform.window, surface);
|
|
|
|
// SDL_FreeSurface(surface);
|
|
|
|
// SDL_free(pixels);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void updateGamepadParts()
|
|
|
|
{
|
2018-01-24 15:56:55 +01:00
|
|
|
s32 tileSize = TIC_SPRITESIZE;
|
|
|
|
s32 offset = 0;
|
|
|
|
SDL_Rect rect;
|
2018-01-24 10:20:05 +01:00
|
|
|
|
2018-01-24 15:56:55 +01:00
|
|
|
const s32 JoySize = 3;
|
|
|
|
SDL_GetWindowSize(platform.window, &rect.w, &rect.h);
|
2018-01-24 10:20:05 +01:00
|
|
|
|
2018-01-24 15:56:55 +01:00
|
|
|
if(rect.w < rect.h)
|
|
|
|
{
|
|
|
|
tileSize = rect.w / 2 / JoySize;
|
|
|
|
offset = (rect.h * 2 - JoySize * tileSize) / 3;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tileSize = rect.w / 5 / JoySize;
|
|
|
|
offset = (rect.h - JoySize * tileSize) / 2;
|
|
|
|
}
|
2018-01-24 10:20:05 +01:00
|
|
|
|
2018-01-24 15:56:55 +01:00
|
|
|
platform.gamepad.part.size = tileSize;
|
|
|
|
platform.gamepad.part.axis = (SDL_Point){0, offset};
|
|
|
|
platform.gamepad.part.a = (SDL_Point){rect.w - 2*tileSize, 2*tileSize + offset};
|
|
|
|
platform.gamepad.part.b = (SDL_Point){rect.w - 1*tileSize, 1*tileSize + offset};
|
|
|
|
platform.gamepad.part.x = (SDL_Point){rect.w - 3*tileSize, 1*tileSize + offset};
|
|
|
|
platform.gamepad.part.y = (SDL_Point){rect.w - 2*tileSize, 0*tileSize + offset};
|
2018-01-24 10:20:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void transparentBlit(u32* out, s32 pitch)
|
|
|
|
{
|
2018-01-24 15:56:55 +01:00
|
|
|
const u8* in = platform.studio->tic->ram.vram.screen.data;
|
|
|
|
const u8* end = in + sizeof(platform.studio->tic->ram.vram.screen);
|
|
|
|
const u32* pal = tic_palette_blit(&platform.studio->tic->config.palette);
|
|
|
|
const u32 Delta = (pitch/sizeof *out - TIC80_WIDTH);
|
2018-01-24 10:20:05 +01:00
|
|
|
|
2018-01-24 15:56:55 +01:00
|
|
|
s32 col = 0;
|
2018-01-24 10:20:05 +01:00
|
|
|
|
2018-01-24 15:56:55 +01:00
|
|
|
while(in != end)
|
|
|
|
{
|
|
|
|
u8 low = *in & 0x0f;
|
|
|
|
u8 hi = (*in & 0xf0) >> TIC_PALETTE_BPP;
|
|
|
|
*out++ = low ? (*(pal + low) | 0xff000000) : 0;
|
|
|
|
*out++ = hi ? (*(pal + hi) | 0xff000000) : 0;
|
|
|
|
in++;
|
2018-01-24 10:20:05 +01:00
|
|
|
|
2018-01-24 15:56:55 +01:00
|
|
|
col += BITS_IN_BYTE / TIC_PALETTE_BPP;
|
2018-01-24 10:20:05 +01:00
|
|
|
|
2018-01-24 15:56:55 +01:00
|
|
|
if (col == TIC80_WIDTH)
|
|
|
|
{
|
|
|
|
col = 0;
|
|
|
|
out += Delta;
|
|
|
|
}
|
|
|
|
}
|
2018-01-24 10:20:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void initTouchGamepad()
|
|
|
|
{
|
2018-01-24 15:56:55 +01:00
|
|
|
if (!platform.renderer)
|
|
|
|
return;
|
2018-01-24 10:20:05 +01:00
|
|
|
|
2018-01-24 15:56:55 +01:00
|
|
|
platform.studio->tic->api.map(platform.studio->tic, &platform.studio->tic->config.bank0.map, &platform.studio->tic->config.bank0.tiles, 0, 0, TIC_MAP_SCREEN_WIDTH, TIC_MAP_SCREEN_HEIGHT, 0, 0, -1, 1);
|
2018-01-24 10:20:05 +01:00
|
|
|
|
2018-01-24 15:56:55 +01:00
|
|
|
if(!platform.gamepad.texture)
|
|
|
|
{
|
|
|
|
platform.gamepad.texture = SDL_CreateTexture(platform.renderer, STUDIO_PIXEL_FORMAT, SDL_TEXTUREACCESS_STREAMING, TEXTURE_SIZE, TEXTURE_SIZE);
|
|
|
|
SDL_SetTextureBlendMode(platform.gamepad.texture, SDL_BLENDMODE_BLEND);
|
|
|
|
}
|
2018-01-24 10:20:05 +01:00
|
|
|
|
2018-01-24 15:56:55 +01:00
|
|
|
{
|
|
|
|
void* pixels = NULL;
|
|
|
|
s32 pitch = 0;
|
2018-01-24 10:20:05 +01:00
|
|
|
|
2018-01-24 15:56:55 +01:00
|
|
|
SDL_LockTexture(platform.gamepad.texture, NULL, &pixels, &pitch);
|
|
|
|
transparentBlit(pixels, pitch);
|
|
|
|
SDL_UnlockTexture(platform.gamepad.texture);
|
|
|
|
}
|
2018-01-24 10:20:05 +01:00
|
|
|
|
2018-01-24 15:56:55 +01:00
|
|
|
updateGamepadParts();
|
2018-01-24 10:20:05 +01:00
|
|
|
}
|
|
|
|
|
2018-01-24 12:55:13 +01:00
|
|
|
static void calcTextureRect(SDL_Rect* rect)
|
|
|
|
{
|
|
|
|
SDL_GetWindowSize(platform.window, &rect->w, &rect->h);
|
|
|
|
|
|
|
|
if (rect->w * TIC80_HEIGHT < rect->h * TIC80_WIDTH)
|
|
|
|
{
|
|
|
|
s32 discreteWidth = rect->w - rect->w % TIC80_WIDTH;
|
|
|
|
s32 discreteHeight = TIC80_HEIGHT * discreteWidth / TIC80_WIDTH;
|
|
|
|
|
|
|
|
rect->x = (rect->w - discreteWidth) / 2;
|
|
|
|
|
|
|
|
rect->y = rect->w > rect->h
|
|
|
|
? (rect->h - discreteHeight) / 2
|
|
|
|
: OFFSET_LEFT*discreteWidth/TIC80_WIDTH;
|
|
|
|
|
|
|
|
rect->w = discreteWidth;
|
|
|
|
rect->h = discreteHeight;
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
s32 discreteHeight = rect->h - rect->h % TIC80_HEIGHT;
|
|
|
|
s32 discreteWidth = TIC80_WIDTH * discreteHeight / TIC80_HEIGHT;
|
|
|
|
|
|
|
|
rect->x = (rect->w - discreteWidth) / 2;
|
|
|
|
rect->y = (rect->h - discreteHeight) / 2;
|
|
|
|
|
|
|
|
rect->w = discreteWidth;
|
|
|
|
rect->h = discreteHeight;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void processMouse()
|
|
|
|
{
|
|
|
|
s32 mx = 0, my = 0;
|
|
|
|
s32 mb = SDL_GetMouseState(&mx, &my);
|
|
|
|
|
2018-01-24 14:13:46 +01:00
|
|
|
tic80_input* input = &platform.studio->tic->ram.input;
|
2018-01-24 12:55:13 +01:00
|
|
|
|
|
|
|
{
|
2018-01-24 14:13:46 +01:00
|
|
|
input->mouse.x = input->mouse.y = 0;
|
2018-01-24 12:55:13 +01:00
|
|
|
|
|
|
|
SDL_Rect rect = {0, 0, 0, 0};
|
|
|
|
calcTextureRect(&rect);
|
|
|
|
|
2018-01-24 14:13:46 +01:00
|
|
|
if(rect.w) input->mouse.x = (mx - rect.x) * TIC80_WIDTH / rect.w;
|
|
|
|
if(rect.h) input->mouse.y = (my - rect.y) * TIC80_HEIGHT / rect.h;
|
2018-01-24 12:55:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
{
|
2018-01-24 14:13:46 +01:00
|
|
|
input->mouse.left = mb & SDL_BUTTON_LMASK;
|
|
|
|
input->mouse.middle = mb & SDL_BUTTON_MMASK;
|
|
|
|
input->mouse.right = mb & SDL_BUTTON_RMASK;
|
2018-01-24 12:55:13 +01:00
|
|
|
}
|
|
|
|
|
2018-01-24 15:56:55 +01:00
|
|
|
// for(int i = 0; i < COUNT_OF(platform.mouse.state); i++)
|
2018-01-24 12:55:13 +01:00
|
|
|
// {
|
2018-01-24 15:56:55 +01:00
|
|
|
// MouseState* state = &platform.mouse.state[i];
|
2018-01-24 12:55:13 +01:00
|
|
|
|
2018-01-24 15:56:55 +01:00
|
|
|
// if(!state->down && (platform.mouse.button & SDL_BUTTON(i + 1)))
|
2018-01-24 12:55:13 +01:00
|
|
|
// {
|
|
|
|
// state->down = true;
|
|
|
|
|
2018-01-24 15:56:55 +01:00
|
|
|
// state->start.x = platform.mouse.cursor.x;
|
|
|
|
// state->start.y = platform.mouse.cursor.y;
|
2018-01-24 12:55:13 +01:00
|
|
|
// }
|
2018-01-24 15:56:55 +01:00
|
|
|
// else if(state->down && !(platform.mouse.button & SDL_BUTTON(i + 1)))
|
2018-01-24 12:55:13 +01:00
|
|
|
// {
|
2018-01-24 15:56:55 +01:00
|
|
|
// state->end.x = platform.mouse.cursor.x;
|
|
|
|
// state->end.y = platform.mouse.cursor.y;
|
2018-01-24 12:55:13 +01:00
|
|
|
|
|
|
|
// state->click = true;
|
|
|
|
// state->down = false;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
|
2018-01-24 14:13:46 +01:00
|
|
|
static void processKeyboard()
|
2018-01-24 10:20:05 +01:00
|
|
|
{
|
2018-01-24 14:13:46 +01:00
|
|
|
static const u8 KeyboardCodes[] =
|
|
|
|
{
|
|
|
|
#include "keycodes.c"
|
|
|
|
};
|
|
|
|
|
|
|
|
tic80_input* input = &platform.studio->tic->ram.input;
|
|
|
|
input->keyboard.data = 0;
|
|
|
|
|
|
|
|
const u8* keyboard = SDL_GetKeyboardState(NULL);
|
|
|
|
|
|
|
|
for(s32 i = 0, c = 0; i < COUNT_OF(KeyboardCodes) && c < COUNT_OF(input->keyboard.keys); i++)
|
|
|
|
if(keyboard[i] && KeyboardCodes[i] > tic_key_unknown)
|
|
|
|
input->keyboard.keys[c++] = KeyboardCodes[i];
|
|
|
|
}
|
|
|
|
|
2018-01-24 15:56:55 +01:00
|
|
|
#if !defined(__EMSCRIPTEN__) && !defined(__MACOSX__)
|
|
|
|
|
|
|
|
static bool checkTouch(const SDL_Rect* rect, s32* x, s32* y)
|
|
|
|
{
|
|
|
|
s32 devices = SDL_GetNumTouchDevices();
|
|
|
|
s32 width = 0, height = 0;
|
|
|
|
SDL_GetWindowSize(platform.window, &width, &height);
|
|
|
|
|
|
|
|
for (s32 i = 0; i < devices; i++)
|
|
|
|
{
|
|
|
|
SDL_TouchID id = SDL_GetTouchDevice(i);
|
|
|
|
|
|
|
|
// very strange, but on Android id always == 0
|
|
|
|
//if (id)
|
|
|
|
{
|
|
|
|
s32 fingers = SDL_GetNumTouchFingers(id);
|
|
|
|
|
|
|
|
if(fingers)
|
|
|
|
{
|
|
|
|
platform.gamepad.counter = 0;
|
|
|
|
|
|
|
|
if (!platform.gamepad.show)
|
|
|
|
{
|
|
|
|
platform.gamepad.alpha = getConfig()->theme.gamepad.touch.alpha;
|
|
|
|
SDL_SetTextureAlphaMod(platform.gamepad.texture, platform.gamepad.alpha);
|
|
|
|
platform.gamepad.show = true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (s32 f = 0; f < fingers; f++)
|
|
|
|
{
|
|
|
|
SDL_Finger* finger = SDL_GetTouchFinger(id, f);
|
|
|
|
|
|
|
|
if (finger && finger->pressure > 0.0f)
|
|
|
|
{
|
|
|
|
SDL_Point point = { (s32)(finger->x * width), (s32)(finger->y * height) };
|
|
|
|
if (SDL_PointInRect(&point, rect))
|
|
|
|
{
|
|
|
|
*x = point.x;
|
|
|
|
*y = point.y;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void processTouchGamepad()
|
|
|
|
{
|
|
|
|
platform.gamepad.touch.data = 0;
|
|
|
|
|
|
|
|
const s32 size = platform.gamepad.part.size;
|
|
|
|
s32 x = 0, y = 0;
|
|
|
|
|
|
|
|
{
|
|
|
|
SDL_Rect axis = {platform.gamepad.part.axis.x, platform.gamepad.part.axis.y, size*3, size*3};
|
|
|
|
|
|
|
|
if(checkTouch(&axis, &x, &y))
|
|
|
|
{
|
|
|
|
x -= axis.x;
|
|
|
|
y -= axis.y;
|
|
|
|
|
|
|
|
s32 xt = x / size;
|
|
|
|
s32 yt = y / size;
|
|
|
|
|
|
|
|
if(yt == 0) platform.gamepad.touch.first.up = true;
|
|
|
|
else if(yt == 2) platform.gamepad.touch.first.down = true;
|
|
|
|
|
|
|
|
if(xt == 0) platform.gamepad.touch.first.left = true;
|
|
|
|
else if(xt == 2) platform.gamepad.touch.first.right = true;
|
|
|
|
|
|
|
|
if(xt == 1 && yt == 1)
|
|
|
|
{
|
|
|
|
xt = (x - size)/(size/3);
|
|
|
|
yt = (y - size)/(size/3);
|
|
|
|
|
|
|
|
if(yt == 0) platform.gamepad.touch.first.up = true;
|
|
|
|
else if(yt == 2) platform.gamepad.touch.first.down = true;
|
|
|
|
|
|
|
|
if(xt == 0) platform.gamepad.touch.first.left = true;
|
|
|
|
else if(xt == 2) platform.gamepad.touch.first.right = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
SDL_Rect a = {platform.gamepad.part.a.x, platform.gamepad.part.a.y, size, size};
|
|
|
|
if(checkTouch(&a, &x, &y)) platform.gamepad.touch.first.a = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
SDL_Rect b = {platform.gamepad.part.b.x, platform.gamepad.part.b.y, size, size};
|
|
|
|
if(checkTouch(&b, &x, &y)) platform.gamepad.touch.first.b = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
SDL_Rect xb = {platform.gamepad.part.x.x, platform.gamepad.part.x.y, size, size};
|
|
|
|
if(checkTouch(&xb, &x, &y)) platform.gamepad.touch.first.x = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
SDL_Rect yb = {platform.gamepad.part.y.x, platform.gamepad.part.y.y, size, size};
|
|
|
|
if(checkTouch(&yb, &x, &y)) platform.gamepad.touch.first.y = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static s32 getAxisMask(SDL_Joystick* joystick)
|
|
|
|
{
|
|
|
|
s32 mask = 0;
|
|
|
|
|
|
|
|
s32 axesCount = SDL_JoystickNumAxes(joystick);
|
|
|
|
|
|
|
|
for (s32 a = 0; a < axesCount; a++)
|
|
|
|
{
|
|
|
|
s32 axe = SDL_JoystickGetAxis(joystick, a);
|
|
|
|
|
|
|
|
if (axe)
|
|
|
|
{
|
|
|
|
if (a == 0)
|
|
|
|
{
|
|
|
|
if (axe > 16384) mask |= SDL_HAT_RIGHT;
|
|
|
|
else if(axe < -16384) mask |= SDL_HAT_LEFT;
|
|
|
|
}
|
|
|
|
else if (a == 1)
|
|
|
|
{
|
|
|
|
if (axe > 16384) mask |= SDL_HAT_DOWN;
|
|
|
|
else if (axe < -16384) mask |= SDL_HAT_UP;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return mask;
|
|
|
|
}
|
|
|
|
|
|
|
|
static s32 getJoystickHatMask(s32 hat)
|
|
|
|
{
|
|
|
|
tic80_gamepads gamepad;
|
|
|
|
gamepad.data = 0;
|
|
|
|
|
|
|
|
gamepad.first.up = hat & SDL_HAT_UP;
|
|
|
|
gamepad.first.down = hat & SDL_HAT_DOWN;
|
|
|
|
gamepad.first.left = hat & SDL_HAT_LEFT;
|
|
|
|
gamepad.first.right = hat & SDL_HAT_RIGHT;
|
|
|
|
|
|
|
|
return gamepad.data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void processJoysticks()
|
|
|
|
{
|
|
|
|
platform.gamepad.joystick.data = 0;
|
|
|
|
s32 index = 0;
|
|
|
|
|
|
|
|
for(s32 i = 0; i < COUNT_OF(platform.joysticks); i++)
|
|
|
|
{
|
|
|
|
SDL_Joystick* joystick = platform.joysticks[i];
|
|
|
|
|
|
|
|
if(joystick && SDL_JoystickGetAttached(joystick))
|
|
|
|
{
|
|
|
|
tic80_gamepad* gamepad = NULL;
|
|
|
|
|
|
|
|
switch(index)
|
|
|
|
{
|
|
|
|
case 0: gamepad = &platform.gamepad.joystick.first; break;
|
|
|
|
case 1: gamepad = &platform.gamepad.joystick.second; break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(gamepad)
|
|
|
|
{
|
|
|
|
gamepad->data |= getJoystickHatMask(getAxisMask(joystick));
|
|
|
|
|
|
|
|
for (s32 h = 0; h < SDL_JoystickNumHats(joystick); h++)
|
|
|
|
gamepad->data |= getJoystickHatMask(SDL_JoystickGetHat(joystick, h));
|
|
|
|
|
|
|
|
s32 numButtons = SDL_JoystickNumButtons(joystick);
|
|
|
|
if(numButtons >= 2)
|
|
|
|
{
|
|
|
|
gamepad->a = SDL_JoystickGetButton(joystick, 0);
|
|
|
|
gamepad->b = SDL_JoystickGetButton(joystick, 1);
|
|
|
|
|
|
|
|
if(numButtons >= 4)
|
|
|
|
{
|
|
|
|
gamepad->x = SDL_JoystickGetButton(joystick, 2);
|
|
|
|
gamepad->y = SDL_JoystickGetButton(joystick, 3);
|
|
|
|
|
|
|
|
// for(s32 i = 5; i < numButtons; i++)
|
|
|
|
// {
|
|
|
|
// s32 back = SDL_JoystickGetButton(joystick, i);
|
|
|
|
|
|
|
|
// if(back)
|
|
|
|
// {
|
|
|
|
// if(!platform.gamepad.backProcessed)
|
|
|
|
// {
|
|
|
|
// if(isGameMenu())
|
|
|
|
// {
|
|
|
|
// platform.mode == TIC_MENU_MODE ? hideGameMenu() : showGameMenu();
|
|
|
|
// platform.gamepad.backProcessed = true;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
// return;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
// platform.gamepad.backProcessed = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
index++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void processGamepad()
|
|
|
|
{
|
|
|
|
// processKeyboardGamepad();
|
|
|
|
|
|
|
|
#if !defined(__EMSCRIPTEN__) && !defined(__MACOSX__)
|
|
|
|
processTouchGamepad();
|
|
|
|
#endif
|
|
|
|
processJoysticks();
|
|
|
|
|
|
|
|
{
|
|
|
|
platform.studio->tic->ram.input.gamepads.data = 0;
|
|
|
|
|
|
|
|
// platform.studio->tic->ram.input.gamepads.data |= platform.gamepad.keyboard.data;
|
|
|
|
platform.studio->tic->ram.input.gamepads.data |= platform.gamepad.touch.data;
|
|
|
|
platform.studio->tic->ram.input.gamepads.data |= platform.gamepad.joystick.data;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-24 14:13:46 +01:00
|
|
|
static void pollEvent()
|
|
|
|
{
|
|
|
|
SDL_Event event;
|
2018-01-24 10:20:05 +01:00
|
|
|
|
|
|
|
if(SDL_PollEvent(&event))
|
|
|
|
{
|
|
|
|
switch(event.type)
|
|
|
|
{
|
|
|
|
// case SDL_KEYDOWN:
|
|
|
|
// if(processShortcuts(&event.key)) return NULL;
|
|
|
|
// break;
|
|
|
|
// case SDL_JOYDEVICEADDED:
|
|
|
|
// {
|
|
|
|
// s32 id = event.jdevice.which;
|
|
|
|
|
|
|
|
// if (id < TIC_GAMEPADS)
|
|
|
|
// {
|
2018-01-24 12:01:19 +01:00
|
|
|
// if(platform.joysticks[id])
|
|
|
|
// SDL_JoystickClose(platform.joysticks[id]);
|
2018-01-24 10:20:05 +01:00
|
|
|
|
2018-01-24 12:01:19 +01:00
|
|
|
// platform.joysticks[id] = SDL_JoystickOpen(id);
|
2018-01-24 10:20:05 +01:00
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// break;
|
|
|
|
|
|
|
|
// case SDL_JOYDEVICEREMOVED:
|
|
|
|
// {
|
|
|
|
// s32 id = event.jdevice.which;
|
|
|
|
|
2018-01-24 12:01:19 +01:00
|
|
|
// if (id < TIC_GAMEPADS && platform.joysticks[id])
|
2018-01-24 10:20:05 +01:00
|
|
|
// {
|
2018-01-24 12:01:19 +01:00
|
|
|
// SDL_JoystickClose(platform.joysticks[id]);
|
|
|
|
// platform.joysticks[id] = NULL;
|
2018-01-24 10:20:05 +01:00
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// break;
|
2018-01-24 15:56:55 +01:00
|
|
|
case SDL_WINDOWEVENT:
|
|
|
|
switch(event.window.event)
|
|
|
|
{
|
|
|
|
case SDL_WINDOWEVENT_RESIZED: updateGamepadParts(); break;
|
2018-01-24 10:20:05 +01:00
|
|
|
// case SDL_WINDOWEVENT_FOCUS_GAINED:
|
|
|
|
|
|
|
|
// #if defined(TIC80_PRO)
|
|
|
|
|
2018-01-24 12:01:19 +01:00
|
|
|
// if(platform.mode != TIC_START_MODE)
|
2018-01-24 10:20:05 +01:00
|
|
|
// {
|
2018-01-24 12:01:19 +01:00
|
|
|
// Console* console = platform.console;
|
2018-01-24 10:20:05 +01:00
|
|
|
|
|
|
|
// u64 mdate = fsMDate(console->fs, console->romName);
|
|
|
|
|
2018-01-24 12:01:19 +01:00
|
|
|
// if(platform.cart.mdate && mdate > platform.cart.mdate)
|
2018-01-24 10:20:05 +01:00
|
|
|
// {
|
|
|
|
// if(studioCartChanged())
|
|
|
|
// {
|
|
|
|
// static const char* Rows[] =
|
|
|
|
// {
|
|
|
|
// "",
|
|
|
|
// "CART HAS CHANGED!",
|
|
|
|
// "",
|
|
|
|
// "DO YOU WANT",
|
|
|
|
// "TO RELOAD IT?"
|
|
|
|
// };
|
|
|
|
|
|
|
|
// showDialog(Rows, COUNT_OF(Rows), reloadConfirm, NULL);
|
|
|
|
// }
|
|
|
|
// else console->updateProject(console);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
// #endif
|
|
|
|
// {
|
2018-01-24 12:01:19 +01:00
|
|
|
// Code* code = platform.editor[platform.bank.index.code].code;
|
|
|
|
// platform.console->codeLiveReload.reload(platform.console, code->src);
|
|
|
|
// if(platform.console->codeLiveReload.active && code->update)
|
2018-01-24 10:20:05 +01:00
|
|
|
// code->update(code);
|
|
|
|
// }
|
2018-01-24 15:56:55 +01:00
|
|
|
// break;
|
|
|
|
}
|
|
|
|
break;
|
2018-01-24 10:20:05 +01:00
|
|
|
// case SDL_FINGERUP:
|
|
|
|
// showSoftKeyboard();
|
|
|
|
// break;
|
|
|
|
case SDL_QUIT:
|
|
|
|
platform.quitFlag = true;
|
|
|
|
// exitStudio();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2018-01-24 12:55:13 +01:00
|
|
|
// return &event;
|
2018-01-24 10:20:05 +01:00
|
|
|
}
|
|
|
|
|
2018-01-24 12:01:19 +01:00
|
|
|
// if(platform.mode != TIC_RUN_MODE)
|
2018-01-24 10:20:05 +01:00
|
|
|
// processGesture();
|
|
|
|
|
2018-01-24 12:01:19 +01:00
|
|
|
// if(!platform.gesture.active)
|
2018-01-24 14:13:46 +01:00
|
|
|
|
|
|
|
processMouse();
|
2018-01-24 15:56:55 +01:00
|
|
|
processGamepad();
|
2018-01-24 14:13:46 +01:00
|
|
|
processKeyboard();
|
2018-01-24 10:20:05 +01:00
|
|
|
|
2018-01-24 12:01:19 +01:00
|
|
|
// if(platform.mode == TIC_RUN_MODE)
|
2018-01-24 10:20:05 +01:00
|
|
|
// {
|
2018-01-24 15:56:55 +01:00
|
|
|
// if(platform.studio->tic->input.gamepad) processGamepadInput();
|
|
|
|
// if(platform.studio->tic->input.mouse) processMouseInput();
|
|
|
|
// if(platform.studio->tic->input.keyboard) processKeyboardInput();
|
2018-01-24 10:20:05 +01:00
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// {
|
|
|
|
// processGamepadInput();
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
|
|
|
|
static void blitTexture()
|
|
|
|
{
|
2018-01-24 15:56:55 +01:00
|
|
|
// tic_mem* tic = platform.studio->tic;
|
2018-01-24 10:20:05 +01:00
|
|
|
SDL_Rect rect = {0, 0, 0, 0};
|
|
|
|
calcTextureRect(&rect);
|
|
|
|
|
|
|
|
void* pixels = NULL;
|
|
|
|
s32 pitch = 0;
|
|
|
|
SDL_LockTexture(platform.texture, NULL, &pixels, &pitch);
|
|
|
|
|
|
|
|
studioTick(pixels);
|
|
|
|
|
|
|
|
// tic_scanline scanline = NULL;
|
|
|
|
// tic_overlap overlap = NULL;
|
|
|
|
// void* data = NULL;
|
|
|
|
|
2018-01-24 12:01:19 +01:00
|
|
|
// switch(platform.mode)
|
2018-01-24 10:20:05 +01:00
|
|
|
// {
|
|
|
|
// case TIC_RUN_MODE:
|
|
|
|
// scanline = tic->api.scanline;
|
|
|
|
// overlap = tic->api.overlap;
|
|
|
|
// break;
|
|
|
|
// case TIC_SPRITE_MODE:
|
|
|
|
// {
|
2018-01-24 12:01:19 +01:00
|
|
|
// Sprite* sprite = platform.editor[platform.bank.index.sprites].sprite;
|
2018-01-24 10:20:05 +01:00
|
|
|
// overlap = sprite->overlap;
|
|
|
|
// data = sprite;
|
|
|
|
// }
|
|
|
|
// break;
|
|
|
|
// case TIC_MAP_MODE:
|
|
|
|
// {
|
2018-01-24 12:01:19 +01:00
|
|
|
// Map* map = platform.editor[platform.bank.index.map].map;
|
2018-01-24 10:20:05 +01:00
|
|
|
// overlap = map->overlap;
|
|
|
|
// data = map;
|
|
|
|
// }
|
|
|
|
// break;
|
|
|
|
// default:
|
|
|
|
// break;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// tic->api.blit(tic, scanline, overlap, data);
|
|
|
|
// SDL_memcpy(pixels, tic->screen, sizeof tic->screen);
|
|
|
|
|
|
|
|
// recordFrame(pixels);
|
|
|
|
// drawDesyncLabel(pixels);
|
|
|
|
|
|
|
|
SDL_UnlockTexture(platform.texture);
|
|
|
|
|
|
|
|
{
|
|
|
|
enum {Header = OFFSET_TOP};
|
|
|
|
SDL_Rect srcRect = {0, 0, TIC80_FULLWIDTH, Header};
|
|
|
|
SDL_Rect dstRect = {0};
|
|
|
|
SDL_GetWindowSize(platform.window, &dstRect.w, &dstRect.h);
|
|
|
|
dstRect.h = rect.y;
|
|
|
|
SDL_RenderCopy(platform.renderer, platform.texture, &srcRect, &dstRect);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
enum {Header = OFFSET_TOP};
|
|
|
|
SDL_Rect srcRect = {0, TIC80_FULLHEIGHT - Header, TIC80_FULLWIDTH, Header};
|
|
|
|
SDL_Rect dstRect = {0};
|
|
|
|
SDL_GetWindowSize(platform.window, &dstRect.w, &dstRect.h);
|
|
|
|
dstRect.y = rect.y + rect.h;
|
|
|
|
dstRect.h = rect.y;
|
|
|
|
SDL_RenderCopy(platform.renderer, platform.texture, &srcRect, &dstRect);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
enum {Header = OFFSET_TOP};
|
|
|
|
enum {Left = OFFSET_LEFT};
|
|
|
|
SDL_Rect srcRect = {0, Header, Left, TIC80_HEIGHT};
|
|
|
|
SDL_Rect dstRect = {0};
|
|
|
|
SDL_GetWindowSize(platform.window, &dstRect.w, &dstRect.h);
|
|
|
|
dstRect.y = rect.y;
|
|
|
|
dstRect.h = rect.h;
|
|
|
|
SDL_RenderCopy(platform.renderer, platform.texture, &srcRect, &dstRect);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
enum {Top = OFFSET_TOP};
|
|
|
|
enum {Left = OFFSET_LEFT};
|
|
|
|
|
|
|
|
SDL_Rect srcRect = {Left, Top, TIC80_WIDTH, TIC80_HEIGHT};
|
|
|
|
|
|
|
|
SDL_RenderCopy(platform.renderer, platform.texture, &srcRect, &rect);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-24 12:01:19 +01:00
|
|
|
static void blitSound()
|
|
|
|
{
|
|
|
|
tic_mem* tic = platform.studio->tic;
|
|
|
|
|
|
|
|
SDL_PauseAudioDevice(platform.audio.device, 0);
|
|
|
|
|
|
|
|
if(platform.audio.cvt.needed)
|
|
|
|
{
|
|
|
|
SDL_memcpy(platform.audio.cvt.buf, tic->samples.buffer, tic->samples.size);
|
|
|
|
SDL_ConvertAudio(&platform.audio.cvt);
|
|
|
|
SDL_QueueAudio(platform.audio.device, platform.audio.cvt.buf, platform.audio.cvt.len_cvt);
|
|
|
|
}
|
|
|
|
else SDL_QueueAudio(platform.audio.device, tic->samples.buffer, tic->samples.size);
|
|
|
|
}
|
|
|
|
|
2018-01-24 15:56:55 +01:00
|
|
|
static void renderGamepad()
|
|
|
|
{
|
|
|
|
if(platform.gamepad.show || platform.gamepad.alpha); else return;
|
|
|
|
|
|
|
|
const s32 tileSize = platform.gamepad.part.size;
|
|
|
|
const SDL_Point axis = platform.gamepad.part.axis;
|
|
|
|
typedef struct { bool press; s32 x; s32 y;} Tile;
|
|
|
|
const Tile Tiles[] =
|
|
|
|
{
|
|
|
|
{platform.studio->tic->ram.input.gamepads.first.up, axis.x + 1*tileSize, axis.y + 0*tileSize},
|
|
|
|
{platform.studio->tic->ram.input.gamepads.first.down, axis.x + 1*tileSize, axis.y + 2*tileSize},
|
|
|
|
{platform.studio->tic->ram.input.gamepads.first.left, axis.x + 0*tileSize, axis.y + 1*tileSize},
|
|
|
|
{platform.studio->tic->ram.input.gamepads.first.right, axis.x + 2*tileSize, axis.y + 1*tileSize},
|
|
|
|
|
|
|
|
{platform.studio->tic->ram.input.gamepads.first.a, platform.gamepad.part.a.x, platform.gamepad.part.a.y},
|
|
|
|
{platform.studio->tic->ram.input.gamepads.first.b, platform.gamepad.part.b.x, platform.gamepad.part.b.y},
|
|
|
|
{platform.studio->tic->ram.input.gamepads.first.x, platform.gamepad.part.x.x, platform.gamepad.part.x.y},
|
|
|
|
{platform.studio->tic->ram.input.gamepads.first.y, platform.gamepad.part.y.x, platform.gamepad.part.y.y},
|
|
|
|
};
|
|
|
|
|
|
|
|
enum {ButtonsCount = 8};
|
|
|
|
|
|
|
|
for(s32 i = 0; i < COUNT_OF(Tiles); i++)
|
|
|
|
{
|
|
|
|
const Tile* tile = Tiles + i;
|
|
|
|
SDL_Rect src = {(tile->press ? ButtonsCount + i : i) * TIC_SPRITESIZE, 0, TIC_SPRITESIZE, TIC_SPRITESIZE};
|
|
|
|
SDL_Rect dest = {tile->x, tile->y, tileSize, tileSize};
|
|
|
|
|
|
|
|
SDL_RenderCopy(platform.renderer, platform.gamepad.texture, &src, &dest);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!platform.gamepad.show && platform.gamepad.alpha)
|
|
|
|
{
|
|
|
|
enum {Step = 3};
|
|
|
|
|
|
|
|
if(platform.gamepad.alpha - Step >= 0) platform.gamepad.alpha -= Step;
|
|
|
|
else platform.gamepad.alpha = 0;
|
|
|
|
|
|
|
|
SDL_SetTextureAlphaMod(platform.gamepad.texture, platform.gamepad.alpha);
|
|
|
|
}
|
|
|
|
|
|
|
|
platform.gamepad.counter = platform.gamepad.touch.data ? 0 : platform.gamepad.counter+1;
|
|
|
|
|
|
|
|
// wait 5 seconds and hide touch gamepad
|
|
|
|
if(platform.gamepad.counter >= 5 * TIC_FRAMERATE)
|
|
|
|
platform.gamepad.show = false;
|
|
|
|
}
|
|
|
|
|
2018-01-24 10:20:05 +01:00
|
|
|
static void tick()
|
|
|
|
{
|
|
|
|
pollEvent();
|
|
|
|
|
2018-01-24 12:01:19 +01:00
|
|
|
// if(!platform.fs) return;
|
2018-01-24 10:20:05 +01:00
|
|
|
|
2018-01-24 12:01:19 +01:00
|
|
|
// if(platform.quitFlag)
|
2018-01-24 10:20:05 +01:00
|
|
|
// {
|
|
|
|
// #if defined __EMSCRIPTEN__
|
2018-01-24 15:56:55 +01:00
|
|
|
// platform.studio->tic->api.clear(platform.studio->tic, TIC_COLOR_BG);
|
2018-01-24 10:20:05 +01:00
|
|
|
// blitTexture();
|
|
|
|
// emscripten_cancel_main_loop();
|
|
|
|
// #endif
|
|
|
|
// return;
|
|
|
|
// }
|
|
|
|
|
2018-01-24 12:01:19 +01:00
|
|
|
// SDL_SystemCursor cursor = platform.mouse.system;
|
|
|
|
// platform.mouse.system = SDL_SYSTEM_CURSOR_ARROW;
|
2018-01-24 10:20:05 +01:00
|
|
|
|
|
|
|
SDL_RenderClear(platform.renderer);
|
|
|
|
|
|
|
|
|
2018-01-24 15:56:55 +01:00
|
|
|
blitTexture();
|
2018-01-24 10:20:05 +01:00
|
|
|
|
2018-01-24 15:56:55 +01:00
|
|
|
// if(platform.mode == TIC_RUN_MODE && platform.studio->tic->input.gamepad)
|
|
|
|
renderGamepad();
|
2018-01-24 10:20:05 +01:00
|
|
|
|
2018-01-24 12:01:19 +01:00
|
|
|
// if(platform.mode == TIC_MENU_MODE || platform.mode == TIC_SURF_MODE)
|
2018-01-24 10:20:05 +01:00
|
|
|
// renderGamepad();
|
|
|
|
|
2018-01-24 12:01:19 +01:00
|
|
|
// if(platform.mouse.system != cursor)
|
|
|
|
// SDL_SetCursor(SDL_CreateSystemCursor(platform.mouse.system));
|
2018-01-24 10:20:05 +01:00
|
|
|
|
|
|
|
|
|
|
|
SDL_RenderPresent(platform.renderer);
|
|
|
|
|
2018-01-24 12:01:19 +01:00
|
|
|
blitSound();
|
2018-01-24 10:20:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
s32 main(s32 argc, char **argv)
|
|
|
|
{
|
|
|
|
SDL_SetHint(SDL_HINT_WINRT_HANDLE_BACK_BUTTON, "1");
|
|
|
|
SDL_SetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, "0");
|
|
|
|
|
|
|
|
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK);
|
|
|
|
|
|
|
|
initSound();
|
|
|
|
|
|
|
|
platform.window = SDL_CreateWindow( TIC_TITLE, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
|
|
|
(TIC80_FULLWIDTH) * STUDIO_UI_SCALE,
|
|
|
|
(TIC80_FULLHEIGHT) * STUDIO_UI_SCALE,
|
|
|
|
SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE
|
|
|
|
#if defined(__CHIP__)
|
|
|
|
| SDL_WINDOW_FULLSCREEN_DESKTOP
|
|
|
|
#endif
|
|
|
|
);
|
|
|
|
|
|
|
|
// set the window icon before renderer is created (issues on Linux)
|
|
|
|
setWindowIcon();
|
|
|
|
|
|
|
|
platform.renderer = SDL_CreateRenderer(platform.window, -1,
|
|
|
|
#if defined(__CHIP__)
|
|
|
|
SDL_RENDERER_SOFTWARE
|
|
|
|
#elif defined(__EMSCRIPTEN__)
|
|
|
|
SDL_RENDERER_ACCELERATED
|
|
|
|
#else
|
|
|
|
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC//(getConfig()->useVsync ? SDL_RENDERER_PRESENTVSYNC : 0)
|
|
|
|
#endif
|
|
|
|
);
|
|
|
|
|
|
|
|
platform.texture = SDL_CreateTexture(platform.renderer, STUDIO_PIXEL_FORMAT, SDL_TEXTUREACCESS_STREAMING, TEXTURE_SIZE, TEXTURE_SIZE);
|
|
|
|
|
2018-01-24 12:01:19 +01:00
|
|
|
platform.studio = studioInit(argc, argv, platform.audio.spec.freq);
|
2018-01-24 10:20:05 +01:00
|
|
|
|
2018-01-24 15:56:55 +01:00
|
|
|
initTouchGamepad();
|
|
|
|
|
2018-01-24 10:20:05 +01:00
|
|
|
#if defined(__EMSCRIPTEN__)
|
|
|
|
emscripten_set_main_loop(emstick, TIC_FRAMERATE, 1);
|
|
|
|
#else
|
|
|
|
{
|
|
|
|
|
|
|
|
bool useDelay = false;
|
|
|
|
{
|
|
|
|
SDL_RendererInfo info;
|
|
|
|
SDL_DisplayMode mode;
|
|
|
|
|
|
|
|
SDL_GetRendererInfo(platform.renderer, &info);
|
|
|
|
SDL_GetCurrentDisplayMode(SDL_GetWindowDisplayIndex(platform.window), &mode);
|
|
|
|
|
|
|
|
useDelay = !(info.flags & SDL_RENDERER_PRESENTVSYNC) || mode.refresh_rate > TIC_FRAMERATE;
|
|
|
|
}
|
|
|
|
|
|
|
|
u64 nextTick = SDL_GetPerformanceCounter();
|
|
|
|
const u64 Delta = SDL_GetPerformanceFrequency() / TIC_FRAMERATE;
|
|
|
|
|
|
|
|
while (!platform.quitFlag)
|
|
|
|
{
|
|
|
|
platform.missedFrame = false;
|
|
|
|
|
|
|
|
nextTick += Delta;
|
|
|
|
|
|
|
|
tick();
|
|
|
|
|
|
|
|
{
|
|
|
|
s64 delay = nextTick - SDL_GetPerformanceCounter();
|
|
|
|
|
|
|
|
if(delay < 0)
|
|
|
|
{
|
|
|
|
nextTick -= delay;
|
|
|
|
platform.missedFrame = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(useDelay || SDL_GetWindowFlags(platform.window) & SDL_WINDOW_MINIMIZED)
|
|
|
|
{
|
|
|
|
u32 time = (u32)(delay * 1000 / SDL_GetPerformanceFrequency());
|
|
|
|
if(time >= 10)
|
|
|
|
SDL_Delay(time);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
studioClose();
|
|
|
|
|
2018-01-24 12:01:19 +01:00
|
|
|
if(platform.audio.cvt.buf)
|
|
|
|
SDL_free(platform.audio.cvt.buf);
|
|
|
|
|
2018-01-24 12:55:13 +01:00
|
|
|
// if(platform.mouse.texture)
|
|
|
|
// SDL_DestroyTexture(platform.mouse.texture);
|
|
|
|
|
2018-01-24 15:56:55 +01:00
|
|
|
SDL_DestroyTexture(platform.gamepad.texture);
|
|
|
|
|
2018-01-24 10:20:05 +01:00
|
|
|
SDL_DestroyTexture(platform.texture);
|
|
|
|
SDL_DestroyRenderer(platform.renderer);
|
|
|
|
SDL_DestroyWindow(platform.window);
|
|
|
|
|
|
|
|
SDL_CloseAudioDevice(platform.audio.device);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|