Mercurial > vba-clojure
changeset 28:2efb971df515
bringing in SDL package
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sun, 04 Mar 2012 21:06:50 -0600 |
parents | b970226568d2 |
children | 2fa26addb901 |
files | configure.ac src/AutoBuild.h src/Makefile.am src/sdl/Array.h src/sdl/Makefile src/sdl/Makefile.am src/sdl/RingBuffer.h src/sdl/SDL.cpp src/sdl/SoundDriver.h src/sdl/SoundSDL.cpp src/sdl/SoundSDL.h src/sdl/TestEmu.cpp src/sdl/Types.h src/sdl/debugger.cpp src/sdl/debugger.h src/sdl/expr-lex.cpp src/sdl/expr.cpp src/sdl/expr.cpp.h src/sdl/expr.l src/sdl/expr.y src/sdl/exprNode.cpp src/sdl/exprNode.h src/sdl/getopt.c src/sdl/getopt.h src/sdl/getopt1.c |
diffstat | 25 files changed, 11346 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
1.1 --- a/configure.ac Sun Mar 04 20:32:31 2012 -0600 1.2 +++ b/configure.ac Sun Mar 04 21:06:50 2012 -0600 1.3 @@ -27,7 +27,8 @@ 1.4 1.5 1.6 # Checks for header files. 1.7 -AC_CHECK_HEADERS([arpa/inet.h limits.h locale.h malloc.h netdb.h netinet/in.h stddef.h stdint.h stdlib.h string.h strings.h sys/socket.h unistd.h]) 1.8 +AC_FUNC_ALLOCA 1.9 +AC_CHECK_HEADERS([arpa/inet.h limits.h locale.h malloc.h netdb.h netinet/in.h stddef.h stdint.h stdlib.h string.h strings.h sys/socket.h unistd.h libintl.h]) 1.10 1.11 # Checks for typedefs, structures, and compiler characteristics. 1.12 AC_HEADER_STDBOOL 1.13 @@ -52,9 +53,6 @@ 1.14 AC_FUNC_STRCOLL 1.15 AC_CHECK_FUNCS([floor ftruncate gethostbyname gethostname inet_ntoa localeconv memchr memset modf pow setlocale socket sqrt strcasecmp strchr strcspn strdup strerror strpbrk strrchr strstr strtoul]) 1.16 1.17 - 1.18 - 1.19 - 1.20 AC_CONFIG_FILES([Makefile 1.21 src/Makefile 1.22 src/lua/Makefile 1.23 @@ -62,7 +60,8 @@ 1.24 src/gba/Makefile 1.25 src/common/Makefile 1.26 src/SFMT/Makefile 1.27 - src/filters/Makefile]) 1.28 + src/filters/Makefile 1.29 + src/sdl/Makefile]) 1.30 1.31 1.32
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/src/AutoBuild.h Sun Mar 04 21:06:50 2012 -0600 2.3 @@ -0,0 +1,30 @@ 2.4 +// -*- C++ -*- 2.5 +// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. 2.6 +// Copyright (C) 1999-2003 Forgotten 2.7 +// Copyright (C) 2004 Forgotten and the VBA development team 2.8 + 2.9 +// This program is free software; you can redistribute it and/or modify 2.10 +// it under the terms of the GNU General Public License as published by 2.11 +// the Free Software Foundation; either version 2, or(at your option) 2.12 +// any later version. 2.13 +// 2.14 +// This program is distributed in the hope that it will be useful, 2.15 +// but WITHOUT ANY WARRANTY; without even the implied warranty of 2.16 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 2.17 +// GNU General Public License for more details. 2.18 +// 2.19 +// You should have received a copy of the GNU General Public License 2.20 +// along with this program; if not, write to the Free Software Foundation, 2.21 +// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 2.22 + 2.23 +#ifndef __AUTOBUILD_H__ 2.24 +#define __AUTOBUILD_H__ 2.25 +#include "version.h" 2.26 +//change the FALSE to TRUE for autoincrement of build number 2.27 +#define INCREMENT_VERSION FALSE 2.28 +#define FILEVER 1,8,0,600 2.29 +#define PRODUCTVER 1,8,0,600 2.30 +#define STRFILEVER "1, 8, 0, 600\0" 2.31 +#define STRPRODUCTVER "1, 8, 0, 600\0" 2.32 +#endif //__AUTOBUILD_H__ 2.33 +
3.1 --- a/src/Makefile.am Sun Mar 04 20:32:31 2012 -0600 3.2 +++ b/src/Makefile.am Sun Mar 04 21:06:50 2012 -0600 3.3 @@ -1,3 +1,3 @@ 3.4 -SUBDIRS = SFMT lua gb gba common filters 3.5 +SUBDIRS = SFMT lua gb gba common filters sdl 3.6 3.7 -noinst_HEADERS = Port.h NLS.h 3.8 +noinst_HEADERS = Port.h NLS.h AutoBuild.h
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/src/sdl/Array.h Sun Mar 04 21:06:50 2012 -0600 4.3 @@ -0,0 +1,40 @@ 4.4 +/*************************************************************************** 4.5 + * Copyright (C) 2008 by Sindre Aam�s * 4.6 + * aamas@stud.ntnu.no * 4.7 + * * 4.8 + * This program is free software; you can redistribute it and/or modify * 4.9 + * it under the terms of the GNU General Public License version 2 as * 4.10 + * published by the Free Software Foundation. * 4.11 + * * 4.12 + * This program is distributed in the hope that it will be useful, * 4.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of * 4.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 4.15 + * GNU General Public License version 2 for more details. * 4.16 + * * 4.17 + * You should have received a copy of the GNU General Public License * 4.18 + * version 2 along with this program; if not, write to the * 4.19 + * Free Software Foundation, Inc., * 4.20 + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 4.21 + ***************************************************************************/ 4.22 +#ifndef ARRAY_H 4.23 +#define ARRAY_H 4.24 + 4.25 +#include <cstddef> 4.26 + 4.27 +template<typename T> 4.28 +class Array { 4.29 + T *a; 4.30 + std::size_t sz; 4.31 + 4.32 + Array(const Array &ar); 4.33 + 4.34 +public: 4.35 + Array(const std::size_t size = 0) : a(size ? new T[size] : 0), sz(size) {} 4.36 + ~Array() { delete []a; } 4.37 + void reset(const std::size_t size) { delete []a; a = size ? new T[size] : 0; sz = size; } 4.38 + std::size_t size() const { return sz; } 4.39 + operator T*() { return a; } 4.40 + operator const T*() const { return a; } 4.41 +}; 4.42 + 4.43 +#endif
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/src/sdl/Makefile Sun Mar 04 21:06:50 2012 -0600 5.3 @@ -0,0 +1,552 @@ 5.4 +# Makefile.in generated by automake 1.10.1 from Makefile.am. 5.5 +# src/sdl/Makefile. Generated from Makefile.in by configure. 5.6 + 5.7 +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 5.8 +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. 5.9 +# This Makefile.in is free software; the Free Software Foundation 5.10 +# gives unlimited permission to copy and/or distribute it, 5.11 +# with or without modifications, as long as this notice is preserved. 5.12 + 5.13 +# This program is distributed in the hope that it will be useful, 5.14 +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without 5.15 +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A 5.16 +# PARTICULAR PURPOSE. 5.17 + 5.18 + 5.19 + 5.20 + 5.21 +pkgdatadir = $(datadir)/VisualBoyAdvance 5.22 +pkglibdir = $(libdir)/VisualBoyAdvance 5.23 +pkgincludedir = $(includedir)/VisualBoyAdvance 5.24 +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd 5.25 +install_sh_DATA = $(install_sh) -c -m 644 5.26 +install_sh_PROGRAM = $(install_sh) -c 5.27 +install_sh_SCRIPT = $(install_sh) -c 5.28 +INSTALL_HEADER = $(INSTALL_DATA) 5.29 +transform = $(program_transform_name) 5.30 +NORMAL_INSTALL = : 5.31 +PRE_INSTALL = : 5.32 +POST_INSTALL = : 5.33 +NORMAL_UNINSTALL = : 5.34 +PRE_UNINSTALL = : 5.35 +POST_UNINSTALL = : 5.36 +build_triplet = x86_64-unknown-linux-gnu 5.37 +host_triplet = x86_64-unknown-linux-gnu 5.38 +target_triplet = x86_64-unknown-linux-gnu 5.39 +bin_PROGRAMS = VisualBoyAdvance$(EXEEXT) 5.40 +noinst_PROGRAMS = TestEmu$(EXEEXT) 5.41 +subdir = src/sdl 5.42 +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in 5.43 +OBJDIR = $(top_srcdir)/src/obj 5.44 +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 5.45 +am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \ 5.46 + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/lib-ld.m4 \ 5.47 + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ 5.48 + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ 5.49 + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/acinclude.m4 \ 5.50 + $(top_srcdir)/configure.in 5.51 +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ 5.52 + $(ACLOCAL_M4) 5.53 +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs 5.54 +CONFIG_CLEAN_FILES = 5.55 +am__installdirs = "$(DESTDIR)$(bindir)" 5.56 +binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) 5.57 +PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) 5.58 +am_TestEmu_OBJECTS = TestEmu.$(OBJEXT) debugger.$(OBJEXT) \ 5.59 + expr-lex.$(OBJEXT) expr.$(OBJEXT) exprNode.$(OBJEXT) 5.60 +TestEmu_OBJECTS = $(am_TestEmu_OBJECTS) 5.61 +am_VisualBoyAdvance_OBJECTS = SDL.$(OBJEXT) debugger.$(OBJEXT) \ 5.62 + expr-lex.$(OBJEXT) expr.$(OBJEXT) exprNode.$(OBJEXT) \ 5.63 + getopt.$(OBJEXT) getopt1.$(OBJEXT) SoundSDL.$(OBJEXT) 5.64 +VisualBoyAdvance_OBJECTS = $(patsubst %,$(OBJDIR)/%,$(am_VisualBoyAdvance_OBJECTS)) 5.65 +DEFAULT_INCLUDES = -I. 5.66 +depcomp = $(SHELL) $(top_srcdir)/depcomp 5.67 +am__depfiles_maybe = depfiles 5.68 +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ 5.69 + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) 5.70 +CCLD = $(CC) 5.71 +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ 5.72 +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ 5.73 + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) 5.74 +CXXLD = $(CXX) 5.75 +CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ 5.76 + -o $@ 5.77 +SOURCES = $(TestEmu_SOURCES) $(VisualBoyAdvance_SOURCES) 5.78 +DIST_SOURCES = $(TestEmu_SOURCES) $(VisualBoyAdvance_SOURCES) 5.79 +ETAGS = etags 5.80 +CTAGS = ctags 5.81 +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) 5.82 +ACLOCAL = ${SHELL} /home/r/proj/vba/trunk/missing --run aclocal-1.10 5.83 +AMTAR = ${SHELL} /home/r/proj/vba/trunk/missing --run tar 5.84 +AUTOCONF = ${SHELL} /home/r/proj/vba/trunk/missing --run autoconf 5.85 +AUTOHEADER = ${SHELL} /home/r/proj/vba/trunk/missing --run autoheader 5.86 +AUTOMAKE = ${SHELL} /home/r/proj/vba/trunk/missing --run automake-1.10 5.87 +AWK = gawk 5.88 +CC = gcc 5.89 +CCDEPMODE = depmode=gcc3 5.90 +CFLAGS = -g -O2 5.91 +CPP = gcc -E 5.92 +CPPFLAGS = 5.93 +CXX = g++ 5.94 +CXXDEPMODE = depmode=gcc3 5.95 +CXXFLAGS = -g -O2 -DC_CORE -DPROFILING -DDEV_VERSION 5.96 +CYGPATH_W = echo 5.97 +DEFS = -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DPACKAGE=\"VisualBoyAdvance\" -DVERSION=\"1.7.2\" -DYYTEXT_POINTER=1 -DHAVE_LIBZ=1 -DHAVE_LIBPNG=1 -DHAVE_LIBPTHREAD=1 -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_MALLOC_H=1 -DHAVE_STRINGS_H=1 -DHAVE_UNISTD_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_NETINET_IN_H=1 5.98 +DEPDIR = .deps 5.99 +ECHO_C = 5.100 +ECHO_N = -n 5.101 +ECHO_T = 5.102 +EGREP = /bin/grep -E 5.103 +EXEEXT = 5.104 +GETTEXT_PACKAGE = 5.105 +GMSGFMT = 5.106 +GREP = /bin/grep 5.107 +GTKMM_CFLAGS = 5.108 +GTKMM_CPPFLAGS = 5.109 +GTKMM_LIBS = 5.110 +INSTALL = /usr/bin/install -c 5.111 +INSTALL_DATA = ${INSTALL} -m 644 5.112 +INSTALL_PROGRAM = ${INSTALL} 5.113 +INSTALL_SCRIPT = ${INSTALL} 5.114 +INSTALL_STRIP_PROGRAM = $(install_sh) -c -s 5.115 +INTLLIBS = 5.116 +LDFLAGS = 5.117 +LEX = flex 5.118 +LEXLIB = -lfl 5.119 +LEX_OUTPUT_ROOT = lex.yy 5.120 +LIBICONV = 5.121 +LIBINTL = 5.122 +LIBOBJS = 5.123 +LIBS = -lpthread -lpng -lz 5.124 +LTLIBICONV = 5.125 +LTLIBINTL = 5.126 +LTLIBOBJS = 5.127 +MAKEINFO = ${SHELL} /home/r/proj/vba/trunk/missing --run makeinfo 5.128 +MKDIR_P = /bin/mkdir -p 5.129 +MKINSTALLDIRS = 5.130 +MSGFMT = 5.131 +MSGMERGE = 5.132 +NASM = /usr/bin/nasm 5.133 +OBJEXT = o 5.134 +PACKAGE = VisualBoyAdvance 5.135 +PACKAGE_BUGREPORT = 5.136 +PACKAGE_NAME = 5.137 +PACKAGE_STRING = 5.138 +PACKAGE_TARNAME = 5.139 +PACKAGE_VERSION = 5.140 +PATH_SEPARATOR = : 5.141 +PKG_CONFIG = 5.142 +POSUB = 5.143 +RANLIB = ranlib 5.144 +SDL_CFLAGS = -I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT 5.145 +SDL_CONFIG = /usr/bin/sdl-config 5.146 +SDL_LIBS = -L/usr/lib -Wl,-rpath,/usr/lib -lSDL -lpthread 5.147 +SET_MAKE = 5.148 +SHELL = /bin/sh 5.149 +STRIP = 5.150 +USE_NLS = 5.151 +VBA_EXTRA = 5.152 +VBA_LIBS = ../gba/libgba.a ../gb/libgb.a ../common/libgbcom.a ../filters/libfilter.a ../lua/libgblua.a ../prof/libprof.a 5.153 +VBA_SRC_EXTRA = lua prof sdl 5.154 +VERSION = 1.7.2 5.155 +XGETTEXT = 5.156 +XMKMF = 5.157 +YACC = bison -y 5.158 +YFLAGS = 5.159 +abs_builddir = /home/r/proj/vba/trunk/src/sdl 5.160 +abs_srcdir = /home/r/proj/vba/trunk/src/sdl 5.161 +abs_top_builddir = /home/r/proj/vba/trunk 5.162 +abs_top_srcdir = /home/r/proj/vba/trunk 5.163 +ac_ct_CC = gcc 5.164 +ac_ct_CXX = g++ 5.165 +am__include = include 5.166 +am__leading_dot = . 5.167 +am__quote = 5.168 +am__tar = ${AMTAR} chof - "$$tardir" 5.169 +am__untar = ${AMTAR} xf - 5.170 +bindir = ${exec_prefix}/bin 5.171 +build = x86_64-unknown-linux-gnu 5.172 +build_alias = 5.173 +build_cpu = x86_64 5.174 +build_os = linux-gnu 5.175 +build_vendor = unknown 5.176 +builddir = . 5.177 +datadir = ${datarootdir} 5.178 +datarootdir = ${prefix}/share 5.179 +docdir = ${datarootdir}/doc/${PACKAGE} 5.180 +dvidir = ${docdir} 5.181 +exec_prefix = ${prefix} 5.182 +host = x86_64-unknown-linux-gnu 5.183 +host_alias = 5.184 +host_cpu = x86_64 5.185 +host_os = linux-gnu 5.186 +host_vendor = unknown 5.187 +htmldir = ${docdir} 5.188 +includedir = ${prefix}/include 5.189 +infodir = ${datarootdir}/info 5.190 +install_sh = $(SHELL) /home/r/proj/vba/trunk/install-sh 5.191 +libdir = ${exec_prefix}/lib 5.192 +libexecdir = ${exec_prefix}/libexec 5.193 +localedir = ${datarootdir}/locale 5.194 +localstatedir = ${prefix}/var 5.195 +mandir = ${datarootdir}/man 5.196 +mkdir_p = /bin/mkdir -p 5.197 +oldincludedir = /usr/include 5.198 +pdfdir = ${docdir} 5.199 +prefix = /usr/local 5.200 +program_transform_name = s,x,x, 5.201 +psdir = ${docdir} 5.202 +sbindir = ${exec_prefix}/sbin 5.203 +sharedstatedir = ${prefix}/com 5.204 +srcdir = . 5.205 +sysconfdir = ${prefix}/etc 5.206 +target = x86_64-unknown-linux-gnu 5.207 +target_alias = 5.208 +target_cpu = x86_64 5.209 +target_os = linux-gnu 5.210 +target_vendor = unknown 5.211 +top_builddir = ../.. 5.212 +top_srcdir = ../.. 5.213 +VisualBoyAdvance_SOURCES = \ 5.214 + SDL.cpp \ 5.215 + debugger.cpp \ 5.216 + debugger.h \ 5.217 + expr-lex.cpp \ 5.218 + expr.cpp \ 5.219 + expr.cpp.h \ 5.220 + exprNode.cpp \ 5.221 + exprNode.h \ 5.222 + getopt.c \ 5.223 + getopt.h \ 5.224 + getopt1.c \ 5.225 + ../AutoBuild.h \ 5.226 + ../NLS.h \ 5.227 + ../Port.h 5.228 + 5.229 +VisualBoyAdvance_LDADD = ../gba/libgba.a ../gb/libgb.a ../common/libgbcom.a ../filters/libfilter.a ../lua/libgblua.a ../prof/libprof.a -L/usr/lib -Wl,-rpath,/usr/lib -lSDL -lpthread 5.230 +VisualBoyAdvance_DEPENDENCIES = ../gba/libgba.a ../gb/libgb.a ../common/libgbcom.a ../filters/libfilter.a ../lua/libgblua.a ../prof/libprof.a 5.231 +TestEmu_SOURCES = \ 5.232 + TestEmu.cpp \ 5.233 + debugger.cpp \ 5.234 + debugger.h \ 5.235 + expr-lex.cpp \ 5.236 + expr.cpp \ 5.237 + expr.cpp.h \ 5.238 + exprNode.cpp \ 5.239 + exprNode.h \ 5.240 + ../AutoBuild.h \ 5.241 + ../NLS.h \ 5.242 + ../Port.h 5.243 + 5.244 +TestEmu_LDADD = ../gba/libgba.a ../gb/libgb.a ../common/libgbcom.a ../filters/libfilter.a ../lua/libgblua.a ../prof/libprof.a -L/usr/lib -Wl,-rpath,/usr/lib -lSDL -lpthread 5.245 +TestEmu_DEPENDENCIES = ../gba/libgba.a ../gb/libgb.a ../common/libgbcom.a ../filters/libfilter.a ../lua/libgblua.a ../prof/libprof.a 5.246 +AM_CPPFLAGS = \ 5.247 + -I$(top_srcdir)/src \ 5.248 + -DSDL \ 5.249 + -DSYSCONFDIR=\"$(sysconfdir)\" 5.250 + 5.251 +AM_CXXFLAGS = -fno-exceptions -I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT 5.252 +all: all-am 5.253 + 5.254 +.SUFFIXES: 5.255 +.SUFFIXES: .c .cpp .o .obj 5.256 +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) 5.257 + @for dep in $?; do \ 5.258 + case '$(am__configure_deps)' in \ 5.259 + *$$dep*) \ 5.260 + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ 5.261 + && exit 0; \ 5.262 + exit 1;; \ 5.263 + esac; \ 5.264 + done; \ 5.265 + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/sdl/Makefile'; \ 5.266 + cd $(top_srcdir) && \ 5.267 + $(AUTOMAKE) --gnu src/sdl/Makefile 5.268 +.PRECIOUS: Makefile 5.269 +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status 5.270 + @case '$?' in \ 5.271 + *config.status*) \ 5.272 + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ 5.273 + *) \ 5.274 + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ 5.275 + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ 5.276 + esac; 5.277 + 5.278 +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) 5.279 + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh 5.280 + 5.281 +$(top_srcdir)/configure: $(am__configure_deps) 5.282 + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh 5.283 +$(ACLOCAL_M4): $(am__aclocal_m4_deps) 5.284 + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh 5.285 +install-binPROGRAMS: $(bin_PROGRAMS) 5.286 + @$(NORMAL_INSTALL) 5.287 + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" 5.288 + @list='$(bin_PROGRAMS)'; for p in $$list; do \ 5.289 + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ 5.290 + if test -f $$p \ 5.291 + ; then \ 5.292 + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ 5.293 + echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ 5.294 + $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ 5.295 + else :; fi; \ 5.296 + done 5.297 + 5.298 +uninstall-binPROGRAMS: 5.299 + @$(NORMAL_UNINSTALL) 5.300 + @list='$(bin_PROGRAMS)'; for p in $$list; do \ 5.301 + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ 5.302 + echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ 5.303 + rm -f "$(DESTDIR)$(bindir)/$$f"; \ 5.304 + done 5.305 + 5.306 +clean-binPROGRAMS: 5.307 + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) 5.308 + 5.309 +clean-noinstPROGRAMS: 5.310 + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) 5.311 +TestEmu$(EXEEXT): $(TestEmu_OBJECTS) $(TestEmu_DEPENDENCIES) 5.312 + @rm -f TestEmu$(EXEEXT) 5.313 + $(CXXLINK) $(TestEmu_OBJECTS) $(TestEmu_LDADD) $(LIBS) 5.314 + 5.315 +OBJECTS_ = \ 5.316 +2xSaImmx.o elf.o GBASound.o gbSound.o Mode2.o RTC.o \ 5.317 +2xSaI.o gbCheats.o getopt1.o Mode3.o scanline.o expr.o \ 5.318 +admame.o gbDis.o getopt.o Mode4.o SDL.o expr-lex.o \ 5.319 +agbprint.o gbGfx.o hq2x.o Mode5.o simple2x.o exprNode.o \ 5.320 +armdis.o Flash.o gbGlobals.o interframe.o motionblur.o Sram.o \ 5.321 +bilinear.o GBACheats.o gbMemory.o lua-engine.o movie.o \ 5.322 +bios.o GBAGfx.o GB.o memgzio.o pixel.o Text.o \ 5.323 +GBAGlobals.o gbPrinter.o Mode0.o prof.o unzip.o debugger.o\ 5.324 +EEprom.o GBA.o gbSGB.o Mode1.o remote.o Util.o \ 5.325 +SoundSDL.o 5.326 + 5.327 +OBJECTS = $(patsubst %,$(OBJDIR)/%,$(OBJECTS_)) 5.328 + 5.329 +$(top_srcdir)/src/VisualBoyAdvance$(EXEEXT): $(OBJECTS) $(top_srcdir)/src/lua/libgblua.a 5.330 + @rm -f VisualBoyAdvance$(EXEEXT) 5.331 + $(CXXLINK) $(OBJECTS) $(top_srcdir)/src/lua/libgblua.a -L/usr/lib -lSDL -lpthread -lpng -lz 5.332 + 5.333 +mostlyclean-compile: 5.334 + -rm -f *.$(OBJEXT) 5.335 + 5.336 +distclean-compile: 5.337 + -rm -f *.tab.c 5.338 + 5.339 +include ./$(DEPDIR)/SDL.Po 5.340 +include ./$(DEPDIR)/TestEmu.Po 5.341 +include ./$(DEPDIR)/debugger.Po 5.342 +include ./$(DEPDIR)/expr-lex.Po 5.343 +include ./$(DEPDIR)/expr.Po 5.344 +include ./$(DEPDIR)/exprNode.Po 5.345 +include ./$(DEPDIR)/getopt.Po 5.346 +include ./$(DEPDIR)/getopt1.Po 5.347 + 5.348 +$(OBJDIR)/%.o: %.c 5.349 + $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< 5.350 + mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po 5.351 +# source='$<' object='$@' libtool=no \ 5.352 +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ 5.353 +# $(COMPILE) -c $< 5.354 + 5.355 +.c.obj: 5.356 + $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` 5.357 + mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po 5.358 +# source='$<' object='$@' libtool=no \ 5.359 +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ 5.360 +# $(COMPILE) -c `$(CYGPATH_W) '$<'` 5.361 + 5.362 +$(OBJDIR)/%.o: %.cpp 5.363 + $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< 5.364 + mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po 5.365 +# source='$<' object='$@' libtool=no \ 5.366 +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ 5.367 +# $(CXXCOMPILE) -c -o $@ $< 5.368 + 5.369 +.cpp.obj: 5.370 + $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` 5.371 + mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po 5.372 +# source='$<' object='$@' libtool=no \ 5.373 +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ 5.374 +# $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` 5.375 + 5.376 +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) 5.377 + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ 5.378 + unique=`for i in $$list; do \ 5.379 + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ 5.380 + done | \ 5.381 + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ 5.382 + END { if (nonempty) { for (i in files) print i; }; }'`; \ 5.383 + mkid -fID $$unique 5.384 +tags: TAGS 5.385 + 5.386 +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ 5.387 + $(TAGS_FILES) $(LISP) 5.388 + tags=; \ 5.389 + here=`pwd`; \ 5.390 + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ 5.391 + unique=`for i in $$list; do \ 5.392 + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ 5.393 + done | \ 5.394 + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ 5.395 + END { if (nonempty) { for (i in files) print i; }; }'`; \ 5.396 + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ 5.397 + test -n "$$unique" || unique=$$empty_fix; \ 5.398 + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ 5.399 + $$tags $$unique; \ 5.400 + fi 5.401 +ctags: CTAGS 5.402 +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ 5.403 + $(TAGS_FILES) $(LISP) 5.404 + tags=; \ 5.405 + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ 5.406 + unique=`for i in $$list; do \ 5.407 + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ 5.408 + done | \ 5.409 + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ 5.410 + END { if (nonempty) { for (i in files) print i; }; }'`; \ 5.411 + test -z "$(CTAGS_ARGS)$$tags$$unique" \ 5.412 + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ 5.413 + $$tags $$unique 5.414 + 5.415 +GTAGS: 5.416 + here=`$(am__cd) $(top_builddir) && pwd` \ 5.417 + && cd $(top_srcdir) \ 5.418 + && gtags -i $(GTAGS_ARGS) $$here 5.419 + 5.420 +distclean-tags: 5.421 + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags 5.422 + 5.423 +distdir: $(DISTFILES) 5.424 + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ 5.425 + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ 5.426 + list='$(DISTFILES)'; \ 5.427 + dist_files=`for file in $$list; do echo $$file; done | \ 5.428 + sed -e "s|^$$srcdirstrip/||;t" \ 5.429 + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ 5.430 + case $$dist_files in \ 5.431 + */*) $(MKDIR_P) `echo "$$dist_files" | \ 5.432 + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ 5.433 + sort -u` ;; \ 5.434 + esac; \ 5.435 + for file in $$dist_files; do \ 5.436 + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ 5.437 + if test -d $$d/$$file; then \ 5.438 + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ 5.439 + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ 5.440 + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ 5.441 + fi; \ 5.442 + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ 5.443 + else \ 5.444 + test -f $(distdir)/$$file \ 5.445 + || cp -p $$d/$$file $(distdir)/$$file \ 5.446 + || exit 1; \ 5.447 + fi; \ 5.448 + done 5.449 +check-am: all-am 5.450 +check: check-am 5.451 +all-am: Makefile $(VisualBoyAdvance_OBJECTS) $(top_srcdir)/src/VisualBoyAdvance$(EXEEXT) 5.452 +installdirs: 5.453 + for dir in "$(DESTDIR)$(bindir)"; do \ 5.454 + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ 5.455 + done 5.456 +install: install-am 5.457 +install-exec: install-exec-am 5.458 +install-data: install-data-am 5.459 +uninstall: uninstall-am 5.460 + 5.461 +install-am: all-am 5.462 + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am 5.463 + 5.464 +installcheck: installcheck-am 5.465 +install-strip: 5.466 + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ 5.467 + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ 5.468 + `test -z '$(STRIP)' || \ 5.469 + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install 5.470 +mostlyclean-generic: 5.471 + 5.472 +clean-generic: 5.473 + 5.474 +distclean-generic: 5.475 + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) 5.476 + 5.477 +maintainer-clean-generic: 5.478 + @echo "This command is intended for maintainers to use" 5.479 + @echo "it deletes files that may require special tools to rebuild." 5.480 +clean: clean-am 5.481 + 5.482 +clean-am: clean-binPROGRAMS clean-generic clean-noinstPROGRAMS \ 5.483 + mostlyclean-am 5.484 + 5.485 +distclean: distclean-am 5.486 + -rm -rf ./$(DEPDIR) 5.487 + -rm -f Makefile 5.488 +distclean-am: clean-am distclean-compile distclean-generic \ 5.489 + distclean-tags 5.490 + 5.491 +dvi: dvi-am 5.492 + 5.493 +dvi-am: 5.494 + 5.495 +html: html-am 5.496 + 5.497 +info: info-am 5.498 + 5.499 +info-am: 5.500 + 5.501 +install-data-am: 5.502 + 5.503 +install-dvi: install-dvi-am 5.504 + 5.505 +install-exec-am: install-binPROGRAMS 5.506 + 5.507 +install-html: install-html-am 5.508 + 5.509 +install-info: install-info-am 5.510 + 5.511 +install-man: 5.512 + 5.513 +install-pdf: install-pdf-am 5.514 + 5.515 +install-ps: install-ps-am 5.516 + 5.517 +installcheck-am: 5.518 + 5.519 +maintainer-clean: maintainer-clean-am 5.520 + -rm -rf ./$(DEPDIR) 5.521 + -rm -f Makefile 5.522 +maintainer-clean-am: distclean-am maintainer-clean-generic 5.523 + 5.524 +mostlyclean: mostlyclean-am 5.525 + 5.526 +mostlyclean-am: mostlyclean-compile mostlyclean-generic 5.527 + 5.528 +pdf: pdf-am 5.529 + 5.530 +pdf-am: 5.531 + 5.532 +ps: ps-am 5.533 + 5.534 +ps-am: 5.535 + 5.536 +uninstall-am: uninstall-binPROGRAMS 5.537 + 5.538 +.MAKE: install-am install-strip 5.539 + 5.540 +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ 5.541 + clean-generic clean-noinstPROGRAMS ctags distclean \ 5.542 + distclean-compile distclean-generic distclean-tags distdir dvi \ 5.543 + dvi-am html html-am info info-am install install-am \ 5.544 + install-binPROGRAMS install-data install-data-am install-dvi \ 5.545 + install-dvi-am install-exec install-exec-am install-html \ 5.546 + install-html-am install-info install-info-am install-man \ 5.547 + install-pdf install-pdf-am install-ps install-ps-am \ 5.548 + install-strip installcheck installcheck-am installdirs \ 5.549 + maintainer-clean maintainer-clean-generic mostlyclean \ 5.550 + mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ 5.551 + tags uninstall uninstall-am uninstall-binPROGRAMS 5.552 + 5.553 +# Tell versions [3.59,3.63) of GNU make to not export all variables. 5.554 +# Otherwise a system limit (for SysV at least) may be exceeded. 5.555 +.NOEXPORT:
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/src/sdl/Makefile.am Sun Mar 04 21:06:50 2012 -0600 6.3 @@ -0,0 +1,51 @@ 6.4 +bin_PROGRAMS = VisualBoyAdvance 6.5 + 6.6 +#noinst_PROGRAMS = TestEmu 6.7 + 6.8 +VisualBoyAdvance_SOURCES = \ 6.9 + SDL.cpp \ 6.10 + debugger.cpp \ 6.11 + debugger.h \ 6.12 + expr-lex.cpp \ 6.13 + expr.cpp \ 6.14 + expr.cpp.h \ 6.15 + exprNode.cpp \ 6.16 + exprNode.h \ 6.17 + getopt.c \ 6.18 + getopt.h \ 6.19 + getopt1.c \ 6.20 + ../AutoBuild.h \ 6.21 + ../NLS.h \ 6.22 + ../Port.h 6.23 + 6.24 +VisualBoyAdvance_LDADD = \ 6.25 + ../lua/libgblua.a \ 6.26 + ../common/libgbcom.a \ 6.27 + ../gb/libgb.a \ 6.28 + ../gba/libgba.a \ 6.29 + ../filters/lib386.a \ 6.30 + ../filters/libfilter.a 6.31 + 6.32 +# TestEmu_SOURCES = \ 6.33 +# TestEmu.cpp \ 6.34 +# debugger.cpp \ 6.35 +# debugger.h \ 6.36 +# expr-lex.cpp \ 6.37 +# expr.cpp \ 6.38 +# expr.cpp.h \ 6.39 +# exprNode.cpp \ 6.40 +# exprNode.h \ 6.41 +# ../AutoBuild.h \ 6.42 +# ../NLS.h \ 6.43 +# ../Port.h 6.44 + 6.45 +# TestEmu_LDADD = @VBA_LIBS@ @SDL_LIBS@ 6.46 + 6.47 +# TestEmu_DEPENDENCIES = @VBA_LIBS@ 6.48 + 6.49 +AM_CPPFLAGS = \ 6.50 + -I$(top_srcdir)/src \ 6.51 + -DSDL \ 6.52 + -DSYSCONFDIR=\"$(sysconfdir)\" 6.53 + 6.54 +AM_CXXFLAGS = -fno-exceptions
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/src/sdl/RingBuffer.h Sun Mar 04 21:06:50 2012 -0600 7.3 @@ -0,0 +1,112 @@ 7.4 +/*************************************************************************** 7.5 + * Copyright (C) 2008 by Sindre Aamås * 7.6 + * aamas@stud.ntnu.no * 7.7 + * * 7.8 + * This program is free software; you can redistribute it and/or modify * 7.9 + * it under the terms of the GNU General Public License version 2 as * 7.10 + * published by the Free Software Foundation. * 7.11 + * * 7.12 + * This program is distributed in the hope that it will be useful, * 7.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of * 7.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 7.15 + * GNU General Public License version 2 for more details. * 7.16 + * * 7.17 + * You should have received a copy of the GNU General Public License * 7.18 + * version 2 along with this program; if not, write to the * 7.19 + * Free Software Foundation, Inc., * 7.20 + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 7.21 + ***************************************************************************/ 7.22 +#ifndef RINGBUFFER_H 7.23 +#define RINGBUFFER_H 7.24 + 7.25 +#include "Array.h" 7.26 +#include <cstddef> 7.27 +#include <algorithm> 7.28 +#include <cstring> 7.29 + 7.30 +template<typename T> 7.31 +class RingBuffer { 7.32 + Array<T> buf; 7.33 + std::size_t sz; 7.34 + std::size_t rpos; 7.35 + std::size_t wpos; 7.36 + 7.37 +public: 7.38 + RingBuffer(const std::size_t sz_in = 0) : sz(0), rpos(0), wpos(0) { reset(sz_in); } 7.39 + 7.40 + std::size_t avail() const { 7.41 + return (wpos < rpos ? 0 : sz) + rpos - wpos - 1; 7.42 + } 7.43 + 7.44 + void clear() { 7.45 + wpos = rpos = 0; 7.46 + } 7.47 + 7.48 + void fill(T value); 7.49 + 7.50 + void read(T *out, std::size_t num); 7.51 + 7.52 + void reset(std::size_t sz_in); 7.53 + 7.54 + std::size_t size() const { 7.55 + return sz - 1; 7.56 + } 7.57 + 7.58 + std::size_t used() const { 7.59 + return (wpos < rpos ? sz : 0) + wpos - rpos; 7.60 + } 7.61 + 7.62 + void write(const T *in, std::size_t num); 7.63 +}; 7.64 + 7.65 +template<typename T> 7.66 +void RingBuffer<T>::fill(const T value) { 7.67 + std::fill(buf + 0, buf + sz, value); 7.68 + rpos = 0; 7.69 + wpos = sz - 1; 7.70 +} 7.71 + 7.72 +template<typename T> 7.73 +void RingBuffer<T>::read(T *out, std::size_t num) { 7.74 + if (rpos + num > sz) { 7.75 + const std::size_t n = sz - rpos; 7.76 + 7.77 + std::memcpy(out, buf + rpos, n * sizeof(T)); 7.78 + 7.79 + rpos = 0; 7.80 + num -= n; 7.81 + out += n; 7.82 + } 7.83 + 7.84 + std::memcpy(out, buf + rpos, num * sizeof(T)); 7.85 + 7.86 + if ((rpos += num) == sz) 7.87 + rpos = 0; 7.88 +} 7.89 + 7.90 +template<typename T> 7.91 +void RingBuffer<T>::reset(const std::size_t sz_in) { 7.92 + sz = sz_in + 1; 7.93 + rpos = wpos = 0; 7.94 + buf.reset(sz_in ? sz : 0); 7.95 +} 7.96 + 7.97 +template<typename T> 7.98 +void RingBuffer<T>::write(const T *in, std::size_t num) { 7.99 + if (wpos + num > sz) { 7.100 + const std::size_t n = sz - wpos; 7.101 + 7.102 + std::memcpy(buf + wpos, in, n * sizeof(T)); 7.103 + 7.104 + wpos = 0; 7.105 + num -= n; 7.106 + in += n; 7.107 + } 7.108 + 7.109 + std::memcpy(buf + wpos, in, num * sizeof(T)); 7.110 + 7.111 + if ((wpos += num) == sz) 7.112 + wpos = 0; 7.113 +} 7.114 + 7.115 +#endif
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/src/sdl/SDL.cpp Sun Mar 04 21:06:50 2012 -0600 8.3 @@ -0,0 +1,3623 @@ 8.4 +// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. 8.5 +// Copyright (C) 1999-2003 Forgotten 8.6 +// Copyright (C) 2004 Forgotten and the VBA development team 8.7 + 8.8 +// This program is free software; you can redistribute it and/or modify 8.9 +// it under the terms of the GNU General Public License as published by 8.10 +// the Free Software Foundation; either version 2, or(at your option) 8.11 +// any later version. 8.12 +// 8.13 +// This program is distributed in the hope that it will be useful, 8.14 +// but WITHOUT ANY WARRANTY; without even the implied warranty of 8.15 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 8.16 +// GNU General Public License for more details. 8.17 +// 8.18 +// You should have received a copy of the GNU General Public License 8.19 +// along with this program; if not, write to the Free Software Foundation, 8.20 +// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 8.21 + 8.22 +#include <stdarg.h> 8.23 +#include <stdlib.h> 8.24 +#include <stdio.h> 8.25 +#include <string.h> 8.26 +#include <sys/types.h> 8.27 +#include <sys/stat.h> 8.28 + 8.29 +#include "AutoBuild.h" 8.30 + 8.31 +#include "Port.h" 8.32 +#include "SDL.h" 8.33 +#include "debugger.h" 8.34 +#include "gba/GBA.h" 8.35 +#include "gba/GBAGlobals.h" 8.36 +#include "gba/agbprint.h" 8.37 +#include "gba/Flash.h" 8.38 +#include "gba/RTC.h" 8.39 +#include "gba/GBASound.h" 8.40 +#include "gb/GB.h" 8.41 +#include "gb/gbGlobals.h" 8.42 +#include "common/Text.h" 8.43 +#include "common/unzip.h" 8.44 +#include "common/Util.h" 8.45 +#include "common/movie.h" 8.46 +#include "common/System.h" 8.47 +#include "common/inputGlobal.h" 8.48 +#include "../common/vbalua.h" 8.49 +#include "SoundSDL.h" 8.50 + 8.51 + 8.52 +#define GBC_CAPABLE ((gbRom[0x143] & 0x80) != 0) 8.53 +#define SGB_CAPABLE (gbRom[0x146] == 0x03) 8.54 + 8.55 +#ifndef WIN32 8.56 +# include <unistd.h> 8.57 +# define GETCWD getcwd 8.58 +#else // WIN32 8.59 +# include <direct.h> 8.60 +# define GETCWD _getcwd 8.61 +#endif // WIN32 8.62 + 8.63 +#ifndef __GNUC__ 8.64 +# define HAVE_DECL_GETOPT 0 8.65 +# define __STDC__ 1 8.66 +# include "getopt.h" 8.67 +#else // ! __GNUC__ 8.68 +# define HAVE_DECL_GETOPT 1 8.69 +# include "getopt.h" 8.70 +#endif // ! __GNUC__ 8.71 + 8.72 +#ifdef MMX 8.73 +extern "C" bool cpu_mmx; 8.74 +#endif 8.75 +extern bool8 soundEcho; 8.76 +extern bool8 soundLowPass; 8.77 +extern bool8 soundReverse; 8.78 +extern int Init_2xSaI(u32); 8.79 +extern void _2xSaI(u8*,u32,u8*,u8*,u32,int,int); 8.80 +extern void _2xSaI32(u8*,u32,u8*,u8*,u32,int,int); 8.81 +extern void Super2xSaI(u8*,u32,u8*,u8*,u32,int,int); 8.82 +extern void Super2xSaI32(u8*,u32,u8*,u8*,u32,int,int); 8.83 +extern void SuperEagle(u8*,u32,u8*,u8*,u32,int,int); 8.84 +extern void SuperEagle32(u8*,u32,u8*,u8*,u32,int,int); 8.85 +extern void Pixelate2x16(u8*,u32,u8*,u8*,u32,int,int); 8.86 +extern void Pixelate2x32(u8*,u32,u8*,u8*,u32,int,int); 8.87 +extern void MotionBlur(u8*,u32,u8*,u8*,u32,int,int); 8.88 +extern void MotionBlur32(u8*,u32,u8*,u8*,u32,int,int); 8.89 +extern void AdMame2x(u8*,u32,u8*,u8*,u32,int,int); 8.90 +extern void AdMame2x32(u8*,u32,u8*,u8*,u32,int,int); 8.91 +extern void Simple2x16(u8*,u32,u8*,u8*,u32,int,int); 8.92 +extern void Simple2x32(u8*,u32,u8*,u8*,u32,int,int); 8.93 +extern void Bilinear(u8*,u32,u8*,u8*,u32,int,int); 8.94 +extern void Bilinear32(u8*,u32,u8*,u8*,u32,int,int); 8.95 +extern void BilinearPlus(u8*,u32,u8*,u8*,u32,int,int); 8.96 +extern void BilinearPlus32(u8*,u32,u8*,u8*,u32,int,int); 8.97 +extern void Scanlines(u8*,u32,u8*,u8*,u32,int,int); 8.98 +extern void Scanlines32(u8*,u32,u8*,u8*,u32,int,int); 8.99 +extern void ScanlinesTV(u8*,u32,u8*,u8*,u32,int,int); 8.100 +extern void ScanlinesTV32(u8*,u32,u8*,u8*,u32,int,int); 8.101 +extern void hq2x(u8*,u32,u8*,u8*,u32,int,int); 8.102 +extern void hq2x32(u8*,u32,u8*,u8*,u32,int,int); 8.103 +extern void lq2x(u8*,u32,u8*,u8*,u32,int,int); 8.104 +extern void lq2x32(u8*,u32,u8*,u8*,u32,int,int); 8.105 + 8.106 +extern void SmartIB(u8*,u32,int,int); 8.107 +extern void SmartIB32(u8*,u32,int,int); 8.108 +extern void MotionBlurIB(u8*,u32,int,int); 8.109 +extern void MotionBlurIB32(u8*,u32,int,int); 8.110 + 8.111 +void Init_Overlay(SDL_Surface *surface, int overlaytype); 8.112 +void Quit_Overlay(void); 8.113 +void Draw_Overlay(SDL_Surface *surface, int size); 8.114 + 8.115 +extern void remoteInit(); 8.116 +extern void remoteCleanUp(); 8.117 +extern void remoteStubMain(); 8.118 +extern void remoteStubSignal(int,int); 8.119 +extern void remoteOutput(char *, u32); 8.120 +extern void remoteSetProtocol(int); 8.121 +extern void remoteSetPort(int); 8.122 +extern void debuggerOutput(char *, u32); 8.123 + 8.124 +extern void CPUUpdateRenderBuffers(bool); 8.125 + 8.126 +struct EmulatedSystem theEmulator = { 8.127 + NULL, 8.128 + NULL, 8.129 + NULL, 8.130 + NULL, 8.131 + NULL, 8.132 + NULL, 8.133 + NULL, 8.134 + NULL, 8.135 + NULL, 8.136 + NULL, 8.137 + NULL, 8.138 + NULL, 8.139 + false, 8.140 + 0 8.141 +}; 8.142 + 8.143 +SDL_Surface *surface = NULL; 8.144 +SDL_Overlay *overlay = NULL; 8.145 +SDL_Rect overlay_rect; 8.146 + 8.147 +int systemSpeed = 0; 8.148 +int systemRedShift = 0; 8.149 +int systemBlueShift = 0; 8.150 +int systemGreenShift = 0; 8.151 +int systemColorDepth = 0; 8.152 +int systemDebug = 0; 8.153 +int systemVerbose = 0; 8.154 +int systemFrameSkip = 0; 8.155 +int systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; 8.156 + 8.157 +int srcPitch = 0; 8.158 +int srcWidth = 0; 8.159 +int srcHeight = 0; 8.160 +int destWidth = 0; 8.161 +int destHeight = 0; 8.162 + 8.163 +int sensorX = 2047; 8.164 +int sensorY = 2047; 8.165 +bool sensorOn = false; 8.166 + 8.167 +int filter = 0; 8.168 +u8 *delta = NULL; 8.169 + 8.170 +int sdlPrintUsage = 0; 8.171 +int disableMMX = 0; 8.172 + 8.173 +int systemCartridgeType = 3; 8.174 +int sizeOption = 0; 8.175 +int captureFormat = 0; 8.176 +int useMovie = 0; 8.177 + 8.178 +int pauseWhenInactive = 0; 8.179 +int active = 1; 8.180 +int emulating = 0; 8.181 +int RGB_LOW_BITS_MASK=0x821; 8.182 +u32 systemColorMap32[0x10000]; 8.183 +u16 systemColorMap16[0x10000]; 8.184 +u16 systemGbPalette[24]; 8.185 +void (*filterFunction)(u8*,u32,u8*,u8*,u32,int,int) = NULL; 8.186 +void (*ifbFunction)(u8*,u32,int,int) = NULL; 8.187 +int ifbType = 0; 8.188 +char filename[2048]; 8.189 +char ipsname[2048]; 8.190 +char biosFileName[2048]; 8.191 +char movieFileName[2048]; 8.192 +char captureDir[2048]; 8.193 +char saveDir[2048]; 8.194 +char batteryDir[2048]; 8.195 + 8.196 +static char *rewindMemory = NULL; 8.197 +static int rewindPos = 0; 8.198 +static int rewindTopPos = 0; 8.199 +static int rewindCounter = 0; 8.200 +static int rewindCount = 0; 8.201 +static bool rewindSaveNeeded = false; 8.202 +static int rewindTimer = 0; 8.203 + 8.204 +#define REWIND_SIZE 400000 8.205 + 8.206 +#define _stricmp strcasecmp 8.207 + 8.208 +/*bool sdlButtons[4][12] = { 8.209 + { false, false, false, false, false, false, 8.210 + false, false, false, false, false, false }, 8.211 + { false, false, false, false, false, false, 8.212 + false, false, false, false, false, false }, 8.213 + { false, false, false, false, false, false, 8.214 + false, false, false, false, false, false }, 8.215 + { false, false, false, false, false, false, 8.216 + false, false, false, false, false, false } 8.217 +};*/ 8.218 +/* 8.219 + I'm changing the way the SDL GUI handles the button 8.220 + input to match the one in win32, this is needed in 8.221 + order to be compatible with the format required by 8.222 + common/movie.cpp 8.223 + --Felipe 8.224 +*/ 8.225 + 8.226 +u16 currentButtons[4] = {0, 0, 0, 0}; 8.227 + 8.228 +bool sdlMotionButtons[4] = { false, false, false, false }; 8.229 +const int32 INITIAL_SENSOR_VALUE = 2047; 8.230 + 8.231 +int sdlNumDevices = 0; 8.232 +SDL_Joystick **sdlDevices = NULL; 8.233 + 8.234 +bool wasPaused = false; 8.235 +int autoFrameSkip = 0; 8.236 +int frameskipadjust = 0; 8.237 +int showRenderedFrames = 0; 8.238 +int renderedFrames = 0; 8.239 + 8.240 +int throttle = 0; 8.241 +u32 throttleLastTime = 0; 8.242 +u32 autoFrameSkipLastTime = 0; 8.243 + 8.244 +int showSpeed = 1; 8.245 +int showSpeedTransparent = 1; 8.246 +bool disableStatusMessages = false; 8.247 +bool paused = false; 8.248 +bool pauseNextFrame = false; 8.249 +bool debugger = false; 8.250 +bool debuggerStub = false; 8.251 +int fullscreen = 0; 8.252 +bool systemSoundOn = false; 8.253 +bool yuv = false; 8.254 +int yuvType = 0; 8.255 +bool removeIntros = false; 8.256 +int sdlFlashSize = 0; 8.257 +int sdlAutoIPS = 1; 8.258 +int sdlRtcEnable = 0; 8.259 +int sdlAgbPrint = 0; 8.260 + 8.261 +int sdlDefaultJoypad = 0; 8.262 + 8.263 +extern void debuggerSignal(int,int); 8.264 + 8.265 +void (*dbgMain)() = debuggerMain; 8.266 +void (*dbgSignal)(int,int) = debuggerSignal; 8.267 +void (*dbgOutput)(char *, u32) = debuggerOutput; 8.268 + 8.269 +int mouseCounter = 0; 8.270 +int autoFire = 0; 8.271 +bool autoFireToggle = false; 8.272 + 8.273 +bool screenMessage[8] = {false,false,false,false,false,false,false,false}; 8.274 +char screenMessageBuffer[8][21]; 8.275 +u32 screenMessageTime[8] = {0,0,0,0,0,0,0,0}; 8.276 +u32 screenMessageDuration[8] = {0,0,0,0,0,0,0,0}; 8.277 + 8.278 +SDL_cond *cond = NULL; 8.279 +SDL_mutex *mutex = NULL; 8.280 +u8* sdlBuffer; 8.281 +int sdlSoundLen = 0; 8.282 +SoundSDL* soundDriver = NULL; 8.283 + 8.284 +char *arg0; 8.285 + 8.286 +#ifndef C_CORE 8.287 +u8 sdlStretcher[16384]; 8.288 +int sdlStretcherPos; 8.289 +#else 8.290 +void (*sdlStretcher)(u8 *, u8*) = NULL; 8.291 +#endif 8.292 + 8.293 +u16 joypad[4][12] = { 8.294 + { SDLK_LEFT, SDLK_RIGHT, 8.295 + SDLK_UP, SDLK_DOWN, 8.296 + SDLK_z, SDLK_x, 8.297 + SDLK_RETURN,SDLK_BACKSPACE, 8.298 + SDLK_a, SDLK_s, 8.299 + SDLK_SPACE, SDLK_F12 8.300 + }, 8.301 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 8.302 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 8.303 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } 8.304 +}; 8.305 + 8.306 +u16 defaultJoypad[12] = { 8.307 + SDLK_LEFT, SDLK_RIGHT, 8.308 + SDLK_UP, SDLK_DOWN, 8.309 + SDLK_z, SDLK_x, 8.310 + SDLK_RETURN,SDLK_BACKSPACE, 8.311 + SDLK_a, SDLK_s, 8.312 + SDLK_SPACE, SDLK_F12 8.313 +}; 8.314 + 8.315 +u16 motion[4] = { 8.316 + SDLK_KP4, SDLK_KP6, SDLK_KP8, SDLK_KP2 8.317 +}; 8.318 + 8.319 +u16 defaultMotion[4] = { 8.320 + SDLK_KP4, SDLK_KP6, SDLK_KP8, SDLK_KP2 8.321 +}; 8.322 + 8.323 +struct option sdlOptions[] = { 8.324 + { "agb-print", no_argument, &sdlAgbPrint, 1 }, 8.325 + { "auto-frameskip", no_argument, &autoFrameSkip, 1 }, 8.326 + { "bios", required_argument, 0, 'b' }, 8.327 + { "config", required_argument, 0, 'c' }, 8.328 + { "debug", no_argument, 0, 'd' }, 8.329 + { "filter", required_argument, 0, 'f' }, 8.330 + { "filter-normal", no_argument, &filter, 0 }, 8.331 + { "filter-tv-mode", no_argument, &filter, 1 }, 8.332 + { "filter-2xsai", no_argument, &filter, 2 }, 8.333 + { "filter-super-2xsai", no_argument, &filter, 3 }, 8.334 + { "filter-super-eagle", no_argument, &filter, 4 }, 8.335 + { "filter-pixelate", no_argument, &filter, 5 }, 8.336 + { "filter-motion-blur", no_argument, &filter, 6 }, 8.337 + { "filter-advmame", no_argument, &filter, 7 }, 8.338 + { "filter-simple2x", no_argument, &filter, 8 }, 8.339 + { "filter-bilinear", no_argument, &filter, 9 }, 8.340 + { "filter-bilinear+", no_argument, &filter, 10 }, 8.341 + { "filter-scanlines", no_argument, &filter, 11 }, 8.342 + { "filter-hq2x", no_argument, &filter, 12 }, 8.343 + { "filter-lq2x", no_argument, &filter, 13 }, 8.344 + { "flash-size", required_argument, 0, 'S' }, 8.345 + { "flash-64k", no_argument, &sdlFlashSize, 0 }, 8.346 + { "flash-128k", no_argument, &sdlFlashSize, 1 }, 8.347 + { "frameskip", required_argument, 0, 's' }, 8.348 + { "fullscreen", no_argument, &fullscreen, 1 }, 8.349 + { "gdb", required_argument, 0, 'G' }, 8.350 + { "help", no_argument, &sdlPrintUsage, 1 }, 8.351 + { "ifb-none", no_argument, &ifbType, 0 }, 8.352 + { "ifb-motion-blur", no_argument, &ifbType, 1 }, 8.353 + { "ifb-smart", no_argument, &ifbType, 2 }, 8.354 + { "ips", required_argument, 0, 'i' }, 8.355 + { "no-agb-print", no_argument, &sdlAgbPrint, 0 }, 8.356 + { "no-auto-frameskip", no_argument, &autoFrameSkip, 0 }, 8.357 + { "no-debug", no_argument, 0, 'N' }, 8.358 + { "no-ips", no_argument, &sdlAutoIPS, 0 }, 8.359 + { "no-mmx", no_argument, &disableMMX, 1 }, 8.360 + { "no-pause-when-inactive", no_argument, &pauseWhenInactive, 0 }, 8.361 + { "no-rtc", no_argument, &sdlRtcEnable, 0 }, 8.362 + { "no-show-speed", no_argument, &showSpeed, 0 }, 8.363 + { "no-throttle", no_argument, &throttle, 0 }, 8.364 + { "pause-when-inactive", no_argument, &pauseWhenInactive, 1 }, 8.365 + { "profile", optional_argument, 0, 'P' }, 8.366 + { "rtc", no_argument, &sdlRtcEnable, 1 }, 8.367 + { "save-type", required_argument, 0, 't' }, 8.368 + { "save-auto", no_argument, &cpuSaveType, 0 }, 8.369 + { "save-eeprom", no_argument, &cpuSaveType, 1 }, 8.370 + { "save-sram", no_argument, &cpuSaveType, 2 }, 8.371 + { "save-flash", no_argument, &cpuSaveType, 3 }, 8.372 + { "save-sensor", no_argument, &cpuSaveType, 4 }, 8.373 + { "save-none", no_argument, &cpuSaveType, 5 }, 8.374 + { "show-speed-normal", no_argument, &showSpeed, 1 }, 8.375 + { "show-speed-detailed", no_argument, &showSpeed, 2 }, 8.376 + { "throttle", required_argument, 0, 'T' }, 8.377 + { "verbose", required_argument, 0, 'v' }, 8.378 + { "video-1x", no_argument, &sizeOption, 0 }, 8.379 + { "video-2x", no_argument, &sizeOption, 1 }, 8.380 + { "video-3x", no_argument, &sizeOption, 2 }, 8.381 + { "video-4x", no_argument, &sizeOption, 3 }, 8.382 + { "yuv", required_argument, 0, 'Y' }, 8.383 + { "recordmovie", required_argument, 0, 'r' }, 8.384 + { "playmovie", required_argument, 0, 'p' }, 8.385 + { "watchmovie", required_argument, 0, 'w' }, 8.386 + { NULL, no_argument, NULL, 0 } 8.387 +}; 8.388 + 8.389 +#ifndef C_CORE 8.390 +#define SDL_LONG(val) \ 8.391 + *((u32 *)&sdlStretcher[sdlStretcherPos]) = val;\ 8.392 + sdlStretcherPos+=4; 8.393 + 8.394 +#define SDL_AND_EAX(val) \ 8.395 + sdlStretcher[sdlStretcherPos++] = 0x25;\ 8.396 + SDL_LONG(val); 8.397 + 8.398 +#define SDL_AND_EBX(val) \ 8.399 + sdlStretcher[sdlStretcherPos++] = 0x81;\ 8.400 + sdlStretcher[sdlStretcherPos++] = 0xe3;\ 8.401 + SDL_LONG(val); 8.402 + 8.403 +#define SDL_OR_EAX_EBX \ 8.404 + sdlStretcher[sdlStretcherPos++] = 0x09;\ 8.405 + sdlStretcher[sdlStretcherPos++] = 0xd8; 8.406 + 8.407 +#define SDL_LOADL_EBX \ 8.408 + sdlStretcher[sdlStretcherPos++] = 0x8b;\ 8.409 + sdlStretcher[sdlStretcherPos++] = 0x1f; 8.410 + 8.411 +#define SDL_LOADW \ 8.412 + sdlStretcher[sdlStretcherPos++] = 0x66;\ 8.413 + sdlStretcher[sdlStretcherPos++] = 0x8b;\ 8.414 + sdlStretcher[sdlStretcherPos++] = 0x06;\ 8.415 + sdlStretcher[sdlStretcherPos++] = 0x83;\ 8.416 + sdlStretcher[sdlStretcherPos++] = 0xc6;\ 8.417 + sdlStretcher[sdlStretcherPos++] = 0x02; 8.418 + 8.419 +#define SDL_LOADL \ 8.420 + sdlStretcher[sdlStretcherPos++] = 0x8b;\ 8.421 + sdlStretcher[sdlStretcherPos++] = 0x06;\ 8.422 + sdlStretcher[sdlStretcherPos++] = 0x83;\ 8.423 + sdlStretcher[sdlStretcherPos++] = 0xc6;\ 8.424 + sdlStretcher[sdlStretcherPos++] = 0x04; 8.425 + 8.426 +#define SDL_LOADL2 \ 8.427 + sdlStretcher[sdlStretcherPos++] = 0x8b;\ 8.428 + sdlStretcher[sdlStretcherPos++] = 0x06;\ 8.429 + sdlStretcher[sdlStretcherPos++] = 0x83;\ 8.430 + sdlStretcher[sdlStretcherPos++] = 0xc6;\ 8.431 + sdlStretcher[sdlStretcherPos++] = 0x03; 8.432 + 8.433 +#define SDL_STOREW \ 8.434 + sdlStretcher[sdlStretcherPos++] = 0x66;\ 8.435 + sdlStretcher[sdlStretcherPos++] = 0x89;\ 8.436 + sdlStretcher[sdlStretcherPos++] = 0x07;\ 8.437 + sdlStretcher[sdlStretcherPos++] = 0x83;\ 8.438 + sdlStretcher[sdlStretcherPos++] = 0xc7;\ 8.439 + sdlStretcher[sdlStretcherPos++] = 0x02; 8.440 + 8.441 +#define SDL_STOREL \ 8.442 + sdlStretcher[sdlStretcherPos++] = 0x89;\ 8.443 + sdlStretcher[sdlStretcherPos++] = 0x07;\ 8.444 + sdlStretcher[sdlStretcherPos++] = 0x83;\ 8.445 + sdlStretcher[sdlStretcherPos++] = 0xc7;\ 8.446 + sdlStretcher[sdlStretcherPos++] = 0x04; 8.447 + 8.448 +#define SDL_STOREL2 \ 8.449 + sdlStretcher[sdlStretcherPos++] = 0x89;\ 8.450 + sdlStretcher[sdlStretcherPos++] = 0x07;\ 8.451 + sdlStretcher[sdlStretcherPos++] = 0x83;\ 8.452 + sdlStretcher[sdlStretcherPos++] = 0xc7;\ 8.453 + sdlStretcher[sdlStretcherPos++] = 0x03; 8.454 + 8.455 +#define SDL_RET \ 8.456 + sdlStretcher[sdlStretcherPos++] = 0xc3; 8.457 + 8.458 +#define SDL_PUSH_EAX \ 8.459 + sdlStretcher[sdlStretcherPos++] = 0x50; 8.460 + 8.461 +#define SDL_PUSH_ECX \ 8.462 + sdlStretcher[sdlStretcherPos++] = 0x51; 8.463 + 8.464 +#define SDL_PUSH_EBX \ 8.465 + sdlStretcher[sdlStretcherPos++] = 0x53; 8.466 + 8.467 +#define SDL_PUSH_ESI \ 8.468 + sdlStretcher[sdlStretcherPos++] = 0x56; 8.469 + 8.470 +#define SDL_PUSH_EDI \ 8.471 + sdlStretcher[sdlStretcherPos++] = 0x57; 8.472 + 8.473 +#define SDL_POP_EAX \ 8.474 + sdlStretcher[sdlStretcherPos++] = 0x58; 8.475 + 8.476 +#define SDL_POP_ECX \ 8.477 + sdlStretcher[sdlStretcherPos++] = 0x59; 8.478 + 8.479 +#define SDL_POP_EBX \ 8.480 + sdlStretcher[sdlStretcherPos++] = 0x5b; 8.481 + 8.482 +#define SDL_POP_ESI \ 8.483 + sdlStretcher[sdlStretcherPos++] = 0x5e; 8.484 + 8.485 +#define SDL_POP_EDI \ 8.486 + sdlStretcher[sdlStretcherPos++] = 0x5f; 8.487 + 8.488 +#define SDL_MOV_ECX(val) \ 8.489 + sdlStretcher[sdlStretcherPos++] = 0xb9;\ 8.490 + SDL_LONG(val); 8.491 + 8.492 +#define SDL_REP_MOVSB \ 8.493 + sdlStretcher[sdlStretcherPos++] = 0xf3;\ 8.494 + sdlStretcher[sdlStretcherPos++] = 0xa4; 8.495 + 8.496 +#define SDL_REP_MOVSW \ 8.497 + sdlStretcher[sdlStretcherPos++] = 0xf3;\ 8.498 + sdlStretcher[sdlStretcherPos++] = 0x66;\ 8.499 + sdlStretcher[sdlStretcherPos++] = 0xa5; 8.500 + 8.501 +#define SDL_REP_MOVSL \ 8.502 + sdlStretcher[sdlStretcherPos++] = 0xf3;\ 8.503 + sdlStretcher[sdlStretcherPos++] = 0xa5; 8.504 + 8.505 +void sdlMakeStretcher(int width) 8.506 +{ 8.507 + sdlStretcherPos = 0; 8.508 + switch(systemColorDepth) { 8.509 + case 16: 8.510 + if(sizeOption) { 8.511 + SDL_PUSH_EAX; 8.512 + SDL_PUSH_ESI; 8.513 + SDL_PUSH_EDI; 8.514 + for(int i = 0; i < width; i++) { 8.515 + SDL_LOADW; 8.516 + SDL_STOREW; 8.517 + SDL_STOREW; 8.518 + if(sizeOption > 1) { 8.519 + SDL_STOREW; 8.520 + } 8.521 + if(sizeOption > 2) { 8.522 + SDL_STOREW; 8.523 + } 8.524 + } 8.525 + SDL_POP_EDI; 8.526 + SDL_POP_ESI; 8.527 + SDL_POP_EAX; 8.528 + SDL_RET; 8.529 + } else { 8.530 + SDL_PUSH_ESI; 8.531 + SDL_PUSH_EDI; 8.532 + SDL_PUSH_ECX; 8.533 + SDL_MOV_ECX(width); 8.534 + SDL_REP_MOVSW; 8.535 + SDL_POP_ECX; 8.536 + SDL_POP_EDI; 8.537 + SDL_POP_ESI; 8.538 + SDL_RET; 8.539 + } 8.540 + break; 8.541 + case 24: 8.542 + if(sizeOption) { 8.543 + SDL_PUSH_EAX; 8.544 + SDL_PUSH_ESI; 8.545 + SDL_PUSH_EDI; 8.546 + int w = width - 1; 8.547 + for(int i = 0; i < w; i++) { 8.548 + SDL_LOADL2; 8.549 + SDL_STOREL2; 8.550 + SDL_STOREL2; 8.551 + if(sizeOption > 1) { 8.552 + SDL_STOREL2; 8.553 + } 8.554 + if(sizeOption > 2) { 8.555 + SDL_STOREL2; 8.556 + } 8.557 + } 8.558 + // need to write the last one 8.559 + SDL_LOADL2; 8.560 + SDL_STOREL2; 8.561 + if(sizeOption > 1) { 8.562 + SDL_STOREL2; 8.563 + } 8.564 + if(sizeOption > 2) { 8.565 + SDL_STOREL2; 8.566 + } 8.567 + SDL_AND_EAX(0x00ffffff); 8.568 + SDL_PUSH_EBX; 8.569 + SDL_LOADL_EBX; 8.570 + SDL_AND_EBX(0xff000000); 8.571 + SDL_OR_EAX_EBX; 8.572 + SDL_POP_EBX; 8.573 + SDL_STOREL2; 8.574 + SDL_POP_EDI; 8.575 + SDL_POP_ESI; 8.576 + SDL_POP_EAX; 8.577 + SDL_RET; 8.578 + } else { 8.579 + SDL_PUSH_ESI; 8.580 + SDL_PUSH_EDI; 8.581 + SDL_PUSH_ECX; 8.582 + SDL_MOV_ECX(3*width); 8.583 + SDL_REP_MOVSB; 8.584 + SDL_POP_ECX; 8.585 + SDL_POP_EDI; 8.586 + SDL_POP_ESI; 8.587 + SDL_RET; 8.588 + } 8.589 + break; 8.590 + case 32: 8.591 + if(sizeOption) { 8.592 + SDL_PUSH_EAX; 8.593 + SDL_PUSH_ESI; 8.594 + SDL_PUSH_EDI; 8.595 + for(int i = 0; i < width; i++) { 8.596 + SDL_LOADL; 8.597 + SDL_STOREL; 8.598 + SDL_STOREL; 8.599 + if(sizeOption > 1) { 8.600 + SDL_STOREL; 8.601 + } 8.602 + if(sizeOption > 2) { 8.603 + SDL_STOREL; 8.604 + } 8.605 + } 8.606 + SDL_POP_EDI; 8.607 + SDL_POP_ESI; 8.608 + SDL_POP_EAX; 8.609 + SDL_RET; 8.610 + } else { 8.611 + SDL_PUSH_ESI; 8.612 + SDL_PUSH_EDI; 8.613 + SDL_PUSH_ECX; 8.614 + SDL_MOV_ECX(width); 8.615 + SDL_REP_MOVSL; 8.616 + SDL_POP_ECX; 8.617 + SDL_POP_EDI; 8.618 + SDL_POP_ESI; 8.619 + SDL_RET; 8.620 + } 8.621 + break; 8.622 + } 8.623 +} 8.624 + 8.625 +#ifdef _MSC_VER 8.626 +#define SDL_CALL_STRETCHER \ 8.627 + {\ 8.628 + __asm mov eax, stretcher\ 8.629 + __asm mov edi, dest\ 8.630 + __asm mov esi, src\ 8.631 + __asm call eax\ 8.632 + } 8.633 +#else 8.634 +#define SDL_CALL_STRETCHER \ 8.635 + asm volatile("call *%%eax"::"a" (stretcher),"S" (src),"D" (dest)) 8.636 +#endif 8.637 +#else 8.638 +#define SDL_CALL_STRETCHER \ 8.639 + sdlStretcher(src, dest) 8.640 + 8.641 +void sdlStretch16x1(u8 *src, u8 *dest) 8.642 +{ 8.643 + u16 *s = (u16 *)src; 8.644 + u16 *d = (u16 *)dest; 8.645 + for(int i = 0; i < srcWidth; i++) 8.646 + *d++ = *s++; 8.647 +} 8.648 + 8.649 +void sdlStretch16x2(u8 *src, u8 *dest) 8.650 +{ 8.651 + u16 *s = (u16 *)src; 8.652 + u16 *d = (u16 *)dest; 8.653 + for(int i = 0; i < srcWidth; i++) { 8.654 + *d++ = *s; 8.655 + *d++ = *s++; 8.656 + } 8.657 +} 8.658 + 8.659 +void sdlStretch16x3(u8 *src, u8 *dest) 8.660 +{ 8.661 + u16 *s = (u16 *)src; 8.662 + u16 *d = (u16 *)dest; 8.663 + for(int i = 0; i < srcWidth; i++) { 8.664 + *d++ = *s; 8.665 + *d++ = *s; 8.666 + *d++ = *s++; 8.667 + } 8.668 +} 8.669 + 8.670 +void sdlStretch16x4(u8 *src, u8 *dest) 8.671 +{ 8.672 + u16 *s = (u16 *)src; 8.673 + u16 *d = (u16 *)dest; 8.674 + for(int i = 0; i < srcWidth; i++) { 8.675 + *d++ = *s; 8.676 + *d++ = *s; 8.677 + *d++ = *s; 8.678 + *d++ = *s++; 8.679 + } 8.680 +} 8.681 + 8.682 +void (*sdlStretcher16[4])(u8 *, u8 *) = { 8.683 + sdlStretch16x1, 8.684 + sdlStretch16x2, 8.685 + sdlStretch16x3, 8.686 + sdlStretch16x4 8.687 +}; 8.688 + 8.689 +void sdlStretch32x1(u8 *src, u8 *dest) 8.690 +{ 8.691 + u32 *s = (u32 *)src; 8.692 + u32 *d = (u32 *)dest; 8.693 + for(int i = 0; i < srcWidth; i++) 8.694 + *d++ = *s++; 8.695 +} 8.696 + 8.697 +void sdlStretch32x2(u8 *src, u8 *dest) 8.698 +{ 8.699 + u32 *s = (u32 *)src; 8.700 + u32 *d = (u32 *)dest; 8.701 + for(int i = 0; i < srcWidth; i++) { 8.702 + *d++ = *s; 8.703 + *d++ = *s++; 8.704 + } 8.705 +} 8.706 + 8.707 +void sdlStretch32x3(u8 *src, u8 *dest) 8.708 +{ 8.709 + u32 *s = (u32 *)src; 8.710 + u32 *d = (u32 *)dest; 8.711 + for(int i = 0; i < srcWidth; i++) { 8.712 + *d++ = *s; 8.713 + *d++ = *s; 8.714 + *d++ = *s++; 8.715 + } 8.716 +} 8.717 + 8.718 +void sdlStretch32x4(u8 *src, u8 *dest) 8.719 +{ 8.720 + u32 *s = (u32 *)src; 8.721 + u32 *d = (u32 *)dest; 8.722 + for(int i = 0; i < srcWidth; i++) { 8.723 + *d++ = *s; 8.724 + *d++ = *s; 8.725 + *d++ = *s; 8.726 + *d++ = *s++; 8.727 + } 8.728 +} 8.729 + 8.730 +void (*sdlStretcher32[4])(u8 *, u8 *) = { 8.731 + sdlStretch32x1, 8.732 + sdlStretch32x2, 8.733 + sdlStretch32x3, 8.734 + sdlStretch32x4 8.735 +}; 8.736 + 8.737 +void sdlStretch24x1(u8 *src, u8 *dest) 8.738 +{ 8.739 + u8 *s = src; 8.740 + u8 *d = dest; 8.741 + for(int i = 0; i < srcWidth; i++) { 8.742 + *d++ = *s++; 8.743 + *d++ = *s++; 8.744 + *d++ = *s++; 8.745 + } 8.746 +} 8.747 + 8.748 +void sdlStretch24x2(u8 *src, u8 *dest) 8.749 +{ 8.750 + u8 *s = (u8 *)src; 8.751 + u8 *d = (u8 *)dest; 8.752 + for(int i = 0; i < srcWidth; i++) { 8.753 + *d++ = *s; 8.754 + *d++ = *(s+1); 8.755 + *d++ = *(s+2); 8.756 + s += 3; 8.757 + *d++ = *s; 8.758 + *d++ = *(s+1); 8.759 + *d++ = *(s+2); 8.760 + s += 3; 8.761 + } 8.762 +} 8.763 + 8.764 +void sdlStretch24x3(u8 *src, u8 *dest) 8.765 +{ 8.766 + u8 *s = (u8 *)src; 8.767 + u8 *d = (u8 *)dest; 8.768 + for(int i = 0; i < srcWidth; i++) { 8.769 + *d++ = *s; 8.770 + *d++ = *(s+1); 8.771 + *d++ = *(s+2); 8.772 + s += 3; 8.773 + *d++ = *s; 8.774 + *d++ = *(s+1); 8.775 + *d++ = *(s+2); 8.776 + s += 3; 8.777 + *d++ = *s; 8.778 + *d++ = *(s+1); 8.779 + *d++ = *(s+2); 8.780 + s += 3; 8.781 + } 8.782 +} 8.783 + 8.784 +void sdlStretch24x4(u8 *src, u8 *dest) 8.785 +{ 8.786 + u8 *s = (u8 *)src; 8.787 + u8 *d = (u8 *)dest; 8.788 + for(int i = 0; i < srcWidth; i++) { 8.789 + *d++ = *s; 8.790 + *d++ = *(s+1); 8.791 + *d++ = *(s+2); 8.792 + s += 3; 8.793 + *d++ = *s; 8.794 + *d++ = *(s+1); 8.795 + *d++ = *(s+2); 8.796 + s += 3; 8.797 + *d++ = *s; 8.798 + *d++ = *(s+1); 8.799 + *d++ = *(s+2); 8.800 + s += 3; 8.801 + *d++ = *s; 8.802 + *d++ = *(s+1); 8.803 + *d++ = *(s+2); 8.804 + s += 3; 8.805 + } 8.806 +} 8.807 + 8.808 +void (*sdlStretcher24[4])(u8 *, u8 *) = { 8.809 + sdlStretch24x1, 8.810 + sdlStretch24x2, 8.811 + sdlStretch24x3, 8.812 + sdlStretch24x4 8.813 +}; 8.814 + 8.815 +#endif 8.816 + 8.817 +u32 sdlFromHex(char *s) 8.818 +{ 8.819 + u32 value; 8.820 + sscanf(s, "%x", &value); 8.821 + return value; 8.822 +} 8.823 + 8.824 +#ifdef __MSC__ 8.825 +#define stat _stat 8.826 +#define S_IFDIR _S_IFDIR 8.827 +#endif 8.828 + 8.829 +void sdlCheckDirectory(char *dir) 8.830 +{ 8.831 + struct stat buf; 8.832 + 8.833 + int len = strlen(dir); 8.834 + 8.835 + char *p = dir + len - 1; 8.836 + 8.837 + if(*p == '/' || 8.838 + *p == '\\') 8.839 + *p = 0; 8.840 + 8.841 + if(stat(dir, &buf) == 0) { 8.842 + if(!(buf.st_mode & S_IFDIR)) { 8.843 + fprintf(stderr, "Error: %s is not a directory\n", dir); 8.844 + dir[0] = 0; 8.845 + } 8.846 + } else { 8.847 + fprintf(stderr, "Error: %s does not exist\n", dir); 8.848 + dir[0] = 0; 8.849 + } 8.850 +} 8.851 + 8.852 +char *sdlGetFilename(char *name) 8.853 +{ 8.854 + static char filebuffer[2048]; 8.855 + 8.856 + int len = strlen(name); 8.857 + 8.858 + char *p = name + len - 1; 8.859 + 8.860 + while(true) { 8.861 + if(*p == '/' || 8.862 + *p == '\\') { 8.863 + p++; 8.864 + break; 8.865 + } 8.866 + len--; 8.867 + p--; 8.868 + if(len == 0) 8.869 + break; 8.870 + } 8.871 + 8.872 + if(len == 0) 8.873 + strcpy(filebuffer, name); 8.874 + else 8.875 + strcpy(filebuffer, p); 8.876 + return filebuffer; 8.877 +} 8.878 + 8.879 +FILE *sdlFindFile(const char *name) 8.880 +{ 8.881 + char buffer[4096]; 8.882 + char path[2048]; 8.883 + 8.884 +#ifdef WIN32 8.885 +#define PATH_SEP ";" 8.886 +#define FILE_SEP '\\' 8.887 +#define EXE_NAME "VisualBoyAdvance-SDL.exe" 8.888 +#else // ! WIN32 8.889 +#define PATH_SEP ":" 8.890 +#define FILE_SEP '/' 8.891 +#define EXE_NAME "VisualBoyAdvance" 8.892 +#endif // ! WIN32 8.893 + 8.894 + fprintf(stderr, "Searching for file %s\n", name); 8.895 + 8.896 + if(GETCWD(buffer, 2048)) { 8.897 + fprintf(stderr, "Searching current directory: %s\n", buffer); 8.898 + } 8.899 + 8.900 + FILE *f = fopen(name, "r"); 8.901 + if(f != NULL) { 8.902 + return f; 8.903 + } 8.904 + 8.905 + char *home = getenv("HOME"); 8.906 + 8.907 + if(home != NULL) { 8.908 + fprintf(stderr, "Searching home directory: %s\n", home); 8.909 + sprintf(path, "%s%c%s", home, FILE_SEP, name); 8.910 + f = fopen(path, "r"); 8.911 + if(f != NULL) 8.912 + return f; 8.913 + } 8.914 + 8.915 +#ifdef WIN32 8.916 + home = getenv("USERPROFILE"); 8.917 + if(home != NULL) { 8.918 + fprintf(stderr, "Searching user profile directory: %s\n", home); 8.919 + sprintf(path, "%s%c%s", home, FILE_SEP, name); 8.920 + f = fopen(path, "r"); 8.921 + if(f != NULL) 8.922 + return f; 8.923 + } 8.924 +#else // ! WIN32 8.925 + fprintf(stderr, "Searching system config directory: %s\n", SYSCONFDIR); 8.926 + sprintf(path, "%s%c%s", SYSCONFDIR, FILE_SEP, name); 8.927 + f = fopen(path, "r"); 8.928 + if(f != NULL) 8.929 + return f; 8.930 +#endif // ! WIN32 8.931 + 8.932 + if(!strchr(arg0, '/') && 8.933 + !strchr(arg0, '\\')) { 8.934 + char *path = getenv("PATH"); 8.935 + 8.936 + if(path != NULL) { 8.937 + fprintf(stderr, "Searching PATH\n"); 8.938 + strncpy(buffer, path, 4096); 8.939 + buffer[4095] = 0; 8.940 + char *tok = strtok(buffer, PATH_SEP); 8.941 + 8.942 + while(tok) { 8.943 + sprintf(path, "%s%c%s", tok, FILE_SEP, EXE_NAME); 8.944 + f = fopen(path, "r"); 8.945 + if(f != NULL) { 8.946 + char path2[2048]; 8.947 + fclose(f); 8.948 + sprintf(path2, "%s%c%s", tok, FILE_SEP, name); 8.949 + f = fopen(path2, "r"); 8.950 + if(f != NULL) { 8.951 + fprintf(stderr, "Found at %s\n", path2); 8.952 + return f; 8.953 + } 8.954 + } 8.955 + tok = strtok(NULL, PATH_SEP); 8.956 + } 8.957 + } 8.958 + } else { 8.959 + // executable is relative to some directory 8.960 + fprintf(stderr, "Searching executable directory\n"); 8.961 + strcpy(buffer, arg0); 8.962 + char *p = strrchr(buffer, FILE_SEP); 8.963 + if(p) { 8.964 + *p = 0; 8.965 + sprintf(path, "%s%c%s", buffer, FILE_SEP, name); 8.966 + f = fopen(path, "r"); 8.967 + if(f != NULL) 8.968 + return f; 8.969 + } 8.970 + } 8.971 + return NULL; 8.972 +} 8.973 + 8.974 +void sdlReadPreferences(FILE *f) 8.975 +{ 8.976 + char buffer[2048]; 8.977 + 8.978 + while(1) { 8.979 + char *s = fgets(buffer, 2048, f); 8.980 + 8.981 + if(s == NULL) 8.982 + break; 8.983 + 8.984 + char *p = strchr(s, '#'); 8.985 + 8.986 + if(p) 8.987 + *p = 0; 8.988 + 8.989 + char *token = strtok(s, " \t\n\r="); 8.990 + 8.991 + if(!token) 8.992 + continue; 8.993 + 8.994 + if(strlen(token) == 0) 8.995 + continue; 8.996 + 8.997 + char *key = token; 8.998 + char *value = strtok(NULL, "\t\n\r"); 8.999 + 8.1000 + if(value == NULL) { 8.1001 + fprintf(stderr, "Empty value for key %s\n", key); 8.1002 + continue; 8.1003 + } 8.1004 + 8.1005 + if(!strcmp(key,"Joy0_Left")) { 8.1006 + joypad[0][KEY_LEFT] = sdlFromHex(value); 8.1007 + } else if(!strcmp(key, "Joy0_Right")) { 8.1008 + joypad[0][KEY_RIGHT] = sdlFromHex(value); 8.1009 + } else if(!strcmp(key, "Joy0_Up")) { 8.1010 + joypad[0][KEY_UP] = sdlFromHex(value); 8.1011 + } else if(!strcmp(key, "Joy0_Down")) { 8.1012 + joypad[0][KEY_DOWN] = sdlFromHex(value); 8.1013 + } else if(!strcmp(key, "Joy0_A")) { 8.1014 + joypad[0][KEY_BUTTON_A] = sdlFromHex(value); 8.1015 + } else if(!strcmp(key, "Joy0_B")) { 8.1016 + joypad[0][KEY_BUTTON_B] = sdlFromHex(value); 8.1017 + } else if(!strcmp(key, "Joy0_L")) { 8.1018 + joypad[0][KEY_BUTTON_L] = sdlFromHex(value); 8.1019 + } else if(!strcmp(key, "Joy0_R")) { 8.1020 + joypad[0][KEY_BUTTON_R] = sdlFromHex(value); 8.1021 + } else if(!strcmp(key, "Joy0_Start")) { 8.1022 + joypad[0][KEY_BUTTON_START] = sdlFromHex(value); 8.1023 + } else if(!strcmp(key, "Joy0_Select")) { 8.1024 + joypad[0][KEY_BUTTON_SELECT] = sdlFromHex(value); 8.1025 + } else if(!strcmp(key, "Joy0_Speed")) { 8.1026 + joypad[0][KEY_BUTTON_SPEED] = sdlFromHex(value); 8.1027 + } else if(!strcmp(key, "Joy0_Capture")) { 8.1028 + joypad[0][KEY_BUTTON_CAPTURE] = sdlFromHex(value); 8.1029 + } else if(!strcmp(key,"Joy1_Left")) { 8.1030 + joypad[1][KEY_LEFT] = sdlFromHex(value); 8.1031 + } else if(!strcmp(key, "Joy1_Right")) { 8.1032 + joypad[1][KEY_RIGHT] = sdlFromHex(value); 8.1033 + } else if(!strcmp(key, "Joy1_Up")) { 8.1034 + joypad[1][KEY_UP] = sdlFromHex(value); 8.1035 + } else if(!strcmp(key, "Joy1_Down")) { 8.1036 + joypad[1][KEY_DOWN] = sdlFromHex(value); 8.1037 + } else if(!strcmp(key, "Joy1_A")) { 8.1038 + joypad[1][KEY_BUTTON_A] = sdlFromHex(value); 8.1039 + } else if(!strcmp(key, "Joy1_B")) { 8.1040 + joypad[1][KEY_BUTTON_B] = sdlFromHex(value); 8.1041 + } else if(!strcmp(key, "Joy1_L")) { 8.1042 + joypad[1][KEY_BUTTON_L] = sdlFromHex(value); 8.1043 + } else if(!strcmp(key, "Joy1_R")) { 8.1044 + joypad[1][KEY_BUTTON_R] = sdlFromHex(value); 8.1045 + } else if(!strcmp(key, "Joy1_Start")) { 8.1046 + joypad[1][KEY_BUTTON_START] = sdlFromHex(value); 8.1047 + } else if(!strcmp(key, "Joy1_Select")) { 8.1048 + joypad[1][KEY_BUTTON_SELECT] = sdlFromHex(value); 8.1049 + } else if(!strcmp(key, "Joy1_Speed")) { 8.1050 + joypad[1][KEY_BUTTON_SPEED] = sdlFromHex(value); 8.1051 + } else if(!strcmp(key, "Joy1_Capture")) { 8.1052 + joypad[1][KEY_BUTTON_CAPTURE] = sdlFromHex(value); 8.1053 + } else if(!strcmp(key,"Joy2_Left")) { 8.1054 + joypad[2][KEY_LEFT] = sdlFromHex(value); 8.1055 + } else if(!strcmp(key, "Joy2_Right")) { 8.1056 + joypad[2][KEY_RIGHT] = sdlFromHex(value); 8.1057 + } else if(!strcmp(key, "Joy2_Up")) { 8.1058 + joypad[2][KEY_UP] = sdlFromHex(value); 8.1059 + } else if(!strcmp(key, "Joy2_Down")) { 8.1060 + joypad[2][KEY_DOWN] = sdlFromHex(value); 8.1061 + } else if(!strcmp(key, "Joy2_A")) { 8.1062 + joypad[2][KEY_BUTTON_A] = sdlFromHex(value); 8.1063 + } else if(!strcmp(key, "Joy2_B")) { 8.1064 + joypad[2][KEY_BUTTON_B] = sdlFromHex(value); 8.1065 + } else if(!strcmp(key, "Joy2_L")) { 8.1066 + joypad[2][KEY_BUTTON_L] = sdlFromHex(value); 8.1067 + } else if(!strcmp(key, "Joy2_R")) { 8.1068 + joypad[2][KEY_BUTTON_R] = sdlFromHex(value); 8.1069 + } else if(!strcmp(key, "Joy2_Start")) { 8.1070 + joypad[2][KEY_BUTTON_START] = sdlFromHex(value); 8.1071 + } else if(!strcmp(key, "Joy2_Select")) { 8.1072 + joypad[2][KEY_BUTTON_SELECT] = sdlFromHex(value); 8.1073 + } else if(!strcmp(key, "Joy2_Speed")) { 8.1074 + joypad[2][KEY_BUTTON_SPEED] = sdlFromHex(value); 8.1075 + } else if(!strcmp(key, "Joy2_Capture")) { 8.1076 + joypad[2][KEY_BUTTON_CAPTURE] = sdlFromHex(value); 8.1077 + } else if(!strcmp(key,"Joy4_Left")) { 8.1078 + joypad[4][KEY_LEFT] = sdlFromHex(value); 8.1079 + } else if(!strcmp(key, "Joy4_Right")) { 8.1080 + joypad[4][KEY_RIGHT] = sdlFromHex(value); 8.1081 + } else if(!strcmp(key, "Joy4_Up")) { 8.1082 + joypad[4][KEY_UP] = sdlFromHex(value); 8.1083 + } else if(!strcmp(key, "Joy4_Down")) { 8.1084 + joypad[4][KEY_DOWN] = sdlFromHex(value); 8.1085 + } else if(!strcmp(key, "Joy4_A")) { 8.1086 + joypad[4][KEY_BUTTON_A] = sdlFromHex(value); 8.1087 + } else if(!strcmp(key, "Joy4_B")) { 8.1088 + joypad[4][KEY_BUTTON_B] = sdlFromHex(value); 8.1089 + } else if(!strcmp(key, "Joy4_L")) { 8.1090 + joypad[4][KEY_BUTTON_L] = sdlFromHex(value); 8.1091 + } else if(!strcmp(key, "Joy4_R")) { 8.1092 + joypad[4][KEY_BUTTON_R] = sdlFromHex(value); 8.1093 + } else if(!strcmp(key, "Joy4_Start")) { 8.1094 + joypad[4][KEY_BUTTON_START] = sdlFromHex(value); 8.1095 + } else if(!strcmp(key, "Joy4_Select")) { 8.1096 + joypad[4][KEY_BUTTON_SELECT] = sdlFromHex(value); 8.1097 + } else if(!strcmp(key, "Joy4_Speed")) { 8.1098 + joypad[4][KEY_BUTTON_SPEED] = sdlFromHex(value); 8.1099 + } else if(!strcmp(key, "Joy4_Capture")) { 8.1100 + joypad[4][KEY_BUTTON_CAPTURE] = sdlFromHex(value); 8.1101 + } else if(!strcmp(key, "Motion_Left")) { 8.1102 + motion[KEY_LEFT] = sdlFromHex(value); 8.1103 + } else if(!strcmp(key, "Motion_Right")) { 8.1104 + motion[KEY_RIGHT] = sdlFromHex(value); 8.1105 + } else if(!strcmp(key, "Motion_Up")) { 8.1106 + motion[KEY_UP] = sdlFromHex(value); 8.1107 + } else if(!strcmp(key, "Motion_Down")) { 8.1108 + motion[KEY_DOWN] = sdlFromHex(value); 8.1109 + } else if(!strcmp(key, "frameSkip")) { 8.1110 + frameSkip = sdlFromHex(value); 8.1111 + if(frameSkip < 0 || frameSkip > 9) 8.1112 + frameSkip = 2; 8.1113 + } else if(!strcmp(key, "gbFrameSkip")) { 8.1114 + gbFrameSkip = sdlFromHex(value); 8.1115 + if(gbFrameSkip < 0 || gbFrameSkip > 9) 8.1116 + gbFrameSkip = 0; 8.1117 + } else if(!strcmp(key, "video")) { 8.1118 + sizeOption = sdlFromHex(value); 8.1119 + if(sizeOption < 0 || sizeOption > 3) 8.1120 + sizeOption = 1; 8.1121 + } else if(!strcmp(key, "fullScreen")) { 8.1122 + fullscreen = sdlFromHex(value) ? 1 : 0; 8.1123 + } else if(!strcmp(key, "useBios")) { 8.1124 + useBios = sdlFromHex(value) ? true : false; 8.1125 + } else if(!strcmp(key, "skipBios")) { 8.1126 + skipBios = sdlFromHex(value) ? true : false; 8.1127 + } else if(!strcmp(key, "biosFile")) { 8.1128 + strcpy(biosFileName, value); 8.1129 + } else if(!strcmp(key, "filter")) { 8.1130 + filter = sdlFromHex(value); 8.1131 + if(filter < 0 || filter > 13) 8.1132 + filter = 0; 8.1133 + } else if(!strcmp(key, "disableStatus")) { 8.1134 + disableStatusMessages = sdlFromHex(value) ? true : false; 8.1135 + } else if(!strcmp(key, "borderOn")) { 8.1136 + gbBorderOn = sdlFromHex(value) ? true : false; 8.1137 + } else if(!strcmp(key, "borderAutomatic")) { 8.1138 + gbBorderAutomatic = sdlFromHex(value) ? true : false; 8.1139 + } else if(!strcmp(key, "emulatorType")) { 8.1140 + gbEmulatorType = sdlFromHex(value); 8.1141 + if(gbEmulatorType < 0 || gbEmulatorType > 5) 8.1142 + gbEmulatorType = 1; 8.1143 + } else if(!strcmp(key, "colorOption")) { 8.1144 + gbColorOption = sdlFromHex(value) ? true : false; 8.1145 + } else if(!strcmp(key, "captureDir")) { 8.1146 + sdlCheckDirectory(value); 8.1147 + strcpy(captureDir, value); 8.1148 + } else if(!strcmp(key, "saveDir")) { 8.1149 + sdlCheckDirectory(value); 8.1150 + strcpy(saveDir, value); 8.1151 + } else if(!strcmp(key, "batteryDir")) { 8.1152 + sdlCheckDirectory(value); 8.1153 + strcpy(batteryDir, value); 8.1154 + } else if(!strcmp(key, "captureFormat")) { 8.1155 + captureFormat = sdlFromHex(value); 8.1156 + } else if(!strcmp(key, "soundQuality")) { 8.1157 + soundQuality = sdlFromHex(value); 8.1158 + switch(soundQuality) { 8.1159 + case 1: break; 8.1160 + default: 8.1161 + fprintf(stderr, "The rerecording version will run only sound at highest quality. Defaulting to 44.1 KHz\n"); 8.1162 + soundQuality = 1; 8.1163 + break; 8.1164 + } 8.1165 + } else if(!strcmp(key, "soundOff")) { 8.1166 + soundOffFlag = sdlFromHex(value) ? true : false; 8.1167 + } else if(!strcmp(key, "soundEnable")) { 8.1168 + int res = sdlFromHex(value) & 0x30f; 8.1169 + soundEnableChannels(res); 8.1170 + soundDisableChannels(~res); 8.1171 + } else if(!strcmp(key, "soundEcho")) { 8.1172 + soundEcho = sdlFromHex(value) ? true : false; 8.1173 + } else if(!strcmp(key, "soundLowPass")) { 8.1174 + soundLowPass = sdlFromHex(value) ? true : false; 8.1175 + } else if(!strcmp(key, "soundReverse")) { 8.1176 + soundReverse = sdlFromHex(value) ? true : false; 8.1177 + } else if(!strcmp(key, "soundVolume")) { 8.1178 + soundVolume = sdlFromHex(value); 8.1179 + if(soundVolume < 0 || soundVolume > 3) 8.1180 + soundVolume = 0; 8.1181 + } else if(!strcmp(key, "removeIntros")) { 8.1182 + removeIntros = sdlFromHex(value) ? true : false; 8.1183 + } else if(!strcmp(key, "saveType")) { 8.1184 + cpuSaveType = sdlFromHex(value); 8.1185 + if(cpuSaveType < 0 || cpuSaveType > 5) 8.1186 + cpuSaveType = 0; 8.1187 + } else if(!strcmp(key, "flashSize")) { 8.1188 + sdlFlashSize = sdlFromHex(value); 8.1189 + if(sdlFlashSize != 0 && sdlFlashSize != 1) 8.1190 + sdlFlashSize = 0; 8.1191 + } else if(!strcmp(key, "ifbType")) { 8.1192 + ifbType = sdlFromHex(value); 8.1193 + if(ifbType < 0 || ifbType > 2) 8.1194 + ifbType = 0; 8.1195 + } else if(!strcmp(key, "showSpeed")) { 8.1196 + showSpeed = sdlFromHex(value); 8.1197 + if(showSpeed < 0 || showSpeed > 2) 8.1198 + showSpeed = 1; 8.1199 + } else if(!strcmp(key, "showSpeedTransparent")) { 8.1200 + showSpeedTransparent = sdlFromHex(value); 8.1201 + } else if(!strcmp(key, "autoFrameSkip")) { 8.1202 + autoFrameSkip = sdlFromHex(value); 8.1203 + } else if(!strcmp(key, "throttle")) { 8.1204 + throttle = sdlFromHex(value); 8.1205 + if(throttle != 0 && (throttle < 5 || throttle > 1000)) 8.1206 + throttle = 0; 8.1207 + } else if(!strcmp(key, "disableMMX")) { 8.1208 +#ifdef MMX 8.1209 + cpu_mmx = sdlFromHex(value) ? false : true; 8.1210 +#endif 8.1211 + } else if(!strcmp(key, "pauseWhenInactive")) { 8.1212 + pauseWhenInactive = sdlFromHex(value) ? true : false; 8.1213 + } else if(!strcmp(key, "agbPrint")) { 8.1214 + sdlAgbPrint = sdlFromHex(value); 8.1215 + } else if(!strcmp(key, "rtcEnabled")) { 8.1216 + sdlRtcEnable = sdlFromHex(value); 8.1217 + } else if(!strcmp(key, "rewindTimer")) { 8.1218 + rewindTimer = sdlFromHex(value); 8.1219 + if(rewindTimer < 0 || rewindTimer > 600) 8.1220 + rewindTimer = 0; 8.1221 + rewindTimer *= 6; // convert value to 10 frames multiple 8.1222 + } else if(!strcmp(key, "enhancedDetection")) { 8.1223 + cpuEnhancedDetection = sdlFromHex(value) ? true : false; 8.1224 + } else { 8.1225 + fprintf(stderr, "Unknown configuration key %s\n", key); 8.1226 + } 8.1227 + } 8.1228 +} 8.1229 + 8.1230 +void sdlReadPreferences() 8.1231 +{ 8.1232 + FILE *f = sdlFindFile("VisualBoyAdvance.cfg"); 8.1233 + 8.1234 + if(f == NULL) { 8.1235 + fprintf(stderr, "Configuration file NOT FOUND (using defaults)\n"); 8.1236 + return; 8.1237 + } else 8.1238 + fprintf(stderr, "Reading configuration file.\n"); 8.1239 + 8.1240 + sdlReadPreferences(f); 8.1241 + 8.1242 + fclose(f); 8.1243 +} 8.1244 + 8.1245 +static void sdlApplyPerImagePreferences() 8.1246 +{ 8.1247 + FILE *f = sdlFindFile("vba-over.ini"); 8.1248 + if(!f) { 8.1249 + fprintf(stderr, "vba-over.ini NOT FOUND (using emulator settings)\n"); 8.1250 + return; 8.1251 + } else 8.1252 + fprintf(stderr, "Reading vba-over.ini\n"); 8.1253 + 8.1254 + char buffer[7]; 8.1255 + buffer[0] = '['; 8.1256 + buffer[1] = rom[0xac]; 8.1257 + buffer[2] = rom[0xad]; 8.1258 + buffer[3] = rom[0xae]; 8.1259 + buffer[4] = rom[0xaf]; 8.1260 + buffer[5] = ']'; 8.1261 + buffer[6] = 0; 8.1262 + 8.1263 + char readBuffer[2048]; 8.1264 + 8.1265 + bool found = false; 8.1266 + 8.1267 + while(1) { 8.1268 + char *s = fgets(readBuffer, 2048, f); 8.1269 + 8.1270 + if(s == NULL) 8.1271 + break; 8.1272 + 8.1273 + char *p = strchr(s, ';'); 8.1274 + 8.1275 + if(p) 8.1276 + *p = 0; 8.1277 + 8.1278 + char *token = strtok(s, " \t\n\r="); 8.1279 + 8.1280 + if(!token) 8.1281 + continue; 8.1282 + if(strlen(token) == 0) 8.1283 + continue; 8.1284 + 8.1285 + if(!strcmp(token, buffer)) { 8.1286 + found = true; 8.1287 + break; 8.1288 + } 8.1289 + } 8.1290 + 8.1291 + if(found) { 8.1292 + while(1) { 8.1293 + char *s = fgets(readBuffer, 2048, f); 8.1294 + 8.1295 + if(s == NULL) 8.1296 + break; 8.1297 + 8.1298 + char *p = strchr(s, ';'); 8.1299 + if(p) 8.1300 + *p = 0; 8.1301 + 8.1302 + char *token = strtok(s, " \t\n\r="); 8.1303 + if(!token) 8.1304 + continue; 8.1305 + if(strlen(token) == 0) 8.1306 + continue; 8.1307 + 8.1308 + if(token[0] == '[') // starting another image settings 8.1309 + break; 8.1310 + char *value = strtok(NULL, "\t\n\r="); 8.1311 + if(value == NULL) 8.1312 + continue; 8.1313 + 8.1314 + if(!strcmp(token, "rtcEnabled")) 8.1315 + rtcEnable(atoi(value) == 0 ? false : true); 8.1316 + else if(!strcmp(token, "flashSize")) { 8.1317 + int size = atoi(value); 8.1318 + if(size == 0x10000 || size == 0x20000) 8.1319 + flashSetSize(size); 8.1320 + } else if(!strcmp(token, "saveType")) { 8.1321 + int save = atoi(value); 8.1322 + if(save >= 0 && save <= 5) 8.1323 + cpuSaveType = save; 8.1324 + } 8.1325 + } 8.1326 + } 8.1327 + fclose(f); 8.1328 +} 8.1329 + 8.1330 +static int sdlCalculateShift(u32 mask) 8.1331 +{ 8.1332 + int m = 0; 8.1333 + 8.1334 + while(mask) { 8.1335 + m++; 8.1336 + mask >>= 1; 8.1337 + } 8.1338 + 8.1339 + return m-5; 8.1340 +} 8.1341 + 8.1342 +static int sdlCalculateMaskWidth(u32 mask) 8.1343 +{ 8.1344 + int m = 0; 8.1345 + int mask2 = mask; 8.1346 + 8.1347 + while(mask2) { 8.1348 + m++; 8.1349 + mask2 >>= 1; 8.1350 + } 8.1351 + 8.1352 + int m2 = 0; 8.1353 + mask2 = mask; 8.1354 + while(!(mask2 & 1)) { 8.1355 + m2++; 8.1356 + mask2 >>= 1; 8.1357 + } 8.1358 + 8.1359 + return m - m2; 8.1360 +} 8.1361 + 8.1362 +void sdlWriteState(int num) 8.1363 +{ 8.1364 + char stateName[2048]; 8.1365 + 8.1366 + if(saveDir[0]) 8.1367 + sprintf(stateName, "%s/%s%d.sgm", saveDir, sdlGetFilename(filename), 8.1368 + num+1); 8.1369 + else 8.1370 + sprintf(stateName,"%s%d.sgm", filename, num+1); 8.1371 + if(theEmulator.emuWriteState) 8.1372 + theEmulator.emuWriteState(stateName); 8.1373 + sprintf(stateName, "Wrote state %d", num+1); 8.1374 + systemScreenMessage(stateName); 8.1375 +} 8.1376 + 8.1377 +void sdlReadState(int num) 8.1378 +{ 8.1379 + char stateName[2048]; 8.1380 + 8.1381 + if(saveDir[0]) 8.1382 + sprintf(stateName, "%s/%s%d.sgm", saveDir, sdlGetFilename(filename), 8.1383 + num+1); 8.1384 + else 8.1385 + sprintf(stateName,"%s%d.sgm", filename, num+1); 8.1386 + 8.1387 + if(theEmulator.emuReadState) 8.1388 + theEmulator.emuReadState(stateName); 8.1389 + 8.1390 + sprintf(stateName, "Loaded state %d", num+1); 8.1391 + systemScreenMessage(stateName); 8.1392 +} 8.1393 + 8.1394 +void sdlWriteBattery() 8.1395 +{ 8.1396 + char buffer[1048]; 8.1397 + 8.1398 + if(batteryDir[0]) 8.1399 + sprintf(buffer, "%s/%s.sav", batteryDir, sdlGetFilename(filename)); 8.1400 + else 8.1401 + sprintf(buffer, "%s.sav", filename); 8.1402 + 8.1403 + theEmulator.emuWriteBattery(buffer); 8.1404 + 8.1405 + systemScreenMessage("Wrote battery"); 8.1406 +} 8.1407 + 8.1408 +void sdlReadBattery() 8.1409 +{ 8.1410 + char buffer[1048]; 8.1411 + 8.1412 + if(batteryDir[0]) 8.1413 + sprintf(buffer, "%s/%s.sav", batteryDir, sdlGetFilename(filename)); 8.1414 + else 8.1415 + sprintf(buffer, "%s.sav", filename); 8.1416 + 8.1417 + bool res = false; 8.1418 + 8.1419 + res = theEmulator.emuReadBattery(buffer); 8.1420 + 8.1421 + if(res) 8.1422 + systemScreenMessage("Loaded battery"); 8.1423 +} 8.1424 + 8.1425 +#define MOD_KEYS (KMOD_CTRL|KMOD_SHIFT|KMOD_ALT|KMOD_META) 8.1426 +#define MOD_NOCTRL (KMOD_SHIFT|KMOD_ALT|KMOD_META) 8.1427 +#define MOD_NOALT (KMOD_CTRL|KMOD_SHIFT|KMOD_META) 8.1428 +#define MOD_NOSHIFT (KMOD_CTRL|KMOD_ALT|KMOD_META) 8.1429 + 8.1430 +void sdlUpdateKey(int key, bool down) 8.1431 +{ 8.1432 + int i; 8.1433 + for(int j = 0; j < 4; j++) { 8.1434 + for(i = 0 ; i < 12; i++) { 8.1435 + if((joypad[j][i] & 0xf000) == 0) { 8.1436 + if(key == joypad[j][i]) 8.1437 + if (down) currentButtons[j] |= 1<<i; 8.1438 + else currentButtons[j] ^= 1<<i; 8.1439 + } 8.1440 + } 8.1441 + } 8.1442 + for(i = 0 ; i < 4; i++) { 8.1443 + if((motion[i] & 0xf000) == 0) { 8.1444 + if(key == motion[i]) 8.1445 + sdlMotionButtons[i] = down; 8.1446 + } 8.1447 + } 8.1448 +} 8.1449 + 8.1450 +void sdlUpdateJoyButton(int which, 8.1451 + int button, 8.1452 + bool pressed) 8.1453 +{ 8.1454 + int i; 8.1455 + for(int j = 0; j < 4; j++) { 8.1456 + for(i = 0; i < 12; i++) { 8.1457 + int dev = (joypad[j][i] >> 12); 8.1458 + int b = joypad[j][i] & 0xfff; 8.1459 + if(dev) { 8.1460 + dev--; 8.1461 + 8.1462 + if((dev == which) && (b >= 128) && (b == (button+128))) { 8.1463 + if (pressed) currentButtons[j] |= 1<<i; 8.1464 + else currentButtons[j] ^= 1<<i; 8.1465 + } 8.1466 + } 8.1467 + } 8.1468 + } 8.1469 + for(i = 0; i < 4; i++) { 8.1470 + int dev = (motion[i] >> 12); 8.1471 + int b = motion[i] & 0xfff; 8.1472 + if(dev) { 8.1473 + dev--; 8.1474 + 8.1475 + if((dev == which) && (b >= 128) && (b == (button+128))) { 8.1476 + sdlMotionButtons[i] = pressed; 8.1477 + } 8.1478 + } 8.1479 + } 8.1480 +} 8.1481 + 8.1482 +void sdlUpdateJoyHat(int which, 8.1483 + int hat, 8.1484 + int value) 8.1485 +{ 8.1486 + int i; 8.1487 + for(int j = 0; j < 4; j++) { 8.1488 + for(i = 0; i < 12; i++) { 8.1489 + int dev = (joypad[j][i] >> 12); 8.1490 + int a = joypad[j][i] & 0xfff; 8.1491 + if(dev) { 8.1492 + dev--; 8.1493 + 8.1494 + if((dev == which) && (a>=32) && (a < 48) && (((a&15)>>2) == hat)) { 8.1495 + int dir = a & 3; 8.1496 + int v = 0; 8.1497 + switch(dir) { 8.1498 + case 0: 8.1499 + v = value & SDL_HAT_UP; 8.1500 + break; 8.1501 + case 1: 8.1502 + v = value & SDL_HAT_DOWN; 8.1503 + break; 8.1504 + case 2: 8.1505 + v = value & SDL_HAT_RIGHT; 8.1506 + break; 8.1507 + case 3: 8.1508 + v = value & SDL_HAT_LEFT; 8.1509 + break; 8.1510 + } 8.1511 + if (v) currentButtons[j] |= 1<<i; 8.1512 + else currentButtons[j] ^= 1<<i; 8.1513 + } 8.1514 + } 8.1515 + } 8.1516 + } 8.1517 + for(i = 0; i < 4; i++) { 8.1518 + int dev = (motion[i] >> 12); 8.1519 + int a = motion[i] & 0xfff; 8.1520 + if(dev) { 8.1521 + dev--; 8.1522 + 8.1523 + if((dev == which) && (a>=32) && (a < 48) && (((a&15)>>2) == hat)) { 8.1524 + int dir = a & 3; 8.1525 + int v = 0; 8.1526 + switch(dir) { 8.1527 + case 0: 8.1528 + v = value & SDL_HAT_UP; 8.1529 + break; 8.1530 + case 1: 8.1531 + v = value & SDL_HAT_DOWN; 8.1532 + break; 8.1533 + case 2: 8.1534 + v = value & SDL_HAT_RIGHT; 8.1535 + break; 8.1536 + case 3: 8.1537 + v = value & SDL_HAT_LEFT; 8.1538 + break; 8.1539 + } 8.1540 + sdlMotionButtons[i] = (v ? true : false); 8.1541 + } 8.1542 + } 8.1543 + } 8.1544 +} 8.1545 + 8.1546 +void sdlUpdateJoyAxis(int which, 8.1547 + int axis, 8.1548 + int value) 8.1549 +{ 8.1550 + int i; 8.1551 + for(int j = 0; j < 4; j++) { 8.1552 + for(i = 0; i < 12; i++) { 8.1553 + int dev = (joypad[j][i] >> 12); 8.1554 + int a = joypad[j][i] & 0xfff; 8.1555 + if(dev) { 8.1556 + dev--; 8.1557 + 8.1558 + if((dev == which) && (a < 32) && ((a>>1) == axis)) { 8.1559 + //I have no idea what this does, is this reimplementation correct? --Felipe 8.1560 + if (value>16384) { 8.1561 + if (a&1) currentButtons[j] |= 1<<i; 8.1562 + else currentButtons[j] ^= 1<<i; 8.1563 + } 8.1564 + else if (value<16384){ 8.1565 + if (a&1) currentButtons[j] ^= 1<<i; 8.1566 + else currentButtons[j] |= 1<<i; 8.1567 + } 8.1568 + } 8.1569 + } 8.1570 + } 8.1571 + } 8.1572 + for(i = 0; i < 4; i++) { 8.1573 + int dev = (motion[i] >> 12); 8.1574 + int a = motion[i] & 0xfff; 8.1575 + if(dev) { 8.1576 + dev--; 8.1577 + 8.1578 + if((dev == which) && (a < 32) && ((a>>1) == axis)) { 8.1579 + sdlMotionButtons[i] = (a & 1) ? (value > 16384) : (value < -16384); 8.1580 + } 8.1581 + } 8.1582 + } 8.1583 +} 8.1584 + 8.1585 +bool sdlCheckJoyKey(int key) 8.1586 +{ 8.1587 + int dev = (key >> 12) - 1; 8.1588 + int what = key & 0xfff; 8.1589 + 8.1590 + if(what >= 128) { 8.1591 + // joystick button 8.1592 + int button = what - 128; 8.1593 + 8.1594 + if(button >= SDL_JoystickNumButtons(sdlDevices[dev])) 8.1595 + return false; 8.1596 + } else if (what < 0x20) { 8.1597 + // joystick axis 8.1598 + what >>= 1; 8.1599 + if(what >= SDL_JoystickNumAxes(sdlDevices[dev])) 8.1600 + return false; 8.1601 + } else if (what < 0x30) { 8.1602 + // joystick hat 8.1603 + what = (what & 15); 8.1604 + what >>= 2; 8.1605 + if(what >= SDL_JoystickNumHats(sdlDevices[dev])) 8.1606 + return false; 8.1607 + } 8.1608 + 8.1609 + // no problem found 8.1610 + return true; 8.1611 +} 8.1612 + 8.1613 +void sdlCheckKeys() 8.1614 +{ 8.1615 + sdlNumDevices = SDL_NumJoysticks(); 8.1616 + 8.1617 + if(sdlNumDevices) 8.1618 + sdlDevices = (SDL_Joystick **)calloc(1,sdlNumDevices * 8.1619 + sizeof(SDL_Joystick **)); 8.1620 + int i; 8.1621 + 8.1622 + bool usesJoy = false; 8.1623 + 8.1624 + for(int j = 0; j < 4; j++) { 8.1625 + for(i = 0; i < 12; i++) { 8.1626 + int dev = joypad[j][i] >> 12; 8.1627 + if(dev) { 8.1628 + dev--; 8.1629 + bool ok = false; 8.1630 + 8.1631 + if(sdlDevices) { 8.1632 + if(dev < sdlNumDevices) { 8.1633 + if(sdlDevices[dev] == NULL) { 8.1634 + sdlDevices[dev] = SDL_JoystickOpen(dev); 8.1635 + } 8.1636 + 8.1637 + ok = sdlCheckJoyKey(joypad[j][i]); 8.1638 + } else 8.1639 + ok = false; 8.1640 + } 8.1641 + 8.1642 + if(!ok) 8.1643 + joypad[j][i] = defaultJoypad[i]; 8.1644 + else 8.1645 + usesJoy = true; 8.1646 + } 8.1647 + } 8.1648 + } 8.1649 + 8.1650 + for(i = 0; i < 4; i++) { 8.1651 + int dev = motion[i] >> 12; 8.1652 + if(dev) { 8.1653 + dev--; 8.1654 + bool ok = false; 8.1655 + 8.1656 + if(sdlDevices) { 8.1657 + if(dev < sdlNumDevices) { 8.1658 + if(sdlDevices[dev] == NULL) { 8.1659 + sdlDevices[dev] = SDL_JoystickOpen(dev); 8.1660 + } 8.1661 + 8.1662 + ok = sdlCheckJoyKey(motion[i]); 8.1663 + } else 8.1664 + ok = false; 8.1665 + } 8.1666 + 8.1667 + if(!ok) 8.1668 + motion[i] = defaultMotion[i]; 8.1669 + else 8.1670 + usesJoy = true; 8.1671 + } 8.1672 + } 8.1673 + 8.1674 + if(usesJoy) 8.1675 + SDL_JoystickEventState(SDL_ENABLE); 8.1676 +} 8.1677 + 8.1678 +void sdlPollEvents() 8.1679 +{ 8.1680 + SDL_Event event; 8.1681 + while(SDL_PollEvent(&event)) { 8.1682 + switch(event.type) { 8.1683 + case SDL_QUIT: 8.1684 + emulating = 0; 8.1685 + break; 8.1686 + case SDL_ACTIVEEVENT: 8.1687 + if(pauseWhenInactive && (event.active.state & SDL_APPINPUTFOCUS)) { 8.1688 + active = event.active.gain; 8.1689 + if(active) { 8.1690 + if(!paused) { 8.1691 + if(emulating) 8.1692 + soundResume(); 8.1693 + } 8.1694 + } else { 8.1695 + wasPaused = true; 8.1696 + if(pauseWhenInactive) { 8.1697 + if(emulating) 8.1698 + soundPause(); 8.1699 + } 8.1700 + 8.1701 + memset(delta,255,sizeof(delta)); 8.1702 + } 8.1703 + } 8.1704 + break; 8.1705 + case SDL_MOUSEMOTION: 8.1706 + case SDL_MOUSEBUTTONUP: 8.1707 + case SDL_MOUSEBUTTONDOWN: 8.1708 + if(fullscreen) { 8.1709 + SDL_ShowCursor(SDL_ENABLE); 8.1710 + mouseCounter = 120; 8.1711 + } 8.1712 + break; 8.1713 + case SDL_JOYHATMOTION: 8.1714 + sdlUpdateJoyHat(event.jhat.which, 8.1715 + event.jhat.hat, 8.1716 + event.jhat.value); 8.1717 + break; 8.1718 + case SDL_JOYBUTTONDOWN: 8.1719 + case SDL_JOYBUTTONUP: 8.1720 + sdlUpdateJoyButton(event.jbutton.which, 8.1721 + event.jbutton.button, 8.1722 + event.jbutton.state == SDL_PRESSED); 8.1723 + break; 8.1724 + case SDL_JOYAXISMOTION: 8.1725 + sdlUpdateJoyAxis(event.jaxis.which, 8.1726 + event.jaxis.axis, 8.1727 + event.jaxis.value); 8.1728 + break; 8.1729 + case SDL_KEYDOWN: 8.1730 + sdlUpdateKey(event.key.keysym.sym, true); 8.1731 + break; 8.1732 + case SDL_KEYUP: 8.1733 + switch(event.key.keysym.sym) { 8.1734 + case SDLK_r: 8.1735 + if(!(event.key.keysym.mod & MOD_NOCTRL) && 8.1736 + (event.key.keysym.mod & KMOD_CTRL)) { 8.1737 + if(emulating) { 8.1738 + theEmulator.emuReset(true); 8.1739 + 8.1740 + systemScreenMessage("Reset"); 8.1741 + } 8.1742 + } 8.1743 + break; 8.1744 + case SDLK_b: 8.1745 + if(!(event.key.keysym.mod & MOD_NOCTRL) && 8.1746 + (event.key.keysym.mod & KMOD_CTRL)) { 8.1747 + if(emulating && theEmulator.emuReadMemState && rewindMemory 8.1748 + && rewindCount) { 8.1749 + rewindPos = --rewindPos & 7; 8.1750 + theEmulator.emuReadMemState(&rewindMemory[REWIND_SIZE*rewindPos], 8.1751 + REWIND_SIZE); 8.1752 + rewindCount--; 8.1753 + rewindCounter = 0; 8.1754 + systemScreenMessage("Rewind"); 8.1755 + } 8.1756 + } 8.1757 + break; 8.1758 + case SDLK_p: 8.1759 + if(!(event.key.keysym.mod & MOD_NOCTRL) && 8.1760 + (event.key.keysym.mod & KMOD_CTRL)) { 8.1761 + paused = !paused; 8.1762 + SDL_PauseAudio(paused); 8.1763 + if(paused) 8.1764 + wasPaused = true; 8.1765 + } 8.1766 + break; 8.1767 + case SDLK_ESCAPE: 8.1768 + emulating = 0; 8.1769 + break; 8.1770 + case SDLK_f: 8.1771 + if(!(event.key.keysym.mod & MOD_NOCTRL) && 8.1772 + (event.key.keysym.mod & KMOD_CTRL)) { 8.1773 + int flags = 0; 8.1774 + fullscreen = !fullscreen; 8.1775 + if(fullscreen) 8.1776 + flags |= SDL_FULLSCREEN; 8.1777 + SDL_SetVideoMode(destWidth, destHeight, systemColorDepth, flags); 8.1778 + // if(SDL_WM_ToggleFullScreen(surface)) 8.1779 + // fullscreen = !fullscreen; 8.1780 + } 8.1781 + break; 8.1782 + case SDLK_F11: 8.1783 + if(dbgMain != debuggerMain) { 8.1784 + if(armState) { 8.1785 + armNextPC -= 4; 8.1786 + reg[15].I -= 4; 8.1787 + } else { 8.1788 + armNextPC -= 2; 8.1789 + reg[15].I -= 2; 8.1790 + } 8.1791 + } 8.1792 + debugger = true; 8.1793 + break; 8.1794 + case SDLK_F1: 8.1795 + case SDLK_F2: 8.1796 + case SDLK_F3: 8.1797 + case SDLK_F4: 8.1798 + case SDLK_F5: 8.1799 + case SDLK_F6: 8.1800 + case SDLK_F7: 8.1801 + case SDLK_F8: 8.1802 + case SDLK_F9: 8.1803 + case SDLK_F10: 8.1804 + if(!(event.key.keysym.mod & MOD_NOSHIFT) && 8.1805 + (event.key.keysym.mod & KMOD_SHIFT)) { 8.1806 + sdlWriteState(event.key.keysym.sym-SDLK_F1); 8.1807 + } else if(!(event.key.keysym.mod & MOD_KEYS)) { 8.1808 + sdlReadState(event.key.keysym.sym-SDLK_F1); 8.1809 + } 8.1810 + break; 8.1811 + case SDLK_1: 8.1812 + case SDLK_2: 8.1813 + case SDLK_3: 8.1814 + case SDLK_4: 8.1815 + if(!(event.key.keysym.mod & MOD_NOALT) && 8.1816 + (event.key.keysym.mod & KMOD_ALT)) { 8.1817 + char *disableMessages[4] = 8.1818 + { "autofire A disabled", 8.1819 + "autofire B disabled", 8.1820 + "autofire R disabled", 8.1821 + "autofire L disabled"}; 8.1822 + char *enableMessages[4] = 8.1823 + { "autofire A", 8.1824 + "autofire B", 8.1825 + "autofire R", 8.1826 + "autofire L"}; 8.1827 + int mask = 1 << (event.key.keysym.sym - SDLK_1); 8.1828 + if(event.key.keysym.sym > SDLK_2) 8.1829 + mask <<= 6; 8.1830 + if(autoFire & mask) { 8.1831 + autoFire &= ~mask; 8.1832 + systemScreenMessage(disableMessages[event.key.keysym.sym - SDLK_1]); 8.1833 + } else { 8.1834 + autoFire |= mask; 8.1835 + systemScreenMessage(enableMessages[event.key.keysym.sym - SDLK_1]); 8.1836 + } 8.1837 + } if(!(event.key.keysym.mod & MOD_NOCTRL) && 8.1838 + (event.key.keysym.mod & KMOD_CTRL)) { 8.1839 + int mask = 0x0100 << (event.key.keysym.sym - SDLK_1); 8.1840 + layerSettings ^= mask; 8.1841 + layerEnable = DISPCNT & layerSettings; 8.1842 + CPUUpdateRenderBuffers(false); 8.1843 + } 8.1844 + break; 8.1845 + case SDLK_5: 8.1846 + case SDLK_6: 8.1847 + case SDLK_7: 8.1848 + case SDLK_8: 8.1849 + if(!(event.key.keysym.mod & MOD_NOCTRL) && 8.1850 + (event.key.keysym.mod & KMOD_CTRL)) { 8.1851 + int mask = 0x0100 << (event.key.keysym.sym - SDLK_1); 8.1852 + layerSettings ^= mask; 8.1853 + layerEnable = DISPCNT & layerSettings; 8.1854 + } 8.1855 + break; 8.1856 + case SDLK_n: 8.1857 + if(!(event.key.keysym.mod & MOD_NOCTRL) && 8.1858 + (event.key.keysym.mod & KMOD_CTRL)) { 8.1859 + if(paused) 8.1860 + paused = false; 8.1861 + pauseNextFrame = true; 8.1862 + } 8.1863 + break; 8.1864 + default: 8.1865 + break; 8.1866 + } 8.1867 + sdlUpdateKey(event.key.keysym.sym, false); 8.1868 + break; 8.1869 + } 8.1870 + } 8.1871 +} 8.1872 + 8.1873 +void usage(char *cmd) 8.1874 +{ 8.1875 + printf("%s [option ...] file\n", cmd); 8.1876 + printf("\ 8.1877 +\n\ 8.1878 +Options:\n\ 8.1879 + -1, --video-1x 1x\n\ 8.1880 + -2, --video-2x 2x\n\ 8.1881 + -3, --video-3x 3x\n\ 8.1882 + -4, --video-4x 4x\n\ 8.1883 + -F, --fullscreen Full screen\n\ 8.1884 + -G, --gdb=PROTOCOL GNU Remote Stub mode:\n\ 8.1885 + tcp - use TCP at port 55555\n\ 8.1886 + tcp:PORT - use TCP at port PORT\n\ 8.1887 + pipe - use pipe transport\n\ 8.1888 + -N, --no-debug Don't parse debug information\n\ 8.1889 + -S, --flash-size=SIZE Set the Flash size\n\ 8.1890 + --flash-64k 0 - 64K Flash\n\ 8.1891 + --flash-128k 1 - 128K Flash\n\ 8.1892 + -T, --throttle=THROTTLE Set the desired throttle (5...1000)\n\ 8.1893 + -Y, --yuv=TYPE Use YUV overlay for drawing:\n\ 8.1894 + 0 - YV12\n\ 8.1895 + 1 - UYVY\n\ 8.1896 + 2 - YVYU\n\ 8.1897 + 3 - YUY2\n\ 8.1898 + 4 - IYUV\n\ 8.1899 + -b, --bios=BIOS Use given bios file\n\ 8.1900 + -c, --config=FILE Read the given configuration file\n\ 8.1901 + -d, --debug Enter debugger\n\ 8.1902 + -f, --filter=FILTER Select filter:\n\ 8.1903 + --filter-normal 0 - normal mode\n\ 8.1904 + --filter-tv-mode 1 - TV Mode\n\ 8.1905 + --filter-2xsai 2 - 2xSaI\n\ 8.1906 + --filter-super-2xsai 3 - Super 2xSaI\n\ 8.1907 + --filter-super-eagle 4 - Super Eagle\n\ 8.1908 + --filter-pixelate 5 - Pixelate\n\ 8.1909 + --filter-motion-blur 6 - Motion Blur\n\ 8.1910 + --filter-advmame 7 - AdvanceMAME Scale2x\n\ 8.1911 + --filter-simple2x 8 - Simple2x\n\ 8.1912 + --filter-bilinear 9 - Bilinear\n\ 8.1913 + --filter-bilinear+ 10 - Bilinear Plus\n\ 8.1914 + --filter-scanlines 11 - Scanlines\n\ 8.1915 + --filter-hq2x 12 - hq2x\n\ 8.1916 + --filter-lq2x 13 - lq2x\n\ 8.1917 + -h, --help Print this help\n\ 8.1918 + -i, --ips=PATCH Apply given IPS patch\n\ 8.1919 + -P, --profile=[HERTZ] Enable profiling\n\ 8.1920 + -s, --frameskip=FRAMESKIP Set frame skip (0...9)\n\ 8.1921 +"); 8.1922 + printf("\ 8.1923 + -t, --save-type=TYPE Set the available save type\n\ 8.1924 + --save-auto 0 - Automatic (EEPROM, SRAM, FLASH)\n\ 8.1925 + --save-eeprom 1 - EEPROM\n\ 8.1926 + --save-sram 2 - SRAM\n\ 8.1927 + --save-flash 3 - FLASH\n\ 8.1928 + --save-sensor 4 - EEPROM+Sensor\n\ 8.1929 + --save-none 5 - NONE\n\ 8.1930 + -v, --verbose=VERBOSE Set verbose logging (trace.log)\n\ 8.1931 + 1 - SWI\n\ 8.1932 + 2 - Unaligned memory access\n\ 8.1933 + 4 - Illegal memory write\n\ 8.1934 + 8 - Illegal memory read\n\ 8.1935 + 16 - DMA 0\n\ 8.1936 + 32 - DMA 1\n\ 8.1937 + 64 - DMA 2\n\ 8.1938 + 128 - DMA 3\n\ 8.1939 + 256 - Undefined instruction\n\ 8.1940 + 512 - AGBPrint messages\n\ 8.1941 +\n\ 8.1942 +Long options only:\n\ 8.1943 + --agb-print Enable AGBPrint support\n\ 8.1944 + --auto-frameskip Enable auto frameskipping\n\ 8.1945 + --ifb-none No interframe blending\n\ 8.1946 + --ifb-motion-blur Interframe motion blur\n\ 8.1947 + --ifb-smart Smart interframe blending\n\ 8.1948 + --no-agb-print Disable AGBPrint support\n\ 8.1949 + --no-auto-frameskip Disable auto frameskipping\n\ 8.1950 + --no-ips Do not apply IPS patch\n\ 8.1951 + --no-mmx Disable MMX support\n\ 8.1952 + --no-pause-when-inactive Don't pause when inactive\n\ 8.1953 + --no-rtc Disable RTC support\n\ 8.1954 + --no-show-speed Don't show emulation speed\n\ 8.1955 + --no-throttle Disable thrrotle\n\ 8.1956 + --pause-when-inactive Pause when inactive\n\ 8.1957 + --rtc Enable RTC support\n\ 8.1958 + --show-speed-normal Show emulation speed\n\ 8.1959 + --show-speed-detailed Show detailed speed data\n\ 8.1960 +"); 8.1961 + printf("\ 8.1962 + -r, --recordmovie=filename Start recording input movie\n\ 8.1963 + -p, --playmovie=filename Play input movie non-read-only\n\ 8.1964 + -w, --watchmovie=filename Play input movie in read-only mode\n\ 8.1965 +"); 8.1966 +} 8.1967 + 8.1968 +static char *szFile; 8.1969 + 8.1970 +void file_run() 8.1971 +{ 8.1972 + utilGetBaseName(szFile, filename); 8.1973 + char *p = strrchr(filename, '.'); 8.1974 + 8.1975 + if(p) 8.1976 + *p = 0; 8.1977 + 8.1978 + if(ipsname[0] == 0) 8.1979 + sprintf(ipsname, "%s.ips", filename); 8.1980 + 8.1981 + bool failed = false; 8.1982 + 8.1983 + IMAGE_TYPE type = utilFindType(szFile); 8.1984 + 8.1985 + if(type == IMAGE_UNKNOWN) { 8.1986 + systemMessage(0, "Unknown file type %s", szFile); 8.1987 + exit(-1); 8.1988 + } 8.1989 + systemCartridgeType = (int)type; 8.1990 + 8.1991 + if(type == IMAGE_GB) { 8.1992 + failed = !gbLoadRom(szFile); 8.1993 + if(!failed) { 8.1994 + systemCartridgeType = 1; 8.1995 + theEmulator = GBSystem; 8.1996 + if(sdlAutoIPS) { 8.1997 + int size = gbRomSize; 8.1998 + utilApplyIPS(ipsname, &gbRom, &size); 8.1999 + if(size != gbRomSize) { 8.2000 + extern bool gbUpdateSizes(); 8.2001 + gbUpdateSizes(); 8.2002 + gbReset(); 8.2003 + } 8.2004 + } 8.2005 + } 8.2006 + } else if(type == IMAGE_GBA) { 8.2007 + int size = CPULoadRom(szFile); 8.2008 + failed = (size == 0); 8.2009 + if(!failed) { 8.2010 + // if(cpuEnhancedDetection && cpuSaveType == 0) { 8.2011 + // utilGBAFindSave(rom, size); 8.2012 + // } 8.2013 + 8.2014 + sdlApplyPerImagePreferences(); 8.2015 + 8.2016 + systemCartridgeType = 0; 8.2017 + theEmulator = GBASystem; 8.2018 + 8.2019 + /* disabled due to problems 8.2020 + if(removeIntros && rom != NULL) { 8.2021 + WRITE32LE(&rom[0], 0xea00002e); 8.2022 + } 8.2023 + */ 8.2024 + 8.2025 + //CPUInit(biosFileName, useBios); 8.2026 + CPUInit(); 8.2027 + CPUReset(); 8.2028 + if(sdlAutoIPS) { 8.2029 + int size = 0x2000000; 8.2030 + utilApplyIPS(ipsname, &rom, &size); 8.2031 + if(size != 0x2000000) { 8.2032 + CPUReset(); 8.2033 + } 8.2034 + } 8.2035 + } 8.2036 + } 8.2037 + 8.2038 + if(failed) { 8.2039 + systemMessage(0, "Failed to load file %s", szFile); 8.2040 + exit(-1); 8.2041 + } 8.2042 + 8.2043 + emulating = 1; 8.2044 + renderedFrames = 0; 8.2045 + } 8.2046 + 8.2047 +int main(int argc, char **argv) 8.2048 +{ 8.2049 + fprintf(stderr, "VisualBoyAdvance version %s [SDL]\n", VERSION); 8.2050 + 8.2051 + arg0 = argv[0]; 8.2052 + 8.2053 + captureDir[0] = 0; 8.2054 + saveDir[0] = 0; 8.2055 + batteryDir[0] = 0; 8.2056 + ipsname[0] = 0; 8.2057 + 8.2058 + int op = -1; 8.2059 + 8.2060 + frameSkip = 2; 8.2061 + gbBorderOn = 0; 8.2062 + 8.2063 + parseDebug = true; 8.2064 + 8.2065 + sdlReadPreferences(); 8.2066 + 8.2067 + sdlPrintUsage = 0; 8.2068 + 8.2069 + while((op = getopt_long(argc, 8.2070 + argv, 8.2071 + "FNT:Y:G:D:b:c:df:hi:p::s:t:v:1234", 8.2072 + sdlOptions, 8.2073 + NULL)) != -1) { 8.2074 + switch(op) { 8.2075 + case 0: 8.2076 + // long option already processed by getopt_long 8.2077 + break; 8.2078 + case 'b': 8.2079 + useBios = true; 8.2080 + if(optarg == NULL) { 8.2081 + fprintf(stderr, "Missing BIOS file name\n"); 8.2082 + exit(-1); 8.2083 + } 8.2084 + strcpy(biosFileName, optarg); 8.2085 + break; 8.2086 + case 'c': 8.2087 + { 8.2088 + if(optarg == NULL) { 8.2089 + fprintf(stderr, "Missing config file name\n"); 8.2090 + exit(-1); 8.2091 + } 8.2092 + FILE *f = fopen(optarg, "r"); 8.2093 + if(f == NULL) { 8.2094 + fprintf(stderr, "File not found %s\n", optarg); 8.2095 + exit(-1); 8.2096 + } 8.2097 + sdlReadPreferences(f); 8.2098 + fclose(f); 8.2099 + } 8.2100 + break; 8.2101 + case 'd': 8.2102 + debugger = true; 8.2103 + break; 8.2104 + case 'h': 8.2105 + sdlPrintUsage = 1; 8.2106 + break; 8.2107 + case 'i': 8.2108 + if(optarg == NULL) { 8.2109 + fprintf(stderr, "Missing IPS name\n"); 8.2110 + exit(-1); 8.2111 + strcpy(ipsname, optarg); 8.2112 + } 8.2113 + break; 8.2114 + case 'Y': 8.2115 + yuv = true; 8.2116 + if(optarg) { 8.2117 + yuvType = atoi(optarg); 8.2118 + switch(yuvType) { 8.2119 + case 0: 8.2120 + yuvType = SDL_YV12_OVERLAY; 8.2121 + break; 8.2122 + case 1: 8.2123 + yuvType = SDL_UYVY_OVERLAY; 8.2124 + break; 8.2125 + case 2: 8.2126 + yuvType = SDL_YVYU_OVERLAY; 8.2127 + break; 8.2128 + case 3: 8.2129 + yuvType = SDL_YUY2_OVERLAY; 8.2130 + break; 8.2131 + case 4: 8.2132 + yuvType = SDL_IYUV_OVERLAY; 8.2133 + break; 8.2134 + default: 8.2135 + yuvType = SDL_YV12_OVERLAY; 8.2136 + } 8.2137 + } else 8.2138 + yuvType = SDL_YV12_OVERLAY; 8.2139 + break; 8.2140 + case 'G': 8.2141 + dbgMain = remoteStubMain; 8.2142 + dbgSignal = remoteStubSignal; 8.2143 + dbgOutput = remoteOutput; 8.2144 + debugger = true; 8.2145 + debuggerStub = true; 8.2146 + if(optarg) { 8.2147 + char *s = optarg; 8.2148 + if(strncmp(s,"tcp:", 4) == 0) { 8.2149 + s+=4; 8.2150 + int port = atoi(s); 8.2151 + remoteSetProtocol(0); 8.2152 + remoteSetPort(port); 8.2153 + } else if(strcmp(s,"tcp") == 0) { 8.2154 + remoteSetProtocol(0); 8.2155 + } else if(strcmp(s, "pipe") == 0) { 8.2156 + remoteSetProtocol(1); 8.2157 + } else { 8.2158 + fprintf(stderr, "Unknown protocol %s\n", s); 8.2159 + exit(-1); 8.2160 + } 8.2161 + } else { 8.2162 + remoteSetProtocol(0); 8.2163 + } 8.2164 + break; 8.2165 + case 'N': 8.2166 + parseDebug = false; 8.2167 + break; 8.2168 + case 'D': 8.2169 + if(optarg) { 8.2170 + systemDebug = atoi(optarg); 8.2171 + } else { 8.2172 + systemDebug = 1; 8.2173 + } 8.2174 + break; 8.2175 + case 'F': 8.2176 + fullscreen = 1; 8.2177 + mouseCounter = 120; 8.2178 + break; 8.2179 + case 'f': 8.2180 + if(optarg) { 8.2181 + filter = atoi(optarg); 8.2182 + } else { 8.2183 + filter = 0; 8.2184 + } 8.2185 + break; 8.2186 + 8.2187 + case 'r': 8.2188 + if(optarg == NULL) { 8.2189 + fprintf(stderr, "ERROR: --recordMovie ('r') needs movie filename as option\n"); 8.2190 + exit(-1); 8.2191 + } 8.2192 + strcpy(movieFileName, optarg); 8.2193 + useMovie = 1; 8.2194 + break; 8.2195 + case 'p': // play without read-only (editable) 8.2196 + fprintf (stderr, "-p got called!\n"); 8.2197 + if(optarg == NULL) { 8.2198 + fprintf(stderr, "ERROR: --playMovie ('p') needs movie filename as option\n"); 8.2199 + exit(-1); 8.2200 + } 8.2201 + strcpy(movieFileName, optarg); 8.2202 + useMovie = 2; 8.2203 + break; 8.2204 + case 'w': // play with read-only 8.2205 + fprintf (stderr, "-w got called!\n"); 8.2206 + if(optarg == NULL) { 8.2207 + fprintf(stderr, "ERROR: --watchMovie ('w') needs movie filename as option\n"); 8.2208 + exit(-1); 8.2209 + } 8.2210 + strcpy(movieFileName, optarg); 8.2211 + useMovie = 3; 8.2212 + break; 8.2213 + 8.2214 + case 'P': 8.2215 +#ifdef PROFILING 8.2216 + if(optarg) { 8.2217 + cpuEnableProfiling(atoi(optarg)); 8.2218 + } else 8.2219 + cpuEnableProfiling(100); 8.2220 +#endif 8.2221 + break; 8.2222 + case 'S': 8.2223 + sdlFlashSize = atoi(optarg); 8.2224 + if(sdlFlashSize < 0 || sdlFlashSize > 1) 8.2225 + sdlFlashSize = 0; 8.2226 + break; 8.2227 + case 's': 8.2228 + if(optarg) { 8.2229 + int a = atoi(optarg); 8.2230 + if(a >= 0 && a <= 9) { 8.2231 + gbFrameSkip = a; 8.2232 + frameSkip = a; 8.2233 + } 8.2234 + } else { 8.2235 + frameSkip = 2; 8.2236 + gbFrameSkip = 0; 8.2237 + } 8.2238 + break; 8.2239 + case 't': 8.2240 + if(optarg) { 8.2241 + int a = atoi(optarg); 8.2242 + if(a < 0 || a > 5) 8.2243 + a = 0; 8.2244 + cpuSaveType = a; 8.2245 + } 8.2246 + break; 8.2247 + case 'T': 8.2248 + if(optarg) { 8.2249 + int t = atoi(optarg); 8.2250 + throttle = t; 8.2251 + } 8.2252 + break; 8.2253 + case 'v': 8.2254 + if(optarg) { 8.2255 + systemVerbose = atoi(optarg); 8.2256 + } else 8.2257 + systemVerbose = 0; 8.2258 + break; 8.2259 + case '1': 8.2260 + sizeOption = 0; 8.2261 + break; 8.2262 + case '2': 8.2263 + sizeOption = 1; 8.2264 + break; 8.2265 + case '3': 8.2266 + sizeOption = 2; 8.2267 + break; 8.2268 + case '4': 8.2269 + sizeOption = 3; 8.2270 + break; 8.2271 + case '?': 8.2272 + sdlPrintUsage = 1; 8.2273 + break; 8.2274 + } 8.2275 + } 8.2276 + 8.2277 + if(sdlPrintUsage) { 8.2278 + usage(argv[0]); 8.2279 + exit(-1); 8.2280 + } 8.2281 + 8.2282 +#ifdef MMX 8.2283 + if(disableMMX) 8.2284 + cpu_mmx = 0; 8.2285 +#endif 8.2286 + 8.2287 + if(rewindTimer) 8.2288 + rewindMemory = (char *)malloc(8*REWIND_SIZE); 8.2289 + 8.2290 + if(sdlFlashSize == 0) 8.2291 + flashSetSize(0x10000); 8.2292 + else 8.2293 + flashSetSize(0x20000); 8.2294 + 8.2295 + rtcEnable(sdlRtcEnable ? true : false); 8.2296 + agbPrintEnable(sdlAgbPrint ? true : false); 8.2297 + 8.2298 + if(!debuggerStub) { 8.2299 + if(optind >= argc) { 8.2300 + systemMessage(0,"Missing image name"); 8.2301 + usage(argv[0]); 8.2302 + exit(-1); 8.2303 + } 8.2304 + } 8.2305 + 8.2306 + if(filter) { 8.2307 + sizeOption = 1; 8.2308 + } 8.2309 + 8.2310 + for(int i = 0; i < 24;) { 8.2311 + systemGbPalette[i++] = (0x1f) | (0x1f << 5) | (0x1f << 10); 8.2312 + systemGbPalette[i++] = (0x15) | (0x15 << 5) | (0x15 << 10); 8.2313 + systemGbPalette[i++] = (0x0c) | (0x0c << 5) | (0x0c << 10); 8.2314 + systemGbPalette[i++] = 0; 8.2315 + } 8.2316 + 8.2317 + systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; 8.2318 + 8.2319 + if(optind < argc) 8.2320 + { 8.2321 + szFile = argv[optind]; 8.2322 + file_run(); 8.2323 + } 8.2324 + else 8.2325 + { 8.2326 + systemCartridgeType = 0; 8.2327 + strcpy(filename, "gnu_stub"); 8.2328 + rom = (u8 *)malloc(0x2000000); 8.2329 + workRAM = (u8 *)calloc(1, 0x40000); 8.2330 + bios = (u8 *)calloc(1,0x4000); 8.2331 + internalRAM = (u8 *)calloc(1,0x8000); 8.2332 + paletteRAM = (u8 *)calloc(1,0x400); 8.2333 + vram = (u8 *)calloc(1, 0x20000); 8.2334 + oam = (u8 *)calloc(1, 0x400); 8.2335 + pix = (u8 *)calloc(1, 4 * 240 * 160); 8.2336 + ioMem = (u8 *)calloc(1, 0x400); 8.2337 + 8.2338 + theEmulator = GBASystem; 8.2339 + 8.2340 + //CPUInit(biosFileName, useBios); 8.2341 + CPUInit(); 8.2342 + CPUReset(); 8.2343 + } 8.2344 + 8.2345 + if(debuggerStub) 8.2346 + remoteInit(); 8.2347 + 8.2348 + int flags = SDL_INIT_VIDEO|SDL_INIT_AUDIO| 8.2349 + SDL_INIT_TIMER|SDL_INIT_NOPARACHUTE; 8.2350 + 8.2351 + if(soundOffFlag) 8.2352 + flags ^= SDL_INIT_AUDIO; 8.2353 + 8.2354 + if(SDL_Init(flags)) { 8.2355 + systemMessage(0, "Failed to init SDL: %s", SDL_GetError()); 8.2356 + exit(-1); 8.2357 + } 8.2358 + 8.2359 + if(SDL_InitSubSystem(SDL_INIT_JOYSTICK)) { 8.2360 + systemMessage(0, "Failed to init joystick support: %s", SDL_GetError()); 8.2361 + } 8.2362 + 8.2363 + sdlCheckKeys(); 8.2364 + 8.2365 + if(systemCartridgeType == 0) { 8.2366 + srcWidth = 240; 8.2367 + srcHeight = 160; 8.2368 + systemFrameSkip = frameSkip; 8.2369 + } else if (systemCartridgeType == 1) { 8.2370 + if(gbBorderOn) { 8.2371 + srcWidth = 256; 8.2372 + srcHeight = 224; 8.2373 + gbBorderLineSkip = 256; 8.2374 + gbBorderColumnSkip = 48; 8.2375 + gbBorderRowSkip = 40; 8.2376 + } else { 8.2377 + srcWidth = 160; 8.2378 + srcHeight = 144; 8.2379 + gbBorderLineSkip = 160; 8.2380 + gbBorderColumnSkip = 0; 8.2381 + gbBorderRowSkip = 0; 8.2382 + } 8.2383 + systemFrameSkip = gbFrameSkip; 8.2384 + } else { 8.2385 + srcWidth = 320; 8.2386 + srcHeight = 240; 8.2387 + } 8.2388 + 8.2389 + destWidth = (sizeOption+1)*srcWidth; 8.2390 + destHeight = (sizeOption+1)*srcHeight; 8.2391 + 8.2392 + surface = SDL_SetVideoMode(destWidth, destHeight, 16, 8.2393 + SDL_ANYFORMAT|SDL_HWSURFACE|SDL_DOUBLEBUF| 8.2394 + (fullscreen ? SDL_FULLSCREEN : 0)); 8.2395 + 8.2396 + if(surface == NULL) { 8.2397 + systemMessage(0, "Failed to set video mode"); 8.2398 + SDL_Quit(); 8.2399 + exit(-1); 8.2400 + } 8.2401 + 8.2402 + systemRedShift = sdlCalculateShift(surface->format->Rmask); 8.2403 + systemGreenShift = sdlCalculateShift(surface->format->Gmask); 8.2404 + systemBlueShift = sdlCalculateShift(surface->format->Bmask); 8.2405 + 8.2406 + systemColorDepth = surface->format->BitsPerPixel; 8.2407 + if(systemColorDepth == 15) 8.2408 + systemColorDepth = 16; 8.2409 + 8.2410 + if(yuv) { 8.2411 + Init_Overlay(surface, yuvType); 8.2412 + systemColorDepth = 32; 8.2413 + systemRedShift = 3; 8.2414 + systemGreenShift = 11; 8.2415 + systemBlueShift = 19; 8.2416 + } 8.2417 + 8.2418 + if(systemColorDepth != 16 && systemColorDepth != 24 && 8.2419 + systemColorDepth != 32) { 8.2420 + fprintf(stderr,"Unsupported color depth '%d'.\nOnly 16, 24 and 32 bit color depths are supported\n", systemColorDepth); 8.2421 + exit(-1); 8.2422 + } 8.2423 + 8.2424 +#ifndef C_CORE 8.2425 + sdlMakeStretcher(srcWidth); 8.2426 +#else 8.2427 + switch(systemColorDepth) { 8.2428 + case 16: 8.2429 + sdlStretcher = sdlStretcher16[sizeOption]; 8.2430 + break; 8.2431 + case 24: 8.2432 + sdlStretcher = sdlStretcher24[sizeOption]; 8.2433 + break; 8.2434 + case 32: 8.2435 + sdlStretcher = sdlStretcher32[sizeOption]; 8.2436 + break; 8.2437 + default: 8.2438 + fprintf(stderr, "Unsupported resolution: %d\n", systemColorDepth); 8.2439 + exit(-1); 8.2440 + } 8.2441 +#endif 8.2442 + 8.2443 + fprintf(stderr,"Color depth: %d\n", systemColorDepth); 8.2444 + 8.2445 + if(systemColorDepth == 16) { 8.2446 + if(sdlCalculateMaskWidth(surface->format->Gmask) == 6) { 8.2447 + Init_2xSaI(565); 8.2448 + RGB_LOW_BITS_MASK = 0x821; 8.2449 + } else { 8.2450 + Init_2xSaI(555); 8.2451 + RGB_LOW_BITS_MASK = 0x421; 8.2452 + } 8.2453 + if(systemCartridgeType == 2) { 8.2454 + for(int i = 0; i < 0x10000; i++) { 8.2455 + systemColorMap16[i] = (((i >> 1) & 0x1f) << systemBlueShift) | 8.2456 + (((i & 0x7c0) >> 6) << systemGreenShift) | 8.2457 + (((i & 0xf800) >> 11) << systemRedShift); 8.2458 + } 8.2459 + } else { 8.2460 + for(int i = 0; i < 0x10000; i++) { 8.2461 + systemColorMap16[i] = ((i & 0x1f) << systemRedShift) | 8.2462 + (((i & 0x3e0) >> 5) << systemGreenShift) | 8.2463 + (((i & 0x7c00) >> 10) << systemBlueShift); 8.2464 + } 8.2465 + } 8.2466 + srcPitch = srcWidth * 2+4; 8.2467 + } else { 8.2468 + if(systemColorDepth != 32) 8.2469 + filterFunction = NULL; 8.2470 + RGB_LOW_BITS_MASK = 0x010101; 8.2471 + if(systemColorDepth == 32) { 8.2472 + Init_2xSaI(32); 8.2473 + } 8.2474 + for(int i = 0; i < 0x10000; i++) { 8.2475 + systemColorMap32[i] = ((i & 0x1f) << systemRedShift) | 8.2476 + (((i & 0x3e0) >> 5) << systemGreenShift) | 8.2477 + (((i & 0x7c00) >> 10) << systemBlueShift); 8.2478 + } 8.2479 + if(systemColorDepth == 32) 8.2480 + srcPitch = srcWidth*4 + 4; 8.2481 + else 8.2482 + srcPitch = srcWidth*3; 8.2483 + } 8.2484 + 8.2485 + if(systemColorDepth != 32) { 8.2486 + switch(filter) { 8.2487 + case 0: 8.2488 + filterFunction = NULL; 8.2489 + break; 8.2490 + case 1: 8.2491 + filterFunction = ScanlinesTV; 8.2492 + break; 8.2493 + case 2: 8.2494 + filterFunction = _2xSaI; 8.2495 + break; 8.2496 + case 3: 8.2497 + filterFunction = Super2xSaI; 8.2498 + break; 8.2499 + case 4: 8.2500 + filterFunction = SuperEagle; 8.2501 + break; 8.2502 + case 5: 8.2503 + filterFunction = Pixelate2x16; 8.2504 + break; 8.2505 + case 6: 8.2506 + filterFunction = MotionBlur; 8.2507 + break; 8.2508 + case 7: 8.2509 + filterFunction = AdMame2x; 8.2510 + break; 8.2511 + case 8: 8.2512 + filterFunction = Simple2x16; 8.2513 + break; 8.2514 + case 9: 8.2515 + filterFunction = Bilinear; 8.2516 + break; 8.2517 + case 10: 8.2518 + filterFunction = BilinearPlus; 8.2519 + break; 8.2520 + case 11: 8.2521 + filterFunction = Scanlines; 8.2522 + break; 8.2523 + case 12: 8.2524 + filterFunction = hq2x; 8.2525 + break; 8.2526 + case 13: 8.2527 + filterFunction = lq2x; 8.2528 + break; 8.2529 + default: 8.2530 + filterFunction = NULL; 8.2531 + break; 8.2532 + } 8.2533 + } else { 8.2534 + switch(filter) { 8.2535 + case 0: 8.2536 + filterFunction = NULL; 8.2537 + break; 8.2538 + case 1: 8.2539 + filterFunction = ScanlinesTV32; 8.2540 + break; 8.2541 + case 2: 8.2542 + filterFunction = _2xSaI32; 8.2543 + break; 8.2544 + case 3: 8.2545 + filterFunction = Super2xSaI32; 8.2546 + break; 8.2547 + case 4: 8.2548 + filterFunction = SuperEagle32; 8.2549 + break; 8.2550 + case 5: 8.2551 + filterFunction = Pixelate2x32; 8.2552 + break; 8.2553 + case 6: 8.2554 + filterFunction = MotionBlur32; 8.2555 + break; 8.2556 + case 7: 8.2557 + filterFunction = AdMame2x32; 8.2558 + break; 8.2559 + case 8: 8.2560 + filterFunction = Simple2x32; 8.2561 + break; 8.2562 + case 9: 8.2563 + filterFunction = Bilinear32; 8.2564 + break; 8.2565 + case 10: 8.2566 + filterFunction = BilinearPlus32; 8.2567 + break; 8.2568 + case 11: 8.2569 + filterFunction = Scanlines32; 8.2570 + break; 8.2571 + case 12: 8.2572 + filterFunction = hq2x32; 8.2573 + break; 8.2574 + case 13: 8.2575 + filterFunction = lq2x32; 8.2576 + break; 8.2577 + default: 8.2578 + filterFunction = NULL; 8.2579 + break; 8.2580 + } 8.2581 + } 8.2582 + 8.2583 + if(systemColorDepth == 16) { 8.2584 + switch(ifbType) { 8.2585 + case 0: 8.2586 + default: 8.2587 + ifbFunction = NULL; 8.2588 + break; 8.2589 + case 1: 8.2590 + ifbFunction = MotionBlurIB; 8.2591 + break; 8.2592 + case 2: 8.2593 + ifbFunction = SmartIB; 8.2594 + break; 8.2595 + } 8.2596 + } else if(systemColorDepth == 32) { 8.2597 + switch(ifbType) { 8.2598 + case 0: 8.2599 + default: 8.2600 + ifbFunction = NULL; 8.2601 + break; 8.2602 + case 1: 8.2603 + ifbFunction = MotionBlurIB32; 8.2604 + break; 8.2605 + case 2: 8.2606 + ifbFunction = SmartIB32; 8.2607 + break; 8.2608 + } 8.2609 + } else 8.2610 + ifbFunction = NULL; 8.2611 + 8.2612 + if(delta == NULL) { 8.2613 + delta = (u8*)malloc(322*242*4); 8.2614 + memset(delta, 255, 322*242*4); 8.2615 + } 8.2616 + 8.2617 + if(!soundOffFlag) 8.2618 + soundInit(); 8.2619 + 8.2620 + autoFrameSkipLastTime = throttleLastTime = systemGetClock(); 8.2621 + 8.2622 + switch(useMovie) 8.2623 + { 8.2624 + case 1: // --recordMovie 8.2625 + VBAMovieCreate(movieFileName, 8.2626 + /*authorInfo*/"", 8.2627 + /*startFlags*/0, 8.2628 + /*controllerFlags*/MOVIE_CONTROLLER(0), 8.2629 + /*typeFlags*/(systemCartridgeType==IMAGE_GBA)?(MOVIE_TYPE_GBA):(GBC_CAPABLE?MOVIE_TYPE_GBC:MOVIE_TYPE_SGB)); 8.2630 + break; 8.2631 + case 2: // --playMovie 8.2632 + VBAMovieOpen(movieFileName, false); 8.2633 + break; 8.2634 + case 3: // --watchMovie 8.2635 + VBAMovieOpen(movieFileName, true); 8.2636 + break; 8.2637 + default: 8.2638 + sdlReadBattery(); 8.2639 + break; 8.2640 + } 8.2641 + SDL_WM_SetCaption("VisualBoyAdvance", NULL); 8.2642 + 8.2643 + char *moviefile = getenv("AUTODEMO"); 8.2644 +// fprintf (stderr, "Checking for AUTODEMO...\n"); 8.2645 + if (moviefile) 8.2646 + { 8.2647 +// fprintf (stderr, "I got a filename OMG!\nCalling VBAMovieOpen...\n"); 8.2648 + VBAMovieOpen(moviefile, true); 8.2649 + } 8.2650 + 8.2651 + while(emulating) { 8.2652 + if(!paused && active) { 8.2653 + if(debugger && theEmulator.emuHasDebugger) 8.2654 + dbgMain(); 8.2655 + else { 8.2656 + theEmulator.emuMain(theEmulator.emuCount); 8.2657 + if(rewindSaveNeeded && rewindMemory && theEmulator.emuWriteMemState) { 8.2658 + rewindCount++; 8.2659 + if(rewindCount > 8) 8.2660 + rewindCount = 8; 8.2661 + if(theEmulator.emuWriteMemState && 8.2662 + theEmulator.emuWriteMemState(&rewindMemory[rewindPos*REWIND_SIZE], 8.2663 + REWIND_SIZE)) { 8.2664 + rewindPos = ++rewindPos & 7; 8.2665 + if(rewindCount == 8) 8.2666 + rewindTopPos = ++rewindTopPos & 7; 8.2667 + } 8.2668 + } 8.2669 + 8.2670 + rewindSaveNeeded = false; 8.2671 + } 8.2672 + } else { 8.2673 + SDL_Delay(500); 8.2674 + } 8.2675 + sdlPollEvents(); 8.2676 + if(mouseCounter) { 8.2677 + mouseCounter--; 8.2678 + if(mouseCounter == 0) 8.2679 + SDL_ShowCursor(SDL_DISABLE); 8.2680 + } 8.2681 + } 8.2682 + 8.2683 + emulating = 0; 8.2684 + fprintf(stderr,"Shutting down\n"); 8.2685 + remoteCleanUp(); 8.2686 + soundShutdown(); 8.2687 + 8.2688 + if(gbRom != NULL || rom != NULL) { 8.2689 + sdlWriteBattery(); 8.2690 + theEmulator.emuCleanUp(); 8.2691 + } 8.2692 + 8.2693 + if(delta) { 8.2694 + free(delta); 8.2695 + delta = NULL; 8.2696 + } 8.2697 + 8.2698 + SDL_Quit(); 8.2699 + return 0; 8.2700 +} 8.2701 + 8.2702 +void systemMessage(int num, const char *msg, ...) 8.2703 +{ 8.2704 + char buffer[2048]; 8.2705 + va_list valist; 8.2706 + 8.2707 + va_start(valist, msg); 8.2708 + vsprintf(buffer, msg, valist); 8.2709 + 8.2710 + fprintf(stderr, "%s\n", buffer); 8.2711 + va_end(valist); 8.2712 +} 8.2713 + 8.2714 +//On WIN32, this function messages requesting 8.2715 +//the window to be redrawn. Can this be ignored here? 8.2716 +void systemRefreshScreen(){} 8.2717 + 8.2718 +void systemRenderFrame() 8.2719 +{ 8.2720 + renderedFrames++; 8.2721 + VBAUpdateFrameCountDisplay(); 8.2722 + VBAUpdateButtonPressDisplay(); 8.2723 + 8.2724 + if(yuv) { 8.2725 + Draw_Overlay(surface, sizeOption+1); 8.2726 + return; 8.2727 + } 8.2728 + 8.2729 + SDL_LockSurface(surface); 8.2730 + 8.2731 + for(int slot = 0 ; slot < 8 ; slot++) 8.2732 + { 8.2733 + if(screenMessage[slot]) { 8.2734 + if(systemCartridgeType == 1 && gbBorderOn) { 8.2735 + gbSgbRenderBorder(); 8.2736 + } 8.2737 + if(((systemGetClock() - screenMessageTime[slot]) < screenMessageDuration[slot]) && 8.2738 + !disableStatusMessages) { 8.2739 + drawText(pix, srcPitch, 10, srcHeight - 20*(slot+1), 8.2740 + screenMessageBuffer[slot]); 8.2741 + } else { 8.2742 + screenMessage[slot] = false; 8.2743 + } 8.2744 + } 8.2745 + } 8.2746 + 8.2747 + if(ifbFunction) { 8.2748 + if(systemColorDepth == 16) 8.2749 + ifbFunction(pix+destWidth+4, destWidth+4, srcWidth, srcHeight); 8.2750 + else 8.2751 + ifbFunction(pix+destWidth*2+4, destWidth*2+4, srcWidth, srcHeight); 8.2752 + } 8.2753 + 8.2754 + if(filterFunction) { 8.2755 + if(systemColorDepth == 16) 8.2756 + filterFunction(pix+destWidth+4,destWidth+4, delta, 8.2757 + (u8*)surface->pixels,surface->pitch, 8.2758 + srcWidth, 8.2759 + srcHeight); 8.2760 + else 8.2761 + filterFunction(pix+destWidth*2+4, 8.2762 + destWidth*2+4, 8.2763 + delta, 8.2764 + (u8*)surface->pixels, 8.2765 + surface->pitch, 8.2766 + srcWidth, 8.2767 + srcHeight); 8.2768 + } else { 8.2769 + int destPitch = surface->pitch; 8.2770 + u8 *src = pix; 8.2771 + u8 *dest = (u8*)surface->pixels; 8.2772 + int i; 8.2773 + u32 *stretcher = (u32 *)sdlStretcher; 8.2774 + if(systemColorDepth == 16) 8.2775 + src += srcPitch; 8.2776 + int option = sizeOption; 8.2777 + if(yuv) 8.2778 + option = 0; 8.2779 + switch(sizeOption) { 8.2780 + case 0: 8.2781 + for(i = 0; i < srcHeight; i++) { 8.2782 + SDL_CALL_STRETCHER; 8.2783 + src += srcPitch; 8.2784 + dest += destPitch; 8.2785 + } 8.2786 + break; 8.2787 + case 1: 8.2788 + for(i = 0; i < srcHeight; i++) { 8.2789 + SDL_CALL_STRETCHER; 8.2790 + dest += destPitch; 8.2791 + SDL_CALL_STRETCHER; 8.2792 + src += srcPitch; 8.2793 + dest += destPitch; 8.2794 + } 8.2795 + break; 8.2796 + case 2: 8.2797 + for(i = 0; i < srcHeight; i++) { 8.2798 + SDL_CALL_STRETCHER; 8.2799 + dest += destPitch; 8.2800 + SDL_CALL_STRETCHER; 8.2801 + dest += destPitch; 8.2802 + SDL_CALL_STRETCHER; 8.2803 + src += srcPitch; 8.2804 + dest += destPitch; 8.2805 + } 8.2806 + break; 8.2807 + case 3: 8.2808 + for(i = 0; i < srcHeight; i++) { 8.2809 + SDL_CALL_STRETCHER; 8.2810 + dest += destPitch; 8.2811 + SDL_CALL_STRETCHER; 8.2812 + dest += destPitch; 8.2813 + SDL_CALL_STRETCHER; 8.2814 + dest += destPitch; 8.2815 + SDL_CALL_STRETCHER; 8.2816 + src += srcPitch; 8.2817 + dest += destPitch; 8.2818 + } 8.2819 + break; 8.2820 + } 8.2821 + } 8.2822 + 8.2823 + if(showSpeed && fullscreen) { 8.2824 + char buffer[50]; 8.2825 + if(showSpeed == 1) 8.2826 + sprintf(buffer, "%d%%", systemSpeed); 8.2827 + else 8.2828 + sprintf(buffer, "%3d%%(%d, %d fps)", systemSpeed, 8.2829 + systemFrameSkip, 8.2830 + showRenderedFrames); 8.2831 + if(showSpeedTransparent) 8.2832 + drawTextTransp((u8*)surface->pixels, 8.2833 + surface->pitch, 8.2834 + 10, 8.2835 + surface->h-20, 8.2836 + buffer); 8.2837 + else 8.2838 + drawText((u8*)surface->pixels, 8.2839 + surface->pitch, 8.2840 + 10, 8.2841 + surface->h-20, 8.2842 + buffer); 8.2843 + } 8.2844 + 8.2845 + SDL_UnlockSurface(surface); 8.2846 + // SDL_UpdateRect(surface, 0, 0, destWidth, destHeight); 8.2847 + SDL_Flip(surface); 8.2848 +} 8.2849 + 8.2850 +bool systemReadJoypads() 8.2851 +{ 8.2852 + return true; 8.2853 +} 8.2854 + 8.2855 +// Kludge to make Lua call the right function. 8.2856 +u32 systemGetOriginalJoypad(int which, bool sensor){ 8.2857 + return systemGetJoypad(which,sensor); 8.2858 +} 8.2859 + 8.2860 +u32 systemGetJoypad(int which, bool sensor) 8.2861 +{ 8.2862 + sensorOn = sensor; 8.2863 + if(which < 0 || which > 3) 8.2864 + which = sdlDefaultJoypad; 8.2865 + 8.2866 + //VBAMovieUpdate(which); 8.2867 + //VBAMovieUpdateState(); 8.2868 + u32 res = 0; 8.2869 + 8.2870 + //----------------------------// 8.2871 + if (VBAMoviePlaying()){ 8.2872 + // VBAMovieRead() overwrites currentButtons[i] 8.2873 + VBAMovieRead(which, sensor); 8.2874 + res = currentButtons[which]; 8.2875 + return res; 8.2876 + } 8.2877 + //---------------------------// 8.2878 + //Temporary implementation, not sure if it's correct --Felipe 8.2879 + 8.2880 + /* 8.2881 + if(sdlButtons[which][KEY_BUTTON_A]) 8.2882 + res |= BUTTON_MASK_A; 8.2883 + if(sdlButtons[which][KEY_BUTTON_B]) 8.2884 + res |= BUTTON_MASK_B; 8.2885 + if(sdlButtons[which][KEY_BUTTON_SELECT]) 8.2886 + res |= BUTTON_MASK_SELECT; 8.2887 + if(sdlButtons[which][KEY_BUTTON_START]) 8.2888 + res |= BUTTON_MASK_START; 8.2889 + if(sdlButtons[which][KEY_RIGHT]) 8.2890 + res |= BUTTON_MASK_RIGHT; 8.2891 + if(sdlButtons[which][KEY_LEFT]) 8.2892 + res |= BUTTON_MASK_LEFT; 8.2893 + if(sdlButtons[which][KEY_UP]) 8.2894 + res |= BUTTON_MASK_UP; 8.2895 + if(sdlButtons[which][KEY_DOWN]) 8.2896 + res |= BUTTON_MASK_DOWN; 8.2897 + if(sdlButtons[which][KEY_BUTTON_R]) 8.2898 + res |= BUTTON_MASK_R; 8.2899 + if(sdlButtons[which][KEY_BUTTON_L]) 8.2900 + res |= BUTTON_MASK_L; 8.2901 + */ 8.2902 +/* 8.2903 + // disallow L+R or U+D of being pressed at the same time 8.2904 + if((res & 48) == 48) 8.2905 + res &= ~16; 8.2906 + if((res & 192) == 192) 8.2907 + res &= ~128; 8.2908 +*/ 8.2909 +/* 8.2910 + if(sdlbuttons[which][KEY_BUTTON_SPEED]) 8.2911 + res |= 1024; 8.2912 + if(sdlButtons[which][KEY_BUTTON_CAPTURE]) 8.2913 + res |= 2048; 8.2914 +*/ 8.2915 + res = currentButtons[which]; 8.2916 + 8.2917 + if(autoFire) { 8.2918 + res &= (~autoFire); 8.2919 + if(autoFireToggle) 8.2920 + res |= autoFire; 8.2921 + autoFireToggle = !autoFireToggle; 8.2922 + } 8.2923 + 8.2924 + //if (res) fprintf(stdout,"%x\n",res); 8.2925 + 8.2926 + return res; 8.2927 +} 8.2928 + 8.2929 +void systemSetJoypad(int which, u32 buttons) 8.2930 +{ 8.2931 + if(which < 0 || which > 3) 8.2932 + which = sdlDefaultJoypad; 8.2933 +/* 8.2934 + sdlButtons[which][KEY_BUTTON_A] = (buttons & 1) != 0; 8.2935 + sdlButtons[which][KEY_BUTTON_B] = (buttons & 2) != 0; 8.2936 + sdlButtons[which][KEY_BUTTON_SELECT] = (buttons & 4) != 0; 8.2937 + sdlButtons[which][KEY_BUTTON_START] = (buttons & 8) != 0; 8.2938 + sdlButtons[which][KEY_RIGHT] = (buttons & 16) != 0; 8.2939 + sdlButtons[which][KEY_LEFT] = (buttons & 32) != 0; 8.2940 + sdlButtons[which][KEY_UP] = (buttons & 64) != 0; 8.2941 + sdlButtons[which][KEY_DOWN] = (buttons & 128) != 0; 8.2942 + sdlButtons[which][KEY_BUTTON_R] = (buttons & 256) != 0; 8.2943 + sdlButtons[which][KEY_BUTTON_L] = (buttons & 512) != 0; 8.2944 +*/ 8.2945 + currentButtons[which]= buttons & 0x3ff; 8.2946 +} 8.2947 + 8.2948 +void systemClearJoypads() 8.2949 +{ 8.2950 + for (int i = 0; i < 4; ++i) 8.2951 + currentButtons[i] = 0; 8.2952 + 8.2953 + //lastKeys = 0; 8.2954 +} 8.2955 + 8.2956 +void systemSetTitle(const char *title) 8.2957 +{ 8.2958 + SDL_WM_SetCaption(title, NULL); 8.2959 +} 8.2960 + 8.2961 +void systemShowSpeed(int speed) 8.2962 +{ 8.2963 + systemSpeed = speed; 8.2964 + 8.2965 + showRenderedFrames = renderedFrames; 8.2966 + renderedFrames = 0; 8.2967 + 8.2968 + if(!fullscreen && showSpeed) { 8.2969 + char buffer[80]; 8.2970 + if(showSpeed == 1) 8.2971 + sprintf(buffer, "VisualBoyAdvance-%3d%%", systemSpeed); 8.2972 + else 8.2973 + sprintf(buffer, "VisualBoyAdvance-%3d%%(%d, %d fps)", systemSpeed, 8.2974 + systemFrameSkip, 8.2975 + showRenderedFrames); 8.2976 + 8.2977 + systemSetTitle(buffer); 8.2978 + } 8.2979 +} 8.2980 + 8.2981 +// FIXME: the timing 8.2982 +void systemFrame(/*int rate*/) //Looking at System.cpp, it looks like rate should be 600 8.2983 +{ 8.2984 + u32 time = systemGetClock(); 8.2985 + if(!wasPaused && autoFrameSkip && !throttle) { 8.2986 + u32 diff = time - autoFrameSkipLastTime; 8.2987 + int speed = 100; 8.2988 + 8.2989 + if(diff) 8.2990 + speed = (1000000/600)/diff; 8.2991 + 8.2992 + if(speed >= 98) { 8.2993 + frameskipadjust++; 8.2994 + 8.2995 + if(frameskipadjust >= 3) { 8.2996 + frameskipadjust=0; 8.2997 + if(systemFrameSkip > 0) 8.2998 + systemFrameSkip--; 8.2999 + } 8.3000 + } else { 8.3001 + if(speed < 80) 8.3002 + frameskipadjust -= (90 - speed)/5; 8.3003 + else if(systemFrameSkip < 9) 8.3004 + frameskipadjust--; 8.3005 + 8.3006 + if(frameskipadjust <= -2) { 8.3007 + frameskipadjust += 2; 8.3008 + if(systemFrameSkip < 9) 8.3009 + systemFrameSkip++; 8.3010 + } 8.3011 + } 8.3012 + } 8.3013 + if(!wasPaused && throttle) { 8.3014 + /*if(!speedup) { 8.3015 + u32 diff = time - throttleLastTime; 8.3016 + 8.3017 + int target = (1000000.0/(600*throttle)); 8.3018 + int d = (target - diff); 8.3019 + 8.3020 + if(d > 0) { 8.3021 + SDL_Delay(d); 8.3022 + } 8.3023 + } 8.3024 + throttleLastTime = systemGetClock(); 8.3025 + */ 8.3026 + } 8.3027 + if(rewindMemory) { 8.3028 + if(++rewindCounter >= rewindTimer) { 8.3029 + rewindSaveNeeded = true; 8.3030 + rewindCounter = 0; 8.3031 + } 8.3032 + } 8.3033 + 8.3034 + if(systemSaveUpdateCounter) { 8.3035 + if(--systemSaveUpdateCounter <= SYSTEM_SAVE_NOT_UPDATED) { 8.3036 + sdlWriteBattery(); 8.3037 + systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; 8.3038 + } 8.3039 + } 8.3040 + 8.3041 + wasPaused = false; 8.3042 + autoFrameSkipLastTime = time; 8.3043 +} 8.3044 + 8.3045 +int systemFramesToSkip(){ 8.3046 + return systemFrameSkip; 8.3047 +} 8.3048 + 8.3049 +int systemScreenCapture(int a) 8.3050 +{ 8.3051 + char buffer[2048]; 8.3052 + 8.3053 + if(captureFormat) { 8.3054 + if(captureDir[0]) 8.3055 + sprintf(buffer, "%s/%s%02d.bmp", captureDir, sdlGetFilename(filename), a); 8.3056 + else 8.3057 + sprintf(buffer, "%s%02d.bmp", filename, a); 8.3058 + 8.3059 + theEmulator.emuWriteBMP(buffer); 8.3060 + } else { 8.3061 + if(captureDir[0]) 8.3062 + sprintf(buffer, "%s/%s%02d.png", captureDir, sdlGetFilename(filename), a); 8.3063 + else 8.3064 + sprintf(buffer, "%s%02d.png", filename, a); 8.3065 + theEmulator.emuWritePNG(buffer); 8.3066 + } 8.3067 + 8.3068 + systemScreenMessage("Screen capture"); 8.3069 + return a; 8.3070 +} 8.3071 + 8.3072 +void soundCallback(void *,u8 *stream,int len){} 8.3073 + 8.3074 +void systemSoundWriteToBuffer(){ 8.3075 + soundDriver->write(soundFinalWave, soundBufferLen); 8.3076 +} 8.3077 + 8.3078 +void systemSoundClearBuffer() 8.3079 +{ 8.3080 + SDL_mutexP(mutex); 8.3081 + memset(sdlBuffer,0,soundBufferTotalLen); 8.3082 + sdlSoundLen=0; 8.3083 + printf("Hi\n"); 8.3084 + SDL_mutexV(mutex); 8.3085 +} 8.3086 + 8.3087 +bool systemSoundInit(){ 8.3088 + systemSoundShutdown(); 8.3089 + soundDriver = new SoundSDL(); 8.3090 + if ( !soundDriver ) 8.3091 + return false; 8.3092 + 8.3093 + if (!soundDriver->init()) //<-- sound sample rate 8.3094 + return false; 8.3095 + 8.3096 + if (!(soundDriver->setThrottle(throttle))){ 8.3097 + fprintf(stderr,"Failed to set desired throttle, defaulting to 100 %%.\n"); 8.3098 + if (!soundDriver->setThrottle(100)) return false; 8.3099 + } 8.3100 + soundPaused = true; 8.3101 + systemSoundOn = true; 8.3102 + return true; 8.3103 +} 8.3104 + 8.3105 +void systemSoundShutdown(){ 8.3106 + if (soundDriver) 8.3107 + { 8.3108 + delete soundDriver; 8.3109 + soundDriver = 0; 8.3110 + } 8.3111 +} 8.3112 + 8.3113 +void systemSoundPause() 8.3114 +{ 8.3115 + SDL_PauseAudio(1); 8.3116 +} 8.3117 + 8.3118 +void systemSoundResume() 8.3119 +{ 8.3120 + SDL_PauseAudio(0); 8.3121 +} 8.3122 + 8.3123 +void systemSoundReset() 8.3124 +{ 8.3125 +} 8.3126 + 8.3127 +u32 systemGetClock() 8.3128 +{ 8.3129 + return SDL_GetTicks(); 8.3130 +} 8.3131 + 8.3132 +void systemUpdateMotionSensor() 8.3133 +{ 8.3134 + if(sdlMotionButtons[KEY_LEFT]) { 8.3135 + sensorX += 3; 8.3136 + if(sensorX > 2197) 8.3137 + sensorX = 2197; 8.3138 + if(sensorX < 2047) 8.3139 + sensorX = 2057; 8.3140 + } else if(sdlMotionButtons[KEY_RIGHT]) { 8.3141 + sensorX -= 3; 8.3142 + if(sensorX < 1897) 8.3143 + sensorX = 1897; 8.3144 + if(sensorX > 2047) 8.3145 + sensorX = 2037; 8.3146 + } else if(sensorX > 2047) { 8.3147 + sensorX -= 2; 8.3148 + if(sensorX < 2047) 8.3149 + sensorX = 2047; 8.3150 + } else { 8.3151 + sensorX += 2; 8.3152 + if(sensorX > 2047) 8.3153 + sensorX = 2047; 8.3154 + } 8.3155 + 8.3156 + if(sdlMotionButtons[KEY_UP]) { 8.3157 + sensorY += 3; 8.3158 + if(sensorY > 2197) 8.3159 + sensorY = 2197; 8.3160 + if(sensorY < 2047) 8.3161 + sensorY = 2057; 8.3162 + } else if(sdlMotionButtons[KEY_DOWN]) { 8.3163 + sensorY -= 3; 8.3164 + if(sensorY < 1897) 8.3165 + sensorY = 1897; 8.3166 + if(sensorY > 2047) 8.3167 + sensorY = 2037; 8.3168 + } else if(sensorY > 2047) { 8.3169 + sensorY -= 2; 8.3170 + if(sensorY < 2047) 8.3171 + sensorY = 2047; 8.3172 + } else { 8.3173 + sensorY += 2; 8.3174 + if(sensorY > 2047) 8.3175 + sensorY = 2047; 8.3176 + } 8.3177 +} 8.3178 + 8.3179 +void systemResetSensor() 8.3180 +{ 8.3181 + sensorX = sensorY = INITIAL_SENSOR_VALUE; 8.3182 +} 8.3183 + 8.3184 +int systemGetSensorX() 8.3185 +{ 8.3186 + return sensorX; 8.3187 +} 8.3188 + 8.3189 +int systemGetSensorY() 8.3190 +{ 8.3191 + return sensorY; 8.3192 +} 8.3193 + 8.3194 +void systemGbPrint(u8 *data,int pages,int feed,int palette, int contrast) 8.3195 +{ 8.3196 +} 8.3197 + 8.3198 +void systemScreenMessage(const char *msg, int slot, int duration, const char *colorList) 8.3199 +{ 8.3200 + screenMessage[slot] = true; 8.3201 + screenMessageTime[slot] = systemGetClock(); 8.3202 + screenMessageDuration[slot] = duration; 8.3203 + if(strlen(msg) > 20) { 8.3204 + strncpy(screenMessageBuffer[slot], msg, 20); 8.3205 + screenMessageBuffer[slot][20] = 0; 8.3206 + } else 8.3207 + strcpy(screenMessageBuffer[slot], msg); 8.3208 +} 8.3209 + 8.3210 +bool systemSoundCanChangeQuality() 8.3211 +{ 8.3212 + return false; 8.3213 +} 8.3214 + 8.3215 +bool systemSoundSetQuality(int quality) 8.3216 +{ 8.3217 + if (systemCartridgeType == 0) 8.3218 + soundSetQuality(quality); 8.3219 + else 8.3220 + gbSoundSetQuality(quality); 8.3221 + 8.3222 + return true; 8.3223 +} 8.3224 + 8.3225 +bool systemPauseOnFrame() 8.3226 +{ 8.3227 + if(pauseNextFrame) { 8.3228 + paused = true; 8.3229 + pauseNextFrame = false; 8.3230 + return true; 8.3231 + } 8.3232 + return false; 8.3233 +} 8.3234 + 8.3235 +// Code donated by Niels Wagenaar (BoycottAdvance) 8.3236 + 8.3237 +// GBA screensize. 8.3238 +#define GBA_WIDTH 240 8.3239 +#define GBA_HEIGHT 160 8.3240 + 8.3241 +void Init_Overlay(SDL_Surface *gbascreen, int overlaytype) 8.3242 +{ 8.3243 + 8.3244 + overlay = SDL_CreateYUVOverlay( GBA_WIDTH, 8.3245 + GBA_HEIGHT, 8.3246 + overlaytype, gbascreen); 8.3247 + fprintf(stderr, "Created %dx%dx%d %s %s overlay\n", 8.3248 + overlay->w,overlay->h,overlay->planes, 8.3249 + overlay->hw_overlay?"hardware":"software", 8.3250 + overlay->format==SDL_YV12_OVERLAY?"YV12": 8.3251 + overlay->format==SDL_IYUV_OVERLAY?"IYUV": 8.3252 + overlay->format==SDL_YUY2_OVERLAY?"YUY2": 8.3253 + overlay->format==SDL_UYVY_OVERLAY?"UYVY": 8.3254 + overlay->format==SDL_YVYU_OVERLAY?"YVYU": 8.3255 + "Unknown"); 8.3256 +} 8.3257 + 8.3258 +void Quit_Overlay(void) 8.3259 +{ 8.3260 + 8.3261 + SDL_FreeYUVOverlay(overlay); 8.3262 +} 8.3263 + 8.3264 +/* NOTE: These RGB conversion functions are not intended for speed, 8.3265 + only as examples. 8.3266 +*/ 8.3267 +inline void RGBtoYUV(Uint8 *rgb, int *yuv) 8.3268 +{ 8.3269 + yuv[0] = (int)((0.257 * rgb[0]) + (0.504 * rgb[1]) + (0.098 * rgb[2]) + 16); 8.3270 + yuv[1] = (int)(128 - (0.148 * rgb[0]) - (0.291 * rgb[1]) + (0.439 * rgb[2])); 8.3271 + yuv[2] = (int)(128 + (0.439 * rgb[0]) - (0.368 * rgb[1]) - (0.071 * rgb[2])); 8.3272 +} 8.3273 + 8.3274 +inline void ConvertRGBtoYV12(SDL_Overlay *o) 8.3275 +{ 8.3276 + int x,y; 8.3277 + int yuv[3]; 8.3278 + Uint8 *p,*op[3]; 8.3279 + 8.3280 + SDL_LockYUVOverlay(o); 8.3281 + 8.3282 + /* Black initialization */ 8.3283 + /* 8.3284 + memset(o->pixels[0],0,o->pitches[0]*o->h); 8.3285 + memset(o->pixels[1],128,o->pitches[1]*((o->h+1)/2)); 8.3286 + memset(o->pixels[2],128,o->pitches[2]*((o->h+1)/2)); 8.3287 + */ 8.3288 + 8.3289 + /* Convert */ 8.3290 + for(y=0; y<160 && y<o->h; y++) { 8.3291 + p=(Uint8 *)pix+srcPitch*y; 8.3292 + op[0]=o->pixels[0]+o->pitches[0]*y; 8.3293 + op[1]=o->pixels[1]+o->pitches[1]*(y/2); 8.3294 + op[2]=o->pixels[2]+o->pitches[2]*(y/2); 8.3295 + for(x=0; x<240 && x<o->w; x++) { 8.3296 + RGBtoYUV(p,yuv); 8.3297 + *(op[0]++)=yuv[0]; 8.3298 + if(x%2==0 && y%2==0) { 8.3299 + *(op[1]++)=yuv[2]; 8.3300 + *(op[2]++)=yuv[1]; 8.3301 + } 8.3302 + p+=4;//s->format->BytesPerPixel; 8.3303 + } 8.3304 + } 8.3305 + 8.3306 + SDL_UnlockYUVOverlay(o); 8.3307 +} 8.3308 + 8.3309 +inline void ConvertRGBtoIYUV(SDL_Overlay *o) 8.3310 +{ 8.3311 + int x,y; 8.3312 + int yuv[3]; 8.3313 + Uint8 *p,*op[3]; 8.3314 + 8.3315 + SDL_LockYUVOverlay(o); 8.3316 + 8.3317 + /* Black initialization */ 8.3318 + /* 8.3319 + memset(o->pixels[0],0,o->pitches[0]*o->h); 8.3320 + memset(o->pixels[1],128,o->pitches[1]*((o->h+1)/2)); 8.3321 + memset(o->pixels[2],128,o->pitches[2]*((o->h+1)/2)); 8.3322 + */ 8.3323 + 8.3324 + /* Convert */ 8.3325 + for(y=0; y<160 && y<o->h; y++) { 8.3326 + p=(Uint8 *)pix+srcPitch*y; 8.3327 + op[0]=o->pixels[0]+o->pitches[0]*y; 8.3328 + op[1]=o->pixels[1]+o->pitches[1]*(y/2); 8.3329 + op[2]=o->pixels[2]+o->pitches[2]*(y/2); 8.3330 + for(x=0; x<240 && x<o->w; x++) { 8.3331 + RGBtoYUV(p,yuv); 8.3332 + *(op[0]++)=yuv[0]; 8.3333 + if(x%2==0 && y%2==0) { 8.3334 + *(op[1]++)=yuv[1]; 8.3335 + *(op[2]++)=yuv[2]; 8.3336 + } 8.3337 + p+=4; //s->format->BytesPerPixel; 8.3338 + } 8.3339 + } 8.3340 + 8.3341 + SDL_UnlockYUVOverlay(o); 8.3342 +} 8.3343 + 8.3344 +inline void ConvertRGBtoUYVY(SDL_Overlay *o) 8.3345 +{ 8.3346 + int x,y; 8.3347 + int yuv[3]; 8.3348 + Uint8 *p,*op; 8.3349 + 8.3350 + SDL_LockYUVOverlay(o); 8.3351 + 8.3352 + for(y=0; y<160 && y<o->h; y++) { 8.3353 + p=(Uint8 *)pix+srcPitch*y; 8.3354 + op=o->pixels[0]+o->pitches[0]*y; 8.3355 + for(x=0; x<240 && x<o->w; x++) { 8.3356 + RGBtoYUV(p,yuv); 8.3357 + if(x%2==0) { 8.3358 + *(op++)=yuv[1]; 8.3359 + *(op++)=yuv[0]; 8.3360 + *(op++)=yuv[2]; 8.3361 + } else 8.3362 + *(op++)=yuv[0]; 8.3363 + 8.3364 + p+=4; //s->format->BytesPerPixel; 8.3365 + } 8.3366 + } 8.3367 + 8.3368 + SDL_UnlockYUVOverlay(o); 8.3369 +} 8.3370 + 8.3371 +inline void ConvertRGBtoYVYU(SDL_Overlay *o) 8.3372 +{ 8.3373 + int x,y; 8.3374 + int yuv[3]; 8.3375 + Uint8 *p,*op; 8.3376 + 8.3377 + SDL_LockYUVOverlay(o); 8.3378 + 8.3379 + for(y=0; y<160 && y<o->h; y++) { 8.3380 + p=(Uint8 *)pix+srcPitch*y; 8.3381 + op=o->pixels[0]+o->pitches[0]*y; 8.3382 + for(x=0; x<240 && x<o->w; x++) { 8.3383 + RGBtoYUV(p,yuv); 8.3384 + if(x%2==0) { 8.3385 + *(op++)=yuv[0]; 8.3386 + *(op++)=yuv[2]; 8.3387 + op[1]=yuv[1]; 8.3388 + } else { 8.3389 + *op=yuv[0]; 8.3390 + op+=2; 8.3391 + } 8.3392 + 8.3393 + p+=4; //s->format->BytesPerPixel; 8.3394 + } 8.3395 + } 8.3396 + 8.3397 + SDL_UnlockYUVOverlay(o); 8.3398 +} 8.3399 + 8.3400 +inline void ConvertRGBtoYUY2(SDL_Overlay *o) 8.3401 +{ 8.3402 + int x,y; 8.3403 + int yuv[3]; 8.3404 + Uint8 *p,*op; 8.3405 + 8.3406 + SDL_LockYUVOverlay(o); 8.3407 + 8.3408 + for(y=0; y<160 && y<o->h; y++) { 8.3409 + p=(Uint8 *)pix+srcPitch*y; 8.3410 + op=o->pixels[0]+o->pitches[0]*y; 8.3411 + for(x=0; x<240 && x<o->w; x++) { 8.3412 + RGBtoYUV(p,yuv); 8.3413 + if(x%2==0) { 8.3414 + *(op++)=yuv[0]; 8.3415 + *(op++)=yuv[1]; 8.3416 + op[1]=yuv[2]; 8.3417 + } else { 8.3418 + *op=yuv[0]; 8.3419 + op+=2; 8.3420 + } 8.3421 + 8.3422 + p+=4; //s->format->BytesPerPixel; 8.3423 + } 8.3424 + } 8.3425 + 8.3426 + SDL_UnlockYUVOverlay(o); 8.3427 +} 8.3428 + 8.3429 +inline void Convert32bit(SDL_Surface *display) 8.3430 +{ 8.3431 + switch(overlay->format) { 8.3432 + case SDL_YV12_OVERLAY: 8.3433 + ConvertRGBtoYV12(overlay); 8.3434 + break; 8.3435 + case SDL_UYVY_OVERLAY: 8.3436 + ConvertRGBtoUYVY(overlay); 8.3437 + break; 8.3438 + case SDL_YVYU_OVERLAY: 8.3439 + ConvertRGBtoYVYU(overlay); 8.3440 + break; 8.3441 + case SDL_YUY2_OVERLAY: 8.3442 + ConvertRGBtoYUY2(overlay); 8.3443 + break; 8.3444 + case SDL_IYUV_OVERLAY: 8.3445 + ConvertRGBtoIYUV(overlay); 8.3446 + break; 8.3447 + default: 8.3448 + fprintf(stderr, "cannot convert RGB picture to obtained YUV format!\n"); 8.3449 + exit(1); 8.3450 + break; 8.3451 + } 8.3452 + 8.3453 +} 8.3454 + 8.3455 + 8.3456 +inline void Draw_Overlay(SDL_Surface *display, int size) 8.3457 +{ 8.3458 + SDL_LockYUVOverlay(overlay); 8.3459 + 8.3460 + Convert32bit(display); 8.3461 + 8.3462 + overlay_rect.x = 0; 8.3463 + overlay_rect.y = 0; 8.3464 + overlay_rect.w = GBA_WIDTH * size; 8.3465 + overlay_rect.h = GBA_HEIGHT * size; 8.3466 + 8.3467 + SDL_DisplayYUVOverlay(overlay, &overlay_rect); 8.3468 + SDL_UnlockYUVOverlay(overlay); 8.3469 +} 8.3470 + 8.3471 +bool systemIsEmulating() 8.3472 +{ 8.3473 + return emulating != 0; 8.3474 +} 8.3475 + 8.3476 +void systemGbBorderOn() 8.3477 +{ 8.3478 + srcWidth = 256; 8.3479 + srcHeight = 224; 8.3480 + gbBorderLineSkip = 256; 8.3481 + gbBorderColumnSkip = 48; 8.3482 + gbBorderRowSkip = 40; 8.3483 + 8.3484 + destWidth = (sizeOption+1)*srcWidth; 8.3485 + destHeight = (sizeOption+1)*srcHeight; 8.3486 + 8.3487 + surface = SDL_SetVideoMode(destWidth, destHeight, 16, 8.3488 + SDL_ANYFORMAT|SDL_HWSURFACE|SDL_DOUBLEBUF| 8.3489 + (fullscreen ? SDL_FULLSCREEN : 0)); 8.3490 +#ifndef C_CORE 8.3491 + sdlMakeStretcher(srcWidth); 8.3492 +#else 8.3493 + switch(systemColorDepth) { 8.3494 + case 16: 8.3495 + sdlStretcher = sdlStretcher16[sizeOption]; 8.3496 + break; 8.3497 + case 24: 8.3498 + sdlStretcher = sdlStretcher24[sizeOption]; 8.3499 + break; 8.3500 + case 32: 8.3501 + sdlStretcher = sdlStretcher32[sizeOption]; 8.3502 + break; 8.3503 + default: 8.3504 + fprintf(stderr, "Unsupported resolution: %d\n", systemColorDepth); 8.3505 + exit(-1); 8.3506 + } 8.3507 +#endif 8.3508 + 8.3509 + if(systemColorDepth == 16) { 8.3510 + if(sdlCalculateMaskWidth(surface->format->Gmask) == 6) { 8.3511 + Init_2xSaI(565); 8.3512 + RGB_LOW_BITS_MASK = 0x821; 8.3513 + } else { 8.3514 + Init_2xSaI(555); 8.3515 + RGB_LOW_BITS_MASK = 0x421; 8.3516 + } 8.3517 + if(systemCartridgeType == 2) { 8.3518 + for(int i = 0; i < 0x10000; i++) { 8.3519 + systemColorMap16[i] = (((i >> 1) & 0x1f) << systemBlueShift) | 8.3520 + (((i & 0x7c0) >> 6) << systemGreenShift) | 8.3521 + (((i & 0xf800) >> 11) << systemRedShift); 8.3522 + } 8.3523 + } else { 8.3524 + for(int i = 0; i < 0x10000; i++) { 8.3525 + systemColorMap16[i] = ((i & 0x1f) << systemRedShift) | 8.3526 + (((i & 0x3e0) >> 5) << systemGreenShift) | 8.3527 + (((i & 0x7c00) >> 10) << systemBlueShift); 8.3528 + } 8.3529 + } 8.3530 + srcPitch = srcWidth * 2+4; 8.3531 + } else { 8.3532 + if(systemColorDepth != 32) 8.3533 + filterFunction = NULL; 8.3534 + RGB_LOW_BITS_MASK = 0x010101; 8.3535 + if(systemColorDepth == 32) { 8.3536 + Init_2xSaI(32); 8.3537 + } 8.3538 + for(int i = 0; i < 0x10000; i++) { 8.3539 + systemColorMap32[i] = ((i & 0x1f) << systemRedShift) | 8.3540 + (((i & 0x3e0) >> 5) << systemGreenShift) | 8.3541 + (((i & 0x7c00) >> 10) << systemBlueShift); 8.3542 + } 8.3543 + if(systemColorDepth == 32) 8.3544 + srcPitch = srcWidth*4 + 4; 8.3545 + else 8.3546 + srcPitch = srcWidth*3; 8.3547 + } 8.3548 +} 8.3549 + 8.3550 +bool systemIsRunningGBA() 8.3551 +{ 8.3552 + return (rom != NULL); 8.3553 +} 8.3554 + 8.3555 +int systemGetDefaultJoypad() 8.3556 +{ 8.3557 + return sdlDefaultJoypad; 8.3558 +} 8.3559 + 8.3560 +bool systemIsPaused() 8.3561 +{ 8.3562 + return paused; 8.3563 +} 8.3564 + 8.3565 +void systemSetPause(bool pause) 8.3566 +{ 8.3567 + paused = pause; 8.3568 + if (pause) 8.3569 + systemSoundPause(); 8.3570 + else 8.3571 + systemSoundResume(); 8.3572 +} 8.3573 + 8.3574 +u16 checksumBIOS() 8.3575 +{ 8.3576 + bool hasBIOS = false; 8.3577 + u8 * tempBIOS; 8.3578 + if(useBios) 8.3579 + { 8.3580 + tempBIOS = (u8 *)malloc(0x4000); 8.3581 + int size = 0x4000; 8.3582 + if(utilLoad(biosFileName, 8.3583 + utilIsGBABios, 8.3584 + tempBIOS, 8.3585 + size)) { 8.3586 + if(size == 0x4000) 8.3587 + hasBIOS = true; 8.3588 + } 8.3589 + } 8.3590 + 8.3591 + u16 biosCheck = 0; 8.3592 + if(hasBIOS) { 8.3593 + for(int i = 0; i < 0x4000; i += 4) 8.3594 + biosCheck += *((u32 *)&tempBIOS[i]); 8.3595 + free(tempBIOS); 8.3596 + } 8.3597 + 8.3598 + return biosCheck; 8.3599 +} 8.3600 + 8.3601 +EmulatedSystemCounters systemCounters = { 8.3602 + 0, //framecount 8.3603 + 0, //lagcount 8.3604 + 0, //extracount 8.3605 + true, //lagged 8.3606 + true //laggedLast 8.3607 +}; 8.3608 + 8.3609 +void VBAOnEnteringFrameBoundary() 8.3610 +{ 8.3611 + CallRegisteredLuaFunctions(LUACALL_AFTEREMULATION); 8.3612 + 8.3613 + if (VBALuaRunning()) 8.3614 + { 8.3615 + VBALuaFrameBoundary(); 8.3616 + } 8.3617 + 8.3618 + VBAMovieUpdateState(); 8.3619 +} 8.3620 + 8.3621 +void VBAOnExitingFrameBoundary() 8.3622 +{ 8.3623 + ; 8.3624 +} 8.3625 + 8.3626 +
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/src/sdl/SoundDriver.h Sun Mar 04 21:06:50 2012 -0600 9.3 @@ -0,0 +1,65 @@ 9.4 +// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. 9.5 +// Copyright (C) 2008 VBA-M development team 9.6 + 9.7 +// This program is free software; you can redistribute it and/or modify 9.8 +// it under the terms of the GNU General Public License as published by 9.9 +// the Free Software Foundation; either version 2, or(at your option) 9.10 +// any later version. 9.11 +// 9.12 +// This program is distributed in the hope that it will be useful, 9.13 +// but WITHOUT ANY WARRANTY; without even the implied warranty of 9.14 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9.15 +// GNU General Public License for more details. 9.16 +// 9.17 +// You should have received a copy of the GNU General Public License 9.18 +// along with this program; if not, write to the Free Software Foundation, 9.19 +// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 9.20 + 9.21 +#ifndef __VBA_SOUND_DRIVER_H__ 9.22 +#define __VBA_SOUND_DRIVER_H__ 9.23 + 9.24 +#include "Types.h" 9.25 + 9.26 +/** 9.27 + * Sound driver abstract interface for the core to use to output sound. 9.28 + * Subclass this to implement a new sound driver. 9.29 + */ 9.30 +class SoundDriver 9.31 +{ 9.32 +public: 9.33 + 9.34 + /** 9.35 + * Destructor. Free the resources allocated by the sound driver. 9.36 + */ 9.37 + virtual ~SoundDriver() { }; 9.38 + 9.39 + /** 9.40 + * Initialize the sound driver. 9.41 + * @param sampleRate In Hertz 9.42 + */ 9.43 + virtual bool init() = 0; 9.44 + 9.45 + /** 9.46 + * Tell the driver that the sound stream has paused 9.47 + */ 9.48 + virtual void pause() = 0; 9.49 + 9.50 + /** 9.51 + * Reset the sound driver 9.52 + */ 9.53 + virtual void reset() = 0; 9.54 + 9.55 + /** 9.56 + * Tell the driver that the sound stream has resumed 9.57 + */ 9.58 + virtual void resume() = 0; 9.59 + 9.60 + /** 9.61 + * Write length bytes of data from the finalWave buffer to the driver output buffer. 9.62 + */ 9.63 + virtual void write(u16 * finalWave, int length) = 0; 9.64 + 9.65 + virtual bool setThrottle(unsigned short throttle) = 0; 9.66 +}; 9.67 + 9.68 +#endif // __VBA_SOUND_DRIVER_H__
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/src/sdl/SoundSDL.cpp Sun Mar 04 21:06:50 2012 -0600 10.3 @@ -0,0 +1,178 @@ 10.4 +// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. 10.5 +// Copyright (C) 2008 VBA-M development team 10.6 + 10.7 +// This program is free software; you can redistribute it and/or modify 10.8 +// it under the terms of the GNU General Public License as published by 10.9 +// the Free Software Foundation; either version 2, or(at your option) 10.10 +// any later version. 10.11 +// 10.12 +// This program is distributed in the hope that it will be useful, 10.13 +// but WITHOUT ANY WARRANTY; without even the implied warranty of 10.14 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10.15 +// GNU General Public License for more details. 10.16 +// 10.17 +// You should have received a copy of the GNU General Public License 10.18 +// along with this program; if not, write to the Free Software Foundation, 10.19 +// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 10.20 + 10.21 +#include "SoundSDL.h" 10.22 + 10.23 +extern int emulating; 10.24 +extern bool speedup; 10.25 + 10.26 +// Hold up to 100 ms of data in the ring buffer 10.27 +const float SoundSDL::_delay = 0.1f; 10.28 + 10.29 +SoundSDL::SoundSDL(): 10.30 + _rbuf(0), 10.31 + _initialized(false) 10.32 +{ 10.33 + 10.34 +} 10.35 + 10.36 +void SoundSDL::soundCallback(void *data, u8 *stream, int len) 10.37 +{ 10.38 + reinterpret_cast<SoundSDL*>(data)->read(reinterpret_cast<u16 *>(stream), len); 10.39 +} 10.40 + 10.41 +void SoundSDL::read(u16 * stream, int length) 10.42 +{ 10.43 + if (!_initialized || length <= 0 || !emulating) 10.44 + return; 10.45 + 10.46 + SDL_mutexP(_mutex); 10.47 + _rbuf.read(stream, std::min(static_cast<std::size_t>(length) / 2, _rbuf.used())); 10.48 + 10.49 + SDL_CondSignal(_cond); 10.50 + SDL_mutexV(_mutex); 10.51 +} 10.52 + 10.53 +void SoundSDL::write(u16 * finalWave, int length) 10.54 +{ 10.55 + if (!_initialized) 10.56 + return; 10.57 + 10.58 + if (SDL_GetAudioStatus() != SDL_AUDIO_PLAYING) 10.59 + SDL_PauseAudio(0); 10.60 + 10.61 + SDL_mutexP(_mutex); 10.62 + 10.63 + unsigned int samples = length / 4; 10.64 + 10.65 + std::size_t avail; 10.66 + while ((avail = _rbuf.avail() / 2) < samples) 10.67 + { 10.68 + _rbuf.write(finalWave, avail * 2); 10.69 + 10.70 + finalWave += avail * 2; 10.71 + samples -= avail; 10.72 + 10.73 + // If emulating and not in speed up mode, synchronize to audio 10.74 + // by waiting till there is enough room in the buffer 10.75 + if (emulating && !speedup) 10.76 + { 10.77 + SDL_CondWait(_cond,_mutex); 10.78 + } 10.79 + else 10.80 + { 10.81 + // Drop the remaining of the audio data 10.82 + SDL_mutexV(_mutex); 10.83 + return; 10.84 + } 10.85 + } 10.86 + 10.87 + _rbuf.write(finalWave, samples * 2); 10.88 + 10.89 + SDL_mutexV(_mutex); 10.90 +} 10.91 + 10.92 + 10.93 +bool SoundSDL::init() 10.94 +{ 10.95 + SDL_AudioSpec audio; 10.96 + audio.freq = SDL_SAMPLE_RATE; 10.97 + audio.format = AUDIO_S16SYS; 10.98 + audio.channels = 2; 10.99 + audio.samples = 1024; 10.100 + audio.callback = soundCallback; 10.101 + audio.userdata = this; 10.102 + 10.103 + if(SDL_OpenAudio(&audio, NULL)) 10.104 + { 10.105 + fprintf(stderr,"Failed to open audio: %s\n", SDL_GetError()); 10.106 + return false; 10.107 + } 10.108 + 10.109 + _rbuf.reset(_delay * SDL_SAMPLE_RATE * 2); 10.110 + 10.111 + _cond = SDL_CreateCond(); 10.112 + _mutex = SDL_CreateMutex(); 10.113 + _initialized = true; 10.114 + 10.115 + return true; 10.116 +} 10.117 + 10.118 +SoundSDL::~SoundSDL() 10.119 +{ 10.120 + if (!_initialized) 10.121 + return; 10.122 + 10.123 + SDL_mutexP(_mutex); 10.124 + int iSave = emulating; 10.125 + emulating = 0; 10.126 + SDL_CondSignal(_cond); 10.127 + SDL_mutexV(_mutex); 10.128 + 10.129 + SDL_DestroyCond(_cond); 10.130 + _cond = NULL; 10.131 + 10.132 + SDL_DestroyMutex(_mutex); 10.133 + _mutex = NULL; 10.134 + 10.135 + SDL_CloseAudio(); 10.136 + 10.137 + emulating = iSave; 10.138 +} 10.139 + 10.140 +void SoundSDL::pause() 10.141 +{ 10.142 + if (!_initialized) 10.143 + return; 10.144 + 10.145 + SDL_PauseAudio(1); 10.146 +} 10.147 + 10.148 +void SoundSDL::resume() 10.149 +{ 10.150 + if (!_initialized) 10.151 + return; 10.152 + 10.153 + SDL_PauseAudio(0); 10.154 +} 10.155 + 10.156 +void SoundSDL::reset() 10.157 +{ 10.158 +} 10.159 + 10.160 +bool SoundSDL::setThrottle(unsigned short throttle){ 10.161 + switch(throttle){ 10.162 + case 25: 10.163 + case 50: 10.164 + case 100: 10.165 + case 200: 10.166 + case 400: 10.167 + break; 10.168 + default: 10.169 + return false; 10.170 + } 10.171 + SDL_CloseAudio(); 10.172 + SDL_AudioSpec audio; 10.173 + audio.freq = SDL_SAMPLE_RATE*throttle/100; 10.174 + audio.format = AUDIO_S16SYS; 10.175 + audio.channels = 2; 10.176 + audio.samples = 1024; 10.177 + audio.callback = soundCallback; 10.178 + audio.userdata = this; 10.179 + _rbuf.reset((_delay * SDL_SAMPLE_RATE * throttle * 2)/100); 10.180 + return !SDL_OpenAudio(&audio,NULL); 10.181 +}
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/src/sdl/SoundSDL.h Sun Mar 04 21:06:50 2012 -0600 11.3 @@ -0,0 +1,56 @@ 11.4 +// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. 11.5 +// Copyright (C) 2008 VBA-M development team 11.6 + 11.7 +// This program is free software; you can redistribute it and/or modify 11.8 +// it under the terms of the GNU General Public License as published by 11.9 +// the Free Software Foundation; either version 2, or(at your option) 11.10 +// any later version. 11.11 +// 11.12 +// This program is distributed in the hope that it will be useful, 11.13 +// but WITHOUT ANY WARRANTY; without even the implied warranty of 11.14 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11.15 +// GNU General Public License for more details. 11.16 +// 11.17 +// You should have received a copy of the GNU General Public License 11.18 +// along with this program; if not, write to the Free Software Foundation, 11.19 +// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 11.20 + 11.21 +#ifndef __VBA_SOUND_SDL_H__ 11.22 +#define __VBA_SOUND_SDL_H__ 11.23 + 11.24 +#include "SoundDriver.h" 11.25 +#include "RingBuffer.h" 11.26 + 11.27 +#include <SDL.h> 11.28 + 11.29 +const int SDL_SAMPLE_RATE = 44100; 11.30 + 11.31 +class SoundSDL: public SoundDriver 11.32 +{ 11.33 +public: 11.34 + SoundSDL(); 11.35 + virtual ~SoundSDL(); 11.36 + 11.37 + virtual bool init(); 11.38 + virtual void pause(); 11.39 + virtual void reset(); 11.40 + virtual void resume(); 11.41 + virtual void write(u16 * finalWave, int length); 11.42 + virtual bool setThrottle(unsigned short throttle); 11.43 + 11.44 +//private: 11.45 + RingBuffer<u16> _rbuf; 11.46 + 11.47 + SDL_cond * _cond; 11.48 + SDL_mutex * _mutex; 11.49 + 11.50 + bool _initialized; 11.51 + 11.52 + // Defines what delay in seconds we keep in the sound buffer 11.53 + static const float _delay; 11.54 + 11.55 + static void soundCallback(void *data, u8 *stream, int length); 11.56 + virtual void read(u16 * stream, int length); 11.57 +}; 11.58 + 11.59 +#endif // __VBA_SOUND_SDL_H__
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/src/sdl/TestEmu.cpp Sun Mar 04 21:06:50 2012 -0600 12.3 @@ -0,0 +1,501 @@ 12.4 +// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. 12.5 +// Copyright (C) 1999-2003 Forgotten 12.6 +// Copyright (C) 2004 Forgotten and the VBA development team 12.7 + 12.8 +// This program is free software; you can redistribute it and/or modify 12.9 +// it under the terms of the GNU General Public License as published by 12.10 +// the Free Software Foundation; either version 2, or(at your option) 12.11 +// any later version. 12.12 +// 12.13 +// This program is distributed in the hope that it will be useful, 12.14 +// but WITHOUT ANY WARRANTY; without even the implied warranty of 12.15 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12.16 +// GNU General Public License for more details. 12.17 +// 12.18 +// You should have received a copy of the GNU General Public License 12.19 +// along with this program; if not, write to the Free Software Foundation, 12.20 +// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 12.21 + 12.22 +#include <stdarg.h> 12.23 +#include <stdlib.h> 12.24 +#include <stdio.h> 12.25 +#include <string.h> 12.26 +#include <sys/types.h> 12.27 +#include <sys/stat.h> 12.28 + 12.29 +#include "AutoBuild.h" 12.30 + 12.31 +#include "SDL.h" 12.32 +#include "debugger.h" 12.33 +#include "common/System.h" 12.34 +#include "common/unzip.h" 12.35 +#include "common/Util.h" 12.36 +#include "gba/GBA.h" 12.37 +#include "gba/GBAGlobals.h" 12.38 +#include "gba/GBASound.h" 12.39 +#include "gb/GB.h" 12.40 +#include "gb/gbGlobals.h" 12.41 + 12.42 +#ifndef WIN32 12.43 +# include <unistd.h> 12.44 +# define GETCWD getcwd 12.45 +#else // WIN32 12.46 +# include <direct.h> 12.47 +# define GETCWD _getcwd 12.48 +#endif // WIN32 12.49 + 12.50 +#ifdef MMX 12.51 +extern "C" bool cpu_mmx; 12.52 +#endif 12.53 +extern bool8 soundEcho; 12.54 +extern bool8 soundLowPass; 12.55 +extern bool8 soundReverse; 12.56 + 12.57 +extern void remoteInit(); 12.58 +extern void remoteCleanUp(); 12.59 +extern void remoteStubMain(); 12.60 +extern void remoteStubSignal(int,int); 12.61 +extern void remoteOutput(char *, u32); 12.62 +extern void remoteSetProtocol(int); 12.63 +extern void remoteSetPort(int); 12.64 +extern void debuggerOutput(char *, u32); 12.65 + 12.66 +struct EmulatedSystem emulator; 12.67 + 12.68 +int systemRedShift = 0; 12.69 +int systemBlueShift = 16; 12.70 +int systemGreenShift = 8; 12.71 +int systemColorDepth = 32; 12.72 +int systemDebug = 0; 12.73 +int systemVerbose = 0; 12.74 +int systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; 12.75 + 12.76 +int sensorX = 2047; 12.77 +int sensorY = 2047; 12.78 +bool sensorOn = false; 12.79 + 12.80 +int cartridgeType = 3; 12.81 +int captureFormat = 0; 12.82 + 12.83 +int emulating = 0; 12.84 +int RGB_LOW_BITS_MASK=0x821; 12.85 +int systemFrameSkip = 0; 12.86 +u32 systemColorMap32[0x10000]; 12.87 +u16 systemColorMap16[0x10000]; 12.88 +u16 systemGbPalette[24]; 12.89 +char filename[2048]; 12.90 +char biosFileName[2048]; 12.91 +char captureDir[2048]; 12.92 +char saveDir[2048]; 12.93 +char batteryDir[2048]; 12.94 + 12.95 +int throttle = 0; 12.96 + 12.97 +bool paused = false; 12.98 +bool debugger = true; 12.99 +bool debuggerStub = false; 12.100 +bool systemSoundOn = false; 12.101 +bool removeIntros = false; 12.102 +int sdlFlashSize = 0; 12.103 +int sdlAutoIPS = 1; 12.104 +int sdlRtcEnable = 0; 12.105 +int sdlAgbPrint = 0; 12.106 + 12.107 +int sdlDefaultJoypad = 0; 12.108 + 12.109 +u16 motion[4] = { 12.110 + SDLK_KP4, SDLK_KP6, SDLK_KP8, SDLK_KP2 12.111 +}; 12.112 + 12.113 +extern void debuggerSignal(int,int); 12.114 + 12.115 +void (*dbgMain)() = debuggerMain; 12.116 +void (*dbgSignal)(int,int) = debuggerSignal; 12.117 +void (*dbgOutput)(char *, u32) = debuggerOutput; 12.118 + 12.119 +char *sdlGetFilename(char *name) 12.120 +{ 12.121 + static char filebuffer[2048]; 12.122 + 12.123 + int len = strlen(name); 12.124 + 12.125 + char *p = name + len - 1; 12.126 + 12.127 + while(true) { 12.128 + if(*p == '/' || 12.129 + *p == '\\') { 12.130 + p++; 12.131 + break; 12.132 + } 12.133 + len--; 12.134 + p--; 12.135 + if(len == 0) 12.136 + break; 12.137 + } 12.138 + 12.139 + if(len == 0) 12.140 + strcpy(filebuffer, name); 12.141 + else 12.142 + strcpy(filebuffer, p); 12.143 + return filebuffer; 12.144 +} 12.145 + 12.146 +void usage(char *cmd) 12.147 +{ 12.148 + printf("%s file-name\n",cmd); 12.149 +} 12.150 + 12.151 +int main(int argc, char **argv) 12.152 +{ 12.153 + fprintf(stderr,"VisualBoyAdvance-Test version %s\n", VERSION); 12.154 + 12.155 + captureDir[0] = 0; 12.156 + saveDir[0] = 0; 12.157 + batteryDir[0] = 0; 12.158 + 12.159 + char buffer[1024]; 12.160 + 12.161 + systemFrameSkip = frameSkip = 2; 12.162 + gbBorderOn = 0; 12.163 + 12.164 + parseDebug = true; 12.165 + 12.166 + if(!debuggerStub) { 12.167 + if(argc <= 1) { 12.168 + systemMessage(0,"Missing image name"); 12.169 + usage(argv[0]); 12.170 + exit(-1); 12.171 + } 12.172 + } 12.173 + 12.174 + for(int i = 0; i < 24;) { 12.175 + systemGbPalette[i++] = (0x1f) | (0x1f << 5) | (0x1f << 10); 12.176 + systemGbPalette[i++] = (0x15) | (0x15 << 5) | (0x15 << 10); 12.177 + systemGbPalette[i++] = (0x0c) | (0x0c << 5) | (0x0c << 10); 12.178 + systemGbPalette[i++] = 0; 12.179 + } 12.180 + 12.181 + if(argc == 2) { 12.182 + char *szFile = argv[optind]; 12.183 + bool failed = false; 12.184 + if(utilIsZipFile(szFile)) { 12.185 + unzFile unz = unzOpen(szFile); 12.186 + 12.187 + if(unz == NULL) { 12.188 + systemMessage(0, "Cannot open file %s", szFile); 12.189 + exit(-1); 12.190 + } 12.191 + int r = unzGoToFirstFile(unz); 12.192 + 12.193 + if(r != UNZ_OK) { 12.194 + unzClose(unz); 12.195 + systemMessage(0, "Bad ZIP file %s", szFile); 12.196 + exit(-1); 12.197 + } 12.198 + 12.199 + bool found = false; 12.200 + 12.201 + unz_file_info info; 12.202 + 12.203 + while(true) { 12.204 + r = unzGetCurrentFileInfo(unz, 12.205 + &info, 12.206 + buffer, 12.207 + sizeof(buffer), 12.208 + NULL, 12.209 + 0, 12.210 + NULL, 12.211 + 0); 12.212 + 12.213 + if(r != UNZ_OK) { 12.214 + unzClose(unz); 12.215 + systemMessage(0,"Bad ZIP file %s", szFile); 12.216 + exit(-1); 12.217 + } 12.218 + 12.219 + if(utilIsGBImage(buffer)) { 12.220 + found = true; 12.221 + cartridgeType = 1; 12.222 + break; 12.223 + } 12.224 + if(utilIsGBAImage(buffer)) { 12.225 + found = true; 12.226 + cartridgeType = 0; 12.227 + break; 12.228 + } 12.229 + 12.230 + r = unzGoToNextFile(unz); 12.231 + 12.232 + if(r != UNZ_OK) 12.233 + break; 12.234 + } 12.235 + 12.236 + if(!found) { 12.237 + unzClose(unz); 12.238 + systemMessage(0, "No image found on ZIP file %s", szFile); 12.239 + exit(-1); 12.240 + } 12.241 + 12.242 + unzClose(unz); 12.243 + } 12.244 + 12.245 + if(utilIsGBImage(szFile) || cartridgeType == 1) { 12.246 + failed = !gbLoadRom(szFile); 12.247 + cartridgeType = 1; 12.248 + emulator = GBSystem; 12.249 + } else if(utilIsGBAImage(szFile) || cartridgeType == 0) { 12.250 + failed = !CPULoadRom(szFile); 12.251 + cartridgeType = 0; 12.252 + emulator = GBASystem; 12.253 + 12.254 + //CPUInit(biosFileName, useBios); 12.255 + CPUInit(); 12.256 + CPUReset(); 12.257 + } else { 12.258 + systemMessage(0, "Unknown file type %s", szFile); 12.259 + exit(-1); 12.260 + } 12.261 + 12.262 + if(failed) { 12.263 + systemMessage(0, "Failed to load file %s", szFile); 12.264 + exit(-1); 12.265 + } 12.266 + strcpy(filename, szFile); 12.267 + char *p = strrchr(filename, '.'); 12.268 + 12.269 + if(p) 12.270 + *p = 0; 12.271 + } else { 12.272 + cartridgeType = 0; 12.273 + strcpy(filename, "gnu_stub"); 12.274 + rom = (u8 *)malloc(0x2000000); 12.275 + workRAM = (u8 *)calloc(1, 0x40000); 12.276 + bios = (u8 *)calloc(1,0x4000); 12.277 + internalRAM = (u8 *)calloc(1,0x8000); 12.278 + paletteRAM = (u8 *)calloc(1,0x400); 12.279 + vram = (u8 *)calloc(1, 0x20000); 12.280 + oam = (u8 *)calloc(1, 0x400); 12.281 + pix = (u8 *)calloc(1, 4 * 240 * 160); 12.282 + ioMem = (u8 *)calloc(1, 0x400); 12.283 + 12.284 + emulator = GBASystem; 12.285 + 12.286 + //CPUInit(biosFileName, useBios); 12.287 + CPUInit(); 12.288 + CPUReset(); 12.289 + } 12.290 + 12.291 + if(debuggerStub) 12.292 + remoteInit(); 12.293 + 12.294 + if(cartridgeType == 0) { 12.295 + } else if (cartridgeType == 1) { 12.296 + if(gbBorderOn) { 12.297 + gbBorderLineSkip = 256; 12.298 + gbBorderColumnSkip = 48; 12.299 + gbBorderRowSkip = 40; 12.300 + } else { 12.301 + gbBorderLineSkip = 160; 12.302 + gbBorderColumnSkip = 0; 12.303 + gbBorderRowSkip = 0; 12.304 + } 12.305 + } else { 12.306 + } 12.307 + 12.308 + for(int i = 0; i < 0x10000; i++) { 12.309 + systemColorMap32[i] = ((i & 0x1f) << systemRedShift) | 12.310 + (((i & 0x3e0) >> 5) << systemGreenShift) | 12.311 + (((i & 0x7c00) >> 10) << systemBlueShift); 12.312 + } 12.313 + 12.314 + emulating = 1; 12.315 + soundInit(); 12.316 + 12.317 + while(emulating) { 12.318 + if(!paused) { 12.319 + if(debugger && emulator.emuHasDebugger) 12.320 + dbgMain(); 12.321 + else 12.322 + emulator.emuMain(emulator.emuCount); 12.323 + } 12.324 + } 12.325 + emulating = 0; 12.326 + fprintf(stderr,"Shutting down\n"); 12.327 + remoteCleanUp(); 12.328 + soundShutdown(); 12.329 + 12.330 + if(gbRom != NULL || rom != NULL) { 12.331 + emulator.emuCleanUp(); 12.332 + } 12.333 + 12.334 + return 0; 12.335 +} 12.336 + 12.337 +void systemMessage(int num, const char *msg, ...) 12.338 +{ 12.339 + char buffer[2048]; 12.340 + va_list valist; 12.341 + 12.342 + va_start(valist, msg); 12.343 + vsprintf(buffer, msg, valist); 12.344 + 12.345 + fprintf(stderr, "%s\n", buffer); 12.346 + va_end(valist); 12.347 +} 12.348 + 12.349 +void systemDrawScreen() 12.350 +{ 12.351 +} 12.352 + 12.353 +bool systemReadJoypads() 12.354 +{ 12.355 + return true; 12.356 +} 12.357 + 12.358 +u32 systemReadJoypad(int,bool) 12.359 +{ 12.360 + return 0; 12.361 +} 12.362 + 12.363 +void systemShowSpeed(int speed) 12.364 +{ 12.365 +} 12.366 + 12.367 +void system10Frames(int rate) 12.368 +{ 12.369 +} 12.370 + 12.371 +void systemFrame(int) 12.372 +{ 12.373 +} 12.374 + 12.375 +void systemSetTitle(const char *title) 12.376 +{ 12.377 +} 12.378 + 12.379 +int systemScreenCapture(int a) 12.380 +{ 12.381 + char buffer[2048]; 12.382 + 12.383 + if(captureFormat) { 12.384 + if(captureDir[0]) 12.385 + sprintf(buffer, "%s/%s%02d.bmp", captureDir, sdlGetFilename(filename), a); 12.386 + else 12.387 + sprintf(buffer, "%s%02d.bmp", filename, a); 12.388 + 12.389 + emulator.emuWriteBMP(buffer); 12.390 + } else { 12.391 + if(captureDir[0]) 12.392 + sprintf(buffer, "%s/%s%02d.png", captureDir, sdlGetFilename(filename), a); 12.393 + else 12.394 + sprintf(buffer, "%s%02d.png", filename, a); 12.395 + emulator.emuWritePNG(buffer); 12.396 + } 12.397 + 12.398 + systemScreenMessage("Screen capture"); 12.399 +} 12.400 + 12.401 +u32 systemReadJoypadExtended() 12.402 +{ 12.403 + return 0; 12.404 +} 12.405 + 12.406 +void systemWriteDataToSoundBuffer() 12.407 +{ 12.408 +} 12.409 + 12.410 +bool systemSoundInit() 12.411 +{ 12.412 + return true; 12.413 +} 12.414 + 12.415 +void systemSoundShutdown() 12.416 +{ 12.417 +} 12.418 + 12.419 +void systemSoundPause() 12.420 +{ 12.421 +} 12.422 + 12.423 +void systemSoundResume() 12.424 +{ 12.425 +} 12.426 + 12.427 +void systemSoundReset() 12.428 +{ 12.429 +} 12.430 + 12.431 +static int ticks = 0; 12.432 + 12.433 +u32 systemGetClock() 12.434 +{ 12.435 + return ticks++; 12.436 +} 12.437 + 12.438 +void systemUpdateMotionSensor() 12.439 +{ 12.440 +} 12.441 + 12.442 +int systemGetSensorX() 12.443 +{ 12.444 + return 0; 12.445 +} 12.446 + 12.447 +int systemGetSensorY() 12.448 +{ 12.449 + return 0; 12.450 +} 12.451 + 12.452 +void systemGbPrint(u8 *data,int pages,int feed,int palette, int contrast) 12.453 +{ 12.454 +} 12.455 + 12.456 +void systemScreenMessage(const char *msg, int slot, int duration, const char *colorList) 12.457 +{ 12.458 +} 12.459 + 12.460 +bool systemCanChangeSoundQuality() 12.461 +{ 12.462 + return false; 12.463 +} 12.464 + 12.465 +bool systemPauseOnFrame() 12.466 +{ 12.467 + return false; 12.468 +} 12.469 + 12.470 +void systemGbBorderOn() 12.471 +{ 12.472 +} 12.473 + 12.474 +bool sdlCheckJoyKey(int) 12.475 +{ 12.476 + return true; 12.477 +} 12.478 + 12.479 +u16 checksumBIOS() 12.480 +{ 12.481 + bool hasBIOS = false; 12.482 + u8 * tempBIOS; 12.483 + if(useBios) 12.484 + { 12.485 + tempBIOS = (u8 *)malloc(0x4000); 12.486 + int size = 0x4000; 12.487 + if(utilLoad(biosFileName, 12.488 + utilIsGBABios, 12.489 + tempBIOS, 12.490 + size)) { 12.491 + if(size == 0x4000) 12.492 + hasBIOS = true; 12.493 + } 12.494 + } 12.495 + 12.496 + u16 biosCheck = 0; 12.497 + if(hasBIOS) { 12.498 + for(int i = 0; i < 0x4000; i += 4) 12.499 + biosCheck += *((u32 *)&tempBIOS[i]); 12.500 + free(tempBIOS); 12.501 + } 12.502 + 12.503 + return biosCheck; 12.504 +}
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/src/sdl/Types.h Sun Mar 04 21:06:50 2012 -0600 13.3 @@ -0,0 +1,33 @@ 13.4 +// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. 13.5 +// Copyright (C) 2008 VBA-M development team 13.6 + 13.7 +// This program is free software; you can redistribute it and/or modify 13.8 +// it under the terms of the GNU General Public License as published by 13.9 +// the Free Software Foundation; either version 2, or(at your option) 13.10 +// any later version. 13.11 +// 13.12 +// This program is distributed in the hope that it will be useful, 13.13 +// but WITHOUT ANY WARRANTY; without even the implied warranty of 13.14 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13.15 +// GNU General Public License for more details. 13.16 +// 13.17 +// You should have received a copy of the GNU General Public License 13.18 +// along with this program; if not, write to the Free Software Foundation, 13.19 +// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 13.20 + 13.21 +#ifndef __VBA_TYPES_H__ 13.22 +#define __VBA_TYPES_H__ 13.23 + 13.24 +#include <stdint.h> 13.25 + 13.26 +typedef uint8_t u8; 13.27 +typedef uint16_t u16; 13.28 +typedef uint32_t u32; 13.29 +typedef uint64_t u64; 13.30 + 13.31 +typedef int8_t s8; 13.32 +typedef int16_t s16; 13.33 +typedef int32_t s32; 13.34 +typedef int64_t s64; 13.35 + 13.36 +#endif // __VBA_TYPES_H__
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/src/sdl/debugger.cpp Sun Mar 04 21:06:50 2012 -0600 14.3 @@ -0,0 +1,1460 @@ 14.4 +// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. 14.5 +// Copyright (C) 1999-2003 Forgotten 14.6 +// Copyright (C) 2004 Forgotten and the VBA development team 14.7 + 14.8 +// This program is free software; you can redistribute it and/or modify 14.9 +// it under the terms of the GNU General Public License as published by 14.10 +// the Free Software Foundation; either version 2, or(at your option) 14.11 +// any later version. 14.12 +// 14.13 +// This program is distributed in the hope that it will be useful, 14.14 +// but WITHOUT ANY WARRANTY; without even the implied warranty of 14.15 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14.16 +// GNU General Public License for more details. 14.17 +// 14.18 +// You should have received a copy of the GNU General Public License 14.19 +// along with this program; if not, write to the Free Software Foundation, 14.20 +// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 14.21 + 14.22 +extern "C" { 14.23 +#include <stdio.h> 14.24 +#include <stdlib.h> 14.25 +} // FIXME: should use c++ headers instead 14.26 + 14.27 +#include <string.h> 14.28 + 14.29 +#include "Port.h" 14.30 +#include "gba/GBA.h" 14.31 +#include "gba/GBAGlobals.h" 14.32 +#include "gba/GBACheats.h" 14.33 +#include "gba/armdis.h" 14.34 +#include "gba/elf.h" 14.35 +#include "common/System.h" 14.36 +#include "exprNode.h" 14.37 + 14.38 +extern bool debugger; 14.39 +extern int emulating; 14.40 + 14.41 +extern struct EmulatedSystem theEmulator; 14.42 + 14.43 +#define debuggerReadMemory(addr) \ 14.44 + READ32LE((&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask])) 14.45 + 14.46 +#define debuggerReadHalfWord(addr) \ 14.47 + READ16LE((&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask])) 14.48 + 14.49 +#define debuggerReadByte(addr) \ 14.50 + map[(addr)>>24].address[(addr) & map[(addr)>>24].mask] 14.51 + 14.52 +#define debuggerWriteMemory(addr, value) \ 14.53 + WRITE32LE(&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask], value) 14.54 + 14.55 +#define debuggerWriteHalfWord(addr, value) \ 14.56 + WRITE16LE(&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask], value) 14.57 + 14.58 +#define debuggerWriteByte(addr, value) \ 14.59 + map[(addr)>>24].address[(addr) & map[(addr)>>24].mask] = (value) 14.60 + 14.61 +struct breakpointInfo { 14.62 + u32 address; 14.63 + u32 value; 14.64 + int size; 14.65 +}; 14.66 + 14.67 +struct DebuggerCommand { 14.68 + const char *name; 14.69 + void (*function)(int,char **); 14.70 + const char *help; 14.71 + const char *syntax; 14.72 +}; 14.73 + 14.74 +void debuggerContinueAfterBreakpoint(); 14.75 + 14.76 +void debuggerHelp(int,char **); 14.77 +void debuggerNext(int,char **); 14.78 +void debuggerContinue(int, char **); 14.79 +void debuggerRegisters(int, char **); 14.80 +void debuggerBreak(int, char **); 14.81 +void debuggerBreakDelete(int, char **); 14.82 +void debuggerBreakList(int, char **); 14.83 +void debuggerBreakArm(int, char **); 14.84 +void debuggerBreakWriteClear(int, char **); 14.85 +void debuggerBreakThumb(int, char **); 14.86 +void debuggerBreakWrite(int, char **); 14.87 +void debuggerDebug(int, char **); 14.88 +void debuggerDisassemble(int, char **); 14.89 +void debuggerDisassembleArm(int, char **); 14.90 +void debuggerDisassembleThumb(int, char **); 14.91 +void debuggerEditByte(int, char **); 14.92 +void debuggerEditHalfWord(int, char **); 14.93 +void debuggerEdit(int, char **); 14.94 +void debuggerIo(int, char **); 14.95 +void debuggerLocals(int, char **); 14.96 +void debuggerMemoryByte(int, char **); 14.97 +void debuggerMemoryHalfWord(int, char **); 14.98 +void debuggerMemory(int, char **); 14.99 +void debuggerPrint(int, char **); 14.100 +void debuggerQuit(int, char **); 14.101 +void debuggerSetRadix(int, char **); 14.102 +void debuggerSymbols(int, char **); 14.103 +void debuggerVerbose(int, char **); 14.104 +void debuggerWhere(int, char **); 14.105 + 14.106 +DebuggerCommand debuggerCommands[] = { 14.107 + { "?", debuggerHelp, "Shows this help information. Type ? <command> for command help", "[<command>]" }, 14.108 + { "ba", debuggerBreakArm, "Adds an ARM breakpoint", "<address>" }, 14.109 + { "bd", debuggerBreakDelete,"Deletes a breakpoint", "<number>" }, 14.110 + { "bl", debuggerBreakList, "Lists breakpoints" }, 14.111 + { "bpw", debuggerBreakWrite, "Break on write", "<address> <size>" }, 14.112 + { "bpwc", debuggerBreakWriteClear, "Clear break on write", NULL }, 14.113 + { "break", debuggerBreak, "Adds a breakpoint on the given function", "<function>|<line>|<file:line>" }, 14.114 + { "bt", debuggerBreakThumb, "Adds a THUMB breakpoint", "<address>" }, 14.115 + { "c", debuggerContinue, "Continues execution" , NULL }, 14.116 + { "d", debuggerDisassemble, "Disassembles instructions", "[<address> [<number>]]" }, 14.117 + { "da", debuggerDisassembleArm, "Disassembles ARM instructions", "[<address> [<number>]]" }, 14.118 + { "dt", debuggerDisassembleThumb, "Disassembles THUMB instructions", "[<address> [<number>]]" }, 14.119 + { "eb", debuggerEditByte, "Modify memory location (byte)", "<address> <hex value>" }, 14.120 + { "eh", debuggerEditHalfWord,"Modify memory location (half-word)","<address> <hex value>" }, 14.121 + { "ew", debuggerEdit, "Modify memory location (word)", "<address> <hex value" }, 14.122 + { "h", debuggerHelp, "Shows this help information. Type h <command> for command help", "[<command>]" }, 14.123 + { "io", debuggerIo, "Show I/O registers status", "[video|video2|dma|timer|misc]" }, 14.124 + { "locals", debuggerLocals, "Shows local variables", NULL }, 14.125 + { "mb", debuggerMemoryByte, "Shows memory contents (bytes)", "<address>" }, 14.126 + { "mh", debuggerMemoryHalfWord, "Shows memory contents (half-words)", "<address>"}, 14.127 + { "mw", debuggerMemory, "Shows memory contents (words)", "<address>" }, 14.128 + { "n", debuggerNext, "Executes the next instruction", "[<count>]" }, 14.129 + { "print", debuggerPrint, "Print the value of a expression (if known)", "[/x|/o|/d] <expression>" }, 14.130 + { "q", debuggerQuit, "Quits the emulator", NULL }, 14.131 + { "r", debuggerRegisters, "Shows ARM registers", NULL }, 14.132 + { "radix", debuggerSetRadix, "Sets the print radix", "<radix>" }, 14.133 + { "symbols", debuggerSymbols, "List symbols", "[<symbol>]" }, 14.134 +#ifndef FINAL_VERSION 14.135 + { "trace", debuggerDebug, "Sets the trace level", "<value>" }, 14.136 +#endif 14.137 +#ifdef DEV_VERSION 14.138 + { "verbose", debuggerVerbose, "Change verbose setting", "<value>" }, 14.139 +#endif 14.140 + { "where", debuggerWhere, "Shows call chain", NULL }, 14.141 + { NULL, NULL, NULL, NULL} // end marker 14.142 +}; 14.143 + 14.144 +breakpointInfo debuggerBreakpointList[100]; 14.145 + 14.146 +int debuggerNumOfBreakpoints = 0; 14.147 +bool debuggerAtBreakpoint = false; 14.148 +int debuggerBreakpointNumber = 0; 14.149 +int debuggerRadix = 0; 14.150 + 14.151 +void debuggerApplyBreakpoint(u32 address, int num, int size) 14.152 +{ 14.153 + if(size) 14.154 + debuggerWriteMemory(address, (u32)(0xe1200070 | 14.155 + (num & 0xf) | 14.156 + ((num<<4)&0xf0))); 14.157 + else 14.158 + debuggerWriteHalfWord(address, 14.159 + (u16)(0xbe00 | num)); 14.160 +} 14.161 + 14.162 +void debuggerDisableBreakpoints() 14.163 +{ 14.164 + for(int i = 0; i < debuggerNumOfBreakpoints; i++) { 14.165 + if(debuggerBreakpointList[i].size) 14.166 + debuggerWriteMemory(debuggerBreakpointList[i].address, 14.167 + debuggerBreakpointList[i].value); 14.168 + else 14.169 + debuggerWriteHalfWord(debuggerBreakpointList[i].address, 14.170 + debuggerBreakpointList[i].value); 14.171 + } 14.172 +} 14.173 + 14.174 +void debuggerEnableBreakpoints(bool skipPC) 14.175 +{ 14.176 + for(int i = 0; i < debuggerNumOfBreakpoints; i++) { 14.177 + if(debuggerBreakpointList[i].address == armNextPC && skipPC) 14.178 + continue; 14.179 + 14.180 + debuggerApplyBreakpoint(debuggerBreakpointList[i].address, 14.181 + i, 14.182 + debuggerBreakpointList[i].size); 14.183 + } 14.184 +} 14.185 + 14.186 +void debuggerUsage(const char *cmd) 14.187 +{ 14.188 + for(int i = 0; ; i++) { 14.189 + if(debuggerCommands[i].name) { 14.190 + if(!strcmp(debuggerCommands[i].name, cmd)) { 14.191 + printf("%s %s\t%s\n", 14.192 + debuggerCommands[i].name, 14.193 + debuggerCommands[i].syntax ? debuggerCommands[i].syntax : "", 14.194 + debuggerCommands[i].help); 14.195 + break; 14.196 + } 14.197 + } else { 14.198 + printf("Unrecognized command '%s'.", cmd); 14.199 + break; 14.200 + } 14.201 + } 14.202 +} 14.203 + 14.204 +void debuggerPrintBaseType(Type *t, u32 value, u32 location, 14.205 + LocationType type, 14.206 + int bitSize, int bitOffset) 14.207 +{ 14.208 + if(bitSize) { 14.209 + if(bitOffset) 14.210 + value >>= ((t->size*8)-bitOffset-bitSize); 14.211 + value &= (1 << bitSize)-1; 14.212 + } else { 14.213 + if(t->size == 2) 14.214 + value &= 0xFFFF; 14.215 + else if(t->size == 1) 14.216 + value &= 0xFF; 14.217 + } 14.218 + 14.219 + if(t->size == 8) { 14.220 + u64 value = 0; 14.221 + if(type == LOCATION_memory) { 14.222 + value = debuggerReadMemory(location) | 14.223 + ((u64)debuggerReadMemory(location+4)<<32); 14.224 + } else if(type == LOCATION_register) { 14.225 + value = reg[location].I | ((u64)reg[location+1].I << 32); 14.226 + } 14.227 + switch(t->encoding) { 14.228 + case DW_ATE_signed: 14.229 + switch(debuggerRadix) { 14.230 + case 0: 14.231 + printf("%lld", value); 14.232 + break; 14.233 + case 1: 14.234 + printf("0x%llx", value); 14.235 + break; 14.236 + case 2: 14.237 + printf("0%llo", value); 14.238 + break; 14.239 + } 14.240 + break; 14.241 + case DW_ATE_unsigned: 14.242 + switch(debuggerRadix) { 14.243 + case 0: 14.244 + printf("%llu", value); 14.245 + break; 14.246 + case 1: 14.247 + printf("0x%llx", value); 14.248 + break; 14.249 + case 2: 14.250 + printf("0%llo", value); 14.251 + break; 14.252 + } 14.253 + break; 14.254 + default: 14.255 + printf("Unknowing 64-bit encoding\n"); 14.256 + } 14.257 + return; 14.258 + } 14.259 + 14.260 + switch(t->encoding) { 14.261 + case DW_ATE_boolean: 14.262 + if(value) 14.263 + printf("true"); 14.264 + else 14.265 + printf("false"); 14.266 + break; 14.267 + case DW_ATE_signed: 14.268 + switch(debuggerRadix) { 14.269 + case 0: 14.270 + printf("%d", value); 14.271 + break; 14.272 + case 1: 14.273 + printf("0x%x", value); 14.274 + break; 14.275 + case 2: 14.276 + printf("0%o", value); 14.277 + break; 14.278 + } 14.279 + break; 14.280 + case DW_ATE_unsigned: 14.281 + case DW_ATE_unsigned_char: 14.282 + switch(debuggerRadix) { 14.283 + case 0: 14.284 + printf("%u", value); 14.285 + break; 14.286 + case 1: 14.287 + printf("0x%x", value); 14.288 + break; 14.289 + case 2: 14.290 + printf("0%o", value); 14.291 + break; 14.292 + } 14.293 + break; 14.294 + default: 14.295 + printf("UNKNOWN BASE %d %08x", t->encoding, value); 14.296 + } 14.297 +} 14.298 + 14.299 +char *debuggerPrintType(Type *t) 14.300 +{ 14.301 + char buffer[1024]; 14.302 + static char buffer2[1024]; 14.303 + 14.304 + if(t->type == TYPE_pointer) { 14.305 + if(t->pointer) 14.306 + strcpy(buffer, debuggerPrintType(t->pointer)); 14.307 + else 14.308 + strcpy(buffer, "void"); 14.309 + sprintf(buffer2, "%s *", buffer); 14.310 + return buffer2; 14.311 + } else if(t->type == TYPE_reference) { 14.312 + strcpy(buffer, debuggerPrintType(t->pointer)); 14.313 + sprintf(buffer2, "%s &", buffer); 14.314 + return buffer2; 14.315 + } 14.316 + return t->name; 14.317 +} 14.318 + 14.319 +void debuggerPrintValueInternal(Function *, Type *, ELFBlock *, int, int, u32); 14.320 +void debuggerPrintValueInternal(Function *f, Type *t, 14.321 + int bitSize, int bitOffset, 14.322 + u32 objLocation, LocationType type); 14.323 + 14.324 +u32 debuggerGetValue(u32 location, LocationType type) 14.325 +{ 14.326 + switch(type) { 14.327 + case LOCATION_memory: 14.328 + return debuggerReadMemory(location); 14.329 + case LOCATION_register: 14.330 + return reg[location].I; 14.331 + case LOCATION_value: 14.332 + return location; 14.333 + } 14.334 + return 0; 14.335 +} 14.336 + 14.337 +void debuggerPrintPointer(Type *t, u32 value) 14.338 +{ 14.339 + printf("(%s)0x%08x", debuggerPrintType(t), value); 14.340 +} 14.341 + 14.342 +void debuggerPrintReference(Type *t, u32 value) 14.343 +{ 14.344 + printf("(%s)0x%08x", debuggerPrintType(t), value); 14.345 +} 14.346 + 14.347 +void debuggerPrintFunction(Type *t, u32 value) 14.348 +{ 14.349 + printf("(%s)0x%08x", debuggerPrintType(t), value); 14.350 +} 14.351 + 14.352 +void debuggerPrintArray(Type *t, u32 value) 14.353 +{ 14.354 + // todo 14.355 + printf("(%s[])0x%08x", debuggerPrintType(t->array->type), value); 14.356 +} 14.357 + 14.358 +void debuggerPrintMember(Function *f, 14.359 + Member *m, 14.360 + u32 objLocation, 14.361 + u32 location) 14.362 +{ 14.363 + int bitSize = m->bitSize; 14.364 + if(bitSize) { 14.365 + u32 value = 0; 14.366 + int off = m->bitOffset; 14.367 + int size = m->byteSize; 14.368 + u32 v = 0; 14.369 + if(size == 1) 14.370 + v = debuggerReadByte(location); 14.371 + else if(size == 2) 14.372 + v = debuggerReadHalfWord(location); 14.373 + else if(size == 4) 14.374 + v = debuggerReadMemory(location); 14.375 + 14.376 + while(bitSize) { 14.377 + int top = size*8 - off; 14.378 + int bot = top - bitSize; 14.379 + top--; 14.380 + if(bot >= 0) { 14.381 + value = (v >> (size*8 - bitSize - off)) & ((1 << bitSize)-1); 14.382 + bitSize = 0; 14.383 + } else { 14.384 + value |= (v & ((1 << top)-1)) << (bitSize - top); 14.385 + bitSize -= (top+1); 14.386 + location -= size; 14.387 + off = 0; 14.388 + if(size == 1) 14.389 + v = debuggerReadByte(location); 14.390 + else if(size == 2) 14.391 + v = debuggerReadHalfWord(location); 14.392 + else 14.393 + v = debuggerReadMemory(location); 14.394 + } 14.395 + } 14.396 + debuggerPrintBaseType(m->type, value, location, LOCATION_memory, 14.397 + bitSize, 0); 14.398 + } else { 14.399 + debuggerPrintValueInternal(f, m->type, m->location, m->bitSize, 14.400 + m->bitOffset, objLocation); 14.401 + } 14.402 +} 14.403 + 14.404 +void debuggerPrintStructure(Function *f, Type *t, u32 objLocation) 14.405 +{ 14.406 + printf("{"); 14.407 + int count = t->structure->memberCount; 14.408 + int i = 0; 14.409 + while(i < count) { 14.410 + Member *m = &t->structure->members[i]; 14.411 + printf("%s=", m->name); 14.412 + LocationType type; 14.413 + u32 location = elfDecodeLocation(f, m->location, &type, objLocation); 14.414 + debuggerPrintMember(f, m, objLocation, location); 14.415 + i++; 14.416 + if(i < count) 14.417 + printf(","); 14.418 + } 14.419 + printf("}"); 14.420 +} 14.421 + 14.422 +void debuggerPrintUnion(Function *f, Type *t, u32 objLocation) 14.423 +{ 14.424 + // todo 14.425 + printf("{"); 14.426 + int count = t->structure->memberCount; 14.427 + int i = 0; 14.428 + while(i < count) { 14.429 + Member *m = &t->structure->members[i]; 14.430 + printf("%s=", m->name); 14.431 + debuggerPrintMember(f, m, objLocation, 0); 14.432 + i++; 14.433 + if(i < count) 14.434 + printf(","); 14.435 + } 14.436 + printf("}"); 14.437 +} 14.438 + 14.439 +void debuggerPrintEnum(Type *t, u32 value) 14.440 +{ 14.441 + int i; 14.442 + for(i = 0; i < t->enumeration->count; i++) { 14.443 + EnumMember *m = (EnumMember *)&t->enumeration->members[i]; 14.444 + if(value == m->value) { 14.445 + puts(m->name); 14.446 + return; 14.447 + } 14.448 + } 14.449 + printf("(UNKNOWN VALUE) %d", value); 14.450 +} 14.451 + 14.452 +void debuggerPrintValueInternal(Function *f, Type *t, 14.453 + int bitSize, int bitOffset, 14.454 + u32 objLocation, LocationType type) 14.455 +{ 14.456 + u32 value = debuggerGetValue(objLocation, type); 14.457 + if(!t) { 14.458 + printf("void"); 14.459 + return; 14.460 + } 14.461 + switch(t->type) { 14.462 + case TYPE_base: 14.463 + debuggerPrintBaseType(t, value, objLocation, type, bitSize, bitOffset); 14.464 + break; 14.465 + case TYPE_pointer: 14.466 + debuggerPrintPointer(t, value); 14.467 + break; 14.468 + case TYPE_reference: 14.469 + debuggerPrintReference(t, value); 14.470 + break; 14.471 + case TYPE_function: 14.472 + debuggerPrintFunction(t, value); 14.473 + break; 14.474 + case TYPE_array: 14.475 + debuggerPrintArray(t, objLocation); 14.476 + break; 14.477 + case TYPE_struct: 14.478 + debuggerPrintStructure(f, t, objLocation); 14.479 + break; 14.480 + case TYPE_union: 14.481 + debuggerPrintUnion(f, t, objLocation); 14.482 + break; 14.483 + case TYPE_enum: 14.484 + debuggerPrintEnum(t, value); 14.485 + break; 14.486 + default: 14.487 + printf("%08x", value); 14.488 + break; 14.489 + } 14.490 +} 14.491 + 14.492 +void debuggerPrintValueInternal(Function *f, Type *t, ELFBlock *loc, 14.493 + int bitSize, int bitOffset, u32 objLocation) 14.494 +{ 14.495 + LocationType type; 14.496 + u32 location; 14.497 + if(loc) { 14.498 + if(objLocation) 14.499 + location = elfDecodeLocation(f, loc, &type, objLocation); 14.500 + else 14.501 + location = elfDecodeLocation(f, loc,&type); 14.502 + } else { 14.503 + location = objLocation; 14.504 + type = LOCATION_memory; 14.505 + } 14.506 + 14.507 + debuggerPrintValueInternal(f, t, bitSize, bitOffset, location, type); 14.508 +} 14.509 + 14.510 +void debuggerPrintValue(Function *f, Object *o) 14.511 +{ 14.512 + debuggerPrintValueInternal(f, o->type, o->location, 0, 0, 0); 14.513 + 14.514 + printf("\n"); 14.515 +} 14.516 + 14.517 +void debuggerSymbols(int argc, char **argv) 14.518 +{ 14.519 + int i = 0; 14.520 + u32 value; 14.521 + u32 size; 14.522 + int type; 14.523 + bool match = false; 14.524 + int matchSize = 0; 14.525 + char *matchStr = NULL; 14.526 + 14.527 + if(argc == 2) { 14.528 + match = true; 14.529 + matchSize = strlen(argv[1]); 14.530 + matchStr = argv[1]; 14.531 + } 14.532 + printf("Symbol Value Size Type \n"); 14.533 + printf("-------------------- ------- -------- -------\n"); 14.534 + char *s = NULL; 14.535 + while((s = elfGetSymbol(i, &value, &size, &type))) { 14.536 + if(*s) { 14.537 + if(match) { 14.538 + if(strncmp(s, matchStr, matchSize) != 0) { 14.539 + i++; 14.540 + continue; 14.541 + } 14.542 + } 14.543 + const char *ts = "?"; 14.544 + switch(type) { 14.545 + case 2: 14.546 + ts = "ARM"; 14.547 + break; 14.548 + case 0x0d: 14.549 + ts = "THUMB"; 14.550 + break; 14.551 + case 1: 14.552 + ts = "DATA"; 14.553 + break; 14.554 + } 14.555 + printf("%-20s %08x %08x %-7s\n", 14.556 + s, value, size, ts); 14.557 + } 14.558 + i++; 14.559 + } 14.560 +} 14.561 + 14.562 +void debuggerSetRadix(int argc, char **argv) 14.563 +{ 14.564 + if(argc != 2) 14.565 + debuggerUsage(argv[0]); 14.566 + else { 14.567 + int r = atoi(argv[1]); 14.568 + 14.569 + bool error = false; 14.570 + switch(r) { 14.571 + case 10: 14.572 + debuggerRadix = 0; 14.573 + break; 14.574 + case 8: 14.575 + debuggerRadix = 2; 14.576 + break; 14.577 + case 16: 14.578 + debuggerRadix = 1; 14.579 + break; 14.580 + default: 14.581 + error = true; 14.582 + printf("Unknown radix %d. Valid values are 8, 10 and 16.\n", r); 14.583 + break; 14.584 + } 14.585 + if(!error) 14.586 + printf("Radix set to %d\n", r); 14.587 + } 14.588 +} 14.589 + 14.590 +void debuggerPrint(int argc, char **argv) 14.591 +{ 14.592 + if(argc != 2 && argc != 3) { 14.593 + debuggerUsage(argv[0]); 14.594 + } else { 14.595 + u32 pc = armNextPC; 14.596 + Function *f = NULL; 14.597 + CompileUnit *u = NULL; 14.598 + 14.599 + elfGetCurrentFunction(pc, 14.600 + &f, &u); 14.601 + 14.602 + int oldRadix = debuggerRadix; 14.603 + if(argc == 3) { 14.604 + if(argv[1][0] == '/') { 14.605 + if(argv[1][1] == 'x') 14.606 + debuggerRadix = 1; 14.607 + else if(argv[1][1] == 'o') 14.608 + debuggerRadix = 2; 14.609 + else if(argv[1][1] == 'd') 14.610 + debuggerRadix = 0; 14.611 + else { 14.612 + printf("Unknown format %c\n", argv[1][1]); 14.613 + return; 14.614 + } 14.615 + } else { 14.616 + printf("Unknown option %s\n", argv[1]); 14.617 + return; 14.618 + } 14.619 + } 14.620 + 14.621 + char *s = argc == 2 ? argv[1] : argv[2]; 14.622 + 14.623 + extern char *exprString; 14.624 + extern int exprCol; 14.625 + extern int yyparse(); 14.626 + exprString = s; 14.627 + exprCol = 0; 14.628 + if(!yyparse()) { 14.629 + extern Node *result; 14.630 + if(result->resolve(result, f, u)) { 14.631 + if(result->member) 14.632 + debuggerPrintMember(f, 14.633 + result->member, 14.634 + result->objLocation, 14.635 + result->location); 14.636 + else 14.637 + debuggerPrintValueInternal(f, result->type, 0, 0, 14.638 + result->location, 14.639 + result->locType); 14.640 + printf("\n"); 14.641 + } else { 14.642 + printf("Error resolving expression\n"); 14.643 + } 14.644 + } else { 14.645 + printf("Error parsing expression:\n"); 14.646 + printf("%s\n", s); 14.647 + exprCol--; 14.648 + for(int i = 0; i < exprCol; i++) 14.649 + printf(" "); 14.650 + printf("^\n"); 14.651 + } 14.652 + extern void exprCleanBuffer(); 14.653 + exprCleanBuffer(); 14.654 + exprNodeCleanUp(); 14.655 + debuggerRadix = oldRadix; 14.656 + } 14.657 +} 14.658 + 14.659 +void debuggerHelp(int n, char **args) 14.660 +{ 14.661 + if(n == 2) { 14.662 + debuggerUsage(args[1]); 14.663 + } else { 14.664 + for(int i = 0; ; i++) { 14.665 + if(debuggerCommands[i].name) { 14.666 + printf("%s\t%s\n", debuggerCommands[i].name, debuggerCommands[i].help); 14.667 + } else 14.668 + break; 14.669 + } 14.670 + } 14.671 +} 14.672 + 14.673 +void debuggerDebug(int n, char **args) 14.674 +{ 14.675 + if(n == 2) { 14.676 + int v = 0; 14.677 + sscanf(args[1], "%d", &v); 14.678 + systemDebug = v; 14.679 + printf("Debug level set to %d\n", systemDebug); 14.680 + } else 14.681 + debuggerUsage("trace"); 14.682 +} 14.683 + 14.684 +void debuggerVerbose(int n, char **args) 14.685 +{ 14.686 + if(n == 2) { 14.687 + int v = 0; 14.688 + sscanf(args[1], "%d", &v); 14.689 + systemVerbose = v; 14.690 + printf("Verbose level set to %d\n", systemVerbose); 14.691 + } else 14.692 + debuggerUsage("verbose"); 14.693 +} 14.694 + 14.695 +void debuggerWhere(int n, char **args) 14.696 +{ 14.697 + void elfPrintCallChain(u32); 14.698 + elfPrintCallChain(armNextPC); 14.699 +} 14.700 + 14.701 +void debuggerLocals(int n, char **args) 14.702 +{ 14.703 + Function *f = NULL; 14.704 + CompileUnit *u = NULL; 14.705 + u32 pc = armNextPC; 14.706 + if(elfGetCurrentFunction(pc, 14.707 + &f, &u)) { 14.708 + Object *o = f->parameters; 14.709 + while(o) { 14.710 + printf("%s=", o->name); 14.711 + debuggerPrintValue(f, o); 14.712 + o = o->next; 14.713 + } 14.714 + 14.715 + o = f->variables; 14.716 + while(o) { 14.717 + bool visible = o->startScope ? pc>=o->startScope : true; 14.718 + if(visible) 14.719 + visible = o->endScope ? pc < o->endScope : true; 14.720 + if(visible) { 14.721 + printf("%s=", o->name); 14.722 + debuggerPrintValue(f, o); 14.723 + } 14.724 + o = o->next; 14.725 + } 14.726 + } else { 14.727 + printf("No information for current address\n"); 14.728 + } 14.729 +} 14.730 + 14.731 +void debuggerNext(int n, char **args) 14.732 +{ 14.733 + int count = 1; 14.734 + if(n == 2) { 14.735 + sscanf(args[1], "%d", &count); 14.736 + } 14.737 + for(int i = 0; i < count; i++) { 14.738 + if(debuggerAtBreakpoint) { 14.739 + debuggerContinueAfterBreakpoint(); 14.740 + debuggerEnableBreakpoints(false); 14.741 + } else 14.742 + theEmulator.emuMain(1); 14.743 + } 14.744 + debuggerDisableBreakpoints(); 14.745 + Function *f = NULL; 14.746 + CompileUnit *u = NULL; 14.747 + u32 a = armNextPC; 14.748 + if(elfGetCurrentFunction(a, &f, &u)) { 14.749 + char *file; 14.750 + int line = elfFindLine(u, f, a, &file); 14.751 + 14.752 + printf("File %s, function %s, line %d\n", file, f->name, 14.753 + line); 14.754 + } 14.755 + debuggerRegisters(0, NULL); 14.756 +} 14.757 + 14.758 +void debuggerContinue(int n, char **args) 14.759 +{ 14.760 + if(debuggerAtBreakpoint) 14.761 + debuggerContinueAfterBreakpoint(); 14.762 + debuggerEnableBreakpoints(false); 14.763 + debugger = false; 14.764 +} 14.765 + 14.766 +void debuggerSignal(int sig,int number) 14.767 +{ 14.768 + switch(sig) { 14.769 + case 4: 14.770 + { 14.771 + printf("Illegal instruction at %08x\n", armNextPC); 14.772 + debugger = true; 14.773 + } 14.774 + break; 14.775 + case 5: 14.776 + { 14.777 + printf("Breakpoint %d reached\n", number); 14.778 + debugger = true; 14.779 + debuggerAtBreakpoint = true; 14.780 + debuggerBreakpointNumber = number; 14.781 + debuggerDisableBreakpoints(); 14.782 + 14.783 + Function *f = NULL; 14.784 + CompileUnit *u = NULL; 14.785 + 14.786 + if(elfGetCurrentFunction(armNextPC, &f, &u)) { 14.787 + char *file; 14.788 + int line = elfFindLine(u,f,armNextPC,&file); 14.789 + printf("File %s, function %s, line %d\n", file, f->name, 14.790 + line); 14.791 + } 14.792 + } 14.793 + break; 14.794 + default: 14.795 + printf("Unknown signal %d\n", sig); 14.796 + break; 14.797 + } 14.798 +} 14.799 + 14.800 +void debuggerBreakList(int, char **) 14.801 +{ 14.802 + printf("Num Address Type Symbol\n"); 14.803 + printf("--- -------- ----- ------\n"); 14.804 + for(int i = 0; i < debuggerNumOfBreakpoints; i++) { 14.805 + printf("%3d %08x %s %s\n",i, debuggerBreakpointList[i].address, 14.806 + debuggerBreakpointList[i].size ? "ARM" : "THUMB", 14.807 + elfGetAddressSymbol(debuggerBreakpointList[i].address)); 14.808 + } 14.809 +} 14.810 + 14.811 +void debuggerBreakDelete(int n, char **args) 14.812 +{ 14.813 + if(n == 2) { 14.814 + int n = 0; 14.815 + sscanf(args[1], "%d", &n); 14.816 + printf("Deleting breakpoint %d (%d)\n", n, debuggerNumOfBreakpoints); 14.817 + if(n >= 0 && n < debuggerNumOfBreakpoints) { 14.818 + n++; 14.819 + if(n < debuggerNumOfBreakpoints) { 14.820 + for(int i = n; i < debuggerNumOfBreakpoints; i++) { 14.821 + debuggerBreakpointList[i-1].address = 14.822 + debuggerBreakpointList[i].address; 14.823 + debuggerBreakpointList[i-1].value = 14.824 + debuggerBreakpointList[i].value; 14.825 + debuggerBreakpointList[i-1].size = 14.826 + debuggerBreakpointList[i].size; 14.827 + } 14.828 + } 14.829 + debuggerNumOfBreakpoints--; 14.830 + } 14.831 + } else 14.832 + debuggerUsage("bd"); 14.833 +} 14.834 + 14.835 +void debuggerBreak(int n, char **args) 14.836 +{ 14.837 + if(n == 2) { 14.838 + u32 address = 0; 14.839 + u32 value = 0; 14.840 + int type = 0; 14.841 + char *s = args[1]; 14.842 + char c = *s; 14.843 + if(strchr(s, ':')) { 14.844 + char *name = s; 14.845 + char *l = strchr(s, ':'); 14.846 + *l++ = 0; 14.847 + int line = atoi(l); 14.848 + 14.849 + u32 addr; 14.850 + Function *f; 14.851 + CompileUnit *u; 14.852 + 14.853 + if(elfFindLineInModule(&addr, name, line)) { 14.854 + if(elfGetCurrentFunction(addr, &f, &u)) { 14.855 + u32 addr2; 14.856 + if(elfGetSymbolAddress(f->name, &addr2, &value, &type)) { 14.857 + address = addr; 14.858 + } else { 14.859 + printf("Unable to get function symbol data\n"); 14.860 + return; 14.861 + } 14.862 + } else { 14.863 + printf("Unable to find function for address\n"); 14.864 + return; 14.865 + } 14.866 + } else { 14.867 + printf("Unable to find module or line\n"); 14.868 + return; 14.869 + } 14.870 + } else if(c >= '0' && c <= '9') { 14.871 + int line = atoi(s); 14.872 + Function *f; 14.873 + CompileUnit *u; 14.874 + u32 addr; 14.875 + 14.876 + if(elfGetCurrentFunction(armNextPC, &f, &u)) { 14.877 + if(elfFindLineInUnit(&addr, u, line)) { 14.878 + if(elfGetCurrentFunction(addr, &f, &u)) { 14.879 + u32 addr2; 14.880 + if(elfGetSymbolAddress(f->name, &addr2, &value, &type)) { 14.881 + address = addr; 14.882 + } else { 14.883 + printf("Unable to get function symbol data\n"); 14.884 + return; 14.885 + } 14.886 + } else { 14.887 + printf("Unable to find function for address\n"); 14.888 + return; 14.889 + } 14.890 + } else { 14.891 + printf("Unable to find line\n"); 14.892 + return; 14.893 + } 14.894 + } else { 14.895 + printf("Cannot find current function\n"); 14.896 + return; 14.897 + } 14.898 + } else { 14.899 + if(!elfGetSymbolAddress(s, &address, &value, &type)) { 14.900 + printf("Function %s not found\n", args[1]); 14.901 + return; 14.902 + } 14.903 + } 14.904 + if(type == 0x02 || type == 0x0d) { 14.905 + int i = debuggerNumOfBreakpoints; 14.906 + int size = 0; 14.907 + if(type == 2) 14.908 + size = 1; 14.909 + debuggerBreakpointList[i].address = address; 14.910 + debuggerBreakpointList[i].value = type == 0x02 ? 14.911 + debuggerReadMemory(address) : debuggerReadHalfWord(address); 14.912 + debuggerBreakpointList[i].size = size; 14.913 + // debuggerApplyBreakpoint(address, i, size); 14.914 + debuggerNumOfBreakpoints++; 14.915 + if(size) 14.916 + printf("Added ARM breakpoint at %08x\n", address); 14.917 + else 14.918 + printf("Added THUMB breakpoint at %08x\n", address); 14.919 + } else { 14.920 + printf("%s is not a function symbol\n", args[1]); 14.921 + } 14.922 + } else 14.923 + debuggerUsage("break"); 14.924 +} 14.925 + 14.926 +void debuggerBreakThumb(int n, char **args) 14.927 +{ 14.928 + if(n == 2) { 14.929 + u32 address = 0; 14.930 + sscanf(args[1],"%x", &address); 14.931 + int i = debuggerNumOfBreakpoints; 14.932 + debuggerBreakpointList[i].address = address; 14.933 + debuggerBreakpointList[i].value = debuggerReadHalfWord(address); 14.934 + debuggerBreakpointList[i].size = 0; 14.935 + // debuggerApplyBreakpoint(address, i, 0); 14.936 + debuggerNumOfBreakpoints++; 14.937 + printf("Added THUMB breakpoint at %08x\n", address); 14.938 + } else 14.939 + debuggerUsage("bt"); 14.940 +} 14.941 + 14.942 +void debuggerBreakArm(int n, char **args) 14.943 +{ 14.944 + if(n == 2) { 14.945 + u32 address = 0; 14.946 + sscanf(args[1],"%x", &address); 14.947 + int i = debuggerNumOfBreakpoints; 14.948 + debuggerBreakpointList[i].address = address; 14.949 + debuggerBreakpointList[i].value = debuggerReadMemory(address); 14.950 + debuggerBreakpointList[i].size = 1; 14.951 + // debuggerApplyBreakpoint(address, i, 1); 14.952 + debuggerNumOfBreakpoints++; 14.953 + printf("Added ARM breakpoint at %08x\n", address); 14.954 + } else 14.955 + debuggerUsage("ba"); 14.956 +} 14.957 + 14.958 +void debuggerBreakOnWrite(u32 *mem, u32 oldvalue, u32 value, int size) 14.959 +{ 14.960 + u32 address = 0; 14.961 + if(mem >= (u32*)&workRAM[0] && mem <= (u32*)&workRAM[0x3ffff]) 14.962 + address = 0x2000000 + ((u64)mem - (u64)&workRAM[0]); 14.963 + else 14.964 + address = 0x3000000 + ((u64)mem - (u64)&internalRAM[0]); 14.965 + 14.966 + if(size == 2) 14.967 + printf("Breakpoint (on write) address %08x old:%08x new:%08x\n", 14.968 + address, oldvalue, value); 14.969 + else if(size == 1) 14.970 + printf("Breakpoint (on write) address %08x old:%04x new:%04x\n", 14.971 + address, (u16)oldvalue,(u16)value); 14.972 + else 14.973 + printf("Breakpoint (on write) address %08x old:%02x new:%02x\n", 14.974 + address, (u8)oldvalue, (u8)value); 14.975 + debugger = true; 14.976 +} 14.977 + 14.978 +void debuggerBreakWriteClear(int n, char **args) 14.979 +{ 14.980 + memset(freezeWorkRAM, false, 0x40000); 14.981 + memset(freezeInternalRAM, false, 0x8000); 14.982 + printf("Cleared all break on write\n"); 14.983 +} 14.984 + 14.985 +void debuggerBreakWrite(int n, char **args) 14.986 +{ 14.987 + if(n == 3) { 14.988 + if(cheatsNumber != 0) { 14.989 + printf("Cheats are enabled. Cannot continue.\n"); 14.990 + return; 14.991 + } 14.992 + u32 address = 0; 14.993 + sscanf(args[1], "%x", &address); 14.994 + int n = 0; 14.995 + sscanf(args[2], "%d", &n); 14.996 + 14.997 + if(address < 0x2000000 || address > 0x3007fff) { 14.998 + printf("Invalid address: %08x\n", address); 14.999 + return; 14.1000 + } 14.1001 + 14.1002 + if(address > 0x203ffff && address < 0x3000000) { 14.1003 + printf("Invalid address: %08x\n", address); 14.1004 + return; 14.1005 + } 14.1006 + 14.1007 + u32 final = address + n; 14.1008 + 14.1009 + if(address < 0x2040000 && final > 0x2040000) { 14.1010 + printf("Invalid byte count: %d\n", n); 14.1011 + return; 14.1012 + } else if(address < 0x3008000 && final > 0x3008000) { 14.1013 + printf("Invalid byte count: %d\n", n); 14.1014 + return; 14.1015 + } 14.1016 + printf("Added break on write at %08x for %d bytes\n", address, n); 14.1017 + for(int i = 0; i < n; i++) { 14.1018 + if((address >> 24) == 2) 14.1019 + freezeWorkRAM[address & 0x3ffff] = true; 14.1020 + else 14.1021 + freezeInternalRAM[address & 0x7fff] = true; 14.1022 + address++; 14.1023 + } 14.1024 + } else 14.1025 + debuggerUsage("bpw"); 14.1026 +} 14.1027 + 14.1028 +void debuggerDisassembleArm(int n, char **args) 14.1029 +{ 14.1030 + char buffer[80]; 14.1031 + u32 pc = reg[15].I; 14.1032 + pc -= 4; 14.1033 + int count = 20; 14.1034 + if(n >= 2) { 14.1035 + sscanf(args[1], "%x", &pc); 14.1036 + } 14.1037 + if(pc & 3) { 14.1038 + printf("Misaligned address %08x\n", pc); 14.1039 + pc &= 0xfffffffc; 14.1040 + } 14.1041 + if(n >= 3) { 14.1042 + sscanf(args[2], "%d", &count); 14.1043 + } 14.1044 + int i = 0; 14.1045 + int len = 0; 14.1046 + char format[30]; 14.1047 + for(i = 0; i < count; i++) { 14.1048 + int l = strlen(elfGetAddressSymbol(pc+4*i)); 14.1049 + if(l > len) 14.1050 + len = l; 14.1051 + } 14.1052 + sprintf(format, "%%08x %%-%ds %%s\n", len); 14.1053 + for(i = 0; i < count; i++) { 14.1054 + u32 addr = pc; 14.1055 + pc += disArm(pc, buffer, 2); 14.1056 + printf(format, addr, elfGetAddressSymbol(addr), buffer); 14.1057 + } 14.1058 +} 14.1059 + 14.1060 +void debuggerDisassembleThumb(int n, char **args) 14.1061 +{ 14.1062 + char buffer[80]; 14.1063 + u32 pc = reg[15].I; 14.1064 + pc -= 2; 14.1065 + int count = 20; 14.1066 + if(n >= 2) { 14.1067 + sscanf(args[1], "%x", &pc); 14.1068 + } 14.1069 + if(pc & 1) { 14.1070 + printf("Misaligned address %08x\n", pc); 14.1071 + pc &= 0xfffffffe; 14.1072 + } 14.1073 + if(n >= 3) { 14.1074 + sscanf(args[2], "%d", &count); 14.1075 + } 14.1076 + 14.1077 + int i = 0; 14.1078 + int len = 0; 14.1079 + char format[30]; 14.1080 + for(i = 0; i < count; i++) { 14.1081 + int l = strlen(elfGetAddressSymbol(pc+2*i)); 14.1082 + if(l > len) 14.1083 + len = l; 14.1084 + } 14.1085 + sprintf(format, "%%08x %%-%ds %%s\n", len); 14.1086 + 14.1087 + for(i = 0; i < count; i++) { 14.1088 + u32 addr = pc; 14.1089 + pc += disThumb(pc, buffer, 2); 14.1090 + printf(format, addr, elfGetAddressSymbol(addr), buffer); 14.1091 + } 14.1092 +} 14.1093 + 14.1094 +void debuggerDisassemble(int n, char **args) 14.1095 +{ 14.1096 + if(armState) 14.1097 + debuggerDisassembleArm(n, args); 14.1098 + else 14.1099 + debuggerDisassembleThumb(n, args); 14.1100 +} 14.1101 + 14.1102 +void debuggerContinueAfterBreakpoint() 14.1103 +{ 14.1104 + printf("Continuing after breakpoint\n"); 14.1105 + debuggerEnableBreakpoints(true); 14.1106 + theEmulator.emuMain(1); 14.1107 + debuggerAtBreakpoint = false; 14.1108 +} 14.1109 + 14.1110 +void debuggerRegisters(int, char **) 14.1111 +{ 14.1112 + char *command[3]; 14.1113 + char buffer[10]; 14.1114 + 14.1115 + printf("R00=%08x R04=%08x R08=%08x R12=%08x\n", 14.1116 + reg[0].I, reg[4].I, reg[8].I, reg[12].I); 14.1117 + printf("R01=%08x R05=%08x R09=%08x R13=%08x\n", 14.1118 + reg[1].I, reg[5].I, reg[9].I, reg[13].I); 14.1119 + printf("R02=%08x R06=%08x R10=%08x R14=%08x\n", 14.1120 + reg[2].I, reg[6].I, reg[10].I, reg[14].I); 14.1121 + printf("R03=%08x R07=%08x R11=%08x R15=%08x\n", 14.1122 + reg[3].I, reg[7].I, reg[11].I, reg[15].I); 14.1123 + printf("CPSR=%08x (%c%c%c%c%c%c%c Mode: %02x)\n", 14.1124 + reg[16].I, 14.1125 + (N_FLAG ? 'N' : '.'), 14.1126 + (Z_FLAG ? 'Z' : '.'), 14.1127 + (C_FLAG ? 'C' : '.'), 14.1128 + (V_FLAG ? 'V' : '.'), 14.1129 + (armIrqEnable ? '.' : 'I'), 14.1130 + ((!(reg[16].I & 0x40)) ? '.' : 'F'), 14.1131 + (armState ? '.' : 'T'), 14.1132 + armMode); 14.1133 + sprintf(buffer,"%08x", armState ? reg[15].I - 4 : reg[15].I - 2); 14.1134 + command[0]=const_cast<char *>("m"); 14.1135 + command[1]=buffer; 14.1136 + command[2]=const_cast<char *>("1"); 14.1137 + debuggerDisassemble(3, command); 14.1138 +} 14.1139 + 14.1140 +void debuggerIoVideo() 14.1141 +{ 14.1142 + printf("DISPCNT = %04x\n", DISPCNT); 14.1143 + printf("DISPSTAT = %04x\n", DISPSTAT); 14.1144 + printf("VCOUNT = %04x\n", VCOUNT); 14.1145 + printf("BG0CNT = %04x\n", BG0CNT); 14.1146 + printf("BG1CNT = %04x\n", BG1CNT); 14.1147 + printf("BG2CNT = %04x\n", BG2CNT); 14.1148 + printf("BG3CNT = %04x\n", BG3CNT); 14.1149 + printf("WIN0H = %04x\n", WIN0H); 14.1150 + printf("WIN0V = %04x\n", WIN0V); 14.1151 + printf("WIN1H = %04x\n", WIN1H); 14.1152 + printf("WIN1V = %04x\n", WIN1V); 14.1153 + printf("WININ = %04x\n", WININ); 14.1154 + printf("WINOUT = %04x\n", WINOUT); 14.1155 + printf("MOSAIC = %04x\n", MOSAIC); 14.1156 + printf("BLDMOD = %04x\n", BLDMOD); 14.1157 + printf("COLEV = %04x\n", COLEV); 14.1158 + printf("COLY = %04x\n", COLY); 14.1159 +} 14.1160 + 14.1161 +void debuggerIoVideo2() 14.1162 +{ 14.1163 + printf("BG0HOFS = %04x\n", BG0HOFS); 14.1164 + printf("BG0VOFS = %04x\n", BG0VOFS); 14.1165 + printf("BG1HOFS = %04x\n", BG1HOFS); 14.1166 + printf("BG1VOFS = %04x\n", BG1VOFS); 14.1167 + printf("BG2HOFS = %04x\n", BG2HOFS); 14.1168 + printf("BG2VOFS = %04x\n", BG2VOFS); 14.1169 + printf("BG3HOFS = %04x\n", BG3HOFS); 14.1170 + printf("BG3VOFS = %04x\n", BG3VOFS); 14.1171 + printf("BG2PA = %04x\n", BG2PA); 14.1172 + printf("BG2PB = %04x\n", BG2PB); 14.1173 + printf("BG2PC = %04x\n", BG2PC); 14.1174 + printf("BG2PD = %04x\n", BG2PD); 14.1175 + printf("BG2X = %08x\n", (BG2X_H<<16)|BG2X_L); 14.1176 + printf("BG2Y = %08x\n", (BG2Y_H<<16)|BG2Y_L); 14.1177 + printf("BG3PA = %04x\n", BG3PA); 14.1178 + printf("BG3PB = %04x\n", BG3PB); 14.1179 + printf("BG3PC = %04x\n", BG3PC); 14.1180 + printf("BG3PD = %04x\n", BG3PD); 14.1181 + printf("BG3X = %08x\n", (BG3X_H<<16)|BG3X_L); 14.1182 + printf("BG3Y = %08x\n", (BG3Y_H<<16)|BG3Y_L); 14.1183 +} 14.1184 + 14.1185 +void debuggerIoDMA() 14.1186 +{ 14.1187 + printf("DM0SAD = %08x\n", (DM0SAD_H<<16)|DM0SAD_L); 14.1188 + printf("DM0DAD = %08x\n", (DM0DAD_H<<16)|DM0DAD_L); 14.1189 + printf("DM0CNT = %08x\n", (DM0CNT_H<<16)|DM0CNT_L); 14.1190 + printf("DM1SAD = %08x\n", (DM1SAD_H<<16)|DM1SAD_L); 14.1191 + printf("DM1DAD = %08x\n", (DM1DAD_H<<16)|DM1DAD_L); 14.1192 + printf("DM1CNT = %08x\n", (DM1CNT_H<<16)|DM1CNT_L); 14.1193 + printf("DM2SAD = %08x\n", (DM2SAD_H<<16)|DM2SAD_L); 14.1194 + printf("DM2DAD = %08x\n", (DM2DAD_H<<16)|DM2DAD_L); 14.1195 + printf("DM2CNT = %08x\n", (DM2CNT_H<<16)|DM2CNT_L); 14.1196 + printf("DM3SAD = %08x\n", (DM3SAD_H<<16)|DM3SAD_L); 14.1197 + printf("DM3DAD = %08x\n", (DM3DAD_H<<16)|DM3DAD_L); 14.1198 + printf("DM3CNT = %08x\n", (DM3CNT_H<<16)|DM3CNT_L); 14.1199 +} 14.1200 + 14.1201 +void debuggerIoTimer() 14.1202 +{ 14.1203 + printf("TM0D = %04x\n", TM0D); 14.1204 + printf("TM0CNT = %04x\n", TM0CNT); 14.1205 + printf("TM1D = %04x\n", TM1D); 14.1206 + printf("TM1CNT = %04x\n", TM1CNT); 14.1207 + printf("TM2D = %04x\n", TM2D); 14.1208 + printf("TM2CNT = %04x\n", TM2CNT); 14.1209 + printf("TM3D = %04x\n", TM3D); 14.1210 + printf("TM3CNT = %04x\n", TM3CNT); 14.1211 +} 14.1212 + 14.1213 +void debuggerIoMisc() 14.1214 +{ 14.1215 + printf("P1 = %04x\n", P1); 14.1216 + printf("IE = %04x\n", IE); 14.1217 + printf("IF = %04x\n", IF); 14.1218 + printf("IME = %04x\n", IME); 14.1219 +} 14.1220 + 14.1221 +void debuggerIo(int n, char **args) 14.1222 +{ 14.1223 + if(n == 1) { 14.1224 + debuggerIoVideo(); 14.1225 + return; 14.1226 + } 14.1227 + if(!strcmp(args[1], "video")) 14.1228 + debuggerIoVideo(); 14.1229 + else if(!strcmp(args[1], "video2")) 14.1230 + debuggerIoVideo2(); 14.1231 + else if(!strcmp(args[1], "dma")) 14.1232 + debuggerIoDMA(); 14.1233 + else if(!strcmp(args[1], "timer")) 14.1234 + debuggerIoTimer(); 14.1235 + else if(!strcmp(args[1], "misc")) 14.1236 + debuggerIoMisc(); 14.1237 + else printf("Unrecognized option %s\n", args[1]); 14.1238 +} 14.1239 + 14.1240 +void debuggerEditByte(int n, char **args) 14.1241 +{ 14.1242 + if(n == 3) { 14.1243 + u32 address; 14.1244 + u32 byte; 14.1245 + sscanf(args[1], "%x", &address); 14.1246 + sscanf(args[2], "%x", &byte); 14.1247 + debuggerWriteByte(address, (u8)byte); 14.1248 + } else 14.1249 + debuggerUsage("eb"); 14.1250 +} 14.1251 + 14.1252 +void debuggerEditHalfWord(int n, char **args) 14.1253 +{ 14.1254 + if(n == 3) { 14.1255 + u32 address; 14.1256 + u32 byte; 14.1257 + sscanf(args[1], "%x", &address); 14.1258 + if(address & 1) { 14.1259 + printf("Error: address must be half-word aligned\n"); 14.1260 + return; 14.1261 + } 14.1262 + sscanf(args[2], "%x", &byte); 14.1263 + debuggerWriteHalfWord(address, (u16)byte); 14.1264 + } else 14.1265 + debuggerUsage("eh"); 14.1266 +} 14.1267 + 14.1268 +void debuggerEdit(int n, char **args) 14.1269 +{ 14.1270 + if(n == 3) { 14.1271 + u32 address; 14.1272 + u32 byte; 14.1273 + sscanf(args[1], "%x", &address); 14.1274 + if(address & 3) { 14.1275 + printf("Error: address must be word aligned\n"); 14.1276 + return; 14.1277 + } 14.1278 + sscanf(args[2], "%x", &byte); 14.1279 + debuggerWriteMemory(address, (u32)byte); 14.1280 + } else 14.1281 + debuggerUsage("ew"); 14.1282 +} 14.1283 + 14.1284 + 14.1285 +#define ASCII(c) (c) < 32 ? '.' : (c) > 127 ? '.' : (c) 14.1286 + 14.1287 +void debuggerMemoryByte(int n, char **args) 14.1288 +{ 14.1289 + if(n == 2) { 14.1290 + u32 addr = 0; 14.1291 + sscanf(args[1], "%x", &addr); 14.1292 + for(int ii = 0; ii < 16; ii++) { 14.1293 + int a = debuggerReadByte(addr); 14.1294 + int b = debuggerReadByte(addr+1); 14.1295 + int c = debuggerReadByte(addr+2); 14.1296 + int d = debuggerReadByte(addr+3); 14.1297 + int e = debuggerReadByte(addr+4); 14.1298 + int f = debuggerReadByte(addr+5); 14.1299 + int g = debuggerReadByte(addr+6); 14.1300 + int h = debuggerReadByte(addr+7); 14.1301 + int i = debuggerReadByte(addr+8); 14.1302 + int j = debuggerReadByte(addr+9); 14.1303 + int k = debuggerReadByte(addr+10); 14.1304 + int l = debuggerReadByte(addr+11); 14.1305 + int m = debuggerReadByte(addr+12); 14.1306 + int n = debuggerReadByte(addr+13); 14.1307 + int o = debuggerReadByte(addr+14); 14.1308 + int p = debuggerReadByte(addr+15); 14.1309 + 14.1310 + printf("%08x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", 14.1311 + addr,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p, 14.1312 + ASCII(a),ASCII(b),ASCII(c),ASCII(d), 14.1313 + ASCII(e),ASCII(f),ASCII(g),ASCII(h), 14.1314 + ASCII(i),ASCII(j),ASCII(k),ASCII(l), 14.1315 + ASCII(m),ASCII(n),ASCII(o),ASCII(p)); 14.1316 + addr += 16; 14.1317 + } 14.1318 + } else 14.1319 + debuggerUsage("mb"); 14.1320 +} 14.1321 + 14.1322 +void debuggerMemoryHalfWord(int n, char **args) 14.1323 +{ 14.1324 + if(n == 2) { 14.1325 + u32 addr = 0; 14.1326 + sscanf(args[1], "%x", &addr); 14.1327 + addr = addr & 0xfffffffe; 14.1328 + for(int ii = 0; ii < 16; ii++) { 14.1329 + int a = debuggerReadByte(addr); 14.1330 + int b = debuggerReadByte(addr+1); 14.1331 + int c = debuggerReadByte(addr+2); 14.1332 + int d = debuggerReadByte(addr+3); 14.1333 + int e = debuggerReadByte(addr+4); 14.1334 + int f = debuggerReadByte(addr+5); 14.1335 + int g = debuggerReadByte(addr+6); 14.1336 + int h = debuggerReadByte(addr+7); 14.1337 + int i = debuggerReadByte(addr+8); 14.1338 + int j = debuggerReadByte(addr+9); 14.1339 + int k = debuggerReadByte(addr+10); 14.1340 + int l = debuggerReadByte(addr+11); 14.1341 + int m = debuggerReadByte(addr+12); 14.1342 + int n = debuggerReadByte(addr+13); 14.1343 + int o = debuggerReadByte(addr+14); 14.1344 + int p = debuggerReadByte(addr+15); 14.1345 + 14.1346 + printf("%08x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", 14.1347 + addr,b,a,d,c,f,e,h,g,j,i,l,k,n,m,p,o, 14.1348 + ASCII(a),ASCII(b),ASCII(c),ASCII(d), 14.1349 + ASCII(e),ASCII(f),ASCII(g),ASCII(h), 14.1350 + ASCII(i),ASCII(j),ASCII(k),ASCII(l), 14.1351 + ASCII(m),ASCII(n),ASCII(o),ASCII(p)); 14.1352 + addr += 16; 14.1353 + } 14.1354 + } else 14.1355 + debuggerUsage("mh"); 14.1356 +} 14.1357 + 14.1358 +void debuggerMemory(int n, char **args) 14.1359 +{ 14.1360 + if(n == 2) { 14.1361 + u32 addr = 0; 14.1362 + sscanf(args[1], "%x", &addr); 14.1363 + addr = addr & 0xfffffffc; 14.1364 + for(int ii = 0; ii < 16; ii++) { 14.1365 + int a = debuggerReadByte(addr); 14.1366 + int b = debuggerReadByte(addr+1); 14.1367 + int c = debuggerReadByte(addr+2); 14.1368 + int d = debuggerReadByte(addr+3); 14.1369 + 14.1370 + int e = debuggerReadByte(addr+4); 14.1371 + int f = debuggerReadByte(addr+5); 14.1372 + int g = debuggerReadByte(addr+6); 14.1373 + int h = debuggerReadByte(addr+7); 14.1374 + 14.1375 + int i = debuggerReadByte(addr+8); 14.1376 + int j = debuggerReadByte(addr+9); 14.1377 + int k = debuggerReadByte(addr+10); 14.1378 + int l = debuggerReadByte(addr+11); 14.1379 + 14.1380 + int m = debuggerReadByte(addr+12); 14.1381 + int n = debuggerReadByte(addr+13); 14.1382 + int o = debuggerReadByte(addr+14); 14.1383 + int p = debuggerReadByte(addr+15); 14.1384 + 14.1385 + printf("%08x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", 14.1386 + addr,d,c,b,a,h,g,f,e,l,k,j,i,p,o,n,m, 14.1387 + ASCII(a),ASCII(b),ASCII(c),ASCII(d), 14.1388 + ASCII(e),ASCII(f),ASCII(g),ASCII(h), 14.1389 + ASCII(i),ASCII(j),ASCII(k),ASCII(l), 14.1390 + ASCII(m),ASCII(n),ASCII(o),ASCII(p)); 14.1391 + addr += 16; 14.1392 + } 14.1393 + } else 14.1394 + debuggerUsage("mw"); 14.1395 +} 14.1396 + 14.1397 +void debuggerQuit(int, char **) 14.1398 +{ 14.1399 + char buffer[10]; 14.1400 + printf("Are you sure you want to quit (y/n)? "); 14.1401 + fgets(buffer, 1024, stdin); 14.1402 + 14.1403 + if(buffer[0] == 'y' || buffer[0] == 'Y') { 14.1404 + debugger = false; 14.1405 + emulating = false; 14.1406 + } 14.1407 +} 14.1408 + 14.1409 +void debuggerOutput(char *s, u32 addr) 14.1410 +{ 14.1411 + if(s) 14.1412 + puts(s); 14.1413 + else { 14.1414 + char c; 14.1415 + 14.1416 + c = debuggerReadByte(addr); 14.1417 + addr++; 14.1418 + while(c) { 14.1419 + putchar(c); 14.1420 + c = debuggerReadByte(addr); 14.1421 + addr++; 14.1422 + } 14.1423 + } 14.1424 +} 14.1425 + 14.1426 +void debuggerMain() 14.1427 +{ 14.1428 + char buffer[1024]; 14.1429 + char *commands[10]; 14.1430 + int commandCount = 0; 14.1431 + 14.1432 + if(theEmulator.emuUpdateCPSR) 14.1433 + theEmulator.emuUpdateCPSR(); 14.1434 + debuggerRegisters(0, NULL); 14.1435 + 14.1436 + while(debugger) { 14.1437 + systemSoundPause(); 14.1438 + printf("debugger> "); 14.1439 + commandCount = 0; 14.1440 + char *s = fgets(buffer, 1024, stdin); 14.1441 + 14.1442 + commands[0] = strtok(s, " \t\n"); 14.1443 + if(commands[0] == NULL) 14.1444 + continue; 14.1445 + commandCount++; 14.1446 + while((s = strtok(NULL, " \t\n"))) { 14.1447 + commands[commandCount++] = s; 14.1448 + if(commandCount == 10) 14.1449 + break; 14.1450 + } 14.1451 + 14.1452 + for(int j = 0; ; j++) { 14.1453 + if(debuggerCommands[j].name == NULL) { 14.1454 + printf("Unrecognized command %s. Type h for help.\n", commands[0]); 14.1455 + break; 14.1456 + } 14.1457 + if(!strcmp(commands[0], debuggerCommands[j].name)) { 14.1458 + debuggerCommands[j].function(commandCount, commands); 14.1459 + break; 14.1460 + } 14.1461 + } 14.1462 + } 14.1463 +}
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 15.2 +++ b/src/sdl/debugger.h Sun Mar 04 21:06:50 2012 -0600 15.3 @@ -0,0 +1,20 @@ 15.4 +// -*- C++ -*- 15.5 +// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. 15.6 +// Copyright (C) 1999-2003 Forgotten 15.7 +// Copyright (C) 2004 Forgotten and the VBA development team 15.8 + 15.9 +// This program is free software; you can redistribute it and/or modify 15.10 +// it under the terms of the GNU General Public License as published by 15.11 +// the Free Software Foundation; either version 2, or(at your option) 15.12 +// any later version. 15.13 +// 15.14 +// This program is distributed in the hope that it will be useful, 15.15 +// but WITHOUT ANY WARRANTY; without even the implied warranty of 15.16 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15.17 +// GNU General Public License for more details. 15.18 +// 15.19 +// You should have received a copy of the GNU General Public License 15.20 +// along with this program; if not, write to the Free Software Foundation, 15.21 +// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 15.22 + 15.23 +extern void debuggerMain();
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 16.2 +++ b/src/sdl/expr-lex.cpp Sun Mar 04 21:06:50 2012 -0600 16.3 @@ -0,0 +1,1590 @@ 16.4 +#line 2 "expr-lex.cpp" 16.5 +/* A lexical scanner generated by flex */ 16.6 + 16.7 +/* Scanner skeleton version: 16.8 + * $Header: /cvsroot/vba/VisualBoyAdvance/src/expr-lex.cpp,v 1.2 2003/06/06 14:17:21 forgotten Exp $ 16.9 + */ 16.10 + 16.11 +#define FLEX_SCANNER 16.12 +#define YY_FLEX_MAJOR_VERSION 2 16.13 +#define YY_FLEX_MINOR_VERSION 5 16.14 + 16.15 +#include <stdio.h> 16.16 +#ifdef __GNUC__ 16.17 +#include <unistd.h> 16.18 +#endif 16.19 + 16.20 + 16.21 +/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ 16.22 +#ifdef c_plusplus 16.23 +#ifndef __cplusplus 16.24 +#define __cplusplus 16.25 +#endif 16.26 +#endif 16.27 + 16.28 + 16.29 +#ifdef __cplusplus 16.30 + 16.31 +#include <stdlib.h> 16.32 + 16.33 +/* Use prototypes in function declarations. */ 16.34 +#define YY_USE_PROTOS 16.35 + 16.36 +/* The "const" storage-class-modifier is valid. */ 16.37 +#define YY_USE_CONST 16.38 + 16.39 +#else /* ! __cplusplus */ 16.40 + 16.41 +#if __STDC__ 16.42 + 16.43 +#define YY_USE_PROTOS 16.44 +#define YY_USE_CONST 16.45 + 16.46 +#endif /* __STDC__ */ 16.47 +#endif /* ! __cplusplus */ 16.48 + 16.49 +#ifdef __TURBOC__ 16.50 + #pragma warn -rch 16.51 + #pragma warn -use 16.52 +#include <io.h> 16.53 +#include <stdlib.h> 16.54 +#define YY_USE_CONST 16.55 +#define YY_USE_PROTOS 16.56 +#endif 16.57 + 16.58 +#ifdef YY_USE_CONST 16.59 +#define yyconst const 16.60 +#else 16.61 +#define yyconst 16.62 +#endif 16.63 + 16.64 + 16.65 +#ifdef YY_USE_PROTOS 16.66 +#define YY_PROTO(proto) proto 16.67 +#else 16.68 +#define YY_PROTO(proto) () 16.69 +#endif 16.70 + 16.71 +/* Returned upon end-of-file. */ 16.72 +#define YY_NULL 0 16.73 + 16.74 +/* Promotes a possibly negative, possibly signed char to an unsigned 16.75 + * integer for use as an array index. If the signed char is negative, 16.76 + * we want to instead treat it as an 8-bit unsigned char, hence the 16.77 + * double cast. 16.78 + */ 16.79 +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) 16.80 + 16.81 +/* Enter a start condition. This macro really ought to take a parameter, 16.82 + * but we do it the disgusting crufty way forced on us by the ()-less 16.83 + * definition of BEGIN. 16.84 + */ 16.85 +#define BEGIN yy_start = 1 + 2 * 16.86 + 16.87 +/* Translate the current start state into a value that can be later handed 16.88 + * to BEGIN to return to the state. The YYSTATE alias is for lex 16.89 + * compatibility. 16.90 + */ 16.91 +#define YY_START ((yy_start - 1) / 2) 16.92 +#define YYSTATE YY_START 16.93 + 16.94 +/* Action number for EOF rule of a given start state. */ 16.95 +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) 16.96 + 16.97 +/* Special action meaning "start processing a new file". */ 16.98 +#define YY_NEW_FILE yyrestart( yyin ) 16.99 + 16.100 +#define YY_END_OF_BUFFER_CHAR 0 16.101 + 16.102 +/* Size of default input buffer. */ 16.103 +#define YY_BUF_SIZE 16384 16.104 + 16.105 +typedef struct yy_buffer_state *YY_BUFFER_STATE; 16.106 + 16.107 +extern int yyleng; 16.108 +extern FILE *yyin, *yyout; 16.109 + 16.110 +#define EOB_ACT_CONTINUE_SCAN 0 16.111 +#define EOB_ACT_END_OF_FILE 1 16.112 +#define EOB_ACT_LAST_MATCH 2 16.113 + 16.114 +/* The funky do-while in the following #define is used to turn the definition 16.115 + * int a single C statement (which needs a semi-colon terminator). This 16.116 + * avoids problems with code like: 16.117 + * 16.118 + * if ( condition_holds ) 16.119 + * yyless( 5 ); 16.120 + * else 16.121 + * do_something_else(); 16.122 + * 16.123 + * Prior to using the do-while the compiler would get upset at the 16.124 + * "else" because it interpreted the "if" statement as being all 16.125 + * done when it reached the ';' after the yyless() call. 16.126 + */ 16.127 + 16.128 +/* Return all but the first 'n' matched characters back to the input stream. */ 16.129 + 16.130 +#define yyless(n) \ 16.131 + do \ 16.132 + { \ 16.133 + /* Undo effects of setting up yytext. */ \ 16.134 + *yy_cp = yy_hold_char; \ 16.135 + YY_RESTORE_YY_MORE_OFFSET \ 16.136 + yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ 16.137 + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ 16.138 + } \ 16.139 + while ( 0 ) 16.140 + 16.141 +#define unput(c) yyunput( c, yytext_ptr ) 16.142 + 16.143 +/* The following is because we cannot portably get our hands on size_t 16.144 + * (without autoconf's help, which isn't available because we want 16.145 + * flex-generated scanners to compile on their own). 16.146 + */ 16.147 +typedef unsigned int yy_size_t; 16.148 + 16.149 + 16.150 +struct yy_buffer_state 16.151 + { 16.152 + FILE *yy_input_file; 16.153 + 16.154 + char *yy_ch_buf; /* input buffer */ 16.155 + char *yy_buf_pos; /* current position in input buffer */ 16.156 + 16.157 + /* Size of input buffer in bytes, not including room for EOB 16.158 + * characters. 16.159 + */ 16.160 + yy_size_t yy_buf_size; 16.161 + 16.162 + /* Number of characters read into yy_ch_buf, not including EOB 16.163 + * characters. 16.164 + */ 16.165 + int yy_n_chars; 16.166 + 16.167 + /* Whether we "own" the buffer - i.e., we know we created it, 16.168 + * and can realloc() it to grow it, and should free() it to 16.169 + * delete it. 16.170 + */ 16.171 + int yy_is_our_buffer; 16.172 + 16.173 + /* Whether this is an "interactive" input source; if so, and 16.174 + * if we're using stdio for input, then we want to use getc() 16.175 + * instead of fread(), to make sure we stop fetching input after 16.176 + * each newline. 16.177 + */ 16.178 + int yy_is_interactive; 16.179 + 16.180 + /* Whether we're considered to be at the beginning of a line. 16.181 + * If so, '^' rules will be active on the next match, otherwise 16.182 + * not. 16.183 + */ 16.184 + int yy_at_bol; 16.185 + 16.186 + /* Whether to try to fill the input buffer when we reach the 16.187 + * end of it. 16.188 + */ 16.189 + int yy_fill_buffer; 16.190 + 16.191 + int yy_buffer_status; 16.192 +#define YY_BUFFER_NEW 0 16.193 +#define YY_BUFFER_NORMAL 1 16.194 + /* When an EOF's been seen but there's still some text to process 16.195 + * then we mark the buffer as YY_EOF_PENDING, to indicate that we 16.196 + * shouldn't try reading from the input source any more. We might 16.197 + * still have a bunch of tokens to match, though, because of 16.198 + * possible backing-up. 16.199 + * 16.200 + * When we actually see the EOF, we change the status to "new" 16.201 + * (via yyrestart()), so that the user can continue scanning by 16.202 + * just pointing yyin at a new input file. 16.203 + */ 16.204 +#define YY_BUFFER_EOF_PENDING 2 16.205 + }; 16.206 + 16.207 +static YY_BUFFER_STATE yy_current_buffer = 0; 16.208 + 16.209 +/* We provide macros for accessing buffer states in case in the 16.210 + * future we want to put the buffer states in a more general 16.211 + * "scanner state". 16.212 + */ 16.213 +#define YY_CURRENT_BUFFER yy_current_buffer 16.214 + 16.215 + 16.216 +/* yy_hold_char holds the character lost when yytext is formed. */ 16.217 +static char yy_hold_char; 16.218 + 16.219 +static int yy_n_chars; /* number of characters read into yy_ch_buf */ 16.220 + 16.221 + 16.222 +int yyleng; 16.223 + 16.224 +/* Points to current character in buffer. */ 16.225 +static char *yy_c_buf_p = (char *) 0; 16.226 +static int yy_init = 1; /* whether we need to initialize */ 16.227 +static int yy_start = 0; /* start state number */ 16.228 + 16.229 +/* Flag which is used to allow yywrap()'s to do buffer switches 16.230 + * instead of setting up a fresh yyin. A bit of a hack ... 16.231 + */ 16.232 +static int yy_did_buffer_switch_on_eof; 16.233 + 16.234 +void yyrestart YY_PROTO(( FILE *input_file )); 16.235 + 16.236 +void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); 16.237 +void yy_load_buffer_state YY_PROTO(( void )); 16.238 +YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); 16.239 +void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); 16.240 +void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); 16.241 +void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); 16.242 +#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) 16.243 + 16.244 +YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); 16.245 +YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str )); 16.246 +YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); 16.247 + 16.248 +static void *yy_flex_alloc YY_PROTO(( yy_size_t )); 16.249 +static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); 16.250 +static void yy_flex_free YY_PROTO(( void * )); 16.251 + 16.252 +#define yy_new_buffer yy_create_buffer 16.253 + 16.254 +#define yy_set_interactive(is_interactive) \ 16.255 + { \ 16.256 + if ( ! yy_current_buffer ) \ 16.257 + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ 16.258 + yy_current_buffer->yy_is_interactive = is_interactive; \ 16.259 + } 16.260 + 16.261 +#define yy_set_bol(at_bol) \ 16.262 + { \ 16.263 + if ( ! yy_current_buffer ) \ 16.264 + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ 16.265 + yy_current_buffer->yy_at_bol = at_bol; \ 16.266 + } 16.267 + 16.268 +#define YY_AT_BOL() (yy_current_buffer->yy_at_bol) 16.269 + 16.270 + 16.271 +#define yywrap() 1 16.272 +#define YY_SKIP_YYWRAP 16.273 +typedef unsigned char YY_CHAR; 16.274 +FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; 16.275 +typedef int yy_state_type; 16.276 +extern char *yytext; 16.277 +#define yytext_ptr yytext 16.278 + 16.279 +static yy_state_type yy_get_previous_state YY_PROTO(( void )); 16.280 +static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); 16.281 +static int yy_get_next_buffer YY_PROTO(( void )); 16.282 +static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); 16.283 + 16.284 +/* Done after the current pattern has been matched and before the 16.285 + * corresponding action - sets up yytext. 16.286 + */ 16.287 +#define YY_DO_BEFORE_ACTION \ 16.288 + yytext_ptr = yy_bp; \ 16.289 + yyleng = (int) (yy_cp - yy_bp); \ 16.290 + yy_hold_char = *yy_cp; \ 16.291 + *yy_cp = '\0'; \ 16.292 + yy_c_buf_p = yy_cp; 16.293 + 16.294 +#define YY_NUM_RULES 10 16.295 +#define YY_END_OF_BUFFER 11 16.296 +static yyconst short int yy_accept[24] = 16.297 + { 0, 16.298 + 0, 0, 11, 9, 8, 8, 6, 7, 9, 4, 16.299 + 3, 2, 2, 8, 5, 3, 2, 2, 2, 2, 16.300 + 2, 1, 0 16.301 + } ; 16.302 + 16.303 +static yyconst int yy_ec[256] = 16.304 + { 0, 16.305 + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 16.306 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16.307 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16.308 + 1, 2, 1, 1, 1, 1, 1, 4, 1, 1, 16.309 + 1, 5, 1, 1, 6, 7, 1, 8, 8, 8, 16.310 + 8, 8, 8, 8, 8, 8, 8, 1, 1, 1, 16.311 + 1, 9, 1, 1, 10, 10, 10, 10, 10, 10, 16.312 + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 16.313 + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 16.314 + 1, 1, 1, 1, 10, 1, 10, 10, 10, 10, 16.315 + 16.316 + 11, 12, 10, 10, 13, 10, 10, 10, 10, 10, 16.317 + 14, 10, 10, 10, 15, 10, 10, 10, 10, 10, 16.318 + 10, 16, 1, 1, 1, 1, 1, 1, 1, 1, 16.319 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16.320 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16.321 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16.322 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16.323 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16.324 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16.325 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16.326 + 16.327 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16.328 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16.329 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16.330 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16.331 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16.332 + 1, 1, 1, 1, 1 16.333 + } ; 16.334 + 16.335 +static yyconst int yy_meta[17] = 16.336 + { 0, 16.337 + 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 16.338 + 2, 2, 2, 2, 2, 2 16.339 + } ; 16.340 + 16.341 +static yyconst short int yy_base[25] = 16.342 + { 0, 16.343 + 0, 0, 32, 33, 15, 17, 33, 33, 22, 33, 16.344 + 22, 0, 16, 19, 33, 20, 0, 11, 15, 11, 16.345 + 12, 0, 33, 21 16.346 + } ; 16.347 + 16.348 +static yyconst short int yy_def[25] = 16.349 + { 0, 16.350 + 23, 1, 23, 23, 23, 23, 23, 23, 23, 23, 16.351 + 23, 24, 24, 23, 23, 23, 24, 24, 24, 24, 16.352 + 24, 24, 0, 23 16.353 + } ; 16.354 + 16.355 +static yyconst short int yy_nxt[50] = 16.356 + { 0, 16.357 + 4, 5, 6, 7, 8, 9, 10, 11, 4, 12, 16.358 + 12, 12, 12, 12, 13, 12, 14, 14, 14, 14, 16.359 + 14, 14, 17, 22, 21, 20, 19, 16, 18, 16, 16.360 + 15, 23, 3, 23, 23, 23, 23, 23, 23, 23, 16.361 + 23, 23, 23, 23, 23, 23, 23, 23, 23 16.362 + } ; 16.363 + 16.364 +static yyconst short int yy_chk[50] = 16.365 + { 0, 16.366 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16.367 + 1, 1, 1, 1, 1, 1, 5, 5, 6, 6, 16.368 + 14, 14, 24, 21, 20, 19, 18, 16, 13, 11, 16.369 + 9, 3, 23, 23, 23, 23, 23, 23, 23, 23, 16.370 + 23, 23, 23, 23, 23, 23, 23, 23, 23 16.371 + } ; 16.372 + 16.373 +static yy_state_type yy_last_accepting_state; 16.374 +static char *yy_last_accepting_cpos; 16.375 + 16.376 +/* The intent behind this definition is that it'll catch 16.377 + * any uses of REJECT which flex missed. 16.378 + */ 16.379 +#define REJECT reject_used_but_not_detected 16.380 +#define yymore() yymore_used_but_not_detected 16.381 +#define YY_MORE_ADJ 0 16.382 +#define YY_RESTORE_YY_MORE_OFFSET 16.383 +char *yytext; 16.384 +#line 1 "expr.l" 16.385 +#define INITIAL 0 16.386 +#line 2 "expr.l" 16.387 +#include "expr.cpp.h" 16.388 + 16.389 +#ifndef __GNUC__ 16.390 +#include <io.h> 16.391 +#define isatty _isatty 16.392 +#endif 16.393 + 16.394 +char *exprString; 16.395 +int exprCol; 16.396 + 16.397 +#define YY_INPUT(buf,result,max_size) \ 16.398 + { \ 16.399 + int c = *exprString++; \ 16.400 + exprCol++;\ 16.401 + result = (c == 0) ? YY_NULL : (buf[0] = c, 1); \ 16.402 + } 16.403 +#define YY_MAIN 0 16.404 +#line 400 "expr-lex.cpp" 16.405 + 16.406 +/* Macros after this point can all be overridden by user definitions in 16.407 + * section 1. 16.408 + */ 16.409 + 16.410 +#ifndef YY_SKIP_YYWRAP 16.411 +#ifdef __cplusplus 16.412 +extern "C" int yywrap YY_PROTO(( void )); 16.413 +#else 16.414 +extern int yywrap YY_PROTO(( void )); 16.415 +#endif 16.416 +#endif 16.417 + 16.418 +#ifndef YY_NO_UNPUT 16.419 +static void yyunput YY_PROTO(( int c, char *buf_ptr )); 16.420 +#endif 16.421 + 16.422 +#ifndef yytext_ptr 16.423 +static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); 16.424 +#endif 16.425 + 16.426 +#ifdef YY_NEED_STRLEN 16.427 +static int yy_flex_strlen YY_PROTO(( yyconst char * )); 16.428 +#endif 16.429 + 16.430 +#ifndef YY_NO_INPUT 16.431 +#ifdef __cplusplus 16.432 +static int yyinput YY_PROTO(( void )); 16.433 +#else 16.434 +static int input YY_PROTO(( void )); 16.435 +#endif 16.436 +#endif 16.437 + 16.438 +#if YY_STACK_USED 16.439 +static int yy_start_stack_ptr = 0; 16.440 +static int yy_start_stack_depth = 0; 16.441 +static int *yy_start_stack = 0; 16.442 +#ifndef YY_NO_PUSH_STATE 16.443 +static void yy_push_state YY_PROTO(( int new_state )); 16.444 +#endif 16.445 +#ifndef YY_NO_POP_STATE 16.446 +static void yy_pop_state YY_PROTO(( void )); 16.447 +#endif 16.448 +#ifndef YY_NO_TOP_STATE 16.449 +static int yy_top_state YY_PROTO(( void )); 16.450 +#endif 16.451 + 16.452 +#else 16.453 +#define YY_NO_PUSH_STATE 1 16.454 +#define YY_NO_POP_STATE 1 16.455 +#define YY_NO_TOP_STATE 1 16.456 +#endif 16.457 + 16.458 +#ifdef YY_MALLOC_DECL 16.459 +YY_MALLOC_DECL 16.460 +#else 16.461 +#if __STDC__ 16.462 +#ifndef __cplusplus 16.463 +#include <stdlib.h> 16.464 +#endif 16.465 +#else 16.466 +/* Just try to get by without declaring the routines. This will fail 16.467 + * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) 16.468 + * or sizeof(void*) != sizeof(int). 16.469 + */ 16.470 +#endif 16.471 +#endif 16.472 + 16.473 +/* Amount of stuff to slurp up with each read. */ 16.474 +#ifndef YY_READ_BUF_SIZE 16.475 +#define YY_READ_BUF_SIZE 8192 16.476 +#endif 16.477 + 16.478 +/* Copy whatever the last rule matched to the standard output. */ 16.479 + 16.480 +#ifndef ECHO 16.481 +/* This used to be an fputs(), but since the string might contain NUL's, 16.482 + * we now use fwrite(). 16.483 + */ 16.484 +#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) 16.485 +#endif 16.486 + 16.487 +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, 16.488 + * is returned in "result". 16.489 + */ 16.490 +#ifndef YY_INPUT 16.491 +#define YY_INPUT(buf,result,max_size) \ 16.492 + if ( yy_current_buffer->yy_is_interactive ) \ 16.493 + { \ 16.494 + int c = '*', n; \ 16.495 + for ( n = 0; n < max_size && \ 16.496 + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ 16.497 + buf[n] = (char) c; \ 16.498 + if ( c == '\n' ) \ 16.499 + buf[n++] = (char) c; \ 16.500 + if ( c == EOF && ferror( yyin ) ) \ 16.501 + YY_FATAL_ERROR( "input in flex scanner failed" ); \ 16.502 + result = n; \ 16.503 + } \ 16.504 + else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ 16.505 + && ferror( yyin ) ) \ 16.506 + YY_FATAL_ERROR( "input in flex scanner failed" ); 16.507 +#endif 16.508 + 16.509 +/* No semi-colon after return; correct usage is to write "yyterminate();" - 16.510 + * we don't want an extra ';' after the "return" because that will cause 16.511 + * some compilers to complain about unreachable statements. 16.512 + */ 16.513 +#ifndef yyterminate 16.514 +#define yyterminate() return YY_NULL 16.515 +#endif 16.516 + 16.517 +/* Number of entries by which start-condition stack grows. */ 16.518 +#ifndef YY_START_STACK_INCR 16.519 +#define YY_START_STACK_INCR 25 16.520 +#endif 16.521 + 16.522 +/* Report a fatal error. */ 16.523 +#ifndef YY_FATAL_ERROR 16.524 +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) 16.525 +#endif 16.526 + 16.527 +/* Default declaration of generated scanner - a define so the user can 16.528 + * easily add parameters. 16.529 + */ 16.530 +#ifndef YY_DECL 16.531 +#define YY_DECL int yylex YY_PROTO(( void )) 16.532 +#endif 16.533 + 16.534 +/* Code executed at the beginning of each rule, after yytext and yyleng 16.535 + * have been set up. 16.536 + */ 16.537 +#ifndef YY_USER_ACTION 16.538 +#define YY_USER_ACTION 16.539 +#endif 16.540 + 16.541 +/* Code executed at the end of each rule. */ 16.542 +#ifndef YY_BREAK 16.543 +#define YY_BREAK break; 16.544 +#endif 16.545 + 16.546 +#define YY_RULE_SETUP \ 16.547 + YY_USER_ACTION 16.548 + 16.549 +YY_DECL 16.550 + { 16.551 + register yy_state_type yy_current_state; 16.552 + register char *yy_cp = NULL, *yy_bp = NULL; 16.553 + register int yy_act; 16.554 + 16.555 +#line 31 "expr.l" 16.556 + 16.557 + 16.558 +#line 554 "expr-lex.cpp" 16.559 + 16.560 + if ( yy_init ) 16.561 + { 16.562 + yy_init = 0; 16.563 + 16.564 +#ifdef YY_USER_INIT 16.565 + YY_USER_INIT; 16.566 +#endif 16.567 + 16.568 + if ( ! yy_start ) 16.569 + yy_start = 1; /* first start state */ 16.570 + 16.571 + if ( ! yyin ) 16.572 + yyin = stdin; 16.573 + 16.574 + if ( ! yyout ) 16.575 + yyout = stdout; 16.576 + 16.577 + if ( ! yy_current_buffer ) 16.578 + yy_current_buffer = 16.579 + yy_create_buffer( yyin, YY_BUF_SIZE ); 16.580 + 16.581 + yy_load_buffer_state(); 16.582 + } 16.583 + 16.584 + while ( 1 ) /* loops until end-of-file is reached */ 16.585 + { 16.586 + yy_cp = yy_c_buf_p; 16.587 + 16.588 + /* Support of yytext. */ 16.589 + *yy_cp = yy_hold_char; 16.590 + 16.591 + /* yy_bp points to the position in yy_ch_buf of the start of 16.592 + * the current run. 16.593 + */ 16.594 + yy_bp = yy_cp; 16.595 + 16.596 + yy_current_state = yy_start; 16.597 +yy_match: 16.598 + do 16.599 + { 16.600 + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; 16.601 + if ( yy_accept[yy_current_state] ) 16.602 + { 16.603 + yy_last_accepting_state = yy_current_state; 16.604 + yy_last_accepting_cpos = yy_cp; 16.605 + } 16.606 + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) 16.607 + { 16.608 + yy_current_state = (int) yy_def[yy_current_state]; 16.609 + if ( yy_current_state >= 24 ) 16.610 + yy_c = yy_meta[(unsigned int) yy_c]; 16.611 + } 16.612 + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; 16.613 + ++yy_cp; 16.614 + } 16.615 + while ( yy_base[yy_current_state] != 33 ); 16.616 + 16.617 +yy_find_action: 16.618 + yy_act = yy_accept[yy_current_state]; 16.619 + if ( yy_act == 0 ) 16.620 + { /* have to back up */ 16.621 + yy_cp = yy_last_accepting_cpos; 16.622 + yy_current_state = yy_last_accepting_state; 16.623 + yy_act = yy_accept[yy_current_state]; 16.624 + } 16.625 + 16.626 + YY_DO_BEFORE_ACTION; 16.627 + 16.628 + 16.629 +do_action: /* This label is used only to access EOF actions. */ 16.630 + 16.631 + 16.632 + switch ( yy_act ) 16.633 + { /* beginning of action switch */ 16.634 + case 0: /* must back up */ 16.635 + /* undo the effects of YY_DO_BEFORE_ACTION */ 16.636 + *yy_cp = yy_hold_char; 16.637 + yy_cp = yy_last_accepting_cpos; 16.638 + yy_current_state = yy_last_accepting_state; 16.639 + goto yy_find_action; 16.640 + 16.641 +case 1: 16.642 +YY_RULE_SETUP 16.643 +#line 33 "expr.l" 16.644 +{ 16.645 + return TOKEN_SIZEOF; 16.646 +} 16.647 + YY_BREAK 16.648 +case 2: 16.649 +YY_RULE_SETUP 16.650 +#line 37 "expr.l" 16.651 +{ 16.652 + return TOKEN_IDENTIFIER; 16.653 +} 16.654 + YY_BREAK 16.655 +case 3: 16.656 +YY_RULE_SETUP 16.657 +#line 41 "expr.l" 16.658 +{ 16.659 + return TOKEN_NUMBER; 16.660 +} 16.661 + YY_BREAK 16.662 +case 4: 16.663 +YY_RULE_SETUP 16.664 +#line 45 "expr.l" 16.665 +{ 16.666 + return TOKEN_DOT; 16.667 +} 16.668 + YY_BREAK 16.669 +case 5: 16.670 +YY_RULE_SETUP 16.671 +#line 49 "expr.l" 16.672 +{ 16.673 + return TOKEN_ARROW; 16.674 +} 16.675 + YY_BREAK 16.676 +case 6: 16.677 +YY_RULE_SETUP 16.678 +#line 53 "expr.l" 16.679 +{ 16.680 + return TOKEN_ADDR; 16.681 +} 16.682 + YY_BREAK 16.683 +case 7: 16.684 +YY_RULE_SETUP 16.685 +#line 57 "expr.l" 16.686 +{ 16.687 + return TOKEN_STAR; 16.688 +} 16.689 + YY_BREAK 16.690 +case 8: 16.691 +YY_RULE_SETUP 16.692 +#line 61 "expr.l" 16.693 + 16.694 + YY_BREAK 16.695 +case 9: 16.696 +YY_RULE_SETUP 16.697 +#line 63 "expr.l" 16.698 +return *yytext; 16.699 + YY_BREAK 16.700 +case 10: 16.701 +YY_RULE_SETUP 16.702 +#line 65 "expr.l" 16.703 +ECHO; 16.704 + YY_BREAK 16.705 +#line 701 "expr-lex.cpp" 16.706 +case YY_STATE_EOF(INITIAL): 16.707 + yyterminate(); 16.708 + 16.709 + case YY_END_OF_BUFFER: 16.710 + { 16.711 + /* Amount of text matched not including the EOB char. */ 16.712 + int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; 16.713 + 16.714 + /* Undo the effects of YY_DO_BEFORE_ACTION. */ 16.715 + *yy_cp = yy_hold_char; 16.716 + YY_RESTORE_YY_MORE_OFFSET 16.717 + 16.718 + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) 16.719 + { 16.720 + /* We're scanning a new file or input source. It's 16.721 + * possible that this happened because the user 16.722 + * just pointed yyin at a new source and called 16.723 + * yylex(). If so, then we have to assure 16.724 + * consistency between yy_current_buffer and our 16.725 + * globals. Here is the right place to do so, because 16.726 + * this is the first action (other than possibly a 16.727 + * back-up) that will match for the new input source. 16.728 + */ 16.729 + yy_n_chars = yy_current_buffer->yy_n_chars; 16.730 + yy_current_buffer->yy_input_file = yyin; 16.731 + yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; 16.732 + } 16.733 + 16.734 + /* Note that here we test for yy_c_buf_p "<=" to the position 16.735 + * of the first EOB in the buffer, since yy_c_buf_p will 16.736 + * already have been incremented past the NUL character 16.737 + * (since all states make transitions on EOB to the 16.738 + * end-of-buffer state). Contrast this with the test 16.739 + * in input(). 16.740 + */ 16.741 + if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) 16.742 + { /* This was really a NUL. */ 16.743 + yy_state_type yy_next_state; 16.744 + 16.745 + yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; 16.746 + 16.747 + yy_current_state = yy_get_previous_state(); 16.748 + 16.749 + /* Okay, we're now positioned to make the NUL 16.750 + * transition. We couldn't have 16.751 + * yy_get_previous_state() go ahead and do it 16.752 + * for us because it doesn't know how to deal 16.753 + * with the possibility of jamming (and we don't 16.754 + * want to build jamming into it because then it 16.755 + * will run more slowly). 16.756 + */ 16.757 + 16.758 + yy_next_state = yy_try_NUL_trans( yy_current_state ); 16.759 + 16.760 + yy_bp = yytext_ptr + YY_MORE_ADJ; 16.761 + 16.762 + if ( yy_next_state ) 16.763 + { 16.764 + /* Consume the NUL. */ 16.765 + yy_cp = ++yy_c_buf_p; 16.766 + yy_current_state = yy_next_state; 16.767 + goto yy_match; 16.768 + } 16.769 + 16.770 + else 16.771 + { 16.772 + yy_cp = yy_c_buf_p; 16.773 + goto yy_find_action; 16.774 + } 16.775 + } 16.776 + 16.777 + else switch ( yy_get_next_buffer() ) 16.778 + { 16.779 + case EOB_ACT_END_OF_FILE: 16.780 + { 16.781 + yy_did_buffer_switch_on_eof = 0; 16.782 + 16.783 + if ( yywrap() ) 16.784 + { 16.785 + /* Note: because we've taken care in 16.786 + * yy_get_next_buffer() to have set up 16.787 + * yytext, we can now set up 16.788 + * yy_c_buf_p so that if some total 16.789 + * hoser (like flex itself) wants to 16.790 + * call the scanner after we return the 16.791 + * YY_NULL, it'll still work - another 16.792 + * YY_NULL will get returned. 16.793 + */ 16.794 + yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; 16.795 + 16.796 + yy_act = YY_STATE_EOF(YY_START); 16.797 + goto do_action; 16.798 + } 16.799 + 16.800 + else 16.801 + { 16.802 + if ( ! yy_did_buffer_switch_on_eof ) 16.803 + YY_NEW_FILE; 16.804 + } 16.805 + break; 16.806 + } 16.807 + 16.808 + case EOB_ACT_CONTINUE_SCAN: 16.809 + yy_c_buf_p = 16.810 + yytext_ptr + yy_amount_of_matched_text; 16.811 + 16.812 + yy_current_state = yy_get_previous_state(); 16.813 + 16.814 + yy_cp = yy_c_buf_p; 16.815 + yy_bp = yytext_ptr + YY_MORE_ADJ; 16.816 + goto yy_match; 16.817 + 16.818 + case EOB_ACT_LAST_MATCH: 16.819 + yy_c_buf_p = 16.820 + &yy_current_buffer->yy_ch_buf[yy_n_chars]; 16.821 + 16.822 + yy_current_state = yy_get_previous_state(); 16.823 + 16.824 + yy_cp = yy_c_buf_p; 16.825 + yy_bp = yytext_ptr + YY_MORE_ADJ; 16.826 + goto yy_find_action; 16.827 + } 16.828 + break; 16.829 + } 16.830 + 16.831 + default: 16.832 + YY_FATAL_ERROR( 16.833 + "fatal flex scanner internal error--no action found" ); 16.834 + } /* end of action switch */ 16.835 + } /* end of scanning one token */ 16.836 + } /* end of yylex */ 16.837 + 16.838 + 16.839 +/* yy_get_next_buffer - try to read in a new buffer 16.840 + * 16.841 + * Returns a code representing an action: 16.842 + * EOB_ACT_LAST_MATCH - 16.843 + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position 16.844 + * EOB_ACT_END_OF_FILE - end of file 16.845 + */ 16.846 + 16.847 +static int yy_get_next_buffer() 16.848 + { 16.849 + register char *dest = yy_current_buffer->yy_ch_buf; 16.850 + register char *source = yytext_ptr; 16.851 + register int number_to_move, i; 16.852 + int ret_val; 16.853 + 16.854 + if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) 16.855 + YY_FATAL_ERROR( 16.856 + "fatal flex scanner internal error--end of buffer missed" ); 16.857 + 16.858 + if ( yy_current_buffer->yy_fill_buffer == 0 ) 16.859 + { /* Don't try to fill the buffer, so this is an EOF. */ 16.860 + if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) 16.861 + { 16.862 + /* We matched a single character, the EOB, so 16.863 + * treat this as a final EOF. 16.864 + */ 16.865 + return EOB_ACT_END_OF_FILE; 16.866 + } 16.867 + 16.868 + else 16.869 + { 16.870 + /* We matched some text prior to the EOB, first 16.871 + * process it. 16.872 + */ 16.873 + return EOB_ACT_LAST_MATCH; 16.874 + } 16.875 + } 16.876 + 16.877 + /* Try to read more data. */ 16.878 + 16.879 + /* First move last chars to start of buffer. */ 16.880 + number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; 16.881 + 16.882 + for ( i = 0; i < number_to_move; ++i ) 16.883 + *(dest++) = *(source++); 16.884 + 16.885 + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) 16.886 + /* don't do the read, it's not guaranteed to return an EOF, 16.887 + * just force an EOF 16.888 + */ 16.889 + yy_current_buffer->yy_n_chars = yy_n_chars = 0; 16.890 + 16.891 + else 16.892 + { 16.893 + int num_to_read = 16.894 + yy_current_buffer->yy_buf_size - number_to_move - 1; 16.895 + 16.896 + while ( num_to_read <= 0 ) 16.897 + { /* Not enough room in the buffer - grow it. */ 16.898 +#ifdef YY_USES_REJECT 16.899 + YY_FATAL_ERROR( 16.900 +"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); 16.901 +#else 16.902 + 16.903 + /* just a shorter name for the current buffer */ 16.904 + YY_BUFFER_STATE b = yy_current_buffer; 16.905 + 16.906 + int yy_c_buf_p_offset = 16.907 + (int) (yy_c_buf_p - b->yy_ch_buf); 16.908 + 16.909 + if ( b->yy_is_our_buffer ) 16.910 + { 16.911 + int new_size = b->yy_buf_size * 2; 16.912 + 16.913 + if ( new_size <= 0 ) 16.914 + b->yy_buf_size += b->yy_buf_size / 8; 16.915 + else 16.916 + b->yy_buf_size *= 2; 16.917 + 16.918 + b->yy_ch_buf = (char *) 16.919 + /* Include room in for 2 EOB chars. */ 16.920 + yy_flex_realloc( (void *) b->yy_ch_buf, 16.921 + b->yy_buf_size + 2 ); 16.922 + } 16.923 + else 16.924 + /* Can't grow it, we don't own it. */ 16.925 + b->yy_ch_buf = 0; 16.926 + 16.927 + if ( ! b->yy_ch_buf ) 16.928 + YY_FATAL_ERROR( 16.929 + "fatal error - scanner input buffer overflow" ); 16.930 + 16.931 + yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; 16.932 + 16.933 + num_to_read = yy_current_buffer->yy_buf_size - 16.934 + number_to_move - 1; 16.935 +#endif 16.936 + } 16.937 + 16.938 + if ( num_to_read > YY_READ_BUF_SIZE ) 16.939 + num_to_read = YY_READ_BUF_SIZE; 16.940 + 16.941 + /* Read in more data. */ 16.942 + YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), 16.943 + yy_n_chars, num_to_read ); 16.944 + 16.945 + yy_current_buffer->yy_n_chars = yy_n_chars; 16.946 + } 16.947 + 16.948 + if ( yy_n_chars == 0 ) 16.949 + { 16.950 + if ( number_to_move == YY_MORE_ADJ ) 16.951 + { 16.952 + ret_val = EOB_ACT_END_OF_FILE; 16.953 + yyrestart( yyin ); 16.954 + } 16.955 + 16.956 + else 16.957 + { 16.958 + ret_val = EOB_ACT_LAST_MATCH; 16.959 + yy_current_buffer->yy_buffer_status = 16.960 + YY_BUFFER_EOF_PENDING; 16.961 + } 16.962 + } 16.963 + 16.964 + else 16.965 + ret_val = EOB_ACT_CONTINUE_SCAN; 16.966 + 16.967 + yy_n_chars += number_to_move; 16.968 + yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; 16.969 + yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; 16.970 + 16.971 + yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; 16.972 + 16.973 + return ret_val; 16.974 + } 16.975 + 16.976 + 16.977 +/* yy_get_previous_state - get the state just before the EOB char was reached */ 16.978 + 16.979 +static yy_state_type yy_get_previous_state() 16.980 + { 16.981 + register yy_state_type yy_current_state; 16.982 + register char *yy_cp; 16.983 + 16.984 + yy_current_state = yy_start; 16.985 + 16.986 + for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) 16.987 + { 16.988 + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); 16.989 + if ( yy_accept[yy_current_state] ) 16.990 + { 16.991 + yy_last_accepting_state = yy_current_state; 16.992 + yy_last_accepting_cpos = yy_cp; 16.993 + } 16.994 + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) 16.995 + { 16.996 + yy_current_state = (int) yy_def[yy_current_state]; 16.997 + if ( yy_current_state >= 24 ) 16.998 + yy_c = yy_meta[(unsigned int) yy_c]; 16.999 + } 16.1000 + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; 16.1001 + } 16.1002 + 16.1003 + return yy_current_state; 16.1004 + } 16.1005 + 16.1006 + 16.1007 +/* yy_try_NUL_trans - try to make a transition on the NUL character 16.1008 + * 16.1009 + * synopsis 16.1010 + * next_state = yy_try_NUL_trans( current_state ); 16.1011 + */ 16.1012 + 16.1013 +#ifdef YY_USE_PROTOS 16.1014 +static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) 16.1015 +#else 16.1016 +static yy_state_type yy_try_NUL_trans( yy_current_state ) 16.1017 +yy_state_type yy_current_state; 16.1018 +#endif 16.1019 + { 16.1020 + register int yy_is_jam; 16.1021 + register char *yy_cp = yy_c_buf_p; 16.1022 + 16.1023 + register YY_CHAR yy_c = 1; 16.1024 + if ( yy_accept[yy_current_state] ) 16.1025 + { 16.1026 + yy_last_accepting_state = yy_current_state; 16.1027 + yy_last_accepting_cpos = yy_cp; 16.1028 + } 16.1029 + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) 16.1030 + { 16.1031 + yy_current_state = (int) yy_def[yy_current_state]; 16.1032 + if ( yy_current_state >= 24 ) 16.1033 + yy_c = yy_meta[(unsigned int) yy_c]; 16.1034 + } 16.1035 + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; 16.1036 + yy_is_jam = (yy_current_state == 23); 16.1037 + 16.1038 + return yy_is_jam ? 0 : yy_current_state; 16.1039 + } 16.1040 + 16.1041 + 16.1042 +#ifndef YY_NO_UNPUT 16.1043 +#ifdef YY_USE_PROTOS 16.1044 +static void yyunput( int c, register char *yy_bp ) 16.1045 +#else 16.1046 +static void yyunput( c, yy_bp ) 16.1047 +int c; 16.1048 +register char *yy_bp; 16.1049 +#endif 16.1050 + { 16.1051 + register char *yy_cp = yy_c_buf_p; 16.1052 + 16.1053 + /* undo effects of setting up yytext */ 16.1054 + *yy_cp = yy_hold_char; 16.1055 + 16.1056 + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) 16.1057 + { /* need to shift things up to make room */ 16.1058 + /* +2 for EOB chars. */ 16.1059 + register int number_to_move = yy_n_chars + 2; 16.1060 + register char *dest = &yy_current_buffer->yy_ch_buf[ 16.1061 + yy_current_buffer->yy_buf_size + 2]; 16.1062 + register char *source = 16.1063 + &yy_current_buffer->yy_ch_buf[number_to_move]; 16.1064 + 16.1065 + while ( source > yy_current_buffer->yy_ch_buf ) 16.1066 + *--dest = *--source; 16.1067 + 16.1068 + yy_cp += (int) (dest - source); 16.1069 + yy_bp += (int) (dest - source); 16.1070 + yy_current_buffer->yy_n_chars = 16.1071 + yy_n_chars = yy_current_buffer->yy_buf_size; 16.1072 + 16.1073 + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) 16.1074 + YY_FATAL_ERROR( "flex scanner push-back overflow" ); 16.1075 + } 16.1076 + 16.1077 + *--yy_cp = (char) c; 16.1078 + 16.1079 + 16.1080 + yytext_ptr = yy_bp; 16.1081 + yy_hold_char = *yy_cp; 16.1082 + yy_c_buf_p = yy_cp; 16.1083 + } 16.1084 +#endif /* ifndef YY_NO_UNPUT */ 16.1085 + 16.1086 + 16.1087 +#ifdef __cplusplus 16.1088 +static int yyinput() 16.1089 +#else 16.1090 +static int input() 16.1091 +#endif 16.1092 + { 16.1093 + int c; 16.1094 + 16.1095 + *yy_c_buf_p = yy_hold_char; 16.1096 + 16.1097 + if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) 16.1098 + { 16.1099 + /* yy_c_buf_p now points to the character we want to return. 16.1100 + * If this occurs *before* the EOB characters, then it's a 16.1101 + * valid NUL; if not, then we've hit the end of the buffer. 16.1102 + */ 16.1103 + if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) 16.1104 + /* This was really a NUL. */ 16.1105 + *yy_c_buf_p = '\0'; 16.1106 + 16.1107 + else 16.1108 + { /* need more input */ 16.1109 + int offset = yy_c_buf_p - yytext_ptr; 16.1110 + ++yy_c_buf_p; 16.1111 + 16.1112 + switch ( yy_get_next_buffer() ) 16.1113 + { 16.1114 + case EOB_ACT_LAST_MATCH: 16.1115 + /* This happens because yy_g_n_b() 16.1116 + * sees that we've accumulated a 16.1117 + * token and flags that we need to 16.1118 + * try matching the token before 16.1119 + * proceeding. But for input(), 16.1120 + * there's no matching to consider. 16.1121 + * So convert the EOB_ACT_LAST_MATCH 16.1122 + * to EOB_ACT_END_OF_FILE. 16.1123 + */ 16.1124 + 16.1125 + /* Reset buffer status. */ 16.1126 + yyrestart( yyin ); 16.1127 + 16.1128 + /* fall through */ 16.1129 + 16.1130 + case EOB_ACT_END_OF_FILE: 16.1131 + { 16.1132 + if ( yywrap() ) 16.1133 + return EOF; 16.1134 + 16.1135 + if ( ! yy_did_buffer_switch_on_eof ) 16.1136 + YY_NEW_FILE; 16.1137 +#ifdef __cplusplus 16.1138 + return yyinput(); 16.1139 +#else 16.1140 + return input(); 16.1141 +#endif 16.1142 + } 16.1143 + 16.1144 + case EOB_ACT_CONTINUE_SCAN: 16.1145 + yy_c_buf_p = yytext_ptr + offset; 16.1146 + break; 16.1147 + } 16.1148 + } 16.1149 + } 16.1150 + 16.1151 + c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ 16.1152 + *yy_c_buf_p = '\0'; /* preserve yytext */ 16.1153 + yy_hold_char = *++yy_c_buf_p; 16.1154 + 16.1155 + 16.1156 + return c; 16.1157 + } 16.1158 + 16.1159 + 16.1160 +#ifdef YY_USE_PROTOS 16.1161 +void yyrestart( FILE *input_file ) 16.1162 +#else 16.1163 +void yyrestart( input_file ) 16.1164 +FILE *input_file; 16.1165 +#endif 16.1166 + { 16.1167 + if ( ! yy_current_buffer ) 16.1168 + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); 16.1169 + 16.1170 + yy_init_buffer( yy_current_buffer, input_file ); 16.1171 + yy_load_buffer_state(); 16.1172 + } 16.1173 + 16.1174 + 16.1175 +#ifdef YY_USE_PROTOS 16.1176 +void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) 16.1177 +#else 16.1178 +void yy_switch_to_buffer( new_buffer ) 16.1179 +YY_BUFFER_STATE new_buffer; 16.1180 +#endif 16.1181 + { 16.1182 + if ( yy_current_buffer == new_buffer ) 16.1183 + return; 16.1184 + 16.1185 + if ( yy_current_buffer ) 16.1186 + { 16.1187 + /* Flush out information for old buffer. */ 16.1188 + *yy_c_buf_p = yy_hold_char; 16.1189 + yy_current_buffer->yy_buf_pos = yy_c_buf_p; 16.1190 + yy_current_buffer->yy_n_chars = yy_n_chars; 16.1191 + } 16.1192 + 16.1193 + yy_current_buffer = new_buffer; 16.1194 + yy_load_buffer_state(); 16.1195 + 16.1196 + /* We don't actually know whether we did this switch during 16.1197 + * EOF (yywrap()) processing, but the only time this flag 16.1198 + * is looked at is after yywrap() is called, so it's safe 16.1199 + * to go ahead and always set it. 16.1200 + */ 16.1201 + yy_did_buffer_switch_on_eof = 1; 16.1202 + } 16.1203 + 16.1204 + 16.1205 +#ifdef YY_USE_PROTOS 16.1206 +void yy_load_buffer_state( void ) 16.1207 +#else 16.1208 +void yy_load_buffer_state() 16.1209 +#endif 16.1210 + { 16.1211 + yy_n_chars = yy_current_buffer->yy_n_chars; 16.1212 + yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; 16.1213 + yyin = yy_current_buffer->yy_input_file; 16.1214 + yy_hold_char = *yy_c_buf_p; 16.1215 + } 16.1216 + 16.1217 + 16.1218 +#ifdef YY_USE_PROTOS 16.1219 +YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) 16.1220 +#else 16.1221 +YY_BUFFER_STATE yy_create_buffer( file, size ) 16.1222 +FILE *file; 16.1223 +int size; 16.1224 +#endif 16.1225 + { 16.1226 + YY_BUFFER_STATE b; 16.1227 + 16.1228 + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); 16.1229 + if ( ! b ) 16.1230 + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); 16.1231 + 16.1232 + b->yy_buf_size = size; 16.1233 + 16.1234 + /* yy_ch_buf has to be 2 characters longer than the size given because 16.1235 + * we need to put in 2 end-of-buffer characters. 16.1236 + */ 16.1237 + b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); 16.1238 + if ( ! b->yy_ch_buf ) 16.1239 + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); 16.1240 + 16.1241 + b->yy_is_our_buffer = 1; 16.1242 + 16.1243 + yy_init_buffer( b, file ); 16.1244 + 16.1245 + return b; 16.1246 + } 16.1247 + 16.1248 + 16.1249 +#ifdef YY_USE_PROTOS 16.1250 +void yy_delete_buffer( YY_BUFFER_STATE b ) 16.1251 +#else 16.1252 +void yy_delete_buffer( b ) 16.1253 +YY_BUFFER_STATE b; 16.1254 +#endif 16.1255 + { 16.1256 + if ( ! b ) 16.1257 + return; 16.1258 + 16.1259 + if ( b == yy_current_buffer ) 16.1260 + yy_current_buffer = (YY_BUFFER_STATE) 0; 16.1261 + 16.1262 + if ( b->yy_is_our_buffer ) 16.1263 + yy_flex_free( (void *) b->yy_ch_buf ); 16.1264 + 16.1265 + yy_flex_free( (void *) b ); 16.1266 + } 16.1267 + 16.1268 + 16.1269 + 16.1270 +#ifdef YY_USE_PROTOS 16.1271 +void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) 16.1272 +#else 16.1273 +void yy_init_buffer( b, file ) 16.1274 +YY_BUFFER_STATE b; 16.1275 +FILE *file; 16.1276 +#endif 16.1277 + 16.1278 + 16.1279 + { 16.1280 + yy_flush_buffer( b ); 16.1281 + 16.1282 + b->yy_input_file = file; 16.1283 + b->yy_fill_buffer = 1; 16.1284 + 16.1285 +#if YY_ALWAYS_INTERACTIVE 16.1286 + b->yy_is_interactive = 1; 16.1287 +#else 16.1288 +#if YY_NEVER_INTERACTIVE 16.1289 + b->yy_is_interactive = 0; 16.1290 +#else 16.1291 + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; 16.1292 +#endif 16.1293 +#endif 16.1294 + } 16.1295 + 16.1296 + 16.1297 +#ifdef YY_USE_PROTOS 16.1298 +void yy_flush_buffer( YY_BUFFER_STATE b ) 16.1299 +#else 16.1300 +void yy_flush_buffer( b ) 16.1301 +YY_BUFFER_STATE b; 16.1302 +#endif 16.1303 + 16.1304 + { 16.1305 + if ( ! b ) 16.1306 + return; 16.1307 + 16.1308 + b->yy_n_chars = 0; 16.1309 + 16.1310 + /* We always need two end-of-buffer characters. The first causes 16.1311 + * a transition to the end-of-buffer state. The second causes 16.1312 + * a jam in that state. 16.1313 + */ 16.1314 + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; 16.1315 + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; 16.1316 + 16.1317 + b->yy_buf_pos = &b->yy_ch_buf[0]; 16.1318 + 16.1319 + b->yy_at_bol = 1; 16.1320 + b->yy_buffer_status = YY_BUFFER_NEW; 16.1321 + 16.1322 + if ( b == yy_current_buffer ) 16.1323 + yy_load_buffer_state(); 16.1324 + } 16.1325 + 16.1326 + 16.1327 +#ifndef YY_NO_SCAN_BUFFER 16.1328 +#ifdef YY_USE_PROTOS 16.1329 +YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) 16.1330 +#else 16.1331 +YY_BUFFER_STATE yy_scan_buffer( base, size ) 16.1332 +char *base; 16.1333 +yy_size_t size; 16.1334 +#endif 16.1335 + { 16.1336 + YY_BUFFER_STATE b; 16.1337 + 16.1338 + if ( size < 2 || 16.1339 + base[size-2] != YY_END_OF_BUFFER_CHAR || 16.1340 + base[size-1] != YY_END_OF_BUFFER_CHAR ) 16.1341 + /* They forgot to leave room for the EOB's. */ 16.1342 + return 0; 16.1343 + 16.1344 + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); 16.1345 + if ( ! b ) 16.1346 + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); 16.1347 + 16.1348 + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ 16.1349 + b->yy_buf_pos = b->yy_ch_buf = base; 16.1350 + b->yy_is_our_buffer = 0; 16.1351 + b->yy_input_file = 0; 16.1352 + b->yy_n_chars = b->yy_buf_size; 16.1353 + b->yy_is_interactive = 0; 16.1354 + b->yy_at_bol = 1; 16.1355 + b->yy_fill_buffer = 0; 16.1356 + b->yy_buffer_status = YY_BUFFER_NEW; 16.1357 + 16.1358 + yy_switch_to_buffer( b ); 16.1359 + 16.1360 + return b; 16.1361 + } 16.1362 +#endif 16.1363 + 16.1364 + 16.1365 +#ifndef YY_NO_SCAN_STRING 16.1366 +#ifdef YY_USE_PROTOS 16.1367 +YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) 16.1368 +#else 16.1369 +YY_BUFFER_STATE yy_scan_string( yy_str ) 16.1370 +yyconst char *yy_str; 16.1371 +#endif 16.1372 + { 16.1373 + int len; 16.1374 + for ( len = 0; yy_str[len]; ++len ) 16.1375 + ; 16.1376 + 16.1377 + return yy_scan_bytes( yy_str, len ); 16.1378 + } 16.1379 +#endif 16.1380 + 16.1381 + 16.1382 +#ifndef YY_NO_SCAN_BYTES 16.1383 +#ifdef YY_USE_PROTOS 16.1384 +YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) 16.1385 +#else 16.1386 +YY_BUFFER_STATE yy_scan_bytes( bytes, len ) 16.1387 +yyconst char *bytes; 16.1388 +int len; 16.1389 +#endif 16.1390 + { 16.1391 + YY_BUFFER_STATE b; 16.1392 + char *buf; 16.1393 + yy_size_t n; 16.1394 + int i; 16.1395 + 16.1396 + /* Get memory for full buffer, including space for trailing EOB's. */ 16.1397 + n = len + 2; 16.1398 + buf = (char *) yy_flex_alloc( n ); 16.1399 + if ( ! buf ) 16.1400 + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); 16.1401 + 16.1402 + for ( i = 0; i < len; ++i ) 16.1403 + buf[i] = bytes[i]; 16.1404 + 16.1405 + buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; 16.1406 + 16.1407 + b = yy_scan_buffer( buf, n ); 16.1408 + if ( ! b ) 16.1409 + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); 16.1410 + 16.1411 + /* It's okay to grow etc. this buffer, and we should throw it 16.1412 + * away when we're done. 16.1413 + */ 16.1414 + b->yy_is_our_buffer = 1; 16.1415 + 16.1416 + return b; 16.1417 + } 16.1418 +#endif 16.1419 + 16.1420 + 16.1421 +#ifndef YY_NO_PUSH_STATE 16.1422 +#ifdef YY_USE_PROTOS 16.1423 +static void yy_push_state( int new_state ) 16.1424 +#else 16.1425 +static void yy_push_state( new_state ) 16.1426 +int new_state; 16.1427 +#endif 16.1428 + { 16.1429 + if ( yy_start_stack_ptr >= yy_start_stack_depth ) 16.1430 + { 16.1431 + yy_size_t new_size; 16.1432 + 16.1433 + yy_start_stack_depth += YY_START_STACK_INCR; 16.1434 + new_size = yy_start_stack_depth * sizeof( int ); 16.1435 + 16.1436 + if ( ! yy_start_stack ) 16.1437 + yy_start_stack = (int *) yy_flex_alloc( new_size ); 16.1438 + 16.1439 + else 16.1440 + yy_start_stack = (int *) yy_flex_realloc( 16.1441 + (void *) yy_start_stack, new_size ); 16.1442 + 16.1443 + if ( ! yy_start_stack ) 16.1444 + YY_FATAL_ERROR( 16.1445 + "out of memory expanding start-condition stack" ); 16.1446 + } 16.1447 + 16.1448 + yy_start_stack[yy_start_stack_ptr++] = YY_START; 16.1449 + 16.1450 + BEGIN(new_state); 16.1451 + } 16.1452 +#endif 16.1453 + 16.1454 + 16.1455 +#ifndef YY_NO_POP_STATE 16.1456 +static void yy_pop_state() 16.1457 + { 16.1458 + if ( --yy_start_stack_ptr < 0 ) 16.1459 + YY_FATAL_ERROR( "start-condition stack underflow" ); 16.1460 + 16.1461 + BEGIN(yy_start_stack[yy_start_stack_ptr]); 16.1462 + } 16.1463 +#endif 16.1464 + 16.1465 + 16.1466 +#ifndef YY_NO_TOP_STATE 16.1467 +static int yy_top_state() 16.1468 + { 16.1469 + return yy_start_stack[yy_start_stack_ptr - 1]; 16.1470 + } 16.1471 +#endif 16.1472 + 16.1473 +#ifndef YY_EXIT_FAILURE 16.1474 +#define YY_EXIT_FAILURE 2 16.1475 +#endif 16.1476 + 16.1477 +#ifdef YY_USE_PROTOS 16.1478 +static void yy_fatal_error( yyconst char msg[] ) 16.1479 +#else 16.1480 +static void yy_fatal_error( msg ) 16.1481 +char msg[]; 16.1482 +#endif 16.1483 + { 16.1484 + (void) fprintf( stderr, "%s\n", msg ); 16.1485 + exit( YY_EXIT_FAILURE ); 16.1486 + } 16.1487 + 16.1488 + 16.1489 + 16.1490 +/* Redefine yyless() so it works in section 3 code. */ 16.1491 + 16.1492 +#undef yyless 16.1493 +#define yyless(n) \ 16.1494 + do \ 16.1495 + { \ 16.1496 + /* Undo effects of setting up yytext. */ \ 16.1497 + yytext[yyleng] = yy_hold_char; \ 16.1498 + yy_c_buf_p = yytext + n; \ 16.1499 + yy_hold_char = *yy_c_buf_p; \ 16.1500 + *yy_c_buf_p = '\0'; \ 16.1501 + yyleng = n; \ 16.1502 + } \ 16.1503 + while ( 0 ) 16.1504 + 16.1505 + 16.1506 +/* Internal utility routines. */ 16.1507 + 16.1508 +#ifndef yytext_ptr 16.1509 +#ifdef YY_USE_PROTOS 16.1510 +static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) 16.1511 +#else 16.1512 +static void yy_flex_strncpy( s1, s2, n ) 16.1513 +char *s1; 16.1514 +yyconst char *s2; 16.1515 +int n; 16.1516 +#endif 16.1517 + { 16.1518 + register int i; 16.1519 + for ( i = 0; i < n; ++i ) 16.1520 + s1[i] = s2[i]; 16.1521 + } 16.1522 +#endif 16.1523 + 16.1524 +#ifdef YY_NEED_STRLEN 16.1525 +#ifdef YY_USE_PROTOS 16.1526 +static int yy_flex_strlen( yyconst char *s ) 16.1527 +#else 16.1528 +static int yy_flex_strlen( s ) 16.1529 +yyconst char *s; 16.1530 +#endif 16.1531 + { 16.1532 + register int n; 16.1533 + for ( n = 0; s[n]; ++n ) 16.1534 + ; 16.1535 + 16.1536 + return n; 16.1537 + } 16.1538 +#endif 16.1539 + 16.1540 + 16.1541 +#ifdef YY_USE_PROTOS 16.1542 +static void *yy_flex_alloc( yy_size_t size ) 16.1543 +#else 16.1544 +static void *yy_flex_alloc( size ) 16.1545 +yy_size_t size; 16.1546 +#endif 16.1547 + { 16.1548 + return (void *) malloc( size ); 16.1549 + } 16.1550 + 16.1551 +#ifdef YY_USE_PROTOS 16.1552 +static void *yy_flex_realloc( void *ptr, yy_size_t size ) 16.1553 +#else 16.1554 +static void *yy_flex_realloc( ptr, size ) 16.1555 +void *ptr; 16.1556 +yy_size_t size; 16.1557 +#endif 16.1558 + { 16.1559 + /* The cast to (char *) in the following accommodates both 16.1560 + * implementations that use char* generic pointers, and those 16.1561 + * that use void* generic pointers. It works with the latter 16.1562 + * because both ANSI C and C++ allow castless assignment from 16.1563 + * any pointer type to void*, and deal with argument conversions 16.1564 + * as though doing an assignment. 16.1565 + */ 16.1566 + return (void *) realloc( (char *) ptr, size ); 16.1567 + } 16.1568 + 16.1569 +#ifdef YY_USE_PROTOS 16.1570 +static void yy_flex_free( void *ptr ) 16.1571 +#else 16.1572 +static void yy_flex_free( ptr ) 16.1573 +void *ptr; 16.1574 +#endif 16.1575 + { 16.1576 + free( ptr ); 16.1577 + } 16.1578 + 16.1579 +#if YY_MAIN 16.1580 +int main() 16.1581 + { 16.1582 + yylex(); 16.1583 + return 0; 16.1584 + } 16.1585 +#endif 16.1586 +#line 65 "expr.l" 16.1587 + 16.1588 + 16.1589 +void exprCleanBuffer() 16.1590 +{ 16.1591 + yy_delete_buffer(yy_current_buffer); 16.1592 + yy_init = 1; 16.1593 +}
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 17.2 +++ b/src/sdl/expr.cpp Sun Mar 04 21:06:50 2012 -0600 17.3 @@ -0,0 +1,998 @@ 17.4 + 17.5 +/* A Bison parser, made from expr.y 17.6 + by GNU Bison version 1.28 */ 17.7 + 17.8 +#define YYBISON 1 /* Identify Bison output. */ 17.9 + 17.10 +#define TOKEN_IDENTIFIER 257 17.11 +#define TOKEN_DOT 258 17.12 +#define TOKEN_STAR 259 17.13 +#define TOKEN_ARROW 260 17.14 +#define TOKEN_ADDR 261 17.15 +#define TOKEN_SIZEOF 262 17.16 +#define TOKEN_NUMBER 263 17.17 + 17.18 +#line 1 "expr.y" 17.19 + 17.20 +namespace std { 17.21 +#include <stdio.h> 17.22 +#include <memory.h> 17.23 +#include <stdlib.h> 17.24 +#include <string.h> 17.25 +} 17.26 + 17.27 +using namespace std; 17.28 + 17.29 +#include "../common/System.h" 17.30 +#include "../gba/elf.h" 17.31 +#include "exprNode.h" 17.32 + 17.33 +extern int yyerror(char *); 17.34 +extern int yylex(); 17.35 +extern char *yytext; 17.36 + 17.37 + 17.38 +//#define YYERROR_VERBOSE 1 17.39 +//#define YYDEBUG 1 17.40 + 17.41 + Node *result = NULL; 17.42 +#ifndef YYSTYPE 17.43 +#define YYSTYPE int 17.44 +#endif 17.45 +#include <stdio.h> 17.46 + 17.47 +#ifndef __cplusplus 17.48 +#ifndef __STDC__ 17.49 +#define const 17.50 +#endif 17.51 +#endif 17.52 + 17.53 + 17.54 + 17.55 +#define YYFINAL 26 17.56 +#define YYFLAG -32768 17.57 +#define YYNTBASE 14 17.58 + 17.59 +#define YYTRANSLATE(x) ((unsigned)(x) <= 263 ? yytranslate[x] : 19) 17.60 + 17.61 +static const char yytranslate[] = { 0, 17.62 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17.63 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17.64 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17.65 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 11, 17.66 + 12, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17.67 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17.68 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17.69 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17.70 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17.71 + 10, 2, 13, 2, 2, 2, 2, 2, 2, 2, 17.72 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17.73 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17.74 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17.75 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17.76 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17.77 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17.78 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17.79 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17.80 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17.81 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17.82 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17.83 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17.84 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17.85 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17.86 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17.87 + 2, 2, 2, 2, 2, 1, 3, 4, 5, 6, 17.88 + 7, 8, 9 17.89 +}; 17.90 + 17.91 +#if YYDEBUG != 0 17.92 +static const short yyprhs[] = { 0, 17.93 + 0, 2, 4, 8, 12, 16, 21, 23, 26, 29, 17.94 + 34, 36 17.95 +}; 17.96 + 17.97 +static const short yyrhs[] = { 15, 17.98 + 0, 16, 0, 11, 15, 12, 0, 15, 4, 18, 17.99 + 0, 15, 6, 18, 0, 15, 10, 17, 13, 0, 17.100 + 18, 0, 5, 15, 0, 7, 15, 0, 8, 11, 17.101 + 15, 12, 0, 9, 0, 3, 0 17.102 +}; 17.103 + 17.104 +#endif 17.105 + 17.106 +#if YYDEBUG != 0 17.107 +static const short yyrline[] = { 0, 17.108 + 32, 35, 36, 37, 38, 39, 42, 43, 44, 45, 17.109 + 49, 53 17.110 +}; 17.111 +#endif 17.112 + 17.113 + 17.114 +#if YYDEBUG != 0 || defined (YYERROR_VERBOSE) 17.115 + 17.116 +static const char * const yytname[] = { "$","error","$undefined.","TOKEN_IDENTIFIER", 17.117 +"TOKEN_DOT","TOKEN_STAR","TOKEN_ARROW","TOKEN_ADDR","TOKEN_SIZEOF","TOKEN_NUMBER", 17.118 +"'['","'('","')'","']'","final","expression","simple_expression","number","ident", NULL 17.119 +}; 17.120 +#endif 17.121 + 17.122 +static const short yyr1[] = { 0, 17.123 + 14, 15, 15, 15, 15, 15, 16, 16, 16, 16, 17.124 + 17, 18 17.125 +}; 17.126 + 17.127 +static const short yyr2[] = { 0, 17.128 + 1, 1, 3, 3, 3, 4, 1, 2, 2, 4, 17.129 + 1, 1 17.130 +}; 17.131 + 17.132 +static const short yydefact[] = { 0, 17.133 + 12, 0, 0, 0, 0, 1, 2, 7, 8, 9, 17.134 + 0, 0, 0, 0, 0, 0, 3, 4, 5, 11, 17.135 + 0, 10, 6, 0, 0, 0 17.136 +}; 17.137 + 17.138 +static const short yydefgoto[] = { 24, 17.139 + 6, 7, 21, 8 17.140 +}; 17.141 + 17.142 +static const short yypact[] = { -1, 17.143 +-32768, -1, -1, -6, -1, 17,-32768,-32768, 17, 17, 17.144 + -1, 7, 5, 5, 13, 8,-32768,-32768,-32768,-32768, 17.145 + 11,-32768,-32768, 25, 26,-32768 17.146 +}; 17.147 + 17.148 +static const short yypgoto[] = {-32768, 17.149 + -2,-32768,-32768, 2 17.150 +}; 17.151 + 17.152 + 17.153 +#define YYLAST 27 17.154 + 17.155 + 17.156 +static const short yytable[] = { 9, 17.157 + 10, 1, 12, 2, 11, 3, 4, 1, 16, 5, 17.158 + 13, 13, 14, 14, 18, 19, 15, 15, 17, 22, 17.159 + 13, 20, 14, 23, 25, 26, 15 17.160 +}; 17.161 + 17.162 +static const short yycheck[] = { 2, 17.163 + 3, 3, 5, 5, 11, 7, 8, 3, 11, 11, 17.164 + 4, 4, 6, 6, 13, 14, 10, 10, 12, 12, 17.165 + 4, 9, 6, 13, 0, 0, 10 17.166 +}; 17.167 +/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ 17.168 +#line 3 "/usr/lib/bison.simple" 17.169 +/* This file comes from bison-1.28. */ 17.170 + 17.171 +/* Skeleton output parser for bison, 17.172 + Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. 17.173 + 17.174 + This program is free software; you can redistribute it and/or modify 17.175 + it under the terms of the GNU General Public License as published by 17.176 + the Free Software Foundation; either version 2, or (at your option) 17.177 + any later version. 17.178 + 17.179 + This program is distributed in the hope that it will be useful, 17.180 + but WITHOUT ANY WARRANTY; without even the implied warranty of 17.181 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17.182 + GNU General Public License for more details. 17.183 + 17.184 + You should have received a copy of the GNU General Public License 17.185 + along with this program; if not, write to the Free Software 17.186 + Foundation, Inc., 59 Temple Place - Suite 330, 17.187 + Boston, MA 02111-1307, USA. */ 17.188 + 17.189 +/* As a special exception, when this file is copied by Bison into a 17.190 + Bison output file, you may use that output file without restriction. 17.191 + This special exception was added by the Free Software Foundation 17.192 + in version 1.24 of Bison. */ 17.193 + 17.194 +/* This is the parser code that is written into each bison parser 17.195 + when the %semantic_parser declaration is not specified in the grammar. 17.196 + It was written by Richard Stallman by simplifying the hairy parser 17.197 + used when %semantic_parser is specified. */ 17.198 + 17.199 +#ifndef YYSTACK_USE_ALLOCA 17.200 +#ifdef alloca 17.201 +#define YYSTACK_USE_ALLOCA 17.202 +#else /* alloca not defined */ 17.203 +#ifdef __GNUC__ 17.204 +#define YYSTACK_USE_ALLOCA 17.205 +#define alloca __builtin_alloca 17.206 +#else /* not GNU C. */ 17.207 +#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386)) 17.208 +#define YYSTACK_USE_ALLOCA 17.209 +#include <alloca.h> 17.210 +#else /* not sparc */ 17.211 +/* We think this test detects Watcom and Microsoft C. */ 17.212 +/* This used to test MSDOS, but that is a bad idea 17.213 + since that symbol is in the user namespace. */ 17.214 +#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__) 17.215 +#if 0 /* No need for malloc.h, which pollutes the namespace; 17.216 + instead, just don't use alloca. */ 17.217 +#include <malloc.h> 17.218 +#endif 17.219 +#else /* not MSDOS, or __TURBOC__ */ 17.220 +#if defined(_AIX) 17.221 +/* I don't know what this was needed for, but it pollutes the namespace. 17.222 + So I turned it off. rms, 2 May 1997. */ 17.223 +/* #include <malloc.h> */ 17.224 + #pragma alloca 17.225 +#define YYSTACK_USE_ALLOCA 17.226 +#else /* not MSDOS, or __TURBOC__, or _AIX */ 17.227 +#if 0 17.228 +#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up, 17.229 + and on HPUX 10. Eventually we can turn this on. */ 17.230 +#define YYSTACK_USE_ALLOCA 17.231 +#define alloca __builtin_alloca 17.232 +#endif /* __hpux */ 17.233 +#endif 17.234 +#endif /* not _AIX */ 17.235 +#endif /* not MSDOS, or __TURBOC__ */ 17.236 +#endif /* not sparc */ 17.237 +#endif /* not GNU C */ 17.238 +#endif /* alloca not defined */ 17.239 +#endif /* YYSTACK_USE_ALLOCA not defined */ 17.240 + 17.241 +#ifdef YYSTACK_USE_ALLOCA 17.242 +#define YYSTACK_ALLOC alloca 17.243 +#else 17.244 +#define YYSTACK_ALLOC malloc 17.245 +#endif 17.246 + 17.247 +/* Note: there must be only one dollar sign in this file. 17.248 + It is replaced by the list of actions, each action 17.249 + as one case of the switch. */ 17.250 + 17.251 +#define yyerrok (yyerrstatus = 0) 17.252 +#define yyclearin (yychar = YYEMPTY) 17.253 +#define YYEMPTY -2 17.254 +#define YYEOF 0 17.255 +#define YYACCEPT goto yyacceptlab 17.256 +#define YYABORT goto yyabortlab 17.257 +#define YYERROR goto yyerrlab1 17.258 +/* Like YYERROR except do call yyerror. 17.259 + This remains here temporarily to ease the 17.260 + transition to the new meaning of YYERROR, for GCC. 17.261 + Once GCC version 2 has supplanted version 1, this can go. */ 17.262 +#define YYFAIL goto yyerrlab 17.263 +#define YYRECOVERING() (!!yyerrstatus) 17.264 +#define YYBACKUP(token, value) \ 17.265 +do \ 17.266 + if (yychar == YYEMPTY && yylen == 1) \ 17.267 + { yychar = (token), yylval = (value); \ 17.268 + yychar1 = YYTRANSLATE (yychar); \ 17.269 + YYPOPSTACK; \ 17.270 + goto yybackup; \ 17.271 + } \ 17.272 + else \ 17.273 + { yyerror ("syntax error: cannot back up"); YYERROR; } \ 17.274 +while (0) 17.275 + 17.276 +#define YYTERROR 1 17.277 +#define YYERRCODE 256 17.278 + 17.279 +#ifndef YYPURE 17.280 +#define YYLEX yylex() 17.281 +#endif 17.282 + 17.283 +#ifdef YYPURE 17.284 +#ifdef YYLSP_NEEDED 17.285 +#ifdef YYLEX_PARAM 17.286 +#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) 17.287 +#else 17.288 +#define YYLEX yylex(&yylval, &yylloc) 17.289 +#endif 17.290 +#else /* not YYLSP_NEEDED */ 17.291 +#ifdef YYLEX_PARAM 17.292 +#define YYLEX yylex(&yylval, YYLEX_PARAM) 17.293 +#else 17.294 +#define YYLEX yylex(&yylval) 17.295 +#endif 17.296 +#endif /* not YYLSP_NEEDED */ 17.297 +#endif 17.298 + 17.299 +/* If nonreentrant, generate the variables here */ 17.300 + 17.301 +#ifndef YYPURE 17.302 + 17.303 +int yychar; /* the lookahead symbol */ 17.304 +YYSTYPE yylval; /* the semantic value of the */ 17.305 + /* lookahead symbol */ 17.306 + 17.307 +#ifdef YYLSP_NEEDED 17.308 +YYLTYPE yylloc; /* location data for the lookahead */ 17.309 + /* symbol */ 17.310 +#endif 17.311 + 17.312 +int yynerrs; /* number of parse errors so far */ 17.313 +#endif /* not YYPURE */ 17.314 + 17.315 +#if YYDEBUG != 0 17.316 +int yydebug; /* nonzero means print parse trace */ 17.317 +/* Since this is uninitialized, it does not stop multiple parsers 17.318 + from coexisting. */ 17.319 +#endif 17.320 + 17.321 +/* YYINITDEPTH indicates the initial size of the parser's stacks */ 17.322 + 17.323 +#ifndef YYINITDEPTH 17.324 +#define YYINITDEPTH 200 17.325 +#endif 17.326 + 17.327 +/* YYMAXDEPTH is the maximum size the stacks can grow to 17.328 + (effective only if the built-in stack extension method is used). */ 17.329 + 17.330 +#if YYMAXDEPTH == 0 17.331 +#undef YYMAXDEPTH 17.332 +#endif 17.333 + 17.334 +#ifndef YYMAXDEPTH 17.335 +#define YYMAXDEPTH 10000 17.336 +#endif 17.337 + 17.338 +/* Define __yy_memcpy. Note that the size argument 17.339 + should be passed with type unsigned int, because that is what the non-GCC 17.340 + definitions require. With GCC, __builtin_memcpy takes an arg 17.341 + of type size_t, but it can handle unsigned int. */ 17.342 + 17.343 +#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ 17.344 +#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT) 17.345 +#else /* not GNU C or C++ */ 17.346 +#ifndef __cplusplus 17.347 + 17.348 +/* This is the most reliable way to avoid incompatibilities 17.349 + in available built-in functions on various systems. */ 17.350 +static void 17.351 +__yy_memcpy (to, from, count) 17.352 + char *to; 17.353 + char *from; 17.354 + unsigned int count; 17.355 +{ 17.356 + register char *f = from; 17.357 + register char *t = to; 17.358 + register int i = count; 17.359 + 17.360 + while (i-- > 0) 17.361 + *t++ = *f++; 17.362 +} 17.363 + 17.364 +#else /* __cplusplus */ 17.365 + 17.366 +/* This is the most reliable way to avoid incompatibilities 17.367 + in available built-in functions on various systems. */ 17.368 +static void 17.369 +__yy_memcpy (char *to, char *from, unsigned int count) 17.370 +{ 17.371 + register char *t = to; 17.372 + register char *f = from; 17.373 + register int i = count; 17.374 + 17.375 + while (i-- > 0) 17.376 + *t++ = *f++; 17.377 +} 17.378 + 17.379 +#endif 17.380 +#endif 17.381 + 17.382 +#line 217 "/usr/lib/bison.simple" 17.383 + 17.384 +/* The user can define YYPARSE_PARAM as the name of an argument to be passed 17.385 + into yyparse. The argument should have type void *. 17.386 + It should actually point to an object. 17.387 + Grammar actions can access the variable by casting it 17.388 + to the proper pointer type. */ 17.389 + 17.390 +#ifdef YYPARSE_PARAM 17.391 +#ifdef __cplusplus 17.392 +#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM 17.393 +#define YYPARSE_PARAM_DECL 17.394 +#else /* not __cplusplus */ 17.395 +#define YYPARSE_PARAM_ARG YYPARSE_PARAM 17.396 +#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; 17.397 +#endif /* not __cplusplus */ 17.398 +#else /* not YYPARSE_PARAM */ 17.399 +#define YYPARSE_PARAM_ARG 17.400 +#define YYPARSE_PARAM_DECL 17.401 +#endif /* not YYPARSE_PARAM */ 17.402 + 17.403 +/* Prevent warning if -Wstrict-prototypes. */ 17.404 +#ifdef __GNUC__ 17.405 +#ifdef YYPARSE_PARAM 17.406 +int yyparse (void *); 17.407 +#else 17.408 +int yyparse (void); 17.409 +#endif 17.410 +#endif 17.411 + 17.412 +int 17.413 +yyparse(YYPARSE_PARAM_ARG) 17.414 + YYPARSE_PARAM_DECL 17.415 +{ 17.416 + register int yystate; 17.417 + register int yyn; 17.418 + register short *yyssp; 17.419 + register YYSTYPE *yyvsp; 17.420 + int yyerrstatus; /* number of tokens to shift before error messages enabled */ 17.421 + int yychar1 = 0; /* lookahead token as an internal (translated) token number */ 17.422 + 17.423 + short yyssa[YYINITDEPTH]; /* the state stack */ 17.424 + YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ 17.425 + 17.426 + short *yyss = yyssa; /* refer to the stacks thru separate pointers */ 17.427 + YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ 17.428 + 17.429 +#ifdef YYLSP_NEEDED 17.430 + YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ 17.431 + YYLTYPE *yyls = yylsa; 17.432 + YYLTYPE *yylsp; 17.433 + 17.434 +#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) 17.435 +#else 17.436 +#define YYPOPSTACK (yyvsp--, yyssp--) 17.437 +#endif 17.438 + 17.439 + int yystacksize = YYINITDEPTH; 17.440 + int yyfree_stacks = 0; 17.441 + 17.442 +#ifdef YYPURE 17.443 + int yychar; 17.444 + YYSTYPE yylval; 17.445 + int yynerrs; 17.446 +#ifdef YYLSP_NEEDED 17.447 + YYLTYPE yylloc; 17.448 +#endif 17.449 +#endif 17.450 + 17.451 + YYSTYPE yyval; /* the variable used to return */ 17.452 + /* semantic values from the action */ 17.453 + /* routines */ 17.454 + 17.455 + int yylen; 17.456 + 17.457 +#if YYDEBUG != 0 17.458 + if (yydebug) 17.459 + fprintf(stderr, "Starting parse\n"); 17.460 +#endif 17.461 + 17.462 + yystate = 0; 17.463 + yyerrstatus = 0; 17.464 + yynerrs = 0; 17.465 + yychar = YYEMPTY; /* Cause a token to be read. */ 17.466 + 17.467 + /* Initialize stack pointers. 17.468 + Waste one element of value and location stack 17.469 + so that they stay on the same level as the state stack. 17.470 + The wasted elements are never initialized. */ 17.471 + 17.472 + yyssp = yyss - 1; 17.473 + yyvsp = yyvs; 17.474 +#ifdef YYLSP_NEEDED 17.475 + yylsp = yyls; 17.476 +#endif 17.477 + 17.478 +/* Push a new state, which is found in yystate . */ 17.479 +/* In all cases, when you get here, the value and location stacks 17.480 + have just been pushed. so pushing a state here evens the stacks. */ 17.481 +yynewstate: 17.482 + 17.483 + *++yyssp = yystate; 17.484 + 17.485 + if (yyssp >= yyss + yystacksize - 1) 17.486 + { 17.487 + /* Give user a chance to reallocate the stack */ 17.488 + /* Use copies of these so that the &'s don't force the real ones into memory. */ 17.489 + YYSTYPE *yyvs1 = yyvs; 17.490 + short *yyss1 = yyss; 17.491 +#ifdef YYLSP_NEEDED 17.492 + YYLTYPE *yyls1 = yyls; 17.493 +#endif 17.494 + 17.495 + /* Get the current used size of the three stacks, in elements. */ 17.496 + int size = yyssp - yyss + 1; 17.497 + 17.498 +#ifdef yyoverflow 17.499 + /* Each stack pointer address is followed by the size of 17.500 + the data in use in that stack, in bytes. */ 17.501 +#ifdef YYLSP_NEEDED 17.502 + /* This used to be a conditional around just the two extra args, 17.503 + but that might be undefined if yyoverflow is a macro. */ 17.504 + yyoverflow("parser stack overflow", 17.505 + &yyss1, size * sizeof (*yyssp), 17.506 + &yyvs1, size * sizeof (*yyvsp), 17.507 + &yyls1, size * sizeof (*yylsp), 17.508 + &yystacksize); 17.509 +#else 17.510 + yyoverflow("parser stack overflow", 17.511 + &yyss1, size * sizeof (*yyssp), 17.512 + &yyvs1, size * sizeof (*yyvsp), 17.513 + &yystacksize); 17.514 +#endif 17.515 + 17.516 + yyss = yyss1; yyvs = yyvs1; 17.517 +#ifdef YYLSP_NEEDED 17.518 + yyls = yyls1; 17.519 +#endif 17.520 +#else /* no yyoverflow */ 17.521 + /* Extend the stack our own way. */ 17.522 + if (yystacksize >= YYMAXDEPTH) 17.523 + { 17.524 + yyerror("parser stack overflow"); 17.525 + if (yyfree_stacks) 17.526 + { 17.527 + free (yyss); 17.528 + free (yyvs); 17.529 +#ifdef YYLSP_NEEDED 17.530 + free (yyls); 17.531 +#endif 17.532 + } 17.533 + return 2; 17.534 + } 17.535 + yystacksize *= 2; 17.536 + if (yystacksize > YYMAXDEPTH) 17.537 + yystacksize = YYMAXDEPTH; 17.538 +#ifndef YYSTACK_USE_ALLOCA 17.539 + yyfree_stacks = 1; 17.540 +#endif 17.541 + yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp)); 17.542 + __yy_memcpy ((char *)yyss, (char *)yyss1, 17.543 + size * (unsigned int) sizeof (*yyssp)); 17.544 + yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp)); 17.545 + __yy_memcpy ((char *)yyvs, (char *)yyvs1, 17.546 + size * (unsigned int) sizeof (*yyvsp)); 17.547 +#ifdef YYLSP_NEEDED 17.548 + yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp)); 17.549 + __yy_memcpy ((char *)yyls, (char *)yyls1, 17.550 + size * (unsigned int) sizeof (*yylsp)); 17.551 +#endif 17.552 +#endif /* no yyoverflow */ 17.553 + 17.554 + yyssp = yyss + size - 1; 17.555 + yyvsp = yyvs + size - 1; 17.556 +#ifdef YYLSP_NEEDED 17.557 + yylsp = yyls + size - 1; 17.558 +#endif 17.559 + 17.560 +#if YYDEBUG != 0 17.561 + if (yydebug) 17.562 + fprintf(stderr, "Stack size increased to %d\n", yystacksize); 17.563 +#endif 17.564 + 17.565 + if (yyssp >= yyss + yystacksize - 1) 17.566 + YYABORT; 17.567 + } 17.568 + 17.569 +#if YYDEBUG != 0 17.570 + if (yydebug) 17.571 + fprintf(stderr, "Entering state %d\n", yystate); 17.572 +#endif 17.573 + 17.574 + goto yybackup; 17.575 + yybackup: 17.576 + 17.577 +/* Do appropriate processing given the current state. */ 17.578 +/* Read a lookahead token if we need one and don't already have one. */ 17.579 +/* yyresume: */ 17.580 + 17.581 + /* First try to decide what to do without reference to lookahead token. */ 17.582 + 17.583 + yyn = yypact[yystate]; 17.584 + if (yyn == YYFLAG) 17.585 + goto yydefault; 17.586 + 17.587 + /* Not known => get a lookahead token if don't already have one. */ 17.588 + 17.589 + /* yychar is either YYEMPTY or YYEOF 17.590 + or a valid token in external form. */ 17.591 + 17.592 + if (yychar == YYEMPTY) 17.593 + { 17.594 +#if YYDEBUG != 0 17.595 + if (yydebug) 17.596 + fprintf(stderr, "Reading a token: "); 17.597 +#endif 17.598 + yychar = YYLEX; 17.599 + } 17.600 + 17.601 + /* Convert token to internal form (in yychar1) for indexing tables with */ 17.602 + 17.603 + if (yychar <= 0) /* This means end of input. */ 17.604 + { 17.605 + yychar1 = 0; 17.606 + yychar = YYEOF; /* Don't call YYLEX any more */ 17.607 + 17.608 +#if YYDEBUG != 0 17.609 + if (yydebug) 17.610 + fprintf(stderr, "Now at end of input.\n"); 17.611 +#endif 17.612 + } 17.613 + else 17.614 + { 17.615 + yychar1 = YYTRANSLATE(yychar); 17.616 + 17.617 +#if YYDEBUG != 0 17.618 + if (yydebug) 17.619 + { 17.620 + fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); 17.621 + /* Give the individual parser a way to print the precise meaning 17.622 + of a token, for further debugging info. */ 17.623 +#ifdef YYPRINT 17.624 + YYPRINT (stderr, yychar, yylval); 17.625 +#endif 17.626 + fprintf (stderr, ")\n"); 17.627 + } 17.628 +#endif 17.629 + } 17.630 + 17.631 + yyn += yychar1; 17.632 + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) 17.633 + goto yydefault; 17.634 + 17.635 + yyn = yytable[yyn]; 17.636 + 17.637 + /* yyn is what to do for this token type in this state. 17.638 + Negative => reduce, -yyn is rule number. 17.639 + Positive => shift, yyn is new state. 17.640 + New state is final state => don't bother to shift, 17.641 + just return success. 17.642 + 0, or most negative number => error. */ 17.643 + 17.644 + if (yyn < 0) 17.645 + { 17.646 + if (yyn == YYFLAG) 17.647 + goto yyerrlab; 17.648 + yyn = -yyn; 17.649 + goto yyreduce; 17.650 + } 17.651 + else if (yyn == 0) 17.652 + goto yyerrlab; 17.653 + 17.654 + if (yyn == YYFINAL) 17.655 + YYACCEPT; 17.656 + 17.657 + /* Shift the lookahead token. */ 17.658 + 17.659 +#if YYDEBUG != 0 17.660 + if (yydebug) 17.661 + fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); 17.662 +#endif 17.663 + 17.664 + /* Discard the token being shifted unless it is eof. */ 17.665 + if (yychar != YYEOF) 17.666 + yychar = YYEMPTY; 17.667 + 17.668 + *++yyvsp = yylval; 17.669 +#ifdef YYLSP_NEEDED 17.670 + *++yylsp = yylloc; 17.671 +#endif 17.672 + 17.673 + /* count tokens shifted since error; after three, turn off error status. */ 17.674 + if (yyerrstatus) yyerrstatus--; 17.675 + 17.676 + yystate = yyn; 17.677 + goto yynewstate; 17.678 + 17.679 +/* Do the default action for the current state. */ 17.680 +yydefault: 17.681 + 17.682 + yyn = yydefact[yystate]; 17.683 + if (yyn == 0) 17.684 + goto yyerrlab; 17.685 + 17.686 +/* Do a reduction. yyn is the number of a rule to reduce with. */ 17.687 +yyreduce: 17.688 + yylen = yyr2[yyn]; 17.689 + if (yylen > 0) 17.690 + yyval = yyvsp[1-yylen]; /* implement default value of the action */ 17.691 + 17.692 +#if YYDEBUG != 0 17.693 + if (yydebug) 17.694 + { 17.695 + int i; 17.696 + 17.697 + fprintf (stderr, "Reducing via rule %d (line %d), ", 17.698 + yyn, yyrline[yyn]); 17.699 + 17.700 + /* Print the symbols being reduced, and their result. */ 17.701 + for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) 17.702 + fprintf (stderr, "%s ", yytname[yyrhs[i]]); 17.703 + fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); 17.704 + } 17.705 +#endif 17.706 + 17.707 + 17.708 + switch (yyn) { 17.709 + 17.710 +case 1: 17.711 +#line 32 "expr.y" 17.712 +{ result = yyvsp[0]; ; 17.713 + break;} 17.714 +case 2: 17.715 +#line 36 "expr.y" 17.716 +{ yyval = yyvsp[0]; ; 17.717 + break;} 17.718 +case 3: 17.719 +#line 37 "expr.y" 17.720 +{ yyval = yyvsp[-1]; ; 17.721 + break;} 17.722 +case 4: 17.723 +#line 38 "expr.y" 17.724 +{ yyval = exprNodeDot(yyvsp[-2], yyvsp[0]); ; 17.725 + break;} 17.726 +case 5: 17.727 +#line 39 "expr.y" 17.728 +{ yyval = exprNodeArrow(yyvsp[-2], yyvsp[0]); ; 17.729 + break;} 17.730 +case 6: 17.731 +#line 40 "expr.y" 17.732 +{ yyval = exprNodeArray(yyvsp[-3], yyvsp[-1]); ; 17.733 + break;} 17.734 +case 7: 17.735 +#line 43 "expr.y" 17.736 +{ yyval = yyvsp[0]; ; 17.737 + break;} 17.738 +case 8: 17.739 +#line 44 "expr.y" 17.740 +{ yyval = exprNodeStar(yyvsp[0]); ; 17.741 + break;} 17.742 +case 9: 17.743 +#line 45 "expr.y" 17.744 +{ yyval = exprNodeAddr(yyvsp[0]); ; 17.745 + break;} 17.746 +case 10: 17.747 +#line 46 "expr.y" 17.748 +{ yyval = exprNodeSizeof(yyvsp[-1]); ; 17.749 + break;} 17.750 +case 11: 17.751 +#line 50 "expr.y" 17.752 +{ yyval = exprNodeNumber(); ; 17.753 + break;} 17.754 +case 12: 17.755 +#line 54 "expr.y" 17.756 +{yyval = exprNodeIdentifier(); ; 17.757 + break;} 17.758 +} 17.759 + /* the action file gets copied in in place of this dollarsign */ 17.760 +#line 543 "/usr/lib/bison.simple" 17.761 + 17.762 + yyvsp -= yylen; 17.763 + yyssp -= yylen; 17.764 +#ifdef YYLSP_NEEDED 17.765 + yylsp -= yylen; 17.766 +#endif 17.767 + 17.768 +#if YYDEBUG != 0 17.769 + if (yydebug) 17.770 + { 17.771 + short *ssp1 = yyss - 1; 17.772 + fprintf (stderr, "state stack now"); 17.773 + while (ssp1 != yyssp) 17.774 + fprintf (stderr, " %d", *++ssp1); 17.775 + fprintf (stderr, "\n"); 17.776 + } 17.777 +#endif 17.778 + 17.779 + *++yyvsp = yyval; 17.780 + 17.781 +#ifdef YYLSP_NEEDED 17.782 + yylsp++; 17.783 + if (yylen == 0) 17.784 + { 17.785 + yylsp->first_line = yylloc.first_line; 17.786 + yylsp->first_column = yylloc.first_column; 17.787 + yylsp->last_line = (yylsp-1)->last_line; 17.788 + yylsp->last_column = (yylsp-1)->last_column; 17.789 + yylsp->text = 0; 17.790 + } 17.791 + else 17.792 + { 17.793 + yylsp->last_line = (yylsp+yylen-1)->last_line; 17.794 + yylsp->last_column = (yylsp+yylen-1)->last_column; 17.795 + } 17.796 +#endif 17.797 + 17.798 + /* Now "shift" the result of the reduction. 17.799 + Determine what state that goes to, 17.800 + based on the state we popped back to 17.801 + and the rule number reduced by. */ 17.802 + 17.803 + yyn = yyr1[yyn]; 17.804 + 17.805 + yystate = yypgoto[yyn - YYNTBASE] + *yyssp; 17.806 + if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) 17.807 + yystate = yytable[yystate]; 17.808 + else 17.809 + yystate = yydefgoto[yyn - YYNTBASE]; 17.810 + 17.811 + goto yynewstate; 17.812 + 17.813 +yyerrlab: /* here on detecting error */ 17.814 + 17.815 + if (! yyerrstatus) 17.816 + /* If not already recovering from an error, report this error. */ 17.817 + { 17.818 + ++yynerrs; 17.819 + 17.820 +#ifdef YYERROR_VERBOSE 17.821 + yyn = yypact[yystate]; 17.822 + 17.823 + if (yyn > YYFLAG && yyn < YYLAST) 17.824 + { 17.825 + int size = 0; 17.826 + char *msg; 17.827 + int x, count; 17.828 + 17.829 + count = 0; 17.830 + /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ 17.831 + for (x = (yyn < 0 ? -yyn : 0); 17.832 + x < (sizeof(yytname) / sizeof(char *)); x++) 17.833 + if (yycheck[x + yyn] == x) 17.834 + size += strlen(yytname[x]) + 15, count++; 17.835 + msg = (char *) malloc(size + 15); 17.836 + if (msg != 0) 17.837 + { 17.838 + strcpy(msg, "parse error"); 17.839 + 17.840 + if (count < 5) 17.841 + { 17.842 + count = 0; 17.843 + for (x = (yyn < 0 ? -yyn : 0); 17.844 + x < (sizeof(yytname) / sizeof(char *)); x++) 17.845 + if (yycheck[x + yyn] == x) 17.846 + { 17.847 + strcat(msg, count == 0 ? ", expecting `" : " or `"); 17.848 + strcat(msg, yytname[x]); 17.849 + strcat(msg, "'"); 17.850 + count++; 17.851 + } 17.852 + } 17.853 + yyerror(msg); 17.854 + free(msg); 17.855 + } 17.856 + else 17.857 + yyerror ("parse error; also virtual memory exceeded"); 17.858 + } 17.859 + else 17.860 +#endif /* YYERROR_VERBOSE */ 17.861 + yyerror("parse error"); 17.862 + } 17.863 + 17.864 + goto yyerrlab1; 17.865 +yyerrlab1: /* here on error raised explicitly by an action */ 17.866 + 17.867 + if (yyerrstatus == 3) 17.868 + { 17.869 + /* if just tried and failed to reuse lookahead token after an error, discard it. */ 17.870 + 17.871 + /* return failure if at end of input */ 17.872 + if (yychar == YYEOF) 17.873 + YYABORT; 17.874 + 17.875 +#if YYDEBUG != 0 17.876 + if (yydebug) 17.877 + fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); 17.878 +#endif 17.879 + 17.880 + yychar = YYEMPTY; 17.881 + } 17.882 + 17.883 + /* Else will try to reuse lookahead token 17.884 + after shifting the error token. */ 17.885 + 17.886 + yyerrstatus = 3; /* Each real token shifted decrements this */ 17.887 + 17.888 + goto yyerrhandle; 17.889 + 17.890 +yyerrdefault: /* current state does not do anything special for the error token. */ 17.891 + 17.892 +#if 0 17.893 + /* This is wrong; only states that explicitly want error tokens 17.894 + should shift them. */ 17.895 + yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ 17.896 + if (yyn) goto yydefault; 17.897 +#endif 17.898 + 17.899 +yyerrpop: /* pop the current state because it cannot handle the error token */ 17.900 + 17.901 + if (yyssp == yyss) YYABORT; 17.902 + yyvsp--; 17.903 + yystate = *--yyssp; 17.904 +#ifdef YYLSP_NEEDED 17.905 + yylsp--; 17.906 +#endif 17.907 + 17.908 +#if YYDEBUG != 0 17.909 + if (yydebug) 17.910 + { 17.911 + short *ssp1 = yyss - 1; 17.912 + fprintf (stderr, "Error: state stack now"); 17.913 + while (ssp1 != yyssp) 17.914 + fprintf (stderr, " %d", *++ssp1); 17.915 + fprintf (stderr, "\n"); 17.916 + } 17.917 +#endif 17.918 + 17.919 +yyerrhandle: 17.920 + 17.921 + yyn = yypact[yystate]; 17.922 + if (yyn == YYFLAG) 17.923 + goto yyerrdefault; 17.924 + 17.925 + yyn += YYTERROR; 17.926 + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) 17.927 + goto yyerrdefault; 17.928 + 17.929 + yyn = yytable[yyn]; 17.930 + if (yyn < 0) 17.931 + { 17.932 + if (yyn == YYFLAG) 17.933 + goto yyerrpop; 17.934 + yyn = -yyn; 17.935 + goto yyreduce; 17.936 + } 17.937 + else if (yyn == 0) 17.938 + goto yyerrpop; 17.939 + 17.940 + if (yyn == YYFINAL) 17.941 + YYACCEPT; 17.942 + 17.943 +#if YYDEBUG != 0 17.944 + if (yydebug) 17.945 + fprintf(stderr, "Shifting error token, "); 17.946 +#endif 17.947 + 17.948 + *++yyvsp = yylval; 17.949 +#ifdef YYLSP_NEEDED 17.950 + *++yylsp = yylloc; 17.951 +#endif 17.952 + 17.953 + yystate = yyn; 17.954 + goto yynewstate; 17.955 + 17.956 + yyacceptlab: 17.957 + /* YYACCEPT comes here. */ 17.958 + if (yyfree_stacks) 17.959 + { 17.960 + free (yyss); 17.961 + free (yyvs); 17.962 +#ifdef YYLSP_NEEDED 17.963 + free (yyls); 17.964 +#endif 17.965 + } 17.966 + return 0; 17.967 + 17.968 + yyabortlab: 17.969 + /* YYABORT comes here. */ 17.970 + if (yyfree_stacks) 17.971 + { 17.972 + free (yyss); 17.973 + free (yyvs); 17.974 +#ifdef YYLSP_NEEDED 17.975 + free (yyls); 17.976 +#endif 17.977 + } 17.978 + return 1; 17.979 +} 17.980 +#line 57 "expr.y" 17.981 + 17.982 + 17.983 +int yyerror(char *s) 17.984 +{ 17.985 + return 0; 17.986 +} 17.987 + 17.988 +#ifndef SDL 17.989 +extern FILE *yyin; 17.990 +int main(int argc, char **argv) 17.991 +{ 17.992 + // yydebug = 1; 17.993 + ++argv, --argc; 17.994 + if(argc > 0) 17.995 + yyin = fopen(argv[0], "r"); 17.996 + else 17.997 + yyin = stdin; 17.998 + if(!yyparse()) 17.999 + result->print(); 17.1000 +} 17.1001 +#endif
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 18.2 +++ b/src/sdl/expr.cpp.h Sun Mar 04 21:06:50 2012 -0600 18.3 @@ -0,0 +1,13 @@ 18.4 +#ifndef YYSTYPE 18.5 +#define YYSTYPE int 18.6 +#endif 18.7 +#define TOKEN_IDENTIFIER 257 18.8 +#define TOKEN_DOT 258 18.9 +#define TOKEN_STAR 259 18.10 +#define TOKEN_ARROW 260 18.11 +#define TOKEN_ADDR 261 18.12 +#define TOKEN_SIZEOF 262 18.13 +#define TOKEN_NUMBER 263 18.14 + 18.15 + 18.16 +extern YYSTYPE yylval;
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 19.2 +++ b/src/sdl/expr.l Sun Mar 04 21:06:50 2012 -0600 19.3 @@ -0,0 +1,71 @@ 19.4 +%{ 19.5 +#include "expr.cpp.h" 19.6 + 19.7 +#ifndef __GNUC__ 19.8 +#include <io.h> 19.9 +#define isatty _isatty 19.10 +#endif 19.11 + 19.12 +char *exprString; 19.13 +int exprCol; 19.14 + 19.15 +#define YY_INPUT(buf,result,max_size) \ 19.16 + { \ 19.17 + int c = *exprString++; \ 19.18 + exprCol++;\ 19.19 + result = (c == 0) ? YY_NULL : (buf[0] = c, 1); \ 19.20 + } 19.21 +%} 19.22 + 19.23 +%option nomain 19.24 +%option noyywrap 19.25 + 19.26 +SIZEOF "sizeof" 19.27 +ID [a-zA-Z_][a-zA-Z0-9_]* 19.28 +NUM [0-9]+ 19.29 +DOT "." 19.30 +ARROW "->" 19.31 +STAR "*" 19.32 +ADDR "&" 19.33 + 19.34 +%% 19.35 + 19.36 +{SIZEOF} { 19.37 + return TOKEN_SIZEOF; 19.38 +} 19.39 + 19.40 +{ID} { 19.41 + return TOKEN_IDENTIFIER; 19.42 +} 19.43 + 19.44 +{NUM} { 19.45 + return TOKEN_NUMBER; 19.46 +} 19.47 + 19.48 +{DOT} { 19.49 + return TOKEN_DOT; 19.50 +} 19.51 + 19.52 +{ARROW} { 19.53 + return TOKEN_ARROW; 19.54 +} 19.55 + 19.56 +{ADDR} { 19.57 + return TOKEN_ADDR; 19.58 +} 19.59 + 19.60 +{STAR} { 19.61 + return TOKEN_STAR; 19.62 +} 19.63 + 19.64 +[ \t\n]+ 19.65 + 19.66 +. return *yytext; 19.67 + 19.68 +%% 19.69 + 19.70 +void exprCleanBuffer() 19.71 +{ 19.72 + yy_delete_buffer(yy_current_buffer); 19.73 + yy_init = 1; 19.74 +}
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/src/sdl/expr.y Sun Mar 04 21:06:50 2012 -0600 20.3 @@ -0,0 +1,77 @@ 20.4 +%{ 20.5 +namespace std { 20.6 +#include <stdio.h> 20.7 +#include <memory.h> 20.8 +#include <stdlib.h> 20.9 +#include <string.h> 20.10 +} 20.11 + 20.12 +using namespace std; 20.13 + 20.14 +#include "System.h" 20.15 +#include "elf.h" 20.16 +#include "exprNode.h" 20.17 + 20.18 +extern int yyerror(char *); 20.19 +extern int yylex(); 20.20 +extern char *yytext; 20.21 + 20.22 + 20.23 +//#define YYERROR_VERBOSE 1 20.24 +//#define YYDEBUG 1 20.25 + 20.26 + Node *result = NULL; 20.27 +%} 20.28 + 20.29 +%token TOKEN_IDENTIFIER TOKEN_DOT TOKEN_STAR TOKEN_ARROW TOKEN_ADDR 20.30 +%token TOKEN_SIZEOF TOKEN_NUMBER 20.31 +%left TOKEN_DOT TOKEN_ARROW '[' 20.32 +%expect 6 20.33 +%% 20.34 + 20.35 +final: expression { result = $1; } 20.36 +; 20.37 + 20.38 +expression: 20.39 + simple_expression { $$ = $1; } | 20.40 + '(' expression ')' { $$ = $2; } | 20.41 + expression TOKEN_DOT ident { $$ = exprNodeDot($1, $3); } | 20.42 + expression TOKEN_ARROW ident { $$ = exprNodeArrow($1, $3); } | 20.43 + expression '[' number ']' { $$ = exprNodeArray($1, $3); } 20.44 +; 20.45 +simple_expression: 20.46 + ident { $$ = $1; } | 20.47 + TOKEN_STAR expression { $$ = exprNodeStar($2); } | 20.48 + TOKEN_ADDR expression { $$ = exprNodeAddr($2); } | 20.49 + TOKEN_SIZEOF '(' expression ')' { $$ = exprNodeSizeof($3); } 20.50 +; 20.51 + 20.52 +number: 20.53 + TOKEN_NUMBER { $$ = exprNodeNumber(); } 20.54 +; 20.55 + 20.56 +ident: 20.57 + TOKEN_IDENTIFIER {$$ = exprNodeIdentifier(); } 20.58 +; 20.59 + 20.60 +%% 20.61 + 20.62 +int yyerror(char *s) 20.63 +{ 20.64 + return 0; 20.65 +} 20.66 + 20.67 +#ifndef SDL 20.68 +extern FILE *yyin; 20.69 +int main(int argc, char **argv) 20.70 +{ 20.71 + // yydebug = 1; 20.72 + ++argv, --argc; 20.73 + if(argc > 0) 20.74 + yyin = fopen(argv[0], "r"); 20.75 + else 20.76 + yyin = stdin; 20.77 + if(!yyparse()) 20.78 + result->print(); 20.79 +} 20.80 +#endif
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 21.2 +++ b/src/sdl/exprNode.cpp Sun Mar 04 21:06:50 2012 -0600 21.3 @@ -0,0 +1,411 @@ 21.4 +// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. 21.5 +// Copyright (C) 1999-2003 Forgotten 21.6 +// Copyright (C) 2004 Forgotten and the VBA development team 21.7 + 21.8 +// This program is free software; you can redistribute it and/or modify 21.9 +// it under the terms of the GNU General Public License as published by 21.10 +// the Free Software Foundation; either version 2, or(at your option) 21.11 +// any later version. 21.12 +// 21.13 +// This program is distributed in the hope that it will be useful, 21.14 +// but WITHOUT ANY WARRANTY; without even the implied warranty of 21.15 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21.16 +// GNU General Public License for more details. 21.17 +// 21.18 +// You should have received a copy of the GNU General Public License 21.19 +// along with this program; if not, write to the Free Software Foundation, 21.20 +// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 21.21 + 21.22 +#include <string.h> 21.23 +#include <stdio.h> 21.24 +#include <stdlib.h> 21.25 + 21.26 +#include "Port.h" 21.27 +#include "gba/GBAGlobals.h" 21.28 +#include "gba/elf.h" 21.29 +#include "exprNode.h" 21.30 + 21.31 +extern char *yytext; 21.32 + 21.33 +#define debuggerReadMemory(addr) \ 21.34 + READ32LE((&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask])) 21.35 + 21.36 +void *exprNodeCleanUpList[100]; 21.37 +int exprNodeCleanUpCount = 0; 21.38 +Type exprNodeType = { 0, TYPE_base, "int", DW_ATE_signed, 4, 0, {0}, 0 }; 21.39 + 21.40 +void exprNodeClean(void *m) 21.41 +{ 21.42 + exprNodeCleanUpList[exprNodeCleanUpCount++] = m; 21.43 +} 21.44 + 21.45 +void exprNodeCleanUp() 21.46 +{ 21.47 + for(int i = 0; i < exprNodeCleanUpCount; i++) { 21.48 + free(exprNodeCleanUpList[i]); 21.49 + } 21.50 + exprNodeCleanUpCount = 0; 21.51 +} 21.52 + 21.53 +Node *exprNodeIdentifier() 21.54 +{ 21.55 + Node *n = (Node *)calloc(1, sizeof(Node)); 21.56 + n->name = strdup(yytext); 21.57 + 21.58 + exprNodeClean(n->name); 21.59 + exprNodeClean(n); 21.60 + 21.61 + n->print = exprNodeIdentifierPrint; 21.62 + n->resolve = exprNodeIdentifierResolve; 21.63 + return n; 21.64 +} 21.65 + 21.66 +bool exprNodeIdentifierResolve(Node *n, Function *f, CompileUnit *u) 21.67 +{ 21.68 + Object *o; 21.69 + if(elfGetObject(n->name, f, u, &o)) { 21.70 + n->type = o->type; 21.71 + n->location = elfDecodeLocation(f, o->location, &n->locType); 21.72 + return true; 21.73 + } else { 21.74 + printf("Object %s not found\n", n->name); 21.75 + } 21.76 + return false; 21.77 +} 21.78 + 21.79 +void exprNodeIdentifierPrint(Node *n) 21.80 +{ 21.81 + printf("%s", n->name); 21.82 +} 21.83 + 21.84 +Node *exprNodeNumber() 21.85 +{ 21.86 + Node *n = (Node *)calloc(1, sizeof(Node)); 21.87 + 21.88 + exprNodeClean(n); 21.89 + n->location = atoi(yytext); 21.90 + n->type = &exprNodeType; 21.91 + n->locType = LOCATION_value; 21.92 + n->print = exprNodeNumberPrint; 21.93 + n->resolve = exprNodeNumberResolve; 21.94 + return n; 21.95 +} 21.96 + 21.97 +bool exprNodeNumberResolve(Node *n, Function *f, CompileUnit *u) 21.98 +{ 21.99 + return true; 21.100 +} 21.101 + 21.102 +void exprNodeNumberPrint(Node *n) 21.103 +{ 21.104 + printf("%d", n->location); 21.105 +} 21.106 + 21.107 +Node *exprNodeStar(Node *exp) 21.108 +{ 21.109 + Node *n = (Node *)calloc(1, sizeof(Node)); 21.110 + exprNodeClean(n); 21.111 + 21.112 + n->expression = exp; 21.113 + 21.114 + n->print = exprNodeStarPrint; 21.115 + n->resolve = exprNodeStarResolve; 21.116 + return n; 21.117 +} 21.118 + 21.119 +bool exprNodeStarResolve(Node *n, Function *f, CompileUnit *u) 21.120 +{ 21.121 + if(n->expression->resolve(n->expression, f, u)) { 21.122 + if(n->expression->type->type == TYPE_pointer) { 21.123 + n->location = n->expression->location; 21.124 + if(n->expression->locType == LOCATION_memory) { 21.125 + n->location = debuggerReadMemory(n->location); 21.126 + } else if(n->expression->locType == LOCATION_register) { 21.127 + n->location = reg[n->expression->location].I; 21.128 + } else { 21.129 + n->location = n->expression->location; 21.130 + } 21.131 + n->type = n->expression->type->pointer; 21.132 + n->locType = LOCATION_memory; 21.133 + return true; 21.134 + } else { 21.135 + printf("Object is not of pointer type\n"); 21.136 + } 21.137 + } 21.138 + return false; 21.139 +} 21.140 + 21.141 +void exprNodeStarPrint(Node *n) 21.142 +{ 21.143 + printf("*"); 21.144 + n->expression->print(n->expression); 21.145 +} 21.146 + 21.147 +Node *exprNodeDot(Node *exp, Node *ident) 21.148 +{ 21.149 + Node *n = (Node *)calloc(1, sizeof(Node)); 21.150 + exprNodeClean(n); 21.151 + 21.152 + n->expression = exp; 21.153 + n->name = ident->name; 21.154 + 21.155 + n->print = exprNodeDotPrint; 21.156 + n->resolve = exprNodeDotResolve; 21.157 + return n; 21.158 +} 21.159 + 21.160 +bool exprNodeDotResolve(Node *n, Function *f, CompileUnit *u) 21.161 +{ 21.162 + if(n->expression->resolve(n->expression, f, u)) { 21.163 + TypeEnum tt = n->expression->type->type; 21.164 + 21.165 + if(tt == TYPE_struct || 21.166 + tt == TYPE_union) { 21.167 + u32 loc = n->expression->location; 21.168 + Type *t = n->expression->type; 21.169 + int count = t->structure->memberCount; 21.170 + int i = 0; 21.171 + while(i < count) { 21.172 + Member *m = &t->structure->members[i]; 21.173 + if(strcmp(m->name, n->name) == 0) { 21.174 + // found member 21.175 + n->type = m->type; 21.176 + if(tt == TYPE_struct) { 21.177 + n->location = elfDecodeLocation(f, m->location, &n->locType, 21.178 + loc); 21.179 + n->objLocation = loc; 21.180 + } else { 21.181 + n->location = loc; 21.182 + n->locType = n->expression->locType; 21.183 + n->objLocation = loc; 21.184 + } 21.185 + n->member = m; 21.186 + return true; 21.187 + } 21.188 + i++; 21.189 + } 21.190 + printf("Member %s not found\n", n->name); 21.191 + } else { 21.192 + printf("Object is not of structure type\n"); 21.193 + } 21.194 + } 21.195 + return false; 21.196 +} 21.197 + 21.198 +void exprNodeDotPrint(Node *n) 21.199 +{ 21.200 + n->expression->print(n->expression); 21.201 + printf(".%s", n->name); 21.202 +} 21.203 + 21.204 +Node *exprNodeArrow(Node *exp, Node *ident) 21.205 +{ 21.206 + Node *n = (Node *)calloc(1, sizeof(Node)); 21.207 + exprNodeClean(n); 21.208 + 21.209 + n->expression = exp; 21.210 + n->name = ident->name; 21.211 + 21.212 + n->print = exprNodeArrowPrint; 21.213 + n->resolve = exprNodeArrowResolve; 21.214 + return n; 21.215 +} 21.216 + 21.217 +bool exprNodeArrowResolve(Node *n, Function *f, CompileUnit *u) 21.218 +{ 21.219 + if(n->expression->resolve(n->expression, f, u)) { 21.220 + TypeEnum tt = n->expression->type->type; 21.221 + if(tt != TYPE_pointer) { 21.222 + printf("Object not of pointer type\n"); 21.223 + return false; 21.224 + } 21.225 + tt = n->expression->type->pointer->type; 21.226 + 21.227 + if(tt == TYPE_struct || 21.228 + tt == TYPE_union) { 21.229 + u32 loc = debuggerReadMemory(n->expression->location); 21.230 + Type *t = n->expression->type->pointer; 21.231 + int count = t->structure->memberCount; 21.232 + int i = 0; 21.233 + while(i < count) { 21.234 + Member *m = &t->structure->members[i]; 21.235 + if(strcmp(m->name, n->name) == 0) { 21.236 + // found member 21.237 + n->type = m->type; 21.238 + if(tt == TYPE_struct) { 21.239 + n->location = elfDecodeLocation(f, m->location, &n->locType, 21.240 + loc); 21.241 + n->objLocation = loc; 21.242 + } else { 21.243 + n->location = loc; 21.244 + n->objLocation = loc; 21.245 + } 21.246 + n->locType = LOCATION_memory; 21.247 + n->member = m; 21.248 + return true; 21.249 + } 21.250 + i++; 21.251 + } 21.252 + printf("Member %s not found\n", n->name); 21.253 + } else { 21.254 + printf("Object is not of structure type\n"); 21.255 + } 21.256 + } 21.257 + return false; 21.258 +} 21.259 + 21.260 +void exprNodeArrowPrint(Node *n) 21.261 +{ 21.262 + n->expression->print(n->expression); 21.263 + printf("->%s", n->name); 21.264 +} 21.265 + 21.266 +Node *exprNodeAddr(Node *exp) 21.267 +{ 21.268 + Node *n = (Node *)calloc(1, sizeof(Node)); 21.269 + exprNodeClean(n); 21.270 + 21.271 + n->expression = exp; 21.272 + 21.273 + n->print = exprNodeAddrPrint; 21.274 + n->resolve = exprNodeAddrResolve; 21.275 + return n; 21.276 +} 21.277 + 21.278 +bool exprNodeAddrResolve(Node *n, Function *f, CompileUnit *u) 21.279 +{ 21.280 + if(n->expression->resolve(n->expression, f, u)) { 21.281 + if(n->expression->locType == LOCATION_memory) { 21.282 + n->location = n->expression->location; 21.283 + n->locType = LOCATION_value; 21.284 + n->type = &exprNodeType; 21.285 + } else if(n->expression->locType == LOCATION_register) { 21.286 + printf("Value is in register %d\n", n->expression->location); 21.287 + } else { 21.288 + printf("Direct value is %d\n", n->location); 21.289 + } 21.290 + return true; 21.291 + } 21.292 + return false; 21.293 +} 21.294 + 21.295 +void exprNodeAddrPrint(Node *n) 21.296 +{ 21.297 + printf("*"); 21.298 + n->expression->print(n->expression); 21.299 +} 21.300 + 21.301 +Node *exprNodeSizeof(Node *exp) 21.302 +{ 21.303 + Node *n = (Node *)calloc(1, sizeof(Node)); 21.304 + exprNodeClean(n); 21.305 + 21.306 + n->expression = exp; 21.307 + 21.308 + n->print = exprNodeSizeofPrint; 21.309 + n->resolve = exprNodeSizeofResolve; 21.310 + return n; 21.311 +} 21.312 + 21.313 +bool exprNodeSizeofResolve(Node *n, Function *f, CompileUnit *u) 21.314 +{ 21.315 + if(n->expression->resolve(n->expression, f, u)) { 21.316 + n->location = n->expression->type->size; 21.317 + n->locType = LOCATION_value; 21.318 + n->type = &exprNodeType; 21.319 + return true; 21.320 + } 21.321 + return false; 21.322 +} 21.323 + 21.324 +void exprNodeSizeofPrint(Node *n) 21.325 +{ 21.326 + printf("sizeof("); 21.327 + n->expression->print(n->expression); 21.328 + printf(")"); 21.329 +} 21.330 + 21.331 +Node *exprNodeArray(Node *exp, Node *number) 21.332 +{ 21.333 + Node *n = (Node *)calloc(1, sizeof(Node)); 21.334 + exprNodeClean(n); 21.335 + 21.336 + n->expression = exp; 21.337 + n->value = number->location; 21.338 + 21.339 + n->print = exprNodeArrayPrint; 21.340 + n->resolve = exprNodeArrayResolve; 21.341 + return n; 21.342 +} 21.343 + 21.344 +int exprNodeGetSize(Array *a, int index) 21.345 +{ 21.346 + index++; 21.347 + if(index == a->maxBounds) { 21.348 + return a->type->size; 21.349 + } else { 21.350 + int size = a->bounds[a->maxBounds-1] * a->type->size; 21.351 + 21.352 + for(int i = index; i < a->maxBounds-1; i++) { 21.353 + size *= a->bounds[i]; 21.354 + } 21.355 + return size; 21.356 + } 21.357 +} 21.358 + 21.359 +bool exprNodeArrayResolve(Node *n, Function *f, CompileUnit *u) 21.360 +{ 21.361 + if(n->expression->resolve(n->expression, f, u)) { 21.362 + TypeEnum tt = n->expression->type->type; 21.363 + if(tt != TYPE_array && 21.364 + tt != TYPE_pointer) { 21.365 + printf("Object not of array or pointer type\n"); 21.366 + return false; 21.367 + } 21.368 + 21.369 + if(tt == TYPE_array) { 21.370 + Array *a = n->expression->type->array; 21.371 + 21.372 + u32 loc = n->expression->location; 21.373 + Type *t = a->type; 21.374 + if(a->maxBounds > 1) { 21.375 + int index = n->expression->index; 21.376 + 21.377 + if(index == a->maxBounds) { 21.378 + printf("Too many indices for array\n"); 21.379 + return false; 21.380 + } 21.381 + 21.382 + if((index+1) < a->maxBounds) { 21.383 + n->type = n->expression->type; 21.384 + n->index = index+1; 21.385 + n->locType = LOCATION_memory; 21.386 + n->location = n->expression->location + 21.387 + n->value * exprNodeGetSize(a, index); 21.388 + return true; 21.389 + } 21.390 + } 21.391 + n->type = t; 21.392 + n->location = loc + n->value * t->size; 21.393 + n->locType = LOCATION_memory; 21.394 + } else { 21.395 + Type *t = n->expression->type->pointer; 21.396 + u32 loc = n->expression->location; 21.397 + if(n->expression->locType == LOCATION_register) 21.398 + loc = reg[loc].I; 21.399 + else 21.400 + loc = debuggerReadMemory(loc); 21.401 + n->type = t; 21.402 + n->location = loc + n->value * t->size; 21.403 + n->locType = LOCATION_memory; 21.404 + } 21.405 + return true; 21.406 + } 21.407 + return false; 21.408 +} 21.409 + 21.410 +void exprNodeArrayPrint(Node *n) 21.411 +{ 21.412 + n->expression->print(n->expression); 21.413 + printf("[%d]", n->value); 21.414 +}
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 22.2 +++ b/src/sdl/exprNode.h Sun Mar 04 21:06:50 2012 -0600 22.3 @@ -0,0 +1,68 @@ 22.4 +// -*- C++ -*- 22.5 +// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. 22.6 +// Copyright (C) 1999-2003 Forgotten 22.7 +// Copyright (C) 2004 Forgotten and the VBA development team 22.8 + 22.9 +// This program is free software; you can redistribute it and/or modify 22.10 +// it under the terms of the GNU General Public License as published by 22.11 +// the Free Software Foundation; either version 2, or(at your option) 22.12 +// any later version. 22.13 +// 22.14 +// This program is distributed in the hope that it will be useful, 22.15 +// but WITHOUT ANY WARRANTY; without even the implied warranty of 22.16 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22.17 +// GNU General Public License for more details. 22.18 +// 22.19 +// You should have received a copy of the GNU General Public License 22.20 +// along with this program; if not, write to the Free Software Foundation, 22.21 +// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 22.22 + 22.23 +struct Node { 22.24 + Type *type; 22.25 + u32 location; 22.26 + u32 objLocation; 22.27 + LocationType locType; 22.28 + int value; 22.29 + int index; 22.30 + char *name; 22.31 + Node *expression; 22.32 + Member *member; 22.33 + void (*print)(Node *); 22.34 + bool (*resolve)(Node *, Function *f, CompileUnit *u); 22.35 +}; 22.36 + 22.37 +extern void exprNodeCleanUp(); 22.38 + 22.39 +extern Node *exprNodeIdentifier(); 22.40 +extern void exprNodeIdentifierPrint(Node *); 22.41 +extern bool exprNodeIdentifierResolve(Node *, Function *, CompileUnit *); 22.42 + 22.43 +extern Node *exprNodeNumber(); 22.44 +extern void exprNodeNumberPrint(Node *); 22.45 +extern bool exprNodeNumberResolve(Node *, Function *, CompileUnit *); 22.46 + 22.47 +extern Node *exprNodeStar(Node *); 22.48 +extern void exprNodeStarPrint(Node *); 22.49 +extern bool exprNodeStarResolve(Node *, Function *, CompileUnit *); 22.50 + 22.51 +extern Node *exprNodeDot(Node *, Node *); 22.52 +extern void exprNodeDotPrint(Node *); 22.53 +extern bool exprNodeDotResolve(Node *, Function *, CompileUnit *); 22.54 + 22.55 +extern Node *exprNodeArrow(Node *, Node *); 22.56 +extern void exprNodeArrowPrint(Node *); 22.57 +extern bool exprNodeArrowResolve(Node *, Function *, CompileUnit *); 22.58 + 22.59 +extern Node *exprNodeAddr(Node *); 22.60 +extern void exprNodeAddrPrint(Node *); 22.61 +extern bool exprNodeAddrResolve(Node *, Function *, CompileUnit *); 22.62 + 22.63 +extern Node *exprNodeSizeof(Node *); 22.64 +extern void exprNodeSizeofPrint(Node *); 22.65 +extern bool exprNodeSizeofResolve(Node *, Function *, CompileUnit *); 22.66 + 22.67 +extern Node *exprNodeArray(Node *, Node *); 22.68 +extern void exprNodeArrayPrint(Node *); 22.69 +extern bool exprNodeArrayResolve(Node *, Function *, CompileUnit *); 22.70 + 22.71 +#define YYSTYPE struct Node *
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 23.2 +++ b/src/sdl/getopt.c Sun Mar 04 21:06:50 2012 -0600 23.3 @@ -0,0 +1,1060 @@ 23.4 +/* Getopt for GNU. 23.5 + NOTE: getopt is now part of the C library, so if you don't know what 23.6 + "Keep this file name-space clean" means, talk to drepper@gnu.org 23.7 + before changing it! 23.8 + 23.9 + Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98 23.10 + Free Software Foundation, Inc. 23.11 + 23.12 + NOTE: This source is derived from an old version taken from the GNU C 23.13 + Library (glibc). 23.14 + 23.15 + This program is free software; you can redistribute it and/or modify it 23.16 + under the terms of the GNU General Public License as published by the 23.17 + Free Software Foundation; either version 2, or (at your option) any 23.18 + later version. 23.19 + 23.20 + This program is distributed in the hope that it will be useful, 23.21 + but WITHOUT ANY WARRANTY; without even the implied warranty of 23.22 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23.23 + GNU General Public License for more details. 23.24 + 23.25 + You should have received a copy of the GNU General Public License 23.26 + along with this program; if not, write to the Free Software 23.27 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 23.28 + USA. */ 23.29 + 23.30 +/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>. 23.31 + Ditto for AIX 3.2 and <stdlib.h>. */ 23.32 +#ifndef _NO_PROTO 23.33 +# define _NO_PROTO 23.34 +#endif 23.35 + 23.36 +#ifdef HAVE_CONFIG_H 23.37 +# include <config.h> 23.38 +#endif 23.39 + 23.40 +#if !defined __STDC__ || !__STDC__ 23.41 +/* This is a separate conditional since some stdc systems 23.42 + reject `defined (const)'. */ 23.43 +# ifndef const 23.44 +# define const 23.45 +# endif 23.46 +#endif 23.47 + 23.48 +#include <stdio.h> 23.49 + 23.50 +/* Comment out all this code if we are using the GNU C Library, and are not 23.51 + actually compiling the library itself. This code is part of the GNU C 23.52 + Library, but also included in many other GNU distributions. Compiling 23.53 + and linking in this code is a waste when using the GNU C library 23.54 + (especially if it is a shared library). Rather than having every GNU 23.55 + program understand `configure --with-gnu-libc' and omit the object files, 23.56 + it is simpler to just do this in the source for each such file. */ 23.57 + 23.58 +#define GETOPT_INTERFACE_VERSION 2 23.59 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 23.60 +# include <gnu-versions.h> 23.61 +# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION 23.62 +# define ELIDE_CODE 23.63 +# endif 23.64 +#endif 23.65 + 23.66 +#ifndef ELIDE_CODE 23.67 + 23.68 + 23.69 +/* This needs to come after some library #include 23.70 + to get __GNU_LIBRARY__ defined. */ 23.71 +#ifdef __GNU_LIBRARY__ 23.72 +/* Don't include stdlib.h for non-GNU C libraries because some of them 23.73 + contain conflicting prototypes for getopt. */ 23.74 +# include <stdlib.h> 23.75 +# include <unistd.h> 23.76 +#endif /* GNU C library. */ 23.77 + 23.78 +#ifdef VMS 23.79 +# include <unixlib.h> 23.80 +# if HAVE_STRING_H - 0 23.81 +# include <string.h> 23.82 +# endif 23.83 +#endif 23.84 + 23.85 +#ifndef _ 23.86 +/* This is for other GNU distributions with internationalized messages. 23.87 + When compiling libc, the _ macro is predefined. */ 23.88 +# ifdef HAVE_LIBINTL_H 23.89 +# include <libintl.h> 23.90 +# define _(msgid) gettext (msgid) 23.91 +# else 23.92 +# define _(msgid) (msgid) 23.93 +# endif 23.94 +#endif 23.95 + 23.96 +#ifdef _MSC_VER 23.97 +#include <string.h> 23.98 +#endif 23.99 + 23.100 +/* This version of `getopt' appears to the caller like standard Unix `getopt' 23.101 + but it behaves differently for the user, since it allows the user 23.102 + to intersperse the options with the other arguments. 23.103 + 23.104 + As `getopt' works, it permutes the elements of ARGV so that, 23.105 + when it is done, all the options precede everything else. Thus 23.106 + all application programs are extended to handle flexible argument order. 23.107 + 23.108 + Setting the environment variable POSIXLY_CORRECT disables permutation. 23.109 + Then the behavior is completely standard. 23.110 + 23.111 + GNU application programs can use a third alternative mode in which 23.112 + they can distinguish the relative order of options and other arguments. */ 23.113 + 23.114 +#include "getopt.h" 23.115 + 23.116 +/* For communication from `getopt' to the caller. 23.117 + When `getopt' finds an option that takes an argument, 23.118 + the argument value is returned here. 23.119 + Also, when `ordering' is RETURN_IN_ORDER, 23.120 + each non-option ARGV-element is returned here. */ 23.121 + 23.122 +char *optarg = NULL; 23.123 + 23.124 +/* Index in ARGV of the next element to be scanned. 23.125 + This is used for communication to and from the caller 23.126 + and for communication between successive calls to `getopt'. 23.127 + 23.128 + On entry to `getopt', zero means this is the first call; initialize. 23.129 + 23.130 + When `getopt' returns -1, this is the index of the first of the 23.131 + non-option elements that the caller should itself scan. 23.132 + 23.133 + Otherwise, `optind' communicates from one call to the next 23.134 + how much of ARGV has been scanned so far. */ 23.135 + 23.136 +/* 1003.2 says this must be 1 before any call. */ 23.137 +int optind = 1; 23.138 + 23.139 +/* Formerly, initialization of getopt depended on optind==0, which 23.140 + causes problems with re-calling getopt as programs generally don't 23.141 + know that. */ 23.142 + 23.143 +int __getopt_initialized = 0; 23.144 + 23.145 +/* The next char to be scanned in the option-element 23.146 + in which the last option character we returned was found. 23.147 + This allows us to pick up the scan where we left off. 23.148 + 23.149 + If this is zero, or a null string, it means resume the scan 23.150 + by advancing to the next ARGV-element. */ 23.151 + 23.152 +static char *nextchar; 23.153 + 23.154 +/* Callers store zero here to inhibit the error message 23.155 + for unrecognized options. */ 23.156 + 23.157 +int opterr = 1; 23.158 + 23.159 +/* Set to an option character which was unrecognized. 23.160 + This must be initialized on some systems to avoid linking in the 23.161 + system's own getopt implementation. */ 23.162 + 23.163 +int optopt = '?'; 23.164 + 23.165 +/* Describe how to deal with options that follow non-option ARGV-elements. 23.166 + 23.167 + If the caller did not specify anything, 23.168 + the default is REQUIRE_ORDER if the environment variable 23.169 + POSIXLY_CORRECT is defined, PERMUTE otherwise. 23.170 + 23.171 + REQUIRE_ORDER means don't recognize them as options; 23.172 + stop option processing when the first non-option is seen. 23.173 + This is what Unix does. 23.174 + This mode of operation is selected by either setting the environment 23.175 + variable POSIXLY_CORRECT, or using `+' as the first character 23.176 + of the list of option characters. 23.177 + 23.178 + PERMUTE is the default. We permute the contents of ARGV as we scan, 23.179 + so that eventually all the non-options are at the end. This allows options 23.180 + to be given in any order, even with programs that were not written to 23.181 + expect this. 23.182 + 23.183 + RETURN_IN_ORDER is an option available to programs that were written 23.184 + to expect options and other ARGV-elements in any order and that care about 23.185 + the ordering of the two. We describe each non-option ARGV-element 23.186 + as if it were the argument of an option with character code 1. 23.187 + Using `-' as the first character of the list of option characters 23.188 + selects this mode of operation. 23.189 + 23.190 + The special argument `--' forces an end of option-scanning regardless 23.191 + of the value of `ordering'. In the case of RETURN_IN_ORDER, only 23.192 + `--' can cause `getopt' to return -1 with `optind' != ARGC. */ 23.193 + 23.194 +static enum 23.195 +{ 23.196 + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER 23.197 +} ordering; 23.198 + 23.199 +/* Value of POSIXLY_CORRECT environment variable. */ 23.200 +static char *posixly_correct; 23.201 + 23.202 +#ifdef __GNU_LIBRARY__ 23.203 +/* We want to avoid inclusion of string.h with non-GNU libraries 23.204 + because there are many ways it can cause trouble. 23.205 + On some systems, it contains special magic macros that don't work 23.206 + in GCC. */ 23.207 +# include <string.h> 23.208 +# define my_index strchr 23.209 +#else 23.210 + 23.211 +# if HAVE_STRING_H 23.212 +# include <string.h> 23.213 +# else 23.214 +# if HAVE_STRINGS_H 23.215 +# include <strings.h> 23.216 +# endif 23.217 +# endif 23.218 + 23.219 +/* Avoid depending on library functions or files 23.220 + whose names are inconsistent. */ 23.221 + 23.222 +#ifndef getenv 23.223 +extern char *getenv (); 23.224 +#endif 23.225 + 23.226 +static char * 23.227 +my_index (str, chr) 23.228 + const char *str; 23.229 + int chr; 23.230 +{ 23.231 + while (*str) 23.232 + { 23.233 + if (*str == chr) 23.234 + return (char *) str; 23.235 + str++; 23.236 + } 23.237 + return 0; 23.238 +} 23.239 + 23.240 +/* If using GCC, we can safely declare strlen this way. 23.241 + If not using GCC, it is ok not to declare it. */ 23.242 +#ifdef __GNUC__ 23.243 +/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. 23.244 + That was relevant to code that was here before. */ 23.245 +# if (!defined __STDC__ || !__STDC__) && !defined strlen 23.246 +/* gcc with -traditional declares the built-in strlen to return int, 23.247 + and has done so at least since version 2.4.5. -- rms. */ 23.248 +extern int strlen (const char *); 23.249 +# endif /* not __STDC__ */ 23.250 +#endif /* __GNUC__ */ 23.251 + 23.252 +#endif /* not __GNU_LIBRARY__ */ 23.253 + 23.254 +/* Handle permutation of arguments. */ 23.255 + 23.256 +/* Describe the part of ARGV that contains non-options that have 23.257 + been skipped. `first_nonopt' is the index in ARGV of the first of them; 23.258 + `last_nonopt' is the index after the last of them. */ 23.259 + 23.260 +static int first_nonopt; 23.261 +static int last_nonopt; 23.262 + 23.263 +#ifdef _LIBC 23.264 +/* Bash 2.0 gives us an environment variable containing flags 23.265 + indicating ARGV elements that should not be considered arguments. */ 23.266 + 23.267 +/* Defined in getopt_init.c */ 23.268 +extern char *__getopt_nonoption_flags; 23.269 + 23.270 +static int nonoption_flags_max_len; 23.271 +static int nonoption_flags_len; 23.272 + 23.273 +static int original_argc; 23.274 +static char *const *original_argv; 23.275 + 23.276 +/* Make sure the environment variable bash 2.0 puts in the environment 23.277 + is valid for the getopt call we must make sure that the ARGV passed 23.278 + to getopt is that one passed to the process. */ 23.279 +static void 23.280 +__attribute__ ((unused)) 23.281 +store_args_and_env (int argc, char *const *argv) 23.282 +{ 23.283 + /* XXX This is no good solution. We should rather copy the args so 23.284 + that we can compare them later. But we must not use malloc(3). */ 23.285 + original_argc = argc; 23.286 + original_argv = argv; 23.287 +} 23.288 +# ifdef text_set_element 23.289 +text_set_element (__libc_subinit, store_args_and_env); 23.290 +# endif /* text_set_element */ 23.291 + 23.292 +# define SWAP_FLAGS(ch1, ch2) \ 23.293 + if (nonoption_flags_len > 0) \ 23.294 + { \ 23.295 + char __tmp = __getopt_nonoption_flags[ch1]; \ 23.296 + __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ 23.297 + __getopt_nonoption_flags[ch2] = __tmp; \ 23.298 + } 23.299 +#else /* !_LIBC */ 23.300 +# define SWAP_FLAGS(ch1, ch2) 23.301 +#endif /* _LIBC */ 23.302 + 23.303 +/* Exchange two adjacent subsequences of ARGV. 23.304 + One subsequence is elements [first_nonopt,last_nonopt) 23.305 + which contains all the non-options that have been skipped so far. 23.306 + The other is elements [last_nonopt,optind), which contains all 23.307 + the options processed since those non-options were skipped. 23.308 + 23.309 + `first_nonopt' and `last_nonopt' are relocated so that they describe 23.310 + the new indices of the non-options in ARGV after they are moved. */ 23.311 + 23.312 +#if defined __STDC__ && __STDC__ 23.313 +static void exchange (char **); 23.314 +#endif 23.315 + 23.316 +static void 23.317 +exchange (argv) 23.318 + char **argv; 23.319 +{ 23.320 + int bottom = first_nonopt; 23.321 + int middle = last_nonopt; 23.322 + int top = optind; 23.323 + char *tem; 23.324 + 23.325 + /* Exchange the shorter segment with the far end of the longer segment. 23.326 + That puts the shorter segment into the right place. 23.327 + It leaves the longer segment in the right place overall, 23.328 + but it consists of two parts that need to be swapped next. */ 23.329 + 23.330 +#ifdef _LIBC 23.331 + /* First make sure the handling of the `__getopt_nonoption_flags' 23.332 + string can work normally. Our top argument must be in the range 23.333 + of the string. */ 23.334 + if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) 23.335 + { 23.336 + /* We must extend the array. The user plays games with us and 23.337 + presents new arguments. */ 23.338 + char *new_str = malloc (top + 1); 23.339 + if (new_str == NULL) 23.340 + nonoption_flags_len = nonoption_flags_max_len = 0; 23.341 + else 23.342 + { 23.343 + memset (__mempcpy (new_str, __getopt_nonoption_flags, 23.344 + nonoption_flags_max_len), 23.345 + '\0', top + 1 - nonoption_flags_max_len); 23.346 + nonoption_flags_max_len = top + 1; 23.347 + __getopt_nonoption_flags = new_str; 23.348 + } 23.349 + } 23.350 +#endif 23.351 + 23.352 + while (top > middle && middle > bottom) 23.353 + { 23.354 + if (top - middle > middle - bottom) 23.355 + { 23.356 + /* Bottom segment is the short one. */ 23.357 + int len = middle - bottom; 23.358 + register int i; 23.359 + 23.360 + /* Swap it with the top part of the top segment. */ 23.361 + for (i = 0; i < len; i++) 23.362 + { 23.363 + tem = argv[bottom + i]; 23.364 + argv[bottom + i] = argv[top - (middle - bottom) + i]; 23.365 + argv[top - (middle - bottom) + i] = tem; 23.366 + SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); 23.367 + } 23.368 + /* Exclude the moved bottom segment from further swapping. */ 23.369 + top -= len; 23.370 + } 23.371 + else 23.372 + { 23.373 + /* Top segment is the short one. */ 23.374 + int len = top - middle; 23.375 + register int i; 23.376 + 23.377 + /* Swap it with the bottom part of the bottom segment. */ 23.378 + for (i = 0; i < len; i++) 23.379 + { 23.380 + tem = argv[bottom + i]; 23.381 + argv[bottom + i] = argv[middle + i]; 23.382 + argv[middle + i] = tem; 23.383 + SWAP_FLAGS (bottom + i, middle + i); 23.384 + } 23.385 + /* Exclude the moved top segment from further swapping. */ 23.386 + bottom += len; 23.387 + } 23.388 + } 23.389 + 23.390 + /* Update records for the slots the non-options now occupy. */ 23.391 + 23.392 + first_nonopt += (optind - last_nonopt); 23.393 + last_nonopt = optind; 23.394 +} 23.395 + 23.396 +/* Initialize the internal data when the first call is made. */ 23.397 + 23.398 +#if defined __STDC__ && __STDC__ 23.399 +static const char *_getopt_initialize (int, char *const *, const char *); 23.400 +#endif 23.401 +static const char * 23.402 +_getopt_initialize (argc, argv, optstring) 23.403 + int argc; 23.404 + char *const *argv; 23.405 + const char *optstring; 23.406 +{ 23.407 + /* Start processing options with ARGV-element 1 (since ARGV-element 0 23.408 + is the program name); the sequence of previously skipped 23.409 + non-option ARGV-elements is empty. */ 23.410 + 23.411 + first_nonopt = last_nonopt = optind; 23.412 + 23.413 + nextchar = NULL; 23.414 + 23.415 + posixly_correct = getenv ("POSIXLY_CORRECT"); 23.416 + 23.417 + /* Determine how to handle the ordering of options and nonoptions. */ 23.418 + 23.419 + if (optstring[0] == '-') 23.420 + { 23.421 + ordering = RETURN_IN_ORDER; 23.422 + ++optstring; 23.423 + } 23.424 + else if (optstring[0] == '+') 23.425 + { 23.426 + ordering = REQUIRE_ORDER; 23.427 + ++optstring; 23.428 + } 23.429 + else if (posixly_correct != NULL) 23.430 + ordering = REQUIRE_ORDER; 23.431 + else 23.432 + ordering = PERMUTE; 23.433 + 23.434 +#ifdef _LIBC 23.435 + if (posixly_correct == NULL 23.436 + && argc == original_argc && argv == original_argv) 23.437 + { 23.438 + if (nonoption_flags_max_len == 0) 23.439 + { 23.440 + if (__getopt_nonoption_flags == NULL 23.441 + || __getopt_nonoption_flags[0] == '\0') 23.442 + nonoption_flags_max_len = -1; 23.443 + else 23.444 + { 23.445 + const char *orig_str = __getopt_nonoption_flags; 23.446 + int len = nonoption_flags_max_len = strlen (orig_str); 23.447 + if (nonoption_flags_max_len < argc) 23.448 + nonoption_flags_max_len = argc; 23.449 + __getopt_nonoption_flags = 23.450 + (char *) malloc (nonoption_flags_max_len); 23.451 + if (__getopt_nonoption_flags == NULL) 23.452 + nonoption_flags_max_len = -1; 23.453 + else 23.454 + memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), 23.455 + '\0', nonoption_flags_max_len - len); 23.456 + } 23.457 + } 23.458 + nonoption_flags_len = nonoption_flags_max_len; 23.459 + } 23.460 + else 23.461 + nonoption_flags_len = 0; 23.462 +#endif 23.463 + 23.464 + return optstring; 23.465 +} 23.466 + 23.467 +/* Scan elements of ARGV (whose length is ARGC) for option characters 23.468 + given in OPTSTRING. 23.469 + 23.470 + If an element of ARGV starts with '-', and is not exactly "-" or "--", 23.471 + then it is an option element. The characters of this element 23.472 + (aside from the initial '-') are option characters. If `getopt' 23.473 + is called repeatedly, it returns successively each of the option characters 23.474 + from each of the option elements. 23.475 + 23.476 + If `getopt' finds another option character, it returns that character, 23.477 + updating `optind' and `nextchar' so that the next call to `getopt' can 23.478 + resume the scan with the following option character or ARGV-element. 23.479 + 23.480 + If there are no more option characters, `getopt' returns -1. 23.481 + Then `optind' is the index in ARGV of the first ARGV-element 23.482 + that is not an option. (The ARGV-elements have been permuted 23.483 + so that those that are not options now come last.) 23.484 + 23.485 + OPTSTRING is a string containing the legitimate option characters. 23.486 + If an option character is seen that is not listed in OPTSTRING, 23.487 + return '?' after printing an error message. If you set `opterr' to 23.488 + zero, the error message is suppressed but we still return '?'. 23.489 + 23.490 + If a char in OPTSTRING is followed by a colon, that means it wants an arg, 23.491 + so the following text in the same ARGV-element, or the text of the following 23.492 + ARGV-element, is returned in `optarg'. Two colons mean an option that 23.493 + wants an optional arg; if there is text in the current ARGV-element, 23.494 + it is returned in `optarg', otherwise `optarg' is set to zero. 23.495 + 23.496 + If OPTSTRING starts with `-' or `+', it requests different methods of 23.497 + handling the non-option ARGV-elements. 23.498 + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. 23.499 + 23.500 + Long-named options begin with `--' instead of `-'. 23.501 + Their names may be abbreviated as long as the abbreviation is unique 23.502 + or is an exact match for some defined option. If they have an 23.503 + argument, it follows the option name in the same ARGV-element, separated 23.504 + from the option name by a `=', or else the in next ARGV-element. 23.505 + When `getopt' finds a long-named option, it returns 0 if that option's 23.506 + `flag' field is nonzero, the value of the option's `val' field 23.507 + if the `flag' field is zero. 23.508 + 23.509 + The elements of ARGV aren't really const, because we permute them. 23.510 + But we pretend they're const in the prototype to be compatible 23.511 + with other systems. 23.512 + 23.513 + LONGOPTS is a vector of `struct option' terminated by an 23.514 + element containing a name which is zero. 23.515 + 23.516 + LONGIND returns the index in LONGOPT of the long-named option found. 23.517 + It is only valid when a long-named option has been found by the most 23.518 + recent call. 23.519 + 23.520 + If LONG_ONLY is nonzero, '-' as well as '--' can introduce 23.521 + long-named options. */ 23.522 + 23.523 +int 23.524 +_getopt_internal (argc, argv, optstring, longopts, longind, long_only) 23.525 + int argc; 23.526 + char *const *argv; 23.527 + const char *optstring; 23.528 + const struct option *longopts; 23.529 + int *longind; 23.530 + int long_only; 23.531 +{ 23.532 + optarg = NULL; 23.533 + 23.534 + if (optind == 0 || !__getopt_initialized) 23.535 + { 23.536 + if (optind == 0) 23.537 + optind = 1; /* Don't scan ARGV[0], the program name. */ 23.538 + optstring = _getopt_initialize (argc, argv, optstring); 23.539 + __getopt_initialized = 1; 23.540 + } 23.541 + 23.542 + /* Test whether ARGV[optind] points to a non-option argument. 23.543 + Either it does not have option syntax, or there is an environment flag 23.544 + from the shell indicating it is not an option. The later information 23.545 + is only used when the used in the GNU libc. */ 23.546 +#ifdef _LIBC 23.547 +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ 23.548 + || (optind < nonoption_flags_len \ 23.549 + && __getopt_nonoption_flags[optind] == '1')) 23.550 +#else 23.551 +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') 23.552 +#endif 23.553 + 23.554 + if (nextchar == NULL || *nextchar == '\0') 23.555 + { 23.556 + /* Advance to the next ARGV-element. */ 23.557 + 23.558 + /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been 23.559 + moved back by the user (who may also have changed the arguments). */ 23.560 + if (last_nonopt > optind) 23.561 + last_nonopt = optind; 23.562 + if (first_nonopt > optind) 23.563 + first_nonopt = optind; 23.564 + 23.565 + if (ordering == PERMUTE) 23.566 + { 23.567 + /* If we have just processed some options following some non-options, 23.568 + exchange them so that the options come first. */ 23.569 + 23.570 + if (first_nonopt != last_nonopt && last_nonopt != optind) 23.571 + exchange ((char **) argv); 23.572 + else if (last_nonopt != optind) 23.573 + first_nonopt = optind; 23.574 + 23.575 + /* Skip any additional non-options 23.576 + and extend the range of non-options previously skipped. */ 23.577 + 23.578 + while (optind < argc && NONOPTION_P) 23.579 + optind++; 23.580 + last_nonopt = optind; 23.581 + } 23.582 + 23.583 + /* The special ARGV-element `--' means premature end of options. 23.584 + Skip it like a null option, 23.585 + then exchange with previous non-options as if it were an option, 23.586 + then skip everything else like a non-option. */ 23.587 + 23.588 + if (optind != argc && !strcmp (argv[optind], "--")) 23.589 + { 23.590 + optind++; 23.591 + 23.592 + if (first_nonopt != last_nonopt && last_nonopt != optind) 23.593 + exchange ((char **) argv); 23.594 + else if (first_nonopt == last_nonopt) 23.595 + first_nonopt = optind; 23.596 + last_nonopt = argc; 23.597 + 23.598 + optind = argc; 23.599 + } 23.600 + 23.601 + /* If we have done all the ARGV-elements, stop the scan 23.602 + and back over any non-options that we skipped and permuted. */ 23.603 + 23.604 + if (optind == argc) 23.605 + { 23.606 + /* Set the next-arg-index to point at the non-options 23.607 + that we previously skipped, so the caller will digest them. */ 23.608 + if (first_nonopt != last_nonopt) 23.609 + optind = first_nonopt; 23.610 + return -1; 23.611 + } 23.612 + 23.613 + /* If we have come to a non-option and did not permute it, 23.614 + either stop the scan or describe it to the caller and pass it by. */ 23.615 + 23.616 + if (NONOPTION_P) 23.617 + { 23.618 + if (ordering == REQUIRE_ORDER) 23.619 + return -1; 23.620 + optarg = argv[optind++]; 23.621 + return 1; 23.622 + } 23.623 + 23.624 + /* We have found another option-ARGV-element. 23.625 + Skip the initial punctuation. */ 23.626 + 23.627 + nextchar = (argv[optind] + 1 23.628 + + (longopts != NULL && argv[optind][1] == '-')); 23.629 + } 23.630 + 23.631 + /* Decode the current option-ARGV-element. */ 23.632 + 23.633 + /* Check whether the ARGV-element is a long option. 23.634 + 23.635 + If long_only and the ARGV-element has the form "-f", where f is 23.636 + a valid short option, don't consider it an abbreviated form of 23.637 + a long option that starts with f. Otherwise there would be no 23.638 + way to give the -f short option. 23.639 + 23.640 + On the other hand, if there's a long option "fubar" and 23.641 + the ARGV-element is "-fu", do consider that an abbreviation of 23.642 + the long option, just like "--fu", and not "-f" with arg "u". 23.643 + 23.644 + This distinction seems to be the most useful approach. */ 23.645 + 23.646 + if (longopts != NULL 23.647 + && (argv[optind][1] == '-' 23.648 + || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) 23.649 + { 23.650 + char *nameend; 23.651 + const struct option *p; 23.652 + const struct option *pfound = NULL; 23.653 + int exact = 0; 23.654 + int ambig = 0; 23.655 + int indfound = -1; 23.656 + int option_index; 23.657 + 23.658 + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) 23.659 + /* Do nothing. */ ; 23.660 + 23.661 + /* Test all long options for either exact match 23.662 + or abbreviated matches. */ 23.663 + for (p = longopts, option_index = 0; p->name; p++, option_index++) 23.664 + if (!strncmp (p->name, nextchar, nameend - nextchar)) 23.665 + { 23.666 + if ((unsigned int) (nameend - nextchar) 23.667 + == (unsigned int) strlen (p->name)) 23.668 + { 23.669 + /* Exact match found. */ 23.670 + pfound = p; 23.671 + indfound = option_index; 23.672 + exact = 1; 23.673 + break; 23.674 + } 23.675 + else if (pfound == NULL) 23.676 + { 23.677 + /* First nonexact match found. */ 23.678 + pfound = p; 23.679 + indfound = option_index; 23.680 + } 23.681 + else 23.682 + /* Second or later nonexact match found. */ 23.683 + ambig = 1; 23.684 + } 23.685 + 23.686 + if (ambig && !exact) 23.687 + { 23.688 + if (opterr) 23.689 + fprintf (stderr, _("%s: option `%s' is ambiguous\n"), 23.690 + argv[0], argv[optind]); 23.691 + nextchar += strlen (nextchar); 23.692 + optind++; 23.693 + optopt = 0; 23.694 + return '?'; 23.695 + } 23.696 + 23.697 + if (pfound != NULL) 23.698 + { 23.699 + option_index = indfound; 23.700 + optind++; 23.701 + if (*nameend) 23.702 + { 23.703 + /* Don't test has_arg with >, because some C compilers don't 23.704 + allow it to be used on enums. */ 23.705 + if (pfound->has_arg) 23.706 + optarg = nameend + 1; 23.707 + else 23.708 + { 23.709 + if (opterr) 23.710 + { 23.711 + if (argv[optind - 1][1] == '-') 23.712 + /* --option */ 23.713 + fprintf (stderr, 23.714 + _("%s: option `--%s' doesn't allow an argument\n"), 23.715 + argv[0], pfound->name); 23.716 + else 23.717 + /* +option or -option */ 23.718 + fprintf (stderr, 23.719 + _("%s: option `%c%s' doesn't allow an argument\n"), 23.720 + argv[0], argv[optind - 1][0], pfound->name); 23.721 + 23.722 + nextchar += strlen (nextchar); 23.723 + 23.724 + optopt = pfound->val; 23.725 + return '?'; 23.726 + } 23.727 + } 23.728 + } 23.729 + else if (pfound->has_arg == 1) 23.730 + { 23.731 + if (optind < argc) 23.732 + optarg = argv[optind++]; 23.733 + else 23.734 + { 23.735 + if (opterr) 23.736 + fprintf (stderr, 23.737 + _("%s: option `%s' requires an argument\n"), 23.738 + argv[0], argv[optind - 1]); 23.739 + nextchar += strlen (nextchar); 23.740 + optopt = pfound->val; 23.741 + return optstring[0] == ':' ? ':' : '?'; 23.742 + } 23.743 + } 23.744 + nextchar += strlen (nextchar); 23.745 + if (longind != NULL) 23.746 + *longind = option_index; 23.747 + if (pfound->flag) 23.748 + { 23.749 + *(pfound->flag) = pfound->val; 23.750 + return 0; 23.751 + } 23.752 + return pfound->val; 23.753 + } 23.754 + 23.755 + /* Can't find it as a long option. If this is not getopt_long_only, 23.756 + or the option starts with '--' or is not a valid short 23.757 + option, then it's an error. 23.758 + Otherwise interpret it as a short option. */ 23.759 + if (!long_only || argv[optind][1] == '-' 23.760 + || my_index (optstring, *nextchar) == NULL) 23.761 + { 23.762 + if (opterr) 23.763 + { 23.764 + if (argv[optind][1] == '-') 23.765 + /* --option */ 23.766 + fprintf (stderr, _("%s: unrecognized option `--%s'\n"), 23.767 + argv[0], nextchar); 23.768 + else 23.769 + /* +option or -option */ 23.770 + fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), 23.771 + argv[0], argv[optind][0], nextchar); 23.772 + } 23.773 + nextchar = (char *) ""; 23.774 + optind++; 23.775 + optopt = 0; 23.776 + return '?'; 23.777 + } 23.778 + } 23.779 + 23.780 + /* Look at and handle the next short option-character. */ 23.781 + 23.782 + { 23.783 + char c = *nextchar++; 23.784 + char *temp = my_index (optstring, c); 23.785 + 23.786 + /* Increment `optind' when we start to process its last character. */ 23.787 + if (*nextchar == '\0') 23.788 + ++optind; 23.789 + 23.790 + if (temp == NULL || c == ':') 23.791 + { 23.792 + if (opterr) 23.793 + { 23.794 + if (posixly_correct) 23.795 + /* 1003.2 specifies the format of this message. */ 23.796 + fprintf (stderr, _("%s: illegal option -- %c\n"), 23.797 + argv[0], c); 23.798 + else 23.799 + fprintf (stderr, _("%s: invalid option -- %c\n"), 23.800 + argv[0], c); 23.801 + } 23.802 + optopt = c; 23.803 + return '?'; 23.804 + } 23.805 + /* Convenience. Treat POSIX -W foo same as long option --foo */ 23.806 + if (temp[0] == 'W' && temp[1] == ';') 23.807 + { 23.808 + char *nameend; 23.809 + const struct option *p; 23.810 + const struct option *pfound = NULL; 23.811 + int exact = 0; 23.812 + int ambig = 0; 23.813 + int indfound = 0; 23.814 + int option_index; 23.815 + 23.816 + /* This is an option that requires an argument. */ 23.817 + if (*nextchar != '\0') 23.818 + { 23.819 + optarg = nextchar; 23.820 + /* If we end this ARGV-element by taking the rest as an arg, 23.821 + we must advance to the next element now. */ 23.822 + optind++; 23.823 + } 23.824 + else if (optind == argc) 23.825 + { 23.826 + if (opterr) 23.827 + { 23.828 + /* 1003.2 specifies the format of this message. */ 23.829 + fprintf (stderr, _("%s: option requires an argument -- %c\n"), 23.830 + argv[0], c); 23.831 + } 23.832 + optopt = c; 23.833 + if (optstring[0] == ':') 23.834 + c = ':'; 23.835 + else 23.836 + c = '?'; 23.837 + return c; 23.838 + } 23.839 + else 23.840 + /* We already incremented `optind' once; 23.841 + increment it again when taking next ARGV-elt as argument. */ 23.842 + optarg = argv[optind++]; 23.843 + 23.844 + /* optarg is now the argument, see if it's in the 23.845 + table of longopts. */ 23.846 + 23.847 + for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) 23.848 + /* Do nothing. */ ; 23.849 + 23.850 + /* Test all long options for either exact match 23.851 + or abbreviated matches. */ 23.852 + for (p = longopts, option_index = 0; p->name; p++, option_index++) 23.853 + if (!strncmp (p->name, nextchar, nameend - nextchar)) 23.854 + { 23.855 + if ((unsigned int) (nameend - nextchar) == strlen (p->name)) 23.856 + { 23.857 + /* Exact match found. */ 23.858 + pfound = p; 23.859 + indfound = option_index; 23.860 + exact = 1; 23.861 + break; 23.862 + } 23.863 + else if (pfound == NULL) 23.864 + { 23.865 + /* First nonexact match found. */ 23.866 + pfound = p; 23.867 + indfound = option_index; 23.868 + } 23.869 + else 23.870 + /* Second or later nonexact match found. */ 23.871 + ambig = 1; 23.872 + } 23.873 + if (ambig && !exact) 23.874 + { 23.875 + if (opterr) 23.876 + fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), 23.877 + argv[0], argv[optind]); 23.878 + nextchar += strlen (nextchar); 23.879 + optind++; 23.880 + return '?'; 23.881 + } 23.882 + if (pfound != NULL) 23.883 + { 23.884 + option_index = indfound; 23.885 + if (*nameend) 23.886 + { 23.887 + /* Don't test has_arg with >, because some C compilers don't 23.888 + allow it to be used on enums. */ 23.889 + if (pfound->has_arg) 23.890 + optarg = nameend + 1; 23.891 + else 23.892 + { 23.893 + if (opterr) 23.894 + fprintf (stderr, _("\ 23.895 +%s: option `-W %s' doesn't allow an argument\n"), 23.896 + argv[0], pfound->name); 23.897 + 23.898 + nextchar += strlen (nextchar); 23.899 + return '?'; 23.900 + } 23.901 + } 23.902 + else if (pfound->has_arg == 1) 23.903 + { 23.904 + if (optind < argc) 23.905 + optarg = argv[optind++]; 23.906 + else 23.907 + { 23.908 + if (opterr) 23.909 + fprintf (stderr, 23.910 + _("%s: option `%s' requires an argument\n"), 23.911 + argv[0], argv[optind - 1]); 23.912 + nextchar += strlen (nextchar); 23.913 + return optstring[0] == ':' ? ':' : '?'; 23.914 + } 23.915 + } 23.916 + nextchar += strlen (nextchar); 23.917 + if (longind != NULL) 23.918 + *longind = option_index; 23.919 + if (pfound->flag) 23.920 + { 23.921 + *(pfound->flag) = pfound->val; 23.922 + return 0; 23.923 + } 23.924 + return pfound->val; 23.925 + } 23.926 + nextchar = NULL; 23.927 + return 'W'; /* Let the application handle it. */ 23.928 + } 23.929 + if (temp[1] == ':') 23.930 + { 23.931 + if (temp[2] == ':') 23.932 + { 23.933 + /* This is an option that accepts an argument optionally. */ 23.934 + if (*nextchar != '\0') 23.935 + { 23.936 + optarg = nextchar; 23.937 + optind++; 23.938 + } 23.939 + else 23.940 + optarg = NULL; 23.941 + nextchar = NULL; 23.942 + } 23.943 + else 23.944 + { 23.945 + /* This is an option that requires an argument. */ 23.946 + if (*nextchar != '\0') 23.947 + { 23.948 + optarg = nextchar; 23.949 + /* If we end this ARGV-element by taking the rest as an arg, 23.950 + we must advance to the next element now. */ 23.951 + optind++; 23.952 + } 23.953 + else if (optind == argc) 23.954 + { 23.955 + if (opterr) 23.956 + { 23.957 + /* 1003.2 specifies the format of this message. */ 23.958 + fprintf (stderr, 23.959 + _("%s: option requires an argument -- %c\n"), 23.960 + argv[0], c); 23.961 + } 23.962 + optopt = c; 23.963 + if (optstring[0] == ':') 23.964 + c = ':'; 23.965 + else 23.966 + c = '?'; 23.967 + } 23.968 + else 23.969 + /* We already incremented `optind' once; 23.970 + increment it again when taking next ARGV-elt as argument. */ 23.971 + optarg = argv[optind++]; 23.972 + nextchar = NULL; 23.973 + } 23.974 + } 23.975 + return c; 23.976 + } 23.977 +} 23.978 + 23.979 +int 23.980 +getopt (argc, argv, optstring) 23.981 + int argc; 23.982 + char *const *argv; 23.983 + const char *optstring; 23.984 +{ 23.985 + return _getopt_internal (argc, argv, optstring, 23.986 + (const struct option *) 0, 23.987 + (int *) 0, 23.988 + 0); 23.989 +} 23.990 + 23.991 +#endif /* Not ELIDE_CODE. */ 23.992 + 23.993 +#ifdef TEST 23.994 + 23.995 +/* Compile with -DTEST to make an executable for use in testing 23.996 + the above definition of `getopt'. */ 23.997 + 23.998 +int 23.999 +main (argc, argv) 23.1000 + int argc; 23.1001 + char **argv; 23.1002 +{ 23.1003 + int c; 23.1004 + int digit_optind = 0; 23.1005 + 23.1006 + while (1) 23.1007 + { 23.1008 + int this_option_optind = optind ? optind : 1; 23.1009 + 23.1010 + c = getopt (argc, argv, "abc:d:0123456789"); 23.1011 + if (c == -1) 23.1012 + break; 23.1013 + 23.1014 + switch (c) 23.1015 + { 23.1016 + case '0': 23.1017 + case '1': 23.1018 + case '2': 23.1019 + case '3': 23.1020 + case '4': 23.1021 + case '5': 23.1022 + case '6': 23.1023 + case '7': 23.1024 + case '8': 23.1025 + case '9': 23.1026 + if (digit_optind != 0 && digit_optind != this_option_optind) 23.1027 + printf ("digits occur in two different argv-elements.\n"); 23.1028 + digit_optind = this_option_optind; 23.1029 + printf ("option %c\n", c); 23.1030 + break; 23.1031 + 23.1032 + case 'a': 23.1033 + printf ("option a\n"); 23.1034 + break; 23.1035 + 23.1036 + case 'b': 23.1037 + printf ("option b\n"); 23.1038 + break; 23.1039 + 23.1040 + case 'c': 23.1041 + printf ("option c with value `%s'\n", optarg); 23.1042 + break; 23.1043 + 23.1044 + case '?': 23.1045 + break; 23.1046 + 23.1047 + default: 23.1048 + printf ("?? getopt returned character code 0%o ??\n", c); 23.1049 + } 23.1050 + } 23.1051 + 23.1052 + if (optind < argc) 23.1053 + { 23.1054 + printf ("non-option ARGV-elements: "); 23.1055 + while (optind < argc) 23.1056 + printf ("%s ", argv[optind++]); 23.1057 + printf ("\n"); 23.1058 + } 23.1059 + 23.1060 + exit (0); 23.1061 +} 23.1062 + 23.1063 +#endif /* TEST */
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 24.2 +++ b/src/sdl/getopt.h Sun Mar 04 21:06:50 2012 -0600 24.3 @@ -0,0 +1,141 @@ 24.4 +/* Declarations for getopt. 24.5 + Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 2000 24.6 + Free Software Foundation, Inc. 24.7 + 24.8 + NOTE: The canonical source of this file is maintained with the GNU C Library. 24.9 + Bugs can be reported to bug-glibc@gnu.org. 24.10 + 24.11 + This program is free software; you can redistribute it and/or modify it 24.12 + under the terms of the GNU General Public License as published by the 24.13 + Free Software Foundation; either version 2, or (at your option) any 24.14 + later version. 24.15 + 24.16 + This program is distributed in the hope that it will be useful, 24.17 + but WITHOUT ANY WARRANTY; without even the implied warranty of 24.18 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24.19 + GNU General Public License for more details. 24.20 + 24.21 + You should have received a copy of the GNU General Public License 24.22 + along with this program; if not, write to the Free Software 24.23 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 24.24 + USA. */ 24.25 + 24.26 +#ifndef _GETOPT_H 24.27 +#define _GETOPT_H 1 24.28 + 24.29 +#ifdef __cplusplus 24.30 +extern "C" { 24.31 +#endif 24.32 + 24.33 +/* For communication from `getopt' to the caller. 24.34 + When `getopt' finds an option that takes an argument, 24.35 + the argument value is returned here. 24.36 + Also, when `ordering' is RETURN_IN_ORDER, 24.37 + each non-option ARGV-element is returned here. */ 24.38 + 24.39 +extern char *optarg; 24.40 + 24.41 +/* Index in ARGV of the next element to be scanned. 24.42 + This is used for communication to and from the caller 24.43 + and for communication between successive calls to `getopt'. 24.44 + 24.45 + On entry to `getopt', zero means this is the first call; initialize. 24.46 + 24.47 + When `getopt' returns -1, this is the index of the first of the 24.48 + non-option elements that the caller should itself scan. 24.49 + 24.50 + Otherwise, `optind' communicates from one call to the next 24.51 + how much of ARGV has been scanned so far. */ 24.52 + 24.53 +extern int optind; 24.54 + 24.55 +/* Callers store zero here to inhibit the error message `getopt' prints 24.56 + for unrecognized options. */ 24.57 + 24.58 +extern int opterr; 24.59 + 24.60 +/* Set to an option character which was unrecognized. */ 24.61 + 24.62 +extern int optopt; 24.63 + 24.64 +/* Describe the long-named options requested by the application. 24.65 + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector 24.66 + of `struct option' terminated by an element containing a name which is 24.67 + zero. 24.68 + 24.69 + The field `has_arg' is: 24.70 + no_argument (or 0) if the option does not take an argument, 24.71 + required_argument (or 1) if the option requires an argument, 24.72 + optional_argument (or 2) if the option takes an optional argument. 24.73 + 24.74 + If the field `flag' is not NULL, it points to a variable that is set 24.75 + to the value given in the field `val' when the option is found, but 24.76 + left unchanged if the option is not found. 24.77 + 24.78 + To have a long-named option do something other than set an `int' to 24.79 + a compiled-in constant, such as set a value from `optarg', set the 24.80 + option's `flag' field to zero and its `val' field to a nonzero 24.81 + value (the equivalent single-letter option character, if there is 24.82 + one). For long options that have a zero `flag' field, `getopt' 24.83 + returns the contents of the `val' field. */ 24.84 + 24.85 +struct option 24.86 +{ 24.87 +#if defined (__STDC__) && __STDC__ 24.88 + const char *name; 24.89 +#else 24.90 + char *name; 24.91 +#endif 24.92 + /* has_arg can't be an enum because some compilers complain about 24.93 + type mismatches in all the code that assumes it is an int. */ 24.94 + int has_arg; 24.95 + int *flag; 24.96 + int val; 24.97 +}; 24.98 + 24.99 +/* Names for the values of the `has_arg' field of `struct option'. */ 24.100 + 24.101 +#define no_argument 0 24.102 +#define required_argument 1 24.103 +#define optional_argument 2 24.104 + 24.105 +#if defined (__STDC__) && __STDC__ 24.106 +/* HAVE_DECL_* is a three-state macro: undefined, 0 or 1. If it is 24.107 + undefined, we haven't run the autoconf check so provide the 24.108 + declaration without arguments. If it is 0, we checked and failed 24.109 + to find the declaration so provide a fully prototyped one. If it 24.110 + is 1, we found it so don't provide any declaration at all. */ 24.111 +#if defined (__GNU_LIBRARY__) || (defined (HAVE_DECL_GETOPT) && !HAVE_DECL_GETOPT) 24.112 +/* Many other libraries have conflicting prototypes for getopt, with 24.113 + differences in the consts, in stdlib.h. To avoid compilation 24.114 + errors, only prototype getopt for the GNU C library. */ 24.115 +extern int getopt (int argc, char *const *argv, const char *shortopts); 24.116 +#else /* not __GNU_LIBRARY__ */ 24.117 +# if !defined (HAVE_DECL_GETOPT) 24.118 +extern int getopt (); 24.119 +# endif 24.120 +#endif /* __GNU_LIBRARY__ */ 24.121 +extern int getopt_long (int argc, char *const *argv, const char *shortopts, 24.122 + const struct option *longopts, int *longind); 24.123 +extern int getopt_long_only (int argc, char *const *argv, 24.124 + const char *shortopts, 24.125 + const struct option *longopts, int *longind); 24.126 + 24.127 +/* Internal only. Users should not call this directly. */ 24.128 +extern int _getopt_internal (int argc, char *const *argv, 24.129 + const char *shortopts, 24.130 + const struct option *longopts, int *longind, 24.131 + int long_only); 24.132 +#else /* not __STDC__ */ 24.133 +extern int getopt (); 24.134 +extern int getopt_long (); 24.135 +extern int getopt_long_only (); 24.136 + 24.137 +extern int _getopt_internal (); 24.138 +#endif /* __STDC__ */ 24.139 + 24.140 +#ifdef __cplusplus 24.141 +} 24.142 +#endif 24.143 + 24.144 +#endif /* getopt.h */
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 25.2 +++ b/src/sdl/getopt1.c Sun Mar 04 21:06:50 2012 -0600 25.3 @@ -0,0 +1,190 @@ 25.4 +/* getopt_long and getopt_long_only entry points for GNU getopt. 25.5 + Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98 25.6 + Free Software Foundation, Inc. 25.7 + 25.8 + NOTE: This source is derived from an old version taken from the GNU C 25.9 + Library (glibc). 25.10 + 25.11 + This program is free software; you can redistribute it and/or modify it 25.12 + under the terms of the GNU General Public License as published by the 25.13 + Free Software Foundation; either version 2, or (at your option) any 25.14 + later version. 25.15 + 25.16 + This program is distributed in the hope that it will be useful, 25.17 + but WITHOUT ANY WARRANTY; without even the implied warranty of 25.18 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25.19 + GNU General Public License for more details. 25.20 + 25.21 + You should have received a copy of the GNU General Public License 25.22 + along with this program; if not, write to the Free Software 25.23 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 25.24 + USA. */ 25.25 + 25.26 +#ifdef HAVE_CONFIG_H 25.27 +#include <config.h> 25.28 +#endif 25.29 + 25.30 +#include "getopt.h" 25.31 + 25.32 +#if !defined __STDC__ || !__STDC__ 25.33 +/* This is a separate conditional since some stdc systems 25.34 + reject `defined (const)'. */ 25.35 +#ifndef const 25.36 +#define const 25.37 +#endif 25.38 +#endif 25.39 + 25.40 +#include <stdio.h> 25.41 + 25.42 +/* Comment out all this code if we are using the GNU C Library, and are not 25.43 + actually compiling the library itself. This code is part of the GNU C 25.44 + Library, but also included in many other GNU distributions. Compiling 25.45 + and linking in this code is a waste when using the GNU C library 25.46 + (especially if it is a shared library). Rather than having every GNU 25.47 + program understand `configure --with-gnu-libc' and omit the object files, 25.48 + it is simpler to just do this in the source for each such file. */ 25.49 + 25.50 +#define GETOPT_INTERFACE_VERSION 2 25.51 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 25.52 +#include <gnu-versions.h> 25.53 +#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION 25.54 +#define ELIDE_CODE 25.55 +#endif 25.56 +#endif 25.57 + 25.58 +#ifndef ELIDE_CODE 25.59 + 25.60 + 25.61 +/* This needs to come after some library #include 25.62 + to get __GNU_LIBRARY__ defined. */ 25.63 +#ifdef __GNU_LIBRARY__ 25.64 +#include <stdlib.h> 25.65 +#endif 25.66 + 25.67 +#ifndef NULL 25.68 +#define NULL 0 25.69 +#endif 25.70 + 25.71 +int 25.72 +getopt_long (argc, argv, options, long_options, opt_index) 25.73 + int argc; 25.74 + char *const *argv; 25.75 + const char *options; 25.76 + const struct option *long_options; 25.77 + int *opt_index; 25.78 +{ 25.79 + return _getopt_internal (argc, argv, options, long_options, opt_index, 0); 25.80 +} 25.81 + 25.82 +/* Like getopt_long, but '-' as well as '--' can indicate a long option. 25.83 + If an option that starts with '-' (not '--') doesn't match a long option, 25.84 + but does match a short option, it is parsed as a short option 25.85 + instead. */ 25.86 + 25.87 +int 25.88 +getopt_long_only (argc, argv, options, long_options, opt_index) 25.89 + int argc; 25.90 + char *const *argv; 25.91 + const char *options; 25.92 + const struct option *long_options; 25.93 + int *opt_index; 25.94 +{ 25.95 + return _getopt_internal (argc, argv, options, long_options, opt_index, 1); 25.96 +} 25.97 + 25.98 + 25.99 +#endif /* Not ELIDE_CODE. */ 25.100 + 25.101 +#ifdef TEST 25.102 + 25.103 +#include <stdio.h> 25.104 + 25.105 +int 25.106 +main (argc, argv) 25.107 + int argc; 25.108 + char **argv; 25.109 +{ 25.110 + int c; 25.111 + int digit_optind = 0; 25.112 + 25.113 + while (1) 25.114 + { 25.115 + int this_option_optind = optind ? optind : 1; 25.116 + int option_index = 0; 25.117 + static struct option long_options[] = 25.118 + { 25.119 + {"add", 1, 0, 0}, 25.120 + {"append", 0, 0, 0}, 25.121 + {"delete", 1, 0, 0}, 25.122 + {"verbose", 0, 0, 0}, 25.123 + {"create", 0, 0, 0}, 25.124 + {"file", 1, 0, 0}, 25.125 + {0, 0, 0, 0} 25.126 + }; 25.127 + 25.128 + c = getopt_long (argc, argv, "abc:d:0123456789", 25.129 + long_options, &option_index); 25.130 + if (c == -1) 25.131 + break; 25.132 + 25.133 + switch (c) 25.134 + { 25.135 + case 0: 25.136 + printf ("option %s", long_options[option_index].name); 25.137 + if (optarg) 25.138 + printf (" with arg %s", optarg); 25.139 + printf ("\n"); 25.140 + break; 25.141 + 25.142 + case '0': 25.143 + case '1': 25.144 + case '2': 25.145 + case '3': 25.146 + case '4': 25.147 + case '5': 25.148 + case '6': 25.149 + case '7': 25.150 + case '8': 25.151 + case '9': 25.152 + if (digit_optind != 0 && digit_optind != this_option_optind) 25.153 + printf ("digits occur in two different argv-elements.\n"); 25.154 + digit_optind = this_option_optind; 25.155 + printf ("option %c\n", c); 25.156 + break; 25.157 + 25.158 + case 'a': 25.159 + printf ("option a\n"); 25.160 + break; 25.161 + 25.162 + case 'b': 25.163 + printf ("option b\n"); 25.164 + break; 25.165 + 25.166 + case 'c': 25.167 + printf ("option c with value `%s'\n", optarg); 25.168 + break; 25.169 + 25.170 + case 'd': 25.171 + printf ("option d with value `%s'\n", optarg); 25.172 + break; 25.173 + 25.174 + case '?': 25.175 + break; 25.176 + 25.177 + default: 25.178 + printf ("?? getopt returned character code 0%o ??\n", c); 25.179 + } 25.180 + } 25.181 + 25.182 + if (optind < argc) 25.183 + { 25.184 + printf ("non-option ARGV-elements: "); 25.185 + while (optind < argc) 25.186 + printf ("%s ", argv[optind++]); 25.187 + printf ("\n"); 25.188 + } 25.189 + 25.190 + exit (0); 25.191 +} 25.192 + 25.193 +#endif /* TEST */