main loop code fixed to decouple updates and draws
authorCharles McGarvey <chazmcgarvey@brokenzipper.com>
Mon, 27 Jul 2009 21:37:27 +0000 (15:37 -0600)
committerCharles McGarvey <chazmcgarvey@brokenzipper.com>
Mon, 27 Jul 2009 21:37:27 +0000 (15:37 -0600)
other miscellaneous fixes included

Makefile.am
README
configure.ac
data/yoinkrc
doc/yoink.6.in
extra/yoink.ebuild
src/Makefile.am
src/YoinkApp.cc
src/engine.cc
src/settings.hh
src/video.cc

index ad16dbe049e6fe1ab7b1944f8dcd5f04032bfac1..95437f2ee2027a5ac276ec2045336f6adf28762e 100644 (file)
@@ -6,8 +6,8 @@ SUBDIRS = yajl src data doc
 EXTRA_DIST = yajl
 
 run: all
-       $(top_srcdir)/src/yoink
+       $(MAKE) -C src run
 
 debug: all
-       gdb $(top_srcdir)/src/yoink
+       $(MAKE) -C src debug
 
diff --git a/README b/README
index 8eb36d8ddb8454ee4e2467992e6a49e167733a57..0193c48f71a21d4b25711902e9b8110b6d85d4ea 100644 (file)
--- a/README
+++ b/README
@@ -10,10 +10,14 @@ The new code is released under the Simplified BSD License.  The old code and
 original resources are provided under the zlib/libpng License.  See COPYING
 for complete details.
 
-External Dependencies:
 
-GL
-SDL
-SDL_image
-boost
+Dependencies:
+
+boost headers  1.35.0
+libGL
+libSDL                 1.2.13
+libSDL_image   1.2.7
+
+Note: The version numbers are the versions I have been using for development,
+not necessarily the minimum required version numbers.
 
index 7b40bb30789a297dee79d9e985d9c587a8003213..63f2034434e53fce1b191899511b865e1a25da68 100644 (file)
@@ -70,12 +70,12 @@ AC_ARG_WITH([assetdir],
                        [eval DATADIR="$datarootdir/yoink"])
 
 AC_SUBST([DATADIR])
-
 AC_DEFINE_UNQUOTED([YOINK_DATADIR], ["$DATADIR"],
                                   [Define to path of game asset directory.])
 
-AC_DEFINE_UNQUOTED([YOINK_CONFIGFILES],                                    
-                                  ["\$HOME/.yoinkrc:/etc/yoinkrc:$DATADIR/yoinkrc"],
+CONFIGFILES="\$HOME/.yoinkrc:/etc/yoinkrc:$DATADIR/yoinkrc"
+
+AC_DEFINE_UNQUOTED([YOINK_CONFIGFILES], ["$CONFIGFILES"],
                                   [Define to colon-delimited config file paths.])
 
 
index 67be5c112b5d0dfa6dadd3bc927922f9e961f313..102848be7ada9c71c84c191eed8c0bd18bbd4841 100644 (file)
@@ -7,10 +7,10 @@
        "video.multisamplebuffers": 6,
        "video.multisamplesamples": 6,
        "video.cursor": true,
-       "video.grab": false,
+       "input.grab": false,
        "video.doublebuffer": true,
        "video.swapcontrol": true,
-       "engine.maxfps": 45,
-       "engine.printfps": true,
+       "video.maxfps": 45,
+       "video.printfps": true,
        "engine.timestep": 0.01
 }
index 70bcca56ec808068e9f3857ba2327c2580ccc5d9..5425c3a91f23021168972ed7120e6e1b591fcfa3 100644 (file)
@@ -34,18 +34,20 @@ Yoink \- An alien-smashing action game.
 .PP
 Leap tall buildings!  Crush stupid robots beneath your feet!  Wield your
 extra-terrestrial powers in the defence of humanity, and send those alien
-invaders back from whence they came!  Do all these things (apart from the last
-one at the moment) in Yoink!  You play the part of a flying alien heroine who
-must defend her home on Earth from other airborne alien invaders.  The game
-draws inspiration from classic arcade games like Joust, Bombjack, Rampage, and
-Defender--simple, fast-moving action.
+invaders back from whence they came!  This is Yoink.
 .PP
+You play the part of a flying alien heroine who must defend her home on Earth
+from other airborne alien invaders.  The game draws inspiration from classic
+arcade games like Joust, Bombjack, Rampage, and Defender--simple, fast-moving
+action.  Basic arguments include:
 .TP
 .B -h, --help
 display this help and exit
 .TP
 .B -v, --version
 output version information and exit
+.br
+.SH TIPS
 .PP
 To attack, you must dive on the enemy at high speed.  If you're going too
 slowly, you'll just drift harmlessly by.  Diving from above gives different
@@ -90,7 +92,7 @@ This is an optional environment variable.
 This is a specific user's configuration file.
 .TP
 3. /etc/yoinkrc
-This is a system-wide configuration file.
+This is the system-wide configuration file.
 .TP
 4. @DATADIR@/yoinkrc
 This is the base configuration file which should be considered read-only.  Look
@@ -100,33 +102,47 @@ Options that are passed as arguments take precedence over options loaded from
 the configuration file(s).  This mechanism is good for running the game with a
 temporary setting which you do not intend to retain.  Keep in mind that if you
 edit and save options in-game, any options you have passed as arguments during
-the invocation of the game will be saved to the $HOME/.yoinkrc configuration
-file.  You may have to go into that file and remove any options you didn't
-intend to set.  When passing options as arguments, you must use the fully
-qualified name of the option if it exists in a subgroup.  For example:
+the invocation of the game will be saved to the
+.I $HOME/.yoinkrc
+configuration file.  You may have to go into that file and remove any options
+you didn't intend to set.  When passing options as arguments, you must use the
+fully qualified name of the option if it exists in a subgroup.  For example:
 .PP
 .TP
 yoink video.fullscreen=true
-Set the option video.fullscreen to true.  This will run the game in full-screen
-mode.
+Set the option
+.I video.fullscreen
+to true.  This will run the game in full-screen mode.
 .TP
 yoink video.maxfps=60
-Set the option video.maxfps to 60.  This will cap the display rate at 60Hz.
+Set the option
+.I video.maxfps
+to 60.  This will cap the display rate at 60Hz.
 .PP
-You can also set options with array values.  Arrays can be passed on the
-command line by surrounding all the parts with square brackets and separating
-each part by a comma.  For example:
+You can also set options with array values.  Arrays can be passed on the command
+line by surrounding all the parts with square brackets and separating each part
+by a comma.  For example:
 .TP
 yoink video.mode=[1024,768]
-Set the option video.mode to an array with numbers 1024 and 768.  The video size
-will be 1024x768.
+Set the option
+.I video.mode
+to an array with numbers 1024 and 768.  The video size will be 1024x768.
 .PP
 Here is a list of some of the options available:
 .TP
 .B engine.timestep
 The amount of time in seconds between each update of the physics state.  A value
 of 0.01 or lower is ideal for accurate physics approximations.  Values that are
-much lower may introduce errors in the game.
+much higher cause the CPU to do less work, but accuracy will suffer.  Errors
+could be introduced in the game with extremely high values.
+.TP
+.B game.detail
+The level of detail.  Possible values are high, medium, and low.  This effects
+the number of objects drawn to the screen.  A high level of detail will draw
+everything but could cause poor frame rates if the graphics driver can't keep up
+with the load.  Lower levels will omit certain details which aren't crucial for
+playing the game with the benefit of higher frame rates.  See the Notes for more
+ways to get good performance.
 .TP
 .B input.grab
 Takes a boolean (true or false).  If true, the cursor pointer will be "stuck"
@@ -139,7 +155,7 @@ This takes an array of four number values which represent the number of bits to
 use for red, green, blue, and the alpha channel.  This is a low-level option of
 limited usefulness.  The default value is almost always preferable.
 .TP
-.B video.cursor
+.B video.showcursor
 This option effects the visibility of the cursor while it is "hovering" over the
 window.  If the value is true, the cursor will be visible.  Otherwise, the
 cursor will be hidden.
@@ -167,8 +183,8 @@ significantly lower the quality of the animation.
 .B video.mode
 The resolution or size of the window.  The value is an array with three number
 elements representing the width, height, and bits per pixel that make up the
-video mode..  A typical value is [800,600,32] for a size of 800x600 pixels with
-millions of colors.
+video mode.  A typical value is [800,600] for a size of 800x600 pixels with
+millions of colors (the third number is optional).
 .TP
 .B video.multisamplebuffers
 The number of multisample buffers used.
@@ -221,12 +237,48 @@ will look in this directory first when it is loading game assets.  Set this
 variable if you move the game's assets to another directory or want to load your
 own assets.
 .br
+.SH NOTES
+.PP
+Yoink may or may not be playable with acceptable frame rates without a hardware
+accelerated OpenGL driver installed and working, depending on how fast your CPU
+is.  Yoink is really not all that heavy on graphics, but it doesn't take much to
+overload a software implementation.  If you're stuck without hardware
+acceleration, there are some things you can do to get better frame rates:
+.PP
+1. Decrease the resolution with the
+.I video.mode
+option.  Due to the nature of the graphics in the game, you can go as low as
+320x240 and not notice a large reduction in image quality.  You can take
+advantage of this by decreasing the resolution and running full-screen (so the
+window is not so itty bitty on your monitor).  This will help out a lot.  Try
+this:
+.TP
+yoink video.mode=[320,240] video.fullscreen=true
+.PP
+2. Decrease the level of detail with the
+.I game.detail
+option.
+.PP
+On the other hand, if you already get high frame rates, you may also want to cap
+the rate so that your computer doesn't do more work than it really needs to.
+This may be useful when you run
+.B yoink
+on your production server at work.  You can get reasonably smooth animation at
+around 30fps, but you can probably tell a difference between that and a higher
+rate like 50fps.  The latter will look noticeably smoother and nice, while the
+former is just "acceptable."  See the
+.I video.maxfps
+option.
+.br
 .SH BUGS
 .PP
+No sound yet.  The original game never had sound, but it would probably be a
+good idea.
+.PP
 The pixelated graphics are actually intentional.  It adds to the charm of the
 game, don't you think?
 .PP
-Send bug reports and patches to:
+Send bug reports, patches, and love notes to:
 .br
 Charles McGarvey <onefriedrice@brokenzipper.com>
 .SH AUTHOR
index a2b311612d03f08c271554a6275adbd6e88b8eb4..16a430c807aa287bcc39741d5b3c91a476f4e40c 100644 (file)
@@ -14,7 +14,7 @@ SLOT="0"
 KEYWORDS="~amd64 ~ppc ~x86"
 IUSE="debug"
 
-RDEPEND="media-libs/libsdl[joystick,video]
+RDEPEND="media-libs/libsdl[opengl]
        media-libs/sdl-image[png]"
 DEPEND="${RDEPEND}
        dev-util/pkgconfig"
index 510dc9efdc278e2a32dee404ce07fd1fc91f22d8..ca4f81ef3f86e19d104a7bb0f2ec5574ca1ccb0a 100644 (file)
@@ -71,3 +71,13 @@ yoink_LDADD    = libdc.la
 
 EXTRA_DIST = cml
 
+
+YOINK_ENVIRONMENT = YOINK_DATADIR="$(top_srcdir)/data" \
+                                       YOINK_CONFIGFILE="$(top_srcdir)/data/yoinkrc"
+
+run: all
+       $(YOINK_ENVIRONMENT) ./yoink
+
+debug: all
+       $(YOINK_ENVIRONMENT) gdb ./yoink
+
index 4b024b47ec74f1e617d87b96689e7a645fbdd4c6..f0a1ad988864fa2388dac6cac0a56c7ebf9c9035 100644 (file)
@@ -76,6 +76,13 @@ YoinkApp::YoinkApp(int argc, char* argv[]) :
                          << "Send requests, patches, and bug reports to <"
                          PACKAGE_BUGREPORT << ">." << std::endl << std::endl;
 
+       char* dataDir = getenv("YOINK_DATADIR");
+
+       if (dataDir)
+       {
+               dc::resource::addSearchPath(dataDir);
+       }
+
        dc::resource::addSearchPath(YOINK_DATADIR);
 
        dc::dispatcher::instance().addHandler("video.context_recreated",
index ec6faa15e9d0505c027c659aa2867ae62eb263ba..7284799343a1f144d136ac65705f94c0ff54ad67 100644 (file)
@@ -75,11 +75,11 @@ public:
                timestep = scalar(ts);
 
                long maxfps = 40;
-               config.get("engine.maxfps", maxfps);
+               config.getNumber("video.maxfps", maxfps);
                drawrate = 1.0 / scalar(maxfps);
 
                printfps = false;
-               config.get("engine.printfps", printfps);
+               config.get("video.printfps", printfps);
        }
 
        ~engine_impl()
@@ -92,6 +92,13 @@ public:
        }
 
 
+       /**
+        * The main loop.  This just calls dispatchEvents(), update(), and draw()
+        * over and over again.  The timing of the update and draw are decoupled.
+        * The actual frame rate is also calculated here.  This function will return
+        * with a value of 0 if the member variable running becomes true.
+        */
+
        int run()
        {
                scalar ticksNow = ticks();
@@ -101,6 +108,7 @@ public:
                scalar nextFPSUpdate = ticksNow + 1.0;
 
                scalar totalTime = 0.0;
+               scalar deltaTime = 0.0;
                scalar accumulator = timestep;
 
                fps = 0;
@@ -109,26 +117,22 @@ public:
                running = true;
                do
                {
-                       dispatchEvents();
-
                        scalar newTicks = ticks();
-                       accumulator += newTicks - ticksNow;
+                       deltaTime = newTicks - ticksNow;
                        ticksNow = newTicks;
 
-                       if (accumulator >= timestep)
+                       if (deltaTime >= 0.25) deltaTime = 0.25;
+                       accumulator += deltaTime;
+
+                       while (accumulator >= timestep)
                        {
+                               dispatchEvents();
                                interface->update(totalTime, timestep);
 
                                totalTime += timestep;
                                accumulator -= timestep;
 
                                nextStep += timestep;
-                               if (ticksNow >= nextStep)
-                               {
-                                       // we missed some scheduled steps, so reset the schedule
-                                       nextStep = ticksNow + timestep;
-                                       accumulator = 0.0;
-                               }
                        }
 
                        if (ticksNow >= nextDraw)
index 9c2f2d83eb21dcc00744f77cfde2d7d990121526..f2a7aedc4151ee9ee60336cdc9b0d23fae7eef22 100644 (file)
@@ -58,6 +58,8 @@ public:
 
        template <typename T>
        bool get(const std::string& key, T& value);
+       template <typename T>
+       bool getNumber(const std::string& key, T& value);
 
 private:
        std::map<std::string,serializable_ptr> map;
@@ -80,6 +82,21 @@ bool settings::get(const std::string& key, T& value)
        }
 }
 
+template <typename T>
+bool settings::getNumber(const std::string& key, T& value)
+{
+       std::map<std::string,serializable_ptr>::const_iterator i = map.find(key);
+
+       if (i != map.end())
+       {
+               serializable_ptr obj = (*i).second;
+               return obj->getNumber(value);
+       }
+       else
+       {
+               return false;
+       }
+}
 
 } // namepsace dc
 
index 6960a0bafac8827abfabaa51cd5fe30fc1e7cbcf..7ad8efcf295dd7b9440c723b2f5bf535a26cf813 100644 (file)
@@ -340,8 +340,8 @@ video::attributes::attributes()
 
        settings::instance().get("video.fullscreen", fullscreen);
        settings::instance().get("video.resizable", resizable);
-       settings::instance().get("video.cursor", cursorVisible);
-       settings::instance().get("video.grab", cursorGrab);
+       settings::instance().get("video.showcursor", cursorVisible);
+       settings::instance().get("input.grab", cursorGrab);
 }
 
 
This page took 0.032473 seconds and 4 git commands to generate.