mirror of https://github.com/sm64pc/sm64pc.git
Merge remote-tracking branch 'upstream/nightly' into textsaves_fix
This commit is contained in:
commit
84b970cfe1
|
@ -31,6 +31,8 @@ typedef double f64;
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#if defined(__MINGW32__)
|
#if defined(__MINGW32__)
|
||||||
#include <_mingw.h>
|
#include <_mingw.h>
|
||||||
#if !defined(__MINGW64_VERSION_MAJOR)
|
#if !defined(__MINGW64_VERSION_MAJOR)
|
||||||
|
@ -39,4 +41,5 @@ typedef long ssize_t;
|
||||||
typedef ptrdiff_t ssize_t;
|
typedef ptrdiff_t ssize_t;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
#endif // _ULTRA64_TYPES_H_
|
||||||
|
|
|
@ -74,9 +74,9 @@ struct newcam_hardpos newcam_fixedcam[] =
|
||||||
#endif // noaccel
|
#endif // noaccel
|
||||||
|
|
||||||
s16 newcam_yaw; //Z axis rotation
|
s16 newcam_yaw; //Z axis rotation
|
||||||
s8 newcam_yaw_acc;
|
f32 newcam_yaw_acc;
|
||||||
s16 newcam_tilt = 1500; //Y axis rotation
|
s16 newcam_tilt = 1500; //Y axis rotation
|
||||||
s8 newcam_tilt_acc;
|
f32 newcam_tilt_acc;
|
||||||
u16 newcam_distance = 750; //The distance the camera stays from the player
|
u16 newcam_distance = 750; //The distance the camera stays from the player
|
||||||
u16 newcam_distance_target = 750; //The distance the player camera tries to reach.
|
u16 newcam_distance_target = 750; //The distance the player camera tries to reach.
|
||||||
f32 newcam_pos_target[3]; //The position the camera is basing calculations off. *usually* Mario.
|
f32 newcam_pos_target[3]; //The position the camera is basing calculations off. *usually* Mario.
|
||||||
|
@ -187,14 +187,20 @@ void newcam_diagnostics(void)
|
||||||
print_text_fmt_int(32,32,"DISTANCE %d",newcam_distance);
|
print_text_fmt_int(32,32,"DISTANCE %d",newcam_distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
static s16 newcam_adjust_value(s16 var, s16 val)
|
static s16 newcam_adjust_value(s16 var, s16 val, s8 max)
|
||||||
{
|
{
|
||||||
var += val;
|
if (val > 0)
|
||||||
if (var > 100)
|
{
|
||||||
var = 100;
|
var += val;
|
||||||
if (var < -100)
|
if (var > max)
|
||||||
var = -100;
|
var = max;
|
||||||
|
}
|
||||||
|
else if (val < 0)
|
||||||
|
{
|
||||||
|
var += val;
|
||||||
|
if (var < max)
|
||||||
|
var = max;
|
||||||
|
}
|
||||||
return var;
|
return var;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,6 +240,8 @@ static int ivrt(u8 axis)
|
||||||
|
|
||||||
static void newcam_rotate_button(void)
|
static void newcam_rotate_button(void)
|
||||||
{
|
{
|
||||||
|
f32 intendedXMag;
|
||||||
|
f32 intendedYMag;
|
||||||
if ((newcam_modeflags & NC_FLAG_8D || newcam_modeflags & NC_FLAG_4D) && newcam_modeflags & NC_FLAG_XTURN) //8 directional camera rotation input for buttons.
|
if ((newcam_modeflags & NC_FLAG_8D || newcam_modeflags & NC_FLAG_4D) && newcam_modeflags & NC_FLAG_XTURN) //8 directional camera rotation input for buttons.
|
||||||
{
|
{
|
||||||
if ((gPlayer1Controller->buttonPressed & L_CBUTTONS) && newcam_analogue == 0)
|
if ((gPlayer1Controller->buttonPressed & L_CBUTTONS) && newcam_analogue == 0)
|
||||||
|
@ -264,27 +272,33 @@ static void newcam_rotate_button(void)
|
||||||
if (newcam_modeflags & NC_FLAG_XTURN)
|
if (newcam_modeflags & NC_FLAG_XTURN)
|
||||||
{
|
{
|
||||||
if ((gPlayer1Controller->buttonDown & L_CBUTTONS) && newcam_analogue == 0)
|
if ((gPlayer1Controller->buttonDown & L_CBUTTONS) && newcam_analogue == 0)
|
||||||
newcam_yaw_acc = newcam_adjust_value(newcam_yaw_acc,accel);
|
newcam_yaw_acc = newcam_adjust_value(newcam_yaw_acc,accel, 100);
|
||||||
else if ((gPlayer1Controller->buttonDown & R_CBUTTONS) && newcam_analogue == 0)
|
else if ((gPlayer1Controller->buttonDown & R_CBUTTONS) && newcam_analogue == 0)
|
||||||
newcam_yaw_acc = newcam_adjust_value(newcam_yaw_acc,-accel);
|
newcam_yaw_acc = newcam_adjust_value(newcam_yaw_acc,-accel, -100);
|
||||||
else
|
else
|
||||||
|
if (!newcam_analogue)
|
||||||
|
{
|
||||||
#ifdef noaccel
|
#ifdef noaccel
|
||||||
newcam_yaw_acc = 0;
|
newcam_yaw_acc = 0;
|
||||||
#else
|
#else
|
||||||
newcam_yaw_acc -= (newcam_yaw_acc*newcam_degrade);
|
newcam_yaw_acc -= (newcam_yaw_acc*newcam_degrade);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gPlayer1Controller->buttonDown & U_CBUTTONS && newcam_modeflags & NC_FLAG_YTURN && newcam_analogue == 0)
|
if (gPlayer1Controller->buttonDown & U_CBUTTONS && newcam_modeflags & NC_FLAG_YTURN && newcam_analogue == 0)
|
||||||
newcam_tilt_acc = newcam_adjust_value(newcam_tilt_acc,accel);
|
newcam_tilt_acc = newcam_adjust_value(newcam_tilt_acc,accel, 100);
|
||||||
else if (gPlayer1Controller->buttonDown & D_CBUTTONS && newcam_modeflags & NC_FLAG_YTURN && newcam_analogue == 0)
|
else if (gPlayer1Controller->buttonDown & D_CBUTTONS && newcam_modeflags & NC_FLAG_YTURN && newcam_analogue == 0)
|
||||||
newcam_tilt_acc = newcam_adjust_value(newcam_tilt_acc,-accel);
|
newcam_tilt_acc = newcam_adjust_value(newcam_tilt_acc,-accel, -100);
|
||||||
else
|
else
|
||||||
|
if (!newcam_analogue)
|
||||||
|
{
|
||||||
#ifdef noaccel
|
#ifdef noaccel
|
||||||
newcam_tilt_acc = 0;
|
newcam_tilt_acc = 0;
|
||||||
#else
|
#else
|
||||||
newcam_tilt_acc -= (newcam_tilt_acc*newcam_degrade);
|
newcam_tilt_acc -= (newcam_tilt_acc*newcam_degrade);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
newcam_framessincec[0] += 1;
|
newcam_framessincec[0] += 1;
|
||||||
newcam_framessincec[1] += 1;
|
newcam_framessincec[1] += 1;
|
||||||
|
@ -316,12 +330,14 @@ static void newcam_rotate_button(void)
|
||||||
|
|
||||||
if (newcam_analogue == 1) //There's not much point in keeping this behind a check, but it wouldn't hurt, just incase any 2player shenanigans ever happen, it makes it easy to disable.
|
if (newcam_analogue == 1) //There's not much point in keeping this behind a check, but it wouldn't hurt, just incase any 2player shenanigans ever happen, it makes it easy to disable.
|
||||||
{ //The joystick values cap at 80, so divide by 8 to get the same net result at maximum turn as the button
|
{ //The joystick values cap at 80, so divide by 8 to get the same net result at maximum turn as the button
|
||||||
|
intendedXMag = gPlayer2Controller->stickX*1.25;
|
||||||
|
intendedYMag = gPlayer2Controller->stickY*1.25;
|
||||||
if (ABS(gPlayer2Controller->stickX) > 20 && newcam_modeflags & NC_FLAG_XTURN)
|
if (ABS(gPlayer2Controller->stickX) > 20 && newcam_modeflags & NC_FLAG_XTURN)
|
||||||
{
|
{
|
||||||
if (newcam_modeflags & NC_FLAG_8D)
|
if (newcam_modeflags & NC_FLAG_8D)
|
||||||
{
|
{
|
||||||
if (newcam_cstick_down == 0)
|
if (newcam_cstick_down == 0)
|
||||||
{
|
{
|
||||||
newcam_cstick_down = 1;
|
newcam_cstick_down = 1;
|
||||||
newcam_centering = 1;
|
newcam_centering = 1;
|
||||||
#ifndef nosound
|
#ifndef nosound
|
||||||
|
@ -344,18 +360,24 @@ static void newcam_rotate_button(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
newcam_yaw_acc = newcam_adjust_value(newcam_yaw_acc,(-gPlayer2Controller->stickX/4));
|
{
|
||||||
|
newcam_yaw_acc = newcam_adjust_value(newcam_yaw_acc,-gPlayer2Controller->stickX/8, intendedXMag);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
if (newcam_analogue)
|
||||||
{
|
{
|
||||||
newcam_cstick_down = 0;
|
newcam_cstick_down = 0;
|
||||||
newcam_yaw_acc -= (newcam_yaw_acc*newcam_degrade);
|
newcam_yaw_acc -= (newcam_yaw_acc*newcam_degrade);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ABS(gPlayer2Controller->stickY) > 20 && newcam_modeflags & NC_FLAG_YTURN)
|
if (ABS(gPlayer2Controller->stickY) > 20 && newcam_modeflags & NC_FLAG_YTURN)
|
||||||
newcam_tilt_acc = newcam_adjust_value(newcam_tilt_acc,(-gPlayer2Controller->stickY/4));
|
newcam_tilt_acc = newcam_adjust_value(newcam_tilt_acc,-gPlayer2Controller->stickY/8, intendedYMag);
|
||||||
else
|
else
|
||||||
|
if (newcam_analogue)
|
||||||
|
{
|
||||||
newcam_tilt_acc -= (newcam_tilt_acc*newcam_degrade);
|
newcam_tilt_acc -= (newcam_tilt_acc*newcam_degrade);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newcam_mouse == 1)
|
if (newcam_mouse == 1)
|
||||||
|
@ -417,9 +439,9 @@ static void newcam_update_values(void)
|
||||||
{//For tilt, this just limits it so it doesn't go further than 90 degrees either way. 90 degrees is actually 16384, but can sometimes lead to issues, so I just leave it shy of 90.
|
{//For tilt, this just limits it so it doesn't go further than 90 degrees either way. 90 degrees is actually 16384, but can sometimes lead to issues, so I just leave it shy of 90.
|
||||||
u8 waterflag = 0;
|
u8 waterflag = 0;
|
||||||
if (newcam_modeflags & NC_FLAG_XTURN)
|
if (newcam_modeflags & NC_FLAG_XTURN)
|
||||||
newcam_yaw += (ivrt(0)*(newcam_yaw_acc*(newcam_sensitivityX/10)));
|
newcam_yaw += ((ivrt(0)*(newcam_yaw_acc*(newcam_sensitivityX/10))));
|
||||||
if (((newcam_tilt < 12000 && newcam_tilt_acc*ivrt(1) > 0) || (newcam_tilt > -12000 && newcam_tilt_acc*ivrt(1) < 0)) && newcam_modeflags & NC_FLAG_YTURN)
|
if (((newcam_tilt < 12000 && newcam_tilt_acc*ivrt(1) > 0) || (newcam_tilt > -12000 && newcam_tilt_acc*ivrt(1) < 0)) && newcam_modeflags & NC_FLAG_YTURN)
|
||||||
newcam_tilt += (ivrt(1)*(newcam_tilt_acc*(newcam_sensitivityY/10)));
|
newcam_tilt += ((ivrt(1)*(newcam_tilt_acc*(newcam_sensitivityY/10))));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (newcam_tilt > 12000)
|
if (newcam_tilt > 12000)
|
||||||
|
|
|
@ -3080,6 +3080,12 @@ void update_camera(struct Camera *c) {
|
||||||
sCButtonsPressed = find_c_buttons_pressed(sCButtonsPressed, gPlayer1Controller->buttonPressed,gPlayer1Controller->buttonDown);
|
sCButtonsPressed = find_c_buttons_pressed(sCButtonsPressed, gPlayer1Controller->buttonPressed,gPlayer1Controller->buttonDown);
|
||||||
#ifdef BETTERCAMERA
|
#ifdef BETTERCAMERA
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gMarioState->action == ACT_SHOT_FROM_CANNON && newcam_active)
|
||||||
|
{
|
||||||
|
gMarioState->area->camera->mode = CAMERA_MODE_NEWCAM;
|
||||||
|
gLakituState.mode = CAMERA_MODE_NEWCAM;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (c->cutscene != 0) {
|
if (c->cutscene != 0) {
|
||||||
|
|
|
@ -21,7 +21,12 @@ struct SpawnInfo;
|
||||||
/**
|
/**
|
||||||
* The maximum number of objects that can be loaded at once.
|
* The maximum number of objects that can be loaded at once.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef NODRAWINGDISTANCE
|
||||||
|
#define OBJECT_POOL_CAPACITY 960
|
||||||
|
#else
|
||||||
#define OBJECT_POOL_CAPACITY 240
|
#define OBJECT_POOL_CAPACITY 240
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Every object is categorized into an object list, which controls the order
|
* Every object is categorized into an object list, which controls the order
|
||||||
|
|
|
@ -493,6 +493,7 @@ ALIGNED8 static u8 gd_texture_sparkle_4[] = {
|
||||||
|
|
||||||
//! No reference to this texture. Two DL's uses the same previous texture
|
//! No reference to this texture. Two DL's uses the same previous texture
|
||||||
// instead of using this texture.
|
// instead of using this texture.
|
||||||
|
// Fixed via setting TEXTURE_FIX to 1.
|
||||||
ALIGNED8 static u8 gd_texture_sparkle_5[] = {
|
ALIGNED8 static u8 gd_texture_sparkle_5[] = {
|
||||||
#include "textures/intro_raw/sparkle_5.rgba16.inc.c"
|
#include "textures/intro_raw/sparkle_5.rgba16.inc.c"
|
||||||
};
|
};
|
||||||
|
@ -569,6 +570,7 @@ static Gfx gd_dl_red_sparkle_4[] = {
|
||||||
gsSPBranchList(gd_dl_sparkle),
|
gsSPBranchList(gd_dl_sparkle),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef TEXTURE_FIX
|
||||||
static Gfx gd_dl_red_sparkle_4_dup[] ={
|
static Gfx gd_dl_red_sparkle_4_dup[] ={
|
||||||
gsDPPipeSync(),
|
gsDPPipeSync(),
|
||||||
gsSPDisplayList(gd_dl_sparkle_red_color),
|
gsSPDisplayList(gd_dl_sparkle_red_color),
|
||||||
|
@ -576,6 +578,15 @@ static Gfx gd_dl_red_sparkle_4_dup[] ={
|
||||||
gsSPBranchList(gd_dl_sparkle),
|
gsSPBranchList(gd_dl_sparkle),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
static Gfx gd_dl_red_sparkle_5[] ={
|
||||||
|
gsDPPipeSync(),
|
||||||
|
gsSPDisplayList(gd_dl_sparkle_red_color),
|
||||||
|
gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, gd_texture_sparkle_5),
|
||||||
|
gsSPBranchList(gd_dl_sparkle),
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
static Gfx gd_dl_silver_sparkle_0[] = {
|
static Gfx gd_dl_silver_sparkle_0[] = {
|
||||||
gsDPPipeSync(),
|
gsDPPipeSync(),
|
||||||
gsSPDisplayList(gd_dl_sparkle_white_color),
|
gsSPDisplayList(gd_dl_sparkle_white_color),
|
||||||
|
@ -611,6 +622,7 @@ static Gfx gd_dl_silver_sparkle_4[] = {
|
||||||
gsSPBranchList(gd_dl_sparkle),
|
gsSPBranchList(gd_dl_sparkle),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef TEXTURE_FIX
|
||||||
static Gfx gd_dl_silver_sparkle_4_dup[] = {
|
static Gfx gd_dl_silver_sparkle_4_dup[] = {
|
||||||
gsDPPipeSync(),
|
gsDPPipeSync(),
|
||||||
gsSPDisplayList(gd_dl_sparkle_white_color),
|
gsSPDisplayList(gd_dl_sparkle_white_color),
|
||||||
|
@ -618,6 +630,15 @@ static Gfx gd_dl_silver_sparkle_4_dup[] = {
|
||||||
gsSPBranchList(gd_dl_sparkle),
|
gsSPBranchList(gd_dl_sparkle),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
static Gfx gd_dl_silver_sparkle_5[] = {
|
||||||
|
gsDPPipeSync(),
|
||||||
|
gsSPDisplayList(gd_dl_sparkle_white_color),
|
||||||
|
gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, gd_texture_sparkle_5),
|
||||||
|
gsSPBranchList(gd_dl_sparkle),
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
static Gfx *gd_red_sparkle_dl_array[] = {
|
static Gfx *gd_red_sparkle_dl_array[] = {
|
||||||
gd_dl_red_sparkle_4,
|
gd_dl_red_sparkle_4,
|
||||||
gd_dl_red_sparkle_4,
|
gd_dl_red_sparkle_4,
|
||||||
|
@ -629,8 +650,13 @@ static Gfx *gd_red_sparkle_dl_array[] = {
|
||||||
gd_dl_red_sparkle_1,
|
gd_dl_red_sparkle_1,
|
||||||
gd_dl_red_sparkle_0,
|
gd_dl_red_sparkle_0,
|
||||||
gd_dl_red_sparkle_0,
|
gd_dl_red_sparkle_0,
|
||||||
|
#ifndef TEXTURE_FIX
|
||||||
gd_dl_red_sparkle_4_dup,
|
gd_dl_red_sparkle_4_dup,
|
||||||
gd_dl_red_sparkle_4_dup,
|
gd_dl_red_sparkle_4_dup,
|
||||||
|
#else
|
||||||
|
gd_dl_red_sparkle_5,
|
||||||
|
gd_dl_red_sparkle_5,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static Gfx *gd_silver_sparkle_dl_array[] = {
|
static Gfx *gd_silver_sparkle_dl_array[] = {
|
||||||
|
@ -644,8 +670,13 @@ static Gfx *gd_silver_sparkle_dl_array[] = {
|
||||||
gd_dl_silver_sparkle_1,
|
gd_dl_silver_sparkle_1,
|
||||||
gd_dl_silver_sparkle_0,
|
gd_dl_silver_sparkle_0,
|
||||||
gd_dl_silver_sparkle_0,
|
gd_dl_silver_sparkle_0,
|
||||||
|
#ifndef TEXTURE_FIX
|
||||||
gd_dl_silver_sparkle_4_dup,
|
gd_dl_silver_sparkle_4_dup,
|
||||||
gd_dl_silver_sparkle_4_dup,
|
gd_dl_silver_sparkle_4_dup,
|
||||||
|
#else
|
||||||
|
gd_dl_silver_sparkle_5,
|
||||||
|
gd_dl_silver_sparkle_5,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static Gfx gd_texture3_dummy_aligner1[] = {
|
static Gfx gd_texture3_dummy_aligner1[] = {
|
||||||
|
|
|
@ -25,6 +25,21 @@
|
||||||
#define GL_GLEXT_PROTOTYPES 1
|
#define GL_GLEXT_PROTOTYPES 1
|
||||||
#include <SDL2/SDL_opengl.h>
|
#include <SDL2/SDL_opengl.h>
|
||||||
|
|
||||||
|
// redefine this if using a different GL loader
|
||||||
|
#define mglGetProcAddress(name) SDL_GL_GetProcAddress(name)
|
||||||
|
|
||||||
|
// we'll define and load it manually in init, just in case
|
||||||
|
typedef void (*PFNMGLFOGCOORDPOINTERPROC)(GLenum type, GLsizei stride, const void *pointer);
|
||||||
|
static PFNMGLFOGCOORDPOINTERPROC mglFogCoordPointer = NULL;
|
||||||
|
|
||||||
|
// since these can have different names, might as well redefine them to a single one
|
||||||
|
#undef GL_FOG_COORD_SRC
|
||||||
|
#undef GL_FOG_COORD
|
||||||
|
#undef GL_FOG_COORD_ARRAY
|
||||||
|
#define GL_FOG_COORD_SRC 0x8450
|
||||||
|
#define GL_FOG_COORD 0x8451
|
||||||
|
#define GL_FOG_COORD_ARRAY 0x8457
|
||||||
|
|
||||||
#include "gfx_cc.h"
|
#include "gfx_cc.h"
|
||||||
#include "gfx_rendering_api.h"
|
#include "gfx_rendering_api.h"
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
|
@ -65,9 +80,12 @@ static uint8_t shader_program_pool_size;
|
||||||
static struct ShaderProgram *cur_shader = NULL;
|
static struct ShaderProgram *cur_shader = NULL;
|
||||||
|
|
||||||
static const float *cur_buf = NULL;
|
static const float *cur_buf = NULL;
|
||||||
|
static const float *cur_fog_ofs = NULL;
|
||||||
static size_t cur_buf_size = 0;
|
static size_t cur_buf_size = 0;
|
||||||
static size_t cur_buf_num_tris = 0;
|
static size_t cur_buf_num_tris = 0;
|
||||||
static size_t cur_buf_stride = 0;
|
static size_t cur_buf_stride = 0;
|
||||||
|
static bool gl_blend = false;
|
||||||
|
static bool gl_adv_fog = false;
|
||||||
|
|
||||||
static const float c_white[] = { 1.f, 1.f, 1.f, 1.f };
|
static const float c_white[] = { 1.f, 1.f, 1.f, 1.f };
|
||||||
|
|
||||||
|
@ -186,13 +204,18 @@ static void gfx_opengl_apply_shader(struct ShaderProgram *prg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prg->shader_id & SHADER_OPT_FOG) {
|
if (prg->shader_id & SHADER_OPT_FOG) {
|
||||||
// have fog, but fog colors are the same for every vertex
|
// fog requested, we can deal with it in one of two ways
|
||||||
// TODO: alpha ain't the same, maybe use glSecondaryColorPointer?
|
if (gl_adv_fog) {
|
||||||
// TODO: or pass start and end from gsSPFogPosition somehow or calculate them from z0, w0 and a0?
|
// if GL_EXT_fog_coord is available, use the provided fog factor as scaled depth for GL fog
|
||||||
// TODO: or alpha blend solid triangles on top, using the fog factor as alpha
|
const float fogrgb[] = { ofs[0], ofs[1], ofs[2] };
|
||||||
// glEnable(GL_FOG);
|
glEnable(GL_FOG);
|
||||||
// glFogi(GL_FOG_MODE, GL_LINEAR);
|
glFogfv(GL_FOG_COLOR, fogrgb); // color is the same for all verts, only intensity is different
|
||||||
// glFogfv(GL_FOG_COLOR, ofs);
|
glEnableClientState(GL_FOG_COORD_ARRAY);
|
||||||
|
mglFogCoordPointer(GL_FLOAT, cur_buf_stride, ofs + 3); // point it to alpha, which is fog factor
|
||||||
|
} else {
|
||||||
|
// if there's no fog coords available, blend it on top of normal tris later
|
||||||
|
cur_fog_ofs = ofs;
|
||||||
|
}
|
||||||
ofs += 4;
|
ofs += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,8 +274,11 @@ static void gfx_opengl_unload_shader(struct ShaderProgram *old_prg) {
|
||||||
glDisable(GL_TEXTURE0);
|
glDisable(GL_TEXTURE0);
|
||||||
glDisable(GL_TEXTURE_2D);
|
glDisable(GL_TEXTURE_2D);
|
||||||
glDisable(GL_ALPHA_TEST);
|
glDisable(GL_ALPHA_TEST);
|
||||||
|
glDisable(GL_FOG);
|
||||||
|
cur_fog_ofs = NULL; // clear fog colors
|
||||||
|
|
||||||
glDisableClientState(GL_COLOR_ARRAY);
|
glDisableClientState(GL_COLOR_ARRAY);
|
||||||
|
if (gl_adv_fog) glDisableClientState(GL_FOG_COORD_ARRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gfx_opengl_load_shader(struct ShaderProgram *new_prg) {
|
static void gfx_opengl_load_shader(struct ShaderProgram *new_prg) {
|
||||||
|
@ -401,6 +427,7 @@ static void gfx_opengl_set_scissor(int x, int y, int width, int height) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gfx_opengl_set_use_alpha(bool use_alpha) {
|
static void gfx_opengl_set_use_alpha(bool use_alpha) {
|
||||||
|
gl_blend = use_alpha;
|
||||||
if (use_alpha) {
|
if (use_alpha) {
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
} else {
|
} else {
|
||||||
|
@ -408,6 +435,32 @@ static void gfx_opengl_set_use_alpha(bool use_alpha) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// draws the same triangles as plain fog color + fog intensity as alpha
|
||||||
|
// on top of the normal tris and blends them to achieve sort of the same effect
|
||||||
|
// as fog would
|
||||||
|
static inline void gfx_opengl_blend_fog_tris(void) {
|
||||||
|
// if a texture was used, replace it with fog color instead, but still keep the alpha
|
||||||
|
if (cur_shader->texture_used[0]) {
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
TEXENV_COMBINE_ON();
|
||||||
|
// out.rgb = input0.rgb
|
||||||
|
TEXENV_COMBINE_SET1(RGB, GL_REPLACE, GL_PRIMARY_COLOR);
|
||||||
|
// out.a = texel0.a * input0.a
|
||||||
|
TEXENV_COMBINE_SET2(ALPHA, GL_MODULATE, GL_TEXTURE, GL_PRIMARY_COLOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
glEnableClientState(GL_COLOR_ARRAY); // enable color array temporarily
|
||||||
|
glColorPointer(4, GL_FLOAT, cur_buf_stride, cur_fog_ofs); // set fog colors as primary colors
|
||||||
|
if (!gl_blend) glEnable(GL_BLEND); // enable blending temporarily
|
||||||
|
glDepthFunc(GL_LEQUAL); // Z is the same as the base triangles
|
||||||
|
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, 3 * cur_buf_num_tris);
|
||||||
|
|
||||||
|
glDepthFunc(GL_LESS); // set back to default
|
||||||
|
if (!gl_blend) glDisable(GL_BLEND); // disable blending if it was disabled
|
||||||
|
glDisableClientState(GL_COLOR_ARRAY); // will get reenabled later anyway
|
||||||
|
}
|
||||||
|
|
||||||
static void gfx_opengl_draw_triangles(float buf_vbo[], size_t buf_vbo_len, size_t buf_vbo_num_tris) {
|
static void gfx_opengl_draw_triangles(float buf_vbo[], size_t buf_vbo_len, size_t buf_vbo_num_tris) {
|
||||||
//printf("flushing %d tris\n", buf_vbo_num_tris);
|
//printf("flushing %d tris\n", buf_vbo_num_tris);
|
||||||
|
|
||||||
|
@ -418,7 +471,10 @@ static void gfx_opengl_draw_triangles(float buf_vbo[], size_t buf_vbo_len, size_
|
||||||
|
|
||||||
gfx_opengl_apply_shader(cur_shader);
|
gfx_opengl_apply_shader(cur_shader);
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 3 * buf_vbo_num_tris);
|
glDrawArrays(GL_TRIANGLES, 0, 3 * cur_buf_num_tris);
|
||||||
|
|
||||||
|
// cur_fog_ofs is only set if GL_EXT_fog_coord isn't used
|
||||||
|
if (cur_fog_ofs) gfx_opengl_blend_fog_tris();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool gl_check_ext(const char *name) {
|
static inline bool gl_check_ext(const char *name) {
|
||||||
|
@ -428,10 +484,11 @@ static inline bool gl_check_ext(const char *name) {
|
||||||
extstr = (const char *)glGetString(GL_EXTENSIONS);
|
extstr = (const char *)glGetString(GL_EXTENSIONS);
|
||||||
|
|
||||||
if (!strstr(extstr, name)) {
|
if (!strstr(extstr, name)) {
|
||||||
fprintf(stderr, "Required GL extension not supported: %s\n", name);
|
fprintf(stderr, "GL extension not supported: %s\n", name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("GL extension detected: %s\n", name);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,16 +522,44 @@ static void gfx_opengl_init(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check extensions that we need
|
// check extensions that we need
|
||||||
bool supported =
|
const bool supported =
|
||||||
gl_check_ext("GL_ARB_multitexture") &&
|
gl_check_ext("GL_ARB_multitexture") &&
|
||||||
gl_check_ext("GL_ARB_texture_env_combine");
|
gl_check_ext("GL_ARB_texture_env_combine");
|
||||||
|
|
||||||
if (!supported) abort();
|
if (!supported) abort();
|
||||||
|
|
||||||
|
gl_adv_fog = false;
|
||||||
|
|
||||||
|
// check whether we can use advanced fog shit
|
||||||
|
const bool fog_ext =
|
||||||
|
vmajor > 1 || vminor > 3 ||
|
||||||
|
gl_check_ext("GL_EXT_fog_coord") ||
|
||||||
|
gl_check_ext("GL_ARB_fog_coord");
|
||||||
|
|
||||||
|
if (fog_ext) {
|
||||||
|
// try to load manually, as this might be an extension, and even then the ext list may lie
|
||||||
|
mglFogCoordPointer = mglGetProcAddress("glFogCoordPointer");
|
||||||
|
if (!mglFogCoordPointer) mglFogCoordPointer = mglGetProcAddress("glFogCoordPointerEXT");
|
||||||
|
if (!mglFogCoordPointer) mglFogCoordPointer = mglGetProcAddress("glFogCoordPointerARB");
|
||||||
|
if (!mglFogCoordPointer)
|
||||||
|
printf("glFogCoordPointer is not actually available, it won't be used.\n");
|
||||||
|
else
|
||||||
|
gl_adv_fog = true; // appears to be all good
|
||||||
|
}
|
||||||
|
|
||||||
printf("GL_VERSION = %s\n", glGetString(GL_VERSION));
|
printf("GL_VERSION = %s\n", glGetString(GL_VERSION));
|
||||||
printf("GL_EXTENSIONS =\n%s\n", glGetString(GL_EXTENSIONS));
|
printf("GL_EXTENSIONS =\n%s\n", glGetString(GL_EXTENSIONS));
|
||||||
|
|
||||||
// these never change
|
if (gl_adv_fog) {
|
||||||
|
// set fog params, they never change
|
||||||
|
printf("GL_EXT_fog_coord available, using that for fog\n");
|
||||||
|
glFogi(GL_FOG_COORD_SRC, GL_FOG_COORD);
|
||||||
|
glFogi(GL_FOG_MODE, GL_LINEAR);
|
||||||
|
glFogf(GL_FOG_START, 0.0f);
|
||||||
|
glFogf(GL_FOG_END, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// these also never change
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, c_white);
|
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, c_white);
|
||||||
|
|
|
@ -155,24 +155,37 @@ static size_t buf_vbo_num_tris;
|
||||||
static struct GfxWindowManagerAPI *gfx_wapi;
|
static struct GfxWindowManagerAPI *gfx_wapi;
|
||||||
static struct GfxRenderingAPI *gfx_rapi;
|
static struct GfxRenderingAPI *gfx_rapi;
|
||||||
|
|
||||||
#if defined(__MINGW32__)
|
#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) && !defined(__APPLE__)
|
||||||
#include <_mingw.h>
|
// old mingw
|
||||||
#if !defined(__MINGW64_VERSION_MAJOR)
|
# include <_mingw.h>
|
||||||
|
# define NO_CLOCK_GETTIME
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NO_CLOCK_GETTIME
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#define CLOCK_MONOTONIC 0
|
#define CLOCK_MONOTONIC 0
|
||||||
//https://stackoverflow.com/questions/5404277/porting-clock-gettime-to-windows
|
// https://stackoverflow.com/questions/5404277/porting-clock-gettime-to-windows
|
||||||
struct timespec { long tv_sec; long tv_nsec; }; //header part
|
struct timespec { long tv_sec; long tv_nsec; };
|
||||||
int clock_gettime(int arg, struct timespec *spec) //C-file part
|
int clock_gettime(int arg, struct timespec *spec) {
|
||||||
{ __int64 wintime; GetSystemTimeAsFileTime((FILETIME*)&wintime);
|
__int64 wintime;
|
||||||
wintime -=116444736000000000LL; //1jan1601 to 1jan1970
|
GetSystemTimeAsFileTime((FILETIME*)&wintime);
|
||||||
spec->tv_sec =wintime / 10000000LL; //seconds
|
wintime -= 116444736000000000LL; //1jan1601 to 1jan1970
|
||||||
spec->tv_nsec =wintime % 10000000LL*100; //nano-seconds
|
spec->tv_sec = wintime / 10000000LL; //seconds
|
||||||
return 0;
|
spec->tv_nsec = wintime % 10000000LL*100; //nano-seconds
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
#else
|
#else // _WIN32
|
||||||
|
#error "Add a clock_gettime() impl for your platform!"
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
|
#else // NO_CLOCK_GETTIME
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#endif
|
|
||||||
#endif
|
#endif // NO_CLOCK_GETTIME
|
||||||
|
|
||||||
static unsigned long get_time(void) {
|
static unsigned long get_time(void) {
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||||
|
|
Loading…
Reference in New Issue