Created
November 15, 2024 20:50
-
-
Save kdrnic/f5fc0c48cb86d34ad8cd6ae896097950 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <allegro.h> | |
#include <winalleg.h> | |
#include <libnet.h> | |
#include <ctype.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <strings.h> | |
#include <time.h> | |
#include <stdint.h> | |
#include <assert.h> | |
#include <ctype.h> | |
static char config_filename[] = "nettest.cfg"; | |
static double realtime; | |
static char logp_temp[5000]; | |
static char error_string[5000]; | |
static char name[32] = "Guest12345"; | |
static char logp_buffer[99999]; | |
static double tick_interval = 1.0 / 20.0; | |
static double last_tick = -999.0; | |
static int tick_count = 0; | |
static int has_logput; | |
static void log_puts(const char *str) | |
{ | |
if(!*str) str++; | |
if(strlen(str) + strlen(logp_buffer) + 1 > sizeof(logp_buffer)) logp_buffer[0] = 0; | |
strcat(logp_buffer, str); | |
strcat(logp_buffer, "\n"); | |
has_logput = 1; | |
} | |
#include "net.h" | |
static void NET_GAME_CL_JOIN(kdrnet_cl_t *cls){} | |
static void NET_GAME_CL_LEAVE(kdrnet_cl_t *cls){} | |
static void NET_GAME_SV_JOIN(kdrnet_sv_t *svs, kdrnet_sv_client *c){} | |
static void NET_GAME_SV_LEAVE(kdrnet_sv_t *svs, kdrnet_sv_client *c){} | |
static void NET_GAME_SV_READ(kdrnet_sv_t *svs, struct kdrnet_sv_client *cl); | |
static void NET_GAME_SV_WRITERELIABLE(kdrnet_sv_t *svs, struct kdrnet_sv_client *cl); | |
static int NET_GAME_SV_WRITEDGRAM(kdrnet_sv_t *svs, struct kdrnet_sv_client *cl, struct sizedbuf *buf); | |
static void NET_GAME_CL_READ(kdrnet_cl_t *cls); | |
static void NET_GAME_CL_WRITE(kdrnet_cl_t *cls, struct sizedbuf *buf); | |
static void NET_GAME_SV_BEGINWRITE(kdrnet_sv_t *svs); | |
static void NET_GAME_SV_ENDWRITE(kdrnet_sv_t *svs); | |
static double get_realtime(void) | |
{ | |
return realtime; | |
} | |
#define base_nc {.log_puts = log_puts, .get_realtime = get_realtime} | |
static kdrnet_cl_t cls = { | |
base_nc, | |
.on_join = NET_GAME_CL_JOIN, | |
.on_leave = NET_GAME_CL_LEAVE, | |
.on_read = NET_GAME_CL_READ, | |
.do_write = NET_GAME_CL_WRITE | |
}; | |
static kdrnet_sv_t svs = { | |
base_nc, | |
.on_join = NET_GAME_SV_JOIN, | |
.on_leave = NET_GAME_SV_LEAVE, | |
.on_read = NET_GAME_SV_READ, | |
.do_write_reliable = NET_GAME_SV_WRITERELIABLE, | |
.do_write_dgram = NET_GAME_SV_WRITEDGRAM, | |
.on_begin_write = NET_GAME_SV_BEGINWRITE, | |
.on_end_write = NET_GAME_SV_ENDWRITE | |
}; | |
static kdrnet_common *nc = 0; | |
static char address[NET_MAX_ADDRESS_LENGTH] = "127.0.0.1"; | |
static NET_DRIVERNAME *drivernames; | |
static NET_DRIVERLIST avail; | |
static char status[640 / 8] = "Set up connection settings below"; | |
static int num_messages_rec = 0; | |
static int num_messages_snt = 0; | |
static int first_connected = 0; | |
static char str_mrec[20] = "0"; | |
static char str_msnt[20] = "0"; | |
static int wave_y, their_wave_y; | |
static int foolish_counter = 0; | |
static char send_string[256] = ""; | |
static char peer_name[32] = ""; | |
static int send_reset = 0; | |
static char broadcast_string[4096]; | |
#define WHITE 0xFFFFFF | |
#define BLUE 0xff | |
#define GREEN 0xFF00 | |
static char chat_string[128] = ""; | |
enum | |
{ | |
CMD_SETWAVEY = 45, | |
CMD_PRINT = 79, | |
CMD_RESET = 97 | |
}; | |
void NET_GAME_SV_BEGINWRITE(kdrnet_sv_t *svs) | |
{ | |
} | |
void NET_GAME_SV_ENDWRITE(kdrnet_sv_t *svs) | |
{ | |
broadcast_string[0] = 0; | |
} | |
static void parsecmd(int c); | |
static void parsecmd_sv(int c) | |
{ | |
if(c == CMD_PRINT){ | |
char str[2048], *line; | |
szb_readstring(&nc->message, str); | |
line = strtok(str, "\n"); | |
while(line){ | |
if(strstr(line, "PRIVMSG ") != line){ | |
if(strlen(broadcast_string)) strcat(broadcast_string, "\n"); | |
strcat(broadcast_string, line); | |
} | |
else | |
{ | |
line += 8; | |
} | |
log_puts(line); | |
line = strtok(0, "\n"); | |
} | |
return; | |
} | |
switch(c){ | |
default: | |
parsecmd(c); | |
} | |
} | |
void parsecmd(int c) | |
{ | |
char str[2048]; | |
switch(c){ | |
case CMD_SETWAVEY: | |
their_wave_y = SZB_READ(&nc->message, int); | |
break; | |
case CMD_PRINT: | |
szb_readstring(&nc->message, str); | |
log_puts(str); | |
break; | |
case CMD_RESET: | |
foolish_counter = 0; | |
break; | |
default: | |
kdrnet_dumpmessage(nc, 0); | |
} | |
} | |
void NET_GAME_SV_READ(kdrnet_sv_t *svs, struct kdrnet_sv_client *cl) | |
{ | |
num_messages_rec++; | |
while(szb_canread(&nc->message)) parsecmd_sv(SZB_READ(&nc->message, unsigned char)); | |
} | |
void NET_GAME_SV_WRITERELIABLE(kdrnet_sv_t *svs, struct kdrnet_sv_client *cl) | |
{ | |
if(strlen(send_string)){ | |
SZB_WRITE(&cl->link.message, (unsigned char) CMD_PRINT); | |
szb_writestring(&cl->link.message, send_string); | |
send_string[0] = 0; | |
} | |
if(strlen(broadcast_string)){ | |
SZB_WRITE(&cl->link.message, (unsigned char) CMD_PRINT); | |
szb_writestring(&cl->link.message, broadcast_string); | |
} | |
if(send_reset){ | |
SZB_WRITE(&cl->link.message, (unsigned char) CMD_RESET); | |
send_reset = 0; | |
} | |
} | |
int NET_GAME_SV_WRITEDGRAM(kdrnet_sv_t *svs, struct kdrnet_sv_client *cl, struct sizedbuf *buf) | |
{ | |
num_messages_snt++; | |
SZB_WRITE(buf, (unsigned char) CMD_SETWAVEY); | |
SZB_WRITE(buf, wave_y); | |
return 1; | |
} | |
void NET_GAME_CL_READ(kdrnet_cl_t *cls) | |
{ | |
num_messages_rec++; | |
while(szb_canread(&nc->message)) parsecmd(SZB_READ(&nc->message, unsigned char)); | |
} | |
void NET_GAME_CL_WRITE(kdrnet_cl_t *cls, struct sizedbuf *buf) | |
{ | |
num_messages_snt++; | |
if(strlen(send_string)){ | |
SZB_WRITE(&cls->link.message, (unsigned char) CMD_PRINT); | |
szb_writestring(&cls->link.message, send_string); | |
send_string[0] = 0; | |
} | |
if(send_reset){ | |
SZB_WRITE(&cls->link.message, (unsigned char) CMD_RESET); | |
send_reset = 0; | |
} | |
SZB_WRITE(buf, (unsigned char) CMD_SETWAVEY); | |
SZB_WRITE(buf, wave_y); | |
} | |
static char *driverlist_getter(int index, int *list_size) | |
{ | |
NET_DRIVERNAME *drv = drivernames; | |
int numdrvs = 0; | |
while(drv->name){ | |
if(index == numdrvs) return drv->name; | |
drv++; | |
numdrvs++; | |
} | |
if(index < 0){ | |
*list_size = numdrvs; | |
} | |
return 0; | |
} | |
static int update_proc(int msg, DIALOG *d, int c); | |
static BITMAP *wave_bmp; | |
static int wave_x = 0; | |
DIALOG the_dialog[] = | |
{ | |
// (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) (dp2) (dp3) | |
{d_clear_proc, 0, 0, 0, 0, WHITE, 0, 0, 0, 0, 0, NULL, NULL, NULL },//0 | |
{d_rtext_proc, 96, 32, 0, 0, WHITE, 0, 0, 0, 0, 0, "Address:", 0, 0 },//1 | |
{d_edit_proc, 96, 32, 224, 8, WHITE, 0, 0, 0, sizeof(address)-1, 0, address, NULL, NULL },//2 | |
{d_radio_proc, 320, 32, 160, 16, WHITE, 0, 0, D_SELECTED, 0, 0, "Server", 0, 0 },//3 | |
{d_radio_proc, 480, 32, 160, 16, WHITE, 0, 0, 0, 0, 0, "Client", 0, 0 },//4 | |
{d_button_proc, 80, 64, 160, 16, WHITE, 0, 0, D_EXIT, 0, 0, "Connect/Listen", NULL, NULL },//5 | |
{d_ctext_proc, 320, 8, 0, 0, WHITE, 0, 0, 0, 0, 0, status, 0, 0 },//6 | |
{d_list_proc, 340, 64, 280, 64, WHITE, 0, 0, D_EXIT, 1, 0, driverlist_getter, 0, 0 },//7 | |
{d_textbox_proc, 16, 136, 608, 96, WHITE, 0, 0, D_SELECTED, 0, 0, logp_buffer, 0, 0 },//8 | |
{update_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },//9 | |
{d_edit_proc, 96, 48, 224, 16, WHITE, 0, 0, 0, sizeof(name)-1, 0, name, 0, 0 },//10 | |
{d_rtext_proc, 96, 48, 0, 0, WHITE, 0, 0, 0, 0, 0, "Client name:", 0, 0 },//11 | |
{d_button_proc, 16, 240, 160, 16, WHITE, 0, 0, D_EXIT, 0, 0, "Click me", 0, 0 },//12 | |
{d_text_proc, 128, 96, 0, 0, WHITE, 0, 0, 0, 0, 0, str_mrec, 0, 0 },//13 | |
{d_rtext_proc, 128, 96, 0, 0, WHITE, 0, 0, 0, 0, 0, "Msgs. received:", 0, 0 },//14 | |
{d_text_proc, 128, 104, 0, 0, WHITE, 0, 0, 0, 0, 0, str_msnt, 0, 0 },//15 | |
{d_rtext_proc, 128, 104, 0, 0, WHITE, 0, 0, 0, 0, 0, "Msgs. sent:", 0, 0 },//16 | |
{d_bitmap_proc, 16, 272, 608, 96, WHITE, 0, 0, 0, 0, 0, 0, 0, 0, },//17 | |
{d_button_proc, 320, 240, 160, 16, WHITE, 0, 0, D_EXIT, 0, 0, "Clear buffer", 0, 0 },//18 | |
{d_button_proc, 16, 376, 160, 16, WHITE, 0, 0, D_EXIT, 0, 0, "Send RESET", 0, 0 },//19 | |
{d_check_proc, 320, 376, 160, 16, WHITE, 0, 0, D_SELECTED, 1, 0, "Send time msgs.", 0, 0 },//20 | |
{d_edit_proc, 16, 400, 464, 8, WHITE, 0, 0, 0, sizeof(chat_string)-1, 0, chat_string, 0, 0 },//21 | |
{d_button_proc, 496, 400, 128, 16, WHITE, 0, 0, D_EXIT, 0, 0, "Send", 0, 0 },//22 | |
{NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL } | |
}; | |
#define sendstring_printf(str, ...) if(1){sprintf(logp_temp, str, ##__VA_ARGS__); put_in_sendstring(logp_temp);} | |
static void put_in_sendstring(char *str) | |
{ | |
char *ss = send_string; | |
if(strlen(send_string)){ | |
while(*ss) ss++; | |
*ss = '\n'; | |
ss++; | |
*ss = 0; | |
} | |
strcat(send_string, str); | |
} | |
int update_proc(int msg, DIALOG *d, int c) | |
{ | |
LARGE_INTEGER frq, cnt; | |
int need_redraw = 0; | |
if(has_logput){ | |
has_logput = 0; | |
the_dialog[8].flags |= D_DIRTY; | |
} | |
if(!(the_dialog[3].flags & D_SELECTED) != !(the_dialog[10].flags & D_DISABLED)){ | |
the_dialog[10].flags ^= D_DISABLED; | |
the_dialog[10].flags |= D_DIRTY; | |
} | |
if(!first_connected){ | |
need_redraw = 1; | |
first_connected = 1; | |
if((nc && nc->mode == KDRNET_MODE_CLIENT) && cls.state) strcpy(status, "Connected"); | |
else if((nc && nc->mode == KDRNET_MODE_SERVER) && num_messages_rec) strcpy(status, "Serving clients"); | |
else | |
{ | |
need_redraw = 0; | |
first_connected = 0; | |
} | |
} | |
if(atoi(str_mrec) != num_messages_rec){ | |
sprintf(str_mrec, "%d", num_messages_rec); | |
the_dialog[13].flags |= D_DIRTY; | |
} | |
if(atoi(str_msnt) != num_messages_snt){ | |
sprintf(str_msnt, "%d", num_messages_snt); | |
the_dialog[15].flags |= D_DIRTY; | |
} | |
QueryPerformanceCounter(&cnt); | |
QueryPerformanceFrequency(&frq); | |
realtime = ((double) cnt.QuadPart) / ((double) frq.QuadPart); | |
if(last_tick + tick_interval < realtime){ | |
if(nc) kdrnet_update(nc); | |
last_tick = realtime; | |
tick_count++; | |
wave_x++; | |
wave_y = wave_bmp->h / 2 + fixtoi(fixmul(fixsin(itofix(wave_x)), itofix(wave_bmp->h / 2 - 1))); | |
if(wave_y < 1) wave_y = 1; | |
if(wave_y >= wave_bmp->h - 1) wave_y = wave_bmp->h - 2; | |
vline(wave_bmp, wave_x % wave_bmp->w, 0, wave_bmp->h - 1, 0); | |
putpixel(wave_bmp, wave_x % wave_bmp->w, wave_y, BLUE); | |
putpixel(wave_bmp, wave_x % wave_bmp->w, their_wave_y, GREEN); | |
rect(wave_bmp, 0, 0, wave_bmp->w - 1, wave_bmp->h - 1, WHITE); | |
the_dialog[17].flags |= D_DIRTY; | |
if(tick_count % 40 == 0){ | |
if(the_dialog[20].flags & D_SELECTED) sendstring_printf("PRIVMSG %02d Peer time: %02.2f", (foolish_counter++) % 99, (float) realtime); | |
} | |
} | |
if(msg != MSG_IDLE) return need_redraw ? D_REDRAW : D_O_K; | |
return need_redraw ? D_REDRAW : D_O_K; | |
} | |
static void driverlist_parse(void) | |
{ | |
NET_DRIVERNAME *drv = drivernames; | |
int numdrvs = 0; | |
while(drv->name){ | |
if(the_dialog[7].d1 == numdrvs) if(nc) nc->driver = drv->num; | |
drv++; | |
numdrvs++; | |
} | |
} | |
int main(int argc, char **argv) | |
{ | |
allegro_init(); | |
set_color_depth(32); | |
set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0); | |
install_keyboard(); | |
install_mouse(); | |
set_display_switch_mode(SWITCH_BACKGROUND); | |
wave_bmp = create_bitmap(608, 96); | |
clear_to_color(wave_bmp, 0); | |
the_dialog[17].dp = wave_bmp; | |
logp_buffer[0] = 0; | |
realtime = 0; | |
net_init(); | |
net_loadconfig(config_filename); | |
avail = net_detectdrivers(net_drivers_all); | |
drivernames = net_getdrivernames(avail); | |
while(!key[KEY_ESC]){ | |
int ret = do_dialog(the_dialog, -1); | |
switch(ret){ | |
case 5: | |
the_dialog[10].flags |= D_DISABLED; | |
the_dialog[7].flags |= D_DISABLED; | |
the_dialog[5].flags |= D_DISABLED; | |
the_dialog[4].flags |= D_DISABLED; | |
the_dialog[3].flags |= D_DISABLED; | |
the_dialog[2].flags |= D_DISABLED; | |
driverlist_parse(); | |
if(the_dialog[3].flags & D_SELECTED){ | |
nc = (kdrnet_common *) &svs; | |
nc->driver = 3; | |
nc->timeout = 5; | |
nc->zombietime = 5; | |
kdrnet_sv_init(&svs); | |
strcpy(status, "Listening for new clients"); | |
} | |
if(the_dialog[4].flags & D_SELECTED){ | |
nc = (kdrnet_common *) &cls; | |
nc->driver = 3; | |
nc->timeout = 5; | |
nc->zombietime = 5; | |
if(!kdrnet_cl_init(&cls, address)) strcpy(cls.name, name); | |
strcpy(status, "Connecting to server"); | |
} | |
break; | |
case 12: | |
log_puts("Clicked, lol"); | |
break; | |
case 18: | |
logp_buffer[0] = 0; | |
break; | |
case 19: | |
send_reset = 1; | |
break; | |
case 22: | |
sendstring_printf("%s", chat_string); | |
chat_string[0] = 0; | |
break; | |
} | |
} | |
return 0; | |
} | |
END_OF_MAIN(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment