parent
7add4d09b9
commit
1d18b23ea1
7 changed files with 685 additions and 736 deletions
@ -0,0 +1,659 @@ |
||||
#define _WIN32_WINNT 0x400 |
||||
|
||||
#include <assert.h> |
||||
#include <ctype.h> |
||||
#include <stdio.h> |
||||
#include <string.h> |
||||
|
||||
//#include "game.h"
|
||||
|
||||
#include <windows.h> |
||||
|
||||
#define STB_GL_IMPLEMENTATION |
||||
#define STB_GLEXT_DEFINE "glext_list.h" |
||||
#include "stb_gl.h" |
||||
|
||||
#define STB_DEFINE |
||||
#include "stb.h" |
||||
|
||||
#include "caveview.h" |
||||
|
||||
#include "sdl.h" |
||||
#include "SDL_opengl.h" |
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION |
||||
#include "stb_image.h" |
||||
|
||||
#define STB_GLPROG_IMPLEMENTATION |
||||
#define STB_GLPROG_ARB_DEFINE_EXTENSIONS |
||||
#include "stb_glprog.h" |
||||
|
||||
#include "stb_easy_font.h" // doesn't require an IMPLEMENTATION |
||||
|
||||
#include "caveview.h" |
||||
|
||||
char *game_name = "caveview"; |
||||
|
||||
// assume only a single texture with all sprites
|
||||
float texture_s_scale; |
||||
float texture_t_scale; |
||||
GLuint interface_tex, logo_tex; |
||||
|
||||
extern int screen_x, screen_y; // main.c
|
||||
|
||||
void print_string(float x, float y, char *text, float r, float g, float b) |
||||
{ |
||||
static char buffer[99999]; |
||||
int num_quads; |
||||
|
||||
num_quads = stb_easy_font_print(x, y, text, NULL, buffer, sizeof(buffer)); |
||||
|
||||
glColor3f(r,g,b); |
||||
glEnableClientState(GL_VERTEX_ARRAY); |
||||
glVertexPointer(2, GL_FLOAT, 16, buffer); |
||||
glDrawArrays(GL_QUADS, 0, num_quads*4); |
||||
glDisableClientState(GL_VERTEX_ARRAY); |
||||
} |
||||
|
||||
float text_color[3]; |
||||
float pos_x = 10; |
||||
float pos_y = 10; |
||||
|
||||
void print(char *text, ...) |
||||
{ |
||||
char buffer[999]; |
||||
va_list va; |
||||
va_start(va, text); |
||||
vsprintf(buffer, text, va); |
||||
va_end(va); |
||||
print_string(pos_x, pos_y, buffer, text_color[0], text_color[1], text_color[2]); |
||||
pos_y += 10; |
||||
} |
||||
|
||||
// mouse offsetting 'pixel to virtual'
|
||||
float xs_p2v, ys_p2v;// xoff_p2v, yoff_p2v;
|
||||
|
||||
// viewport offseting 'virtual to pixel'
|
||||
float xs_v2p, ys_v2p, xoff_v2p, yoff_v2p; |
||||
|
||||
float camang[3], camloc[3] = { 0,0,75 }; |
||||
float player_zoom = 1.0; |
||||
int third_person; |
||||
float rotate_view = 0.0; |
||||
|
||||
#define REVERSE_DEPTH |
||||
|
||||
|
||||
void init_game(void) |
||||
{ |
||||
// init_graphics();
|
||||
} |
||||
|
||||
void camera_to_worldspace(float world[3], float cam_x, float cam_y, float cam_z) |
||||
{ |
||||
float vec[3] = { cam_x, cam_y, cam_z }; |
||||
float t[3]; |
||||
float s,c; |
||||
s = (float) sin(camang[0]*3.141592/180); |
||||
c = (float) cos(camang[0]*3.141592/180); |
||||
|
||||
t[0] = vec[0]; |
||||
t[1] = c*vec[1] - s*vec[2]; |
||||
t[2] = s*vec[1] + c*vec[2]; |
||||
|
||||
s = (float) sin(camang[2]*3.141592/180); |
||||
c = (float) cos(camang[2]*3.141592/180); |
||||
world[0] = c*t[0] - s*t[1]; |
||||
world[1] = s*t[0] + c*t[1]; |
||||
world[2] = t[2]; |
||||
} |
||||
|
||||
// camera worldspace velocity
|
||||
float cam_vel[3]; |
||||
|
||||
int controls; |
||||
|
||||
#define MAX_VEL 150.0f // blocks per second
|
||||
#define ACCEL 6.0f |
||||
#define DECEL 3.0f |
||||
|
||||
#define STATIC_FRICTION DECEL |
||||
#define EFFECTIVE_ACCEL (ACCEL+DECEL) |
||||
|
||||
// dynamic friction:
|
||||
//
|
||||
// if going at MAX_VEL, ACCEL and friction must cancel
|
||||
// EFFECTIVE_ACCEL = DECEL + DYNAMIC_FRIC*MAX_VEL
|
||||
#define DYNAMIC_FRICTION (ACCEL/(float)MAX_VEL) |
||||
|
||||
float view_x_vel = 0; |
||||
float view_z_vel = 0; |
||||
float pending_view_x; |
||||
float pending_view_z; |
||||
float pending_view_x; |
||||
float pending_view_z; |
||||
|
||||
void process_tick_raw(float dt) |
||||
{ |
||||
int i; |
||||
float thrust[3] = { 0,0,0 }; |
||||
float world_thrust[3]; |
||||
|
||||
// choose direction to apply thrust
|
||||
|
||||
thrust[0] = (controls & 3)== 1 ? EFFECTIVE_ACCEL : (controls & 3)== 2 ? -EFFECTIVE_ACCEL : 0; |
||||
thrust[1] = (controls & 12)== 4 ? EFFECTIVE_ACCEL : (controls & 12)== 8 ? -EFFECTIVE_ACCEL : 0; |
||||
thrust[2] = (controls & 48)==16 ? EFFECTIVE_ACCEL : (controls & 48)==32 ? -EFFECTIVE_ACCEL : 0; |
||||
|
||||
// @TODO clamp thrust[0] & thrust[1] vector length to EFFECTIVE_ACCEL
|
||||
|
||||
camera_to_worldspace(world_thrust, thrust[0], thrust[1], 0); |
||||
world_thrust[2] += thrust[2]; |
||||
|
||||
for (i=0; i < 3; ++i) { |
||||
float acc = world_thrust[i]; |
||||
cam_vel[i] += acc*dt; |
||||
} |
||||
|
||||
if (cam_vel[0] || cam_vel[1] || cam_vel[2]) |
||||
{ |
||||
float vel = (float) sqrt(cam_vel[0]*cam_vel[0] + cam_vel[1]*cam_vel[1] + cam_vel[2]*cam_vel[2]); |
||||
float newvel = vel; |
||||
float dec = STATIC_FRICTION + DYNAMIC_FRICTION*vel; |
||||
newvel = vel - dec*dt; |
||||
if (newvel < 0) |
||||
newvel = 0; |
||||
cam_vel[0] *= newvel/vel; |
||||
cam_vel[1] *= newvel/vel; |
||||
cam_vel[2] *= newvel/vel; |
||||
} |
||||
|
||||
camloc[0] += cam_vel[0] * dt; |
||||
camloc[1] += cam_vel[1] * dt; |
||||
camloc[2] += cam_vel[2] * dt; |
||||
|
||||
view_x_vel *= (float) pow(0.75, dt); |
||||
view_z_vel *= (float) pow(0.75, dt); |
||||
|
||||
view_x_vel += (pending_view_x - view_x_vel)*dt*60; |
||||
view_z_vel += (pending_view_z - view_z_vel)*dt*60; |
||||
|
||||
pending_view_x -= view_x_vel * dt; |
||||
pending_view_z -= view_z_vel * dt; |
||||
camang[0] += view_x_vel * dt; |
||||
camang[2] += view_z_vel * dt; |
||||
camang[0] = stb_clamp(camang[0], -90, 90); |
||||
camang[2] = (float) fmod(camang[2], 360); |
||||
} |
||||
|
||||
void process_tick(float dt) |
||||
{ |
||||
while (dt > 1.0f/60) { |
||||
process_tick_raw(1.0f/60); |
||||
dt -= 1.0f/60; |
||||
} |
||||
process_tick_raw(dt); |
||||
} |
||||
|
||||
void update_view(float dx, float dy) |
||||
{ |
||||
// hard-coded mouse sensitivity, not resolution independent?
|
||||
pending_view_z -= dx*300; |
||||
pending_view_x -= dy*700; |
||||
} |
||||
|
||||
extern int screen_x, screen_y; |
||||
extern int is_synchronous_debug; |
||||
float render_time; |
||||
|
||||
extern int chunk_locations, chunks_considered, chunks_in_frustum; |
||||
extern int quads_considered, quads_rendered; |
||||
extern int chunk_storage_rendered, chunk_storage_considered, chunk_storage_total; |
||||
extern int view_dist_in_chunks; |
||||
extern int num_threads_active, num_meshes_started, num_meshes_uploaded; |
||||
extern float chunk_server_activity; |
||||
|
||||
static Uint64 start_time, end_time; // render time
|
||||
|
||||
float chunk_server_status[32]; |
||||
int chunk_server_pos; |
||||
|
||||
void draw_stats(void) |
||||
{ |
||||
int i; |
||||
|
||||
static Uint64 last_frame_time; |
||||
Uint64 cur_time = SDL_GetPerformanceCounter(); |
||||
float chunk_server=0; |
||||
float frame_time = (cur_time - last_frame_time) / (float) SDL_GetPerformanceFrequency(); |
||||
last_frame_time = cur_time; |
||||
|
||||
chunk_server_status[chunk_server_pos] = chunk_server_activity; |
||||
chunk_server_pos = (chunk_server_pos+1) %32; |
||||
|
||||
for (i=0; i < 32; ++i) |
||||
chunk_server += chunk_server_status[i] / 32.0f; |
||||
|
||||
stb_easy_font_spacing(-0.75); |
||||
pos_y = 10; |
||||
text_color[0] = text_color[1] = text_color[2] = 1.0f; |
||||
print("Frame time: %6.2fms, CPU frame render time: %5.2fms", frame_time*1000, render_time*1000); |
||||
print("Tris: %4.1fM drawn of %4.1fM in range", 2*quads_rendered/1000000.0f, 2*quads_considered/1000000.0f); |
||||
print("Vbuf storage: %dMB in frustum of %dMB in range of %dMB in cache", chunk_storage_rendered>>20, chunk_storage_considered>>20, chunk_storage_total>>20); |
||||
print("Num mesh builds started this frame: %d; num uploaded this frame: %d\n", num_meshes_started, num_meshes_uploaded); |
||||
print("QChunks: %3d in frustum of %3d valid of %3d in range", chunks_in_frustum, chunks_considered, chunk_locations); |
||||
print("Mesh worker threads active: %d", num_threads_active); |
||||
print("View distance: %d blocks", view_dist_in_chunks*16); |
||||
print("%s", glGetString(GL_RENDERER)); |
||||
|
||||
if (is_synchronous_debug) { |
||||
text_color[0] = 1.0; |
||||
text_color[1] = 0.5; |
||||
text_color[2] = 0.5; |
||||
print("SLOWNESS: Synchronous debug output is enabled!"); |
||||
} |
||||
} |
||||
|
||||
void draw_main(void) |
||||
{ |
||||
glEnable(GL_CULL_FACE); |
||||
glDisable(GL_TEXTURE_2D); |
||||
glDisable(GL_LIGHTING); |
||||
glEnable(GL_DEPTH_TEST); |
||||
#ifdef REVERSE_DEPTH |
||||
glDepthFunc(GL_GREATER); |
||||
glClearDepth(0); |
||||
#else |
||||
glDepthFunc(GL_LESS); |
||||
glClearDepth(1); |
||||
#endif |
||||
glDepthMask(GL_TRUE); |
||||
glDisable(GL_SCISSOR_TEST); |
||||
glClearColor(0.6f,0.7f,0.9f,0.0f); |
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
||||
glColor3f(1,1,1); |
||||
glFrontFace(GL_CW); |
||||
glEnable(GL_TEXTURE_2D); |
||||
glDisable(GL_BLEND); |
||||
|
||||
|
||||
glMatrixMode(GL_PROJECTION); |
||||
glLoadIdentity(); |
||||
|
||||
#ifdef REVERSE_DEPTH |
||||
stbgl_Perspective(player_zoom, 90, 70, 3000, 1.0/16); |
||||
#else |
||||
stbgl_Perspective(player_zoom, 90, 70, 1.0/16, 3000); |
||||
#endif |
||||
|
||||
// now compute where the camera should be
|
||||
glMatrixMode(GL_MODELVIEW); |
||||
glLoadIdentity(); |
||||
stbgl_initCamera_zup_facing_y(); |
||||
|
||||
//glTranslatef(0,150,-5);
|
||||
// position the camera and render it
|
||||
|
||||
if (third_person) { |
||||
glTranslatef(0,2.5,0); |
||||
glRotatef(-camang[0],1,0,0); |
||||
|
||||
glTranslatef(0,2,0); |
||||
glRotatef(-camang[2]-rotate_view,0,0,1); |
||||
|
||||
//glTranslatef(0,0,1);
|
||||
//glTranslatef(0,0,-1);
|
||||
} else { |
||||
glRotatef(-camang[0],1,0,0); |
||||
glRotatef(-camang[2],0,0,1); |
||||
} |
||||
|
||||
glTranslatef(-camloc[0], -camloc[1], -camloc[2]); |
||||
|
||||
start_time = SDL_GetPerformanceCounter(); |
||||
render_caves(camloc); |
||||
end_time = SDL_GetPerformanceCounter(); |
||||
|
||||
render_time = (end_time - start_time) / (float) SDL_GetPerformanceFrequency(); |
||||
|
||||
glMatrixMode(GL_PROJECTION); |
||||
glLoadIdentity(); |
||||
gluOrtho2D(0,screen_x/2,screen_y/2,0); |
||||
glMatrixMode(GL_MODELVIEW); |
||||
glLoadIdentity(); |
||||
glDisable(GL_TEXTURE_2D); |
||||
glDisable(GL_BLEND); |
||||
glDisable(GL_CULL_FACE); |
||||
draw_stats(); |
||||
} |
||||
|
||||
|
||||
|
||||
#pragma warning(disable:4244; disable:4305; disable:4018) |
||||
|
||||
#define SCALE 2 |
||||
|
||||
void error(char *s) |
||||
{ |
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", s, NULL); |
||||
exit(0); |
||||
} |
||||
|
||||
void ods(char *fmt, ...) |
||||
{ |
||||
char buffer[1000]; |
||||
va_list va; |
||||
va_start(va, fmt); |
||||
vsprintf(buffer, fmt, va); |
||||
va_end(va); |
||||
SDL_Log("%s", buffer); |
||||
} |
||||
|
||||
#define TICKS_PER_SECOND 60 |
||||
|
||||
static SDL_Window *window; |
||||
|
||||
extern void init_game(void); |
||||
extern void draw_main(void); |
||||
extern void process_tick(float dt); |
||||
extern void editor_init(void); |
||||
|
||||
void draw(void) |
||||
{ |
||||
draw_main(); |
||||
SDL_GL_SwapWindow(window); |
||||
} |
||||
|
||||
|
||||
static int initialized=0; |
||||
static float last_dt; |
||||
|
||||
int screen_x,screen_y; |
||||
|
||||
float carried_dt = 0; |
||||
#define TICKRATE 60 |
||||
|
||||
|
||||
int raw_level_time; |
||||
extern void init_game(void); |
||||
extern void draw_main(void); |
||||
|
||||
float global_timer; |
||||
|
||||
int loopmode(float dt, int real, int in_client) |
||||
{ |
||||
float actual_dt = dt; |
||||
|
||||
float jump_timer = dt; |
||||
|
||||
if (!initialized) return 0; |
||||
|
||||
if (!real) |
||||
return 0; |
||||
|
||||
// don't allow more than 6 frames to update at a time
|
||||
if (dt > 0.075) dt = 0.075; |
||||
|
||||
global_timer += dt; |
||||
|
||||
carried_dt += dt; |
||||
while (carried_dt > 1.0/TICKRATE) { |
||||
//update_input();
|
||||
// if the player is dead, stop the sim
|
||||
carried_dt -= 1.0/TICKRATE; |
||||
} |
||||
|
||||
process_tick(dt); |
||||
draw(); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int quit; |
||||
|
||||
//int winproc(void *data, stbwingraph_event *e)
|
||||
|
||||
extern int editor_scale; |
||||
extern void editor_key(enum stbte_action act); |
||||
extern int controls; |
||||
|
||||
void active_control_set(int key) |
||||
{ |
||||
controls |= 1 << key; |
||||
} |
||||
|
||||
void active_control_clear(int key) |
||||
{ |
||||
controls &= ~(1 << key); |
||||
} |
||||
|
||||
extern void update_view(float dx, float dy); |
||||
|
||||
void process_sdl_mouse(SDL_Event *e) |
||||
{ |
||||
update_view((float) e->motion.xrel / screen_x, (float) e->motion.yrel / screen_y); |
||||
} |
||||
|
||||
void process_event(SDL_Event *e) |
||||
{ |
||||
switch (e->type) { |
||||
case SDL_MOUSEMOTION: |
||||
process_sdl_mouse(e); |
||||
break; |
||||
case SDL_MOUSEBUTTONDOWN: |
||||
case SDL_MOUSEBUTTONUP: |
||||
case SDL_MOUSEWHEEL: |
||||
//stbte_mouse_sdl(edit_map, e, 1.0f/editor_scale,1.0f/editor_scale,0,0);
|
||||
break; |
||||
|
||||
case SDL_QUIT: |
||||
quit = 1; |
||||
break; |
||||
|
||||
case SDL_WINDOWEVENT: |
||||
switch (e->window.event) { |
||||
case SDL_WINDOWEVENT_SIZE_CHANGED: |
||||
screen_x = e->window.data1; |
||||
screen_y = e->window.data2; |
||||
loopmode(0,1,0); |
||||
break; |
||||
} |
||||
break; |
||||
|
||||
case SDL_TEXTINPUT: |
||||
switch(e->text.text[0]) { |
||||
#if 0 |
||||
case 27: { |
||||
#if 0 |
||||
int result; |
||||
SDL_ShowCursor(SDL_ENABLE); |
||||
if (MessageBox(e->handle, "Exit CLTT?", "CLTT", MB_OKCANCEL) == IDOK); |
||||
#endif |
||||
{ |
||||
quit = 1; |
||||
break; |
||||
} |
||||
//SDL_ShowCursor(SDL_DISABLE);
|
||||
break; |
||||
} |
||||
#endif |
||||
} |
||||
break; |
||||
|
||||
case SDL_KEYDOWN: { |
||||
int k = e->key.keysym.sym; |
||||
int s = e->key.keysym.scancode; |
||||
SDL_Keymod mod; |
||||
mod = SDL_GetModState(); |
||||
if (k == SDLK_ESCAPE) { |
||||
#ifndef DO_EDITOR |
||||
quit = 1; |
||||
#endif |
||||
} |
||||
|
||||
if (s == SDL_SCANCODE_D) active_control_set(0); |
||||
if (s == SDL_SCANCODE_A) active_control_set(1); |
||||
if (s == SDL_SCANCODE_W) active_control_set(2); |
||||
if (s == SDL_SCANCODE_S) active_control_set(3); |
||||
if (k == SDLK_SPACE) active_control_set(4);
|
||||
if (s == SDL_SCANCODE_LCTRL) active_control_set(5); |
||||
if (s == SDL_SCANCODE_S) active_control_set(6); |
||||
if (s == SDL_SCANCODE_D) active_control_set(7); |
||||
|
||||
#if 0 |
||||
if (game_mode == GAME_editor) { |
||||
switch (k) { |
||||
case SDLK_RIGHT: editor_key(STBTE_scroll_right); break; |
||||
case SDLK_LEFT : editor_key(STBTE_scroll_left ); break; |
||||
case SDLK_UP : editor_key(STBTE_scroll_up ); break; |
||||
case SDLK_DOWN : editor_key(STBTE_scroll_down ); break; |
||||
} |
||||
switch (s) { |
||||
case SDL_SCANCODE_S: editor_key(STBTE_tool_select); break; |
||||
case SDL_SCANCODE_B: editor_key(STBTE_tool_brush ); break; |
||||
case SDL_SCANCODE_E: editor_key(STBTE_tool_erase ); break; |
||||
case SDL_SCANCODE_R: editor_key(STBTE_tool_rectangle ); break; |
||||
case SDL_SCANCODE_I: editor_key(STBTE_tool_eyedropper); break; |
||||
case SDL_SCANCODE_L: editor_key(STBTE_tool_link); break; |
||||
case SDL_SCANCODE_G: editor_key(STBTE_act_toggle_grid); break; |
||||
} |
||||
if ((e->key.keysym.mod & KMOD_CTRL) && !(e->key.keysym.mod & ~KMOD_CTRL)) { |
||||
switch (s) { |
||||
case SDL_SCANCODE_X: editor_key(STBTE_act_cut ); break; |
||||
case SDL_SCANCODE_C: editor_key(STBTE_act_copy ); break; |
||||
case SDL_SCANCODE_V: editor_key(STBTE_act_paste); break; |
||||
case SDL_SCANCODE_Z: editor_key(STBTE_act_undo ); break; |
||||
case SDL_SCANCODE_Y: editor_key(STBTE_act_redo ); break; |
||||
} |
||||
} |
||||
} |
||||
#endif |
||||
break; |
||||
} |
||||
case SDL_KEYUP: { |
||||
int k = e->key.keysym.sym; |
||||
int s = e->key.keysym.scancode; |
||||
if (s == SDL_SCANCODE_D) active_control_clear(0); |
||||
if (s == SDL_SCANCODE_A) active_control_clear(1); |
||||
if (s == SDL_SCANCODE_W) active_control_clear(2); |
||||
if (s == SDL_SCANCODE_S) active_control_clear(3); |
||||
if (k == SDLK_SPACE) active_control_clear(4);
|
||||
if (s == SDL_SCANCODE_LCTRL) active_control_clear(5); |
||||
if (s == SDL_SCANCODE_S) active_control_clear(6); |
||||
if (s == SDL_SCANCODE_D) active_control_clear(7); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
static SDL_GLContext *context; |
||||
|
||||
static float getTimestep(float minimum_time) |
||||
{ |
||||
float elapsedTime; |
||||
double thisTime; |
||||
static double lastTime = -1; |
||||
|
||||
if (lastTime == -1) |
||||
lastTime = SDL_GetTicks() / 1000.0 - minimum_time; |
||||
|
||||
for(;;) { |
||||
thisTime = SDL_GetTicks() / 1000.0; |
||||
elapsedTime = (float) (thisTime - lastTime); |
||||
if (elapsedTime >= minimum_time) { |
||||
lastTime = thisTime;
|
||||
return elapsedTime; |
||||
} |
||||
// @TODO: compute correct delay
|
||||
SDL_Delay(1); |
||||
} |
||||
} |
||||
|
||||
void APIENTRY gl_debug(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *param) |
||||
{ |
||||
#if 0 |
||||
if (severity == GL_DEBUG_SEVERITY_LOW_ARB) |
||||
return; |
||||
#endif |
||||
ods("%s\n", message); |
||||
} |
||||
|
||||
int is_synchronous_debug; |
||||
void enable_synchronous(void) |
||||
{ |
||||
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); |
||||
is_synchronous_debug = 1; |
||||
} |
||||
|
||||
void prepare_threads(void); |
||||
|
||||
//void stbwingraph_main(void)
|
||||
int SDL_main(int argc, char **argv) |
||||
{ |
||||
SDL_Init(SDL_INIT_VIDEO); |
||||
|
||||
prepare_threads(); |
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_RED_SIZE , 8); |
||||
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); |
||||
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE , 8); |
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); |
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); |
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); |
||||
|
||||
#ifdef GL_DEBUG |
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG); |
||||
#endif |
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); |
||||
|
||||
screen_x = 1920; |
||||
screen_y = 1080; |
||||
|
||||
window = SDL_CreateWindow("caveview", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, |
||||
screen_x, screen_y, |
||||
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE |
||||
); |
||||
if (!window) error("Couldn't create window"); |
||||
|
||||
context = SDL_GL_CreateContext(window); |
||||
if (!context) error("Couldn't create context"); |
||||
|
||||
SDL_GL_MakeCurrent(window, context); // is this true by default?
|
||||
|
||||
// if (!IsDebuggerPresent())
|
||||
SDL_SetRelativeMouseMode(SDL_TRUE); |
||||
|
||||
stbgl_initExtensions(); |
||||
|
||||
#ifdef GL_DEBUG |
||||
if (glDebugMessageCallbackARB) { |
||||
glDebugMessageCallbackARB(gl_debug, NULL); |
||||
|
||||
enable_synchronous(); |
||||
} |
||||
#endif |
||||
|
||||
SDL_GL_SetSwapInterval(0); // only when profiling
|
||||
|
||||
render_init(); |
||||
mesh_init(); |
||||
world_init(); |
||||
|
||||
init_game(); |
||||
initialized = 1; |
||||
|
||||
while (!quit) { |
||||
SDL_Event e; |
||||
while (SDL_PollEvent(&e)) |
||||
process_event(&e); |
||||
|
||||
loopmode(getTimestep(0.0166f/8), 1, 1); |
||||
quit=quit; |
||||
} |
||||
|
||||
return 0; |
||||
} |
@ -1,354 +0,0 @@ |
||||
#include <windows.h> |
||||
//#include "game.h"
|
||||
#include "stb.h" |
||||
|
||||
#include "sdl.h" |
||||
#include "SDL_opengl.h" |
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION |
||||
#include "stb_image.h" |
||||
|
||||
#define STB_GL_IMPLEMENTATION |
||||
#include "stb_gl.h" |
||||
|
||||
#define STB_GLPROG_IMPLEMENTATION |
||||
#define STB_GLPROG_ARB_DEFINE_EXTENSIONS |
||||
#include "stb_glprog.h" |
||||
|
||||
#include "stb_easy_font.h" |
||||
|
||||
char *game_name = "caveview"; |
||||
|
||||
// assume only a single texture with all sprites
|
||||
float texture_s_scale; |
||||
float texture_t_scale; |
||||
GLuint interface_tex, logo_tex; |
||||
|
||||
extern int screen_x, screen_y; // main.c
|
||||
|
||||
int tex_w, tex_h; |
||||
void *tex_data; |
||||
|
||||
GLuint load_texture(char *filename, int keep) |
||||
{ |
||||
GLuint tex; |
||||
tex_data = stbi_load(filename, &tex_w, &tex_h, NULL, 4); |
||||
if (tex_data == NULL) { |
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, |
||||
game_name, |
||||
"Couldn't open image file.", |
||||
NULL); |
||||
exit(1); |
||||
} |
||||
|
||||
glGenTextures(1, &tex); |
||||
glBindTexture(GL_TEXTURE_2D, tex); |
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_w, tex_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_data); |
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
||||
|
||||
if (!keep) { |
||||
free(tex_data); |
||||
tex_data = NULL; |
||||
} |
||||
|
||||
return tex; |
||||
} |
||||
|
||||
static void init_graphics(void) |
||||
{ |
||||
//logo_tex = load_texture("sss_logo.png",0);
|
||||
//interface_tex = load_texture("game_art.png",1);
|
||||
texture_s_scale = 1.0f / tex_w; |
||||
texture_t_scale = 1.0f / tex_h; |
||||
} |
||||
|
||||
void print_string(float x, float y, char *text, float r, float g, float b) |
||||
{ |
||||
static char buffer[99999]; |
||||
int num_quads; |
||||
|
||||
num_quads = stb_easy_font_print(x, y, text, NULL, buffer, sizeof(buffer)); |
||||
|
||||
glColor3f(r,g,b); |
||||
glEnableClientState(GL_VERTEX_ARRAY); |
||||
glVertexPointer(2, GL_FLOAT, 16, buffer); |
||||
glDrawArrays(GL_QUADS, 0, num_quads*4); |
||||
glDisableClientState(GL_VERTEX_ARRAY); |
||||
} |
||||
|
||||
float text_color[3]; |
||||
float pos_x = 10; |
||||
float pos_y = 10; |
||||
|
||||
void print(char *text, ...) |
||||
{ |
||||
char buffer[999]; |
||||
va_list va; |
||||
va_start(va, text); |
||||
vsprintf(buffer, text, va); |
||||
va_end(va); |
||||
print_string(pos_x, pos_y, buffer, text_color[0], text_color[1], text_color[2]); |
||||
pos_y += 10; |
||||
} |
||||
|
||||
// mouse offsetting 'pixel to virtual'
|
||||
float xs_p2v, ys_p2v;// xoff_p2v, yoff_p2v;
|
||||
|
||||
// viewport offseting 'virtual to pixel'
|
||||
float xs_v2p, ys_v2p, xoff_v2p, yoff_v2p; |
||||
|
||||
float camang[3], camloc[3] = { 0,0,75 }; |
||||
float player_zoom = 1.0; |
||||
int third_person; |
||||
float rotate_view = 0.0; |
||||
|
||||
#define REVERSE_DEPTH |
||||
|
||||
|
||||
void init_game(void) |
||||
{ |
||||
init_graphics(); |
||||
} |
||||
|
||||
void render_caves(float pos[3]); |
||||
|
||||
void camera_to_worldspace(float world[3], float cam_x, float cam_y, float cam_z) |
||||
{ |
||||
float vec[3] = { cam_x, cam_y, cam_z }; |
||||
float t[3]; |
||||
float s,c; |
||||
s = (float) sin(camang[0]*3.141592/180); |
||||
c = (float) cos(camang[0]*3.141592/180); |
||||
|
||||
t[0] = vec[0]; |
||||
t[1] = c*vec[1] - s*vec[2]; |
||||
t[2] = s*vec[1] + c*vec[2]; |
||||
|
||||
s = (float) sin(camang[2]*3.141592/180); |
||||
c = (float) cos(camang[2]*3.141592/180); |
||||
world[0] = c*t[0] - s*t[1]; |
||||
world[1] = s*t[0] + c*t[1]; |
||||
world[2] = t[2]; |
||||
} |
||||
|
||||
// camera worldspace velocity
|
||||
float cam_vel[3]; |
||||
|
||||
int controls; |
||||
|
||||
#define MAX_VEL 150.0f // blocks per second
|
||||
#define ACCEL 6.0f |
||||
#define DECEL 3.0f |
||||
|
||||
#define STATIC_FRICTION DECEL |
||||
#define EFFECTIVE_ACCEL (ACCEL+DECEL) |
||||
|
||||
// dynamic friction:
|
||||
//
|
||||
// if going at MAX_VEL, ACCEL and friction must cancel
|
||||
// EFFECTIVE_ACCEL = DECEL + DYNAMIC_FRIC*MAX_VEL
|
||||
#define DYNAMIC_FRICTION (ACCEL/(float)MAX_VEL) |
||||
|
||||
float view_x_vel = 0; |
||||
float view_z_vel = 0; |
||||
float pending_view_x; |
||||
float pending_view_z; |
||||
float pending_view_x; |
||||
float pending_view_z; |
||||
|
||||
void process_tick_raw(float dt) |
||||
{ |
||||
int i; |
||||
float thrust[3] = { 0,0,0 }; |
||||
float world_thrust[3]; |
||||
|
||||
// choose direction to apply thrust
|
||||
|
||||
thrust[0] = (controls & 3)== 1 ? EFFECTIVE_ACCEL : (controls & 3)== 2 ? -EFFECTIVE_ACCEL : 0; |
||||
thrust[1] = (controls & 12)== 4 ? EFFECTIVE_ACCEL : (controls & 12)== 8 ? -EFFECTIVE_ACCEL : 0; |
||||
thrust[2] = (controls & 48)==16 ? EFFECTIVE_ACCEL : (controls & 48)==32 ? -EFFECTIVE_ACCEL : 0; |
||||
|
||||
// @TODO clamp thrust[0] & thrust[1] vector length to EFFECTIVE_ACCEL
|
||||
|
||||
camera_to_worldspace(world_thrust, thrust[0], thrust[1], 0); |
||||
world_thrust[2] += thrust[2]; |
||||
|
||||
for (i=0; i < 3; ++i) { |
||||
float acc = world_thrust[i]; |
||||
cam_vel[i] += acc*dt; |
||||
} |
||||
|
||||
if (cam_vel[0] || cam_vel[1] || cam_vel[2]) |
||||
{ |
||||
float vel = (float) sqrt(cam_vel[0]*cam_vel[0] + cam_vel[1]*cam_vel[1] + cam_vel[2]*cam_vel[2]); |
||||
float newvel = vel; |
||||
float dec = STATIC_FRICTION + DYNAMIC_FRICTION*vel; |
||||
newvel = vel - dec*dt; |
||||
if (newvel < 0) |
||||
newvel = 0; |
||||
cam_vel[0] *= newvel/vel; |
||||
cam_vel[1] *= newvel/vel; |
||||
cam_vel[2] *= newvel/vel; |
||||
} |
||||
|
||||
camloc[0] += cam_vel[0] * dt; |
||||
camloc[1] += cam_vel[1] * dt; |
||||
camloc[2] += cam_vel[2] * dt; |
||||
|
||||
view_x_vel *= (float) pow(0.75, dt); |
||||
view_z_vel *= (float) pow(0.75, dt); |
||||
|
||||
view_x_vel += (pending_view_x - view_x_vel)*dt*60; |
||||
view_z_vel += (pending_view_z - view_z_vel)*dt*60; |
||||
|
||||
pending_view_x -= view_x_vel * dt; |
||||
pending_view_z -= view_z_vel * dt; |
||||
camang[0] += view_x_vel * dt; |
||||
camang[2] += view_z_vel * dt; |
||||
camang[0] = stb_clamp(camang[0], -90, 90); |
||||
camang[2] = (float) fmod(camang[2], 360); |
||||
} |
||||
|
||||
void process_tick(float dt) |
||||
{ |
||||
while (dt > 1.0f/60) { |
||||
process_tick_raw(1.0f/60); |
||||
dt -= 1.0f/60; |
||||
} |
||||
process_tick_raw(dt); |
||||
} |
||||
|
||||
void update_view(float dx, float dy) |
||||
{ |
||||
// hard-coded mouse sensitivity, not resolution independent?
|
||||
pending_view_z -= dx*300; |
||||
pending_view_x -= dy*700; |
||||
} |
||||
|
||||
extern int screen_x, screen_y; |
||||
extern int is_synchronous_debug; |
||||
float render_time; |
||||
|
||||
extern int chunk_locations, chunks_considered, chunks_in_frustum; |
||||
extern int quads_considered, quads_rendered; |
||||
extern int chunk_storage_rendered, chunk_storage_considered, chunk_storage_total; |
||||
extern int view_dist_in_chunks; |
||||
extern int num_threads_active, num_meshes_started, num_meshes_uploaded; |
||||
extern float chunk_server_activity; |
||||
|
||||
static Uint64 start_time, end_time; // render time
|
||||
|
||||
float chunk_server_status[32]; |
||||
int chunk_server_pos; |
||||
|
||||
void draw_stats(void) |
||||
{ |
||||
int i; |
||||
|
||||
static Uint64 last_frame_time; |
||||
Uint64 cur_time = SDL_GetPerformanceCounter(); |
||||
float chunk_server=0; |
||||
float frame_time = (cur_time - last_frame_time) / (float) SDL_GetPerformanceFrequency(); |
||||
last_frame_time = cur_time; |
||||
|
||||
chunk_server_status[chunk_server_pos] = chunk_server_activity; |
||||
chunk_server_pos = (chunk_server_pos+1) %32; |
||||
|
||||
for (i=0; i < 32; ++i) |
||||
chunk_server += chunk_server_status[i] / 32.0f; |
||||
|
||||
stb_easy_font_spacing(-0.75); |
||||
pos_y = 10; |
||||
text_color[0] = text_color[1] = text_color[2] = 1.0f; |
||||
print("Frame time: %6.2fms, CPU frame render time: %5.2fms", frame_time*1000, render_time*1000); |
||||
print("Tris: %4.1fM drawn of %4.1fM in range", 2*quads_rendered/1000000.0f, 2*quads_considered/1000000.0f); |
||||
print("Vbuf storage: %dMB in frustum of %dMB in range of %dMB in cache", chunk_storage_rendered>>20, chunk_storage_considered>>20, chunk_storage_total>>20); |
||||
print("Num mesh builds started this frame: %d; num uploaded this frame: %d\n", num_meshes_started, num_meshes_uploaded); |
||||
print("QChunks: %3d in frustum of %3d valid of %3d in range", chunks_in_frustum, chunks_considered, chunk_locations); |
||||
print("Mesh worker threads active: %d", num_threads_active); |
||||
print("View distance: %d blocks", view_dist_in_chunks*16); |
||||
print("%s", glGetString(GL_RENDERER)); |
||||
|
||||
if (is_synchronous_debug) { |
||||
text_color[0] = 1.0; |
||||
text_color[1] = 0.5; |
||||
text_color[2] = 0.5; |
||||
print("SLOWNESS: Synchronous debug output is enabled!"); |
||||
} |
||||
} |
||||
|
||||
void draw_main(void) |
||||
{ |
||||
glEnable(GL_CULL_FACE); |
||||
glDisable(GL_TEXTURE_2D); |
||||
glDisable(GL_LIGHTING); |
||||
glEnable(GL_DEPTH_TEST); |
||||
#ifdef REVERSE_DEPTH |
||||
glDepthFunc(GL_GREATER); |
||||
glClearDepth(0); |
||||
#else |
||||
glDepthFunc(GL_LESS); |
||||
glClearDepth(1); |
||||
#endif |
||||
glDepthMask(GL_TRUE); |
||||
glDisable(GL_SCISSOR_TEST); |
||||
glClearColor(0.6f,0.7f,0.9f,0.0f); |
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
||||
glColor3f(1,1,1); |
||||
glFrontFace(GL_CW); |
||||
glEnable(GL_TEXTURE_2D); |
||||
glDisable(GL_BLEND); |
||||
|
||||
|
||||
glMatrixMode(GL_PROJECTION); |
||||
glLoadIdentity(); |
||||
|
||||
#ifdef REVERSE_DEPTH |
||||
stbgl_Perspective(player_zoom, 90, 70, 3000, 1.0/16); |
||||
#else |
||||
stbgl_Perspective(player_zoom, 90, 70, 1.0/16, 3000); |
||||
#endif |
||||
|
||||
// now compute where the camera should be
|
||||
glMatrixMode(GL_MODELVIEW); |
||||
glLoadIdentity(); |
||||
stbgl_initCamera_zup_facing_y(); |
||||
|
||||
//glTranslatef(0,150,-5);
|
||||
// position the camera and render it
|
||||
|
||||
if (third_person) { |
||||
glTranslatef(0,2.5,0); |
||||
glRotatef(-camang[0],1,0,0); |
||||
|
||||
glTranslatef(0,2,0); |
||||
glRotatef(-camang[2]-rotate_view,0,0,1); |
||||
|
||||
//glTranslatef(0,0,1);
|
||||
//glTranslatef(0,0,-1);
|
||||
} else { |
||||
glRotatef(-camang[0],1,0,0); |
||||
glRotatef(-camang[2],0,0,1); |
||||
} |
||||
|
||||
glTranslatef(-camloc[0], -camloc[1], -camloc[2]); |
||||
|
||||
start_time = SDL_GetPerformanceCounter(); |
||||
render_caves(camloc); |
||||
end_time = SDL_GetPerformanceCounter(); |
||||
|
||||
render_time = (end_time - start_time) / (float) SDL_GetPerformanceFrequency(); |
||||
|
||||
glMatrixMode(GL_PROJECTION); |
||||
glLoadIdentity(); |
||||
gluOrtho2D(0,screen_x/2,screen_y/2,0); |
||||
glMatrixMode(GL_MODELVIEW); |
||||
glLoadIdentity(); |
||||
glDisable(GL_TEXTURE_2D); |
||||
glDisable(GL_BLEND); |
||||
glDisable(GL_CULL_FACE); |
||||
draw_stats(); |
||||
} |
@ -1,359 +0,0 @@ |
||||
#pragma warning(disable:4244; disable:4305; disable:4018) |
||||
|
||||
#define _WIN32_WINNT 0x400 |
||||
|
||||
#include "sdl.h" |
||||
#include "sdl_mixer.h" |
||||
|
||||
#include <assert.h> |
||||
#include <ctype.h> |
||||
#include <stdio.h> |
||||
#include <string.h> |
||||
|
||||
//#include "game.h"
|
||||
|
||||
#include <windows.h> |
||||
|
||||
#define STB_GLEXT_DEFINE "glext_list.h" |
||||
#include "stb_gl.h" |
||||
|
||||
#define STB_DEFINE |
||||
#include "stb.h" |
||||
|
||||
#include "caveview.h" |
||||
|
||||
#define SCALE 2 |
||||
|
||||
void error(char *s) |
||||
{ |
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", s, NULL); |
||||
exit(0); |
||||
} |
||||
|
||||
void ods(char *fmt, ...) |
||||
{ |
||||
char buffer[1000]; |
||||
va_list va; |
||||
va_start(va, fmt); |
||||
vsprintf(buffer, fmt, va); |
||||
va_end(va); |
||||
SDL_Log("%s", buffer); |
||||
} |
||||
|
||||
#define TICKS_PER_SECOND 60 |
||||
|
||||
static SDL_Window *window; |
||||
|
||||
extern void init_game(void); |
||||
extern void draw_main(void); |
||||
extern void process_tick(float dt); |
||||
extern void editor_init(void); |
||||
|
||||
void draw(void) |
||||
{ |
||||
draw_main(); |
||||
SDL_GL_SwapWindow(window); |
||||
} |
||||
|
||||
|
||||
static int initialized=0; |
||||
static float last_dt; |
||||
|
||||
int screen_x,screen_y; |
||||
|
||||
float carried_dt = 0; |
||||
#define TICKRATE 60 |
||||
|
||||
|
||||
int raw_level_time; |
||||
extern void init_game(void); |
||||
extern void draw_main(void); |
||||
|
||||
float global_timer; |
||||
|
||||
int loopmode(float dt, int real, int in_client) |
||||
{ |
||||
float actual_dt = dt; |
||||
|
||||
float jump_timer = dt; |
||||
|
||||
if (!initialized) return 0; |
||||
|
||||
if (!real) |
||||
return 0; |
||||
|
||||
// don't allow more than 6 frames to update at a time
|
||||
if (dt > 0.075) dt = 0.075; |
||||
|
||||
global_timer += dt; |
||||
|
||||
carried_dt += dt; |
||||
while (carried_dt > 1.0/TICKRATE) { |
||||
//update_input();
|
||||
// if the player is dead, stop the sim
|
||||
carried_dt -= 1.0/TICKRATE; |
||||
} |
||||
|
||||
process_tick(dt); |
||||
draw(); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int quit; |
||||
|
||||
//int winproc(void *data, stbwingraph_event *e)
|
||||
|
||||
extern int editor_scale; |
||||
extern void editor_key(enum stbte_action act); |
||||
extern int controls; |
||||
|
||||
void active_control_set(int key) |
||||
{ |
||||
controls |= 1 << key; |
||||
} |
||||
|
||||
void active_control_clear(int key) |
||||
{ |
||||
controls &= ~(1 << key); |
||||
} |
||||
|
||||
extern void update_view(float dx, float dy); |
||||
|
||||
void process_sdl_mouse(SDL_Event *e) |
||||
{ |
||||
update_view((float) e->motion.xrel / screen_x, (float) e->motion.yrel / screen_y); |
||||
} |
||||
|
||||
void process_event(SDL_Event *e) |
||||
{ |
||||
switch (e->type) { |
||||
case SDL_MOUSEMOTION: |
||||
process_sdl_mouse(e); |
||||
break; |
||||
case SDL_MOUSEBUTTONDOWN: |
||||
case SDL_MOUSEBUTTONUP: |
||||
case SDL_MOUSEWHEEL: |
||||
//stbte_mouse_sdl(edit_map, e, 1.0f/editor_scale,1.0f/editor_scale,0,0);
|
||||
break; |
||||
|
||||
case SDL_QUIT: |
||||
quit = 1; |
||||
break; |
||||
|
||||
case SDL_WINDOWEVENT: |
||||
switch (e->window.event) { |
||||
case SDL_WINDOWEVENT_SIZE_CHANGED: |
||||
screen_x = e->window.data1; |
||||
screen_y = e->window.data2; |
||||
loopmode(0,1,0); |
||||
break; |
||||
} |
||||
break; |
||||
|
||||
case SDL_TEXTINPUT: |
||||
switch(e->text.text[0]) { |
||||
#if 0 |
||||
case 27: { |
||||
#if 0 |
||||
int result; |
||||
SDL_ShowCursor(SDL_ENABLE); |
||||
if (MessageBox(e->handle, "Exit CLTT?", "CLTT", MB_OKCANCEL) == IDOK); |
||||
#endif |
||||
{ |
||||
quit = 1; |
||||
break; |
||||
} |
||||
//SDL_ShowCursor(SDL_DISABLE);
|
||||
break; |
||||
} |
||||
#endif |
||||
} |
||||
break; |
||||
|
||||
case SDL_KEYDOWN: { |
||||
int k = e->key.keysym.sym; |
||||
int s = e->key.keysym.scancode; |
||||
SDL_Keymod mod; |
||||
mod = SDL_GetModState(); |
||||
if (k == SDLK_ESCAPE) { |
||||
#ifndef DO_EDITOR |
||||
quit = 1; |
||||
#endif |
||||
} |
||||
|
||||
if (s == SDL_SCANCODE_D) active_control_set(0); |
||||
if (s == SDL_SCANCODE_A) active_control_set(1); |
||||
if (s == SDL_SCANCODE_W) active_control_set(2); |
||||
if (s == SDL_SCANCODE_S) active_control_set(3); |
||||
if (k == SDLK_SPACE) active_control_set(4);
|
||||
if (s == SDL_SCANCODE_LCTRL) active_control_set(5); |
||||
if (s == SDL_SCANCODE_S) active_control_set(6); |
||||
if (s == SDL_SCANCODE_D) active_control_set(7); |
||||
|
||||
#if 0 |
||||
if (game_mode == GAME_editor) { |
||||
switch (k) { |
||||
case SDLK_RIGHT: editor_key(STBTE_scroll_right); break; |
||||
case SDLK_LEFT : editor_key(STBTE_scroll_left ); break; |
||||
case SDLK_UP : editor_key(STBTE_scroll_up ); break; |
||||
case SDLK_DOWN : editor_key(STBTE_scroll_down ); break; |
||||
} |
||||
switch (s) { |
||||
case SDL_SCANCODE_S: editor_key(STBTE_tool_select); break; |
||||
case SDL_SCANCODE_B: editor_key(STBTE_tool_brush ); break; |
||||
case SDL_SCANCODE_E: editor_key(STBTE_tool_erase ); break; |
||||
case SDL_SCANCODE_R: editor_key(STBTE_tool_rectangle ); break; |
||||
case SDL_SCANCODE_I: editor_key(STBTE_tool_eyedropper); break; |
||||
case SDL_SCANCODE_L: editor_key(STBTE_tool_link); break; |
||||
case SDL_SCANCODE_G: editor_key(STBTE_act_toggle_grid); break; |
||||
} |
||||
if ((e->key.keysym.mod & KMOD_CTRL) && !(e->key.keysym.mod & ~KMOD_CTRL)) { |
||||
switch (s) { |
||||
case SDL_SCANCODE_X: editor_key(STBTE_act_cut ); break; |
||||
case SDL_SCANCODE_C: editor_key(STBTE_act_copy ); break; |
||||
case SDL_SCANCODE_V: editor_key(STBTE_act_paste); break; |
||||
case SDL_SCANCODE_Z: editor_key(STBTE_act_undo ); break; |
||||
case SDL_SCANCODE_Y: editor_key(STBTE_act_redo ); break; |
||||
} |
||||
} |
||||
} |
||||
#endif |
||||
break; |
||||
} |
||||
case SDL_KEYUP: { |
||||
int k = e->key.keysym.sym; |
||||
int s = e->key.keysym.scancode; |
||||
if (s == SDL_SCANCODE_D) active_control_clear(0); |
||||
if (s == SDL_SCANCODE_A) active_control_clear(1); |
||||
if (s == SDL_SCANCODE_W) active_control_clear(2); |
||||
if (s == SDL_SCANCODE_S) active_control_clear(3); |
||||
if (k == SDLK_SPACE) active_control_clear(4);
|
||||
if (s == SDL_SCANCODE_LCTRL) active_control_clear(5); |
||||
if (s == SDL_SCANCODE_S) active_control_clear(6); |
||||
if (s == SDL_SCANCODE_D) active_control_clear(7); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
static SDL_GLContext *context; |
||||
|
||||
static float getTimestep(float minimum_time) |
||||
{ |
||||
float elapsedTime; |
||||
double thisTime; |
||||
static double lastTime = -1; |
||||
|
||||
if (lastTime == -1) |
||||
lastTime = SDL_GetTicks() / 1000.0 - minimum_time; |
||||
|
||||
for(;;) { |
||||
thisTime = SDL_GetTicks() / 1000.0; |
||||
elapsedTime = (float) (thisTime - lastTime); |
||||
if (elapsedTime >= minimum_time) { |
||||
lastTime = thisTime;
|
||||
return elapsedTime; |
||||
} |
||||
// @TODO: compute correct delay
|
||||
SDL_Delay(1); |
||||
} |
||||
} |
||||
|
||||
void APIENTRY gl_debug(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *param) |
||||
{ |
||||
#if 0 |
||||
if (severity == GL_DEBUG_SEVERITY_LOW_ARB) |
||||
return; |
||||
#endif |
||||
ods("%s\n", message); |
||||
} |
||||
|
||||
extern void do_music(int16 *stream, int samples); |
||||
|
||||
extern void foo(void); |
||||
|
||||
void render_init(void); |
||||
|
||||
int is_synchronous_debug; |
||||
void enable_synchronous(void) |
||||
{ |
||||
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); |
||||
is_synchronous_debug = 1; |
||||
} |
||||
|
||||
void prepare_threads(void); |
||||
|
||||
//void stbwingraph_main(void)
|
||||
int SDL_main(int argc, char **argv) |
||||
{ |
||||
SDL_Init(SDL_INIT_VIDEO); |
||||
|
||||
prepare_threads(); |
||||
|
||||
Mix_Init(0); |
||||
Mix_OpenAudio(48000, AUDIO_S16SYS, 2, 1024); // 1024 bytes = 256 samples =
|
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_RED_SIZE , 8); |
||||
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); |
||||
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE , 8); |
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); |
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); |
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); |
||||
|
||||
#ifdef GL_DEBUG |
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG); |
||||
#endif |
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); |
||||
|
||||
screen_x = 1920; |
||||
screen_y = 1080; |
||||
|
||||
window = SDL_CreateWindow("caveview", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, |
||||
screen_x, screen_y, |
||||
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE |
||||
); |
||||
if (!window) error("Couldn't create window"); |
||||
|
||||
context = SDL_GL_CreateContext(window); |
||||
if (!context) error("Couldn't create context"); |
||||
|
||||
SDL_GL_MakeCurrent(window, context); // is this true by default?
|
||||
|
||||
// if (!IsDebuggerPresent())
|
||||
SDL_SetRelativeMouseMode(SDL_TRUE); |
||||
|
||||
stbgl_initExtensions(); |
||||
|
||||
#ifdef GL_DEBUG |
||||
if (glDebugMessageCallbackARB) { |
||||
glDebugMessageCallbackARB(gl_debug, NULL); |
||||
|
||||
enable_synchronous(); |
||||
} |
||||
#endif |
||||
|
||||
SDL_GL_SetSwapInterval(0); // only when profiling
|
||||
|
||||
render_init(); |
||||
mesh_init(); |
||||
world_init(); |
||||
|
||||
init_game(); |
||||
//editor_init();
|
||||
initialized = 1; |
||||
|
||||
while (!quit) { |
||||
SDL_Event e; |
||||
while (SDL_PollEvent(&e)) |
||||
process_event(&e); |
||||
|
||||
loopmode(getTimestep(0.0166f/8), 1, 1); |
||||
quit=quit; |
||||
} |
||||
//music_end();
|
||||
|
||||
return 0; |
||||
} |
Loading…
Reference in New Issue