Use avahi for network, share config over network, use unique for shared random
This commit is contained in:
parent
d1fe907235
commit
0c61d8a25a
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
*.o
|
||||||
|
bomber
|
||||||
|
matcher
|
3
AUTHORS
3
AUTHORS
@ -2,3 +2,6 @@ David Ashley
|
|||||||
dashxdr@gmail.com
|
dashxdr@gmail.com
|
||||||
http://www.xdr.com/dash
|
http://www.xdr.com/dash
|
||||||
http://www.linuxmotors.com
|
http://www.linuxmotors.com
|
||||||
|
|
||||||
|
Stefan Bühler
|
||||||
|
http://stbuehler.de/
|
||||||
|
36
Makefile
36
Makefile
@ -1,37 +1,23 @@
|
|||||||
#DBG = -g
|
#DBG = -g
|
||||||
CC = gcc
|
CC = gcc
|
||||||
CFLAGS = -O2 -Wall $(shell sdl-config --cflags) $(DBG)
|
WARNFLAGS = -Wall -Wmissing-declarations -Wdeclaration-after-statement -Wcast-align -Winline -Wsign-compare -Wnested-externs -Wpointer-arith -Wformat-security
|
||||||
|
CFLAGS = -g -D_REENTRANT -O2 -Wall $(shell sdl-config --cflags) $(DBG) $(WARNFLAGS)
|
||||||
|
|
||||||
all: bomber matcher
|
.PHONY: all clean
|
||||||
|
all: bomber
|
||||||
|
|
||||||
bomber: bomber.o gfx.o sound.o matcher
|
bomber: bomber.o gfx.o sound.o announce.o matcher
|
||||||
gcc -o bomber bomber.o gfx.o sound.o $(shell sdl-config --libs) $(DBG)
|
gcc -o bomber bomber.o gfx.o sound.o announce.o $(shell sdl-config --libs) -lavahi-common -lavahi-client $(DBG)
|
||||||
|
|
||||||
matcher: matcher.c
|
matcher: matcher.c
|
||||||
|
|
||||||
bomber.o: bomber.c bomber.h gfx.h
|
bomber.o: bomber.c bomber.h gfx.h announce.h
|
||||||
|
|
||||||
gfx.o: gfx.c gfx.h bomber.h
|
gfx.o: gfx.c gfx.h bomber.h
|
||||||
|
|
||||||
sound.o: sound.c
|
sound.o: sound.c
|
||||||
|
|
||||||
|
announce.o: announce.c announce.h
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o matcher bomber
|
rm -f *.o matcher bomber
|
||||||
|
|
||||||
test: all
|
|
||||||
./bomber
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
WORK = /ram
|
|
||||||
VER = 1.0.3
|
|
||||||
DDIR = SDL_bomber-$(VER)
|
|
||||||
|
|
||||||
package: clean
|
|
||||||
rm -rf $(WORK)/$(DDIR)
|
|
||||||
mkdir $(WORK)/$(DDIR)
|
|
||||||
cp *.c *.h Makefile* README INSTALL COPYING AUTHORS TODO $(WORK)/$(DDIR)
|
|
||||||
cp -a data $(WORK)/$(DDIR)
|
|
||||||
cp ChangeLog $(WORK)/$(DDIR)
|
|
||||||
cd $(WORK) && tar czf $(DDIR).tgz $(DDIR)
|
|
||||||
|
408
announce.c
Normal file
408
announce.c
Normal file
@ -0,0 +1,408 @@
|
|||||||
|
|
||||||
|
#include "announce.h"
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <avahi-client/client.h>
|
||||||
|
#include <avahi-client/lookup.h>
|
||||||
|
#include <avahi-client/publish.h>
|
||||||
|
|
||||||
|
#include <avahi-common/alternative.h>
|
||||||
|
#include <avahi-common/error.h>
|
||||||
|
#include <avahi-common/malloc.h>
|
||||||
|
#include <avahi-common/thread-watch.h>
|
||||||
|
|
||||||
|
#define SERVICE_TYPE "_sdlbomber._udp"
|
||||||
|
|
||||||
|
static AvahiClient *client = NULL;
|
||||||
|
static AvahiThreadedPoll *threaded_poll = NULL;
|
||||||
|
static AvahiEntryGroup *group = NULL;
|
||||||
|
|
||||||
|
static char* name = NULL;
|
||||||
|
|
||||||
|
static uint16_t port = 0;
|
||||||
|
static uint32_t unique = 0, version = 0;
|
||||||
|
|
||||||
|
static volatile int all_for_now;
|
||||||
|
|
||||||
|
gamelistentry gamelistentries[10];
|
||||||
|
int gamelistsize = 0;
|
||||||
|
|
||||||
|
static void myerror(AvahiClient *c, const char *s) {
|
||||||
|
fprintf(stderr, "Error in: %s\n (%s)", s, avahi_strerror(avahi_client_errno(client)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void create_services(AvahiClient *c);
|
||||||
|
|
||||||
|
static void entry_group_callback(AvahiEntryGroup *g, AvahiEntryGroupState state, AVAHI_GCC_UNUSED void *userdata) {
|
||||||
|
group = g;
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case AVAHI_ENTRY_GROUP_ESTABLISHED :
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AVAHI_ENTRY_GROUP_COLLISION :
|
||||||
|
{
|
||||||
|
char *n = avahi_alternative_service_name(name);
|
||||||
|
avahi_free(name);
|
||||||
|
name = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* And recreate the services */
|
||||||
|
avahi_entry_group_reset(group);
|
||||||
|
create_services(avahi_entry_group_get_client(g));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AVAHI_ENTRY_GROUP_FAILURE :
|
||||||
|
fprintf(stderr, "Entry group failure: %s\n", avahi_strerror(avahi_client_errno(avahi_entry_group_get_client(g))));
|
||||||
|
|
||||||
|
avahi_threaded_poll_quit(threaded_poll);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AVAHI_ENTRY_GROUP_UNCOMMITED:
|
||||||
|
case AVAHI_ENTRY_GROUP_REGISTERING:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void create_services(AvahiClient *c) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!group) {
|
||||||
|
if (!(group = avahi_entry_group_new(c, entry_group_callback, NULL))) {
|
||||||
|
myerror(c, "avahi_entry_group_new");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
again:
|
||||||
|
if (avahi_entry_group_is_empty(group)) {
|
||||||
|
char buf_unique[128], buf_version[128];
|
||||||
|
snprintf(buf_unique, sizeof(buf_unique), "unique=%X", (unsigned int) unique);
|
||||||
|
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_unique, buf_version, NULL)) < 0) {
|
||||||
|
|
||||||
|
if (ret == AVAHI_ERR_COLLISION)
|
||||||
|
goto collision;
|
||||||
|
|
||||||
|
fprintf(stderr, "Failed to add "SERVICE_TYPE": %s\n", avahi_strerror(ret));
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ret = avahi_entry_group_commit(group)) < 0) {
|
||||||
|
fprintf(stderr, "Failed to commit entry group: %s\n", avahi_strerror(ret));
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
collision:
|
||||||
|
{
|
||||||
|
char *n = avahi_alternative_service_name(name);
|
||||||
|
avahi_free(name);
|
||||||
|
name = n;
|
||||||
|
}
|
||||||
|
avahi_entry_group_reset(group);
|
||||||
|
goto again;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
avahi_threaded_poll_quit(threaded_poll);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void client_callback(AvahiClient *c, AvahiClientState state, void * userdata) {
|
||||||
|
client = c;
|
||||||
|
switch (state) {
|
||||||
|
case AVAHI_CLIENT_S_RUNNING:
|
||||||
|
if (port != 0) create_services(c);
|
||||||
|
break;
|
||||||
|
case AVAHI_CLIENT_FAILURE:
|
||||||
|
myerror(c, "client failure");
|
||||||
|
avahi_threaded_poll_quit(threaded_poll);
|
||||||
|
break;
|
||||||
|
case AVAHI_CLIENT_S_COLLISION:
|
||||||
|
case AVAHI_CLIENT_S_REGISTERING:
|
||||||
|
if (group) {
|
||||||
|
avahi_entry_group_reset(group);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case AVAHI_CLIENT_CONNECTING:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int registergame(char *playername, uint16_t p, uint32_t uniq, unsigned char v[4]) {
|
||||||
|
if (name) avahi_free(name);
|
||||||
|
name = avahi_strdup(playername);
|
||||||
|
|
||||||
|
port = p;
|
||||||
|
unique = htonl(uniq);
|
||||||
|
memcpy(&version, v, 4);
|
||||||
|
version = htonl(version);
|
||||||
|
|
||||||
|
avahi_threaded_poll_lock(threaded_poll);
|
||||||
|
create_services(client);
|
||||||
|
avahi_threaded_poll_unlock(threaded_poll);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void unregistergame() {
|
||||||
|
port = 0;
|
||||||
|
|
||||||
|
avahi_threaded_poll_lock(threaded_poll);
|
||||||
|
if (group) avahi_entry_group_reset(group);
|
||||||
|
group = NULL;
|
||||||
|
avahi_threaded_poll_unlock(threaded_poll);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void resolve_callback(AvahiServiceResolver *r, 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;
|
||||||
|
uint32_t want_version = *(uint32_t*) userdata;
|
||||||
|
assert(r);
|
||||||
|
|
||||||
|
if (protocol != AVAHI_PROTO_INET) goto done; /* ignore non IPv4 for now */
|
||||||
|
if (gamelistsize >= GAMELIST_MAXSIZE) goto done;
|
||||||
|
|
||||||
|
/* Called whenever a service has been resolved successfully or timed out */
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
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))));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AVAHI_RESOLVER_FOUND: {
|
||||||
|
gamelistentry *ge;
|
||||||
|
unsigned int uniq, version;
|
||||||
|
int have_unique = 0, have_version = 0;
|
||||||
|
AvahiStringList *psl;
|
||||||
|
for (psl = txt ; psl ; psl = psl->next) {
|
||||||
|
if (0 == strncmp("unique=", (const char*) psl->text, 7)) {
|
||||||
|
sscanf((const char*) psl->text, "unique=%X", &uniq);
|
||||||
|
have_unique = 1;
|
||||||
|
} else if (0 == strncmp("version=", (const char*) psl->text, 8)) {
|
||||||
|
sscanf((const char*) psl->text, "version=%X", &version);
|
||||||
|
if (version != want_version) goto done; /* version mismatch */
|
||||||
|
have_version = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!have_unique || !have_version) goto done;
|
||||||
|
i = gamelistsize++;
|
||||||
|
ge = &gamelistentries[i];
|
||||||
|
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;
|
||||||
|
ge->name = avahi_strdup(name);
|
||||||
|
ge->unique = ntohl(uniq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
avahi_service_resolver_free(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void browse_callback(AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event,
|
||||||
|
const char *name, const char *type, const char *domain, AvahiLookupResultFlags flags, void* userdata) {
|
||||||
|
|
||||||
|
assert(b);
|
||||||
|
|
||||||
|
/* Called whenever a new services becomes available on the LAN or is removed from the LAN */
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case AVAHI_BROWSER_FAILURE:
|
||||||
|
|
||||||
|
fprintf(stderr, "(Browser) %s\n", avahi_strerror(avahi_client_errno(client)));
|
||||||
|
avahi_threaded_poll_quit(threaded_poll);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case AVAHI_BROWSER_NEW:
|
||||||
|
/* 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
|
||||||
|
function we free it. If the server is terminated before
|
||||||
|
the callback function is called the server will free
|
||||||
|
the resolver for us. */
|
||||||
|
|
||||||
|
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)));
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AVAHI_BROWSER_REMOVE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AVAHI_BROWSER_ALL_FOR_NOW:
|
||||||
|
all_for_now = 1;
|
||||||
|
break;
|
||||||
|
case AVAHI_BROWSER_CACHE_EXHAUSTED:
|
||||||
|
all_for_now = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void freefoundgames() {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < gamelistsize; i++) {
|
||||||
|
avahi_free(gamelistentries[i].name);
|
||||||
|
}
|
||||||
|
gamelistsize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int searchgames(unsigned char version[4]) {
|
||||||
|
int i;
|
||||||
|
AvahiServiceBrowser *sb = NULL;
|
||||||
|
uint32_t gameversion;
|
||||||
|
memcpy(&gameversion, version, 4);
|
||||||
|
gameversion = htonl(gameversion);
|
||||||
|
|
||||||
|
freefoundgames();
|
||||||
|
|
||||||
|
avahi_threaded_poll_lock(threaded_poll);
|
||||||
|
|
||||||
|
all_for_now = 0;
|
||||||
|
|
||||||
|
if (NULL == (sb = avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, SERVICE_TYPE, NULL, 0, browse_callback, &gameversion))) {
|
||||||
|
fprintf(stderr, "Failed to create service browser: %s\n", avahi_strerror(avahi_client_errno(client)));
|
||||||
|
avahi_threaded_poll_unlock(threaded_poll);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
avahi_threaded_poll_unlock(threaded_poll);
|
||||||
|
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
usleep(200000);
|
||||||
|
|
||||||
|
avahi_threaded_poll_lock(threaded_poll);
|
||||||
|
|
||||||
|
if (all_for_now) {
|
||||||
|
avahi_service_browser_free(sb);
|
||||||
|
avahi_threaded_poll_unlock(threaded_poll);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
avahi_threaded_poll_unlock(threaded_poll);
|
||||||
|
}
|
||||||
|
|
||||||
|
avahi_threaded_poll_lock(threaded_poll);
|
||||||
|
avahi_service_browser_free(sb);
|
||||||
|
avahi_threaded_poll_unlock(threaded_poll);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int initannouncer() {
|
||||||
|
if (!(threaded_poll = avahi_threaded_poll_new())) {
|
||||||
|
fprintf(stderr, "avahi_threaded_poll_new failed\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(client = avahi_client_new(avahi_threaded_poll_get(threaded_poll), 0, client_callback, NULL, NULL))) {
|
||||||
|
fprintf(stderr, "avahi_client_new failed\n");
|
||||||
|
avahi_threaded_poll_free(threaded_poll);
|
||||||
|
threaded_poll = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (avahi_threaded_poll_start(threaded_poll) < 0) {
|
||||||
|
fprintf(stderr, "avahi_threaded_poll_start failed\n");
|
||||||
|
avahi_client_free(client);
|
||||||
|
avahi_threaded_poll_free(threaded_poll);
|
||||||
|
client = NULL;
|
||||||
|
threaded_poll = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeannouncer() {
|
||||||
|
freefoundgames();
|
||||||
|
|
||||||
|
avahi_threaded_poll_stop(threaded_poll);
|
||||||
|
if (client) avahi_client_free(client);
|
||||||
|
if (threaded_poll) avahi_threaded_poll_free(threaded_poll);
|
||||||
|
client = NULL;
|
||||||
|
threaded_poll = NULL;
|
||||||
|
|
||||||
|
avahi_free(name);
|
||||||
|
name = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
int openmatcher()
|
||||||
|
{
|
||||||
|
struct hostent *hostptr;
|
||||||
|
if(matcheropened) return 1;
|
||||||
|
hostptr=gethostbyname(mname);
|
||||||
|
if(!hostptr)
|
||||||
|
{
|
||||||
|
hostptr=gethostbyaddr(mname,strlen(mname),AF_INET);
|
||||||
|
if(!hostptr)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memset(&matchername,0,sizeof(matchername));
|
||||||
|
matchername.sin_family=AF_INET;
|
||||||
|
matchername.sin_port=htons(PORT);
|
||||||
|
memcpy(&matchername.sin_addr,hostptr->h_addr,hostptr->h_length);
|
||||||
|
matcheropened=1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int registergame()
|
||||||
|
{
|
||||||
|
long now;
|
||||||
|
int size;
|
||||||
|
long lastreg;
|
||||||
|
|
||||||
|
if(!openmatcher()) return 0;
|
||||||
|
pulseoff();
|
||||||
|
now=longtime();
|
||||||
|
lastreg=now-1;
|
||||||
|
while(longtime()-now<10)
|
||||||
|
{
|
||||||
|
if(longtime()-lastreg>=1)
|
||||||
|
{
|
||||||
|
lastreg=longtime();
|
||||||
|
putmsg(&matchername,regpacket,REGISTERLEN);
|
||||||
|
}
|
||||||
|
size=getmsg(1000);
|
||||||
|
if(size<REGISTERLEN+1) continue;
|
||||||
|
if(mesg[0]!=PKT_ACK) continue;
|
||||||
|
if(memcmp(regpacket,mesg+1,REGISTERLEN)) continue;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int unregistergame()
|
||||||
|
{
|
||||||
|
long now;
|
||||||
|
int size;
|
||||||
|
|
||||||
|
|
||||||
|
if(!openmatcher()) return 0;
|
||||||
|
pulseoff();
|
||||||
|
now=longtime();
|
||||||
|
clearreg();
|
||||||
|
while(longtime()-now<10)
|
||||||
|
{
|
||||||
|
putmsg(&matchername,regpacket,REGISTERLEN);
|
||||||
|
size=getmsg(1000);
|
||||||
|
if(size<REGISTERLEN+1) continue;
|
||||||
|
if(mesg[0]!=PKT_ACK) continue;
|
||||||
|
if(memcmp(regpacket,mesg+1,REGISTERLEN)) continue;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
25
announce.h
Normal file
25
announce.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef ANNOUNCE_H
|
||||||
|
#define ANNOUNCE_H
|
||||||
|
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
typedef struct gamelistentry gamelistentry;
|
||||||
|
struct gamelistentry {
|
||||||
|
struct sockaddr_in netname;
|
||||||
|
char *name;
|
||||||
|
uint32_t unique;
|
||||||
|
};
|
||||||
|
|
||||||
|
int registergame(char *playername, uint16_t port, uint32_t unique, unsigned char version[4]);
|
||||||
|
void unregistergame();
|
||||||
|
int searchgames(unsigned char version[4]);
|
||||||
|
|
||||||
|
int initannouncer();
|
||||||
|
void freeannouncer();
|
||||||
|
|
||||||
|
#define GAMELIST_MAXSIZE 10
|
||||||
|
|
||||||
|
extern gamelistentry gamelistentries[GAMELIST_MAXSIZE];
|
||||||
|
extern int gamelistsize;
|
||||||
|
|
||||||
|
#endif
|
2
bomber.h
2
bomber.h
@ -66,6 +66,7 @@ typedef struct player
|
|||||||
int flags;
|
int flags;
|
||||||
int abilities;
|
int abilities;
|
||||||
int speed;
|
int speed;
|
||||||
|
int speedturtle_timeout;
|
||||||
int bombsused;
|
int bombsused;
|
||||||
int bombsavailable;
|
int bombsavailable;
|
||||||
int flamelength;
|
int flamelength;
|
||||||
@ -164,6 +165,7 @@ typedef struct bonustile
|
|||||||
int px,py;
|
int px,py;
|
||||||
int type;
|
int type;
|
||||||
}bonustile;
|
}bonustile;
|
||||||
|
|
||||||
#define TILE_NONE -1
|
#define TILE_NONE -1
|
||||||
#define TILE_BOMB 5
|
#define TILE_BOMB 5
|
||||||
#define TILE_FLAME 2
|
#define TILE_FLAME 2
|
||||||
|
35
gfx.c
35
gfx.c
@ -29,7 +29,7 @@ void dumpgfx()
|
|||||||
{
|
{
|
||||||
usedcolors = 0;
|
usedcolors = 0;
|
||||||
}
|
}
|
||||||
int bestmatch(int red,int green,int blue)
|
static int bestmatch(int red,int green,int blue)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int bestcolor,bestdelta=0;
|
int bestcolor,bestdelta=0;
|
||||||
@ -61,7 +61,7 @@ int delta;
|
|||||||
return bestcolor;
|
return bestcolor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updatemap(void)
|
static void updatemap(void)
|
||||||
{
|
{
|
||||||
SDL_SetColors(thescreen, themap, 0, 256);
|
SDL_SetColors(thescreen, themap, 0, 256);
|
||||||
}
|
}
|
||||||
@ -117,7 +117,7 @@ int cnt;
|
|||||||
updatemap();
|
updatemap();
|
||||||
}
|
}
|
||||||
|
|
||||||
uchar *compressfig(uchar *put,gfxset *gs,
|
static uchar *compressfig(uchar *put,gfxset *gs,
|
||||||
int sourcex,int sourcey,int sizex,int sizey)
|
int sourcex,int sourcey,int sizex,int sizey)
|
||||||
{
|
{
|
||||||
int j,gswidth;
|
int j,gswidth;
|
||||||
@ -154,7 +154,7 @@ int dx,dy;
|
|||||||
*put++=0;
|
*put++=0;
|
||||||
return put;
|
return put;
|
||||||
}
|
}
|
||||||
void gfxfetchsingle(figure *fig,gfxset *gs,int sourcex,int sourcey,int sizex,int sizey)
|
static void gfxfetchsingle(figure *fig,gfxset *gs,int sourcex,int sourcey,int sizex,int sizey)
|
||||||
{
|
{
|
||||||
uchar *p,*p2;
|
uchar *p,*p2;
|
||||||
int dx,dy;
|
int dx,dy;
|
||||||
@ -401,16 +401,14 @@ void copyupxysize(int x,int y,int xsize,int ysize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void set_color(int color, int red, int green, int blue)
|
// static void set_color(int color, int red, int green, int blue) {
|
||||||
{
|
// themap[color].r=red;
|
||||||
themap[color].r=red;
|
// themap[color].g=green;
|
||||||
themap[color].g=green;
|
// themap[color].b=blue;
|
||||||
themap[color].b=blue;
|
// }
|
||||||
|
|
||||||
}
|
void opengfx(int argc, char **argv) {
|
||||||
void opengfx(int argc, char **argv)
|
unsigned long videoflags;
|
||||||
{
|
|
||||||
unsigned long videoflags;
|
|
||||||
|
|
||||||
themap[0].r=0;
|
themap[0].r=0;
|
||||||
themap[0].g=0;
|
themap[0].g=0;
|
||||||
@ -657,17 +655,16 @@ SDLK_LALT,MYALTL,
|
|||||||
SDLK_RALT,MYALTR,
|
SDLK_RALT,MYALTR,
|
||||||
ENDMARK
|
ENDMARK
|
||||||
};
|
};
|
||||||
int looklist(int code,int *list)
|
static int looklist(int code,int *list)
|
||||||
{
|
{
|
||||||
while(*list!=ENDMARK)
|
while((unsigned int)*list!=ENDMARK) {
|
||||||
{
|
|
||||||
if(*list==code)
|
if(*list==code)
|
||||||
return list[1];
|
return list[1];
|
||||||
list+=2;
|
list+=2;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int mapkey(int code,int qual)
|
static int mapkey(int code,int qual)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(qual & KMOD_SHIFT)
|
if(qual & KMOD_SHIFT)
|
||||||
@ -681,7 +678,7 @@ int mapkey(int code,int qual)
|
|||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
void markkey(int code,int status)
|
static void markkey(int code,int status)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int *ip;
|
int *ip;
|
||||||
@ -818,7 +815,7 @@ int i,*ip,code;
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void drawrect(int x,int y,int xs,int ys,int c)
|
static void drawrect(int x,int y,int xs,int ys,int c)
|
||||||
{
|
{
|
||||||
uchar *p;
|
uchar *p;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user