From dbc223eb843f97c021c45b86a681d468a0fbecd5 Mon Sep 17 00:00:00 2001 From: Ville Lindholm Date: Thu, 28 May 2026 16:35:31 +0300 Subject: [PATCH] Initial commit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Import existing source tree; original VCS history is no longer available. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- COPYING | 339 + COPYING.LIB | 478 ++ ChangeLog | 1312 ++++ Info.plist.in | 30 + KoboPlayer | Bin 0 -> 100 bytes Makefile.am | 110 + Makefile.in | 885 +++ README | 370 ++ README.html | 803 +++ README.jp | 46 + README.osx | 6 + README.sfont | 85 + README.xkobo | 146 + README.xkobo.jp | 139 + TODO | 330 + acconfig.h | 0 aclocal.m4 | 1044 ++++ aconfig.h | 190 + aconfig.h.in | 189 + buildpkg.sh | 37 + cfg-beta | 2 + cfg-cross-release | 2 + cfg-profile | 2 + cfg-release | 2 + cfg-work | 2 + cfg-work-opt | 2 + cfgform.cpp | 152 + cfgform.h | 76 + cfgparse.cpp | 1080 ++++ cfgparse.h | 199 + compile | 99 + config.guess | 1391 +++++ config.h | 149 + config.sub | 1492 +++++ configure | 12135 ++++++++++++++++++++++++++++++++++++ configure.in | 350 ++ dashboard.cpp | 452 ++ dashboard.h | 98 + data/Makefile.am | 9 + data/Makefile.in | 515 ++ data/gfx/Makefile.am | 17 + data/gfx/Makefile.in | 360 ++ data/gfx/bigfont3.png | Bin 0 -> 98569 bytes data/gfx/bigship.png | Bin 0 -> 140878 bytes data/gfx/bmr-green.png | Bin 0 -> 31832 bytes data/gfx/bmr-pink.png | Bin 0 -> 31023 bytes data/gfx/bmr-purple.png | Bin 0 -> 30303 bytes data/gfx/bolt.png | Bin 0 -> 4611 bytes data/gfx/boltexpl.png | Bin 0 -> 9380 bytes data/gfx/bomb.png | Bin 0 -> 14106 bytes data/gfx/bombdeto.png | Bin 0 -> 12255 bytes data/gfx/brushes.png | Bin 0 -> 234 bytes data/gfx/bullet5b.png | Bin 0 -> 10040 bytes data/gfx/bulletexpl2.png | Bin 0 -> 4917 bytes data/gfx/counterfont.png | Bin 0 -> 48362 bytes data/gfx/crosshair.png | Bin 0 -> 484 bytes data/gfx/deluxe.png | Bin 0 -> 6238 bytes data/gfx/explo1e.png | Bin 0 -> 15883 bytes data/gfx/explo3e.png | Bin 0 -> 44062 bytes data/gfx/explo4e.png | Bin 0 -> 29578 bytes data/gfx/explo5e.png | Bin 0 -> 43771 bytes data/gfx/fighter.png | Bin 0 -> 28137 bytes data/gfx/flatstars1.png | Bin 0 -> 3270 bytes data/gfx/focusfx.png | Bin 0 -> 18897 bytes data/gfx/goldfont.png | Bin 0 -> 24246 bytes data/gfx/hitnoise.png | Bin 0 -> 5884 bytes data/gfx/icefont2.png | Bin 0 -> 18589 bytes data/gfx/loading3.png | Bin 0 -> 82489 bytes data/gfx/logo-outline.png | Bin 0 -> 41387 bytes data/gfx/logomask3.png | Bin 0 -> 7012 bytes data/gfx/missile.png | Bin 0 -> 22199 bytes data/gfx/missile2.png | Bin 0 -> 24933 bytes data/gfx/missile3.png | Bin 0 -> 24296 bytes data/gfx/noise.png | Bin 0 -> 8886 bytes data/gfx/player.png | Bin 0 -> 36628 bytes data/gfx/ring.png | Bin 0 -> 33025 bytes data/gfx/ringexpl2b.png | Bin 0 -> 27170 bytes data/gfx/rock1c.png | Bin 0 -> 33940 bytes data/gfx/rock2.png | Bin 0 -> 30388 bytes data/gfx/rockexpl.png | Bin 0 -> 24872 bytes data/gfx/screen2.png | Bin 0 -> 89304 bytes data/gfx/shinyrock.png | Bin 0 -> 35715 bytes data/gfx/tiles-blood.png | Bin 0 -> 25701 bytes data/gfx/tiles-chrome.png | Bin 0 -> 28065 bytes data/gfx/tiles-double.png | Bin 0 -> 21865 bytes data/gfx/tiles-green.png | Bin 0 -> 14915 bytes data/gfx/tiles-metal.png | Bin 0 -> 19753 bytes data/sfx/Makefile.am | 19 + data/sfx/Makefile.in | 362 ++ data/sfx/aguitar1.agw | 49 + data/sfx/bassdrum5.agw | 42 + data/sfx/bleep1.agw | 36 + data/sfx/bleep3.agw | 35 + data/sfx/boltfire2.agw | 53 + data/sfx/boltfire2e.agw | 30 + data/sfx/boltfire2o.agw | 30 + data/sfx/boltfire2s.agw | 52 + data/sfx/brass2.agw | 57 + data/sfx/bzzzt1.agw | 37 + data/sfx/cannon1.agw | 141 + data/sfx/claps1.agw | 41 + data/sfx/edge2.agw | 41 + data/sfx/explo1b-rg.agw | 58 + data/sfx/explo1b.agw | 71 + data/sfx/explo1c-rg.agw | 58 + data/sfx/explo1c.agw | 72 + data/sfx/explo3d.agw | 71 + data/sfx/explo4d.agw | 80 + data/sfx/explo5.agw | 47 + data/sfx/explo5b.agw | 47 + data/sfx/explo5c.agw | 46 + data/sfx/explo6.agw | 78 + data/sfx/fmthump1b.agw | 29 + data/sfx/gameover1.agw | 70 + data/sfx/hardsync1.agw | 44 + data/sfx/impact2.agw | 27 + data/sfx/impact2b.agw | 27 + data/sfx/impact2c.agw | 27 + data/sfx/klank2b.agw | 29 + data/sfx/klank3.agw | 39 + data/sfx/klank3b.agw | 39 + data/sfx/klank3c.agw | 39 + data/sfx/klank4.agw | 45 + data/sfx/kobosfx.h | 54 + data/sfx/launch.agw | 60 + data/sfx/launch2.agw | 73 + data/sfx/launch3b.agw | 88 + data/sfx/launch4.agw | 70 + data/sfx/metallic7.agw | 66 + data/sfx/metallic7rs.agw | 53 + data/sfx/music.agw | 9 + data/sfx/music_c.agw | 12 + data/sfx/noiseburst2.agw | 25 + data/sfx/phattpad2.agw | 52 + data/sfx/pioing1b.agw | 48 + data/sfx/rockexplo.agw | 90 + data/sfx/save_waves.agw | 60 + data/sfx/schwoom1.agw | 52 + data/sfx/schwoop2.agw | 56 + data/sfx/schwoop3.agw | 42 + data/sfx/sfx.agw | 66 + data/sfx/sfx_c.agw | 58 + data/sfx/sine.agw | 25 + data/sfx/snare1.agw | 45 + data/sfx/synbass1.agw | 40 + data/sfx/test2.agw | 15 + data/sfx/test2.mid | Bin 0 -> 27488 bytes data/sfx/thunder1.agw | 25 + data/sfx/trance1.agw | 25 + data/sfx/trance1.mid | Bin 0 -> 9269 bytes data/sfx/trance1_c.agw | 26 + data/sfx/zapp1.agw | 32 + depcomp | 411 ++ eel/Makefile.am | 8 + eel/Makefile.in | 434 ++ eel/_e_script.h | 40 + eel/e_builtin.c | 462 ++ eel/e_builtin.h | 59 + eel/e_getargs.c | 1023 +++ eel/e_lexer.c | 419 ++ eel/e_lexer.h | 65 + eel/e_path.c | 60 + eel/e_register.c | 89 + eel/e_register.h | 96 + eel/e_script.c | 159 + eel/e_script.h | 29 + eel/e_symtab.c | 444 ++ eel/e_symtab.h | 239 + eel/e_util.c | 236 + eel/e_util.h | 107 + eel/eel-comp-src.txt | 89 + eel/eel-lang.txt | 161 + eel/eel.c | 573 ++ eel/eel.h | 376 ++ enemies.cpp | 188 + enemies.h | 437 ++ enemy.cpp | 1429 +++++ filemap.cpp | 857 +++ filemap.h | 170 + form.cpp | 321 + form.h | 84 + game.cpp | 138 + game.h | 83 + gamectl.cpp | 409 ++ gamectl.h | 122 + gamestate.cpp | 206 + gamestate.h | 84 + graphics/Makefile.am | 10 + graphics/Makefile.in | 457 ++ graphics/cs.c | 720 +++ graphics/cs.h | 472 ++ graphics/display.cpp | 104 + graphics/display.h | 24 + graphics/filters.c | 1159 ++++ graphics/filters.h | 192 + graphics/gfxengine.cpp | 1426 +++++ graphics/gfxengine.h | 282 + graphics/glSDL.c | 2328 +++++++ graphics/glSDL.h | 399 ++ graphics/region.c | 213 + graphics/region.h | 61 + graphics/sofont.cpp | 577 ++ graphics/sofont.h | 103 + graphics/sprite.c | 612 ++ graphics/sprite.h | 242 + graphics/toolkit.cpp | 764 +++ graphics/toolkit.h | 196 + graphics/vidmodes.c | 193 + graphics/vidmodes.h | 93 + graphics/window.cpp | 654 ++ graphics/window.h | 339 + icons.tar.gz | Bin 0 -> 26073 bytes install-sh | 251 + kobo.cpp | 2164 +++++++ kobo.h | 167 + kobodl.6 | 378 ++ kobolog.h | 44 + logger.c | 484 ++ logger.h | 158 + manage.cpp | 730 +++ manage.h | 110 + map.cpp | 220 + map.h | 69 + missing | 283 + mkinstalldirs | 40 + myship.cpp | 665 ++ myship.h | 113 + options.cpp | 506 ++ options.h | 75 + pfile.cpp | 282 + pfile.h | 136 + prefs.cpp | 177 + prefs.h | 137 + radar.cpp | 297 + radar.h | 76 + random.cpp | 26 + random.h | 71 + rwc-20040113.txt | 15 + rwc-20071005.txt | 15 + scenes.cpp | 1179 ++++ scenes.h | 62 + score.cpp | 733 +++ score.h | 220 + screen.cpp | 1042 ++++ screen.h | 105 + sound.cpp | 708 +++ sound.h | 152 + sound/Makefile.am | 12 + sound/Makefile.in | 459 ++ sound/a_agw.c | 528 ++ sound/a_agw.h | 359 ++ sound/a_bus.c | 297 + sound/a_bus.h | 50 + sound/a_channel.c | 250 + sound/a_channel.h | 251 + sound/a_commands.c | 226 + sound/a_commands.h | 98 + sound/a_control.c | 113 + sound/a_control.h | 91 + sound/a_delay.c | 594 ++ sound/a_delay.h | 122 + sound/a_events.c | 242 + sound/a_events.h | 411 ++ sound/a_filters.c | 353 ++ sound/a_filters.h | 110 + sound/a_globals.c | 113 + sound/a_globals.h | 136 + sound/a_limiter.c | 140 + sound/a_limiter.h | 70 + sound/a_math.h | 32 + sound/a_midi.c | 267 + sound/a_midi.h | 41 + sound/a_midicon.c | 351 ++ sound/a_midicon.h | 35 + sound/a_midifile.c | 806 +++ sound/a_midifile.h | 144 + sound/a_midisock.c | 234 + sound/a_midisock.h | 45 + sound/a_mixers.h | 359 ++ sound/a_patch.c | 753 +++ sound/a_patch.h | 99 + sound/a_pitch.c | 60 + sound/a_pitch.h | 107 + sound/a_plugin.c | 292 + sound/a_plugin.h | 386 ++ sound/a_sequencer.c | 116 + sound/a_sequencer.h | 51 + sound/a_struct.c | 36 + sound/a_struct.h | 43 + sound/a_tools.h | 266 + sound/a_types.h | 444 ++ sound/a_voice.c | 711 +++ sound/a_voice.h | 199 + sound/a_wave.c | 987 +++ sound/a_wave.h | 261 + sound/a_wca.c | 1829 ++++++ sound/a_wca.h | 180 + sound/a_wcaosc.h | 589 ++ sound/audio.c | 1126 ++++ sound/audio.h | 241 + sound/audiodev.c | 187 + sound/audiodev.h | 32 + sound/ptable.h | 141 + sound/sfifo.c | 327 + sound/sfifo.h | 110 + states.cpp | 1995 ++++++ states.h | 542 ++ version.h | 29 + 308 files changed, 81555 insertions(+) create mode 100644 COPYING create mode 100644 COPYING.LIB create mode 100644 ChangeLog create mode 100644 Info.plist.in create mode 100644 KoboPlayer create mode 100644 Makefile.am create mode 100644 Makefile.in create mode 100644 README create mode 100644 README.html create mode 100644 README.jp create mode 100644 README.osx create mode 100644 README.sfont create mode 100644 README.xkobo create mode 100644 README.xkobo.jp create mode 100644 TODO create mode 100644 acconfig.h create mode 100644 aclocal.m4 create mode 100644 aconfig.h create mode 100644 aconfig.h.in create mode 100755 buildpkg.sh create mode 100755 cfg-beta create mode 100755 cfg-cross-release create mode 100755 cfg-profile create mode 100755 cfg-release create mode 100755 cfg-work create mode 100755 cfg-work-opt create mode 100644 cfgform.cpp create mode 100644 cfgform.h create mode 100644 cfgparse.cpp create mode 100644 cfgparse.h create mode 100755 compile create mode 100755 config.guess create mode 100644 config.h create mode 100755 config.sub create mode 100755 configure create mode 100644 configure.in create mode 100644 dashboard.cpp create mode 100644 dashboard.h create mode 100644 data/Makefile.am create mode 100644 data/Makefile.in create mode 100644 data/gfx/Makefile.am create mode 100644 data/gfx/Makefile.in create mode 100644 data/gfx/bigfont3.png create mode 100644 data/gfx/bigship.png create mode 100644 data/gfx/bmr-green.png create mode 100644 data/gfx/bmr-pink.png create mode 100644 data/gfx/bmr-purple.png create mode 100644 data/gfx/bolt.png create mode 100644 data/gfx/boltexpl.png create mode 100644 data/gfx/bomb.png create mode 100644 data/gfx/bombdeto.png create mode 100644 data/gfx/brushes.png create mode 100644 data/gfx/bullet5b.png create mode 100644 data/gfx/bulletexpl2.png create mode 100644 data/gfx/counterfont.png create mode 100644 data/gfx/crosshair.png create mode 100644 data/gfx/deluxe.png create mode 100644 data/gfx/explo1e.png create mode 100644 data/gfx/explo3e.png create mode 100644 data/gfx/explo4e.png create mode 100644 data/gfx/explo5e.png create mode 100644 data/gfx/fighter.png create mode 100644 data/gfx/flatstars1.png create mode 100644 data/gfx/focusfx.png create mode 100644 data/gfx/goldfont.png create mode 100644 data/gfx/hitnoise.png create mode 100644 data/gfx/icefont2.png create mode 100644 data/gfx/loading3.png create mode 100644 data/gfx/logo-outline.png create mode 100644 data/gfx/logomask3.png create mode 100644 data/gfx/missile.png create mode 100644 data/gfx/missile2.png create mode 100644 data/gfx/missile3.png create mode 100644 data/gfx/noise.png create mode 100644 data/gfx/player.png create mode 100644 data/gfx/ring.png create mode 100644 data/gfx/ringexpl2b.png create mode 100644 data/gfx/rock1c.png create mode 100644 data/gfx/rock2.png create mode 100644 data/gfx/rockexpl.png create mode 100644 data/gfx/screen2.png create mode 100644 data/gfx/shinyrock.png create mode 100644 data/gfx/tiles-blood.png create mode 100644 data/gfx/tiles-chrome.png create mode 100644 data/gfx/tiles-double.png create mode 100644 data/gfx/tiles-green.png create mode 100644 data/gfx/tiles-metal.png create mode 100644 data/sfx/Makefile.am create mode 100644 data/sfx/Makefile.in create mode 100644 data/sfx/aguitar1.agw create mode 100644 data/sfx/bassdrum5.agw create mode 100644 data/sfx/bleep1.agw create mode 100644 data/sfx/bleep3.agw create mode 100644 data/sfx/boltfire2.agw create mode 100644 data/sfx/boltfire2e.agw create mode 100644 data/sfx/boltfire2o.agw create mode 100644 data/sfx/boltfire2s.agw create mode 100644 data/sfx/brass2.agw create mode 100644 data/sfx/bzzzt1.agw create mode 100644 data/sfx/cannon1.agw create mode 100644 data/sfx/claps1.agw create mode 100644 data/sfx/edge2.agw create mode 100644 data/sfx/explo1b-rg.agw create mode 100644 data/sfx/explo1b.agw create mode 100644 data/sfx/explo1c-rg.agw create mode 100644 data/sfx/explo1c.agw create mode 100644 data/sfx/explo3d.agw create mode 100644 data/sfx/explo4d.agw create mode 100644 data/sfx/explo5.agw create mode 100644 data/sfx/explo5b.agw create mode 100644 data/sfx/explo5c.agw create mode 100644 data/sfx/explo6.agw create mode 100644 data/sfx/fmthump1b.agw create mode 100644 data/sfx/gameover1.agw create mode 100644 data/sfx/hardsync1.agw create mode 100644 data/sfx/impact2.agw create mode 100644 data/sfx/impact2b.agw create mode 100644 data/sfx/impact2c.agw create mode 100644 data/sfx/klank2b.agw create mode 100644 data/sfx/klank3.agw create mode 100644 data/sfx/klank3b.agw create mode 100644 data/sfx/klank3c.agw create mode 100644 data/sfx/klank4.agw create mode 100644 data/sfx/kobosfx.h create mode 100644 data/sfx/launch.agw create mode 100644 data/sfx/launch2.agw create mode 100644 data/sfx/launch3b.agw create mode 100644 data/sfx/launch4.agw create mode 100644 data/sfx/metallic7.agw create mode 100644 data/sfx/metallic7rs.agw create mode 100644 data/sfx/music.agw create mode 100644 data/sfx/music_c.agw create mode 100644 data/sfx/noiseburst2.agw create mode 100644 data/sfx/phattpad2.agw create mode 100644 data/sfx/pioing1b.agw create mode 100644 data/sfx/rockexplo.agw create mode 100644 data/sfx/save_waves.agw create mode 100644 data/sfx/schwoom1.agw create mode 100644 data/sfx/schwoop2.agw create mode 100644 data/sfx/schwoop3.agw create mode 100644 data/sfx/sfx.agw create mode 100644 data/sfx/sfx_c.agw create mode 100644 data/sfx/sine.agw create mode 100644 data/sfx/snare1.agw create mode 100644 data/sfx/synbass1.agw create mode 100644 data/sfx/test2.agw create mode 100644 data/sfx/test2.mid create mode 100644 data/sfx/thunder1.agw create mode 100644 data/sfx/trance1.agw create mode 100644 data/sfx/trance1.mid create mode 100644 data/sfx/trance1_c.agw create mode 100644 data/sfx/zapp1.agw create mode 100755 depcomp create mode 100644 eel/Makefile.am create mode 100644 eel/Makefile.in create mode 100644 eel/_e_script.h create mode 100644 eel/e_builtin.c create mode 100644 eel/e_builtin.h create mode 100644 eel/e_getargs.c create mode 100644 eel/e_lexer.c create mode 100644 eel/e_lexer.h create mode 100644 eel/e_path.c create mode 100644 eel/e_register.c create mode 100644 eel/e_register.h create mode 100644 eel/e_script.c create mode 100644 eel/e_script.h create mode 100644 eel/e_symtab.c create mode 100644 eel/e_symtab.h create mode 100644 eel/e_util.c create mode 100644 eel/e_util.h create mode 100644 eel/eel-comp-src.txt create mode 100644 eel/eel-lang.txt create mode 100644 eel/eel.c create mode 100644 eel/eel.h create mode 100644 enemies.cpp create mode 100644 enemies.h create mode 100644 enemy.cpp create mode 100644 filemap.cpp create mode 100644 filemap.h create mode 100644 form.cpp create mode 100644 form.h create mode 100644 game.cpp create mode 100644 game.h create mode 100644 gamectl.cpp create mode 100644 gamectl.h create mode 100644 gamestate.cpp create mode 100644 gamestate.h create mode 100644 graphics/Makefile.am create mode 100644 graphics/Makefile.in create mode 100644 graphics/cs.c create mode 100644 graphics/cs.h create mode 100644 graphics/display.cpp create mode 100644 graphics/display.h create mode 100644 graphics/filters.c create mode 100644 graphics/filters.h create mode 100644 graphics/gfxengine.cpp create mode 100644 graphics/gfxengine.h create mode 100644 graphics/glSDL.c create mode 100644 graphics/glSDL.h create mode 100644 graphics/region.c create mode 100644 graphics/region.h create mode 100644 graphics/sofont.cpp create mode 100644 graphics/sofont.h create mode 100644 graphics/sprite.c create mode 100644 graphics/sprite.h create mode 100644 graphics/toolkit.cpp create mode 100644 graphics/toolkit.h create mode 100644 graphics/vidmodes.c create mode 100644 graphics/vidmodes.h create mode 100644 graphics/window.cpp create mode 100644 graphics/window.h create mode 100644 icons.tar.gz create mode 100755 install-sh create mode 100644 kobo.cpp create mode 100644 kobo.h create mode 100644 kobodl.6 create mode 100644 kobolog.h create mode 100644 logger.c create mode 100644 logger.h create mode 100644 manage.cpp create mode 100644 manage.h create mode 100644 map.cpp create mode 100644 map.h create mode 100755 missing create mode 100755 mkinstalldirs create mode 100644 myship.cpp create mode 100644 myship.h create mode 100644 options.cpp create mode 100644 options.h create mode 100644 pfile.cpp create mode 100644 pfile.h create mode 100644 prefs.cpp create mode 100644 prefs.h create mode 100644 radar.cpp create mode 100644 radar.h create mode 100644 random.cpp create mode 100644 random.h create mode 100644 rwc-20040113.txt create mode 100644 rwc-20071005.txt create mode 100644 scenes.cpp create mode 100644 scenes.h create mode 100644 score.cpp create mode 100644 score.h create mode 100644 screen.cpp create mode 100644 screen.h create mode 100644 sound.cpp create mode 100644 sound.h create mode 100644 sound/Makefile.am create mode 100644 sound/Makefile.in create mode 100644 sound/a_agw.c create mode 100644 sound/a_agw.h create mode 100644 sound/a_bus.c create mode 100644 sound/a_bus.h create mode 100644 sound/a_channel.c create mode 100644 sound/a_channel.h create mode 100644 sound/a_commands.c create mode 100644 sound/a_commands.h create mode 100644 sound/a_control.c create mode 100644 sound/a_control.h create mode 100644 sound/a_delay.c create mode 100644 sound/a_delay.h create mode 100644 sound/a_events.c create mode 100644 sound/a_events.h create mode 100644 sound/a_filters.c create mode 100644 sound/a_filters.h create mode 100644 sound/a_globals.c create mode 100644 sound/a_globals.h create mode 100644 sound/a_limiter.c create mode 100644 sound/a_limiter.h create mode 100644 sound/a_math.h create mode 100644 sound/a_midi.c create mode 100644 sound/a_midi.h create mode 100644 sound/a_midicon.c create mode 100644 sound/a_midicon.h create mode 100644 sound/a_midifile.c create mode 100644 sound/a_midifile.h create mode 100644 sound/a_midisock.c create mode 100644 sound/a_midisock.h create mode 100644 sound/a_mixers.h create mode 100644 sound/a_patch.c create mode 100644 sound/a_patch.h create mode 100644 sound/a_pitch.c create mode 100644 sound/a_pitch.h create mode 100644 sound/a_plugin.c create mode 100644 sound/a_plugin.h create mode 100644 sound/a_sequencer.c create mode 100644 sound/a_sequencer.h create mode 100644 sound/a_struct.c create mode 100644 sound/a_struct.h create mode 100644 sound/a_tools.h create mode 100644 sound/a_types.h create mode 100644 sound/a_voice.c create mode 100644 sound/a_voice.h create mode 100644 sound/a_wave.c create mode 100644 sound/a_wave.h create mode 100644 sound/a_wca.c create mode 100644 sound/a_wca.h create mode 100644 sound/a_wcaosc.h create mode 100644 sound/audio.c create mode 100644 sound/audio.h create mode 100644 sound/audiodev.c create mode 100644 sound/audiodev.h create mode 100644 sound/ptable.h create mode 100644 sound/sfifo.c create mode 100644 sound/sfifo.h create mode 100644 states.cpp create mode 100644 states.h create mode 100644 version.h diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..a43ea21 --- /dev/null +++ b/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, 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., 675 Mass Ave, Cambridge, MA 02139, 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/COPYING.LIB b/COPYING.LIB new file mode 100644 index 0000000..9033c8f --- /dev/null +++ b/COPYING.LIB @@ -0,0 +1,478 @@ +********************************************************************* +* IMPORTANT! IMPORTANT! IMPORTANT! IMPORTANT! IMPORTANT! IMPORTANT! * +* * +* "Kobo Deluxe" is a game based on the work of many programmers, * +* artists, porters, testers and devoted fans. * +* * +* In order to make the new code useful to more people, even in * +* closed source productions, I am making it available under * +* the terms of the GNU LGPL. * +* * +* However, note that the GNU LGPL only applies to * +* *some* of the files in this distribution, not all of them! * +* * +* If you are going to reuse all or part of "Kobo Deluxe", please * +* read the terms stated in the header of *each file* first. * +* * +* IMPORTANT! IMPORTANT! IMPORTANT! IMPORTANT! IMPORTANT! IMPORTANT! * +********************************************************************* + + Below this line follows an unmodified copy of the GNU LGPL +--------------------------------------------------------------------- + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 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 +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +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 and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, 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 library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete 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 distribute a copy of this License along with the +Library. + + 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 Library or any portion +of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +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 Library, 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 Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you 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. + + If distribution of 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 satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be 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. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library 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. + + 9. 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 Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +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 with +this License. + + 11. 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 Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library 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 Library. + +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. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library 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. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser 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 Library +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 Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +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 + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "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 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. 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 LIBRARY 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 +LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..a68d5e0 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,1312 @@ +Kobo Deluxe v0.5.1 + * Fixed segfault with weird audio buffer sizes. + * *Maybe* clears the screen a bit sooner... (One + could see a magnified desktop or garbage display + for a moment on some systems.) + * When there is no profile, the automatic New Player + dialog sends you on to the main menu, rather than + back to the intro. + * Added a bunch of AGW explosion sounds. + * Added new "big ship" launch and escape sound. + * Fixed infinite loop bug in filemapper_t::get_next(). + (Thanks Joey Hess!) + * New "core destroyed" sound. + * When compiled with PROFILE_AUDIO, the 'R' key + reloads all sound effects. + * Integer atan2() approximation for sprite rotation. + * "Fixed" cubic resampler. (There will be a jump of one + sample when switching to/from cubic interpolation.) + * New player fire sounds, including overheat warning. + * Tweaked various sounds and related logic. + * 10% health award for core destroyed, and another 25% + for stage cleared. (No more 100% for stage cleared!) + * Health can now be up to 200%, but will decrease + quickly towards 100%. + * Destupified the bargraph_t value() interface... + * Waveform info after loading with logverbosity >= 2. + * Added pause sound. + * Added "Safe video settings" message when "escape + hammering" is detected. + * Explosions can now actually show the first frame. + * Explosion "random start frame" removed. + * Initial white flash for explosions. + * Fewer bonus lives! (We have the health bonus now...) + * Default and rock explos assume half speed of objects. + * Added player bolt impact fx. + * Improved player explosion. + * Bomb detonation fx directed at the player. + * Fixed a positional audio wrap bug. + * Configurable "Cannon Sound Suppression." + * Configurable overheat warning buzzer. + * Doubled rock health for Newbie skill. + +Kobo Deluxe v0.5.0 + * Added 'autoshot' command line switch for grabbing + ingame screenshot series. + * Added animated rocks. + * Added 88.2, 96, 176.4 and 192 kHz sample rates. + * Default video mode changed to 640x480. + * Option 'internalres' considered obsolete. (Was + never implemented.) + * s_filter_scale() fallback from Scale2x and + Diamond2x for non 2x factor changed to bilinear. + * Newbie mode changes: + * Three alternating nose/wing guns. + * Two alternating rearward wing guns. + * Fixed nonsense values for the SDL_GL_DOUBLEBUFFER + attribute. (Thanks, Sam Palmer!) + * Fixed Y/N buttons in the requester dialogs. + * Some new explosions, enemy bullets and other gfx. + * Fixed segfault in myship.cpp in (the extremely + unlikely) case of running out of sprite objects. + * 'pushmove' now counts as a cheat. (No highscores.) + * Added simple parallax starfield, along with none/ + old/parallax starfield style switch. + * Intro mode now sets it's own fixed logic rate. + * Enemy definitions now have "death handlers". + * Invisible enemies no longer allocate sprites. + * Background color fade in damage noise flash and + noise-out effects. + * Map now marks cores as needed to select orientation + specific core tiles. + * Broken base branches are left as is. + * No dithering for the logo mask! (Thanks again, + Sam Palmer! :-) + * Separated map tile index from map state bits. + * Added alternate straight sections in bases. + * OpenGL vsync is now optional. + * Added 'S' key for screenshot. (PrintScreen is + stolen by some desktop environments.) + * Larger fps counter, for 1000+ rates... + * Corrected cs_engine_t.time type. Animation should + be smooth and reliable now! + * Tweaked screen.png a little. (Contrast, AA, ...) + * "Audio Options" renamed "Sound Options". + * Rocks are now destructible again (255 hits in + Classic mode; other values in new skill levels). + They also have an explosion all of their own. + * Special detonation animation for bombs. + * Bullets, player, enemies etc in separate layers. + * More firepower in the "Gamer" skill level. + * Benchmark based progress bar. + * Framework overlay now rendered as small tiles in + the corners of the playfield window, to avoid full + window impact on slow video cards in OpenGL mode. + * glSDL: + * Now compiles with OpenGL disabled. (Thanks, + Michael Sterrett!) + * Gamer mode changes: + * Higher firing rate. + * Added "videopages" option to make smart refresh work + with triple buffered displays, and for disabling + smart refresh if all else fails. + * Fixed weird audio fragment sizes. + * Fixed cubic interpolation -1 sample index bug in + a_mixers.h. + * Graphics loader refactored; gets parameters from a + table, and provides more verbose error messages. + * New "Boomerang" fighters with 16 rotations. + * New fighter ship. (Replaces the teal missile.) + * New gray, red and blue missiles. + * Disabled colorkey filter in gfxengine. + * New "loading" logo. + * Slightly slower (more readable) scroll text. + * Added window_t::textwidth_fxp(), to fix the unsmooth + text scrolling. + * Added "How to play" screen. + * Added "Highscores only for Classic mode!" notice. + * Added optional mouse capture when playing. Pause or + abort game to release! + * Added joystick selection. (Thanks, Erik Auerswald!) + * Decided the substantial change in appearance calls + for a minor version bump, so: 0.5.0. + * The -help switch is now handled as a proper command, + avoiding the stupid "unknown argument" error. + * Added -options_man command to output option docs in + Un*x man format. + * Updated the Un*x man file, and replaced the README + with a rendition of the man file. + * Made a new README from the man file. + * New counter font. + * Fixed some minor compiler warnings. + * Updated the TODO. + +Kobo Deluxe v0.4.1 + * Got fed up with these "pre" version codes that + don't fit into package versioning systems and + look generally silly. + * Implemented logic/audio timeline sync for + constant sound effect latency. Events are no + longer quantized to buffers. + * Improved the latency selector a bit. + * Latency calculations now assume 2 fragments for + SDL. (We use 3 fragments for OSS.) + * Latency calculation now picks the *closest* + buffer size; not the biggest one with lower or + equal latency. + * Removed "games" from the install paths on Un*x + systems, and moved the score files to the more + correct $(sharedstatedir). The install target + now works as expected for an autoconf build. + * Reverb and limiter controls replaced with the + simplified "Ambience" and "Volume Boost" + controls. + * Mega stoopid bug fixed: If video initialization + failed after changing video settings from the + options menu, the game would start back up + anyway - without a display! + * kobo.cpp now keeps a copy of the preferences, + so safe settings can be restored should reinit + inside the run/reinit loop fail. + * LoadRAW_S8() became LoadRAW(), and can now load + "raw" files with an 8 byte header containing "RAW" + followed by the audio_formats_t format code, and + a 32 bit sample rate in big endian format. The + MSB of the format code byte is set if the + waveform is looped. + * Implemented SaveRAW(). (Always saves in the above + format.) + * Implemented quick hack sound caching by providing + a script that saves all sounds to disk, and + alternative loader scripts that use those instead + of the AGW sounds. This currently generates 2 MB + of raw audio data. + * Added window_t::refresh() to enable the engine + to correctly handle windows that aren't repainted + every frame. + * Added endian swapping code for 16 and 32 bit raw + audio files. Files are in big endian, so this + code is only compiled on little endian archs. + * The mixers in a_tools.h now test for the zero + samples in debug builds. + * Removed in-game music pausing/restarting. + * Game Over no longer stops the game logic. + * Player profiles cannot be symlinks. (Security.) + * When loading a "raw" file, audio_wave_load() + takes looped/one-shot from the file. + * AGW w_load() and w_save() now tells EEL about + errors! (Kinda' handy... :-) + * Replaced "fine.raw" with "breakdown1.agw". + (The "fortress destroyed" sound.) + * Replaced "shot.raw" with "missile1.agw". + (The player fire sound.) + * Fixed sound FX bug: _enemy::hit() used x and y + fields of _enemy objects after release(). + * Another sleeping bug: _myship::explode() + generated lots of huge, nasty coordinates. + * Removed "expl3.raw" completely, and removed + "bomb.raw" from "core destroyed." + * Added a logger with redirection capabilities. + * Fixed mouse control bug; the crosshair hot-spot + offset was wrong in some resolutions, because + of the border that's put around the screen in + certain resolutions and in windowed modes. + * display_t refactored to use refresh(). + * Added dashboard.(cpp|h) and refactored the health + bar to use refresh(). + * The framework is now rendered through refresh(). + * Removed the pixel_* cruft in the _screen class. + * The _radar class becomes radar_window_t, which + is a window_t with callback driven rendering. + * window_t gets offscreen window/surface support. + * gfxengine now whines a little if it has to change + the buffering mode from the requested one. + * The health bar is only visible if there's more + than one health point maximum. (So, it's no longer + visible in Classic Mode.) + * gfxengine_t should now initialize the dirtyrect + management for page flipping properly. + * Removed the odd "OpenGL" resolutions in the video + options. + * No buffering mode for OpenGL in video options. + * Removed AC_FUNC_MALLOC. Who needs malloc(0)...? + * Added logfile and logformat options. + * Removed all extern "C" clauses around C includes. + * Fixed the "selector tube" heights; the surfaces + were much taller than the images. + * Tweaked the cleanalpha filter parameters. + * Optimized the dither filter; it doesn't *have* + to touch all the data to just do nothing... :-) + * Optimized the image processing filters. + * Added "No Alpha Blending" feature. + * Moved the sprite filters into filters.h. + * loadrect() renamed copyrect() and is now + applying scaling to coordinates like all other + calls. + * SemiTriple removed from buffering modes. You get + the same setup with doublebuffer(1); shadow(1). + * Old retrace sync cruft removed. + * ESC from any "normal" state now gives you some + version of the main menu. + * Added brightness/contrast filter. + * Moved less h/w related stuff from "Video Options" + into a new "Graphics Options" section. + * Added generic 'flags' field to filter arguments, + and threw in a global s_filter_flags as well. + * Removed window dependency from gamestate.(cpp|h) + and changed the license to LGPL. + * Upgraded to glSDL 0.7, w/ dynamic OpenGL loading. + * Added "Random" and "4x4 Filter" dithering methods. + * All graphics converted to PNG format. + * Added support for scaling to (almost) arbitrary + resolutions, including lower than the native + resolution of the graphics. + * The command line usage message now generates the + list of recognized options from the prefs object. + * Buffer overflow bug in new_player_t fixed. (?) + (Thanks to Donny Viszneki for reporting it!) + * Fixed a free()/delete bug in filemapper_t. + * Rewrote most of the radar display code. + * Removed unused scrolling cruft in window_t. + * Changed version to 0.4.1. Too many 0.4something. + * Made the player ship cursor flash slightly. + * Fixed missing slash before the config file name. + (Never noticed this before, as it apparently + affects only Mac OS X.) + * Fixed the title screen cheat mode indicator. + * Thanks to Antonio Messina, who managed to break + the game logic desipte a broken arm: + * Fixed difficulty wrap at stage 1601. + * Added option always_fire. + * Fixed missing gamecontrol_t constructor. + * Bilinear scaling without oversampling is now + actually *without* oversampling. + * Optimization: Scaling checks for clipping or + clamping only near the edges of surfaces. + * The SDL audio callback now deals with "evil" + buffer sizes. (Thanks to Hans de Goede!) + * Losing window focus now pauses the game. (Thanks, + Marianne Ibbotson!) + * Upgraded to glSDL 0.8. + * gfxengine no longer shuts down the SDL video + subsystem when hiding, as this causes problems + with glSDL for no gain. + * Implemented selectable Newbie, Oldie and Elite + skill levels. + * kobo_form_t:xoffs now also works for button(). + * Added kobo_form_t:medium(). + * Added "spread" fire for Newbie mode. + * Lower rear fire rate for Elite mode. + * Max number of saved scores per profile increased + to 100. + * Added cannon heat/cooling simulation. + * Added Video Mode Manager vidmodes.[ch] + * Some ships flying around in intro mode. + * New screen layout. + * Optimized and improved the video noise effect. + * Menu highlight bar: + * Faster movement. + * Parallax "slime" effect. + * Zoom-to-size effect. + * Made more room for extreme scores in Hall of Fame. + * Red noise to indicate damage. + * Snappier health bar. + * Added gun temperature bars. + * Upgraded to glSDL 0.9. (Colorkey fix.) + * Sound control cleanup; added sound.(h|cpp). + * Changed to Classic mode + four "New Mode" skill + levels; Newbie, Gamer, Elite and God. + * maxfps default changed from disabled to 100. + * Added CharOffset table to SoFont, to avoid mixing + actual character positions up with source blitting + extents. + * Fixed rectangle size calculations and rounding in + the graphics engine. (Improves rendering accuracy + in "odd" resolutions.) + * Fixed screen border refresh. + * Added hotspot logic to the sprite engine. + * New player "plasma bolts" and two new explosions. + * Incomplete base destruction bug fixed (?) + * Fractional frame times use double instead of float. + * Added configurable time filter. + * Default scale mode changed to Bilinear. + * Bilinear+Oversampling removed from config menu. + * Added "Strictly Regulated" frame rate limiter. + * Options moved to "System Options": + * Maximum Frame Rate + * Strictly Regulated Frame Rate + * Time Filter + * Motion Interpolation + * Removed some unimplemented video driver enums. + * Current score and stage is now checked when + quitting from within a game. + * Image filters are now removed properly. + * Added window centering for "some platforms". + * Hammering on Escape is trapped and aborts the + game when loading, or switches to a safe video mode + when running. + * Some refactoring to hunt down memory leaks and other + issues. Most statically allocated objects gone. + * Sped up the slow, annoying nibble effects. + * "Weird characters" in New Player name editor fixed. + * Proper Yes/No dialog for exit and abort game. + * Unused song ballad1 + instruments removed. + * "Dummy" score file (for WinZIP) is now minimal, no + scores, no stages finished. + +Kobo Deluxe v0.4pre10 (Unofficial Debian/PPC fix release) + * #include "config.h" was missing in e_getargs.c... + * Applied security fix for saving the user config. + * Added default case in glSDL's _print_glerror(), + since I get flooded with warnings otherwise. + (All GL_* are in an enum in my new GL.h.) + * Added max_FPS feature, to restrict the frame + rate. Useful on video drivers without retrace + sync and/or when you want to reduce CPU load. + (Thanks to Martijn van Oosterhout for the + original patch!) + * Added man page, contributed by Joey Hess. + * Fixed some minor typos in the man page. + * Added resolutions 1600x1200 and 1920x1440 and + 2048x1536, for extreme/insane users. ;-) + * Removed 57 unused AGW scripts. (These belong to + Audiality, which is now a separate project.) + * Updated and shortened the scroll text. + * Added monitor noise effect with sound effect. + * Fixed two related bugs in s_filter_scale() that + would 1) cause NEAREST to be one pixel off + vertically and 2) linear interpolation modes to + be off by half a pixel horizontally. + * Tweaked the death explosion, so it expands, + decays and ends, instead of just rolling for as + long as the player is dead, as it used to be. + * Added Game Over sound effect. + * Dead player no longer takes hits. (This avoids + the hysterical thumping of bullets hitting the + non-existent ship during the death sequence.) + * Added README.osx, which points out that you may + have to create the score-dir to make Kobo DL + work. This applies to other archs as well, so + perhaps I should put it in an FAQ or something? + (Thanks to Adam Marks the the Mac OS X binary!) + * Tweaked launch.agw. (More turbine; less noise.) + * Added Get Ready sound effect. + * Exiting pause mode now throws you right back + in the game. (No "get ready" state.) + * Added configurable "get ready" countdown. + * "Get ready" countdown now ends by starting the + game, rather than entering pause mode. + * Controls are reset whenever you get a new ship. + * Improved the loading status screen a bit. + * Added shrinking and green->red fading bar + during the last second of the "Get Ready" + countdown. (0.7 s in "Quick Start" mode.) + * Added a critical error state with a red + flashing box and stuff. This shows up if a + player profile cannot be created, or if + starting a game fails for some reason. + * The game now remembers the last map played + until you quit, instead of resetting to the + last completed map all the time. (Thanks to + David Andersson for the idea!) + * Fixes backported from Audiality: + * midi_process() was called even if MIDI + input was not enabled, resulting in the + engine waiting for data on stdin once + per buffer... *heh* Fixed. + * OSS MIDI input fixed. (When soft through + was disabled, the device would be opened + write only! The drivers I used before + obviously always opened RDWR...) + * Poly and mono Patch Plugins now + initialize the primary output and send + busses for voices. (So *that's* why my + mixes broke... Oops!) + * New, properly working envelope generator + backported from Audiality. + * VE_ISET event eliminated - only IRAMP + is used for ramped voice controls. + * glSDL changes for glSDL-0.4: + * "no TexInfo" changed from 0xffffffff to + 0, since SDL 1.2.5 and up inits the + unused1 field to that, specifically for + glSDL. + * Added compile time and runtime warnings + for SDL versions prior to 1.2.5. + +Kobo Deluxe v0.4pre9 (Debian/PPC fix release; first try) + * EEL changes: + * Stole eel_get_argsv() from the not yet + released Audiality 0.1.0. (Fixed some + more va_list issues.) + * glSDL changes for glSDL-0.4: + * Added (gl)SDL_SaveBMP(). + * "Fixed" OpenGL pixel format for + glReadPixels. (Maybe I got the glSDL pixel + format wrong? Dunno, and I'm on an ATI card + and driver so I don't trust anything...) + * Fixed _glSDL_BlitFromGL() (I think...) + * Removed the "Intelligent Display Abstraction + Layer" for now, as it's not yet usable. + * Added screen() property to gfxengine_t, to have + a standard way of rendering to the full screen + area. + * Added gfxengine_t::clear() method. + * Added coarse clipping to SoFont. (The scroller + made the coords wrap in 1280x1024. *heh*) + +Kobo Deluxe v0.4pre9 (unreleased) + * Started hacking the "Intelligent Display Abstraction + Layer". + * glSDL changes for glSDL-0.4: + * Fixed C++ issue with IMG_Load(). + * Fixed stupid M$isms: Textures are now + *uploaded* to the card. + * SDL_OPENGLBLIT removed. (Used only to + prevent certain unimplemented stuff from + causing *really* Bad Things to happen.) + * Depth buffer silliness fixed. (We don't + use the depth buffer...) + * "fake_screen" is now a real surface. + * Implemented blitting from the screen. + * Implemented blitting within the screen. + * Implemented screen locking/unlocking. + * Fixed prototype for glSDL_GetVideoSurface(). + * EEL changes: + * Added eel_load_from_mem(). (Thanks to + Florian Schulze!) + * Cleaned up the EEL script management + code a little. + * Using va_copy() in e_getargs.c, since + assignments are not legal on all + platforms. (Thanks, Andreas Heck!) + +Kobo Deluxe v0.4pre8 + * Added Extreme Pickyness Mode (--enable-epm). + (Unfortunately, this is not enough to ensure that + stuff compiles on gcc 3.x. Guess I'll just have to + install gcc3, or rely on gcc3 users reporting all + warnings and errors.) + * Some const string issues fixed. (Returning a const + string as "char *" and the like.) + * Removed all AdLib stuff and support for non- + standard MIDI file variants. However cool it might + be to play those files, I have no use for it and + can't maintain it in this project. + * Removed old bogus stuff from the comments in + filemap.h. + * Minor cleanups in filemap.cpp. + * Some GCC3 fixes in score.cpp. (String copying...) + * Scroll text updated. + * Improved scroller "speed throttling". + * Returning to the intro now restores the "demo" map. + * Added Electric Fence to the Extreme Pickyness Mode. + * Started cleaning up the C code using Splint. (Can + someone please donate a FlexLint license...? :-) + * load_sounds() in kobo.cpp fixed; it wouldn't load + the music if the sound effects were loaded with + a previous call. + * Somewhere along the way, I managed to get the + intro to generate a new demo map on every intro + screen switch. Fixed. + * Audio engine changes: + * Added OSS 'pollaudio' for debugging. + * Fixed index outside array in + audio_wave_free()! + * Tightened up the API - signs only where + needed and things like that. + * 0 dB peak amplitude for 32 bit waveforms + changed to [-1.0, +1.0]. + * ptab_init() now takes an integer argument. + (No implicit float->fixp16:16 conversion.) + * Ports and "clients" are now named for + debugging/tracing, although client names + exist only if AEV_TRACING is compiled in. + * Cleaned up audio event system names. + Everything is now aev_, and most + names have been significantly shortened. + * Added aev_init() macro for ports! (Aargh!) + * Open/close of subsystems cleaned up. All + subsystems now have audio_*_open/close() + calls, and should (hopefully) clean up + properly when closed. + * Audio engine open/close API changed; + the full sequence is now: + audio_open() (optional) + audio_start() + audio_stop() (optional) + audio_close() + Note that the waveform and scripting + subsystems will still initialize + themselves automatically if used before + calling audio_open(). + ! The last two seem to have fixed the + issues with restarting the engine on + Linux! Remains to see if that was the + whole problem... + BENCHMARK: speed1.agw renders in 27.2 s. + speed2.agw renders in 21.5 s. + Total: 48.7 s. + * Added block based processing framework. + * Implemented block read, write and add. + * Added block based envelope processing. + * Using the new envelope interface - but + still processing one sample at a time. + (BENCHMARK: speed.agw renders in 34.2 s!) + * Using 32 frame blocks in wca_filter() + and wca_gain(). + (BENCHMARK: speed.agw renders in 33.6 s. + wca_filter() disabled: 31 s.) + * Converted wca_osc() to block based + processing, and made some minor + optimizations. + * WCA_SYNC for WCA_NOISE fixed. Each sync + pulse now shifts in a new value through + the S&H as well. + * Fixed bug in spectrum oscillators: They + would produce no output with a mod1 input + of less than 1.0. They now produce pure + sine, as originally intended. + * HSPECTRUM and PHSPECTRUM fixed: They + actually didn't separate roll-off control + for odd and even harmonics at all! (Thus, + they were basically just broken versions + of SPECTRUM...) + * SPECTRUM modulation mapping unified; MOD1 + now always controls the overtone stepping. + * The new AHSPECTRUM replaces PHSPECTRUM. + * HSPECTRUM becomes a AHSPECTRUM with + multiplicative overtone stepping control. + BENCHMARK: speed1.agw: 10.2 s. 167% faster. + speed2.agw: 17.7 s. 21% faster. + Total: 27.9 s. 75% faster. + Obviously, the optimizations worked out + rather well. Next, we'll try to do something + about those spectrum oscillators... + +Kobo Deluxe v0.4pre7 + * Old samples boosted by 70%, to compensate for the + lack of an illogical amplification factor in the + new engine. :-) + * The screwed up scroll position during the "Game + Over" state fixed. + * "Early bullets", flickering and other crap fixed. + * gfxengine_t and sprite.[ch]: Added clampcolor() and + s_clampcolor (for specifying what color and alpha + to assume for areas outside images), and changed + the color format to Uint8 in the range [0,255], to + be consistent with the change in window_t. + * manage: Selecting a starting stage before staring + a game now preserves the actual map that is + generated. You don't get a new version of the + same level, but the exact map you're looking at + before starting the game. + * radar: Fixed potential color allocation bug when + changing video mode; it used to initialize only + once during the game life time... + * radar: Tweaked colors, and made the the blue + launcher nodes visible on the radar. + * Options 'cheat' and 'indicator' are now commands + rather than switches, so they cannot be saved in + the configuration by accident. + * Split the "push move" mode off from 'indicator' + into a feature of it's own, activated with + the 'pushmove' command. + * Game and Control options moved to the top of the + options main menu. + * Scrolling radar implemented. Can be disabled in + Game Options, to work like the old version. + * gfxengine_t make slightly more robust WRT calls + being made while the screen is closed. + * Switching between fullscreen and windowed modes + can now be done at any time with the usual ALT+ENTER + shortcut. :-) Special case activates pause mode if + it's done in the middle of a game. + * Random number generator split in two; pubrand and + gamerand, and get_seed() member added, as a + preparation for demo recording and playback. + * 'P' and the mighty strange Pause Key parsed and + routed to the pause function. (This is also used + internally, as a neat way of telling whatever state + might be active to pause.) + * Touched up the screen framework artwork a little. + * Optimized background rendering some. (Occasional + clipped extra row and column of tiles eliminated.) + * Stupid bug in window_t::invalidate() found and + killed: gfxengine_t clips invalidated rects, so we + need to make sure our window is selected! + * window_t now supports background images. clear() + takes an optional SDL_Rect, and blits from the + image, if there is one, or fills with the + background color as in previous versions.) + * Background graphics in the displays and the radar + screen! :-) + * Added dither plugin with hard-coded 2x2 filter. + * Added options to turn dithering off. + * Added kludge for OpenGL cards that can't handle + RGBA8, but turns it into RGBA4, and a switch to + enable it if required. + * sprite: S_BLITMODE_NORMAL renamed S_BLITMODE_AUTO. + (Makes more sense!) + * Option broken_numdia (Broken NumPad Diagonals) + added - I want to use the page up/down keys for + other stuff, even if *some* systems can't decode + the numpad correctly! :-/ + * Added the algorithmically constructed sound + effect "SOUND_LAUNCH". + * Separated the AGW scripting engine core from the + audio engine and made it the "Extensible Embeddable + Language". (a_agw.[ch] now contain only the AGW + extension to EEL.) + * Added the algorithmically constructed sound + effect "SOUND_LAUNCH2", for the "blue balls". + * Fixed some bugs in filemapper_t. + * Any jerking, flickering etc when entering a new + stage should now be *completely* eliminated. I + think... ;-) + * Intro doesn't conflict with stage 100 any more. + * Implemented 2D positional sound effects. :-) + * Added screenshot feature. (OpenGL not implemented, + as the current glSDL cannot read the screen surface.) + Saves BMP only, and is connected to PrintScreen and + SysReq. + * EEL now uses the same callback prototype for all + extensions, whether they are commands, operators + or functions. + * Ported Jeremy Sheeley's player profiles patch + from 0.3, and tweaked the user interface a little. + * Fixed double initialization of the manage object. + * Extended the score file format into a more powerful, + versionned "profile file format". + * file.(h|cpp) and parts of score.(h|cpp) replaced + with pfile.(h|cpp), which implements a generic, + portable "toolkit" for platform independent binary + data file access. + * Added game.(h|cpp), which collects all configurable + game parameters in one place. + * The "speed" parameter is now considered a cheat, + and is no more available from within the game. + * Last player profile is remembered in the config. + * Added optional "Diagonals Emphasis Filter". (I'd + say it only makes control feel sluggish most of the + time, but it might work for someone... I'm open to + suggestions if anyone has an idea for a smarter + filter.) + * Eliminated extra calls to score_manager_t::record(). + * Start level selection in intro mode removed. + * Implemented collision/health system. When two + "collidable" objects collide, the damage of each + object is subtracted from the health of the other. + (Object properties set so that the game will + play exactly like the original with the single + player default settings for the player ship.) + * Turned the "shield = -1" feature into 'shootable'. + * Added health bar. + * Threw in detection and fix to read broken 73 byte + scorefiles from older Win32 versions. (Seems like + the new code works right on Win32 as well, BTW.) + * Various fixes and additions to filemapper_t. + (Scanning multiple directories, most importantly.) + * Removed "./scores" from the SCORES path for now, + as it's actually the same place as the default + score dir on Win32. (You'd get all profiles and + scores twice, that is.) + * Removed "bgm.raw" as it's not used anymore. + * No hyphen before the "pre" from now on! + * glSDL changes: + * Applications can now set the colorkey of + of surface *after* SDL_DisplayFormat() - + although it will just discard the TexInfo, + resulting in the surface being converted + before the first blit, and after every + change in the surface. + * Silly intermediate buffer eliminated in + _DownloadTexture(). + * glSDL automatically stretches resolutions + below 640x480 using an integer factor. + * Audio engine changes: + * Benchmarking tries to use gettimeofday() if + not compiled for x86 CPUs. + * a_tools.h got some cleaning up, some new + macros, and mixing functions optimized with + a Duff's Device variant. + * __mastervol() is obsoleted by the groups, + and was killed to save some cycles. (It ate + almost 1% of my P-III 933!) + * Ditched the "Smart Stereo" Limiter - it's + not loud enough, and should be replaced with + something that drives the signal non-linear + to squeeze more power in when the signal + isn't panned center. + * Dropped the saturating 32->16 bit converter, + and fixed the limiter so that it reliably + *limits* the signal the way it should. + * Limiter does no longer invert the signal. + * Added ACC_PRIORITY. + * Added controls for Channel Inserts. + * Channel default controls (used in DETACH + mode) removed. Just expect channel controls + to stay where you leave them, and + everything should be fine - and faster! + * Implemented dynamic voice allocation. + * ACC_DETACH now effectively means + "polyphonic mode". "Detached" voices are + still owned by the channel that launched + them - but just as before, channel + controls don't affect voices directly after + they're launched. (Even that may change + eventually...) + * Ripped mid.cpp and mid.h from the AdLib FM + player AdPlug 1.1. Started stripping off + the FM stuff and converting it to C and the + "midisock" interface. + * Added primitive VU-meter to the voice mixer. + * Implemented audio_wave_convert(), using the + voice mixer in interpolated 16x oversampled + mode. + * Added simple enhancer and noise gate + functions to the init time wave API. + * Hacked basic polyphony support into a_midicon. + * ACC_RANDTRIG is now *really* a 16:16 fixp + value, to allow finer control of the + randomize depth. (Next, I'll make the section + end marker fixed point, to allow sub sample + accurate loop timing - as well as finer + RETRIG and RANDTRIG control. :-) + * Fabricated a nice 3'rd degree LUT for + various MIDI -> Linear Control mapping. + * Introduced a more solid scheme for keeping + track of allocated voices. + * audio_channel_play() now takes 16:16 linear + pitch and 16:16 volume, instead of the bogus + MIDI format arguments. + * Added audio_wave_filter(). + * DETACH mode split into ADM_POLY and + ADM_FULL, to natively support the slightly + different ways DETACH mode is used by + midicon and for sound effects. + * Added cubic (4-point) interpolation, based + on a formula by Olli Niemitalo. Low freq + sines sound *perfect* - no audible distortion + whatsoever. It sounds great up to 1:1, but + runs into trouble in the upper half of the + octave above 1:1 - linear 2X+ sounds better + from there and up. The best part is that the + CPU usage is somewhere in between linear 2X + and linear 4X on a P-III. + * Volume ramping bug fixed: The "boot strap" + values calculated when starting new voices + were wrong, and resulted in an undesired + fade in over one buffer. + * "Playing" indicator below the per-voice VUs. + * Waveform size restrictions eliminated! (Well, + you'd probably have trouble with 2+ GB on 32 + bit systems... ;-) + * Dynamic voice allocation now always starts + with voice 0 in the first pass, when looking + for unused voices. (The other passes are still + starting at the voice after the last voice + allocated, to favor the "oldest" voice when + there are multiple equivalent choices.) + * Implemented MIDI CCs 120, 121, 123, 126 & 127. + * Added SILENT and RESTING states to the plugin + API, to deal with silent output efficiently. + * Optimized bus handling; now, bus send buffer + clearing and other stuff isn't even considered + unless a bus actually is in use. + * Implemented the Bus Control MIDI CCs. (39...55 + on the first AUDIO_MAX_BUSSES channels.) + * Reverb SNR improved. The internal precision is + now 8 bits higher than that of the I/O, which + produces "perfect" results down to the LSB in + the final output. + * Implemented CCs 88, 89 and 91; "primary bus", + "send bus" and "send level". + * Added SINEMORPH, SPECTRUM, and LSPECTRUM + oscillators. + * Changed ACC_PITCH to fixed point linear freq, + where the integer bits correspond to MIDI + pitch. That is, 60.0 now does what 1.0 used + to do, and to step up one octave, add 12.0 + instead of multiplying by 2.0. + * Various oscillators and stuff added to the + Waveform Construction API. + * Added bandlimiting or oversampling to all + Waveform Construction API oscillators. + * Modulation API cleaned up. + * Voice mixer code cleaned up a bit. + * Voices now use timestamped events for control. + * "Plugin style" API for patches separates the + channel->voice bindings from the engine core. + BENCHMARKING NOTE: Right now it takes 60 seconds to + load and render the 72 AGW sounds I've created + so far. Although most of the code is currently + *very* inefficient, only the SPECTRUM oscillators + are really so slow that it matters. + * Audio Voice Mixer benchmark results, 20020111: + (P-III 933, 48 kHz, 20 ms latency, playing + an 8 kHz 8 bit stereo sample in 32 voices, + compiler optimizations disabled. Unit is percent + of total CPU time.) + ----------------------------------------------- + Very Low: 6.9% + Low: 14.5% + Normal: 10.1% + High: 17.9% + Very High: 136% (overload!) + + (Same, but with gcc/g++ -O3 optimization.) + ----------------------------------------------- + Very Low: 3.5% + Low: 6.5% + Normal: 4.6% + High: 7.9% + Very High: 78% (causes underruns) + + Obviously, on this machine, the "Normal" mode, + which is using plain linear interpolation, is + almost as fast as the "Very Low" mode, whereas + the "Low" mode is more expensive. This is to be + expected from CPUs with fast multiplications. + * Audio Voice Mixer benchmark results, 20020503: + (Same machine, same settings, same test, but with + the new cubic interpolating mixer, internal + fragment size limit, timestamped events etc. With + -O3 optimizations.) + ----------------------------------------------- + Very Low: 4.5% + Low: 6.8% + Normal: 5.5% + High: 8.2% + Very High: 9.5% + + Higher loads occur only when pushing the pitch more + than ~1.5 octaves above fs in "Very High" quality. + (That results in linear interpolation w/ 4x+ + oversampling, which is pretty slow.) + + +*** The Audio Engine: Why the GPLed files? + + The sound code used in Kobo Deluxe was originally written + by Masanao Izumo , for XKobo 1.11+. + Masanao also added the sound effect samples that are still + being used. + + You may have noticed that, while most, if not all of the + current audio engine is new code, which is LGPLed, a few + files (a_globals.[ch] and audio.[ch]) are GPLed, and + contain a copyright notice mentioning Masanao Izumo. + + This effectively means that the whole audio engine has + to be used under the terms of the GPL; not the LGPL. + + As this will probably be too restrective for many of the + users the engine is targetting, I've contacted Masanao + for a resolution, but have yet to receive a response. + + David Olofson + +Kobo Deluxe v0.4-pre6 + * I've compiled with -Wall and nearly all of the + additional warning switches (not activated by -Wall) + to verify all code. Many things that non-gcc + compilers could complain about should be fixed in + this version. + * "Video Driver" option not shown if there's only one + choice. (Which is the case if you build w/o OpenGL.) + * Exit with ESCAPE from config menues fixed - now + cancels any changes and plays the appropriate sfx. + * Solaris package building script 'buildpkg.sh' and + required configure.in fix by Andreas Spångberg added. + * String copy bug in cfgparse.cpp fixed. (Andreas + Spångberg.) + * Switching between windowed and fullscreen modes no + more results the screen being offset. + * Screen centering fixed. + * Border in windowed mode fixed. + * Cleaned up audio config menu, and added volume + controls for sfx, (future) intro music and in-game + music. (Note that the "Master Volume" is still + there, and it's still digital...) + * Icreased the number of volume levels available in + the audio config menu. (Used to be 25% increments.) + * Added redefined() and accept() to config_parser_t. + * Non-interactive widgets handled correctly in menues. + * Added headers to configuration menues. + * Added 'unit' string to ct_spin_t. + * window_t::select() now comes in a private flavor + without checks. + * Config menues now make use of OS_UPDATE_* flags in + addition to the OS_CANCEL tag, to allow instant + effect controls to cancel/undo properly. + * config_form_t now has a virtual member undo_hook() + that's called by undo(). (Used to make ESC exit work.) + * Audio engine changes: + * Channels are separated into voices (mixing) + and channels (control abstraction) levels. + * Groups added for easy channel management. + * The API provides access to channels and + groups, but not direct access to voices. + * All fixed point values are now 16:16. + * API variants with float arguments added. + * AC_DETACH added. (Easy SFX control.) + * Panning/balance control added. + * Added "waves" to get rid of sample pointers. + * AC_SPEED removed. (Obsoleted by the internal + conversion to original wave sample rates.) + * Fixed bug in reverb: Right input missing! + * Another reverb bug: The delay buffer was too + short for >=32000 kHz with the current taps. + * Implemented AC_RETRIG and AC_RANDTRIG. + * Improved resampling frequency accuracy. + * Improved looping accuracy and quality. + * Added MIDI input implementation for OSS and + ALSA raw MIDI interfaces. + * Fixed potential crash bug; mixing buffer + size variable would be wrong if the desired + buffer size couldn't be set! + * Added higher quality voice resamplers. + * sound.[ch] replaced by a_wave.[ch]. + * Auto trig w/ timeout on the oscilloscope. + * 8 & 16 bit mono + 16 bit stereo added. + * Engine code restructured and modularized. + * "Waveform Construction API" added. + * Channel->bus->master mixing architecture. + * FX plugin API added. (Internal, for now.) + * Reverb LPF cutoff made configurable and + independent of the sample rate. + * Added generic "browsing" API to config_parser_t. + * Added a copy of LGPL 2.1, and started sorting out + which licence applies where. (Basically, the old code + is GPL, while most of the new code I've written from + scratch is LGPL.) + * Added window_t::center_token[_fxp]() for nice columns. + * Started documenting a little... + * Added "Audio CPU Load" screen for gcc/x86. (Needs + high resolution timestamping, and I'm using RDTSC for + now.) + * Added text alignment system for the ct_* widgets, to + make use of the new center_token() methods. + * Various tweaks and adjustments. + * Credits updated. + +Kobo Deluxe v0.4-pre5 + * New versioning rules introduced; + * Any -preX suffix should *always* be included + in AM_INIT_AUTOMAKE(). + * No more development snapshots - every package + released has a version number of it's own, + with a -preX suffix if appropriate. + * Surface leak when reloading graphics fixed. + * gfxengine_t::unload() now takes -1 (default) for + unloading all banks. + * gfxengine_t::unload() also destroys SoFont objects! + * Void pointer arithmetics and some bogus braces fixed. + (Thanks, Riki!) + * Moved sound effects out into files. (Raw format for + now, as WAV doesn't support signed 8 bit data...) + * Minor sound code cleanups. + * bgmfile.[ch] removed. (Used to be Linux only anyway...) + * config_parser_t created. (prefs_t is now derived from + that class, and contains no parsing code whatsoever.) + Also eliminates duplication of "command" decoding for + non-config stuff like -showcfg, -debug and -fps. + * SDL_VIDEOEXPOSE is *finally* at least handled! :-) + * Removed gcc-only compiler flags and fixed other stuff + that caused trouble with some compilers. (Thanks to + Andreas Spångberg for the Solaris patch!) + * Menu and state code cleaned up a little. + * Configuration menu split up into Video, Audio, + Controls and Game. + * ct_list_t now interprets change(0) (ie button press + or similar) as change(1), rather than just ignoring + it. + +Kobo Deluxe v0.4-pre4 + * Replaced corrupted README.jp. + * Delayed fps printout to program exit, as some setups + have serious trouble with output to the console while + running the game. + * Fixed a sleeping bug in the gl_blendfunc() wrapper. + * It's now possible to quit gracefully while loading + data. (Check when updating the progress bar.) + * Old style mouse control is back. (Not that I + understand how anyone could play with that... :-) + * Bigger and more visible mouse crosshair. + * Added 'mouse' switch and 'mousemode' variable to + config. (MMD_RELATIVE not yet implemented!) + * Video config cleaned up - unsupported OpenGL + settings removed. + * Radar window code cleaned up and simplified. + * window_t::alloc_color renamed to map_rgb, which is + more appropriate. The new version takes either three + Uint8 components (rather than X style Uint16), or an + Uint32 for "HTML style" hex codes. + * Diagonal rocket sprites lined up with diagonal Kobo + (the player's ship! :-) sprites. (The ship has an + offset of +1 pixel in y in the gfx) + * Added missing (8'th) frame to explosion animation. + * glSDL: + * Some tiling bugs fixed. + * Single tile case optimized. + * Vertical tiling implemented. + * Horizontal and vertical tiling across multiple + textures implemented! (Not both h & v, though.) + * Off-screen blits are culled. + * Benchmark results: + P-III 933, Matrox G400, XFree86 4.1.0-17mdk: + Resolution SDL 2D glSDL ratio + ----------------------------------------------- + 1280x1024 16 60 3.8 + 960x720 28 102 3.6 + 640x480 62 202 3.3 + 320x240 227 205 0.9 + + Note that OpenGL is pumping quite a bit more pixels + than SDL's RLE blitter in this game, due to the alpha + blended window frame. Here are the results with no + frame: + P-III 933, Matrox G400, XFree86 4.1.0-17mdk: + Resolution SDL 2D glSDL ratio + ----------------------------------------------- + 1280x1024 18 93 5.2 + 960x720 32 163 5.1 + 640x480 70 205 2.9 + 320x240 256 205 0.8 + Notice how glSDL appears to win even more in higher + resolutions, while it loses a little to SDL 2D in the + low end, where fill rate becomes next to insignificant + to OpenGL. + +Kobo Deluxe v0.4-pre3 + * Hitting the window close button now causes a "brutal" + quit, just like hitting ctrl-C in the console. + * Mac OS X OpenGL build script fix. + * Now uses SDL_opengl.h if present. (Dunno if the check + is totally portable, though - but if it fail, at least + things shouldn't be worse than with the old way.) + * Implemented tiling of wide surfaces. + * Does *not* support multiple textures, so it + won't help with wide *and* tall surfaces, that + simply won't fit in one texture. (Sorry, + 256x256 people! ;-) + * The rendering loop for tall surface tiling is + missing... (Mostly a matter of cut'n'paste + + search'n'replace.) + * Anyway, this means that Kobo Deluxe now + RENDERS PERFECTLY ON OPENGL! :-) + +Kobo Deluxe v0.4-pre2 + * The glSDL layer: + * Now uses handles instead of pointers! + * Various bugs and stability issues fixed. + --> Still misses vital features. + --> Leaks textures - or at least TexInfos. + * Some double buffer compatibility issues fixed. + * "Stall" when rebuilding menues fixed. + +Kobo Deluxe v0.4-pre1 + * Build with OpenGL on X fixed - without breaking Win32 + and Mac OS X! + * Added dummy score file to keep stupid WinZip from + removing 'scoredir'... + * Added README.jp translated by Tsuyoshi Iguchi (?). + +Kobo Deluxe v0.3 + * Name officially changed to 'Kobo Deluxe' + * Upgraded to sfifo-1.2. + * Various configure script fixes. + * Added README file. + * Updated logo. + * Added filemapper_t, to handle paths on all platforms. + * Rearranged main loop to handle re-initialization. + * Fixed garbage after name in score files. + * Rearranged score management code slightly. + * Added prefs_t, which can parse, read and write options + from/to command line args and files. + * Kobo now tries to save a backup of the user score file + in the user's home dir. + * Cleaned up the game state system a bit, and added + confirmation dialogs before aborting game or quitting + Kobo. + * Added various eye candy. + * Added "Options" page. + * Class myship now releases the player ship object as well + when turned off. (myship, and a bunch of other objects, + won't be destroyed and re-created when reinitializing.) + * Moved graphics/ and audio/ from source to include path. + * Added sound effects to the user interface. + * Added Mac OS X fixes by Max Horn + * Quits on window close event (Max Horn ) + * Paths for Mac OS X bundles added. + * Fixed +/- keys for selecting level. (Thanks Max!) + * Automatic timed logo/highscore switch added. + * Credits screen added. + * Simple scroll text added. + * Win32 and Mac OS X bundle install styles added. + * Added feedback delay based reverb with LP filters. + * Added limiter/AGC with threshold and release params. + * Joystick support; Samuel Hart . + * Filter plugin support added to "sprite". + * Plugins added: rgb8, rgba8, cleanalpha, key2alpha, scale + and displayformat. + * Implemented the "size" feature with three different + scaling filter modes. + * Sprite and tile "palettes" separated for correct scaling. + * Added various "fade out" effects. + * Added "LOADING" screen. + * Added "Screen Buffer Mode" setting with single, double, + semi triple and half buffering modes. (Note that the game + doesn't yet support all of them properly.) + * Added FPS counter. (-fps switch) + * Progress bar while loading and converting data. + * gamestatemanager_t instead of those switch() statements... + * Added "Get Ready" and "Game Over" states. + * Improved filemapper_t and score_t portability. (I think...) + * Removed annoying key state clearing. + * SoFont: + * CleanSurface() now only cleans the top row. + * Fixed rounding when spacer width is odd. + * No testing of '|' (for cursor) if the font + doesn't have it. + * CS engine: + * Freeing free objects won't crash the engine. + * Safer and (probably) faster wrapping code. + * "width" and "height" replace "size" option. + * Cleaned up config_form_t and added a "rebuild" action for + dynamic configuration panels. + * Added config options and gfxengine_t::driver(). (No OpenGL + code yet. OpenGL options hidden in "options".) + * Added a thin black border in windowed mode. + * Proper clipping done by window_t::invalidate() and + gfxengine_t::invalidate(). + * Sprite and text calls for fixed point coordinates added. + * Fixed gfxengine_t::loadrect() - it dropped the RLE! + * Added contrast and offset parameters to cleanalpha plugin. + * Audio engine: + * Added "nearest sample" resampling support. + * Improved sample looping accuracy. + * Added "samplerate" option. + * Random pitch effect on some sound effects. + * Improved pause mode. (Switches to "get ready".) + * BTN_FIRE can now be used to start game from intro. + * Cleanup + fix: SHIPS display is now updated correctly. + * Added quick hack OpenGL rendering layer. (64 bit broken!) + * "Escape" in pause mode now sends you to "Abort Game?". + * Added AdvanceMAME "Scale2x" scaling filter. + * Gave up on Scale2x + fuzziness factor - it just won't work + for 256+ color graphics. (It's still there, though.) + * Added Diamond2x scaling filter - The Best so far! Also + very fast, even without serious optimizations. + * Various scaling filter bug fixes and cleanups. + * C++ extension changed from '.C' to '.cpp'. + * Linux/i586/VGA vidsync hack removed. + * Added main menu with "Start Game!", "Options" etc. + * sprite.c: Size check for loading sprite palettes. + * Added rotating tube effect for menu highlighting. + +*** Name changed to "Kobo Deluxe". + +SKobo v0.2 + * "sprite.c" now uses SDL_DisplayFormatAlpha(). + * Various autoconf checks added and implemented. + * Audio ported to SDL. (OSS support remains.) + * "-latency XXX" argument to set maximum desired audio + latency in milliseconds. Default is 50 ms. + * Added control API to audio engine. (Moved looping there.) + * Initial Win32 support: + * Hacked temporary kludge in score.C + * Added _snprintf define for snprintf() + +SKobo v0.1 update (forgot to mention this...) + * GIMPed new "Kobo Next Generation" logo. + * Added the display_t class, which inherits from window_t, + and forms a display with a caption and text field. + * Added GIMPed framework for the whole screen. + * Re-implemented the "starfield" by grabbing 64 starry + tiles from an XKobo screenshot. + * Centered radar screen vertically, moving "stage" and + "ships" down below the radar screen. + * Added "HIGHSCORE" display. + +SKobo v0.1 + * Removed all X specific code. + * Added graphics and control system code from Project Spitfire. + * Wrote gfxengine_t class. (Control system + video wrapper.) + * Rearranged source tree and switched to autoconf/automake. + * Wrote window_t class. (Clipping, scrolling etc.) + * Fixed some bugs in sprite.c and cs.c. (*heh*) + * Added text using the C++ version of SFont; SoFont. + * Changed audiodev_t to open in nonblocking mode, to avoid the + game going to sleep if the device is busy. SKobo disables + sound FX if the audio device cannot be opened. + * Pixeled new font and GIMPed a temorary logo. + * Added alpha blended frame with rounded corners. + * Added scrolling background (level 20) in intro mode. + * Selecting starting level now shows the selected level in + the radar display and intro screen background. + * Enlarged the core diameter by two pixels. + +*** David Olofson forks from 'V1.11+-do3', and + calls the new branch SKobo, with version numbers starting over + at 0.1. + +V1.11+-do3 + * Cleaned up audio code and API. + * Added sample looping feature. + * Changed mixed fp/integer mixer into integer-only. + * Increased internal mixer level to avoid dropping bits. + * Fixed silly bug from -do2: The original sound was indeed + in stereo! <:*) + +V1.11+-do2 + * Adjusted sound effects reference level. (Louder sfx.) + +V1.11+-do1 + * Ported sound to OSS + * Sound is enabled by default (use -nosound to disable) + * Made audio run asynchronously with lock-free command FIFO + +*** David Olofson picks up XKobo 1.11+ from Izumo, + adding '-doX' to the version code. + +V1.11+ + * SGI sound added. + * Triple size mode added. + +*** Masanao Izumo picks up XKobo 1.11, appending + '+' to the version code. + +V1.11 + * ?? + +V1.10 + * fixed an endianness problem of score files + * secure score files + +V1.9 + * take measure against system calls interrupted by SIGALRM + * '-hiscores' option + * bonus ships + +V1.8 + * add close() in file.C + +V1.7 + * enabled to move on diagonals using the numeric keypad + +V1.6 + * support for Solaris 2 + +V1.5 + * ceased to use semaphores + * fixed a strange usage of setitimer + * '-wait' option + +V1.4 + * '-cheat' option + * enabled to play using a mouse + * enabled to compile with gcc-2.7.0 + +V1.3 + * fixed a bug about '-fit' option + * enabled to select a stage to play + +V1.2 + * support for TrueColor X server + * '-fit' option + * '-doublesize' option + +V1.1 + * first uploaded to tsx-11.mit.edu diff --git a/Info.plist.in b/Info.plist.in new file mode 100644 index 0000000..85b6f39 --- /dev/null +++ b/Info.plist.in @@ -0,0 +1,30 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + @EXEFILE@ + CFBundleGetInfoString + @VERSION@, Copyright 2001 David Olofson + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + @PACKAGE@ + CFBundlePackageType + APPL + CFBundleShortVersionString + @VERSION@ + CFBundleSignature + ???? + CFBundleVersion + @VERSION@ + NSMainNibFile + SDLMain.nib + NSPrincipalClass + NSApplication + NSHumanReadableCopyright + Copyright 2001 David Olofson + + diff --git a/KoboPlayer b/KoboPlayer new file mode 100644 index 0000000000000000000000000000000000000000..6ec74917e2c7e4b2efe45d0cdd1d1e74e7140c03 GIT binary patch literal 100 lcmZQzfB^6Or2K%K#LCnnr~rvnK#;$i2v83rlD_{?005y14Ltw= literal 0 HcmV?d00001 diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..5bb9240 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,110 @@ +if BUILD_MACOSX_BUNDLE +bundle_contents = @PACKAGE@.app/Contents +else +if BUILD_SIMPLE_BUNDLE +bundle_contents = @PACKAGE@ +endif +endif + +kobo_scoredir=@SCOREDIR@ + +INCLUDES = -DKOBO_DATA_DIR=\""@DATADIR@"\" \ + -DKOBO_SCORE_DIR=\""$(kobo_scoredir)"\" \ + -DKOBO_CONFIG_DIR=\""@CONFIGDIR@"\" \ + -DKOBO_CONFIG_FILE=\""@CONFIGFILE@"\" \ + -DSYSCONF_DIR=\""$(sysconfdir)"\" \ + -Isound -Igraphics -Ieel -Idata/sfx @LOCALCFLAGS@ + +SUBDIRS = graphics sound data eel + +bin_PROGRAMS = kobodl + +GRAPHICS_LIB = graphics/libgraphics.a @MATHLIB@ +SOUND_LIB = sound/libsound.a @AUDIO_LIBS@ +EEL_LIB = eel/libeel.a + +kobodl_SOURCES = enemies.cpp enemy.cpp pfile.cpp gamectl.cpp manage.cpp map.cpp \ + myship.cpp radar.cpp random.cpp scenes.cpp score.cpp screen.cpp \ + filemap.cpp prefs.cpp cfgform.cpp options.cpp gamestate.cpp \ + states.cpp form.cpp cfgparse.cpp game.cpp kobo.cpp logger.c \ + dashboard.cpp sound.cpp +kobodl_LDADD = $(GRAPHICS_LIB) $(SOUND_LIB) $(EEL_LIB) + +kobodl_LDFLAGS = -o $(EXEFILE) + +man_MANS = kobodl.6 + +CLEANFILES = $(EXEFILE) Info.plist log.html + +AUTOMAKE_OPTIONS = foreign + +EXTRA_DIST = *.h Info.plist.in KoboPlayer COPYING.LIB *.txt \ + README.jp README.sfont README.xkobo README.xkobo.jp README.osx \ + README.html \ + cfg-work cfg-beta cfg-release cfg-profile cfg-cross-release \ + cfg-work-opt buildpkg.sh kobodl.6 icons.tar.gz + + +if BUILD_MACOSX_BUNDLE + +@PACKAGE@_bundle: ${EXEFILE} + mkdir -p $(bundle_contents)/MacOS + echo "APPL????" > $(bundle_contents)/PkgInfo + $(INSTALL_DATA) Info.plist $(bundle_contents) + $(INSTALL_PROGRAM) ${EXEFILE} $(bundle_contents)/MacOS/ + +install-exec-hook: @PACKAGE@_bundle + rm -rf $(DESTDIR)$(prefix)/@PACKAGE@.app + mkdir -p $(DESTDIR)$(prefix)/ + cp -r @PACKAGE@.app $(DESTDIR)$(prefix)/ + +clean-local: + rm -rf $(bundle_contents) + +else + +if BUILD_SIMPLE_BUNDLE + +@PACKAGE@_bundle: ${EXEFILE} + $(INSTALL_PROGRAM) ${EXEFILE} $(bundle_contents)/ + +install-exec-hook: @PACKAGE@_bundle + rm -rf $(DESTDIR)/$(prefix)/@PACKAGE@ + mkdir -p $(DESTDIR)/$(prefix)/ + cp COPYING @PACKAGE@/COPYING.txt + cp COPYING.LIB @PACKAGE@/COPYING_LIB.txt + cp ChangeLog @PACKAGE@/ChangeLog.txt + cp TODO @PACKAGE@/TODO.txt + cp README @PACKAGE@/README.txt + cp README.jp @PACKAGE@/README_jp.txt + cp README.sfont @PACKAGE@/sfont.txt + cp README.xkobo @PACKAGE@/xkobo.txt + cp README.xkobo.jp @PACKAGE@/xkobo_jp.txt + cp KoboPlayer @PACKAGE@/scores/42 + cp -r @PACKAGE@ $(DESTDIR)/$(prefix)/ + +clean-local: + rm -rf $(bundle_contents) + +else +@PACKAGE@_bundle: + +install-exec-hook: + +clean-local: + +endif + +endif + + +if UNIX_SCOREDIR + +install-data-hook: $(DESTDIR)$(kobo_scoredir) + chmod a+w $(DESTDIR)$(kobo_scoredir) + +else + +install-data-hook: + +endif diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..5f5c6ed --- /dev/null +++ b/Makefile.in @@ -0,0 +1,885 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = . +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +bin_PROGRAMS = kobodl$(EXEEXT) +DIST_COMMON = README $(am__configure_deps) $(srcdir)/Info.plist.in \ + $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(srcdir)/aconfig.h.in $(top_srcdir)/configure COPYING \ + COPYING.LIB ChangeLog TODO acconfig.h compile config.guess \ + config.sub depcomp install-sh missing mkinstalldirs +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno configure.status.lineno +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = aconfig.h +CONFIG_CLEAN_FILES = Info.plist +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man6dir)" +binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +PROGRAMS = $(bin_PROGRAMS) +am_kobodl_OBJECTS = enemies.$(OBJEXT) enemy.$(OBJEXT) pfile.$(OBJEXT) \ + gamectl.$(OBJEXT) manage.$(OBJEXT) map.$(OBJEXT) \ + myship.$(OBJEXT) radar.$(OBJEXT) random.$(OBJEXT) \ + scenes.$(OBJEXT) score.$(OBJEXT) screen.$(OBJEXT) \ + filemap.$(OBJEXT) prefs.$(OBJEXT) cfgform.$(OBJEXT) \ + options.$(OBJEXT) gamestate.$(OBJEXT) states.$(OBJEXT) \ + form.$(OBJEXT) cfgparse.$(OBJEXT) game.$(OBJEXT) \ + kobo.$(OBJEXT) logger.$(OBJEXT) dashboard.$(OBJEXT) \ + sound.$(OBJEXT) +kobodl_OBJECTS = $(am_kobodl_OBJECTS) +am__DEPENDENCIES_1 = graphics/libgraphics.a +am__DEPENDENCIES_2 = sound/libsound.a +am__DEPENDENCIES_3 = eel/libeel.a +kobodl_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ + $(am__DEPENDENCIES_3) +DEFAULT_INCLUDES = -I. -I$(srcdir) -I. +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +SOURCES = $(kobodl_SOURCES) +DIST_SOURCES = $(kobodl_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-exec-recursive install-info-recursive \ + install-recursive installcheck-recursive installdirs-recursive \ + pdf-recursive ps-recursive uninstall-info-recursive \ + uninstall-recursive +man6dir = $(mandir)/man6 +NROFF = nroff +MANS = $(man_MANS) +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + { test ! -d $(distdir) \ + || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr $(distdir); }; } +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AUDIO_LIBS = @AUDIO_LIBS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_MACOSX_BUNDLE_FALSE = @BUILD_MACOSX_BUNDLE_FALSE@ +BUILD_MACOSX_BUNDLE_TRUE = @BUILD_MACOSX_BUNDLE_TRUE@ +BUILD_SIMPLE_BUNDLE_FALSE = @BUILD_SIMPLE_BUNDLE_FALSE@ +BUILD_SIMPLE_BUNDLE_TRUE = @BUILD_SIMPLE_BUNDLE_TRUE@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CONFIGDIR = @CONFIGDIR@ +CONFIGFILE = @CONFIGFILE@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXEFILE = @EXEFILE@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LOCALCFLAGS = @LOCALCFLAGS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MATHLIB = @MATHLIB@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +POW_LIB = @POW_LIB@ +RANLIB = @RANLIB@ +SCOREDIR = @SCOREDIR@ +SDL_CFLAGS = @SDL_CFLAGS@ +SDL_CONFIG = @SDL_CONFIG@ +SDL_LIBS = @SDL_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +UNIX_SCOREDIR_FALSE = @UNIX_SCOREDIR_FALSE@ +UNIX_SCOREDIR_TRUE = @UNIX_SCOREDIR_TRUE@ +VERSION = @VERSION@ +XMKMF = @XMKMF@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +@BUILD_MACOSX_BUNDLE_FALSE@@BUILD_SIMPLE_BUNDLE_TRUE@bundle_contents = @PACKAGE@ +@BUILD_MACOSX_BUNDLE_TRUE@bundle_contents = @PACKAGE@.app/Contents +kobo_scoredir = @SCOREDIR@ +INCLUDES = -DKOBO_DATA_DIR=\""@DATADIR@"\" \ + -DKOBO_SCORE_DIR=\""$(kobo_scoredir)"\" \ + -DKOBO_CONFIG_DIR=\""@CONFIGDIR@"\" \ + -DKOBO_CONFIG_FILE=\""@CONFIGFILE@"\" \ + -DSYSCONF_DIR=\""$(sysconfdir)"\" \ + -Isound -Igraphics -Ieel -Idata/sfx @LOCALCFLAGS@ + +SUBDIRS = graphics sound data eel +GRAPHICS_LIB = graphics/libgraphics.a @MATHLIB@ +SOUND_LIB = sound/libsound.a @AUDIO_LIBS@ +EEL_LIB = eel/libeel.a +kobodl_SOURCES = enemies.cpp enemy.cpp pfile.cpp gamectl.cpp manage.cpp map.cpp \ + myship.cpp radar.cpp random.cpp scenes.cpp score.cpp screen.cpp \ + filemap.cpp prefs.cpp cfgform.cpp options.cpp gamestate.cpp \ + states.cpp form.cpp cfgparse.cpp game.cpp kobo.cpp logger.c \ + dashboard.cpp sound.cpp + +kobodl_LDADD = $(GRAPHICS_LIB) $(SOUND_LIB) $(EEL_LIB) +kobodl_LDFLAGS = -o $(EXEFILE) +man_MANS = kobodl.6 +CLEANFILES = $(EXEFILE) Info.plist log.html +AUTOMAKE_OPTIONS = foreign +EXTRA_DIST = *.h Info.plist.in KoboPlayer COPYING.LIB *.txt \ + README.jp README.sfont README.xkobo README.xkobo.jp README.osx \ + README.html \ + cfg-work cfg-beta cfg-release cfg-profile cfg-cross-release \ + cfg-work-opt buildpkg.sh kobodl.6 icons.tar.gz + +all: aconfig.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +.SUFFIXES: .c .cpp .o .obj +am--refresh: + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign '; \ + cd $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) + +aconfig.h: stamp-h1 + @if test ! -f $@; then \ + rm -f stamp-h1; \ + $(MAKE) stamp-h1; \ + else :; fi + +stamp-h1: $(srcdir)/aconfig.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status aconfig.h +$(srcdir)/aconfig.h.in: $(am__configure_deps) $(top_srcdir)/acconfig.h + cd $(top_srcdir) && $(AUTOHEADER) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f aconfig.h stamp-h1 +Info.plist: $(top_builddir)/config.status $(srcdir)/Info.plist.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ + rm -f "$(DESTDIR)$(bindir)/$$f"; \ + done + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) +kobodl$(EXEEXT): $(kobodl_OBJECTS) $(kobodl_DEPENDENCIES) + @rm -f kobodl$(EXEEXT) + $(CXXLINK) $(kobodl_LDFLAGS) $(kobodl_OBJECTS) $(kobodl_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cfgform.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cfgparse.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dashboard.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enemies.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enemy.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filemap.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/form.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/game.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gamectl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gamestate.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kobo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logger.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/manage.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/map.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/myship.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/options.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pfile.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prefs.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radar.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scenes.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/score.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/screen.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sound.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/states.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.cpp.o: +@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +uninstall-info-am: +install-man6: $(man6_MANS) $(man_MANS) + @$(NORMAL_INSTALL) + test -z "$(man6dir)" || $(mkdir_p) "$(DESTDIR)$(man6dir)" + @list='$(man6_MANS) $(dist_man6_MANS) $(nodist_man6_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ + for i in $$l2; do \ + case "$$i" in \ + *.6*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + case "$$ext" in \ + 6*) ;; \ + *) ext='6' ;; \ + esac; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man6dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man6dir)/$$inst"; \ + done +uninstall-man6: + @$(NORMAL_UNINSTALL) + @list='$(man6_MANS) $(dist_man6_MANS) $(nodist_man6_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ + for i in $$l2; do \ + case "$$i" in \ + *.6*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + case "$$ext" in \ + 6*) ;; \ + *) ext='6' ;; \ + esac; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f '$(DESTDIR)$(man6dir)/$$inst'"; \ + rm -f "$(DESTDIR)$(man6dir)/$$inst"; \ + done + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) aconfig.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) aconfig.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) aconfig.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) aconfig.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(am__remove_distdir) + mkdir $(distdir) + $(mkdir_p) $(distdir)/. + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(mkdir_p) "$(distdir)/$$subdir" \ + || exit 1; \ + distdir=`$(am__cd) $(distdir) && pwd`; \ + top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ + (cd $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$top_distdir" \ + distdir="$$distdir/$$subdir" \ + distdir) \ + || exit 1; \ + fi; \ + done + -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r $(distdir) +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && cd $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}' +distuninstallcheck: + @cd $(distuninstallcheck_dir) \ + && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile $(PROGRAMS) $(MANS) aconfig.h +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man6dir)"; do \ + test -z "$$dir" || $(mkdir_p) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-binPROGRAMS clean-generic clean-local mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +info: info-recursive + +info-am: + +install-data-am: install-man + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-data-hook + +install-exec-am: install-binPROGRAMS + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-exec-hook + +install-info: install-info-recursive + +install-man: install-man6 + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-info-am uninstall-man + +uninstall-info: uninstall-info-recursive + +uninstall-man: uninstall-man6 + +.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \ + check-am clean clean-binPROGRAMS clean-generic clean-local \ + clean-recursive ctags ctags-recursive dist dist-all dist-bzip2 \ + dist-gzip dist-shar dist-tarZ dist-zip distcheck distclean \ + distclean-compile distclean-generic distclean-hdr \ + distclean-recursive distclean-tags distcleancheck distdir \ + distuninstallcheck dvi dvi-am html html-am info info-am \ + install install-am install-binPROGRAMS install-data \ + install-data-am install-data-hook install-exec install-exec-am \ + install-exec-hook install-info install-info-am install-man \ + install-man6 install-strip installcheck installcheck-am \ + installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic maintainer-clean-recursive \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am uninstall-binPROGRAMS uninstall-info-am \ + uninstall-man uninstall-man6 + + +@BUILD_MACOSX_BUNDLE_TRUE@@PACKAGE@_bundle: ${EXEFILE} +@BUILD_MACOSX_BUNDLE_TRUE@ mkdir -p $(bundle_contents)/MacOS +@BUILD_MACOSX_BUNDLE_TRUE@ echo "APPL????" > $(bundle_contents)/PkgInfo +@BUILD_MACOSX_BUNDLE_TRUE@ $(INSTALL_DATA) Info.plist $(bundle_contents) +@BUILD_MACOSX_BUNDLE_TRUE@ $(INSTALL_PROGRAM) ${EXEFILE} $(bundle_contents)/MacOS/ + +@BUILD_MACOSX_BUNDLE_TRUE@install-exec-hook: @PACKAGE@_bundle +@BUILD_MACOSX_BUNDLE_TRUE@ rm -rf $(DESTDIR)$(prefix)/@PACKAGE@.app +@BUILD_MACOSX_BUNDLE_TRUE@ mkdir -p $(DESTDIR)$(prefix)/ +@BUILD_MACOSX_BUNDLE_TRUE@ cp -r @PACKAGE@.app $(DESTDIR)$(prefix)/ + +@BUILD_MACOSX_BUNDLE_TRUE@clean-local: +@BUILD_MACOSX_BUNDLE_TRUE@ rm -rf $(bundle_contents) + +@BUILD_MACOSX_BUNDLE_FALSE@@BUILD_SIMPLE_BUNDLE_TRUE@@PACKAGE@_bundle: ${EXEFILE} +@BUILD_MACOSX_BUNDLE_FALSE@@BUILD_SIMPLE_BUNDLE_TRUE@ $(INSTALL_PROGRAM) ${EXEFILE} $(bundle_contents)/ + +@BUILD_MACOSX_BUNDLE_FALSE@@BUILD_SIMPLE_BUNDLE_TRUE@install-exec-hook: @PACKAGE@_bundle +@BUILD_MACOSX_BUNDLE_FALSE@@BUILD_SIMPLE_BUNDLE_TRUE@ rm -rf $(DESTDIR)/$(prefix)/@PACKAGE@ +@BUILD_MACOSX_BUNDLE_FALSE@@BUILD_SIMPLE_BUNDLE_TRUE@ mkdir -p $(DESTDIR)/$(prefix)/ +@BUILD_MACOSX_BUNDLE_FALSE@@BUILD_SIMPLE_BUNDLE_TRUE@ cp COPYING @PACKAGE@/COPYING.txt +@BUILD_MACOSX_BUNDLE_FALSE@@BUILD_SIMPLE_BUNDLE_TRUE@ cp COPYING.LIB @PACKAGE@/COPYING_LIB.txt +@BUILD_MACOSX_BUNDLE_FALSE@@BUILD_SIMPLE_BUNDLE_TRUE@ cp ChangeLog @PACKAGE@/ChangeLog.txt +@BUILD_MACOSX_BUNDLE_FALSE@@BUILD_SIMPLE_BUNDLE_TRUE@ cp TODO @PACKAGE@/TODO.txt +@BUILD_MACOSX_BUNDLE_FALSE@@BUILD_SIMPLE_BUNDLE_TRUE@ cp README @PACKAGE@/README.txt +@BUILD_MACOSX_BUNDLE_FALSE@@BUILD_SIMPLE_BUNDLE_TRUE@ cp README.jp @PACKAGE@/README_jp.txt +@BUILD_MACOSX_BUNDLE_FALSE@@BUILD_SIMPLE_BUNDLE_TRUE@ cp README.sfont @PACKAGE@/sfont.txt +@BUILD_MACOSX_BUNDLE_FALSE@@BUILD_SIMPLE_BUNDLE_TRUE@ cp README.xkobo @PACKAGE@/xkobo.txt +@BUILD_MACOSX_BUNDLE_FALSE@@BUILD_SIMPLE_BUNDLE_TRUE@ cp README.xkobo.jp @PACKAGE@/xkobo_jp.txt +@BUILD_MACOSX_BUNDLE_FALSE@@BUILD_SIMPLE_BUNDLE_TRUE@ cp KoboPlayer @PACKAGE@/scores/42 +@BUILD_MACOSX_BUNDLE_FALSE@@BUILD_SIMPLE_BUNDLE_TRUE@ cp -r @PACKAGE@ $(DESTDIR)/$(prefix)/ + +@BUILD_MACOSX_BUNDLE_FALSE@@BUILD_SIMPLE_BUNDLE_TRUE@clean-local: +@BUILD_MACOSX_BUNDLE_FALSE@@BUILD_SIMPLE_BUNDLE_TRUE@ rm -rf $(bundle_contents) + +@BUILD_MACOSX_BUNDLE_FALSE@@BUILD_SIMPLE_BUNDLE_FALSE@@PACKAGE@_bundle: + +@BUILD_MACOSX_BUNDLE_FALSE@@BUILD_SIMPLE_BUNDLE_FALSE@install-exec-hook: + +@BUILD_MACOSX_BUNDLE_FALSE@@BUILD_SIMPLE_BUNDLE_FALSE@clean-local: + +@UNIX_SCOREDIR_TRUE@install-data-hook: $(DESTDIR)$(kobo_scoredir) +@UNIX_SCOREDIR_TRUE@ chmod a+w $(DESTDIR)$(kobo_scoredir) + +@UNIX_SCOREDIR_FALSE@install-data-hook: +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/README b/README new file mode 100644 index 0000000..f4e50d6 --- /dev/null +++ b/README @@ -0,0 +1,370 @@ +(This document was generated from the kobodl.6 'man' file.) + + Kobo Deluxe + ----------- + v0.5.1 + + An enhanced port + of the scrolling video game + XKobo + +DESCRIPTION + Kobo Deluxe is a 3'rd person scrolling 2D shooter with a simple and + responsive control system - which you'll need to tackle the tons of + enemy ships that shoot at you, chase you, circle around you shooting, + or even launch other ships at you, while you're trying to destroy the + labyrinth shaped bases. There are 50 action packed levels with smoothly + increasing difficulty, and different combinations of enemies that + require different tactics to be dealt with successfully. + + Kobo Deluxe has an improved graphics engine that delivers smoother ani- + mation, while keeping the game logic totally accurate and predictable + regardless of frame rate. It also adds sound effects, new graphics, + fullscreen mode, four extra skill levels with smoother gameplay and + various other features expected from a modern game. (There is still a + "Clasic" mode that plays exactly like the original XKobo.) + + Kobo Deluxe uses SDL for sound, graphics and input, and builds and runs + on all major operating systems, as well as some more unusual platforms. + It can also use OpenGL for accelerated rendering, through glSDL. + + In short, Kobo Deluxe is loads of classical arcade style fun for just + about any machine with graphics and sound! + +CONTROLS + The ship can be controlled with the keyboard, or optionally a mouse or + joystick. With the keyboard, the arrow keys move the ship (two keys for + diagonals), and the shift and ctrl keys shoots. The numeric key pad can + also be used; the usual 2/4/6/8 (arrows), and also 1/3/7/9 for single + key diagonals. Escape enters the meny system, from where it is possi- + ble to change settings, start a new game or exit the game. + +OPTIONS + Note that all relevant options can be also configured in the config + file, which can be edited directly, or using the options menus in the + game. + + -[no]logfile + Log To File. Default: Off. + + -logformat + Log File Format. Default: 0. + + -logverbosity + Log Verbosity Level. Default: 2. + + -[no]joystick + Use Joystick. Default: Off. + + -joystick_no + Joystick Number. Default: 0. + + -[no]mouse + Use Mouse. Default: Off. + + -mousemode + Mouse Control Mode. Default: 1. + + -[no]broken_numdia + Broken NumPad Diagonals. Default: Off. + + -dia_emphasis + Diagonals Emphasis Filter. Default: 0. + + -[no]always_fire + Always Fire. Default: Off. + + -[no]mousecapture + In-game Mouse Capture. Default: On. + + -scrollradar + Radar Scroll Mode. Default: 2. + + -[no]filter + Enable/disable motion interpolation. Interpolation is what makes + animation smooth at high frame rates despite the game logic run- + ning at 33.33 fps. However, it also adds some input latency! + Default: On. + + -timefilter + Time filter, for smoothing out timing jitter induced by the + operating system. Default: 50. + + -countdown + Get Ready Countdown. Default: 5. + + -starfield + Starfield Style. Default: 2. + + -stars Number of Parallax Stars. Default: 500. + + -overheatloud + Overheat Warning Loudness. Default: 100. + + -cannonloud + Player Cannons Loudness. Default: 100. + + -[no]sound + Enable Sound. Default: On. + + -[no]music + Enable Music. Default: On. + + -[no]cached_sounds + Use Cached Sounds. Default: Off. + + -[no]oss + Use OSS Sound Driver. Default: Off. + + -samplerate + Sample Rate. Default: 44100. + + -latency + Sound Latency. Default: 50. + + -mixquality + Mixing Quality. Default: 3. + + -vol Master Volume. Default: 100. + + -intro_vol + Intro Music Volume. Default: 100. + + -sfx_vol + Sound Effects Volume. Default: 100. + + -music_vol + In-Game Music Volume. Default: 50. + + -reverb + Reverb Level. Default: 100. + + -vol_boost + Volume Boost. Default: 0. + + -[no]fullscreen + Fullscreen Display. Default: Off. + + -videodriver + Display Driver. Default: 0. + + -width Horizontal Resolution. Default: 640. + + -height + Vertical Resolution. Default: 480. + + -aspect + Pixel Aspect Ratio. Default: 1000. + + -depth Display Depth. Default: 0. + + -maxfps + Limit the framerate (fps). Saves power on laptops (75 works + well), and can also avoid long stalls due to timesharing and + background processes. Default: 100. + + -maxfpsstrict + Strictly Regulated fps. Default: 0. + + -buffer + Display Buffer Mode. Default: 1. + + -[no]shadow + Use Software Shadow Buffer. Default: On. + + -videomode + Video Mode. Default: 17200. + + -[no]vsync + Enable Vertical Sync. Default: On. + + -videopages + Number of Video Pages. Default: -1. + + -scalemode + Scaling Filter Mode. Default: 1. + + -[no]dither + Use Dithering. Default: On. + + -dither_type + Dither Type. Default: 0. + + -[no]broken_rgba8 + Broken RGBA (OpenGL). Default: Off. + + -[no]alpha + Use Alpha Blending. Default: On. + + -brightness + Brightness. Default: 100. + + -contrast + Contrast. Default: 100. + + -files Specify the root path of the game. Default: "" + + -gfx Specify the path to the game's graphics data. Default: "" + + -sfx Specify the path to the game's sound data. Default: "" + + -scores + Specify the path to the game's score files. Default: "" + + -size (Not saved!) Screen Size (Obsolete). Default: 0. + + -wait Game Speed (Obsolete). Default: 30. + + -bgm (Not saved!) Background Music File (Obsolete). Default: "" + + -threshold + (Not saved!) Limiter Gain. Default: 200. + + -release + (Not saved!) Limiter Speed. Default: 50. + + -internalres + (Not saved!) Texture Resolution. Default: 1. + + -last_profile + Last used player profile. Default: 0. + + -number_of_joysticks + Number of Connected Joysticks. Default: 0. + + -[no]showcfg + (Not saved!) Show Configuration. Default: Off. + + -[no]hiscores + (Not saved!) List High Scores. Default: Off. + + -[no]highscores + (Not saved!) List High Scores. Default: Off. + + -[no]override + (Not saved!) Ignore Configuration File. Default: Off. + + -[no]debug + (Not saved!) Enable Debug Features. Default: Off. + + -[no]fps + (Not saved!) Display frames per second in game screen. Default: + Off. + + -[no]noframe + (Not saved!) Do not render rounded corners on the playfield. + Default: Off. + + -[no]midi + (Not saved!) Enable MIDI Input. Default: Off. + + -[no]cheat + (Not saved!) Enable/disable cheat mode. Cheat mode allows any + level to be played, but highscores are not saved! Default: Off. + + -[no]indicator + (Not saved!) Enable Collision Indicator Mode. Default: Off. + + -[no]pushmove + (Not saved!) Enable Push Move Mode. Default: Off. + + -[no]noparachute + (Not saved!) Disable SDL Parachute. Default: Off. + + -[no]pollaudio + (Not saved!) Use Polling Audio Output. Default: Off. + + -[no]autoshot + (Not saved!) Ingame screenshots/movie. Default: Off. + + -[no]help + (Not saved!) Print usage info and exit. Default: Off. + + -[no]options_man + (Not saved!) Print options for 'man'. Default: Off. + +FILES + ~/.kobodlrc + The per-user configuration file for Kobo Deluxe. + +AUTHORS + Originally written by Akira Higuchi (a-higuti@math.hokudai.ac.jp), + XKobo was turned into Kobo Deluxe by David Olofson + +THANKS + Thanks, in no particular order, to... + + Akira Higuchi + Author of the Original XKobo. + + Masanao Izumo + Sound effects and original sound engine. + + Torsten Giebl + Slackware. + + David Andersson + Various Good Ideas. + + Max Horn + Mac OS X & Build Script Patches. + + Jeremy Sheeley + Player Profiles. + + Tsuyoshi Iguchi + FreeBSD, NetBSD. + + Samuel Hart + Joystick Support. + + G. Low Solaris. + + Gerry Jo Trick Jellestad + Testing and ideas. + + Riki Intel Compiler. + + Andreas Spaangberg + Sun Compiler & Bug Spotting. + + SixK Amiga Port. + + Joey Hess + Debian. + + Martijn van Oosterhout + FPS limiter. + + Antonio Messina + Stage 1601+ difficulty wrap, Always Fire option. + + Hans de Goede + Audio buffer handling bug. + + Marianne Ibbotson + "Autopause" idea. + + Sam Palmer + MS Windows testing. + + Michael Sterrett + glSDL issues. + + Sam Lantinga & Others + SDL, the Simple DirectMedia library. + + Members of the SDL mailing list + Testing and ideas. + +COPYRIGHT + Copyright (c) 1995, 1996 Akira Higuchi + Copyright (C) 1997 Masanao Izumo + Copyright (C) 1999-2001 Simon Peter + Copyright (C) 2002 Florian Schulze + Copyright (C) 2002 Jeremy Sheeley + Copyright (C) 2005 Erik Auerswald + Copyright (c) 1999-2007 David Olofson + + Kobo Deluxe is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License. diff --git a/README.html b/README.html new file mode 100644 index 0000000..af62b8b --- /dev/null +++ b/README.html @@ -0,0 +1,803 @@ + + + + + + + + + +KOBODL + + + + +

KOBODL

+ +NAME
+SYNOPSIS
+DESCRIPTION
+CONTROLS
+OPTIONS
+FILES
+AUTHORS
+THANKS
+COPYRIGHT
+ +
+ + + +

NAME

+ + +

kobodl - Kobo +Deluxe, an enhanced version of the scrolling game XKobo

+ + +

SYNOPSIS

+ + +

kobodl [ +options ]

+ + +

DESCRIPTION

+ + +

Kobo Deluxe is +a 3’rd person scrolling 2D shooter with a simple and +responsive control system - which you’ll need to +tackle the tons of enemy ships that shoot at you, chase you, +circle around you shooting, or even launch other ships at +you, while you’re trying to destroy the labyrinth +shaped bases. There are 50 action packed levels with +smoothly increasing difficulty, and different combinations +of enemies that require different tactics to be dealt with +successfully.

+ +

Kobo Deluxe has +an improved graphics engine that delivers smoother +animation, while keeping the game logic totally accurate and +predictable regardless of frame rate. It also adds sound +effects, new graphics, fullscreen mode, four extra skill +levels with smoother gameplay and various other features +expected from a modern game. (There is still a +"Clasic" mode that plays exactly like the original +XKobo.)

+ +

Kobo Deluxe +uses SDL for sound, graphics and input, and builds and runs +on all major operating systems, as well as some more unusual +platforms. It can also use OpenGL for accelerated rendering, +through glSDL.

+ +

In short, Kobo +Deluxe is loads of classical arcade style fun for just about +any machine with graphics and sound!

+ + +

CONTROLS

+ + +

The ship can be +controlled with the keyboard, or optionally a mouse or +joystick. With the keyboard, the arrow keys move the ship +(two keys for diagonals), and the shift and ctrl keys +shoots. The numeric key pad can also be used; the usual +2/4/6/8 (arrows), and also 1/3/7/9 for single key diagonals. +Escape enters the meny system, from where it is possible to +change settings, start a new game or exit the game.

+ + +

OPTIONS

+ + +

Note that all +relevant options can be also configured in the config file, +which can be edited directly, or using the options menus in +the game.
+−[no]logfile

+ +

Log To File. Default: Off.

+ +

−logformat

+ +

Log File Format. Default: +0.

+ +

−logverbosity

+ +

Log Verbosity Level. Default: +2.

+ +

−[no]joystick

+ +

Use Joystick. Default: Off.

+ +

−joystick_no

+ +

Joystick Number. Default: +0.

+ +

−[no]mouse

+ +

Use Mouse. Default: Off.

+ +

−mousemode

+ +

Mouse Control Mode. Default: +1.

+ + +

−[no]broken_numdia

+ +

Broken NumPad Diagonals. +Default: Off.

+ +

−dia_emphasis

+ +

Diagonals Emphasis Filter. +Default: 0.

+ + +

−[no]always_fire

+ +

Always Fire. Default: Off.

+ + +

−[no]mousecapture

+ +

In-game Mouse Capture. Default: +On.

+ +

−scrollradar

+ +

Radar Scroll Mode. Default: +2.

+ +

−[no]filter

+ +

Enable/disable motion +interpolation. Interpolation is what makes animation smooth +at high frame rates despite the game logic running at 33.33 +fps. However, it also adds some input latency! Default: +On.

+ +

−timefilter

+ +

Time filter, for smoothing out +timing jitter induced by the operating system. Default: +50.

+ +

−countdown

+ +

Get Ready Countdown. Default: +5.

+ +

−starfield

+ +

Starfield Style. Default: +2.

+ + + + + + + + +
+ + + +

−stars

+ + +

Number of Parallax +Stars. Default: 500.

+
+ +

−[no]sound

+ +

Enable Sound. Default: On.

+ +

−[no]music

+ +

Enable Music. Default: On.

+ + +

−[no]cached_sounds

+ +

Use Cached Sounds. Default: +Off.

+ +

−[no]oss

+ +

Use OSS Sound Driver. Default: +Off.

+ +

−samplerate

+ +

Sample Rate. Default: +44100.

+ +

−latency

+ +

Sound Latency. Default: 50.

+ +

−mixquality

+ +

Mixing Quality. Default: 3.

+ + + + + + + + +
+ + + +

−vol

+ + +

Master Volume. +Default: 100.

+
+ +

−intro_vol

+ +

Intro Music Volume. Default: +100.

+ +

−sfx_vol

+ +

Sound Effects Volume. Default: +100.

+ +

−music_vol

+ +

In-Game Music Volume. Default: +50.

+ +

−reverb

+ +

Reverb Level. Default: 100.

+ +

−vol_boost

+ +

Volume Boost. Default: 0.

+ + +

−[no]fullscreen

+ +

Fullscreen Display. Default: +Off.

+ +

−videodriver

+ +

Display Driver. Default: 0.

+ + + + + + + + +
+ + + +

−width

+ + +

Horizontal +Resolution. Default: 640.

+
+ +

−height

+ +

Vertical Resolution. Default: +480.

+ +

−aspect

+ +

Pixel Aspect Ratio. Default: +1000.

+ + + + + + + + +
+ + + +

−depth

+ + +

Display Depth. +Default: 0.

+
+ +

−maxfps

+ +

Limit the framerate (fps). +Saves power on laptops (75 works well), and can also avoid +long stalls due to timesharing and background processes. +Default: 100.

+ +

−maxfpsstrict

+ +

Strictly Regulated fps. +Default: 0.

+ +

−buffer

+ +

Display Buffer Mode. Default: +1.

+ +

−[no]shadow

+ +

Use Software Shadow Buffer. +Default: On.

+ +

−videomode

+ +

Video Mode. Default: 17200.

+ +

−[no]vsync

+ +

Enable Vertical Sync. Default: +On.

+ +

−videopages

+ +

Number of Video Pages. Default: +-1.

+ +

−scalemode

+ +

Scaling Filter Mode. Default: +1.

+ +

−[no]dither

+ +

Use Dithering. Default: On.

+ +

−dither_type

+ +

Dither Type. Default: 0.

+ + +

−[no]broken_rgba8

+ +

Broken RGBA (OpenGL). Default: +Off.

+ +

−[no]alpha

+ +

Use Alpha Blending. Default: +On.

+ +

−brightness

+ +

Brightness. Default: 100.

+ +

−contrast

+ +

Contrast. Default: 100.

+ + + + + + + + + + + + + + + + + +
+ + + +

−files

+ + +

Specify the root +path of the game. Default: ""

+ + + +

−gfx

+ + +

Specify the path to +the game’s graphics data. Default: ""

+ + + +

−sfx

+ + +

Specify the path to +the game’s sound data. Default: ""

+ +

−scores

+ +

Specify the path to the +game’s score files. Default: ""

+ + + + + + + + + + + + + + + + + +
+ + + +

−size

+ + +

(Not saved!) Screen +Size (Obsolete). Default: 0.

+ + + +

−wait

+ + +

Game Speed +(Obsolete). Default: 30.

+ + + +

−bgm

+ + +

(Not saved!) +Background Music File (Obsolete). Default: ""

+ +

−threshold

+ +

(Not saved!) Limiter Gain. +Default: 200.

+ +

−release

+ +

(Not saved!) Limiter Speed. +Default: 50.

+ +

−internalres

+ +

(Not saved!) Texture +Resolution. Default: 1.

+ +

−last_profile

+ +

Last used player profile. +Default: 0.

+ + +

−number_of_joysticks

+ +

Number of Connected Joysticks. +Default: 0.

+ +

−[no]showcfg

+ +

(Not saved!) Show +Configuration. Default: Off.

+ +

−[no]hiscores

+ +

(Not saved!) List High Scores. +Default: Off.

+ + +

−[no]highscores

+ +

(Not saved!) List High Scores. +Default: Off.

+ +

−[no]override

+ +

(Not saved!) Ignore +Configuration File. Default: Off.

+ +

−[no]debug

+ +

(Not saved!) Enable Debug +Features. Default: Off.

+ +

−[no]fps

+ +

(Not saved!) Display frames per +second in game screen. Default: Off.

+ +

−[no]noframe

+ +

(Not saved!) Do not render +rounded corners on the playfield. Default: Off.

+ +

−[no]midi

+ +

(Not saved!) Enable MIDI Input. +Default: Off.

+ +

−[no]cheat

+ +

(Not saved!) Enable/disable +cheat mode. Cheat mode allows any level to be played, but +highscores are not saved! Default: Off.

+ + +

−[no]indicator

+ +

(Not saved!) Enable Collision +Indicator Mode. Default: Off.

+ +

−[no]pushmove

+ +

(Not saved!) Enable Push Move +Mode. Default: Off.

+ + +

−[no]noparachute

+ +

(Not saved!) Disable SDL +Parachute. Default: Off.

+ + +

−[no]pollaudio

+ +

(Not saved!) Use Polling Audio +Output. Default: Off.

+ +

−[no]autoshot

+ +

(Not saved!) Ingame +screenshots/movie. Default: Off.

+ +

−[no]help

+ +

(Not saved!) Print usage info +and exit. Default: Off.

+ + +

−[no]options_man

+ +

(Not saved!) Print options for +’man’. Default: Off.

+ + +

FILES

+ + + +

~/.kobodlrc

+ +

The per-user configuration file +for Kobo Deluxe.

+ + +

AUTHORS

+ + +

Originally +written by Akira Higuchi (a-higuti@math.hokudai.ac.jp), +XKobo was turned into Kobo Deluxe by David Olofson +<david@olofson.net>

+ + +

THANKS

+ + +

Thanks, in no +particular order, to...
+Akira Higuchi

+ +

Author of the Original +XKobo.

+ +

Masanao Izumo

+ +

Sound effects and original +sound engine.

+ +

Torsten Giebl

+ +

Slackware.

+ +

David Andersson

+ +

Various Good Ideas.

+ +

Max Horn

+ +

Mac OS X & Build Script +Patches.

+ +

Jeremy Sheeley

+ +

Player Profiles.

+ +

Tsuyoshi Iguchi

+ +

FreeBSD, NetBSD.

+ +

Samuel Hart

+ +

Joystick Support.

+ + + + + + + + +
+ + +

G. Low

+ + +

Solaris.

+
+ +

Gerry Jo Trick +Jellestad

+ +

Testing and ideas.

+ + + + + + + + +
+ + +

Riki

+ + +

Intel Compiler.

+
+ +

Andreas Spaangberg

+ +

Sun Compiler & Bug +Spotting.

+ + + + + + + + +
+ + +

SixK

+ + +

Amiga Port.

+
+ +

Joey Hess

+ +

Debian.

+ +

Martijn van +Oosterhout

+ +

FPS limiter.

+ +

Antonio Messina

+ +

Stage 1601+ difficulty wrap, +Always Fire option.

+ +

Hans de Goede

+ +

Audio buffer handling bug.

+ +

Marianne Ibbotson

+ +

"Autopause" idea.

+ +

Sam Palmer

+ +

MS Windows testing.

+ +

Michael Sterrett

+ +

glSDL issues.

+ +

Sam Lantinga & +Others

+ +

SDL, the Simple DirectMedia +library.

+ +

Members of the SDL mailing +list

+ +

Testing and ideas.

+ + +

COPYRIGHT

+ + +

Copyright (c) +1995, 1996 Akira Higuchi

+ +

Copyright (C) +1997 Masanao Izumo

+ +

Copyright (C) +1999-2001 Simon Peter

+ +

Copyright (C) +2002 Florian Schulze

+ +

Copyright (C) +2002 Jeremy Sheeley

+ +

Copyright (C) +2005 Erik Auerswald

+ +

Copyright (c) +1999-2007 David Olofson

+ +

Kobo +Deluxe is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public +License.

+
+ + diff --git a/README.jp b/README.jp new file mode 100644 index 0000000..942edd0 --- /dev/null +++ b/README.jp @@ -0,0 +1,46 @@ + + Kobo Deluxe + ----------- + v0.4 + + $B%7%e!<%F%#%s%0%2!<%`(B XKobo$B$N6/2=HG(B + +Kobo Deluxe $B$OBh;0e>:$7!"E(5!$NAH$_9g$o$;$,JQ2=$7$^$9!#$&$^$/@Z$jH4$1$k(B +$B$?$a$K$O$=$NETEYE*3N$J@oN,$rI,MW$H$7$^$9!#(B + +Kobo Deluxe$B$O%0%i%U%#%C%/%(%s%8%s$r?J2=$5$;!"%2!<%`$N?J9T$d%?%$(B +$B%_%s%0$K0MB8$7$J$$=@Fp$J%U%l!<%`%l!<%H@_Dj$r2DG=$H$7$F$$$^$9!#$^$?!"(B +$B8z2L2;!"GIe$GF0:n$7$^$9!#$"$^$j0lHLE*$G$O$J%W%i%C%H%[!<%`$G$bF0:n$9$k(B +$B$+$b$7$l$^$;$s!#(B + +$B$R$H$3$H$G8@$&$J$i!"(BKobo Deluxe$B$O%/%i%7%C%/$J%"!<%1!<%I%9%?%$%k$N(B +$B%2!<%`$r!"MM!9$J4D6-$N%^%7%s$GM7$Y$k$h$&$K$7$?$H$$$&$3$H$G$9!#(B + + Enjoy...! + + David Olofson + http://olofson.net + + +Thanks to: + Akira Higuchi ($B%*%j%8%J%kHG(BXKobo$B$N:n------------------------------------ + +License: GPL +Author: Karl Bartel +WWW: http://members.linuxstart.com/~karlb/ + +Usage: + 1. Load a font and place it in an SDL_Surface *. If your are using the + SDL_image library you can do this with Font=IMG_Load("filename"); + 2. Initialize the font by using InitFont(surface *Font); + 3. Now you can use the font in you SDL program. + Please take a look at SFont.h to get info about the funtions. + +FileFormat: + The font file can be any type image file. The characters start with + ASCII symbol #33. They are seperated by pink(255,0,255) lines at the top + of the image. The space between these lines is the width of the caracter. + Just take a look at the font, and you'll be able to understand what I tried + to explain here. + The easiest way to create a new font is to use the GIMP's Logo function. + Use the following string as text (ASCII 33-127 with escape sequences and + spaces between the letters): + ! \" # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \\ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ + +Example for the font file format: + +____ _____ _____ _____ <- This is the pink line at the top + + # ##### #### + # # # # # + # # # # # + # # ##### # + ##### # # # + # # # # # + # # ##### #### + + |----| + Width of the character + + |----------| +Part of the font surface that is beeing blitted + + +ChangeLog: +2.0 beta + *** Added SoFont, a C++ version of SFont *** + Added lock and unlock for hardware surfaces + Added blinking cursor to SFont_Input + Added check for ASCII<33 in SFont_Input + TextWidth returned a too highh value -> fixed + +1.4 + Added support for multiple fonts in one program + Add a missing "*" in the SFont.h file + Proper '\0' at the end of stings produced by SFont_Input + Fixed problems in SFont_Input, which were creating '\b' in the string + Fixed two other bugs in SFont_Input + Added the SFontViewer adn new test programs + +1.3 + Fixed three wrong interpretations of the file format + o wrong division (float had to be used) + o detection of right ends of pink lines (were one pixel too far right) + o blit destination (all blits were too far right) + support for non-alpha mapped fonts + some fonts updated + +1.2 + added XCenteredString + +1.1 + renamed font.c to SFont.c and font.h to SFont.h + better Makefile +1.0 + Added the Input function + Added a check wether the Font has been loaded +0.9 + better Makefile for the example (using sdl-config) + better Neon Font +0.8 + First Release + +If you have any Questions please write a mail! + +Karl \ No newline at end of file diff --git a/README.xkobo b/README.xkobo new file mode 100644 index 0000000..746ecf4 --- /dev/null +++ b/README.xkobo @@ -0,0 +1,146 @@ + +------------------------------------------------------------------------- + + __ __ + \ \ / / + \ \/ / ## ## #### ##### #### + \ / ## ## ## ## ## ## ## ## + / \ #### ## ## ##### ## ## + / /\ \ ## ## ## ## ## ## ## ## + / / \ \ ## ## #### ##### #### + /_/ --' + Version 1.11+-do3 + + by + + Akira Higuchi + + + sound effects and other enhancements + Masanao Izumo + + improved OSS sound engine + David Olofson + +------------------------------------------------------------------------- + +* DESCRIPTION + Xkobo is a single player action game. The play is quite + simple. Your object is to destroy all the fortresses. You + can control your ship by pressing the cursor keys (or mov- + ing the mouse cursor), and shot beams by pressing the + SHIFT key (or the left mouse button). The game can be + paused by pressing 's' (or the right mouse button). + +------------------------------------------------------------------------- + +* REQUIREMENT + Xkobo requires: + 1) Unix (BSD, Linux, etc.) + 2) X window system (256 colors or greater) + 3) OSS compatible sound system (8 kHz, 16 bit stereo) + 4) C++ compiler + + Xkobo is known to compile and run under the following systems: + * Linux + * Sun-OS 4.1.4 + * BSD/OS + * Solaris 2.4 (Sparc) + * HP-UX 9.05 + +------------------------------------------------------------------------- + +* INSTALLING + Edit Imakefile (if you need) and run + + % xmkmf -a + % make + % su + # make install + # make install.man + +------------------------------------------------------------------------- + +* OPTIONS + -display displayname + This option specifies the name of the X server to use. + + -fit + This option causes xkobo to use the default colormap. + Without this option, xkobo uses a private colormap. + + -wait value + This option specifies the speed of the game. The + default value is 30(msec). + + -doublesize + This option causes xkobo to enlarge the size of the + window. But it costs HUGE memory. + + -fast + This option causes xkobo to use a faster algorithm. But + it costs much memory. + + -cheat + Cheat mode. It allows any level to be played, does not + update score table. + + -hiscores + Print the high score table to standard out, and exit. + + -sound + Enable sound effects. (Default.) + + -nosound + Disable sound effects. + + -vol value + Set sound effects volume to value. Default is 100. + +FIXME: Some options aren't translated from README.jp. + +------------------------------------------------------------------------- + +* THANKS TO ... + + Bruce Cheng + Christoph Lameter + Davide Rossi + Eduard Martinescu + Elan Feingold + Helmut Hoenig + Jeff Epler + Joe Ramey + Joey Hess + Michael Sterrett + Mihail Iotov + Shoichi Nakayama + Thomas Marsh + Torsten Wolnik + +* David's Thanks To... + + Akira Higuchi (original Xkobo) + Masanao Izumo (sound effects) + +========================================================================= + + XKOBO, a video-oriented game + Copyright (C) 1995,1996 Akira Higuchi + a-higuti@math.hokudai.ac.jp + + 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., + 675 Mass Ave, Cambridge, MA 02139, USA. + +========================================================================= diff --git a/README.xkobo.jp b/README.xkobo.jp new file mode 100644 index 0000000..4b16123 --- /dev/null +++ b/README.xkobo.jp @@ -0,0 +1,139 @@ + +------------------------------------------------------------------------- + + XKOBO Version 1.11+-do3 + + Fri Jan 10 11:17:50 JST 1997 Akira Higuchi + a-higuti@math.hokudai.ac.jp + +------------------------------------------------------------------------- + +* DESCRIPTION + + Xkobo $B$O#1?MMQ$N%"%/%7%g%s%2!<%`$G$9!#@N$N%J%`%3$N%2!<%`(B Bosconian + $B$K;w$F$$$^$9!#%k!<%k$OC1=c$G!"<+5!$rA`$C$F2hLL>e$K$"$kMW:I$rA4$FGK(B + $B2u$9$k$3$H$,%2!<%`$NL\E*$G$9!#(B + +------------------------------------------------------------------------- + +* REQUIREMENT + + Xkobo $B$r%3%s%Q%$%k!?eI=<($G$-$k(B X $B%5!<%P(B) + 3) C++ $B%3%s%Q%$%i(B + + Xkobo $B$O>/$J$/$H$b0J2<$N%7%9%F%`$GF0:n$7$^$9!#(B + + * Linux + * Sun-OS 4.1.4 + * BSD/OS + * Solaris 2.4 (Sparc) + * HP-UX 9.05 + +------------------------------------------------------------------------- + +* INSTALLING + + $B$b$7I,MW$J$i(B Imakefile $B$rJT=8$7$F$+$i!"e$G%3%s%Q%$%k$,40N;$G$9!#$b$7$"$J$?$,(B root $B$K$J$l$k$J$i!"/$J$$$H!"(Bxkobo $B$N(B + $B1GA|$N?'$,JQ$K$J$k$3$H$,$"$j$^$9!#$3$l$r;XDj$7$J$+$C$?$i!"%W(B + $B%i%$%Y!<%H%+%i!<%^%C%W$r;HMQ$7$^$9!#(B + $BCm!'(Bsgi $BMQ$K%O%C%/$7$?$3$N%P!<%8%g%s$G$O!$$3$N%*%W%7%g%s$O$"(B + $B$j$^$;$s!%(B + + -wait value + $B%2!<%`$N%9%T!<%I$r;XDj$7$^$9!#$3$N%*%W%7%g%s$G;XDj$7$J$1$l$P!"(B + 40$B!J%_%jIC!KKh$K2hLL$,%"%C%W%G!<%H$5$l$^$9!#(B + + -doublesize + $B2hLL$N%5%$%:$,=D2#$=$l$>$l#2G\$K$J$j$^$9!#$?$@!";HMQ$9$k%a%b(B + $B%j$NNL$,Ls#4G\!*$K$J$j$^$9!#(B + + -tetrasize + $B2hLL$N%5%$%:$,=D2#$=$l$>$l#4G\$K$J$j$^$9!#$?$@!";HMQ$9$k%a%b(B + $B%j$NNL$,Ls#1#6G\!*$K$J$j$^$9!#(B + + -fast + $BB.$$%"%k%4%j%:%`$r;HMQ$7$^$9!#%a%b%j$N;HMQNL$OA}$($^$9!#(B + + -cheat + $B%A%c%C%H!&%b!<%I$Gr7o2<$G$N2~B$!?:FG[I[$,2DG=(B + $B$G$9!#>\$7$/$O(B COPYING $B$r$_$F$/$@$5$$!#(B + + $B5l%P!<%8%g%s$KB8:_$7$?(B Towns PAD $BBP1~$O:o=|$7$^$7$?!#JL$N%W%m%0%i%`(B + xpadtrans $B$r;H$($P(B Towns PAD $B$GA`:n$G$-$k$h$&$K$J$j$^$9!#>\$7$/$O!"(B + http://www.math.hokudai.ac.jp/~a-higuti/ + http://seki.math.hokudai.ac.jp:20080/ + $B$"$?$j$rGA$$$F$_$F2<$5$$!#(B + +------------------------------------------------------------------------- + +* THANKS TO ... + + Bruce Cheng + Christoph Lameter + Davide Rossi + Eduard Martinescu + Elan Feingold + Helmut Hoenig + Jeff Epler + Joe Ramey + Joey Hess + Michael Sterrett + Mihail Iotov + Shoichi Nakayama + Thomas Marsh + Torsten Wolnik + diff --git a/TODO b/TODO new file mode 100644 index 0000000..c4759c5 --- /dev/null +++ b/TODO @@ -0,0 +1,330 @@ + + Priority: + + * Cleaner gold fonts! (Poor AA in bigfont3, and goldfont + is just a scaled and colorized version of icefont2.) + + * Sort the video modes! + + * Nodes and cores should have some sort of "spawn" + effect when firing. + + * Logic object pool optimization: Use LIFO pool + lists! + + * Graphics scaling: + * Remove or hide the advanced graphics options! + * Graphics quality: + * Fastest + * Medium + * Best (Default) + * Custom (show old detailed settings) + * At first startup, quality would be + "Unknown". The game will start by + testing the intro with no logo. The game + picks a quality setting based on frame + rate. If "Medium" or "Fastest" is picked, + the game should warn and ask the user. + * Specify in the loader what scaling methods should + be used for each quality setting. (What about + Custom?) + * Disable alpha in Fastest quality. Medium...? + + * Better scaling! + * Try SDL_resize!!! + * Combine Scale2x and Diamond2x? + * S-spline style enhancement filters? + * Detail textures? + + * Indirectly changing the video mode (by changing one + of the "Show" options) will not trigger a video + restart. + + * Death sequence UI timing should not be governed by + game logic time! Throw in a "state time" feature in + the gamestate manager or something. Or perhaps just + switch to a fixed logic frame rate when not + actually in-game? (It does actually make sense to + scale in-game effects with game speed!) + + * Quicker menu navigation with PgUp/Dn, Home, End etc. + + * 3D "rockfield" for highscore and/or credits? (2D + parallax rocks + stars without glSDL.) glSDL should + support texture filtering for nice scaling. + + * There should be some feedback from the sound engine, + perhaps... As it is, you can't even see what sample + rate it's actually using. + + Bugs: + + * Y scale factor f*cked up when switching to 2560x1600! + Apparently happens only after "escape hammering"... + + * In-game music volume affects intro music! + + * Mouse crosshair can stick around after disabling mouse + control! + + * Multiple keys and buttons bound to the same + function results in up/down state confusion; if + you release one of the keys, the "target" gets a + release event, despite other keys with the same + target being held down. + + * Nibble effect still doesn't like double buffering. + + * The sound engine is mixing up PAN events!!! + + * glSDL surface leak when taking screenshots! + + * Do we *really* wait for all bases to stop exploding + after the player lost a ship...? + + * Noise fx glitches in some resolutions. + + * If a ctrl+enter fullscreen/windowed switch is made + while the menu is shown, the text goes away! + + * Any playing game aborts after toggling windowed/ + fullscreen! + + * VSync settings doesn't change as it should! Doesn't seem + to be much I can do about this... + + * Leaving the game running for a few hours results in + "hickups" at around 2 Hz, until the graphics is reloaded + or similar. (Logic re-init?) + + * Downscaling (sub 320x240) breaks the radar and + causes various other issues. (Pretty much expected...) + + * SIGSTOP kills the main thread... SDL/AMD64 bug...? + + * SIGSTOP/SIGCONT seems to confuse the game logic. + (Already fixed...?) + + * SDL_GetAppState()! (Fixed...?) + + + Internals: + + * Try to create a scoredir if missing! + + * Add doc() method to the config manager, for longer + explanations of the options. + * Structured documentation for values...? + + * Try reading back from the display buffer to autodetect + how page flipping is handled! Mark pages with a few + pixels in the corner (binary page numbers), and see + if/when they come back. + + * Pause mode should not consume CPU or GPU power, + at least not if the window is passive. + + * Multiple priority groups for sound effects! + + * glSDL and EEL should output errors to the logger. + + * Switch to PhysicsFS!? + + * WAV writer? (Just for "cache sounds on disk.") + + * Don't overwrite other windows when refreshing the + in-game framework. + + * Convert text files to Win32 format in the Win32 + install target! + + * Add source info to "key" codes, to tell joystick + input from keyboard and the like, when desired. + + * Use custom keyboard repeat code. Should be used + for joystick events as well. + + * Show a system dialog of some sort, instead of + printing to stderr. (Critical errors only.) + + * Range checking on command line args and config. + + * Remove either gamecontrol or gsm event pushing + calls from skobo_gfxengine_t::frame(). Don't know + which one, but it can't be right the way it is + now... + + * Rearrange the source tree so that all source is + in an src subdir. + + * Put README, COPYING etc in binary distros. (Done + for Win32 "simple bundles".) + + * Add CRC or simple "checksum" to score files, to + prevent too easy modification. You must at least + download the game source and hack it if you + *really* want to cheat! ;-) + + + Features: + + * Proper start-of-map savegames! + + * Instructions! (In the radar window...?) + + * Input configurator!!! + + * Game statistics! + * Shots fired + * Hits + * Accuracy + * Kills + * Deaths + * Damage + + * Adrenaline Mode: + * Health/damage accounting + * Powerups + * Indestructible labyrinths + * N bases or objects to destroy + * Loads of aggressive enemies + * "Forced speedrun" style gameplay + + * Throw in some *real* music. (The demo songs don't + really have anything to do with Kobo Deluxe. I + was basically just testing things when developing + the audio engine.) + + * Implement "world snapshot" feature, to use for + save game option, as well as internal temporary + save game for changing video options in the + middle of the game and the like. Needs to save + score, lives etc, the current map, all objects, + random number seed etc. + + * Implement multiplayer modes. (Deathmatch and + Cooperative, for starters.) + + * Separate personal and global highscores. Where + applicable, one could keep score for player/user, + system local, local network and the internet, + and/or maybe some kind user defined groups. + + * New "Instructions" solution. (New state...?) + + * "Sloppy Refresh" hack to improve frame rate for + sprites and base tiles, while reducing it for + the starry background tiles. + + * On targets with sync'ed flips, accept "close + enough" refresh rates as time base, so that the + video frame rate becomes an integer multiple of + the engine frame rate. (Smoother scrolling.) + + Gameplay: + + * Elite and God modes should make enemies smarter + (aim-ahead, at least). We want "tough" - not + "stupid fast"! + + Radar: + * Radar markings for death + respawn points when + getting killed? + + * Show map borders in radar, for orientation? + + Base layout: + * Prevent the map generator from building + impossible bases! Possibly build a list of + tested and approved random seeds for each + level... + * Don't make bases where you have to navigate + into the base on the first few levels. + * Simulation based base verification method: + 1. Destroy all destructible nodes. + 2. Figure out how many turns one would + have to navigate into the base in + order to get a shot at the core. + * Provide a fixed set of maps for fair highscore, + speedruns and the like! As it is, every game + is truly unique, so scores cannot really be + compared. (Well, that *could* be considered + part of the game, of course...) + + * Import some extra maps from xkobo-1.11+w01? + + * Bonus levels...? + + * "Smooth chase" scroll in non Classic modes? Maybe + even filtered player movement? + + * Fire to push rocks around? + + * "Milking" cores that fire enemies is a potential + way of cheating for a higher score. Throw in an + enemy_m* after some time as assassin to prevent + this? (How to detect whether the player is doing + something "sensible" or not...?) + + Trick suggested a nice and simple solution: Just + lower the "price tag" on enemies spawned from + nodes over time. No effect on gameplay, but if + you fly around shooting defenseless enemies for + too long, they'll eventually stop counting + towards your score. The only remaining problem + is figuring out when to start decreasing enemy + scores, and how fast. + + + Features: + + * Instant restart button? (Shouldn't really be needed + if the "impossible base" bugs are fixed...) + + * Should be able to skip the death explosion sequence, + if there are more ships! Maybe an option to remove + it (and other effects) altogether? + + * Separate highscores for different skills. + + * Help texts (in the radar window?) for config options! + + * Add native OpenGL support with sub-pixel accurate + rendering for ultra smooth animation. + + * Nice health bar flash effects. + + * Fine rotation adjustment when using OpenGL. (Needs + a generic high resolution rotation field.) + + * Screen pixel accurate map scrolling. + + * "Stage cleared" screens with stats and stuff! + + * Demo recording and playback! (Nice feature and + debugging tool.) + + * Implement waveshaper AGW command! + + * New master output processor: + * Three bands with separate "boost" controls. + + * Non-linear audio output for high boost! + + * New limiter that programs a waveshaper based + on input level? + + * Interesting soundscape while loading? + + * "Center Playfield" (as opposed to "center framework") + video option + + * Default/Changed status indicators in the options. + + + Web site and other stuff: + + * Find binary packages and maintainers! + + * Links to unrelated games sites. + + * Write a design paper! diff --git a/acconfig.h b/acconfig.h new file mode 100644 index 0000000..e69de29 diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..6639d33 --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,1044 @@ +# generated automatically by aclocal 1.9.6 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# Configure paths for SDL +# Sam Lantinga 9/21/99 +# stolen from Manish Singh +# stolen back from Frank Belew +# stolen from Manish Singh +# Shamelessly stolen from Owen Taylor + +dnl AM_PATH_SDL([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) +dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS +dnl +AC_DEFUN([AM_PATH_SDL], +[dnl +dnl Get the cflags and libraries from the sdl-config script +dnl +AC_ARG_WITH(sdl-prefix,[ --with-sdl-prefix=PFX Prefix where SDL is installed (optional)], + sdl_prefix="$withval", sdl_prefix="") +AC_ARG_WITH(sdl-exec-prefix,[ --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional)], + sdl_exec_prefix="$withval", sdl_exec_prefix="") +AC_ARG_ENABLE(sdltest, [ --disable-sdltest Do not try to compile and run a test SDL program], + , enable_sdltest=yes) + + if test x$sdl_exec_prefix != x ; then + sdl_args="$sdl_args --exec-prefix=$sdl_exec_prefix" + if test x${SDL_CONFIG+set} != xset ; then + SDL_CONFIG=$sdl_exec_prefix/bin/sdl-config + fi + fi + if test x$sdl_prefix != x ; then + sdl_args="$sdl_args --prefix=$sdl_prefix" + if test x${SDL_CONFIG+set} != xset ; then + SDL_CONFIG=$sdl_prefix/bin/sdl-config + fi + fi + + if test "x$prefix" != xNONE; then + PATH="$prefix/bin:$prefix/usr/bin:$PATH" + fi + AC_PATH_PROG(SDL_CONFIG, sdl-config, no, [$PATH]) + min_sdl_version=ifelse([$1], ,0.11.0,$1) + AC_MSG_CHECKING(for SDL - version >= $min_sdl_version) + no_sdl="" + if test "$SDL_CONFIG" = "no" ; then + no_sdl=yes + else + SDL_CFLAGS=`$SDL_CONFIG $sdlconf_args --cflags` + SDL_LIBS=`$SDL_CONFIG $sdlconf_args --libs` + + sdl_major_version=`$SDL_CONFIG $sdl_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + sdl_minor_version=`$SDL_CONFIG $sdl_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + sdl_micro_version=`$SDL_CONFIG $sdl_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + if test "x$enable_sdltest" = "xyes" ; then + ac_save_CFLAGS="$CFLAGS" + ac_save_CXXFLAGS="$CXXFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $SDL_CFLAGS" + CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" +dnl +dnl Now check if the installed SDL is sufficiently new. (Also sanity +dnl checks the results of sdl-config to some extent +dnl + rm -f conf.sdltest + AC_TRY_RUN([ +#include +#include +#include +#include "SDL.h" + +char* +my_strdup (char *str) +{ + char *new_str; + + if (str) + { + new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char)); + strcpy (new_str, str); + } + else + new_str = NULL; + + return new_str; +} + +int main (int argc, char *argv[]) +{ + int major, minor, micro; + char *tmp_version; + + /* This hangs on some systems (?) + system ("touch conf.sdltest"); + */ + { FILE *fp = fopen("conf.sdltest", "a"); if ( fp ) fclose(fp); } + + /* HP/UX 9 (%@#!) writes to sscanf strings */ + tmp_version = my_strdup("$min_sdl_version"); + if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { + printf("%s, bad version string\n", "$min_sdl_version"); + exit(1); + } + + if (($sdl_major_version > major) || + (($sdl_major_version == major) && ($sdl_minor_version > minor)) || + (($sdl_major_version == major) && ($sdl_minor_version == minor) && ($sdl_micro_version >= micro))) + { + return 0; + } + else + { + printf("\n*** 'sdl-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version); + printf("*** of SDL required is %d.%d.%d. If sdl-config is correct, then it is\n", major, minor, micro); + printf("*** best to upgrade to the required version.\n"); + printf("*** If sdl-config was wrong, set the environment variable SDL_CONFIG\n"); + printf("*** to point to the correct copy of sdl-config, and remove the file\n"); + printf("*** config.cache before re-running configure\n"); + return 1; + } +} + +],, no_sdl=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) + CFLAGS="$ac_save_CFLAGS" + CXXFLAGS="$ac_save_CXXFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + if test "x$no_sdl" = x ; then + AC_MSG_RESULT(yes) + ifelse([$2], , :, [$2]) + else + AC_MSG_RESULT(no) + if test "$SDL_CONFIG" = "no" ; then + echo "*** The sdl-config script installed by SDL could not be found" + echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the SDL_CONFIG environment variable to the" + echo "*** full path to sdl-config." + else + if test -f conf.sdltest ; then + : + else + echo "*** Could not run SDL test program, checking why..." + CFLAGS="$CFLAGS $SDL_CFLAGS" + CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" + AC_TRY_LINK([ +#include +#include "SDL.h" + +int main(int argc, char *argv[]) +{ return 0; } +#undef main +#define main K_and_R_C_main +], [ return 0; ], + [ echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding SDL or finding the wrong" + echo "*** version of SDL. If it is not finding SDL, you'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"], + [ echo "*** The test program failed to compile or link. See the file config.log for the" + echo "*** exact error that occured. This usually means SDL was incorrectly installed" + echo "*** or that you have moved SDL since it was installed. In the latter case, you" + echo "*** may want to edit the sdl-config script: $SDL_CONFIG" ]) + CFLAGS="$ac_save_CFLAGS" + CXXFLAGS="$ac_save_CXXFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + SDL_CFLAGS="" + SDL_LIBS="" + ifelse([$3], , :, [$3]) + fi + AC_SUBST(SDL_CFLAGS) + AC_SUBST(SDL_LIBS) + rm -f conf.sdltest +]) + +# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION so it can be traced. +# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], + [AM_AUTOMAKE_VERSION([1.9.6])]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 7 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE]) +AC_SUBST([$1_FALSE]) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 8 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH]) +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +#serial 3 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 8 + +# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. +AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 12 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.58])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_PROG_INSTALL_SH +AM_PROG_INSTALL_STRIP +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +]) +]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $1 | $1:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +install_sh=${install_sh-"$am_aux_dir/install-sh"} +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_MKDIR_P +# --------------- +# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. +# +# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories +# created by `make install' are always world readable, even if the +# installer happens to have an overly restrictive umask (e.g. 077). +# This was a mistake. There are at least two reasons why we must not +# use `-m 0755': +# - it causes special bits like SGID to be ignored, +# - it may be too restrictive (some setups expect 775 directories). +# +# Do not use -m 0755 and let people choose whatever they expect by +# setting umask. +# +# We cannot accept any implementation of `mkdir' that recognizes `-p'. +# Some implementations (such as Solaris 8's) are not thread-safe: if a +# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c' +# concurrently, both version can detect that a/ is missing, but only +# one can create it and the other will error out. Consequently we +# restrict ourselves to GNU make (using the --version option ensures +# this.) +AC_DEFUN([AM_PROG_MKDIR_P], +[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + # We used to keeping the `.' as first argument, in order to + # allow $(mkdir_p) to be used without argument. As in + # $(mkdir_p) $(somedir) + # where $(somedir) is conditionally defined. However this is wrong + # for two reasons: + # 1. if the package is installed by a user who cannot write `.' + # make install will fail, + # 2. the above comment should most certainly read + # $(mkdir_p) $(DESTDIR)$(somedir) + # so it does not work when $(somedir) is undefined and + # $(DESTDIR) is not. + # To support the latter case, we have to write + # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), + # so the `.' trick is pointless. + mkdir_p='mkdir -p --' +else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + for d in ./-p ./--version; + do + test -d $d && rmdir $d + done + # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. + if test -f "$ac_aux_dir/mkinstalldirs"; then + mkdir_p='$(mkinstalldirs)' + else + mkdir_p='$(install_sh) -d' + fi +fi +AC_SUBST([mkdir_p])]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + diff --git a/aconfig.h b/aconfig.h new file mode 100644 index 0000000..524de5d --- /dev/null +++ b/aconfig.h @@ -0,0 +1,190 @@ +/* aconfig.h. Generated from aconfig.h.in by configure. */ +/* aconfig.h.in. Generated from configure.in by autoheader. */ + +/* Define to 1 if you have the `atexit' function. */ +#define HAVE_ATEXIT 1 + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#define HAVE_DIRENT_H 1 + +/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ +/* #undef HAVE_DOPRNT */ + +/* Define to 1 if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have the `floor' function. */ +#define HAVE_FLOOR 1 + +/* Define to 1 if you have the `getegid' function. */ +#define HAVE_GETEGID 1 + +/* Define to 1 if you have the `getpagesize' function. */ +#define HAVE_GETPAGESIZE 1 + +/* Define to 1 if you have the `gettimeofday' function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `SDL_image' library (-lSDL_image). */ +#define HAVE_LIBSDL_IMAGE 1 + +/* Define to 1 if you have the `memcmp' function. */ +#define HAVE_MEMCMP 1 + +/* Define to 1 if you have the `memmove' function. */ +#define HAVE_MEMMOVE 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `memset' function. */ +#define HAVE_MEMSET 1 + +/* Define to 1 if you have the `mkdir' function. */ +#define HAVE_MKDIR 1 + +/* Define to 1 if you have a working `mmap' system call. */ +#define HAVE_MMAP 1 + +/* Define to 1 if you have the `munmap' function. */ +#define HAVE_MUNMAP 1 + +/* Define to 1 if you have the header file, and it defines `DIR'. */ +/* #undef HAVE_NDIR_H */ + +/* Define to 1 if you have the `pow' function. */ +#define HAVE_POW 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SDL_SDL_OPENGL_H 1 + +/* Define to 1 if you have the `select' function. */ +#define HAVE_SELECT 1 + +/* Define to 1 if you have the `setgid' function. */ +#define HAVE_SETGID 1 + +/* Define to 1 if you have the `snprintf' function. */ +#define HAVE_SNPRINTF 1 + +/* Define to 1 if you have the `sqrt' function. */ +#define HAVE_SQRT 1 + +/* Define to 1 if you have the `stat' function. */ +#define HAVE_STAT 1 + +/* Define to 1 if `stat' has the bug that it succeeds when given the + zero-length file name argument. */ +/* #undef HAVE_STAT_EMPTY_STRING_BUG */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `strchr' function. */ +#define HAVE_STRCHR 1 + +/* Define to 1 if you have the `strdup' function. */ +#define HAVE_STRDUP 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strrchr' function. */ +#define HAVE_STRRCHR 1 + +/* Define to 1 if you have the `strstr' function. */ +#define HAVE_STRSTR 1 + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_DIR_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_NDIR_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the `vprintf' function. */ +#define HAVE_VPRINTF 1 + +/* Define to 1 if you have the `vsnprintf' function. */ +#define HAVE_VSNPRINTF 1 + +/* Define to 1 if you have the `_snprintf' function. */ +/* #undef HAVE__SNPRINTF */ + +/* Define to 1 if you have the `_vsnprintf' function. */ +/* #undef HAVE__VSNPRINTF */ + +/* Define to 1 if `lstat' dereferences a symlink specified with a trailing + slash. */ +#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1 + +/* Name of package */ +#define PACKAGE "KoboDeluxe" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "" + +/* Define as the return type of signal handlers (`int' or `void'). */ +#define RETSIGTYPE void + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Version number of package */ +#define VERSION "0.5.1" + +/* Define to 1 if the X Window System is missing or not being used. */ +/* #undef X_DISPLAY_MISSING */ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif diff --git a/aconfig.h.in b/aconfig.h.in new file mode 100644 index 0000000..8f6033a --- /dev/null +++ b/aconfig.h.in @@ -0,0 +1,189 @@ +/* aconfig.h.in. Generated from configure.in by autoheader. */ + +/* Define to 1 if you have the `atexit' function. */ +#undef HAVE_ATEXIT + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_DIRENT_H + +/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ +#undef HAVE_DOPRNT + +/* Define to 1 if you have the header file. */ +#undef HAVE_ERRNO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the `floor' function. */ +#undef HAVE_FLOOR + +/* Define to 1 if you have the `getegid' function. */ +#undef HAVE_GETEGID + +/* Define to 1 if you have the `getpagesize' function. */ +#undef HAVE_GETPAGESIZE + +/* Define to 1 if you have the `gettimeofday' function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `SDL_image' library (-lSDL_image). */ +#undef HAVE_LIBSDL_IMAGE + +/* Define to 1 if you have the `memcmp' function. */ +#undef HAVE_MEMCMP + +/* Define to 1 if you have the `memmove' function. */ +#undef HAVE_MEMMOVE + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `memset' function. */ +#undef HAVE_MEMSET + +/* Define to 1 if you have the `mkdir' function. */ +#undef HAVE_MKDIR + +/* Define to 1 if you have a working `mmap' system call. */ +#undef HAVE_MMAP + +/* Define to 1 if you have the `munmap' function. */ +#undef HAVE_MUNMAP + +/* Define to 1 if you have the header file, and it defines `DIR'. */ +#undef HAVE_NDIR_H + +/* Define to 1 if you have the `pow' function. */ +#undef HAVE_POW + +/* Define to 1 if you have the header file. */ +#undef HAVE_SDL_SDL_OPENGL_H + +/* Define to 1 if you have the `select' function. */ +#undef HAVE_SELECT + +/* Define to 1 if you have the `setgid' function. */ +#undef HAVE_SETGID + +/* Define to 1 if you have the `snprintf' function. */ +#undef HAVE_SNPRINTF + +/* Define to 1 if you have the `sqrt' function. */ +#undef HAVE_SQRT + +/* Define to 1 if you have the `stat' function. */ +#undef HAVE_STAT + +/* Define to 1 if `stat' has the bug that it succeeds when given the + zero-length file name argument. */ +#undef HAVE_STAT_EMPTY_STRING_BUG + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strchr' function. */ +#undef HAVE_STRCHR + +/* Define to 1 if you have the `strdup' function. */ +#undef HAVE_STRDUP + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strrchr' function. */ +#undef HAVE_STRRCHR + +/* Define to 1 if you have the `strstr' function. */ +#undef HAVE_STRSTR + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_SYS_DIR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_IOCTL_H + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_SYS_NDIR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `vprintf' function. */ +#undef HAVE_VPRINTF + +/* Define to 1 if you have the `vsnprintf' function. */ +#undef HAVE_VSNPRINTF + +/* Define to 1 if you have the `_snprintf' function. */ +#undef HAVE__SNPRINTF + +/* Define to 1 if you have the `_vsnprintf' function. */ +#undef HAVE__VSNPRINTF + +/* Define to 1 if `lstat' dereferences a symlink specified with a trailing + slash. */ +#undef LSTAT_FOLLOWS_SLASHED_SYMLINK + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME + +/* Version number of package */ +#undef VERSION + +/* Define to 1 if the X Window System is missing or not being used. */ +#undef X_DISPLAY_MISSING + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif diff --git a/buildpkg.sh b/buildpkg.sh new file mode 100755 index 0000000..0af74c8 --- /dev/null +++ b/buildpkg.sh @@ -0,0 +1,37 @@ +#!/bin/sh +# +# How to build a solaris package, by Andreas Spångberg: +# ./configure +# make +# cd solaris +# ./buildpkg.sh +# pkgadd -d ./ASkobodl.pkg +# + +ARCH=`uname -p` +INSTDIR=`pwd`/package +cd .. +make install DESTDIR=$INSTDIR +cd $INSTDIR + +cat > pkginfo << EOPKG +PKG="ASkobodl" +NAME=`grep PACKAGE ../../aconfig.h | awk -e '{print $3}'` +ARCH="$ARCH" +VERSION=`grep VERSION ../../aconfig.h | awk -e '{print $3}'` +CATEGORY="games" +VENDOR="David Olofson" +EMAIL="david@olofson.net" +PSTAMP="Andreas Spångberg" +BASEDIR="/usr/local" +CLASSES="none" +EOPKG + +echo "i pkginfo=./pkginfo" > prototype +find . -print | pkgproto ./usr/local= >> prototype + +cd .. +pkgmk -d . -f package/prototype -o +rm -rf $INSTDIR +echo 1 | pkgtrans -os . ASkobodl.pkg +rm -rf ./ASkobodl diff --git a/cfg-beta b/cfg-beta new file mode 100755 index 0000000..6a90a36 --- /dev/null +++ b/cfg-beta @@ -0,0 +1,2 @@ +#!/bin/sh +CFLAGS="-O3" CXXFLAGS="-O3" ./configure --enable-debug --enable-alsa --enable-opengl --enable-oss diff --git a/cfg-cross-release b/cfg-cross-release new file mode 100755 index 0000000..0e67785 --- /dev/null +++ b/cfg-cross-release @@ -0,0 +1,2 @@ +#!/bin/sh +CFLAGS="-O3 -Wall" CXXFLAGS="-O3 -Wall" cross-configure --disable-debug --disable-epm diff --git a/cfg-profile b/cfg-profile new file mode 100755 index 0000000..27f5757 --- /dev/null +++ b/cfg-profile @@ -0,0 +1,2 @@ +#!/bin/sh +CFLAGS="-O3 -pg" CXXFLAGS="-O3 -pg" ./configure --disable-alsa --enable-opengl --enable-oss diff --git a/cfg-release b/cfg-release new file mode 100755 index 0000000..0c88348 --- /dev/null +++ b/cfg-release @@ -0,0 +1,2 @@ +#!/bin/sh +CFLAGS="-O3" CXXFLAGS="-O3" ./configure --prefix=/usr --disable-alsa --enable-opengl --enable-oss diff --git a/cfg-work b/cfg-work new file mode 100755 index 0000000..a914827 --- /dev/null +++ b/cfg-work @@ -0,0 +1,2 @@ +#!/bin/sh +CFLAGS="-O0" CXXFLAGS="-O0" ./configure --prefix=/usr --enable-epm --enable-debug --disable-alsa --enable-opengl --enable-oss diff --git a/cfg-work-opt b/cfg-work-opt new file mode 100755 index 0000000..7e9667c --- /dev/null +++ b/cfg-work-opt @@ -0,0 +1,2 @@ +#!/bin/sh +CFLAGS="-O3" CXXFLAGS="-O3" ./configure --prefix=/usr --enable-epm --enable-debug --disable-alsa --enable-opengl --enable-oss diff --git a/cfgform.cpp b/cfgform.cpp new file mode 100644 index 0000000..160b395 --- /dev/null +++ b/cfgform.cpp @@ -0,0 +1,152 @@ +/*(GPL) +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 2001-2003, 2006-2007 David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "kobolog.h" +#include "config.h" +#include "cfgform.h" +#include "kobo.h" +#include "sound.h" +#include "vidmodes.h" + +int global_status = 0; + + +config_form_t::config_form_t() +{ + prf = NULL; + stat = 0; +} + + +config_form_t::~config_form_t() +{ +} + + +void config_form_t::open(prefs_t *p) +{ + init(gengine); + place(wmain->x(), wmain->y(), wmain->width(), wmain->height()); + font(B_NORMAL_FONT); + foreground(wmain->map_rgb(0xffffff)); + background(wmain->map_rgb(0x000000)); + prf = p; + prfbak = *p; + stat = global_status & (OS_RELOAD | OS_RESTART | OS_UPDATE); + build_all(); +} + + +void config_form_t::close() +{ + vmm_Close(); + clean(); +} + + +void config_form_t::undo() +{ + *prf = prfbak; + undo_hook(); +} + + +int config_form_t::status() +{ + return stat; +} + + +void config_form_t::clearstatus(int mask) +{ + stat &= ~mask; + global_status = stat & (OS_RELOAD | OS_RESTART | OS_UPDATE); +} + + +void config_form_t::setstatus(int mask) +{ + stat |= mask; + global_status = stat & (OS_RELOAD | OS_RESTART | OS_UPDATE); +} + +/*virtual*/ void config_form_t::change(int delta) +{ + kobo_form_t::change(delta); + + if(!selected()) + return; + + if(selected()->tag & OS_CLOSE) + { + if(delta == 0) + { + sound.ui_ok(); + setstatus(OS_CLOSE); + } + } + else if(selected()->tag & OS_CANCEL) + { + if(delta == 0) + { + sound.ui_cancel(); + undo(); + setstatus(OS_CLOSE); + } + } + else + sound.ui_tick(); + + if(selected()->user) + prf->changed = 1; + + setstatus(selected()->tag & (OS_RELOAD | OS_RESTART | OS_UPDATE)); + + // If a video mode from the table is selected, get the parameters + // from the video mode manager! + if(prf->videomode) + { + VMM_Mode *m = vmm_FindMode(prf->videomode); + if(m) + { + prf->width = m->width; + prf->height = m->height; + prf->aspect = (int)(m->aspect * 1000.0f + .5f); + } + } + + if(selected()->tag & OS_REBUILD) + { + int sel = selected_index(); + build_all(); + select(sel); + } +} + +/* virtual */void config_form_t::build() +{ +} + +/* virtual */ void config_form_t::undo_hook() +{ + stat = 0; + global_status = 0; +} diff --git a/cfgform.h b/cfgform.h new file mode 100644 index 0000000..086d442 --- /dev/null +++ b/cfgform.h @@ -0,0 +1,76 @@ +/* +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 2001, 2003, David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _CONFIG_FORM_H_ +#define _CONFIG_FORM_H_ + +#include "form.h" +#include "prefs.h" + +enum +{ + OS_CLOSE = 0x0001, + OS_CANCEL = 0x0002, + OS_REBUILD = 0x0004, + OS_ACTION = 0x000f, + + OS_RELOAD_GRAPHICS = 0x0010, + OS_RELOAD_AUDIO_CACHE = 0x0020, + OS_RELOAD = 0x0070, + + OS_RESTART_VIDEO = 0x0100, + OS_RESTART_AUDIO = 0x0200, + OS_RESTART_ENGINE = 0x0400, + OS_RESTART_INPUT = 0x0800, + OS_RESTART_LOGGER = 0x0080, + OS_RESTART = 0x0f80, + + OS_UPDATE_AUDIO = 0x1000, + OS_UPDATE_ENGINE = 0x2000, + OS_UPDATE = 0xf000 +}; + + +class config_form_t : public kobo_form_t +{ + protected: + prefs_t *prf; + prefs_t prfbak; + int stat; + public: + config_form_t(); + virtual ~config_form_t(); + void open(prefs_t *p); + virtual void build(); // <-- Override this! + //...and this, if you need. Normally, + //it just sets the status to 0. + virtual void undo_hook(); + void close(); + int status(); + void setstatus(int mask); + void clearstatus(int mask); + void undo(); + void change(int delta); +}; + +extern int global_status; + +#endif //_CONFIG_FORM_H_ diff --git a/cfgparse.cpp b/cfgparse.cpp new file mode 100644 index 0000000..c6fcb18 --- /dev/null +++ b/cfgparse.cpp @@ -0,0 +1,1080 @@ +/*(LGPL) +------------------------------------------------------------------- + cfgparse.cpp - Generic Config File and Argument Parser +------------------------------------------------------------------- + * Copyright (C) 2001, 2007 David Olofson + * + * This code is released under the terms of the GNU LGPL. + */ + +#include "config.h" +#include "logger.h" + +#include +#include +#include + +#include "cfgparse.h" + +#define MAX_CONFIG_LINES 1024 + + +/*---------------------------------------------------------- + cfg_key_t +----------------------------------------------------------*/ + +cfg_key_t::cfg_key_t() +{ + next = NULL; + name = ""; + save = 1; + typecode = CFG_NONE; + redefined = 0; + description = NULL; +} + + +cfg_key_t::~cfg_key_t() +{ + free(description); +} + + +int cfg_key_t::read(int argc, char *argv[]) +{ + return 0; +} + + +int cfg_key_t::test(const char *arg) +{ + if(arg[0] == '-' || arg[0] == '/') + ++arg; + return !strcmp(name, arg); +} + + +/*---------------------------------------------------------- + cfg_comment_t +----------------------------------------------------------*/ + +void cfg_comment_t::write(FILE *f) +{ + fprintf(f, "#%s\n", name); +} + + +int cfg_comment_t::copy(cfg_key_t *from) +{ + if(typecode != from->typecode) + return -1; + return 0; +} + + +/*---------------------------------------------------------- + cfg_switch_t +----------------------------------------------------------*/ + +cfg_switch_t::cfg_switch_t(const char *_name, int &var, int def, int _save) +{ + name = _name; + value = &var; + default_value = def; + save = _save; + typecode = CFG_BOOL; +} + + +int cfg_switch_t::copy(cfg_key_t *from) +{ + if(typecode != from->typecode) + return -1; + *value = *((cfg_switch_t *)from)->value; + return 0; +} + + +int cfg_switch_t::test(const char *arg) +{ + if(arg[0] == '-' || arg[0] == '/') + ++arg; + if(strncmp("no", name, 2)) + if(!strncmp("no", arg, 2)) + arg += 2; + return !strcmp(name, arg); +} + + +int cfg_switch_t::read(int argc, char *argv[]) +{ + char *arg = argv[0]; + *value = 1; + if(arg[0] == '-' || arg[0] == '/') + ++arg; + if(!strncmp("no", arg, 2)) + *value = 0; + if(!strncmp("no", name, 2)) + *value = !(*value); + return 1; +} + + +void cfg_switch_t::write(FILE *f) +{ + fprintf(f, *value ? "%s\n" : "no%s\n", name); +} + + +void cfg_switch_t::set_default() +{ + *value = default_value; +} + + +int cfg_switch_t::is_your_var(void *var) +{ + return var == (void *)value; +} + + + +/*---------------------------------------------------------- + cfg_key_int_t +----------------------------------------------------------*/ + +cfg_key_int_t::cfg_key_int_t(const char *_name, int &var, int def, int _save) +{ + name = _name; + value = &var; + default_value = def; + save = _save; + typecode = CFG_INT; +} + + +int cfg_key_int_t::copy(cfg_key_t *from) +{ + if(typecode != from->typecode) + return -1; + *value = *((cfg_key_int_t *)from)->value; + return 0; +} + + +int cfg_key_int_t::read(int argc, char *argv[]) +{ + if(argc < 2) + return -1; + *value = atoi(argv[1]); + return 2; +} + + +void cfg_key_int_t::write(FILE *f) +{ + fprintf(f, "%s %d\n", name, *value); +} + + +void cfg_key_int_t::set_default() +{ + *value = default_value; +} + + +int cfg_key_int_t::is_your_var(void *var) +{ + return var == (void *)value; +} + + + +/*---------------------------------------------------------- + cfg_key_float_t +----------------------------------------------------------*/ + +cfg_key_float_t::cfg_key_float_t(const char *_name, float &var, float def, int _save) +{ + name = _name; + value = &var; + default_value = def; + save = _save; + typecode = CFG_FLOAT; +} + + +int cfg_key_float_t::copy(cfg_key_t *from) +{ + if(typecode != from->typecode) + return -1; + *value = *((cfg_key_float_t *)from)->value; + return 0; +} + + + + +int cfg_key_float_t::read(int argc, char *argv[]) +{ + if(argc < 2) + return -1; + *value = atof(argv[1]); + return 2; +} + + +void cfg_key_float_t::write(FILE *f) +{ + fprintf(f, "%s %f\n", name, *value); +} + + +void cfg_key_float_t::set_default() +{ + *value = default_value; +} + + +int cfg_key_float_t::is_your_var(void *var) +{ + return var == (void *)value; +} + + + +/*---------------------------------------------------------- + cfg_key_string_t +----------------------------------------------------------*/ + +cfg_key_string_t::cfg_key_string_t(const char *_name, cfg_string_t &var, + const cfg_string_t def, int _save) +{ + name = _name; + value = &var; + strncpy(default_value, def, CFG_STRING_LENGTH); + save = _save; + typecode = CFG_STRING; +} + + +int cfg_key_string_t::copy(cfg_key_t *from) +{ + if(typecode != from->typecode) + return -1; + memcpy(*value, *((cfg_key_string_t *)from)->value, CFG_STRING_LENGTH); + return 0; +} + + +int cfg_key_string_t::read(int argc, char *argv[]) +{ + if(argc < 2) + return -1; + strncpy(*value, argv[1], CFG_STRING_LENGTH); + return 2; +} + + +void cfg_key_string_t::write(FILE *f) +{ + fprintf(f, "%s \"%s\"\n", name, *value); +} + + +void cfg_key_string_t::set_default() +{ + strncpy(*value, default_value, CFG_STRING_LENGTH); +} + + +int cfg_key_string_t::is_your_var(void *var) +{ + return var == (void *)value; +} + + + +/*---------------------------------------------------------- + config_parser_t +----------------------------------------------------------*/ + +config_parser_t::config_parser_t() +{ + keys = last_key = NULL; + changed = 0; + initialized = 0; +} + + +void config_parser_t::initialize() +{ + if(initialized) + return; + + init(); + set_defaults(); + build_table(); + initialized = 1; +} + +void config_parser_t::build_table() +{ + cfg_key_t *k = keys; + nkeys = 0; + while(k) + { + ++nkeys; + k = k->next; + } + table = new cfg_key_t*[nkeys]; + + k = keys; + int i = 0; + while(k) + { + table[i++] = k; + k = k->next; + } +} + +config_parser_t::~config_parser_t() +{ + cfg_key_t *k = keys; + while(k) + { + keys = k->next; + delete k; + k = keys; + } + delete[]table; +} + +config_parser_t &config_parser_t::operator = (config_parser_t &from) +{ + initialize(); + from.initialize(); + cfg_key_t *k = keys; + while(k) + { + cfg_key_t *fk = from.keys; + while(fk) + { + if(!strcmp(fk->name, k->name)) + { + if(k->copy(fk) < 0) + log_printf(ELOG, "config_parser_t: Tried" + " to copy from incompatible" + " source!\n"); + break; + } + fk = fk->next; + } + k = k->next; + } + return *this; +} + +void config_parser_t::add(cfg_key_t *_key) +{ + if(last_key) + { + last_key->next = _key; + last_key = _key; + } + else + keys = last_key = _key; +} + + +void config_parser_t::comment(const char *text) +{ + add(new cfg_comment_t(text)); +} + + +void config_parser_t::yesno(const char *name, int &var, int def, int save) +{ + add(new cfg_switch_t(name, var, def, save)); +} + + +void config_parser_t::command(const char *name, int &var) +{ + add(new cfg_switch_t(name, var, 0, 0)); +} + + +void config_parser_t::key(const char *name, int &var, int def, int save) +{ + add(new cfg_key_int_t(name, var, def, save)); +} + + +void config_parser_t::key(const char *name, float &var, float def, int save) +{ + add(new cfg_key_float_t(name, var, def, save)); +} + + +void config_parser_t::key(const char *name, cfg_string_t &var, + const cfg_string_t def, int save) +{ + add(new cfg_key_string_t(name, var, def, save)); +} + + +void config_parser_t::desc(const char *text) +{ + if(!last_key) + { + log_printf(ELOG, "config_parser_t::description() called" + " with no key registered!\n"); + return; + } + last_key->description = strdup(text); +} + + +void config_parser_t::set_defaults() +{ + cfg_key_t *k = keys; + while(k) + { + k->set_default(); + k->redefined = 0; + k = k->next; + } +} + + +/* + * "Uuuh, a leetle icky finite state machine parser... :-D" + * (Actually a very nice and simple way of coding this kind + * of stuff, if you don't want to drag in Bison or something.) + */ +enum scanstate_t +{ + SS_BLANK, + SS_QUOTE, + SS_WORD, + SS_COMMENT +}; + +int config_parser_t::read_config(char ***cv, FILE *f) +{ + *cv = (char **)calloc(MAX_CONFIG_LINES, sizeof(char *)); + if(!*cv) + return -1; + + if(!f) + { + free((*cv)); + (*cv) = NULL; + return -2; + } + + fseek(f, 0, SEEK_END); + int len = ftell(f); + (*cv)[0] = (char *)malloc(len+1); + if(!(*cv)[0]) + { + rewind(f); + free(*cv); + *cv = NULL; + return -3; + } + rewind(f); + if(fread((*cv)[0], len, 1, f) < 0) + { + free(*cv[0]); + free(*cv); + *cv = NULL; + return -4; + } + (*cv)[0][len] = 0; + + char *v = (*cv)[0]; + scanstate_t state = SS_BLANK; + int arg = 1; + int start_arg = 0; + while(*v) + { + switch(state) + { + case SS_BLANK: + if(*v == '"') + { + start_arg = 1; + state = SS_QUOTE; + } + else if(*v == '#') + state = SS_COMMENT; + else if(*v > ' ') + { + start_arg = 1; + state = SS_WORD; + } + break; + case SS_QUOTE: + if(*v == '"') + { + *v = 0; + state = SS_BLANK; + } + break; + case SS_WORD: + if(*v <= ' ') + { + *v = 0; + state = SS_BLANK; + } + break; + case SS_COMMENT: + if((*v == 10) || (*v == 13)) + state = SS_BLANK; + break; + } + if(start_arg) + { + if(arg < MAX_CONFIG_LINES) + { + if(state == SS_QUOTE) + (*cv)[arg++] = v+1; + else + (*cv)[arg++] = v; + } + start_arg = 0; + } + ++v; + } + rewind(f); + return arg; +} + + +int config_parser_t::parse(int argc, char *argv[]) +{ + initialize(); + + int i = 0; + while(i < argc) + { + if(argv[i][0] == '#') + { + ++i; + continue; + } + + cfg_key_t *k = keys; + int grabbed = 0; + while(k) + { + if(k->test(argv[i])) + { + grabbed = k->read(argc - i, argv + i); + if(grabbed > 0) + { + k->redefined = 1; + break; + } + else if(grabbed < 0) + { + log_printf(ELOG, "ERROR: Too few parameters to" + " argument '%s'!\n", + k->name); + return -2; + } + } + k = k->next; + } + if(!grabbed) + { + log_printf(ELOG, "ERROR: Unknown argument" + " '%s'!\n", argv[i]); + return -3; + } + i += grabbed; + } + postload(); + return 0; /* Ok. */ +} + + +int config_parser_t::read(FILE *f) +{ + int res = -10; + int cc; + char **cv; + cc = read_config(&cv, f); + if(cc > 0) + { + res = parse(cc, cv); + if(cv) + free(cv[0]); + free(cv); + } + return res; +} + + +int config_parser_t::write(FILE *f) +{ + initialize(); + + presave(); + cfg_key_t *k = keys; + while(k) + { + if(k->save) + k->write(f); + k = k->next; + } + return ferror(f); +} + + +int config_parser_t::_redefined(void *var) +{ + cfg_key_t *k = keys; + while(k) + { + if(k->is_your_var(var)) + return k->redefined; + k = k->next; + } + return 0; +} + + +void config_parser_t::_accept(void *var) +{ + cfg_key_t *k = keys; + while(k) + { + if(k->is_your_var(var)) + { + k->redefined = 0; + break; + } + k = k->next; + } +} + + + +/*---------------------------------------------------------- + Generic Symbol Table Style API +----------------------------------------------------------*/ + +int config_parser_t::find(const char *name) +{ + if(!table) + initialize(); + if(!table) + return -1; + for(int i = 0; i < nkeys; ++i) + if(table[i]->test(name)) + return i; + return -1; +} + + +int config_parser_t::find_next(int symbol) +{ + if(!table) + initialize(); + if(!table) + return -1; + + // Note that this simple code handles the + // "find first" -1 case for free. :-) + ++symbol; + if(symbol < 0) + return -1; + else if(symbol >= nkeys) + return -1; + + return symbol; +} + + +int config_parser_t::check_symbol(int symbol) +{ + if(!table) + return -1; + if(symbol < 0) + return -1; + else if(symbol >= nkeys) + return -1; + return 0; +} + + +cfg_types_t config_parser_t::type(int symbol) +{ + if(check_symbol(symbol) < 0) + return CFG_NONE; + return table[symbol]->typecode; +} + + +int config_parser_t::do_save(int symbol) +{ + if(check_symbol(symbol) < 0) + return CFG_NONE; + return table[symbol]->save; +} + + +const char *config_parser_t::description(int symbol) +{ + if(check_symbol(symbol) < 0) + return ""; + if(table[symbol]->description) + return table[symbol]->description; + else + return ""; +} + + +const char *config_parser_t::name(int symbol) +{ + if(check_symbol(symbol) < 0) + return ""; + if(table[symbol]->name) + return table[symbol]->name; + else + return ""; +} + + +void config_parser_t::set(int symbol, int value) +{ + if(check_symbol(symbol) < 0) + return; + switch(table[symbol]->typecode) + { + case CFG_NONE: + return; + case CFG_BOOL: + { + cfg_switch_t *k = (cfg_switch_t *)table[symbol]; + *(k->value) = value ? 1 : 0; + } + break; + case CFG_INT: + { + cfg_key_int_t *k = (cfg_key_int_t *)table[symbol]; + *(k->value) = value; + } + break; + case CFG_FLOAT: + { + cfg_key_float_t *k = (cfg_key_float_t *)table[symbol]; + *(k->value) = (float)value; + } + break; + case CFG_STRING: + { + cfg_key_string_t *k = (cfg_key_string_t *)table[symbol]; + snprintf(*(k->value), CFG_STRING_LENGTH-1, "%d", value); + } + break; + } + table[symbol]->redefined = 1; +} + + +void config_parser_t::set(int symbol, float value) +{ + if(check_symbol(symbol) < 0) + return; + switch(table[symbol]->typecode) + { + case CFG_NONE: + return; + case CFG_BOOL: + { + cfg_switch_t *k = (cfg_switch_t *)table[symbol]; + *(k->value) = value ? 1 : 0; + } + break; + case CFG_INT: + { + cfg_key_int_t *k = (cfg_key_int_t *)table[symbol]; + *(k->value) = (int)value; + } + break; + case CFG_FLOAT: + { + cfg_key_float_t *k = (cfg_key_float_t *)table[symbol]; + *(k->value) = value; + } + break; + case CFG_STRING: + { + cfg_key_string_t *k = (cfg_key_string_t *)table[symbol]; + snprintf(*(k->value), CFG_STRING_LENGTH-1, "%f", value); + } + break; + } + table[symbol]->redefined = 1; +} + + +void config_parser_t::set(int symbol, const char *text) +{ + if(check_symbol(symbol) < 0) + return; + switch(table[symbol]->typecode) + { + case CFG_NONE: + return; + case CFG_BOOL: + { + /* + * Unfortunately, only *real* operating systems have + * strcasecmp(), so we have to mess around a little. + */ + char buf[16]; + strncpy(buf, text, 15); + for(int i = 0; i < 15; ++i) + buf[i] = tolower(buf[i]); + cfg_switch_t *k = (cfg_switch_t *)table[symbol]; + if( strncmp(buf, "yes", 3) || strncmp(buf, "true", 4) || + strcmp(buf, "on") || strncmp(buf, "enable", 6) || + strncmp(buf, "activ", 5) || + strcmp(buf, "one") || strcmp(buf, "1") ) + *(k->value) = 1; + else + *(k->value) = 0; + } + break; + case CFG_INT: + { + cfg_key_int_t *k = (cfg_key_int_t *)table[symbol]; + *(k->value) = atoi(text); + } + break; + case CFG_FLOAT: + { + cfg_key_float_t *k = (cfg_key_float_t *)table[symbol]; + *(k->value) = atof(text); + } + break; + case CFG_STRING: + { + cfg_key_string_t *k = (cfg_key_string_t *)table[symbol]; + strncpy(*(k->value), text, CFG_STRING_LENGTH-1); + *(k->value)[CFG_STRING_LENGTH-1] = 0; + } + break; + } + table[symbol]->redefined = 1; +} + + +int config_parser_t::get_i(int symbol) +{ + if(check_symbol(symbol) < 0) + return 0; + switch(table[symbol]->typecode) + { + case CFG_NONE: + return 0; + case CFG_BOOL: + { + cfg_switch_t *k = (cfg_switch_t *)table[symbol]; + return *(k->value) ? 1 : 0; + } + case CFG_INT: + { + cfg_key_int_t *k = (cfg_key_int_t *)table[symbol]; + return *(k->value); + } + case CFG_FLOAT: + { + cfg_key_float_t *k = (cfg_key_float_t *)table[symbol]; + return (int)*(k->value); + } + case CFG_STRING: + { + cfg_key_string_t *k = (cfg_key_string_t *)table[symbol]; + return atoi(*(k->value)); + } + } + return 0; +} + + +float config_parser_t::get_f(int symbol) +{ + if(check_symbol(symbol) < 0) + return 0.0; + switch(table[symbol]->typecode) + { + case CFG_NONE: + return 0.0; + case CFG_BOOL: + { + cfg_switch_t *k = (cfg_switch_t *)table[symbol]; + return *(k->value) ? 1.0 : 0.0; + } + case CFG_INT: + { + cfg_key_int_t *k = (cfg_key_int_t *)table[symbol]; + return (float)*(k->value); + } + case CFG_FLOAT: + { + cfg_key_float_t *k = (cfg_key_float_t *)table[symbol]; + return *(k->value); + } + case CFG_STRING: + { + cfg_key_string_t *k = (cfg_key_string_t *)table[symbol]; + return atof(*(k->value)); + } + } + return 0.0; +} + + +const char *config_parser_t::get_s(int symbol) +{ + if(check_symbol(symbol) < 0) + return ""; + switch(table[symbol]->typecode) + { + case CFG_NONE: + return ""; + case CFG_BOOL: + { + cfg_switch_t *k = (cfg_switch_t *)table[symbol]; + return *(k->value) ? "On" : "Off"; + } + case CFG_INT: + { + cfg_key_int_t *k = (cfg_key_int_t *)table[symbol]; + snprintf(retbuf, sizeof(retbuf)-1, "%d", *(k->value)); + return retbuf; + } + case CFG_FLOAT: + { + cfg_key_float_t *k = (cfg_key_float_t *)table[symbol]; + snprintf(retbuf, sizeof(retbuf)-1, "%f", *(k->value)); + return retbuf; + } + case CFG_STRING: + { + cfg_key_string_t *k = (cfg_key_string_t *)table[symbol]; + return *(k->value); + } + break; + } + return ""; +} + + +int config_parser_t::get_default_i(int symbol) +{ + if(check_symbol(symbol) < 0) + return 0; + switch(table[symbol]->typecode) + { + case CFG_NONE: + return 0; + case CFG_BOOL: + { + cfg_switch_t *k = (cfg_switch_t *)table[symbol]; + return k->default_value ? 1 : 0; + } + case CFG_INT: + { + cfg_key_int_t *k = (cfg_key_int_t *)table[symbol]; + return k->default_value; + } + case CFG_FLOAT: + { + cfg_key_float_t *k = (cfg_key_float_t *)table[symbol]; + return (int)k->default_value; + } + case CFG_STRING: + { + cfg_key_string_t *k = (cfg_key_string_t *)table[symbol]; + return atoi(k->default_value); + } + } + return 0; +} + + +float config_parser_t::get_default_f(int symbol) +{ + if(check_symbol(symbol) < 0) + return 0.0; + switch(table[symbol]->typecode) + { + case CFG_NONE: + return 0.0; + case CFG_BOOL: + { + cfg_switch_t *k = (cfg_switch_t *)table[symbol]; + return k->default_value ? 1.0 : 0.0; + } + case CFG_INT: + { + cfg_key_int_t *k = (cfg_key_int_t *)table[symbol]; + return (float)k->default_value; + } + case CFG_FLOAT: + { + cfg_key_float_t *k = (cfg_key_float_t *)table[symbol]; + return k->default_value; + } + case CFG_STRING: + { + cfg_key_string_t *k = (cfg_key_string_t *)table[symbol]; + return atof(k->default_value); + } + } + return 0.0; +} + + +const char *config_parser_t::get_default_s(int symbol) +{ + if(check_symbol(symbol) < 0) + return ""; + switch(table[symbol]->typecode) + { + case CFG_NONE: + return ""; + case CFG_BOOL: + { + cfg_switch_t *k = (cfg_switch_t *)table[symbol]; + return k->default_value ? "On" : "Off"; + } + case CFG_INT: + { + cfg_key_int_t *k = (cfg_key_int_t *)table[symbol]; + snprintf(retbuf, sizeof(retbuf)-1, "%d", k->default_value); + return retbuf; + } + case CFG_FLOAT: + { + cfg_key_float_t *k = (cfg_key_float_t *)table[symbol]; + snprintf(retbuf, sizeof(retbuf)-1, "%f", k->default_value); + return retbuf; + } + case CFG_STRING: + { + cfg_key_string_t *k = (cfg_key_string_t *)table[symbol]; + return k->default_value; + } + break; + } + return ""; +} + diff --git a/cfgparse.h b/cfgparse.h new file mode 100644 index 0000000..356ecf7 --- /dev/null +++ b/cfgparse.h @@ -0,0 +1,199 @@ +/* +------------------------------------------------------------------- + cfgparse.h - Generic Config File and Argument Parser +------------------------------------------------------------------- + * Copyright (C) 2001, 2007 David Olofson + * + * This code is released under the terms of the GNU LGPL. + */ + +#ifndef CFGPARSE_H +#define CFGPARSE_H + +#include + +enum cfg_types_t +{ + CFG_NONE, + CFG_BOOL, + CFG_INT, + CFG_FLOAT, + CFG_STRING +}; + + +#define CFG_STRING_LENGTH 256 + +typedef char cfg_string_t[CFG_STRING_LENGTH]; + + +class cfg_key_t +{ + public: + cfg_key_t *next; + int save; + int redefined; + + cfg_types_t typecode; + const char *name; + char *description; + cfg_key_t(); + virtual ~cfg_key_t(); + virtual int read(int argc, char *argv[]); + virtual int test(const char *arg); + virtual int copy(cfg_key_t *from) = 0; + virtual void write(FILE *f) = 0; + virtual void set_default() = 0; + virtual int is_your_var(void *var) = 0; +}; + + +class cfg_comment_t : public cfg_key_t +{ + public: + cfg_comment_t(const char *text) { name = text; } + int read(int argc, char *argv[]) { return 0; } + int copy(cfg_key_t *from); + void write(FILE *f); + void set_default() { ; } + int is_your_var(void *var) { return 0; } +}; + + +class cfg_switch_t : public cfg_key_t +{ + public: + int *value; + int default_value; + + cfg_switch_t(const char *_name, int &var, int def, int _save); + int copy(cfg_key_t *from); + virtual int test(const char *arg); + int read(int argc, char *argv[]); + void write(FILE *f); + void set_default(); + int is_your_var(void *var); +}; + + +class cfg_key_int_t : public cfg_key_t +{ + public: + int *value; + int default_value; + + cfg_key_int_t(const char *_name, int &var, int def, int _save); + int copy(cfg_key_t *from); + int read(int argc, char *argv[]); + void write(FILE *f); + void set_default(); + int is_your_var(void *var); +}; + + +class cfg_key_float_t : public cfg_key_t +{ + public: + float *value; + float default_value; + + cfg_key_float_t(const char *_name, float &var, float def, int _save); + int copy(cfg_key_t *from); + int read(int argc, char *argv[]); + void write(FILE *f); + void set_default(); + int is_your_var(void *var); +}; + + +class cfg_key_string_t : public cfg_key_t +{ + public: + cfg_string_t *value; + cfg_string_t default_value; + + cfg_key_string_t(const char *_name, cfg_string_t &var, + const cfg_string_t def, int _save); + int copy(cfg_key_t *from); + int read(int argc, char *argv[]); + void write(FILE *f); + void set_default(); + int is_your_var(void *var); +}; + + +class config_parser_t +{ + cfg_key_t *keys, *last_key; + int initialized; + int nkeys; // For symbol table API + cfg_key_t **table; // For symbol table API + cfg_string_t retbuf; // For symbol table API + void initialize(); + void print_switch(FILE *f, const char *base, int flag); + int read_config(char ***cv, FILE *f); + void add(cfg_key_t *_key); + int _redefined(void *var); + void _accept(void *var); + void build_table(); + int check_symbol(int symbol); + protected: + //Key registration: For use in inherited init() + void comment(const char *text); + void yesno(const char *name, int &var, int def, int save = 1); + void command(const char *name, int &var); + void key(const char *name, int &var, int def, int save = 1); + void key(const char *name, float &var, float def, int save = 1); + void key(const char *name, cfg_string_t &var, const cfg_string_t def, + int save = 1); + void desc(const char *text); + + //Plug key registration and custom stuff in here! + virtual void init() = 0; + virtual void postload() { ; } + virtual void presave() { ; } + public: + int changed; //Set when *edited* by the user + config_parser_t(); + virtual ~config_parser_t(); + config_parser_t &operator = (config_parser_t &from); + void set_defaults(); + int parse(int argc, char *argv[]); + int read(FILE *f); + int write(FILE *f); + + //Changed since last accept() call? + int redefined(int &var) { return _redefined(&var); } + int redefined(float &var) { return _redefined(&var); } + int redefined(cfg_string_t &var) { return _redefined(&var); } + + //Reset redefined() state to 0. + void accept(int &var) { _accept(&var); } + void accept(float &var) { _accept(&var); } + void accept(cfg_string_t &var) { _accept(&var); } + + /* Generic Symbol Table Style API */ + int find(const char *name); + int find_next(int symbol = -1); + cfg_types_t type(int symbol); + int do_save(int symbol); + const char *name(int symbol); + const char *description(int symbol); + void set(int symbol, int value); + void set(int symbol, float value); + void set(int symbol, const char *text); + int get_i(int symbol); + int get_default_i(int symbol); + float get_f(int symbol); + float get_default_f(int symbol); + /* + * WARNING: These ones sometimes return pointers to non-constant + * buffers! Therefore, you need to copy the results + * before you call these functions again. + */ + const char *get_s(int symbol); + const char *get_default_s(int symbol); +}; + + +#endif //CFGPARSE_H diff --git a/compile b/compile new file mode 100755 index 0000000..9bb997a --- /dev/null +++ b/compile @@ -0,0 +1,99 @@ +#! /bin/sh + +# Wrapper for compilers which do not understand `-c -o'. + +# Copyright 1999, 2000 Free Software Foundation, Inc. +# Written by Tom Tromey . +# +# 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, 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. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Usage: +# compile PROGRAM [ARGS]... +# `-o FOO.o' is removed from the args passed to the actual compile. + +prog=$1 +shift + +ofile= +cfile= +args= +while test $# -gt 0; do + case "$1" in + -o) + # configure might choose to run compile as `compile cc -o foo foo.c'. + # So we do something ugly here. + ofile=$2 + shift + case "$ofile" in + *.o | *.obj) + ;; + *) + args="$args -o $ofile" + ofile= + ;; + esac + ;; + *.c) + cfile=$1 + args="$args $1" + ;; + *) + args="$args $1" + ;; + esac + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no `-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # `.c' file was seen then we are probably linking. That is also + # ok. + exec "$prog" $args +fi + +# Name of file we expect compiler to create. +cofile=`echo $cfile | sed -e 's|^.*/||' -e 's/\.c$/.o/'` + +# Create the lock directory. +# Note: use `[/.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo $cofile | sed -e 's|[/.-]|_|g'`.d +while true; do + if mkdir $lockdir > /dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir $lockdir; exit 1" 1 2 15 + +# Run the compile. +"$prog" $args +status=$? + +if test -f "$cofile"; then + mv "$cofile" "$ofile" +fi + +rmdir $lockdir +exit $status diff --git a/config.guess b/config.guess new file mode 100755 index 0000000..9e55e1a --- /dev/null +++ b/config.guess @@ -0,0 +1,1391 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + +timestamp='2003-05-19' + +# This file 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. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + macppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvmeppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mipseb-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + DRS?6000:UNIX_SV:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7 && exit 0 ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c \ + && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && exit 0 + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + # avoid double evaluation of $set_cc_for_build + test -n "$CC_FOR_BUILD" || eval $set_cc_for_build + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + *:UNICOS/mp:*:*) + echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*|*:GNU/FreeBSD:*:*) + # Determine whether the default compiler uses glibc. + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #if __GLIBC__ >= 2 + LIBC=gnu + #else + LIBC= + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC} + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + x86:Interix*:3*) + echo i586-pc-interix3 + exit 0 ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit 0 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit 0 ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit 0 ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i*86:*:5:[78]*) + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit 0 ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit 0 ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + case `uname -p` in + *86) UNAME_PROCESSOR=i686 ;; + powerpc) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0 + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.h b/config.h new file mode 100644 index 0000000..375bbd1 --- /dev/null +++ b/config.h @@ -0,0 +1,149 @@ +/*(GPL) +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 1995, 1996, Akira Higuchi + * Copyright (C) 2001-2003, David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _KOBO_CONFIG_H_ +#define _KOBO_CONFIG_H_ + +#include + +#ifndef DEBUG +# undef DBG +# undef DBG2 +# undef DBG3 +# undef DBG4 +# define DBG(x) +# define DBG2(x) +# define DBG3(x) +# define DBG4(x) +#endif + +#ifndef HAVE_SNPRINTF +#ifndef HAVE__SNPRINTF +#error Must have snprintf() or _snprintf! +#endif +#define snprintf _snprintf +#endif + +#ifndef HAVE_VSNPRINTF +#ifndef HAVE__VSNPRINTF +#error Must have vsnprintf() or _vsnprintf! +#endif +#define vsnprintf _vsnprintf +#endif + +/* + * On some platforms, assignments of these "opaque objects" are + * illegal - while on others, the macro to handle that can be + * missing... Oh, and this is really only in C99, of course. :-/ + */ +#include +#ifndef va_copy +# ifdef __va_copy +# define va_copy(to, from) __va_copy(to, from) +# else +# define va_copy(to, from) (to) = (from) +# endif +#endif + +/* Key/button repeat timing */ +#define KOBO_KEY_DELAY 250 +#define KOBO_KEY_REPEAT 40 + +/* + * This was originally 1024, but was changed in Kobo Deluxe 0.4.1 + * to avoid the bug where we run out of enemies when destroying a + * base, and thus leave parts of it behind. + */ +#define ENEMY_MAX 2048 + +/* + * Game display size. + * + * In XKobo, there was only WSIZE - VIEWLIMIT was added + * for Kobo Deluxe, and WSIZE was set to 230, to add some + * extra pixels, most of which were more or less covered + * by the rounded framework. + * + * As of Kobo Deluxe 0.4.1, WSIZE is restored to the + * original 224. + * + * Note that if WSIZE is larger than VIEWLIMIT, some + * objects might be created or deleted in view. Finding + * out whether or not it can really happen calls for + * closer analysis of the code. + */ +#define WSIZE 224 +#define MARGIN 8 + +/* + * (In XKobo, WSIZE was used where this is + * used now; in the game logic code.) + * + * NOTE: I *DON'T* want to change the view + * range as the XKobo engine knows it, + * as that would make the game play + * slightly differently. (Probably not + * so that anyone would notice, but + * let's not take chances... This is + * NOT "Kobo II".) + */ +#define VIEWLIMIT 224 + +// Player ship hit rect size +#define HIT_MYSHIP 5 + +// Player bolt hit rect size +#define HIT_BOLT 5 + +/* Actually, this is not the *full* size in windowed mode any more. */ +#define SCREEN_WIDTH 320 +#define SCREEN_HEIGHT 240 + +/* Various size info (DO NOT EDIT!) */ +#define CHIP_SIZEX_LOG2 4 +#define CHIP_SIZEY_LOG2 4 +#define MAP_SIZEX_LOG2 6 +#define MAP_SIZEY_LOG2 7 +#define WORLD_SIZEX_LOG2 (MAP_SIZEX_LOG2+CHIP_SIZEX_LOG2) +#define WORLD_SIZEY_LOG2 (MAP_SIZEY_LOG2+CHIP_SIZEY_LOG2) +#define NOISE_SIZEX_LOG2 8 + +#define CHIP_SIZEX (1<. Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k \ + | m32r | m68000 | m68k | m88k | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | msp430 \ + | ns16k | ns32k \ + | openrisc | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* \ + | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* \ + | m32r-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | msp430-* \ + | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ + | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ + | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nv1) + basic_machine=nv1-cray + os=-unicosmp + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + or32 | or32-*) + basic_machine=or32-unknown + os=-coff + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2) + basic_machine=i686-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic4x | c4x*) + basic_machine=tic4x-unknown + os=-coff + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparc | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure b/configure new file mode 100755 index 0000000..90b3a55 --- /dev/null +++ b/configure @@ -0,0 +1,12135 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.61. +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + +if test "x$CONFIG_SHELL" = x; then + if (eval ":") 2>/dev/null; then + as_have_required=yes +else + as_have_required=no +fi + + if test $as_have_required = yes && (eval ": +(as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=\$LINENO + as_lineno_2=\$LINENO + test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && + test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } +") 2> /dev/null; then + : +else + as_candidate_shells= + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + case $as_dir in + /*) + for as_base in sh bash ksh sh5; do + as_candidate_shells="$as_candidate_shells $as_dir/$as_base" + done;; + esac +done +IFS=$as_save_IFS + + + for as_shell in $as_candidate_shells $SHELL; do + # Try only shells that exist, to save several forks. + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { ("$as_shell") 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +_ASEOF +}; then + CONFIG_SHELL=$as_shell + as_have_required=yes + if { "$as_shell" 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +(as_func_return () { + (exit $1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = "$1" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test $exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } + +_ASEOF +}; then + break +fi + +fi + + done + + if test "x$CONFIG_SHELL" != x; then + for as_var in BASH_ENV ENV + do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + done + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + + if test $as_have_required = no; then + echo This script requires a shell more modern than all the + echo shells that I found on your system. Please install a + echo modern shell, or manually run the script under such a + echo shell if you do have one. + { (exit 1); exit 1; } +fi + + +fi + +fi + + + +(eval "as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0") || { + echo No shell found that supports shell functions. + echo Please tell autoconf@gnu.org about your system, + echo including any error possibly output before this + echo message +} + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + + +exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + +ac_unique_file="Makefile.am" +ac_unique_file="Makefile.am" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='SHELL +PATH_SEPARATOR +PACKAGE_NAME +PACKAGE_TARNAME +PACKAGE_VERSION +PACKAGE_STRING +PACKAGE_BUGREPORT +exec_prefix +prefix +program_transform_name +bindir +sbindir +libexecdir +datarootdir +datadir +sysconfdir +sharedstatedir +localstatedir +includedir +oldincludedir +docdir +infodir +htmldir +dvidir +pdfdir +psdir +libdir +localedir +mandir +DEFS +ECHO_C +ECHO_N +ECHO_T +LIBS +build_alias +host_alias +target_alias +build +build_cpu +build_vendor +build_os +host +host_cpu +host_vendor +host_os +target +target_cpu +target_vendor +target_os +INSTALL_PROGRAM +INSTALL_SCRIPT +INSTALL_DATA +CYGPATH_W +PACKAGE +VERSION +ACLOCAL +AUTOCONF +AUTOMAKE +AUTOHEADER +MAKEINFO +install_sh +STRIP +INSTALL_STRIP_PROGRAM +mkdir_p +AWK +SET_MAKE +am__leading_dot +AMTAR +am__tar +am__untar +XMKMF +CC +CFLAGS +LDFLAGS +CPPFLAGS +ac_ct_CC +EXEEXT +OBJEXT +DEPDIR +am__include +am__quote +AMDEP_TRUE +AMDEP_FALSE +AMDEPBACKSLASH +CCDEPMODE +am__fastdepCC_TRUE +am__fastdepCC_FALSE +CPP +X_CFLAGS +X_PRE_LIBS +X_LIBS +X_EXTRA_LIBS +BUILD_MACOSX_BUNDLE_TRUE +BUILD_MACOSX_BUNDLE_FALSE +BUILD_SIMPLE_BUNDLE_TRUE +BUILD_SIMPLE_BUNDLE_FALSE +UNIX_SCOREDIR_TRUE +UNIX_SCOREDIR_FALSE +DATADIR +SCOREDIR +CONFIGDIR +CONFIGFILE +EXEFILE +MATHLIB +CXX +CXXFLAGS +ac_ct_CXX +CXXDEPMODE +am__fastdepCXX_TRUE +am__fastdepCXX_FALSE +RANLIB +SDL_CONFIG +SDL_CFLAGS +SDL_LIBS +GREP +EGREP +LIBOBJS +POW_LIB +AUDIO_LIBS +LOCALCFLAGS +LTLIBOBJS' +ac_subst_files='' + ac_precious_vars='build_alias +host_alias +target_alias +XMKMF +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP +CXX +CXXFLAGS +CCC' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=\$ac_optarg ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute directory names. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; } +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + { echo "$as_me: error: Working directory cannot be determined" >&2 + { (exit 1); exit 1; }; } +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + { echo "$as_me: error: pwd does not report name of working directory" >&2 + { (exit 1); exit 1; }; } + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$0" || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 + { (exit 1); exit 1; }; } + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +X features: + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] + --target=TARGET configure for building compilers for TARGET [HOST] +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + --enable-debug Build with debug switches and defines default=no + --disable-sdltest Do not try to compile and run a test SDL program + --enable-opengl use OpenGL rendering layer default=yes + --enable-oss support the OSS audio API default=no + --enable-alsa support the ALSA audio API default=no + --enable-epm Compile with extremely picky settings default=no + --enable-efence Link with ElectricFence default=no + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-x use the X Window System + --with-sdl-prefix=PFX Prefix where SDL is installed (optional) + --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional) + +Some influential environment variables: + XMKMF Path to xmkmf, Makefile generator for X Window System + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + CXX C++ compiler command + CXXFLAGS C++ compiler flags + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +configure +generated by GNU Autoconf 2.61 + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.61. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args '$ac_arg'" + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------------- ## +## File substitutions. ## +## ------------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -n "$CONFIG_SITE"; then + set x "$CONFIG_SITE" +elif test "x$prefix" != xNONE; then + set x "$prefix/share/config.site" "$prefix/etc/config.site" +else + set x "$ac_default_prefix/share/config.site" \ + "$ac_default_prefix/etc/config.site" +fi +shift +for ac_site_file +do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + + + + + + + + + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +ac_config_headers="$ac_config_headers aconfig.h" + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 +echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} + { (exit 1); exit 1; }; } +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 +echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} + { (exit 1); exit 1; }; } + +{ echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6; } +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 +echo "$as_me: error: invalid value of canonical build" >&2;} + { (exit 1); exit 1; }; };; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6; } +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} + { (exit 1); exit 1; }; } +fi + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 +echo "$as_me: error: invalid value of canonical host" >&2;} + { (exit 1); exit 1; }; };; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +{ echo "$as_me:$LINENO: checking target system type" >&5 +echo $ECHO_N "checking target system type... $ECHO_C" >&6; } +if test "${ac_cv_target+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "x$target_alias" = x; then + ac_cv_target=$ac_cv_host +else + ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&2;} + { (exit 1); exit 1; }; } +fi + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_target" >&5 +echo "${ECHO_T}$ac_cv_target" >&6; } +case $ac_cv_target in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical target" >&5 +echo "$as_me: error: invalid value of canonical target" >&2;} + { (exit 1); exit 1; }; };; +esac +target=$ac_cv_target +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_target +shift +target_cpu=$1 +target_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +target_os=$* +IFS=$ac_save_IFS +case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac + + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +test -n "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- +am__api_version="1.9" +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done +IFS=$as_save_IFS + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ echo "$as_me:$LINENO: checking whether build environment is sane" >&5 +echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&5 +echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&2;} + { (exit 1); exit 1; }; } + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! +Check your system clock" >&5 +echo "$as_me: error: newly created file is older than distributed files! +Check your system clock" >&2;} + { (exit 1); exit 1; }; } +fi +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. echo might interpret backslashes. +# By default was `s,x,x', remove it if useless. +cat <<\_ACEOF >conftest.sed +s/[\\$]/&&/g;s/;s,x,x,$// +_ACEOF +program_transform_name=`echo $program_transform_name | sed -f conftest.sed` +rm -f conftest.sed + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 +echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + # We used to keeping the `.' as first argument, in order to + # allow $(mkdir_p) to be used without argument. As in + # $(mkdir_p) $(somedir) + # where $(somedir) is conditionally defined. However this is wrong + # for two reasons: + # 1. if the package is installed by a user who cannot write `.' + # make install will fail, + # 2. the above comment should most certainly read + # $(mkdir_p) $(DESTDIR)$(somedir) + # so it does not work when $(somedir) is undefined and + # $(DESTDIR) is not. + # To support the latter case, we have to write + # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), + # so the `.' trick is pointless. + mkdir_p='mkdir -p --' +else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + for d in ./-p ./--version; + do + test -d $d && rmdir $d + done + # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. + if test -f "$ac_aux_dir/mkinstalldirs"; then + mkdir_p='$(mkinstalldirs)' + else + mkdir_p='$(install_sh) -d' + fi +fi + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_AWK+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { echo "$as_me:$LINENO: result: $AWK" >&5 +echo "${ECHO_T}$AWK" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; } +set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + SET_MAKE= +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 +echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} + { (exit 1); exit 1; }; } +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE=KoboDeluxe + VERSION=0.5.1 + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +install_sh=${install_sh-"$am_aux_dir/install-sh"} + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +echo "${ECHO_T}$ac_ct_STRIP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. + +AMTAR=${AMTAR-"${am_missing_run}tar"} + +am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' + + + + + + +LOCALCFLAGS='' + + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 +echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi + + +{ echo "$as_me:$LINENO: result: $_am_result" >&5 +echo "${ECHO_T}$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi + + +if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +# +# List of possible output files, starting from the most likely. +# The algorithm is not robust to junk in `.', hence go to wildcards (a.*) +# only as a last resort. b.out is created by i960 compilers. +ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' +# +# The IRIX 6 linker writes into existing files which may not be +# executable, retaining their permissions. Remove them first so a +# subsequent execution test works. +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { (ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi + +{ echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6; } +if test -z "$ac_file"; then + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext + +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6; } + +{ echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +{ echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_c89=$ac_arg +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6; } ;; + xno) + { echo "$as_me:$LINENO: result: unsupported" >&5 +echo "${ECHO_T}unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; +esac + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CC" am_compiler_list= + +{ echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; } +if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 +echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + + +if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ echo "$as_me:$LINENO: checking for X" >&5 +echo $ECHO_N "checking for X... $ECHO_C" >&6; } + + +# Check whether --with-x was given. +if test "${with_x+set}" = set; then + withval=$with_x; +fi + +# $have_x is `yes', `no', `disabled', or empty when we do not yet know. +if test "x$with_x" = xno; then + # The user explicitly disabled X. + have_x=disabled +else + case $x_includes,$x_libraries in #( + *\'*) { { echo "$as_me:$LINENO: error: Cannot use X directory names containing '" >&5 +echo "$as_me: error: Cannot use X directory names containing '" >&2;} + { (exit 1); exit 1; }; };; #( + *,NONE | NONE,*) if test "${ac_cv_have_x+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # One or both of the vars are not set, and there is no cached value. +ac_x_includes=no ac_x_libraries=no +rm -f -r conftest.dir +if mkdir conftest.dir; then + cd conftest.dir + cat >Imakefile <<'_ACEOF' +incroot: + @echo incroot='${INCROOT}' +usrlibdir: + @echo usrlibdir='${USRLIBDIR}' +libdir: + @echo libdir='${LIBDIR}' +_ACEOF + if (export CC; ${XMKMF-xmkmf}) >/dev/null 2>/dev/null && test -f Makefile; then + # GNU make sometimes prints "make[1]: Entering...", which would confuse us. + for ac_var in incroot usrlibdir libdir; do + eval "ac_im_$ac_var=\`\${MAKE-make} $ac_var 2>/dev/null | sed -n 's/^$ac_var=//p'\`" + done + # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. + for ac_extension in a so sl; do + if test ! -f "$ac_im_usrlibdir/libX11.$ac_extension" && + test -f "$ac_im_libdir/libX11.$ac_extension"; then + ac_im_usrlibdir=$ac_im_libdir; break + fi + done + # Screen out bogus values from the imake configuration. They are + # bogus both because they are the default anyway, and because + # using them would break gcc on systems where it needs fixed includes. + case $ac_im_incroot in + /usr/include) ac_x_includes= ;; + *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;; + esac + case $ac_im_usrlibdir in + /usr/lib | /lib) ;; + *) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;; + esac + fi + cd .. + rm -f -r conftest.dir +fi + +# Standard set of common directories for X headers. +# Check X11 before X11Rn because it is often a symlink to the current release. +ac_x_header_dirs=' +/usr/X11/include +/usr/X11R6/include +/usr/X11R5/include +/usr/X11R4/include + +/usr/include/X11 +/usr/include/X11R6 +/usr/include/X11R5 +/usr/include/X11R4 + +/usr/local/X11/include +/usr/local/X11R6/include +/usr/local/X11R5/include +/usr/local/X11R4/include + +/usr/local/include/X11 +/usr/local/include/X11R6 +/usr/local/include/X11R5 +/usr/local/include/X11R4 + +/usr/X386/include +/usr/x386/include +/usr/XFree86/include/X11 + +/usr/include +/usr/local/include +/usr/unsupported/include +/usr/athena/include +/usr/local/x11r5/include +/usr/lpp/Xamples/include + +/usr/openwin/include +/usr/openwin/share/include' + +if test "$ac_x_includes" = no; then + # Guess where to find include files, by looking for Xlib.h. + # First, try using that file with no special directory specified. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # We can compile using X headers with no special include directory. +ac_x_includes= +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + for ac_dir in $ac_x_header_dirs; do + if test -r "$ac_dir/X11/Xlib.h"; then + ac_x_includes=$ac_dir + break + fi +done +fi + +rm -f conftest.err conftest.$ac_ext +fi # $ac_x_includes = no + +if test "$ac_x_libraries" = no; then + # Check for the libraries. + # See if we find them without any special options. + # Don't add to $LIBS permanently. + ac_save_LIBS=$LIBS + LIBS="-lX11 $LIBS" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +XrmInitialize () + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + LIBS=$ac_save_LIBS +# We can link X programs with no special library path. +ac_x_libraries= +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + LIBS=$ac_save_LIBS +for ac_dir in `echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g` +do + # Don't even attempt the hair of trying to link an X program! + for ac_extension in a so sl; do + if test -r "$ac_dir/libX11.$ac_extension"; then + ac_x_libraries=$ac_dir + break 2 + fi + done +done +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi # $ac_x_libraries = no + +case $ac_x_includes,$ac_x_libraries in #( + no,* | *,no | *\'*) + # Didn't find X, or a directory has "'" in its name. + ac_cv_have_x="have_x=no";; #( + *) + # Record where we found X for the cache. + ac_cv_have_x="have_x=yes\ + ac_x_includes='$ac_x_includes'\ + ac_x_libraries='$ac_x_libraries'" +esac +fi +;; #( + *) have_x=yes;; + esac + eval "$ac_cv_have_x" +fi # $with_x != no + +if test "$have_x" != yes; then + { echo "$as_me:$LINENO: result: $have_x" >&5 +echo "${ECHO_T}$have_x" >&6; } + no_x=yes +else + # If each of the values was on the command line, it overrides each guess. + test "x$x_includes" = xNONE && x_includes=$ac_x_includes + test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries + # Update the cache value to reflect the command line values. + ac_cv_have_x="have_x=yes\ + ac_x_includes='$x_includes'\ + ac_x_libraries='$x_libraries'" + { echo "$as_me:$LINENO: result: libraries $x_libraries, headers $x_includes" >&5 +echo "${ECHO_T}libraries $x_libraries, headers $x_includes" >&6; } +fi + +if test "$no_x" = yes; then + # Not all programs may use this symbol, but it does not hurt to define it. + +cat >>confdefs.h <<\_ACEOF +#define X_DISPLAY_MISSING 1 +_ACEOF + + X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS= +else + if test -n "$x_includes"; then + X_CFLAGS="$X_CFLAGS -I$x_includes" + fi + + # It would also be nice to do this for all -L options, not just this one. + if test -n "$x_libraries"; then + X_LIBS="$X_LIBS -L$x_libraries" + # For Solaris; some versions of Sun CC require a space after -R and + # others require no space. Words are not sufficient . . . . + { echo "$as_me:$LINENO: checking whether -R must be followed by a space" >&5 +echo $ECHO_N "checking whether -R must be followed by a space... $ECHO_C" >&6; } + ac_xsave_LIBS=$LIBS; LIBS="$LIBS -R$x_libraries" + ac_xsave_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + X_LIBS="$X_LIBS -R$x_libraries" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + LIBS="$ac_xsave_LIBS -R $x_libraries" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + X_LIBS="$X_LIBS -R $x_libraries" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: result: neither works" >&5 +echo "${ECHO_T}neither works" >&6; } +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + ac_c_werror_flag=$ac_xsave_c_werror_flag + LIBS=$ac_xsave_LIBS + fi + + # Check for system-dependent libraries X programs must link with. + # Do this before checking for the system-independent R6 libraries + # (-lICE), since we may need -lsocket or whatever for X linking. + + if test "$ISC" = yes; then + X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet" + else + # Martyn Johnson says this is needed for Ultrix, if the X + # libraries were built with DECnet support. And Karl Berry says + # the Alpha needs dnet_stub (dnet does not exist). + ac_xsave_LIBS="$LIBS"; LIBS="$LIBS $X_LIBS -lX11" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char XOpenDisplay (); +int +main () +{ +return XOpenDisplay (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: checking for dnet_ntoa in -ldnet" >&5 +echo $ECHO_N "checking for dnet_ntoa in -ldnet... $ECHO_C" >&6; } +if test "${ac_cv_lib_dnet_dnet_ntoa+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldnet $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dnet_ntoa (); +int +main () +{ +return dnet_ntoa (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_dnet_dnet_ntoa=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_dnet_dnet_ntoa=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_dnet_dnet_ntoa" >&5 +echo "${ECHO_T}$ac_cv_lib_dnet_dnet_ntoa" >&6; } +if test $ac_cv_lib_dnet_dnet_ntoa = yes; then + X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet" +fi + + if test $ac_cv_lib_dnet_dnet_ntoa = no; then + { echo "$as_me:$LINENO: checking for dnet_ntoa in -ldnet_stub" >&5 +echo $ECHO_N "checking for dnet_ntoa in -ldnet_stub... $ECHO_C" >&6; } +if test "${ac_cv_lib_dnet_stub_dnet_ntoa+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldnet_stub $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dnet_ntoa (); +int +main () +{ +return dnet_ntoa (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_dnet_stub_dnet_ntoa=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_dnet_stub_dnet_ntoa=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5 +echo "${ECHO_T}$ac_cv_lib_dnet_stub_dnet_ntoa" >&6; } +if test $ac_cv_lib_dnet_stub_dnet_ntoa = yes; then + X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub" +fi + + fi +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$ac_xsave_LIBS" + + # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT, + # to get the SysV transport functions. + # Chad R. Larson says the Pyramis MIS-ES running DC/OSx (SVR4) + # needs -lnsl. + # The nsl library prevents programs from opening the X display + # on Irix 5.2, according to T.E. Dickey. + # The functions gethostbyname, getservbyname, and inet_addr are + # in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking. + { echo "$as_me:$LINENO: checking for gethostbyname" >&5 +echo $ECHO_N "checking for gethostbyname... $ECHO_C" >&6; } +if test "${ac_cv_func_gethostbyname+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define gethostbyname to an innocuous variant, in case declares gethostbyname. + For example, HP-UX 11i declares gettimeofday. */ +#define gethostbyname innocuous_gethostbyname + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char gethostbyname (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef gethostbyname + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gethostbyname (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_gethostbyname || defined __stub___gethostbyname +choke me +#endif + +int +main () +{ +return gethostbyname (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_func_gethostbyname=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_gethostbyname=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5 +echo "${ECHO_T}$ac_cv_func_gethostbyname" >&6; } + + if test $ac_cv_func_gethostbyname = no; then + { echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5 +echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6; } +if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gethostbyname (); +int +main () +{ +return gethostbyname (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_nsl_gethostbyname=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_nsl_gethostbyname=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5 +echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6; } +if test $ac_cv_lib_nsl_gethostbyname = yes; then + X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl" +fi + + if test $ac_cv_lib_nsl_gethostbyname = no; then + { echo "$as_me:$LINENO: checking for gethostbyname in -lbsd" >&5 +echo $ECHO_N "checking for gethostbyname in -lbsd... $ECHO_C" >&6; } +if test "${ac_cv_lib_bsd_gethostbyname+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lbsd $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gethostbyname (); +int +main () +{ +return gethostbyname (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_bsd_gethostbyname=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_bsd_gethostbyname=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_bsd_gethostbyname" >&5 +echo "${ECHO_T}$ac_cv_lib_bsd_gethostbyname" >&6; } +if test $ac_cv_lib_bsd_gethostbyname = yes; then + X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd" +fi + + fi + fi + + # lieder@skyler.mavd.honeywell.com says without -lsocket, + # socket/setsockopt and other routines are undefined under SCO ODT + # 2.0. But -lsocket is broken on IRIX 5.2 (and is not necessary + # on later versions), says Simon Leinen: it contains gethostby* + # variants that don't use the name server (or something). -lsocket + # must be given before -lnsl if both are needed. We assume that + # if connect needs -lnsl, so does gethostbyname. + { echo "$as_me:$LINENO: checking for connect" >&5 +echo $ECHO_N "checking for connect... $ECHO_C" >&6; } +if test "${ac_cv_func_connect+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define connect to an innocuous variant, in case declares connect. + For example, HP-UX 11i declares gettimeofday. */ +#define connect innocuous_connect + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char connect (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef connect + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char connect (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_connect || defined __stub___connect +choke me +#endif + +int +main () +{ +return connect (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_func_connect=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_connect=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_connect" >&5 +echo "${ECHO_T}$ac_cv_func_connect" >&6; } + + if test $ac_cv_func_connect = no; then + { echo "$as_me:$LINENO: checking for connect in -lsocket" >&5 +echo $ECHO_N "checking for connect in -lsocket... $ECHO_C" >&6; } +if test "${ac_cv_lib_socket_connect+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $X_EXTRA_LIBS $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char connect (); +int +main () +{ +return connect (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_socket_connect=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_socket_connect=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_socket_connect" >&5 +echo "${ECHO_T}$ac_cv_lib_socket_connect" >&6; } +if test $ac_cv_lib_socket_connect = yes; then + X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS" +fi + + fi + + # Guillermo Gomez says -lposix is necessary on A/UX. + { echo "$as_me:$LINENO: checking for remove" >&5 +echo $ECHO_N "checking for remove... $ECHO_C" >&6; } +if test "${ac_cv_func_remove+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define remove to an innocuous variant, in case declares remove. + For example, HP-UX 11i declares gettimeofday. */ +#define remove innocuous_remove + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char remove (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef remove + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char remove (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_remove || defined __stub___remove +choke me +#endif + +int +main () +{ +return remove (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_func_remove=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_remove=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_remove" >&5 +echo "${ECHO_T}$ac_cv_func_remove" >&6; } + + if test $ac_cv_func_remove = no; then + { echo "$as_me:$LINENO: checking for remove in -lposix" >&5 +echo $ECHO_N "checking for remove in -lposix... $ECHO_C" >&6; } +if test "${ac_cv_lib_posix_remove+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lposix $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char remove (); +int +main () +{ +return remove (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_posix_remove=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_posix_remove=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_posix_remove" >&5 +echo "${ECHO_T}$ac_cv_lib_posix_remove" >&6; } +if test $ac_cv_lib_posix_remove = yes; then + X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix" +fi + + fi + + # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. + { echo "$as_me:$LINENO: checking for shmat" >&5 +echo $ECHO_N "checking for shmat... $ECHO_C" >&6; } +if test "${ac_cv_func_shmat+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define shmat to an innocuous variant, in case declares shmat. + For example, HP-UX 11i declares gettimeofday. */ +#define shmat innocuous_shmat + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char shmat (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef shmat + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shmat (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_shmat || defined __stub___shmat +choke me +#endif + +int +main () +{ +return shmat (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_func_shmat=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_shmat=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_shmat" >&5 +echo "${ECHO_T}$ac_cv_func_shmat" >&6; } + + if test $ac_cv_func_shmat = no; then + { echo "$as_me:$LINENO: checking for shmat in -lipc" >&5 +echo $ECHO_N "checking for shmat in -lipc... $ECHO_C" >&6; } +if test "${ac_cv_lib_ipc_shmat+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lipc $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shmat (); +int +main () +{ +return shmat (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_ipc_shmat=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_ipc_shmat=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_ipc_shmat" >&5 +echo "${ECHO_T}$ac_cv_lib_ipc_shmat" >&6; } +if test $ac_cv_lib_ipc_shmat = yes; then + X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc" +fi + + fi + fi + + # Check for libraries that X11R6 Xt/Xaw programs need. + ac_save_LDFLAGS=$LDFLAGS + test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries" + # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to + # check for ICE first), but we must link in the order -lSM -lICE or + # we get undefined symbols. So assume we have SM if we have ICE. + # These have to be linked with before -lX11, unlike the other + # libraries we check for below, so use a different variable. + # John Interrante, Karl Berry + { echo "$as_me:$LINENO: checking for IceConnectionNumber in -lICE" >&5 +echo $ECHO_N "checking for IceConnectionNumber in -lICE... $ECHO_C" >&6; } +if test "${ac_cv_lib_ICE_IceConnectionNumber+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lICE $X_EXTRA_LIBS $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char IceConnectionNumber (); +int +main () +{ +return IceConnectionNumber (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_ICE_IceConnectionNumber=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_ICE_IceConnectionNumber=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5 +echo "${ECHO_T}$ac_cv_lib_ICE_IceConnectionNumber" >&6; } +if test $ac_cv_lib_ICE_IceConnectionNumber = yes; then + X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE" +fi + + LDFLAGS=$ac_save_LDFLAGS + +fi + + + +{ echo "$as_me:$LINENO: checking target platform and install style" >&5 +echo $ECHO_N "checking target platform and install style... $ECHO_C" >&6; }; +build_macosx_bundle=no +build_simple_bundle=no +unix_scoredir=yes +DATADIR='$(datadir)/kobo-deluxe' +SCOREDIR='$(sharedstatedir)/kobo-deluxe/scores' +CONFIGDIR='HOME>>' +CONFIGFILE='.kobodlrc' +EXEFILE=kobodl +case "$target_os" in + linux*) + { echo "$as_me:$LINENO: result: GNU/Linux; Un*x style" >&5 +echo "${ECHO_T}GNU/Linux; Un*x style" >&6; } + MATHLIB="-lm" + if test x$have_x = xyes; then + CFLAGS="$CFLAGS $X_CFLAGS" + fi + ;; + beos) + { echo "$as_me:$LINENO: result: BeOS; Un*x style install" >&5 +echo "${ECHO_T}BeOS; Un*x style install" >&6; } + MATHLIB="" + ;; + mingw32*) + { echo "$as_me:$LINENO: result: Win32 (mingw32); Simple bundle" >&5 +echo "${ECHO_T}Win32 (mingw32); Simple bundle" >&6; } + build_simple_bundle=yes + unix_scoredir=no + DATADIR='EXE>>' + SCOREDIR='EXE>>scores' + CONFIGDIR='EXE>>' + CONFIGFILE='kobodl.cfg' + EXEFILE=kobodl.exe + MATHLIB="" + ;; + cygwin*) + { echo "$as_me:$LINENO: result: Win32 (cygwin); Simple bundle" >&5 +echo "${ECHO_T}Win32 (cygwin); Simple bundle" >&6; } + build_simple_bundle=yes + unix_scoredir=no + DATADIR='EXE>>' + SCOREDIR='EXE>>scores' + CONFIGDIR='EXE>>' + CONFIGFILE='kobodl.cfg' + EXEFILE=kobodl.exe + MATHLIB="" + ;; + darwin*) + { echo "$as_me:$LINENO: result: Mac OS X/Darwin; Mac OS X bundle" >&5 +echo "${ECHO_T}Mac OS X/Darwin; Mac OS X bundle" >&6; } + build_macosx_bundle=yes + DATADIR='EXE>>../Resources' + SCOREDIR='/Library/Preferences/KoboDeluxe/scores' + CONFIGDIR='HOME>>Library/Preferences' + CONFIGFILE='KoboDeluxe Preferences' + MATHLIB="" + ;; + aix*) + { echo "$as_me:$LINENO: result: AIX; Un*x style" >&5 +echo "${ECHO_T}AIX; Un*x style" >&6; } + if test x$ac_cv_c_compiler_gnu = xyes; then + CFLAGS="-mthreads" + fi + if test x$have_x = xyes; then + CFLAGS="$CFLAGS $X_CFLAGS" + fi + ;; + solaris*) + { echo "$as_me:$LINENO: result: Solaris SPARC; Un*x style" >&5 +echo "${ECHO_T}Solaris SPARC; Un*x style" >&6; } + MATHLIB="-lm" + CFLAGS="$CFLAGS $X_CFLAGS" + ;; + *) + { echo "$as_me:$LINENO: result: Unknown (assuming Un*x-like); Un*x style" >&5 +echo "${ECHO_T}Unknown (assuming Un*x-like); Un*x style" >&6; } + MATHLIB="-lm" + if test x$have_x = xyes; then + CFLAGS="$CFLAGS $X_CFLAGS" + fi + ;; +esac + + +if test x$build_macosx_bundle = xyes; then + BUILD_MACOSX_BUNDLE_TRUE= + BUILD_MACOSX_BUNDLE_FALSE='#' +else + BUILD_MACOSX_BUNDLE_TRUE='#' + BUILD_MACOSX_BUNDLE_FALSE= +fi + + + +if test x$build_simple_bundle = xyes; then + BUILD_SIMPLE_BUNDLE_TRUE= + BUILD_SIMPLE_BUNDLE_FALSE='#' +else + BUILD_SIMPLE_BUNDLE_TRUE='#' + BUILD_SIMPLE_BUNDLE_FALSE= +fi + + + +if test x$unix_scoredir = xyes; then + UNIX_SCOREDIR_TRUE= + UNIX_SCOREDIR_FALSE='#' +else + UNIX_SCOREDIR_TRUE='#' + UNIX_SCOREDIR_FALSE= +fi + + + + + + + + + +# Check whether --enable-debug was given. +if test "${enable_debug+set}" = set; then + enableval=$enable_debug; +else + enable_debug=no +fi + +{ echo "$as_me:$LINENO: checking for debug build" >&5 +echo $ECHO_N "checking for debug build... $ECHO_C" >&6; } +if test x$enable_debug = xyes; then + CFLAGS="$CFLAGS -g -DDEBUG" + CXXFLAGS="$CXXFLAGS -g -DDEBUG" +fi +{ echo "$as_me:$LINENO: result: $enable_debug" >&5 +echo "${ECHO_T}$enable_debug" >&6; } + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_c89=$ac_arg +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6; } ;; + xno) + { echo "$as_me:$LINENO: result: unsupported" >&5 +echo "${ECHO_T}unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; +esac + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CC" am_compiler_list= + +{ echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; } +if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 +echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + + +if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { echo "$as_me:$LINENO: result: $CXX" >&5 +echo "${ECHO_T}$CXX" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 +echo "${ECHO_T}$ac_ct_CXX" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C++ compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +{ echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6; } +if test "${ac_cv_cxx_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6; } +GXX=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 +echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cxx_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cxx_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CXXFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cxx_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CXX" am_compiler_list= + +{ echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; } +if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5 +echo "${ECHO_T}$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + + +if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done +IFS=$as_save_IFS + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_AWK+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { echo "$as_me:$LINENO: result: $AWK" >&5 +echo "${ECHO_T}$AWK" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$AWK" && break +done + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + + + +SDL_VERSION=1.2.0 + +# Check whether --with-sdl-prefix was given. +if test "${with_sdl_prefix+set}" = set; then + withval=$with_sdl_prefix; sdl_prefix="$withval" +else + sdl_prefix="" +fi + + +# Check whether --with-sdl-exec-prefix was given. +if test "${with_sdl_exec_prefix+set}" = set; then + withval=$with_sdl_exec_prefix; sdl_exec_prefix="$withval" +else + sdl_exec_prefix="" +fi + +# Check whether --enable-sdltest was given. +if test "${enable_sdltest+set}" = set; then + enableval=$enable_sdltest; +else + enable_sdltest=yes +fi + + + if test x$sdl_exec_prefix != x ; then + sdl_args="$sdl_args --exec-prefix=$sdl_exec_prefix" + if test x${SDL_CONFIG+set} != xset ; then + SDL_CONFIG=$sdl_exec_prefix/bin/sdl-config + fi + fi + if test x$sdl_prefix != x ; then + sdl_args="$sdl_args --prefix=$sdl_prefix" + if test x${SDL_CONFIG+set} != xset ; then + SDL_CONFIG=$sdl_prefix/bin/sdl-config + fi + fi + + if test "x$prefix" != xNONE; then + PATH="$prefix/bin:$prefix/usr/bin:$PATH" + fi + # Extract the first word of "sdl-config", so it can be a program name with args. +set dummy sdl-config; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_SDL_CONFIG+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $SDL_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_SDL_CONFIG="$SDL_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_SDL_CONFIG="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + test -z "$ac_cv_path_SDL_CONFIG" && ac_cv_path_SDL_CONFIG="no" + ;; +esac +fi +SDL_CONFIG=$ac_cv_path_SDL_CONFIG +if test -n "$SDL_CONFIG"; then + { echo "$as_me:$LINENO: result: $SDL_CONFIG" >&5 +echo "${ECHO_T}$SDL_CONFIG" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + min_sdl_version=$SDL_VERSION + { echo "$as_me:$LINENO: checking for SDL - version >= $min_sdl_version" >&5 +echo $ECHO_N "checking for SDL - version >= $min_sdl_version... $ECHO_C" >&6; } + no_sdl="" + if test "$SDL_CONFIG" = "no" ; then + no_sdl=yes + else + SDL_CFLAGS=`$SDL_CONFIG $sdlconf_args --cflags` + SDL_LIBS=`$SDL_CONFIG $sdlconf_args --libs` + + sdl_major_version=`$SDL_CONFIG $sdl_args --version | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'` + sdl_minor_version=`$SDL_CONFIG $sdl_args --version | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'` + sdl_micro_version=`$SDL_CONFIG $sdl_config_args --version | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'` + if test "x$enable_sdltest" = "xyes" ; then + ac_save_CFLAGS="$CFLAGS" + ac_save_CXXFLAGS="$CXXFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $SDL_CFLAGS" + CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" + rm -f conf.sdltest + if test "$cross_compiling" = yes; then + echo $ac_n "cross compiling; assumed OK... $ac_c" +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include +#include +#include "SDL.h" + +char* +my_strdup (char *str) +{ + char *new_str; + + if (str) + { + new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char)); + strcpy (new_str, str); + } + else + new_str = NULL; + + return new_str; +} + +int main (int argc, char *argv[]) +{ + int major, minor, micro; + char *tmp_version; + + /* This hangs on some systems (?) + system ("touch conf.sdltest"); + */ + { FILE *fp = fopen("conf.sdltest", "a"); if ( fp ) fclose(fp); } + + /* HP/UX 9 (%@#!) writes to sscanf strings */ + tmp_version = my_strdup("$min_sdl_version"); + if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { + printf("%s, bad version string\n", "$min_sdl_version"); + exit(1); + } + + if (($sdl_major_version > major) || + (($sdl_major_version == major) && ($sdl_minor_version > minor)) || + (($sdl_major_version == major) && ($sdl_minor_version == minor) && ($sdl_micro_version >= micro))) + { + return 0; + } + else + { + printf("\n*** 'sdl-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version); + printf("*** of SDL required is %d.%d.%d. If sdl-config is correct, then it is\n", major, minor, micro); + printf("*** best to upgrade to the required version.\n"); + printf("*** If sdl-config was wrong, set the environment variable SDL_CONFIG\n"); + printf("*** to point to the correct copy of sdl-config, and remove the file\n"); + printf("*** config.cache before re-running configure\n"); + return 1; + } +} + + +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +no_sdl=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + + CFLAGS="$ac_save_CFLAGS" + CXXFLAGS="$ac_save_CXXFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + if test "x$no_sdl" = x ; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + : + else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + if test "$SDL_CONFIG" = "no" ; then + echo "*** The sdl-config script installed by SDL could not be found" + echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the SDL_CONFIG environment variable to the" + echo "*** full path to sdl-config." + else + if test -f conf.sdltest ; then + : + else + echo "*** Could not run SDL test program, checking why..." + CFLAGS="$CFLAGS $SDL_CFLAGS" + CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include "SDL.h" + +int main(int argc, char *argv[]) +{ return 0; } +#undef main +#define main K_and_R_C_main + +int +main () +{ + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding SDL or finding the wrong" + echo "*** version of SDL. If it is not finding SDL, you'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + echo "*** The test program failed to compile or link. See the file config.log for the" + echo "*** exact error that occured. This usually means SDL was incorrectly installed" + echo "*** or that you have moved SDL since it was installed. In the latter case, you" + echo "*** may want to edit the sdl-config script: $SDL_CONFIG" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + CFLAGS="$ac_save_CFLAGS" + CXXFLAGS="$ac_save_CXXFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + SDL_CFLAGS="" + SDL_LIBS="" + { { echo "$as_me:$LINENO: error: *** SDL version $SDL_VERSION required!" >&5 +echo "$as_me: error: *** SDL version $SDL_VERSION required!" >&2;} + { (exit 1); exit 1; }; } + + fi + + + rm -f conf.sdltest + +CFLAGS="$CFLAGS $SDL_CFLAGS" +CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" +LIBS="$LIBS $SDL_LIBS" + + + +{ echo "$as_me:$LINENO: checking for IMG_Load in -lSDL_image" >&5 +echo $ECHO_N "checking for IMG_Load in -lSDL_image... $ECHO_C" >&6; } +if test "${ac_cv_lib_SDL_image_IMG_Load+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lSDL_image -lSDL + $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char IMG_Load (); +int +main () +{ +return IMG_Load (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_SDL_image_IMG_Load=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_SDL_image_IMG_Load=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_SDL_image_IMG_Load" >&5 +echo "${ECHO_T}$ac_cv_lib_SDL_image_IMG_Load" >&6; } +if test $ac_cv_lib_SDL_image_IMG_Load = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSDL_IMAGE 1 +_ACEOF + + LIBS="-lSDL_image $LIBS" + +else + { { echo "$as_me:$LINENO: error: You need the SDL_image library to compile this software. + Get it at http://www.libsdl.org/projects/SDL_image/" >&5 +echo "$as_me: error: You need the SDL_image library to compile this software. + Get it at http://www.libsdl.org/projects/SDL_image/" >&2;} + { (exit 1); exit 1; }; } +fi + +LIBS="$LIBS -lSDL_image" + + +{ echo "$as_me:$LINENO: checking for OpenGL support" >&5 +echo $ECHO_N "checking for OpenGL support... $ECHO_C" >&6; } +have_opengl=no +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + #if defined(__APPLE__) && defined(__MACH__) + #include + #else + #include + #endif + +int +main () +{ + + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + +have_opengl=yes + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +# Check whether --enable-opengl was given. +if test "${enable_opengl+set}" = set; then + enableval=$enable_opengl; +else + enable_opengl=yes +fi + +if test x$enable_opengl = xyes; then + { echo "$as_me:$LINENO: result: $have_opengl" >&5 +echo "${ECHO_T}$have_opengl" >&6; } +else + have_opengl=no + { echo "$as_me:$LINENO: result: Disabled" >&5 +echo "${ECHO_T}Disabled" >&6; } +fi + +if test x$have_opengl = xyes; then + CFLAGS="$CFLAGS -DHAVE_OPENGL" + CXXFLAGS="$CXXFLAGS -DHAVE_OPENGL" +fi + + + + + + + +ac_header_dirent=no +for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do + as_ac_Header=`echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_hdr that defines DIR" >&5 +echo $ECHO_N "checking for $ac_hdr that defines DIR... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include <$ac_hdr> + +int +main () +{ +if ((DIR *) 0) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 +_ACEOF + +ac_header_dirent=$ac_hdr; break +fi + +done +# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. +if test $ac_header_dirent = dirent.h; then + { echo "$as_me:$LINENO: checking for library containing opendir" >&5 +echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6; } +if test "${ac_cv_search_opendir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char opendir (); +int +main () +{ +return opendir (); + ; + return 0; +} +_ACEOF +for ac_lib in '' dir; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_search_opendir=$ac_res +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext + if test "${ac_cv_search_opendir+set}" = set; then + break +fi +done +if test "${ac_cv_search_opendir+set}" = set; then + : +else + ac_cv_search_opendir=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 +echo "${ECHO_T}$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +else + { echo "$as_me:$LINENO: checking for library containing opendir" >&5 +echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6; } +if test "${ac_cv_search_opendir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char opendir (); +int +main () +{ +return opendir (); + ; + return 0; +} +_ACEOF +for ac_lib in '' x; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_search_opendir=$ac_res +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext + if test "${ac_cv_search_opendir+set}" = set; then + break +fi +done +if test "${ac_cv_search_opendir+set}" = set; then + : +else + ac_cv_search_opendir=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 +echo "${ECHO_T}$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +fi + +{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 +echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Extract the first word of "grep ggrep" to use in msg output +if test -z "$GREP"; then +set dummy grep ggrep; ac_prog_name=$2 +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_GREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue + # Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_GREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +GREP="$ac_cv_path_GREP" +if test -z "$GREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_GREP=$GREP +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 +echo "${ECHO_T}$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + # Extract the first word of "egrep" to use in msg output +if test -z "$EGREP"; then +set dummy egrep; ac_prog_name=$2 +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_EGREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue + # Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_EGREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +EGREP="$ac_cv_path_EGREP" +if test -z "$EGREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_EGREP=$EGREP +fi + + + fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 +echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_stdc=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 +echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6; } +if test "${ac_cv_header_time+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_time=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_time=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 +echo "${ECHO_T}$ac_cv_header_time" >&6; } +if test $ac_cv_header_time = yes; then + +cat >>confdefs.h <<\_ACEOF +#define TIME_WITH_SYS_TIME 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + + + +for ac_header in errno.h fcntl.h stdlib.h string.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + +for ac_header in sys/ioctl.h sys/time.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in SDL/SDL_opengl.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + +{ echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6; } +if test "${ac_cv_c_const+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset cs; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_const=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_c_const=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +echo "${ECHO_T}$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +cat >>confdefs.h <<\_ACEOF +#define const +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for inline" >&5 +echo $ECHO_N "checking for inline... $ECHO_C" >&6; } +if test "${ac_cv_c_inline+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_inline=$ac_kw +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 +echo "${ECHO_T}$ac_cv_c_inline" >&6; } + + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + +{ echo "$as_me:$LINENO: checking return type of signal handlers" >&5 +echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6; } +if test "${ac_cv_type_signal+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include + +int +main () +{ +return *(signal (0, 0)) (0) == 1; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_signal=int +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_signal=void +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5 +echo "${ECHO_T}$ac_cv_type_signal" >&6; } + +cat >>confdefs.h <<_ACEOF +#define RETSIGTYPE $ac_cv_type_signal +_ACEOF + + + + + + + + +for ac_func in strdup strstr strchr strrchr +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + + + +for ac_func in snprintf _snprintf vsnprintf _vsnprintf +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + +for ac_func in pow sqrt +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + + + +for ac_func in munmap mkdir select stat +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + + + + +for ac_func in atexit floor memmove memset memcmp +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +for ac_func in gettimeofday +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + +for ac_func in getegid setgid +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +{ echo "$as_me:$LINENO: checking for working memcmp" >&5 +echo $ECHO_N "checking for working memcmp... $ECHO_C" >&6; } +if test "${ac_cv_func_memcmp_working+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_memcmp_working=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* Some versions of memcmp are not 8-bit clean. */ + char c0 = '\100', c1 = '\200', c2 = '\201'; + if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0) + return 1; + + /* The Next x86 OpenStep bug shows up only when comparing 16 bytes + or more and with at least one buffer not starting on a 4-byte boundary. + William Lewis provided this test program. */ + { + char foo[21]; + char bar[21]; + int i; + for (i = 0; i < 4; i++) + { + char *a = foo + i; + char *b = bar + i; + strcpy (a, "--------01111111"); + strcpy (b, "--------10000000"); + if (memcmp (a, b, 16) >= 0) + return 1; + } + return 0; + } + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_memcmp_working=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_func_memcmp_working=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_memcmp_working" >&5 +echo "${ECHO_T}$ac_cv_func_memcmp_working" >&6; } +test $ac_cv_func_memcmp_working = no && case " $LIBOBJS " in + *" memcmp.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS memcmp.$ac_objext" + ;; +esac + + +{ echo "$as_me:$LINENO: checking for working strtod" >&5 +echo $ECHO_N "checking for working strtod... $ECHO_C" >&6; } +if test "${ac_cv_func_strtod+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_strtod=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +$ac_includes_default +#ifndef strtod +double strtod (); +#endif +int +main() +{ + { + /* Some versions of Linux strtod mis-parse strings with leading '+'. */ + char *string = " +69"; + char *term; + double value; + value = strtod (string, &term); + if (value != 69 || term != (string + 4)) + return 1; + } + + { + /* Under Solaris 2.4, strtod returns the wrong value for the + terminating character under some conditions. */ + char *string = "NaN"; + char *term; + strtod (string, &term); + if (term != string && *(term - 1) == 0) + return 1; + } + return 0; +} + +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_strtod=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_func_strtod=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_strtod" >&5 +echo "${ECHO_T}$ac_cv_func_strtod" >&6; } +if test $ac_cv_func_strtod = no; then + case " $LIBOBJS " in + *" strtod.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS strtod.$ac_objext" + ;; +esac + +{ echo "$as_me:$LINENO: checking for pow" >&5 +echo $ECHO_N "checking for pow... $ECHO_C" >&6; } +if test "${ac_cv_func_pow+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define pow to an innocuous variant, in case declares pow. + For example, HP-UX 11i declares gettimeofday. */ +#define pow innocuous_pow + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char pow (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef pow + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pow (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_pow || defined __stub___pow +choke me +#endif + +int +main () +{ +return pow (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_func_pow=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_pow=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_pow" >&5 +echo "${ECHO_T}$ac_cv_func_pow" >&6; } + +if test $ac_cv_func_pow = no; then + { echo "$as_me:$LINENO: checking for pow in -lm" >&5 +echo $ECHO_N "checking for pow in -lm... $ECHO_C" >&6; } +if test "${ac_cv_lib_m_pow+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lm $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pow (); +int +main () +{ +return pow (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_m_pow=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_m_pow=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_m_pow" >&5 +echo "${ECHO_T}$ac_cv_lib_m_pow" >&6; } +if test $ac_cv_lib_m_pow = yes; then + POW_LIB=-lm +else + { echo "$as_me:$LINENO: WARNING: cannot find library containing definition of pow" >&5 +echo "$as_me: WARNING: cannot find library containing definition of pow" >&2;} +fi + +fi + +fi + + +for ac_func in vprintf +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +{ echo "$as_me:$LINENO: checking for _doprnt" >&5 +echo $ECHO_N "checking for _doprnt... $ECHO_C" >&6; } +if test "${ac_cv_func__doprnt+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define _doprnt to an innocuous variant, in case declares _doprnt. + For example, HP-UX 11i declares gettimeofday. */ +#define _doprnt innocuous__doprnt + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char _doprnt (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef _doprnt + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char _doprnt (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub__doprnt || defined __stub____doprnt +choke me +#endif + +int +main () +{ +return _doprnt (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_func__doprnt=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func__doprnt=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func__doprnt" >&5 +echo "${ECHO_T}$ac_cv_func__doprnt" >&6; } +if test $ac_cv_func__doprnt = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_DOPRNT 1 +_ACEOF + +fi + +fi +done + + + + +for ac_header in stdlib.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_func in getpagesize +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +{ echo "$as_me:$LINENO: checking for working mmap" >&5 +echo $ECHO_N "checking for working mmap... $ECHO_C" >&6; } +if test "${ac_cv_func_mmap_fixed_mapped+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_mmap_fixed_mapped=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +/* malloc might have been renamed as rpl_malloc. */ +#undef malloc + +/* Thanks to Mike Haertel and Jim Avera for this test. + Here is a matrix of mmap possibilities: + mmap private not fixed + mmap private fixed at somewhere currently unmapped + mmap private fixed at somewhere already mapped + mmap shared not fixed + mmap shared fixed at somewhere currently unmapped + mmap shared fixed at somewhere already mapped + For private mappings, we should verify that changes cannot be read() + back from the file, nor mmap's back from the file at a different + address. (There have been systems where private was not correctly + implemented like the infamous i386 svr4.0, and systems where the + VM page cache was not coherent with the file system buffer cache + like early versions of FreeBSD and possibly contemporary NetBSD.) + For shared mappings, we should conversely verify that changes get + propagated back to all the places they're supposed to be. + + Grep wants private fixed already mapped. + The main things grep needs to know about mmap are: + * does it exist and is it safe to write into the mmap'd area + * how to use it (BSD variants) */ + +#include +#include + +#if !defined STDC_HEADERS && !defined HAVE_STDLIB_H +char *malloc (); +#endif + +/* This mess was copied from the GNU getpagesize.h. */ +#ifndef HAVE_GETPAGESIZE +/* Assume that all systems that can run configure have sys/param.h. */ +# ifndef HAVE_SYS_PARAM_H +# define HAVE_SYS_PARAM_H 1 +# endif + +# ifdef _SC_PAGESIZE +# define getpagesize() sysconf(_SC_PAGESIZE) +# else /* no _SC_PAGESIZE */ +# ifdef HAVE_SYS_PARAM_H +# include +# ifdef EXEC_PAGESIZE +# define getpagesize() EXEC_PAGESIZE +# else /* no EXEC_PAGESIZE */ +# ifdef NBPG +# define getpagesize() NBPG * CLSIZE +# ifndef CLSIZE +# define CLSIZE 1 +# endif /* no CLSIZE */ +# else /* no NBPG */ +# ifdef NBPC +# define getpagesize() NBPC +# else /* no NBPC */ +# ifdef PAGESIZE +# define getpagesize() PAGESIZE +# endif /* PAGESIZE */ +# endif /* no NBPC */ +# endif /* no NBPG */ +# endif /* no EXEC_PAGESIZE */ +# else /* no HAVE_SYS_PARAM_H */ +# define getpagesize() 8192 /* punt totally */ +# endif /* no HAVE_SYS_PARAM_H */ +# endif /* no _SC_PAGESIZE */ + +#endif /* no HAVE_GETPAGESIZE */ + +int +main () +{ + char *data, *data2, *data3; + int i, pagesize; + int fd; + + pagesize = getpagesize (); + + /* First, make a file with some known garbage in it. */ + data = (char *) malloc (pagesize); + if (!data) + return 1; + for (i = 0; i < pagesize; ++i) + *(data + i) = rand (); + umask (0); + fd = creat ("conftest.mmap", 0600); + if (fd < 0) + return 1; + if (write (fd, data, pagesize) != pagesize) + return 1; + close (fd); + + /* Next, try to mmap the file at a fixed address which already has + something else allocated at it. If we can, also make sure that + we see the same garbage. */ + fd = open ("conftest.mmap", O_RDWR); + if (fd < 0) + return 1; + data2 = (char *) malloc (2 * pagesize); + if (!data2) + return 1; + data2 += (pagesize - ((long int) data2 & (pagesize - 1))) & (pagesize - 1); + if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_FIXED, fd, 0L)) + return 1; + for (i = 0; i < pagesize; ++i) + if (*(data + i) != *(data2 + i)) + return 1; + + /* Finally, make sure that changes to the mapped area do not + percolate back to the file as seen by read(). (This is a bug on + some variants of i386 svr4.0.) */ + for (i = 0; i < pagesize; ++i) + *(data2 + i) = *(data2 + i) + 1; + data3 = (char *) malloc (pagesize); + if (!data3) + return 1; + if (read (fd, data3, pagesize) != pagesize) + return 1; + for (i = 0; i < pagesize; ++i) + if (*(data + i) != *(data3 + i)) + return 1; + close (fd); + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_mmap_fixed_mapped=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_func_mmap_fixed_mapped=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_mmap_fixed_mapped" >&5 +echo "${ECHO_T}$ac_cv_func_mmap_fixed_mapped" >&6; } +if test $ac_cv_func_mmap_fixed_mapped = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_MMAP 1 +_ACEOF + +fi +rm -f conftest.mmap + +{ echo "$as_me:$LINENO: checking whether lstat dereferences a symlink specified with a trailing slash" >&5 +echo $ECHO_N "checking whether lstat dereferences a symlink specified with a trailing slash... $ECHO_C" >&6; } +if test "${ac_cv_func_lstat_dereferences_slashed_symlink+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + rm -f conftest.sym conftest.file +echo >conftest.file +if test "$as_ln_s" = "ln -s" && ln -s conftest.file conftest.sym; then + if test "$cross_compiling" = yes; then + ac_cv_func_lstat_dereferences_slashed_symlink=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +struct stat sbuf; + /* Linux will dereference the symlink and fail. + That is better in the sense that it means we will not + have to compile and use the lstat wrapper. */ + return lstat ("conftest.sym/", &sbuf) == 0; + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_lstat_dereferences_slashed_symlink=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_func_lstat_dereferences_slashed_symlink=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +else + # If the `ln -s' command failed, then we probably don't even + # have an lstat function. + ac_cv_func_lstat_dereferences_slashed_symlink=no +fi +rm -f conftest.sym conftest.file + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_lstat_dereferences_slashed_symlink" >&5 +echo "${ECHO_T}$ac_cv_func_lstat_dereferences_slashed_symlink" >&6; } + +test $ac_cv_func_lstat_dereferences_slashed_symlink = yes && + +cat >>confdefs.h <<_ACEOF +#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1 +_ACEOF + + +if test $ac_cv_func_lstat_dereferences_slashed_symlink = no; then + case " $LIBOBJS " in + *" lstat.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS lstat.$ac_objext" + ;; +esac + +fi + +{ echo "$as_me:$LINENO: checking whether stat accepts an empty string" >&5 +echo $ECHO_N "checking whether stat accepts an empty string... $ECHO_C" >&6; } +if test "${ac_cv_func_stat_empty_string_bug+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_stat_empty_string_bug=yes +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +struct stat sbuf; + return stat ("", &sbuf) == 0; + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_stat_empty_string_bug=no +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_func_stat_empty_string_bug=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_stat_empty_string_bug" >&5 +echo "${ECHO_T}$ac_cv_func_stat_empty_string_bug" >&6; } +if test $ac_cv_func_stat_empty_string_bug = yes; then + case " $LIBOBJS " in + *" stat.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS stat.$ac_objext" + ;; +esac + + +cat >>confdefs.h <<_ACEOF +#define HAVE_STAT_EMPTY_STRING_BUG 1 +_ACEOF + +fi + +if test $ac_cv_c_compiler_gnu = yes; then + { echo "$as_me:$LINENO: checking whether $CC needs -traditional" >&5 +echo $ECHO_N "checking whether $CC needs -traditional... $ECHO_C" >&6; } +if test "${ac_cv_prog_gcc_traditional+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_pattern="Autoconf.*'x'" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +Autoconf TIOCGETP +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "$ac_pattern" >/dev/null 2>&1; then + ac_cv_prog_gcc_traditional=yes +else + ac_cv_prog_gcc_traditional=no +fi +rm -f conftest* + + + if test $ac_cv_prog_gcc_traditional = no; then + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +Autoconf TCGETA +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "$ac_pattern" >/dev/null 2>&1; then + ac_cv_prog_gcc_traditional=yes +fi +rm -f conftest* + + fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_gcc_traditional" >&5 +echo "${ECHO_T}$ac_cv_prog_gcc_traditional" >&6; } + if test $ac_cv_prog_gcc_traditional = yes; then + CC="$CC -traditional" + fi +fi + + + +{ echo "$as_me:$LINENO: checking for OSS audio support" >&5 +echo $ECHO_N "checking for OSS audio support... $ECHO_C" >&6; } +if test x$enable_oss = xyes; then + have_oss=no + if test x$have_oss != xyes; then + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + #include + +int +main () +{ + + int arg = SNDCTL_DSP_SETFRAGMENT; + ++arg; + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + + have_oss=yes + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test x$have_oss != xyes; then + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + #include + +int +main () +{ + + int arg = SNDCTL_DSP_SETFRAGMENT; + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + + have_oss=yes + CFLAGS="$CFLAGS -DOSS_USE_SOUNDCARD_H" + CXXFLAGS="$CXXFLAGS -DOSS_USE_SOUNDCARD_H" + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi +fi + +# Check whether --enable-oss was given. +if test "${enable_oss+set}" = set; then + enableval=$enable_oss; +else + enable_oss=no +fi + +if test x$enable_oss = xyes; then + { echo "$as_me:$LINENO: result: $have_oss" >&5 +echo "${ECHO_T}$have_oss" >&6; } +else + have_oss=no + { echo "$as_me:$LINENO: result: Disabled" >&5 +echo "${ECHO_T}Disabled" >&6; } +fi + +if test x$have_oss = xyes; then + CFLAGS="$CFLAGS -DHAVE_OSS" + CXXFLAGS="$CXXFLAGS -DHAVE_OSS" +fi + + +if test "${ac_cv_header_sys_asoundlib_h+set}" = set; then + { echo "$as_me:$LINENO: checking for sys/asoundlib.h" >&5 +echo $ECHO_N "checking for sys/asoundlib.h... $ECHO_C" >&6; } +if test "${ac_cv_header_sys_asoundlib_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_sys_asoundlib_h" >&5 +echo "${ECHO_T}$ac_cv_header_sys_asoundlib_h" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking sys/asoundlib.h usability" >&5 +echo $ECHO_N "checking sys/asoundlib.h usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking sys/asoundlib.h presence" >&5 +echo $ECHO_N "checking sys/asoundlib.h presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: sys/asoundlib.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: sys/asoundlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/asoundlib.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: sys/asoundlib.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: sys/asoundlib.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: sys/asoundlib.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/asoundlib.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: sys/asoundlib.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/asoundlib.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: sys/asoundlib.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/asoundlib.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: sys/asoundlib.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/asoundlib.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: sys/asoundlib.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/asoundlib.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: sys/asoundlib.h: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for sys/asoundlib.h" >&5 +echo $ECHO_N "checking for sys/asoundlib.h... $ECHO_C" >&6; } +if test "${ac_cv_header_sys_asoundlib_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_sys_asoundlib_h=$ac_header_preproc +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_sys_asoundlib_h" >&5 +echo "${ECHO_T}$ac_cv_header_sys_asoundlib_h" >&6; } + +fi +if test $ac_cv_header_sys_asoundlib_h = yes; then + have_alsa_hdr=yes +fi + + +{ echo "$as_me:$LINENO: checking for snd_pcm_open in -lasound" >&5 +echo $ECHO_N "checking for snd_pcm_open in -lasound... $ECHO_C" >&6; } +if test "${ac_cv_lib_asound_snd_pcm_open+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lasound $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char snd_pcm_open (); +int +main () +{ +return snd_pcm_open (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_asound_snd_pcm_open=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_asound_snd_pcm_open=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_asound_snd_pcm_open" >&5 +echo "${ECHO_T}$ac_cv_lib_asound_snd_pcm_open" >&6; } +if test $ac_cv_lib_asound_snd_pcm_open = yes; then + have_alsa_lib=yes +fi + +{ echo "$as_me:$LINENO: checking for ALSA audio support" >&5 +echo $ECHO_N "checking for ALSA audio support... $ECHO_C" >&6; } +have_alsa=no +if test x$have_alsa_hdr = xyes -a x$have_alsa_lib = xyes; then + have_alsa=yes +fi + +# Check whether --enable-alsa was given. +if test "${enable_alsa+set}" = set; then + enableval=$enable_alsa; +else + enable_alsa=no +fi + +if test x$enable_alsa = xyes; then + { echo "$as_me:$LINENO: result: $have_alsa" >&5 +echo "${ECHO_T}$have_alsa" >&6; } +else + have_alsa=no + { echo "$as_me:$LINENO: result: Disabled" >&5 +echo "${ECHO_T}Disabled" >&6; } +fi + +if test x$have_alsa = xyes; then + CFLAGS="$CFLAGS -DHAVE_ALSA" + CXXFLAGS="$CXXFLAGS -DHAVE_ALSA" + AUDIO_LIBS="-lasound" +else + AUDIO_LIBS="" +fi + + + +# Check whether --enable-epm was given. +if test "${enable_epm+set}" = set; then + enableval=$enable_epm; +else + enable_epm=no +fi + +{ echo "$as_me:$LINENO: checking for Extreme Pickyness Mode" >&5 +echo $ECHO_N "checking for Extreme Pickyness Mode... $ECHO_C" >&6; } +if test x$enable_epm = xyes; then + LOCALCFLAGS="$LOCALCFLAGS -Wall -Werror -Wwrite-strings -fno-builtin" +fi +{ echo "$as_me:$LINENO: result: $enable_epm" >&5 +echo "${ECHO_T}$enable_epm" >&6; } + + +# Check whether --enable-efence was given. +if test "${enable_efence+set}" = set; then + enableval=$enable_efence; +else + enable_efence=no +fi + +{ echo "$as_me:$LINENO: checking if we should use ElectricFence" >&5 +echo $ECHO_N "checking if we should use ElectricFence... $ECHO_C" >&6; } +if test x$enable_efence = xyes; then + LIBS="$LIBS -lefence" +fi +{ echo "$as_me:$LINENO: result: $enable_efence" >&5 +echo "${ECHO_T}$enable_efence" >&6; } + + + +ac_config_files="$ac_config_files Makefile Info.plist graphics/Makefile sound/Makefile data/Makefile data/sfx/Makefile data/gfx/Makefile eel/Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { echo "$as_me:$LINENO: updating cache $cache_file" >&5 +echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 +echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${BUILD_MACOSX_BUNDLE_TRUE}" && test -z "${BUILD_MACOSX_BUNDLE_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"BUILD_MACOSX_BUNDLE\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"BUILD_MACOSX_BUNDLE\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${BUILD_SIMPLE_BUNDLE_TRUE}" && test -z "${BUILD_SIMPLE_BUNDLE_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"BUILD_SIMPLE_BUNDLE\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"BUILD_SIMPLE_BUNDLE\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${UNIX_SCOREDIR_TRUE}" && test -z "${UNIX_SCOREDIR_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"UNIX_SCOREDIR\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"UNIX_SCOREDIR\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 + +# Save the log message, to keep $[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.61. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.61, + with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2006 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + { echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + CONFIG_SHELL=$SHELL + export CONFIG_SHELL + exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "aconfig.h") CONFIG_HEADERS="$CONFIG_HEADERS aconfig.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "Info.plist") CONFIG_FILES="$CONFIG_FILES Info.plist" ;; + "graphics/Makefile") CONFIG_FILES="$CONFIG_FILES graphics/Makefile" ;; + "sound/Makefile") CONFIG_FILES="$CONFIG_FILES sound/Makefile" ;; + "data/Makefile") CONFIG_FILES="$CONFIG_FILES data/Makefile" ;; + "data/sfx/Makefile") CONFIG_FILES="$CONFIG_FILES data/sfx/Makefile" ;; + "data/gfx/Makefile") CONFIG_FILES="$CONFIG_FILES data/gfx/Makefile" ;; + "eel/Makefile") CONFIG_FILES="$CONFIG_FILES eel/Makefile" ;; + + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +# +# Set up the sed scripts for CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "$CONFIG_FILES"; then + +_ACEOF + + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +SHELL!$SHELL$ac_delim +PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim +PACKAGE_NAME!$PACKAGE_NAME$ac_delim +PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim +PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim +PACKAGE_STRING!$PACKAGE_STRING$ac_delim +PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim +exec_prefix!$exec_prefix$ac_delim +prefix!$prefix$ac_delim +program_transform_name!$program_transform_name$ac_delim +bindir!$bindir$ac_delim +sbindir!$sbindir$ac_delim +libexecdir!$libexecdir$ac_delim +datarootdir!$datarootdir$ac_delim +datadir!$datadir$ac_delim +sysconfdir!$sysconfdir$ac_delim +sharedstatedir!$sharedstatedir$ac_delim +localstatedir!$localstatedir$ac_delim +includedir!$includedir$ac_delim +oldincludedir!$oldincludedir$ac_delim +docdir!$docdir$ac_delim +infodir!$infodir$ac_delim +htmldir!$htmldir$ac_delim +dvidir!$dvidir$ac_delim +pdfdir!$pdfdir$ac_delim +psdir!$psdir$ac_delim +libdir!$libdir$ac_delim +localedir!$localedir$ac_delim +mandir!$mandir$ac_delim +DEFS!$DEFS$ac_delim +ECHO_C!$ECHO_C$ac_delim +ECHO_N!$ECHO_N$ac_delim +ECHO_T!$ECHO_T$ac_delim +LIBS!$LIBS$ac_delim +build_alias!$build_alias$ac_delim +host_alias!$host_alias$ac_delim +target_alias!$target_alias$ac_delim +build!$build$ac_delim +build_cpu!$build_cpu$ac_delim +build_vendor!$build_vendor$ac_delim +build_os!$build_os$ac_delim +host!$host$ac_delim +host_cpu!$host_cpu$ac_delim +host_vendor!$host_vendor$ac_delim +host_os!$host_os$ac_delim +target!$target$ac_delim +target_cpu!$target_cpu$ac_delim +target_vendor!$target_vendor$ac_delim +target_os!$target_os$ac_delim +INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim +INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim +INSTALL_DATA!$INSTALL_DATA$ac_delim +CYGPATH_W!$CYGPATH_W$ac_delim +PACKAGE!$PACKAGE$ac_delim +VERSION!$VERSION$ac_delim +ACLOCAL!$ACLOCAL$ac_delim +AUTOCONF!$AUTOCONF$ac_delim +AUTOMAKE!$AUTOMAKE$ac_delim +AUTOHEADER!$AUTOHEADER$ac_delim +MAKEINFO!$MAKEINFO$ac_delim +install_sh!$install_sh$ac_delim +STRIP!$STRIP$ac_delim +INSTALL_STRIP_PROGRAM!$INSTALL_STRIP_PROGRAM$ac_delim +mkdir_p!$mkdir_p$ac_delim +AWK!$AWK$ac_delim +SET_MAKE!$SET_MAKE$ac_delim +am__leading_dot!$am__leading_dot$ac_delim +AMTAR!$AMTAR$ac_delim +am__tar!$am__tar$ac_delim +am__untar!$am__untar$ac_delim +XMKMF!$XMKMF$ac_delim +CC!$CC$ac_delim +CFLAGS!$CFLAGS$ac_delim +LDFLAGS!$LDFLAGS$ac_delim +CPPFLAGS!$CPPFLAGS$ac_delim +ac_ct_CC!$ac_ct_CC$ac_delim +EXEEXT!$EXEEXT$ac_delim +OBJEXT!$OBJEXT$ac_delim +DEPDIR!$DEPDIR$ac_delim +am__include!$am__include$ac_delim +am__quote!$am__quote$ac_delim +AMDEP_TRUE!$AMDEP_TRUE$ac_delim +AMDEP_FALSE!$AMDEP_FALSE$ac_delim +AMDEPBACKSLASH!$AMDEPBACKSLASH$ac_delim +CCDEPMODE!$CCDEPMODE$ac_delim +am__fastdepCC_TRUE!$am__fastdepCC_TRUE$ac_delim +am__fastdepCC_FALSE!$am__fastdepCC_FALSE$ac_delim +CPP!$CPP$ac_delim +X_CFLAGS!$X_CFLAGS$ac_delim +X_PRE_LIBS!$X_PRE_LIBS$ac_delim +X_LIBS!$X_LIBS$ac_delim +X_EXTRA_LIBS!$X_EXTRA_LIBS$ac_delim +BUILD_MACOSX_BUNDLE_TRUE!$BUILD_MACOSX_BUNDLE_TRUE$ac_delim +BUILD_MACOSX_BUNDLE_FALSE!$BUILD_MACOSX_BUNDLE_FALSE$ac_delim +BUILD_SIMPLE_BUNDLE_TRUE!$BUILD_SIMPLE_BUNDLE_TRUE$ac_delim +BUILD_SIMPLE_BUNDLE_FALSE!$BUILD_SIMPLE_BUNDLE_FALSE$ac_delim +UNIX_SCOREDIR_TRUE!$UNIX_SCOREDIR_TRUE$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi + +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +_ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF +CEOF$ac_eof +_ACEOF + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +UNIX_SCOREDIR_FALSE!$UNIX_SCOREDIR_FALSE$ac_delim +DATADIR!$DATADIR$ac_delim +SCOREDIR!$SCOREDIR$ac_delim +CONFIGDIR!$CONFIGDIR$ac_delim +CONFIGFILE!$CONFIGFILE$ac_delim +EXEFILE!$EXEFILE$ac_delim +MATHLIB!$MATHLIB$ac_delim +CXX!$CXX$ac_delim +CXXFLAGS!$CXXFLAGS$ac_delim +ac_ct_CXX!$ac_ct_CXX$ac_delim +CXXDEPMODE!$CXXDEPMODE$ac_delim +am__fastdepCXX_TRUE!$am__fastdepCXX_TRUE$ac_delim +am__fastdepCXX_FALSE!$am__fastdepCXX_FALSE$ac_delim +RANLIB!$RANLIB$ac_delim +SDL_CONFIG!$SDL_CONFIG$ac_delim +SDL_CFLAGS!$SDL_CFLAGS$ac_delim +SDL_LIBS!$SDL_LIBS$ac_delim +GREP!$GREP$ac_delim +EGREP!$EGREP$ac_delim +LIBOBJS!$LIBOBJS$ac_delim +POW_LIB!$POW_LIB$ac_delim +AUDIO_LIBS!$AUDIO_LIBS$ac_delim +LOCALCFLAGS!$LOCALCFLAGS$ac_delim +LTLIBOBJS!$LTLIBOBJS$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 24; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi + +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-2.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end +_ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF +:end +s/|#_!!_#|//g +CEOF$ac_eof +_ACEOF + + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF +fi # test -n "$CONFIG_FILES" + + +for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 +echo "$as_me: error: Invalid tag $ac_tag." >&2;} + { (exit 1); exit 1; }; };; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac + ac_file_inputs="$ac_file_inputs $ac_f" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input="Generated from "`IFS=: + echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + fi + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin";; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir="$ac_dir" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= + +case `sed -n '/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' $ac_file_inputs` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s&@configure_input@&$configure_input&;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" >$tmp/out + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out"; rm -f "$tmp/out";; + *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; + esac + ;; + :H) + # + # CONFIG_HEADER + # +_ACEOF + +# Transform confdefs.h into a sed script `conftest.defines', that +# substitutes the proper values into config.h.in to produce config.h. +rm -f conftest.defines conftest.tail +# First, append a space to every undef/define line, to ease matching. +echo 's/$/ /' >conftest.defines +# Then, protect against being on the right side of a sed subst, or in +# an unquoted here document, in config.status. If some macros were +# called several times there might be several #defines for the same +# symbol, which is useless. But do not sort them, since the last +# AC_DEFINE must be honored. +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where +# NAME is the cpp macro being defined, VALUE is the value it is being given. +# PARAMS is the parameter list in the macro definition--in most cases, it's +# just an empty string. +ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' +ac_dB='\\)[ (].*,\\1define\\2' +ac_dC=' ' +ac_dD=' ,' + +uniq confdefs.h | + sed -n ' + t rset + :rset + s/^[ ]*#[ ]*define[ ][ ]*// + t ok + d + :ok + s/[\\&,]/\\&/g + s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p + s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p + ' >>conftest.defines + +# Remove the space that was appended to ease matching. +# Then replace #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +# (The regexp can be short, since the line contains either #define or #undef.) +echo 's/ $// +s,^[ #]*u.*,/* & */,' >>conftest.defines + +# Break up conftest.defines: +ac_max_sed_lines=50 + +# First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" +# Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" +# Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" +# et cetera. +ac_in='$ac_file_inputs' +ac_out='"$tmp/out1"' +ac_nxt='"$tmp/out2"' + +while : +do + # Write a here document: + cat >>$CONFIG_STATUS <<_ACEOF + # First, check the format of the line: + cat >"\$tmp/defines.sed" <<\\CEOF +/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def +/^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def +b +:def +_ACEOF + sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS + ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in + sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail + grep . conftest.tail >/dev/null || break + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines conftest.tail + +echo "ac_result=$ac_in" >>$CONFIG_STATUS +cat >>$CONFIG_STATUS <<\_ACEOF + if test x"$ac_file" != x-; then + echo "/* $configure_input */" >"$tmp/config.h" + cat "$ac_result" >>"$tmp/config.h" + if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f $ac_file + mv "$tmp/config.h" $ac_file + fi + else + echo "/* $configure_input */" + cat "$ac_result" + fi + rm -f "$tmp/out12" +# Compute $ac_file's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $ac_file | $ac_file:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $ac_file" >`$as_dirname -- $ac_file || +$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X$ac_file : 'X\(//\)[^/]' \| \ + X$ac_file : 'X\(//\)$' \| \ + X$ac_file : 'X\(/\)' \| . 2>/dev/null || +echo X$ac_file | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { echo "$as_me:$LINENO: executing $ac_file commands" >&5 +echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir=$dirpart/$fdir + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done + ;; + + esac +done # for ac_tag + + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + diff --git a/configure.in b/configure.in new file mode 100644 index 0000000..8558e9c --- /dev/null +++ b/configure.in @@ -0,0 +1,350 @@ +dnl Process this file with autoconf to produce a configure script. + +dnl---------------------------------------------------------- +dnl configure.in for Kobo Deluxe - David Olofson, 2001-2007 +dnl Some tests stolen from SDL (http://www.libsdl.org) +dnl---------------------------------------------------------- + +AC_INIT(Makefile.am) +AC_CONFIG_SRCDIR([Makefile.am]) +AM_CONFIG_HEADER(aconfig.h) +AC_CANONICAL_HOST +AC_CANONICAL_TARGET +AM_INIT_AUTOMAKE(KoboDeluxe, 0.5.1) + +dnl (For Extreme Pickyness Mode) +LOCALCFLAGS='' + + +dnl------------------------------------------------------- +dnl Look for X +dnl------------------------------------------------------- +dnl *MUST* be out here! Pretty much everything breaks on +dnl some targets if they're inside the case statement... +AC_PATH_X +AC_PATH_XTRA + + +dnl------------------------------------------------------- +dnl Detect target platform and build style +dnl------------------------------------------------------- +AC_MSG_CHECKING(target platform and install style); +build_macosx_bundle=no +build_simple_bundle=no +unix_scoredir=yes +DATADIR='$(datadir)/kobo-deluxe' +SCOREDIR='$(sharedstatedir)/kobo-deluxe/scores' +CONFIGDIR='HOME>>' +CONFIGFILE='.kobodlrc' +EXEFILE=kobodl +case "$target_os" in + linux*) + AC_MSG_RESULT(GNU/Linux; Un*x style) + MATHLIB="-lm" + if test x$have_x = xyes; then + CFLAGS="$CFLAGS $X_CFLAGS" + fi + ;; + beos) + AC_MSG_RESULT(BeOS; Un*x style install) + MATHLIB="" + ;; + mingw32*) + AC_MSG_RESULT(Win32 (mingw32); Simple bundle) + build_simple_bundle=yes + unix_scoredir=no + DATADIR='EXE>>' + SCOREDIR='EXE>>scores' + CONFIGDIR='EXE>>' + CONFIGFILE='kobodl.cfg' + EXEFILE=kobodl.exe + MATHLIB="" + ;; + cygwin*) + AC_MSG_RESULT(Win32 (cygwin); Simple bundle) + build_simple_bundle=yes + unix_scoredir=no + DATADIR='EXE>>' + SCOREDIR='EXE>>scores' + CONFIGDIR='EXE>>' + CONFIGFILE='kobodl.cfg' + EXEFILE=kobodl.exe + MATHLIB="" + ;; + darwin*) + AC_MSG_RESULT(Mac OS X/Darwin; Mac OS X bundle) + build_macosx_bundle=yes + DATADIR='EXE>>../Resources' + SCOREDIR='/Library/Preferences/KoboDeluxe/scores' + CONFIGDIR='HOME>>Library/Preferences' + CONFIGFILE='KoboDeluxe Preferences' + MATHLIB="" + ;; + aix*) + AC_MSG_RESULT(AIX; Un*x style) + if test x$ac_cv_c_compiler_gnu = xyes; then + CFLAGS="-mthreads" + fi + if test x$have_x = xyes; then + CFLAGS="$CFLAGS $X_CFLAGS" + fi + ;; + solaris*) + AC_MSG_RESULT(Solaris SPARC; Un*x style) + MATHLIB="-lm" + CFLAGS="$CFLAGS $X_CFLAGS" + ;; + *) + AC_MSG_RESULT(Unknown (assuming Un*x-like); Un*x style) + MATHLIB="-lm" + if test x$have_x = xyes; then + CFLAGS="$CFLAGS $X_CFLAGS" + fi + ;; +esac +AM_CONDITIONAL(BUILD_MACOSX_BUNDLE, test x$build_macosx_bundle = xyes) +AM_CONDITIONAL(BUILD_SIMPLE_BUNDLE, test x$build_simple_bundle = xyes) +AM_CONDITIONAL(UNIX_SCOREDIR, test x$unix_scoredir = xyes) +AC_SUBST(DATADIR) +AC_SUBST(SCOREDIR) +AC_SUBST(CONFIGDIR) +AC_SUBST(CONFIGFILE) +AC_SUBST(EXEFILE) +AC_SUBST(MATHLIB) + + +dnl------------------------------------------------------- +dnl Checks for debug mode +dnl------------------------------------------------------- +AC_ARG_ENABLE(debug, +[ --enable-debug Build with debug switches and defines [default=no]], + , enable_debug=no) +AC_MSG_CHECKING(for debug build) +if test x$enable_debug = xyes; then + CFLAGS="$CFLAGS -g -DDEBUG" + CXXFLAGS="$CXXFLAGS -g -DDEBUG" +fi +AC_MSG_RESULT($enable_debug) + + +dnl------------------------------------------------------- +dnl Checks for programs. +dnl------------------------------------------------------- +AC_PROG_CC +AC_PROG_CXX +AC_PROG_INSTALL +AC_PROG_AWK +AC_PROG_RANLIB + + +dnl------------------------------------------------------- +dnl Checks for SDL +dnl------------------------------------------------------- +SDL_VERSION=1.2.0 +AM_PATH_SDL($SDL_VERSION,:, + AC_MSG_ERROR([*** SDL version $SDL_VERSION required!]) +) +CFLAGS="$CFLAGS $SDL_CFLAGS" +CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" +LIBS="$LIBS $SDL_LIBS" + + +dnl------------------------------------------------------- +dnl Checks for SDL_image +dnl------------------------------------------------------- +AC_CHECK_LIB(SDL_image, IMG_Load,, + AC_MSG_ERROR([You need the SDL_image library to compile this software. + Get it at http://www.libsdl.org/projects/SDL_image/]), + -lSDL +) +LIBS="$LIBS -lSDL_image" + + +dnl------------------------------------------------------- +dnl Checks for OpenGL +dnl------------------------------------------------------- +AC_MSG_CHECKING(for OpenGL support) +have_opengl=no +AC_TRY_COMPILE([ + #if defined(__APPLE__) && defined(__MACH__) + #include + #else + #include + #endif +],[ +],[ +have_opengl=yes +]) + +AC_ARG_ENABLE(opengl, +[ --enable-opengl use OpenGL rendering layer [default=yes]], + , enable_opengl=yes) +if test x$enable_opengl = xyes; then + AC_MSG_RESULT($have_opengl) +else + have_opengl=no + AC_MSG_RESULT(Disabled) +fi + +if test x$have_opengl = xyes; then + CFLAGS="$CFLAGS -DHAVE_OPENGL" + CXXFLAGS="$CXXFLAGS -DHAVE_OPENGL" +fi + + +dnl------------------------------------------------------- +dnl Checks for header files. +dnl------------------------------------------------------- +AC_HEADER_DIRENT +AC_HEADER_STDC +AC_HEADER_TIME +AC_CHECK_HEADERS(errno.h fcntl.h stdlib.h string.h) +AC_CHECK_HEADERS(sys/ioctl.h sys/time.h unistd.h) +AC_CHECK_HEADERS(SDL/SDL_opengl.h) + + +dnl------------------------------------------------------- +dnl Checks for typedefs, structures, and compiler characteristics. +dnl------------------------------------------------------- +AC_C_CONST +AC_C_INLINE +AC_TYPE_SIGNAL + + +dnl------------------------------------------------------- +dnl Checks for library functions. +dnl------------------------------------------------------- +AC_CHECK_FUNCS(strdup strstr strchr strrchr) +AC_CHECK_FUNCS(snprintf _snprintf vsnprintf _vsnprintf) +AC_CHECK_FUNCS(pow sqrt) +AC_CHECK_FUNCS(munmap mkdir select stat) +AC_CHECK_FUNCS(atexit floor memmove memset memcmp) +AC_CHECK_FUNCS(gettimeofday) +AC_CHECK_FUNCS(getegid setgid) +AC_FUNC_MEMCMP +AC_FUNC_STRTOD +AC_FUNC_VPRINTF +AC_FUNC_MMAP +dnl AC_FUNC_MALLOC +AC_FUNC_STAT +AC_PROG_GCC_TRADITIONAL + + +dnl------------------------------------------------------- +dnl See if the OSS audio interface is supported (from SDL) +dnl------------------------------------------------------- +AC_MSG_CHECKING(for OSS audio support) +if test x$enable_oss = xyes; then + have_oss=no + if test x$have_oss != xyes; then + AC_TRY_COMPILE([ + #include + ],[ + int arg = SNDCTL_DSP_SETFRAGMENT; + ++arg; + ],[ + have_oss=yes + ]) + fi + if test x$have_oss != xyes; then + AC_TRY_COMPILE([ + #include + ],[ + int arg = SNDCTL_DSP_SETFRAGMENT; + ],[ + have_oss=yes + CFLAGS="$CFLAGS -DOSS_USE_SOUNDCARD_H" + CXXFLAGS="$CXXFLAGS -DOSS_USE_SOUNDCARD_H" + ]) + fi +fi + +AC_ARG_ENABLE(oss, +[ --enable-oss support the OSS audio API [default=no]], + , enable_oss=no) +if test x$enable_oss = xyes; then + AC_MSG_RESULT($have_oss) +else + have_oss=no + AC_MSG_RESULT(Disabled) +fi + +if test x$have_oss = xyes; then + CFLAGS="$CFLAGS -DHAVE_OSS" + CXXFLAGS="$CXXFLAGS -DHAVE_OSS" +fi + + +dnl------------------------------------------------------- +dnl See if the ALSA audio interface is supported (from SDL) +dnl------------------------------------------------------- +AC_CHECK_HEADER(sys/asoundlib.h, have_alsa_hdr=yes) +AC_CHECK_LIB(asound, snd_pcm_open, have_alsa_lib=yes) +AC_MSG_CHECKING(for ALSA audio support) +have_alsa=no +if test x$have_alsa_hdr = xyes -a x$have_alsa_lib = xyes; then + have_alsa=yes +fi + +AC_ARG_ENABLE(alsa, +[ --enable-alsa support the ALSA audio API [default=no]], + , enable_alsa=no) +if test x$enable_alsa = xyes; then + AC_MSG_RESULT($have_alsa) +else + have_alsa=no + AC_MSG_RESULT(Disabled) +fi + +if test x$have_alsa = xyes; then + CFLAGS="$CFLAGS -DHAVE_ALSA" + CXXFLAGS="$CXXFLAGS -DHAVE_ALSA" + AUDIO_LIBS="-lasound" +else + AUDIO_LIBS="" +fi +AC_SUBST(AUDIO_LIBS) + + +dnl------------------------------------------------------- +dnl Checks for Extreme Pickyness Mode +dnl We have to put this here, as throwing -Werror +dnl into C(XX)FLAGS will cause lots of autoconf +dnl tests to fail on some systems. +dnl------------------------------------------------------- +AC_ARG_ENABLE(epm, +[ --enable-epm Compile with extremely picky settings [default=no]], + , enable_epm=no) +AC_MSG_CHECKING(for Extreme Pickyness Mode) +if test x$enable_epm = xyes; then + LOCALCFLAGS="$LOCALCFLAGS -Wall -Werror -Wwrite-strings -fno-builtin" +fi +AC_MSG_RESULT($enable_epm) +AC_SUBST(LOCALCFLAGS) + +dnl------------------------------------------------------- +dnl Check if we should use ElectricFence +dnl------------------------------------------------------- +AC_ARG_ENABLE(efence, +[ --enable-efence Link with ElectricFence [default=no]], + , enable_efence=no) +AC_MSG_CHECKING(if we should use ElectricFence) +if test x$enable_efence = xyes; then + LIBS="$LIBS -lefence" +fi +AC_MSG_RESULT($enable_efence) +AC_SUBST(LOCALCFLAGS) + + +dnl------------------------------------------------------- +dnl Generate output files +dnl------------------------------------------------------- +AC_OUTPUT([Makefile +Info.plist +graphics/Makefile +sound/Makefile +data/Makefile +data/sfx/Makefile +data/gfx/Makefile +eel/Makefile +]) diff --git a/dashboard.cpp b/dashboard.cpp new file mode 100644 index 0000000..385b61f --- /dev/null +++ b/dashboard.cpp @@ -0,0 +1,452 @@ +/*(GPL) +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 2003, 2007 David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "config.h" +#include "kobo.h" +#include "random.h" +#include +#include + +#define MAX_PROGRESS 1000 + + +/*---------------------------------------------------------- + Screen +----------------------------------------------------------*/ + +void screen_window_t::border(int top, int left, int right, int bottom) +{ + _top = top; + _left = left; + _right = right; + _bottom = bottom; +} + + +void screen_window_t::refresh(SDL_Rect *r) +{ + int x, y, w, h; + foreground(map_rgb(0x000000)); + x = 0; + y = 0; + w = width(); + h = _top; + fillrect(x, y, w, h); + + y = height() - _bottom; + h = _bottom; + fillrect(x, y, w, h); + + y = _top; + w = _left; + h = height() - _top - _bottom; + fillrect(x, y, w, h); + + x = width() - _right; + w = _right; + fillrect(x, y, w, h); +} + + +/*---------------------------------------------------------- + Dashboard +----------------------------------------------------------*/ + +dashboard_window_t::dashboard_window_t() +{ + _mode = DASHBOARD_BLACK; + _percent = 0.0f; + _msg = NULL; +} + + +dashboard_window_t::~dashboard_window_t() +{ + free(_msg); +} + + +void dashboard_window_t::mode(dashboard_modes_t m) +{ + int vis; + _mode = m; + switch(_mode) + { + case DASHBOARD_GAME: + vis = 1; + break; + default: + vis = 0; + break; + } + wmain->visible(vis); + whealth->visible(vis); + wtemp->visible(vis); + wttemp->visible(vis); + wradar->visible(vis); + dhigh->visible(vis); + dscore->visible(vis); + dstage->visible(vis); + dships->visible(vis); + switch(_mode) + { + case DASHBOARD_OFF: + break; + default: + gengine->invalidate(); + gengine->flip(); + gengine->invalidate(); + gengine->flip(); + gengine->invalidate(); + break; + } +} + + +void dashboard_window_t::doing(const char *msg) +{ + free(_msg); + _msg = strdup(msg); + invalidate(); + gengine->flip(); +} + + +void dashboard_window_t::progress_init(float *progtab) +{ + if(!progtab) + { + progress_table = (float *)malloc(MAX_PROGRESS * sizeof(float)); + progress_bench = (progress_table != NULL); + } + else + { + progress_table = progtab; + progress_bench = 0; + } + progress_index = 0; +} + + +void dashboard_window_t::progress() +{ + if(progress_table) + { + if(progress_bench) + { + progress_table[progress_index++] = (float)SDL_GetTicks(); + _percent = 0.0f; + } + else + _percent = progress_table[progress_index++]; + } + else + _percent = 50.0f; + invalidate(); + gengine->flip(); +} + + +void dashboard_window_t::progress_done() +{ + if(progress_bench) + { + int i; + int total = SDL_GetTicks() - (int)progress_table[0]; + printf("Progress percentages:\n"); + printf("---------------------\n"); + for(i = 0; i < progress_index; ++i) + printf("\t%f,\n", (progress_table[i] - + progress_table[0]) * 100.0f / total); + printf("---------------------\n"); + free(progress_table); + progress_bench = 0; + } + progress_table = NULL; +} + + +void dashboard_window_t::render_progress() +{ + SDL_Rect r; + int x, y, w, h; + + x = 0; + w = (int)(_percent * 0.01f * width() + 0.5f); + if(w < 4) + w = 4; + else if(w > width()) + w = width(); + + h = 16; + y = height() - h; + + r.x = x; + r.y = y; + r.w = w; + r.h = h; + + foreground(map_rgb(0x000099)); + rectangle(x, y, w, h); + + ++x; + ++y; + w -= 2; + h -= 2; + foreground(map_rgb(0x0000cc)); + rectangle(x, y, w, h); + + ++x; + ++y; + w -= 2; + h -= 2; + foreground(map_rgb(0x0000ff)); + fillrect(x, y, w, h); + + r.x = 0; + r.y = height() - 40; + r.w = width(); + r.h = 12; + foreground(map_rgb(0x000000)); + fillrect(r.x, r.y, r.w, r.h); + if(_msg) + { + font(B_NORMAL_FONT); + center(height() - 40, _msg); + } +} + + +#define NIBBLE_W 4 +#define NIBBLE_H 4 +#define NIBBLE_TILES ((SCREEN_WIDTH/NIBBLE_W+1)*(SCREEN_HEIGHT/NIBBLE_H+1)) + +void dashboard_window_t::nibble(int tool) +{ + int i; + int x[NIBBLE_TILES]; + int y[NIBBLE_TILES]; + + mode(DASHBOARD_OFF); + + if(tool < 0) + tool = (pubrand.get(20) + SDL_GetTicks()) % 5; + + /* Clear */ + for(i = 0; i < NIBBLE_TILES; ++i) + x[i] = y[i] = -1; + + /* Fill in */ + int ind = 0; + int xx = -NIBBLE_W / 2; + int yy = -NIBBLE_H / 2; + for(i = 0; i < NIBBLE_TILES; ++i) + { + ind = pubrand.get() % NIBBLE_TILES; + if(ind >= NIBBLE_TILES) + ind = 0; + while(x[ind] != -1) + if(++ind >= NIBBLE_TILES) + ind = 0; + x[ind] = xx; + y[ind] = yy; + xx += NIBBLE_W; + if(xx >= SCREEN_WIDTH + NIBBLE_W / 2) + { + xx = -NIBBLE_W / 2; + yy += NIBBLE_H; + } + } + + /* Clear 8000 tiles/second, until all are done. */ + foreground(map_rgb(0x000000)); + ind = 0; + int last_index; + int t = SDL_GetTicks(); + while(ind < NIBBLE_TILES) + { + int nt = SDL_GetTicks(); + int dt = nt - t; + t = nt; + last_index = ind; /* For double buffer mode */ + for(i = 0; i < dt * 8; ++i) + { + if(ind >= NIBBLE_TILES) + break; + switch (tool) + { + case 0: + fillrect(x[ind] + NIBBLE_W / 2, + y[ind] + NIBBLE_H / 2, + NIBBLE_W, NIBBLE_H); + break; + default: + sprite(x[ind] - 8 + NIBBLE_W / 2, + y[ind] - 8 + + NIBBLE_H / 2, B_BRUSHES, + tool - 1); + break; + } + ++ind; + } + gengine->invalidate(); + gengine->flip(); + if(gengine->doublebuffer()) + { + for(i = 0; i < dt * 4; ++i) + { + if(last_index >= NIBBLE_TILES) + break; + switch (tool) + { + case 0: + fillrect(x[last_index] + + NIBBLE_W / 2, + y[last_index] + + NIBBLE_H / 2, + NIBBLE_W, + NIBBLE_H); + break; + default: + sprite(x[last_index] - 8 + + NIBBLE_W / 2, + y[last_index] - 8 + + NIBBLE_H / 2, + B_BRUSHES, + tool - 1); + break; + } + ++last_index; + } + } + } + mode(DASHBOARD_BLACK); + gengine->flip(); +} + + +void dashboard_window_t::refresh(SDL_Rect *r) +{ + switch(_mode) + { + case DASHBOARD_OFF: + break; + case DASHBOARD_BLACK: + background(map_rgb(0x000000)); + clear(); + break; + case DASHBOARD_GAME: + sprite(0, 0, B_SCREEN, 0); + break; + case DASHBOARD_LOADING: + background(map_rgb(0x000000)); + clear(); + sprite((width() - 250) / 2, 55, B_LOADING, 0); + render_progress(); + break; + } +} + + +/*---------------------------------------------------------- + Bar graph display +----------------------------------------------------------*/ + +bargraph_t::bargraph_t() +{ + _value = 0.0f; + _redmax = 1; + _y = -1000; + _enabled = 1; +} + + +void bargraph_t::value(float val) +{ + if(val < 0.0f) + _value = 0.0f; + else + _value = val; + if(!_enabled) + return; + int y = (int)((height() - 2) * _value); + if(y != _y) + invalidate(); +} + + +void bargraph_t::enable(int ena) +{ + _enabled = ena; + invalidate(); +} + + +void bargraph_t::refresh(SDL_Rect *r) +{ + if(!_enabled) + { + clear(); + return; + } + float v = _value; + int red, green, blue; + if(v > 1.0f) + { + blue = 50 + (v - 1.0f) * 512; + if(_redmax) + { + red = 255; + green = blue / 2; + } + else + { + green = 255; + red = blue / 2; + } + v = 1.0f; + } + else + { + if(_redmax) + { + red = (int)(v * 300.0); + green = (int)((1.0 - v) * 400.0); + } + else + { + red = (int)((1.0 - v) * 300.0); + green = (int)(v * 400.0); + } + blue = 50; + } + if(green > 180) + green = 180; + if(red > 230) + red = 230; + if(blue > 255) + blue = 255; + _y = (int)((height() - 2) * (1.0f - v)); + foreground(bgcolor); + fillrect(0, 0, width(), height()); + foreground(map_rgb(red, green, blue)); + fillrect(1, _y + 1, width() - 2, height() - _y - 2); +} diff --git a/dashboard.h b/dashboard.h new file mode 100644 index 0000000..01003d5 --- /dev/null +++ b/dashboard.h @@ -0,0 +1,98 @@ +/*(GPL) +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 2003, 2007 David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef KOBO_DASHBOARD_H +#define KOBO_DASHBOARD_H + +#include "window.h" + + +/* "Screen" window; takes care of the border, if any. */ +class screen_window_t : public window_t +{ + int _top, _left, _right, _bottom; + public: + void border(int top, int left, int right, int bottom); + void refresh(SDL_Rect *r); +}; + + +enum dashboard_modes_t { + DASHBOARD_OFF = 0, + DASHBOARD_BLACK, + DASHBOARD_GAME, + DASHBOARD_LOADING +}; + +/* Dashboard window; dashboard or loading screen. */ +class dashboard_window_t : public window_t +{ + char *_msg; + float _percent; + dashboard_modes_t _mode; + int progress_index; + float *progress_table; + Uint32 progress_time; + int progress_bench; + void render_progress(); + public: + dashboard_window_t(); + ~dashboard_window_t(); + void mode(dashboard_modes_t m); + void doing(const char *msg); + void progress_init(float *progtab); + void progress(); + void progress_done(); + /* + * Tools: + * -1: Random tool + * 0: Black 4x4 square + * 1+: Brushes from "brushes.png"; + * 1: Soft black 16 pixel round brush + * 2: (4/8)x4 tilable romboid brush + * 3: Tilable garbage brush + * 4: Vertical "D" brush + */ + void nibble(int tool = -1); + void refresh(SDL_Rect *r); +}; + + +/* Bar graph display */ +class bargraph_t : public window_t +{ + float _value; + int _redmax; + int _y; + int _enabled; + public: + bargraph_t(); + void value(float val); + void refresh(SDL_Rect *r); + void redmax(int rm) + { + _redmax = rm; + } + void enable(int ena); +}; + + +#endif /* KOBO_DASHBOARD_H */ diff --git a/data/Makefile.am b/data/Makefile.am new file mode 100644 index 0000000..6727a7d --- /dev/null +++ b/data/Makefile.am @@ -0,0 +1,9 @@ +if UNIX_SCOREDIR +koboscoredir = @SCOREDIR@ +koboscore_DATA = +else +koboscoredir = $(srcdir)/../@PACKAGE@/scores +koboscore_DATA = +endif + +SUBDIRS = sfx gfx diff --git a/data/Makefile.in b/data/Makefile.in new file mode 100644 index 0000000..aaf9b49 --- /dev/null +++ b/data/Makefile.in @@ -0,0 +1,515 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = data +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/aconfig.h +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-exec-recursive install-info-recursive \ + install-recursive installcheck-recursive installdirs-recursive \ + pdf-recursive ps-recursive uninstall-info-recursive \ + uninstall-recursive +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(koboscoredir)" +koboscoreDATA_INSTALL = $(INSTALL_DATA) +DATA = $(koboscore_DATA) +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AUDIO_LIBS = @AUDIO_LIBS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_MACOSX_BUNDLE_FALSE = @BUILD_MACOSX_BUNDLE_FALSE@ +BUILD_MACOSX_BUNDLE_TRUE = @BUILD_MACOSX_BUNDLE_TRUE@ +BUILD_SIMPLE_BUNDLE_FALSE = @BUILD_SIMPLE_BUNDLE_FALSE@ +BUILD_SIMPLE_BUNDLE_TRUE = @BUILD_SIMPLE_BUNDLE_TRUE@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CONFIGDIR = @CONFIGDIR@ +CONFIGFILE = @CONFIGFILE@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXEFILE = @EXEFILE@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LOCALCFLAGS = @LOCALCFLAGS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MATHLIB = @MATHLIB@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +POW_LIB = @POW_LIB@ +RANLIB = @RANLIB@ +SCOREDIR = @SCOREDIR@ +SDL_CFLAGS = @SDL_CFLAGS@ +SDL_CONFIG = @SDL_CONFIG@ +SDL_LIBS = @SDL_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +UNIX_SCOREDIR_FALSE = @UNIX_SCOREDIR_FALSE@ +UNIX_SCOREDIR_TRUE = @UNIX_SCOREDIR_TRUE@ +VERSION = @VERSION@ +XMKMF = @XMKMF@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +@UNIX_SCOREDIR_FALSE@koboscoredir = $(srcdir)/../@PACKAGE@/scores +@UNIX_SCOREDIR_TRUE@koboscoredir = @SCOREDIR@ +@UNIX_SCOREDIR_FALSE@koboscore_DATA = +@UNIX_SCOREDIR_TRUE@koboscore_DATA = +SUBDIRS = sfx gfx +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign data/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign data/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +uninstall-info-am: +install-koboscoreDATA: $(koboscore_DATA) + @$(NORMAL_INSTALL) + test -z "$(koboscoredir)" || $(mkdir_p) "$(DESTDIR)$(koboscoredir)" + @list='$(koboscore_DATA)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(koboscoreDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(koboscoredir)/$$f'"; \ + $(koboscoreDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(koboscoredir)/$$f"; \ + done + +uninstall-koboscoreDATA: + @$(NORMAL_UNINSTALL) + @list='$(koboscore_DATA)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(koboscoredir)/$$f'"; \ + rm -f "$(DESTDIR)$(koboscoredir)/$$f"; \ + done + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(mkdir_p) "$(distdir)/$$subdir" \ + || exit 1; \ + distdir=`$(am__cd) $(distdir) && pwd`; \ + top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ + (cd $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$top_distdir" \ + distdir="$$distdir/$$subdir" \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(DATA) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(koboscoredir)"; do \ + test -z "$$dir" || $(mkdir_p) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +info: info-recursive + +info-am: + +install-data-am: install-koboscoreDATA + +install-exec-am: + +install-info: install-info-recursive + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-info-am uninstall-koboscoreDATA + +uninstall-info: uninstall-info-recursive + +.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am \ + clean clean-generic clean-recursive ctags ctags-recursive \ + distclean distclean-generic distclean-recursive distclean-tags \ + distdir dvi dvi-am html html-am info info-am install \ + install-am install-data install-data-am install-exec \ + install-exec-am install-info install-info-am \ + install-koboscoreDATA install-man install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic maintainer-clean-recursive \ + mostlyclean mostlyclean-generic mostlyclean-recursive pdf \ + pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \ + uninstall-info-am uninstall-koboscoreDATA + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/data/gfx/Makefile.am b/data/gfx/Makefile.am new file mode 100644 index 0000000..a7ec9b0 --- /dev/null +++ b/data/gfx/Makefile.am @@ -0,0 +1,17 @@ +KOBOGFX_OBJECTS = *.png + +if BUILD_MACOSX_BUNDLE +kobogfxdir = $(srcdir)/../@PACKAGE@.app/Contents/Resources/gfx +else + +if BUILD_SIMPLE_BUNDLE +kobogfxdir = $(srcdir)/../@PACKAGE@/gfx +else +kobogfxdir = $(datadir)/kobo-deluxe/gfx +endif + +endif + +kobogfx_DATA = $(KOBOGFX_OBJECTS) + +EXTRA_DIST = $(KOBOGFX_OBJECTS) diff --git a/data/gfx/Makefile.in b/data/gfx/Makefile.in new file mode 100644 index 0000000..a8b3fe8 --- /dev/null +++ b/data/gfx/Makefile.in @@ -0,0 +1,360 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = data/gfx +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/aconfig.h +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(kobogfxdir)" +kobogfxDATA_INSTALL = $(INSTALL_DATA) +DATA = $(kobogfx_DATA) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AUDIO_LIBS = @AUDIO_LIBS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_MACOSX_BUNDLE_FALSE = @BUILD_MACOSX_BUNDLE_FALSE@ +BUILD_MACOSX_BUNDLE_TRUE = @BUILD_MACOSX_BUNDLE_TRUE@ +BUILD_SIMPLE_BUNDLE_FALSE = @BUILD_SIMPLE_BUNDLE_FALSE@ +BUILD_SIMPLE_BUNDLE_TRUE = @BUILD_SIMPLE_BUNDLE_TRUE@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CONFIGDIR = @CONFIGDIR@ +CONFIGFILE = @CONFIGFILE@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXEFILE = @EXEFILE@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LOCALCFLAGS = @LOCALCFLAGS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MATHLIB = @MATHLIB@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +POW_LIB = @POW_LIB@ +RANLIB = @RANLIB@ +SCOREDIR = @SCOREDIR@ +SDL_CFLAGS = @SDL_CFLAGS@ +SDL_CONFIG = @SDL_CONFIG@ +SDL_LIBS = @SDL_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +UNIX_SCOREDIR_FALSE = @UNIX_SCOREDIR_FALSE@ +UNIX_SCOREDIR_TRUE = @UNIX_SCOREDIR_TRUE@ +VERSION = @VERSION@ +XMKMF = @XMKMF@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +KOBOGFX_OBJECTS = *.png +@BUILD_MACOSX_BUNDLE_FALSE@@BUILD_SIMPLE_BUNDLE_FALSE@kobogfxdir = $(datadir)/kobo-deluxe/gfx +@BUILD_MACOSX_BUNDLE_FALSE@@BUILD_SIMPLE_BUNDLE_TRUE@kobogfxdir = $(srcdir)/../@PACKAGE@/gfx +@BUILD_MACOSX_BUNDLE_TRUE@kobogfxdir = $(srcdir)/../@PACKAGE@.app/Contents/Resources/gfx +kobogfx_DATA = $(KOBOGFX_OBJECTS) +EXTRA_DIST = $(KOBOGFX_OBJECTS) +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign data/gfx/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign data/gfx/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +uninstall-info-am: +install-kobogfxDATA: $(kobogfx_DATA) + @$(NORMAL_INSTALL) + test -z "$(kobogfxdir)" || $(mkdir_p) "$(DESTDIR)$(kobogfxdir)" + @list='$(kobogfx_DATA)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(kobogfxDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(kobogfxdir)/$$f'"; \ + $(kobogfxDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(kobogfxdir)/$$f"; \ + done + +uninstall-kobogfxDATA: + @$(NORMAL_UNINSTALL) + @list='$(kobogfx_DATA)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(kobogfxdir)/$$f'"; \ + rm -f "$(DESTDIR)$(kobogfxdir)/$$f"; \ + done +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(DATA) +installdirs: + for dir in "$(DESTDIR)$(kobogfxdir)"; do \ + test -z "$$dir" || $(mkdir_p) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-kobogfxDATA + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am uninstall-kobogfxDATA + +.PHONY: all all-am check check-am clean clean-generic distclean \ + distclean-generic distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-exec \ + install-exec-am install-info install-info-am \ + install-kobogfxDATA install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ + pdf-am ps ps-am uninstall uninstall-am uninstall-info-am \ + uninstall-kobogfxDATA + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/data/gfx/bigfont3.png b/data/gfx/bigfont3.png new file mode 100644 index 0000000000000000000000000000000000000000..08e82741415ad05141bd271cfc35f52f13aba2c3 GIT binary patch literal 98569 zcmaf)Q*>p)v+yU$L=)SZ*f_B#b|$uMTNB&1t%+^hww;rl*mwTxuDibba@Y4#yI=NR z)m>HH)m6V8{##BQ;Ro)IZ{NNlNJ@w(e)|R+|8GnU1NBeJ!9R5Wdw@A9iVJZEdZ-~ycAVOuSkwgML|%z7VRvVyVMsTPdShu)*#&dYuBYj%2elm{H!^7<6J_g(&Nm%tX{#cx z9-nFclS?00t~VIy5rY`yFtpFyKqu9!nM1GAx2e=hU@dyIlfPPfu9?u6_T!7l4)@06 zNq`&UNe(AQS867a*x1gyOkPdCbN%&3D(0;?XD4+%RwRUjr)_axmB;ZlHuS0Ddlb`4vqug*W?l?}Q-AkQL}jX~eR&Pu`<|8i zkn)+$`+m%O9I3$BK3~t~-RFFC?Z~BYY6`)UC;k5aiyM%UG$472|0O3+txZBAqB1Wj z{$`TY%!Zg>DR-;x$%t03ru%(O^qPNSmRu#}x3NE|a(&IKcZuUxB7~0#(b?r^>HW+2 zh$5;6?AOj-Q)E$3mfBd$n^3co>elnA@%C5BmDgLz$-Ju*;F_lAkzfqyCvGQ|=+oWu zb$Ldh=c5x|`F|>U0tM8njggL-i<|U6_(S$x=ntu}VvSV7xg)5}WzcYW|JuKn(7pWC zVMFTbM1|i-i|$IF2V6Ag3Ob-l)nB(G=;qK7^x~20WAL@(o6qV*IjmKyx7gvRYdojl zU*HCs_ZQD~&#N9xMwOz<5BhI04cW{Z2|9|NSEsRiVW9{@kbp&k?1&hn#ws~-*)Nwn zJ362FYG>FjGE;0N4>K{KL!9Fs#Al3_wF@s+@*mFe_X3@eGA7SEa`SW=w0Y)=J22Ga z;|wUtDQ1gn*i_!`2)x{`qqCSX;dv#~> z`_IOY^X^B|CwsTsnD!#N!AzbuwTU-1s&ATxNS3H*Hm z4bNB?j!Q9Y3@;2t`BeXC*11cbD>tVKd!g2QO2)g56dyI!=MPP*iPilD{1clU+nFRa zad!E8&!Jh>eF}rW>F-aXTwP`#{gsIB>>h2U{mGYbo5;aj4%H0|>EnSR8|3?bV^->` z&CfRuoZ$4+^J2Z%#X6gstD8=P4^(o8EAF=gIIQ(`NI3mp$)G{b_;@5&yK8@|*wXlaFA zE1Ce;wRf>NNcb2*GT1%$96Z$|ABF>+Kjd~lQ60X_{dUy6i+9UKYucmCTM-I($ulE27XUX8&u!W= zYAsR(wzArkunGcN>VT+Qdprhs9O2Q*daA z@#(C9cuKvMInU5VfPJkGh4;q#_4)6QqZW%hMpD+bUo>a$hJHJ#Zpk7aFOgOoN12-$ zjl(Hj#=LjP+X!TZce5@iYYTU0b~%098i$HQO%-&QoV%Pcqna^cc%#A^NzeaB(U*UH9RG zq%ZH0ZhrtSumqD!{TS2F>4zbwkR!bIToStX{+N%^Om6Zf&onkcK7NYR+zq5L;NJPs z_gdVH!)}~Cb+TRQtE4v`9hAdOwIN|%;X4EO2K?+fF}`Y?XlYfhJIB^FEc;czZHkefYD?2#Pzx=Tes6M>A2VT8QBFX8sNG~ynYL|~L zN+*5 zbg}e&b5JT?rsm-}OUv^t^%Frqdk}YgGhZz48XDKL;=@S+MkKkYifVbib9{sX<(kL9 zd~|%L#m9B}b$M#_kIQ3INky`CHc@Q`=>k=lPRf)Hgg4#QuOp(|ORriTIzNdNk%zNU zZfI*bt^^nDnWLiK=_?(hM=rv`0&4AiYQtzUk-wY_$yqI68$HQ4%0mFJ4xsO@@($Nk z9jt$J)(qGBcGZFJ^I6U;PAah5AsnOuR;m^(1Y

)A)-o6GryMuc7v-a;BTLk<6J~ zVtFURLT^lFw7t}9H|JTSS~?w0C!$pXwcwaa>!ZvmJg7z`Z>lG%{8sdZpab|hk8`IC zBeNzx-GVH=F2Soi*He1oB!0G8xtitYAlhYe|$L>s|vqM~|jIQfGr6f#>g_J$@V8_=-T=GvSdM2Ft>C6zwLVu$yJ}6J%%_z?VRTs^-$K7GsLXbj zuEsrU#~((ft+sWblQYAEwIs>WzGnX^cd9Wy>L_cFOcRMH8OB0#L-IX^)Wli*dU|zz zK>lH9=C!J|TvT;@bANgv#V96;eiwI2%0D!BQ-I$G(T7+1pOqc8x1b>h;?11Jw-ZOY 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

  • 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 I32@N=0U!`@WB>pF literal 0 HcmV?d00001 diff --git a/data/gfx/bigship.png b/data/gfx/bigship.png new file mode 100644 index 0000000000000000000000000000000000000000..ada494a576cdaafdb27926af9a28b7e73ae43710 GIT binary patch literal 140878 zcmXt91yEbx)5YBh?v&zI+@0c{Kq>Bp0>xd5I}~^KV8z{v6?bs z;fS+lY3K-RMegZpiC{IjhzqNMV!9+{j!t7Ob*~Ej-}+JY@ydzr#j_lUAC-M8JhG5K z_sONSy{#hW!uh=QAnRGUd0TDw|KAThbK*1}yRprkXLeO*XJ?`*7Rlq|<0`Kae`_cY za{b@fGD;vtN##Cbxv%)~Mq;XBkblkA8T*;g*Nbl#_Eo!IFZZO#O;c=aY|hbDXggYt|LHh=y`iMO#=e)k55e4s}^g&%D_@_UpT*(Vu7~=;RaI5O#28#+VzG-S0~ZfN0NG{t zQ)koKFL8?}ubN!xJ}aEjcGV|c=EQ@KRG9|ZE;9<_86{QZBqWj=Nel9H*E;3Ep* z#)tlm@InV!&V=-dn->h^SU300-LFl?oC2xxbieH~>+0%qI=vt8B4i>x3%~_n=GfgA z4dTD)RynO5wY9bPNm{D9t#+$?q@<+kAOe-yrQarfds5-9!{%J<#cKuz2A%fC#xS!y zjt1@=N_C^V0J)PN8z3V3rq%{Ea^z=n&leOp-i9n=+kvMHwOrifPqFMbQB_$=4O7w~1Pn)JZItH#FZ#A{aRy#X8B7sY$ zp^=SFZzcfRzZ*~1(XaA)R+g5R9wLWrSU)Xvp}!R+VPIkTQKyc+p1c!^>F7HS%*{2KISxFEG>N7?F8UPLP#qWLX z^wgFob(E%91_YvKV0hmu9H^*nvvGu8$%y@H!y&86tXE(!HN+=pd)wsc=_xHc`(v_V z{OI0qJ2Iw^QYbD4a*M7Qebkxb3Ci?gPOWPt&_@jWZes(W>5tpF5`fVhc~ho$PEESL z@yEeB#Ls;UuCpA^cxY~JHo}b>SP1De;rp>M)`u-VmLuwYcyR%JQcJPDosOG{zB<-m z9FfOeDw675QY-{mUSbSQZSBuIqz2)UJ69ee>B<}UaYOIZb(Q(zJcX^>p=5tbv)xt@ zF)=Zz%Brf?anM3M9=F3h5A(wg&(4awyL0u~!_agoSjk*a!TWbl3pGY+^of!vl0SZM zRG&}|$<6X44F6j?Jw1(s+R$aadVem?BgVhsVdeq3-lIA`Kkw@3>heopJlP9Crre5` zquee|HQbrXmxitgkG%Dk;*^2jM<|A#OkHw-147g2$yn znEsa3)WnC;*TacXlmxvLS2|s;e=A**YUu@BwU4xLp7(jHoI$78om^n=7K4qA&GEze z`si8n=EUp6rkaf#9}(bCh|v=kECKf?1?A|D<-%{$TOAN`v3_S)uB1aq!LdZ0wIgR6 zfro)qURg;8K!dKZJanV0mCiP=Gpf8uzCc8DqAqtVl zt)L=Ht9qJ%>Hr(Gy#9kFZ;Q6@ZCkf z`Le{7jvcHn63S|swWq{bV#o}syF(fN$fIza)2rSD}RA(DC_VQWFPD@jl%EyV9|Mw>{ zG7^3E=(a>E|5B&tk}O^=U%h3du95>A6H}JoZY4M=VQ}!Xs>qcL^sJ}sz;Pgu{e10Nx%{@eau%6?|thtpS2!BBEbl4fQ-{Fx^gfB z&^X$vg>OThBs51Tw^Z}2hGHr7oyU1?{hy9n6(#cwx0KLcNX9?FS!is>1>;6anVzCF zS+jeX*Wi!~xrE2YVhIViFZpi4L{7@(bp(c=BaZfuSPV}Nd~zc3LHpxYoSCi^-r6d- zeFM3Ce*Hlt)v?Soo@uby`5I#?pgEHGvu4k!H4*l_Wf!aZ^{-q4!B!j-!VEPl09Fcx z24?Tz5AZ{#928Ypa51*2@?{pcwPhH4evFSqE3z;)*S*Q% zBepr9IpVB5`yyU_;K+(X3U1s3fH&{mBfAw!&+$C8I~$&50TTph0v72&dS1$oVwJZOh$ z>ERhyYpH%7;K#`=?#XV|KQA(9cZ*joJvut-btGpUE$Hmbj*rJhh@=h9>&Op~kWKPb z2;37$8~QEDrYMx5U2XbUUiAecLMbbW5-_wY*~U&oFyI*fnePJwH_6cr1du!F9+Gt3 z8EWFw>$<*JY)@~9EI@^1k1W!>;l+~Mu^kGG=~`Z&77t0=Ea4$;G0F9TQnwj|%a**@=UhD~l>GCm9^3Oc);|JVm z+m!TPTm(4Jv8pR-R2sqEgyzIcZ-EwXj#~Bb<6|4Q&Re_)Wh7aRDc9_J_O>*+_p^6R z#(#=6la4-6D5j~%I_jmV2r*>ZTe?V}lndY}nLX<;WoU2j?i@AMu>E9V zBk_xfNxH`5ZVqi*Ub4xLg@a3uzh%U#Cxu+ZU2INXpWD|hvkK=vkxqa*7Z&qzTNpOc)GQhfer zS2^@y7gD9fB#<^PM(CxN&taQYfEuf|Qm4Ad`Gl|ns-(vNng}I!7}n{~I9=SX)-U6L zIoCKGDP!G*n_|cvnXL564;Xs1HQ0_-R|88cE659jz5HU3IINAp*Xp_Xxh-b2R{hx9 zQ&xMXn3<72eV^fvB3J1@^2$l!h=QXkmIPv@If)S#WxtVX3Kdz#&dkk)o9WTvq56nX z9T@oWnz|)iygxUq2jsyhDPjzzNNFHC@Hr3*5P7^k7z+qpvTa4$@le6B{3L6Tzh> z6#;-LU$TrM(U6-w{ei$mW&Kh+godkW)OuHX#DUuuDWlDwmDN>8 zax0Tqk4{7A5>UNehDE5U?CLb`G`6!3M=)(%O;-pmErzjtgexZgLEguZIgY2>o-+7x zl$eC_t3#J8Lk$djxM>Fo&X&B)0uKd176iJZTW#_VK>um=R=QaBf;4e}%Cy&x*(ZS_ z>FFt`i8q1_@8v6(idRn>6JiNYearia!9F za5Z=lql(lF4lpq#rY~slA_;-R$2S847weWPrb;AQfJ&Mm6?vwEX3|2baJ$F?{VQR< zEXK>|q-(TU9w=TOie!)C@5+y_G~rCmDl{gBuEkw}+r~{m#TP=xLZL6Ao2B{X)WHZx zT*4w!o;;D&o|nn=DPVB1g!a#$y}gnn85vj4FTfBV*8B2?3LK^@R2Iezms&eAYB1vn zKJ=1u9el(Foy&O56m%L&ZNT1Z_xI;` zO?%jC&(qqW$07e0xsuY-X&%g)MI|UCC&x-0-D|lXVSzmS@Jsv&ru_vlBa28M#)~H< zNCu&3?7$6O)v{&6KR?tTccx0x1x_Ah*4!mg6J)30$cov-$AJ}yM(bb-q{2%HWLsa{ z31P>Dsq%*EDiLeStw~2!MKp>q63w|HEOgOv)l}s8p_RO7c?k=Wen7=GQ|hxx_*JeWmtapLs6GH{G{!lQ|k;EL@pN^c4fCF{~H{7I;H_s+0xM`EmDcurBarQ}`+lG7veP z6=MfwQGjoK292Od0We}7-3az_aZBz0zqf;Wg zHPlZMfl#a-w@>XXD+Wy*?&V-+@}bs~=Hs8SA-iqoQk@olWBt3t)%`qGI}OY=`NfTx zxr=&ZAJ+?>aivUk;rx4om~C<3bkIcFRH<=?N(dF!~?Ev zoUYOfx)&sbhRCiv9KUC{mD;U#gBXBcm;GsSArCIkXU*K7cvYy$KaY5FtKOCqv23g*Mlsv=n{Ma#gLycf(p602XLI;L;=_2r^0_D{I619PAiN)uh1(F zTYHNJrk$%>%HOx{Jd7M{cwbmd=7@IOWM7yMCwxTr$??6{wQt!*%JJVu47AvjM=i0& z1(!)^e1uimnZ91q6pU4~@xcRW)Osw#rb9#;8yn5JNT8dF@ldLft*a5Ry{bh zpKT>hPQ5}nDLvr>HIOLY)iD?c40T@$VdG{KejD~7WM#2y5R20V zaIwGYz7c`o5|{c-_GA3dxYOHs(2a!o1jK$&;L6hwB}c^BK!mw|`=bsbdmt@@Rc-en;OAoB&fUoupL4w_7mmrdMSf5FRdgvwToNK3#qw`ZuO?kD?%$l0 z7;hqa8Mc0fB^UEaDE7$7?AlK=21nKKY&-;8iLTIzhXT}2m z0`l;&-ijjz_0BAKJANr?{M9`n$KUti1FN9BSuJxOBLYt{q--}CtBj7nTMNZ;10k}27Cs4BjT;pKjz>mYW6o@(+17$zP zv5832MPr0#EwGk)iaaw-Vx9*YnJES8wcl`6Dzs^f>WsxB3j)=@ot~RoOB1M|J<4A7 zhkHWzK-P_(%hWrnZOch@d&~Cj;>4UJU3q!@lWaDlnD~aoPY3AIT`T(Z;*?kv$}vy# z1Qh(;k#6B(WGB!dinB2t!2gzkJY*p`!Zm5-_lcj2#DR>NNB&UTOe5Te7b!%5Fo?@hTxI2uIRw(8wBcCp+GRhs_t?g`$CZlo-K zm^V|yh3o$`>s7g==PybD&Sy)=#W&> ze$@>*kpj752CUJgZ?BJC>@lK$56QbrO1w(>^KW`uBes86+#SE-_yh_?9>HK;#|2&G zi}fJTU!rW9z-V~xrkB<^IS{DB@M0jv;`OIy$-U5ZD`Cr9*Yo-A@hC^!P*3VC(EnuT zBYAeZh0iq#;wU{%Y+l*Zl@AO^L)ZUWajw-5hzOuVv%ku$RvNWF`Rz&}3;1BIpSq$R zZcDGkoNUVcsreH9pt(fH-Uq#cy(9c-kL8>Ao^pnoNOJWJJ8jcFkTBO5mPVz{>RqxD zuM{u0Iiti=oby@e210jv)qc^H$+G#pu}ti--;pD+UZCn!qL8nyyi7#M9@(x11{bif zfAI|diG`T)U1BjZI*?c8u$CSm3-~Sqj>O4hCIuHz$A1eAC}I4TG1vuGxgluKzEnfjp@%`IvgbGXt5{9ZR{eHlftZ{PZQs>jaI$~I}2S7Lxx{Q z4i8E)?RQGC#Uy;SJ_zct!!R%XYSaxk2hd!4x?~(@UYeIUCg6KCn0n=DFV?z1oI*oG zJ?_)3zJ0St>WRne<18yui9CbR>PkS(!A- z*cE_MhTo`hTEtUFJC9s>a_)L!ydTc@#%5JBYZHbK8}r8bMF_7w11&UY2|%(3T00+< zG9Dd3(Sa3t%xGQ4B>U*As2;sI?DF_WHZANe-^f>%MYGYECQ<+AmhHi1k;a zi=u~Zp(icGVaUHUcdnkwtdD7R@Pa2E7*ZZzbfAV@xi;kD|MXvK{y{|r*+RBDM$B&k zKOL{E3@5LA&}X^=E@iA}m5m1Bhhq2e&6M@)92Mq?p`_v+*fs)>{ zOnz=}^MtWeR!gCvYH$Z+{9tNn<8v>gaRz-7T78pUqH?irhdsQ-w9`Ho6+PotnKcCw z+c?n(2=ozv#``7ZqhZ`aFkbFBw6&4#zTxTVZN9{bKtqAh6l1Cfl=%}3w&7&+HqjI; z9?S|aO-Zgrf@>q{tW7^>rr1<+C(=Tx{cRn9gXX16@}un$&+TkwU~CM-tg~}0T5W5Z zM=BmAqgrco<;f|v-evgUMp;$G#Is|L)u^|iej?wuPcRw-gOlI;g_a!as&GoD?0ute@n%J-vw*=?;3!6_tLUFgzw=Gqtsi_7G8B;Hh<`Xm)sM(^{Nq`yC`) zGwE)d31l9gnVl@*6#e}EPa|t)!i*6Bb|xS4Wb-jpLb%nY@$;qLF zl97FVeUAviyeLV@CQIy1yE`pg$-f7w@&`4BbHqp^SgR=$=C{ zUH0(rdUuAqyF1&*f18N{b8>gHYFA_VeQEcj!lorA#-yQht_DCLaLwo6-}no-Fh6Os zC%UQI5DuS!i1qesG+6LK@Q+n99mcIP&n%5CgT57jqWEa8{59l27HlYLFSyq?4rzk)Z-eUQF&?xpAv`yUOo zFdOYBLc0oh6%1b%WmN1$k6dzw3sJLNa=6AvujK_}wznAw|J~ zWZ`*{FhYjlRiatP6(LIR7e^?mZ1xII93e2VMg3OCMa#=e+$3GuNntRnBpgqk7&}p6 z-s5;`G&aN&{<$zWCoAh^`y?+P>KLz^aenT$3jR{b;vuRYe2j$1p{VIE7SSd9+7c|E z`D3Nv(J;ZW6^QD**#o$LTO8)#ay><;XhDb7u_hIaCH+l^wF`Wti`CnZvsEb3dU|$d zp`e0^+JhQ0yyrX+o!_=kkg1a3$z&y#yH_mQ{_AX%@pK8kDdtyTpl%+Nl%5Td+V;zP z&@t%nAh_s&^C+*Wi6dBFH@gd5v5q)TVaB_ub2HG1XmG(-v*2VUs|lVbh&r;dH37HA zG}k{;VeEeRaC^2Imdvu?AtWMH!Iz`iV%B7uH%xm$q7vq|9WC6@=$`+ zr+@@;CA)VXsB(RDcoA&n<~DsldaQ7#+@WyHLf7ixOK0AFvJcll2gwwr8lxE~n%DEhHhR09^KQ zz_UR_kuMRlyrzG>$i6~#EZnfy8%EjTKYq-sHz9H}W`#{Da;VqparH&o+OIrAb$8|? zw4@YxLotX-r3sF;mL3fJN=9nONJJVGm3npFqrIT|<4*(ARr%moZ`8ffNr{wsXO|~N zEiEnON##TZEBVq{IxPhxWTa`H7zt{LcYM7xeAz`jRt|ubhxpqCQ!UB%gfju7=~lYbHTI0R)INBMtR05X1i z^UXf-^sM-~@EtZO6!l;k5Z!c&TOFbK4N?Y+?#>Sj$3@N1)asqOt=%lkcO3mGsk7k8 zHq_RCK5m^YQD>`7+>YjO3Ri=|vD};4%ItclJ@Y`!@xo8syb3QJba-PV)sFf?V{5W6pZ#G|E_35#6>17UmY;3P=`la$VvOmb((@)LVY zo?I%9$evj^=!ezw&FYbFerov<6Kivsnd5rFiszdT*=U2r&k}28<>QFv)ua!L%k%&>BHa5i%?*+VU$*doQmBn_#=#8i(jL+-;CI;Wp`bl19ft+SvF zf{TmW@B7Kk(J!X45fP5$Lt^(5%^{E`{~;{;&`?4*UXY5k2JlY+Os~Vw{NC-GfG{JL z#D~sz-ye`U2JyQdeVbT`HsG%>> z7;!lViVvmTZkXRzomaKz7Uws+pgMvshg}9aQFS}&hSV5j9+l#bs>BZX){cN(#T0E; zOY0lj679;ZmFpk%bx!C&$$8IriL>_Zp(rz5N}o%~eLUwm;KFZP2$yz^p^CdZf9;oO zDDQ7$^Bo0ITAm52NuZlm0LT`0l*bS2W3i;m0MMcz&du*a>!*TXHID$*E^!qQ6j>T_ zte{CbC$9{7S%TJn*2tuyn84Yor843YT{8gM=DRDyqO+R#B4|_nJvsOF)N0M^rc|y| z{Z3JA98R_C_KfazzNj84gJTSDT&;>@OnuRby=J|iX;1vKw$vS>QOW(x#pRAn05ZR* zJbik88#v>9V7*emHeqixWp-&!-p-C~o_9W2dYd-aHWbJlQeq9{=jYyCNxKrD&9&-q zXAnJEEJTDa(ku^oD}@xxDWb>~GUnshi^XkT42>6Q6iYMbIv*dC0d$07T5ZpTyV-N~ zg%-ib#}v>W>7Ek5zt_LitD~p-<|%Pbsa_YRr70W9e`asrB{oy5i9W?vs2Jh!{M-`Sg!b9j$|VIM&fl{+PIeVUWUKsL; zwnR_}yZ=%wg@MWn<`x%cr>7;AoY99{>2~D?8UJBI8&nXf*oar;ZwXshkjMJ&&e&=5 zgsTWt@drV@yagL@4Am-Ml!q4Pvq072xD zlVhf+&xfo2dB{t5Hp*{rTK@0V=$l^KkcXG89HOqrJ&tO`>ZKOP56Dz+3MNkkJ}**E z3)T#HU)^y#JH3a~5)|>j7Kf$B66kN#MdXAIX@CoPvLPrkww3ke0;$IRh^6VfI#?lyO-m{=vw zuY-b%217l!0DQSv08uSoE<}PcS^jcHOO4<=?Hdeb4YJAu4rUWe6m zVWr(tv?fLI_ATm>JfDfea{+NAhMPQYv`u zs?t(q%er!8quLb4EaZ#P{;5QmqJ1@pX>GFb$#dndXs493hKBhQs{ZuA`FcB34P$9} zZNzlEhJ6>r^8BrLz1R&^T)lVnV1nVNVBV7D)cm|GG*3G_qwZWGWSqk?kt{W*+6)z! zu#P~z-4`&eu@fQVSSn4}C*4Y|N`wF>sR~V$+mhBOKi?*B;b>ywdg?2@;nQT$@^zx)!g_^3M21s*YG9!?j5l5llpdio$s7^Zn~s z2EqLA++X#$V_5i2mc~yvyK|vZ7E&@Y5>oP=eLeeqD51`l9drgi!sO;+Edi#JW;%Cj zYHFx6-9zI_2gt<@YVcCX;*xK)rz))I&&}~D zvQJKTb}r#ztSe2fBrbJ+Kd^(?-nZ%O)|tG9>b-AMy>DM&or*)1by=`*+HUMZI3W{r zERQbV6I`jD1-z};24lylF}}I-IH_do&rFY!tUu)Q$XYWmL)m`sGAJ9DpC1r}jCI{Q z=^yKT(b?P}y~lQS1uyiAZCUM#E z3U5|Ox4%#L2x#P!Wyqe~Uurf(-q(j4<%!}|H~IE1gvw@;k#?}x6JFRUjd=b zuo7{=)HNF8-k(2Rx$B|vB5=8*v#KgNQ_L4X8AtVJS=>Nc%%rI z6#&pY-`VOFg_iMkZf9RdSeT(gIV4!jY=dY@5qVlcxl7^AJrx}z$qS`+Xsa4sstHjg z;-@m-kPEZ);t`p^?Jd5?4PyF)m8`4XxVKzbs9`<4%@6DLvZ}%uwe?3PW@;`Sn~O}f zS5^J4B+!K?RcAXkXR5N7?8^@8NAIe{Tm*GybYSW+*);N2!}9+$N9b9-pj%)jn} zZ}hT5k6HPR5^PEX?feX!6q!>56!d z6aKYtD{Q;m_p%QPN(K`80@BQd+{P99D9V z_4z6C-pv21BI_m|d#ck$w!Ez=%yt@HLsF9t~w8<#7;|B z&)I}4Jvv1@M8{pCwrwf-?PspH|7DOa;-3u(b%A0x6dftg22;u9(-vc;%R|F2b7QM7 zxxtM6DI2J)`&0R1U%!5Zs{L*z#dCAtZcBSijYV;c^ApL!W;7a$!&s{xPkw^Z_RU0| zPwQP=IZ9aZK8g{^X+&BBP0fReke;kJx`Li$&!Fn)WH&yU^7xy*f|J8X1eS%IKU2V-7>mR4mEyh(9bn05$$N6S4_FMp92-J9HMHao2rds(Wxt_^w}ej%TC|Bwp%1-7Bp z)QbY2@US11_(7Px9!?n&KmDd??HM|@-J98p!3kOU_#TL(1l58Tc6L&%HVHz_^1L2q zc$f3BeMWUVUz3!xLf+e(@5irajFk42#*diBbyJC+y& zIWtpjersFczy$a0&|)>L~+3(E(ZutA6_OyFu3 zphqJ3=0!hJMl4Jm@MrgG3mvHpY>k3_OW{T4uvkHu&!5$pZ`zkmX0KF|@bbLaC6tX1 zlsh>ln60g~4I8=FriFHp%eUI#MiGYy1Y)W>gdgFeM%-}q9ckvXb4}j6eCHMxpv=@V z6r;t7-U|%udQPy11e@fwC3!&+_Q1OFsL%=lpVFXOupSYBO>|M!*K3`=MJF&xIBmWAbIGso%vsUQHVP0^@#$ z#5ex$N_Sqt>+I=fb81_g5OjXvhu=-6=hKmuAG{dbPio4|ut_3n9E^nV{V88bv?kON zNuy24i4_mna{U0GjUGqyY1m;?>B>#2y!_gTyzg9hJF^~$7#3{J#or?YgaqRo*uKwl z?9O(!c<(`X=lgU(0PKX|^W@)y>ovENcfkUtIkbF6DZp$LeN9-s*c<;T1-S)Zj{a|| z=KK)%P_Lu#E_shVS)kk6Snn%x`1}AAomT2K$5IHpy@mP!6NcdrGr}YoW!O{Y9*`K9 zkkXLCke|w(Slb9WpvXztbt+ES=jRcd_|D&1Y_ka!{QH1zYK5dCMv~b&Js~0%?pZlY z)>)tVzOx#ScY?31gwK-^SEvIQH_jv0rOb9wE7tbb`L(U-ve^`sLJ;%+HiN4E!tmI% z!V}WqFShIsj!RaGX`+bA&OoqiuF2*`C-k8B&qSl{oNQrlC7+2Ws!MAmAXmDW1WxSd z;r+U@HtgBPU!jtCsfwVTD-@n_*;##;d07xS4+!rT<(MFqWORTJ?Mo|bx%r6w(V_Ot zFhYpW`Ev~^>^x9AduDpQSM*^`ngqyz6UjhKovH|%5P6LjD|)G*sO~G4!jt6u)Grzi zhH0$m8pxLpbI?zPR{hnj`x!GMe(Vl-Te2D-JnoRl+et@ZnRWqj%sGq!8DSP2F408( z+S^n41}8GSvEh$vvHfXJkyy1MarvWl5lDeA0qDeHX#9P0mO}glp_@iLtcf2;g^psWwH&8_IaC zU^%l?98?fFux=Vu2o(=ytMGPM@38#kDm(0mczf%UM+JeBeGa9m{;Paz;B$F@8t3^l z7$~I{mZ7!!gc_?*47;G!{6y}4^kjcK)j1Rvk!Mc+tQatKQV4F#$cRKqUsrS5n)bc~ z50H^F5*HX}Bqi%~e#{;B`a8@W1K#n)cokYThI$zsMPiCRba>|ip7l6_>KOuj=5O>eK87M z)U#r-(qu1^APcI7cX4;WnVScD1;h9bY5!P_Dl9x zzNoN8q$BY1^4fYjMcJW^Mj#1~&H1;X)~-hDt1$q|#W{1UttEtA5|03os*0gl5~Lb1U&%GfUTGW9Hk9T735nQsNbC8 zDU)xfO;*K={;Wrm|C)MM5*ruuev{heb8=Lh(bl>n#W!eVbSqhoLIdoVit0mOZ8AX* z@!{)(&VY=l@UQoilx8a)6u7-@V!rC@>%>$n)>=)f3G7C5dq8bzxtS0)k`rTqpN+=2 zoteC&d19^`!jyc~}2uks_=2*o_E|f~W_~&fdz&Y3Kdd?p(&? zs9@6woQ|Y8wBOL-s*|A4m)qubd!5UtPdVzGV@B_LrKRAQuivRDb&~#@)jA?4r^bum zJz*X%#6;5@Y;t^^OFg<&OtOD*GcdP zknxMpTCOZtt7oV!7O}0!jkjsFXn|7%S*aSjAE|?1}u5e0|>SFJl^Uh(v zwN)joQ4Ov@7yTvL(Htwu{0YIPpB7RH&v(NFVxj7z7gcY)=MDf9O~&5dT#G4$*r}h z^wafror|-J*O$|Q<*B3D(!}S7^WDk!oyn2Ly^kOikVZ%(GvI5xa70rx4FRGkVE^`r z+h?Eqoou!4Kdsl&%~NjvTwQ8kSS~$Y1ZS6TR`dJm>aaPQxQW=R!#V?}l;jlfeTOOK z&#=`LFC&Z2^(P*bW3gOyJ#kU-*YCF8qZ}Ho58r|M0R)lLGt<2zr(@DR|CHP$Dp*(; z!Gpv23`Zwth1xY*Bh{%u**t!NJ-$-YOs%szK>{i)#G@%P1ZQ-BUSe=q_1@J`uJJ>) zL6(4HAk-S9dwz6N*xPU7>+N!_CPslLVaJt7=pq|hTjqcJSu3c6#!u#ACe~xby~nq0 zmn)AiJ~sQMm`_s2>dHpQ)`GHsn`)F<3SL3t>Q1)wNJy3g0BCd0EhiktVvd2QGl(Mi zJQR3s|4ch2sVStlaKro68&dDBa>SgURyoN1w^vi_d~FXNRR@O#71yh(cAEG*)2Gi? zi77}w5~EQg%$+j@Vw=_m3UqG+l?G^`|4XWGEh0eR4?Khq`9xmz-px$vr_$xA3rKMSiayRu@!*+UpOWYYP~tRQS` zljS65&@{|5?u}mVWn-+gT#%>Ndz?w_UV7o%l>mH`(|Qh%WYnm@N*3AI$Mgol3NMfK z2kal%A2#=A%zMFB@^ZJJuSM(nVyTtMZ(jsMO2=eu%XqCz_dX0Iv-P6`?czc5#_(K(Lr;4-fNm)9faz*xj z*L`&r=br^tRma@~VEg?HV?W*Rnta0#t&Uf2x;#>Q9{~Mx#=kqpEs(m|9lCQUunras z1NU^m<4ekiRR7cBmYkOA$6gy)SuUL87~5Kot&lAQ7ceWl-`|Ze5TkX?-{`wtYy?%? zR94jl9JFboOwX)`R4@ZZE%Xg&_v zpg2ytcR7O=bqb%zDVa5=e^W$|*-7(&%h1fjYb$C}Jr?aN|5A@0!*CN>{>}Cxq@fTJ z7Dj0*nby{EP?^>E;HZL)fMhr8V~xp(7hBiR5MJ{1e#ufn(qM^SONlZyyEtUmyf&h~ zNgePr;8wq`)pegk*^Gp5;?#OUd8+voI_z;twOKqMj%R19UFt|A=IJ9bq!UQ+mPpuj3_ck$G!%5ZPkA3_=+@k?G{ zEC^f7BN-CRX-A~?&Cg*-GyH`XjFtlz+K~`vCRr_5-qkCoMYHChyqX;Fxyx%C?bH9X z0EaAxos8jx2Sjr2r%Ru1`{Nlx_Yd}$>%Fn>l9NA5hl`DKe(R9mkYq#)FvbzZk@BK^ zzxeSYge~GAp8L}OZfxzD{1;?c(rZ=xL+oZF}K{K*0V&bu+g zi%YZdNzxI1NK2Q_%%ri+hz+Z@`D$FV*9DY1nwF#7%}1tUhfaV03lqOJ**`e2_VWxb zP_N;42pL-VexGlHq*>O&zQis=s}MSzFsgiY+4(*wyaBm^_NIWc+pPz&`UYZL!Fw$p zk&!0~<^`C|eo+6nTX0MYKGzZv%qa%Qn5Cy3Y?UXtj#G`>kSz_a%qaxs9C;mnr6#BF zSVnN!gnuBU^n0A5Ve0(ny>XKx`XAAGx-#o}a$>LLcD5P^E=yAU2)-j_4E!cCBJY(2 z&%Y+qs=d8^p$9l+rh1xs@6);PM>~R;nlPwl{T~4MKnK4BdYV}`1VphL8uO>he5+9A z5zQsH7GXBmf@MbiiY?LR=g0j_p~WE7ieiKjLPyq0c=dAgb5qz23u%P>1*Qebw(UnP z94DgL#4H$$K}>+r6tM~buIn!@sc9_r-2lNLSPHh;IQHV=^A$IQ9UWUDi6~(=#ObrA z`R(8RZ9>r~j_0Cjn&0Q*D4d_0 z;LMpbK;Kp5lg9Bpq@v+@5)$pWIfyjt8FBkcK4!x=Sob`iPbk?+!^$Cqr%9n9RTVuH zqgE_(`2cS)65J&{iJ==rV==0=Dz-o>AT+~3)@z%kPWhr=gW(8C10MSRzw)Q8X>Ppn zHB>5POw$)s^B2t3(?~YV2V;=5OZjhB@t#p3~<(Jr8qxFy>Nt) zu`P^rZ9zTx3{nwVy=D?kwK=(^xtAO2ejo5YDdig+$N7GtR6r4EfY1T~WTQ^1ra}7=vYZxMk>*<)D+tg(dm;PEJ03iph-NtA)(ZeCACb3pp zX{@gx8%2<+mO^`~+Y9>R0*L$9|t&Hb<>iVLiLv9J9EJd`RHf4G1TE-RDq} zs*$2i%@WWc;6P{6KVpc6f4ftaVVvHZ32yrt(vy!+y#Fg0(U_tH!i3XZgwx$DPfya^ zs{_#6-FIWUqn&|9jbJc9rB-Pc7i81f#7{r1{k=pYF*GBH=Lsywqr0~sb?O<8=T|s& z@;JBLatozmjzS^l3zc0>J|c=M1fFgng@PA|q6!G8(9qL->sTk1awjR*A?Pfy$D1ar zxXfuDb<;*s6yFa(pj66bQUhbRcW>Ldf@_~S`N(~L2t0Io9F31p)Dy`B`F#EgJ^~1b zBPdN($PF1@DZnr^gsoAL3WaKkm6avRr6Q$Lq4{+>u44Q|aq#do1F33wMi^D``Pgn9 z!>!R-?<1ls2-QC|y239~H!KH5^ZgQ3MNu3@_uK9Ny*{99CdCD9iHg{~A=wZla-{FcecNrX;~nq#Ig%}L^7$~0MvZ*_#ge%-AOo0qvWn?=SR|TX zDbT!-Qvnl%hlol7gBG#9RU+dGiXOz84pTlF!)iou%_2yF2*i*=N9roFr3<1-WFSeS zV~qP7H6B7wgFbi=?1DyXi7t_VapNwhbFr-!akP`vy(e(Lxwx3$0SV~;)l z1g)(}db)cEA@fqurYb6$Cn+s0V^*u1f>s;75sHA6E?J&A$EQB^DSrB=f0}G|onpZ^ zSiIzzdlmS2D(C^EY9L(~Su0T)yMx8~r|4EoJnDpqgl@plb;`jg^RaHuI9(L8OY|+5 z*(v}o3**Z#F zI*q0q=tdAt4hh5~o~j~+fkZ{dTK$

    315HTbP1=ei`HQ;vw3!z|n4z+Rtk64GUsU5&qUYvktFV3>K zw6u{1uHd8Vded^sj~~%oYmrD0FAo)4p;#)jzMiF8t+KYZ-W1`#ihR%z!4S9-sRfZ* z5JNy%_wUgZ&qj3}gwT9B5CIVt;;tkw{CuG)zCnYh8Q7NT{JRNA(FLyK5Rb=s_St87 z_`wGW2tiy?d~-9{1hcWoBo2?>e=iR{_z=JF3%^Jz)yjHyjeNd9DwQIetu-s`4dL1dRida0vYN%7Jx%WPlgQjMfpm`y-1G*K=-ZNPAK7th zX8L5Iy0&tu4kQJYN*T+lqw8(Bo{I~X0?eIwVRP)`@)_Ttgn;mSkm^zpRRv4)b0`9e zr2=cKtF*PZGe36~`FM3iya(56AT>V`p@hiqcss?y3KthAseR30YqAqVSm??!6XF6z z&EtZ$g$oszGdtf)!|@QRNiDbb_{$wpE0szcuy3+lzF}TwwA#;eT2f)SrpZvT*{NpWvNuktgbARNG8eUt|A||4&g35%RveS z>3HNjuVv7B2HVpyR1+`d`l+Jm-&`B2Bq0^nR1Jk@+k&QhQdL!if)Wffi5-3Olx?i6%EtR5Mp;*jOt5wOYEYXr|Wo`8;@}Y(dcHmZv zNL5E_Iw8%!8N>xe#pk15;uFvz?m=GDH~F|m&}-OrRWXd0PeA|kfBtdu*=JwaBZS=3 z-PKL0T;%aXhYB%;c+*z#N+GLe5|Yv%$&ac6$8-477eCKOKl-cG$~ETaXBi$ICYwEX z83cD@bJ_gXPV>(Z{|u`rh^RtvNYZjp(DepE=cq<7q)@0Tlwu`33gFd1dI-G$@oSK! zDP&70l=EzD^9V;gCf6@gd*nE#<=};4$Z!Hj2x`Su@I0bjgY?QORtT*2Zp#%SphgmV zT86ehyn6n`6^)4Lbb6pQ)lR+9@ZVCtMNU;Tua!6WbORwhfUXKO;h_nMu1FN&;#n?} zwJMp_47Ey)+4(toy1SX5J9`!R6d}1ExqRN|)7l5ilhE3Qx9t|H{S!RaDD#|Mq7wzh z4Wk(`tVo!er81+9U=}8Ei&@&X?V?e9#Vhy{aA^Pj{mbD{=#!4?Ap8q8@I2yeZEWr8 zA@k(ZJbUzcglk{HM^!uwMPS=Ca@j16TAjItd3t+#xG;0#>haNvh{RrGW)^9Lpi!c> z<+Z#puVJj^34|n0yR*4h5jik)zltJs9i>)81&oeC*HaWV*w#y|e~9(zGXO_kGWVpa zm3%HwJRV2*YP;C=OKv4dUw2wlHH=`0NHj)IPZ!0N3s{c8YShW+bC`9L`Gt7~`ujL{ z?#NZ+gD65c0o4*xQ6SL;ih>gGXcR+4LMC3Pcge0V2ZjeRA$)!4`~oT;LJY>tbwvrLSSqj>HL3bB{f?vQ?0@kTcC zkf=hSOOJ)cMJ(H5c6N@Tp`qsRV76KGvM+1<7EM46|3g?1w+RdhT5fjedc8y6c1cG( zh#*Y8;o((Qa0?k^y$Z63i0Q~+92p2gdJq=Rl86Bz6}8k$N4Sh*3(UF+rk@D(a0)|H zsTw+})w~!EL_D)nrBNzTEv)+m+smF@Zf)@Cr=KJk3=)mSh(=?$6050X;Wyv`u~2w( zmnemT6dvw|Q)NIW(y&=xT*9_Y=I7_xGBm{D!-uaLA0h%7P2%YWbdSQRLktz3X8z<4 zaJqNEb#H}{YcU%Y7OWDQSwqFe2n5jeAXat`sRju4jUlCqYg^C#dp$sFYisL@qHy5A z0bGfrC`hYbqmo_cf&X=aNRy8uz@_Qt*&Jv_Q4p5J^3sy8*E2iE$jAtfJ@(kui=U7O z@igB00>s-O)d%r5D(ycHE9a0ikCGuvEEPjE1mr-K0t3H4PR!3yHBtoj-(}QhPg9tF zfyJlq$F7!N)+=4pw8`~smR-Ad;Y#pbapb0WUML)cJ;}oS0=<2Gzynu}j}r2b$#!IJ+28I+kJ-LEN!IVfwge&qv^Voz1IYQC z5<3kVlbVhf;z{4Xcn(##0?{Q`F$wfcI=Bpi-%V>-wf-kw^r8Hz^8&D;HuY z5$C#n`x)K07hTsWE-a9}FvG%;!#I}53UKPwDaJ;}$gHk1GBSdys<`gyX0w!cSqpgJ zvMa<81U-zd2J!t4?YCNVZk2Q<0<>sBYPNxARj}7qaq@X&!vXIo>d0QaN**Gu$hJP> z%g0fNpekc%o{15%2!te&NON~u^WQR#l)g>0Rr5PqLy3@Gt)d3wsNq)Mpzg9~d3ojY z%gZZ|_`hHNmF>UuOKB;nix;(&ODUT!q)jcE4HaVPH*Q81g|m~BjE;`7nptK0_HlGw z$F{E$pDjD_suhT&kX@rB4*eAa{Sa$!;o@wD>OFsqs~FHdhUgi?2}hAujmGjc_WW54 zvr0$-@0vFf=-EQJy}wdhoqNRuG&?(+m7XLN3L=HSLtMWwbJ;|8^S>|R^nuexo2t`x`602TEHw*^) z2iQI~%G{HOdEj$j#HvH(2Ngmr>l zF7fR(l6@vE;Q$d4LX`@POXr`tiEL2X;VfZ5((d8S@x~* z)>OoNQK4PkEMoiaQ(ki%!}SDGRf(!9N6t^NZQC|#wHnJy3+&vngQL%%`N{K%Pos`} z5c~9_(7ywUSz6UH7+{tYw6sD;K*zFd>a|&%<1_vXR6@`&&^tPbF*k_Sq+(dpp=RqvfN7l5px;h}`8rpzFQ&coO6tjfqCUK^Zqw5B)Z+$%Z!(1}T<9IV!1U5OLw8>cq& zJmH=Zg6VcDYfInVm?>-~AcbO~h@?5JDLvXcI@{)R>k=T@)5GlIB8#i5O%*G#DcZe~ zSz%~sh|$~c;N*Azm9XtHH$P7(6k>L6o{5PGPM$U}?Q z(ZVjOR1r=X%T7|03d@BI*|Rg$rx%fxGKfdeue}X7djT0qA&2+Fy?;Y%tN#<_i&3JH zB3)eyJv}}2cJ{I(VN!jrO1WI;Ona2kZ3foTDW>%x)y_e(k9~{c>BAecny(l{D=RC@ z%gal&rrXoY`K-L8;nuvhNTui=-%2#y=8Nqk$SusX@Z3@VhQ)HYI6F%$8fAWAk*(Xd zapL63pDZ8m5Zb<5adY#?a1uFu4SfGEX>SKlRVWl9M5D!~{H^Xgi5mWhkd#mj8bnnO zM}locFzh;JX&ry^PXavgN_^_|`b;LXdVOnKd*@;^em1HToBcmRHbbcCL?M*s?T;Yj z`j$(vc$|gBMJ9GkaCY)6jmA%wkG}V2+|s&#gdaTs5B>wKDF`K@tvpI&{Vc^#y$iQ% z3}w&ls6+b@fgo6Q+(r>=c?NHN9yJs}Pxnxte1=zJ(bH&H=hxR)Z)j<6>#gV4Wi6kl z_UyBmmQ8B&2=DXpHL87fvdJgzd7PV?qOGlsg~bI%hKD)!{PURRPdI*dT#r}JBST^2 z*bVU5S4b}%V*T+pc-Q~H-TMY|qx<>l`6t<#T}Aa$d}89SNYBiW_n_v%s)#Xv?R!Ae z5WyI$&)rYPbCI5V-xWpZvuDp0rluwjH4WI3La?W$wKX*-F@-?0O_N%!Ml>3|q=vt- zeRd^_i;G;hZyzWB&kyL<0~|kooLg_Xh1In+*0Ndl@4tq_ho1scO))92d2N_$4#xR% zqh2*kV=+vr!$nh73PG1zHN)EJDOT^Fraqm+tDQj`O+wo+-l<2Bqt}96r*HWQLffF! zNTJ{$gru{x3sqH7gn|~*2)9KDrC@5$D7)+@nCpf~(IJg=uV}2yuKjyWh?|$4wZ`$; z*}0!@O|^6`p2JiGngD{qAUA#R10+UA$YfS277Cb_MIaEMZ~HjocihPjKKUo~>OoGP zJjv@09;CFk#`^j?*I$2qv)1tw;S`&CD@*yx7#r6VwfzxK+fJ;06-XlL(>eDB(C>VfBYOg&dxrpS!!IwKcuaj33b~ z5%{jUa&r&lAHRHu1rPtn?$HChaN-2F9Xv?6TqcvraNxQFJo4xxKQTV)pn=$O4eqh~ zk)!*;snI)sh|qRFevpt($4I5Zl*_BsANw5Ueg8n!wNM3w)l2?ZcKfhYhjt1nlrnJU zhsBTQIj8667ino}O)W@F$Fekmz}gUOyMmA0loj6K)2#(LbNVzrcicg-P+(&SUkkgR=BWIWA5*M8E$(&-1*Bm@h*Cfwu$ycEvP&HoLw8d>;6GG@5us*Y%GK4Gl7N z=JbrJh?E`(5^ifl*A2hMv2mtv{^B|=TEHL~36Z}rOQ}((?s+7WNlL{c$y5uPqLR&? zY!1JrFH>nV{r!V#A*G3|*Re|#s+m05sU^5z7zZSgUF6S z*!@$8ulx>UU3v5f%r6fS2-Hwjk6pXA_%5NY-+3wsp;W;8@aX6m)01bWRYjy#-Qf0L`A@8yb#`nPO)}wigKet#dS!vwo)t?_l@xNKV+^Nwv$#xY5j98M&{5j0*@^8J8 z{HPGBC8hV_ty{M;b@t4Rs)!Uq;0i%XH#UnvTdq66_S^1c`|Wo!cGJytj*XF>o5!s; zFfEH*qd{9bO|euWnuw!oKbiOuEg6j4KY;zh{mAw{*n1b^s~=;cD~lF^#npZcqmHV2 z3=RgV*EJMcNw>$D=qSguoMm*30;arv1%^&FO}wl_CUn%ckVmq*5tLr6Q3;jBqH#+Ug7c z_v6eO!uif8BNoz;nn?d_447Sk#gs27VE zMqtxr;>GQHo|G&tEpgq!gG@d7Bz>O4$?0iYT3b+coz=_=ojtucp2y7jXPe*uHO+JC zGRPXT9L4eixD`QT-bD-Acy<-5Sir5U;+77fj<%s+`!1{({tcPxLhif+4u6wf$~2J# zWQ*NM&qh^U+S?%#iCp%V1nELP9%aOtqh86e>P1mU4+M(OKMGPl@aoL=++&$cW?l&T zVyU#-$Y&9XV0m@bcOvz?4L9*it@y6X#f!6Cd*A@49(aHr&*sGRG>Jq4)i79HU7@41 z7u%7{oImno^HGLV7}tLY>)5{`TRM@u?tn+X#Dsm4P#p4=c3jsX81(tXVlkvtDHc;q zd&3O8ugWjzi$v$2VX@1?D1|w_{WV7I%#-9E`Npy4TuocE+2j@ZtgWptODVhJ={C!+ z0|{RQRC-Lj{`K_Va3lFzjn(ya>PyS0ib5ip;Evz?ul%2n{{dZ|!^zoM+S=Ou_*q?{ zy|V{TQ8|D12vYu-@iP!Xzv)BRC+u9Ln`pEEA$pmsARN@7_x^ znxb5uVTb-8=Pp7)`peptU~6HNa7(0m@(DB}gcgp+U9%qkA!d!wWil&;fq{YK*seWW z0s#Zp^;nvpr@FRARMY(Q({yR|cQco~$|RC5UE{>`G_iP$U@*j5W|fw7J7Zg2&Q1RK z>r3egqTTutoKp`WBT1jnGv8*H{Q}``DA!vs8-i$5(A%4)S~bZ%@+Hg%K0{pzprm?H zbRB6nkX8*X(N60vZ^vA`h;-c_ylP)C+qNenk;tAvD4Z&;t=gV#tD%-w5o>ALw6Ya1 zGSzS#2gmc+x_dVZ&mF}8&MYm{-Q9)jO3I}Yv3Qb1Yb%w~MI7g3vlpvbIPUWoa{P9l*iiXz#w zXPB0j7C&ja0+~}V*9<0ij!4Xer?xf;+kuifA$D5Md9?)GJU<>IF6)TDHDw) zNwu|8EY9FMr(QiD@ic+g+=e!=8|%a&WU>pn>vqUYGx*G>=@|wagW1{MCLfQzdq;>y z(=06XqXt^}&|RP9Ht*}S%p9S*yv$kyP6kFi`-Zzk?%vPimUBDsZMr}H!}&O4kw|2} z5e%gZYZ+Szp(v^<-tk+%h27f9>2v2;T3Di7DpRl3sW<8r3VEvaI(u$<4Huq#lAsWr zU0I>CvlFDCTrLp_$7xNsQ7p_fZ&qI=9}W|E&F!c|*I=JKgcob~`7BP-@z|fzI}9#5 z7v}~EhpVWn$DTby==v5^b%5XcjW4jh(`D3#;0&xgkawZpIwaMx>x8v5jTTSgnpJ8S zPJZ^~dVpROKidq$*khU&<#L&Ny-sT?g_259%wz}&ffUd=I>zodzm2^=`yZHi%UjuY z`|AjW!>mqD5>*t=EUnPh-HDV?DU}IF;Q*`ZBJ+6>a-XIL9Bvi>CecRmsx% z&?o5|0asDEFuP@w&%S-#q|>eBazXa*U86PV(&pw#)Yplc1q`c-8gG+<9S22y{uGV5 zv;Xns#Oz+ln6PA;<}Z$pjwnlWb1w+!bQ%q@W!EmOrlSH}GOFMBAN6{jRDVAaU86QP z50=IG%qm?yeMq2Ms{w-c-U0NWj@_8TaSj8g@h!;DgLf9}=fQduC43TN*EaM6cj4xi zahA>@JBN|G?}UX@bUg4!jE(`C%KYLGy52xlUAnqp+qP{$kYX{$#hC%lIb#%eZ)H!n zN&3j&uu_GiJAcXYgsK%D{NmF{`KLdEEm)z^XuNM^WQ3);x#tCR*^P!6-n|EN!;z!O zM{XEQ2|>MHqot>ZSTIQO!UcqFGnL8E(bbJWp<1ipNoeoxLknuy_6&~w3ViHGQNpJQ z?A?KW&FgWqOE}9@$gUCOp4Y?jc@p3IJw`@-K64Ah=tcug^LIa^quW_n7-j3$3h#c$ zr)jlT@G?-$z*-S9Rd{yi2W_cpYW{&Qd>`aze%X)WDPmiz~=9Cc*rGv4!P!ma3 z*4Aj4=B2y%%i^eBuM=!(p{u)#!nt!`+f1#j(B9dN5DL{=4JjqhRz3mpOFy|y3a?`8tA%1M+c0JO)xdJoAH*qzG(meAOJ~3K~$dv7Jdky zqU*ZvO(YV&Oo^13rb##wK}jUYWV77*OCO;7#+%4gs!Y$$GBY#H;_@=7;b8{G##nvf zII8O~wUVK;yB8r8YPA|3g7%(1G()3NJB#N&^U8c;Qy9CqqhI@ayy80c{3(BZ?YR>& z=ZW3(-`O_mfvz&QFoLT3d{QacwQGWwmLB5qE^fc|IM#WvC8$m9dryLQ=daZ4{IVew zh4{YP-d;QR+#sHN?+>@-frsZzV*Qzkt3LmI>(M4VQ6G4k!YM!xlGN>q38ykTejgyL9J26 zsyC3Ti3r9Z(Sy>`fvW_t))#S4J_7M3pYa>v&=+Yt@fAk5ff^7jE)V0nE}_sy@p%X3 zau2<|F7J59U-Am*-9uHqg*Oe&F2uB zM%U;Bre$H;7EZH6pHLhk{m{~e=PFpa72K1LLA)JCuSagb0iOCM?MFV#@EB-@U}1R+ zp63t@TFv+wN6G{}Jtl*LCpP)0uCIuw8L-;ggSP9oVE&#@Q#=0fp{Bir20ZmD_#7&g zN*CMP+Xr3O#dTeT5ahC1x;i>oNhbN`ckUtD*+oxx52~s*Wl${6PEN9O#}3ABz6s^= z$1&?QoIcHg>HxKxLMYTg2+1|q^b(DZa{BZxe&H9s z&zs)xc{+k~Xsa&nBCM}LrVQU3`+(`j(pvF5f4L+b`+YCT7C*EWBqNUF+>vf;ix$?` zriGNL%)%nOZoKg&eAv+Z6@C&b77J{@`DQfNf#n5k*JWXC4coSfrrHpyfoX5>v2lft z2u6^B2vXCqYE|q)4!c(N7hLalpHDaj|MGhbGQJ^rN3Z#rDg|%it{dd{#>Ey^;4e+}3`rc+aQjrDJ{QG6}s``_ydPext7IR4Nr3 zjRvM^5()%p6pPdy2O}8t7uQA_5`GfO=ktu-cq4}ELS~Vg?XbAEirJ_WOLrhtgNE%; zuhnrp7Z=T!j8F|6>0#F@*o8c{S@lN=dbT6S4D$^6KCf@w0DV zH$6Q))M^O^2McT)J>v6O0cR1`R((GA4!yf#cZ?Xt@BFWM>DqgMKWsMFt-MM;n&)|U zhC(46$3aSo>$;n9Q?6ENluQ00DjxS$Nbx_XR4OrY!wu+;1DQok+hHlYPQ$DdOSR() zrRf20V!1YsCvc^L?MhtfVpl6zg#vb?$)|S$Iq^EAqQTccPG9B$wv2$H`|fNI*#Yzx*o1tK;*1?;H>O3sv;Qq!I7H;`VqZM@yRY)C^%9lV zdcFSPa5x+cM50C{*%B~9A!bgTz^qnrr6dpzH+z9L2JQVMWZ5?B>sf}czk#r#AeSyu z^CXp8m9@+gj`YyuX^6JsqT#wOj_cwH6;}^IvdbT>7~YE<-jB3RdUDw^@Bc*S>U9MJ9HH}88L^zow5HL11f*i*sm(4MB-2vL# z+HhvhV0w~rz0PW88P|1D17UwnsRo`NMg}9uPz*1eL?%0-bBoVs$vuNnm_B0`ZT1JA=5N(RaG@mt<|VhDwvjqYns#x z1?+H=ZH+*$Ckt*+qOeA2Khoev$K6@T7y8q=QBRu%C>FW&~=0J=SO+V zTfR#yl)J=d4zkN|zNquf{lC|+En6$!^Qm=Q=NDfzQvGTl2Z*?ibE{z(I2%dGb+Igq zWIRqbpQlkOVJm`IEV?Aspf)oO;w2pW7N#vm>pV$JUV-Sr(rJCfz#i1+sOiZNMx^*jtVIZZXT#nJ* zS!5t`3b_RJS)b2^g37<_{B6rYRV&~Avjtq|Lq8^;29UEX>n(vmV3UuZU>q#ZLs9+Z zS+*=vsgyq<-@KN$9LML=Kg71{UjuXJHsi-t6tqM;mQ)ZeU3jXFrv;FKh|fw<@k(oW zlZTNH{Ugz-`xt6nW!rX$ME&=`;^HWdV-pNEu81H1=+%s6S0Zvy3y&~Rc$(}IoX=}~ zZRdZh*@~f;zWRxa*7VUs^SU z2oVY0ElE;6y>#u_gB=btJv~jaSi*HZJWryi8trWzjE;_wd+sqF|Ms`ZG+i1^Phxxc zdc}zz#NckcjuE`GkJFktN;(OxX$Z#sR9USiSX*nS(NGA5>Zq!_dF&b(7{D}JSYO}H z@BGfMfept__VB$6KgB}12Yv1w1DT_o9(kK}ZsMIr>977X)|n^Y5BwuP{u2gHB@&52 z*=*L>IEos&ju8k@5rV<3TZzZxXwBn>Z0aHlp`fT5=~SAL!9fZqp62j9_pm7aMoP=` zs7nLJUW=vZ5RTzJ^BrP}Ng@Klkk2R7UKfPJH5A1|2+4s11N8RxqU$=2 zqw(ysH}k(g^+Er(b{@PLSe=5|75I#JgEjqzKQPLF^($ECp1J$g^hW(VPXIU>3Y4Bm&7+2qiAPYRlyoE?(>*9xuHlem36h0EM+AJ-s$> z8~S^^8OWT2i_7qL;tq4_O`i-D|K_9EXP$f?FXQ(4BR-SyczkT5#U&C7Q7n~cX=|6J zWr~f1{I+Ya#nAPpt(4g84HAkPBV;vr>KT4p<1g`s@Ex*CJXE9 zRHmm{dHNa5l@%tgKY$1Xs8p&ruD`7;SE?*8X9#rkv-kCHrmrK#|Igle$Jt$#`Tu>s z_4a$G-KoiBCNt?Fg_fv51QlInMQn=|6y2Y)cHMQ03+!)qUDltCbwxo0m31jgu^>nd zgbsm_-ZPWQ^qJe+x1Qf0-#e2;bQdKwm*@4mFUZW~=FaI@He zapsvDNH^}|()-Wn|4sihJN8-}+&j!6H_4Xx3MR}B)!MQF>%kiy06z0P2af}6aUJKw zx?$iQvC6x?kMw<{ZR1p{G`6?X)7w+8y$M>@%6hR`u~cS!atb3ohm~)8H=RvMCWeNP zI9P2ftRX{0v4w4hF0H$Rs>a>EwYod{eDGax1k5Z@3@$;`8L=0na$Ug^w=;R<()| z4hQvTnGDHvdiHb9Oi16Cl*$!G#>ViYjjVXeh~n*hkhGekD+L`1 z=xTtb28gFXj~;#0GB(zYVN}p{m(EUwwQH9j#b@@ZW?@V2B+k%&8St5cd#ZDJ@XT*( zwTFL(^}uyc0iWdg+g8VM&eL=qd>_~Iu*xM`T3dw-j_d(QwYH+^`Vk?+5qwG&#>U4X zndU&nC116%P;dsel2S@E#UT}e=Gb9A&5d;FbCP{Cv&6+h!Xm4*n+;Uh5 zgexEm)&ZUEtqXZ`Z-f!s?qNk^9xW8~-K)59_8;gb94-a776o-Zwed=lEx3ti|bSdFvl47ZZ>jn)w9M>h2EigPh zjAJy=yZSU@ZA;iww1S4{VYC;a>O-IORzQ9 z!U2)y#{+-LgZrDv9T;NT4Rg(zH`q=wtCp|*N)E?*N02>x-ZmhmO!=O-=14xGUcefS z$LqzL!KLS>rX~#23?^8eqpY7G7K&v?N5?ogo@KD);yN}mH%zlGNi?KE4ddwv4Anw2 zyrcL4q*8F;z!Ew-N}PCN4+|D72(A|$!3R6owz~&3Cgv>Q_VrK8@||7>04w!OtwC`U&Fp zXErl7ox^rKWNwTVtJk9HVKg&|qQ?+g6h}*v6K#}b1JQ5}q03o54Gpkp5uACZ&5j+P z=5?#VL!~;! za?J_kz&E#a3z593Jhf+v0 zOsrOUpl$B@sLJkLATvh9;JRYgj%+xOjt`Qaf_-8~e6P{=&;zDsbfssz&GiV)N) zHAY89@KBJNK|?IgfdgX*Cl4aHMyz2H@+7)vlMAeKWqAjS-9oj*`7D}-je@Y^17DB%HQ}PvYfl9UVOx{azHsD#GiSd z_lTk>p+Ngw)Vm@EnolSSH7S`A3bmTWqnCf5RiF9`GMOB<v?3W7AQ5aYIH6>3G?8c!KFkAF$wQ@11wty;WXU;zV?LGo_<3N4j}UkoQk~ql z2QwPQcRhZ+dpC>CD7vDe2%m;I9rV2Z^~_zlg6-RPQZ7{~7W0%X7pd8hEfQ*&gPk8G z>_bR`rP-X+2Jd=1#QH#O1vLd~y+QiQl|?)+h7kE##|$uC(AnxQWvp=lnP{1|(oTBr zzY$M`t5;oIDy%p=R=(^L_`|!d0RH0`^Favl7SDC}N#9SoLRlD=-Y}JN=k&fkob{pe za6=)crlv4Vou=ky8XB9>braX~sa7o>xbsdN*9ARwz?UBAQ8M zY7)(^(0TkxOioVW`F>r_S&+|W$XYgpB9I$HO>`12?769@I`?vD>`9u#>%{|zU+=ANBfiO()CDII`^{vL+`7rha*Zm534=;>O0C!0#-wT9< z5UvixLi$P1vhf@j4MDSJB7}+%0=raXYU?JH%qWXadjr{GiNRgFDOe7KV;H4ra9k8T zOah%VU)6Zqn-;LLa}YBY)ZM8@Fu4R!wOZJ*Z4RkqJ~%Ltf(OgJ+&S<49GaM-u=fd^ z!Z>*?!N!);dA$4WPVu<6geyP#3eJ7c0IXC(<5<72WcUI-c z3qD<#I^|=r>eYXP^VF~J2HySq{LYZ73>2Km|dAgm`~HxmLzB()Gi2uj04 zG&ZH6v4uimMz2aRHFk)y7nCQ23eza%aT-J!Q(CkNICE7HGK;!{$ymJ{+?XN}Dn5(P z$Ucq77oCRv)LkfM5}|3}djX&MtMGO_i1o{V-vs>WA9$qvTx}G13V63bn3g1|33e$$ zHiMuA2x}%nQ4saSgessqJ%x2>Hw$0?W*&WT1C}olW*pNl11?%U)uRJ_$z}Ad>|&v^ z>2Mmn&Vm}G;uHLA{X0qPqiB}L9hq*n_q~mui*5B0y;27CRy`{%H5JIyh2~Dso@A=JB58cnehDX?Y-v%;+L)gV&7;B24Fg?Y# zl3fpBe7bx4DCcwd_56?qEJ*ax*W5w~1x145OLjLb=CqbOkK!{kzl06@yeQYm5AbyC zICjP7Gq9ka@#!J_jX%S8;fH5@w=i|WdlQvwzJl}6O&fu;e&6w<{sE9?osgm^vs)q| zKo_8k!(U6N8gtj4#Mt;`{e~~~DCn>QibWzE7#Tst8W2{A?#jTd;M7tH4JWLIr+rMT z7CicD@RCJ=J*G2!sGZ^de%?6mNnSg6HUGKWNAFn?L_P~n#C`hLM>?MzFTBn0`BOzv zgdzk2xkVGCXLj#lAxLOCiV{Rb)zM-4&ioUG4~@?1Hx;HQs3{sm8&D<>p$kdaPzbw4 zRs$z222-m)?lNe?<*va~Y0HhHSQ1$jIO7Im2ithWbSO4<;En7#^_p;fu*yA(xHT%k1kQtsA}jm<&`L)Ys?iOgQr5Yopj=aHF1Y@00L>LE~6 zM5##qmI4}}NjR}{Aw%6OInBB=a6WZD6a&{`dKHXRiY@oeW1?8)@srQNy6b9`Pz*xR zKz>Jph^5f_Pr!NTCY<|!`Uvo*7m3fVdg13eilT&Ep)^Y=cNcuw7;`P5s@g1{parl( z(Q_FU8bZ^-^XN2e9K{H>WPm_rN%tZWs)k;l^s4VOYBn+_QlhywJj;hFxD~<0k9~ye z#V4pedJF!6P59G?@H1mLT9{p3r}Nl~3w&qpvQX(epTT|X=T8D}{6qLCe;}l5fcHw@ z&ncRQVVY>VhK8s}d}O^hZDwkMj`j{(nwu~*eKra>Tp28}>?)#KKog*b;v8}U4Q^~` zabQ(w8`IrQ$Z-J!;O|waY>P0M>1Jd18Wx>i;p5gnkluO&Ls{s0+j*YS*oE4=0_*4B z!oK5*M_KL*MCDPMEq5=ip9+ zrXi(3Y3M{S^Qs@H%d$;|(z$566(x zWB8s7_G*@`Fv~r8@N;Z zAk|y{9qIarXcHI_P{6Mi01e-Dl;Xd92=D2;ZU)ZyL;0xB1JX9&*S_byRtV7=jYjbm zwJLmfk0MDUB+_+JM}}FrY#BXEmSY$}(#-RGeCZ<*L}CdJY+tzQw>Jd zau=2~PjmOeb5W}WvTcp*Uc3OYx`WrYZRI_=D`-7@fibt?EC&1KwC5#OSy_FGoH66 zY}qZw5qvQgBsko)8-wA^lAa0gWJCeeE0>*`8*dsH~7AP3Q~5&VzHDf z6f5hwdm@&dHgpk0LPBCmpGnm~3xyF@m5^^CYb8RB?bIxbL{~4mVFU}CB7(?U6KKA} zuogvx+L$xC4GJ(k8RnA6m#{b9i7;peDt-U}AOJ~3K~znYP&5b@d=TLn+PvcckLopl zg+IFQ^T6i_x}Nc3JD?dzKkclj!so12Np;~0j?)V{6w@fM7>`P6njN?3Tf65>9z$7;02!R_y3PAbE?{LffB z_#O@@e8iE#_9@9HF6H|S9=XEpxxZ}}OjlJ8qV5ZXeu7%;-Xu5__H0C-* z)EE?PC|XdgLAeH6VS*D!ZsfSJUlJSJ%5=8Mrec&k*Z$>nanUIeU+6eb{*vl{{Yy>; z_j11V67wkm-8IK9CQK|D$>J4K@Yc6iA5iOR0+yvpe zq_M9k)Vg|cQwg%6K8-%`Ut&Hv;0oXO70a?tQw_s3V)68ps*aWG<3|w^3rSWBp%^B<=Mi!$;Cq;{ zIDVv!o(26Vu^5GDgpp{3@mPeRRFeJeY4mgxwVqRm4?KpG&2j5soUJXV;2zq85>5o3 zJsd`D??LTYi2dO8RB!&*L$X@>Q{cMiefoC{VVw?KWf;c1RC5zyGfcHw9gpQRlkJ+j z*ifaa3s6-bRe{FtJ`!_!2sgCw%+M4M4NehUomEgAU9^Q0AV84d!67&V4esvlZXqzZ zySux)JA}dAgF|q43k>eAxBpvpU+xoCRMFGZ^x0?2I_uNF!aK>1o#wuRiGbHW?`-6t z#$P<9xSOlCIZ>N=gQn$Y=Wcn)l0R%svUzm<9cnAQF#7)SWgwD(SpZuH&P!(T77Ll4 zK1dd$QX4<^U;V6gMJH2HzJ(;KTtPW%?&>7+>YyZpPGmJMc}TNSknDx7eA?R3jt>(n z6Uf1~yBC6rysB; zj*&oIK9nEVGP5Xa^YhLTYAPmXTMlqE#E=W8{sT`|{4a{5E8Lhlxa1h8#q62ro5z;_ z=BR1)!uI>g`l43iYAzBj{k5Hofc)(p@fLO|_!Ivv^S^rZ7Fm^f74+!nEg9a$Oslfw z!OTBL3AGFS#aWCyl~BKoKFEC}!z*ns4918N$gz{5viNP^%SY{JCCB-Lvm|1*M>dkV@dgss1mt_?+Uh@-J)c3{<4LFm~ExMd(6h z?D?gyf!C8bg#2ggCF|VX%eY*E+Z(w?e2=uojW;Y?=YCZk9jAyro56kCs=s7tM^wq? zwHu|2J0uw8#dXRj5G%{tpmdBnHRY}q@m9-u?+}e_K9WGyChxXExn#i0M?mpcz4dl+ zL=kDffx{BdtnCJ2slnYbD~Yb(WR`DxHlgwL_q`ZCFf2HC*5{Yw%AxGGu(z4oN-ew3 znjN0xMzJG~-PudK3;*&AAT$0*B^pTkU6{`cawy5K;!!U!^RPF{tOK;hDenvhsN6a@2gLh3v2V* zY#Z~1SCn6Me1$5KxetD%PFLx%rX z+kQOa;n6=0{k5co51;}eXt{c0YITNE?#hO{R9ZdSKgn(oUAE#yVs6B6;@SHvxR z#<>SHMyPs@d5m7$Mb;`3beRM*bFm*}56a)7P%St^(4zy5^7`>FouP*+j8Y>wlc8oD zr*%As`Cc4P!iD^({49^Fk*ck9K6mioMSIsZI_g)bB0u%uOv8w?;?{&yTn6DCtU>1} z3eGC+j6dW=CT8|z5S6kwAX;91lWhIig7z>nW=DIOWj%7W_pCa8Fb=sks|X>AVPX3b zMf3$jj-WESakK7em68V7?!$EIu~mW+?U- z$$$D-$CGS*QnkCDld`bgB5zd*D}5crKxTEB=yl-@s>lz*2+COffv9XS1Qk=k+!YGt*h`b#vgO$jBoD6=fpd!s2itM-tu3i+Z5QR|MclyR+3MJq6Cml9h^ zQYFfA08}TK?8nXsdGxrs%jweK!$tnJ|Kf)+f40-tF;oxu#e1bfnmN0m+UR5Z%KF=Y z*`5^c+|XlM_cN?05YYu_OLog@OF!V3ou7Lf*tf>@@W{7JbzfZ_hRTAzv75q21!t%GF530!AB=bkd15=eZgreu!J`82Mh)c61 zYK=A3SiyCYj31;7*;fJ-_U7ex2~Jg5zw>zm7H=0&_hP5vr6S!|stnn0!6D02e^t7> zOcM3zed7d~tOgyNLwCF9TEno{#o0Vn@{GR4@(CAQlp6T`nV^i*rBb}>9-84Kj5UZ zJrfU3GW`Ny*F9UeGhDc&XFlJ3-^^DEA#CyBttIVUu3@QnG@S~5dHLTGQbW+O7?>z; zw#`HVk&DEn)U<8~YUI@`m3I}L7XSap*g7{i_XKd#b`>8Xcmf)|8vT*jo!&e7PvxC7 z({1tviH?pA<1DLnaf!Jp6?(WrS;dM@<$TjsHxJ3HPE~8`W0E5EP0%jqHNfxNR}+8l z9N4{NUu}}9PH;0n5fk{tb6Awv0JJ4lW)E*h4xQS1?X!x7!@`mhl*=)}pD3>%d5e|J z6U{TA0rs@zPz<5}M#@h`YRq9{=4wc?Yv)$$g?ZS35$(?9!!f{m&kRPT1&sBJmCKj! zUo%X!D8}ljF%go+_FjRjm^nB&EY8i%^)+f+*K~Kk^RG57VnvDtp{iESpR0XO_J#WL z`r|^Y(IPoVx_F_fsVN6FTr}pIw^~P9s!>}`JEd{znz#J;Nw8Qsy@AfsHeV5E0#vV4 zT3VV*_can)qDzDBt4w-{d!8b-?k?xV0MjbsIhJLmMzuOdct1cka*%U$bo^_d#U>2T zmN-IJsrp@NtnMmb(JXYAGsk+BGv<2u-@kunR_xD$`HD;L5{G^aEn5Lt*N{m8AP(l3 ztlnJ$up~ulVEV!t7#Jw4pg>$q45miND9NWr$X5(gE*H&L1P+;RwJ`wS*3inz>W9Ql zZMb-$0ic0-rzj@yDn`x#^u@28z>vz#S4Cx(Yrx3fgdr8MJIVl#_mRc}e-kBLEZnL) zSXCMK_X0@&KN#0*(T%MfwVl-g2H9SlDCGWhkzV}o=3ATk<%vff*Atn|X43_(A${8d zv|l5s0G~ZdDk@w;!eT}0EzU0^#tC+ue}Vh`0NiB7(eD%aT21oYNl3)Nj&)&Sp(`dr z@G%b$&-<+Nx@*dq3Gd{pt=58s*Jk&7@*pGtks)nyb=6be)D%LqySr;T8I=nVixGmM z8nx-;?!m5-QKF;(*~)5_k|?&Y0uY!6%Tgu+4kY*Ta&oVvsblL$?i)(ej^yZ%peps} z`19vX{kty*e-IgEe{0q6X8~&YZm@bKVw27KfASp=1*p31=sR$EkRk$DYU-R7c+wf4K>qkDN1Fd2R;tj z??*>Re_GVT{4``=LwB6m0gUl;64%{!qaowjJokxudU{mSH0~$0L;qoX0JQEv)2UV| zAWM$f-I{kk!o$aJeQjF(ZBex^6?V`j&r4KVTN@8Bu)xQ_8#$(2?sN*Eboao={J@B~ zo4WW#yGnfw7!KLf>_s!mz&Qati4qSF5B}Ausf+U3+S%jd}W`1rg3u3lbVu0_aL4bCP)2-d7I{FvK%k;q)|m;KfA zD=|$kqH&wOpa;5nh_E)m2L;xVbe>jsmo9_Bj{Am(-Xi4Vy=RUq@bWBntUavxJfD`I zot;gxv$N}`$(LqQQBk=cm6y6b9hRo&sQl<51i=RaJv$1=;in!3rkCqta!!hl}hER7re0!tyw^zf$U{*JU>qQf*JMNZZLr9 zBqBXMy<@ZW>Y!`aHK9%0Ati8S-}igpSn~|4^)_c0GzS8zxKQ+fR!7Ly!)|Q7={03} z=g>)fEt z_x)`U8J``993|#E?nEgjKQkyzvz@<=VKa(5>qXhYu;2-ygrYesk$(Iq9%5fH@4+)c zCbuK0Snzq~@aE)0miu^5iZbxPS_uMUtcPX*Jao|cvjMPfPDMmStTsB*FE1~bt4tfU z0UIXZ1IAJrA={zE`=tVppD#6$DpiZrzZ1T0`5+P-1d#RKT?T_`51leB8Y6Z&mzrK> z)YSAAohQM^4d*w!=PWsp^+$)T-L^9x!l6eSYE0=(@B4MH+e(8y0L*<0#LQnu6sfv@ z06Y4=x7TNYy<5K;;lwScp@D7ic9nX0)!K)A>I+BwnUi0Wzl#cW+DuloP|0ewM7`3w zLcNkWZ{u2gwjrp*TpDfV;w}35>rUUC< z7ZL+cc)7#<`u8k5QeaHXm%EeYKIBC`31PH%dSaa&E_4dK=m;}b;M)NDXM&-0d%=gU z_m1nDq5h9jG@hUP-xf|cIx|H=zl?L|IJC-^t7c@Y>NHtxCt~YM%6Q_(9B*+lbU~CB zLlK4hoig&Na^1dWrKb|d%yPLh08uaBA9^OyEyUa+`Yd{RH<#W0JjZjd4-8|ySrvc zr&JXYp@73;@KgzZ)G(#@nE#`zXtlf01M63ovJb#8wCu+4xLt))g;joEL1QtXM!0mM z6;>+4a+s6;^x^PPQihZ++%}`c0tXgYAdnjc7~~HIEAW!i?mm3Ixa&1Pp{w1;Em4Kz zCLtrBdf?v%MCWXI7GB=JZHwJR+H5kPY8LI9q&8+`!4wi zXlmmzb}3NolSNbe>#C|8wq`#I}Qi$d;Q* zgQ^C23lph2%W2Zv70c>9U_Ap&)1o9}X59ZCXV+tuEn1A2qB9}tL54Ufkpw;-rE2}O zT5%5Q)ulIzhBN{Bz!R-vBC4p)3aFVbS=z*<64K_+S_^R}Qy!&Yoc}z9M7-Lhf^FdS z!{B*QhE}f2HXU_5AU~7xGKDoU9f@T2-_5K-X?uI-;i36LwZY_6z6dJ^yO9DUMtk~G z0{b_xg(U7lrHJR))&d2Ki3;(oU)iysrjMjA=XUlRJrKuM% zU1itMwg2S%o?ML@Gh|;J3L*ST742Gdn7$ZU0Ao=CqW)VkU%BMiM;~Rg$v;a9FDA*m zxo1c%T+tb*%P=(8>#t>dCSCUArmUo@re?3l0hdKv+_6iMritg@fBDGcdiHP4anj_S zB{M=wikeIjOOc>QcxrWZEQ`w#U?W+rG<+r_08VBT7wa*gnzc?Q%aGW6qxYR3tcocI|0D75D*>aDqX*4iv%iAvW>>c3 zBwwmOeWvMSP@xjVbb@%KD3JIqH3eI1X*Tvj5w-m^OoN>^LmIdpj*TLD?c24;ClX#{ z3;IBYzW;FF9qYh4cyR%rub9@<^yN;#i4kSP6UBr$$}UK|ik+nwM1Uq7mhQFUm*nu# z-)j@Gm+aG;MwPk-UP$l5!vkQGIn?nVH1WUu63Kd#eT)h{mUhI6_778;DlKOdp%;jJ zJ4O8IX`kg`jvb-UA0wXu(W5Aloea&$x~d49p`TT*2u4il2U4JFMf^g_*Dt&d0w`78 zD3i|i6iMDiHaG=2Dx*>~lj>@>xP44HE_(L~9%r|~&VtU0n{XSBvvM4l)3IJfcr;kw zyNXB{l`MK@ie&%;gpXU7L&QT>>Yr)9hwp=uM57$aS@Dr3wd&$ZO7=ZQnG^>i28`&m zI?_glh)fsP?_s3J{ZkmoqQ`NznSzD=PcBeL_CZDGDkGo^Zz;I|igYx|B;l~wj_9kRTmuhg!k}eL=&SmO8{c(saCC`0m zoWh_J;(dY2(vd>&%Su&W`@BTI zja`y#-dB73r~d{{dI@MYTFgJg!NCzHD(fR>x%MG*T=>4dOj?3SG*S{maQPim=!YEi zB7#YC&OatdT4szs^vl{jUK}xC%FdFbf7wl6}~uXFdWjzIDw zRXPh#(gN_rABG$Yj^kr!IHd}%^A|uNOys3VA<*37F z{tPe?P#KD#_g2+=UTK#&rok!AHV>>e8-m+-7^pth!yJ~>1=Wb!(i|hBMFw$LxQpi} znq=vJ4qP{qm}+Vt{V4_UiHwW1d+*|s+h7DQy!nBO0>uCZg7NVTT0UcY7K}O~E&EwG z-I>3)53wQpTZ&B|iddQIXz%EArh)_(on|Xg{{;NRVP$8X1~7_qOl9(N{-_6+oZu3B zyNhp$iHS&7s|YD#t-9htg+W+CE(agLzjhyn>tc!jGGc9!&+)RekeuEPmLr4 z<)vA|o)T0u_cW=rfc0`jF?xzMF~b!+2nFhsoYIopWVU8Xu!&ZX7aUEz39&+ex~pJ2 zpt^eyj?Ro^XfsIGV5g_yFVzL&3QZqJu$Uq)gF@l1}v6vbCxuy5(EX z{=4Q!hlSl~wf>l3KJ zNdVHn=f#uDJ~z0+a)@B}Tw>V`!W0u)bT+ER*>iXVHVBUiM=rS+5rQd^9?P!Baa#aJ z=f$6yQidy3;B3PIA`M3k_;Wx~v3&T{ly@c{!zsEzW*?QpjxYe#NvjT6cBYyCr3`Yw z1Y*nQ&_1Awn^~Ice>+_rMnVQM@1;&tlx@+1u584+Qi#vZZWON_5B`~NTmTUG6sRLA z%<*y{*%0@Q*cj&kcRM?~4Is%|SbTqx*{U*le_DJzX7u^7D%~T2T9f812!#&SCejN{ zP$QVRs!$8s=Dgd6Bmb6Vli%+7C0`L9zDXX+zXW!`r9yqu)BV4bPK&|BLrpf>d_ODm zP+8=Rrr`%_e^vw&oYg;Oox5+aG5SG2Y0&JY0*Mq*v3<~WSvK+7X30&r`o!|g^U(h( z%lS=$re7PEfS~`H*K4z{$r32Q;&TZkG=*|REaBzF@$vAcoeBNnErNNucrO2;LCX-; zHf9qMnmD}kM+}gnOX93VjzZvdfC8iGIfYK^4?u0P=6_$F1c~H1z~masWZ0=70yDCz z^5mwwFMr#hzSrwqrCYa(J~4og4Ykzh#)Rhz2kfYIA(($TChw1_rYHAByno+Lod0_D z)f;+)hO^VdR+HwnLlw@YA&L<%{O8cB`x6p+ABxaEpy`8aHfV zQB?2yF$d`GM5LcCzo zS(kURx>`D6XAZM1i6wcetRjGsB4!tW8|RnO2vKKd?~w&5%FgnxUU$&5gb)1s`Th|5 z?xtO<*-_WroGM8kfEqws-I1W6=eFJO`Lhfv*UTfe^f$uU(w+`j>T}aq-?ifaW>DyBkGg>`I_-%;ln+CeI5k zcz`#+i{?^9iW@Sq`>(kR-|?J}RVK9tAO3&>rs4Y(Mqt+-?M31#5V~v*L`i=d)tard zSoVHPU`|tXHdP$~Nrs33r3Wk=T>LckA3kli=KQMv5L53Xr86r@MQx7wV&TfyUIuDv zXh2)D$@-byaOd$$+Vu2v;_l^x34kANv|POVOtP@%Fh=inBSM^E7HB7~LPq$C*ux|= z8_vNlLNl2Vr_lEK4`muH=@u*WaSH86wo^6!DVi;o{+gMxupir18`wvw~`v zL5e^aGtEs68 z=TD_KS#SRRVPWNa-g(dda#Jdxx3amp*=aO@0PcSCn0UVkW!X05m3Tyk6vA_k40@IS zpB8`tiar|k^CzzgkxX-eM+MyMv_a>!JWO3BB{g6s{W-X=-v|xZGVGgm853oN8e=n3_vt&(=U|r8YuXy|80s)Cu*v@Qm6L$2xBWV-<$6 z#G+W}a%zFQzZON(VDm#@OIUCzDJj!%a0eQ!nP+EPz+)5M&mgM#-@%1+I<-)0^MC_6 zoq-QQA^w@+@p?DN6hRB^-NWEW>fE^6794xVr^Dhc3Yiz+EUXyYG~ zh#i{Rz0~4gmJI=DA;+97`J6e&%#E&$!Ma}-oky?``jzF#F@9L6V5mCGO6F+q|;z~1$vhU5cn;hbYw4OZUR z!5o{bM<@)8L|FwnrSgRfJ`@9369SfLV7n}Zo1qM3G!pA}H#Wr|6Ukj3 |wHGJjO;b{ax(Je`1OL^g-P*juzh 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

    _S=3JfO~dHth$)&6$nu=<2lqY-O0 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

    65d>J44U!;YMA(`LRRred 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 literal 0 HcmV?d00001 diff --git a/data/gfx/bmr-green.png b/data/gfx/bmr-green.png new file mode 100644 index 0000000000000000000000000000000000000000..b9eeda376c2362014af8fb5826494e4ccdf58795 GIT binary patch literal 31832 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 XOKLh)Xx%yt00000NkvXXu0mjfXP(|B literal 0 HcmV?d00001 diff --git a/data/gfx/bmr-pink.png b/data/gfx/bmr-pink.png new file mode 100644 index 0000000000000000000000000000000000000000..5f4ddc89bbdcaf1a2ba5dc29f4c6c3b3ce4c6a14 GIT binary patch literal 31023 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 literal 0 HcmV?d00001 diff --git a/data/gfx/boltexpl.png b/data/gfx/boltexpl.png new file mode 100644 index 0000000000000000000000000000000000000000..2ec4a06130c38a91036985aae04fc411566eeafe GIT binary patch literal 9380 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 Y3UvujuPG%MBme*a07*qoM6N<$f}?4HYXATM literal 0 HcmV?d00001 diff --git a/data/gfx/bombdeto.png b/data/gfx/bombdeto.png new file mode 100644 index 0000000000000000000000000000000000000000..bb97382a5dc5bb14b8809b6354d711586540a07e GIT binary patch literal 12255 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

    nLv`?EiRdxV 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 literal 0 HcmV?d00001 diff --git a/data/gfx/brushes.png b/data/gfx/brushes.png new file mode 100644 index 0000000000000000000000000000000000000000..92497e927ce4566e8e35c1402e82ab4122541bc0 GIT binary patch literal 234 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 literal 0 HcmV?d00001 diff --git a/data/gfx/counterfont.png b/data/gfx/counterfont.png new file mode 100644 index 0000000000000000000000000000000000000000..ddb3571c1eb8c274878bd5afd4dc310c065bf5fd GIT binary patch literal 48362 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 W2MQEd&bkl)000059w% literal 0 HcmV?d00001 diff --git a/data/gfx/crosshair.png b/data/gfx/crosshair.png new file mode 100644 index 0000000000000000000000000000000000000000..2a1ab1f1d533c6aa157aae171ff0da7e577fe5f3 GIT binary patch literal 484 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 IM6N<$f@ZZV=l}o! literal 0 HcmV?d00001 diff --git a/data/gfx/explo1e.png b/data/gfx/explo1e.png new file mode 100644 index 0000000000000000000000000000000000000000..9e68a5e82d5cc45b585a0e9e7a82bf6bd3a80d8d GIT binary patch literal 15883 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 literal 0 HcmV?d00001 diff --git a/data/gfx/explo5e.png b/data/gfx/explo5e.png new file mode 100644 index 0000000000000000000000000000000000000000..835a6fae8fd35585c1577b3f41b6b9359fcb3422 GIT binary patch literal 43771 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
  • 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¨ZggKIP>6}M$O0RsjNbyixnbq= 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 K+EtoPQU3=zqA)1{ literal 0 HcmV?d00001 diff --git a/data/gfx/missile.png b/data/gfx/missile.png new file mode 100644 index 0000000000000000000000000000000000000000..3fd11b7ae19bc76ef138ec217bc1b45e1f5000d5 GIT binary patch literal 22199 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 literal 0 HcmV?d00001 diff --git a/data/gfx/missile2.png b/data/gfx/missile2.png new file mode 100644 index 0000000000000000000000000000000000000000..059a3c87012c013ae322b6dbd9d0e6e75c0a4fef GIT binary patch literal 24933 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 literal 0 HcmV?d00001 diff --git a/data/gfx/missile3.png b/data/gfx/missile3.png new file mode 100644 index 0000000000000000000000000000000000000000..c5c5fe99ec24a402342ddb9e244e0ed78fa7e0ee GIT binary patch literal 24296 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 be`xqW;B~P$$Ol)800000NkvXXu0mjf*X``6 literal 0 HcmV?d00001 diff --git a/data/gfx/noise.png b/data/gfx/noise.png new file mode 100644 index 0000000000000000000000000000000000000000..6ac8e27bd907eef6d694d6ed5b57c15c8cb99aca GIT binary patch literal 8886 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

    fIti)GGOJU#*)$P;Fl>>CPjt& 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

    2|2^~SFWP5rVv%!XWJE;z_Ta-M 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 literal 0 HcmV?d00001 diff --git a/data/gfx/rockexpl.png b/data/gfx/rockexpl.png new file mode 100644 index 0000000000000000000000000000000000000000..6a3cb93d1577adb6146956053d3de3639ac19314 GIT binary patch literal 24872 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 b?=AixKS7lwd^H>Q00000NkvXXu0mjf^QYys literal 0 HcmV?d00001 diff --git a/data/gfx/screen2.png b/data/gfx/screen2.png new file mode 100644 index 0000000000000000000000000000000000000000..26599c3e26c1a9d1b7e8beeec5cc88280342493d GIT binary patch literal 89304 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

    FUpiKn*p)~^*YEMIg^ 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êj*gsCgYHxH(3sjjg*Kb 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 IM6N<$f(MAXiU0rr literal 0 HcmV?d00001 diff --git a/data/gfx/shinyrock.png b/data/gfx/shinyrock.png new file mode 100644 index 0000000000000000000000000000000000000000..bd3476ee5785b5b3ad539f404cea20ca360b471c GIT binary patch literal 35715 zcmV(_K-9m9P)PyA07*naRCwC#y=Rmi)zSC+>+X~D%$&(t(nzD6g_2PKflNkZlY=oi7;LaH8T-Lx z0|so2$Uz7pfrQACP|k4_CTMcbC+FVp2L*U|Ibn3yUF)uO-Jj0V=-;(>?f`v)3Kk{>cLd{fXdrWcY4A@ZFa6&WqCI6Ty3I zTd!zaQuStW_K7J;*efo2?bXw-c4$rn{j}WR?6~sUyT;_4m~@{aiWgt@=*$A;M9_nz zfYCGd)pO>gpD;(nG_iZDdaalvoH6G!X#;MC7%INp5`9_B7v*mInI|BBddu2<(Feo` z;b_bqI$*RU=6?14d*MamRMqxzhH1cf#W%Np^^VXxVzkeC0x2cw~kqDrcQ#DH$MI%cXp?_5PJb1v1&voo5VG zcf zrL;1h`D1Rh4rumHW<}3+ipI)v4wGTO>h7WeI1ypxDc<^FXuncQC)>!MchW@z>ARTC zV$Q5Kj%7AGXw=OA&5xI@4MefPm#$Yi&vT2PdcYkPaZZr z_SoyqOKJJtyaRNhAoP)&ttm$_!ouVH zezJZn|D=d?^3WE)GQpHOeJAoJ!>Y-}O$&p`ByF~8OIf;sKX7wEr=pO_r^J}3t-gA4 z>Na2=A28ZW4GP7qWFmFt{kMjs0T4iB@=wk~E=FZF0lfHud_(NQj2E4T6uRKx1!f}^ z;9(i-_>Kltq!F<_jM!=53p6Me>2dwv@(n4?{)>1WM<*XL9*Idb zqeC-Syp@xYl5``FavRzatV2sXG73Fu`Tx?7O>qFn@&+UQOl3bi$)t@ezRPiqN)fH& z&-?-X7W_1@iA)9)q$biHOA%krE9Amvda&>veaLh(Poozp6F_A1DiOmCU)FC$V} zIhF7_V?bdg+c1%ipL|?t8TV!wQnFo_axaE1Y&38fH+n{*rM=XZm(uV%_$wt4qmx`Z zSw|W!vJr+^a*6~HX8z9kNB&yER=Oyqnh09PaR#+o=k?=tNxbLNT#E+4NiQ0HgNa-` zjAtm)#I%B>=Jy%SLISA5Mh8ul(MvWC((T%_QwUxEK@KcrF&Q)yqn|-&C?TRmPKhKj zq(bIW?%${1OAQCe!+@JUqLh$fHg_~lwvKF<>eojjCxyyStQkWg+P}xNt8X`!1G55p#ln5Xkyug*m{D zW*oQ}gc05FK3&4u|2)@oG~l_5J@`0`hA+{whHezIWo8lvKhJND$=4C313lTK;pH6c zQqPPMZ4&G88WTX}Brc$rDqM`D7zb|VU>xf&N}|KlcnVWBlURiyhfcQPA_H)eR_q;{ z)cM@P`AGHD(nJ`QZd7!<&H;j%wvj1BPXC}3x@n^sFA?oHAnEB zJVY5)OvS?i9ON(&g>xy&OJY5)IVQi6cd^q$8X+ps(@2zz!FFSOe211larzPGRn9*A z2qyCl`|+dFz|ic86A}(U9?y^i^Vz{XM$kmZU;;}!F9*1M<*BZ2tVK_n+l2vBM4K_Y7WK6XWhf^j%;xcqMY%x zGn=K9aWy^UBQYt|*q?Ca{}3Z#6)j9;I;XIbahy&S{a6^r)#75;Hj!}Q{0t7LlbG-M+;GJ8eU6b83}!!mWK6gKLwV-tB=`$C<%r$fMJwCrL4!a~ zFFGtzV7A$skN`sFO75yu-exz8`Ibf8$je*^cqyZi9qi;VllqMdM~FDy^J?xv^D-l; zqLLx(MZ>??P6v}XOe?GLk+HRJRb2D=J8t^1Rj;y@&2(c#$0b;Z5hf7oe`RARt^zLO zVGQ7B7e|KC%v$zQij$Fe@sqLMwLXCY&*V1%1(Z<(tR&26-o%9o3sGKqY+LA z8wt?IM^vLHhJ=cCNb#V=7GMgGEV69iApNXlIZpn>=Ue~;coQcES}>}k{w)s0X~0|_ z@3*{!g+mGZC3C&7W{ZPAAiGaT537VintXj?G+6 zj25IrFTS=|{YC!g^Fl?|n}isQk9yX!o(MT);>AKI+v#JD;4|~ralP+zIN^G}=QjR_ zTDDS6I$9oNFVCVS#Mx2Po2&Zb;M4gBLm2bk;60WWH6A!Ok6Yqm&cmg66_t^i{%J)-=KwdmeEf)E^>%ajRg%>ZJH&) z#@nqwj>z8`%PPJnogN}s5k!dbK%qw)|Im#qIUb)pPbW3pz~kgoNj@%AB67?bmjFTz z-netpVVaptHWFL0)5k=rSj%K0+{qu2DUS?(Sy%td;fs1_?eIM`G7XuXgxOC3E9tnA z$l&*6axUN3+8$Zvj~D(##(&65XwWeR!Cp>b24lINI&R}Un$ff6Ky+DL^L<5d2Ed)f z7(@@_xs+_uxQQUA^8`)k@b+bXx?98z-!4UJ=2_PAAL@96dyz3xK_M!=l%ipAyK!e+ z`R6g`$nOWamtxAv=PA4lqnA1qGBIE}oKqJUe+lJb09yG2eVFJZjk~dtK_4m_RMuA! zNwD`=cI@Y28ZaPuojvTrNH<|}(4*JHw*bQq-ndfHGZqco5f~VQfi1W>mp`(MIdiA^F62N_WMZOg+8fxe#h@FoZgqtk>O)2#owOzk1 zvz0DJ(S(nE9A+$|uoL7jIJk!hLU`XZd=`)Y(eryUze2-c%&f=349tAR&1|L<7p(;O zyYRkm`!epi`GxkeZ?P0T4{$kObASh^!-;~2#aMZY93hr!9$y?sfy`=~-N9va)62J< z%5{L3-RvWmy%h2aPaw7$o?98ue$1{fZ)Yni+j#|82V}8}OilyB6wr!$mv&j)`8$fC z>*xS}U^M^WHa2ntlZc_xhY3A;Ox2Fnaq*@68tKUEzhE=(BJmGKQ%xGf(W9jk-Ck2= z90G)mFJ9Cw7o)I+R-#-%4K_N-qMs_vE8Hf7)URcl=Te_Opiz%I@~<`dR)3h*F#v;#KuxWT1=BEKi@?&EcB)+&N5;T|62 z8Gg(2yucq=MmYuqQ53)RueR2>1ei_kJ`SMg9sYqH7e!d;MMdT?BMDO!3jWLLi9>+Z zr_@a`5McxDSeQ>At(1^Q6u~u&pae~?=9W))#gpDWV`D}yX0&MN!bK?=lyDG1h(>H= zqwf`WEQ;g*Dx^bK?k_lu6(8-4VHB&FNI%`Y%vIFT%lZ7h$N$@v`+pgKKx(<7b=WR^ zTtfq`yhemgILN1gb9kDKT#d6e~QOXQf)6O$oMH#tN(8o?z z`y6*?uZ!3J-dT;)TX7ShiFBqh6S$pUlZBs?xt=gOG32enFW-%0Km0>DcMld|84=Dv z&m9;U%vF5GWhf}f=$D!neTH~-G5uN>w;=2LN>)T;3G^Sf^AG@ z3#U@bW;TU1e@)*Q4?ohf`@HWEj3g5qhnUQp%%h9**v7l8A(w^zoevhT*%AjINUy%G zS=z_NXlcRCVHAepq=reH!JU}U`SpLc?ujSgq-IzDCnS6ZK>;2`|koZDcHm(IR++FZho0IY2SzQo;G6 zVR`x!%YyOoo5LFeS#(mwVf1t}oIwcQW*e6?1smFJ_Qw_{kl&SdP_NR0hHN5Kk3oDq6guT}K(9#4O$l;P|%Od)5 zVM9v~)m+SQ&S5$C0k3dIKzYotEj~VIj})%s5PPWPFza}pODLk7^<2s|nAk6J*I1rg z8FvCaC#@d2k$N_mL-#*ReqjWTT7U=D1)n*u^D7`xgMl$@ zA%_As@D%xK@LTKe7xgFFfqWz|>kY%nHl>jsZsVVP%NcmE@-!c@P>p*`LtLhr*+U5Hb z<1u^wWZqAym`MX;}G$ z-}4Z+2M#{+<-tVw_hn(Np_67}q;rs|WC1le7>1h`GIv^DT=t6&?D*keEYxIfnyD&t z=trf74zg*(6b`5qtE(!>8U&Q&Y?ygTdljGCsS|_&` z2c!n_u`q!)G8oREV%Cob-?%U-{nA4VG? zQ_?pfCP@U*GM(G#;a0Zr8{Q8&AF_Y&k(wA^;H#Y~mGu$9f`vMYaMI3T-sfe$+9BWY zMRQ{Os9@`iNLeo`8Dt|UWh|2^Bf{PMR(<6Cea|#T5?Wws{e-%iTHL4v2+@q2J}lH? zVifa&Rd;=|vp{4{1C0t@Dj(&$CMs zCSs&<9^cS>sOgFoyOQI##{6rfpnqh{?4gG$mg3_qin%k`_k{ZV$4PJE?F)xD=_W+; zgpx@ePUdqG9gJWCJL-Iwt*lIj-xwLUDQ#9ywj#M`AcJC5E@C|8sI1)Z_01dl65}5g zhYl!bThpUbfG88`AfI~1;o@RynEj3B$>otG1b|4SxTJ%pZnm}7Uth9mdrJ67ShpcoEtPrFjG70@riKeyt$z4g=3keDQo)D% zvsd^$vD|ihM48Jl)-jsttncc*HMA}T22#~uwy`HoE<`6JnfBI4G|LcB8Z*O>Q;~2#mP(q=Tf7o-){w)K` zrfUketm`cZlzKEFHSdt;e%nXy#Rh^8M>Ez(96LtYG-34q^)K~4_&@H{(SIe>Cx0cW z#gl)f^HZa04;rr%KfIZ84?@CGnYXB~&Of!&(n|@>$ks2L?^xvL2f8bk%nQn*sp2R^8>?l2fdUr7!oqkg;d6Ixu{`qMc~IU7Tq% z&F*DwLYH|1UgqB#Bl34>ED5>*qxujh#4twpkb~{a>8$8>Sfyc5}$$`sf7v zFiw}AXHm7iOS~tBA0g{AGKbg|>$ZiV6V!k{GDe$0)s3yc3G(0Pzt4Z4|2`-B2w7w= zpS5g=e1guROII|Eu)_?0Gp?_m7DbZpb(GwA|zQ(i#~MK98$*OrKcX zlD$D~S#i;Qi~9zIHgZ+xrPhqjtS)^;ef{6W5=lLw+1G0p4@EkA)rZ70;#+aaPD{}M zXTX{L2Sn_E__ugj{403lU(Ov+X$es-*0@7mVvD$4JgzRQ9yM}cN)WHQd}YutpwG+piJbLKR}GSScQfy}I$@f%SciIM}LI2)9@y{wmJzdHRmW1|r=gz7^3` zqC)Hzi^Uz$vlo3;JRs?ph)}=yM642DhzG^ow(A$XoIrZ~!`*51!W-;OFBK-(wq*Fc7ln&{&*oO0jP)i(=i0Mf6dJSyopOq4E$r3dcr9y9>y zWlTlMM@tn@uh=j8^r?qac0(eYThJM?pkoU~gme1;xn|^m2_W=5$W;?8z=RbFor=txmS~8J|N(EQkHYsK4MO**|BDl%GjsuFfUGt8dvH^bt ziw84ZxX58BSyJDr>xQM=_TMoBRLTg@O(Em4WI3*kU!3NblS4J!!JX*fb6Uuxhk6VI zb;r7S)0huNtGgC^#qfJ`bJ#2$|c+Y-JdrB^N7RLg>-V@J>lddIs|WVq}qn78_>T@z`Ix zA}=*FUM`sdT7WXZfQk|I{4J@Kh#JZ$03Bv>DL}?b5iVQWQ`1XQCV)uiNu1D06Cpwz zW(!6_jHYg!DU~@`%pcI1i4j0WqMt9YkVcpMSZWn^=5Y!*u+m2p7CP8P9|Ga9r)I=2 zYPQ+QpaAGZi;lze5`~kZsmvlPzk*SKlMH&X;GvTc4r{|1=2YTS<&L3MzgSqGJn^SINp} z-jN^Q(n&9S2;)T|LXkF_N|nGtlpUKY2dShL9d3ezQPMQ2#Nv6Fj~HNZ&_^p8JOmNQ z1%?#LQ<+OmItX&?23aOD2HZr^PEwK+NTbU<@}q}-U=lXc0SVd6S+?W^5^fqevh25@ z!$1@x&6v@Q6qlTvyiA>~texMK+q}WhC>XXL3}{@1vuE7&Tac zHjL<|Y6mCn!W51cQOO~SpC}zf38JT$*knsmFCL!D@p*nZ{n!X2P|;$QQi>t-(7};Y z94+HeiQ>nH1Zf&aa{Cu4^J_p)Ge@pLO`-<{8G%wJB{kwflRpOnKpxFNHsHsC1Sn^c z+zEti(SoCc>O>+BK{wnpR7}>dzvSj$ZA(I=7K#*fciAGFB zP|z0Zl3TD|`i{|jGF_a41(<~qEurF2QE~!|rRYaz=tiX<3!P|@sV73H*pPS@lrZbq z&tU`r4{2D@k&cFt(mGp8>;%#{9_#+>Uo15fE6~P& zEDXYgAczi|$(%S4o5@d<6e5Pe0AvvcBq+2ej>J#@u|UEOa_K-vHBBtQjE12mF)@h( z9E|y29+_SgV&u|F0A-RsSs1DGl_4Feuyf=o;8_f4G0-XxOX|Sp(jJ9I;KzA#kekUS zo84q3tq^92>^gkR6B&UJP{^fdNJBwP7@UN_OJejKIWl>jjmY#70}ddFAfwK9MOT6Aq=66UNp!UnGiNb6V9Js9lK((7Py3FZbwfwcKVT!QQL_m*@Qjb#3#9! zjf}=kJ0Bq-@JLGLsKhE5>i>zE-;NC*dCX@uUUVpSZL+nvwzB}>#|+qgtfLqW7V@Y} zTBT1Cd&3o?|0fn;9bU@NUolM{n>#-eZ!m(hU^Ba%)^ zb}XG88s>sybspFU7%4-gpN|P8-N^DwqwS+4J0BkR;NJq@(}kNfu6HI6L2_NF5T+Ir z{p9dEhbUn#0v&<|xFD=Ytzf+rZA4Ej-0z83?P z;61)3o3%$WjEE9NKIk}!^~NO#4`im!15F zUFh)=A&o*L?9^nE^gPrQ`$Bw4BRZ-%%xYSR;Uf(lQ95-qha|)AY1`P!ok(Etkl3`WO(To~v?!GwfKZYv#@#0gdQg{$>+VZenRA67Ip z5g`qgOzc^j;XhwDA74Q2KXoTvXz`=agpLO=@-6eZ1Hl8#Bd6Q(%E|;DeEHBXwZrM9 z9tVOQn8=}zS9yv(VRV0Vc}9tG-IKI!xS?HKO2w;qpkQN;Q&-P zR9zZB(1D3CJ#?bQ$}m=NGYiootHvY)SX<+v29+S&@Y8|@2Wf1@#z981-JcBa5Ow~% zqsLecq+v%#2M4hc;$2Qs?oYat+36xU#&(GPNVMZ63k^m*45x<-hRi51RVKV_erohU zU4&jDXz^hrNB|#R%JHBjN82`=Z-1EpQ|gKu*az4N(a3O?pygVkn25BTqF$#DBq2c5Z}rw?b>b&XEec+|G*F6!jTlnq zgd``L8Dh)#p_{c*5ItRV(?*CkH25&ni=Du)?7E8ZFSvki>kmo=b=1;I8->7rirI+5 zIfRH%yVvyErwQhN6;-whworqMHac*SjY^RHJc*f7dP4fQzf9;t|D^F~cGFA?-5jC{ z1G!8kN*B|xBO~o_RwVI%fu86=Jk;aGLpd$@S;j$br=KtBiE2Lmcai}#SQ;fG2iQ$J zqsYcc5F70{2=FM^wI|(2R_3I&(#rw*kqGcx(%D1~Av|<(KrK$1tkUMauwxS|*~xC8 zlf4x17KK0r8NJk-bRFT|5$W%vm%~Ic5<_JIXEBW|N(d9x7K&et0e19vi+#Az6Qi2_ z)H4nfWjxROWHK+B{(5%8ByWW#M;rTb&`Bj84&!Dlx$NR>>bZ-WL&~>F4npXrju0OF zMDVZ`H-1#kp$H2tvEZUrNj$h?aJ{~Z9yCO8)5KtWbW_SUPN5Wy+gP7Wc{7V7`shN? z%{qeQaRyZ^z()hK`M4(eacq`R%W8UPW(1QN$8-jB8WuE|5S zJ9WT$Y$d=XG|XUiz44O|MB)Xw(c?x(1S>&;NX)=NITy2=*%S+PeSVV5%?6m*B#snUv3fpd7(mDs-?4z1G26H|6 zOs1YQS}3U7Mq*?NzuvSW*(MO1yNW_RC=A0yfEu2lnTG~HmAkU3(DBmxvs$#$Cj^-tWGw9dzU9Yv+@j!akJOxh863Gg5RrgDh7 z`U4NwCoMIh^m&K1lsjaZ4*Uc-z$UCTFrTfIeKX`go0IzRaHCq@HBv8GSwlI`qM?fl zw2b55YX8%3>`p#>_QnlaJ>vt49Y2ft4l@#y*vQw!+H+pnokF#ifVVPQH9M#sMgc2X z$1e2Dr;1mE@=4y}gX%9503tnOzG8Kt+td}%{l+#^-ikoSw}Nff+n04D7wZX(Ti!4>R97xlhodGS!v z{Fa5W&wkJxl4HKKb~P-biXzEWQ_DD(2Alq>TX{I??5PT8exK1F(Mt|ht;45ij~;?e zWp$11me*R6YoR6*TB~ZZa{NYFR3Ky(D{lZAb=x;1p4gT`w(k!yzES%~aCK~jm27{)&|JSk6 zhBBQ#(wM$I`fT>LREtealg`UtQEpBPWrWWNPBv!-V&=WNZ?ax}uRYZkjFJsmmXVT8 zniw3bjx=N&JeoDi;sPI;#@T%2CuAF7_Lj<*`6gUag6f4%vCMKN&}6_e#i zrfsZFPTM!7`wu6Sqdr1sF4d09=+^8NJ0>!C)M18D!{A+atN&3=jMblVsVU zpJXYLw^^%v!R05A>pw>uvRX%JGIiUe_D{nnqJ>$8P_}ufKE{q5&%zVX!YNWrC$f~1 zj80wM`zO=_m}!jUIxXof-rlAE{d)R;pZ`AppMQiRH1C~o<(6(mWC+W$l)q8@i-Lr~ zZ#EgR6Ij`JW^}+E(2$9hjNQ_>$^`>9J3^uuCps*6*(Z4hEZxZX_5!md(3e#~oiy;) z4`CJs$ibb4t&Q!)18u#+X`I*KcSgFmeE-e$18=>KYb!6wQx4X2E^YnccPD~>n9Dv1 zDhImXimtxJcOv|g#3^EV)8U@>UibF)JD<$94G`}XFSIvp>=Pjo6g$N!OXPt`51rjp zRUKF!YK`vo*DV%B1C*{8{}4X6x>W3rZRzmdSUk|ry%&hBLTwiN#p-Cs{@YI(u=Xa1 zRv~J{B5^46;AgiM4H$pA@H{P+i~Ge>p+9_ZSI&U(XA5_=ctD&l&JW)4{zJtlLI9`O zDTGUG6IJ4UaZm7$cSY6!(6YEwgoRilJ{Mn!r^LNAXU-Uq^j!bidLhJjVu=vqHr2mS zSO#P~FBNVfglHCx;wAB6*OXJQ9LUG&?cz-l6G8|f9u*IWn=7s>A5iPd#cCmhct@-g z4~x5FSAQ`hYd}+Px~LGsFTNK~i$}#Ju}eOll0LwxTOq^-ag(@5+%7JNo&EipNiV|x z?2@5y@E6WTZlsA25Yem|v%;IVzAi;m_{fDkg#}_9AV?97>1}g!zisSFu?rb2?)p`s z1cTVb8Wid4(XSYEKXk@YQvesR@W@xYY^*@TA(QFk+HH*~E@ERQ>D3=UnA?O(D64&f z_J@uX>vM>FK05Nv&#}}HAuM$d2@E%`=}NIy*dr78h@qfGOARr!QqzdYDC?%K6id}T zGL3ikm;Dn#I%Wh~DO?gAoxh_vZY`sm>t&L0V zV@z~9Q6eZ)jjxPO>2vezC2slgO6vq%n6XRp8M+rvN~!n47=Dz}_gM%;2;;y>z9gLy zd9l=y65heH!QvfwkJfq4M#dtk^E|JN$`}X%j^^bIA%>q_bTNu>PTv!wQc?oWV`&*> zlyfoVG*FD~+{y>0=u(-%y(2h&Z`n*CQDWp9HP3E1dr&IAyo}>p?S2aB#(;s|QQp^2 z8kCa#xR{>|)hZP9Opq<}GM+g(h2GDwaoKid1xLQ=v;>7J{G`d!h2f`Xr9y$zb@MxD z!ozcHpp7p4WRNQv&WOA?Ju`*Y-`F+vZt4&;;${b($n;~Dbf^1X&CX1n0LOin0|}XS zoD4#p9lpn&$}BYSlWW)c)G?BN#%ZJ*BePRL+tW`+avh(6eHgLQ!GsLc3&T^1BucPp zd5sz%N+Va$f`X6S$px>@PackGnF;VIZ?lzZI>|<5H=R=WO4Dm6C-tRGb13R0!VlcS zGc@BPpERtb$=++#7iVQAT{&IUqj{bxT5z+A0BwZPlSiqny*%*hZ<5^x&aS`8B2A(h z1AQMNOmGscTV6w=>qsR+P&ks$q8Y&#_S3DE|D&6$cgNh&x8!=7qh9#V{vt5+Xj)Z>S!mFp;K9kT3AWoT$!v(1Ua+u) zMJxp-k%@|y8q%;#?71f=iTn>b_NvwNF_aB_gM;>0aRCa>i9+cw%sW-@d)Q zz+hrTSwa(OfDb=1S#rsZoSYaxwZ`q;hZ!$64kF{hh=dJ4-3-zc-;(j`MCdPjw(Q-G zLOO@A5g>zpJcP+39XG0+d3oXWMF}F2(pH_=OFeyrF_Mmh2;FFjG6W}0vi+i*hcn~W zIosz8R=bGMj20saUqaTD9x8}(gwJTwra9~XWs=&>I8S~7a< za^F?4=L#)J2=Jny0e(2*kg;J!;J{8XY6X6*xbaa-gnT5Rkz(dL3;&j$a8=#a(9{v283h?HK04_q3kL=| z@G{L@{y#+tD0oI}+ZP98UVIeMhl396c<3TX4l!If47rb%oH;J;u0q!*zWuwX!;OrD zmO|190WrK36Q)aBaP!C;hsLpj=SG5`7-C_9$S9a;!;ByRD753HjCP&&7TX^O#i5Yg z+Pzkgg`X%fWI}WyVI&io2wt)gTKCna$A*}a!~pdbh-2|iE*ZF($#{OlC>&B`L8Krt z0m2>8T_J`Lp&G$H+RzdtibNY`$$IX0N$QIjSMBs3q5}uuM-U~C9Afm)L^Gw6wT~4g zppdCY{n{@S3^b$QA)Eb}a4?h}x@af2Ed9AL2_lJt&of%O2-8Q9K9r+b`4LPMQb#`~ zyY3lXTnb&;-||kcs-mZd0G+6$WBWhsooAF>)s^pmH{V;abGOvp${>_U0!ieIG1y?6 zWP>wKGiDsd#>Uwm8+!nI#yMb*F-d?7hztTm4g%#IJLm4Iu3R^s_n~V%sjI76?|pe| z%~?wy)NAc~Pu;W6KKtzb|L={CghT^1bTg{Qz7t&3T1JItJl?lWVSo`#0&)y6iwt#W zgeUeeU0TCe;x|n0j9=x&|I+P@U{WN8giQxBDs_ah@PHb8x%gS}53R;6r12 zC+$Fz1iQ)7i%$ca@xsY{QvO;ScXrL5!&d-B1ImBV<<@d^TuAZd&|H5BiWH_BrSu6NeUf>aV+u-;S(pq`0Tdq z*z376L9Nx9{yFJW457)M;eD#+`43&_Efq|dVKC^{PMoINtPTQ3Ne!S z6p)cn=)or*$}P`7lbtlMw83sKq%WycyU~$|FiHa<0#sZg_$Z7c^tMy8+s7w`re4** zZ%KM_lq~&((XdGn$4A0JAdrwqsphI|LVd?6uK;%yxU$eVMiV***pEVr)7efZJ_%`D zQ`b3DM&)i*Uix5M^@!2LFnN4>sHKh~VR9UpBW<>);1*oz^&R7`mU#mS2Nw^WA~O9L z#K?oyTdzOnlm$gxKiqMKIxk5S2bBV0!g!>Ka+rEt9HoCn`i)$f_8HFv^+%dM;6_{M zMxvP=v>~HVi;heO5+NzSAk!0Uo;)$XFd5UWb8NX8k33@-Si}gBkkRlNM8#;%)v8Yw zCjEwsx)W#mvuD#o8(E-;iGhMm4LKwtbQ2EA%d(HTlO%~Y_)9xdm#4z>=qE)jHbV$v z6bU1d2NZl9U0LBiWsjCsfRBntFL4*lV33)N&`XX{@;Es3a|op-_nb3j|Gm2O%8R>Z zwo+h(A`UP_4hxMeDF$@EPJ5*M0^ZAIiO|&pra>)5n%O~^E?|rz^`x-L&dP6f%C=y- z*Er zQGi>5?)mOnN$DK=IEY6Y8=o4Ibdy82D9qU~JVjpMv-Y`7L+2clESi8`64YQ5!eJ1| zkZWgaaSDRyMWbSowA{u;rj9;R<`0W2eM=`#1cfvvhiC%Q*c7peQmD(t^=BtP$o6LD`|?GO z9HWRymJAZLIHmd=3MqU7&7WmFT9{-4JD9sySw6n7UdoWipn#1;f*LF&2C)c}!IP|+ z#r4HWj*(sdynXr0#%e57#*nGUV;r4u$rDouV^ffVdD6yWUl|4XAy+gMudtK?FA$Ii z1OtSS8A1g~tEqXQdx|XcT24@ms}wCof*d}taw-SWaT%Xr%Bpf>)7oU&W8^9SY`f)h zPm2>~oJNM3PZu^h99kI0WxPq?~=G8VUb0rh#(K7agngm7?-sM|DjwN zib-t5HzKQ>RDp!UOvcdIOC3pSa8O7SmQwSj*NSCm>fyu56K2eJC7CRB2#UCb@hC7# z1Re14o0J{dos&ib+{W#N^Ua1>sWMm!m3opW1O$v>5+;Qa35GJSP9~opa}wg5jM;#W zKw_dEg@?dq0+Z`tPzb5E_LM!j0>GDK=R?BkK*!_|0*_k8IYNdo38=M?3{B|>UQXxL zweb{T93+OxFq<3+nn;nsL9S0fl^-ZC|Gtr)ch%2?Asmv#umFcqR9q5d@YR`0-Qz=L zROk)P?8%*1-Dwcs~cLp_^n-)0B;;3{GMW>b?Qbft2 zpp(ErHEdIT*qPK04iuDa&e`#%9C5~IA_2(c5u{PEa44cGL1WX})B>>6>u`E)pS3z(zx(ND+`xX=$nb%V435 z0$ggRFRz&~j)XvP7(pHngB%tv1vw_C*4k4X0%xW33*?o}bfOSJ;sA3PKqJW@P+);> zZy%eYOvK~GlVjlvVp4>D2C&KFk|hRokj6lv&{TMIyljH`jl$v)|B9Gu0UjPjG89n| zj3Wa&IW?l0YqMp3L$9-Rn{&AtH&Ag`Z^GD+6-NO9YYi~U#( z89|gZAz+v=0VAknaBybEHjZ{q8q&o*SUi-wFl;%52r){I267nK1mwvRqJUDD-&C0N zAT0)ByWXEYM=>?hXqZTVj)RYcOa={wbksU9xV4M|taWA`KX`JEI0bU_Av2243^HV> zVH8d8zss8f;$LnMjd;1MQAo$38CSr+TuG_Hx>^9)5L zhKocV4;PIzIsy$9VKr~S%UaYhIz;4*}b zhL6IClvy)#>SB}qeRt;rg#zs~ArmG_H!2zd0eNJ_nKB@CPci>bgM;H_Xd^_P1_p3( z@W_zBLLllFOp#i7Rt(&kePtg-#!&Iep zc<6si^2mf~#8^-)n;FUY#ou@S%ytVnc+4S13K3U$djgkL@faZGsdQp-{y7x&RJg& zT@>)BC5uNB4&%5uNSM^6rh@xr9q-2n9_uA6e!RWeKxc zhK$1^&hpN!$kHu#WpCZ(_y{7*Bt@1nLM&s9eq!_-c)J44>z+WlXY}Q61~G8yLZ=3c zS;VLz%>F`O#cs@x4(D#}Pi7g$Mn#Zk5RWbtJO+txYOK(cc$YtPd-ef>1Y0STnz9!O zfcfYY4_gN+&7k{G&y9XpmJ~Jv)Kg%X0xlU^u!eZEl6P* zO834}0j1eBl>dBY!?>_f7{^8>K@o>AwZxEif7_ix0j%MH^*ur`$OwI;=%UC+u#icz zeNWHEN|V1=6z;cQ8z4cJ5yGT-FAcoK4V*?gNI&vUMZEjd*}~WR`a1xd3>msf(MW)g z&WyL&Q5l=k`(po(28#m}86ty%ipo+Xe59oRyN4>$v)}|jPo`}Fi4U8 z&7)6Oe)&On)n4(g!?6Yi8K;Phgv)F6!T5}CY#puqg!(~wOg~@KGlUo;LX?_`>yYby z_315@<X5Z3Qjms0M9GMRir;~7C{IhvyHT}59GS@x3uf4FyQ_^S@QMe16q)_i` z`rh^`czUkjKn87TC_FA@7{g-`PqHQG{7dwkPgd2%u#ixnux3if%4z`xmzmU~h)uif zZ>{UENg=lK<#PrG(nF_@TTyi4DENSmFYG7GJ9btX9ori{~YP@96e9?$FCkQ3YOd5EKKJS0Q!qJzIyN_EhAcEQCW)S)u)V4H0;@0wR|y14laIN zeqL==+8Sij(f(Td>HGVc#u#&!ZC&z0LbNXway%RTbHhJA*t=yK^23bvEqEd+ne#(R zs3ZJ9`9#r4DZ(2>+KW}WCuPl|$)lTu_ z#v%PS_4Rer(#r*ndZ1g>TL`z(cY_$N1lp4es`W}k29p< zCGqPcL1<&-m9+(qVl1txUlm?JcWC3f%+biNQbWswrpEsGzB`VJB)(FK%}`t79WBY9 z|2OMf1##*;En^vVb@}Mn-9AS(Rx5ryqDKqsQyk?uO$}L5_o3p^%3mgBG%I+@PLAN><_(XgZbxhfjX{f}1& zlN#c?dY9#n^3^6Qa>4eFFD5nxM>loOr)K@;&O=}Dk8bfej|(>)+WA86@IM^g436W* z0kvn>#j|1L7iQ`KH!0 zYNu^W#7uESh@|+sxZ0ilWX-ZKOVj>_Kc3(?-z3hoS3ew^4oO{HEpj`>r^Wll=j;zY zbi=XJp8Q;KV4wJyI9FWYU%U0{^G=%XBhxNkDKlcR*P{V{vgg4v&Avlx!-Q7nWlVPye@Lt2_ZyM+$I)_HgW0;-yP0Iqz_;-myl9( zw!hXryIq==`M#Ri%REn#IC8l74f~GP`f1HzCCi||YdD0_XX?L^-V>e93}ntk+Rg3k z#wQ?{m-=~Z!L(+ujM)J9a}No8GH3qo>#&_f)9D~b4H0sT%G$ARv-)DOiVNU(FX8w5+rLAC7%B249I$QKrw9AYgOzLD zi73C~+6~$|_8_5>!NWr!jtyeQi*^+i`o6oIdk@ULnO8|*;UfV)N=Q2`*ik%O&GLQo zMENg?manoNn>-2*H3X8|D$iCQcdCj2e0MqD#QJ;o(TfLYgi#gmB(Z679Ha8Li_=Zk z)%zun0l>iHP2yPOC8<5V%y_<1`cz1Kj=x8~6%eG5@bT%UiA*?sj_B5R6)N1Jzk58t zc;0%D*GW?Z#z^2$z?0O)Zb*5>aVsj|U5Adjj{(NXq0)zoi%S6_!D{h}Gf?rf5ZN z5s55eBy21+$z32)+FOpOY=gL(_q-|nhyeop2?!4|5!0J%K9_;^gQii^2gQ5|wWWPOtd!uKz*wU&s)p zNCPq%Y?8RxxT^M9@OJa_=e|Y@VZtP^OF@zX z0TyA*Na%-F1#ie+^yLL#FYSI8nE)9b7Z;N-`uX~e^_4tNkEPoY%&PUmFho5r-&>3G4yK9AQ>Qwguo?)i;Vyb zB&0~_R_(0v^5gR3OFBss&`gd3E;2qYEdmDzxlff;u%$1N( zC=j3!MqQx(qJGLf{K%1yRbRmhJ$Cj3wcUh}QP4`%)DShK8R9eZwU0GOWfWj&e@o^FX|iN7NKZ6* zLq#TrPYP4EJ|u2$D!YUmI!7~Iq$nU5BtQ@+4`|e5QoxeT>y*#el{Moj+sQkmP$=Ny z!fs81fe=aUECK`qmzSKCs{HNPcw@V(UhzA6? zm~xS7K8Hh8|G&;2@Z2+Z;llX!_0s)vFF8qZ#KXh~!fax*6uDk)Dx&~WCtK>7*uyDo@}Ml@K1q32Pv0pNUW5%Z$IFWF`P;l-Rg35)NT}Yz$=FHPZX)%I@JsqT_|Y z0S^m-icLTq1%nzC6m+cPw5yJt(grM>nZhgeKG*Px;bRhG2?aJ2J63sLtu*N^;3a42 zVCu@08e@#01pe?asYfPOLn90V3RE;>G-5)e#$P*Z7&JXVe#z9N;lz?&6d zK*{%35y%rj4kS#38XU*tnX(D(4=+1>rJ_h^B?mOX!X=;$j~sCVB~x#%8!dY!J}nae z-cV~1gMa`91(jKJVDeEUdN36)=C8{-lLmrvFUik1j3eP;qGIAP#yBAiR7_MfRMY)x z@ZQN^?!IO`5{Mi*T%x2IL&7K(J28o%Ay5qEA1PBLBKn4Mza#`>WJ*SS;vA<`@gjnP zAJuL)+b5Ubn38`IDijf9naKK@6KaP_6d4E*iu5tgF8BF@wc1;1iAa%0Lr_G;$0(IP zbBGW+PkvuH`E#>PJ0(m4d|W2jg)%B>W^p+=G$P0gt?SC~-xU#4o9{&LXW<`Dt|0;O-kP-%}50 zD2yO5a1i*YXeh|&_(YKqi_NdKmhq+iM~V+90wg3?#KOLKi4n{f>0uPCNy?VsjI$8DCSC~8C zye}0GqaYzrN-m@U6saXo4i6{pZp-eTd;y!YgI5N%0s|8ll`wM{!$QzVh8QO?&RAXU z!AzMX^I~`Z<%Jn(Ol;0z9(!2MW)|`Z;&ic}A_21C-h42r0vz$p9^>k?j`Rhh%^1RVrlO=fI!2>N2Q2`Lx3uK$M{c728&J!ZHK&6 zUO3_TE10+l6r@rUDgYm0S+(j@*-68q(cwbQxIj{Z(#QAlQE^a^@Q_dtc#77nK9rmk z*mbCAb@=ZInE{0o4^RLF3@p6Tenu`fDi5V6l|M4B#>E+uEMwvV20l{B3sUho4v&H& zo9&MbPl`=Cms!=p#1aiq0QIRom5M)q@hHdrqCl5_x z1BUX}9_>7}W`Y&3l0y(dCXb9ok_ZKKj2hQgpPy_6^F?Kca;DKF@G2&aJ4lza#O+-1F=QxAiWKoRVc=&~k zm{bAMf&7M+mR64#ItnUDWa4<3xTP`!9xegS{LyvkN!f8`zjQ=BUxWh!G!%-Zigzi@ zQfMT=kfgcJefFeQSR0k!QO{QEJp?iZ6oL|HNhvvlI)SR56niQ)DYUw1Yg;+rYL@W` zknl_UR>Q}~n7CG|_L8Od_f3j;DhB!ie|4yB;`T8yU+@Uffq**JuuqjD^$$*7;$%#>r~Q@5`R#>5Xur5vijDDU_LHZVPx1s2+IbzF5Iga3 zo2(bc$^g?Fv!sG^WwVn-L|Mlb{F&34$pS2HR;65?bj(pz=4AG<0M{U)ZkXJQNeXMX zE2(Fx@-T05Awz7%qmylC;*HFv$lqn^eI`*!b6b5KqG?-xcEpD zDlt3v;OL}SGe=0f?X+tctPgQ(K4CATwrZ?PZjfKl4p<$*v|-`DlPRB z)YC(a;dl1GURD91&yT)VP@FY^qEjfvv!Q@o3Ulfxgz)YkEtB4~g|gy`7WGJHp&9BAlwp zUdjE^h>%A^!Na2&89$`1?-?m4AKn}^`zM%kfI}RERxBKR+Hpy-9~DzNc;B046v#o_ zBZvJ}rYxc3kYW)x^8`ueb0&Kk#FF#d`rj^hnJf6(>vnVW1f)g^_zd$7S0IyM4PW6I zk|aai*;lp=MZwm#xfcX=VN_B?=;R4@QRE2y*hpj~^Uz68?wt%0_P5-gW8cbyIg!T1 z!(o&F9k=8f3LGM8^Au>kq?`X&_r6e2#706;WE>BLA~rhX82F}`0&JFXoLke+NvPxz zNTo~UL~O0V<><`Qub84pMAG(tSbPX!l{^RG8)<9>?unmr1Qm_oJXR*ja%~JCm<4Fvz!=;S34zG zIg@h#A-~ZKq=~yL0tuN2d3=741i@od%8#VnuV$VXzD0mco_0>6hBPaQAc#{Zt5f0& zhDW^5r5|>EodSml_&v>hhU2-I6N%Bousl3vOg@=*Z!A3F3LBq3F5`ooh|Rz81?IAb zZUz!xoDyD=9r8X?c>8TWfyNe09_JovC~zrT2%{EHnDW=B17(AMb0(iA#3&IgJTfRa z?2kA+4p1~7*N zbE&m6ho+WKAF!`=@3A~^kulKmP&kGnX||GZ1}hLON4lKrigyS8#C0}9BUhl(#*b)1 z&{wc3pyfw~{Li@$1cAmF31qII9UY1J_{1>}G*;jYB!>Ji6koT+VpQ&;pW|7`3?v4T zi3oL9rOf`w;oRrOjy%Rpz`|fH9q0rTwF(ORDiG9?!n{}fWyH_ol14673N#TVoC8!; z02m!qZ;U+Qx^AhPw}(s~Sj0H))8UE~$Fbqy3)WqR?EnE14j}^ivFOCuYEz05J92taJV9Er^k+e$NQ5jRPxxk*m!7|c!V-dTgn82{>LuN)UTJf8q1Uh zq<}CA3d`_{J@>SK{jXJ!EYro-r_IgsGPy}e1}e4aEFva~@5Dd)L>29%Gj{Yj{hja% zr7tm)Mt!eFu-2!WVb)Cr{?e0S3%Jp%Qrol zPe)GGjX8|4j#tT0#Lt@>TW;H31#>Ey)HbFU8S`YxL&YJ96WC7B8UFs7Cts?F?{h@_ z2tC;|B4LFhMRXLeSX4$sPt|Q&5$MKW-m*iCw8z+#`+B4B_K6I#h`Be+- z+iNb3%R0E3TxQ(dSo5=WJFArrODoQ3xJ^HKucQ$jG&|jq(CgOPzjjtDA5!OiDEhsn zvv;8vq}`z%^vZ8Hzw*bbX|8Q8ksr2Qo3j+#IKbOv`SIug{z0>3f&ohrdQyf>^p>C_m z+%;{!;~GiKi=Su}*~0L{F4G<->ekZue0_`36LtSQ$;_+fth_%SiR6aY9mNzT#s{o= zxhemHqb69t-_V`={+FKpzvF+$|JzZ<0tlH#BER$x4F4j3bPpCLZ3EWM@xJ88vqvRA zkqYzI4;B+$`J0Yn?+f+0dFRjB+J9^EJtNm1Rb35Xaomu8DEVlrcl6$)Bda$sYasoc ze0V6G{@Ky|28AXOIpiPA{xR{;QI)sIXpz>vW+Igtd)K7jKrQp}FXhLn`XNu-dBeZG z{OJB^mqif~Zsqca&3vx&;F{kbSwA>^H9Co3v-sKI#gukr%WoSW9Py^R{Cw{Gn|9az zG~b{5c9--A?_5L z#7c2oq2Uj0)2tLAWbp;z3Na?uh;NJKg_>L1^l3h!O>7oIh;N7s#dYGi@fjaESDNMw zJ|&VuxZ*N#gZPw~HCS`nG-uE%)(KCDFN=?g_lwJd`nN)D)11Kv#1SC|#dpQ&;w-VC z82xEzTJ;V_>%}dikP`#qDzQeK8r1dFoI1_lutdBpd{2Bu+#s4ntXTiRod41Oa?&`! zcR$88NGoWihfy_Hsu$|sOiZKN#&?h9m(;4?oHW0sFrd7dn$9=4 zhuIL}Wg3}JyBb|0zovF)s-8jUYkUp;emaQL!)j?xEHhs`o3Gl6h(_+^w6~@EQ7KU1 zSXG-7=`nVV`xO*GG;s^90RPA~4l$~T74f%*s=hf3jqh+C63pjiHqb%VROkQnua8!J z`TN>=>dhi70fJ3zU>CVaDmnj^VNtd5{#AX6$mNq{E3ZJ4|IBFB1=_xQ2H%c`CQhPr z2^e9E+_fn2v|VL|zt5Q3Hy4~g;bF~ZF)gG>7`vCc>kCzu-mzLw{c%@Qnlo8WAFEl8 z#r|0X&7m?ar~do6S6X)Elb{RmqX}TAuAl z3Qq_zBz`5%5)GnF94k)int5Ec?&Fi+=L}i`(cz_}j1$1g<fKX8Z?eu-YFU`nwor7B&J)6@wY)k(Sp=V;&-0iWzo~;Uxda0@CJ8a6QzcLwub0U$5-KuW~JIC%az4M zfya1`7rC7rVFcp1puL(IY&qq?>MK|U9N-F`p^mM{m=rPR4OXE5Ypk{p4q6H)m%ih* zJWYZ)m!K#oRaLj?-S0l}V;9f^6akNKaW`}5CB*#p8)r|c04Fy*F?SEIlSD#8E|DvI zoT6d8Bya5wUnusxzMMxNDt5wtuyG89@v4lZJxtSAKg~kALsHcJ1b+wDCIf8mG zSQ9xBc#ZGT#97?QN@{7sBB*bxLID;X^V(V0vVcFbi`zJd>$#XBIW`j~5~?hp(uS^D z82SX)@H4h>kej)HTIwe%hM4a(P8kRAFYceakrxqY7=VSqBt$^X#kn)tQ1R`vHlJIh zzyk~uB~J*G0UBv!G|XA-uef|lX3=Z7tmG92h+^R2Vv$AAx3V@wMJH-Sy=M;aIJeNr z!vvTJMwo++W{4_O_^fDVUV=_^K295B_=Ff`4KsN|ajH-tS2=RxwLHys+R^zPVDl;_ z5o&O12g6kK;}ceNetnH+c8q^XmAVe);(zr(Wqq8cOTS_kLZJEbLOcbINDWWouF+NO# zBwuk-#RaI199WS-;gjUaA)`=Ffi=7r1%Fndu8IXXxV2T|Bal1Aq9ZRWF(MpD%4Zc}9i2xipk zbJ#;2Io7h5>j>j=5qBe@HAX6Kfw54X^%@H}od`Pr#$TvKr;S-;DEM;4OWYRCS#cuY zW*!Te!yMk^ucV1{A_w=kEJnS*QZ?wLXXmLJn` zjExVNw4kFRvjUUTxfB<3cI2E&*2h0jlHS2%5Q}$n8gYC^u=zRX;nce)RnlJX(rEoI z`dNg^65a=_z~?~{_$Y=`(FwDgYR}k6oY`!~A;RC&z%{Jo5yDtXsEVqCb;mYJaZW;| zkHxIwd(0upyEuy?vQoKjc_D@v$k^HlAQ+g4*r7fq%j1b-ICr1r3I|$gvVQLsblC+AYXK!kFW@$Tb zavY24<|#B_fLc~Cip-QC%71r4k6mmGl4b{eq!{A>3uz*ZijK(06_Z-~TDEH49K$ob z&VF3>(+3>lS#H!xTb5mZU_9@}xHc5xriba^^G@{W-2ODU|Mw6&`1jzG_o4JR6x_Fo# z#<&D{2c7SdM5j0awS@`un16?bp`Kyx+g@rhG3p{yD$qhPm>EVw=M^ko2DpYDe2>Qn zAutwdQ$*CQo%(Y!3L)y)$eZ-iMZljKp@!H5M|aJtDU5h3p}pb@7aJFyfFJM#L-<5d zP{|>M)G3o8*95(L3ciBI7%61N_yZ{vz{W*JG*jUo9ZGh)5JoOl2|dgR8a{b^q(DCM zPz5jWuxc6^RCH7vT)?J40#K1WZLG2a6r^tUVGss942m?8#l@rGR<1bg*EF{tL69U& z1i?sY9tm9Je6aC(F{J`@rM;hve1<+WKFKTmpZ3l)zRK!c`~PR$Q}*7O6EZN*Ad`TK zh_(V+oR7nCs8+4k)~Q-;J+<0aYsEUF#d)HlOd=>y5E+E1hztS3kU%DqkdQfh9-n8u zAF}(t=T)=!4(H4H(Dfl7^4r&MJh{G0?!iKgSVESjSMg9q zk4kG&Zy;L-_vpcdkcI~d53z(?r~QCq#}9=;0)wC1hWd zm%{oytjw32dPU0P1QN2v(S&%b9X-VyR9p48gei!k(5reELPJFcRAL#IrFP>=zM3=AT@nH7iD zrOZkk9G6;q<+&`_010ct3`14k%GAAAx#F^fJ)u#YfkXx}QDSkiNQBZd0PqH+N23S) zi93M^5XX;13_%Q=E>bMR;R@+FITj;^ny6acTl`!m42qtj0?q;9UZz#aiECg5g=m77 zF5|#zOI6cvWyJEnh{*`z*su`mbsveKA_pQV4`OVGG`)h+8U|Jb@g8d$bwBDW zB8EX1eiX8>V4z_jBgd?pQlo9c+Cb7i+8$-hYOhZjM zi$tS%TndYXR$d$(6<@F1i)sJzla%*qj!kAwJR#Q}r&l=Ih8@Wq_hn8>hQc<#Z*|-> z6M{G-&Hw}g$CnvttN`&Eo6nliCQ}I~3TMZV_b6YIM)TJ}6kEavi6apsj_+vj!^LSN z#m;T+@LJH3uwW9$K*B%@=ufQuK}K<(vq_YR$E0BF|5m;+@FQcO#kHlbl;q_0VDwL+ zrZ`eUZe2<|ifTHxVb)tWOY<|H{2+~Ln*O+Lmo`Ql zEXgVwg1FCdFtn-QG4afjG!nBL#h@eJEPXthjD~|qL^`H^6n{>CcIokS2GP>v_88~b zZ4w$5EJpZf@mk-)VSilQm=3zb$ZV8mXt@Fn1-r0&qN}Zc5`S5Dh_ssA;v8#?&Xppl zKt@>Eqd!090crDHX(h$`QMd2+H+g{H~FRb z<9pnngv)GAKF^l4$rZnlznNlx+?e68a>(3}xy;^Z@h$2H!E0hc^uCN+MW(yOvPF7d z-lO_g^@E%;&MvOf@7Kn-0{V7ywe_Dlo$vGmU8FjGoO6dUTT|@&%;n*gSGU~X5A+PF z{WSaC>O4K))@olREm8KZ?iac4tiisU`Kf)VBdnI$-qbhcdtT`WC2W}Hx=sC0=?u;4 zZdTu7(cHSblb}<0)YmD^h4Kh{hh8%z{QN198)w+{VfHNhfw*_|Db(>jUo}d_KzEaI zeBCJ!BWFvoY|HQrpHjWzl&GOI9G0P0)mo$aR-D3{PgdnpcZsdh)wJXko_&-o56zoI zLssP{r%*e1h7__}r|PBB-n_~cr&K@r-|gS+-|gS+U-5v$GvM8P!}^(gig-!5_hpA1 z83=W^no#~nqbR)~{crrbsnQ!H&gOAr$X(H)HCy+c zd}-gwe!sYtpYn^hGQ3@f_wHO)*Kd|Sh!Naz;GzxQvTv)`MYq;Q`i-}6QRl4-9WBjA zKC4^N5bFOR9n2ng!^Rn3bnRa`ap(NNsTdFE*8SwIuDUPmhu-cv72_d4a^{B2WncMg z*PPOxE^KXMmS*oP|FE-vFjf3aGzjsOxLRB#1{ir;Z6o^GagKQQi}0i3T5*%O)V#dW zc40<;dH$2C%h#C?h+l|NVzAeKw^Qk_0gAtU6}V5_CPs?lko^&-+V8;|S+#XT?0#{k z=?dgLbB(3nc$fIgr{1T;4Q4^0_}L7tzxbfibCIX=wa90ro)EDc#T4;lF<4}@J16vajTYB6wLB+&Dkh5o!d+cFu-^tSMI8QzxKWG} zgGAOBPG_12K~R-Bc0t3?#SEr{VltV)`BLV%ouxhhjHemc{P`9hny)reh(aFuj3g^x z%*fo?-kKhMk-cYuIsHc35lG|{!<8{894grdZSjB`1o0@w1v3Sp8KK3@gp%a~;jjZuoTKXZAC#JLL!$J=x zM~NdcwP5BKp8kCP!7T2auo^)VQIx#Mmgw=c3_vJNzpc9NDS0AC8HUavuH*>ya>Yo> zLse;YJ%pFdg4fWoqLIU7EDV!8MF$4tf8vR!v-}Ubf9xI0<-H6KN5Rd(~_F- zNS2Fvi(I&iC?+6FxnqY<9{T06G)+j1;9W*c{e|l;=(~bK&l#9qDhoKDQEF^SH0z*Srr}gq~o@UhJ{GKsfg3ct)=Ermp zDC+ucu05T_yZILGM%}?rn1ze64Cf3wX`RsecSk`wPv9ECQxw3v6p(|!N){HmdrsRM z_O$R@3webpa1@0eWHem3+-*;Hy=-@+H3GT3#E)PG4Q#-T4Vlcz)gK+c^8Zyrm-~A8 zrFYc~9LX;jKpUeO%MNa*fNq9J_K6eIk$jr*hbvaeUo)4FS;#|7L&d@wdh z?~6;H#I}n{3aF!*?OaN4Hc8er$6dv8O4sX5mNOO};ys?{Kd_-Om_O1fTV~tt&6ZQI zpkvOkN+nmLy$b~A?QxF{f3$+)04#VYpY#E+h< z$!=mZx8Oi!I2NW-MuZS&N?hekMKKx4YfOaqSj&%Sq8ynbhSE$Al9Y3qNP!pmyi#x> z5*{mf@D=q|GNa(pIfAJ$Vi2(@xt2-m^ z*$DRX7&?#fE>n4tSx9sf4c4UG!8e}&;rYY31Gp3~6|}R2OZkL{xd9vgls=po82k0( zs>a<2p5b8@Qp*uS+{A4Nx-?gcU`!0>@hbZYE(f5T*KxC+BLpeLj+Jc7-AVCXxj8S) z7*@+m+zymc&va~zVG0*<85#~}R?`4B$_9wf|YLUeIHIgBKP^I}g)5(DU& zxcicP$;a9JgUh)M7gi<%K6LUqy{0h5VM?$l_Q+w|9TaewFiuAEDdQOmY-2A(tjALA zzWnOxp_SagBIeVL!Dvor02gy5*W*X`j`SuE{&HC_l)H%yu3*k7IIJlg{h$%{e7R>NoW^2$SilxMWRgL~{?^q=ou~Qx zbGEaUV(fejRH8DQxA_Pai9^&I#T)vfXbFkwJc*-+B8n+v6Hjp(3y{g91S>}<#fh?c z%!$6;>xePaYV)(4gr--k(m<%e-;L`5)WU;UR_XjNN$Y%mggejniq3q&w zirLCwf_M&geU@bTp5wW)R_dUh8CYn=%Kc2|dj6B$v{8(UP&l~o+dyB=m-$4~X;mDi z0}l>{)5sUh;SieVF&(6coIyBB_J^T3w06s?Iz{OTFIkviZ>%Rc%_m`lxQ*4Z-5`#7}7|%3R z=Fq?}OqQGKhwnv`J78a5R8J9p-o;Km6>!hqaD(UNe(?z?*ziHqp&2Tx8+q6^7A?g&G>La|?UT#^qUkGxUml zPsol9v>*}UFom?xfq|20Y$l75xM%=N)@I_P7L9RKC(2I#l`3ppjGG^GO!(HgcJ|SIN#~ur zF$qz7=P)Gvkx&E58JtvW@;J5YdE=_<7{9a z)xa>r`!N({czR{`P*9rY$dM_gQdLXM+x4muw2UUeSrd;2KAqf7ppE*yjy zMFtgAVdFghi&q%UhxDMV*WT0&HiMzD-9ZOq{SGBGj_Uh>2xKRo~4!P_?LLvXX3RyJ}L zL2S6l<2Cm1Gg_!4oBVCzSO0r*?e`2IJl&pUWj`iCESR(*coiFdB&>e-^0(s2Blukx zHdrs9fg_aAje<@OFCwrKg0O4Br%4IYzSC<*2k77@xY>h^7BYzfQ!lY`iiF=l|0 zyHEeWGnDT{0qc}QGaTAC9HxaJGJ+UkYOx|vh*t%Z$IrC5%g$3M;0vG?B~f^`lQ^B| zI1V|#NRAK9J8BD(#aKS0isNVqWV#5mo(!~uuC;F`Ily`IjP9YGG-5EA0@hKJ;1v0Y zV&f1TbKbYC&k(fTCEeVkhLC_UI4EZ$9&+&TDjP9biL=Z4o6Nm^;SbEy&l=0Cc(757 z1q-=+MhJ}z%JEXq7T?B)yZdlJMP~hT2Xaa{OgBf-X{VG!93zJfWbsR$XEsrv<6-y4 zzJlNSdt~cWDmjFYVMK7#gp1QS4+9JBoFLFhZN%E8)Q5f30AC36ba3c7bYi#7}~CJt!P}t7c8U|D>^1o267S! ztxJ7qX_AyCQ&MJBYMba}FvXOy1Ho7f6zsIq2<`H(K1>qA){HKn(tt`6UOG8M3-x5v zMH@Zju#bk2`3L>exB4)^BU0!>uU(^Z z6!=D6nH>Grh<($mkC z_t?V}u?06O1q6u_C4v_n!)JSPRSJ?r>sbL;h)H}&7Z%)D=q5&(E>zefz5YScgvfG> zzodx*MqpY%Y62OXt1v?Q$%sF3u_VpwI zaJ{W3(?=OS#F#|`$5=-RL#QJ{jLztZ#~e>DPJ*wtTKJ40E%+$qT!MT|J8jqrU=WW> z&lEnJjNqc=df7}4?VL^yCL`H}j}~-nv~bAK-t2z=A3tEe-!XudcEeIbHZmbhOf*z9 z;+Pn1+RGoL;N@1xJFR2rq=#%2nlO+NIEi8kd9ig%syjeA>_?)QkIBVLm@znzaiCzd zDG#nmaf9%tdcx68jM=gc}%1Z11k;@U1EDFIo@+ZHU?75QL-6Dh;oAD;zUr2CZuI8 z&pwhAzow;(Z`p;y2?W>Ch?hLFX~K&Tk&k$M(GQ*-e#Zd5X|f-wC5(+hsF-A6!-W;% zmgl71sXpN0xb54^`5Y%fRJ?$K4GAmK9_tf}Q>HOhAKxCG#1}{uYa)cgYrn1g<|B61MukYjpz7%OFIWS9-GLYy-U_rrxA(VB_ zhf`Plt>pYb;q}YZ61>C_NN5P$SPygSs+9Ux5O2HS9M{lVT8I!JN)(03!~^k{w3n8q zbVwo#oNJ(u_$SJ1)%+R4F#L<~u2n=*dBA|Vi;y*jpJ9# zQsy8kosDzCC0TeGM;3?h&_f6Zim9%#-`O|*J1fA&qWW-0Tqc($EI5%7gu=?F`u!iK zRqyOX&6buZ3W7{rxG-=MD+~WDr#v0>!EjD_9rctFMa6;6WEujoN0mRXN`sDZvlzF{ z+P<9~3?v6D5;884w?n>BKA2ALhq}kT=Zo*6mL}XN#E76rb3Sq2_|cJc@Y*it=cjX+ ztsEkTj)DbySYPJ4ZAn9F^jcBBVD#P)78+1F#u-R-V-4Bgbltw>L~49_py4smI*CD) z;6V_d3tc{-Nt3@8DU}+VUiyVZ|Zu`^+CENtKGqx>4C8psR%oD*syw(XN>z+ z)*Vi>_Yoc9DtD$r4p9_hsI3JL>wj31W)gd&F<3!oIhAXzrkp>cJ`ONAy2RFRkeZmCNrxe6s1RY?l`&1BJ0O z_g6V9-|9!b^sI(`BRpeDWE)QWhP;v6KmFohKWYx!8oDRPhZIO)qu7jYm45zlS!LQ( zuw&x1F8_r^nE{UC#3!^0^B((}6)F1v!PLl^R_}QC8FG(p%Z3*E-G=L#CAss)kEmR) zmaXnLlWv-9=BrcH%X7l^_dMn6`(3hmy3?F2T{UcK{A>Hd@%6v!Clhg;tWC+9J7V7P z40W~Rt>sPq?Y%ThnKSL?`f-E&(M3bwe6hQ~_(21*elvV-``}`)vVy1I?2aJ~c}g_UrIrN)9HrSUdhOzWOGEs-rEdQRJsn7(`VNv-00000 LNkvXXu0mjf^O&bK literal 0 HcmV?d00001 diff --git a/data/gfx/tiles-blood.png b/data/gfx/tiles-blood.png new file mode 100644 index 0000000000000000000000000000000000000000..59ce3a879185857653d931b2b37343a527e62922 GIT binary patch literal 25701 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 z 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 TstAr#0{}|z)a0sVOhf(;&5xo` literal 0 HcmV?d00001 diff --git a/data/gfx/tiles-double.png b/data/gfx/tiles-double.png new file mode 100644 index 0000000000000000000000000000000000000000..66dc4a9b5ff0864c985f99b85fc8647e24789be6 GIT binary patch literal 21865 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 O0000hjzyb?ofkjFLC4!PbN)5K! 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 aJ. + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi +# `libtool' can also be set to `yes' or `no'. + +depfile=${depfile-`echo "$object" | sed 's,\([^/]*\)$,.deps/\1,;s/\.\([^.]*\)$/.P\1/'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. + "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> $depfile + echo >> $depfile + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> $depfile + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. This file always lives in the current directory. + # Also, the AIX compiler puts `$object:' at the start of each line; + # $object doesn't have directory information. + stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'` + tmpdepfile="$stripped.u" + outname="$stripped.o" + if test "$libtool" = yes; then + "$@" -Wc,-M + else + "$@" -M + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + + if test -f "$tmpdepfile"; then + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" + sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +tru64) + # The Tru64 AIX compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + + tmpdepfile1="$object.d" + tmpdepfile2=`echo "$object" | sed -e 's/.o$/.d/'` + if test "$libtool" = yes; then + "$@" -Wc,-MD + else + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + if test -f "$tmpdepfile1"; then + tmpdepfile="$tmpdepfile1" + else + tmpdepfile="$tmpdepfile2" + fi + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a space and a tab in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the proprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + test -z "$dashmflag" && dashmflag=-M + ( IFS=" " + case " $* " in + *" --mode=compile "*) # this is libtool, let us make it quiet + for arg + do # cycle over the arguments + case "$arg" in + "--mode=compile") + # insert --quiet before "--mode=compile" + set fnord "$@" --quiet + shift # fnord + ;; + esac + set fnord "$@" "$arg" + shift # fnord + shift # "$arg" + done + ;; + esac + "$@" $dashmflag | sed 's:^[^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + ) & + proc=$! + "$@" + stat=$? + wait "$proc" + if test "$stat" != 0; then exit $stat; fi + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + # X makedepend + ( + shift + cleared=no + for arg in "$@"; do + case $cleared in no) + set ""; shift + cleared=yes + esac + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift;; + -*) + ;; + *) + set fnord "$@" "$arg"; shift;; + esac + done + obj_suffix="`echo $object | sed 's/^.*\././'`" + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} 2>/dev/null -o"$obj_suffix" -f"$tmpdepfile" "$@" + ) & + proc=$! + "$@" + stat=$? + wait "$proc" + if test "$stat" != 0; then exit $stat; fi + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tail +3 "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the proprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + ( IFS=" " + case " $* " in + *" --mode=compile "*) + for arg + do # cycle over the arguments + case $arg in + "--mode=compile") + # insert --quiet before "--mode=compile" + set fnord "$@" --quiet + shift # fnord + ;; + esac + set fnord "$@" "$arg" + shift # fnord + shift # "$arg" + done + ;; + esac + "$@" -E | + sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + ) & + proc=$! + "$@" + stat=$? + wait "$proc" + if test "$stat" != 0; then exit $stat; fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the proprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + ( IFS=" " + case " $* " in + *" --mode=compile "*) + for arg + do # cycle over the arguments + case $arg in + "--mode=compile") + # insert --quiet before "--mode=compile" + set fnord "$@" --quiet + shift # fnord + ;; + esac + set fnord "$@" "$arg" + shift # fnord + shift # "$arg" + done + ;; + esac + "$@" -E | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" + ) & + proc=$! + "$@" + stat=$? + wait "$proc" + if test "$stat" != 0; then exit $stat; fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 diff --git a/eel/Makefile.am b/eel/Makefile.am new file mode 100644 index 0000000..dc250d9 --- /dev/null +++ b/eel/Makefile.am @@ -0,0 +1,8 @@ +noinst_LIBRARIES = libeel.a + +INCLUDES = @LOCALCFLAGS@ + +libeel_a_SOURCES = eel.c e_script.c e_symtab.c e_path.c e_util.c \ + e_lexer.c e_register.c e_builtin.c e_getargs.c + +EXTRA_DIST = *.h *.txt diff --git a/eel/Makefile.in b/eel/Makefile.in new file mode 100644 index 0000000..ef6a128 --- /dev/null +++ b/eel/Makefile.in @@ -0,0 +1,434 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = eel +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/aconfig.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) +AR = ar +ARFLAGS = cru +libeel_a_AR = $(AR) $(ARFLAGS) +libeel_a_LIBADD = +am_libeel_a_OBJECTS = eel.$(OBJEXT) e_script.$(OBJEXT) \ + e_symtab.$(OBJEXT) e_path.$(OBJEXT) e_util.$(OBJEXT) \ + e_lexer.$(OBJEXT) e_register.$(OBJEXT) e_builtin.$(OBJEXT) \ + e_getargs.$(OBJEXT) +libeel_a_OBJECTS = $(am_libeel_a_OBJECTS) +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(libeel_a_SOURCES) +DIST_SOURCES = $(libeel_a_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AUDIO_LIBS = @AUDIO_LIBS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_MACOSX_BUNDLE_FALSE = @BUILD_MACOSX_BUNDLE_FALSE@ +BUILD_MACOSX_BUNDLE_TRUE = @BUILD_MACOSX_BUNDLE_TRUE@ +BUILD_SIMPLE_BUNDLE_FALSE = @BUILD_SIMPLE_BUNDLE_FALSE@ +BUILD_SIMPLE_BUNDLE_TRUE = @BUILD_SIMPLE_BUNDLE_TRUE@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CONFIGDIR = @CONFIGDIR@ +CONFIGFILE = @CONFIGFILE@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXEFILE = @EXEFILE@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LOCALCFLAGS = @LOCALCFLAGS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MATHLIB = @MATHLIB@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +POW_LIB = @POW_LIB@ +RANLIB = @RANLIB@ +SCOREDIR = @SCOREDIR@ +SDL_CFLAGS = @SDL_CFLAGS@ +SDL_CONFIG = @SDL_CONFIG@ +SDL_LIBS = @SDL_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +UNIX_SCOREDIR_FALSE = @UNIX_SCOREDIR_FALSE@ +UNIX_SCOREDIR_TRUE = @UNIX_SCOREDIR_TRUE@ +VERSION = @VERSION@ +XMKMF = @XMKMF@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +noinst_LIBRARIES = libeel.a +INCLUDES = @LOCALCFLAGS@ +libeel_a_SOURCES = eel.c e_script.c e_symtab.c e_path.c e_util.c \ + e_lexer.c e_register.c e_builtin.c e_getargs.c + +EXTRA_DIST = *.h *.txt +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign eel/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign eel/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libeel.a: $(libeel_a_OBJECTS) $(libeel_a_DEPENDENCIES) + -rm -f libeel.a + $(libeel_a_AR) libeel.a $(libeel_a_OBJECTS) $(libeel_a_LIBADD) + $(RANLIB) libeel.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/e_builtin.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/e_getargs.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/e_lexer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/e_path.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/e_register.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/e_script.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/e_symtab.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/e_util.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eel.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-noinstLIBRARIES ctags distclean distclean-compile \ + distclean-generic distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/eel/_e_script.h b/eel/_e_script.h new file mode 100644 index 0000000..ca83ee9 --- /dev/null +++ b/eel/_e_script.h @@ -0,0 +1,40 @@ +/*(LGPL) +--------------------------------------------------------------------------- + _e_script.h - EEL source code management (Private) +--------------------------------------------------------------------------- + * Copyright (C) 2002, David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _EEL__SCRIPT_H_ +#define _EEL__SCRIPT_H_ + +#include "eel.h" +#include "e_script.h" + +#define MAX_SCRIPTS 256 + +typedef struct script_t +{ + char *name; + unsigned char *data; + unsigned len; +} script_t; + +extern script_t eel_scripttab[MAX_SCRIPTS]; + + +#endif /*_EEL__SCRIPT_H_*/ diff --git a/eel/e_builtin.c b/eel/e_builtin.c new file mode 100644 index 0000000..fc60fe3 --- /dev/null +++ b/eel/e_builtin.c @@ -0,0 +1,462 @@ +/*(LGPL) +--------------------------------------------------------------------------- + e_builtin.c - EEL built-in commands and directives +--------------------------------------------------------------------------- + * Copyright (C) 2002, 2003, David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define DBG(x) + +#include "kobolog.h" +#include "math.h" +#include "e_builtin.h" +#include "e_util.h" +#include "e_lexer.h" + + +/*---------------------------------------------------------- + Command Callbacks +----------------------------------------------------------*/ + +int eel_cmd_end(int argc, struct eel_data_t *argv) +{ + DBG(log_printf(DLOG, "end;\n");) + return 0; +} + + +int eel_cmd_set(int argc, struct eel_data_t *argv) +{ + eel_symbol_t *to; + eel_data_t *val; + + if(eel_get_args("nV(irsce)", &to, &val) != 2) + return -1; + + DBG(log_printf(DLOG, "set %s, ", eel_s_stringrep(to));) + DBG(log_printf(DLOG, "%s;\n", eel_d_stringrep(val));) + + eel_s_set(to, val); + + return 1; +} + + +int eel_cmd_print(int argc, struct eel_data_t *argv) +{ + int i; + for(i = 0; i < argc; ++i) + { + if(EDT_SYMREF == argv[i].type) + switch(argv[i].value.sym->type) + { + case EST_CONSTANT: + case EST_VARIABLE: + /* Print the *value* of these... */ + log_printf(ULOG, "%s", eel_d_stringrep( + &argv[i].value.sym->data)); + continue; + default: + break; + } + log_printf(ULOG, "%s", eel_d_stringrep(argv + i)); + } + + return 1; +} + + +/*---------------------------------------------------------- + Operator Callbacks +----------------------------------------------------------*/ + +static inline eel_datatypes_t promote(struct eel_data_t *left, + struct eel_data_t *right) +{ + if(left->type == right->type) + { + if(left->type == EDT_INTEGER || left->type == EDT_REAL) + return left->type; + else + { + eel_error("Operands of unsupported type!"); + return -1; + } + } + + if(left->type == EDT_INTEGER) + { + left->value.r = (double)left->value.i; + left->type = EDT_REAL; + } + else if(left->type != EDT_REAL) + { + eel_error("Left hand operand of unsupported type!"); + return -1; + } + + if(right->type == EDT_INTEGER) + { + right->value.r = (double)right->value.i; + right->type = EDT_REAL; + } + else if(right->type != EDT_REAL) + { + eel_error("Right hand operand of unsupported type!"); + return -1; + } + + return EDT_REAL; +} + + +int eel_op_add(int argc, struct eel_data_t *argv) +{ + eel_data_t *left = argv, *right = argv + 1; + DBG(log_printf(DLOG, "add ");) + if(argc != 2) + { + eel_error("Operator needs exactly two arguments!"); + return -1; + } + switch(promote(left, right)) + { + case EDT_REAL: + DBG(log_printf(DLOG, "%f, %f\n", left->value.r, right->value.r);) + left->value.r += right->value.r; + break; + case EDT_INTEGER: + DBG(log_printf(DLOG, "%d, %d\n", left->value.i, right->value.i);) + left->value.i += right->value.i; + break; + default: + return -1; + } + return 0; +} + + +int eel_op_sub(int argc, struct eel_data_t *argv) +{ + eel_data_t *left = argv, *right = argv + 1; + DBG(log_printf(DLOG, "sub ");) + if(argc != 2) + { + eel_error("Operator needs exactly two arguments!"); + return -1; + } + switch(promote(left, right)) + { + case EDT_REAL: + DBG(log_printf(DLOG, "%f, %f\n", left->value.r, right->value.r);) + left->value.r -= right->value.r; + break; + case EDT_INTEGER: + DBG(log_printf(DLOG, "%d, %d\n", left->value.i, right->value.i);) + left->value.i -= right->value.i; + break; + default: + return -1; + } + return 0; +} + + +int eel_op_mul(int argc, struct eel_data_t *argv) +{ + eel_data_t *left = argv, *right = argv + 1; + DBG(log_printf(DLOG, "mul ");) + if(argc != 2) + { + eel_error("Operator needs exactly two arguments!"); + return -1; + } + switch(promote(left, right)) + { + case EDT_REAL: + DBG(log_printf(DLOG, "%f, %f\n", left->value.r, right->value.r);) + left->value.r *= right->value.r; + break; + case EDT_INTEGER: + DBG(log_printf(DLOG, "%d, %d\n", left->value.i, right->value.i);) + left->value.i *= right->value.i; + break; + default: + return -1; + } + return 0; +} + + +int eel_op_div(int argc, struct eel_data_t *argv) +{ + eel_data_t *left = argv, *right = argv + 1; + DBG(log_printf(DLOG, "div ");) + if(argc != 2) + { + eel_error("Operator needs exactly two arguments!"); + return -1; + } + switch(promote(left, right)) + { + case EDT_REAL: + if(!right->value.r) + { + eel_error("Division by zero!"); + return -1; + } + DBG(log_printf(DLOG, "%f, %f\n", left->value.r, right->value.r);) + left->value.r /= right->value.r; + break; + case EDT_INTEGER: + if(!right->value.i) + { + eel_error("Division by zero!"); + return -1; + } + DBG(log_printf(DLOG, "%d, %d\n", left->value.i, right->value.i);) + left->value.i /= right->value.i; + break; + default: + return -1; + } + return 0; +} + + +int eel_op_mod(int argc, struct eel_data_t *argv) +{ + eel_data_t *left = argv, *right = argv + 1; + DBG(log_printf(DLOG, "mod ");) + if(argc != 2) + { + eel_error("Operator needs exactly two arguments!"); + return -1; + } + switch(promote(left, right)) + { + case EDT_REAL: + if(!right->value.r) + { + eel_error("Zero modulus!"); + return -1; + } + DBG(log_printf(DLOG, "%f, %f\n", left->value.r, right->value.r);) + left->value.r -= right->value.r * + floor(left->value.r / right->value.r); + break; + case EDT_INTEGER: + if(!right->value.i) + { + eel_error("Zero modulus!"); + return -1; + } + DBG(log_printf(DLOG, "%d, %d\n", left->value.i, right->value.i);) + left->value.i %= right->value.i; + break; + default: + return -1; + } + return 0; +} + + +int eel_op_pow(int argc, struct eel_data_t *argv) +{ + eel_data_t *left = argv, *right = argv + 1; + DBG(log_printf(DLOG, "pow ");) + if(argc != 2) + { + eel_error("Operator needs exactly two arguments!"); + return -1; + } + switch(promote(left, right)) + { + case EDT_REAL: + DBG(log_printf(DLOG, "%f, %f\n", left->value.r, right->value.r);) + left->value.r = pow(left->value.r, right->value.r); + break; + case EDT_INTEGER: + DBG(log_printf(DLOG, "%d, %d\n", left->value.i, right->value.i);) + left->value.i = pow(left->value.i, right->value.i); + break; + default: + return -1; + } + return 0; +} + + +/*---------------------------------------------------------- + Directive Callbacks +----------------------------------------------------------*/ + +int eel_dir_include(void) +{ + int h, res; + const char *fn; + + if(eel_parse_args(" ", '\n') < 0) + return -1; + + if(eel_get_args("s", &fn) < 0) + return -1; + + h = eel_load(fn); + if(h < 0) + { + eel_error("Couldn't include file \"%s\"!", fn); + return -1; + } + res = eel_run(h); + eel_free(h); + + if(res < 0) + return res; + else + return 1; +} + + +int eel_dir_define(void) +{ + eel_symbol_t *to; + eel_data_t *val; + int res; + + if(eel_parse_args(" ", '\n') < 0) + return -1; + + res = eel_get_args("n[V(irsce)]", &to, &val); + + if(res < 0) + return -1; + + switch(res) + { + case 1: + DBG(log_printf(DLOG, "#define\t%s\n", eel_s_stringrep(to));) + to->data.type = EDT_ILLEGAL; + to->data.value.i = 0; + to->type = EST_CONSTANT; + break; + case 2: + DBG(log_printf(DLOG, "#define\t%s\t%s\n", + eel_s_stringrep(to), eel_d_stringrep(val));) + eel_s_set(to, val); + to->type = EST_CONSTANT; + break; + default: + eel_error("Expected either one or two arguments!"); + return -1; + } + return res; +} + + +/*---------------------------------------------------------- + Special Callbacks +----------------------------------------------------------*/ + +static int _proc_func(void) +{ + const char *funcname; + eel_symbol_t *s; + int tk, res; + + /* Get function name */ + tk = eel_lex(0); + if(tk != TK_NEWSYM) + { + eel_error("Function/procedure name must be unique!"); + return -1; + } + funcname = eel_current.lval->value.s; + + /* Create function symbol */ + s = eel_s_new(funcname, EST_FUNCTION); + if(!s) + { + eel_error("INTERNAL ERROR: Failed to create " + "function/procedure symbol!"); + return -1; + } + + /* Check argument list */ + if(eel_lex(0) != '(') + { + eel_error("Expected '('!"); + return -1; + } + + /* Store the start of the *argument list*... :-) */ + s->data.value.a = bio_tell(eel_current.bio); + s->token = eel_current.script; + eel_push_scope(); + res = eel_parse_args(",", ')'); + eel_pop_scope(); + if(res < 0) + return -1; + + DBG(log_printf(DLOG, "Function/procedure '%s' defined; starting at %d.\n", + s->name, s->data.value.a);) + + /* Find start of body ("the code") */ + if(eel_lex(0) != '{') + { + eel_error("Expected '{'!"); + return -1; + } + + return 1; +} + +int eel_spec_function(void) +{ + int c; + + if(_proc_func() < 0) + return -1; + + /* QUICK HACK: Skip function body */ + while((c = bio_getchar(eel_current.bio)) != '}') + if(EOF == c) + { + eel_error("EOF inside function body!"); + return -1; + } + + return 1; +} + +int eel_spec_procedure(void) +{ + int c; + + if(_proc_func() < 0) + return -1; + + /* QUICK HACK: Skip procedure body */ + while((c = bio_getchar(eel_current.bio)) != '}') + if(EOF == c) + { + eel_error("EOF inside procedure body!"); + return -1; + } + + return 1; +} diff --git a/eel/e_builtin.h b/eel/e_builtin.h new file mode 100644 index 0000000..8970f7c --- /dev/null +++ b/eel/e_builtin.h @@ -0,0 +1,59 @@ +/*(LGPL) +--------------------------------------------------------------------------- + e_builtin.c - EEL built-in commands and directives +--------------------------------------------------------------------------- + * Copyright (C) 2002, David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _EEL_BUILTIN_H_ +#define _EEL_BUILTIN_H_ + +#include "eel.h" + +/*---------------------------------------------------------- + Command Callbacks +----------------------------------------------------------*/ +int eel_cmd_end(int argc, struct eel_data_t *argv); +int eel_cmd_set(int argc, struct eel_data_t *argv); +int eel_cmd_print(int argc, struct eel_data_t *argv); + + +/*---------------------------------------------------------- + Operator Callbacks +----------------------------------------------------------*/ +int eel_op_add(int argc, struct eel_data_t *argv); +int eel_op_sub(int argc, struct eel_data_t *argv); +int eel_op_mul(int argc, struct eel_data_t *argv); +int eel_op_div(int argc, struct eel_data_t *argv); +int eel_op_mod(int argc, struct eel_data_t *argv); +int eel_op_pow(int argc, struct eel_data_t *argv); + + +/*---------------------------------------------------------- + Directive Callbacks +----------------------------------------------------------*/ +int eel_dir_include(void); +int eel_dir_define(void); + + +/*---------------------------------------------------------- + Special Callbacks +----------------------------------------------------------*/ +int eel_spec_function(void); +int eel_spec_procedure(void); + +#endif /*_EEL_BUILTIN_H_*/ diff --git a/eel/e_getargs.c b/eel/e_getargs.c new file mode 100644 index 0000000..adea3d9 --- /dev/null +++ b/eel/e_getargs.c @@ -0,0 +1,1023 @@ +/*(LGPL) +--------------------------------------------------------------------------- + e_getargs.c - scanf() style "argument fetcher" + expr. evaluator +--------------------------------------------------------------------------- + * Copyright (C) 2002, 2003, David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +#include "kobolog.h" +#include "config.h" +#include "eel.h" +#include "e_lexer.h" +#include "e_util.h" +#include "e_builtin.h" + +#define DBG(x) + + +/*---------------------------------------------------------- + Argument list parser +----------------------------------------------------------*/ + +eel_data_t eel_arg_table[EEL_MAX_ARGS]; +int eel_arg_token_table[EEL_MAX_ARGS]; + +int eel_arg_count = 0; +eel_data_t *eel_args = eel_arg_table; +int *eel_arg_tokens = eel_arg_token_table; + + +int eel_grab_arg(void) +{ + if(eel_arg_count >= EEL_MAX_ARGS) + return -1; + + eel_arg_tokens[eel_arg_count] = eel_current.token; + + if(eel_current.lval) + { + if(EDT_SYMREF == eel_current.lval->type) + { + /* Kill "runaway indirection" right at it's root! */ + if(EDT_SYMREF == eel_current.lval->value.sym->data.type) + eel_d_copy(eel_current.lval, + &eel_current.lval->value.sym->data); + } + + /* + * Important: + * This is a *move* operation! This is + * to avoid copying external string + * buffers around, while still making + * sure the new eel_data_t gains true + * ownership of them. + */ + eel_args[eel_arg_count] = *eel_current.lval; + free(eel_current.lval); + eel_current.lval = NULL; + } + ++eel_arg_count; + return eel_arg_count; +} + + +void eel_clear_args(int first) +{ + int i; + for(i = first; i < eel_arg_count; ++i) + eel_d_freestring(eel_args + i); + eel_arg_count = first; +} + + +void eel_remove_arg(int pos) +{ + int i; + eel_d_freestring(eel_args + pos); + for(i = pos + 1; i < eel_arg_count; ++i) + { + eel_args[i-1] = eel_args[i]; + eel_arg_tokens[i-1] = eel_arg_tokens[i]; + } + --eel_arg_count; +} + + +/* + * Remove all arguments in the range ]start, end[. + * (That is, not including args 'start' or 'end'.) + */ +void eel_collapse(int start, int end) +{ + int i; + for(i = start + 1; i < end; ++i) + eel_remove_arg(i); +} + + +/* + * Try to convert 'd' into a value. If it's not + * possible, nothing will be done. + */ +static inline void resolve(eel_data_t *d) +{ + if(EDT_SYMREF == d->type) + switch(d->value.sym->type) + { + case EST_CONSTANT: + case EST_VARIABLE: + case EST_ENUM: + /* These are OK. */ + *d = d->value.sym->data; + break; + default: + break; + } +} + + +/* + * Steenkin' special case for a single unary minus before a term. + * (Could be recursive, call unary operator callbacks and stuff, + * but there are too many screaming babies here right now... :-) + */ +static inline int neg(int pos) +{ + eel_data_t *d; + if((EDT_SYMREF == eel_args[pos].type) && + (EST_OPERATOR == eel_args[pos].value.sym->type)) + { + DBG(log_printf(DLOG, "neg\n");) + if(eel_op_sub != eel_args[pos].value.sym->data.value.op.cb) + { + eel_error("No unary operator '%s'!", + eel_args[pos].value.sym->name); + return -1; + } + d = &eel_args[pos+1]; + if(!d) + { + eel_error("Expected operand for unary minus!"); + return -1; + } + resolve(d); + switch(d->type) + { + case EDT_REAL: /* Real */ + d->value.r = -d->value.r; + break; + case EDT_INTEGER: /* Integer */ + d->value.i = -d->value.i; + break; + case EDT_SYMREF: /* Symbol reference */ + eel_error("Chained unary operators not yet supported!"); + return -1; + case EDT_SYMTAB: /* Symbol table reference */ + case EDT_STRING: /* String */ + case EDT_CADDR: /* Code address */ + case EDT_SYMNAME: /* Name of a new symbol (String) */ + case EDT_OPERATOR: /* Operator callback */ + case EDT_DIRECTIVE: /* Directive parser callback */ + case EDT_SPECIAL: /* Special parser callback */ + case EDT_ILLEGAL: + eel_error("Illegal operation!"); + return -1; + } + eel_remove_arg(pos); + } + else + resolve(&eel_args[pos]); + return 0; +} + + +/* + * Recursively evaluate expression, taking operator + * precedence in account. The 'left' argument is the + * index of the left operand, which is also the + * target for the result, and must be followed by an + * operator and a valid right term. + * +FIXME: + * Note that a single unary minus is allowed as a + * part of each term, and will be evaluated here. + * This feature should be removed as soon as the + * new operator system is fully implemented. (Unary + * minus can then be implemented as just another EEL + * operator.) +/FIXME + * + * Returns the index of the last argument used, or a + * negative value, if the operation fails. + * +FIXME: Handle 0 returns from operators...? + */ +static int recursive_eval(int left) +{ + int right = left + 1; + if(neg(left) < 0) + return -1; + + while(right + 1 < eel_arg_count) + { + eel_symbol_t *op, *op2; + op = eel_args[right].value.sym; + if(neg(right + 1) < 0) + return -1; + + if(right + 2 < eel_arg_count) + { + op2 = eel_args[right + 2].value.sym; + if(op2->data.value.op.priority > op->data.value.op.priority) + { + int maxr = recursive_eval(right + 1); + eel_remove_arg(right); /* Remove operator */ + if(op->data.value.op.cb(2, eel_args + left) < 0) + return -1; + + eel_remove_arg(right); /* Remove right term */ + return maxr; + } + } + eel_remove_arg(right); /* Remove operator token */ + if(op->data.value.op.cb(2, eel_args + left) < 0) + return -1; + + eel_remove_arg(right); /* Remove right hand term */ + } + return right; +} + + +/* + * Evaluate expression, starting at position 'start' + * in the internal argument list. The whole expression + * will be replaced by a single term, stored in the + * 'start' position, and all terms after it will be + * deleted. + * + * Returns a token corresponding to the result type, + * or a negative value in case of an error. + */ +static int do_eval(int start) +{ + if(eel_arg_count - start > 1) + { + int right; +#if 0 +int i; +for(i = 0; i < start; ++i) + log_printf(D3LOG, " "); +log_printf(D3LOG, "do_eval(): "); +for(i = start; i < eel_arg_count; ++i) +{ + if(EDT_SYMREF == eel_args[i].type) + log_printf(D3LOG, "<%s, %d>", eel_symbol_is(eel_args[i].value.sym), + eel_arg_tokens[i]); + else + log_printf(D3LOG, "<%s, %d>", eel_data_is(&eel_args[i]), + eel_arg_tokens[i]); +} +log_printf(D3LOG, "\n"); +#endif + right = recursive_eval(start); + if(right < 0) + return -1; + + /* Check for bogus "terminating operator" */ + if(right < eel_arg_count) + { + eel_error("Expression syntax error!"); + return -1; + } + } + + /* Prepare and return result */ +/* eel_clear_args(start + 1);*/ + switch (eel_args[start].type) + { + case EDT_REAL: + eel_arg_tokens[start] = TK_RNUM; + break; + case EDT_INTEGER: + eel_arg_tokens[start] = TK_INUM; + break; + case EDT_STRING: + eel_arg_tokens[start] = TK_STRN; + break; + case EDT_SYMNAME: + eel_arg_tokens[start] = TK_NEWSYM; + break; + case EDT_SYMTAB: + /* + * Note: + * If we were to get a namespace reference, it would + * actually be an EDT_SYMREF referring to the namespace + * symbol, rather than a raw pointer to namespace + * symbol table itself. + */ + eel_error("Weird... do_eval() saw a symbol table reference."); + eel_arg_tokens[start] = -1; + break; + case EDT_SYMREF: + case EDT_OPERATOR: + case EDT_DIRECTIVE: + case EDT_SPECIAL: + eel_arg_tokens[start] = TK_SYMREF; + break; + default: + eel_error("Weird things going on in do_eval()!"); + eel_arg_tokens[start] = -1; + break; + } + return eel_arg_tokens[start]; +} + + +/* + * Grab, and if required, evaluate the next "token". + * + * This function will return a token, and when applicable, + * the corresponding eel_data_t already last in the argument + * list. + * + * Note that returned arguments may be results of evaluated + * expressions, rather than constants from the source. + * + * Also note that the function will stop at ')' tokens. This + * functions as a way of supporting the alternative LISP + * style function calls (required when functions are used + * inside argument lists and expressions). It's also a + * feature that's relied upon internally, to recursively + * resolve expressions containing parentheses. + */ +static int eval(int report_eoln) +{ + int tk = EOF; + int prev_tk; + int expect_operator = 0; + int tokens = 0; + int start = eel_arg_count; + int grab_and_return = 0; + eel_symbol_t *sym; + /* + * Get terms and operators, checking that we + * get term, operator(s), term,... etc. Stop + * and evaluate if the chain is broken, or + * any other token is seen. + */ + while(1) + { + prev_tk = tk; + tk = eel_lex(report_eoln); + switch(tk) + { + case TK_SYMREF: + sym = eel_current.lval->value.sym; + if(expect_operator) + { + if(EST_OPERATOR != sym->type) + { + eel_unlex(); + return do_eval(start); + } + expect_operator = 0; + } + else + if(EST_OPERATOR != sym->type) + expect_operator = 1; + break; + case TK_NEWSYM: + case TK_RNUM: + case TK_INUM: + case TK_STRN: + if(expect_operator) + { + eel_unlex(); + return do_eval(start); + } + expect_operator = !expect_operator; + break; + case '(': + if(eval(report_eoln) < 0) + return -1; + tk = eel_lex(report_eoln); + if(')' != tk) + { + eel_error("Unmatched '(' in expression!"); + return -1; + } + continue; + case ')': + if(0 == tokens) + /* Not part of the expression. */ + return ')'; + else + { + eel_unlex(); + return do_eval(start); + } + break; + default: + if(0 == tokens) + { + return tk; + } + else + { + eel_unlex(); + return do_eval(start); + } + } + if(eel_grab_arg() < 0) + { + eel_error("Argument overflow!"); + return -1; + } + if(grab_and_return) + return tk; + ++tokens; + } +} + + +int eel_parse_args(const char *separators, char terminator) +{ + int sep_required = (strchr(separators, ' ') == 0); + int expect_separator = 0; + int tk; + eel_current.arg = 1; + while( (tk = eval('\n' == terminator)) ) + { + if(tk == terminator) + return 0; + switch(tk) + { + case TK_SYMREF: + /* No operators here, please! */ + if(EST_OPERATOR == eel_args[eel_arg_count-1]. + value.sym->type) + { + eel_error("Incorrectly used operator!"); + eel_current.arg = 0; + return -1; + } + case TK_NEWSYM: + case TK_RNUM: + case TK_INUM: + case TK_STRN: + if(expect_separator) + { + eel_error("Argument separator expected!"); + eel_current.arg = 0; + return -1; + } + expect_separator = sep_required; + break; + default: + if(tk < 256) + if(strchr(separators, tk)) + { + expect_separator = 0; + ++eel_current.arg; + break; + } +/* eel_error("Unexpected token!");*/ + eel_current.arg = 0; + return -1; + } + } + eel_error("Unexpected end of file!"); + eel_current.arg = 0; + return -1; +} + + +/*---------------------------------------------------------- + Argument list fetcher +----------------------------------------------------------*/ + +/* + * Extract a "value" out of an argument. + * Only types marked in 'types' are accepted. + * + * If symrefs are accepted, the 'stypes' mask + * determines which symbol types are accepted. + * + * Returns NULL upon failure, or the address of + * a eel_data_t struct. + */ +static eel_data_t *get_value(eel_data_t *arg, int types, int stypes) +{ + eel_data_t *dat; + + dat = arg; + + /* Find actual source data */ +#if 0 + while(EDT_SYMREF == dat->type) +#else + if(EDT_SYMREF == dat->type) +#endif + { + switch(dat->value.sym->type) + { + case EST_ENUM: + /* Keep symref if enums are desired! */ + if(types & EDTM_SYMREF) + break; + case EST_CONSTANT: + case EST_VARIABLE: + dat = &dat->value.sym->data; + break; + default: + eel_error("Invalid argument!"); + return NULL; + } + } + + if((EDT_SYMREF == dat->type) && (types & EDTM_SYMREF)) + { + /* Check symbol type */ + if(!(stypes & (1<value.sym->type))) + { + eel_error("Wrong symbol type! (%s)", + eel_data_is(dat)); + return NULL; + } + return arg; + } + else + { + /* Check data type */ + if(!(types & (1<type))) + { + eel_error("Wrong data type! (%s)", + eel_data_is(dat)); + return NULL; + } + return dat; + } +} + + +/* + * Find the symbol table entry for the variable + * referenced by 'arg'. If 'arg' is not a symbol + * reference, or if the referenced symbol is not + * a variable, NULL is returned, otherwise the + * symbol is returned. + */ +static eel_symbol_t *get_variable(eel_data_t *arg) +{ + eel_symbol_t *sym; + + if(EDT_SYMREF != arg->type) + return NULL; + + sym = arg->value.sym; + + if(sym->type != EST_VARIABLE) + { + eel_error("Expected a variable, not %s!", eel_symbol_is(sym)); + return NULL; + } + return sym; +} + + +static int eel_get_argsv(int argc, struct eel_data_t *argv, + const char *fmt, va_list args) +{ + int parsing = 1; + int optional = 0; + int tuple = 0; + int using_tuple = 0; + const char *tuple_start = NULL; + int got = 0; + int flags; + eel_data_t *dat; + eel_symbol_t *sym; + va_list args_tuple_start; + + int *i; + double *r; + char **s; + eel_data_t **datp; + eel_symbol_t **symp; + + eel_current.arg = 1; + + va_copy(args_tuple_start, args); + + while(parsing > 0) + { + eel_data_t *a; + + /* Handle "harmless" control characters */ + switch(*fmt) + { + case 0: +/* case ')': For LISP style function calls */ + if(tuple_start) + { + /* + * We should never get here if + * we have an argument tuple! + */ + log_printf(ELOG,"eel eel_get_args(): Error in" + " format string; " + "unterminated argument" + "tuple!\n"); + parsing = -1; + continue; + } + if(!optional && (got < argc)) + { + eel_error("%d arguments required; got %d!", + got, argc); + parsing = -1; + continue; + } + parsing = 0; + continue; + case '<': + /* Argument tuple start */ + ++fmt; + va_end(args_tuple_start); + if(using_tuple) + { + log_printf(ELOG,"eel eel_get_args(): Error in" + " format string; " + "'<' inside tuple!\n"); + parsing = -1; + continue; + } + using_tuple = 1; + tuple_start = fmt; + va_copy(args_tuple_start, args); + continue; + case '>': + /* Argument tuple end */ + if(!tuple_start) + { + log_printf(ELOG,"eel eel_get_args(): Error in" + " format string; " + "'>' without '<'!\n"); + parsing = -1; + continue; + } + fmt = tuple_start; + va_end(args); + va_copy(args, args_tuple_start); + ++tuple; + continue; + case '[': + /* Optional arguments */ + optional = 1; + case ']': + ++fmt; + continue; + case '*': + /* Throw away this argument */ + ++fmt; + ++eel_current.arg; + continue; + case ',': + ++fmt; + continue; + default: + if(got < argc) + a = argv + got; + else + { + parsing = 0; + continue; + } + } + + /* Handle actual data extraction tokens */ + switch(*fmt) + { + case '?': + datp = va_arg(args, eel_data_t **); + datp[tuple] = a; + break; + case 'E': + symp = va_arg(args, eel_symbol_t **); + if(EDT_SYMREF != a->type) + { + eel_error("Not an enum constant!\n"); + parsing = -1; + continue; + } + symp[tuple] = a->value.sym; + + /* Handle variables containing symrefs! */ + if( (symp[tuple]->type == EST_VARIABLE) && + (symp[tuple]->data.type == EDT_SYMREF) ) + symp[tuple] = symp[tuple]->data.value.sym; + + if(symp[tuple]->type != EST_ENUM) + { + eel_error("%s, not an enum constant!", + eel_symbol_is(symp[tuple])); + parsing = -1; + continue; + } + break; + case 'V': + datp = va_arg(args, eel_data_t **); + if('(' == *(fmt+1)) + { + fmt += 2; + flags = 0; + while(*fmt != ')') + { + switch(*fmt) + { + case 0: + log_printf(ELOG,"Unexpected end" + " of control" + "string!\n"); + parsing = -1; + break; + case 'i': + flags |= EDTM_INTEGER; + break; + case 'r': + flags |= EDTM_REAL; + break; + case 's': + flags |= EDTM_STRING; + break; + case 'c': + flags |= EDTM_CADDR; + break; + case 'e': + flags |= EDTM_SYMREF; + break; + default: + log_printf(ELOG,"Unknown type" + " code '%c'!", + *fmt); + parsing = -1; + break; + } + if(parsing < 0) + break; + ++fmt; + } + if(parsing < 0) + continue; + } + else + flags = EDTM_REAL | EDTM_INTEGER | + EDTM_STRING | EDTM_CADDR; + datp[tuple] = get_value(a, flags, ESTM_ENUM); + if(!datp[tuple]) + { + parsing = -1; + continue; + } + break; + case 'e': + i = va_arg(args, int *); + if(a->type != EDT_SYMREF) + { + eel_error("Enum argument must be a symref, " + "not %s!", eel_data_is(a)); + parsing = -1; + continue; + } + sym = a->value.sym; + if(sym->type == EST_VARIABLE) + { + /* Follow reference */ + eel_data_t *sd = &sym->data; + if(sd->type == EDT_SYMREF) + if(sd->value.sym->type == EST_ENUM) + sym = sd->value.sym; + } + if(sym->type != EST_ENUM) + { + eel_error("Expected enumerated type, not %s!", + eel_symbol_is(sym)); + parsing = -1; + continue; + } + if(sym->token != *i) + { + /* Oops, inter-enum namespace conflict! + * See if we can find the same identifier + * in the *right* class... + */ + sym = eel_s_find_n_tk(sym, sym->name, *i); + if(!sym) + { + eel_error("Wrong enumeration class!"); + parsing = -1; + continue; + } + } + i[tuple] = sym->data.value.i; + break; + case 'f': + symp = va_arg(args, eel_symbol_t **); + if(EDT_SYMREF != a->type) + { + eel_error("Not a function!\n"); + parsing = -1; + continue; + } + symp[tuple] = a->value.sym; + + /* Handle variables containing symrefs! */ + if( (symp[tuple]->type == EST_VARIABLE) && + (symp[tuple]->data.type == EDT_SYMREF) ) + symp[tuple] = symp[tuple]->data.value.sym; + + if(symp[tuple]->type != EST_FUNCTION) + { + eel_error("%s, not a function!", + eel_symbol_is(symp[tuple])); + parsing = -1; + continue; + } + break; + case 'i': + i = va_arg(args, int *); + dat = get_value(a, EDTM_INTEGER | EDTM_REAL | EDTM_STRING, + 0); + if(!dat) + { + eel_error("Failed to cast argument to integer."); + parsing = -1; + continue; + } + switch(dat->type) + { + case EDT_REAL: + i[tuple] = (int)dat->value.r; + break; + case EDT_INTEGER: + i[tuple] = dat->value.i; + break; + case EDT_STRING: + i[tuple] = (int)atof(dat->value.s); + break; + default: + eel_error("INTERNAL: Got type I didn't ask for."); + parsing = -1; + continue; + } + break; + case 'n': + symp = va_arg(args, eel_symbol_t **); + symp[tuple] = get_variable(a); + if(!symp[tuple]) + { + if(a->type == EDT_SYMNAME) + symp[tuple] = eel_set_integer( + a->value.s, 0); + if(!symp[tuple]) + { + eel_error("Failed to create new symbol! '%s'", + a->value.s); + parsing = -1; + continue; + } + } + break; + case 'r': + r = va_arg(args, double *); + dat = get_value(a, EDTM_INTEGER | EDTM_REAL | EDTM_STRING, + 0); + if(!dat) + { + eel_error("Failed to cast argument to real."); + parsing = -1; + continue; + } + switch(dat->type) + { + case EDT_REAL: + r[tuple] = dat->value.r; + break; + case EDT_INTEGER: + r[tuple] = (double)dat->value.i; + break; + case EDT_STRING: + r[tuple] = atof(dat->value.s); + break; + default: + eel_error("INTERNAL: Got type I didn't ask for."); + parsing = -1; + continue; + } + break; + case 's': + s = va_arg(args, char **); + dat = get_value(a, EDTM_STRING, 0); + if(!dat) + { + eel_error("Failed to cast argument to string."); + parsing = -1; + continue; + } + switch(dat->type) + { +#if 0 +TODO: (String memory management problem) + case EDT_REAL: + break; + case EDT_INTEGER: + break; +#endif + case EDT_STRING: + s[tuple] = dat->value.s; + break; + default: + eel_error("INTERNAL: Got type I didn't ask for."); + parsing = -1; + continue; + } + break; + case 'v': + symp = va_arg(args, eel_symbol_t **); + symp[tuple] = get_variable(a); + if(!symp[tuple]) + { + parsing = -1; + continue; + } + break; + default: + eel_error("eel_get_args(): Error in format string; " + "unknown control char '%c'.\n", *fmt); + parsing = -1; + continue; + } + ++fmt; + ++got; + ++eel_current.arg; /* (For error messages) */ + } + va_end(args_tuple_start); + + if(parsing < 0) + return -1; /* Error exit! */ + + eel_current.arg = 0; + + if(!optional) + { + /* + * We *should* be at the end of the format string + * now. Let's check... + */ + while(*fmt) + { + switch(*fmt) + { + case '>': + case ']': + break; + default: + eel_error("Insufficient number of arguments!"); + return -1; + } + ++fmt; + } + } + + if(argc > got) + { + eel_error("Too many arguments!"); + eel_current.arg = 0; + return -1; + } + + return got; +} + + +int eel_get_args_from(int argc, struct eel_data_t *argv, const char *fmt, ...) +{ + int ret; + va_list args; + va_start(args, fmt); + ret = eel_get_argsv(argc, argv, fmt, args); + va_end(args); + return ret; +} + + +int eel_get_args(const char *fmt, ...) +{ + int ret; + va_list args; + va_start(args, fmt); + ret = eel_get_argsv(eel_arg_count, eel_args, fmt, args); + va_end(args); + return ret; +} + diff --git a/eel/e_lexer.c b/eel/e_lexer.c new file mode 100644 index 0000000..14c952d --- /dev/null +++ b/eel/e_lexer.c @@ -0,0 +1,419 @@ +/*(LGPL) +--------------------------------------------------------------------------- + e_lexer.c - EEL engine lexer +--------------------------------------------------------------------------- + * Copyright (C) 2002, David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include + +#include "e_lexer.h" +#include "e_util.h" + + +int eel_get_unique_token() +{ + static int last = TK_USER; + return last++; +} + + +static char *lexbuf = NULL; +static int lexbuf_length = 0; + + +static int lexbuf_realloc(int len) +{ + char *nsb; + lexbuf_length = len * 5 / 4; + nsb = (char *)realloc(lexbuf, lexbuf_length + 1); + if(!nsb) + { + eel_error("EEL lexer out of memory!"); + return -1; + } + lexbuf = nsb; + return 0; +} + + +static inline int lexbuf_bump(int len) +{ + if(len >= lexbuf_length) + return lexbuf_realloc(len); + return 0; +} + + +void eel_lexer_cleanup(void) +{ + if(eel_current.lval) + { + eel_d_freestring(eel_current.lval); + free(eel_current.lval); + eel_current.lval = NULL; + } + free(lexbuf); + lexbuf = NULL; + lexbuf_length = 0; +} + + +static int skipwhite(int report_eoln) +{ + int c; + /* Ignore whitespace and get first nonwhite character. */ + while((c = bio_getchar(eel_current.bio)) == ' ' || c == '\t' || + c == '\r' || c == '\n') + if((c == '\n') && report_eoln) + return c; + return c; +} + + +static eel_data_t *newdata(eel_datatypes_t type) +{ + eel_data_t *d = (eel_data_t *)calloc(1, sizeof(eel_data_t)); + if(!d) + return NULL; + d->type = type; + return d; +} + + +static int get_figure(bio_file_t *h, int base) +{ + int n = bio_getchar(h); + if(n >= '0' && n <= '9') + n -= '0'; + else if(n >= 'a' && n <= 'z') + n -= 'a'; + else if(n >= 'A' && n <= 'Z') + n -= 'A'; + else + return -1; + if(n >= base) + return -1; + return n; +} + + +static int get_num(bio_file_t *h, int base, int figures) +{ + int value = 0; + while(figures--) + { + int n = get_figure(h, base); + if(n < 0) + return n; + value *= base; + value += n; + } + return value; +} + + +/* + * Parse quoted string. + * C printf "backslash codes" are supported, + * as well as "\dXXX", for decimal codes. + */ +static int parse_string(bio_file_t *h) +{ + int c, len = 0; + while((c = bio_getchar(h)) != '"') + { + switch(c) + { + case EOF: + eel_error("EOF inside string literal!"); + return TK_ERROR; + case '\\': + c = bio_getchar(h); + switch(c) + { + case EOF: + eel_error("EOF inside string escape sequence!"); + return -1; + case '0': + c = get_num(h, 8, 3); + if(c < 0) + { + eel_error("Illegal octal figure!"); + return TK_ERROR; + } + break; + case 'a': + c = '\a'; + break; + case 'b': + c = '\b'; + break; + case 'c': + c = '\0'; + break; + case 'd': + c = get_num(h, 10, 2); + if(c < 0) + { + eel_error("Illegal decimal figure!"); + return TK_ERROR; + } + break; + case 'f': + c = '\f'; + break; + case 'n': + c = '\n'; + break; + case 'r': + c = '\r'; + break; + case 't': + c = '\t'; + break; + case 'v': + c = '\v'; + break; + case 'x': + c = get_num(h, 16, 2); + if(c < 0) + { + eel_error("Illegal hex figure!"); + return TK_ERROR; + } + break; + default: + break; + } + break; + default: + break; + } + lexbuf_bump(len + 1); + lexbuf[len++] = c; + } + lexbuf[len] = 0; + eel_current.lval = newdata(EDT_STRING); + if(!eel_current.lval) + return TK_ERROR; + eel_d_setstring(eel_current.lval, lexbuf); + return TK_STRN; +} + + +static inline int token(int tk) +{ + eel_current.token = tk; + return tk; +} + +/* + * Pass 1 for 'report_eoln' to get '\n' back whenever a + * newline occurs in the source. + * + * Note that newlines inside comments are *always* treated + * as white space! + */ +int eel_lex(int report_eoln) +{ + int c, prevc; + int negative = 0, directive = 0; + bio_file_t *h = eel_current.bio; + eel_symbol_t *s; + + /* Handle eel_unlex() pushbacks */ + if(eel_current.unlexed) + { + eel_current.unlexed = 0; + return eel_current.token; + } + + /* In case someone should ignore an lval... */ + if(eel_current.lval) + { + eel_d_freestring(eel_current.lval); + free(eel_current.lval); + eel_current.lval = NULL; + } + + while(1) + { + c = skipwhite(report_eoln); + if(c == EOF) + return token(0); + + /* /X comment tokens */ + if(c == '/') + { + switch ((c = bio_getchar(h))) + { + case '/': /* C++ style single line comment */ + while(EOF != (c = bio_getchar(h))) + if('\n' == c) + break; + continue; + case '*': /* C style comment */ + prevc = 0; + while(EOF != (c = bio_getchar(h))) + { + if(('/' == c) && ('*' == prevc)) + break; + else + prevc = c; + } + continue; + default: + bio_ungetc(h); + c = '/'; + break; + } + } + break; + } + + /* + * Char starts a number => parse the number. + * Note: This never returns an EDT_INTEGER! + */ + if(c == '.' || isdigit(c)) + { + bio_ungetc(h); + eel_current.lval = newdata(EDT_REAL); + if(!eel_current.lval) + return token(TK_ERROR); + eel_current.lval->value.r = bio_strtod(h); + if(negative) + eel_current.lval->value.r = -eel_current.lval->value.r; + return token(TK_RNUM); + } + + negative = 0; + + /* + * (Multi)character literal (cast to integer) + * Note that this is always little endian, so + * it's safe to use for "FourCC" identifiers + * and the like. + */ + if('\'' == c) + { + eel_current.lval = newdata(EDT_INTEGER); + if(!eel_current.lval) + return token(TK_ERROR); + eel_current.lval->value.i = 0; + while((c = bio_getchar(h)) != '\'') + { + if(EOF == c) + { + eel_error("EOF inside character literal!"); + return token(TK_ERROR); + } + eel_current.lval->value.i <<= 8; + eel_current.lval->value.i |= c; + } + return token(TK_INUM); + } + + /* String literal */ + if('"' == c) + return token(parse_string(h)); + + /* Check for "preprocessor" directives */ + if('#' == c) + { + directive = 1; + c = bio_getchar(h); + } + + /* Char starts an identifier => read the name. */ + if(isalpha(c) || ('_' == c)) + { + int len = 1; + int start = bio_tell(h) - 1; + while((isalnum(c = bio_getchar(h)) || ('_' == c)) && (EOF != c)) + ++len; + + if(lexbuf_bump(len) < 0) + return token(TK_ERROR); + bio_seek(h, start, SEEK_SET); + bio_read(h, lexbuf, len); + lexbuf[len] = '\0'; + + if(directive) + { + directive = 0; + s = eel_s_find_n_t(NULL, lexbuf, EST_DIRECTIVE); + if(!s) + { + eel_error("Unknown directive '%s'!", + lexbuf); + return token(TK_ERROR); + } + if(s->type != EST_DIRECTIVE) + { + eel_error("Preprocessor directive expected!"); + return token(TK_ERROR); + } + eel_current.lval = newdata(EDT_SYMREF); + eel_current.lval->value.sym = s; + return token(TK_SYMREF); + } + else + { + s = eel_s_find(NULL, lexbuf); + if(s) + { + eel_current.lval = newdata(EDT_SYMREF); + eel_current.lval->value.sym = s; + return token(TK_SYMREF); + } + else + { + eel_current.lval = newdata(EDT_SYMNAME); + eel_d_setstring(eel_current.lval, lexbuf); + return token(TK_NEWSYM); + } + } + } + + /* Look for valid operator characters */ + if(strchr("+-*/^<>~&%@!|$", (char)c)) + { + lexbuf[0] = c; + lexbuf[1] = 0; + s = eel_s_find_n_t(NULL, lexbuf, EST_OPERATOR); + if(!s) + { + eel_error("Unknown operator '%s'!", lexbuf); + return token(TK_ERROR); + } + eel_current.lval = newdata(EDT_SYMREF); + eel_current.lval->value.sym = s; + return token(TK_SYMREF); + } + + return token(c); +} + + +void eel_unlex(void) +{ + eel_current.unlexed = 1; +} diff --git a/eel/e_lexer.h b/eel/e_lexer.h new file mode 100644 index 0000000..4e9d1b8 --- /dev/null +++ b/eel/e_lexer.h @@ -0,0 +1,65 @@ +/*(LGPL) +--------------------------------------------------------------------------- + e_lexer.h - EEL engine lexer +--------------------------------------------------------------------------- + * Copyright (C) 2002, David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _EEL_LEXER_H_ +#define _EEL_LEXER_H_ + +#include "eel.h" + + +/*---------------------------------------------------------- + Tokens and Unique User Token management +----------------------------------------------------------*/ + +/* Errors... */ +#define TK_ERROR -1 /* Lexer complains about something */ + +/* Immediate arguments */ +#define TK_RNUM 300 /* Real number */ +#define TK_INUM 301 /* Integer number */ +#define TK_STRN 302 /* String literal */ + +/* Symbol reference */ +#define TK_SYMREF 303 + +/* New symbol */ +#define TK_NEWSYM 304 + +#define TK_USER 1024 + +int eel_get_unique_token(); + + +/*---------------------------------------------------------- + The Lexer +----------------------------------------------------------*/ +/* Get next "token" */ +int eel_lex(int report_eoln); + +/* + * Push back last token + lval. + * Works only for *one* token per context! + */ +void eel_unlex(void); + +void eel_lexer_cleanup(void); + +#endif /*_EEL_LEXER_H_*/ diff --git a/eel/e_path.c b/eel/e_path.c new file mode 100644 index 0000000..f3871db --- /dev/null +++ b/eel/e_path.c @@ -0,0 +1,60 @@ +/*(LGPL) +--------------------------------------------------------------------------- + e_path.c - EEL file +--------------------------------------------------------------------------- + * Copyright (C) 2002, David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + +#include "eel.h" + + +/*---------------------------------------------------------- + File System Interface (Hah! :-) +----------------------------------------------------------*/ + +static char *_eel_path = NULL; + + +void eel_set_path(const char *path) +{ + if(_eel_path) + free(_eel_path); + if(path) + _eel_path = strdup(path); + else + _eel_path = NULL; +} + + +const char *eel_path(void) +{ + if(!_eel_path) + { +#if defined(WIN32) + eel_set_path(""); +#elif defined(MACOS) + eel_set_path(""); +#else + eel_set_path("./"); +#endif + } + return _eel_path; +} + diff --git a/eel/e_register.c b/eel/e_register.c new file mode 100644 index 0000000..e62e1af --- /dev/null +++ b/eel/e_register.c @@ -0,0 +1,89 @@ +/*(LGPL) +--------------------------------------------------------------------------- + e_register.c - EEL extension registry +--------------------------------------------------------------------------- + * Copyright (C) 2002, David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "e_register.h" +#include "e_symtab.h" +#include "e_lexer.h" + +eel_symbol_t *_register(const char *name, eel_symtypes_t stype, + eel_datatypes_t type) +{ + eel_symbol_t *s = eel_s_new(name, stype); + if(!s) + return (eel_symbol_t *)0; + s->data.type = type; + return s; +} + + +int eel_register_operator(const char *name, eel_operator_cb_t handler, + int priority, int retargs, int preargs) +{ + eel_symbol_t *s = _register(name, EST_OPERATOR, EDT_OPERATOR); + if(!s) + return -1; + + s->token = eel_get_unique_token(); + s->data.value.op.priority = priority; + s->data.value.op.retargs = retargs; + s->data.value.op.preargs = preargs; + s->data.value.op.cb = handler; + return s->token; +} + + +int eel_register_enum_class(void) +{ + return eel_get_unique_token(); +} + + +int eel_register_enum(int eclass, const char *name, int value) +{ + eel_symbol_t *s = _register(name, EST_ENUM, EDT_INTEGER); + if(!s) + return -1; + s->token = eclass; + s->data.value.i = value; + return 0; +} + + +int eel_register_directive(const char *name, eel_parser_cb_t parser) +{ + eel_symbol_t *s = _register(name, EST_DIRECTIVE, EDT_DIRECTIVE); + if(!s) + return -1; + s->token = eel_get_unique_token(); + s->data.value.parse = parser; + return 0; +} + + +int eel_register_special(const char *name, eel_parser_cb_t parser) +{ + eel_symbol_t *s = _register(name, EST_SPECIAL, EDT_SPECIAL); + if(!s) + return -1; + s->token = eel_get_unique_token(); + s->data.value.parse = parser; + return 0; +} diff --git a/eel/e_register.h b/eel/e_register.h new file mode 100644 index 0000000..458cf47 --- /dev/null +++ b/eel/e_register.h @@ -0,0 +1,96 @@ +/*(LGPL) +--------------------------------------------------------------------------- + e_register.h - EEL extension registry +--------------------------------------------------------------------------- + * Copyright (C) 2002, David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _EEL_REGISTER_H_ +#define _EEL_REGISTER_H_ + +#include "eel.h" + +/*---------------------------------------------------------- + Language Extension API +----------------------------------------------------------*/ + +/* + * Register an EEL operator. ("The real thing") + * + * (This is the "direct to the metal" interface; you may want + * to use eel_register_cmd_operator(), eel_register_func_operator() + * or eel_register_math_operator() instead most of the time.) + * + * The callback should check the types and number of + * arguments (easily done with eel_get_args()), and return + * 1 upon success, -1 in case of an error, or 0 if the script + * should be terminated. + * + * Operator precendence in expressions is controlled by means + * of operator priorities specified when operators are + * registered. EEL built-in operators also have priorities, + * and these are of course put in relation to the ones + * specified for extension operators; + * '=' (assignment) 0 (always lowest) + * '+' '-' (add, sub) 10 + * '*' '/' '%' (mul, div, mod) 20 + * '^' (power) 30 + * (command and function operators) 100 + * + * 'retargs' is the number of return arguments, and 'preargs' + * is the number of arguments that must be placed *before* the + * operator token. (Only normal, "post operator token" argument + * lists can be variable length!) + * + * The return value is the command's unique token, or a + * negative value upon failure. + */ +int eel_register_operator(const char *name, eel_operator_cb_t handler, + int priority, int retargs, int preargs); + +/* Register a new enum class. The unique token is returned. */ +int eel_register_enum_class(void); + +/* + * Add enum constant to specified enum class. + * + * A negative value is returned if the operation fails. + */ +int eel_register_enum(int eclass, const char *name, int value); + +/* + * Register a directive. + * + * A directive is similar to a command, but can optionally be + * invoked with a '#' before it's name. It does argument + * parsing itself, which provides more detailed control. + * + * A negative value is returned if the operation fails. + */ +int eel_register_directive(const char *name, int (*parser)(void)); + +/* + * Register a special. + * + * A special does argument parsing itself, like a directive, + * but the # syntax is not valid. + * + * A negative value is returned if the operation fails. + */ +int eel_register_special(const char *name, int (*parser)(void)); + +#endif /*_EEL_REGISTER_H_*/ diff --git a/eel/e_script.c b/eel/e_script.c new file mode 100644 index 0000000..71e9f73 --- /dev/null +++ b/eel/e_script.c @@ -0,0 +1,159 @@ +/*(LGPL) +--------------------------------------------------------------------------- + e_script.c - EEL source code management +--------------------------------------------------------------------------- + * Copyright (C) 2002, David Olofson + * Copyright (C) 2002, Florian Schulze + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include + +#include "config.h" +#include "_e_script.h" +#include "e_util.h" + +#define DBG(x) + + +/*---------------------------------------------------------- + Script source management +----------------------------------------------------------*/ + +script_t eel_scripttab[MAX_SCRIPTS]; + +int eel_script_alloc() +{ + int h = 0; + while(h < MAX_SCRIPTS) + { + if(!eel_scripttab[h].data) + return h; + ++h; + } + return -1; +} + + +int eel_load(const char *filename) +{ + FILE *f; + int h = eel_script_alloc(); + if(h < 0) + return h; + + /* Construct full name with path */ + eel_scripttab[h].name = malloc(strlen(filename) + + strlen(eel_path()) + 2); + if(!eel_scripttab[h].name) + return -1; + strcpy(eel_scripttab[h].name, eel_path()); +#ifdef WIN32 + strcat(eel_scripttab[h].name, "\\"); +#elif defined MACOS + strcat(eel_scripttab[h].name, ":"); +#else + strcat(eel_scripttab[h].name, "/"); +#endif + strcat(eel_scripttab[h].name, filename); + + f = fopen(eel_scripttab[h].name, "rb"); + if(!f) + return -1; + + if(fseek(f, 0, SEEK_END) == 0) + { + eel_scripttab[h].len = ftell(f); + if(fseek(f, 0, SEEK_SET) == 0) + { + eel_scripttab[h].data = (unsigned char *)malloc( + eel_scripttab[h].len + 1); + if(eel_scripttab[h].data) + { + if(fread(eel_scripttab[h].data, + eel_scripttab[h].len, + 1, f) == 1) + { + fclose(f); + DBG(log_printf(DLOG, "Loaded script \"%s\"." + " (Handle %d)\n", + eel_scripttab[h].name, + h);) + return h; + } + DBG(printf("eel_load(): Read error!\n");) + eel_free(h); + } + DBG(printf("eel_load(): Memory allocation error!\n");) + } + DBG(printf("eel_load(): Rewind error!\n");) + } + DBG(printf("eel_load(): Seek-to-end error!\n");) + fclose(f); + return -2; +} + + +int eel_load_from_mem(const char *script, unsigned len) +{ + char name_buffer[128]; + int h = eel_script_alloc(); + if(h < 0) + return h; + + /* Construct name */ + snprintf(name_buffer, 127, "mem_script (%p, %u)", script, len); + name_buffer[127] = '\0'; + eel_scripttab[h].name = (char *)malloc(strlen(name_buffer) + 1); + if(!eel_scripttab[h].name) + return -1; + + strcpy(eel_scripttab[h].name, name_buffer); + + eel_scripttab[h].len = len; + eel_scripttab[h].data = + (unsigned char *)malloc(eel_scripttab[h].len + 1); + if(!eel_scripttab[h].data) + { + DBG(printf("eel_load_from_mem(): Memory allocation error!\n");) + return -2; + } + memcpy(eel_scripttab[h].data, script, len); + DBG(printf("Loaded script \"%s\" (Handle %d)\n", + eel_scripttab[h].name, h);) + return h; +} + + +void eel_free(int handle) +{ + if(handle < 0) + return; + if(handle > MAX_SCRIPTS) + return; + if(!eel_scripttab[handle].data) + return; + + DBG(printf("Freeing script \"%s\". (Handle %d)\n", + eel_scripttab[handle].name, handle);) + free(eel_scripttab[handle].data); + eel_scripttab[handle].data = NULL; + free(eel_scripttab[handle].name); + eel_scripttab[handle].name = NULL; + eel_scripttab[handle].len = 0; +} diff --git a/eel/e_script.h b/eel/e_script.h new file mode 100644 index 0000000..b7c6e03 --- /dev/null +++ b/eel/e_script.h @@ -0,0 +1,29 @@ +/*(LGPL) +--------------------------------------------------------------------------- + e_script.h - EEL source code management (API) +--------------------------------------------------------------------------- + * Copyright (C) 2002, David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _EEL_SCRIPT_H_ +#define _EEL_SCRIPT_H_ + +int eel_load(const char *filename); +int eel_load_from_mem(const char *script, unsigned len); +void eel_free(int handle); + +#endif /*_EEL_SCRIPT_H_*/ diff --git a/eel/e_symtab.c b/eel/e_symtab.c new file mode 100644 index 0000000..8947423 --- /dev/null +++ b/eel/e_symtab.c @@ -0,0 +1,444 @@ +/*(LGPL) +--------------------------------------------------------------------------- + symtab.c - Simple symbol table for EEL +--------------------------------------------------------------------------- + * Copyright (C) 2000-2003, 2007 David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "config.h" + +#include +#include +#include + +#include "kobolog.h" +#include "e_symtab.h" + +#define DBG(x) + +#define STRINGREP_SIZE 128 + +#define MAX_SCOPES 32 + + +/*------------------------------------------------ + Data container +------------------------------------------------*/ + +int eel_d_copy(eel_data_t *data, const eel_data_t *from) +{ + eel_d_freestring(data); + switch (from->type) + { + case EDT_ILLEGAL: + case EDT_REAL: + case EDT_INTEGER: + case EDT_CADDR: + case EDT_SYMREF: + case EDT_SYMTAB: + case EDT_OPERATOR: + case EDT_DIRECTIVE: + case EDT_SPECIAL: + *data = *from; + return 1; + case EDT_STRING: + case EDT_SYMNAME: + data->type = from->type; + return eel_d_setstring(data, from->value.s); + } + return -1; +} + +int eel_d_setstring(eel_data_t *data, const char *s) +{ + if((EDT_STRING == data->type) || (EDT_SYMNAME == data->type)) + free(data->value.s); + else + data->type = EDT_STRING; + data->value.s = (char *)malloc(strlen(s) + 1); + if(data->value.s < 0) + return -1; + strcpy(data->value.s, s); + return 0; +} + +void eel_d_grabstring(eel_data_t *data, char *s) +{ + if((EDT_STRING == data->type) || (EDT_SYMNAME == data->type)) + free(data->value.s); + else + data->type = EDT_STRING; + data->value.s = s; +} + +void eel_d_freestring(eel_data_t *data) +{ + if((data->type != EDT_STRING) && (data->type != EDT_SYMNAME)) + return; + free(data->value.s); + data->value.s = 0; +} + +/* NOTE: Output string only valid until next call. */ +const char *eel_d_stringrep(eel_data_t * data) +{ + static char buf[STRINGREP_SIZE]; + switch (data->type) + { + case EDT_ILLEGAL: + return ""; + case EDT_REAL: + snprintf(buf, STRINGREP_SIZE, "%.10g", data->value.r); + return buf; + case EDT_INTEGER: + snprintf(buf, STRINGREP_SIZE, "%d", data->value.i); + return buf; + case EDT_STRING: + case EDT_SYMNAME: + if(data->value.s) + { + strncpy(buf, data->value.s, STRINGREP_SIZE); + return buf; + } + else + return ""; + case EDT_SYMTAB: + return ""; + case EDT_CADDR: + snprintf(buf, STRINGREP_SIZE, "%x", data->value.a); + return buf; + case EDT_SYMREF: + return eel_s_stringrep(data->value.sym); + case EDT_OPERATOR: + if(data->value.s) + { + snprintf(buf, STRINGREP_SIZE, "(%s)", + data->value.s); + return buf; + } + else + return ""; + case EDT_DIRECTIVE: + if(data->value.s) + { + snprintf(buf, STRINGREP_SIZE, "(#%s)", + data->value.s); + return buf; + } + else + return ""; + case EDT_SPECIAL: + if(data->value.s) + { + snprintf(buf, STRINGREP_SIZE, "(%s)", + data->value.s); + return buf; + } + else + return ""; + default: + return ""; + } +} + + +/*------------------------------------------------ + Symbol table +------------------------------------------------*/ + +/* The symbol table: a chain of `struct symrec'. */ +static eel_symbol_t *eel_s_table[MAX_SCOPES]; + +static int _current_scope = 0; +static int _deepest_scope = 0; + + +int eel_s_open(void) +{ + memset(eel_s_table, 0, sizeof(eel_s_table)); + _current_scope = 0; + _deepest_scope = 0; + return 0; +} + + +void eel_s_close(void) +{ + eel_s_freeall(); +} + + +eel_symbol_t *eel_s_new(const char *name, eel_symtypes_t type) +{ + eel_symbol_t *sym; + sym = (eel_symbol_t *) calloc(1, sizeof(eel_symbol_t)); + if(!sym) + { + log_printf(ELOG, "eel_s_new: Out of memory!\n"); + return 0; + } + sym->name = strdup(name); + sym->type = type; + switch (type) + { + case EST_UNDEFINED: + break; + case EST_CONSTANT: + case EST_VARIABLE: + sym->data.type = EDT_REAL; /* Default type */ + break; + case EST_LABEL: + case EST_FUNCTION: + sym->data.type = EDT_CADDR; + break; + case EST_OPERATOR: + sym->data.type = EDT_OPERATOR; + break; + case EST_DIRECTIVE: + sym->data.type = EDT_DIRECTIVE; + break; + case EST_SPECIAL: + sym->data.type = EDT_SPECIAL; + break; + case EST_ENUM: + sym->data.type = EDT_INTEGER; /* For the value */ + break; + case EST_NAMESPACE: + sym->data.type = EDT_SYMTAB; + default: + log_printf(ELOG, "internal error: created" + " symbol of undef type\n"); + } + sym->next = (struct eel_symbol_t *)eel_s_table[_current_scope]; + eel_s_table[_current_scope] = sym; + return sym; +} + +static void _free_scope(int scope) +{ + eel_symbol_t *sym, *nextptr; + for(sym = eel_s_table[scope]; sym; sym = nextptr) + { + nextptr = (eel_symbol_t *) sym->next; + eel_d_freestring(&sym->data); + free(sym->name); + free(sym); + } + eel_s_table[scope] = (eel_symbol_t *)0; +} + +void eel_s_freeall(void) +{ + int scope; + for(scope = 0; scope < MAX_SCOPES; ++scope) + _free_scope(scope); +} + +eel_symbol_t *eel_s_find(eel_symbol_t * sym, const char *eel_s_name) +{ + int scope = _current_scope; + while(scope >= 0) + { + if(!sym) + sym = eel_s_table[scope]; + for(; sym; sym = (eel_symbol_t *) sym->next) + if(strcmp(sym->name, eel_s_name) == 0) + return sym; + sym = NULL; + --scope; + } + return NULL; +} + +eel_symbol_t *eel_s_find_n_tk(eel_symbol_t * sym, const char *eel_s_name, int token) +{ + int scope = _current_scope; + while(scope >= 0) + { + if(!sym) + sym = eel_s_table[scope]; + for(; sym; sym = (eel_symbol_t *) sym->next) + if((sym->token == token) && + (strcmp(sym->name, eel_s_name) == 0)) + return sym; + sym = NULL; + --scope; + } + return NULL; +} + +eel_symbol_t *eel_s_find_tk(eel_symbol_t * sym, int token) +{ + int scope = _current_scope; + while(scope >= 0) + { + if(!sym) + sym = eel_s_table[scope]; + for(; sym; sym = (eel_symbol_t *) sym->next) + if(sym->token == token) + return sym; + sym = NULL; + --scope; + } + return NULL; +} + +eel_symbol_t *eel_s_find_n_t(eel_symbol_t * sym, const char *eel_s_name, + eel_symtypes_t type) +{ + int scope = _current_scope; + while(scope >= 0) + { + if(!sym) + sym = eel_s_table[scope]; + for(; sym; sym = (eel_symbol_t *) sym->next) + if((sym->type == type) && + (strcmp(sym->name, eel_s_name) == 0)) + return sym; + --scope; + } + return NULL; +} + +eel_symbol_t *eel_s_find_t(eel_symbol_t * sym, eel_symtypes_t type) +{ + int scope = _current_scope; + while(scope >= 0) + { + if(!sym) + sym = eel_s_table[scope]; + for(; sym; sym = (eel_symbol_t *) sym->next) + if(sym->type == type) + return sym; + --scope; + } + return NULL; +} + +/* NOTE: Output string only valid until next call. */ +const char *eel_s_stringrep(eel_symbol_t * sym) +{ + static char buf[STRINGREP_SIZE]; + switch (sym->type) + { + case EST_UNDEFINED: + snprintf(buf, STRINGREP_SIZE, "", + sym->name); + return buf; + case EST_CONSTANT: + strncpy(buf, eel_d_stringrep(&sym->data), STRINGREP_SIZE); + return buf; + case EST_VARIABLE: + case EST_LABEL: + case EST_FUNCTION: + case EST_OPERATOR: + case EST_DIRECTIVE: + case EST_SPECIAL: + case EST_ENUM: + case EST_NAMESPACE: + strncpy(buf, sym->name, STRINGREP_SIZE); + return buf; + default: + return ""; + } +} + + +/*------------------------------------------------ + Scope/Namespace Management +------------------------------------------------*/ + +int eel_push_scope(void) +{ + if(_deepest_scope >= MAX_SCOPES-1) + { + log_printf(ELOG, "EEL ERROR: Too deep scope nesting!\n"); + return -1; + } + ++_deepest_scope; + _current_scope = _deepest_scope; + DBG(log_printf(DLOG, "eel_push_scope(): current scope = %d\n", _current_scope);) + return 0; +} + + +int eel_pop_scope(void) +{ + if(!_deepest_scope) + { + log_printf(ELOG, "EEL ERROR: Tried to pop root scope!\n"); + return -1; + } + _free_scope(_deepest_scope); + --_deepest_scope; + _current_scope = _deepest_scope; + DBG(log_printf(DLOG, "eel_pop_scope(): current scope = %d\n", _current_scope);) + return 0; +} + + +int eel_scope(void) +{ + return _current_scope; +} + + +int eel_set_scope(int ns) +{ + if(ns < 0 || ns > _deepest_scope) + { + log_printf(ELOG, "EEL ERROR: Tried to select illegal scope!\n"); + return -1; + } + _current_scope = ns; + return 0; +} + + +void eel_restore_scope(void) +{ + _current_scope = _deepest_scope; +} + + +/*------------------------------------------------ + Symbol table tools +------------------------------------------------*/ + +eel_symbol_t *eel_s_get(const char *name, eel_symtypes_t type) +{ + eel_symbol_t *sym = eel_s_find(NULL, name); + if(sym) + { + if(sym->type == type) + return sym; + else + { + log_printf(ELOG, "eel_s_integer: '%s' is of" + " the wrong type!\n", name); + return NULL; + } + } + else + return eel_s_new(name, type); +} + + +int eel_s_set(eel_symbol_t *sym, const eel_data_t *dat) +{ + return eel_d_copy(&sym->data, dat); +} diff --git a/eel/e_symtab.h b/eel/e_symtab.h new file mode 100644 index 0000000..3a0bea1 --- /dev/null +++ b/eel/e_symtab.h @@ -0,0 +1,239 @@ +/*(LGPL) +--------------------------------------------------------------------------- + symtab.h - Simple symbol table for EEL +--------------------------------------------------------------------------- + * Copyright (C) 2000, 2002, David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _EEL_SYMTAB_H_ +#define _EEL_SYMTAB_H_ + + +/*------------------------------------------------ + Data container +------------------------------------------------*/ + +struct eel_symbol_table_t; +struct eel_symbol_t; +struct eel_data_t; + +typedef int (*eel_operator_cb_t)(int argc, struct eel_data_t *argv); +typedef int (*eel_parser_cb_t)(void); + +/* Native datatypes */ +typedef enum +{ + EDT_ILLEGAL = 0, + EDT_REAL, /* Real */ + EDT_INTEGER, /* Integer */ + EDT_STRING, /* String */ + EDT_CADDR, /* Code address */ + EDT_SYMREF, /* Symbol reference */ + EDT_SYMTAB, /* Symbol Table Reference (for namespaces) */ + EDT_SYMNAME, /* Name of a new symbol (String) */ + EDT_OPERATOR, /* Operator callback */ + EDT_DIRECTIVE, /* Directive parser callback */ + EDT_SPECIAL /* Special parser callback */ +} eel_datatypes_t; + +#define EDTM_ILLEGAL (1< callback; token = priority */ + EST_DIRECTIVE, /* data -> callback */ + EST_SPECIAL, /* data -> callback */ + EST_ENUM, /* token = enum type; data.i = enum value */ + EST_NAMESPACE /* data -> namespace symbol table */ +} eel_symtypes_t; + +#define ESTM_UNDEFINED (1< +#include +#include + +#include "kobolog.h" +#include "e_util.h" +#include "eel.h" + +#include "_e_script.h" + + +/*---------------------------------------------------------- + "stdio" style API for raw memory buffers +----------------------------------------------------------*/ + +bio_file_t *bio_open(void *data, int len) +{ + bio_file_t *bio = malloc(sizeof(bio_file_t)); + if(!bio) + return NULL; + bio->data = (unsigned char *)data; + bio->len = len; + bio->pos = 0; + return bio; +} + + +bio_file_t *bio_clone(bio_file_t *bio) +{ + bio_file_t *c = malloc(sizeof(bio_file_t)); + if(!c) + return NULL; + *c = *bio; + return c; +} + + +void bio_close(bio_file_t *bio) +{ + free(bio); +} + + +int bio_seek(bio_file_t *bio, int offset, int whence) +{ + switch(whence) + { + case SEEK_SET: + bio->pos = offset; + break; + case SEEK_CUR: + bio->pos += offset; + break; + case SEEK_END: + bio->pos = bio->len - offset; + break; + } + if(bio->pos < 0) + bio->pos = 0; + else if(bio->pos > bio->len) + bio->pos = bio->len; + return 0; +} + + +int bio_read(bio_file_t *bio, char *buf, int count) +{ + if(bio->pos + count > bio->len) + count = bio->len - bio->pos; + memcpy(buf, bio->data + bio->pos, count); + bio->pos += count; + return count; +} + + +double bio_strtod(bio_file_t *bio) +{ + char *p = (char *)bio->data + bio->pos; + double val; + val = strtod(p, &p); + bio->pos = p - (char *)bio->data; + return val; +} + + +/*---------------------------------------------------------- + Context management ("VM stack") +----------------------------------------------------------*/ + +eel_context_t eel_current = { + NULL, + NULL, + -1, + 0, + 0, + EOF, + NULL +}; + +static eel_context_t *context_stack = NULL; + + +void eel_push_context(void) +{ + eel_context_t *c = malloc(sizeof(eel_context_t)); + if(!c) + { + eel_error("INTERNAL ERROR: Failed to push context!"); + return; + } + memcpy(c, &eel_current, sizeof(eel_context_t)); + c->previous = context_stack; + context_stack = c; +} + + +void eel_pop_context(void) +{ + eel_context_t *c = context_stack; + if(!c) + { + eel_error("INTERNAL ERROR: No context to pop!"); + return; + } + memcpy(&eel_current, c, sizeof(eel_context_t)); + context_stack = c->previous; + if(c->lval) + { + eel_d_freestring(c->lval); + free(c->lval); + } + free(c); +} + + + +/*---------------------------------------------------------- + Error handling tools +----------------------------------------------------------*/ + +static int last_script = -1; + +int eel_error(const char *format, ...) +{ + int count = 0; + va_list args; + int i, pos, line = 1; + + /* Figure out which line we're at... */ + pos = bio_tell(eel_current.bio); + bio_seek(eel_current.bio, 0, SEEK_SET); + for(i = 0; i < pos; ++i) + if('\n' == bio_getchar(eel_current.bio)) + ++line; + + if((eel_current.script >= 0) && (eel_current.script != last_script)) + { + count = log_printf(ELOG, "(EEL) in file \"%s\":\n", + eel_scripttab[eel_current.script].name); + last_script = eel_current.script; + } + if(eel_current.arg) + count += log_printf(ELOG, "(EEL) line %d, arg %d: ", + line, eel_current.arg); + else + count += log_printf(ELOG, "(EEL) line %d: ", line); + va_start(args, format); + count += vfprintf(stderr, format, args); + va_end(args); + count += log_printf(ELOG, "\n"); + return count; +} + +const char *eel_symbol_is(eel_symbol_t *s) +{ + switch(s->type) + { + case EST_UNDEFINED: return "an undedined symbol"; + case EST_CONSTANT: return "a constant"; + case EST_VARIABLE: return "a variable"; + case EST_LABEL: return "a label"; + case EST_FUNCTION: return "a function"; + case EST_OPERATOR: return "an operator"; + case EST_DIRECTIVE: return "a directive"; + case EST_SPECIAL: return "a special"; + case EST_ENUM: return "an enum constant"; + case EST_NAMESPACE: return "a namespace"; + } + /* + * Should be here, and not under default:, to get + * a warning if we forget to add new types. :-) + */ + return "a broken symbol! (illegal type)"; +} + +const char *eel_data_is(eel_data_t *d) +{ + switch(d->type) + { + case EDT_ILLEGAL: return "an illegal value"; + case EDT_REAL: return "a real value"; + case EDT_INTEGER: return "an integer value"; + case EDT_STRING: return "a string"; + case EDT_CADDR: return "a code address"; + case EDT_SYMREF: return "a symbol reference"; + case EDT_SYMTAB: return "a symbol table pointer"; + case EDT_SYMNAME: return "a (new) symbol name"; + case EDT_OPERATOR: return "an operator callback pointer"; + case EDT_DIRECTIVE: return "a directive callback pointer"; + case EDT_SPECIAL: return "a special callback pointer"; + } + return "a broken value! (illegal type)"; +} + + diff --git a/eel/e_util.h b/eel/e_util.h new file mode 100644 index 0000000..7124a35 --- /dev/null +++ b/eel/e_util.h @@ -0,0 +1,107 @@ +/*(LGPL) +--------------------------------------------------------------------------- + e_util.h - EEL engine utilities +--------------------------------------------------------------------------- + * Copyright (C) 2002, David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _EEL_UTIL_H_ +#define _EEL_UTIL_H_ + +#include +#include "eel.h" + + +/*---------------------------------------------------------- + "stdio" style API for raw memory buffers +----------------------------------------------------------*/ + +typedef struct bio_file_t +{ + unsigned char *data; + int len; + int pos; +} bio_file_t; + +bio_file_t *bio_open(void *data, int len); +bio_file_t *bio_clone(bio_file_t *bio); +void bio_close(bio_file_t *bio); + +/* Get the next character from the buffer */ +static inline int bio_getchar(bio_file_t *bio) +{ + if(bio->pos < bio->len) + return bio->data[bio->pos++]; + else + return EOF; +} + +/* Push last character back */ +static inline void bio_ungetc(bio_file_t *bio) +{ + if(bio->pos > 0) + --bio->pos; +} + +/* + * Get the current source buffer position + */ +static inline int bio_tell(bio_file_t *bio) +{ + return bio->pos; +} + +/* + * Set the current source buffer position + */ +int bio_seek(bio_file_t *bio, int offset, int whence); + +/* + * Read 'count' bytes from the source code, + * starting at the current position, into + * 'buf'. Returns the number of bytes + * actually read. + */ +int bio_read(bio_file_t *bio, char *buf, int count); + +double bio_strtod(bio_file_t *bio); + + +/*---------------------------------------------------------- + Context management ("VM stack") +------------------------------------------------------------ + * This supports skipping between scripts, and also keeps + * track of the arg count for error messages. + */ + +typedef struct eel_context_t +{ + struct eel_context_t *previous; + bio_file_t *bio; + int script; + int arg; + int unlexed; + int token; + eel_data_t *lval; +} eel_context_t; + +extern eel_context_t eel_current; + +void eel_push_context(void); +void eel_pop_context(void); + +#endif /*_EEL_UTIL_H_*/ diff --git a/eel/eel-comp-src.txt b/eel/eel-comp-src.txt new file mode 100644 index 0000000..0aaec00 --- /dev/null +++ b/eel/eel-comp-src.txt @@ -0,0 +1,89 @@ + + The "EEL Compressed Source" file format + --------------------------------------- + +EEL Compressed Source files are EEL source files stripped of +all comments and formatting information. They are tokenized +using an external dictionary, which contains all keywords of +EEL and extensions, and any project names. Immediate values +are encoded using an extended "variable length number" BCD +format. + +* EEL Compressed Source files should have the extension + ".eec" instead of the normal ".eel", for reliable + identification, and to avoid accidentally overwriting + source files with compressed source files. (That would + be nasty, as the compression is destructive WRT comments, + symbol names and code formatting...) + +* The files are based on 4 bit words. Wider words (8 or 16 + bits) are *not* aligned to 8 or 16 bits, but start + directly at the current 4 bit word position. + +* There are two modes: XASCII and XBCD. Decoding of a file + starts in the XASCII mode. XASCII codes are 8 bits, and + XBCD codes are 4 bits. + +* The file starts with an 8 bit version code for the EEL + dictionary to use. Then follows a list of 4 byte EEL + extension IDs, terminated by a 0 byte. The EEL extension + IDs are of the form "XXXv", where "XXX" is an acronym + identifying the extension, and "v" is the version of the + extension dictionary to use. + + Any extension ID that doesn't math any known EEL + extension is assumed to be a Local Dictionary name. + ".eed" will be appended to the full 4 byte string (no + version code), and then EEL will try to find a file by + that name and load it as a Local Dictionary. + +* A Local Dictionary file consists of a 32 bit little + endian integer that holds the number of tokens needed + by the dictionary, *optionally* followed by a list of + null terminated ASCII strings, holding the human + readable names of all tokens. (The token name list is + useful when mixing compressed source with ASCII source + during development.) + +* Token values are allocated from 0 and up as + dictionaries are loaded. This is why there are + extension version numbers in the dictionary lists - + and it should also make it obvious that EEL extensions + must only *add* to their dictionaries if compatibility + with old compressed sources is to be maintained. + +* XASCII code: + 0-14 XBCD code + enter XBCD mode + + 15 Local token dictionary follows + 16 8 bit character follows + 17 Null terminated 8 bit quoted string + 18 Quoted 8 bit Pascal string follows + 19 Quoted 8 bit Pascal string continued + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + + 32-127 Standard 7 bit ASCII (copied as is) + + 128-191 Short Tokens + 192-254 Extended Tokens (8 extra bits follow) + 255 Wide Tokens (16 extra bits follow) + +* XBCD code: + 0-9 Decimal numbers 0-9 + 10 Decimal point (.) + 11 Unary minus (-) + 12 Argument separator/white space + 13 Statement terminator (;) + 14 Single XASCII character follows + 15 Switch to XASCII mode diff --git a/eel/eel-lang.txt b/eel/eel-lang.txt new file mode 100644 index 0000000..09d5aef --- /dev/null +++ b/eel/eel-lang.txt @@ -0,0 +1,161 @@ + + The Extensible Embeddable Language + ---------------------------------- + + Well, here's a simple extensible scripting language + for ya' - all in a few thousand lines of (hopefully) + portable C code! No external tools needed to build + this version, although future versions might have the + parsing functions replaced with a Bison parser. (You + still won't really need Bison, unless you want to + change the language syntax.) + + Extending the language is done by adding commands, + directives, operators, enums and "specials". It's pretty + much as simple as it gets, without using a custom source + preprocessor. A single scanf() style function call does + argument checking and casting for commands, so you + usually get away with a single call to get all your + arguments. + + The Language: + EEL is CaSe SEnSitIve! + + An EEL file consists of zero or more statements. + + There are (so far) two kinds of statements: Command + Statements and Assignments. + + A Command Statement starts with a command name, + followed by zero or more coma (,) separated arguments, + and is terminated with a semicolon (;). Some commands + accept variable numbers of arguments. + + A command argument may be of any type, which means + that symbol references, command references and other + weird stuff can be passed. + + "Functions" can be implemented as commands that + require one or more arguments to be passed by + reference. (See "set" / '=' command, which is an + example of this.) + + Assignments can be written in two forms; either using + the 'set' command, which takes two arguments; the + target and the source - or the more compact '=' + operator method, is which the target is on the left + side of the '=' operator, and the source is on the + right. +TODO: + "Function commands" can alternatively be called using + the traditional "a = function ...;" style. The + command's first argument should be an output argument, + and preferably the only output argument. (Note that + the *real* set command/'=' operator is not involved!) +/TODO + + Variables are created implicitly as a result of the + first Assignment. (This will probably change...) + + Variables are dynamically typed. Both value and type + may be changed after a variable has been declared. + + EEL strives to use "late casting", which means that + in the normal case, assignments change type as well + as value. +TODO: + The above is somewhat confusing, and will most probably + change. We need a clear distinction between "passing + by value" and "passing by reference", as this becomes + very important in algorithmic code.) +/TODO + + Data types that can be stored in a variable: + Real (64 bit float) + Integer (32 bit signed) + String (Null terminated) + Code Address (Source or bytecode position) + Symbol Reference (Can refer to any symbol) + + Symbol reference variables are quite interesting, as + they can theoretically reference *anything*, including + commands - and all type info is available as an extra + bonus. (Note that most of this is rather useless right + now, as the language doesn't have constructs that can + make use of it!) + + Built-in EEL commands, functions and directives: + end; + End of script. (Same effect as EOF.) + + set , ; + = ; + Set variable to . If + is not yet defined, it will be created + automatically. (This is likely to change.) + + print arg[, arg[,...]]; + Print the arguments in the "standard console". + + procedure ([arg[, arg[,...]]]) { } + function ([arg[, arg[,...]]]) { } + Define procedure 'procname' or function + 'funcname', respectively. The function will + take (as in "require") the specified + (dynamically typed) arguments, and when it's + invoked, the code in between the curly + brackets ('{' and '}') will be executed. + The function *must* return a value, while + the procedure must *not* - that's the only + difference between them. + + When a function or procedure is running, a + local "partition" of the symbol table is used. + Initially, this table contains only the + arguments, but any new variables declared as + the body code executes are added to *this* + table, instead of the global table, as in the + normal case. The "partition" (actually just a + local namespace) is removed as the function + or procedure returns, which obviously means + that the argument variables, as well as any + local variables, are deleted. + + [arg[, arg[,...]]]; + Function invocation. Works just like a + command invocation, although EEL will just + add the arguments to the Local Symbol Table - + it will not perform any type checking, as + argument types aren't supported as of now. + + #include + Run the file 'filename' in the current scope, + and then continue executing the current + script. + + Note that as of now, this is not 100% + compatible with the way a C/C++ preprocessor + works! It's more like loading and executing + a "subroutine script". + + #define + C header compatibility hack for defining + constants. It's mostly there to allow EEL + scripts to share headers with other languages + using C preprocessors, like C or C++. We want + to do that *without* actually using cpp, as + EEL scripts are supposed to load and run from + source without "special tools". + +TODO: + : + Label declaration. Creates a symbol + that contains the Code Address of the + statement following the colon. + +TODO: + i = 0; + for i < 10 + { + ... + } i = i + 1; diff --git a/eel/eel.c b/eel/eel.c new file mode 100644 index 0000000..e128233 --- /dev/null +++ b/eel/eel.c @@ -0,0 +1,573 @@ +/*(LGPL) +--------------------------------------------------------------------------- + eel.c - The "Extensible Embeddable Language" +--------------------------------------------------------------------------- + * Copyright (C) 2002, 2007 David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* +TODO: + * Eliminate the parser and use the expression + evaluator instead. "Everything is an expression." + The evaluator will need a few extra features, but + lots of messy code will be eliminated, and the + design will be much cleaner and more flexible. + + * Make all commands, functions and stuff operators. + Binary commands and operators should use the same + callback prototype. A way of describing return, + reference and input arguments will be needed. (Not + sure about multiple return arguments...) + + * Split the command and operator callbacks up + into one "parser" callback, and one or more + run-time callbacks. Leave argument grabbing/casting + and callback selection to the parser callbacks, for + simplicity and flexibility. (They can still use + tools like the EEL argument grabber.) Let them + generate byte code or similar (using some EEL API + calls) for one or more "operations", as required to + perform the desired actions. + + Interpreting mode could still be implemented, + with some overhead, by compiling and executing one + statement at a time - although IMHO, one might as + well make a complete switch to compiling + VM. + That would eliminate issues with distinguishing + between compiled and interpreted functions and the + like. + + * To make the above work, we'll need a distinction + between compile time and run-time symbols. (In + fact, we don't really need actual symbols at run + time, other than for globals. Local variables + should be allocated from some VM stack.) For + example, some features of the current argument + grabber won't work for compiling, as they rely on + the actual contents of a symbol, to extract data. + Such features will have to be implemented though + run-time callbacks that execute the corresponding + operations. + + * Remove EDT_INTEGER? The lexer currently never + returns TK_INUM except for character literals, + and I'm starting to think it's a good idea to + keep it that way, for various reasons... + + * Functions should return values! Make sure + that errors are issued if a function returns + without an explicit return statement. + + * Add "procedure" keyword for "functions" + without return values. Issue an error if a + "return with value" statement is executed + within a procedure. + + * Implement conditional constructs. + + * Implement '&' ("address" of function) operator. + + * Add a procedure extension(name) to EEL, to allow + scripts to check for extension availability and + version. Should return version #, or 0 if the + extension is not available. There should probably + also be a uses(name), to avoid implicitly stuffing + all available extensions into the name space of + every script. + + * Eliminate all fixed size arrays and limits... + + * Implement the Compressed Source file format. + + */ + +#include "config.h" +#include +#include +#include + +#include "eel.h" +#include "e_lexer.h" +#include "e_util.h" +#include "e_builtin.h" + +#include "_e_script.h" + + +/*---------------------------------------------------------- + Parser/Interpreter +----------------------------------------------------------*/ + +static int command(void) +{ + eel_symbol_t *sym = eel_current.lval->value.sym; + + if(!sym->data.value.op.cb) + { + eel_error("INTERNAL ERROR: Command callback missing!"); + return -1; + } + + if(sym->data.value.op.retargs) + { + eel_error("INTERNAL ERROR: Return value ignored!"); + return -1; + } + + if(eel_parse_args(",", ';') < 0) + return -1; + + return sym->data.value.op.cb(eel_arg_count, eel_args); +} + + +static int assignment(int token) +{ + int res; + + /* Get target */ + switch(token) + { + case TK_SYMREF: + switch (eel_current.lval->value.sym->type) + { + case EST_UNDEFINED: + case EST_VARIABLE: + break; + default: + eel_error("Cannot change the value of %s!", + eel_symbol_is(eel_current.lval->value.sym)); + return -1; + } + case TK_NEWSYM: + if(eel_grab_arg() < 0) + { + eel_error("Argument overflow!"); + return -1; + } + break; +#if 0 + case 0: + eel_error("Unexpected end of file!"); + return -1; + default: + eel_error("Unexpected token!"); + return -1; +#endif + } + + /* Get operator */ + if(eel_lex(0) != '=') + { + eel_error("Expected '='!"); + return -1; + } + + /* Get source */ + if(eel_parse_args(",", ';') < 0) + return -1; + + /* End of declaration; execute! */ + res = eel_cmd_set(eel_arg_count, eel_args); + + return res; +} + + +static int directive(void) +{ + int res; + eel_symbol_t *sym = eel_current.lval->value.sym; + + if(!sym->data.value.parse) + { + eel_error("INTERNAL ERROR: Directive callback missing!"); + return -1; + } + + res = sym->data.value.parse(); + return res; +} + + +static int function(void) +{ + int arg, res; + eel_symbol_t *func = eel_current.lval->value.sym; + + eel_push_scope(); + + /* Grab arguments */ + res = eel_parse_args(",", ';'); + + /* Enter function */ + eel_push_context(); + if(eel_current.script == func->token) + eel_current.bio = bio_clone(eel_current.bio); + else + eel_current.bio = bio_open(eel_scripttab[func->token].data, + eel_scripttab[func->token].len); + if(!eel_current.bio) + { + eel_error("INTERNAL ERROR: Failed to set up script" + " reading at start of function!"); + eel_pop_context(); + eel_pop_scope(); + return -1; + } + res = bio_seek(eel_current.bio, func->data.value.a, SEEK_SET); + + /* + * Find out where to stuff the arguments. + */ + for(arg = 0; (arg < eel_arg_count) && (res >= 0); ) + switch(eel_lex(0)) + { + case ',': + /* Already verified, so we just skip them. */ + break; + case TK_NEWSYM: + { + eel_symbol_t *sym; + sym = eel_set_data(eel_current.lval->value.s, + eel_args + arg); + if(sym) + { + sym->type = EST_VARIABLE; + ++arg; + } + else + { + eel_error("INTERNAL ERROR: Failed to " + "create argument variable!"); + res = -1; + } + break; + } + case TK_SYMREF: + eel_error("Function argument clashes with " + "previously defined symbol!"); + res = -1; + break; + default: + eel_error("Syntax error in argument list!"); + res = -1; + break; + } + + /* Find start of body ("the code") */ + if(res >= 0) + { + if(eel_lex(0) != ')') + { + eel_error("Expected ')'!"); + res = -1; + } + else if(eel_lex(0) != '{') + { + eel_error("Expected '{'!"); + res = -1; + } + } + + if(res >= 0) + { + /* + * Execute function + * + * Note that this is a simple, inefficient + * RECURSIVE implementation! + * + * Alternatively, we could set up a "trigger" + * to run "the rest of this function" when + * the function ends - and then just return. + */ + res = eel_call(eel_current.script, bio_tell(eel_current.bio)); + } + + /* Leave function */ + bio_close(eel_current.bio); + eel_pop_context(); + eel_pop_scope(); + + if(res >= 0) + return 1; + else + return res; +} + + +int eel_call(int handle, int pos) +{ + int res = 1; + int depth = 0; + eel_push_context(); + eel_current.script = handle; + eel_current.bio = bio_open(eel_scripttab[handle].data, + eel_scripttab[handle].len); + if(!eel_current.bio) + { + eel_error("INTERNAL ERROR: Couldn't read script!"); + eel_pop_context(); + return -1; + } + bio_seek(eel_current.bio, pos, SEEK_SET); + + eel_current.lval = NULL; + while(res > 0) + { + /* Start of statement */ + eel_clear_args(0); + eel_current.arg = 0; + switch(eel_lex(0)) + { + case 0: + /* End of script */ + res = 0; + break; + case ';': + /* Empty statement */ + res = 1; + break; + case '{': + /* Begin scope */ + eel_push_scope(); + ++depth; + res = 1; + break; + case '}': + /* End scope */ + if(depth) + { + eel_pop_scope(); + --depth; + } + else + res = 0; + break; + case TK_NEWSYM: + res = assignment(TK_NEWSYM); + break; + case TK_SYMREF: + switch(eel_current.lval->value.sym->type) + { + case EST_CONSTANT: /* Just to get a more + * sensible error message... + */ + case EST_UNDEFINED: + case EST_VARIABLE: + res = assignment(TK_SYMREF); + break; +/* case EST_COMMAND: + res = command(); + break;*/ + case EST_FUNCTION: + res = function(); + break; + case EST_DIRECTIVE: + case EST_SPECIAL: + res = directive(); + break; + case EST_ENUM: + case EST_LABEL: + eel_error("Syntax error!"); + res = -1; + break; + case EST_OPERATOR: + res = command(); + break; + default: + eel_error("INTERNAL ERROR: Lexer returned" + " symbol of illegal type!"); + res = -1; + break; + } + break; + default: + eel_error("Unexpected character!"); + res = -1; + break; + } + } + eel_current.arg = 0; + bio_close(eel_current.bio); + eel_pop_context(); + return res; +} + + +int eel_run(int handle) +{ + return eel_call(handle, 0); +} + + +static int _eel_users = 0; + +int eel_open(void) +{ + if(_eel_users++) + return 0; + + memset(eel_scripttab, 0, sizeof(eel_scripttab)); + + if(eel_s_open() < 0) + { + _eel_users = 0; + return -1; + } + + eel_register_operator("end", eel_cmd_end, 100, 0, 0); + eel_register_operator("set", eel_cmd_set, 100, 0, 0); + eel_register_operator("print", eel_cmd_print, 100, 0, 0); + + eel_register_operator("+", eel_op_add, 10, 0, 1); + eel_register_operator("-", eel_op_sub, 10, 0, 1); + + eel_register_operator("*", eel_op_mul, 20, 0, 1); + eel_register_operator("/", eel_op_div, 20, 0, 1); + eel_register_operator("%", eel_op_mod, 20, 0, 1); + + eel_register_operator("^", eel_op_pow, 30, 0, 1); + + eel_register_directive("include", eel_dir_include); + eel_register_directive("define", eel_dir_define); + + eel_register_special("function", eel_spec_function); + eel_register_special("procedure", eel_spec_procedure); +/* eel_register_special("global", eel_spec_global);*/ + + return 0; +} + +void eel_close() +{ + int h; + if(!_eel_users) + return; + + for(h = 0; h < MAX_SCRIPTS; ++h) + eel_free(h); + + eel_s_freeall(); + eel_set_path(NULL); + eel_s_close(); + eel_lexer_cleanup(); + + --_eel_users; +} + + + +/*---------------------------------------------------------- + EEL variable access +----------------------------------------------------------*/ + +eel_symbol_t *eel_set_integer(const char *name, int value) +{ + eel_symbol_t *sym = eel_s_get(name, EST_VARIABLE); + if(!sym) + return NULL; + eel_d_freestring(&sym->data); + sym->data.type = EDT_INTEGER; + sym->data.value.i = value; + return sym; +} + + +eel_symbol_t *eel_set_real(const char *name, double value) +{ + eel_symbol_t *sym = eel_s_get(name, EST_VARIABLE); + if(!sym) + return NULL; + eel_d_freestring(&sym->data); + sym->data.type = EDT_REAL; + sym->data.value.r = value; + return sym; +} + + +eel_symbol_t *eel_set_string(const char *name, const char *s) +{ + eel_symbol_t *sym = eel_s_get(name, EST_VARIABLE); + if(!sym) + return NULL; + eel_d_setstring(&sym->data, s); + return sym; +} + + +eel_symbol_t *eel_set_data(const char *name, const eel_data_t *dat) +{ + eel_symbol_t *sym = eel_s_get(name, EST_VARIABLE); + if(!sym) + return NULL; + + eel_d_freestring(&sym->data); + switch (dat->type) + { + case EDT_ILLEGAL: + case EDT_REAL: + case EDT_INTEGER: + case EDT_CADDR: + case EDT_SYMREF: + case EDT_SYMTAB: + case EDT_OPERATOR: + case EDT_DIRECTIVE: + case EDT_SPECIAL: + sym->data = *dat; + break; + case EDT_STRING: + case EDT_SYMNAME: + sym->data.type = dat->type; + if(eel_d_setstring(&sym->data, dat->value.s) < 0) + return NULL; + break; + } + return sym; +} + + +eel_symbol_t *eel_clone_symbol(const char *name, const eel_symbol_t *orig) +{ + eel_symbol_t *sym = eel_s_new(name, orig->type); + if(!sym) + return NULL; + + eel_d_freestring(&sym->data); + switch (orig->data.type) + { + case EDT_ILLEGAL: + case EDT_REAL: + case EDT_INTEGER: + case EDT_CADDR: + case EDT_SYMREF: + case EDT_SYMTAB: + case EDT_OPERATOR: + case EDT_DIRECTIVE: + case EDT_SPECIAL: + sym->data = orig->data; + break; + case EDT_STRING: + case EDT_SYMNAME: + sym->data.type = orig->data.type; + if(eel_d_setstring(&sym->data, orig->data.value.s) < 0) + return NULL; + break; + } + return sym; +} diff --git a/eel/eel.h b/eel/eel.h new file mode 100644 index 0000000..05fe855 --- /dev/null +++ b/eel/eel.h @@ -0,0 +1,376 @@ +/*(LGPL) +--------------------------------------------------------------------------- + eel.c - The "Extensible Embeddable Language" +--------------------------------------------------------------------------- + * Copyright (C) 2002, David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* +TODO: + ...or at least think about: Extend the dynamic typing to + include functions. Ex: + + set some_var, some_function; + + will connect 'some_function' to 'some_var', so that the + function is called to calculate the value whenever the + variable is read. Obviously, such a variable becomes + read-only! This could be worked around with the following + syntax: + + set some_var, read_function, write_function; + + A handy syntax extension: + + set some_var, some_function(...); + + or + + set some_other_var, + { + ... + some code + ... + }; + + which would be interpreted as a nameless, single statement + function being connected to 'some_var', and a nameless + function with a normal body being connected to + 'some_other_var'. + + The whole point with this is that it allows the way a + variable gets written to change at run time, and that it's + even applicable to code that isn't aware of this feature. + + BTW, this is pretty similar to Delphi 'properties' - + although you cannot turn variables into properties or vice + versa, at run time, as you could do with this feature. + +---------------------------------------------------------------------- + + Scope/Namespace management sucks. Namespaces probably need + to be arranged in a tree rather than a stack. + + This becomes obvious when considering what happens when you + call a function... The function executes in a scope that's + the calling scope + a local namespace! + + Indeed, this could be considered an interesting "feature", + but I'm not sure it's as useful as it is confusing... + + As a quick hack solution, one could reserve the first few + namespaces (ie highest levels) for language extensions, to + make it easy to install and remove extensions without them + interfering with each other. + + One could possible change the "scope level" into a "scope + handle", and make a scope a "list of namespaces" rather + than the current "lowest namespace index". That would allow + multiple totally independent scopes under the same scripting + engine. + + */ + +#ifndef _EEL_H_ +#define _EEL_H_ + +#include "e_script.h" +#include "e_symtab.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define EEL_MAX_ARGS 128 + +#define _EEL_API_ + +#include "e_register.h" + + +/*---------------------------------------------------------- + Toolkit for directive callbacks +----------------------------------------------------------*/ + +/* + * The internal argument list. Avoid using this directly! + */ +extern int eel_arg_count; +extern eel_data_t *eel_args; + +/* + * Add the last lval returned from the lexer to the internal + * argument list. + */ +int eel_grab_arg(void); + +/* + * Clear the internal argument list starting at argument + * 'first'. + */ +void eel_clear_args(int first); + +/* + * Parse arguments separated by one of the characters in + * 'separators', until the character 'terminator' is + * matched, or an error occurs. + * + * The arguments that are "grabbed" are added to the + * internal argument list using eel_grab_arg(), and can + * be retrieved, decoded and typechecked with eel_get_args() + * if desired. + * + * Returns a negative value in case of an error. + */ +int eel_parse_args(const char *separators, char terminator); + + +/*---------------------------------------------------------- + Toolkit for command callbacks +----------------------------------------------------------*/ + +/* + * Grab arguments from the internal argument list, verifying + * that their types and count are in accordance with 'fmt'. + * Results will be stored in the variables passed by + * reference after the 'fmt' argument. + * + * Normally, the argument count not matching the number of + * arguments specified in the format string will be reported + * as an error. However, this can be changed by means of + * argument tipples and optional arguments, denoted by the + * '<', '>' and '[', ']' characters respectively. + * + * The return value is the number of arguments correctly + * retrieved, or a negative value if something goes wrong. + * + * Format string syntax: + * + * Char Meaning Type + *-------------------------------------------------------------------- + * * Skip argument N/A + * + * , Next argument (optional) N/A + * + * ? Grab any argument as is eel_data_t * + * + * < > Argument tipple. The argument spec in N/A + * between the < and > will be repeated + * until all arguments have been grabbed, + * or an error occurs. The target args + * should be ARRAYS and *must* be large + * enough to fit all arguments retrieved, + * or bad things will happen. Argument + * tipples cannot be nested. There must + * be no argument specifiers after the + * '>', as an argument tipple repeats + * "forever". Normally, the arguments + * must match an *integer* number of + * tipple repetitions - but this can be + * changed using the Optional Argument + * format codes. + * + * [ ] Optional arguments. Arguments beyond N/A + * the '[' character after the 'argv' + * array has been exhausted will not + * generate an error, as this situation + * normally would. + * + * Optional arguments inside argument + * tipples apply only to the *last* + * tipple repetition. + * + * Note that no argument specifiers must + * follow the ']' character - or; optional + * arguments must be the last ones in the + * list. + * + * E Get any enum symbol. Any enum class eel_symbol_t * + * is accepted. (Do check, if you care!) + * + * V Get value of any allowed type. This eel_data_t * + * code can optionally be followed by a + * list of allowed types, enclosed within + * parentheses. If no list is specified, + * all *value* data types are accepted, + * including EDT_CADDR. Available types: + * i integer (EDT_INTEGER) + * r real (EDT_REAL) + * s string (EDT_STRING) + * c code address (EDT_CADDR) + * e enum constant (EDT_SYMREF) + * All but 'e' are set by default, if no + * explicit list is provided. + * + * Note that symrefs are followed, to get + * the values of the symbols they refer to, + * except that when 'e' (enum constant) is + * listed, symrefs to enum constants will + * stay symrefs. + * + * e Get enum value. The argument should be int + * INITIALIZED with the enum class. Only + * enum constants from the right class + * are accepted. + * + * i Get integer value int + * + * n Get or create variable. In the case of eel_symbol_t * + * a new variable being created, the + * argument has to be a string holding the + * name of the new variable. The type of + * a new variable is undefined. + * + * r Get real value double + * + * s Get string value char * + * NOTE: Currently it's NOT possible to + * get non-string values casted to strings. + * (We need a fast, reference counting + * string package...) + * + * v Get variable (must be defined) eel_symbol_t * + * + * f Get function "address". The returned eel_symbol_t * + * symbol will be of type EST_FUNCTION. + * + * Any other character in the format string in matched with that + * respective character in the input. + */ +int eel_get_args(const char *fmt, ...); + + +/* + * Like eel_get_args(), but reads from the specified eel_data_t + * array instead of the internal argument list. + */ +int eel_get_args_from(int argc, struct eel_data_t *argv, const char *fmt, ...); + +/* + * Print a nice error "prompt" with file name, line # + * and arg #, followed by your formatted error message, + * followed by a newline ('\n') where appropriate. (Don't + * add this yourself, unless you need multiple lines.) + * + * Note that syntax checking and most type + * and error checking is done automatically + * by EEL (mostly in eel_get_args()). This + * function is only for errors that EEL + * can't detect. + * + * Returns total number of characters printed. + */ +int eel_error(const char *format, ...); + +/* + * Returns a string describing the specified symbol + * in a way that would complete the sentences: + * "This is ..." + * "Expected ..." + */ +const char *eel_symbol_is(eel_symbol_t *s); + +/* + * As eel_symbol_is(), but for data containers. + */ +const char *eel_data_is(eel_data_t *d); + + + +/*---------------------------------------------------------- + Runtime API +----------------------------------------------------------*/ + +/* + * Set the EEL path for scripts and includes. + * + * This must be a valid path, terminated by a + * '/', '\', ':' or whatever "directory separator" + * the current platform is using, and will be + * prepended to file names passed to the #include + * directive. + */ +void eel_set_path(const char *path); + +/* Returns the current EEL path. */ +const char *eel_path(void); + +/* Open/Close EEL. (Keep track of nested calls!) */ +int eel_open(void); +void eel_close(); + +/* + * Execute code inside script 'handle', starting at 'pos'. + * + * Execution will take place as a "sub procedure", with it's + * own context¨, but *not* automatically it's own *scope*. + * This is because most real applications will require + * scripts to be passed some "arguments", which is actually + * done by creating a few variables before the script is + * called. Obviously, the code that sets up the "argument + * variables" and calls eel_run() will also have to do any + * scope pushing and popping *around* these calls - which is + * why it can't be done inside eel_run(). + * + * The following events will end execution: + * - A statement gives a "stop execution" return code. + * - The top level scope is terminated; ie an unmatched + * curly brace ('}') is found. + * - EOF is reached. + * - An error occurs. + * + * Returns the result, which will be negative in the case + * of an error. + */ +int eel_call(int handle, int pos); + +/* + * Run a script from the start. + * + * Currently 100% equivalent to eel_call('handle', 0); + */ +int eel_run(int handle); + +/* + * Create or set variable 'name' to the specified value. + * Existing symbols *must* be of type ST_VARIABLE, or + * these calls will fail. + * + * Returns the changed/created symbol, or NULL if the + * operation failed. + */ +eel_symbol_t *eel_set_integer(const char *name, int value); +eel_symbol_t *eel_set_real(const char *name, double value); +eel_symbol_t *eel_set_string(const char *name, const char *s); +eel_symbol_t *eel_set_data(const char *name, const eel_data_t *dat); + +/* + * Make an exact copy of symbol 'orig', except for the name, + * which will be 'name'. Symbol 'name' must not exist before + * this call. + * + * Returns the created symbol, or NULL if the operation failed. + */ +eel_symbol_t *eel_clone_symbol(const char *name, const eel_symbol_t *orig); + +#undef _EEL_API_ + +#ifdef __cplusplus +}; +#endif + +#endif /* _EEL_H_ */ diff --git a/enemies.cpp b/enemies.cpp new file mode 100644 index 0000000..81700a0 --- /dev/null +++ b/enemies.cpp @@ -0,0 +1,188 @@ +/* +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 1995, 1996 Akira Higuchi + * Copyright (C) 2001, 2003, 2007 David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include "enemies.h" +#include "random.h" +#include "radar.h" + +_enemy _enemies::enemy[ENEMY_MAX]; +_enemy *_enemies::enemy_max; +const enemy_kind *_enemies::ekind_to_generate_1; +const enemy_kind *_enemies::ekind_to_generate_2; +int _enemies::e1_interval; +int _enemies::e2_interval; +int _enemies::explocount = 0; +int _enemies::is_intro = 0; + +_enemy::_enemy() +{ + object = NULL; + _state = notuse; +} + +void _enemy::state(_state_t s) +{ + switch(s) + { + case notuse: + if(object) + { + gengine->free_obj(object); + object = NULL; + } + break; + case reserved: + case moving: + if(bank >= 0) + { + if(!object) + object = gengine->get_obj(ek->layer); + if(!object) + break; + if(s == moving) + cs_obj_show(object); + else + cs_obj_hide(object); + } + else if(object) + { + gengine->free_obj(object); + object = NULL; + } + break; + } + _state = s; +} + + + +void _enemies::off() +{ + _enemy *enemyp; + for(enemyp = enemy; enemyp < enemy + ENEMY_MAX; enemyp++) + enemyp->release(); +} + +int _enemies::init() +{ + _enemy *enemyp; + for(enemyp = enemy; enemyp < enemy + ENEMY_MAX; enemyp++) + enemyp->init(); + enemy_max = enemy; + ekind_to_generate_1 = NULL; + ekind_to_generate_2 = NULL; + e1_interval = 1; + e2_interval = 1; + return 0; +} + +void _enemies::move() +{ + _enemy *enemyp; + /* realize reserved enemies */ + for(enemyp = enemy; enemyp < enemy + ENEMY_MAX; enemyp++) + { + if(enemyp->realize()) + enemy_max = enemyp; + } + for(enemyp = enemy; enemyp <= enemy_max; enemyp++) + enemyp->move(); +} + +void _enemies::move_intro() +{ + _enemy *enemyp; + is_intro = 1; + /* realize reserved enemies */ + for(enemyp = enemy; enemyp < enemy + ENEMY_MAX; enemyp++) + { + if(enemyp->realize()) + enemy_max = enemyp; + } + for(enemyp = enemy; enemyp <= enemy_max; enemyp++) + enemyp->move_intro(); + is_intro = 0; +} + +void _enemies::put() +{ + _enemy *enemyp; + for(enemyp = enemy; enemyp <= enemy_max; enemyp++) + enemyp->put(); +} + +int _enemies::make(const enemy_kind * ek, int x, int y, int h, int v, + int di) +{ + _enemy *enemyp; + for(enemyp = enemy; enemyp < enemy + ENEMY_MAX; enemyp++) + if(!enemyp->make(ek, x, y, h, v, di)) + return 0; + return 1; +} + +const enemy_kind *_enemies::randexp() +{ + explocount += 1 + pubrand.get(1); + switch(explocount & 3) + { + case 0: + return &explosion; + case 1: + return &explosion3; + case 2: + return &explosion4; + default: + return &explosion5; + } +} + +int _enemies::erase_cannon(int x, int y) +{ + int count = 0; + _enemy *enemyp; + for(enemyp = enemy; enemyp < enemy + ENEMY_MAX; enemyp++) + count += enemyp->erase_cannon(x, y); + if(count) + wradar->update(x, y); + return count; +} + +int _enemies::exist_pipe() +{ + int count = 0; + _enemy *enemyp; + for(enemyp = enemy; enemyp < enemy + ENEMY_MAX; enemyp++) + if(enemyp->is_pipe()) + count++; + return count; +} + +void _enemies::set_ekind_to_generate(const enemy_kind * e1, int i1, + const enemy_kind * e2, int i2) +{ + ekind_to_generate_1 = e1; + ekind_to_generate_2 = e2; + e1_interval = i1; + e2_interval = i2; +} diff --git a/enemies.h b/enemies.h new file mode 100644 index 0000000..2971f61 --- /dev/null +++ b/enemies.h @@ -0,0 +1,437 @@ +/* +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 1995, 1996 Akira Higuchi + * Copyright (C) 2001-2003, 2007 David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef XKOBO_H_ENEMIES +#define XKOBO_H_ENEMIES + +#include +#include "kobo.h" +#include "config.h" +#include "myship.h" +#include "manage.h" +#include "sound.h" + +#define ABS(x) (((x)>=0) ? (x) : (-(x))) +#define MAX(x,y) (((x)>(y)) ? (x) : (y)) + +#define HEALTH_INDESTRUCTIBLE 9000000 + +class _enemy; +class _enemies; +//---------------------------------------------------------------------------// +struct enemy_kind +{ + int score; + void (_enemy::*make) (); + void (_enemy::*move) (); + void (_enemy::*kill) (); + int hitsize; + int bank, frame; + int layer; +}; + + +extern const enemy_kind beam; +extern const enemy_kind explosion; +extern const enemy_kind explosion3; +extern const enemy_kind explosion4; +extern const enemy_kind explosion5; +extern const enemy_kind ringexpl; +extern const enemy_kind beamexpl; +extern const enemy_kind boltexpl; +extern const enemy_kind rockexpl; +extern const enemy_kind enemy1; +extern const enemy_kind enemy2; +extern const enemy_kind enemy3; +extern const enemy_kind enemy4; +extern const enemy_kind enemy5; +extern const enemy_kind enemy6; +extern const enemy_kind enemy7; +extern const enemy_kind bomb1; +extern const enemy_kind bomb2; +extern const enemy_kind bombdeto; +extern const enemy_kind cannon; +extern const enemy_kind pipe1; +extern const enemy_kind core; +extern const enemy_kind pipe2; +extern const enemy_kind rock; +extern const enemy_kind ring; +extern const enemy_kind enemy_m1; +extern const enemy_kind enemy_m2; +extern const enemy_kind enemy_m3; +extern const enemy_kind enemy_m4; + + +//---------------------------------------------------------------------------// +enum _state_t +{ + notuse, + reserved, + moving +}; + +class _enemy +{ + cs_obj_t *object; /* For the gfxengine connection */ + _state_t _state; + const enemy_kind *ek; + int x, y; + int h, v; + int di; + int a, b; + int count; + int health; + int damage; + int shootable; + int diffx, diffy; + int norm; + int hitsize; + int bank, frame; + void hit(int dmg); + void move_enemy_m(int quick, int maxspeed); + void move_enemy_template(int quick, int maxspeed); + void move_enemy_template_2(int quick, int maxspeed); + void move_enemy_template_3(int quick, int maxspeed); + void shot_template(const enemy_kind * ekp, + int shift, int rand_num, int maxspeed); + void shot_template_8_dir(const enemy_kind * ekp); + public: + _enemy(); + inline void init(); + inline void release(); + void state(_state_t s); + inline void move(); + inline void move_intro(); + inline void put(); + inline int make(const enemy_kind * k, + int px, int py, int h1, int v1, int dir = 0); + inline int realize(); + inline int is_pipe(); + inline int erase_cannon(int px, int py); + + void kill_default(); + + void make_beam(); + void move_beam(); + void kill_beam(); + + void make_rock(); + void move_rock(); + void kill_rock(); + + void make_ring(); + void move_ring(); + void kill_ring(); + + void make_bomb(); + void move_bomb1(); + void move_bomb2(); + + void make_expl(); + void move_expl(); + + void make_cannon(); + void move_cannon(); + void kill_cannon(); + + void make_core(); + void move_core(); + void kill_core(); + + void make_pipe1(); + void move_pipe1(); + + void make_pipe2(); + void move_pipe2(); + + void make_enemy1(); + void move_enemy1(); + + void make_enemy2(); + void move_enemy2(); + + void make_enemy3(); + void move_enemy3(); + + void make_enemy4(); + void move_enemy4(); + + void make_enemy(); + void move_enemy5(); + void move_enemy6(); + void move_enemy7(); + + void make_enemy_m1(); + void move_enemy_m1(); + + void make_enemy_m2(); + void move_enemy_m2(); + + void make_enemy_m3(); + void move_enemy_m3(); + + void make_enemy_m4(); + void move_enemy_m4(); +}; + +//---------------------------------------------------------------------------// +class _enemies +{ + static _enemy enemy[ENEMY_MAX]; + static _enemy *enemy_max; + static const enemy_kind *ekind_to_generate_1; + static const enemy_kind *ekind_to_generate_2; + static int e1_interval; + static int e2_interval; + static int explocount; + public: + static int is_intro; + static int init(); + static void off(); + static void move(); + static void move_intro(); + static void put(); + static int make(const enemy_kind * ek, + int x, int y, int h = 0, int v = 0, int di = 0); + static const enemy_kind *randexp(); + static int erase_cannon(int x, int y); + static int exist_pipe(); + static void set_ekind_to_generate(const enemy_kind * ek1, int i1, + const enemy_kind * ek2, int i2); + static inline const enemy_kind *ek1() + { + return ekind_to_generate_1; + } + static inline const enemy_kind *ek2() + { + return ekind_to_generate_2; + } + static inline int eint1() + { + return e1_interval; + } + static inline int eint2() + { + return e2_interval; + } +}; + +extern _enemies enemies; + + +inline void _enemy::init() +{ + release(); +} + +inline void _enemy::release() +{ + state(notuse); +} + +inline int _enemy::make(const enemy_kind * k, int px, int py, + int h1, int v1, int dir) +{ + if(_state != notuse) + return -1; + + ek = k; + state(reserved); + x = PIXEL2CS(px); + y = PIXEL2CS(py); + di = dir; + h = h1; + v = v1; + a = 0; + b = 0; + count = 0; + health = 20; + damage = 50; + shootable = 1; + hitsize = ek->hitsize; + bank = ek->bank; + frame = ek->frame; + (this->*(ek->make)) (); + return 0; +} + +inline void _enemy::hit(int dmg) +{ + if(HEALTH_INDESTRUCTIBLE != health) + health -= dmg; + if(enemies.is_intro) + { + if(health <= 0) + { + enemies.make(&explosion, CS2PIXEL(x), CS2PIXEL(y)); + release(); + } + return; + } + else if(health > 0) + { + if(ek == &rock) + sound.g_bolt_hit_rock(x, y); + else + sound.g_bolt_hit(x, y); + return; + } + + manage.add_score(ek->score); + (this->*(ek->kill)) (); +} + +inline int _enemy::erase_cannon(int px, int py) +{ + if( (_state != notuse) && (ek == &cannon) + && ((signed)(CS2PIXEL(x) & (WORLD_SIZEX - 1)) >> 4 == px) + && ((signed)(CS2PIXEL(y) & (WORLD_SIZEY - 1)) >> 4 == py) + ) + { + release(); + return 1; + } + return 0; +} + +inline void _enemy::move() +{ + if(_state != moving) + return; + x += h; + y += v; + diffx = CS2PIXEL(x) - myship.get_x(); + diffy = CS2PIXEL(y) - myship.get_y(); + + if(diffx > (WORLD_SIZEX >> 1)) + { + diffx -= WORLD_SIZEX; + x -= PIXEL2CS(WORLD_SIZEX); + } + if(diffx < -(WORLD_SIZEX >> 1)) + { + diffx += WORLD_SIZEX; + x += PIXEL2CS(WORLD_SIZEX); + } + if(diffy > (WORLD_SIZEY >> 1)) + { + diffy -= WORLD_SIZEY; + y -= PIXEL2CS(WORLD_SIZEY); + } + if(diffy < -(WORLD_SIZEY >> 1)) + { + diffy += WORLD_SIZEY; + y += PIXEL2CS(WORLD_SIZEY); + } + + norm = MAX(ABS(diffx), ABS(diffy)); + (this->*(ek->move)) (); + + // Handle collisions with the player ship + if((hitsize >= 0) && (norm < (hitsize + HIT_MYSHIP))) + if(prefs->cmd_indicator) + sound.g_player_damage(); + else if(myship.alive()) + { + hit(game.damage); // Ship damages object + myship.hit(damage); // Object damages ship + } + + // Handle collisions with player bolts (Player bolts kill themselves + // when they hit something, so we don't need to hit them from here.) + if(!shootable || (norm >= ((VIEWLIMIT >> 1) + 8))) + return; + + int dmg = myship.hit_bolt(CS2PIXEL(x), CS2PIXEL(y), + hitsize + HIT_BOLT, health); + if(dmg) + if(prefs->cmd_indicator) + sound.g_player_damage(); + else + hit(dmg); // Bolt damages object +} + +inline void _enemy::move_intro() +{ + if(_state != moving) + return; + x += h; + y += v; + diffx = CS2PIXEL(x) - myship.get_x(); + diffy = CS2PIXEL(y) - myship.get_y(); + + if(diffx > (WORLD_SIZEX >> 1)) + { + diffx -= WORLD_SIZEX; + x -= PIXEL2CS(WORLD_SIZEX); + } + if(diffx < -(WORLD_SIZEX >> 1)) + { + diffx += WORLD_SIZEX; + x += PIXEL2CS(WORLD_SIZEX); + } + if(diffy > (WORLD_SIZEY >> 1)) + { + diffy -= WORLD_SIZEY; + y -= PIXEL2CS(WORLD_SIZEY); + } + if(diffy < -(WORLD_SIZEY >> 1)) + { + diffy += WORLD_SIZEY; + y += PIXEL2CS(WORLD_SIZEY); + } + + norm = MAX(ABS(diffx), ABS(diffy)); + (this->*(ek->move)) (); +} + +inline void _enemy::put() +{ + if(!object) + return; + object->point.v.x = x; + object->point.v.y = y; + cs_obj_image(object, bank, frame + di - 1); +} + +inline int _enemy::realize() +{ + if(_state == reserved) + { + state(moving); + if(object) + { + object->point.v.x = x; + object->point.v.y = y; + cs_point_force(&object->point); + } + } + return (_state == moving); +} + +inline int _enemy::is_pipe() +{ + return ((_state != notuse) && ((ek == &pipe1) || (ek == &pipe2))); +} + + +#endif // XKOBO_H_ENEMIES diff --git a/enemy.cpp b/enemy.cpp new file mode 100644 index 0000000..136eefb --- /dev/null +++ b/enemy.cpp @@ -0,0 +1,1429 @@ +/*(GPL) +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 1995, 1996 Akira Higuchi + * Copyright (C) 2001-2003, 2007 David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "screen.h" +#include "manage.h" +#include "enemies.h" +#include "myship.h" +#include "random.h" +#include + +/////////////////////////////////////////////////////////////////////////////// +// Fast integer atan() approximation. Input is 24:8 fixed point. +// Output is 0..64 for 0..45 deg, accurate accurate down to LSB. +// In: q = 256 * minv / maxv (0..256 <==> 0..1) +// Out: atan(q / 256) * 256 (0..64 <==> 0..45 deg) +/////////////////////////////////////////////////////////////////////////////// +// atan() approximations for 0..9 deg: +// a = 83 * q / 256 - q*q / 2844 (+/- 2.1%) +// a = 82 * q / 256 - k*k / 8500 - x*x*x / 1600000 (+/- 0.6%) +/////////////////////////////////////////////////////////////////////////////// +static inline int fastatan(int q) +{ + int q2 = q * q; + int q3 = q2 * q; + return (82 * q >> 8) - (62 * q2 >> 19) - (10 * q3 >> 24); +} + +static int speed2dir(int sx, int sy, int frames) +{ + if(!sx && !sy) + return 0; + int at2; + if(sx > 0) + { + // Right + if(sy < 0) + { + // Top-right quadrant + sy = -sy; + if(sy > sx) + at2 = fastatan(sx * 256 / sy); + else + at2 = 128 - fastatan(sy * 256 / sx); + } + else + { + // Bottom-right quadrant + if(sx > sy) + at2 = 128 + fastatan(sy * 256 / sx); + else + at2 = 256 - fastatan(sx * 256 / sy); + } + } + else + { + // Left + sx = -sx; + if(sy > 0) + { + // Bottom-left quadrant + if(sy > sx) + at2 = 256 + fastatan(sx * 256 / sy); + else + at2 = 384 - fastatan(sy * 256 / sx); + } + else + { + // Top-left quadrant + sy = -sy; + if(sx > sy) + at2 = 384 + fastatan(sy * 256 / sx); + else + at2 = 512 - fastatan(sx * 256 / sy); + } + } + at2 = (at2 * frames + 256) >> 9; + return at2 > frames - 1 ? 1 : at2 + 1; +} + + +/* + * =========================================================================== + * (template) + * =========================================================================== + */ + +inline void _enemy::move_enemy_m(int quick, int maxspeed) +{ + if(diffx > 0) + { + if(h > -maxspeed) + h -= quick; + } + else if(diffx < 0) + { + if(h < maxspeed) + h += quick; + } + if(diffy > 0) + { + if(v > -maxspeed) + v -= quick; + } + else if(diffy < 0) + { + if(v < maxspeed) + v += quick; + } +} + +inline void _enemy::move_enemy_template(int quick, int maxspeed) +{ + if(diffx > 0) + { + if(h > -maxspeed) + h -= quick; + } + else if(diffx < 0) + { + if(h < maxspeed) + h += quick; + } + if(diffy > 0) + { + if(v > -maxspeed) + v -= quick; + } + else if(diffy < 0) + { + if(v < maxspeed) + v += quick; + } + int ndi = speed2dir(h, v, 16); + if(ndi > 0) + di = ndi; +} + +inline void _enemy::move_enemy_template_2(int quick, int maxspeed) +{ + h = -PIXEL2CS(diffy) / (1< 0) + { + if(h > -maxspeed) + h -= quick; + } + else if(diffx < 0) + { + if(h < maxspeed) + h += quick; + } + if(diffy > 0) + { + if(v > -maxspeed) + v -= quick; + } + else if(diffy < 0) + { + if(v < maxspeed) + v += quick; + } + int ndi = speed2dir(h, v, 16); + if(ndi > 0) + di = ndi; +} + +inline void _enemy::move_enemy_template_3(int quick, int maxspeed) +{ + h = PIXEL2CS(diffy) / (1< 0) + { + if(h > -maxspeed) + h -= quick; + } + else if(diffx < 0) + { + if(h < maxspeed) + h += quick; + } + if(diffy > 0) + { + if(v > -maxspeed) + v -= quick; + } + else if(diffy < 0) + { + if(v < maxspeed) + v += quick; + } + int ndi = speed2dir(h, v, 16); + if(ndi > 0) + di = ndi; +} + +inline void _enemy::shot_template(const enemy_kind * ekp, + int shift, int rnd, int maxspeed) +{ + int vx = -diffx; + int vy = -diffy; + if(rnd) + { + vx += gamerand.get() & (rnd - 1) - (rnd >> 1); + vy += gamerand.get() & (rnd - 1) - (rnd >> 1); + } + vx = PIXEL2CS(vx) / (1< 0) + { + if(vx > maxspeed) + vx = maxspeed; + else if(vx < -maxspeed) + vx = -maxspeed; + if(vy > maxspeed) + vy = maxspeed; + else if(vy < -maxspeed) + vy = -maxspeed; + } + enemies.make(ekp, CS2PIXEL(x + vx), CS2PIXEL(y + vy), vx, + vy); + if(enemies.is_intro) + return; + if(&ring == ekp) + sound.g_launch_ring(x, y); + else if(&beam == ekp) + sound.g_launch_beam(x, y); + else if(&bomb1 == ekp || &bomb2 == ekp) + sound.g_launch_bomb(x, y); + else + sound.g_launch(x, y); +} + +void _enemy::shot_template_8_dir(const enemy_kind * ekp) +{ + static int vx[] = { 0, 200, 300, 200, 0, -200, -300, -200 }; + static int vy[] = { -300, -200, 0, 200, 300, 200, 0, -200 }; + int i; + for(i = 0; i < 8; i++) + enemies.make(ekp, CS2PIXEL(x), CS2PIXEL(y), vx[i], + vy[i]); + if(&ring == ekp) + sound.g_m_launch_ring(x, y); + else if(&beam == ekp) + sound.g_m_launch_beam(x, y); + else if(&bomb1 == ekp || &bomb2 == ekp) + sound.g_m_launch_bomb(x, y); + else + sound.g_m_launch(x, y); +} + +void _enemy::kill_default() +{ + enemies.make(enemies.randexp(), CS2PIXEL(x), CS2PIXEL(y), + h >> 1, v >> 1); + sound.g_enemy_explo(x, y); + release(); +} + + +/* + * =========================================================================== + * beam + * =========================================================================== + */ +void _enemy::make_beam() +{ + di = 1 + pubrand.get(4); + health = 1; + shootable = 0; + damage = 20; +} + +void _enemy::move_beam() +{ + if(norm >= ((VIEWLIMIT >> 1) + 32)) + release(); + di += pubrand.get(1) + 1; + if(di > 16) + di = 1; +} + +void _enemy::kill_beam() +{ + enemies.make(&beamexpl, CS2PIXEL(x), CS2PIXEL(y)); + release(); +} + +const enemy_kind beam = { + 0, + &_enemy::make_beam, + &_enemy::move_beam, + &_enemy::kill_beam, + 2, + B_BULLETS, 0, + LAYER_BULLETS +}; + +/* + * =========================================================================== + * rock + * =========================================================================== + */ +void _enemy::make_rock() +{ + count = 500; + health = game.rock_health; + damage = game.rock_damage; + di = gamerand.get(5) + 1; + a = gamerand.get(1) ? 1 : -1; + switch(gamerand.get() % 3) + { + case 0: + bank = B_ROCK1; + break; + case 1: + bank = B_ROCK2; + break; + case 2: + bank = B_ROCK3; + break; + } +} + +void _enemy::move_rock() +{ + if(bank == B_ROCK3) + { + di += a; + if(di < 1) + di += 48; + else if(di > 48) + di -= 48; + } + else + di = ((di + a - 1) & 31) + 1; +} + +void _enemy::kill_rock() +{ + enemies.make(&rockexpl, CS2PIXEL(x), CS2PIXEL(y), h >> 1, v >> 1); + sound.g_rock_explo(x, y); + release(); +} + +const enemy_kind rock = { + 10, + &_enemy::make_rock, + &_enemy::move_rock, + &_enemy::kill_rock, + 4, + B_ROCK1, 0, + LAYER_ENEMIES +}; + +/* + * =========================================================================== + * ring + * =========================================================================== + */ +void _enemy::make_ring() +{ + count = 500; + health = 20; + damage = 30; + di = 1; +} + +void _enemy::move_ring() +{ + di += 1 + pubrand.get(1); + if(di > 16) + di = 1; +} + +void _enemy::kill_ring() +{ + enemies.make(&ringexpl, CS2PIXEL(x), CS2PIXEL(y), h >> 1, v >> 1); + sound.g_ring_explo(x, y); + release(); +} + +const enemy_kind ring = { + 1, + &_enemy::make_ring, + &_enemy::move_ring, + &_enemy::kill_ring, + 4, + B_RING, 0, + LAYER_BULLETS +}; + +/* + * =========================================================================== + * bomb + * =========================================================================== + */ +void _enemy::make_bomb() +{ + count = 500; + health = 20; + damage = 70; + di = 1; +} + +void _enemy::move_bomb1() +{ + int h1 = ABS(diffx); + int v1 = ABS(diffy); + if(((h1 < 100) && (v1 < 30)) || (h1 < 30) && (v1 < 100)) + { + int vx1 = PIXEL2CS(-diffx) / (3*8); + int vy1 = PIXEL2CS(-diffy) / (3*8); + int vx2 = vx1, vx3 = vx1; + int vy2 = vy1, vy3 = vy1; + int i; + for(i = 0; i < 4; i++) + { + int tmp = vx2; + vx2 += (vy2 >> 4); + vy2 -= (tmp >> 4); + tmp = vx3; + vx3 -= (vy3 >> 4); + vy3 += (tmp >> 4); + } + enemies.make(&beam, CS2PIXEL(x), CS2PIXEL(y), vx2, vy2); + enemies.make(&beam, CS2PIXEL(x), CS2PIXEL(y), vx3, vy3); + enemies.make(&bombdeto, CS2PIXEL(x), CS2PIXEL(y), vx1, vy1); + sound.g_bomb_deto(x, y); + release(); + } + if(++di > 16) + di = 1; +} + +const enemy_kind bomb1 = { + 5, + &_enemy::make_bomb, + &_enemy::move_bomb1, + &_enemy::kill_default, + 5, + B_BOMB, 0, + LAYER_ENEMIES +}; + +/* + * =========================================================================== + * bomb2 + * =========================================================================== + */ +void _enemy::move_bomb2() +{ + int h1 = ABS(diffx); + int v1 = ABS(diffy); + if(((h1 < 100) && (v1 < 20)) || (h1 < 20) && (v1 < 100)) + { + int vx1 = PIXEL2CS(-diffx) / (3*8); + int vy1 = PIXEL2CS(-diffy) / (3*8); + int vx2 = vx1, vx3 = vx1; + int vy2 = vy1, vy3 = vy1; + int i; + for(i = 0; i < 6; i++) + { + int tmp = vx2; + vx2 += (vy2 >> 4); + vy2 -= (tmp >> 4); + tmp = vx3; + vx3 -= (vy3 >> 4); + vy3 += (tmp >> 4); + } + int vx4 = vx2, vx5 = vx3; + int vy4 = vy2, vy5 = vy3; + for(i = 0; i < 6; i++) + { + int tmp = vx2; + vx2 += (vy2 >> 4); + vy2 -= (tmp >> 4); + tmp = vx3; + vx3 -= (vy3 >> 4); + vy3 += (tmp >> 4); + } + enemies.make(&beam, CS2PIXEL(x), CS2PIXEL(y), vx1, vy1); + enemies.make(&beam, CS2PIXEL(x), CS2PIXEL(y), vx2, vy2); + enemies.make(&beam, CS2PIXEL(x), CS2PIXEL(y), vx3, vy3); + enemies.make(&beam, CS2PIXEL(x), CS2PIXEL(y), vx4, vy4); + enemies.make(&beam, CS2PIXEL(x), CS2PIXEL(y), vx5, vy5); + enemies.make(&bombdeto, CS2PIXEL(x), CS2PIXEL(y), vx1, vy1); + sound.g_bomb_deto(x, y); + release(); + } + if(--di < 1) + di = 16; +} + +const enemy_kind bomb2 = { + 20, + &_enemy::make_bomb, + &_enemy::move_bomb2, + &_enemy::kill_default, + 5, + B_BOMB, 0, + LAYER_ENEMIES +}; + +/* + * =========================================================================== + * explosionX + * Various explosions + * =========================================================================== + */ +void _enemy::make_expl() +{ + health = 1; + damage = 0; + shootable = 0; + switch(bank) + { + case B_EXPLO1: + case B_BOMBDETO: + a = 8; + break; + case B_EXPLO3: + case B_EXPLO4: + case B_EXPLO5: + case B_ROCKEXPL: + a = 12; + break; + case B_RINGEXPL: + frame = 8 * pubrand.get(1); + a = 8; + break; + case B_BULLETEXPL: + a = 6; + break; + case B_BOLTEXPL: + frame = 6 * pubrand.get(1); + di = pubrand.get(2); + a = 6; + break; + } +} + +void _enemy::move_expl() +{ + if(++di > a) + release(); +} + +const enemy_kind explosion = { + 0, + &_enemy::make_expl, + &_enemy::move_expl, + &_enemy::kill_default, + -1, + B_EXPLO1, 0, + LAYER_FX +}; + +const enemy_kind explosion3 = { + 0, + &_enemy::make_expl, + &_enemy::move_expl, + &_enemy::kill_default, + -1, + B_EXPLO3, 0, + LAYER_FX +}; + +const enemy_kind explosion4 = { + 0, + &_enemy::make_expl, + &_enemy::move_expl, + &_enemy::kill_default, + -1, + B_EXPLO4, 0, + LAYER_FX +}; + +const enemy_kind explosion5 = { + 0, + &_enemy::make_expl, + &_enemy::move_expl, + &_enemy::kill_default, + -1, + B_EXPLO5, 0, + LAYER_FX +}; + +/* + * =========================================================================== + * ringexpl + * Ring dies in a flash + * =========================================================================== + */ +const enemy_kind ringexpl = { + 0, + &_enemy::make_expl, + &_enemy::move_expl, + &_enemy::kill_default, + -1, + B_RINGEXPL, 0, + LAYER_FX +}; + +/* + * =========================================================================== + * beamexpl + * Enemy "bullet" discharges + * =========================================================================== + */ +const enemy_kind beamexpl = { + 0, + &_enemy::make_expl, + &_enemy::move_expl, + &_enemy::kill_default, + -1, + B_BULLETEXPL, 0, + LAYER_FX +}; + +/* + * =========================================================================== + * boltexpl + * Player bolt discharges + * =========================================================================== + */ +const enemy_kind boltexpl = { + 0, + &_enemy::make_expl, + &_enemy::move_expl, + &_enemy::kill_default, + -1, + B_BOLTEXPL, 0, + LAYER_FX +}; + +/* + * =========================================================================== + * rockexpl + * Rock *finally* explodes + * =========================================================================== + */ +const enemy_kind rockexpl = { + 0, + &_enemy::make_expl, + &_enemy::move_expl, + &_enemy::kill_default, + -1, + B_ROCKEXPL, 0, + LAYER_FX +}; + +/* + * =========================================================================== + * bombdeto + * Bomb detonation (not really an explosion!) + * =========================================================================== + */ +const enemy_kind bombdeto = { + 0, + &_enemy::make_expl, + &_enemy::move_expl, + &_enemy::kill_default, + -1, + B_BOMBDETO, 0, + LAYER_ENEMIES +}; + +/* + * =========================================================================== + * cannon + * =========================================================================== + */ +void _enemy::make_cannon() +{ + count = 0; + health = 20; + damage = 75; + b = enemies.eint1() - 1; + a = gamerand.get() & b; +} + +void _enemy::move_cannon() +{ + (count)++; + (count) &= (b); + if(count == a && norm < ((VIEWLIMIT >> 1) + 8)) + { + int shift = (enemies.ek1() == &beam) ? 6 : 5; + this->shot_template(enemies.ek1(), shift, 32, 0); + } +} + +void _enemy::kill_cannon() +{ + enemies.make(&pipe1, CS2PIXEL(x), CS2PIXEL(y)); + sound.g_base_node_explo(x, y); + release(); +} + +const enemy_kind cannon = { + 10, + &_enemy::make_cannon, + &_enemy::move_cannon, + &_enemy::kill_cannon, + 4, + -1, 0, + LAYER_BASES +}; + +/* + * =========================================================================== + * core + * =========================================================================== + */ +void _enemy::make_core() +{ + count = 0; + health = 20; + damage = 150; + b = enemies.eint2() - 1; + a = gamerand.get() & b; +} + +void _enemy::move_core() +{ + (count)++; + (count) &= (b); + if(count == a && norm < ((VIEWLIMIT >> 1) + 8)) + { + int shift = (enemies.ek2() == &beam) ? 6 : 5; + this->shot_template(enemies.ek2(), shift, 0, 0); + } +} + +void _enemy::kill_core() +{ + enemies.make(&pipe2, CS2PIXEL(x), CS2PIXEL(y), 0, 0, 3); + enemies.make(&pipe2, CS2PIXEL(x), CS2PIXEL(y), 0, 0, 7); + enemies.make(&pipe2, CS2PIXEL(x), CS2PIXEL(y), 0, 0, 1); + enemies.make(&pipe2, CS2PIXEL(x), CS2PIXEL(y), 0, 0, 5); + enemies.make(&explosion4, CS2PIXEL(x), CS2PIXEL(y)); + sound.g_base_core_explo(x, y); + release(); + manage.destroyed_a_core(); +} + +const enemy_kind core = { + 200, + &_enemy::make_core, + &_enemy::move_core, + &_enemy::kill_core, + 4, + -1, 0, + LAYER_BASES +}; + +/* + * =========================================================================== + * pipe1 + * =========================================================================== + */ +void _enemy::make_pipe1() +{ + health = 1; + damage = 0; + shootable = 0; + count = 4; + a = 0; + b = 0; +} + +void _enemy::move_pipe1() +{ + sound.g_pipe_rumble(x, y); + if((norm < ((VIEWLIMIT >> 1) + 32)) && (count == 1)) + enemies.make(&explosion, + CS2PIXEL(x) + pubrand.get(4) - 8, + CS2PIXEL(y) + pubrand.get(4) - 8, + 0, 0, 1); + + if(++count < 4) + return; + count = 0; + + int x1 = (CS2PIXEL(x) & (WORLD_SIZEX - 1)) >> 4; + int y1 = (CS2PIXEL(y) & (WORLD_SIZEY - 1)) >> 4; + int a_next = 0; + int x_next = 0; + int y_next = 0; + int m = screen.get_map(x1, y1); + int p = MAP_BITS(m); + if(IS_SPACE(p)) + { + release(); + return; + } + if(norm < ((VIEWLIMIT >> 1) + 32)) + enemies.make(enemies.randexp(), CS2PIXEL(x), CS2PIXEL(y), + 0, 0, b); + b = 1; + if((p ^ a) == U_MASK) + { + a_next = D_MASK; + y_next = -PIXEL2CS(16); + } + if((p ^ a) == R_MASK) + { + a_next = L_MASK; + x_next = PIXEL2CS(16); + } + if((p ^ a) == D_MASK) + { + a_next = U_MASK; + y_next = PIXEL2CS(16); + } + if((p ^ a) == L_MASK) + { + a_next = R_MASK; + x_next = -PIXEL2CS(16); + } + if(a_next) + { + screen.set_map(x1, y1, 0); + x += x_next; + y += y_next; + a = a_next; + return; + } + if(!(p & CORE)) + screen.set_map(x1, y1, m ^ a); + release(); +} +const enemy_kind pipe1 = { + 0, + &_enemy::make_pipe1, + &_enemy::move_pipe1, + &_enemy::kill_default, + -1, + -1, 0, + LAYER_BASES +}; + +/* + * =========================================================================== + * pipe2 + * =========================================================================== + */ +void _enemy::make_pipe2() +{ + int x1 = (CS2PIXEL(x) & (WORLD_SIZEX - 1)) >> 4; + int y1 = (CS2PIXEL(y) & (WORLD_SIZEY - 1)) >> 4; + + screen.set_map(x1, y1, 0); + health = 1; + damage = 0; + shootable = 0; + count = 4; + switch (di) + { + case 1: + a = D_MASK; + y -= PIXEL2CS(16); + break; + case 3: + a = L_MASK; + x += PIXEL2CS(16); + break; + case 5: + a = U_MASK; + y += PIXEL2CS(16); + break; + case 7: + a = R_MASK; + x -= PIXEL2CS(16); + break; + } +} + + +void _enemy::move_pipe2() +{ + if((norm < ((VIEWLIMIT >> 1) + 32)) && (count == 1)) + enemies.make(&explosion, + CS2PIXEL(x) + pubrand.get(4) - 8, + CS2PIXEL(y) + pubrand.get(4) - 8, + 0, 0, 1); + if(++count < 4) + { + sound.g_pipe_rumble(x, y); + return; + } + count = 0; + + int x1 = (CS2PIXEL(x) & (WORLD_SIZEX - 1)) >> 4; + int y1 = (CS2PIXEL(y) & (WORLD_SIZEY - 1)) >> 4; + int a_next = 0; + int x_next = 0; + int y_next = 0; + int p = MAP_BITS(screen.get_map(x1, y1)); + if(IS_SPACE(p)) + { + release(); + return; + } + if((p ^ a) == 0) + { + manage.add_score(30); + release(); + enemies.erase_cannon(x1, y1); + screen.set_map(x1, y1, 0); + sound.g_base_node_explo(x, y); + if(norm < ((VIEWLIMIT >> 1) + 32)) + enemies.make(enemies.randexp(), CS2PIXEL(x), CS2PIXEL(y)); + return; + } + if((p ^ a) == HARD) + { + release(); + screen.set_map(x1, y1, 0); + sound.g_pipe_rumble(x, y); + if(norm < ((VIEWLIMIT >> 1) + 32)) + enemies.make(enemies.randexp(), CS2PIXEL(x), CS2PIXEL(y), + 0, 0, 1); + return; + } + if((p ^ a) == U_MASK) + { + a_next = D_MASK; + y_next = -PIXEL2CS(16); + } + if((p ^ a) == R_MASK) + { + a_next = L_MASK; + x_next = PIXEL2CS(16); + } + if((p ^ a) == D_MASK) + { + a_next = U_MASK; + y_next = PIXEL2CS(16); + } + if((p ^ a) == L_MASK) + { + a_next = R_MASK; + x_next = -PIXEL2CS(16); + } + screen.set_map(x1, y1, 0); + sound.g_pipe_rumble(x, y); + if(norm < ((VIEWLIMIT >> 1) + 32)) + enemies.make(enemies.randexp(), CS2PIXEL(x), CS2PIXEL(y), + 0, 0, 1); + if(a_next) + { + x += x_next; + y += y_next; + a = a_next; + return; + } + p ^= a; + if(p & U_MASK) + enemies.make(&pipe2, CS2PIXEL(x), CS2PIXEL(y), 0, 0, 1); + if(p & R_MASK) + enemies.make(&pipe2, CS2PIXEL(x), CS2PIXEL(y), 0, 0, 3); + if(p & D_MASK) + enemies.make(&pipe2, CS2PIXEL(x), CS2PIXEL(y), 0, 0, 5); + if(p & L_MASK) + enemies.make(&pipe2, CS2PIXEL(x), CS2PIXEL(y), 0, 0, 7); + manage.add_score(10); + release(); +} + + +const enemy_kind pipe2 = { + 0, + &_enemy::make_pipe2, + &_enemy::move_pipe2, + &_enemy::kill_default, + -1, + -1, 0, + LAYER_BASES +}; + +/* + * =========================================================================== + * enemy1 + * Gray Dumb Missile + * =========================================================================== + */ +void _enemy::make_enemy1() +{ + di = 1; + health = 20; +} + +void _enemy::move_enemy1() +{ + this->move_enemy_template(2, 256); +} +const enemy_kind enemy1 = { + 2, + &_enemy::make_enemy1, + &_enemy::move_enemy1, + &_enemy::kill_default, + 6, + B_MISSILE1, 0, + LAYER_ENEMIES +}; + +/* + * =========================================================================== + * enemy2 + * Teal Firing Fighter + * =========================================================================== + */ +void _enemy::make_enemy2() +{ + di = 1; + health = 20; + count = gamerand.get() & 63; +} + +void _enemy::move_enemy2() +{ + this->move_enemy_template(4, 192); + if(--(count) <= 0) + { + if(norm < ((VIEWLIMIT >> 1) + 8)) + { + this->shot_template(&beam, 5, 0, 0); + } + count = 32; + } +} +const enemy_kind enemy2 = { + 10, + &_enemy::make_enemy2, + &_enemy::move_enemy2, + &_enemy::kill_default, + 6, + B_FIGHTER, 0, + LAYER_ENEMIES +}; + +/* + * =========================================================================== + * enemy3 + * Maroon Homing Missile + * =========================================================================== + */ +void _enemy::make_enemy3() +{ + di = 1; + health = 20; +} + +void _enemy::move_enemy3() +{ + this->move_enemy_template(32, 96); +} +const enemy_kind enemy3 = { + 1, + &_enemy::make_enemy3, + &_enemy::move_enemy3, + &_enemy::kill_default, + 6, + B_MISSILE2, 0, + LAYER_ENEMIES +}; + +/* + * =========================================================================== + * enemy4 + * Blue Homing Missile + * =========================================================================== + */ +void _enemy::make_enemy4() +{ + di = 1; + health = 20; +} + +void _enemy::move_enemy4() +{ + this->move_enemy_template(4, 96); +} +const enemy_kind enemy4 = { + 1, + &_enemy::make_enemy4, + &_enemy::move_enemy4, + &_enemy::kill_default, + 6, + B_MISSILE3, 0, + LAYER_ENEMIES +}; + +/* + * =========================================================================== + * enemy5 + * Green Boomerang Fighter + * =========================================================================== + */ +void _enemy::make_enemy() +{ + count = gamerand.get() & 127; + di = 1; + health = 20; + a = 0; +} + +void _enemy::move_enemy5() +{ + if(a == 0) + { + if(norm > ((VIEWLIMIT >> 1) - 32)) + this->move_enemy_template(6, 192); + else + a = 1; + } + else + { + if(norm < VIEWLIMIT) + this->move_enemy_template_2(4, 192); + else + a = 0; + } + if(enemies.is_intro) + { + if(gamerand.get(7) > 110) + hit(1); + } + else if((--count) <= 0) + { + count = 8; + if(norm > ((VIEWLIMIT >> 1) - 32)) + this->shot_template(&beam, 6, 0, 0); + } +} +const enemy_kind enemy5 = { + 5, + &_enemy::make_enemy, + &_enemy::move_enemy5, + &_enemy::kill_default, + 6, + B_BMR_GREEN, 0, + LAYER_ENEMIES +}; + +/* + * =========================================================================== + * enemy6 + * Purple Boomerang Fighter + * =========================================================================== + */ +void _enemy::move_enemy6() +{ + if(a == 0) + { + if(norm > ((VIEWLIMIT >> 1) - 0)) + this->move_enemy_template(6, 192); + else + a = 1; + } + else + { + if(norm < VIEWLIMIT) + this->move_enemy_template_2(5, 192); + else + a = 0; + } + if((--count) <= 0) + { + count = 128; + if(norm > ((VIEWLIMIT >> 1) - 32)) + this->shot_template(&beam, 6, 0, 0); + } +} +const enemy_kind enemy6 = { + 2, + &_enemy::make_enemy, + &_enemy::move_enemy6, + &_enemy::kill_default, + 6, + B_BMR_PURPLE, 0, + LAYER_ENEMIES +}; + +/* + * =========================================================================== + * enemy7 + * Pink Boomerang Fighter + * =========================================================================== + */ +void _enemy::move_enemy7() +{ + if(a == 0) + { + if(norm > ((VIEWLIMIT >> 1) - 32)) + this->move_enemy_template(6, 192); + else + a = 1; + } + else + { + if(norm < VIEWLIMIT) + this->move_enemy_template_3(4, 192); + else + a = 0; + } + if(enemies.is_intro) + { + if(gamerand.get(7) > 110) + hit(1); + } + else if((--count) <= 0) + { + count = 8; + if(norm > ((VIEWLIMIT >> 1) - 32)) + this->shot_template(&beam, 6, 0, 0); + } +} +const enemy_kind enemy7 = { + 5, + &_enemy::make_enemy, + &_enemy::move_enemy7, + &_enemy::kill_default, + 6, + B_BMR_PINK, 0, + LAYER_ENEMIES +}; +/* + * =========================================================================== + * enemy_m1 + * =========================================================================== + */ +void _enemy::make_enemy_m1() +{ + di = 1; + health = 20 * 26; + count = gamerand.get() & 15; +} + +void _enemy::move_enemy_m1() +{ + this->move_enemy_m(3, 128); + if(++di > 16) + di = 1; + if((count--) <= 0) + { + count = 4; + if(norm < ((VIEWLIMIT >> 1) - 16)) + { + this->shot_template(&enemy1, 4, 0, 0); + } + } + if(health < 200) + { + this->shot_template_8_dir(&enemy2); + release(); + } +} +const enemy_kind enemy_m1 = { + 50, + &_enemy::make_enemy_m1, + &_enemy::move_enemy_m1, + &_enemy::kill_default, + 12, + B_BIGSHIP, 0, + LAYER_ENEMIES +}; + +/* + * =========================================================================== + * enemy_m2 + * =========================================================================== + */ +void _enemy::make_enemy_m2() +{ + di = 1; + health = 20 * 26; + count = gamerand.get() & 15; +} + +void _enemy::move_enemy_m2() +{ + this->move_enemy_m(3, 128); + if(++di > 16) + di = 1; + if((count--) <= 0) + { + count = 8; + if(norm < ((VIEWLIMIT >> 1) + 8)) + { + this->shot_template(&enemy2, 4, 128, 192); + } + } + if(health < 200) + { + this->shot_template_8_dir(&bomb2); + release(); + } +} +const enemy_kind enemy_m2 = { + 50, + &_enemy::make_enemy_m2, + &_enemy::move_enemy_m2, + &_enemy::kill_default, + 12, + B_BIGSHIP, 0, + LAYER_ENEMIES +}; + +/* + * =========================================================================== + * enemy_m3 + * =========================================================================== + */ +void _enemy::make_enemy_m3() +{ + di = 1; + health = 20 * 26; + count = gamerand.get() & 15; +} + +void _enemy::move_enemy_m3() +{ + this->move_enemy_m(3, 128); + if(--di < 1) + di = 16; + if((count--) <= 0) + { + count = 64; + if(norm < ((VIEWLIMIT >> 1) + 8)) + { + this->shot_template_8_dir(&bomb2); + } + } + if(health < 200) + { + this->shot_template_8_dir(&rock); + release(); + } +} +const enemy_kind enemy_m3 = { + 50, + &_enemy::make_enemy_m3, + &_enemy::move_enemy_m3, + &_enemy::kill_default, + 12, + B_BIGSHIP, 0, + LAYER_ENEMIES +}; + +/* + * =========================================================================== + * enemy_m4 + * =========================================================================== + */ +void _enemy::make_enemy_m4() +{ + di = 1; + health = 20 * 26; + count = gamerand.get() & 15; +} + +void _enemy::move_enemy_m4() +{ + this->move_enemy_m(2, 96); + if(--di < 1) + di = 16; + static const enemy_kind *shot[8] = { + &enemy1, &enemy2, &bomb2, &ring, &enemy1, &enemy2, &ring, + &enemy1 + }; + if((count--) <= 0) + { + count = 64; + if(norm < ((VIEWLIMIT >> 1) + 8)) + { + this->shot_template_8_dir(shot[gamerand.get() & 7]); + } + } + if(health < 200) + { + this->shot_template_8_dir(&rock); + release(); + } +} +const enemy_kind enemy_m4 = { + 100, + &_enemy::make_enemy_m4, + &_enemy::move_enemy_m4, + &_enemy::kill_default, + 12, + B_BIGSHIP, 0, + LAYER_ENEMIES +}; + + +/*---------------------------------------------------------------------------*/ +/* void _enemy::make_xxxx(){} + * void _enemy::move_xxxx(){} + * void _enemy::die_xxxx(){} + * enemy_kind xxxxx = { + * score, + * make_xxxx, move_xxxx, die_xxx, + * hitsize, + * bank, frame, tilesize + * }; + */ diff --git a/filemap.cpp b/filemap.cpp new file mode 100644 index 0000000..e0d75e8 --- /dev/null +++ b/filemap.cpp @@ -0,0 +1,857 @@ +/*(LGPL) +------------------------------------------------------------ + filemap.cpp - Simple Portable File Path Mapper +------------------------------------------------------------ + * Copyright (C) David Olofson, 2001, 2003, 2007 + * This code is released under the terms of the GNU LGPL. + */ + +#include "config.h" +#include "kobolog.h" + +#include "filemap.h" + +#include +#include +#include +#include + +#ifdef HAVE_STAT +#include +#include +#endif + + +fm_object_t::~fm_object_t() +{ + free(path); +} + + +/* + * Delete the 'count' first bytes of a string. + * Does *not* realloc(), so it's safe to use + * on static or local (stack) buffers. + * + * Returns new length of string. + */ +static int strdel(char *str, int count) +{ + int len = strlen(str); + memmove(str, str+count, len-count+1); + return len-count; +} + + +/* + * Inserts string 'ins' into 'str', starting at 'pos'. + * Does *not* realloc(), so it's safe to use + * on static or local (stack) buffers. + * + * Relies on FM_BUFFER_SIZE to prevent buffer overflow! + * (In fact, it stops at (str + FM_BUFFER_SIZE - 1) to + * ensure that the result is NULL terminated.) + * + * Returns new length of string. + */ +static int strins(char *str, const char *ins, int pos) +{ + char *cpy = strdup(str+pos); + if(!cpy) + return strlen(str); //Silly but harmless... + + snprintf(str+pos, FM_BUFFER_SIZE-pos-1, "%s%s", ins, cpy); + str[FM_BUFFER_SIZE - 1] = 0; + free(cpy); + return strlen(str); +} + + +filemapper_t::filemapper_t() +{ + keys = NULL; + app_path = strdup("."); + next_buffer = 0; + objects = NULL; + current_obj = NULL; + + /* + * I'll put this here for now. + * Don't know if it's the perfect place... + */ + char *home = (char *)getenv("HOME"); + if(home) + addpath("HOME", home); +} + + +filemapper_t::~filemapper_t() +{ + fm_key_t *k = keys; + while(k) + { + fm_key_t *nk = k->next; + free(k->path); + delete k; + k = nk; + } + while(objects) + { + fm_object_t *o = objects; + objects = objects->next; + delete o; + } + free(app_path); +} + + +char *filemapper_t::salloc() +{ + char *b = buffers[next_buffer++]; + if(next_buffer >= FM_BUFFERS) + next_buffer = 0; + return b; +} + + +void filemapper_t::no_double_slashes(char *buf) +{ + /* + * Clean slashes + */ + char *c = buf; + while(c[0]) + { + if(c[0] == '/') + { + if(0 == c[1]) + c[0] = 0; + else + while('/' == c[1]) + strdel(c + 1, 1); + } + ++c; + } +} + + +void filemapper_t::unix_slashes(char *buf) +{ + /* + * Convert "~/" into "HOME>>". + */ + if(strncmp(buf, "~/", 2) == 0) + { + strdel(buf, 2); + strins(buf, "HOME" FM_DEREF_TOKEN, 0); + } + +#if defined(WIN32) + int len = strlen(buf); + for(int i = 0; i < len; ++i) + if(buf[i] == '\\') + buf[i] = '/'; +#elif defined(MACOS) + int start = 0; + int len = strlen(buf); + for(int i = start; i < len; ++i) + if(buf[i] == ':') + buf[i] = '/'; +#endif + no_double_slashes(buf); +} + + +void filemapper_t::sys_slashes(char *buf) +{ + no_double_slashes(buf); + +#if defined(WIN32) + int len; + if(strncmp(buf, "./", 2) == 0) + len = strdel(buf, 2); + else + len = strlen(buf); + for(int i = 0; i < len; ++i) + if(buf[i] == '/') + buf[i] = '\\'; +#elif defined(MACOS) + /* + * Untested. + */ + int len; + if(strncmp(buf, "./", 2) == 0) + len = strdel(buf, 2); + else + len = strlen(buf); + /* Fix absolute/relative */ + if(buf[0] == '/') + len = strdel(buf, 1); + else + { + memmove(buf + 1, buf, len); + ++len; + buf[0] = ':'; + } + /* + * '/' --> ':' + */ + for(int i = 0; i < len; ++i) + if(buf[i] == '/') + buf[i] = ':'; + /* + * "..:" --> "::" + */ + for(int i = 0; i < len; ++i) + if(strncmp(buf + i, "..:", 3) == 0) + { + strdel(buf + i, 1); + buf[i] = ':'; + --len; + } +#endif +} + + +void filemapper_t::exepath(const char *appname) +{ + free(app_path); + app_path = strdup(sys2unix(appname)); + if(app_path) + { + char *c = strrchr(app_path, '/'); + if(c) + c[0] = 0; + else + { + free(app_path); + app_path = strdup("."); + } + } + else + app_path = strdup("."); + addpath("EXE", app_path); + log_printf(DLOG, "Application path: '%s'\n", app_path); +} + + +void filemapper_t::addpath(const char *key, const char *path, int first) +{ + fm_key_t *k, *insk; + try + { + k = new fm_key_t; + strncpy(k->key, key, 8); + k->key[8] = 0; + k->path = strdup(path); + if(!k->path) + { + delete k; + return; + } + if(first) + { + k->next = keys; + keys = k; + } + else + { + k->next = NULL; + if(keys) + { + insk = keys; + while(insk->next) + insk = insk->next; + insk->next = k; + } + else + keys = k; + } + } + catch(...) + { + return; + } +} + + +fm_key_t *filemapper_t::getkey(fm_key_t *key, const char *ref) +{ + int all = ref ? 0 : (ref[0] == '*'); + if(key) + { + if(!ref) + ref = key->key; + else if(all) + return key->next; + else + key = key->next; + } + else + { + if(!ref || all) + return keys; + else + key = keys; + } + + while(key) + { + if(strcmp(key->key, ref) == 0) + return key; + key = key->next; + } + return NULL; +} + + +/* + * Checks if an object exists, and if so, what kind it is. + */ +int filemapper_t::probe(const char *syspath) +{ +#ifdef HAVE_STAT + struct stat st; +// log_printf(DLOG, "probe(\"%s\") (with stat())\n", syspath); + if(::stat(syspath, &st) == 0) + { + if(S_ISDIR(st.st_mode)) + return FM_DIR; + else + return FM_FILE; + } +#else +#warning This platform lacks stat(). File/directory probing may be unreliable! + // This is wrong and weird, but *does* in fact + // work on Linux... where it isn't needed! *heh* + // (Opening a dir with "r" will succeed on Linux, BTW...) + FILE *f = ::fopen(syspath, "r+"); +// log_printf(DLOG, "probe(\"%s\") (with fopen())\n", syspath); + if(f) + { + ::fclose(f); + return FM_FILE; + } + else + if(errno == EISDIR) + return FM_DIR; +#endif + return FM_ERROR; +} + + +/* + * Create a file for writing, or if it exists, test if it + * can be opened in write mode. + * + * Returns + * FM_FILE if the file exists and is writable, + * FM_FILE_CREATE if the file had to be created, + * FM_DIR if the path leads to a directory, or + * FM_ERROR if the object is not a writable file. + */ +int filemapper_t::test_file_create(const char *syspath) +{ + int exists = (probe(syspath) == FM_FILE); + FILE *f = ::fopen(syspath, "a"); + if(f) + { + fclose(f); + if(exists) + { +// log_printf(DLOG, " File is writable!\n"); + return FM_FILE; + } + else + { +// log_printf(DLOG, " File created!\n"); + return FM_FILE_CREATE; + } + } + else + { + if(errno == EISDIR) + { +// log_printf(DLOG, " Is a directory.\n"); + return FM_DIR; + } +// else +// log_printf(DLOG, " Nope.\n"); + } + return FM_ERROR; +} + + +int filemapper_t::test_file_dir_any(const char *syspath, int kind) +{ + int res = probe(syspath); + switch (res) + { + case FM_ERROR: +// log_printf(DLOG, " Nope.\n"); + break; + case FM_FILE: + if((kind == FM_ANY) || (kind == FM_FILE)) + { +// log_printf(DLOG, " Found! (File)\n"); + return 1; + } + break; + case FM_DIR: + if((kind == FM_ANY) || (kind == FM_DIR)) + { +// log_printf(DLOG, " Found! (Dir)\n"); + return 1; + } + break; + case FM_ANY: + log_printf(ELOG, "INTERNAL ERROR: filemapper_t::probe()" + " returned FM_ANY...\n"); + break; + } + if(res != FM_ERROR) + switch (kind) + { + case FM_FILE: +// log_printf(DLOG, " Not a file.\n"); + break; + case FM_DIR: +// log_printf(DLOG, " Not a directory.\n"); + break; + default: + break; + } + return 0; +} + + +char *filemapper_t::sys2unix(const char *syspath) +{ + char *buffer = salloc(); + strncpy(buffer, syspath, FM_BUFFER_SIZE - 1); + buffer[FM_BUFFER_SIZE - 1] = 0; + unix_slashes(buffer); + return buffer; +} + + +char *filemapper_t::unix2sys(const char *path) +{ + char *buffer = salloc(); + strncpy(buffer, path, FM_BUFFER_SIZE - 1); + buffer[FM_BUFFER_SIZE - 1] = 0; + sys_slashes(buffer); + return buffer; +} + + +/* + * Try the specified operation on a path. + * The path must be in *system* format. + */ +int filemapper_t::try_get(const char *path, int kind) +{ + switch (kind) + { + case FM_FILE: + case FM_DIR: + case FM_ANY: + if(test_file_dir_any(path, kind)) + return 1; + break; + case FM_FILE_CREATE: + switch (test_file_create(path)) + { + case FM_FILE: + case FM_FILE_CREATE: + return 1; + default: + break; + } + break; + default: + break; + } + return 0; +} + + +void filemapper_t::add_object(const char *path, int kind) +{ + try + { + fm_object_t *obj = new fm_object_t; + obj->path = strdup(path); + if(!obj->path) + { + delete obj; + return; + } + obj->kind = kind; + + obj->next = NULL; + if(objects) + { + fm_object_t *insobj = objects; + while(insobj->next) + insobj = insobj->next; + insobj->next = obj; + } + else + objects = obj; + } + catch(...) + { + return; + } +} + + +/* + * Parse the specified path, recurse through all possible + * combinations, trying each terminal with try_get(). + * + * When the 'build' argument is 0, the function returns + * the first valid hit. + * + * 'ref' must be in unix format, but 'result' will be in + * system format. + * + * NEW MODE: + * When the 'build' argument is non-zero, all + * possible paths are generated and tested. All + * valid objects are added to a linked list of + * fm_object_t. + * + * Note that in this mode, 'result' is not used + * or set! You may pass NULL. + * +TODO: Wildcards... + * + */ +int filemapper_t::recurse_get(char *result, const char *ref, int kind, + int level, int build) +{ +// log_printf(DLOG, " [level %d]\n", level); + char buffer[FM_BUFFER_SIZE]; + strncpy(buffer, ref, FM_BUFFER_SIZE); + + // Check for the ">>" dereferencing token. + char *obj = (char *)strstr(ref, FM_DEREF_TOKEN); + + // If there isn't one, the object path will + // be tried as is. + if(!obj) + { + int res; + snprintf(buffer, FM_BUFFER_SIZE, "%s", ref); + buffer[FM_BUFFER_SIZE-1] = 0; +#if 0 + { + for(int s=0; s>" + if(len > 8) + len = 8; + memcpy(kclass, ref, len); + kclass[len] = 0; + + fm_key_t *k = NULL; + int hits = 0; + while( (k = getkey(k, kclass)) ) + { + ++hits; + snprintf(buffer, FM_BUFFER_SIZE, "%s/%s", k->path, obj); + buffer[FM_BUFFER_SIZE-1] = 0; +#if 0 + { + for(int s=0; spath); + if(dt[2] == '/') // No slash after ">>"! + strdel(dt + 2, 1); + res = recurse_get(buffer, buffer, kind, level + 1, + build); + } + else + { +// log_printf(DLOG, "Trying '%s' -> '%s'...", k->key, +// k->path); + sys_slashes(buffer); + res = try_get(buffer, kind); + if(build && res) + add_object(buffer, kind); + } + if(res && !build) + { + strncpy(result, buffer, FM_BUFFER_SIZE); + return 1; + } + } +#if 0 + if(!hits) + { + for(int s=0; snext; + delete obj; + } + + if(kind == FM_FILE_CREATE) + { +// log_printf(ELOG, "filemapper_t: Tried to create files" +// " in get_all()!\n"); + return; + } +#if 0 + else if(kind == FM_DIR) + log_printf(DLOG, "get_all('%s', DIR)...", ref); + else + log_printf(DLOG, "get_all('%s')...", ref); +#endif + recurse_get(NULL, ref, kind, 1, 1); + current_obj = objects; + current_dir = NULL; +} + + +const char *filemapper_t::get_next() +{ + while(1) + { + if(!current_dir) + { + // + // Get next object! + // + if(!current_obj) + return NULL; //All done. + + switch(probe(current_obj->path)) + { + case FM_FILE: + { + const char *res = current_obj->path; + current_obj = current_obj->next; +// log_printf(DLOG, "get_next() found file '%s'.\n", res); + return res; + } + case FM_DIR: + current_dir = ::opendir(current_obj->path); +// log_printf(DLOG, "get_next() found dir '%s'.\n", +// current_obj->path); + if(!current_dir) + { + //Couldn't opendir()! Skip object... + current_obj = current_obj->next; + continue; + } + break; + default: + //Probing failed! Skip this object. +// log_printf(DLOG, "get_next(): Object '%s' skipped!\n", +// current_obj->path); + current_obj = current_obj->next; + continue; + } + } + + // + // Get first/next dir entry! + // + struct dirent *d = readdir(current_dir); + if(!d) + { + // Error or end-of-dir ==> try next object + closedir(current_dir); + current_dir = NULL; + current_obj = current_obj->next; +// log_printf(DLOG, "get_next(): end-of-dir\n"); + continue; + } + + // Get dir entry + char *path = salloc(); + if(!path) + { + log_printf(CELOG, "Out of memory in get_next()!\n", path); + return NULL; + } + + // Skip "parent dir" links! +#ifdef MACOS + if(!strcmp(d->d_name, "::")) //??? +#else + if(!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) +#endif + continue; + + // Check dir entry! + snprintf(path, FM_BUFFER_SIZE, +#ifdef WIN32 + "%s\\%s", +#elif defined(MACOS) + "%s:%s", +#else + "%s/%s", +#endif + current_obj->path, d->d_name); + switch(probe(path)) + { + case FM_FILE: +// log_printf(DLOG, "get_next() found file '%s'.\n", path); + return path; + case FM_DIR: + //We don't do recursive, so skip subdirs... +// log_printf(DLOG, "get_next() found dir '%s'.\n", path); + continue; + default: +// log_printf(DLOG, "get_next() found crap in dir.\n"); + continue; + } + } +} + + +FILE *filemapper_t::fopen(const char *ref, const char *mode) +{ + const char *path = NULL; + int md = 0; + + if(strchr(mode, 'r')) + md = 1; + else if(strchr(mode, 'w')) + md = 3; + else if(strchr(mode, 'a')) + md = 5; + if(md) + if(strchr(mode, '+')) + md += 1; + + switch(md) + { + case 0: //Error! + return NULL; + case 1: //r + case 2: //r+ + path = get(ref, FM_FILE); + break; + case 3: //w + case 4: //w+ + case 5: //a + case 6: //a+ + path = get(ref, FM_FILE_CREATE); + break; + } + if(path) + return ::fopen(path, mode); + else + return NULL; +} + + +DIR *filemapper_t::opendir(const char *ref) +{ + const char *path = get(ref, FM_DIR); + if(path) + return ::opendir(path); + else + return NULL; +} + + +int filemapper_t::mkdir(const char *ref, int perm) +{ + log_printf(ELOG, "filemapper_t::mkdir() not yet implemented!\n"); + return -1; +#if 0 + const char *path = get(ref, FM_DIR_CREATE); +// ::mkdir(path, perm); +#endif +} + + +void filemapper_t::print(FILE *f, const char *ref) +{ + char key[9]; + key[8] = 0; + char *obj = (char *)strstr(ref, FM_DEREF_TOKEN); + if(!obj) + strncpy(key, ref, 8); + else + { + int len = obj - ref; + strncpy(key, ref, 8); + if(len > 8) + len = 8; + key[len] = 0; + } + int all = (key[0] == '*'); + fm_key_t *k = keys; + while(k) + { + if(strcmp(k->key, key) == 0 || all) + fprintf(f, "%s"FM_DEREF_TOKEN" --> \"%s\"\n", k->key, k->path); + k = k->next; + } +} diff --git a/filemap.h b/filemap.h new file mode 100644 index 0000000..de091a0 --- /dev/null +++ b/filemap.h @@ -0,0 +1,170 @@ +/* +------------------------------------------------------------ + filemap.h - Simple Portable File Path Mapper +------------------------------------------------------------ + * © David Olofson, 2001 + * This code is released under the terms of the GNU LGPL. + */ + +/* + * Path syntax: + * All filemapper_t functions but exepath() + * and sys2unix() (obviously!) expect paths in the + * native system format. + * + * ALL OTHER PATHS SHOULD BE IN UNIX FORMAT. + * + * All arguments that are expected to be in system + * format are named along the lines of "syspath". + * + * Classes: + * The 'class>>' construct expands to one of the + * paths registered for 'class', or makes the mapping + * fail (NULL is returned), if the object doesn't + * exist or cannot be created as applicable. + * + * Class references are recursive, and are resolved + * late, at mapping time. (That is, they are resolved + * when someone asks for it, not when registering + * paths.) + * + * Class "HOME>>" is built-in, and resolves to the + * root of the user home directory. (Currently + * looks only at the environment variable "HOME", + * which may not be defined on all platforms.) + * + * Class "EXE>>" is another built-in, and refers to + * the path extracted from exepath(). + */ + +#ifndef _FILEMAP_H_ +#define _FILEMAP_H_ + +#include "aconfig.h" + +#define FM_DEREF_TOKEN ">>" + +#include +#include + +#define FM_BUFFERS 16 +#define FM_BUFFER_SIZE 512 + + +struct fm_key_t +{ + fm_key_t *next; + char key[10]; + char *path; +}; + + +enum +{ + FM_ERROR = 0, + FM_FILE, + FM_DIR, + FM_ANY, + FM_FILE_CREATE, + FM_DIR_CREATE +}; + + +// Not a great name - but fm_path_t would just be confusing, +// and an fm_object_t can actually be either a dir or a file. +struct fm_object_t +{ + fm_object_t *next; + char *path; + int kind; + ~fm_object_t(); +}; + + +class filemapper_t +{ + // For get_(first|next)() + fm_object_t *objects; + fm_object_t *current_obj; + DIR *current_dir; + + // File mapper keys + fm_key_t *keys; + + // Application executable path + char *app_path; + + // Silly/safe/string alloc :-) + char buffers[FM_BUFFERS][FM_BUFFER_SIZE]; + int next_buffer; + char *salloc(); + + // Various private funcs + void no_double_slashes(char *buf); + void unix_slashes(char *buf); + void sys_slashes(char *buf); + int probe(const char *syspath); + int test_file_create(const char *syspath); + int test_file_dir_any(const char *syspath, int kind); + int try_get(const char *path, int kind); + void add_object(const char *path, int kind); + int recurse_get(char *result, const char *ref, int kind, + int level, int build); + public: + filemapper_t(); + ~filemapper_t(); + + // Set/get path to exe file. + // Note that exepath() expects a + // path in the *native system* format, + // while exepath() returns a Unix path. + void exepath(const char *syspath); + const char *exepath() { return app_path; } + + // Add 'path' to class 'key'. + // Key should be given *without* the '::'. + void addpath(const char *key, const char *path, int first = 0); + + // key == NULL, ref == NULL or "*": + // Get first key. + // key == NULL, ref == : + // Get first key of class 'ref'. + // key == , ref == NULL: + // Get next key of same class as 'key'. + // key == , ref == : + // Get next key of class 'ref'. + // The "*" wildcard for 'ref' is allowed. + // Returns NULL if no key was found. + fm_key_t *getkey(fm_key_t *key = NULL, const char *ref = NULL); + + // Get object path (returns path in system format!) + const char *get(const char *ref, int kind = FM_FILE); + +/* +FIXME: Do these really handle the 'kind' argument properly...? +FIXME: When looking for files, they should return only files +FIXME: matching the 'ref' path, while when looking for dirs, +FIXME: every file inside each matching dir should be returned. +*/ + // Initialize path scan. Use get_next() to get the + // paths to all matches. + void get_all(const char *ref, int kind = FM_FILE); + + // Get next object (returns path in system format!) + const char *get_next(); + + // Open/create file/dir. + FILE *fopen(const char *ref, const char *mode); + DIR *opendir(const char *ref); + int mkdir(const char *ref, int perm); + + // Print out all registered paths of class 'ref' + // to stream 'f'. (ref == '*') ==> All classes. + void print(FILE *f, const char *ref); + + // Translate to and from the internal Unix-like path format + char *sys2unix(const char *syspath); + char *unix2sys(const char *path); +}; + +#endif diff --git a/form.cpp b/form.cpp new file mode 100644 index 0000000..6d0375a --- /dev/null +++ b/form.cpp @@ -0,0 +1,321 @@ +/*(GPL) +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 2001, 2002, 2007 David Olofson + * Copyright (C) 2005 Erik Auerswald + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define DBG(x) + +#include "kobolog.h" +#include "config.h" +#include "form.h" +#include "kobo.h" +#include "audio.h" + +kobo_form_t::kobo_form_t() +{ + ypos = 0; + current_list = NULL; + _big = 0; + xoffs = 0.5; + halign = ALIGN_DEFAULT; +} + + +kobo_form_t::~kobo_form_t() +{ +} + + +void kobo_form_t::next() +{ + sound.ui_move(); + ct_form_t::next(); +} + + +void kobo_form_t::prev() +{ + sound.ui_move(); + ct_form_t::prev(); +} + + +/* virtual */ void kobo_form_t::change(int delta) +{ + ct_form_t::change(delta); + if(selected()->user) + { + int *val = (int *)selected()->user; + *val = selected()->value(); + DBG(log_printf(D2LOG, "Changed to %d\n", selected()->value());) + } +} + + +/* virtual */void kobo_form_t::build() +{ +} + + +void kobo_form_t::init_widget(ct_widget_t *w) +{ + current_widget = w; + w->init(engine); + switch(_big) + { + case 0: + w->place(x(), y()+ypos, width(), LINE_H); + w->font(B_NORMAL_FONT); + ypos += LINE_H; + break; + case 1: + w->place(x(), y()+ypos, width(), BIG_LINE_H); + w->font(B_BIG_FONT); + ypos += BIG_LINE_H; + break; + case 2: + w->place(x(), y()+ypos, width(), BIG_LINE_H); + w->font(B_MEDIUM_FONT); + ypos += BIG_LINE_H; + break; + } + w->halign(halign); + add(w); +} + + +void kobo_form_t::big() +{ + _big = 1; +} + + +void kobo_form_t::medium() +{ + _big = 2; +} + + +void kobo_form_t::small() +{ + _big = 0; +} + + +void kobo_form_t::begin() +{ + clean(); + ypos = 15; + current_list = NULL; + small(); +} + + +void kobo_form_t::label(const char *cap) +{ + ct_label_t *w = new ct_label_t(cap); + init_widget(w); +} + + +void kobo_form_t::yesno(const char *cap, int *var, int tag) +{ + current_list = new ct_list_t(cap); + current_list->offset(xoffs, 0); + current_list->user = var; + current_list->tag = tag; + current_list->add("Yes", 1); + current_list->add("No", 0); + init_widget(current_list); +} + + +void kobo_form_t::onoff(const char *cap, int *var, int tag) +{ + current_list = new ct_list_t(cap); + current_list->offset(xoffs, 0); + current_list->user = var; + current_list->tag = tag; + current_list->add("On", 1); + current_list->add("Off", 0); + init_widget(current_list); +} + + +void kobo_form_t::spin(const char *cap, int *var, int min, int max, + const char *unit, int tag) +{ + ct_spin_t *w = new ct_spin_t(cap, min, max, unit); + w->offset(xoffs, 0); + w->user = var; + w->tag = tag; + init_widget(w); +} + + +void kobo_form_t::list(const char *cap, int *var, int tag) +{ + ct_list_t *w = new ct_list_t(cap); + w->offset(xoffs, 0); + w->user = var; + w->tag = tag; + current_list = w; + init_widget(w); +} + + +void kobo_form_t::item(const char *cap, int value, int ind) +{ + if(current_list) + { + ct_item_t *i = new ct_item_t(cap, value); + i->index(ind); + current_list->add(i); + } + else + log_printf(ELOG, "kobo_form_t::form_item(): No list!\n"); +} + + +void kobo_form_t::perc_list(int first, int last, int step) +{ + char buf[50]; + for(int i = first; i <= last; i += step) + { + snprintf(buf, sizeof(buf), "%d%%", i); + item(buf, i); + } +} + + +void kobo_form_t::enum_list(int first, int last) +{ + char buf[50]; + for(int i = first; i <= last; i++) + { + snprintf(buf, sizeof(buf), "%d", i); + item(buf, i); + } +} + + +void kobo_form_t::button(const char *cap, int tag) +{ + ct_widget_t *w = new ct_button_t(cap); + w->offset(xoffs, 0); + w->tag = tag; + init_widget(w); +} + + +void kobo_form_t::data(config_parser_t *_d) +{ + _data = _d; +} + + +void kobo_form_t::editor(int handle, int tag) +{ + if(!_data) + return; + + switch(_data->type(handle)) + { + default: + log_printf(ELOG, "kobo_form_t: Unknown data type!\n"); + break; + case CFG_BOOL: + onoff(_data->description(handle), (int *)NULL, tag); + current_widget->user2 = handle; + break; + case CFG_INT: + case CFG_FLOAT: + spin(_data->description(handle), (int *)NULL, + -100000, 100000, "", tag); + current_widget->user2 = handle; + break; + case CFG_STRING: + log_printf(ELOG, "kobo_form_t: String editor not yet implemented!\n"); + break; + } +} + + +void kobo_form_t::editor(const char *name, int tag) +{ + if(!_data) + return; + + int h = _data->find(name); + if(h < 0) + return; + editor(h, tag); +} + + +void kobo_form_t::space(int lines) +{ + if(_big) + ypos += BIG_SPACE_SIZE * lines; + else + ypos += SPACE_SIZE * lines; +} + + +void kobo_form_t::end() +{ +} + + +void kobo_form_t::build_all() +{ + xoffs = 0.5; + begin(); + build(); + end(); + + /* + * Initialize all widgets from prefs and/or config_parser. + */ + ct_widget_t *w = widgets; + while(w) + { + if(w->user) + { + int *val = (int *)w->user; + if(val) + { + w->value(*val); + log_printf(D3LOG, "Initialized to %d from prefs\n", + w->value()); + } + else if(_data) + { + w->value(_data->get_i(w->user2)); + log_printf(D3LOG, "Initialized to %d from config_parser\n", + w->value()); + } + } + w = w->next; + if(w == widgets) + break; //Done! + } +} + diff --git a/form.h b/form.h new file mode 100644 index 0000000..cb518a4 --- /dev/null +++ b/form.h @@ -0,0 +1,84 @@ +/*(GPL) +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 2001, 2007 David Olofson + * Copyright (C) 2005 Erik Auerswald + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _KOBO_FORM_H_ +#define _KOBO_FORM_H_ + +#include "toolkit.h" +#include "cfgparse.h" + +#define LINE_H 9 +#define SPACE_SIZE 7 + +#define BIG_LINE_H 18 +#define BIG_SPACE_SIZE 14 + +class kobo_form_t : public ct_form_t +{ + config_parser_t *_data; + //Called by build_all(). + void begin(); + void end(); + protected: + ct_widget_t *current_widget; + ct_list_t *current_list; + int ypos; + int _big; + float xoffs; + ct_align_t halign; + virtual void init_widget(ct_widget_t *wg); + + //Toolkit + void big(); + void medium(); + void small(); + void label(const char *cap); + void yesno(const char *cap, int *var, int tag = 0); + void onoff(const char *cap, int *var, int tag = 0); + void spin(const char *cap, int *var, int min, int max, + const char *unit, int tag = 0); + void button(const char *cap, int tag = 0); + void space(int lines = 1); + + //config_parser_t aware version! :-) + void data(config_parser_t *_d); + void editor(int handle, int tag = 0); + void editor(const char *name, int tag = 0); + + //List tools + void list(const char *cap, int *var, int tag = 0); + void item(const char *cap, int value, int ind = 0); + void perc_list(int first, int last, int step); + void enum_list(int first, int last); + + //Internal wrapper for build() + void build_all(); + public: + kobo_form_t(); + virtual ~kobo_form_t(); + void next(); + void prev(); + virtual void change(int delta); + virtual void build(); +}; + +#endif diff --git a/game.cpp b/game.cpp new file mode 100644 index 0000000..1a54f0a --- /dev/null +++ b/game.cpp @@ -0,0 +1,138 @@ +/*(GPL) +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 2002, 2007 David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "config.h" +#include "game.h" + +game_t game; + + +game_t::game_t() +{ + reset(); +} + + +void game_t::reset() +{ + set(GAME_SINGLE, SKILL_CLASSIC); +} + + +void game_t::set(game_types_t tp, skill_levels_t sk) +{ + type = tp; + skill = sk; + + // Game and player + speed = 30; + lives = 5; + bonus_first = 2000; + bonus_every = 3000; + health = 1; + health_fade = 5; + damage = 0; + bolts = 10; + bolt_damage = 20; + noseloadtime = 1; + noseheatup = 0; + nosecooling = 256; + altfire = 0; + tailloadtime = 1; + tailheatup = 0; + tailcooling = 256; + + // Enemies + rock_health = 255 * bolt_damage; + rock_damage = 1000; + + switch(skill) + { + case SKILL_CLASSIC: + break; + case SKILL_NEWBIE: + speed = 40; + lives = 5; + bonus_first = 5000; + bonus_every = 7000; + health = 100; + damage = 100; + bolts = MAX_BOLTS; + noseloadtime = 1; + noseheatup = 14; + nosecooling = 5; + tailloadtime = 0; + tailheatup = 7; + tailcooling = 5; + altfire = 1; + rock_health = 200; + rock_damage = 50; + break; + case SKILL_GAMER: + speed = 30; + lives = 5; + bonus_first = 8000; + bonus_every = 8000; + health = 60; + damage = 100; + bolts = MAX_BOLTS; + noseloadtime = 0; + noseheatup = 10; + nosecooling = 5; + tailloadtime = 1; + tailheatup = 20; + tailcooling = 5; + rock_health = 500; + rock_damage = 50; + break; + case SKILL_ELITE: + speed = 27; + lives = 4; + bonus_first = 10000; + bonus_every = 10000; + health = 50; + damage = 50; + bolts = MAX_BOLTS; + noseloadtime = 1; + noseheatup = 26; + nosecooling = 5; + tailloadtime = 2; + tailheatup = 39; + tailcooling = 5; + break; + case SKILL_GOD: + default: + speed = 25; + lives = 3; + bonus_first = 10000; + bonus_every = 10000; + health = 40; + damage = 30; + bolts = MAX_BOLTS; + noseloadtime = 1; + noseheatup = 30; + nosecooling = 5; + tailloadtime = 2; + tailheatup = 45; + tailcooling = 5; + break; + } +} diff --git a/game.h b/game.h new file mode 100644 index 0000000..d4b0b7d --- /dev/null +++ b/game.h @@ -0,0 +1,83 @@ +/*(GPL) +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 2002, 2007 David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _KOBO_GAME_H_ +#define _KOBO_GAME_H_ + +// Max number of player bolts flying +#define MAX_BOLTS 40 + +enum game_types_t +{ + GAME_UNKNOWN = -1, + GAME_SINGLE, + GAME_SINGLE_NEW, + GAME_COOPERATIVE, + GAME_DEATHMATCH, + GAME_EXPERIMENTAL = 0x10000000 // Testing! No official highscores. +}; + + +enum skill_levels_t +{ + SKILL_UNKNOWN = -1, + SKILL_CLASSIC, + SKILL_NEWBIE, + SKILL_GAMER, + SKILL_ELITE, + SKILL_GOD +}; + +class game_t +{ + public: + int type; + int skill; + int speed; // ms per logic frame + int lives; // When starting new games of certain types + int bonus_first; // First bonus ship at this score + int bonus_every; // New bonus ship every N points + int health; // Initial health + int health_fade; // Health fade period (logic frames/unit) + int damage; // Damage player inflicts when colliding with + // another object + int bolts; // maximum active at a time + int noseloadtime; // logic frames per nose shot + int noseheatup; // nose cannon heatup per shot + int nosecooling; // nose cannon cooling speed + int altfire; // use wing mounted cannons and stuff + int tailloadtime; // logic frames per tail shot + int tailheatup; // tail cannon heatup per shot + int tailcooling; // tail cannon cooling speed + int bolt_damage; // Damage inflicted by player fire bolt + + // Enemies + int rock_health; + int rock_damage; + + game_t(); + void reset(); + void set(game_types_t tp, skill_levels_t sk); +}; + +extern game_t game; + +#endif /*_KOBO_GAME_H_*/ diff --git a/gamectl.cpp b/gamectl.cpp new file mode 100644 index 0000000..48c7054 --- /dev/null +++ b/gamectl.cpp @@ -0,0 +1,409 @@ +/* +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 1995, 1996, Akira Higuchi + * Copyright (C) 2001 - 2003, 2006, David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "manage.h" +#include "kobo.h" +#include "gamectl.h" +#include "myship.h" + + +int gamecontrol_t::afire; +int gamecontrol_t::r_delay = 250; +int gamecontrol_t::r_interval = 40; +int gamecontrol_t::space; +int gamecontrol_t::left; +int gamecontrol_t::up; +int gamecontrol_t::down; +int gamecontrol_t::right; +int gamecontrol_t::dl; +int gamecontrol_t::dr; +int gamecontrol_t::ul; +int gamecontrol_t::ur; +int gamecontrol_t::shot; +int gamecontrol_t::direction = 1; +int gamecontrol_t::new_direction = 0; +int gamecontrol_t::latch_timer = 0; +int gamecontrol_t::movekey_pressed; + + +void gamecontrol_t::init(int always_fire) +{ + afire = always_fire; + left = 0; + right = 0; + up = 0; + down = 0; + shot = 0; + movekey_pressed = 0; + SDL_EnableKeyRepeat(r_delay, r_interval); +} + + +gamecontrol_t::gamecontrol_t() +{ + init(0); +} + + +void gamecontrol_t::repeat(int delay, int interval) +{ + r_delay = delay; + r_interval = interval; + //Temporary kludge - should apply repeat to + //all switch inputs, not just the keyboard! + SDL_EnableKeyRepeat(delay, interval); +} + + +void gamecontrol_t::clear() +{ + direction = 1; +} + + +int gamecontrol_t::map(SDLKey sym) +{ +/* +FIXME: This should be replaced by a configurable mapping system. +*/ + switch(sym) + { + case KEY_KP_LEFT: + case SDLK_LEFT: + return BTN_LEFT; + case KEY_KP_RIGHT: + case SDLK_RIGHT: + return BTN_RIGHT; + case KEY_KP_UP: + case SDLK_UP: + return BTN_UP; + case KEY_KP_DOWN: + case SDLK_DOWN: + return BTN_DOWN; + case KEY_KP_DL: + return BTN_DL; + case KEY_KP_DR: + return BTN_DR; + case KEY_KP_UL: + return BTN_UL; + case KEY_KP_UR: + return BTN_UR; + + case SDLK_PAGEUP: + if(prefs->broken_numdia) + return BTN_UR; + else + return BTN_NEXT; + case SDLK_PAGEDOWN: + if(prefs->broken_numdia) + return BTN_DR; + else + return BTN_PREV; + case SDLK_HOME: + if(prefs->broken_numdia) + return BTN_UL; + else + return -1; + case SDLK_END: + if(prefs->broken_numdia) + return BTN_UL; + else + return -1; + + case SDLK_LSHIFT: + case SDLK_RSHIFT: + case SDLK_LCTRL: + case SDLK_RCTRL: + return BTN_FIRE; + case SDLK_ESCAPE: + return BTN_EXIT; + case SDLK_PAUSE: + case SDLK_p: + return BTN_PAUSE; + case SDLK_SPACE: + return BTN_START; + case SDLK_KP_ENTER: + case SDLK_RETURN: + return BTN_SELECT; + case SDLK_KP_PLUS: + return BTN_INC; + case SDLK_KP_MINUS: + return BTN_DEC; + case SDLK_y: + return BTN_YES; + case SDLK_n: + return BTN_NO; + case SDLK_BACKSPACE: + return BTN_BACK; + case SDLK_F1: + return BTN_F1; + case SDLK_F2: + return BTN_F2; + case SDLK_F3: + return BTN_F3; + case SDLK_F4: + return BTN_F4; + case SDLK_F5: + return BTN_F5; + case SDLK_F6: + return BTN_F6; + case SDLK_F7: + return BTN_F7; + case SDLK_F8: + return BTN_F8; + case SDLK_F9: + return BTN_F9; + case SDLK_F10: + return BTN_F10; + case SDLK_F11: + return BTN_F11; + case SDLK_F12: + return BTN_F12; + default: + return -1; + } +} + + +void gamecontrol_t::press(int k) +{ + switch(k) + { + case BTN_LEFT: + left = 1; + break; + case BTN_RIGHT: + right = 1; + break; + case BTN_UP: + up = 1; + break; + case BTN_DOWN: + down = 1; + break; + case BTN_UL: + ul = 1; + break; + case BTN_UR: + ur = 1; + break; + case BTN_DL: + dl = 1; + break; + case BTN_DR: + dr = 1; + break; + case BTN_FIRE: + shot = 1; + break; + } + gamecontrol_t::change(); +} + +void gamecontrol_t::release(int k) +{ + switch(k) + { + case BTN_LEFT: + left = 0; + break; + case BTN_RIGHT: + right = 0; + break; + case BTN_UP: + up = 0; + break; + case BTN_DOWN: + down = 0; + break; + case BTN_UL: + ul = 0; + break; + case BTN_UR: + ur = 0; + break; + case BTN_DL: + dl = 0; + break; + case BTN_DR: + dr = 0; + break; + case BTN_FIRE: + shot = 0; + break; + } + gamecontrol_t::change(); +} + + +void gamecontrol_t::mouse_press(int n) +{ + if(n == 1) + shot = 1; +// else if(n == 3) +// manage.key_down(KEY_START); + gamecontrol_t::change(); +} + + +void gamecontrol_t::mouse_release(int n) +{ + if(n == 1) + shot = 0; + gamecontrol_t::change(); +} + + +void gamecontrol_t::mouse_position(int h, int v) +{ + switch(prefs->mousemode) + { + case MMD_OFF: + return; + case MMD_CROSSHAIR: + myship.put_crosshair(); + break; + case MMD_RELATIVE: + /* Insert delta pos sensitivity filter here */ + break; + } + if(h > 0) + { + if(v > 0) + { + if(h > (v << 1)) + direction = 3; + else if(v > (h << 1)) + direction = 5; + else + direction = 4; + } + else if(v <= 0) + { + if(h > ((-v) << 1)) + direction = 3; + else if((-v) > (h << 1)) + direction = 1; + else + direction = 2; + } + else + direction = 3; + } + else if(h <= 0) + { + if(v > 0) + { + if((-h) > (v << 1)) + direction = 7; + else if(v > ((-h) << 1)) + direction = 5; + else + direction = 6; + } + else if(v <= 0) + { + if((-h) > ((-v) << 1)) + direction = 7; + else if((-v) > ((-h) << 1)) + direction = 1; + else + direction = 8; + } + else + direction = 7; + } +} + + +void gamecontrol_t::change() +{ + int lr = left - right + ul - ur + dl - dr; + int ud = up - down + ul + ur - dl - dr; + if(lr > 0) + { + if(ud > 0) + new_direction = 8; + else if(ud < 0) + new_direction = 6; + else + new_direction = 7; + } + else if(lr < 0) + { + if(ud > 0) + new_direction = 2; + else if(ud < 0) + new_direction = 4; + else + new_direction = 3; + } + else + { + if(ud > 0) + new_direction = 1; + else if(ud < 0) + new_direction = 5; + else + new_direction = 0; + } + + if(prefs->dia_emphasis) + { + if(!new_direction) + { + //Change to neutral. Cancel delayed latch! + latch_timer = 0; + } + else if(!movekey_pressed) + { + //Change from neutral - latch immediately. + direction = new_direction; + latch_timer = 0; + } + else if(new_direction & 1) + { + //Change from diagonal! + latch_timer = prefs->dia_emphasis; + } + else + { + //Change to diagonal - latch immediately. + direction = new_direction; + latch_timer = 0; + } + } + else if(new_direction) + direction = new_direction; + + movekey_pressed = (new_direction != 0); + mouse_x = 0; + mouse_y = 0; +} + + +void gamecontrol_t::process() +{ + if(latch_timer) + if(!--latch_timer) + direction = new_direction; +} diff --git a/gamectl.h b/gamectl.h new file mode 100644 index 0000000..dfdebf2 --- /dev/null +++ b/gamectl.h @@ -0,0 +1,122 @@ +/* +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 1995, 1996, Akira Higuchi + * Copyright (C) 2001, 2002, 2006, David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _KOBO_GAMECTL_H_ +#define _KOBO_GAMECTL_H_ + +#include "glSDL.h" +#include "config.h" + +#define KEY_KP_DOWN SDLK_KP2 +#define KEY_KP_LEFT SDLK_KP4 +#define KEY_KP_UP SDLK_KP8 +#define KEY_KP_RIGHT SDLK_KP6 +#define KEY_KP_DL SDLK_KP1 +#define KEY_KP_DR SDLK_KP3 +#define KEY_KP_UL SDLK_KP7 +#define KEY_KP_UR SDLK_KP9 + + +enum buttons_t +{ + BTN_UP, //Joystick, arrows, numpad etc + BTN_DOWN, + BTN_LEFT, + BTN_RIGHT, + BTN_UL, + BTN_UR, + BTN_DL, + BTN_DR, + + BTN_INC, // + + BTN_DEC, // - + + BTN_NEXT, // PageUp + BTN_PREV, // PageDn + + BTN_YES, // 'Y' + BTN_NO, // 'N' + + BTN_FIRE, //ctrl, fire button, mouse button,... + BTN_START, //Space + BTN_SELECT, //Return, enter,... + BTN_EXIT, //ESC + BTN_PAUSE, //Pause or P; also used as an internal event. + BTN_CLOSE, //Window close button, ALT-F4,... + BTN_BACK, //Backspace + + BTN_F1, //Function keys + BTN_F2, + BTN_F3, + BTN_F4, + + BTN_F5, + BTN_F6, + BTN_F7, + BTN_F8, + + BTN_F9, + BTN_F10, + BTN_F11, + BTN_F12 +}; + + +enum mousemodes_t +{ + MMD_OFF = 0, + MMD_CROSSHAIR, + MMD_RELATIVE +}; + + +class gamecontrol_t +{ + static int r_delay, r_interval; + static int afire; + static int space; + static int left, up, down, right, ul, ur, dl, dr; + static int shot; + static int direction, new_direction; + static int latch_timer; + static int movekey_pressed; + static void change(); + public: + gamecontrol_t(); + static void init(int always_fire); + static void repeat(int delay, int interval); + static void clear(); + static int map(SDLKey sym); + static void process(); // Call every frame! + static void press(int k); + static void release(int k); + static void mouse_press(int n); + static void mouse_release(int n); + static void mouse_position(int h, int v); + static inline int dir() { return direction; } + static inline int get_shot() { return shot || afire; } + static inline int dir_push() { return movekey_pressed; } +}; + +extern gamecontrol_t gamecontrol; + +#endif //_KOBO_KEY_H_ diff --git a/gamestate.cpp b/gamestate.cpp new file mode 100644 index 0000000..a6ebe00 --- /dev/null +++ b/gamestate.cpp @@ -0,0 +1,206 @@ +/*(LGPL) +------------------------------------------------------------ + Game State Manager +------------------------------------------------------------ + * Copyright (C) 2001-2003, David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define DBG(x) + +#include +#include "logger.h" +#include "gamestate.h" + +/*---------------------------------------------------------- + gamestate_t +----------------------------------------------------------*/ + +gamestate_t::gamestate_t() +{ + next = 0; + manager = 0; + unicode = 0; +} + +gamestate_t::~gamestate_t() {} + +void gamestate_t::pop() +{ + if(!manager) + return; + //This is far from fool-proof, but it should + //handle the most common cases of "trying to + //pop 'this' more than once"... + if(manager->current() == this) + manager->pop(); + else + log_printf(WLOG, "GameStateManager: " + "WARNING: Tried to pop state more than once!\n"); +} + +void gamestate_t::enter() {} +void gamestate_t::leave() {} +void gamestate_t::yield() {} +void gamestate_t::reenter() {} +void gamestate_t::press(int button) {} +void gamestate_t::release(int button) {} +void gamestate_t::pos(int x, int y) {} +void gamestate_t::delta(int dx, int dy) {} +void gamestate_t::frame() {} +void gamestate_t::pre_render() {} +void gamestate_t::post_render() {} + + + +/*---------------------------------------------------------- + gamestatemanager_t +----------------------------------------------------------*/ + +gamestatemanager_t::gamestatemanager_t() +{ + top = 0; +} + + +gamestatemanager_t::~gamestatemanager_t() +{ +} + + +void gamestatemanager_t::change(gamestate_t *gs) +{ + gs->manager = this; + + gamestate_t *oldtop = top; + if(top) + top = top->next; + gs->next = top; + top = gs; + + if(oldtop) + { + oldtop->leave(); + oldtop->manager = 0; + } + if(top) + top->enter(); + + log_printf(DLOG, "GameStateManager: Switched to '%s'\n", gs->name); +} + + +void gamestatemanager_t::push(gamestate_t *gs) +{ + gs->manager = this; + + gamestate_t *oldtop = top; + gs->next = top; + top = gs; + + if(oldtop) + oldtop->yield(); + if(top) + top->enter(); + + log_printf(DLOG, "GameStateManager: Pushed state '%s'\n", gs->name); +} + + +void gamestatemanager_t::pop() +{ + gamestate_t *oldtop = top; + if(top) + top = top->next; + if(oldtop) + { + oldtop->leave(); + oldtop->manager = 0; + log_printf(DLOG, "GameStateManager: Popped state '%s'\n", oldtop->name); + } + if(top) + top->reenter(); +} + + +gamestate_t *gamestatemanager_t::current() +{ + return top; +} + + +gamestate_t *gamestatemanager_t::previous() +{ + if(top) + return top->next; + else + return NULL; +} + + +void gamestatemanager_t::press(int button, int unicode) +{ + if(top) + { + top->unicode = unicode; + top->press(button); + } +} + + +void gamestatemanager_t::release(int button, int unicode) +{ + if(top) + { + top->unicode = unicode; + top->release(button); + } +} + + +void gamestatemanager_t::pos(int x, int y) +{ + if(top) + top->pos(x, y); +} + + +void gamestatemanager_t::delta(int dx, int dy) +{ + if(top) + top->delta(dx, dy); +} + + +void gamestatemanager_t::frame() +{ + if(top) + top->frame(); +} + + +void gamestatemanager_t::pre_render() +{ + if(top) + top->pre_render(); +} + + +void gamestatemanager_t::post_render() +{ + if(top) + top->post_render(); +} diff --git a/gamestate.h b/gamestate.h new file mode 100644 index 0000000..2a7f872 --- /dev/null +++ b/gamestate.h @@ -0,0 +1,84 @@ +/*(LGPL) +------------------------------------------------------------ + Game State Manager +------------------------------------------------------------ + * Copyright (C) 2001-2003, David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _GAMESTATEMANAGER_H_ +#define _GAMESTATEMANAGER_H_ + +class gamestatemanager_t; + +class gamestate_t +{ + friend class gamestatemanager_t; + private: + gamestate_t *next; //LIFO stack + gamestatemanager_t *manager; + protected: + const char *name; + int unicode; //for last press()/release() + void pop(); + + virtual void press(int button); + virtual void release(int button); + virtual void pos(int x, int y); + virtual void delta(int dx, int dy); + + virtual void enter(); + virtual void leave(); + virtual void yield(); + virtual void reenter(); + + virtual void frame(); //Control system stuff + virtual void pre_render(); //Background rendering + virtual void post_render(); //Foreground rendering + public: + gamestate_t(); + virtual ~gamestate_t(); +}; + + +class gamestatemanager_t +{ + private: + gamestate_t *top; //Stack top + public: + gamestatemanager_t(); + ~gamestatemanager_t(); + + /* Event router interface */ + void press(int button, int unicode = 0); + void release(int button, int unicode = 0); + void pos(int x, int y); + void delta(int dx, int dy); + + /* CS frame and rendering callbacks */ + void frame(); + void pre_render(); + void post_render(); + + /* State management */ + void change(gamestate_t *gs); + void push(gamestate_t *gs); + void pop(); + gamestate_t *current(); + gamestate_t *previous(); +}; + +#endif /*_GAMESTATEMANAGER_H_*/ diff --git a/graphics/Makefile.am b/graphics/Makefile.am new file mode 100644 index 0000000..4579977 --- /dev/null +++ b/graphics/Makefile.am @@ -0,0 +1,10 @@ +noinst_LIBRARIES = libgraphics.a + +INCLUDES = @LOCALCFLAGS@ + +libgraphics_a_SOURCES = cs.c sprite.c filters.c glSDL.c \ + gfxengine.cpp window.cpp sofont.cpp \ + display.cpp toolkit.cpp vidmodes.c \ + region.c + +EXTRA_DIST = *.h diff --git a/graphics/Makefile.in b/graphics/Makefile.in new file mode 100644 index 0000000..d1dc39e --- /dev/null +++ b/graphics/Makefile.in @@ -0,0 +1,457 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = graphics +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/aconfig.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) +AR = ar +ARFLAGS = cru +libgraphics_a_AR = $(AR) $(ARFLAGS) +libgraphics_a_LIBADD = +am_libgraphics_a_OBJECTS = cs.$(OBJEXT) sprite.$(OBJEXT) \ + filters.$(OBJEXT) glSDL.$(OBJEXT) gfxengine.$(OBJEXT) \ + window.$(OBJEXT) sofont.$(OBJEXT) display.$(OBJEXT) \ + toolkit.$(OBJEXT) vidmodes.$(OBJEXT) region.$(OBJEXT) +libgraphics_a_OBJECTS = $(am_libgraphics_a_OBJECTS) +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +SOURCES = $(libgraphics_a_SOURCES) +DIST_SOURCES = $(libgraphics_a_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AUDIO_LIBS = @AUDIO_LIBS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_MACOSX_BUNDLE_FALSE = @BUILD_MACOSX_BUNDLE_FALSE@ +BUILD_MACOSX_BUNDLE_TRUE = @BUILD_MACOSX_BUNDLE_TRUE@ +BUILD_SIMPLE_BUNDLE_FALSE = @BUILD_SIMPLE_BUNDLE_FALSE@ +BUILD_SIMPLE_BUNDLE_TRUE = @BUILD_SIMPLE_BUNDLE_TRUE@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CONFIGDIR = @CONFIGDIR@ +CONFIGFILE = @CONFIGFILE@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXEFILE = @EXEFILE@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LOCALCFLAGS = @LOCALCFLAGS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MATHLIB = @MATHLIB@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +POW_LIB = @POW_LIB@ +RANLIB = @RANLIB@ +SCOREDIR = @SCOREDIR@ +SDL_CFLAGS = @SDL_CFLAGS@ +SDL_CONFIG = @SDL_CONFIG@ +SDL_LIBS = @SDL_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +UNIX_SCOREDIR_FALSE = @UNIX_SCOREDIR_FALSE@ +UNIX_SCOREDIR_TRUE = @UNIX_SCOREDIR_TRUE@ +VERSION = @VERSION@ +XMKMF = @XMKMF@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +noinst_LIBRARIES = libgraphics.a +INCLUDES = @LOCALCFLAGS@ +libgraphics_a_SOURCES = cs.c sprite.c filters.c glSDL.c \ + gfxengine.cpp window.cpp sofont.cpp \ + display.cpp toolkit.cpp vidmodes.c \ + region.c + +EXTRA_DIST = *.h +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .cpp .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign graphics/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign graphics/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libgraphics.a: $(libgraphics_a_OBJECTS) $(libgraphics_a_DEPENDENCIES) + -rm -f libgraphics.a + $(libgraphics_a_AR) libgraphics.a $(libgraphics_a_OBJECTS) $(libgraphics_a_LIBADD) + $(RANLIB) libgraphics.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cs.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/display.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filters.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gfxengine.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glSDL.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/region.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sofont.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sprite.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/toolkit.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vidmodes.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/window.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.cpp.o: +@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-noinstLIBRARIES ctags distclean distclean-compile \ + distclean-generic distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/graphics/cs.c b/graphics/cs.c new file mode 100644 index 0000000..1fd8af4 --- /dev/null +++ b/graphics/cs.c @@ -0,0 +1,720 @@ +/*(LGPL) + * Project Spitfire sprites + scrolling engine for SDL +---------------------------------------------------------------------- + cs.c - Simplistic Control System +---------------------------------------------------------------------- + * Copyright (C) 2001, 2003, 2007 David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define DBG(x) + +#include "cs.h" +#include "logger.h" +#include +#include +#include + +/*#define ABS(x) (((x)>=0) ? (x) : (-(x)))*/ +#define ABS(x) labs(x) + + +static inline void __wrap_point(cs_point_t *p, int wx, int wy) +{ + if(wx) + { + if(p->gx < 0) + p->gx += (-p->gx / wx + 1) * wx; + p->gx %= wx; + } + if(wy) + { + if(p->gy < 0) + p->gy += (-p->gy / wy + 1) * wy; + p->gy %= wy; + } +} + + +/* + * Make one point do it's thing... + */ +static inline void __move_point(cs_point_t *p, int wx, int wy) +{ + /* + * Push filter + */ + p->ox = p->v.x; + p->oy = p->v.y; + + /* + * Update position and speed + */ + p->v.x += p->v.xv; + p->v.y += p->v.yv; + p->v.xv += p->v.xa; + p->v.yv += p->v.ya; + + __wrap_point(p, wx, wy); +} + + +/* + * Update the motion filtered output of a point. + */ +static inline void __update_point_f(cs_point_t *p, int ff, int wx, int wy) +{ + int ogx = p->gx; + int ogy = p->gy; + int ox = p->ox; + int oy = p->oy; + + /* Unwrap filter for correct interpolation */ + if(wx | wy) + { + if((ox - p->v.x) > (wx >> 1)) + ox -= wx; + else if((p->v.x - ox) > (wx >> 1)) + ox += wx; + if((oy - p->v.y) > (wy >> 1)) + oy -= wy; + else if((p->v.y - oy) > (wy >> 1)) + oy += wy; + } + + /* + * Interpolate output graphics coordinate + */ + p->gx = (ff * p->v.x + (256 - ff) * ox) >> 8; + p->gy = (ff * p->v.y + (256 - ff) * oy) >> 8; + + /* + * Wrap interpolated output + */ + if(wx) + { + while(p->gx < 0) + p->gx += wx; + p->gx %= wx; + } + if(wy) + { + while(p->gy < 0) + p->gy += wy; + p->gy %= wy; + } + + /* + * Generate "changed" flag mask. + */ + p->changed = (ogx ^ p->gx) | (ogy ^ p->gy); +} + + +static inline void __update_point(cs_point_t *p, int ff) +{ + int ogx = p->gx; + int ogy = p->gy; + + /* + * Interpolate output graphics coordinate + */ + p->gx = p->v.x; + p->gy = p->v.y; + + /* + * Generate "changed" flag mask. + */ + p->changed = (ogx ^ p->gx) | (ogy ^ p->gy); +} + + +/* +---------------------------------------------------------------------- + * cs_obj_t +---------------------------------------------------------------------- + */ + +/* + * Final adjustment of interpolated graphics coords to deal + * with the display window wrapping over the edge of the world. + */ +static inline void __fix_wrap(cs_engine_t *e, cs_obj_t *o) +{ + if(o->point.gx + (o->w << __CS_SHIFT) < 0) + o->point.gx += e->wx; + else if(o->point.gx > (e->w << __CS_SHIFT)) + o->point.gx -= e->wx; + if(o->point.gy + (o->h << __CS_SHIFT) < 0) + o->point.gy += e->wy; + else if(o->point.gy > (e->h << __CS_SHIFT)) + o->point.gy -= e->wy; +} + + +static inline int __onscreen(cs_engine_t *e, cs_obj_t *o) +{ + int gx = CS2PIXEL(o->point.gx); + int gy = CS2PIXEL(o->point.gy); + if((gx + o->w < 0) || (gx > e->w)) + return 0; + if((gy + o->h < 0) || (gy > e->h)) + return 0; + return 1; +} + + +static inline void __obj_set_layer(cs_obj_t *o, unsigned int layer) +{ + if(o->layer < 0) + o->layer = CS_DEFAULT_LAYER; + if(layer >= CS_LAYERS) + layer = CS_LAYERS - 1; + o->layer = layer; +} + +/* + * Add object *first*, ie with lowest priority. + * (Hmmm... Isn't that how some h/w sprite generators do it, + * if you allocate in increasing channel order?) + */ +static inline void __obj_attach(cs_obj_t *o) +{ + if(o->head || o->next || o->prev) + { + log_printf(ELOG, "cs: HEEEELP! Someone's trying" + " to short-circuit my guts!\n"); + return; + } + + if(o->layer < 0) + o->layer = CS_DEFAULT_LAYER; + o->next = o->owner->objects[o->layer]; + o->head = &o->owner->objects[o->layer]; + if(o->next) + o->next->prev = o; + o->owner->objects[o->layer] = o; +} + +/* + * BEWARE! There's a nasty hack in here; these objects need to + * keep track of the addresses of their list heads in order to + * remove themselves properly! + */ +static inline void __obj_detach(cs_obj_t *o) +{ + /* "Bypass" */ + if(o->next) + o->next->prev = o->prev; + if(o->prev) + o->prev->next = o->next; + /* In case we're the first object in the list... */ + if(o->head) + if(*(o->head) == o) + *(o->head) = o->next; + + o->head = NULL; + o->next = NULL; + o->prev = NULL; +} + + +void cs_obj_layer(cs_obj_t *o, unsigned int layer) +{ + if(layer == o->layer) + return; + + __obj_set_layer(o, layer); + if(o->flags | CS_OBJ_ACTIVE) + { + __obj_detach(o); + __obj_attach(o); + } +} + + +void cs_obj_activate(cs_obj_t *o) +{ + if(o->flags | CS_OBJ_ACTIVE) + { + DBG(log_printf(DLOG, "cs: Tried to activate active object!\n");) + return; + } + + __obj_attach(o); + o->flags |= CS_OBJ_ACTIVE; +} + + +void cs_obj_deactivate(cs_obj_t *o) +{ + if(!(o->flags | CS_OBJ_ACTIVE)) + { + DBG(log_printf(DLOG, "cs: Tried to deactivate passive object!\n");) + return; + } + + __obj_detach(o); + o->flags &= ~CS_OBJ_ACTIVE; +} + + +/* Basic methods */ + +void cs_obj_pos(cs_obj_t *o, int x, int y) +{ + o->point.v.x = PIXEL2CS(x); + o->point.v.y = PIXEL2CS(y); +} + + +void cs_obj_vel(cs_obj_t *o, int xs, int ys) +{ + o->point.v.xv = xs; + o->point.v.yv = ys; +} + + +/*Set movement acceleration*/ +void cs_obj_acc(cs_obj_t *o, int xa, int ya) +{ + o->point.v.xa = xa; + o->point.v.ya = ya; +} + + +/*Disable display*/ +void cs_obj_hide(cs_obj_t *o) +{ + o->flags &= ~CS_OBJ_VISIBLE; +} + + +/*Enable display*/ +void cs_obj_show(cs_obj_t *o) +{ + if(o->flags & CS_OBJ_VISIBLE) + return; + + o->flags |= CS_OBJ_VISIBLE; + /* + * Kludge? I'm not sure this is really the right place... + */ + cs_point_force(&o->point); +} + + +/* + * Remove and throw back in the pool + */ +void cs_obj_free(cs_obj_t *o) +{ + if(o->head == &o->owner->pool) + { + DBG(log_printf(DLOG, "cs: Tried to free free object %p!\n", + o);) + return; + } + cs_obj_deactivate(o); + if(o->on_free) + o->on_free(o); + cs_obj_clear(o); + + /* Set up head pointer for error checking. */ + o->head = &o->owner->pool; + + /* Link to pool; singly only */ + o->next = o->owner->pool; + o->owner->pool = o; + + ++o->owner->pool_free; +} + +void cs_obj_clear(cs_obj_t *o) +{ + o->flags = 0; + o->layer = -1; + o->fire.rate = 0; + o->score = 0; + o->health = 0; +} + +void cs_obj_vector(cs_obj_t *o, cs_vector_t * v) +{ + if(v) + o->point.v = *v; + else + memset(&(o->point.v), 0, sizeof(o->point.v)); +} + + + +/* Animation methods */ +void cs_obj_anim(cs_obj_t *o, int bank, + int first, int num, int start, int spd) +{ + o->anim.bank = bank; + o->anim.frame = first; + o->anim.fframe = first; + o->anim.aframes = num; + o->anim.cframe = start << 4; + o->anim.aspeed = spd; + o->flags |= CS_OBJ_DOANIM; +} + + +void cs_obj_image(cs_obj_t *o, int bank, int frame) +{ + o->anim.bank = bank; + o->anim.frame = frame; + o->flags &= ~CS_OBJ_DOANIM; + if((bank >= 0) && (bank < o->owner->nimageinfo)) + { + o->w = o->owner->imageinfo[bank].w; + o->h = o->owner->imageinfo[bank].h; + } + else + o->w = o->h = 1; +} + + +/*Start death sequence*/ +void cs_obj_explode(cs_obj_t *o) +{ + o->flags |= CS_OBJ_DYING; +/* +FIXME: Hardcoded bank for explosion!!! +*/ + cs_obj_anim(o, 4, 0, 15, 0, 12); + if(o->on_dying) + o->on_dying(o); +} + +void cs_obj_shoot(cs_obj_t *o, int xo, int yo, int xs, + int ys, int rate, int delay, int ammo) +{ + o->fire.v.x = xo; + o->fire.v.y = yo; + o->fire.v.xv = xs; + o->fire.v.yv = ys; + o->fire.rate = rate; + o->fire.timer = delay; + o->fire.ammo = ammo; +} + + + +/* + * cs_engine_t + */ + +static cs_obj_t *__new_obj(cs_engine_t *e) +{ + cs_obj_t *o = calloc(1, sizeof(cs_obj_t)); + if(!o) + return NULL; + + o->owner = e; + o->prev = NULL; + o->next = NULL; + cs_obj_clear(o); + ++e->pool_total; + return o; +} + +cs_engine_t *cs_engine_create(int w, int h, int objects) +{ + cs_engine_t *e = calloc(1, sizeof(cs_engine_t)); + if(!e) + return NULL; + + cs_engine_set_size(e, w, h); + cs_engine_set_wrap(e, 0, 0); + + /* + * Create some objects and throw into the pool. + * Note that "pool_free" gets initialized by + * cs_obj_die(), objects are initialized and so + * on, this way - automatically! + */ + while(objects--) + { + cs_obj_t *o = __new_obj(e); + if(o) + cs_obj_free(o); + else + { + /* Oops, no memory... */ + cs_engine_delete(e); + return NULL; + } + } + return e; +} + + +cs_obj_t *cs_engine_get_obj(cs_engine_t *e) +{ + cs_obj_t *o = e->pool; + if(o) + { + e->pool = o->next; + o->head = NULL; + o->prev = NULL; + o->next = NULL; + --e->pool_free; + } + return o; +} + + +void cs_engine_set_size(cs_engine_t *e, int w, int h) +{ + e->w = w; + e->h = h; +} + + +void cs_engine_set_image_size(cs_engine_t *e, int bank, int w, int h) +{ + if(bank < 0) + return; + + if(bank >= e->nimageinfo) + { + int nnii = bank + 16; + image_info_t *nii = realloc(e->imageinfo, + sizeof(image_info_t) * nnii); + if(!nii) + return; + + e->nimageinfo = nnii; + e->imageinfo = nii; + } + + e->imageinfo[bank].w = w; + e->imageinfo[bank].h = h; +} + + +void cs_engine_set_wrap(cs_engine_t *e, int x, int y) +{ + e->wx = PIXEL2CS(x); + e->wy = PIXEL2CS(y); +} + + +void cs_engine_delete(cs_engine_t *e) +{ + cs_obj_t *o; + /* First get all objects to the pool... */ + cs_engine_reset(e); + /* ...then empty the pool. */ + while((o = cs_engine_get_obj(e))) + free(o); + free(e->imageinfo); + free(e); +} + + +void cs_engine_reset(cs_engine_t *e) +{ + int i; + for(i = 0; i < CS_LAYERS; ++i) + while(e->objects[i]) + cs_obj_free(e->objects[i]); + e->time = 0.0; +} + + + +/* +---------------------------------------------------------------------- + * The actual *engine* :-) +---------------------------------------------------------------------- + */ + +void __enemy_fire(cs_obj_t *o) +{ + log_printf(DLOG, "fire!\n"); +} + +void __make_move(cs_obj_t *o, int wx, int wy) +{ + /* + * Movement + */ + __move_point(&o->point, wx, wy); + + /* + * Animation + */ + if(o->flags & CS_OBJ_DOANIM) + { +/* +FIXME: Dirty hack here... Should play *any* death animation one-shot and then die. +*/ + if((o->flags & CS_OBJ_DYING) + && (o->anim.cframe >> 4 == 14)) + cs_obj_free(o); + + o->anim.cframe += o->anim.aspeed; + o->anim.cframe %= o->anim.aframes << 4; + o->anim.frame = (o->anim.cframe >> 4) + o->anim.fframe; + } + + /* + * Fire / spawning + */ + if(!(o->flags & CS_OBJ_DYING) && o->fire.rate) + { + if(o->fire.timer > 0) + --o->fire.timer; + else + { + o->fire.timer = o->fire.rate; + __enemy_fire(o); + if(o->on_fire) + o->on_fire(o); + } + } +} + + +void __update_points(cs_engine_t *e, float frac_frame) +{ + cs_obj_t *o; + int i; + int ff = frac_frame * 256.0; + + if(ff < 0) + ff = 0; + else if(ff > 256) + ff = 256; + + if(e->filter) + for(i = 0; i < CS_USER_POINTS; ++i) + __update_point_f(&e->points[i], ff, e->wx, e->wy); + else + for(i = 0; i < CS_USER_POINTS; ++i) + __update_point(&e->points[i], ff); + + for(i = 0; i < CS_LAYERS; ++i) + { + if(e->filter) + __update_point_f(&e->offsets[i], ff, e->wx, e->wy); + else + __update_point(&e->offsets[i], ff); + e->changed[i] = 0; + o = e->objects[i]; + while(o) + { + if(e->filter) + __update_point_f(&o->point, ff, e->wx, + e->wy); + else + __update_point(&o->point, ff); + o->point.gx -= e->offsets[i].gx; + o->point.gy -= e->offsets[i].gy; + e->changed[i] |= o->point.changed; + __fix_wrap(e, o); + o = o->next; + } + } +} + + +void __run_all(cs_engine_t *e) +{ + int i; + cs_obj_t *o; + + for(i = 0; i < CS_USER_POINTS; ++i) + __move_point(&e->points[i], e->wx, e->wy); + + for(i = 0; i < CS_LAYERS; ++i) + { + __move_point(&e->offsets[i], e->wx, e->wy); + o = e->objects[i]; + while(o) + { + __make_move(o, e->wx, e->wy); + o = o->next; + } + } +} + + +void __wrap_all(cs_engine_t *e) +{ + int i; + cs_obj_t *o; + + for(i = 0; i < CS_USER_POINTS; ++i) + __wrap_point(&e->points[i], e->wx, e->wy); + + for(i = 0; i < CS_LAYERS; ++i) + { + __wrap_point(&e->offsets[i], e->wx, e->wy); + o = e->objects[i]; + while(o) + { + __wrap_point(&o->point, e->wx, e->wy); + o = o->next; + } + } +} + + +void cs_engine_advance(cs_engine_t *e, double to_frame) +{ + if(to_frame > 0) + { + int frames = floor(to_frame) - floor(e->time); + if(frames > 0) + { + while(frames--) + { + __run_all(e); + e->on_frame(e); + } + } + } + e->time = to_frame; + if(e->wx || e->wy) + __wrap_all(e); + __update_points(e, to_frame - floor(to_frame)); +} + + +void cs_engine_render(cs_engine_t *e) +{ + cs_obj_t *o; + int i; + + for(i = CS_LAYERS - 1; i >= 0; --i) + { + o = e->objects[i]; + while(o) + { + if(o->flags & CS_OBJ_VISIBLE) + if(o->render) + if(__onscreen(e, o)) + o->render(o); + o = o->next; + } + } +} diff --git a/graphics/cs.h b/graphics/cs.h new file mode 100644 index 0000000..8f0628f --- /dev/null +++ b/graphics/cs.h @@ -0,0 +1,472 @@ +/*(LGPL) + * Project Spitfire sprites + scrolling engine for SDL +---------------------------------------------------------------------- + cs.h - Simplistic Control System +---------------------------------------------------------------------- + * Copyright (C) 2001, 2003, 2007 David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Note on coordinates: + * Normally, cs assumes that the world continues + * indefinitely in every direction. (Actually, + * it wraps at 4 Gpixel intervals... :-) + * + * However, by calling cs_engine_set_wrap(x, y), + * it's possible to make the engine wrap + * automatically, to nicely support old style + * endless scrolling games. The movement system + * will automatically wrap around edges, and + * most importantly, *interpolation* will work + * correctly in conjunction with wrapping. This + * applies to all points in the system, user + * points included. + * + * Note that cs doesn't have an internal notion + * of layers when it comes to wrapping, which + * means that it's not trivial to implement + * wrapping for parallax scrolling correctly. + * All parallax layers have to be of the same + * size, as cs cannot tell which points belong + * to which layer when performing the internal + * calculations. + * + * Call cs_engine_set_wrap(0, 0); to disable + * wrapping. Wrapping can be set or disabled + * individually for each axis. + * + * Note on graphics coordinates: + * Graphics coordinates don't always wrap at the + * same time as their corresponding object + * coordinates! This is because the engine must + * consider the view rectangle and the bounding + * rectangles of objects, and adjust the wrapping + * so that all objects that should be visible + * are. + * + * Note on wrapping (with wrapping enabled only): + * When a layer is scrolled so that it's limits + * end up inside the display window, the engine + * automatically makes objects wrap around from + * the far edge, so that continuous looping is + * possible. + * However, note that this breaks if objects can + * be seen at more than one edge at a time! That + * is, (wrap size - display size) must be bigger + * than the size of the largest object. + * + * TODO: + * * Scrap the animation system and throw + * something nicer in. A primitive VM based + * "scripting" system with + * commands and switches based on speed, + * direction, state etc would be incredibly + * powerful, and still not too complicated. + * + * * Implement collision detection. There should + * be flags to enable/disable it on per-layer + * as well as per-object basis. + * + * * Group all per-layer stuff into a struct, + * and then use an array of structs. + * + * * Split each layer into two lists; one for + * visible objects and one for hidden objects, + * so they can be handled more efficiently. + * (Hidden objects are skipped one by one in + * the render loop now, for example - it will + * become worse over time, I think.) + * + * * Implement some sort of zone based collision + * detection engine that scales better than + * "check everything against everything". + */ + /* + * + * BUGS: + * * There is a restriction on object movement + * speed in a wrapping world: No object must + * move more than half of the extent of the + * world on either axis in one engine cycle. + * STATUS: Who cares? + * + * * Objects that are not free or active (they + * do *not* have to be visible!) are "missing + * in action" as far as the engine is concerned. + * It won't find them unless you free them, + * or make them visible. + * STATUS: Can and should be fixed. + */ + +#ifndef _CS_H_ +#define _CS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + + +#define __CS_SHIFT 8 +#define CS2PIXEL(x) ( (x) >> __CS_SHIFT ) +#define PIXEL2CS(x) ( (x) << __CS_SHIFT ) + +#define CS_LAYERS 8 +#define CS_DEFAULT_LAYER 1 /*0 is normally for overlays*/ +#define CS_USER_POINTS 16 + +/* +FIXME: This fixpoint crap should probably be changed to float... +FIXME: Would break the "changed" mask bonus feature described +FIXME: below, though. +*/ + +typedef struct +{ + /* 24:8 fixpoint values */ + int x, y; /* logic position */ + int xv, yv; + int xa, ya; +} cs_vector_t; + + +/* + * Some handy vector construction macros... + * + * NOTE: position (x,y) in integer format, not fixpoint! + */ + +/* Point */ +static inline cs_vector_t cs_vector_p(int x, int y) +{ + cs_vector_t v; + v.x = PIXEL2CS(x); + v.y = PIXEL2CS(y); + v.xv = v.yv = v.xa = v.ya = 0; + return v; +} + +/* Point + velocity */ +static inline cs_vector_t cs_vector_pv(int x, int y, int xv, int yv) +{ + cs_vector_t v; + v.x = PIXEL2CS(x); + v.y = PIXEL2CS(y); + v.xv = xv; + v.yv = yv; + v.xa = v.ya = 0; + return v; +} + +/* Point + velocity + acceleration */ +static inline cs_vector_t cs_vector_pva(int x, int y, int xv, int yv, int xa, int ya) +{ + cs_vector_t v; + v.x = PIXEL2CS(x); + v.y = PIXEL2CS(y); + v.xv = xv; + v.yv = yv; + v.xa = xa; + v.ya = ya; + return v; +} + + +/* + * Generic coordinate + speed and acceleration type. Position filtering + * support is built-in as well, for smooth animation regardless of + * control system / video frame rate ratio. +FIXME: Interpolation can break detailed animations involving multiple +FIXME: sprites that move and animate (changing images) at the same +FIXME: time. Provide a "CS_OBJ_NO_INTERPOLATION" flag? + */ +typedef struct +{ + /* 24:8 fixpoint values here as well */ + cs_vector_t v; + + int ox, oy; /* last position (for filtering) */ + int gx, gy; /* graphic position */ + + /* (changed != 0) if gx or gy changed during the last update. + * This is a bit mask with the same format as the coords, + * which means that you can mask some low bits off to set + * a coarse movement sensitivity threshold. + * Ex. (changed & 0xffffff00) == "gx or gy moved to + * another pixel posn." + */ + int changed; +} cs_point_t; + + +/* + * Force the interpolation filter of a point to the current + * position of the vector. (This is required when activating + * new objects.) + */ +static inline void cs_point_force(cs_point_t *p) +{ + p->ox = p->gx = p->v.x; + p->oy = p->gy = p->v.y; +} + + +/* + * This stuff is translated from Object Pascal to "Object + * Oriented Style C" with my new naming conventions... + * I don't consider this code needing advanced OO, so I + * don't want to drag C++ in. + */ + +struct cs_engine_t; +struct cs_obj_t; + +/* +---------------------------------------------------------------------- + * cs_obj_t (used to be object + sprite) +---------------------------------------------------------------------- + * + * "The Basic Move Object. + * + * This object reperesents a moving object on the screen. + * You just tell it in what direction to go, and the Game Graphics + * system will do the job." + * + * What to do in the callbacks: + * collision() Check accurately if two objects really collide. + * (The control system will ask when bounding rects + * are overlapping and the collision masks indicate + * that a collision would affect one or both objects.) + */ +typedef struct cs_obj_t +{ + struct cs_engine_t *owner; + struct cs_obj_t **head; + struct cs_obj_t *next, *prev; + + cs_point_t point; /* Position, speed, acceleration */ + + int w, h; /* Sprite bounding rect size (pixels) */ + + int flags; + int layer; + + /* Collision filter (new) */ + int group_mask; /* bit set = "belongs to group" */ + int hit_mask; /* bit set = "can hit group" */ + + struct + { + int bank; /* Image bank */ + int frame; /* Image frame */ + int fframe; /* First frame (integer) */ + int aframes; /* # of frames; from fframe (integer) */ + int cframe; /* Current frame; from fframe (28:4 fixp) */ + int aspeed; /* Frames / engine cycle (28:4 fixp) */ + } anim; + + struct + { + cs_vector_t v; /* weapon offset + vel + acc */ + int rate; /* frames/shot */ + int timer; + int ammo; /* bullet type */ + } fire; + + int score; /*Score for destroy*/ + int health; /*Health points*/ + + /* + * Event callbacks + */ + int (*on_hit)(struct cs_obj_t *o); /* Ouch! */ + int (*on_dying)(struct cs_obj_t *o); /* Destructing... */ + int (*on_fire)(struct cs_obj_t *o); /* BOOM! */ + + /* + * Collision detection callbacks + * Called when bounding rect intersection is detected. + * Should return 1 if there actually is a collision. + */ + int (*collision)(struct cs_obj_t *o1, struct cs_obj_t *o2); + + /* + * Rendering callback + * NOTE: Use (gx,gy) when rendering, *NOT* (x,y)! + */ + void (*render)(struct cs_obj_t *o); + + /* + * User destructor; Object is freed after you return. + */ + int (*on_free)(struct cs_obj_t *o); + + /* User data */ + int tag; /* user ID */ + void *user; /* user data */ +} cs_obj_t; + + +/* cs_obj_t flags */ + +/* + * True when an object is "in the system"; ie when it's in one of + * the sprite lists, as opposed to in the free pool, or unattached. + * ("Unattached" is the state an object is in when you've just got + * it from cs_engine_get_obj().) + */ +#define CS_OBJ_ACTIVE 0x00000001 + +/* + * Note that an object with a 0 visible flag is still *active*! It's + * coordinates are updated, animation, collisions, spawning/shooting + * etc runs - it's just not visible. (Well, whatever is spawned is.) + */ +#define CS_OBJ_VISIBLE 0x00000002 + +/* + * Set by the collision detection system whenever any part of the + * object's bounding rectangle is inside the bounding rectangle + * of the screen. + */ +#define CS_OBJ_ONSCREN 0x00000004 + +/* + * Set whenever the cs animation system is to be used to generate + * image frame numbers for this object. + */ +#define CS_OBJ_DOANIM 0x00000008 + +/* + * Set while the object is marked as dying. Normally, you would + * run some animation and perhaps spawn some explosion objects, + * and then free the object. + */ +#define CS_OBJ_DYING 0x00000010 + + +/* Basic methods */ +/* + * Note: You only really need cs_obj_layer(), cs_obj_show() + * and cs_obj_free(). The others are just for more fine + * grained life cycle control. + */ +void cs_obj_layer(cs_obj_t *o, unsigned int layer); +void cs_obj_activate(cs_obj_t *o); /* Add to cs */ +void cs_obj_show(cs_obj_t *o); /* Enable display */ +void cs_obj_hide(cs_obj_t *o); /* Disable display */ +void cs_obj_deactivate(cs_obj_t *o); /* Disengage from cs */ +void cs_obj_free(cs_obj_t *o); /* Remove and throw back in the pool */ + +void cs_obj_pos(cs_obj_t *o, int x, int y); /* Set new position */ +void cs_obj_vel(cs_obj_t *o, int xs, int ys); /* Set movement speed */ +void cs_obj_acc(cs_obj_t *o, int xa, int ya); /* Set movement acceleration */ +void cs_obj_vector(cs_obj_t *o, cs_vector_t *v);/* Set all */ + +void cs_obj_clear(cs_obj_t *o); + +/* Animation methods */ +void cs_obj_image(cs_obj_t *o, int bank, int frame); +void cs_obj_anim(cs_obj_t *o, int bank, + int first, int num, + int start, int spd); +void cs_obj_explode(cs_obj_t *o); /*Start death sequence*/ + +/* Fire/spawning control */ +/* NOTE: + In the original version, spawned object speed was + absolute, while here, it's relative to object 'o'. +*/ +void cs_obj_shoot(cs_obj_t *o, int xo, int yo, int xs, + int ys, int rate, int delay, int ammo); + + +typedef struct +{ + int w, h; +} image_info_t; + +/* +---------------------------------------------------------------------- + * cs_engine_t (new) +---------------------------------------------------------------------- + */ +typedef struct cs_engine_t +{ + /* Display window size (pixels) */ + int w, h; + + /* Wrapping limits (pixels) */ + int wx, wy; + + /* Motion filtering */ + int filter; /* 0: newest, + * 1: linear interpolation + */ + + /* Current time in frames */ + double time; + + /* + * Callback that's called once per Control System + * frame from within cs_engine_advance(). + */ + void (*on_frame)(struct cs_engine_t *e); + + /* Active objects */ + cs_obj_t *objects[CS_LAYERS]; + + /* Layer position/offset control */ + cs_point_t offsets[CS_LAYERS]; + + /* Position control for custom stuff */ + cs_point_t points[CS_USER_POINTS]; + + /* + * Combined "changed" flag masks for the object groups above. + */ + int changed[CS_LAYERS]; + + /* Pool of unused objects */ + cs_obj_t *pool; + int pool_free; /* # of objects in here */ + int pool_total; /* # of objects in system */ + + /* Image info table */ + image_info_t *imageinfo; + int nimageinfo; +} cs_engine_t; + + +cs_engine_t *cs_engine_create(int w, int h, int objects); +void cs_engine_set_size(cs_engine_t *e, int w, int h); +void cs_engine_set_image_size(cs_engine_t *e, int bank, int w, int h); +void cs_engine_set_wrap(cs_engine_t *e, int x, int y); +void cs_engine_delete(cs_engine_t *e); + +void cs_engine_reset(cs_engine_t *e); +void cs_engine_advance(cs_engine_t *e, double to_frame); /* 0 == reset timer*/ +void cs_engine_render(cs_engine_t *e); + +cs_obj_t *cs_engine_get_obj(cs_engine_t *e); + +#ifdef __cplusplus +}; +#endif + +#endif /* _CS_H_ */ diff --git a/graphics/display.cpp b/graphics/display.cpp new file mode 100644 index 0000000..cfeeb52 --- /dev/null +++ b/graphics/display.cpp @@ -0,0 +1,104 @@ +/*(LGPL) + * Simple display for score, lives etc. + * © David Olofson, 2001-2003, 2007 + */ + +#define D_LINE_HEIGHT 9 + +#define D_LINE1_POS 1 +#define D_LINE1_TXOFFS 0 + +#define D_LINE2_POS 9 +#define D_LINE2_TXOFFS 0 + +#include + +#include "window.h" +#include "display.h" + +display_t::display_t() +{ + _on = 0; + caption("CAPTION"); + text("TEXT"); + on(); +} + + +void display_t::color(Uint32 _cl) +{ + _color = _cl; + if(_on) + invalidate(); +} + + +void display_t::caption(const char *cap) +{ + strncpy(_caption, cap, sizeof(_caption)); + if(_on) + invalidate(); +} + + +void display_t::text(const char *txt) +{ + strncpy(_text, txt, sizeof(_text)); + if(_on) + invalidate(); +} + + +void display_t::on() +{ + if(_on) + return; + + _on = 1; + invalidate(); +} + + +void display_t::off() +{ + if(!_on) + return; + + _on = 0; + invalidate(); +} + + +void display_t::render_caption() +{ + SDL_Rect r; + r.x = 0; + r.y = D_LINE1_POS; + r.w = width(); + r.h = D_LINE_HEIGHT; + background(_color); + clear(&r); + if(_on) + center(D_LINE1_POS + D_LINE1_TXOFFS, _caption); +} + + +void display_t::render_text() +{ + SDL_Rect r; + r.x = 0; + r.y = D_LINE2_POS; + r.w = width(); + r.h = D_LINE_HEIGHT; + background(_color); + clear(&r); + if(_on) + center(D_LINE2_POS + D_LINE2_TXOFFS, _text); +} + + +void display_t::refresh(SDL_Rect *r) +{ + render_caption(); + render_text(); +} diff --git a/graphics/display.h b/graphics/display.h new file mode 100644 index 0000000..50ea4f5 --- /dev/null +++ b/graphics/display.h @@ -0,0 +1,24 @@ +/*(LGPL) + * Simple display for score, lives etc. + * © David Olofson, 2001 + */ + +#include "window.h" + +class display_t : public window_t +{ + char _caption[64]; + char _text[64]; + int _on; + Uint32 _color; + void render_caption(); + void render_text(); + public: + display_t(); + void refresh(SDL_Rect *r); + void color(Uint32 _cl); + void caption(const char *cap); + void text(const char *txt); + void on(); + void off(); +}; diff --git a/graphics/filters.c b/graphics/filters.c new file mode 100644 index 0000000..106041e --- /dev/null +++ b/graphics/filters.c @@ -0,0 +1,1159 @@ +/*(LGPL) +---------------------------------------------------------------------- + filters.c - Filters for the sprite manager +---------------------------------------------------------------------- + * Copyright (C) 2001, 2003, 2006, 2007 David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include "logger.h" +#include "glSDL.h" +#include "SDL_image.h" +#include "sprite.h" +#include "filters.h" + + +/*-------------------------------------------------- + RNG +--------------------------------------------------*/ + +static unsigned int rnd = 16576; + +//Resets the noise generator +static void noise_reset(int seed) +{ + rnd = 16576 + seed; +} + +//Returns a pseudo random number in the range [0, 65535] +static inline int noise(void) +{ + rnd *= 1566083941UL; + rnd++; + rnd &= 0xffffffffUL; /* NOP on 32 bit machines */ + return (int)(rnd * (rnd >> 16) >> 16); +} + + +/*-------------------------------------------------- + Pixel access ops for 32 bit RGBA +--------------------------------------------------*/ + +static pix_t getpix32_empty = {0x7f, 0x7f, 0x7f, 0x7f}; + +static inline pix_t getpix32(SDL_Surface *s, int x, int y) +{ + pix_t *p; + if((x < 0) || (x >= s->w) || (y < 0) || (y >= s->h)) + return getpix32_empty; + + p = (pix_t *)((char *)s->pixels + y * s->pitch); + return p[x]; +} + + +/* Clamping version */ +static inline pix_t getpix32c(SDL_Surface *s, int x, int y) +{ + pix_t *p; + if(x < 0) + x = 0; + else if(x >= s->w-1) + x = s->w-1; + if(y < 0) + y = 0; + else if(y >= s->h-1) + y = s->h-1; + p = (pix_t *)((char *)s->pixels + y * s->pitch); + return p[x]; +} + +#define GETPIXI(gp) \ +{ \ + int c0x, c0y, c1x, c1y; \ + int c[4]; \ + pix_t e = {0, 0, 0, 0}; \ + pix_t p[4], r; \ + getpix32_empty = e; \ + \ + /* Calculate filter core */ \ + x -= 8; \ + y -= 8; \ + c1x = x & 0xf; \ + c1y = y & 0xf; \ + c0x = 16 - c1x; \ + c0y = 16 - c1y; \ + c[0] = c0x * c0y; \ + c[1] = c1x * c0y; \ + c[2] = c0x * c1y; \ + c[3] = c1x * c1y; \ + \ + /* Grab input pixels */ \ + x >>= 4; \ + y >>= 4; \ + p[0] = gp(s, x, y); \ + p[1] = gp(s, x+1, y); \ + p[2] = gp(s, x, y+1); \ + p[3] = gp(s, x+1, y+1); \ + \ + /* Interpolate... */ \ + r.r = (p[0].r*c[0] + p[1].r*c[1] + p[2].r*c[2] + p[3].r*c[3])>>8; \ + r.g = (p[0].g*c[0] + p[1].g*c[1] + p[2].g*c[2] + p[3].g*c[3])>>8; \ + r.b = (p[0].b*c[0] + p[1].b*c[1] + p[2].b*c[2] + p[3].b*c[3])>>8; \ + r.a = (p[0].a*c[0] + p[1].a*c[1] + p[2].a*c[2] + p[3].a*c[3])>>8; \ + return r; \ +} + +/* Interpolated; 28:4 fixed point coords. */ +static inline pix_t getpix32i(SDL_Surface *s, int x, int y) +{ + GETPIXI(getpix32) +} + + +/* Clamping version */ +static inline pix_t getpix32ic(SDL_Surface *s, int x, int y) +{ + GETPIXI(getpix32c) +} + + +static inline pix_t *pix32(SDL_Surface *s, int x, int y) +{ + static pix_t dummy = {0x7f, 0x7f, 0x7f, 0x7f}; + pix_t *p; + if((x < 0) || (x >= s->w) || (y < 0) || (y >= s->h)) + return &dummy; + p = (pix_t *)((char *)s->pixels + y * s->pitch); + return p + x; +} + + +static inline void setpix32(SDL_Surface *s, int x, int y, pix_t pix) +{ + pix_t *p; + if((x < 0) || (x >= s->w) || (y < 0) || (y >= s->h)) + return; + p = (pix_t *)((char *)s->pixels + y * s->pitch); + p[x] = pix; +} + + +/*-------------------------------------------------- + Non-clipping versions of everything + (No clamping here, obviously...!) +--------------------------------------------------*/ + +static inline pix_t getpix32_nc(SDL_Surface *s, int x, int y) +{ + pix_t *p = (pix_t *)((char *)s->pixels + y * s->pitch); +#ifdef DEBUG + if((x < 0) || (x >= s->w) || (y < 0) || (y >= s->h)) + { + log_printf(ELOG, "Clip in getpix32_nc()!" + " x = %d, y = %d\n", x, y); +*((char *)NULL) = 0; + return getpix32_empty; + } +#endif + return p[x]; +} + + +/* Interpolated; 28:4 fixed point coords. */ +static inline pix_t getpix32i_nc(SDL_Surface *s, int x, int y) +{ +#ifdef DEBUG + if((x < 0) || (x >= s->w << 4) || (y < 0) || (y >= s->h << 4)) + { + log_printf(ELOG, "Clip in getpix32i_nc()!" + " x = %d, y = %d\n", x>>4, y>>4); +*((char *)NULL) = 0; +// return getpix32_empty; + } + GETPIXI(getpix32) +#else + GETPIXI(getpix32_nc) +#endif +} +#undef GETPIXI + +static inline void setpix32_nc(SDL_Surface *s, int x, int y, pix_t pix) +{ + pix_t *p = (pix_t *)((char *)s->pixels + y * s->pitch); +#ifdef DEBUG + if((x < 0) || (x >= s->w) || (y < 0) || (y >= s->h)) + { + log_printf(ELOG, "Clip in setpix32_nc()!" + " x = %d, y = %d\n", x, y); +*((char *)NULL) = 0; +// return; + } +#endif + p[x] = pix; +} + + +static inline pix_t *pix32_nc(SDL_Surface *s, int x, int y) +{ + pix_t *p = (pix_t *)((char *)s->pixels + y * s->pitch); +#ifdef DEBUG +// static pix_t trash; + if((x < 0) || (x >= s->w) || (y < 0) || (y >= s->h)) + { + log_printf(ELOG, "Clip in pix32_nc()!" + " x = %d, y = %d\n", x, y); +*((char *)NULL) = 0; +// return &trash; + } +#endif + return p + x; +} + + + +/*-------------------------------------------------- + The filters +--------------------------------------------------*/ + +int s_filter_rgba8(s_bank_t *b, unsigned first, unsigned frames, + s_filter_args_t *args) +{ + unsigned i; + SDL_PixelFormat fmt; + memset(&fmt, 0, sizeof(fmt)); + fmt.BitsPerPixel = 32; + fmt.BytesPerPixel = 4; +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + fmt.Rmask = 0xff000000; + fmt.Gmask = 0x00ff0000; + fmt.Bmask = 0x0000ff00; + fmt.Amask = 0x000000ff; +#else + fmt.Rmask = 0x000000ff; + fmt.Gmask = 0x0000ff00; + fmt.Bmask = 0x00ff0000; + fmt.Amask = 0xff000000; +#endif + for(i = 0; i < frames; ++i) + { + SDL_Surface *tmp; + s_sprite_t *s = s_get_sprite_b(b, first+i); + if(!s) + continue; + tmp = SDL_ConvertSurface(s->surface, &fmt, + SDL_SWSURFACE); + if(!tmp) + return -1; + + SDL_FreeSurface(s->surface); + s->surface = tmp; + } + return 0; +} + + +int s_filter_dither(s_bank_t *b, unsigned first, unsigned frames, + s_filter_args_t *args) +{ + int x, y; + unsigned i; + int ar, ag, ab; + if(!args->x && !args->r && !args->g && !args->b) + return 0; + noise_reset(first); + for(i = 0; i < frames; ++i) + { + s_sprite_t *s = s_get_sprite_b(b, first+i); + if(!s) + continue; + ar = args->r; + ag = args->g; + ab = args->b; + if(args->x) + switch (s_blitmode) + { + case S_BLITMODE_AUTO: + if(s->surface->format->Amask) + ar = ag = ab = 8; + break; + case S_BLITMODE_OPAQUE: + break; + case S_BLITMODE_COLORKEY: + case S_BLITMODE_ALPHA: + ar = ag = ab = 8; + break; + } + switch(args->y) + { + default: + case 0: + case 1: + ar >>= 1; + ag >>= 1; + ab >>= 1; + case 2: + break; + } + for(y = (args->flags & SF_CLAMP_SFONT) ? 1 : 0; y < b->h; ++y) + { + pix_t *p = (pix_t *)((char *)s->surface->pixels + + y * s->surface->pitch); + switch(args->y) + { + default: + case 0: + /* 2x2 filter */ + for(x = 0; x < b->w; ++x) + { + int r, g, b; + pix_t *pix = p + x; + if((x^y)&1) + { + r = pix->r + ar; + g = pix->g + ag; + b = pix->b + ab; + if(r>255) + r = 255; + if(g>255) + g = 255; + if(b>255) + b = 255; + } + else + { + r = pix->r - ar; + g = pix->g - ag; + b = pix->b - ab; + if(r<0) + r = 0; + if(g<0) + g = 0; + if(b<0) + b = 0; + } + pix->r = r; + pix->g = g; + pix->b = b; + } + break; + case 1: + /* 4x4 filter */ + for(x = 0; x < b->w; ++x) + { + int dr, dg, db; + int r, g, b; + pix_t *pix = p + x; + r = pix->r; + g = pix->g; + b = pix->b; + if((x^y) & 1) + { + dr = ar; + dg = ag; + db = ab; + } + else + { + dr = -ar; + dg = -ag; + db = -ab; + } + if(y & 1) + { + dr += ar >> 1; + dg += ag >> 1; + db += ab >> 1; + } + else + { + dr -= ar >> 1; + dg -= ag >> 1; + db -= ab >> 1; + } + r += dr; + g += dg; + b += db; + + if(r>255) + r = 255; + else if(r<0) + r = 0; + + if(g>255) + g = 255; + else if(g<0) + g = 0; + + if(b>255) + b = 255; + else if(b<0) + b = 0; + + pix->r = r; + pix->g = g; + pix->b = b; + } + break; + case 2: + /* Random */ + for(x = 0; x < b->w; ++x) + { + int r, g, b, z; + pix_t *pix = p + x; + z = noise(); + r = pix->r - ar + (((ar << 1) - 1) & z); + g = pix->g - ag + (((ag << 1) - 1) & z); + b = pix->b - ab + (((ab << 1) - 1) & z); + + if(r>255) + r = 255; + else if(r<0) + r = 0; + + if(g>255) + g = 255; + else if(g<0) + g = 0; + + if(b>255) + b = 255; + else if(b<0) + b = 0; + + pix->r = r; + pix->g = g; + pix->b = b; + } + break; + } + } + } + return 0; +} + + +/* + * Ugly hack to get around the problems caused by + * SDL_SetColorKey() ignoring the alpha channel. + * Basically just sets the blue LSB of any pixels + * that match the colorkey, but have non-transparent + * alpha. + */ +static void tweak_ck(SDL_Surface *s) +{ + int x, y; + if(s->format->BitsPerPixel != 32) + return; + for(y = 0; y < s->h; ++y) + { + pix_t *p = (pix_t *)((char *)s->pixels + y * s->pitch); + for(x = 0; x < s->w; ++x) + { + pix_t *pix = p + x; + if(!pix->r && !pix->g && !pix->b) + if(pix->a) + pix->b |= 1; + } + } +} + + +int s_filter_displayformat(s_bank_t * b, unsigned first, unsigned frames, + s_filter_args_t * args) +{ + unsigned i; + for(i = 0; i < frames; ++i) + { + SDL_Surface *tmp; + s_sprite_t *s = s_get_sprite_b(b, first + i); + if(!s) + continue; + + switch(s_blitmode) + { + case S_BLITMODE_AUTO: + if(s->surface->format->Amask) + SDL_SetAlpha(s->surface, + SDL_SRCALPHA | + SDL_RLEACCEL, + SDL_ALPHA_OPAQUE); + else + SDL_SetColorKey(s->surface, SDL_RLEACCEL, 0); + break; + case S_BLITMODE_OPAQUE: + SDL_SetColorKey(s->surface, SDL_RLEACCEL, 0); + break; + case S_BLITMODE_COLORKEY: + SDL_SetColorKey(s->surface, + SDL_SRCCOLORKEY | SDL_RLEACCEL, + SDL_MapRGB(s->surface->format, + s_colorkey.r, + s_colorkey.g, + s_colorkey.b)); + break; + case S_BLITMODE_ALPHA: + SDL_SetAlpha(s->surface, + SDL_SRCALPHA | SDL_RLEACCEL, + s_alpha); + break; + } + + if(args->x) + { + if(s->surface->format->Amask) + tweak_ck(s->surface); + tmp = SDL_DisplayFormat(s->surface); + if(s->surface->format->Amask) + SDL_SetColorKey(tmp, + SDL_SRCCOLORKEY | SDL_RLEACCEL, + SDL_MapRGB(tmp->format, 0,0,0)); + } + else + { + if(s->surface->format->Amask) + tmp = SDL_DisplayFormatAlpha(s->surface); + else + tmp = SDL_DisplayFormat(s->surface); + } + if(!tmp) + return -1; + + SDL_FreeSurface(s->surface); + s->surface = tmp; + } + return 0; +} + + +typedef struct +{ + SDL_Surface *src; /* Source surface */ + SDL_Surface *dst; /* Destination surface */ + int scx, scy; /* Scale (fixp 16:16) */ + int start_sy, start_sx; /* Src start pos (fixp 16:16) */ + int start_x, start_y; /* Dst start pos (pixels) */ + int max_x, max_y; /* Dst end pos (pixels) */ +} scale_params_t; + + +static inline void select_rect(scale_params_t *p, scale_params_t *orig, + int x, int y, int w, int h) +{ + p->start_sx = orig->start_sx + x * orig->scx; + p->start_sy = orig->start_sy + y * orig->scy; + p->start_x = orig->start_x + x; + p->start_y = orig->start_y + y; + p->max_x = p->start_x + w; + p->max_y = p->start_y + h; +} + +/* Optimization tool; use the slow clipping funcs only around the edges! */ +static inline void do_scale(scale_params_t *p, + void (*border)(scale_params_t *p), + void (*body)(scale_params_t *p)) +{ + /* Copy the parameters */ + scale_params_t lp = *p; + int w = p->max_x - p->start_x; + int h = p->max_y - p->start_y; + int bx = (65535 + p->scx) / p->scx; + int by = (65535 + p->scy) / p->scy; + if(bx * 2 >= w || by * 2 >= h) + { + /* Area too small - body size would be zero or negative! */ + select_rect(&lp, p, 0, 0, w, h); + border(&lp); + return; + } + + /* Top border */ + select_rect(&lp, p, 0, 0, w, by); + border(&lp); + + /* Bottom border */ + select_rect(&lp, p, 0, h - by, w, by); + border(&lp); + + /* Left border */ + select_rect(&lp, p, 0, by, bx, h - 2 * by); + border(&lp); + + /* Right border */ + select_rect(&lp, p, w - bx, by, bx, h - 2 * by); + border(&lp); + + /* Body */ + select_rect(&lp, p, bx, by, w - 2 * bx, h - 2 * by); + body(&lp); +} + + +/* + * Ugly but fast "nearest pixel" scaling + */ + +static void scale_nearest(scale_params_t *p) +{ + int x, y, sx, sy; + for(y = p->start_y, sy = p->start_sy; y < p->max_y; ++y, sy += p->scy) + { + pix_t *pix = (pix_t *)((char *)p->dst->pixels + + y * p->dst->pitch); + for(x = p->start_x, sx = p->start_sx; x < p->max_x; + ++x, sx += p->scx) + pix[x] = getpix32_nc(p->src, sx >> 16, sy >> 16); + } +} + + +/* + * Bilinear scaling + */ + +static void do_scale_bilinear_noclip(scale_params_t *p) +{ + int x, y, sx, sy; + for(y = p->start_y, sy = p->start_sy; y < p->max_y; ++y, sy += p->scy) + { + pix_t *pix = (pix_t *)((char *)p->dst->pixels + + y * p->dst->pitch); + for(x = p->start_x, sx = p->start_sx; x < p->max_x; + ++x, sx += p->scx) + pix[x] = getpix32i_nc(p->src, sx >> 12, sy >> 12); + } +} + +static void do_scale_bilinear_clip(scale_params_t *p) +{ + int x, y, sx, sy; + for(y = p->start_y, sy = p->start_sy; y < p->max_y; ++y, sy += p->scy) + { + pix_t *pix = (pix_t *)((char *)p->dst->pixels + + y * p->dst->pitch); + for(x = p->start_x, sx = p->start_sx; x < p->max_x; + ++x, sx += p->scx) + pix[x] = getpix32i(p->src, sx >> 12, sy >> 12); + } +} + +static void do_scale_bilinear_clamp(scale_params_t *p) +{ + int x, y, sx, sy; + for(y = p->start_y, sy = p->start_sy; y < p->max_y; ++y, sy += p->scy) + { + pix_t *pix = (pix_t *)((char *)p->dst->pixels + + y * p->dst->pitch); + for(x = p->start_x, sx = p->start_sx; x < p->max_x; + ++x, sx += p->scx) + pix[x] = getpix32ic(p->src, sx >> 12, sy >> 12); + } +} + +static void scale_bilinear(scale_params_t *p) +{ + do_scale(p, do_scale_bilinear_clip, do_scale_bilinear_noclip); +} + +static void scale_bilinear_clamp(scale_params_t *p) +{ + do_scale(p, do_scale_bilinear_clamp, do_scale_bilinear_noclip); +} + + +/* + * Scale2x scaling + * + * This one's cool for 16 color graphics and the like, but + * even with the fuzziness factor, it doesn't work well + * with 24 bit data, or even 256 color graphics. + */ +#define CDIFF(x,y) (((x).r^(y).r) | ((x).g^(y).g) | ((x).b^(y).b) | ((x).a^(y).a)) +#define SCALE2X(gp, sp) \ +{ \ + int DB, BF, DH, FH; \ + pix_t B ; \ + pix_t D, E, F; \ + pix_t H ; \ + pix_t E0, E1; \ + pix_t E2, E3; \ + B = gp(p->src, sx, sy-1); \ + D = gp(p->src, sx-1, sy); \ + E = gp(p->src, sx, sy); \ + F = gp(p->src, sx+1, sy); \ + H = gp(p->src, sx, sy+1); \ + DB = CDIFF(D, B) & 0xc0; \ + BF = CDIFF(B, F) & 0xc0; \ + DH = CDIFF(D, H) & 0xc0; \ + FH = CDIFF(F, H) & 0xc0; \ + E0 = (!DB && BF && DH) ? D : E; \ + E1 = (!BF && DB && FH) ? F : E; \ + E2 = (!DH && DB && FH) ? D : E; \ + E3 = (!FH && DH && BF) ? F : E; \ + sp(p->dst, x, y, E0); \ + sp(p->dst, x+1, y, E1); \ + sp(p->dst, x, y+1, E2); \ + sp(p->dst, x+1, y+1, E3); \ +} +static void do_scale_2x_noclip(scale_params_t *p) +{ + int x, y, sx, sy; + for(y = p->start_y, sy = p->start_sy >> 16; y < p->max_y; y += 2, ++sy) + for(x = p->start_x, sx = p->start_sx >> 16; x < p->max_x; + x += 2, ++sx) + SCALE2X(getpix32_nc, setpix32_nc); +} + +static void do_scale_2x_clip(scale_params_t *p) +{ + int x, y, sx, sy; + for(y = p->start_y, sy = p->start_sy >> 16; y < p->max_y; y += 2, ++sy) + for(x = p->start_x, sx = p->start_sx >> 16; x < p->max_x; + x += 2, ++sx) + SCALE2X(getpix32, setpix32); +} + +static void do_scale_2x_clamp(scale_params_t *p) +{ + int x, y, sx, sy; + for(y = p->start_y, sy = p->start_sy >> 16; y < p->max_y; y += 2, ++sy) + for(x = p->start_x, sx = p->start_sx >> 16; x < p->max_x; + x += 2, ++sx) + SCALE2X(getpix32c, setpix32); +} +#undef CDIFF +#undef SCALE2X + +static void scale_2x(scale_params_t *p) +{ + do_scale(p, do_scale_2x_clip, do_scale_2x_noclip); +} + +static void scale_2x_clamp(scale_params_t *p) +{ + do_scale(p, do_scale_2x_clamp, do_scale_2x_noclip); +} + + +/* + * Diamond2x scaling + * + * This works *great* though; kicks the butt of + * Linear/Oversampled real hard - and at an order + * of magnitude higher speed! :-) + */ +#define MIX(t,x,y,z) (t).r = ((x).r+(x).r+(y).r+(z).r)>>2; \ + (t).g = ((x).g+(x).g+(y).g+(z).g)>>2; \ + (t).b = ((x).b+(x).b+(y).b+(z).b)>>2; \ + (t).a = ((x).a+(x).a+(y).a+(z).a)>>2; +#define DIAMOND(gp, sp) \ +{ \ + pix_t B; \ + pix_t D, E, F; \ + pix_t H; \ + pix_t E0, E1; \ + pix_t E2, E3; \ + B = gp(p->src, sx, sy-1); \ + D = gp(p->src, sx-1, sy); \ + E = gp(p->src, sx, sy); \ + F = gp(p->src, sx+1, sy); \ + H = gp(p->src, sx, sy+1); \ + MIX(E0, E, B, D); \ + MIX(E1, E, B, F); \ + MIX(E2, E, H, D); \ + MIX(E3, E, H, F); \ + sp(p->dst, x, y, E0); \ + sp(p->dst, x+1, y, E1); \ + sp(p->dst, x, y+1, E2); \ + sp(p->dst, x+1, y+1, E3); \ +} +static void do_scale_diamond2x_noclip(scale_params_t *p) +{ + int x, y, sx, sy; + for(y = p->start_y, sy = p->start_sy >> 16; y < p->max_y; y += 2, ++sy) + for(x = p->start_x, sx = p->start_sx >> 16; x < p->max_x; + x += 2, ++sx) + DIAMOND(getpix32_nc, setpix32_nc); +} + +static void do_scale_diamond2x_clip(scale_params_t *p) +{ + int x, y, sx, sy; + for(y = p->start_y, sy = p->start_sy >> 16; y < p->max_y; y += 2, ++sy) + for(x = p->start_x, sx = p->start_sx >> 16; x < p->max_x; + x += 2, ++sx) + DIAMOND(getpix32, setpix32); +} + +static void do_scale_diamond2x_clamp(scale_params_t *p) +{ + int x, y, sx, sy; + for(y = p->start_y, sy = p->start_sy >> 16; y < p->max_y; y += 2, ++sy) + for(x = p->start_x, sx = p->start_sx >> 16; x < p->max_x; + x += 2, ++sx) + DIAMOND(getpix32c, setpix32); +} +#undef MIX +#undef DIAMOND + +static void scale_diamond2x(scale_params_t *p) +{ + do_scale(p, do_scale_diamond2x_clip, do_scale_diamond2x_noclip); +} + +static void scale_diamond2x_clamp(scale_params_t *p) +{ + do_scale(p, do_scale_diamond2x_clamp, do_scale_diamond2x_noclip); +} + + +int s_filter_scale(s_bank_t *b, unsigned first, unsigned frames, + s_filter_args_t *args) +{ + scale_params_t params; + int fmode, smode = args->x; + unsigned i; + if((args->fx <= 0.0f) && (args->fy <= 0.0f)) + return 0; + if((args->fx == 1.0f) && (args->fy <= 1.0f)) + return 0; + + switch(smode) + { + case SF_SCALE_NEAREST: + case SF_SCALE_BILINEAR: + break; + case SF_SCALE_SCALE2X: + case SF_SCALE_DIAMOND: + if((args->fx != 2.0) || (args->fy != 2.0)) + { + log_printf(WLOG, "Scale2x and Diamond2x scaling " + "works only with a scaling factor " + "of exactly 2.0!\n"); +/* smode = SF_SCALE_NEAREST;*/ + smode = SF_SCALE_BILINEAR; + } + break; + } + + getpix32_empty = s_clampcolor; + + params.max_x = (int)ceil(b->w * args->fx); + params.scx = (int)(65536.0 / args->fx); + params.scy = (int)(65536.0 / args->fy); + params.start_x = 0; + params.start_sx = 0; + + /* Check for special SFont mode */ + if(args->flags & SF_CLAMP_SFONT) + { + params.start_y = 1; + params.start_sy = 65536; + params.max_y = (int)((b->h - 1) * args->fy + 1 + 0.5f); + } + else + { + params.start_y = 0; + params.start_sy = 0; + params.max_y = (int)(b->h * args->fy + 0.5f); + } + + /* Decode filter type + SF_CLAMP_EXTEND flag */ + fmode = (args->flags & SF_CLAMP_EXTEND) ? 1 : 0; + switch(smode) + { + case SF_SCALE_NEAREST: + fmode += 0; + break; + case SF_SCALE_BILINEAR: + fmode += 2; + /* Offset by half a pixel */ + params.start_sx += params.scx / 2; + params.start_sy += params.scy / 2; + break; + case SF_SCALE_SCALE2X: + fmode += 4; + break; + case SF_SCALE_DIAMOND: + fmode += 6; + break; + } + + for(i = 0; i < frames; ++i) + { + s_sprite_t *s = s_get_sprite_b(b, first+i); + if(!s) + continue; + params.src = s->surface; + params.dst = SDL_CreateRGBSurface(SDL_SWSURFACE, + params.max_x, params.max_y, 32, +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff); +#else + 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000); +#endif + if(!params.dst) + return -1; +#ifdef DEBUG + SDL_FillRect(params.dst, NULL, + SDL_MapRGB(params.dst->format, 255, 128, 0)); +#endif + + /* Deal with SFont marker row */ + if(args->flags & SF_CLAMP_SFONT) + { + int x, sx; + pix_t clear = {0, 0, 0, 0}; + /* Scale marker row with "nearest" filter */ + for(x = 0, sx = params.start_sx; x < params.max_x; + ++x, sx += params.scx) + setpix32_nc(params.dst, x, 0, + getpix32(params.src, + sx >> 16, 0)); + /* Remove marker row to avoid garbage */ + for(x = 0; x < b->w; ++x) + setpix32_nc(params.src, x, 0, clear); + } + + /* Do the scaling! */ + switch(fmode) + { + case 0: /*Nearest*/ + case 1: /*Nearest + extend clamping*/ + scale_nearest(¶ms); + break; + case 2: /*Bilinear*/ + scale_bilinear(¶ms); + break; + case 3: /*Bilinear + extend clamping*/ + scale_bilinear_clamp(¶ms); + break; + case 4: /*Scale2x*/ + scale_2x(¶ms); + break; + case 5: /*Scale2x + extend clamping*/ + scale_2x_clamp(¶ms); + break; + case 6: /*Diamond2x*/ + scale_diamond2x(¶ms); + break; + case 7: /*Diamond2x + extend clamping*/ + scale_diamond2x_clamp(¶ms); + break; + } + + SDL_FreeSurface(s->surface); + s->surface = params.dst; + } + b->w = params.max_x; + b->h = params.max_y; + return 0; +} + + +int s_filter_cleanalpha(s_bank_t *b, unsigned first, unsigned frames, + s_filter_args_t *args) +{ + int min = args->min; + int max = args->max; + int x, y; + unsigned i; + int contrast = (int)(args->fx * 256); + int offset = args->x + 128; /* 128 for the bias! */ + if(!contrast) + contrast = 256; /*Default = 1.0*/ + for(i = 0; i < frames; ++i) + { + s_sprite_t *s = s_get_sprite_b(b, first+i); + if(!s) + continue; + for(y = (args->flags & SF_CLAMP_SFONT) ? 1 : 0; y < b->h; ++y) + { + pix_t *p = (pix_t *)((char *)s->surface->pixels + + y * s->surface->pitch); + for(x = 0; x < b->w; ++x) + { + pix_t *pix = p + x; + int alpha = pix->a; + alpha = (alpha-128) * contrast >> 8; + alpha += offset; + if(alpha <= min) + pix->a = pix->r = pix->g = pix->b = 0; + else if(alpha > max) + pix->a = 255; + else + pix->a = alpha; + } + } + } + return 0; +} + + +int s_filter_brightness(s_bank_t *b, unsigned first, unsigned frames, + s_filter_args_t *args) +{ + int min = args->min; + int max = args->max; + int x, y; + unsigned i; + int contrast = (int)(args->fy * 256); + int offset = (int)(args->fx * 256 - 256) + 128; /* bias! */ + if((256 == contrast) && (128 == offset) && (min <= 0) && (max >= 255)) + return 0; /* No effect! --> */ + + for(i = 0; i < frames; ++i) + { + s_sprite_t *s = s_get_sprite_b(b, first + i); + if(!s) + continue; + for(y = (args->flags & SF_CLAMP_SFONT) ? 1 : 0; y < b->h; ++y) + { + pix_t *p = (pix_t *)((char *)s->surface->pixels + + y * s->surface->pitch); + for(x = 0; x < b->w; ++x) + { + int v; + pix_t *pix = p + x; + v = ((pix->r - 128) * contrast >> 8) + offset; + if(v < min) + v = min; + else if(v > max) + v = max; + pix->r = v; + v = ((pix->g - 128) * contrast >> 8) + offset; + if(v < min) + v = min; + else if(v > max) + v = max; + pix->g = v; + v = ((pix->b - 128) * contrast >> 8) + offset; + if(v < min) + v = min; + else if(v > max) + v = max; + pix->b = v; + } + } + } + return 0; +} + + +static void construct_limits(int *min, int *max, int maxdev) +{ + *min -= maxdev; + if(*min < 0) + *min = 0; + *max += maxdev; + if(*max > 255) + *max = 255; +} + + +static inline int check_limits(int min, int max, int value) +{ + if(value < min) + return 0; + if(value > max) + return 0; + return 1; +} + + +int s_filter_key2alpha(s_bank_t *b, unsigned first, unsigned frames, + s_filter_args_t *args) +{ + int x, y, krmin, krmax, kgmin, kgmax, kbmin, kbmax; + unsigned i; + krmin = krmax = s_colorkey.r; + kgmin = kgmax = s_colorkey.g; + kbmin = kbmax = s_colorkey.b; + construct_limits(&krmin, &krmax, args->max); + construct_limits(&kgmin, &kgmax, args->max); + construct_limits(&kbmin, &kbmax, args->max); + for(i = 0; i < frames; ++i) + { + s_sprite_t *s = s_get_sprite_b(b, first+i); + if(!s) + continue; + for(y = (args->flags & SF_CLAMP_SFONT) ? 1 : 0; y < b->h; ++y) + { + pix_t *p = (pix_t *)((char *)s->surface->pixels + + y * s->surface->pitch); + for(x = 0; x < b->h; ++x) + { + pix_t *pix = p + x; + if(check_limits(krmin, krmax, pix->r) + && check_limits(kgmin, kgmax, pix->g) + && check_limits(kbmin, kbmax, pix->b)) + pix->r = pix->g = pix->b = pix->a = 0; + } + } + } + return 0; +} + + +int s_filter_noise(s_bank_t *b, unsigned first, unsigned frames, + s_filter_args_t *args) +{ + int x, y; + unsigned i; + int br, bg, bb; /* bias */ + int ar, ag, ab; /* amplitude */ + i = args->min; + br = args->r * i >> 8; + bg = args->g * i >> 8; + bb = args->b * i >> 8; + i = args->max - args->min; + ar = args->r * i >> 8; + ag = args->g * i >> 8; + ab = args->b * i >> 8; + noise_reset(args->x); + for(i = 0; i < frames; ++i) + { + s_sprite_t *s = s_get_sprite_b(b, first+i); + if(!s) + continue; + for(y = (args->flags & SF_CLAMP_SFONT) ? 1 : 0; y < b->h; ++y) + { + pix_t *p = (pix_t *)((char *)s->surface->pixels + + y * s->surface->pitch); + for(x = 0; x < b->w; ++x) + { + int r, g, b; + pix_t *pix = p + x; + int rnd = noise(); + r = rnd * ar + br + pix->r; + g = rnd * ag + bg + pix->g; + b = rnd * ab + bb + pix->b; + if(r>255) + r = 255; + if(g>255) + g = 255; + if(b>255) + b = 255; + pix->r = r; + pix->g = g; + pix->b = b; + } + } + } + return 0; +} diff --git a/graphics/filters.h b/graphics/filters.h new file mode 100644 index 0000000..82ea343 --- /dev/null +++ b/graphics/filters.h @@ -0,0 +1,192 @@ +/*(LGPL) +---------------------------------------------------------------------- + filters.h - Filters for the sprite manager +---------------------------------------------------------------------- + * Copyright (C) David Olofson, 2001, 2003 + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef SPRITE_FILTERS_H +#define SPRITE_FILTERS_H + +#include "sprite.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Flags (args.flags) that apply to most plugins: + */ +#define SF_CLAMP_EXTEND 0x00000001 +#define SF_CLAMP_SFONT 0x00000002 + + +/* + * Convert bank to RGBA 8:8:8:8 format. + * + * (No arguments.) + */ +int s_filter_rgba8(s_bank_t *b, unsigned first, unsigned frames, + s_filter_args_t *args); + +/* + * Dither R, G and B channels to the specified bit depth. + * + * args.x = 1 activates 16 bit RGBA fix (assume +/-16 dither depth for RGBA) + * args.y = dither type (0 = 2x2 filter, 1 = random) + * + * args.r = red dither depth + * args.g = green dither depth + * args.b = blue dither depth + * + * args.flags; + * SF_CLAMP_SFONT SFont mode; first row is ignored. + * + * Note: This plugin does *not* dither the alpha channel! + */ +int s_filter_dither(s_bank_t *b, unsigned first, unsigned frames, + s_filter_args_t *args); + +/* + * Convert bank to display format for fast rendering. + * + * args.x = 1 forces use of SDL_DisplayFormat(). + * RGBA surfaces get a colorkey of <0,0,0,0>. + */ +int s_filter_displayformat(s_bank_t *b, unsigned first, unsigned frames, + s_filter_args_t *args); + +/* + * Convert colorkey to alpha channel. + * + * The global colorkey variable is used for base colorkey value. + * args.max = colorkey detection fuzziness factor + * args.flags; + * SF_CLAMP_SFONT SFont mode; first row is ignored. + */ +int s_filter_key2alpha(s_bank_t *b, unsigned first, unsigned frames, + s_filter_args_t *args); + +/* + * Adjust alpha level and contrast, and then clean out almost opaque + * and almost transparent pixels. + * + * args.fx = alpha contrast (1.0 = unchanged; 2.0 = double; scales around 128) + * args.x = alpha offset (0 = unchanged; -255 = all transp.; 255 = all opaque) + * + * args.min = min alpha passed (lower ==> 0) + * args.max = max alpha passed (higher ==> 255) + * + * args.flags; + * SF_CLAMP_SFONT SFont mode; first row is ignored. + */ +int s_filter_cleanalpha(s_bank_t *b, unsigned first, unsigned frames, + s_filter_args_t *args); + +/* + * Adjust brightness and contrast. + * + * args.fx = brightness (1.0 = unchanged; 0.0 = black; 2.0 = white) + * args.fy = contrast (1.0 = unchanged; 0.5 = 50%; 2.0 = 200%) + * + * args.min = min value (clamping) + * args.max = max value (clamping) + * + * args.flags; + * SF_CLAMP_SFONT SFont mode; first row is ignored. + */ +int s_filter_brightness(s_bank_t *b, unsigned first, unsigned frames, + s_filter_args_t *args); + +/* + * Scale images by the specified factor, using the specified method. + * + * args.x = scaling mode; + * SF_SCALE_NEAREST Nearest + * SF_SCALE_BILINEAR Bilinear interpolation + * SF_SCALE_SCALE2X Scale2x (Based on an algo from AdvanceMAME) + * SF_SCALE_DIAMOND Diamond (Weighted diamond shaped core) + * + * args.fx = horizontal scale factor (1.0 ==> 1:1) + * args.fy = vertical scale factor (1.0 ==> 1:1) + * + * args.flags; + * SF_CLAMP_EXTEND Clamp at edges; image edge is extended outwards + * SF_CLAMP_SFONT SFont mode; first row is treated specially. + * + */ +#define SF_SCALE_NEAREST 0 +#define SF_SCALE_BILINEAR 1 +#define SF_SCALE_SCALE2X 2 +#define SF_SCALE_DIAMOND 3 +int s_filter_scale(s_bank_t *b, unsigned first, unsigned frames, + s_filter_args_t *args); + +#if 0 +/* +TODO: + * Add shaded light to images. + * + * args.fx = Highlight X position ([0,1]) + * args.fy = Highlight Y position ([0,1]) + * args.fz = Highlight "half intensity" radius + * + * args.x = Gradient type: + * SF_LIGHT_LINEAR Linear gradient + * SF_LIGHT_CIRCULAR Circular spotlight + * + * args.z = Gradient rotation (65536 units/rotation) + * + * args.min = "Ambient light" + * args.max = Max brightness + * + * args.r = Light color, red component + * args.g = Light color, green component + * args.b = Light color, blue component + * + * args.flags; + * SF_CLAMP_SFONT SFont mode; first row is ignored. + */ +#define SF_LIGHT_LINEAR 0 +#define SF_LIGHT_CIRCULAR 1 +int s_filter_light(s_bank_t *b, unsigned first, unsigned frames, + s_filter_args_t *args); +#endif + +/* + * Add single colored noise to images. + * + * args.x = Pseudo-RNG seed for first frame + * + * args.min = Min brightness ([0,255]) + * args.max = Max brightness ([0,255]) + * + * args.r = Noise color, red component ([0,255]) + * args.g = Noise color, green component ([0,255]) + * args.b = Noise color, blue component ([0,255]) + * + * args.flags; + * SF_CLAMP_SFONT SFont mode; first row is ignored. + */ +int s_filter_noise(s_bank_t *b, unsigned first, unsigned frames, + s_filter_args_t *args); + +#ifdef __cplusplus +} +#endif + +#endif /* SPRITE_FILTERS_H */ diff --git a/graphics/gfxengine.cpp b/graphics/gfxengine.cpp new file mode 100644 index 0000000..c70a4b1 --- /dev/null +++ b/graphics/gfxengine.cpp @@ -0,0 +1,1426 @@ +/*(LGPL) +---------------------------------------------------------------------- + gfxengine.cpp - Graphics Engine +---------------------------------------------------------------------- + * Copyright (C) 2001-2003, 2006-2007 David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define DBG(x) x + +#include "logger.h" + +#include +#include + +#include "gfxengine.h" +#include "filters.h" +#include "SDL_image.h" +#include "glSDL.h" +#include "sofont.h" +#include "window.h" + +gfxengine_t *gfxengine; + + +gfxengine_t::gfxengine_t() +{ + gfxengine = this; /* Uurgh! Kludge. */ + + screen_surface = NULL; + softbuf = NULL; + fullwin = NULL; + window = NULL; + windows = NULL; + wx = wy = 0; + xs = ys = 256; // 1.0 + sxs = sys = 256; // 1.0 + sf1 = df = dsf = acf = NULL; + gfx = NULL; + csengine = NULL; + _driver = GFX_DRIVER_SDL2D; + _shadow = 1; + _doublebuf = 1; + _pages = -1; + _vsync = 1; + _fullscreen = 0; + _centered = 0; + use_interpolation = 1; + _depth = 0; + _title = "GfxEngine v0.4"; + _icontitle = "GfxEngine"; + _cursor = 1; + _width = 320; + _height = 240; + _autoinvalidate = 1; + _scalemode = GFX_SCALE_NEAREST; + _clamping = 0; + xflags = 0; + + _dither = 0; + _dither_type = 0; + broken_rgba8 = 0; + alpha_threshold = 0; + + _brightness = 1.0; + _contrast = 1.0; + + last_tick = -1000000; + ticks_per_frame = 1000.0/60.0; + + is_running = 0; + is_showing = 0; + is_open = 0; + + memset(fonts, 0, sizeof(fonts)); + + xscroll = yscroll = 0; + for(int i = 0; i < CS_LAYERS ; ++i) + xratio[i] = yratio[i] = 0.0; + + dirtyrects[0] = 0; + dirtyrects[1] = 0; + frontpage = 0; + backpage = 1; + screenshot_count = 0; +} + + +gfxengine_t::~gfxengine_t() +{ + stop(); + hide(); + close(); + window_t *w = windows; + while(w) + { + w->engine = NULL; + w = w->next; + } +} + + +void gfxengine_t::output(window_t *outwin) +{ + window = outwin; +} + + +/*---------------------------------------------------------- + Initialization +----------------------------------------------------------*/ + +void gfxengine_t::size(int w, int h) +{ + int was_showing = is_showing; + hide(); + + _width = w; + _height = h; + if(csengine) + cs_engine_set_size(csengine, w, h); + + if(was_showing) + show(); +} + +void gfxengine_t::centered(int c) +{ + int was_showing = is_showing; + hide(); + + _centered = c; + + if(was_showing) + show(); +} + +void gfxengine_t::scale(float x, float y) +{ + xs = (int)(x * 256.f); + ys = (int)(y * 256.f); + log_printf(DLOG, "gfxengine: Setting scale to %d:256 x %d:256.\n", xs, ys); +} + +void gfxengine_t::mode(int bits, int fullscreen) +{ + int was_showing = is_showing; + hide(); + + int olddepth = _depth; + _depth = bits; + if(_depth != olddepth) + reload(); + _fullscreen = fullscreen; + + if(was_showing) + show(); +} + +void gfxengine_t::driver(gfx_drivers_t drv) +{ + int was_showing = is_showing; + hide(); + + _driver = drv; + + if(was_showing) + show(); +} + +void gfxengine_t::doublebuffer(int use) +{ + if(_doublebuf == use) + return; + + int was_showing = is_showing; + hide(); + + _doublebuf = use; + + if(was_showing) + show(); +} + +void gfxengine_t::pages(int np) +{ + _pages = np; +} + +void gfxengine_t::vsync(int use) +{ + if(_vsync == use) + return; + + int was_showing = is_showing; + hide(); + + _vsync = use; + + if(was_showing) + show(); +} + +void gfxengine_t::shadow(int use) +{ + if(_shadow == use) + return; + + int was_showing = is_showing; + hide(); + + _shadow = use; + + if(was_showing) + show(); +} + +void gfxengine_t::autoinvalidate(int use) +{ + _autoinvalidate = use; +} + +void gfxengine_t::period(float frameduration) +{ + if(frameduration > 0) + { + ticks_per_frame = frameduration; + } + else + log_printf(DLOG, "gfxengine: Time line reset.\n"); + if(csengine) + cs_engine_advance(csengine, 0); +} + +void gfxengine_t::wrap(int x, int y) +{ + wx = x; + wy = y; + if(csengine) + cs_engine_set_wrap(csengine, x, y); +} + + +/*---------------------------------------------------------- + Data management +----------------------------------------------------------*/ + +void gfxengine_t::reset_filters() +{ + /* Remove all filters */ + s_remove_filter(NULL); + sf1 = df = dsf = acf = NULL; + + /* Set up filter pipeline */ + s_remove_filter(NULL); + + s_add_filter(s_filter_rgba8); +#if 0 + s_filter_t *fi; + fi = s_add_filter(s_filter_key2alpha); + fi->args.max = 1; +#endif + sf1 = s_add_filter(s_filter_scale); + sf2 = s_add_filter(s_filter_scale); + acf = s_add_filter(s_filter_cleanalpha); + bcf = s_add_filter(s_filter_brightness); + df = s_add_filter(s_filter_dither); + dsf = s_add_filter(s_filter_displayformat); + + /* Set default parameters */ +// colorkey(0, 0, 0); + clampcolor(0, 0, 0, 0); + scalemode(GFX_SCALE_NEAREST); + dither(0, 0); + noalpha(0); + brightness(1.0, 1.0); + filterflags(0); +} + + +void gfxengine_t::filterflags(int fgs) +{ + s_filter_flags = fgs; +} + + +void gfxengine_t::scalemode(gfx_scalemodes_t sm, int clamping) +{ + _scalemode = sm; + _clamping = clamping; + if(!sf1 || !df) + return; + + int rxs = (xs * 256 + 128) / sxs; + int rys = (ys * 256 + 128) / sys; +#if 1 + // Filter 2 is off in most cases + sf2->args.x = 0; + sf2->args.fx = 0.0f; + sf2->args.fy = 0.0f; +#endif + if((rxs == 256) && (rys == 256)) + { + sf1->args.x = SF_SCALE_NEAREST; + sf1->args.fx = 1.0f; + sf1->args.fy = 1.0f; + return; + } + + switch(clamping) + { + default: + case 0: + filterflags(0); + break; + case 1: + filterflags(SF_CLAMP_EXTEND); + break; + case 2: + filterflags(SF_CLAMP_SFONT); + break; + } + + sf1->args.fx = rxs * (1.0f/256.0f); + sf1->args.fy = rys * (1.0f/256.0f); + + switch(_scalemode) + { + case GFX_SCALE_NEAREST: //Nearest + sf1->args.x = SF_SCALE_NEAREST; + break; + case GFX_SCALE_BILINEAR: //Bilinear + sf1->args.x = SF_SCALE_BILINEAR; + break; + case GFX_SCALE_BILIN_OVER: //Bilinear + Oversampling +#if 0 + sf1->args.x = SF_SCALE_BILINEAR; + sf2->args.x = SF_SCALE_BILINEAR; + sf1->args.fx = rxs * (1.5f/256.f); + sf1->args.fy = rys * (1.5f/256.f); + sf2->args.fx = 1.0f/1.5f; + sf2->args.fy = 1.0f/1.5f; + break; + /* Hack for better bilinear [+ oversampling] scaling... */ + switch(clamping) + { + case 2: + sf1->args.x = SF_SCALE_NEAREST; + sf2->args.x = SF_SCALE_BILINEAR; + switch((rxs + 128) / 256) + { + case 2: + sf1->args.fx = 4.0f; + sf1->args.fy = 4.0f; + sf2->args.fx = 0.5f; + sf2->args.fy = 0.5f; + break; + case 3: + sf1->args.fx = 2.0f; + sf1->args.fy = 2.0f; + sf2->args.fx = 1.5f; + sf2->args.fy = 1.5f; + break; + case 4: + sf1->args.fx = 2.0f; + sf1->args.fy = 2.0f; + sf2->args.fx = 2.0f; + sf2->args.fy = 2.0f; + break; + default: + sf1->args.fx = rxs * (2.f/256.f); + sf1->args.fy = rys * (2.f/256.f); + sf2->args.fx = 0.5f; + sf2->args.fy = 0.5f; + break; + } + break; + default: + sf1->args.x = SF_SCALE_BILINEAR; + break; + } +#endif + sf1->args.x = SF_SCALE_BILINEAR; + break; + case GFX_SCALE_SCALE2X: //Scale2x + sf1->args.x = SF_SCALE_SCALE2X; + break; + case GFX_SCALE_DIAMOND: //Diamond2x + sf1->args.x = SF_SCALE_DIAMOND; + break; + } +} + + +void gfxengine_t::source_scale(float x, float y) +{ + sxs = (int)(x * 256.f); + sys = (int)(y * 256.f); + scalemode(_scalemode, _clamping); +} + +#if 0 +void gfxengine_t::colorkey(Uint8 r, Uint8 g, Uint8 b) +{ + s_colorkey.r = r; + s_colorkey.g = g; + s_colorkey.b = b; +} +#endif + +void gfxengine_t::clampcolor(Uint8 r, Uint8 g, Uint8 b, Uint8 a) +{ + s_clampcolor.r = r; + s_clampcolor.g = g; + s_clampcolor.b = b; + s_clampcolor.a = b; +} + + +void gfxengine_t::dither(int type, int _broken_rgba8) +{ + _dither = type >= 0; + _dither_type = type; + broken_rgba8 = _broken_rgba8; + + if(!df) + return; + if(!screen_surface) + return; + + if(_dither) + { + if(_driver == GFX_DRIVER_GLSDL) + { + //Klugde for glSDL, which doesn't give us a faked + //screen surface - while we're interested only in + //the *texture* depth; not the display depth! + df->args.r = df->args.g = df->args.b = 0; + //Another kludge, because some cards support RGB8 + //(24 bit) textures, but not RGBA8 (32 bit). + df->args.x = broken_rgba8; + } + else + { + df->args.x = 0; + df->args.r = 1<<(screen_surface->format->Rloss-1); + df->args.g = 1<<(screen_surface->format->Gloss-1); + df->args.b = 1<<(screen_surface->format->Bloss-1); + } + } + else + df->args.x = df->args.r = df->args.g = df->args.b = 0; + df->args.y = type; +} + + +void gfxengine_t::noalpha(int threshold) +{ + alpha_threshold = threshold; + if(!dsf || !acf) + return; + + if(threshold > 0) + { + acf->args.min = 128; + acf->args.max = 128; + acf->args.fx = 1.0; + acf->args.x = threshold; + + dsf->args.x = 1; + } + else + { + acf->args.min = 16; + acf->args.max = 255-16; + acf->args.fx = 1.3; + acf->args.x = -16; + + dsf->args.x = 0; + } +} + + +void gfxengine_t::brightness(float bright, float contr) +{ + _brightness = bright; + _contrast = contr; + if(!bcf) + return; + + bcf->args.fx = _brightness; + bcf->args.fy = _contrast; + bcf->args.min = 0; + bcf->args.max = 255; +} + + +int gfxengine_t::loadimage(int bank, const char *name) +{ + if(!csengine) + { + log_printf(ELOG, "loadimage: Engine must be open!\n"); + return -10; + } + s_blitmode = S_BLITMODE_AUTO; + log_printf(DLOG, "Loading image %s (bank %d)...\n", name, bank); + if(s_load_image(gfx, bank, name)) + { + log_printf(ELOG, " Failed to load %s!\n", name); + return -1; + } + + s_bank_t *b = s_get_bank(gfx, bank); + if(!b) + { + log_printf(ELOG, " gfxengine: Internal error 1!\n"); + return -15; + } + cs_engine_set_image_size(csengine, bank, b->w, b->h); + + log_printf(DLOG, " Ok.\n"); + return 0; +} + + +int gfxengine_t::loadtiles(int bank, int w, int h, const char *name) +{ + if(!csengine) + { + log_printf(ELOG, "loadtiles: Engine must be open!\n"); + return -10; + } + s_blitmode = S_BLITMODE_AUTO; + log_printf(DLOG, "Loading tiles %s (bank %d; %dx%d)...\n", + name, bank, w, h); + if(s_load_bank(gfx, bank, w, h, name)) + { + log_printf(ELOG, " Failed to load %s!\n", name); + return -2; + } + + cs_engine_set_image_size(csengine, bank, w, h); + + log_printf(DLOG, " Ok. (%d frames)\n", s_get_bank(gfx, bank)->max+1); + return 0; +} + + +int gfxengine_t::loadfont(int bank, const char *name) +{ + if(!csengine) + { + log_printf(ELOG, "loadfont: Engine must be open!\n"); + return -10; + } + s_blitmode = S_BLITMODE_AUTO; + scalemode(_scalemode, 2); + log_printf(DLOG, "Loading font %s (bank %d)...\n", name, bank); + if(s_load_image(gfx, bank, name)) + { + log_printf(ELOG, " Failed to load %s!\n", name); + return -2; + } + if(bank >= GFX_BANKS) + { + log_printf(ELOG, " Too high bank #!\n"); + return -3; + } + + if(!fonts[bank]) + fonts[bank] = new SoFont; + if(!fonts[bank]) + { + log_printf(ELOG, " Failed to instantiate SoFont!\n"); + return -4; + } + + fonts[bank]->ExtraSpace((xs + 127) / 256); + if(fonts[bank]->load(s_get_sprite(gfx, bank, 0)->surface)) + { + s_detach_sprite(gfx, bank, 0); + log_printf(DLOG, " Ok.\n"); + return 0; + } + else + { + log_printf(ELOG, " SoFont::load() failed!\n"); + return -5; + } + return 0; +} + + +int gfxengine_t::copyrect(int bank, int sbank, int sframe, SDL_Rect *r) +{ + SDL_Rect sr = *r; + if(!csengine) + { + log_printf(ELOG, "copyrect: Engine must be open!\n"); + return -10; + } + log_printf(DLOG, "Copying rect from %d:%d (bank %d)...\n", + sbank, sframe, bank); + int x2 = (int)((sr.x + sr.w) * xs + 128) >> 8; + int y2 = (int)((sr.y + sr.h) * ys + 128) >> 8; + sr.x = (int)(sr.x * xs + 128) >> 8; + sr.y = (int)(sr.y * ys + 128) >> 8; + sr.w = x2 - sr.x; + sr.h = y2 - sr.y; + if(s_copy_rect(gfx, bank, sbank, sframe, &sr) < 0) + { + log_printf(ELOG, " s_copy_rect() failed!\n"); + return -1; + } + log_printf(DLOG, " Ok.\n"); + return 0; +} + + +int gfxengine_t::is_loaded(int bank) +{ + if(!csengine) + return 0; + if(!s_get_bank(gfx, (unsigned)bank)) + return 0; + return 1; +} + + +void gfxengine_t::reload() +{ + log_printf(DLOG, "Reloading all banks. (Not implemented!)\n"); +// s_reload_all_banks(gfx); +} + + +void gfxengine_t::unload(int bank) +{ + if(bank < 0) + { + log_printf(DLOG, "Unloading all banks.\n"); + for(int i = 0; i < GFX_BANKS; ++i) + { + delete fonts[i]; + fonts[i] = NULL; + } + if(gfx) + s_delete_all_banks(gfx); + } + else + { + log_printf(DLOG, "Unloading bank %d.\n", bank); + if(bank < GFX_BANKS) + { + delete fonts[bank]; + fonts[bank] = NULL; + } + if(gfx) + s_delete_bank(gfx, bank); + } +} + + +/*---------------------------------------------------------- + Engine open/close +----------------------------------------------------------*/ + +void gfxengine_t::on_frame(cs_engine_t *e) +{ + gfxengine->__frame(); + gfxengine->frame(); +} + + +int gfxengine_t::open(int objects, int extraflags) +{ + xflags = extraflags; + + if(is_open) + return show(); + + log_printf(DLOG, "Opening engine...\n"); + csengine = cs_engine_create(_width, _height, objects); + if(!csengine) + { + log_printf(ELOG, "Failed to set up control system engine!\n"); + return -1; + } + + csengine->on_frame = on_frame; + cs_engine_set_wrap(csengine, wx, wy); + + gfx = s_new_container(GFX_BANKS); + if(!gfx) + { + log_printf(ELOG, "Failed to set up graphics container!\n"); + cs_engine_delete(csengine); + return -2; + } + + reset_filters(); + + is_open = 1; + return show(); +} + + +void gfxengine_t::close() +{ + if(!is_open) + return; + + log_printf(DLOG ,"Closing engine...\n"); + stop(); + hide(); + unload(); + cs_engine_delete(csengine); + csengine = NULL; + s_remove_filter(NULL); + sf1 = df = dsf = acf = NULL; + s_delete_container(gfx); + gfx = NULL; + is_open = 0; +} + + +/*---------------------------------------------------------- + Settings +----------------------------------------------------------*/ + +void gfxengine_t::title(const char *win, const char *icon) +{ + _title = win; + _icontitle = icon; + if(screen_surface) + SDL_WM_SetCaption(_title, _icontitle); +} + + +/*---------------------------------------------------------- + Display show/hide +----------------------------------------------------------*/ + +int gfxengine_t::show() +{ + int flags = 0; + + if(!is_open) + return -1; + + if(is_showing) + return 0; + + if(_centered && !_fullscreen) + SDL_putenv((char *)"SDL_VIDEO_CENTERED=1"); + + log_printf(DLOG, "Opening screen...\n"); + if(!SDL_WasInit(SDL_INIT_VIDEO)) + if(SDL_InitSubSystem(SDL_INIT_VIDEO) == -1) + { + log_printf(ELOG, "Failed to initialize SDL!\n"); + return -2; + } + + switch(_driver) + { + case GFX_DRIVER_SDL2D: + break; + case GFX_DRIVER_GLSDL: + if(!_doublebuf) + { + log_printf(WLOG, "Only double buffering is supported" + " with OpenGL drivers!\n"); + doublebuffer(1); + } + if(_shadow) + { + log_printf(WLOG, "Shadow buffer not supported" + " with OpenGL drivers!\n"); + shadow(0); + } + break; + } + + switch(_driver) + { + case GFX_DRIVER_SDL2D: + /* Nothing extra */ + break; + case GFX_DRIVER_GLSDL: + flags |= SDL_GLSDL; + break; + } + + if(_doublebuf) + flags |= SDL_DOUBLEBUF | SDL_HWSURFACE; + else + { + if(!_shadow) + flags |= SDL_HWSURFACE; + } + + if(_fullscreen) + flags |= SDL_FULLSCREEN; + + glSDL_VSync(_vsync); + flags |= xflags; + + screen_surface = SDL_SetVideoMode(_width, _height, _depth, flags); + if(!screen_surface) + { + log_printf(ELOG, "Failed to open display!\n"); + return -3; + } + + if(_driver != GFX_DRIVER_GLSDL) + { + if((screen_surface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) + { + if(!_doublebuf) + { + log_printf(WLOG, "Could not get" + " single buffered display.\n"); + doublebuffer(1); + } + } + else + { + if(_doublebuf) + { + log_printf(WLOG, "Could not get" + " double buffered display.\n"); + doublebuffer(0); + } + } + } + + if((screen_surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE) + { + if(_shadow) + { + softbuf = SDL_CreateRGBSurface(SDL_SWSURFACE, + _width, _height, + screen_surface->format->BitsPerPixel, + screen_surface->format->Rmask, + screen_surface->format->Gmask, + screen_surface->format->Bmask, + screen_surface->format->Amask); + if(!softbuf) + { + log_printf(WLOG, "Failed to create shadow buffer! " + "Trying direct rendering.\n"); + shadow(0); + } + } + } + else + { + if(_shadow) + log_printf(WLOG, "Shadow buffer requested; " + "relying on SDL's shadow buffer.\n"); + else + { + log_printf(WLOG, "Could not get h/w display surface.\n"); + shadow(0); //...which means we're using SDL's shadow. + } + } + + SDL_WM_SetCaption(_title, _icontitle); + SDL_ShowCursor(_cursor); + cs_engine_set_size(csengine, _width, _height); + csengine->filter = use_interpolation; + + dither(_dither); + noalpha(alpha_threshold); + is_showing = 1; + + fullwin = new window_t; + fullwin->init(this); + fullwin->place(0, 0, (int)(_width / xscale()), + (int)(_height / yscale())); + + clear(); + + return 0; +} + + +void gfxengine_t::clear(Uint32 _color) +{ + if(!fullwin) + return; + + fullwin->background(fullwin->map_rgb(_color)); + fullwin->clear(); + flip(); + fullwin->clear(); + flip(); + fullwin->clear(); +} + + +void gfxengine_t::hide(void) +{ + if(!is_showing) + return; + + log_printf(DLOG, "Closing screen...\n"); + stop(); + delete fullwin; + fullwin = NULL; + + // Make sure no windows keep old surface pointers! + window_t *w = windows; + while(w) + { + if((w->surface == screen_surface) || + (w->surface == softbuf)) + w->surface = NULL; + w = w->next; + } + + if(softbuf) + { + SDL_FreeSurface(softbuf); + softbuf = NULL; + } + screen_surface = NULL; + + is_showing = 0; +} + + +void gfxengine_t::invalidate(SDL_Rect *rect, window_t *window) +{ + switch(_pages) + { + case -1: + if(_doublebuf) + __invalidate(1, rect, window); + __invalidate(0, rect, window); + break; + case 0: + __invalidate(0, NULL, NULL); + break; + case 3: + __invalidate(2, rect, window); + // Fallthrough! + case 2: + __invalidate(1, rect, window); + // Fallthrough! + case 1: + __invalidate(0, rect, window); + break; + } +} + + +void gfxengine_t::__invalidate(int page, SDL_Rect *rect, window_t *window) +{ + if(!screen_surface) + return; + + if(!rect || (_pages == 0)) + { + dirtyrects[page] = 1; + dirtytable[page][0].x = 0; + dirtytable[page][0].y = 0; + dirtytable[page][0].w = screen_surface->w; + dirtytable[page][0].h = screen_surface->h; + dirtywtable[page][0] = NULL; + return; + } + + /* Clip to screen (stolen from SDL_surface.c) */ + SDL_Rect dr = *rect; + int Amin, Amax, Bmin, Bmax; + + /* Horizontal intersection */ + Amin = dr.x; + Amax = Amin + dr.w; + Bmin = screen_surface->clip_rect.x; + Bmax = Bmin + screen_surface->clip_rect.w; + if(Bmin > Amin) + Amin = Bmin; + dr.x = Amin; + if(Bmax < Amax) + Amax = Bmax; + dr.w = Amax - Amin > 0 ? Amax - Amin : 0; + + /* Vertical intersection */ + Amin = dr.y; + Amax = Amin + dr.h; + Bmin = screen_surface->clip_rect.y; + Bmax = Bmin + screen_surface->clip_rect.h; + if(Bmin > Amin) + Amin = Bmin; + dr.y = Amin; + if(Bmax < Amax) + Amax = Bmax; + dr.h = Amax - Amin > 0 ? Amax - Amin : 0; + + if(!dr.w || !dr.h) + return; + + for(int i = 0; i < dirtyrects[page]; ++i) + if(memcmp(&dirtytable[page][i], &dr, sizeof(dr)) == 0) + return; + + if(dirtyrects[page] < MAX_DIRTYRECTS - 1) + { + dirtytable[page][dirtyrects[page]] = dr; + dirtywtable[page][dirtyrects[page]] = window; + ++dirtyrects[page]; + } + else + log_printf(ELOG, "gfxengine: Page %d out of dirtyrects!\n", + page); +} + + +/*---------------------------------------------------------- + Engine start/stop +----------------------------------------------------------*/ + +void gfxengine_t::start_engine() +{ + last_tick = -1000000; +} + + +void gfxengine_t::stop_engine() +{ +} + + +/*---------------------------------------------------------- + Control +----------------------------------------------------------*/ + +/* + * Run engine until stop() is called. + * + * The virtual member frame() will be called once for + * each control system frame. pre_render() and + * post_render() will be called before/after the engine + * renders each video frame. + */ +void gfxengine_t::run() +{ + open(); + show(); + start_engine(); + is_running = 1; + double toframe = 0.0f; + double fdt = 1.0f; + cs_engine_advance(csengine, 0); + while(is_running) + { + int t = (int)SDL_GetTicks(); + int dt = t - last_tick; + last_tick = t; + if(abs(dt) > 500) + last_tick = t; + if(dt > 250) + dt = (int)ticks_per_frame; + if(_timefilter) + fdt += (dt - fdt) * _timefilter; + else + fdt = ticks_per_frame; + toframe += fdt / ticks_per_frame; + cs_engine_advance(csengine, toframe); + pre_render(); + window->select(); + cs_engine_render(csengine); + post_render(); + if(_autoinvalidate) + window->invalidate(); + flip(); + } + stop_engine(); +} + + +void gfxengine_t::stop() +{ + if(!is_running) + return; + + log_printf(DLOG, "Stopping engine...\n"); + is_running = 0; +} + + +void gfxengine_t::cursor(int csr) +{ + _cursor = csr; + if(screen_surface) + SDL_ShowCursor(csr); +} + + +void gfxengine_t::interpolation(int inter) +{ + use_interpolation = inter; + if(!csengine) + return; + + csengine->filter = use_interpolation; +} + + +void gfxengine_t::timefilter(float coeff) +{ + if(coeff < 0.001f) + _timefilter = 0.0f; + else if(coeff > 1.0f) + _timefilter = 1.0f; + else + _timefilter = coeff; +} + + +void gfxengine_t::scroll_ratio(int layer, float xr, float yr) +{ + if(layer < 0) + return; + if(layer >= CS_LAYERS) + return; + + xratio[layer] = xr; + yratio[layer] = yr; +} + + +void gfxengine_t::scroll(int xscr, int yscr) +{ + xscroll = xscr; + yscroll = yscr; + + /* Apply current scroll pos to layers */ + for(int i = 0; i < CS_LAYERS ; ++i) + { + csengine->offsets[i].v.x = (int)floor(xscroll * xratio[i]); + csengine->offsets[i].v.y = (int)floor(yscroll * yratio[i]); + } +} + + +void gfxengine_t::force_scroll() +{ + if(csengine) + for(int i = 0; i < CS_LAYERS ; ++i) + cs_point_force(&csengine->offsets[i]); +} + + +int gfxengine_t::xoffs(int layer) +{ + if(layer < 0) + return 0; + if(layer >= CS_LAYERS) + return 0; + return csengine->offsets[layer].gx; +} + + +int gfxengine_t::yoffs(int layer) +{ + if(layer < 0) + return 0; + if(layer >= CS_LAYERS) + return 0; + return csengine->offsets[layer].gy; +} + + +SDL_Surface *gfxengine_t::surface() +{ + if(softbuf) + return softbuf; + else + return screen_surface; +} + + +void gfxengine_t::screenshot() +{ + char filename[1024]; + snprintf(filename, sizeof(filename), "screen%d.bmp", screenshot_count++); + SDL_SaveBMP(screen_surface, filename); +} + + +/*---------------------------------------------------------- + Internal stuff +----------------------------------------------------------*/ + +/* Default frame handler */ +void gfxengine_t::frame() +{ + SDL_Event ev; + while(SDL_PollEvent(&ev)) + { + if(ev.type == SDL_KEYDOWN) + if(ev.key.keysym.sym == SDLK_ESCAPE) + stop(); + } +} + + +/* Internal frame handler */ +void gfxengine_t::__frame() +{ +} + + +void gfxengine_t::pre_render() +{ +} + + +void gfxengine_t::post_render() +{ +} + + +void gfxengine_t::refresh_rect(SDL_Rect *r) +{ + window_t *w = windows; + for(w = windows; w; w = w->next) + { + if(!w->visible()) + continue; + + SDL_Rect dr = *r; + + /* Clip to window */ + int Amin, Amax, Bmin, Bmax; + + /* Horizontal intersection */ + Amin = dr.x; + Amax = Amin + dr.w; + Bmin = w->phys_rect.x; + Bmax = Bmin + w->phys_rect.w; + if(Bmin > Amin) + Amin = Bmin; + dr.x = Amin; + if(Bmax < Amax) + Amax = Bmax; + dr.w = Amax - Amin > 0 ? Amax - Amin : 0; + + /* Vertical intersection */ + Amin = dr.y; + Amax = Amin + dr.h; + Bmin = w->phys_rect.y; + Bmax = Bmin + w->phys_rect.h; + if(Bmin > Amin) + Amin = Bmin; + dr.y = Amin; + if(Bmax < Amax) + Amax = Bmax; + dr.h = Amax - Amin > 0 ? Amax - Amin : 0; + + if(dr.w && dr.h) + w->phys_refresh(&dr); + } +} + + +void gfxengine_t::flip() +{ + if(!screen_surface) + return; + + // Init dirtyrect table flipping, if necessary. + switch(_pages) + { + case -1: + if(!_doublebuf) + frontpage = backpage = 0; + else if(frontpage == backpage) + { + frontpage = 0; + backpage = 1; + } + break; + case 0: + frontpage = backpage = 0; + invalidate(); + break; + case 1: + frontpage = backpage = 0; + break; + case 2: + case 3: + if(frontpage == backpage) + { + frontpage = 0; + backpage = 1; + } + break; + } + + // Process the dirtyrects. + int i; + for(i = 0; i < dirtyrects[backpage]; ++i) + { + if(dirtywtable[backpage][i]) + { + if(!dirtywtable[backpage][i]->visible()) + continue; + SDL_Rect dr = dirtytable[backpage][i]; + dirtywtable[backpage][i]->phys_refresh(&dr); + } + else + refresh_rect(&dirtytable[backpage][i]); + } + + // Perform the actual flip or update + if(_shadow) + { + for(i = 0; i < dirtyrects[backpage]; ++i) + SDL_BlitSurface(softbuf, + &dirtytable[backpage][i], + screen_surface, + &dirtytable[backpage][i]); + } + if(_doublebuf) + { + dirtyrects[backpage] = 0; + if(_pages == -1) + { + backpage = !backpage; + frontpage = !frontpage; + } + else if(_pages > 1) + { + backpage = (backpage + 1) % _pages; + frontpage = (frontpage + 1) % _pages; + } + SDL_Flip(screen_surface); + } + else + { + SDL_UpdateRects(screen_surface, dirtyrects[0], dirtytable[0]); + dirtyrects[0] = 0; + } +} + + +/* + * Generic render() callback for sprites and tiles. + */ +void gfxengine_t::render_sprite(cs_obj_t *o) +{ + SDL_Rect dest_rect; + s_sprite_t *s = gfxengine->get_sprite(o->anim.bank, o->anim.frame); + if(!s || !s->surface) + return; + + int x = o->point.gx - (s->x << 8); + int y = o->point.gy - (s->y << 8); + dest_rect.x = CS2PIXEL((x * gfxengine->xs + 128) >> 8); + dest_rect.y = CS2PIXEL((y * gfxengine->ys + 128) >> 8); + dest_rect.x += (gfxengine->window->x() * gfxengine->xs + 128) >> 8; + dest_rect.y += (gfxengine->window->y() * gfxengine->xs + 128) >> 8; + SDL_BlitSurface(s->surface, NULL, gfxengine->surface(), &dest_rect); + + if(!gfxengine->_autoinvalidate) + { + dest_rect.w = s->surface->w; + dest_rect.h = s->surface->h; + gfxengine->invalidate(&dest_rect); + } +} + + +cs_obj_t *gfxengine_t::get_obj(int layer) +{ + cs_obj_t *o = cs_engine_get_obj(csengine); + if(o) + { + o->render = render_sprite; + cs_obj_layer(o, layer); + cs_obj_activate(o); + } + return o; +} + + +void gfxengine_t::free_obj(cs_obj_t *obj) +{ + cs_obj_free(obj); +} + + +int gfxengine_t::objects_in_use() +{ + if(!csengine) + return 0; + + return csengine->pool_total - csengine->pool_free; +} + + +SoFont *gfxengine_t::get_font(unsigned int f) +{ + if(f < GFX_BANKS) + return fonts[f]; + else + return NULL; +} diff --git a/graphics/gfxengine.h b/graphics/gfxengine.h new file mode 100644 index 0000000..b473247 --- /dev/null +++ b/graphics/gfxengine.h @@ -0,0 +1,282 @@ +/*(LGPL) +---------------------------------------------------------------------- + gfxengine.h - Graphics Engine +---------------------------------------------------------------------- + * Copyright (C) 2001-2003, 2007 David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _GFXENGINE_H_ +#define _GFXENGINE_H_ + +#define GFX_BANKS 256 +#define MAX_DIRTYRECTS 1024 +#define MAX_PAGES 3 + +#include +#include +#include +#include "glSDL.h" +#include "sprite.h" +#include "cs.h" + +enum gfx_drivers_t +{ + GFX_DRIVER_SDL2D = 0, + GFX_DRIVER_GLSDL = 1 +}; + +enum gfx_scalemodes_t +{ + GFX_SCALE_NEAREST = 0, + GFX_SCALE_BILINEAR = 1, + GFX_SCALE_BILIN_OVER = 2, + GFX_SCALE_SCALE2X = 3, + GFX_SCALE_DIAMOND = 4 +}; + +class window_t; +class SoFont; + +class gfxengine_t +{ + friend class window_t; + public: + gfxengine_t(); + virtual ~gfxengine_t(); + + void output(window_t *outwin); + window_t *output() { return window; } + + void screen(window_t *fullwin); + window_t *screen() { return fullwin; } + + /* + * Initialization + */ + void size(int w, int h); + void centered(int c); + void scale(float x, float y); + void driver(gfx_drivers_t drv); + void mode(int bits, int fullscreen); + + // 1: Use double buffering if possible + void doublebuffer(int use); + + // -1: Use default for shadow() and doublebuffer() settings + // 0: None; assume flipping gives you a garbage buffer + // 1: Assume flipping leaves the back buffer intact + // 2: Assume two buffers that are swapped when flipping + // 3: Assume three buffers cycled when flipping + void pages(int np); + + // 1: Enable vsync, if available + void vsync(int use); + + // 1: Use a software shadow back buffer, if possible + void shadow(int use); + + void autoinvalidate(int use); + + void interpolation(int inter); + + // 0 to reset internal timer + void period(float frameduration); + + // 0 to disable timing, running one logic frame per rendered frame. + // 1 to disable filtering, using raw delta times for timing. + void timefilter(float coeff); + + void wrap(int x, int y); + + /* Info */ + int doublebuffer() { return _doublebuf; } + int shadow() { return _shadow; } + int autoinvalidate() { return _autoinvalidate; } + + /* Engine open/close */ + int open(int objects = 1024, int extraflags = 0); + void close(); + + /* Data management (use while engine is open) */ + void reset_filters(); + void filterflags(int fgs); + void scalemode(gfx_scalemodes_t sm, int clamping = 0); + void source_scale(float x, float y); +// void colorkey(Uint8 r, Uint8 g, Uint8 b); + void clampcolor(Uint8 r, Uint8 g, Uint8 b, Uint8 a); + void dither(int type = 0, int _broken_rgba8 = 0); + void noalpha(int threshold = 128); + void brightness(float bright, float contr); + + int loadimage(int bank, const char *name); + int loadtiles(int bank, int w, int h, const char *name); + int loadfont(int bank, const char *name); + int copyrect(int bank, int sbank, int sframe, SDL_Rect *r); + + int is_loaded(int bank); + void reload(); + void unload(int bank = -1); + + /* Settings (use while engine is open) */ + void title(const char *win, const char *icon); + + /* Display show/hide */ + int show(); + void hide(); + + /* Main loop take-over */ + void run(); + + /* + * Override these; + * frame() is called once per control system frame, + * after the control system has executed. + * pre_render() is called after the engine has advanced + * to the state for the current video frame + * (interpolated state is calculated), before + * the engine renders all graphics. + * post_render() is called after the engine have + * rendered all sprites, but before video the + * sync/flip/update operation. + */ + virtual void frame(); + virtual void pre_render(); + virtual void post_render(); + + /* + --------------------------------------------- + * The members below this line can safely be + * called from within the frame() handler. + */ + + /* Rendering */ + void clear(Uint32 _color = 0x000000); + void invalidate(SDL_Rect *rect = NULL, window_t *window = NULL); + + /* Screenshots */ + void screenshot(); + + /* Control */ + cs_engine_t *cs() { return csengine; } + SDL_Surface *surface(); + void flip(); // Flip pages + void update(); // Full update, making current draw page visible + void stop(); + cs_obj_t *get_obj(int layer); + void free_obj(cs_obj_t *obj); + void cursor(int csr); + + s_sprite_t *get_sprite(unsigned bank, int _frame) + { + return s_get_sprite(gfx, bank, _frame); + } + SoFont *get_font(unsigned int f); + int set_hotspot(unsigned bank, int _frame, int x, int y) + { + return s_set_hotspot(gfx, bank, _frame, x, y); + } + + void scroll_ratio(int layer, float xr, float yr); + void scroll(int xs, int ys); + void force_scroll(); + + int xoffs(int layer); + int yoffs(int layer); + + /* Info */ + int objects_in_use(); + + int width() { return _width; } + int height() { return _height; } + float xscale() { return xs * (1.f/256.f); } + float yscale() { return ys * (1.f/256.f); } + + protected: + gfx_drivers_t _driver; + gfx_scalemodes_t _scalemode; + int _clamping; + SDL_Surface *screen_surface; + SDL_Surface *softbuf; + int backpage; + int frontpage; + int dirtyrects[MAX_PAGES]; + SDL_Rect dirtytable[MAX_PAGES][MAX_DIRTYRECTS]; + window_t *dirtywtable[MAX_PAGES][MAX_DIRTYRECTS]; + window_t *fullwin; + window_t *window; + window_t *windows; // Linked list + int wx, wy; + int xs, ys; // fix 24:8 + int sxs, sys; // fix 24:8 + s_filter_t *sf1, *sf2; // Scaling filter plugins + s_filter_t *acf; // Alpha cleaning plugin + s_filter_t *bcf; // Brightness/contrast plugin + s_filter_t *df; // Dither filter plugin + s_filter_t *dsf; // Display format plugin + int xscroll, yscroll; + float xratio[CS_LAYERS]; + float yratio[CS_LAYERS]; + s_container_t *gfx; + SoFont *fonts[GFX_BANKS]; // Kludge. + cs_engine_t *csengine; + int xflags; + int _doublebuf; + int _pages; + int _vsync; + int _shadow; + int _fullscreen; + int _centered; + int _autoinvalidate; + int use_interpolation; + int _width, _height; + int _depth; + const char *_title; + const char *_icontitle; + int _cursor; + int _dither; + int _dither_type; + int broken_rgba8; //Klugde for OpenGL (if RGBA8 ==> RGBA4) + int alpha_threshold; //For noalpha() + float _brightness; + float _contrast; + + int last_tick; + float ticks_per_frame; + float _timefilter; + + int is_showing; + int is_running; + int is_open; + + int screenshot_count; + + void __invalidate(int page, SDL_Rect *rect = NULL, + window_t *window = NULL); + void refresh_rect(SDL_Rect *r); + + static void on_frame(cs_engine_t *e); + void __frame(); + + void start_engine(); + void stop_engine(); + static void render_sprite(cs_obj_t *o); +}; + + +extern gfxengine_t *gfxengine; + +#endif diff --git a/graphics/glSDL.c b/graphics/glSDL.c new file mode 100644 index 0000000..599a1ff --- /dev/null +++ b/graphics/glSDL.c @@ -0,0 +1,2328 @@ +/*(LGPL) +------------------------------------------------------------ + glSDL 0.9 - SDL 2D API on top of OpenGL +------------------------------------------------------------ + * Copyright (C) 2001-2004, 2006-2007 David Olofson + * This code is released under the terms of the GNU LGPL. + */ + +#define _GLSDL_NO_REDEFINES_ +#include "glSDL.h" + +#ifdef HAVE_OPENGL + +#define LEAK_TRACKING + +#define DBG(x) /*error messages, warnings*/ +#define DBG2(x) /*texture allocation*/ +#define DBG3(x) /*chopping/tiling*/ +#define DBG4(x) /*texture uploading*/ +#define DBG5(x) /*two-way chopping/tiling*/ +#define DBG6(x) /*OpenGL lib loading*/ + +#undef CKSTATS /*colorkey statistics*/ + +/* Keep this on for now! Makes large surfaces faster. */ +#define FAKE_MAXTEXSIZE 256 + +#include +#include +#include + +#if HAS_SDL_OPENGL_H +#include "SDL_opengl.h" +#else +#ifdef WIN32 +#include +#endif +#if defined(__APPLE__) && defined(__MACH__) +#include +#include +#else +#include +#include +#endif +#endif + +#if defined(_WIN32) && !defined(APIENTRY) && \ + !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) +#include +#endif +#ifndef APIENTRY +#define APIENTRY +#endif + + +static inline void clip_rect(SDL_Rect *r, SDL_Rect *to) +{ + int dx1 = r->x; + int dy1 = r->y; + int dx2 = dx1 + r->w; + int dy2 = dy1 + r->h; + if(dx1 < to->x) + dx1 = to->x; + if(dy1 < to->y) + dy1 = to->y; + if(dx2 > to->x + to->w) + dx2 = to->x + to->w; + if(dy2 > to->y + to->h) + dy2 = to->y + to->h; + if(dx2 < dx1 || dy2 < dy1) + { + r->x = r->y = 0; + r->w = r->h = 0; + } + else + { + r->x = dx1; + r->y = dy1; + r->w = dx2 - dx1; + r->h = dy2 - dy1; + } +} + + +/*---------------------------------------------------------- + OpenGL interface +----------------------------------------------------------*/ + +static struct +{ + void (APIENTRY *Begin)(GLenum); + void (APIENTRY *BindTexture)(GLenum, GLuint); + void (APIENTRY *BlendFunc)(GLenum, GLenum); + void (APIENTRY *Color4ub)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); + void (APIENTRY *DeleteTextures)(GLsizei n, const GLuint *textures); + void (APIENTRY *Disable)(GLenum cap); + void (APIENTRY *Enable)(GLenum cap); + void (APIENTRY *End)(void); + void (APIENTRY *Flush)(void); + void (APIENTRY *GenTextures)(GLsizei n, GLuint *textures); + GLenum (APIENTRY *GetError)(void); + void (APIENTRY *GetIntegerv)(GLenum pname, GLint *params); + void (APIENTRY *LoadIdentity)(void); + void (APIENTRY *MatrixMode)(GLenum mode); + void (APIENTRY *Ortho)(GLdouble left, GLdouble right, GLdouble bottom, + GLdouble top, GLdouble zNear, GLdouble zFar); + void (APIENTRY *PixelStorei)(GLenum pname, GLint param); + void (APIENTRY *ReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, GLvoid *pixels); + void (APIENTRY *TexCoord2f)(GLfloat s, GLfloat t); + void (APIENTRY *TexImage2D)(GLenum target, GLint level, GLint internalformat, + GLsizei width, GLsizei height, GLint border, + GLenum format, GLenum type, const GLvoid *pixels); + void (APIENTRY *TexParameteri)(GLenum target, GLenum pname, GLint param); + void (APIENTRY *TexSubImage2D)(GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + GLenum format, GLenum type, const GLvoid *pixels); + void (APIENTRY *Translatef)(GLfloat x, GLfloat y, GLfloat z); + void (APIENTRY *Vertex2i)(GLint x, GLint y); + void (APIENTRY *Viewport)(GLint x, GLint y, GLsizei width, GLsizei height); + void (APIENTRY *Rotated)(GLdouble, GLdouble, GLdouble, GLdouble); + void (APIENTRY *Scalef)(GLfloat, GLfloat, GLfloat); + void (APIENTRY *PushMatrix)(void); + void (APIENTRY *PopMatrix)(void); +} gl; + + +static int GetGL(void) +{ + int i; + struct + { + const char *name; + void **fn; + } glfuncs[] = { + {"glBegin", (void *)&gl.Begin }, + {"glBindTexture", (void *)&gl.BindTexture }, + {"glBlendFunc", (void *)&gl.BlendFunc }, + {"glColor4ub", (void *)&gl.Color4ub }, + {"glDeleteTextures", (void *)&gl.DeleteTextures }, + {"glDisable", (void *)&gl.Disable }, + {"glEnable", (void *)&gl.Enable }, + {"glEnd", (void *)&gl.End }, + {"glFlush", (void *)&gl.Flush }, + {"glGenTextures", (void *)&gl.GenTextures }, + {"glGetError", (void *)&gl.GetError }, + {"glGetIntegerv", (void *)&gl.GetIntegerv }, + {"glLoadIdentity", (void *)&gl.LoadIdentity }, + {"glMatrixMode", (void *)&gl.MatrixMode }, + {"glOrtho", (void *)&gl.Ortho }, + {"glPixelStorei", (void *)&gl.PixelStorei }, + {"glReadPixels", (void *)&gl.ReadPixels }, + {"glTexCoord2f", (void *)&gl.TexCoord2f }, + {"glTexImage2D", (void *)&gl.TexImage2D }, + {"glTexParameteri", (void *)&gl.TexParameteri }, + {"glTexSubImage2D", (void *)&gl.TexSubImage2D }, + {"glTranslatef", (void *)&gl.Translatef }, + {"glVertex2i", (void *)&gl.Vertex2i }, + {"glViewport", (void *)&gl.Viewport }, + {"glRotated", (void *)&gl.Rotated }, + {"glScalef", (void *)&gl.Scalef }, + {"glPushMatrix", (void *)&gl.PushMatrix }, + {"glPopMatrix", (void *)&gl.PopMatrix }, + {NULL, NULL } + }; + for(i = 0; glfuncs[i].name; ++i) + { + *glfuncs[i].fn = SDL_GL_GetProcAddress(glfuncs[i].name); + if(!*glfuncs[i].fn) + { + DBG6(fprintf(stderr,"glSDL/wrapper ERROR: Could not get " + "OpenGL function '%s'!\n", + glfuncs[i].name);) + return -1; + } + DBG6(printf("Got OpenGL function '%s'.\n", glfuncs[i].name);) + } + return 0; +} + + +static int LoadGL(void) +{ + if(GetGL() < 0) + { + DBG6(printf("Couldn't get GL funcs! Trying to load lib...\n");) + SDL_GL_LoadLibrary(NULL); + if(GetGL() < 0) + { + DBG6(printf("Still couldn't get GL funcs!\n");) + return -1; + } + } + return 0; +} + + +static void UnloadGL(void) +{ +} + + +static void print_glerror(int point) +{ +#if (DBG(1)+0 == 1) + const char *err = ""; + switch(gl.GetError()) + { + case GL_NO_ERROR: + return; + case GL_INVALID_ENUM: + err = "GL_INVALID_ENUM"; + break; + case GL_INVALID_VALUE: + err = "GL_INVALID_VALUE"; + break; + case GL_INVALID_OPERATION: + err = "GL_INVALID_OPERATION"; + break; + case GL_STACK_OVERFLOW: + err = "GL_STACK_OVERFLOW"; + break; + case GL_STACK_UNDERFLOW: + err = "GL_STACK_UNDERFLOW"; + break; + case GL_OUT_OF_MEMORY: + err = "GL_OUT_OF_MEMORY"; + break; + default: + err = ""; + break; + } + fprintf(stderr,"OpenGL error \"%s\" at point %d.\n", err, point); +#endif +} + + +/*---------------------------------------------------------- + OpenGL state wrapper +----------------------------------------------------------*/ + +static struct +{ + int do_blend; + int do_texture; + GLint texture; + GLenum sfactor, dfactor; +} glstate; + +static void gl_reset(void) +{ + glstate.do_blend = -1; + glstate.do_blend = -1; + glstate.texture = -1; + glstate.sfactor = 0xffffffff; + glstate.dfactor = 0xffffffff; +} + +static __inline__ void gl_do_blend(int on) +{ + if(glstate.do_blend == on) + return; + + if(on) + gl.Enable(GL_BLEND); + else + gl.Disable(GL_BLEND); + glstate.do_blend = on; +} + +static __inline__ void gl_do_texture(int on) +{ + if(glstate.do_texture == on) + return; + + if(on) + gl.Enable(GL_TEXTURE_2D); + else + gl.Disable(GL_TEXTURE_2D); + glstate.do_texture = on; +} + +static __inline__ void gl_blendfunc(GLenum sfactor, GLenum dfactor) +{ + if((sfactor == glstate.sfactor) && (dfactor == glstate.dfactor)) + return; + + gl.BlendFunc(sfactor, dfactor); + + glstate.sfactor = sfactor; + glstate.dfactor = dfactor; +} + +static __inline__ void gl_texture(GLuint tx) +{ + if(tx == (unsigned)glstate.texture) + return; + + gl.BindTexture(GL_TEXTURE_2D, tx); + glstate.texture = tx; +} + + +/*---------------------------------------------------------- + Global stuff +----------------------------------------------------------*/ + +static int initialized = 0; + +static int using_glsdl = 0; +#define USING_GLSDL (0 != using_glsdl) + +#define MAX_TEXINFOS 16384 + +static glSDL_TexInfo **texinfotab = NULL; +static GLint maxtexsize = 256; +static SDL_PixelFormat RGBfmt, RGBAfmt; + +static void UnloadTexture(glSDL_TexInfo *txi); + +static int scale = 1; +static int vsync = 1; + +static SDL_Surface *fake_screen = NULL; + + +static int glSDL_BlitGL(SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect); + + +/*---------------------------------------------------------- + glSDL Global State +----------------------------------------------------------*/ + +static struct +{ + Uint8 alpha; /* Alpha */ + Uint8 r, g, b; /* Color modulation */ + float cx, cy; /* Transform center offset */ + float sx, sy; /* Scale */ + float rot; /* Rotation */ +} state; + + +void glSDL_SetBlendAlpha(Uint8 alpha) +{ + state.alpha = alpha; +} + + +void glSDL_SetBlendColor(Uint8 r, Uint8 g, Uint8 b) +{ + state.r = r; + state.g = g; + state.b = b; +} + + +void glSDL_SetCenter(float x, float y) +{ + state.cx = x; + state.cy = y; +} + + +void glSDL_SetRotation(float angle) +{ + state.rot = angle; +} + + +void glSDL_SetScale(float x, float y) +{ + state.sx = x; + state.sy = y; +} + + +void glSDL_ResetState(void) +{ + glSDL_SetBlendAlpha(255); + glSDL_SetBlendColor(255, 255, 255); + glSDL_SetCenter(0.0f, 0.0f); + glSDL_SetRotation(0.0f); + glSDL_SetScale(1.0f, 1.0f); +} + + +/*---------------------------------------------------------- + Code +----------------------------------------------------------*/ + +/* Get texinfo for a surface. */ +static __inline__ glSDL_TexInfo *glSDL_GetTexInfo(SDL_Surface *surface) +{ + if(texinfotab) + return texinfotab[surface->unused1]; + else + return NULL; +} + + +/* Allocate a "blank" texinfo for a suface. */ +glSDL_TexInfo *glSDL_AllocTexInfo(SDL_Surface *surface) +{ + int handle, i = 0; + glSDL_TexInfo *txi; + if(!surface) + return NULL; + + txi = glSDL_GetTexInfo(surface); + if(txi) + return txi; /* There already is one! --> */ + + /* Find a free handle... */ + handle = -1; + for(i = 1; i < MAX_TEXINFOS + 1; ++i) + if(NULL == texinfotab[i]) + { + handle = i; + break; + } + + if(handle < 0) + { + DBG(fprintf(stderr, "glSDL/wrapper: Out of handles!\n")); + return NULL; + } + + /* ...and hook a new texinfo struct up to it. */ + texinfotab[handle] = (glSDL_TexInfo*)calloc(1, sizeof(glSDL_TexInfo)); + if(!texinfotab[handle]) + return NULL; + + /* Connect the surface to the new TexInfo. */ + surface->unused1 = (Uint32)handle; + + DBG2(fprintf(stderr, "glSDL/wrapper: Allocated TexInfo %d.\n", handle)); + + return texinfotab[handle]; +} + + +static void FreeTexInfo(Uint32 handle) +{ + if(handle >= MAX_TEXINFOS) + return; + if(!texinfotab[handle]) + return; + + UnloadTexture(texinfotab[handle]); + texinfotab[handle]->textures = 0; + free(texinfotab[handle]->texture); + texinfotab[handle]->texture = NULL; + free(texinfotab[handle]); + texinfotab[handle] = NULL; + DBG2(fprintf(stderr, "glSDL/wrapper: Freed TexInfo %d.\n", handle)); +} + + +/* Detach and free the texinfo of a surface. */ +void glSDL_FreeTexInfo(SDL_Surface *surface) +{ + if(!texinfotab) + return; + + if(!surface) + return; + + if(!glSDL_GetTexInfo(surface)) + return; + + FreeTexInfo(surface->unused1); + GLSDL_FIX_SURFACE(surface); +} + + +/* + * Calculate chopping/tiling of a surface to + * fit it into the smallest possible OpenGL + * texture. + */ +static int CalcChop(SDL_Surface *s, glSDL_TexInfo *txi) +{ + int rows, vw, vh; + int vertical = 0; + int texsize; + int lastw, lasth, minsize; + + vw = s->w; + vh = s->h; + + DBG3(fprintf(stderr, "w=%d, h=%d ", vw, vh)); + if(vh > vw) + { + int t = vw; + vw = vh; + vh = t; + vertical = 1; + DBG3(fprintf(stderr, "(vertical) \t")); + } + + /* + * Check whether this is a "huge" surface - at least one dimension + * must be <= than the maximum texture size, or we'll have to chop + * in both directions. + */ + if(vh > maxtexsize) + { + /* + * Very simple hack for now; we just tile + * both ways with maximum size textures. + */ + texsize = maxtexsize; + + txi->tilemode = GLSDL_TM_HUGE; + txi->texsize = texsize; + txi->tilew = texsize; + txi->tileh = texsize; + txi->tilespertex = 1; + + /* Calculate number of textures needed */ + txi->textures = (vw + texsize - 1) / texsize; + txi->textures *= (vh + texsize - 1) / texsize; + txi->texture = (int*)malloc(txi->textures * sizeof(int)); + memset(txi->texture, -1, txi->textures * sizeof(int)); + DBG5(fprintf(stderr, "two-way tiling; textures=%d\n", txi->textures)); + if(!txi->texture) + { + fprintf(stderr, "glSDL/wrapper: INTERNAL ERROR: Failed to allocate" + " texture name table!\n"); + return -3; + } + return 0; + } + + /* Calculate minimum size */ + rows = 1; + lastw = vw; + lasth = vh; + minsize = lastw > lasth ? lastw : lasth; + while(1) + { + int w, h, size; + ++rows; + w = vw / rows; + h = rows * vh; + size = w > h ? w : h; + if(size >= minsize) + { + --rows; + break; + } + lastw = w; + lasth = h; + minsize = size; + } + if(minsize > maxtexsize) + { + /* Handle multiple textures for very wide/tall surfaces. */ + minsize = maxtexsize; + rows = (vw + minsize-1) / minsize; + } + DBG3(fprintf(stderr, "==> minsize=%d ", minsize)); + DBG3(fprintf(stderr, "(rows=%d) \t", rows)); + + /* Recalculate with nearest higher power-of-2 width. */ + for(texsize = 1; texsize < minsize; texsize <<= 1) + ; + txi->texsize = texsize; + rows = (vw + texsize-1) / texsize; + DBG3(fprintf(stderr, "==> texsize=%d (rows=%d) \t", texsize, rows)); + + /* Calculate number of tiles per texture */ + txi->tilespertex = txi->texsize / vh; + DBG3(fprintf(stderr, "tilespertex=%d \t", txi->tilespertex)); + + /* Calculate number of textures needed */ + txi->textures = (rows + txi->tilespertex-1) / txi->tilespertex; + txi->texture = (int*)malloc(txi->textures * sizeof(int)); + memset(txi->texture, -1, txi->textures * sizeof(int)); + DBG3(fprintf(stderr, "textures=%d, ", txi->textures)); + if(!txi->texture) + { + fprintf(stderr, "glSDL/wrapper: INTERNAL ERROR: Failed to allocate" + " texture name table!\n"); + return -2; + } + + /* Set up tile size. (Only one axis supported here!) */ + if(1 == rows) + { + txi->tilemode = GLSDL_TM_SINGLE; + if(vertical) + { + txi->tilew = vh; + txi->tileh = vw; + } + else + { + txi->tilew = vw; + txi->tileh = vh; + } + } + else if(vertical) + { + txi->tilemode = GLSDL_TM_VERTICAL; + txi->tilew = vh; + txi->tileh = texsize; + } + else + { + txi->tilemode = GLSDL_TM_HORIZONTAL; + txi->tilew = texsize; + txi->tileh = vh; + } + + DBG3(fprintf(stderr, "tilew=%d, tileh=%d\n", txi->tilew, txi->tileh)); + return 0; +} + + +/* Add a glSDL_TexInfo struct to an SDL_Surface */ +static int glSDL_AddTexInfo(SDL_Surface *surface) +{ + glSDL_TexInfo *txi; + + if(!surface) + return -1; + if(IS_GLSDL_SURFACE(surface)) + return 0; /* Do nothing */ + + glSDL_AllocTexInfo(surface); + txi = glSDL_GetTexInfo(surface); + if(!txi) + return -2; /* Oops! Didn't get a texinfo... --> */ + + if(CalcChop(surface, txi) < 0) + return -3; + + SDL_SetClipRect(surface, NULL); + + return 0; +} + + +/* Create a surface of the prefered OpenGL RGB texture format */ +static SDL_Surface *CreateRGBSurface(int w, int h) +{ + SDL_Surface *s; + Uint32 rmask, gmask, bmask; + int bits = 24; +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + rmask = 0x00ff0000; + gmask = 0x0000ff00; + bmask = 0x000000ff; +#else + rmask = 0x000000ff; + gmask = 0x0000ff00; + bmask = 0x00ff0000; +#endif + s = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, + bits, rmask, gmask, bmask, 0); + if(s) + GLSDL_FIX_SURFACE(s); + + glSDL_AddTexInfo(s); + return s; +} + + +/* Create a surface of the prefered OpenGL RGBA texture format */ +static SDL_Surface *CreateRGBASurface(int w, int h) +{ + SDL_Surface *s; + Uint32 rmask, gmask, bmask, amask; + int bits = 32; +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + rmask = 0xff000000; + gmask = 0x00ff0000; + bmask = 0x0000ff00; + amask = 0x000000ff; +#else + rmask = 0x000000ff; + gmask = 0x0000ff00; + bmask = 0x00ff0000; + amask = 0xff000000; +#endif + s = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, + bits, rmask, gmask, bmask, amask); + if(s) + GLSDL_FIX_SURFACE(s); + + glSDL_AddTexInfo(s); + return s; +} + + +static void init_formats(void) +{ + SDL_Surface *s = CreateRGBSurface(1, 1); + if(!s) + return; + RGBfmt = *(s->format); + glSDL_FreeSurface(s); + + s = CreateRGBASurface(1, 1); + if(!s) + return; + RGBAfmt = *(s->format); + glSDL_FreeSurface(s); +} + + +static int FormatIsOk(SDL_Surface *surface) +{ + SDL_PixelFormat *pf; + if(!surface) + return 1; /* Well, there ain't much we can do anyway... */ + + pf = surface->format; + + /* Colorkeying always requires conversion! */ + if(surface->flags & SDL_SRCCOLORKEY) + return 0; + + /* We need pitch == (width * BytesPerPixel) for glTex[Sub]Image2D() */ + if(surface->pitch != (surface->w * pf->BytesPerPixel)) + return 0; + + if(pf->Amask) + { + if(pf->BytesPerPixel != RGBAfmt.BytesPerPixel) + return 0; + if(pf->Rmask != RGBAfmt.Rmask) + return 0; + if(pf->Gmask != RGBAfmt.Gmask) + return 0; + if(pf->Bmask != RGBAfmt.Bmask) + return 0; + if(pf->Amask != RGBAfmt.Amask) + return 0; + } + else + { + if(pf->BytesPerPixel != RGBfmt.BytesPerPixel) + return 0; + if(pf->Rmask != RGBfmt.Rmask) + return 0; + if(pf->Gmask != RGBfmt.Gmask) + return 0; + if(pf->Bmask != RGBfmt.Bmask) + return 0; + } + return 1; +} + + + +static void key2alpha(SDL_Surface *surface) +{ + int x, y; +#ifdef CKSTATS + int transp = 0; +#endif + Uint32 rgbmask = surface->format->Rmask | + surface->format->Gmask | + surface->format->Bmask; + Uint32 ckey = surface->format->colorkey & rgbmask; + if(SDL_LockSurface(surface) < 0) + return; + + for(y = 0; y < surface->h; ++y) + { + Uint32 *px = (Uint32 *)((char *)surface->pixels + y*surface->pitch); + for(x = 0; x < surface->w; ++x) + if((px[x] & rgbmask) == ckey) + { + px[x] = 0; +#ifdef CKSTATS + ++transp; +#endif + } + } +#ifdef CKSTATS + printf("glSDL/wrapper: key2alpha(); %dx%d surface, %d opaque pixels.\n", + surface->w, surface->h, + surface->w * surface->h - transp); +#endif + SDL_UnlockSurface(surface); +} + + + +/*---------------------------------------------------------- + SDL style API +----------------------------------------------------------*/ + +static void KillAllTextures(void) +{ + if(texinfotab) + { + unsigned i; +#ifdef LEAK_TRACKING + int leaked = 0; + for(i = 3; i < MAX_TEXINFOS + 1; ++i) + if(texinfotab[i]) + { + ++leaked; + fprintf(stderr, "glSDL/wrapper: Leaked TexInfo" + " %d! (%d %dx%d textures)\n", + i, + texinfotab[i]->textures, + texinfotab[i]->texsize, + texinfotab[i]->texsize + ); + } + if(leaked) + fprintf(stderr, "glSDL/wrapper: Leaked %d TexInfos!\n", leaked); +#endif + for(i = 1; i < MAX_TEXINFOS + 1; ++i) + FreeTexInfo(i); + free(texinfotab); + texinfotab = NULL; + } +} + +void glSDL_Quit(void) +{ + if(SDL_WasInit(SDL_INIT_VIDEO)) + { + glSDL_FreeTexInfo(SDL_GetVideoSurface()); + if(fake_screen) + { + glSDL_FreeTexInfo(fake_screen); + SDL_FreeSurface(fake_screen); + fake_screen = NULL; + } + UnloadGL(); + SDL_QuitSubSystem(SDL_INIT_VIDEO); + } +#ifndef LEAK_TRACKING + KillAllTextures(); +#endif +} + + +void glSDL_FullQuit(void) +{ +#ifdef LEAK_TRACKING + KillAllTextures(); +#endif + glSDL_Quit(); + SDL_Quit(); +} + + +void glSDL_QuitSubSystem(Uint32 flags) +{ + if(flags & SDL_INIT_VIDEO) + glSDL_Quit(); + SDL_QuitSubSystem(flags); +} + + +SDL_Surface *glSDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) +{ + SDL_Surface *screen; + GLint gl_doublebuf; + + if(!initialized) + { + glSDL_ResetState(); + initialized = 1; + } + + if(USING_GLSDL) + { + glSDL_FreeTexInfo(SDL_GetVideoSurface()); + if(fake_screen) + { + glSDL_FreeTexInfo(fake_screen); + SDL_FreeSurface(fake_screen); + fake_screen = NULL; + } + UnloadGL(); + using_glsdl = 0; + } + + if(!(flags & SDL_GLSDL)) + { + screen = SDL_SetVideoMode(width, height, bpp, flags); + if(screen) + GLSDL_FIX_SURFACE(screen); + return screen; + } + + if((SDL_Linked_Version()->major <= 1) && + (SDL_Linked_Version()->minor <= 2) && + (SDL_Linked_Version()->patch < 5)) + fprintf(stderr, "glSDL/wrapper WARNING: Using SDL version" + " 1.2.5 or later is strongly" + " recommended!\n"); + + if(LoadGL() < 0) + { + fprintf(stderr, "glSDL/wrapper ERROR: Could not load OpenGL library!\n"); + return NULL; + } + +/* + * FIXME: Here's the place to insert proper handling of this call being + * used for resizing the window... For now, just make sure we + * don't end up with invalid texinfos and stuff no matter what. + */ + KillAllTextures(); + + texinfotab = (glSDL_TexInfo**)calloc(MAX_TEXINFOS + 1, sizeof(glSDL_TexInfo *)); + if(!texinfotab) + return NULL; + + /* Remove flag to avoid confusion inside SDL - just in case! */ + flags &= ~SDL_GLSDL; + + flags |= SDL_OPENGL; + if(bpp == 15) + { + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); + } + else if(bpp == 16) + { + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); + } + else if(bpp >= 24) + { + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); + } + gl_doublebuf = (flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF; + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, gl_doublebuf); + SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, vsync); + scale = 1; + + screen = SDL_SetVideoMode(width*scale, height*scale, bpp, flags); + if(!screen) + { + KillAllTextures(); + return NULL; + } + + GLSDL_FIX_SURFACE(screen); + +#ifdef FAKE_MAXTEXSIZE + maxtexsize = FAKE_MAXTEXSIZE; +#else + gl.GetIntegerv(GL_MAX_TEXTURE_SIZE, &maxtexsize); +#endif + DBG(fprintf(stderr, "glSDL/wrapper: Max texture size: %d\n", maxtexsize)); + + init_formats(); + gl_reset(); + + if(glSDL_AddTexInfo(screen) < 0) + { + DBG(fprintf(stderr, "glSDL/wrapper: Failed to add info to screen surface!\n")); + SDL_QuitSubSystem(SDL_INIT_VIDEO); + return NULL; + } + + glSDL_SetClipRect(screen, &screen->clip_rect); + + gl.Viewport(0, 0, screen->w * scale, screen->h * scale); + /* + * Note that this projection is upside down in + * relation to the OpenGL coordinate system. + */ + gl.MatrixMode(GL_PROJECTION); + gl.LoadIdentity(); + gl.Ortho(0, scale * (float)screen->w, scale * (float)screen->h, 0, + -1.0, 1.0); + + gl.MatrixMode(GL_MODELVIEW); + gl.LoadIdentity(); + gl.Translatef(0.0f, 0.0f, 0.0f); + + gl.Disable(GL_DEPTH_TEST); + gl.Disable(GL_CULL_FACE); + + /* + * Create a software shadow buffer of the requested size. + * This is used for blit-from-screen and simulation of + * direct software rendering. (Dog slow crap. It's only + * legitimate use is probably screen shots.) + */ + fake_screen = CreateRGBSurface(screen->w / scale, + screen->h / scale); + using_glsdl = 1; + return fake_screen; +} + + +SDL_Surface *glSDL_GetVideoSurface(void) +{ + if(fake_screen) + return fake_screen; + else + return SDL_GetVideoSurface(); +} + + +void glSDL_UpdateRects(SDL_Surface *screen, int numrects, SDL_Rect *rects) +{ + if(IS_GLSDL_SURFACE(screen)) + glSDL_Flip(screen); + else + SDL_UpdateRects(screen, numrects, rects); +} + + +void glSDL_UpdateRect(SDL_Surface *screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h) +{ + SDL_Rect r; + r.x = x; + r.y = y; + r.w = w; + r.h = h; + glSDL_UpdateRects(screen, 1, &r); +} + + +int glSDL_Flip(SDL_Surface *screen) +{ + if(!IS_GLSDL_SURFACE(screen)) + return SDL_Flip(screen); + + SDL_GL_SwapBuffers(); + return 0; +} + + +void glSDL_FreeSurface(SDL_Surface *surface) +{ + if(!surface) + return; + glSDL_FreeTexInfo(surface); + SDL_FreeSurface(surface); +} + + +int glSDL_LockSurface(SDL_Surface *surface) +{ + if(!surface) + return 0; + + if(IS_GLSDL_SURFACE(surface)) + { + if((surface == fake_screen) || + (SDL_GetVideoSurface() == surface)) + { + if(scale > 1) + return -1; + + glSDL_Invalidate(fake_screen, NULL); + + gl.PixelStorei(GL_UNPACK_ROW_LENGTH, + fake_screen->pitch / + fake_screen->format->BytesPerPixel); + + gl.ReadPixels(0, 0, fake_screen->w, fake_screen->h, + GL_RGB, GL_UNSIGNED_BYTE, + fake_screen->pixels); + return 0; + } + else + { + glSDL_Invalidate(surface, NULL); + return SDL_LockSurface(surface); + } + } + else + return SDL_LockSurface(surface); +} + + +void glSDL_UnlockSurface(SDL_Surface *surface) +{ + if(!surface) + return; + + if(IS_GLSDL_SURFACE(surface)) + { + glSDL_UploadSurface(surface); + if((surface == fake_screen) || + (SDL_GetVideoSurface() == surface)) + glSDL_BlitGL(fake_screen, NULL, + SDL_GetVideoSurface(), NULL); + } + else + SDL_UnlockSurface(surface); +} + + +int glSDL_SetColorKey(SDL_Surface *surface, Uint32 flag, Uint32 key) +{ + int res = SDL_SetColorKey(surface, flag, key); + if(res < 0) + return res; + /* + * If an application does this *after* SDL_DisplayFormat, + * we're basically screwed, unless we want to do an + * in-place surface conversion hack here. + * + * What we do is just kill the glSDL texinfo... No big + * deal in most cases, as glSDL only converts once anyway, + * *unless* you keep modifying the surface. + */ + if(IS_GLSDL_SURFACE(surface)) + glSDL_FreeTexInfo(surface); + return res; +} + + +int glSDL_SetAlpha(SDL_Surface *surface, Uint32 flag, Uint8 alpha) +{ + /* + * This is just parameters to OpenGL, so the actual + * "work" is done in glSDL_BlitSurface(). + */ + return SDL_SetAlpha(surface, flag, alpha); +} + + +SDL_bool glSDL_SetClipRect(SDL_Surface *surface, SDL_Rect *rect) +{ + SDL_bool res; + SDL_Surface *screen; + SDL_Rect fsr; + if(!surface) + return SDL_FALSE; + + screen = SDL_GetVideoSurface(); + + res = SDL_SetClipRect(surface, rect); + if(!res) + return SDL_FALSE; + + if(!rect) + { + fsr.x = 0; + fsr.y = 0; + fsr.w = screen->w; + fsr.h = screen->h; + rect = &fsr; + } + if(surface == fake_screen) + { + SDL_Rect r; + r.x = rect->x; + r.y = rect->y; + r.w = rect->w; + r.h = rect->h; + surface = screen; + SDL_SetClipRect(surface, rect); + return SDL_TRUE; + } + return res; +} + + +static int glSDL_BlitFromGL(SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect) +{ + int i, sy0, dy0; + SDL_Rect sr, dr; + + if(scale > 1) + return -1; + + /* In case the destination has an OpenGL texture... */ + glSDL_Invalidate(dst, dstrect); + + /* Abuse the fake screen buffer a little. */ + gl.PixelStorei(GL_UNPACK_ROW_LENGTH, fake_screen->pitch / + fake_screen->format->BytesPerPixel); + if(srcrect) + { + sr = *srcrect; + dr.x = dr.y = 0; + dr.w = fake_screen->w; + dr.h = fake_screen->h; + clip_rect(&sr, &dr); + gl.ReadPixels(sr.x, sr.y, sr.w, sr.h, GL_RGB, GL_UNSIGNED_BYTE, + fake_screen->pixels); + } + else + { + sr.x = sr.y = 0; + sr.w = dst->w; + srcrect = &sr; + gl.ReadPixels(0, 0, fake_screen->w, fake_screen->h, + GL_RGB, GL_UNSIGNED_BYTE, fake_screen->pixels); + } + + /* Blit to the actual target! (Vert. flip... Uuurgh!) */ + if(dstrect) + dr = *dstrect; + else + { + dr.x = dr.y = 0; + dstrect = &dr; + } + + i = srcrect->h; + sy0 = srcrect->y; + dy0 = dstrect->y + dstrect->h - 1; + while(i--) + { + sr.y = sy0 + i; + dr.y = dy0 - i; + sr.h = 1; + if(SDL_BlitSurface(fake_screen, &sr, dst, &dr) < 0) + return -1; + } + return 0; +} + + +static __inline__ void BlitGL_single(glSDL_TexInfo *txi, + float sx1, float sy1, SDL_Rect *dst, unsigned char alpha) +{ + float sx2, sy2, texscale; + if(!txi->textures) + return; + if(-1 == txi->texture[0]) + return; + gl_texture(txi->texture[0]); + + texscale = 1.0 / (float)txi->texsize; + sx2 = (sx1 + (float)dst->w) * texscale; + sy2 = (sy1 + (float)dst->h) * texscale; + sx1 *= texscale; + sy1 *= texscale; + + gl.Begin(GL_QUADS); + gl.Color4ub(state.r, state.g, state.b, alpha); + gl.TexCoord2f(sx1, sy1); + gl.Vertex2i(dst->x, dst->y); + gl.TexCoord2f(sx2, sy1); + gl.Vertex2i(dst->x + dst->w, dst->y); + gl.TexCoord2f(sx2, sy2); + gl.Vertex2i(dst->x + dst->w, dst->y + dst->h); + gl.TexCoord2f(sx1, sy2); + gl.Vertex2i(dst->x, dst->y + dst->h); + gl.End(); +} + + +static void BlitGL_htile(glSDL_TexInfo *txi, + float sx1, float sy1, SDL_Rect *dst, unsigned char alpha) +{ + int tex; + float tile, sx2, sy2, yo; + float texscale = 1.0 / (float)txi->texsize; + float tileh = (float)txi->tileh * texscale; + sx2 = (sx1 + (float)dst->w) * texscale; + sy2 = (sy1 + (float)dst->h) * texscale; + sx1 *= texscale; + sy1 *= texscale; + tile = floor(sx1); + tex = (int)tile / txi->tilespertex; + yo = ((int)tile % txi->tilespertex) * tileh; + + if(tex >= txi->textures) + return; + if(-1 == txi->texture[tex]) + return; + gl_texture(txi->texture[tex]); + + gl.Begin(GL_QUADS); + while(tile < sx2) + { + int tdx1 = dst->x; + int tdx2 = dst->x + dst->w; + float tsx1 = sx1 - tile; + float tsx2 = sx2 - tile; + + /* Clip to current tile */ + if(tsx1 < 0.0) + { + tdx1 -= (int)(tsx1 * txi->texsize); + tsx1 = 0.0; + } + if(tsx2 > 1.0) + { + tdx2 -= (int)((tsx2 - 1.0) * txi->texsize); + tsx2 = 1.0; + } + + /* Maybe select next texture? */ + if(yo + tileh > 1.0) + { + ++tex; + gl.End(); + if(tex >= txi->textures) + return; + if(-1 == txi->texture[tex]) + return; + gl_texture(txi->texture[tex]); + yo = 0.0; + gl.Begin(GL_QUADS); + } + + gl.Color4ub(state.r, state.g, state.b, alpha); + gl.TexCoord2f(tsx1, yo + sy1); + gl.Vertex2i(tdx1, dst->y); + gl.TexCoord2f(tsx2, yo + sy1); + gl.Vertex2i(tdx2, dst->y); + gl.TexCoord2f(tsx2, yo + sy2); + gl.Vertex2i(tdx2, dst->y + dst->h); + gl.TexCoord2f(tsx1, yo + sy2); + gl.Vertex2i(tdx1, dst->y + dst->h); + + tile += 1.0; + yo += tileh; + } + gl.End(); +} + + +static void BlitGL_vtile(glSDL_TexInfo *txi, + float sx1, float sy1, SDL_Rect *dst, unsigned char alpha) +{ + int tex; + float tile, sx2, sy2, xo; + float texscale = 1.0 / (float)txi->texsize; + float tilew = (float)txi->tilew * texscale; + sx2 = (sx1 + (float)dst->w) * texscale; + sy2 = (sy1 + (float)dst->h) * texscale; + sx1 *= texscale; + sy1 *= texscale; + tile = floor(sy1); + tex = (int)tile / txi->tilespertex; + xo = ((int)tile % txi->tilespertex) * tilew; + + if(tex >= txi->textures) + return; + if(-1 == txi->texture[tex]) + return; + gl_texture(txi->texture[tex]); + + gl.Begin(GL_QUADS); + while(tile < sy2) + { + int tdy1 = dst->y; + int tdy2 = dst->y + dst->h; + float tsy1 = sy1 - tile; + float tsy2 = sy2 - tile; + + /* Clip to current tile */ + if(tsy1 < 0.0) + { + tdy1 -= (int)(tsy1 * txi->texsize); + tsy1 = 0.0; + } + if(tsy2 > 1.0) + { + tdy2 -= (int)((tsy2 - 1.0) * txi->texsize); + tsy2 = 1.0; + } + + /* Maybe select next texture? */ + if(xo + tilew > 1.0) + { + ++tex; + gl.End(); + if(tex >= txi->textures) + return; + if(-1 == txi->texture[tex]) + return; + gl_texture(txi->texture[tex]); + xo = 0.0; + gl.Begin(GL_QUADS); + } + + gl.Color4ub(state.r, state.g, state.b, alpha); + gl.TexCoord2f(xo + sx1, tsy1); + gl.Vertex2i(dst->x, tdy1); + gl.TexCoord2f(xo + sx2, tsy1); + gl.Vertex2i(dst->x + dst->w, tdy1); + gl.TexCoord2f(xo + sx2, tsy2); + gl.Vertex2i(dst->x + dst->w, tdy2); + gl.TexCoord2f(xo + sx1, tsy2); + gl.Vertex2i(dst->x, tdy2); + + tile += 1.0; + xo += tilew; + } + gl.End(); +} + + +static void BlitGL_hvtile(SDL_Surface *src, glSDL_TexInfo *txi, + float sx1, float sy1, SDL_Rect *dst, unsigned char alpha) +{ + int x, y, last_tex, tex; + float sx2, sy2; + float texscale = 1.0 / (float)txi->texsize; + int tilesperrow = (src->w + txi->tilew - 1) / txi->tilew; + sx2 = (sx1 + (float)dst->w) * texscale; + sy2 = (sy1 + (float)dst->h) * texscale; + sx1 *= texscale; + sy1 *= texscale; + + last_tex = tex = (int)(floor(sy1) * tilesperrow + floor(sx1)); + if(tex >= txi->textures) + return; + if(-1 == txi->texture[tex]) + return; + gl_texture(txi->texture[tex]); + + gl.Begin(GL_QUADS); + for(y = (int)floor(sy1); y < sy2; ++y) + { + int tdy1 = dst->y; + int tdy2 = dst->y + dst->h; + float tsy1 = sy1 - y; + float tsy2 = sy2 - y; + + /* Clip to current tile */ + if(tsy1 < 0.0) + { + tdy1 -= (int)(tsy1 * txi->texsize); + tsy1 = 0.0; + } + if(tsy2 > 1.0) + { + tdy2 -= (int)((tsy2 - 1.0) * txi->texsize); + tsy2 = 1.0; + } + for(x = (int)floor(sx1); x < sx2; ++x) + { + int tdx1 = dst->x; + int tdx2 = dst->x + dst->w; + float tsx1 = sx1 - x; + float tsx2 = sx2 - x; + + /* Clip to current tile */ + if(tsx1 < 0.0) + { + tdx1 -= (int)(tsx1 * txi->texsize); + tsx1 = 0.0; + } + if(tsx2 > 1.0) + { + tdx2 -= (int)((tsx2 - 1.0) * txi->texsize); + tsx2 = 1.0; + } + + /* Select texture */ + tex = y * tilesperrow + x; + if(tex != last_tex) + { + gl.End(); + if(tex >= txi->textures) + return; + if(-1 == txi->texture[tex]) + return; + gl_texture(txi->texture[tex]); + last_tex = tex; + gl.Begin(GL_QUADS); + } + + gl.Color4ub(state.r, state.g, state.b, alpha); + gl.TexCoord2f(tsx1, tsy1); + gl.Vertex2i(tdx1, tdy1); + gl.TexCoord2f(tsx2, tsy1); + gl.Vertex2i(tdx2, tdy1); + gl.TexCoord2f(tsx2, tsy2); + gl.Vertex2i(tdx2, tdy2); + gl.TexCoord2f(tsx1, tsy2); + gl.Vertex2i(tdx1, tdy2); + } + } + gl.End(); +} + + +/* + * Calculate the actual blit rectangle and source offset + * for a blit from a rectangle in a surface with specified + * size to a surface with a cliprect. + * + * In: rect source rectangle + * w, h source surface size + * (x, y) destination coordinate + * clip destination clip rectangle + * + * Out: (x, y) source top-left offset + * rect destination rectangle + * + * Returns 1 if the result is visible, otherwise 0. + */ +static __inline__ int blitclip(SDL_Rect *rect, int w, int h, + int *x, int *y, SDL_Rect *clip) +{ + int sx1, sy1, sx2, sy2; + int dx1, dy1, dx2, dy2; + + /* Get source and destination coordinates */ + sx1 = rect->x; + sy1 = rect->y; + sx2 = sx1 + rect->w; + sy2 = sy1 + rect->h; + dx1 = *x; + dy1 = *y; + + /* Keep source rect inside source surface */ + if(sx1 < 0) + { + dx1 -= sx1; + sx1 = 0; + } + if(sy1 < 0) + { + dy1 -= sy1; + sy1 = 0; + } + if(sx2 > w) + sx2 = w; + if(sy2 > h) + sy2 = h; + + /* Cull blits from void space */ + if(sx1 >= sx2 || sy1 >= sy2) + return 0; + + /* Calculate destination lower-right */ + dx2 = dx1 + (sx2 - sx1); + dy2 = dy1 + (sy2 - sy1); + + if(clip) + { + /* Clip to destination cliprect */ + if(dx1 < clip->x) + { + sx1 += clip->x - dx1; + dx1 = clip->x; + } + if(dy1 < clip->y) + { + sy1 += clip->y - dy1; + dy1 = clip->y; + } + if(dx2 > clip->x + clip->w) + dx2 = clip->x + clip->w; + if(dy2 > clip->y + clip->h) + dy2 = clip->y + clip->h; + } + + /* Cull nop/off-screen blits */ + if(dx1 >= dx2 || dy1 >= dy2) + return 0; + + *x = sx1; + *y = sy1; + rect->x = dx1; + rect->y = dy1; + rect->w = dx2 - dx1; + rect->h = dy2 - dy1; + return 1; +} + + +static int glSDL_BlitGL(SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect) +{ + glSDL_TexInfo *txi; + SDL_Rect r; + int x, y; + unsigned char alpha; + int plain = (state.rot == 0.0f) && + (state.sx == 1.0f) && + (state.sy == 1.0f); + if(!src || !dst) + return -1; + + /* Get source and destination coordinates */ + if(srcrect) + r = *srcrect; + else + { + r.x = r.y = 0; + r.w = src->w; + r.h = src->h; + } + if(dstrect) + { + x = dstrect->x; + y = dstrect->y; + } + else + x = y = 0; + + /* Clip! */ + if(!blitclip(&r, src->w, src->h, &x, &y, + plain ? &dst->clip_rect : NULL)) + { + if(dstrect) + dstrect->w = dstrect->h = 0; + return 0; + } + + /* Write back the resulting cliprect */ + if(dstrect) + *dstrect = r; + + /* Make sure we have a source with a valid texture */ + glSDL_UploadSurface(src); + txi = glSDL_GetTexInfo(src); + if(!txi) + return -1; + + /* Set up blending */ + if(src->flags & (SDL_SRCALPHA | SDL_SRCCOLORKEY) || + (state.alpha != 255)) + { + gl_blendfunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gl_do_blend(1); + } + else + gl_do_blend(0); + + /* Enable texturing */ + gl_do_texture(1); + + /* + * Note that we actually *prevent* the use of "full surface alpha" + * and alpha channel in combination - to stay SDL 2D compatible. + */ + if((src->flags & SDL_SRCALPHA) && + (!src->format->Amask || (src->flags & SDL_SRCCOLORKEY))) + alpha = src->format->alpha; + else + alpha = 255; + + /* ...however, the GL only global state alpha is always applied! */ + alpha = (Uint32)alpha * state.alpha * 258 >> 16; + + /* Render! */ + if(!plain) + { + int rcx = (r.w >> 1) + state.cx; + int rcy = (r.h >> 1) + state.cy; + gl.PushMatrix(); + gl.Translatef(r.x + rcx, r.y + rcy, 0.0f); + if(state.rot) + gl.Rotated(state.rot, 0.0f, 0.0f, 1.0f); + if(state.sx || state.sy) + gl.Scalef(state.sx, state.sy, 1.0f); + r.x = -rcx; + r.y = -rcy; + } + switch(txi->tilemode) + { + case GLSDL_TM_SINGLE: + BlitGL_single(txi, x, y, &r, alpha); + break; + case GLSDL_TM_HORIZONTAL: + BlitGL_htile(txi, x, y, &r, alpha); + break; + case GLSDL_TM_VERTICAL: + BlitGL_vtile(txi, x, y, &r, alpha); + break; + case GLSDL_TM_HUGE: + BlitGL_hvtile(src, txi, x, y, &r, alpha); + break; + } + if(!plain) + gl.PopMatrix(); + return 0; +} + + +int glSDL_BlitSurface(SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect) +{ + SDL_Surface *vs; + if(!src || !dst) + return -1; + + /* + * Figure out what to do: + * Not using glSDL: SDL_BlitSurface() + * screen->screen: _glSDL_BlitFromGL() + _glSDL_BlitGL() + * surface->screen: _glSDL_BlitGL() + * screen->surface: _glSDL_BlitFromGL() + * surface->surface: SDL_BlitSurface() + */ + if(!USING_GLSDL) + return SDL_BlitSurface(src, srcrect, dst, dstrect); + + vs = SDL_GetVideoSurface(); + if(src == fake_screen) + src = vs; + if(dst == fake_screen) + dst = vs; + if(src == vs) + { + if(dst == vs) + { + glSDL_BlitFromGL(srcrect, fake_screen, dstrect); + return glSDL_BlitGL(fake_screen, srcrect, + dst, dstrect); + } + else + { + return glSDL_BlitFromGL(srcrect, dst, dstrect); + } + } + else + { + if(dst == vs) + { + return glSDL_BlitGL(src, srcrect, + dst, dstrect); + } + else + { + glSDL_Invalidate(dst, dstrect); + return SDL_BlitSurface(src, srcrect, dst, dstrect); + } + } +} + + +int glSDL_FillRect(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color) +{ + SDL_Surface *vs = SDL_GetVideoSurface(); + SDL_PixelFormat *pf = dst->format; + int dx1, dy1, dx2, dy2; + Uint32 r, g, b; + + if(dst == fake_screen) + dst = vs; + if(vs != dst) + glSDL_Invalidate(dst, dstrect); + if((vs != dst) || !USING_GLSDL) + return SDL_FillRect(dst, dstrect, color); + + if(dstrect) + { + dx1 = dstrect->x; + dy1 = dstrect->y; + dx2 = dx1 + dstrect->w; + dy2 = dy1 + dstrect->h; + if(dx1 < dst->clip_rect.x) + dx1 = dst->clip_rect.x; + if(dy1 < dst->clip_rect.y) + dy1 = dst->clip_rect.y; + if(dx2 > dst->clip_rect.x + dst->clip_rect.w) + dx2 = dst->clip_rect.x + dst->clip_rect.w; + if(dy2 > dst->clip_rect.y + dst->clip_rect.h) + dy2 = dst->clip_rect.y + dst->clip_rect.h; + dstrect->x = dx1; + dstrect->y = dy1; + dstrect->w = dx2 - dx1; + dstrect->h = dy2 - dy1; + if(!dstrect->w || !dstrect->h) + return 0; + } + else + { + dx1 = dst->clip_rect.x; + dy1 = dst->clip_rect.y; + dx2 = dx1 + dst->clip_rect.w; + dy2 = dy1 + dst->clip_rect.h; + } + + r = color & pf->Rmask; + r = r >> pf->Rshift; + r = r << pf->Rloss; + g = color & pf->Gmask; + g = g >> pf->Gshift; + g = g << pf->Gloss; + b = color & pf->Bmask; + b = b >> pf->Bshift; + b = b << pf->Bloss; + + r = r * state.r * 258 >> 16; + g = g * state.g * 258 >> 16; + b = b * state.b * 258 >> 16; + + gl_do_texture(0); + if(state.alpha != 255) + { + gl_blendfunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gl_do_blend(1); + } + else + gl_do_blend(0); + + gl.Begin(GL_QUADS); + gl.Color4ub(r, g, b, state.alpha); + gl.Vertex2i(dx1, dy1); + gl.Vertex2i(dx2, dy1); + gl.Vertex2i(dx2, dy2); + gl.Vertex2i(dx1, dy2); + gl.End(); + return 0; +} + + +SDL_Surface *glSDL_DisplayFormat(SDL_Surface *surface) +{ + SDL_Surface *s, *tmp; + if(USING_GLSDL) + { + int use_rgba = (surface->flags & SDL_SRCCOLORKEY) || + ((surface->flags & SDL_SRCALPHA) && + surface->format->Amask); + if(use_rgba) + tmp = SDL_ConvertSurface(surface, &RGBAfmt, SDL_SWSURFACE); + else + tmp = SDL_ConvertSurface(surface, &RGBfmt, SDL_SWSURFACE); + if(!tmp) + return NULL; + GLSDL_FIX_SURFACE(tmp); + SDL_SetAlpha(tmp, 0, 0); + + if(surface->flags & SDL_SRCCOLORKEY) + { + /* + * We drop colorkey data here, but we have to, + * or we'll run into trouble when converting, + * in particular from indexed color formats. + */ + SDL_SetColorKey(tmp, SDL_SRCCOLORKEY, + surface->format->colorkey); + key2alpha(tmp); + } + SDL_SetColorKey(tmp, 0, 0); + + if(use_rgba) + s = CreateRGBASurface(surface->w, surface->h); + else + s = CreateRGBSurface(surface->w, surface->h); + if(!s) + { + glSDL_FreeSurface(tmp); + return NULL; + } + SDL_BlitSurface(tmp, NULL, s, NULL); + glSDL_FreeSurface(tmp); + + if(surface->flags & SDL_SRCALPHA) + SDL_SetAlpha(s, SDL_SRCALPHA, + surface->format->alpha); + return s; + } + else + { + s = SDL_DisplayFormat(surface); + if(s) + GLSDL_FIX_SURFACE(s); + return s; + } +} + + +SDL_Surface *glSDL_DisplayFormatAlpha(SDL_Surface *surface) +{ + SDL_Surface *s, *tmp; + if(USING_GLSDL) + { + tmp = SDL_ConvertSurface(surface, &RGBAfmt, SDL_SWSURFACE); + if(!tmp) + return NULL; + GLSDL_FIX_SURFACE(tmp); + + SDL_SetAlpha(tmp, 0, 0); + SDL_SetColorKey(tmp, 0, 0); + s = CreateRGBASurface(surface->w, surface->h); + if(!s) + { + glSDL_FreeSurface(tmp); + return NULL; + } + SDL_BlitSurface(tmp, NULL, s, NULL); + glSDL_FreeSurface(tmp); + + if(surface->flags & SDL_SRCCOLORKEY) + { + SDL_SetColorKey(s, SDL_SRCCOLORKEY, + surface->format->colorkey); + key2alpha(s); + } + if(surface->flags & SDL_SRCALPHA) + SDL_SetAlpha(s, SDL_SRCALPHA, + surface->format->alpha); + return s; + } + else + { + s = SDL_DisplayFormatAlpha(surface); + if(s) + GLSDL_FIX_SURFACE(s); + return s; + } +} + + +SDL_Surface *glSDL_ConvertSurface + (SDL_Surface *src, SDL_PixelFormat *fmt, Uint32 flags) +{ + SDL_Surface *s = SDL_ConvertSurface(src, fmt, flags); + if(s) + GLSDL_FIX_SURFACE(s); + return s; +} + + +SDL_Surface *glSDL_CreateRGBSurface + (Uint32 flags, int width, int height, int depth, + Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) +{ + SDL_Surface *s = SDL_CreateRGBSurface(flags, width, height, depth, + Rmask, Gmask, Bmask, Amask); + if(s) + GLSDL_FIX_SURFACE(s); + return s; +} + + +SDL_Surface *glSDL_CreateRGBSurfaceFrom(void *pixels, + int width, int height, int depth, int pitch, + Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) +{ + SDL_Surface *s = SDL_CreateRGBSurfaceFrom(pixels, + width, height, depth, pitch, + Rmask, Gmask, Bmask, Amask); + if(s) + GLSDL_FIX_SURFACE(s); + return s; +} + + +SDL_Surface *glSDL_LoadBMP(const char *file) +{ + SDL_Surface *s = SDL_LoadBMP(file); + if(s) + GLSDL_FIX_SURFACE(s); + return s; +} + + +int glSDL_SaveBMP(SDL_Surface *surface, const char *file) +{ + SDL_Rect r; + SDL_Surface *buf; + SDL_Surface *screen = SDL_GetVideoSurface(); + + if(!USING_GLSDL) + return SDL_SaveBMP(surface, file); + + if((surface != screen) && (surface != fake_screen)) + return SDL_SaveBMP(surface, file); + + buf = CreateRGBSurface(fake_screen->w, fake_screen->h); + + r.x = 0; + r.y = 0; + r.w = fake_screen->w; + r.h = fake_screen->h; + if(glSDL_BlitFromGL(&r, buf, &r) < 0) + return -1; + + return SDL_SaveBMP(buf, file); + + glSDL_FreeSurface(buf); +} + + + + +static int InitTexture(SDL_Surface *datasurf, glSDL_TexInfo *txi, int tex) +{ + gl.GenTextures(1, (unsigned int *)&txi->texture[tex]); + gl.BindTexture(GL_TEXTURE_2D, txi->texture[tex]); + gl.PixelStorei(GL_UNPACK_ROW_LENGTH, datasurf->pitch / + datasurf->format->BytesPerPixel); + gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + gl.TexImage2D(GL_TEXTURE_2D, 0, + datasurf->format->Amask ? GL_RGBA8 : GL_RGB8, + txi->texsize, txi->texsize, 0, + datasurf->format->Amask ? GL_RGBA : GL_RGB, + GL_UNSIGNED_BYTE, NULL); + print_glerror(1); + return 0; +} + + +/* Image tiled horizontally (wide surface), or not at all */ +static int UploadHoriz(SDL_Surface *datasurf, glSDL_TexInfo *txi) +{ + int bpp = datasurf->format->BytesPerPixel; + int res; + int tex = 0; + int fromx = 0; + int toy = txi->texsize; /* To init first texture */ + while(1) + { + int thistw = datasurf->w - fromx; + if(thistw > txi->tilew) + thistw = txi->tilew; + else if(thistw <= 0) + break; + if(toy + txi->tileh > txi->texsize) + { + toy = 0; + res = InitTexture(datasurf, txi, tex); + if(res < 0) + return res; + ++tex; + } + gl.TexSubImage2D(GL_TEXTURE_2D, 0, 0, toy, + thistw, txi->tileh, + datasurf->format->Amask ? GL_RGBA : GL_RGB, + GL_UNSIGNED_BYTE, + (char *)datasurf->pixels + bpp * fromx); + print_glerror(2); + fromx += txi->tilew; + toy += txi->tileh; + gl.Flush(); + } + return 0; +} + + +/* Image tiled vertically (tall surface) */ +static int UploadVert(SDL_Surface *datasurf, glSDL_TexInfo *txi) +{ + int res; + int tex = 0; + int fromy = 0; + int tox = txi->texsize; /* To init first texture */ + while(1) + { + int thisth = datasurf->h - fromy; + if(thisth > txi->tileh) + thisth = txi->tileh; + else if(thisth <= 0) + break; + if(tox + txi->tilew > txi->texsize) + { + tox = 0; + res = InitTexture(datasurf, txi, tex); + if(res < 0) + return res; + ++tex; + } + gl.TexSubImage2D(GL_TEXTURE_2D, 0, tox, 0, + txi->tilew, thisth, + datasurf->format->Amask ? GL_RGBA : GL_RGB, + GL_UNSIGNED_BYTE, + (char *)datasurf->pixels + datasurf->pitch * fromy); + print_glerror(3); + fromy += txi->tileh; + tox += txi->tilew; + gl.Flush(); + } + return 0; +} + + +/* Image tiled two-way (huge surface) */ +static int UploadHuge(SDL_Surface *datasurf, glSDL_TexInfo *txi) +{ + int bpp = datasurf->format->BytesPerPixel; + int res; + int tex = 0; + int y = 0; + while(y < datasurf->h) + { + int x; + int thisth = datasurf->h - y; + if(thisth > txi->tileh) + thisth = txi->tileh; + x = 0; + while(x < datasurf->w) + { + int thistw = datasurf->w - x; + if(thistw > txi->tilew) + thistw = txi->tilew; + res = InitTexture(datasurf, txi, tex++); + if(res < 0) + return res; + gl.TexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, + thistw, thisth, + datasurf->format->Amask ? GL_RGBA : GL_RGB, + GL_UNSIGNED_BYTE, + (char *)datasurf->pixels + + datasurf->pitch * y + bpp * x); + print_glerror(4); + x += txi->tilew; + gl.Flush(); + } + y += txi->tileh; + } + return 0; +} + + +/* Upload all textures for a surface. */ +static int UploadTextures(SDL_Surface *datasurf, glSDL_TexInfo *txi) +{ + switch(txi->tilemode) + { + case GLSDL_TM_SINGLE: + case GLSDL_TM_HORIZONTAL: + UploadHoriz(datasurf, txi); + break; + case GLSDL_TM_VERTICAL: + UploadVert(datasurf, txi); + break; + case GLSDL_TM_HUGE: + UploadHuge(datasurf, txi); + break; + } + return 0; +} + + +SDL_Surface *glSDL_IMG_Load(const char *file) +{ + SDL_Surface *s; + s = IMG_Load(file); + if(s) + GLSDL_FIX_SURFACE(s); + return s; +} + + +/*---------------------------------------------------------- + glSDL specific API extensions +----------------------------------------------------------*/ + +int glSDL_VSync(int use) +{ + int old = vsync; + if(use >= 0) + vsync = use; + return old; +} + + +void glSDL_Invalidate(SDL_Surface *surface, SDL_Rect *area) +{ + glSDL_TexInfo *txi; + if(!surface) + return; + txi = glSDL_GetTexInfo(surface); + if(!txi) + return; + if(!area) + { + txi->invalid_area.x = 0; + txi->invalid_area.y = 0; + txi->invalid_area.w = surface->w; + txi->invalid_area.h = surface->h; + return; + } + txi->invalid_area = *area; +} + + +int glSDL_UploadSurface(SDL_Surface *surface) +{ + SDL_Surface *datasurf = surface; + glSDL_TexInfo *txi; + int i; + /* + * For now, we just assume that *every* texture needs + * conversion before uploading. + */ + + /* If there's no TexInfo, add one. */ + if(!IS_GLSDL_SURFACE(surface)) + glSDL_AddTexInfo(surface); + + txi = glSDL_GetTexInfo(surface); + if(!txi) + return -1; + + /* No partial updates implemented yet... */ + if(txi->invalid_area.w) + glSDL_UnloadSurface(surface); + else + { + int missing = 0; + if(txi->textures) + { + for(i = 0; i < txi->textures; ++i) + if(-1 == txi->texture[i]) + { + missing = 1; + break; + } + if(!missing) + return 0; /* They're already there! */ + } + } + + if(txi->texsize > maxtexsize) + { + fprintf(stderr, "glSDL/wrapper: INTERNAL ERROR: Too large texture!\n"); + return -1; /* This surface wasn't tiled properly... */ + } + + /* + * Kludge: Convert if not of preferred RGB or RGBA format. + * + * Conversion should only be done when *really* needed. + * That is, it should rarely have to be done with OpenGL + * 1.2+. + * + * Besides, any surface that's been SDL_DisplayFormat()ed + * should already be in the best known OpenGL format - + * preferably one that makes DMA w/o conversion possible. + */ + if(FormatIsOk(surface)) + datasurf = surface; + else + { + DBG(fprintf(stderr, "glSDL/wrapper: WARNING: On-the-fly conversion performed!\n")); + if(surface->format->Amask) + datasurf = glSDL_DisplayFormatAlpha(surface); + else + datasurf = glSDL_DisplayFormat(surface); + if(!datasurf) + return -2; + } + + if(UploadTextures(datasurf, txi) < 0) + return -3; + + if(datasurf != surface) + glSDL_FreeSurface(datasurf); + return 0; +} + + +static void UnloadTexture(glSDL_TexInfo *txi) +{ + int i; + if(SDL_WasInit(SDL_INIT_VIDEO)) + for(i = 0; i < txi->textures; ++i) + gl.DeleteTextures(1, (unsigned int *)&txi->texture[i]); + memset(&txi->invalid_area, 0, sizeof(txi->invalid_area)); +} + + +void glSDL_UnloadSurface(SDL_Surface *surface) +{ + glSDL_TexInfo *txi; + if(!IS_GLSDL_SURFACE(surface)) + return; + + txi = glSDL_GetTexInfo(surface); + if(txi) + UnloadTexture(txi); +} + + +#else /* HAVE_OPENGL */ + +/*---------------------------------------------------------- + Dummies for glSDL extensions that require OpenGL +----------------------------------------------------------*/ + +void glSDL_Invalidate(SDL_Surface *surface, SDL_Rect *area) +{ +} + +int glSDL_UploadSurface(SDL_Surface *surface) +{ + return 0; +} + +void glSDL_UnloadSurface(SDL_Surface *surface) +{ +} + +int glSDL_VSync(int use) +{ + return 0; +} + +void glSDL_SetBlendAlpha(Uint8 alpha) +{ +} + +void glSDL_SetBlendColor(Uint8 r, Uint8 g, Uint8 b) +{ +} + +void glSDL_SetCenter(float x, float y) +{ +} + +void glSDL_SetRotation(float angle) +{ +} + +void glSDL_SetScale(float x, float y) +{ +} + +void glSDL_ResetState(void) +{ +} + +#endif /* HAVE_OPENGL */ diff --git a/graphics/glSDL.h b/graphics/glSDL.h new file mode 100644 index 0000000..7bdf193 --- /dev/null +++ b/graphics/glSDL.h @@ -0,0 +1,399 @@ +/*(LGPL) +------------------------------------------------------------ + glSDL 0.9 - SDL 2D API on top of OpenGL +------------------------------------------------------------ + * Copyright (C) 2001-2004, 2006-2007 David Olofson + * This code is released under the terms of the GNU LGPL. + */ + +#ifndef _GLSDL_H_ +#define _GLSDL_H_ + +/* + * If you don't use GNU autotools or similar, uncomment this to + * compile with OpenGL enabled: +#define HAVE_OPENGL + * + * NOTE: + * See README about using this glSDL wrapper with + * SDL versions that have the glSDL backend! + */ + +/* We're still using SDL datatypes here - we just add some stuff. */ +#include "SDL.h" + +/* + * Ignore the flag from SDL w/ glSDL backend, since we're going + * to use glSDL/wrapper by default. + */ +#ifdef SDL_GLSDL +#undef SDL_GLSDL +#endif + +#ifndef HAVE_OPENGL + +/* Fakes to make glSDL code compile with SDL. */ +#define SDL_GLSDL 0 +#define GLSDL_FIX_SURFACE(s) + +#else /* HAVE_OPENGL */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if (SDL_MAJOR_VERSION <= 1) && (SDL_MINOR_VERSION <= 2) && \ + (SDL_PATCHLEVEL < 5) +#warning glSDL: Using SDL version 1.2.5 or later is strongly recommended! +#endif + +/*---------------------------------------------------------- + SDL style API +----------------------------------------------------------*/ + +typedef enum glSDL_TileModes +{ + GLSDL_TM_SINGLE, + GLSDL_TM_HORIZONTAL, + GLSDL_TM_VERTICAL, + GLSDL_TM_HUGE +} glSDL_TileModes; + + +typedef struct glSDL_TexInfo +{ + int textures; + int *texture; + int texsize; /* width/height of OpenGL texture */ + glSDL_TileModes tilemode; + int tilew, tileh; /* At least one must equal texsize! */ + int tilespertex; + + /* Area of surface to download when/after unlocking */ + SDL_Rect invalid_area; +} glSDL_TexInfo; + +#define GLSDL_FIX_SURFACE(s) (s)->unused1 = 0; +#define IS_GLSDL_SURFACE(s) ((s) && texinfotab && glSDL_GetTexInfo(s)) + +#ifdef SDL_GLSDL +#undef SDL_GLSDL /* In case SDL has the glSDL backend... */ +#endif +#define SDL_GLSDL 0x00100000 /* Create an OpenGL 2D rendering context */ + + +/* + * Wraps SDL_SetVideoMode(), and adds support for the SDL_GLSDL flag. + * + * If 'flags' contains SDL_GLSDL, glSDL_SetVideoMode() sets up a "pure" + * OpenGL rendering context for use with the glSDL_ calls. + * + * SDL can be closed as usual (using SDL_ calls), but you should call + * glSDL_Quit() (kludge) to allow glSDL to clean up it's internal stuff. + */ +SDL_Surface *glSDL_SetVideoMode(int width, int height, int bpp, Uint32 flags); +void glSDL_Quit(void); + +void glSDL_QuitSubSystem(Uint32 flags); + +/* Replaces SDL_Quit() entirely, when using the override defines */ +void glSDL_FullQuit(void); + +SDL_Surface *glSDL_GetVideoSurface(void); + +void glSDL_UpdateRects(SDL_Surface *screen, int numrects, SDL_Rect *rects); +void glSDL_UpdateRect(SDL_Surface *screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h); + +/* + * Works like SDL_Flip(), but may also perform enqueued blits. + * (That is, it's possible that the implementation renders + * *nothing* until glSDL_Flip() is called.) + */ +int glSDL_Flip(SDL_Surface *screen); + +void glSDL_FreeSurface(SDL_Surface *surface); + +int glSDL_LockSurface(SDL_Surface *surface); +void glSDL_UnlockSurface(SDL_Surface *surface); + +/* + * Like the respective SDL functions, although they ignore + * SDL_RLEACCEL, as it makes no sense in this context. + */ +int glSDL_SetColorKey(SDL_Surface *surface, Uint32 flag, Uint32 key); +int glSDL_SetAlpha(SDL_Surface *surface, Uint32 flag, Uint8 alpha); + +/* + * Sets up clipping for the screen, or a SDL_Surface. + * + * Note that this function takes both SDL_Surfaces and + * glSDL_Surfaces. + */ +SDL_bool glSDL_SetClipRect(SDL_Surface *surface, SDL_Rect *rect); + +int glSDL_BlitSurface(SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect); + +int glSDL_FillRect(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color); + +/* + * Convert the given surface into a SDL_Surface (if it isn't + * one already), and makes sure that the underlying SDL_Surface + * is of a pixel format suitable for fast texture downloading. + * + * Note that you *only* have to use this function if you want + * fast pixel access to surfaces (ie "procedural textures"). + * Any surfaces that aren't converted will be downloaded + * automatically upon the first call to glSDL_BlitSurface(), + * but if conversion is required, it will be required for + * every glSDL_UnlockSurface() call. + * + * IMPORTANT: + * You *can* pass an SDL_Surface directly to this function, + * and it will try to deal with it nicely. However, this + * requires that a temporary SDL_Surface is created, and + * this surface is cached only until the texture memory is + * needed for new surfaces. + */ +SDL_Surface *glSDL_DisplayFormat(SDL_Surface *surface); +SDL_Surface *glSDL_DisplayFormatAlpha(SDL_Surface *surface); + +SDL_Surface *glSDL_ConvertSurface + (SDL_Surface *src, SDL_PixelFormat *fmt, Uint32 flags); +SDL_Surface *glSDL_CreateRGBSurface + (Uint32 flags, int width, int height, int depth, + Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); +SDL_Surface *glSDL_CreateRGBSurfaceFrom(void *pixels, + int width, int height, int depth, int pitch, + Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); +SDL_Surface *glSDL_LoadBMP(const char *file); +int glSDL_SaveBMP(SDL_Surface *surface, const char *file); + +#ifdef __cplusplus +} +#endif + +/* Some ugly "overriding"... */ +#ifndef _GLSDL_NO_REDEFINES_ +/* + * You *always* need to lock and unlock a glSDL surface in + * order to get glSDL to update the OpenGL texture! + */ +#undef SDL_MUSTLOCK +#define SDL_MUSTLOCK(surface) \ + (surface->offset || \ + ((surface->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_RLEACCEL)) != 0) || \ + IS_GLSDL_SURFACE(surface)) + +#define SDL_SetVideoMode glSDL_SetVideoMode +#define SDL_GetVideoSurface glSDL_GetVideoSurface +#define SDL_Quit glSDL_FullQuit +#define SDL_QuitSubSystem glSDL_QuitSubSystem +#define SDL_UpdateRects glSDL_UpdateRects +#define SDL_UpdateRect glSDL_UpdateRect +#define SDL_Flip glSDL_Flip +#define SDL_FreeSurface glSDL_FreeSurface +#define SDL_LockSurface glSDL_LockSurface +#define SDL_UnlockSurface glSDL_UnlockSurface +#define SDL_SetColorKey glSDL_SetColorKey +#define SDL_SetAlpha glSDL_SetAlpha +#define SDL_SetClipRect glSDL_SetClipRect +#undef SDL_BlitSurface +#define SDL_BlitSurface glSDL_BlitSurface +#define SDL_FillRect glSDL_FillRect +#define SDL_DisplayFormat glSDL_DisplayFormat +#define SDL_DisplayFormatAlpha glSDL_DisplayFormatAlpha +#define SDL_ConvertSurface glSDL_ConvertSurface +#define SDL_CreateRGBSurface glSDL_CreateRGBSurface +#define SDL_CreateRGBSurfaceFrom glSDL_CreateRGBSurfaceFrom +#undef SDL_AllocSurface +#define SDL_AllocSurface glSDL_CreateRGBSurface +#undef SDL_LoadBMP +#define SDL_LoadBMP glSDL_LoadBMP +#undef SDL_SaveBMP +#define SDL_SaveBMP glSDL_SaveBMP +#define IMG_Load(x) glSDL_IMG_Load(x) +#endif + +#endif /* HAVE_OPENGL */ + + +#ifdef HAVE_OPENGL + +/* Some extra overloading for common external lib calls... */ +#include "SDL_image.h" +#ifdef __cplusplus +extern "C" { +#endif +SDL_Surface *glSDL_IMG_Load(const char *file); +#ifdef __cplusplus +} +#endif + +#endif /* HAVE_OPENGL */ + + +/*---------------------------------------------------------- + glSDL API extensions, transparent +----------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif +/* + * Invalidate part of a texture. + * + * This function can be used either between calls to + * glSDL_LockSurface() and glSDL_UnlockSurface(), or before + * calling glSDL_DownloadSurface(). + * + * In either case, it causes only the specified area to be + * downloaded when unlocking the surface, or calling + * glSDL_UnlockSurface(), respectively. + * + * Note that if this function is not used, glSDL assumes that + * the entire surface has to be updated. (That is, it's safe + * to ignore this function - it's "just a performance hack.") + * + * Passing a rectangle with zero height or width cancels the + * downloading when/after unlocking the surface. Use if you + * just want to read the texture, but feel like being nice and + * obeying SDL_MUSTLOCK() - which is a good idea, as things + * may change... + * + * Passing NULL for the 'area' argument results in the entire + * surface being invalidated. + * + * NOTE: This function does NOT perform clipping! Weird or + * even Bad Things may happen if you specify areas + * that protrude outside the edges of the actual + * surface. + */ +void glSDL_Invalidate(SDL_Surface *surface, SDL_Rect *area); + +/* + * Make sure that the texture of the specified surface is up + * to date in OpenGL texture memory. + * + * This can be used together with glSDL_UnloadSurface() to + * implement custom texture caching schemes. + * + * Returns 0 on success, or a negative value if something + * went wrong. + */ +int glSDL_UploadSurface(SDL_Surface *surface); + +/* + * Free the texture space used by the specified surface. + * + * Normally, glSDL should download textures when needed, and + * unload the oldest (in terms of use) surfaces, if it runs out + * of texture space. + */ +void glSDL_UnloadSurface(SDL_Surface *surface); + + +/*---------------------------------------------------------- + glSDL API extensions, OpenGL mode ONLY +----------------------------------------------------------*/ + +/* + * Enable, disable or check the state of "vsync" or + * vertical retrace synchronization. Note that enabling + * this does not *guarantee* that the driver actually + * uses vsync; it only instructs OpenGL to do so if + * possible. + * Pass 1 for 'use' to enable vsync, '0' to disable + * it, and -1 to just return the current state without + * changing it. + * Returns the vsync state *before* any change made + * by the call. + * + * NOTE: Ignored when not using OpenGL acceleration! + */ +int glSDL_VSync(int use); + +/* + * Set alpha multiplier. This is multiplied with any full + * surface alpha or alpha channels of surfaces. + * + * The default value is 255, which makes glSDL render like + * the standard SDL 2D backends, ie based only on the + * surface settings. + * + * This function affects the global state of glSDL. + * + * NOTE: NOT available without OpenGL acceleration! + */ +void glSDL_SetBlendAlpha(Uint8 alpha); + +/* + * Set color multipliers. These are multiplied with the + * respective color channers of rendered surfaces, + * modulating the brightness of the resulting output. + * + * The default values are 255, which makes glSDL render + * like the standard SDL 2D backends. + * + * This function affects the global state of glSDL. + * + * NOTE: NOT available without OpenGL acceleration! + */ +void glSDL_SetBlendColor(Uint8 r, Uint8 g, Uint8 b); + +/* + * Set center offset in pixels for scaling and rotation. + * + * The default is (0, 0), which makes surfaces rotate and + * scale around their centers. + * + * This function affects the global state of glSDL. + * + * NOTE: NOT available without OpenGL acceleration! + */ +void glSDL_SetCenter(float x, float y); + + +/* + * Set rotation angle in degrees. Rotation is done around + * the center point, which is defined as + * (w/2 + cx, h/2 + cy) + * where w and h are the width and height of the source + * surface, and cx and cy are the center offsets set by + * glSDL_SetCenter(). + * + * The default value is 0.0f, which makes glSDL render + * like a normal SDL 2D backend. + * + * This function affects the global state of glSDL. + * + * NOTE: NOT available without OpenGL acceleration! + */ +void glSDL_SetRotation(float angle); + +/* + * Set scale factor. Scaling is centered around around + * the point + * (w/2 + cx, h/2 + cy) + * where w and h are the width and height of the source + * surface, and cx and cy are the center offsets set by + * glSDL_SetCenter(). + * + * The default value is 1.0f, which makes glSDL render + * like a normal SDL 2D backend. + * + * This function affects the global state of glSDL. + * + * NOTE: NOT available without OpenGL acceleration! + */ +void glSDL_SetScale(float x, float y); + +/* + * Reset glSDL global state to defaults. + */ +void glSDL_ResetState(void); +#ifdef __cplusplus +} +#endif + + +#endif /* _GLSDL_H_ */ diff --git a/graphics/region.c b/graphics/region.c new file mode 100644 index 0000000..f72b45d --- /dev/null +++ b/graphics/region.c @@ -0,0 +1,213 @@ +/*(LGPL) +---------------------------------------------------------------------- + region.c - Graphics Engine +---------------------------------------------------------------------- + * Copyright (C) 2007 David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "region.h" +#include + +static struct +{ + RGN_region *region; + int x, y; + SDL_Surface *target; +} s; + + +static Uint32 gp1(SDL_Surface *surface, int x, int y) +{ + return *((Uint8 *)surface->pixels + y * surface->pitch + x); +} + + +static Uint32 gp2(SDL_Surface *surface, int x, int y) +{ + return *((Uint16 *)surface->pixels + y * surface->pitch / 2 + x); +} + + +static Uint32 gp3(SDL_Surface *surface, int x, int y) +{ + int bpp = surface->format->BytesPerPixel; + Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp; +#if (SDL_BYTEORDER == SDL_BIG_ENDIAN) + return p[0] << 16 | p[1] << 8 | p[2]; +#else + return p[0] | p[1] << 8 | p[2] << 16; +#endif +} + + +static Uint32 gp4(SDL_Surface *surface, int x, int y) +{ + return *((Uint32 *)surface->pixels + y * surface->pitch / 4 + x); +} + + +RGN_region *RGN_ScanMask(SDL_Surface *src, Uint32 key) +{ + RGN_region *rgn = (RGN_region *)calloc(1, sizeof(RGN_region)); + Uint32 (*gp)(SDL_Surface *surface, int x, int y); + int x, y; + if(!rgn) + return NULL; + rgn->rows = src->h; + rgn->spans = (Uint16 **)calloc(1, sizeof(Uint16 *) * src->h); + if(!rgn->spans) + { + RGN_FreeRegion(rgn); + return NULL; + } + switch(src->format->BytesPerPixel) + { + case 1: + gp = gp1; + break; + case 2: + gp = gp2; + break; + case 3: + gp = gp3; + break; + case 4: + gp = gp4; + break; + default: + RGN_FreeRegion(rgn); + return NULL; + } + SDL_LockSurface(src); + for(y = 0; y < src->h; ++y) + { + int i = 0; + int drawing = 0; + Uint16 *sp = (Uint16 *)malloc(sizeof(Uint16) * 2 * (src->w + 1)); + if(!sp) + { + SDL_UnlockSurface(src); + RGN_FreeRegion(rgn); + return NULL; + } + for(x = 0; x < src->w; ++x) + { + int nd = (gp(src, x, y) == key); + if(nd != drawing) + { + sp[i++] = x; + drawing = nd; + } + } + if(drawing) + sp[i++] = src->w; + sp[i++] = 0; + sp[i++] = 0; + rgn->spans[y] = (Uint16 *)realloc(sp, sizeof(Uint16) * i); + if(!rgn->spans[y]) + rgn->spans[y] = sp; + } + SDL_UnlockSurface(src); + return rgn; +} + + +void RGN_FreeRegion(RGN_region *rgn) +{ + if(!rgn) + return; + if(rgn->spans) + { + int i; + for(i = rgn->rows - 1; i >= 0; --i) + free(rgn->spans[i]); + free(rgn->spans); + } + free(rgn); +} + + +void RGN_Target(SDL_Surface *tgt) +{ + s.target = tgt; +} + + +void RGN_SetRegion(RGN_region *rgn, int xpos, int ypos) +{ + s.region = rgn; + s.x = xpos; + s.y = ypos; +} + + +int RGN_Blit(SDL_Surface *src, SDL_Rect *sr, int x, int y) +{ +// FIXME: Clipping is only half done here... + int yy0, yy, yy1; + int sxmin, sxmax, symin, symax; + SDL_Rect sr2; + if(!s.region) + { + SDL_Rect dr; + dr.x = x; + dr.y = y; + return SDL_BlitSurface(src, sr, s.target, &dr); + } + if(sr) + { + sxmin = sr->x; + symin = sr->y; + sxmax = sxmin + sr->w; + symax = symin + sr->h; + } + else + { + sxmin = 0; + symin = 0; + sxmax = src->w; + symax = src->h; + } + yy0 = s.y; + if(yy0 >= y + (symax - symin)) + return 0; + if(yy0 < y) + yy0 = y; + yy1 = s.y + s.region->rows; + if(y >= yy1) + return 0; + if(yy1 > y + (symax - symin)) + yy1 = y + (symax - symin); + sr2.h = 1; + for(yy = yy0; yy < yy1; ++yy) + { + SDL_Rect dr; + Uint16 *spans = s.region->spans[yy - s.y]; + sr2.y = symin + y - yy0; + dr.y = yy; + for( ; spans[0] && spans[1] ; spans += 2) + { + int x0 = s.x + spans[0]; + int x1 = s.x + spans[1]; + dr.x = x0; + sr2.x = sxmin + x0 - x; + sr2.w = x1 - x0; + SDL_BlitSurface(src, &sr2, s.target, &dr); + } + } + return 0; +} diff --git a/graphics/region.h b/graphics/region.h new file mode 100644 index 0000000..cb88e62 --- /dev/null +++ b/graphics/region.h @@ -0,0 +1,61 @@ +/*(LGPL) +---------------------------------------------------------------------- + region.h - Graphics Engine +---------------------------------------------------------------------- + * Copyright (C) 2007 David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef KOBO_REGION_H +#define KOBO_REGION_H + +#include "glSDL.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Region + * Describes an area as a number of pixel spaced rows, + * each containing zero or more spans on the form . + */ +typedef struct RGN_region +{ + int rows; + Uint16 **spans; +} RGN_region; + +/* Construct region by scanning an SDL surface */ +RGN_region *RGN_ScanMask(SDL_Surface *src, Uint32 key); + +/* Free a region */ +void RGN_FreeRegion(RGN_region *rgn); + +/* Set target for region rendering */ +void RGN_Target(SDL_Surface *tgt); + +/* Select and position region for subsequent operations */ +void RGN_SetRegion(RGN_region *rgn, int xpos, int ypos); + +/* Blit to region! */ +int RGN_Blit(SDL_Surface *src, SDL_Rect *sr, int x, int y); + +#ifdef __cplusplus +}; +#endif + +#endif /* KOBO_REGION_H */ diff --git a/graphics/sofont.cpp b/graphics/sofont.cpp new file mode 100644 index 0000000..3ade135 --- /dev/null +++ b/graphics/sofont.cpp @@ -0,0 +1,577 @@ +#include "logger.h" +#include "stdlib.h" +#include "sofont.h" +#include "string.h" + +SoFont::SoFont() +{ + picture = NULL; + CharPos = NULL; + CharOffset = NULL; + Spacing = NULL; + height = 0; + max_i = 0; + spacew = 0; + cursShift = 0; + background = 0; + xspace = 1; +} + +SoFont::~SoFont() +{ + if(picture) + SDL_FreeSurface(picture); + delete[]CharPos; + delete[]CharOffset; + delete[]Spacing; +} + +namespace SoFontUtilities +{ + Uint32 SoFontGetPixel(SDL_Surface * Surface, Sint32 X, Sint32 Y) + { + Uint8 *bits; + Uint32 Bpp; + + if(!Surface) + { + log_printf(ELOG, "SoFontGetPixel: No surface!\n"); + return 0; + } + if((X < 0) || (X >= Surface->w)) + { + log_printf(ELOG, "SoFontGetPixel: X (%d)" + " out of range!\n", X); + return 0; + } + + Bpp = Surface->format->BytesPerPixel; + + bits = ((Uint8 *) Surface->pixels) + Y * Surface->pitch + + X * Bpp; + + switch (Bpp) + { + case 1: + return *((Uint8 *) Surface->pixels + + Y * Surface->pitch + X); + break; + case 2: + return *((Uint16 *) Surface->pixels + + Y * Surface->pitch / 2 + X); + break; + case 3: + // Format/endian independent + Uint8 r, g, b; + r = *((bits) + Surface->format->Rshift / 8); + g = *((bits) + Surface->format->Gshift / 8); + b = *((bits) + Surface->format->Bshift / 8); + return SDL_MapRGB(Surface->format, r, g, b); + break; + case 4: + return *((Uint32 *) Surface->pixels + + Y * Surface->pitch / 4 + X); + break; + } + log_printf(ELOG, "SoFontGetPixel: Unsupported pixel format!\n"); + return 0; // David (to get rid of warning) + } + void SoFontSetPixel(SDL_Surface * Surface, Sint32 X, Sint32 Y, + Uint32 c) + { + Uint8 *bits; + Uint32 Bpp; + + if(!Surface) + { + log_printf(ELOG, "SoFontSetPixel: No surface!\n"); + return; + } + if((X < 0) || (X >= Surface->w)) + { + log_printf(ELOG, "SoFontSetPixel: X (%d)" + " out of range!\n", X); + return; + } + + Bpp = Surface->format->BytesPerPixel; + + bits = ((Uint8 *) Surface->pixels) + Y * Surface->pitch + + X * Bpp; + + switch (Bpp) + { + case 1: + *((Uint8 *) Surface->pixels + Y * Surface->pitch + + X) = (Uint8) c; + break; + case 2: + *((Uint16 *) Surface->pixels + + Y * Surface->pitch / 2 + X) = + (Uint16) c; + break; + case 3: + // Format/endian independent + Uint8 r, g, b; + SDL_GetRGB(c, Surface->format, &r, &g, &b); + *((bits) + Surface->format->Rshift / 8) = r; + *((bits) + Surface->format->Gshift / 8) = g; + *((bits) + Surface->format->Bshift / 8) = b; + break; + case 4: + *((Uint32 *) Surface->pixels + + Y * Surface->pitch / 4 + X) = c; + break; + } + } + void clipx(SDL_Rect * srcrect, SDL_Rect * dstrect, SDL_Rect * clip) + { + // Use if destination have the same size than source. + int dx = clip->x - dstrect->x; + + int sw = srcrect->w; // Because SDL_Rect.w are + // unsigned. + int dw = dstrect->w; + + if(dx > 0) + { + srcrect->x += dx; + dstrect->x += dx; + + sw -= dx; + dw -= dx; + } + + int dwx = (dstrect->x + dstrect->w) - (clip->x + clip->w); + + if(dwx > 0) + { + sw -= dwx; + dw -= dwx; + } + + if(sw > 0) + srcrect->w = sw; + else + srcrect->w = 0; + + if(dw > 0) + dstrect->w = dw; + else + dstrect->w = 0; + } + void sdcRects(SDL_Rect * source, SDL_Rect * destination, + SDL_Rect clipping) + { + // Use if destination have the same size than source & + // cliping on destination + int dx = clipping.x - destination->x; + int dy = clipping.y - destination->y; + + int sw = source->w; + int sh = source->h; + + if(dx > 0) + { + source->x += dx; + destination->x += dx; + + sw -= dx; + destination->w -= dx; + } + if(dy > 0) + { + source->y += dy; + destination->y += dy; + + sh -= dy; + destination->h -= dy; + } + + int dwx = (destination->x + destination->w) - (clipping.x + + clipping.w); + int dhy = (destination->y + destination->h) - (clipping.y + + clipping.h); + + if(dwx > 0) + { + sw -= dwx; + destination->w -= dwx; + } + if(dhy > 0) + { + sh -= dhy; + destination->h -= dhy; + } + + if(sw > 0) + source->w = sw; + else + source->w = 0; + + if(sh > 0) + source->h = sh; + else + source->h = 0; + + } + +} +using namespace SoFontUtilities; + +bool SoFont::DoStartNewChar(Sint32 x) +{ + if(!picture) + return false; + return SoFontGetPixel(picture, x, 0) == + SDL_MapRGB(picture->format, 255, 0, 255); +} + +void SoFont::CleanSurface() +{ + if(!picture) + return; + + int x = 0, y = 0; + Uint32 pix = SDL_MapRGB(picture->format, 255, 0, 255); + + while(x < picture->w) + { + y = 0; + if(SoFontGetPixel(picture, x, y) == pix) + SoFontSetPixel(picture, x, y, background); + x++; + } +} + + +bool SoFont::load(SDL_Surface * FontSurface) +{ + int x = 0, i = 0, s = 0; + + int _CharPos[256]; + int _CharOffset[256]; + int _Spacing[256]; + + if(!FontSurface) + { + log_printf(ELOG, "SoFont recieved a NULL SDL_Surface\n"); + return false; + } + if(picture) + SDL_FreeSurface(picture); + picture = FontSurface; + height = picture->h - 1; + while(x < picture->w) + { + if(DoStartNewChar(x)) + { + if(i) + _Spacing[i - 1] = x - s + xspace; + int p = x; + while((x < picture->w) && (DoStartNewChar(x))) + x++; + s = x; + _CharPos[i] = (x + p + 1) / 2; + _CharOffset[i] = x - _CharPos[i]; + i++; + } + x++; + } + //Note that spacing is not needed for the last char, + //as it's just used for the blit width calculation. + if(i) + _Spacing[i - 1] = x - s; + _Spacing[i] = 0; + _CharOffset[i] = 0; + _CharPos[i++] = picture->w; + + max_i = START_CHAR + i - 1; + background = SoFontGetPixel(picture, 0, height); +// FIXME: Use this when there is no alpha channel? +// SDL_SetColorKey(picture, SDL_SRCCOLORKEY, background); + CleanSurface(); + + delete[]CharPos; + delete[]CharOffset; + delete[]Spacing; + CharPos = new int[i]; + CharOffset = new int[i]; + Spacing = new int[i]; + memcpy(CharPos, _CharPos, i * sizeof(int)); + memcpy(CharOffset, _CharOffset, i * sizeof(int)); + memcpy(Spacing, _Spacing, i * sizeof(int)); + + // We search for a smart space width: + // Changed from "a", "A", "0" for Kobo Deluxe. + // Spaces were *way* to wide! //David + spacew = 0; + if(!spacew) + spacew = TextWidth("i") * 3 / 2; + if(!spacew) + spacew = TextWidth("I") * 3 / 2; + if(!spacew) + spacew = TextWidth(".") * 3 / 2; + if(!spacew) + spacew = CharPos[1] - CharPos[0]; + + // We search for a smart cursor position: + int cursBegin = 0; + int cursWidth = 0; + cursShift = 0; + if('|' > max_i) + return true; //No bar in this font! + + if(background == SoFontGetPixel(picture, CharPos['|' - START_CHAR], + height / 2)) + { + // Up to the first | color + for(cursBegin = 0; cursBegin <= TextWidth("|"); + cursBegin++) + if(background != SoFontGetPixel(picture, + CharPos['|' - START_CHAR] + + cursBegin, height / 2)) + break; + // Up to the end of the | color + for(cursWidth = 0; cursWidth <= TextWidth("|"); + cursWidth++) + if(background == SoFontGetPixel(picture, + CharPos['|' - START_CHAR] + + cursBegin + cursWidth, + height / 2)) + break; + } + else + { + // Up to the end of the | color + for(cursWidth = 0; cursWidth <= TextWidth("|"); + cursWidth++) + if(background == SoFontGetPixel(picture, + CharPos['|' - START_CHAR] + + cursWidth, height / 2)) + break; + } + cursShift = cursBegin + 1; // cursWidth could be used if + // image format changes. + + return true; +} + +void SoFont::PutString(SDL_Surface *Surface, int x, int y, + const char *text, SDL_Rect *clip) +{ + if((!picture) || (!Surface) || (!text)) + return; + int ofs, i = 0; + SDL_Rect srcrect, dstrect; + while(text[i] != '\0') + { + if(text[i] == ' ') + { + x += spacew; + i++; + } + else if((text[i] >= START_CHAR) && (text[i] <= max_i)) + { + ofs = text[i] - START_CHAR; + srcrect.w = dstrect.w = + this->CharPos[ofs + 1] - + this->CharPos[ofs]; + srcrect.h = dstrect.h = height; + srcrect.x = this->CharPos[ofs]; + srcrect.y = 1; + dstrect.x = x - CharOffset[ofs]; + dstrect.y = y; + x += Spacing[ofs]; + if(clip) + sdcRects(&srcrect, &dstrect, *clip); + SDL_BlitSurface(picture, &srcrect, Surface, + &dstrect); + i++; + } + else + i++; // other chars are ignored + + // Coarse clipping + if(clip) + { + if(x > clip->x + clip->w) + return; + } + else + { + if(x > Surface->w) + return; + } + } +} + +void SoFont::PutStringWithCursor(SDL_Surface * Surface, int xs, int y, + const char *text, int cursPos, SDL_Rect * clip, + bool showCurs) +{ + if((!picture) || (!Surface) || (!text)) + return; + if('|' > max_i) + showCurs = false; + int ofs, i = 0, x = xs; + + SDL_Rect srcrect, dstrect; + + // We want the cursor to appear under the main text. + if(showCurs) + { + while(text[i] != '\0') + if(i == cursPos) + break; + else if(text[i] == ' ') + { + x += spacew; + i++; + } + else if((text[i] >= START_CHAR) + && (text[i] <= max_i)) + { + ofs = text[i] - START_CHAR; + x += Spacing[ofs]; + i++; + } + else + i++; + ofs = '|' - START_CHAR; + + srcrect.w = dstrect.w = CharPos[ofs + 1] - CharPos[ofs]; + srcrect.h = dstrect.h = height; + srcrect.x = this->CharPos[ofs]; + srcrect.y = 1; + dstrect.x = x - cursShift; + dstrect.y = y; + if(clip) + sdcRects(&srcrect, &dstrect, *clip); + SDL_BlitSurface(picture, &srcrect, Surface, &dstrect); + } + // Then the text: + PutString(Surface, xs, y, text, clip); +} +int SoFont::TextWidth(const char *text, int min, int max) +{ + if(!picture) + return 0; + int ofs, x = 0, i = min; + while((text[i] != '\0') && (i < max)) + { + if(text[i] == ' ') + { + x += spacew; + i++; + } + else if((text[i] >= START_CHAR) && (text[i] <= max_i)) + { + ofs = text[i] - START_CHAR; + x += Spacing[ofs]; + i++; + } + else + i++; + } + return x; +} +void SoFont::XCenteredString(SDL_Surface * Surface, int y, + const char *text, SDL_Rect * clip) +{ + if(!picture) + return; + PutString(Surface, Surface->w / 2 - TextWidth(text) / 2, y, text, + clip); +} + +void SoFont::CenteredString(SDL_Surface * Surface, int x, int y, + const char *text, SDL_Rect * clip) +{ + if(!picture) + return; + PutString(Surface, x - TextWidth(text) / 2, y - height / 2, text, + clip); +} + +void SoFont::CenteredString(SDL_Surface * Surface, const char *text, + SDL_Rect * clip) +{ + if(!picture) + return; + CenteredString(Surface, Surface->clip_rect.w / 2, + Surface->clip_rect.h / 2, text, clip); +} + +void SoFont::PutStringCleverCursor(SDL_Surface * Surface, const char *text, + int cursPos, SDL_Rect * r, SDL_Rect * clip, bool showCurs) +{ + if((!picture) || (!text)) + return; + + int w1, w2; + + w1 = TextWidth(text, 0, cursPos); + w2 = TextWidth(text); + + if((w2 < r->w) || (w1 < r->w / 2)) + PutStringWithCursor(Surface, r->x, + r->y + (r->h - height) / 2, text, cursPos, + clip, showCurs); + else if(w1 < w2 - r->w / 2) + PutStringWithCursor(Surface, r->x - w1 + r->w / 2, + r->y + (r->h - height) / 2, text, cursPos, + clip, showCurs); + else + PutStringWithCursor(Surface, r->x - w2 + r->w, + r->y + (r->h - height) / 2, text, cursPos, + clip, showCurs); +} + +int SoFont::TextCursorAt(const char *text, int px) +{ + if(!picture) + return 0; + int ofs, x = 0, i = 0, ax = 0; + + if(px <= 0) + return 0; + + while(text[i] != '\0') + { + if(text[i] == ' ') + { + x += spacew; + i++; + } + else if((text[i] >= START_CHAR) && (text[i] <= max_i)) + { + ofs = text[i] - START_CHAR; + x += Spacing[ofs]; + i++; + } + else + i++; + + if(px < (ax + x) / 2) + return (i - 1); + ax = x; + } + return i; +} + +int SoFont::CleverTextCursorAt(const char *text, int px, int cursPos, + SDL_Rect * r) +{ + if((!picture) || (!text)) + return 0; + int w1, w2; + w1 = TextWidth(text, 0, cursPos); + w2 = TextWidth(text); + if((w2 < r->w) || (w1 < r->w / 2)) + return TextCursorAt(text, px); + else if(w1 < w2 - r->w / 2) + return TextCursorAt(text, px + w1 - (r->w / 2)); + else + return TextCursorAt(text, px + w2 - r->w); +} diff --git a/graphics/sofont.h b/graphics/sofont.h new file mode 100644 index 0000000..4cf62e1 --- /dev/null +++ b/graphics/sofont.h @@ -0,0 +1,103 @@ + /* + SoFont - SDL Object Font Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Originally from C Library: + Karl Bartel + +* SFONT - SDL Font Library by Karl Bartel * +* * +* All functions are explained below. There are two versions of each * +* funtction. The first is the normal one, the function with the * +* 2 at the end can be used when you want to handle more than one font * +* in your program. * +* * + + Copied into a C++ object to allow multiple fonts by: + Luc-Olivier de Charriere + + David Olofson : + * Strings changed to 'const char *' + * Cursor tests first check if '|' is present. + * Shadowed variables fixed. + * Garbage data in spacing table fixed. (Thanks to + Andreas Spångberg for discovering this one!) + * Added ExtraSpace(). (Scaling support hack...) + * Disabled colorkeying. (Ruins some RGBA fonts!) +*/ + +#ifndef __SOFONT_H +#define __SOFONT_H + +#include "glSDL.h" + +class SoFont +{ +public: + SoFont(); + ~SoFont(); + + bool load(SDL_Surface *FontSurface); + + // Blits a string to a surface + // Destination: the suface you want to blit to + // text: a string containing the text you want to blit. + void PutString(SDL_Surface *Surface, int x, int y, const char *text, SDL_Rect *clip=NULL); + void PutStringWithCursor(SDL_Surface *Surface, int x, int y, const char *text, int cursPos, SDL_Rect *clip=NULL, bool showCurs=true); + + // Returns the width of "text" in pixels + int TextWidth(const char *text, int min=0, int max=255); + + int FontHeight() { return height; } + + // Blits a string to with centered x position + void XCenteredString(SDL_Surface *Surface, int y, const char *text, SDL_Rect* clip=NULL); + // Blits a string to with centered x & y position + void CenteredString(SDL_Surface *Surface, const char *text, SDL_Rect* clip=NULL); + // Blits a string to with centered around x & y positions + void CenteredString(SDL_Surface *Surface, int x, int y, const char *text, SDL_Rect* clip=NULL); + + // This was specially developped for GUI + void PutStringCleverCursor(SDL_Surface *Surface, const char *text, int cursPos, SDL_Rect *r, SDL_Rect* clip=NULL, bool showCurs=true); + + // Gives the cursor position given a x-axix point in the text + int TextCursorAt(const char *text, int px); + int CleverTextCursorAt(const char *text, int px, int cursPos, SDL_Rect *r); + +# define START_CHAR 33 + int getMinChar(){return START_CHAR;} + int getMaxChar(){return max_i;} + + void ExtraSpace(int xs) + { + xspace = xs; + } + +protected: + int height; + SDL_Surface *picture; + int *CharPos; + int *CharOffset; + int *Spacing; + int xspace; + + int max_i, spacew, cursShift; + Uint32 background; + bool DoStartNewChar(Sint32 x); + void CleanSurface(); +}; + +#endif diff --git a/graphics/sprite.c b/graphics/sprite.c new file mode 100644 index 0000000..bb3c582 --- /dev/null +++ b/graphics/sprite.c @@ -0,0 +1,612 @@ +/*(LGPL) +---------------------------------------------------------------------- + sprite.c - Sprite engine for use with cs.h +---------------------------------------------------------------------- + * Copyright (C) 2001, 2003, 2007 David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* +TODO: Automatic extension of the bank and sprite +TODO: tables as needed when loading banks. +*/ + +#define DBG(x) x + +#include +#include +#include "logger.h" +#include "glSDL.h" +#include "SDL_image.h" +#include "sprite.h" +#include "filters.h" + + +s_blitmodes_t s_blitmode = S_BLITMODE_AUTO; +pix_t s_colorkey = {0, 0, 0, 0}; +pix_t s_clampcolor = {0, 0, 0, 0}; +unsigned char s_alpha = SDL_ALPHA_OPAQUE; +int s_filter_flags = 0; + + +s_filter_t *filters = NULL; + + +/* +---------------------------------------------------------------------- + Filter Plugin Interface +---------------------------------------------------------------------- + */ + +s_filter_t *s_insert_filter(s_filter_cb_t callback) +{ + s_filter_t *nf = calloc(1, sizeof(s_filter_t)); + if(!nf) + return NULL; + + nf->callback = callback; + nf->next = filters; + filters = nf; + return nf; +} + + +s_filter_t *s_add_filter(s_filter_cb_t callback) +{ + s_filter_t *nf = calloc(1, sizeof(s_filter_t)); + if(!nf) + return NULL; + + nf->callback = callback; + if(!filters) + filters = nf; + else + { + s_filter_t *f = filters; + while(f->next) + f = f->next; + f->next = nf; + } + return nf; +} + + +/* filter == NULL means "remove all plugins" */ +void s_remove_filter(s_filter_t *filter) +{ + s_filter_t *f; + if(!filters) + return; + + f = filters; + while(f->next) + { + if(f->next == filter || !filter) + { + s_filter_t *df = f->next; + f->next = f->next->next; + free(df); + } + else + f = f->next; + } + if(filters == filter || !filter) + { + s_filter_t *df = filters; + filters = filters->next; + free(df); + } +} + + +static void __run_plugins(s_bank_t *b, unsigned first, unsigned frames) +{ + s_filter_t *f = filters; + while(f) + { + int oflags = f->args.flags; + f->args.flags |= s_filter_flags; + f->callback(b, first, frames, &f->args); + f->args.flags = oflags; + f = f->next; + } +} + + +/* +---------------------------------------------------------------------- + Basic Container Management +---------------------------------------------------------------------- + */ + +static int __alloc_bank_table(s_container_t *c, unsigned int count) +{ + c->max = count - 1; + c->banks = (s_bank_t **)calloc((unsigned)count, sizeof(s_bank_t *)); + return -(c->banks == NULL); +} + +s_container_t *s_new_container(unsigned banks) +{ + s_container_t *ret = (s_container_t *)calloc(1, sizeof(s_container_t)); + if(!ret) + return NULL; + if(__alloc_bank_table(ret, banks) < 0) + return NULL; + return ret; +} + +void s_delete_container(s_container_t *c) +{ + s_delete_all_banks(c); + free(c->banks); + free(c); +} + + +/* + * Allocates a new sprite. + * If the sprite exists already, it's surface will be removed, so + * that one can safely expect to get an *empty* sprite. + */ +s_sprite_t *s_new_sprite_b(s_bank_t *b, unsigned frame) +{ + s_sprite_t *s = NULL; + if(frame > b->max) + return NULL; + if(!b->sprites[frame]) + { + s = calloc(1, sizeof(s_sprite_t)); + if(!s) + return NULL; + b->sprites[frame] = s; + } + else + { + if(s->surface) + SDL_FreeSurface(s->surface); + s->surface = NULL; + } + return s; +} + + +/* + * Allocates a new sprite. + * If the sprite exists already, it's surface will be removed, so + * that one can safely expect to get an *empty* sprite. + * + * If the bank does not exist, or if the operation failed for + * other reasons, this call returns NULL. + */ +s_sprite_t *s_new_sprite(s_container_t *c, unsigned bank, unsigned frame) +{ + if(bank > c->max) + return NULL; + if(!c->banks[bank]) + return NULL; + + return s_new_sprite_b(c->banks[bank], frame); +} + + +void s_delete_sprite_b(s_bank_t *b, unsigned frame) +{ + if(!b->sprites) /* This can happen when failing to create a new bank */ + return; + if(frame > b->max) + return; + if(!b->sprites[frame]) + return; + if(b->sprites[frame]->surface) + SDL_FreeSurface(b->sprites[frame]->surface); + b->sprites[frame]->surface = NULL; + free(b->sprites[frame]); + b->sprites[frame] = NULL; +} + + +void s_delete_sprite(s_container_t *c, unsigned bank, unsigned frame) +{ + s_bank_t *b = s_get_bank(c, bank); + if(b) + s_delete_sprite_b(b, frame); +} + + +static int __alloc_sprite_table(s_bank_t *b, unsigned frames) +{ + b->max = frames - 1; + b->sprites = (s_sprite_t **)calloc(frames, sizeof(s_sprite_t *)); + if(!b->sprites) + return -1; + return 0; +} + + +s_bank_t *s_new_bank(s_container_t *c, unsigned bank, unsigned frames, + unsigned w, unsigned h) +{ + s_bank_t *b; + DBG(log_printf(DLOG, "s_new_bank(%p, %d, %d, %d, %d)\n", + c, bank, frames, w, h);) + if(bank > c->max) + return NULL; + if(c->banks[bank]) + s_delete_bank(c, bank); + + c->banks[bank] = (s_bank_t *)calloc(1, sizeof(s_bank_t)); + if(!c->banks[bank]) + return NULL; + if(__alloc_sprite_table(c->banks[bank], frames) < 0) + { + s_delete_bank(c, bank); + return NULL; + } + b = c->banks[bank]; + b->max = frames - 1; + b->w = w; + b->h = h; + return b; +} + + +void s_delete_bank(s_container_t *c, unsigned bank) +{ + unsigned i; + s_bank_t *b; + if(!c->banks) + return; + if(bank > c->max) + return; + b = c->banks[bank]; + if(b) + { + for(i = 0; i <= b->max; ++i) + s_delete_sprite_b(b, i); + free(b->sprites); + free(b); + c->banks[bank] = NULL; + } +} + + +void s_delete_all_banks(s_container_t *c) +{ + unsigned i; + for(i = 0; i <= c->max; ++i) + s_delete_bank(c, i); +} + + + +/* +---------------------------------------------------------------------- + Getting data +---------------------------------------------------------------------- + */ + +s_bank_t *s_get_bank(s_container_t *c, unsigned bank) +{ + if(bank > c->max) + return NULL; + if(!c->banks[bank]) + return NULL; + return c->banks[bank]; +} + +s_sprite_t *s_get_sprite(s_container_t *c, unsigned bank, unsigned frame) +{ + s_bank_t *b = s_get_bank(c, bank); + if(!b) + return NULL; + if(frame > b->max) + return NULL; + return b->sprites[frame]; +} + +s_sprite_t *s_get_sprite_b(s_bank_t *b, unsigned frame) +{ + if(!b) + return NULL; + if(frame > b->max) + return NULL; + return b->sprites[frame]; +} + +void s_detach_sprite(s_container_t *c, unsigned bank, unsigned frame) +{ + s_sprite_t *s = s_get_sprite(c, bank, frame); + if(!s) + return; + s->surface = NULL; +} + + +/* +---------------------------------------------------------------------- + File tools +---------------------------------------------------------------------- + */ + +static int extract_sprite(s_bank_t *bank, unsigned frame, + SDL_Surface *src, SDL_Rect *from) +{ + int y; + SDL_Surface *tmp; + if(frame > bank->max) + { + log_printf(ELOG, "sprite: Too many frames!\n"); + return -1; + } + if(!s_new_sprite_b(bank, frame)) + return -2; + + tmp = SDL_CreateRGBSurface(src->flags, + from->w, from->h, + src->format->BitsPerPixel, + src->format->Rmask, + src->format->Gmask, + src->format->Bmask, + src->format->Amask ); + if(!tmp) + return -3; + + /* Copy the pixel data */ + if(SDL_LockSurface(src) < 0) + { + log_printf(ELOG, "sprite: extract_sprite() failed to lock surface!\n"); + SDL_FreeSurface(tmp); + return -4; + } + for(y = 0; y < tmp->h; ++y) + { + char *s = (char *)src->pixels + src->pitch * (y + from->y) + + from->x * src->format->BytesPerPixel; + char *d = (char *)tmp->pixels + tmp->pitch * y; + memcpy(d, s, src->format->BytesPerPixel * tmp->w); + } + SDL_UnlockSurface(src); + + /* Copy palette, if any */ + if(src->format->palette) + SDL_SetColors(tmp, src->format->palette->colors, 0, + src->format->palette->ncolors); + + /* Copy alpha and colorkey */ + if(src->flags & SDL_SRCALPHA) + SDL_SetAlpha(tmp, src->flags & (SDL_SRCALPHA | SDL_RLEACCEL), + src->format->alpha); + if(src->flags & SDL_SRCCOLORKEY) + SDL_SetColorKey(tmp, src->flags & (SDL_SRCCOLORKEY | SDL_RLEACCEL), + src->format->colorkey); + + bank->sprites[frame]->surface = tmp; + + DBG(log_printf(DLOG, "image %d: (%d,%d)/%dx%d @ %p\n", frame, + from->x, from->y, from->w, from->h, + bank->sprites[frame]->surface);) + return 0; +} + + +int s_copy_rect(s_container_t *c, unsigned bank, + unsigned frombank, unsigned fromframe, SDL_Rect *from) +{ +#if 0 + s_filter_args_t args; +#endif + SDL_Surface *src; + s_sprite_t *s; + s_bank_t *b; + + /* Get source image */ + s = s_get_sprite(c, frombank, fromframe); + if(!s) + { + log_printf(ELOG, "sprite: Couldn't get source sprite %d:%d!\n", + frombank, fromframe); + return -1; + } + src = s->surface; + if(!src) + { + log_printf(ELOG, "sprite: Sprite %d:%d" + " does not have a surface!\n", + frombank, fromframe); + return -2; + } + + /* Create destination bank */ + b = s_new_bank(c, bank, 1, from->w, from->h); + if(!b) + { + log_printf(ELOG, "sprite: Failed to allocate bank %d!\n", bank); + return -3; + } + + if(extract_sprite(b, 0, src, from) < 0) + { + log_printf(ELOG, "sprite: Something went wrong while " + "copying from sprite %d:%d.\n", + frombank, fromframe); + return -4; + } +#if 0 + memset(&args, 0, sizeof(args)); + args.x = 0; + s_filter_displayformat(b, 0, 1, &args); +#endif + return 0; +} + + +int s_load_image(s_container_t *c, unsigned bank, const char *name) +{ + SDL_Surface *src; + s_bank_t *b; + + src = IMG_Load(name); + if(!src) + { + log_printf(ELOG, "sprite: Failed to load sprite \"%s\"!\n", name); + return -1; + } + + b = s_new_bank(c, bank, 1, src->clip_rect.w, src->clip_rect.h); + if(!b) + { + log_printf(ELOG, "sprite: Failed to allocate bank for \"%s\"!\n", name); + return -2; + } + + if(extract_sprite(b, 0, src, &src->clip_rect) < 0) + { + log_printf(ELOG, "sprite: Something went wrong while" + " extracting sprite \"%s\".\n", name); + return -3; + } + + SDL_FreeSurface(src); + __run_plugins(b, 0, 1); + return 0; +} + + +int s_load_sprite(s_container_t *c, unsigned bank, unsigned frame, + const char *name) +{ + SDL_Surface *src; + SDL_Rect from; + s_bank_t *b = s_get_bank(c, bank); + if(!b) + { + log_printf(ELOG, "sprite: While loading \"%s\":" + " Bank %d does not exist!\n", name, bank); + return -2; + } + + src = IMG_Load(name); + if(!src) + { + log_printf(ELOG, "sprite: Failed to load sprite \"%s\"!\n", name); + return -1; + } + + from = src->clip_rect; + if( (from.w != b->w) || (from.h != b->h) ) + { + log_printf(ELOG, "sprite: Warning: Sprite \"%s\" cropped" + " to fit in bank %d.\n", name, bank); + from.w = b->w; + from.h = b->h; + } + + if(extract_sprite(b, frame, src, &from) < 0) + { + log_printf(ELOG, "sprite: Something went wrong while" + " extracting sprite \"%s\".\n", name); + return -3; + } + + SDL_FreeSurface(src); + __run_plugins(b, frame, 1); + return 0; +} + + +int s_load_bank(s_container_t *c, unsigned bank, unsigned w, unsigned h, + const char *name) +{ + SDL_Surface *src; + s_bank_t *b; + int x, y; + unsigned frame = 0; + unsigned frames; + + DBG(log_printf(DLOG, "s_load_bank(%p, %d, %d, %d, %s)\n", + c, bank, w, h, name);) + + src = IMG_Load(name); + if(!src) + { + log_printf(ELOG, "sprite: Failed to load sprite palette %s!\n", name); + return -1; + } + + if(w > src->w) + { + log_printf(ELOG, "sprite: Source image %s not wide enough!\n", name); + return -4; + } + + if(h > src->h) + { + log_printf(ELOG, "sprite: Source image %s not high enough!\n", name); + return -5; + } + + frames = (src->w / w) * (src->h / h); + b = s_new_bank(c, bank, frames, w, h); + if(!b) + { + log_printf(ELOG, "sprite: Failed to allocate bank for \"%s\"!\n", name); + return -2; + } + for(y = 0; y <= src->h - h; y += h) + for(x = 0; x <= src->w - w; x += w) + { + SDL_Rect r; + r.x = x; + r.y = y; + r.w = w; + r.h = h; + if(extract_sprite(b, frame, src, &r) < 0) + { + log_printf(ELOG, "sprite: Something went wrong while" + " extracting sprites.\n"); + return -3; + } + ++frame; + } + SDL_FreeSurface(src); + __run_plugins(b, 0, frames); + return 0; +} + + +int s_set_hotspot(s_container_t *c, unsigned bank, int frame, int x, int y) +{ + if(frame < 0) + { + frame = 0; + while(1) + { + s_sprite_t *s = s_get_sprite(c, bank, frame++); + if(!s) + break; + s->x = x; + s->y = y; + } + } + else + { + s_sprite_t *s = s_get_sprite(c, bank, frame); + s->x = x; + s->y = y; + } + return 0; +} diff --git a/graphics/sprite.h b/graphics/sprite.h new file mode 100644 index 0000000..6897cdc --- /dev/null +++ b/graphics/sprite.h @@ -0,0 +1,242 @@ +/*(LGPL) +---------------------------------------------------------------------- + sprite.h - Sprite engine for use with cs.h +---------------------------------------------------------------------- + * Copyright (C) 2001, 2003, 2007 David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _SPRITE_H_ +#define _SPRITE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "glSDL.h" + +typedef enum +{ + S_BLITMODE_AUTO = 0, /* Use source alpha if present */ + S_BLITMODE_OPAQUE, /* Alpha: blend over black during conv. */ + S_BLITMODE_COLORKEY, /* Like OPAQUE, but apply colorkey to the result */ + S_BLITMODE_ALPHA /* Apply source alpha during conv, + * then use full surface alpha */ +} s_blitmodes_t; + +struct s_container_t; + +/* sprite image */ +typedef struct +{ + int x, y; /* kern or hot-spot*/ +#if 0 +/* TODO TODO TODO TODO TODO TODO */ + struct + { + int x, y, w, h; /* spacing or collision rect */ + } logic; +/* /TODO TODO TODO TODO TODO TODO */ +#endif + SDL_Surface *surface; +} s_sprite_t; + +/* Bank of sprite images */ +typedef struct +{ +#if 0 +/* TODO TODO TODO TODO TODO TODO */ + struct s_container_t *container; + int index; /* Index of this bank */ +/* /TODO TODO TODO TODO TODO TODO */ +#endif + unsigned w, h; /* Same size for all sprites in bank! */ + unsigned last; + unsigned max; + s_sprite_t **sprites; +} s_bank_t; + +/* Two dimensionally indexed sprite container */ +typedef struct s_container_t +{ + unsigned max; + s_bank_t **banks; +} s_container_t; + + +/* + * Basic Container Management + */ +s_container_t *s_new_container(unsigned banks); +void s_delete_container(s_container_t *c); + +s_bank_t *s_new_bank(s_container_t *c, unsigned bank, unsigned frames, + unsigned w, unsigned h); +void s_delete_bank(s_container_t *c, unsigned bank); +void s_delete_all_banks(s_container_t *c); + +s_sprite_t *s_new_sprite(s_container_t *c, unsigned bank, unsigned frame); +void s_delete_sprite(s_container_t *c, unsigned bank, unsigned frame); + +/* + * Getting data + */ +s_sprite_t *s_get_sprite(s_container_t *c, unsigned bank, unsigned frame); +/* Detach sprite image from the manager. */ +void s_detach_sprite(s_container_t *c, unsigned bank, unsigned frame); + +/* + * File Import Tools + * (Will run plugins as files are loaded!) + */ +int s_load_image(s_container_t *c, unsigned bank, const char *name); +int s_load_bank(s_container_t *c, unsigned bank, unsigned w, unsigned h, + const char *name); +int s_load_sprite(s_container_t *c, unsigned bank, unsigned frame, + const char *name); + +/* + * Rendering Tools + */ +int s_generate_bank(s_container_t *c, unsigned bank, unsigned w, unsigned h, + const char *name); + +/* + * Sprite metadata + */ +/* Set sprite hotspot. Pass -1 for 'frame' to set hotspot for all frames. */ +int s_set_hotspot(s_container_t *c, unsigned bank, int frame, int x, int y); + + +/* + * Internal data manipulation API + * (Will not automatically run plugins.) + */ +int s_copy_rect(s_container_t *c, unsigned bank, + unsigned frombank, unsigned fromframe, SDL_Rect *from); + +/* + * Lower level interfaces + */ +s_bank_t *s_get_bank(s_container_t *c, unsigned bank); +s_sprite_t *s_get_sprite_b(s_bank_t *b, unsigned frame); +s_sprite_t *s_new_sprite_b(s_bank_t *b, unsigned frame); +void s_delete_sprite_b(s_bank_t *b, unsigned frame); + + +/* + * Filter Plugin Interface + * + * Rules: + * * Plugins are called to process one bank at a time, + * after new frames have been loaded. + * + * * Plugins are called in the order they were + * registered. + * + * * Plugins may replace the surfaces of sprites. If + * they do so, they're responsible for disposing of + * the old surfaces. + * + * * It is recommended that plugins operate only on + * the specified range of frames in a bank. + * + * * The surface size of all sprites in a bank should + * preferably match that of the bank. A chain of + * plugins may break this rule temporarily, as long + * as "order is restored" (ie surfaces are resized, or + * bank size values is adjusted) before the chain ends. + * + * Cool plugin ideas: + * * Rotator: + * Takes a bank and generates N rotated versions of + * each sprite. + * + * * Bumpmapper: + * Takes a bank and applies light, shadows, highlights + * and stuff to frames that have bumpmap channels. + * (Q: Where do we put bumpmaps? Extend the bank to + * twice the # of frames, using the last half for BMs? + * Use two banks? I think we need an API change that + * make plugins operators; X = A B, where the + * banks X, A and B are arguments.) + * + * * Mixer: + * A plugin that takes two banks and performs various + * operations between them to produce the output. + * + * * Colorizer: + * Converts images to HSV and then replaces hue with + * a fixed color. + * + * * Map Colorizer: + * Like Colorizer, but uses a (wrapping) source image + * as a map to determine the new hue for each pixel. + * + * * Tiled Stretch: + * Given a list of tile interdependencies, generate + * all tiles required for seamless rendering of the + * map for which the interdependency list was generated. + */ +typedef struct s_filter_args_t +{ + int x, y, z; + float fx, fy, fz; + int min, max; + short r, g, b; + int flags; + unsigned bank; + void *data; +} s_filter_args_t; + +typedef int (*s_filter_cb_t)(s_bank_t *b, unsigned first, unsigned frames, + s_filter_args_t *args); + +typedef struct s_filter_t +{ + struct s_filter_t *next; + s_filter_cb_t callback; + s_filter_args_t args; +} s_filter_t; + +s_filter_t *s_insert_filter(s_filter_cb_t callback); +s_filter_t *s_add_filter(s_filter_cb_t callback); +/* callback == NULL means "remove all plugins" */ +void s_remove_filter(s_filter_t *filter); + +/* RGBA pixel type (used internally by most filters as well) */ +typedef struct +{ + Uint8 r; + Uint8 g; + Uint8 b; + Uint8 a; +} pix_t; + +/* + * UURGH!!! This should be OO like the rest... + */ +extern s_blitmodes_t s_blitmode; +extern pix_t s_colorkey; /* NOTE: Alpha is ignored! */ +extern pix_t s_clampcolor; +extern unsigned char s_alpha; +extern int s_filter_flags; /* Global flags; applied to all plugins. */ + +#ifdef __cplusplus +}; +#endif + +#endif /* _SPRITE_H_ */ diff --git a/graphics/toolkit.cpp b/graphics/toolkit.cpp new file mode 100644 index 0000000..d1a1f06 --- /dev/null +++ b/graphics/toolkit.cpp @@ -0,0 +1,764 @@ +/*(LGPL) +--------------------------------------------------------------------------- + toolkit.cpp - Simple "GUI" toolkit for config screens. +--------------------------------------------------------------------------- + * Copyright (C) 2001 David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "config.h" + +#include +#include + +#include "window.h" +#include "toolkit.h" + + + +/*---------------------------------------------------------- + ct_widget_t:: +----------------------------------------------------------*/ + +ct_widget_t::ct_widget_t() +{ + interactive = 0; + transparent = 1; + highlighted = 0; + user = NULL; + user2 = 0; + tag = 0; + _color = 0; + next = prev = NULL; + _widget_index = -1; + halign(ALIGN_DEFAULT); + valign(ALIGN_DEFAULT); + _token = 0; + xo = yo = 0.0; +} + + +void ct_widget_t::halign(ct_align_t ha) +{ + if(ALIGN_DEFAULT == ha) + _halign = ALIGN_RIGHT; + else + _halign = ha; +} + + +void ct_widget_t::valign(ct_align_t va) +{ + if(ALIGN_DEFAULT == va) + _valign = ALIGN_TOP; + else + _valign = va; +} + + +void ct_widget_t::init(gfxengine_t *e) +{ + window_t::init(e); + _color = map_rgb(0,0,0); +} + + +void ct_widget_t::transparency(int t) +{ + if(t == transparent) + return; + + transparent = t; + if(!transparent) + render(); +} + + +void ct_widget_t::highlight(int hl) +{ + if(hl == highlighted) + return; + + highlighted = hl; + if(!transparent) + render(); +} + + +void ct_widget_t::color(Uint32 _cl) +{ + if(_cl == _color) + return; + + _color = _cl; + if(!transparent) + render(); +} + + +void ct_widget_t::render() +{ + if(!transparent) + { + foreground(_color); + fillrect(0, 0, width(), height()); + } + if(highlighted) + ct_engine.render_highlight(this); +} + + +/* Handy tool function used by some descendents. */ +void ct_widget_t::render_text_aligned(const char *buf) +{ + int yy = 0; + switch(_valign) + { + case ALIGN_DEFAULT: //dummy + case ALIGN_NONE: + case ALIGN_TOP: + yy = yoffs(); + break; + case ALIGN_BOTTOM: + yy = height() - fontheight() - yoffs(); + break; + case ALIGN_CENTER: + case ALIGN_CENTER_TOKEN: + yy = (height() - fontheight()) / 2 + yoffs(); + break; + } + switch(_halign) + { + case ALIGN_DEFAULT: //dummy + case ALIGN_NONE: + case ALIGN_LEFT: + string(xoffs(), yy, buf); + break; + case ALIGN_RIGHT: + center_token(width() - xoffs(), yy, buf); + break; + case ALIGN_CENTER: + center_token(xoffs(), yy, buf, -1); + break; + case ALIGN_CENTER_TOKEN: + center_token(xoffs(), yy, buf, _token); + break; + } +} + + +void ct_widget_t::change(int delta) +{ + _value += delta; +} + + +void ct_widget_t::value(int val) +{ + _value = val; +} + + +int ct_widget_t::value() +{ + return _value; +} + + + +/*---------------------------------------------------------- + ct_engine_t:: +----------------------------------------------------------*/ + +void default_render_highlight(ct_widget_t *wg) +{ + Uint32 hlc[6]; + hlc[0] = wg->map_rgb(0x440000); + hlc[1] = wg->map_rgb(0x660000); + hlc[2] = wg->map_rgb(0x880000); + hlc[3] = wg->map_rgb(0x990000); + hlc[4] = wg->map_rgb(0xaa0000); + hlc[5] = wg->map_rgb(0xbb0000); + wg->foreground(hlc[5]); + wg->fillrect(0, 6, wg->width(), wg->height()-6-1); + for(int i = 0; i < 6; ++i) + { + wg->foreground(hlc[i]); + wg->fillrect(0, i, wg->width(), 1); + wg->fillrect(0, wg->height()-1-i, wg->width(), 1); + } +} + + +ct_engine_t::ct_engine_t() +{ + ct_engine.render_highlight = default_render_highlight; +} + + +ct_engine_t ct_engine; + + + +/*---------------------------------------------------------- + ct_label_t:: +----------------------------------------------------------*/ + +ct_label_t::ct_label_t(const char *cap) +{ + xo = 0.5; + if(cap) + caption(cap); + else + caption("Label"); +} + + +void ct_label_t::halign(ct_align_t ha) +{ + if(ALIGN_DEFAULT == ha) + _halign = ALIGN_CENTER; + else + _halign = ha; +} + + +void ct_label_t::caption(const char *cap) +{ + strncpy(_caption, cap, sizeof(_caption)); + _caption[sizeof(_caption)-1] = 0; + if(!transparent) + render(); +} + + +void ct_label_t::render() +{ + ct_widget_t::render(); + render_text_aligned(_caption); +} + + +/*---------------------------------------------------------- + ct_item_t:: +----------------------------------------------------------*/ + +ct_item_t::ct_item_t(const char *cap, int val) +{ + if(cap) + caption(cap); + else + caption("Item"); + _value = val; +} + + +void ct_item_t::caption(const char *cap) +{ + strncpy(_caption, cap, sizeof(_caption)); + _caption[sizeof(_caption)-1] = 0; +} + + +static ct_item_t dummy_item("", -1); + + +/*---------------------------------------------------------- + ct_list_t:: +----------------------------------------------------------*/ + +ct_list_t::ct_list_t(const char *cap) : ct_label_t(cap) +{ + interactive = 1; + if(cap) + caption(cap); + else + caption("List"); + items = NULL; + _selected = NULL; + + _token = ':'; + xo = 0.55; +} + + +ct_list_t::~ct_list_t() +{ + clean(); +} + + +void ct_list_t::halign(ct_align_t ha) +{ + if(ALIGN_DEFAULT == ha) + _halign = ALIGN_CENTER_TOKEN; + else + _halign = ha; +} + + +void ct_list_t::clean() +{ + if(!items) + return; + + /* + * Break the circular list first, or we'll + * blow up the memory manager...! :-) + */ + items->prev->next = NULL; + + while(items) + { + ct_item_t *i = items; + items = i->next; + delete i; + } + + items = NULL; + _selected = NULL; +} + + +void ct_list_t::add(ct_item_t *item) +{ + if(items) + { + item->next = items; + item->prev = items->prev; + items->prev->next = item; + items->prev = item; + } + else + { + item->next = item->prev = item; + items = item; + _selected = item; + if(!transparent) + render(); + } +} + + +void ct_list_t::add(const char *cap, int val) +{ + ct_item_t *it = new ct_item_t(cap, val); + add(it); +} + + +void ct_list_t::select(ct_item_t *item) +{ + _selected = item; +#if 0 + ct_item_t *i = items; + if(i) + for(int n = 0; n < 10000; ++n) //Just in case... + { + if(i == _selected) + { + _value = n; + break; + } + i = i->next; + } +#endif + if(_selected) + _value = _selected->value(); + if(!transparent) + render(); +} + + +void ct_list_t::select(int ind) +{ + if(!items) + return; + + _selected = items; + for(int i = 0; i < ind; ++i) + _selected = _selected->next; + select(_selected); //To update _value, render etc... +} + + +ct_item_t *ct_list_t::selected() +{ + if(!items) + return &dummy_item; + + return _selected; +} + + +void ct_list_t::value(int val) +{ + if(!items) + return; + + ct_item_t *best = items; + _selected = items; + while(_selected->value() != val) + { + if(labs(_selected->value()-val) < labs(best->value()-val)) + best = _selected; + if(_selected->next == items) + break; + _selected = _selected->next; + } + if(_selected->value() != val) + _selected = best; + select(_selected); //To update _value, render etc... +} + + +int ct_list_t::value() +{ + if(!items) + return dummy_item.value(); + if(_selected) + return _selected->value(); + else + return dummy_item.value(); +} + + +void ct_list_t::change(int delta) +{ + if(_selected) + { + if(0 == delta) + delta = 1; + if(delta > 0) + for(int i = 0; i < delta; ++i) + _selected = _selected->next; + else if(delta < 0) + for(int i = 0; i > delta; --i) + _selected = _selected->prev; + select(_selected); //To update _value, render etc... + } + ct_widget_t::change(delta); +} + + +void ct_list_t::render() +{ + char buf[128]; + const char *ic; + if(_selected) + ic = _selected->caption(); + else + ic = dummy_item.caption(); + ct_widget_t::render(); + snprintf(buf, sizeof(buf), "%s: %s", caption(), ic); + //center(0, buf); + //center_token(width()*3/5, 0, buf, ':'); + render_text_aligned(buf); +} + + + +/*---------------------------------------------------------- + ct_spin_t:: +----------------------------------------------------------*/ + +ct_spin_t::ct_spin_t(const char *cap, int _min, int _max, + const char *__unit) : ct_label_t(cap) +{ + interactive = 1; + min = _min; + max = _max; + _token = ':'; + xo = 0.55; + if(__unit) + unit(__unit); + else + unit(""); +} + + +void ct_spin_t::unit(const char *txt) +{ + strncpy(_unit, txt, sizeof(_unit)); + _unit[sizeof(_unit)-1] = 0; + if(!transparent) + render(); +} + + +void ct_spin_t::value(int val) +{ + val -= min; + while(val < 0) + val += max - min + 1; + val %= max - min + 1; + val += min; + ct_label_t::value(val); +} + + +void ct_spin_t::change(int delta) +{ + value(_value + delta); +} + + +void ct_spin_t::render() +{ + char buf[128]; + ct_widget_t::render(); + snprintf(buf, sizeof(buf), "%s: %d %s", caption(), _value, unit()); + //center(0, buf); + //center_token(width()*3/5, 0, buf, ':'); + render_text_aligned(buf); +} + + + +/*---------------------------------------------------------- + ct_button_t:: +----------------------------------------------------------*/ + +ct_button_t::ct_button_t(const char *cap) : ct_label_t(cap) +{ + interactive = 1; +} + + +void ct_button_t::render() +{ + ct_label_t::render(); +} + + +void ct_button_t::change(int delta) +{ + ct_label_t::change(delta); + if(!transparent) + render(); +} + + + +/*---------------------------------------------------------- + ct_form_t:: +----------------------------------------------------------*/ + +ct_form_t::ct_form_t() +{ + widgets = NULL; + _selected = NULL; +} + + +ct_form_t::~ct_form_t() +{ + if(!widgets) + return; + + /* + * Break the circular list first, or we'll + * blow up the memory manager...! :-) + */ + widgets->prev->next = NULL; + + while(widgets) + { + ct_widget_t *i = widgets; + widgets = i->next; + delete i; + } +} + + +void ct_form_t::add(ct_widget_t *widget) +{ + if(widgets) + { + widget->next = widgets; + widget->prev = widgets->prev; + widgets->prev->next = widget; + widgets->prev = widget; + widget->_widget_index = widget->prev->_widget_index + 1; + if(!_selected->interactive) + select(widget); + } + else + { + widget->_widget_index = 0; + widget->next = widget->prev = widget; + widgets = widget; + select(widget); + } + render_nontransparent(); +} + + +void ct_form_t::clean() +{ + if(!widgets) + return; + + /* + * Break the circular list first, or we'll + * blow up the memory manager...! :-) + */ + widgets->prev->next = NULL; + + while(widgets) + { + ct_widget_t *w = widgets; + widgets = w->next; + delete w; + } + + widgets = NULL; + _selected = NULL; +} + + +void ct_form_t::select(ct_widget_t *widget) +{ + if(_selected) + _selected->highlight(0); + _selected = widget; + if(_selected) + { + _selected->highlight(1); + if(!_selected->transparent) + _selected->render(); + } +} + + +void ct_form_t::select(int ind) +{ + if(!widgets) + return; + + if(!widgets) + return; + + ct_widget_t *sel = widgets; + for(int i = 0; i < ind; ++i) + sel = sel->next; + + int lim = 10000; + while(!sel->interactive) + { + if(!lim--) + break; + sel = sel->next; + } + select(sel); +} + + +void ct_form_t::next() +{ + if(!widgets) + return; + + if(!_selected) + { + select(0); + return; + } + + ct_widget_t *sel = _selected->next; + + int lim = 1000; + while(!sel->interactive) + { + if(!lim--) + break; + sel = sel->next; + } + select(sel); +} + + +void ct_form_t::prev() +{ + if(!widgets) + return; + + if(!_selected) + { + select(0); + return; + } + + ct_widget_t *sel = _selected->prev; + + int lim = 1000; + while(!sel->interactive) + { + if(!lim--) + break; + sel = sel->prev; + } + select(sel); +} + + +ct_widget_t *ct_form_t::selected() +{ + return _selected; +} + + +int ct_form_t::selected_index() +{ + if(_selected) + return _selected->_widget_index; + else + return -1; +} + + +void ct_form_t::change(int delta) +{ + if(_selected) + _selected->change(delta); +} + + +void ct_form_t::render() +{ + ct_widget_t *w = widgets; + while(w) + { + w->render(); + w = w->next; + if(w == widgets) + break; //Done! + } +} + + +void ct_form_t::render_nontransparent() +{ + ct_widget_t *w = widgets; + while(w) + { + if(!w->transparent) + w->render(); + w = w->next; + if(w == widgets) + break; //Done! + } +} diff --git a/graphics/toolkit.h b/graphics/toolkit.h new file mode 100644 index 0000000..46de69d --- /dev/null +++ b/graphics/toolkit.h @@ -0,0 +1,196 @@ +/*(LGPL) +--------------------------------------------------------------------------- + toolkit.h - Simple "GUI" toolkit for config screens. +--------------------------------------------------------------------------- + * Copyright (C) 2001, David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Note: change(0) means "apply", and would be the normal + * result of pressing enter while a widget is selected. + */ + +#include "window.h" + +enum ct_align_t +{ + ALIGN_DEFAULT = -1, + ALIGN_NONE = 0, + ALIGN_LEFT, + ALIGN_TOP = ALIGN_LEFT, + ALIGN_RIGHT, + ALIGN_BOTTOM = ALIGN_RIGHT, + ALIGN_CENTER, + ALIGN_CENTER_TOKEN +}; + +class ct_widget_t : public window_t +{ + protected: + friend class ct_form_t; + int interactive; + int transparent; + int highlighted; + Uint32 _color; + int _value; + int _widget_index; + ct_align_t _halign; + ct_align_t _valign; + char _token; + float xo, yo; //[0,1] maps to [0,width()]! + virtual void render(); + void render_text_aligned(const char *buf); + public: + ct_widget_t *next, *prev; //*CIRCULAR* list! + void *user; //user stuff + int user2; //user stuff + int tag; //user stuff + ct_widget_t(); + virtual void init(gfxengine_t *e); + void transparency(int t); + void highlight(int hl); + void color(Uint32 _cl); + virtual void change(int delta); + virtual void value(int val); + virtual int value(); + + //Contents alignment modes. + virtual void halign(ct_align_t ha); + virtual void valign(ct_align_t va); + ct_align_t halign() { return _halign; } + ct_align_t valign() { return _valign; } + + //Token and offsets- used by some alignment modes. + virtual void token(char tok) { _token = tok; } + char token() { return _token; } + virtual void offset(float x, float y) { xo = x; yo = y; } + int xoffs() { return (int)(xo * width()); } + int yoffs() { return (int)(yo * height()); } + float rxoffs() { return xo; } + float ryoffs() { return yo; } +}; + + +class ct_engine_t +{ + public: + ct_engine_t(); + void (*render_highlight)(ct_widget_t *wg); +}; + +extern ct_engine_t ct_engine; + + +class ct_label_t : public ct_widget_t +{ + protected: + char _caption[64]; + void render(); + public: + ct_label_t(const char *cap = NULL); + void caption(const char *cap); + const char *caption() { return _caption; } + virtual void halign(ct_align_t ha); +}; + + +class ct_item_t +{ + protected: + char _caption[64]; + int _index; + int _value; + public: + ct_item_t *next, *prev; //*CIRCULAR* list! + ct_item_t(const char *cap = NULL, int val = 0); + void caption(const char *cap); + const char *caption() { return _caption; } + void value(int val) { _value = val; } + int value() { return _value; } + void index(int i) { _index = i; } + int index() { return _index; } +}; + +class ct_list_t : public ct_label_t +{ + protected: + ct_item_t *items; + ct_item_t *_selected; + void render(); + public: + ct_list_t(const char *cap = NULL); + virtual ~ct_list_t(); + void add(ct_item_t *item); + void add(const char *cap, int val); + void clean(); + void select(ct_item_t *item); + void select(int ind); + ct_item_t *selected(); + void value(int val); + int value(); + void change(int delta); + virtual void halign(ct_align_t ha); +}; + + +class ct_spin_t : public ct_label_t +{ + protected: + int min; + int max; + char _unit[32]; + void render(); + public: + ct_spin_t(const char *cap = NULL, int _min = 0, int _max = 99999, + const char *__unit = NULL); + void value(int val); + void change(int delta); + void unit(const char *txt); + const char *unit() { return _unit; } +}; + + +class ct_button_t : public ct_label_t +{ + protected: + void render(); + public: + ct_button_t(const char *cap = NULL); + void change(int delta); +}; + + +class ct_form_t : public window_t +{ + protected: + ct_widget_t *widgets; + ct_widget_t *_selected; + public: + ct_form_t(); + virtual ~ct_form_t(); + void add(ct_widget_t *w); + void clean(); + virtual void select(ct_widget_t *w); + virtual void select(int ind); + virtual void next(); + virtual void prev(); + ct_widget_t *selected(); + int selected_index(); + void render(); + void render_nontransparent(); + virtual void change(int delta); +}; diff --git a/graphics/vidmodes.c b/graphics/vidmodes.c new file mode 100644 index 0000000..77403a0 --- /dev/null +++ b/graphics/vidmodes.c @@ -0,0 +1,193 @@ +/*(LGPL) +--------------------------------------------------------------------------- + vidmodes.c - Video Mode Manager for Kobo Deluxe +--------------------------------------------------------------------------- + * Copyright (C) 2007 David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "vidmodes.h" +#include +#include + +typedef struct VMM_IMode +{ + int flags, width, height, id; + const char *name; +} VMM_IMode; + +static VMM_IMode modetab[] = +{ + // 4:3 modes + {VMM_4_3 | VMM_PC, 320, 200, 0x04300, "CGA"}, + {VMM_4_3 | VMM_PC, 320, 240, 0x04301, "QVGA"}, + {VMM_4_3, 320, 256, 0x04302, "Amiga LoRes"}, + {VMM_4_3 | VMM_LORES, 400, 300, 0x04310, NULL}, + {VMM_4_3 | VMM_LORES, 512, 384, 0x04320, NULL}, + {VMM_4_3 | VMM_PC, 640, 480, 0x04330, "VGA"}, + {VMM_4_3, 640, 512, 0x04331, "Amiga HiRes"}, + {VMM_4_3 | VMM_TV, 768, 576, 0x04340, "PAL"}, + {VMM_4_3 | VMM_PC, 800, 600, 0x04350, NULL}, + {VMM_4_3 | VMM_LORES, 960, 720, 0x04360, NULL}, + {VMM_4_3 | VMM_PC, 1024, 768, 0x04370, "XGA"}, + {VMM_4_3 | VMM_PC, 1152, 864, 0x04380, NULL}, + {VMM_4_3 | VMM_PC, 1280, 960, 0x04390, NULL}, + {VMM_4_3 | VMM_PC, 1400, 1050, 0x043a0, "SXGA+"}, + {VMM_4_3 | VMM_PC, 1600, 1200, 0x043b0, "UXGA"}, + {VMM_4_3 | VMM_PC, 1920, 1440, 0x043c0, NULL}, + {VMM_4_3 | VMM_PC, 2048, 1536, 0x043d0, "QXGA"}, + + // 3:2 modes + {VMM_3_2 | VMM_LORES, 360, 240, 0x03200, NULL}, + {VMM_3_2 | VMM_LORES, 720, 480, 0x03240, "NTSC"}, + {VMM_3_2, 1152, 768, 0x03280, NULL}, + {VMM_3_2, 1280, 854, 0x03290, NULL}, + {VMM_3_2, 1440, 960, 0x032a0, NULL}, + + // 5:4 modes + {VMM_5_4 | VMM_LORES, 320, 256, 0x05400, "Amiga LoRes"}, + {VMM_5_4 | VMM_LORES, 640, 512, 0x05430, "Amiga HiRes"}, + {VMM_5_4 | VMM_PC, 1280, 1024, 0x05490, "SXGA"}, + {VMM_5_4, 2560, 2048, 0x054e0, "QSXGA"}, + + // 16:10 modes + {VMM_16_10 | VMM_LORES, 320, 200, 0x10a00, NULL}, + {VMM_16_10 | VMM_PC, 640, 400, 0x10a30, NULL}, + {VMM_16_10 | VMM_LORES, 840, 525, 0x10a50, NULL}, + {VMM_16_10 | VMM_PC, 1280, 800, 0x10a90, NULL}, + {VMM_16_10 | VMM_PC, 1680, 1050, 0x10ab0, "WSXGA+"}, + {VMM_16_10 | VMM_PC, 1920, 1200, 0x10ac0, "WUXGA"}, + {VMM_16_10 | VMM_PC, 2560, 1600, 0x10ae0, "WQXGA"}, + + // 16:9 modes + {VMM_16_9 | VMM_LORES, 480, 270, 0x10910, NULL}, + {VMM_16_9 | VMM_LORES, 678, 384, 0x10930, NULL}, + {VMM_16_9 | VMM_TV, 854, 480, 0x10950, "WVGA"}, + {VMM_16_9 | VMM_LORES, 960, 540, 0x10960, NULL}, + {VMM_16_9, 1280, 720, 0x10990, "HD 720"}, + {VMM_16_9 | VMM_TV, 1356, 768, 0x109a0, "Flat TV"}, + {VMM_16_9 | VMM_TV, 1920, 1080, 0x109c0, "HD 1080"}, + {VMM_16_9, 2560, 1440, 0x109e0, NULL}, + + // End of table + {0, 0, 0} +}; + + +/*------------------------------------------------------------------------- + Gathering and constructing modes +-------------------------------------------------------------------------*/ + +static VMM_Mode *vmm_modes = NULL; + +int vmm_Init(int show, int hide) +{ + int i; + VMM_Mode *lastm = NULL; + vmm_Close(); + +/* +TODO: Include detected SDL modes, if requested. + */ + + for(i = 0; modetab[i].width; ++i) + { + VMM_Mode *m; + double nominal_aspect; + VMM_IMode *im = &modetab[i]; + if(im->flags & hide) + continue; + if(!(im->flags & show)) + continue; + m = calloc(1, sizeof(VMM_Mode)); + if(!m) + return -1; /* Out of memory! */ + m->id = im->id; + m->width = im->width; + m->height = im->height; + m->flags = im->flags; + if(im->flags & VMM_3_2) + nominal_aspect = 3.0f / 2.0f; + else if(im->flags & VMM_5_4) + nominal_aspect = 5.0f / 4.0f; + else if(im->flags & VMM_16_10) + nominal_aspect = 16.0f / 10.0f; + else if(im->flags & VMM_16_9) + nominal_aspect = 16.0f / 9.0f; + else + nominal_aspect = 4.0f / 3.0f; + if(im->width) + m->aspect = nominal_aspect / im->width * im->height; + else + m->aspect = 1.0f; + if(im->name) + m->name = strdup(im->name); + if(lastm) + lastm->next = m; + else + vmm_modes = m; + lastm = m; + } + + return 0; +} + + +void vmm_Close(void) +{ + VMM_Mode *m = vmm_First(); + while(m) + { + VMM_Mode *dm = m; + m = vmm_Next(m); + free(dm->name); + free(dm); + } + vmm_modes = NULL; +} + + +/*------------------------------------------------------------------------- + Scanning +-------------------------------------------------------------------------*/ + +VMM_Mode *vmm_First(void) +{ + return vmm_modes; +} + + +VMM_Mode *vmm_Next(VMM_Mode *current) +{ + return current->next; +} + + +/*------------------------------------------------------------------------- + Indexing +-------------------------------------------------------------------------*/ + +VMM_Mode *vmm_FindMode(int id) +{ + VMM_Mode *m = vmm_First(); + while(m) + { + if(m->id == id) + return m; + m = vmm_Next(m); + } + return NULL; +} diff --git a/graphics/vidmodes.h b/graphics/vidmodes.h new file mode 100644 index 0000000..f7da560 --- /dev/null +++ b/graphics/vidmodes.h @@ -0,0 +1,93 @@ +/*(LGPL) +--------------------------------------------------------------------------- + vidmodes.h - Video Mode Manager for Kobo Deluxe +--------------------------------------------------------------------------- + * Copyright (C) 2007 David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef KOBO_VIDMODES_H +#define KOBO_VIDMODES_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/*------------------------------------------------------------------------- + Data Types and Structures +-------------------------------------------------------------------------*/ + +typedef enum +{ + VMM_ALL = 0xffffffff, + VMM_DETECT = 0x00000001, /* Available modes as detected by SDL */ + VMM_4_3 = 0x00000010, /* 4:3 modes */ + VMM_3_2 = 0x00000020, /* 3:2 modes */ + VMM_5_4 = 0x00000040, /* 5:4 modes */ + VMM_16_10 = 0x00000080, /* 16:10 modes */ + VMM_16_9 = 0x00000100, /* 16:9 modes */ + VMM_PC = 0x00010000, /* Standard PC/Mac modes */ + VMM_WPC = 0x00020000, /* Widescreen PC/Mac modes */ + VMM_TV = 0x00040000, /* Standard TV modes */ + VMM_WTV = 0x00080000, /* Widescreen TV modes */ + VMM_LORES = 0x10000000 /* Special low resolution modes */ +} VMM_Flags; + + +typedef struct VMM_Mode VMM_Mode; +struct VMM_Mode +{ + VMM_Mode *next; /* Next mode in list */ + char *name; /* Name, if any */ + int id; /* Somewhat constant mode ID */ + int width; /* Display width in pixels */ + int height; /* Display height in pixels */ + int flags; /* (WMM_Flags) */ + float aspect; /* Pixel aspect ratio */ +}; + + +/*------------------------------------------------------------------------- + Gathering and constructing modes +-------------------------------------------------------------------------*/ +int vmm_Init(int show, int hide); +void vmm_Close(void); + + +/*------------------------------------------------------------------------- + Scanning +-------------------------------------------------------------------------*/ +VMM_Mode *vmm_First(void); +VMM_Mode *vmm_Next(VMM_Mode *current); + + +/*------------------------------------------------------------------------- + Indexing +-------------------------------------------------------------------------*/ +VMM_Mode *vmm_FindMode(int id); + + +/*------------------------------------------------------------------------- + Searching +-------------------------------------------------------------------------*/ +/* TODO: VMM_Mode *vmm_Find(int width, int height, int aspect); */ + +#ifdef __cplusplus +}; +#endif + +#endif /* KOBO_VIDMODES_H */ diff --git a/graphics/window.cpp b/graphics/window.cpp new file mode 100644 index 0000000..9a889c7 --- /dev/null +++ b/graphics/window.cpp @@ -0,0 +1,654 @@ +/*(LGPL) +--------------------------------------------------------------------------- + window.cpp - Generic Rendering Window +--------------------------------------------------------------------------- + * Copyright (C) 2001-2003, 2006, 2007 David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "logger.h" +#include "window.h" +#include "gfxengine.h" +#include "sofont.h" + +#define SELECT if(selected != this) _select(); + +window_t *window_t::selected = NULL; + +window_t::window_t() +{ + engine = NULL; + surface = NULL; + next = NULL; + prev = NULL; + phys_rect.x = phys_rect.y = 0; + phys_rect.w = 320; + phys_rect.h = 240; + fgcolor = bgcolor = 0; + selected = 0; + xs = ys = 256; + bg_bank = -1; + bg_frame = -1; + _visible = 1; + _offscreen = 0; +} + + +window_t::~window_t() +{ + if(_offscreen && surface) + SDL_FreeSurface(surface); + if(selected == this) + selected = NULL; + unlink(); +} + + +void window_t::init(gfxengine_t *e) +{ + link(e); + xs = engine->xs; + ys = engine->ys; + if(_offscreen && surface) + { + SDL_FreeSurface(surface); + surface = NULL; + } + _offscreen = 0; + surface = engine->surface(); +} + + +void window_t::visible(int vis) +{ + if(_offscreen) + return; // Cannot be visible! + if(_visible == vis) + return; + _visible = vis; + invalidate(); +} + + +void window_t::link(gfxengine_t *e) +{ + unlink(); + engine = e; + next = NULL; + prev = engine->windows; + if(prev) + { + while(prev->next) + prev = prev->next; + prev->next = this; + } + else + engine->windows = this; +} + + +void window_t::unlink(void) +{ + if(engine) + { + if(engine->windows == this) + engine->windows = next; + if(engine->surface() == surface) + surface = NULL; + } + if(next) + next->prev = prev; + if(prev) + prev->next = next; +} + + +void window_t::place(int left, int top, int sizex, int sizey) +{ + int x2 = ((left + sizex) * xs + 128) >> 8; + int y2 = ((top + sizey) * ys + 128) >> 8; + phys_rect.x = (left * xs + 128) >> 8; + phys_rect.y = (top * ys + 128) >> 8; + phys_rect.w = x2 - phys_rect.x; + phys_rect.h = y2 - phys_rect.y; +} + + +int window_t::offscreen() +{ + if(!engine) + return -1; + if(!engine->surface()) + return -1; + if(_offscreen) + return 0; // Already offscreen! + visible(0); + _offscreen = 1; + SDL_Surface *s = SDL_CreateRGBSurface(SDL_SWSURFACE, + phys_rect.w, phys_rect.h, + 32, 0xff000000, 0x00ff0000, + 0x0000ff00, 0x000000ff); + if(!s) + return -1; + surface = SDL_DisplayFormat(s); + SDL_FreeSurface(s); + if(!surface) + return -1; + return 0; +} + + +void window_t::select() +{ + if(engine) + _select(); +} + + +void window_t::_select() +{ + SDL_Rect r = phys_rect; + selected = this; + if(surface) + SDL_SetClipRect(surface, &r); +} + + +void window_t::invalidate(SDL_Rect *r) +{ + if(!engine) + return; + if(!engine->surface()) + return; + + SELECT + + if(_offscreen) + { + if(!r) + { + SDL_Rect rr; + rr.x = 0; + rr.y = 0; + rr.w = phys_rect.w; + rr.h = phys_rect.h; + phys_refresh(&rr); + glSDL_Invalidate(surface, &rr); + } + else + { + phys_refresh(r); + glSDL_Invalidate(surface, r); + } + return; + } + + if(!r) + engine->invalidate(&phys_rect, this); + else + { + /* Translate to screen coordinates */ + SDL_Rect dr = *r; + dr.x = (dr.x * xs + 128) >> 8; + dr.y = (dr.y * ys + 128) >> 8; + dr.w = (((dr.w + dr.x) * xs + 128) >> 8) - dr.x; + dr.h = (((dr.h + dr.y) * ys + 128) >> 8) - dr.y; + dr.x += phys_rect.x; + dr.y += phys_rect.y; + + /* Clip to window (stolen from SDL_surface.c) */ + int Amin, Amax, Bmin, Bmax; + + /* Horizontal intersection */ + Amin = dr.x; + Amax = Amin + dr.w; + Bmin = phys_rect.x; + Bmax = Bmin + phys_rect.w; + if(Bmin > Amin) + Amin = Bmin; + dr.x = Amin; + if(Bmax < Amax) + Amax = Bmax; + dr.w = Amax - Amin > 0 ? Amax - Amin : 0; + + /* Vertical intersection */ + Amin = dr.y; + Amax = Amin + dr.h; + Bmin = phys_rect.y; + Bmax = Bmin + phys_rect.h; + if(Bmin > Amin) + Amin = Bmin; + dr.y = Amin; + if(Bmax < Amax) + Amax = Bmax; + dr.h = Amax - Amin > 0 ? Amax - Amin : 0; + + if(dr.w && dr.h) + engine->invalidate(&dr, this); + } +} + + +/*--------------------------------------------------------------- + Rendering API +---------------------------------------------------------------*/ + +Uint32 window_t::map_rgb(Uint8 r, Uint8 g, Uint8 b) +{ + if(!engine) + return 0; + + if(surface) + return SDL_MapRGB(surface->format, r, g, b); + else + return 0xffffff; +} + +Uint32 window_t::map_rgb(Uint32 rgb) +{ + if(!engine) + return 0; + + Uint8 r = (rgb >> 16) & 0xff; + Uint8 g = (rgb >> 8) & 0xff; + Uint8 b = rgb & 0xff; + + if(surface) + return SDL_MapRGB(surface->format, r, g, b); + else + return 0xffffff; +} + +void window_t::bgimage(int bank, int frame) +{ + bg_bank = bank; + bg_frame = frame; +} + + +void window_t::colorkey(Uint32 color) +{ + if(!engine) + return; + if(!engine->surface()) + return; + if(!_offscreen) + return; + SDL_SetColorKey(surface, SDL_SRCCOLORKEY, color); +} + +void window_t::colorkey() +{ + if(!engine) + return; + if(!engine->surface()) + return; + if(!_offscreen) + return; + SDL_SetColorKey(surface, 0, 0); +} + +void window_t::alpha(float a) +{ + if(!engine) + return; + if(!engine->surface()) + return; + if(!_offscreen) + return; + SDL_SetAlpha(surface, SDL_SRCALPHA, (int)(a * 255.0)); +} + + +void window_t::font(int fnt) +{ + _font = fnt; +} + + +void window_t::string(int _x, int _y, const char *txt) +{ + string_fxp(PIXEL2CS(_x), PIXEL2CS(_y), txt); +} + + +void window_t::center(int _y, const char *txt) +{ + center_fxp(PIXEL2CS(_y), txt); +} + + +void window_t::center_token(int _x, int _y, const char *txt, char token) +{ + center_token_fxp(PIXEL2CS(_x), PIXEL2CS(_y), txt, token); +} + + +void window_t::string_fxp(int _x, int _y, const char *txt) +{ + if(!engine) + return; + + _x = CS2PIXEL((_x * xs + 128) >> 8); + _y = CS2PIXEL((_y * ys + 128) >> 8); + SoFont *f = engine->get_font(_font); + if(!f) + return; + SELECT + _x += phys_rect.x; + _y += phys_rect.y; + if(surface) + f->PutString(surface, _x, _y, txt); +} + + +void window_t::center_fxp(int _y, const char *txt) +{ + _y = CS2PIXEL((_y * ys + 128) >> 8); + + if(!engine) + return; + + SoFont *f = engine->get_font(_font); + if(!f) + return; + SELECT + int _x = (phys_rect.w - f->TextWidth(txt) + 1) / 2; + _x += phys_rect.x; + _y += phys_rect.y; + if(surface) + f->PutString(surface, _x, _y, txt); +} + + +void window_t::center_token_fxp(int _x, int _y, const char *txt, char token) +{ + _x = CS2PIXEL((_x * xs + 128) >> 8); + _y = CS2PIXEL((_y * ys + 128) >> 8); + + if(!engine) + return; + + SoFont *f = engine->get_font(_font); + if(!f) + return; + SELECT + int _cx; + if(-1 == token) + _cx = _x - f->TextWidth(txt)/2; + else + { + int tokpos; + /* + * My docs won't say if strchr(???, 0) is legal + * or even defined, so I'm not taking any chances... + */ + if(token) + { + char *tok = strchr(txt, token); + if(tok) + tokpos = tok-txt; + else + tokpos = 255; + } + else + tokpos = 255; + _cx = _x - f->TextWidth(txt, 0, tokpos); + } + _cx += phys_rect.x; + _y += phys_rect.y; + if(surface) + f->PutString(surface, _cx, _y, txt); +} + + +int window_t::textwidth_fxp(const char *txt, int min, int max) +{ + if(!engine) + return strlen(txt); + + SoFont *f = engine->get_font(_font); + if(!f) + return strlen(txt); + + return (f->TextWidth(txt, min, max) << 16) / xs; +} + + +int window_t::textwidth(const char *txt, int min, int max) +{ + if(!engine) + return strlen(txt); + + SoFont *f = engine->get_font(_font); + if(!f) + return strlen(txt); + + return (f->TextWidth(txt, min, max) << 8) / xs; +} + + +int window_t::fontheight() +{ + if(!engine) + return 1; + + SoFont *f = engine->get_font(_font); + if(!f) + return 1; + + return (f->FontHeight() * 256) / ys; +} + + +void window_t::clear(SDL_Rect *r) +{ + SDL_Rect sr, dr; + if(!engine) + return; + if(!surface) + return; + SELECT + if(!r) + { + sr = phys_rect; + sr.x = 0; + sr.y = 0; + dr = phys_rect; + } + else + { + sr.x = ((int)r->x * xs + 128) >> 8; + sr.y = ((int)r->y * ys + 128) >> 8; + sr.w = (((int)(r->x + r->w) * xs + 128) >> 8) - sr.x; + sr.h = (((int)(r->y + r->h) * ys + 128) >> 8) - sr.y; + dr = sr; + dr.x += phys_rect.x; + dr.y += phys_rect.y; + } + if((-1 == bg_bank) && (-1 == bg_frame)) + SDL_FillRect(surface, &dr, bgcolor); + else + { + s_sprite_t *s = engine->get_sprite(bg_bank, bg_frame); + if(!s || !s->surface) + { + SDL_FillRect(surface, &dr, bgcolor); + return; + } + SDL_BlitSurface(s->surface, &sr, surface, &dr); + } +} + + +void window_t::point(int _x, int _y) +{ + int x2 = ((_x + 1) * xs + 128) >> 8; + int y2 = ((_y + 1) * ys + 128) >> 8; + _x = (_x * xs + 128) >> 8; + _y = (_y * ys + 128) >> 8; + + if(!engine) + return; + SELECT + /* Quick hack; slow */ + SDL_Rect r; + r.x = phys_rect.x + _x; + r.y = phys_rect.y + _y; + r.w = x2 - _x; + r.h = y2 - _y; + if(surface) + SDL_FillRect(surface, &r, fgcolor); +} + + +void window_t::fillrect(int _x, int _y, int w, int h) +{ + int x2 = ((_x + w) * xs + 128) >> 8; + int y2 = ((_y + h) * ys + 128) >> 8; + _x = (_x * xs + 128) >> 8; + _y = (_y * ys + 128) >> 8; + + if(!engine) + return; + SELECT + SDL_Rect r; + r.x = phys_rect.x + _x; + r.y = phys_rect.y + _y; + r.w = x2 - _x; + r.h = y2 - _y; + if(surface) + SDL_FillRect(surface, &r, fgcolor); +} + + +void window_t::rectangle(int _x, int _y, int w, int h) +{ + fillrect(_x, _y, w, 1); + fillrect(_x, _y + h - 1, w, 1); + fillrect(_x, _y + 1, 1, h - 2); + fillrect(_x + w - 1, _y + 1, 1, h - 2); +} + + +void window_t::fillrect_fxp(int _x, int _y, int w, int h) +{ + int xx = CS2PIXEL((_x * xs + 128) >> 8); + int yy = CS2PIXEL((_y * ys + 128) >> 8); + w = CS2PIXEL(((w + _x) * xs + 128) >> 8) - xx; + h = CS2PIXEL(((h + _y) * ys + 128) >> 8) - yy; + + if(!engine) + return; + SELECT + SDL_Rect r; + r.x = phys_rect.x + xx; + r.y = phys_rect.y + yy; + r.w = w; + r.h = h; + if(surface) + SDL_FillRect(surface, &r, fgcolor); +} + + +void window_t::sprite(int _x, int _y, int bank, int frame, int inval) +{ + sprite_fxp(PIXEL2CS(_x), PIXEL2CS(_y), bank, frame, inval); +} + + +void window_t::sprite_fxp(int _x, int _y, int bank, int frame, int inval) +{ + if(!engine) + return; + s_sprite_t *s = engine->get_sprite(bank, frame); + if(!s || !s->surface) + return; + _x = CS2PIXEL(((_x - (s->x << 8)) * xs + 128) >> 8); + _y = CS2PIXEL(((_y - (s->y << 8)) * ys + 128) >> 8); + SDL_Rect dest_rect; + + SELECT + dest_rect.x = phys_rect.x + _x; + dest_rect.y = phys_rect.y + _y; + if(surface) + SDL_BlitSurface(s->surface, NULL, surface, &dest_rect); + + if(inval && !engine->autoinvalidate()) + { + dest_rect.w = s->surface->w; + dest_rect.h = s->surface->h; + engine->invalidate(&dest_rect, this); + } +} + + +void window_t::blit(int dx, int dy, + int sx, int sy, int sw, int sh, window_t *src) +{ + if(!engine) + return; + if(!src) + return; + if(!surface) + return; + if(!src->surface) + return; + SELECT + + SDL_Rect src_rect; + int sx2 = ((sx + sw) * xs + 128) >> 8; + int sy2 = ((sy + sh) * ys + 128) >> 8; + src_rect.x = (sx * xs + 128) >> 8; + src_rect.y = (sy * ys + 128) >> 8; + src_rect.w = sx2 - src_rect.x; + src_rect.h = sy2 - src_rect.y; + + SDL_Rect dest_rect; + dest_rect.x = phys_rect.x + ((dx * xs + 128) >> 8); + dest_rect.y = phys_rect.y + ((dy * ys + 128) >> 8); + + SDL_BlitSurface(src->surface, &src_rect, surface, &dest_rect); +} + + +void window_t::blit(int dx, int dy, window_t *src) +{ + if(!engine) + return; + if(!src) + return; + if(!surface) + return; + if(!src->surface) + return; + + SELECT + dx = (dx * xs + 128) >> 8; + dy = (dy * ys + 128) >> 8; + + SDL_Rect src_rect; + src_rect.x = 0; + src_rect.y = 0; + src_rect.w = src->surface->w; + src_rect.h = src->surface->h; + + SDL_Rect dest_rect; + dest_rect.x = phys_rect.x + dx; + dest_rect.y = phys_rect.y + dy; + + SDL_BlitSurface(src->surface, &src_rect, surface, &dest_rect); +} diff --git a/graphics/window.h b/graphics/window.h new file mode 100644 index 0000000..702ec1d --- /dev/null +++ b/graphics/window.h @@ -0,0 +1,339 @@ +/*(LGPL) +--------------------------------------------------------------------------- + window.h - Generic Rendering Window +--------------------------------------------------------------------------- + * Copyright (C) 2001-2003, 2007 David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Programmer's Documentation: + * The window_t class represents a simple window of the + * screen surface. It provides some high level rendering + * functions that operate inside the window's bounding + * rectangle. All operations are clipped. However, + * window occlusion is *not* handled, so you can't use + * this class for "real" windows. + * + * virtual void init(gfxengine_t *e); + * Call this to connect a window_t instance to + * the gfxengine_t instance that manages your + * screen. You *must* call this for pretty much + * any other calls to work. + * + * void place(int left, int top, int sizex, int sizey); + * Position the window on the screen. + * + * int offscreen(); + * Make this an off-screen window, with a + * surface of it's own for rendering. An off- + * screen window will never be directly visible, + * but can be used as a source window for blit(). + * May return -1 if there is an error. + * + * void select(); + * Makes this window active, and sets up SDL's + * clipping appropriately. You should not use + * this call normally, but it's provided to + * allow this engine to interface with other + * SDL code. + * + * void invalidate(SDL_Rect *r = NULL); + * Invalidate the specified area, or the whole + * window if r is NULL. This will ensure that + * any changes in the invalidated area are made + * visible on the screen. Note that this call + * may also indirectly cause one or more calls + * to refresh(). + * + * virtual void refresh(SDL_Rect *r); + * Virtual refresh call to be implemented by + * windows that aren't repainted every frame. + * After a call to invalidate(), refresh() will + * be called by the engine as necessary to + * produce a correct display. Note that in some + * cases, this means that refresh() will be + * called once for each screen flip, until all + * buffers (usually two) are up to date. Also + * note that you should do all rendering to the + * window either directly *or* in the refresh() + * function. + * + * Uint32 map_rgb(Uint8 r, Uint8 g, Uint8 b); + * Uint32 map_rgb(Uint32 rgb); + * Two different ways of translating a color in + * standard RGB format (separate components or + * HTML style hex code, respectively) into a + * pixel value compatible with the screen. + * + * void foreground(Uint32 color); + * void background(Uint32 color); + * Change the foreground and background colors + * used by subsequent rendering operations. + * Note that the arguments have to be in screen + * pixel format - the easiest way is to use the + * map_rgb() calls to generate the values. + * + * void bgimage(int bank, int frame); + * Select a background image, to use instead of + * a background color. Setting bank and frame to + * -1 (default) disables the image, so that the + * background color is used instead. + * + * void colorkey(Uint32 color); + * void colorkey(); + * Set the colorkey for this window to 'color' + * and enable colorkeying. This affects blit() + * when this window is used as the source. The + * version without arguments disables + * colorkeying for this window. + * NOTE: Colorkeying is only supported by + * offscreen windows. + * + * void alpha(float a); + * Set the full surface alpha of this window. + * 0.0 is fully transparent and 1.0 is opaque. + * NOTE: Alpha is only supported by offscreen + * windows. + * + * void clear(SDL_Rect *r = NULL); + * Fill the specified rectangle with the current + * background color or background image. If r is + * NULL (default), clear the whole window. + * + * void font(int fnt); + * Select the font to be used for subsequent + * text rendering operations. The argument is a + * gfxengine_t bank index, and must refer to a + * bank that has been loaded with + * gfxengine_t::loadfont(). + * + * void string(int _x, int _y, const char *txt); + * Put text string 'txt' starting at (_x, _y). + * + * void center(int _y, const char *txt); + * Put text string 'txt' centered horizontally + * inside the window, using '_y' as the y coord. + * + * void center_token(int _x, int _y, const char *txt, char token = 0); + * Print string 'txt', positioning it so that + * the first occurrence of character 'token' + * is located at (_x, _y). Omitting the 'token' + * argument, or passing 0 aligns the end of the + * string with _x. Setting 'token' to -1 results + * in the graphical center of the string being + * located at (_x, _y) - basically an advanced + * version of center(). + * + * void string_fxp(int _x, int _y, const char *txt); + * void center_fxp(int _y, const char *txt); + * void center_token_fxp(int _x, int _y, const char *txt, char token = 0); + * gfxengine_t fixed point format versions of + * the corresponding non-fxp calls. (For sub- + * pixel accurate rendering and/or to make use + * of the higher resolutions in scaled modes.) + * + * int textwidth(const char *txt, int min = 0, int max = 255); + * Calculates the graphical width of 'txt' if it + * was to be printed with the current font. + * Calculation starts at position 'min' in the + * string, and ends at 'max', which makes it + * possible to use this call for various + * advanced alignment calculations. + * + * int fontheight(); + * Returns the height of the currently selected + * font. + * + * void point(int _x, int _y); + * Plot a pixel with the current foreground + * color at (_x, _y). Note that the pixel will + * become a quadratic block if the screen is + * scaled to a higher resolution. + * + * void rectangle(int _x, int _y, int w, int h); + * Draw a hollow rectangle of w x h pixels at + * (_x, _y). The line thickness is scaled along + * with screen resolution, as with point(). + * + * void fillrect(int _x, int _y, int w, int h); + * Draw a solid rectangle of w x h pixels at + * (_x, _y). + * + * void fillrect_fxp(int _x, int _y, int w, int h); + * As fillrect(), but with pixel or sub-pixel + * accuracy, depending on scaling and video + * driver. + * + * void sprite(int _x, int _y, int bank, int frame, int inval = 1); + * Render sprite 'bank':'frame' at (_x, _y). If + * inval is passed and set to 0, the affected + * area will *not* be invalidated automatically. + * + * void sprite_fxp(int _x, int _y, int bank, int frame, int inval = 1); + * As sprite(), but with pixel or sub-pixel + * accuracy, depending on scaling and video + * driver. + * + * void blit(int dx, int dy, window_t *src); + * Blit from window 'src' into this window, placing + * the top left corner of 'src' at (dx, dy). + * + * void blit(int dx, int dy, int sx, int sy, int sw, int sh, window_t *src); + * Blit rectangle (sx, sy, sw, sh) from window 'src' + * into this window, placing the top left corner of + * 'src' at (dx, dy). + * + * int x() { return rect.x / xsc; } + * int y() { return rect.y / ysc; } + * int width() { return rect.w / xsc; } + * int height() { return rect.h / ysc; } + * Get the current screen position of the + * window's top-left corner, and it's size. + * + * int x2() { return (rect.x + rect.w) / xsc; } + * int y2() { return (rect.y + rect.h) / ysc; } + * Get the screen position of the bottom-right + * corner of the window. + */ + +#ifndef _WINDOW_H_ +#define _WINDOW_H_ + +#include "glSDL.h" + +class gfxengine_t; + +class window_t +{ + friend class gfxengine_t; + public: + window_t(); + window_t(gfxengine_t *e); + virtual ~window_t(); + + virtual void init(gfxengine_t *e); + void place(int left, int top, int sizex, int sizey); + int offscreen(); + void visible(int vis); + int visible() { return _visible; } + void select(); + void invalidate(SDL_Rect *r = NULL); + virtual void refresh(SDL_Rect *r) { ; } + + /* Color tools */ + Uint32 mulrgb(Uint32 c1, Uint32 c2) + { + int r = ((c1 >> 16) & 0xff) * ((c2 >> 16) & 0xff) * 258 >> 16; + int g = ((c1 >> 8) & 0xff) * ((c2 >> 8) & 0xff) * 258 >> 16; + int b = (c1 & 0xff) * (c2 & 0xff) * 258 >> 16; + return r << 16 | g << 8 | b; + } + Uint32 fadergb(Uint32 rgb, Uint8 fade) + { + int r = ((rgb >> 16) & 0xff) * fade * 258 >> 16; + int g = ((rgb >> 8) & 0xff) * fade * 258 >> 16; + int b = (rgb & 0xff) * fade * 258 >> 16; + return r << 16 | g << 8 | b; + } + + /* Rendering */ + Uint32 map_rgb(Uint8 r, Uint8 g, Uint8 b); + Uint32 map_rgb(Uint32 rgb); + void foreground(Uint32 color) { fgcolor = color; } + void background(Uint32 color) { bgcolor = color; }; + + void bgimage(int bank = -1, int frame = -1); + void colorkey(Uint32 color); + void colorkey(); + void alpha(float a); + + void clear(SDL_Rect *r = NULL); + void font(int fnt); + void string(int _x, int _y, const char *txt); + void center(int _y, const char *txt); + void center_token(int _x, int _y, const char *txt, char token = 0); + void string_fxp(int _x, int _y, const char *txt); + void center_fxp(int _y, const char *txt); + void center_token_fxp(int _x, int _y, const char *txt, char token = 0); + int textwidth(const char *txt, int min = 0, int max = 255); + int textwidth_fxp(const char *txt, int min = 0, int max = 255); + int fontheight(); + + void point(int _x, int _y); + void rectangle(int _x, int _y, int w, int h); + void fillrect(int _x, int _y, int w, int h); + void fillrect_fxp(int _x, int _y, int w, int h); + + void sprite(int _x, int _y, int bank, int frame, int inval = 1); + void sprite_fxp(int _x, int _y, int bank, int frame, int inval = 1); + + void blit(int dx, int dy, int sx, int sy, int sw, int sh, window_t *src); + void blit(int dx, int dy, window_t *src); + + int x() { return (phys_rect.x * 256 + 128) / xs; } + int y() { return (phys_rect.y * 256 + 128) / ys; } + int x2() { return ((phys_rect.x + phys_rect.w) * 256 + 128) / xs; } + int y2() { return ((phys_rect.y + phys_rect.h) * 256 + 128) / ys; } + int width() { return x2() - x(); } + int height() { return y2() - y(); } + + SDL_Rect phys_rect; + + protected: + window_t *next, *prev; + /* + * Kludge: This is for window selection to work. + * the problem is that this will break (along + * with some other things) if more than one + * gfxengine_t instance is used. + */ + static window_t *selected; //Currently selected window + + gfxengine_t *engine; + SDL_Surface *surface; + int xs, ys; //fixp 24:8 + Uint32 fgcolor, bgcolor; + int bg_bank, bg_frame; + int _font; + int _visible; + int _offscreen; + + void _select(); //Internal version + void link(gfxengine_t *e); + void unlink(void); + + void phys_refresh(SDL_Rect *r) + { + if(!r) + refresh(NULL); + else + { + SDL_Rect dr; + dr.x = r->x - phys_rect.x; + dr.y = r->y - phys_rect.y; + int x2 = (int)(dr.x + r->w) * 256 / xs; + int y2 = (int)(dr.y + r->h) * 256 / ys; + dr.x = (int)dr.x * 256 / xs; + dr.y = (int)dr.y * 256 / ys; + dr.w = x2 - dr.x; + dr.h = y2 - dr.y; + refresh(&dr); + } + } +}; + +#endif diff --git a/icons.tar.gz b/icons.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..663e4d2eb496e9c3fdcc2d7b9d8849a981360ce4 GIT binary patch literal 26073 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νpr2x(UcR-i^Xd*4+&!zcqB=>)~&@YtPI3N3@Aq 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 e=Uy-N0cn+c +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef DEBUG +#include "audio.h" +extern "C" { +/*For the oscilloscope*/ +#include "a_globals.h" +/*For VU and voice info*/ +#include "a_struct.h" +} +#endif + +#include "kobolog.h" +#include "config.h" +#include "kobo.h" +#include "states.h" +#include "screen.h" +#include "manage.h" +#include "score.h" +#include "gamectl.h" +#include "random.h" +#include "version.h" +#include "options.h" +#include "myship.h" +#include "enemies.h" + +#define MAX_FPS_RESULTS 64 + +/* Joystick support */ +#define DEFAULT_JOY_LR 0 // Joystick axis left-right default +#define DEFAULT_JOY_UD 1 // Joystick axis up-down default +#define DEFAULT_JOY_FIRE 0 // Default fire button on joystick +#define DEFAULT_JOY_START 1 + + +/*---------------------------------------------------------- + Singletons +----------------------------------------------------------*/ +KOBO_sound sound; + + +/*---------------------------------------------------------- + Globals +----------------------------------------------------------*/ +filemapper_t *fmap = NULL; +prefs_t *prefs = NULL; +kobo_gfxengine_t *gengine = NULL; + +screen_window_t *wscreen = NULL; +dashboard_window_t *wdash = NULL; +bargraph_t *whealth = NULL; +bargraph_t *wtemp = NULL; +bargraph_t *wttemp = NULL; +radar_map_t *wmap = NULL; +radar_window_t *wradar = NULL; +window_t *wmain = NULL; +display_t *dhigh = NULL; +display_t *dscore = NULL; +display_t *dstage = NULL; +display_t *dships = NULL; +RGN_region *logo_region = NULL; + +int mouse_x = 0; +int mouse_y = 0; +int mouse_left = 0; +int mouse_middle = 0; +int mouse_right = 0; + +int exit_game = 0; + + +static int main_init() +{ + prefs = new prefs_t; + fmap = new filemapper_t; + gengine = new kobo_gfxengine_t; + return 0; +} + + +static void main_cleanup() +{ + delete gengine; + gengine = NULL; + delete fmap; + fmap = NULL; + delete prefs; + prefs = NULL; +} + + +/*---------------------------------------------------------- + Various functions +----------------------------------------------------------*/ + +static void setup_dirs(char *xpath) +{ + fmap->exepath(xpath); + + fmap->addpath("DATA", KOBO_DATA_DIR); + + /* + * Graphics data + */ + /* Current dir; from within the build tree */ + fmap->addpath("GFX", "./data/gfx"); + /* Real data dir */ + fmap->addpath("GFX", "DATA>>gfx"); + /* Current dir */ + fmap->addpath("GFX", "./gfx"); + + /* + * Sound data + */ + /* Current dir; from within the build tree */ + fmap->addpath("SFX", "./data/sfx"); + /* Real data dir */ + fmap->addpath("SFX", "DATA>>sfx"); + /* Current dir */ + fmap->addpath("SFX", "./sfx"); + + /* + * Score files (user and global) + */ + fmap->addpath("SCORES", KOBO_SCORE_DIR); + /* 'scores' in current dir (For importing scores, perhaps...) */ +// (Disabled for now, since filemapper_t can't tell +// when it hits the same dir more than once...) +// fmap->addpath("SCORES", "./scores"); + + /* + * Configuration files + */ + fmap->addpath("CONFIG", KOBO_CONFIG_DIR); + /* System local */ + fmap->addpath("CONFIG", SYSCONF_DIR); + /* In current dir (last resort) */ + fmap->addpath("CONFIG", "./"); +} + + +static void add_dirs(prefs_t *p) +{ + char buf[300]; + if(p->dir[0]) + { + char *upath = fmap->sys2unix(p->dir); + snprintf(buf, 300, "%s/sfx", upath); + fmap->addpath("SFX", buf, 1); + snprintf(buf, 300, "%s/gfx", upath); + fmap->addpath("GFX", buf, 1); + snprintf(buf, 300, "%s/scores", upath); + fmap->addpath("SCORES", buf, 1); + snprintf(buf, 300, "%s", upath); + fmap->addpath("CONFIG", buf, 0); + } + + if(p->sfxdir[0]) + fmap->addpath("SFX", fmap->sys2unix(p->sfxdir), 1); + + if(p->gfxdir[0]) + fmap->addpath("GFX", fmap->sys2unix(p->gfxdir), 1); + + if(p->scoredir[0]) + fmap->addpath("SCORES", fmap->sys2unix(p->scoredir), 1); +} + + +#ifdef DEBUG +static void draw_osc(int mode) +{ + int mx = oscframes; + if(mx > wmain->width()) + mx = wmain->width(); + int yo = wmain->height() - 40; + wmain->foreground(wmain->map_rgb(0x000099)); + wmain->fillrect(0, yo, wmain->width(), 1); + wmain->foreground(wmain->map_rgb(0x990000)); + wmain->fillrect(0, yo - 32, wmain->width(), 1); + wmain->fillrect(0, yo + 31, wmain->width(), 1); + + switch(mode) + { + case 0: + wmain->foreground(wmain->map_rgb(0x009900)); + for(int s = 0; s < mx; ++s) + wmain->point(s, ((oscbufl[s]+oscbufr[s]) >> 11) + yo); + break; + case 1: + wmain->foreground(wmain->map_rgb(0x009900)); + for(int s = 0; s < mx; ++s) + wmain->point(s, (oscbufl[s] >> 10) + yo); + wmain->foreground(wmain->map_rgb(0xcc0000)); + for(int s = 0; s < mx; ++s) + wmain->point(s, (oscbufr[s] >> 10) + yo); + break; + case 2: + wmain->foreground(wmain->map_rgb(0x009900)); + for(int s = 0; s < mx; ++s) + wmain->point(s>>1, (oscbufl[s] >> 10) + yo); + wmain->foreground(wmain->map_rgb(0xcc0000)); + for(int s = 0; s < mx; ++s) + wmain->point((s>>1) + (mx>>1), (oscbufr[s] >> 10) + yo); + wmain->fillrect(mx/2, yo-34, 1, 68); + break; + } + + wmain->foreground(wmain->map_rgb(0xcc0000)); + wmain->fillrect(0, yo - 32, 6, limiter.attenuation >> 11); +} + + +static void draw_vu(void) +{ + int xo = (wmain->width() - 5 * AUDIO_MAX_VOICES) / 2; + int yo = wmain->height() - 50; + wmain->foreground(wmain->map_rgb(0x000000)); + for(int s = 4; s < 40; s += 4) + wmain->fillrect(xo, yo+s, 5 * AUDIO_MAX_VOICES-1, 1); + wmain->foreground(wmain->map_rgb(0x333333)); + wmain->fillrect(xo-1, yo, 5 * AUDIO_MAX_VOICES+1, 1); + wmain->fillrect(xo-1, yo+40, 5 * AUDIO_MAX_VOICES+1, 4); + for(int s = 0; s <= AUDIO_MAX_VOICES; ++s) + wmain->fillrect(xo + s*5 - 1, yo+1, 1, 39); + for(int s = 0; s < AUDIO_MAX_VOICES; ++s) + { + int vu, vu2, vumin; + if(VS_STOPPED != voicetab[s].state) + { + wmain->foreground(wmain->map_rgb(0x009900)); + wmain->fillrect(xo + 1, yo + 41, 2, 2); + + vu = labs((voicetab[s].ic[VIC_LVOL].v>>1) + + (voicetab[s].ic[VIC_RVOL].v>>1)) >> + RAMP_BITS; +#ifdef AUDIO_USE_VU + vu2 = voicetab[s].vu; + voicetab[s].vu = 0; +#else + vu2 = 0; +#endif + vu2 = (vu2>>4) * (vu>>4) >> 8; + vu2 >>= 11; + if(vu2 > 40) + vu2 = 40; + vu >>= 11; + if(vu > 40) + vu = 40; + vumin = vu < vu2 ? vu : vu2; + } + else + vu = vu2 = vumin = 0; + wmain->foreground(wmain->map_rgb(0x006600)); + wmain->fillrect(xo, yo + 40 - vu, 4, vu - vu2); + wmain->foreground(wmain->map_rgb(0xffcc00)); + wmain->fillrect(xo, yo + 40 - vu2, 4, vu2); + xo += 5; + } +} +#endif + + +/*---------------------------------------------------------- + The main object +----------------------------------------------------------*/ +class KOBO_main +{ + public: +#ifdef DEBUG + static int audio_vismode; +#endif + static SDL_Joystick *joystick; + static int js_lr; + static int js_ud; + static int js_fire; + static int js_start; + + static FILE *logfile; + + static Uint32 esc_tick; + static int esc_count; + static int exit_game_fast; + + // Frame rate counter + static int fps_count; + static int fps_starttime; + static int fps_nextresult; + static int fps_lastresult; + static float *fps_results; + static display_t *dfps; + + // Frame rate limiter + static float max_fps_filter; + static int max_fps_begin; + + static int xoffs; + static int yoffs; + + // Backup in case we screw up we can't get back up + static prefs_t safe_prefs; + + static int open(); + static void close(); + static int run(); + + static int open_logging(prefs_t *p); + static void close_logging(); + static void load_config(prefs_t *p); + static void save_config(prefs_t *p); + + static void build_screen(); + static int init_display(prefs_t *p); + static void close_display(); + + static void show_progress(prefs_t *p); + static void progress(); + static void doing(const char *msg); + static int load_graphics(prefs_t *p); + static int load_sounds(prefs_t *p, int render_all = 0); + + static int init_js(prefs_t *p); + static void close_js(); + + static int escape_hammering(); + static int quit_requested(); + static void brutal_quit(); + static void pause_game(); + + static void print_fps_results(); +}; + +#ifdef DEBUG +int KOBO_main::audio_vismode = 0; +#endif + +SDL_Joystick *KOBO_main::joystick = NULL; +int KOBO_main::js_lr = DEFAULT_JOY_LR; +int KOBO_main::js_ud = DEFAULT_JOY_UD; +int KOBO_main::js_fire = DEFAULT_JOY_FIRE; +int KOBO_main::js_start = DEFAULT_JOY_START; + +FILE *KOBO_main::logfile = NULL; + +Uint32 KOBO_main::esc_tick = 0; +int KOBO_main::esc_count = 0; +int KOBO_main::exit_game_fast = 0; + +int KOBO_main::fps_count = 0; +int KOBO_main::fps_starttime = 0; +int KOBO_main::fps_nextresult = 0; +int KOBO_main::fps_lastresult = 0; +float *KOBO_main::fps_results = NULL; +display_t *KOBO_main::dfps = NULL; + +float KOBO_main::max_fps_filter = 0.0f; +int KOBO_main::max_fps_begin = 0; + +int KOBO_main::xoffs = 0; +int KOBO_main::yoffs = 0; + +prefs_t KOBO_main::safe_prefs; + + +static KOBO_main km; + + +void KOBO_main::print_fps_results() +{ + int i, r = fps_nextresult; + if(fps_lastresult != MAX_FPS_RESULTS-1) + r = 0; + for(i = 0; i < fps_lastresult; ++i) + { + log_printf(ULOG, "%.1f fps\n", fps_results[r++]); + if(r >= MAX_FPS_RESULTS) + r = 0; + } + + free(fps_results); + fps_nextresult = 0; + fps_lastresult = 0; + fps_results = NULL; +} + + +int KOBO_main::escape_hammering() +{ + Uint32 nt = SDL_GetTicks(); + if(nt - esc_tick > 300) + esc_count = 1; + else + ++esc_count; + esc_tick = nt; + return esc_count >= 5; +} + + +int KOBO_main::quit_requested() +{ + SDL_Event e; + while(SDL_PollEvent(&e)) + { + switch(e.type) + { + case SDL_QUIT: + exit_game_fast = 1; + break; + case SDL_VIDEOEXPOSE: + gengine->invalidate(); + break; + case SDL_KEYUP: + switch(e.key.keysym.sym) + { + case SDLK_ESCAPE: + if(escape_hammering()) + exit_game_fast = 1; + break; + default: + break; + } + break; + } + } + if(exit_game_fast) + return 1; + return SDL_QuitRequested(); +} + + +void KOBO_main::close_logging() +{ + /* Flush logs to disk, close log files etc. */ + log_close(); + + if(logfile) + { + fclose(logfile); + logfile = NULL; + } +} + + +int KOBO_main::open_logging(prefs_t *p) +{ + close_logging(); + + if(log_open() < 0) + return -1; + + if(p && p->logfile) + switch (p->logformat) + { + case 2: + logfile = fopen("log.html", "wb"); + break; + default: + logfile = fopen("log.txt", "wb"); + break; + } + + if(logfile) + { + log_set_target_stream(0, logfile); + log_set_target_stream(1, logfile); + } + else + { + log_set_target_stream(0, stdout); + log_set_target_stream(1, stderr); + } + + log_set_target_stream(2, NULL); + + if(p) + switch(p->logformat) + { + default: + log_set_target_flags(-1, LOG_TIMESTAMP); + break; + case 1: + log_set_target_flags(-1, LOG_ANSI | LOG_TIMESTAMP); + break; + case 2: + log_set_target_flags(-1, LOG_HTML | LOG_TIMESTAMP); + break; + } + + /* All levels output to stdout... */ + log_set_level_target(-1, 0); + + /* ...except these, that output to stderr. */ + log_set_level_target(ELOG, 1); + log_set_level_target(CELOG, 1); + + /* Some fancy colors... */ + log_set_level_attr(ULOG, LOG_YELLOW); + log_set_level_attr(WLOG, LOG_YELLOW | LOG_BRIGHT); + log_set_level_attr(ELOG, LOG_RED | LOG_BRIGHT); + log_set_level_attr(CELOG, LOG_RED | LOG_BRIGHT | LOG_BLINK); + log_set_level_attr(DLOG, LOG_CYAN); + log_set_level_attr(D2LOG, LOG_BLUE | LOG_BRIGHT); + log_set_level_attr(D3LOG, LOG_BLUE); + + /* Disable levels as desired */ + if(p) + switch(p->logverbosity) + { + case 0: + log_set_level_target(ELOG, 2); + case 1: + log_set_level_target(WLOG, 2); + case 2: + log_set_level_target(DLOG, 2); + case 3: + log_set_level_target(D2LOG, 2); + case 4: + log_set_level_target(D3LOG, 2); + case 5: + break; + } + + if(p && p->logfile && !logfile) + log_printf(ELOG, "Couldn't open log file!\n"); + + return 0; +} + + +void KOBO_main::build_screen() +{ + gengine->clear(0x000000); + + wdash->place(xoffs, yoffs, SCREEN_WIDTH, SCREEN_HEIGHT); + + whealth->place(xoffs + 4, yoffs + 92, 8, 128); + whealth->bgimage(B_HEALTH_LID, 0); + whealth->background(whealth->map_rgb(0x182838)); + whealth->redmax(0); + + wmain->place(xoffs + 8 + MARGIN, yoffs + MARGIN, WSIZE, WSIZE); + gengine->output(wmain); + + dhigh->place(xoffs + 252, yoffs + 4, 64, 18); + dhigh->font(B_NORMAL_FONT); + dhigh->bgimage(B_HIGH_BACK, 0); + dhigh->caption("HIGHSCORE"); + dhigh->text("000000000"); + + dscore->place(dhigh->x(), dhigh->y2() + 4, 64, 18); + dscore->font(B_NORMAL_FONT); + dscore->bgimage(B_SCORE_BACK, 0); + dscore->caption("SCORE"); + dscore->text("000000000"); + + wmap->place(0, 0, MAP_SIZEX, MAP_SIZEY); + wmap->offscreen(); + + wradar->place(xoffs + 244, + yoffs + (SCREEN_HEIGHT - MAP_SIZEY) / 2, + MAP_SIZEX, MAP_SIZEY); + wradar->bgimage(B_RADAR_BACK, 0); + + wtemp->place(xoffs + 244, yoffs + 188, 4, 32); + wtemp->bgimage(B_TEMP_LID, 0); + wtemp->background(wtemp->map_rgb(0x182838)); + wtemp->redmax(1); + + wttemp->place(xoffs + 248, yoffs + 188, 4, 32); + wttemp->bgimage(B_TTEMP_LID, 0); + wttemp->background(wttemp->map_rgb(0x182838)); + wttemp->redmax(1); + + dships->place(xoffs + 264, yoffs + 196, 38, 18); + dships->font(B_NORMAL_FONT); + dships->bgimage(B_SHIPS_BACK, 0); + dships->caption("SHIPS"); + dships->text("000"); + + dstage->place(dships->x(), dships->y2() + 4, 38, 18); + dstage->font(B_NORMAL_FONT); + dstage->bgimage(B_STAGE_BACK, 0); + dstage->caption("STAGE"); + dstage->text("000"); + + if(prefs->cmd_fps) + { + dfps = new display_t; + dfps->init(gengine); + dfps->place(0, -9, 48, 18); + dfps->color(wdash->map_rgb(0, 0, 0)); + dfps->font(B_NORMAL_FONT); + dfps->caption("FPS"); + } +} + + +int KOBO_main::init_display(prefs_t *p) +{ + int dw, dh; // Display size + int gw, gh; // Game "window" size + gengine->title("Kobo Deluxe " VERSION, "kobodl"); + gengine->driver((gfx_drivers_t)p->videodriver); + + dw = p->width; + dh = p->height; + if(p->fullscreen) + { + // This game assumes 1:1 pixel aspect ratio, or 4:3 + // width:height ratio, so we need to adjust accordingly. + // Note: + // This code assumes 1:1 pixels for all resolutions! + // This does not hold true for 1280x1024 or a CRT + // for example, but that's an incorrect (although + // all too common) setup anyway. (1280x1024 is for + // 5:4 TFT displays only!) + if(dw * 3 >= dh * 4) + { + // 4:3 or widescreen; Height defines size + gw = dh * 4 / 3; + gh = dh; + } + else + { + // "tallscreen" (probably 5:4 TFT or rotated display) + // Width defines size + gw = dw; + gh = dw * 3 / 4; + } + } + else + { + gw = dw; + gh = dh; + } + + // Scaling has 16ths granularity, so tiles scale properly! + gengine->scale((int)((gw * 16 + 8) / SCREEN_WIDTH) / 16.f, + (int)((gh * 16 + 8) / SCREEN_HEIGHT) / 16.f); + + // Read back and recalculate, in case the engine has some ideas... + gw = (int)(SCREEN_WIDTH * gengine->xscale() + 0.5f); + gh = (int)(SCREEN_HEIGHT * gengine->yscale() + 0.5f); + + if(!p->fullscreen) + { + //Add thin black border around the game "screen" in windowed mode. + dw = gw + 8; + dh = gh + 8; + } + + xoffs = (int)((dw - gw) / 2 / gengine->xscale()); + yoffs = (int)((dh - gh) / 2 / gengine->yscale()); + gengine->size(dw, dh); + + gengine->mode(0, p->fullscreen); + gengine->doublebuffer(p->doublebuf); + gengine->pages(p->pages); + gengine->vsync(p->vsync); + gengine->shadow(p->shadow); + gengine->cursor(0); + + gengine->period(game.speed); + sound.period(game.speed); + gengine->timefilter(p->timefilter * 0.01f); + gengine->interpolation(p->filter); + + gengine->scroll_ratio(LAYER_OVERLAY, 0.0, 0.0); + gengine->scroll_ratio(LAYER_BULLETS, 1.0, 1.0); + gengine->scroll_ratio(LAYER_FX, 1.0, 1.0); + gengine->scroll_ratio(LAYER_PLAYER, 1.0, 1.0); + gengine->scroll_ratio(LAYER_ENEMIES, 1.0, 1.0); + gengine->scroll_ratio(LAYER_BASES, 1.0, 1.0); + gengine->wrap(MAP_SIZEX * CHIP_SIZEX, MAP_SIZEY * CHIP_SIZEY); + + if(gengine->open(ENEMY_MAX) < 0) + return -1; + + gengine->clear(); + + wscreen = new screen_window_t; + wscreen->init(gengine); + wscreen->place(0, 0, + (int)(gengine->width() / gengine->xscale() + 0.5f), + (int)(gengine->height() / gengine->yscale() + 0.5f)); + wscreen->border((int)(yoffs * gengine->yscale() + 0.5f), + (int)(xoffs * gengine->xscale() + 0.5f), + dw - gw - (int)(xoffs * gengine->xscale() + 0.5f), + dh - gh - (int)(yoffs * gengine->yscale() + 0.5f)); + + wdash = new dashboard_window_t; + wdash->init(gengine); + whealth = new bargraph_t; + whealth->init(gengine); + wmain = new window_t; + wmain->init(gengine); + dhigh = new display_t; + dhigh->init(gengine); + dscore = new display_t; + dscore->init(gengine); + wmap = new radar_map_t; + wmap->init(gengine); + wradar = new radar_window_t; + wradar->init(gengine); + wtemp = new bargraph_t; + wtemp->init(gengine); + wttemp = new bargraph_t; + wttemp->init(gengine); + dships = new display_t; + dships->init(gengine); + dstage = new display_t; + dstage->init(gengine); + + build_screen(); + + wdash->mode(DASHBOARD_BLACK); + + return 0; +} + + +void KOBO_main::close_display() +{ + delete dfps; + dfps = NULL; + delete dstage; + dstage = NULL; + delete dships; + dships = NULL; + delete wttemp; + wttemp = NULL; + delete wtemp; + wtemp = NULL; + delete wradar; + wradar = NULL; + delete wmap; + wmap = NULL; + delete dscore; + dscore = NULL; + delete dhigh; + dhigh = NULL; + delete wmain; + wmain = NULL; + delete whealth; + whealth = NULL; + delete wdash; + wdash = NULL; + delete wscreen; + wscreen = NULL; +} + + +void KOBO_main::show_progress(prefs_t *p) +{ + wdash->mode(DASHBOARD_LOADING); + wdash->doing(""); +} + + +void KOBO_main::progress() +{ + wdash->progress(); +} + + +void KOBO_main::doing(const char *msg) +{ + wdash->doing(msg); +} + + +#ifndef TIME_PROGRESS +static float progtab_graphics[] = { + 0.000000, + 1.167315, + 4.085603, + 5.836576, + 7.490273, + 9.046693, + 10.992218, + 12.937743, + 13.813230, + 15.564202, + 17.217899, + 18.774319, + 20.428015, + 22.081713, + 23.540855, + 25.291828, + 26.848249, + 28.404669, + 29.961090, + 32.003891, + 33.560310, + 35.311283, + 36.770428, + 38.521400, + 40.369648, + 41.828793, + 43.190662, + 44.649807, + 46.595329, + 48.151752, + 49.610893, + 51.361866, + 53.501945, + 58.852139, + 60.116730, + 61.089493, + 63.521400, + 66.050583, + 68.287941, + 69.844360, + 72.665367, + 74.124512, + 76.653694, + 77.334633, + 79.182877, + 80.642021, + 82.295723, + 83.852142, + 85.505836, + 87.159531, + 88.813232, + 90.369652, + 92.023346, + 93.677040, + 95.233459, + 96.984436, + 98.540855, + 100.0, + 0 +}; + +static float progtab_sounds[] = { + 0.000000, + 58.709679, + 59.516129, + 98.790321, + 98.790321, + 100.0, + 0 +}; + +static float progtab_all[] = { + 0.000000, + 1.556684, + 2.639594, + 3.282572, + 4.060914, + 4.737733, + 5.380711, + 8.697124, + 8.764806, + 10.016920, + 10.761421, + 11.472081, + 12.216582, + 12.893401, + 13.604061, + 14.416244, + 15.093062, + 15.262267, + 16.074450, + 17.428087, + 18.680202, + 19.932318, + 20.879864, + 21.759729, + 23.011845, + 24.365482, + 24.534687, + 24.839256, + 25.651438, + 26.429781, + 26.700508, + 27.241962, + 29.678511, + 38.477158, + 40.203045, + 40.372250, + 40.913704, + 42.571911, + 45.211506, + 45.922165, + 46.565144, + 46.903553, + 48.866329, + 48.967850, + 49.306259, + 49.847717, + 50.389172, + 50.964466, + 51.641285, + 52.115059, + 52.690357, + 53.231812, + 53.773266, + 54.382404, + 54.991539, + 55.499153, + 56.006767, + 57.495770, + 82.673431, + 82.978004, + 99.763115, + 99.796951, + 100.0, + 0 +}; +#endif + + +typedef enum +{ + KOBO_CLAMP = 0x0001, // Clamp to frame edge pixels + KOBO_CLAMP_OPAQUE = 0x0002, // Clamp to black instead of transparent + KOBO_NOALPHA = 0x0004, // Disable alpha channel + KOBO_NODITHER = 0x0008, // Disable dithering + KOBO_NEAREST = 0x0010, // Force NEAREST scale mode + KOBO_CENTER = 0x0020, // Center hotspot in frames + KOBO_NOBRIGHT = 0x0040, // Disable brightness/contrast filter + KOBO_FONT = 0x0080, // Load as "SFont" rather than tiles! + KOBO_MESSAGE = 0x1000 // Not a file! 'path' is a message. +} KOBO_GfxDescFlags; + +typedef struct KOBO_GfxDesc +{ + const char *path; // Path + name (for filemapper) + int bank; // Sprite bank ID + int w, h; // Frame size (original image pixels) + float scale; // Scale of source data rel. 320x240 + int flags; // KOBO_GfxDescFlags +} KOBO_GfxDesc; + +static KOBO_GfxDesc gfxdesc[] = { + // Loading screen + { "Loading loading screen graphics", 0, 0,0, 0.0f, KOBO_MESSAGE }, + { "GFX>>loading3.png", B_LOADING, 0, 0, 2.0f, + KOBO_CLAMP | KOBO_NOALPHA }, + { "GFX>>icefont2.png", B_NORMAL_FONT, 0, 0, 2.0f, KOBO_FONT }, + + // In-game + { "Loading in-game graphics", 0, 0,0, 0.0f, KOBO_MESSAGE }, + { "GFX>>tiles-green.png", B_TILES1, 32, 32, 2.0f, KOBO_CLAMP }, + { "GFX>>tiles-metal.png", B_TILES2, 32, 32, 2.0f, KOBO_CLAMP }, + { "GFX>>tiles-blood.png", B_TILES3, 32, 32, 2.0f, KOBO_CLAMP }, + { "GFX>>tiles-double.png", B_TILES4, 32, 32, 2.0f, KOBO_CLAMP }, + { "GFX>>tiles-chrome.png", B_TILES5, 32, 32, 2.0f, KOBO_CLAMP }, + { "GFX>>flatstars1.png", B_OLDSTARS, 32, 32, 2.0f, KOBO_CLAMP }, + { "GFX>>crosshair.png", B_CROSSHAIR, 32, 32, 2.0f, KOBO_CENTER }, + { "GFX>>player.png", B_PLAYER, 40, 40, 2.0f, KOBO_CENTER }, + { "GFX>>bmr-green.png", B_BMR_GREEN, 40, 40, 2.0f, KOBO_CENTER }, + { "GFX>>bmr-purple.png", B_BMR_PURPLE, 40, 40, 2.0f, KOBO_CENTER }, + { "GFX>>bmr-pink.png", B_BMR_PINK, 40, 40, 2.0f, KOBO_CENTER }, + { "GFX>>fighter.png", B_FIGHTER, 40, 40, 2.0f, KOBO_CENTER }, + { "GFX>>missile.png", B_MISSILE1, 40, 40, 2.0f, KOBO_CENTER }, + { "GFX>>missile2.png", B_MISSILE2, 40, 40, 2.0f, KOBO_CENTER }, + { "GFX>>missile3.png", B_MISSILE3, 40, 40, 2.0f, KOBO_CENTER }, + { "GFX>>bolt.png", B_BOLT, 16, 16, 2.0f, KOBO_CENTER }, + { "GFX>>boltexpl.png", B_BOLTEXPL, 32, 32, 2.0f, KOBO_CENTER }, + { "GFX>>explo1e.png", B_EXPLO1, 48, 48, 2.0f, KOBO_CENTER }, + { "GFX>>explo3e.png", B_EXPLO3, 64, 64, 2.0f, KOBO_CENTER }, + { "GFX>>explo4e.png", B_EXPLO4, 64, 64, 2.0f, KOBO_CENTER }, + { "GFX>>explo5e.png", B_EXPLO5, 64, 64, 2.0f, KOBO_CENTER }, + { "GFX>>rock1c.png", B_ROCK1, 32, 32, 2.0f, KOBO_CENTER }, + { "GFX>>rock2.png", B_ROCK2, 32, 32, 2.0f, KOBO_CENTER }, + { "GFX>>shinyrock.png", B_ROCK3, 32, 32, 2.0f, KOBO_CENTER }, + { "GFX>>rockexpl.png", B_ROCKEXPL, 64, 64, 2.0f, KOBO_CENTER }, + { "GFX>>bullet5b.png", B_BULLETS, 16, 16, 2.0f, KOBO_CENTER }, + { "GFX>>bulletexpl2.png", B_BULLETEXPL, 32, 32, 2.0f, KOBO_CENTER }, + { "GFX>>ring.png", B_RING, 32, 32, 2.0f, KOBO_CENTER }, + { "GFX>>ringexpl2b.png", B_RINGEXPL, 40, 40, 2.0f, KOBO_CENTER }, + { "GFX>>bomb.png", B_BOMB, 24, 24, 2.0f, KOBO_CENTER }, + { "GFX>>bombdeto.png", B_BOMBDETO, 40, 40, 2.0f, KOBO_CENTER }, + { "GFX>>bigship.png", B_BIGSHIP, 72, 72, 2.0f, KOBO_CENTER }, + + // Framework + { "Loading framework graphics", 0, 0,0, 0.0f, KOBO_MESSAGE }, + { "GFX>>screen2.png", B_SCREEN, 0, 0, 2.0f, KOBO_CLAMP_OPAQUE }, + + // Logo + { "Loading logo", 0, 0,0, 0.0f, KOBO_MESSAGE }, + { "GFX>>logo-outline.png", B_LOGO, 0, 0, 2.0f, 0 }, + { "GFX>>deluxe.png", B_LOGODELUXE, 0, 0, 2.0f, 0 }, + { "GFX>>logomask3.png", B_LOGOMASK, 0, 0, 4.0f, + KOBO_NEAREST | KOBO_NODITHER }, + + // Fonts + { "Loading fonts", 0, 0,0, 0.0f, KOBO_MESSAGE }, + { "GFX>>goldfont.png", B_MEDIUM_FONT, 0, 0, 2.0f, KOBO_FONT }, + { "GFX>>bigfont3.png", B_BIG_FONT, 0, 0, 2.0f, KOBO_FONT }, + { "GFX>>counterfont.png", B_COUNTER_FONT, 0, 0, 2.0f, KOBO_FONT }, + + // Special FX + { "Loading special FX graphics", 0, 0,0, 0.0f, KOBO_MESSAGE }, + { "GFX>>noise.png", B_NOISE, NOISE_SIZEX, 1, 1.0f, + KOBO_CLAMP }, + { "GFX>>hitnoise.png", B_HITNOISE, NOISE_SIZEX, 1, 1.0f, + KOBO_CLAMP | KOBO_NEAREST }, + { "GFX>>focusfx.png", B_FOCUSFX, 0, 0, 1.0f, KOBO_CLAMP }, + { "GFX>>brushes.png", B_BRUSHES, 16, 16, 1.0f, + KOBO_CLAMP | KOBO_NEAREST | KOBO_NOALPHA }, + + { NULL, 0, 0, 0, 0.0f, 0 } // Terminator +}; + + +int KOBO_main::load_graphics(prefs_t *p) +{ + KOBO_GfxDesc *gd; + gengine->reset_filters(); + show_progress(p); + for(gd = gfxdesc; gd->path; ++gd) + { + if(gd->flags & KOBO_MESSAGE) + { + doing(gd->path); + continue; + } + + // Set scale (filter) mode and clamping + int clamping; + gfx_scalemodes_t sm; + if(gd->flags & KOBO_CLAMP) + { + gengine->clampcolor(0, 0, 0, 0); + clamping = 1; + } + else if(gd->flags & KOBO_CLAMP_OPAQUE) + { + gengine->clampcolor(0, 0, 0, 255); + clamping = 1; + } + else + clamping = 0; + if(gd->flags & KOBO_NEAREST) + sm = GFX_SCALE_NEAREST; + else + sm = (gfx_scalemodes_t) p->scalemode; + gengine->scalemode(sm, clamping); + + // Disable brightness filter? + if(gd->flags & KOBO_NOBRIGHT) + gengine->brightness(1.0f, 1.0f); + else + gengine->brightness(0.01f * p->brightness, + 0.01f * p->contrast); + + // Dithering + if(gd->flags & KOBO_NODITHER || !p->use_dither) + gengine->dither(-1); + else + gengine->dither(p->dither_type, p->broken_rgba8); + + // Alpha channels + if(gd->flags & KOBO_NOALPHA || !p->alpha) + gengine->noalpha(NOALPHA_THRESHOLD); + else + gengine->noalpha(0); + + // Source image scale + gengine->source_scale(gd->scale, gd->scale); + + // Load! + const char *fn = fmap->get(gd->path); + if(!fn) + { + log_printf(ELOG, "Couldn't get path to \"%s\"!\n", + gd->path); + return -1; + } + int res; + if(gd->flags & KOBO_FONT) + res = gengine->loadfont(gd->bank, fn); + else if(!gd->w || !gd->h) + res = gengine->loadimage(gd->bank, fn); + else + res = gengine->loadtiles(gd->bank, gd->w, gd->h, fn); + if(res < 0) + { + log_printf(ELOG, "Couldn't load \"%s\"!\n", fn); + return -1; + } + + // Hotspot + if(gd->flags & KOBO_CENTER) + gengine->set_hotspot(gd->bank, -1, + (int)(gd->w / gd->scale / 2), + (int)(gd->h / gd->scale / 2)); + + // Update progress bar + progress(); + } + + // Chop up the dashboard graphics as needed + SDL_Rect r; + r.w = r.h = 16; + r.x = (8 + MARGIN); + r.y = MARGIN; + if(gengine->copyrect(B_FRAME_TL, B_SCREEN, 0, &r) < 0) + return -6; + progress(); + r.x += WSIZE - 16; + if(gengine->copyrect(B_FRAME_TR, B_SCREEN, 0, &r) < 0) + return -7; + progress(); + r.x = (8 + MARGIN); + r.y = MARGIN + WSIZE - 16; + if(gengine->copyrect(B_FRAME_BL, B_SCREEN, 0, &r) < 0) + return -8; + progress(); + r.x += WSIZE - 16; + if(gengine->copyrect(B_FRAME_BR, B_SCREEN, 0, &r) < 0) + return -9; + progress(); + r.x = 252; + r.y = 4; + r.w = 64; + r.h = 18; + if(gengine->copyrect(B_HIGH_BACK, B_SCREEN, 0, &r) < 0) + return -26; + progress(); + r.y += 18 + 4; + if(gengine->copyrect(B_SCORE_BACK, B_SCREEN, 0, &r) < 0) + return -27; + progress(); + r.x = 244; + r.y = (SCREEN_HEIGHT - MAP_SIZEY) / 2; + r.w = MAP_SIZEX; + r.h = MAP_SIZEY; + if(gengine->copyrect(B_RADAR_BACK, B_SCREEN, 0, &r) < 0) + return -28; + progress(); + r.x = 264; + r.y = 196; + r.w = 38; + r.h = 18; + if(gengine->copyrect(B_SHIPS_BACK, B_SCREEN, 0, &r) < 0) + return -29; + progress(); + r.y += 18 + 4; + if(gengine->copyrect(B_STAGE_BACK, B_SCREEN, 0, &r) < 0) + return -30; + progress(); + r.x = 4; + r.y = 92; + r.w = 8; + r.h = 128; + if(gengine->copyrect(B_HEALTH_LID, B_SCREEN, 0, &r) < 0) + return -31; + progress(); + r.x = 244; + r.y = 188; + r.w = 4; + r.h = 32; + if(gengine->copyrect(B_TEMP_LID, B_SCREEN, 0, &r) < 0) + return -32; + progress(); + r.x += 4; + if(gengine->copyrect(B_TTEMP_LID, B_SCREEN, 0, &r) < 0) + return -33; + progress(); + + // Prepare the logo region + s_sprite_t *s = gengine->get_sprite(B_LOGOMASK, 0); + if(!s || !s->surface) + return -10; + RGN_FreeRegion(logo_region); + logo_region = RGN_ScanMask(s->surface, + SDL_MapRGB(s->surface->format, 255, 255, 255)); + if(!logo_region) + { + log_printf(ELOG, "Could not create logo region!\n"); + return -92; + } + progress(); + + return 0; +} + + +static int progress_cb(const char *msg) +{ + if(msg) + km.doing(msg); + km.progress(); + if(km.quit_requested()) + return -999; + return 0; +} + + +int KOBO_main::load_sounds(prefs_t *p, int render_all) +{ + if(!p->use_sound) + return 0; + show_progress(p); + return sound.load(progress_cb, render_all); +} + + +int KOBO_main::init_js(prefs_t *p) +{ + /* Activate Joystick sub-sys if we are using it */ + if(p->use_joystick) + { + if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0) + { + log_printf(ELOG, "Error setting up joystick!\n"); + return -1; + } + p->number_of_joysticks = SDL_NumJoysticks(); + if(p->number_of_joysticks > 0) + { + SDL_JoystickEventState(SDL_ENABLE); + if(p->joystick_no >= p->number_of_joysticks) + p->joystick_no = 0; + joystick = SDL_JoystickOpen(p->joystick_no); + if(!joystick) + { + SDL_QuitSubSystem(SDL_INIT_JOYSTICK); + return -2; + } + } + else + { + log_printf(ELOG, "No joysticks found!\n"); + joystick = NULL; + return -3; + } + + } + return 0; +} + + +void KOBO_main::close_js() +{ + if(!SDL_WasInit(SDL_INIT_JOYSTICK)) + return; + + if(!joystick) + return; + + if(SDL_JoystickOpened(0)) + SDL_JoystickClose(joystick); + joystick = NULL; + + SDL_QuitSubSystem(SDL_INIT_JOYSTICK); +} + + +void KOBO_main::load_config(prefs_t *p) +{ + FILE *f = fmap->fopen(KOBO_CONFIG_DIR "/" KOBO_CONFIG_FILE, "r"); + if(f) + { + p->read(f); + fclose(f); + } +} + + +void KOBO_main::save_config(prefs_t *p) +{ + FILE *f; +#if defined(HAVE_GETEGID) && defined(HAVE_SETGID) + gid_t oldgid = getegid(); + if(setgid(getgid()) != 0) + { + log_printf(ELOG, "Cannot save config! (%s)\n", + strerror(errno)); + return; + } +#endif + f = fmap->fopen(KOBO_CONFIG_DIR "/" KOBO_CONFIG_FILE, "w"); + if(f) + { + p->write(f); + fclose(f); + } +#if defined(HAVE_GETEGID) && defined(HAVE_SETGID) + if(setgid(oldgid) != 0) + { + log_printf(ELOG, "Cannot restore GID! (%s)\n", + strerror(errno)); + return; + } +#endif +} + + +void KOBO_main::brutal_quit() +{ + if(exit_game_fast) + { + log_printf(ULOG, "Second try quitting; using brutal method!\n"); + atexit(SDL_Quit); + close_logging(); + exit(1); + } + + exit_game_fast = 1; + if(gengine) + gengine->stop(); +} + + +void KOBO_main::pause_game() +{ + if(gsm.current() != &st_pause_game) + gsm.press(BTN_PAUSE); +} + + +void kobo_render_highlight(ct_widget_t *wg) +{ + screen.set_highlight(wg->y() + wg->height() / 2 - wmain->y(), + wg->height()); +} + + +int KOBO_main::open() +{ + if(init_display(prefs) < 0) + return -1; + +#ifdef TIME_PROGRESS + wdash->progress_init(NULL); +#else + wdash->progress_init(progtab_all); +#endif + + if(load_graphics(prefs) < 0) + return -2; + +#ifdef TIME_PROGRESS + // Use these two lines to time graphics and sounds separately! + wdash->progress_done(); + wdash->progress_init(NULL); +#endif + + sound.open(); + + if(load_sounds(prefs) < 0) + return -3; + + wdash->progress_done(); + + wdash->nibble(); + + ct_engine.render_highlight = kobo_render_highlight; + wdash->mode(DASHBOARD_GAME); + wradar->mode(RM_NOISE); + pubrand.init(); + init_js(prefs); + gamecontrol.init(prefs->always_fire); + manage.init(); + + gsm.push(&st_intro_title); + + return 0; +} + + +void KOBO_main::close() +{ + close_js(); + RGN_FreeRegion(logo_region); + logo_region = NULL; + close_display(); + if(gengine) + { + delete gengine; + gengine = NULL; + } + sound.close(); + SDL_Quit(); +} + + +int KOBO_main::run() +{ + int retry_status = 0; + int dont_retry = 0; + while(1) + { + if(!retry_status) + { + safe_prefs = *prefs; + gengine->run(); + + if(!manage.game_stopped()) + manage.abort(); + + if(exit_game_fast) + break; + + if(exit_game) + { + if(wdash) + wdash->nibble(); + break; + } + dont_retry = 0; + } + + retry_status = 0; + if(global_status & OS_RESTART_AUDIO) + { + if(prefs->use_sound) + { + log_printf(ULOG, "--- Restarting audio...\n"); + sound.stop(); +#ifdef TIME_PROGRESS + wdash->progress_init(NULL); +#else + wdash->progress_init(progtab_sounds); +#endif + if(load_sounds(prefs) < 0) + return 5; + wdash->progress_done(); + sound.open(); + wdash->nibble(); + log_printf(ULOG, "--- Audio restarted.\n"); + wdash->mode(DASHBOARD_GAME); + wradar->mode(screen.radar_mode); + manage.set_bars(); + } + else + { + log_printf(ULOG, "--- Stopping audio...\n"); + sound.close(); + log_printf(ULOG, "--- Audio stopped.\n"); + } + } + if((global_status & OS_RELOAD_AUDIO_CACHE) && prefs->cached_sounds) + { + log_printf(ULOG, "--- Rendering sounds to disk...\n"); +#ifdef TIME_PROGRESS + wdash->progress_init(NULL); +#else + wdash->progress_init(progtab_sounds); +#endif + if(load_sounds(prefs) < 0) + { + log_printf(ELOG, "--- Could not render sounds to disk!\n"); + st_error.message("Could not render to disk!", + "Please, check your installation."); + gsm.push(&st_error); + } + wdash->progress_done(); + wdash->mode(DASHBOARD_GAME); + wradar->mode(screen.radar_mode); + manage.set_bars(); + } + if(global_status & OS_RESTART_VIDEO) + { + log_printf(ULOG, "--- Restarting video...\n"); + wdash->nibble(); + gengine->hide(); + close_display(); + gengine->unload(); + if(init_display(prefs) < 0) + { + log_printf(ELOG, "--- Video init failed!\n"); + st_error.message("Video initialization failed!", + "Try different settings."); + gsm.push(&st_error); + if(dont_retry) + return 6; + *prefs = safe_prefs; + dont_retry = 1; + retry_status |= OS_RESTART_VIDEO; + } + else + { + gamecontrol.init(prefs->always_fire); + log_printf(ULOG, "--- Video restarted.\n"); + } + } + if(global_status & (OS_RELOAD_GRAPHICS | + OS_RESTART_VIDEO)) + { + if(!(global_status & OS_RESTART_VIDEO)) + wdash->nibble(); + gengine->unload(); + RGN_FreeRegion(logo_region); + logo_region = NULL; + if(!retry_status) + { + log_printf(ULOG, "--- Reloading graphics...\n"); +#ifdef TIME_PROGRESS + wdash->progress_init(NULL); +#else + wdash->progress_init(progtab_graphics); +#endif + if(load_graphics(prefs) < 0) + return 7; + wdash->progress_done(); + wdash->nibble(); + wdash->mode(DASHBOARD_GAME); + wradar->mode(screen.radar_mode); + manage.set_bars(); + log_printf(ULOG, "--- Graphics reloaded.\n"); + } + } + if(global_status & OS_RESTART_ENGINE) + log_printf(ELOG, "OS_RESTART_ENGINE not implemented!\n"); + if(global_status & OS_RESTART_INPUT) + { + close_js(); + init_js(prefs); + gamecontrol.init(prefs->always_fire); + } + if(global_status & OS_RESTART_LOGGER) + open_logging(prefs); + + global_status = retry_status; + km.pause_game(); + manage.reenter(); + } + return 0; +} + + +/*---------------------------------------------------------- + Kobo Graphics Engine +----------------------------------------------------------*/ + +kobo_gfxengine_t::kobo_gfxengine_t() +{ +} + + +void kobo_gfxengine_t::frame() +{ + sound.frame(); + + if(!gsm.current()) + { + log_printf(CELOG, "INTERNAL ERROR: No gamestate!\n"); + exit_game = 1; + stop(); + return; + } + if(exit_game || manage.aborted()) + { + stop(); + return; + } + + /* + * Process input + */ + SDL_Event ev; + while(SDL_PollEvent(&ev)) + { + int k, ms; + switch (ev.type) + { + case SDL_KEYDOWN: + switch(ev.key.keysym.sym) + { +#ifdef PROFILE_AUDIO + case SDLK_F10: + ++km.audio_vismode; + break; + case SDLK_F12: + audio_print_info(); + break; + case SDLK_r: + { + audio_channel_stop(-1, -1); + int startt = SDL_GetTicks(); + audio_wave_load(0, "sfx.agw", 0); + log_printf(VLOG, "(Loading + processing time: %d ms)\n", + SDL_GetTicks() - startt); + break; + } +#endif + case SDLK_DELETE: + if(prefs->cmd_debug) + { + manage.ships = 1; + myship.hit(1000); + } + break; + case SDLK_RETURN: + ms = SDL_GetModState(); + if(ms & (KMOD_CTRL | KMOD_SHIFT | KMOD_META)) + break; + if(!(ms & KMOD_ALT)) + break; + km.pause_game(); + prefs->fullscreen = !prefs->fullscreen; + prefs->changed = 1; + global_status |= OS_RELOAD_GRAPHICS | + OS_RESTART_VIDEO; + stop(); + return; + case SDLK_PRINT: + case SDLK_SYSREQ: +// FIXME: Doesn't this trigger when entering names and stuff...? + case SDLK_s: + gengine->screenshot(); + break; + default: + break; + } + k = gamecontrol.map(ev.key.keysym.sym); + gamecontrol.press(k); + gsm.press(k, ev.key.keysym.unicode); + break; + case SDL_KEYUP: + if((ev.key.keysym.sym == SDLK_ESCAPE) && km.escape_hammering()) + { + km.pause_game(); + prefs->fullscreen = 0; + prefs->videodriver = (int)GFX_DRIVER_SDL2D; + prefs->width = 640; + prefs->height = 480; + prefs->aspect = 1000; + prefs->depth = 0; + prefs->doublebuf = 0; + prefs->pages = -1; + prefs->shadow = 1; + prefs->scalemode = (int)GFX_SCALE_NEAREST; + prefs->brightness = 100; + prefs->contrast = 100; + global_status |= OS_RELOAD_GRAPHICS | + OS_RESTART_VIDEO; + stop(); + st_error.message("Safe video settings applied!", + "Enter Options menu to save."); + gsm.push(&st_error); + return; + } + k = gamecontrol.map(ev.key.keysym.sym); + if(k == SDLK_PAUSE) + { + gamecontrol.press(BTN_PAUSE); + gsm.press(BTN_PAUSE); + } + else + { + gamecontrol.release(k); + gsm.release(k); + } + break; + case SDL_VIDEOEXPOSE: + gengine->invalidate(); + break; + case SDL_ACTIVEEVENT: + // Any type of focus loss should activate pause mode! + if(!ev.active.gain) + km.pause_game(); + break; + case SDL_QUIT: + /*gsm.press(BTN_CLOSE);*/ + km.brutal_quit(); + break; + case SDL_JOYBUTTONDOWN: + if(ev.jbutton.button == km.js_fire) + { + gamecontrol.press(BTN_FIRE); + gsm.press(BTN_FIRE); + } + else if(ev.jbutton.button == km.js_start) + { + gamecontrol.press(BTN_START); + gsm.press(BTN_START); + } + break; + case SDL_JOYBUTTONUP: + if(ev.jbutton.button == km.js_fire) + { + gamecontrol.release(BTN_FIRE); + gsm.release(BTN_FIRE); + } + break; + case SDL_JOYAXISMOTION: + // FIXME: We will want to allow these to be + // redefined, but for now, this works ;-) + if(ev.jaxis.axis == km.js_lr) + { + if(ev.jaxis.value < -3200) + { + gamecontrol.press(BTN_LEFT); + gsm.press(BTN_LEFT); + } + else if(ev.jaxis.value > 3200) + { + gamecontrol.press(BTN_RIGHT); + gsm.press(BTN_RIGHT); + } + else + { + gamecontrol.release(BTN_LEFT); + gamecontrol.release(BTN_RIGHT); + gsm.release(BTN_LEFT); + gsm.release(BTN_RIGHT); + } + + } + else if(ev.jaxis.axis == km.js_ud) + { + if(ev.jaxis.value < -3200) + { + gamecontrol.press(BTN_UP); + gsm.press(BTN_UP); + } + else if(ev.jaxis.value > 3200) + { + gamecontrol.press(BTN_DOWN); + gsm.press(BTN_DOWN); + } + else + { + gamecontrol.release(BTN_UP); + gamecontrol.release(BTN_DOWN); + gsm.release(BTN_UP); + gsm.release(BTN_DOWN); + } + + } + case SDL_MOUSEMOTION: + mouse_x = (int)(ev.motion.x / gengine->xscale()) - km.xoffs; + mouse_y = (int)(ev.motion.y / gengine->yscale()) - km.yoffs; + if(prefs->use_mouse) + gamecontrol.mouse_position( + mouse_x - 8 - MARGIN - WSIZE/2, + mouse_y - MARGIN - WSIZE/2); + break; + case SDL_MOUSEBUTTONDOWN: + mouse_x = (int)(ev.motion.x / gengine->xscale()) - km.xoffs; + mouse_y = (int)(ev.motion.y / gengine->yscale()) - km.yoffs; + gsm.press(BTN_FIRE); + if(prefs->use_mouse) + { + gamecontrol.mouse_position( + mouse_x - 8 - MARGIN - WSIZE/2, + mouse_y - MARGIN - WSIZE/2); + switch(ev.button.button) + { + case SDL_BUTTON_LEFT: + mouse_left = 1; + break; + case SDL_BUTTON_MIDDLE: + mouse_middle = 1; + break; + case SDL_BUTTON_RIGHT: + mouse_right = 1; + break; + } + gamecontrol.press(BTN_FIRE); + } + break; + case SDL_MOUSEBUTTONUP: + mouse_x = (int)(ev.motion.x / gengine->xscale()) - km.xoffs; + mouse_y = (int)(ev.motion.y / gengine->yscale()) - km.yoffs; + if(prefs->use_mouse) + { + gamecontrol.mouse_position( + mouse_x - 8 - MARGIN - WSIZE/2, + mouse_y - MARGIN - WSIZE/2); + switch(ev.button.button) + { + case SDL_BUTTON_LEFT: + mouse_left = 0; + break; + case SDL_BUTTON_MIDDLE: + mouse_middle = 0; + break; + case SDL_BUTTON_RIGHT: + mouse_right = 0; + break; + } + } + if(!mouse_left && !mouse_middle && !mouse_right) + { + if(prefs->use_mouse) + gamecontrol.release(BTN_FIRE); + gsm.release(BTN_FIRE); + } + break; + } + } + gamecontrol.process(); + + /* + * Run the current gamestate for one frame + */ + gsm.frame(); + + if(prefs->cmd_autoshot && !manage.game_stopped()) + { + static int c = 0; + ++c; + if(c >= 3) + { + gengine->screenshot(); + c = 0; + } + } +} + + +void kobo_gfxengine_t::pre_render() +{ + sound.run(); + gsm.pre_render(); +} + + +void kobo_gfxengine_t::post_render() +{ + gsm.post_render(); + + if(!prefs->cmd_noframe) + { + wmain->sprite(0, 0, B_FRAME_TL, 0, 0); + wmain->sprite(WSIZE - 16, 0, B_FRAME_TR, 0, 0); + wmain->sprite(0, WSIZE - 16, B_FRAME_BL, 0, 0); + wmain->sprite(WSIZE - 16, WSIZE - 16, B_FRAME_BR, 0, 0); + } + +#ifdef DEBUG + if(prefs->cmd_debug) + { + char buf[20]; + snprintf(buf, sizeof(buf), "Obj: %d", + gengine->objects_in_use()); + wmain->font(B_NORMAL_FONT); + wmain->string(160, 5, buf); + } + + switch (km.audio_vismode % 5) + { + case 0: + break; + case 1: + draw_osc(0); + break; + case 2: + draw_vu(); + break; + case 3: + draw_osc(1); + break; + case 4: + draw_osc(2); + break; + } +#endif + + // Frame rate counter + int nt = (int)SDL_GetTicks(); + int tt = nt - km.fps_starttime; + if((tt > 1000) && km.fps_count) + { + float f = km.fps_count * 1000.0 / tt; + ::screen.fps(f); + km.fps_count = 0; + km.fps_starttime = nt; + if(prefs->cmd_fps) + { + char buf[20]; + snprintf(buf, sizeof(buf), "%.1f", f); + km.dfps->text(buf); + if(!km.fps_results) + km.fps_results = (float *) + calloc(MAX_FPS_RESULTS, + sizeof(float)); + if(km.fps_results) + { + km.fps_results[km.fps_nextresult++] = f; + if(km.fps_nextresult >= MAX_FPS_RESULTS) + km.fps_nextresult = 0; + if(km.fps_nextresult > km.fps_lastresult) + km.fps_lastresult = km.fps_nextresult; + } + } + } + ++km.fps_count; + + // Frame rate limiter + if(prefs->max_fps) + { + if(prefs->max_fps_strict) + { + static double nextframe = -1000000.0f; + while(1) + { + double t = (double)SDL_GetTicks(); + if(fabs(nextframe - t) > 1000.0f) + nextframe = t; + double d = nextframe - t; + if(d > 10.0f) + SDL_Delay(10); + else if(d > 1.0f) + SDL_Delay(1); + else + break; + } + nextframe += 1000.0f / prefs->max_fps; + } + else + { + int rtime = nt - km.max_fps_begin; + km.max_fps_begin = nt; + km.max_fps_filter += (float)(rtime - km.max_fps_filter) * 0.3; + int delay = (int)(1000.0 / prefs->max_fps - + km.max_fps_filter + 0.5); + if((delay > 0) && (delay < 1100)) + SDL_Delay(delay); + km.max_fps_begin = (int)SDL_GetTicks(); + } + } +} + + +/*---------------------------------------------------------- + main() and related stuff +----------------------------------------------------------*/ + +static void put_usage() +{ + printf("\nKobo Deluxe %s\n", KOBO_VERSION); + printf("Usage: kobodl []\n"); + printf("Recognized options:\n"); + int s = -1; + while(1) + { + const char *fs; + s = prefs->find_next(s); + if(s < 0) + break; + switch(prefs->type(s)) + { + case CFG_BOOL: + fs = " -[no]%-16.16s[%s]\t%s%s\n"; + break; + case CFG_INT: + case CFG_FLOAT: + fs = " -%-20.20s[%s]\t%s%s\n"; + break; + case CFG_STRING: + fs = " -%-20.20s[\"%s\"]\t%s%s\n"; + break; + default: + continue; + } + printf(fs, prefs->name(s), prefs->get_default_s(s), + prefs->do_save(s) ? "" : "(Not saved!) ", + prefs->description(s)); + } +} + + +static void put_options_man() +{ + int s = -1; + while(1) + { + const char *fs; + s = prefs->find_next(s); + if(s < 0) + break; + switch(prefs->type(s)) + { + case CFG_BOOL: + fs = ".TP\n.B \\-[no]%s\n%s%s. Default: %s.\n"; + break; + case CFG_INT: + case CFG_FLOAT: + fs = ".TP\n.B \\-%s\n%s%s. Default: %s.\n"; + break; + case CFG_STRING: + fs = ".TP\n.B \\-%s\n%s%s. Default: \"%s\"\n"; + break; + default: + continue; + } + printf(fs, prefs->name(s), + prefs->do_save(s) ? "" : "(Not saved!) ", + prefs->description(s), + prefs->get_default_s(s)); + } +} + + +extern "C" void emergency_close(void) +{ + km.close(); +} + + +extern "C" RETSIGTYPE breakhandler(int dummy) +{ + /* For platforms that drop the handlers on the first signal... */ + signal(SIGTERM, breakhandler); + signal(SIGINT, breakhandler); + km.brutal_quit(); +#if (RETSIGTYPE != void) + return 0; +#endif +} + + +int main(int argc, char *argv[]) +{ + int cmd_exit = 0; + atexit(emergency_close); + signal(SIGTERM, breakhandler); + signal(SIGINT, breakhandler); + + SDL_Init(0); + + if(main_init()) + { + fprintf(stderr, "INTERNAL ERROR\n"); + return 1; + }; + + km.open_logging(NULL); + + setup_dirs(argv[0]); + --argc; + ++argv; + + if((argc < 1) || (strcmp("-override", argv[0]) != 0)) + km.load_config(prefs); + + if((prefs->parse(argc, argv) < 0) || prefs->cmd_help) + { + put_usage(); + main_cleanup(); + return 1; + } + + if(prefs->cmd_options_man) + { + put_options_man(); + main_cleanup(); + return 1; + } + + if(prefs->cmd_noparachute) + { + SDL_Quit(); + SDL_Init(SDL_INIT_NOPARACHUTE); + } + + km.open_logging(prefs); + + for(int a = 0; a < argc; ++a) + log_printf(DLOG, "argv[%d] = \"%s\"\n", a, argv[a]); + + int k = -1; + while((k = prefs->find_next(k)) >= 0) + { + log_printf(D3LOG, "key %d: \"%s\"\ttype=%d\t\"%s\"\n", + k, + prefs->name(k), + prefs->type(k), + prefs->description(k) + ); + } + + add_dirs(prefs); + + if(prefs->cmd_hiscores) + { + scorefile.gather_high_scores(); + scorefile.print_high_scores(); + cmd_exit = 1; + } + + if(prefs->cmd_showcfg) + { + printf("Configuration:\n"); + printf("----------------------------------------\n"); + prefs->write(stdout); + printf("\nPaths:\n"); + printf("----------------------------------------\n"); + fmap->print(stdout, "*"); + printf("----------------------------------------\n"); + cmd_exit = 1; + } + + if(cmd_exit) + { + km.close_logging(); + main_cleanup(); + return 0; + } + + if(km.open() < 0) + { + km.close_logging(); + main_cleanup(); + return 1; + } + + km.run(); + + km.close(); + + /* + * Seems like we got all the way here without crashing, + * so let's save the current configuration! :-) + */ + if(prefs->changed) + { + km.save_config(prefs); + prefs->changed = 0; + } + + if(prefs->cmd_fps) + km.print_fps_results(); + + km.close_logging(); + main_cleanup(); + return 0; +} diff --git a/kobo.h b/kobo.h new file mode 100644 index 0000000..19fedea --- /dev/null +++ b/kobo.h @@ -0,0 +1,167 @@ +/* +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 1995, 1996 Akira Higuchi + * Copyright (C) 2001-2003, 2005, 2007 David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _KOBO_H_ +#define _KOBO_H_ + +#include "gfxengine.h" +#include "window.h" +#include "display.h" +#include "filemap.h" +#include "prefs.h" +#include "radar.h" +#include "dashboard.h" +#include "sound.h" +#include "region.h" + +/*---------------------------------------------------------- + Singletons +----------------------------------------------------------*/ +extern KOBO_sound sound; + + +/*---------------------------------------------------------- + Globals +----------------------------------------------------------*/ + +class kobo_gfxengine_t : public gfxengine_t +{ + void frame(); + void pre_render(); + void post_render(); + public: + kobo_gfxengine_t(); +}; + +extern kobo_gfxengine_t *gengine; +extern filemapper_t *fmap; +extern prefs_t *prefs; + +extern screen_window_t *wscreen; +extern dashboard_window_t *wdash; +extern bargraph_t *whealth; +extern bargraph_t *wtemp; +extern bargraph_t *wttemp; +extern radar_map_t *wmap; +extern radar_window_t *wradar; +extern window_t *wmain; +extern display_t *dhigh; +extern display_t *dscore; +extern display_t *dstage; +extern display_t *dships; + +extern RGN_region *logo_region; + +extern int mouse_x, mouse_y; +extern int mouse_left, mouse_middle, mouse_right; + +extern int exit_game; + + +/* Sprite priority levels */ +#define LAYER_OVERLAY 0 // Mouse crosshair +#define LAYER_BULLETS 1 // Bullets - most important! +#define LAYER_FX 2 // Explosions and similar effects +#define LAYER_PLAYER 3 // Player and fire bolts +#define LAYER_ENEMIES 4 // Enemies +#define LAYER_BASES 5 // Bases and stationary enemies + +/* Graphics banks */ +typedef enum +{ + B_TILES1 = 0, + B_TILES2, + B_TILES3, + B_TILES4, + B_TILES5, + + B_OLDSTARS, + B_CROSSHAIR, + B_PLAYER, + B_BULLETS, + B_BULLETEXPL, + B_RING, + B_RINGEXPL, + B_BOMB, + B_BOMBDETO, + B_BOLT, + B_BOLTEXPL, + B_EXPLO1, + B_EXPLO3, + B_EXPLO4, + B_EXPLO5, + B_ROCK1, + B_ROCK2, + B_ROCK3, + B_ROCKEXPL, + B_BMR_GREEN, + B_BMR_PURPLE, + B_BMR_PINK, + B_FIGHTER, + B_MISSILE1, + B_MISSILE2, + B_MISSILE3, + B_BIGSHIP, + + B_NOISE, + B_HITNOISE, + B_FOCUSFX, + + B_SCREEN, + B_FRAME_TL, + B_FRAME_TR, + B_FRAME_BL, + B_FRAME_BR, + B_LOGO, + B_LOGOMASK, + B_LOGODELUXE, + B_BRUSHES, + + B_HIGH_BACK, + B_SCORE_BACK, + B_RADAR_BACK, + B_SHIPS_BACK, + B_STAGE_BACK, + + B_HEALTH_LID, + B_TEMP_LID, + B_TTEMP_LID, + + B_LOADING, + B_NORMAL_FONT, + B_MEDIUM_FONT, + B_BIG_FONT, + B_COUNTER_FONT +} KOBO_Banks; + +#define NOALPHA_THRESHOLD 64 + +#define INTRO_SCENE -100000 + +typedef enum +{ + STARFIELD_NONE = 0, + STARFIELD_OLD, + STARFIELD_PARALLAX +} KOBO_StarfieldModes; + +#endif // _KOBO_H_ diff --git a/kobodl.6 b/kobodl.6 new file mode 100644 index 0000000..7395f1f --- /dev/null +++ b/kobodl.6 @@ -0,0 +1,378 @@ +.TH KOBODL 6 "26 December 2007" +.SH NAME +kobodl - Kobo Deluxe, an enhanced version of the scrolling game XKobo +.SH SYNOPSIS +.B kobodl +[ +.I options +] +.SH DESCRIPTION +Kobo Deluxe is a 3'rd person scrolling 2D shooter with a simple and responsive +control system - which you'll need to tackle the tons of enemy ships that shoot +at you, chase you, circle around you shooting, or even launch other ships at +you, while you're trying to destroy the labyrinth shaped bases. There are 50 +action packed levels with smoothly increasing difficulty, and different +combinations of enemies that require different tactics to be dealt with +successfully. +.P +Kobo Deluxe has an improved graphics engine that delivers smoother animation, +while keeping the game logic totally accurate and predictable regardless of +frame rate. It also adds sound effects, new graphics, fullscreen mode, four +extra skill levels with smoother gameplay and various other features expected +from a modern game. (There is still a "Clasic" mode that plays exactly like the +original XKobo.) +.P +Kobo Deluxe uses SDL for sound, graphics and input, and builds and runs on all +major operating systems, as well as some more unusual platforms. It can also +use OpenGL for accelerated rendering, through glSDL. +.P +In short, Kobo Deluxe is loads of classical arcade style fun for just about any +machine with graphics and sound! +.SH CONTROLS +The ship can be controlled with the keyboard, or optionally a mouse or +joystick. With the keyboard, the arrow keys move the ship (two keys for +diagonals), and the shift and ctrl keys shoots. The numeric key pad can also be +used; the usual 2/4/6/8 (arrows), and also 1/3/7/9 for single key diagonals. +Escape enters the meny system, from where it is possible to change settings, +start a new game or exit the game. +.SH OPTIONS +Note that all relevant options can be also configured in the config file, +which can be edited directly, or using the options menus in the game. +.TP +.B \-[no]logfile +Log To File. Default: Off. +.TP +.B \-logformat +Log File Format. Default: 0. +.TP +.B \-logverbosity +Log Verbosity Level. Default: 2. +.TP +.B \-[no]joystick +Use Joystick. Default: Off. +.TP +.B \-joystick_no +Joystick Number. Default: 0. +.TP +.B \-[no]mouse +Use Mouse. Default: Off. +.TP +.B \-mousemode +Mouse Control Mode. Default: 1. +.TP +.B \-[no]broken_numdia +Broken NumPad Diagonals. Default: Off. +.TP +.B \-dia_emphasis +Diagonals Emphasis Filter. Default: 0. +.TP +.B \-[no]always_fire +Always Fire. Default: Off. +.TP +.B \-[no]mousecapture +In-game Mouse Capture. Default: On. +.TP +.B \-scrollradar +Radar Scroll Mode. Default: 2. +.TP +.B \-[no]filter +Enable/disable motion interpolation. Interpolation is what makes animation +smooth at high frame rates despite the game logic running at 33.33 fps. +However, it also adds some input latency! Default: On. +.TP +.B \-timefilter +Time filter, for smoothing out timing jitter induced by the operating system. +Default: 50. +.TP +.B \-countdown +Get Ready Countdown. Default: 5. +.TP +.B \-starfield +Starfield Style. Default: 2. +.TP +.B \-stars +Number of Parallax Stars. Default: 500. +.TP +.B \-overheatloud +Overheat Warning Loudness. Default: 100. +.TP +.B \-cannonloud +Player Cannons Loudness. Default: 100. +.TP +.B \-[no]sound +Enable Sound. Default: On. +.TP +.B \-[no]music +Enable Music. Default: On. +.TP +.B \-[no]cached_sounds +Use Cached Sounds. Default: Off. +.TP +.B \-[no]oss +Use OSS Sound Driver. Default: Off. +.TP +.B \-samplerate +Sample Rate. Default: 44100. +.TP +.B \-latency +Sound Latency. Default: 50. +.TP +.B \-mixquality +Mixing Quality. Default: 3. +.TP +.B \-vol +Master Volume. Default: 100. +.TP +.B \-intro_vol +Intro Music Volume. Default: 100. +.TP +.B \-sfx_vol +Sound Effects Volume. Default: 100. +.TP +.B \-music_vol +In-Game Music Volume. Default: 30. +.TP +.B \-reverb +Reverb Level. Default: 100. +.TP +.B \-vol_boost +Volume Boost. Default: 0. +.TP +.B \-[no]fullscreen +Fullscreen Display. Default: Off. +.TP +.B \-videodriver +Display Driver. Default: 0. +.TP +.B \-width +Horizontal Resolution. Default: 640. +.TP +.B \-height +Vertical Resolution. Default: 480. +.TP +.B \-aspect +Pixel Aspect Ratio. Default: 1000. +.TP +.B \-depth +Display Depth. Default: 0. +.TP +.B \-maxfps +Limit the framerate (fps). Saves power on laptops (75 works well), and can also +avoid long stalls due to timesharing and background processes. Default: 100. +.TP +.B \-maxfpsstrict +Strictly Regulated fps. Default: 0. +.TP +.B \-buffer +Display Buffer Mode. Default: 1. +.TP +.B \-[no]shadow +Use Software Shadow Buffer. Default: On. +.TP +.B \-videomode +Video Mode. Default: 17200. +.TP +.B \-[no]vsync +Enable Vertical Sync. Default: On. +.TP +.B \-videopages +Number of Video Pages. Default: -1. +.TP +.B \-scalemode +Scaling Filter Mode. Default: 1. +.TP +.B \-[no]dither +Use Dithering. Default: On. +.TP +.B \-dither_type +Dither Type. Default: 0. +.TP +.B \-[no]broken_rgba8 +Broken RGBA (OpenGL). Default: Off. +.TP +.B \-[no]alpha +Use Alpha Blending. Default: On. +.TP +.B \-brightness +Brightness. Default: 100. +.TP +.B \-contrast +Contrast. Default: 100. +.TP +.B \-files +Specify the root path of the game. Default: "" +.TP +.B \-gfx +Specify the path to the game's graphics data. Default: "" +.TP +.B \-sfx +Specify the path to the game's sound data. Default: "" +.TP +.B \-scores +Specify the path to the game's score files. Default: "" +.TP +.B \-size +(Not saved!) Screen Size (Obsolete). Default: 0. +.TP +.B \-wait +Game Speed (Obsolete). Default: 30. +.TP +.B \-bgm +(Not saved!) Background Music File (Obsolete). Default: "" +.TP +.B \-threshold +(Not saved!) Limiter Gain. Default: 200. +.TP +.B \-release +(Not saved!) Limiter Speed. Default: 50. +.TP +.B \-internalres +(Not saved!) Texture Resolution. Default: 1. +.TP +.B \-last_profile +Last used player profile. Default: 0. +.TP +.B \-number_of_joysticks +Number of Connected Joysticks. Default: 0. +.TP +.B \-[no]showcfg +(Not saved!) Show Configuration. Default: Off. +.TP +.B \-[no]hiscores +(Not saved!) List High Scores. Default: Off. +.TP +.B \-[no]highscores +(Not saved!) List High Scores. Default: Off. +.TP +.B \-[no]override +(Not saved!) Ignore Configuration File. Default: Off. +.TP +.B \-[no]debug +(Not saved!) Enable Debug Features. Default: Off. +.TP +.B \-[no]fps +(Not saved!) Display frames per second in game screen. Default: Off. +.TP +.B \-[no]noframe +(Not saved!) Do not render rounded corners on the playfield. Default: Off. +.TP +.B \-[no]midi +(Not saved!) Enable MIDI Input. Default: Off. +.TP +.B \-[no]cheat +(Not saved!) Enable/disable cheat mode. Cheat mode allows any level to be +played, but highscores are not saved! Default: Off. +.TP +.B \-[no]indicator +(Not saved!) Enable Collision Indicator Mode. Default: Off. +.TP +.B \-[no]pushmove +(Not saved!) Enable Push Move Mode. Default: Off. +.TP +.B \-[no]noparachute +(Not saved!) Disable SDL Parachute. Default: Off. +.TP +.B \-[no]pollaudio +(Not saved!) Use Polling Audio Output. Default: Off. +.TP +.B \-[no]autoshot +(Not saved!) Ingame screenshots/movie. Default: Off. +.TP +.B \-[no]help +(Not saved!) Print usage info and exit. Default: Off. +.TP +.B \-[no]options_man +(Not saved!) Print options for 'man'. Default: Off. +.SH FILES +.TP +.B ~/.kobodlrc +The per-user configuration file for Kobo Deluxe. +.SH AUTHORS +Originally written by +Akira Higuchi (a-higuti@math.hokudai.ac.jp), XKobo was turned into Kobo +Deluxe by David Olofson +.SH THANKS +Thanks, in no particular order, to... +.TP +.B Akira Higuchi +Author of the Original XKobo. +.TP +.B Masanao Izumo +Sound effects and original sound engine. +.TP +.B Torsten Giebl +Slackware. +.TP +.B David Andersson +Various Good Ideas. +.TP +.B Max Horn +Mac OS X & Build Script Patches. +.TP +.B Jeremy Sheeley +Player Profiles. +.TP +.B Tsuyoshi Iguchi +FreeBSD, NetBSD. +.TP +.B Samuel Hart +Joystick Support. +.TP +.B G. Low +Solaris. +.TP +.B Gerry Jo "Trick" Jellestad +Testing and ideas. +.TP +.B "Riki" +Intel Compiler. +.TP +.B Andreas Spaangberg +Sun Compiler & Bug Spotting. +.TP +.B "SixK" +Amiga Port. +.TP +.B Joey Hess +Debian. +.TP +.B Martijn van Oosterhout +FPS limiter. +.TP +.B Antonio Messina +Stage 1601+ difficulty wrap, Always Fire option. +.TP +.B Hans de Goede +Audio buffer handling bug. +.TP +.B Marianne Ibbotson +"Autopause" idea. +.TP +.B Sam Palmer +MS Windows testing. +.TP +.B Michael Sterrett +glSDL issues. +.TP +.B Sam Lantinga & Others +SDL, the Simple DirectMedia library. +.TP +.B Members of the SDL mailing list +Testing and ideas. +.SH COPYRIGHT +Copyright (c) 1995, 1996 Akira Higuchi +.P +Copyright (C) 1997 Masanao Izumo +.P +Copyright (C) 1999-2001 Simon Peter +.P +Copyright (C) 2002 Florian Schulze +.P +Copyright (C) 2002 Jeremy Sheeley +.P +Copyright (C) 2005 Erik Auerswald +.P +Copyright (c) 1999-2007 David Olofson +.P +\fBKobo Deluxe\fP is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License. diff --git a/kobolog.h b/kobolog.h new file mode 100644 index 0000000..a80e41c --- /dev/null +++ b/kobolog.h @@ -0,0 +1,44 @@ +/*(GPL) +------------------------------------------------------------ + Kobo Deluxe - Logger definitions +------------------------------------------------------------ + * Copyright (C) 2003, David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef KOBOLOG_H +#define KOBOLOG_H + +#include "logger.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Critical error messages: "Huston, we have a problem." */ +#define CELOG 5 + +/* Debug messages; level 2: Detailed */ +#define D2LOG 6 + +/* Debug messages; level 3: Deep Hack Mode stuff */ +#define D3LOG 7 + +#ifdef __cplusplus +}; +#endif + +#endif /* KOBOLOG_H */ diff --git a/logger.c b/logger.c new file mode 100644 index 0000000..f315c2b --- /dev/null +++ b/logger.c @@ -0,0 +1,484 @@ +/*(LGPL) +--------------------------------------------------------------------------- + logger.c - Simple logger with redirection +--------------------------------------------------------------------------- + * Copyright (C) 2003, David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include + +#include "config.h" +#include "logger.h" +#include "glSDL.h" + +#define LOG_BUFFER 1024 + +static int i__last; +#define for_one_or_all(iterator, index, items) \ + if(index < LOG_TARGETS) \ + { \ + if(index >= 0) \ + iterator = i__last = index; \ + else \ + { \ + iterator = 0; \ + i__last = items - 1; \ + } \ + } \ + else \ + { \ + iterator = 0; \ + i__last = -10; \ + } \ + --iterator; \ + while(++iterator <= i__last) + + +typedef struct +{ + /* Stream output */ + int use_stream; + FILE *stream; + + /* Callback output */ + int handle; + int (*callback)(int handle, const char *data); + + /* Formatting control */ + unsigned flags; + int written; +} LOG_target; + + +typedef struct +{ + /* Output */ + int target; + + /* Atributes */ + unsigned attr; +} LOG_level; + + +static LOG_level *l_levels = NULL; +static LOG_target *l_targets = NULL; +static char *l_buffer = NULL; + +Uint32 start_time; + + +/*-------------------------------------------------------------------- + Low level internal stuff +--------------------------------------------------------------------*/ + +/* Write stuff without any translation */ +static inline int log_write_raw(int target, const char *text) +{ + if(l_targets[target].use_stream) + return fputs(text, l_targets[target].stream); + else if(l_targets[target].callback) + return l_targets[target].callback( + l_targets[target].handle, text); + else + { + /* We should never get here. */ + assert(0); + } +} + + +/* Write log file header if applicable. */ +static inline void check_header(int target) +{ + if(l_targets[target].written) + return; + + if(l_targets[target].flags & LOG_HTML) + { + log_write_raw(target, "\n"); + log_write_raw(target, "\n\t\n"); + log_write_raw(target, "\t\tLog File\n"); + log_write_raw(target, "\t\t\n"); + log_write_raw(target, "\t\n"); + log_write_raw(target, "\t\n"); + } + l_targets[target].written = 1; +} + + +/* Write log file footer if applicable. */ +static inline void check_footer(int target) +{ + if(!l_targets[target].written) + return; + + if(l_targets[target].flags & LOG_HTML) + log_write_raw(target, "\t\n\n"); +} + + +/* Write converting/escaping any reserved characters as needed */ +static inline int log_write(int target, const char *text) +{ + int i; + if(l_targets[target].flags & LOG_HTML) + { +/* +FIXME: Optimize this a little, maybe. :-) +*/ + char buf[2] = "\0\0"; + int last = -1; + for(i = 0; text[i]; ++i) + { + buf[0] = text[i]; + switch(text[i]) + { + case '\n': + log_write_raw(target, "
    \n"); + break; + case ' ': + if(' ' == last) + log_write_raw(target, " "); + else + log_write_raw(target, " "); + break; + case '<': + log_write_raw(target, "<"); + break; + case '>': + log_write_raw(target, ">"); + break; + case '&': + log_write_raw(target, "&"); + break; + default: + log_write_raw(target, buf); + break; + } + last = text[i]; + } + return i; + } + else + return log_write_raw(target, text); +} + + +static inline void put_timestamp(int level) +{ + if(l_targets[l_levels[level].target].flags & LOG_TIMESTAMP) + { + char buf[16]; + snprintf(buf, sizeof(buf)-1, "[%d] ", SDL_GetTicks() - start_time); + log_write_raw(l_levels[level].target, buf); + } +} + + +#define ANSI_SUPPORTED_FLAGS (LOG_COLORS | LOG_BRIGHT | LOG_STRONG | LOG_BLINK) +#define HTML_SUPPORTED_FLAGS (LOG_COLORS | LOG_BRIGHT | LOG_STRONG | LOG_BLINK) + +static inline void set_attr(int level) +{ + unsigned a = l_levels[level].attr; + if(l_targets[l_levels[level].target].flags & LOG_ANSI) + { +#define SEP if('[' != buf[pos - 1]) buf[pos++] = ';' + int pos = 0; + char buf[24]; + if(!(a & ANSI_SUPPORTED_FLAGS)) + return; + + buf[pos++] = '\033'; + buf[pos++] = '['; + if(a & LOG_COLORS) + { + buf[pos++] = '3'; + buf[pos++] = '0' + (a & LOG_COLORS) - 1; + } + if(a & LOG_BRIGHT) + { + SEP; + buf[pos++] = '1'; + } + if(a & LOG_STRONG) + { + SEP; + buf[pos++] = '4'; + } + if(a & LOG_BLINK) + { + SEP; + buf[pos++] = '5'; + } + buf[pos++] = 'm'; + buf[pos++] = '\0'; + log_write_raw(l_levels[level].target, buf); +#undef SEP + } + else if(l_targets[l_levels[level].target].flags & LOG_HTML) + { + if(a & LOG_COLORS) + { + const char *sel; + if(a & LOG_BRIGHT) + switch( (a & LOG_COLORS) - 1) + { + case 0: sel = ""; break; + case 1: sel = ""; break; + case 2: sel = ""; break; + case 3: sel = ""; break; + case 4: sel = ""; break; + case 5: sel = ""; break; + case 6: sel = ""; break; + case 7: + default: + sel = ""; break; + } + else + switch( (a & LOG_COLORS) - 1) + { + case 0: sel = ""; break; + case 1: sel = ""; break; + case 2: sel = ""; break; + case 3: sel = ""; break; + case 4: sel = ""; break; + case 5: sel = ""; break; + case 6: sel = ""; break; + case 7: + default: + sel = ""; break; + } + log_write_raw(l_levels[level].target, sel); + } + if(a & LOG_STRONG) + log_write_raw(l_levels[level].target, ""); + if(a & LOG_BLINK) + log_write_raw(l_levels[level].target, ""); + } +} + + +static inline void reset_attr(int level) +{ + unsigned a = l_levels[level].attr; + if(l_targets[l_levels[level].target].flags & LOG_ANSI) + { + if(!(a & ANSI_SUPPORTED_FLAGS)) + return; + + log_write_raw(l_levels[level].target, "\033[0m"); + } + else if(l_targets[l_levels[level].target].flags & LOG_HTML) + { + if(a & LOG_BLINK) + log_write_raw(l_levels[level].target, ""); + if(a & LOG_STRONG) + log_write_raw(l_levels[level].target, ""); + if(a & LOG_COLORS) + log_write_raw(l_levels[level].target, ""); + } +} + + +static inline int is_active(int level) +{ + LOG_target *t = &l_targets[l_levels[level].target]; + return (t->use_stream || t->callback); +} + + +/*-------------------------------------------------------------------- + API entry points +--------------------------------------------------------------------*/ + +int log_open(void) +{ + if(l_levels) + return 0; + + l_levels = calloc(LOG_LEVELS, sizeof(LOG_level)); + if(!l_levels) + return -1; + + l_targets = calloc(LOG_TARGETS, sizeof(LOG_target)); + if(!l_targets) + { + log_close(); + return -2; + } + l_buffer = calloc(1, LOG_BUFFER); + if(!l_buffer) + { + log_close(); + return -3; + } + + log_set_target_stream(-1, stdout); + log_set_target_flags(-1, 0); + + log_set_level_target(-1, 0); + log_set_level_attr(-1, LOG_NOCOLOR); + + start_time = SDL_GetTicks(); + return 0; +} + + +#define CHECK_INIT (l_levels ? 0 : -1) + + +void log_close(void) +{ + int i; + if(CHECK_INIT < 0) + return; + for(i = 0; i < LOG_TARGETS; ++i) + check_footer(i); + free(l_targets); + l_targets = NULL; + free(l_levels); + l_levels = NULL; + free(l_buffer); + l_buffer = NULL; +} + + +void log_set_target_stream(int target, FILE *stream) +{ + int i; + if(CHECK_INIT < 0) + return; + + for_one_or_all(i, target, LOG_TARGETS) + { + l_targets[i].callback = NULL; + l_targets[i].stream = stream; + l_targets[i].use_stream = (stream != NULL); + } +} + + +void log_set_target_callback(int target, + int (*callback)(int handle, const char *data), int handle) +{ + int i; + if(CHECK_INIT < 0) + return; + + for_one_or_all(i, target, LOG_TARGETS) + { + l_targets[i].use_stream = 0; + l_targets[i].callback = callback; + l_targets[i].handle = handle; + } +} + + +void log_set_target_flags(int target, unsigned flags) +{ + int i; + if(CHECK_INIT < 0) + return; + + for_one_or_all(i, target, LOG_TARGETS) + l_targets[i].flags = flags; +} + + +void log_set_level_target(int level, int target) +{ + int i; + if(CHECK_INIT < 0) + return; + + for_one_or_all(i, level, LOG_LEVELS) + l_levels[i].target = target; +} + + +void log_set_level_attr(int level, unsigned attr) +{ + int i; + if(CHECK_INIT < 0) + return; + + for_one_or_all(i, level, LOG_LEVELS) + l_levels[i].attr = attr; +} + + +int log_puts(int level, const char *text) +{ + int result, result2; + + if(CHECK_INIT < 0) + return -1; + + if(level < 0 || level >= LOG_LEVELS) + return -2; + + if(!is_active(level)) + return 0; + + check_header(l_levels[level].target); + set_attr(level); + put_timestamp(level); + + result = log_write(l_levels[level].target, text); + if(result >= 0) + { + result2 = log_write_raw(l_levels[level].target, "\n"); + if(result2 >= 0) + result += result2; + } + reset_attr(level); + return result; +} + + +int log_printf(int level, const char *format, ...) +{ + va_list args; + int result; + + if(CHECK_INIT < 0) + return -1; + + if(level < 0 || level >= LOG_LEVELS) + return -2; + + if(!is_active(level)) + return 0; + + check_header(l_levels[level].target); + set_attr(level); + put_timestamp(level); + + va_start(args, format); + result = vsnprintf(l_buffer, LOG_BUFFER-1, format, args); + va_end(args); + if(result >= 0) + result = log_write(l_levels[level].target, l_buffer); + reset_attr(level); + return result; +} diff --git a/logger.h b/logger.h new file mode 100644 index 0000000..2d100f6 --- /dev/null +++ b/logger.h @@ -0,0 +1,158 @@ +/*(LGPL) +--------------------------------------------------------------------------- + logger.h - Simple logger with redirection +--------------------------------------------------------------------------- + * Copyright (C) 2003, David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef DO_LOGGER_H +#define DO_LOGGER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* +TODO: Levels sending to multiple targets. +TODO: Printing to multiple levels. +*/ + +#define LOG_TARGETS 8 +#define LOG_LEVELS 32 + +/* + * Standard log levels (so libs and stuff can share your logger! :-) + */ +#define ULOG 0 /* User: Messages meant for normal users */ +#define WLOG 1 /* Warning: Warning messages */ +#define ELOG 2 /* Error: Error messages */ +#define VLOG 3 /* Verbose: Messages for advanced users */ +#define DLOG 4 /* Debug: Debug messages */ + + +typedef enum +{ + LOG_ANSI = 0x00000001, /* Use ANSI escape codes */ + LOG_HTML = 0x00000002, /* Use HTML formatting tags */ + LOG_TIMESTAMP = 0x00000100 /* Timestamp messages */ +} LOG_flags; + + +typedef enum +{ + LOG_COLORS = 0x000f, /* Mask for color bits */ + LOG_NOCOLOR = 0, /* Don't try to change! */ + LOG_BLACK, + LOG_RED, + LOG_GREEN, + LOG_YELLOW, + LOG_BLUE, + LOG_MAGENTA, + LOG_CYAN, + LOG_WHITE, + LOG_BRIGHT = 0x0100, /* High intensity colors */ + LOG_STRONG = 0x0200, /* Bold or underlined */ + LOG_BLINK = 0x0400 /* Blinking, if possible */ +} LOG_attributes; + + +/* + * The usual open/close calls... + * + * Note that log_close() may write footers and stuff to files, + * so you may get slightly broken log files if you exit + * without calling it! + * + * log_open() returns a negative value in case of failure. + */ +int log_open(void); +void log_close(void); + + +/* + * Send output through 'target' to 'stream'. 'stream' must be + * a valid stdio stream opened for output. + * + * If 'target' is -1, all targets are changed. + */ +void log_set_target_stream(int target, FILE *stream); + + +/* + * Send output through 'target' to 'callback'. The callback + * will receive the value passed as 'handle' as it's first + * argument, followed by the data to output. (NULL terminated + * string.) The callback should return the number of bytes + * successfully handled, or, in case of failure, a negative + * value. + * + * If 'target' is -1, all targets are changed. + */ +void log_set_target_callback(int target, + int (*callback)(int handle, const char *data), int handle); + + +/* + * Set formatting flags for 'target'. + * + * If 'target' is -1, all targets are changed. + */ +void log_set_target_flags(int target, unsigned flags); + + +/* + * Send output through 'level' to 'target'. 'levels' is a bit + * mask with one bit for each log level. + * + * If 'level' is -1, all levels are changed. + */ +void log_set_level_target(int level, int target); + + +/* + * Set attributes for 'level'. + * + * If 'level' is -1, all levels are changed. + */ +void log_set_level_attr(int level, unsigned attr); + + +/* + * Print 'text' to 'level'. 'level' is the index of the log + * level to print to. No formatting will be done, and the + * output will be followed by a "newline". + * + * Returns a negative value in case of failure. + */ +int log_puts(int level, const char *text); + + +/* + * Format and print to 'level'. 'level' is the index of the + * log level to print to. + * + * Returns a negative value in case of failure. + */ +int log_printf(int level, const char *format, ...); + +#ifdef __cplusplus +}; +#endif + +#endif /* DO_LOGGER_H */ diff --git a/manage.cpp b/manage.cpp new file mode 100644 index 0000000..caa266f --- /dev/null +++ b/manage.cpp @@ -0,0 +1,730 @@ +/*(GPL) +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 1995, 1996 Akira Higuchi + * Copyright (C) 2002 Jeremy Sheeley + * Copyright (C) 2001-2003, 2007 David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +// Define to get time and ships lost printed out per finished stage +// NOTE: Also disables bonus ships! +#undef PLAYSTATS + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#ifndef M_PI +# define M_PI 3.14159265358979323846 /* pi */ +#endif + +#include "kobo.h" +#include "screen.h" +#include "manage.h" +#include "options.h" +#include "scenes.h" +#include "score.h" +#include "enemies.h" +#include "myship.h" +#include "radar.h" +#include "gamectl.h" +#include "states.h" +#include "audio.h" +#include "random.h" + +#define GIGA 1000000000 + +int _manage::blank = 0; +int _manage::next_state_out; +int _manage::next_state_next; +int _manage::game_seed; +int _manage::scene_num; +int _manage::ships; +int _manage::score; +float _manage::disp_health; +float _manage::disp_temp; +int _manage::score_changed = 1; +int _manage::ships_changed = 1; +int _manage::bonus_next; +int _manage::flush_score_count = 0; +int _manage::flush_ships_count = 0; +int _manage::scroll_jump = 0; +int _manage::delay_count; +int _manage::rest_cores; +int _manage::introtime = 0; +int _manage::exit_manage = 0; +int _manage::playing = 0; +int _manage::_get_ready = 0; +int _manage::_game_over = 0; +s_hiscore_t _manage::hi; +int _manage::noise_duration = 0; +int _manage::noise_timer = 0; +int _manage::noise_flash = 500; +float _manage::noise_level = 0.0f; +int _manage::intro_x = CHIP_SIZEX * (64-18); +int _manage::intro_y = CHIP_SIZEY * (64-7); +int _manage::show_bars = 0; + +#ifdef PLAYSTATS +static Uint32 start_time = 0; +static int start_ships = 0; +#endif + + +void _manage::set_bars() +{ + whealth->enable(show_bars); + wtemp->enable(show_bars); + wttemp->enable(show_bars); +} + + +// NOTE: +// After a noise out has faded out the sound effects, it's the +// noise/interfecence effect when the playfield is reinitialized +// that "accidentally" restores volume! +// +void _manage::run_noise() +{ + if(noise_flash == -2) + { + // Damage flash + noise_timer -= game.speed; + if(noise_timer <= 0) + noise_timer = 0; + screen.noise(noise_timer); + float t = (float)noise_timer / noise_duration; + wmain->background(wmain->map_rgb(wmain->fadergb(0xff0000, + (int)(t * noise_level * 64)))); + screen.set_noise(B_HITNOISE, t * noise_level, + t * noise_level, 0.0f); + return; + } + else if(noise_flash == -1) + { + // Noise-out + noise_timer -= game.speed; + if(noise_timer <= 0) + noise_timer = 0; + float t = (float)noise_timer / noise_duration; + float a = t * 2.0f * M_PI; + wmain->background(wmain->map_rgb(wmain->fadergb(0x00ff99, + (int)(sin(a * 0.5f) * 0.3f * 64)))); + screen.set_noise(B_NOISE, 1.0f - t, + sin(a * 0.5f) * 0.3f, + 0.3f + t * 0.5f); + sound.sfx_volume(t); + return; + } + + wmain->background(wmain->map_rgb(0x00000)); + + // Noise/interference + int noise; + if(noise_timer > noise_flash) + { + noise_timer -= game.speed; + noise = 1; + } + else if(noise_timer > 0) + { + unsigned prob = noise_flash - noise_timer; + prob <<= 8; + prob /= noise_flash; + noise_timer -= game.speed; + noise = pubrand.get(8) > prob; + } + else + { + noise_timer = 0; + noise = 0; + } + + noise_level += (noise - noise_level) * 0.3f; + screen.set_noise(B_NOISE, noise_level, 0.0f, noise_level); + screen.noise(noise_level > 0.1f); + + sound.ui_noise(noise); +} + + +void _manage::noise(int duration, int flash) +{ + noise_flash = flash; + noise_duration = noise_timer = duration; + sound.ui_noise(-1); + screen.set_noise(B_NOISE, 1.0f, 0.0f, 1.0f); + noise_level = 1.0f; +} + + +void _manage::noise_out(int duration) +{ + noise_flash = -1; + noise_duration = noise_timer = duration; + screen.noise(1); +} + + +void _manage::noise_damage(float amt) +{ + noise_flash = -2; + noise_duration = noise_timer = (int)(300.0f + 1500.0f * amt); + noise_level = 0.3f + 0.3f * amt; +} + + +void _manage::game_start() +{ + _game_over = 0; + hi.clear(); + + game.set(GAME_SINGLE, (skill_levels_t)scorefile.profile()->skill); + +#ifdef PLAYSTATS + ships = 100; +#else + ships = game.lives; +#endif + disp_health = 0; + disp_temp = 0; + score = 0; + flush_score_count = 0; + bonus_next = game.bonus_first; + gengine->period(game.speed); + sound.period(game.speed); + screen.init_scene(scene_num); + init_resources_to_play(1); + + gamecontrol.clear(); + gamecontrol.repeat(0, 0); + + playing = 1; + _get_ready = 1; + + hi.skill = game.skill; + hi.playtime = 0; + hi.gametype = game.type; +#if 1 + // The new skill levels are under development! + // We want to mark highscores so they're not mistaken + // for official scores from a future finalized version. + if(game.skill != SKILL_CLASSIC) + hi.gametype |= GAME_EXPERIMENTAL; +#endif + hi.saves = 0; + hi.loads = 0; + hi.start_scene = scene_num; + hi.end_lives = ships; + sound.g_music(SOUND_BGM); + +#ifdef PLAYSTATS + start_time = SDL_GetTicks(); + start_ships = ships; +#endif +} + + +void _manage::game_stop() +{ + if(!prefs->cmd_cheat && !prefs->cmd_pushmove) + { + hi.score = score; + hi.end_scene = scene_num; + hi.end_health = myship.health(); + + scorefile.record(&hi); + } + ships = 0; + ships_changed = 1; + audio_channel_stop(0, -1); + playing = 0; +} + +void _manage::next_scene() +{ +#ifdef PLAYSTATS + printf("stage %d:\n", scene_num); + Uint32 nst = SDL_GetTicks(); + printf(" time: %d s\n", (nst - start_time) / 1000); + printf(" deaths: %d\n", start_ships - ships); + start_time = nst; + start_ships = ships; +#endif + scene_num++; + if(scene_num >= GIGA - 1) + scene_num = GIGA - 2; + screen.init_scene(scene_num); + scroll_jump = 1; + _get_ready = 1; +} + + +void _manage::retry() +{ + if(!prefs->cmd_cheat) + { + ships--; + ships_changed = 1; + } + if(ships <= 0) + { + if(!_game_over) + { + game_stop(); + _game_over = 1; + } + } + else + _get_ready = 1; + gamecontrol.clear(); +} + + +void _manage::init_resources_title() +{ + noise(1000, 800); + screen.init_scene(INTRO_SCENE); + gengine->period(30); + sound.period(30); + gamerand.init(); + enemies.init(); + myship.init(); + myship.off(); + screen.prepare(); + screen.generate_fixed_enemies(); + put_info(); + put_score(); + put_ships(); + put_health(1); + put_temp(1); + run_intro(); + gengine->force_scroll(); + gamecontrol.repeat(KOBO_KEY_DELAY, KOBO_KEY_REPEAT); + show_bars = 0; + set_bars(); +} + + +void _manage::init_resources_to_play(int newship) +{ + noise(400, 300); + delay_count = 0; + flush_score_count = (flush_score_count) ? -1 : 0; + flush_ships_count = 0; + score_changed = 0; + next_state_out = 0; + next_state_next = 0; + + gamerand.init(); + game_seed = gamerand.get_seed(); + enemies.init(); + myship.init(); + if(newship) + myship.health(game.health); + rest_cores = screen.prepare(); + scroll_jump = 1; + screen.generate_fixed_enemies(); + put_info(); + put_score(); + put_ships(); + switch(game.skill) + { + case SKILL_CLASSIC: + show_bars = 0; + break; + case SKILL_NEWBIE: + case SKILL_GAMER: + case SKILL_ELITE: + case SKILL_GOD: + default: + show_bars = 1; + break; + } + set_bars(); + put_health(1); + put_temp(1); + myship.put(); + gengine->scroll(PIXEL2CS(myship.get_virtx()), + PIXEL2CS(myship.get_virty())); + gengine->force_scroll(); +} + + +void _manage::put_health(int force) +{ + int h = myship.health(); + if(h > disp_health) + { + disp_health += (float)game.health * .05; + if(disp_health > h) + disp_health = h; +// whealth->background(whealth->map_rgb(0, 100, 0)); + } + else if(h < disp_health) + { + disp_health -= (float)game.health * .1; + if(disp_health < h) + disp_health = h; +// whealth->background(whealth->map_rgb(128, 0, 0)); + } +// else +// whealth->background(whealth->map_rgb(0, 0, 0)); + whealth->value((float)disp_health / game.health); + if(force) + whealth->invalidate(); +} + + +void _manage::put_temp(int force) +{ + wtemp->value(myship.get_nose_temp() / 256.0f); + wttemp->value(myship.get_tail_temp() / 256.0f); + if(force) + { + wtemp->invalidate(); + wttemp->invalidate(); + } +} + + +void _manage::put_info() +{ + static char s[16]; + + snprintf(s, 16, "%010d", scorefile.highscore()); + dhigh->text(s); + dhigh->on(); + + snprintf(s, 16, "%03d", scene_num + 1); + dstage->text(s); + dstage->on(); + + score_changed = 1; + ships_changed = 1; +} + + +void _manage::put_score() +{ + if(score_changed) + { + static char s[32]; + snprintf(s, 16, "%010d", score); + dscore->text(s); + dscore->on(); + if(score > scorefile.highscore()) + { + dhigh->text(s); + dhigh->on(); + } + score_changed = 0; + } + if(flush_score_count > 0) + flush_score(); +} + + +void _manage::put_ships() +{ + if(ships_changed) + { + static char s[32]; + if(!prefs->cmd_cheat) + snprintf(s, 16, "%03d", ships); + else + snprintf(s, 16, "999"); + dships->text(s); + dships->on(); + ships_changed = 0; + } + if(flush_ships_count > 0) + flush_ships(); +} + + +void _manage::flush_score() +{ + flush_score_count--; + if(flush_score_count & 1) + return; + + if(flush_score_count & 2) + dscore->off(); + else + dscore->on(); + if(flush_score_count == 0) + flush_score_count = -1; +} + + +void _manage::flush_ships() +{ + flush_ships_count--; + if(flush_ships_count & 1) + return; + + if(flush_ships_count & 2) + dships->off(); + else + dships->on(); + if(flush_ships_count == 0) + flush_ships_count = -1; +} + + +/****************************************************************************/ +void _manage::init() +{ + scorefile.init(); + ships = 0; + exit_manage = 0; + scene_num = -1; + flush_ships_count = 0; + flush_score_count = 0; + delay_count = 0; + screen.init(); + init_resources_title(); +} + + +void _manage::run_intro() +{ + double t = SDL_GetTicks() * 0.001f; + gengine->scroll(PIXEL2CS(intro_x), PIXEL2CS(intro_y)); + intro_y -= 3; + intro_x &= MAP_SIZEX*CHIP_SIZEX-1; + intro_y &= MAP_SIZEY*CHIP_SIZEY-1; + sound.g_position(intro_x + (WSIZE >> 1), intro_y + (WSIZE >> 1)); + myship.set_position(intro_x + (WSIZE >> 1) + (int)(WSIZE * 0.3f * sin(t)), + intro_y + (WSIZE >> 1) + (int)(WSIZE * 0.3f * sin(t * 1.73))); + enemies.move_intro(); + enemies.put(); + + put_health(); + put_temp(); + put_score(); + put_ships(); + + run_noise(); +} + + +void _manage::update() +{ + myship.put(); + enemies.put(); + put_score(); + put_ships(); + gengine->scroll(PIXEL2CS(myship.get_virtx()), + PIXEL2CS(myship.get_virty())); + if(scroll_jump) + { + gengine->force_scroll(); + scroll_jump = 0; + } + run_noise(); +} + + +void _manage::run_pause() +{ + put_health(); + put_temp(); + update(); +} + + +void _manage::run_game() +{ + put_health(); + put_temp(); + + if(delay_count) + delay_count--; + + if(delay_count == 1) + { + if(enemies.exist_pipe()) + delay_count = 2; + else + { + int newship = next_state_out; + put_info(); + if(next_state_out) + { + retry(); + if(ships <= 0) + return; + } + if(next_state_next) + next_scene(); + init_resources_to_play(newship); + return; + } + } + + myship.move(); + enemies.move(); + myship.hit_structure(); + update(); + ++hi.playtime; +} + + +void _manage::lost_myship() +{ + if(delay_count == 0) + delay_count = 100; + next_state_out = 1; +} + + +void _manage::destroyed_a_core() +{ + // Award 10% health bonus for destroyed core! + myship.health_bonus(10); + rest_cores--; + if(rest_cores == 0) + { + next_state_next = 1; + delay_count = 50; + // Award another 25% health bonus for stage cleared! + myship.health_bonus(25); + } + screen.generate_fixed_enemies(); +} + + +void _manage::add_score(int sc) +{ + score += sc; + if(score >= GIGA) //This *could* happen... Or maybe not. :-) + score = GIGA - 1; + else if(!prefs->cmd_cheat) + { +#ifndef PLAYSTATS + if(score >= bonus_next) + { + bonus_next += game.bonus_every; + ships++; + ships_changed = 1; + flush_ships_count = 50; + sound.ui_oneup(); + } +#endif + if(score >= scorefile.highscore()) + { + if(flush_score_count == 0) + flush_score_count = 50; + } + } + score_changed = 1; +} + + +void _manage::select_next(int redraw_map) +{ + if((scene_num < scorefile.last_scene()) || prefs->cmd_cheat) + { + sound.ui_tick(); + scene_num++; + } + else + sound.ui_error(); + select_scene(scene_num); +} + + +void _manage::select_prev(int redraw_map) +{ + scene_num--; + if(scene_num < 0) + { + sound.ui_error(); + scene_num = 0; + } + else + sound.ui_tick(); + select_scene(scene_num); +} + + +void _manage::regenerate() +{ + sound.ui_tick(); + select_scene(scene_num, 1); +} + + +void _manage::select_scene(int scene, int redraw_map) +{ + scene_num = scene; + put_info(); + if(redraw_map) + screen.init_scene(-scene_num - 1); + noise(150, 0); +} + + +void _manage::abort() +{ + if(!exit_manage) + { + game_stop(); + exit_manage = 1; + } +} + + +void _manage::freeze_abort() +{ + exit_manage = 1; +} + + +void _manage::reenter() +{ + exit_manage = 0; + put_health(1); + put_temp(1); + put_info(); + put_score(); + put_ships(); +} + + +int _manage::get_ready() +{ + if(_get_ready) + { + _get_ready = 0; + return 1; + } + return 0; +} + + +int _manage::game_over() +{ + return _game_over; +} diff --git a/manage.h b/manage.h new file mode 100644 index 0000000..24cd294 --- /dev/null +++ b/manage.h @@ -0,0 +1,110 @@ +/*(GPL) +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 1995, 1996 Akira Higuchi + * Copyright (C) 2002 Jeremy Sheeley + * Copyright (C) 2001-2003, 2007 David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _KOBO_MANAGE_H_ +#define _KOBO_MANAGE_H_ + +#include "glSDL.h" +#include "score.h" + +class _manage +{ + static int blank; + static int next_state_out; + static int next_state_next; + static int game_seed; + static int bonus_next; + static int scroll_jump; + static int delay_count; + static int introtime; + static int rest_cores; + static int exit_manage; + static int playing; + static int _get_ready; + static int _game_over; + static s_hiscore_t hi; + static int noise_flash; + static int noise_duration; + static int noise_timer; + static float noise_level; + static int intro_x; + static int intro_y; + static int show_bars; + + static void next_scene(); + static void retry(); + + static int scene_num; + static int score; + static float disp_health; + static float disp_temp; + static int flush_score_count; + static int flush_ships_count; + static int score_changed; + static int ships_changed; + static void put_health(int force = 0); + static void put_temp(int force = 0); + static void put_info(); + static void put_score(); + static void put_ships(); + static void flush_score(); + static void flush_ships(); + static void game_stop(); + static void run_noise(); + public: + static int ships; + static void init(); + static void set_bars(); + static void init_resources_title(); + static void init_resources_to_play(int newship); + static void noise(int duration, int flash); + static void noise_out(int duration); + static void noise_damage(float amt); + static void update(); + static void run_intro(); + static void run_pause(); + static void run_game(); + static void lost_myship(); + static void destroyed_a_core(); + static void add_score(int sc); + static void key_down(SDLKey sym); + static void key_up(SDLKey sym); + static int title_blank() { return blank; } + static void select_next(int redraw_map = 1); + static void select_prev(int redraw_map = 1); + static void regenerate(); + static void select_scene(int scene, int redraw_map = 1); + static int scene() { return scene_num; } + static void abort(); + static void freeze_abort(); + static int aborted() { return exit_manage; } + static void reenter(); + static int game_stopped() { return !playing; } + static int get_ready(); + static void game_start(); + static int game_over(); +}; + +extern _manage manage; + +#endif //_KOBO_MANAGE_H_ diff --git a/map.cpp b/map.cpp new file mode 100644 index 0000000..4d0b549 --- /dev/null +++ b/map.cpp @@ -0,0 +1,220 @@ +/*(GPL) +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 1995, 1996 Akira Higuchi + * Copyright (C) 2002, 2007 David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "config.h" +#include "map.h" +#include "random.h" + +void _map::init() +{ + int i, j; + for(i = 0; i < MAP_SIZEX; i++) + for(j = 0; j < MAP_SIZEY; j++) + pos(i, j) = SPACE; +} + +void _map::make_maze(int x, int y, int difx, int dify) +{ + int i, j; + int vx, vy; + + /* clear */ + for(i = x - difx; i <= x + difx; i++) + for(j = y - dify; j <= y + dify; j++) + pos(i, j) = SPACE; + + /* push initial sites */ + site_max = 0; + if(gamerand.get(8) < 128) + { + pos(x, y) = CORE | R_MASK | L_MASK; + maze_push(x - 1, y); + maze_push(x + 1, y); + } + else + { + pos(x, y) = CORE | U_MASK | D_MASK; + maze_push(x, y - 1); + maze_push(x, y + 1); + } + + for(;;) + { + /* get one */ + if(maze_pop()) + break; + vx = sitex[site_max]; + vy = sitey[site_max]; + + int dirs[4]; + for(i = 0; i < 4; i++) + dirs[i] = 0; + int dirs_max = 0; + if(maze_judge(x, y, difx, dify, vx + 2, vy + 0)) + dirs[dirs_max++] = 1; + if(maze_judge(x, y, difx, dify, vx + 0, vy + 2)) + dirs[dirs_max++] = 2; + if(maze_judge(x, y, difx, dify, vx - 2, vy + 0)) + dirs[dirs_max++] = 3; + if(maze_judge(x, y, difx, dify, vx + 0, vy - 2)) + dirs[dirs_max++] = 4; + if(dirs_max == 0) + continue; /* there are no places to go */ + i = gamerand.get() % dirs_max; + maze_move_and_push(vx, vy, dirs[i]); + maze_push(vx, vy); + } +} + +int _map::maze_pop() +{ + if(site_max == 0) + return 1; + int i = gamerand.get() % site_max; + site_max--; + if(i != site_max) + { + int tmpx = sitex[site_max]; + int tmpy = sitey[site_max]; + sitex[site_max] = sitex[i]; + sitey[site_max] = sitey[i]; + sitex[i] = tmpx; + sitey[i] = tmpy; + } + return 0; +} + +void _map::maze_push(int x, int y) +{ + sitex[site_max] = x; + sitey[site_max++] = y; + pos(x, y) = WALL; +} + +void _map::maze_move_and_push(int x, int y, int d) +{ + int x1 = x; + int y1 = y; + switch (d) + { + case 1: + { + x1 += 2; + break; + } + case 2: + { + y1 += 2; + break; + } + case 3: + { + x1 -= 2; + break; + } + case 4: + { + y1 -= 2; + break; + } + } + maze_push(x1, y1); + pos((x + x1) / 2, (y + y1) / 2) = WALL; +} + +int _map::maze_judge(int cx, int cy, int dx, int dy, int x, int y) +{ + if((x < cx - dx) || (x > cx + dx) || (y < cy - dy) + || (y > cy + dy)) + return 0; + if(pos(x, y) == WALL) + return 0; + return 1; +} + +// Translate map "tile state bits" into tile index +// +// The hard end nodes need some special treatment here. There are 16 direction +// mask combinations, but only 4 are valid in this case. So, we use a 16 x 2 +// bit lookup "table" (packed into an 'int') to get the right tile index. +// +// 00 01 10 11 <-- mask bits 1 (right) and 0 (up) +// ----------------------------------------------------- +// 00 -- 00 01 -- +// 01 10 -- -- -- <-- Tile indices +// 10 11 -- -- -- +// 11 -- -- -- -- +// ^ +// '- mask bits 3 (left) and 2 (down) +// +// Thus, our table is 00000000 00000011 00000010 00010000 == 0x00030210 +// +static inline int bits2tile(int n) +{ + if(n & CORE) // Core + return n & (U_MASK | D_MASK) ? 6 : 7; + else if(n & HARD) // One of the 4 indestructible end nodes + return (0x00030210 >> ((n & 15) << 1)) & 3; + else if(n == 5) // Vertical pipe + return pubrand.get(2) ? 13 : 4; + else if(n == 10) // Vertical pipe + return pubrand.get(2) ? 18 : 5; + else // Other pipe parts or normal end nodes + return n + 8; +} + +void _map::convert(unsigned ratio) +{ + int i, j; + int p = 0; + for(i = 0; i < MAP_SIZEX; i++) + for(j = 0; j < MAP_SIZEY; j++) + { + p = pos(i, j) & CORE; + if(IS_SPACE(pos(i, j))) + { + clearpos(i, j); + continue; + } + if((j > 0) && !IS_SPACE(pos(i, j - 1))) + p |= U_MASK; + if((i < MAP_SIZEX - 1) && !IS_SPACE(pos(i + 1, j))) + p |= R_MASK; + if((j < MAP_SIZEY - 1) && !IS_SPACE(pos(i, j + 1))) + p |= D_MASK; + if((i > 0) && !IS_SPACE(pos(i - 1, j))) + p |= L_MASK; + if((p == U_MASK) || (p == R_MASK) || (p == D_MASK) + || (p == L_MASK)) + { + if(gamerand.get(8) < ratio) + p |= HARD; + } + pos(i, j) = (bits2tile(p) << 8) | p; + } +} + + +void _map::clearpos(int x, int y) +{ + pos(x, y) = (gamerand.get(6) << 8) | SPACE; +} diff --git a/map.h b/map.h new file mode 100644 index 0000000..19a5374 --- /dev/null +++ b/map.h @@ -0,0 +1,69 @@ +/*(GPL) +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 1995, 1996 Akira Higuchi + * Copyright (C) 2002, 2007 David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef XKOBO_H_MAP +#define XKOBO_H_MAP + +#include "config.h" + +#define SITE_MAX 1024 + +#define WALL 1 + +// Tile state bits +#define U_MASK (1<<0) +#define R_MASK (1<<1) +#define D_MASK (1<<2) +#define L_MASK (1<<3) +#define CORE (1<<4) +#define HIT_MASK (CORE | U_MASK | R_MASK | D_MASK | L_MASK) +#define HARD (1<<5) +#define SPACE (1<<6) +#define MAP_BITS(x) ((x) & 0xff) + +#define IS_SPACE(x) ((x) & SPACE) + +class _map +{ + public: + void init(); + void make_maze(int x, int y, int difx, int dify); + void convert(unsigned ratio); /* ratio < 64 */ + inline unsigned short &pos(int x, int y) + { + x &= MAP_SIZEX - 1; + y &= MAP_SIZEY - 1; + return data[(y << MAP_SIZEX_LOG2) + x]; + } + void clearpos(int x, int y); + protected: + int sitex[SITE_MAX]; + int sitey[SITE_MAX]; + int site_max; + unsigned short data[1 << (MAP_SIZEX_LOG2 + MAP_SIZEY_LOG2)]; + int maze_pop(); + void maze_push(int x, int y); + void maze_move_and_push(int x, int y, int d); + int maze_judge(int cx, int cy, int dx, int dy, int x, int y); +}; + +#endif // XKOBO_H_MAP diff --git a/missing b/missing new file mode 100755 index 0000000..0a7fb5a --- /dev/null +++ b/missing @@ -0,0 +1,283 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. +# Copyright 1996, 1997, 1999, 2000 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# 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, 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. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +case "$1" in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case "$1" in + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch]" + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing 0.3 - GNU automake" + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + + aclocal) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` + fi + if [ -f "$file" ]; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit 1 + fi + ;; + + makeinfo) + if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then + # We have makeinfo, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` + fi + touch $file + ;; + + tar) + shift + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + fi + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar ${1+"$@"} && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar ${1+"$@"} && exit 0 + fi + firstarg="$1" + if shift; then + case "$firstarg" in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" ${1+"$@"} && exit 0 + ;; + esac + case "$firstarg" in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" ${1+"$@"} && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequirements for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 diff --git a/mkinstalldirs b/mkinstalldirs new file mode 100755 index 0000000..4f58503 --- /dev/null +++ b/mkinstalldirs @@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +# $Id: mkinstalldirs,v 1.13 1999/01/05 03:18:55 bje Exp $ + +errstatus=0 + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here diff --git a/myship.cpp b/myship.cpp new file mode 100644 index 0000000..954e9ae --- /dev/null +++ b/myship.cpp @@ -0,0 +1,665 @@ +/* +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 1995, 1996, Akira Higuchi + * Copyright (C) 2001-2003, 2007 David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "kobo.h" +#include "screen.h" +#include "myship.h" +#include "enemies.h" +#include "gamectl.h" +#include "manage.h" +#include "random.h" +#include "sound.h" + +#define WING_GUN_OFFSET 4 + +_myship_state _myship::_state; +int _myship::di; +int _myship::virtx; +int _myship::virty; +int _myship::x; +int _myship::y; +int _myship::_health; +int _myship::health_time; +int _myship::explo_time; +int _myship::nose_reload_timer; +int _myship::nose_temperature; +int _myship::nose_alt = 0; +int _myship::tail_reload_timer; +int _myship::tail_temperature; +int _myship::tail_alt = WING_GUN_OFFSET; +int _myship::lapx; +int _myship::lapy; +int _myship::boltx[MAX_BOLTS]; +int _myship::bolty[MAX_BOLTS]; +int _myship::boltdx[MAX_BOLTS]; +int _myship::boltdy[MAX_BOLTS]; +int _myship::boltst[MAX_BOLTS]; +cs_obj_t *_myship::object; +cs_obj_t *_myship::bolt_objects[MAX_BOLTS]; +cs_obj_t *_myship::crosshair; + + +_myship::_myship() +{ + object = NULL; + memset(bolt_objects, 0, sizeof(bolt_objects)); + crosshair = NULL; +} + + +void _myship::state(_myship_state s) +{ + switch (s) + { + case dead: + if(object) + gengine->free_obj(object); + object = NULL; + if(crosshair) + gengine->free_obj(crosshair); + crosshair = NULL; + break; + case normal: + if(!object) + object = gengine->get_obj(LAYER_PLAYER); + if(object) + cs_obj_show(object); + break; + } + _state = s; +} + + +void _myship::off() +{ + state(dead); + int i; + for(i = 0; i < MAX_BOLTS; i++) + if(bolt_objects[i]) + { + gengine->free_obj(bolt_objects[i]); + bolt_objects[i] = NULL; + } +} + + +int _myship::init() +{ + nose_reload_timer = 0; + nose_temperature = 0; + tail_reload_timer = 0; + tail_temperature = 0; + x = WORLD_SIZEX >> 1; + y = (WORLD_SIZEY >> 2) * 3; + virtx = x - (WSIZE >> 1); + virty = y - (WSIZE >> 1); + lapx = 0; + lapy = 0; + di = 1; + state(normal); + + apply_position(); + + int i; + for(i = 0; i < MAX_BOLTS; i++) + { + boltx[i] = 0; + bolty[i] = 0; + boltdx[i] = 0; + boltdy[i] = 0; + boltst[i] = 0; + if(bolt_objects[i]) + gengine->free_obj(bolt_objects[i]); + bolt_objects[i] = NULL; + } + return 0; +} + + +void _myship::explode(int x, int y) +{ + if(explo_time == 56) + manage.noise_out(1000); + else if(explo_time > 64) + return; + + int d = 4096 - (64 - explo_time)*(64 - explo_time); + int i; + for(i = 0; i < 2; ++i) + { + int dx = (int)(pubrand.get(6)) - 32; + int dy = (int)(pubrand.get(6)) - 32; + int vx = dx * (4096 - d) >> 8; + int vy = dy * (4096 - d) >> 8; + dx = dx * d >> 12; + dy = dy * d >> 12; + enemies.make(enemies.randexp(), x + dx, y + dy, vx, vy, + explo_time >> 4); + } + ++explo_time; +} + + +#define BEAMV1 12 +#define BEAMV2 (BEAMV1*2/3) + +int _myship::move() +{ + int i; + di = gamecontrol.dir(); + + if(++health_time >= game.health_fade) + { + health_time = 0; + if(_health > game.health) + --_health; + } + + virtx = x - (WSIZE >> 1); + virty = y - (WSIZE >> 1); + if(_state == normal) + { + int vd, vo; + if(!prefs->cmd_pushmove) + { + vd = 2; + vo = 3; + } + else if(gamecontrol.dir_push()) + { + vd = 1; + vo = 1; + } + else + { + vd = 0; + vo = 0; + } + switch (di) + { + case 1: + virty -= vo; + break; + case 2: + virty -= vd; + virtx += vd; + break; + case 3: + virtx += vo; + break; + case 4: + virtx += vd; + virty += vd; + break; + case 5: + virty += vo; + break; + case 6: + virty += vd; + virtx -= vd; + break; + case 7: + virtx -= vo; + break; + case 8: + virtx -= vd; + virty -= vd; + break; + } + explo_time = 0; + } + else if(_state == dead) + explode(x, y); + + lapx = 0; + lapy = 0; + if(virtx < 0) + { + virtx += WORLD_SIZEX; + lapx = WORLD_SIZEX; + } + if(virtx >= WORLD_SIZEX) + { + virtx -= WORLD_SIZEX; + lapx = -WORLD_SIZEX; + } + if(virty < 0) + { + virty += WORLD_SIZEY; + lapy = WORLD_SIZEY; + } + if(virty >= WORLD_SIZEY) + { + virty -= WORLD_SIZEY; + lapy = -WORLD_SIZEY; + } + x = virtx + (WSIZE >> 1); + y = virty + (WSIZE >> 1); + + nose_temperature -= game.nosecooling; + if(nose_temperature < 0) + nose_temperature = 0; + tail_temperature -= game.tailcooling; + if(tail_temperature < 0) + tail_temperature = 0; + + if((_state == normal) && gamecontrol.get_shot()) + { + if(game.skill == SKILL_CLASSIC) + { + if(nose_reload_timer > 0) + --nose_reload_timer; + else + { + _myship::xkobo_shot(); + nose_reload_timer = game.noseloadtime - 1; + } + } + else + { + int fired = 0; + if(tail_reload_timer > 0) + --tail_reload_timer; + else if(!_myship::tail_fire()) + fired = 1; // Ok! + else + fired = 2; // Overheat! + if(nose_reload_timer > 0) + --nose_reload_timer; + else if(!_myship::nose_fire()) + fired = 1; // Ok! + else + fired = 2; // Overheat! + if(fired == 1) + sound.g_player_fire(); + else if(fired == 2) + sound.g_player_overheat(); + } + } + else + { + if(!gamecontrol.get_shot()) + { + nose_alt = 1; + sound.g_player_fire_off(); + } + if(nose_reload_timer > 0) + --nose_reload_timer; + if(tail_reload_timer > 0) + --tail_reload_timer; + } + + const char animtab[8] = { 3, 2, 1, 0, 1, 2, 1, 2 }; + for(i = 0; i < MAX_BOLTS; i++) + { + if(!boltst[i]) + continue; + ++boltst[i]; + boltx[i] += lapx; + bolty[i] += lapy; + boltx[i] += boltdx[i]; + bolty[i] += boltdy[i]; + if((ABS(boltx[i] - x) >= (VIEWLIMIT >> 1) + 16) || + (ABS(bolty[i] - y) >= (VIEWLIMIT >> 1) + 16)) + { + boltst[i] = 0; + if(bolt_objects[i]) + gengine->free_obj(bolt_objects[i]); + bolt_objects[i] = NULL; + } + else if(bolt_objects[i]) + cs_obj_image(bolt_objects[i], B_BOLT, + (bolt_objects[i]->anim.frame & 0xfffffffc) + + animtab[boltst[i] & 7]); + } + return 0; +} + + +void _myship::hit(int dmg) +{ + if(_state != normal) + return; + + if(!dmg) + dmg = 1000; + + if(_health && (dmg < _health)) + manage.noise_damage((float)dmg / _health); + else + manage.noise_damage(1.0f); + + _health -= dmg; + if(_health > 0) + sound.g_player_damage(); + else + { + _health = 0; + manage.lost_myship(); + state(dead); + sound.g_player_explo_start(); + } +} + + +void _myship::health_bonus(int h) +{ + if(game.skill == SKILL_CLASSIC) + return; + _health += game.health * h / 100; + health_time = 0; + if(_health > game.health * 2) + _health = game.health * 2; +} + + +int _myship::hit_structure() +{ + int x1, y1; + int i, ch; + + // Check bolts/objects + for(i = 0; i < MAX_BOLTS; i++) + { + if(!boltst[i]) + continue; + x1 = (boltx[i] & (WORLD_SIZEX - 1)) >> 4; + y1 = (bolty[i] & (WORLD_SIZEY - 1)) >> 4; + ch = screen.get_map(x1, y1); + if(!IS_SPACE(ch) && (ch & HIT_MASK)) + { + sound.g_bolt_hit(x1<<12, y1<<12); + enemies.make(&boltexpl, boltx[i], bolty[i]); + boltst[i] = 0; + if(bolt_objects[i]) + gengine->free_obj(bolt_objects[i]); + bolt_objects[i] = NULL; + } + } + + // Check player/bases + x1 = (x & (WORLD_SIZEX - 1)) >> 4; + y1 = (y & (WORLD_SIZEY - 1)) >> 4; + ch = screen.get_map(x1, y1); + if(!IS_SPACE(ch) && (ch & HIT_MASK)) + { + if(prefs->cmd_indicator) + sound.g_player_damage(); + else + _myship::hit(1000); + } + return 0; +} + + +int _myship::hit_bolt(int ex, int ey, int hitsize, int health) +{ + int dmg = 0; + int i; + for(i = 0; i < MAX_BOLTS; i++) + { + if(boltst[i] == 0) + continue; + if(ABS(ex - boltx[i]) >= hitsize) + continue; + if(ABS(ey - bolty[i]) >= hitsize) + continue; + if(!prefs->cmd_cheat) + { + boltst[i] = 0; + if(bolt_objects[i]) + gengine->free_obj(bolt_objects[i]); + bolt_objects[i] = NULL; + } + enemies.make(&boltexpl, boltx[i], bolty[i]); + dmg += game.bolt_damage; + if(dmg >= health) + break; + } + return dmg; +} + + +void _myship::put_crosshair() +{ + if(_state != normal) + return; + if(!crosshair) + { + crosshair = gengine->get_obj(LAYER_OVERLAY); + if(crosshair) + cs_obj_show(crosshair); + } + if(crosshair) + { + cs_obj_image(crosshair, B_CROSSHAIR, 0); + crosshair->point.v.x = PIXEL2CS(mouse_x - 8 - MARGIN); + crosshair->point.v.y = PIXEL2CS(mouse_y - MARGIN); + } +} + + +int _myship::put() +{ + /* Player */ + apply_position(); + if(object) + cs_obj_image(object, B_PLAYER, (di - 1) * 2); + + /* Bullets */ + int i; + for(i = 0; i < MAX_BOLTS; i++) + { + if(!bolt_objects[i]) + continue; + if(boltst[i]) + { + bolt_objects[i]->point.v.x = PIXEL2CS(boltx[i]); + bolt_objects[i]->point.v.y = PIXEL2CS(bolty[i]); + } + } + return 0; +} + + +void _myship::shot_single(int i, int dir, int offset) +{ + int doffset = (offset * 7071 + (offset > 0 ? 5000 : -5000)) / 10000; + boltst[i] = 1; + boltx[i] = x; + bolty[i] = y; + switch((dir + 1) % 8 + 1) + { + case 1: + bolty[i] -= offset; + break; + case 2: + bolty[i] -= doffset; + boltx[i] += doffset; + break; + case 3: + boltx[i] += offset; + break; + case 4: + boltx[i] += doffset; + bolty[i] += doffset; + break; + case 5: + bolty[i] += offset; + break; + case 6: + bolty[i] += doffset; + boltx[i] -= doffset; + break; + case 7: + boltx[i] -= offset; + break; + case 8: + boltx[i] -= doffset; + bolty[i] -= doffset; + break; + } + switch(dir) + { + case 1: + boltdx[i] = 0; + boltdy[i] = -BEAMV1; + break; + case 2: + boltdy[i] = -BEAMV2; + boltdx[i] = BEAMV2; + break; + case 3: + boltdx[i] = BEAMV1; + boltdy[i] = 0; + break; + case 4: + boltdx[i] = BEAMV2; + boltdy[i] = BEAMV2; + break; + case 5: + boltdx[i] = 0; + boltdy[i] = BEAMV1; + break; + case 6: + boltdy[i] = BEAMV2; + boltdx[i] = -BEAMV2; + break; + case 7: + boltdx[i] = -BEAMV1; + boltdy[i] = 0; + break; + case 8: + boltdx[i] = -BEAMV2; + boltdy[i] = -BEAMV2; + break; + } + if(!bolt_objects[i]) + bolt_objects[i] = gengine->get_obj(LAYER_PLAYER); + if(bolt_objects[i]) + { + bolt_objects[i]->point.v.x = PIXEL2CS(boltx[i]); + bolt_objects[i]->point.v.y = PIXEL2CS(bolty[i]); + cs_obj_image(bolt_objects[i], B_BOLT, (((dir - 1) & 0x3) << 2) + 3); + cs_obj_show(bolt_objects[i]); + } +} + + +int _myship::xkobo_shot() +{ + int i, j; + for(i = 0; i < game.bolts && boltst[i]; i++) + ; + for(j = i + 1; j < game.bolts && boltst[j]; j++) + ; + if(j >= game.bolts) + { + sound.g_player_overheat(1); + return 1; + } + shot_single(i, di, 0); + shot_single(j, (di > 4) ? (di - 4) : (di + 4), 0); + sound.g_player_fire(); + return 0; +} + + +int _myship::nose_fire() +{ + int i, j; + // Logic: If firing would cause overheat, wait! + if(255 - nose_temperature < game.noseheatup) + return 1; + for(i = 0; i < game.bolts && boltst[i]; i++) + ; + if(!game.altfire) + { + if(i >= game.bolts) + return 1; + shot_single(i, di, 0); + nose_temperature += game.noseheatup; + nose_reload_timer = game.noseloadtime; + return 0; + } + for(j = i + 1; j < game.bolts && boltst[j]; j++) + ; + if(j >= game.bolts) + return 1; + if(++nose_alt > 2) + nose_alt = 0; + shot_single(i, di, (nose_alt - 1) * WING_GUN_OFFSET); + if(++nose_alt > 2) + nose_alt = 0; + shot_single(j, di, (nose_alt - 1) * WING_GUN_OFFSET); + nose_temperature += game.noseheatup; + nose_reload_timer = game.noseloadtime; + return 0; +} + + +int _myship::tail_fire() +{ + int i; + if(255 - tail_temperature < game.tailheatup) + return 1; + for(i = 0; i < game.bolts && boltst[i]; i++) + ; + if(i >= game.bolts) + return 1; + if(game.altfire) + { + tail_alt = -tail_alt; + shot_single(i, (di > 4) ? (di - 4) : (di + 4), tail_alt); + } + else + shot_single(i, (di > 4) ? (di - 4) : (di + 4), 0); + tail_temperature += game.tailheatup; + tail_reload_timer = game.tailloadtime; + return 0; +} + + +void _myship::set_position(int px, int py) +{ + x = px; + y = py; + virtx = x - (WSIZE >> 1); + virty = y - (WSIZE >> 1); + + if(object) + { + apply_position(); + cs_point_force(&object->point); + } +} + + +void _myship::apply_position() +{ + if(object) + { + object->point.v.x = PIXEL2CS(x); + object->point.v.y = PIXEL2CS(y); + } + sound.g_position(x, y); +} diff --git a/myship.h b/myship.h new file mode 100644 index 0000000..18e953e --- /dev/null +++ b/myship.h @@ -0,0 +1,113 @@ +/* +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 1995, 1996, Akira Higuchi + * Copyright (C) 2001, 2003, 2007 David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef XKOBO_H_MYSHIP +#define XKOBO_H_MYSHIP + +#include "config.h" +#include "gfxengine.h" +#include "game.h" + +#define ABS(x) (((x)>=0) ? (x) : (-(x))) +#define MAX(x,y) (((x)>(y)) ? (x) : (y)) + +//---------------------------------------------------------------------------// +enum _myship_state +{ + normal, + dead +}; + +class _myship +{ + static _myship_state _state; + static int di; /* direction */ + static int virtx, virty; /* scroll position */ + static int x, y; + static int _health; + static int health_time; + static int explo_time; + static int nose_reload_timer; + static int nose_temperature; + static int nose_alt; + static int tail_reload_timer; + static int tail_temperature; + static int tail_alt; + static int lapx, lapy; + static int boltx[MAX_BOLTS], bolty[MAX_BOLTS]; + static int boltdx[MAX_BOLTS], boltdy[MAX_BOLTS]; + static int boltst[MAX_BOLTS]; + /* For the gfxengine connection */ + static cs_obj_t *object; + static cs_obj_t *bolt_objects[MAX_BOLTS]; + static cs_obj_t *crosshair; + static void state(_myship_state s); + static void shot_single(int i, int dir, int offset); + static void apply_position(); + static void explode(int x, int y); + public: + _myship(); + static inline int get_x() + { + return x; + } + static inline int get_y() + { + return y; + } + static inline int get_virtx() + { + return virtx; + } + static inline int get_virty() + { + return virty; + } + static inline int get_nose_temp() + { + return nose_temperature; + } + static inline int get_tail_temp() + { + return tail_temperature; + } + static int init(); + static void off(); + static int move(); + static int put(); + static void put_crosshair(); + static int xkobo_shot(); + static int nose_fire(); + static int tail_fire(); + static int hit_structure(); + static int hit_bolt(int ex, int ey, int hitsize, int health); + static void hit(int dmg); + static int health() { return _health; } + static void health(int h) { _health = h; } + static void health_bonus(int h); + static void set_position(int px, int py); + static int alive() { return _state == normal; } +}; + +extern _myship myship; + +#endif // XKOBO_H_MYSHIP diff --git a/options.cpp b/options.cpp new file mode 100644 index 0000000..2161c6c --- /dev/null +++ b/options.cpp @@ -0,0 +1,506 @@ +/*(GPL) +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 2001-2003, 2006-2007 David Olofson + * Copyright (C) 2005 Erik Auerswald + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include "config.h" +#include "options.h" +#include "gfxengine.h" +#include "gamectl.h" +#include "a_types.h" +#include "kobo.h" + + +void system_options_t::build() +{ + medium(); + label("System Options"); + + space(); + small(); + xoffs = 0.6; + list("Maximum Frame Rate", &prf->max_fps, OS_REBUILD); + { + char buf[10]; + item("OFF", 0); + for(int i = 1; i < 25; i += 1) + { + snprintf((char *)&buf, sizeof(buf), + "%d Hz", i); + item(buf, i); + } + for(int i = 25; i < 100; i += 5) + { + snprintf((char *)&buf, sizeof(buf), + "%d Hz", i); + item(buf, i); + } + for(int i = 100; i <= 200; i += 10) + { + snprintf((char *)&buf, sizeof(buf), + "%d Hz", i); + item(buf, i); + } + } + if(prf->max_fps) + yesno("Strictly Regulated", &prf->max_fps_strict, 0); + + space(); + xoffs = 0.6; + list("Time Filter", &prf->timefilter, OS_UPDATE_ENGINE); + item("Off", 100); + item("Fast", 75); + item("Normal", 50); + item("Slow", 10); + item("Logic/Video Lock", 0); + onoff("Motion Interpolation", &prf->filter, OS_UPDATE_ENGINE); + + space(); + xoffs = 0.6; + yesno("Log Messages to File", &prf->logfile, OS_RESTART_LOGGER); + list("Log Output Format", &prf->logformat, 0); + item("Plain Text", 0); + item("ANSI Coloring", 1); + item("HTML", 2); + xoffs = 0.45; + list("Log Verbosity", &prf->logverbosity, 0); + item("Critical Errors Only", 0); + item("Errors Only", 1); + item("Errors & Warnings", 2); + item("Some Debug", 3); + item("More Debug", 4); + item("Everything", 5); + + big(); + space(); + xoffs = 0.5; + button("ACCEPT", OS_CLOSE); + button("CANCEL", OS_CANCEL); +} + + +void video_options_t::build() +{ + medium(); + label("Video Options"); + space(); + small(); + + if(firstbuild) + { + vmm_Init(VMM_ALL, 0); + VMM_Mode *vm = vmm_FindMode(prf->videomode); + if(vm) + { + if(vm->flags & VMM_PC) + showmodes = VMM_PC; + else if(vm->flags & VMM_TV) + showmodes = VMM_TV; + else if(vm->flags & VMM_4_3) + showmodes = VMM_4_3; + else if(vm->flags & VMM_3_2) + showmodes = VMM_3_2; + else if(vm->flags & VMM_5_4) + showmodes = VMM_5_4; + else if(vm->flags & VMM_16_10) + showmodes = VMM_16_10; + else if(vm->flags & VMM_16_9) + showmodes = VMM_16_9; + else + showmodes = VMM_ALL; + if(vm->flags & VMM_LORES) + showlow = 1; + } + else + { + showmodes = VMM_PC; + showlow = 0; + prf->videomode = -1; + } + firstbuild = 0; + } + + xoffs = 0.35; + list("Show Modes" , &showmodes, OS_REBUILD); + item("Show All", VMM_ALL); + item("Common PC/Mac Modes", VMM_PC); + item("Common TV Modes", VMM_TV); + item("4:3 (Standard CRT)", VMM_4_3); + item("3:2 (NTSC TV)", VMM_3_2); + item("5:4 (Some TFTs)", VMM_5_4); + item("16:10 (PC/Mac Widescreen)", VMM_16_10); + item("16:9 (TV Widescreen)", VMM_16_9); + xoffs = 0.7; + yesno("Show Odd Low Resolutions" , &showlow, OS_REBUILD); + xoffs = 0.5; + list("Display Mode", &prf->videomode, OS_RESTART_VIDEO | OS_REBUILD); + vmm_Init(showmodes, showlow ? 0 : VMM_LORES); + VMM_Mode *vm = vmm_First(); + char buf[256]; + buf[sizeof(buf) - 1] = 0; + while(vm) + { + if(vm->name) + snprintf(buf, sizeof(buf) - 1, "%dx%d (%s)", + vm->width, vm->height, vm->name); + else + snprintf(buf, sizeof(buf) - 1, "%dx%d", + vm->width, vm->height); + item(buf, vm->id); + vm = vmm_Next(vm); + } + item("Custom", -1); + if(prf->videomode < 0) + { + spin("Width", &prf->width, 32, 4096, "pixels", + OS_RESTART_VIDEO | OS_REBUILD); + spin("Height", &prf->height, 32, 4096, "pixels", + OS_RESTART_VIDEO | OS_REBUILD); + } + space(); + yesno("Fullscreen Display", &prf->fullscreen, OS_RESTART_VIDEO); + list("Display Depth", &prf->depth, OS_RESTART_VIDEO); + item("Default", 0); + item("8 bits", 8); + item("15 bits", 15); + item("16 bits", 16); + item("24 bits", 24); + item("32 bits", 32); +#if defined(HAVE_OPENGL) && !defined(GLSDL_OFF) + list("Display Driver", &prf->videodriver, OS_RESTART_VIDEO | + OS_REBUILD); + item("SDL 2D", GFX_DRIVER_SDL2D); + item("OpenGL/glSDL", GFX_DRIVER_GLSDL); +#else + prf->videodriver = GFX_DRIVER_SDL2D; +#endif + space(); + xoffs = 0.55; + switch(prf->videodriver) + { + case GFX_DRIVER_SDL2D: + list("Display Buffering Mode", &prf->doublebuf, OS_RESTART_VIDEO); + item("Single", 0); + item("Double", 1); + yesno("Software Shadow Buffer", &prf->shadow, OS_RESTART_VIDEO); + break; + case GFX_DRIVER_GLSDL: + yesno("Vertical Retrace Sync", &prf->vsync, OS_RESTART_VIDEO); + break; + } + list("Display Buffer Pages", &prf->pages, OS_UPDATE_ENGINE); + item("Assume Standard", -1); + item("Always Repaint", 0); + item("Single", 1); + item("Double", 2); + item("Triple", 3); + big(); + space(); + xoffs = 0.5; + button("ACCEPT", OS_CLOSE); + button("CANCEL", OS_CANCEL); +} + + +void graphics_options_t::build() +{ + medium(); + label("Graphics Options"); + space(); + small(); + xoffs = 0.6; + list("Scale Mode", &prf->scalemode, OS_RELOAD_GRAPHICS); + item("Nearest", GFX_SCALE_NEAREST); + item("Bilinear", GFX_SCALE_BILINEAR); +// FIXME: Bilinear+Oversampling is unreliable and doesn't help much anyway +// item("Bilinear+Oversampling", GFX_SCALE_BILIN_OVER); + +// FIXME: We need to specify a fallback chain for when filters do not support +// FIXME: ratios. So, we have quality and image specific requirements, and we +// FIXME: want a list of filters/modes in order of preference. + +// if((gengine->xscale() == 2.0f) && (gengine->yscale() == 2.0f)) +// { + item("Scale2x", GFX_SCALE_SCALE2X); + item("Diamond2x", GFX_SCALE_DIAMOND); +// } +// else if(prf->scalemode >= GFX_SCALE_SCALE2X) +// prf->scalemode = GFX_SCALE_BILINEAR; + space(1); + yesno("Dithering", &prf->use_dither, OS_RELOAD_GRAPHICS); + list("Dither Type", &prf->dither_type, OS_RELOAD_GRAPHICS); + item("2x2 Filter", 0); + item("4x4 Filter", 1); + item("Random", 2); + switch(prf->videodriver) + { + case GFX_DRIVER_GLSDL: + yesno("Broken RGBA8 (OpenGL)", &prf->broken_rgba8, + OS_RELOAD_GRAPHICS); + break; + } + space(); + yesno("Alpha Blending", &prf->alpha, OS_RELOAD_GRAPHICS); + space(); + list("Brightness", &prf->brightness, OS_RELOAD_GRAPHICS); + perc_list(50, 150, 10); + list("Contrast", &prf->contrast, OS_RELOAD_GRAPHICS); + perc_list(50, 150, 10); + big(); + space(); + xoffs = 0.5; + button("ACCEPT", OS_CLOSE); + button("CANCEL", OS_CANCEL); +} + + +void audio_options_t::build() +{ + medium(); + label("Sound Options"); + small(); + space(); + xoffs = 0.57; + yesno("Enable Sound", &prf->use_sound, OS_RESTART_AUDIO | OS_REBUILD); + if(prf->use_sound) + { + yesno("Enable Music", &prf->use_music, OS_RESTART_AUDIO | OS_REBUILD); + yesno("Cached Sounds", &prf->cached_sounds, OS_RELOAD_AUDIO_CACHE); + + //System + space(); + list("Sample Rate", &prf->samplerate, OS_RESTART_AUDIO); + item("8 kHz", 8000); + item("11025 Hz", 11025); + item("16 kHz", 16000); + item("22050", 22050); + item("32 kHz", 32000); + item("44.1 kHz", 44100); + item("48 kHz", 48000); + item("88.2 kHz", 88200); + item("96 kHz", 96000); + item("176.4 kHz", 176400); + item("192 kHz", 192000); + list("Mixing Quality", &prf->mixquality, OS_UPDATE_AUDIO); + item("Very Low", AQ_VERY_LOW); + item("Low", AQ_LOW); + item("Normal", AQ_NORMAL); + item("High", AQ_HIGH); + item("Very High", AQ_VERY_HIGH); + list("Sound Latency", &prf->latency, OS_RESTART_AUDIO); + { + char buf[10]; + for(int i = 1; i < 20; i += 1) + { + snprintf((char *)&buf, sizeof(buf), + "%d ms", i); + item(buf, i); + } + for(int i = 20; i < 50; i += 5) + { + snprintf((char *)&buf, sizeof(buf), + "%d ms", i); + item(buf, i); + } + for(int i = 50; i < 100; i += 10) + { + snprintf((char *)&buf, sizeof(buf), + "%d ms", i); + item(buf, i); + } + for(int i = 100; i <= 500; i += 25) + { + snprintf((char *)&buf, sizeof(buf), + "%d ms", i); + item(buf, i); + } + } +#ifdef HAVE_OSS + yesno("Use OSS Sound Driver", &prf->use_oss, OS_RESTART_AUDIO); +#else + // We're running out of space here... :-/ + space(); +#endif + //Mixer + list("Sound Effects Level", &prf->sfx_vol, OS_UPDATE_AUDIO); + item("OFF", 0); + perc_list(10, 90, 10); + perc_list(100, 200, 25); + if(prf->use_music) + { + list("Intro Music Level", &prf->intro_vol, OS_UPDATE_AUDIO); + item("OFF", 0); + perc_list(10, 90, 10); + perc_list(100, 200, 25); + list("In-Game Music Level", &prf->music_vol, OS_UPDATE_AUDIO); + item("OFF", 0); + perc_list(10, 90, 10); + perc_list(100, 200, 25); + } + + //Master effects + list("Ambience", &prf->reverb, OS_UPDATE_AUDIO); + item("OFF", 0); + item("Low", 50); + item("Normal", 100); + item("High", 175); + item("Extreme", 250); + list("Volume Boost", &prf->vol_boost, OS_UPDATE_AUDIO); + item("OFF", 0); + item("Low", 1); + item("Moderate", 2); + item("High", 3); + item("Extreme", 4); + } + space(); + big(); + xoffs = 0.5; + button("ACCEPT", OS_CLOSE); + button("CANCEL", OS_CANCEL | OS_UPDATE_AUDIO); +} + +void audio_options_t::undo_hook() +{ + clearstatus(OS_RELOAD | OS_RESTART | OS_UPDATE); + setstatus(OS_UPDATE_AUDIO); +} + + +void control_options_t::build() +{ + medium(); + label("Control Options"); + space(); + small(); + xoffs = 0.67; + yesno("Always Fire", &prf->always_fire, OS_RESTART_INPUT); + space(); + yesno("Broken NumPad Diagonals", &prf->broken_numdia, 0); + list("Diagonals Emphasis Filter", &prf->dia_emphasis, 0); + item("OFF", 0); + item("1 frame", 1); + item("2 frames", 2); + item("3 frames", 3); + item("4 frames", 4); + item("5 frames", 5); + space(); + + if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0) + label("Could not initialize joysticks!"); + else + { + prf->number_of_joysticks = SDL_NumJoysticks(); + yesno("Use Joystick", &prf->use_joystick, + OS_RESTART_INPUT | OS_REBUILD); + if(prf->use_joystick) + { + if(prf->number_of_joysticks) + { + list("Joystick Number", &prf->joystick_no, + OS_RESTART_INPUT); + enum_list(0, prf->number_of_joysticks - 1); + } + else + label("No Joysticks Found!"); + } + } + space(); + + yesno("Use Mouse", &prf->use_mouse, OS_RESTART_INPUT | OS_REBUILD); + if(prf->use_mouse) + { + list("Mouse Control Mode", &prf->mousemode, OS_RESTART_INPUT); + item("Disabled", MMD_OFF); + item("Crosshair", MMD_CROSSHAIR); + } + space(); + yesno("In-game Mouse Capture", &prf->mousecapture, 0); + big(); + space(); + xoffs = 0.5; + button("ACCEPT", OS_CLOSE); + button("CANCEL", OS_CANCEL); +} + + +void game_options_t::build() +{ + medium(); + label("Game Options"); + space(); + small(); + xoffs = 0.6; + list("Radar Scroll Mode", &prf->scrollradar, 0); + item("Off", 0); +// FIXME: Radar sweep mode is broken! +// item("Sweep", 1); + item("Scroll", 2); + space(); + list("Get Ready Countdown", &prf->countdown, 0); + item("Quick Start", 0); + item("1 second", 1); + item("2 seconds", 2); + item("3 seconds", 3); + item("4 seconds", 4); + item("5 seconds", 5); + item("6 seconds", 6); + item("7 seconds", 7); + item("8 seconds", 8); + item("9 seconds", 9); + item("Wait Forever", 10); + space(); + list("Starfield Mode", &prf->starfield, OS_REBUILD); + item("None", STARFIELD_NONE); + item("Old (Flat)", STARFIELD_OLD); + item("Parallax", STARFIELD_PARALLAX); + if(prf->starfield == STARFIELD_PARALLAX) + { + list("Starfield Density", &prf->stars, 0); + item("Minimal", 50); + item("Low", 250); + item("Normal", 500); + item("High", 1000); + item("Massive", 2500); + item("Insane", 8000); + } + space(); + xoffs = 0.7; + list("Cannon Overheat Warning", &prf->overheatloud, 0); + item("Off", 0); + item("Soft", 50); + item("Normal", 100); + item("Loud", 200); + list("Cannon Sound Suppression", &prf->cannonloud, 0); + item("Off", 200); + item("Low", 100); + item("High", 50); + big(); + space(); + xoffs = 0.5; + button("ACCEPT", OS_CLOSE); + button("CANCEL", OS_CANCEL | OS_UPDATE_ENGINE); +} + +void game_options_t::undo_hook() +{ + clearstatus(OS_RELOAD | OS_RESTART | OS_UPDATE); + setstatus(OS_UPDATE_ENGINE); +} diff --git a/options.h b/options.h new file mode 100644 index 0000000..523d11b --- /dev/null +++ b/options.h @@ -0,0 +1,75 @@ +/*(GPL) +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 2001, 2003, 2007 David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _KOBO_OPTIONS_H_ +#define _KOBO_OPTIONS_H_ + +#include "cfgform.h" +#include "vidmodes.h" + +class system_options_t : public config_form_t +{ + public: + void build(); +}; + +class video_options_t : public config_form_t +{ + int showmodes; + int showlow; + int firstbuild; + public: + video_options_t() + { + showmodes = VMM_PC; + showlow = 0; + firstbuild = 1; + } + void build(); +}; + +class graphics_options_t : public config_form_t +{ + public: + void build(); +}; + +class audio_options_t : public config_form_t +{ + public: + void build(); + void undo_hook(); +}; + +class control_options_t : public config_form_t +{ + public: + void build(); +}; + +class game_options_t : public config_form_t +{ + public: + void build(); + void undo_hook(); +}; + +#endif //_KOBO_OPTIONS_H_ diff --git a/pfile.cpp b/pfile.cpp new file mode 100644 index 0000000..fb0addb --- /dev/null +++ b/pfile.cpp @@ -0,0 +1,282 @@ +/*(LGPL) +--------------------------------------------------------------------------- + pfile.cpp - Portable File Access Toolkit +--------------------------------------------------------------------------- + * Copyright (C) 2002, 2003, David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define DBG(x) + +#include +#include +#include + +#include "kobolog.h" +#include "pfile.h" + + +/*---------------------------------------------------------- + Constructor/Destructor +----------------------------------------------------------*/ + +pfile_t::pfile_t(FILE *file) +{ + f = file; + _status = 0; + bufsize = bufused = bufpos = 0; + buffer = NULL; +} + + +pfile_t::~pfile_t() +{ + buffer_close(); +} + + +/*---------------------------------------------------------- + Internal buffer control +----------------------------------------------------------*/ + +int pfile_t::buffer_init() +{ + buffer_close(); + + bufsize = 1024; + buffer = (char *)malloc(bufsize); + if(!buffer) + return status(-1); + + bufused = bufpos = 0; + return _status; +} + + +int pfile_t::buffer_write() +{ + DBG(log_printf(D3LOG, "pfile_t::buffer_write() %d bytes\n", bufused);) + if(fwrite(buffer, bufused, 1, f) != 1) + return status(-1); + + bufused = bufpos = 0; + return _status; +} + + +int pfile_t::buffer_read(int len) +{ + buffer_close(); + + bufsize = len; + buffer = (char *)malloc(bufsize); + if(!buffer) + return status(-1); + + if(fread(buffer, bufsize, 1, f) != 1) + { + buffer_close(); + return status(-1); + } + + bufused = bufsize; + bufpos = 0; + return status(len); +} + + +void pfile_t::buffer_close() +{ + free(buffer); + buffer = NULL; + bufsize = bufused = bufpos = 0; +} + + +int pfile_t::read(void *data, int len) +{ + if(_status < 0) + return _status; + + if(buffer) + { + if(bufpos + len > bufused) + return -1; + memcpy(data, buffer + bufpos, len); + bufpos += len; + return len; + } + else + { + if(fread(data, len, 1, f) != 1) + return status(-1); + return len; + } +} + + +int pfile_t::write(void *data, int len) +{ + if(_status < 0) + return _status; + DBG(log_printf(D3LOG, "pfile_t::write(block of %d bytes)\n", len);) + + if(bufused + len > bufsize) + { + int nbs = (bufused + len) * 3 / 2; + char *nb = (char *)realloc(buffer, nbs); + if(!nb) + return -1; + buffer = nb; + bufsize = nbs; + } + memcpy(buffer + bufused, data, len); + bufused += len; + return len; +} + + + +/*---------------------------------------------------------- + Status +----------------------------------------------------------*/ + +int pfile_t::status() +{ + int os = _status; + _status = 0; + return os; +} + + +int pfile_t::status(int new_status) +{ + if(_status >= 0) + _status = new_status; + return _status; +} + + +/*---------------------------------------------------------- + Little endian read/write API +----------------------------------------------------------*/ + +int pfile_t::read(unsigned int &x) +{ + unsigned char b[4]; + int result = read(&b, 4); + if(4 == result) + x = b[0] | (b[1] << 8) | (b[2] << 16) | (b[3] << 24); + return result; +} + + +int pfile_t::read(int &x) +{ + unsigned int ux; + int result = read(ux); + if(4 == result) + x = (int)ux; + return result; +} + + +int pfile_t::write(unsigned int x) +{ + DBG(log_printf(D3LOG, "pfile_t::write(int)\n");) + unsigned char b[4]; + b[0] = x & 0xff; + b[1] = (x >> 8) & 0xff; + b[2] = (x >> 16) & 0xff; + b[3] = (x >> 24) & 0xff; + return status(write(&b, 4)); +} + + +int pfile_t::write(int x) +{ + return status(write((unsigned int)x)); +} + + +/*---------------------------------------------------------- + Unbuffered Write API +----------------------------------------------------------*/ +int pfile_t::write_ub(void *data, int len) +{ + DBG(log_printf(D3LOG, "pfile_t::write_ub(block of %d bytes)\n", len);) + if(fwrite(data, len, 1, f) != 1) + return status(-1); + + return _status; +} + + +int pfile_t::write_ub(unsigned int x) +{ + unsigned char b[4]; + b[0] = x & 0xff; + b[1] = (x >> 8) & 0xff; + b[2] = (x >> 16) & 0xff; + b[3] = (x >> 24) & 0xff; + return status(write_ub(&b, 4)); +} + + +int pfile_t::write_ub(int x) +{ + return status(write_ub((unsigned int)x)); +} + + +/*---------------------------------------------------------- + RIFF style chunk API +----------------------------------------------------------*/ + +int pfile_t::chunk_read() +{ + unsigned int size; + + chunk_writing = 0; + if(read(chunk_id) != 4) + return _status; + if(read(size) != 4) + return _status; + + return buffer_read(size); +} + + +int pfile_t::chunk_write(int id) +{ + chunk_writing = 1; + chunk_id = id; + buffer_init(); + return _status; +} + + +int pfile_t::chunk_end() +{ + if(chunk_writing) + { + write_ub(chunk_id); + write_ub(bufused); + buffer_write(); + } + buffer_close(); + return _status; +} diff --git a/pfile.h b/pfile.h new file mode 100644 index 0000000..15b9220 --- /dev/null +++ b/pfile.h @@ -0,0 +1,136 @@ +/*(LGPL) +--------------------------------------------------------------------------- + pfile.h - Portable File Access Toolkit +--------------------------------------------------------------------------- + * Copyright (C) 2002, David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _PFILE_H_ +#define _PFILE_H_ + + //////////////////////////////////////////////////////////// + // Note that these classes can keep track of only one + // chunk at a time! Recursive chunk-inside-chunk is *NOT* + // supported. +//////////////////////////////////////////////////////////// + +//Create a little endian "FOURCC" ID code. (That is, 'a' will be +//first if the integer result is stored in little endian format +//in a file.) +#define MAKE_4CC(a, b, c, d) \ + ((a)&0xff | ((b)<<8)&0xff00 | \ + ((c)<<16)&0xff0000 | ((d)<<24)&0xff000000) + + + //////////////////////////////////////////////////////////// + // pfile_t - Portable File Access Base Class +//////////////////////////////////////////////////////////// +// Handles the reading and writing of data from/to file +// via the internal buffer. +// +// Reading can be done either directly from the file, or +// through the internal buffer. +// +// To read through the buffer, the desired number of +// bytes (for example, all bytes of a chunk) must be +// read into the buffer using read_buffer(). Subsequent +// reads will be from the buffer, and end-of-buffer is +// treated like EOF. +// +// Writing is always done to the buffer. To actually +// write data to file, call write_buffer(). +// +// IMPORTANT: +// Written data is *lost* if the pfile object +// is destroyed before write_buffer() is called! +// +// Reading RIFF style chunks: +// Use chunk_read() to read the entire chunk into +// the internal buffer. If this succeeds, +// chunk_type() and chunk_size() will return +// information about the chunk, and subsequent +// read() calls will read from the data section of +// the chunk. Use chunk_end() to stop reading, and +// discard the buffer. The next read() will start +// at the first byte after the end of the chunk. +// +// Writing RIFF style chunks: +// Use chunk_write() to set the type of the chunk +// to write. Subsequent write()ing will be done to +// the internal buffer, which will grow as needed. +// Use chunk_end() to write the whole chunk, with +// the correct size and all data. chunk_end() will +// discard the buffer and return the object to +// "direct" operation. +// +class pfile_t +{ + FILE *f; //Just a plain file handle... + int _status; // < 0 if there was an error + int bufsize; //Actual malloc()ed size of buffer + int bufused; //Current buffer write position + int bufpos; //Current buffer read position + char *buffer; //Read/write buffer + int chunk_id; //Chunk type ID + int chunk_writing; //1 if we're building a chunk for writing + + // Initialize buffer for writing. Subsequent write() calls + // will write to the buffer instead of the file. + int buffer_init(); + + // Initialize buffer, and read 'len' bytes into it. + // Subsequent read() calls will read from the buffer + // instead of the file. + int buffer_read(int len); + + //Unbuffered write operations + int write_ub(void *data, int len); + int write_ub(unsigned int x); + int write_ub(int x); + public: + pfile_t(FILE *file); + virtual ~pfile_t(); + + int status(); //Read and reset current status. + int status(int new_status); //Set (provided the current status + // >= 0) and return (new) status + + //These return # of bytes read, or -1 in case of EOF, or an error. + int read(void *data, int len); + int read(unsigned int &x); + int read(int &x); + + void buffer_close(); //Discard the buffer and return to + //"direct" operation. + + //These return # of bytes written, or -1 in case of EOF, or an error. + int write(void *data, int len); + int write(unsigned int x); + int write(int x); + + int buffer_write(); //Write the whole buffer to the file. + //This will flush the buffer as well. + + //RIFF style chunk handling + int chunk_read(); + int chunk_type() { return chunk_id; } + int chunk_size() { return bufused; } + int chunk_write(int id); + int chunk_end(); +}; + +#endif diff --git a/prefs.cpp b/prefs.cpp new file mode 100644 index 0000000..ea60a1e --- /dev/null +++ b/prefs.cpp @@ -0,0 +1,177 @@ +/*(GPL) +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 2001-2003, 2007 David Olofson + * Copyright (C) 2005 Erik Auerswald + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "kobolog.h" +#include "prefs.h" +#include "gfxengine.h" +#include "gamectl.h" +#include "a_types.h" +#include "game.h" + +void prefs_t::init() +{ + comment("--------------------------------------------"); + comment(" Kobo Deluxe "VERSION" Configuration File"); + comment("--------------------------------------------"); + comment(" Switches - [no]"); + comment(" Values - [|\"\"]"); + comment("--------------------------------------------"); + comment("--- System options --------------------------"); + yesno("logfile", logfile, 0); desc("Log To File"); + key("logformat", logformat, 0); desc("Log File Format"); + key("logverbosity", logverbosity, 2); desc("Log Verbosity Level"); + + comment("--- Input options --------------------------"); + yesno("joystick", use_joystick, 0); desc("Use Joystick"); + key("joystick_no", joystick_no, 0); desc("Joystick Number"); + yesno("mouse", use_mouse, 0); desc("Use Mouse"); + key("mousemode", mousemode, MMD_CROSSHAIR); desc("Mouse Control Mode"); + yesno("broken_numdia", broken_numdia, 0); desc("Broken NumPad Diagonals"); + key("dia_emphasis", dia_emphasis, 0); desc("Diagonals Emphasis Filter"); + yesno("always_fire", always_fire, 0); desc("Always Fire"); + yesno("mousecapture", mousecapture, 1); desc("In-game Mouse Capture"); + + comment("--- Game options ---------------------------"); + key("scrollradar", scrollradar, 2); desc("Radar Scroll Mode"); + yesno("filter", filter, 1); desc("Motion Interpolation"); + key("timefilter", timefilter, 50); desc("Time Filter"); + key("countdown", countdown, 5); desc("Get Ready Countdown"); + key("starfield", starfield, 2); desc("Starfield Style"); + key("stars", stars, 500); desc("Number of Parallax Stars"); + key("overheatloud", overheatloud, 100); desc("Overheat Warning Loudness"); + key("cannonloud", cannonloud, 100); desc("Player Cannons Loudness"); + + comment("--- Sound settings -------------------------"); + yesno("sound", use_sound, 1); desc("Enable Sound"); + yesno("music", use_music, 1); desc("Enable Music"); + yesno("cached_sounds", cached_sounds, 0); desc("Use Cached Sounds"); +#ifdef HAVE_OSS + yesno("oss", use_oss, 0); +#else + yesno("oss", use_oss, 0, 0); //Don't write! +#endif + desc("Use OSS Sound Driver"); + key("samplerate", samplerate, 44100); desc("Sample Rate"); + key("latency", latency, 50); desc("Sound Latency"); + key("mixquality", mixquality, AQ_HIGH); desc("Mixing Quality"); + key("vol", volume, 100); desc("Master Volume"); + key("intro_vol", intro_vol, 100); desc("Intro Music Volume"); + key("sfx_vol", sfx_vol, 100); desc("Sound Effects Volume"); + key("music_vol", music_vol, 30); desc("In-Game Music Volume"); + key("reverb", reverb, 100); desc("Reverb Level"); + key("vol_boost", vol_boost, 0); desc("Volume Boost"); + + comment("--- Video settings -------------------------"); + yesno("fullscreen", fullscreen, 0); desc("Fullscreen Display"); + key("videodriver", videodriver, GFX_DRIVER_SDL2D); + desc("Display Driver"); + key("width", width, 640); desc("Horizontal Resolution"); + key("height", height, 480); desc("Vertical Resolution"); + key("aspect", aspect, 1000); desc("Pixel Aspect Ratio"); + key("depth", depth, 0); desc("Display Depth"); + key("maxfps", max_fps, 100); desc("Maximum fps"); + key("maxfpsstrict", max_fps_strict, 0); desc("Strictly Regulated fps"); + key("buffer", doublebuf, 1); desc("Display Buffer Mode"); + yesno("shadow", shadow, 1); desc("Use Software Shadow Buffer"); + key("videomode", videomode, 0x04330); desc("Video Mode"); + yesno("vsync", vsync, 1); desc("Enable Vertical Sync"); + key("videopages", pages, -1); desc("Number of Video Pages"); + + comment("--- Graphics settings ----------------------"); + key("scalemode", scalemode, 1); desc("Scaling Filter Mode"); + yesno("dither", use_dither, 1); desc("Use Dithering"); + key("dither_type", dither_type, 0); desc("Dither Type"); + yesno("broken_rgba8", broken_rgba8, 0); desc("Broken RGBA (OpenGL)"); + yesno("alpha", alpha, 1); desc("Use Alpha Blending"); + key("brightness", brightness, 100); desc("Brightness"); + key("contrast", contrast, 100); desc("Contrast"); + + comment("--- File paths -----------------------------"); + key("files", dir, ""); desc("Game Root Path"); + key("gfx", gfxdir, ""); desc("Graphics Data Path"); + key("sfx", sfxdir, ""); desc("Sound Data Path"); + key("scores", scoredir, ""); desc("Score File Path"); + + // Obsolete stuff (not written into new files) + key("size", o_size, 0, 0); desc("Screen Size (Obsolete)"); + key("wait", o_wait_msec, 30); desc("Game Speed (Obsolete)"); + key("bgm", o_bgm_indexfile, "", 0); + desc("Background Music File (Obsolete)"); + key("threshold", o_threshold, 200, 0); desc("Limiter Gain"); + key("release", o_release, 50, 0); desc("Limiter Speed"); + key("internalres", o_internalres, 1, 0); desc("Texture Resolution"); + + comment("--- Temporary variables --------------------"); + key("last_profile", last_profile, 0); + desc("Last used player profile"); + key("number_of_joysticks", number_of_joysticks, 0); + desc("Number of Connected Joysticks"); + + // "Commands" - never written to config files + command("showcfg", cmd_showcfg); desc("Show Configuration"); + command("hiscores", cmd_hiscores); desc("List High Scores"); + command("highscores", cmd_hiscores); desc("List High Scores"); + command("override", cmd_override); desc("Ignore Configuration File"); + command("debug", cmd_debug); desc("Enable Debug Features"); + command("fps", cmd_fps); desc("Show Frame Rate"); + command("noframe", cmd_noframe); desc("Remove Window Frame"); + command("midi", cmd_midi); desc("Enable MIDI Input"); + command("cheat", cmd_cheat); desc("Enable Cheat Mode"); + command("indicator", cmd_indicator); + desc("Enable Collision Indicator Mode"); + command("pushmove", cmd_pushmove); desc("Enable Push Move Mode"); + command("noparachute", cmd_noparachute); desc("Disable SDL Parachute"); + command("pollaudio", cmd_pollaudio); desc("Use Polling Audio Output"); + command("autoshot", cmd_autoshot); desc("Ingame screenshots/movie"); + command("help", cmd_help); desc("Print usage info and exit"); + command("options_man", cmd_options_man); + desc("Print options for 'man'"); +} + + +void prefs_t::postload() +{ + if(redefined(o_size)) + { + //For pre 20011007 compatibility + width = 320 * o_size; + height = 240 * o_size; + o_size = 0; + accept(o_size); + } + + if((o_wait_msec != 30) && !cmd_cheat) + { + log_printf(ELOG, "'wait' is only avaliable in cheat mode!\n"); + o_wait_msec = 30; + } + + if(scrollradar == 1) + { + log_printf(ELOG, "Radar sweep mode broken and disabled!\n"); + scrollradar = 2; + } + + // Some unimplemented enums were removed in 0.4.1 + if(videodriver != GFX_DRIVER_SDL2D) + videodriver = GFX_DRIVER_GLSDL; +} diff --git a/prefs.h b/prefs.h new file mode 100644 index 0000000..b56bc43 --- /dev/null +++ b/prefs.h @@ -0,0 +1,137 @@ +/*(GPL) +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 2001-2003, 2007 David Olofson + * Copyright (C) 2005 Erik Auerswald + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _KOBO_PREFS_H_ +#define _KOBO_PREFS_H_ + +#include "aconfig.h" +#include "cfgparse.h" + +class prefs_t : public config_parser_t +{ + public: + //System options + int logfile; //Log messages to log.txt/html + int logformat; //0: text, 1: ANSI, 2: HTML + int logverbosity; + + //Input options + int use_joystick; + int joystick_no; //which joystick to use + int use_mouse; + int mousemode; + int broken_numdia; + int dia_emphasis; + int always_fire; + int mousecapture; + + //Game options + int filter; //Use motion filtering + int timefilter; //Delta time filter + int scrollradar; //Radar display mode + int countdown; //"Get Ready" countdown + int starfield; //None/Old/parallax + int stars; //Number of parallax stars + int overheatloud; //Overheat warning loudness + int cannonloud; //Cannon loudness + + //Sound: System + int use_sound; //Enable sound + int use_music; //Enable "real" music + int cached_sounds; //Use prerendered waveforms + int use_oss; //Use OSS audio driver + int samplerate; + int latency; //Audio latency in ms + int mixquality; //Mixer quality control + int volume; //Digital master volume + //Sound: Mixer + int intro_vol; //Intro music volume + int sfx_vol; //Sound effects volume + int music_vol; //In-game music volume + //Sound: Master Effects + int reverb; //Master reverb level + int vol_boost; //Master volume boost + + //Video settings + int fullscreen; //Use fullscreen mode + int videodriver; //Internal video driver + int width; //Screen/window width + int height; //Screen/window height + int aspect; //Pixel aspect ratio * 1000 + int depth; //Bits per pixel + int max_fps; //Maximum fps + int max_fps_strict; //Strictly regulated fps limiter + int doublebuf; //Use double buffering + int shadow; //Use software shadow buffer + int videomode; //New video mode codes + int vsync; //Vertical (retrace) sync + int pages; //Number of physical video pages + + //Graphics settings + int scalemode; //Scaling filter mode + int use_dither; + int dither_type; + int broken_rgba8; //For some OpenGL setups + int alpha; //Alpha blending + int brightness; //Graphics brightness + int contrast; //Graphics contrast + + //File paths + cfg_string_t dir; //Path to kobo-deluxe/ + cfg_string_t gfxdir; //Path to gfx/ + cfg_string_t sfxdir; //Path to sfx/ + cfg_string_t scoredir; //Path to scores/ + + //Obsolete stuff (compatibility) + int o_size; //Screen scale + int o_wait_msec; //ms per control system frame + cfg_string_t o_bgm_indexfile; //Ext playlist path + int o_threshold; //Limiter threshold + int o_release; //Limiter release rate + int o_internalres; //Internal resolution for OpenGL + + //"Hidden" stuff ("to remember until next startup") + int last_profile; //Last used player profile + int number_of_joysticks; //no of connected joysticks + + void init(); + void postload(); + + /* "Commands" - never written to config files */ + int cmd_showcfg; + int cmd_hiscores; + int cmd_override; + int cmd_debug; + int cmd_fps; + int cmd_noframe; + int cmd_midi; + int cmd_cheat; //Unlimited lives; select any starting stage + int cmd_indicator; //Enable collision testing mode + int cmd_pushmove; //Stop when not holding any direction down + int cmd_noparachute; //Disable SDL parachute + int cmd_pollaudio; //Use polling based audio instead of thread + int cmd_autoshot; //Take ingame screenshots + int cmd_help; //Show help and exit + int cmd_options_man; //Output OPTIONS doc in Un*x man source format +}; + +#endif //_KOBO_PREFS_H_ diff --git a/radar.cpp b/radar.cpp new file mode 100644 index 0000000..5932e0b --- /dev/null +++ b/radar.cpp @@ -0,0 +1,297 @@ +/* +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 1995, 1996 Akira Higuchi + * Copyright (C) 2001-2003, 2005-2007 David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + +#include "kobo.h" +#include "kobolog.h" +#include "screen.h" +#include "myship.h" +#include "radar.h" +#include "prefs.h" +#include "random.h" + +/*--------------------------------------------------------------------- + radar_map_t +---------------------------------------------------------------------*/ +radar_map_t::radar_map_t() +{ + w = MAP_SIZEX; + h = MAP_SIZEY; + pixel_core = 0; + pixel_launcher = 0; + pixel_hard = 0; + pixel_bg = 0; +} + + +void radar_map_t::update(int x, int y, int force) +{ + int a = MAP_BITS(screen.get_map(x, y)); + if(IS_SPACE(a)) + { + if(!force) + return; + foreground(pixel_bg); + } + else if(a & CORE) + foreground(pixel_core); + else if((a == U_MASK) || (a == R_MASK) || (a == D_MASK) || (a == L_MASK)) + foreground(pixel_launcher); + else if((a & HIT_MASK)) + foreground(pixel_hard); + point(x, y); +} + + +void radar_map_t::refresh(SDL_Rect *r) +{ + clear(r); + SDL_Rect nr; + if(!r) + { + nr.x = 0; + nr.y = 0; + nr.w = w; + nr.h = h; + r = &nr; + } + int i, j; + for(i = r->x; i < r->w; i++) + for(j = r->y; j < r->h; j++) + update(i, j, 0); +} + + +/*--------------------------------------------------------------------- + radar_window_t +---------------------------------------------------------------------*/ +radar_window_t::radar_window_t() +{ + _mode = RM_OFF; + old_scrollradar = -1; + xpos = -1; + ypos = -1; + xoffs = 0; + yoffs = 0; + time = 0; + refresh_pos = 0; +} + + +void radar_window_t::update(int mx, int my) +{ + wmap->update(mx, my, 1); + if(prefs->scrollradar == 1) + return; /* No instant updates in sweep mode! */ + SDL_Rect r; + r.x = (mx - xoffs) & (MAP_SIZEX-1); + r.y = (my - yoffs) & (MAP_SIZEY-1); + r.w = r.h = 1; + invalidate(&r); +} + + +void radar_window_t::update_player(int px, int py) +{ + SDL_Rect r; + r.x = (px - pxoffs) & (MAP_SIZEX-1); + r.y = (py - pyoffs) & (MAP_SIZEY-1); + r.w = r.h = 1; + invalidate(&r); +} + + +void radar_window_t::refresh(SDL_Rect *r) +{ + int t = SDL_GetTicks(); + clear(r); + switch(_mode) + { + case RM__REINIT: + case RM_OFF: + case RM_NOISE: + case RM_INFO: + break; + case RM_SHOW: + blit(0, 0, wmap); + break; + case RM_RADAR: + switch(prefs->scrollradar) + { + case 0: + blit(0, 0, wmap); + break; + case 1: + foreground(map_rgb(48, 192, 160)); + fillrect(0, refresh_pos - 1, wmap->w, 1); + foreground(map_rgb(40, 160, 128)); + fillrect(0, refresh_pos - 2, wmap->w, 1); + foreground(map_rgb(32, 128, 96)); + fillrect(0, refresh_pos - 3, wmap->w, 1); + // Fallthrough! + case 2: + blit(-xoffs, MAP_SIZEY - yoffs, wmap); + blit(-xoffs, -yoffs, wmap); + blit(MAP_SIZEX - xoffs, MAP_SIZEY - yoffs, wmap); + blit(MAP_SIZEX - xoffs, -yoffs, wmap); + break; + } + if(_mode != RM_SHOW) + { + foreground(map_rgb((t >> 1) & 255, + 120 + ((t >> 2) & 127), + 120 + ((t >> 2) & 127))); + point((xpos - pxoffs) & (MAP_SIZEX - 1), + (ypos - pyoffs) & (MAP_SIZEY - 1)); + } + break; + } +} + + +void radar_window_t::mode(radar_modes_t newmode) +{ + if(newmode == RM__REINIT) + newmode = _mode; + wmap->offscreen(); + wmap->pixel_core = wmap->map_rgb(255, 255, 128); + wmap->pixel_hard = wmap->map_rgb(64, 128, 128); + wmap->pixel_launcher = wmap->map_rgb(64, 200, 240); + wmap->pixel_bg = wmap->map_rgb(32, 48, 64); + wmap->background(wmap->pixel_bg); + wmap->colorkey(wmap->pixel_bg); + _mode = newmode; + refresh_pos = 0; + time = SDL_GetTicks(); + wmap->invalidate(); + invalidate(); +} + + +void radar_window_t::set_scroll(int xs, int ys) +{ + xoffs = (xs + MAP_SIZEX / 2) & (MAP_SIZEX - 1); + yoffs = (ys + MAP_SIZEY / 2) & (MAP_SIZEY - 1); +} + + +void radar_window_t::sweep(void) +{ + int start_y = refresh_pos; + int ct = SDL_GetTicks(); + int t = ct - time; + int end_y = t / 8; + if((t < 0) || (end_y >= wmap->h)) + { + end_y = wmap->h; + time = ct; + refresh_pos = 0; + set_scroll(xpos, ypos); + platched = 0; + } + else + refresh_pos = end_y; + if(!platched) + if(refresh_pos > ((ypos - pyoffs) & (MAP_SIZEY - 1))) + { + pxoffs = xoffs; + pyoffs = yoffs; + platched = 1; + } + SDL_Rect r; + r.x = 0; + r.y = start_y >= 3 ? start_y - 3 : 0; + r.w = wmap->w; + r.h = end_y - start_y + 1; + invalidate(&r); +} + + +void radar_window_t::radar() +{ + int xpos_new = (myship.get_x() & (WORLD_SIZEX - 1)) >> 4; + int ypos_new = (myship.get_y() & (WORLD_SIZEY - 1)) >> 4; + switch(prefs->scrollradar) + { + case 0: /* No scrolling */ + // Note this first one just invalidates the *area* + // that the player is in! That is, if the player + // has moved, the player will be somewhere else + // when the rendering is performed, and no player + // cursor is rendered. + update_player(xpos, ypos); + if((xpos_new == xpos) && (ypos_new == ypos)) + break; + xpos = xpos_new; + ypos = ypos_new; + pxoffs = pyoffs = xoffs = yoffs = 0; + update_player(xpos, ypos); + break; + case 1: /* Radar screen sweep */ + update_player(xpos, ypos); + xpos = xpos_new; + ypos = ypos_new; + sweep(); + update_player(xpos, ypos); + break; + case 2: /* Plain scrolling */ + if((xpos_new == xpos) && (ypos_new == ypos)) + break; + xpos = xpos_new; + ypos = ypos_new; + set_scroll(xpos, ypos); + pxoffs = xoffs; + pyoffs = yoffs; + invalidate(); + break; + } +} + + +void radar_window_t::frame() +{ + if(prefs->scrollradar != old_scrollradar) + { + old_scrollradar = prefs->scrollradar; + refresh_pos = 0; + time = SDL_GetTicks(); + pxoffs = pyoffs = xoffs = yoffs = 0; + invalidate(); + } + switch(_mode) + { + case RM__REINIT: + case RM_OFF: + break; + case RM_RADAR: + radar(); + break; + case RM_SHOW: + break; + case RM_NOISE: + case RM_INFO: + invalidate(); + break; + } +} diff --git a/radar.h b/radar.h new file mode 100644 index 0000000..4e55a8e --- /dev/null +++ b/radar.h @@ -0,0 +1,76 @@ +/*(GPL) +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 1995, 1996 Akira Higuchi + * Copyright (C) 2001-2003, 2005-2007 David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef KOBO_RADAR_H +#define KOBO_RADAR_H + +#include "window.h" + +enum radar_modes_t +{ + RM__REINIT, // Reinitialize (lost windows etc) + RM_OFF, // Gray, empty + RM_RADAR, // Radar display + RM_SHOW, // Show map (no player ship cursor) + RM_NOISE, // Radar interference + RM_INFO // Scrolling info display +}; + +// The off-screen map window +class radar_map_t : public window_t +{ + public: + int w, h; //Map size (tiles) + Uint32 pixel_core; //Pixel colors + Uint32 pixel_launcher; + Uint32 pixel_hard; + Uint32 pixel_bg; + radar_map_t(); + void refresh(SDL_Rect *r); + void update(int x, int y, int force); //Update one tile +}; + +// The on-screen radar window +class radar_window_t : public window_t +{ + radar_modes_t _mode; + int old_scrollradar; //To detect prefs change + int xpos, ypos; //Player position (tiles) + int xoffs, yoffs; //Scroll offset (tiles) + int pxoffs, pyoffs; //Scroll offset for player marker + int platched; //p*offset latched yet? + int time; //for delta time calc + int refresh_pos; //Sweeping refresh posn + void sweep(); //Incremental sweeping refresh + void radar(); //Drive any actual radar mode + void noise(); //Render noise effect + void set_scroll(int xs, int ys);//Set map scroll offset + public: + radar_window_t(); + void refresh(SDL_Rect *r); + void mode(radar_modes_t newmode);//Set radar mode + void update(int mx, int my); //Update map + radar + void update_player(int px, int py);//Update player cursor + void frame(); //Track player, drive logic etc... +}; + +#endif // KOBO_RADAR_H diff --git a/random.cpp b/random.cpp new file mode 100644 index 0000000..051a794 --- /dev/null +++ b/random.cpp @@ -0,0 +1,26 @@ +/*(GPL) +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 1995, 1996, Akira Higuchi + * Copyright (C) 2002, David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "random.h" + +rand_num_t gamerand; +rand_num_t pubrand; diff --git a/random.h b/random.h new file mode 100644 index 0000000..97c69c7 --- /dev/null +++ b/random.h @@ -0,0 +1,71 @@ +/*(GPL) +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 1995, 1996, Akira Higuchi + * Copyright (C) 2002, 2007 David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _KOBO_RANDOM_H_ +#define _KOBO_RANDOM_H_ + +#include +#include "glSDL.h" + +class rand_num_t +{ + Uint32 seed; + public: + void init(Uint32 _seed = 0) + { + if(_seed) + seed = _seed; + else + seed = SDL_GetTicks(); + } + Uint32 get_seed() { return seed; } + Uint32 get() + { + seed *= 1566083941UL; + seed++; + seed &= 0xffffffffUL; + return seed; + } + Uint32 get(Uint32 bit) + { + seed *= 1566083941UL; + seed++; + seed &= 0xffffffffUL; + return (seed >> (32 - bit)); + } +}; + +//This instance is *ONLY* for map generation and +//pure game AI stuff!!! Stealing numbers from here +//will screw up demo playback totally, as demos +//record only the seed used for each level; not +//every random number used. +extern rand_num_t gamerand; + +//Use this "public" random number generator for +//other stuff, like explosion effects, and things +//that may pick different amounts of numbers +//depending on engine version, configuration, +//computer speed and the like. +extern rand_num_t pubrand; + +#endif //_KOBO_RANDOM_H_ diff --git a/rwc-20040113.txt b/rwc-20040113.txt new file mode 100644 index 0000000..6af3765 --- /dev/null +++ b/rwc-20040113.txt @@ -0,0 +1,15 @@ +-------------------------------------------------------- + (lines) (words) (bytes) +Root: 17203 46478 367321 +-------------------------------------------------------- +Subdirs: + ./autom4te.cache 0 0 0 + ./data 35 108 736 + ./eel 4474 13404 105546 + ./graphics 9916 28839 212012 + ./sound 16624 55079 397875 +-------------------------------------------------------- +Total: 48252 143908 1083490 +-------------------------------------------------------- +Filename pattern: *.([cChH]|[ch]pp|[CH]PP) +-------------------------------------------------------- diff --git a/rwc-20071005.txt b/rwc-20071005.txt new file mode 100644 index 0000000..54a108d --- /dev/null +++ b/rwc-20071005.txt @@ -0,0 +1,15 @@ +-------------------------------------------------------- + (lines) (words) (bytes) +Root: 17554 47376 376215 +-------------------------------------------------------- +Subdirs: + ./autom4te.cache 0 0 0 + ./data 35 108 736 + ./eel 4474 13401 105519 + ./graphics 10588 31216 229546 + ./sound 16631 55108 398040 +-------------------------------------------------------- +Total: 49282 147209 1110056 +-------------------------------------------------------- +Filename pattern: *.([cChH]|[ch]pp|[CH]PP) +-------------------------------------------------------- diff --git a/scenes.cpp b/scenes.cpp new file mode 100644 index 0000000..583fb40 --- /dev/null +++ b/scenes.cpp @@ -0,0 +1,1179 @@ + +/* + * XKOBO, a video-oriented game + * Copyright (C) 1995,1996 Akira Higuchi + * a-higuti@math.hokudai.ac.jp + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include "scenes.h" + +const _scene scene[] = { +#if 0 + /* Test map */ + { + 0, 32, 0, + &enemy_m1, 128, &beam, 16, + 1,{ + {&enemy_m4, 1, 5}, +// {&enemy4, 10, 5}, + }, + 1,{ +// {32, 64, 31, 62}, + {48, 64, 4, 4}, + }, + }, +#endif + /* 1 */ + { + 0, 32, 96, + &beam, 128, &beam, 16, + 1,{ + {&enemy4, 10, 5}, + }, + 2,{ + {48, 64, 4, 4}, + {24, 80, 4, 4}, + }, + }, + /* 2 */ + { + 0, 32, 96, + &beam, 64, &beam, 64, + 3,{ + {&enemy4, 10, 5}, + {&enemy4, 10, 5}, + {&enemy1, 10, 5}, + }, + 4,{ + {16, 48, 6, 6}, + {48, 48, 6, 6}, + {16, 64, 6, 6}, + {48, 64, 6, 6}, + }, + }, + /* 3 */ + { + 64, 32, 64, + &beam, 64, &beam, 16, + 1,{ + {&rock, 20, 3}, + }, + 6,{ + {16, 40, 4, 4}, + {16, 60, 4, 4}, + {16, 80, 4, 4}, + {48, 40, 4, 4}, + {48, 60, 4, 4}, + {48, 80, 4, 4}, + }, + }, + /* 4 */ + { + 0, 32, 96, + &beam, 32, &beam, 8, + 1,{ + {&enemy4, 10, 5}, + }, + 3,{ + {14, 55, 6, 6}, + {55, 14, 6, 6}, + {35, 70, 6, 6}, + }, + }, + /* 5 */ + { + 0, 32, 96, + &beam, 128, &beam, 128, + 3,{ + {&enemy6, 10, 5}, + {&enemy6, 10, 5}, + {&enemy4, 10, 5}, + }, + 2,{ + {32, 32, 6, 6}, + {32, 64, 6, 6}, + }, + }, + /* 6 */ + { + 0, 32, 96, + &enemy1, 32, &enemy1, 8, + 0,{ + {&enemy1, 40, 10}, + }, + 1,{ + {32, 64, 8, 8}, + }, + }, + /* 7 */ + { + 0, 32, 64, + &ring, 64, &enemy1, 32, + 2,{ + {&enemy3, 30, 5}, + {&enemy6, 20, 5}, + }, + 8,{ + {32, 54, 3, 3}, + {42, 54, 3, 3}, + {42, 64, 3, 3}, + {42, 74, 3, 3}, + {32, 74, 3, 3}, + {22, 74, 3, 3}, + {22, 64, 3, 3}, + {22, 54, 3, 3}, + }, + }, + /* 8 */ + { + 0, 32, 64, + &enemy4, 64, &enemy1, 8, + 3,{ + {&ring , 20, 5}, + {&ring , 20, 5}, + {&ring , 20, 5}, + }, + 8,{ + {48, 64, 4, 4}, + {16, 64, 4, 4}, + {32, 80, 4, 4}, + {32, 48, 4, 4}, + {44, 76, 4, 4}, + {20, 76, 4, 4}, + {44, 52, 4, 4}, + {20, 52, 4, 4}, + }, + }, + /* 9 */ + { + 0, 32, 96, + &beam, 16, &beam, 8, + 1,{ + {&bomb2, 20, 5}, + }, + 1,{ + {32, 32, 7, 7}, + }, + }, + /* 10 */ + { + 0, 32, 96, + &bomb1, 128, &bomb1, 4, + 1,{ + {&rock, 100, 5}, + }, + 1,{ + {32, 64, 12, 12}, + }, + }, + /* 11 */ + { + 0, 32, 96, + &enemy2, 128, &enemy1, 32, + 5,{ + {&rock, 30, 5}, + {&enemy3, 50, 5}, + {&enemy6, 20, 5}, + {&enemy7, 10, 5}, + {&bomb1, 20, 5}, + }, + 6,{ + { 5, 64, 3, 3}, + {15, 64, 3, 3}, + {25, 64, 3, 3}, + {35, 64, 3, 3}, + {45, 64, 3, 3}, + {55, 64, 3, 3}, + }, + }, + /* 12 */ + { + 0, 47, 33, + &beam, 128, &beam, 16, + 3,{ + {&enemy6, 10, 5}, + {&enemy6, 10, 5}, + {&rock, 100, 5}, + }, + 3,{ + { 15, 88, 12, 12}, + { 21, 20, 12, 12}, + { 50, 70, 12, 12}, + }, + }, + /* 13 */ + { + 0, 32, 64, + &bomb2, 128, &enemy1, 32, + 2,{ + {&bomb1, 30, 5}, + {&bomb1, 20, 5}, + }, + 5,{ + { 24, 66, 3, 3}, + { 23, 80, 3, 3}, + { 44, 50, 3, 3}, + { 39, 102, 3, 3}, + { 15, 43, 3, 3}, + }, + }, + /* 14 */ + { + 0, 24, 107, + &enemy2, 128, &beam, 8, + 4,{ + {&enemy3, 10, 5}, + {&enemy6, 10, 5}, + {&rock, 100, 5}, + {&enemy2, 10, 5}, + }, + 3,{ + { 9, 36, 5, 5}, + { 44, 19, 5, 5}, + { 46, 79, 5, 5}, + }, + }, + /* 15 */ + { + 0, 36, 94, + &enemy4, 64, &bomb1, 32, + 2,{ + {&enemy6, 10, 5}, + {&rock, 50, 5}, + }, + 5,{ + { 16, 54, 4, 4}, + { 47, 56, 4, 4}, + { 24, 70, 4, 4}, + { 31, 14, 4, 4}, + { 27, 31, 4, 4}, + }, + }, + /* 16 */ + { + 0, 31, 37, + &enemy6, 64, &enemy6, 8, + 3,{ + {&enemy1, 20, 5}, + {&enemy3, 10, 5}, + {&rock, 100, 5}, + }, + 5,{ + { 41, 84, 6, 10}, + { 12, 115, 6, 5}, + { 22, 92, 6, 10}, + { 11, 26, 8, 8}, + { 51, 65, 9, 7}, + }, + }, + /* 17 */ + { + 0, 53, 17, + &beam, 32, &enemy1, 32, + 1,{ + {&enemy3, 10, 5}, + }, + 10,{ + { 14, 99, 6, 6}, + { 37, 18, 6, 6}, + { 13, 67, 6, 6}, + { 19, 46, 6, 6}, + { 41, 59, 6, 6}, + { 39, 97, 6, 6}, + { 47, 32, 6, 6}, + { 56, 100, 6, 6}, + { 19, 25, 6, 6}, + { 54, 76, 6, 6}, + }, + }, + /* 18 */ + { + 0, 32, 80, + &enemy1, 32, &ring, 8, + 4,{ + {&rock, 40, 2}, + {&enemy1, 20, 5}, + {&rock, 40, 5}, + {&enemy1, 20, 5}, + }, + 3,{ + { 27, 104, 5, 5}, + { 49, 105, 5, 5}, + { 32, 90, 5, 5}, + }, + }, + /* 19 */ + { + 0, 32, 64, + &ring, 128, &enemy1, 8, + 0,{ + {&enemy1, 30, 5}, + }, + 16,{ + { 32, 91, 3, 3}, + { 42, 89, 3, 3}, + { 51, 83, 3, 3}, + { 57, 74, 3, 3}, + { 59, 64, 3, 3}, + { 57, 54, 3, 3}, + { 51, 45, 3, 3}, + { 42, 39, 3, 3}, + { 32, 37, 3, 3}, + { 22, 39, 3, 3}, + { 13, 45, 3, 3}, + { 7, 54, 3, 3}, + { 5, 64, 3, 3}, + { 7, 74, 3, 3}, + { 13, 83, 3, 3}, + { 22, 89, 3, 3}, + }, + }, + /* 20 */ + { + 0, 7, 84, + &enemy7, 128, &enemy5, 16, + 0,{ + {&bomb2, 30, 5}, + }, + 20,{ + { 37, 82, 6, 6}, + { 13, 99, 6, 6}, + { 30, 44, 6, 6}, + { 19, 14, 6, 6}, + { 55, 85, 6, 6}, + { 23, 69, 6, 6}, + { 16, 35, 6, 6}, + { 11, 52, 6, 6}, + { 36, 116, 6, 6}, + { 39, 97, 6, 6}, + { 50, 114, 6, 6}, + { 39, 22, 6, 6}, + { 55, 43, 6, 6}, + { 52, 71, 6, 6}, + { 56, 100, 6, 6}, + { 54, 25, 6, 6}, + { 51, 57, 6, 6}, + { 7, 115, 6, 6}, + { 47, 8, 6, 6}, + { 8, 70, 6, 6}, + }, + }, + /* 21 */ + { + 0, 26, 30, + &enemy1, 128, &beam, 16, + 2,{ + {&enemy3, 20, 5}, + {&rock, 50, 5}, + }, + 6,{ + { 27, 79, 5, 5}, + { 6, 105, 5, 5}, + { 11, 50, 5, 5}, + { 11, 23, 5, 5}, + { 56, 57, 5, 5}, + { 7, 70, 5, 5}, + }, + }, + /* 22 */ + { + 0, 38, 120, + &ring, 128, &beam, 16, + 6,{ + {&ring, 10, 5}, + {&ring, 10, 5}, + {&ring, 10, 5}, + {&ring, 10, 5}, + {&ring, 10, 5}, + {&enemy_m1, 1, 5}, + }, + 30,{ + { 55, 25, 4, 4}, + { 49, 12, 4, 4}, + { 30, 84, 4, 4}, + { 33, 97, 4, 4}, + { 24, 21, 4, 4}, + { 28, 52, 4, 4}, + { 50, 117, 4, 4}, + { 22, 95, 4, 4}, + { 46, 56, 4, 4}, + { 36, 10, 4, 4}, + { 15, 77, 4, 4}, + { 32, 74, 4, 4}, + { 7, 15, 4, 4}, + { 13, 107, 4, 4}, + { 6, 51, 4, 4}, + { 11, 62, 4, 4}, + { 57, 76, 4, 4}, + { 57, 95, 4, 4}, + { 11, 90, 4, 4}, + { 46, 93, 4, 4}, + { 34, 27, 4, 4}, + { 58, 56, 4, 4}, + { 40, 45, 4, 4}, + { 10, 31, 4, 4}, + { 44, 35, 4, 4}, + { 25, 122, 4, 4}, + { 24, 62, 4, 4}, + { 51, 107, 4, 4}, + { 16, 50, 4, 4}, + { 25, 110, 4, 4}, + }, + }, + /* 23 */ + { + 0, 13, 92, + &bomb1, 64, &bomb1, 32, + 4,{ + {&enemy1, 20, 5}, + {&enemy2, 10, 5}, + {&enemy7, 10, 5}, + {&enemy6, 20, 5}, + }, + 5,{ + { 40, 95, 15, 15}, + { 44, 28, 13, 18}, + { 15, 16, 12, 15}, + { 14, 50, 13, 12}, + { 49, 62, 12, 11}, + }, + }, + /* 24 */ + { + 127, 32, 41, + &enemy1, 128, &beam, 16, + 3,{ + {&rock, 50, 5}, + {&enemy2, 20, 5}, + {&bomb2, 30, 5}, + }, + 8,{ + { 38, 73, 4, 4}, + { 27, 98, 4, 4}, + { 27, 71, 4, 4}, + { 56, 89, 4, 4}, + { 39, 6, 4, 4}, + { 12, 67, 4, 4}, + { 58, 14, 4, 4}, + { 14, 21, 4, 4}, + }, + }, + /* 25 */ + { + 256, 32, 96, + &beam, 32, &enemy1, 32, + 2,{ + {&enemy6, 50, 5}, + {&rock, 100, 5}, + }, + 2,{ + {25, 53, 7, 6}, + {40, 70, 5, 4}, + }, + }, + /* 26 */ + { + 0, 32, 64, + &ring, 64, &ring, 16, + 0,{ + {&enemy1, 40, 10}, + }, + 32,{ + { 8, 8, 5, 5}, + {24, 8, 5, 5}, + {40, 8, 5, 5}, + {56, 8, 5, 5}, + { 8, 24, 5, 5}, + {24, 24, 5, 5}, + {40, 24, 5, 5}, + {56, 24, 5, 5}, + { 8, 40, 5, 5}, + {24, 40, 5, 5}, + {40, 40, 5, 5}, + {56, 40, 5, 5}, + { 8, 56, 5, 5}, + {24, 56, 5, 5}, + {40, 56, 5, 5}, + {56, 56, 5, 5}, + { 8, 72, 5, 5}, + {24, 72, 5, 5}, + {40, 72, 5, 5}, + {56, 72, 5, 5}, + { 8, 88, 5, 5}, + {24, 88, 5, 5}, + {40, 88, 5, 5}, + {56, 88, 5, 5}, + { 8, 104, 5, 5}, + {24, 104, 5, 5}, + {40, 104, 5, 5}, + {56, 104, 5, 5}, + { 8, 120, 5, 5}, + {24, 120, 5, 5}, + {40, 120, 5, 5}, + {56, 120, 5, 5}, + }, + }, + /* 27 */ + { + 0, 32, 64, + &beam, 32, &enemy5, 32, + 3,{ + {&enemy1, 20, 5}, + {&bomb1, 50, 5}, + {&enemy_m2, 1, 5}, + }, + 4,{ + { 49, 64, 6, 10}, + { 40, 40, 11, 4}, + { 36, 95, 13, 4}, + { 13, 74, 8, 10}, + }, + }, + /* 28 */ + { + 4, 45, 107, + &enemy1, 32, &enemy5, 16, + 1,{ + {&rock, 50, 5}, + }, + 4,{ + { 15, 108, 11, 18}, + { 13, 62, 12, 19}, + { 46, 42, 11, 41}, + { 16, 23, 13, 13}, + }, + }, + /* 29 */ + { + 0, 32, 60, + &enemy2, 128, &beam, 4, + 5,{ + {&enemy5, 20, 5}, + {&bomb2, 10, 5}, + {&rock, 50, 5}, + {&enemy_m1, 1, 5}, + {&enemy7, 10, 5}, + }, + 5,{ + { 40, 46, 13, 9}, + { 20, 74, 12, 8}, + { 24, 106, 11, 6}, + { 29, 120, 14, 6}, + { 54, 90, 5, 8}, + }, + }, + /* 30 */ + { + 0, 23, 71, + &enemy5, 64, &beam, 16, + 3,{ + {&enemy6, 2, 5}, + {&enemy6, 2, 5}, + {&enemy_m4, 1, 5}, + }, + 20,{ + { 38, 120, 5, 5}, + { 43, 64, 5, 5}, + { 32, 106, 5, 5}, + { 14, 52, 5, 5}, + { 48, 76, 5, 5}, + { 9, 110, 5, 5}, + { 12, 34, 5, 5}, + { 40, 90, 5, 5}, + { 38, 33, 5, 5}, + { 23, 9, 5, 5}, + { 22, 120, 5, 5}, + { 9, 90, 5, 5}, + { 6, 15, 5, 5}, + { 41, 46, 5, 5}, + { 43, 13, 5, 5}, + { 25, 88, 5, 5}, + { 8, 65, 5, 5}, + { 57, 49, 5, 5}, + { 52, 108, 5, 5}, + { 6, 77, 5, 5}, + }, + }, + /* 31 */ + { + 0, 32, 120, + &ring, 64, &ring, 8, + 0,{ + {&enemy1, 10, 5}, + }, + 16,{ + { 24, 8, 6, 6}, + { 24, 24, 6, 6}, + { 24, 40, 6, 6}, + { 24, 56, 6, 6}, + { 24, 72, 6, 6}, + { 24, 88, 6, 6}, + { 24, 104, 6, 6}, + { 24, 120, 6, 6}, + { 40, 8, 6, 6}, + { 40, 24, 6, 6}, + { 40, 40, 6, 6}, + { 40, 56, 6, 6}, + { 40, 72, 6, 6}, + { 40, 88, 6, 6}, + { 40, 104, 6, 6}, + { 40, 120, 6, 6}, + }, + }, + /* 32 */ + { + 0, 32, 96, + &beam, 128, &beam, 16, + 0,{ + {&enemy1, 40, 10}, + }, + 1,{ + {32, 64, 24, 24}, + }, + }, + /* 33 */ + { + 0, 24, 113, + &enemy4, 32, &enemy4, 16, + 5,{ + {&enemy5, 30, 5}, + {&bomb1, 50, 5}, + {&enemy_m2, 1, 5}, + {&enemy2, 20, 5}, + {&rock, 100, 5}, + }, + 5,{ + { 17, 70, 13, 21}, + { 46, 32, 10, 10}, + { 49, 63, 10, 11}, + { 18, 25, 14, 21}, + { 45, 109, 10, 17}, + }, + }, + /* 34 */ + { + 0, 54, 120, + &enemy6, 64, &beam, 16, + 1,{ + {&bomb2, 10, 5}, + }, + 15,{ + { 8, 87, 6, 15}, + { 26, 72, 9, 12}, + { 37, 110, 9, 6}, + { 36, 31, 16, 5}, + { 32, 11, 17, 9}, + { 46, 51, 6, 12}, + { 54, 96, 5, 10}, + { 12, 39, 5, 11}, + { 13, 116, 9, 9}, + { 40, 93, 7, 6}, + { 7, 64, 6, 6}, + { 7, 10, 5, 8}, + { 47, 77, 8, 5}, + { 28, 46, 5, 6}, + { 56, 14, 5, 5}, + }, + }, + /* 35 */ + { + 0, 32, 64, + &enemy3, 128, &ring, 32, + 8,{ + {&enemy1, 10, 5}, + {&enemy_m1, 1, 5}, + {&bomb2, 10, 5}, + {&enemy2, 10, 5}, + {&enemy_m2, 1, 5}, + {&enemy4, 10, 5}, + {&enemy5, 10, 5}, + {&enemy7, 10, 5}, + }, + 8,{ + {32, 48, 7, 7}, + {48, 48, 7, 7}, + {48, 64, 7, 7}, + {48, 80, 7, 7}, + {32, 80, 7, 7}, + {16, 80, 7, 7}, + {16, 64, 7, 7}, + {16, 48, 7, 7}, + }, + }, + /* 36 */ + { + 0, 32, 64, + &beam, 16, &enemy2, 64, + 5,{ + {&enemy1, 10, 10}, + {&enemy2, 10, 10}, + {&bomb2, 10, 10}, + {&enemy_m1, 1, 10}, + {&enemy_m2, 1, 10}, + }, + 10,{ + {16, 20, 4, 4}, + {16, 40, 4, 4}, + {16, 60, 4, 4}, + {16, 80, 4, 4}, + {16,100, 4, 4}, + {48, 20, 4, 4}, + {48, 40, 4, 4}, + {48, 60, 4, 4}, + {48, 80, 4, 4}, + {48,100, 4, 4}, + }, + }, + /* 37 */ + { + 256, 32, 96, + &beam, 64, &ring, 64, + 0,{ + {&ring, 0, 5}, + }, + 1,{ + {32, 58, 18, 18}, + }, + }, + /* 38 */ + { + 0, 32, 72, + &ring, 64, &bomb1, 4, + 1,{ + {&rock, 10, 5}, + }, + 20,{ + {16, 48, 3, 3}, + {24, 48, 3, 3}, + {32, 48, 3, 3}, + {40, 48, 3, 3}, + {48, 48, 3, 3}, + {16, 64, 3, 3}, + {24, 64, 3, 3}, + {32, 64, 3, 3}, + {40, 64, 3, 3}, + {48, 64, 3, 3}, + {16, 80, 3, 3}, + {24, 80, 3, 3}, + {32, 80, 3, 3}, + {40, 80, 3, 3}, + {48, 80, 3, 3}, + {16, 96, 3, 3}, + {24, 96, 3, 3}, + {32, 96, 3, 3}, + {40, 96, 3, 3}, + {48, 96, 3, 3}, + }, + }, + /* 39 */ + { + 0, 32, 50, + &enemy5, 32, &enemy2, 16, + 6,{ + {&enemy_m2, 1, 5}, + {&rock , 50, 5}, + {&rock , 50, 5}, + {&rock , 50, 5}, + {&enemy_m1, 1, 5}, + {&rock , 50, 5}, + }, + 8,{ + {34, 14, 4, 4}, + {16, 22, 4, 4}, + { 6, 35, 4, 4}, + {22, 38, 4, 4}, + {45, 40, 4, 4}, + { 6, 52, 4, 4}, + {46, 66, 4, 4}, + {30, 70, 4, 4}, + {15, 90, 4, 4}, + }, + }, + /* 40 */ + { + 0, 28, 11, + &bomb1, 128, &enemy1, 16, + 1,{ + {&enemy6, 10, 5}, + }, + 35,{ + { 12, 48, 9, 9}, + { 14, 80, 6, 5}, + { 42, 14, 7, 3}, + { 52, 112, 4, 9}, + { 33, 103, 5, 6}, + { 17, 12, 4, 3}, + { 49, 78, 5, 4}, + { 49, 50, 4, 5}, + { 19, 32, 5, 5}, + { 32, 77, 6, 4}, + { 9, 113, 4, 9}, + { 36, 38, 7, 6}, + { 50, 96, 8, 3}, + { 57, 7, 3, 5}, + { 53, 34, 5, 7}, + { 11, 94, 5, 3}, + { 27, 63, 3, 6}, + { 44, 4, 3, 3}, + { 48, 63, 5, 6}, + { 37, 51, 6, 3}, + { 28, 116, 3, 3}, + { 8, 31, 4, 5}, + { 4, 18, 3, 3}, + { 13, 69, 6, 4}, + { 21, 96, 3, 3}, + { 36, 114, 3, 3}, + { 55, 87, 5, 3}, + { 58, 63, 3, 7}, + { 35, 87, 4, 4}, + { 35, 25, 3, 4}, + { 20, 107, 3, 5}, + { 13, 4, 3, 3}, + { 23, 21, 4, 4}, + { 5, 8, 3, 5}, + { 47, 22, 7, 3}, + }, + }, + /* 41 */ + { + 0, 32, 96, + &beam, 64, &beam, 16, + 1,{ + {&bomb2, 40, 10}, + }, + 1,{ + {32, 64, 18, 18}, + }, + }, + /* 42 */ + { + 0, 54, 46, + &enemy7, 64, &enemy5, 32, + 3,{ + {&bomb2, 10, 5}, + {&enemy1, 10, 5}, + {&enemy6, 10, 5}, + }, + 20,{ + { 8, 106, 5, 8}, + { 7, 32, 5, 13}, + { 39, 83, 9, 7}, + { 54, 63, 8, 9}, + { 28, 20, 6, 13}, + { 16, 61, 14, 10}, + { 55, 25, 6, 13}, + { 53, 106, 8, 7}, + { 38, 115, 5, 7}, + { 22, 109, 7, 14}, + { 12, 82, 7, 8}, + { 39, 51, 5, 5}, + { 57, 89, 5, 7}, + { 41, 21, 5, 7}, + { 10, 10, 9, 6}, + { 20, 41, 5, 5}, + { 38, 66, 5, 5}, + { 54, 121, 7, 5}, + { 37, 100, 5, 6}, + { 41, 7, 5, 5}, + }, + }, + /* 43 */ + { + 0, 22, 107, + &enemy2, 64, &bomb1, 8, + 7,{ + {&enemy4, 20, 5}, + {&bomb2, 30, 5}, + {&enemy2, 20, 5}, + {&enemy6, 20, 5}, + {&bomb2, 30, 5}, + {&enemy7, 30, 5}, + {&enemy_m3, 1, 5}, + }, + 5,{ + { 49, 38, 8, 14}, + { 20, 86, 5, 10}, + { 19, 28, 14, 16}, + { 19, 57, 17, 8}, + { 48, 86, 8, 18}, + }, + }, + /* 44 */ + { + 0, 32, 64, + &enemy2, 64, &ring, 8, + 4,{ + {&bomb2, 20, 7}, + {&rock, 20, 8}, + {&enemy_m1, 1, 5}, + {&rock, 20, 8}, + }, + 24,{ + { 46, 64, 3, 3}, + { 18, 64, 3, 3}, + { 32, 79, 3, 3}, + { 32, 48, 3, 3}, + { 43, 75, 3, 3}, + { 21, 75, 3, 3}, + { 43, 53, 3, 3}, + { 21, 53, 3, 3}, + { 32, 91, 3, 3}, + { 42, 89, 3, 3}, + { 51, 83, 3, 3}, + { 57, 74, 3, 3}, + { 59, 64, 3, 3}, + { 57, 54, 3, 3}, + { 51, 45, 3, 3}, + { 42, 39, 3, 3}, + { 32, 37, 3, 3}, + { 22, 39, 3, 3}, + { 13, 45, 3, 3}, + { 7, 54, 3, 3}, + { 5, 64, 3, 3}, + { 7, 74, 3, 3}, + { 13, 83, 3, 3}, + { 22, 89, 3, 3}, + }, + }, + /* 45 */ + { + 0, 31, 87, + &bomb1, 64, &ring, 16, + 1,{ + {&bomb2, 20, 5}, + }, + 10,{ + { 18, 66, 15, 15}, + { 52, 59, 7, 54}, + { 31, 101, 8, 7}, + { 39, 41, 4, 30}, + { 9, 97, 7, 13}, + { 21, 44, 11, 5}, + { 25, 118, 5, 5}, + { 20, 16, 8, 14}, + { 42, 122, 10, 4}, + { 5, 16, 4, 4}, + }, + }, + /* 46 */ + { + 0, 59, 34, + &beam, 64, &beam, 16, + 4,{ + {&rock, 15, 5}, + {&enemy_m3, 1, 5}, + {&rock, 15, 5}, + {&enemy_m1, 1, 5}, + }, + 35,{ + { 46, 19, 9, 10}, + { 45, 115, 10, 4}, + { 14, 60, 5, 8}, + { 48, 60, 5, 10}, + { 21, 45, 8, 5}, + { 11, 83, 5, 13}, + { 39, 97, 13, 8}, + { 36, 49, 4, 3}, + { 18, 8, 5, 4}, + { 40, 80, 9, 5}, + { 54, 44, 8, 4}, + { 13, 27, 9, 3}, + { 15, 110, 3, 5}, + { 9, 122, 5, 4}, + { 28, 63, 6, 6}, + { 35, 39, 3, 3}, + { 6, 5, 5, 3}, + { 6, 113, 4, 3}, + { 6, 40, 4, 5}, + { 29, 116, 3, 9}, + { 29, 9, 4, 4}, + { 59, 65, 3, 10}, + { 21, 86, 3, 7}, + { 4, 60, 3, 6}, + { 6, 18, 5, 4}, + { 29, 22, 5, 6}, + { 52, 4, 10, 3}, + { 18, 19, 4, 3}, + { 46, 34, 5, 3}, + { 57, 91, 3, 4}, + { 59, 103, 3, 6}, + { 25, 35, 4, 3}, + { 19, 122, 3, 4}, + { 54, 80, 3, 3}, + { 5, 101, 3, 3}, + }, + }, + /* 47 */ + { + 0, 24, 31, + &enemy5, 64, &ring, 32, + 5,{ + {&enemy1, 10, 5}, + {&enemy7, 10, 5}, + {&enemy1, 10, 5}, + {&enemy7, 10, 5}, + {&bomb2, 10, 5}, + }, + 35,{ + { 29, 37, 19, 2}, + { 24, 109, 3, 11}, + { 7, 62, 3, 4}, + { 47, 92, 2, 4}, + { 50, 112, 7, 12}, + { 54, 22, 8, 10}, + { 35, 104, 5, 7}, + { 32, 69, 9, 5}, + { 27, 46, 17, 5}, + { 32, 14, 9, 10}, + { 12, 28, 8, 4}, + { 5, 94, 4, 18}, + { 46, 57, 7, 2}, + { 46, 83, 11, 3}, + { 58, 76, 4, 2}, + { 56, 94, 4, 4}, + { 59, 63, 2, 3}, + { 16, 120, 3, 4}, + { 14, 75, 2, 11}, + { 17, 18, 2, 2}, + { 7, 6, 6, 4}, + { 37, 28, 6, 2}, + { 6, 47, 2, 3}, + { 50, 72, 2, 2}, + { 57, 44, 2, 9}, + { 18, 8, 2, 6}, + { 46, 8, 2, 2}, + { 25, 90, 4, 2}, + { 4, 37, 3, 3}, + { 17, 98, 2, 2}, + { 27, 58, 9, 2}, + { 27, 81, 5, 3}, + { 57, 7, 5, 2}, + { 7, 120, 2, 6}, + { 36, 92, 3, 3}, + }, + }, + /* 48 */ + { + 0, 19, 92, + &enemy1, 64, &enemy2, 128, + 3,{ + {&enemy1, 10, 5}, + {&bomb2, 10, 5}, + {&rock, 20, 5}, + }, + 38,{ + { 16, 54, 3, 3}, + { 47, 56, 3, 4}, + { 24, 70, 4, 3}, + { 31, 14, 3, 3}, + { 27, 31, 4, 3}, + { 36, 94, 4, 4}, + { 21, 19, 3, 4}, + { 36, 68, 4, 3}, + { 53, 4, 3, 3}, + { 36, 80, 4, 4}, + { 17, 36, 4, 3}, + { 34, 118, 4, 3}, + { 40, 13, 3, 4}, + { 55, 121, 4, 4}, + { 43, 26, 4, 3}, + { 12, 71, 4, 4}, + { 58, 108, 3, 4}, + { 51, 36, 4, 4}, + { 23, 94, 3, 3}, + { 46, 73, 4, 4}, + { 9, 25, 4, 3}, + { 27, 48, 3, 3}, + { 50, 91, 3, 3}, + { 14, 122, 3, 3}, + { 17, 113, 3, 4}, + { 16, 8, 3, 4}, + { 36, 38, 3, 4}, + { 25, 103, 4, 3}, + { 55, 70, 3, 4}, + { 28, 56, 3, 3}, + { 23, 85, 3, 3}, + { 50, 108, 3, 3}, + { 25, 122, 3, 3}, + { 14, 82, 4, 4}, + { 50, 16, 4, 4}, + { 38, 49, 4, 3}, + { 4, 6, 3, 3}, + { 7, 38, 3, 3}, + }, + }, + /* 49 */ + { + 0, 38, 67, + &beam, 32, &beam, 8, + 6,{ + {&enemy2, 10, 5}, + {&bomb1, 50, 5}, + {&enemy1, 20, 5}, + {&enemy2, 10, 5}, + {&enemy_m1, 1, 5}, + {&enemy1, 20, 5}, + }, + 22,{ + { 28, 104, 10, 6}, + { 43, 28, 12, 7}, + { 22, 72, 7, 10}, + { 11, 16, 8, 6}, + { 50, 102, 8, 4}, + { 12, 40, 5, 6}, + { 49, 80, 11, 5}, + { 6, 95, 4, 13}, + { 51, 61, 6, 10}, + { 30, 14, 4, 4}, + { 17, 118, 6, 6}, + { 34, 52, 6, 7}, + { 40, 119, 15, 6}, + { 31, 91, 15, 4}, + { 53, 10, 8, 9}, + { 8, 61, 4, 7}, + { 7, 28, 5, 4}, + { 58, 92, 4, 4}, + { 19, 55, 5, 5}, + { 25, 29, 4, 5}, + { 58, 44, 4, 4}, + { 9, 76, 4, 4}, + }, + }, + /* 50 */ + { + 0, 32, 120, + &beam, 8, &enemy1, 8, + 1,{ + {&bomb2, 80, 5}, + }, + 1,{ + {32, 60, 30, 45}, + }, + }, + { + /******************* dummy *************************/ + -1, 0, 0, + &enemy1, 0, &enemy1, 0, + 0,{ + {&enemy1, 0, 0}, + }, + 0,{ + {0, 0, 0, 0}, + }, + }, +}; diff --git a/scenes.h b/scenes.h new file mode 100644 index 0000000..d9c99a8 --- /dev/null +++ b/scenes.h @@ -0,0 +1,62 @@ + +/* + * XKOBO, a video-oriented game + * Copyright (C) 1995,1996 Akira Higuchi + * a-higuti@math.hokudai.ac.jp + * Copyright (C) 2006, 2007 David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef XKOBO_H_SCENES +#define XKOBO_H_SCENES + +#include "config.h" +#include "enemies.h" + +#define SCENE_ENEMY_MAX 20 +#define SCENE_BASE_MAX 40 + +struct enemy_set +{ + const enemy_kind *kind; + int num; + int speed; +}; + +struct _base +{ + int x, y, h, v; +}; + +struct _scene +{ + int ratio; + int startx; + int starty; + const enemy_kind *ek1; + int ek1_interval; + const enemy_kind *ek2; + int ek2_interval; + int enemy_max; + enemy_set enemy[SCENE_ENEMY_MAX]; + int base_max; + _base base[SCENE_BASE_MAX]; +}; + +extern const _scene scene[]; + +#endif // XKOBO_H_SCENES diff --git a/score.cpp b/score.cpp new file mode 100644 index 0000000..a99530d --- /dev/null +++ b/score.cpp @@ -0,0 +1,733 @@ +/* +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 1995, 1996 Akira Higuchi + * Copyright (C) 2002 Jeremy Sheeley + * Copyright (C) 2001-2003, 2007 David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define DBG(x) +#define DBG2(x) +#define DBG3(x) + +#include +#include +#include +#include +#include +#include + +#if HAVE_DIRENT_H +# include +# define NAMLEN(dirent) strlen((dirent)->d_name) +#else +# define dirent direct +# define NAMLEN(dirent) (dirent)->d_namlen +# if HAVE_SYS_NDIR_H +# include +# endif +# if HAVE_SYS_DIR_H +# include +# endif +# if HAVE_NDIR_H +# include +# endif +#endif + +#if !defined(WIN32) && !defined(MACOS) +#include +#endif + +#include "kobolog.h" +#include "kobo.h" +#include "score.h" + +score_manager_t scorefile; + + +/*---------------------------------------------------------- + s_hiscore_t +----------------------------------------------------------*/ + +s_hiscore_t::s_hiscore_t() +{ + profile = NULL; + name[0] = 0; + clear(); +} + +void s_hiscore_t::clear() +{ + start_date = 0; + end_date = 0; + skill = -1; + score = 0; + start_scene = -1; + end_scene = -1; + end_lives = -1; + end_health = -1; + playtime = 0; + saves = loads = -1; + gametype = -1; +} + +void s_hiscore_t::read(pfile_t &pf) +{ + pf.read(start_date); + pf.read(end_date); + pf.read(skill); + pf.read(score); + pf.read(start_scene); + pf.read(end_scene); + pf.read(end_lives); + pf.read(end_health); + pf.read(playtime); + pf.read(saves); + pf.read(loads); + pf.read(gametype); +#if 0 + log_printf(DLOG, "--------\n"); + log_printf(DLOG, " start_date: %u\n", start_date); + log_printf(DLOG, " end_date: %u\n", end_date); + log_printf(DLOG, " skill: %d\n", skill); + log_printf(DLOG, " gametype: %d\n", gametype); + log_printf(DLOG, " score: %u\n", score); + log_printf(DLOG, " start_scene: %d\n", start_scene); + log_printf(DLOG, " end_scene: %d\n", end_scene); + log_printf(DLOG, " end_lives: %d\n", end_lives); + log_printf(DLOG, " end_health: %d\n", end_health); + log_printf(DLOG, " playtime: %u\n", playtime); + log_printf(DLOG, " saves: %d\n", saves); + log_printf(DLOG, " loads: %d\n", loads); + log_printf(DLOG, "--------\n"); +#endif +} + +void s_hiscore_t::write(pfile_t &pf) +{ + pf.write(start_date); + pf.write(end_date); + pf.write(skill); + pf.write(score); + pf.write(start_scene); + pf.write(end_scene); + pf.write(end_lives); + pf.write(end_health); + pf.write(playtime); + pf.write(saves); + pf.write(loads); + pf.write(gametype); +} + + +/*---------------------------------------------------------- + s_profile_t +----------------------------------------------------------*/ + +s_profile_t::s_profile_t() +{ + for(int i = 0; i < HISCORE_SAVE_MAX; ++i) + hiscoretab[i].profile = this; + filename = NULL; +} + +s_profile_t::~s_profile_t() +{ + free(filename); +} + +void s_profile_t::clear() +{ + best_score = 0; + last_scene = 0; + name[0] = 0; + version = 0; + skill = SKILL_CLASSIC; + handicap = 0; + color1 = -1; + color2 = -1; + hiscores = 0; + for(int i = 0; i < HISCORE_SAVE_MAX; ++i) + hiscoretab[i].clear(); +} + +int s_profile_t::load(const char *fn) +{ + log_printf(D3LOG, "s_profile_t::load('%s')\n", fn); + + free(filename); + filename = strdup(fn); + + FILE *f = fopen(filename, "rb"); + if(!f) + { + log_printf(ELOG, "Failed to open player profile '%s'!\n", fn); + return -1; + } + + pfile_t pf(f); + + clear(); + + // Check if this is an old broken 73 byte file written by a + // previous version for Win32. If it is, skip the first byte. + fseek(f, 0, SEEK_END); + if(ftell(f) == 73) + { + log_printf(ELOG, "Broken score file '%s' detected and fixed.\n", fn); + fseek(f, 1, SEEK_SET); + } + else + fseek(f, 0, SEEK_SET); + + pf.read(best_score); + pf.read(last_scene); + pf.read(name, sizeof(name)); + log_printf(DLOG, "name: %s\n", name); + log_printf(DLOG, " best_score: %u\n", best_score); + log_printf(DLOG, " last_scene: %u\n", last_scene); + pf.buffer_close(); + + if(pf.status() < 0) + { + log_printf(ELOG, "Error reading player profile '%s'!\n", fn); + fclose(f); + return -1; + } + + //Kobo Deluxe profile file format 1+ + int chunks = 0; + while(!feof(f)) + { + if(pf.chunk_read() < 0) + { + pf.status(); // Just EOF - no big deal... + break; + } + switch(pf.chunk_type()) + { + case MAKE_4CC('P', 'R', 'O', 'F'): + log_printf(D2LOG, "Chunk 'PROF'; %d bytes.\n", + pf.chunk_size()); + if(pf.chunk_size() >= 20) + { + pf.read(version); + pf.read(skill); + pf.read(handicap); + pf.read(color1); + pf.read(color2); + } + else + { + log_printf(WLOG, "WARNING: Truncated 'PROF' chunk" + " in player profile '%s'!\n", fn); + } + break; + case MAKE_4CC('H', 'I', 'S', 'C'): + log_printf(D2LOG, "Chunk 'HISC'; %d bytes.\n", + pf.chunk_size()); + if(hiscores < HISCORE_SAVE_MAX) + hiscoretab[hiscores++].read(pf); + break; + default: + { + char tp[5]; + int t = pf.chunk_type(); + tp[0] = (t >> 24) & 0xff; + tp[1] = (t >> 16) & 0xff; + tp[2] = (t >> 8) & 0xff; + tp[3] = t & 0xff; + tp[4] = 0; + log_printf(D2LOG, "Unknown chunk '%s'; %d bytes.\n", + tp, pf.chunk_size()); + } + break; + } + ++chunks; + pf.chunk_end(); + } + + if(!chunks) + { + log_printf(D2LOG, "Old scorefile.\n"); + //Construct a "fake" highscore entry from the old data. + hiscores = 1; + hiscoretab[0].skill = SKILL_CLASSIC; //Can't tell speed. + hiscoretab[0].gametype = GAME_SINGLE; //No others available. + hiscoretab[0].score = best_score; + hiscoretab[0].end_scene = last_scene; //Likely, but... + hiscoretab[0].saves = 0; //Not implemented. + hiscoretab[0].loads = 0; //Not implemented. + } + + fclose(f); + return pf.status(); +} + + +int s_profile_t::save() +{ + log_printf(D3LOG, "s_profile_t::save('%s')\n", filename); +#ifndef WIN32 + umask(022); +#endif + if(!filename) + { + log_printf(ELOG, "Failed to save player profile - no file name!\n"); + return -1; + } + +//The "safe list"; platforms that do not have symlinks: +#if !defined(WIN32) +#ifdef HAVE_STAT + // We will not write score files via symlinks! + struct stat statbuf; + if(lstat(filename, &statbuf) < 0) + { + log_printf(ELOG, "Cannot stat player profile '%s'! " + "Could be a symlink - will NOT write.\n", + filename); + return -1; + } + if( (statbuf.st_mode & S_IFLNK) == S_IFLNK ) + { + log_printf(ELOG, "Player profile '%s' is a symlink! " + "I will NOT write through symlinks.\n", + filename); + return -1; + } +#else +#warning ================= SECURITY HAZARD ================= +#warning If this platform has symlinks or similar, please +#warning add an appropriate test. If not, add your platform +#warning to the "safe list". Either way, if you read this, +#warning post a bug report to the Kobo Deluxe maintainer. +#warning ================= SECURITY HAZARD ================= +#error (Remove this line to compile anyway.) +#endif /* HAVE_STAT */ +#endif /* "Safe list" */ + + FILE *f = fopen(filename, "wb"); + if(!f) + { + log_printf(ELOG, "Failed to create player profile '%s'!\n", + filename); + return -1; + } + + fseek(f, 0, SEEK_SET); + + pfile_t pf(f); + + // Write old XKobo stuff + pf.write(best_score); + pf.write(last_scene); + pf.write(name, sizeof(name)); + pf.buffer_write(); + + // Write profile header + if(pf.chunk_write(MAKE_4CC('P', 'R', 'O', 'F')) < 0) + { + fclose(f); + return pf.status(); + } + pf.write((unsigned int)PROFILE_VERSION); + pf.write(skill); + pf.write(handicap); + pf.write(color1); + pf.write(color2); + pf.chunk_end(); + + // Write highscores + for(unsigned int i = 0; i < hiscores; ++i) + { + if(pf.chunk_write(MAKE_4CC('H', 'I', 'S', 'C')) < 0) + { + fclose(f); + return pf.status(); + } + hiscoretab[i].write(pf); + pf.chunk_end(); + } + + fclose(f); + return pf.status(); +} + + +s_hiscore_t *s_profile_t::best_hiscore() +{ + if(!hiscores) + return NULL; + + s_hiscore_t *hs = hiscoretab; + for(unsigned int i = 1; i < hiscores; ++i) + if(hiscoretab[i].score > hs->score) + hs = hiscoretab + i; + + return hs; +} + + +/*---------------------------------------------------------- + score_manager_t +----------------------------------------------------------*/ + +score_manager_t::score_manager_t() +{ +} + + +score_manager_t::~score_manager_t() +{ +} + + +void score_manager_t::init() +{ + const char *p; + + // The logic to this is: + // 1. Check to see if they have an old score file. + // If they do, rename it to follow the new naming format + // which is X.UID. On Win32 (which doesn't have a UID), the + // UID is set to 42. + // 2. Load all of the X.UID scores into our array. + // 3. Determine what the last used file was. + + // Change as of 0.4-pre7: "score files" are upgraded + // to "player profile files", which contain IFF style + // chunks beyond the 74 XKobo compatible bytes. + +#ifdef WIN32 +/* +FIXME: This should be properly implemented on Windoze - if we +FIXME: decide that it's actually much point. (Users, security etc +FIXME: are rather foreign matters to the average winuser...) +*/ + int nUID = 42; +#else + uid_t nUID = getuid(); +#endif + // Now load all of the files. Start with trying to get the old + // file name first. That file's information will become games[0], + // and then the old file name will be deleted. + + int numberSaveGamesFound = 0; + for(int i = 0; i < MAX_PROFILES; i++) + profiles[i].clear(); + + char buf[1024]; + snprintf(buf, sizeof(buf), "SCORES>>%u", nUID); + p = fmap->get(buf); + if(p) + { + if(profiles[numberSaveGamesFound].load(p) < 0) + log_printf(WLOG, "WARNING: Can't read score file!\n"); + else + { + numberSaveGamesFound = 1; + log_printf(ULOG, "Old score file \"%s\" found" + " and imported.\n", p); + } + } + + // Search through all registered score directories + // for all of the files that end in .UID + struct stat st_buffer; + fmap->get_all("SCORES>>", FM_DIR); + char UIDbuf[12]; + snprintf(UIDbuf, sizeof(UIDbuf), ".%u", nUID); + while(1) + { + const char *path = fmap->get_next(); + if(!path) + break; + + // if the last characters in the file name is the string + // UIDbuf... + char *tmpptr = strstr((char *)path, UIDbuf); + if(tmpptr != NULL && (*(tmpptr + strlen(UIDbuf)) == '\0')) + { + if(stat(path, &st_buffer)) + continue; + if(!S_ISREG(st_buffer.st_mode)) + continue; + + if(profiles[numberSaveGamesFound].load(path) < 0) + continue; + + if((++numberSaveGamesFound) >= MAX_PROFILES) + break; + } + } + + numProfiles = numberSaveGamesFound; + + // If there are no save files, introbase in states.cpp will take + // them to the enter_name screen. + + gather_high_scores(); + print_high_scores(); +} + + +int score_manager_t::addPlayer(const char *name) +{ + log_printf(D3LOG, "creating profile %d\n", numProfiles); + if(numProfiles == MAX_PROFILES) + return -1; + int ret = 0; +#ifdef WIN32 + int userid = 42; +#else + uid_t userid = getuid(); +#endif + profiles[numProfiles].clear(); + strncpy(profiles[numProfiles].name, name, SCORE_NAME_LEN); + +// TODO: Somewhere around here would be a nice place to check if the +// TODO: scoredir exists, and if not, try to create one. + + // This means that we always create new profiles in the first + // scoredir registered. (Loaded score files are written back + // where they were read from when changed.) + char buf[1024]; + snprintf(buf, sizeof(buf), "SCORES>>%s.%u", name, userid); + const char *fn = fmap->get(buf, FM_FILE_CREATE); + free(profiles[numProfiles].filename); + if(fn) + profiles[numProfiles].filename = strdup(fn); + else + { + profiles[numProfiles].filename = NULL; + log_printf(ELOG, "ERROR: Couldn't resolve player profile" + " path '%s'!\n", buf); + ret = -2; + } + + log_printf(ULOG, "Created new player profile '%s' for player '%s'\n", + fn ? fn : "", profiles[numProfiles].name); + currentProfile = numProfiles; + + // Try to create the high score file. + if(profiles[numProfiles].save() < 0) + ret = -3; + + numProfiles++; + return ret; +} + + +void score_manager_t::select_profile(int prof) +{ + log_printf(D3LOG, "score_manager_t::select_profile(%d)\n", prof); + currentProfile = prof; +} + + +// Rules: +// * Highest score gets highest priority. +// * If the maximum number of entries is +// exceeded, the lowest score entry is +// overwritten. +// * best_score and last_scene of the +// profile are bumped if exceeded. +void score_manager_t::record(s_hiscore_t *entry, int force) +{ + log_printf(D3LOG, "score_manager_t::record\n"); + s_profile_t *p = profiles + currentProfile; + int write; + if(force) + write = 1; + else + write = 0; + + if(entry->score > p->best_score) + { + p->best_score = entry->score; + write = 1; + } + + if(entry->end_scene > p->last_scene) + { + p->last_scene = entry->end_scene; + write = 1; + } + + int si = -1; + if(p->hiscores < HISCORE_SAVE_MAX) + { + // Grab next free slot + si = p->hiscores++; + } + else + { + // Find worst score +//FIXME: Pick old or new when scores are equal? + unsigned int worst_score = entry->score; + for(int i = 0; i < HISCORE_SAVE_MAX; ++i) + if(p->hiscoretab[i].score <= worst_score) + { + si = i; + worst_score = p->hiscoretab[i].score; + } + } + if(si >= 0) + { + // Copy and "fix" entry... + log_printf(DLOG, "Saving in slot %d.\n", si); + p->hiscoretab[si] = *entry; + p->hiscoretab[si].profile = p; + memcpy(p->hiscoretab[si].name, p->name, SCORE_NAME_LEN); + write = 1; + } + else + log_printf(DLOG, "Not saved.\n"); + + if(write) + { + log_printf(DLOG, "Writing file %s for player %s...\n", + p->filename, p->name); + p->save(); + gather_high_scores(); + print_high_scores(); + log_printf(DLOG, " Done!\n"); + } +} + + +int s_table_cmp(const void *_a, const void *_b) +{ + s_hiscore_t *a = (s_hiscore_t *)_a; + s_hiscore_t *b = (s_hiscore_t *)_b; +#if 0 + if(a->gametype < b->gametype) + return 1; + else if(a->gametype > b->gametype) + return -1; + else +#endif + if(a->score < b->score) + return 1; + else if(a->score > b->score) + return -1; + return 0; +} + + +void score_manager_t::gather_high_scores(int placeholders) +{ + const int sc[] = { + 10000, 9000, 8000, 7000, 6000, + 5000, 4000, 3000, 2000, 1000, + 0 + }; + const int st[] = { + 10, 9, 8, 7, 6, + 5, 4, 3, 2, 1 + }; + const char *nm[] = { + "DAVID OLOFSON", + "AKIRA HIGUCHI", + "MASANAO IZUMO", + "MAX HORN", + "SAMUEL HART", + "ANDREAS", + "TRICK", + "RIKI", + "GEORGIE", + "JEREMY" + }; + + for(int i = 0; i < MAX_HIGHSCORES; ++i) + high_tbl[i].clear(); + + s_profile_t p; + highs = 0; + fmap->get_all("SCORES>>", FM_DIR); + while(highs < MAX_HIGHSCORES) + { + const char *path = fmap->get_next(); + if(!path) + break; + + if(p.load(path) < 0) + continue; + + s_hiscore_t *hs = p.best_hiscore(); + if(!hs) + continue; + + high_tbl[highs] = *hs; + memcpy(high_tbl[highs].name, p.name, SCORE_NAME_LEN); + high_tbl[highs].profile = NULL; + ++highs; + } + + if(placeholders) + { + //Throw some nice looking names in, if there's room. ;-) + int i = 0; + while(highs < MAX_HIGHSCORES) + { + if(!sc[i]) + break; + memcpy(high_tbl[highs].name, nm[i], SCORE_NAME_LEN); + high_tbl[highs].skill = SKILL_CLASSIC; + high_tbl[highs].gametype = GAME_SINGLE; + high_tbl[highs].score = sc[i]; + high_tbl[highs].start_scene = 0; + high_tbl[highs].end_scene = st[i]; + ++i; + ++highs; + } + } + + qsort(high_tbl, highs, sizeof(high_tbl[0]), s_table_cmp); +} + + +int score_manager_t::highscore(int prof) +{ + if(-1 == prof) + return profiles[currentProfile].last_scene; + else if(-2 == prof) + return high_tbl[0].score; + else + return profiles[prof].best_score; +} + + +void score_manager_t::print_high_scores() +{ + if(!highs) + { + log_printf(WLOG, "No hiscore entries found!\n"); + return; + } + + log_printf(ULOG, "Name Score Start End\n"); + for(unsigned int j = 0; j < highs; j++) + { + log_printf(ULOG, "%-20s %9u %5d %3d\n", high_tbl[j].name, + high_tbl[j].score, + high_tbl[j].start_scene, + high_tbl[j].end_scene); + } +} diff --git a/score.h b/score.h new file mode 100644 index 0000000..a4ea228 --- /dev/null +++ b/score.h @@ -0,0 +1,220 @@ +/* +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 1995, 1996 Akira Higuchi + * Copyright (C) 2001, 2002 David Olofson + * Copyright (C) 2002 Jeremy Sheeley + * Copyright (C) 2007 David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _KOBO_SCORE_H_ +#define _KOBO_SCORE_H_ + +#include "config.h" +#include "game.h" +#include "pfile.h" + +#define MAX_PROFILES 100 +#define MAX_HIGHSCORES 100 +#define HISCORE_SAVE_MAX 100 + +#define PROFILE_VERSION 1 + +//DO NOT CHANGE! (Will break the file format.) +#define SCORE_NAME_LEN 64 + + +/*---------------------------------------------------------- + s_*_t - Profile and score data wrappers +----------------------------------------------------------*/ +// File format: +// * The first 74 bytes are identical to those in old +// XKobo score files, for compatibility reasons. +// +// * New sections are added in the form of RIFF style +// chunks, starting at offset 74 in the file. (See +// pfile.(h|cpp) for details.) +// +// * Chunks of unknown types are IGNORED, and are +// therefore LOST if the file is overwritten by an +// older version of Kobo Deluxe. +// +// * Extra data beyond the end of a chunk (ie data that +// is added by a later version of Kobo Deluxe) is +// IGNORED, and is therefore LOST if the file is +// overwritten by an older version of Kobo Deluxe. +// +// * New versions may ADD data to chunks, but never +// remove data from chunks. +// +// * New versions may add new chunk types. +// +// * New versions may remove old chunk types, although +// this is STRONGLY DISCOURAGED, as it may render +// old Kobo Deluxe versions seeing a vertually empty +// profile file... +// +// * Strings are stored as fixed length, null padded +// arrays of 64 bytes. All strings should have at +// least one terminating null byte. +// +// * Signed and unsigned int are stored as little +// endian 32 bit integers. +// +// Version 1 chunks: +// +// PROF: //Player profile header +// Sint32 version; +// Sint32 skill; +// Sint32 handicap; +// Sint32 color1; +// Sint32 color2; +// +// HISC: //Hiscore entry +// Uint32 start_date; +// Uint32 end_date; +// Sint32 skill; +// Uint32 score; +// Sint32 start_scene; +// Sint32 end_scene; +// Sint32 end_lives; +// Sint32 end_health; +// Uint32 playtime; +// Sint32 saves; +// Sint32 loads; +// Sint32 gametype; +// + +struct s_profile_t; + +// Stored as one "HISC" chunk for each entry. +// No "real" maximum number of entries per profile, +// but the current implementation uses an array of +// HISCORE_SAVE_MAX entries. +// FIXME: Should be dynamic, although there should +// FIXME: probably be some sensible limit regardless. +struct s_hiscore_t +{ + // For all of the below, -1 (signed) or 0 (unsigned) means "unknown". + unsigned int start_date; //Seconds since 2000...? + unsigned int end_date; //Seconds since 2000...? + int skill; //Skill setting used + int gametype; //Single/cooperative/deathmatch/... + unsigned int score; //Score achieved + int start_scene; //Scene player started on + int end_scene; //Scene player quit or died on + int end_lives; //# of lives when player quit + int end_health; //Health when player quit + unsigned int playtime; //Effective play time, logic frames + int saves; //# of times game was saved + int loads; //# of times game was aborted + loaded + + // The fields below this line are not saved to file. + s_profile_t *profile; //Profile this entry belongs to, + //if any. (May be NULL!) + char name[SCORE_NAME_LEN]; //(Kludge for highscore table.) + + s_hiscore_t(); + void clear(); //Reset and clear all fields. + void read(pfile_t &f); //Read this struct from pfile 'f'. + void write(pfile_t &f); //Write this struct to pfile 'f'. +}; + +// Stored as one "PROF" chunk. +struct s_profile_t +{ + //Old stuff (from XKobo) + unsigned int best_score; //Best score + int last_scene; //Last scene completed + char name[SCORE_NAME_LEN]; //Player name + + //New stuff (for Kobo Deluxe 0.4) + unsigned int version; //Profile file format version + int skill; //Player skill setting + int handicap; //Player handicap. 0 == none. + int color1; //Primary color. (-1 == default) + int color2; //Secondary color. (-1 == default) + + s_hiscore_t hiscoretab[HISCORE_SAVE_MAX]; + + // The fields below this line are not saved to file. + unsigned int hiscores; //# of hiscores stored + char *filename; + + s_profile_t(); + ~s_profile_t(); + void clear(); //Reset and clear all fields. + int load(const char *fn); //Load from file 'fn'. + int save(); //Save back to file. + + s_hiscore_t *best_hiscore(); +}; + + +/*---------------------------------------------------------- + score_manager_t +----------------------------------------------------------*/ + +class score_manager_t +{ + s_profile_t profiles[MAX_PROFILES]; + unsigned int currentProfile; + public: + unsigned int highs; + s_hiscore_t high_tbl[MAX_HIGHSCORES]; + + int numProfiles; + score_manager_t(); + ~score_manager_t(); + int addPlayer(const char *name); + void init(); + s_profile_t *profile(int prof = -1) + { + if(prof < 0) + return profiles + currentProfile; + else + return profiles + prof; + } + // NOTE: hiscore() with no argument (or -2) returns + // the best known score of all found profiles; NOT + // that of the current profile. + int highscore(int prof = -2); + int last_scene(int prof = -1) + { + if(prof < 0) + return profiles[currentProfile].last_scene; + else + return profiles[prof].last_scene; + } + char *name(int prof = -1) + { + if(prof < 0) + return profiles[currentProfile].name; + else + return profiles[prof].name; + } + void select_profile(int prof); + int current_profile() { return currentProfile; } + void record(s_hiscore_t *entry, int force = 0); + void gather_high_scores(int placeholders = 0); + void print_high_scores(); +}; + +extern score_manager_t scorefile; + +#endif //_KOBO_SCORE_H_ diff --git a/screen.cpp b/screen.cpp new file mode 100644 index 0000000..e16243a --- /dev/null +++ b/screen.cpp @@ -0,0 +1,1042 @@ +/*(GPL) +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 1995, 1996, Akira Higuchi + * Copyright (C) 2001-2003, 2005, 2007 David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#ifndef M_PI +# define M_PI 3.14159265358979323846 /* pi */ +#endif + +#include "kobo.h" +#include "screen.h" +#include "manage.h" +#include "options.h" +#include "enemies.h" +#include "myship.h" +#include "radar.h" +#include "scenes.h" +#include "config.h" +#include "random.h" +#include "version.h" + +int _screen::scene_max; +int _screen::scene_num; +int _screen::level; +int _screen::generate_count; +_map _screen::map; +int _screen::show_title = 0; +int _screen::do_noise = 0; +float _screen::_fps = 40; +float _screen::scroller_speed = SCROLLER_SPEED; +float _screen::target_speed = SCROLLER_SPEED; +int _screen::noise_y = 0; +int _screen::noise_h = WSIZE; +int _screen::noise_source = B_NOISE; +float _screen::noise_fade = 0.0f; +float _screen::noise_bright = 0.0f; +float _screen::noise_depth = 0.0f; +int _screen::highlight_y = WSIZE / 2; +int _screen::highlight_h = 0; +int _screen::hi_sc[10]; +int _screen::hi_st[10]; +char _screen::hi_nm[10][20]; +int _screen::nstars = 0; +KOBO_Star *_screen::stars = NULL; +Uint32 _screen::starcolors[STAR_COLORS]; +int _screen::star_oxo = 0; +int _screen::star_oyo = 0; +radar_modes_t _screen::radar_mode = RM_OFF; + + +_screen::~_screen() +{ + free(stars); +} + + +void _screen::init() +{ + scene_max = 0; + while(scene[scene_max].ratio != -1) + scene_max++; +} + + +void _screen::render_title_plasma(int t, float fade, int y, int h) +{ + s_sprite_t *s = gengine->get_sprite(B_FOCUSFX, 0); + if(!s || !s->surface) + return; + SDL_Surface *fx = s->surface; + SDL_Rect sr; + sr.x = 0; + sr.w = fx->w; + sr.h = 1; + for(int ty = 0; ty < h; ++ty) + { + float sy = (float)ty / (h - 1); + float shape = sin(M_PI * sy); + float plasma = 0.5f + 0.5f * sin(t * 0.004f + + sin(t * 0.00017f) * sy * 18.0f); + float plasma2 = 0.5f + 0.5f * sin(t * 0.001f + + sin(t * 0.00013f) * sy * 12.0f); + int i = (int)((fx->h - 1) * (0.3f * plasma + 0.7f * shape) * fade); + int xo = (int)(8192 * plasma2 * gengine->xscale() / 256); + xo -= (int)(xo / fx->w) * fx->w; + int xmax = wmain->phys_rect.x + wmain->phys_rect.w; + for(int x = -xo; x < xmax; x += fx->w) + { + sr.y = i; + RGN_Blit(fx, &sr, x, y + ty); + } + } +} + + +void _screen::render_title_noise(float fade, int y, int h, int bank, int frame) +{ + for(int ty = 0; ty < h; ) + { + int xo = (int)(pubrand.get(16) * gengine->xscale()) / 256; + s_sprite_t *s = gengine->get_sprite(bank, pubrand.get(4)); + if(!s || !s->surface) + continue; + SDL_Surface *fx = s->surface; + xo -= (int)(xo / fx->w) * fx->w; + int xmax = wmain->phys_rect.x + wmain->phys_rect.w; + for(int x = -xo; x < xmax; x += fx->w) + RGN_Blit(fx, NULL, x, y + ty); + ty += fx->h; + } +} + + +static int flashin(int t) +{ + if(t < 0) + return 1; + else if(t > 800) + return 0; + else + return (t % 200) > 100; +} + + +void _screen::title(int t, float fade, int mode) +{ + // Enclosed effect + s_sprite_t *s = gengine->get_sprite(B_LOGO, 0); + if(!s || !s->surface) + return; + float mf = (1.0f - fade); + int h = s->surface->h; + int y0 = wmain->phys_rect.y + (int)(60 * gengine->yscale() + 0.5f); + int y = (int)(y0 - mf * mf * mf * (y0 + h) + 0.5f); + wmain->select(); + RGN_Target(gengine->surface()); + RGN_SetRegion(logo_region, + wmain->phys_rect.x + + (int)((wmain->width() - 206) / 2 * gengine->xscale()), + y); + switch(mode) + { + case 0: + render_title_plasma(t, fade, y, h); + break; + case 1: + render_title_noise(fade, y, h, (int)B_NOISE, 0); + break; + case 2: + render_title_noise(fade, y, h, (int)B_HITNOISE, 0); + break; + } + + // Outline + wmain->sprite_fxp(PIXEL2CS((wmain->width() - 206) / 2), + (int)((y * 256 + 255) / gengine->yscale()) - + PIXEL2CS(wmain->y()), + B_LOGO, 0); + + // "DELUXE" + wmain->sprite_fxp(PIXEL2CS((wmain->width() - 139) / 2), + PIXEL2CS(123) + (int)(PIXEL2CS(160) * mf * mf), + B_LOGODELUXE, 0); + + // Version + if(fade > 0.9) + { + wmain->font(B_NORMAL_FONT); + wmain->center(132, KOBO_VERSION); + } + + // Cheat mode warning + if((prefs->cmd_cheat || prefs->cmd_pushmove) && (t % 1000 < 500)) + { + wmain->font(B_MEDIUM_FONT); + wmain->center(145, "CHEAT MODE"); + } +#if 1 + // WIP notice + if(!flashin(t - 2000)) + { + wmain->font(B_MEDIUM_FONT); + wmain->center(170, "This is a Work in Progress!"); + wmain->center(180, "Check http://olofson.net/kobodl"); + } +#endif +} + + +void _screen::init_highscores() +{ + for(unsigned int i = 0; i < 10; ++i) + if(i < scorefile.highs) + { + hi_sc[i] = scorefile.high_tbl[i].score; + hi_st[i] = scorefile.high_tbl[i].end_scene; + strncpy(hi_nm[i], scorefile.high_tbl[i].name, 19); + hi_nm[i][19] = 0; + } + else + { + hi_sc[i] = 0; + hi_st[i] = 0; + strcpy(hi_nm[i], "---"); + } + +} + + +void _screen::highscores(int t, float fade) +{ + int i, y; + float mf = (1.0f - fade); + mf *= mf * mf * mf * mf; + screen.set_highlight(0, 0); + + wmain->font(B_BIG_FONT); + y = (int)(PIXEL2CS(100) * mf) - 256; + if(y < 0) + y = 0; + wmain->center_fxp(PIXEL2CS(20) - y, "HALL OF FAME"); + int xo = (int)(50 * 256 * mf); + wmain->sprite_fxp(PIXEL2CS(32) - xo, PIXEL2CS(30), + B_PLAYER, (t / 50) % 16); + wmain->sprite_fxp(PIXEL2CS(wmain->width() - 32) + xo, PIXEL2CS(30), + B_PLAYER, 15 - (t / 50) % 16); + + wmain->font(B_NORMAL_FONT); + y = (int)(PIXEL2CS(75) * mf - 0.5f) - 256; + if(y < 0) + y = 0; + wmain->center_fxp(PIXEL2CS(40) - y, "(Score/Stage/Name)"); + + wmain->font(B_MEDIUM_FONT); + float yo = t * (11*18+100) * 256.0 / 12500.0 - PIXEL2CS(110); + for(i = 0, y = 65; i < 10; ++i, y += 18) + { + static char s[20]; + float xo, cy; + int real_y = PIXEL2CS(y) - (int)yo; + if(real_y < PIXEL2CS(55) || real_y > PIXEL2CS(165)) + continue; + cy = (PIXEL2CS(y) - yo) - PIXEL2CS(65 + 5*18/2); + xo = cy*cy*cy*cy*cy * 1e-16; + snprintf(s, 16, "%d", hi_sc[i]); + wmain->center_token_fxp(PIXEL2CS(70)+(int)xo, real_y, s); + snprintf(s, 16, "%d", hi_st[i]); + wmain->center_token_fxp(PIXEL2CS((70+125)/2)+(int)xo, real_y, s, -1); + wmain->string_fxp(PIXEL2CS(125)+(int)xo, real_y, hi_nm[i]); + } +#if 1 + if(!flashin(t - 1000)) + { + wmain->font(B_MEDIUM_FONT); + wmain->center(170, "NOTE: Highscores for \"Classic\" only!"); + wmain->center(180, "The new skill levels are experimental."); + } +#endif +} + + +void _screen::credits(int t) +{ + if((t % 4000 < 3600) && (t / 4000 <= 2)) + screen.set_highlight(102, 70); + else + screen.set_highlight(0, 0); + int t2 = 10 * (t % 4000) / 3700; + if(t % 4000 < 3700) + switch(t / 4000) + { + case 0: + wmain->font(B_BIG_FONT); + if(t2 > 0) + wmain->center(80, "DAVID OLOFSON"); + wmain->font(B_NORMAL_FONT); + if(t2 > 2) + wmain->center(105, "New SDL Audio & GFX Engines"); + if(t2 > 3) + wmain->center(115, "New Graphics, Sound & Music"); + break; + case 1: + wmain->font(B_BIG_FONT); + if(t2 > 0) + wmain->center(80, "AKIRA HIGUCHI"); + wmain->font(B_NORMAL_FONT); + if(t2 > 2) + wmain->center(110, "XKobo - The Original Game"); + break; + case 2: + wmain->font(B_BIG_FONT); + if(t2 > 0) + wmain->center(80, "MASANAO IZUMO"); + wmain->font(B_NORMAL_FONT); + if(t2 > 2) + wmain->center(105, "Original Sounds"); + if(t2 > 3) + wmain->center(115, "Original Sound Engine"); + break; + } + if(!flashin(t - 11000)) + { + wmain->font(B_MEDIUM_FONT); + wmain->center(170, "Additional Credits & Thanks"); + wmain->center(180, "in the scroller below"); + } +} + + +void _screen::help(int t) +{ + wmain->font(B_BIG_FONT); + wmain->center(53, "HOW TO PLAY"); + + // 0..3000: Control + if(t < 200) + screen.set_highlight(112, 80); + else if(t < 2800) + { + if(t > 2700) + screen.set_highlight(0, 0); + wmain->font(B_MEDIUM_FONT); + wmain->sprite(wmain->width() / 2, 105, B_PLAYER, (t / 50) % 16); + wmain->center(125, "Use arrow keys or NumPad."); + wmain->center(135, "to control the ship."); + } + else if(t < 3000) + return; + + // 3000..6000: Fire + else if(t < 3200) + screen.set_highlight(112, 80); + else if(t < 5800) + { + if(t > 5700) + screen.set_highlight(0, 0); + wmain->font(B_MEDIUM_FONT); + int i; + for(i = 0; i < 4; ++i) + { + int t2 = t + 153 * i; + wmain->sprite(wmain->width() / 2 - (t2 / 5) % 120, 105, + B_BOLT, 8 + (t2 / 50) % 4); + wmain->sprite(wmain->width() / 2 + (t2 / 5) % 120, 105, + B_BOLT, 8 + (t2 / 50) % 4); + } + wmain->sprite(wmain->width() / 2, 105, B_PLAYER, 4); + wmain->center(135, "Use any SHIFT or CONTROL keys to fire."); + } + else if(t < 6000) + return; + + // 6000..9000: Bases + else if(t < 6200) + screen.set_highlight(112, 80); + else if(t < 8800) + { + if(t > 8700) + screen.set_highlight(0, 0); + wmain->font(B_MEDIUM_FONT); +// TODO: Short demo of how to destroy a base + int i; + for(i = B_TILES1; i <= B_TILES5; ++i) + { + int xo = 24 * i - (5 * 24 / 2) + 4; + wmain->sprite(wmain->width() / 2 + xo, 105 - 8, i, 7); + } + wmain->center(135, "Destroy bases by shooting their cores."); + } + else if(t < 9000) + return; + + // 9000..14000: Shoot everything! + else if(t < 9200) + screen.set_highlight(112, 80); + else if(t < 13800) + { + if(t > 13700) + screen.set_highlight(0, 0); + wmain->font(B_MEDIUM_FONT); +// TODO: Short demo of intense battle + wmain->sprite(50, 110, B_RING, (t / 30) % 16); + wmain->sprite(65, 90, B_BOMB, (t / 40) % 16); + wmain->sprite(80, 110, B_BMR_GREEN, (t / 80) % 16); + wmain->sprite(95, 90, B_BMR_PURPLE, (t / 70) % 16); + wmain->sprite(110, 110, B_BMR_PINK, (t / 60) % 16); + wmain->sprite(125, 90, B_FIGHTER, (t / 50) % 16); + wmain->sprite(140, 110, B_MISSILE1, (t / 45) % 16); + wmain->sprite(155, 90, B_MISSILE2, (t / 40) % 16); + wmain->sprite(170, 110, B_MISSILE3, (t / 55) % 16); + wmain->center(125, "Shoot everything that moves,"); + wmain->center(135, "but avoid getting hit!"); + } + else if(t < 14000) + return; + + // 14000..20000: Indestructible + else if(t < 14200) + screen.set_highlight(112, 80); + else if(t < 19800) + { + if(t > 19700) + screen.set_highlight(0, 0); + wmain->font(B_MEDIUM_FONT); +// TODO: Demo destroying a rock in Gamer mode? + int i; + for(i = B_TILES1; i <= B_TILES5; ++i) + { + int xo = 24 * i - (5 * 24 / 2) + 4; + wmain->sprite(wmain->width() / 2 + xo, 82 - 8, i, 0); + } + wmain->center(87, "Some objects are indestructible..."); + wmain->sprite(65, 120, B_ROCK1, (t / 45) % 32); + wmain->sprite(90, 115, B_ROCK2, (t / 40) % 32); + wmain->sprite(115, 125, B_ROCK3, (t / 35) % 48); + wmain->sprite(155, 120, B_BIGSHIP, (t / 40) % 16); + wmain->center(135, "...or take many hits to destroy."); + } +} + + +void _screen::scroller() +{ + if(do_noise) + return; + + /* + * Adjust scroller speed according to + * frame rate, for readability. + */ + if(_fps < 30) + target_speed = SCROLLER_SPEED / 2; + else if(_fps > 40) + target_speed = SCROLLER_SPEED; + + scroller_speed += (target_speed - scroller_speed) * 0.05; + + static const char scrolltext[] = + "Welcome to KOBO DELUXE, an enhanced version of " + "Akira Higuchi's fabulous X-Window game XKOBO. " + " " + "KOBO DELUXE uses SDL, the Simple DirectMedia " + "Layer (www.libsdl.org) for graphics and input, " + "and Audiality (olofson.net/audiality) for sound " + "and music. " + " " + "KOBO DELUXE has been known to hinder productivity on: " + " " + " - " + "Windows 95/98/ME - " + "Windows 2000/XP - " + "Mac OS X (PPC) - " + "BeOS (x86, PPC) - " + "AmigaOS (68k, PPC) - " + "Solaris (x86, SPARC) - " + "QNX (x86) - " + "GNU/Linux (x86, x86_64, PPC, PPC64) - " + "OpenBSD (x86, PPC, SPARC, SPARC64) - " + "FreeBSD (x86) - " + "NetBSD (x86) - " + "IRIX - " + "OS/2 - " + "PlayStation 2/PS2Linux - " + "Xbox - " + "Syllable - " + "ITOS (Nokia internet tablets) - " + " " + "Any help in the Cause of Infiltrating Further " + "Platforms is Greatly Appreciated! " + " " + "Additional Credits & Thanks to: " + " Torsten Giebl (Slackware)" + " David Andersson (Some Good Ideas)" + " Samuel Hart (Joystick Support)" + " Max Horn (Mac OS X)" + " Jeremy Sheeley (Player Profiles)" + " Tsuyoshi Iguchi (FreeBSD, NetBSD)" + " G. Low (Solaris)" + " Gerry Jo \"Trick\" Jellestad (Testing & Ideas)" + " \"Riki\" (Intel Compiler)" + " Andreas Spaangberg (Sun Compiler)" + " \"SixK\" (Amiga Port)" + " Joey Hess (Debian)" + " Martijn van Oosterhout (FPS limiter)" + " Antonio Messina (Stage 1601+, Always Fire)" + " Hans de Goede (Audio bug)" + " Marianne Ibbotson (\"Autopause\")" + " Sam Palmer (Windows testing)" + " Michael Sterrett (glSDL issues)" + " Sam Lantinga & Others (SDL)" + " Members of the SDL Mailing List" + " " + "Additional Thanks from Akira Higuchi Go To: " + " Bruce Cheng" + " Christoph Lameter" + " Davide Rossi" + " Eduard Martinescu" + " Elan Feingold" + " Helmut Hoenig" + " Jeff Epler" + " Joe Ramey" + " Joey Hess" + " Michael Sterrett" + " Mihail Iotov" + " Shoichi Nakayama" + " Thomas Marsh" + " Torsten Wolnik" + " " + "And as we said in the old days... " + " " + " "; +// FIXME: Nasty static state variables... + static const char *stp = scrolltext; + static int pos = PIXEL2CS(SCREEN_WIDTH); + static int t = 0; + int nt = (int)SDL_GetTicks(); + int dt = nt - t; + t = nt; + if(dt > 100) + dt = 100; + static int fdt = 0; + fdt += ((dt<<8) - fdt) >> 3; + pos -= (fdt * PIXEL2CS((int)scroller_speed) + 128000) / 256000; + wmain->font(B_BIG_FONT); + wmain->string_fxp(pos, PIXEL2CS(200), stp); + + /* + * Chop away characters at the left edge + */ + char buf[2] = {*stp, 0}; + int cw = wmain->textwidth_fxp(buf); + if(-pos > cw) + { + pos += cw; + ++stp; + if(*stp == 0) + { + // Wrap! + pos = PIXEL2CS(SCREEN_WIDTH); + stp = scrolltext; + } + } +} + + +void _screen::init_scene(int sc) +{ + map.init(); + if(sc < 0) + { + /* + * Intro mode + */ + show_title = 1; + myship.off(); + enemies.off(); + if(sc == INTRO_SCENE) + { + /* + * Plain intro - no map + */ + radar_mode = RM_OFF; /* Clear radar */ + scene_num = 19; + level = 0; + } + else + { + /* + * Map selection - show current map + */ + radar_mode = RM_SHOW; + scene_num = -(sc+1) % scene_max; + level = -(sc+1) / scene_max; + } + } + else + { + /* + * In-game mode + */ + show_title = 0; + scene_num = sc % scene_max; + level = sc / scene_max; + radar_mode = RM_RADAR; + } + gengine->period(game.speed); + sound.period(game.speed); + + const _scene *s = &scene[scene_num]; + int i; + for(i = 0; i < s->base_max; i++) + map.make_maze(s->base[i].x, s->base[i].y, s->base[i].h, + s->base[i].v); + map.convert(s->ratio); + generate_count = 0; + wradar->mode(radar_mode); +} + + +int _screen::prepare() +{ + if(scene_num < 0) + return 0; + const _scene *s = &scene[scene_num]; + int i, j; + int count_core = 0; + int c = 0; + + int lc = level > 31 ? 31 : level; + int interval_1 = (s->ek1_interval) >> lc; + int interval_2 = (s->ek2_interval) >> lc; + if(interval_1 < 4) + interval_1 = 4; + if(interval_2 < 4) + interval_2 = 4; + enemies.set_ekind_to_generate(s->ek1, interval_1, s->ek2, + interval_2); + + wmain->clear(); + for(i = 0; i < MAP_SIZEX; i++) + for(j = 0; j < MAP_SIZEY; j++) + { + int m = MAP_BITS(map.pos(i, j)); + if(IS_SPACE(m)) + continue; + if((m == U_MASK) || (m == R_MASK) || (m == D_MASK) + || (m == L_MASK)) + { + enemies.make(&cannon, i * 16 + 8, + j * 16 + 8); + c++; + } + else if(m & CORE) + { + enemies.make(&core, i * 16 + 8, + j * 16 + 8); + count_core++; + c++; + } + } + + myship.set_position(s->startx << 4, s->starty << 4); + + return count_core; +} + + +void _screen::generate_fixed_enemies() +{ + static int sint[16] = + { 0, 12, 23, 30, 32, 30, 23, 12, 0, -12, -23, -30, + -32, -30, -23, -12 }; + static int cost[16] = + { 32, 30, 23, 12, 0, -12, -23, -30, -32, -30, -23, + -12, 0, 12, 23, 30 }; + const _scene *s = &scene[scene_num]; + if(generate_count < s->enemy_max) + { + int j; + for(j = 0; j < s->enemy[generate_count].num; j++) + { + int sp = s->enemy[generate_count].speed; + int x, y, h, v, t; + x = gamerand.get() % (WORLD_SIZEX - VIEWLIMIT * 2); + y = gamerand.get() % (WORLD_SIZEY - VIEWLIMIT * 2); + x -= (WORLD_SIZEX / 2 - VIEWLIMIT); + y -= (WORLD_SIZEY / 2 - VIEWLIMIT); + if(x < 0) + x -= VIEWLIMIT; + else + x += VIEWLIMIT; + if(y < 0) + y -= VIEWLIMIT; + else + y += VIEWLIMIT; + x += myship.get_x(); + y += myship.get_y(); + + t = gamerand.get(4); + h = PIXEL2CS(sp * sint[t]) / 64; + v = PIXEL2CS(sp * cost[t]) / 64; + enemies.make(s->enemy[generate_count].kind, x, y, + h, v); + } + generate_count++; + } + if(generate_count >= s->enemy_max) + generate_count = 0; +} + + +void _screen::set_map(int x, int y, int n) +{ + if(n == 0) + map.clearpos(x, y); + else + map.pos(x, y) = n; + wradar->update(x, y); +} + + +void _screen::render_noise(window_t *win) +{ + if(!do_noise) + return; + if(noise_fade < 0.01f) + return; + int ymax = noise_y + noise_h; + int np = pubrand.get(8); + int dnp = pubrand.get(4) - 8; + float ifade = 1.0f - noise_fade; + float step = 1.0f + ifade*ifade*ifade * 5.0f; + float rstep = (ifade + ifade*ifade*ifade * 10.0f) / 256.0f; + if(step < 1.0f) + step = 1.0f; + if(rstep < 0.0f) + rstep = 0.0f; + for(float fy = noise_y + pubrand.get(8) * rstep; fy < ymax; + fy += step + pubrand.get(8) * rstep) + { + int xo = PIXEL2CS(pubrand.get(NOISE_SIZEX_LOG2)); + int xmax = ((WSIZE + CS2PIXEL(xo)) >> NOISE_SIZEX_LOG2) + 1; + dnp += pubrand.get(3) - 4 + pubrand.get(1); + np += dnp; + if(np > 255) + np = 255, dnp = -dnp / 2; + else if(np < 0) + np = 0, dnp = -dnp / 2; + float level = np * noise_depth * (1.0f - noise_bright) / 255.0f + + noise_bright; + for(int x = 0; x < xmax; ++x) + win->sprite_fxp(PIXEL2CS(x<height() / 2; + + static float ypos = -50; + static float hf = 0; + static int ot = 0; + int t = (int)SDL_GetTicks(); + int dt = t - ot; + ot = t; + if(dt > 1000) + dt = 100; + + //Spring + friction style velocity component + if(dt < 500) + ypos += ((float)highlight_y - ypos) * (float)dt * 0.005f; + else + ypos = (float)highlight_y; + + //Constant velocity component + float v = (float)dt * 0.2f; + if((float)highlight_y - ypos > v) + ypos += v; + else if((float)highlight_y - ypos < -v) + ypos -= v; + else + ypos = (float)highlight_y; + + // Scale to new height + hf += ((float)highlight_h - hf) * (float)dt * 0.01f; + + // Render! + int y = (int)((ypos - hf / 2.0f) * 256.0f); + int h = (int)(hf * 256.0f); + if(h < 128) + return; + for(int ty = -256; ty <= h; ty += h + 256) + { + int xo = PIXEL2CS(pubrand.get(NOISE_SIZEX_LOG2)); + int xmax = ((WSIZE + CS2PIXEL(xo)) >> NOISE_SIZEX_LOG2) + 1; + for(int x = 0; x < xmax; ++x) + wmain->sprite_fxp(PIXEL2CS(x << NOISE_SIZEX_LOG2) - xo, + ty + y, + B_NOISE, 6); + } + + int x0 = win->phys_rect.x; + s_sprite_t *s = gengine->get_sprite(B_FOCUSFX, 0); + if(!s || !s->surface) + return; + SDL_Surface *fx = s->surface; + SDL_Surface *dst = gengine->surface(); + y = (int)((y * gengine->yscale() + 128) / 256) + win->phys_rect.y; + h = (int)(hf * gengine->yscale()); + win->select(); + for(int ty = 0; ty < h; ++ty) + { + float sy = (float)ty / (h - 1); + float scy = sy * hf; + float shape = 1.0f - sin(M_PI * sy); + float edges = shape * shape * shape; + float plasma = 0.5f + 0.5f * sin(t * 0.004f + + sin(t * 0.00017f) * scy * 0.18f); + float plasma2 = 0.5f + 0.5f * sin(t * .003 + + sin(t * 0.0001f) * scy * 0.12f); + int i = (int)((fx->h - 1) * ((.5f * plasma + .5f * plasma * shape) * + (1.0f - edges) + edges)); + int xo = (int)((t * 10 + 8192 * plasma2) * gengine->xscale() / 256); + xo -= (int)(xo / fx->w) * fx->w; + int xmax = (int)((WSIZE * gengine->xscale() + xo) / fx->w); + for(int x = 0; x <= xmax; ++x) + { + SDL_Rect sr, dr; + sr.x = 0; + sr.y = i; + sr.w = fx->w; + sr.h = 1; + dr.x = x0 + (int)(x * fx->w) - xo; + dr.y = y + ty; + SDL_BlitSurface(fx, &sr, dst, &dr); + } + } +} + + +void _screen::set_highlight(int y, int h) +{ + highlight_y = y; + highlight_h = h; +} + + +// This starfield implementation may seem a bit backwards. Instead of moving +// around in a 3D point cloud, projecting by dividing x and y by z etc, we're +// doing a plain orthogonal projection. That is, the z coordinates have no +// direct impact on rendering! +// What actually creates the parallax effect is that we scroll the *stars* +// around at different speeds, depending on their distance from the screen, +// which effectively replaces the usual (x/z, y/z) operation when projecting. +// The interesting part is that stars wrap around the edges automatically as +// a side effect of the integer arithmetics. Thus we can have a nice, dense +// "3D" starfield covering the whole window - no nearby stars way off screen, +// and no distant stars wrapping around in a small square in the middle of the +// screen. No clipping is needed, and thus, no cycles are wasted animating off- +// screen stars. +// Of course, this design means we cannot move along the Z axis (well, not +// trivially, at least), but we don't really need that here anyway. +// +#define WSX (WORLD_SIZEX << 8) +#define WSY (WORLD_SIZEY << 8) +void _screen::render_starfield(window_t *win, int xo, int yo) +{ + int i; + int w = win->width() * 256; + int h = win->height() * 256; + int xc = w / 2; + int yc = h / 2; + + // Calculate delta from last position, dealing with map position wrap + int dx = (xo - star_oxo) & (WSX - 1); + star_oxo = xo; + if(dx & (WSX >> 1)) + dx |= 1 - (WSX - 1); + int dy = (yo - star_oyo) & (WSY - 1); + star_oyo = yo; + if(dy & (WSY >> 1)) + dy |= 1 - (WSY - 1); + + // Scale the deltas to compensate for window/starfield size mismatch + // (Otherwise stars at zero distance won't sync up with the map as + // intended!) + dx = (dx << 16) / w; + dy = (dy << 16) / h; + + /* (Re-)initialize starfield */ + if(nstars != prefs->stars) + { + free(stars); + nstars = prefs->stars; + stars = (KOBO_Star *)malloc(nstars * sizeof(KOBO_Star)); + if(!stars) + { + nstars = 0; + return; // Out of memory!!! + } + for(i = 0; i < nstars; ++i) + { + stars[i].x = pubrand.get(); + stars[i].y = pubrand.get(); + int zz = 255 * i / nstars; + stars[i].z = 65025 - zz * zz; + } + } + + // Map colors (Should be done elsewhere, but must be re-done after + // restarting video!) + for(i = 0; i < STAR_COLORS; i += 2) + { + int c = 64 + i * (255 - 64) / STAR_COLORS; + starcolors[STAR_COLORS - i - 1] = win->map_rgb( + win->fadergb(0x6699cc, c)); + starcolors[STAR_COLORS - i - 2] = win->map_rgb( + win->fadergb(0x999966, c)); + } + + win->select(); + for(i = 0; i < nstars; ++i) + { + int z = (int)stars[i].z >> (16 - STAR_ZBITS); + + // Move stars with deltas scaled by 'z' + stars[i].x -= (dx << 8) / (z + STAR_Z0); + stars[i].y -= (dy << 8) / (z + STAR_Z0); + + // Scale and center + int x = (stars[i].x * (w >> 8) >> 8) + xc; + int y = (stars[i].y * (h >> 8) >> 8) + yc; + + // Plot! + win->foreground(starcolors[z * STAR_COLORS >> STAR_ZBITS]); + int s = 256 - (z * 128 >> STAR_ZBITS); + win->fillrect_fxp(x, y, s, s); + } +} + + +void _screen::render_background(window_t *win) +{ + if(!win) + return; + if(do_noise && (noise_fade >= 1.0f)) + return; + + int vx, vy, xo, yo, x, y, xmax, ymax; + int mx, my; + vx = gengine->xoffs(LAYER_BASES); + vy = gengine->yoffs(LAYER_BASES); + + /* + * Start exactly at the top-left corner + * of the tile visible in the top-left + * corner of the display window. + */ + xo = vx & (PIXEL2CS(CHIP_SIZEX) - 1); + yo = vy & (PIXEL2CS(CHIP_SIZEY) - 1); + mx = CS2PIXEL(vx >> CHIP_SIZEX_LOG2); + my = CS2PIXEL(vy >> CHIP_SIZEY_LOG2); + ymax = ((WSIZE+CS2PIXEL(yo)) >> CHIP_SIZEY_LOG2) + 1; + xmax = ((WSIZE+CS2PIXEL(xo)) >> CHIP_SIZEX_LOG2) + 1; + + /* + * NOTE: + * We need to clear regardless of starfield mode, as the new tiles + * use alpha/colorkey. + */ + win->clear(); + + /* Render parallax starfield, if selected */ + if(prefs->starfield == STARFIELD_PARALLAX) + render_starfield(win, vx, vy); + + int tileset = B_TILES1 + (scene_num / 10) % 5; + switch(prefs->starfield) + { + case STARFIELD_NONE: + case STARFIELD_PARALLAX: + /* Ignore star tiles */ + for(y = 0; y < ymax; ++y) + for(x = 0; x < xmax; ++x) + { + int n = map.pos(mx + x, my + y); + if(IS_SPACE(n)) + continue; + win->sprite_fxp(PIXEL2CS(x<> 8); + } + break; + case STARFIELD_OLD: + /* Draw all tiles, XKobo style */ + for(y = 0; y < ymax; ++y) + for(x = 0; x < xmax; ++x) + { + int n = map.pos(mx + x, my + y); + int b = IS_SPACE(n) ? B_OLDSTARS : tileset; + win->sprite_fxp(PIXEL2CS(x<> 8); + } + break; + } +} + + +void _screen::render_fx(window_t *win) +{ + if(!win) + return; + render_noise(win); + render_highlight(win); +} + + +void _screen::fps(float f) +{ + _fps = f; +} + + +void _screen::noise(int on) +{ + do_noise = on; +} diff --git a/screen.h b/screen.h new file mode 100644 index 0000000..0c39013 --- /dev/null +++ b/screen.h @@ -0,0 +1,105 @@ +/*(GPL) +------------------------------------------------------------ + Kobo Deluxe - An enhanced SDL port of XKobo +------------------------------------------------------------ + * Copyright (C) 1995, 1996 Akira Higuchi + * Copyright (C) 2001-2003, 2007 David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _KOBO_SCREEN_H_ +#define _KOBO_SCREEN_H_ + +#include "map.h" +#include "radar.h" + +#define STAR_COLORS 16 +#define STAR_ZBITS 10 +#define STAR_Z0 256 + +class window_t; + +struct KOBO_Star +{ + short x; + short y; + unsigned short z; +}; + +class _screen +{ + protected: + static int scene_num; + static int level; + static int generate_count; + static _map map; + static int scene_max; + static int show_title; + static int do_noise; + static float _fps; + static float scroller_speed; + static float target_speed; + static int noise_y; + static int noise_h; + static int noise_source; + static float noise_fade; + static float noise_bright; + static float noise_depth; + static int highlight_y; + static int highlight_h; + static int hi_sc[10]; + static int hi_st[10]; + static char hi_nm[10][20]; + static int nstars; + static KOBO_Star *stars; + static Uint32 starcolors[STAR_COLORS]; + static int star_oxo; + static int star_oyo; + static void render_noise(window_t *win); + static void render_highlight(window_t *win); + static void render_title_plasma(int t, float fade, int y, int h); + static void render_title_noise(float fade, int y, int h, int bank, int frame); + static void render_starfield(window_t *win, int xo, int yo); + public: + ~_screen(); + static radar_modes_t radar_mode; // Last set radar mode + static void init(); + static void init_scene(int sc); + static int prepare(); + static void generate_fixed_enemies(); + static inline int get_map(int x, int y) + { + return map.pos(x, y); + } + static void set_map(int x, int y, int n); + static void set_highlight(int y, int h); + static void set_noise(int source, float fade, float bright, float depth); + static void render_background(window_t * win); + static void render_fx(window_t * win); + static void title(int t, float fade, int mode); + static void init_highscores(); + static void highscores(int t, float fade); + static void credits(int t); + static void help(int t); + static void scroller(); + static void fps(float f); + static float fps() { return _fps; } + static void noise(int on); +}; + +extern _screen screen; + +#endif //_KOBO_SCREEN_H_ diff --git a/sound.cpp b/sound.cpp new file mode 100644 index 0000000..d6dfd43 --- /dev/null +++ b/sound.cpp @@ -0,0 +1,708 @@ +/*(GPL) +------------------------------------------------------------ + Kobo Deluxe - Wrapper for Sound Control +------------------------------------------------------------ + * Copyright (C) 2007 David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "sound.h" + +#include "kobo.h" +#include "kobolog.h" +#include "random.h" +#include "audio.h" + +int KOBO_sound::sounds_loaded = 0; +int KOBO_sound::music_loaded = 0; +int KOBO_sound::time = 0; +int KOBO_sound::_period = 30; +int KOBO_sound::sfx2d_tag = 0; +int KOBO_sound::listener_x = 0; +int KOBO_sound::listener_y = 0; +int KOBO_sound::wrap_x = 0; +int KOBO_sound::wrap_y = 0; +int KOBO_sound::scale = 65536 / 1000; +int KOBO_sound::panscale = 65536 / 700; +int KOBO_sound::firing = 0; +int KOBO_sound::overheat = 0; +unsigned KOBO_sound::rumble = 0; + + +KOBO_sound::KOBO_sound() +{ +} + + +KOBO_sound::~KOBO_sound() +{ + close(); +} + + +/*-------------------------------------------------- + Open/close +--------------------------------------------------*/ + + +int KOBO_sound::load(int (*prog)(const char *msg), int force) +{ + int res; + int save_to_disk = 0; + const char *ap = fmap->get("SFX>>", FM_DIR); + if(!ap) + { + log_printf(ELOG, "Couldn't find audio data directory!\n"); + return -1; + } + audio_set_path(ap); + + if(!sounds_loaded || force) + { + if(prog("Loading sound effects")) + return -999; + res = -1; + if(prefs->cached_sounds && !force) + { + res = audio_wave_load(0, "sfx_c.agw", 0); + if(res < 0) + save_to_disk = 1; + } + if(res < 0) + res = audio_wave_load(0, "sfx.agw", 0); + if(res >= 0) + sounds_loaded = 1; + else + log_printf(ELOG, "Could not load sound effects!\n"); + prog(NULL); + } + + if(prefs->use_music && !music_loaded || force) + { + if(prog("Loading music")) + return -999; + res = -1; + if(prefs->cached_sounds && !force) + { + res = audio_wave_load(0, "music_c.agw", 0); + if(res < 0) + save_to_disk = 1; + } + if(res < 0) + res = audio_wave_load(0, "music.agw", 0); + if(res >= 0) + music_loaded = 1; + else + log_printf(ELOG, "Could not load music!\n"); + prog(NULL); + } + + if(save_to_disk) + if(prog("Preparing audio engine")) + return -999; + + audio_wave_prepare(-1); + + if(save_to_disk) + { + if(prog("Writing sounds to disk")) + return -999; + if(audio_wave_load(0, "save_waves.agw", 0) < 0) + log_printf(ELOG, "Could not save sounds to disk!\n"); + } + + audio_wave_info(-1); + + return prog(NULL); +} + + +void KOBO_sound::prefschange() +{ + /* Levels */ +// audio_master_volume((float)prefs->volume/100.0); + audio_group_controlf(SOUND_GROUP_UI, ACC_VOLUME, + (float)prefs->intro_vol/100.0); + audio_group_controlf(SOUND_GROUP_UIMUSIC, ACC_VOLUME, + (float)prefs->intro_vol/100.0); + audio_group_controlf(SOUND_GROUP_SFX, ACC_VOLUME, + (float)prefs->sfx_vol/100.0); + audio_group_controlf(SOUND_GROUP_BGMUSIC, ACC_VOLUME, + (float)prefs->music_vol/100.0); + set_boost(prefs->vol_boost); + audio_quality((audio_quality_t)prefs->mixquality); + + // Bus 7: Our "Master Reverb Bus" + master_reverb((float)prefs->reverb/100.0); +} + + +int KOBO_sound::open() +{ + if(!prefs->use_sound) + { + log_printf(WLOG, "Sound disabled!\n"); + return 0; + } + + if(audio_start(prefs->samplerate, prefs->latency, prefs->use_oss, prefs->cmd_midi, + prefs->cmd_pollaudio) < 0) + { + log_printf(ELOG, "Couldn't initialize audio;" + " disabling sound effects.\n"); + return -1; + } + + // Channel grouping. We use only one chanel per group here, so we + // just assign the first channels to the available groups. + for(int i = 0; i < AUDIO_MAX_GROUPS; ++i) + audio_channel_control(i, -1, ACC_GROUP, i); + + // Dirty hack for the music; the sequencer uses channels 16..31. + for(int i = 16; i < 32; ++i) + audio_channel_control(i, -1, ACC_GROUP, SOUND_GROUP_BGMUSIC); + + // Higher priority for music and UI effects + audio_channel_control(SOUND_GROUP_BGMUSIC, AVT_ALL, ACC_PRIORITY, 1); + audio_channel_control(SOUND_GROUP_UIMUSIC, AVT_ALL, ACC_PRIORITY, 2); + audio_channel_control(SOUND_GROUP_UI, AVT_ALL, ACC_PRIORITY, 3); + audio_channel_control(SOUND_GROUP_SFX, AVT_ALL, ACC_PRIORITY, 4); + + g_wrap(MAP_SIZEX*CHIP_SIZEX, MAP_SIZEY*CHIP_SIZEY); + g_scale(VIEWLIMIT * 3 / 2, VIEWLIMIT); + + // For the noise "bzzzt" effect :-) + audio_channel_control(3, -1, ACC_PRIM_BUS, 1); + + // Bus 0: Sound effects + audio_bus_control(0, 1, ABC_FX_TYPE, AFX_NONE); + audio_bus_controlf(0, 0, ABC_SEND_MASTER, 1.0); + audio_bus_controlf(0, 0, ABC_SEND_BUS_7, 0.5); // Always a little rvb! + + // Bus 1: Sound effects with less reverb + audio_bus_control(1, 1, ABC_FX_TYPE, AFX_NONE); + audio_bus_controlf(1, 0, ABC_SEND_MASTER, 1.0); + audio_bus_controlf(1, 0, ABC_SEND_BUS_7, 0.1); + + prefschange(); + + time = SDL_GetTicks(); + return 0; +} + + +void KOBO_sound::stop() +{ + audio_stop(); +} + + +void KOBO_sound::close() +{ + audio_close(); + sounds_loaded = 0; + music_loaded = 0; +} + + + +/*-------------------------------------------------- + Main controls +--------------------------------------------------*/ + +void KOBO_sound::master_reverb(float rvb) +{ + int master_rvb = (int)(rvb * 65536.0); + audio_bus_controlf(7, 0, ABC_SEND_MASTER, 0.0); + audio_bus_control(7, 1, ABC_SEND_MASTER, master_rvb); + if(master_rvb) + audio_bus_control(7, 1, ABC_FX_TYPE, AFX_REVERB); + else + audio_bus_control(7, 1, ABC_FX_TYPE, AFX_NONE); +} + + +void KOBO_sound::set_boost(int boost) +{ + switch(boost) + { + case 0: + audio_set_limiter(1.0, 5.0); + break; + case 1: + audio_set_limiter(.9, 4.5); + break; + case 2: + default: + audio_set_limiter(.75, 4.0); + break; + case 3: + audio_set_limiter(.5, 3.5); + break; + case 4: + audio_set_limiter(.25, 3.0); + break; + } +} + + +void KOBO_sound::sfx_volume(float vol) +{ + audio_group_controlf(SOUND_GROUP_SFX, ACC_VOLUME, + (float)prefs->sfx_vol * vol / 100.0f); +} + + +void KOBO_sound::intro_volume(float vol) +{ + audio_group_controlf(SOUND_GROUP_UIMUSIC, ACC_VOLUME, + (float)prefs->intro_vol * vol / 100.0f); +} + + +void KOBO_sound::music_volume(float vol) +{ + audio_group_controlf(SOUND_GROUP_BGMUSIC, ACC_VOLUME, + (float)prefs->music_vol * vol / 100.0f); +} + + +void KOBO_sound::period(int ms) +{ + if(ms > 0) + _period = ms; + time = 0; +} + + +void KOBO_sound::frame() +{ +#if 0 + // Positional audio test + static int aaa = 0; + if(++aaa > 20) + aaa = 0; + if(aaa == 10) + g_play(SOUND_OVERHEAT, listener_x + 128, listener_y, 32768, 55<<16); + else if (aaa == 20) + g_play(SOUND_OVERHEAT, listener_x - 128, listener_y, 32768, 67<<16); +#endif + // Advance to next game logic frame + int nc = audio_next_callback(); + if(time < nc) + time = nc; + else + time -= 1 + (labs(time - nc) >> 5); + audio_bump(time); + time += _period; + + // Various sound control logic + ++rumble; // Rumble timer +} + + +void KOBO_sound::run() +{ + audio_run(); +} + + +/*-------------------------------------------------- + In-game sound +--------------------------------------------------*/ + +void KOBO_sound::g_music(int wid) +{ + audio_channel_control(SOUND_GROUP_BGMUSIC, AVT_FUTURE, ACC_PATCH, wid); + audio_channel_control(SOUND_GROUP_UI, AVT_FUTURE, ACC_PAN, 0); + audio_channel_play(SOUND_GROUP_BGMUSIC, 0, 60<<16, 65536); +} + + +void KOBO_sound::play(int wid, int vol, int pitch, int pan) +{ + audio_channel_control(SOUND_GROUP_UI, AVT_FUTURE, ACC_PATCH, wid); + audio_channel_control(SOUND_GROUP_UI, AVT_FUTURE, ACC_PAN, pan); + audio_channel_play(SOUND_GROUP_UI, 0, pitch, vol); +} + + +void KOBO_sound::g_position(int x, int y) +{ + listener_x = x; + listener_y = y; +} + + +void KOBO_sound::g_wrap(int w, int h) +{ + wrap_x = w; + wrap_y = h; +} + + +void KOBO_sound::g_scale(int maxrange, int pan_maxrange) +{ + scale = 65536 / maxrange; + panscale = 65536 / pan_maxrange; +} + + +void KOBO_sound::g_play(int wid, int x, int y, int vol, int pitch) +{ + int volume, vx, vy, pan; + /* Calculate volume */ + x -= listener_x; + y -= listener_y; + if(wrap_x) + { + x += wrap_x / 2; + while(x < 0) + x += wrap_x; + x %= wrap_x; + x -= wrap_x / 2; + } + if(wrap_y) + { + y += wrap_y / 2; + while(y < 0) + y += wrap_y; + y %= wrap_y; + y -= wrap_y / 2; + } + + /* Approximation of distance attenuation */ + vx = abs(x * scale); + vy = abs(y * scale); + if((vx | vy) & 0xffff0000) + return; + + vx = (65536 - vx) >> 1; + vy = (65536 - vy) >> 1; + volume = vx * vy >> 14; + volume = (volume>>1) * (volume>>1) >> 14; + + pan = x * panscale; + if(pan < -65536) + pan = -65536; + else if(pan > 65536) + pan = 65536; + + audio_channel_control(SOUND_GROUP_SFX, AVT_FUTURE, ACC_PATCH, wid); + audio_channel_control(SOUND_GROUP_SFX, AVT_FUTURE, ACC_PAN, pan); + audio_channel_control(SOUND_GROUP_SFX, AVT_FUTURE, ACC_VOLUME, volume); + audio_channel_play(SOUND_GROUP_SFX, sfx2d_tag, pitch, vol); + sfx2d_tag = (sfx2d_tag + 1) & 0xffff; +} + + +void KOBO_sound::g_play0(int wid, int vol, int pitch) +{ + audio_channel_control(SOUND_GROUP_SFX, AVT_FUTURE, ACC_PATCH, wid); + audio_channel_control(SOUND_GROUP_SFX, AVT_FUTURE, ACC_PAN, 0); + audio_channel_control(SOUND_GROUP_SFX, AVT_FUTURE, ACC_VOLUME, 65536); + audio_channel_play(SOUND_GROUP_SFX, sfx2d_tag, 60<<16, vol); + sfx2d_tag = (sfx2d_tag + 1) & 0xffff; +} + + +void KOBO_sound::g_player_fire() +{ + if(firing) + g_play0(SOUND_SHOT, (prefs->cannonloud << 13) / 100); + else + { + firing = 1; + g_play0(SOUND_SHOT_START, 20000); + } + overheat = 0; +} + + +void KOBO_sound::g_player_fire_off() +{ + if(firing) + { + firing = 0; + g_play0(SOUND_SHOT_END, 20000); + } +} + + +void KOBO_sound::g_player_overheat(int classic) +{ + if(overheat) + return; + overheat = 1; + g_play0(SOUND_SHOT_OVERHEAT, (prefs->cannonloud << 13) / 75); + if(!classic) + g_play(SOUND_OVERHEAT, listener_x + 100, listener_y, + (prefs->overheatloud << 14) / 100); +} + + +void KOBO_sound::g_player_damage() +{ + int p0 = (60<<16) + (pubrand.get(9) << 8); + g_play(SOUND_DAMAGE, listener_x - 100, listener_y, + 65536, p0 + 3000); + g_play(SOUND_DAMAGE, listener_x + 100, listener_y, + 65536, p0 - 3000); +} + + +void KOBO_sound::g_player_explo_start() +{ + g_player_damage(); + g_play(SOUND_EXPLO_PLAYER, listener_x - 100, listener_y, + 65536, (55<<16) + 4000); + g_play(SOUND_EXPLO_PLAYER, listener_x + 100, listener_y, + 65536, (55<<16) - 4000); +} + + +void KOBO_sound::g_bolt_hit(int x, int y) +{ + g_play(SOUND_METALLIC1 + (pubrand.get() % 3), + CS2PIXEL(x), CS2PIXEL(y), + 12000); +} + + +void KOBO_sound::g_bolt_hit_rock(int x, int y) +{ + g_play(SOUND_HIT1 + (pubrand.get() % 3), + CS2PIXEL(x), CS2PIXEL(y), + 20000); +} + + +void KOBO_sound::g_base_node_explo(int x, int y) +{ + g_play(pubrand.get(8) > 128 ? SOUND_EXPLO_NODE1 : SOUND_EXPLO_NODE2, + CS2PIXEL(x), CS2PIXEL(y)); + rumble = 0; +} + + +void KOBO_sound::g_base_core_explo(int x, int y) +{ + x = CS2PIXEL(x); + y = CS2PIXEL(y); + g_play(pubrand.get(8) > 128 ? SOUND_EXPLO_NODE1 : SOUND_EXPLO_NODE2, + x, y, 100000, 62<<16); + g_play(SOUND_FINE, x + 30, y, 65536, (60<<16) + 4000); + g_play(SOUND_FINE, x - 30, y, 65536, (60<<16) - 4000); + rumble = 0; +} + + +void KOBO_sound::g_pipe_rumble(int x, int y) +{ + if(rumble < 4 + pubrand.get(3)) + return; + g_play(pubrand.get(8) > 128 ? SOUND_RUMBLE_NODE1 : SOUND_RUMBLE_NODE2, + CS2PIXEL(x), CS2PIXEL(y)); + rumble = 0; +} + + +void KOBO_sound::g_enemy_explo(int x, int y) +{ + g_play(SOUND_EXPLO_ENEMY1 + (pubrand.get() % 2), + CS2PIXEL(x), CS2PIXEL(y), 40000); +} + + +void KOBO_sound::g_rock_explo(int x, int y) +{ + g_play(SOUND_EXPLO_ROCK, CS2PIXEL(x), CS2PIXEL(y), 40000); +} + + +void KOBO_sound::g_ring_explo(int x, int y) +{ + g_play(SOUND_EXPLO_RING1 + (pubrand.get() % 3), + CS2PIXEL(x), CS2PIXEL(y), 32768); +} + + +void KOBO_sound::g_bomb_deto(int x, int y) +{ + g_play(SOUND_BOMB_DETO, CS2PIXEL(x), CS2PIXEL(y), 40000); +} + + +void KOBO_sound::g_launch_ring(int x, int y) +{ + g_play(SOUND_RING, CS2PIXEL(x), CS2PIXEL(y)); +} + + +void KOBO_sound::g_launch_beam(int x, int y) +{ + g_play(SOUND_BEAM, CS2PIXEL(x), CS2PIXEL(y)); +} + + +void KOBO_sound::g_launch_bomb(int x, int y) +{ + g_play(SOUND_LAUNCH2, CS2PIXEL(x), CS2PIXEL(y)); +} + + +void KOBO_sound::g_launch(int x, int y) +{ + g_play(SOUND_LAUNCH, CS2PIXEL(x), CS2PIXEL(y)); +} + + +void KOBO_sound::g_m_launch_ring(int x, int y) +{ + g_play(SOUND_RING, CS2PIXEL(x), CS2PIXEL(y)); + g_play(SOUND_ENEMYM, CS2PIXEL(x), CS2PIXEL(y)); +} + + +void KOBO_sound::g_m_launch_beam(int x, int y) +{ + g_play(SOUND_BEAM, CS2PIXEL(x), CS2PIXEL(y)); + g_play(SOUND_ENEMYM, CS2PIXEL(x), CS2PIXEL(y)); +} + + +void KOBO_sound::g_m_launch_bomb(int x, int y) +{ + g_play(SOUND_LAUNCH2, CS2PIXEL(x), CS2PIXEL(y)); + g_play(SOUND_ENEMYM, CS2PIXEL(x), CS2PIXEL(y)); +} + + +void KOBO_sound::g_m_launch(int x, int y) +{ + g_play(SOUND_LAUNCH, CS2PIXEL(x), CS2PIXEL(y)); + g_play(SOUND_ENEMYM, CS2PIXEL(x), CS2PIXEL(y)); +} + + +/*-------------------------------------------------- + UI sound effects +--------------------------------------------------*/ + +void KOBO_sound::ui_music(int wid) +{ +// KLUDGE UNTIL MIDI SONGS AND FX CONTROL IS FIXED! + audio_bus_control(0, 1, ABC_FX_TYPE, AFX_NONE); + audio_bus_controlf(0, 0, ABC_SEND_MASTER, 1.0); + audio_bus_controlf(0, 0, ABC_SEND_BUS_7, 0.5); +// KLUDGE UNTIL MIDI SONGS AND FX CONTROL IS FIXED! + audio_channel_control(SOUND_GROUP_UIMUSIC, AVT_FUTURE, ACC_PATCH, wid); + audio_channel_play(SOUND_GROUP_UIMUSIC, 0, 60<<16, 65536); +} + + +void KOBO_sound::ui_noise(int n) +{ + if(n < 0) + { + sound.sfx_volume(0.0f); + audio_channel_control(SOUND_GROUP_UI, + AVT_FUTURE, ACC_PATCH, SOUND_BZZZT); + audio_channel_play(SOUND_GROUP_UI, 0, 60<<16, + 10000 + pubrand.get(14)); + return; + } + if(n && pubrand.get(1)) + { + sound.sfx_volume(0.0f); + audio_channel_control(SOUND_GROUP_UI, + AVT_FUTURE, ACC_PATCH, SOUND_BZZZT); + audio_channel_play(SOUND_GROUP_UI, 0, 60<<16, + 20000 + pubrand.get(14)); + } + else + sound.sfx_volume(1.0f); +} + + +void KOBO_sound::ui_ok() +{ + play(SOUND_EXPLO_NODE1, 32768); +} + + +void KOBO_sound::ui_cancel() +{ + play(SOUND_CANCEL, 20000); +} + + +void KOBO_sound::ui_move() +{ + play(SOUND_MOVE, 20000); +} + + +void KOBO_sound::ui_tick() +{ + play(SOUND_METALLIC1, 15000); +} + + +void KOBO_sound::ui_error() +{ + play(SOUND_OVERHEAT, 20000); +} + + +void KOBO_sound::ui_play() +{ + play(SOUND_PLAY, 32768, (50<<16) + 2000, -40000); + play(SOUND_PLAY, 32768, (50<<16) - 2000, 40000); +} + + +void KOBO_sound::ui_pause() +{ + play(SOUND_PAUSE, 32768, (56<<16) + 2000, -40000); + play(SOUND_PAUSE, 32768, (56<<16) - 2000, 40000); +} + + +void KOBO_sound::ui_ready() +{ + play(SOUND_READY, 15000, (60<<16) + 3000, -40000); + play(SOUND_READY, 15000, (60<<16) - 3000, 40000); +} + + +void KOBO_sound::ui_countdown(int remain) +{ + play(SOUND_TICK, 20000, (65 - remain)<<16); +} + + +void KOBO_sound::ui_oneup() +{ + play(SOUND_ONEUP, 32768, (60<<16) + 5000, -40000); + play(SOUND_ONEUP, 32768, (60<<16) - 5000, 40000); +} + + +void KOBO_sound::ui_gameover() +{ + play(SOUND_GAMEOVER); +} diff --git a/sound.h b/sound.h new file mode 100644 index 0000000..2843a7a --- /dev/null +++ b/sound.h @@ -0,0 +1,152 @@ +/*(GPL) +------------------------------------------------------------ + Kobo Deluxe - Wrapper for Sound Control +------------------------------------------------------------ + * Copyright (C) 2007 David Olofson + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef KOBO_SOUND_H +#define KOBO_SOUND_H + +#include "kobosfx.h" + +/* Sound groups */ +#define SOUND_GROUP_UI 0 +#define SOUND_GROUP_SFX 1 +#define SOUND_GROUP_UIMUSIC 2 +#define SOUND_GROUP_BGMUSIC 3 + + +class KOBO_sound +{ + static int sounds_loaded; + static int music_loaded; + + /* In-game sfx stuff */ + static int time; + static int _period; + static int sfx2d_tag; + static int listener_x; + static int listener_y; + static int wrap_x; + static int wrap_y; + static int scale; + static int panscale; + static int firing; + static int overheat; + static unsigned rumble; + + public: + KOBO_sound(); + ~KOBO_sound(); + + /*-------------------------------------------------- + Open/close + --------------------------------------------------*/ + static int open(); + static void prefschange(); + static int load(int (*prog)(const char *msg), int force); + static void stop(); + static void close(); + + /*-------------------------------------------------- + Main controls + --------------------------------------------------*/ + static void master_reverb(float rvb); + static void set_boost(int vol_boost); + static void sfx_volume(float vol); + static void intro_volume(float vol); + static void music_volume(float vol); + static void period(int ms); // 0 to reset time + static void frame(); + static void run(); + + /* Play a user interface sound */ + static void play(int wid, int vol = 65536, int pitch = 60<<16, + int pan = 0); + + /* Play a sound at a specific location on the map */ + static void g_play(int wid, int x, int y, + int vol = 65536, int pitch = 60<<16); + + /* Play a sound right where the listener is. */ + static void g_play0(int wid, int vol = 65536, int pitch = 60<<16); + + /*-------------------------------------------------- + In-game sound + --------------------------------------------------*/ + /* Play in-game music */ + static void g_music(int wid); + + /* Set listener position */ + static void g_position(int x, int y); + + /* Set world size for wrapping */ + static void g_wrap(int w, int h); + + /* + * Set world scale. 'maxrange' is the distance where + * a sound is out of the audible range. + */ + static void g_scale(int maxrange, int pan_maxrange); + + /* Various sound effects */ + static void g_player_fire(); + static void g_player_fire_off(); + static void g_player_overheat(int classic = 0); + static void g_player_damage(); + static void g_player_explo_start(); + static void g_bolt_hit(int x, int y); + static void g_bolt_hit_rock(int x, int y); + static void g_base_node_explo(int x, int y); + static void g_base_core_explo(int x, int y); + static void g_pipe_rumble(int x, int y); + static void g_enemy_explo(int x, int y); + static void g_rock_explo(int x, int y); + static void g_ring_explo(int x, int y); + static void g_bomb_deto(int x, int y); + static void g_launch_ring(int x, int y); + static void g_launch_beam(int x, int y); + static void g_launch_bomb(int x, int y); + static void g_launch(int x, int y); + static void g_m_launch_ring(int x, int y); + static void g_m_launch_beam(int x, int y); + static void g_m_launch_bomb(int x, int y); + static void g_m_launch(int x, int y); + + /*-------------------------------------------------- + UI sound effects + --------------------------------------------------*/ + /* Low level interface */ + static void ui_music(int wid); + + /* Various UI effects */ + static void ui_noise(int n); + static void ui_ok(); + static void ui_cancel(); + static void ui_move(); + static void ui_tick(); + static void ui_error(); + static void ui_play(); + static void ui_pause(); + static void ui_ready(); + static void ui_countdown(int remain); + static void ui_oneup(); + static void ui_gameover(); +}; + +#endif /* KOBO_SOUND_H */ diff --git a/sound/Makefile.am b/sound/Makefile.am new file mode 100644 index 0000000..08650d3 --- /dev/null +++ b/sound/Makefile.am @@ -0,0 +1,12 @@ +noinst_LIBRARIES = libsound.a + +INCLUDES = -I../eel -I../graphics @LOCALCFLAGS@ + +libsound_a_SOURCES = audio.c a_globals.c a_struct.c \ + audiodev.c a_midi.c sfifo.c a_pitch.c a_midisock.c \ + a_wave.c a_patch.c a_channel.c a_voice.c a_bus.c \ + a_commands.c a_control.c a_midicon.c a_midifile.c \ + a_plugin.c a_delay.c a_limiter.c a_filters.c \ + a_wca.c a_agw.c a_sequencer.c a_events.c + +EXTRA_DIST = *.h diff --git a/sound/Makefile.in b/sound/Makefile.in new file mode 100644 index 0000000..d7915a7 --- /dev/null +++ b/sound/Makefile.in @@ -0,0 +1,459 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = sound +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/aconfig.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) +AR = ar +ARFLAGS = cru +libsound_a_AR = $(AR) $(ARFLAGS) +libsound_a_LIBADD = +am_libsound_a_OBJECTS = audio.$(OBJEXT) a_globals.$(OBJEXT) \ + a_struct.$(OBJEXT) audiodev.$(OBJEXT) a_midi.$(OBJEXT) \ + sfifo.$(OBJEXT) a_pitch.$(OBJEXT) a_midisock.$(OBJEXT) \ + a_wave.$(OBJEXT) a_patch.$(OBJEXT) a_channel.$(OBJEXT) \ + a_voice.$(OBJEXT) a_bus.$(OBJEXT) a_commands.$(OBJEXT) \ + a_control.$(OBJEXT) a_midicon.$(OBJEXT) a_midifile.$(OBJEXT) \ + a_plugin.$(OBJEXT) a_delay.$(OBJEXT) a_limiter.$(OBJEXT) \ + a_filters.$(OBJEXT) a_wca.$(OBJEXT) a_agw.$(OBJEXT) \ + a_sequencer.$(OBJEXT) a_events.$(OBJEXT) +libsound_a_OBJECTS = $(am_libsound_a_OBJECTS) +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(libsound_a_SOURCES) +DIST_SOURCES = $(libsound_a_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AUDIO_LIBS = @AUDIO_LIBS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_MACOSX_BUNDLE_FALSE = @BUILD_MACOSX_BUNDLE_FALSE@ +BUILD_MACOSX_BUNDLE_TRUE = @BUILD_MACOSX_BUNDLE_TRUE@ +BUILD_SIMPLE_BUNDLE_FALSE = @BUILD_SIMPLE_BUNDLE_FALSE@ +BUILD_SIMPLE_BUNDLE_TRUE = @BUILD_SIMPLE_BUNDLE_TRUE@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CONFIGDIR = @CONFIGDIR@ +CONFIGFILE = @CONFIGFILE@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXEFILE = @EXEFILE@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LOCALCFLAGS = @LOCALCFLAGS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MATHLIB = @MATHLIB@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +POW_LIB = @POW_LIB@ +RANLIB = @RANLIB@ +SCOREDIR = @SCOREDIR@ +SDL_CFLAGS = @SDL_CFLAGS@ +SDL_CONFIG = @SDL_CONFIG@ +SDL_LIBS = @SDL_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +UNIX_SCOREDIR_FALSE = @UNIX_SCOREDIR_FALSE@ +UNIX_SCOREDIR_TRUE = @UNIX_SCOREDIR_TRUE@ +VERSION = @VERSION@ +XMKMF = @XMKMF@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +noinst_LIBRARIES = libsound.a +INCLUDES = -I../eel -I../graphics @LOCALCFLAGS@ +libsound_a_SOURCES = audio.c a_globals.c a_struct.c \ + audiodev.c a_midi.c sfifo.c a_pitch.c a_midisock.c \ + a_wave.c a_patch.c a_channel.c a_voice.c a_bus.c \ + a_commands.c a_control.c a_midicon.c a_midifile.c \ + a_plugin.c a_delay.c a_limiter.c a_filters.c \ + a_wca.c a_agw.c a_sequencer.c a_events.c + +EXTRA_DIST = *.h +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign sound/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign sound/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libsound.a: $(libsound_a_OBJECTS) $(libsound_a_DEPENDENCIES) + -rm -f libsound.a + $(libsound_a_AR) libsound.a $(libsound_a_OBJECTS) $(libsound_a_LIBADD) + $(RANLIB) libsound.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a_agw.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a_bus.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a_channel.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a_commands.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a_control.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a_delay.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a_events.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a_filters.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a_globals.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a_limiter.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a_midi.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a_midicon.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a_midifile.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a_midisock.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a_patch.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a_pitch.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a_plugin.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a_sequencer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a_struct.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a_voice.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a_wave.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a_wca.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audio.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audiodev.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sfifo.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-noinstLIBRARIES ctags distclean distclean-compile \ + distclean-generic distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/sound/a_agw.c b/sound/a_agw.c new file mode 100644 index 0000000..ead55b0 --- /dev/null +++ b/sound/a_agw.c @@ -0,0 +1,528 @@ +/*(LGPL) +--------------------------------------------------------------------------- + a_agw.c - "Algorithmically Generated Waveform" file support +--------------------------------------------------------------------------- + * Copyright (C) 2002, 2003, David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define DBG(x) + +#include + +#include "kobolog.h" +#include "config.h" +#include "eel.h" +#include "a_types.h" +#include "a_wca.h" +#include "a_control.h" + + +/* Enum class handles */ + +static int enum_aformat, enum_amodtarget, enum_awaveform, enum_afiltertype; +static int enum_amixmode, enum_aresample; + +static int enum_pparam, enum_pdriver; + + +/*---------------------------------------------------------- + AGW Command Callbacks +----------------------------------------------------------*/ + +static int op_w_reset(int argc, struct eel_data_t *argv) +{ + DBG(log_printf(D2LOG, "w_reset;\n");) + wca_reset(); + return 1; +} + + +static int op_w_format(int argc, struct eel_data_t *argv) +{ + int target; + double fs; + int format = enum_aformat; +#if 0 + /* Alternative, more verbose method. */ + eel_symbol_t *fmt; + if(eel_get_args("iEr", &target, &fmt, &fs) != 3) + return -1; + if(fmt->token != enum_aformat) + { + eel_error("Wrong enum class!"); + return -1; + } + DBG(log_printf(D2LOG, "w_format %d, %s, %f;\n", target, eel_s_stringrep(fmt), fs);) + format = fmt->data.value.i; +#else + if(eel_get_args("ier", &target, &format, &fs) != 3) + return -1; +#endif + DBG(log_printf(D2LOG, "w_format %d, %d, %f;\n", target, format, fs);) + audio_wave_format(target, format, (int)fs); + return 1; +} + + +static int op_w_gain(int argc, struct eel_data_t *argv) +{ + int target; + if(eel_get_args("i", &target) != 1) + return -1; + DBG(log_printf(D2LOG, "w_gain %d;\n", target);) + wca_gain(target); + return 1; +} + + +static int op_w_convert(int argc, struct eel_data_t *argv) +{ + int source, target; + double fs; + int format = enum_aformat; + int interpol = enum_aresample; + argc = eel_get_args("iie[re]", + &source, &target, &format, + &fs, &interpol); + if(argc < 3) + return -1; + if(argc < 4) + fs = 0; + if(argc < 5) + interpol = AR_BEST; + DBG(log_printf(D2LOG, "w_convert %d, %d, %d, %d, %d;\n", source, target, + format, (int)fs, interpol);) + audio_wave_convert(source, target, format, (int)fs, interpol); + return 1; +} + + +static int op_w_enhance(int argc, struct eel_data_t *argv) +{ + int target; + double f, level; + if(eel_get_args("irr", &target, &f, &level) != 3) + return -1; + DBG(log_printf(D2LOG, "w_enhance %d, %d, %f;\n", target, (int)f, level);) + wca_enhance(target, (int)f, level); + return 1; +} + + +static int op_w_gate(int argc, struct eel_data_t *argv) +{ + int target; + double f, min, thres, att; + if(eel_get_args("irrrr", + &target, &f, &min, &thres, &att) != 5) + return -1; + DBG(log_printf(D2LOG, "w_gate %d, %d, %f, %f, %f;\n", + target, (int)f, min, thres, att);) + wca_gate(target, (int)f, min, thres, att); + return 1; +} + + +static int op_w_blank(int argc, struct eel_data_t *argv) +{ + int target, loop; + unsigned samples; + argc = eel_get_args("ii[i]", &target, &samples, &loop); + if(argc < 2) + return -1; + if(argc < 3) + loop = 0; + DBG(log_printf(D2LOG, "w_blank %d, %d, %d;\n", target, samples, loop);) + audio_wave_blank(target, samples, loop); + return 1; +} + + +static int op_w_load(int argc, struct eel_data_t *argv) +{ + int target, loop; + const char *fn; + argc = eel_get_args("is[i]", &target, &fn, &loop); + if(argc < 2) + return -1; + if(argc < 3) + loop = 0; + DBG(log_printf(D2LOG, "w_load %d, \"%s\", %d;\n", target, fn, loop);) + if(audio_wave_load(target, fn, loop) < 0) + return -1; + return 1; +} + + +static int op_w_save(int argc, struct eel_data_t *argv) +{ + int target; + const char *fn; + if(eel_get_args("is", &target, &fn) != 2) + return -1; + DBG(log_printf(D2LOG, "w_save %d, \"%s\";\n", target, fn);) + if(audio_wave_save(target, fn) < 0) + return -1; + return 1; +} + + +static int op_w_prepare(int argc, struct eel_data_t *argv) +{ + int target; + if(eel_get_args("i", &target) < 1) + return -1; + DBG(log_printf(D2LOG, "w_prepare %d;\n", target);) + audio_wave_prepare(target); + return 1; +} + + +static int op_w_env(int argc, struct eel_data_t *argv) +{ + int i; + int modtarget = enum_amodtarget; + double dur[WCA_MAX_ENV_STEPS]; + double val[WCA_MAX_ENV_STEPS]; + + if(argc > 1 + 2*WCA_MAX_ENV_STEPS) + { + eel_error("Too many envelope steps!"); + return -1; + } + + if(eel_get_args("e[]", &modtarget, &dur, &val) != argc) + return -1; + + DBG(log_printf(D2LOG, "w_env %d", modtarget);) + wca_mod_reset(modtarget); + if(2 == argc) + { + /* + * Note that dur[0] actually becomes a *value* + * rather than a time in this case! + */ + DBG(log_printf(D2LOG, ", %f;\n", dur[0]);) + wca_val(modtarget, dur[0]); + return 1; + } + for(i = 1; i < argc; i += 2) + { + int sec = (i-1)/2; + DBG(log_printf(D2LOG, ", <%f", dur[sec]);) + if(i+1 >= argc) + { + eel_error(" argruments must" + " come in pairs!"); + return -1; + } + DBG(else + log_printf(D2LOG, ", %f", val[sec]);) + DBG(log_printf(D2LOG, ">");) + wca_env(modtarget, dur[sec], val[sec]); + } + DBG(log_printf(D2LOG, ";\n");) + + return 1; +} + + +static int op_w_mod(int argc, struct eel_data_t *argv) +{ + int mt; + double f, a, d; + mt = enum_amodtarget; + if(eel_get_args("errr", &mt, &f, &a, &d) != 4) + return -1; + DBG(log_printf(D2LOG, "w_mod %d, %f, %f, %f;\n", mt, f, a, d);) + wca_mod(mt, f, a, d); + return 1; +} + + +static int op_w_osc(int argc, struct eel_data_t *argv) +{ + int target, wf, mm; + wf = enum_awaveform; + mm = enum_amixmode; + switch(eel_get_args("ie[e]", &target, &wf, &mm)) + { + case 2: + mm = WCA_ADD; + case 3: + break; + default: + return -1; + } + DBG(log_printf(D2LOG, "w_osc %d, %d, %d;\n", target, wf, mm);) + wca_osc(target, wf, mm); + return 1; +} + + +static int op_w_filter(int argc, struct eel_data_t *argv) +{ + int target, ft; + ft = enum_afiltertype; + if(eel_get_args("ie", &target, &ft) != 2) + return -1; + DBG(log_printf(D2LOG, "w_filter %d, %d;\n", target, ft);) + wca_filter(target, ft); + return 1; +} + + + +/*---------------------------------------------------------- + Patch Command Callbacks +----------------------------------------------------------*/ + +static int op_p_param(int argc, struct eel_data_t *argv) +{ + int patch, param; + double value; + param = enum_pparam; + if(eel_get_args("ier", &patch, ¶m, &value) != 3) + return -1; + switch(param) + { + case APP_DRIVER: + case APP_WAVE: + case APP_ENV_SKIP: + case APP_LFO_SHAPE: + audio_patch_param(patch, param, (int)value); + break; + default: + audio_patch_param(patch, param, (int)(value * 65536.0)); + break; + } + DBG(log_printf(D2LOG, "p_param %d, %d, %f;\n", patch, param, value);) + return 1; +} + + +static int op_p_driver(int argc, struct eel_data_t *argv) +{ + int patch; + eel_symbol_t *callback; + if(eel_get_args("if", &patch, &callback) != 2) + return -1; + DBG(log_printf(D2LOG, "p_driver %d, %s;\n", patch, eel_s_stringrep(callback));) + return 1; +} + + +/*---------------------------------------------------------- + Init code +----------------------------------------------------------*/ + +static void load_keywords(void) +{ + /* WCA calls */ + eel_register_operator("w_reset", op_w_reset, 100, 0 ,0); + eel_register_operator("w_format", op_w_format, 100, 0 ,0); + eel_register_operator("w_blank", op_w_blank, 100, 0 ,0); + eel_register_operator("w_load", op_w_load, 100, 0 ,0); + eel_register_operator("w_save", op_w_save, 100, 0 ,0); + eel_register_operator("w_prepare", op_w_prepare, 100, 0 ,0); + eel_register_operator("w_env", op_w_env, 100, 0 ,0); + eel_register_operator("w_mod", op_w_mod, 100, 0 ,0); + eel_register_operator("w_osc", op_w_osc, 100, 0 ,0); + eel_register_operator("w_filter", op_w_filter, 100, 0 ,0); + eel_register_operator("w_gain", op_w_gain, 100, 0 ,0); + eel_register_operator("w_convert", op_w_convert, 100, 0 ,0); + eel_register_operator("w_enhance", op_w_enhance, 100, 0 ,0); + eel_register_operator("w_gate", op_w_gate, 100, 0 ,0); + + /* w_convert resampling modes */ + enum_aresample = eel_register_enum_class(); + eel_register_enum(enum_aresample, "NEAREST", AR_NEAREST); + eel_register_enum(enum_aresample, "NEAREST4X", AR_NEAREST_4X); + eel_register_enum(enum_aresample, "LINEAR", AR_LINEAR); + eel_register_enum(enum_aresample, "LINEAR2X", AR_LINEAR_2X_R); + eel_register_enum(enum_aresample, "LINEAR4X", AR_LINEAR_4X_R); + eel_register_enum(enum_aresample, "LINEAR8X", AR_LINEAR_8X_R); + eel_register_enum(enum_aresample, "LINEAR16X", AR_LINEAR_16X_R); + eel_register_enum(enum_aresample, "CUBIC", AR_CUBIC_R); + + eel_register_enum(enum_aresample, "WORST", AR_WORST); + eel_register_enum(enum_aresample, "MEDIUM", AR_MEDIUM); + eel_register_enum(enum_aresample, "BEST", AR_BEST); + + /* Sample formats */ + enum_aformat = eel_register_enum_class(); + eel_register_enum(enum_aformat, "MONO8", AF_MONO8); + eel_register_enum(enum_aformat, "STEREO8", AF_STEREO8); + eel_register_enum(enum_aformat, "MONO16", AF_MONO16); + eel_register_enum(enum_aformat, "STEREO16", AF_STEREO16); + eel_register_enum(enum_aformat, "MONO32", AF_MONO32); + eel_register_enum(enum_aformat, "STEREO32", AF_STEREO32); + + /* Modulation targets */ + enum_amodtarget = eel_register_enum_class(); + eel_register_enum(enum_amodtarget, "AMPLITUDE", WCA_AMPLITUDE); + eel_register_enum(enum_amodtarget, "BALANCE", WCA_BALANCE); + eel_register_enum(enum_amodtarget, "FREQUENCY", WCA_FREQUENCY); + eel_register_enum(enum_amodtarget, "LIMIT", WCA_LIMIT); + eel_register_enum(enum_amodtarget, "MOD1", WCA_MOD1); + eel_register_enum(enum_amodtarget, "MOD2", WCA_MOD2); + eel_register_enum(enum_amodtarget, "MOD3", WCA_MOD3); + + /* Oscillator output modes */ + enum_amixmode = eel_register_enum_class(); + eel_register_enum(enum_amixmode, "ADD", WCA_ADD); + eel_register_enum(enum_amixmode, "MUL", WCA_MUL); + eel_register_enum(enum_amixmode, "FM", WCA_FM); + eel_register_enum(enum_amixmode, "FM_ADD", WCA_FM_ADD); + eel_register_enum(enum_amixmode, "SYNC", WCA_SYNC); + eel_register_enum(enum_amixmode, "SYNC_ADD", WCA_SYNC_ADD); + + /* Oscillator waveforms */ + enum_awaveform = eel_register_enum_class(); + eel_register_enum(enum_awaveform, "DC", WCA_DC); + eel_register_enum(enum_awaveform, "SINE", WCA_SINE); + eel_register_enum(enum_awaveform, "HALFSINE", WCA_HALFSINE); + eel_register_enum(enum_awaveform, "RECTSINE", WCA_RECTSINE); + eel_register_enum(enum_awaveform, "SINEMORPH", WCA_SINEMORPH); + eel_register_enum(enum_awaveform, "BLMORPH", WCA_BLMORPH); + eel_register_enum(enum_awaveform, "BLCROSS", WCA_BLCROSS); + eel_register_enum(enum_awaveform, "PULSE", WCA_PULSE); + eel_register_enum(enum_awaveform, "TRIANGLE", WCA_TRIANGLE); + eel_register_enum(enum_awaveform, "NOISE", WCA_NOISE); + eel_register_enum(enum_awaveform, "SPECTRUM", WCA_SPECTRUM); + eel_register_enum(enum_awaveform, "ASPECTRUM", WCA_ASPECTRUM); + eel_register_enum(enum_awaveform, "HSPECTRUM", WCA_HSPECTRUM); + eel_register_enum(enum_awaveform, "AHSPECTRUM", WCA_AHSPECTRUM); + + /* Filter types */ + enum_afiltertype = eel_register_enum_class(); + eel_register_enum(enum_afiltertype, "ALLPASS", WCA_ALLPASS); + eel_register_enum(enum_afiltertype, "LOWPASS_6", WCA_LOWPASS_6DB); + eel_register_enum(enum_afiltertype, "HIGHPASS_6", WCA_HIGHPASS_6DB); + eel_register_enum(enum_afiltertype, "LOWPASS_12", WCA_LOWPASS_12DB); + eel_register_enum(enum_afiltertype, "HIGHPASS_12", WCA_HIGHPASS_12DB); + eel_register_enum(enum_afiltertype, "BANDPASS_12", WCA_BANDPASS_12DB); + eel_register_enum(enum_afiltertype, "NOTCH_12", WCA_NOTCH_12DB); + eel_register_enum(enum_afiltertype, "PEAK_12", WCA_PEAK_12DB); + + /* Patch calls */ + eel_register_operator("p_param", op_p_param, 100, 0 ,0); + eel_register_operator("p_driver", op_p_driver, 100, 0 ,0); + + /* Patch Parameters */ + enum_pparam = eel_register_enum_class(); + eel_register_enum(enum_pparam, "DRIVER", APP_DRIVER); + eel_register_enum(enum_pparam, "WAVE", APP_WAVE); + eel_register_enum(enum_pparam, "RANDPITCH", APP_RANDPITCH); + eel_register_enum(enum_pparam, "RANDVOL", APP_RANDVOL); + + eel_register_enum(enum_pparam, "ENV_SKIP", APP_ENV_SKIP); + eel_register_enum(enum_pparam, "ENV_L0", APP_ENV_L0); + eel_register_enum(enum_pparam, "ENV_DELAY", APP_ENV_DELAY); + eel_register_enum(enum_pparam, "ENV_T1", APP_ENV_T1); + eel_register_enum(enum_pparam, "ENV_L1", APP_ENV_L1); + eel_register_enum(enum_pparam, "ENV_HOLD", APP_ENV_HOLD); + eel_register_enum(enum_pparam, "ENV_T2", APP_ENV_T2); + eel_register_enum(enum_pparam, "ENV_L2", APP_ENV_L2); + eel_register_enum(enum_pparam, "ENV_T3", APP_ENV_T3); + eel_register_enum(enum_pparam, "ENV_T4", APP_ENV_T4); + + /* Patch Drivers */ + enum_pdriver = eel_register_enum_class(); + eel_register_enum(enum_pdriver, "MONO", PD_MONO); + eel_register_enum(enum_pdriver, "POLY", PD_POLY); + eel_register_enum(enum_pdriver, "MIDI", PD_MIDI); + eel_register_enum(enum_pdriver, "EEL", PD_EEL); +} + + +/*---------------------------------------------------------- + API code +----------------------------------------------------------*/ + +static int _agw_initialized = 0; + + +int agw_open(void) +{ + if(_agw_initialized) + return 0; + + eel_open(); + + eel_push_scope(); /* begin AGW extensions scope */ + + load_keywords(); + + /* Built-in variables */ + (void)eel_set_integer("target", -1); + + _agw_initialized = 1; + return 0; +} + +void agw_close(void) +{ + if(!_agw_initialized) + return; + + eel_pop_scope(); /* end AGW extensions scope */ + + eel_close(); + + _agw_initialized = 0; +} + +#define CHECKINIT if(!_agw_initialized) agw_open(); + +int agw_load(int wid, const char *name) +{ + int script, res; + + CHECKINIT + + if(wid < 0) + { + wid = audio_wave_alloc(wid); + if(wid < 0) + return wid; + } + + script = eel_load(name); + if(script < 0) + return -1; + + eel_push_scope(); /* begin script scope */ + + /* Initialize "argument" variables */ + (void)eel_set_integer("target", wid); + + /* Reset the waveform construction engine */ + wca_reset(); + + res = eel_run(script); + eel_free(script); + + eel_pop_scope(); /* end script scope */ + + if(res < 0) + return -1; + + audio_wave_prepare(wid); + + return wid; +} diff --git a/sound/a_agw.h b/sound/a_agw.h new file mode 100644 index 0000000..26de07f --- /dev/null +++ b/sound/a_agw.h @@ -0,0 +1,359 @@ +/*(LGPL) +--------------------------------------------------------------------------- + a_agw.h - "Algorithmically Generated Waveform" file support +--------------------------------------------------------------------------- + * Copyright (C) 2002, 2003, David Olofson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * The AGW v0.1 file format: + * + * This extension to the EEL language makes it possible + * to use EEL scripts to construct waveforms using the + * "Waveform Construction API" of the engine. + * + * Why!? + * Well, pages of hard-coded calls to the Waveform + * Construction API and recompiling for every turn + * while creating sounds got boring, so I decided to + * hack up something simple to get cleaner code and + * faster sound editing. + * + * Over a few weeks, the file format turned into an + * interpreted language, which I eventually cleaned up + * and separated from the engine. This language is + * called "EEL" - Extensible Embeddable Language, and + * is not tied to the audio engine. + * + * Built-in commands: + * // + * C++ style comment. + * + */ /* ... */ +/* C style comment. + * + * w_reset; + * Resets the AGW engine state to the default. + * This is done automatically before a script + * is executed after being loaded with w_load(). + * See below for default settings for w_env etc. + * + * w_format , , ; + * Set format of to ; + * samples per second. + * + * Supported sample formats: + * MONO8 STEREO8 + * MONO16 STEREO16 + * + * w_blank , , ; + * Create samples of silent data + * for waveform . can be either 0 + * or 1, and if it's 1, the waveform will be + * set up for looping playback. + * + * w_env [,

    Mrv>mj4HukYE54EXQ~uqYgCOR|Q2RsK&B; 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 literal 0 HcmV?d00001 diff --git a/data/gfx/ringexpl2b.png b/data/gfx/ringexpl2b.png new file mode 100644 index 0000000000000000000000000000000000000000..2c693e31853d853486c11d55633e0868ee112d3b GIT binary patch literal 27170 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 literal 0 HcmV?d00001 diff --git a/data/gfx/rock1c.png b/data/gfx/rock1c.png new file mode 100644 index 0000000000000000000000000000000000000000..1c4be19bb586a5102a93732ba869ae4f1e5d4e68 GIT binary patch literal 33940 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 Ef{wC%J^%m! literal 0 HcmV?d00001 diff --git a/data/gfx/rock2.png b/data/gfx/rock2.png new file mode 100644 index 0000000000000000000000000000000000000000..99faa8ccd662b770569375e0fd753e8500308982 GIT binary patch literal 30388 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

  • 0D=I?w9fY~u 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 literal 0 HcmV?d00001 diff --git a/data/gfx/flatstars1.png b/data/gfx/flatstars1.png new file mode 100644 index 0000000000000000000000000000000000000000..be81036287302f3bf257deb4808c45b347acff0c GIT binary patch literal 3270 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 literal 0 HcmV?d00001 diff --git a/data/gfx/goldfont.png b/data/gfx/goldfont.png new file mode 100644 index 0000000000000000000000000000000000000000..d1ba96350a6a49df01ee98417e607278bfdac74f GIT binary patch literal 24246 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 KMNUMnLSTZVq45&{ literal 0 HcmV?d00001 diff --git a/data/gfx/loading3.png b/data/gfx/loading3.png new file mode 100644 index 0000000000000000000000000000000000000000..e3fb0b8c68366bcb1841a45c2b404c04da7f6579 GIT binary patch literal 82489 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 z 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