complete rewrite

This commit is contained in:
Nishi 2026-01-07 04:24:22 +09:00
commit 8a717a2b2e
Signed by: nishi
GPG key ID: 27EF69B208EB9343
41 changed files with 2625 additions and 1255 deletions

View file

@ -1,298 +0,0 @@
#include <af_common.h>
#define SHADOW_WIDTH 1024
#define SHADOW_HEIGHT 1024
double gl_cam_lr = 0;
double gl_cam_ud = 0;
double gl_cam_x;
double gl_cam_y;
double gl_cam_z;
int gl_scene = AF_SCENE_MAIN;
GLuint gl_shadow;
static GLuint shadow_texture;
gl_scene_t gl_scenes[] = {
{gl_main_changed, gl_main_init, gl_main_draw, gl_main_after}, /**/
{NULL, NULL, NULL, NULL} /**/
};
static char gl_status[256];
void gl_resize(int width, int height) {
glViewport(0, 0, width, height);
}
void gl_init(void) {
GLfloat lightamb[] = {0.25, 0.25, 0.25, 1.0};
GLfloat lightcol[] = {1.0, 1.0, 1.0, 1.0};
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
glEnable(GL_BLEND);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glEnable(GL_CULL_FACE);
glLightfv(GL_LIGHT0, GL_AMBIENT, lightamb);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightcol);
glLightfv(GL_LIGHT0, GL_SPECULAR, lightcol);
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
gl_font_init();
gl_status[0] = 0;
glGenTextures(1, &shadow_texture);
glBindTexture(GL_TEXTURE_2D, shadow_texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);
glBindTexture(GL_TEXTURE_2D, 0);
if(gl_shader(&gl_shadow, DATAROOTDIR "/assaultfish/shadow.vs", DATAROOTDIR "/assaultfish/shadow.fs")) {
glUseProgram(gl_shadow);
glUniform1i(glGetUniformLocation(gl_shadow, "texture"), 1);
glUniform1i(glGetUniformLocation(gl_shadow, "texture_in"), 0);
}
}
void gl_cube(double x, double y, double z, double xs, double ys, double zs, double xr, double yr, double zr) {
int i;
glPushMatrix();
glTranslatef(x, y, z);
glScalef(xs, ys, zs);
glRotatef(xr, 1, 0, 0);
glRotatef(yr, 0, 1, 0);
glRotatef(zr, 0, 0, 1);
for(i = 0; i < 6; i++) {
glBegin(GL_QUADS);
glNormal3f(0, 0, 1);
glTexCoord2f(0, 0);
glVertex3f(-0.5, 0.5, 0.5);
glTexCoord2f(0, 1);
glVertex3f(-0.5, -0.5, 0.5);
glTexCoord2f(1, 1);
glVertex3f(0.5, -0.5, 0.5);
glTexCoord2f(1, 0);
glVertex3f(0.5, 0.5, 0.5);
glEnd();
if(i == 3) {
glRotatef(90, 1, 0, 0);
} else if(i == 4) {
glRotatef(180, 1, 0, 0);
} else {
glRotatef(90, 0, 1, 0);
}
}
glPopMatrix();
}
static void gl_common(void) {
char buf1[128];
char buf2[128];
int l;
gl_util_begin_2d();
glColor4f(0, 0, 0, 0.5);
sprintf(buf1, "AssaultFish %s", AF_VERSION);
sprintf(buf2, "%s", AF_COPYRIGHT);
l = gl_font_width(buf1);
if(l < gl_font_width(buf2)) l = gl_font_width(buf2);
glBegin(GL_QUADS);
glVertex2f(MwGetInteger(opengl, MwNwidth) - l, MwGetInteger(opengl, MwNheight) - gl_font_height(buf1) - gl_font_height(buf2));
glVertex2f(MwGetInteger(opengl, MwNwidth) - l, MwGetInteger(opengl, MwNheight));
glVertex2f(MwGetInteger(opengl, MwNwidth), MwGetInteger(opengl, MwNheight));
glVertex2f(MwGetInteger(opengl, MwNwidth), MwGetInteger(opengl, MwNheight) - gl_font_height(buf1) - gl_font_height(buf2));
glEnd();
glColor3f(1, 1, 1);
gl_font_text(buf1, MwGetInteger(opengl, MwNwidth) - gl_font_width(buf1), MwGetInteger(opengl, MwNheight) - gl_font_height(buf1) - gl_font_height(buf2), 1);
gl_font_text(buf2, MwGetInteger(opengl, MwNwidth) - gl_font_width(buf2), MwGetInteger(opengl, MwNheight) - gl_font_height(buf2), 1);
gl_font_text(gl_status, 0, 0, 1);
gl_util_end_2d();
}
static void scene(void) {
if(gl_scenes[gl_scene].draw != NULL) gl_scenes[gl_scene].draw();
}
void gl_render(void) {
GLfloat lightpos[4] = {2.5, 5, -2.5, 1};
GLint viewport[4];
GLdouble modelview[16];
GLdouble modelview2[16];
if(gl_scenes[gl_scene].init != NULL) gl_scenes[gl_scene].init();
glClear(GL_DEPTH_BUFFER_BIT);
glGetIntegerv(GL_VIEWPORT, &viewport[0]);
glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluPerspective(60, (double)SHADOW_WIDTH / SHADOW_HEIGHT, 0.01, 100.0);
gluLookAt(lightpos[0], lightpos[1], lightpos[2], 0, 0, 0, 0, 1, 0);
glGetDoublev(GL_MODELVIEW_MATRIX, &modelview[0]);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDisable(GL_LIGHTING);
glCullFace(GL_FRONT);
scene();
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, shadow_texture);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE0);
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glEnable(GL_LIGHTING);
glCullFace(GL_BACK);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, (double)MwGetInteger(opengl, MwNwidth) / MwGetInteger(opengl, MwNheight), 0.01, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(gl_cam_x, gl_cam_y, gl_cam_z, gl_cam_x + cos(gl_cam_lr / 180.0 * M_PI), gl_cam_y + sin(gl_cam_ud / 180.0 * M_PI), gl_cam_z + sin(gl_cam_lr / 180.0 * M_PI), 0, 1, 0);
glGetDoublev(GL_MODELVIEW_MATRIX, &modelview2[0]);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glTranslated(0.5, 0.5, 0.5);
glScaled(0.5, 0.5, 0.5);
glMultMatrixd(modelview);
glMultMatrixd(modelview2);
glMatrixMode(GL_MODELVIEW);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, shadow_texture);
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
scene();
glActiveTexture(GL_TEXTURE1);
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE0);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
gl_common();
if(gl_scenes[gl_scene].after != NULL) gl_scenes[gl_scene].after();
}
void gl_scene_change(void) {
if(gl_scenes[gl_scene].changed != NULL) gl_scenes[gl_scene].changed();
gl_status[0] = 0;
}
void gl_set_status(const char* status) {
strcpy(gl_status, status);
}
static void cross(double* out, double v00, double v01, double v02, double v10, double v11, double v12) {
out[0] = v01 * v12 - v02 * v11;
out[1] = v02 * v10 - v00 * v12;
out[2] = v00 * v11 - v01 * v10;
}
/*
* v0-v2
* | /
* v1/
*/
void gl_calc_normal3(double* out, double v00, double v01, double v02, double v10, double v11, double v12, double v20, double v21, double v22) {
double v[3];
double l = 0;
int i;
cross(&v[0], /**/
v10 - v00, v11 - v01, v12 - v02, /**/
v20 - v00, v21 - v01, v22 - v02 /**/
);
l = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
for(i = 0; i < 3; i++) {
out[i] = v[i] / l;
}
}
/*
* v0-v3
* | |
* v1-v2
*/
void gl_calc_normal4(double* out, double v00, double v01, double v02, double v10, double v11, double v12, double v20, double v21, double v22, double v30, double v31, double v32) {
double v0[3];
double v1[3];
int i;
double l = 0;
gl_calc_normal3(&v0[0], v00, v01, v02, v10, v11, v12, v30, v31, v32);
gl_calc_normal3(&v1[0], v10, v11, v12, v20, v21, v22, v30, v31, v32);
for(i = 0; i < 3; i++) {
out[i] = v0[i] + v1[i];
}
l = sqrt(out[0] * out[0] + out[1] * out[1] + out[2] * out[2]);
for(i = 0; i < 3; i++) {
out[i] = out[i] / l;
}
}

View file

@ -1,60 +0,0 @@
#include <af_common.h>
#include <stb_image.h>
static GLuint font_atlas;
static int font_width = 0, font_height = 0;
void gl_font_init(void) {
unsigned int ch;
unsigned char* data = stbi_load(DATAROOTDIR "/assaultfish/font.png", &font_width, &font_height, &ch, 4);
glGenTextures(1, &font_atlas);
glBindTexture(GL_TEXTURE_2D, font_atlas);
if(data != NULL) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, font_width, font_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
free(data);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);
}
void gl_font_text(const char* text, int x, int y, double scale) {
int i;
int gw = font_width / 16 * scale, gh = font_height / 16 * scale;
int is = glIsEnabled(GL_TEXTURE_2D) ? 1 : 0;
gl_util_begin_2d();
if(!is) glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, font_atlas);
glBegin(GL_QUADS);
for(i = 0; text[i] != 0; i++) {
double bx = 1.0 / 16 * (text[i] % 16), by = 1.0 / 16 * (text[i] / 16);
glTexCoord2f(bx, by);
glVertex2f(i * gw + x, y);
glTexCoord2f(bx + 1.0 / 16, by);
glVertex2f(i * gw + x + gw, y);
glTexCoord2f(bx + 1.0 / 16, by + 1.0 / 16);
glVertex2f(i * gw + x + gw, y + gh);
glTexCoord2f(bx, by + 1.0 / 16);
glVertex2f(i * gw + x, y + gh);
}
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
if(!is) glDisable(GL_TEXTURE_2D);
gl_util_end_2d();
}
int gl_font_width(const char* text) {
return font_width / 16 * strlen(text);
}
int gl_font_height(const char* text) {
return font_height / 16;
}

View file

@ -1,67 +0,0 @@
#include <af_common.h>
#include <stb_image.h>
static double rad;
void gl_main_changed(void) {
rad = 0;
}
void gl_main_init(void) {
gl_cam_x = 0;
gl_cam_y = 0;
gl_cam_z = -1;
gl_cam_lr = 90;
gl_cam_ud = 0;
}
void gl_main_draw(void) {
int i;
glUniform1f(glGetUniformLocation(gl_shadow, "solid_color"), 1);
glPushMatrix();
glRotatef(rad, 1, 0, 0);
glRotatef(rad, 0, 1, 0);
glRotatef(rad, 0, 0, 1);
for(i = 0; i < 8; i++) {
int c = (i % 2) == 0 ? 1 : 0;
double n[3];
double u = 0.3;
gl_calc_normal3(&n[0], 0, u * 1.4, 0, -u, 0, u, u, 0, u);
glColor3f(c ? 0.75 : 0, 0, c ? 0 : 0.75);
glBegin(GL_TRIANGLES);
glNormal3f(n[0], n[1], n[2]);
glVertex3f(0, u * 1.4, 0);
glVertex3f(-u, 0, u);
glVertex3f(u, 0, u);
glEnd();
glRotatef(90, 0, 1, 0);
if(i == 3) {
glRotatef(180, 0, 0, 1);
glRotatef(90, 0, 1, 0);
}
}
glPopMatrix();
glColor3f(1, 1, 1);
glBegin(GL_QUADS);
glNormal3f(0, 1, 0);
glVertex3f(-5, -1, -5);
glVertex3f(-5, -1, 5);
glVertex3f(5, -1, 5);
glVertex3f(5, -1, -5);
glEnd();
glUniform1f(glGetUniformLocation(gl_shadow, "solid_color"), 0);
}
void gl_main_after(void) {
rad += 60.0 / (1000.0 / AF_WAIT_MS);
}

View file

@ -1,108 +0,0 @@
#include <af_common.h>
static void err(const char* path, GLuint shader) {
GLint len, ret;
char* e;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
e = malloc(len);
e[len] = 0;
glGetShaderInfoLog(shader, len, &ret, e);
fprintf(stderr, "%s: %s\n", path, e);
free(e);
}
int gl_shader(GLuint* r, const char* vs, const char* fs) {
GLuint vsi;
GLuint fsi;
FILE* f;
int vsl = 0;
int fsl = 0;
char* vss;
char* fss;
GLint st;
if((f = fopen(vs, "rb")) != NULL) {
fseek(f, 0, SEEK_END);
vsl = ftell(f);
fseek(f, 0, SEEK_SET);
vss = malloc(vsl + 1);
fread(vss, vsl, 1, f);
vss[vsl] = 0;
fclose(f);
} else {
return 0;
}
if((f = fopen(fs, "rb")) != NULL) {
fseek(f, 0, SEEK_END);
fsl = ftell(f);
fseek(f, 0, SEEK_SET);
fss = malloc(fsl + 1);
fread(fss, fsl, 1, f);
fss[fsl] = 0;
fclose(f);
} else {
free(vss);
return 0;
}
vsi = glCreateShader(GL_VERTEX_SHADER);
fsi = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(vsi, 1, (const GLchar**)&vss, NULL);
glShaderSource(fsi, 1, (const GLchar**)&fss, NULL);
glCompileShader(vsi);
glGetShaderiv(vsi, GL_COMPILE_STATUS, &st);
if(!st) {
err(vs, vsi);
glDeleteShader(vsi);
glDeleteShader(fsi);
free(vss);
free(fss);
return 0;
}
glCompileShader(fsi);
glGetShaderiv(fsi, GL_COMPILE_STATUS, &st);
if(!st) {
err(fs, fsi);
glDeleteShader(vsi);
glDeleteShader(fsi);
free(vss);
free(fss);
return 0;
}
free(vss);
free(fss);
*r = glCreateProgram();
glAttachShader(*r, vsi);
glAttachShader(*r, fsi);
glDeleteShader(vsi);
glDeleteShader(fsi);
glLinkProgram(*r);
glGetProgramiv(*r, GL_LINK_STATUS, &st);
if(!st) {
glDeleteProgram(*r);
return 0;
}
return 1;
}

View file

@ -1,34 +0,0 @@
#include <af_common.h>
void gl_util_begin_2d(void) {
glUseProgram(0);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glDisable(GL_CULL_FACE);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, MwGetInteger(opengl, MwNwidth), MwGetInteger(opengl, MwNheight), 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
}
void gl_util_end_2d(void) {
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glEnable(GL_CULL_FACE);
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
glUseProgram(gl_shadow);
}

View file

@ -1,103 +0,0 @@
#include <af_common.h>
MwWidget root, window, opengl;
static const MwRect sizes[] = {
{0, 0, 640, 480},
{0, 0, 800, 600},
{0, 0, 1024, 768},
{0, 0, 1280, 1024},
};
static void resize(MwWidget handle, void* user, void* client) {
int ww = MwGetInteger(window, MwNwidth);
int wh = MwGetInteger(window, MwNheight);
MwVaApply(opengl,
MwNwidth, ww,
MwNheight, wh,
NULL);
gl_resize(ww, wh);
}
static void tick(MwWidget handle, void* user, void* client) {
net_poll();
gl_render();
MwOpenGLSwapBuffer(opengl);
}
static void* gl_load(const char* name) {
return MwOpenGLGetProcAddress(opengl, name);
}
void scene_change(int scene) {
gl_scene = scene;
gl_scene_change();
ui_scene_change();
}
int main(int argc, char** argv) {
MwSizeHints sh;
MwRect rc;
int i;
MwLibraryInit();
root = MwVaCreateWidget(NULL, "root", NULL, 0, 0, 0, 0,
MwNwaitMS, AF_WAIT_MS,
MwNbitmapFont, 0,
MwNmodernLook, 1,
NULL);
window = MwVaCreateWidget(MwWindowClass, "main", root, 0, 0, 640, 480,
MwNtitle, "AssaultFish",
NULL);
MwGetScreenSize(window, &rc);
for(i = sizeof(sizes) / sizeof(sizes[0]) - 1; i >= 0; i--) {
if(sizes[i].width < rc.width && sizes[i].height < rc.height) {
sh.min_width = sh.max_width = sizes[i].width;
sh.min_height = sh.max_height = sizes[i].height;
break;
}
}
for(i = 1; i < argc; i++) {
if(strcmp(argv[i], "--width") == 0 && (i + 1) < argc) {
sh.min_width = sh.max_width = atoi(argv[i + 1]);
} else if(strcmp(argv[i], "--height") == 0 && (i + 1) < argc) {
sh.min_height = sh.max_height = atoi(argv[i + 1]);
}
}
MwVaApply(window,
MwNsizeHints, &sh,
MwNx, (rc.width - sh.max_width) / 2,
MwNy, (rc.height - sh.max_height) / 2,
MwNwidth, sh.max_width,
MwNheight, sh.max_height,
NULL);
opengl = MwCreateWidget(MwOpenGLClass, "opengl", window, 0, 0, sh.max_width, sh.max_height);
MwOpenGLMakeCurrent(opengl);
gladLoadGLLoader(gl_load);
resize(window, NULL, NULL);
gl_init();
ui_init();
scene_change(AF_SCENE_MAIN);
MwAddUserHandler(window, MwNresizeHandler, resize, NULL);
MwAddUserHandler(root, MwNtickHandler, tick, NULL);
MwLoop(root);
}

View file

@ -1,107 +0,0 @@
#include <af_common.h>
static fishsoup_client_t* client = NULL;
enum OPAQUE_STATES {
OPAQUE_WAITING_HELLO = 0,
OPAQUE_JOINING
};
typedef struct opaque {
char username[256];
int state;
} opaque_t;
static void net_return(MwWidget handle, void* user, void* client) {
scene_change(AF_SCENE_MAIN);
}
static void on_packet(fishsoup_client_t* self, fishsoup_packet_t* pkt) {
opaque_t* o = self->user;
if(pkt->header.type == AF_PACKET_HELLO && pkt->header.length == sizeof(af_packet_hello_t) && o->state == OPAQUE_WAITING_HELLO) {
af_packet_hello_t* p_hello = pkt->data;
unsigned char mj, mi, pt;
af_common_version(&mj, &mi, &pt);
af_common_log_info("HELLO packet: Server version %hhu.%hhu.%hhu\n", p_hello->major, p_hello->minor, p_hello->patch);
if(mj == p_hello->major && mi >= p_hello->minor && (mi == p_hello->minor ? (pt >= p_hello->patch) : (1))) {
fishsoup_packet_t p;
af_packet_join_t p_join;
af_common_log_info("Server version is compatible with this client\n");
p.header.type = AF_PACKET_JOIN;
p.header.length = sizeof(p_join);
p.data = &p_join;
memcpy(p_join.username, o->username, 256);
fishsoup_packet_send(self->fd, &p);
o->state = OPAQUE_JOINING;
gl_set_status("Joining");
return;
}
af_common_log_info("Server version is incompatible with this client\n");
MwAddUserHandler(ui_message("Server version is incompatible with this client"), MwNactivateHandler, net_return, NULL);
fishsoup_client_destroy(self);
client = NULL;
} else if(pkt->header.type == AF_PACKET_OK && pkt->header.length == sizeof(af_packet_ok_t) && o->state == OPAQUE_JOINING) {
af_packet_ok_t* p_ok = pkt->data;
af_common_log_info("OK Packet: Joined successfully\n");
gl_set_status("Downloading data");
} else if(pkt->header.type == AF_PACKET_ERROR && pkt->header.length == sizeof(af_packet_error_t) && o->state == OPAQUE_JOINING) {
af_packet_error_t* p_error = pkt->data;
af_common_log_info("ERROR Packet: Failed to join\n");
fishsoup_client_destroy(self);
client = NULL;
}
}
static void on_disconnect(fishsoup_client_t* self) {
free(self->user);
}
void net_connect(const char* username, const char* hostname, int port) {
opaque_t* o;
scene_change(AF_SCENE_CONNECTING);
client = fishsoup_client(hostname, port == 0 ? AF_DEFAULT_PORT : port);
if(client == NULL) {
MwAddUserHandler(ui_message("Failed to connect"), MwNactivateHandler, net_return, NULL);
return;
}
o = client->user = malloc(sizeof(opaque_t));
o->state = OPAQUE_WAITING_HELLO;
memset(o->username, 0, 256);
memcpy(o->username, username, strlen(username));
fishsoup_client_on_packet(client, on_packet);
fishsoup_client_on_disconnect(client, on_disconnect);
gl_set_status("Waiting for server to be ready");
}
void net_poll(void) {
int ret;
if(client == NULL) return;
while(client != NULL && (ret = fishsoup_client_poll(client)) > 0);
if(ret < 0) {
MwAddUserHandler(ui_message("Connection destroyed"), MwNactivateHandler, net_return, NULL);
fishsoup_client_destroy(client);
client = NULL;
return;
}
}

View file

@ -1,125 +0,0 @@
#include <af_common.h>
MwWidget ui_notice(int width, int height) {
if(width == 0 && height == 0) {
width = 400;
height = 300;
}
return MwVaCreateWidget(MwFrameClass, "notice", window, (MwGetInteger(window, MwNwidth) - width) / 2, (MwGetInteger(window, MwNheight) - height) / 2, width, height,
MwNhasBorder, 1,
MwNinverted, 0,
NULL);
}
void ui_notice_destroy(MwWidget widget) {
MwDestroyWidget(widget);
}
static void ui_login_join(MwWidget handle, void* user, void* client) {
char* username = MwStringDuplicate(MwGetText(MwGetVoid(user, "VusernameEntry"), MwNtext));
char* hostname = MwStringDuplicate(MwGetText(MwGetVoid(user, "VhostnameEntry"), MwNtext));
int port = atoi(MwGetText(MwGetVoid(user, "VportEntry"), MwNtext));
MwLLDestroyPixmap(MwGetVoid(user, MwNpixmap));
ui_notice_destroy(user);
net_connect(username, hostname, port);
free(username);
free(hostname);
}
static void ui_login(void) {
MwWidget wnd = ui_notice(0, 0);
int bw = MwDefaultBorderWidth(wnd);
MwWidget join = MwVaCreateWidget(MwButtonClass, "join", wnd, MwGetInteger(wnd, MwNwidth) - bw - 10 - 96, MwGetInteger(wnd, MwNheight) - bw - 10 - 24, 96, 24,
MwNtext, "Join",
NULL);
MwWidget box = MwVaCreateWidget(MwBoxClass, "box", wnd, bw, bw, MwGetInteger(wnd, MwNwidth) - bw * 2, MwGetInteger(wnd, MwNheight) - bw * 2 - 10 - 24,
MwNorientation, MwVERTICAL,
MwNmargin, 10,
MwNpadding, 10,
NULL);
MwWidget icon = MwVaCreateWidget(MwImageClass, "icon", box, 0, 0, 0, 0,
MwNfillArea, 0,
MwNfixedSize, 100,
NULL);
MwWidget entrybox[3];
MwWidget entryinput[3];
MwLLPixmap px = MwLoadImage(wnd, DATAROOTDIR "/assaultfish/logo.png");
const char* labels[3] = {
"Username",
"Hostname",
"Port"};
const char* entries[3] = {
"JohnDoe",
"127.0.0.1",
"",
};
int i;
char buf[16];
sprintf(buf, "%d", AF_DEFAULT_PORT);
entries[2] = buf;
for(i = 0; i < 3; i++) {
entrybox[i] = MwVaCreateWidget(MwBoxClass, "entrybox", box, 0, 0, 0, 0,
MwNfixedSize, 24,
MwNmargin, 10,
NULL);
MwVaCreateWidget(MwLabelClass, "label", entrybox[i], 0, 0, 0, 0,
MwNfixedSize, 100,
MwNtext, labels[i],
MwNalignment, MwALIGNMENT_END,
NULL);
entryinput[i] = MwVaCreateWidget(MwEntryClass, "entry", entrybox[i], 0, 0, 0, 0,
MwNtext, entries[i],
NULL);
}
MwVaApply(icon,
MwNpixmap, px,
NULL);
MwVaApply(wnd,
MwNpixmap, px,
"VusernameEntry", entryinput[0],
"VhostnameEntry", entryinput[1],
"VportEntry", entryinput[2],
NULL);
MwAddUserHandler(join, MwNactivateHandler, ui_login_join, wnd);
}
static void ui_message_ok(MwWidget handle, void* user, void* client) {
MwDispatchUserHandler(user, MwNactivateHandler, NULL);
ui_notice_destroy(user);
}
MwWidget ui_message(const char* message) {
MwWidget wnd = ui_notice(0, 0);
int bw = MwDefaultBorderWidth(wnd);
MwWidget label = MwVaCreateWidget(MwLabelClass, "label", wnd, bw, (MwGetInteger(wnd, MwNheight) - 24) / 2, MwGetInteger(wnd, MwNwidth) - bw * 2, 24,
MwNtext, message,
NULL);
MwWidget ok = MwVaCreateWidget(MwButtonClass, "ok", wnd, MwGetInteger(wnd, MwNwidth) - bw - 10 - 96, MwGetInteger(wnd, MwNheight) - bw - 10 - 24, 96, 24,
MwNtext, "OK",
NULL);
MwAddUserHandler(ok, MwNactivateHandler, ui_message_ok, wnd);
return wnd;
}
void ui_scene_change(void) {
if(gl_scene == AF_SCENE_MAIN) {
ui_login();
}
}
void ui_init(void) {
MwToggleDarkTheme(root, 1);
}