--- /dev/null
+{
+ "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
+ }
+ ]
+ }
+}
--- /dev/null
+{
+ "BigExplosion": {
+ "delay": 0.1,
+ "loop": true,
+ "frames": [
+ {
+ "index": 0
+ },
+ {
+ "index": 1
+ },
+ {
+ "index": 2
+ },
+ {
+ "index": 3
+ },
+ {
+ "index": 4
+ },
+ {
+ "index": 5
+ }
+ ]
+ }
+}
--- /dev/null
+{
+ "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
+ }
+ ]
+ }
+}
--- /dev/null
+{
+ "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
+ }
+ ]
+ }
+}
--- /dev/null
+{
+ "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
+ }
+ ]
+ }
+}
--- /dev/null
+{
+ "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
+ }
+ ]
+ }
+}
--- /dev/null
+{
+ "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
+ }
+ ]
+ }
+}
--- /dev/null
+{
+ "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
+ }
+ ]
+ }
+}
+++ /dev/null
-<?xml version="1.0" standalone="yes"?>
-<animation name="AlienWarrior" texture="AlienWarrior">
- <sequence name="Stand" type="Stand" delay="1">
- <frame index="0" duration="2"/>
- <frame index="1" duration="0.25"/>
- <frame index="2" duration="2"/>
- <frame index="1" duration="0.25"/>
- </sequence>
-
- <sequence name="Run" type="Run" delay="0.25">
- <frame index="3"/>
- <frame index="4"/>
- <frame index="5"/>
- <frame index="6"/>
- </sequence>
-
- <sequence name="StopRunning" type="Stand" delay="10" loop="false" next="Stand">
- <frame index="7"/>
- </sequence>
-
- <sequence name="Jump" type="Jump" delay="0.25" next="FlyDiagonallyUp">
- <frame index="17"/>
- </sequence>
-
- <sequence name="Land" type="Stand" delay="1" loop="false" next="Stand">
- <frame index="13"duration="0.25"/>
- </sequence>
-
- <sequence name="FlyDiagonallyUp" type="Fly" delay="0.1">
- <frame index="18"/>
- </sequence>
-
- <sequence name="FlyDiagonallyDown" type="Fly" delay="0.1">
- <frame index="19"/>
- </sequence>
-
- <sequence name="FlyStraightUp" type="Fly" delay="0.1">
- <frame index="19"/>
- </sequence>
-
- <sequence name="FlyHorizontally" type="Fly">
- <frame index="3"/>
- </sequence>
-
- <sequence name="Punch" type="Attack" delay="0.2">
- <frame index="8"/>
- <frame index="9"/>
- </sequence>
-
- <sequence name="StartFiring" type="Attack" delay="0.1" next="Fire">
- <frame index="0"/>
- <frame index="8"/>
- </sequence>
-
- <sequence name="Fire" type="Attack" delay="1">
- <frame index="10" duration="0.2"/>
- <frame index="11" duration="0.2"/>
- </sequence>
-
- <sequence name="StopFiring" type="Attack" delay="0.1" next="Stand">
- <frame index="8"/>
- <frame index="0"/>
- </sequence>
-
- <sequence name="KnockedDown" type="Hit" delay="0.1" loop="false">
- <frame index="16"/>
- <frame index="15"/>
- </sequence>
-
- <sequence name="Flattened" type="Hit" delay="1">
- <frame index="13"/>
- </sequence>
-</animation>
+++ /dev/null
-<?xml version="1.0" standalone="yes"?> \r<animation name="BigExplosion" texture="BigExplosion">\r <sequence name="BigExplosion" delay="0.1" loop="false">\r <frame index="0"/>\r <frame index="1"/>\r <frame index="2"/>\r <frame index="3"/>\r <frame index="4"/>\r <frame index="5"/>\r </sequence>\r</animation>\r
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" standalone="yes"?> \r<animation name="Bonuses" texture="Bonuses">\r <sequence name="SmallHealth" delay="0.1">\r <frame index="0"/>\r <frame index="1"/>\r <frame index="2"/>\r <frame index="1"/>\r </sequence>\r\r <sequence name="LargeHealth" delay="0.1">\r <frame index="3"/>\r <frame index="4"/>\r <frame index="5"/>\r <frame index="4"/>\r </sequence>\r\r <sequence name="SmallRedPotion" delay="0.1">\r <frame index="6"/>\r <frame index="7"/>\r <frame index="8"/>\r <frame index="7"/>\r </sequence>\r\r <sequence name="SmallBluePotion" delay="0.1">\r <frame index="9"/>\r <frame index="10"/>\r <frame index="11"/>\r <frame index="10"/>\r </sequence>\r\r <sequence name="FirstAidKit" delay="1.0">\r <frame index="12"/>\r </sequence>\r\r <sequence name="AlienFirstAidKit" delay="1.0">\r <frame index="13"/>\r </sequence>\r\r <sequence name="Cake" delay="1.0">\r <frame index="14"/>\r </sequence>\r\r <sequence name="FizzyDrink" delay="1.0">\r <frame index="15"/>\r </sequence>\r\r <sequence name="Cheese" delay="1.0">\r <frame index="16"/>\r </sequence>\r\r <sequence name="Chocolate" delay="1.0">\r <frame index="17"/>\r </sequence>\r\r <sequence name="MilkBottle" delay="1.0">\r <frame index="18"/>\r </sequence>\r\r <sequence name="OneSadCookie" delay="1.0">\r <frame index="19"/>\r </sequence>\r</animation>\r
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" standalone="yes"?> \r<animation name="Bullet" texture="Particles">\r <sequence name="Punch" delay="1.0">\r <!-- This punch sequence is highly bogus. Should be possible to have a sprite with no animation -->\r\r <frame index="31"/>\r </sequence>\r\r <sequence name="SmallBullet" delay="0.05">\r <frame index="16"/>\r <frame index="17"/>\r </sequence>\r\r <sequence name="MediumBullet" delay="0.05">\r <frame index="17"/>\r <frame index="18"/>\r </sequence>\r\r <sequence name="SmallFireball" delay="0.05">\r <frame index="0"/>\r <frame index="1"/>\r </sequence>\r\r <sequence name="MediumFireball" delay="0.05">\r <frame index="2"/>\r <frame index="1"/>\r </sequence>\r\r <sequence name="LargeFireball" delay="0.05">\r <frame index="21"/>\r <frame index="2"/>\r </sequence>\r</animation>\r
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" standalone="yes"?> \r<animation name="Effects" texture="Particles">\r <sequence name="Fireball" delay="0.1">\r <frame index="0"/>\r <frame index="1"/>\r <frame index="2"/>\r <frame index="1"/>\r <frame index="0"/>\r </sequence>\r\r <sequence name="Smoke" delay="0.05" loop="false">\r <frame index="4"/>\r <frame index="5"/>\r <frame index="6"/>\r </sequence>\r\r <sequence name="GreenDiamond" delay="0.05">\r <frame index="7"/>\r <frame index="8"/>\r <frame index="9"/>\r <frame index="10"/>\r <frame index="11"/>\r </sequence>\r\r <sequence name="ChargeParticle" delay="0.03" loop="false">\r <frame index="12"/>\r <frame index="13"/>\r <frame index="1"/>\r <frame index="3"/>\r <frame index="14"/>\r <frame index="13"/>\r <frame index="12"/>\r </sequence>\r\r <sequence name="Poof" delay="0.05" loop="false">\r <frame index="23"/>\r <frame index="24"/>\r <frame index="25"/>\r <frame index="26"/>\r <frame index="27"/>\r </sequence>\r</animation>\r
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" standalone="yes"?> \r<animation name="Heroine" texture="Heroine">\r <sequence name="Stand" type="Stand" delay="1">\r <frame index="1" duration="4.0"/>\r\r <frame index="3" duration="0.1"/>\r <frame index="1" duration="0.1"/>\r <frame index="3" duration="0.1"/>\r\r <frame index="1" duration="2.0"/>\r\r <frame index="0" duration="2.0"/>\r <frame index="1" duration="0.1"/>\r <frame index="2" duration="2.0"/>\r\r <frame index="1" duration="3.0"/>\r\r <frame index="3" duration="0.1"/>\r <frame index="1" duration="0.1"/>\r <frame index="3" duration="0.1"/>\r\r <frame index="1" duration="2.0"/>\r\r <frame index="0" duration="4.0"/>\r <frame index="1" duration="0.1"/>\r <frame index="2" duration="3.0"/>\r <frame index="1" duration="0.1"/>\r <frame index="0" duration="1.0"/>\r <frame index="1" duration="2.0"/>\r\r <frame index="3" duration="0.1"/>\r <frame index="1" duration="0.1"/>\r <frame index="3" duration="0.1"/>\r </sequence>\r\r <sequence name="Blink" type="Stand" delay="0.25" next="Stand">\r <frame index="3" duration="0.25"/>\r </sequence>\r\r <sequence name="Run" type="Run" delay="0.25">\r <frame index="4"/>\r <frame index="5"/>\r <frame index="6"/>\r <frame index="7"/>\r </sequence>\r\r <sequence name="StopRunning" type="Stand" delay="10" loop="false" next="Stand">\r <frame index="8"/>\r </sequence>\r\r <sequence name="Jump" type="Jump" delay="0.25" next="FlyDiagonallyUp">\r <frame index="9" duration="0.25"/>\r </sequence>\r\r <sequence name="Land" type="Stand" delay="0.5" next="StopRunning">\r <frame index="9" duration="0.25"/>\r </sequence>\r\r <sequence name="FlyDiagonallyUp" type="Fly" delay="0.1">\r <frame index="10"/>\r <frame index="11"/>\r </sequence>\r\r <sequence name="FlyDiagonallyDown" type="Fly" delay="0.1">\r <frame index="12"/>\r <frame index="13"/>\r </sequence>\r\r <sequence name="FlyStraightUp" type="Fly" delay="0.1">\r <frame index="0"/>\r </sequence>\r\r <sequence name="FlyHorizontally" type="Fly" delay="0.1">\r <frame index="4"/>\r <frame index="14"/>\r </sequence>\r\r <sequence name="KnockedDown" type="Hit" delay="0.1">\r <frame index="17"/>\r <frame index="18"/>\r </sequence>\r\r <sequence name="Flattened" type="Hit" delay="1.0">\r <frame index="19"/>\r </sequence>\r\r <sequence name="StartCharging" type="Charge" delay="0.2" next="Charge">\r <frame index="21"/>\r </sequence>\r\r <sequence name="Charge" type="Charge" delay="0.2" loop="false">\r <frame index="22"/>\r </sequence>\r\r <sequence name="FireCharge" type="Charge" delay="0.2">\r <frame index="23"/>\r </sequence>\r</animation>\r
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" standalone="yes"?> \r<animation name="Jetbot" texture="Jetbot">\r <sequence name="Stand" type="Stand" delay="1">\r <frame index="0" duration="2"/>\r <frame index="1" duration="0.25"/>\r <frame index="2" duration="2"/>\r <frame index="1" duration="0.25"/>\r </sequence>\r\r <sequence name="Run" type="Run" delay="0.1">\r <frame index="3"/>\r <frame index="4"/>\r </sequence>\r\r <sequence name="StopRunning" type="Stand" delay="10" loop="false" next="Stand">\r <frame index="6"/>\r </sequence>\r\r <sequence name="Jump" type="Jump" delay="0.25" next="FlyDiagonallyUp">\r <frame index="6"/>\r </sequence>\r\r <sequence name="Land" type="Stand" delay="1" loop="false" next="Stand">\r <frame index="6"duration="0.25"/>\r <frame index="0"duration="0.25"/>\r </sequence>\r\r <sequence name="FlyDiagonallyUp" type="Fly" delay="0.1">\r <frame index="3"/>\r <frame index="4"/>\r </sequence>\r\r <sequence name="FlyDiagonallyDown" type="Fly" delay="0.1">\r <frame index="3"/>\r <frame index="4"/>\r </sequence>\r\r <sequence name="FlyStraightUp" type="Fly" delay="0.1">\r <frame index="3"/>\r <frame index="4"/>\r </sequence>\r\r <sequence name="FlyHorizontally" type="Fly" delay="0.1">\r <frame index="3"/>\r <frame index="4"/>\r </sequence>\r\r <sequence name="Punch" type="Attack" delay="0.05" next="Stand">\r <frame index="3"/>\r </sequence>\r\r <sequence name="StartFiring" type="Attack" delay="0.1" next="Fire">\r <frame index="3"/>\r </sequence>\r\r <sequence name="Fire" type="Attack" delay="1.0">\r <frame index="3" duration="0.2"/>\r </sequence>\r\r <sequence name="StopFiring" type="Attack" delay="0.1" next="Stand">\r <frame index="3"/>\r </sequence>\r\r <sequence name="KnockedDown" type="Hit" delay="1.0">\r <frame index="5"/>\r </sequence>\r\r <sequence name="Flattened" type="Hit" delay="1.0">\r <frame index="6"/>\r </sequence>\r</animation>\r
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" standalone="yes"?> \r<animation name="RobotTrooper" texture="RobotTrooper">\r <sequence name="Stand" type="Stand" delay="1">\r <frame index="0" duration="2"/>\r <frame index="1" duration="0.25"/>\r <frame index="2" duration="2"/>\r <frame index="1" duration="0.25"/>\r </sequence>\r\r <sequence name="Run" type="Run" delay="0.25">\r <frame index="4"/>\r <frame index="5"/>\r <frame index="6"/>\r <frame index="7"/>\r </sequence>\r\r <sequence name="StopRunning" type="Stand" delay="10" loop="false" next="Stand">\r <frame index="5"/>\r </sequence>\r\r <sequence name="Jump" type="Jump" delay="0.25" next="FlyDiagonallyUp">\r <frame index="17"/>\r </sequence>\r\r <sequence name="Land" type="Stand" delay="1" loop="false" next="Stand">\r <frame index="19"duration="0.25"/>\r <frame index="14"duration="0.25"/>\r </sequence>\r\r <sequence name="FlyDiagonallyUp" type="Fly" delay="0.1">\r <frame index="18"/>\r </sequence>\r\r <sequence name="FlyDiagonallyDown" type="Fly" delay="0.1">\r <frame index="18"/>\r </sequence>\r\r <sequence name="FlyStraightUp" type="Fly" delay="0.1">\r <frame index="18"/>\r </sequence>\r\r <sequence name="FlyHorizontally" type="Fly">\r <frame index="18"/>\r </sequence>\r\r <sequence name="Punch" type="Attack" delay="0.05" next="Stand">\r <frame index="8"/>\r <frame index="9"/>\r <frame index="10"/>\r <frame index="11"/>\r <frame index="12"/>\r <frame index="13"/>\r </sequence>\r\r <sequence name="StartFiring" type="Attack" delay="0.1" next="Fire">\r <frame index="14"/>\r <frame index="15"/>\r <frame index="16"/>\r </sequence>\r\r <sequence name="Fire" type="Attack" delay="1.0">\r <frame index="17" duration="0.2"/>\r <frame index="16" duration="0.2"/>\r </sequence>\r\r <sequence name="StopFiring" type="Attack" delay="0.1" next="Stand">\r <frame index="16"/>\r <frame index="15"/>\r <frame index="14"/>\r </sequence>\r\r <sequence name="KnockedDown" type="Hit" delay="1.0">\r <frame index="18"/>\r </sequence>\r\r <sequence name="Flattened" type="Hit" delay="1.0">\r <frame index="19"/>\r </sequence>\r</animation>\r
\ No newline at end of file
random.hh \
rectangle.cc \
rectangle.hh \
+ resource.cc \
+ resource.hh \
serializable.cc \
serializable.hh \
serializer.cc \
texture.cc \
texture.hh \
thread.hh \
+ tilemap.hh \
timer.cc \
timer.hh \
vector.hh \
video.hh \
$(ENDLIST)
-libdc_a_CPPFLAGS = -I/usr/include/SDL -I$(top_srcdir)/yajl/src -O3
+libdc_a_CPPFLAGS = -I/usr/include/SDL -I$(top_srcdir)/yajl/src -Wall
#libdc_a_LDFLAGS = -lstdc++ -lSDL_image -lSDL_sound
libdc_a_LIBADD = $(top_srcdir)/yajl/libyajl.a
YoinkApp.hh \
$(ENDLIST)
-yoink_CPPFLAGS = -I/usr/include/SDL -O3
+yoink_CPPFLAGS = -I/usr/include/SDL -Wall
#yoink_LDFLAGS = -lstdc++ -lSDL_image -lSDL_sound
-yoink_LDADD = libdc.a ../yajl/libyajl.a
+yoink_LDADD = libdc.a libtinyxml.a ../yajl/libyajl.a
--- /dev/null
+
+/*******************************************************************************
+
+ 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 "animation.hh"
+
+
+namespace dc {
+
+
+class animation_impl
+{
+public:
+
+ class sequence
+ {
+ };
+
+ std::map<std::string,sequence> sequences;
+};
+
+
+
+
+} // namespace dc
+
--- /dev/null
+
+/*******************************************************************************
+
+ 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.
+
+*******************************************************************************/
+
+#ifndef _ANIMATION_HH_
+#define _ANIMATION_HH_
+
+/**
+ * @file animation.hh
+ * Motion picture!!
+ */
+
+#include <boost/shared_ptr.hpp>
+
+
+namespace dc {
+
+
+class animation_impl;
+
+class animation : public resource
+{
+public:
+ animation(const std::string& name);
+
+ void setSequence(const std::string& sequence);
+ bool isSequenceDone();
+
+ void update(scalar dt);
+ unsigned getFrame();
+
+private:
+ boost::shared_ptr<animation_impl> impl;
+};
+
+
+} // namespace dc
+
+#endif // _ANIMATION_HH_
+
void throwError()
{
unsigned char* errorMsg = yajl_get_error(hand, 0, 0, 0);
- deserializer::parser_error error((char*)errorMsg);
+ deserializer::exception error((char*)errorMsg);
yajl_free_error(hand, errorMsg);
throw error;
}
serializable* pullNext();
void pop();
- struct parser_error : std::runtime_error
+ struct exception : std::runtime_error
{
- explicit parser_error(const std::string& what_arg) :
+ explicit exception(const std::string& what_arg) :
std::runtime_error(what_arg) {}
};
--- /dev/null
+
+/*******************************************************************************
+
+ 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 <unistd.h>
+
+#include "resource.hh"
+
+
+namespace dc {
+
+
+std::vector<std::string> resource::searchPaths_;
+
+
+resource::resource(const std::string& name) throw(exception)
+{
+ filePath_ = getPathToResource(name);
+
+ if (!filePath_.empty())
+ {
+ throw exception("cannot find resource file " + name);
+ }
+}
+
+resource::~resource() {}
+
+
+const std::string& resource::getPathToFile()
+{
+ return filePath_;
+}
+
+void resource::addSearchPath(const std::string& directory)
+{
+ if (directory[directory.length() - 1] != '/')
+ {
+ searchPaths_.push_back(directory + '/');
+ }
+ else
+ {
+ searchPaths_.push_back(directory);
+ }
+}
+
+std::string resource::getPathToResource(const std::string& name)
+{
+ std::vector<std::string>::iterator i;
+
+ for (i = searchPaths_.begin(); i != searchPaths_.end(); i++)
+ {
+ const char* fullPath = ((*i) + name).c_str();
+ if (access(fullPath, R_OK) == 0)
+ {
+ return std::string(fullPath);
+ }
+ }
+
+ return std::string();
+}
+
+
+} // namespace dc
+
--- /dev/null
+
+/*******************************************************************************
+
+ 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.
+
+*******************************************************************************/
+
+#ifndef _RESOURCE_HH_
+#define _RESOURCE_HH_
+
+/**
+ * @file resource.hh
+ * Parent class of textures, sounds, other assets.
+ */
+
+#include <stdexcept>
+#include <string>
+#include <vector>
+
+
+namespace dc {
+
+
+/**
+ * Generic resource class.
+ */
+
+class resource
+{
+public:
+ struct exception : public std::runtime_error
+ {
+ explicit exception(const std::string& what_arg) :
+ std::runtime_error(what_arg) {}
+ };
+
+ resource(const std::string& name) throw(exception);
+ virtual ~resource();
+
+ /**
+ * Get the path of the file associated with this resource.
+ * @return Path.
+ */
+
+ const std::string& getPathToFile();
+
+
+ /**
+ * Add a directory to search when looking for resource files.
+ * @param directory Path to a directory.
+ */
+
+ static void addSearchPath(const std::string& directory);
+
+ /**
+ * Get the path to a resource of a given name.
+ * @param name Name of a resource. The name will be appended to each search
+ * directory in order.
+ * @return The first path found which resolves to a file.
+ */
+
+ static std::string getPathToResource(const std::string& name);
+
+private:
+ std::string filePath_;
+ static std::vector<std::string> searchPaths_;
+};
+
+
+} // namespace dc
+
+#endif // _RESOURCE_HH_
+
switch (err)
{
case yajl_gen_generation_complete:
- throw serializer::generator_error("the archive has already terminated");
+ throw serializer::exception("the archive has already terminated");
case yajl_gen_keys_must_be_strings:
- throw serializer::generator_error("map keys must be strings");
+ throw serializer::exception("map keys must be strings");
case yajl_max_depth_exceeded:
- throw serializer::generator_error("maximum archive depth exceeded");
+ throw serializer::exception("maximum archive depth exceeded");
case yajl_gen_in_error_state:
- throw serializer::generator_error("serializer already in error state");
+ throw serializer::exception("serializer already in error state");
}
}
void flush();
- struct generator_error : std::runtime_error
+ struct exception : std::runtime_error
{
- explicit generator_error(const std::string& what_arg) :
+ explicit exception(const std::string& what_arg) :
std::runtime_error(what_arg) {}
};
" does not contain any valid settings." << std::endl;
}
}
- catch (deserializer::parser_error e)
+ catch (deserializer::exception e)
{
std::cerr << "Cannot load settings from " << filePath <<
" because an exception was thrown: " << e.what() << std::endl;
template <typename T>
class singleton
{
- static T* ptr;
+ static T* ptr_;
public:
singleton()
{
- if (!ptr)
+ if (!ptr_)
{
// This hack is from Game Programming Gems.
long long offset = (long long)(T*)1 - (long long)(singleton<T>*)(T*)1;
- ptr = (T*)((long long)this + offset);
+ ptr_ = (T*)((long long)this + offset);
}
}
~singleton()
{
long long offset = (long long)(T*)1 - (long long)(singleton<T>*)(T*)1;
- if (ptr == (T*)((long long)this + offset))
+ if (ptr_ == (T*)((long long)this + offset))
{
- ptr = 0;
+ ptr_ = 0;
}
}
static T& instance()
{
- if (!ptr)
+ if (!ptr_)
{
throw std::runtime_error("accessing uninstantiated singleton");
}
- return *ptr;
+ return *ptr_;
}
- static T* instancePtr()
+ static T* instance__ptr()
{
- return ptr;
+ return ptr_;
}
};
-template <typename T> T* singleton<T>::ptr = 0;
+template <typename T> T* singleton<T>::ptr_ = 0;
#endif // _SINGLETON_HH_
*******************************************************************************/
-#include <stdexcept>
#include <cstdlib>
#include <boost/bind.hpp>
}
public:
- texture_impl(const std::string& filePath, bool keepInMemory)
- : object(0), imageData(0), imagePath(filePath), keepData(keepInMemory)
+ texture_impl(texture* outside, bool keepInMemory)
+ : interface(outside), keepData(keepInMemory), object(0), imageData(0)
{
dispatcher::instance().addHandler("video.context_recreated",
boost::bind(&texture_impl::contextRecreated, this, _1),
return value;
}
- // Adapted from some public domain code. This code is common enough that it
- // really should be included in SDL_image...
static SDL_Surface* prepareImageForGL(SDL_Surface* surface)
{
- /* Use the surface width and height expanded to powers of 2 */
+ // Adapted from some public domain code. This stuff is common enough
+ // that it really should be included in SDL_image... We need this
+ // because images loaded with SDL_image aren't exactly OpenGL-ready
+ // right out of the box.
+
int w = powerOfTwo(surface->w);
int h = powerOfTwo(surface->h);
+ // 1. OpenGL images must (generally) have dimensions of a power-of-two.
+
SDL_Surface* image = SDL_CreateRGBSurface
(
SDL_SWSURFACE,
w, h,
32,
-#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
0x000000FF,
0x0000FF00,
0x00FF0000,
return 0;
}
- // Save the alpha blending attributes.
Uint32 savedFlags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
Uint8 savedAlpha = surface->format->alpha;
if (savedFlags & SDL_SRCALPHA)
}
SDL_Rect srcArea, destArea;
- /* Copy the surface into the GL texture image */
srcArea.x = 0; destArea.x = 0;
- /* Copy it in at the bottom, because we're going to flip
- this image upside-down in a moment
- */
srcArea.y = 0; destArea.y = h - surface->h;
srcArea.w = surface->w;
srcArea.h = surface->h;
SDL_BlitSurface(surface, &srcArea, image, &destArea);
- /* Restore the alpha blending attributes */
if (savedFlags & SDL_SRCALPHA)
{
SDL_SetAlpha(surface, savedFlags, savedAlpha);
}
- /* Turn the image upside-down, because OpenGL textures
- start at the bottom-left, instead of the top-left
- */
+ // 2. OpenGL textures make more sense when they are "upside down."
+
Uint8 line[image->pitch];
- /* These two make the following more readable */
Uint8 *pixels = static_cast<Uint8*>(image->pixels);
Uint16 pitch = image->pitch;
int ybegin = 0;
int yend = image->h - 1;
- // TODO: consider if this lock is legal/appropriate
- if (SDL_MUSTLOCK(image)) { SDL_LockSurface(image); }
+ 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);
+ 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); }
+ if (SDL_MUSTLOCK(image)) SDL_UnlockSurface(image);
return image;
}
{
SDL_Surface* surface;
- surface = IMG_Load(imagePath.c_str());
+ surface = IMG_Load(interface->getPathToFile().c_str());
if (!surface)
{
- throw std::runtime_error("could not load image data from file");
+ throw texture::exception("loading failed");
}
imageData = prepareImageForGL(surface);
if (!imageData)
{
- throw std::runtime_error("error in preparing image data for GL");
+ throw texture::exception("");
}
if (imageData->format->BytesPerPixel == 3)
else
{
SDL_FreeSurface(imageData);
- throw std::runtime_error("image must be 24 or 32 bpp");
+ throw texture::exception("image is not the required 24 or 32 bpp");
}
width = imageData->w;
imageData->pixels
);
- // These default filters can be changed later...
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
if (!keepData)
{
int mode;
GLuint object;
- std::string imagePath;
bool keepData;
SDL_Surface* imageData;
+
+ texture* interface;
};
-texture::texture(const std::string& filePath, bool keepInMemory)
- : impl(new texture_impl(filePath, keepInMemory)) {}
-
-
-const std::string& texture::filePath()
-{
- return impl->imagePath;
-}
+texture::texture(const std::string& name, bool keepInMemory)
+ : resource(name), impl(new texture_impl(this, keepInMemory)) {}
void texture::bind()
{
- glBindTexture(GL_TEXTURE_2D, object());
+ glBindTexture(GL_TEXTURE_2D, getObject());
}
-GLuint texture::object()
+GLuint texture::getObject()
{
if (!impl->object)
{
}
-unsigned texture::width()
+unsigned texture::getWidth()
{
+ if (!impl->object)
+ {
+ impl->uploadToGL();
+ }
+
return impl->width;
}
-unsigned texture::height()
+unsigned texture::getHeight()
{
+ if (!impl->object)
+ {
+ impl->uploadToGL();
+ }
+
return impl->height;
}
-
} // namespace dc
#ifndef _TEXTURE_HH_
#define _TEXTURE_HH_
+/**
+ * @file texture.hh
+ * Image-loading and OpenGL texture loading.
+ */
+
+#include <stdexcept>
+
#include <boost/shared_ptr.hpp>
+#include "resource.hh"
#include "opengl.hh"
class texture_impl;
-class texture
+class texture : public resource
{
public:
- texture(const std::string& filePath, bool keepInMemory = false);
-
- const std::string& filePath();
+ texture(const std::string& name, bool keepInMemory = false);
void bind();
- GLuint object();
+ GLuint getObject();
+
+ unsigned getWidth();
+ unsigned getHeight();
- unsigned width();
- unsigned height();
+ struct exception : std::runtime_error
+ {
+ explicit exception(const std::string& what_arg) :
+ std::runtime_error(what_arg) {}
+ };
private:
boost::shared_ptr<texture_impl> impl;
--- /dev/null
+
+/*******************************************************************************
+
+ 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.
+
+*******************************************************************************/
+
+#ifndef _TILEMAP_HH_
+#define _TILEMAP_HH_
+
+/**
+ * @file tilemap.hh
+ * Small subclass to give some basic tile-mapping functionality to textures.
+ */
+
+#include <cassert>
+
+#include <boost/shared_ptr.hpp>
+
+#include "opengl.hh"
+#include "texture.hh"
+
+
+namespace dc {
+
+
+namespace tile {
+
+/**
+ * Possible orientations for texture coordinates.
+ */
+
+typedef enum
+{
+ normal = 0, ///< Normal orientation.
+ flip = 1, ///< Flip over a horizontal axis.
+ reverse = 2, ///< Flip over a vertical axis.
+ flip_and_reverse = 3 ///< Flip over both.
+} orientation;
+
+} // namespace tile
+
+
+/**
+ * A tilemap is a texture which is meant to be divided into smaller sprites.
+ * This class provides all the functionality of a texture and adds some methods
+ * to get texture coordinates to individual tiles within the tilemap. For
+ * simplicity, this class assumes square tiles.
+ */
+
+class tilemap : public texture
+{
+public:
+ tilemap(const std::string& filePath, bool keepInMemory = false,
+ unsigned tilesU = 1, unsigned tilesV = 1)
+ : texture(filePath, keepInMemory), tilesU_(tilesU), tilesV_(tilesV) {}
+
+
+ /**
+ * Set the number of rows and columns of square tiles.
+ * @param tilesU Columns of tiles.
+ * @param tilesV Rows of tiles.
+ */
+
+ void setTileDimensions(unsigned tilesU, unsigned tilesV)
+ {
+ tilesU_ = tilesU;
+ tilesV_ = tilesV;
+ }
+
+
+ /**
+ * Calculate texture coordinates for a tile at a certain index. Tiles are
+ * indexed start with zero as the to-left tile and moving across, then down.
+ * @param index The tile index.
+ * @param coords An array of floats where the texture coordinates will be
+ * stored after this call. The first coordinate (u,v) will be in the first
+ * two places and so on until all four coordinates are stored, therefore
+ * requiring enough room for an array of eight floats. The winding of the
+ * coordinates is always counter-clockwise (the GL default).
+ */
+
+ void getTileCoords(unsigned index, float coords[8])
+ {
+ assert(index < tilesU_ * tilesV_);
+
+ float w = 1.0 / float(tilesU_);
+ float h = 1.0 / float(tilesV_);
+
+ coords[0] = float(index % tilesU_) * w;
+ coords[1] = (float(tilesV_ - 1) - float(index / tilesU_)) * h;
+ coords[2] = coords[0] + w;
+ coords[3] = coords[1];
+ coords[4] = coords[2];
+ coords[5] = coords[1] + h;
+ coords[6] = coords[0];
+ coords[7] = coords[5];
+ }
+
+ /**
+ * This version let's you specify an orientation that will be reflected in
+ * the texture coordinates. This allows you to easily map a texture
+ * backwards or upside-down.
+ * @param what The orientation; can be flip, reverse, or flip_and_reverse.
+ */
+
+ void getTileCoords(unsigned index, float coords[8], tile::orientation what)
+ {
+ getTileCoords(index, coords);
+
+ if (what & tile::flip)
+ {
+ coords[1] = coords[5];
+ coords[5] = coords[3];
+ coords[3] = coords[7];
+ coords[7] = coords[5];
+ }
+ if (what & tile::reverse)
+ {
+ coords[0] = coords[2];
+ coords[2] = coords[6];
+ coords[4] = coords[6];
+ coords[6] = coords[0];
+ }
+ }
+
+private:
+ unsigned tilesU_;
+ unsigned tilesV_;
+};
+
+
+} // namespace dc
+
+#endif // _TILEMAP_HH_
+