From 16d1a05b0777e97a45c48e2874aa4e5cc791282e Mon Sep 17 00:00:00 2001 From: Charles McGarvey Date: Fri, 31 Jul 2009 19:12:25 -0600 Subject: [PATCH] fixed up video and texture handling --- Makefile.am | 7 + configure.ac | 2 +- data/Makefile.am | 2 +- data/animations/AlienWarrior.json | 394 ++++++++++++---------- data/animations/BigExplosion.json | 50 +-- data/animations/Bonuses.json | 288 ++++++++-------- data/animations/Bullets.json | 138 ++++---- data/animations/Effects.json | 216 ++++++------ data/animations/Heroine.json | 532 ++++++++++++++++-------------- data/animations/Jetbot.json | 384 +++++++++++---------- data/animations/RobotTrooper.json | 432 +++++++++++++----------- data/tilemaps/AlienWarrior.json | 8 +- data/tilemaps/BackgroundFar.json | 12 +- data/tilemaps/BackgroundNear.json | 12 +- data/tilemaps/BigExplosion.json | 12 +- data/tilemaps/Bonuses.json | 12 +- data/tilemaps/Building.json | 12 +- data/tilemaps/Font.json | 8 +- data/tilemaps/Heroine.json | 8 +- data/tilemaps/Jetbot.json | 8 +- data/tilemaps/Particles.json | 12 +- data/tilemaps/RobotTrooper.json | 8 +- data/tilemaps/Scenery.json | 12 +- data/tilemaps/StatusBars.json | 8 +- data/tilemaps/TowerBlock1.json | 12 +- data/tilemaps/Trees.json | 12 +- data/yoinkrc | 18 +- doc/yoink.6.in | 15 +- extra/yoink.ebuild | 3 +- src/Character.hh | 7 - src/Makefile.am | 3 + src/Moof/Engine.cc | 43 ++- src/Moof/Engine.hh | 12 +- src/Moof/Math.hh | 25 +- src/Moof/OpenGL.cc | 70 ++++ src/Moof/OpenGL.hh | 34 ++ src/Moof/Scene.cc | 35 +- src/Moof/Settings.cc | 6 +- src/Moof/Texture.cc | 213 +++++++----- src/Moof/Texture.hh | 10 +- src/Moof/Tilemap.cc | 113 ++++--- src/Moof/Video.cc | 61 ++-- src/Moof/Video.hh | 44 +-- src/TilemapFont.hh | 6 - src/YoinkApp.cc | 77 +++-- 45 files changed, 1913 insertions(+), 1483 deletions(-) create mode 100644 src/Moof/OpenGL.cc diff --git a/Makefile.am b/Makefile.am index 95437f2..b77b1f2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,9 +5,16 @@ SUBDIRS = yajl src data doc EXTRA_DIST = yajl + run: all $(MAKE) -C src run debug: all $(MAKE) -C src debug + +RPMBUILD = rpmbuild + +RPM: dist-bzip2 + $(RPMBUILD) -ba --nodeps extra/yoink.spec + diff --git a/configure.ac b/configure.ac index cc0e8be..4aafa81 100644 --- a/configure.ac +++ b/configure.ac @@ -156,9 +156,9 @@ AC_SUBST([DATA_FILES]) AC_CONFIG_FILES([Makefile data/Makefile - src/Makefile doc/Makefile doc/yoink.6 + src/Makefile yajl/Makefile]) AC_CONFIG_HEADERS([src/config.h]) diff --git a/data/Makefile.am b/data/Makefile.am index 0ab7958..61318d2 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -1,5 +1,5 @@ -nobase_dist_pkgdata_DATA = @DATA_FILES@ +nobase_dist_pkgdata_DATA = @DATA_FILES@ yoinkrc appsdir=$(prefix)/share/applications dist_apps_DATA = yoink.desktop diff --git a/data/animations/AlienWarrior.json b/data/animations/AlienWarrior.json index 15d28cf..2268fca 100644 --- a/data/animations/AlienWarrior.json +++ b/data/animations/AlienWarrior.json @@ -1,184 +1,214 @@ { - "Stand": { - "type": "Stand", - "delay": 1, - "frames": [ - { - "index": 0, - "duration": 2 - }, - { - "index": 1, - "duration": 0.25 - }, - { - "index": 2, - "duration": 2 - }, - { - "index": 1, - "duration": 0.25 - } - ] - }, - "Run": { - "type": "Run", - "delay": 0.25, - "frames": [ - { - "index": 3 - }, - { - "index": 4 - }, - { - "index": 5 - }, - { - "index": 6 - } - ] - }, - "StopRunning": { - "type": "Stand", - "next": "Stand", - "delay": 10, - "loop": true, - "frames": [ - { - "index": 7 - } - ] - }, - "Jump": { - "type": "Jump", - "next": "FlyDiagonallyUp", - "delay": 0.25, - "frames": [ - { - "index": 17 - } - ] - }, - "Land": { - "type": "Stand", - "next": "Stand", - "delay": 1, - "loop": true, - "frames": [ - { - "index": 13, - "duration": 0.25 - } - ] - }, - "FlyDiagonallyUp": { - "type": "Fly", - "delay": 0.1, - "frames": [ - { - "index": 18 - } - ] - }, - "FlyDiagonallyDown": { - "type": "Fly", - "delay": 0.1, - "frames": [ - { - "index": 19 - } - ] - }, - "FlyStraightUp": { - "type": "Fly", - "delay": 0.1, - "frames": [ - { - "index": 19 - } - ] - }, - "FlyHorizontally": { - "type": "Fly", - "frames": [ - { - "index": 3 - } - ] - }, - "Punch": { - "type": "Attack", - "delay": 0.2, - "frames": [ - { - "index": 8 - }, - { - "index": 9 - } - ] - }, - "StartFiring": { - "type": "Attack", - "next": "Fire", - "delay": 0.1, - "frames": [ - { - "index": 0 - }, - { - "index": 8 - } - ] - }, - "Fire": { - "type": "Attack", - "delay": 1, - "frames": [ - { - "index": 10, - "duration": 0.2 - }, - { - "index": 11, - "duration": 0.2 - } - ] - }, - "StopFiring": { - "type": "Attack", - "next": "Stand", - "delay": 0.1, - "frames": [ - { - "index": 8 - }, - { - "index": 0 - } - ] - }, - "KnockedDown": { - "type": "Hit", - "delay": 0.1, - "loop": true, - "frames": [ - { - "index": 16 - }, - { - "index": 15 - } - ] - }, - "Flattened": { - "type": "Hit", - "delay": 1, - "frames": [ - { - "index": 13 - } - ] - } + "Stand": + { + "type": "Stand", + "delay": 1, + "frames": + [ + { + "index": 0, + "duration": 2 + }, + { + "index": 1, + "duration": 0.25 + }, + { + "index": 2, + "duration": 2 + }, + { + "index": 1, + "duration": 0.25 + } + ] + }, + "Run": + { + "type": "Run", + "delay": 0.25, + "frames": + [ + { + "index": 3 + }, + { + "index": 4 + }, + { + "index": 5 + }, + { + "index": 6 + } + ] + }, + "StopRunning": + { + "type": "Stand", + "next": "Stand", + "delay": 10, + "loop": true, + "frames": + [ + { + "index": 7 + } + ] + }, + "Jump": + { + "type": "Jump", + "next": "FlyDiagonallyUp", + "delay": 0.25, + "frames": + [ + { + "index": 17 + } + ] + }, + "Land": + { + "type": "Stand", + "next": "Stand", + "delay": 1, + "loop": true, + "frames": + [ + { + "index": 13, + "duration": 0.25 + } + ] + }, + "FlyDiagonallyUp": + { + "type": "Fly", + "delay": 0.1, + "frames": + [ + { + "index": 18 + } + ] + }, + "FlyDiagonallyDown": + { + "type": "Fly", + "delay": 0.1, + "frames": + [ + { + "index": 19 + } + ] + }, + "FlyStraightUp": + { + "type": "Fly", + "delay": 0.1, + "frames": + [ + { + "index": 19 + } + ] + }, + "FlyHorizontally": + { + "type": "Fly", + "frames": + [ + { + "index": 3 + } + ] + }, + "Punch": + { + "type": "Attack", + "delay": 0.2, + "frames": + [ + { + "index": 8 + }, + { + "index": 9 + } + ] + }, + "StartFiring": + { + "type": "Attack", + "next": "Fire", + "delay": 0.1, + "frames": + [ + { + "index": 0 + }, + { + "index": 8 + } + ] + }, + "Fire": + { + "type": "Attack", + "delay": 1, + "frames": + [ + { + "index": 10, + "duration": 0.2 + }, + { + "index": 11, + "duration": 0.2 + } + ] + }, + "StopFiring": + { + "type": "Attack", + "next": "Stand", + "delay": 0.1, + "frames": + [ + { + "index": 8 + }, + { + "index": 0 + } + ] + }, + "KnockedDown": + { + "type": "Hit", + "delay": 0.1, + "loop": true, + "frames": + [ + { + "index": 16 + }, + { + "index": 15 + } + ] + }, + "Flattened": + { + "type": "Hit", + "delay": 1, + "frames": + [ + { + "index": 13 + } + ] + } } diff --git a/data/animations/BigExplosion.json b/data/animations/BigExplosion.json index a0cb719..32aad03 100644 --- a/data/animations/BigExplosion.json +++ b/data/animations/BigExplosion.json @@ -1,26 +1,28 @@ { - "BigExplosion": { - "delay": 0.1, - "loop": true, - "frames": [ - { - "index": 0 - }, - { - "index": 1 - }, - { - "index": 2 - }, - { - "index": 3 - }, - { - "index": 4 - }, - { - "index": 5 - } - ] - } + "BigExplosion": + { + "delay": 0.1, + "loop": true, + "frames": + [ + { + "index": 0 + }, + { + "index": 1 + }, + { + "index": 2 + }, + { + "index": 3 + }, + { + "index": 4 + }, + { + "index": 5 + } + ] + } } diff --git a/data/animations/Bonuses.json b/data/animations/Bonuses.json index 88cacad..9bd61b7 100644 --- a/data/animations/Bonuses.json +++ b/data/animations/Bonuses.json @@ -1,134 +1,158 @@ { - "SmallHealth": { - "delay": 0.1, - "frames": [ - { - "index": 0 - }, - { - "index": 1 - }, - { - "index": 2 - }, - { - "index": 1 - } - ] - }, - "LargeHealth": { - "delay": 0.1, - "frames": [ - { - "index": 3 - }, - { - "index": 4 - }, - { - "index": 5 - }, - { - "index": 4 - } - ] - }, - "SmallRedPotion": { - "delay": 0.1, - "frames": [ - { - "index": 6 - }, - { - "index": 7 - }, - { - "index": 8 - }, - { - "index": 7 - } - ] - }, - "SmallBluePotion": { - "delay": 0.1, - "frames": [ - { - "index": 9 - }, - { - "index": 10 - }, - { - "index": 11 - }, - { - "index": 10 - } - ] - }, - "FirstAidKit": { - "delay": 1, - "frames": [ - { - "index": 12 - } - ] - }, - "AlienFirstAidKit": { - "delay": 1, - "frames": [ - { - "index": 13 - } - ] - }, - "Cake": { - "delay": 1, - "frames": [ - { - "index": 14 - } - ] - }, - "FizzyDrink": { - "delay": 1, - "frames": [ - { - "index": 15 - } - ] - }, - "Cheese": { - "delay": 1, - "frames": [ - { - "index": 16 - } - ] - }, - "Chocolate": { - "delay": 1, - "frames": [ - { - "index": 17 - } - ] - }, - "MilkBottle": { - "delay": 1, - "frames": [ - { - "index": 18 - } - ] - }, - "OneSadCookie": { - "delay": 1, - "frames": [ - { - "index": 19 - } - ] - } + "SmallHealth": + { + "delay": 0.1, + "frames": + [ + { + "index": 0 + }, + { + "index": 1 + }, + { + "index": 2 + }, + { + "index": 1 + } + ] + }, + "LargeHealth": + { + "delay": 0.1, + "frames": + [ + { + "index": 3 + }, + { + "index": 4 + }, + { + "index": 5 + }, + { + "index": 4 + } + ] + }, + "SmallRedPotion": + { + "delay": 0.1, + "frames": + [ + { + "index": 6 + }, + { + "index": 7 + }, + { + "index": 8 + }, + { + "index": 7 + } + ] + }, + "SmallBluePotion": + { + "delay": 0.1, + "frames": + [ + { + "index": 9 + }, + { + "index": 10 + }, + { + "index": 11 + }, + { + "index": 10 + } + ] + }, + "FirstAidKit": + { + "delay": 1, + "frames": + [ + { + "index": 12 + } + ] + }, + "AlienFirstAidKit": + { + "delay": 1, + "frames": + [ + { + "index": 13 + } + ] + }, + "Cake": + { + "delay": 1, + "frames": + [ + { + "index": 14 + } + ] + }, + "FizzyDrink": + { + "delay": 1, + "frames": + [ + { + "index": 15 + } + ] + }, + "Cheese": + { + "delay": 1, + "frames": + [ + { + "index": 16 + } + ] + }, + "Chocolate": + { + "delay": 1, + "frames": + [ + { + "index": 17 + } + ] + }, + "MilkBottle": + { + "delay": 1, + "frames": + [ + { + "index": 18 + } + ] + }, + "OneSadCookie": + { + "delay": 1, + "frames": + [ + { + "index": 19 + } + ] + } } diff --git a/data/animations/Bullets.json b/data/animations/Bullets.json index caca7af..d92428f 100644 --- a/data/animations/Bullets.json +++ b/data/animations/Bullets.json @@ -1,65 +1,77 @@ { - "Punch": { - "delay": 1, - "frames": [ - { - "index": 31 - } - ] - }, - "SmallBullet": { - "delay": 0.05, - "frames": [ - { - "index": 16 - }, - { - "index": 17 - } - ] - }, - "MediumBullet": { - "delay": 0.05, - "frames": [ - { - "index": 17 - }, - { - "index": 18 - } - ] - }, - "SmallFireball": { - "delay": 0.05, - "frames": [ - { - "index": 0 - }, - { - "index": 1 - } - ] - }, - "MediumFireball": { - "delay": 0.05, - "frames": [ - { - "index": 2 - }, - { - "index": 1 - } - ] - }, - "LargeFireball": { - "delay": 0.05, - "frames": [ - { - "index": 21 - }, - { - "index": 2 - } - ] - } + "Punch": + { + "delay": 1, + "frames": + [ + { + "index": 31 + } + ] + }, + "SmallBullet": + { + "delay": 0.05, + "frames": + [ + { + "index": 16 + }, + { + "index": 17 + } + ] + }, + "MediumBullet": + { + "delay": 0.05, + "frames": + [ + { + "index": 17 + }, + { + "index": 18 + } + ] + }, + "SmallFireball": + { + "delay": 0.05, + "frames": + [ + { + "index": 0 + }, + { + "index": 1 + } + ] + }, + "MediumFireball": + { + "delay": 0.05, + "frames": + [ + { + "index": 2 + }, + { + "index": 1 + } + ] + }, + "LargeFireball": + { + "delay": 0.05, + "frames": + [ + { + "index": 21 + }, + { + "index": 2 + } + ] + } } diff --git a/data/animations/Effects.json b/data/animations/Effects.json index 35e0464..03b877f 100644 --- a/data/animations/Effects.json +++ b/data/animations/Effects.json @@ -1,105 +1,115 @@ { - "Fireball": { - "delay": 0.1, - "frames": [ - { - "index": 0 - }, - { - "index": 1 - }, - { - "index": 2 - }, - { - "index": 1 - }, - { - "index": 0 - } - ] - }, - "Smoke": { - "delay": 0.05, - "loop": true, - "frames": [ - { - "index": 4 - }, - { - "index": 5 - }, - { - "index": 6 - } - ] - }, - "GreenDiamond": { - "delay": 0.05, - "frames": [ - { - "index": 7 - }, - { - "index": 8 - }, - { - "index": 9 - }, - { - "index": 10 - }, - { - "index": 11 - } - ] - }, - "ChargeParticle": { - "delay": 0.03, - "loop": true, - "frames": [ - { - "index": 12 - }, - { - "index": 13 - }, - { - "index": 1 - }, - { - "index": 3 - }, - { - "index": 14 - }, - { - "index": 13 - }, - { - "index": 12 - } - ] - }, - "Poof": { - "delay": 0.05, - "loop": true, - "frames": [ - { - "index": 23 - }, - { - "index": 24 - }, - { - "index": 25 - }, - { - "index": 26 - }, - { - "index": 27 - } - ] - } + "Fireball": + { + "delay": 0.1, + "frames": + [ + { + "index": 0 + }, + { + "index": 1 + }, + { + "index": 2 + }, + { + "index": 1 + }, + { + "index": 0 + } + ] + }, + "Smoke": + { + "delay": 0.05, + "loop": true, + "frames": + [ + { + "index": 4 + }, + { + "index": 5 + }, + { + "index": 6 + } + ] + }, + "GreenDiamond": + { + "delay": 0.05, + "frames": + [ + { + "index": 7 + }, + { + "index": 8 + }, + { + "index": 9 + }, + { + "index": 10 + }, + { + "index": 11 + } + ] + }, + "ChargeParticle": + { + "delay": 0.03, + "loop": true, + "frames": + [ + { + "index": 12 + }, + { + "index": 13 + }, + { + "index": 1 + }, + { + "index": 3 + }, + { + "index": 14 + }, + { + "index": 13 + }, + { + "index": 12 + } + ] + }, + "Poof": + { + "delay": 0.05, + "loop": true, + "frames": + [ + { + "index": 23 + }, + { + "index": 24 + }, + { + "index": 25 + }, + { + "index": 26 + }, + { + "index": 27 + } + ] + } } diff --git a/data/animations/Heroine.json b/data/animations/Heroine.json index 55ffb7d..ca47ea0 100644 --- a/data/animations/Heroine.json +++ b/data/animations/Heroine.json @@ -1,253 +1,283 @@ { - "Stand": { - "type": "Stand", - "delay": 1, - "frames": [ - { - "index": 1, - "duration": 4 - }, - { - "index": 3, - "duration": 0.1 - }, - { - "index": 1, - "duration": 0.1 - }, - { - "index": 3, - "duration": 0.1 - }, - { - "index": 1, - "duration": 2 - }, - { - "index": 0, - "duration": 2 - }, - { - "index": 1, - "duration": 0.1 - }, - { - "index": 2, - "duration": 2 - }, - { - "index": 1, - "duration": 3 - }, - { - "index": 3, - "duration": 0.1 - }, - { - "index": 1, - "duration": 0.1 - }, - { - "index": 3, - "duration": 0.1 - }, - { - "index": 1, - "duration": 2 - }, - { - "index": 0, - "duration": 4 - }, - { - "index": 1, - "duration": 0.1 - }, - { - "index": 2, - "duration": 3 - }, - { - "index": 1, - "duration": 0.1 - }, - { - "index": 0, - "duration": 1 - }, - { - "index": 1, - "duration": 2 - }, - { - "index": 3, - "duration": 0.1 - }, - { - "index": 1, - "duration": 0.1 - }, - { - "index": 3, - "duration": 0.1 - } - ] - }, - "Blink": { - "type": "Stand", - "next": "Stand", - "delay": 0.25, - "frames": [ - { - "index": 3, - "duration": 0.25 - } - ] - }, - "Run": { - "type": "Run", - "delay": 0.25, - "frames": [ - { - "index": 4 - }, - { - "index": 5 - }, - { - "index": 6 - }, - { - "index": 7 - } - ] - }, - "StopRunning": { - "type": "Stand", - "next": "Stand", - "delay": 10, - "loop": true, - "frames": [ - { - "index": 8 - } - ] - }, - "Jump": { - "type": "Jump", - "next": "FlyDiagonallyUp", - "delay": 0.25, - "frames": [ - { - "index": 9, - "duration": 0.25 - } - ] - }, - "Land": { - "type": "Stand", - "next": "StopRunning", - "delay": 0.5, - "frames": [ - { - "index": 9, - "duration": 0.25 - } - ] - }, - "FlyDiagonallyUp": { - "type": "Fly", - "delay": 0.1, - "frames": [ - { - "index": 10 - }, - { - "index": 11 - } - ] - }, - "FlyDiagonallyDown": { - "type": "Fly", - "delay": 0.1, - "frames": [ - { - "index": 12 - }, - { - "index": 13 - } - ] - }, - "FlyStraightUp": { - "type": "Fly", - "delay": 0.1, - "frames": [ - { - "index": 0 - } - ] - }, - "FlyHorizontally": { - "type": "Fly", - "delay": 0.1, - "frames": [ - { - "index": 4 - }, - { - "index": 14 - } - ] - }, - "KnockedDown": { - "type": "Hit", - "delay": 0.1, - "frames": [ - { - "index": 17 - }, - { - "index": 18 - } - ] - }, - "Flattened": { - "type": "Hit", - "delay": 1, - "frames": [ - { - "index": 19 - } - ] - }, - "StartCharging": { - "type": "Charge", - "next": "Charge", - "delay": 0.2, - "frames": [ - { - "index": 21 - } - ] - }, - "Charge": { - "type": "Charge", - "delay": 0.2, - "loop": true, - "frames": [ - { - "index": 22 - } - ] - }, - "FireCharge": { - "type": "Charge", - "delay": 0.2, - "frames": [ - { - "index": 23 - } - ] - } + "Stand": + { + "type": "Stand", + "delay": 1, + "frames": + [ + { + "index": 1, + "duration": 4 + }, + { + "index": 3, + "duration": 0.1 + }, + { + "index": 1, + "duration": 0.1 + }, + { + "index": 3, + "duration": 0.1 + }, + { + "index": 1, + "duration": 2 + }, + { + "index": 0, + "duration": 2 + }, + { + "index": 1, + "duration": 0.1 + }, + { + "index": 2, + "duration": 2 + }, + { + "index": 1, + "duration": 3 + }, + { + "index": 3, + "duration": 0.1 + }, + { + "index": 1, + "duration": 0.1 + }, + { + "index": 3, + "duration": 0.1 + }, + { + "index": 1, + "duration": 2 + }, + { + "index": 0, + "duration": 4 + }, + { + "index": 1, + "duration": 0.1 + }, + { + "index": 2, + "duration": 3 + }, + { + "index": 1, + "duration": 0.1 + }, + { + "index": 0, + "duration": 1 + }, + { + "index": 1, + "duration": 2 + }, + { + "index": 3, + "duration": 0.1 + }, + { + "index": 1, + "duration": 0.1 + }, + { + "index": 3, + "duration": 0.1 + } + ] + }, + "Blink": + { + "type": "Stand", + "next": "Stand", + "delay": 0.25, + "frames": + [ + { + "index": 3, + "duration": 0.25 + } + ] + }, + "Run": + { + "type": "Run", + "delay": 0.25, + "frames": + [ + { + "index": 4 + }, + { + "index": 5 + }, + { + "index": 6 + }, + { + "index": 7 + } + ] + }, + "StopRunning": + { + "type": "Stand", + "next": "Stand", + "delay": 10, + "loop": true, + "frames": + [ + { + "index": 8 + } + ] + }, + "Jump": + { + "type": "Jump", + "next": "FlyDiagonallyUp", + "delay": 0.25, + "frames": + [ + { + "index": 9, + "duration": 0.25 + } + ] + }, + "Land": + { + "type": "Stand", + "next": "StopRunning", + "delay": 0.5, + "frames": + [ + { + "index": 9, + "duration": 0.25 + } + ] + }, + "FlyDiagonallyUp": + { + "type": "Fly", + "delay": 0.1, + "frames": + [ + { + "index": 10 + }, + { + "index": 11 + } + ] + }, + "FlyDiagonallyDown": + { + "type": "Fly", + "delay": 0.1, + "frames": + [ + { + "index": 12 + }, + { + "index": 13 + } + ] + }, + "FlyStraightUp": + { + "type": "Fly", + "delay": 0.1, + "frames": + [ + { + "index": 0 + } + ] + }, + "FlyHorizontally": + { + "type": "Fly", + "delay": 0.1, + "frames": + [ + { + "index": 4 + }, + { + "index": 14 + } + ] + }, + "KnockedDown": + { + "type": "Hit", + "delay": 0.1, + "frames": + [ + { + "index": 17 + }, + { + "index": 18 + } + ] + }, + "Flattened": + { + "type": "Hit", + "delay": 1, + "frames": + [ + { + "index": 19 + } + ] + }, + "StartCharging": + { + "type": "Charge", + "next": "Charge", + "delay": 0.2, + "frames": + [ + { + "index": 21 + } + ] + }, + "Charge": + { + "type": "Charge", + "delay": 0.2, + "loop": true, + "frames": + [ + { + "index": 22 + } + ] + }, + "FireCharge": + { + "type": "Charge", + "delay": 0.2, + "frames": + [ + { + "index": 23 + } + ] + } } diff --git a/data/animations/Jetbot.json b/data/animations/Jetbot.json index 240641a..f5f3152 100644 --- a/data/animations/Jetbot.json +++ b/data/animations/Jetbot.json @@ -1,179 +1,209 @@ { - "Stand": { - "type": "Stand", - "delay": 1, - "frames": [ - { - "index": 0, - "duration": 2 - }, - { - "index": 1, - "duration": 0.25 - }, - { - "index": 2, - "duration": 2 - }, - { - "index": 1, - "duration": 0.25 - } - ] - }, - "Run": { - "type": "Run", - "delay": 0.1, - "frames": [ - { - "index": 3 - }, - { - "index": 4 - } - ] - }, - "StopRunning": { - "type": "Stand", - "next": "Stand", - "delay": 10, - "loop": true, - "frames": [ - { - "index": 6 - } - ] - }, - "Jump": { - "type": "Jump", - "next": "FlyDiagonallyUp", - "delay": 0.25, - "frames": [ - { - "index": 6 - } - ] - }, - "Land": { - "type": "Stand", - "next": "Stand", - "delay": 1, - "loop": true, - "frames": [ - { - "index": 6, - "duration": 0.25 - }, - { - "index": 0, - "duration": 0.25 - } - ] - }, - "FlyDiagonallyUp": { - "type": "Fly", - "delay": 0.1, - "frames": [ - { - "index": 3 - }, - { - "index": 4 - } - ] - }, - "FlyDiagonallyDown": { - "type": "Fly", - "delay": 0.1, - "frames": [ - { - "index": 3 - }, - { - "index": 4 - } - ] - }, - "FlyStraightUp": { - "type": "Fly", - "delay": 0.1, - "frames": [ - { - "index": 3 - }, - { - "index": 4 - } - ] - }, - "FlyHorizontally": { - "type": "Fly", - "delay": 0.1, - "frames": [ - { - "index": 3 - }, - { - "index": 4 - } - ] - }, - "Punch": { - "type": "Attack", - "next": "Stand", - "delay": 0.05, - "frames": [ - { - "index": 3 - } - ] - }, - "StartFiring": { - "type": "Attack", - "next": "Fire", - "delay": 0.1, - "frames": [ - { - "index": 3 - } - ] - }, - "Fire": { - "type": "Attack", - "delay": 1, - "frames": [ - { - "index": 3, - "duration": 0.2 - } - ] - }, - "StopFiring": { - "type": "Attack", - "next": "Stand", - "delay": 0.1, - "frames": [ - { - "index": 3 - } - ] - }, - "KnockedDown": { - "type": "Hit", - "delay": 1, - "frames": [ - { - "index": 5 - } - ] - }, - "Flattened": { - "type": "Hit", - "delay": 1, - "frames": [ - { - "index": 6 - } - ] - } + "Stand": + { + "type": "Stand", + "delay": 1, + "frames": + [ + { + "index": 0, + "duration": 2 + }, + { + "index": 1, + "duration": 0.25 + }, + { + "index": 2, + "duration": 2 + }, + { + "index": 1, + "duration": 0.25 + } + ] + }, + "Run": + { + "type": "Run", + "delay": 0.1, + "frames": + [ + { + "index": 3 + }, + { + "index": 4 + } + ] + }, + "StopRunning": + { + "type": "Stand", + "next": "Stand", + "delay": 10, + "loop": true, + "frames": + [ + { + "index": 6 + } + ] + }, + "Jump": + { + "type": "Jump", + "next": "FlyDiagonallyUp", + "delay": 0.25, + "frames": + [ + { + "index": 6 + } + ] + }, + "Land": + { + "type": "Stand", + "next": "Stand", + "delay": 1, + "loop": true, + "frames": + [ + { + "index": 6, + "duration": 0.25 + }, + { + "index": 0, + "duration": 0.25 + } + ] + }, + "FlyDiagonallyUp": + { + "type": "Fly", + "delay": 0.1, + "frames": + [ + { + "index": 3 + }, + { + "index": 4 + } + ] + }, + "FlyDiagonallyDown": + { + "type": "Fly", + "delay": 0.1, + "frames": + [ + { + "index": 3 + }, + { + "index": 4 + } + ] + }, + "FlyStraightUp": + { + "type": "Fly", + "delay": 0.1, + "frames": + [ + { + "index": 3 + }, + { + "index": 4 + } + ] + }, + "FlyHorizontally": + { + "type": "Fly", + "delay": 0.1, + "frames": + [ + { + "index": 3 + }, + { + "index": 4 + } + ] + }, + "Punch": + { + "type": "Attack", + "next": "Stand", + "delay": 0.05, + "frames": + [ + { + "index": 3 + } + ] + }, + "StartFiring": + { + "type": "Attack", + "next": "Fire", + "delay": 0.1, + "frames": + [ + { + "index": 3 + } + ] + }, + "Fire": + { + "type": "Attack", + "delay": 1, + "frames": + [ + { + "index": 3, + "duration": 0.2 + } + ] + }, + "StopFiring": + { + "type": "Attack", + "next": "Stand", + "delay": 0.1, + "frames": + [ + { + "index": 3 + } + ] + }, + "KnockedDown": + { + "type": "Hit", + "delay": 1, + "frames": + [ + { + "index": 5 + } + ] + }, + "Flattened": + { + "type": "Hit", + "delay": 1, + "frames": + [ + { + "index": 6 + } + ] + } } diff --git a/data/animations/RobotTrooper.json b/data/animations/RobotTrooper.json index ed68a9b..fcdf579 100644 --- a/data/animations/RobotTrooper.json +++ b/data/animations/RobotTrooper.json @@ -1,203 +1,233 @@ { - "Stand": { - "type": "Stand", - "delay": 1, - "frames": [ - { - "index": 0, - "duration": 2 - }, - { - "index": 1, - "duration": 0.25 - }, - { - "index": 2, - "duration": 2 - }, - { - "index": 1, - "duration": 0.25 - } - ] - }, - "Run": { - "type": "Run", - "delay": 0.25, - "frames": [ - { - "index": 4 - }, - { - "index": 5 - }, - { - "index": 6 - }, - { - "index": 7 - } - ] - }, - "StopRunning": { - "type": "Stand", - "next": "Stand", - "delay": 10, - "loop": true, - "frames": [ - { - "index": 5 - } - ] - }, - "Jump": { - "type": "Jump", - "next": "FlyDiagonallyUp", - "delay": 0.25, - "frames": [ - { - "index": 17 - } - ] - }, - "Land": { - "type": "Stand", - "next": "Stand", - "delay": 1, - "loop": true, - "frames": [ - { - "index": 19, - "duration": 0.25 - }, - { - "index": 14, - "duration": 0.25 - } - ] - }, - "FlyDiagonallyUp": { - "type": "Fly", - "delay": 0.1, - "frames": [ - { - "index": 18 - } - ] - }, - "FlyDiagonallyDown": { - "type": "Fly", - "delay": 0.1, - "frames": [ - { - "index": 18 - } - ] - }, - "FlyStraightUp": { - "type": "Fly", - "delay": 0.1, - "frames": [ - { - "index": 18 - } - ] - }, - "FlyHorizontally": { - "type": "Fly", - "frames": [ - { - "index": 18 - } - ] - }, - "Punch": { - "type": "Attack", - "next": "Stand", - "delay": 0.05, - "frames": [ - { - "index": 8 - }, - { - "index": 9 - }, - { - "index": 10 - }, - { - "index": 11 - }, - { - "index": 12 - }, - { - "index": 13 - } - ] - }, - "StartFiring": { - "type": "Attack", - "next": "Fire", - "delay": 0.1, - "frames": [ - { - "index": 14 - }, - { - "index": 15 - }, - { - "index": 16 - } - ] - }, - "Fire": { - "type": "Attack", - "delay": 1, - "frames": [ - { - "index": 17, - "duration": 0.2 - }, - { - "index": 16, - "duration": 0.2 - } - ] - }, - "StopFiring": { - "type": "Attack", - "next": "Stand", - "delay": 0.1, - "frames": [ - { - "index": 16 - }, - { - "index": 15 - }, - { - "index": 14 - } - ] - }, - "KnockedDown": { - "type": "Hit", - "delay": 1, - "frames": [ - { - "index": 18 - } - ] - }, - "Flattened": { - "type": "Hit", - "delay": 1, - "frames": [ - { - "index": 19 - } - ] - } + "Stand": + { + "type": "Stand", + "delay": 1, + "frames": + [ + { + "index": 0, + "duration": 2 + }, + { + "index": 1, + "duration": 0.25 + }, + { + "index": 2, + "duration": 2 + }, + { + "index": 1, + "duration": 0.25 + } + ] + }, + "Run": + { + "type": "Run", + "delay": 0.25, + "frames": + [ + { + "index": 4 + }, + { + "index": 5 + }, + { + "index": 6 + }, + { + "index": 7 + } + ] + }, + "StopRunning": + { + "type": "Stand", + "next": "Stand", + "delay": 10, + "loop": true, + "frames": + [ + { + "index": 5 + } + ] + }, + "Jump": + { + "type": "Jump", + "next": "FlyDiagonallyUp", + "delay": 0.25, + "frames": + [ + { + "index": 17 + } + ] + }, + "Land": + { + "type": "Stand", + "next": "Stand", + "delay": 1, + "loop": true, + "frames": + [ + { + "index": 19, + "duration": 0.25 + }, + { + "index": 14, + "duration": 0.25 + } + ] + }, + "FlyDiagonallyUp": + { + "type": "Fly", + "delay": 0.1, + "frames": + [ + { + "index": 18 + } + ] + }, + "FlyDiagonallyDown": + { + "type": "Fly", + "delay": 0.1, + "frames": + [ + { + "index": 18 + } + ] + }, + "FlyStraightUp": + { + "type": "Fly", + "delay": 0.1, + "frames": + [ + { + "index": 18 + } + ] + }, + "FlyHorizontally": + { + "type": "Fly", + "frames": + [ + { + "index": 18 + } + ] + }, + "Punch": + { + "type": "Attack", + "next": "Stand", + "delay": 0.05, + "frames": + [ + { + "index": 8 + }, + { + "index": 9 + }, + { + "index": 10 + }, + { + "index": 11 + }, + { + "index": 12 + }, + { + "index": 13 + } + ] + }, + "StartFiring": + { + "type": "Attack", + "next": "Fire", + "delay": 0.1, + "frames": + [ + { + "index": 14 + }, + { + "index": 15 + }, + { + "index": 16 + } + ] + }, + "Fire": + { + "type": "Attack", + "delay": 1, + "frames": + [ + { + "index": 17, + "duration": 0.2 + }, + { + "index": 16, + "duration": 0.2 + } + ] + }, + "StopFiring": + { + "type": "Attack", + "next": "Stand", + "delay": 0.1, + "frames": + [ + { + "index": 16 + }, + { + "index": 15 + }, + { + "index": 14 + } + ] + }, + "KnockedDown": + { + "type": "Hit", + "delay": 1, + "frames": + [ + { + "index": 18 + } + ] + }, + "Flattened": + { + "type": "Hit", + "delay": 1, + "frames": + [ + { + "index": 19 + } + ] + } } diff --git a/data/tilemaps/AlienWarrior.json b/data/tilemaps/AlienWarrior.json index 471fed4..b1e409d 100644 --- a/data/tilemaps/AlienWarrior.json +++ b/data/tilemaps/AlienWarrior.json @@ -1,6 +1,6 @@ { - "TilesU": 8, - "TilesV": 4, - "MinFilter": Nearest, - "MagFilter": Nearest + "tiles_s": 8, + "tiles_t": 4, + "min_filter": "nearest", + "mag_filter": "nearest" } diff --git a/data/tilemaps/BackgroundFar.json b/data/tilemaps/BackgroundFar.json index 8780bea..564692b 100644 --- a/data/tilemaps/BackgroundFar.json +++ b/data/tilemaps/BackgroundFar.json @@ -1,8 +1,8 @@ { - "TilesU": 1, - "TilesV": 1, - "MinFilter": "Linear", - "MagFilter": "Linear", - "WrapU": "Clamp", - "WrapV": "Clamp" + "tiles_s": 1, + "tiles_t": 1, + "min_filter": "linear", + "mag_filter": "linear", + "wrap_s": "clamp", + "wrap_t": "clamp" } diff --git a/data/tilemaps/BackgroundNear.json b/data/tilemaps/BackgroundNear.json index 2ae0637..c6bb637 100644 --- a/data/tilemaps/BackgroundNear.json +++ b/data/tilemaps/BackgroundNear.json @@ -1,8 +1,8 @@ { - "TilesU": 1, - "TilesV": 1, - "MinFilter": "Linear", - "MagFilter": "Linear", - "WrapU": "Repeat", - "WrapV": "Repeat" + "tiles_s": 1, + "tiles_t": 1, + "min_filter": "linear", + "mag_filter": "linear", + "wrap_s": "repeat", + "wrap_t": "repeat" } diff --git a/data/tilemaps/BigExplosion.json b/data/tilemaps/BigExplosion.json index b57a190..3913ad4 100644 --- a/data/tilemaps/BigExplosion.json +++ b/data/tilemaps/BigExplosion.json @@ -1,8 +1,8 @@ { - "TilesU": 8, - "TilesV": 1, - "MinFilter": "Linear", - "MagFilter": "Linear", - "WrapU": "Clamp", - "WrapV": "Clamp" + "tiles_s": 8, + "tiles_t": 1, + "min_filter": "nearest", + "mag_filter": "nearest", + "wrap_s": "clamp", + "wrap_t": "clamp" } diff --git a/data/tilemaps/Bonuses.json b/data/tilemaps/Bonuses.json index 5c024d5..e5ac533 100644 --- a/data/tilemaps/Bonuses.json +++ b/data/tilemaps/Bonuses.json @@ -1,8 +1,8 @@ { - "TilesU": 8, - "TilesV": 4, - "MinFilter": "Linear", - "MagFilter": "Linear", - "WrapU": "Clamp", - "WrapV": "Clamp" + "tiles_s": 8, + "tiles_t": 4, + "min_filter": "nearest", + "mag_filter": "nearest", + "wrap_s": "clamp", + "wrap_t": "clamp" } diff --git a/data/tilemaps/Building.json b/data/tilemaps/Building.json index ebc6842..e5ac533 100644 --- a/data/tilemaps/Building.json +++ b/data/tilemaps/Building.json @@ -1,8 +1,8 @@ { - "TilesU": 8, - "TilesV": 4, - "MinFilter": "Nearest", - "MagFilter": "Nearest", - "WrapU": "Clamp", - "WrapV": "Clamp" + "tiles_s": 8, + "tiles_t": 4, + "min_filter": "nearest", + "mag_filter": "nearest", + "wrap_s": "clamp", + "wrap_t": "clamp" } diff --git a/data/tilemaps/Font.json b/data/tilemaps/Font.json index 8b1214b..57a341c 100644 --- a/data/tilemaps/Font.json +++ b/data/tilemaps/Font.json @@ -1,6 +1,6 @@ { - "TilesU": 8, - "TilesV": 8, - "MinFilter": "Nearest", - "MagFilter": "Nearest" + "tiles_s": 8, + "tiles_t": 8, + "min_filter": "nearest", + "mag_filter": "nearest" } diff --git a/data/tilemaps/Heroine.json b/data/tilemaps/Heroine.json index 3420a10..b1e409d 100644 --- a/data/tilemaps/Heroine.json +++ b/data/tilemaps/Heroine.json @@ -1,6 +1,6 @@ { - "TilesU": 8, - "TilesV": 4, - "MinFilter": "Nearest", - "MagFilter": "Nearest" + "tiles_s": 8, + "tiles_t": 4, + "min_filter": "nearest", + "mag_filter": "nearest" } diff --git a/data/tilemaps/Jetbot.json b/data/tilemaps/Jetbot.json index 52af3b0..bf95ae6 100644 --- a/data/tilemaps/Jetbot.json +++ b/data/tilemaps/Jetbot.json @@ -1,6 +1,6 @@ { - "TilesU": 4, - "TilesV": 2, - "MinFilter": "Nearest", - "MagFilter": "Nearest" + "tiles_s": 4, + "tiles_t": 2, + "min_filter": "nearest", + "mag_filter": "nearest" } diff --git a/data/tilemaps/Particles.json b/data/tilemaps/Particles.json index 5c024d5..e5ac533 100644 --- a/data/tilemaps/Particles.json +++ b/data/tilemaps/Particles.json @@ -1,8 +1,8 @@ { - "TilesU": 8, - "TilesV": 4, - "MinFilter": "Linear", - "MagFilter": "Linear", - "WrapU": "Clamp", - "WrapV": "Clamp" + "tiles_s": 8, + "tiles_t": 4, + "min_filter": "nearest", + "mag_filter": "nearest", + "wrap_s": "clamp", + "wrap_t": "clamp" } diff --git a/data/tilemaps/RobotTrooper.json b/data/tilemaps/RobotTrooper.json index 3420a10..b1e409d 100644 --- a/data/tilemaps/RobotTrooper.json +++ b/data/tilemaps/RobotTrooper.json @@ -1,6 +1,6 @@ { - "TilesU": 8, - "TilesV": 4, - "MinFilter": "Nearest", - "MagFilter": "Nearest" + "tiles_s": 8, + "tiles_t": 4, + "min_filter": "nearest", + "mag_filter": "nearest" } diff --git a/data/tilemaps/Scenery.json b/data/tilemaps/Scenery.json index 83339cf..ac6f951 100644 --- a/data/tilemaps/Scenery.json +++ b/data/tilemaps/Scenery.json @@ -1,8 +1,8 @@ { - "TilesU": 4, - "TilesV": 4, - "MinFilter": "Linear", - "MagFilter": "Linear", - "WrapU": "Repeat", - "WrapV": "Repeat" + "tiles_s": 4, + "tiles_t": 4, + "min_filter": "nearest", + "mag_filter": "nearest", + "wrap_s": "repeat", + "wrap_t": "repeat" } diff --git a/data/tilemaps/StatusBars.json b/data/tilemaps/StatusBars.json index 01b5ed0..1ff8dcd 100644 --- a/data/tilemaps/StatusBars.json +++ b/data/tilemaps/StatusBars.json @@ -1,6 +1,6 @@ { - "TilesU": 4, - "TilesV": 1, - "MinFilter": "Nearest", - "MagFilter": "Nearest" + "tiles_s": 4, + "tiles_t": 1, + "min_filter": "nearest", + "mag_filter": "nearest" } diff --git a/data/tilemaps/TowerBlock1.json b/data/tilemaps/TowerBlock1.json index 98e7587..1dbed9e 100644 --- a/data/tilemaps/TowerBlock1.json +++ b/data/tilemaps/TowerBlock1.json @@ -1,8 +1,8 @@ { - "TilesU": 4, - "TilesV": 4, - "MinFilter": "Linear", - "MagFilter": "Linear", - "WrapU": "Clamp", - "WrapV": "Clamp" + "tiles_s": 4, + "tiles_t": 4, + "min_filter": "nearest", + "mag_filter": "nearest", + "wrap_s": "clamp", + "wrap_t": "clamp" } diff --git a/data/tilemaps/Trees.json b/data/tilemaps/Trees.json index 247ec97..b2090e5 100644 --- a/data/tilemaps/Trees.json +++ b/data/tilemaps/Trees.json @@ -1,8 +1,8 @@ { - "TilesU": 2, - "TilesV": 1, - "MinFilter": "Linear", - "MagFilter": "Linear", - "WrapU": "Clamp", - "WrapV": "Clamp" + "tiles_s": 2, + "tiles_t": 1, + "min_filter": "nearest", + "mag_filter": "nearest", + "wrap_s": "clamp", + "wrap_t": "clamp" } diff --git a/data/yoinkrc b/data/yoinkrc index 102848b..2faf40d 100644 --- a/data/yoinkrc +++ b/data/yoinkrc @@ -1,16 +1,16 @@ /* C-style comments are allowed. */ { - "video.fullscreen": false, - "video.resizable": true, - "video.mode": [800, 600], + "engine.timestep": 0.01, + "input.grab": false, "video.colorbuffers": [8, 8, 8, 8], - "video.multisamplebuffers": 6, - "video.multisamplesamples": 6, "video.cursor": true, - "input.grab": false, "video.doublebuffer": true, - "video.swapcontrol": true, + "video.fullscreen": false, "video.maxfps": 45, - "video.printfps": true, - "engine.timestep": 0.01 + "video.mode": [800, 600], + "video.multisamplebuffers": 6, + "video.multisamplesamples": 6, + "video.resizable": true, + //"video.printfps": true, + "video.swapcontrol": true } diff --git a/doc/yoink.6.in b/doc/yoink.6.in index c5eec63..e712ef2 100644 --- a/doc/yoink.6.in +++ b/doc/yoink.6.in @@ -131,6 +131,10 @@ to an array with numbers 1024 and 768. The video size will be 1024x768. .PP Here is a list of some of the options available: .TP +.B engine.rngseed +The number value used as a seed for the random number generator. Set this to +make the game more predictable. This is typically only useful for debugging. +.TP .B engine.timestep The amount of time in seconds between each update of the physics state. A value of 0.01 or lower is ideal for accurate physics approximations. Values that are @@ -277,11 +281,10 @@ option. .br .SH BUGS .PP -No sound yet. The original game never had sound, but it would probably be a -good idea. +No sound yet. .PP -The pixelated graphics are actually intentional. It adds to the charm of the -game, don't you think? +The pixelated graphics are actually intentional. It adds to the old school +charm of the game, don't you think? .PP Send bug reports, patches, and love notes to: .br @@ -289,5 +292,5 @@ Charles McGarvey .SH AUTHOR .PP Neil Carter was the original creator of Yoink, his winning entry in the -uDevGames 2003 Mac game development contest. Charles McGarvey rewrote the game -with SDL and is the current maintainer. +uDevGames 2003 Mac game development contest. Charles McGarvey restored the game +and is the current maintainer. diff --git a/extra/yoink.ebuild b/extra/yoink.ebuild index 16a430c..76e1514 100644 --- a/extra/yoink.ebuild +++ b/extra/yoink.ebuild @@ -15,7 +15,8 @@ KEYWORDS="~amd64 ~ppc ~x86" IUSE="debug" RDEPEND="media-libs/libsdl[opengl] - media-libs/sdl-image[png]" + media-libs/sdl-image[png] + virtual/opengl" DEPEND="${RDEPEND} dev-util/pkgconfig" diff --git a/src/Character.hh b/src/Character.hh index b1965ce..2894c5e 100644 --- a/src/Character.hh +++ b/src/Character.hh @@ -50,13 +50,6 @@ public: Mf::Tilemap& getTilemap(); Mf::Animation& getAnimation(); - - struct Exception : public std::runtime_error - { - explicit Exception(const std::string& what_arg) : - std::runtime_error(what_arg) {} - }; - private: Mf::Tilemap tilemap; Mf::Animation animation; diff --git a/src/Makefile.am b/src/Makefile.am index 9ea7843..0826767 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,8 +5,10 @@ libmoof_la_SOURCES = \ Moof/Aabb.hh \ Moof/Animation.cc \ Moof/Animation.hh \ + Moof/Camera.hh \ Moof/ConvertUTF.c \ Moof/ConvertUTF.h \ + Moof/Cullable.hh \ Moof/Deserializer.cc \ Moof/Deserializer.hh \ Moof/Dispatcher.cc \ @@ -18,6 +20,7 @@ libmoof_la_SOURCES = \ Moof/Interpolator.hh \ Moof/Math.hh \ Moof/Mippleton.hh \ + Moof/OpenGL.cc \ Moof/OpenGL.hh \ Moof/Profiler.hh \ Moof/Random.cc \ diff --git a/src/Moof/Engine.cc b/src/Moof/Engine.cc index bcc336c..be8ca5f 100644 --- a/src/Moof/Engine.cc +++ b/src/Moof/Engine.cc @@ -28,7 +28,6 @@ #include // exit #include -#include #include #include @@ -48,26 +47,32 @@ namespace Mf { class Engine::EngineImpl { public: - EngineImpl(const std::string& name, int argc, char* argv[], - const std::string& configFile, Engine* outer) : - settings(argc, argv), - interface(outer) + EngineImpl(int argc, char* argv[], const std::string& configFile, + const std::string& name, const std::string& iconFile, + Engine* outer) : + interface(outer), + settings(argc, argv) { if (SDL_Init(SDL_INIT_EVERYTHING | SDL_INIT_EVENTTHREAD) != 0) { - throw std::runtime_error(SDL_GetError()); + throw Exception(SDL_GetError()); } if (FE_Init() != 0) { - throw std::runtime_error(FE_GetError()); + throw Exception(FE_GetError()); } - setSeed(); - settings.loadFromFile(configFile); - video = VideoPtr(new Video(name)); - video->makeActive(); + long randomSeed; + if (settings.get("engine.rngseed", randomSeed)) + { + setSeed(randomSeed); + } + else + { + setSeed(); + } double ts = 0.01; settings.get("engine.timestep", ts); @@ -79,11 +84,14 @@ public: printFps = false; settings.get("video.printfps", printFps); + + video = VideoPtr(new Video(name, iconFile)); + video->makeActive(); } ~EngineImpl() { - // The video object must be destroyed before we can shutdown SDL. + // the video object must be destroyed before we can shutdown SDL video.reset(); FE_Quit(); @@ -201,6 +209,8 @@ public: } + Engine* interface; + Settings settings; Dispatcher dispatcher; VideoPtr video; @@ -212,14 +222,13 @@ public: long fps; bool printFps; - - Engine* interface; }; -Engine::Engine(const std::string& name, int argc, char* argv[], - const std::string& configFile) : - impl_(new Engine::EngineImpl(name, argc, argv, configFile, this)) {} +Engine::Engine(int argc, char* argv[], const std::string& configFile, + const std::string& name, const std::string& iconFile) : + impl_(new Engine::EngineImpl(argc, argv, configFile, name, iconFile, this)) +{} Engine::~Engine() {} diff --git a/src/Moof/Engine.hh b/src/Moof/Engine.hh index 112b87e..2d7dfd6 100644 --- a/src/Moof/Engine.hh +++ b/src/Moof/Engine.hh @@ -29,6 +29,8 @@ #ifndef _MOOF_ENGINE_HH_ #define _MOOF_ENGINE_HH_ +#include + #include #include @@ -46,8 +48,8 @@ class Video; class Engine : public Singleton { public: - Engine(const std::string& name, int argc, char* argv[], - const std::string& configFile); + Engine(int argc, char* argv[], const std::string& configFile, + const std::string& name, const std::string& iconFile); virtual ~Engine(); int run(); @@ -66,6 +68,12 @@ public: virtual void draw(Scalar alpha); virtual void handleEvent(const Event& event); + struct Exception : std::runtime_error + { + explicit Exception(const std::string& what_arg) : + std::runtime_error(what_arg) {} + }; + private: class EngineImpl; boost::shared_ptr impl_; diff --git a/src/Moof/Math.hh b/src/Moof/Math.hh index 563746e..c4e3484 100644 --- a/src/Moof/Math.hh +++ b/src/Moof/Math.hh @@ -37,27 +37,28 @@ #include #include - -namespace Mf { +#include // GLscalar -// Basic types. +namespace Mf { -typedef float Scalar; ///< Scalar type. -typedef cml::vector2f Vector2; -typedef cml::vector3f Vector3; -typedef cml::vector4f Vector4; +typedef GLscalar Scalar; -typedef cml::matrix33f_c Matrix3; -typedef cml::matrix44f_c Matrix4; +typedef cml::vector< Scalar, cml::fixed<2> > Vector2; +typedef cml::vector< Scalar, cml::fixed<3> > Vector3; +typedef cml::vector< Scalar, cml::fixed<4> > Vector4; -typedef cml::quaternionf_p Quaternion; +typedef cml::matrix< Scalar, cml::fixed<3,3>, + cml::col_basis, cml::col_major > Matrix3; +typedef cml::matrix< Scalar, cml::fixed<4,4>, + cml::col_basis, cml::col_major > Matrix4; -typedef Vector4 Color; +typedef cml::quaternion< Scalar, cml::fixed<>, cml::vector_first, + cml::positive_cross > Quaternion; -const Scalar EPSILON = 0.000001f; +const Scalar EPSILON = 0.000001; /** * Check the equality of scalars with a certain degree of error allowed. diff --git a/src/Moof/OpenGL.cc b/src/Moof/OpenGL.cc new file mode 100644 index 0000000..6f223d1 --- /dev/null +++ b/src/Moof/OpenGL.cc @@ -0,0 +1,70 @@ + +/******************************************************************************* + + Copyright (c) 2009, Charles McGarvey + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +#include "OpenGL.hh" + + +#if USE_DOUBLE_PRECISION + +void (*glLoadMatrix)(const GLscalar*)(glLoadMatrixd); +void (*glMultMatrix)(const GLscalar*)(glMultMatrixd); + +void (*glColor3)(GLscalar, GLscalar, GLscalar)(glColor3d); +void (*glColor4)(GLscalar, GLscalar, GLscalar, GLscalar)(glColor4d); +void (*glColor3v)(const GLscalar*)(glColor3dv); +void (*glColor4v)(const GLscalar*)(glColor4dv); + +void (*glVertex2)(GLscalar, GLscalar)(glVertex2d); +void (*glVertex3)(GLscalar, GLscalar, GLscalar)(glVertex3d); +void (*glVertex4)(GLscalar, GLscalar, GLscalar, GLscalar)(glVertex4d); +void (*glVertex2v)(const GLscalar*)(glVertex2dv); +void (*glVertex3v)(const GLscalar*)(glVertex3dv); +void (*glVertex4v)(const GLscalar*)(glVertex4dv); + +#else + +void (*glLoadMatrix)(const GLscalar*)(glLoadMatrixf); +void (*glMultMatrix)(const GLscalar*)(glMultMatrixf); + +void (*glVertex2)(GLscalar, GLscalar)(glVertex2f); +void (*glVertex3)(GLscalar, GLscalar, GLscalar)(glVertex3f); +void (*glVertex4)(GLscalar, GLscalar, GLscalar, GLscalar)(glVertex4f); +void (*glVertex2v)(const GLscalar*)(glVertex2fv); +void (*glVertex3v)(const GLscalar*)(glVertex3fv); +void (*glVertex4v)(const GLscalar*)(glVertex4fv); + +void (*glColor3)(GLscalar, GLscalar, GLscalar)(glColor3f); +void (*glColor4)(GLscalar, GLscalar, GLscalar, GLscalar)(glColor4f); +void (*glColor3v)(const GLscalar*)(glColor3fv); +void (*glColor4v)(const GLscalar*)(glColor4fv); + +#endif + + +/** vim: set ts=4 sw=4 tw=80: *************************************************/ + diff --git a/src/Moof/OpenGL.hh b/src/Moof/OpenGL.hh index 0e793f6..6db55ce 100644 --- a/src/Moof/OpenGL.hh +++ b/src/Moof/OpenGL.hh @@ -31,6 +31,40 @@ #include + +/* Define to 1 if you want to use double precision floating-point numbers. */ +#define USE_DOUBLE_PRECISION 1 + + +#if USE_DOUBLE_PRECISION + +typedef GLdouble GLscalar; +#define GL_SCALAR GL_DOUBLE + +#else + +typedef GLfloat GLscalar; +#define GL_SCALAR GL_FLOAT + +#endif + + +extern void (*glLoadMatrix)(const GLscalar*); +extern void (*glMultMatrix)(const GLscalar*); + +extern void (*glColor3)(GLscalar, GLscalar, GLscalar); +extern void (*glColor4)(GLscalar, GLscalar, GLscalar, GLscalar); +extern void (*glColor3v)(const GLscalar*); +extern void (*glColor4v)(const GLscalar*); + +extern void (*glVertex2)(GLscalar, GLscalar); +extern void (*glVertex3)(GLscalar, GLscalar, GLscalar); +extern void (*glVertex4)(GLscalar, GLscalar, GLscalar, GLscalar); +extern void (*glVertex2v)(const GLscalar*); +extern void (*glVertex3v)(const GLscalar*); +extern void (*glVertex4v)(const GLscalar*); + + #endif // _MOOF_OPENGL_HH_ /** vim: set ts=4 sw=4 tw=80: *************************************************/ diff --git a/src/Moof/Scene.cc b/src/Moof/Scene.cc index f4dd1c0..5f4a440 100644 --- a/src/Moof/Scene.cc +++ b/src/Moof/Scene.cc @@ -123,7 +123,7 @@ class Scene::SceneImpl : public Mippleton glPushMatrix(); //std::cout << "transforming..." << std::endl; //std::cout << transformation << std::endl; - glMultMatrixf(transformation.data()); + glMultMatrix(transformation.data()); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); image.bind(); @@ -143,13 +143,13 @@ class Scene::SceneImpl : public Mippleton { glBegin(GL_TRIANGLE_FAN); glTexCoord2f(texCoords[0], texCoords[1]); - glVertex3f(xf, yf, 0.0f); + glVertex2f(xf, yf); glTexCoord2f(texCoords[2], texCoords[3]); - glVertex3f(xf+1.0, yf, 0.0f); + glVertex2f(xf+1.0, yf); glTexCoord2f(texCoords[4], texCoords[5]); - glVertex3f(xf+1.0, yf+1.0, 0.0f); + glVertex2f(xf+1.0, yf+1.0); glTexCoord2f(texCoords[6], texCoords[7]); - glVertex3f(xf, yf+1.0, 0.0f); + glVertex2f(xf, yf+1.0); glEnd(); } } @@ -174,7 +174,8 @@ class Scene::SceneImpl : public Mippleton Billboard(const Matrix4& transform, const std::string& textureName, SerializablePtr root) : Scenery(transform, textureName), - index(0) + index(0), + uScale(1) { std::map rootObj; @@ -190,6 +191,10 @@ class Scene::SceneImpl : public Mippleton index = Tilemap::Index(value); } } + if ((it = rootObj.find("u_scale")) != rootObj.end()) + { + (*it).second->get(uScale); + } } image.getTileCoords(index, texCoords); @@ -198,21 +203,28 @@ class Scene::SceneImpl : public Mippleton void draw(Scalar alpha) { glPushMatrix(); - glMultMatrixf(transformation.data()); + glMultMatrix(transformation.data()); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); image.bind(); + float increment = 1.0f / float(uScale); + int x; + float xf; + + for (x = 0, xf = 0.0f; x < uScale; x++, xf += increment) + { glBegin(GL_TRIANGLE_FAN); glTexCoord2f(texCoords[0], texCoords[1]); - glVertex2f(0.0f, 0.0f); + glVertex2f(xf, 0.0f); glTexCoord2f(texCoords[2], texCoords[3]); - glVertex2f(1.0f, 0.0f); + glVertex2f(xf+increment, 0.0f); glTexCoord2f(texCoords[4], texCoords[5]); - glVertex2f(1.0f, 1.0f); + glVertex2f(xf+increment, 1.0f); glTexCoord2f(texCoords[6], texCoords[7]); - glVertex2f(0.0f, 1.0f); + glVertex2f(xf, 1.0f); glEnd(); + } glPopMatrix(); } @@ -225,6 +237,7 @@ class Scene::SceneImpl : public Mippleton private: Tilemap::Index index; Scalar texCoords[8]; + long uScale; }; diff --git a/src/Moof/Settings.cc b/src/Moof/Settings.cc index d13302d..ccf690a 100644 --- a/src/Moof/Settings.cc +++ b/src/Moof/Settings.cc @@ -100,13 +100,13 @@ void Settings::loadFromFiles(const std::vector& filePaths, boost::replace_first(path, "$HOME", home); } - Deserializer deserializer(*it, true); - - std::cout << "Looking for a config file at " << path << std::endl; try { + Deserializer deserializer(*it, true); + SerializablePtr obj = deserializer.deserialize(); std::map map; + if (obj && obj->get(map)) { if (!precedence) diff --git a/src/Moof/Texture.cc b/src/Moof/Texture.cc index 44a0b42..8bd3c4a 100644 --- a/src/Moof/Texture.cc +++ b/src/Moof/Texture.cc @@ -26,7 +26,7 @@ *******************************************************************************/ -#include +#include // memcpy #include @@ -62,20 +62,25 @@ class Texture::TextureImpl : public Mippleton { if (object_) { + if (object_ == globalObject_) + { + globalObject_ = 0; + } + glDeleteTextures(1, &object_); object_ = 0; } } /** - * If the GL context was recreated, we probably need to reload the texture. - * This may involve reading it from disk again, but hopefully the OS was - * smart enough to cache it if the client has plenty of RAM. + * If the GL context was recreated, we need to reload the texture. This may + * involve reading it from disk again, but hopefully the OS was smart enough + * to cache it if the client has plenty of RAM. */ void contextRecreated(const Notification& note) { - unloadFromGL(); + object_ = globalObject_ = 0; uploadToGL(); } @@ -95,6 +100,29 @@ class Texture::TextureImpl : public Mippleton return value; } + + static void flipSurface(SDL_Surface* image) + { + unsigned char* pixels = (Uint8*)(image->pixels); + + unsigned pitch = image->pitch; + unsigned char line[pitch]; + + int yBegin = 0; + int yEnd = image->h - 1; + + if (SDL_MUSTLOCK(image)) SDL_LockSurface(image); + while (yBegin < yEnd) + { + memcpy(line, pixels + pitch * yBegin, pitch); + memcpy(pixels + pitch * yBegin, pixels + pitch * yEnd, pitch); + memcpy(pixels + pitch * yEnd, line, pitch); + yBegin++; + yEnd--; + } + if (SDL_MUSTLOCK(image)) SDL_UnlockSurface(image); + } + public: /** @@ -103,16 +131,17 @@ public: explicit TextureImpl(const std::string& name) : Mippleton(name), + surface_(0), width_(0), height_(0), mode_(0), minFilter_(GL_NEAREST), - maxFilter_(GL_NEAREST), - wrapU_(GL_CLAMP), - wrapV_(GL_CLAMP), + magFilter_(GL_NEAREST), + wrapS_(GL_CLAMP), + wrapT_(GL_CLAMP), object_(0) { - uploadToGL(); + loadFromFile(); // we want to know when the GL context is recreated Dispatcher::instance().addHandler("video.context_recreated", @@ -121,6 +150,11 @@ public: ~TextureImpl() { + if (surface_) + { + SDL_FreeSurface(surface_); + } + unloadFromGL(); Dispatcher::instance().removeHandler(this); @@ -139,10 +173,15 @@ public: int w = powerOfTwo(surface->w); int h = powerOfTwo(surface->h); + // 2. OpenGL textures make more sense within the coordinate system when + // they are "upside down," so let's flip it. + + flipSurface(surface); + // 1. OpenGL images must (generally) have dimensions of a power-of-two. // If this one doesn't, we can at least be more friendly by expanding // the dimensions so that they are, though there will be some empty - // space within the range of normal texture coordinates. It's better of + // space within the range of normal texture coordinates. It's better if // textures are the right size to begin with. SDL_Surface* image = SDL_CreateRGBSurface @@ -151,14 +190,14 @@ public: w, h, 32, #if SDL_BYTEORDER == SDL_LIL_ENDIAN - 0x000000FF, - 0x0000FF00, - 0x00FF0000, + 0x000000FF, + 0x0000FF00, + 0x00FF0000, 0xFF000000 #else 0xFF000000, - 0x00FF0000, - 0x0000FF00, + 0x00FF0000, + 0x0000FF00, 0x000000FF #endif ); @@ -187,27 +226,6 @@ public: SDL_SetAlpha(surface, savedFlags, savedAlpha); } - // 2. OpenGL textures make more sense within the coordinate system when - // they are "upside down," so let's flip it. - - Uint8 line[image->pitch]; - - Uint8 *pixels = static_cast(image->pixels); - Uint16 pitch = image->pitch; - int ybegin = 0; - int yend = image->h - 1; - - if (SDL_MUSTLOCK(image)) SDL_LockSurface(image); - while (ybegin < yend) - { - memcpy(line, pixels + pitch * ybegin, pitch); - memcpy(pixels + pitch * ybegin, pixels + pitch * yend, pitch); - memcpy(pixels + pitch * yend, line, pitch); - ybegin++; - yend--; - } - if (SDL_MUSTLOCK(image)) SDL_UnlockSurface(image); - return image; } @@ -217,7 +235,7 @@ public: * @return Image data. */ - SDL_Surface* loadImageData() + void loadFromFile() { SDL_Surface* surface; @@ -225,7 +243,7 @@ public: if (!surface) { - throw Texture::Exception("loading failed"); + throw Texture::Exception("loading from file failed"); } SDL_Surface* temp = prepareImageForGL(surface); @@ -233,7 +251,7 @@ public: if (!temp) { - throw Texture::Exception("image couldn't be prepared for GL"); + throw Texture::Exception("uploading to opengl failed"); } if (temp->format->BytesPerPixel == 3) @@ -247,13 +265,13 @@ public: else { SDL_FreeSurface(temp); - throw Texture::Exception("image is not the required 24 or 32 bpp"); + throw Texture::Exception("incompatible color mode"); } width_ = temp->w; height_ = temp->h; - return temp; + surface_ = temp; } @@ -266,11 +284,11 @@ public: { if (object_) { - // Already loaded. + // already loaded return; } - SDL_Surface* imageData = loadImageData(); + if (!surface_) loadFromFile(); glGenTextures(1, &object_); glBindTexture(GL_TEXTURE_2D, object_); @@ -280,17 +298,18 @@ public: GL_TEXTURE_2D, 0, mode_, - imageData->w, - imageData->h, + surface_->w, + surface_->h, 0, mode_, GL_UNSIGNED_BYTE, - imageData->pixels + surface_->pixels ); setProperties(); - SDL_FreeSurface(imageData); + SDL_FreeSurface(surface_); + surface_ = 0; } @@ -302,23 +321,70 @@ public: void setProperties() { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter_); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, maxFilter_); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapU_); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapV_); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter_); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS_); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT_); } + inline void setMinFilter(GLuint filter) + { + bind(); + minFilter_ = filter; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter_); + } + + inline void setMagFilter(GLuint filter) + { + bind(); + magFilter_ = filter; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter_); + } + + inline void setWrapS(GLuint wrap) + { + bind(); + wrapS_ = wrap; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS_); + } - unsigned width_; ///< Horizontal dimension of the image. - unsigned height_; ///< Vertical dimension. + inline void setWrapT(GLuint wrap) + { + bind(); + wrapT_ = wrap; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT_); + } - GLuint mode_; ///< Depth of the image, GL_RGB or GL_RGBA. - GLuint minFilter_; ///< Filter. - GLuint maxFilter_; ///< Filter. - GLuint wrapU_; ///< Wrapping behavior horizontally. - GLuint wrapV_; ///< Wrapping behavior vertically. - GLuint object_; ///< GL texture handle. + + inline void bind() + { + if (object_ == 0) + { + uploadToGL(); + } + if (object_ != globalObject_) + { + glBindTexture(GL_TEXTURE_2D, object_); + globalObject_ = object_; + } + } + + + SDL_Surface* surface_; + unsigned width_; ///< Horizontal dimension of the image. + unsigned height_; ///< Vertical dimension. + + GLuint mode_; ///< Depth of the image, GL_RGB or GL_RGBA. + GLuint minFilter_; ///< Minifcation filter. + GLuint magFilter_; ///< Magnification filter. + GLuint wrapS_; ///< Wrapping behavior horizontally. + GLuint wrapT_; ///< Wrapping behavior vertically. + + GLuint object_; ///< GL texture handle. + static GLuint globalObject_; ///< Global GL texture handle. }; +GLuint Texture::TextureImpl::globalObject_ = 0; + Texture::Texture(const std::string& name) : // pass through @@ -332,7 +398,8 @@ Texture::Texture(const std::string& name) : void Texture::bind() { - glBindTexture(GL_TEXTURE_2D, getObject()); + // pass through + impl_->bind(); } @@ -362,36 +429,32 @@ unsigned Texture::getHeight() void Texture::setMinFilter(GLuint filter) { - impl_->minFilter_ = filter; -} - -void Texture::setMaxFilter(GLuint filter) -{ - impl_->maxFilter_ = filter; + // pass through + impl_->setMinFilter(filter); } -void Texture::setWrapU(GLuint wrap) +void Texture::setMagFilter(GLuint filter) { - impl_->wrapU_ = wrap; + // pass through + impl_->setMagFilter(filter); } -void Texture::setWrapV(GLuint wrap) +void Texture::setWrapS(GLuint wrap) { - impl_->wrapV_ = wrap; + // pass through + impl_->setWrapS(wrap); } - -void Texture::applyChanges() +void Texture::setWrapT(GLuint wrap) { - bind(); - impl_->setProperties(); + // pass through + impl_->setWrapT(wrap); } std::string Texture::getPathToResource(const std::string& name) { - // TODO since this is a generic library class, more than PNG should be - // supported + // TODO named resources must be png for now return Resource::getPathToResource("textures/" + name + ".png"); } diff --git a/src/Moof/Texture.hh b/src/Moof/Texture.hh index e858093..2ab4710 100644 --- a/src/Moof/Texture.hh +++ b/src/Moof/Texture.hh @@ -38,8 +38,8 @@ #include -#include #include +#include namespace Mf { @@ -57,11 +57,9 @@ public: unsigned getHeight(); void setMinFilter(GLuint filter); - void setMaxFilter(GLuint filter); - void setWrapU(GLuint wrap); - void setWrapV(GLuint wrap); - - void applyChanges(); + void setMagFilter(GLuint filter); + void setWrapS(GLuint wrap); + void setWrapT(GLuint wrap); static std::string getPathToResource(const std::string& name); diff --git a/src/Moof/Tilemap.cc b/src/Moof/Tilemap.cc index 6accbd1..1bfbfbc 100644 --- a/src/Moof/Tilemap.cc +++ b/src/Moof/Tilemap.cc @@ -38,15 +38,51 @@ namespace Mf { class Tilemap::TilemapImpl : public Mippleton { + static GLint filterFromString(const std::string& filter) + { + if (filter == "linear") + { + return GL_LINEAR; + } + else if (filter == "nearest_mipmap_nearest") + { + return GL_NEAREST_MIPMAP_NEAREST; + } + else if (filter == "nearest_mipmap_linear") + { + return GL_NEAREST_MIPMAP_LINEAR; + } + else if (filter == "linear_mipmap_nearest") + { + return GL_LINEAR_MIPMAP_NEAREST; + } + else if (filter == "linear_mipmap_linear") + { + return GL_LINEAR_MIPMAP_LINEAR; + } + + return GL_NEAREST; + } + + static GLint wrapFromString(const std::string& wrap) + { + if (wrap == "repeat") + { + return GL_REPEAT; + } + + return GL_CLAMP; + } + public: TilemapImpl(const std::string& name) : Mippleton(name), - tilesU_(1), - tilesV_(1), + magFilter_(GL_NEAREST), minFilter_(GL_NEAREST), - maxFilter_(GL_NEAREST), - wrapU_(GL_CLAMP), - wrapV_(GL_CLAMP) + nTilesS_(1), + nTilesT_(1), + wrapS_(GL_CLAMP), + wrapT_(GL_CLAMP) { loadFromFile(); } @@ -65,76 +101,64 @@ public: { std::map::iterator it; - if ((it = rootObj.find("TilesU")) != rootObj.end()) + if ((it = rootObj.find("tiles_s")) != rootObj.end()) { long value; if ((*it).second->get(value)) { - tilesU_ = unsigned(value); + nTilesS_ = unsigned(value); } } - if ((it = rootObj.find("TilesV")) != rootObj.end()) + if ((it = rootObj.find("tiles_t")) != rootObj.end()) { long value; if ((*it).second->get(value)) { - tilesV_ = unsigned(value); + nTilesT_ = unsigned(value); } } - if ((it = rootObj.find("MinFilter")) != rootObj.end()) + if ((it = rootObj.find("min_filter")) != rootObj.end()) { std::string value; if ((*it).second->get(value)) { - if (value == "Linear") - { - minFilter_ = GL_LINEAR; - } + minFilter_ = filterFromString(value); } } - if ((it = rootObj.find("MaxFilter")) != rootObj.end()) + if ((it = rootObj.find("mag_filter")) != rootObj.end()) { std::string value; if ((*it).second->get(value)) { - if (value == "Linear") - { - maxFilter_ = GL_LINEAR; - } + magFilter_ = filterFromString(value); } } - if ((it = rootObj.find("WrapU")) != rootObj.end()) + if ((it = rootObj.find("wrap_s")) != rootObj.end()) { std::string value; if ((*it).second->get(value)) { - if (value == "Repeat") - { - wrapU_ = GL_REPEAT; - } + wrapS_ = wrapFromString(value); } } - if ((it = rootObj.find("WrapV")) != rootObj.end()) + if ((it = rootObj.find("wrap_t")) != rootObj.end()) { std::string value; if ((*it).second->get(value)) { - if (value == "Repeat") - { - wrapV_ = GL_REPEAT; - } + wrapT_ = wrapFromString(value); } } } } } - unsigned tilesU_; - unsigned tilesV_; + GLuint magFilter_; GLuint minFilter_; - GLuint maxFilter_; - GLuint wrapU_; - GLuint wrapV_; + unsigned nTilesS_; + unsigned nTilesT_; + GLuint wrapS_; + GLuint wrapT_; }; @@ -142,25 +166,26 @@ Tilemap::Tilemap(const std::string& name) : Texture(name), impl_(Tilemap::TilemapImpl::retain(name), &Tilemap::TilemapImpl::release) { + bind(); + setMinFilter(impl_->minFilter_); - setMaxFilter(impl_->maxFilter_); - setWrapU(impl_->wrapU_); - setWrapV(impl_->wrapV_); - applyChanges(); + setMagFilter(impl_->magFilter_); + setWrapS(impl_->wrapS_); + setWrapT(impl_->wrapT_); } bool Tilemap::getTileCoords(unsigned index, Scalar coords[8]) { // make sure the index represents a real tile - if (index >= impl_->tilesU_ * impl_->tilesV_) return false; + if (index >= impl_->nTilesS_ * impl_->nTilesT_) return false; - Scalar w = 1.0 / Scalar(impl_->tilesU_); - Scalar h = 1.0 / Scalar(impl_->tilesV_); + Scalar w = 1.0 / Scalar(impl_->nTilesS_); + Scalar h = 1.0 / Scalar(impl_->nTilesT_); - coords[0] = Scalar(index % impl_->tilesU_) * w; - coords[1] = (Scalar(impl_->tilesV_ - 1) - - Scalar(index / impl_->tilesU_)) * h; + coords[0] = Scalar(index % impl_->nTilesS_) * w; + coords[1] = (Scalar(impl_->nTilesT_ - 1) - + Scalar(index / impl_->nTilesS_)) * h; coords[2] = coords[0] + w; coords[3] = coords[1]; coords[4] = coords[2]; diff --git a/src/Moof/Video.cc b/src/Moof/Video.cc index c41517e..0130d69 100644 --- a/src/Moof/Video.cc +++ b/src/Moof/Video.cc @@ -28,6 +28,8 @@ #include +#include + #include "Dispatcher.hh" #include "Serializable.hh" #include "Settings.hh" @@ -39,41 +41,29 @@ namespace Mf { Video::Video() { - std::string caption; - if (Settings::instance().get("video.caption", caption)) - { - init(attribs_, caption); - } - else - { - init(attribs_, "Untitled"); - } + init(attribs_); } -Video::Video(const Attributes& attribs, const std::string& caption) +Video::Video(const Attributes& attribs) { - init(attribs, caption); + init(attribs); } -Video::Video(const Attributes& attribs) +Video::Video(const std::string& caption, const std::string& icon) { - std::string caption; - if (Settings::instance().get("video.caption", caption)) + if (attribs_.caption == "Untitled") { - init(attribs, caption); + attribs_.caption = caption; } - else + if (attribs_.icon == "") { - init(attribs, "Untitled"); + attribs_.icon = icon; } -} -Video::Video(const std::string& caption) -{ - init(attribs_, caption); + init(attribs_); } -void Video::init(const Attributes& attribs, const std::string& caption) +void Video::init(const Attributes& attribs) { context_ = 0; flags_ = 0; @@ -82,7 +72,8 @@ void Video::init(const Attributes& attribs, const std::string& caption) setFull(attribs.fullscreen); setResizable(attribs.resizable); setOpenGLAttributes(); - setCaption(caption); + setCaption(attribs.caption); + setIcon(); setCursorVisible(attribs.cursorVisible); setCursorGrab(attribs.cursorGrab); setVideoMode(attribs.mode); @@ -163,14 +154,26 @@ bool Video::iconify() void Video::setCaption(const std::string& caption) { + attribs_.caption = caption; SDL_WM_SetCaption(caption.c_str(), 0); } +void Video::setIcon() +{ + if (attribs_.icon != "") + { + SDL_Surface* icon = IMG_Load(attribs_.icon.c_str()); + if (icon) + { + SDL_WM_SetIcon(icon, 0); + SDL_FreeSurface(icon); + } + } +} + std::string Video::getCaption() const { - char* str; - SDL_WM_GetCaption(&str, 0); - return std::string(str); + return attribs_.caption; } @@ -331,6 +334,12 @@ Video::Attributes::Attributes() Settings::instance().get("video.swapcontrol", swapControl); Settings::instance().get("video.hardwareonly", hardwareonly); + if (!Settings::instance().get("video.caption", caption)) + { + caption = "Untitled"; + } + Settings::instance().get("video.icon", icon); + std::vector dimensions; Settings::instance().get("video.mode", dimensions); if (dimensions.size() > 0) dimensions[0]->get(mode[0]); diff --git a/src/Moof/Video.hh b/src/Moof/Video.hh index a76dca2..bb1fdd4 100644 --- a/src/Moof/Video.hh +++ b/src/Moof/Video.hh @@ -45,32 +45,33 @@ public: struct Attributes { // OpenGL attributes - long colorBuffer[4]; // rgba - long frameBuffer; - bool doubleBuffer; - long depthBuffer; - long stencilBuffer; - long accumBuffer[4]; // rgba - bool stereo; - long multisampleBuffers; - long multisampleSamples; - bool swapControl; - bool hardwareonly; + long colorBuffer[4]; // rgba + long frameBuffer; + bool doubleBuffer; + long depthBuffer; + long stencilBuffer; + long accumBuffer[4]; // rgba + bool stereo; + long multisampleBuffers; + long multisampleSamples; + bool swapControl; + bool hardwareonly; // Window attributes - long mode[3]; // width, height, bpp - bool fullscreen; - bool resizable; - bool cursorVisible; - bool cursorGrab; + std::string caption; + std::string icon; + long mode[3]; // width, height, bpp + bool fullscreen; + bool resizable; + bool cursorVisible; + bool cursorGrab; Attributes(); }; Video(); - Video(const Attributes& attribs); - Video(const Attributes& attribs, const std::string& caption); - Video(const std::string& caption); + explicit Video(const Attributes& attribs); + explicit Video(const std::string& caption, const std::string& icon); ~Video(); void setVideoMode(const long mode[3]); @@ -109,10 +110,13 @@ public: }; private: - void init(const Attributes& attribs, const std::string& caption); + void init(const Attributes& attribs); + void recreateContext(); void setOpenGLAttributes(); + void setIcon(); + SDL_Surface* context_; unsigned flags_; Attributes attribs_; diff --git a/src/TilemapFont.hh b/src/TilemapFont.hh index 56a2d4b..04d9e1e 100644 --- a/src/TilemapFont.hh +++ b/src/TilemapFont.hh @@ -40,12 +40,6 @@ class TilemapFont : public Mf::Tilemap { public: - struct Exception : public std::runtime_error - { - explicit Exception(const std::string& what_arg) : - std::runtime_error(what_arg) {} - }; - TilemapFont(); void getTileCoords(char symbol, Mf::Scalar coords[8], diff --git a/src/YoinkApp.cc b/src/YoinkApp.cc index 5b034d7..232c097 100644 --- a/src/YoinkApp.cc +++ b/src/YoinkApp.cc @@ -64,24 +64,24 @@ static std::string configFiles() return files; } - -YoinkApp::YoinkApp(int argc, char* argv[]) : - Mf::Engine(PACKAGE_STRING, argc, argv, configFiles()) +static std::string iconFile() { - std::cout << PACKAGE_STRING << std::endl - << "Compiled " << __TIME__ " " __DATE__ << std::endl - << "Send requests, patches, and bug reports to <" - PACKAGE_BUGREPORT << ">." << std::endl << std::endl; - char* dataDir = getenv("YOINK_DATADIR"); + // first set up the search paths so we can find the icon and other resources if (dataDir) { Mf::Resource::addSearchPath(dataDir); } - Mf::Resource::addSearchPath(YOINK_DATADIR); + return Mf::Resource::getPathToResource("yoink.png"); +} + + +YoinkApp::YoinkApp(int argc, char* argv[]) : + Mf::Engine(argc, argv, configFiles(), PACKAGE_STRING, iconFile()) +{ Mf::Dispatcher::instance().addHandler("video.context_recreated", boost::bind(&YoinkApp::contextRecreated, this, _1), this); setupGL(); @@ -104,6 +104,8 @@ YoinkApp::YoinkApp(int argc, char* argv[]) : fadeIn.init(coeff, 0.5f); testScene = new Mf::Scene("Test"); + + x = y = z = 0.0; } YoinkApp::~YoinkApp() @@ -112,25 +114,29 @@ YoinkApp::~YoinkApp() delete font; Mf::Dispatcher::instance().removeHandler(this); - - std::cout << "Goodbye..." << std::endl; } void YoinkApp::setupGL() { glEnable(GL_TEXTURE_2D); + //glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glShadeModel(GL_SMOOTH); + glEnable(GL_POLYGON_SMOOTH); + + //int texSize; + //glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texSize); + //std::cout << "texture size: " << texSize << std::endl; //glEnable(GL_BLEND); //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.0); - glClearColor(0.0, 0.0, 1.0, 1.0); + glClearColor(1.0, 0.0, 0.0, 1.0); //glLineWidth(10.0f); } @@ -159,9 +165,9 @@ void YoinkApp::update(Mf::Scalar t, Mf::Scalar dt) void YoinkApp::draw(Mf::Scalar alpha) { - //Mf::vector4 meh; + //Mf::Vector4 meh; //meh.random(0.0, 1.0); - //static Mf::vector4 c1(meh); + //static Mf::Vector4 c1(meh); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -170,6 +176,7 @@ void YoinkApp::draw(Mf::Scalar alpha) //Mf::Scalar cosstate = std::cos(drawstate); + glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0, 1.33333, 1.0, 2000.0); @@ -186,12 +193,14 @@ void YoinkApp::draw(Mf::Scalar alpha) /* + glLoadIdentity(); + someChar->getTilemap().bind(); glColor3f(1.0, 1.0, 1.0); - unsigned heroFrame = someChar->getAnimation().getFrame(); + Mf::Tilemap::Index heroFrame = someChar->getAnimation().getFrame(); - float coords[8]; + Mf::Scalar coords[8]; someChar->getTilemap().getTileCoords(heroFrame, coords); glBegin(GL_QUADS); @@ -207,7 +216,7 @@ void YoinkApp::draw(Mf::Scalar alpha) someChar->getTilemap().getTileCoords(heroFrame, coords, - Mf::tilemap::reverse); + Mf::Tilemap::REVERSE); glBegin(GL_QUADS); glTexCoord2f(coords[0], coords[1]); @@ -223,7 +232,7 @@ void YoinkApp::draw(Mf::Scalar alpha) glColor4f(1.0,0.0,0.0,0.5); glBindTexture(GL_TEXTURE_2D, 0); - glColor4fv(c1.data()); + glColor4v(c1.data()); glRectd(-cosstate, -sinstate, sinstate, cosstate); glRectf(0.0f, 0.0f, sinstate, cosstate); @@ -273,13 +282,13 @@ void YoinkApp::draw(Mf::Scalar alpha) glBegin(GL_QUADS); glTexCoord2f(coords[0], coords[1]); - glVertex3f(0.0, -1.0, 0.0); + glVertex3(0.0, -1.0, 0.0); glTexCoord2f(coords[2], coords[3]); - glVertex3f(1.0, -1.0, 0.0); + glVertex3(1.0, -1.0, 0.0); glTexCoord2f(coords[4], coords[5]); - glVertex3f(1.0, 0.0, 0.0); + glVertex3(1.0, 0.0, 0.0); glTexCoord2f(coords[6], coords[7]); - glVertex3f(0.0, 0.0, 0.0); + glVertex3(0.0, 0.0, 0.0); glEnd(); glEnable(GL_BLEND); @@ -291,7 +300,7 @@ void YoinkApp::draw(Mf::Scalar alpha) glBegin(GL_LINES); glVertex2f(0.0f, 0.0f); - glVertex2fv(interp.getState(alpha).data()); + glVertex2v(interp.getState(alpha).data()); glEnd(); glColor4f(0.0f, 0.0f, 0.0f, fadeIn.getState(alpha)); @@ -358,8 +367,26 @@ void YoinkApp::handleEvent(const Mf::Event& event) int main(int argc, char* argv[]) { - YoinkApp app(argc, argv); - return app.run(); + std::cout << PACKAGE_STRING << std::endl + << "Compiled " << __TIME__ " " __DATE__ << std::endl + << "Send requests, patches, and bug reports to <" + PACKAGE_BUGREPORT << ">." << std::endl << std::endl; + + int status = 0; + + try + { + YoinkApp app(argc, argv); + status = app.run(); + } + catch (Mf::Engine::Exception e) + { + std::cerr << "Unhandled exception: " << e.what() << std::endl; + status = 1; + } + + std::cout << "Goodbye..." << std::endl; + return status; } /** vim: set ts=4 sw=4 tw=80: *************************************************/ -- 2.45.2