add clang-format config and format everything
This commit is contained in:
parent
187ec1a68e
commit
56458af5fc
29
.clang-format
Normal file
29
.clang-format
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
---
|
||||||
|
BasedOnStyle: LLVM
|
||||||
|
IndentWidth: 4
|
||||||
|
TabWidth: 4
|
||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
AccessModifierOffset: -4
|
||||||
|
AlignAfterOpenBracket: AlwaysBreak
|
||||||
|
AlignOperands: false
|
||||||
|
AlignTrailingComments: false
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
|
AllowShortBlocksOnASingleLine: true
|
||||||
|
AllowShortFunctionsOnASingleLine: Empty
|
||||||
|
AllowShortIfStatementsOnASingleLine: true
|
||||||
|
AllowShortLoopsOnASingleLine: true
|
||||||
|
AlwaysBreakTemplateDeclarations: true
|
||||||
|
BinPackArguments: false
|
||||||
|
BinPackParameters: false
|
||||||
|
BreakConstructorInitializersBeforeComma: true
|
||||||
|
ColumnLimit: 160
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||||
|
ConstructorInitializerIndentWidth: 0
|
||||||
|
MaxEmptyLinesToKeep: 2
|
||||||
|
NamespaceIndentation: All
|
||||||
|
PointerAlignment: Left
|
||||||
|
SpaceAfterCStyleCast: true
|
||||||
|
Standard: Cpp11
|
||||||
|
UseTab: Always
|
||||||
|
...
|
198
src/announce.c
198
src/announce.c
@ -2,12 +2,12 @@
|
|||||||
#include "announce.h"
|
#include "announce.h"
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
|
|
||||||
#include <time.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <avahi-client/client.h>
|
#include <avahi-client/client.h>
|
||||||
#include <avahi-client/lookup.h>
|
#include <avahi-client/lookup.h>
|
||||||
@ -20,10 +20,10 @@
|
|||||||
|
|
||||||
#define SERVICE_TYPE "_sdlbomber._udp"
|
#define SERVICE_TYPE "_sdlbomber._udp"
|
||||||
|
|
||||||
static AvahiClient *client = NULL;
|
static AvahiClient* client = NULL;
|
||||||
static AvahiThreadedPoll *threaded_poll = NULL;
|
static AvahiThreadedPoll* threaded_poll = NULL;
|
||||||
static AvahiEntryGroup *group = NULL;
|
static AvahiEntryGroup* group = NULL;
|
||||||
static AvahiServiceBrowser *browser = NULL;
|
static AvahiServiceBrowser* browser = NULL;
|
||||||
|
|
||||||
static char* name = NULL;
|
static char* name = NULL;
|
||||||
|
|
||||||
@ -37,32 +37,31 @@ static char buffer_glchanged[10];
|
|||||||
gamelistentry gamelistentries[10];
|
gamelistentry gamelistentries[10];
|
||||||
int gamelistsize = 0;
|
int gamelistsize = 0;
|
||||||
|
|
||||||
static void myerror(AvahiClient *c, const char *s) {
|
static void myerror(AvahiClient* c, const char* s) {
|
||||||
fprintf(stderr, "Error in: %s\n (%s)", s, avahi_strerror(avahi_client_errno(c)));
|
fprintf(stderr, "Error in: %s\n (%s)", s, avahi_strerror(avahi_client_errno(c)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void create_services(AvahiClient *c);
|
static void create_services(AvahiClient* c);
|
||||||
|
|
||||||
static void entry_group_callback(AvahiEntryGroup *g, AvahiEntryGroupState state, AVAHI_GCC_UNUSED void *userdata) {
|
static void entry_group_callback(AvahiEntryGroup* g, AvahiEntryGroupState state, AVAHI_GCC_UNUSED void* userdata) {
|
||||||
group = g;
|
group = g;
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case AVAHI_ENTRY_GROUP_ESTABLISHED :
|
case AVAHI_ENTRY_GROUP_ESTABLISHED:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AVAHI_ENTRY_GROUP_COLLISION :
|
case AVAHI_ENTRY_GROUP_COLLISION: {
|
||||||
{
|
char* n = avahi_alternative_service_name(name);
|
||||||
char *n = avahi_alternative_service_name(name);
|
avahi_free(name);
|
||||||
avahi_free(name);
|
name = n;
|
||||||
name = n;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* And recreate the services */
|
/* And recreate the services */
|
||||||
avahi_entry_group_reset(group);
|
avahi_entry_group_reset(group);
|
||||||
create_services(avahi_entry_group_get_client(g));
|
create_services(avahi_entry_group_get_client(g));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AVAHI_ENTRY_GROUP_FAILURE :
|
case AVAHI_ENTRY_GROUP_FAILURE:
|
||||||
fprintf(stderr, "Entry group failure: %s\n", avahi_strerror(avahi_client_errno(avahi_entry_group_get_client(g))));
|
fprintf(stderr, "Entry group failure: %s\n", avahi_strerror(avahi_client_errno(avahi_entry_group_get_client(g))));
|
||||||
|
|
||||||
avahi_threaded_poll_quit(threaded_poll);
|
avahi_threaded_poll_quit(threaded_poll);
|
||||||
@ -74,7 +73,7 @@ static void entry_group_callback(AvahiEntryGroup *g, AvahiEntryGroupState state,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void create_services(AvahiClient *c) {
|
static void create_services(AvahiClient* c) {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!group) {
|
if (!group) {
|
||||||
@ -90,10 +89,9 @@ again:
|
|||||||
snprintf(buf_version, sizeof(buf_version), "version=%X", (unsigned int) version);
|
snprintf(buf_version, sizeof(buf_version), "version=%X", (unsigned int) version);
|
||||||
if ((ret = avahi_entry_group_add_service(group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, name, SERVICE_TYPE, NULL, NULL, port, buf_version, NULL)) < 0) {
|
if ((ret = avahi_entry_group_add_service(group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, name, SERVICE_TYPE, NULL, NULL, port, buf_version, NULL)) < 0) {
|
||||||
|
|
||||||
if (ret == AVAHI_ERR_COLLISION)
|
if (ret == AVAHI_ERR_COLLISION) goto collision;
|
||||||
goto collision;
|
|
||||||
|
|
||||||
fprintf(stderr, "Failed to add "SERVICE_TYPE": %s\n", avahi_strerror(ret));
|
fprintf(stderr, "Failed to add " SERVICE_TYPE ": %s\n", avahi_strerror(ret));
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,12 +103,11 @@ again:
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
collision:
|
collision : {
|
||||||
{
|
char* n = avahi_alternative_service_name(name);
|
||||||
char *n = avahi_alternative_service_name(name);
|
avahi_free(name);
|
||||||
avahi_free(name);
|
name = n;
|
||||||
name = n;
|
}
|
||||||
}
|
|
||||||
avahi_entry_group_reset(group);
|
avahi_entry_group_reset(group);
|
||||||
goto again;
|
goto again;
|
||||||
|
|
||||||
@ -118,8 +115,8 @@ fail:
|
|||||||
avahi_threaded_poll_quit(threaded_poll);
|
avahi_threaded_poll_quit(threaded_poll);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void client_callback(AvahiClient *c, AvahiClientState state, void * userdata) {
|
static void client_callback(AvahiClient* c, AvahiClientState state, void* userdata) {
|
||||||
(void)userdata;
|
(void) userdata;
|
||||||
|
|
||||||
client = c;
|
client = c;
|
||||||
switch (state) {
|
switch (state) {
|
||||||
@ -132,16 +129,14 @@ static void client_callback(AvahiClient *c, AvahiClientState state, void * userd
|
|||||||
break;
|
break;
|
||||||
case AVAHI_CLIENT_S_COLLISION:
|
case AVAHI_CLIENT_S_COLLISION:
|
||||||
case AVAHI_CLIENT_S_REGISTERING:
|
case AVAHI_CLIENT_S_REGISTERING:
|
||||||
if (group) {
|
if (group) { avahi_entry_group_reset(group); }
|
||||||
avahi_entry_group_reset(group);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case AVAHI_CLIENT_CONNECTING:
|
case AVAHI_CLIENT_CONNECTING:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int registergame(const char *playername, uint16_t p, const unsigned char v[4]) {
|
int registergame(const char* playername, uint16_t p, const unsigned char v[4]) {
|
||||||
if (name) avahi_free(name);
|
if (name) avahi_free(name);
|
||||||
name = avahi_strdup(playername);
|
name = avahi_strdup(playername);
|
||||||
|
|
||||||
@ -165,7 +160,7 @@ void unregistergame(void) {
|
|||||||
avahi_threaded_poll_unlock(threaded_poll);
|
avahi_threaded_poll_unlock(threaded_poll);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void remove_game_with_name(const char *name) {
|
static void remove_game_with_name(const char* name) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < buffer_glsize; i++) {
|
for (i = 0; i < buffer_glsize; i++) {
|
||||||
@ -180,15 +175,26 @@ static void remove_game_with_name(const char *name) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void resolve_callback(AvahiServiceResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event,
|
static void resolve_callback(
|
||||||
const char *name, const char *type, const char *domain, const char *host_name, const AvahiAddress *address,
|
AvahiServiceResolver* r,
|
||||||
uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags flags, void* userdata) {
|
AvahiIfIndex interface,
|
||||||
|
AvahiProtocol protocol,
|
||||||
|
AvahiResolverEvent event,
|
||||||
|
const char* name,
|
||||||
|
const char* type,
|
||||||
|
const char* domain,
|
||||||
|
const char* host_name,
|
||||||
|
const AvahiAddress* address,
|
||||||
|
uint16_t port,
|
||||||
|
AvahiStringList* txt,
|
||||||
|
AvahiLookupResultFlags flags,
|
||||||
|
void* userdata) {
|
||||||
int i;
|
int i;
|
||||||
uint32_t want_version;
|
uint32_t want_version;
|
||||||
(void)interface;
|
(void) interface;
|
||||||
(void)host_name;
|
(void) host_name;
|
||||||
(void)flags;
|
(void) flags;
|
||||||
(void)userdata;
|
(void) userdata;
|
||||||
assert(r);
|
assert(r);
|
||||||
|
|
||||||
if (protocol != AVAHI_PROTO_INET) goto done; /* ignore non IPv4 for now */
|
if (protocol != AVAHI_PROTO_INET) goto done; /* ignore non IPv4 for now */
|
||||||
@ -200,75 +206,89 @@ static void resolve_callback(AvahiServiceResolver *r, AvahiIfIndex interface, Av
|
|||||||
/* Called whenever a service has been resolved successfully or timed out */
|
/* Called whenever a service has been resolved successfully or timed out */
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case AVAHI_RESOLVER_FAILURE:
|
case AVAHI_RESOLVER_FAILURE:
|
||||||
fprintf(stderr, "(Resolver) Failed to resolve service '%s' of type '%s' in domain '%s': %s\n", name, type, domain, avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(r))));
|
fprintf(
|
||||||
break;
|
stderr,
|
||||||
|
"(Resolver) Failed to resolve service '%s' of type '%s' in domain '%s': %s\n",
|
||||||
|
name,
|
||||||
|
type,
|
||||||
|
domain,
|
||||||
|
avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(r))));
|
||||||
|
break;
|
||||||
|
|
||||||
case AVAHI_RESOLVER_FOUND: {
|
case AVAHI_RESOLVER_FOUND: {
|
||||||
gamelistentry *ge;
|
gamelistentry* ge;
|
||||||
unsigned int version;
|
unsigned int version;
|
||||||
int have_version = 0;
|
int have_version = 0;
|
||||||
AvahiStringList *psl;
|
AvahiStringList* psl;
|
||||||
for (psl = txt ; psl ; psl = psl->next) {
|
for (psl = txt; psl; psl = psl->next) {
|
||||||
if (0 == strncmp("version=", (const char*) psl->text, 8)) {
|
if (0 == strncmp("version=", (const char*) psl->text, 8)) {
|
||||||
sscanf((const char*) psl->text, "version=%X", &version);
|
sscanf((const char*) psl->text, "version=%X", &version);
|
||||||
if (version != want_version) goto done; /* version mismatch */
|
if (version != want_version) goto done; /* version mismatch */
|
||||||
have_version = 1;
|
have_version = 1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!have_version) goto done;
|
|
||||||
remove_game_with_name(name);
|
|
||||||
i = buffer_glsize++;
|
|
||||||
ge = &buffer_glentries[i];
|
|
||||||
buffer_glchanged[i] = 1;
|
|
||||||
memset(ge, 0, sizeof(*ge));
|
|
||||||
ge->netname.sin_addr.s_addr = address->data.ipv4.address;
|
|
||||||
ge->netname.sin_family = AF_INET;
|
|
||||||
ge->netname.sin_port = port;
|
|
||||||
strncpy(ge->name, name, 15);
|
|
||||||
}
|
}
|
||||||
|
if (!have_version) goto done;
|
||||||
|
remove_game_with_name(name);
|
||||||
|
i = buffer_glsize++;
|
||||||
|
ge = &buffer_glentries[i];
|
||||||
|
buffer_glchanged[i] = 1;
|
||||||
|
memset(ge, 0, sizeof(*ge));
|
||||||
|
ge->netname.sin_addr.s_addr = address->data.ipv4.address;
|
||||||
|
ge->netname.sin_family = AF_INET;
|
||||||
|
ge->netname.sin_port = port;
|
||||||
|
strncpy(ge->name, name, 15);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
avahi_service_resolver_free(r);
|
avahi_service_resolver_free(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void browse_callback(AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event,
|
static void browse_callback(
|
||||||
const char *name, const char *type, const char *domain, AvahiLookupResultFlags flags, void* userdata) {
|
AvahiServiceBrowser* b,
|
||||||
(void)flags;
|
AvahiIfIndex interface,
|
||||||
|
AvahiProtocol protocol,
|
||||||
|
AvahiBrowserEvent event,
|
||||||
|
const char* name,
|
||||||
|
const char* type,
|
||||||
|
const char* domain,
|
||||||
|
AvahiLookupResultFlags flags,
|
||||||
|
void* userdata) {
|
||||||
|
(void) flags;
|
||||||
|
|
||||||
assert(b);
|
assert(b);
|
||||||
|
|
||||||
/* Called whenever a new services becomes available on the LAN or is removed from the LAN */
|
/* Called whenever a new services becomes available on the LAN or is removed from the LAN */
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case AVAHI_BROWSER_FAILURE:
|
case AVAHI_BROWSER_FAILURE:
|
||||||
|
|
||||||
fprintf(stderr, "(Browser) %s\n", avahi_strerror(avahi_client_errno(client)));
|
fprintf(stderr, "(Browser) %s\n", avahi_strerror(avahi_client_errno(client)));
|
||||||
avahi_threaded_poll_quit(threaded_poll);
|
avahi_threaded_poll_quit(threaded_poll);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case AVAHI_BROWSER_NEW:
|
case AVAHI_BROWSER_NEW:
|
||||||
/* fprintf(stderr, "(Browser) NEW: service '%s' of type '%s' in domain '%s'\n", name, type, domain); */
|
/* fprintf(stderr, "(Browser) NEW: service '%s' of type '%s' in domain '%s'\n", name, type, domain); */
|
||||||
|
|
||||||
/* We ignore the returned resolver object. In the callback
|
/* We ignore the returned resolver object. In the callback
|
||||||
function we free it. If the server is terminated before
|
function we free it. If the server is terminated before
|
||||||
the callback function is called the server will free
|
the callback function is called the server will free
|
||||||
the resolver for us. */
|
the resolver for us. */
|
||||||
|
|
||||||
if (!(avahi_service_resolver_new(client, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolve_callback, userdata)))
|
if (!(avahi_service_resolver_new(client, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolve_callback, userdata)))
|
||||||
fprintf(stderr, "Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_client_errno(client)));
|
fprintf(stderr, "Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_client_errno(client)));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AVAHI_BROWSER_REMOVE:
|
case AVAHI_BROWSER_REMOVE:
|
||||||
remove_game_with_name(name);
|
remove_game_with_name(name);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AVAHI_BROWSER_ALL_FOR_NOW:
|
case AVAHI_BROWSER_ALL_FOR_NOW:
|
||||||
break;
|
break;
|
||||||
case AVAHI_BROWSER_CACHE_EXHAUSTED:
|
case AVAHI_BROWSER_CACHE_EXHAUSTED:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ struct gamelistentry {
|
|||||||
char name[16];
|
char name[16];
|
||||||
};
|
};
|
||||||
|
|
||||||
int registergame(const char *playername, uint16_t port, const unsigned char version[4]);
|
int registergame(const char* playername, uint16_t port, const unsigned char version[4]);
|
||||||
void unregistergame(void);
|
void unregistergame(void);
|
||||||
|
|
||||||
int searchgames(void);
|
int searchgames(void);
|
||||||
|
34
src/bomber.c
34
src/bomber.c
@ -1,31 +1,31 @@
|
|||||||
|
#include <fcntl.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/types.h>
|
|
||||||
#include <netdb.h>
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <signal.h>
|
#include <sys/types.h>
|
||||||
#include <fcntl.h>
|
#include <unistd.h>
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
#include "bomber.h"
|
|
||||||
#include "gfx.h"
|
|
||||||
#include "announce.h"
|
#include "announce.h"
|
||||||
#include "sound.h"
|
#include "bomber.h"
|
||||||
#include "menu.h"
|
|
||||||
#include "utils.h"
|
|
||||||
#include "network.h"
|
|
||||||
#include "game.h"
|
|
||||||
#include "draw.h"
|
#include "draw.h"
|
||||||
|
#include "game.h"
|
||||||
|
#include "gfx.h"
|
||||||
|
#include "menu.h"
|
||||||
|
#include "network.h"
|
||||||
|
#include "sound.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
char *p;
|
char* p;
|
||||||
|
|
||||||
strcpy(playername,"ANONYMOUS");
|
strcpy(playername, "ANONYMOUS");
|
||||||
p=getenv("USER");
|
p = getenv("USER");
|
||||||
if(p) strncpy(playername,p,sizeof(playername)-1);
|
if (p) strncpy(playername, p, sizeof(playername) - 1);
|
||||||
|
|
||||||
create_seed_unique();
|
create_seed_unique();
|
||||||
|
|
||||||
|
75
src/bomber.h
75
src/bomber.h
@ -1,7 +1,8 @@
|
|||||||
#ifndef BOMBER_H
|
#ifndef BOMBER_H
|
||||||
#define BOMBER_H
|
#define BOMBER_H
|
||||||
|
|
||||||
#include "SDL.h"
|
#include "list.h"
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
typedef unsigned char uchar;
|
typedef unsigned char uchar;
|
||||||
extern int xcolors[256];
|
extern int xcolors[256];
|
||||||
@ -38,30 +39,25 @@ extern int xcolors[256];
|
|||||||
typedef struct gfxset {
|
typedef struct gfxset {
|
||||||
uchar gs_colormap[768];
|
uchar gs_colormap[768];
|
||||||
uchar gs_inout[256];
|
uchar gs_inout[256];
|
||||||
uchar *gs_pic;
|
uchar* gs_pic;
|
||||||
int gs_xsize;
|
int gs_xsize;
|
||||||
int gs_ysize;
|
int gs_ysize;
|
||||||
} gfxset;
|
} gfxset;
|
||||||
|
|
||||||
typedef struct figure {
|
typedef struct figure {
|
||||||
int xsize,ysize;
|
int xsize, ysize;
|
||||||
int xdelta,ydelta;
|
int xdelta, ydelta;
|
||||||
uchar *graphics;
|
uchar* graphics;
|
||||||
} figure;
|
} figure;
|
||||||
|
|
||||||
typedef struct solid {
|
typedef struct solid {
|
||||||
int xsize,ysize;
|
int xsize, ysize;
|
||||||
uchar *graphics;
|
uchar* graphics;
|
||||||
} solid;
|
} solid;
|
||||||
|
|
||||||
typedef struct listhead listhead;
|
|
||||||
struct listhead {
|
|
||||||
listhead *prev, *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct player {
|
typedef struct player {
|
||||||
listhead list, list_all_players;
|
listhead list, list_all_players;
|
||||||
int xpos,ypos;
|
int xpos, ypos;
|
||||||
int flags;
|
int flags;
|
||||||
int abilities;
|
int abilities;
|
||||||
int speed;
|
int speed;
|
||||||
@ -69,15 +65,15 @@ typedef struct player {
|
|||||||
int bombsused;
|
int bombsused;
|
||||||
int bombsavailable;
|
int bombsavailable;
|
||||||
int flamelength;
|
int flamelength;
|
||||||
int *at;
|
int* at;
|
||||||
int figcount;
|
int figcount;
|
||||||
int doing;
|
int doing;
|
||||||
int action;
|
int action;
|
||||||
int color;
|
int color;
|
||||||
int controller;
|
int controller;
|
||||||
int fixx,fixy;
|
int fixx, fixy;
|
||||||
int kills, deaths;
|
int kills, deaths;
|
||||||
figure *figure;
|
figure* figure;
|
||||||
} player;
|
} player;
|
||||||
|
|
||||||
#define FLG_CONTROL 1
|
#define FLG_CONTROL 1
|
||||||
@ -85,25 +81,25 @@ typedef struct player {
|
|||||||
|
|
||||||
|
|
||||||
typedef struct sprite {
|
typedef struct sprite {
|
||||||
int flags;
|
int flags;
|
||||||
int xpos,ypos;
|
int xpos, ypos;
|
||||||
figure *fig;
|
figure* fig;
|
||||||
} sprite;
|
} sprite;
|
||||||
|
|
||||||
typedef struct damage {
|
typedef struct damage {
|
||||||
int xpos,ypos;
|
int xpos, ypos;
|
||||||
int xsize,ysize;
|
int xsize, ysize;
|
||||||
} damage;
|
} damage;
|
||||||
|
|
||||||
typedef struct bomb {
|
typedef struct bomb {
|
||||||
listhead list;
|
listhead list;
|
||||||
int type;
|
int type;
|
||||||
int xpos,ypos;
|
int xpos, ypos;
|
||||||
int px,py;
|
int px, py;
|
||||||
int power;
|
int power;
|
||||||
int timer;
|
int timer;
|
||||||
int figcount;
|
int figcount;
|
||||||
player *owner;
|
player* owner;
|
||||||
} bomb;
|
} bomb;
|
||||||
|
|
||||||
|
|
||||||
@ -117,11 +113,11 @@ typedef struct bomb {
|
|||||||
|
|
||||||
typedef struct flame {
|
typedef struct flame {
|
||||||
listhead list;
|
listhead list;
|
||||||
int xpos,ypos;
|
int xpos, ypos;
|
||||||
int px,py;
|
int px, py;
|
||||||
int timer;
|
int timer;
|
||||||
int lurd;
|
int lurd;
|
||||||
player *owner;
|
player* owner;
|
||||||
} flame;
|
} flame;
|
||||||
|
|
||||||
#define FL_UP 2
|
#define FL_UP 2
|
||||||
@ -131,27 +127,27 @@ typedef struct flame {
|
|||||||
|
|
||||||
typedef struct brickdecay {
|
typedef struct brickdecay {
|
||||||
listhead list;
|
listhead list;
|
||||||
int xpos,ypos;
|
int xpos, ypos;
|
||||||
int px,py;
|
int px, py;
|
||||||
int timer;
|
int timer;
|
||||||
} brickdecay;
|
} brickdecay;
|
||||||
|
|
||||||
typedef struct bonustile {
|
typedef struct bonustile {
|
||||||
listhead list;
|
listhead list;
|
||||||
int xpos,ypos;
|
int xpos, ypos;
|
||||||
int px,py;
|
int px, py;
|
||||||
int type;
|
int type;
|
||||||
} bonustile;
|
} bonustile;
|
||||||
|
|
||||||
typedef struct generic {
|
typedef struct generic {
|
||||||
listhead list;
|
listhead list;
|
||||||
int xpos,ypos;
|
int xpos, ypos;
|
||||||
int px,py;
|
int px, py;
|
||||||
int timer;
|
int timer;
|
||||||
void (*process)();
|
void (*process)();
|
||||||
void (*draw)();
|
void (*draw)();
|
||||||
void *ptr1,*ptr2;
|
void *ptr1, *ptr2;
|
||||||
int data1,data2;
|
int data1, data2;
|
||||||
} generic;
|
} generic;
|
||||||
|
|
||||||
enum tile_types {
|
enum tile_types {
|
||||||
@ -175,10 +171,10 @@ enum tile_types {
|
|||||||
|
|
||||||
|
|
||||||
// #define ACT_INVALID 0x88
|
// #define ACT_INVALID 0x88
|
||||||
#define ACT_NONE 0
|
#define ACT_NONE 0
|
||||||
#define ACT_UP 1
|
#define ACT_UP 1
|
||||||
#define ACT_DOWN 2
|
#define ACT_DOWN 2
|
||||||
#define ACT_LEFT 3
|
#define ACT_LEFT 3
|
||||||
#define ACT_RIGHT 4
|
#define ACT_RIGHT 4
|
||||||
#define ACT_ENTER 5
|
#define ACT_ENTER 5
|
||||||
#define ACT_QUIT 6
|
#define ACT_QUIT 6
|
||||||
@ -200,7 +196,6 @@ enum tile_types {
|
|||||||
#define CODE_ALLDEAD 2
|
#define CODE_ALLDEAD 2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define MAXTHINGS 500
|
#define MAXTHINGS 500
|
||||||
#define MAXSETS 8
|
#define MAXSETS 8
|
||||||
#define MAXSPRITES 256
|
#define MAXSPRITES 256
|
||||||
|
446
src/draw.c
446
src/draw.c
@ -1,15 +1,15 @@
|
|||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/types.h>
|
|
||||||
#include <netdb.h>
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <signal.h>
|
#include <sys/types.h>
|
||||||
#include <fcntl.h>
|
#include <unistd.h>
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
#include "bomber.h"
|
#include "bomber.h"
|
||||||
#include "draw.h"
|
#include "draw.h"
|
||||||
@ -48,191 +48,206 @@ figure flamefigs[MAXSETS][NUMFLAMEFRAMES];
|
|||||||
figure tiles[15];
|
figure tiles[15];
|
||||||
figure death[NUMDEATHFRAMES];
|
figure death[NUMDEATHFRAMES];
|
||||||
|
|
||||||
int fontxsize,fontysize;
|
int fontxsize, fontysize;
|
||||||
int bigfontxsize,bigfontysize,bigfontyspace;
|
int bigfontxsize, bigfontysize, bigfontyspace;
|
||||||
|
|
||||||
static int textx,texty;
|
static int textx, texty;
|
||||||
|
|
||||||
static const unsigned char *remapstring = (const unsigned char*) "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ.:!?\177/\\*-,>< =";
|
static const unsigned char* remapstring = (const unsigned char*) "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ.:!?\177/\\*-,>< =";
|
||||||
static char asciiremap[256];
|
static char asciiremap[256];
|
||||||
|
|
||||||
/* On screen array variables */
|
/* On screen array variables */
|
||||||
int arraynumx=15;
|
int arraynumx = 15;
|
||||||
int arraynumy=11;
|
int arraynumy = 11;
|
||||||
int arraystartx=20;
|
int arraystartx = 20;
|
||||||
int arraystarty=70;
|
int arraystarty = 70;
|
||||||
int arrayspacex=40;
|
int arrayspacex = 40;
|
||||||
int arrayspacey=36;
|
int arrayspacey = 36;
|
||||||
|
|
||||||
static sprite sprites[MAXSPRITES];
|
static sprite sprites[MAXSPRITES];
|
||||||
static int spritesused=0;
|
static int spritesused = 0;
|
||||||
|
|
||||||
#define IBUFFLEN 1024
|
#define IBUFFLEN 1024
|
||||||
int ileft=0,ihand=0,byteswide;
|
int ileft = 0, ihand = 0, byteswide;
|
||||||
unsigned char ibuff[IBUFFLEN],*itake;
|
unsigned char ibuff[IBUFFLEN], *itake;
|
||||||
|
|
||||||
static void freegfxset(gfxset *gs) {
|
static void freegfxset(gfxset* gs) {
|
||||||
if(gs->gs_pic) free(gs->gs_pic);
|
if (gs->gs_pic) free(gs->gs_pic);
|
||||||
gs->gs_pic=0;
|
gs->gs_pic = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int myci() {
|
static int myci() {
|
||||||
if (!ileft) {
|
if (!ileft) {
|
||||||
ileft=read(ihand,ibuff,IBUFFLEN);
|
ileft = read(ihand, ibuff, IBUFFLEN);
|
||||||
|
|
||||||
if(!ileft) return -1;
|
if (!ileft) return -1;
|
||||||
itake=ibuff;
|
itake = ibuff;
|
||||||
}
|
}
|
||||||
ileft--;
|
ileft--;
|
||||||
return *itake++;
|
return *itake++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dopcxreal(char *name,gfxset *gs) {
|
static int dopcxreal(char* name, gfxset* gs) {
|
||||||
int xs,ys;
|
int xs, ys;
|
||||||
int i,j,k;
|
int i, j, k;
|
||||||
int totalsize;
|
int totalsize;
|
||||||
int width,height;
|
int width, height;
|
||||||
unsigned char *bm,*lp;
|
unsigned char *bm, *lp;
|
||||||
char tname[256];
|
char tname[256];
|
||||||
|
|
||||||
memset(gs,0,sizeof(gfxset));
|
memset(gs, 0, sizeof(gfxset));
|
||||||
ileft=0;
|
ileft = 0;
|
||||||
snprintf(tname,sizeof(tname),DATADIR "/%s",name);
|
snprintf(tname, sizeof(tname), DATADIR "/%s", name);
|
||||||
ihand=open(tname,O_RDONLY);
|
ihand = open(tname, O_RDONLY);
|
||||||
if(ihand<0) {
|
if (ihand < 0) {
|
||||||
char tname2[260];
|
char tname2[260];
|
||||||
snprintf(tname2,sizeof(tname2),"%s.pcx",tname);
|
snprintf(tname2, sizeof(tname2), "%s.pcx", tname);
|
||||||
ihand=open(tname2,O_RDONLY);
|
ihand = open(tname2, O_RDONLY);
|
||||||
if(ihand<0)
|
if (ihand < 0) return 1;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
if(myci()!=10) {close(ihand);return 2;} // 10=zsoft .pcx
|
if (myci() != 10) {
|
||||||
if(myci()!=5) {close(ihand);return 3;} // version 3.0
|
close(ihand);
|
||||||
if(myci()!=1) {close(ihand);return 4;} //encoding method
|
return 2;
|
||||||
if(myci()!=8) {close(ihand);return 5;} //bpp
|
} // 10=zsoft .pcx
|
||||||
xs=myci();
|
if (myci() != 5) {
|
||||||
xs|=myci()<<8;
|
close(ihand);
|
||||||
ys=myci();
|
return 3;
|
||||||
ys|=myci()<<8;
|
} // version 3.0
|
||||||
width=myci();
|
if (myci() != 1) {
|
||||||
width|=myci()<<8;
|
close(ihand);
|
||||||
height=myci();
|
return 4;
|
||||||
height|=myci()<<8;
|
} // encoding method
|
||||||
width=width+1-xs;
|
if (myci() != 8) {
|
||||||
height=height+1-ys;
|
close(ihand);
|
||||||
for(i=0;i<48+4;++i) myci();
|
return 5;
|
||||||
|
} // bpp
|
||||||
|
xs = myci();
|
||||||
|
xs |= myci() << 8;
|
||||||
|
ys = myci();
|
||||||
|
ys |= myci() << 8;
|
||||||
|
width = myci();
|
||||||
|
width |= myci() << 8;
|
||||||
|
height = myci();
|
||||||
|
height |= myci() << 8;
|
||||||
|
width = width + 1 - xs;
|
||||||
|
height = height + 1 - ys;
|
||||||
|
for (i = 0; i < 48 + 4; ++i) myci();
|
||||||
myci();
|
myci();
|
||||||
if(myci()!=1) {close(ihand);return 6;} // # of planes
|
if (myci() != 1) {
|
||||||
byteswide=myci();
|
close(ihand);
|
||||||
byteswide|=myci()<<8;
|
return 6;
|
||||||
i=myci();
|
} // # of planes
|
||||||
i|=myci()<<8;
|
byteswide = myci();
|
||||||
// if(i!=1) {close(ihand);return 7;} // 1=color/bw,2=grey
|
byteswide |= myci() << 8;
|
||||||
for(i=0;i<58;++i) myci();
|
i = myci();
|
||||||
totalsize=height*byteswide;
|
i |= myci() << 8;
|
||||||
bm=malloc(totalsize+1);
|
// if(i!=1) {close(ihand);return 7;} // 1=color/bw,2=grey
|
||||||
if(!bm) {close(ihand);return 8;} // no memory
|
for (i = 0; i < 58; ++i) myci();
|
||||||
gs->gs_pic=bm;
|
totalsize = height * byteswide;
|
||||||
gs->gs_xsize=width;
|
bm = malloc(totalsize + 1);
|
||||||
gs->gs_ysize=height;
|
if (!bm) {
|
||||||
while(height--) {
|
close(ihand);
|
||||||
lp=bm;
|
return 8;
|
||||||
i=byteswide;
|
} // no memory
|
||||||
while(i>0) {
|
gs->gs_pic = bm;
|
||||||
j=myci();
|
gs->gs_xsize = width;
|
||||||
if(j<0xc0) {
|
gs->gs_ysize = height;
|
||||||
*lp++=j;
|
while (height--) {
|
||||||
|
lp = bm;
|
||||||
|
i = byteswide;
|
||||||
|
while (i > 0) {
|
||||||
|
j = myci();
|
||||||
|
if (j < 0xc0) {
|
||||||
|
*lp++ = j;
|
||||||
--i;
|
--i;
|
||||||
} else {
|
} else {
|
||||||
j&=0x3f;
|
j &= 0x3f;
|
||||||
k=myci();
|
k = myci();
|
||||||
while(j-- && i) {
|
while (j-- && i) {
|
||||||
*lp++=k;
|
*lp++ = k;
|
||||||
--i;
|
--i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bm+=width;
|
bm += width;
|
||||||
}
|
}
|
||||||
lseek(ihand,-0x300,SEEK_END);
|
lseek(ihand, -0x300, SEEK_END);
|
||||||
read(ihand,gs->gs_colormap,0x300);
|
read(ihand, gs->gs_colormap, 0x300);
|
||||||
close(ihand);
|
close(ihand);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dopcx(char *name,gfxset *gs) {
|
static int dopcx(char* name, gfxset* gs) {
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err=dopcxreal(name,gs);
|
err = dopcxreal(name, gs);
|
||||||
if(err)
|
if (err) printf("Error loading \"%s\":code %d\n", name, err);
|
||||||
printf("Error loading \"%s\":code %d\n",name,err);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void getgroup(char *name,gfxset *colorgs,figure *fig,int count) {
|
static void getgroup(char* name, gfxset* colorgs, figure* fig, int count) {
|
||||||
int err;
|
int err;
|
||||||
int i;
|
int i;
|
||||||
gfxset gs;
|
gfxset gs;
|
||||||
|
|
||||||
err=dopcx(name,&gs);
|
err = dopcx(name, &gs);
|
||||||
if(err) exit(1000+err);
|
if (err) exit(1000 + err);
|
||||||
createinout(&gs);
|
createinout(&gs);
|
||||||
for(i=0;i<MAXSETS;++i,fig+=count,++colorgs) {
|
for (i = 0; i < MAXSETS; ++i, fig += count, ++colorgs) {
|
||||||
if(!colorgs->gs_pic) continue;
|
if (!colorgs->gs_pic) continue;
|
||||||
memmove(gs.gs_colormap,colorgs->gs_colormap,
|
memmove(gs.gs_colormap, colorgs->gs_colormap, sizeof(gs.gs_colormap));
|
||||||
sizeof(gs.gs_colormap));
|
|
||||||
createinout(&gs);
|
createinout(&gs);
|
||||||
gfxfetch(&gs,fig,count);
|
gfxfetch(&gs, fig, count);
|
||||||
}
|
}
|
||||||
freegfxset(&gs);
|
freegfxset(&gs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void getsingle(char *name,figure *fig,int count) {
|
static void getsingle(char* name, figure* fig, int count) {
|
||||||
gfxset gs;
|
gfxset gs;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err=dopcx(name,&gs);
|
err = dopcx(name, &gs);
|
||||||
if(err) exit(1000+err);
|
if (err) exit(1000 + err);
|
||||||
createinout(&gs);
|
createinout(&gs);
|
||||||
gfxfetch(&gs,fig,count);
|
gfxfetch(&gs, fig, count);
|
||||||
freegfxset(&gs);
|
freegfxset(&gs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void texthome(void) {
|
static void texthome(void) {
|
||||||
textx=texty=10;
|
textx = texty = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawstring(int xpos, int ypos, const char *str) {
|
void drawstring(int xpos, int ypos, const char* str) {
|
||||||
char ch;
|
char ch;
|
||||||
|
|
||||||
while((ch=*str++)) {
|
while ((ch = *str++)) {
|
||||||
drawfigure(xpos,ypos,font+asciiremap[toupper(ch)]);
|
drawfigure(xpos, ypos, font + asciiremap[toupper(ch)]);
|
||||||
xpos+=fontxsize;
|
xpos += fontxsize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawbigstring(int xpos, int ypos, const char *str) {
|
void drawbigstring(int xpos, int ypos, const char* str) {
|
||||||
char ch;
|
char ch;
|
||||||
|
|
||||||
while('\0' != (ch=*str++)) {
|
while ('\0' != (ch = *str++)) {
|
||||||
drawfigure(xpos,ypos,bigfont+asciiremap[toupper(ch)]);
|
drawfigure(xpos, ypos, bigfont + asciiremap[toupper(ch)]);
|
||||||
xpos+=bigfontxsize;
|
xpos += bigfontxsize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void centerbig(int y, const char *str) {
|
void centerbig(int y, const char* str) {
|
||||||
int w;
|
int w;
|
||||||
|
|
||||||
w=strlen(str)*bigfontxsize;
|
w = strlen(str) * bigfontxsize;
|
||||||
drawbigstring((IXSIZE-w)>>1,y,str);
|
drawbigstring((IXSIZE - w) >> 1, y, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
// static void scrprintf(char *str,...) {
|
// static void scrprintf(char *str,...) {
|
||||||
// char output[256],*p,*p2;
|
// char output[256],*p,*p2;
|
||||||
// va_list ap;
|
// va_list ap;
|
||||||
//
|
//
|
||||||
// va_start(ap, str);
|
// va_start(ap, str);
|
||||||
//
|
//
|
||||||
// vsprintf(output,str,ap);
|
// vsprintf(output,str,ap);
|
||||||
// p=output;
|
// p=output;
|
||||||
// for(;;) {
|
// for(;;) {
|
||||||
@ -253,201 +268,196 @@ void centerbig(int y, const char *str) {
|
|||||||
// copyup();
|
// copyup();
|
||||||
// }
|
// }
|
||||||
|
|
||||||
static void bigscrprintf(char *str,...) {
|
static void bigscrprintf(char* str, ...) {
|
||||||
char output[256],*p,*p2;
|
char output[256], *p, *p2;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, str);
|
va_start(ap, str);
|
||||||
vsnprintf(output,sizeof(output),str,ap);
|
vsnprintf(output, sizeof(output), str, ap);
|
||||||
p=output;
|
p = output;
|
||||||
for(;;) {
|
for (;;) {
|
||||||
p2=p;
|
p2 = p;
|
||||||
while(*p2 && *p2!='\n') ++p2;
|
while (*p2 && *p2 != '\n') ++p2;
|
||||||
if(*p2) {
|
if (*p2) {
|
||||||
*p2=0;
|
*p2 = 0;
|
||||||
drawbigstring(textx,texty,p);
|
drawbigstring(textx, texty, p);
|
||||||
texty+=bigfontysize;
|
texty += bigfontysize;
|
||||||
textx=10;
|
textx = 10;
|
||||||
p=p2+1;
|
p = p2 + 1;
|
||||||
} else {
|
} else {
|
||||||
drawbigstring(textx,texty,p);
|
drawbigstring(textx, texty, p);
|
||||||
textx+=bigfontxsize*(p2-p);
|
textx += bigfontxsize * (p2 - p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
copyup();
|
copyup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void addsprite(int x,int y,figure *fig) {
|
void addsprite(int x, int y, figure* fig) {
|
||||||
sprite *sp;
|
sprite* sp;
|
||||||
|
|
||||||
if(spritesused==MAXSPRITES) return;
|
if (spritesused == MAXSPRITES) return;
|
||||||
sp=sprites+spritesused++;
|
sp = sprites + spritesused++;
|
||||||
sp->flags=0;
|
sp->flags = 0;
|
||||||
sp->xpos=x;
|
sp->xpos = x;
|
||||||
sp->ypos=y;
|
sp->ypos = y;
|
||||||
sp->fig=fig;
|
sp->fig = fig;
|
||||||
}
|
}
|
||||||
|
|
||||||
void plotsprites(void) {
|
void plotsprites(void) {
|
||||||
int i;
|
int i;
|
||||||
sprite *sp;
|
sprite* sp;
|
||||||
|
|
||||||
sp=sprites;
|
sp = sprites;
|
||||||
for(i=0;i<spritesused;++i) {
|
for (i = 0; i < spritesused; ++i) {
|
||||||
drawfigure(sp->xpos,sp->ypos,sp->fig);
|
drawfigure(sp->xpos, sp->ypos, sp->fig);
|
||||||
++sp;
|
++sp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void erasesprites(void) {
|
void erasesprites(void) {
|
||||||
int i;
|
int i;
|
||||||
sprite *sp;
|
sprite* sp;
|
||||||
figure *fig;
|
figure* fig;
|
||||||
|
|
||||||
sp=sprites;
|
sp = sprites;
|
||||||
for(i=0;i<spritesused;++i) {
|
for (i = 0; i < spritesused; ++i) {
|
||||||
fig=sp->fig;
|
fig = sp->fig;
|
||||||
|
|
||||||
solidcopy(&background,
|
solidcopy(&background, sp->xpos + fig->xdelta, sp->ypos + fig->ydelta, fig->xsize, fig->ysize);
|
||||||
sp->xpos+fig->xdelta,sp->ypos+fig->ydelta,
|
|
||||||
fig->xsize,fig->ysize);
|
|
||||||
++sp;
|
++sp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearsprites(void) {
|
void clearsprites(void) {
|
||||||
int i;
|
int i;
|
||||||
sprite *sp;
|
sprite* sp;
|
||||||
figure *fig;
|
figure* fig;
|
||||||
|
|
||||||
sp=sprites;
|
sp = sprites;
|
||||||
for(i=0;i<spritesused;++i) {
|
for (i = 0; i < spritesused; ++i) {
|
||||||
fig=sp->fig;
|
fig = sp->fig;
|
||||||
|
|
||||||
clearrect(sp->xpos+fig->xdelta,sp->ypos+fig->ydelta,
|
clearrect(sp->xpos + fig->xdelta, sp->ypos + fig->ydelta, fig->xsize, fig->ysize);
|
||||||
fig->xsize,fig->ysize);
|
|
||||||
++sp;
|
++sp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearspritelist(void) {
|
void clearspritelist(void) {
|
||||||
spritesused=0;
|
spritesused = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tovideox(int x) {
|
int tovideox(int x) {
|
||||||
return (x>>FRACTION)+arraystartx;
|
return (x >> FRACTION) + arraystartx;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tovideoy(int y) {
|
int tovideoy(int y) {
|
||||||
return (y>>FRACTION)+arraystarty;
|
return (y >> FRACTION) + arraystarty;
|
||||||
}
|
}
|
||||||
|
|
||||||
int screentoarrayx(int x) {
|
int screentoarrayx(int x) {
|
||||||
x+=arrayspacex << (FRACTION+2);
|
x += arrayspacex << (FRACTION + 2);
|
||||||
return ((x>>FRACTION)+(arrayspacex>>1))/arrayspacex-4;
|
return ((x >> FRACTION) + (arrayspacex >> 1)) / arrayspacex - 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
int screentoarrayy(int y) {
|
int screentoarrayy(int y) {
|
||||||
y+=arrayspacey << (FRACTION+2);
|
y += arrayspacey << (FRACTION + 2);
|
||||||
return ((y>>FRACTION)+(arrayspacey>>1))/arrayspacey-4;
|
return ((y >> FRACTION) + (arrayspacey >> 1)) / arrayspacey - 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
int arraytoscreenx(int x) {
|
int arraytoscreenx(int x) {
|
||||||
return arrayspacex*x<<FRACTION;
|
return arrayspacex * x << FRACTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
int arraytoscreeny(int y) {
|
int arraytoscreeny(int y) {
|
||||||
return arrayspacey*y<<FRACTION;
|
return arrayspacey * y << FRACTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void loadfonts(void) {
|
static void loadfonts(void) {
|
||||||
int i,j;
|
int i, j;
|
||||||
const unsigned char *p;
|
const unsigned char* p;
|
||||||
|
|
||||||
getsingle(fontname,font,NUMCHARACTERS);
|
getsingle(fontname, font, NUMCHARACTERS);
|
||||||
getsingle(bigfontname,bigfont,NUMCHARACTERS);
|
getsingle(bigfontname, bigfont, NUMCHARACTERS);
|
||||||
fontxsize=8;
|
fontxsize = 8;
|
||||||
fontysize=12;
|
fontysize = 12;
|
||||||
bigfontxsize=16;
|
bigfontxsize = 16;
|
||||||
bigfontysize=24;
|
bigfontysize = 24;
|
||||||
bigfontyspace=32;
|
bigfontyspace = 32;
|
||||||
p=remapstring;
|
p = remapstring;
|
||||||
j=0;while(*p && *p!=' ') ++p,++j;
|
j = 0;
|
||||||
memset(asciiremap,j,sizeof(asciiremap));
|
while (*p && *p != ' ') ++p, ++j;
|
||||||
p=remapstring;
|
memset(asciiremap, j, sizeof(asciiremap));
|
||||||
i=0;
|
p = remapstring;
|
||||||
while(*p && i<NUMCHARACTERS)
|
i = 0;
|
||||||
asciiremap[(int)*p++]=i++;
|
while (*p && i < NUMCHARACTERS) asciiremap[(int) *p++] = i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadgfx() {
|
void loadgfx() {
|
||||||
gfxset *gs;
|
gfxset* gs;
|
||||||
gfxset *colorgs;
|
gfxset* colorgs;
|
||||||
int err;
|
int err;
|
||||||
int i;
|
int i;
|
||||||
char name[267];
|
char name[267];
|
||||||
|
|
||||||
strcpy(walkingname,"walk");
|
strcpy(walkingname, "walk");
|
||||||
strcpy(colorsetname,"pal");
|
strcpy(colorsetname, "pal");
|
||||||
strcpy(backgroundname,"field0");
|
strcpy(backgroundname, "field0");
|
||||||
strcpy(blocksname,"blocks3");
|
strcpy(blocksname, "blocks3");
|
||||||
strcpy(blocksxname,"blocks3x");
|
strcpy(blocksxname, "blocks3x");
|
||||||
strcpy(bombs1name,"bomb1");
|
strcpy(bombs1name, "bomb1");
|
||||||
strcpy(bombs2name,"bomb2");
|
strcpy(bombs2name, "bomb2");
|
||||||
strcpy(flamesname,"flames");
|
strcpy(flamesname, "flames");
|
||||||
strcpy(tilesname,"tiles");
|
strcpy(tilesname, "tiles");
|
||||||
strcpy(deathname,"death1");
|
strcpy(deathname, "death1");
|
||||||
strcpy(fontname,"font");
|
strcpy(fontname, "font");
|
||||||
strcpy(bigfontname,"bigfont");
|
strcpy(bigfontname, "bigfont");
|
||||||
|
|
||||||
gs=malloc((MAXSETS+1)*sizeof(gfxset));
|
gs = malloc((MAXSETS + 1) * sizeof(gfxset));
|
||||||
if(!gs)
|
if (!gs) nomem("loadgfx");
|
||||||
nomem("loadgfx");
|
colorgs = gs + 1;
|
||||||
colorgs=gs+1;
|
|
||||||
|
|
||||||
for(i=0;i<MAXSETS;++i) {
|
for (i = 0; i < MAXSETS; ++i) {
|
||||||
snprintf(name,sizeof(name),"%s%d",colorsetname,i);
|
snprintf(name, sizeof(name), "%s%d", colorsetname, i);
|
||||||
err=dopcx(name,colorgs+i);
|
err = dopcx(name, colorgs + i);
|
||||||
if(err) continue;
|
if (err) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
loadfonts();
|
loadfonts();
|
||||||
texthome();
|
texthome();
|
||||||
bigscrprintf("Loading graphics...\n");
|
bigscrprintf("Loading graphics...\n");
|
||||||
|
|
||||||
err=dopcx(backgroundname,gs);
|
err = dopcx(backgroundname, gs);
|
||||||
if(err) exit(1000+err);
|
if (err) exit(1000 + err);
|
||||||
createinout(gs);
|
createinout(gs);
|
||||||
solidfetch(gs,&background);
|
solidfetch(gs, &background);
|
||||||
solidfetch(gs,&backgroundoriginal);
|
solidfetch(gs, &backgroundoriginal);
|
||||||
freegfxset(gs);
|
freegfxset(gs);
|
||||||
|
|
||||||
bigscrprintf("Loading blocks\n");
|
bigscrprintf("Loading blocks\n");
|
||||||
getsingle(blocksname,blocks,3);
|
getsingle(blocksname, blocks, 3);
|
||||||
bigscrprintf("Loading block explosions\n");
|
bigscrprintf("Loading block explosions\n");
|
||||||
getsingle(blocksxname,blocksx,9);
|
getsingle(blocksxname, blocksx, 9);
|
||||||
bigscrprintf("Loading walking figures\n");
|
bigscrprintf("Loading walking figures\n");
|
||||||
getgroup(walkingname,colorgs,walking[0],NUMWALKFRAMES);
|
getgroup(walkingname, colorgs, walking[0], NUMWALKFRAMES);
|
||||||
bigscrprintf("Loading normal bombs\n");
|
bigscrprintf("Loading normal bombs\n");
|
||||||
getgroup(bombs1name,colorgs,bombs1[0],NUMBOMBFRAMES);
|
getgroup(bombs1name, colorgs, bombs1[0], NUMBOMBFRAMES);
|
||||||
bigscrprintf("Loading controlled bombs\n");
|
bigscrprintf("Loading controlled bombs\n");
|
||||||
getgroup(bombs2name,colorgs,bombs2[0],NUMBOMBFRAMES);
|
getgroup(bombs2name, colorgs, bombs2[0], NUMBOMBFRAMES);
|
||||||
bigscrprintf("Loading flames\n");
|
bigscrprintf("Loading flames\n");
|
||||||
// getgroup(flamesname,colorgs,flamefigs[0],NUMFLAMEFRAMES);
|
// getgroup(flamesname,colorgs,flamefigs[0],NUMFLAMEFRAMES);
|
||||||
getsingle(flamesname,flamefigs[0],NUMFLAMEFRAMES);
|
getsingle(flamesname, flamefigs[0], NUMFLAMEFRAMES);
|
||||||
bigscrprintf("Loading bonus tiles\n");
|
bigscrprintf("Loading bonus tiles\n");
|
||||||
getsingle(tilesname,tiles,15);
|
getsingle(tilesname, tiles, 15);
|
||||||
bigscrprintf("Loading death sequence\n");
|
bigscrprintf("Loading death sequence\n");
|
||||||
getsingle(deathname,death,NUMDEATHFRAMES);
|
getsingle(deathname, death, NUMDEATHFRAMES);
|
||||||
|
|
||||||
for(i=0;i<MAXSETS;++i)
|
for (i = 0; i < MAXSETS; ++i) freegfxset(colorgs + i);
|
||||||
freegfxset(colorgs+i);
|
|
||||||
free(gs);
|
free(gs);
|
||||||
bigscrprintf("Done loading graphics\n");
|
bigscrprintf("Done loading graphics\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void failure(char *str,...) {
|
void failure(char* str, ...) {
|
||||||
char output[256];
|
char output[256];
|
||||||
va_list ap;
|
va_list ap;
|
||||||
int len;
|
int len;
|
||||||
@ -458,11 +468,11 @@ void failure(char *str,...) {
|
|||||||
len = vsnprintf(output, sizeof(output), str, ap);
|
len = vsnprintf(output, sizeof(output), str, ap);
|
||||||
if (len >= 256) len = 255; /* truncated string */
|
if (len >= 256) len = 255; /* truncated string */
|
||||||
clear();
|
clear();
|
||||||
drawbigstring((IXSIZE - len*bigfontxsize) / 2, (IYSIZE-bigfontysize) / 2, output);
|
drawbigstring((IXSIZE - len * bigfontxsize) / 2, (IYSIZE - bigfontysize) / 2, output);
|
||||||
copyup();
|
copyup();
|
||||||
|
|
||||||
now = longtime();
|
now = longtime();
|
||||||
while (!exitflag && longtime()-now < 3) {
|
while (!exitflag && longtime() - now < 3) {
|
||||||
scaninput();
|
scaninput();
|
||||||
if (anydown()) {
|
if (anydown()) {
|
||||||
takedown();
|
takedown();
|
||||||
|
17
src/draw.h
17
src/draw.h
@ -3,12 +3,12 @@
|
|||||||
|
|
||||||
void loadgfx(void);
|
void loadgfx(void);
|
||||||
|
|
||||||
void drawstring(int xpos, int ypos, const char *str);
|
void drawstring(int xpos, int ypos, const char* str);
|
||||||
void drawbigstring(int xpos, int ypos, const char *str);
|
void drawbigstring(int xpos, int ypos, const char* str);
|
||||||
|
|
||||||
void centerbig(int y, const char *str);
|
void centerbig(int y, const char* str);
|
||||||
|
|
||||||
void addsprite(int x,int y,figure *fig);
|
void addsprite(int x, int y, figure* fig);
|
||||||
void plotsprites(void);
|
void plotsprites(void);
|
||||||
void erasesprites(void);
|
void erasesprites(void);
|
||||||
void clearsprites(void);
|
void clearsprites(void);
|
||||||
@ -22,10 +22,10 @@ int screentoarrayy(int y);
|
|||||||
int arraytoscreenx(int x);
|
int arraytoscreenx(int x);
|
||||||
int arraytoscreeny(int y);
|
int arraytoscreeny(int y);
|
||||||
|
|
||||||
void failure(char *str,...);
|
void failure(char* str, ...);
|
||||||
|
|
||||||
extern int fontxsize,fontysize;
|
extern int fontxsize, fontysize;
|
||||||
extern int bigfontxsize,bigfontysize,bigfontyspace;
|
extern int bigfontxsize, bigfontysize, bigfontyspace;
|
||||||
|
|
||||||
/* On screen array variables */
|
/* On screen array variables */
|
||||||
extern int arraynumx, arraynumy, arraystartx, arraystarty, arrayspacex, arrayspacey;
|
extern int arraynumx, arraynumy, arraystartx, arraystarty, arrayspacex, arrayspacey;
|
||||||
@ -37,6 +37,7 @@ extern int arraynumx, arraynumy, arraystartx, arraystarty, arrayspacex, arrayspa
|
|||||||
#define NUMDEATHFRAMES 41
|
#define NUMDEATHFRAMES 41
|
||||||
|
|
||||||
|
|
||||||
extern figure blocks[3], blocksx[9], bombs1[MAXSETS][NUMBOMBFRAMES], bombs2[MAXSETS][NUMBOMBFRAMES], flamefigs[MAXSETS][NUMFLAMEFRAMES], tiles[15], death[NUMDEATHFRAMES];
|
extern figure blocks[3], blocksx[9], bombs1[MAXSETS][NUMBOMBFRAMES], bombs2[MAXSETS][NUMBOMBFRAMES], flamefigs[MAXSETS][NUMFLAMEFRAMES], tiles[15],
|
||||||
|
death[NUMDEATHFRAMES];
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
813
src/game.c
813
src/game.c
File diff suppressed because it is too large
Load Diff
14
src/game.h
14
src/game.h
@ -1,11 +1,13 @@
|
|||||||
#ifndef GAME_H
|
#ifndef GAME_H
|
||||||
#define GAME_H
|
#define GAME_H
|
||||||
|
|
||||||
|
#include "bomber.h"
|
||||||
|
|
||||||
#define FRACTION 9
|
#define FRACTION 9
|
||||||
#define SPEEDDELTA (1<<(FRACTION-1))
|
#define SPEEDDELTA (1 << (FRACTION - 1))
|
||||||
#define SPEEDMAX (10<<FRACTION)
|
#define SPEEDMAX (10 << FRACTION)
|
||||||
#define SPEEDSTART (6<<FRACTION)
|
#define SPEEDSTART (6 << FRACTION)
|
||||||
#define SPEEDTURTLE (3<<FRACTION)
|
#define SPEEDTURTLE (3 << FRACTION)
|
||||||
#define SPEEDTURTLE_TIMEOUT 250
|
#define SPEEDTURTLE_TIMEOUT 250
|
||||||
|
|
||||||
#define TEMPNODES 2
|
#define TEMPNODES 2
|
||||||
@ -18,10 +20,10 @@ struct GameOptions {
|
|||||||
void run_single_player(void);
|
void run_single_player(void);
|
||||||
void run_network_game(void);
|
void run_network_game(void);
|
||||||
|
|
||||||
void set_game_options(GameOptions *options);
|
void set_game_options(GameOptions* options);
|
||||||
|
|
||||||
extern char playername[16];
|
extern char playername[16];
|
||||||
|
|
||||||
extern solid background,backgroundoriginal;
|
extern solid background, backgroundoriginal;
|
||||||
|
|
||||||
#endif
|
#endif
|
56
src/gfx.h
56
src/gfx.h
@ -8,15 +8,15 @@
|
|||||||
extern int usedcolors;
|
extern int usedcolors;
|
||||||
extern uchar mymap[];
|
extern uchar mymap[];
|
||||||
extern int screen;
|
extern int screen;
|
||||||
extern int fontbase,fontysize;
|
extern int fontbase, fontysize;
|
||||||
extern char *imageloc;
|
extern char* imageloc;
|
||||||
|
|
||||||
extern long map2[];
|
extern long map2[];
|
||||||
extern uchar fmap[128];
|
extern uchar fmap[128];
|
||||||
extern int buttonstate,buttondown;
|
extern int buttonstate, buttondown;
|
||||||
extern int mxpos,mypos;
|
extern int mxpos, mypos;
|
||||||
|
|
||||||
extern int pressedcodes[KEYMAX],downcodes[KEYMAX],numpressed,numdown;
|
extern int pressedcodes[KEYMAX], downcodes[KEYMAX], numpressed, numdown;
|
||||||
|
|
||||||
|
|
||||||
void opengfx(void);
|
void opengfx(void);
|
||||||
@ -25,21 +25,21 @@ void gfxunlock(void);
|
|||||||
void pollinput(void);
|
void pollinput(void);
|
||||||
int takedown(void);
|
int takedown(void);
|
||||||
void closegfx(void);
|
void closegfx(void);
|
||||||
void greyrect(int x,int y,int xsize,int ysize);
|
void greyrect(int x, int y, int xsize, int ysize);
|
||||||
void clearrect(int x,int y,int xsize,int ysize);
|
void clearrect(int x, int y, int xsize, int ysize);
|
||||||
void solidfetch(gfxset *gs,solid *dest);
|
void solidfetch(gfxset* gs, solid* dest);
|
||||||
extern void dumpgfx(void);
|
extern void dumpgfx(void);
|
||||||
extern void createinout(struct gfxset *);
|
extern void createinout(struct gfxset*);
|
||||||
extern void getcolors(void);
|
extern void getcolors(void);
|
||||||
extern void gfxfetch(struct gfxset *,struct figure *,int);
|
extern void gfxfetch(struct gfxset*, struct figure*, int);
|
||||||
extern void puttile(int destx,int desty,int source);
|
extern void puttile(int destx, int desty, int source);
|
||||||
extern void store(int x,int y,int which);
|
extern void store(int x, int y, int which);
|
||||||
extern void restore(int x,int y,int which);
|
extern void restore(int x, int y, int which);
|
||||||
extern void copyup(void);
|
extern void copyup(void);
|
||||||
extern void copyupxy(int x,int y);
|
extern void copyupxy(int x, int y);
|
||||||
extern void copyupxysize(int x,int y,int xsize,int ysize);
|
extern void copyupxysize(int x, int y, int xsize, int ysize);
|
||||||
extern void getfigures(void);
|
extern void getfigures(void);
|
||||||
extern unsigned long getcolor(char *name); /* unsigned long */
|
extern unsigned long getcolor(char* name); /* unsigned long */
|
||||||
extern int checkpressed(int code);
|
extern int checkpressed(int code);
|
||||||
extern int checkdown(int code);
|
extern int checkdown(int code);
|
||||||
extern int checkbutton(int button);
|
extern int checkbutton(int button);
|
||||||
@ -48,22 +48,22 @@ extern int anydown(void);
|
|||||||
extern int firstdown(void);
|
extern int firstdown(void);
|
||||||
extern void scaninput(void);
|
extern void scaninput(void);
|
||||||
extern void fontinit(void);
|
extern void fontinit(void);
|
||||||
extern void writechar(int x,int y,uchar ch);
|
extern void writechar(int x, int y, uchar ch);
|
||||||
extern void clear(void);
|
extern void clear(void);
|
||||||
extern void drawbox(int x,int y,int size,int color);
|
extern void drawbox(int x, int y, int size, int color);
|
||||||
extern void drawbox2(int x,int y,int sizex,int sizey,int color);
|
extern void drawbox2(int x, int y, int sizex, int sizey, int color);
|
||||||
extern void drawfillrect(int x,int y,int size,int color);
|
extern void drawfillrect(int x, int y, int size, int color);
|
||||||
extern void bigpixel(int x,int y,int color);
|
extern void bigpixel(int x, int y, int color);
|
||||||
extern void invert(int x,int y);
|
extern void invert(int x, int y);
|
||||||
extern int getmousex(void);
|
extern int getmousex(void);
|
||||||
extern int getmousey(void);
|
extern int getmousey(void);
|
||||||
extern void drawsquare(int x,int y,uchar *source);
|
extern void drawsquare(int x, int y, uchar* source);
|
||||||
extern void colormapon(void);
|
extern void colormapon(void);
|
||||||
extern void colormapoff(void);
|
extern void colormapoff(void);
|
||||||
extern void palette(uchar *pal);
|
extern void palette(uchar* pal);
|
||||||
extern void drawfigure(int x,int y,figure *fig);
|
extern void drawfigure(int x, int y, figure* fig);
|
||||||
extern void drawfigureany(int x,int y,figure *fig,solid *dest);
|
extern void drawfigureany(int x, int y, figure* fig, solid* dest);
|
||||||
void solidcopy(solid *src,int destx,int desty,int sizex,int sizey);
|
void solidcopy(solid* src, int destx, int desty, int sizex, int sizey);
|
||||||
void solidcopyany(solid *src,solid *dest,int destx,int desty,int sizex,int sizey);
|
void solidcopyany(solid* src, solid* dest, int destx, int desty, int sizex, int sizey);
|
||||||
|
|
||||||
#endif // GFXX_H
|
#endif // GFXX_H
|
||||||
|
32
src/list.c
32
src/list.c
@ -1,11 +1,11 @@
|
|||||||
|
|
||||||
#include "bomber.h"
|
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
#include "bomber.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
typedef union genericlistitem genericlistitem;
|
typedef union genericlistitem genericlistitem;
|
||||||
union genericlistitem {
|
union genericlistitem {
|
||||||
genericlistitem *next;
|
genericlistitem* next;
|
||||||
listhead list;
|
listhead list;
|
||||||
bomb b;
|
bomb b;
|
||||||
flame f;
|
flame f;
|
||||||
@ -16,8 +16,8 @@ union genericlistitem {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* doesn't use prev link */
|
/* doesn't use prev link */
|
||||||
static genericlistitem *things=0;
|
static genericlistitem* things = 0;
|
||||||
static genericlistitem *free_things;
|
static genericlistitem* free_things;
|
||||||
|
|
||||||
static int count_used = 0;
|
static int count_used = 0;
|
||||||
|
|
||||||
@ -27,20 +27,18 @@ void alloc_things(void) {
|
|||||||
if (!things) {
|
if (!things) {
|
||||||
things = calloc(sizeof(genericlistitem), MAXTHINGS);
|
things = calloc(sizeof(genericlistitem), MAXTHINGS);
|
||||||
} else {
|
} else {
|
||||||
memset(things, 0, sizeof(genericlistitem)*MAXTHINGS);
|
memset(things, 0, sizeof(genericlistitem) * MAXTHINGS);
|
||||||
}
|
}
|
||||||
if (!things) nomem("Trying to allocate thing memory");
|
if (!things) nomem("Trying to allocate thing memory");
|
||||||
|
|
||||||
for (i=0; i < MAXTHINGS - 1; ++i) {
|
for (i = 0; i < MAXTHINGS - 1; ++i) { things[i].next = &things[i + 1]; }
|
||||||
things[i].next = &things[i + 1];
|
|
||||||
}
|
|
||||||
things[i].next = 0;
|
things[i].next = 0;
|
||||||
free_things = things;
|
free_things = things;
|
||||||
count_used = 0;
|
count_used = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *_allocentry(size_t size) {
|
void* _allocentry(size_t size) {
|
||||||
genericlistitem *entry = free_things;
|
genericlistitem* entry = free_things;
|
||||||
|
|
||||||
if (size > sizeof(genericlistitem)) return 0;
|
if (size > sizeof(genericlistitem)) return 0;
|
||||||
|
|
||||||
@ -52,33 +50,33 @@ void *_allocentry(size_t size) {
|
|||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
void freeentry(void *ptr) {
|
void freeentry(void* ptr) {
|
||||||
genericlistitem *entry = ptr;
|
genericlistitem* entry = ptr;
|
||||||
entry->next = free_things;
|
entry->next = free_things;
|
||||||
free_things = entry;
|
free_things = entry;
|
||||||
count_used--;
|
count_used--;
|
||||||
}
|
}
|
||||||
|
|
||||||
void list_add_tail(listhead *head, listhead *entry) {
|
void list_add_tail(listhead* head, listhead* entry) {
|
||||||
entry->next = head;
|
entry->next = head;
|
||||||
entry->prev = head->prev;
|
entry->prev = head->prev;
|
||||||
head->prev->next = entry;
|
head->prev->next = entry;
|
||||||
head->prev = entry;
|
head->prev = entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
void list_del(listhead *entry) {
|
void list_del(listhead* entry) {
|
||||||
entry->next->prev = entry->prev;
|
entry->next->prev = entry->prev;
|
||||||
entry->prev->next = entry->next;
|
entry->prev->next = entry->next;
|
||||||
entry->next = entry->prev = entry;
|
entry->next = entry->prev = entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
void list_init_head(listhead *head) {
|
void list_init_head(listhead* head) {
|
||||||
head->next = head;
|
head->next = head;
|
||||||
head->prev = head;
|
head->prev = head;
|
||||||
}
|
}
|
||||||
|
|
||||||
void things_list_clear(listhead *head) {
|
void things_list_clear(listhead* head) {
|
||||||
genericlistitem *entry;
|
genericlistitem* entry;
|
||||||
|
|
||||||
while (head->next != head) {
|
while (head->next != head) {
|
||||||
entry = container_of(head->next, __typeof__(*entry), list);
|
entry = container_of(head->next, __typeof__(*entry), list);
|
||||||
|
39
src/list.h
39
src/list.h
@ -1,10 +1,16 @@
|
|||||||
#ifndef LIST_H
|
#ifndef LIST_H
|
||||||
#define LIST_H
|
#define LIST_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
/* from linux kernel (with some changes for "iso" c) */
|
/* from linux kernel (with some changes for "iso" c) */
|
||||||
|
|
||||||
#define container_of(ptr, type, member) \
|
typedef struct listhead listhead;
|
||||||
((type *)( (char *)(__typeof__( ((type *)0)->member ) *)(ptr) - offsetof(type,member)))
|
struct listhead {
|
||||||
|
listhead *prev, *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define container_of(ptr, type, member) ((type*) ((char*) (__typeof__(((type*) 0)->member)*) (ptr) -offsetof(type, member)))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* list_entry - get the struct for this entry
|
* list_entry - get the struct for this entry
|
||||||
@ -15,20 +21,20 @@
|
|||||||
#define list_entry(ptr, type, member) container_of(ptr, type, member)
|
#define list_entry(ptr, type, member) container_of(ptr, type, member)
|
||||||
|
|
||||||
void alloc_things(void);
|
void alloc_things(void);
|
||||||
void *_allocentry(size_t size);
|
void* _allocentry(size_t size);
|
||||||
#define allocentry(type) (type*) _allocentry(sizeof(type))
|
#define allocentry(type) (type*) _allocentry(sizeof(type))
|
||||||
void freeentry(void *ptr);
|
void freeentry(void* ptr);
|
||||||
|
|
||||||
void list_add_tail(listhead *header, listhead *entry);
|
void list_add_tail(listhead* header, listhead* entry);
|
||||||
#define addtail(head, entry) list_add_tail(head, &(entry->list));
|
#define addtail(head, entry) list_add_tail(head, &(entry->list));
|
||||||
|
|
||||||
/* remove entry from list */
|
/* remove entry from list */
|
||||||
void list_del(listhead *entry);
|
void list_del(listhead* entry);
|
||||||
#define removeitem(entry) list_del(&(entry->list));
|
#define removeitem(entry) list_del(&(entry->list));
|
||||||
|
|
||||||
void list_init_head(listhead *head);
|
void list_init_head(listhead* head);
|
||||||
|
|
||||||
void things_list_clear(listhead *head); /* listhead member must be the first member */
|
void things_list_clear(listhead* head); /* listhead member must be the first member */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* list_for_each_entry - iterate over list of given type
|
* list_for_each_entry - iterate over list of given type
|
||||||
@ -36,11 +42,10 @@ void things_list_clear(listhead *head); /* listhead member must be the first mem
|
|||||||
* @head: the head for your list.
|
* @head: the head for your list.
|
||||||
* @member: the name of the list_struct within the struct.
|
* @member: the name of the list_struct within the struct.
|
||||||
*/
|
*/
|
||||||
#define list_for_each_entry(pos, head, member) \
|
#define list_for_each_entry(pos, head, member) \
|
||||||
for (pos = list_entry((head)->next, __typeof__(*pos), member); \
|
for (pos = list_entry((head)->next, __typeof__(*pos), member); /* prefetch(pos->member.next), */ \
|
||||||
/* prefetch(pos->member.next), */ \
|
&pos->member != (head); \
|
||||||
&pos->member != (head); \
|
pos = list_entry(pos->member.next, __typeof__(*pos), member))
|
||||||
pos = list_entry(pos->member.next, __typeof__(*pos), member))
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
|
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
|
||||||
@ -49,11 +54,9 @@ void things_list_clear(listhead *head); /* listhead member must be the first mem
|
|||||||
* @head:<->the head for your list.
|
* @head:<->the head for your list.
|
||||||
* @member:>the name of the list_struct within the struct.
|
* @member:>the name of the list_struct within the struct.
|
||||||
*/
|
*/
|
||||||
#define list_for_each_entry_safe(pos, n, head, member) \
|
#define list_for_each_entry_safe(pos, n, head, member) \
|
||||||
for (pos = list_entry((head)->next, __typeof__(*pos), member), \
|
for (pos = list_entry((head)->next, __typeof__(*pos), member), n = list_entry(pos->member.next, __typeof__(*pos), member); &pos->member != (head); \
|
||||||
n = list_entry(pos->member.next, __typeof__(*pos), member); \
|
pos = n, n = list_entry(n->member.next, __typeof__(*n), member))
|
||||||
&pos->member != (head); \
|
|
||||||
pos = n, n = list_entry(n->member.next, __typeof__(*n), member))
|
|
||||||
|
|
||||||
#define list_empty(head) ((head) == (head)->next)
|
#define list_empty(head) ((head) == (head)->next)
|
||||||
|
|
||||||
|
453
src/matcher.c
453
src/matcher.c
@ -1,17 +1,17 @@
|
|||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/uio.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <netdb.h>
|
|
||||||
#include <sys/timeb.h>
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <sys/timeb.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <signal.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define MAXMSG 256
|
#define MAXMSG 256
|
||||||
@ -20,7 +20,7 @@
|
|||||||
#define TIMETOLIVE 600 // seconds
|
#define TIMETOLIVE 600 // seconds
|
||||||
|
|
||||||
typedef unsigned char uchar;
|
typedef unsigned char uchar;
|
||||||
char logging=0;
|
char logging = 0;
|
||||||
|
|
||||||
unsigned char mesg[MAXMSG];
|
unsigned char mesg[MAXMSG];
|
||||||
int lastsize;
|
int lastsize;
|
||||||
@ -35,8 +35,7 @@ char masterhostname[256];
|
|||||||
#define MAXMATCHES 16
|
#define MAXMATCHES 16
|
||||||
|
|
||||||
|
|
||||||
struct registration
|
struct registration {
|
||||||
{
|
|
||||||
uchar id;
|
uchar id;
|
||||||
uchar unique[4];
|
uchar unique[4];
|
||||||
uchar password[4];
|
uchar password[4];
|
||||||
@ -44,16 +43,14 @@ struct registration
|
|||||||
uchar name[16];
|
uchar name[16];
|
||||||
uchar status;
|
uchar status;
|
||||||
};
|
};
|
||||||
struct query
|
struct query {
|
||||||
{
|
|
||||||
uchar id;
|
uchar id;
|
||||||
uchar password[4];
|
uchar password[4];
|
||||||
uchar version[4];
|
uchar version[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gamehost
|
struct gamehost {
|
||||||
{
|
struct gamehost *next, *prev;
|
||||||
struct gamehost *next,*prev;
|
|
||||||
uchar machine[4];
|
uchar machine[4];
|
||||||
uchar port[2];
|
uchar port[2];
|
||||||
struct registration reg;
|
struct registration reg;
|
||||||
@ -61,107 +58,93 @@ struct gamehost
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct gamehost *freehosts=0,*activehosts=0;
|
struct gamehost *freehosts = 0, *activehosts = 0;
|
||||||
|
|
||||||
|
|
||||||
|
int udpsocket, myport;
|
||||||
int udpsocket,myport;
|
struct sockaddr_in myname = {0}, mastername = {0};
|
||||||
struct sockaddr_in myname={0},mastername={0};
|
|
||||||
socklen_t senderlength;
|
socklen_t senderlength;
|
||||||
struct sockaddr_in sender={0};
|
struct sockaddr_in sender = {0};
|
||||||
|
|
||||||
long longtime(void)
|
long longtime(void) {
|
||||||
{
|
struct timeb tb;
|
||||||
struct timeb tb;
|
|
||||||
ftime(&tb);
|
ftime(&tb);
|
||||||
return tb.time;
|
return tb.time;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *timestr()
|
char* timestr() {
|
||||||
{
|
static char timestring[80];
|
||||||
static char timestring[80];
|
|
||||||
|
|
||||||
time_t t;
|
time_t t;
|
||||||
int l;
|
int l;
|
||||||
time(&t);
|
time(&t);
|
||||||
strcpy(timestring,ctime(&t));
|
strcpy(timestring, ctime(&t));
|
||||||
l=strlen(timestring);
|
l = strlen(timestring);
|
||||||
if(l && timestring[l-1]=='\n') timestring[l-1]=0;
|
if (l && timestring[l - 1] == '\n') timestring[l - 1] = 0;
|
||||||
return timestring;
|
return timestring;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int putmsg(struct sockaddr_in *toname,unsigned char *msg,int len)
|
int putmsg(struct sockaddr_in* toname, unsigned char* msg, int len) {
|
||||||
{
|
int status;
|
||||||
int status;
|
|
||||||
|
|
||||||
status=sendto(udpsocket,msg,len,0,
|
status = sendto(udpsocket, msg, len, 0, (struct sockaddr*) toname, sizeof(struct sockaddr_in));
|
||||||
(struct sockaddr *)toname,sizeof(struct sockaddr_in));
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
void ack()
|
void ack() {
|
||||||
{
|
uchar copy[256];
|
||||||
uchar copy[256];
|
|
||||||
|
|
||||||
*copy=PKT_ACK;
|
*copy = PKT_ACK;
|
||||||
memmove(copy+1,mesg,lastsize);
|
memmove(copy + 1, mesg, lastsize);
|
||||||
putmsg(&sender,copy,lastsize+1);
|
putmsg(&sender, copy, lastsize + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int getmsg(int seconds)
|
int getmsg(int seconds) {
|
||||||
{
|
int size;
|
||||||
int size;
|
|
||||||
|
|
||||||
lastsize=-1;
|
lastsize = -1;
|
||||||
memset(&sender,0,sizeof(sender));
|
memset(&sender, 0, sizeof(sender));
|
||||||
senderlength=sizeof(sender);
|
senderlength = sizeof(sender);
|
||||||
if(seconds)
|
if (seconds) {
|
||||||
{
|
struct timeval timeout;
|
||||||
struct timeval timeout;
|
fd_set readfds;
|
||||||
fd_set readfds;
|
int res;
|
||||||
int res;
|
|
||||||
|
|
||||||
timeout.tv_sec=seconds;
|
timeout.tv_sec = seconds;
|
||||||
timeout.tv_usec=0;
|
timeout.tv_usec = 0;
|
||||||
FD_ZERO(&readfds);
|
FD_ZERO(&readfds);
|
||||||
FD_SET(udpsocket,&readfds);
|
FD_SET(udpsocket, &readfds);
|
||||||
res=select(udpsocket+1,&readfds,0,0,&timeout);
|
res = select(udpsocket + 1, &readfds, 0, 0, &timeout);
|
||||||
if(res<=0) return -1;
|
if (res <= 0) return -1;
|
||||||
}
|
}
|
||||||
lastsize=size=recvfrom(udpsocket,mesg,MAXMSG,0,
|
lastsize = size = recvfrom(udpsocket, mesg, MAXMSG, 0, (struct sockaddr*) &sender, &senderlength);
|
||||||
(struct sockaddr *)&sender,&senderlength);
|
return size;
|
||||||
return size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
long longind(unsigned char *p)
|
long longind(unsigned char* p) {
|
||||||
{
|
return (p[0] << 24L) | (p[1] << 16L) | (p[2] << 8) | p[3];
|
||||||
return (p[0]<<24L) | (p[1]<<16L) | (p[2]<<8) | p[3];
|
|
||||||
}
|
}
|
||||||
short shortind(unsigned char *p)
|
short shortind(unsigned char* p) {
|
||||||
{
|
return (p[0] << 8L) | p[1];
|
||||||
return (p[0]<<8L) | p[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void openport(int portwant)
|
void openport(int portwant) {
|
||||||
{
|
int status;
|
||||||
int status;
|
|
||||||
|
|
||||||
myport=portwant;
|
myport = portwant;
|
||||||
udpsocket=socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP);
|
udpsocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
if(udpsocket==-1)
|
if (udpsocket == -1) {
|
||||||
{
|
|
||||||
perror("socket()");
|
perror("socket()");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
memset(&myname,0,sizeof(myname));
|
memset(&myname, 0, sizeof(myname));
|
||||||
myname.sin_family=AF_INET;
|
myname.sin_family = AF_INET;
|
||||||
myname.sin_addr.s_addr=htonl(INADDR_ANY);
|
myname.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
myname.sin_port=htons(myport);
|
myname.sin_port = htons(myport);
|
||||||
|
|
||||||
status=bind(udpsocket,(struct sockaddr *) &myname,sizeof(myname));
|
status = bind(udpsocket, (struct sockaddr*) &myname, sizeof(myname));
|
||||||
if(status==-1)
|
if (status == -1) {
|
||||||
{
|
|
||||||
perror("bind()");
|
perror("bind()");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@ -169,224 +152,206 @@ int status;
|
|||||||
|
|
||||||
#define PERBLOCK 512
|
#define PERBLOCK 512
|
||||||
|
|
||||||
struct gamehost *newhost()
|
struct gamehost* newhost() {
|
||||||
{
|
struct gamehost *h, *block;
|
||||||
struct gamehost *h,*block;
|
int i;
|
||||||
int i;
|
|
||||||
|
|
||||||
if(!freehosts)
|
if (!freehosts) {
|
||||||
{
|
block = malloc(sizeof(struct gamehost) * PERBLOCK);
|
||||||
block=malloc(sizeof(struct gamehost)*PERBLOCK);
|
if (!block) return 0;
|
||||||
if(!block) return 0;
|
freehosts = block;
|
||||||
freehosts=block;
|
i = PERBLOCK - 1;
|
||||||
i=PERBLOCK-1;
|
while (i--) {
|
||||||
while(i--)
|
block->next = block + 1;
|
||||||
{
|
|
||||||
block->next=block+1;
|
|
||||||
++block;
|
++block;
|
||||||
}
|
}
|
||||||
block->next=0;
|
block->next = 0;
|
||||||
}
|
}
|
||||||
h=freehosts;
|
h = freehosts;
|
||||||
freehosts=freehosts->next;
|
freehosts = freehosts->next;
|
||||||
memset(h,0,sizeof(struct gamehost));
|
memset(h, 0, sizeof(struct gamehost));
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
void freehost(struct gamehost *h)
|
void freehost(struct gamehost* h) {
|
||||||
{
|
h->next = freehosts;
|
||||||
h->next=freehosts;
|
freehosts = h;
|
||||||
freehosts=h;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct gamehost *findmatch(struct registration *key)
|
struct gamehost* findmatch(struct registration* key) {
|
||||||
{
|
struct gamehost* h;
|
||||||
struct gamehost *h;
|
h = activehosts;
|
||||||
h=activehosts;
|
while (h) {
|
||||||
while(h)
|
if (!memcmp(&h->reg, key, sizeof(struct registration) - 1)) return h;
|
||||||
{
|
h = h->next;
|
||||||
if(!memcmp(&h->reg,key,sizeof(struct registration)-1))
|
|
||||||
return h;
|
|
||||||
h=h->next;
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void insert(struct gamehost* h) {
|
||||||
void insert(struct gamehost *h)
|
if (activehosts) {
|
||||||
{
|
h->next = activehosts;
|
||||||
if(activehosts)
|
h->prev = activehosts->prev;
|
||||||
{
|
activehosts->prev = h;
|
||||||
h->next=activehosts;
|
activehosts = h;
|
||||||
h->prev=activehosts->prev;
|
} else {
|
||||||
activehosts->prev=h;
|
h->next = h->prev = 0;
|
||||||
activehosts=h;
|
activehosts = h;
|
||||||
} else
|
|
||||||
{
|
|
||||||
h->next=h->prev=0;
|
|
||||||
activehosts=h;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void delete(struct gamehost *h)
|
void delete (struct gamehost* h) {
|
||||||
{
|
if (h->prev)
|
||||||
if(h->prev)
|
h->prev->next = h->next;
|
||||||
h->prev->next=h->next;
|
|
||||||
else
|
else
|
||||||
activehosts=h->next;
|
activehosts = h->next;
|
||||||
if(h->next)
|
if (h->next) h->next->prev = h->prev;
|
||||||
h->next->prev=h->prev;
|
|
||||||
freehost(h);
|
freehost(h);
|
||||||
}
|
}
|
||||||
void doreg()
|
void doreg() {
|
||||||
{
|
struct registration* new;
|
||||||
struct registration *new;
|
struct gamehost* match;
|
||||||
struct gamehost *match;
|
long now;
|
||||||
long now;
|
|
||||||
|
|
||||||
new=(struct registration *)mesg;
|
new = (struct registration*) mesg;
|
||||||
match=findmatch(new);
|
match = findmatch(new);
|
||||||
if(logging)
|
if (logging) {
|
||||||
{
|
unsigned addr = ntohl(sender.sin_addr.s_addr);
|
||||||
unsigned addr=ntohl(sender.sin_addr.s_addr);
|
unsigned short port = ntohs(sender.sin_port);
|
||||||
unsigned short port=ntohs(sender.sin_port);
|
printf(
|
||||||
printf("reg :%s:%d.%d.%d.%d:%d %c%lx '%s'\n",timestr(),
|
"reg :%s:%d.%d.%d.%d:%d %c%lx '%s'\n",
|
||||||
(addr>>24)&255,(addr>>16)&255,(addr>>8)&255,addr&255,port,
|
timestr(),
|
||||||
new->status ? '+' : '-',(long)match,new->name);
|
(addr >> 24) & 255,
|
||||||
|
(addr >> 16) & 255,
|
||||||
|
(addr >> 8) & 255,
|
||||||
|
addr & 255,
|
||||||
|
port,
|
||||||
|
new->status ? '+' : '-',
|
||||||
|
(long) match,
|
||||||
|
new->name);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
if(!match && !new->status) {ack();return;}
|
if (!match && !new->status) {
|
||||||
if(match && new->status) {ack();return;}
|
ack();
|
||||||
if(!match && new->status)
|
return;
|
||||||
{
|
}
|
||||||
match=newhost();
|
if (match && new->status) {
|
||||||
if(!match) return; // No memory, what can we do?
|
ack();
|
||||||
memmove(match->machine,&sender.sin_addr.s_addr,4);
|
return;
|
||||||
memmove(match->port,&sender.sin_port,2);
|
}
|
||||||
match->reg=*new;
|
if (!match && new->status) {
|
||||||
now=longtime();
|
match = newhost();
|
||||||
match->timeout=now+TIMETOLIVE;
|
if (!match) return; // No memory, what can we do?
|
||||||
|
memmove(match->machine, &sender.sin_addr.s_addr, 4);
|
||||||
|
memmove(match->port, &sender.sin_port, 2);
|
||||||
|
match->reg = *new;
|
||||||
|
now = longtime();
|
||||||
|
match->timeout = now + TIMETOLIVE;
|
||||||
ack();
|
ack();
|
||||||
insert(match);
|
insert(match);
|
||||||
return;
|
return;
|
||||||
} else // match && !new->status
|
} else // match && !new->status
|
||||||
{
|
{
|
||||||
delete(match);
|
delete (match);
|
||||||
ack();
|
ack();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void doquery()
|
void doquery() {
|
||||||
{
|
uchar* password;
|
||||||
uchar *password;
|
uchar* version;
|
||||||
uchar *version;
|
struct gamehost* h;
|
||||||
struct gamehost *h;
|
uchar response[2048], *rput, *countersave;
|
||||||
uchar response[2048],*rput,*countersave;
|
int counter;
|
||||||
int counter;
|
|
||||||
|
|
||||||
if(logging)
|
if (logging) {
|
||||||
{
|
unsigned addr = ntohl(sender.sin_addr.s_addr);
|
||||||
unsigned addr=ntohl(sender.sin_addr.s_addr);
|
unsigned short port = ntohs(sender.sin_port);
|
||||||
unsigned short port=ntohs(sender.sin_port);
|
printf("query:%s:%d.%d.%d.%d:%d\n", timestr(), (addr >> 24) & 255, (addr >> 16) & 255, (addr >> 8) & 255, addr & 255, port);
|
||||||
printf("query:%s:%d.%d.%d.%d:%d\n",timestr(),
|
|
||||||
(addr>>24)&255,(addr>>16)&255,(addr>>8)&255,addr&255,port);
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
password=mesg+1;
|
password = mesg + 1;
|
||||||
version=mesg+5;
|
version = mesg + 5;
|
||||||
h=activehosts;
|
h = activehosts;
|
||||||
rput=response;
|
rput = response;
|
||||||
*rput++=PKT_INFO;
|
*rput++ = PKT_INFO;
|
||||||
memmove(rput,password,4);
|
memmove(rput, password, 4);
|
||||||
rput+=4;
|
rput += 4;
|
||||||
memmove(rput,version,4);
|
memmove(rput, version, 4);
|
||||||
rput+=4;
|
rput += 4;
|
||||||
countersave=rput;
|
countersave = rput;
|
||||||
*rput++=0;
|
*rput++ = 0;
|
||||||
*rput++=0;
|
*rput++ = 0;
|
||||||
counter=0;
|
counter = 0;
|
||||||
|
|
||||||
while(h)
|
while (h) {
|
||||||
{
|
if (!memcmp(password, h->reg.password, 4) && !memcmp(version, h->reg.version, 4) && counter < MAXMATCHES) {
|
||||||
if(!memcmp(password,h->reg.password,4) &&
|
|
||||||
!memcmp(version,h->reg.version,4) && counter<MAXMATCHES)
|
|
||||||
{
|
|
||||||
++counter;
|
++counter;
|
||||||
memmove(rput,h->reg.unique,4);
|
memmove(rput, h->reg.unique, 4);
|
||||||
rput+=4;
|
rput += 4;
|
||||||
memmove(rput,h->machine,4);
|
memmove(rput, h->machine, 4);
|
||||||
rput+=4;
|
rput += 4;
|
||||||
memmove(rput,h->port,2);
|
memmove(rput, h->port, 2);
|
||||||
rput+=2;
|
rput += 2;
|
||||||
memmove(rput,h->reg.name,sizeof(h->reg.name));
|
memmove(rput, h->reg.name, sizeof(h->reg.name));
|
||||||
rput+=sizeof(h->reg.name);
|
rput += sizeof(h->reg.name);
|
||||||
}
|
}
|
||||||
h=h->next;
|
h = h->next;
|
||||||
}
|
}
|
||||||
*countersave++=counter>>8;
|
*countersave++ = counter >> 8;
|
||||||
*countersave++=counter;
|
*countersave++ = counter;
|
||||||
putmsg(&sender,response,rput-response);
|
putmsg(&sender, response, rput - response);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void purge(long cutoff)
|
void purge(long cutoff) {
|
||||||
{
|
struct gamehost *h, *h2;
|
||||||
struct gamehost *h,*h2;
|
h = activehosts;
|
||||||
h=activehosts;
|
while (h) {
|
||||||
while(h)
|
h2 = h;
|
||||||
{
|
h = h->next;
|
||||||
h2=h;
|
if (cutoff - h2->timeout > 0) { delete (h2); }
|
||||||
h=h->next;
|
|
||||||
if(cutoff-h2->timeout>0)
|
|
||||||
{
|
|
||||||
delete(h2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc,char **argv)
|
int main(int argc, char** argv) {
|
||||||
{
|
int i;
|
||||||
int i;
|
int want;
|
||||||
int want;
|
int size;
|
||||||
int size;
|
long purgetime;
|
||||||
long purgetime;
|
long now;
|
||||||
long now;
|
|
||||||
|
|
||||||
want=PORT;
|
want = PORT;
|
||||||
if(argc>1)
|
if (argc > 1) {
|
||||||
{
|
for (i = 1; i < argc; ++i)
|
||||||
for(i=1;i<argc;++i)
|
if (!strncmp(argv[i], "-p", 2)) {
|
||||||
if(!strncmp(argv[i],"-p",2))
|
if (strlen(argv[i]) > 2)
|
||||||
{
|
want = atoi(argv[i] + 2);
|
||||||
if(strlen(argv[i])>2) want=atoi(argv[i]+2);
|
else if (i + 1 < argc)
|
||||||
else if(i+1<argc) want=atoi(argv[i+1]);
|
want = atoi(argv[i + 1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
freehosts=0;
|
freehosts = 0;
|
||||||
openport(want);
|
openport(want);
|
||||||
purgetime=longtime()+TIMETOLIVE;
|
purgetime = longtime() + TIMETOLIVE;
|
||||||
for(;;)
|
for (;;) {
|
||||||
{
|
size = getmsg(10);
|
||||||
size=getmsg(10);
|
if (size >= 1) switch (*mesg) {
|
||||||
if(size>=1)
|
|
||||||
switch(*mesg)
|
|
||||||
{
|
|
||||||
case PKT_REGISTER:
|
case PKT_REGISTER:
|
||||||
if(size<sizeof(struct registration)) continue;
|
if (size < sizeof(struct registration)) continue;
|
||||||
doreg();
|
doreg();
|
||||||
break;
|
break;
|
||||||
case PKT_QUERY:
|
case PKT_QUERY:
|
||||||
if(size<sizeof(struct query)) continue;
|
if (size < sizeof(struct query)) continue;
|
||||||
doquery();
|
doquery();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
now=longtime();
|
now = longtime();
|
||||||
if(now-purgetime>0) // avoid year 203x bug...
|
if (now - purgetime > 0) // avoid year 203x bug...
|
||||||
{
|
{
|
||||||
purge(purgetime);
|
purge(purgetime);
|
||||||
purgetime+=TIMETOLIVE;
|
purgetime += TIMETOLIVE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
247
src/menu.c
247
src/menu.c
@ -1,73 +1,66 @@
|
|||||||
|
|
||||||
#include "bomber.h"
|
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
#include "draw.h"
|
|
||||||
#include "gfx.h"
|
|
||||||
#include "utils.h"
|
|
||||||
#include "sound.h"
|
|
||||||
#include "network.h"
|
|
||||||
#include "announce.h"
|
#include "announce.h"
|
||||||
|
#include "bomber.h"
|
||||||
|
#include "draw.h"
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
|
#include "gfx.h"
|
||||||
|
#include "network.h"
|
||||||
|
#include "sound.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
GameOptions configopts = { 2, 1, 0, 2 };
|
GameOptions configopts = {2, 1, 0, 2};
|
||||||
|
|
||||||
/* Generic menu */
|
/* Generic menu */
|
||||||
|
|
||||||
typedef enum {
|
typedef enum { MENU_ANY = -1, MENU_MAIN = 0, MENU_CONFIG = 2, MENU_JOIN = 3 } menuname;
|
||||||
MENU_ANY = -1,
|
|
||||||
MENU_MAIN = 0,
|
|
||||||
MENU_CONFIG = 2,
|
|
||||||
MENU_JOIN = 3
|
|
||||||
} menuname;
|
|
||||||
|
|
||||||
#define MENU_SELECT(x) ((menuname) (-x-1))
|
#define MENU_SELECT(x) ((menuname)(-x - 1))
|
||||||
|
|
||||||
static int menuhistory[32]={0};
|
static int menuhistory[32] = {0};
|
||||||
static char menustring[1024];
|
static char menustring[1024];
|
||||||
static char *menuput,*menuitems[40],*menutitle;
|
static char *menuput, *menuitems[40], *menutitle;
|
||||||
static int menunum, menuexit;
|
static int menunum, menuexit;
|
||||||
static int menudelta;
|
static int menudelta;
|
||||||
|
|
||||||
static void drawmenu(int selected) {
|
static void drawmenu(int selected) {
|
||||||
int i,j;
|
int i, j;
|
||||||
int tx,ty;
|
int tx, ty;
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
j=strlen(menutitle)*bigfontxsize;
|
j = strlen(menutitle) * bigfontxsize;
|
||||||
drawbigstring((IXSIZE-j) >> 1,20,menutitle);
|
drawbigstring((IXSIZE - j) >> 1, 20, menutitle);
|
||||||
ty=((IYSIZE-(bigfontysize*menunum))>>1)-(IYSIZE>>3);
|
ty = ((IYSIZE - (bigfontysize * menunum)) >> 1) - (IYSIZE >> 3);
|
||||||
for(i=0;i<menunum;++i)
|
for (i = 0; i < menunum; ++i) {
|
||||||
{
|
j = strlen(menuitems[i]) * bigfontxsize;
|
||||||
j=strlen(menuitems[i])*bigfontxsize;
|
tx = (IXSIZE - j) >> 1;
|
||||||
tx=(IXSIZE-j) >> 1;
|
if (i == selected) {
|
||||||
if(i==selected)
|
greyrect(0, ty - 1, tx - 5, bigfontysize);
|
||||||
{
|
greyrect(tx + j + 3, ty - 1, IXSIZE - (tx + j + 3), bigfontysize);
|
||||||
greyrect(0,ty-1,tx-5,bigfontysize);
|
|
||||||
greyrect(tx+j+3,ty-1,IXSIZE-(tx+j+3),bigfontysize);
|
|
||||||
}
|
}
|
||||||
drawbigstring(tx,ty,menuitems[i]);
|
drawbigstring(tx, ty, menuitems[i]);
|
||||||
ty+=bigfontyspace;
|
ty += bigfontyspace;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int domenu(menuname whichmenu, int (*pause)(void)) {
|
static int domenu(menuname whichmenu, int (*pause)(void)) {
|
||||||
char redraw;
|
char redraw;
|
||||||
int selected;
|
int selected;
|
||||||
int mcount=0;
|
int mcount = 0;
|
||||||
|
|
||||||
if(whichmenu>=0)
|
if (whichmenu >= 0)
|
||||||
selected=menuhistory[whichmenu];
|
selected = menuhistory[whichmenu];
|
||||||
else
|
else
|
||||||
selected=-whichmenu-1;
|
selected = -whichmenu - 1;
|
||||||
|
|
||||||
if (!pause) pause=mypause;
|
if (!pause) pause = mypause;
|
||||||
|
|
||||||
redraw=1;
|
redraw = 1;
|
||||||
clearspritelist();
|
clearspritelist();
|
||||||
while(!exitflag) {
|
while (!exitflag) {
|
||||||
if(redraw) {
|
if (redraw) {
|
||||||
drawmenu(selected);
|
drawmenu(selected);
|
||||||
redraw=0;
|
redraw = 0;
|
||||||
}
|
}
|
||||||
if (!pause()) return -1;
|
if (!pause()) return -1;
|
||||||
scaninput();
|
scaninput();
|
||||||
@ -75,37 +68,37 @@ static int domenu(menuname whichmenu, int (*pause)(void)) {
|
|||||||
|
|
||||||
clearsprites();
|
clearsprites();
|
||||||
clearspritelist();
|
clearspritelist();
|
||||||
addsprite(IXSIZE/2-50-20,IYSIZE-80,walking[2]+(30+mcount%15));
|
addsprite(IXSIZE / 2 - 50 - 20, IYSIZE - 80, walking[2] + (30 + mcount % 15));
|
||||||
addsprite(IXSIZE/2+50-20,IYSIZE-80,walking[3]+(30+(mcount+7)%15));
|
addsprite(IXSIZE / 2 + 50 - 20, IYSIZE - 80, walking[3] + (30 + (mcount + 7) % 15));
|
||||||
plotsprites();
|
plotsprites();
|
||||||
copyup();
|
copyup();
|
||||||
|
|
||||||
if(anydown()) playsound(3);
|
if (anydown()) playsound(3);
|
||||||
while(anydown()) {
|
while (anydown()) {
|
||||||
switch(takedown()) {
|
switch (takedown()) {
|
||||||
case MYLEFT:
|
case MYLEFT:
|
||||||
menudelta=-1;
|
menudelta = -1;
|
||||||
return selected;
|
return selected;
|
||||||
case MYRIGHT:
|
case MYRIGHT:
|
||||||
case ' ':
|
case ' ':
|
||||||
case 13:
|
case 13:
|
||||||
menudelta=1;
|
menudelta = 1;
|
||||||
return selected;
|
return selected;
|
||||||
case 'k':
|
case 'k':
|
||||||
case MYUP:
|
case MYUP:
|
||||||
if (selected) --selected;
|
if (selected)
|
||||||
else selected=menunum-1;
|
--selected;
|
||||||
if (whichmenu>=0)
|
else
|
||||||
menuhistory[whichmenu]=selected;
|
selected = menunum - 1;
|
||||||
redraw=1;
|
if (whichmenu >= 0) menuhistory[whichmenu] = selected;
|
||||||
|
redraw = 1;
|
||||||
break;
|
break;
|
||||||
case 'j':
|
case 'j':
|
||||||
case MYDOWN:
|
case MYDOWN:
|
||||||
++selected;
|
++selected;
|
||||||
if (selected==menunum) selected=0;
|
if (selected == menunum) selected = 0;
|
||||||
if (whichmenu>=0)
|
if (whichmenu >= 0) menuhistory[whichmenu] = selected;
|
||||||
menuhistory[whichmenu]=selected;
|
redraw = 1;
|
||||||
redraw=1;
|
|
||||||
break;
|
break;
|
||||||
case 0x1b:
|
case 0x1b:
|
||||||
if (MENU_MAIN == whichmenu && menuexit != selected) {
|
if (MENU_MAIN == whichmenu && menuexit != selected) {
|
||||||
@ -123,45 +116,45 @@ static int domenu(menuname whichmenu, int (*pause)(void)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void menustart() {
|
static void menustart() {
|
||||||
menunum=-1;
|
menunum = -1;
|
||||||
menuput=menustring;
|
menuput = menustring;
|
||||||
*menuput=0;
|
*menuput = 0;
|
||||||
menuexit = 0;
|
menuexit = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void additem_s(char *item, int len) {
|
static void additem_s(char* item, int len) {
|
||||||
if (len < 0 || (menustring+sizeof(menustring)-menuput <= len)) return;
|
if (len < 0 || (menustring + sizeof(menustring) - menuput <= len)) return;
|
||||||
|
|
||||||
if(menunum<0)
|
if (menunum < 0)
|
||||||
menutitle=menuput;
|
menutitle = menuput;
|
||||||
else
|
else
|
||||||
menuitems[menunum]=menuput;
|
menuitems[menunum] = menuput;
|
||||||
++menunum;
|
++menunum;
|
||||||
memcpy(menuput,item,len+1);
|
memcpy(menuput, item, len + 1);
|
||||||
menuput += len+1;
|
menuput += len + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void additem(char *item,...) {
|
static void additem(char* item, ...) {
|
||||||
char output[256];
|
char output[256];
|
||||||
va_list ap;
|
va_list ap;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
va_start(ap, item);
|
va_start(ap, item);
|
||||||
|
|
||||||
len = vsnprintf(output,sizeof(output),item,ap);
|
len = vsnprintf(output, sizeof(output), item, ap);
|
||||||
if (len >= 256) len = 255; /* truncated string */
|
if (len >= 256) len = 255; /* truncated string */
|
||||||
|
|
||||||
additem_s(output, len);
|
additem_s(output, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addexit(char *item,...) {
|
static void addexit(char* item, ...) {
|
||||||
char output[256];
|
char output[256];
|
||||||
va_list ap;
|
va_list ap;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
va_start(ap, item);
|
va_start(ap, item);
|
||||||
|
|
||||||
len = vsnprintf(output,sizeof(output),item,ap);
|
len = vsnprintf(output, sizeof(output), item, ap);
|
||||||
if (len >= 256) len = 255; /* truncated string */
|
if (len >= 256) len = 255; /* truncated string */
|
||||||
|
|
||||||
menuexit = menunum;
|
menuexit = menunum;
|
||||||
@ -173,9 +166,9 @@ static void addexit(char *item,...) {
|
|||||||
|
|
||||||
/* game menues */
|
/* game menues */
|
||||||
|
|
||||||
static const char *densities[]={"PACKED","HIGH","MEDIUM","LOW"};
|
static const char* densities[] = {"PACKED", "HIGH", "MEDIUM", "LOW"};
|
||||||
static const char *generosities[]={"LOW","MEDIUM","HIGH","RIDICULOUS"};
|
static const char* generosities[] = {"LOW", "MEDIUM", "HIGH", "RIDICULOUS"};
|
||||||
static const char *dis_en_abled[]={"DISABLED","ENABLED"};
|
static const char* dis_en_abled[] = {"DISABLED", "ENABLED"};
|
||||||
|
|
||||||
static void config_menu(void) {
|
static void config_menu(void) {
|
||||||
int sel;
|
int sel;
|
||||||
@ -184,30 +177,30 @@ static void config_menu(void) {
|
|||||||
menustart();
|
menustart();
|
||||||
additem("GAME OPTIONS");
|
additem("GAME OPTIONS");
|
||||||
additem("RETURN TO MAIN MENU");
|
additem("RETURN TO MAIN MENU");
|
||||||
additem("DENSITY: %s",densities[configopts.density]);
|
additem("DENSITY: %s", densities[configopts.density]);
|
||||||
additem("GENEROSITY: %s",generosities[configopts.generosity]);
|
additem("GENEROSITY: %s", generosities[configopts.generosity]);
|
||||||
additem("INITIAL FLAME LENGTH: %d",configopts.flames+1);
|
additem("INITIAL FLAME LENGTH: %d", configopts.flames + 1);
|
||||||
additem("INITIAL NUMBER OF BOMBS: %d",configopts.bombs+1);
|
additem("INITIAL NUMBER OF BOMBS: %d", configopts.bombs + 1);
|
||||||
additem("SOUND: %s", dis_en_abled[sound_enabled]);
|
additem("SOUND: %s", dis_en_abled[sound_enabled]);
|
||||||
sel=domenu(MENU_CONFIG, NULL);
|
sel = domenu(MENU_CONFIG, NULL);
|
||||||
switch (sel) {
|
switch (sel) {
|
||||||
case 0:
|
case 0:
|
||||||
return;
|
return;
|
||||||
case 1:
|
case 1:
|
||||||
configopts.density+=menudelta;
|
configopts.density += menudelta;
|
||||||
configopts.density&=3;
|
configopts.density &= 3;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
configopts.generosity+=menudelta;
|
configopts.generosity += menudelta;
|
||||||
configopts.generosity&=3;
|
configopts.generosity &= 3;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
configopts.flames+=menudelta;
|
configopts.flames += menudelta;
|
||||||
configopts.flames&=7;
|
configopts.flames &= 7;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
configopts.bombs+=menudelta;
|
configopts.bombs += menudelta;
|
||||||
configopts.bombs&=7;
|
configopts.bombs &= 7;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
sound_enabled = 1 - sound_enabled;
|
sound_enabled = 1 - sound_enabled;
|
||||||
@ -218,20 +211,20 @@ static void config_menu(void) {
|
|||||||
|
|
||||||
static void draw_host_game(void) {
|
static void draw_host_game(void) {
|
||||||
int i;
|
int i;
|
||||||
char *name;
|
char* name;
|
||||||
char temp[64];
|
char temp[64];
|
||||||
|
|
||||||
#define M3X (IXSIZE/3)
|
#define M3X (IXSIZE / 3)
|
||||||
#define M3Y (IYSIZE/4)
|
#define M3Y (IYSIZE / 4)
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
centerbig(20,"HOST NETWORK GAME");
|
centerbig(20, "HOST NETWORK GAME");
|
||||||
drawbigstring(M3X,M3Y,"SLOT NAME");
|
drawbigstring(M3X, M3Y, "SLOT NAME");
|
||||||
for(i=0;i<MAXNETNODES;++i) {
|
for (i = 0; i < MAXNETNODES; ++i) {
|
||||||
if(!netnodes[i].used) continue;
|
if (!netnodes[i].used) continue;
|
||||||
name=netnodes[i].name;
|
name = netnodes[i].name;
|
||||||
snprintf(temp,sizeof(temp)," %d %s",i+1,name);
|
snprintf(temp, sizeof(temp), " %d %s", i + 1, name);
|
||||||
drawbigstring(M3X,M3Y+(i+2)*bigfontyspace,temp);
|
drawbigstring(M3X, M3Y + (i + 2) * bigfontyspace, temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
copyup();
|
copyup();
|
||||||
@ -246,10 +239,10 @@ static void host_game(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
draw_host_game();
|
draw_host_game();
|
||||||
for(;;) {
|
for (;;) {
|
||||||
scaninput();
|
scaninput();
|
||||||
while(anydown()) {
|
while (anydown()) {
|
||||||
switch(takedown()) {
|
switch (takedown()) {
|
||||||
case 0x1b:
|
case 0x1b:
|
||||||
unregistergame();
|
unregistergame();
|
||||||
cancel_network_game();
|
cancel_network_game();
|
||||||
@ -278,27 +271,25 @@ static void drawjoinscreen(void) {
|
|||||||
char name[17];
|
char name[17];
|
||||||
char temp[64];
|
char temp[64];
|
||||||
|
|
||||||
#define JX (IXSIZE/3)
|
#define JX (IXSIZE / 3)
|
||||||
#define JY (IYSIZE/4)
|
#define JY (IYSIZE / 4)
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
centerbig(20,"JOIN NETWORK GAME");
|
centerbig(20, "JOIN NETWORK GAME");
|
||||||
drawbigstring(JX,JY,"SLOT NAME");
|
drawbigstring(JX, JY, "SLOT NAME");
|
||||||
for (i = 0; i < MAXNETNODES; ++i) {
|
for (i = 0; i < MAXNETNODES; ++i) {
|
||||||
if(!netnodes[i].used) continue;
|
if (!netnodes[i].used) continue;
|
||||||
memmove(name,netnodes[i].name,16);
|
memmove(name, netnodes[i].name, 16);
|
||||||
name[16]=0;
|
name[16] = 0;
|
||||||
snprintf(temp,sizeof(temp)," %d %s",i+1,name);
|
snprintf(temp, sizeof(temp), " %d %s", i + 1, name);
|
||||||
drawbigstring(JX,JY+(i+1)*bigfontyspace,temp);
|
drawbigstring(JX, JY + (i + 1) * bigfontyspace, temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tryjoin(int which) {
|
static int tryjoin(int which) {
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
if (0 == (res = send_join(&gamelistentries[which].netname, playername))) {
|
if (0 == (res = send_join(&gamelistentries[which].netname, playername))) { return 0; }
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!exitflag) {
|
while (!exitflag) {
|
||||||
switch (res) {
|
switch (res) {
|
||||||
@ -309,18 +300,20 @@ static int tryjoin(int which) {
|
|||||||
drawjoinscreen();
|
drawjoinscreen();
|
||||||
copyup();
|
copyup();
|
||||||
break;
|
break;
|
||||||
case 3: return 1;
|
case 3:
|
||||||
default: break;
|
return 1;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
scaninput();
|
scaninput();
|
||||||
while(anydown()) {
|
while (anydown()) {
|
||||||
switch(takedown()) {
|
switch (takedown()) {
|
||||||
case 0x1b:
|
case 0x1b:
|
||||||
send_quit();
|
send_quit();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res=scaninvite(200);
|
res = scaninvite(200);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -335,9 +328,7 @@ static void join_game(void) {
|
|||||||
int i;
|
int i;
|
||||||
int sel = -1;
|
int sel = -1;
|
||||||
|
|
||||||
if (!searchgames()) {
|
if (!searchgames()) { return; }
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
menuhistory[MENU_JOIN] = 0;
|
menuhistory[MENU_JOIN] = 0;
|
||||||
|
|
||||||
@ -348,9 +339,7 @@ static void join_game(void) {
|
|||||||
addexit("EXIT");
|
addexit("EXIT");
|
||||||
} else {
|
} else {
|
||||||
additem("JOIN NETWORK GAME");
|
additem("JOIN NETWORK GAME");
|
||||||
for (i = 0; i < gamelistsize; i++) {
|
for (i = 0; i < gamelistsize; i++) { additem(gamelistentries[i].name); }
|
||||||
additem(gamelistentries[i].name);
|
|
||||||
}
|
|
||||||
addexit("EXIT");
|
addexit("EXIT");
|
||||||
}
|
}
|
||||||
sel = domenu(MENU_JOIN, join_game_pause);
|
sel = domenu(MENU_JOIN, join_game_pause);
|
||||||
@ -358,12 +347,8 @@ static void join_game(void) {
|
|||||||
}
|
}
|
||||||
stop_search();
|
stop_search();
|
||||||
|
|
||||||
if(menuexit == sel || !gamelistsize) {
|
if (menuexit == sel || !gamelistsize) { return; }
|
||||||
return;
|
if (!tryjoin(sel)) { return; }
|
||||||
}
|
|
||||||
if(!tryjoin(sel)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
run_network_game();
|
run_network_game();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,16 +356,16 @@ void mainloop(void) {
|
|||||||
int sel;
|
int sel;
|
||||||
|
|
||||||
exitflag = 0;
|
exitflag = 0;
|
||||||
while(!exitflag) {
|
while (!exitflag) {
|
||||||
menustart();
|
menustart();
|
||||||
additem("BOMBER MAIN MENU");
|
additem("BOMBER MAIN MENU");
|
||||||
additem("EXIT GAME");
|
additem("EXIT GAME");
|
||||||
additem("START SINGLE PLAYER GAME");
|
additem("START SINGLE PLAYER GAME");
|
||||||
additem("OPTIONS");
|
additem("OPTIONS");
|
||||||
// additem("REMAP MOVEMENT KEYS");
|
// additem("REMAP MOVEMENT KEYS");
|
||||||
additem("START NETWORK GAME");
|
additem("START NETWORK GAME");
|
||||||
additem("JOIN NETWORK GAME");
|
additem("JOIN NETWORK GAME");
|
||||||
sel=domenu(MENU_MAIN, NULL);
|
sel = domenu(MENU_MAIN, NULL);
|
||||||
if (menudelta < 0) sel = -1;
|
if (menudelta < 0) sel = -1;
|
||||||
switch (sel) {
|
switch (sel) {
|
||||||
case 0:
|
case 0:
|
||||||
|
359
src/network.c
359
src/network.c
@ -1,34 +1,34 @@
|
|||||||
|
|
||||||
#include "bomber.h"
|
#include "network.h"
|
||||||
#include "announce.h"
|
#include "announce.h"
|
||||||
|
#include "bomber.h"
|
||||||
|
#include "draw.h"
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
#include "network.h"
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "draw.h"
|
|
||||||
|
|
||||||
#define MAXMSG 4096
|
#define MAXMSG 4096
|
||||||
|
|
||||||
int udpsocket;
|
int udpsocket;
|
||||||
const unsigned char gameversion[4]={0xda,0x01,0x00,0x09};
|
const unsigned char gameversion[4] = {0xda, 0x01, 0x00, 0x09};
|
||||||
|
|
||||||
struct netnode netnodes[MAXNETNODES];
|
struct netnode netnodes[MAXNETNODES];
|
||||||
|
|
||||||
static int informsize;
|
static int informsize;
|
||||||
static unsigned char regpacket[64];
|
static unsigned char regpacket[64];
|
||||||
|
|
||||||
static struct sockaddr_in myname={0},mastername={0};
|
static struct sockaddr_in myname = {0}, mastername = {0};
|
||||||
static socklen_t senderlength;
|
static socklen_t senderlength;
|
||||||
static struct sockaddr_in sender={0};
|
static struct sockaddr_in sender = {0};
|
||||||
|
|
||||||
static unsigned char mesg[MAXMSG]="";
|
static unsigned char mesg[MAXMSG] = "";
|
||||||
uchar needwhole=0;
|
uchar needwhole = 0;
|
||||||
int mydatacount;
|
int mydatacount;
|
||||||
int myslot;
|
int myslot;
|
||||||
network_type network = NETWORK_NONE;
|
network_type network = NETWORK_NONE;
|
||||||
|
|
||||||
int actioncount;
|
int actioncount;
|
||||||
unsigned char actionblock[ACTIONHIST*MAXNETNODES];
|
unsigned char actionblock[ACTIONHIST * MAXNETNODES];
|
||||||
|
|
||||||
int myaction;
|
int myaction;
|
||||||
unsigned char actions[MAXNETNODES];
|
unsigned char actions[MAXNETNODES];
|
||||||
@ -37,22 +37,22 @@ unsigned char latestactions[MAXNETNODES];
|
|||||||
long latestcounts[MAXNETNODES];
|
long latestcounts[MAXNETNODES];
|
||||||
|
|
||||||
enum network_packet_types {
|
enum network_packet_types {
|
||||||
PKT_ACK, /* perfect copy of packet received */
|
PKT_ACK, /* perfect copy of packet received */
|
||||||
/* join / host game */
|
/* join / host game */
|
||||||
/* slave -> master packets */
|
/* slave -> master packets */
|
||||||
PKT_JOIN, /* 4 bytes version #, 4 bytes joinunique #, 16 bytes name */
|
PKT_JOIN, /* 4 bytes version #, 4 bytes joinunique #, 16 bytes name */
|
||||||
PKT_QUIT, /* 4 bytes unique # */
|
PKT_QUIT, /* 4 bytes unique # */
|
||||||
/* master -> slave packets */
|
/* master -> slave packets */
|
||||||
PKT_INVITE, /* 4 bytes unique #, 1 byte your slot (0xff for kick, no data following it) #, any # of 1:slot,16:name sets (-1 end) */
|
PKT_INVITE, /* 4 bytes unique #, 1 byte your slot (0xff for kick, no data following it) #, any # of 1:slot,16:name sets (-1 end) */
|
||||||
PKT_BEGIN, /* clone of INVITE */
|
PKT_BEGIN, /* clone of INVITE */
|
||||||
PKT_CONFIG, /* 4 bytes unique #, config */
|
PKT_CONFIG, /* 4 bytes unique #, config */
|
||||||
PKT_ACCEPT, /* 4 bytes join unique #, 132 bytes seed + unique #, config, slot info (see invite) */
|
PKT_ACCEPT, /* 4 bytes join unique #, 132 bytes seed + unique #, config, slot info (see invite) */
|
||||||
PKT_REJECT, /* 4 bytes join unique #, 4 bytes version #, 1: reason */
|
PKT_REJECT, /* 4 bytes join unique #, 4 bytes version #, 1: reason */
|
||||||
/* ingame actions */
|
/* ingame actions */
|
||||||
/* slave -> master packets */
|
/* slave -> master packets */
|
||||||
PKT_MYDATA, /* 4 bytes unique #,4 bytes frame #, 1 byte data */
|
PKT_MYDATA, /* 4 bytes unique #,4 bytes frame #, 1 byte data */
|
||||||
/* master -> slave packets */
|
/* master -> slave packets */
|
||||||
PKT_STEP, /* 4 bytes unique #, 4 bytes frame #, history x MAXNETNODES bytes ACT_* */
|
PKT_STEP, /* 4 bytes unique #, 4 bytes frame #, history x MAXNETNODES bytes ACT_* */
|
||||||
|
|
||||||
PKT_INVALID = 0xff
|
PKT_INVALID = 0xff
|
||||||
};
|
};
|
||||||
@ -65,10 +65,7 @@ enum reject_reason {
|
|||||||
|
|
||||||
#define _REJECT_LAST REJECT_VERSION
|
#define _REJECT_LAST REJECT_VERSION
|
||||||
|
|
||||||
const char *reject_reason_str[] = {
|
const char* reject_reason_str[] = {"Server full", "Version mismatch"};
|
||||||
"Server full",
|
|
||||||
"Version mismatch"
|
|
||||||
};
|
|
||||||
|
|
||||||
/* all bytes stored MSB first */
|
/* all bytes stored MSB first */
|
||||||
|
|
||||||
@ -125,135 +122,126 @@ received will be answered with PKT_QUIT.
|
|||||||
|
|
||||||
/* Network I/O, building/checking packets */
|
/* Network I/O, building/checking packets */
|
||||||
|
|
||||||
#if defined (TEST_LATENCY)
|
#if defined(TEST_LATENCY)
|
||||||
#define NUMQ 512
|
#define NUMQ 512
|
||||||
struct message {
|
struct message {
|
||||||
int time;
|
int time;
|
||||||
struct sockaddr_in *to;
|
struct sockaddr_in* to;
|
||||||
int tosize;
|
int tosize;
|
||||||
unsigned char msg[512];
|
unsigned char msg[512];
|
||||||
int len;
|
int len;
|
||||||
} message[NUMQ]={0};
|
} message[NUMQ] = {0};
|
||||||
|
|
||||||
|
|
||||||
outmsgs() {
|
outmsgs() {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i=0;i<NUMQ;++i) {
|
for (i = 0; i < NUMQ; ++i) {
|
||||||
if(message[i].time) {
|
if (message[i].time) {
|
||||||
--message[i].time;
|
--message[i].time;
|
||||||
if(message[i].time) continue;
|
if (message[i].time) continue;
|
||||||
sendto(udpsocket,message[i].msg,message[i].len,0,
|
sendto(udpsocket, message[i].msg, message[i].len, 0, message[i].to, sizeof(struct sockaddr_in));
|
||||||
message[i].to,sizeof(struct sockaddr_in));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int putmsg(struct sockaddr_in *toname,unsigned char *msg,int len) {
|
static int putmsg(struct sockaddr_in* toname, unsigned char* msg, int len) {
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
#if defined (TEST_LATENCY)
|
#if defined(TEST_LATENCY)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i=0;i<NUMQ;++i) {
|
for (i = 0; i < NUMQ; ++i) {
|
||||||
if(!message[i].time) {
|
if (!message[i].time) {
|
||||||
message[i].time=10;
|
message[i].time = 10;
|
||||||
message[i].to=toname;
|
message[i].to = toname;
|
||||||
memcpy(message[i].msg,msg,len);
|
memcpy(message[i].msg, msg, len);
|
||||||
message[i].len=len;
|
message[i].len = len;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
#else
|
||||||
status=sendto(udpsocket,msg,len,0,
|
status = sendto(udpsocket, msg, len, 0, (struct sockaddr*) toname, sizeof(struct sockaddr_in));
|
||||||
(struct sockaddr *)toname,sizeof(struct sockaddr_in));
|
|
||||||
return status;
|
return status;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int getmsg(int msec) {
|
static int getmsg(int msec) {
|
||||||
int size;
|
int size;
|
||||||
|
|
||||||
memset(&sender,0,sizeof(sender));
|
memset(&sender, 0, sizeof(sender));
|
||||||
senderlength=sizeof(sender);
|
senderlength = sizeof(sender);
|
||||||
if(msec) {
|
if (msec) {
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
fd_set readfds;
|
fd_set readfds;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
memset(&timeout,0,sizeof(timeout));
|
memset(&timeout, 0, sizeof(timeout));
|
||||||
timeout.tv_sec=msec/1000;
|
timeout.tv_sec = msec / 1000;
|
||||||
timeout.tv_usec=(msec%1000)*1000;
|
timeout.tv_usec = (msec % 1000) * 1000;
|
||||||
FD_ZERO(&readfds);
|
FD_ZERO(&readfds);
|
||||||
FD_SET(udpsocket,&readfds);
|
FD_SET(udpsocket, &readfds);
|
||||||
res=select(udpsocket+1,&readfds,0,0,&timeout);
|
res = select(udpsocket + 1, &readfds, 0, 0, &timeout);
|
||||||
if(res<=0) return -1;
|
if (res <= 0) return -1;
|
||||||
}
|
}
|
||||||
size=recvfrom(udpsocket,mesg,MAXMSG,0,
|
size = recvfrom(udpsocket, mesg, MAXMSG, 0, (struct sockaddr*) &sender, &senderlength);
|
||||||
(struct sockaddr *)&sender,&senderlength);
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int isvalidunique(unsigned char *p) {
|
static int isvalidunique(unsigned char* p) {
|
||||||
return 0 == memcmp(p, &network_unique, 4);
|
return 0 == memcmp(p, &network_unique, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int isvalidversion(unsigned char *p) {
|
static int isvalidversion(unsigned char* p) {
|
||||||
return 0 == memcmp(p, gameversion, 4);
|
return 0 == memcmp(p, gameversion, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned char* writeuint32(unsigned char *p, Uint32 i) {
|
static unsigned char* writeuint32(unsigned char* p, Uint32 i) {
|
||||||
p[0]=i>>24L;
|
p[0] = i >> 24L;
|
||||||
p[1]=i>>16L;
|
p[1] = i >> 16L;
|
||||||
p[2]=i>>8L;
|
p[2] = i >> 8L;
|
||||||
p[3]=i;
|
p[3] = i;
|
||||||
return p+4;
|
return p + 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint32 readuint32(unsigned char *p) {
|
static Uint32 readuint32(unsigned char* p) {
|
||||||
return (p[0]<<24L) | (p[1]<<16L) | (p[2]<<8) | p[3];
|
return (p[0] << 24L) | (p[1] << 16L) | (p[2] << 8) | p[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned char* write_unique(unsigned char *p) {
|
static unsigned char* write_unique(unsigned char* p) {
|
||||||
memcpy(p, &network_unique, 4);
|
memcpy(p, &network_unique, 4);
|
||||||
return p + 4;
|
return p + 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned char* write_version(unsigned char *p) {
|
static unsigned char* write_version(unsigned char* p) {
|
||||||
memcpy(p, &gameversion, 4);
|
memcpy(p, &gameversion, 4);
|
||||||
return p + 4;
|
return p + 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int isvalidmsg_from_slave() {
|
static int isvalidmsg_from_slave() {
|
||||||
int i;
|
int i;
|
||||||
void *host;
|
void* host;
|
||||||
void *port;
|
void* port;
|
||||||
|
|
||||||
if (!isvalidunique(mesg+1)) return -1;
|
if (!isvalidunique(mesg + 1)) return -1;
|
||||||
host=&sender.sin_addr.s_addr;
|
host = &sender.sin_addr.s_addr;
|
||||||
port=&sender.sin_port;
|
port = &sender.sin_port;
|
||||||
for(i=1;i<MAXNETNODES;++i)
|
for (i = 1; i < MAXNETNODES; ++i)
|
||||||
if(netnodes[i].used &&
|
if (netnodes[i].used && !memcmp(&netnodes[i].netname.sin_addr.s_addr, host, 4) && !memcmp(&netnodes[i].netname.sin_port, port, 2)) return i;
|
||||||
!memcmp(&netnodes[i].netname.sin_addr.s_addr,host,4) &&
|
|
||||||
!memcmp(&netnodes[i].netname.sin_port,port,2))
|
|
||||||
return i;
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int isvalidmsg_from_master() {
|
static int isvalidmsg_from_master() {
|
||||||
if (sender.sin_family != mastername.sin_family
|
if (sender.sin_family != mastername.sin_family || sender.sin_addr.s_addr != mastername.sin_addr.s_addr || sender.sin_port != mastername.sin_port) return 0;
|
||||||
|| sender.sin_addr.s_addr != mastername.sin_addr.s_addr
|
|
||||||
|| sender.sin_port != mastername.sin_port) return 0;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handling game actions */
|
/* Handling game actions */
|
||||||
|
|
||||||
static void addactions(void) {
|
static void addactions(void) {
|
||||||
memmove(actionblock+MAXNETNODES, actionblock, (ACTIONHIST-1)*MAXNETNODES);
|
memmove(actionblock + MAXNETNODES, actionblock, (ACTIONHIST - 1) * MAXNETNODES);
|
||||||
memcpy(actionblock, actions, MAXNETNODES);
|
memcpy(actionblock, actions, MAXNETNODES);
|
||||||
++actioncount;
|
++actioncount;
|
||||||
}
|
}
|
||||||
@ -264,8 +252,8 @@ static void sendactions(int which) {
|
|||||||
msg[0] = PKT_STEP;
|
msg[0] = PKT_STEP;
|
||||||
write_unique(msg + 1);
|
write_unique(msg + 1);
|
||||||
writeuint32(msg + 5, actioncount);
|
writeuint32(msg + 5, actioncount);
|
||||||
memcpy(msg + 9, actionblock, MAXNETNODES*ACTIONHIST);
|
memcpy(msg + 9, actionblock, MAXNETNODES * ACTIONHIST);
|
||||||
putmsg(&netnodes[which].netname, msg, MAXNETNODES*ACTIONHIST + 9);
|
putmsg(&netnodes[which].netname, msg, MAXNETNODES * ACTIONHIST + 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sendmine(int frame) {
|
static void sendmine(int frame) {
|
||||||
@ -289,17 +277,15 @@ int networktraffic(void) {
|
|||||||
case NETWORK_NONE:
|
case NETWORK_NONE:
|
||||||
return -1;
|
return -1;
|
||||||
case NETWORK_MASTER:
|
case NETWORK_MASTER:
|
||||||
memcpy(actions,latestactions,MAXNETNODES);
|
memcpy(actions, latestactions, MAXNETNODES);
|
||||||
actions[0]=myaction;
|
actions[0] = myaction;
|
||||||
if (myaction == ACT_QUIT) {
|
if (myaction == ACT_QUIT) {
|
||||||
for (i = 1; i < MAXNETNODES; ++i) {
|
for (i = 1; i < MAXNETNODES; ++i) {
|
||||||
if (netnodes[i].used)
|
if (netnodes[i].used) actions[i] = ACT_QUIT;
|
||||||
actions[i] = ACT_QUIT;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i = 1; i < MAXNETNODES; ++i) {
|
for (i = 1; i < MAXNETNODES; ++i) {
|
||||||
if (netnodes[i].used)
|
if (netnodes[i].used) actions[i] &= ACT_MASK; /* only keep direction */
|
||||||
actions[i] &= ACT_MASK; /* only keep direction */
|
|
||||||
}
|
}
|
||||||
now = gtime();
|
now = gtime();
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -313,7 +299,7 @@ int networktraffic(void) {
|
|||||||
if (length < 10) continue;
|
if (length < 10) continue;
|
||||||
whosent = isvalidmsg_from_slave();
|
whosent = isvalidmsg_from_slave();
|
||||||
if (whosent <= 0) continue;
|
if (whosent <= 0) continue;
|
||||||
count = readuint32(mesg+5);
|
count = readuint32(mesg + 5);
|
||||||
if (count > latestcounts[whosent]) {
|
if (count > latestcounts[whosent]) {
|
||||||
latestcounts[whosent] = count;
|
latestcounts[whosent] = count;
|
||||||
actions[whosent] = (actions[whosent] & ~ACT_MASK) | mesg[9]; /* don't drop "action" keys */
|
actions[whosent] = (actions[whosent] & ~ACT_MASK) | mesg[9]; /* don't drop "action" keys */
|
||||||
@ -324,10 +310,9 @@ int networktraffic(void) {
|
|||||||
addactions(); /* update action history block */
|
addactions(); /* update action history block */
|
||||||
|
|
||||||
for (i = 1; i < MAXNETNODES; ++i) {
|
for (i = 1; i < MAXNETNODES; ++i) {
|
||||||
if(netnodes[i].used) {
|
if (netnodes[i].used) {
|
||||||
sendactions(i); /* send actions to every active node */
|
sendactions(i); /* send actions to every active node */
|
||||||
if (actions[i] == ACT_QUIT)
|
if (actions[i] == ACT_QUIT) netnodes[i].used = 0; /* remove disconnected clients */
|
||||||
netnodes[i].used = 0; /* remove disconnected clients */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return actioncount;
|
return actioncount;
|
||||||
@ -339,7 +324,7 @@ int networktraffic(void) {
|
|||||||
sendmine(mydatacount);
|
sendmine(mydatacount);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* if we got already one packet we only wait 3msec, otherwise 30msec */
|
/* if we got already one packet we only wait 3msec, otherwise 30msec */
|
||||||
long cur = gtime();
|
long cur = gtime();
|
||||||
if (count >= 0 && cur - now > 3) break;
|
if (count >= 0 && cur - now > 3) break;
|
||||||
if (exitflag || cur - now > 30) break;
|
if (exitflag || cur - now > 30) break;
|
||||||
@ -361,37 +346,37 @@ int networktraffic(void) {
|
|||||||
|
|
||||||
/* Handling socket init */
|
/* Handling socket init */
|
||||||
|
|
||||||
int winsock=0;
|
int winsock = 0;
|
||||||
|
|
||||||
void getsocket(void) {
|
void getsocket(void) {
|
||||||
int status;
|
int status;
|
||||||
socklen_t slen = sizeof(myname);
|
socklen_t slen = sizeof(myname);
|
||||||
#if defined(__WIN32__) || defined(WIN32)
|
#if defined(__WIN32__) || defined(WIN32)
|
||||||
char dummydata[128];
|
char dummydata[128];
|
||||||
|
|
||||||
if(WSAStartup(0x0101,(void *)dummydata)) {
|
if (WSAStartup(0x0101, (void*) dummydata)) {
|
||||||
printf("Windows dumped\n");
|
printf("Windows dumped\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
winsock=1;
|
winsock = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
udpsocket=socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP);
|
udpsocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
if(udpsocket==-1) {
|
if (udpsocket == -1) {
|
||||||
perror("socket()");
|
perror("socket()");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
memset(&myname,0,sizeof(myname));
|
memset(&myname, 0, sizeof(myname));
|
||||||
myname.sin_family=AF_INET;
|
myname.sin_family = AF_INET;
|
||||||
myname.sin_addr.s_addr=htonl(INADDR_ANY);
|
myname.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
myname.sin_port=htons(0);
|
myname.sin_port = htons(0);
|
||||||
status=bind(udpsocket,(struct sockaddr *) &myname,sizeof(myname));
|
status = bind(udpsocket, (struct sockaddr*) &myname, sizeof(myname));
|
||||||
if(-1 == status) {
|
if (-1 == status) {
|
||||||
perror("bind()");
|
perror("bind()");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
status = getsockname(udpsocket, (struct sockaddr *) &myname, &slen);
|
status = getsockname(udpsocket, (struct sockaddr*) &myname, &slen);
|
||||||
if(-1 == status) {
|
if (-1 == status) {
|
||||||
perror("getsockname()");
|
perror("getsockname()");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@ -399,7 +384,7 @@ char dummydata[128];
|
|||||||
|
|
||||||
void freesocket(void) {
|
void freesocket(void) {
|
||||||
#if defined(__WIN32__) || defined(WIN32)
|
#if defined(__WIN32__) || defined(WIN32)
|
||||||
if(!winsock) return;
|
if (!winsock) return;
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -413,7 +398,7 @@ static unsigned char* write_inform(unsigned char* put) {
|
|||||||
|
|
||||||
*put++ = 0xff; /* slot specific for each slave */
|
*put++ = 0xff; /* slot specific for each slave */
|
||||||
for (i = 0; i < MAXNETNODES; ++i) {
|
for (i = 0; i < MAXNETNODES; ++i) {
|
||||||
if(!netnodes[i].used) continue;
|
if (!netnodes[i].used) continue;
|
||||||
*put++ = i;
|
*put++ = i;
|
||||||
memmove(put, netnodes[i].name, 16);
|
memmove(put, netnodes[i].name, 16);
|
||||||
put += 16;
|
put += 16;
|
||||||
@ -424,15 +409,15 @@ static unsigned char* write_inform(unsigned char* put) {
|
|||||||
|
|
||||||
static void send_inform_all(unsigned char type) {
|
static void send_inform_all(unsigned char type) {
|
||||||
int i;
|
int i;
|
||||||
unsigned char *put = mesg;
|
unsigned char* put = mesg;
|
||||||
|
|
||||||
*put++ = type;
|
*put++ = type;
|
||||||
put = write_unique(put);
|
put = write_unique(put);
|
||||||
put = write_inform(put);
|
put = write_inform(put);
|
||||||
informsize = put-mesg;
|
informsize = put - mesg;
|
||||||
|
|
||||||
for(i=1;i<MAXNETNODES;++i) {
|
for (i = 1; i < MAXNETNODES; ++i) {
|
||||||
if(netnodes[i].used) {
|
if (netnodes[i].used) {
|
||||||
mesg[5] = i;
|
mesg[5] = i;
|
||||||
putmsg(&netnodes[i].netname, mesg, informsize);
|
putmsg(&netnodes[i].netname, mesg, informsize);
|
||||||
}
|
}
|
||||||
@ -448,36 +433,35 @@ static unsigned char* write_config(unsigned char* put) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void build_config() {
|
static void build_config() {
|
||||||
unsigned char *put;
|
unsigned char* put;
|
||||||
|
|
||||||
put=mesg;
|
put = mesg;
|
||||||
*put++=PKT_CONFIG;
|
*put++ = PKT_CONFIG;
|
||||||
put = write_config(put);
|
put = write_config(put);
|
||||||
informsize=put-mesg;
|
informsize = put - mesg;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_config1(int which) {
|
static void send_config1(int which) {
|
||||||
putmsg(&netnodes[which].netname,mesg,informsize);
|
putmsg(&netnodes[which].netname, mesg, informsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_config() {
|
void send_config() {
|
||||||
int i;
|
int i;
|
||||||
build_config();
|
build_config();
|
||||||
for (i = 1; i < MAXNETNODES; ++i)
|
for (i = 1; i < MAXNETNODES; ++i)
|
||||||
if (netnodes[i].used)
|
if (netnodes[i].used) send_config1(i);
|
||||||
send_config1(i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_reject(struct sockaddr_in *toname, Uint32 network_join_unique, unsigned char reason) {
|
static void send_reject(struct sockaddr_in* toname, Uint32 network_join_unique, unsigned char reason) {
|
||||||
mesg[0] = PKT_REJECT;
|
mesg[0] = PKT_REJECT;
|
||||||
memcpy(mesg+1, &network_join_unique, sizeof(network_join_unique));
|
memcpy(mesg + 1, &network_join_unique, sizeof(network_join_unique));
|
||||||
write_version(mesg+5);
|
write_version(mesg + 5);
|
||||||
mesg[9] = reason;
|
mesg[9] = reason;
|
||||||
putmsg(toname,mesg,10);
|
putmsg(toname, mesg, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_accept(Uint32 network_join_unique) {
|
static void send_accept(Uint32 network_join_unique) {
|
||||||
unsigned char *put = mesg;
|
unsigned char* put = mesg;
|
||||||
|
|
||||||
*put++ = PKT_ACCEPT;
|
*put++ = PKT_ACCEPT;
|
||||||
memcpy(put, &network_join_unique, sizeof(network_join_unique));
|
memcpy(put, &network_join_unique, sizeof(network_join_unique));
|
||||||
@ -485,15 +469,15 @@ static void send_accept(Uint32 network_join_unique) {
|
|||||||
put = write_seed_unique(put);
|
put = write_seed_unique(put);
|
||||||
put = write_config(put);
|
put = write_config(put);
|
||||||
put = write_inform(put);
|
put = write_inform(put);
|
||||||
putmsg(&sender,mesg,put-mesg);
|
putmsg(&sender, mesg, put - mesg);
|
||||||
}
|
}
|
||||||
|
|
||||||
int start_network_game() {
|
int start_network_game() {
|
||||||
if(!registergame(playername, myname.sin_port, gameversion)) return 0;
|
if (!registergame(playername, myname.sin_port, gameversion)) return 0;
|
||||||
memset(netnodes,0,sizeof(netnodes));
|
memset(netnodes, 0, sizeof(netnodes));
|
||||||
netnodes[0].used=1;
|
netnodes[0].used = 1;
|
||||||
memmove(netnodes[0].name,playername,16);
|
memmove(netnodes[0].name, playername, 16);
|
||||||
myslot=0;
|
myslot = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -512,13 +496,11 @@ void cancel_network_game() {
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
mesg[0] = PKT_INVITE;
|
mesg[0] = PKT_INVITE;
|
||||||
write_unique(mesg+1);
|
write_unique(mesg + 1);
|
||||||
mesg[5] = 0xff;
|
mesg[5] = 0xff;
|
||||||
|
|
||||||
for(i=1;i<MAXNETNODES;++i) {
|
for (i = 1; i < MAXNETNODES; ++i) {
|
||||||
if(netnodes[i].used) {
|
if (netnodes[i].used) { putmsg(&netnodes[i].netname, mesg, 6); }
|
||||||
putmsg(&netnodes[i].netname,mesg,6);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -528,18 +510,18 @@ int handle_joins() {
|
|||||||
unsigned char temp[64];
|
unsigned char temp[64];
|
||||||
Uint32 network_join_unique = 0;
|
Uint32 network_join_unique = 0;
|
||||||
|
|
||||||
size=getmsg(40);
|
size = getmsg(40);
|
||||||
switch (*mesg) {
|
switch (*mesg) {
|
||||||
case PKT_JOIN:
|
case PKT_JOIN:
|
||||||
if (size < 25) return 0;
|
if (size < 25) return 0;
|
||||||
memcpy(&network_join_unique, mesg+5, sizeof(network_join_unique));
|
memcpy(&network_join_unique, mesg + 5, sizeof(network_join_unique));
|
||||||
if (!isvalidversion(mesg+1)) {
|
if (!isvalidversion(mesg + 1)) {
|
||||||
send_reject(&sender, network_join_unique, REJECT_VERSION);
|
send_reject(&sender, network_join_unique, REJECT_VERSION);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PKT_QUIT:
|
case PKT_QUIT:
|
||||||
if (size < 5 || !isvalidunique(mesg+1)) return 0;
|
if (size < 5 || !isvalidunique(mesg + 1)) return 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
@ -556,37 +538,33 @@ int handle_joins() {
|
|||||||
if (-1 == j) j = i;
|
if (-1 == j) j = i;
|
||||||
continue; /* don't compare with unused host */
|
continue; /* don't compare with unused host */
|
||||||
}
|
}
|
||||||
if(memcmp(&netnodes[i].netname.sin_addr.s_addr,
|
if (memcmp(&netnodes[i].netname.sin_addr.s_addr, &sender.sin_addr.s_addr, 4)) continue;
|
||||||
&sender.sin_addr.s_addr,4)) continue;
|
if (memcmp(&netnodes[i].netname.sin_port, &sender.sin_port, 2)) continue;
|
||||||
if(memcmp(&netnodes[i].netname.sin_port,
|
|
||||||
&sender.sin_port,2)) continue;
|
|
||||||
/* found host */
|
/* found host */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (*mesg) {
|
switch (*mesg) {
|
||||||
case PKT_QUIT:
|
case PKT_QUIT:
|
||||||
if(i < MAXNETNODES) /* if host found, reset entry */
|
if (i < MAXNETNODES) /* if host found, reset entry */
|
||||||
memset(netnodes+i,0,sizeof(struct netnode));
|
memset(netnodes + i, 0, sizeof(struct netnode));
|
||||||
/* send always ACK for QUITs */
|
/* send always ACK for QUITs */
|
||||||
*temp=PKT_ACK;
|
*temp = PKT_ACK;
|
||||||
memmove(temp+1,mesg,5);
|
memmove(temp + 1, mesg, 5);
|
||||||
putmsg(&sender,temp,6);
|
putmsg(&sender, temp, 6);
|
||||||
break;
|
break;
|
||||||
case PKT_JOIN:
|
case PKT_JOIN:
|
||||||
if (i==MAXNETNODES && j==-1) { /* reject */
|
if (i == MAXNETNODES && j == -1) { /* reject */
|
||||||
send_reject(&sender, network_join_unique, REJECT_FULL);
|
send_reject(&sender, network_join_unique, REJECT_FULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(i==MAXNETNODES) i=j;
|
if (i == MAXNETNODES) i = j;
|
||||||
memmove(&netnodes[i].netname.sin_addr.s_addr,
|
memmove(&netnodes[i].netname.sin_addr.s_addr, &sender.sin_addr.s_addr, 4);
|
||||||
&sender.sin_addr.s_addr,4);
|
memmove(&netnodes[i].netname.sin_port, &sender.sin_port, 2);
|
||||||
memmove(&netnodes[i].netname.sin_port,
|
netnodes[i].netname.sin_family = AF_INET;
|
||||||
&sender.sin_port,2);
|
netnodes[i].used = 1;
|
||||||
netnodes[i].netname.sin_family=AF_INET;
|
memcpy(netnodes[i].name, mesg + 9, 16);
|
||||||
netnodes[i].used=1;
|
|
||||||
memcpy(netnodes[i].name,mesg+9,16);
|
|
||||||
netnodes[i].name[15] = '\0';
|
netnodes[i].name[15] = '\0';
|
||||||
|
|
||||||
send_accept(network_join_unique);
|
send_accept(network_join_unique);
|
||||||
@ -597,18 +575,20 @@ int handle_joins() {
|
|||||||
|
|
||||||
/* Client side */
|
/* Client side */
|
||||||
|
|
||||||
static int read_inform(unsigned char** pbuf, int *psize) {
|
static int read_inform(unsigned char** pbuf, int* psize) {
|
||||||
unsigned char *buf = *pbuf;
|
unsigned char* buf = *pbuf;
|
||||||
int size = *psize;
|
int size = *psize;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (size < 1) return 0;
|
if (size < 1) return 0;
|
||||||
myslot = *buf++; size--;
|
myslot = *buf++;
|
||||||
|
size--;
|
||||||
if (0xff == myslot) return 1;
|
if (0xff == myslot) return 1;
|
||||||
|
|
||||||
if (size < 1) return 0;
|
if (size < 1) return 0;
|
||||||
while (0xff != *buf) {
|
while (0xff != *buf) {
|
||||||
i = *buf++; size--;
|
i = *buf++;
|
||||||
|
size--;
|
||||||
if (size < 17 || i >= MAXNETNODES) return 0;
|
if (size < 17 || i >= MAXNETNODES) return 0;
|
||||||
netnodes[i].used = 1;
|
netnodes[i].used = 1;
|
||||||
memcpy(netnodes[i].name, buf, 16);
|
memcpy(netnodes[i].name, buf, 16);
|
||||||
@ -634,16 +614,16 @@ static void read_config(unsigned char* buf) {
|
|||||||
/* returns 0=ignore packet,1=we're rejected,2=INVITE/CONFIG,3=BEGIN */
|
/* returns 0=ignore packet,1=we're rejected,2=INVITE/CONFIG,3=BEGIN */
|
||||||
int scaninvite(int msec) {
|
int scaninvite(int msec) {
|
||||||
int size;
|
int size;
|
||||||
unsigned char *take;
|
unsigned char* take;
|
||||||
|
|
||||||
size = getmsg(msec);
|
size = getmsg(msec);
|
||||||
|
|
||||||
if (size < 6) return 0;
|
if (size < 6) return 0;
|
||||||
if (*mesg!=PKT_INVITE && *mesg!=PKT_BEGIN && *mesg!=PKT_CONFIG) return 0;
|
if (*mesg != PKT_INVITE && *mesg != PKT_BEGIN && *mesg != PKT_CONFIG) return 0;
|
||||||
if (!isvalidmsg_from_master()) return 0;
|
if (!isvalidmsg_from_master()) return 0;
|
||||||
if (!isvalidunique(mesg+1)) return 0;
|
if (!isvalidunique(mesg + 1)) return 0;
|
||||||
|
|
||||||
take = mesg+5;
|
take = mesg + 5;
|
||||||
size -= 5;
|
size -= 5;
|
||||||
|
|
||||||
switch (*mesg) {
|
switch (*mesg) {
|
||||||
@ -666,35 +646,35 @@ int scaninvite(int msec) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int send_join(struct sockaddr_in *netname, char playername[16]) {
|
int send_join(struct sockaddr_in* netname, char playername[16]) {
|
||||||
int size;
|
int size;
|
||||||
long now;
|
long now;
|
||||||
Uint32 join_unique = gtime();
|
Uint32 join_unique = gtime();
|
||||||
unsigned char *buf;
|
unsigned char* buf;
|
||||||
|
|
||||||
mastername = *netname;
|
mastername = *netname;
|
||||||
*regpacket=PKT_JOIN;
|
*regpacket = PKT_JOIN;
|
||||||
write_version(regpacket + 1);
|
write_version(regpacket + 1);
|
||||||
writeuint32(regpacket+5, join_unique);
|
writeuint32(regpacket + 5, join_unique);
|
||||||
memcpy(regpacket+9, playername, 16);
|
memcpy(regpacket + 9, playername, 16);
|
||||||
now=longtime();
|
now = longtime();
|
||||||
putmsg(&mastername,regpacket,1+4+4+16);
|
putmsg(&mastername, regpacket, 1 + 4 + 4 + 16);
|
||||||
while(longtime()-now < 3) {
|
while (longtime() - now < 3) {
|
||||||
if (0 == (size = getmsg(1000))) {
|
if (0 == (size = getmsg(1000))) {
|
||||||
/* got no message, send join again */
|
/* got no message, send join again */
|
||||||
putmsg(&mastername,regpacket,1+4+4+16);
|
putmsg(&mastername, regpacket, 1 + 4 + 4 + 16);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (size < 5) continue;
|
if (size < 5) continue;
|
||||||
if (readuint32(mesg+1) != join_unique) continue;
|
if (readuint32(mesg + 1) != join_unique) continue;
|
||||||
switch (*mesg) {
|
switch (*mesg) {
|
||||||
case PKT_ACCEPT:
|
case PKT_ACCEPT:
|
||||||
if (size < 1+4+132+4+2) continue;
|
if (size < 1 + 4 + 132 + 4 + 2) continue;
|
||||||
read_seed_unique(mesg + 5);
|
read_seed_unique(mesg + 5);
|
||||||
read_config(mesg+137);
|
read_config(mesg + 137);
|
||||||
buf = mesg+141;
|
buf = mesg + 141;
|
||||||
size -= 141;
|
size -= 141;
|
||||||
if (!read_inform(&buf,&size)) return 0;
|
if (!read_inform(&buf, &size)) return 0;
|
||||||
return 2;
|
return 2;
|
||||||
case PKT_REJECT:
|
case PKT_REJECT:
|
||||||
if (size < 10 || mesg[9] > _REJECT_LAST) {
|
if (size < 10 || mesg[9] > _REJECT_LAST) {
|
||||||
@ -716,14 +696,13 @@ void send_quit() {
|
|||||||
int size;
|
int size;
|
||||||
|
|
||||||
*regpacket = PKT_QUIT;
|
*regpacket = PKT_QUIT;
|
||||||
write_unique(regpacket+1);
|
write_unique(regpacket + 1);
|
||||||
now=longtime();
|
now = longtime();
|
||||||
while(longtime()-now<10) {
|
while (longtime() - now < 10) {
|
||||||
putmsg(&mastername,regpacket,5);
|
putmsg(&mastername, regpacket, 5);
|
||||||
size=getmsg(1000);
|
size = getmsg(1000);
|
||||||
if(size<6) continue;
|
if (size < 6) continue;
|
||||||
if(mesg[0] != PKT_ACK || mesg[1] != PKT_QUIT) continue;
|
if (mesg[0] != PKT_ACK || mesg[1] != PKT_QUIT) continue;
|
||||||
if (isvalidunique(mesg+2))
|
if (isvalidunique(mesg + 2)) break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
#ifndef NETWORK_H
|
#ifndef NETWORK_H
|
||||||
#define NETWORK_H
|
#define NETWORK_H
|
||||||
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
enum {
|
enum { MAXNETNODES = 8 };
|
||||||
MAXNETNODES = 8
|
|
||||||
};
|
|
||||||
|
|
||||||
struct netnode {
|
struct netnode {
|
||||||
struct sockaddr_in netname;
|
struct sockaddr_in netname;
|
||||||
@ -22,7 +20,7 @@ extern struct netnode netnodes[MAXNETNODES];
|
|||||||
void getsocket(void);
|
void getsocket(void);
|
||||||
void freesocket(void);
|
void freesocket(void);
|
||||||
|
|
||||||
int send_join(struct sockaddr_in *netname, char playername[16]);
|
int send_join(struct sockaddr_in* netname, char playername[16]);
|
||||||
void send_config();
|
void send_config();
|
||||||
void send_quit();
|
void send_quit();
|
||||||
int scaninvite(int msec);
|
int scaninvite(int msec);
|
||||||
@ -45,8 +43,8 @@ int networktraffic(void);
|
|||||||
|
|
||||||
extern int mydatacount;
|
extern int mydatacount;
|
||||||
extern int myslot;
|
extern int myslot;
|
||||||
extern int actionput,actioncount;
|
extern int actionput, actioncount;
|
||||||
extern unsigned char actionblock[ACTIONHIST*MAXNETNODES];
|
extern unsigned char actionblock[ACTIONHIST * MAXNETNODES];
|
||||||
|
|
||||||
extern int myaction;
|
extern int myaction;
|
||||||
extern unsigned char actions[MAXNETNODES];
|
extern unsigned char actions[MAXNETNODES];
|
||||||
|
202
src/sound.c
202
src/sound.c
@ -1,9 +1,9 @@
|
|||||||
#include <unistd.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <SDL_audio.h>
|
#include <SDL_audio.h>
|
||||||
#include <SDL_error.h>
|
#include <SDL_error.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
|
|
||||||
@ -13,16 +13,16 @@
|
|||||||
|
|
||||||
int sound_enabled = 1;
|
int sound_enabled = 1;
|
||||||
|
|
||||||
static char dirlist[]=DATADIR;
|
static char dirlist[] = DATADIR;
|
||||||
|
|
||||||
static int readsound(int num);
|
static int readsound(int num);
|
||||||
|
|
||||||
#define NUMSOUNDS ((int)(sizeof(soundnames)/sizeof(char*)))
|
#define NUMSOUNDS ((int) (sizeof(soundnames) / sizeof(char*)))
|
||||||
#define MIXMAX 16
|
#define MIXMAX 16
|
||||||
|
|
||||||
#define SOUND_QUIET -1
|
#define SOUND_QUIET -1
|
||||||
|
|
||||||
static const char *soundnames[] = {
|
static const char* soundnames[] = {
|
||||||
"bomb1.raw",
|
"bomb1.raw",
|
||||||
"power1.raw",
|
"power1.raw",
|
||||||
"death.raw",
|
"death.raw",
|
||||||
@ -31,9 +31,8 @@ static const char *soundnames[] = {
|
|||||||
"power2.raw",
|
"power2.raw",
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct sample
|
typedef struct sample {
|
||||||
{
|
char* data;
|
||||||
char *data;
|
|
||||||
int len;
|
int len;
|
||||||
} sample;
|
} sample;
|
||||||
|
|
||||||
@ -41,151 +40,140 @@ typedef struct sample
|
|||||||
|
|
||||||
static sample samples[NUMSOUNDS];
|
static sample samples[NUMSOUNDS];
|
||||||
|
|
||||||
static int soundworking=0;
|
static int soundworking = 0;
|
||||||
static int fragment;
|
static int fragment;
|
||||||
// static int soundwrite,soundread;
|
// static int soundwrite,soundread;
|
||||||
static int *soundbuffer;
|
static int* soundbuffer;
|
||||||
static int soundbufferlen;
|
static int soundbufferlen;
|
||||||
static unsigned char sndclip[8192];
|
static unsigned char sndclip[8192];
|
||||||
|
|
||||||
#define MAXSOUNDCOMMANDS 32
|
#define MAXSOUNDCOMMANDS 32
|
||||||
static char soundcommands[MAXSOUNDCOMMANDS];
|
static char soundcommands[MAXSOUNDCOMMANDS];
|
||||||
static int soundtake,soundput;
|
static int soundtake, soundput;
|
||||||
|
|
||||||
static int sndplaying[MIXMAX],sndposition[MIXMAX];
|
static int sndplaying[MIXMAX], sndposition[MIXMAX];
|
||||||
static void fillaudio(void *udata,Uint8 *buffer,int len)
|
static void fillaudio(void* udata, Uint8* buffer, int len) {
|
||||||
{
|
char com, *p;
|
||||||
char com,*p;
|
int i, j, *ip;
|
||||||
int i,j,*ip;
|
int which;
|
||||||
int which;
|
(void) udata;
|
||||||
(void)udata;
|
|
||||||
|
|
||||||
while(soundtake!=soundput)
|
while (soundtake != soundput) {
|
||||||
{
|
com = soundcommands[soundtake];
|
||||||
com=soundcommands[soundtake];
|
soundtake = (soundtake + 1) & (MAXSOUNDCOMMANDS - 1);
|
||||||
soundtake=(soundtake+1)&(MAXSOUNDCOMMANDS-1);
|
if (com == SOUND_QUIET) {
|
||||||
if(com==SOUND_QUIET) {memset(sndposition,0,sizeof(sndposition));continue;}
|
memset(sndposition, 0, sizeof(sndposition));
|
||||||
if(com<NUMSOUNDS)
|
continue;
|
||||||
{
|
}
|
||||||
for(i=0;i<MIXMAX;++i)
|
if (com < NUMSOUNDS) {
|
||||||
if(!sndposition[i])
|
for (i = 0; i < MIXMAX; ++i)
|
||||||
{
|
if (!sndposition[i]) {
|
||||||
sndposition[i]=1;
|
sndposition[i] = 1;
|
||||||
sndplaying[i]=com;
|
sndplaying[i] = com;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
memset(soundbuffer,0,soundbufferlen);
|
memset(soundbuffer, 0, soundbufferlen);
|
||||||
for(i=0;i<MIXMAX;++i)
|
for (i = 0; i < MIXMAX; ++i) {
|
||||||
{
|
if (!sndposition[i]) continue;
|
||||||
if(!sndposition[i]) continue;
|
which = sndplaying[i];
|
||||||
which=sndplaying[i];
|
if (sndposition[i] == samples[which].len) {
|
||||||
if(sndposition[i]==samples[which].len)
|
sndposition[i] = 0;
|
||||||
{
|
|
||||||
sndposition[i]=0;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
p=samples[which].data;
|
p = samples[which].data;
|
||||||
if(!p) continue;
|
if (!p) continue;
|
||||||
p+=len*(sndposition[i]++ -1);
|
p += len * (sndposition[i]++ - 1);
|
||||||
ip=soundbuffer;
|
ip = soundbuffer;
|
||||||
j=len;
|
j = len;
|
||||||
while(j--) *ip++ += *p++;
|
while (j--) *ip++ += *p++;
|
||||||
}
|
}
|
||||||
j=len;
|
j = len;
|
||||||
ip=soundbuffer;;
|
ip = soundbuffer;
|
||||||
while(j--) *buffer++ = sndclip[4096+*ip++];
|
;
|
||||||
|
while (j--) *buffer++ = sndclip[4096 + *ip++];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int soundopen(void) {
|
int soundopen(void) {
|
||||||
SDL_AudioSpec wanted;
|
SDL_AudioSpec wanted;
|
||||||
int i,j;
|
int i, j;
|
||||||
|
|
||||||
soundtake=soundput=0;
|
soundtake = soundput = 0;
|
||||||
memset(sndposition,0,sizeof(sndposition));
|
memset(sndposition, 0, sizeof(sndposition));
|
||||||
memset(sndplaying,0,sizeof(sndplaying));
|
memset(sndplaying, 0, sizeof(sndplaying));
|
||||||
fragment=SNDFRAGMENT<<1;
|
fragment = SNDFRAGMENT << 1;
|
||||||
soundbufferlen=fragment*sizeof(int);
|
soundbufferlen = fragment * sizeof(int);
|
||||||
soundbuffer=malloc(soundbufferlen);
|
soundbuffer = malloc(soundbufferlen);
|
||||||
if(!soundbuffer) return -2;
|
if (!soundbuffer) return -2;
|
||||||
|
|
||||||
memset(&wanted,0,sizeof(wanted));
|
memset(&wanted, 0, sizeof(wanted));
|
||||||
wanted.freq=22050;
|
wanted.freq = 22050;
|
||||||
wanted.channels=2;
|
wanted.channels = 2;
|
||||||
wanted.format=AUDIO_U8;
|
wanted.format = AUDIO_U8;
|
||||||
wanted.samples=fragment>>1;
|
wanted.samples = fragment >> 1;
|
||||||
wanted.callback=fillaudio;
|
wanted.callback = fillaudio;
|
||||||
wanted.userdata=0;
|
wanted.userdata = 0;
|
||||||
|
|
||||||
if(SDL_OpenAudio(&wanted,0)<0)
|
if (SDL_OpenAudio(&wanted, 0) < 0) {
|
||||||
{
|
fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
|
||||||
fprintf(stderr,"Couldn't open audio: %s\n",SDL_GetError());
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
soundworking=1;
|
soundworking = 1;
|
||||||
|
|
||||||
for(i=0;i<8192;i++)
|
for (i = 0; i < 8192; i++) {
|
||||||
{
|
j = i - 4096;
|
||||||
j=i-4096;
|
sndclip[i] = j > 127 ? 255 : (j < -128 ? 0 : j + 128);
|
||||||
sndclip[i]=j > 127 ? 255 : (j<-128 ? 0 : j+128);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i=0;i<NUMSOUNDS;++i)
|
for (i = 0; i < NUMSOUNDS; ++i) readsound(i);
|
||||||
readsound(i);
|
|
||||||
|
|
||||||
SDL_PauseAudio(0);
|
SDL_PauseAudio(0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
void soundclose(void) {
|
void soundclose(void) {
|
||||||
if(soundworking)
|
if (soundworking) {
|
||||||
{
|
|
||||||
SDL_CloseAudio();
|
SDL_CloseAudio();
|
||||||
soundworking=0;
|
soundworking = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int readsound(int num) {
|
int readsound(int num) {
|
||||||
char name[256],*p1,*p2,ch;
|
char name[256], *p1, *p2, ch;
|
||||||
int file,size,len;
|
int file, size, len;
|
||||||
p1=dirlist;
|
p1 = dirlist;
|
||||||
for(;;)
|
for (;;) {
|
||||||
{
|
p2 = name;
|
||||||
p2=name;
|
while (*p1 && (ch = *p1++) != ',') *p2++ = ch;
|
||||||
while(*p1 && (ch=*p1++)!=',')
|
if (p2 > name && p2[-1] != '/') *p2++ = '/';
|
||||||
*p2++=ch;
|
strcpy(p2, soundnames[num]);
|
||||||
if(p2>name && p2[-1]!='/') *p2++='/';
|
file = open(name, O_RDONLY);
|
||||||
strcpy(p2,soundnames[num]);
|
if (file >= 0) break;
|
||||||
file=open(name,O_RDONLY);
|
if (!*p1) {
|
||||||
if(file>=0) break;
|
samples[num].len = -1;
|
||||||
if(!*p1)
|
|
||||||
{
|
|
||||||
samples[num].len=-1;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
size=lseek(file,0,SEEK_END);
|
size = lseek(file, 0, SEEK_END);
|
||||||
lseek(file,0,SEEK_SET);
|
lseek(file, 0, SEEK_SET);
|
||||||
len=samples[num].len=(size+fragment-1)/fragment;
|
len = samples[num].len = (size + fragment - 1) / fragment;
|
||||||
len*=fragment;
|
len *= fragment;
|
||||||
p1=samples[num].data=malloc(len);
|
p1 = samples[num].data = malloc(len);
|
||||||
if(p1)
|
if (p1) {
|
||||||
{
|
read(file, p1, size);
|
||||||
read(file,p1,size);
|
if (len - size) memset(p1 + size, 0, len - size);
|
||||||
if(len-size) memset(p1+size,0,len-size);
|
while (size--) *p1++ ^= 0x80;
|
||||||
while(size--) *p1++ ^= 0x80;
|
|
||||||
} else
|
} else
|
||||||
samples[num].data=0;
|
samples[num].data = 0;
|
||||||
close(file);
|
close(file);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void playsound(int n) {
|
void playsound(int n) {
|
||||||
if (sound_enabled) {
|
if (sound_enabled) {
|
||||||
soundcommands[soundput]=n;
|
soundcommands[soundput] = n;
|
||||||
soundput=(soundput+1)&(MAXSOUNDCOMMANDS-1);
|
soundput = (soundput + 1) & (MAXSOUNDCOMMANDS - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
73
src/utils.c
73
src/utils.c
@ -1,17 +1,17 @@
|
|||||||
|
|
||||||
#include "bomber.h"
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include "bomber.h"
|
||||||
#include "gfx.h"
|
#include "gfx.h"
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
int volatile hc=0;
|
int volatile hc = 0;
|
||||||
char volatile interrupted=0;
|
char volatile interrupted = 0;
|
||||||
static Uint32 cur_unique;
|
static Uint32 cur_unique;
|
||||||
Uint32 network_unique;
|
Uint32 network_unique;
|
||||||
|
|
||||||
@ -20,12 +20,12 @@ Uint32 gtime(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Uint32 longtime(void) {
|
Uint32 longtime(void) {
|
||||||
return gtime()/1000;
|
return gtime() / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* surf random generator: x (Daniel J. Bernstein) */
|
/* surf random generator: x (Daniel J. Bernstein) */
|
||||||
#define ROT(x, b) (((x) << (b)) | ((x) >> (32-(b))))
|
#define ROT(x, b) (((x) << (b)) | ((x) >> (32 - (b))))
|
||||||
#define MUSH(i, b) x = t[i] += (((x ^ seed[i]) + sum) ^ ROT(x,b))
|
#define MUSH(i, b) x = t[i] += (((x ^ seed[i]) + sum) ^ ROT(x, b))
|
||||||
static void surf(Uint32 out[8], const Uint32 in[12], const Uint32 seed[32]) {
|
static void surf(Uint32 out[8], const Uint32 in[12], const Uint32 seed[32]) {
|
||||||
Uint32 t[12], x, sum = 0;
|
Uint32 t[12], x, sum = 0;
|
||||||
int r, i, loop;
|
int r, i, loop;
|
||||||
@ -35,11 +35,20 @@ static void surf(Uint32 out[8], const Uint32 in[12], const Uint32 seed[32]) {
|
|||||||
for (loop = 0; loop < 2; ++loop) {
|
for (loop = 0; loop < 2; ++loop) {
|
||||||
for (r = 0; r < 16; ++r) {
|
for (r = 0; r < 16; ++r) {
|
||||||
sum += 0x9e3779b9;
|
sum += 0x9e3779b9;
|
||||||
MUSH(0, 5); MUSH(1, 7); MUSH(2, 9); MUSH(3, 13);
|
MUSH(0, 5);
|
||||||
MUSH(4, 5); MUSH(5, 7); MUSH(6, 9); MUSH(7, 13);
|
MUSH(1, 7);
|
||||||
MUSH(8, 5); MUSH(9, 7); MUSH(10, 9); MUSH(11, 13);
|
MUSH(2, 9);
|
||||||
|
MUSH(3, 13);
|
||||||
|
MUSH(4, 5);
|
||||||
|
MUSH(5, 7);
|
||||||
|
MUSH(6, 9);
|
||||||
|
MUSH(7, 13);
|
||||||
|
MUSH(8, 5);
|
||||||
|
MUSH(9, 7);
|
||||||
|
MUSH(10, 9);
|
||||||
|
MUSH(11, 13);
|
||||||
}
|
}
|
||||||
for (i = 0; i < 8; ++i) out[i] ^= t[i+4];
|
for (i = 0; i < 8; ++i) out[i] ^= t[i + 4];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#undef ROT
|
#undef ROT
|
||||||
@ -62,10 +71,14 @@ static Uint32 surf_init(void) {
|
|||||||
if (-1 == fd) {
|
if (-1 == fd) {
|
||||||
Uint32 genseed[4][8];
|
Uint32 genseed[4][8];
|
||||||
surf_seed[0] = surf_seed[1] = gtime();
|
surf_seed[0] = surf_seed[1] = gtime();
|
||||||
surf_in[0]++; surf(genseed[0], surf_in, surf_seed);
|
surf_in[0]++;
|
||||||
surf_in[0]++; surf(genseed[1], surf_in, surf_seed);
|
surf(genseed[0], surf_in, surf_seed);
|
||||||
surf_in[0]++; surf(genseed[2], surf_in, surf_seed);
|
surf_in[0]++;
|
||||||
surf_in[0]++; surf(genseed[3], surf_in, surf_seed);
|
surf(genseed[1], surf_in, surf_seed);
|
||||||
|
surf_in[0]++;
|
||||||
|
surf(genseed[2], surf_in, surf_seed);
|
||||||
|
surf_in[0]++;
|
||||||
|
surf(genseed[3], surf_in, surf_seed);
|
||||||
memcpy(surf_seed, genseed[0], 32);
|
memcpy(surf_seed, genseed[0], 32);
|
||||||
memcpy(surf_seed, genseed[1], 32);
|
memcpy(surf_seed, genseed[1], 32);
|
||||||
memcpy(surf_seed, genseed[2], 32);
|
memcpy(surf_seed, genseed[2], 32);
|
||||||
@ -86,14 +99,15 @@ static Uint32 surf_init(void) {
|
|||||||
static Uint32 surf_random(void) {
|
static Uint32 surf_random(void) {
|
||||||
if (surf_left == 0) {
|
if (surf_left == 0) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; (i < 12) && !(++surf_in[i]); i++) ;
|
for (i = 0; (i < 12) && !(++surf_in[i]); i++)
|
||||||
|
;
|
||||||
surf_left = 8;
|
surf_left = 8;
|
||||||
surf(surf_out, surf_in, surf_seed);
|
surf(surf_out, surf_in, surf_seed);
|
||||||
}
|
}
|
||||||
return surf_out[--surf_left];
|
return surf_out[--surf_left];
|
||||||
}
|
}
|
||||||
|
|
||||||
void read_seed_unique(unsigned char *buf) {
|
void read_seed_unique(unsigned char* buf) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
memset(surf_in, 0, sizeof(surf_in));
|
memset(surf_in, 0, sizeof(surf_in));
|
||||||
@ -101,12 +115,12 @@ void read_seed_unique(unsigned char *buf) {
|
|||||||
surf_left = 0;
|
surf_left = 0;
|
||||||
|
|
||||||
memcpy(&surf_seed, buf, sizeof(surf_seed));
|
memcpy(&surf_seed, buf, sizeof(surf_seed));
|
||||||
memcpy(&network_unique, buf+sizeof(surf_seed), sizeof(network_unique));
|
memcpy(&network_unique, buf + sizeof(surf_seed), sizeof(network_unique));
|
||||||
cur_unique = ntohl(network_unique);
|
cur_unique = ntohl(network_unique);
|
||||||
for (i = 0; i < 32; i++) surf_seed[i] = ntohl(surf_seed[i]);
|
for (i = 0; i < 32; i++) surf_seed[i] = ntohl(surf_seed[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char* write_seed_unique(unsigned char *buf) {
|
unsigned char* write_seed_unique(unsigned char* buf) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < 32; i++) {
|
for (i = 0; i < 32; i++) {
|
||||||
@ -200,34 +214,34 @@ Uint32 get_unique(void) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void nomem(char *str) {
|
void nomem(char* str) {
|
||||||
printf("No memory!!![%s]\n",str);
|
printf("No memory!!![%s]\n", str);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int mypause(void) {
|
int mypause(void) {
|
||||||
while(!interrupted) {
|
while (!interrupted) {
|
||||||
pollinput();
|
pollinput();
|
||||||
SDL_Delay(1);
|
SDL_Delay(1);
|
||||||
}
|
}
|
||||||
interrupted=0;
|
interrupted = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint32 sdlhandler(Uint32 time) {
|
static Uint32 sdlhandler(Uint32 time) {
|
||||||
#if defined (SDL_LATENCY)
|
#if defined(SDL_LATENCY)
|
||||||
outmsgs();
|
outmsgs();
|
||||||
#endif
|
#endif
|
||||||
interrupted=1;
|
interrupted = 1;
|
||||||
hc++;
|
hc++;
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pulseon(void) {
|
void pulseon(void) {
|
||||||
SDL_SetTimer(40,sdlhandler);
|
SDL_SetTimer(40, sdlhandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hexdump(unsigned char *p, int len) {
|
void hexdump(unsigned char* p, int len) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
if (15 == len % 16)
|
if (15 == len % 16)
|
||||||
@ -235,6 +249,5 @@ void hexdump(unsigned char *p, int len) {
|
|||||||
else
|
else
|
||||||
fprintf(stderr, "0x%X ", p[i]);
|
fprintf(stderr, "0x%X ", p[i]);
|
||||||
}
|
}
|
||||||
if (i % 16)
|
if (i % 16) fprintf(stderr, "\n");
|
||||||
fprintf(stderr, "\n");
|
|
||||||
}
|
}
|
||||||
|
12
src/utils.h
12
src/utils.h
@ -1,6 +1,8 @@
|
|||||||
#ifndef UTILS_H
|
#ifndef UTILS_H
|
||||||
#define UTILS_H
|
#define UTILS_H
|
||||||
|
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
Uint32 gtime(void);
|
Uint32 gtime(void);
|
||||||
Uint32 longtime(void);
|
Uint32 longtime(void);
|
||||||
|
|
||||||
@ -10,21 +12,21 @@ void set_unique(Uint32 unique);
|
|||||||
Uint32 get_unique(void);
|
Uint32 get_unique(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SEED_UNIQUE_SIZE (32*4+4)
|
#define SEED_UNIQUE_SIZE (32 * 4 + 4)
|
||||||
void read_seed_unique(unsigned char *buf);
|
void read_seed_unique(unsigned char* buf);
|
||||||
unsigned char* write_seed_unique(unsigned char *buf);
|
unsigned char* write_seed_unique(unsigned char* buf);
|
||||||
void create_seed_unique(void);
|
void create_seed_unique(void);
|
||||||
|
|
||||||
extern Uint32 network_unique;
|
extern Uint32 network_unique;
|
||||||
|
|
||||||
int myrand(void);
|
int myrand(void);
|
||||||
|
|
||||||
void nomem(char *str);
|
void nomem(char* str);
|
||||||
|
|
||||||
int mypause(void);
|
int mypause(void);
|
||||||
void pulseon(void);
|
void pulseon(void);
|
||||||
|
|
||||||
void hexdump(unsigned char *p, int len);
|
void hexdump(unsigned char* p, int len);
|
||||||
|
|
||||||
extern volatile int hc;
|
extern volatile int hc;
|
||||||
extern volatile char interrupted;
|
extern volatile char interrupted;
|
||||||
|
Loading…
Reference in New Issue
Block a user