From 6c82fc18f9a2dee242ff939e99b6faa0abb10452 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 18 Apr 2001 23:47:38 +0000 Subject: [PATCH] Initial revision --- FILEID.DIZ | 10 + LICENSE.TXT | 340 +++++++ Makefile | 390 ++++++++ README | 26 + docs/LICENSE.TXT | 340 +++++++ docs/changelog.txt | 108 +++ docs/thanks.txt | 31 + docs/todo.txt | 237 +++++ programs/april.toby | 61 ++ programs/april_modified.toby | 63 ++ programs/boolTest.toby | 51 + programs/boxes.toby | 46 + programs/colorBlocks.toby | 30 + programs/connie.toby | 74 ++ programs/eyes.toby | 91 ++ programs/flowerVines.toby | 53 ++ programs/globTest.toby | 30 + programs/gradient.toby | 34 + programs/gradient2.toby | 32 + programs/greg1.toby | 34 + programs/nesting.toby | 50 + programs/nicki.toby | 53 ++ programs/psychedelic.toby | 36 + programs/psychedelic2.toby | 33 + programs/psychedelic3.toby | 28 + programs/psychedelic4.toby | 32 + programs/rotateTurtle.toby | 14 + programs/sabrina.toby | 44 + programs/sabrina2.toby | 33 + programs/swirls.toby | 69 ++ programs/testArray.toby | 82 ++ programs/testMultiTurtling.toby | 46 + programs/testRecursive.toby | 14 + programs/testReturn.toby | 14 + programs/testStep.toby | 67 ++ programs/testString.toby | 86 ++ programs/testTurtleSpace.toby | 68 ++ programs/testWhile.toby | 56 ++ programs/theLight.toby | 46 + programs/triangleWeb.toby | 45 + programs/triangleWheel.toby | 31 + programs/webBox.toby | 20 + programs/wierdBox.toby | 20 + programs/wireOrb.toby | 23 + splash.jpg | Bin 0 -> 43387 bytes src/exceptions/ExecException.h | 80 ++ src/exceptions/FlowException.h | 112 +++ src/exceptions/HaltException.h | 82 ++ src/exceptions/IOException.h | 42 + src/exceptions/ParseException.h | 82 ++ src/exceptions/ReturnException.h | 65 ++ src/exceptions/TobyException.h | 56 ++ src/i18n/example.tobylang | 235 +++++ src/i18n/french.tobylang | 239 +++++ src/i18n/tobykeywords.tobylang | 98 ++ .../FrameBufferTurtleSpaceRenderer.cpp | 408 ++++++++ .../FrameBufferTurtleSpaceRenderer.h | 135 +++ .../gtkrenderer/GTKTurtleSpaceRenderer.cpp | 313 ++++++ .../gtkrenderer/GTKTurtleSpaceRenderer.h | 72 ++ .../sdlrenderer/SDLTurtleSpaceRenderer.cpp | 145 +++ .../sdlrenderer/SDLTurtleSpaceRenderer.h | 62 ++ .../threads/nullthreads/NullMutex.cpp | 56 ++ src/platform/threads/nullthreads/NullMutex.h | 43 + .../threads/nullthreads/NullThread.cpp | 66 ++ src/platform/threads/nullthreads/NullThread.h | 46 + .../threads/pthreads/PthreadsMutex.cpp | 56 ++ src/platform/threads/pthreads/PthreadsMutex.h | 42 + .../threads/pthreads/PthreadsThread.cpp | 65 ++ .../threads/pthreads/PthreadsThread.h | 46 + src/platform/threads/sdlthreads/SDLMutex.cpp | 56 ++ src/platform/threads/sdlthreads/SDLMutex.h | 47 + src/platform/threads/sdlthreads/SDLThread.cpp | 61 ++ src/platform/threads/sdlthreads/SDLThread.h | 45 + src/standalone.cpp | 153 +++ src/turtlespace/Turtle.cpp | 167 ++++ src/turtlespace/Turtle.h | 82 ++ src/turtlespace/TurtleSpace.cpp | 888 ++++++++++++++++++ src/turtlespace/TurtleSpace.h | 128 +++ src/turtlespace/TurtleSpaceRenderer.h | 117 +++ src/util/TobyCollection.cpp | 126 +++ src/util/TobyCollection.h | 57 ++ src/util/TobyGeometry.h | 134 +++ src/util/TobyLanguage.cpp | 171 ++++ src/util/TobyLanguage.h | 335 +++++++ src/util/TobyMutex.h | 46 + src/util/TobyObject.h | 58 ++ src/util/TobyStack.cpp | 35 + src/util/TobyStack.h | 42 + src/util/TobyString.cpp | 98 ++ src/util/TobyString.h | 57 ++ src/util/TobyThread.h | 52 + 91 files changed, 8692 insertions(+) create mode 100644 FILEID.DIZ create mode 100644 LICENSE.TXT create mode 100644 Makefile create mode 100644 README create mode 100644 docs/LICENSE.TXT create mode 100644 docs/changelog.txt create mode 100644 docs/thanks.txt create mode 100644 docs/todo.txt create mode 100644 programs/april.toby create mode 100644 programs/april_modified.toby create mode 100644 programs/boolTest.toby create mode 100644 programs/boxes.toby create mode 100644 programs/colorBlocks.toby create mode 100644 programs/connie.toby create mode 100644 programs/eyes.toby create mode 100644 programs/flowerVines.toby create mode 100644 programs/globTest.toby create mode 100644 programs/gradient.toby create mode 100644 programs/gradient2.toby create mode 100644 programs/greg1.toby create mode 100644 programs/nesting.toby create mode 100644 programs/nicki.toby create mode 100644 programs/psychedelic.toby create mode 100644 programs/psychedelic2.toby create mode 100644 programs/psychedelic3.toby create mode 100644 programs/psychedelic4.toby create mode 100644 programs/rotateTurtle.toby create mode 100644 programs/sabrina.toby create mode 100644 programs/sabrina2.toby create mode 100644 programs/swirls.toby create mode 100644 programs/testArray.toby create mode 100644 programs/testMultiTurtling.toby create mode 100644 programs/testRecursive.toby create mode 100644 programs/testReturn.toby create mode 100644 programs/testStep.toby create mode 100644 programs/testString.toby create mode 100644 programs/testTurtleSpace.toby create mode 100644 programs/testWhile.toby create mode 100644 programs/theLight.toby create mode 100644 programs/triangleWeb.toby create mode 100644 programs/triangleWheel.toby create mode 100644 programs/webBox.toby create mode 100644 programs/wierdBox.toby create mode 100644 programs/wireOrb.toby create mode 100644 splash.jpg create mode 100644 src/exceptions/ExecException.h create mode 100644 src/exceptions/FlowException.h create mode 100644 src/exceptions/HaltException.h create mode 100644 src/exceptions/IOException.h create mode 100644 src/exceptions/ParseException.h create mode 100644 src/exceptions/ReturnException.h create mode 100644 src/exceptions/TobyException.h create mode 100644 src/i18n/example.tobylang create mode 100644 src/i18n/french.tobylang create mode 100644 src/i18n/tobykeywords.tobylang create mode 100644 src/platform/renderers/fbrenderer/FrameBufferTurtleSpaceRenderer.cpp create mode 100644 src/platform/renderers/fbrenderer/FrameBufferTurtleSpaceRenderer.h create mode 100644 src/platform/renderers/gtkrenderer/GTKTurtleSpaceRenderer.cpp create mode 100644 src/platform/renderers/gtkrenderer/GTKTurtleSpaceRenderer.h create mode 100644 src/platform/renderers/sdlrenderer/SDLTurtleSpaceRenderer.cpp create mode 100644 src/platform/renderers/sdlrenderer/SDLTurtleSpaceRenderer.h create mode 100644 src/platform/threads/nullthreads/NullMutex.cpp create mode 100644 src/platform/threads/nullthreads/NullMutex.h create mode 100644 src/platform/threads/nullthreads/NullThread.cpp create mode 100644 src/platform/threads/nullthreads/NullThread.h create mode 100644 src/platform/threads/pthreads/PthreadsMutex.cpp create mode 100644 src/platform/threads/pthreads/PthreadsMutex.h create mode 100644 src/platform/threads/pthreads/PthreadsThread.cpp create mode 100644 src/platform/threads/pthreads/PthreadsThread.h create mode 100644 src/platform/threads/sdlthreads/SDLMutex.cpp create mode 100644 src/platform/threads/sdlthreads/SDLMutex.h create mode 100644 src/platform/threads/sdlthreads/SDLThread.cpp create mode 100644 src/platform/threads/sdlthreads/SDLThread.h create mode 100644 src/standalone.cpp create mode 100644 src/turtlespace/Turtle.cpp create mode 100644 src/turtlespace/Turtle.h create mode 100644 src/turtlespace/TurtleSpace.cpp create mode 100644 src/turtlespace/TurtleSpace.h create mode 100644 src/turtlespace/TurtleSpaceRenderer.h create mode 100644 src/util/TobyCollection.cpp create mode 100644 src/util/TobyCollection.h create mode 100644 src/util/TobyGeometry.h create mode 100644 src/util/TobyLanguage.cpp create mode 100644 src/util/TobyLanguage.h create mode 100644 src/util/TobyMutex.h create mode 100644 src/util/TobyObject.h create mode 100644 src/util/TobyStack.cpp create mode 100644 src/util/TobyStack.h create mode 100644 src/util/TobyString.cpp create mode 100644 src/util/TobyString.h create mode 100644 src/util/TobyThread.h diff --git a/FILEID.DIZ b/FILEID.DIZ new file mode 100644 index 0000000..83f2547 --- /dev/null +++ b/FILEID.DIZ @@ -0,0 +1,10 @@ + +Toby. + +A learning environment inspired by LOGO (TurtleGraphics). + +Please read the included README for all the dirty details. + +--ryan. (icculus@linuxgames.com) + + diff --git a/LICENSE.TXT b/LICENSE.TXT new file mode 100644 index 0000000..ae3b531 --- /dev/null +++ b/LICENSE.TXT @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e120c9d --- /dev/null +++ b/Makefile @@ -0,0 +1,390 @@ +#-----------------------------------------------------------------------------# +# TOBY -- An abstract interpreter engine and system for learning. +# Copyright (C) 1999 Ryan C. Gordon. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#-----------------------------------------------------------------------------# + + +#-----------------------------------------------------------------------------# +# Makefile for building Toby on Unix-like systems. Follow the instructions +# for editing this file, then run "make" on the command line. +# +# Written by Ryan C. Gordon (icculus@linuxgames.com) +#-----------------------------------------------------------------------------# + + +#-----------------------------------------------------------------------------# +# Set to your liking. +#-----------------------------------------------------------------------------# +CC = gcc +LINKER = gcc + + +#-----------------------------------------------------------------------------# +# If this makefile fails to detect Cygwin correctly, or you want to force +# the build process's behaviour, set it to "true" or "false" (w/o quotes). +#-----------------------------------------------------------------------------# +#cygwin := true +#cygwin := false +cygwin := autodetect + +#-----------------------------------------------------------------------------# +# Set this to true if you want to create a debug build. +#-----------------------------------------------------------------------------# +debugging := false +#debugging := true + +#-----------------------------------------------------------------------------# +# Set this to what your platform has. +# Current option(s): "pthreads", "sdl", "null". +#-----------------------------------------------------------------------------# +#platform_threads := pthreads +platform_threads := sdl +#platform_threads := null + +#-----------------------------------------------------------------------------# +# Set this to what your platform has. +# Current option(s): "sdl", "gtk". +#-----------------------------------------------------------------------------# +#platform_video := sdl +platform_video := gtk + + +#-----------------------------------------------------------------------------# +# To use a different platform's ASM or portable C, change this. +#-----------------------------------------------------------------------------# +#USE_ASM := -DUSE_I386_ASM +USE_ASM := -DUSE_PORTABLE_C + + + +#-----------------------------------------------------------------------------# +# You only need to set SDL_INC_DIR and SDL_LIB_DIR if you are using CygWin +# as a compiler and SDL for video. +# +# SDL_INC_DIR is where SDL.h and associated headers can be found, and +# SDL_LIB_DIR is where SDL.lib and SDL.dll are located. These may be set as +# environment variables, if you'd prefer to not hack the Makefile. +# +# Same thing applies for GTK+, if you are using that. Good luck. +# +# examples: +# SDL_INC_DIR := C:/2/SDL-1.1.8/include +# SDL_LIB_DIR := C:/2/SDL-1.1.8/lib +#-----------------------------------------------------------------------------# +ifeq ($(strip $(SDL_INC_DIR)),) + SDL_INC_DIR := please_set_me_cygwin_users +endif + +ifeq ($(strip $(SDL_LIB_DIR)),) + SDL_LIB_DIR := please_set_me_cygwin_users +endif + +ifeq ($(strip $(GTK_INC_DIR)),) + GTK_INC_DIR := please_set_me_cygwin_users +endif + +ifeq ($(strip $(GTK_LIB_DIR)),) + GTK_LIB_DIR := please_set_me_cygwin_users +endif + + + + + +#-----------------------------------------------------------------------------# +#-----------------------------------------------------------------------------# +#-----------------------------------------------------------------------------# +#-----------------------------------------------------------------------------# +# Everything below this line is probably okay. +#-----------------------------------------------------------------------------# +#-----------------------------------------------------------------------------# +#-----------------------------------------------------------------------------# +#-----------------------------------------------------------------------------# + + +#-----------------------------------------------------------------------------# +# CygWin autodetect. +#-----------------------------------------------------------------------------# + +ifeq ($(strip $(cygwin)),autodetect) + ifneq ($(strip $(shell gcc -v 2>&1 |grep "cygwin")),) + cygwin := true + else + cygwin := false + endif +endif + + +#-----------------------------------------------------------------------------# +# Set up video flags... +#-----------------------------------------------------------------------------# +using_sdl_at_all := false +ifeq ($(strip $(platform_video)),sdl) + using_sdl_at_all := true +endif +ifeq ($(strip $(platform_threads)),sdl) + using_sdl_at_all := true +endif + +ifeq ($(strip $(using_sdl_at_all)),true) + ifeq ($(strip $(cygwin)),true) + ifeq ($(strip $(SDL_INC_DIR)),please_set_me_cygwin_users) + $(error Cygwin users need to set the SDL_INC_DIR envr var.) + else + CFLAGS += -I$(SDL_INC_DIR) + endif + + ifeq ($(strip $(SDL_LIB_DIR)),please_set_me_cygwin_users) + $(error Cygwin users need to set the SDL_LIB_DIR envr var.) + else + LDFLAGS += -L$(SDL_LIB_DIR) -lSDL + endif + else + CFLAGS += $(shell sdl-config --cflags) + LDFLAGS += $(shell sdl-config --libs) + endif +endif + +ifeq ($(strip $(platform_video)),gtk) + ifeq ($(strip $(cygwin)),true) + ifeq ($(strip $(GTK_INC_DIR)),please_set_me_cygwin_users) + $(error Cygwin users need to set the GTK_INC_DIR envr var.) + else + CFLAGS += -I$(GTK_INC_DIR) + endif + + ifeq ($(strip $(GTK_LIB_DIR)),please_set_me_cygwin_users) + $(error Cygwin users need to set the GTK_LIB_DIR envr var.) + else + LDFLAGS += -L$(GTK_LIB_DIR) -lgtk -lgdk -lglib + endif + else + CFLAGS += $(shell gtk-config --cflags) + LDFLAGS += $(shell gtk-config --libs) + endif +endif + +#-----------------------------------------------------------------------------# +# Platform-specific binary stuff. +#-----------------------------------------------------------------------------# + +ifeq ($(strip $(cygwin)),true) + ASM = nasmw + EXE_EXT = .exe + ASMOBJFMT = win32 + ASMDEFS = -dC_IDENTIFIERS_UNDERSCORED + CFLAGS += -DC_IDENTIFIERS_UNDERSCORED +else + ASM = nasm + EXE_EXT = + ASMOBJFMT = elf +endif + + +#-----------------------------------------------------------------------------# +# General compiler, assembler, and linker flags. +#-----------------------------------------------------------------------------# + +BINDIR := bin +SRCDIR := src + +CFLAGS += $(USE_ASM) -I$(SRCDIR) -D_REENTRANT -fsigned-char -DPLATFORM_UNIX +CFLAGS += -Wall -Werror -fexceptions -frtti + +ifeq ($(strip $(debugging)),true) + CFLAGS += -DDEBUG -g -fno-omit-frame-pointer + LDFLAGS += -g -fno-omit-frame-pointer +else + CFLAGS += -D_NDEBUG -O2 -fomit-frame-pointer + LDFLAGS += -O2 -fomit-frame-pointer +endif + +ifneq ($(strip $(USE_ASM)),-DUSE_PORTABLE_C) + CFLAGS += -O2 -fasm +endif + +ASMFLAGS := -f $(ASMOBJFMT) $(ASMDEFS) + + +#-----------------------------------------------------------------------------# +# Source and target names. +#-----------------------------------------------------------------------------# + +MAINEXE := $(BINDIR)/toby$(strip $(EXE_EXT)) +STANDALONEEXE := $(BINDIR)/standalone$(strip $(EXE_EXT)) + +EXES := $(STANDALONEEXE) #$(MAINEXE) + +UTILSRCS := util/TobyCollection.cpp util/TobyStack.cpp util/TobyString.cpp \ + util/TobyLanguage.cpp +TURTLESPACESRCS := turtlespace/Turtle.cpp turtlespace/TurtleSpace.cpp + +valid_threads_target := false +ifeq ($(strip $(platform_threads)),pthreads) + THREADSRCS := platform/threads/pthreads/PthreadsThread.cpp \ + platform/threads/pthreads/PthreadsMutex.cpp + THREADSDIR := pthreads + valid_threads_target := true +endif + +ifeq ($(strip $(platform_threads)),sdl) + THREADSRCS := platform/threads/sdlthreads/SDLThread.cpp \ + platform/threads/sdlthreads/SDLMutex.cpp + THREADSDIR := sdlthreads + valid_threads_target := true +endif + +ifeq ($(strip $(platform_threads)),null) + THREADSRCS := platform/threads/nullthreads/NullThread.cpp \ + platform/threads/nullthreads/NullMutex.cpp + THREADSDIR := nullthreads + valid_threads_target := true +endif + +ifneq ($(strip $(valid_threads_target)),true) + $(error platform_threads flag in Makefile is not valid.) +endif + + +valid_video_target := false +ifeq ($(strip $(platform_video)),sdl) + VIDEOSRCS := platform/renderers/fbrenderer/FrameBufferTurtleSpaceRenderer.cpp \ + platform/renderers/sdlrenderer/SDLTurtleSpaceRenderer.cpp + VIDEODIR := sdlrenderer + valid_video_target := true +endif + +ifeq ($(strip $(platform_video)),gtk) + VIDEOSRCS := platform/renderers/gtkrenderer/GTKTurtleSpaceRenderer.cpp + VIDEODIR := gtkrenderer + valid_video_target := true +endif + +ifneq ($(strip $(valid_video_target)),true) + $(error platform_video flag in Makefile is not valid.) +endif + + + +COMMONSRCS := $(UTILSRCS) $(TURTLESPACESRCS) $(THREADSRCS) $(VIDEOSRCS) + +# Rule for getting list of objects from source +COMMONOBJS1 := $(COMMONSRCS:.c=.o) +COMMONOBJS2 := $(COMMONOBJS1:.cpp=.o) +COMMONOBJS3 := $(COMMONOBJS2:.asm=.o) + +COMMONOBJS := $(foreach f,$(COMMONOBJS3),$(BINDIR)/$(f)) +COMMONSRCS := $(foreach f,$(COMMONOBJS3),$(SRCDIR)/$(f)) + + +CLEANUP = $(wildcard *.exe) $(wildcard *.obj) \ + $(wildcard $(BINDIR)/*.exe) $(wildcard $(BINDIR)/*.obj) \ + $(wildcard *~) $(wildcard *.err) \ + $(wildcard .\#*) core + + +#-----------------------------------------------------------------------------# +# Rules. +#-----------------------------------------------------------------------------# + +# Rules for turning source files into .o files +$(BINDIR)/%.o: $(SRCDIR)/%.cpp + $(CC) -c -o $@ $< $(CFLAGS) + +$(BINDIR)/%.o: $(SRCDIR)/%.c + $(CC) -c -o $@ $< $(CFLAGS) + +$(BINDIR)/%.o: $(SRCDIR)/%.asm + $(ASM) $(ASMFLAGS) -o $@ $< + +.PHONY: all clean listobjs + +all: $(BINDIR) $(EXES) + +$(MAINEXE) : $(BINDIR) $(COMMONOBJS) $(BINDIR)/toby.o + $(LINKER) -o $(MAINEXE) $(LDFLAGS) $(COMMONOBJS) $(BINDIR)/toby.o + +$(STANDALONEEXE) : $(BINDIR) $(COMMONOBJS) $(BINDIR)/standalone.o + $(LINKER) -o $(STANDALONEEXE) $(LDFLAGS) $(COMMONOBJS) $(BINDIR)/standalone.o + +$(BINDIR): + @sh -c 'if [ ! -d $(BINDIR) ]; then mkdir $(BINDIR); fi' + @sh -c 'if [ ! -d $(BINDIR)/turtlespace ]; then mkdir $(BINDIR)/turtlespace; fi' + @sh -c 'if [ ! -d $(BINDIR)/util ]; then mkdir $(BINDIR)/util; fi' + @sh -c 'if [ ! -d $(BINDIR)/platform ]; then mkdir $(BINDIR)/platform; fi' + @sh -c 'if [ ! -d $(BINDIR)/platform/renderers ]; then mkdir $(BINDIR)/platform/renderers; fi' + @sh -c 'if [ ! -d $(BINDIR)/platform/renderers/fbrenderer ]; then mkdir $(BINDIR)/platform/renderers/fbrenderer; fi' + @sh -c 'if [ ! -d $(BINDIR)/platform/renderers/$(VIDEODIR) ]; then mkdir $(BINDIR)/platform/renderers/$(VIDEODIR); fi' + @sh -c 'if [ ! -d $(BINDIR)/platform/threads ]; then mkdir $(BINDIR)/platform/threads; fi' + @sh -c 'if [ ! -d $(BINDIR)/platform/threads/$(THREADSDIR) ]; then mkdir $(BINDIR)/platform/threads/$(THREADSDIR); fi' + +clean: + rm -f $(CLEANUP) + rm -rf $(BINDIR) + +listobjs: + @echo OBJECTS: + @echo $(COMMONOBJS) + @echo + @echo EXECUTABLES: + @echo $(EXES) + +showcfg: + @echo "Using CygWin : $(cygwin)" + @echo "Debugging : $(debugging)" + @echo "ASM flag : $(USE_ASM)" + @echo "Video library : $(platform_video)" + @echo "Thread library : $(platform_threads)" + +#-----------------------------------------------------------------------------# +# This section is pretty much just for Ryan's use to make distributions. +# You Probably Should Not Touch. +#-----------------------------------------------------------------------------# + +# These are the files needed in a binary distribution, regardless of what +# platform is being used. +BINSCOMMON = $(MAINEXE) $(STANDALONEEXE) +BINSCOMMON += LICENSE.TXT + +.PHONY: package msbins win32bins nocygwin +package: clean + cd .. ; zip -9rz ./toby-src-$(shell date +%m%d%Y).zip toby -x "*CVS*" < toby/FILEID.DIZ + + +ifeq ($(strip $(cygwin)),true) +msbins: win32bins + +win32bins: clean all +ifeq ($(strip $(platform_video)),sdl) + cp $(SDL_LIB_DIR)/SDL.dll . + EXTRAPACKAGELIBS := SDL.dll +endif + echo -e "\r\n\r\n\r\nHEY YOU.\r\n\r\n\r\nTake a look at README-win32bins.txt FIRST.\r\n\r\n\r\n--ryan. (icculus@linuxgames.com)\r\n\r\n" |zip -9rz ../toby-win32bins-$(shell date +%m%d%Y).zip $(EXES) $(EXTRAPACKAGELIBS) README-win32bins.txt + +else +msbins: nocygwin +win32bins: nocygwin +endif + +nocygwin: + @echo This must be done on a Windows box in the Cygwin environment. + +#-----------------------------------------------------------------------------# +# That's all, folks. +#-----------------------------------------------------------------------------# + +# end of Makefile ... diff --git a/README b/README new file mode 100644 index 0000000..4b63152 --- /dev/null +++ b/README @@ -0,0 +1,26 @@ +Documentation is in the docs/ directory. It's meager, but there are plans to + greatly enhance the contents of this directory in the near future. + +Quick start: + +Compile the source into an executable file: + +"make" + +Run it: + +"./toby" + +Obviously, this is for Unix environments like Linux. + +This program is licensed under the GNU General Public License. Please know + your rights and freedoms; the license text can be found in docs/LICENSE.TXT; + another copy is also in the root directory of the source tree, so you have + ample opportunity to find it. :) + +Enjoy! + +--ryan. (icculus@linuxgames.com) + + + diff --git a/docs/LICENSE.TXT b/docs/LICENSE.TXT new file mode 100644 index 0000000..ae3b531 --- /dev/null +++ b/docs/LICENSE.TXT @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/docs/changelog.txt b/docs/changelog.txt new file mode 100644 index 0000000..f911cc2 --- /dev/null +++ b/docs/changelog.txt @@ -0,0 +1,108 @@ +Toby CHANGELOG. + + +Please note that only the most significant changes are noted here. Also, +things that aren't visually interesting usually aren't mentioned. For +example, the fact that the keyword tables are now autosorted doesn't get +noted, but the fact that there's now a splash screen is noted. This is +meant to be informative, but not authoritative. + + +If you want a byte-for-byte revision history, please use the CVS server: + [hhmm...which is not currently available, since XNOT's demise. The + repository is intact, and will be made public again sooner or later.] + +What's new in Toby alpha6: +- Added (multidimensional) arrays, a String intrinsic type, and functions for + string manipulation to the interpreter and Toby language. +- Added French translation by Olivier Scalbert. Thanks! +- Rewrote TurtleSpace...AGAIN. TurtleSpace is now a class (not an interface) + which does all the high-level stuff. It talks to a TurtleSpaceRenderer + interface, which does the low-level stuff, like getting bits to the screen. + the high-level code (turtle management, etc) was moved out of JTurtleSpace + and into TurtleSpace. The rest of JTurtleSpace became SwingRenderer. + Turtle.java had all the painting and calculation stuff moved out of it and + into SwingRenderer. Turtle.java is now just a container of info for a given + turtle (angle, size, position, etc.), and is in the main turtlespace + package. TriangleTurtle mostly made it's way into SwingRenderer for now, and + will eventually move into TurtleSpace. Turtles, I guess, will always be + triangles. Abstractness has limits. :) +- Added (for my amusement as much as a test of the new TurtleSpace) an + SDL-based native code implementation of TurtleSpaceRenderer. It crashes + sooner than later, and everything but line-drawing is a no-op, but it runs! + This is not to be tried by the weak, but the C and java code is in there. +- This will be the last Java release by me. The next revision will be a C++ + rewrite. The Java code will be kept around, and enhancements and fixes will + still be accepted, but I will be focusing on the C++ version after alpha6. + +What's new in Toby alpha5: +- Fixes, improvements, and revisions, oh my! +- Added a thanks.txt file to the docs. +- Added some basic batch file/scripts for running Toby. +- The parser and interpreter have been COMPLETELY rewritten. The new system + has been termed the TUD engine (for Toby Universal Domination), and it's + much, MUCH, faster than the alpha4 interpreter for several reasons. + At the same time, it's also much more flexible, which means sooner or later + more languages will get plugged into this project. An honest-to-God LOGO + implementation comes to mind, but other things like scientific modelling + languages and such should not be ruled out, either. +- TurtleSpace has become an interface, which is implemented by a + JComponent-based widget. This abstraction will, eventually, allow us to + create a Spotlet (Java UI on the Palm Pilot) version of Toby. +- A lot of handy code was moved from TobyProcedure.java (most of what wasn't + moved out of this class was eventually rewritten) to SaneTokenizer.java. + Anything that could be considered abstract was moved out of TobyTokenizer + and placed in SaneTokenizer, too. Now TobyTokenizer.java does just what is + absolutely specific to the Toby language. +- The program has been separated into packages under the last.toby.* tree. +- Lots of things that had wide use, like TobyParseException, have been made + more abstract (in this case, renamed to "ParseException"). +- The interpreter is no longer a subclass of TurtleSpace. They are completely + separate entities, which makes better sense in the long run. +- TobyLanguage no longer uses printf()-style format tags, like "%s," "%d," + etc, since this prevents true language abstraction. Now tags are simply + "%1," "%2," etc., so they may be in any order in the text and still + recieve correct replacement, and we can change the output of "12" to "twelve" + in the source base and not have to change the local strings. Furthermore, + the English text is the default hardcoded language, but this may be + overridden at runtime by a toby.lang file, so new languages may be added + without a recompile or modification of the source code. +- Toby.java is now just an entry to the code. The original Toby.java has + become last.toby.gui.TobyFrame ... +- Fixes to the Swing code. +- SaneTokenizer now handles pushBack() better. +- Much, much more. + +...basically, this was a almost complete rewrite; every subsystem was looked +at, and reevaluated. There is still more to be done. + + +What's new in Toby alpha4: +- Lots of bug fixes and code improvements. +- Required Java version is now 1.2, Java 1.1 w/ Swing will not be + sufficient for much longer, I think. +- Toby now understands the "==" operator, which works like the Java + "==" operator...equivalence checking. +- Splash screen code is written and incorporated. Need a better graphic. +- An angle of zero degrees in TurtleSpace used to be due north. This was + because LOGO treated angles this way. This has been changed to follow + geometric convention; zero degrees is now due east. +- All literal strings have been moved to TobyLanguage.java ...Code has + been added to make dynamic language support a reality. Soon, there will + be translations to other languages, and in the next alpha, you won't + even need a recompile (or restart) to switch languages. +- On file open, if the file doesn't exist, we try to open filename.toby, + just in case. On save, if .toby extension isn't specified, we add it. +- Checks for various incompatibilities in virtual machines/class library + implementations have been moved to Incompatibilities.java. +- ...and much, much more. + + +What's new in Toby alpha3: +- Lots of stuff; this is the first public release, and I wasn't keeping a + changelog before this. :) + +--ryan. (icculus@lokigames.com) + + + diff --git a/docs/thanks.txt b/docs/thanks.txt new file mode 100644 index 0000000..c14fec0 --- /dev/null +++ b/docs/thanks.txt @@ -0,0 +1,31 @@ +At this point, TOBY has been entirely written, and maintained by + Ryan C. Gordon (icculus@linuxgames.com), but in the spirit of the GNU + project, the software is placed under GNU General Public License, and hopes + to see more contributors in the future. At such a time, this file will list + more names. :) In the meantime... + +...Ryan would like to give a shout out to the following: + +- Gregory S. Read, for testing Toby's limits, breaking the ELSEIF statement, + and being a bizarre sort of soul mate. Get yer slack on. +- Sabrina Blanks, April Andrews, and Nicki Publick for being unwitting test + subjects for Toby. +- Loren Osborne, for many hours of debate and discussion of implementation. +- Michael Roessler, who managed to sleep through the noise of my clicky + keyboard on many consecutive nights of hacking. +- The journal list gang, for listening to Ryan ramble about his life. +- Robert Spidle, for battling ninjas. +- The "Dragon book" for parsing concepts. Friggin' trees, man. +- Mr. Mullen and Mrs. Kelly, for putting me up to the original project. +- Karie Publick, for the naming the program, in a roundabout way. +- Mrs. Strohm, for many things I never knew I'd be thanking her for later. +- YOUcentric, for proof that Java doesn't necessarily suck. +- Sun Microsystems, for all the effort to disprove YOUcentric. +- Bernd Kreimeier, for thoughts on efficiency of the instanceof operator. +- Ani Difranco, Phish, Soul Coughing, Soul Miner's Daughter, Beastie Boys, + AMG, Belle and Sebastian, and Tool for providing the Soundtrack for da Hack. +- The Freshmeat crew, for cutting my appindex entry by about 18 sentences. +- ...and 'A' through 'F' in the phone book. + +--ryan. + diff --git a/docs/todo.txt b/docs/todo.txt new file mode 100644 index 0000000..9f74f0f --- /dev/null +++ b/docs/todo.txt @@ -0,0 +1,237 @@ +// Things still to be done for TOBY... +// some are bugfixes, some are enhancements, some are hopes and dreams... + + +(Most of these were written in regards to previous rewrites of the codebase. + The C++ version (the current one) is rewrite #4. Much of this is possibly + Java-specific.) + +ongoing bugfixes/enhancements : + Build a table with all available renderers, and let the user pick them + at runtime? Is this worthwhile? + + The FrameBuffer and SDL renderers are inefficient and broken. + + Move the source tree to src/ + + GLOBAL REFERENCING IS FUCKED. + + I want an alpha channel in the pen. By default, there's 15 or so colors + with setPenColor(). Then there's more advanced drawing with + setPenColorRGB. I also want a setPenColorRGBA or something. + + The only pencolor StdFunction should set red, green, blue, and alpha in + one call. The weaker versions should be in a Toby-specific package. + + I'd like to be able to have a way to tell TurtleSpace to change it's + coordinate system, so it's not pixel-based, but 1-100, or 0.0-1.0 or + 999 to 1055 or whatever. + + I want TurtleSpace to just be graphic-specific stuff. All the turtle + management, etc. should be in a separate class, which makes requests + through the interface for drawing lines between two points, text, etc. + + There should be a IntegerIntrinsic and a FloatIntrinsic (which may hold + a double), not a NumberIntrinsic. FloatIntrinsics should throw an + exeception if you call getIntValue() when it's holding an non-whole number. + + Hhm...might need a CastExpressionLogicContext or something. + + Strange duplicate error if I have a bogus file on the command line. + + A font height stdfunction would be good. + + JTurtleSpace: drawing the turtle is not resetting the GC's color. + + There isn't a "!=" operator in Toby?! + + Typechecking in the Toby parser is either screwed, or nonexistant. + + A screenshot facility might be nice. + + TobyMenuBar.java : Need to not hardcode TobyParser... + TobyMenuBar.java : Move execution to separate class. + + LogicContext should not have statics. + + The statics in LogicContext prevent multiple concurrent interpreters. + + swing turtle should be fixed width, not based on screen size. + + Allow JTurtleSpace to load graphics in background. + + stdfunctions should have their names assigned at construction by + the caller. + + Keep static references to the stdfunctions logic contexts, and + have the parsers install them in the globallogiccontext themselves. + + Add TurtleSpaceException. + + Have a turtle built on startup. + + Are all the linkImpl()s protected? executeImpl? + + use gratuitous verifyEndLine() calls. + + elseif hoses. + + Why are the fields in FlowException public? + + Can I have one java.awt.Graphics object per thread? So I don't need to + synchronize graphic functions? + + Sometimes program locks before initial paint. File open problem? + + Remove as many synchronizings from TurtleSpaces as possible. + + Make it so swing turtles don't need to be a square. This code is mostly in + place. Nuke private setSize() and the sideLength var and see what breaks... + + JTurtleSpace.getTurtleSpaceWidth() and height must not return different + values during interpretation, so must handle component resize events... + + Move VERSION and TITLE from last.toby.Toby to last.toby.util.TobyLanguage? + + Need method in TurtleSpace to determine due north + (it's different for Toby and LOGO...) + + not one damned comment is correct anymore. :) + + (See if getParent()/getValue() vs. public members are much slower...) + check all nodetrees freeResourceImpls... + + Make tobylanguage more neutral. + + Make ReturnException. + Make GotoException. + Make BreakException. + + Change NodeTree to TreeNode. ANnoying. + + We need to remove as many "SYNTAX ERROR" messages as possible. This + should be a last-choice message for when the parser is COMPLETELY + confused as to the state of the program. It should NEVER be used by + the interpreter. This might add a bunch of strings to TobyLanguage. + + incompatibility : Drawing on eastern edge of turtle space leaves + graphic artifacts on Win32 Sun JDK ... + + Parser.searchAlphabeticArray() could have a better search + algorithm. And alphabetizeArrayElements() is weak. It's just a lame + bubble sort right now. + + operator precedence needs to be done on levels (i.e. '*' and '/' are + on the same "level"...) + + Have Toby not start at screen size, but something average, and then + save the window position/size...? + + Maybe we can move all the file i/o from TobyFrame.java to its own class? + + Better splash graphic. PLEASE. + + Literal strings are all centralized into a static class, which is + good. Now, It would be better if TobyLanguage would, at startup, + read the literals from disk, so not even a recompile is needed to + change the language of the application. If worse comes to worse, + we default to the English literals which are static. + + can we pre-JIT specific classes/methods? + + Alt-hotkey should bring up the menus. A lot of the hotkeys aren't making + it past the text editor component right now. + + In fact, rip out that cruddy editor widget... + + The ultimate ongoing fix are the "!!!" comments. Any comments containing + '!!!' have been placed there to alert me that there is a bug/deficiency + in the code that is worth revisiting, but probably isn't crippling. As + such, they tend to build up. Feel free to fix any of these and submit + patches to rgordon@xnot.com ... + + Make inputarea use sane keys...I don't like the Swing defaults. Therefore + someday I'd like to either replace the Swing component with a homegrown + prettier/more functional textarea, or make some sort of customizer; + config file or whatnot. Mostly, I'd like SHIFT-DELETE and SHIFT-INSERT + to cut and paste. :) Other enhancements welcome. + + Functions can specify a return type and then return nothing. This should + be considered a bug. (Java and C consider it a feature, and it is, but + it confuses beginning programmers.) + + FIX VARVIEWER. It is BADLY broken. It's never worked right. + + When program is quitting, and you hit cancel on the "save" dialog, the + window still closes (although the VM doesn't terminate). This behavior + only seems to happen when the window manager tries to close the window + (clicking the little 'X' in win95, or whatnot under Linux)...selecting + "Quit" from the Toby menu seems to work correctly. + + Maximize window instead of sizing to screen width and height: is there a + way to do this in Swing? + + Move parse and execution time report code to more user-friendly output. + Right now it just dumps to stdout. I'd like it to go to + EditorInformationDisplay or something. + + Make Applet work with JavaScript...so JScript can pass a string of TOBY + code (perhaps from a form's textarea...) to the applet to draw. + + (Does the applet even work anymore?) + + +Milestones: NOT ACCURATE ANYMORE. + +alpha2 : completed. + Convert from AWT 1.1 to Swing. (COMPLETED) + remove dependency on last.* packages. (COMPLETED) + remove glaring bugs. (COMPLETED) + +alpha3 : completed. + Add globals (COMPLETED) + descending FOR loops and STEPs... (COMPLETED) + WHILEs... (COMPLETED) + line/column readout in TobyInputArea. (COMPLETED) + +alpha4 : completed. + allow assignments in var declaration. (COMPLETED) + more standard functions... (COMPLETED) + Fix as many "!!!" comments as possible. (COMPLETED) + Initial dynamic language support. (COMPLETED) + Add splash screen code. (COMPLETED) + +alpha5 : completed. + Fully separate parser and interpreter. (COMPLETED) + Separate interpreter and TurtleSpace. (COMPLETED) + Rewrite interpreter to use parse trees. (COMPLETED) + Split this thing up into packages. (COMPLETED) + Abstract TurtleSpace into interface. (COMPLETED) + +alpha6 : in progress. + COMMENT EVERYTHING. + add arrays? (COMPLETED) + add String intrinsic? (COMPLETED) + Printing source code. + Printing current TurtleSpace. + Undo/redo + Make TurtleSpace into a bean. + Add status bar to bottom of frame... + Implement help system. + Rewrite VarViewer to be cooler. + Rewrite/replace text editor. + German langfile. + Spanish langfile. + French langfile. (COMPLETED) + Write Spotlet version of TurtleSpace. + Verify the applet works in a + Java 1.2 compatible browser (HotJava?) + +1.0 : not yet begun. + fix bugs reported from betas. + Clean up interface problems reported in beta2. + fix all outstanding bugs. + release. + +// end of todo ... + diff --git a/programs/april.toby b/programs/april.toby new file mode 100644 index 0000000..0963203 --- /dev/null +++ b/programs/april.toby @@ -0,0 +1,61 @@ +function main() returns nothing + // april kicks ass + flower() +endfunction + + +function flower() returns nothing + number i + number bob + number direction + + direction = 1 + + bob = 0 + + for i = 100 downto 10 step -5 + bob = bob + direction + + if (bob >= 12) + bob = 11 + direction = -1 + endif + + if (bob <= 0) + bob = 0 + direction = 1 + endif + + setPenColor(bob) + + webbox(i) + endfor + +endfunction + + +function webbox(number m) returns nothing + number i + + for i = 1 to 360 / 10 + box(m) + turnRight(10) + + endfor +endfunction + + +function box(number size) returns nothing + + number i + + for i = 1 to 4 + goForward(size) + turnRight(90) + endfor + +endfunction + + + + diff --git a/programs/april_modified.toby b/programs/april_modified.toby new file mode 100644 index 0000000..b443c7a --- /dev/null +++ b/programs/april_modified.toby @@ -0,0 +1,63 @@ +function main() returns nothing + // april kicks ass + flower() +endfunction + + +function flower() returns nothing + number i + number bob + number direction + + direction = 1 + + bob = 0 + + for i = 10 to 100 step 5 + bob = bob + direction + + if (bob >= 12) + bob = 11 + direction = -1 + endif + + if (bob <= 0) + bob = 0 + direction = 1 + endif + + setPenColor(bob) + webbox(i) + endfor + +endfunction + + +function webbox(number m) returns nothing + number i + + for i = 1 to 360 / 10 + box(m) + turnRight(10) + + endfor +endfunction + + +function box(number size) returns nothing + + number i + + for i = 1 to 4 + goForward(size) + turnRight(90) + endfor + +endfunction + + + + + + + diff --git a/programs/boolTest.toby b/programs/boolTest.toby new file mode 100644 index 0000000..890b35e --- /dev/null +++ b/programs/boolTest.toby @@ -0,0 +1,51 @@ +//------------------------------------------------------------ +// boolTest.toby ... Should draw two large circles +// of dotted lines, connected in the center of +// TurtleSpace. +// +// - Tests IF statement, BOOLEAN intrinsic. +// +// Copyright (c) Lighting and Sound Technologies, 1998. +// Written by Ryan C. Gordon. +//------------------------------------------------------------ + +function main() returns nothing + + boolean isDrawTime + boolean goRight + number i + + disableFence() + + isDrawTime = true + + for i = 1 to 720 + if (isDrawTime == true) + setPenDown() + isDrawTime = false + else + setPenUp() + isDrawTime = true + endif + + goForward(10) + + // this isn't meant to be + // efficient. This is a test. + if (i > 360) + goRight = true + endif + + if (goRight) + turnRight(1) + else + turnLeft(1) + endif + endfor + +endfunction + +// end of boolTest.toby ... + + + diff --git a/programs/boxes.toby b/programs/boxes.toby new file mode 100644 index 0000000..fd82d3d --- /dev/null +++ b/programs/boxes.toby @@ -0,0 +1,46 @@ +// boxes.toby : Various cool geometrics with simple boxes. + +function box(number size) returns nothing +//---------------------------------------------------------// +// Most functions in this package make use of this // +// function for cool stuff. // +// // +// params : (number) size == size of one side of box. // +// returns : void. // +//---------------------------------------------------------// + number i + for i = 1 to 4 + goForward(size) + turnRight(90) + endfor +endfunction + + + +function webBox(number size, number angle) returns nothing +//---------------------------------------------------------// +// Make a weblike pattern out of boxes. // +// // +// params : (number) size == size of one side of box. // +// (number) angle == amount of turn for each // +// box. Smaller number == // +// more boxes. // +// returns : void. // +//---------------------------------------------------------// + number i + for i = 1 to (360 / angle) + box(size) + turnRight(angle) + endfor +endfunction + + +function main() returns nothing + webBox(100, 2) +endfunction + +// end of boxes.toby ... + + + + diff --git a/programs/colorBlocks.toby b/programs/colorBlocks.toby new file mode 100644 index 0000000..68d6562 --- /dev/null +++ b/programs/colorBlocks.toby @@ -0,0 +1,30 @@ +function main() returns nothing + + number i + + for i = 0 to 15 + setPenColor(i) + fillBlock(i * 20, (i + 1) * 20) + endfor + +endfunction + + +function fillBlock(number start, number stop) returns nothing + + number i + + setPenDown() + + for i = start to stop + setTurtleXY(0, i) + setAngle(0) + goForward(30) + endfor + +endfunction + + + + + diff --git a/programs/connie.toby b/programs/connie.toby new file mode 100644 index 0000000..4745534 --- /dev/null +++ b/programs/connie.toby @@ -0,0 +1,74 @@ +// +// Something quick to test STEP...first four +// circles should have turtle loop around +// it three times. The next four should just draw. +// +// Copyright (c) 1999 Lighting and Sound Technologies. +// Written by Ryan C. Gordon. + +function main() returns nothing + number i + + setPenColor(1) + + for i = 1 to 360 + turnRight(3) + goForward(5) + endfor + for i = 1 to 360 step 1 + turnLeft(3) + goForward(5) + endfor + turnRight(90) + for i = 360 downto 1 + turnRight(3) + goForward(5) + endfor + for i = 360 downto 1 step -1 + turnLeft(3) + goForward(5) + endfor + + setPenColor(2) + + + // these four for loops should not run... + for i = 1 downto 360 step -1 + goForward(1000) + endfor + for i = 360 to 1 step 1 + goForward(1000) + endfor + for i = 1 downto 360 step -1.7 + goForward(1000) + endfor + for i = 360 to 1 step 1.5 + goForward(1000) + endfor + + setPenColor(4) + + turnRight(45) + for i = 1 to 360 step 3.0 + turnRight(3) + goForward(5) + endfor + for i = 1 to 360 step 3 + turnLeft(3) + goForward(5) + endfor + turnRight(90) + for i = 360 downto 1 step -3.0 + turnRight(3) + goForward(5) + endfor + for i = 360 downto 1 step -3 + turnLeft(3) + goForward(5) + endfor + + + hideTurtle() +endfunction + + diff --git a/programs/eyes.toby b/programs/eyes.toby new file mode 100644 index 0000000..b4206b8 --- /dev/null +++ b/programs/eyes.toby @@ -0,0 +1,91 @@ +//------------------------------------------------------------ +// eyes.toby : draw some eyes on the screen. +// +// Copyright (c) Lighting and Sound Technologies, 1998. +// Written by Ryan C. Gordon. +//------------------------------------------------------------ + +// Global variables... +//number eyeballStep + + +function eyeballs(number skip) returns nothing + number i + boolean isDrawTime + + isDrawTime = false + + setPenColor(4) + for i = 1 to 720 + if (isDrawTime) + setPenDown() + isDrawTime = false + else + setPenUp() + isDrawTime = true + endif + goForward(skip) + + if (i >= 360) + turnRight(1) + else + turnLeft(1) + endif + endfor +endfunction + + +function pupil(number x, number y) returns nothing + number color = 0 + number i + number direction = 1 + + setTurtleXY(x, y) + + for i = 1 to 360 + setPenColor(color) + setPenDown() + goForward(30) + setPenUp() + goBackward(30) + turnRight(1) + color = color + direction + if (color >= 15) + direction = -1 + elseif (color <= 0) + direction = 1 + endif + endfor +endfunction + + +function main() returns nothing + number centerX + number centerY + + centerX = getTurtleX() + centerY = getTurtleY() + + eyeballs(2) + +// center = calculateRadius(eyeballStep) + + + pupil(centerX - 115, centerY) + pupil(centerX + 115, centerY) + + // use the turtle as a "nose." :) + setTurtleXY(centerX, centerY + 50) + setAngle(90) + +endfunction + +// end of eyes.toby ... + + + + + + + + diff --git a/programs/flowerVines.toby b/programs/flowerVines.toby new file mode 100644 index 0000000..8fbc5e6 --- /dev/null +++ b/programs/flowerVines.toby @@ -0,0 +1,53 @@ +number r = 0.0 +number g = 0.0 +number b = 0.0 + +function main() returns nothing + hideTurtle() + disableFence() + rightDragon(20, 3) +endfunction + +function leftDragon(number iteration, number dist) returns nothing + r = r + 0.001 + if (r > 1.0) + r = 0.0 + endif + setPenColorRGB(r, g, b) + if (iteration == 0) + g = g + 0.01 + if (g > 1.0) + g = 0.0 + endif + goForward(dist) + else + leftDragon(iteration - 1, dist) + turnLeft(90) + rightDragon(iteration - 1, dist) + endif +endfunction + + +function rightDragon(number iteration, number dist) returns nothing + b = b + 0.001 + if (b > 1.0) + b = 0.0 + endif + setPenColorRGB(r, g, b) + if (iteration == 0) + g = g + 0.01 + if (g > 1.0) + g = 0.0 + endif + goForward(dist) + else + leftDragon(iteration - 1, dist) + turnRight(90) + rightDragon(iteration - 1, dist) + endif +endfunction + + + + + diff --git a/programs/globTest.toby b/programs/globTest.toby new file mode 100644 index 0000000..401e771 --- /dev/null +++ b/programs/globTest.toby @@ -0,0 +1,30 @@ +//--------------------------------------------------- +// If globals are working correctly, this should +// draw a line east, WAY off the edge of +// TurtleSpace. Otherwise, it'll just draw a +// line somewhere other than due east, or maybe just +// draw a line about 5 pixels wide or give an error +// or something like that. +// +//Copyright (c) 1999 Lighting and Sound Technologies. +// Written by Ryan C. Gordon. +//--------------------------------------------------- + +number thisIsGlobal = 90 + +function main() returns nothing + disableFence() + turnRight(thisIsGlobal) + thisIsGlobal = 10000 + testGlob() + goForward(thisIsGlobal) +endfunction + +function testGlob() returns nothing + number thisIsGlobal + + thisIsGlobal = 5 +endfunction + + + diff --git a/programs/gradient.toby b/programs/gradient.toby new file mode 100644 index 0000000..ab64149 --- /dev/null +++ b/programs/gradient.toby @@ -0,0 +1,34 @@ +function main() returns nothing + + number i = 0 + number stepSizeH = 1 / getTurtleSpaceWidth() + number stepSizeV = 1 / getTurtleSpaceHeight() + number r = 0.0 + number g = 1.0 + number b = 0.0 + + disableFence() + hideTurtle() + turnRight(90) + + for b = 0.0 to 1.0 step stepSizeV + setTurtleXY(0, i) + for r = 0.0 to 1.0 step stepSizeH + setPenColorRGB(r, g, b) + goForward(1) + endfor + g = g - stepSizeV + i = i + 1 + endfor + +endfunction + + + + + + + + + + diff --git a/programs/gradient2.toby b/programs/gradient2.toby new file mode 100644 index 0000000..515aff5 --- /dev/null +++ b/programs/gradient2.toby @@ -0,0 +1,32 @@ +function main() returns nothing + + number i = 0 + number stepSizeH = 1 / getTurtleSpaceWidth() + number stepSizeV = 1 / getTurtleSpaceHeight() + number r = 0.0 + number b = 0.0 + + disableFence() + hideTurtle() + turnRight(90) + + for b = 0.0 to 1.0 step stepSizeV + setTurtleXY(0, i) + for r = 0.0 to 1.0 step stepSizeH + setPenColorRGB(r, 0.0, b) + goForward(1) + endfor + i = i + 1 + endfor + +endfunction + + + + + + + + + + diff --git a/programs/greg1.toby b/programs/greg1.toby new file mode 100644 index 0000000..a1cbea9 --- /dev/null +++ b/programs/greg1.toby @@ -0,0 +1,34 @@ +function main() returns nothing + number i + number j + + for j = 1 to 100 + for i = 1 to 360 + goForward(1) + turnRight(1) + endfor + turnRight(j) + endfor +endfunction + + +function circle() returns nothing + number i + number color + + for i = 1 to 360 step 4 + + color = round(random() * 10) + 1 + setPenColor(color) + goForward(3) + turnRight(1) + endfor +endfunction + + + + + + + + diff --git a/programs/nesting.toby b/programs/nesting.toby new file mode 100644 index 0000000..600a0d9 --- /dev/null +++ b/programs/nesting.toby @@ -0,0 +1,50 @@ +//-------------------------------------------------------- +// nesting.toby -- A program to test nested FORs and IFs. +// +// This program will draw boxes increasingly large, and +// in many colors, to test if Toby can handle some +// nested FORs and IFs. It should look like a square +// with different colored lines pulsing, and in the +// end, four squares, moving in different directions +// should be drawn. +// +// There are cleaner ways to write this program, but +// we wanted to nest stuff. +// +// Copyright (c) 1999 Lighting and Sound Technologies +// Written by Ryan C. Gordon. +//-------------------------------------------------------- + +function main() returns nothing + number totalIterations + number boxSize + number boxLoop + number color + number direction + + hideTurtle() + + for direction = 1 to 4 + color = 0 + for totalIterations = 1 to 5 + for boxSize = 1 to 100 + color = color + 1 + if (color > 15) + color = 0 + endif + setPenColor(color) + for boxLoop = 1 to 4 + goForward(boxSize) + turnLeft(90) + endfor + endfor + endfor + turnRight(90) + endfor + +endfunction + + + + + diff --git a/programs/nicki.toby b/programs/nicki.toby new file mode 100644 index 0000000..8e9b874 --- /dev/null +++ b/programs/nicki.toby @@ -0,0 +1,53 @@ +number color + +function main() returns nothing + disableFence() + hideturtle() + flower(50, 100, 1) +endfunction + + +function flower(number start, number end, number hop) returns nothing +// nicki is cool + + number joe + number color = 0 + number direction = 1 + + for joe = start to end step hop + color = color + direction + + if (color > 11) + color = 11 + direction = -1 + endif + + if (color < 0) + color = 0 + direction = 1 + endif + + setPenColor(color) + webbox(joe) + endfor +endfunction + +function webbox(number size) returns nothing + number x + + for x = 1 to 360 / 10 + octogon(size) + turnRight(15) + endfor +endfunction + + +function octogon(number size) returns nothing + number i + + for i = 1 to 8 + goForward(size) + turnRight(45) + endfor +endfunction + diff --git a/programs/psychedelic.toby b/programs/psychedelic.toby new file mode 100644 index 0000000..af8f92c --- /dev/null +++ b/programs/psychedelic.toby @@ -0,0 +1,36 @@ +number color + +function main() returns nothing + number i + color = 0 + disableFence() +hideTurtle() + for i = 1 to 360 step 2 + circle() + turnRight(2) + endfor +endfunction + + +function circle() returns nothing + number i + + for i = 1 to 360 + color = color + 1 + if (color > 11) + color = 0 + endif + setPenColor(color) + goForward(3) + turnRight(1) + endfor +endfunction + + + + + + + + + diff --git a/programs/psychedelic2.toby b/programs/psychedelic2.toby new file mode 100644 index 0000000..e906510 --- /dev/null +++ b/programs/psychedelic2.toby @@ -0,0 +1,33 @@ +function main() returns nothing + number i + number color + color = 0 + + disableFence() + hideTurtle() + + for i = 1 to 360 step 2 + setPenColor(color) + circle() + turnRight(2) + color = color + 1 + if (color > 15) + color = 0 + endif + endfor +endfunction + + +function circle() returns nothing + number i + + for i = 1 to 360 + goForward(3) + turnRight(1) + endfor +endfunction + + + + + diff --git a/programs/psychedelic3.toby b/programs/psychedelic3.toby new file mode 100644 index 0000000..f5d07dd --- /dev/null +++ b/programs/psychedelic3.toby @@ -0,0 +1,28 @@ +function main() returns nothing + number i + + for i = 1 to 360 step 2 + circle() + turnRight(2) + endfor +endfunction + + +function circle() returns nothing + number i + number color + + for i = 1 to 360 + + color = round(random() * 10) + 1 + setPenColor(color) + goForward(3) + turnRight(1) + endfor +endfunction + + + + + + diff --git a/programs/psychedelic4.toby b/programs/psychedelic4.toby new file mode 100644 index 0000000..498d1a3 --- /dev/null +++ b/programs/psychedelic4.toby @@ -0,0 +1,32 @@ +function main() returns nothing + number i + number angle = 0 + + for i = 1 to 360 step 2 + circle() + homeTurtle() + angle = angle + 3 + turnRight(angle) + endfor +endfunction + + +function circle() returns nothing + number i + number color + + for i = 1 to 360 step 4 + + color = round(random() * 10) + 1 + setPenColor(color) + goForward(3) + turnRight(1) + endfor +endfunction + + + + + + + diff --git a/programs/rotateTurtle.toby b/programs/rotateTurtle.toby new file mode 100644 index 0000000..ccf4a94 --- /dev/null +++ b/programs/rotateTurtle.toby @@ -0,0 +1,14 @@ +// This just rotates the turtle once around. + +function main() returns nothing + number i + + for i = 1 to 360 + turnRight(1) + pause(5) + endfor +endfunction + + + + diff --git a/programs/sabrina.toby b/programs/sabrina.toby new file mode 100644 index 0000000..ccca300 --- /dev/null +++ b/programs/sabrina.toby @@ -0,0 +1,44 @@ +function main() returns nothing + number xMax = getTurtleSpaceWidth() + number yMax = getTurtleSpaceHeight() + number xPos + number yPos + number angle + number distance + number color + + disableFence() + hideTurtle() + + while (true) + color = round(random() * 14) + 1 + xPos = round(random() * xMax) + 1 + yPos = round(random() * yMax) + 1 + angle = round(random() * 360) + 1 + distance = random() * (yMax / 2) + + setPenColor(color) + setTurtleXY(xPos, yPos) + setAngle(angle) + goForward(distance) + endwhile + +endfunction + + + + + + + + + + + + + + + + + + diff --git a/programs/sabrina2.toby b/programs/sabrina2.toby new file mode 100644 index 0000000..a7d7918 --- /dev/null +++ b/programs/sabrina2.toby @@ -0,0 +1,33 @@ + +function main() returns nothing + + number myValue + + number i + + while (true) + for i = 1 to 36 + setPenColor(round(random() * 15)) + myValue = random() * 100 + box(myValue) + + turnRight(10) + endfor + cleanupTurtleSpace() + endwhile +endfunction + + +function box(number size) returns nothing + + number counter + + for counter = 1 to 4 + goForward(size) + turnRight(90) + endfor + +endfunction + + + diff --git a/programs/swirls.toby b/programs/swirls.toby new file mode 100644 index 0000000..88d08ad --- /dev/null +++ b/programs/swirls.toby @@ -0,0 +1,69 @@ +number r = 0.0 +number g = 0.0 +number b = 0.0 + +function main() returns nothing + //doTopLeftFan() + doDragon() +endfunction + +function doTopLeftFan() returns nothing + setTurtleXY(10, 100) + setAngle(90) + fanLeft(175, 10) +endfunction + +function fanLeft(number distance, number angle) returns nothing + if (distance >= 0) + goForward(distance) + goBackward(distance - 10) + turnLeft(angle) + fanLeft(distance - 5, angle) + endif +endfunction + +function doDragon() returns nothing + rightDragon(20, 3) +endfunction + +function leftDragon(number iteration, number dist) returns nothing + r = r + 0.001 + if (r > 1.0) + r = 0.0 + endif + setPenColorRGB(r, g, b) + if (iteration == 0) + g = g + 0.01 + if (g > 1.0) + g = 0.0 + endif + goForward(dist) + else + leftDragon(iteration - 1, dist) + turnLeft(90) + rightDragon(iteration - 1, dist) + endif +endfunction + + +function rightDragon(number iteration, number dist) returns nothing + b = b + 0.001 + if (b > 1.0) + b = 0.0 + endif + setPenColorRGB(r, g, b) + if (iteration == 0) + g = g + 0.01 + if (g > 1.0) + g = 0.0 + endif + goForward(dist) + else + leftDragon(iteration - 1, dist) + turnRight(90) + rightDragon(iteration - 1, dist) + endif +endfunction + + + diff --git a/programs/testArray.toby b/programs/testArray.toby new file mode 100644 index 0000000..494cf15 --- /dev/null +++ b/programs/testArray.toby @@ -0,0 +1,82 @@ +// this is not meant to be efficient. This is meant to +// test arrays in Toby. --ryan. + +function main() returns nothing + number i + array of number[1 to 2] screendim + array of number[1 to 13][0 to 1] myarray + + screendim[1] = getTurtleSpaceWidth() + screendim[2] = getTurtleSpaceHeight() + + homeTurtle() + drawMoon(screendim[1] - (screendim[1] / 4), screendim[2] - ((screendim[2] / 8) * 7)) + + homeTurtle() + myarray[1][0] = 90 + myarray[1][1] = 100 + myarray[2][0] = -90 + myarray[2][1] = 100 + myarray[3][0] = -90 + myarray[3][1] = 200 + myarray[4][0] = -90 + myarray[4][1] = 100 + myarray[5][0] = -90 + myarray[5][1] = 100 + myarray[6][0] = -90 + myarray[6][1] = 50 + myarray[7][0] = 90 + myarray[7][1] = 25 + myarray[8][0] = 90 + myarray[8][1] = 50 + myarray[9][0] = -90 + myarray[9][1] = 75 + myarray[10][0] = -90 + myarray[10][1] = 100 + myarray[11][0] = -60 + myarray[11][1] = 115 + myarray[12][0] = -60 + myarray[13][1] = 115 + + runArray(myarray) + + hideTurtle() +endfunction + + +/// !!! should be an error. +function runArray(array of number [1 to 3][0 to 1] anArray) returns nothing + number i + + for i = 1 to 13 + turnRight(anArray[i][0]) + goForward(anArray[i][1]) + endfor +endfunction + + +// this would be a sun, but I'm too lazy to draw more +// than a circle. :) +function drawMoon(number x, number y) returns nothing + number i + number moonstep = 2 + + setPenDown() + setTurtleXY(x - 29, y) + + for i = 1 to 360 / moonstep + goForward(1) + turnRight(moonstep) + endfor +endfunction + +// end of arrayTest.toby ... + + + + + + + + + diff --git a/programs/testMultiTurtling.toby b/programs/testMultiTurtling.toby new file mode 100644 index 0000000..6f1d702 --- /dev/null +++ b/programs/testMultiTurtling.toby @@ -0,0 +1,46 @@ +//--------------------------------------------------------- +// A basic test of multiturtling capabilities. +// +// This should have four turtles each draw +// a circle, so you get a diamond-like +// cluster. The north circle should be blue, +// the west green, east cyan, and south red. +// +// Written by Ryan C. Gordon. +// Copyright (c) Lighting and Sound Technologies, 2000. +//--------------------------------------------------------- + +function main() returns nothing + number i + number turtleId + + disableFence() + addTurtle() + addTurtle() + addTurtle() + + setPenColor(3) + + useTurtle(1) + turnRight(90) + setPenColor(4) + useTurtle(2) + turnLeft(90) + setPenColor(1) + useTurtle(3) + turnLeft(180) + setPenColor(2) + + for i = 1 to 360 + for turtleId = 0 to 3 + useTurtle(turtleId) + turnRight(1) + goForward(1) + endfor + endfor +endfunction + + + + + diff --git a/programs/testRecursive.toby b/programs/testRecursive.toby new file mode 100644 index 0000000..d359fcb --- /dev/null +++ b/programs/testRecursive.toby @@ -0,0 +1,14 @@ + +number counter = 0 + +function main() returns nothing + goForward(100) + turnRight(90) + + counter = counter + 1 + if (counter < 4) + main() + endif +endfunction + + diff --git a/programs/testReturn.toby b/programs/testReturn.toby new file mode 100644 index 0000000..634409a --- /dev/null +++ b/programs/testReturn.toby @@ -0,0 +1,14 @@ + + +function main() returns nothing + number x = 10 + x = returnOneThousand() + goForward(x) +endfunction + + +function returnOneThousand() returns number + + return(1000) +endfunction + diff --git a/programs/testStep.toby b/programs/testStep.toby new file mode 100644 index 0000000..216dbf4 --- /dev/null +++ b/programs/testStep.toby @@ -0,0 +1,67 @@ +// +// Something quick to test STEP...first four +// circles should have turtle loop around +// it three times. The next four should just draw. +// +// Copyright (c) 1999 Lighting and Sound Technologies. +// Written by Ryan C. Gordon. + +function main() returns nothing + number i + + for i = 1 to 360 + turnRight(3) + goForward(5) + endfor + for i = 1 to 360 step 1 + turnLeft(3) + goForward(5) + endfor + turnRight(90) + for i = 360 to 1 + turnRight(3) + goForward(5) + endfor + for i = 360 to 1 step -1 + turnLeft(3) + goForward(5) + endfor + + // these four for loops should not run... + for i = 1 to 360 step -1 + goForward(1000) + endfor + for i = 360 to 1 step 1 + goForward(1000) + endfor + for i = 1 to 360 step -1.7 + goForward(1000) + endfor + for i = 360 to 1 step 1.5 + goForward(1000) + endfor + + + turnRight(45) + for i = 1 to 360 step 3.0 + turnRight(3) + goForward(5) + endfor + for i = 1 to 360 step 3 + turnLeft(3) + goForward(5) + endfor + turnRight(90) + for i = 360 to 1 step -3.0 + turnRight(3) + goForward(5) + endfor + for i = 360 to 1 step -3 + turnLeft(3) + goForward(5) + endfor + + hideTurtle() +endfunction + + diff --git a/programs/testString.toby b/programs/testString.toby new file mode 100644 index 0000000..fa36283 --- /dev/null +++ b/programs/testString.toby @@ -0,0 +1,86 @@ +function main() returns nothing + string x + array of string[0 to 10] myStrings + number fontHeight = 12 + number i + string leftRight + + setPenUp() + + leftRight = "Left side-=-Middle-=-Right side" + x = "test of stringlength() was successful." + x = rightString(x, stringlength(x) - 8) + + myStrings[0] = "String array test." + myStrings[1] = "w00t, old boy, w00t!" + myStrings[2] = joinStrings("this string->", "<-was joined") + myStrings[3] = leftString(leftRight, 9) + myStrings[4] = substring(leftRight, 12, 6) + myStrings[5] = rightString(leftRight, 10) + myStrings[6] = upperCaseString("ThiS IS uPpER casEd.") + myStrings[7] = lowerCaseString("ThiS IS LoWEr casEd.") + myStrings[8] = x + myStrings[9] = "last one" + + setTurtleXY(10, fontHeight) + setAngle(0) + x = "passing string in a variable to a function." + drawString(x) + + setAngle(90) + goForward(fontHeight) + setAngle(0) + drawString("string literal in a function call.") + + setAngle(90) + goForward(fontHeight) + setAngle(0) + if ("equality tester" == "equality tester") + drawString("equality operator working.") + else + drawString("equality operator NOT working!") + endif + + setAngle(90) + goForward(fontHeight) + setAngle(0) + if ("abc" > "def") + drawString("greater-than operator working.") + else + drawString("greater-than operator NOT working!") + endif + + setAngle(90) + goForward(fontHeight) + setAngle(0) + if ("abc" < "def") + drawString("less-than operator NOT working.") + else + drawString("less-than operator working!") + endif + + + + homeTurtle() + + for i = 0 to 10 + setPenColor(i + 1) + goForward(fontHeight * 3) + drawString(myStrings[i]) + goBackward(fontHeight * 3) + turnRight(36) + endfor + + // test rotation. + // test strlen + +endfunction + + + + + + + + + diff --git a/programs/testTurtleSpace.toby b/programs/testTurtleSpace.toby new file mode 100644 index 0000000..a01cab7 --- /dev/null +++ b/programs/testTurtleSpace.toby @@ -0,0 +1,68 @@ +//------------------------------------------------------------------- +// Test that TurtleSpace coordinate functions are functioning +// properly. You should end up with four arrows, east west, north +// and south, extending to the edges of TurtleSpace, centered on the +// edge. +// +// Copyright (c) 1999 Lighting and Sound Technologies. +// Written by Ryan C. Gordon. +//------------------------------------------------------------------- + +function main() returns nothing + number i + number maxX = getTurtleSpaceWidth() + number maxY = getTurtleSpaceHeight() + number centerX = getTurtleX() + number centerY = getTurtleY() + + hideTurtle() + + // horizontal shaft. + setTurtleXY(0, centerY) + setAngle(0) + goForward(maxX) + + // vertical shaft. + setTurtleXY(centerX, 0) + setAngle(90) + goForward(maxY) + + // western arrow. + setTurtleXY(0, centerY) + setAngle(-45) + goForward(100) + setTurtleXY(0, centerY) + setAngle(45) + goForward(100) + + // eastern arrow. + setTurtleXY(maxX, centerY) + setAngle(-135) + goForward(100) + setTurtleXY(maxX, centerY) + setAngle(135) + goForward(100) + + // northern arrow. + setTurtleXY(centerX, 0) + setAngle(135) + goForward(100) + setTurtleXY(centerX, 0) + setAngle(45) + goForward(100) + + // southern arrow. + setTurtleXY(centerX, maxY) + setAngle(-135) + goForward(100) + setTurtleXY(centerX, maxY) + setAngle(-45) + goForward(100) +endfunction + + + + + + + diff --git a/programs/testWhile.toby b/programs/testWhile.toby new file mode 100644 index 0000000..3202d6f --- /dev/null +++ b/programs/testWhile.toby @@ -0,0 +1,56 @@ +//---------------------------------------------------- +// This is an over-glorified test of the +// WHILE/ENDWHILE construct, buried in the +// doTriangle() function. If it works, you should +// end up with three filled-in triangles. +// +// Copyright (c) 1999 Lighting and Sound Technologies. +// Written by Ryan C. Gordon. +//---------------------------------------------------- + +function main() returns nothing + hideTurtle() + nuclearSymbol(150) +endfunction + + +function nuclearSymbol(number size) returns nothing + number i + + setPenColor(14) + + for i = 1 to size + setAngle(300) + doTriangle(i) + + setAngle(180) + doTriangle(i) + + setAngle(60) + doTriangle(i) + endfor +endfunction + + +function doTriangle(number size) returns number + number i + + i = 1 + + while (i <= 3) + i = i + 1 + goForward(size) + turnRight(360 / 3) + endwhile +endfunction + + + + + + + + + + + diff --git a/programs/theLight.toby b/programs/theLight.toby new file mode 100644 index 0000000..bd5c081 --- /dev/null +++ b/programs/theLight.toby @@ -0,0 +1,46 @@ +// theLight.toby : Just plain cool. + +function clockwise(number size) returns nothing + number i + for i = 1 to 360 + setPenDown() + goForward(size) + setPenUp() + goBackward(size) + turnRight(1) + endfor +endfunction + + +function theLight() returns nothing + +// This will eventually step in a FOR loop... + + clockwise(50) + clockwise(100) + clockwise(150) + clockwise(200) + clockwise(250) + clockwise(300) + clockwise(350) + clockwise(400) + clockwise(450) + clockwise(500) +endfunction + + +function main() returns nothing + disableFence() + theLight() +endfunction + +// end of theLight.toby ... + + + + + + + + + diff --git a/programs/triangleWeb.toby b/programs/triangleWeb.toby new file mode 100644 index 0000000..1b2fded --- /dev/null +++ b/programs/triangleWeb.toby @@ -0,0 +1,45 @@ +function main() returns nothing + number top = getTurtleSpaceWidth() + if (top < getTurtleSpaceHeight()) + top = getTurtleSpaceHeight() + endif + + disableFence() + setPenColor(8) + spiderWeb(top, top * 0.03, top * 0.15) +endfunction + +function spiderWeb(number max, number min, number increment) returns nothing + number i + + if (increment > 0.0) + increment = increment * -1.0 + endif + + for i = max downto min step increment + triangleWheel(i, 12) + endfor +endfunction + + +function triangleWheel(number size, number angle) returns nothing + number i + + for i = 1 to 360 / angle + isosceles(size) + turnRight(angle) + endfor +endfunction + + +function isosceles(number size) returns nothing + number i + + for i = 1 to 3 + goForward(size) + turnRight(120) + endfor +endfunction + + + diff --git a/programs/triangleWheel.toby b/programs/triangleWheel.toby new file mode 100644 index 0000000..1b390ba --- /dev/null +++ b/programs/triangleWheel.toby @@ -0,0 +1,31 @@ +function main() returns nothing + number i + + for i = 1 to 4 + triangleWheel(120, 12) + triangleWheel(80, 12) + triangleWheel(40, 12) + turnRight(90) + endfor +endfunction + +function triangleWheel(number size, number angle) returns nothing + number i + + for i = 1 to 360 / angle + isosceles(size) + turnRight(angle) + endfor +endfunction + + +function isosceles(number size) returns nothing + number i + + for i = 1 to 3 + goForward(size) + turnRight(60) + endfor +endfunction + + diff --git a/programs/webBox.toby b/programs/webBox.toby new file mode 100644 index 0000000..310cc34 --- /dev/null +++ b/programs/webBox.toby @@ -0,0 +1,20 @@ +function box(number size) returns nothing + number i + + for i = 1 to 4 + setPenColor(i) + goForward(size) + turnRight(90) + endfor +endfunction + + +function main() returns nothing + number i + + for i = 1 to 36 + box(100) + turnRight(10) + endfor +endfunction + diff --git a/programs/wierdBox.toby b/programs/wierdBox.toby new file mode 100644 index 0000000..4f55527 --- /dev/null +++ b/programs/wierdBox.toby @@ -0,0 +1,20 @@ +function wierdBox(number size) returns nothing + number i + + for i = 1 to 7 + setPenColor(i) + goForward(size) + turnRight(90) + endfor +endfunction + + +function main() returns nothing + number i + + for i = 1 to 36 + wierdBox(100) + turnRight(10) + endfor +endfunction + diff --git a/programs/wireOrb.toby b/programs/wireOrb.toby new file mode 100644 index 0000000..ef02975 --- /dev/null +++ b/programs/wireOrb.toby @@ -0,0 +1,23 @@ +function main() returns nothing + number i + + hideTurtle() + + for i = 1 to 360 step 2 + circle() + turnRight(2) + endfor +endfunction + + +function circle() returns nothing + number i + + for i = 1 to 360 + goForward(3) + turnRight(1) + endfor +endfunction + + + diff --git a/splash.jpg b/splash.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1e654326d811dc4ef8f892dddc8fda2c3f1e7e79 GIT binary patch literal 43387 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 literal 0 HcmV?d00001 diff --git a/src/exceptions/ExecException.h b/src/exceptions/ExecException.h new file mode 100644 index 0000000..f291a39 --- /dev/null +++ b/src/exceptions/ExecException.h @@ -0,0 +1,80 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _INCLUDE_EXECEXCEPTION_H_ +#define _INCLUDE_EXECEXCEPTION_H_ + +#include "exceptions/FlowException.h" + + +/* + * ExecExceptions are for interpretation errors at runtime, as opposed to + * parsetime errors. + * + * Written by Ryan C. Gordon. (icculus@linuxgames.com) + */ +class ExecException : public FlowException +{ +public: + static ExecException *getInstance(void) + { + return(new ExecException()); // !!! + } // ExecException::getInstance + + static void _throw(const char *err, const char *p, int l) + throw (ExecException *) + { + ExecException *e = getInstance(); + initThrow(e, err, p, l); + throw(e); + } // ExecException::_throw + + static void _throw(const char *err, const char *pName) + throw (ExecException *) + { + ExecException *e = getInstance(); + initThrow(e, err, pName); + throw(e); + } // ExecException::_throw + + static void _throw(const char *err, int lineNum) throw (ExecException *) + { + ExecException *e = getInstance(); + initThrow(e, err, lineNum); + throw(e); + } // ExecException::_throw + + static void _throw(const char *err) throw (ExecException *) + { + ExecException *e = getInstance(); + initThrow(e, err); + throw(e); + } // ExecException::_throw + +private: + // no public construction. + ExecException(void) : FlowException() {} + ExecException(char *_msg) : FlowException(_msg) {} +}; // class ExecException + +#endif // !defined _INCLUDE_EXECEXCEPTION_H_ + +// end of ExecException.h ... + + diff --git a/src/exceptions/FlowException.h b/src/exceptions/FlowException.h new file mode 100644 index 0000000..435cd36 --- /dev/null +++ b/src/exceptions/FlowException.h @@ -0,0 +1,112 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _INCLUDE_FLOWEXCEPTION_H_ +#define _INCLUDE_FLOWEXCEPTION_H_ + +#include "exceptions/TobyException.h" + + +// !!! +#define LINENUM_UNDEFINED -1 + +/* + * FlowExceptions are anything that interrupts program flow: this includes + * parsing/linking errors, runtime errors, and user-initiated aborts, plus + * other forms of normal logic interruptions like return statements. + * + * This is a generic base class. Coders should look to the subclasses. + * + * Written by Ryan C. Gordon. (icculus@linuxgames.com) + */ +class FlowException : public TobyException +{ +public: + // !!! public final static int LINENUM_UNDEFINED = -1; + + // !!! These should be pooled... + virtual ~FlowException(void) + { + if (procName != NULL) + delete procName; + } // Destructor + + + const char *getProcName(void) + { + return(procName->c_str()); + } // FlowException::getProcName + + + int getSourceLine(void) + { + return(exceptionLine); + } // FlowException::getSourceLine + + +protected: + // no public construction. + FlowException(void) : TobyException(), + procName(new TobyString()), exceptionLine(LINENUM_UNDEFINED) + { + } // Constructor + + + FlowException(char *_msg) : TobyException(_msg), + procName(new TobyString()), exceptionLine(LINENUM_UNDEFINED) + { + } // Constructor + + + static void initThrow(FlowException *e, const char *err, + const char *pName, int lineNum) + { + e->msg->assignCStr(err); + e->procName->assignCStr(pName); + e->exceptionLine = lineNum; + } // FlowException::initThrow (overloaded; the works.) + + + static void initThrow(FlowException *e, const char *err, const char *pName) + { + initThrow(e, err, pName, LINENUM_UNDEFINED); + } // FlowException::initThrow (overloaded; no line number.) + + + static void initThrow(FlowException *e, const char *err, int lineNum) + { + initThrow(e, err, NULL, lineNum); + } // FlowException::initThrow (overloaded; just line number.) + + + static void initThrow(FlowException *e, const char *err) + { + initThrow(e, err, NULL, LINENUM_UNDEFINED); + } // FlowException::initThrow (overloaded; no line number or procedure.) + +private: + TobyString *procName; + int exceptionLine; +}; // class FlowException + +#endif // !defined _INCLUDE_FLOWEXCEPTION_H_ + +// end of FlowException.h ... + + diff --git a/src/exceptions/HaltException.h b/src/exceptions/HaltException.h new file mode 100644 index 0000000..492d961 --- /dev/null +++ b/src/exceptions/HaltException.h @@ -0,0 +1,82 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _INCLUDE_HALTEXCEPTION_H_ +#define _INCLUDE_HALTEXCEPTION_H_ + +#include "exceptions/FlowException.h" + + +/* + * HaltExceptions are thrown when the user requests an early end to + * interpretation by hitting ESC or selecting the "STOP" menu item + * or whatnot. This allows for clean termination of the interpreter at + * any time. + * + * Written by Ryan C. Gordon. (icculus@linuxgames.com) + */ +class HaltException : public FlowException +{ +public: + static HaltException *getInstance(void) + { + return(new HaltException()); // !!! + } // HaltException::getInstance + + static void _throw(const char *err, const char *p, int l) + throw (HaltException *) + { + HaltException *e = getInstance(); + initThrow(e, err, p, l); + throw(e); + } // HaltException::_throw + + static void _throw(const char *err, const char *pName) + throw (HaltException *) + { + HaltException *e = getInstance(); + initThrow(e, err, pName); + throw(e); + } // HaltException::_throw + + static void _throw(const char *err, int lineNum) throw (HaltException *) + { + HaltException *e = getInstance(); + initThrow(e, err, lineNum); + throw(e); + } // HaltException::_throw + + static void _throw(const char *err) throw (HaltException *) + { + HaltException *e = getInstance(); + initThrow(e, err); + throw(e); + } // HaltException::_throw + +private: + // no public construction. + HaltException(void) : FlowException() {} + HaltException(char *_msg) : FlowException(_msg) {} +}; // class HaltException + +#endif // !defined _INCLUDE_HALTEXCEPTION_H_ + +// end of HaltException.h ... + + diff --git a/src/exceptions/IOException.h b/src/exceptions/IOException.h new file mode 100644 index 0000000..fa35403 --- /dev/null +++ b/src/exceptions/IOException.h @@ -0,0 +1,42 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _INCLUDE_IOEXCEPTION_H_ +#define _INCLUDE_IOEXCEPTION_H_ + +#include "exceptions/TobyException.h" + + +/* + * IOExceptions are thrown when reading from or writing to something (disk, + * network, etc) fails or encounters an unusual situation.. + * + * Written by Ryan C. Gordon. (icculus@linuxgames.com) + */ +class IOException : public TobyException +{ +public: + IOException(char *_msg) : TobyException(_msg) {} + IOException(void) : TobyException() {} +}; // class IOException + +#endif // !defined _INCLUDE_IOEXCEPTION_H_ + +// end of IOException.h ... + diff --git a/src/exceptions/ParseException.h b/src/exceptions/ParseException.h new file mode 100644 index 0000000..d668af7 --- /dev/null +++ b/src/exceptions/ParseException.h @@ -0,0 +1,82 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _INCLUDE_PARSEEXCEPTION_H_ +#define _INCLUDE_PARSEEXCEPTION_H_ + +#include "exceptions/FlowException.h" + + +/* + * ParseExceptions are thrown when there is a syntax error or some other + * incorrect language construct is encountered at parse time. This + * exception is also used to signal an unresolved symbol during the "link" + * stage. + * + * Written by Ryan C. Gordon. (icculus@linuxgames.com) + */ +class ParseException : public FlowException +{ +public: + static ParseException *getInstance(void) + { + return(new ParseException()); // !!! + } // ParseException::getInstance + + static void _throw(const char *err, const char *p, int l) + throw (ParseException *) + { + ParseException *e = getInstance(); + initThrow(e, err, p, l); + throw(e); + } // ParseException::_throw + + static void _throw(const char *err, const char *pName) + throw (ParseException *) + { + ParseException *e = getInstance(); + initThrow(e, err, pName); + throw(e); + } // ParseException::_throw + + static void _throw(const char *err, int lineNum) throw (ParseException *) + { + ParseException *e = getInstance(); + initThrow(e, err, lineNum); + throw(e); + } // ParseException::_throw + + static void _throw(const char *err) throw (ParseException *) + { + ParseException *e = getInstance(); + initThrow(e, err); + throw(e); + } // ParseException::_throw + +private: + // no public construction. + ParseException(void) : FlowException() {} + ParseException(char *_msg) : FlowException(_msg) {} +}; // class ParseException + +#endif // !defined _INCLUDE_PARSEEXCEPTION_H_ + +// end of ParseException.h ... + + diff --git a/src/exceptions/ReturnException.h b/src/exceptions/ReturnException.h new file mode 100644 index 0000000..70a0e2a --- /dev/null +++ b/src/exceptions/ReturnException.h @@ -0,0 +1,65 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _INCLUDE_RETURNEXCEPTION_H_ +#define _INCLUDE_RETURNEXCEPTION_H_ + +#include "exceptions/FlowException.h" + + +/* + * ReturnExceptions are used to break the logic flow when a RETURN statement + * is hit. FunctionLogicContexts explicitly listen for this and pass control + * back to their parent contexts when such an exception is caught. + * + * Written by Ryan C. Gordon. (icculus@linuxgames.com) + */ +class ReturnException : public FlowException +{ +public: + static ReturnException *getInstance(void) + { + return(new ReturnException()); // !!! + } // ReturnException::getInstance + + public TobyObject *getReturnValue(void) + { + return(returnValue); + } // ReturnException::getReturnValue + + static void _throw(TobyObject *value) throw (ReturnException *) + { + ReturnException *e = getInstance(); + e->returnValue = value; + initThrow(e, ""); + throw(e); + } // ReturnException::_throw + +private: + // no public construction. + ReturnException(void) : FlowException(), returnValue(NULL) {} + ReturnException(char *_msg) : FlowException(_msg), returnValue(NULL) {} + TobyObject *returnValue; +}; // class ReturnException + +#endif // !defined _INCLUDE_RETURNEXCEPTION_H_ + +// end of ReturnException.h ... + + diff --git a/src/exceptions/TobyException.h b/src/exceptions/TobyException.h new file mode 100644 index 0000000..ab44e73 --- /dev/null +++ b/src/exceptions/TobyException.h @@ -0,0 +1,56 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _INCLUDE_TOBYEXCEPTION_H_ +#define _INCLUDE_TOBYEXCEPTION_H_ + +#include "util/TobyObject.h" +#include "util/TobyString.h" + +/* + * ExecExceptions are for interpretation errors at runtime, as opposed to + * parsetime errors. + * + * Written by Ryan C. Gordon. (icculus@linuxgames.com) + */ +class TobyException : public TobyObject +{ +public: + TobyException(char *_msg) : msg(new TobyString(_msg)) {} + TobyException(void) : msg(new TobyString("")) {} + + virtual ~TobyException(void) + { + if (msg != NULL) + delete msg; + } // Destructor + + const char *getMessage(void) + { + return(msg->c_str()); + } // TobyException::getMessage + +protected: + TobyString *msg; +}; // class TobyException + +#endif // !defined TobyException + +// end of TobyException.h ... + diff --git a/src/i18n/example.tobylang b/src/i18n/example.tobylang new file mode 100644 index 0000000..dfee2ff --- /dev/null +++ b/src/i18n/example.tobylang @@ -0,0 +1,235 @@ +# +# This text written by Ryan C. Gordon. +# +# If you are translating to a new language, do this: +# +# 1. Ask yourself, "Do I have a good enough grasp of Java and Toby to +# understand this file, and what its purpose is? Do I have sufficient +# translating skills? Do I have the ethics to NOT put naughty words that +# the Toby maintainers will not understand in here?" If you answered +# "no" to any of these questions, stop now. +# 2. Change the "This text written by" line above to contain your +# name. DO NOT CHANGE THE COPYRIGHT. You will be given credit for your +# work, but by submitting your work, the maintainers of Toby gain +# sole ownership of it. If you don't like that, stop now. +# 3. E-mail your completed work to Ryan at icculus@lokigames.com. He'll +# incorporate it into the next release of Toby. +# 4. Lines beginning with '#' are ignored when this file is parsed. +# Lines with nothing but whitespace are also ignored. +# 5. Only translate the text after the equal sign on each line. That is, +# a line that reads: "last.toby.util.TobyLanguage.MENUNAME_FILE = File" +# You would translate "File", and not "last.toby.util..." +# 6. Whitespace is trimmed from each side of the translated string at runtime. +# 7. Sometimes strings need dynamic content. For example, there might be +# a string that needs to convey, "error in "MyFunction" on line 15.", +# to accomodate this, such strings would have "%0" and "%1", with +# a description of what each represents. You may move the tokens to +# whatever order they need to be in; %1 can come before %0 if your +# language requires this, so long as all of those replacing tokens +# continue to exist somewhere in the translated string. +# 8. Please try out your translation in the program to make sure that the +# program parses the langfile correctly, and that everything looks good. +# 9. Expect to be notified if we have more translating work for you +# in the future. :) +# 10. Questions about context of strings and other concerns can be addressed +# to icculus@lokigames.com. Please understand that I only speak English, +# and even that poorly. :) +# +# Have fun, +# --ryan. +# + +# These are printed if there are problems in loading this langfile. +# Therefore, it's best to parse these at the top of the file. +# What the % values are suppose to represent are pretty obvious. +last.toby.util.TobyLanguage.LANGIOEXCEPT = LANGUAGE: IOException reading language data. +last.toby.util.TobyLanguage.LANGBOGUSLINE = LANGUAGE: Line %0 is bogus in %1. +last.toby.util.TobyLanguage.LANGNOSUCHCLASS = LANGUAGE: No such class [%0] on line %1 in %2. +last.toby.util.TobyLanguage.LANGNOSUCHFIELD = LANGUAGE: No such field [%0] on line %1 in %2. +last.toby.util.TobyLanguage.LANGNOTPUBLIC = LANGUAGE: Field [%0] is not public on line %1 in %2. +last.toby.util.TobyLanguage.LANGNOTSTATIC = LANGUAGE: Field [%0] is not static on line %1 in %2. +last.toby.util.TobyLanguage.LANGNOTSTRING = LANGUAGE: Field [%0] is not a string on line %1 in %2. +last.toby.util.TobyLanguage.LANGISFINAL = LANGUAGE: Field [%0] is final on line %1 in %2. +last.toby.util.TobyLanguage.LANGSETFAILED = LANGUAGE: Setting field [%0] failed with message [%1] on line %2 in %3. + + +# The usage/commandline information. Printed to stderr. +last.toby.util.TobyLanguage.USAGE = USAGE: Toby.class [--langfile=xxx] [sourceFile.toby] + + +# Please change this to be your name, and the language you translated to. +last.toby.util.TobyLanguage.TRANSLATION_BY = English language text by Ryan C. Gordon. + + +# Translate the text, but don't change my name. :) +last.toby.util.TobyLanguage.WRITTENBY = Written by Ryan C. Gordon. +last.toby.util.TobyLanguage.COPYRIGHT = Copyright (C) 1999 Ryan C. Gordon + + +# This is a string in a message box's title bar. +last.toby.util.TobyLanguage.ERROR = Error + + +# This is a title bar string of a Yes/No "overwrite this file?" message box. +last.toby.util.TobyLanguage.FILE_EXISTS = File exists + + +# This is the string in the title bar of a Yes/No message box. +last.toby.util.TobyLanguage.PLEASE_CONFIRM = Please confirm + + +# Question in a yes/no message box. +last.toby.util.TobyLanguage.SAVE_MODIFIED_PROG = Save modified program? + + +# This is shown in the main window's title bar before a program is saved. +# Once saved, this is replaced with the filename where the program is stored. +last.toby.util.TobyLanguage.NEW_PROGRAM = new program + + +# %0 is replaced with a filename at runtime in these strings... +last.toby.util.TobyLanguage.FILE_NOT_FOUND = File "%0" not found. +last.toby.util.TobyLanguage.CANNOT_LOAD_FILE = Cannot load file "%0". +last.toby.util.TobyLanguage.OVERWRITE_FILENAME = Overwrite "%0"? +last.toby.util.TobyLanguage.CANNOT_WRITE_TO = Cannot write to "%0". + + +# These three are printed to stderr on three separate lines if there's +# a class loading problem. Try not to use more than 80 characters per string. +last.toby.util.TobyLanguage.MISSING_CLASS1 = Cannot find a necessary .class file. +last.toby.util.TobyLanguage.MISSING_CLASS2 = Perhaps you need to set your CLASSPATH? +last.toby.util.TobyLanguage.MISSING_CLASS3 = Also, make sure you have JDK 1.2 or later! + + +# These are three separate strings that make up one sentence: +# one string per line; try not to use more than 80 characters per string, +# as this is printed to stderr. +last.toby.util.TobyLanguage.NO_GUI1 = Your Java Virtual Machine has thrown an error...chances are, you don't have +last.toby.util.TobyLanguage.NO_GUI2 = the GUI support you need. Please start your Window system before running this +last.toby.util.TobyLanguage.NO_GUI3 = program. + + +# This is printed to stderr after the NO_GUI strings, and is followed by +# whatever information is attached to the thrown error. +last.toby.util.TobyLanguage.HERES_THE_ERR = For record, here's the error: + + +# Other warnings and errors... +last.toby.util.TobyLanguage.MSG_BAD_JAVA = Your Java Virtual Machine is too old; goto http://java.sun.com/ ... +last.toby.util.TobyLanguage.SETICON_BROKEN = WARNING: setIconImage() is broken on this Java Virtual Machine! +last.toby.util.TobyLanguage.TOOMANYFILES = More than one file specified on commandline! Just using the first one. + + +# This is printed to stderr when a warning can be worked around (currently, +# the only warning is the setIconImage(), above). +last.toby.util.TobyLanguage.WORK_AROUND_IT = (We will work around it, though.) + + +# Menu items. +last.toby.util.TobyLanguage.MENUNAME_FILE = File +last.toby.util.TobyLanguage.MENUITEM_NEW = New +last.toby.util.TobyLanguage.MENUITEM_OPEN = Open... +last.toby.util.TobyLanguage.MENUITEM_SAVE = Save +last.toby.util.TobyLanguage.MENUITEM_SAVEAS = Save as... +last.toby.util.TobyLanguage.MENUITEM_PRINT = Print... +last.toby.util.TobyLanguage.MENUITEM_QUIT = Quit + +last.toby.util.TobyLanguage.MENUNAME_HELP = Help +last.toby.util.TobyLanguage.MENUITEM_HELP = Help... +last.toby.util.TobyLanguage.MENUITEM_ABOUT = About... + +last.toby.util.TobyLanguage.MENUNAME_RUN = Run +last.toby.util.TobyLanguage.MENUITEM_STARTCODE = Start program +last.toby.util.TobyLanguage.MENUITEM_STOPCODE = Stop program +last.toby.util.TobyLanguage.MENUITEM_CLEAR = Cleanup TurtleSpace + +last.toby.util.TobyLanguage.MENUNAME_DEBUG = Debug +last.toby.util.TobyLanguage.MENUITEM_TRACE = Trace +last.toby.util.TobyLanguage.MENUITEM_STEP = Step +last.toby.util.TobyLanguage.MENUITEM_WATCHVARS = Watch variables + + +# This is a file description for the file open dialog, and shows up in +# the dropdown for "show files of type" ... +last.toby.util.TobyLanguage.TOBY_FILE_DESCRIPTION = TOBY source code + + +# This is the current position of the text cursor in the editing window. +# %0 and %1 are replaced with numbers at runtime. +last.toby.util.TobyLanguage.CARET_POSITION = line %0, column %1 + + +# %0 is another string (probably one of the ones below), that tells what +# sort of error occurred, such as "Syntax error." +# %1 is a numeric. %2 is the name of a function in the user's Toby program. +last.toby.util.TobyLanguage.ERR_IN_FUNC = %0 on line %1 in function %2 + + +# Same as above, but the error didn't occur inside a function. +last.toby.util.TobyLanguage.ERR_OUT_FUNC = %0 on line %1 + + + +# Error messages. +# +# Please note that the capitalized words are keywords +# in the Toby language, and should not be translated. +# (unless you are also translating the keywords in +# in last.toby.parsers.toby.TobyParser, too, but those +# changes will not be accepted in an official Toby +# distribution.) +last.toby.util.TobyLanguage.INTERNAL_ERROR = Internal error +last.toby.util.TobyLanguage.EXPECTED_TOKEN = Expected token +last.toby.util.TobyLanguage.SYNTAX_ERROR = Syntax error +last.toby.util.TobyLanguage.BAD_ASSIGNMENT = Assignment not allowed +last.toby.util.TobyLanguage.DOUBLE_DEF = Duplicate definition +last.toby.util.TobyLanguage.ORPHAN_CODE = Code outside function +last.toby.util.TobyLanguage.BAD_TYPE = Bad variable type +last.toby.util.TobyLanguage.NOT_VAR = Expected variable +last.toby.util.TobyLanguage.NO_MAINLINE = Expected mainline +last.toby.util.TobyLanguage.NO_RPAREN = Expected ")" +last.toby.util.TobyLanguage.NO_LPAREN = Expected "(" +last.toby.util.TobyLanguage.NO_ASSIGN = Expected "=" +last.toby.util.TobyLanguage.NOT_A_FUNC = Undefined function +last.toby.util.TobyLanguage.BADNUM_ARGS = Wrong arguments +last.toby.util.TobyLanguage.BAD_IDENT = Invalid identifier +last.toby.util.TobyLanguage.NO_ENDFOR = FOR without ENDFOR +last.toby.util.TobyLanguage.NO_FOR = ENDFOR without FOR +last.toby.util.TobyLanguage.NO_ENDWHILE = WHILE without ENDWHILE +last.toby.util.TobyLanguage.NO_WHILE = ENDWHILE without WHILE +last.toby.util.TobyLanguage.ORPHAN_ELIF = ELSEIF without IF +last.toby.util.TobyLanguage.ORPHAN_ELSE = ELSE without IF +last.toby.util.TobyLanguage.ORPHAN_ENDIF = ENDIF without IF +last.toby.util.TobyLanguage.TYPE_MMATCH = Type mismatch +last.toby.util.TobyLanguage.BAD_ARGUMENT = Invalid argument +last.toby.util.TobyLanguage.MAIN_RETVAL = MAIN returns a value +last.toby.util.TobyLanguage.BAD_GLOBAL = Expected variable or FUNCTION +last.toby.util.TobyLanguage.EXPECTED_END = Expected ENDFUNCTION +last.toby.util.TobyLanguage.NO_RETTYPE = Expected RETURNS +last.toby.util.TobyLanguage.ELIF_AFTER_ELSE = ELSEIF after ELSE +last.toby.util.TobyLanguage.ELSE_AFTER_ELSE = Multiple ELSE statements +last.toby.util.TobyLanguage.NO_VAR_DECL = Can't declare variables here +last.toby.util.TobyLanguage.FUNC_IN_FUNC = FUNCTION within function +last.toby.util.TobyLanguage.DIV_BY_ZERO = Division by zero +last.toby.util.TobyLanguage.NOCURTURTLE = No current turtle +last.toby.util.TobyLanguage.TURTLE_FENCED = Turtle past fence +last.toby.util.TobyLanguage.OUT_OF_RANGE = Out of range +last.toby.util.TobyLanguage.OVERFLOW = Overflow +last.toby.util.TobyLanguage.NOT_AN_ARRAY = Expected array +last.toby.util.TobyLanguage.NO_RARRAY = Expected "]" +last.toby.util.TobyLanguage.NO_LARRAY = Expected "[" +last.toby.util.TobyLanguage.NOT_WHOLE_NUM = Expected whole number + + +# This is an internal error alert message. +last.toby.util.TobyLanguage.SHOULDNOTBE = This should not happen. Email icculus@lokigames.com! (English only!) + + +# Other stuff. +last.toby.util.TobyLanguage.NOT_YET_IMPLEMENTED = Feature not yet implemented. + + +# end of example.tobylang ... + + + diff --git a/src/i18n/french.tobylang b/src/i18n/french.tobylang new file mode 100644 index 0000000..9a12bd8 --- /dev/null +++ b/src/i18n/french.tobylang @@ -0,0 +1,239 @@ +# +# This text written by Ryan C. Gordon. +# +# If you are translating to a new language, do this: +# +# 1. Ask yourself, "Do I have a good enough grasp of Java and Toby to +# understand this file, and what its purpose is? Do I have sufficient +# translating skills? Do I have the ethics to NOT put naughty words that +# the Toby maintainers will not understand in here?" If you answered +# "no" to any of these questions, stop now. +# 2. Change the "This text written by" line above to contain your +# name. DO NOT CHANGE THE COPYRIGHT. You will be given credit for your +# work, but by submitting your work, the maintainers of Toby gain +# sole ownership of it. If you don't like that, stop now. +# 3. E-mail your completed work to Ryan at icculus@lokigames.com. He'll +# incorporate it into the next release of Toby. +# 4. Lines beginning with '#' are ignored when this file is parsed. +# Lines with nothing but whitespace are also ignored. +# 5. Only translate the text after the equal sign on each line. That is, +# a line that reads: "last.toby.util.TobyLanguage.MENUNAME_FILE = File" +# You would translate "File", and not "last.toby.util..." +# 6. Whitespace is trimmed from each side of the translated string at runtime. +# 7. Sometimes strings need dynamic content. For example, there might be +# a string that needs to convey, "error in "MyFunction" on line 15.", +# to accomodate this, such strings would have "%0" and "%1", with +# a description of what each represents. You may move the tokens to +# whatever order they need to be in; %1 can come before %0 if your +# language requires this, so long as all of those replacing tokens +# continue to exist somewhere in the translated string. +# 8. Please try out your translation in the program to make sure that the +# program parses the langfile correctly, and that everything looks good. +# 9. Expect to be notified if we have more translating work for you +# in the future. :) +# 10. Questions about context of strings and other concerns can be addressed +# to icculus@lokigames.com. Please understand that I only speak English, +# and even that poorly. :) +# +# Have fun, +# --ryan. +# + +# These are printed if there are problems in loading this langfile. +# Therefore, it's best to parse these at the top of the file. +# What the % values are suppose to represent are pretty obvious. +last.toby.util.TobyLanguage.LANGIOEXCEPT = LANGUAGE: IOException pendant lecture des données linguistiques. +last.toby.util.TobyLanguage.LANGBOGUSLINE = LANGUAGE: Ligne %0 est fausse à partir de colonne %1. +last.toby.util.TobyLanguage.LANGNOSUCHCLASS = LANGUAGE: Classe: [%0]inexistante à la ligne %1 colonne %2. +last.toby.util.TobyLanguage.LANGNOSUCHFIELD = LANGUAGE: Pas de champ [%0] à la ligne %1 colnone %2. +last.toby.util.TobyLanguage.LANGNOTPUBLIC = LANGUAGE: Champ [%0] n'est pas publique à la ligne %1 colonne %2. +last.toby.util.TobyLanguage.LANGNOTSTATIC = LANGUAGE: Champ [%0] n'est pas statique à la ligne %1 colonne %2. +last.toby.util.TobyLanguage.LANGNOTSTRING = LANGUAGE: Champ [%0] n'est pas une chaine à la ligne %1 colonne %2. +last.toby.util.TobyLanguage.LANGISFINAL = LANGUAGE: Champ [%0] est final à la ligne %1 colonne %2. +last.toby.util.TobyLanguage.LANGSETFAILED = LANGUAGE: Erreur assignation champ [%0] avec message [%1] à la ligne %2 colonne %3. + + +# The usage/commandline information. Printed to stderr. +last.toby.util.TobyLanguage.USAGE = USAGE: Toby.class [--langfile=xxx] [sourceFile.toby] + + +# Please change this to be your name, and the language you translated to. +last.toby.util.TobyLanguage.TRANSLATION_BY = English language text by Ryan C. Gordon. + + +# Translate the text, but don't change my name. :) +last.toby.util.TobyLanguage.WRITTENBY = Written by Ryan C. Gordon. +last.toby.util.TobyLanguage.COPYRIGHT = Copyright (C) 1999 Ryan C. Gordon + + +# This is a string in a message box's title bar. +last.toby.util.TobyLanguage.ERROR = Erreur + + +# This is a title bar string of a Yes/No "overwrite this file?" message box. +last.toby.util.TobyLanguage.FILE_EXISTS = Fichier existe + + +# This is the string in the title bar of a Yes/No message box. +last.toby.util.TobyLanguage.PLEASE_CONFIRM = Confirmez SVP + + +# Question in a yes/no message box. +last.toby.util.TobyLanguage.SAVE_MODIFIED_PROG = Sauver programme modifié? + + +# This is shown in the main window's title bar before a program is saved. +# Once saved, this is replaced with the filename where the program is stored. +last.toby.util.TobyLanguage.NEW_PROGRAM = nouveau programme + + +# %0 is replaced with a filename at runtime in these strings... +last.toby.util.TobyLanguage.FILE_NOT_FOUND = Fichier "%0" non trouvé. +last.toby.util.TobyLanguage.CANNOT_LOAD_FILE = Ne peut charger fichier "%0". +last.toby.util.TobyLanguage.OVERWRITE_FILENAME = Ecraser "%0"? +last.toby.util.TobyLanguage.CANNOT_WRITE_TO = Ne peux écrire vers "%0". + + +# These three are printed to stderr on three separate lines if there's +# a class loading problem. Try not to use more than 80 characters per string. +last.toby.util.TobyLanguage.MISSING_CLASS1 = Ne peut pas trouver un fichier .class nécessaire. +last.toby.util.TobyLanguage.MISSING_CLASS2 = Vérifier la valeur de CLASSPATH? +last.toby.util.TobyLanguage.MISSING_CLASS3 = Vérifier la version JDK (>=JDK1.2) ! + + +# These are three separate strings that make up one sentence: +# one string per line; try not to use more than 80 characters per string, +# as this is printed to stderr. +last.toby.util.TobyLanguage.NO_GUI1 = Votre machine virtuelle Java à lancé une exception...peut être n'avez vous pas +last.toby.util.TobyLanguage.NO_GUI2 = le support graphique nécessaire. Démarrer votre système de fenêtre avant de démarrer +last.toby.util.TobyLanguage.NO_GUI3 = ce programme. + + +# This is printed to stderr after the NO_GUI strings, and is followed by +# whatever information is attached to the thrown error. +last.toby.util.TobyLanguage.HERES_THE_ERR = Pour mémoire, voici l'erreur: + + +# Other warnings and errors... +last.toby.util.TobyLanguage.MSG_BAD_JAVA = Votre machine virtuelle Java est trop ancienne; aller à http://java.sun.com/ ... +last.toby.util.TobyLanguage.SETICON_BROKEN = ATTENTION: setIconImage() ne fonctionne pas sur cette machine virtuelle Java! +last.toby.util.TobyLanguage.TOOMANYFILES = Plusieurs fichiers spécifiés sur la ligne de commande! Utilise seulement le premier. + + +# This is printed to stderr when a warning can be worked around (currently, +# the only warning is the setIconImage(), above). +last.toby.util.TobyLanguage.WORK_AROUND_IT = (Nous continuons quand même.) + + +# Menu items. +last.toby.util.TobyLanguage.MENUNAME_FILE = Fichier +last.toby.util.TobyLanguage.MENUITEM_NEW = Nouveau +last.toby.util.TobyLanguage.MENUITEM_OPEN = Ouvrir... +last.toby.util.TobyLanguage.MENUITEM_SAVE = Sauver +last.toby.util.TobyLanguage.MENUITEM_SAVEAS = Sauver sous... +last.toby.util.TobyLanguage.MENUITEM_PRINT = Imprimer... +last.toby.util.TobyLanguage.MENUITEM_QUIT = Quitter + +last.toby.util.TobyLanguage.MENUNAME_HELP = Aide +last.toby.util.TobyLanguage.MENUITEM_HELP = Aide... +last.toby.util.TobyLanguage.MENUITEM_ABOUT = A propos... + +last.toby.util.TobyLanguage.MENUNAME_RUN = Action +last.toby.util.TobyLanguage.MENUITEM_STARTCODE = Démarrer programme +last.toby.util.TobyLanguage.MENUITEM_STOPCODE = Arrêter programme +last.toby.util.TobyLanguage.MENUITEM_CLEAR = Effacer zone tortue + +last.toby.util.TobyLanguage.MENUNAME_DEBUG = Mis au point +last.toby.util.TobyLanguage.MENUITEM_TRACE = Trace +last.toby.util.TobyLanguage.MENUITEM_STEP = Pas à pas +last.toby.util.TobyLanguage.MENUITEM_WATCHVARS = Voir variables + + +# This is a file description for the file open dialog, and shows up in +# the dropdown for "show files of type" ... +last.toby.util.TobyLanguage.TOBY_FILE_DESCRIPTION = TOBY code source + + +# This is the current position of the text cursor in the editing window. +# %0 and %1 are replaced with numbers at runtime. +last.toby.util.TobyLanguage.CARET_POSITION = ligne %0, colonne %1 + + +# %0 is another string (probably one of the ones below), that tells what +# sort of error occurred, such as "Syntax error." +# %1 is a numeric. %2 is the name of a function in the user's Toby program. +last.toby.util.TobyLanguage.ERR_IN_FUNC = %0 à la ligne %1 dans la fonction %2 + + +# Same as above, but the error didn't occur inside a function. +last.toby.util.TobyLanguage.ERR_OUT_FUNC = %0 à la ligne %1 + + + +# Error messages. +# +# Please note that the capitalized words are keywords +# in the Toby language, and should not be translated. +# (unless you are also translating the keywords in +# in last.toby.parsers.toby.TobyParser, too, but those +# changes will not be accepted in an official Toby +# distribution.) +last.toby.util.TobyLanguage.INTERNAL_ERROR = Erreur interne +last.toby.util.TobyLanguage.EXPECTED_TOKEN = Expected token +last.toby.util.TobyLanguage.SYNTAX_ERROR = Erreur de syntaxe +last.toby.util.TobyLanguage.BAD_ASSIGNMENT = Assignation non autorisée +last.toby.util.TobyLanguage.DOUBLE_DEF = Définition dupliquée +last.toby.util.TobyLanguage.ORPHAN_CODE = Code en dehors de fonction +last.toby.util.TobyLanguage.BAD_TYPE = Type de variable incorrect +last.toby.util.TobyLanguage.NOT_VAR = Variable attendue +last.toby.util.TobyLanguage.NO_MAINLINE = Point d'entrée du programme exigé +last.toby.util.TobyLanguage.NO_RPAREN = ")" attendu +last.toby.util.TobyLanguage.NO_LPAREN = "(" attendu +last.toby.util.TobyLanguage.NO_ASSIGN = "=" attendu +last.toby.util.TobyLanguage.NOT_A_FUNC = Fonction indéfinie +last.toby.util.TobyLanguage.BADNUM_ARGS = Arguments invalides +last.toby.util.TobyLanguage.BAD_IDENT = Identifiant invalide +last.toby.util.TobyLanguage.NO_ENDFOR = POUR sans FINPOUR +last.toby.util.TobyLanguage.NO_FOR = FINPOUR sans POUR +last.toby.util.TobyLanguage.NO_ENDWHILE = TANTQUE sans FINTANTQUE +last.toby.util.TobyLanguage.NO_WHILE = FINTANTQUE sans TANTQUE +last.toby.util.TobyLanguage.ORPHAN_ELIF = SINONSI sans SI +last.toby.util.TobyLanguage.ORPHAN_ELSE = SINON sans SI +last.toby.util.TobyLanguage.ORPHAN_ENDIF = FINSI sans SI +last.toby.util.TobyLanguage.TYPE_MMATCH = Confusion de type +last.toby.util.TobyLanguage.BAD_ARGUMENT = Argument invalide +last.toby.util.TobyLanguage.MAIN_RETVAL = PRINCIPAL retourne une valeur +last.toby.util.TobyLanguage.BAD_GLOBAL = Variable ou FONCTION attendue +last.toby.util.TobyLanguage.EXPECTED_END = FINFONCTION attendu +last.toby.util.TobyLanguage.NO_RETTYPE = RETOUR attendu +last.toby.util.TobyLanguage.ELIF_AFTER_ELSE = SINONSI après SINON +last.toby.util.TobyLanguage.ELSE_AFTER_ELSE = Multiples SINON +last.toby.util.TobyLanguage.NO_VAR_DECL = Ne peut pas déclarer de variable ici +last.toby.util.TobyLanguage.FUNC_IN_FUNC = FONCTION dans fonction +last.toby.util.TobyLanguage.DIV_BY_ZERO = Division par zero +last.toby.util.TobyLanguage.NOCURTURTLE = Pas de tortue courante +last.toby.util.TobyLanguage.TURTLE_FENCED = Tortue a dépassé la barrière + +# !!! FIXME: Localize this text! +last.toby.util.TobyLanguage.OUT_OF_RANGE = Out of range +last.toby.util.TobyLanguage.OVERFLOW = Overflow +last.toby.util.TobyLanguage.NOT_AN_ARRAY = Expected array +last.toby.util.TobyLanguage.NO_RARRAY = Expected "]" +last.toby.util.TobyLanguage.NO_LARRAY = Expected "[" +last.toby.util.TobyLanguage.NOT_WHOLE_NUM = Expected whole number + + + +# This is an internal error alert message. +last.toby.util.TobyLanguage.SHOULDNOTBE = Ceci ne devrait pas arriver. Envoyer un Email à icculus@lokigames.com! (en Anglais seulement!) + + +# Other stuff. +last.toby.util.TobyLanguage.NOT_YET_IMPLEMENTED = Fonctionalité non implémentée. + + +# end of example.tobylang ... + + + + diff --git a/src/i18n/tobykeywords.tobylang b/src/i18n/tobykeywords.tobylang new file mode 100644 index 0000000..4004094 --- /dev/null +++ b/src/i18n/tobykeywords.tobylang @@ -0,0 +1,98 @@ +# +# Don't change this unless you know what you are doing. +# Please refer to example.tobylang for basic instructions. +# +# EVERYTHING IN HERE MUST BE LOWERCASE, OR YOU WILL GET STRANGE RUNTIME +# ERRORS. The Toby language is case insensitive to the end user, but for +# efficiency, some of the data sorting internally expects these strings to +# be lowercase. +# +# --ryan c. gordon (icculus@lokigames.com) +# + +last.toby.parsers.toby.TobyParser.OPER_LPAREN = ( +last.toby.parsers.toby.TobyParser.OPER_RPAREN = ) +last.toby.parsers.toby.TobyParser.OPER_SEPARATOR = , +last.toby.parsers.toby.TobyParser.OPER_ASSIGNMENT = = +last.toby.parsers.toby.TobyParser.OPER_EQUALS = == +last.toby.parsers.toby.TobyParser.OPER_MULTIPLY = * +last.toby.parsers.toby.TobyParser.OPER_DIVIDE = / +last.toby.parsers.toby.TobyParser.OPER_MODULO = % +last.toby.parsers.toby.TobyParser.OPER_ADD = + +last.toby.parsers.toby.TobyParser.OPER_SUBTRACT = - +last.toby.parsers.toby.TobyParser.OPER_GREATER = > +last.toby.parsers.toby.TobyParser.OPER_LESS = < +last.toby.parsers.toby.TobyParser.OPER_GREATEREQL = >= +last.toby.parsers.toby.TobyParser.OPER_LESSEQL = <= +last.toby.parsers.toby.TobyParser.OPER_LARRAY = [ +last.toby.parsers.toby.TobyParser.OPER_RARRAY = ] +last.toby.parsers.toby.TobyParser.KEYWORD_NUMBER = number +last.toby.parsers.toby.TobyParser.KEYWORD_BOOLEAN = boolean +last.toby.parsers.toby.TobyParser.KEYWORD_NOTHING = nothing +last.toby.parsers.toby.TobyParser.KEYWORD_ARRAY = array +last.toby.parsers.toby.TobyParser.KEYWORD_STRING = string +last.toby.parsers.toby.TobyParser.KEYWORD_IF = if +last.toby.parsers.toby.TobyParser.KEYWORD_ELSEIF = elseif +last.toby.parsers.toby.TobyParser.KEYWORD_ELSE = else +last.toby.parsers.toby.TobyParser.KEYWORD_ENDIF = endif +last.toby.parsers.toby.TobyParser.KEYWORD_BEGINFOR = for +last.toby.parsers.toby.TobyParser.KEYWORD_TO = to +last.toby.parsers.toby.TobyParser.KEYWORD_OF = of +last.toby.parsers.toby.TobyParser.KEYWORD_DOWNTO = downto +last.toby.parsers.toby.TobyParser.KEYWORD_STEP = step +last.toby.parsers.toby.TobyParser.KEYWORD_ENDFOR = endfor +last.toby.parsers.toby.TobyParser.KEYWORD_RETURN = return +last.toby.parsers.toby.TobyParser.KEYWORD_BEGINFUNC = function +last.toby.parsers.toby.TobyParser.KEYWORD_ENDFUNC = endfunction +last.toby.parsers.toby.TobyParser.KEYWORD_TRUE = true +last.toby.parsers.toby.TobyParser.KEYWORD_FALSE = false +last.toby.parsers.toby.TobyParser.KEYWORD_RETURNS = returns +last.toby.parsers.toby.TobyParser.KEYWORD_BEGINWHILE = while +last.toby.parsers.toby.TobyParser.KEYWORD_ENDWHILE = endwhile +last.toby.parsers.toby.TobyParser.KEYWORD_MAINLINE = main +last.toby.parsers.toby.TobyParser.PROCNAME_ADDTURTLE = addturtle +last.toby.parsers.toby.TobyParser.PROCNAME_USETURTLE = useturtle +last.toby.parsers.toby.TobyParser.PROCNAME_REMTURTLE = removeturtle +last.toby.parsers.toby.TobyParser.PROCNAME_REMALLTURTLES = removeallturtles +last.toby.parsers.toby.TobyParser.PROCNAME_HIDETURTLE = hideturtle +last.toby.parsers.toby.TobyParser.PROCNAME_SHOWTURTLE = showturtle +last.toby.parsers.toby.TobyParser.PROCNAME_HIDEALLTURTLES = hideallturtles +last.toby.parsers.toby.TobyParser.PROCNAME_SHOWALLTURTLES = showallturtles +last.toby.parsers.toby.TobyParser.PROCNAME_FORWARD = goforward +last.toby.parsers.toby.TobyParser.PROCNAME_BACKWARD = gobackward +last.toby.parsers.toby.TobyParser.PROCNAME_RIGHT = turnright +last.toby.parsers.toby.TobyParser.PROCNAME_LEFT = turnleft +last.toby.parsers.toby.TobyParser.PROCNAME_SETPEN = setpencolor +last.toby.parsers.toby.TobyParser.PROCNAME_SETPENRGB = setpencolorrgb +last.toby.parsers.toby.TobyParser.PROCNAME_PENUP = setpenup +last.toby.parsers.toby.TobyParser.PROCNAME_PENDOWN = setpendown +last.toby.parsers.toby.TobyParser.PROCNAME_ISPENUP = ispenup +last.toby.parsers.toby.TobyParser.PROCNAME_ISPENDOWN = ispendown +last.toby.parsers.toby.TobyParser.PROCNAME_RANDOM = random +last.toby.parsers.toby.TobyParser.PROCNAME_ROUND = round +last.toby.parsers.toby.TobyParser.PROCNAME_TSPACEHIGH = getturtlespaceheight +last.toby.parsers.toby.TobyParser.PROCNAME_TSPACEWIDE = getturtlespacewidth +last.toby.parsers.toby.TobyParser.PROCNAME_STOP = stopprogram +last.toby.parsers.toby.TobyParser.PROCNAME_SETANGLE = setangle +last.toby.parsers.toby.TobyParser.PROCNAME_GETANGLE = getangle +last.toby.parsers.toby.TobyParser.PROCNAME_PAUSE = pause +last.toby.parsers.toby.TobyParser.PROCNAME_GETTURTLEX = getturtlex +last.toby.parsers.toby.TobyParser.PROCNAME_GETTURTLEY = getturtley +last.toby.parsers.toby.TobyParser.PROCNAME_SETTURTXY = setturtlexy +last.toby.parsers.toby.TobyParser.PROCNAME_HOMETURTLE = hometurtle +last.toby.parsers.toby.TobyParser.PROCNAME_HOMEALLTURTLES = homeallturtles +last.toby.parsers.toby.TobyParser.PROCNAME_CLEANUP = cleanupturtlespace +last.toby.parsers.toby.TobyParser.PROCNAME_ENABLEFENCE = enablefence +last.toby.parsers.toby.TobyParser.PROCNAME_DISABLEFENCE = disablefence +last.toby.parsers.toby.TobyParser.PROCNAME_SETFENCE = setfence +last.toby.parsers.toby.TobyParser.PROCNAME_SUBSTRING = substring +last.toby.parsers.toby.TobyParser.PROCNAME_LEFTSTRING = leftstring +last.toby.parsers.toby.TobyParser.PROCNAME_RIGHTSTRING = rightstring +last.toby.parsers.toby.TobyParser.PROCNAME_UCASESTRING = uppercasestring +last.toby.parsers.toby.TobyParser.PROCNAME_LCASESTRING = lowercasestring +last.toby.parsers.toby.TobyParser.PROCNAME_DRAWSTRING = drawstring +last.toby.parsers.toby.TobyParser.PROCNAME_STRINGLEN = stringlength +last.toby.parsers.toby.TobyParser.PROCNAME_JOINSTRINGS = joinstrings + +# end of tobykeywords.tobylang ... + diff --git a/src/platform/renderers/fbrenderer/FrameBufferTurtleSpaceRenderer.cpp b/src/platform/renderers/fbrenderer/FrameBufferTurtleSpaceRenderer.cpp new file mode 100644 index 0000000..daad6b2 --- /dev/null +++ b/src/platform/renderers/fbrenderer/FrameBufferTurtleSpaceRenderer.cpp @@ -0,0 +1,408 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "platform/renderers/fbrenderer/FrameBufferTurtleSpaceRenderer.h" + +#include "SDL.h" // !!! + +FrameBufferTurtleSpaceRenderer::FrameBufferTurtleSpaceRenderer(void) + : TurtleSpaceRenderer(), defaultSurface(NULL) +{ +} // Constructor + + +FrameBufferTurtleSpaceRenderer::~FrameBufferTurtleSpaceRenderer(void) +{ + deleteSurface(); +} // Destructor + + +bool FrameBufferTurtleSpaceRenderer::resize(int _w, int _h) +{ + if (screenResize(_w, _h) == false) + return(false); + + toby_uint32 *oldbuf = NULL; + toby_uint32 *p = getSurface(); + + // need an extra copy so we don't createSurface() twice in a row. + if (p != NULL) + { + oldbuf = new toby_uint32[w * h]; + memcpy(oldbuf, p, (w * h) * sizeof (toby_uint32)); + deleteSurface(); + } // if + + createSurface(_w, _h); + p = getSurface(); + if (p == NULL) + { + if (oldbuf == NULL) + delete[] oldbuf; + return(false); + } // if + + blankPixels(p, _w, _h); + if (oldbuf != NULL) + { + // !!! copy old framebuffer to new, centered. + delete[] oldbuf; + } // if + + w = _w; + h = _h; + return(true); +} // FrameBufferTurtleSpaceRenderer::resize + + +void FrameBufferTurtleSpaceRenderer::notifyGrabbed(void) +{ +} // FrameBufferTurtleSpaceRenderer::notifyGrabbed(void) + + +void FrameBufferTurtleSpaceRenderer::notifyUngrabbed(void) +{ +} // FrameBufferTurtleSpaceRenderer::notifyUngrabbed + + +void FrameBufferTurtleSpaceRenderer::blankPixels(toby_uint32 *p, int _w, int _h) +{ + // !!! This could optimize, I bet. + int max = _w * _h; + for (int i = 0; i < max; i++) + p[i] = 0xFF000000; // Full alpha, no red or green or blue. +} // FrameBufferTurtleSpaceRenderer::blankPixels + + +double FrameBufferTurtleSpaceRenderer::getTurtleSpaceWidth(void) +{ + return(w); +} // FrameBufferTurtleSpaceRenderer::getTurtleSpaceWidth + + +double FrameBufferTurtleSpaceRenderer::getTurtleSpaceHeight(void) +{ + return(h); +} // FrameBufferTurtleSpaceRenderer::getTurtleSpaceHeight + + +double FrameBufferTurtleSpaceRenderer::getDesiredTurtleWidth(void) +{ + return(w * 0.02); +} // FrameBufferTurtleSpaceRenderer::getDesiredTurtleWidth + + +double FrameBufferTurtleSpaceRenderer::getDesiredTurtleHeight(void) +{ + return(getDesiredTurtleWidth()); +} // FrameBufferTurtleSpaceRenderer::getDesiredTurtleHeight + + +void FrameBufferTurtleSpaceRenderer::renderString(double x, double y, + double angle, + float r, float b, + float g, float a, + const char *str) +{ +} // FrameBufferTurtleSpaceRenderer::renderString + + +#define LINEBLITCHUNKS 10 + +void FrameBufferTurtleSpaceRenderer::renderLine(double _x1, double _y1, + double _x2, double _y2, + float r, float b, + float g, float a) +{ + // This is a standard Bresenham line-drawing algorithm, but the specific + // implementation was borrowed, optimized, and mangled from + // SGE's DoLine code: + // http://www.etek.chalmers.se/~e8cal1/sge/ + + toby_uint32 pval = constructPixelValue(r, g, b, a); + int x1 = TobyGeometry::roundDoubleToInt(_x1); + int y1 = TobyGeometry::roundDoubleToInt(_y1); + int x2 = TobyGeometry::roundDoubleToInt(_x2); + int y2 = TobyGeometry::roundDoubleToInt(_y2); + + FrameBufferRect rects[LINEBLITCHUNKS]; + toby_uint32 *p = getSurface(); + + _D(("LFB: rendering line...(%d, %d)-(%d, %d), (%f, %f, %f, %f)...\n", + x1, y1, x2, y2, r, g, b, a)); + + int dx, dy, sdx, sdy, x, y, px, py, incr; + + dx = x2 - x1; + dy = y2 - y1; + + sdx = (dx < 0) ? -1 : 1; + sdy = (dy < 0) ? -1 : 1; + + dx = sdx * dx + 1; + dy = sdy * dy + 1; + + x = y = 0; + + px = x1; + py = y1; + + if ((dx == 1) && (dy == 1)) + { + _D(("LFB: Single pixel line fastpath.\n")); + *(((toby_uint32 *) p) + ((py * w) + px)) = pval; + putToScreen(p, px, py, 1, 1); + return; + } // if + + else if (dx == 1) + { + _D(("LFB: Vertical line fastpath.\n")); + toby_uint32 *linep = ((toby_uint32 *) p) + ((py * w) + px); + incr = w * sdy; + for (y = 0; y < dy; y++) + { + *linep = pval; + linep += incr; + } // for + putToScreen(p, (x1 < x2) ? x1 : x2, (y1 < y2) ? y1 : y2, 1, dy); + return; + } // else if + + else if (dy == 1) + { + _D(("LFB: Horizontal line fastpath.\n")); + toby_uint32 *linep = ((toby_uint32 *) p) + ((py * w) + px); + incr = sdx; + for (x = 0; x < dx; x++) + { + *linep = pval; + linep += incr; + } // for + putToScreen(p, (x1 < x2) ? x1 : x2, (y1 < y2) ? y1 : y2, dx, 1); + return; + } // else if + + else if (dx >= dy) + { + _D(("LFB: Line with major axis of X.\n")); + + int lastX = px; + int thisY = py; + int rectidx = 0; + + for (x = 0; x < dx; x++) + { + *( ((toby_uint32 *) p) + ((py * w) + px) ) = pval; + + y += dy; + if (y >= dx) // run length completed. + { + if (rectidx != -1) + { + rects[rectidx].x = (lastX < px) ? lastX : px; + rects[rectidx].y = thisY; + rects[rectidx].w = (px - lastX) * sdx; + rects[rectidx].h = 1; + + rectidx++; + if (rectidx >= LINEBLITCHUNKS) + rectidx = -1; + } // if + + y -= dx; + py += sdy; + + lastX = px; + thisY = py; + } // if + px += sdx; + } // for + + if (rectidx != -1) + putMultToScreen(p, rectidx, rects); + else + goto tobylfb_blit_slanted_line; + + return; + } // else if + + else + { + _D(("LFB: Line with major axis of Y.\n")); + + int lastY = py; + int thisX = px; + int rectidx = 0; + + for (y = 0; y < dy; y++) + { + *( ((toby_uint32 *) p) + ((py * w) + px) ) = pval; + + x += dx; + if (x >= dy) // run length completed. + { + if (rectidx != -1) + { + rects[rectidx].x = thisX; + rects[rectidx].y = (lastY < py) ? lastY : py; + rects[rectidx].w = 1; + rects[rectidx].h = (py - lastY) * sdy; + + rectidx++; + if (rectidx >= LINEBLITCHUNKS) + rectidx = -1; + } // if + + x -= dy; + px += sdx; + + lastY = py; + thisX = px; + } // if + py += sdy; + } // for + + if (rectidx != -1) + putMultToScreen(p, rectidx, rects); + else + goto tobylfb_blit_slanted_line; + + return; + } // else + + assert(0); // should have return'd or goto'd by here. + +tobylfb_blit_slanted_line: + // !!! This isn't rendering right in all cases. + + float chunkX = ((float) dx) / ((float) LINEBLITCHUNKS); + float chunkY = ((float) dy) / ((float) LINEBLITCHUNKS); + float yincr; + float fx, fy; + + fx = (float) ((x1 < x2) ? x1 : x2); + + if ( ((sdx > 0) && (sdy > 0)) || // line from q1 to q4. + ((sdx < 0) && (sdy < 0)) ) + { + fy = (float) ((y1 < y2) ? y1 : y2); + yincr = chunkY; + } // if + + else // line from q3 to q2. + { + fy = (float) (((y1 > y2) ? y1 : y2)) - chunkY; + yincr = -chunkY; + } // else + + for (int i = 0; i < LINEBLITCHUNKS; i++) + { + rects[i].x = (int) (fx); + rects[i].y = (int) (fy); + rects[i].w = (int) (chunkX + 0.5); + rects[i].h = (int) (chunkY + 0.5); + + if (rects[i].w == 0) + rects[i].w++; + + if (rects[i].h == 0) + rects[i].h++; + + fx += chunkX; + fy += yincr; + } // for + + putMultToScreen(p, LINEBLITCHUNKS, rects); +} // FrameBufferTurtleSpaceRenderer::renderLine + + +void FrameBufferTurtleSpaceRenderer::renderTurtle(Turtle *turtle) throw (ExecException *) +{ + _D(("LFB: renderTurtle() called. NOT IMPLEMENTED.\n")); +} // FrameBufferTurtleSpaceRenderer::renderTurtle + + +void FrameBufferTurtleSpaceRenderer::blankTurtle(Turtle *turtle) throw (ExecException *) +{ + _D(("LFB: blankTurtle() called. NOT IMPLEMENTED.\n")); +} // FrameBufferTurtleSpaceRenderer::blankTurtle + + +void FrameBufferTurtleSpaceRenderer::cleanup(void) throw (ExecException *) +{ + blankPixels(getSurface(), w, h); +} // FrameBufferTurtleSpaceRenderer::cleanup + + +inline toby_uint32 FrameBufferTurtleSpaceRenderer::constructPixelValue( + float r, + float g, + float b, + float a) +{ + // !!! check this. + return( + (((int) (a * 255.0)) << 24) | + (((int) (r * 255.0)) << 16) | + (((int) (b * 255.0)) << 8) | + (((int) (g * 255.0)) ) + ); + +#if 0 + _D(("%f, %f, %f, %f == ", r, b, g, a)); + + for (unsigned int i = 1 << 31; i != 0; i >>= 1) + _D(("%d", (int) ((pval & i) / i))); + + _D(("\n")); +#endif + +} // FrameBufferTurtleSpaceRenderer::constructPixelValue + + +void FrameBufferTurtleSpaceRenderer::createSurface(int _w, int _h) +{ + defaultSurface = new toby_uint32[_w * _h]; +} // FrameBufferTurtleSpaceRenderer::createSurface + + +void FrameBufferTurtleSpaceRenderer::deleteSurface(void) +{ + if (defaultSurface != NULL) + delete[] defaultSurface; +} // FrameBufferTurtleSpaceRenderer::deleteSurface + + +toby_uint32 *FrameBufferTurtleSpaceRenderer::getSurface(void) +{ + return(defaultSurface); +} // FrameBufferTurtleSpaceRenderer::getSurface + + +void FrameBufferTurtleSpaceRenderer::putMultToScreen(toby_uint32 *pix, + int rectCount, + FrameBufferRect *rects) +{ + for (int i = 0; i < rectCount; i++) + putToScreen(pix, rects[i].x, rects[i].y, rects[i].w, rects[i].h); +} // FrameBufferTurtleSpaceRenderer::putMultToScreen + +// end of FrameBufferTurtleSpaceRenderer.cpp ... + diff --git a/src/platform/renderers/fbrenderer/FrameBufferTurtleSpaceRenderer.h b/src/platform/renderers/fbrenderer/FrameBufferTurtleSpaceRenderer.h new file mode 100644 index 0000000..4a0d6c2 --- /dev/null +++ b/src/platform/renderers/fbrenderer/FrameBufferTurtleSpaceRenderer.h @@ -0,0 +1,135 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _INCLUDE_FRAMEBUFFERTURTLESPACERENDERER_H_ +#define _INCLUDE_FRAMEBUFFERTURTLESPACERENDERER_H_ + +#include "turtlespace/TurtleSpaceRenderer.h" +#include "util/TobyGeometry.h" + + +typedef struct __STRUCT_FrameBufferRect +{ + int x; + int y; + int w; + int h; +} FrameBufferRect; + +/* + * An implementation of TurtleSpaceRenderer that writes to a linear + * framebuffer in memory. Internally, this framebuffer is 32-bits per + * pixel: 8 bits each for red, green, blue, and alpha. Rendering into + * this framebuffer is done within this class, which expects a subclass + * to take responsibility for getting the bits to the screen. The subclass + * is also responsible for converting the 32-bit format to their visual's + * format, including alpha-blending. + * + * Written by Ryan C. Gordon. (icculus@linuxgames.com) + */ +class FrameBufferTurtleSpaceRenderer : public TurtleSpaceRenderer +{ +public: + FrameBufferTurtleSpaceRenderer(void); + virtual ~FrameBufferTurtleSpaceRenderer(void); + + // Do NOT override this. This base class will call screenResize(), + // where you can perform your own setup. + virtual bool resize(int _w, int _h); + + // Grab notifications are currently no-ops in this class, but if you + // override them, please call the superclass's version first, just + // in case. + virtual void notifyGrabbed(void); + virtual void notifyUngrabbed(void); + + // These will probably not need overriding. + virtual double getTurtleSpaceWidth(void); + virtual double getTurtleSpaceHeight(void); + virtual double getDesiredTurtleWidth(void); + virtual double getDesiredTurtleHeight(void); + virtual void renderString(double x, double y, double angle, + float r, float b, float g, float a, + const char *str); + virtual void renderLine(double x1, double y1, double x2, double y2, + float r, float b, float g, float a); + virtual void renderTurtle(Turtle *turtle) throw (ExecException *); + virtual void blankTurtle(Turtle *turtle) throw (ExecException *); + virtual void cleanup(void) throw (ExecException *); + + +protected: + + // This returns a 32-bit value based on four floats that represent + // intensity of the color channels in the range of 0.0 to 1.0. + inline toby_uint32 constructPixelValue(float r, float g, float b, float a); + + // Set the screen surface (the window, the fullscreen resolution, + // whatever) to (_w) by (_h) pixels. Returns (true) if successful, + // (false) otherwise. If this succeeds, this base class will then + // attempt to build an offscreen surface (via createSurface()). + // You must implement this. + virtual bool screenResize(int _w, int _h) = 0; + + // Some toolkits can accelerate blits to the screen if they manage + // their own offscreen memory surface. In such a case, this method + // should be overridden to build a platform-specific surface. The + // offscreen surface must be a linear framebuffer, 32-bits per pixel, + // in format 0xAARRBBGG (Alpha, Red, Blue, Green). If not overridden, + // this base class will allocate a block of memory for itself. + virtual void createSurface(int _w, int _h); + + // Free resources allocated by createSurface(). The base class will + // always call deleteSurface() before calling createSurface() again + // (in case of resizing, etc). This, by default, cleans up an + // internal buffer created by this base class. You must override + // this if you overrode createSurface()! + virtual void deleteSurface(void); + + // Get the offscreen surface's linear framebuffer. This, by default, + // returns the memory buffer allocated by this base class. If + // createSurface() could not build an offscreen surface, this method + // should return NULL. You must override this if you overrode + // createSurface()! + virtual toby_uint32 *getSurface(void); + + // Take the framebuffer pointed to by (pix) and display the pixels + // within the rectangle specified by (x), (y), (w), and (h). + // You must implement this! + virtual void putToScreen(toby_uint32 *pix, int x, int y, int w, int h) = 0; + + // If your renderer can accelerate putting multiple rectangles to + // the screen at the same time, then override this. + // The default implementation just calls putToScreen() on each + // rectangle in the array. + virtual void putMultToScreen(toby_uint32 *pix, int rectCount, + FrameBufferRect *rects); + +private: + toby_uint32 *defaultSurface; + int w; + int h; + + void blankPixels(toby_uint32 *p, int _w, int _h); +}; // class FrameBufferTurtleSpaceRenderer + +#endif // !defined _INCLUDE_FRAMEBUFFERTURTLESPACERENDERER_H_ + +// end of FrameBufferTurtleSpaceRenderer.h ... + diff --git a/src/platform/renderers/gtkrenderer/GTKTurtleSpaceRenderer.cpp b/src/platform/renderers/gtkrenderer/GTKTurtleSpaceRenderer.cpp new file mode 100644 index 0000000..63bc08c --- /dev/null +++ b/src/platform/renderers/gtkrenderer/GTKTurtleSpaceRenderer.cpp @@ -0,0 +1,313 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "platform/renderers/gtkrenderer/GTKTurtleSpaceRenderer.h" + + +// !!! make these into instance members! +static volatile bool window_still_not_displayed = true; +static volatile bool quit_event_caught = false; + +static gboolean on_gtkcanvas_expose(GtkWidget *widget, + GdkEventExpose *event, + gpointer user_data) +{ + GTKTurtleSpaceRenderer *r = (GTKTurtleSpaceRenderer *) user_data; + assert(r != NULL); + + gint _x = event->area.x; + gint _y = event->area.y; + gint _w = event->area.width; + gint _h = event->area.height; + + GdkGC *_gc = gdk_gc_new(widget->window); + GdkPixmap *p = r->getOffscreenPixmap(); + if (p == NULL) + { + gdk_rgb_gc_set_foreground(_gc, 0x000000); + gdk_draw_rectangle(widget->window, _gc, TRUE, _x, _y, _w, _h); + } // if + else + { + gdk_draw_pixmap(widget->window, _gc, p, _x, _y, _x, _y, _w, _h); + } // else + + gdk_gc_unref(_gc); + + window_still_not_displayed = false; + + return(FALSE); +} // on_gtkcanvas_expose + + +GTKTurtleSpaceRenderer::GTKTurtleSpaceRenderer(void) + : gc(NULL), offscreen_pixmap(NULL), + canvas(gtk_drawing_area_new()) +{ + gtk_widget_ref(canvas); + gdk_rgb_init(); + gtk_widget_set_default_colormap(gdk_rgb_get_cmap()); + gtk_widget_set_default_visual(gdk_rgb_get_visual()); + + gtk_signal_connect(GTK_OBJECT(canvas), "expose_event", + GTK_SIGNAL_FUNC(on_gtkcanvas_expose), this); +} // Constructor + + +GTKTurtleSpaceRenderer::~GTKTurtleSpaceRenderer(void) +{ + if (canvas != NULL) + { + gtk_widget_hide(canvas); + gtk_widget_unref(canvas); + } // if + + if (offscreen_pixmap != NULL) + { + gdk_pixmap_unref(offscreen_pixmap); + } // if +} // Destructor + + +bool GTKTurtleSpaceRenderer::resize(int w, int h) +{ + _D(("GTK canvas resize: (%d, %d).\n", w, h)); + + if (canvas == NULL) + return(false); + + GdkPixmap *pix = gdk_pixmap_new(canvas->window, w, h, -1); + if (pix == NULL) + return(false); + + GtkStyle *_style = gtk_style_copy(gtk_widget_get_style(canvas)); + memcpy(&(_style->bg[GTK_STATE_NORMAL]), &_style->black, sizeof (GdkColor)); + gtk_widget_set_style(canvas, _style); + + gtk_widget_set_usize(canvas, w, h); + gtk_widget_show(canvas); + + GdkGC *_gc = gdk_gc_new(canvas->window); + gdk_rgb_gc_set_foreground(_gc, 0x00000000); + gdk_draw_rectangle(pix, _gc, TRUE, 0, 0, w, h); + + if (offscreen_pixmap != NULL) + { + // !!! move old image to new pixmap. gdk_draw_pixmap( + gdk_pixmap_unref(offscreen_pixmap); + } // if + + gdk_gc_unref(_gc); + offscreen_pixmap = pix; + + while ((window_still_not_displayed) || (gtk_events_pending())) + gtk_main_iteration(); + + while ((canvas->allocation.width != w) || (canvas->allocation.height != h)) + gtk_main_iteration(); + + return(true); +} // GTKTurtleSpaceRenderer::resize + + +void GTKTurtleSpaceRenderer::notifyGrabbed(void) +{ + gc = gdk_gc_new(canvas->window); + assert(gc != NULL); + + while (gtk_events_pending()) + gtk_main_iteration(); +} // GTKTurtleSpaceRenderer::notifyGrabbed + + +void GTKTurtleSpaceRenderer::notifyUngrabbed(void) +{ + if (gc != NULL) + { + gdk_gc_destroy(gc); + gc = NULL; + } // if + + while (gtk_events_pending()) + gtk_main_iteration(); +} // GTKTurtleSpaceRenderer::notifyUngrabbed + + +double GTKTurtleSpaceRenderer::getTurtleSpaceWidth(void) +{ + assert(canvas != NULL); + return((double) canvas->allocation.width); +} // GTKTurtleSpaceRenderer::getTurtleSpaceWidth + + +double GTKTurtleSpaceRenderer::getTurtleSpaceHeight(void) +{ + assert(canvas != NULL); + return((double) canvas->allocation.height); +} // GTKTurtleSpaceRenderer::getTurtleSpaceHeight + + +double GTKTurtleSpaceRenderer::getDesiredTurtleWidth(void) +{ + return(canvas->allocation.width * 0.02); +} // GTKTurtleSpaceRenderer::getDesiredTurtleWidth + + +double GTKTurtleSpaceRenderer::getDesiredTurtleHeight(void) +{ + return(canvas->allocation.height * 0.02); +} // GTKTurtleSpaceRenderer::getDesiredTurtleHeight + + +inline guint32 GTKTurtleSpaceRenderer::constructPixelValue(float r, float g, + float b, float a) +{ + // !!! check this. + return( + //(((int) (a * 255.0)) << 24) | + (((int) (r * 255.0)) << 16) | + (((int) (b * 255.0)) << 8) | + (((int) (g * 255.0)) ) + ); +} // FrameBufferTurtleSpaceRenderer::constructPixelValue + + +void GTKTurtleSpaceRenderer::renderString(double x, double y, double angle, + float r, float b, float g, float a, + const char *str) +{ +} // GTKTurtleSpaceRenderer::renderString + + +void GTKTurtleSpaceRenderer::renderLine(double _x1, double _y1, + double _x2, double _y2, + float r, float b, + float g, float a) +{ + + assert(canvas != NULL); + assert(offscreen_pixmap != NULL); + assert(gc != NULL); + + guint32 pval = constructPixelValue(r, g, b, a); + + gdk_rgb_gc_set_foreground(gc, pval); + + int x1 = TobyGeometry::roundDoubleToInt(_x1); + int y1 = TobyGeometry::roundDoubleToInt(_y1); + int x2 = TobyGeometry::roundDoubleToInt(_x2); + int y2 = TobyGeometry::roundDoubleToInt(_y2); + + gdk_draw_line(offscreen_pixmap, gc, x1, y1, x2, y2); + gdk_draw_line(canvas->window, gc, x1, y1, x2, y2); +} // GTKTurtleSpaceRenderer::renderLine + + +void GTKTurtleSpaceRenderer::renderTurtle(Turtle *t) throw (ExecException *) +{ +} // GTKTurtleSpaceRenderer::renderTurtle + + +void GTKTurtleSpaceRenderer::blankTurtle(Turtle *t) throw (ExecException *) +{ +} // GTKTurtleSpaceRenderer::blankTurtle + + +void GTKTurtleSpaceRenderer::cleanup(void) throw (ExecException *) +{ + assert(canvas != NULL); + assert(gc != NULL); + + gdk_rgb_gc_set_foreground(gc, 0x00000000); + gdk_draw_rectangle(canvas->window, gc, TRUE, 0, 0, + canvas->allocation.width, canvas->allocation.height); + + while (gtk_events_pending()) + gtk_main_iteration(); +} // GTKTurtleSpaceRenderer::cleanup + + +GtkWidget *GTKTurtleSpaceRenderer::getDrawingAreaWidget(void) +{ + return(canvas); +} // GTKTurtleSpaceRenderer::getDrawingAreaWidget + + +GdkPixmap *GTKTurtleSpaceRenderer::getOffscreenPixmap(void) +{ + return(offscreen_pixmap); +} // GTKTurtleSpaceRenderer::getOffscreenPixmap + + +static gint on_gtk_window_delete(GtkWidget *widget, + GdkEvent *event, + gpointer data ) +{ + quit_event_caught = true; + return(FALSE); +} // on_gtk_window_delete + + +TurtleSpaceRenderer *__platformBuildStandaloneRenderer(char *winTitle, + int *argc, char ***argv) +{ + window_still_not_displayed = true; + quit_event_caught = false; + + gtk_init(argc, argv); + + GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + assert(window != NULL); + + // prevent user from resizing window... + gtk_window_set_policy(GTK_WINDOW(window), FALSE, FALSE, TRUE); + + gtk_window_set_title(GTK_WINDOW(window), winTitle); + + GTKTurtleSpaceRenderer *retval = new GTKTurtleSpaceRenderer(); + assert(retval != NULL); + GtkWidget *darea = retval->getDrawingAreaWidget(); + assert(darea != NULL); + + gtk_signal_connect(GTK_OBJECT(window), "delete_event", + GTK_SIGNAL_FUNC(on_gtk_window_delete), darea); + + gtk_widget_realize(window); + gtk_container_add(GTK_CONTAINER(window), darea); + gtk_widget_realize(darea); + gtk_widget_show(darea); + gtk_widget_show(window); + + while (gtk_events_pending()) + gtk_main_iteration(); + + return(retval); +} // __platformBuildStandaloneRenderer + + +bool __platformRendererDoEvents(void) +{ + while (gtk_events_pending()) + gtk_main_iteration(); + + return(!quit_event_caught); +} // __platformRendererDoEvents + +// end of GTKTurtleSpaceRenderer.cpp ... + diff --git a/src/platform/renderers/gtkrenderer/GTKTurtleSpaceRenderer.h b/src/platform/renderers/gtkrenderer/GTKTurtleSpaceRenderer.h new file mode 100644 index 0000000..449495e --- /dev/null +++ b/src/platform/renderers/gtkrenderer/GTKTurtleSpaceRenderer.h @@ -0,0 +1,72 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _INCLUDE_GTKTURTLESPACERENDERER_H_ +#define _INCLUDE_GTKTURTLESPACERENDERER_H_ + +#include +#include "turtlespace/TurtleSpaceRenderer.h" +#include "util/TobyGeometry.h" + +/* + * A GTK+-based TurtleSpaceRenderer. GTK+ and related libraries can be + * found at http://www.gtk.org/. + * + * Written by Ryan C. Gordon. (icculus@linuxgames.com) + */ +class GTKTurtleSpaceRenderer : public TurtleSpaceRenderer +{ +public: + GTKTurtleSpaceRenderer(void); + virtual ~GTKTurtleSpaceRenderer(void); + + virtual bool resize(int _w, int _h); + virtual void notifyGrabbed(void); + virtual void notifyUngrabbed(void); + virtual double getTurtleSpaceWidth(void); + virtual double getTurtleSpaceHeight(void); + virtual double getDesiredTurtleWidth(void); + virtual double getDesiredTurtleHeight(void); + virtual void renderString(double x, double y, double angle, + float r, float b, float g, float a, + const char *str); + virtual void renderLine(double x1, double y1, double x2, double y2, + float r, float b, float g, float a); + virtual void renderTurtle(Turtle *turtle) throw (ExecException *); + virtual void blankTurtle(Turtle *turtle) throw (ExecException *); + virtual void cleanup(void) throw (ExecException *); + + virtual GtkWidget *getDrawingAreaWidget(void); + virtual GdkPixmap *getOffscreenPixmap(void); + +protected: + // This returns a 32-bit value based on four floats that represent + // intensity of the color channels in the range of 0.0 to 1.0. + inline guint32 constructPixelValue(float r, float g, float b, float a); + +private: + GdkGC *gc; + GdkPixmap *offscreen_pixmap; + GtkWidget *canvas; +}; // class GTKTurtleSpaceRenderer + +#endif // !defined _INCLUDE_GTKTURTLESPACERENDERER_H_ + +// end of GTKTurtleSpaceRenderer.h ... + diff --git a/src/platform/renderers/sdlrenderer/SDLTurtleSpaceRenderer.cpp b/src/platform/renderers/sdlrenderer/SDLTurtleSpaceRenderer.cpp new file mode 100644 index 0000000..0fec22e --- /dev/null +++ b/src/platform/renderers/sdlrenderer/SDLTurtleSpaceRenderer.cpp @@ -0,0 +1,145 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "platform/renderers/sdlrenderer/SDLTurtleSpaceRenderer.h" + + +SDLTurtleSpaceRenderer::SDLTurtleSpaceRenderer(Uint32 flags) + : FrameBufferTurtleSpaceRenderer(), + sdlflags(flags), + swsurface(NULL) +{ +} // Constructor + + +SDLTurtleSpaceRenderer::~SDLTurtleSpaceRenderer(void) +{ + deleteSurface(); + SDL_QuitSubSystem(SDL_INIT_VIDEO); +} // Destructor + + +bool SDLTurtleSpaceRenderer::screenResize(int _w, int _h) +{ + if (SDL_Init(SDL_INIT_VIDEO) < 0) + return(false); + + SDL_WM_SetCaption("Toby", "Toby"); + SDL_Surface *screen = SDL_SetVideoMode(_w, _h, 32, sdlflags); + return(screen != NULL); +} // SDLTurtleSpaceRenderer::screenResize + + +void SDLTurtleSpaceRenderer::createSurface(int _w, int _h) +{ + swsurface = SDL_CreateRGBSurface(SDL_SWSURFACE, _w, _h, 32, + 0x00FF0000, 0x0000FF00, + 0x000000FF, 0xFF000000); +} // SDLTurtleSpaceRenderer::createSurface + + +void SDLTurtleSpaceRenderer::deleteSurface(void) +{ + if (swsurface != NULL) + { + SDL_FreeSurface(swsurface); + swsurface = NULL; + } // if +} // SDLTurtleSpaceRenderer::deleteSurface + + +void SDLTurtleSpaceRenderer::putToScreen(toby_uint32 *pix, + int x, int y, + int w, int h) +{ + assert(pix == swsurface->pixels); + SDL_Rect rect = {x, y, w, h}; + SDL_Surface *screen = SDL_GetVideoSurface(); + assert(screen != NULL); + + if (SDL_MUSTLOCK(screen)) + SDL_LockSurface(screen); + + SDL_BlitSurface(swsurface, &rect, screen, &rect); + + if (SDL_MUSTLOCK(screen)) + SDL_UnlockSurface(screen); + + SDL_UpdateRect(screen, x, y, w, h); // !!! need this? +} // SDLTurtleSpaceRenderer::putToScreen + + +void SDLTurtleSpaceRenderer::putMultToScreen(toby_uint32 *pix, int rectCount, + FrameBufferRect *rects) +{ + assert(pix == swsurface->pixels); + SDL_Surface *screen = SDL_GetVideoSurface(); + assert(screen != NULL); + + if (SDL_MUSTLOCK(screen)) + SDL_LockSurface(screen); + + for (int i = 0; i < rectCount; i++) + { + SDL_Rect r = {rects[i].x, rects[i].y, rects[i].w, rects[i].h}; + SDL_BlitSurface(swsurface, &r, screen, &r); + SDL_UpdateRect(screen, r.x, r.y, r.w, r.h); + } // for + + if (SDL_MUSTLOCK(screen)) + SDL_UnlockSurface(screen); + +// SDL_UpdateRects(screen, rectCount, (SDL_Rect *) rects); // !!! need this? +} // SDLTurtleSpaceRenderer::putToScreen + + +toby_uint32 *SDLTurtleSpaceRenderer::getSurface(void) +{ + if (swsurface == NULL) + return(NULL); + + return((toby_uint32 *) swsurface->pixels); +} // SDLTurtleSpaceRenderer::getSurface + + +TurtleSpaceRenderer *__platformBuildStandaloneRenderer(char *winTitle, + int *argc, char ***argv) +{ + SDLTurtleSpaceRenderer *retval = new SDLTurtleSpaceRenderer(0); + SDL_WM_SetCaption(winTitle, winTitle); + return(retval); +} // __platformBuildStandaloneRenderer + + +bool __platformRendererDoEvents(void) +{ + bool retval = true; + SDL_Event event; + + while (SDL_PollEvent(&event)) + { + if (event.type == SDL_QUIT) + retval = false; + } // while + + return(retval); +} // __platformRendererDoEvents + +// end of SDLTurtleSpaceRenderer.cpp ... + diff --git a/src/platform/renderers/sdlrenderer/SDLTurtleSpaceRenderer.h b/src/platform/renderers/sdlrenderer/SDLTurtleSpaceRenderer.h new file mode 100644 index 0000000..a9af489 --- /dev/null +++ b/src/platform/renderers/sdlrenderer/SDLTurtleSpaceRenderer.h @@ -0,0 +1,62 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _INCLUDE_SDLTURTLESPACERENDERER_H_ +#define _INCLUDE_SDLTURTLESPACERENDERER_H_ + +#include "SDL.h" +#include "platform/renderers/fbrenderer/FrameBufferTurtleSpaceRenderer.h" + +/* + * An implementation of TurtleSpaceRenderer that does its drawing through + * FrameBufferTurtleSpaceRenderer as a superclass, and uses SDL for getting + * the bits to the screen. SDL stands for Simple Directmedia Layer, and + * is a fast, easy-to-use, cross-platform library for graphics, sound, + * input, etc. + * + * SDL can be found at http://www.libsdl.org/ + * + * Written by Ryan C. Gordon. (icculus@linuxgames.com) + */ +class SDLTurtleSpaceRenderer : public FrameBufferTurtleSpaceRenderer +{ +public: + SDLTurtleSpaceRenderer(Uint32 sdlflags); + virtual ~SDLTurtleSpaceRenderer(void); + + virtual bool screenResize(int _w, int _h); + +protected: + virtual void createSurface(int _w, int _h); + virtual void deleteSurface(void); + virtual toby_uint32 *getSurface(void); + virtual void putToScreen(toby_uint32 *pix, int x, int y, int w, int h); + virtual void putMultToScreen(toby_uint32 *pix, int rectCount, + FrameBufferRect *rects); + +private: + Uint32 sdlflags; + SDL_Surface *screen; + SDL_Surface *swsurface; +}; // class SDLTurtleSpaceRenderer + +#endif // !defined _INCLUDE_SDLTURTLESPACERENDERER_H_ + +// end of SDLTurtleSpaceRenderer.h ... + diff --git a/src/platform/threads/nullthreads/NullMutex.cpp b/src/platform/threads/nullthreads/NullMutex.cpp new file mode 100644 index 0000000..34380d5 --- /dev/null +++ b/src/platform/threads/nullthreads/NullMutex.cpp @@ -0,0 +1,56 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "platform/threads/nullthreads/NullMutex.h" + + +NullMutex::NullMutex(void) +{ + _D(("NullMutex::NullMutex() called!\n")); +} // Constructor + + +NullMutex::~NullMutex(void) +{ + _D(("NullMutex::~NullMutex() called!\n")); +} // Destructor + + +void NullMutex::request(void) +{ + _D(("NullMutex::release() called!\n")); +} // NullMutex::request + + +void NullMutex::release(void) +{ + _D(("NullMutex::release() called!\n")); +} // NullMutex::request + + + +// eine kleine platform glue... + +TobyMutex *__platformBuildMutex(void) +{ + return(new NullMutex()); +} // __platformBuildMutex + +// end of NullMutex.cpp ... + diff --git a/src/platform/threads/nullthreads/NullMutex.h b/src/platform/threads/nullthreads/NullMutex.h new file mode 100644 index 0000000..6722f7e --- /dev/null +++ b/src/platform/threads/nullthreads/NullMutex.h @@ -0,0 +1,43 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _INCLUDE_NULLMUTEX_H_ +#define _INCLUDE_NULLMUTEX_H_ + +#include "util/TobyMutex.h" + +/* + * A null implementation of TobyMutex. Use this as a stub to get you going + * until you can implement your own platform-specify mutex implementation. + * + * Written by Ryan C. Gordon. (icculus@linuxgames.com) + */ +class NullMutex : public TobyMutex +{ +public: + NullMutex(void); + virtual ~NullMutex(void); + virtual void request(void); + virtual void release(void); +}; // class NullMutex + +#endif // !defined _INCLUDE_NULLMUTEX_H_ + +// end of NullMutex.h ... + diff --git a/src/platform/threads/nullthreads/NullThread.cpp b/src/platform/threads/nullthreads/NullThread.cpp new file mode 100644 index 0000000..9b5e3fc --- /dev/null +++ b/src/platform/threads/nullthreads/NullThread.cpp @@ -0,0 +1,66 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "platform/threads/nullthreads/NullThread.h" + + +NullThread::NullThread(void) +{ + _D(("NullThread::NullThread() called!\n")); +} // Constructor + + +NullThread::~NullThread(void) +{ + _D(("NullThread::~NullThread() called!\n")); +} // Destructor + + +void NullThread::start(void *(*runfunc)(void *)) +{ + _D(("NullThread::start() called!\n")); +} // NullThread::start + + +void NullThread::waitForTermination(void) +{ + _D(("NullThread::waitForTermination() called!\n")); +} // NullThread::waitForTermination + + +bool NullThread::isTerminated(void) +{ + _D(("NullThread::isTerminated() called!\n")); + return(true); +} // NullThread::isTerminated + + +TobyThread *__platformBuildThread(void) +{ + return(new NullThread()); +} // __platformBuildThread + + +void __platformThreadYieldCurrent(void) +{ + _D(("Null version of __platformThreadYieldCurrent() called!\n")); +} // __platformThreadYieldCurrent + +// end of NullThread.cpp ... + diff --git a/src/platform/threads/nullthreads/NullThread.h b/src/platform/threads/nullthreads/NullThread.h new file mode 100644 index 0000000..ecb0d52 --- /dev/null +++ b/src/platform/threads/nullthreads/NullThread.h @@ -0,0 +1,46 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _INCLUDE_NULLTHREAD_H_ +#define _INCLUDE_NULLTHREAD_H_ + +#include +#include +#include "util/TobyThread.h" + +/* + * A null implementation of TobyThreads. Use this as a stub until you can get + * platform-specific code written. + * + * Written by Ryan C. Gordon. (icculus@linuxgames.com) + */ +class NullThread : public TobyThread +{ +public: + NullThread(void); + virtual ~NullThread(void); + virtual void start(void *(*runfunc)(void *)); + virtual void waitForTermination(void); + virtual bool isTerminated(void); +}; // class NullThread + +#endif // !defined _INCLUDE_NULLTHREAD_H_ + +// end of NullThread.h ... + diff --git a/src/platform/threads/pthreads/PthreadsMutex.cpp b/src/platform/threads/pthreads/PthreadsMutex.cpp new file mode 100644 index 0000000..7d4ffec --- /dev/null +++ b/src/platform/threads/pthreads/PthreadsMutex.cpp @@ -0,0 +1,56 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "platform/threads/pthreads/PthreadsMutex.h" + + +PthreadsMutex::PthreadsMutex(void) +{ + // !!! +} // Constructor + + +PthreadsMutex::~PthreadsMutex(void) +{ + // !!! +} // Destructor + + +void PthreadsMutex::request(void) +{ + // !!! +} // PthreadsMutex::request + + +void PthreadsMutex::release(void) +{ + // !!! +} // PthreadsMutex::request + + + +// eine kleine platform glue... + +TobyMutex *__platformBuildMutex(void) +{ + return(new PthreadsMutex()); +} // __platformBuildMutex + +// end of PthreadsMutex.cpp ... + diff --git a/src/platform/threads/pthreads/PthreadsMutex.h b/src/platform/threads/pthreads/PthreadsMutex.h new file mode 100644 index 0000000..4758c83 --- /dev/null +++ b/src/platform/threads/pthreads/PthreadsMutex.h @@ -0,0 +1,42 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _INCLUDE_PTHREADSMUTEX_H_ +#define _INCLUDE_PTHREADSMUTEX_H_ + +#include "util/TobyMutex.h" + +/* + * A POSIX threads implementation of TobyMutex. + * + * Written by Ryan C. Gordon. (icculus@linuxgames.com) + */ +class PthreadsMutex : public TobyMutex +{ +public: + PthreadsMutex(void); + virtual ~PthreadsMutex(void); + virtual void request(void); + virtual void release(void); +}; // class PthreadsMutex + +#endif // !defined _INCLUDE_PTHREADSMUTEX_H_ + +// end of PthreadsMutex.h ... + diff --git a/src/platform/threads/pthreads/PthreadsThread.cpp b/src/platform/threads/pthreads/PthreadsThread.cpp new file mode 100644 index 0000000..0b1e2ff --- /dev/null +++ b/src/platform/threads/pthreads/PthreadsThread.cpp @@ -0,0 +1,65 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "platform/threads/pthreads/PthreadsThread.h" + + +PthreadsThread::PthreadsThread(void) +{ +} // Constructor + + +PthreadsThread::~PthreadsThread(void) +{ +} // Destructor + + +void PthreadsThread::start(void *(*runfunc)(void *)) +{ +} // PthreadsThread::start + + +void PthreadsThread::waitForTermination(void) +{ +} // PthreadsThread::waitForTermination + + +bool PthreadsThread::isTerminated(void) +{ + return(true); +} // PthreadsThread::isTerminated + + +TobyThread *__platformBuildThread(void) +{ + return(new PthreadsThread()); +} // __platformBuildThread + + +void __platformThreadYieldCurrent(void) +{ +#if (defined _POSIX_PRIORITY_SCHEDULING) + sched_yield(); +#else +#warning There is no sched_yield() on this platform... +#endif +} // __platformThreadYieldCurrent + +// end of PthreadsThread.cpp ... + diff --git a/src/platform/threads/pthreads/PthreadsThread.h b/src/platform/threads/pthreads/PthreadsThread.h new file mode 100644 index 0000000..a5f589f --- /dev/null +++ b/src/platform/threads/pthreads/PthreadsThread.h @@ -0,0 +1,46 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _INCLUDE_PTHREADSTHREAD_H_ +#define _INCLUDE_PTHREADSTHREAD_H_ + +#include +#include +#include "util/TobyThread.h" + +/* + * A Pthreads-based implementation of TobyThreads. This covers most Unixes, + * and other POSIX-compliant systems. + * + * Written by Ryan C. Gordon. (icculus@linuxgames.com) + */ +class PthreadsThread : public TobyThread +{ +public: + PthreadsThread(void); + virtual ~PthreadsThread(void); + virtual void start(void *(*runfunc)(void *)); + virtual void waitForTermination(void); + virtual bool isTerminated(void); +}; // class PthreadsThread + +#endif // !defined _INCLUDE_PTHREADSTHREAD_H_ + +// end of PthreadsThread.h ... + diff --git a/src/platform/threads/sdlthreads/SDLMutex.cpp b/src/platform/threads/sdlthreads/SDLMutex.cpp new file mode 100644 index 0000000..aaa1a83 --- /dev/null +++ b/src/platform/threads/sdlthreads/SDLMutex.cpp @@ -0,0 +1,56 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "platform/threads/sdlthreads/SDLMutex.h" + + +SDLMutex::SDLMutex(void) +{ + // !!! +} // Constructor + + +SDLMutex::~SDLMutex(void) +{ + // !!! +} // Destructor + + +void SDLMutex::request(void) +{ + // !!! +} // SDLMutex::request + + +void SDLMutex::release(void) +{ + // !!! +} // SDLMutex::request + + + +// eine kleine platform glue... + +TobyMutex *__platformBuildMutex(void) +{ + return(new SDLMutex()); +} // __platformBuildMutex + +// end of SDLMutex.cpp ... + diff --git a/src/platform/threads/sdlthreads/SDLMutex.h b/src/platform/threads/sdlthreads/SDLMutex.h new file mode 100644 index 0000000..2d1c9b3 --- /dev/null +++ b/src/platform/threads/sdlthreads/SDLMutex.h @@ -0,0 +1,47 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _INCLUDE_SDLMUTEX_H_ +#define _INCLUDE_SDLMUTEX_H_ + +#include "SDL.h" +#include "util/TobyMutex.h" + +/* + * An implementation of TobyMutex that uses Simple Directmedia Layer + * for platform-indepent synchronization. Might as well use this if you + * are using the SDL renderer, too. + * + * SDL source code and docs can be found at http://www.libsdl.org/ ... + * + * Written by Ryan C. Gordon. (icculus@linuxgames.com) + */ +class SDLMutex : public TobyMutex +{ +public: + SDLMutex(void); + virtual ~SDLMutex(void); + virtual void request(void); + virtual void release(void); +}; // class SDLMutex + +#endif // !defined _INCLUDE_SDLMUTEX_H_ + +// end of SDLMutex.h ... + diff --git a/src/platform/threads/sdlthreads/SDLThread.cpp b/src/platform/threads/sdlthreads/SDLThread.cpp new file mode 100644 index 0000000..c8a8f22 --- /dev/null +++ b/src/platform/threads/sdlthreads/SDLThread.cpp @@ -0,0 +1,61 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "platform/threads/sdlthreads/SDLThread.h" + + +SDLThread::SDLThread(void) +{ +} // Constructor + + +SDLThread::~SDLThread(void) +{ +} // Destructor + + +void SDLThread::start(void *(*runfunc)(void *)) +{ +} // SDLThread::start + + +void SDLThread::waitForTermination(void) +{ +} // SDLThread::waitForTermination + + +bool SDLThread::isTerminated(void) +{ + return(true); +} // SDLThread::isTerminated + + +TobyThread *__platformBuildThread(void) +{ + return(new SDLThread()); +} // __platformBuildThread + + +void __platformThreadYieldCurrent(void) +{ + SDL_Delay(1); +} // __platformThreadYieldCurrent + +// end of SDLThread.cpp ... + diff --git a/src/platform/threads/sdlthreads/SDLThread.h b/src/platform/threads/sdlthreads/SDLThread.h new file mode 100644 index 0000000..48f768c --- /dev/null +++ b/src/platform/threads/sdlthreads/SDLThread.h @@ -0,0 +1,45 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _INCLUDE_SDLTHREAD_H_ +#define _INCLUDE_SDLTHREAD_H_ + +#include "SDL.h" +#include "util/TobyThread.h" + +/* + * A SDL-based implementation of TobyThreads. This covers most Unixes, + * and other POSIX-compliant systems. + * + * Written by Ryan C. Gordon. (icculus@linuxgames.com) + */ +class SDLThread : public TobyThread +{ +public: + SDLThread(void); + virtual ~SDLThread(void); + virtual void start(void *(*runfunc)(void *)); + virtual void waitForTermination(void); + virtual bool isTerminated(void); +}; // class SDLThread + +#endif // !defined _INCLUDE_SDLTHREAD_H_ + +// end of SDLThread.h ... + diff --git a/src/standalone.cpp b/src/standalone.cpp new file mode 100644 index 0000000..8742c1e --- /dev/null +++ b/src/standalone.cpp @@ -0,0 +1,153 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +/* + * This is a program entry point for a standalone Toby interpreter. + * There is no user interface, it just takes a source file on the command + * line and fires up the interpreter and renderer. + * + * Written by Ryan C. Gordon (icculus@linuxgames.com) + */ + +#include +#include +#include "turtlespace/TurtleSpace.h" +#include "turtlespace/TurtleSpaceRenderer.h" +#include "util/TobyThread.h" + +int main(int argc, char **argv) +{ + bool no_timing = false; + struct timeval start_time; + struct timeval end_time; + TurtleSpaceRenderer *renderer; + + renderer = __platformBuildStandaloneRenderer(TobyLanguage::NAME, + &argc, &argv); + + if ((renderer == NULL) || (renderer->resize(640, 480) == false)) + { + printf("failed to create TurtleSpaceRenderer.\n"); + return(0); + } // if + + TurtleSpace tspace(renderer); + + if (gettimeofday(&start_time, NULL) == -1) + { + perror("WARNING! gettimeofday() failed"); + no_timing = true; + } // if + + try + { + tspace.grabTurtleSpace(); + tspace.removeAllTurtles(); + tspace.addTurtle(); + tspace.useTurtle(0); + tspace.defaultAllTurtles(); + tspace.cleanup(); + tspace.enableFence(); + +#if 1 + + tspace.setPenColor(0.0, 1.0, 0.0, 0.0); + + for (int j = 0; j < 360; j++) + { + for (int i = 0; i < 4; i++) + { + tspace.advanceTurtle(165); + tspace.rotateTurtle(90); + } // for + tspace.rotateTurtle(1); + } // for + +#else + + float r = 0.0; + float g = 1.0; + float b = 0.0; + float a = 0.0; + + double xmax = tspace.getTurtleSpaceWidth(); + double ymax = tspace.getTurtleSpaceHeight(); + + float xincr = (1.0 / (float) xmax) * 2.0; + float yincr = (1.0 / (float) ymax) * 2.0; + + tspace.rotateTurtle(90); + + for (double y = 0.0; y < ymax; y += 1.0) + { + r = 0.0; + for (double x = 0.0; x < xmax; x += 1.0) + { + tspace.setPenColor(r, b, g, a); + tspace.setTurtleXY(x, y); + tspace.advanceTurtle(1); + r += xincr; + if ((xincr > 0.0) && (x >= (xmax / 2))) + xincr = -xincr; + } // for + xincr = -xincr; + + g -= yincr; + b += yincr; + + if ((yincr > 0.0) && (y >= (ymax / 2))) + yincr = -yincr; + } // for + +#endif + + + tspace.releaseTurtleSpace(); + } // try + + catch (TobyException *e) + { + printf("Exception!\n[%s]\n", e->getMessage()); + delete e; + } // catch + + if (gettimeofday(&end_time, NULL) == -1) + { + perror("WARNING! gettimeofday() failed"); + no_timing = true; + } // if + + if (no_timing == false) + { + unsigned long ms; + ms = (unsigned long) (((end_time.tv_sec - start_time.tv_sec) * 1000) + + ((end_time.tv_usec - start_time.tv_usec) / 1000)); + printf("total time == (%ld) milliseconds.\n", ms); + } // if + + while (__platformRendererDoEvents()) + { + __platformThreadYieldCurrent(); + } // while + + delete renderer; + return(0); +} // main + diff --git a/src/turtlespace/Turtle.cpp b/src/turtlespace/Turtle.cpp new file mode 100644 index 0000000..c4b1fb8 --- /dev/null +++ b/src/turtlespace/Turtle.cpp @@ -0,0 +1,167 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "turtlespace/Turtle.h" + +void Turtle::setSize(double newSize) +{ + sideLength = newSize; +} // Turtle::setSize + + +void Turtle::setWidth(double newSize) +{ + setSize(newSize); +} // Turtle::setWidth + + +void Turtle::setHeight(double newSize) +{ + setSize(newSize); +} // Turtle::setHeight + + +double Turtle::getWidth(void) +{ + return(sideLength); +} // Turtle::getWidth + + +double Turtle::getHeight(void) +{ + return(sideLength); +} // Turtle::getHeight + + +void Turtle::setVisible(bool visibility) +{ + isVisible = visibility; +} // Turtle::setVisible + + +bool Turtle::getVisible(void) +{ + return(isVisible); +} // Turtle::setVisible + + +void Turtle::setXY(double x, double y) +{ + turtleX = x; + turtleY = y; +} // Turtle::setXY + + +void Turtle::setX(double x) +{ + turtleX = x; +} // Turtle::setX + + +void Turtle::setY(double y) +{ + turtleY = y; +} // Turtle::setY + + +double Turtle::getX() +{ + return(turtleX); +} // Turtle::getX + + +double Turtle::getY() +{ + return(turtleY); +} // getY + + +void Turtle::getXY(double *x, double *y) +{ + if (x != NULL) + *x = turtleX; + + if (y != NULL) + *y = turtleY; +} // Turtle::getXY + + +void Turtle::rotate(double degrees) +{ + setAngle(angle + degrees); +} // Turtle::rotate + + +double Turtle::getAngle(void) +{ + return(angle); +} // getAngle + + +void Turtle::setAngle(double newAngle) +{ + angle = newAngle; + while (angle < 0) + angle += 360.0; + + // !!! can't do mod with floating point? angle %= 360.0; + while (angle >= 360.0) + angle -= 360.0; +} // Turtle::setAngle + + +void Turtle::setPenDown(bool newState) +{ + shouldDraw = newState; +} // Turtle::setPenDown + + +bool Turtle::isPenDown(void) +{ + return(shouldDraw); +} // Turtle::isPenDown + + +void Turtle::getPenColor(float *r, float *g, float *b, float *a) +{ + if (r != NULL) + *r = penRed; + + if (g != NULL) + *g = penGreen; + + if (b != NULL) + *b = penBlue; + + if (a != NULL) + *a = penAlpha; +} // Turtle::getPenColor + + +void Turtle::setPenColor(float r, float g, float b, float a) +{ + penRed = r; + penGreen = g; + penBlue = b; + penAlpha = a; +} // Turtle::setPenColor + + +// end of Turtle.cpp ... + diff --git a/src/turtlespace/Turtle.h b/src/turtlespace/Turtle.h new file mode 100644 index 0000000..409f483 --- /dev/null +++ b/src/turtlespace/Turtle.h @@ -0,0 +1,82 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _INCLUDE_TURTLE_H_ +#define _INCLUDE_TURTLE_H_ + +#include "util/TobyObject.h" + +/* + * The Turtle class. This is all the state related to one of those little + * line-drawing cursors that roams around TurtleSpace. Note that changing + * state like visibility or size doesn't affect the visual representation + * by default; these are just data structures. The TurtleSpace and + * TurtleSpaceRenderer classes handle getting those changes to the screen. + * + * Written by Ryan C. Gordon. (icculus@linuxgames.com) + */ +class Turtle : public TobyObject +{ +public: + Turtle(void) : sideLength(0.0), angle(270.0), + turtleX(0.0), turtleY(0.0), + isVisible(false), shouldDraw(true), + penRed(1.0), penGreen(1.0), penBlue(1.0), penAlpha(1.0) {} + + virtual ~Turtle(void) {} + + void setWidth(double newSize); + void setHeight(double newSize); + double getWidth(void); + double getHeight(void); + void setVisible(bool visibility); + bool getVisible(void); + void setXY(double x, double y); + void setX(double x); + void setY(double y); + double getX(void); + double getY(void); + void getXY(double *x, double *y); + void rotate(double degrees); + double getAngle(void); + void setAngle(double newAngle); + void setPenDown(bool newState); + bool isPenDown(void); + void getPenColor(float *r, float *g, float *b, float *a); + void setPenColor(float r, float g, float b, float a); + +private: + double sideLength; // Size of one side of Turtle. + double angle; // 0 - 360 degrees. Direction faced. + double turtleX; // X location of Turtle. + double turtleY; // Y location of Turtle. + bool isVisible; // Should we even paint this guy? + bool shouldDraw; // Should we leave trails? + float penRed; // Turtle's pen's red element. + float penGreen; // Turtle's pen's green element. + float penBlue; // Turtle's pen's blue element. + float penAlpha; // Turtle's pen's alpha element. + + void setSize(double newSize); // !!! remove. Turtle is not necessarily square. +}; // class Turtle + +#endif // !defined _INCLUDE_TURTLE_H_ + +// end of Turtle.h ... + diff --git a/src/turtlespace/TurtleSpace.cpp b/src/turtlespace/TurtleSpace.cpp new file mode 100644 index 0000000..033849c --- /dev/null +++ b/src/turtlespace/TurtleSpace.cpp @@ -0,0 +1,888 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "turtlespace/TurtleSpace.h" + +TurtleSpace::TurtleSpace(TurtleSpaceRenderer *_renderer) : + dueNorth(270.0), turtles(NULL), turtlesArraySize(0), + turtlePool(new TobyStack()), fenceEnabled(false), turtle(NULL), + renderer(_renderer), turtleSync(__platformBuildMutex()) +{ + assert(_renderer != NULL); +} // Constructor + + +TurtleSpace::~TurtleSpace(void) +{ + for (int i = 0; i < turtlesArraySize; i++) + { + if (turtles[i] != NULL) + delete turtles[i]; + } // for + + if (turtles != NULL) + free(turtles); + + while (turtlePool->isEmpty() == false) + delete turtlePool->remove(0); + + delete turtlePool; + +} // Destructor + + +static inline void clampFloat(float *x, float min, float max) +{ + if (*x < min) + *x = min; + else if (*x > max) + *x = max; +} // clampFloat + + +static inline void clampColorValues(float *r, float *g, float *b, float *a) +{ + clampFloat(r, 0.0, 1.0); + clampFloat(g, 0.0, 1.0); + clampFloat(b, 0.0, 1.0); + clampFloat(a, 0.0, 1.0); +} // clampColorValues + + +TurtleSpaceRenderer *TurtleSpace::getTurtleSpaceRenderer(void) +{ + return(renderer); +} // TurtleSpace::getTurtleSpaceRenderer + +double TurtleSpace::getTurtleSpaceWidth(void) +{ + return(renderer->getTurtleSpaceWidth()); +} // TurtleSpace::getTurtleSpaceWidth + + +double TurtleSpace::getTurtleSpaceHeight(void) +{ + return(renderer->getTurtleSpaceHeight()); +} // TurtleSpace::getTurtleSpaceWidth + + +double TurtleSpace::getDueNorth(void) +{ + return(dueNorth); +} // TurtleSpace::getDueNorth + + +void TurtleSpace::setDueNorth(double angle) +{ + dueNorth = angle; +} // TurtleSpace::setDueNorth + + +Turtle *TurtleSpace::getTurtleByIndex(int turtleIndex) +{ + Turtle *retVal = NULL; + + turtleSync->request(); + + if (turtles != NULL) + { + if ((turtleIndex >= 0) && (turtleIndex < turtlesArraySize)) + retVal = turtles[turtleIndex]; + } // if + + turtleSync->release(); + + return(retVal); +} // TurtleSpace::getTurtleByIndex + + +int TurtleSpace::getTurtleCount(void) +{ + int retVal = 0; + + turtleSync->request(); + + if (turtles != NULL) + { + for (int i = 0; i < turtlesArraySize; i++) + { + if (turtles[i] != NULL) + retVal++; + } // for + } // if + + turtleSync->release(); + + return(retVal); +} // TurtleSpace::getTurtleCount + + +Turtle *TurtleSpace::buildNewTurtle(void) throw (ExecException *) +{ + Turtle *retVal = NULL; + + turtleSync->request(); + retVal = (Turtle *) turtlePool->pop(); + turtleSync->release(); + + if (retVal == NULL) + retVal = new Turtle(); + + defaultTurtle(retVal); + + return(retVal); +} // TurtleSpace::buildNewTurtle + + +int TurtleSpace::addTurtle(void) throw (ExecException *) +{ + Turtle *newTurtle = buildNewTurtle(); + + turtleSync->request(); + + if (turtles != NULL) + { + for (int i = 0; i < turtlesArraySize; i++) + { + if (turtles[i] == NULL) + { + turtles[i] = newTurtle; + turtleSync->release(); + return(i); + } // if + } // for + } // if + + // if we landed here, we need to increase the size of the array... + + turtlesArraySize++; + turtles = (Turtle **)realloc(turtles, turtlesArraySize * sizeof(Turtle *)); + assert(turtles != NULL); + turtles[turtlesArraySize - 1] = newTurtle; + turtleSync->release(); + return(turtlesArraySize - 1); +} // TurtleSpace::addTurtle + + +bool TurtleSpace::removeTurtle(int turtleIndex) throw (ExecException *) +{ + bool retVal = false; + Turtle *t = getTurtleByIndex(turtleIndex); + + if (turtle == t) // set selected turtle to none if removing selected. + turtle = NULL; + + // !!! Should we throw an ExecException if turtleIndex is bogus? + + if (t != NULL) // ...if removing a valid, existing turtle... + { + renderer->blankTurtle(t); + t->setVisible(false); + turtleSync->request(); + turtlePool->push(t); + turtles[turtleIndex] = NULL; + turtleSync->release(); + retVal = true; + } // if + + return(retVal); +} // TurtleSpace::removeTurtle + + +void TurtleSpace::removeAllTurtles(void) throw (ExecException *) +{ + turtleSync->request(); + + if (turtles != NULL) + { + for (int i = 0; i < turtlesArraySize; i++) + { + if (turtles[i] != NULL) + removeTurtle(i); + } // for + } // if + + turtleSync->release(); +} // TurtleSpace::removeAllTurtles + + +void TurtleSpace::grabTurtleSpace(void) +{ + renderer->notifyGrabbed(); +} // TurtleSpace::grabTurtleSpace + + +void TurtleSpace::releaseTurtleSpace(void) +{ + renderer->notifyUngrabbed(); +} // TurtleSpace::grabTurtleSpace + + +void TurtleSpace::verifyPointInsideFence(double x, double y) + throw (ExecException *) +{ + if (fenceEnabled == true) + { + if ( (x < 0.00) || (x > renderer->getTurtleSpaceWidth()) || + (y < 0.00) || (y > renderer->getTurtleSpaceHeight()) ) + { + ExecException::_throw(TobyLanguage::TURTLE_FENCED); + } // if + } // if +} // TurtleSpace::verifyPointInsideFence + + +void TurtleSpace::enableFence(void) throw (ExecException *) +{ + setFence(true); +} // TurtleSpace::enableFence + + +void TurtleSpace::disableFence(void) throw (ExecException *) +{ + setFence(false); +} // TurtleSpace::disableFence + + +void TurtleSpace::setFence(bool buildFence) throw (ExecException *) +{ + fenceEnabled = buildFence; + + turtleSync->request(); + + try + { + if ((buildFence == true) && (turtles != NULL)) + { + Turtle *t; + + for (int i = 0; i < turtlesArraySize; i++) + { + t = turtles[i]; + if (t != NULL) + verifyPointInsideFence(t->getX(), t->getY()); + } // for + } // if + } // try + + catch (TobyObject *obj) + { + turtleSync->release(); + throw obj; + } // catch + + turtleSync->release(); +} // TurtleSpace::setFence + + +void TurtleSpace::useTurtle(int turtleIndex) throw (ExecException *) +{ + turtleSync->request(); + + Turtle *newTurtle = getTurtleByIndex(turtleIndex); + if (newTurtle != NULL) + turtle = newTurtle; + else + { + turtleSync->release(); + ExecException::_throw(TobyLanguage::BAD_ARGUMENT); + } // else + + turtleSync->release(); +} // TurtleSpace::useTurtle + + +double TurtleSpace::getTurtleX(void) throw (ExecException *) +{ + turtleSync->request(); + + if (turtle == NULL) + { + turtleSync->release(); + ExecException::_throw(TobyLanguage::NOCURTURTLE); + } // if + + double retval = turtle->getX(); + turtleSync->release(); + return(retval); +} // TurtleSpace::getTurtleX + + +double TurtleSpace::getTurtleY(void) throw (ExecException *) +{ + turtleSync->request(); + + if (turtle == NULL) + { + turtleSync->release(); + ExecException::_throw(TobyLanguage::NOCURTURTLE); + } // if + + double retval = turtle->getY(); + turtleSync->release(); + return(retval); +} // TurtleSpace::getTurtleY + + +double TurtleSpace::getTurtleWidth(void) throw (ExecException *) +{ + turtleSync->request(); + if (turtle == NULL) + { + turtleSync->release(); + ExecException::_throw(TobyLanguage::NOCURTURTLE); + } // if + + double retval = turtle->getWidth(); + turtleSync->release(); + return(retval); +} // TurtleSpace::getTurtleWidth + + +double TurtleSpace::getTurtleHeight(void) throw (ExecException *) +{ + turtleSync->request(); + if (turtle == NULL) + { + turtleSync->release(); + ExecException::_throw(TobyLanguage::NOCURTURTLE); + } // if + + double retval = turtle->getHeight(); + turtleSync->release(); + return(retval); +} // TurtleSpace::getTurtleHeight + + +void TurtleSpace::setTurtleX(double x) throw (ExecException *) +{ + turtleSync->request(); + + if (turtle == NULL) + { + turtleSync->release(); + ExecException::_throw(TobyLanguage::NOCURTURTLE); + } // if + + if (x == turtle->getX()) + turtleSync->release(); + else + { + bool isVis = turtle->getVisible(); + if (isVis == true) + renderer->blankTurtle(turtle); + + turtle->setX(x); + + if (isVis == true) + renderer->renderTurtle(turtle); + + double y = turtle->getY(); + turtleSync->release(); + verifyPointInsideFence(x, y); + } // else +} // TurtleSpace::setTurtleX + + +void TurtleSpace::setTurtleY(double y) throw (ExecException *) +{ + turtleSync->request(); + + if (turtle == NULL) + { + turtleSync->release(); + ExecException::_throw(TobyLanguage::NOCURTURTLE); + } // if + + if (y == turtle->getY()) + turtleSync->release(); + else + { + bool isVis = turtle->getVisible(); + if (isVis == true) + renderer->blankTurtle(turtle); + + turtle->setY(y); + + if (isVis == true) + renderer->renderTurtle(turtle); + + double x = turtle->getX(); + turtleSync->release(); + verifyPointInsideFence(x, y); + } // else +} // TurtleSpace::setTurtleY + + +void TurtleSpace::setTurtleXY(double x, double y) throw (ExecException *) +{ + turtleSync->request(); + + if (turtle == NULL) + { + turtleSync->release(); + ExecException::_throw(TobyLanguage::NOCURTURTLE); + } // if + + if ((y == turtle->getY()) && (x == turtle->getX())) + turtleSync->release(); + else + { + bool isVis = turtle->getVisible(); + if (isVis == true) + renderer->blankTurtle(turtle); + + turtle->setXY(x, y); + + if (isVis == true) + renderer->renderTurtle(turtle); + + turtleSync->release(); + verifyPointInsideFence(x, y); + } // else +} // TurtleSpace::setTurtleXY + + +void TurtleSpace::setTurtleWidth(double newWidth) throw (ExecException *) +{ + turtleSync->request(); + + if (turtle == NULL) + { + turtleSync->release(); + ExecException::_throw(TobyLanguage::NOCURTURTLE); + } // if + + if (newWidth != turtle->getWidth()) + { + bool isVis = turtle->getVisible(); + if (isVis == true) + renderer->blankTurtle(turtle); + + turtle->setWidth(newWidth); + + if (isVis == true) + renderer->renderTurtle(turtle); + } // if + + turtleSync->release(); +} // TurtleSpace::setTurtleWidth + + +void TurtleSpace::setTurtleHeight(double newHeight) throw (ExecException *) +{ + turtleSync->request(); + + if (turtle == NULL) + { + turtleSync->release(); + ExecException::_throw(TobyLanguage::NOCURTURTLE); + } // if + + if (newHeight != turtle->getHeight()) + { + bool isVis = turtle->getVisible(); + if (isVis == true) + renderer->blankTurtle(turtle); + + turtle->setHeight(newHeight); + + if (isVis == true) + renderer->renderTurtle(turtle); + } // if + + turtleSync->release(); +} // TurtleSpace::setTurtleHeight + + +void TurtleSpace::setTurtleVisibility(Turtle *t, bool isVis) + throw (ExecException *) +{ + if (isVis != t->getVisible()) + { + t->setVisible(isVis); + + if (isVis == true) + renderer->renderTurtle(t); + else + renderer->blankTurtle(t); + } // if +} // TurtleSpace::setTurtleVisibility + + +void TurtleSpace::setTurtleVisibility(bool isVis) throw (ExecException *) +{ + turtleSync->request(); + + if (turtle == NULL) + { + turtleSync->release(); + ExecException::_throw(TobyLanguage::NOCURTURTLE); + } // if + + setTurtleVisibility(turtle, isVis); + turtleSync->release(); +} // TurtleSpace::setTurtleVisible + + +void TurtleSpace::showTurtle(void) throw (ExecException *) +{ + setTurtleVisibility(true); +} // TurtleSpace::showTurtle + + +void TurtleSpace::showAllTurtles(void) throw (ExecException *) +{ + turtleSync->request(); + + for (int i = 0; i < turtlesArraySize; i++) + { + if (turtles[i] != NULL) + setTurtleVisibility(turtles[i], true); + } // for + + turtleSync->release(); +} // TurtleSpace::showAllTurtles + + +void TurtleSpace::hideTurtle(void) throw (ExecException *) +{ + setTurtleVisibility(false); +} // TurtleSpace::hideTurtle + + +void TurtleSpace::hideAllTurtles(void) throw (ExecException *) +{ + turtleSync->request(); + + for (int i = 0; i < turtlesArraySize; i++) + { + if (turtles[i] != NULL) + setTurtleVisibility(turtles[i], false); + } // for + + turtleSync->release(); +} // TurtleSpace::hideAllTurtles + + +void TurtleSpace::advanceTurtle(double distance) throw (ExecException *) +{ + if (distance == 0.0) + return; + + turtleSync->request(); + + if (turtle == NULL) + { + turtleSync->release(); + ExecException::_throw(TobyLanguage::NOCURTURTLE); + } // if + + double angle = turtle->getAngle(); + double turtleX = turtle->getX(); + double turtleY = turtle->getY(); + double x, y; + + TobyGeometry::calculateLine(angle, distance, turtleX, turtleY, &x, &y); + + bool isVis = turtle->getVisible(); + if (isVis == true) + renderer->blankTurtle(turtle); + + if (turtle->isPenDown()) // draw the line covering path turtle took? + { + float r, g, b, a; + turtle->getPenColor(&r, &g, &b, &a); + +// !!! needs to clamp lines to dimensions of TurtleSpace. + renderer->renderLine(turtleX, turtleY, x, y, r, b, g, a); + } // if + + turtle->setXY(x, y); + + if (isVis == true) + renderer->renderTurtle(turtle); + + turtleSync->release(); + + verifyPointInsideFence(x, y); +} // TurtleSpace::advanceTurtle + + +void TurtleSpace::setTurtleAngle(double angle) throw (ExecException *) +{ + turtleSync->request(); + + if (turtle == NULL) + { + turtleSync->release(); + ExecException::_throw(TobyLanguage::NOCURTURTLE); + } // if + + if (angle != turtle->getAngle()) + { + bool isVis = turtle->getVisible(); + if (isVis == true) + renderer->blankTurtle(turtle); + + turtle->setAngle(angle); + + if (isVis == true) + renderer->renderTurtle(turtle); + } // if + + turtleSync->release(); +} // TurtleSpace::setTurtleAngle + + +void TurtleSpace::rotateTurtle(double degree) throw (ExecException *) +{ + if (degree == 0.0) + return; + + turtleSync->request(); + + if (turtle == NULL) + { + turtleSync->release(); + ExecException::_throw(TobyLanguage::NOCURTURTLE); + } // if + + setTurtleAngle(turtle->getAngle() + degree); + + turtleSync->release(); +} // TurtleSpace::rotateTurtle + + +void TurtleSpace::homeTurtle(Turtle *t) throw (ExecException *) +{ + double x = renderer->getTurtleSpaceWidth() / 2; + double y = renderer->getTurtleSpaceHeight() / 2; + + turtleSync->request(); + + if ((x != t->getX()) || (y != t->getY())) + { + bool isVis = t->getVisible(); + if (isVis == true) + renderer->blankTurtle(t); + + t->setXY(x, y); + + if (isVis == true) + renderer->renderTurtle(t); + } // if + + turtleSync->release(); +} // TurtleSpace::homeTurtle + + +void TurtleSpace::homeTurtle(void) throw (ExecException *) +{ + // !!! This code is always the same... can we get this in a macro + // !!! or inline function? + turtleSync->request(); + + if (turtle == NULL) + { + turtleSync->release(); + ExecException::_throw(TobyLanguage::NOCURTURTLE); + } // if + + homeTurtle(turtle); + + turtleSync->release(); +} // TurtleSpace::homeTurtle + + +void TurtleSpace::homeAllTurtles(void) throw (ExecException *) +{ + turtleSync->request(); + + for (int i = 0; i < turtlesArraySize; i++) + { + if (turtles[i] != NULL) + homeTurtle(turtles[i]); + } // for + + turtleSync->release(); +} // TurtleSpace::homeAllTurtles + + +void TurtleSpace::defaultTurtle(Turtle *t) throw (ExecException *) +{ + assert(t != NULL); + + float r = getDefaultPenRed(); + float g = getDefaultPenGreen(); + float b = getDefaultPenBlue(); + float a = getDefaultPenAlpha(); + + clampColorValues(&r, &g, &b, &a); // better safe than sorry. + + bool isVis = t->getVisible(); + + if (t->getAngle() != dueNorth) + { + if (isVis == true) + { + renderer->blankTurtle(t); + isVis = false; + } // if + t->setAngle(dueNorth); + } // if + + t->setPenDown(true); + t->setPenColor(r, g, b, a); + + double x = renderer->getTurtleSpaceWidth() / 2; + double y = renderer->getTurtleSpaceHeight() / 2; + if ((t->getX() != x) || (t->getY() != y)) + { + if (isVis == true) + { + renderer->blankTurtle(t); + isVis = false; + } // if + t->setXY(x, y); + } // if + + t->setVisible(true); + if (isVis == false) + renderer->renderTurtle(t); +} // TurtleSpace::defaultTurtle + + +void TurtleSpace::defaultTurtle(void) throw (ExecException *) +{ + turtleSync->request(); + + if (turtle == NULL) + { + turtleSync->release(); + ExecException::_throw(TobyLanguage::NOCURTURTLE); + } // if + + defaultTurtle(turtle); + + turtleSync->release(); +} // TurtleSpace::defaultTurtle + + +void TurtleSpace::defaultAllTurtles(void) throw (ExecException *) +{ + turtleSync->request(); + + if (turtles != NULL) + { + for (int i = 0; i < turtlesArraySize; i++) + defaultTurtle(turtles[i]); + } // if + + turtleSync->release(); +} // TurtleSpace::defaultAllTurtles + + +void TurtleSpace::setPenColor(float r, float g, float b, float a) + throw (ExecException *) +{ + clampColorValues(&r, &g, &b, &a); + + turtleSync->request(); + + if (turtle == NULL) + { + turtleSync->release(); + ExecException::_throw(TobyLanguage::NOCURTURTLE); + } // if + + turtle->setPenColor(r, g, b, a); + + turtleSync->release(); +} // TurtleSpace::setPenColor + + +void TurtleSpace::setPen(bool drawing) throw (ExecException *) +{ + turtleSync->request(); + + if (turtle == NULL) + { + turtleSync->release(); + ExecException::_throw(TobyLanguage::NOCURTURTLE); + } // if + + turtle->setPenDown(drawing); + + turtleSync->release(); +} // TurtleSpace::setPen + + +void TurtleSpace::setPenUp(void) throw (ExecException *) +{ + setPen(false); +} // TurtleSpace::setPenUp + + +void TurtleSpace::setPenDown(void) throw (ExecException *) +{ + setPen(true); +} // TurtleSpace::setPenDown + + +void TurtleSpace::drawString(const char *str) throw (ExecException *) +{ + turtleSync->request(); + + if (turtle == NULL) + { + turtleSync->release(); + ExecException::_throw(TobyLanguage::NOCURTURTLE); + } // if + + float r, g, b, a; + double x = turtle->getX(); + double y = turtle->getY(); + double angle = turtle->getAngle(); + turtle->getPenColor(&r, &g, &b, &a); + + turtleSync->release(); + + renderer->renderString(x, y, angle, r, g, b, a, str); +} // TurtleSpace::renderString + + +void TurtleSpace::cleanup(void) throw (ExecException *) +{ + renderer->cleanup(); + + turtleSync->request(); + + for (int i = 0; i < turtlesArraySize; i++) + { + if (turtles[i]->getVisible()) + renderer->renderTurtle(turtles[i]); + } // for + + turtleSync->release(); +} // TurtleSpace::cleanup + + +// end of TurtleSpace.cpp ... + diff --git a/src/turtlespace/TurtleSpace.h b/src/turtlespace/TurtleSpace.h new file mode 100644 index 0000000..1b71497 --- /dev/null +++ b/src/turtlespace/TurtleSpace.h @@ -0,0 +1,128 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _INCLUDE_TURTLESPACE_H_ +#define _INCLUDE_TURTLESPACE_H_ + +#include "util/TobyObject.h" +#include "util/TobyLanguage.h" +#include "util/TobyMutex.h" +#include "util/TobyStack.h" +#include "util/TobyGeometry.h" +#include "turtlespace/Turtle.h" +#include "turtlespace/TurtleSpaceRenderer.h" + +/* + * This is TurtleSpace, the interpreted program's interface to the + * screen. This specific class has no physical representation; the actual + * widget/window/whatever is managed by an implementation of the + * TurtleSpaceRenderer class, which takes commands from this class and + * gets the bits to the screen. Besides being the abstract link between + * the renderer and the interpreted program, TurtleSpace handles Turtle + * maintenance and other TurtleGraphics-related state. + * + * Written by Ryan C. Gordon. (icculus@linuxgames.com) + */ +class TurtleSpace : public TobyObject +{ +public: + TurtleSpace(TurtleSpaceRenderer *_renderer); + virtual ~TurtleSpace(void); + + // Basic TurtleSpace information queries. + TurtleSpaceRenderer *getTurtleSpaceRenderer(void); + double getTurtleSpaceWidth(void); + double getTurtleSpaceHeight(void); + double getDueNorth(void); + void setDueNorth(double angle); + static float getDefaultPenRed(void) { return(1.0); } + static float getDefaultPenGreen(void) { return(1.0); } + static float getDefaultPenBlue(void) { return(1.0); } + static float getDefaultPenAlpha(void) { return(1.0); } + + // Turtle pool manipulation. + int getTurtleCount(void); + int addTurtle(void) throw (ExecException *); + bool removeTurtle(int turtleIndex) throw (ExecException *); + void removeAllTurtles(void) throw (ExecException *); + + // Rendering state-machine interface. + void grabTurtleSpace(void); + void releaseTurtleSpace(void); + + // Fence state-machine interface. + void enableFence(void) throw (ExecException *); + void disableFence(void) throw (ExecException *); + void setFence(bool buildFence) throw (ExecException *); + + // Turtle state-machine interface. + void useTurtle(int turtleIndex) throw (ExecException *); + double getTurtleX(void) throw (ExecException *); + double getTurtleY(void) throw (ExecException *); + double getTurtleWidth(void) throw (ExecException *); + double getTurtleHeight(void) throw (ExecException *); + void setTurtleX(double x) throw (ExecException *); + void setTurtleY(double y) throw (ExecException *); + void setTurtleXY(double x, double y) throw (ExecException *); + void setTurtleWidth(double newWidth) throw (ExecException *); + void setTurtleHeight(double newHeight) throw (ExecException *); + void setTurtleVisibility(bool isVis) throw (ExecException *); + void showTurtle(void) throw (ExecException *); + void showAllTurtles(void) throw (ExecException *); + void hideTurtle(void) throw (ExecException *); + void hideAllTurtles(void) throw (ExecException *); + void advanceTurtle(double distance) throw (ExecException *); + void setTurtleAngle(double angle) throw (ExecException *); + void rotateTurtle(double degree) throw (ExecException *); + void homeTurtle(void) throw (ExecException *); + void homeAllTurtles(void) throw (ExecException *); + void defaultTurtle(void) throw (ExecException *); + void defaultAllTurtles(void) throw (ExecException *); + void setPenColor(float r, float g, float b, float a) throw (ExecException *); + void setPen(bool drawing) throw (ExecException *); + void setPenUp(void) throw (ExecException *); + void setPenDown(void) throw (ExecException *); + + // miscellaneous rendering stuff. + void drawString(const char *str) throw (ExecException *); + void cleanup(void) throw (ExecException *); + +protected: + Turtle *getTurtleByIndex(int turtleIndex); + Turtle *buildNewTurtle(void) throw (ExecException *); + void homeTurtle(Turtle *t) throw (ExecException *); + void defaultTurtle(Turtle *t) throw (ExecException *); + void verifyPointInsideFence(double x, double y) throw (ExecException *); + void setTurtleVisibility(Turtle *t, bool isVis) throw (ExecException *); + +private: + double dueNorth; + Turtle **turtles; + int turtlesArraySize; + TobyStack *turtlePool; + bool fenceEnabled; + Turtle *turtle; + TurtleSpaceRenderer *renderer; + TobyMutex *turtleSync; +}; // class TurtleSpace + +#endif // !defined _INCLUDE_TURTLESPACE_H_ + +// end of TurtleSpace.h ... + diff --git a/src/turtlespace/TurtleSpaceRenderer.h b/src/turtlespace/TurtleSpaceRenderer.h new file mode 100644 index 0000000..52f6c2c --- /dev/null +++ b/src/turtlespace/TurtleSpaceRenderer.h @@ -0,0 +1,117 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _INCLUDE_TURTLESPACERENDERER_H_ +#define _INCLUDE_TURTLESPACERENDERER_H_ + +#include "util/TobyObject.h" +#include "exceptions/ExecException.h" +#include "turtlespace/Turtle.h" + +/* + * The TurtleSpaceRenderer interface. This is a pure virtual class, so + * you'll need to implement it for your given platform. This class has the + * physical representation of TurtleSpace, and gets the bits to the screen. + * + * Examples of subclasses would be a Qt implementation, an SDL + * implementation, a Win32 implementation, etc. + * + * Written by Ryan C. Gordon. (icculus@linuxgames.com) + */ +class TurtleSpaceRenderer : public TobyObject +{ +public: + TurtleSpaceRenderer(void) {} + virtual ~TurtleSpaceRenderer(void) {} + + // Create a screen surface: windows should be created, or resolutions + // should be changed in this method. If the screen surface can not + // be created to satisfaction, this should return (false). If the + // screen initialization was successful, this should return (true). + // Note that this method may be called multiple times during the + // existance of the object, whether previous calls failed or not. + // If there is a resize call after/during rendering (even while + // TurtleSpace is "grabbed"), then the renderer should strive to + // maintain the currently rendered image in the new size. + virtual bool resize(int w, int h) = 0; + + // These notification methods are called when TurtleSpace rendering + // begins and ends, presumably at program interpretation start and + // finish. This is for your renderer's informational purposes only, + // and you aren't required to do anything at all in these methods. + virtual void notifyGrabbed(void) = 0; + virtual void notifyUngrabbed(void) = 0; + + // Get the dimensions of the current screen surface in pixels. + virtual double getTurtleSpaceWidth(void) = 0; + virtual double getTurtleSpaceHeight(void) = 0; + + // Get the preferred default dimensions for a turtle in pixels, which + // may or may not be ignored completely. Note the turtle may also be + // arbitrarily resized during program interpretation. + virtual double getDesiredTurtleWidth(void) = 0; + virtual double getDesiredTurtleHeight(void) = 0; + + // Render a text string to the screen, starting at coordinate (x), (y), + // and tilted at (angle), where 270.0 is due north. The color + // channels, (r), (b), (g), and (a), are the red, blue, green, and + // alpha, are specified in a range of 0.0 (no intensity on that + // channel) to 1.0 (full intensity on that channel). (str) is, of + // course, the string to render. Extra credit for antialiasing. + virtual void renderString(double x, double y, double angle, + float r, float b, float g, float a, + const char *str) = 0; + + + // Render a line segment between 2 points, in the specified color. + // The color values will be clamped between 0.0 and 1.0, and the + // line coordinates will be clamped to be inside the dimensions of + // TurtleSpace. + virtual void renderLine(double x1, double y1, double x2, double y2, + float r, float b, float g, float a) = 0; + + // These need to be replaced by !!! + virtual void renderTurtle(Turtle *turtle) throw (ExecException) = 0; + virtual void blankTurtle(Turtle *turtle) throw (ExecException) = 0; + + // Blank TurtleSpace to full alpha, and zero red, green, and blue. + // Turtles that need rerendering will be handled by calls to + // the renderTurtle() method after this call. + virtual void cleanup(void) throw (ExecException) = 0; +}; // class TurtleSpaceRenderer + + + // This gets filled in along with the platform-specific subclass. + // It should be a standalone TurtleSpace, or return NULL if it can't. + // For example, a GTK+ widget-based TurtleSpace should build a GtkWindow + // around it so that it needs nothing else to display. Width and height + // are specified in pixels. +TurtleSpaceRenderer *__platformBuildStandaloneRenderer(char *winTitle, + int *argc, char ***argv); + + // This gets called to give you a chance to run a toolkit-specific + // event queue or other idle-time upkeep you may need. If a quit event + // or some other reason to abort the program arises, return false, + // otherwise, return true. +bool __platformRendererDoEvents(void); + +#endif // !defined _INCLUDE_TURTLESPACERENDERER_H_ + +// end of TurtleSpaceRenderer.h ... + diff --git a/src/util/TobyCollection.cpp b/src/util/TobyCollection.cpp new file mode 100644 index 0000000..2096ee0 --- /dev/null +++ b/src/util/TobyCollection.cpp @@ -0,0 +1,126 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "util/TobyCollection.h" + + +TobyCollection::TobyCollection(void) : list(NULL) +{ +} // Constructor + + +TobyCollection::~TobyCollection(void) +{ + TobyLinkedList *next = NULL; + + while (list != NULL) + { + next = list->next; + delete list; + list = next; + } // while +} // Destructor + + +void TobyCollection::insertElement(TobyObject *elem, int pos) +{ + int count = 0; + + for (TobyLinkedList *i = list; i != NULL; i = i->next) + { + if (count == pos) + { + TobyLinkedList *node = new TobyLinkedList; + assert(node != NULL); + + node->obj = elem; + node->next = i; + node->prev = i->prev; + i->prev = node; + if (node->prev != NULL) + node->prev->next = node; + + return; + } // if + + count++; + } // for +} // TobyCollection::insertElement + + +TobyObject *TobyCollection::elementAt(int pos) +{ + int count = 0; + + for (TobyLinkedList *i = list; i != NULL; i = i->next) + { + if (count == pos) + return(i->obj); + + count++; + } // for + + return(NULL); +} // TobyCollection::insertElement + + +TobyObject *TobyCollection::remove(int pos) +{ + int count = 0; + + for (TobyLinkedList *i = list; i != NULL; i = i->next) + { + if (count == pos) + { + TobyObject *retval = i->obj; + if (i->prev != NULL) + i->prev->next = i->next; + + if (i->next != NULL) + i->next->prev = i->prev; + + delete i; + return(retval); + } // if + count++; + } // for + + return(NULL); +} // TobyCollection::remove + + +bool TobyCollection::isEmpty(void) +{ + return(list == NULL); +} // TobyCollection::isEmpty + + +int TobyCollection::size(void) +{ + // O(n), not O(1). + int retval = 0; + + for (TobyLinkedList *i = list; i != NULL; i = i->next) + retval++; + + return(retval); +} // TobyCollection::size + +// end of TobyCollection.cpp ... + diff --git a/src/util/TobyCollection.h b/src/util/TobyCollection.h new file mode 100644 index 0000000..8b7924b --- /dev/null +++ b/src/util/TobyCollection.h @@ -0,0 +1,57 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _INCLUDE_TOBYCOLLECTION_H_ +#define _INCLUDE_TOBYCOLLECTION_H_ + +#include "util/TobyObject.h" + +/* + * This is a base class for linear collections: lists, stacks, etc. + * + * Written by Ryan C. Gordon. (icculus@linuxgames.com) + */ + +// internally, this is just a linked list. +typedef struct TobyLinkedListStruct +{ + TobyObject *obj; + struct TobyLinkedListStruct *prev; + struct TobyLinkedListStruct *next; +} TobyLinkedList; + +class TobyCollection : public TobyObject +{ +public: + TobyCollection(void); + virtual ~TobyCollection(void); + virtual void insertElement(TobyObject *elem, int pos); + virtual TobyObject *elementAt(int pos); + virtual TobyObject *remove(int pos); + virtual bool isEmpty(void); + virtual int size(void); + +protected: + TobyLinkedList *list; +}; // class TobyCollection + +#endif // !defined _INCLUDE_TOBYCOLLECTION_H_ + +// end of TobyCollection.h ... + diff --git a/src/util/TobyGeometry.h b/src/util/TobyGeometry.h new file mode 100644 index 0000000..8283565 --- /dev/null +++ b/src/util/TobyGeometry.h @@ -0,0 +1,134 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _INCLUDE_TOBYGEOMETRY_H_ +#define _INCLUDE_TOBYGEOMETRY_H_ + +#include +#include "util/TobyObject.h" + + +/* + * Some needed math routines. + * + * Written by Ryan C. Gordon. (icculus@linuxgames.com) + */ +class TobyGeometry +{ +public: + static inline double degreesToRadians(double degrees) + { + return(degrees * (M_PI / 180.0)); + } // TobyGeometry::degreesToRadians + + + static inline double radiansToDegrees(double radians) + { + return(radians * (180.0 / M_PI)); + } // TobyGeometry::degreesToRadians + + + static inline int roundDoubleToInt(double dbl) + { + return((int) (dbl + 0.5)); + } // TobyGeometry::roundDoubleToInt + + + static inline void calculateLine(double heading, double distance, + double startX, double startY, + double *endX, double *endY) + /* + * This procedure calculates coordinates for a line. No line is actually + * drawn by this procedure, though. + * + * params : heading == 0 - 360 degree direction line goes. + * distance == total space line should cover. + * startX == Starting x coordinate for line. + * startY == Starting y coordinate for line. + * *endX == filled with end point on X-axis. + * *endY == filled with end point on Y-axis. + * returns : void. Data is return in (endX) and (endY). + */ + { + assert(endX != NULL); + assert(endY != NULL); + + double rad = degreesToRadians(heading); + *endX = (cos(rad) * (double) distance) + startX; + *endY = (sin(rad) * (double) distance) + startY; + } // TobyGeometry::calculateLine + + /* + * This converts a float in the range of 0.0 to 1.0 to an 8-bit integer. + * A value of 0.0 (zero percent) yields a return of 0. A value of 1.0 + * (one hundred percent) yields a return of 255. Everything else is + * somewhere inbetween. Values not in the range of 0.0 to 1.0 are clamped + * before conversion. + */ + static inline toby_uint8 floatTo8Bit(float val) + { + if (val > 1.0) + val = 1.0; + else if (val < 0.0) + val = 0.0; + + return((toby_uint8) (val * 255.0)); + } // TobyGeometry::floatTo8Bit + + + static inline double pythagorian(double s1, double hypotenuse) + /* + * The Pythagorian Theorem: Figure out the length of the third side + * of a right triangle, based on the lengths of the other two. + * + * The formula is like this: The sum of the squares of the lengths of + * the two non-hypotenuse sides of a right triangle will equal the + * square of the hypotenuse. So, if we know two sides of a right + * triangle, we can get the third. (In this function, you need to know + * which is the hypotenuse, but you can easily write a version of + * this that figures out the hypotenuse based on the other two sides. + * + * To find a non-hypotenuse side: + * (H2 represents hypotenuse, squared.) + * (X2 represents 1st non-hypotenuse side, squared.) + * (Y2 represents 2nd non-hypotenuse side, squared.) + * + * H2 = X2 + Y2 + * H2 - X2 = Y2 + X2 - X2 + * H2 - X2 = Y2 + * H2 - H2 - X2 = Y2 - H2 + * -X2 = Y2 - H2 + * X2 = - Y2 + H2 + * X2 = H2 - Y2 + * + * params : s1 == length of known non-hypotenuse side of rt. triangle. + * hypotenuse == length of hypotenuse of right triangle. + * returns : length of third side of right triangle. + */ + { + return(sqrt((hypotenuse * hypotenuse) - (s1 * s1))); + } // TobyGeometry::pythagorian + +}; // class TobyGeometry + +#endif // !defined _INCLUDE_TOBYGEOMETRY_H_ + +// end of TobyGeometry.h ... + + diff --git a/src/util/TobyLanguage.cpp b/src/util/TobyLanguage.cpp new file mode 100644 index 0000000..74bed32 --- /dev/null +++ b/src/util/TobyLanguage.cpp @@ -0,0 +1,171 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "util/TobyLanguage.h" + + + // Do NOT translate the strings in here! + // The program will default to English (using the below strings) + // if it doesn't load langfiles to use a different language. + // Translations should be done from a separate langfile. + +char *TobyLanguage::NAME = "Toby"; + +char *TobyLanguage::USAGE = "USAGE: Toby.class [--langfile=xxx] [sourceFile.toby]"; + +char *TobyLanguage::TRANSLATION_BY = + "English language text by Ryan C. Gordon."; + +char *TobyLanguage::WRITTENBY = "Written by Ryan C. Gordon."; +char *TobyLanguage::COPYRIGHT = "Copyright (C) 1999 Ryan C. Gordon"; + +char *TobyLanguage::ERROR = "Error"; +char *TobyLanguage::NOT_YET_IMPLEMENTED = "Feature not yet implemented."; +char *TobyLanguage::NODETREE_LOCKED = "NodeTree already locked."; +char *TobyLanguage::NODETREE_ULOCKED = "NodeTree already unlocked."; +char *TobyLanguage::BAD_CHILD_NODE = "Adding bad child type to NodeTree"; +char *TobyLanguage::USING_FREE_NODE = "Attempt to use NodeTree" + " that has already called" + " freeResources()!"; + +char *TobyLanguage::NEW_PROGRAM = "new program"; +char *TobyLanguage::PLEASE_CONFIRM = "Whoa!"; +char *TobyLanguage::SAVE_MODIFIED_PROG = "Save modified program?"; +char *TobyLanguage::FILE_NOT_FOUND = "File \"%0\" not found."; +char *TobyLanguage::CANNOT_LOAD_FILE = "Cannot load file \"%0\"."; +char *TobyLanguage::FILE_EXISTS = "File exists"; +char *TobyLanguage::OVERWRITE_FILENAME = "Overwrite \"%0\"?"; +char *TobyLanguage::CANNOT_WRITE_TO = "Cannot write to \"%0\"."; + +char *TobyLanguage::TOOMANYFILES = "More than one file specified on" + " commandline! Just using the first one."; + +char *TobyLanguage::REPLACE_FORMAT_ERR = + "Format string contains no \"%\" sequence!"; +char *TobyLanguage::REPLACE_RANGE_ERR = + "Replace index must be between (0) and (9)."; + +char *TobyLanguage::NO_GUI1 = "There was an error while starting the" + " graphics engine..."; +char *TobyLanguage::NO_GUI2 = " Chances are, you don't have the GUI support" + " you need. Please start"; +char *TobyLanguage::NO_GUI3 = " your Window system before running" + " this program."; + +char *TobyLanguage::HERES_THE_ERR = "For record, here's the error:"; + +char *TobyLanguage::TOBY_FILE_DESCRIPTION = "TOBY source code"; + +char *TobyLanguage::CARET_POSITION = "line %0, column %1"; + +char *TobyLanguage::ERR_IN_FUNC = "%0 on line %1 in function %2"; +char *TobyLanguage::ERR_OUT_FUNC = "%0 on line %1"; + +char *TobyLanguage::SHOULDNOTBE = "This should not happen." + " Email icculus@linuxgames.com!" + " (English only!)"; + + // Menuitems... +char *TobyLanguage::MENUNAME_FILE = "File"; +char *TobyLanguage::MENUITEM_NEW = "New"; +char *TobyLanguage::MENUITEM_OPEN = "Open..."; +char *TobyLanguage::MENUITEM_SAVE = "Save"; +char *TobyLanguage::MENUITEM_SAVEAS = "Save as..."; +char *TobyLanguage::MENUITEM_PRINT = "Print..."; +char *TobyLanguage::MENUITEM_QUIT = "Quit"; + +char *TobyLanguage::MENUNAME_HELP = "Help"; +char *TobyLanguage::MENUITEM_HELP = "Help..."; +char *TobyLanguage::MENUITEM_ABOUT = "About..."; + +char *TobyLanguage::MENUNAME_RUN = "Run"; +char *TobyLanguage::MENUITEM_STARTCODE = "Start program"; +char *TobyLanguage::MENUITEM_STOPCODE = "Stop program"; +char *TobyLanguage::MENUITEM_CLEAR = "Cleanup TurtleSpace"; + +char *TobyLanguage::MENUNAME_DEBUG = "Debug"; +char *TobyLanguage::MENUITEM_TRACE = "Trace"; +char *TobyLanguage::MENUITEM_STEP = "Step"; +char *TobyLanguage::MENUITEM_WATCHVARS = "Watch variables"; + + + // Constants representing error messages... +char *TobyLanguage::INTERNAL_ERROR = "Internal error"; +char *TobyLanguage::EXPECTED_TOKEN = "Expected token"; +char *TobyLanguage::SYNTAX_ERROR = "Syntax error"; +char *TobyLanguage::BAD_ASSIGNMENT = "Assignment not allowed"; +char *TobyLanguage::DOUBLE_DEF = "Duplicate definition"; +char *TobyLanguage::ORPHAN_CODE = "Code outside function"; +char *TobyLanguage::BAD_TYPE = "Bad variable type"; +char *TobyLanguage::NOT_VAR = "Expected variable"; +char *TobyLanguage::NO_MAINLINE = "Expected mainline"; +char *TobyLanguage::NO_RPAREN = "Expected \")\""; +char *TobyLanguage::NO_LPAREN = "Expected \"(\""; +char *TobyLanguage::NO_ASSIGN = "Expected \"=\""; +char *TobyLanguage::NOT_A_FUNC = "Undefined function"; +char *TobyLanguage::BADNUM_ARGS = "Wrong arguments"; +char *TobyLanguage::BAD_IDENT = "Invalid identifier"; +char *TobyLanguage::NO_ENDFOR = "FOR without ENDFOR"; +char *TobyLanguage::NO_FOR = "ENDFOR without FOR"; +char *TobyLanguage::NO_ENDWHILE = "WHILE without ENDWHILE"; +char *TobyLanguage::NO_WHILE = "ENDWHILE without WHILE"; +char *TobyLanguage::ORPHAN_ELIF = "ELSEIF without IF"; +char *TobyLanguage::ORPHAN_ELSE = "ELSE without IF"; +char *TobyLanguage::ORPHAN_ENDIF = "ENDIF without IF"; +char *TobyLanguage::TYPE_MMATCH = "Type mismatch"; +char *TobyLanguage::BAD_ARGUMENT = "Invalid argument"; +char *TobyLanguage::MAIN_RETVAL = "MAIN returns a value"; +char *TobyLanguage::BAD_GLOBAL = "Expected variable or FUNCTION"; +char *TobyLanguage::EXPECTED_END = "Expected ENDFUNCTION"; +char *TobyLanguage::NO_RETTYPE = "Expected RETURNS"; +char *TobyLanguage::ELIF_AFTER_ELSE = "ELSEIF after ELSE"; +char *TobyLanguage::ELSE_AFTER_ELSE = "Multiple ELSE statements"; +char *TobyLanguage::NO_VAR_DECL = "Can't declare variables here"; +char *TobyLanguage::FUNC_IN_FUNC = "FUNCTION within function"; +char *TobyLanguage::DIV_BY_ZERO = "Division by zero"; +char *TobyLanguage::NOCURTURTLE = "No current turtle"; +char *TobyLanguage::TURTLE_FENCED = "Turtle past fence"; +char *TobyLanguage::OUT_OF_RANGE = "Out of range"; +char *TobyLanguage::OVERFLOW = "Overflow"; +char *TobyLanguage::NOT_AN_ARRAY = "Expected array"; +char *TobyLanguage::NO_RARRAY = "Expected \"]\""; +char *TobyLanguage::NO_LARRAY = "Expected \"[\""; +char *TobyLanguage::NOT_WHOLE_NUM = "Expected whole number"; + +char *TobyLanguage::LANGIOEXCEPT = "LANGUAGE: IOException reading" + " language data."; +char *TobyLanguage::LANGBOGUSLINE = "LANGUAGE: Line %0 is bogus in %1."; +char *TobyLanguage::LANGNOSUCHCLASS = "LANGUAGE: No such class [%0] on" + " line %1 in %2."; +char *TobyLanguage::LANGNOSUCHFIELD = "LANGUAGE: No such field [%0] on" + " line %1 in %2."; +char *TobyLanguage::LANGNOTPUBLIC = "LANGUAGE: Field [%0] is not" + " on line %1 in %2."; +char *TobyLanguage::LANGNOTSTATIC = "LANGUAGE: Field [%0] is not" + " on line %1 in %2."; +char *TobyLanguage::LANGNOTSTRING = "LANGUAGE: Field [%0] is not" + " a string on line %1 in %2."; +char *TobyLanguage::LANGISFINAL = "LANGUAGE: Field [%0] is final" + " on line %1 in %2."; +char *TobyLanguage::LANGSETFAILED = "LANGUAGE: Setting field [%0] " + " failed with message [%1]" + " on line %2 in %3."; + +// end of TobyLanguage.cpp ... + diff --git a/src/util/TobyLanguage.h b/src/util/TobyLanguage.h new file mode 100644 index 0000000..2b7a450 --- /dev/null +++ b/src/util/TobyLanguage.h @@ -0,0 +1,335 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _INCLUDE_TOBYLANGUAGE_H_ +#define _INCLUDE_TOBYLANGUAGE_H_ + +#include "util/TobyObject.h" + +/* + * This class contains all the literal strings used throughout Toby. + * By keeping these all in one place, it becomes trivial to change + * not only individual text within the program, but also the entire + * language. + * + * To use a different language than English, just specify + * --langfile=/path/langfile or --langfile=url://hostname/path/langfile + * on the command line. + * + * Written by Ryan C. Gordon. (icculus@linuxgames.com) + */ +class TobyLanguage +{ +private: + TobyLanguage(void) {} // prevent public construction. + +public: + static char *NAME; + static char *USAGE; + static char *TRANSLATION_BY; + static char *WRITTENBY; + static char *COPYRIGHT; + static char *ERROR; + static char *NOT_YET_IMPLEMENTED; + static char *NODETREE_LOCKED; + static char *NODETREE_ULOCKED; + static char *BAD_CHILD_NODE; + static char *USING_FREE_NODE; + static char *NEW_PROGRAM; + static char *PLEASE_CONFIRM; + static char *SAVE_MODIFIED_PROG; + static char *FILE_NOT_FOUND; + static char *CANNOT_LOAD_FILE; + static char *FILE_EXISTS; + static char *OVERWRITE_FILENAME; + static char *CANNOT_WRITE_TO; + static char *TOOMANYFILES; + static char *REPLACE_FORMAT_ERR; + static char *REPLACE_RANGE_ERR; + static char *NO_GUI1; + static char *NO_GUI2; + static char *NO_GUI3; + static char *HERES_THE_ERR; + static char *TOBY_FILE_DESCRIPTION; + static char *CARET_POSITION; + static char *ERR_IN_FUNC; + static char *ERR_OUT_FUNC; + static char *SHOULDNOTBE; + static char *MENUNAME_FILE; + static char *MENUITEM_NEW; + static char *MENUITEM_OPEN; + static char *MENUITEM_SAVE; + static char *MENUITEM_SAVEAS; + static char *MENUITEM_PRINT; + static char *MENUITEM_QUIT; + static char *MENUNAME_HELP; + static char *MENUITEM_HELP; + static char *MENUITEM_ABOUT; + static char *MENUNAME_RUN; + static char *MENUITEM_STARTCODE; + static char *MENUITEM_STOPCODE; + static char *MENUITEM_CLEAR; + static char *MENUNAME_DEBUG; + static char *MENUITEM_TRACE; + static char *MENUITEM_STEP; + static char *MENUITEM_WATCHVARS; + static char *INTERNAL_ERROR; + static char *EXPECTED_TOKEN; + static char *SYNTAX_ERROR; + static char *BAD_ASSIGNMENT; + static char *DOUBLE_DEF; + static char *ORPHAN_CODE; + static char *BAD_TYPE; + static char *NOT_VAR; + static char *NO_MAINLINE; + static char *NO_RPAREN; + static char *NO_LPAREN; + static char *NO_ASSIGN; + static char *NOT_A_FUNC; + static char *BADNUM_ARGS; + static char *BAD_IDENT; + static char *NO_ENDFOR; + static char *NO_FOR; + static char *NO_ENDWHILE; + static char *NO_WHILE; + static char *ORPHAN_ELIF; + static char *ORPHAN_ELSE; + static char *ORPHAN_ENDIF; + static char *TYPE_MMATCH; + static char *BAD_ARGUMENT; + static char *MAIN_RETVAL; + static char *BAD_GLOBAL; + static char *EXPECTED_END; + static char *NO_RETTYPE; + static char *ELIF_AFTER_ELSE; + static char *ELSE_AFTER_ELSE; + static char *NO_VAR_DECL; + static char *FUNC_IN_FUNC; + static char *DIV_BY_ZERO; + static char *NOCURTURTLE; + static char *TURTLE_FENCED; + static char *OUT_OF_RANGE; + static char *OVERFLOW; + static char *NOT_AN_ARRAY; + static char *NO_RARRAY; + static char *NO_LARRAY; + static char *NOT_WHOLE_NUM; + static char *LANGIOEXCEPT; + static char *LANGBOGUSLINE; + static char *LANGNOSUCHCLASS; + static char *LANGNOSUCHFIELD; + static char *LANGNOTPUBLIC; + static char *LANGNOTSTATIC; + static char *LANGNOTSTRING; + static char *LANGISFINAL; + static char *LANGSETFAILED; + + +#if 0 +// !!! PUT THIS BACK IN! + + /* + * Read a string from a langfile. This will read until a non-blank + * line that isn't a comment is found. + * + * params: ir == InputReader that is reading a langfile. + * returns: char *in a given language. + * @exception IOException on i/o errors. + */ + static String readLangString(InputReader ir) throw (IOException) + { + String retVal = null; + + do + { + retVal = br.readLine(); + + if (retVal == null) + return(null); + + retVal = retVal.trim(); + if ((retVal.length() > 0) && (retVal.charAt(0) != '#')) + return(retVal); + + } while (true); + } // readLangString + + + static Class retrieveLangClass(String cName, int line, String file) + { + Class retVal = null; + try + { + retVal = Class.forName(cName); + } // try + catch (ClassNotFoundException cnfe) + { + String s = TobyLanguage.LANGNOSUCHCLASS; + s = replaceFmtTokenInStr(0, s, cName); + s = replaceFmtTokenInStr(1, s, line); + s = replaceFmtTokenInStr(2, s, file); + System.err.println(s); + } // catch + + return(retVal); + } // retrieveLangClass + + + static Field retrieveLangField(Class c, String fName, + int line, String file) + { + Field retVal = null; + + try + { + retVal = c.getField(fName); + } // try + catch (NoSuchFieldException nsfe) + { + String s = TobyLanguage.LANGNOSUCHFIELD; + s = replaceFmtTokenInStr(0, s, fName); + s = replaceFmtTokenInStr(1, s, line); + s = replaceFmtTokenInStr(2, s, file); + System.err.println(s); + return(null); + } // catch + + int mods = retVal.getModifiers(); + + if (java.lang.reflect.Modifier.isPublic(mods) == false) + { + String s = TobyLanguage.LANGNOTPUBLIC; + s = replaceFmtTokenInStr(0, s, fName); + s = replaceFmtTokenInStr(1, s, line); + s = replaceFmtTokenInStr(2, s, file); + System.err.println(s); + return(null); + } // if + + else if (java.lang.reflect.Modifier.isStatic(mods) == false) + { + String s = TobyLanguage.LANGNOTSTATIC; + s = replaceFmtTokenInStr(0, s, fName); + s = replaceFmtTokenInStr(1, s, line); + s = replaceFmtTokenInStr(2, s, file); + System.err.println(s); + return(null); + } // else if + + else if (java.lang.reflect.Modifier.isFinal(mods) == true) + { + String s = TobyLanguage.LANGISFINAL; + s = replaceFmtTokenInStr(0, s, fName); + s = replaceFmtTokenInStr(1, s, line); + s = replaceFmtTokenInStr(2, s, file); + System.err.println(s); + return(null); + } // else if + + else if (retVal.getType().getName().equals("java.lang.String") == false) + { + String s = TobyLanguage.LANGNOTSTRING; + s = replaceFmtTokenInStr(0, s, fName); + s = replaceFmtTokenInStr(1, s, line); + s = replaceFmtTokenInStr(2, s, file); + System.err.println(s); + return(null); + } // else if + + return(retVal); + } // retrieveLangField + + + static boolean setLangField(String cName, String fName, String val, + int line, String file) + { + Class c = retrieveLangClass(cName, line, file); + if (c == null) + return(false); + + Field f = retrieveLangField(c, fName, line, file); + if (f == null) + return(false); + + try + { + f.set(null, val); + } // try + catch (Exception e) + { + String s = TobyLanguage.LANGSETFAILED; + s = replaceFmtTokenInStr(0, s, fName); + s = replaceFmtTokenInStr(1, s, e.getMessage()); + s = replaceFmtTokenInStr(2, s, line); + s = replaceFmtTokenInStr(3, s, file); + System.err.println(s); + return(false); + } // catch + + return(true); + } // setLangField + + + static void reportBogusLangLine(int lineNum, String fname) + { + String s = TobyLanguage.LANGBOGUSLINE; + s = replaceFmtTokenInStr(0, s, lineNum); + s = replaceFmtTokenInStr(1, s, fname); + System.err.println(s); + } // reportBogusLangLine + + + static void loadLangFile(LineNumberReader lnr, String file) throws IOException + { + String langString = null; + + while ( (langString = readLangString(lnr)) != null ) + { + int pos = langString.indexOf('='); + int line = lnr.getLineNumber(); + if (pos == -1) + { + reportBogusLangLine(line, file); + continue; + } // if + + String fullName = langString.substring(0, pos).trim(); + String value = langString.substring(pos + 1).trim(); + + pos = fullName.lastIndexOf('.'); + if (pos == -1) + { + reportBogusLangLine(line, file); + continue; + } // if + + String className = fullName.substring(0, pos); + String fieldName = fullName.substring(pos + 1); + + setLangField(className, fieldName, value, line, file); + } // while + } // loadLangFile +#endif + +}; // class TobyLanguage + +#endif // !defined _INCLUDE_TOBYLANGUAGE_H_ + +// end of TobyLanguage.h ... + diff --git a/src/util/TobyMutex.h b/src/util/TobyMutex.h new file mode 100644 index 0000000..e3fd78f --- /dev/null +++ b/src/util/TobyMutex.h @@ -0,0 +1,46 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _INCLUDE_TOBYMUTEX_H_ +#define _INCLUDE_TOBYMUTEX_H_ + +#include "util/TobyObject.h" + +/* + * An abstraction over platform-specific threading mutexes. + * + * Written by Ryan C. Gordon. (icculus@linuxgames.com) + */ +class TobyMutex : public TobyObject +{ +public: + TobyMutex(void) {} + virtual ~TobyMutex(void) {} + virtual void request(void) = 0; + virtual void release(void) = 0; +}; // class TobyMutex + + +// This gets filled in along with the platform-specific subclass... +TobyMutex *__platformBuildMutex(void); + +#endif // !defined _INCLUDE_TOBYMUTEX_H_ + +// end of TobyMutex.h ... + diff --git a/src/util/TobyObject.h b/src/util/TobyObject.h new file mode 100644 index 0000000..a277219 --- /dev/null +++ b/src/util/TobyObject.h @@ -0,0 +1,58 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _INCLUDE_TOBYOBJECT_H_ +#define _INCLUDE_TOBYOBJECT_H_ + +#include // ...gotta have my printf. :) +#include // make sure NULL is always defined. +#include // make sure assert() is always defined. + +// !!! This needs to change. +typedef signed long toby_sint32; +typedef unsigned long toby_uint32; +typedef signed short toby_sint16; +typedef unsigned short toby_uint16; +typedef signed char toby_sint8; +typedef unsigned char toby_uint8; + + +#if (defined DEBUG) +#define _D(x) printf x; +#else +#define _D(x) +#endif + + +/* + * This is a common base class for all other Toby class. + * + * Written by Ryan C. Gordon. (icculus@linuxgames.com) + */ +class TobyObject +{ + + // !!! assert(0) in the copy constructor. + +}; // class TobyObject + +#endif // !defined _INCLUDE_TOBYOBJECT_H_ + +// end of TobyObject.h ... + diff --git a/src/util/TobyStack.cpp b/src/util/TobyStack.cpp new file mode 100644 index 0000000..5f90b11 --- /dev/null +++ b/src/util/TobyStack.cpp @@ -0,0 +1,35 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "util/TobyStack.h" + +void TobyStack::push(TobyObject *elem) +{ + insertElement(elem, 0); +} // TobyStack::push + + +TobyObject *TobyStack::pop(void) +{ + return(remove(0)); +} // TobyStack::pop + +// end of TobyStack.cpp ... + + diff --git a/src/util/TobyStack.h b/src/util/TobyStack.h new file mode 100644 index 0000000..16c5422 --- /dev/null +++ b/src/util/TobyStack.h @@ -0,0 +1,42 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _INCLUDE_TOBYSTACK_H_ +#define _INCLUDE_TOBYSTACK_H_ + +#include "util/TobyCollection.h" + +/* + * This is a general object stack. First in, last out. + * + * Written by Ryan C. Gordon. (icculus@linuxgames.com) + */ +class TobyStack : public TobyCollection +{ +public: +// TobyStack(void); +// virtual ~TobyStack(void); + virtual void push(TobyObject *elem); + virtual TobyObject *pop(void); +}; // class TobyStack + +#endif // !defined _INCLUDE_TOBYSTACK_H_ + +// end of TobyStack.h ... + diff --git a/src/util/TobyString.cpp b/src/util/TobyString.cpp new file mode 100644 index 0000000..b9e9be3 --- /dev/null +++ b/src/util/TobyString.cpp @@ -0,0 +1,98 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "util/TobyString.h" + +TobyString::TobyString(void) : str(NULL) +{ + assignCStr(""); +} // Constructor + +TobyString::TobyString(const char *_str) : str(NULL) +{ + assignCStr(""); +} // Constructor + +TobyString::TobyString(const TobyString *_str) : str(NULL) +{ + assignCStr(_str->c_str()); +} // Constructor + +TobyString::~TobyString(void) +{ + if (str != NULL) + free(str); +} // Destructor + +const char *TobyString::c_str(void) const +{ + return(str); // READ. ONLY. +} // TobyString::c_str + +#if 0 +// !!! +char *TobyString::operator char *(void) +{ + return((const char *) str); +} // TobyString::operator char * +#endif + +void TobyString::assignCStr(const char *_str) +{ + if (_str == NULL) + _str = ""; + + str = (char *) realloc(str, strlen(_str) + 1); + strcpy(str, _str); +} // assignCStr + + +bool TobyString::replaceFormatToken(int n, const char *val) +{ + assert(val != NULL); + assert((n >= 0) && (n <= 9)); + + char token[3] = {'%', '0' + n, '\0'}; + char *ptr; + + ptr = strstr(str, token); + if (ptr == NULL) + return(false); + + char *buf = new char[strlen(str) + strlen(val) + 1]; + *ptr = '\0'; // chop string at "%n". + strcpy(buf, str); + strcat(buf, val); + strcat(buf, ptr + 2); + assignCStr(buf); + delete[] buf; + + return(true); +} // TobyString::replaceFormatToken + + +bool TobyString::replaceFormatToken(int n, int val) +{ + char buf[128]; + snprintf(buf, sizeof (buf), "%d", val); + return(replaceFormatToken(n, buf)); +} // TobyString::replaceFormatToken + +// end of TobyString.cpp ... + diff --git a/src/util/TobyString.h b/src/util/TobyString.h new file mode 100644 index 0000000..47671a0 --- /dev/null +++ b/src/util/TobyString.h @@ -0,0 +1,57 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _INCLUDE_TOBYSTRING_H_ +#define _INCLUDE_TOBYSTRING_H_ + +#include +#include +#include "util/TobyObject.h" + +/* + * This is a relatively minimal string class, for dealing with the + * ugliness of string memory management. + * + * Written by Ryan C. Gordon. (icculus@linuxgames.com) + */ +class TobyString : public TobyObject +{ +public: + TobyString(void); + TobyString(const char *_str); + TobyString(const TobyString *_str); + + virtual ~TobyString(void); + + const char *c_str(void) const; + //char * operator char *(void); + + bool replaceFormatToken(int n, const char *val); + bool replaceFormatToken(int n, int val); + + void assignCStr(const char *str); + +private: + char *str; +}; // class TobyString + +#endif // !defined _INCLUDE_TOBYSTRING_H_ + +// end of TobyString.h ... + diff --git a/src/util/TobyThread.h b/src/util/TobyThread.h new file mode 100644 index 0000000..6123e8c --- /dev/null +++ b/src/util/TobyThread.h @@ -0,0 +1,52 @@ +/* + * TOBY -- An abstract interpreter engine and system for learning. + * Copyright (C) 1999 Ryan C. Gordon. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _INCLUDE_TOBYTHREAD_H_ +#define _INCLUDE_TOBYTHREAD_H_ + +#include "util/TobyObject.h" + +/* + * An abstraction over platform-specific threads: multiple contexts of + * execution in the same process space, sharing resources. + * + * Written by Ryan C. Gordon. (icculus@linuxgames.com) + */ +class TobyThread : public TobyObject +{ +public: + TobyThread(void) {} + virtual ~TobyThread(void) {} + virtual void start(void *(*runfunc)(void *)) = 0; + virtual void waitForTermination(void) = 0; + virtual bool isTerminated(void) = 0; +}; // class TobyThread + + +// This gets filled in along with the platform-specific subclass... +TobyThread *__platformBuildThread(void); + +// This gets called to yield the currently executing thread, which may be the +// main thread, for which no corresponding TobyThread exists. +void __platformThreadYieldCurrent(void); + +#endif // !defined _INCLUDE_TOBYTHREAD_H_ + +// end of TobyThread.h ... +