Added initial LBreakout2 sources, already slightly modified - it does not work yet!
This commit is contained in:
8
project/jni/application/lbreakout2/common/Makefile.am
Normal file
8
project/jni/application/lbreakout2/common/Makefile.am
Normal file
@@ -0,0 +1,8 @@
|
||||
DEFS = @DEFS@ @network_flag@ @netdebug_flag@ @sdlnet_flag@
|
||||
|
||||
noinst_LIBRARIES = libcommon.a
|
||||
|
||||
libcommon_a_SOURCES = \
|
||||
list.c net.c tools.c parser.c
|
||||
|
||||
EXTRA_DIST = list.h net.h messages.h tools.h parser.h gettext.h
|
||||
459
project/jni/application/lbreakout2/common/Makefile.in
Normal file
459
project/jni/application/lbreakout2/common/Makefile.in
Normal file
@@ -0,0 +1,459 @@
|
||||
# Makefile.in generated by automake 1.9.6 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
# 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
top_builddir = ..
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
INSTALL = @INSTALL@
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
target_triplet = @target@
|
||||
subdir = common
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/m4/codeset.m4 \
|
||||
$(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/glibc21.m4 \
|
||||
$(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intdiv0.m4 \
|
||||
$(top_srcdir)/m4/intmax.m4 $(top_srcdir)/m4/inttypes-pri.m4 \
|
||||
$(top_srcdir)/m4/inttypes.m4 $(top_srcdir)/m4/inttypes_h.m4 \
|
||||
$(top_srcdir)/m4/isc-posix.m4 $(top_srcdir)/m4/lcmessage.m4 \
|
||||
$(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
|
||||
$(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/longdouble.m4 \
|
||||
$(top_srcdir)/m4/longlong.m4 $(top_srcdir)/m4/nls.m4 \
|
||||
$(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/printf-posix.m4 \
|
||||
$(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/signed.m4 \
|
||||
$(top_srcdir)/m4/size_max.m4 $(top_srcdir)/m4/stdint_h.m4 \
|
||||
$(top_srcdir)/m4/uintmax_t.m4 $(top_srcdir)/m4/ulonglong.m4 \
|
||||
$(top_srcdir)/m4/wchar_t.m4 $(top_srcdir)/m4/wint_t.m4 \
|
||||
$(top_srcdir)/m4/xsize.m4 $(top_srcdir)/acinclude.m4 \
|
||||
$(top_srcdir)/configure.in
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_HEADER = $(top_builddir)/config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
LIBRARIES = $(noinst_LIBRARIES)
|
||||
AR = ar
|
||||
ARFLAGS = cru
|
||||
libcommon_a_AR = $(AR) $(ARFLAGS)
|
||||
libcommon_a_LIBADD =
|
||||
am_libcommon_a_OBJECTS = list.$(OBJEXT) net.$(OBJEXT) tools.$(OBJEXT) \
|
||||
parser.$(OBJEXT)
|
||||
libcommon_a_OBJECTS = $(am_libcommon_a_OBJECTS)
|
||||
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
|
||||
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
CCLD = $(CC)
|
||||
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
SOURCES = $(libcommon_a_SOURCES)
|
||||
DIST_SOURCES = $(libcommon_a_SOURCES)
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ACLOCAL = @ACLOCAL@
|
||||
ALLOCA = @ALLOCA@
|
||||
AMDEP_FALSE = @AMDEP_FALSE@
|
||||
AMDEP_TRUE = @AMDEP_TRUE@
|
||||
AMTAR = @AMTAR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@
|
||||
CATOBJEXT = @CATOBJEXT@
|
||||
CC = @CC@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DATADIRNAME = @DATADIRNAME@
|
||||
DEFS = @DEFS@ @network_flag@ @netdebug_flag@ @sdlnet_flag@
|
||||
DEPDIR = @DEPDIR@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
GENCAT = @GENCAT@
|
||||
GLIBC21 = @GLIBC21@
|
||||
GMSGFMT = @GMSGFMT@
|
||||
GREP = @GREP@
|
||||
HAVE_ASPRINTF = @HAVE_ASPRINTF@
|
||||
HAVE_POSIX_PRINTF = @HAVE_POSIX_PRINTF@
|
||||
HAVE_SNPRINTF = @HAVE_SNPRINTF@
|
||||
HAVE_WPRINTF = @HAVE_WPRINTF@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
INSTOBJEXT = @INSTOBJEXT@
|
||||
INTLBISON = @INTLBISON@
|
||||
INTLLIBS = @INTLLIBS@
|
||||
INTLOBJS = @INTLOBJS@
|
||||
INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBICONV = @LIBICONV@
|
||||
LIBINTL = @LIBINTL@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LTLIBICONV = @LTLIBICONV@
|
||||
LTLIBINTL = @LTLIBINTL@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MKINSTALLDIRS = @MKINSTALLDIRS@
|
||||
MSGFMT = @MSGFMT@
|
||||
MSGMERGE = @MSGMERGE@
|
||||
OBJEXT = @OBJEXT@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
POSUB = @POSUB@
|
||||
RANLIB = @RANLIB@
|
||||
SDL_CFLAGS = @SDL_CFLAGS@
|
||||
SDL_CONFIG = @SDL_CONFIG@
|
||||
SDL_LIBS = @SDL_LIBS@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
STRIP = @STRIP@
|
||||
USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
|
||||
USE_NLS = @USE_NLS@
|
||||
VERSION = @VERSION@
|
||||
XGETTEXT = @XGETTEXT@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
|
||||
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
appname = @appname@
|
||||
arch_flag = @arch_flag@
|
||||
audio_flag = @audio_flag@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
doc_dir = @doc_dir@
|
||||
docdir = @docdir@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
hi_dir = @hi_dir@
|
||||
hi_inst_flag = @hi_inst_flag@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
htmldir = @htmldir@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
inst_dir = @inst_dir@
|
||||
inst_flag = @inst_flag@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
locdir_flag = @locdir_flag@
|
||||
mandir = @mandir@
|
||||
mixer_flag = @mixer_flag@
|
||||
mkdir_p = @mkdir_p@
|
||||
netdebug_flag = @netdebug_flag@
|
||||
network_flag = @network_flag@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
sbindir = @sbindir@
|
||||
sdlnet_flag = @sdlnet_flag@
|
||||
sdlnet_lib_flag = @sdlnet_lib_flag@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
sysconfdir = @sysconfdir@
|
||||
target = @target@
|
||||
target_alias = @target_alias@
|
||||
target_cpu = @target_cpu@
|
||||
target_os = @target_os@
|
||||
target_vendor = @target_vendor@
|
||||
warp_flag = @warp_flag@
|
||||
win32_deps = @win32_deps@
|
||||
win32_inst_script = @win32_inst_script@
|
||||
noinst_LIBRARIES = libcommon.a
|
||||
libcommon_a_SOURCES = \
|
||||
list.c net.c tools.c parser.c
|
||||
|
||||
EXTRA_DIST = list.h net.h messages.h tools.h parser.h gettext.h
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .o .obj
|
||||
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
|
||||
&& exit 0; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign common/Makefile'; \
|
||||
cd $(top_srcdir) && \
|
||||
$(AUTOMAKE) --foreign common/Makefile
|
||||
.PRECIOUS: Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: $(am__configure_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
clean-noinstLIBRARIES:
|
||||
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
|
||||
libcommon.a: $(libcommon_a_OBJECTS) $(libcommon_a_DEPENDENCIES)
|
||||
-rm -f libcommon.a
|
||||
$(libcommon_a_AR) libcommon.a $(libcommon_a_OBJECTS) $(libcommon_a_LIBADD)
|
||||
$(RANLIB) libcommon.a
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT)
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parser.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tools.Po@am__quote@
|
||||
|
||||
.c.o:
|
||||
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
|
||||
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
|
||||
|
||||
.c.obj:
|
||||
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
|
||||
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
|
||||
uninstall-info-am:
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
mkid -fID $$unique
|
||||
tags: TAGS
|
||||
|
||||
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$tags $$unique; \
|
||||
fi
|
||||
ctags: CTAGS
|
||||
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$tags $$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& cd $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) $$here
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
|
||||
list='$(DISTFILES)'; for file in $$list; do \
|
||||
case $$file in \
|
||||
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
|
||||
esac; \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
|
||||
dir="/$$dir"; \
|
||||
$(mkdir_p) "$(distdir)$$dir"; \
|
||||
else \
|
||||
dir=''; \
|
||||
fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
|
||||
fi; \
|
||||
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
|
||||
else \
|
||||
test -f $(distdir)/$$file \
|
||||
|| cp -p $$d/$$file $(distdir)/$$file \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(LIBRARIES)
|
||||
installdirs:
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
`test -z '$(STRIP)' || \
|
||||
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-tags
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-am
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am:
|
||||
|
||||
install-exec-am:
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-man:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am: uninstall-info-am
|
||||
|
||||
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
|
||||
clean-noinstLIBRARIES ctags distclean distclean-compile \
|
||||
distclean-generic distclean-tags distdir dvi dvi-am html \
|
||||
html-am info info-am install install-am install-data \
|
||||
install-data-am install-exec install-exec-am install-info \
|
||||
install-info-am install-man install-strip installcheck \
|
||||
installcheck-am installdirs maintainer-clean \
|
||||
maintainer-clean-generic mostlyclean mostlyclean-compile \
|
||||
mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
|
||||
uninstall-am uninstall-info-am
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
||||
69
project/jni/application/lbreakout2/common/gettext.h
Normal file
69
project/jni/application/lbreakout2/common/gettext.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/* Convenience header for conditional use of GNU <libintl.h>.
|
||||
Copyright (C) 1995-1998, 2000-2002 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library General Public License as published
|
||||
by the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
USA. */
|
||||
|
||||
#ifndef _LIBGETTEXT_H
|
||||
#define _LIBGETTEXT_H 1
|
||||
|
||||
/* NLS can be disabled through the configure --disable-nls option. */
|
||||
#if ENABLE_NLS
|
||||
|
||||
/* Get declarations of GNU message catalog functions. */
|
||||
# include <libintl.h>
|
||||
|
||||
#else
|
||||
|
||||
/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
|
||||
chokes if dcgettext is defined as a macro. So include it now, to make
|
||||
later inclusions of <locale.h> a NOP. We don't include <libintl.h>
|
||||
as well because people using "gettext.h" will not include <libintl.h>,
|
||||
and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
|
||||
is OK. */
|
||||
#if defined(__sun)
|
||||
# include <locale.h>
|
||||
#endif
|
||||
|
||||
/* Disabled NLS.
|
||||
The casts to 'const char *' serve the purpose of producing warnings
|
||||
for invalid uses of the value returned from these functions.
|
||||
On pre-ANSI systems without 'const', the config.h file is supposed to
|
||||
contain "#define const". */
|
||||
# define gettext(Msgid) ((const char *) (Msgid))
|
||||
# define dgettext(Domainname, Msgid) ((const char *) (Msgid))
|
||||
# define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid))
|
||||
# define ngettext(Msgid1, Msgid2, N) \
|
||||
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
|
||||
# define dngettext(Domainname, Msgid1, Msgid2, N) \
|
||||
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
|
||||
# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
|
||||
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
|
||||
# define textdomain(Domainname) ((const char *) (Domainname))
|
||||
# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname))
|
||||
# define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset))
|
||||
|
||||
#endif
|
||||
|
||||
/* A pseudo function call that serves as a marker for the automated
|
||||
extraction of messages, but does not call gettext(). The run-time
|
||||
translation is done at a different place in the code.
|
||||
The argument, String, should be a literal string. Concatenated strings
|
||||
and other string expressions won't work.
|
||||
The macro's expansion is not parenthesized, so that it is suitable as
|
||||
initializer for static 'char[]' or 'const char[]' variables. */
|
||||
#define gettext_noop(String) String
|
||||
|
||||
#endif /* _LIBGETTEXT_H */
|
||||
BIN
project/jni/application/lbreakout2/common/libcommon.a
Normal file
BIN
project/jni/application/lbreakout2/common/libcommon.a
Normal file
Binary file not shown.
360
project/jni/application/lbreakout2/common/list.c
Normal file
360
project/jni/application/lbreakout2/common/list.c
Normal file
@@ -0,0 +1,360 @@
|
||||
/***************************************************************************
|
||||
list.c - description
|
||||
-------------------
|
||||
begin : Sun Sep 2 2001
|
||||
copyright : (C) 2001 by Michael Speck
|
||||
email : kulkanie@gmx.net
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "list.h"
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Create a new list
|
||||
auto_delete: Free memory of data pointer when deleting entry
|
||||
callback: Use this callback to free memory of data including
|
||||
the data pointer itself.
|
||||
Return Value: List pointer
|
||||
====================================================================
|
||||
*/
|
||||
List *list_create( int auto_delete, void (*callback)(void*) )
|
||||
{
|
||||
List *list = calloc( 1, sizeof( List ) );
|
||||
list->head = calloc( 1, sizeof( ListEntry ) );
|
||||
list->tail = calloc( 1, sizeof( ListEntry ) );
|
||||
list->head->next = list->tail;
|
||||
list->head->prev = list->head;
|
||||
list->tail->next = list->tail;
|
||||
list->tail->prev = list->head;
|
||||
list->auto_delete = auto_delete;
|
||||
list->callback = callback;
|
||||
list->cur_entry = list->head;
|
||||
return list;
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
Delete list and entries.
|
||||
====================================================================
|
||||
*/
|
||||
void list_delete( List *list )
|
||||
{
|
||||
list_clear( list );
|
||||
free( list->head );
|
||||
free( list->tail );
|
||||
free( list );
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
Delete all entries but keep the list. Reset current_entry to head
|
||||
pointer.
|
||||
====================================================================
|
||||
*/
|
||||
void list_clear( List *list )
|
||||
{
|
||||
while( !list_empty( list ) ) list_delete_pos( list, 0 );
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
Insert new item at position.
|
||||
Return Value: True if successful else False.
|
||||
====================================================================
|
||||
*/
|
||||
int list_insert( List *list, void *item, int pos )
|
||||
{
|
||||
int i;
|
||||
ListEntry *cur = list->head;
|
||||
ListEntry *new_entry = 0;
|
||||
|
||||
/* check if insertion possible */
|
||||
if ( pos < 0 || pos > list->count ) return 0;
|
||||
if ( item == 0 ) return 0;
|
||||
/* get to previous entry */
|
||||
for (i = 0; i < pos; i++) cur = cur->next;
|
||||
/* create and anchor new entry */
|
||||
new_entry = calloc( 1, sizeof( ListEntry ) );
|
||||
new_entry->item = item;
|
||||
new_entry->next = cur->next;
|
||||
new_entry->prev = cur;
|
||||
cur->next->prev = new_entry;
|
||||
cur->next = new_entry;
|
||||
list->count++;
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
Add new item at the end of the list.
|
||||
====================================================================
|
||||
*/
|
||||
int list_add( List *list, void *item )
|
||||
{
|
||||
ListEntry *new_entry = 0;
|
||||
/* check if insertion possible */
|
||||
if ( item == 0 ) return 0;
|
||||
/* create and anchor new entry */
|
||||
new_entry = calloc( 1, sizeof( ListEntry ) );
|
||||
new_entry->item = item;
|
||||
new_entry->next = list->tail;
|
||||
new_entry->prev = list->tail->prev;
|
||||
list->tail->prev->next = new_entry;
|
||||
list->tail->prev = new_entry;
|
||||
list->count++;
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
Delete item at position. If this was the current entry update
|
||||
current_entry to valid previous pointer.
|
||||
Return Value: True if successful else False.
|
||||
====================================================================
|
||||
*/
|
||||
int list_delete_pos( List *list, int pos )
|
||||
{
|
||||
int i;
|
||||
ListEntry *cur = list->head;
|
||||
|
||||
/* check if deletion possbile */
|
||||
if ( list_empty( list ) ) return 0;
|
||||
if ( pos < 0 || pos >= list->count ) return 0;
|
||||
/* get to correct entry */
|
||||
for ( i = 0; i <= pos; i++ ) cur = cur->next;
|
||||
/* modify anchors */
|
||||
cur->next->prev = cur->prev;
|
||||
cur->prev->next = cur->next;
|
||||
/* decrease counter */
|
||||
list->count--;
|
||||
/* check current_entry */
|
||||
if ( list->cur_entry == cur )
|
||||
list->cur_entry = list->cur_entry->prev;
|
||||
/* free memory */
|
||||
if ( list->auto_delete ) {
|
||||
if ( list->callback )
|
||||
(list->callback)( cur->item );
|
||||
else
|
||||
free( cur->item );
|
||||
}
|
||||
free( cur );
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
Delete item if in list. If this was the current entry update
|
||||
current_entry to valid previous pointer.
|
||||
Return Value: True if successful else False.
|
||||
====================================================================
|
||||
*/
|
||||
int list_delete_item( List *list, void *item )
|
||||
{
|
||||
return list_delete_pos( list, list_check( list, item ) );
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
Delete entry.
|
||||
Return Value: True if successful else False.
|
||||
====================================================================
|
||||
*/
|
||||
int list_delete_entry( List *list, ListEntry *entry )
|
||||
{
|
||||
/* delete possible? */
|
||||
if ( entry == 0 ) return 0;
|
||||
if ( list->count == 0 ) return 0;
|
||||
if ( entry == list->head || entry == list->tail ) return 0;
|
||||
/* adjust anchor and counter */
|
||||
entry->prev->next = entry->next;
|
||||
entry->next->prev = entry->prev;
|
||||
list->count--;
|
||||
/* check current_entry */
|
||||
if ( list->cur_entry == entry )
|
||||
list->cur_entry = list->cur_entry->prev;
|
||||
/* free memory */
|
||||
if ( list->auto_delete ) {
|
||||
if ( list->callback )
|
||||
(list->callback)( entry->item );
|
||||
else
|
||||
free( entry->item );
|
||||
}
|
||||
free( entry );
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
Get item from position if in list.
|
||||
Return Value: Item pointer if found else Null pointer.
|
||||
====================================================================
|
||||
*/
|
||||
void* list_get( List *list, int pos )
|
||||
{
|
||||
int i;
|
||||
ListEntry *cur = list->head;
|
||||
|
||||
if ( pos < 0 || pos >= list->count ) return 0;
|
||||
for ( i = 0; i <= pos; i++ ) cur = cur->next;
|
||||
return cur->item;
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
Check if item's in list.
|
||||
Return Value: Position of item else -1.
|
||||
====================================================================
|
||||
*/
|
||||
int list_check( List *list, void *item )
|
||||
{
|
||||
int pos = -1;
|
||||
ListEntry *cur = list->head->next;
|
||||
while ( cur != list->tail ) {
|
||||
pos++;
|
||||
if ( cur->item == item ) break;
|
||||
cur = cur->next;
|
||||
}
|
||||
if ( cur == list->tail ) pos = -1; /* item not found */
|
||||
return pos;
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
Return first item stored in list and set current_entry to this
|
||||
entry.
|
||||
Return Value: Item pointer if found else Null pointer.
|
||||
====================================================================
|
||||
*/
|
||||
void* list_first( List *list )
|
||||
{
|
||||
list->cur_entry = list->head->next;
|
||||
return list->head->next->item;
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
Return last item stored in list and set current_entry to this
|
||||
entry.
|
||||
Return Value: Item pointer if found else Null pointer.
|
||||
====================================================================
|
||||
*/
|
||||
void* list_last( List *list )
|
||||
{
|
||||
list->cur_entry = list->tail->prev;
|
||||
return list->tail->prev->item;
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
Return item in current_entry.
|
||||
Return Value: Item pointer if found else Null pointer.
|
||||
====================================================================
|
||||
*/
|
||||
void* list_current( List *list )
|
||||
{
|
||||
return list->cur_entry->item;
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
Reset current_entry to head of list.
|
||||
====================================================================
|
||||
*/
|
||||
void list_reset( List *list )
|
||||
{
|
||||
list->cur_entry = list->head;
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
Get next item and update current_entry (reset if tail reached)
|
||||
Return Value: Item pointer if found else Null (if tail of list).
|
||||
====================================================================
|
||||
*/
|
||||
void* list_next( List *list )
|
||||
{
|
||||
list->cur_entry = list->cur_entry->next;
|
||||
if ( list->cur_entry == list->tail ) list_reset( list );
|
||||
return list->cur_entry->item;
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
Get previous item and update current_entry.
|
||||
Return Value: Item pointer if found else Null (if head of list).
|
||||
====================================================================
|
||||
*/
|
||||
void* list_prev( List *list )
|
||||
{
|
||||
list->cur_entry = list->cur_entry->prev;
|
||||
return list->cur_entry->item;
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
Delete the current entry if not tail or head. This is the entry
|
||||
that contains the last returned item by list_next/prev().
|
||||
Return Value: True if it was a valid deleteable entry.
|
||||
====================================================================
|
||||
*/
|
||||
int list_delete_current( List *list )
|
||||
{
|
||||
if ( list->cur_entry == 0 || list->cur_entry == list->head || list->cur_entry == list->tail ) return 0;
|
||||
list_delete_entry( list, list->cur_entry );
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
Check if list is empty.
|
||||
Return Value: True if list counter is 0 else False.
|
||||
====================================================================
|
||||
*/
|
||||
int list_empty( List *list )
|
||||
{
|
||||
return list->count == 0;
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
Return entry containing the passed item.
|
||||
Return Value: True if entry found else False.
|
||||
====================================================================
|
||||
*/
|
||||
ListEntry *list_entry( List *list, void *item )
|
||||
{
|
||||
ListEntry *entry = list->head->next;
|
||||
while ( entry != list->tail ) {
|
||||
if ( entry->item == item ) return entry;
|
||||
entry = entry->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
Transfer an entry from one list to another list by removing from
|
||||
'source' and adding to 'dest' thus if source does not contain
|
||||
the item this is equvalent to list_add( dest, item ).
|
||||
====================================================================
|
||||
*/
|
||||
void list_transfer( List *source, List *dest, void *item )
|
||||
{
|
||||
int old_auto_flag;
|
||||
/* add to destination */
|
||||
list_add( dest, item );
|
||||
/* as the pointer is added to dest without changes only the empty
|
||||
entry must be deleted in source */
|
||||
old_auto_flag = source->auto_delete;
|
||||
source->auto_delete = LIST_NO_AUTO_DELETE;
|
||||
list_delete_item( source, item );
|
||||
source->auto_delete = old_auto_flag;
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
Deqeue the first list entry. (must not use auto_delete therefore)
|
||||
====================================================================
|
||||
*/
|
||||
void *list_dequeue( List *list )
|
||||
{
|
||||
void *item;
|
||||
if ( list->count > 0 ) {
|
||||
item = list->head->next->item;
|
||||
list_delete_pos( list, 0 );
|
||||
return item;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
202
project/jni/application/lbreakout2/common/list.h
Normal file
202
project/jni/application/lbreakout2/common/list.h
Normal file
@@ -0,0 +1,202 @@
|
||||
/***************************************************************************
|
||||
list.h - description
|
||||
-------------------
|
||||
begin : Sun Sep 2 2001
|
||||
copyright : (C) 2001 by Michael Speck
|
||||
email : kulkanie@gmx.net
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef __LIST_H
|
||||
#define __LIST_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Dynamic list handling data as void pointers.
|
||||
====================================================================
|
||||
*/
|
||||
typedef struct _ListEntry {
|
||||
struct _ListEntry *next;
|
||||
struct _ListEntry *prev;
|
||||
void *item;
|
||||
} ListEntry;
|
||||
typedef struct {
|
||||
int auto_delete;
|
||||
int count;
|
||||
ListEntry *head;
|
||||
ListEntry *tail;
|
||||
void (*callback)(void*);
|
||||
ListEntry *cur_entry;
|
||||
} List;
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Create a new list
|
||||
auto_delete: Free memory of data pointer when deleting entry
|
||||
callback: Use this callback to free memory of data including
|
||||
the data pointer itself.
|
||||
Return Value: List pointer
|
||||
====================================================================
|
||||
*/
|
||||
enum { LIST_NO_AUTO_DELETE = 0, LIST_AUTO_DELETE };
|
||||
enum { LIST_NO_CALLBACK = 0 };
|
||||
List *list_create( int auto_delete, void (*callback)(void*) );
|
||||
/*
|
||||
====================================================================
|
||||
Delete list and entries.
|
||||
====================================================================
|
||||
*/
|
||||
void list_delete( List *list );
|
||||
/*
|
||||
====================================================================
|
||||
Delete all entries but keep the list. Reset current_entry to head
|
||||
pointer.
|
||||
====================================================================
|
||||
*/
|
||||
void list_clear( List *list );
|
||||
/*
|
||||
====================================================================
|
||||
Insert new item at position.
|
||||
Return Value: True if successful else False.
|
||||
====================================================================
|
||||
*/
|
||||
int list_insert( List *list, void *item, int pos );
|
||||
/*
|
||||
====================================================================
|
||||
Add new item at the end of the list.
|
||||
====================================================================
|
||||
*/
|
||||
int list_add( List *list, void *item );
|
||||
/*
|
||||
====================================================================
|
||||
Delete item at pos. If this was the current entry update
|
||||
current_entry to valid previous pointer.
|
||||
Return Value: True if successful else False.
|
||||
====================================================================
|
||||
*/
|
||||
int list_delete_pos( List *list, int pos );
|
||||
/*
|
||||
====================================================================
|
||||
Delete item if in list. If this was the current entry update
|
||||
current_entry to valid previous pointer.
|
||||
Return Value: True if successful else False.
|
||||
====================================================================
|
||||
*/
|
||||
int list_delete_item( List *list, void *item );
|
||||
/*
|
||||
====================================================================
|
||||
Delete entry.
|
||||
====================================================================
|
||||
*/
|
||||
int list_delete_entry( List *list, ListEntry *entry );
|
||||
/*
|
||||
====================================================================
|
||||
Get item from position if in list.
|
||||
Return Value: Item pointer if found else Null pointer.
|
||||
====================================================================
|
||||
*/
|
||||
void* list_get( List *list, int pos );
|
||||
/*
|
||||
====================================================================
|
||||
Check if item's in list.
|
||||
Return Value: Position of item else -1.
|
||||
====================================================================
|
||||
*/
|
||||
int list_check( List *list, void *item );
|
||||
/*
|
||||
====================================================================
|
||||
Return first item stored in list and set current_entry to this
|
||||
entry.
|
||||
Return Value: Item pointer if found else Null pointer.
|
||||
====================================================================
|
||||
*/
|
||||
void* list_first( List *list );
|
||||
/*
|
||||
====================================================================
|
||||
Return last item stored in list and set current_entry to this
|
||||
entry.
|
||||
Return Value: Item pointer if found else Null pointer.
|
||||
====================================================================
|
||||
*/
|
||||
void* list_last( List *list );
|
||||
/*
|
||||
====================================================================
|
||||
Return item in current_entry.
|
||||
Return Value: Item pointer if found else Null pointer.
|
||||
====================================================================
|
||||
*/
|
||||
void* list_current( List *list );
|
||||
/*
|
||||
====================================================================
|
||||
Reset current_entry to head of list.
|
||||
====================================================================
|
||||
*/
|
||||
void list_reset( List *list );
|
||||
/*
|
||||
====================================================================
|
||||
Get next item and update current_entry (reset if tail reached).
|
||||
Return Value: Item pointer if found else Null (if tail of list).
|
||||
====================================================================
|
||||
*/
|
||||
void* list_next( List *list );
|
||||
/*
|
||||
====================================================================
|
||||
Get previous item and update current_entry.
|
||||
Return Value: Item pointer if found else Null (if head of list).
|
||||
====================================================================
|
||||
*/
|
||||
void* list_prev( List *list );
|
||||
/*
|
||||
====================================================================
|
||||
Delete the current entry if not tail or head. This is the entry
|
||||
that contains the last returned item by list_next/prev().
|
||||
Return Value: True if it was a valid deleteable entry.
|
||||
====================================================================
|
||||
*/
|
||||
int list_delete_current( List *list );
|
||||
/*
|
||||
====================================================================
|
||||
Check if list is empty.
|
||||
Return Value: True if list counter is 0 else False.
|
||||
====================================================================
|
||||
*/
|
||||
int list_empty( List *list );
|
||||
/*
|
||||
====================================================================
|
||||
Return entry containing the passed item.
|
||||
Return Value: True if entry found else False.
|
||||
====================================================================
|
||||
*/
|
||||
ListEntry *list_entry( List *list, void *item );
|
||||
/*
|
||||
====================================================================
|
||||
Transfer an entry from one list to another list by removing from
|
||||
'source' and adding to 'dest' thus if source does not contain
|
||||
the item this is equvalent to list_add( dest, item ).
|
||||
====================================================================
|
||||
*/
|
||||
void list_transfer( List *source, List *dest, void *item );
|
||||
/*
|
||||
====================================================================
|
||||
Deqeue the first list entry. (must not use auto_delete therefore)
|
||||
====================================================================
|
||||
*/
|
||||
void *list_dequeue( List *list );
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
273
project/jni/application/lbreakout2/common/messages.h
Normal file
273
project/jni/application/lbreakout2/common/messages.h
Normal file
@@ -0,0 +1,273 @@
|
||||
/***************************************************************************
|
||||
messages.h - description
|
||||
-------------------
|
||||
begin : Mon Oct 21 12:02:57 CEST 2002
|
||||
copyright : (C) 2001 by Michael Speck
|
||||
email : kulkanie@gmx.net
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef __MESSAGES_H
|
||||
#define __MESSAGES_H
|
||||
|
||||
/* protocol of server and client which must be equal */
|
||||
#define PROTOCOL 4
|
||||
|
||||
/* a list of all messages in the game for client or server */
|
||||
enum {
|
||||
/* 00 */
|
||||
MSG_HEARTBEAT = 0,
|
||||
/* tells the remote one is still alive. can't be checked in another
|
||||
* way as the connection is not a stream */
|
||||
|
||||
/* 01 */
|
||||
MSG_ERROR,
|
||||
/* string message
|
||||
*
|
||||
* transfer an error message */
|
||||
|
||||
/* 02 */
|
||||
MSG_SERVER_INFO,
|
||||
/* string message
|
||||
*
|
||||
* server message written to chat */
|
||||
|
||||
/* 03 */
|
||||
MSG_CONNECT,
|
||||
/* int8 protocol
|
||||
* string username
|
||||
* string password
|
||||
*
|
||||
* password is currently unused. requests login at server */
|
||||
|
||||
/* 04 */
|
||||
MSG_LOGIN_OKAY,
|
||||
/* int32 user id
|
||||
* string user name
|
||||
*
|
||||
* accept login and tell client its server user id and its name */
|
||||
|
||||
/* 05 */
|
||||
MSG_DISCONNECT,
|
||||
/* tell server user has disconnect or vice versa */
|
||||
|
||||
/* 06 */
|
||||
MSG_PREPARE_FULL_UPDATE,
|
||||
/* clear user list and levelset list */
|
||||
|
||||
/* 07 */
|
||||
MSG_ADD_USER,
|
||||
/* string user name
|
||||
* int32 user id
|
||||
*
|
||||
* add a visible user. */
|
||||
|
||||
/* 08 */
|
||||
MSG_REMOVE_USER,
|
||||
/* int32 user id
|
||||
*
|
||||
* remove user by that id. is used as well to hide a user */
|
||||
|
||||
/* 09 */
|
||||
MSG_UNHIDE,
|
||||
/* send by user to set hide 0 after a game was finished.
|
||||
* prevents buffer overflow when game is done but user is
|
||||
* idle (looking at stats or whatever) */
|
||||
|
||||
/* 0a */
|
||||
MSG_CHANNEL_LIST,
|
||||
/* int8 count
|
||||
* string names
|
||||
* ...
|
||||
*
|
||||
* send the list of all default channels */
|
||||
|
||||
/* 0b */
|
||||
MSG_LEVELSET_LIST,
|
||||
/* int8 count
|
||||
* string names
|
||||
* ...
|
||||
*
|
||||
* send the list of all available levelsets */
|
||||
|
||||
/* 0c */
|
||||
MSG_CHATTER,
|
||||
/* string message
|
||||
*
|
||||
* broadcast this message to all visible users */
|
||||
|
||||
/* 0d */
|
||||
MSG_WHISPER,
|
||||
/* user user id
|
||||
* string message
|
||||
*
|
||||
* whisper this message to the user with the user_id which may be
|
||||
* located in any channel */
|
||||
|
||||
/* 0e */
|
||||
MSG_COMMAND,
|
||||
/* string command
|
||||
*
|
||||
* user has entered a command. the prepended '/' has already been
|
||||
* removed by the client */
|
||||
|
||||
/* 0f */
|
||||
MSG_OPEN_GAME,
|
||||
/* int32 challenged_id
|
||||
* string setname
|
||||
* int8 diff
|
||||
* int8 rounds
|
||||
* int8 frags
|
||||
* int8 balls
|
||||
*
|
||||
* open a game and add the sending user and the user by id 'challenged_id'
|
||||
* to it. */
|
||||
|
||||
/* 10 */
|
||||
MSG_CHALLENGE,
|
||||
/* string username
|
||||
* string setname
|
||||
* ... as above
|
||||
*
|
||||
* inform user that it has been challenged by 'user_id' */
|
||||
|
||||
/* 11 */
|
||||
MSG_ACCEPT_CHALLENGE,
|
||||
/* accept challenge (does not require additional data as it is sent
|
||||
* within the game context) */
|
||||
|
||||
/* 12 */
|
||||
MSG_REJECT_CHALLENGE,
|
||||
/* reject challenge (as above) */
|
||||
|
||||
/* 13 */
|
||||
MSG_CANCEL_GAME,
|
||||
/* challenger cancells challenge which will kill the game and unhide
|
||||
* both users (as above) */
|
||||
|
||||
/* 14 */
|
||||
MSG_BUSY,
|
||||
/* int32 user_id
|
||||
*
|
||||
* user cannot react on a request. the 'user_id' is the
|
||||
* requesting user who gets the busy message */
|
||||
|
||||
/* 15 */
|
||||
MSG_ENTER_CHANNEL,
|
||||
/* string name
|
||||
*
|
||||
* client requests to server to enter this channel */
|
||||
|
||||
/* 16 */
|
||||
MSG_SET_CHANNEL,
|
||||
/* string name
|
||||
*
|
||||
* set the name of the current channel */
|
||||
|
||||
/* 17 */
|
||||
MSG_QUIT_GAME,
|
||||
/* if send by a player the opponent will be informed
|
||||
* and then both are returned to the chat channel */
|
||||
|
||||
/* 18 */
|
||||
MSG_LEVEL_DATA,
|
||||
/* int8 flags
|
||||
* string title
|
||||
* string author
|
||||
* string bricks
|
||||
* string extras
|
||||
*
|
||||
* leveldata 32+252*2 bytes except the first two byte.
|
||||
* first tells wether the client plays at top or bottom
|
||||
* and second tells the comm delay of the server */
|
||||
|
||||
/* 19 */
|
||||
MSG_READY,
|
||||
/* send by client to confirm reception of level or to
|
||||
* show that its ready */
|
||||
|
||||
/* 1a */
|
||||
MSG_PAUSE,
|
||||
/* pause game */
|
||||
|
||||
/* 1b */
|
||||
MSG_UNPAUSE,
|
||||
/* guess what, eh? */
|
||||
|
||||
/* 1c */
|
||||
MSG_PADDLE_STATE,
|
||||
/* int16 state
|
||||
*
|
||||
* position and fire flags of a paddle */
|
||||
|
||||
/* 1d */
|
||||
MSG_BALL_POSITIONS,
|
||||
/* ???
|
||||
*
|
||||
* attached/moving ball positions */
|
||||
|
||||
/* 1e */
|
||||
MSG_SHOT_POSITIONS,
|
||||
/* ???
|
||||
*
|
||||
* moving shot positions */
|
||||
|
||||
/* 1f */
|
||||
MSG_SCORES,
|
||||
/* int24 paddle bottom
|
||||
* int24 paddle top
|
||||
*
|
||||
* current scores of paddles */
|
||||
|
||||
/* 20 */
|
||||
MSG_BRICK_HITS,
|
||||
/* ???
|
||||
*
|
||||
* brick modifications */
|
||||
|
||||
/* 21 */
|
||||
MSG_NEW_EXTRAS,
|
||||
/* ???
|
||||
*
|
||||
* extras collected by both paddles */
|
||||
|
||||
/* 22 */
|
||||
MSG_ROUND_OVER,
|
||||
/* int8 winner
|
||||
*
|
||||
* id of winner paddle or -1 if draw */
|
||||
|
||||
/* 23 */
|
||||
MSG_LAST_ROUND_OVER,
|
||||
/* int8 winner
|
||||
*
|
||||
* tells client that game is finished */
|
||||
|
||||
/* 24 */
|
||||
MSG_GAME_STATS,
|
||||
/* statistics
|
||||
*
|
||||
* final game stats */
|
||||
|
||||
/* 25 */
|
||||
MSG_ADD_LEVELSET,
|
||||
/* string setname
|
||||
*
|
||||
* add a new levelset to client information */
|
||||
|
||||
/* 26 */
|
||||
MSG_SET_COMM_DELAY
|
||||
/* int16 delay
|
||||
*
|
||||
* delay between communication frames */
|
||||
};
|
||||
|
||||
#endif
|
||||
765
project/jni/application/lbreakout2/common/net.c
Normal file
765
project/jni/application/lbreakout2/common/net.c
Normal file
@@ -0,0 +1,765 @@
|
||||
#include "net.h"
|
||||
#include "../client/lbreakout.h"
|
||||
#include <SDL.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
|
||||
/* Basic layer for network communication. A single UDP socket
|
||||
* is bound to a port. Received packages are stored in one
|
||||
* global buffer.
|
||||
* Socket addresses are wrapped in a struct called NetAddr to
|
||||
* which raw data may be sent as unreliable datagrams.
|
||||
*
|
||||
* Error/message stream: sys_printf()
|
||||
*/
|
||||
|
||||
int (*sys_printf)(const char *format, ...) = printf;
|
||||
|
||||
/* ********** UDP SOCKET ********** */
|
||||
|
||||
#ifdef SDL_NET_ENABLED
|
||||
UDPsocket SDL_socket = 0;
|
||||
UDPpacket *SDL_packet = 0;
|
||||
#else
|
||||
int net_socket = -1;
|
||||
#endif
|
||||
NetAddr net_local_addr;
|
||||
NetAddr net_sender_addr;
|
||||
char net_buffer[MAX_MSG_SIZE + PACKET_HEADER_SIZE];
|
||||
int net_buffer_cur_size = 0;
|
||||
|
||||
int net_show_drops = 1;
|
||||
#ifdef NET_DEBUG_MSG
|
||||
int net_show_packets = 1;
|
||||
#else
|
||||
int net_show_packets = 0;
|
||||
#endif
|
||||
|
||||
#ifdef NETWORK_ENABLED
|
||||
#ifndef SDL_NET_ENABLED
|
||||
static void sockaddr_to_netaddr( struct sockaddr *sa, NetAddr *addr )
|
||||
{
|
||||
struct sockaddr_in *sin;
|
||||
addr->sa = *sa;
|
||||
/* if AF_INET get ip */
|
||||
if ( sa->sa_family == AF_INET ) {
|
||||
sin = (struct sockaddr_in*)sa;
|
||||
*(int *)&addr->inet_ip = *(int *)&sin->sin_addr; /* wow */
|
||||
}
|
||||
}
|
||||
|
||||
static void netaddr_to_sockaddr( NetAddr *addr, struct sockaddr *sa )
|
||||
{
|
||||
*sa = addr->sa;
|
||||
}
|
||||
|
||||
/* resolve name but leave port 0 */
|
||||
static bool resolve_hostname( char *host, struct sockaddr *sa, int *sa_len )
|
||||
{
|
||||
struct sockaddr_in *sin;
|
||||
struct sockaddr_in6 *sin6;
|
||||
struct hostent *hostlist;
|
||||
|
||||
/* resolve the host's address via DNS lookup */
|
||||
if ( ( hostlist = gethostbyname( host ) ) == 0 ) {
|
||||
sys_printf( _("unable to resolve %s: %s\n"), host, strerror( errno) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* put host address to sa struct. simply use the first resolved address */
|
||||
*sa_len = sizeof(*sa);
|
||||
memset( sa, 0, *sa_len );
|
||||
switch ( hostlist->h_addrtype ) {
|
||||
case AF_INET:
|
||||
sin = (struct sockaddr_in*)sa;
|
||||
sin->sin_family = AF_INET;
|
||||
memcpy( &sin->sin_addr, hostlist->h_addr_list[0], hostlist->h_length );
|
||||
break;
|
||||
case AF_INET6:
|
||||
sin6 = (struct sockaddr_in6*)sa;
|
||||
sin6->sin6_family = AF_INET6;
|
||||
memcpy( &sin6->sin6_addr, hostlist->h_addr_list[0], hostlist->h_length );
|
||||
break;
|
||||
default:
|
||||
sys_printf( "unable to resolve: address family %i not supported\n",
|
||||
hostlist->h_addrtype );
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void net_get_local_addr( int port )
|
||||
{
|
||||
char buf[MAXHOSTNAMELEN];
|
||||
struct sockaddr_in sa;
|
||||
int sa_len;
|
||||
|
||||
gethostname(buf, MAXHOSTNAMELEN);
|
||||
buf[MAXHOSTNAMELEN-1] = 0;
|
||||
|
||||
resolve_hostname( buf, (struct sockaddr*)&sa, &sa_len ); /* port is missing */
|
||||
sa.sin_port = htons((short)port);
|
||||
|
||||
sockaddr_to_netaddr( (struct sockaddr *)&sa, &net_local_addr );
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* open UDP socket */
|
||||
bool net_init( int port )
|
||||
{
|
||||
#ifdef NETWORK_ENABLED
|
||||
#ifdef SDL_NET_ENABLED
|
||||
if(SDLNet_Init()==-1) {
|
||||
sys_printf("SDLNet_Init: %s\n", SDLNet_GetError());
|
||||
return 0;
|
||||
}
|
||||
SDL_socket=SDLNet_UDP_Open(port);
|
||||
if(!SDL_socket) {
|
||||
sys_printf("SDLNet_UDP_Open: %s\n", SDLNet_GetError());
|
||||
return 0;
|
||||
}
|
||||
SDL_packet = SDLNet_AllocPacket(MAX_MSG_SIZE + PACKET_HEADER_SIZE);
|
||||
if(SDL_packet==0) {
|
||||
sys_printf("cannot allocate packet: out of memory\n" );
|
||||
return 0;
|
||||
}
|
||||
/* net_local_addr is unset */
|
||||
net_local_addr.SDL_address.host = 0;
|
||||
net_local_addr.SDL_address.port = 0;
|
||||
return 1;
|
||||
#else
|
||||
struct sockaddr_in sa;
|
||||
int sa_len;
|
||||
int fcntl_args, i, new_args;
|
||||
|
||||
if ( (net_socket = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0 )
|
||||
sys_printf( "couldn't create socket: %s\n", strerror(errno) );
|
||||
else
|
||||
if ( fcntl( net_socket, F_GETFL, &fcntl_args) < 0 )
|
||||
sys_printf( "couldn't get fcntl args: %s\n", strerror(errno) );
|
||||
else
|
||||
{
|
||||
new_args = O_NONBLOCK;
|
||||
/* no idea, no idea... fcntl seems to work differently since kernel 2.6
|
||||
if (fcntl_args&O_APPEND) new_args|=O_APPEND;
|
||||
if (fcntl_args&O_ASYNC) new_args|=O_ASYNC;
|
||||
if (fcntl_args&O_DIRECT) new_args|=O_DIRECT;*/
|
||||
if ( fcntl( net_socket, F_SETFL, new_args ) < 0 )
|
||||
sys_printf( "couldn't set fcntl args: %s\n", strerror(errno) );
|
||||
else {
|
||||
sa_len = sizeof(sa);
|
||||
memset( &sa, 0, sa_len );
|
||||
sa.sin_family = AF_INET;
|
||||
sa.sin_port = htons((short)port);
|
||||
sa.sin_addr.s_addr = htonl(INADDR_ANY); /* all interfaces */
|
||||
|
||||
i = 10; /* try ten successive ports */
|
||||
while ( bind( net_socket, (struct sockaddr*)&sa, sa_len ) < 0 ) {
|
||||
sys_printf( "binding to port %i failed: %s\n", port, strerror(errno) );
|
||||
sa.sin_port = htons((short)port++);
|
||||
if ( --i == 0 ) {
|
||||
close( net_socket );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
net_get_local_addr( port );
|
||||
sys_printf( _("UDP socket bound to %s:%i\n"),
|
||||
net_addr_to_string( &net_local_addr ), port );
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void net_shutdown( void )
|
||||
{
|
||||
#ifdef NETWORK_ENABLED
|
||||
#ifdef SDL_NET_ENABLED
|
||||
SDLNet_UDP_Close(SDL_socket); SDL_socket = 0;
|
||||
SDLNet_FreePacket(SDL_packet); SDL_packet = 0;
|
||||
SDLNet_Quit();
|
||||
#else
|
||||
close( net_socket );
|
||||
sys_printf( "UDP socket closed\n" );
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void net_send_packet( NetAddr *to, int len, void *data )
|
||||
{
|
||||
#ifdef NETWORK_ENABLED
|
||||
#ifdef SDL_NET_ENABLED
|
||||
SDL_packet->channel = -1;
|
||||
memcpy( SDL_packet->data, data, len );
|
||||
SDL_packet->len = len;
|
||||
SDL_packet->address = to->SDL_address;
|
||||
SDLNet_UDP_Send(SDL_socket,-1,SDL_packet);
|
||||
#else
|
||||
struct sockaddr sa;
|
||||
|
||||
/* empty packets are not send */
|
||||
if ( len == 0 ) {
|
||||
sys_printf( "net_send_packet: null length packet\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
netaddr_to_sockaddr( to, &sa );
|
||||
|
||||
if ( sendto( net_socket, data, len, 0, &sa, sizeof(sa) ) < 0 ) {
|
||||
if (errno == EWOULDBLOCK)
|
||||
return;
|
||||
if (errno == ECONNREFUSED)
|
||||
return;
|
||||
sys_printf( "net_send_packet: %s\n", strerror(errno) );
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
bool net_recv_packet( void )
|
||||
{
|
||||
#ifdef NETWORK_ENABLED
|
||||
int ret;
|
||||
#ifdef SDL_NET_ENABLED
|
||||
ret = SDLNet_UDP_Recv(SDL_socket, SDL_packet);
|
||||
if ( ret == -1 ) {
|
||||
sys_printf("SDLNet_UDP_Recv: %s\n", SDLNet_GetError());
|
||||
return 0;
|
||||
}
|
||||
if ( ret == 1 ) {
|
||||
memcpy( net_buffer, SDL_packet->data, SDL_packet->len );
|
||||
net_buffer_cur_size = SDL_packet->len;
|
||||
net_sender_addr.SDL_address = SDL_packet->address;
|
||||
return 1;
|
||||
}
|
||||
net_buffer_cur_size = 0;
|
||||
return 0;
|
||||
#else
|
||||
struct sockaddr sa;
|
||||
int sa_len = sizeof(sa);
|
||||
|
||||
ret = recvfrom( net_socket,
|
||||
net_buffer, sizeof(net_buffer),
|
||||
0,
|
||||
&sa, &sa_len);
|
||||
if (ret == -1) {
|
||||
if (errno == EWOULDBLOCK)
|
||||
return 0;
|
||||
if (errno == ECONNREFUSED)
|
||||
return 0;
|
||||
sys_printf( "net_recv_packet: %s\n", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
net_buffer_cur_size = ret;
|
||||
|
||||
sockaddr_to_netaddr( &sa, &net_sender_addr );
|
||||
|
||||
return (ret>0);
|
||||
#endif
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* if host contains trailing :xxxxx 'port' is overwritten */
|
||||
bool net_build_addr( NetAddr *addr, char *host, int port )
|
||||
{
|
||||
#ifdef NETWORK_ENABLED
|
||||
char *ptr;
|
||||
#ifndef SDL_NET_ENABLED
|
||||
struct sockaddr sa;
|
||||
int sa_len;
|
||||
#endif
|
||||
if ( (ptr = strchr( host, ':' )) ) {
|
||||
*ptr = 0;
|
||||
port = atoi( ptr+1 );
|
||||
}
|
||||
|
||||
#ifdef SDL_NET_ENABLED
|
||||
if ( SDLNet_ResolveHost(&addr->SDL_address, host, port ) == -1 )
|
||||
{
|
||||
sys_printf("SDLNet_ResolveHost: %s\n", SDLNet_GetError());
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
#else
|
||||
memset( addr, 0, sizeof( NetAddr ) );
|
||||
if ( resolve_hostname( host, &sa, &sa_len ) ) {
|
||||
switch ( sa.sa_family ) {
|
||||
case AF_INET:
|
||||
((struct sockaddr_in*)&sa)->sin_port = htons((short)port);
|
||||
break;
|
||||
case AF_INET6:
|
||||
((struct sockaddr_in6*)&sa)->sin6_port = htons((short)port);
|
||||
break;
|
||||
default:
|
||||
/* not reached as resolve_hostname allows the same types */
|
||||
return 0;
|
||||
}
|
||||
sockaddr_to_netaddr( &sa, addr );
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* compare host and port */
|
||||
bool net_compare_addr( NetAddr *a1, NetAddr *a2 )
|
||||
{
|
||||
#ifdef NETWORK_ENABLED
|
||||
#ifdef SDL_NET_ENABLED
|
||||
if ( a1->SDL_address.host == a2->SDL_address.host )
|
||||
if ( a1->SDL_address.port == a2->SDL_address.port )
|
||||
return 1;
|
||||
return 0;
|
||||
#else
|
||||
/* by now only AF_INET addresses may be compared */
|
||||
if ( a1->sa.sa_family == AF_INET && a2->sa.sa_family == AF_INET ) {
|
||||
if ( a1->inet_ip[0] == a2->inet_ip[0] )
|
||||
if ( a1->inet_ip[1] == a2->inet_ip[1] )
|
||||
if ( a1->inet_ip[2] == a2->inet_ip[2] )
|
||||
if ( a1->inet_ip[3] == a2->inet_ip[3] )
|
||||
if ( ((struct sockaddr_in*)&a1->sa)->sin_port ==
|
||||
((struct sockaddr_in*)&a2->sa)->sin_port )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
sys_printf( "only AF_INET addresses may be compared yet\n" );
|
||||
return 0;
|
||||
#endif
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
char *net_addr_to_string( NetAddr *_addr ) /* not allocated but static */
|
||||
{
|
||||
#ifdef NETWORK_ENABLED
|
||||
#ifdef SDL_NET_ENABLED
|
||||
int ip[4];
|
||||
static char host_ip[64];
|
||||
char *host;
|
||||
if(!(host=SDLNet_ResolveIP(&_addr->SDL_address)))
|
||||
{
|
||||
//printf("SDLNet_ResolveIP: %s\n", SDLNet_GetError());
|
||||
ip[0] = _addr->SDL_address.host & 0xff;
|
||||
ip[1] = (_addr->SDL_address.host>>8) & 0xff;
|
||||
ip[2] = (_addr->SDL_address.host>>16) & 0xff;
|
||||
ip[3] = (_addr->SDL_address.host>>24) & 0xff;
|
||||
snprintf( host_ip, 64, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3] );
|
||||
return host_ip;
|
||||
}
|
||||
return host;
|
||||
#else
|
||||
static char str[64];
|
||||
int len = 64;
|
||||
struct sockaddr *addr = &_addr->sa;
|
||||
struct sockaddr_in *sin;
|
||||
struct sockaddr_in6 *sin6;
|
||||
/*struct sockaddr_un *sun;*/
|
||||
|
||||
str[len-1] = 0;
|
||||
snprintf( str, len, "undefined" );
|
||||
|
||||
switch ( addr->sa_family ) {
|
||||
case AF_INET:
|
||||
sin = (struct sockaddr_in*)addr;
|
||||
if ( !inet_ntop( AF_INET, &sin->sin_addr, str, len ) ) {
|
||||
sys_printf( "inet_ntop failed: %s\n", strerror( errno ) );
|
||||
}
|
||||
break;
|
||||
case AF_INET6:
|
||||
sin6 = (struct sockaddr_in6*)addr;
|
||||
if ( !inet_ntop( AF_INET6, &sin6->sin6_addr, str, len ) ) {
|
||||
sys_printf( "inet_ntop failed: %s\n", strerror( errno ) );
|
||||
}
|
||||
break;
|
||||
case AF_UNIX:
|
||||
/*sun = (struct sockaddr_un *)addr;
|
||||
if( sun->sun_path[0] == 0 ) {
|
||||
snprintf( str, len, "unknown" );
|
||||
sys_printf( "net_query_ip: unknown unix path\n" );
|
||||
}
|
||||
else
|
||||
snprintf( str, sun->sun_path, len );*/
|
||||
break;
|
||||
default:
|
||||
snprintf( str, len, "unknown" );
|
||||
break;
|
||||
}
|
||||
|
||||
return str;
|
||||
#endif
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ********** MESSAGE ********** */
|
||||
|
||||
char *msg_buf = 0;
|
||||
int *msg_buf_cur_size = 0;
|
||||
int msg_buf_max_size = 0;
|
||||
int msg_write_overflow = 0;
|
||||
|
||||
#ifdef NET_DEBUG_MSG
|
||||
static void msg_print_raw( int len, char *buf )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < len; i++ )
|
||||
printf( "%02x ", (unsigned char) buf[i] );
|
||||
printf( "\n" );
|
||||
}
|
||||
#endif
|
||||
|
||||
static char* msg_get_writeable_space( int size )
|
||||
{
|
||||
if ( *msg_buf_cur_size + size > msg_buf_max_size ) {
|
||||
msg_write_overflow = 1;
|
||||
*msg_buf_cur_size = 0;
|
||||
}
|
||||
return msg_buf + *msg_buf_cur_size;
|
||||
}
|
||||
|
||||
void msg_begin_writing( char *buf, int *cur_size, int max_size )
|
||||
{
|
||||
msg_buf = buf;
|
||||
msg_buf_cur_size = cur_size;
|
||||
msg_buf_max_size = max_size;
|
||||
*msg_buf_cur_size = 0;
|
||||
msg_write_overflow = 0;
|
||||
}
|
||||
void msg_write_int8 ( int c )
|
||||
{
|
||||
unsigned char *ptr = msg_get_writeable_space( 1 );
|
||||
ptr[0] = (char)c;
|
||||
*msg_buf_cur_size += 1;
|
||||
}
|
||||
void msg_write_int16 ( int s )
|
||||
{
|
||||
unsigned char *ptr = msg_get_writeable_space( 2 );
|
||||
ptr[0] = s & 0xff;
|
||||
ptr[1] = (s>>8) & 0xff;
|
||||
*msg_buf_cur_size += 2;
|
||||
}
|
||||
void msg_write_int32 ( int i )
|
||||
{
|
||||
unsigned char *ptr = msg_get_writeable_space( 4 );
|
||||
ptr[0] = i & 0xff;
|
||||
ptr[1] = (i>>8) & 0xff;
|
||||
ptr[2] = (i>>16) & 0xff;
|
||||
ptr[3] = (i>>24) & 0xff;
|
||||
*msg_buf_cur_size += 4;
|
||||
}
|
||||
void msg_write_string( char *str )
|
||||
{
|
||||
char *ptr = msg_get_writeable_space( strlen(str)+1 );
|
||||
if ( strlen(str)+1 > msg_buf_max_size ) return; /* would cause segfault */
|
||||
strcpy( ptr, str );
|
||||
*msg_buf_cur_size += strlen(str)+1;
|
||||
}
|
||||
void msg_printf ( char *format, ... )
|
||||
{
|
||||
char buf[MAX_MSG_SIZE];
|
||||
va_list args;
|
||||
|
||||
va_start( args, format );
|
||||
vsnprintf( buf, MAX_MSG_SIZE, format, args ); buf[MAX_MSG_SIZE-1] = 0;
|
||||
va_end( args );
|
||||
msg_write_string( buf );
|
||||
}
|
||||
void msg_write ( int len, void *data )
|
||||
{
|
||||
unsigned char *ptr = msg_get_writeable_space( len );
|
||||
if ( len > msg_buf_max_size ) return; /* would cause segfault */
|
||||
memcpy( ptr, data, len );
|
||||
*msg_buf_cur_size += len;
|
||||
}
|
||||
int msg_get_max_size()
|
||||
{
|
||||
return msg_buf_max_size;
|
||||
}
|
||||
bool msg_write_failed()
|
||||
{
|
||||
return msg_write_overflow;
|
||||
}
|
||||
|
||||
int msg_read_exceeded = 0;
|
||||
int msg_read_pos = 0;
|
||||
|
||||
static char* msg_get_readable_space( int size )
|
||||
{
|
||||
if ( msg_read_pos + size > net_buffer_cur_size ) {
|
||||
msg_read_exceeded = 1;
|
||||
msg_read_pos = 0;
|
||||
}
|
||||
return net_buffer + msg_read_pos;
|
||||
|
||||
}
|
||||
|
||||
bool msg_is_connectionless()
|
||||
{
|
||||
return ( *(int*)net_buffer == 0 );
|
||||
}
|
||||
void msg_begin_reading()
|
||||
{
|
||||
msg_read_exceeded = 0;
|
||||
msg_read_pos = 0;
|
||||
}
|
||||
void msg_begin_connectionless_reading()
|
||||
{
|
||||
msg_read_exceeded = 0;
|
||||
msg_read_pos = PACKET_HEADER_SIZE;
|
||||
}
|
||||
int msg_read_int8 ( void )
|
||||
{
|
||||
unsigned char *ptr = msg_get_readable_space( 1 );
|
||||
msg_read_pos += 1;
|
||||
return ptr[0];
|
||||
}
|
||||
int msg_read_int16( void )
|
||||
{
|
||||
unsigned char *ptr = msg_get_readable_space( 2 );
|
||||
msg_read_pos += 2;
|
||||
return ptr[0] + (ptr[1]<<8);
|
||||
}
|
||||
int msg_read_int32( void )
|
||||
{
|
||||
unsigned char *ptr = msg_get_readable_space( 4 );
|
||||
msg_read_pos += 4;
|
||||
return ptr[0] + (ptr[1]<<8) + (ptr[2]<<16) + (ptr[3]<<24);
|
||||
}
|
||||
char* msg_read_string( void )
|
||||
{
|
||||
static char buf[MAX_MSG_SIZE]; /* can't be bigger including trailing \0 */
|
||||
char c;
|
||||
int i = 0;
|
||||
|
||||
while ( 1 ) {
|
||||
c = msg_read_int8();
|
||||
buf[i++] = c;
|
||||
if ( i == MAX_MSG_SIZE ) break; /* to be sure */
|
||||
if ( c == 0 ) break;
|
||||
}
|
||||
buf[MAX_MSG_SIZE-1] = 0;
|
||||
|
||||
return buf;
|
||||
}
|
||||
void msg_read( int len, char *buf )
|
||||
{
|
||||
unsigned char *ptr = msg_get_readable_space( len );
|
||||
msg_read_pos += len;
|
||||
memcpy( buf, ptr, len );
|
||||
}
|
||||
|
||||
bool msg_read_failed( void )
|
||||
{
|
||||
return msg_read_exceeded;
|
||||
}
|
||||
|
||||
/* ********** TRANSMISSION ********** */
|
||||
|
||||
/* transmit a connectionless message */
|
||||
void net_transmit_connectionless( NetAddr *addr, int len, char *data )
|
||||
{
|
||||
int cur_size;
|
||||
char packet[PACKET_HEADER_SIZE + MAX_MSG_SIZE];
|
||||
|
||||
memset( packet, 0, PACKET_HEADER_SIZE ); /* connectionless header */
|
||||
msg_begin_writing( packet + PACKET_HEADER_SIZE, &cur_size, MAX_MSG_SIZE );
|
||||
msg_write( len, data );
|
||||
if ( msg_write_failed() ) return;
|
||||
|
||||
net_send_packet( addr, PACKET_HEADER_SIZE + cur_size, packet );
|
||||
|
||||
if ( net_show_packets )
|
||||
sys_printf( "--> %s: connectionless size=%i\n",
|
||||
net_addr_to_string( addr ),
|
||||
cur_size + PACKET_HEADER_SIZE );
|
||||
}
|
||||
|
||||
void socket_init( NetSocket *sock, NetAddr *addr )
|
||||
{
|
||||
memset( sock, 0, sizeof( NetSocket ) );
|
||||
|
||||
sock->remote_addr = *addr;
|
||||
sock->outgoing_id = 1; /* as id 0 means connectionless */
|
||||
sock->idle_since = time(0);
|
||||
|
||||
//sys_printf( "%s: socket initiated\n", net_addr_to_string( addr ) );
|
||||
}
|
||||
|
||||
void socket_reinit( NetSocket *socket ) /* with same address */
|
||||
{
|
||||
NetAddr addr = socket->remote_addr;
|
||||
socket_init( socket, &addr );
|
||||
}
|
||||
|
||||
void socket_print_stats( NetSocket *sock )
|
||||
{
|
||||
sys_printf ( "%s: STATISTICS\n drops: %i(%i packets)\n %i good packets\n",
|
||||
net_addr_to_string( &sock->remote_addr ),
|
||||
sock->drop_count, sock->dropped_packet_count,
|
||||
sock->good_packet_count );
|
||||
}
|
||||
|
||||
/* transmit CODE_RED/BLUE message and re-transmit dropped CODE_RED messages.
|
||||
* length 0 messages are not transmitted. re-transmission of CODE_RED messages
|
||||
* is handled in any case */
|
||||
void socket_transmit( NetSocket *sock, int code, int len, char *data )
|
||||
{
|
||||
char packet[PACKET_HEADER_SIZE + MAX_MSG_SIZE];
|
||||
int is_code_red = 0, cur_size = 0;
|
||||
|
||||
/* do not use sockets with fatal error */
|
||||
if ( sock->fatal_error ) return;
|
||||
|
||||
/* add code red message to buffer */
|
||||
if ( code == CODE_RED ) {
|
||||
if ( sock->code_red_buf_cur_size + len > MAX_MSG_SIZE ) {
|
||||
sock->fatal_error = 1; /* overflowed */
|
||||
return;
|
||||
}
|
||||
memcpy( sock->code_red_buf + sock->code_red_buf_cur_size, data, len );
|
||||
sock->code_red_buf_cur_size += len;
|
||||
/* do not send the message if waiting for a receipt */
|
||||
if ( sock->outgoing_code_red > 0 && !sock->retransmit_code_red_buf )
|
||||
return;
|
||||
else
|
||||
is_code_red = 1;
|
||||
}
|
||||
|
||||
if ( sock->retransmit_code_red_buf )
|
||||
is_code_red = 1;
|
||||
|
||||
msg_begin_writing( packet, &cur_size, PACKET_HEADER_SIZE + MAX_MSG_SIZE );
|
||||
msg_write_int32( sock->outgoing_id | (is_code_red<<31) );
|
||||
msg_write_int32( sock->incoming_code_red );
|
||||
|
||||
if ( is_code_red )
|
||||
sock->outgoing_code_red = sock->outgoing_id;
|
||||
|
||||
sock->outgoing_id++;
|
||||
|
||||
/* if code red buffer was not received resend it and clear the flag.
|
||||
* if not waiting for a receipt (thus an initial code red message)
|
||||
* send it as well */
|
||||
if ( is_code_red ) {
|
||||
msg_write( sock->code_red_buf_cur_size, sock->code_red_buf );
|
||||
sock->retransmit_code_red_buf = 0;
|
||||
}
|
||||
|
||||
/* add code blue packet if space is left */
|
||||
if ( code == CODE_BLUE && cur_size + len <= msg_get_max_size() )
|
||||
msg_write( len, data );
|
||||
|
||||
/* no data? */
|
||||
if ( cur_size == PACKET_HEADER_SIZE ) return;
|
||||
|
||||
/* send packet */
|
||||
net_send_packet( &sock->remote_addr, cur_size, packet );
|
||||
#ifdef NET_DEBUG_MSG
|
||||
printf( "OUT: "); msg_print_raw( cur_size, packet );
|
||||
#endif
|
||||
|
||||
if ( net_show_packets )
|
||||
sys_printf( "--> %s: out=%i(%s) size=%i in=%i(RED:%i)\n",
|
||||
net_addr_to_string( &sock->remote_addr ),
|
||||
sock->outgoing_id-1, is_code_red?"RED":"BLUE",
|
||||
cur_size,
|
||||
sock->incoming_id, sock->incoming_code_red );
|
||||
}
|
||||
|
||||
/* update socker by net_packet header if net_sender_addr is sock.remote_addr
|
||||
* and set read pointer to packet payload. if false is returned packet is
|
||||
* not parsed. */
|
||||
bool socket_process_header( NetSocket *sock )
|
||||
{
|
||||
int id, is_code_red, last_ack_code_red, drops = 0;
|
||||
|
||||
/* do not process fatal socks */
|
||||
if ( sock->fatal_error ) return 0;
|
||||
|
||||
/* correct sock? */
|
||||
if ( !net_compare_addr( &net_sender_addr, &sock->remote_addr ) )
|
||||
return 0;
|
||||
|
||||
#ifdef NET_DEBUG_MSG
|
||||
printf( " IN: " ); msg_print_raw( net_buffer_cur_size, net_buffer );
|
||||
#endif
|
||||
|
||||
/* read header */
|
||||
msg_begin_reading();
|
||||
id = msg_read_int32(); /* new incoming id, the difference to sock->incoming_id is
|
||||
the number of dropped packets */
|
||||
is_code_red = id >> 31; /* highest bit tells wether code red packet */
|
||||
id &= ~(1<<31);
|
||||
last_ack_code_red = msg_read_int32(); /* last code red packet remote received */
|
||||
|
||||
/* duplicated packets are not handled */
|
||||
if ( id <= sock->incoming_id ) {
|
||||
if ( net_show_drops )
|
||||
sys_printf( "%s: out of order packet %i at %i\n",
|
||||
net_addr_to_string( &sock->remote_addr ),
|
||||
id, sock->incoming_id );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* despite dropped packets this packet is handled */
|
||||
if ( id > sock->incoming_id+1 ) {
|
||||
drops = id - (sock->incoming_id+1);
|
||||
sock->dropped_packet_count += drops;
|
||||
sock->drop_count++;
|
||||
if ( net_show_drops )
|
||||
sys_printf( "%s: dropped %i packets at %i\n",
|
||||
net_addr_to_string( &sock->remote_addr ),
|
||||
drops, sock->incoming_id+1 );
|
||||
}
|
||||
sock->good_packet_count++;
|
||||
|
||||
sock->incoming_id = id; /* last incoming packet (no matter wether red or blue) */
|
||||
if ( is_code_red )
|
||||
sock->incoming_code_red = id; /* last code red packet socket received */
|
||||
|
||||
if ( sock->outgoing_code_red ) {
|
||||
if ( sock->outgoing_code_red == last_ack_code_red ) {
|
||||
/* was received so we can clear code_red buffer */
|
||||
sock->outgoing_code_red = 0;
|
||||
sock->code_red_buf_cur_size = 0;
|
||||
}
|
||||
else
|
||||
if ( sock->outgoing_code_red > last_ack_code_red ) {
|
||||
/* resend code_red buffer as it was dropped */
|
||||
sock->retransmit_code_red_buf = 1;
|
||||
}
|
||||
else {
|
||||
/* fatal error occured as remote received a newer code red packet
|
||||
* although we had no receipt for the current one */
|
||||
sock->fatal_error = 1;
|
||||
}
|
||||
}
|
||||
|
||||
sock->idle_since = time(0); /* reset idle time stamp */
|
||||
|
||||
/* if packet is empty mark it as unreadable */
|
||||
if ( msg_read_pos == net_buffer_cur_size )
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
121
project/jni/application/lbreakout2/common/net.h
Normal file
121
project/jni/application/lbreakout2/common/net.h
Normal file
@@ -0,0 +1,121 @@
|
||||
#ifndef __NET_H
|
||||
#define __NET_H
|
||||
|
||||
#ifdef NETWORK_ENABLED
|
||||
#ifdef SDL_NET_ENABLED
|
||||
#include <SDL_net.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <errno.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/poll.h>
|
||||
#include <signal.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef bool
|
||||
#define bool int
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
#ifdef NETWORK_ENABLED
|
||||
#ifdef SDL_NET_ENABLED
|
||||
IPaddress SDL_address;
|
||||
#else
|
||||
struct sockaddr sa;
|
||||
unsigned char inet_ip[4]; /* AF_INET dotted ip */
|
||||
#endif
|
||||
#endif
|
||||
} NetAddr;
|
||||
|
||||
#define MAX_MSG_SIZE 1016
|
||||
#define PACKET_HEADER_SIZE 8
|
||||
|
||||
typedef struct {
|
||||
NetAddr remote_addr;
|
||||
int fatal_error; /* code red buffer has been flooded */
|
||||
|
||||
int idle_since; /* global time stamp when last packet was received (secs) */
|
||||
|
||||
int drop_count; /* number of drops */
|
||||
int dropped_packet_count; /* number of dropped packets */
|
||||
int good_packet_count; /* number of successfully processed packets */
|
||||
|
||||
int incoming_id; /* last incoming remote outgoing_id */
|
||||
int outgoing_id; /* packet id increased every sent */
|
||||
int incoming_code_red; /* id of last incoming code red packet. is sent
|
||||
in the header to let remote know if any code
|
||||
red packets were dropped */
|
||||
int outgoing_code_red; /* last outgoing_id of code_red packet if socket
|
||||
is still waiting for reception acknowledgment. if
|
||||
packet was delivered successfully this is cleared
|
||||
to 0 as well as code_red_buf */
|
||||
int retransmit_code_red_buf; /* retransmit buffer as net_process_header
|
||||
has received an incoming_code_red less
|
||||
than outgoing_code_red */
|
||||
|
||||
char code_red_buf[MAX_MSG_SIZE];
|
||||
char code_red_buf_cur_size;
|
||||
} NetSocket;
|
||||
|
||||
extern NetAddr net_local_addr;
|
||||
extern NetAddr net_sender_addr;
|
||||
|
||||
bool net_init( int port );
|
||||
void net_shutdown( void );
|
||||
void net_send_packet( NetAddr *to, int len, void *data );
|
||||
bool net_recv_packet( void ); /* into net_packet from net_sender_addr */
|
||||
|
||||
bool net_build_addr( NetAddr *addr, char *host, int port );
|
||||
bool net_compare_addr( NetAddr *a1, NetAddr *a2 );
|
||||
char *net_addr_to_string( NetAddr *addr ); /* not allocated but static */
|
||||
|
||||
void msg_begin_writing( char *buf, int *cur_size, int max_size );
|
||||
void msg_write_int8 ( int c );
|
||||
void msg_write_int16 ( int s );
|
||||
void msg_write_int32 ( int i );
|
||||
void msg_write_string( char *str );
|
||||
void msg_printf ( char *format, ... );
|
||||
void msg_write ( int len, void *data );
|
||||
int msg_get_max_size();
|
||||
bool msg_write_failed(); /* check wether overflow occured */
|
||||
|
||||
bool msg_is_connectionless();
|
||||
void msg_begin_reading(); /* of net_packet, starts at header */
|
||||
void msg_begin_connectionless_reading(); /* of net_packet, starts after header as useless data */
|
||||
int msg_read_int8 ( void );
|
||||
int msg_read_int16( void );
|
||||
int msg_read_int32( void );
|
||||
char* msg_read_string( void );
|
||||
void msg_read( int len, char *buf );
|
||||
bool msg_read_failed(); /* check wether data couldn't be extracted */
|
||||
|
||||
void socket_init( NetSocket *sock, NetAddr *addr );
|
||||
void socket_reinit( NetSocket *socket ); /* with same address */
|
||||
void socket_print_stats( NetSocket *sock );
|
||||
|
||||
/* transmit a connectionless message */
|
||||
void net_transmit_connectionless( NetAddr *addr, int len, char *data );
|
||||
|
||||
/* transmit CODE_RED/BLUE message and re-transmit dropped CODE_RED messages.
|
||||
* length 0 messages are not transmitted but re-transmission of CODE_RED messages
|
||||
* is handled in any case */
|
||||
#define CODE_BLUE 0
|
||||
#define CODE_RED 1
|
||||
void socket_transmit( NetSocket *sock, int code, int len, char *data );
|
||||
|
||||
/* update socket by net_packet header if net_sender_addr is socket.remote_addr
|
||||
* and set read pointer to packet payload. if false is returned packet is
|
||||
* not parsed. */
|
||||
bool socket_process_header( NetSocket *sock );
|
||||
|
||||
#endif
|
||||
|
||||
697
project/jni/application/lbreakout2/common/parser.c
Normal file
697
project/jni/application/lbreakout2/common/parser.c
Normal file
@@ -0,0 +1,697 @@
|
||||
/***************************************************************************
|
||||
parser.c - description
|
||||
-------------------
|
||||
begin : Sat Mar 9 2002
|
||||
copyright : (C) 2001 by Michael Speck
|
||||
email : kulkanie@gmx.net
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "parser.h"
|
||||
#include "tools.h"
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Error string.
|
||||
====================================================================
|
||||
*/
|
||||
static char parser_sub_error[1024];
|
||||
static char parser_error[1024];
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
This buffer is used to fully load resource files when the
|
||||
compact format is used.
|
||||
====================================================================
|
||||
*/
|
||||
enum { CBUFFER_SIZE = 131072 }; /* 128 KB */
|
||||
static char cbuffer[CBUFFER_SIZE];
|
||||
static char* cbuffer_pos = 0; /* position in cbuffer */
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
As we need constant strings sometimes we have to define a maximum
|
||||
length for tokens.
|
||||
====================================================================
|
||||
*/
|
||||
enum { PARSER_MAX_TOKEN_LENGTH = 1024 };
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Locals
|
||||
====================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Macro to shorten the fread call for a single character.
|
||||
====================================================================
|
||||
*/
|
||||
#define FILE_READCHAR( file, c ) fread( &c, sizeof( char ), 1, file )
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Find next newline in cbuffer and replace it with \0 and return the
|
||||
pointer to the current line.
|
||||
====================================================================
|
||||
*/
|
||||
static char* parser_get_next_line()
|
||||
{
|
||||
char *line = cbuffer_pos;
|
||||
char *newpos;
|
||||
if ( cbuffer_pos[0] == 0 )
|
||||
return 0; /* completely read. no more lines. */
|
||||
if ( ( newpos = strchr( cbuffer_pos, 10 ) ) == 0 )
|
||||
cbuffer_pos += strlen( cbuffer_pos ); /* last line */
|
||||
else {
|
||||
cbuffer_pos = newpos + 1; /* set pointer to next line */
|
||||
newpos[0] = 0; /* terminate current line */
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Set parse error string: "file:line: error"
|
||||
====================================================================
|
||||
*/
|
||||
static void parser_set_parse_error( char *fname, FILE *file, char *error )
|
||||
{
|
||||
int end, pos;
|
||||
int line_count = 1;
|
||||
char c;
|
||||
end = ftell( file ); pos = 0;
|
||||
fseek( file, 0, SEEK_SET );
|
||||
while ( pos < end ) {
|
||||
FILE_READCHAR( file, c ); pos++;
|
||||
if ( c == 10 ) line_count++;
|
||||
}
|
||||
sprintf( parser_error, "%s: %i: %s",
|
||||
fname, line_count, error );
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Check if the given character occurs in the symbol list.
|
||||
If the first symbol is ' ' it is used as wildcard for all
|
||||
white-spaces.
|
||||
====================================================================
|
||||
*/
|
||||
static int is_symbol( int c, char *symbols )
|
||||
{
|
||||
int i = 0;
|
||||
if ( symbols[0] == ' ' && c <= 32 ) return 1;
|
||||
while ( symbols[i] != 0 )
|
||||
if ( c == symbols[i++] )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Move file position forward until reading in the given character.
|
||||
If stop is ' ' whitespaces will be ignored.
|
||||
====================================================================
|
||||
*/
|
||||
static void file_skip( FILE *file, char stop )
|
||||
{
|
||||
char c = 0;
|
||||
FILE_READCHAR( file, c );
|
||||
while ( ( ( stop == ' ' && c <= 32 ) || ( stop != ' ' && c != stop ) ) && !feof( file ) )
|
||||
FILE_READCHAR( file, c );
|
||||
if ( !feof( file ) )
|
||||
fseek( file, -1, SEEK_CUR );
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Read next token from current file position where symbols is a
|
||||
list of characters used to break up the tokens. The symbols
|
||||
themself are returned as tokens. If ' ' occurs in the symbol list
|
||||
it will be ignored and whitespaces are removed automatically.
|
||||
The token does not exceed PARSER_MAX_TOKEN_LENGTH.
|
||||
Enclosing ".." are kept at the token. Use file_compare_token()
|
||||
to test it's contents.
|
||||
Returns False on EoF.
|
||||
====================================================================
|
||||
*/
|
||||
static int file_read_token_intern( FILE *file, char *symbols, char *token )
|
||||
{
|
||||
int pos = 0;
|
||||
char c;
|
||||
token[0] = 0;
|
||||
file_skip( file, ' ' );
|
||||
FILE_READCHAR( file, c );
|
||||
if ( feof( file ) ) {
|
||||
sprintf( parser_sub_error, "unexpected end of file" );
|
||||
return 0;
|
||||
}
|
||||
/* string? */
|
||||
if ( c == '"' ) {
|
||||
token[pos++] = '"';
|
||||
FILE_READCHAR( file, c );
|
||||
while ( ( !feof( file ) && c != '"' ) ) {
|
||||
token[pos++] = c;
|
||||
if ( pos == PARSER_MAX_TOKEN_LENGTH - 2 ) {
|
||||
token[pos++] = '"';
|
||||
token[pos] = 0;
|
||||
sprintf( parser_sub_error, "token exceeds limit" );
|
||||
return 0;
|
||||
}
|
||||
FILE_READCHAR( file, c );
|
||||
}
|
||||
token[pos++] = '"';
|
||||
token[pos] = 0;
|
||||
if ( feof( file ) ) {
|
||||
sprintf( parser_sub_error, "unexpected end of file" );
|
||||
token[0] = 0;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/* symbol? */
|
||||
if ( is_symbol( c, symbols ) ) {
|
||||
token[0] = c; token[1] = 0;
|
||||
return 1;
|
||||
}
|
||||
/* other token */
|
||||
while ( !is_symbol( c, symbols ) && !feof( file ) ) {
|
||||
token[pos++] = c;
|
||||
if ( pos == PARSER_MAX_TOKEN_LENGTH - 1 ) {
|
||||
token[pos] = 0;
|
||||
sprintf( parser_sub_error, "token exceeds limit" );
|
||||
return 0;
|
||||
}
|
||||
FILE_READCHAR( file, c );
|
||||
}
|
||||
token[pos] = 0;
|
||||
if ( feof( file ) )
|
||||
return 1;
|
||||
fseek( file, -1, SEEK_CUR );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Skip all tokens until one begins with character 'stop'. This
|
||||
token is also ignored.
|
||||
====================================================================
|
||||
*/
|
||||
static void file_skip_section( FILE *file, char stop )
|
||||
{
|
||||
char token[PARSER_MAX_TOKEN_LENGTH];
|
||||
do {
|
||||
file_read_token_intern( file, PARSER_SYMBOLS, token );
|
||||
} while ( !feof( file ) && token[0] != stop );
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Read next token and skip comments enclosed in tokens
|
||||
skip[0], skip[1] (if skip is not NULL).
|
||||
Return 0 if EoF.
|
||||
====================================================================
|
||||
*/
|
||||
static int file_read_token( FILE *file, char *symbols, char *skip, char *token )
|
||||
{
|
||||
while ( 1 ) {
|
||||
if ( !file_read_token_intern( file, symbols, token ) )
|
||||
return 0;
|
||||
if ( skip ) {
|
||||
if ( token[0] == skip[0] )
|
||||
file_skip_section( file, skip[1] );
|
||||
else
|
||||
break;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Remove quotes if any and return result as newly allocated string.
|
||||
====================================================================
|
||||
*/
|
||||
static char* parser_remove_quotes( char *string )
|
||||
{
|
||||
char *new;
|
||||
if ( string[0] != '"' )
|
||||
return strdup( string );
|
||||
new = calloc( strlen( string ) - 1, sizeof( char ) );
|
||||
strncpy( new, string + 1, strlen( string ) - 2 );
|
||||
new[strlen( string ) - 2] = 0;
|
||||
return new;
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Proceed in the given string until it ends or non-whitespace occurs
|
||||
and return the new position.
|
||||
====================================================================
|
||||
*/
|
||||
static char* string_ignore_whitespace( char *string )
|
||||
{
|
||||
int i = 0;
|
||||
while ( string[i] != 0 && string[i] <= 32 ) i++;
|
||||
return string + i;
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
This function searches file from the current position for the next
|
||||
pdata entry.
|
||||
====================================================================
|
||||
*/
|
||||
static PData* parser_parse_file( FILE *file )
|
||||
{
|
||||
char token[PARSER_MAX_TOKEN_LENGTH];
|
||||
PData *pd = 0, *sub = 0;
|
||||
|
||||
/* get name */
|
||||
if ( !file_read_token( file, PARSER_SYMBOLS, PARSER_SKIP_SYMBOLS, token ) )
|
||||
return 0;
|
||||
if ( is_symbol( token[0], PARSER_SYMBOLS ) ) {
|
||||
sprintf( parser_sub_error, "parse error before '%s'", token );
|
||||
return 0;
|
||||
}
|
||||
pd = calloc( 1, sizeof( PData ) );
|
||||
pd->name = parser_remove_quotes( token );
|
||||
/* check type */
|
||||
if ( !file_read_token( file, PARSER_SYMBOLS, PARSER_SKIP_SYMBOLS, token ) )
|
||||
goto failure;
|
||||
switch ( token[0] ) {
|
||||
case PARSER_SET:
|
||||
/* assign single value or list */
|
||||
pd->values = list_create( LIST_AUTO_DELETE, LIST_NO_CALLBACK );
|
||||
if ( !file_read_token( file, PARSER_SYMBOLS, PARSER_SKIP_SYMBOLS, token ) )
|
||||
goto failure;
|
||||
if ( token[0] != PARSER_LIST_BEGIN ) {
|
||||
if ( is_symbol( token[0], PARSER_SYMBOLS ) ) {
|
||||
sprintf( parser_sub_error, "parse error before '%s'", token );
|
||||
goto failure;
|
||||
}
|
||||
else
|
||||
list_add( pd->values, parser_remove_quotes( token ) );
|
||||
}
|
||||
else {
|
||||
if ( !file_read_token( file, PARSER_SYMBOLS, PARSER_SKIP_SYMBOLS, token ) )
|
||||
goto failure;
|
||||
while ( token[0] != PARSER_LIST_END ) {
|
||||
if ( is_symbol( token[0], PARSER_SYMBOLS ) ) {
|
||||
sprintf( parser_sub_error, "parse error before '%s'", token );
|
||||
goto failure;
|
||||
}
|
||||
else
|
||||
list_add( pd->values, parser_remove_quotes( token ) );
|
||||
if ( !file_read_token( file, PARSER_SYMBOLS, PARSER_SKIP_SYMBOLS, token ) )
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PARSER_GROUP_BEGIN:
|
||||
/* check all entries until PARSER_GROUP_END */
|
||||
pd->entries = list_create( LIST_NO_AUTO_DELETE, LIST_NO_CALLBACK );
|
||||
while ( 1 ) {
|
||||
if ( !file_read_token( file, PARSER_SYMBOLS, PARSER_SKIP_SYMBOLS, token ) )
|
||||
goto failure;
|
||||
if ( token[0] == PARSER_GROUP_END )
|
||||
break;
|
||||
fseek( file, -strlen( token ), SEEK_CUR );
|
||||
sub = parser_parse_file( file );
|
||||
if ( sub )
|
||||
list_add( pd->entries, sub );
|
||||
else
|
||||
goto failure;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
sprintf( parser_sub_error, "parse error before '%s'", token );
|
||||
goto failure;
|
||||
}
|
||||
return pd;
|
||||
failure:
|
||||
parser_free( &pd );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Publics
|
||||
====================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
This function splits a string into tokens using the characters
|
||||
found in symbols as breakpoints. If the first symbol is ' ' all
|
||||
whitespaces are used as breakpoints though NOT added as a token
|
||||
(thus removed from string).
|
||||
====================================================================
|
||||
*/
|
||||
List* parser_split_string( char *string, char *symbols )
|
||||
{
|
||||
int pos;
|
||||
char *token = 0;
|
||||
List *list = list_create( LIST_AUTO_DELETE, LIST_NO_CALLBACK );
|
||||
while ( string[0] != 0 ) {
|
||||
if ( symbols[0] == ' ' )
|
||||
string = string_ignore_whitespace( string );
|
||||
if ( string[0] == 0 ) break;
|
||||
pos = 1; /* 'read in' first character */
|
||||
while ( string[pos - 1] != 0 && !is_symbol( string[pos - 1], symbols ) && string[pos - 1] != '"' ) pos++;
|
||||
if ( pos > 1 )
|
||||
pos--;
|
||||
else
|
||||
if ( string[pos - 1] == '"' ) {
|
||||
/* read a string */
|
||||
string = string + 1; pos = 0;
|
||||
while ( string[pos] != 0 && string[pos] != '"' ) pos++;
|
||||
token = calloc( pos + 1, sizeof( char ) );
|
||||
strncpy( token, string, pos ); token[pos] = 0;
|
||||
list_add( list, token );
|
||||
string = string + pos + (string[pos] != 0);
|
||||
continue;
|
||||
}
|
||||
token = calloc( pos + 1, sizeof( char ) );
|
||||
strncpy( token, string, pos); token[pos] = 0;
|
||||
list_add( list, token );
|
||||
string = string + pos;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
/*
|
||||
====================================================================
|
||||
This is the light version of parser_split_string which checks for
|
||||
just one character and does not add this glue characters to the
|
||||
list. It's about 2% faster. Wow.
|
||||
====================================================================
|
||||
*/
|
||||
List *parser_explode_string( char *string, char c )
|
||||
{
|
||||
List *list = list_create( LIST_AUTO_DELETE, LIST_NO_CALLBACK );
|
||||
char *next_slash = 0;
|
||||
char buffer[64];
|
||||
while ( string[0] != 0 && ( next_slash = strchr( string, c ) ) != 0 ) {
|
||||
if ( next_slash != string ) {
|
||||
strcpy_lt( buffer, string, (next_slash-string>63)?63:(next_slash-string) );
|
||||
list_add( list, strdup( buffer ) );
|
||||
}
|
||||
string += next_slash - string + 1;
|
||||
}
|
||||
if ( string[0] != 0 )
|
||||
list_add( list, strdup( string ) );
|
||||
return list;
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
This function reads in a whole file and converts it into a
|
||||
PData tree struct. If an error occurs NULL is returned and
|
||||
parser_error is set.
|
||||
====================================================================
|
||||
*/
|
||||
static int parser_read_file_full( FILE *file, PData *top )
|
||||
{
|
||||
PData *sub = 0;
|
||||
char token[1024];
|
||||
/* parse file */
|
||||
while ( !feof( file ) ) {
|
||||
if ( ( sub = parser_parse_file( file ) ) != 0 )
|
||||
list_add( top->entries, sub );
|
||||
else
|
||||
return 0;
|
||||
/* skip comments and whitespaces */
|
||||
if ( !file_read_token( file, PARSER_SYMBOLS, PARSER_SKIP_SYMBOLS, token ) ) {
|
||||
if ( token[0] != 0 )
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
else
|
||||
fseek( file, -strlen( token ), SEEK_CUR );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
static int parser_read_file_compact( PData *section )
|
||||
{
|
||||
/* section is the parent pdata that needs some
|
||||
entries */
|
||||
PData *pd = 0;
|
||||
char *line, *cur;
|
||||
while ( ( line = parser_get_next_line() ) ) {
|
||||
switch ( line[0] ) {
|
||||
case '>':
|
||||
/* this section is finished */
|
||||
return 1;
|
||||
case '<':
|
||||
/* add a whole subsection */
|
||||
pd = calloc( 1, sizeof( PData ) );
|
||||
pd->name = strdup( line + 1 );
|
||||
pd->entries = list_create( LIST_NO_AUTO_DELETE, LIST_NO_CALLBACK );
|
||||
parser_read_file_compact( pd );
|
||||
/* add to section */
|
||||
list_add( section->entries, pd );
|
||||
break;
|
||||
default:
|
||||
/* read values as subsection */
|
||||
pd = calloc( 1, sizeof( PData ) );
|
||||
/* check name */
|
||||
if ( ( cur = strchr( line, '»' ) ) == 0 ) {
|
||||
sprintf( parser_sub_error, "parse error: use '»' for assignment or '<' for section" );
|
||||
return 0;
|
||||
}
|
||||
cur[0] = 0; cur++;
|
||||
pd->name = strdup( line );
|
||||
/* get values */
|
||||
pd->values = parser_explode_string( cur, '°' );
|
||||
/* add to section */
|
||||
list_add( section->entries, pd );
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
PData* parser_read_file( char *tree_name, char *fname )
|
||||
{
|
||||
int size;
|
||||
char magic = 0;
|
||||
FILE *file = 0;
|
||||
PData *top = 0;
|
||||
/* open file */
|
||||
if ( ( file = fopen( fname, "r" ) ) == 0 ) {
|
||||
sprintf( parser_error, "%s: file not found", fname );
|
||||
return 0;
|
||||
}
|
||||
/* create top level pdata */
|
||||
top = calloc( 1, sizeof( PData ) );
|
||||
top->name = strdup( tree_name );
|
||||
top->entries = list_create( LIST_NO_AUTO_DELETE, LIST_NO_CALLBACK );
|
||||
/* parse */
|
||||
FILE_READCHAR( file, magic );
|
||||
if ( magic == '@' ) {
|
||||
/* get the whole contents -- 1 and CBUFFER_SIZE are switched */
|
||||
fseek( file, 0, SEEK_END ); size = ftell( file ) - 2;
|
||||
if ( size >= CBUFFER_SIZE ) {
|
||||
fprintf( stderr, "%s: file's too big to fit the compact buffer (128KB)\n", fname );
|
||||
size = CBUFFER_SIZE - 1;
|
||||
}
|
||||
fseek( file, 2, SEEK_SET );
|
||||
fread( cbuffer, 1, size, file );
|
||||
cbuffer[size] = 0;
|
||||
/* set indicator to beginning of text */
|
||||
cbuffer_pos = cbuffer;
|
||||
/* parse cbuffer */
|
||||
if ( !parser_read_file_compact( top ) ) {
|
||||
parser_set_parse_error( fname, file, parser_sub_error );
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
else {
|
||||
fseek( file, 0, SEEK_SET );
|
||||
if ( !parser_read_file_full( file, top ) ) {
|
||||
parser_set_parse_error( fname, file, parser_sub_error );
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
/* finalize */
|
||||
fclose( file );
|
||||
return top;
|
||||
failure:
|
||||
fclose( file );
|
||||
parser_free( &top );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
This function frees a PData tree struct.
|
||||
====================================================================
|
||||
*/
|
||||
void parser_free( PData **pdata )
|
||||
{
|
||||
PData *entry = 0;
|
||||
if ( (*pdata) == 0 ) return;
|
||||
if ( (*pdata)->name ) free( (*pdata)->name );
|
||||
if ( (*pdata)->values ) list_delete( (*pdata)->values );
|
||||
if ( (*pdata)->entries ) {
|
||||
list_reset( (*pdata)->entries );
|
||||
while ( ( entry = list_next( (*pdata)->entries ) ) )
|
||||
parser_free( &entry );
|
||||
list_delete( (*pdata)->entries );
|
||||
}
|
||||
free( *pdata ); *pdata = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Functions to access a PData tree.
|
||||
'name' is the pass within tree 'pd' where subtrees are separated
|
||||
by '/' (e.g.: name = 'config/graphics/animations')
|
||||
parser_get_pdata : get pdata entry associated with 'name'
|
||||
parser_get_entries : get list of subtrees (PData structs) in 'name'
|
||||
parser_get_values : get value list of 'name'
|
||||
parser_get_value : get a single value from value list of 'name'
|
||||
parser_get_int : get first value of 'name' converted to integer
|
||||
parser_get_double : get first value of 'name' converted to double
|
||||
parser_get_string : get first value of 'name' _duplicated_
|
||||
If an error occurs result is set NULL, False is returned and
|
||||
parse_error is set.
|
||||
====================================================================
|
||||
*/
|
||||
int parser_get_pdata ( PData *pd, char *name, PData **result )
|
||||
{
|
||||
int i, found;
|
||||
PData *pd_next = pd;
|
||||
PData *entry = 0;
|
||||
char *sub = 0;
|
||||
List *path = parser_explode_string( name, '/' );
|
||||
for ( i = 0, list_reset( path ); i < path->count; i++ ) {
|
||||
sub = list_next( path );
|
||||
if ( !pd_next->entries ) {
|
||||
sprintf( parser_sub_error, "%s: no subtrees", pd_next->name );
|
||||
goto failure;
|
||||
}
|
||||
list_reset( pd_next->entries ); found = 0;
|
||||
while ( ( entry = list_next( pd_next->entries ) ) )
|
||||
if ( strlen( entry->name ) == strlen( sub ) && !strncmp( entry->name, sub, strlen( sub ) ) ) {
|
||||
pd_next = entry;
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
if ( !found ) {
|
||||
sprintf( parser_sub_error, "%s: subtree '%s' not found", pd_next->name, sub );
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
list_delete( path );
|
||||
*result = pd_next;
|
||||
return 1;
|
||||
failure:
|
||||
sprintf( parser_error, "parser_get_pdata: %s/%s: %s", pd->name, name, parser_sub_error );
|
||||
list_delete( path );
|
||||
*result = 0;
|
||||
return 0;
|
||||
}
|
||||
int parser_get_entries( PData *pd, char *name, List **result )
|
||||
{
|
||||
PData *entry;
|
||||
*result = 0;
|
||||
if ( !parser_get_pdata( pd, name, &entry ) ) {
|
||||
sprintf( parser_sub_error, "parser_get_entries:\n %s", parser_error );
|
||||
strcpy( parser_error, parser_sub_error );
|
||||
return 0;
|
||||
}
|
||||
if ( !entry->entries || entry->entries->count == 0 ) {
|
||||
sprintf( parser_error, "parser_get_entries: %s/%s: no subtrees", pd->name, name );
|
||||
return 0;
|
||||
}
|
||||
*result = entry->entries;
|
||||
return 1;
|
||||
}
|
||||
int parser_get_values ( PData *pd, char *name, List **result )
|
||||
{
|
||||
PData *entry;
|
||||
*result = 0;
|
||||
if ( !parser_get_pdata( pd, name, &entry ) ) {
|
||||
sprintf( parser_sub_error, "parser_get_values:\n %s", parser_error );
|
||||
strcpy( parser_error, parser_sub_error );
|
||||
return 0;
|
||||
}
|
||||
if ( !entry->values || entry->values->count == 0 ) {
|
||||
sprintf( parser_error, "parser_get_values: %s/%s: no values", pd->name, name );
|
||||
return 0;
|
||||
}
|
||||
*result = entry->values;
|
||||
return 1;
|
||||
}
|
||||
int parser_get_value ( PData *pd, char *name, char **result, int index )
|
||||
{
|
||||
List *values;
|
||||
if ( !parser_get_values( pd, name, &values ) ) {
|
||||
sprintf( parser_sub_error, "parser_get_value:\n %s", parser_error );
|
||||
strcpy( parser_error, parser_sub_error );
|
||||
return 0;
|
||||
}
|
||||
if ( index >= values->count ) {
|
||||
sprintf( parser_error, "parser_get_value: %s/%s: index %i out of range (%i elements)",
|
||||
pd->name, name, index, values->count );
|
||||
return 0;
|
||||
}
|
||||
*result = list_get( values, index );
|
||||
return 1;
|
||||
}
|
||||
int parser_get_int ( PData *pd, char *name, int *result )
|
||||
{
|
||||
char *value;
|
||||
if ( !parser_get_value( pd, name, &value, 0 ) ) {
|
||||
sprintf( parser_sub_error, "parser_get_int:\n %s", parser_error );
|
||||
strcpy( parser_error, parser_sub_error );
|
||||
return 0;
|
||||
}
|
||||
*result = atoi( value );
|
||||
return 1;
|
||||
}
|
||||
int parser_get_double ( PData *pd, char *name, double *result )
|
||||
{
|
||||
char *value;
|
||||
if ( !parser_get_value( pd, name, &value, 0 ) ) {
|
||||
sprintf( parser_sub_error, "parser_get_double:\n %s", parser_error );
|
||||
strcpy( parser_error, parser_sub_error );
|
||||
return 0;
|
||||
}
|
||||
*result = strtod( value, 0 );
|
||||
return 1;
|
||||
}
|
||||
int parser_get_string ( PData *pd, char *name, char **result )
|
||||
{
|
||||
char *value;
|
||||
if ( !parser_get_value( pd, name, &value, 0 ) ) {
|
||||
sprintf( parser_sub_error, "parser_get_string:\n %s", parser_error );
|
||||
strcpy( parser_error, parser_sub_error );
|
||||
return 0;
|
||||
}
|
||||
*result = strdup( value );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
If an error occurred you can query the reason with this function.
|
||||
====================================================================
|
||||
*/
|
||||
char* parser_get_error( void )
|
||||
{
|
||||
return parser_error;
|
||||
}
|
||||
|
||||
150
project/jni/application/lbreakout2/common/parser.h
Normal file
150
project/jni/application/lbreakout2/common/parser.h
Normal file
@@ -0,0 +1,150 @@
|
||||
/***************************************************************************
|
||||
parser.h - description
|
||||
-------------------
|
||||
begin : Sat Mar 9 2002
|
||||
copyright : (C) 2001 by Michael Speck
|
||||
email : kulkanie@gmx.net
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __PARSER_H
|
||||
#define __PARSER_H
|
||||
|
||||
#include "list.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
This module provides functions to parse ASCII data from strings
|
||||
and files.
|
||||
Synopsis:
|
||||
groupname <begin group> entry1 .. entryX <end group>
|
||||
variable <set> value
|
||||
A group entry may either be a variable or a group (interlacing).
|
||||
A variable value may either be a single token or a list of tokens
|
||||
enclosed by <begin list> <end list>.
|
||||
Text enclosed by ".." is counted as a single token.
|
||||
====================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Symbols.
|
||||
Note: These symbols are ignored when found in a token "<expression>"
|
||||
as they belong to this token then.
|
||||
PARSER_GROUP_BEGIN: <begin group>
|
||||
PARSER_GROUP_END: <end group>
|
||||
PARSER_SET: <set>
|
||||
PARSER_LIST_BEGIN: <begin list>
|
||||
PARSER_LIST_END: <end list>
|
||||
PARSER_COMMENT_BEGIN: <begin comment>
|
||||
PARSER_COMMENT_END: <end comment>
|
||||
PARSER_SYMBOLS: List of all symbols + whitespace used to
|
||||
split strings and tokens.
|
||||
PARSER_SKIP_SYMBOLS: text bewteen these two symbols is handled as
|
||||
comment and therefore completely ignored
|
||||
====================================================================
|
||||
*/
|
||||
#define PARSER_GROUP_BEGIN '{'
|
||||
#define PARSER_GROUP_END '}'
|
||||
#define PARSER_SET '='
|
||||
#define PARSER_LIST_BEGIN '('
|
||||
#define PARSER_LIST_END ')'
|
||||
#define PARSER_COMMENT_BEGIN '['
|
||||
#define PARSER_COMMENT_END ']'
|
||||
#define PARSER_SYMBOLS " =(){}[]"
|
||||
#define PARSER_SKIP_SYMBOLS "[]"
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
An input string is converted into a PData tree struct.
|
||||
The name identifies this entry and it's the token that is searched
|
||||
for when reading this entry.
|
||||
Either 'values' or 'entries' is set.
|
||||
If 'entries' is not NULL the PData is a group and 'entries'
|
||||
contains pointers to other groups or lists.
|
||||
If 'values' is not NULL the PData is a list and 'values' contains
|
||||
a list of value strings associated with 'name'.
|
||||
====================================================================
|
||||
*/
|
||||
typedef struct {
|
||||
char *name;
|
||||
List *values;
|
||||
List *entries;
|
||||
} PData;
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
This function splits a string into tokens using the characters
|
||||
found in symbols as breakpoints. If the first symbol is ' ' all
|
||||
whitespaces are used as breakpoints though NOT added as a token
|
||||
(thus removed from string).
|
||||
====================================================================
|
||||
*/
|
||||
List* parser_split_string( char *string, char *symbols );
|
||||
/*
|
||||
====================================================================
|
||||
This is the light version of parser_split_string which checks for
|
||||
just one character and does not add this glue characters to the
|
||||
list. It's about 2% faster. Wow.
|
||||
====================================================================
|
||||
*/
|
||||
List *parser_explode_string( char *string, char c );
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
This function reads in a whole file and converts it into a
|
||||
PData tree struct. If an error occurs NULL is returned and
|
||||
parser_error is set. 'tree_name' is the name of the PData tree.
|
||||
====================================================================
|
||||
*/
|
||||
PData* parser_read_file( char *tree_name, char *fname );
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
This function frees a PData tree struct.
|
||||
====================================================================
|
||||
*/
|
||||
void parser_free( PData **pdata );
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Functions to access a PData tree.
|
||||
'name' is the pass within tree 'pd' where subtrees are separated
|
||||
by '/' (e.g.: name = 'config/graphics/animations')
|
||||
parser_get_pdata : get pdata entry associated with 'name'
|
||||
parser_get_entries : get list of subtrees (PData structs) in 'name'
|
||||
parser_get_values : get value list of 'name'
|
||||
parser_get_value : get a single value from value list of 'name'
|
||||
parser_get_int : get first value of 'name' converted to integer
|
||||
parser_get_double : get first value of 'name' converted to double
|
||||
parser_get_string : get first value of 'name' _duplicated_
|
||||
If an error occurs result is set NULL, False is returned and
|
||||
parse_error is set.
|
||||
====================================================================
|
||||
*/
|
||||
int parser_get_pdata ( PData *pd, char *name, PData **result );
|
||||
int parser_get_entries( PData *pd, char *name, List **result );
|
||||
int parser_get_values ( PData *pd, char *name, List **result );
|
||||
int parser_get_value ( PData *pd, char *name, char **result, int index );
|
||||
int parser_get_int ( PData *pd, char *name, int *result );
|
||||
int parser_get_double ( PData *pd, char *name, double *result );
|
||||
int parser_get_string ( PData *pd, char *name, char **result );
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
If an error occurred you can query the message with this function.
|
||||
====================================================================
|
||||
*/
|
||||
char* parser_get_error( void );
|
||||
|
||||
#endif
|
||||
385
project/jni/application/lbreakout2/common/tools.c
Normal file
385
project/jni/application/lbreakout2/common/tools.c
Normal file
@@ -0,0 +1,385 @@
|
||||
/***************************************************************************
|
||||
tools.c - description
|
||||
-------------------
|
||||
begin : Fri Jan 19 2001
|
||||
copyright : (C) 2001 by Michael Speck
|
||||
email : kulkanie@gmx.net
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "tools.h"
|
||||
|
||||
/* compares to strings and returns true if their first strlen(str1) chars are equal */
|
||||
int strequal( char *str1, char *str2 )
|
||||
{
|
||||
if ( strlen( str1 ) != strlen( str2 ) ) return 0;
|
||||
return ( !strncmp( str1, str2, strlen( str1 ) ) );
|
||||
}
|
||||
|
||||
/* set delay to ms milliseconds */
|
||||
void delay_set( Delay *delay, int ms )
|
||||
{
|
||||
delay->limit = ms;
|
||||
delay->cur = 0;
|
||||
}
|
||||
|
||||
/* reset delay ( cur = 0 )*/
|
||||
void delay_reset( Delay *delay )
|
||||
{
|
||||
delay->cur = 0;
|
||||
}
|
||||
|
||||
/* check if times out and reset */
|
||||
int delay_timed_out( Delay *delay, int ms )
|
||||
{
|
||||
delay->cur += ms;
|
||||
if ( delay->cur >= delay->limit ) {
|
||||
|
||||
delay->cur = 0;
|
||||
return 1;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void goto_tile( int *x, int *y, int d )
|
||||
{
|
||||
/* 0 -up, clockwise, 5 - left up */
|
||||
switch ( d ) {
|
||||
|
||||
case 1:
|
||||
if ( !( (*x) & 1 ) )
|
||||
(*y)--;
|
||||
(*x)++;
|
||||
break;
|
||||
case 2:
|
||||
if ( (*x) & 1 )
|
||||
(*y)++;
|
||||
(*x)++;
|
||||
break;
|
||||
case 4:
|
||||
if ( (*x) & 1 )
|
||||
(*y)++;
|
||||
(*x)--;
|
||||
break;
|
||||
case 5:
|
||||
if ( !( (*x) & 1 ) )
|
||||
(*y)--;
|
||||
(*x)--;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* return distance between to map positions */
|
||||
int get_dist( int x1, int y1, int x2, int y2 )
|
||||
{
|
||||
int range = 0;
|
||||
|
||||
while ( x1 != x2 || y1 != y2 ) {
|
||||
|
||||
/* approach to x2,y2 */
|
||||
/* 0 -up, clockwise, 5 - left up */
|
||||
if ( y1 < y2 ) {
|
||||
|
||||
if ( x1 < x2 )
|
||||
goto_tile( &x1, &y1, 2 );
|
||||
else
|
||||
if ( x1 > x2 )
|
||||
goto_tile( &x1, &y1, 4 );
|
||||
else
|
||||
y1++;
|
||||
|
||||
}
|
||||
else
|
||||
if ( y1 > y2 ) {
|
||||
|
||||
if ( x1 < x2 )
|
||||
goto_tile( &x1, &y1, 1 );
|
||||
else
|
||||
if ( x1 > x2 )
|
||||
goto_tile( &x1, &y1, 5 );
|
||||
else
|
||||
y1--;
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
if ( x1 < x2 )
|
||||
x1++;
|
||||
else
|
||||
if ( x1 > x2 )
|
||||
x1--;
|
||||
|
||||
}
|
||||
|
||||
range++;
|
||||
}
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
/* init random seed by using ftime */
|
||||
void set_random_seed()
|
||||
{
|
||||
srand( (unsigned int)time( 0 ) );
|
||||
}
|
||||
|
||||
/* get coordinates from string */
|
||||
void get_coord( char *str, int *x, int *y )
|
||||
{
|
||||
int i;
|
||||
char *cur_arg = 0;
|
||||
|
||||
*x = *y = 0;
|
||||
|
||||
/* get position of comma */
|
||||
for ( i = 0; i < strlen( str ); i++ )
|
||||
if ( str[i] == ',' ) break;
|
||||
if ( i == strlen( str ) ) {
|
||||
fprintf( stderr, "get_coord: no comma found in pair of coordinates '%s'\n", str );
|
||||
return; /* no comma found */
|
||||
}
|
||||
|
||||
/* y */
|
||||
cur_arg = str + i + 1;
|
||||
if ( cur_arg[0] == 0 )
|
||||
fprintf( stderr, "get_coord: warning: y-coordinate is empty (maybe you left a space between x and comma?)\n" );
|
||||
*y = atoi( cur_arg );
|
||||
/* x */
|
||||
cur_arg = strdup( str ); cur_arg[i] = 0;
|
||||
*x = atoi( cur_arg );
|
||||
FREE( cur_arg );
|
||||
}
|
||||
|
||||
/* replace new_lines with spaces in text */
|
||||
void repl_new_lines( char *text )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < strlen( text ); i++ )
|
||||
if ( text[i] < 32 )
|
||||
text[i] = 32;
|
||||
}
|
||||
|
||||
// convert a str into text ( for listbox ) //
|
||||
// char width is the width of a line in characters //
|
||||
Text* create_text( char *orig_str, int char_width )
|
||||
{
|
||||
int i, j;
|
||||
char line[256]; /* a line should not exceed this length */
|
||||
int pos;
|
||||
int last_space;
|
||||
int new_line;
|
||||
Text *text = 0;
|
||||
char *str = 0;
|
||||
|
||||
text = calloc ( 1, sizeof( Text ) );
|
||||
|
||||
// maybe orig_str is a constant expression; duplicate for safety //
|
||||
str = strdup( orig_str );
|
||||
|
||||
// replace original new_lines with spaces //
|
||||
repl_new_lines( str );
|
||||
|
||||
/* change some spaces to new_lines, so that the new text fits the wanted line_length */
|
||||
/* NOTE: '#' means new_line ! */
|
||||
// if character width is 0 it's just a single line //
|
||||
if ( char_width > 0 ) {
|
||||
pos = 0;
|
||||
while ( pos < strlen( str ) ) {
|
||||
last_space = 0;
|
||||
new_line = 0;
|
||||
i = 0;
|
||||
while ( !new_line && i < char_width && i + pos < strlen( str ) ) {
|
||||
switch ( str[pos + i] ) {
|
||||
case '#': new_line = 1;
|
||||
case 32: last_space = i; break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if ( i + pos >= strlen( str ) ) break;
|
||||
if ( last_space == 0 ) {
|
||||
/* uhh... much to long, we'll have to cut a word into pieces ... */
|
||||
last_space = char_width / 2;
|
||||
}
|
||||
str[pos + last_space] = 10;
|
||||
pos += last_space;
|
||||
}
|
||||
}
|
||||
|
||||
/* count lines */
|
||||
if ( char_width > 0 ) {
|
||||
for ( i = 0; i < strlen( str ); i++ )
|
||||
if ( str[i] == 10 )
|
||||
text->count++;
|
||||
/* maybe one unfinished line */
|
||||
if ( str[strlen( str ) - 1] != 10 )
|
||||
text->count++;
|
||||
}
|
||||
else
|
||||
text->count = 1;
|
||||
|
||||
/* get mem */
|
||||
text->lines = calloc( text->count, sizeof( char* ) );
|
||||
|
||||
pos = 0;
|
||||
/* get all lines */
|
||||
for ( j = 0; j < text->count; j++ ) {
|
||||
i = 0;
|
||||
while ( pos + i < strlen( str ) && str[pos + i] != 10 ) {
|
||||
line[i] = str[i + pos];
|
||||
i++;
|
||||
}
|
||||
pos += i; pos++;
|
||||
line[i] = 0;
|
||||
text->lines[j] = strdup( line );
|
||||
}
|
||||
|
||||
if ( text->count == 0 )
|
||||
fprintf( stderr, "conv_to_text: warning: line_count is 0\n" );
|
||||
|
||||
free( str );
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
// delete text //
|
||||
void delete_text( Text *text )
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( text == 0 ) return;
|
||||
/*
|
||||
if ( lines[1][1] == 'e' && lines[1][0] == '<' )
|
||||
printf( "hallo\n" );
|
||||
|
||||
printf( "--- deleting:\n" );
|
||||
for ( i = 0; i < line_count; i++ ) {
|
||||
printf( lines[i] );
|
||||
printf( "\n" );
|
||||
}*/
|
||||
if ( text->lines ) {
|
||||
for ( i = 0; i < text->count; i++ )
|
||||
if ( text->lines[i] )
|
||||
free( text->lines[i] );
|
||||
free( text->lines );
|
||||
}
|
||||
free( text );
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Get type and prefix from string:
|
||||
type::prefix
|
||||
Set both pointers 0 if failure.
|
||||
====================================================================
|
||||
*/
|
||||
void get_type_and_prefix( char *arg, char **type, char **prefix )
|
||||
{
|
||||
char *first, *second;
|
||||
|
||||
*type = *prefix = 0;
|
||||
|
||||
first = strtok( arg, ":" );
|
||||
second = strtok( 0, ":" );
|
||||
|
||||
if ( first == 0 || second == 0 ) return;
|
||||
|
||||
*type = strdup( first );
|
||||
*prefix = strdup( second );
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Replace any existence of character old into new.
|
||||
====================================================================
|
||||
*/
|
||||
void strrepl( char **str, char c_old, char c_new )
|
||||
{
|
||||
char *pos;
|
||||
while ( ( pos = strchr( *str, c_old ) ) != 0 )
|
||||
pos[0] = c_new;
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Copy source to dest and at maximum limit chars. Terminate with 0.
|
||||
====================================================================
|
||||
*/
|
||||
void strcpy_lt( char *dest, char *src, int limit )
|
||||
{
|
||||
int len = strlen( src );
|
||||
if ( len > limit ) {
|
||||
strncpy( dest, src, limit );
|
||||
dest[limit] = 0;
|
||||
}
|
||||
else
|
||||
strcpy( dest, src );
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Parse a version string and return the major version and the current
|
||||
update.
|
||||
====================================================================
|
||||
*/
|
||||
void parse_version( char *string, int *version, int *update )
|
||||
{
|
||||
char *ptr = strchr( string, '.' );
|
||||
if ( ptr ) ptr[0] = 0;
|
||||
*version = atoi( string );
|
||||
if ( ptr ) {
|
||||
ptr++;
|
||||
*update = atoi( ptr );
|
||||
if ( *update < 10 && ptr[0] != '0' )
|
||||
*update *= 10; /* allow stuff like 1.01 */
|
||||
ptr--;
|
||||
ptr[0] = '.';
|
||||
}
|
||||
else
|
||||
*update = 0;
|
||||
}
|
||||
|
||||
/* allocate memory or exit with error if out of it */
|
||||
void *salloc( int num, int size )
|
||||
{
|
||||
void *ptr = calloc( num, size );
|
||||
if ( ptr == 0 ) {
|
||||
printf( "out of memory\n" );
|
||||
exit(1);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* print contents of pointer raw */
|
||||
void print_raw( int len, char *buf )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < len; i++ )
|
||||
printf( "%02x ", (unsigned char) buf[i] );
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
/* check whether a string does only contain letters, digits or
|
||||
* underscores */
|
||||
int is_alphanum( char *str )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i< strlen(str); i++ )
|
||||
if ( !((str[i]>=48&&str[i]<=57)||(str[i]>=65&&str[i]<=90)||(str[i]>=97&&str[i]<=122)||str[i]=='_') )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
129
project/jni/application/lbreakout2/common/tools.h
Normal file
129
project/jni/application/lbreakout2/common/tools.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/***************************************************************************
|
||||
tools.h - description
|
||||
-------------------
|
||||
begin : Fri Jan 19 2001
|
||||
copyright : (C) 2001 by Michael Speck
|
||||
email : kulkanie@gmx.net
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef __TOOLS_H
|
||||
#define __TOOLS_H
|
||||
|
||||
/* this file contains some useful tools */
|
||||
|
||||
/* free with a check */
|
||||
#define FREE( ptr ) { if ( ptr ) free( ptr ); ptr = 0; }
|
||||
|
||||
/* check if a serious of flags is set in source */
|
||||
#define CHECK_FLAGS( source, flags ) ( source & (flags) )
|
||||
|
||||
/* return random value between ( and including ) upper,lower limit */
|
||||
#define RANDOM( lower, upper ) ( ( rand() % ( ( upper ) - ( lower ) + 1 ) ) + ( lower ) )
|
||||
|
||||
/* compute distance of two vectors */
|
||||
#define VEC_DIST( vec1, vec2 ) ( sqrt( ( vec1.x - vec2.x ) * ( vec1.x - vec2.x ) + ( vec1.y - vec2.y ) * ( vec1.y - vec2.y ) ) )
|
||||
|
||||
/* return true if strings are fully equal */
|
||||
#define STRCMP( str1, str2 ) ( ( strlen( str1 ) == strlen( str2 ) ) && !strncmp( str1, str2, strlen( str1 ) ) )
|
||||
|
||||
/* return minimum */
|
||||
#define MINIMUM( a, b ) ((a<b)?a:b)
|
||||
|
||||
/* return maximum */
|
||||
#define MAXIMUM( a, b ) ((a>b)?a:b)
|
||||
|
||||
/* square value */
|
||||
#define SQUARE( x ) ((x)*(x))
|
||||
|
||||
/* compares to strings and returns true if their first strlen(str1) chars are equal */
|
||||
int strequal( char *str1, char *str2 );
|
||||
|
||||
/* delete lines */
|
||||
void delete_lines( char **lines, int line_number );
|
||||
|
||||
/* delay struct */
|
||||
typedef struct {
|
||||
int limit;
|
||||
int cur;
|
||||
} Delay;
|
||||
|
||||
/* set delay to ms milliseconds */
|
||||
void delay_set( Delay *delay, int ms );
|
||||
|
||||
/* reset delay ( cur = 0 )*/
|
||||
void delay_reset( Delay *delay );
|
||||
|
||||
/* check if time's out ( add ms milliseconds )and reset */
|
||||
int delay_timed_out( Delay *delay, int ms );
|
||||
|
||||
/* return distance betwteen to map positions */
|
||||
int get_dist( int x1, int y1, int x2, int y2 );
|
||||
|
||||
/* init random seed by using ftime */
|
||||
void set_random_seed();
|
||||
|
||||
/* get coordintaes from string */
|
||||
void get_coord( char *str, int *x, int *y );
|
||||
|
||||
// text structure //
|
||||
typedef struct {
|
||||
char **lines;
|
||||
int count;
|
||||
} Text;
|
||||
// convert a str into text ( for listbox ) //
|
||||
Text* create_text( char *str, int char_width );
|
||||
// delete text //
|
||||
void delete_text( Text *text );
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Get type and prefix from string:
|
||||
type::prefix
|
||||
Set both pointers 0 if failure.
|
||||
====================================================================
|
||||
*/
|
||||
void get_type_and_prefix( char *arg, char **ext, char **prefix );
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Replace any existence of character old into new.
|
||||
====================================================================
|
||||
*/
|
||||
void strrepl( char **str, char c_old, char c_new );
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Copy source to dest and at maximum limit chars. Terminate with 0.
|
||||
====================================================================
|
||||
*/
|
||||
void strcpy_lt( char *dest, char *src, int limit );
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Parse a version string and return the major version and the current
|
||||
update.
|
||||
====================================================================
|
||||
*/
|
||||
void parse_version( char *string, int *version, int *update );
|
||||
|
||||
|
||||
/* allocate memory or exit with error if out of it */
|
||||
void *salloc( int num, int size );
|
||||
|
||||
/* print contents of pointer raw */
|
||||
void print_raw( int len, char *buf );
|
||||
|
||||
/* check whether a string does only contain letters, digits or
|
||||
* underscores */
|
||||
int is_alphanum( char *str );
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user