added D3D11 and D3D12 renderers from Emil/n64-fast3d-engine
along with options to select backends for windowing, rendering, audio and controls in the Makefile use RENDER_API=D3D11 or D3D12 for the D3D renderers, that will also automatically enable using DXGI for windowing; SDL2 will still be used for input and audio for the time being also adds three-point filtering to the OpenGL backend and an option for it in the menu
This commit is contained in:
parent
fe1a8a8602
commit
a81a8e6ef1
107
Makefile
107
Makefile
|
@ -54,9 +54,16 @@ DISCORDRPC ?= 0
|
|||
NO_BZERO_BCOPY ?= 0
|
||||
NO_LDIV ?= 0
|
||||
|
||||
# Use OpenGL 1.3 renderer
|
||||
# Backend selection
|
||||
|
||||
LEGACY_GL ?= 0
|
||||
# Renderers: GL, GL_LEGACY, D3D11, D3D12
|
||||
RENDER_API ?= GL
|
||||
# Window managers: SDL2, DXGI (forced if D3D11 or D3D12 in RENDER_API)
|
||||
WINDOW_API ?= SDL2
|
||||
# Audio backends: SDL2
|
||||
AUDIO_API ?= SDL2
|
||||
# Controller backends (can have multiple, space separated): SDL2
|
||||
CONTROLLER_API ?= SDL2
|
||||
|
||||
# Misc settings for EXTERNAL_DATA
|
||||
|
||||
|
@ -207,6 +214,22 @@ ifeq ($(TARGET_WEB),1)
|
|||
VERSION_CFLAGS := $(VERSION_CFLAGS) -DTARGET_WEB
|
||||
endif
|
||||
|
||||
# Check backends
|
||||
|
||||
ifneq (,$(filter $(RENDER_API),D3D11 D3D12))
|
||||
ifneq ($(WINDOWS_BUILD),1)
|
||||
$(error DirectX is only supported on Windows)
|
||||
endif
|
||||
ifneq ($(WINDOW_API),DXGI)
|
||||
$(warning DirectX renderers require DXGI, forcing WINDOW_API value)
|
||||
WINDOW_API := DXGI
|
||||
endif
|
||||
else
|
||||
ifeq ($(WINDOW_API),DXGI)
|
||||
$(error DXGI can only be used with DirectX renderers)
|
||||
endif
|
||||
endif
|
||||
|
||||
################### Universal Dependencies ###################
|
||||
|
||||
# (This is a bit hacky, but a lot of rules implicitly depend
|
||||
|
@ -515,18 +538,68 @@ endif
|
|||
PYTHON := python3
|
||||
SDLCONFIG := $(CROSS)sdl2-config
|
||||
|
||||
# configure backend flags
|
||||
|
||||
BACKEND_CFLAGS := -DRAPI_$(RENDER_API)=1 -DWAPI_$(WINDOW_API)=1 -DAAPI_$(AUDIO_API)=1
|
||||
# can have multiple controller APIs
|
||||
BACKEND_CFLAGS += $(foreach capi,$(CONTROLLER_API),-DCAPI_$(capi)=1)
|
||||
BACKEND_LDFLAGS :=
|
||||
SDL2_USED := 0
|
||||
|
||||
# for now, it's either SDL+GL or DXGI+DirectX, so choose based on WAPI
|
||||
ifeq ($(WINDOW_API),DXGI)
|
||||
DXBITS := `cat $(ENDIAN_BITWIDTH) | tr ' ' '\n' | tail -1`
|
||||
ifeq ($(RENDER_API),D3D11)
|
||||
BACKEND_LDFLAGS += -ld3d11
|
||||
else ifeq ($(RENDER_API),D3D12)
|
||||
BACKEND_LDFLAGS += -ld3d12
|
||||
endif
|
||||
BACKEND_LDFLAGS += -ld3dcompiler -ldxgi -ldxguid
|
||||
BACKEND_LDFLAGS += -lsetupapi -ldinput8 -luser32 -lgdi32 -limm32 -lole32 -loleaut32 -lshell32 -lwinmm -lversion -luuid -static
|
||||
else ifeq ($(WINDOW_API),SDL2)
|
||||
ifeq ($(WINDOWS_BUILD),1)
|
||||
CC_CHECK := $(CC) -fsyntax-only -fsigned-char $(INCLUDE_CFLAGS) -Wall -Wextra -Wno-format-security $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) `$(SDLCONFIG) --cflags` -DUSE_SDL=2
|
||||
CFLAGS := $(OPT_FLAGS) $(INCLUDE_CFLAGS) $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) -fno-strict-aliasing -fwrapv `$(SDLCONFIG) --cflags` -DUSE_SDL=2
|
||||
BACKEND_LDFLAGS += -lglew32 -lglu32 -lopengl32
|
||||
else ifeq ($(TARGET_RPI),1)
|
||||
BACKEND_LDFLAGS += -lGLESv2
|
||||
else ifeq ($(OSX_BUILD),1)
|
||||
BACKEND_LDFLAGS += -framework OpenGL `pkg-config --libs glew`
|
||||
else
|
||||
BACKEND_LDFLAGS += -lGL
|
||||
endif
|
||||
SDL_USED := 2
|
||||
endif
|
||||
|
||||
ifeq ($(AUDIO_API),SDL2)
|
||||
SDL_USED := 2
|
||||
endif
|
||||
|
||||
ifneq (,$(findstring SDL,$(CONTROLLER_API)))
|
||||
SDL_USED := 2
|
||||
endif
|
||||
|
||||
# SDL can be used by different systems, so we consolidate all of that shit into this
|
||||
ifeq ($(SDL_USED),2)
|
||||
BACKEND_CFLAGS += -DHAVE_SDL2=1 `$(SDLCONFIG) --cflags`
|
||||
ifeq ($(WINDOWS_BUILD),1)
|
||||
BACKEND_LDFLAGS += `$(SDLCONFIG) --static-libs` -lsetupapi -luser32 -limm32 -lOle32 -loleaut32 -lshell32 -lwinmm -lversion
|
||||
else
|
||||
BACKEND_LDFLAGS += `$(SDLCONFIG) --libs`
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(WINDOWS_BUILD),1)
|
||||
CC_CHECK := $(CC) -fsyntax-only -fsigned-char $(BACKEND_CFLAGS) $(INCLUDE_CFLAGS) -Wall -Wextra -Wno-format-security $(VERSION_CFLAGS) $(GRUCODE_CFLAGS)
|
||||
CFLAGS := $(OPT_FLAGS) $(INCLUDE_CFLAGS) $(BACKEND_CFLAGS) $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) -fno-strict-aliasing -fwrapv
|
||||
|
||||
else ifeq ($(TARGET_WEB),1)
|
||||
CC_CHECK := $(CC) -fsyntax-only -fsigned-char $(INCLUDE_CFLAGS) -Wall -Wextra -Wno-format-security $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) -s USE_SDL=2
|
||||
CFLAGS := $(OPT_FLAGS) $(INCLUDE_CFLAGS) $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) -fno-strict-aliasing -fwrapv -s USE_SDL=2
|
||||
CC_CHECK := $(CC) -fsyntax-only -fsigned-char $(BACKEND_CFLAGS) $(INCLUDE_CFLAGS) -Wall -Wextra -Wno-format-security $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) -s USE_SDL=2
|
||||
CFLAGS := $(OPT_FLAGS) $(INCLUDE_CFLAGS) $(BACKEND_CFLAGS) $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) -fno-strict-aliasing -fwrapv -s USE_SDL=2
|
||||
|
||||
# Linux / Other builds below
|
||||
else
|
||||
CC_CHECK := $(CC) -fsyntax-only -fsigned-char $(INCLUDE_CFLAGS) -Wall -Wextra -Wno-format-security $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) `$(SDLCONFIG) --cflags` -DUSE_SDL=2
|
||||
CFLAGS := $(OPT_FLAGS) $(INCLUDE_CFLAGS) $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) -fno-strict-aliasing -fwrapv `$(SDLCONFIG) --cflags` -DUSE_SDL=2
|
||||
CC_CHECK := $(CC) -fsyntax-only -fsigned-char $(BACKEND_CFLAGS) $(INCLUDE_CFLAGS) -Wall -Wextra -Wno-format-security $(VERSION_CFLAGS) $(GRUCODE_CFLAGS)
|
||||
CFLAGS := $(OPT_FLAGS) $(INCLUDE_CFLAGS) $(BACKEND_CFLAGS) $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) -fno-strict-aliasing -fwrapv
|
||||
|
||||
endif
|
||||
|
||||
# Check for enhancement options
|
||||
|
@ -598,26 +671,28 @@ ASFLAGS := -I include -I $(BUILD_DIR) $(VERSION_ASFLAGS)
|
|||
|
||||
ifeq ($(TARGET_WEB),1)
|
||||
LDFLAGS := -lm -lGL -lSDL2 -no-pie -s TOTAL_MEMORY=20MB -g4 --source-map-base http://localhost:8080/ -s "EXTRA_EXPORTED_RUNTIME_METHODS=['callMain']"
|
||||
|
||||
else ifeq ($(WINDOWS_BUILD),1)
|
||||
LDFLAGS := $(BITS) -march=$(TARGET_ARCH) -Llib -lpthread -lglew32 `$(SDLCONFIG) --static-libs` -lm -lglu32 -lsetupapi -ldinput8 -luser32 -lgdi32 -limm32 -lole32 -loleaut32 -lshell32 -lwinmm -lversion -luuid -lopengl32 -static
|
||||
LDFLAGS := $(BITS) -march=$(TARGET_ARCH) -Llib -lpthread $(BACKEND_LDFLAGS) -static
|
||||
ifeq ($(CROSS),)
|
||||
LDFLAGS += -no-pie
|
||||
endif
|
||||
ifeq ($(WINDOWS_CONSOLE),1)
|
||||
LDFLAGS += -mconsole
|
||||
endif
|
||||
|
||||
else ifeq ($(TARGET_RPI),1)
|
||||
# Linux / Other builds below
|
||||
LDFLAGS := $(OPT_FLAGS) -lm -lGLESv2 `$(SDLCONFIG) --libs` -no-pie
|
||||
LDFLAGS := $(OPT_FLAGS) -lm $(BACKEND_LDFLAGS) -no-pie
|
||||
|
||||
else ifeq ($(OSX_BUILD),1)
|
||||
LDFLAGS := -lm $(BACKEND_LDFLAGS) -no-pie -lpthread
|
||||
|
||||
else
|
||||
ifeq ($(OSX_BUILD),1)
|
||||
LDFLAGS := -lm -framework OpenGL `$(SDLCONFIG) --libs` -no-pie -lpthread `pkg-config --libs libusb-1.0 glfw3 glew`
|
||||
else
|
||||
LDFLAGS := $(BITS) -march=$(TARGET_ARCH) -lm -lGL `$(SDLCONFIG) --libs` -no-pie -lpthread
|
||||
LDFLAGS := $(BITS) -march=$(TARGET_ARCH) -lm $(BACKEND_LDFLAGS) -no-pie -lpthread
|
||||
ifeq ($(DISCORDRPC),1)
|
||||
LDFLAGS += -ldl -Wl,-rpath .
|
||||
endif
|
||||
endif
|
||||
|
||||
endif # End of LDFLAGS
|
||||
|
||||
# Prevent a crash with -sopt
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#define TEXT_OPT_DOUBLE _("DOUBLE")
|
||||
#define TEXT_RESET_WINDOW _("RESET WINDOW")
|
||||
#define TEXT_OPT_HUD _("HUD")
|
||||
#define TEXT_OPT_THREEPOINT _("THREE POINT")
|
||||
|
||||
#define TEXT_BIND_A _("A BUTTON")
|
||||
#define TEXT_BIND_B _("B BUTTON")
|
||||
|
@ -109,6 +110,7 @@
|
|||
#define TEXT_OPT_DOUBLE _("Double")
|
||||
#define TEXT_RESET_WINDOW _("Reset Window")
|
||||
#define TEXT_OPT_HUD _("HUD")
|
||||
#define TEXT_OPT_THREEPOINT _("Three-point")
|
||||
|
||||
#define TEXT_BIND_A _("A Button")
|
||||
#define TEXT_BIND_B _("B Button")
|
||||
|
|
|
@ -80,6 +80,7 @@ static const u8 optsVideoStr[][32] = {
|
|||
{ TEXT_OPT_VSYNC },
|
||||
{ TEXT_OPT_DOUBLE },
|
||||
{ TEXT_OPT_HUD },
|
||||
{ TEXT_OPT_THREEPOINT },
|
||||
};
|
||||
|
||||
static const u8 optsAudioStr[][32] = {
|
||||
|
@ -122,6 +123,7 @@ static const u8 bindStr[][32] = {
|
|||
static const u8 *filterChoices[] = {
|
||||
optsVideoStr[2],
|
||||
optsVideoStr[3],
|
||||
optsVideoStr[8],
|
||||
};
|
||||
|
||||
static const u8 *vsyncChoices[] = {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#ifdef AAPI_SDL2
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
#include "audio_api.h"
|
||||
|
@ -58,3 +60,5 @@ struct AudioAPI audio_sdl = {
|
|||
audio_sdl_play,
|
||||
audio_sdl_shutdown
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef AUDIO_SDL_H
|
||||
#define AUDIO_SDL_H
|
||||
|
||||
#include "audio_api.h"
|
||||
|
||||
extern struct AudioAPI audio_sdl;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#if USE_SDL == 2
|
||||
#ifdef WAPI_SDL2
|
||||
# include <SDL2/SDL.h>
|
||||
# define WINDOWPOS_CENTERED SDL_WINDOWPOS_CENTERED
|
||||
#else
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#ifdef CAPI_SDL2
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
@ -296,3 +298,5 @@ struct ControllerAPI controller_sdl = {
|
|||
controller_sdl_bind,
|
||||
controller_sdl_shutdown
|
||||
};
|
||||
|
||||
#endif // CAPI_SDL2
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,10 @@
|
|||
#ifndef GFX_DIRECT3D11_H
|
||||
#define GFX_DIRECT3D11_H
|
||||
|
||||
#include "gfx_window_manager_api.h"
|
||||
#include "gfx_rendering_api.h"
|
||||
|
||||
extern struct GfxWindowManagerAPI gfx_dxgi;
|
||||
extern struct GfxRenderingAPI gfx_d3d11_api;
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,10 @@
|
|||
#ifndef GFX_DIRECT3D12_H
|
||||
#define GFX_DIRECT3D12_H
|
||||
|
||||
#include "gfx_window_manager_api.h"
|
||||
#include "gfx_rendering_api.h"
|
||||
|
||||
extern struct GfxWindowManagerAPI gfx_dxgi;
|
||||
extern struct GfxRenderingAPI gfx_d3d12_api;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,143 @@
|
|||
#if (defined(RAPI_D3D11) || defined(RAPI_D3D12)) && (defined(_WIN32) || defined(_WIN64))
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
extern "C" {
|
||||
#include "../platform.h"
|
||||
}
|
||||
|
||||
#include "gfx_direct3d_common.h"
|
||||
#include "gfx_cc.h"
|
||||
|
||||
void ThrowIfFailed(HRESULT res) {
|
||||
if (FAILED(res))
|
||||
sys_fatal("error while initializing D3D:\nerror code 0x%08X", res);
|
||||
}
|
||||
|
||||
void ThrowIfFailed(HRESULT res, HWND h_wnd, const char *message) {
|
||||
if (FAILED(res))
|
||||
sys_fatal("%s\nerror code 0x%08X", message, res);
|
||||
}
|
||||
|
||||
void get_cc_features(uint32_t shader_id, CCFeatures *cc_features) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
cc_features->c[0][i] = (shader_id >> (i * 3)) & 7;
|
||||
cc_features->c[1][i] = (shader_id >> (12 + i * 3)) & 7;
|
||||
}
|
||||
|
||||
cc_features->opt_alpha = (shader_id & SHADER_OPT_ALPHA) != 0;
|
||||
cc_features->opt_fog = (shader_id & SHADER_OPT_FOG) != 0;
|
||||
cc_features->opt_texture_edge = (shader_id & SHADER_OPT_TEXTURE_EDGE) != 0;
|
||||
cc_features->opt_noise = (shader_id & SHADER_OPT_NOISE) != 0;
|
||||
|
||||
cc_features->used_textures[0] = false;
|
||||
cc_features->used_textures[1] = false;
|
||||
cc_features->num_inputs = 0;
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
if (cc_features->c[i][j] >= SHADER_INPUT_1 && cc_features->c[i][j] <= SHADER_INPUT_4) {
|
||||
if (cc_features->c[i][j] > cc_features->num_inputs) {
|
||||
cc_features->num_inputs = cc_features->c[i][j];
|
||||
}
|
||||
}
|
||||
if (cc_features->c[i][j] == SHADER_TEXEL0 || cc_features->c[i][j] == SHADER_TEXEL0A) {
|
||||
cc_features->used_textures[0] = true;
|
||||
}
|
||||
if (cc_features->c[i][j] == SHADER_TEXEL1) {
|
||||
cc_features->used_textures[1] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cc_features->do_single[0] = cc_features->c[0][2] == 0;
|
||||
cc_features->do_single[1] = cc_features->c[1][2] == 0;
|
||||
cc_features->do_multiply[0] = cc_features->c[0][1] == 0 && cc_features->c[0][3] == 0;
|
||||
cc_features->do_multiply[1] = cc_features->c[1][1] == 0 && cc_features->c[1][3] == 0;
|
||||
cc_features->do_mix[0] = cc_features->c[0][1] == cc_features->c[0][3];
|
||||
cc_features->do_mix[1] = cc_features->c[1][1] == cc_features->c[1][3];
|
||||
cc_features->color_alpha_same = (shader_id & 0xfff) == ((shader_id >> 12) & 0xfff);
|
||||
}
|
||||
|
||||
void append_str(char *buf, size_t *len, const char *str) {
|
||||
while (*str != '\0') buf[(*len)++] = *str++;
|
||||
}
|
||||
|
||||
void append_line(char *buf, size_t *len, const char *str) {
|
||||
while (*str != '\0') buf[(*len)++] = *str++;
|
||||
buf[(*len)++] = '\r';
|
||||
buf[(*len)++] = '\n';
|
||||
}
|
||||
|
||||
const char *shader_item_to_str(uint32_t item, bool with_alpha, bool only_alpha, bool inputs_have_alpha, bool hint_single_element) {
|
||||
if (!only_alpha) {
|
||||
switch (item) {
|
||||
default:
|
||||
case SHADER_0:
|
||||
return with_alpha ? "float4(0.0, 0.0, 0.0, 0.0)" : "float3(0.0, 0.0, 0.0)";
|
||||
case SHADER_INPUT_1:
|
||||
return with_alpha || !inputs_have_alpha ? "input.input1" : "input.input1.rgb";
|
||||
case SHADER_INPUT_2:
|
||||
return with_alpha || !inputs_have_alpha ? "input.input2" : "input.input2.rgb";
|
||||
case SHADER_INPUT_3:
|
||||
return with_alpha || !inputs_have_alpha ? "input.input3" : "input.input3.rgb";
|
||||
case SHADER_INPUT_4:
|
||||
return with_alpha || !inputs_have_alpha ? "input.input4" : "input.input4.rgb";
|
||||
case SHADER_TEXEL0:
|
||||
return with_alpha ? "texVal0" : "texVal0.rgb";
|
||||
case SHADER_TEXEL0A:
|
||||
return hint_single_element ? "texVal0.a" : (with_alpha ? "float4(texVal0.a, texVal0.a, texVal0.a, texVal0.a)" : "float3(texVal0.a, texVal0.a, texVal0.a)");
|
||||
case SHADER_TEXEL1:
|
||||
return with_alpha ? "texVal1" : "texVal1.rgb";
|
||||
}
|
||||
} else {
|
||||
switch (item) {
|
||||
default:
|
||||
case SHADER_0:
|
||||
return "0.0";
|
||||
case SHADER_INPUT_1:
|
||||
return "input.input1.a";
|
||||
case SHADER_INPUT_2:
|
||||
return "input.input2.a";
|
||||
case SHADER_INPUT_3:
|
||||
return "input.input3.a";
|
||||
case SHADER_INPUT_4:
|
||||
return "input.input4.a";
|
||||
case SHADER_TEXEL0:
|
||||
return "texVal0.a";
|
||||
case SHADER_TEXEL0A:
|
||||
return "texVal0.a";
|
||||
case SHADER_TEXEL1:
|
||||
return "texVal1.a";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void append_formula(char *buf, size_t *len, uint8_t c[2][4], bool do_single, bool do_multiply, bool do_mix, bool with_alpha, bool only_alpha, bool opt_alpha) {
|
||||
if (do_single) {
|
||||
append_str(buf, len, shader_item_to_str(c[only_alpha][3], with_alpha, only_alpha, opt_alpha, false));
|
||||
} else if (do_multiply) {
|
||||
append_str(buf, len, shader_item_to_str(c[only_alpha][0], with_alpha, only_alpha, opt_alpha, false));
|
||||
append_str(buf, len, " * ");
|
||||
append_str(buf, len, shader_item_to_str(c[only_alpha][2], with_alpha, only_alpha, opt_alpha, true));
|
||||
} else if (do_mix) {
|
||||
append_str(buf, len, "lerp(");
|
||||
append_str(buf, len, shader_item_to_str(c[only_alpha][1], with_alpha, only_alpha, opt_alpha, false));
|
||||
append_str(buf, len, ", ");
|
||||
append_str(buf, len, shader_item_to_str(c[only_alpha][0], with_alpha, only_alpha, opt_alpha, false));
|
||||
append_str(buf, len, ", ");
|
||||
append_str(buf, len, shader_item_to_str(c[only_alpha][2], with_alpha, only_alpha, opt_alpha, true));
|
||||
append_str(buf, len, ")");
|
||||
} else {
|
||||
append_str(buf, len, "(");
|
||||
append_str(buf, len, shader_item_to_str(c[only_alpha][0], with_alpha, only_alpha, opt_alpha, false));
|
||||
append_str(buf, len, " - ");
|
||||
append_str(buf, len, shader_item_to_str(c[only_alpha][1], with_alpha, only_alpha, opt_alpha, false));
|
||||
append_str(buf, len, ") * ");
|
||||
append_str(buf, len, shader_item_to_str(c[only_alpha][2], with_alpha, only_alpha, opt_alpha, true));
|
||||
append_str(buf, len, " + ");
|
||||
append_str(buf, len, shader_item_to_str(c[only_alpha][3], with_alpha, only_alpha, opt_alpha, false));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,33 @@
|
|||
#if defined(RAPI_D3D11) || defined(RAPI_D3D12)
|
||||
|
||||
#ifndef GFX_DIRECT3D_COMMON_H
|
||||
#define GFX_DIRECT3D_COMMON_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <windows.h>
|
||||
|
||||
struct CCFeatures {
|
||||
uint8_t c[2][4];
|
||||
bool opt_alpha;
|
||||
bool opt_fog;
|
||||
bool opt_texture_edge;
|
||||
bool opt_noise;
|
||||
bool used_textures[2];
|
||||
uint32_t num_inputs;
|
||||
bool do_single[2];
|
||||
bool do_multiply[2];
|
||||
bool do_mix[2];
|
||||
bool color_alpha_same;
|
||||
};
|
||||
|
||||
void ThrowIfFailed(HRESULT res);
|
||||
void ThrowIfFailed(HRESULT res, HWND h_wnd, const char *message);
|
||||
void get_cc_features(uint32_t shader_id, CCFeatures *shader_features);
|
||||
void append_str(char *buf, size_t *len, const char *str);
|
||||
void append_line(char *buf, size_t *len, const char *str);
|
||||
const char *shader_item_to_str(uint32_t item, bool with_alpha, bool only_alpha, bool inputs_have_alpha, bool hint_single_element);
|
||||
void append_formula(char *buf, size_t *len, uint8_t c[2][4], bool do_single, bool do_multiply, bool do_mix, bool with_alpha, bool only_alpha, bool opt_alpha);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef LEGACY_GL
|
||||
#ifdef RAPI_GL
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
@ -29,9 +29,12 @@
|
|||
#endif
|
||||
|
||||
#include "../platform.h"
|
||||
#include "../configfile.h"
|
||||
#include "gfx_cc.h"
|
||||
#include "gfx_rendering_api.h"
|
||||
|
||||
#define TEX_CACHE_STEP 512
|
||||
|
||||
struct ShaderProgram {
|
||||
uint32_t shader_id;
|
||||
GLuint opengl_program_id;
|
||||
|
@ -39,17 +42,30 @@ struct ShaderProgram {
|
|||
bool used_textures[2];
|
||||
uint8_t num_floats;
|
||||
GLint attrib_locations[7];
|
||||
GLint uniform_locations[6];
|
||||
uint8_t attrib_sizes[7];
|
||||
uint8_t num_attribs;
|
||||
bool used_noise;
|
||||
GLint frame_count_location;
|
||||
GLint window_height_location;
|
||||
};
|
||||
|
||||
struct GLTexture {
|
||||
GLuint gltex;
|
||||
GLfloat size[2];
|
||||
bool filter;
|
||||
};
|
||||
|
||||
static struct ShaderProgram shader_program_pool[64];
|
||||
static uint8_t shader_program_pool_size;
|
||||
static GLuint opengl_vbo;
|
||||
|
||||
static int tex_cache_size = 0;
|
||||
static int num_textures = 0;
|
||||
static struct GLTexture *tex_cache = NULL;
|
||||
|
||||
static struct ShaderProgram *opengl_prg = NULL;
|
||||
static struct GLTexture *opengl_tex[2];
|
||||
static int opengl_curtex = 0;
|
||||
|
||||
static uint32_t frame_count;
|
||||
static uint32_t current_height;
|
||||
|
||||
|
@ -68,25 +84,38 @@ static void gfx_opengl_vertex_array_set_attribs(struct ShaderProgram *prg) {
|
|||
}
|
||||
}
|
||||
|
||||
static void gfx_opengl_set_uniforms(struct ShaderProgram *prg) {
|
||||
static inline void gfx_opengl_set_shader_uniforms(struct ShaderProgram *prg) {
|
||||
if (prg->used_noise) {
|
||||
glUniform1i(prg->frame_count_location, frame_count);
|
||||
glUniform1i(prg->window_height_location, current_height);
|
||||
glUniform1i(prg->uniform_locations[4], frame_count);
|
||||
glUniform1i(prg->uniform_locations[5], current_height);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void gfx_opengl_set_texture_uniforms(struct ShaderProgram *prg, const int tile) {
|
||||
if (prg->used_textures[tile] && opengl_tex[tile]) {
|
||||
glUniform2f(prg->uniform_locations[tile*2 + 0], opengl_tex[tile]->size[0], opengl_tex[tile]->size[1]);
|
||||
glUniform1i(prg->uniform_locations[tile*2 + 1], opengl_tex[tile]->filter);
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_opengl_unload_shader(struct ShaderProgram *old_prg) {
|
||||
if (old_prg != NULL) {
|
||||
for (int i = 0; i < old_prg->num_attribs; i++) {
|
||||
for (int i = 0; i < old_prg->num_attribs; i++)
|
||||
glDisableVertexAttribArray(old_prg->attrib_locations[i]);
|
||||
}
|
||||
if (old_prg == opengl_prg)
|
||||
opengl_prg = NULL;
|
||||
} else {
|
||||
opengl_prg = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_opengl_load_shader(struct ShaderProgram *new_prg) {
|
||||
opengl_prg = new_prg;
|
||||
glUseProgram(new_prg->opengl_program_id);
|
||||
gfx_opengl_vertex_array_set_attribs(new_prg);
|
||||
gfx_opengl_set_uniforms(new_prg);
|
||||
gfx_opengl_set_shader_uniforms(new_prg);
|
||||
gfx_opengl_set_texture_uniforms(new_prg, 0);
|
||||
gfx_opengl_set_texture_uniforms(new_prg, 1);
|
||||
}
|
||||
|
||||
static void append_str(char *buf, size_t *len, const char *str) {
|
||||
|
@ -206,7 +235,7 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(uint32_t shad
|
|||
bool color_alpha_same = (shader_id & 0xfff) == ((shader_id >> 12) & 0xfff);
|
||||
|
||||
char vs_buf[1024];
|
||||
char fs_buf[1024];
|
||||
char fs_buf[2048];
|
||||
size_t vs_len = 0;
|
||||
size_t fs_len = 0;
|
||||
size_t num_floats = 4;
|
||||
|
@ -265,9 +294,41 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(uint32_t shad
|
|||
}
|
||||
if (used_textures[0]) {
|
||||
append_line(fs_buf, &fs_len, "uniform sampler2D uTex0;");
|
||||
append_line(fs_buf, &fs_len, "uniform vec2 uTex0Size;");
|
||||
append_line(fs_buf, &fs_len, "uniform bool uTex0Filter;");
|
||||
}
|
||||
if (used_textures[1]) {
|
||||
append_line(fs_buf, &fs_len, "uniform sampler2D uTex1;");
|
||||
append_line(fs_buf, &fs_len, "uniform vec2 uTex1Size;");
|
||||
append_line(fs_buf, &fs_len, "uniform bool uTex1Filter;");
|
||||
}
|
||||
|
||||
// 3 point texture filtering
|
||||
// Original author: ArthurCarvalho
|
||||
// Slightly modified GLSL implementation by twinaphex, mupen64plus-libretro project.
|
||||
|
||||
if (used_textures[0] || used_textures[1]) {
|
||||
if (configFiltering == 2) {
|
||||
append_line(fs_buf, &fs_len, "#define TEX_OFFSET(off) texture2D(tex, texCoord - (off)/texSize)");
|
||||
append_line(fs_buf, &fs_len, "lowp vec4 filter3point(in sampler2D tex, in mediump vec2 texCoord, in mediump vec2 texSize) {");
|
||||
append_line(fs_buf, &fs_len, " mediump vec2 offset = fract(texCoord*texSize - vec2(0.5));");
|
||||
append_line(fs_buf, &fs_len, " offset -= step(1.0, offset.x + offset.y);");
|
||||
append_line(fs_buf, &fs_len, " lowp vec4 c0 = TEX_OFFSET(offset);");
|
||||
append_line(fs_buf, &fs_len, " lowp vec4 c1 = TEX_OFFSET(vec2(offset.x - sign(offset.x), offset.y));");
|
||||
append_line(fs_buf, &fs_len, " lowp vec4 c2 = TEX_OFFSET(vec2(offset.x, offset.y - sign(offset.y)));");
|
||||
append_line(fs_buf, &fs_len, " return c0 + abs(offset.x)*(c1-c0) + abs(offset.y)*(c2-c0);");
|
||||
append_line(fs_buf, &fs_len, "}");
|
||||
append_line(fs_buf, &fs_len, "lowp vec4 sampleTex(in sampler2D tex, in mediump vec2 uv, in mediump vec2 texSize, in bool filter) {");
|
||||
append_line(fs_buf, &fs_len, "if (filter)");
|
||||
append_line(fs_buf, &fs_len, "return filter3point(tex, uv, texSize);");
|
||||
append_line(fs_buf, &fs_len, "else");
|
||||
append_line(fs_buf, &fs_len, "return texture2D(tex, uv);");
|
||||
append_line(fs_buf, &fs_len, "}");
|
||||
} else {
|
||||
append_line(fs_buf, &fs_len, "lowp vec4 sampleTex(in sampler2D tex, in mediump vec2 uv, in mediump vec2 texSize, in bool filter) {");
|
||||
append_line(fs_buf, &fs_len, "return texture2D(tex, uv);");
|
||||
append_line(fs_buf, &fs_len, "}");
|
||||
}
|
||||
}
|
||||
|
||||
if (opt_alpha && opt_noise) {
|
||||
|
@ -283,10 +344,10 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(uint32_t shad
|
|||
append_line(fs_buf, &fs_len, "void main() {");
|
||||
|
||||
if (used_textures[0]) {
|
||||
append_line(fs_buf, &fs_len, "vec4 texVal0 = texture2D(uTex0, vTexCoord);");
|
||||
append_line(fs_buf, &fs_len, "vec4 texVal0 = sampleTex(uTex0, vTexCoord, uTex0Size, uTex0Filter);");
|
||||
}
|
||||
if (used_textures[1]) {
|
||||
append_line(fs_buf, &fs_len, "vec4 texVal1 = texture2D(uTex1, vTexCoord);");
|
||||
append_line(fs_buf, &fs_len, "vec4 texVal1 = sampleTex(uTex1, vTexCoord, uTex1Size, uTex1Filter);");
|
||||
}
|
||||
|
||||
append_str(fs_buf, &fs_len, opt_alpha ? "vec4 texel = " : "vec3 texel = ");
|
||||
|
@ -409,16 +470,20 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(uint32_t shad
|
|||
|
||||
if (used_textures[0]) {
|
||||
GLint sampler_location = glGetUniformLocation(shader_program, "uTex0");
|
||||
prg->uniform_locations[0] = glGetUniformLocation(shader_program, "uTex0Size");
|
||||
prg->uniform_locations[1] = glGetUniformLocation(shader_program, "uTex0Filter");
|
||||
glUniform1i(sampler_location, 0);
|
||||
}
|
||||
if (used_textures[1]) {
|
||||
GLint sampler_location = glGetUniformLocation(shader_program, "uTex1");
|
||||
prg->uniform_locations[2] = glGetUniformLocation(shader_program, "uTex1Size");
|
||||
prg->uniform_locations[3] = glGetUniformLocation(shader_program, "uTex1Filter");
|
||||
glUniform1i(sampler_location, 1);
|
||||
}
|
||||
|
||||
if (opt_alpha && opt_noise) {
|
||||
prg->frame_count_location = glGetUniformLocation(shader_program, "frame_count");
|
||||
prg->window_height_location = glGetUniformLocation(shader_program, "window_height");
|
||||
prg->uniform_locations[4] = glGetUniformLocation(shader_program, "frame_count");
|
||||
prg->uniform_locations[5] = glGetUniformLocation(shader_program, "window_height");
|
||||
prg->used_noise = true;
|
||||
} else {
|
||||
prg->used_noise = false;
|
||||
|
@ -443,18 +508,30 @@ static void gfx_opengl_shader_get_info(struct ShaderProgram *prg, uint8_t *num_i
|
|||
}
|
||||
|
||||
static GLuint gfx_opengl_new_texture(void) {
|
||||
GLuint ret;
|
||||
glGenTextures(1, &ret);
|
||||
return ret;
|
||||
if (num_textures >= tex_cache_size) {
|
||||
tex_cache_size += TEX_CACHE_STEP;
|
||||
tex_cache = realloc(tex_cache, sizeof(struct GLTexture) * tex_cache_size);
|
||||
if (!tex_cache) sys_fatal("out of memory allocating texture cache");
|
||||
// invalidate these because they might be pointing to garbage now
|
||||
opengl_tex[0] = NULL;
|
||||
opengl_tex[1] = NULL;
|
||||
}
|
||||
glGenTextures(1, &tex_cache[num_textures].gltex);
|
||||
return num_textures++;
|
||||
}
|
||||
|
||||
static void gfx_opengl_select_texture(int tile, GLuint texture_id) {
|
||||
opengl_tex[tile] = tex_cache + texture_id;
|
||||
opengl_curtex = tile;
|
||||
glActiveTexture(GL_TEXTURE0 + tile);
|
||||
glBindTexture(GL_TEXTURE_2D, texture_id);
|
||||
glBindTexture(GL_TEXTURE_2D, opengl_tex[tile]->gltex);
|
||||
gfx_opengl_set_texture_uniforms(opengl_prg, tile);
|
||||
}
|
||||
|
||||
static void gfx_opengl_upload_texture(uint8_t *rgba32_buf, int width, int height) {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgba32_buf);
|
||||
opengl_tex[opengl_curtex]->size[0] = width;
|
||||
opengl_tex[opengl_curtex]->size[1] = height;
|
||||
}
|
||||
|
||||
static uint32_t gfx_cm_to_opengl(uint32_t val) {
|
||||
|
@ -471,6 +548,11 @@ static void gfx_opengl_set_sampler_parameters(int tile, bool linear_filter, uint
|
|||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, gfx_cm_to_opengl(cms));
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gfx_cm_to_opengl(cmt));
|
||||
opengl_curtex = tile;
|
||||
if (opengl_tex[tile]) {
|
||||
opengl_tex[tile]->filter = linear_filter;
|
||||
gfx_opengl_set_texture_uniforms(opengl_prg, tile);
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_opengl_set_depth_test(bool depth_test) {
|
||||
|
@ -540,6 +622,10 @@ static void gfx_opengl_init(void) {
|
|||
sys_fatal("could not init GLEW:\n%s", glewGetErrorString(err));
|
||||
#endif
|
||||
|
||||
tex_cache_size = TEX_CACHE_STEP;
|
||||
tex_cache = calloc(tex_cache_size, sizeof(struct GLTexture));
|
||||
if (!tex_cache) sys_fatal("out of memory allocating texture cache");
|
||||
|
||||
// check GL version
|
||||
int vmajor, vminor;
|
||||
bool is_es = false;
|
||||
|
@ -591,4 +677,4 @@ struct GfxRenderingAPI gfx_opengl_api = {
|
|||
gfx_opengl_shutdown
|
||||
};
|
||||
|
||||
#endif // !LEGACY_GL
|
||||
#endif // RAPI_GL
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#ifdef LEGACY_GL
|
||||
#ifdef RAPI_GL_LEGACY
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
@ -603,4 +603,4 @@ struct GfxRenderingAPI gfx_opengl_api = {
|
|||
gfx_opengl_shutdown
|
||||
};
|
||||
|
||||
#endif // LEGACY_GL
|
||||
#endif // RAPI_GL_LEGACY
|
||||
|
|
|
@ -1719,9 +1719,20 @@ void gfx_get_dimensions(uint32_t *width, uint32_t *height) {
|
|||
}
|
||||
|
||||
void gfx_init(struct GfxWindowManagerAPI *wapi, struct GfxRenderingAPI *rapi) {
|
||||
char window_title[96] =
|
||||
#ifndef USE_GLES
|
||||
"Super Mario 64 PC port (OpenGL)"
|
||||
#else
|
||||
"Super Mario 64 PC port (OpenGL_ES2)"
|
||||
#endif
|
||||
#ifdef NIGHTLY
|
||||
" nightly " GIT_HASH
|
||||
#endif
|
||||
;
|
||||
|
||||
gfx_wapi = wapi;
|
||||
gfx_rapi = rapi;
|
||||
gfx_wapi->init();
|
||||
gfx_wapi->init(window_title);
|
||||
gfx_rapi->init();
|
||||
|
||||
// Used in the 120 star TAS
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#ifdef WAPI_SDL2
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#define FOR_WINDOWS 1
|
||||
#else
|
||||
|
@ -50,8 +52,11 @@ static SDL_GLContext ctx = NULL;
|
|||
static int inverted_scancode_table[512];
|
||||
static Uint32 frame_start = 0;
|
||||
|
||||
const SDL_Scancode windows_scancode_table[] =
|
||||
{
|
||||
static kb_callback_t kb_key_down = NULL;
|
||||
static kb_callback_t kb_key_up = NULL;
|
||||
static void (*kb_all_keys_up)(void) = NULL;
|
||||
|
||||
const SDL_Scancode windows_scancode_table[] = {
|
||||
/* 0 1 2 3 4 5 6 7 */
|
||||
/* 8 9 A B C D E F */
|
||||
SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_ESCAPE, SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_3, SDL_SCANCODE_4, SDL_SCANCODE_5, SDL_SCANCODE_6, /* 0 */
|
||||
|
@ -140,7 +145,7 @@ static void gfx_sdl_reset_dimension_and_pos() {
|
|||
SDL_GL_SetSwapInterval(configWindow.vsync); // in case vsync changed
|
||||
}
|
||||
|
||||
static void gfx_sdl_init(void) {
|
||||
static void gfx_sdl_init(const char *window_title) {
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||
|
@ -160,17 +165,6 @@ static void gfx_sdl_init(void) {
|
|||
else if (gCLIOpts.FullScreen == 2)
|
||||
configWindow.fullscreen = false;
|
||||
|
||||
char window_title[96] =
|
||||
#ifndef USE_GLES
|
||||
"Super Mario 64 PC port (OpenGL)";
|
||||
#else
|
||||
"Super Mario 64 PC port (OpenGL_ES2)";
|
||||
#endif
|
||||
|
||||
#ifdef NIGHTLY
|
||||
strcat(window_title, " nightly " GIT_HASH);
|
||||
#endif
|
||||
|
||||
wnd = SDL_CreateWindow(
|
||||
window_title,
|
||||
configWindow.x, configWindow.y, configWindow.w, configWindow.h,
|
||||
|
@ -223,7 +217,8 @@ static int translate_scancode(int scancode) {
|
|||
}
|
||||
|
||||
static void gfx_sdl_onkeydown(int scancode) {
|
||||
keyboard_on_key_down(translate_scancode(scancode));
|
||||
if (kb_key_down)
|
||||
kb_key_down(translate_scancode(scancode));
|
||||
|
||||
const Uint8 *state = SDL_GetKeyboardState(NULL);
|
||||
|
||||
|
@ -234,7 +229,8 @@ static void gfx_sdl_onkeydown(int scancode) {
|
|||
}
|
||||
|
||||
static void gfx_sdl_onkeyup(int scancode) {
|
||||
keyboard_on_key_up(translate_scancode(scancode));
|
||||
if (kb_key_up)
|
||||
kb_key_up(translate_scancode(scancode));
|
||||
}
|
||||
|
||||
static void gfx_sdl_handle_events(void) {
|
||||
|
@ -277,6 +273,12 @@ static void gfx_sdl_handle_events(void) {
|
|||
gfx_sdl_set_fullscreen();
|
||||
}
|
||||
|
||||
static void gfx_sdl_set_keyboard_callbacks(kb_callback_t on_key_down, kb_callback_t on_key_up, void (*on_all_keys_up)(void)) {
|
||||
kb_key_down = on_key_down;
|
||||
kb_key_up = on_key_up;
|
||||
kb_all_keys_up = on_all_keys_up;
|
||||
}
|
||||
|
||||
static bool gfx_sdl_start_frame(void) {
|
||||
frame_start = SDL_GetTicks();
|
||||
return true;
|
||||
|
@ -304,6 +306,7 @@ static void gfx_sdl_shutdown(void) {
|
|||
|
||||
struct GfxWindowManagerAPI gfx_sdl = {
|
||||
gfx_sdl_init,
|
||||
gfx_sdl_set_keyboard_callbacks,
|
||||
gfx_sdl_main_loop,
|
||||
gfx_sdl_get_dimensions,
|
||||
gfx_sdl_handle_events,
|
||||
|
@ -313,3 +316,5 @@ struct GfxWindowManagerAPI gfx_sdl = {
|
|||
gfx_sdl_get_time,
|
||||
gfx_sdl_shutdown
|
||||
};
|
||||
|
||||
#endif // BACKEND_WM
|
||||
|
|
|
@ -4,8 +4,11 @@
|
|||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef bool (*kb_callback_t)(int code);
|
||||
|
||||
struct GfxWindowManagerAPI {
|
||||
void (*init)(void);
|
||||
void (*init)(const char *window_title);
|
||||
void (*set_keyboard_callbacks)(kb_callback_t on_key_down, kb_callback_t on_key_up, void (*on_all_keys_up)(void));
|
||||
void (*main_loop)(void (*run_one_game_iter)(void));
|
||||
void (*get_dimensions)(uint32_t *width, uint32_t *height);
|
||||
void (*handle_events)(void);
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
|
||||
#include "gfx/gfx_pc.h"
|
||||
#include "gfx/gfx_opengl.h"
|
||||
#include "gfx/gfx_direct3d11.h"
|
||||
#include "gfx/gfx_direct3d12.h"
|
||||
#include "gfx/gfx_sdl.h"
|
||||
|
||||
#include "audio/audio_api.h"
|
||||
|
@ -23,6 +25,7 @@
|
|||
#include "cliopts.h"
|
||||
#include "configfile.h"
|
||||
#include "controller/controller_api.h"
|
||||
#include "controller/controller_keyboard.h"
|
||||
#include "fs/fs.h"
|
||||
|
||||
#include "game/game_init.h"
|
||||
|
@ -162,9 +165,26 @@ void main_func(void) {
|
|||
|
||||
configfile_load(configfile_name());
|
||||
|
||||
#if defined(WAPI_SDL1) || defined(WAPI_SDL2)
|
||||
wm_api = &gfx_sdl;
|
||||
#elif defined(WAPI_DXGI)
|
||||
wm_api = &gfx_dxgi;
|
||||
#else
|
||||
#error No window API!
|
||||
#endif
|
||||
|
||||
#if defined(RAPI_D3D11)
|
||||
rendering_api = &gfx_d3d11_api;
|
||||
#elif defined(RAPI_D3D12)
|
||||
rendering_api = &gfx_d3d12_api;
|
||||
#elif defined(RAPI_GL) || defined(RAPI_GL_LEGACY)
|
||||
rendering_api = &gfx_opengl_api;
|
||||
#else
|
||||
#error No rendering API!
|
||||
#endif
|
||||
|
||||
gfx_init(wm_api, rendering_api);
|
||||
wm_api->set_keyboard_callbacks(keyboard_on_key_down, keyboard_on_key_up, keyboard_on_all_keys_up);
|
||||
|
||||
if (audio_api == NULL && audio_sdl.init())
|
||||
audio_api = &audio_sdl;
|
||||
|
@ -193,6 +213,7 @@ void main_func(void) {
|
|||
emscripten_set_main_loop(em_main_loop, 0, 0);
|
||||
request_anim_frame(on_anim_frame);
|
||||
#else
|
||||
while (true)
|
||||
wm_api->main_loop(produce_one_frame);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ void sys_fatal(const char *fmt, ...) {
|
|||
sys_fatal_impl(msg);
|
||||
}
|
||||
|
||||
#if USE_SDL
|
||||
#ifdef HAVE_SDL2
|
||||
|
||||
// we can just ask SDL for most of this shit if we have it
|
||||
#include <SDL2/SDL.h>
|
||||
|
|
Loading…
Reference in New Issue