diff options
| author | Magnus Auvinen <magnus.auvinen@gmail.com> | 2009-10-27 14:38:53 +0000 |
|---|---|---|
| committer | Magnus Auvinen <magnus.auvinen@gmail.com> | 2009-10-27 14:38:53 +0000 |
| commit | 878ede3080ab2cfb627aca505c397d9765052996 (patch) | |
| tree | 98bff371070e1dca0295f0ca58d64ac4ee8042ce /src/engine/client | |
| parent | 9b99ec0e60b60134e46f2f71d707230948f7db03 (diff) | |
| download | zcatch-878ede3080ab2cfb627aca505c397d9765052996.tar.gz zcatch-878ede3080ab2cfb627aca505c397d9765052996.zip | |
major update with stuff
Diffstat (limited to 'src/engine/client')
| -rw-r--r-- | src/engine/client/ec_client.cpp (renamed from src/engine/client/ec_client.c) | 396 | ||||
| -rw-r--r-- | src/engine/client/ec_gfx.c | 1020 | ||||
| -rw-r--r-- | src/engine/client/ec_gfx.cpp | 992 | ||||
| -rw-r--r-- | src/engine/client/ec_gfx_text.cpp (renamed from src/engine/client/ec_gfx_text.c) | 29 | ||||
| -rw-r--r-- | src/engine/client/ec_inp.cpp (renamed from src/engine/client/ec_inp.c) | 12 | ||||
| -rw-r--r-- | src/engine/client/ec_snd.cpp (renamed from src/engine/client/ec_snd.c) | 22 | ||||
| -rw-r--r-- | src/engine/client/ec_srvbrowse.cpp (renamed from src/engine/client/ec_srvbrowse.c) | 69 |
7 files changed, 1274 insertions, 1266 deletions
diff --git a/src/engine/client/ec_client.c b/src/engine/client/ec_client.cpp index 0c707ccf..7ba0a2bb 100644 --- a/src/engine/client/ec_client.c +++ b/src/engine/client/ec_client.cpp @@ -28,6 +28,28 @@ #include <mastersrv/mastersrv.h> #include <versionsrv/versionsrv.h> +#include "editor.h" +#include "graphics.h" +#include "client.h" + +static IEditor *m_pEditor = 0; +static IEngineGraphics *m_pGraphics = 0; +IEngineGraphics *Graphics() { return m_pGraphics; } + +static IGameClient *m_pGameClient = 0; + + +class CClient : public IEngine +{ +public: + virtual class IGraphics *Graphics() + { + return m_pGraphics; + } +}; + +static CClient m_Client; + const int prediction_margin = 1000/50/2; /* magic network prediction value */ /* @@ -43,7 +65,7 @@ const int prediction_margin = 1000/50/2; /* magic network prediction value */ */ /* network client, must be accessible from other parts like the server browser */ -NETCLIENT *net; +CNetClient m_NetClient; /* TODO: ugly, fix me */ extern void client_serverbrowse_set(NETADDR *addr, int request, int token, SERVER_INFO *info); @@ -171,22 +193,22 @@ static void graph_render(GRAPH *g, float x, float y, float w, float h, const cha char buf[32]; int i; - gfx_blend_normal(); + //m_pGraphics->BlendNormal(); - gfx_texture_set(-1); + Graphics()->TextureSet(-1); - gfx_quads_begin(); - gfx_setcolor(0, 0, 0, 0.75f); - gfx_quads_drawTL(x, y, w, h); - gfx_quads_end(); + m_pGraphics->QuadsBegin(); + Graphics()->SetColor(0, 0, 0, 0.75f); + Graphics()->QuadsDrawTL(x, y, w, h); + m_pGraphics->QuadsEnd(); - gfx_lines_begin(); - gfx_setcolor(0.95f, 0.95f, 0.95f, 1.00f); - gfx_lines_draw(x, y+h/2, x+w, y+h/2); - gfx_setcolor(0.5f, 0.5f, 0.5f, 0.75f); - gfx_lines_draw(x, y+(h*3)/4, x+w, y+(h*3)/4); - gfx_lines_draw(x, y+h/4, x+w, y+h/4); + Graphics()->LinesBegin(); + Graphics()->SetColor(0.95f, 0.95f, 0.95f, 1.00f); + Graphics()->LinesDraw(x, y+h/2, x+w, y+h/2); + Graphics()->SetColor(0.5f, 0.5f, 0.5f, 0.75f); + Graphics()->LinesDraw(x, y+(h*3)/4, x+w, y+(h*3)/4); + Graphics()->LinesDraw(x, y+h/4, x+w, y+h/4); for(i = 1; i < GRAPH_MAX; i++) { float a0 = (i-1)/(float)GRAPH_MAX; @@ -197,22 +219,22 @@ static void graph_render(GRAPH *g, float x, float y, float w, float h, const cha float v0 = (g->values[i0]-g->min) / (g->max-g->min); float v1 = (g->values[i1]-g->min) / (g->max-g->min); - gfx_setcolorvertex(0, g->colors[i0][0], g->colors[i0][1], g->colors[i0][2], 0.75f); - gfx_setcolorvertex(1, g->colors[i1][0], g->colors[i1][1], g->colors[i1][2], 0.75f); - gfx_lines_draw(x+a0*w, y+h-v0*h, x+a1*w, y+h-v1*h); + Graphics()->SetColorVertex(0, g->colors[i0][0], g->colors[i0][1], g->colors[i0][2], 0.75f); + Graphics()->SetColorVertex(1, g->colors[i1][0], g->colors[i1][1], g->colors[i1][2], 0.75f); + Graphics()->LinesDraw(x+a0*w, y+h-v0*h, x+a1*w, y+h-v1*h); } - gfx_lines_end(); + Graphics()->LinesEnd(); - gfx_texture_set(debug_font); - gfx_quads_text(x+2, y+h-16, 16, 1,1,1,1, description); + Graphics()->TextureSet(debug_font); + Graphics()->QuadsText(x+2, y+h-16, 16, 1,1,1,1, description); str_format(buf, sizeof(buf), "%.2f", g->max); - gfx_quads_text(x+w-8*strlen(buf)-8, y+2, 16, 1,1,1,1, buf); + Graphics()->QuadsText(x+w-8*strlen(buf)-8, y+2, 16, 1,1,1,1, buf); str_format(buf, sizeof(buf), "%.2f", g->min); - gfx_quads_text(x+w-8*strlen(buf)-8, y+h-16, 16, 1,1,1,1, buf); + Graphics()->QuadsText(x+w-8*strlen(buf)-8, y+h-16, 16, 1,1,1,1, buf); } @@ -336,40 +358,40 @@ enum }; /* the game snapshots are modifiable by the game */ -SNAPSTORAGE snapshot_storage; -static SNAPSTORAGE_HOLDER *snapshots[NUM_SNAPSHOT_TYPES] = {0, 0}; +CSnapshotStorage snapshot_storage; +static CSnapshotStorage::CHolder *snapshots[NUM_SNAPSHOT_TYPES] = {0, 0}; static int recived_snapshots = 0; -static char snapshot_incomming_data[MAX_SNAPSHOT_SIZE]; +static char snapshot_incomming_data[CSnapshot::MAX_SIZE]; -static SNAPSTORAGE_HOLDER demorec_snapshotholders[NUM_SNAPSHOT_TYPES]; -static char *demorec_snapshotdata[NUM_SNAPSHOT_TYPES][2][MAX_SNAPSHOT_SIZE]; +static CSnapshotStorage::CHolder demorec_snapshotholders[NUM_SNAPSHOT_TYPES]; +static char *demorec_snapshotdata[NUM_SNAPSHOT_TYPES][2][CSnapshot::MAX_SIZE]; /* --- */ void *snap_get_item(int snapid, int index, SNAP_ITEM *item) { - SNAPSHOT_ITEM *i; + CSnapshotItem *i; dbg_assert(snapid >= 0 && snapid < NUM_SNAPSHOT_TYPES, "invalid snapid"); - i = snapshot_get_item(snapshots[snapid]->alt_snap, index); - item->datasize = snapshot_get_item_datasize(snapshots[snapid]->alt_snap, index); - item->type = snapitem_type(i); - item->id = snapitem_id(i); - return (void *)snapitem_data(i); + i = snapshots[snapid]->m_pAltSnap->GetItem(index); + item->datasize = snapshots[snapid]->m_pAltSnap->GetItemSize(index); + item->type = i->Type(); + item->id = i->ID(); + return (void *)i->Data(); } void snap_invalidate_item(int snapid, int index) { - SNAPSHOT_ITEM *i; + CSnapshotItem *i; dbg_assert(snapid >= 0 && snapid < NUM_SNAPSHOT_TYPES, "invalid snapid"); - i = snapshot_get_item(snapshots[snapid]->alt_snap, index); + i = snapshots[snapid]->m_pAltSnap->GetItem(index); if(i) { - if((char *)i < (char *)snapshots[snapid]->alt_snap || (char *)i > (char *)snapshots[snapid]->alt_snap + snapshots[snapid]->snap_size) + if((char *)i < (char *)snapshots[snapid]->m_pAltSnap || (char *)i > (char *)snapshots[snapid]->m_pAltSnap + snapshots[snapid]->m_SnapSize) dbg_msg("ASDFASDFASdf", "ASDFASDFASDF"); - if((char *)i >= (char *)snapshots[snapid]->snap && (char *)i < (char *)snapshots[snapid]->snap + snapshots[snapid]->snap_size) + if((char *)i >= (char *)snapshots[snapid]->m_pSnap && (char *)i < (char *)snapshots[snapid]->m_pSnap + snapshots[snapid]->m_SnapSize) dbg_msg("ASDFASDFASdf", "ASDFASDFASDF"); - i->type_and_id = -1; + i->m_TypeAndID = -1; } } @@ -381,11 +403,11 @@ void *snap_find_item(int snapid, int type, int id) if(!snapshots[snapid]) return 0x0; - for(i = 0; i < snapshots[snapid]->snap->num_items; i++) + for(i = 0; i < snapshots[snapid]->m_pSnap->m_NumItems; i++) { - SNAPSHOT_ITEM *itm = snapshot_get_item(snapshots[snapid]->alt_snap, i); - if(snapitem_type(itm) == type && snapitem_id(itm) == id) - return (void *)snapitem_data(itm); + CSnapshotItem *itm = snapshots[snapid]->m_pAltSnap->GetItem(i); + if(itm->Type() == type && itm->ID() == id) + return (void *)itm->Data(); } return 0x0; } @@ -395,7 +417,7 @@ int snap_num_items(int snapid) dbg_assert(snapid >= 0 && snapid < NUM_SNAPSHOT_TYPES, "invalid snapid"); if(!snapshots[snapid]) return 0; - return snapshots[snapid]->snap->num_items; + return snapshots[snapid]->m_pSnap->m_NumItems; } /* ------ time functions ------ */ @@ -412,35 +434,34 @@ float client_localtime() { return (time_get()-local_start_time)/(float)(time_fre /* ----- send functions ----- */ int client_send_msg() { - const MSG_INFO *info = msg_get_info(); - NETCHUNK packet; + const MSG_INFO *pInfo = msg_get_info(); + CNetChunk Packet; - if(!info) + if(!pInfo) return -1; if(client_state() == CLIENTSTATE_OFFLINE) return 0; - - mem_zero(&packet, sizeof(NETCHUNK)); + mem_zero(&Packet, sizeof(CNetChunk)); - packet.client_id = 0; - packet.data = info->data; - packet.data_size = info->size; + Packet.m_ClientID = 0; + Packet.m_pData = pInfo->data; + Packet.m_DataSize = pInfo->size; - if(info->flags&MSGFLAG_VITAL) - packet.flags |= NETSENDFLAG_VITAL; - if(info->flags&MSGFLAG_FLUSH) - packet.flags |= NETSENDFLAG_FLUSH; + if(pInfo->flags&MSGFLAG_VITAL) + Packet.m_Flags |= NETSENDFLAG_VITAL; + if(pInfo->flags&MSGFLAG_FLUSH) + Packet.m_Flags |= NETSENDFLAG_FLUSH; - if(info->flags&MSGFLAG_RECORD) + if(pInfo->flags&MSGFLAG_RECORD) { if(demorec_isrecording()) - demorec_record_message(packet.data, packet.data_size); + demorec_record_message(Packet.m_pData, Packet.m_DataSize); } - if(!(info->flags&MSGFLAG_NOSEND)) - netclient_send(net, &packet); + if(!(pInfo->flags&MSGFLAG_NOSEND)) + m_NetClient.Send(&Packet); return 0; } @@ -494,7 +515,7 @@ void client_rcon(const char *cmd) int client_connection_problems() { - return netclient_gotproblems(net); + return m_NetClient.GotProblems(); } void client_direct_input(int *input, int size) @@ -594,7 +615,7 @@ static void client_on_enter_game() /* reset snapshots */ snapshots[SNAP_CURRENT] = 0; snapshots[SNAP_PREV] = 0; - snapstorage_purge_all(&snapshot_storage); + snapshot_storage.PurgeAll(); recived_snapshots = 0; snapshot_parts = 0; current_predtick = 0; @@ -645,7 +666,7 @@ void client_connect(const char *server_address_str) rcon_authed = 0; server_address.port = port; - netclient_connect(net, &server_address); + m_NetClient.Connect(&server_address); client_set_state(CLIENTSTATE_CONNECTING); graph_init(&inputtime_margin_graph, -150.0f, 150.0f); @@ -659,7 +680,7 @@ void client_disconnect_with_reason(const char *reason) /* */ rcon_authed = 0; - netclient_disconnect(net, reason); + m_NetClient.Disconnect(reason); client_set_state(CLIENTSTATE_OFFLINE); map_unload(); @@ -701,7 +722,7 @@ void client_serverinfo_request() static int client_load_data() { - debug_font = gfx_load_texture("debug_font.png", IMG_AUTO, TEXLOAD_NORESAMPLE); + debug_font = Graphics()->LoadTexture("debug_font.png", IMG_AUTO, TEXLOAD_NORESAMPLE); return 1; } @@ -721,9 +742,9 @@ static void client_debug_render() if(!config.debug) return; - gfx_blend_normal(); - gfx_texture_set(debug_font); - gfx_mapscreen(0,0,gfx_screenwidth(),gfx_screenheight()); + //m_pGraphics->BlendNormal(); + Graphics()->TextureSet(debug_font); + Graphics()->MapScreen(0,0,Graphics()->ScreenWidth(),Graphics()->ScreenHeight()); if(time_get()-last_snap > time_freq()) { @@ -739,13 +760,13 @@ static void client_debug_render() total = 42 */ frametime_avg = frametime_avg*0.9f + frametime*0.1f; - str_format(buffer, sizeof(buffer), "ticks: %8d %8d mem %dk %d gfxmem: %dk fps: %3d", + str_format(buffer, sizeof(buffer), "ticks: %8d %8d mem %dk %d gfxmem: N/A fps: %3d", current_tick, current_predtick, mem_stats()->allocated/1024, mem_stats()->total_allocations, - gfx_memory_usage()/1024, + /*gfx_memory_usage()/1024, */ // TODO: Refactor: Reenable this (int)(1.0f/frametime_avg)); - gfx_quads_text(2, 2, 16, 1,1,1,1, buffer); + Graphics()->QuadsText(2, 2, 16, 1,1,1,1, buffer); { @@ -761,7 +782,7 @@ static void client_debug_render() str_format(buffer, sizeof(buffer), "send: %3d %5d+%4d=%5d (%3d kbps) avg: %5d\nrecv: %3d %5d+%4d=%5d (%3d kbps) avg: %5d", send_packets, send_bytes, send_packets*42, send_total, (send_total*8)/1024, send_bytes/send_packets, recv_packets, recv_bytes, recv_packets*42, recv_total, (recv_total*8)/1024, recv_bytes/recv_packets); - gfx_quads_text(2, 14, 16, 1,1,1,1, buffer); + Graphics()->QuadsText(2, 14, 16, 1,1,1,1, buffer); } /* render rates */ @@ -774,7 +795,7 @@ static void client_debug_render() { str_format(buffer, sizeof(buffer), "%4d %20s: %8d %8d %8d", i, modc_getitemname(i), snapshot_data_rate[i]/8, snapshot_data_updates[i], (snapshot_data_rate[i]/snapshot_data_updates[i])/8); - gfx_quads_text(2, 100+y*12, 16, 1,1,1,1, buffer); + Graphics()->QuadsText(2, 100+y*12, 16, 1,1,1,1, buffer); y++; } } @@ -783,16 +804,16 @@ static void client_debug_render() str_format(buffer, sizeof(buffer), "pred: %d ms %3.2f", (int)((st_get(&predicted_time, now)-st_get(&game_time, now))*1000/(float)time_freq()), predicted_time.adjustspeed[1]); - gfx_quads_text(2, 70, 16, 1,1,1,1, buffer); + Graphics()->QuadsText(2, 70, 16, 1,1,1,1, buffer); /* render graphs */ if(config.dbg_graphs) { - //gfx_mapscreen(0,0,400.0f,300.0f); - float w = gfx_screenwidth()/4.0f; - float h = gfx_screenheight()/6.0f; - float sp = gfx_screenwidth()/100.0f; - float x = gfx_screenwidth()-w-sp; + //Graphics()->MapScreen(0,0,400.0f,300.0f); + float w = Graphics()->ScreenWidth()/4.0f; + float h = Graphics()->ScreenHeight()/6.0f; + float sp = Graphics()->ScreenWidth()/100.0f; + float x = Graphics()->ScreenWidth()-w-sp; graph_scale_max(&fps_graph); graph_scale_min(&fps_graph); @@ -809,13 +830,13 @@ void client_quit() const char *client_error_string() { - return netclient_error_string(net); + return m_NetClient.ErrorString(); } static void client_render() { if(config.gfx_clear) - gfx_clear(1,1,0); + Graphics()->Clear(1,1,0); modc_render(); client_debug_render(); @@ -888,15 +909,15 @@ static int player_score_comp(const void *a, const void *b) return -1; } -static void client_process_packet(NETCHUNK *packet) +static void client_process_packet(CNetChunk *pPacket) { - if(packet->client_id == -1) + if(pPacket->m_ClientID == -1) { /* connectionlesss */ - if(packet->data_size == (int)(sizeof(VERSIONSRV_VERSION) + sizeof(VERSION_DATA)) && - memcmp(packet->data, VERSIONSRV_VERSION, sizeof(VERSIONSRV_VERSION)) == 0) + if(pPacket->m_DataSize == (int)(sizeof(VERSIONSRV_VERSION) + sizeof(VERSION_DATA)) && + memcmp(pPacket->m_pData, VERSIONSRV_VERSION, sizeof(VERSIONSRV_VERSION)) == 0) { - unsigned char *versiondata = (unsigned char*) packet->data + sizeof(VERSIONSRV_VERSION); + unsigned char *versiondata = (unsigned char*)pPacket->m_pData + sizeof(VERSIONSRV_VERSION); int version_match = !memcmp(versiondata, VERSION_DATA, sizeof(VERSION_DATA)); dbg_msg("client/version", "version does %s (%d.%d.%d)", @@ -910,12 +931,12 @@ static void client_process_packet(NETCHUNK *packet) } } - if(packet->data_size >= (int)sizeof(SERVERBROWSE_LIST) && - memcmp(packet->data, SERVERBROWSE_LIST, sizeof(SERVERBROWSE_LIST)) == 0) + if(pPacket->m_DataSize >= (int)sizeof(SERVERBROWSE_LIST) && + memcmp(pPacket->m_pData, SERVERBROWSE_LIST, sizeof(SERVERBROWSE_LIST)) == 0) { - int size = packet->data_size-sizeof(SERVERBROWSE_LIST); + int size = pPacket->m_DataSize-sizeof(SERVERBROWSE_LIST); int num = size/sizeof(MASTERSRV_ADDR); - MASTERSRV_ADDR *addrs = (MASTERSRV_ADDR *)((char*)packet->data+sizeof(SERVERBROWSE_LIST)); + MASTERSRV_ADDR *addrs = (MASTERSRV_ADDR *)((char*)pPacket->m_pData+sizeof(SERVERBROWSE_LIST)); int i; for(i = 0; i < num; i++) @@ -937,47 +958,47 @@ static void client_process_packet(NETCHUNK *packet) { int packet_type = 0; - if(packet->data_size >= (int)sizeof(SERVERBROWSE_INFO) && memcmp(packet->data, SERVERBROWSE_INFO, sizeof(SERVERBROWSE_INFO)) == 0) + if(pPacket->m_DataSize >= (int)sizeof(SERVERBROWSE_INFO) && memcmp(pPacket->m_pData, SERVERBROWSE_INFO, sizeof(SERVERBROWSE_INFO)) == 0) packet_type = 2; - if(packet->data_size >= (int)sizeof(SERVERBROWSE_OLD_INFO) && memcmp(packet->data, SERVERBROWSE_OLD_INFO, sizeof(SERVERBROWSE_OLD_INFO)) == 0) + if(pPacket->m_DataSize >= (int)sizeof(SERVERBROWSE_OLD_INFO) && memcmp(pPacket->m_pData, SERVERBROWSE_OLD_INFO, sizeof(SERVERBROWSE_OLD_INFO)) == 0) packet_type = 1; if(packet_type) { /* we got ze info */ - UNPACKER up; + CUnpacker up; SERVER_INFO info = {0}; int i; int token = -1; - unpacker_reset(&up, (unsigned char*)packet->data+sizeof(SERVERBROWSE_INFO), packet->data_size-sizeof(SERVERBROWSE_INFO)); + up.Reset((unsigned char*)pPacket->m_pData+sizeof(SERVERBROWSE_INFO), pPacket->m_DataSize-sizeof(SERVERBROWSE_INFO)); if(packet_type >= 2) - token = atol(unpacker_get_string(&up)); - str_copy(info.version, unpacker_get_string(&up), sizeof(info.version)); - str_copy(info.name, unpacker_get_string(&up), sizeof(info.name)); - str_copy(info.map, unpacker_get_string(&up), sizeof(info.map)); - str_copy(info.gametype, unpacker_get_string(&up), sizeof(info.gametype)); - info.flags = atol(unpacker_get_string(&up)); - info.progression = atol(unpacker_get_string(&up)); - info.num_players = atol(unpacker_get_string(&up)); - info.max_players = atol(unpacker_get_string(&up)); + token = atol(up.GetString()); + str_copy(info.version, up.GetString(), sizeof(info.version)); + str_copy(info.name, up.GetString(), sizeof(info.name)); + str_copy(info.map, up.GetString(), sizeof(info.map)); + str_copy(info.gametype, up.GetString(), sizeof(info.gametype)); + info.flags = atol(up.GetString()); + info.progression = atol(up.GetString()); + info.num_players = atol(up.GetString()); + info.max_players = atol(up.GetString()); str_format(info.address, sizeof(info.address), "%d.%d.%d.%d:%d", - packet->address.ip[0], packet->address.ip[1], packet->address.ip[2], - packet->address.ip[3], packet->address.port); + pPacket->m_Address.ip[0], pPacket->m_Address.ip[1], pPacket->m_Address.ip[2], + pPacket->m_Address.ip[3], pPacket->m_Address.port); for(i = 0; i < info.num_players; i++) { - str_copy(info.players[i].name, unpacker_get_string(&up), sizeof(info.players[i].name)); - info.players[i].score = atol(unpacker_get_string(&up)); + str_copy(info.players[i].name, up.GetString(), sizeof(info.players[i].name)); + info.players[i].score = atol(up.GetString()); } - if(!up.error) + if(!up.Error()) { /* sort players */ qsort(info.players, info.num_players, sizeof(*info.players), player_score_comp); - if(net_addr_comp(&server_address, &packet->address) == 0) + if(net_addr_comp(&server_address, &pPacket->m_Address) == 0) { mem_copy(¤t_server_info, &info, sizeof(current_server_info)); current_server_info.netaddr = server_address; @@ -986,9 +1007,9 @@ static void client_process_packet(NETCHUNK *packet) else { if(packet_type == 2) - client_serverbrowse_set(&packet->address, BROWSESET_TOKEN, token, &info); + client_serverbrowse_set(&pPacket->m_Address, BROWSESET_TOKEN, token, &info); else - client_serverbrowse_set(&packet->address, BROWSESET_OLD_INTERNET, -1, &info); + client_serverbrowse_set(&pPacket->m_Address, BROWSESET_OLD_INTERNET, -1, &info); } } } @@ -997,7 +1018,7 @@ static void client_process_packet(NETCHUNK *packet) else { int sys; - int msg = msg_unpack_start(packet->data, packet->data_size, &sys); + int msg = msg_unpack_start(pPacket->m_pData, pPacket->m_DataSize, &sys); if(sys) { @@ -1193,15 +1214,15 @@ static void client_process_packet(NETCHUNK *packet) mem_copy((char*)snapshot_incomming_data + part*MAX_SNAPSHOT_PACKSIZE, data, part_size); snapshot_parts |= 1<<part; - if(snapshot_parts == (1<<num_parts)-1) + if(snapshot_parts == (unsigned)((1<<num_parts)-1)) { - static SNAPSHOT emptysnap; - SNAPSHOT *deltashot = &emptysnap; + static CSnapshot emptysnap; + CSnapshot *deltashot = &emptysnap; int purgetick; void *deltadata; int deltasize; - unsigned char tmpbuffer2[MAX_SNAPSHOT_SIZE]; - unsigned char tmpbuffer3[MAX_SNAPSHOT_SIZE]; + unsigned char tmpbuffer2[CSnapshot::MAX_SIZE]; + unsigned char tmpbuffer3[CSnapshot::MAX_SIZE]; int snapsize; complete_size = (num_parts-1) * MAX_SNAPSHOT_PACKSIZE + part_size; @@ -1210,13 +1231,13 @@ static void client_process_packet(NETCHUNK *packet) snapshot_parts = 0; /* find snapshot that we should use as delta */ - emptysnap.data_size = 0; - emptysnap.num_items = 0; + emptysnap.m_DataSize = 0; + emptysnap.m_NumItems = 0; /* find delta */ if(delta_tick >= 0) { - int deltashot_size = snapstorage_get(&snapshot_storage, delta_tick, 0, &deltashot, 0); + int deltashot_size = snapshot_storage.Get(delta_tick, 0, &deltashot, 0); if(deltashot_size < 0) { @@ -1233,7 +1254,7 @@ static void client_process_packet(NETCHUNK *packet) } /* decompress snapshot */ - deltadata = snapshot_empty_delta(); + deltadata = CSnapshot::EmptyDelta(); deltasize = sizeof(int)*3; if(complete_size) @@ -1249,19 +1270,19 @@ static void client_process_packet(NETCHUNK *packet) /* unpack delta */ purgetick = delta_tick; - snapsize = snapshot_unpack_delta(deltashot, (SNAPSHOT*)tmpbuffer3, deltadata, deltasize); + snapsize = CSnapshot::UnpackDelta(deltashot, (CSnapshot*)tmpbuffer3, deltadata, deltasize); if(snapsize < 0) { dbg_msg("client", "delta unpack failed!"); return; } - if(msg != NETMSG_SNAPEMPTY && snapshot_crc((SNAPSHOT*)tmpbuffer3) != crc) + if(msg != NETMSG_SNAPEMPTY && ((CSnapshot*)tmpbuffer3)->Crc() != crc) { if(config.debug) { dbg_msg("client", "snapshot crc error #%d - tick=%d wantedcrc=%d gotcrc=%d compressed_size=%d delta_tick=%d", - snapcrcerrors, game_tick, crc, snapshot_crc((SNAPSHOT*)tmpbuffer3), complete_size, delta_tick); + snapcrcerrors, game_tick, crc, ((CSnapshot*)tmpbuffer3)->Crc(), complete_size, delta_tick); } snapcrcerrors++; @@ -1282,14 +1303,14 @@ static void client_process_packet(NETCHUNK *packet) /* purge old snapshots */ purgetick = delta_tick; - if(snapshots[SNAP_PREV] && snapshots[SNAP_PREV]->tick < purgetick) - purgetick = snapshots[SNAP_PREV]->tick; - if(snapshots[SNAP_CURRENT] && snapshots[SNAP_CURRENT]->tick < purgetick) - purgetick = snapshots[SNAP_PREV]->tick; - snapstorage_purge_until(&snapshot_storage, purgetick); + if(snapshots[SNAP_PREV] && snapshots[SNAP_PREV]->m_Tick < purgetick) + purgetick = snapshots[SNAP_PREV]->m_Tick; + if(snapshots[SNAP_CURRENT] && snapshots[SNAP_CURRENT]->m_Tick < purgetick) + purgetick = snapshots[SNAP_PREV]->m_Tick; + snapshot_storage.PurgeUntil(purgetick); /* add new */ - snapstorage_add(&snapshot_storage, game_tick, time_get(), snapsize, (SNAPSHOT*)tmpbuffer3, 1); + snapshot_storage.Add(game_tick, time_get(), snapsize, (CSnapshot*)tmpbuffer3, 1); /* add snapshot to demo */ if(demorec_isrecording()) @@ -1320,8 +1341,8 @@ static void client_process_packet(NETCHUNK *packet) st_init(&predicted_time, game_tick*time_freq()/50); predicted_time.adjustspeed[1] = 1000.0f; st_init(&game_time, (game_tick-1)*time_freq()/50); - snapshots[SNAP_PREV] = snapshot_storage.first; - snapshots[SNAP_CURRENT] = snapshot_storage.last; + snapshots[SNAP_PREV] = snapshot_storage.m_pFirst; + snapshots[SNAP_CURRENT] = snapshot_storage.m_pLast; local_start_time = time_get(); client_set_state(CLIENTSTATE_ONLINE); } @@ -1345,8 +1366,8 @@ static void client_process_packet(NETCHUNK *packet) { /* game message */ if(demorec_isrecording()) - demorec_record_message(packet->data, packet->data_size); - /* demorec_record_write("MESG", packet->data_size, ); */ + demorec_record_message(pPacket->m_pData, pPacket->m_DataSize); + /* demorec_record_write("MESG", pPacket->data_size, ); */ modc_message(msg); } @@ -1358,22 +1379,21 @@ int client_mapdownload_totalsize() { return mapdownload_totalsize; } static void client_pump_network() { - NETCHUNK packet; - netclient_update(net); + m_NetClient.Update(); if(client_state() != CLIENTSTATE_DEMOPLAYBACK) { /* check for errors */ - if(client_state() != CLIENTSTATE_OFFLINE && netclient_state(net) == NETSTATE_OFFLINE) + if(client_state() != CLIENTSTATE_OFFLINE && m_NetClient.State() == NETSTATE_OFFLINE) { client_set_state(CLIENTSTATE_OFFLINE); client_disconnect(); - dbg_msg("client", "offline error='%s'", netclient_error_string(net)); + dbg_msg("client", "offline error='%s'", m_NetClient.ErrorString()); } /* */ - if(client_state() == CLIENTSTATE_CONNECTING && netclient_state(net) == NETSTATE_ONLINE) + if(client_state() == CLIENTSTATE_CONNECTING && m_NetClient.State() == NETSTATE_ONLINE) { /* we switched to online */ dbg_msg("client", "connected, sending info"); @@ -1383,15 +1403,16 @@ static void client_pump_network() } /* process packets */ - while(netclient_recv(net, &packet)) - client_process_packet(&packet); + CNetChunk Packet; + while(m_NetClient.Recv(&Packet)) + client_process_packet(&Packet); } -static void client_democallback_snapshot(void *data, int size) +static void client_democallback_snapshot(void *pData, int Size) { /* update ticks, they could have changed */ const DEMOREC_PLAYBACKINFO *info = demorec_playback_info(); - SNAPSTORAGE_HOLDER *temp; + CSnapshotStorage::CHolder *temp; current_tick = info->current_tick; prev_tick = info->previous_tick; @@ -1400,8 +1421,8 @@ static void client_democallback_snapshot(void *data, int size) snapshots[SNAP_PREV] = snapshots[SNAP_CURRENT]; snapshots[SNAP_CURRENT] = temp; - mem_copy(snapshots[SNAP_CURRENT]->snap, data, size); - mem_copy(snapshots[SNAP_CURRENT]->alt_snap, data, size); + mem_copy(snapshots[SNAP_CURRENT]->m_pSnap, pData, Size); + mem_copy(snapshots[SNAP_CURRENT]->m_pAltSnap, pData, Size); modc_newsnapshot(); /*modc_predict();*/ @@ -1476,20 +1497,20 @@ static void client_update() while(1) { - SNAPSTORAGE_HOLDER *cur = snapshots[SNAP_CURRENT]; - int64 tickstart = (cur->tick)*time_freq()/50; + CSnapshotStorage::CHolder *cur = snapshots[SNAP_CURRENT]; + int64 tickstart = (cur->m_Tick)*time_freq()/50; if(tickstart < now) { - SNAPSTORAGE_HOLDER *next = snapshots[SNAP_CURRENT]->next; + CSnapshotStorage::CHolder *next = snapshots[SNAP_CURRENT]->m_pNext; if(next) { snapshots[SNAP_PREV] = snapshots[SNAP_CURRENT]; snapshots[SNAP_CURRENT] = next; /* set ticks */ - current_tick = snapshots[SNAP_CURRENT]->tick; - prev_tick = snapshots[SNAP_PREV]->tick; + current_tick = snapshots[SNAP_CURRENT]->m_Tick; + prev_tick = snapshots[SNAP_PREV]->m_Tick; if(snapshots[SNAP_CURRENT] && snapshots[SNAP_PREV]) { @@ -1506,8 +1527,8 @@ static void client_update() if(snapshots[SNAP_CURRENT] && snapshots[SNAP_PREV]) { - int64 curtick_start = (snapshots[SNAP_CURRENT]->tick)*time_freq()/50; - int64 prevtick_start = (snapshots[SNAP_PREV]->tick)*time_freq()/50; + int64 curtick_start = (snapshots[SNAP_CURRENT]->m_Tick)*time_freq()/50; + int64 prevtick_start = (snapshots[SNAP_PREV]->m_Tick)*time_freq()/50; /*tg_add(&predicted_time_graph, pred_now, 0); */ int prev_pred_tick = (int)(pred_now*50/time_freq()); int new_pred_tick = prev_pred_tick+1; @@ -1520,10 +1541,10 @@ static void client_update() prevtick_start = prev_pred_tick*time_freq()/50; predintratick = (pred_now - prevtick_start) / (float)(curtick_start-prevtick_start); - if(new_pred_tick < snapshots[SNAP_PREV]->tick-SERVER_TICK_SPEED || new_pred_tick > snapshots[SNAP_PREV]->tick+SERVER_TICK_SPEED) + if(new_pred_tick < snapshots[SNAP_PREV]->m_Tick-SERVER_TICK_SPEED || new_pred_tick > snapshots[SNAP_PREV]->m_Tick+SERVER_TICK_SPEED) { dbg_msg("client", "prediction time reset!"); - st_init(&predicted_time, snapshots[SNAP_CURRENT]->tick*time_freq()/50); + st_init(&predicted_time, snapshots[SNAP_CURRENT]->m_Tick*time_freq()/50); } if(new_pred_tick > current_predtick) @@ -1606,27 +1627,24 @@ static void client_versionupdate() { if(jobs_status(&version_serveraddr.job) == JOBSTATUS_DONE) { - NETCHUNK packet; + CNetChunk Packet; - mem_zero(&packet, sizeof(NETCHUNK)); + mem_zero(&Packet, sizeof(Packet)); version_serveraddr.addr.port = VERSIONSRV_PORT; - packet.client_id = -1; - packet.address = version_serveraddr.addr; - packet.data = VERSIONSRV_GETVERSION; - packet.data_size = sizeof(VERSIONSRV_GETVERSION); - packet.flags = NETSENDFLAG_CONNLESS; + Packet.m_ClientID = -1; + Packet.m_Address = version_serveraddr.addr; + Packet.m_pData = VERSIONSRV_GETVERSION; + Packet.m_DataSize = sizeof(VERSIONSRV_GETVERSION); + Packet.m_Flags = NETSENDFLAG_CONNLESS; - netclient_send(net, &packet); + m_NetClient.Send(&Packet); state++; } } } -extern int editor_update_and_render(); -extern void editor_init(); - static void client_run() { NETADDR bindaddr; @@ -1640,14 +1658,16 @@ static void client_run() snapshot_parts = 0; /* init graphics and sound */ - if(gfx_init() != 0) + m_pGraphics = CreateEngineGraphics(); + if(m_pGraphics->Init() != 0) return; /* start refreshing addresses while we load */ mastersrv_refresh_addresses(); /* init the editor */ - editor_init(); + m_pEditor = CreateEditor(); + m_pEditor->Init(m_pGraphics); /* sound is allowed to fail */ snd_init(); @@ -1657,12 +1677,13 @@ static void client_run() return; /* init the mod */ + m_pGameClient = CreateGameClient(&m_Client); modc_init(); dbg_msg("client", "version %s", modc_net_version()); /* open socket */ mem_zero(&bindaddr, sizeof(bindaddr)); - net = netclient_open(bindaddr, 0); + m_NetClient.Open(bindaddr, 0); /* connect to the server if wanted */ /* @@ -1714,7 +1735,7 @@ static void client_run() } /* release focus */ - if(!gfx_window_active()) + if(!Graphics()->WindowActive()) { if(window_must_refocus == 0) inp_mouse_mode_absolute(); @@ -1727,7 +1748,7 @@ static void client_run() } /* refocus */ - if(window_must_refocus && gfx_window_active()) + if(window_must_refocus && Graphics()->WindowActive()) { if(window_must_refocus < 3) { @@ -1767,8 +1788,8 @@ static void client_run() if(config.cl_editor) { client_update(); - editor_update_and_render(); - gfx_swap(); + m_pEditor->UpdateAndRender(); + m_pGraphics->Swap(); } else { @@ -1784,7 +1805,7 @@ static void client_run() if((frames%10) == 0) { client_render(); - gfx_swap(); + m_pGraphics->Swap(); } } else @@ -1799,7 +1820,7 @@ static void client_run() { static PERFORMACE_INFO scope = {"gfx_swap", 0}; perf_start(&scope); - gfx_swap(); + m_pGraphics->Swap(); perf_end(); } } @@ -1815,7 +1836,7 @@ static void client_run() /* be nice */ if(config.dbg_stress) thread_sleep(5); - else if(config.cl_cpu_throttle || !gfx_window_active()) + else if(config.cl_cpu_throttle || !Graphics()->WindowActive()) thread_sleep(1); if(config.dbg_hitch) @@ -1832,7 +1853,7 @@ static void client_run() frames/(float)(reportinterval/time_freq()), 1.0f/frametime_high, 1.0f/frametime_low, - netclient_state(net)); + m_NetClient.State()); } frametime_low = 1; frametime_high = 0; @@ -1857,10 +1878,15 @@ static void client_run() modc_shutdown(); client_disconnect(); - gfx_shutdown(); + m_pGraphics->Shutdown(); snd_shutdown(); } +void gfx_swap() +{ + m_pGraphics->Swap(); +} + static void con_connect(void *result, void *user_data) { str_copy(cmd_connect, console_arg_string(result, 0), sizeof(cmd_connect)); @@ -1886,7 +1912,7 @@ static void con_ping(void *result, void *user_data) static void con_screenshot(void *result, void *user_data) { - gfx_screenshot(); + Graphics()->TakeScreenshot(); } static void con_rcon(void *result, void *user_data) @@ -1911,7 +1937,7 @@ const char *client_demoplayer_play(const char *filename) int crc; const char *error; client_disconnect(); - netclient_error_string_reset(net); + m_NetClient.ResetErrorString(); /* try to start playback */ demorec_playback_registercallbacks(client_democallback_snapshot, client_democallback_message); @@ -1939,15 +1965,15 @@ const char *client_demoplayer_play(const char *filename) snapshots[SNAP_CURRENT] = &demorec_snapshotholders[SNAP_CURRENT]; snapshots[SNAP_PREV] = &demorec_snapshotholders[SNAP_PREV]; - snapshots[SNAP_CURRENT]->snap = (SNAPSHOT *)demorec_snapshotdata[SNAP_CURRENT][0]; - snapshots[SNAP_CURRENT]->alt_snap = (SNAPSHOT *)demorec_snapshotdata[SNAP_CURRENT][1]; - snapshots[SNAP_CURRENT]->snap_size = 0; - snapshots[SNAP_CURRENT]->tick = -1; + snapshots[SNAP_CURRENT]->m_pSnap = (CSnapshot *)demorec_snapshotdata[SNAP_CURRENT][0]; + snapshots[SNAP_CURRENT]->m_pAltSnap = (CSnapshot *)demorec_snapshotdata[SNAP_CURRENT][1]; + snapshots[SNAP_CURRENT]->m_SnapSize = 0; + snapshots[SNAP_CURRENT]->m_Tick = -1; - snapshots[SNAP_PREV]->snap = (SNAPSHOT *)demorec_snapshotdata[SNAP_PREV][0]; - snapshots[SNAP_PREV]->alt_snap = (SNAPSHOT *)demorec_snapshotdata[SNAP_PREV][1]; - snapshots[SNAP_PREV]->snap_size = 0; - snapshots[SNAP_PREV]->tick = -1; + snapshots[SNAP_PREV]->m_pSnap = (CSnapshot *)demorec_snapshotdata[SNAP_PREV][0]; + snapshots[SNAP_PREV]->m_pAltSnap = (CSnapshot *)demorec_snapshotdata[SNAP_PREV][1]; + snapshots[SNAP_PREV]->m_SnapSize = 0; + snapshots[SNAP_PREV]->m_Tick = -1; /* enter demo playback state */ client_set_state(CLIENTSTATE_DEMOPLAYBACK); diff --git a/src/engine/client/ec_gfx.c b/src/engine/client/ec_gfx.c deleted file mode 100644 index 1ea9f407..00000000 --- a/src/engine/client/ec_gfx.c +++ /dev/null @@ -1,1020 +0,0 @@ -/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */ - -#include <base/detect.h> - -#include "SDL.h" - -#ifdef CONF_FAMILY_WINDOWS - #define WIN32_LEAN_AND_MEAN - #include <windows.h> -#endif - -#ifdef CONF_PLATFORM_MACOSX - #include <OpenGL/gl.h> - #include <OpenGL/glu.h> -#else - #include <GL/gl.h> - #include <GL/glu.h> -#endif - -#include <base/system.h> -#include <engine/external/pnglite/pnglite.h> - -#include <engine/e_client_interface.h> -#include <engine/e_engine.h> -#include <engine/e_config.h> -#include <engine/e_keys.h> - -#include <string.h> -#include <stdio.h> -#include <math.h> - -/* compressed textures */ -#define GL_COMPRESSED_RGB_ARB 0x84ED -#define GL_COMPRESSED_RGBA_ARB 0x84EE -#define GL_COMPRESSED_ALPHA_ARB 0x84E9 - -#define TEXTURE_MAX_ANISOTROPY_EXT 0x84FE - -enum -{ - DRAWING_QUADS=1, - DRAWING_LINES=2 -}; - -/* */ -typedef struct { float x, y, z; } VEC3; -typedef struct { float u, v; } TEXCOORD; -typedef struct { float r, g, b, a; } COLOR; - -typedef struct -{ - VEC3 pos; - TEXCOORD tex; - COLOR color; -} VERTEX; - -const int vertex_buffer_size = 32*1024; -static VERTEX *vertices = 0; -static int num_vertices = 0; - -static int no_gfx = 0; - -static COLOR color[4]; -static TEXCOORD texture[4]; - -static int do_screenshot = 0; -static int render_enable = 1; - -static int screen_width = -1; -static int screen_height = -1; -static float rotation = 0; -static int drawing = 0; - -static float screen_x0 = 0; -static float screen_y0 = 0; -static float screen_x1 = 0; -static float screen_y1 = 0; - -static int invalid_texture = 0; - -typedef struct -{ - GLuint tex; - int memsize; - int flags; - int next; -} TEXTURE; - -enum -{ - MAX_TEXTURES = 1024*4 -}; - -static TEXTURE textures[MAX_TEXTURES]; -static int first_free_texture; -static int memory_usage = 0; - -static SDL_Surface *screen_surface; - -static const unsigned char null_texture_data[] = { - 0xff,0x00,0x00,0xff, 0xff,0x00,0x00,0xff, 0x00,0xff,0x00,0xff, 0x00,0xff,0x00,0xff, - 0xff,0x00,0x00,0xff, 0xff,0x00,0x00,0xff, 0x00,0xff,0x00,0xff, 0x00,0xff,0x00,0xff, - 0x00,0x00,0xff,0xff, 0x00,0x00,0xff,0xff, 0xff,0xff,0x00,0xff, 0xff,0xff,0x00,0xff, - 0x00,0x00,0xff,0xff, 0x00,0x00,0xff,0xff, 0xff,0xff,0x00,0xff, 0xff,0xff,0x00,0xff, -}; - -static void flush() -{ - if(num_vertices == 0) - return; - - if(no_gfx) - { - num_vertices = 0; - return; - } - - - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - glVertexPointer(3, GL_FLOAT, - sizeof(VERTEX), - (char*)vertices); - glTexCoordPointer(2, GL_FLOAT, - sizeof(VERTEX), - (char*)vertices + sizeof(float)*3); - glColorPointer(4, GL_FLOAT, - sizeof(VERTEX), - (char*)vertices + sizeof(float)*5); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - - if(render_enable) - { - if(drawing == DRAWING_QUADS) - glDrawArrays(GL_QUADS, 0, num_vertices); - else if(drawing == DRAWING_LINES) - glDrawArrays(GL_LINES, 0, num_vertices); - } - - /* Reset pointer */ - num_vertices = 0; -} - -static void add_vertices(int count) -{ - num_vertices += count; - if((num_vertices + count) >= vertex_buffer_size) - flush(); -} - -static int try_init() -{ - const SDL_VideoInfo *info; - int flags = SDL_OPENGL; - - screen_width = config.gfx_screen_width; - screen_height = config.gfx_screen_height; - - info = SDL_GetVideoInfo(); - - /* set flags */ - flags = SDL_OPENGL; - flags |= SDL_GL_DOUBLEBUFFER; - flags |= SDL_HWPALETTE; - if(config.dbg_resizable) - flags |= SDL_RESIZABLE; - - if(info->hw_available) - flags |= SDL_HWSURFACE; - else - flags |= SDL_SWSURFACE; - - if(info->blit_hw) - flags |= SDL_HWACCEL; - - if(config.gfx_fullscreen) - flags |= SDL_FULLSCREEN; - - /* set gl attributes */ - if(config.gfx_fsaa_samples) - { - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, config.gfx_fsaa_samples); - } - else - { - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0); - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0); - } - - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, config.gfx_vsync); - - /* set caption */ - SDL_WM_SetCaption("Teeworlds", "Teeworlds"); - - /* create window */ - screen_surface = SDL_SetVideoMode(screen_width, screen_height, 0, flags); - if(screen_surface == NULL) - { - dbg_msg("gfx", "unable to set video mode: %s", SDL_GetError()); - return -1; - } - - return 0; -} - -void gfx_font_init(); - -static int gfx_init_window() -{ - if(try_init() == 0) - return 0; - - /* try disabling fsaa */ - while(config.gfx_fsaa_samples) - { - config.gfx_fsaa_samples--; - - if(config.gfx_fsaa_samples) - dbg_msg("gfx", "lowering FSAA to %d and trying again", config.gfx_fsaa_samples); - else - dbg_msg("gfx", "disabling FSAA and trying again"); - - if(try_init() == 0) - return 0; - } - - /* try lowering the resolution */ - if(config.gfx_screen_width != 640 || config.gfx_screen_height != 480) - { - dbg_msg("gfx", "setting resolution to 640x480 and trying again"); - config.gfx_screen_width = 640; - config.gfx_screen_height = 480; - - if(try_init() == 0) - return 0; - } - - dbg_msg("gfx", "out of ideas. failed to init graphics"); - - return -1; -} - -int gfx_init() -{ - int i; - - if(config.dbg_stress) - no_gfx = 1; - - { - int systems = 0; - - if(!no_gfx) - systems |= SDL_INIT_VIDEO; - - if(config.snd_enable) - systems |= SDL_INIT_AUDIO; - - if(config.cl_eventthread) - systems |= SDL_INIT_EVENTTHREAD; - - if(SDL_Init(systems) < 0) - { - dbg_msg("gfx", "unable to init SDL: %s", SDL_GetError()); - return -1; - } - } - - atexit(SDL_Quit); - - if(!no_gfx) - { - #ifdef CONF_FAMILY_WINDOWS - if(!getenv("SDL_VIDEO_WINDOW_POS") && !getenv("SDL_VIDEO_CENTERED")) - putenv("SDL_VIDEO_WINDOW_POS=8,27"); - #endif - - if(gfx_init_window() != 0) - return -1; - } - - /* Init vertices */ - if (vertices) - mem_free(vertices); - vertices = (VERTEX*)mem_alloc(sizeof(VERTEX) * vertex_buffer_size, 1); - num_vertices = 0; - - - /* - dbg_msg("gfx", "OpenGL version %d.%d.%d", context.version_major(), - context.version_minor(), - context.version_rev());*/ - - - /* Set all z to -5.0f */ - for (i = 0; i < vertex_buffer_size; i++) - vertices[i].pos.z = -5.0f; - - /* init textures */ - first_free_texture = 0; - for(i = 0; i < MAX_TEXTURES; i++) - textures[i].next = i+1; - textures[MAX_TEXTURES-1].next = -1; - - if(!no_gfx) - { - SDL_ShowCursor(0); - gfx_mapscreen(0,0,config.gfx_screen_width, config.gfx_screen_height); - - /* set some default settings */ - glEnable(GL_BLEND); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - glAlphaFunc(GL_GREATER, 0); - glEnable(GL_ALPHA_TEST); - glDepthMask(0); - - - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } - - /* init input */ - inp_init(); - - /* create null texture, will get id=0 */ - invalid_texture = gfx_load_texture_raw(4,4,IMG_RGBA,null_texture_data,IMG_RGBA,TEXLOAD_NORESAMPLE); - dbg_msg("", "invalid texture id: %d %d", invalid_texture, textures[invalid_texture].tex); - - - /* font init */ - gfx_font_init(); - /* perform some tests */ - /* pixeltest_dotesting(); */ - - /*if(config.dbg_stress) - gfx_minimize();*/ - - return 0; -} - -float gfx_screenaspect() -{ - return gfx_screenwidth()/(float)gfx_screenheight(); -} - -int gfx_window_active() -{ - return SDL_GetAppState()&SDL_APPINPUTFOCUS; -} - -int gfx_window_open() -{ - return SDL_GetAppState()&SDL_APPACTIVE; -} - -VIDEO_MODE fakemodes[] = { - {320,240,8,8,8}, {400,300,8,8,8}, {640,480,8,8,8}, - {720,400,8,8,8}, {768,576,8,8,8}, {800,600,8,8,8}, - {1024,600,8,8,8}, {1024,768,8,8,8}, {1152,864,8,8,8}, - {1280,768,8,8,8}, {1280,800,8,8,8}, {1280,960,8,8,8}, - {1280,1024,8,8,8}, {1368,768,8,8,8}, {1400,1050,8,8,8}, - {1440,900,8,8,8}, {1440,1050,8,8,8}, {1600,1000,8,8,8}, - {1600,1200,8,8,8}, {1680,1050,8,8,8}, {1792,1344,8,8,8}, - {1800,1440,8,8,8}, {1856,1392,8,8,8}, {1920,1080,8,8,8}, - {1920,1200,8,8,8}, {1920,1440,8,8,8}, {1920,2400,8,8,8}, - {2048,1536,8,8,8}, - - {320,240,5,6,5}, {400,300,5,6,5}, {640,480,5,6,5}, - {720,400,5,6,5}, {768,576,5,6,5}, {800,600,5,6,5}, - {1024,600,5,6,5}, {1024,768,5,6,5}, {1152,864,5,6,5}, - {1280,768,5,6,5}, {1280,800,5,6,5}, {1280,960,5,6,5}, - {1280,1024,5,6,5}, {1368,768,5,6,5}, {1400,1050,5,6,5}, - {1440,900,5,6,5}, {1440,1050,5,6,5}, {1600,1000,5,6,5}, - {1600,1200,5,6,5}, {1680,1050,5,6,5}, {1792,1344,5,6,5}, - {1800,1440,5,6,5}, {1856,1392,5,6,5}, {1920,1080,5,6,5}, - {1920,1200,5,6,5}, {1920,1440,5,6,5}, {1920,2400,5,6,5}, - {2048,1536,5,6,5} -}; - -int gfx_get_video_modes(VIDEO_MODE *list, int maxcount) -{ - int num_modes = sizeof(fakemodes)/sizeof(VIDEO_MODE); - SDL_Rect **modes; - - if(config.gfx_display_all_modes) - { - int count = sizeof(fakemodes)/sizeof(VIDEO_MODE); - mem_copy(list, fakemodes, sizeof(fakemodes)); - if(maxcount < count) - count = maxcount; - return count; - } - - /* TODO: fix this code on osx or windows */ - - modes = SDL_ListModes(NULL, SDL_OPENGL|SDL_GL_DOUBLEBUFFER|SDL_FULLSCREEN); - if(modes == NULL) - { - /* no modes */ - num_modes = 0; - } - else if(modes == (SDL_Rect**)-1) - { - /* all modes */ - } - else - { - int i; - num_modes = 0; - for(i = 0; modes[i]; ++i) - { - if(num_modes == maxcount) - break; - list[num_modes].width = modes[i]->w; - list[num_modes].height = modes[i]->h; - list[num_modes].red = 8; - list[num_modes].green = 8; - list[num_modes].blue = 8; - num_modes++; - } - } - - return num_modes; -} - -int gfx_unload_texture(int index) -{ - if(index == invalid_texture) - return 0; - - if(index < 0) - return 0; - - glDeleteTextures(1, &textures[index].tex); - textures[index].next = first_free_texture; - memory_usage -= textures[index].memsize; - first_free_texture = index; - return 0; -} - -void gfx_blend_none() -{ - if(no_gfx) return; - glDisable(GL_BLEND); -} - -void gfx_blend_normal() -{ - if(no_gfx) return; - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -} - -void gfx_blend_additive() -{ - if(no_gfx) return; - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE); -} - -int gfx_memory_usage() { return memory_usage; } - -static unsigned char sample(int w, int h, const unsigned char *data, int u, int v, int offset) -{ - return (data[(v*w+u)*4+offset]+ - data[(v*w+u+1)*4+offset]+ - data[((v+1)*w+u)*4+offset]+ - data[((v+1)*w+u+1)*4+offset])/4; -} - -int gfx_load_texture_raw(int w, int h, int format, const void *data, int store_format, int flags) -{ - int mipmap = 1; - unsigned char *texdata = (unsigned char *)data; - unsigned char *tmpdata = 0; - int oglformat = 0; - int store_oglformat = 0; - int tex = 0; - - /* don't waste memory on texture if we are stress testing */ - if(config.dbg_stress || no_gfx) - return invalid_texture; - - /* grab texture */ - tex = first_free_texture; - first_free_texture = textures[tex].next; - textures[tex].next = -1; - - /* resample if needed */ - if(!(flags&TEXLOAD_NORESAMPLE) && config.gfx_texture_quality==0) - { - if(w > 16 && h > 16 && format == IMG_RGBA) - { - unsigned char *tmpdata; - int c = 0; - int x, y; - - tmpdata = (unsigned char *)mem_alloc(w*h*4, 1); - - w/=2; - h/=2; - - for(y = 0; y < h; y++) - for(x = 0; x < w; x++, c++) - { - tmpdata[c*4] = sample(w*2, h*2, texdata, x*2,y*2, 0); - tmpdata[c*4+1] = sample(w*2, h*2, texdata, x*2,y*2, 1); - tmpdata[c*4+2] = sample(w*2, h*2, texdata, x*2,y*2, 2); - tmpdata[c*4+3] = sample(w*2, h*2, texdata, x*2,y*2, 3); - } - texdata = tmpdata; - } - } - - oglformat = GL_RGBA; - if(format == IMG_RGB) - oglformat = GL_RGB; - else if(format == IMG_ALPHA) - oglformat = GL_ALPHA; - - /* upload texture */ - if(config.gfx_texture_compression) - { - store_oglformat = GL_COMPRESSED_RGBA_ARB; - if(store_format == IMG_RGB) - store_oglformat = GL_COMPRESSED_RGB_ARB; - else if(store_format == IMG_ALPHA) - store_oglformat = GL_COMPRESSED_ALPHA_ARB; - } - else - { - store_oglformat = GL_RGBA; - if(store_format == IMG_RGB) - store_oglformat = GL_RGB; - else if(store_format == IMG_ALPHA) - store_oglformat = GL_ALPHA; - } - - glGenTextures(1, &textures[tex].tex); - glBindTexture(GL_TEXTURE_2D, textures[tex].tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); - gluBuild2DMipmaps(GL_TEXTURE_2D, store_oglformat, w, h, oglformat, GL_UNSIGNED_BYTE, texdata); - - /* calculate memory usage */ - { - int pixel_size = 4; - if(store_format == IMG_RGB) - pixel_size = 3; - else if(store_format == IMG_ALPHA) - pixel_size = 1; - - textures[tex].memsize = w*h*pixel_size; - if(mipmap) - { - while(w > 2 && h > 2) - { - w>>=1; - h>>=1; - textures[tex].memsize += w*h*pixel_size; - } - } - } - - memory_usage += textures[tex].memsize; - mem_free(tmpdata); - return tex; -} - -/* simple uncompressed RGBA loaders */ -int gfx_load_texture(const char *filename, int store_format, int flags) -{ - int l = strlen(filename); - int id; - IMAGE_INFO img; - - if(l < 3) - return -1; - if(gfx_load_png(&img, filename)) - { - if (store_format == IMG_AUTO) - store_format = img.format; - - id = gfx_load_texture_raw(img.width, img.height, img.format, img.data, store_format, flags); - mem_free(img.data); - return id; - } - - return invalid_texture; -} - -int gfx_load_png(IMAGE_INFO *img, const char *filename) -{ - char completefilename[512]; - unsigned char *buffer; - png_t png; - - /* open file for reading */ - png_init(0,0); - - engine_getpath(completefilename, sizeof(completefilename), filename, IOFLAG_READ); - - if(png_open_file(&png, completefilename) != PNG_NO_ERROR) - { - dbg_msg("game/png", "failed to open file. filename='%s'", completefilename); - return 0; - } - - if(png.depth != 8 || (png.color_type != PNG_TRUECOLOR && png.color_type != PNG_TRUECOLOR_ALPHA)) - { - dbg_msg("game/png", "invalid format. filename='%s'", completefilename); - png_close_file(&png); - return 0; - } - - buffer = (unsigned char *)mem_alloc(png.width * png.height * png.bpp, 1); - png_get_data(&png, buffer); - png_close_file(&png); - - img->width = png.width; - img->height = png.height; - if(png.color_type == PNG_TRUECOLOR) - img->format = IMG_RGB; - else if(png.color_type == PNG_TRUECOLOR_ALPHA) - img->format = IMG_RGBA; - img->data = buffer; - return 1; -} - -void gfx_shutdown() -{ - if (vertices) - mem_free(vertices); - - /* TODO: SDL, is this correct? */ - SDL_Quit(); -} - -void gfx_screenshot() -{ - do_screenshot = 1; -} - - -extern int text_render_codepaths_usage[5]; - -void gfx_swap() -{ - /*dbg_msg("", "%d %d %d %d %d", - text_render_codepaths_usage[0], - text_render_codepaths_usage[1], - text_render_codepaths_usage[2], - text_render_codepaths_usage[3], - text_render_codepaths_usage[4]); - - text_render_codepaths_usage[0] = 0; - text_render_codepaths_usage[1] = 0; - text_render_codepaths_usage[2] = 0; - text_render_codepaths_usage[3] = 0; - text_render_codepaths_usage[4] = 0;*/ - - if(do_screenshot) - { - /* find filename */ - char filename[128]; - static int index = 1; - - for(; index < 1000; index++) - { - IOHANDLE io; - str_format(filename, sizeof(filename), "screenshots/screenshot%04d.png", index); - io = engine_openfile(filename, IOFLAG_READ); - if(io) - io_close(io); - else - break; - } - - gfx_screenshot_direct(filename); - - do_screenshot = 0; - } - - { - static PERFORMACE_INFO pscope = {"glfwSwapBuffers", 0}; - perf_start(&pscope); - SDL_GL_SwapBuffers(); - perf_end(); - } - - if(render_enable && config.gfx_finish) - glFinish(); -} - -void gfx_screenshot_direct(const char *filename) -{ - /* fetch image data */ - int y; - int w = screen_width; - int h = screen_height; - unsigned char *pixel_data = (unsigned char *)mem_alloc(w*(h+1)*4, 1); - unsigned char *temp_row = pixel_data+w*h*4; - glReadPixels(0,0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixel_data); - - /* flip the pixel because opengl works from bottom left corner */ - for(y = 0; y < h/2; y++) - { - mem_copy(temp_row, pixel_data+y*w*4, w*4); - mem_copy(pixel_data+y*w*4, pixel_data+(h-y-1)*w*4, w*4); - mem_copy(pixel_data+(h-y-1)*w*4, temp_row,w*4); - } - - /* find filename */ - { - char wholepath[1024]; - png_t png; - - engine_savepath(filename, wholepath, sizeof(wholepath)); - - /* save png */ - dbg_msg("client", "saved screenshot to '%s'", wholepath); - png_open_file_write(&png, wholepath); - png_set_data(&png, w, h, 8, PNG_TRUECOLOR_ALPHA, (unsigned char *)pixel_data); - png_close_file(&png); - } - - /* clean up */ - mem_free(pixel_data); -} - -int gfx_screenwidth() -{ - return screen_width; -} - -int gfx_screenheight() -{ - return screen_height; -} - -void gfx_texture_set(int slot) -{ - dbg_assert(drawing == 0, "called gfx_texture_set within begin"); - if(no_gfx) return; - if(slot == -1) - { - glDisable(GL_TEXTURE_2D); - } - else - { - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, textures[slot].tex); - } -} - -void gfx_clear(float r, float g, float b) -{ - if(no_gfx) return; - glClearColor(r,g,b,0.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); -} - -void gfx_mapscreen(float tl_x, float tl_y, float br_x, float br_y) -{ - screen_x0 = tl_x; - screen_y0 = tl_y; - screen_x1 = br_x; - screen_y1 = br_y; - if(no_gfx) return; - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(tl_x, br_x, br_y, tl_y, 1.0f, 10.f); -} - -void gfx_getscreen(float *tl_x, float *tl_y, float *br_x, float *br_y) -{ - *tl_x = screen_x0; - *tl_y = screen_y0; - *br_x = screen_x1; - *br_y = screen_y1; -} - -void gfx_quads_begin() -{ - dbg_assert(drawing == 0, "called quads_begin twice"); - drawing = DRAWING_QUADS; - - gfx_quads_setsubset(0,0,1,1); - gfx_quads_setrotation(0); - gfx_setcolor(1,1,1,1); -} - -void gfx_quads_end() -{ - dbg_assert(drawing == DRAWING_QUADS, "called quads_end without begin"); - flush(); - drawing = 0; -} - - -void gfx_quads_setrotation(float angle) -{ - dbg_assert(drawing == DRAWING_QUADS, "called gfx_quads_setrotation without begin"); - rotation = angle; -} - -void gfx_setcolorvertex(int i, float r, float g, float b, float a) -{ - dbg_assert(drawing != 0, "called gfx_quads_setcolorvertex without begin"); - color[i].r = r; - color[i].g = g; - color[i].b = b; - color[i].a = a; -} - -void gfx_setcolor(float r, float g, float b, float a) -{ - dbg_assert(drawing != 0, "called gfx_quads_setcolor without begin"); - gfx_setcolorvertex(0, r, g, b, a); - gfx_setcolorvertex(1, r, g, b, a); - gfx_setcolorvertex(2, r, g, b, a); - gfx_setcolorvertex(3, r, g, b, a); -} - -void gfx_quads_setsubset(float tl_u, float tl_v, float br_u, float br_v) -{ - dbg_assert(drawing == DRAWING_QUADS, "called gfx_quads_setsubset without begin"); - - texture[0].u = tl_u; texture[1].u = br_u; - texture[0].v = tl_v; texture[1].v = tl_v; - - texture[3].u = tl_u; texture[2].u = br_u; - texture[3].v = br_v; texture[2].v = br_v; -} - -void gfx_quads_setsubset_free( - float x0, float y0, float x1, float y1, - float x2, float y2, float x3, float y3) -{ - texture[0].u = x0; texture[0].v = y0; - texture[1].u = x1; texture[1].v = y1; - texture[2].u = x2; texture[2].v = y2; - texture[3].u = x3; texture[3].v = y3; -} - - -static void rotate(VEC3 *center, VEC3 *point) -{ - float x = point->x - center->x; - float y = point->y - center->y; - point->x = x * cosf(rotation) - y * sinf(rotation) + center->x; - point->y = x * sinf(rotation) + y * cosf(rotation) + center->y; -} - -void gfx_quads_draw(float x, float y, float w, float h) -{ - gfx_quads_drawTL(x-w/2, y-h/2,w,h); -} - -void gfx_quads_drawTL(float x, float y, float width, float height) -{ - VEC3 center; - - dbg_assert(drawing == DRAWING_QUADS, "called quads_draw without begin"); - - center.x = x + width/2; - center.y = y + height/2; - center.z = 0; - - vertices[num_vertices].pos.x = x; - vertices[num_vertices].pos.y = y; - vertices[num_vertices].tex = texture[0]; - vertices[num_vertices].color = color[0]; - rotate(¢er, &vertices[num_vertices].pos); - - vertices[num_vertices + 1].pos.x = x+width; - vertices[num_vertices + 1].pos.y = y; - vertices[num_vertices + 1].tex = texture[1]; - vertices[num_vertices + 1].color = color[1]; - rotate(¢er, &vertices[num_vertices + 1].pos); - - vertices[num_vertices + 2].pos.x = x + width; - vertices[num_vertices + 2].pos.y = y+height; - vertices[num_vertices + 2].tex = texture[2]; - vertices[num_vertices + 2].color = color[2]; - rotate(¢er, &vertices[num_vertices + 2].pos); - - vertices[num_vertices + 3].pos.x = x; - vertices[num_vertices + 3].pos.y = y+height; - vertices[num_vertices + 3].tex = texture[3]; - vertices[num_vertices + 3].color = color[3]; - rotate(¢er, &vertices[num_vertices + 3].pos); - - add_vertices(4); -} - -void gfx_quads_draw_freeform( - float x0, float y0, float x1, float y1, - float x2, float y2, float x3, float y3) -{ - dbg_assert(drawing == DRAWING_QUADS, "called quads_draw_freeform without begin"); - - vertices[num_vertices].pos.x = x0; - vertices[num_vertices].pos.y = y0; - vertices[num_vertices].tex = texture[0]; - vertices[num_vertices].color = color[0]; - - vertices[num_vertices + 1].pos.x = x1; - vertices[num_vertices + 1].pos.y = y1; - vertices[num_vertices + 1].tex = texture[1]; - vertices[num_vertices + 1].color = color[1]; - - vertices[num_vertices + 2].pos.x = x3; - vertices[num_vertices + 2].pos.y = y3; - vertices[num_vertices + 2].tex = texture[3]; - vertices[num_vertices + 2].color = color[3]; - - vertices[num_vertices + 3].pos.x = x2; - vertices[num_vertices + 3].pos.y = y2; - vertices[num_vertices + 3].tex = texture[2]; - vertices[num_vertices + 3].color = color[2]; - - add_vertices(4); -} - -void gfx_quads_text(float x, float y, float size, float r, float g, float b, float a, const char *text) -{ - float startx = x; - - gfx_quads_begin(); - gfx_setcolor(r,g,b,a); - - while(*text) - { - char c = *text; - text++; - - if(c == '\n') - { - x = startx; - y += size; - } - else - { - gfx_quads_setsubset( - (c%16)/16.0f, - (c/16)/16.0f, - (c%16)/16.0f+1.0f/16.0f, - (c/16)/16.0f+1.0f/16.0f); - - gfx_quads_drawTL(x,y,size,size); - x += size/2; - } - } - - gfx_quads_end(); -} - -void gfx_lines_begin() -{ - dbg_assert(drawing == 0, "called begin twice"); - drawing = DRAWING_LINES; - gfx_setcolor(1,1,1,1); -} - -void gfx_lines_end() -{ - dbg_assert(drawing == DRAWING_LINES, "called end without begin"); - flush(); - drawing = 0; -} - -void gfx_lines_draw(float x0, float y0, float x1, float y1) -{ - dbg_assert(drawing == DRAWING_LINES, "called draw without begin"); - - vertices[num_vertices].pos.x = x0; - vertices[num_vertices].pos.y = y0; - vertices[num_vertices].tex = texture[0]; - vertices[num_vertices].color = color[0]; - - vertices[num_vertices + 1].pos.x = x1; - vertices[num_vertices + 1].pos.y = y1; - vertices[num_vertices + 1].tex = texture[1]; - vertices[num_vertices + 1].color = color[1]; - - add_vertices(2); -} - -void gfx_clip_enable(int x, int y, int w, int h) -{ - if(no_gfx) return; - glScissor(x, gfx_screenheight()-(y+h), w, h); - glEnable(GL_SCISSOR_TEST); -} - -void gfx_clip_disable() -{ - if(no_gfx) return; - glDisable(GL_SCISSOR_TEST); -} - -void gfx_minimize() -{ - SDL_WM_IconifyWindow(); -} - -void gfx_maximize() -{ - /* TODO: SDL */ -} diff --git a/src/engine/client/ec_gfx.cpp b/src/engine/client/ec_gfx.cpp new file mode 100644 index 00000000..5632581a --- /dev/null +++ b/src/engine/client/ec_gfx.cpp @@ -0,0 +1,992 @@ +/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */ + +#include <base/detect.h> + +#include "SDL.h" + +#ifdef CONF_FAMILY_WINDOWS + #define WIN32_LEAN_AND_MEAN + #include <windows.h> +#endif + +#ifdef CONF_PLATFORM_MACOSX + #include <OpenGL/gl.h> + #include <OpenGL/glu.h> +#else + #include <GL/gl.h> + #include <GL/glu.h> +#endif + +#include <base/system.h> +#include <engine/external/pnglite/pnglite.h> + +#include <engine/e_client_interface.h> +#include <engine/e_engine.h> +#include <engine/e_config.h> +#include <engine/e_keys.h> + +#include <string.h> +#include <stdio.h> +#include <math.h> + +/* compressed textures */ +#define GL_COMPRESSED_RGB_ARB 0x84ED +#define GL_COMPRESSED_RGBA_ARB 0x84EE +#define GL_COMPRESSED_ALPHA_ARB 0x84E9 + +#define TEXTURE_MAX_ANISOTROPY_EXT 0x84FE + + +void gfx_font_init(); + +VIDEO_MODE fakemodes[] = { + {320,240,8,8,8}, {400,300,8,8,8}, {640,480,8,8,8}, + {720,400,8,8,8}, {768,576,8,8,8}, {800,600,8,8,8}, + {1024,600,8,8,8}, {1024,768,8,8,8}, {1152,864,8,8,8}, + {1280,768,8,8,8}, {1280,800,8,8,8}, {1280,960,8,8,8}, + {1280,1024,8,8,8}, {1368,768,8,8,8}, {1400,1050,8,8,8}, + {1440,900,8,8,8}, {1440,1050,8,8,8}, {1600,1000,8,8,8}, + {1600,1200,8,8,8}, {1680,1050,8,8,8}, {1792,1344,8,8,8}, + {1800,1440,8,8,8}, {1856,1392,8,8,8}, {1920,1080,8,8,8}, + {1920,1200,8,8,8}, {1920,1440,8,8,8}, {1920,2400,8,8,8}, + {2048,1536,8,8,8}, + + {320,240,5,6,5}, {400,300,5,6,5}, {640,480,5,6,5}, + {720,400,5,6,5}, {768,576,5,6,5}, {800,600,5,6,5}, + {1024,600,5,6,5}, {1024,768,5,6,5}, {1152,864,5,6,5}, + {1280,768,5,6,5}, {1280,800,5,6,5}, {1280,960,5,6,5}, + {1280,1024,5,6,5}, {1368,768,5,6,5}, {1400,1050,5,6,5}, + {1440,900,5,6,5}, {1440,1050,5,6,5}, {1600,1000,5,6,5}, + {1600,1200,5,6,5}, {1680,1050,5,6,5}, {1792,1344,5,6,5}, + {1800,1440,5,6,5}, {1856,1392,5,6,5}, {1920,1080,5,6,5}, + {1920,1200,5,6,5}, {1920,1440,5,6,5}, {1920,2400,5,6,5}, + {2048,1536,5,6,5} +}; + +int gfx_get_video_modes(VIDEO_MODE *list, int maxcount) +{ + int num_modes = sizeof(fakemodes)/sizeof(VIDEO_MODE); + SDL_Rect **modes; + + if(config.gfx_display_all_modes) + { + int count = sizeof(fakemodes)/sizeof(VIDEO_MODE); + mem_copy(list, fakemodes, sizeof(fakemodes)); + if(maxcount < count) + count = maxcount; + return count; + } + + /* TODO: fix this code on osx or windows */ + + modes = SDL_ListModes(NULL, SDL_OPENGL|SDL_GL_DOUBLEBUFFER|SDL_FULLSCREEN); + if(modes == NULL) + { + /* no modes */ + num_modes = 0; + } + else if(modes == (SDL_Rect**)-1) + { + /* all modes */ + } + else + { + int i; + num_modes = 0; + for(i = 0; modes[i]; ++i) + { + if(num_modes == maxcount) + break; + list[num_modes].width = modes[i]->w; + list[num_modes].height = modes[i]->h; + list[num_modes].red = 8; + list[num_modes].green = 8; + list[num_modes].blue = 8; + num_modes++; + } + } + + return num_modes; +} + + +#include "graphics.h" + +class CGraphics_OpenGL : public IEngineGraphics +{ +protected: + /* */ + typedef struct { float x, y, z; } CPoint; + typedef struct { float u, v; } CTexCoord; + typedef struct { float r, g, b, a; } CColor; + + typedef struct + { + CPoint m_Pos; + CTexCoord m_Tex; + CColor m_Color; + } CVertex; + + enum + { + MAX_VERTICES = 32*1024, + MAX_TEXTURES = 1024*4, + + DRAWING_QUADS=1, + DRAWING_LINES=2 + }; + + CVertex m_aVertices[MAX_VERTICES]; + int m_NumVertices; + + CColor m_aColor[4]; + CTexCoord m_aTexture[4]; + + bool m_RenderEnable; + + float m_Rotation; + int m_Drawing; + bool m_DoScreenshot; + + float m_ScreenX0; + float m_ScreenY0; + float m_ScreenX1; + float m_ScreenY1; + + int m_InvalidTexture; + + struct CTexture + { + GLuint tex; + int memsize; + int flags; + int next; + }; + + enum + { + + }; + + CTexture m_aTextures[MAX_TEXTURES]; + int m_FirstFreeTexture; + int m_TextureMemoryUsage; + + + void Flush() + { + if(m_NumVertices == 0) + return; + + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glVertexPointer(3, GL_FLOAT, + sizeof(CVertex), + (char*)m_aVertices); + glTexCoordPointer(2, GL_FLOAT, + sizeof(CVertex), + (char*)m_aVertices + sizeof(float)*3); + glColorPointer(4, GL_FLOAT, + sizeof(CVertex), + (char*)m_aVertices + sizeof(float)*5); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + + if(m_RenderEnable) + { + if(m_Drawing == DRAWING_QUADS) + glDrawArrays(GL_QUADS, 0, m_NumVertices); + else if(m_Drawing == DRAWING_LINES) + glDrawArrays(GL_LINES, 0, m_NumVertices); + } + + /* Reset pointer */ + m_NumVertices = 0; + } + + void AddVertices(int count) + { + m_NumVertices += count; + if((m_NumVertices + count) >= MAX_VERTICES) + Flush(); + } + + void Rotate(CPoint *pCenter, CPoint *pPoint) + { + float x = pPoint->x - pCenter->x; + float y = pPoint->y - pCenter->y; + pPoint->x = x * cosf(m_Rotation) - y * sinf(m_Rotation) + pCenter->x; + pPoint->y = x * sinf(m_Rotation) + y * cosf(m_Rotation) + pCenter->y; + } + + + + + static unsigned char sample(int w, int h, const unsigned char *data, int u, int v, int offset) + { + return (data[(v*w+u)*4+offset]+ + data[(v*w+u+1)*4+offset]+ + data[((v+1)*w+u)*4+offset]+ + data[((v+1)*w+u+1)*4+offset])/4; + } +public: + CGraphics_OpenGL() + { + m_NumVertices = 0; + + m_ScreenX0 = 0; + m_ScreenY0 = 0; + m_ScreenX1 = 0; + m_ScreenY1 = 0; + + m_ScreenWidth = -1; + m_ScreenHeight = -1; + + m_Rotation = 0; + m_Drawing = 0; + m_InvalidTexture = 0; + + m_TextureMemoryUsage = 0; + + m_RenderEnable = true; + m_DoScreenshot = false; + } + + + virtual void ClipEnable(int x, int y, int w, int h) + { + //if(no_gfx) return; + glScissor(x, ScreenHeight()-(y+h), w, h); + glEnable(GL_SCISSOR_TEST); + } + + virtual void ClipDisable() + { + //if(no_gfx) return; + glDisable(GL_SCISSOR_TEST); + } + + + virtual void BlendNone() + { + glDisable(GL_BLEND); + } + + virtual void BlendNormal() + { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + + virtual void BlendAdditive() + { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + } + + //int gfx_memory_usage() { return m_MemoryUsage; } + + virtual void MapScreen(float tl_x, float tl_y, float br_x, float br_y) + { + m_ScreenX0 = tl_x; + m_ScreenY0 = tl_y; + m_ScreenX1 = br_x; + m_ScreenY1 = br_y; + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(tl_x, br_x, br_y, tl_y, 1.0f, 10.f); + } + + virtual void GetScreen(float *tl_x, float *tl_y, float *br_x, float *br_y) + { + *tl_x = m_ScreenX0; + *tl_y = m_ScreenY0; + *br_x = m_ScreenX1; + *br_y = m_ScreenY1; + } + + virtual void LinesBegin() + { + dbg_assert(m_Drawing == 0, "called begin twice"); + m_Drawing = DRAWING_LINES; + SetColor(1,1,1,1); + } + + virtual void LinesEnd() + { + dbg_assert(m_Drawing == DRAWING_LINES, "called end without begin"); + Flush(); + m_Drawing = 0; + } + + virtual void LinesDraw(float x0, float y0, float x1, float y1) + { + dbg_assert(m_Drawing == DRAWING_LINES, "called draw without begin"); + + m_aVertices[m_NumVertices].m_Pos.x = x0; + m_aVertices[m_NumVertices].m_Pos.y = y0; + m_aVertices[m_NumVertices].m_Tex = m_aTexture[0]; + m_aVertices[m_NumVertices].m_Color = m_aColor[0]; + + m_aVertices[m_NumVertices + 1].m_Pos.x = x1; + m_aVertices[m_NumVertices + 1].m_Pos.y = y1; + m_aVertices[m_NumVertices + 1].m_Tex = m_aTexture[1]; + m_aVertices[m_NumVertices + 1].m_Color = m_aColor[1]; + + AddVertices(2); + } + + + + virtual int UnloadTexture(int Index) + { + if(Index == m_InvalidTexture) + return 0; + + if(Index < 0) + return 0; + + glDeleteTextures(1, &m_aTextures[Index].tex); + m_aTextures[Index].next = m_FirstFreeTexture; + m_TextureMemoryUsage -= m_aTextures[Index].memsize; + m_FirstFreeTexture = Index; + return 0; + } + + + virtual int LoadTextureRaw(int Width, int Height, int Format, const void *pData, int StoreFormat, int Flags) + { + int mipmap = 1; + unsigned char *texdata = (unsigned char *)pData; + unsigned char *tmpdata = 0; + int oglformat = 0; + int store_oglformat = 0; + int tex = 0; + + /* don't waste memory on texture if we are stress testing */ + if(config.dbg_stress) + return m_InvalidTexture; + + /* grab texture */ + tex = m_FirstFreeTexture; + m_FirstFreeTexture = m_aTextures[tex].next; + m_aTextures[tex].next = -1; + + /* resample if needed */ + if(!(Flags&TEXLOAD_NORESAMPLE) && config.gfx_texture_quality==0) + { + if(Width > 16 && Height > 16 && Format == IMG_RGBA) + { + unsigned char *tmpdata; + int c = 0; + int x, y; + + tmpdata = (unsigned char *)mem_alloc(Width*Height*4, 1); + + Width/=2; + Height/=2; + + for(y = 0; y < Height; y++) + for(x = 0; x < Width; x++, c++) + { + tmpdata[c*4] = sample(Width*2, Height*2, texdata, x*2,y*2, 0); + tmpdata[c*4+1] = sample(Width*2, Height*2, texdata, x*2,y*2, 1); + tmpdata[c*4+2] = sample(Width*2, Height*2, texdata, x*2,y*2, 2); + tmpdata[c*4+3] = sample(Width*2, Height*2, texdata, x*2,y*2, 3); + } + texdata = tmpdata; + } + } + + oglformat = GL_RGBA; + if(Format == IMG_RGB) + oglformat = GL_RGB; + else if(Format == IMG_ALPHA) + oglformat = GL_ALPHA; + + /* upload texture */ + if(config.gfx_texture_compression) + { + store_oglformat = GL_COMPRESSED_RGBA_ARB; + if(StoreFormat == IMG_RGB) + store_oglformat = GL_COMPRESSED_RGB_ARB; + else if(StoreFormat == IMG_ALPHA) + store_oglformat = GL_COMPRESSED_ALPHA_ARB; + } + else + { + store_oglformat = GL_RGBA; + if(StoreFormat == IMG_RGB) + store_oglformat = GL_RGB; + else if(StoreFormat == IMG_ALPHA) + store_oglformat = GL_ALPHA; + } + + glGenTextures(1, &m_aTextures[tex].tex); + glBindTexture(GL_TEXTURE_2D, m_aTextures[tex].tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + gluBuild2DMipmaps(GL_TEXTURE_2D, store_oglformat, Width, Height, oglformat, GL_UNSIGNED_BYTE, texdata); + + /* calculate memory usage */ + { + int pixel_size = 4; + if(StoreFormat == IMG_RGB) + pixel_size = 3; + else if(StoreFormat == IMG_ALPHA) + pixel_size = 1; + + m_aTextures[tex].memsize = Width*Height*pixel_size; + if(mipmap) + { + while(Width > 2 && Height > 2) + { + Width>>=1; + Height>>=1; + m_aTextures[tex].memsize += Width*Height*pixel_size; + } + } + } + + m_TextureMemoryUsage += m_aTextures[tex].memsize; + mem_free(tmpdata); + return tex; + } + + /* simple uncompressed RGBA loaders */ + virtual int LoadTexture(const char *pFilename, int StoreFormat, int Flags) + { + int l = strlen(pFilename); + int id; + IMAGE_INFO img; + + if(l < 3) + return -1; + if(LoadPNG(&img, pFilename)) + { + if (StoreFormat == IMG_AUTO) + StoreFormat = img.format; + + id = LoadTextureRaw(img.width, img.height, img.format, img.data, StoreFormat, Flags); + mem_free(img.data); + return id; + } + + return m_InvalidTexture; + } + + virtual int LoadPNG(IMAGE_INFO *pImg, const char *pFilename) + { + char aCompleteFilename[512]; + unsigned char *pBuffer; + png_t png; + + /* open file for reading */ + png_init(0,0); + + engine_getpath(aCompleteFilename, sizeof(aCompleteFilename), pFilename, IOFLAG_READ); + + if(png_open_file(&png, aCompleteFilename) != PNG_NO_ERROR) + { + dbg_msg("game/png", "failed to open file. filename='%s'", aCompleteFilename); + return 0; + } + + if(png.depth != 8 || (png.color_type != PNG_TRUECOLOR && png.color_type != PNG_TRUECOLOR_ALPHA)) + { + dbg_msg("game/png", "invalid format. filename='%s'", aCompleteFilename); + png_close_file(&png); + return 0; + } + + pBuffer = (unsigned char *)mem_alloc(png.width * png.height * png.bpp, 1); + png_get_data(&png, pBuffer); + png_close_file(&png); + + pImg->width = png.width; + pImg->height = png.height; + if(png.color_type == PNG_TRUECOLOR) + pImg->format = IMG_RGB; + else if(png.color_type == PNG_TRUECOLOR_ALPHA) + pImg->format = IMG_RGBA; + pImg->data = pBuffer; + return 1; + } + + void ScreenshotDirect(const char *filename) + { + /* fetch image data */ + int y; + int w = m_ScreenWidth; + int h = m_ScreenHeight; + unsigned char *pixel_data = (unsigned char *)mem_alloc(w*(h+1)*4, 1); + unsigned char *temp_row = pixel_data+w*h*4; + glReadPixels(0,0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixel_data); + + /* flip the pixel because opengl works from bottom left corner */ + for(y = 0; y < h/2; y++) + { + mem_copy(temp_row, pixel_data+y*w*4, w*4); + mem_copy(pixel_data+y*w*4, pixel_data+(h-y-1)*w*4, w*4); + mem_copy(pixel_data+(h-y-1)*w*4, temp_row,w*4); + } + + /* find filename */ + { + char wholepath[1024]; + png_t png; + + engine_savepath(filename, wholepath, sizeof(wholepath)); + + /* save png */ + dbg_msg("client", "saved screenshot to '%s'", wholepath); + png_open_file_write(&png, wholepath); + png_set_data(&png, w, h, 8, PNG_TRUECOLOR_ALPHA, (unsigned char *)pixel_data); + png_close_file(&png); + } + + /* clean up */ + mem_free(pixel_data); + } + + virtual void TextureSet(int TextureID) + { + dbg_assert(m_Drawing == 0, "called Graphics()->TextureSet within begin"); + if(TextureID == -1) + { + glDisable(GL_TEXTURE_2D); + } + else + { + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, m_aTextures[TextureID].tex); + } + } + + virtual void Clear(float r, float g, float b) + { + glClearColor(r,g,b,0.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + + virtual void QuadsBegin() + { + dbg_assert(m_Drawing == 0, "called quads_begin twice"); + m_Drawing = DRAWING_QUADS; + + QuadsSetSubset(0,0,1,1); + QuadsSetRotation(0); + SetColor(1,1,1,1); + } + + virtual void QuadsEnd() + { + dbg_assert(m_Drawing == DRAWING_QUADS, "called quads_end without begin"); + Flush(); + m_Drawing = 0; + } + + virtual void QuadsSetRotation(float Angle) + { + dbg_assert(m_Drawing == DRAWING_QUADS, "called Graphics()->QuadsSetRotation without begin"); + m_Rotation = Angle; + } + + virtual void SetColorVertex(int i, float r, float g, float b, float a) + { + dbg_assert(m_Drawing != 0, "called gfx_quads_setcolorvertex without begin"); + m_aColor[i].r = r; + m_aColor[i].g = g; + m_aColor[i].b = b; + m_aColor[i].a = a; + } + + virtual void SetColor(float r, float g, float b, float a) + { + dbg_assert(m_Drawing != 0, "called gfx_quads_setcolor without begin"); + SetColorVertex(0, r, g, b, a); + SetColorVertex(1, r, g, b, a); + SetColorVertex(2, r, g, b, a); + SetColorVertex(3, r, g, b, a); + } + + virtual void QuadsSetSubset(float tl_u, float tl_v, float br_u, float br_v) + { + dbg_assert(m_Drawing == DRAWING_QUADS, "called Graphics()->QuadsSetSubset without begin"); + + m_aTexture[0].u = tl_u; m_aTexture[1].u = br_u; + m_aTexture[0].v = tl_v; m_aTexture[1].v = tl_v; + + m_aTexture[3].u = tl_u; m_aTexture[2].u = br_u; + m_aTexture[3].v = br_v; m_aTexture[2].v = br_v; + } + + virtual void QuadsSetSubsetFree( + float x0, float y0, float x1, float y1, + float x2, float y2, float x3, float y3) + { + m_aTexture[0].u = x0; m_aTexture[0].v = y0; + m_aTexture[1].u = x1; m_aTexture[1].v = y1; + m_aTexture[2].u = x2; m_aTexture[2].v = y2; + m_aTexture[3].u = x3; m_aTexture[3].v = y3; + } + + virtual void QuadsDraw(float x, float y, float w, float h) + { + QuadsDrawTL(x-w/2, y-h/2,w,h); + } + + virtual void QuadsDrawTL(float x, float y, float w, float h) + { + CPoint Center; + + dbg_assert(m_Drawing == DRAWING_QUADS, "called quads_draw without begin"); + + Center.x = x + w/2; + Center.y = y + h/2; + Center.z = 0; + + m_aVertices[m_NumVertices].m_Pos.x = x; + m_aVertices[m_NumVertices].m_Pos.y = y; + m_aVertices[m_NumVertices].m_Tex = m_aTexture[0]; + m_aVertices[m_NumVertices].m_Color = m_aColor[0]; + Rotate(&Center, &m_aVertices[m_NumVertices].m_Pos); + + m_aVertices[m_NumVertices + 1].m_Pos.x = x+w; + m_aVertices[m_NumVertices + 1].m_Pos.y = y; + m_aVertices[m_NumVertices + 1].m_Tex = m_aTexture[1]; + m_aVertices[m_NumVertices + 1].m_Color = m_aColor[1]; + Rotate(&Center, &m_aVertices[m_NumVertices + 1].m_Pos); + + m_aVertices[m_NumVertices + 2].m_Pos.x = x + w; + m_aVertices[m_NumVertices + 2].m_Pos.y = y+h; + m_aVertices[m_NumVertices + 2].m_Tex = m_aTexture[2]; + m_aVertices[m_NumVertices + 2].m_Color = m_aColor[2]; + Rotate(&Center, &m_aVertices[m_NumVertices + 2].m_Pos); + + m_aVertices[m_NumVertices + 3].m_Pos.x = x; + m_aVertices[m_NumVertices + 3].m_Pos.y = y+h; + m_aVertices[m_NumVertices + 3].m_Tex = m_aTexture[3]; + m_aVertices[m_NumVertices + 3].m_Color = m_aColor[3]; + Rotate(&Center, &m_aVertices[m_NumVertices + 3].m_Pos); + + AddVertices(4); + } + + void QuadsDrawFreeform( + float x0, float y0, float x1, float y1, + float x2, float y2, float x3, float y3) + { + dbg_assert(m_Drawing == DRAWING_QUADS, "called quads_draw_freeform without begin"); + + m_aVertices[m_NumVertices].m_Pos.x = x0; + m_aVertices[m_NumVertices].m_Pos.y = y0; + m_aVertices[m_NumVertices].m_Tex = m_aTexture[0]; + m_aVertices[m_NumVertices].m_Color = m_aColor[0]; + + m_aVertices[m_NumVertices + 1].m_Pos.x = x1; + m_aVertices[m_NumVertices + 1].m_Pos.y = y1; + m_aVertices[m_NumVertices + 1].m_Tex = m_aTexture[1]; + m_aVertices[m_NumVertices + 1].m_Color = m_aColor[1]; + + m_aVertices[m_NumVertices + 2].m_Pos.x = x3; + m_aVertices[m_NumVertices + 2].m_Pos.y = y3; + m_aVertices[m_NumVertices + 2].m_Tex = m_aTexture[3]; + m_aVertices[m_NumVertices + 2].m_Color = m_aColor[3]; + + m_aVertices[m_NumVertices + 3].m_Pos.x = x2; + m_aVertices[m_NumVertices + 3].m_Pos.y = y2; + m_aVertices[m_NumVertices + 3].m_Tex = m_aTexture[2]; + m_aVertices[m_NumVertices + 3].m_Color = m_aColor[2]; + + AddVertices(4); + } + + virtual void QuadsText(float x, float y, float Size, float r, float g, float b, float a, const char *pText) + { + float startx = x; + + QuadsBegin(); + SetColor(r,g,b,a); + + while(*pText) + { + char c = *pText; + pText++; + + if(c == '\n') + { + x = startx; + y += Size; + } + else + { + QuadsSetSubset( + (c%16)/16.0f, + (c/16)/16.0f, + (c%16)/16.0f+1.0f/16.0f, + (c/16)/16.0f+1.0f/16.0f); + + QuadsDrawTL(x,y,Size,Size); + x += Size/2; + } + } + + QuadsEnd(); + } + + virtual bool Init() + { + /* Set all z to -5.0f */ + for(int i = 0; i < MAX_VERTICES; i++) + m_aVertices[i].m_Pos.z = -5.0f; + + /* init textures */ + m_FirstFreeTexture = 0; + for(int i = 0; i < MAX_TEXTURES; i++) + m_aTextures[i].next = i+1; + m_aTextures[MAX_TEXTURES-1].next = -1; + + /* set some default settings */ + glEnable(GL_BLEND); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glAlphaFunc(GL_GREATER, 0); + glEnable(GL_ALPHA_TEST); + glDepthMask(0); + + /* create null texture, will get id=0 */ + static const unsigned char aNullTextureData[] = { + 0xff,0x00,0x00,0xff, 0xff,0x00,0x00,0xff, 0x00,0xff,0x00,0xff, 0x00,0xff,0x00,0xff, + 0xff,0x00,0x00,0xff, 0xff,0x00,0x00,0xff, 0x00,0xff,0x00,0xff, 0x00,0xff,0x00,0xff, + 0x00,0x00,0xff,0xff, 0x00,0x00,0xff,0xff, 0xff,0xff,0x00,0xff, 0xff,0xff,0x00,0xff, + 0x00,0x00,0xff,0xff, 0x00,0x00,0xff,0xff, 0xff,0xff,0x00,0xff, 0xff,0xff,0x00,0xff, + }; + + m_InvalidTexture = LoadTextureRaw(4,4,IMG_RGBA,aNullTextureData,IMG_RGBA,TEXLOAD_NORESAMPLE); + dbg_msg("", "invalid texture id: %d %d", m_InvalidTexture, m_aTextures[m_InvalidTexture].tex); + + return true; + } +}; + +class CGraphics_SDL : public CGraphics_OpenGL +{ + SDL_Surface *m_pScreenSurface; + + int TryInit() + { + const SDL_VideoInfo *pInfo; + int Flags = SDL_OPENGL; + + m_ScreenWidth = config.gfx_screen_width; + m_ScreenHeight = config.gfx_screen_height; + + pInfo = SDL_GetVideoInfo(); + + /* set flags */ + Flags = SDL_OPENGL; + Flags |= SDL_GL_DOUBLEBUFFER; + Flags |= SDL_HWPALETTE; + if(config.dbg_resizable) + Flags |= SDL_RESIZABLE; + + if(pInfo->hw_available) + Flags |= SDL_HWSURFACE; + else + Flags |= SDL_SWSURFACE; + + if(pInfo->blit_hw) + Flags |= SDL_HWACCEL; + + if(config.gfx_fullscreen) + Flags |= SDL_FULLSCREEN; + + /* set gl attributes */ + if(config.gfx_fsaa_samples) + { + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, config.gfx_fsaa_samples); + } + else + { + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0); + } + + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, config.gfx_vsync); + + /* set caption */ + SDL_WM_SetCaption("Teeworlds", "Teeworlds"); + + /* create window */ + m_pScreenSurface = SDL_SetVideoMode(m_ScreenWidth, m_ScreenHeight, 0, Flags); + if(m_pScreenSurface == NULL) + { + dbg_msg("gfx", "unable to set video mode: %s", SDL_GetError()); + return -1; + } + + return 0; + } + + + int InitWindow() + { + if(TryInit() == 0) + return 0; + + /* try disabling fsaa */ + while(config.gfx_fsaa_samples) + { + config.gfx_fsaa_samples--; + + if(config.gfx_fsaa_samples) + dbg_msg("gfx", "lowering FSAA to %d and trying again", config.gfx_fsaa_samples); + else + dbg_msg("gfx", "disabling FSAA and trying again"); + + if(TryInit() == 0) + return 0; + } + + /* try lowering the resolution */ + if(config.gfx_screen_width != 640 || config.gfx_screen_height != 480) + { + dbg_msg("gfx", "setting resolution to 640x480 and trying again"); + config.gfx_screen_width = 640; + config.gfx_screen_height = 480; + + if(TryInit() == 0) + return 0; + } + + dbg_msg("gfx", "out of ideas. failed to init graphics"); + + return -1; + } + + +public: + CGraphics_SDL() + { + m_pScreenSurface = 0; + } + + virtual bool Init() + { + { + int Systems = SDL_INIT_VIDEO; + + if(config.snd_enable) + Systems |= SDL_INIT_AUDIO; + + if(config.cl_eventthread) + Systems |= SDL_INIT_EVENTTHREAD; + + if(SDL_Init(Systems) < 0) + { + dbg_msg("gfx", "unable to init SDL: %s", SDL_GetError()); + return -1; + } + } + + atexit(SDL_Quit); + + #ifdef CONF_FAMILY_WINDOWS + if(!getenv("SDL_VIDEO_WINDOW_POS") && !getenv("SDL_VIDEO_CENTERED")) + putenv("SDL_VIDEO_WINDOW_POS=8,27"); + #endif + + if(InitWindow() != 0) + return -1; + + SDL_ShowCursor(0); + + CGraphics_OpenGL::Init(); + + MapScreen(0,0,config.gfx_screen_width, config.gfx_screen_height); + + /* init input */ + inp_init(); + + /* font init */ + gfx_font_init(); + + return 0; + } + + virtual void Shutdown() + { + /* TODO: SDL, is this correct? */ + SDL_Quit(); + } + + virtual void Minimize() + { + SDL_WM_IconifyWindow(); + } + + virtual void Maximize() + { + /* TODO: SDL */ + } + + virtual int WindowActive() + { + return SDL_GetAppState()&SDL_APPINPUTFOCUS; + } + + virtual int WindowOpen() + { + return SDL_GetAppState()&SDL_APPACTIVE; + + } + + virtual void TakeScreenshot() + { + m_DoScreenshot = true; + } + + virtual void Swap() + { + if(m_DoScreenshot) + { + /* find filename */ + char filename[128]; + static int index = 1; + + for(; index < 1000; index++) + { + IOHANDLE io; + str_format(filename, sizeof(filename), "screenshots/screenshot%04d.png", index); + io = engine_openfile(filename, IOFLAG_READ); + if(io) + io_close(io); + else + break; + } + + ScreenshotDirect(filename); + m_DoScreenshot = false; + } + + { + static PERFORMACE_INFO pscope = {"glfwSwapBuffers", 0}; + perf_start(&pscope); + SDL_GL_SwapBuffers(); + perf_end(); + } + + if(config.gfx_finish) + glFinish(); + } +}; + +extern IEngineGraphics *CreateEngineGraphics() { return new CGraphics_SDL(); } diff --git a/src/engine/client/ec_gfx_text.c b/src/engine/client/ec_gfx_text.cpp index de40e391..d17d1bed 100644 --- a/src/engine/client/ec_gfx_text.c +++ b/src/engine/client/ec_gfx_text.cpp @@ -1,7 +1,9 @@ #include <base/system.h> #include <string.h> #include <engine/e_client_interface.h> +#include <engine/client/graphics.h> +extern IEngineGraphics *Graphics(); #ifdef CONF_PLATFORM_MACOSX #include <OpenGL/gl.h> @@ -138,8 +140,7 @@ typedef struct FONT static int font_get_index(int pixelsize) { - int i; - for(i = 0; i < NUM_FONT_SIZES; i++) + for(unsigned i = 0; i < NUM_FONT_SIZES; i++) { if(font_sizes[i] >= pixelsize) return i; @@ -150,8 +151,7 @@ static int font_get_index(int pixelsize) FONT *gfx_font_load(const char *filename) { - int i; - FONT *font = mem_alloc(sizeof(FONT), 1); + FONT *font = (FONT *)mem_alloc(sizeof(FONT), 1); mem_zero(font, sizeof(*font)); str_copy(font->filename, filename, sizeof(font->filename)); @@ -162,7 +162,7 @@ FONT *gfx_font_load(const char *filename) return NULL; } - for(i = 0; i < NUM_FONT_SIZES; i++) + for(unsigned i = 0; i < NUM_FONT_SIZES; i++) font->sizes[i].font_size = -1; return font; @@ -484,6 +484,7 @@ static float font_kerning(FONT *font, int left, int right) return (kerning.x>>6); } + void gfx_text_ex(TEXT_CURSOR *cursor, const char *text, int length) { FONT *font = cursor->font; @@ -503,10 +504,10 @@ void gfx_text_ex(TEXT_CURSOR *cursor, const char *text, int length) float size = cursor->font_size; /* to correct coords, convert to screen coords, round, and convert back */ - gfx_getscreen(&screen_x0, &screen_y0, &screen_x1, &screen_y1); + Graphics()->GetScreen(&screen_x0, &screen_y0, &screen_x1, &screen_y1); - fake_to_screen_x = (gfx_screenwidth()/(screen_x1-screen_x0)); - fake_to_screen_y = (gfx_screenheight()/(screen_y1-screen_y0)); + fake_to_screen_x = (Graphics()->ScreenWidth()/(screen_x1-screen_x0)); + fake_to_screen_y = (Graphics()->ScreenHeight()/(screen_y1-screen_y0)); actual_x = cursor->x * fake_to_screen_x; actual_y = cursor->y * fake_to_screen_y; @@ -554,11 +555,11 @@ void gfx_text_ex(TEXT_CURSOR *cursor, const char *text, int length) else glBindTexture(GL_TEXTURE_2D, sizedata->textures[0]); - gfx_quads_begin(); + Graphics()->QuadsBegin(); if (i == 0) - gfx_setcolor(0.0f, 0.0f, 0.0f, 0.3f*text_a); + Graphics()->SetColor(0.0f, 0.0f, 0.0f, 0.3f*text_a); else - gfx_setcolor(text_r, text_g, text_b, text_a); + Graphics()->SetColor(text_r, text_g, text_b, text_a); } while(current < end) @@ -629,8 +630,8 @@ void gfx_text_ex(TEXT_CURSOR *cursor, const char *text, int length) { if(cursor->flags&TEXTFLAG_RENDER) { - gfx_quads_setsubset(chr->uvs[0], chr->uvs[1], chr->uvs[2], chr->uvs[3]); - gfx_quads_drawTL(draw_x+chr->offset_x*size, draw_y+chr->offset_y*size, chr->width*size, chr->height*size); + Graphics()->QuadsSetSubset(chr->uvs[0], chr->uvs[1], chr->uvs[2], chr->uvs[3]); + Graphics()->QuadsDrawTL(draw_x+chr->offset_x*size, draw_y+chr->offset_y*size, chr->width*size, chr->height*size); } advance = chr->advance_x + font_kerning(font, character, nextcharacter)/size; @@ -658,7 +659,7 @@ void gfx_text_ex(TEXT_CURSOR *cursor, const char *text, int length) } if(cursor->flags&TEXTFLAG_RENDER) - gfx_quads_end(); + Graphics()->QuadsEnd(); } cursor->x = draw_x; diff --git a/src/engine/client/ec_inp.c b/src/engine/client/ec_inp.cpp index 495614d6..cf956471 100644 --- a/src/engine/client/ec_inp.c +++ b/src/engine/client/ec_inp.cpp @@ -5,6 +5,7 @@ #include <base/system.h> #include <engine/e_client_interface.h> #include <engine/e_config.h> +#include <engine/client/graphics.h> static struct { @@ -20,6 +21,9 @@ static int input_grabbed = 0; static unsigned int last_release = 0; static unsigned int release_delta = -1; +// TODO: Refactor: Remove this +extern IEngineGraphics *Graphics(); + void inp_mouse_relative(int *x, int *y) { int nx = 0, ny = 0; @@ -32,8 +36,8 @@ void inp_mouse_relative(int *x, int *y) if(input_grabbed) { SDL_GetMouseState(&nx,&ny); - SDL_WarpMouse(gfx_screenwidth()/2,gfx_screenheight()/2); - nx -= gfx_screenwidth()/2; ny -= gfx_screenheight()/2; + SDL_WarpMouse(Graphics()->ScreenWidth()/2,Graphics()->ScreenHeight()/2); + nx -= Graphics()->ScreenWidth()/2; ny -= Graphics()->ScreenHeight()/2; } } @@ -138,10 +142,10 @@ void inp_update() { int i; - if(input_grabbed && !gfx_window_active()) + if(input_grabbed && !Graphics()->WindowActive()) inp_mouse_mode_absolute(); - /*if(!input_grabbed && gfx_window_active()) + /*if(!input_grabbed && Graphics()->WindowActive()) inp_mouse_mode_relative();*/ /* clear and begin count on the other one */ diff --git a/src/engine/client/ec_snd.c b/src/engine/client/ec_snd.cpp index ac41ec59..3baea982 100644 --- a/src/engine/client/ec_snd.c +++ b/src/engine/client/ec_snd.cpp @@ -1,12 +1,15 @@ /* copyright (c) 2007 magnus auvinen, see licence.txt for more info */ #include <base/system.h> #include <engine/e_client_interface.h> +#include <engine/client/graphics.h> #include <engine/e_config.h> #include <engine/e_engine.h> #include "SDL.h" -#include <engine/external/wavpack/wavpack.h> +extern "C" { // wavpack + #include <engine/external/wavpack/wavpack.h> +} #include <stdio.h> #include <stdlib.h> #include <math.h> @@ -140,7 +143,6 @@ static int iabs(int i) static void mix(short *final_out, unsigned frames) { int mix_buffer[MAX_FRAMES*2] = {0}; - int i, s; int master_vol; /* aquire lock while we are mixing */ @@ -148,7 +150,7 @@ static void mix(short *final_out, unsigned frames) master_vol = sound_volume; - for(i = 0; i < NUM_VOICES; i++) + for(unsigned i = 0; i < NUM_VOICES; i++) { if(voices[i].snd) { @@ -160,7 +162,7 @@ static void mix(short *final_out, unsigned frames) short *in_l = &v->snd->data[v->tick*step]; short *in_r = &v->snd->data[v->tick*step+1]; - int end = v->snd->num_frames-v->tick; + unsigned end = v->snd->num_frames-v->tick; int rvol = v->channel->vol; int lvol = v->channel->vol; @@ -202,7 +204,7 @@ static void mix(short *final_out, unsigned frames) } /* process all frames */ - for(s = 0; s < end; s++) + for(unsigned s = 0; s < end; s++) { *out++ += (*in_l)*lvol; *out++ += (*in_r)*rvol; @@ -225,7 +227,7 @@ static void mix(short *final_out, unsigned frames) { /* clamp accumulated values */ /* TODO: this seams slow */ - for(i = 0; i < frames; i++) + for(unsigned i = 0; i < frames; i++) { int j = i<<1; int vl = ((mix_buffer[j]*master_vol)/101)>>8; @@ -281,12 +283,16 @@ int snd_init() return 0; } +// TODO: Refactor: Remove this +extern IEngineGraphics *Graphics(); + + int snd_update() { /* update volume */ int wanted_volume = config.snd_volume; - if(!gfx_window_active() && config.snd_nonactive_mute) + if(!Graphics()->WindowActive() && config.snd_nonactive_mute) wanted_volume = 0; if(wanted_volume != sound_volume) @@ -332,7 +338,7 @@ static void rate_convert(int sid) /* allocate new data */ num_frames = (int)((snd->num_frames/(float)snd->rate)*mixing_rate); - new_data = mem_alloc(num_frames*snd->channels*sizeof(short), 1); + new_data = (short *)mem_alloc(num_frames*snd->channels*sizeof(short), 1); for(i = 0; i < num_frames; i++) { diff --git a/src/engine/client/ec_srvbrowse.c b/src/engine/client/ec_srvbrowse.cpp index 4a85e778..1b04937a 100644 --- a/src/engine/client/ec_srvbrowse.c +++ b/src/engine/client/ec_srvbrowse.cpp @@ -11,7 +11,7 @@ #include <string.h> #include <stdlib.h> -extern NETCLIENT *net; +extern CNetClient m_NetClient; /* ------ server browse ---- */ @@ -150,7 +150,7 @@ static void client_serverbrowse_filter() if(sorted_serverlist) mem_free(sorted_serverlist); num_sorted_servers_capacity = num_servers; - sorted_serverlist = mem_alloc(num_sorted_servers_capacity*sizeof(int), 1); + sorted_serverlist = (int *)mem_alloc(num_sorted_servers_capacity*sizeof(int), 1); } /* filter the servers */ @@ -401,7 +401,7 @@ SERVERENTRY *client_serverbrowse_add(NETADDR *addr) { SERVERENTRY **newlist; num_server_capacity += 100; - newlist = mem_alloc(num_server_capacity*sizeof(SERVERENTRY*), 1); + newlist = (SERVERENTRY **)mem_alloc(num_server_capacity*sizeof(SERVERENTRY*), 1); mem_copy(newlist, serverlist, num_servers*sizeof(SERVERENTRY*)); mem_free(serverlist); serverlist = newlist; @@ -506,28 +506,28 @@ void client_serverbrowse_refresh(int type) if(type == BROWSETYPE_LAN) { - unsigned char buffer[sizeof(SERVERBROWSE_GETINFO)+1]; - NETCHUNK packet; + unsigned char Buffer[sizeof(SERVERBROWSE_GETINFO)+1]; + CNetChunk Packet; int i; - mem_copy(buffer, SERVERBROWSE_GETINFO, sizeof(SERVERBROWSE_GETINFO)); - buffer[sizeof(SERVERBROWSE_GETINFO)] = current_token; + mem_copy(Buffer, SERVERBROWSE_GETINFO, sizeof(SERVERBROWSE_GETINFO)); + Buffer[sizeof(SERVERBROWSE_GETINFO)] = current_token; - packet.client_id = -1; - mem_zero(&packet, sizeof(packet)); - packet.address.ip[0] = 255; - packet.address.ip[1] = 255; - packet.address.ip[2] = 255; - packet.address.ip[3] = 255; - packet.flags = NETSENDFLAG_CONNLESS; - packet.data_size = sizeof(buffer); - packet.data = buffer; + Packet.m_ClientID = -1; + mem_zero(&Packet, sizeof(Packet)); + Packet.m_Address.ip[0] = 255; + Packet.m_Address.ip[1] = 255; + Packet.m_Address.ip[2] = 255; + Packet.m_Address.ip[3] = 255; + Packet.m_Flags = NETSENDFLAG_CONNLESS; + Packet.m_DataSize = sizeof(Buffer); + Packet.m_pData = Buffer; broadcast_time = time_get(); for(i = 8303; i <= 8310; i++) { - packet.address.port = i; - netclient_send(net, &packet); + Packet.m_Address.port = i; + m_NetClient.Send(&Packet); } if(config.debug) @@ -537,8 +537,7 @@ void client_serverbrowse_refresh(int type) need_refresh = 1; else if(type == BROWSETYPE_FAVORITES) { - int i; - for(i = 0; i < num_favorite_servers; i++) + for(int i = 0; i < num_favorite_servers; i++) client_serverbrowse_set(&favorite_servers[i], BROWSESET_FAV_ADD, -1, 0); } } @@ -546,7 +545,7 @@ void client_serverbrowse_refresh(int type) static void client_serverbrowse_request_impl(NETADDR *addr, SERVERENTRY *entry) { /*unsigned char buffer[sizeof(SERVERBROWSE_GETINFO)+1];*/ - NETCHUNK p; + CNetChunk Packet; if(config.debug) { @@ -558,17 +557,17 @@ static void client_serverbrowse_request_impl(NETADDR *addr, SERVERENTRY *entry) /*mem_copy(buffer, SERVERBROWSE_GETINFO, sizeof(SERVERBROWSE_GETINFO)); buffer[sizeof(SERVERBROWSE_GETINFO)] = current_token;*/ - p.client_id = -1; - p.address = *addr; - p.flags = NETSENDFLAG_CONNLESS; + Packet.m_ClientID = -1; + Packet.m_Address = *addr; + Packet.m_Flags = NETSENDFLAG_CONNLESS; /*p.data_size = sizeof(buffer); p.data = buffer; netclient_send(net, &p);*/ /* send old requtest style aswell */ - p.data_size = sizeof(SERVERBROWSE_OLD_GETINFO); - p.data = SERVERBROWSE_OLD_GETINFO; - netclient_send(net, &p); + Packet.m_DataSize = sizeof(SERVERBROWSE_OLD_GETINFO); + Packet.m_pData = SERVERBROWSE_OLD_GETINFO; + m_NetClient.Send(&Packet); if(entry) entry->request_time = time_get(); @@ -591,16 +590,16 @@ void client_serverbrowse_update() if(need_refresh && !mastersrv_refreshing()) { NETADDR addr; - NETCHUNK p; + CNetChunk Packet; int i; need_refresh = 0; - mem_zero(&p, sizeof(p)); - p.client_id = -1; - p.flags = NETSENDFLAG_CONNLESS; - p.data_size = sizeof(SERVERBROWSE_GETLIST); - p.data = SERVERBROWSE_GETLIST; + mem_zero(&Packet, sizeof(Packet)); + Packet.m_ClientID = -1; + Packet.m_Flags = NETSENDFLAG_CONNLESS; + Packet.m_DataSize = sizeof(SERVERBROWSE_GETLIST); + Packet.m_pData = SERVERBROWSE_GETLIST; for(i = 0; i < MAX_MASTERSERVERS; i++) { @@ -608,8 +607,8 @@ void client_serverbrowse_update() if(!addr.ip[0] && !addr.ip[1] && !addr.ip[2] && !addr.ip[3]) continue; - p.address = addr; - netclient_send(net, &p); + Packet.m_Address = addr; + m_NetClient.Send(&Packet); } if(config.debug) |