mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 01:58:19 +00:00
continued the cleanup
This commit is contained in:
parent
99f0a47d6b
commit
906ece7894
|
@ -80,26 +80,6 @@ struct animation {
|
||||||
instance:sequence attach = attach
|
instance:sequence attach = attach
|
||||||
}
|
}
|
||||||
|
|
||||||
struct gui_box {
|
|
||||||
int x = @1
|
|
||||||
int y = @2
|
|
||||||
int w = @3
|
|
||||||
int h = @4
|
|
||||||
}
|
|
||||||
|
|
||||||
struct gui_compositebox {
|
|
||||||
instance:gui_box rect = rect
|
|
||||||
instance:gui_box center = center
|
|
||||||
}
|
|
||||||
|
|
||||||
struct gui_widgets {
|
|
||||||
array:gui_compositebox boxes = boxes.*
|
|
||||||
array:gui_box misc = misc.*
|
|
||||||
}
|
|
||||||
|
|
||||||
const array:int gui_box = gui.boxes.*
|
|
||||||
const array:int gui_misc = gui.misc.*
|
|
||||||
|
|
||||||
struct data_container {
|
struct data_container {
|
||||||
array:image images = images.*
|
array:image images = images.*
|
||||||
array:spriteset spritesets = sprites.*
|
array:spriteset spritesets = sprites.*
|
||||||
|
@ -111,7 +91,6 @@ struct data_container {
|
||||||
array:soundset sounds = sounds.*
|
array:soundset sounds = sounds.*
|
||||||
array:animation animations = animations.*
|
array:animation animations = animations.*
|
||||||
|
|
||||||
instance:gui_widgets gui = gui
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const array:int weapon = weapons.*
|
const array:int weapon = weapons.*
|
||||||
|
|
|
@ -215,6 +215,10 @@ sounds {
|
||||||
|
|
||||||
|
|
||||||
images {
|
images {
|
||||||
|
null {
|
||||||
|
filename ""
|
||||||
|
}
|
||||||
|
|
||||||
game {
|
game {
|
||||||
filename "data/game.png"
|
filename "data/game.png"
|
||||||
}
|
}
|
||||||
|
@ -663,7 +667,7 @@ sprites {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tees images.char_default 8 4 {
|
tees images.null 8 4 {
|
||||||
tee_body 0 0 3 3
|
tee_body 0 0 3 3
|
||||||
tee_body_outline 3 0 3 3
|
tee_body_outline 3 0 3 3
|
||||||
tee_foot 6 1 2 1
|
tee_foot 6 1 2 1
|
||||||
|
@ -827,77 +831,3 @@ animations {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gui {
|
|
||||||
boxes {
|
|
||||||
button {
|
|
||||||
rect 0 0 48 48
|
|
||||||
center 16 16 16 16
|
|
||||||
}
|
|
||||||
|
|
||||||
screen_thick {
|
|
||||||
rect 0 384 48 48
|
|
||||||
center 16 400 16 16
|
|
||||||
}
|
|
||||||
|
|
||||||
screen_transparent {
|
|
||||||
rect 48 384 48 48
|
|
||||||
center 64 400 16 16
|
|
||||||
}
|
|
||||||
|
|
||||||
screen_info {
|
|
||||||
rect 96 384 48 48
|
|
||||||
center 112 400 16 16
|
|
||||||
}
|
|
||||||
|
|
||||||
screen_textbox {
|
|
||||||
rect 144 384 48 48
|
|
||||||
center 160 400 16 16
|
|
||||||
}
|
|
||||||
|
|
||||||
screen_list {
|
|
||||||
rect 192 384 48 48
|
|
||||||
center 208 400 16 16
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
misc {
|
|
||||||
button_big_topleft 0 0 16 16
|
|
||||||
button_big_topmid 16 0 16 16
|
|
||||||
button_big_topright 32 0 16 16
|
|
||||||
button_big_midleft 0 16 16 16
|
|
||||||
button_big_midmid 16 16 16 16
|
|
||||||
button_big_midright 32 16 16 16
|
|
||||||
button_big_btmleft 0 32 16 16
|
|
||||||
button_big_btmmid 16 32 16 16
|
|
||||||
button_big_btmright 32 32 16 16
|
|
||||||
slider_big_horiz_begin 0 48 16 16
|
|
||||||
slider_big_horiz_mid 16 48 16 16
|
|
||||||
slider_big_horiz_end 32 48 16 16
|
|
||||||
slider_small_horiz_begin 0 96 16 16
|
|
||||||
slider_small_horiz_mid 16 96 16 16
|
|
||||||
slider_small_horiz_end 32 96 16 16
|
|
||||||
slider_small_vert_begin 48 96 16 16
|
|
||||||
radio_unchecked 64 112 32 32
|
|
||||||
radio_checked 96 112 32 32
|
|
||||||
slider_small_vert_mid 48 112 16 16
|
|
||||||
slider_small_vert_end 48 128 16 16
|
|
||||||
slider_big_vert_begin 48 48 16 16
|
|
||||||
slider_big_handle_vert 64 48 16 32
|
|
||||||
slider_big_handle_horiz 80 64 32 16
|
|
||||||
slider_small_handle_horiz 80 48 16 16
|
|
||||||
slider_big_arrow_left 0 64 16 16
|
|
||||||
slider_big_arrow_up 16 64 16 16
|
|
||||||
slider_big_arrow_right 32 64 16 16
|
|
||||||
slider_big_arrow_down 16 80 16 16
|
|
||||||
slider_small_arrow_left 0 112 16 16
|
|
||||||
slider_small_arrow_up 16 112 16 16
|
|
||||||
slider_small_arrow_right 32 112 16 16
|
|
||||||
slider_small_arrow_down 16 128 16 16
|
|
||||||
slider_small_handle_vert 96 48 16 16
|
|
||||||
slider_big_vert_mid 48 64 16 16
|
|
||||||
slider_big_vert_end 48 80 16 16
|
|
||||||
checkbox_unchecked 64 112 32 32
|
|
||||||
checkbox_checked 96 112 32 32
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
14
src/game/client/gc_anim.h
Normal file
14
src/game/client/gc_anim.h
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
struct animstate
|
||||||
|
{
|
||||||
|
keyframe body;
|
||||||
|
keyframe back_foot;
|
||||||
|
keyframe front_foot;
|
||||||
|
keyframe attach;
|
||||||
|
};
|
||||||
|
|
||||||
|
void anim_seq_eval(sequence *seq, float time, keyframe *frame);
|
||||||
|
void anim_eval(animation *anim, float time, animstate *state);
|
||||||
|
void anim_add_keyframe(keyframe *seq, keyframe *added, float amount);
|
||||||
|
void anim_add(animstate *state, animstate *added, float amount);
|
||||||
|
void anim_eval_add(animstate *state, animation *anim, float time, float amount);
|
File diff suppressed because it is too large
Load diff
93
src/game/client/gc_client.h
Normal file
93
src/game/client/gc_client.h
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
#include <game/g_vmath.h>
|
||||||
|
#include <game/g_protocol.h>
|
||||||
|
#include <game/g_game.h>
|
||||||
|
|
||||||
|
#include <game/client/gc_render.h>
|
||||||
|
|
||||||
|
// sound channels
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CHN_GUI=0,
|
||||||
|
CHN_MUSIC,
|
||||||
|
CHN_WORLD,
|
||||||
|
CHN_GLOBAL,
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct data_container *data;
|
||||||
|
|
||||||
|
extern vec2 mouse_pos;
|
||||||
|
extern vec2 local_character_pos;
|
||||||
|
extern vec2 local_target_pos;
|
||||||
|
|
||||||
|
// snap pointers
|
||||||
|
extern const obj_player_character *local_character;
|
||||||
|
extern const obj_player_character *local_prev_character;
|
||||||
|
extern const obj_player_info *local_info;
|
||||||
|
extern const obj_flag *flags[2];
|
||||||
|
extern const obj_game *gameobj;
|
||||||
|
|
||||||
|
// predicted players
|
||||||
|
extern player_core predicted_prev_player;
|
||||||
|
extern player_core predicted_player;
|
||||||
|
|
||||||
|
// input
|
||||||
|
extern int picked_up_weapon;
|
||||||
|
extern player_input input_data;
|
||||||
|
extern int input_target_lock;
|
||||||
|
|
||||||
|
// chat
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CHATMODE_NONE=0,
|
||||||
|
CHATMODE_ALL,
|
||||||
|
CHATMODE_TEAM,
|
||||||
|
CHATMODE_CONSOLE,
|
||||||
|
CHATMODE_REMOTECONSOLE,
|
||||||
|
};
|
||||||
|
|
||||||
|
extern int chat_mode;
|
||||||
|
void chat_add_line(int client_id, int team, const char *line);
|
||||||
|
void chat_reset();
|
||||||
|
|
||||||
|
// client data
|
||||||
|
struct client_data
|
||||||
|
{
|
||||||
|
char name[64];
|
||||||
|
char skin_name[64];
|
||||||
|
int skin_id;
|
||||||
|
int skin_color;
|
||||||
|
int team;
|
||||||
|
int emoticon;
|
||||||
|
int emoticon_start;
|
||||||
|
player_core predicted;
|
||||||
|
|
||||||
|
tee_render_info skin_info; // this is what the server reports
|
||||||
|
tee_render_info render_info; // this is what we use
|
||||||
|
|
||||||
|
void update_render_info();
|
||||||
|
};
|
||||||
|
|
||||||
|
extern client_data client_datas[MAX_CLIENTS];
|
||||||
|
|
||||||
|
// kill messages
|
||||||
|
struct killmsg
|
||||||
|
{
|
||||||
|
int weapon;
|
||||||
|
int victim;
|
||||||
|
int killer;
|
||||||
|
int mode_special; // for CTF, if the guy is carrying a flag for example
|
||||||
|
int tick;
|
||||||
|
};
|
||||||
|
|
||||||
|
const int killmsg_max = 5;
|
||||||
|
extern killmsg killmsgs[killmsg_max];
|
||||||
|
extern int killmsg_current;
|
||||||
|
|
||||||
|
// various helpers
|
||||||
|
void snd_play_random(int chn, int setid, float vol, vec2 pos);
|
||||||
|
void process_events(int snaptype);
|
||||||
|
void clear_object_pointers();
|
||||||
|
void reset_projectile_particles();
|
||||||
|
void send_info(bool start);
|
||||||
|
|
||||||
|
void effect_air_jump(vec2 pos);
|
500
src/game/client/gc_hooks.cpp
Normal file
500
src/game/client/gc_hooks.cpp
Normal file
|
@ -0,0 +1,500 @@
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <engine/e_interface.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <engine/e_config.h>
|
||||||
|
#include <engine/client/ec_font.h>
|
||||||
|
};
|
||||||
|
|
||||||
|
#include <game/generated/gc_data.h>
|
||||||
|
#include <game/g_game.h>
|
||||||
|
#include <game/g_version.h>
|
||||||
|
|
||||||
|
#include "gc_client.h"
|
||||||
|
#include "gc_skin.h"
|
||||||
|
#include "gc_render.h"
|
||||||
|
#include "gc_mapres_image.h"
|
||||||
|
#include "gc_mapres_tilemap.h"
|
||||||
|
|
||||||
|
extern unsigned char internal_data[];
|
||||||
|
|
||||||
|
extern void menu_init();
|
||||||
|
extern bool menu_active;
|
||||||
|
extern bool menu_game_active;
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" void modc_init()
|
||||||
|
{
|
||||||
|
static FONT_SET default_font;
|
||||||
|
|
||||||
|
int before = gfx_memory_usage();
|
||||||
|
font_set_load(&default_font, "fonts/default_font%d.tfnt", "fonts/default_font%d.png", "fonts/default_font%d_b.png", 14, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 36);
|
||||||
|
dbg_msg("font", "gfx memory usage: %d", gfx_memory_usage()-before);
|
||||||
|
|
||||||
|
gfx_text_set_default_font(&default_font);
|
||||||
|
|
||||||
|
menu_init();
|
||||||
|
|
||||||
|
// setup sound channels
|
||||||
|
snd_set_channel(CHN_GUI, 1.0f, 0.0f);
|
||||||
|
snd_set_channel(CHN_MUSIC, 1.0f, 0.0f);
|
||||||
|
snd_set_channel(CHN_WORLD, 0.9f, 1.0f);
|
||||||
|
snd_set_channel(CHN_GLOBAL, 1.0f, 0.0f);
|
||||||
|
|
||||||
|
// load the data container
|
||||||
|
data = load_data_from_memory(internal_data);
|
||||||
|
|
||||||
|
// TODO: should be removed
|
||||||
|
snd_set_listener_pos(0.0f, 0.0f);
|
||||||
|
|
||||||
|
float total = data->num_sounds+data->num_images;
|
||||||
|
float current = 0;
|
||||||
|
|
||||||
|
// load textures
|
||||||
|
for(int i = 0; i < data->num_images; i++)
|
||||||
|
{
|
||||||
|
render_loading(current/total);
|
||||||
|
data->images[i].id = gfx_load_texture(data->images[i].filename, IMG_AUTO);
|
||||||
|
current++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// load sounds
|
||||||
|
for(int s = 0; s < data->num_sounds; s++)
|
||||||
|
{
|
||||||
|
render_loading(current/total);
|
||||||
|
for(int i = 0; i < data->sounds[s].num_sounds; i++)
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
//if (strcmp(data->sounds[s].sounds[i].filename + strlen(data->sounds[s].sounds[i].filename) - 3, ".wv") == 0)
|
||||||
|
id = snd_load_wv(data->sounds[s].sounds[i].filename);
|
||||||
|
//else
|
||||||
|
// id = snd_load_wav(data->sounds[s].sounds[i].filename);
|
||||||
|
|
||||||
|
data->sounds[s].sounds[i].id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
current++;
|
||||||
|
}
|
||||||
|
|
||||||
|
skin_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void modc_entergame()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void modc_shutdown()
|
||||||
|
{
|
||||||
|
// shutdown the menu
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
player_core predicted_prev_player;
|
||||||
|
player_core predicted_player;
|
||||||
|
static int predicted_tick = 0;
|
||||||
|
static int last_new_predicted_tick = -1;
|
||||||
|
|
||||||
|
extern "C" void modc_predict()
|
||||||
|
{
|
||||||
|
player_core before_prev_player = predicted_prev_player;
|
||||||
|
player_core before_player = predicted_player;
|
||||||
|
|
||||||
|
// repredict player
|
||||||
|
world_core world;
|
||||||
|
int local_cid = -1;
|
||||||
|
|
||||||
|
// search for players
|
||||||
|
for(int i = 0; i < snap_num_items(SNAP_CURRENT); i++)
|
||||||
|
{
|
||||||
|
SNAP_ITEM item;
|
||||||
|
const void *data = snap_get_item(SNAP_CURRENT, i, &item);
|
||||||
|
int client_id = item.id;
|
||||||
|
|
||||||
|
if(item.type == OBJTYPE_PLAYER_CHARACTER)
|
||||||
|
{
|
||||||
|
const obj_player_character *character = (const obj_player_character *)data;
|
||||||
|
client_datas[client_id].predicted.world = &world;
|
||||||
|
world.players[client_id] = &client_datas[client_id].predicted;
|
||||||
|
|
||||||
|
client_datas[client_id].predicted.read(character);
|
||||||
|
}
|
||||||
|
else if(item.type == OBJTYPE_PLAYER_INFO)
|
||||||
|
{
|
||||||
|
const obj_player_info *info = (const obj_player_info *)data;
|
||||||
|
if(info->local)
|
||||||
|
local_cid = client_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// predict
|
||||||
|
for(int tick = client_tick()+1; tick <= client_predtick(); tick++)
|
||||||
|
{
|
||||||
|
// fetch the local
|
||||||
|
if(tick == client_predtick() && world.players[local_cid])
|
||||||
|
predicted_prev_player = *world.players[local_cid];
|
||||||
|
|
||||||
|
// first calculate where everyone should move
|
||||||
|
for(int c = 0; c < MAX_CLIENTS; c++)
|
||||||
|
{
|
||||||
|
if(!world.players[c])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
mem_zero(&world.players[c]->input, sizeof(world.players[c]->input));
|
||||||
|
if(local_cid == c)
|
||||||
|
{
|
||||||
|
// apply player input
|
||||||
|
int *input = client_get_input(tick);
|
||||||
|
if(input)
|
||||||
|
world.players[c]->input = *((player_input*)input);
|
||||||
|
}
|
||||||
|
|
||||||
|
world.players[c]->tick();
|
||||||
|
}
|
||||||
|
|
||||||
|
// move all players and quantize their data
|
||||||
|
for(int c = 0; c < MAX_CLIENTS; c++)
|
||||||
|
{
|
||||||
|
if(!world.players[c])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: this should be moved into the g_game
|
||||||
|
// but not done to preserve the nethash
|
||||||
|
if(length(world.players[c]->vel) > 150.0f)
|
||||||
|
world.players[c]->vel = normalize(world.players[c]->vel) * 150.0f;
|
||||||
|
|
||||||
|
world.players[c]->move();
|
||||||
|
world.players[c]->quantize();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tick > last_new_predicted_tick)
|
||||||
|
{
|
||||||
|
last_new_predicted_tick = tick;
|
||||||
|
|
||||||
|
if(local_cid != -1 && world.players[local_cid])
|
||||||
|
{
|
||||||
|
vec2 pos = world.players[local_cid]->pos;
|
||||||
|
int events = world.players[local_cid]->triggered_events;
|
||||||
|
if(events&COREEVENT_GROUND_JUMP) snd_play_random(CHN_WORLD, SOUND_PLAYER_JUMP, 1.0f, pos);
|
||||||
|
if(events&COREEVENT_AIR_JUMP)
|
||||||
|
{
|
||||||
|
effect_air_jump(pos);
|
||||||
|
snd_play_random(CHN_WORLD, SOUND_PLAYER_AIRJUMP, 1.0f, pos);
|
||||||
|
}
|
||||||
|
//if(events&COREEVENT_HOOK_LAUNCH) snd_play_random(CHN_WORLD, SOUND_HOOK_LOOP, 1.0f, pos);
|
||||||
|
if(events&COREEVENT_HOOK_ATTACH_PLAYER) snd_play_random(CHN_WORLD, SOUND_HOOK_ATTACH_PLAYER, 1.0f, pos);
|
||||||
|
if(events&COREEVENT_HOOK_ATTACH_GROUND) snd_play_random(CHN_WORLD, SOUND_HOOK_ATTACH_GROUND, 1.0f, pos);
|
||||||
|
//if(events&COREEVENT_HOOK_RETRACT) snd_play_random(CHN_WORLD, SOUND_PLAYER_JUMP, 1.0f, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
dbg_msg("predict", "%d %d %d", tick,
|
||||||
|
(int)world.players[c]->pos.x, (int)world.players[c]->pos.y,
|
||||||
|
(int)world.players[c]->vel.x, (int)world.players[c]->vel.y);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tick == client_predtick() && world.players[local_cid])
|
||||||
|
predicted_player = *world.players[local_cid];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(config.debug && predicted_tick == client_predtick())
|
||||||
|
{
|
||||||
|
if(predicted_player.pos.x != before_player.pos.x ||
|
||||||
|
predicted_player.pos.y != before_player.pos.y)
|
||||||
|
{
|
||||||
|
dbg_msg("client", "prediction error, (%d %d) (%d %d)",
|
||||||
|
(int)before_player.pos.x, (int)before_player.pos.y,
|
||||||
|
(int)predicted_player.pos.x, (int)predicted_player.pos.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(predicted_prev_player.pos.x != before_prev_player.pos.x ||
|
||||||
|
predicted_prev_player.pos.y != before_prev_player.pos.y)
|
||||||
|
{
|
||||||
|
dbg_msg("client", "prediction error, prev (%d %d) (%d %d)",
|
||||||
|
(int)before_prev_player.pos.x, (int)before_prev_player.pos.y,
|
||||||
|
(int)predicted_prev_player.pos.x, (int)predicted_prev_player.pos.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
predicted_tick = client_predtick();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" void modc_newsnapshot()
|
||||||
|
{
|
||||||
|
static int snapshot_count = 0;
|
||||||
|
snapshot_count++;
|
||||||
|
|
||||||
|
process_events(SNAP_CURRENT);
|
||||||
|
|
||||||
|
if(config.dbg_stress)
|
||||||
|
{
|
||||||
|
if((client_tick()%250) == 0)
|
||||||
|
{
|
||||||
|
msg_pack_start(MSG_SAY, MSGFLAG_VITAL);
|
||||||
|
msg_pack_int(-1);
|
||||||
|
msg_pack_string("galenskap!!!!", 512);
|
||||||
|
msg_pack_end();
|
||||||
|
client_send_msg();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clear_object_pointers();
|
||||||
|
|
||||||
|
// setup world view
|
||||||
|
{
|
||||||
|
// 1. fetch local player
|
||||||
|
// 2. set him to the center
|
||||||
|
int num = snap_num_items(SNAP_CURRENT);
|
||||||
|
for(int i = 0; i < num; i++)
|
||||||
|
{
|
||||||
|
SNAP_ITEM item;
|
||||||
|
const void *data = snap_get_item(SNAP_CURRENT, i, &item);
|
||||||
|
|
||||||
|
if(item.type == OBJTYPE_PLAYER_INFO)
|
||||||
|
{
|
||||||
|
const obj_player_info *info = (const obj_player_info *)data;
|
||||||
|
|
||||||
|
client_datas[info->clientid].team = info->team;
|
||||||
|
|
||||||
|
if(info->local)
|
||||||
|
{
|
||||||
|
local_info = info;
|
||||||
|
const void *data = snap_find_item(SNAP_CURRENT, OBJTYPE_PLAYER_CHARACTER, item.id);
|
||||||
|
if(data)
|
||||||
|
{
|
||||||
|
local_character = (const obj_player_character *)data;
|
||||||
|
local_character_pos = vec2(local_character->x, local_character->y);
|
||||||
|
|
||||||
|
const void *p = snap_find_item(SNAP_PREV, OBJTYPE_PLAYER_CHARACTER, item.id);
|
||||||
|
if(p)
|
||||||
|
local_prev_character = (obj_player_character *)p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(item.type == OBJTYPE_GAME)
|
||||||
|
gameobj = (obj_game *)data;
|
||||||
|
else if(item.type == OBJTYPE_FLAG)
|
||||||
|
{
|
||||||
|
flags[item.id%2] = (const obj_flag *)data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||||
|
client_datas[i].update_render_info();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" void modc_render()
|
||||||
|
{
|
||||||
|
// this should be moved around abit
|
||||||
|
if(client_state() == CLIENTSTATE_ONLINE)
|
||||||
|
{
|
||||||
|
render_game();
|
||||||
|
|
||||||
|
// handle team switching
|
||||||
|
// TODO: FUGLY!!!
|
||||||
|
if(config.cl_team != -10)
|
||||||
|
{
|
||||||
|
msg_pack_start(MSG_SETTEAM, MSGFLAG_VITAL);
|
||||||
|
msg_pack_int(config.cl_team);
|
||||||
|
msg_pack_end();
|
||||||
|
client_send_msg();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // if (client_state() != CLIENTSTATE_CONNECTING && client_state() != CLIENTSTATE_LOADING)
|
||||||
|
{
|
||||||
|
menu_render();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
config.cl_team = -10;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" int modc_snap_input(int *data)
|
||||||
|
{
|
||||||
|
picked_up_weapon = -1;
|
||||||
|
|
||||||
|
if(!input_target_lock)
|
||||||
|
{
|
||||||
|
input_data.target_x = (int)mouse_pos.x;
|
||||||
|
input_data.target_y = (int)mouse_pos.y;
|
||||||
|
|
||||||
|
if(!input_data.target_x && !input_data.target_y)
|
||||||
|
input_data.target_y = 1;
|
||||||
|
}
|
||||||
|
input_target_lock = 0;
|
||||||
|
|
||||||
|
if(chat_mode != CHATMODE_NONE)
|
||||||
|
input_data.state = STATE_CHATTING;
|
||||||
|
else if(menu_active)
|
||||||
|
input_data.state = STATE_IN_MENU;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
input_data.state = STATE_PLAYING;
|
||||||
|
input_data.left = inp_key_state(config.key_move_left);
|
||||||
|
input_data.right = inp_key_state(config.key_move_right);
|
||||||
|
input_data.hook = inp_key_state(config.key_hook);
|
||||||
|
input_data.jump = inp_key_state(config.key_jump);
|
||||||
|
}
|
||||||
|
|
||||||
|
// stress testing
|
||||||
|
if(config.dbg_stress)
|
||||||
|
{
|
||||||
|
float t = client_localtime();
|
||||||
|
mem_zero(&input_data, sizeof(input_data));
|
||||||
|
|
||||||
|
input_data.left = ((int)t/2)&1;
|
||||||
|
input_data.right = ((int)t/2+1)&1;
|
||||||
|
input_data.jump = ((int)t);
|
||||||
|
input_data.fire = ((int)(t*10));
|
||||||
|
input_data.hook = ((int)(t*2))&1;
|
||||||
|
input_data.wanted_weapon = ((int)t)%NUM_WEAPONS;
|
||||||
|
input_data.target_x = (int)(sinf(t*3)*100.0f);
|
||||||
|
input_data.target_y = (int)(cosf(t*3)*100.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy and return size
|
||||||
|
mem_copy(data, &input_data, sizeof(input_data));
|
||||||
|
return sizeof(input_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void menu_do_disconnected();
|
||||||
|
void menu_do_connecting();
|
||||||
|
void menu_do_connected();
|
||||||
|
|
||||||
|
extern "C" void modc_statechange(int state, int old)
|
||||||
|
{
|
||||||
|
clear_object_pointers();
|
||||||
|
|
||||||
|
if(state == CLIENTSTATE_OFFLINE)
|
||||||
|
{
|
||||||
|
menu_do_disconnected();
|
||||||
|
menu_game_active = false;
|
||||||
|
}
|
||||||
|
else if(state == CLIENTSTATE_LOADING)
|
||||||
|
menu_do_connecting();
|
||||||
|
else if(state == CLIENTSTATE_CONNECTING)
|
||||||
|
menu_do_connecting();
|
||||||
|
else if (state == CLIENTSTATE_ONLINE)
|
||||||
|
{
|
||||||
|
menu_active = false;
|
||||||
|
menu_game_active = true;
|
||||||
|
//snapshot_count = 0;
|
||||||
|
|
||||||
|
menu_do_connected();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void modc_message(int msg)
|
||||||
|
{
|
||||||
|
if(msg == MSG_CHAT)
|
||||||
|
{
|
||||||
|
int cid = msg_unpack_int();
|
||||||
|
int team = msg_unpack_int();
|
||||||
|
const char *message = msg_unpack_string();
|
||||||
|
dbg_msg("message", "chat cid=%d team=%d msg='%s'", cid, team, message);
|
||||||
|
chat_add_line(cid, team, message);
|
||||||
|
|
||||||
|
if(cid >= 0)
|
||||||
|
snd_play(CHN_GUI, data->sounds[SOUND_CHAT_CLIENT].sounds[0].id, 0);
|
||||||
|
else
|
||||||
|
snd_play(CHN_GUI, data->sounds[SOUND_CHAT_SERVER].sounds[0].id, 0);
|
||||||
|
}
|
||||||
|
else if(msg == MSG_SETINFO)
|
||||||
|
{
|
||||||
|
int cid = msg_unpack_int();
|
||||||
|
const char *name = msg_unpack_string();
|
||||||
|
const char *skinname = msg_unpack_string();
|
||||||
|
|
||||||
|
strncpy(client_datas[cid].name, name, 64);
|
||||||
|
strncpy(client_datas[cid].skin_name, skinname, 64);
|
||||||
|
|
||||||
|
int use_custom_color = msg_unpack_int();
|
||||||
|
client_datas[cid].skin_info.color_body = skin_get_color(msg_unpack_int());
|
||||||
|
client_datas[cid].skin_info.color_feet = skin_get_color(msg_unpack_int());
|
||||||
|
client_datas[cid].skin_info.size = 64;
|
||||||
|
|
||||||
|
// find new skin
|
||||||
|
client_datas[cid].skin_id = skin_find(client_datas[cid].skin_name);
|
||||||
|
if(client_datas[cid].skin_id < 0)
|
||||||
|
client_datas[cid].skin_id = 0;
|
||||||
|
|
||||||
|
if(use_custom_color)
|
||||||
|
client_datas[cid].skin_info.texture = skin_get(client_datas[cid].skin_id)->color_texture;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
client_datas[cid].skin_info.texture = skin_get(client_datas[cid].skin_id)->org_texture;
|
||||||
|
client_datas[cid].skin_info.color_body = vec4(1,1,1,1);
|
||||||
|
client_datas[cid].skin_info.color_feet = vec4(1,1,1,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
client_datas[cid].update_render_info();
|
||||||
|
}
|
||||||
|
else if(msg == MSG_WEAPON_PICKUP)
|
||||||
|
{
|
||||||
|
int weapon = msg_unpack_int();
|
||||||
|
|
||||||
|
picked_up_weapon = weapon+1;
|
||||||
|
}
|
||||||
|
else if(msg == MSG_READY_TO_ENTER)
|
||||||
|
{
|
||||||
|
client_entergame();
|
||||||
|
}
|
||||||
|
else if(msg == MSG_KILLMSG)
|
||||||
|
{
|
||||||
|
killmsg_current = (killmsg_current+1)%killmsg_max;
|
||||||
|
killmsgs[killmsg_current].killer = msg_unpack_int();
|
||||||
|
killmsgs[killmsg_current].victim = msg_unpack_int();
|
||||||
|
killmsgs[killmsg_current].weapon = msg_unpack_int();
|
||||||
|
killmsgs[killmsg_current].mode_special = msg_unpack_int();
|
||||||
|
killmsgs[killmsg_current].tick = client_tick();
|
||||||
|
}
|
||||||
|
else if (msg == MSG_EMOTICON)
|
||||||
|
{
|
||||||
|
int cid = msg_unpack_int();
|
||||||
|
int emoticon = msg_unpack_int();
|
||||||
|
client_datas[cid].emoticon = emoticon;
|
||||||
|
client_datas[cid].emoticon_start = client_tick();
|
||||||
|
}
|
||||||
|
else if(msg == MSG_SOUND_GLOBAL)
|
||||||
|
{
|
||||||
|
int soundid = msg_unpack_int();
|
||||||
|
snd_play_random(CHN_GLOBAL, soundid, 1.0f, vec2(0,0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void modc_connected()
|
||||||
|
{
|
||||||
|
// init some stuff
|
||||||
|
col_init(32);
|
||||||
|
|
||||||
|
img_init();
|
||||||
|
tilemap_init();
|
||||||
|
chat_reset();
|
||||||
|
|
||||||
|
reset_projectile_particles();
|
||||||
|
|
||||||
|
clear_object_pointers();
|
||||||
|
last_new_predicted_tick = -1;
|
||||||
|
|
||||||
|
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||||
|
{
|
||||||
|
client_datas[i].name[0] = 0;
|
||||||
|
client_datas[i].team = 0;
|
||||||
|
client_datas[i].emoticon = 0;
|
||||||
|
client_datas[i].emoticon_start = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < killmsg_max; i++)
|
||||||
|
killmsgs[i].tick = -100000;
|
||||||
|
|
||||||
|
send_info(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" const char *modc_net_version() { return TEEWARS_NETVERSION; }
|
|
@ -5,6 +5,12 @@
|
||||||
#include "gc_mapres_image.h"
|
#include "gc_mapres_image.h"
|
||||||
#include "../g_mapres.h"
|
#include "../g_mapres.h"
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
TILEFLAG_VFLIP=1,
|
||||||
|
TILEFLAG_HFLIP=2,
|
||||||
|
};
|
||||||
|
|
||||||
int tilemap_init()
|
int tilemap_init()
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -8,12 +8,6 @@ int tilemap_init();
|
||||||
// renders the tilemaps
|
// renders the tilemaps
|
||||||
void tilemap_render(float scale, int fg);
|
void tilemap_render(float scale, int fg);
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
TILEFLAG_VFLIP=1,
|
|
||||||
TILEFLAG_HFLIP=2,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct mapres_tilemap
|
struct mapres_tilemap
|
||||||
{
|
{
|
||||||
int image;
|
int image;
|
||||||
|
|
|
@ -23,6 +23,7 @@ extern "C" {
|
||||||
|
|
||||||
#include "../generated/gc_data.h"
|
#include "../generated/gc_data.h"
|
||||||
#include "gc_render.h"
|
#include "gc_render.h"
|
||||||
|
#include "gc_anim.h"
|
||||||
#include "gc_skin.h"
|
#include "gc_skin.h"
|
||||||
#include "gc_ui.h"
|
#include "gc_ui.h"
|
||||||
#include <mastersrv/mastersrv.h>
|
#include <mastersrv/mastersrv.h>
|
||||||
|
@ -73,11 +74,6 @@ enum
|
||||||
PAGE_SYSTEM,
|
PAGE_SYSTEM,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void select_sprite(int id, int flags=0, int sx=0, int sy=0);
|
|
||||||
|
|
||||||
extern void draw_round_rect_ext(float x, float y, float w, float h, float r, int corners);
|
|
||||||
extern void draw_round_rect(float x, float y, float w, float h, float r);
|
|
||||||
|
|
||||||
static void ui_draw_rect(const RECT *r, vec4 color, int corners, float rounding)
|
static void ui_draw_rect(const RECT *r, vec4 color, int corners, float rounding)
|
||||||
{
|
{
|
||||||
gfx_texture_set(-1);
|
gfx_texture_set(-1);
|
||||||
|
@ -259,12 +255,6 @@ int ui_do_edit_box(void *id, const RECT *rect, char *str, int str_size, bool hid
|
||||||
r = 1;
|
r = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int box_type;
|
|
||||||
if (ui_active_item() == id || ui_hot_item() == id || ui_last_active_item() == id)
|
|
||||||
box_type = GUI_BOX_SCREEN_INFO;
|
|
||||||
else
|
|
||||||
box_type = GUI_BOX_SCREEN_TEXTBOX;
|
|
||||||
|
|
||||||
bool just_got_active = false;
|
bool just_got_active = false;
|
||||||
|
|
||||||
if(ui_active_item() == id)
|
if(ui_active_item() == id)
|
||||||
|
@ -1972,7 +1962,7 @@ int menu2_render()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void modmenu_render()
|
void menu_render()
|
||||||
{
|
{
|
||||||
static int mouse_x = 0;
|
static int mouse_x = 0;
|
||||||
static int mouse_y = 0;
|
static int mouse_y = 0;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||||
#ifndef __MENU_H
|
#ifndef __MENU_H
|
||||||
#define __MENU_H
|
#define __MENU_H
|
||||||
|
/*
|
||||||
void draw_image_button(void *id, const char *text, int checked, float x, float y, float w, float h, void *extra);
|
void draw_image_button(void *id, const char *text, int checked, float x, float y, float w, float h, void *extra);
|
||||||
void draw_single_part_button(void *id, const char *text, int checked, float x, float y, float w, float h, void *extra);
|
void draw_single_part_button(void *id, const char *text, int checked, float x, float y, float w, float h, void *extra);
|
||||||
void draw_menu_button(void *id, const char *text, int checked, float x, float y, float w, float h, void *extra);
|
void draw_menu_button(void *id, const char *text, int checked, float x, float y, float w, float h, void *extra);
|
||||||
|
@ -12,5 +12,5 @@ int ui_do_edit_box(void *id, float x, float y, float w, float h, char *str, int
|
||||||
int ui_do_check_box(void *id, float x, float y, float w, float h, int value);
|
int ui_do_check_box(void *id, float x, float y, float w, float h, int value);
|
||||||
int do_scroll_bar_horiz(void *id, float x, float y, float width, int steps, int last_index);
|
int do_scroll_bar_horiz(void *id, float x, float y, float width, int steps, int last_index);
|
||||||
int do_scroll_bar_vert(void *id, float x, float y, float height, int steps, int last_index);
|
int do_scroll_bar_vert(void *id, float x, float y, float height, int steps, int last_index);
|
||||||
|
*/
|
||||||
#endif
|
#endif
|
||||||
|
|
237
src/game/client/gc_render.cpp
Normal file
237
src/game/client/gc_render.cpp
Normal file
|
@ -0,0 +1,237 @@
|
||||||
|
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||||
|
#include <math.h>
|
||||||
|
#include <engine/e_interface.h>
|
||||||
|
#include <engine/e_config.h>
|
||||||
|
#include "../generated/gc_data.h"
|
||||||
|
#include "../g_protocol.h"
|
||||||
|
#include "../g_math.h"
|
||||||
|
#include "gc_render.h"
|
||||||
|
#include "gc_anim.h"
|
||||||
|
#include "gc_client.h"
|
||||||
|
|
||||||
|
static float sprite_w_scale;
|
||||||
|
static float sprite_h_scale;
|
||||||
|
|
||||||
|
void select_sprite(sprite *spr, int flags, int sx, int sy)
|
||||||
|
{
|
||||||
|
int x = spr->x+sx;
|
||||||
|
int y = spr->y+sy;
|
||||||
|
int w = spr->w;
|
||||||
|
int h = spr->h;
|
||||||
|
int cx = spr->set->gridx;
|
||||||
|
int cy = spr->set->gridy;
|
||||||
|
|
||||||
|
float f = sqrtf(h*h + w*w);
|
||||||
|
sprite_w_scale = w/f;
|
||||||
|
sprite_h_scale = h/f;
|
||||||
|
|
||||||
|
float x1 = x/(float)cx;
|
||||||
|
float x2 = (x+w)/(float)cx;
|
||||||
|
float y1 = y/(float)cy;
|
||||||
|
float y2 = (y+h)/(float)cy;
|
||||||
|
float temp = 0;
|
||||||
|
|
||||||
|
if(flags&SPRITE_FLAG_FLIP_Y)
|
||||||
|
{
|
||||||
|
temp = y1;
|
||||||
|
y1 = y2;
|
||||||
|
y2 = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(flags&SPRITE_FLAG_FLIP_X)
|
||||||
|
{
|
||||||
|
temp = x1;
|
||||||
|
x1 = x2;
|
||||||
|
x2 = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx_quads_setsubset(x1, y1, x2, y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void select_sprite(int id, int flags, int sx, int sy)
|
||||||
|
{
|
||||||
|
if(id < 0 || id > data->num_sprites)
|
||||||
|
return;
|
||||||
|
select_sprite(&data->sprites[id], flags, sx, sy);
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_sprite(float x, float y, float size)
|
||||||
|
{
|
||||||
|
gfx_quads_draw(x, y, size*sprite_w_scale, size*sprite_h_scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void draw_round_rect_ext(float x, float y, float w, float h, float r, int corners)
|
||||||
|
{
|
||||||
|
int num = 8;
|
||||||
|
for(int i = 0; i < num; i+=2)
|
||||||
|
{
|
||||||
|
float a1 = i/(float)num * pi/2;
|
||||||
|
float a2 = (i+1)/(float)num * pi/2;
|
||||||
|
float a3 = (i+2)/(float)num * pi/2;
|
||||||
|
float ca1 = cosf(a1);
|
||||||
|
float ca2 = cosf(a2);
|
||||||
|
float ca3 = cosf(a3);
|
||||||
|
float sa1 = sinf(a1);
|
||||||
|
float sa2 = sinf(a2);
|
||||||
|
float sa3 = sinf(a3);
|
||||||
|
|
||||||
|
if(corners&1) // TL
|
||||||
|
gfx_quads_draw_freeform(
|
||||||
|
x+r, y+r,
|
||||||
|
x+(1-ca1)*r, y+(1-sa1)*r,
|
||||||
|
x+(1-ca3)*r, y+(1-sa3)*r,
|
||||||
|
x+(1-ca2)*r, y+(1-sa2)*r);
|
||||||
|
|
||||||
|
if(corners&2) // TR
|
||||||
|
gfx_quads_draw_freeform(
|
||||||
|
x+w-r, y+r,
|
||||||
|
x+w-r+ca1*r, y+(1-sa1)*r,
|
||||||
|
x+w-r+ca3*r, y+(1-sa3)*r,
|
||||||
|
x+w-r+ca2*r, y+(1-sa2)*r);
|
||||||
|
|
||||||
|
if(corners&4) // BL
|
||||||
|
gfx_quads_draw_freeform(
|
||||||
|
x+r, y+h-r,
|
||||||
|
x+(1-ca1)*r, y+h-r+sa1*r,
|
||||||
|
x+(1-ca3)*r, y+h-r+sa3*r,
|
||||||
|
x+(1-ca2)*r, y+h-r+sa2*r);
|
||||||
|
|
||||||
|
if(corners&8) // BR
|
||||||
|
gfx_quads_draw_freeform(
|
||||||
|
x+w-r, y+h-r,
|
||||||
|
x+w-r+ca1*r, y+h-r+sa1*r,
|
||||||
|
x+w-r+ca3*r, y+h-r+sa3*r,
|
||||||
|
x+w-r+ca2*r, y+h-r+sa2*r);
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx_quads_drawTL(x+r, y+r, w-r*2, h-r*2); // center
|
||||||
|
gfx_quads_drawTL(x+r, y, w-r*2, r); // top
|
||||||
|
gfx_quads_drawTL(x+r, y+h-r, w-r*2, r); // bottom
|
||||||
|
gfx_quads_drawTL(x, y+r, r, h-r*2); // left
|
||||||
|
gfx_quads_drawTL(x+w-r, y+r, r, h-r*2); // right
|
||||||
|
|
||||||
|
if(!(corners&1)) gfx_quads_drawTL(x, y, r, r); // TL
|
||||||
|
if(!(corners&2)) gfx_quads_drawTL(x+w, y, -r, r); // TR
|
||||||
|
if(!(corners&4)) gfx_quads_drawTL(x, y+h, r, -r); // BL
|
||||||
|
if(!(corners&8)) gfx_quads_drawTL(x+w, y+h, -r, -r); // BR
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_round_rect(float x, float y, float w, float h, float r)
|
||||||
|
{
|
||||||
|
draw_round_rect_ext(x,y,w,h,r,0xf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void render_tee(animstate *anim, tee_render_info *info, int emote, vec2 dir, vec2 pos)
|
||||||
|
{
|
||||||
|
vec2 direction = dir;
|
||||||
|
vec2 position = pos;
|
||||||
|
|
||||||
|
//gfx_texture_set(data->images[IMAGE_CHAR_DEFAULT].id);
|
||||||
|
gfx_texture_set(info->texture);
|
||||||
|
gfx_quads_begin();
|
||||||
|
//gfx_quads_draw(pos.x, pos.y-128, 128, 128);
|
||||||
|
|
||||||
|
// first pass we draw the outline
|
||||||
|
// second pass we draw the filling
|
||||||
|
for(int p = 0; p < 2; p++)
|
||||||
|
{
|
||||||
|
int outline = p==0 ? 1 : 0;
|
||||||
|
|
||||||
|
for(int f = 0; f < 2; f++)
|
||||||
|
{
|
||||||
|
float animscale = info->size * 1.0f/64.0f;
|
||||||
|
float basesize = info->size;
|
||||||
|
if(f == 1)
|
||||||
|
{
|
||||||
|
gfx_quads_setrotation(anim->body.angle*pi*2);
|
||||||
|
|
||||||
|
// draw body
|
||||||
|
gfx_setcolor(info->color_body.r, info->color_body.g, info->color_body.b, info->color_body.a);
|
||||||
|
vec2 body_pos = position + vec2(anim->body.x, anim->body.y)*animscale;
|
||||||
|
select_sprite(outline?SPRITE_TEE_BODY_OUTLINE:SPRITE_TEE_BODY, 0, 0, 0);
|
||||||
|
gfx_quads_draw(body_pos.x, body_pos.y, basesize, basesize);
|
||||||
|
|
||||||
|
// draw eyes
|
||||||
|
if(p == 1)
|
||||||
|
{
|
||||||
|
switch (emote)
|
||||||
|
{
|
||||||
|
case EMOTE_PAIN:
|
||||||
|
select_sprite(SPRITE_TEE_EYE_PAIN, 0, 0, 0);
|
||||||
|
break;
|
||||||
|
case EMOTE_HAPPY:
|
||||||
|
select_sprite(SPRITE_TEE_EYE_HAPPY, 0, 0, 0);
|
||||||
|
break;
|
||||||
|
case EMOTE_SURPRISE:
|
||||||
|
select_sprite(SPRITE_TEE_EYE_SURPRISE, 0, 0, 0);
|
||||||
|
break;
|
||||||
|
case EMOTE_ANGRY:
|
||||||
|
select_sprite(SPRITE_TEE_EYE_ANGRY, 0, 0, 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
select_sprite(SPRITE_TEE_EYE_NORMAL, 0, 0, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
float eyescale = basesize*0.40f;
|
||||||
|
float h = emote == EMOTE_BLINK ? basesize*0.15f : eyescale;
|
||||||
|
float eyeseparation = (0.075f - 0.010f*fabs(direction.x))*basesize;
|
||||||
|
vec2 offset = vec2(direction.x*0.125f, -0.05f+direction.y*0.10f)*basesize;
|
||||||
|
gfx_quads_draw(body_pos.x-eyeseparation+offset.x, body_pos.y+offset.y, eyescale, h);
|
||||||
|
gfx_quads_draw(body_pos.x+eyeseparation+offset.x, body_pos.y+offset.y, -eyescale, h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw feet
|
||||||
|
gfx_setcolor(info->color_feet.r, info->color_feet.g, info->color_feet.b, info->color_feet.a);
|
||||||
|
select_sprite(outline?SPRITE_TEE_FOOT_OUTLINE:SPRITE_TEE_FOOT, 0, 0, 0);
|
||||||
|
|
||||||
|
keyframe *foot = f ? &anim->front_foot : &anim->back_foot;
|
||||||
|
|
||||||
|
float w = basesize;
|
||||||
|
float h = basesize/2;
|
||||||
|
|
||||||
|
gfx_quads_setrotation(foot->angle*pi*2);
|
||||||
|
gfx_quads_draw(position.x+foot->x*animscale, position.y+foot->y*animscale, w, h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx_quads_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void calc_screen_params(float amount, float wmax, float hmax, float aspect, float *w, float *h)
|
||||||
|
{
|
||||||
|
float f = sqrt(amount) / sqrt(aspect);
|
||||||
|
*w = f*aspect;
|
||||||
|
*h = f;
|
||||||
|
|
||||||
|
// limit the view
|
||||||
|
if(*w > wmax)
|
||||||
|
{
|
||||||
|
*w = wmax;
|
||||||
|
*h = *w/aspect;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(*h > hmax)
|
||||||
|
{
|
||||||
|
*h = hmax;
|
||||||
|
*w = *h*aspect;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mapscreen_to_world(float center_x, float center_y, float parallax_x, float parallax_y,
|
||||||
|
float offset_x, float offset_y, float aspect, float zoom, float *points)
|
||||||
|
{
|
||||||
|
float width, height;
|
||||||
|
calc_screen_params(1300*1000, 1500, 1050, aspect, &width, &height);
|
||||||
|
center_x *= parallax_x;
|
||||||
|
center_y *= parallax_y;
|
||||||
|
width *= zoom;
|
||||||
|
height *= zoom;
|
||||||
|
points[0] = offset_x+center_x-width/2;
|
||||||
|
points[1] = offset_y+center_y-height/2;
|
||||||
|
points[2] = offset_x+center_x+width/2;
|
||||||
|
points[3] = offset_y+center_y+height/2;
|
||||||
|
}
|
|
@ -1,17 +1,9 @@
|
||||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||||
struct animstate
|
#ifndef GAME_CLIENT_RENDER_H
|
||||||
{
|
#define GAME_CLIENT_RENDER_H
|
||||||
keyframe body;
|
|
||||||
keyframe back_foot;
|
|
||||||
keyframe front_foot;
|
|
||||||
keyframe attach;
|
|
||||||
};
|
|
||||||
|
|
||||||
void anim_seq_eval(sequence *seq, float time, keyframe *frame);
|
#include "../g_vmath.h"
|
||||||
void anim_eval(animation *anim, float time, animstate *state);
|
#include "../g_mapitems.h"
|
||||||
void anim_add_keyframe(keyframe *seq, keyframe *added, float amount);
|
|
||||||
void anim_add(animstate *state, animstate *added, float amount);
|
|
||||||
void anim_eval_add(animstate *state, animation *anim, float time, float amount);
|
|
||||||
|
|
||||||
struct tee_render_info
|
struct tee_render_info
|
||||||
{
|
{
|
||||||
|
@ -21,4 +13,46 @@ struct tee_render_info
|
||||||
float size;
|
float size;
|
||||||
};
|
};
|
||||||
|
|
||||||
void render_tee(animstate *anim, tee_render_info *info, int emote, vec2 dir, vec2 pos);
|
// sprite renderings
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SPRITE_FLAG_FLIP_Y=1,
|
||||||
|
SPRITE_FLAG_FLIP_X=2,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct sprite;
|
||||||
|
|
||||||
|
void select_sprite(sprite *spr, int flags=0, int sx=0, int sy=0);
|
||||||
|
void select_sprite(int id, int flags=0, int sx=0, int sy=0);
|
||||||
|
|
||||||
|
void draw_sprite(float x, float y, float size);
|
||||||
|
|
||||||
|
// rects
|
||||||
|
void draw_round_rect(float x, float y, float w, float h, float r);
|
||||||
|
void draw_round_rect_ext(float x, float y, float w, float h, float r, int corners);
|
||||||
|
|
||||||
|
// larger rendering methods
|
||||||
|
void menu_render();
|
||||||
|
void render_game();
|
||||||
|
void render_world(float center_x, float center_y, float zoom);
|
||||||
|
void render_loading(float percent);
|
||||||
|
|
||||||
|
// object render methods (gc_render_obj.cpp)
|
||||||
|
void render_tee(class animstate *anim, tee_render_info *info, int emote, vec2 dir, vec2 pos);
|
||||||
|
void render_flag(const struct obj_flag *prev, const struct obj_flag *current);
|
||||||
|
void render_powerup(const struct obj_powerup *prev, const struct obj_powerup *current);
|
||||||
|
void render_projectile(const struct obj_projectile *current, int itemid);
|
||||||
|
void render_player(
|
||||||
|
const struct obj_player_character *prev_char, const struct obj_player_character *player_char,
|
||||||
|
const struct obj_player_info *prev_info, const struct obj_player_info *player_info);
|
||||||
|
|
||||||
|
// map render methods (gc_render_map.cpp)
|
||||||
|
void render_quads(QUAD *quads, int num_quads);
|
||||||
|
void render_tilemap(TILE *tiles, int w, int h, float scale);
|
||||||
|
|
||||||
|
// helpers
|
||||||
|
void mapscreen_to_world(float center_x, float center_y, float parallax_x, float parallax_y,
|
||||||
|
float offset_x, float offset_y, float aspect, float zoom, float *points);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
167
src/game/client/gc_render_map.cpp
Normal file
167
src/game/client/gc_render_map.cpp
Normal file
|
@ -0,0 +1,167 @@
|
||||||
|
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||||
|
#include <engine/e_interface.h>
|
||||||
|
#include "../g_math.h"
|
||||||
|
#include "gc_client.h"
|
||||||
|
|
||||||
|
static void rotate(POINT *center, POINT *point, float rotation)
|
||||||
|
{
|
||||||
|
int x = point->x - center->x;
|
||||||
|
int y = point->y - center->y;
|
||||||
|
point->x = (int)(x * cosf(rotation) - y * sinf(rotation) + center->x);
|
||||||
|
point->y = (int)(x * sinf(rotation) + y * cosf(rotation) + center->y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void render_quads(QUAD *quads, int num_quads)
|
||||||
|
{
|
||||||
|
gfx_quads_begin();
|
||||||
|
float conv = 1/255.0f;
|
||||||
|
for(int i = 0; i < num_quads; i++)
|
||||||
|
{
|
||||||
|
QUAD *q = &quads[i];
|
||||||
|
|
||||||
|
gfx_quads_setsubset_free(
|
||||||
|
fx2f(q->texcoords[0].x), fx2f(q->texcoords[0].y),
|
||||||
|
fx2f(q->texcoords[1].x), fx2f(q->texcoords[1].y),
|
||||||
|
fx2f(q->texcoords[2].x), fx2f(q->texcoords[2].y),
|
||||||
|
fx2f(q->texcoords[3].x), fx2f(q->texcoords[3].y)
|
||||||
|
);
|
||||||
|
|
||||||
|
float r=1, g=1, b=1, a=1;
|
||||||
|
float offset_x = 0;
|
||||||
|
float offset_y = 0;
|
||||||
|
float rot = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
// TODO: fix this
|
||||||
|
if(editor.animate)
|
||||||
|
{
|
||||||
|
if(q->pos_env >= 0 && q->pos_env < editor.map.envelopes.len())
|
||||||
|
{
|
||||||
|
ENVELOPE *e = editor.map.envelopes[q->pos_env];
|
||||||
|
float t = editor.animate_time+q->pos_env_offset/1000.0f;
|
||||||
|
offset_x = e->eval(t, 0);
|
||||||
|
offset_y = e->eval(t, 1);
|
||||||
|
rot = e->eval(t, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(q->color_env >= 0 && q->color_env < editor.map.envelopes.len())
|
||||||
|
{
|
||||||
|
ENVELOPE *e = editor.map.envelopes[q->color_env];
|
||||||
|
float t = editor.animate_time+q->color_env_offset/1000.0f;
|
||||||
|
r = e->eval(t, 0);
|
||||||
|
g = e->eval(t, 1);
|
||||||
|
b = e->eval(t, 2);
|
||||||
|
a = e->eval(t, 3);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
gfx_setcolorvertex(0, q->colors[0].r*conv*r, q->colors[0].g*conv*g, q->colors[0].b*conv*b, q->colors[0].a*conv*a);
|
||||||
|
gfx_setcolorvertex(1, q->colors[1].r*conv*r, q->colors[1].g*conv*g, q->colors[1].b*conv*b, q->colors[1].a*conv*a);
|
||||||
|
gfx_setcolorvertex(2, q->colors[2].r*conv*r, q->colors[2].g*conv*g, q->colors[2].b*conv*b, q->colors[2].a*conv*a);
|
||||||
|
gfx_setcolorvertex(3, q->colors[3].r*conv*r, q->colors[3].g*conv*g, q->colors[3].b*conv*b, q->colors[3].a*conv*a);
|
||||||
|
|
||||||
|
POINT *points = q->points;
|
||||||
|
|
||||||
|
if(rot != 0)
|
||||||
|
{
|
||||||
|
static POINT rotated[4];
|
||||||
|
rotated[0] = q->points[0];
|
||||||
|
rotated[1] = q->points[1];
|
||||||
|
rotated[2] = q->points[2];
|
||||||
|
rotated[3] = q->points[3];
|
||||||
|
points = rotated;
|
||||||
|
|
||||||
|
rotate(&q->points[4], &rotated[0], rot);
|
||||||
|
rotate(&q->points[4], &rotated[1], rot);
|
||||||
|
rotate(&q->points[4], &rotated[2], rot);
|
||||||
|
rotate(&q->points[4], &rotated[3], rot);
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx_quads_draw_freeform(
|
||||||
|
fx2f(points[0].x)+offset_x, fx2f(points[0].y)+offset_y,
|
||||||
|
fx2f(points[1].x)+offset_x, fx2f(points[1].y)+offset_y,
|
||||||
|
fx2f(points[2].x)+offset_x, fx2f(points[2].y)+offset_y,
|
||||||
|
fx2f(points[3].x)+offset_x, fx2f(points[3].y)+offset_y
|
||||||
|
);
|
||||||
|
}
|
||||||
|
gfx_quads_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void render_tilemap(TILE *tiles, int w, int h, float scale)
|
||||||
|
{
|
||||||
|
//gfx_texture_set(img_get(tmap->image));
|
||||||
|
float screen_x0, screen_y0, screen_x1, screen_y1;
|
||||||
|
gfx_getscreen(&screen_x0, &screen_y0, &screen_x1, &screen_y1);
|
||||||
|
|
||||||
|
// calculate the final pixelsize for the tiles
|
||||||
|
float tile_pixelsize = 1024/32.0f;
|
||||||
|
float final_tilesize = scale/(screen_x1-screen_x0) * gfx_screenwidth();
|
||||||
|
float final_tilesize_scale = final_tilesize/tile_pixelsize;
|
||||||
|
|
||||||
|
gfx_quads_begin();
|
||||||
|
|
||||||
|
int starty = (int)(screen_y0/scale)-1;
|
||||||
|
int startx = (int)(screen_x0/scale)-1;
|
||||||
|
int endy = (int)(screen_y1/scale)+1;
|
||||||
|
int endx = (int)(screen_x1/scale)+1;
|
||||||
|
|
||||||
|
// adjust the texture shift according to mipmap level
|
||||||
|
float texsize = 1024.0f;
|
||||||
|
float frac = (1.25f/texsize) * (1/final_tilesize_scale);
|
||||||
|
float nudge = (0.5f/texsize) * (1/final_tilesize_scale);
|
||||||
|
|
||||||
|
for(int y = starty; y < endy; y++)
|
||||||
|
for(int x = startx; x < endx; x++)
|
||||||
|
{
|
||||||
|
int mx = x;
|
||||||
|
int my = y;
|
||||||
|
if(mx<0)
|
||||||
|
continue; // mx = 0;
|
||||||
|
if(mx>=w)
|
||||||
|
continue; // mx = w-1;
|
||||||
|
if(my<0)
|
||||||
|
continue; // my = 0;
|
||||||
|
if(my>=h)
|
||||||
|
continue; // my = h-1;
|
||||||
|
|
||||||
|
int c = mx + my*w;
|
||||||
|
|
||||||
|
unsigned char index = tiles[c].index;
|
||||||
|
if(index)
|
||||||
|
{
|
||||||
|
unsigned char flags = tiles[c].flags;
|
||||||
|
int tx = index%16;
|
||||||
|
int ty = index/16;
|
||||||
|
int px0 = tx*(1024/16);
|
||||||
|
int py0 = ty*(1024/16);
|
||||||
|
int px1 = (tx+1)*(1024/16)-1;
|
||||||
|
int py1 = (ty+1)*(1024/16)-1;
|
||||||
|
|
||||||
|
float u0 = nudge + px0/texsize+frac;
|
||||||
|
float v0 = nudge + py0/texsize+frac;
|
||||||
|
float u1 = nudge + px1/texsize-frac;
|
||||||
|
float v1 = nudge + py1/texsize-frac;
|
||||||
|
|
||||||
|
if(flags&TILEFLAG_VFLIP)
|
||||||
|
{
|
||||||
|
float tmp = u0;
|
||||||
|
u0 = u1;
|
||||||
|
u1 = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(flags&TILEFLAG_HFLIP)
|
||||||
|
{
|
||||||
|
float tmp = v0;
|
||||||
|
v0 = v1;
|
||||||
|
v1 = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx_quads_setsubset(u0,v0,u1,v1);
|
||||||
|
|
||||||
|
gfx_quads_drawTL(x*scale, y*scale, scale, scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx_quads_end();
|
||||||
|
}
|
478
src/game/client/gc_render_obj.cpp
Normal file
478
src/game/client/gc_render_obj.cpp
Normal file
|
@ -0,0 +1,478 @@
|
||||||
|
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||||
|
#include <math.h>
|
||||||
|
#include <engine/e_interface.h>
|
||||||
|
#include <engine/e_config.h>
|
||||||
|
#include "../generated/gc_data.h"
|
||||||
|
#include "../g_protocol.h"
|
||||||
|
#include "../g_math.h"
|
||||||
|
#include "gc_render.h"
|
||||||
|
#include "gc_anim.h"
|
||||||
|
#include "gc_client.h"
|
||||||
|
|
||||||
|
|
||||||
|
void render_projectile(const obj_projectile *current, int itemid)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
if(debug_firedelay)
|
||||||
|
{
|
||||||
|
debug_firedelay = time_get()-debug_firedelay;
|
||||||
|
dbg_msg("game", "firedelay=%.2f ms", debug_firedelay/(float)time_freq()*1000.0f);
|
||||||
|
debug_firedelay = 0;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
gfx_texture_set(data->images[IMAGE_GAME].id);
|
||||||
|
gfx_quads_begin();
|
||||||
|
|
||||||
|
// get positions
|
||||||
|
float gravity = -400;
|
||||||
|
if(current->type != WEAPON_ROCKET)
|
||||||
|
gravity = -100;
|
||||||
|
if(current->type == WEAPON_BOMB)
|
||||||
|
gravity = 0;
|
||||||
|
|
||||||
|
float ct = (client_tick()-current->start_tick)/(float)SERVER_TICK_SPEED + client_ticktime()*1/(float)SERVER_TICK_SPEED;
|
||||||
|
vec2 startpos(current->x, current->y);
|
||||||
|
vec2 startvel(current->vx, current->vy);
|
||||||
|
vec2 pos = calc_pos(startpos, startvel, gravity, ct);
|
||||||
|
vec2 prevpos = calc_pos(startpos, startvel, gravity, ct-0.001f);
|
||||||
|
|
||||||
|
select_sprite(data->weapons[current->type%data->num_weapons].sprite_proj);
|
||||||
|
vec2 vel = pos-prevpos;
|
||||||
|
//vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), client_intratick());
|
||||||
|
|
||||||
|
// add particle for this projectile
|
||||||
|
//proj_particles.addparticle(current->type, itemid, pos, vel);
|
||||||
|
|
||||||
|
if(length(vel) > 0.00001f)
|
||||||
|
gfx_quads_setrotation(get_angle(vel));
|
||||||
|
else
|
||||||
|
gfx_quads_setrotation(0);
|
||||||
|
|
||||||
|
// TODO: do this, but nice
|
||||||
|
//temp_system.new_particle(pos, vec2(0,0), 0.3f, 14.0f, 0, 0.95f);
|
||||||
|
|
||||||
|
gfx_quads_draw(pos.x, pos.y, 32, 32);
|
||||||
|
gfx_quads_setrotation(0);
|
||||||
|
gfx_quads_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
void render_powerup(const obj_powerup *prev, const obj_powerup *current)
|
||||||
|
{
|
||||||
|
gfx_texture_set(data->images[IMAGE_GAME].id);
|
||||||
|
gfx_quads_begin();
|
||||||
|
vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), client_intratick());
|
||||||
|
float angle = 0.0f;
|
||||||
|
float size = 64.0f;
|
||||||
|
if (current->type == POWERUP_WEAPON)
|
||||||
|
{
|
||||||
|
angle = 0; //-pi/6;//-0.25f * pi * 2.0f;
|
||||||
|
select_sprite(data->weapons[current->subtype%data->num_weapons].sprite_body);
|
||||||
|
size = data->weapons[current->subtype%data->num_weapons].visual_size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const int c[] = {
|
||||||
|
SPRITE_POWERUP_HEALTH,
|
||||||
|
SPRITE_POWERUP_ARMOR,
|
||||||
|
SPRITE_POWERUP_WEAPON,
|
||||||
|
SPRITE_POWERUP_NINJA,
|
||||||
|
SPRITE_POWERUP_TIMEFIELD
|
||||||
|
};
|
||||||
|
select_sprite(c[current->type]);
|
||||||
|
|
||||||
|
if(c[current->type] == SPRITE_POWERUP_NINJA)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
proj_particles.addparticle(0, 0,
|
||||||
|
pos+vec2((frandom()-0.5f)*80.0f, (frandom()-0.5f)*20.0f),
|
||||||
|
vec2((frandom()-0.5f)*10.0f, (frandom()-0.5f)*10.0f));*/
|
||||||
|
size *= 2.0f;
|
||||||
|
pos.x += 10.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx_quads_setrotation(angle);
|
||||||
|
|
||||||
|
float offset = pos.y/32.0f + pos.x/32.0f;
|
||||||
|
pos.x += cosf(client_localtime()*2.0f+offset)*2.5f;
|
||||||
|
pos.y += sinf(client_localtime()*2.0f+offset)*2.5f;
|
||||||
|
draw_sprite(pos.x, pos.y, size);
|
||||||
|
gfx_quads_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
void render_flag(const obj_flag *prev, const obj_flag *current)
|
||||||
|
{
|
||||||
|
float angle = 0.0f;
|
||||||
|
float size = 42.0f;
|
||||||
|
|
||||||
|
gfx_blend_normal();
|
||||||
|
gfx_texture_set(data->images[IMAGE_GAME].id);
|
||||||
|
gfx_quads_begin();
|
||||||
|
|
||||||
|
if(current->team == 0) // red team
|
||||||
|
select_sprite(SPRITE_FLAG_RED);
|
||||||
|
else
|
||||||
|
select_sprite(SPRITE_FLAG_BLUE);
|
||||||
|
|
||||||
|
gfx_quads_setrotation(angle);
|
||||||
|
|
||||||
|
vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), client_intratick());
|
||||||
|
|
||||||
|
if(local_info && current->carried_by == local_info->clientid)
|
||||||
|
pos = local_character_pos;
|
||||||
|
|
||||||
|
//gfx_setcolor(current->team ? 0 : 1,0,current->team ? 1 : 0,1);
|
||||||
|
//draw_sprite(pos.x, pos.y, size);
|
||||||
|
gfx_quads_draw(pos.x, pos.y-size*0.75f, size, size*2);
|
||||||
|
gfx_quads_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void render_hand(tee_render_info *info, vec2 center_pos, vec2 dir, float angle_offset, vec2 post_rot_offset)
|
||||||
|
{
|
||||||
|
// for drawing hand
|
||||||
|
//const skin *s = skin_get(skin_id);
|
||||||
|
|
||||||
|
float basesize = 10.0f;
|
||||||
|
//dir = normalize(hook_pos-pos);
|
||||||
|
|
||||||
|
vec2 hand_pos = center_pos + dir;
|
||||||
|
float angle = get_angle(dir);
|
||||||
|
if (dir.x < 0)
|
||||||
|
angle -= angle_offset;
|
||||||
|
else
|
||||||
|
angle += angle_offset;
|
||||||
|
|
||||||
|
vec2 dirx = dir;
|
||||||
|
vec2 diry(-dir.y,dir.x);
|
||||||
|
|
||||||
|
if (dir.x < 0)
|
||||||
|
diry = -diry;
|
||||||
|
|
||||||
|
hand_pos += dirx * post_rot_offset.x;
|
||||||
|
hand_pos += diry * post_rot_offset.y;
|
||||||
|
|
||||||
|
//gfx_texture_set(data->images[IMAGE_CHAR_DEFAULT].id);
|
||||||
|
gfx_texture_set(info->texture);
|
||||||
|
gfx_quads_begin();
|
||||||
|
gfx_setcolor(info->color_body.r, info->color_body.g, info->color_body.b, info->color_body.a);
|
||||||
|
|
||||||
|
// two passes
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
bool outline = i == 0;
|
||||||
|
|
||||||
|
select_sprite(outline?SPRITE_TEE_HAND_OUTLINE:SPRITE_TEE_HAND, 0, 0, 0);
|
||||||
|
gfx_quads_setrotation(angle);
|
||||||
|
gfx_quads_draw(hand_pos.x, hand_pos.y, 2*basesize, 2*basesize);
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx_quads_setrotation(0);
|
||||||
|
gfx_quads_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
void render_player(
|
||||||
|
const obj_player_character *prev_char,
|
||||||
|
const obj_player_character *player_char,
|
||||||
|
const obj_player_info *prev_info,
|
||||||
|
const obj_player_info *player_info
|
||||||
|
)
|
||||||
|
{
|
||||||
|
obj_player_character prev;
|
||||||
|
obj_player_character player;
|
||||||
|
prev = *prev_char;
|
||||||
|
player = *player_char;
|
||||||
|
|
||||||
|
obj_player_info info = *player_info;
|
||||||
|
|
||||||
|
float intratick = client_intratick();
|
||||||
|
float ticktime = client_ticktime();
|
||||||
|
|
||||||
|
if(player.health < 0) // dont render dead players
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(info.local && config.cl_predict)
|
||||||
|
{
|
||||||
|
if(!local_character || (local_character->health < 0) || (gameobj && gameobj->game_over))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// apply predicted results
|
||||||
|
predicted_player.write(&player);
|
||||||
|
predicted_prev_player.write(&prev);
|
||||||
|
intratick = client_intrapredtick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 direction = get_direction(player.angle);
|
||||||
|
float angle = player.angle/256.0f;
|
||||||
|
vec2 position = mix(vec2(prev.x, prev.y), vec2(player.x, player.y), intratick);
|
||||||
|
|
||||||
|
if(prev.health < 0) // Don't flicker from previous position
|
||||||
|
position = vec2(player.x, player.y);
|
||||||
|
|
||||||
|
bool stationary = player.vx < 1 && player.vx > -1;
|
||||||
|
bool inair = col_check_point(player.x, player.y+16) == 0;
|
||||||
|
|
||||||
|
// evaluate animation
|
||||||
|
float walk_time = fmod(position.x, 100.0f)/100.0f;
|
||||||
|
animstate state;
|
||||||
|
anim_eval(&data->animations[ANIM_BASE], 0, &state);
|
||||||
|
|
||||||
|
if(inair)
|
||||||
|
anim_eval_add(&state, &data->animations[ANIM_INAIR], 0, 1.0f); // TODO: some sort of time here
|
||||||
|
else if(stationary)
|
||||||
|
anim_eval_add(&state, &data->animations[ANIM_IDLE], 0, 1.0f); // TODO: some sort of time here
|
||||||
|
else
|
||||||
|
anim_eval_add(&state, &data->animations[ANIM_WALK], walk_time, 1.0f);
|
||||||
|
|
||||||
|
if (player.weapon == WEAPON_HAMMER)
|
||||||
|
{
|
||||||
|
float a = clamp((client_tick()-player.attacktick+ticktime)/10.0f, 0.0f, 1.0f);
|
||||||
|
anim_eval_add(&state, &data->animations[ANIM_HAMMER_SWING], a, 1.0f);
|
||||||
|
}
|
||||||
|
if (player.weapon == WEAPON_NINJA)
|
||||||
|
{
|
||||||
|
float a = clamp((client_tick()-player.attacktick+ticktime)/40.0f, 0.0f, 1.0f);
|
||||||
|
anim_eval_add(&state, &data->animations[ANIM_NINJA_SWING], a, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw hook
|
||||||
|
if (prev.hook_state>0 && player.hook_state>0)
|
||||||
|
{
|
||||||
|
gfx_texture_set(data->images[IMAGE_GAME].id);
|
||||||
|
gfx_quads_begin();
|
||||||
|
//gfx_quads_begin();
|
||||||
|
|
||||||
|
vec2 pos = position;
|
||||||
|
vec2 hook_pos;
|
||||||
|
|
||||||
|
if(player_char->hooked_player != -1)
|
||||||
|
{
|
||||||
|
if(local_info && player_char->hooked_player == local_info->clientid)
|
||||||
|
{
|
||||||
|
hook_pos = mix(vec2(predicted_prev_player.pos.x, predicted_prev_player.pos.y),
|
||||||
|
vec2(predicted_player.pos.x, predicted_player.pos.y), client_intrapredtick());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
hook_pos = mix(vec2(prev_char->hook_x, prev_char->hook_y), vec2(player_char->hook_x, player_char->hook_y), client_intratick());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
hook_pos = mix(vec2(prev.hook_x, prev.hook_y), vec2(player.hook_x, player.hook_y), intratick);
|
||||||
|
|
||||||
|
float d = distance(pos, hook_pos);
|
||||||
|
vec2 dir = normalize(pos-hook_pos);
|
||||||
|
|
||||||
|
gfx_quads_setrotation(get_angle(dir)+pi);
|
||||||
|
|
||||||
|
// render head
|
||||||
|
select_sprite(SPRITE_HOOK_HEAD);
|
||||||
|
gfx_quads_draw(hook_pos.x, hook_pos.y, 24,16);
|
||||||
|
|
||||||
|
// render chain
|
||||||
|
select_sprite(SPRITE_HOOK_CHAIN);
|
||||||
|
for(float f = 24; f < d; f += 24)
|
||||||
|
{
|
||||||
|
vec2 p = hook_pos + dir*f;
|
||||||
|
gfx_quads_draw(p.x, p.y,24,16);
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx_quads_setrotation(0);
|
||||||
|
gfx_quads_end();
|
||||||
|
|
||||||
|
render_hand(&client_datas[info.clientid].render_info, position, normalize(hook_pos-pos), -pi/2, vec2(20, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw gun
|
||||||
|
{
|
||||||
|
gfx_texture_set(data->images[IMAGE_GAME].id);
|
||||||
|
gfx_quads_begin();
|
||||||
|
gfx_quads_setrotation(state.attach.angle*pi*2+angle);
|
||||||
|
|
||||||
|
// normal weapons
|
||||||
|
int iw = clamp(player.weapon, 0, NUM_WEAPONS-1);
|
||||||
|
select_sprite(data->weapons[iw].sprite_body, direction.x < 0 ? SPRITE_FLAG_FLIP_Y : 0);
|
||||||
|
|
||||||
|
vec2 dir = direction;
|
||||||
|
float recoil = 0.0f;
|
||||||
|
vec2 p;
|
||||||
|
if (player.weapon == WEAPON_HAMMER)
|
||||||
|
{
|
||||||
|
// Static position for hammer
|
||||||
|
p = position;
|
||||||
|
p.y += data->weapons[iw].offsety;
|
||||||
|
// if attack is under way, bash stuffs
|
||||||
|
if(direction.x < 0)
|
||||||
|
{
|
||||||
|
gfx_quads_setrotation(-pi/2-state.attach.angle*pi*2);
|
||||||
|
p.x -= data->weapons[iw].offsetx;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gfx_quads_setrotation(-pi/2+state.attach.angle*pi*2);
|
||||||
|
}
|
||||||
|
draw_sprite(p.x, p.y, data->weapons[iw].visual_size);
|
||||||
|
}
|
||||||
|
else if (player.weapon == WEAPON_NINJA)
|
||||||
|
{
|
||||||
|
p = position;
|
||||||
|
p.y += data->weapons[iw].offsety;
|
||||||
|
|
||||||
|
if(direction.x < 0)
|
||||||
|
{
|
||||||
|
gfx_quads_setrotation(-pi/2-state.attach.angle*pi*2);
|
||||||
|
p.x -= data->weapons[iw].offsetx;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gfx_quads_setrotation(-pi/2+state.attach.angle*pi*2);
|
||||||
|
}
|
||||||
|
draw_sprite(p.x, p.y, data->weapons[iw].visual_size);
|
||||||
|
|
||||||
|
// HADOKEN
|
||||||
|
if ((client_tick()-player.attacktick) <= (SERVER_TICK_SPEED / 6) && data->weapons[iw].nummuzzlesprites)
|
||||||
|
{
|
||||||
|
int itex = rand() % data->weapons[iw].nummuzzlesprites;
|
||||||
|
float alpha = 1.0f;
|
||||||
|
if (alpha > 0.0f && data->weapons[iw].sprite_muzzle[itex].psprite)
|
||||||
|
{
|
||||||
|
vec2 dir = vec2(player_char->x,player_char->y) - vec2(prev_char->x, prev_char->y);
|
||||||
|
dir = normalize(dir);
|
||||||
|
float hadokenangle = get_angle(dir);
|
||||||
|
gfx_quads_setrotation(hadokenangle);
|
||||||
|
//float offsety = -data->weapons[iw].muzzleoffsety;
|
||||||
|
select_sprite(data->weapons[iw].sprite_muzzle[itex].psprite, 0);
|
||||||
|
vec2 diry(-dir.y,dir.x);
|
||||||
|
p = position;
|
||||||
|
float offsetx = data->weapons[iw].muzzleoffsetx;
|
||||||
|
p -= dir * offsetx;
|
||||||
|
draw_sprite(p.x, p.y, 160.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO: should be an animation
|
||||||
|
recoil = 0;
|
||||||
|
float a = (client_tick()-player.attacktick+intratick)/5.0f;
|
||||||
|
if(a < 1)
|
||||||
|
recoil = sinf(a*pi);
|
||||||
|
p = position + dir * data->weapons[iw].offsetx - dir*recoil*10.0f;
|
||||||
|
p.y += data->weapons[iw].offsety;
|
||||||
|
draw_sprite(p.x, p.y, data->weapons[iw].visual_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player.weapon == WEAPON_GUN || player.weapon == WEAPON_SHOTGUN)
|
||||||
|
{
|
||||||
|
// check if we're firing stuff
|
||||||
|
if (true)//prev.attackticks)
|
||||||
|
{
|
||||||
|
float alpha = 0.0f;
|
||||||
|
int phase1tick = (client_tick() - player.attacktick);
|
||||||
|
if (phase1tick < (data->weapons[iw].muzzleduration + 3))
|
||||||
|
{
|
||||||
|
float t = ((((float)phase1tick) + intratick)/(float)data->weapons[iw].muzzleduration);
|
||||||
|
alpha = LERP(2.0, 0.0f, min(1.0f,max(0.0f,t)));
|
||||||
|
}
|
||||||
|
|
||||||
|
int itex = rand() % data->weapons[iw].nummuzzlesprites;
|
||||||
|
if (alpha > 0.0f && data->weapons[iw].sprite_muzzle[itex].psprite)
|
||||||
|
{
|
||||||
|
float offsety = -data->weapons[iw].muzzleoffsety;
|
||||||
|
select_sprite(data->weapons[iw].sprite_muzzle[itex].psprite, direction.x < 0 ? SPRITE_FLAG_FLIP_Y : 0);
|
||||||
|
if(direction.x < 0)
|
||||||
|
offsety = -offsety;
|
||||||
|
|
||||||
|
vec2 diry(-dir.y,dir.x);
|
||||||
|
vec2 muzzlepos = p + dir * data->weapons[iw].muzzleoffsetx + diry * offsety;
|
||||||
|
|
||||||
|
draw_sprite(muzzlepos.x, muzzlepos.y, data->weapons[iw].visual_size);
|
||||||
|
/*gfx_setcolor(1.0f,1.0f,1.0f,alpha);
|
||||||
|
vec2 diry(-dir.y,dir.x);
|
||||||
|
p += dir * muzzleparams[player.weapon].offsetx + diry * offsety;
|
||||||
|
gfx_quads_draw(p.x,p.y,muzzleparams[player.weapon].sizex, muzzleparams[player.weapon].sizey);*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gfx_quads_end();
|
||||||
|
|
||||||
|
switch (player.weapon)
|
||||||
|
{
|
||||||
|
case WEAPON_GUN: render_hand(&client_datas[info.clientid].render_info, p, direction, -3*pi/4, vec2(-15, 4)); break;
|
||||||
|
case WEAPON_SHOTGUN: render_hand(&client_datas[info.clientid].render_info, p, direction, -pi/2, vec2(-5, 4)); break;
|
||||||
|
case WEAPON_ROCKET: render_hand(&client_datas[info.clientid].render_info, p, direction, -pi/2, vec2(-4, 7)); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// render the "shadow" tee
|
||||||
|
if(info.local && config.debug)
|
||||||
|
{
|
||||||
|
vec2 ghost_position = mix(vec2(prev_char->x, prev_char->y), vec2(player_char->x, player_char->y), client_intratick());
|
||||||
|
tee_render_info ghost = client_datas[info.clientid].render_info;
|
||||||
|
ghost.color_body.a = 0.5f;
|
||||||
|
ghost.color_feet.a = 0.5f;
|
||||||
|
render_tee(&state, &ghost, player.emote, direction, ghost_position); // render ghost
|
||||||
|
}
|
||||||
|
|
||||||
|
// render the tee
|
||||||
|
render_tee(&state, &client_datas[info.clientid].render_info, player.emote, direction, position);
|
||||||
|
|
||||||
|
if(player.state == STATE_CHATTING)
|
||||||
|
{
|
||||||
|
gfx_texture_set(data->images[IMAGE_EMOTICONS].id);
|
||||||
|
gfx_quads_begin();
|
||||||
|
select_sprite(SPRITE_DOTDOT);
|
||||||
|
gfx_quads_draw(position.x + 24, position.y - 40, 64,64);
|
||||||
|
gfx_quads_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (client_datas[info.clientid].emoticon_start != -1 && client_datas[info.clientid].emoticon_start + 2 * client_tickspeed() > client_tick())
|
||||||
|
{
|
||||||
|
gfx_texture_set(data->images[IMAGE_EMOTICONS].id);
|
||||||
|
gfx_quads_begin();
|
||||||
|
|
||||||
|
int since_start = client_tick() - client_datas[info.clientid].emoticon_start;
|
||||||
|
int from_end = client_datas[info.clientid].emoticon_start + 2 * client_tickspeed() - client_tick();
|
||||||
|
|
||||||
|
float a = 1;
|
||||||
|
|
||||||
|
if (from_end < client_tickspeed() / 5)
|
||||||
|
a = from_end / (client_tickspeed() / 5.0);
|
||||||
|
|
||||||
|
float h = 1;
|
||||||
|
if (since_start < client_tickspeed() / 10)
|
||||||
|
h = since_start / (client_tickspeed() / 10.0);
|
||||||
|
|
||||||
|
float wiggle = 0;
|
||||||
|
if (since_start < client_tickspeed() / 5)
|
||||||
|
wiggle = since_start / (client_tickspeed() / 5.0);
|
||||||
|
|
||||||
|
float wiggle_angle = sin(5*wiggle);
|
||||||
|
|
||||||
|
gfx_quads_setrotation(pi/6*wiggle_angle);
|
||||||
|
|
||||||
|
gfx_setcolor(1.0f,1.0f,1.0f,a);
|
||||||
|
// client_datas::emoticon is an offset from the first emoticon
|
||||||
|
select_sprite(SPRITE_OOP + client_datas[info.clientid].emoticon);
|
||||||
|
gfx_quads_draw(position.x, position.y - 23 - 32*h, 64, 64*h);
|
||||||
|
gfx_quads_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
// render name plate
|
||||||
|
if(!info.local && config.cl_nameplates)
|
||||||
|
{
|
||||||
|
//gfx_text_color
|
||||||
|
float a = 1;
|
||||||
|
if(config.cl_nameplates_always == 0)
|
||||||
|
a = clamp(1-powf(distance(local_target_pos, position)/200.0f,16.0f), 0.0f, 1.0f);
|
||||||
|
|
||||||
|
const char *name = client_datas[info.clientid].name;
|
||||||
|
float tw = gfx_text_width(0, 28.0f, name, -1);
|
||||||
|
gfx_text_color(1,1,1,a);
|
||||||
|
gfx_text(0, position.x-tw/2.0f, position.y-60, 28.0f, name, -1);
|
||||||
|
gfx_text_color(1,1,1,1);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,5 @@
|
||||||
|
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -15,8 +17,9 @@ extern "C" {
|
||||||
//#include "game/mapres_col.h"
|
//#include "game/mapres_col.h"
|
||||||
#include <game/g_mapres.h>
|
#include <game/g_mapres.h>
|
||||||
#include <game/g_game.h>
|
#include <game/g_game.h>
|
||||||
|
#include <game/client/gc_render.h>
|
||||||
|
|
||||||
#include "editor.hpp"
|
#include "ed_editor.hpp"
|
||||||
|
|
||||||
static int checker_texture = 0;
|
static int checker_texture = 0;
|
||||||
static int background_texture = 0;
|
static int background_texture = 0;
|
||||||
|
@ -116,9 +119,6 @@ int LAYERGROUP::swap_layers(int index0, int index1)
|
||||||
/********************************************************
|
/********************************************************
|
||||||
OTHER
|
OTHER
|
||||||
*********************************************************/
|
*********************************************************/
|
||||||
extern void draw_round_rect_ext(float x, float y, float w, float h, float r, int corners);
|
|
||||||
extern void draw_round_rect(float x, float y, float w, float h, float r);
|
|
||||||
|
|
||||||
static void ui_draw_rect(const RECT *r, vec4 color, int corners, float rounding)
|
static void ui_draw_rect(const RECT *r, vec4 color, int corners, float rounding)
|
||||||
{
|
{
|
||||||
gfx_texture_set(-1);
|
gfx_texture_set(-1);
|
||||||
|
@ -1961,67 +1961,6 @@ void EDITOR::make_game_group(LAYERGROUP *group)
|
||||||
editor.game_group->name = "Game";
|
editor.game_group->name = "Game";
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int version;
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
int external;
|
|
||||||
int image_name;
|
|
||||||
int image_data;
|
|
||||||
} MAPITEM_IMAGE;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int version;
|
|
||||||
int offset_x;
|
|
||||||
int offset_y;
|
|
||||||
int parallax_x;
|
|
||||||
int parallax_y;
|
|
||||||
|
|
||||||
int start_layer;
|
|
||||||
int num_layers;
|
|
||||||
} MAPITEM_GROUP;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int version;
|
|
||||||
int type;
|
|
||||||
int flags;
|
|
||||||
} MAPITEM_LAYER;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
MAPITEM_LAYER layer;
|
|
||||||
int version;
|
|
||||||
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
int flags;
|
|
||||||
|
|
||||||
COLOR color;
|
|
||||||
int color_env;
|
|
||||||
int color_env_offset;
|
|
||||||
|
|
||||||
int image;
|
|
||||||
int data;
|
|
||||||
} MAPITEM_LAYER_TILEMAP;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
MAPITEM_LAYER layer;
|
|
||||||
int version;
|
|
||||||
|
|
||||||
int num_quads;
|
|
||||||
int data;
|
|
||||||
int image;
|
|
||||||
} MAPITEM_LAYER_QUADS;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int version;
|
|
||||||
} MAPITEM_VERSION;
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static int make_version(int i, const T &v)
|
static int make_version(int i, const T &v)
|
||||||
{ return (i<<16)+sizeof(T); }
|
{ return (i<<16)+sizeof(T); }
|
||||||
|
@ -2411,6 +2350,7 @@ extern "C" void editor_init()
|
||||||
editor.show_envelope_editor = 1;
|
editor.show_envelope_editor = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
if(1)
|
if(1)
|
||||||
{
|
{
|
||||||
float w, h;
|
float w, h;
|
||||||
|
@ -2426,7 +2366,7 @@ extern "C" void editor_init()
|
||||||
calc_screen_params(amount, max, max, 9.0f/16.0f, &w, &h); dbg_msg("", "%f %f %f", w, h, w*h);
|
calc_screen_params(amount, max, max, 9.0f/16.0f, &w, &h); dbg_msg("", "%f %f %f", w, h, w*h);
|
||||||
calc_screen_params(amount, max, max, 16.0f/3.0f, &w, &h); dbg_msg("", "%f %f %f", w, h, w*h);
|
calc_screen_params(amount, max, max, 16.0f/3.0f, &w, &h); dbg_msg("", "%f %f %f", w, h, w*h);
|
||||||
calc_screen_params(amount, max, max, 3.0f/16.0f, &w, &h); dbg_msg("", "%f %f %f", w, h, w*h);
|
calc_screen_params(amount, max, max, 3.0f/16.0f, &w, &h); dbg_msg("", "%f %f %f", w, h, w*h);
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void editor_update_and_render()
|
extern "C" void editor_update_and_render()
|
|
@ -1,6 +1,9 @@
|
||||||
|
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "array.h"
|
#include "array.h"
|
||||||
|
#include "../g_mapitems.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <engine/e_system.h>
|
#include <engine/e_system.h>
|
||||||
|
@ -28,76 +31,14 @@ enum
|
||||||
|
|
||||||
DIALOG_NONE=0,
|
DIALOG_NONE=0,
|
||||||
DIALOG_LOAD_IMAGE,
|
DIALOG_LOAD_IMAGE,
|
||||||
|
|
||||||
LAYERTYPE_INVALID=0,
|
|
||||||
LAYERTYPE_GAME,
|
|
||||||
LAYERTYPE_TILES,
|
|
||||||
LAYERTYPE_QUADS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int x, y; // 22.10 fixed point
|
|
||||||
} POINT;
|
|
||||||
|
|
||||||
// float to fixed
|
|
||||||
inline int f2fx(float v) { return (int)(v*(float)(1<<10)); }
|
|
||||||
inline float fx2f(int v) { return v*(1.0f/(1<<10)); }
|
|
||||||
|
|
||||||
typedef struct // as in file
|
|
||||||
{
|
|
||||||
int r, g, b, a;
|
|
||||||
} COLOR;
|
|
||||||
|
|
||||||
typedef struct // as in file
|
|
||||||
{
|
|
||||||
POINT points[5];
|
|
||||||
COLOR colors[4];
|
|
||||||
POINT texcoords[4];
|
|
||||||
|
|
||||||
int pos_env;
|
|
||||||
int pos_env_offset;
|
|
||||||
|
|
||||||
int color_env;
|
|
||||||
int color_env_offset;
|
|
||||||
} QUAD;
|
|
||||||
|
|
||||||
typedef struct // as in file
|
typedef struct // as in file
|
||||||
{
|
{
|
||||||
POINT position;
|
POINT position;
|
||||||
int type;
|
int type;
|
||||||
} ENTITY;
|
} ENTITY;
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
ENTITY_NULL=0,
|
|
||||||
ENTITY_SPAWN,
|
|
||||||
ENTITY_SPAWN_RED,
|
|
||||||
ENTITY_SPAWN_BLUE,
|
|
||||||
ENTITY_FLAGSTAND_RED,
|
|
||||||
ENTITY_FLAGSTAND_BLUE,
|
|
||||||
ENTITY_ARMOR_1,
|
|
||||||
ENTITY_HEATH_1,
|
|
||||||
ENTITY_WEAPON_SHOTGUN,
|
|
||||||
ENTITY_WEAPON_ROCKET,
|
|
||||||
ENTITY_POWERUP_NINJA,
|
|
||||||
NUM_ENTITIES,
|
|
||||||
|
|
||||||
TILE_AIR=0,
|
|
||||||
TILE_SOLID,
|
|
||||||
TILE_NOHOOK,
|
|
||||||
|
|
||||||
ENTITY_OFFSET=255-16*4,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct // as in file
|
|
||||||
{
|
|
||||||
unsigned char index;
|
|
||||||
unsigned char flags;
|
|
||||||
unsigned char reserved1;
|
|
||||||
unsigned char reserved2;
|
|
||||||
} TILE;
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
CURVETYPE_STEP=0,
|
CURVETYPE_STEP=0,
|
||||||
|
@ -531,39 +472,3 @@ public:
|
||||||
|
|
||||||
virtual void render_properties(RECT *toolbox);
|
virtual void render_properties(RECT *toolbox);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
inline void calc_screen_params(float amount, float wmax, float hmax, float aspect, float *w, float *h)
|
|
||||||
{
|
|
||||||
float f = sqrt(amount) / sqrt(aspect);
|
|
||||||
*w = f*aspect;
|
|
||||||
*h = f;
|
|
||||||
|
|
||||||
// limit the view
|
|
||||||
if(*w > wmax)
|
|
||||||
{
|
|
||||||
*w = wmax;
|
|
||||||
*h = *w/aspect;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(*h > hmax)
|
|
||||||
{
|
|
||||||
*h = hmax;
|
|
||||||
*w = *h*aspect;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void mapscreen_to_world(float center_x, float center_y, float parallax_x, float parallax_y,
|
|
||||||
float offset_x, float offset_y, float aspect, float zoom, float *points)
|
|
||||||
{
|
|
||||||
float width, height;
|
|
||||||
calc_screen_params(1300*1000, 1500, 1050, aspect, &width, &height);
|
|
||||||
center_x *= parallax_x;
|
|
||||||
center_y *= parallax_y;
|
|
||||||
width *= zoom;
|
|
||||||
height *= zoom;
|
|
||||||
points[0] = offset_x+center_x-width/2;
|
|
||||||
points[1] = offset_y+center_y-height/2;
|
|
||||||
points[2] = offset_x+center_x+width/2;
|
|
||||||
points[3] = offset_y+center_y+height/2;
|
|
||||||
}
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include <game/client/gc_mapres_tilemap.h>
|
#include <game/client/gc_mapres_tilemap.h>
|
||||||
#include "editor.hpp"
|
#include "ed_editor.hpp"
|
||||||
|
|
||||||
|
|
||||||
LAYER_GAME::LAYER_GAME(int w, int h)
|
LAYER_GAME::LAYER_GAME(int w, int h)
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "editor.hpp"
|
#include "ed_editor.hpp"
|
||||||
#include <game/g_math.h>
|
#include <game/g_math.h>
|
||||||
|
#include <game/generated/gc_data.h>
|
||||||
|
#include <game/client/gc_render.h>
|
||||||
|
|
||||||
LAYER_QUADS::LAYER_QUADS()
|
LAYER_QUADS::LAYER_QUADS()
|
||||||
{
|
{
|
||||||
|
@ -12,88 +14,6 @@ LAYER_QUADS::~LAYER_QUADS()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rotate(POINT *center, POINT *point, float rotation)
|
|
||||||
{
|
|
||||||
int x = point->x - center->x;
|
|
||||||
int y = point->y - center->y;
|
|
||||||
point->x = (int)(x * cosf(rotation) - y * sinf(rotation) + center->x);
|
|
||||||
point->y = (int)(x * sinf(rotation) + y * cosf(rotation) + center->y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void render_quads(QUAD *quads, int num_quads)
|
|
||||||
{
|
|
||||||
gfx_quads_begin();
|
|
||||||
float conv = 1/255.0f;
|
|
||||||
for(int i = 0; i < num_quads; i++)
|
|
||||||
{
|
|
||||||
QUAD *q = &quads[i];
|
|
||||||
|
|
||||||
gfx_quads_setsubset_free(
|
|
||||||
fx2f(q->texcoords[0].x), fx2f(q->texcoords[0].y),
|
|
||||||
fx2f(q->texcoords[1].x), fx2f(q->texcoords[1].y),
|
|
||||||
fx2f(q->texcoords[2].x), fx2f(q->texcoords[2].y),
|
|
||||||
fx2f(q->texcoords[3].x), fx2f(q->texcoords[3].y)
|
|
||||||
);
|
|
||||||
|
|
||||||
float r=1, g=1, b=1, a=1;
|
|
||||||
float offset_x = 0;
|
|
||||||
float offset_y = 0;
|
|
||||||
float rot = 0;
|
|
||||||
|
|
||||||
if(editor.animate)
|
|
||||||
{
|
|
||||||
if(q->pos_env >= 0 && q->pos_env < editor.map.envelopes.len())
|
|
||||||
{
|
|
||||||
ENVELOPE *e = editor.map.envelopes[q->pos_env];
|
|
||||||
float t = editor.animate_time+q->pos_env_offset/1000.0f;
|
|
||||||
offset_x = e->eval(t, 0);
|
|
||||||
offset_y = e->eval(t, 1);
|
|
||||||
rot = e->eval(t, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(q->color_env >= 0 && q->color_env < editor.map.envelopes.len())
|
|
||||||
{
|
|
||||||
ENVELOPE *e = editor.map.envelopes[q->color_env];
|
|
||||||
float t = editor.animate_time+q->color_env_offset/1000.0f;
|
|
||||||
r = e->eval(t, 0);
|
|
||||||
g = e->eval(t, 1);
|
|
||||||
b = e->eval(t, 2);
|
|
||||||
a = e->eval(t, 3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gfx_setcolorvertex(0, q->colors[0].r*conv*r, q->colors[0].g*conv*g, q->colors[0].b*conv*b, q->colors[0].a*conv*a);
|
|
||||||
gfx_setcolorvertex(1, q->colors[1].r*conv*r, q->colors[1].g*conv*g, q->colors[1].b*conv*b, q->colors[1].a*conv*a);
|
|
||||||
gfx_setcolorvertex(2, q->colors[2].r*conv*r, q->colors[2].g*conv*g, q->colors[2].b*conv*b, q->colors[2].a*conv*a);
|
|
||||||
gfx_setcolorvertex(3, q->colors[3].r*conv*r, q->colors[3].g*conv*g, q->colors[3].b*conv*b, q->colors[3].a*conv*a);
|
|
||||||
|
|
||||||
POINT *points = q->points;
|
|
||||||
|
|
||||||
if(rot != 0)
|
|
||||||
{
|
|
||||||
static POINT rotated[4];
|
|
||||||
rotated[0] = q->points[0];
|
|
||||||
rotated[1] = q->points[1];
|
|
||||||
rotated[2] = q->points[2];
|
|
||||||
rotated[3] = q->points[3];
|
|
||||||
points = rotated;
|
|
||||||
|
|
||||||
rotate(&q->points[4], &rotated[0], rot);
|
|
||||||
rotate(&q->points[4], &rotated[1], rot);
|
|
||||||
rotate(&q->points[4], &rotated[2], rot);
|
|
||||||
rotate(&q->points[4], &rotated[3], rot);
|
|
||||||
}
|
|
||||||
|
|
||||||
gfx_quads_draw_freeform(
|
|
||||||
fx2f(points[0].x)+offset_x, fx2f(points[0].y)+offset_y,
|
|
||||||
fx2f(points[1].x)+offset_x, fx2f(points[1].y)+offset_y,
|
|
||||||
fx2f(points[2].x)+offset_x, fx2f(points[2].y)+offset_y,
|
|
||||||
fx2f(points[3].x)+offset_x, fx2f(points[3].y)+offset_y
|
|
||||||
);
|
|
||||||
}
|
|
||||||
gfx_quads_end();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LAYER_QUADS::render()
|
void LAYER_QUADS::render()
|
||||||
{
|
{
|
||||||
gfx_texture_set(-1);
|
gfx_texture_set(-1);
|
||||||
|
|
|
@ -1,84 +1,8 @@
|
||||||
#include <game/client/gc_mapres_tilemap.h>
|
#include <game/client/gc_mapres_tilemap.h>
|
||||||
#include <game/g_math.h>
|
#include <game/g_math.h>
|
||||||
#include "editor.hpp"
|
#include <game/generated/gc_data.h>
|
||||||
|
#include <game/client/gc_render.h>
|
||||||
static void render_tilemap(TILE *tiles, int w, int h, float scale)
|
#include "ed_editor.hpp"
|
||||||
{
|
|
||||||
//gfx_texture_set(img_get(tmap->image));
|
|
||||||
float screen_x0, screen_y0, screen_x1, screen_y1;
|
|
||||||
gfx_getscreen(&screen_x0, &screen_y0, &screen_x1, &screen_y1);
|
|
||||||
|
|
||||||
// calculate the final pixelsize for the tiles
|
|
||||||
float tile_pixelsize = 1024/32.0f;
|
|
||||||
float final_tilesize = scale/(screen_x1-screen_x0) * gfx_screenwidth();
|
|
||||||
float final_tilesize_scale = final_tilesize/tile_pixelsize;
|
|
||||||
|
|
||||||
gfx_quads_begin();
|
|
||||||
|
|
||||||
int starty = (int)(screen_y0/scale)-1;
|
|
||||||
int startx = (int)(screen_x0/scale)-1;
|
|
||||||
int endy = (int)(screen_y1/scale)+1;
|
|
||||||
int endx = (int)(screen_x1/scale)+1;
|
|
||||||
|
|
||||||
// adjust the texture shift according to mipmap level
|
|
||||||
float texsize = 1024.0f;
|
|
||||||
float frac = (1.25f/texsize) * (1/final_tilesize_scale);
|
|
||||||
float nudge = (0.5f/texsize) * (1/final_tilesize_scale);
|
|
||||||
|
|
||||||
for(int y = starty; y < endy; y++)
|
|
||||||
for(int x = startx; x < endx; x++)
|
|
||||||
{
|
|
||||||
int mx = x;
|
|
||||||
int my = y;
|
|
||||||
if(mx<0)
|
|
||||||
continue; // mx = 0;
|
|
||||||
if(mx>=w)
|
|
||||||
continue; // mx = w-1;
|
|
||||||
if(my<0)
|
|
||||||
continue; // my = 0;
|
|
||||||
if(my>=h)
|
|
||||||
continue; // my = h-1;
|
|
||||||
|
|
||||||
int c = mx + my*w;
|
|
||||||
|
|
||||||
unsigned char index = tiles[c].index;
|
|
||||||
if(index)
|
|
||||||
{
|
|
||||||
unsigned char flags = tiles[c].flags;
|
|
||||||
int tx = index%16;
|
|
||||||
int ty = index/16;
|
|
||||||
int px0 = tx*(1024/16);
|
|
||||||
int py0 = ty*(1024/16);
|
|
||||||
int px1 = (tx+1)*(1024/16)-1;
|
|
||||||
int py1 = (ty+1)*(1024/16)-1;
|
|
||||||
|
|
||||||
float u0 = nudge + px0/texsize+frac;
|
|
||||||
float v0 = nudge + py0/texsize+frac;
|
|
||||||
float u1 = nudge + px1/texsize-frac;
|
|
||||||
float v1 = nudge + py1/texsize-frac;
|
|
||||||
|
|
||||||
if(flags&TILEFLAG_VFLIP)
|
|
||||||
{
|
|
||||||
float tmp = u0;
|
|
||||||
u0 = u1;
|
|
||||||
u1 = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(flags&TILEFLAG_HFLIP)
|
|
||||||
{
|
|
||||||
float tmp = v0;
|
|
||||||
v0 = v1;
|
|
||||||
v1 = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
gfx_quads_setsubset(u0,v0,u1,v1);
|
|
||||||
|
|
||||||
gfx_quads_drawTL(x*scale, y*scale, scale, scale);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gfx_quads_end();
|
|
||||||
}
|
|
||||||
|
|
||||||
LAYER_TILES::LAYER_TILES(int w, int h)
|
LAYER_TILES::LAYER_TILES(int w, int h)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||||
|
#ifndef GAME_GAME_H
|
||||||
|
#define GAME_GAME_H
|
||||||
|
|
||||||
#include <engine/e_system.h>
|
#include <engine/e_system.h>
|
||||||
#include <game/g_math.h>
|
#include <game/g_math.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
@ -169,3 +172,5 @@ enum
|
||||||
ITEM_ARMOR=0x00030001,
|
ITEM_ARMOR=0x00030001,
|
||||||
ITEM_NINJA=0x00040001,
|
ITEM_NINJA=0x00040001,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
138
src/game/g_mapitems.h
Normal file
138
src/game/g_mapitems.h
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||||
|
#ifndef GAME_MAPITEMS_H
|
||||||
|
#define GAME_MAPITEMS_H
|
||||||
|
|
||||||
|
// layer types
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
LAYERTYPE_INVALID=0,
|
||||||
|
LAYERTYPE_GAME, // not used
|
||||||
|
LAYERTYPE_TILES,
|
||||||
|
LAYERTYPE_QUADS,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// game layer tiles
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
ENTITY_NULL=0,
|
||||||
|
ENTITY_SPAWN,
|
||||||
|
ENTITY_SPAWN_RED,
|
||||||
|
ENTITY_SPAWN_BLUE,
|
||||||
|
ENTITY_FLAGSTAND_RED,
|
||||||
|
ENTITY_FLAGSTAND_BLUE,
|
||||||
|
ENTITY_ARMOR_1,
|
||||||
|
ENTITY_HEATH_1,
|
||||||
|
ENTITY_WEAPON_SHOTGUN,
|
||||||
|
ENTITY_WEAPON_ROCKET,
|
||||||
|
ENTITY_POWERUP_NINJA,
|
||||||
|
NUM_ENTITIES,
|
||||||
|
|
||||||
|
TILE_AIR=0,
|
||||||
|
TILE_SOLID,
|
||||||
|
TILE_NOHOOK,
|
||||||
|
|
||||||
|
TILEFLAG_VFLIP=1,
|
||||||
|
TILEFLAG_HFLIP=2,
|
||||||
|
|
||||||
|
ENTITY_OFFSET=255-16*4,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int x, y; // 22.10 fixed point
|
||||||
|
} POINT;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int r, g, b, a;
|
||||||
|
} COLOR;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
POINT points[5];
|
||||||
|
COLOR colors[4];
|
||||||
|
POINT texcoords[4];
|
||||||
|
|
||||||
|
int pos_env;
|
||||||
|
int pos_env_offset;
|
||||||
|
|
||||||
|
int color_env;
|
||||||
|
int color_env_offset;
|
||||||
|
} QUAD;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned char index;
|
||||||
|
unsigned char flags;
|
||||||
|
unsigned char reserved1;
|
||||||
|
unsigned char reserved2;
|
||||||
|
} TILE;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int version;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int external;
|
||||||
|
int image_name;
|
||||||
|
int image_data;
|
||||||
|
} MAPITEM_IMAGE;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int version;
|
||||||
|
int offset_x;
|
||||||
|
int offset_y;
|
||||||
|
int parallax_x;
|
||||||
|
int parallax_y;
|
||||||
|
|
||||||
|
int start_layer;
|
||||||
|
int num_layers;
|
||||||
|
} MAPITEM_GROUP;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int version;
|
||||||
|
int type;
|
||||||
|
int flags;
|
||||||
|
} MAPITEM_LAYER;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
MAPITEM_LAYER layer;
|
||||||
|
int version;
|
||||||
|
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
COLOR color;
|
||||||
|
int color_env;
|
||||||
|
int color_env_offset;
|
||||||
|
|
||||||
|
int image;
|
||||||
|
int data;
|
||||||
|
} MAPITEM_LAYER_TILEMAP;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
MAPITEM_LAYER layer;
|
||||||
|
int version;
|
||||||
|
|
||||||
|
int num_quads;
|
||||||
|
int data;
|
||||||
|
int image;
|
||||||
|
} MAPITEM_LAYER_QUADS;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int version;
|
||||||
|
} MAPITEM_VERSION;
|
||||||
|
|
||||||
|
// float to fixed
|
||||||
|
inline int f2fx(float v) { return (int)(v*(float)(1<<10)); }
|
||||||
|
inline float fx2f(int v) { return v*(1.0f/(1<<10)); }
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,4 +1,8 @@
|
||||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||||
|
#ifndef GAME_MAPRES_COL_H
|
||||||
|
#define GAME_MAPRES_COL_H
|
||||||
|
|
||||||
|
|
||||||
#include <game/g_vmath.h>
|
#include <game/g_vmath.h>
|
||||||
|
|
||||||
struct mapres_collision
|
struct mapres_collision
|
||||||
|
@ -13,3 +17,5 @@ int col_check_point(int x, int y);
|
||||||
int col_width();
|
int col_width();
|
||||||
int col_height();
|
int col_height();
|
||||||
bool col_intersect_line(vec2 pos0, vec2 pos1, vec2 *out);
|
bool col_intersect_line(vec2 pos0, vec2 pos1, vec2 *out);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
#ifndef BASE_MATH_H
|
#ifndef BASE_MATH_H
|
||||||
#define BASE_MATH_H
|
#define BASE_MATH_H
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T clamp(T val, T min, T max)
|
inline T clamp(T val, T min, T max)
|
||||||
{
|
{
|
||||||
|
@ -22,6 +24,9 @@ inline T mix(const T a, const T b, TB amount)
|
||||||
{
|
{
|
||||||
return a + (b-a)*amount;
|
return a + (b-a)*amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline float frandom() { return rand()/(float)(RAND_MAX); }
|
||||||
|
|
||||||
const float pi = 3.1415926535897932384626433f;
|
const float pi = 3.1415926535897932384626433f;
|
||||||
|
|
||||||
template <typename T> inline T min(T a, T b) { return a<b?a:b; }
|
template <typename T> inline T min(T a, T b) { return a<b?a:b; }
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||||
// NOTE: Be very careful when editing this file as it will change the network version
|
// NOTE: Be very careful when editing this file as it will change the network version
|
||||||
|
|
||||||
|
#ifndef GAME_PROTOCOL_H
|
||||||
|
#define GAME_PROTOCOL_H
|
||||||
|
|
||||||
// --------- PHYSICS TWEAK! --------
|
// --------- PHYSICS TWEAK! --------
|
||||||
const float ground_control_speed = 7.0f;
|
const float ground_control_speed = 7.0f;
|
||||||
const float ground_control_accel = 2.0f;
|
const float ground_control_accel = 2.0f;
|
||||||
|
@ -213,3 +216,5 @@ struct obj_player_info
|
||||||
int latency;
|
int latency;
|
||||||
int latency_flux;
|
int latency_flux;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue