Compare commits

..

131 Commits

Author SHA1 Message Date
Kayne Ruse 854dc0eb45 Added a link to the stable build 2014-04-08 21:24:49 +10:00
Kayne Ruse e90afb7e4a Merge branch 'net-map' 2014-04-08 21:13:17 +10:00
Kayne Ruse 0453f6becf The map paging is functional 2014-04-07 02:56:48 +10:00
Kayne Ruse c8a58ab515 Wrote a potentially buggy algorithm
This algorithm is designed to find the distance of a certain region,
however it may have been better to do a quick check, rather than worrying
how many regions were loaded at once.
2014-04-07 01:24:05 +10:00
Kayne Ruse 553f8dbfa5 Fixed some framerate issues 2014-04-06 20:53:51 +10:00
Kayne Ruse 2bacdcdab7 The basic server map is being displayed in the client 2014-04-06 03:38:58 +10:00
Kayne Ruse 99aecbfdbb The client->server->client region protocol is working 2014-04-06 02:48:43 +11:00
Kayne Ruse 27bda5dc28 Working on the client side map code (read more)
I've also added in some debug code to the map classes, because I was
hunting down a std::bad_alloc beingthrown. Turns out I forgot to set the
map sizes in the client's InWorld constructor. I'm committing the fix, and
the debug code.
2014-04-06 02:25:55 +11:00
Kayne Ruse 962f3f5dd0 Added "camera" 2014-04-05 01:56:05 +11:00
Kayne Ruse 41077b43b3 Merge branch 'network-map' 2014-03-31 21:54:22 +11:00
Kayne Ruse 4410ab892f Finished the region serial code 2014-03-31 21:40:50 +11:00
Kayne Ruse 60000cb0cf Minor tweak 2014-03-31 03:38:05 +11:00
Kayne Ruse 66b00255d5 Merge branch 'lua-api' into network-map 2014-03-31 01:32:39 +11:00
Kayne Ruse a5b68cf1fd Expaneded the lua API for Regions
I've added lua hooks for both pager functor classes. Hopefully, I haven't
missed any corner cases, because it took me a while to hunt everything
down. One issue is that the map's save directory needs to be set in the
Format class, but it'll do for now. I'll review this again when I've got
more than one map running at one time.

There should be enough here for a lua-driven map generator to be
implemented, even if it's a bit rough. I think I'll test this out in the
editor eventually, but getting the base branch's network map code going
comes first.

The current process is extremely convulted, so I need to document
everything that I've done so far, including C++ and lua functions.
2014-03-31 01:30:11 +11:00
Kayne Ruse 4cff57fe71 Established a connection between the Region objects and lua 2014-03-28 04:11:34 +11:00
Kayne Ruse 38b603fc8f Began working on the lua API for the map
The basic framework is done.
2014-03-28 03:24:14 +11:00
Kayne Ruse 47684380a9 I'm having trouble with the sequence of events 2014-03-26 00:30:10 +11:00
Kayne Ruse e4bfbfb906 Minor code tweaks, this needs a lot of forethought 2014-03-16 00:28:19 +11:00
Kayne Ruse 9db86c19f6 Implemented a macro for the serial buffer size 2014-03-15 23:36:31 +11:00
Kayne Ruse d5b551cec3 Reduced the footprint of the tiles
Also prepping for serializing the regions.
2014-03-15 23:02:21 +11:00
Kayne Ruse 7e500027e3 Loosened the requirements for constructing a MapPager
This is so that I can configure the size of the pages in the config.cfg
file.
2014-03-15 19:16:42 +11:00
Kayne Ruse dd786ba579 Merge branch 'server' (read more)
The only different between this commit and the currently stable branch is the
serialization code and a slight tweak to the server's startup sequence. I tried
to refactor the server, by moving the clientMap and playerMap into their own
wrapper classes, but that failed miserably. I need to stop getting so worked up
all the time, I've wasted way too much time already.
2014-03-11 19:04:32 +11:00
Kayne Ruse 5a57888305 Fixed the crash bug 2014-03-11 18:54:06 +11:00
Kayne Ruse 706aa5e1d7 Another worthless tweak 2014-03-10 23:56:47 +11:00
Kayne Ruse 19c1b1197d Added a brand new bug, I hate this branch 2014-03-10 23:15:57 +11:00
Kayne Ruse 5cf62f5517 Nothing special, just commiting minor changes 2014-03-09 01:51:17 +11:00
Kayne Ruse 56d02ad8d4 Working on reimplementing the player characters
I've also added EraseIf() to the manager classes.
2014-03-07 22:09:50 +11:00
Kayne Ruse 006a72174f Merge branch 'master' into server 2014-03-07 21:05:09 +11:00
Kayne Ruse 0cbc9dd9db Merge branch 'serial' into server (read more)
Conflicts:
	server/server_application.cpp (resolved)

After completing the serialization code, I'm merging it into the server's
development branch. This means that although the connection and
disconnection functionality work, I still need to test the player systems
from the new server with the new serialization code.

Immediately following this commit, I'll be merging the minor tweaks to the
editor from the master branch into this one.
2014-03-07 20:58:37 +11:00
Kayne Ruse 60c31ff56d Slight code tweak 2014-03-07 20:27:34 +11:00
Kayne Ruse 6a204643f6 Serialization is finally functional 2014-03-07 20:17:11 +11:00
Kayne Ruse 59285d1630 This isn't fucking working 2014-03-07 04:49:16 +11:00
Kayne Ruse a850d6b1af Added dummy serialization functions 2014-03-06 00:20:31 +11:00
Kayne Ruse f17fa0f345 Added lua, added db connection to PlayerManager
I've also revised the startup process a bit.
2014-03-05 00:27:21 +11:00
Kayne Ruse 756d4e770d Connection and disconnection are working correctly
I've dummied out the player code, so only the client connection code is
working. Otherwise the protocol hasn't changed.

I've also made a few other tweaks as I went along, but nothing really
major.
2014-03-04 02:48:47 +11:00
Kayne Ruse 7bb5e8ce0d Moving client and player data into manager classes
Remember: anything with "manager" in its name organizes a number of other
objects, as far as I'm concerned.

I'll eventually have a database connection in the PlayerManager class;
this'll make it easier to manage the database.
2014-03-02 23:20:37 +11:00
Kayne Ruse 975533afba Minor tweak to the editor's menu bar 2014-03-01 23:58:06 +11:00
Kayne Ruse 19749f7c87 Added grey highlighting to the debug text 2014-03-01 03:31:46 +11:00
Kayne Ruse 7703c4b0ad Merge branch 'master' into stable
Even though some parts of the new map system are a stub, I feel confident
enough to merge this branch back onto the stable branch.

On the whole, I've reduced the complexity of the system, while also allowing
acceptable restrictions.

The RegionPager class works correctly. The Update() member is empty, but it's
still usable.

I've removed TileSheetManager, so the maps can only have one tileset each;
that's fine.

The tiles are voxel integers.

The editor needs an entire overhaul. I think some of the GUI components
are too complex. The sooner I can implement the map in the main
client/server system the better.
2014-03-01 00:48:19 +11:00
Kayne Ruse dc8f594eec Tested RegionPager, removed trace statements, fixed logic errors 2014-03-01 00:39:39 +11:00
Kayne Ruse 4629b7302b Fixed Region's internals 2014-02-28 23:14:22 +11:00
Kayne Ruse 02d83d1f16 BUG: Region's memory isn't being zeroed by the looks of it 2014-02-28 03:41:03 +11:00
Kayne Ruse 91c9cef56d Working on the TileSheet class 2014-02-28 03:40:18 +11:00
Kayne Ruse f7d4912942 Merge branch 'stable' 2014-02-24 01:41:40 +11:00
Kayne Ruse eb8674b84f Moved the technical document 2014-02-24 01:41:21 +11:00
Kayne Ruse ff44e4d916 Merge branch 'stable' 2014-02-24 01:14:16 +11:00
Kayne Ruse e66540f114 Updated README 2014-02-24 01:12:42 +11:00
Kayne Ruse 639c0c70e3 RegionPager can now be instanciated with template parameters
* Fixed Region::GetX() and Region::GetY()
* Replaced calls to std::find_if with regular for loops
* Changed typing of RegionPager::regionList
** regionList now holds pointers rather than the objects themselves
* Added vestigial classes MapFileFormat and MapGenerator
** MapGenerator creates and destroys the region objects
* I'm leaving in the debugging code for now
** This includes trace statements and a basterdized main() function in
/editor/main.cpp
2014-02-24 00:34:02 +11:00
Kayne Ruse 37b02352e2 Fleshed out inherited functions
TODO:
* RegionPagerBase::Update() is a stub
* MapFileFormat
* MapGenerator
* Can replace the calls to std::find_if() with a utility function
2014-02-23 03:08:37 +11:00
Kayne Ruse 31c8bd7fd2 Split the pager class into two
I've also made the base class abstract, and the derived class a template.
Hopefully this'll let me work on different parts of the class without
major issues.

This code compiles, but since it's incomplete, I can't test it properly.
2014-02-21 03:42:02 +11:00
Kayne Ruse 808fe570a3 Added empty RegionPager 2014-02-18 01:18:04 +11:00
Kayne Ruse e706cc9d13 Completed a simple region class 2014-02-15 20:06:20 +11:00
Kayne Ruse eb02cc4b6a Removed the old map system from the editor 2014-02-11 21:56:45 +11:00
Kayne Ruse 31cca61d1c Added position data to player objects 2013-12-31 02:25:16 +11:00
Kayne Ruse 071e0d9021 I'm sick of multithreading.
I'm also sick of bastards on the internet.
2013-12-30 14:11:44 +11:00
Kayne Ruse a494bfbb38 Fixed horrible naming convention 2013-12-25 22:09:59 +11:00
Kayne Ruse baadf554cd BUGFIX: Solved server failure
Cause:

server/server_application.cpp: line 93

The last argument to std::pair was simply a call to WorldRoom's
contructor. This created a temporary object that fufilled this line, but
after the new std::pair object was added to worldRoomMap, this WorldRoom
object went out of scope.

server/server_application.cpp: line 96

When OpenRoom() was called using an object that was out of scope, the
entire server simply failed.

Solution:

Changed worldRoomMap to hold a pointer to a WorldRoom object, rather than the
object itself. The new and delete operators should be used to create and
delete WorldRoom objects respectfully.
2013-12-14 00:23:20 +11:00
Kayne Ruse 9df16fede0 WARNING: Server fails on startup
For some reason, when trying to initiate the room thread, the entire
server simply fails. There is no crash, no error message, or anything. I
have no idea what's wrong.
2013-12-11 22:22:01 +11:00
Kayne Ruse dd0ad31ac6 Tweaked README.md 2013-12-11 18:54:51 +11:00
Kayne Ruse be26c9d103 Started working on multithreaded rooms 2013-12-08 15:55:49 +11:00
Kayne Ruse a448c8fb68 Added the nightly build link to the readme 2013-12-07 03:28:41 +11:00
Kayne Ruse de1a6a050f Fixed jittery lag and client closing issues 2013-12-07 03:24:39 +11:00
Kayne Ruse 49c9abe91b Added controls, it's now MP capable 2013-12-07 02:36:48 +11:00
Kayne Ruse 3b05476689 Connections and disconnections are working across different clients 2013-12-07 01:33:27 +11:00
Kayne Ruse 1c032bfc47 Implemented client-side player creation; incomplete 2013-12-06 23:03:46 +11:00
Kayne Ruse 1a7457f650 Imported and refactored PlayerCharacter from the old branch 2013-12-06 21:00:35 +11:00
Kayne Ruse e640eda771 Moved client scenes to a sub directory, reworked build process 2013-12-06 20:22:55 +11:00
Kayne Ruse fc2b67608f Added new graphics stuff, adjusted build process 2013-12-06 18:29:55 +11:00
Kayne Ruse a3a990cc01 Added player support to the server
This code is essentially copied from the old branch, since the two
branches are now functionally identical. How much time have I wasted
rewriting this?
2013-12-06 17:47:03 +11:00
Kayne Ruse f6a4674a2f Moved networking code into high cohesion functions 2013-12-02 17:54:47 +11:00
Kayne Ruse 865620b4a8 Renamed some things, and removed Client::index 2013-12-01 18:36:18 +11:00
Kayne Ruse 1e0ed350fc Removed Multithreading, simplifying the server
Networking and multithreading working at the same time is really fucking
hard. It's better to just have the one thread, and not worry about speed
at this stage.
2013-12-01 15:21:00 +11:00
Kayne Ruse 6ccc874583 Implemented the log on and log off systems
This is a pretty straight forward port of the old version, including the
incredibly hacky server list. But I just need to remember that this is a
prototype.
2013-11-23 17:53:36 +11:00
Kayne Ruse ca86dc5fb8 Added a delay, to give the machine a rest 2013-11-23 01:25:49 +11:00
Kayne Ruse e3605e4dc5 The client is receiving the list of servers 2013-11-22 23:19:29 +11:00
Kayne Ruse cb9aef95ec Reworked NetworkQueue as a template class 2013-11-22 19:57:24 +11:00
Kayne Ruse 09f97de0e6 Added HandlePacket() to the lobby 2013-11-22 19:56:15 +11:00
Kayne Ruse f5466b9982 Added config based directories 2013-11-17 00:13:16 +11:00
Kayne Ruse e176a60d28 client to server contact 2013-11-16 23:46:59 +11:00
Kayne Ruse dc24d1b059 Committing the empty WorldRoom class 2013-11-13 02:03:25 +11:00
Kayne Ruse fa3fc18ddf Imported and updated ConfigUtility 2013-11-09 21:13:00 +11:00
Kayne Ruse c2941cd3e8 Moved the thread out of the NetworkQueue class 2013-11-09 20:04:06 +11:00
Kayne Ruse bf15a5d957 Minor tweak 2013-11-09 16:32:35 +11:00
Kayne Ruse f01463bab3 Added and tested the network queue in the server
This is a reimplementation of the old network queue, but using a class.
This still uses a separate thread, so that packets can wait if there's any
lag. Really, thinking about it, I wonder how necessary this was.

On the upside, no singletons this time. Which means that you can have
several instances of UDPNetworkManager. That's unintentional, but good to
know.
2013-11-03 00:22:41 +11:00
Kayne Ruse 54cd26b76f Removed a lot of rubbish from the server 2013-11-02 19:00:08 +11:00
Kayne Ruse 2bd8adaf69 Added an empty navigation shell to the client 2013-10-27 22:00:09 +11:00
Kayne Ruse 26eba2def6 Moved some common/* files into directories 2013-10-27 20:17:37 +11:00
Kayne Ruse 43852ce755 Hooked the two scenes together
What the hell am I doing?
2013-10-27 00:43:37 +11:00
Kayne Ruse 81fab06e3b Dummied out the load & save functions 2013-10-22 20:22:35 +11:00
Kayne Ruse 77a90f9c0c Slight refactoring 2013-10-22 20:19:09 +11:00
Kayne Ruse bc32f2a2f0 The editor scene now works correctly with the TileSheetManager 2013-10-22 19:43:20 +11:00
Kayne Ruse 76bfecd466 RegionPager now uses a reference to TileSheetManager 2013-10-22 19:35:24 +11:00
Kayne Ruse d4eb1e7b8d Checking in the test scene and test tilesets 2013-10-22 19:22:18 +11:00
Kayne Ruse 2ec307510d Revised TileSheet & TileSheetManager 2013-10-22 19:18:35 +11:00
Kayne Ruse 0b4e6003d6 Created the TileSheetManager class
This class will manage the large(ish) number of tile sheets for a specific
map.
2013-10-21 23:53:36 +11:00
Kayne Ruse 7e603ffa89 Moved the map systems into their own directory 2013-10-17 23:33:02 +11:00
Kayne Ruse 6fc8570cf4 Added the saving function 2013-10-17 23:10:43 +11:00
Kayne Ruse 0bfd916df4 Fixed inverted camera, and added RegionPager::Prune() 2013-10-17 22:18:42 +11:00
Kayne Ruse 88aee0f4f5 Created the loadGameMap() function, still incomplete
Although the overall logic of this function is finished, I still need to
write the callbacks for RegionPager's onNew and onDelete.

I've also tested this using a hand written save/index file. I've written
up a map file format by hand, and I'll be implementing it over the next
few commits.
2013-10-14 21:12:09 +11:00
Kayne Ruse 0d3c3243a0 Added a debug display 2013-10-11 20:07:57 +11:00
Kayne Ruse 871b1136c2 Pager and menu bar working together without interfering with each other 2013-10-11 01:14:02 +11:00
Kayne Ruse f64c935ffe Imported revamped GUI classes, moved map classes 2013-10-11 00:30:31 +11:00
Kayne Ruse 600ec6789b Removed debug code from the editor 2013-10-07 02:32:36 +11:00
Kayne Ruse 65a3937592 Imported the rsc/ folder from the old branch 2013-10-07 01:32:29 +11:00
Kayne Ruse 719c8f49a6 Added region highlighting 2013-10-06 19:22:26 +11:00
Kayne Ruse 29928c0b92 Added a draw function to the pager
I'm also committing some simple debugging code in the scene.
2013-10-04 02:18:10 +10:00
Kayne Ruse a88a1f7cf7 Systems are working correctly, but needs cleaning 2013-10-04 00:34:57 +10:00
Kayne Ruse 46efbfbe9a Forgot to add the license 2013-10-03 23:20:04 +10:00
Kayne Ruse 26ff8dcc8f Created RegionPager 2013-10-03 23:04:16 +10:00
Kayne Ruse 9c91e9d5fd Decoupled the TileSheet class from the Map class
I moved the rangeEnd variable into the TileSheet class, making it static.
I also tweaked the return types for a few functions in Region, and removed
the sheetIndex member from Tile.
2013-10-03 21:29:11 +10:00
Kayne Ruse 3628d3c1fd Finished the delcaration of the Map class
This is actually a lot harder than I was expecting. When I program, I
approach from the angle of "What do I need to do?" rather than "how do I do
this?" At least this is finally done, so I can get to the implementation
stage. But, as I progress, I'll need to keep in mind what I need for the
index file.

Actually, I just realized that I didn't write the index functions. Well,
it should be interesting, at least.
2013-10-01 23:02:46 +10:00
Kayne Ruse 6c9406147a Added width & height members to Tile, moved local functions to utility.*pp
I've added more members to the Tile structure, namely the width & height
of the tile. This is to fix a circular logic problem, which is too
abstract for this commit message ;)

I've also moved the local/static/inline/etc. utility functions to their
own module in the common directory, because this is just cleaner that
redefining the same code a dozen times.

The map's logic is still the same, but I need to keep moving; I've been
procrastinating far too much.
2013-10-01 21:46:34 +10:00
Kayne Ruse aae244de39 Code tweak 2013-09-25 21:27:00 +10:00
Kayne Ruse d5b14c2679 Created the TileSheet class
This is incomplete on it's own, but used as part of the whole map system,
it should work well. This class keeps track of various, seemingly
unrelated states, which are used as part of the larger map system.

Also, fixed Region's members being public.
2013-09-25 20:39:59 +10:00
Kayne Ruse a54fbfb9e9 Added static linking 2013-09-21 16:26:01 +10:00
Kayne Ruse 9cbbfe77b7 After some testing Region seems OK 2013-09-19 22:52:26 +10:00
Kayne Ruse 9b64c67068 Finished a prototype of Region, needs testing 2013-09-19 16:52:15 +10:00
Kayne Ruse de0227a1cf Demonstration of Tile & Region classes 2013-09-19 01:22:52 +10:00
Kayne Ruse 1dfeabf195 SDL_net is working 2013-09-09 12:15:26 +10:00
Kayne Ruse 6c5197f3f2 The server runs the setup scripts on startup 2013-09-05 23:02:48 +10:00
Kayne Ruse 09453cc24e Added lua and SQL, but removed lsqlite3.c
lsqlite3.c looked like a good idea for connnecting SQL and lua, but I
couldn't get it to work and rather than struggle on this, I'll write my
own library later on.
2013-09-05 20:08:50 +10:00
Kayne Ruse 4b62310158 Revised build process to include the common/ directory 2013-09-04 20:49:55 +10:00
Kayne Ruse 43f2190c3e Created the database setup script 2013-09-04 19:17:16 +10:00
Kayne Ruse 3225da6b13 Added client scenes 2013-08-31 03:27:11 +10:00
Kayne Ruse 0c233b8764 Added readme.md 2013-08-29 21:55:09 +10:00
Kayne Ruse 027d0125ef Boilerplate, boilerplate, boilerplate!!!
I've created a project for client & editor programs, by simply copying one
to the other. Right now, the client still has the editor scene, but I'll
switch that out soon.

I've also added a license header to the server's source. I don't remember
what else I did, but at this point it should theoretically build out of
the box.
2013-08-29 21:17:43 +10:00
Kayne Ruse e4884c3e18 Added more placeholder files 2013-08-29 20:35:02 +10:00
Kayne Ruse b675f516e7 Beginning to create the placeholder classes 2013-08-29 19:57:25 +10:00
Kayne Ruse d5f7363c33 Minor rename 2013-08-25 13:59:13 +10:00
Kayne Ruse 7458962ad4 Rearranged the logic 2013-08-24 23:20:43 +10:00
Kayne Ruse 0a0b61287e Started working on the room system 2013-08-11 20:39:08 +10:00
117 changed files with 4252 additions and 3931 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
#Editor generated files
#*.sln
#*.vcproj
*.sln
*.vcproj
*.suo
*.ncb
*.user
+16 -16
View File
@@ -1,31 +1,31 @@
_This project is currently in it's early prototype stage. You can see other versions in various branches or tagged as prototype-X._
The most recent stable windows build can be found [here](https://dl.dropboxusercontent.com/u/46669050/Tortuga.rar).
Tortuga is a 2D multiplayer role playing game set in a large archipelago occupied by warring pirate clans. The emphasis of this game is on multiplayer cooperation, competition, and server customization. The game runs on highly customizable server software that can support up to 150 simultaneous players or more. The player characters are tied to the server where they are created and are susceptible to permadeath: deletion of a character upon death.
Tortuga is an open source 2D multiplayer role playing game featuring permadeath (deletion of a character upon death). The emphasis of this game is on multiplayer cooperation, competition, exploration and customization. The game runs on customizable server software that can support up to 150 simultaneous players or more.
## Libraries
This game is inspired by classic 2D RPGs, as well as more modern sandbox MMOs. This project is currently independently created and funded, with the goal of creating a game that will engage user's imagination and inspire a large modding community.
* [SDL](http://www.libsdl.org/) - Simple DirectMedia Layer API
* [SDL_net](http://www.libsdl.org/projects/SDL_net/) - SDL's networking extension. This must be installed first.
* [Codebase](https://github.com/Ratstail91/Codebase) - generic reusable code modules
## External Dependencies
## Instructions
* [SDL 1.6](http://www.libsdl.org/) - Simple DirectMedia Layer API
* [SDL_net 1.2](http://www.libsdl.org/projects/SDL_net/) - SDL's networking extension
* [lua 5.2](http://www.lua.org/) - The lua programming language
* [SQLite3](http://www.sqlite.org/) - A lightweight SQL database engine
* This project uses C++11, which is available via GNU (or MinGW) 4.7, or Visual Studio 2012. Personally, I'm using MinGW 4.7.2.
* I'm trying to keep this as IDE agnostic as possible, so if you use an IDE, please add it's files to .gitignore.
* You can read more details on the Tortuga wiki [here](https://github.com/Ratstail91/Tortuga/wiki).
## Documentation
[Tortuga Game Design Document](https://github.com/Ratstail91/Tortuga/blob/docs/design%20doc.docx?raw=true)
[Tortuga Technical Document](https://github.com/Ratstail91/Tortuga/blob/docs/technical%20doc.docx?raw=true)
## Copyright
The current version of Tortuga is released under the [zlib license](http://en.wikipedia.org/wiki/Zlib_License).
Copyright (c) 2013 Kayne Ruse
Copyright (c) 2013, 2014 Kayne Ruse
This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
+8
View File
@@ -0,0 +1,8 @@
#ifndef CHANNELS_HPP_
#define CHANNELS_HPP_
enum Channels {
SERVER = 0
};
#endif
+40 -73
View File
@@ -5,7 +5,7 @@
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* including commercial ClientApplications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
@@ -24,17 +24,23 @@
#include <stdexcept>
#include <chrono>
//-------------------------
//Static declarations
//-------------------------
ClientApplication ClientApplication::instance;
//-------------------------
//Scene headers
//-------------------------
//Add the custom scene headers here
#include "in_combat.hpp"
#include "in_world.hpp"
#include "lobby.hpp"
#include "main_menu.hpp"
#include "option_screen.hpp"
#include "splash_screen.hpp"
#include "main_menu.hpp"
#include "options_menu.hpp"
#include "lobby_menu.hpp"
#include "in_world.hpp"
#include "in_combat.hpp"
//-------------------------
//Public access members
@@ -45,60 +51,33 @@ ClientApplication::ClientApplication() {
}
ClientApplication::~ClientApplication() {
UnloadScene();
//
}
/* ClientApplication::Init()
* This function initializes the entire program. There are a number of things
* that could go wrong here, which is why there is such an unusual order of
* operations.
* Important things to note:
* The APIs are initiated here.
* The global objects are initialized here.
* The game's screen is created here, based on information loaded from the config file.
* The ConfigUtility's call to Load() also ensures that the "rsc\" folder is in the directory. It's easy to forget it.
*/
void ClientApplication::Init() {
//load the config file
try {
configUtil->Load("rsc/config.cfg");
}
catch(std::runtime_error& e) {
std::string s = e.what();
s += "; Ensure that the \"rsc\" directory is present";
throw(std::runtime_error(s));
}
//load the prerequisites
config.Load("rsc\\config.cfg");
//initialize the APIs
//initialize SDL
if (SDL_Init(SDL_INIT_VIDEO)) {
throw(std::runtime_error("Failed to initialize SDL"));
}
BaseScene::SetScreen(config.Int("screen.w"), config.Int("screen.h"), 0, (config.Bool("screen.f")) ? SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN : SDL_HWSURFACE|SDL_DOUBLEBUF);
//initialize SDL_net
if (SDLNet_Init()) {
throw(std::runtime_error("Failed to initialize SDL_net"));
}
//create the screen
Uint32 flags = SDL_HWSURFACE | SDL_DOUBLEBUF;
flags |= configUtil->Bool("screen.f") ? SDL_FULLSCREEN : 0;
BaseScene::SetScreen(
configUtil->Int("screen.w"),
configUtil->Int("screen.h"),
SDL_GetVideoInfo()->vfmt->BitsPerPixel,
flags);
//initiate the remaining singletons
netUtil->Open(0, sizeof(Packet));
network.Open(0, PACKET_BUFFER_SIZE);
}
void ClientApplication::Proc() {
LoadScene(SceneList::FIRST);
//prepare the time system
typedef std::chrono::high_resolution_clock Clock;
typedef std::chrono::steady_clock Clock;
Clock::duration delta(16 * Clock::duration::period::den / std::milli::den);
std::chrono::duration<int, std::milli> delta(16);
Clock::time_point simTime = Clock::now();
Clock::time_point realTime;
@@ -116,29 +95,19 @@ void ClientApplication::Proc() {
//simulate game time
while (simTime < realTime) {
//call each user defined function
activeScene->RunFrame(double(delta.count()) / Clock::duration::period::den);
activeScene->RunFrame(double(delta.count()) / std::chrono::duration<int, std::milli>::period::den);
simTime += delta;
}
//draw the game to the screen
activeScene->RenderFrame();
//give the computer a break
SDL_Delay(10);
}
UnloadScene();
}
void ClientApplication::Quit() {
//clean up the singletons
netUtil->Close();
surfaceMgr->FreeAll();
//clean up the scene
UnloadScene();
//deinitialize the APIs
network.Close();
SDLNet_Quit();
SDL_Quit();
}
@@ -149,29 +118,27 @@ void ClientApplication::Quit() {
void ClientApplication::LoadScene(SceneList sceneIndex) {
UnloadScene();
switch(sceneIndex) {
//add scene creation calls here
case SceneList::FIRST:
case SceneList::SPLASHSCREEN:
activeScene = new SplashScreen(&config);
break;
case SceneList::MAINMENU:
activeScene = new MainMenu(&config);
break;
case SceneList::OPTIONSMENU:
activeScene = new OptionsMenu(&config);
break;
case SceneList::LOBBYMENU:
activeScene = new LobbyMenu(&config, &network, &clientIndex);
break;
case SceneList::INWORLD:
activeScene = new InWorld(&config, &network, &clientIndex);
break;
case SceneList::INCOMBAT:
activeScene = new InCombat();
break;
case SceneList::INWORLD:
activeScene = new InWorld();
break;
case SceneList::LOBBY:
activeScene = new Lobby();
break;
case SceneList::MAINMENU:
activeScene = new MainMenu();
break;
case SceneList::OPTIONSCREEN:
activeScene = new OptionScreen();
break;
case SceneList::FIRST:
case SceneList::SPLASHSCREEN:
activeScene = new SplashScreen();
break;
default:
throw(std::logic_error("Failed to recognize the scene index"));
}
+10 -15
View File
@@ -24,39 +24,34 @@
#include "scene_list.hpp"
#include "base_scene.hpp"
#include "singleton.hpp"
#include "packet.hpp"
#include "information_manager.hpp"
#include "config_utility.hpp"
#include "surface_manager.hpp"
#include "network_packet.hpp"
#include "udp_network_utility.hpp"
#include "SDL/SDL.h"
class ClientApplication {
public:
/* Public access members */
private:
ClientApplication();
~ClientApplication();
static ClientApplication instance;
public:
static ClientApplication* GetInstance() { return &instance; }
void Init();
void Proc();
void Quit();
ClientApplication(ClientApplication const&) = delete;
ClientApplication(ClientApplication const&&) = delete;
private:
/* Private access members */
//Private access members
void LoadScene(SceneList sceneIndex);
void UnloadScene();
BaseScene* activeScene = nullptr;
ConfigUtility* configUtil = Singleton<ConfigUtility>::Get();
SurfaceManager* surfaceMgr = Singleton<SurfaceManager>::Get();
UDPNetworkUtility* netUtil = Singleton<UDPNetworkUtility>::Get();
InformationManager* infoMgr = Singleton<InformationManager>::Get();
ConfigUtility config;
UDPNetworkUtility network;
int clientIndex = -1; //replace with a struct?
};
#endif
-314
View File
@@ -1,314 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "in_world.hpp"
#include <iostream>
using namespace std;
//-------------------------
//Public access members
//-------------------------
InWorld::InWorld() {
#ifdef DEBUG
cout << "entering InWorld" << endl;
#endif
cout << "Client Index: " << infoMgr->GetClientIndex() << endl;
font.SetSurface(surfaceMgr->Get("font"));
//debugging
Packet p;
p.meta.type = Packet::Type::PLAYER_NEW;
p.meta.clientIndex = infoMgr->GetClientIndex();
snprintf(p.playerInfo.handle, PACKET_STRING_SIZE, "%s", configUtil->CString("handle"));
snprintf(p.playerInfo.avatar, PACKET_STRING_SIZE, "%s", configUtil->CString("avatar"));
p.playerInfo.position = {50, 50};
p.playerInfo.motion = {0, 0};
netUtil->Send(GAME_CHANNEL, &p, sizeof(Packet));
//request a sync
p.meta.type = Packet::Type::SYNCHRONIZE;
p.meta.clientIndex = infoMgr->GetClientIndex();
netUtil->Send(GAME_CHANNEL, &p, sizeof(Packet));
}
InWorld::~InWorld() {
#ifdef DEBUG
cout << "leaving InWorld" << endl;
#endif
}
//-------------------------
//Frame loop
//-------------------------
void InWorld::FrameStart() {
//
}
void InWorld::Update(double delta) {
while(HandlePacket(popNetworkPacket()));
for (auto& it : playerCharacters) {
it.second.Update(delta);
}
}
void InWorld::FrameEnd() {
//
}
void InWorld::Render(SDL_Surface* const screen) {
ClockFrameRate();
for (auto& it : playerCharacters) {
it.second.DrawTo(screen);
}
//since we're using this twice, make a tmp var
string fps = itos(GetFrameRate());
font.DrawStringTo(fps, screen, screen->w - fps.size() * font.GetCharW(), 0);
}
//-------------------------
//Event handlers
//-------------------------
void InWorld::QuitEvent() {
//ensure that the client is disconnected properly
ExitGame();
SetNextScene(SceneList::QUIT);
}
void InWorld::MouseMotion(SDL_MouseMotionEvent const& motion) {
//
}
void InWorld::MouseButtonDown(SDL_MouseButtonEvent const& button) {
//
}
void InWorld::MouseButtonUp(SDL_MouseButtonEvent const& button) {
//
}
void InWorld::KeyDown(SDL_KeyboardEvent const& key) {
//general
switch(key.keysym.sym) {
case SDLK_ESCAPE:
ExitGame();
break;
}
//player movement
if (infoMgr->GetPlayerIndex() == -1) {
return;
}
switch(key.keysym.sym) {
case SDLK_w:
playerCharacters[infoMgr->GetPlayerIndex()].MoveDirection(CardinalDirection::NORTH);
SendState();
break;
case SDLK_s:
playerCharacters[infoMgr->GetPlayerIndex()].MoveDirection(CardinalDirection::SOUTH);
SendState();
break;
case SDLK_a:
playerCharacters[infoMgr->GetPlayerIndex()].MoveDirection(CardinalDirection::WEST);
SendState();
break;
case SDLK_d:
playerCharacters[infoMgr->GetPlayerIndex()].MoveDirection(CardinalDirection::EAST);
SendState();
break;
}
}
void InWorld::KeyUp(SDL_KeyboardEvent const& key) {
//player movement reversed
switch(key.keysym.sym) {
case SDLK_w:
playerCharacters[infoMgr->GetPlayerIndex()].MoveDirection(CardinalDirection::SOUTH);
SendState();
break;
case SDLK_s:
playerCharacters[infoMgr->GetPlayerIndex()].MoveDirection(CardinalDirection::NORTH);
SendState();
break;
case SDLK_a:
playerCharacters[infoMgr->GetPlayerIndex()].MoveDirection(CardinalDirection::EAST);
SendState();
break;
case SDLK_d:
playerCharacters[infoMgr->GetPlayerIndex()].MoveDirection(CardinalDirection::WEST);
SendState();
break;
}
}
//-------------------------
//Utilities
//-------------------------
int InWorld::HandlePacket(Packet p) {
switch(p.meta.type) {
case Packet::Type::NONE:
//DO NOTHING
return 0;
break;
case Packet::Type::PING:
//quick pong
p.meta.type = Packet::Type::PONG;
p.meta.clientIndex = infoMgr->GetClientIndex();
netUtil->Send(&p.meta.address, &p, sizeof(Packet));
break;
case Packet::Type::PONG:
//
break;
// case Packet::Type::BROADCAST_REQUEST:
// //
// break;
// case Packet::Type::BROADCAST_RESPONSE:
// //
// break;
// case Packet::Type::JOIN_REQUEST:
// //
// break;
// case Packet::Type::JOIN_RESPONSE:
// //
// break;
case Packet::Type::DISCONNECT:
HandleDisconnection(p);
break;
// case Packet::Type::SYNCHRONIZE:
// //
// break;
case Packet::Type::PLAYER_NEW:
AddPlayer(p);
break;
case Packet::Type::PLAYER_DELETE:
RemovePlayer(p);
break;
case Packet::Type::PLAYER_UPDATE:
UpdatePlayer(p);
break;
default:
throw(runtime_error("Failed to recognize the packet type: " + itos(int(p.meta.type))));
}
return 1;
}
void InWorld::Disconnect() {
Packet p;
//delete the player
p.meta.type = Packet::Type::PLAYER_DELETE;
p.meta.clientIndex = infoMgr->GetClientIndex();
p.playerInfo.index = infoMgr->GetPlayerIndex();
netUtil->Send(GAME_CHANNEL, &p, sizeof(Packet));
//disconnect
p.meta.type = Packet::Type::DISCONNECT;
p.meta.clientIndex = infoMgr->GetClientIndex();
netUtil->Send(GAME_CHANNEL, &p, sizeof(Packet));
netUtil->Unbind(GAME_CHANNEL);
//reset the client
infoMgr->ResetClientIndex();
infoMgr->ResetPlayerIndex();
}
void InWorld::ExitGame() {
Disconnect();
SetNextScene(SceneList::MAINMENU);
endQueueThread();
cout << "The game session has ended" << endl;
}
void InWorld::HandleDisconnection(Packet& disconnect) {
Disconnect();
SetNextScene(SceneList::MAINMENU);
endQueueThread();
cout << "You have been disconnected" << endl;
}
void InWorld::AddPlayer(Packet& p) {
if (playerCharacters.find(p.playerInfo.index) != playerCharacters.end()) {
throw(runtime_error("Duplicate players detected"));
}
//position
playerCharacters[p.playerInfo.index].SetPosition(p.playerInfo.position);
playerCharacters[p.playerInfo.index].SetMotion(p.playerInfo.motion);
//sprite
playerCharacters[p.playerInfo.index].GetSprite()->SetSurface(surfaceMgr->Get(p.playerInfo.avatar), 32, 48);
playerCharacters[p.playerInfo.index].FaceDirection();
//is it this player?
if (p.meta.clientIndex == infoMgr->GetClientIndex()) {
infoMgr->SetPlayerIndex(p.playerInfo.index);
}
//debugging
cout << "New player, index " << p.playerInfo.index << endl;
}
void InWorld::RemovePlayer(Packet& p) {
if (playerCharacters.find(p.playerInfo.index) == playerCharacters.end()) {
throw(runtime_error("Player to delete not found"));
}
playerCharacters.erase(p.playerInfo.index);
}
void InWorld::UpdatePlayer(Packet& p) {
if (playerCharacters.find(p.playerInfo.index) == playerCharacters.end()) {
AddPlayer(p);
return;
}
playerCharacters[p.playerInfo.index].SetPosition(p.playerInfo.position);
playerCharacters[p.playerInfo.index].SetMotion(p.playerInfo.motion);
playerCharacters[p.playerInfo.index].FaceDirection();
}
void InWorld::SendState() {
//send the state of this player's character
if (infoMgr->GetPlayerIndex() == -1) {
return;
}
Packet p;
p.meta.type = Packet::Type::PLAYER_UPDATE;
p.meta.clientIndex = infoMgr->GetClientIndex();
p.playerInfo.index = infoMgr->GetPlayerIndex();
p.playerInfo.position = playerCharacters[infoMgr->GetPlayerIndex()].GetPosition();
p.playerInfo.motion = playerCharacters[infoMgr->GetPlayerIndex()].GetMotion();
netUtil->Send(GAME_CHANNEL, &p, sizeof(Packet));
}
-234
View File
@@ -1,234 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "lobby.hpp"
#include <iostream>
using namespace std;
//-------------------------
//Public access members
//-------------------------
Lobby::Lobby() {
#ifdef DEBUG
cout << "entering Lobby" << endl;
#endif
refreshButton.Setup(50, 50, surfaceMgr->Get("button"), surfaceMgr->Get("font"), "Refresh");
joinButton.Setup(50, 100, surfaceMgr->Get("button"), surfaceMgr->Get("font"), "Join");
backButton.Setup(50, 150, surfaceMgr->Get("button"), surfaceMgr->Get("font"), "Back");
font.SetSurface(surfaceMgr->Get("font"));
listBox.x = 280;
listBox.y = 50;
listBox.w = GetScreen()->w - listBox.x - 50;
listBox.h = font.GetCharH();
serverList.push_back({"foo",{0,0}});
serverList.push_back({"bar",{0,0}});
serverList.push_back({"foobar",{0,0}});
flushNetworkQueue();
beginQueueThread();
BroadcastNetwork();
}
Lobby::~Lobby() {
#ifdef DEBUG
cout << "leaving Lobby" << endl;
#endif
}
//-------------------------
//Frame loop
//-------------------------
void Lobby::FrameStart() {
//
}
void Lobby::Update(double delta) {
while(HandlePacket(popNetworkPacket()));
}
void Lobby::FrameEnd() {
//
}
void Lobby::Render(SDL_Surface* const screen) {
refreshButton.DrawTo(screen);
joinButton.DrawTo(screen);
backButton.DrawTo(screen);
for (int i = 0; i < serverList.size(); i++) {
if (selectedServer == &serverList[i]) {
//draw the highlight box
SDL_Rect r = listBox;
r.y += i * font.GetCharH();
SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 255, 127, 39));
}
font.DrawStringTo(serverList[i].name, screen, listBox.x, listBox.y + i * font.GetCharH());
}
}
//-------------------------
//Event handlers
//-------------------------
void Lobby::MouseMotion(SDL_MouseMotionEvent const& motion) {
refreshButton.MouseMotion(motion);
joinButton.MouseMotion(motion);
backButton.MouseMotion(motion);
}
void Lobby::MouseButtonDown(SDL_MouseButtonEvent const& button) {
refreshButton.MouseButtonDown(button);
joinButton.MouseButtonDown(button);
backButton.MouseButtonDown(button);
}
void Lobby::MouseButtonUp(SDL_MouseButtonEvent const& button) {
if (refreshButton.MouseButtonUp(button) == Button::State::HOVER) {
BroadcastNetwork();
selectedServer = nullptr;
}
else if (joinButton.MouseButtonUp(button) == Button::State::HOVER) {
if (selectedServer) {
ConnectToServer(selectedServer);
selectedServer = nullptr;
}
}
else if (backButton.MouseButtonUp(button) == Button::State::HOVER) {
SetNextScene(SceneList::MAINMENU);
endQueueThread();
selectedServer = nullptr;
}
else if (
//clicked within bounds TODO: make the damn collision system
button.x > listBox.x &&
button.y > listBox.y &&
button.x < listBox.x + listBox.w &&
button.y < listBox.y + (listBox.h * serverList.size())
)
{
//selecting a server
selectedServer = &serverList[(button.y - listBox.y) / listBox.h];
}
else {
//lose focus on a server
selectedServer = nullptr;
}
}
void Lobby::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
case SDLK_ESCAPE:
SetNextScene(SceneList::MAINMENU);
break;
}
}
void Lobby::KeyUp(SDL_KeyboardEvent const& key) {
//
}
//-------------------------
//Utilities
//-------------------------
int Lobby::HandlePacket(Packet p) {
switch(p.meta.type) {
case Packet::Type::NONE:
//DO NOTHING
return 0;
break;
case Packet::Type::PING:
//quick pong
p.meta.type = Packet::Type::PONG;
netUtil->Send(&p.meta.address, &p, sizeof(Packet));
break;
case Packet::Type::PONG:
//
break;
// case Packet::Type::BROADCAST_REQUEST:
// //
// break;
case Packet::Type::BROADCAST_RESPONSE:
PushServer(p);
break;
// case Packet::Type::JOIN_REQUEST:
// //
// break;
case Packet::Type::JOIN_RESPONSE:
BeginGame(p);
break;
// case Packet::Type::DISCONNECT:
// //
// break;
// case Packet::Type::SYNCHRONIZE:
// //
// break;
// case Packet::Type::PLAYER_NEW:
// //
// break;
// case Packet::Type::PLAYER_DELETE:
// //
// break;
// case Packet::Type::PLAYER_UPDATE:
// //
// break;
default:
throw(runtime_error("Failed to recognize the packet type: " + itos(int(p.meta.type))));
}
return 1;
}
void Lobby::BroadcastNetwork() {
Packet p;
p.meta.type = Packet::Type::BROADCAST_REQUEST;
netUtil->Send("255.255.255.255", configUtil->Int("server.port"), &p, sizeof(Packet));
serverList.clear();
}
void Lobby::PushServer(Packet& bcast) {
ServerEntry entry;
entry.name = bcast.serverInfo.name;
entry.address = bcast.meta.address;
serverList.push_back(entry);
}
void Lobby::ConnectToServer(ServerEntry* server) {
//_attempt_ to connect to a server
if (!server) {
throw(runtime_error("No server received"));
}
Packet p;
p.meta.type = Packet::Type::JOIN_REQUEST;
netUtil->Send(&server->address, reinterpret_cast<void*>(&p), sizeof(Packet));
}
void Lobby::BeginGame(Packet& response) {
//should be downloading the resources here as well
infoMgr->SetClientIndex(response.meta.clientIndex);
netUtil->Bind(&response.meta.address, GAME_CHANNEL);
SetNextScene(SceneList::INWORLD);
}
+5 -10
View File
@@ -27,21 +27,16 @@
using namespace std;
int main(int, char**) {
#ifdef DEBUG
cout << "Beginning program" << endl;
#endif
cout << "Beginning client" << endl;
try {
ClientApplication app;
app.Init();
app.Proc();
app.Quit();
ClientApplication::GetInstance()->Init();
ClientApplication::GetInstance()->Proc();
ClientApplication::GetInstance()->Quit();
}
catch(exception& e) {
cerr << "Fatal error: " << e.what() << endl;
cerr << "Fatal exception thrown: " << e.what() << endl;
return 1;
}
#ifdef DEBUG
cout << "Clean exit" << endl;
#endif
return 0;
}
+12 -7
View File
@@ -1,16 +1,17 @@
#config
LIBDIR=../libs
LOCALLIBS=$(LIBDIR)/out/libCodebase.a $(LIBDIR)/out/libCommon.a
LIB=$(LOCALLIBS) -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL
INCLUDES=$(LIBDIR)/Codebase $(LIBDIR)/common
INCLUDES+=. scenes ../common ../common/graphics ../common/map ../common/network ../common/ui
LIBS+=libclient.a ../libcommon.a -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL -llua -lsqlite3
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES))
#source
SRC=$(wildcard *.cpp)
CXXSRC=$(wildcard *.cpp)
CSRC=$(wildcard *.c)
#objects
OBJDIR=obj
OBJ=$(addprefix $(OBJDIR)/,$(SRC:.cpp=.o))
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
OBJ+=$(addprefix $(OBJDIR)/,$(CSRC:.c=.o))
#output
OUTDIR=../out
@@ -18,7 +19,8 @@ OUT=$(addprefix $(OUTDIR)/,client)
#targets
all: $(OBJ) $(OUT)
$(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIB)
$(MAKE) -C scenes
$(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIBS)
$(OBJ): | $(OBJDIR)
@@ -33,6 +35,9 @@ $(OUTDIR):
$(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
$(OBJDIR)/%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
clean:
$(RM) *.o *.a *.exe
+39 -36
View File
@@ -21,8 +21,10 @@
*/
#include "player_character.hpp"
#define WALKING_SPEED 140
void PlayerCharacter::Update(double delta) {
if (limitSpeed) {
if (diagonal) {
constexpr double d = 1.0/sqrt(2);
position += motion * delta * d;
}
@@ -32,83 +34,84 @@ void PlayerCharacter::Update(double delta) {
sprite.Update(delta);
}
void PlayerCharacter::MoveDirection(CardinalDirection cd) {
void PlayerCharacter::AdjustDirection(Direction direction) {
//shift the movement in this direction
switch(cd) {
case CardinalDirection::NORTH:
switch(direction) {
case Direction::NORTH:
if (motion.y >= 0) {
motion.y -= WALKING_SPEED;
}
break;
case CardinalDirection::SOUTH:
case Direction::SOUTH:
if (motion.y <= 0) {
motion.y += WALKING_SPEED;
}
break;
case CardinalDirection::WEST:
case Direction::WEST:
if (motion.x >= 0) {
motion.x -= WALKING_SPEED;
}
break;
case CardinalDirection::EAST:
case Direction::EAST:
if (motion.x <= 0) {
motion.x += WALKING_SPEED;
}
break;
}
//face the correct direction
FaceDirection();
ResetDirection();
}
void PlayerCharacter::FaceDirection(CardinalDirection cd) {
switch(cd) {
case CardinalDirection::NORTH:
sprite.SetCurrentStrip(1);
void PlayerCharacter::FaceDirection(Direction direction) {
//this function depends on the format of the sprite sheets
switch(direction) {
case Direction::NORTH:
sprite.SetYIndex(1);
break;
case CardinalDirection::SOUTH:
sprite.SetCurrentStrip(0);
case Direction::SOUTH:
sprite.SetYIndex(0);
break;
case CardinalDirection::WEST:
sprite.SetCurrentStrip(2);
case Direction::WEST:
sprite.SetYIndex(2);
break;
case CardinalDirection::EAST:
sprite.SetCurrentStrip(3);
case Direction::EAST:
sprite.SetYIndex(3);
break;
}
}
void PlayerCharacter::FaceDirection() {
void PlayerCharacter::ResetDirection() {
//base the direction on the character's movement
if (motion.y < 0) {
FaceDirection(CardinalDirection::NORTH);
}
if (motion.y > 0) {
FaceDirection(CardinalDirection::SOUTH);
FaceDirection(Direction::SOUTH);
}
if (motion.x < 0) {
FaceDirection(CardinalDirection::WEST);
else if (motion.y < 0) {
FaceDirection(Direction::NORTH);
}
if (motion.x > 0) {
FaceDirection(CardinalDirection::EAST);
else if (motion.x > 0) {
FaceDirection(Direction::EAST);
}
CheckSpeed();
else if (motion.x < 0) {
FaceDirection(Direction::WEST);
}
ResetSpeed();
}
void PlayerCharacter::CheckSpeed() {
void PlayerCharacter::ResetSpeed() {
//diagonal
if (motion.x != 0 && motion.y != 0) {
sprite.SetInterval(0.1);
limitSpeed = true;
sprite.SetDelay(0.1);
diagonal = true;
}
//cardinal
else if (motion != 0) {
sprite.SetInterval(0.1);
limitSpeed = false;
sprite.SetDelay(0.1);
diagonal = false;
}
//not moving
else {
sprite.SetInterval(0);
sprite.SetCurrentFrame(0);
limitSpeed = false;
sprite.SetDelay(0);
sprite.SetXIndex(0);
diagonal = false;
}
}
+12 -9
View File
@@ -24,20 +24,25 @@
#include "vector2.hpp"
#include "sprite_sheet.hpp"
#include "defines.hpp"
class PlayerCharacter {
public:
enum class Direction {
NORTH, SOUTH, EAST, WEST
};
PlayerCharacter() = default;
~PlayerCharacter() = default;
void Update(double delta);
void MoveDirection(CardinalDirection);
void FaceDirection(CardinalDirection);
void FaceDirection();
void DrawTo(SDL_Surface* const dest, int camX, int camY) { sprite.DrawTo(dest, position.x - camX, position.y - camY); }
void DrawTo(SDL_Surface* const dest) { sprite.DrawTo(dest, position.x, position.y); }
//clunky code results in smooth movement and controls
void AdjustDirection(Direction);
void FaceDirection(Direction);
void ResetDirection();
void ResetSpeed();
//accessors and mutators
Vector2 SetPosition(Vector2 v) { return position = v; }
@@ -50,14 +55,12 @@ public:
SpriteSheet* GetSprite() { return &sprite; }
private:
void CheckSpeed();
Vector2 position;
Vector2 motion;
SpriteSheet sprite;
//for moving diagonal
bool limitSpeed = false;
//for moving diagonally
bool diagonal = false;
};
#endif
+5 -5
View File
@@ -29,12 +29,12 @@ enum class SceneList {
FIRST,
//custom indexes
INCOMBAT,
INWORLD,
LOBBY,
MAINMENU,
OPTIONSCREEN,
SPLASHSCREEN,
MAINMENU,
OPTIONSMENU,
LOBBYMENU,
INWORLD,
INCOMBAT,
};
#endif
@@ -34,7 +34,7 @@ SDL_Surface* BaseScene::screen = nullptr;
//-------------------------
BaseScene::BaseScene() {
nextScene = SceneList::CONTINUE;
//
}
BaseScene::~BaseScene() {
@@ -28,18 +28,18 @@
class BaseScene {
public:
/* Public access members */
//Public access members
BaseScene();
virtual ~BaseScene();
/* Program control */
//Program control
static SDL_Surface* SetScreen(int w, int h, int bpp = 0, Uint32 flags = SDL_HWSURFACE|SDL_DOUBLEBUF);
static SDL_Surface* GetScreen();
SceneList SetNextScene(SceneList sceneIndex);
SceneList GetNextScene() const;
/* Frame loop */
//Frame loop
virtual void RunFrame(double delta);
virtual void RenderFrame();
@@ -50,7 +50,7 @@ protected:
virtual void FrameEnd() {}
virtual void Render(SDL_Surface* const screen) {}
/* Event handlers */
//Event handlers
virtual void QuitEvent() { SetNextScene(SceneList::QUIT); }
virtual void MouseMotion(SDL_MouseMotionEvent const&) {}
virtual void MouseButtonDown(SDL_MouseButtonEvent const&) {}
@@ -68,7 +68,7 @@ protected:
private:
static SDL_Surface* screen;
SceneList nextScene;
SceneList nextScene = SceneList::CONTINUE;
};
#endif
@@ -21,24 +21,16 @@
*/
#include "in_combat.hpp"
#include <iostream>
using namespace std;
//-------------------------
//Public access members
//-------------------------
InCombat::InCombat() {
#ifdef DEBUG
cout << "entering InCombat" << endl;
#endif
//
}
InCombat::~InCombat() {
#ifdef DEBUG
cout << "leaving InCombat" << endl;
#endif
//
}
//-------------------------
@@ -26,18 +26,18 @@
class InCombat : public BaseScene {
public:
/* Public access members */
//Public access members
InCombat();
~InCombat();
protected:
/* Frame loop */
//Frame loop
void FrameStart();
void Update(double delta);
void FrameEnd();
void Render(SDL_Surface* const);
/* Event handlers */
//Event handlers
void MouseMotion(SDL_MouseMotionEvent const&);
void MouseButtonDown(SDL_MouseButtonEvent const&);
void MouseButtonUp(SDL_MouseButtonEvent const&);
+499
View File
@@ -0,0 +1,499 @@
/* Copyright: (c) Kayne Ruse 2013
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "in_world.hpp"
#include "channels.hpp"
#include <algorithm>
#include <cmath>
#include <stdexcept>
//debugging
#include <iostream>
using std::cout;
using std::endl;
//-------------------------
//Public access members
//-------------------------
InWorld::InWorld(ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex):
config(*argConfig),
network(*argNetwork),
clientIndex(*argClientIndex)
{
//setup the utility objects
buttonImage.LoadSurface(config["dir.interface"] + "button_menu.bmp");
buttonImage.SetClipH(buttonImage.GetClipH()/3);
font.LoadSurface(config["dir.fonts"] + "pk_white_8.bmp");
//pass the utility objects
disconnectButton.SetImage(&buttonImage);
disconnectButton.SetFont(&font);
shutDownButton.SetImage(&buttonImage);
shutDownButton.SetFont(&font);
//set the button positions
disconnectButton.SetX(50);
disconnectButton.SetY(50 + buttonImage.GetClipH() * 0);
shutDownButton.SetX(50);
shutDownButton.SetY(50 + buttonImage.GetClipH() * 1);
//set the button texts
disconnectButton.SetText("Disconnect");
shutDownButton.SetText("Shut Down");
//load the tilesheet
tileSheet.Load(config["dir.tilesets"] + "terrain.bmp", 12, 15);
//setup the map object
mapPager.SetRegionWidth(REGION_WIDTH);
mapPager.SetRegionHeight(REGION_HEIGHT);
mapPager.SetRegionDepth(REGION_DEPTH);
//create the server-side player object
NetworkPacket packet;
packet.meta.type = NetworkPacket::Type::PLAYER_NEW;
packet.playerInfo.clientIndex = clientIndex;
snprintf(packet.playerInfo.handle, PACKET_STRING_SIZE, "%s", config["player.handle"].c_str());
snprintf(packet.playerInfo.avatar, PACKET_STRING_SIZE, "%s", config["player.avatar"].c_str());
packet.playerInfo.position = {0,0};
packet.playerInfo.motion = {0,0};
//send it
char buffer[PACKET_BUFFER_SIZE];
serialize(&packet, buffer);
network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE);
//request a sync
packet.meta.type = NetworkPacket::Type::SYNCHRONIZE;
serialize(&packet, buffer);
network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE);
//debug
// RequestRegion(0, 0);
}
InWorld::~InWorld() {
//
}
//-------------------------
//Frame loop
//-------------------------
void InWorld::FrameStart() {
//
}
void InWorld::Update(double delta) {
NetworkPacket packet;
//suck in all waiting packets
while(network.Receive()) {
deserialize(&packet, network.GetInData());
packet.meta.srcAddress = network.GetInPacket()->address;
HandlePacket(packet);
}
//update the characters
for (auto& it : playerCharacters) {
it.second.Update(delta);
}
//TODO: sort the players and entities by Y position
//update the camera
if(localCharacter) {
camera.x = localCharacter->GetPosition().x - camera.marginX;
camera.y = localCharacter->GetPosition().y - camera.marginY;
}
//check the map
UpdateMap();
}
void InWorld::FrameEnd() {
//
}
void InWorld::RenderFrame() {
// SDL_FillRect(GetScreen(), 0, 0);
Render(GetScreen());
SDL_Flip(GetScreen());
}
void InWorld::Render(SDL_Surface* const screen) {
//draw the map
for (auto it = mapPager.GetContainer()->begin(); it != mapPager.GetContainer()->end(); it++) {
tileSheet.DrawRegionTo(screen, *it, camera.x, camera.y);
}
//draw characters
for (auto& it : playerCharacters) {
it.second.DrawTo(screen, camera.x, camera.y);
}
//draw UI
disconnectButton.DrawTo(screen);
shutDownButton.DrawTo(screen);
font.DrawStringTo(to_string_custom(fps.GetFrameRate()), screen, 0, 0);
fps.Calculate();
}
//-------------------------
//Event handlers
//-------------------------
void InWorld::QuitEvent() {
//exit the game AND the server
RequestDisconnect();
}
void InWorld::MouseMotion(SDL_MouseMotionEvent const& motion) {
disconnectButton.MouseMotion(motion);
shutDownButton.MouseMotion(motion);
}
void InWorld::MouseButtonDown(SDL_MouseButtonEvent const& button) {
disconnectButton.MouseButtonDown(button);
shutDownButton.MouseButtonDown(button);
}
void InWorld::MouseButtonUp(SDL_MouseButtonEvent const& button) {
if (disconnectButton.MouseButtonUp(button) == Button::State::HOVER) {
RequestDisconnect();
}
if (shutDownButton.MouseButtonUp(button) == Button::State::HOVER) {
RequestShutDown();
}
}
void InWorld::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
case SDLK_ESCAPE: {
QuitEvent();
}
break;
//player movement
case SDLK_LEFT:
if (localCharacter) {
localCharacter->AdjustDirection(PlayerCharacter::Direction::WEST);
SendState();
}
break;
case SDLK_RIGHT:
if (localCharacter) {
localCharacter->AdjustDirection(PlayerCharacter::Direction::EAST);
SendState();
}
break;
case SDLK_UP:
if (localCharacter) {
localCharacter->AdjustDirection(PlayerCharacter::Direction::NORTH);
SendState();
}
break;
case SDLK_DOWN:
if (localCharacter) {
localCharacter->AdjustDirection(PlayerCharacter::Direction::SOUTH);
SendState();
}
break;
}
}
void InWorld::KeyUp(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
//player movement
case SDLK_LEFT:
if (localCharacter) {
localCharacter->AdjustDirection(PlayerCharacter::Direction::EAST);
SendState();
}
break;
case SDLK_RIGHT:
if (localCharacter) {
localCharacter->AdjustDirection(PlayerCharacter::Direction::WEST);
SendState();
}
break;
case SDLK_UP:
if (localCharacter) {
localCharacter->AdjustDirection(PlayerCharacter::Direction::SOUTH);
SendState();
}
break;
case SDLK_DOWN:
if (localCharacter) {
localCharacter->AdjustDirection(PlayerCharacter::Direction::NORTH);
SendState();
}
break;
}
}
//-------------------------
//Network handlers
//-------------------------
void InWorld::HandlePacket(NetworkPacket packet) {
switch(packet.meta.type) {
case NetworkPacket::Type::DISCONNECT:
HandleDisconnect(packet);
break;
case NetworkPacket::Type::PLAYER_NEW:
HandlePlayerNew(packet);
break;
case NetworkPacket::Type::PLAYER_DELETE:
HandlePlayerDelete(packet);
break;
case NetworkPacket::Type::PLAYER_UPDATE:
HandlePlayerUpdate(packet);
break;
case NetworkPacket::Type::REGION_CONTENT:
HandleRegionContent(packet);
break;
//handle errors
default:
throw(std::runtime_error("Unknown NetworkPacket::Type encountered"));
break;
}
}
void InWorld::HandleDisconnect(NetworkPacket packet) {
network.Unbind(Channels::SERVER);
clientIndex = -1;
SetNextScene(SceneList::MAINMENU);
}
void InWorld::HandlePlayerNew(NetworkPacket packet) {
if (playerCharacters.find(packet.playerInfo.playerIndex) != playerCharacters.end()) {
throw(std::runtime_error("Cannot create duplicate players"));
}
playerCharacters[packet.playerInfo.playerIndex].GetSprite()->LoadSurface(config["dir.sprites"] + packet.playerInfo.avatar, 4, 4);
playerCharacters[packet.playerInfo.playerIndex].SetPosition(packet.playerInfo.position);
playerCharacters[packet.playerInfo.playerIndex].SetMotion(packet.playerInfo.motion);
playerCharacters[packet.playerInfo.playerIndex].ResetDirection();
//catch this client's player object
if (packet.playerInfo.clientIndex == clientIndex && !localCharacter) {
playerIndex = packet.playerInfo.playerIndex;
localCharacter = &playerCharacters[playerIndex];
//setup the camera
camera.width = GetScreen()->w;
camera.height = GetScreen()->h;
//center on the player's character
camera.marginX = (GetScreen()->w / 2 - localCharacter->GetSprite()->GetImage()->GetClipW() / 2);
camera.marginY = (GetScreen()->h / 2 - localCharacter->GetSprite()->GetImage()->GetClipH() / 2);
}
}
void InWorld::HandlePlayerDelete(NetworkPacket packet) {
if (playerCharacters.find(packet.playerInfo.playerIndex) == playerCharacters.end()) {
throw(std::runtime_error("Cannot delete non-existant players"));
}
playerCharacters.erase(packet.playerInfo.playerIndex);
//catch this client's player object
if (packet.playerInfo.clientIndex == clientIndex) {
playerIndex = -1;
localCharacter = nullptr;
}
}
void InWorld::HandlePlayerUpdate(NetworkPacket packet) {
if (playerCharacters.find(packet.playerInfo.playerIndex) == playerCharacters.end()) {
HandlePlayerNew(packet);
return;
}
//update only if the message didn't originate from here
if (packet.playerInfo.clientIndex != clientIndex) {
playerCharacters[packet.playerInfo.playerIndex].SetPosition(packet.playerInfo.position);
playerCharacters[packet.playerInfo.playerIndex].SetMotion(packet.playerInfo.motion);
}
playerCharacters[packet.playerInfo.playerIndex].ResetDirection();
}
void InWorld::HandleRegionContent(NetworkPacket packet) {
//replace existing regions
if (mapPager.FindRegion(packet.regionInfo.x, packet.regionInfo.y)) {
mapPager.UnloadRegion(packet.regionInfo.x, packet.regionInfo.y);
}
mapPager.PushRegion(packet.regionInfo.region);
packet.regionInfo.region = nullptr;
//debugging
cout << "Received region: " << packet.regionInfo.x << ", " << packet.regionInfo.y << endl;
if (mapPager.FindRegion(packet.regionInfo.x, packet.regionInfo.y)) {
cout << "Success" << endl;
}
else {
cout << "Failure" << endl;
}
}
//-------------------------
//Server control
//-------------------------
void InWorld::SendState() {
NetworkPacket packet;
char buffer[PACKET_BUFFER_SIZE];
//pack the packet
packet.meta.type = NetworkPacket::Type::PLAYER_UPDATE;
packet.playerInfo.clientIndex = clientIndex;
packet.playerInfo.playerIndex = playerIndex;
packet.playerInfo.position = localCharacter->GetPosition();
packet.playerInfo.motion = localCharacter->GetMotion();
serialize(&packet, buffer);
network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE);
}
void InWorld::RequestDisconnect() {
NetworkPacket packet;
char buffer[PACKET_BUFFER_SIZE];
//send a disconnect request
packet.meta.type = NetworkPacket::Type::DISCONNECT;
packet.clientInfo.index = clientIndex;
serialize(&packet, buffer);
network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE);
}
void InWorld::RequestShutDown() {
NetworkPacket packet;
char buffer[PACKET_BUFFER_SIZE];
//send a shutdown request
packet.meta.type = NetworkPacket::Type::SHUTDOWN;
packet.clientInfo.index = clientIndex;
serialize(&packet, buffer);
network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE);
}
void InWorld::RequestRegion(int x, int y) {
NetworkPacket packet;
char buffer[PACKET_BUFFER_SIZE];
//pack the region's data
packet.meta.type = NetworkPacket::Type::REGION_REQUEST;
packet.regionInfo.x = x;
packet.regionInfo.y = y;
serialize(&packet, buffer);
network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE);
}
//-------------------------
//Utilities
//-------------------------
int InWorld::CheckBufferDistance(Region* const region) {
/* DOCUMENTATION
* This algorithm is extremely complex and involed, but initial tests show
* that it gives the right answers. The purpose is to determine how far off screen
* a certain region is, so that it can be unloaded when necessary.
*
* If the region is actually onscreen, then there's no reason to run the rest, so
* the algorithm corrects for the camera's location, before checking the bounds of
* the screen.
*
* The next part is tricky. If X or Y is negative, then it is divided by the
* graphical size of the regions, resulting in a usable integer, representing how
* far from the screen it is in "region units". If, however, X or Y is larger than
* 0, than first, the size of the screen is subtracted from that variable, before
* it is then divided by the graphical size of a region. Finally, to compensate for
* the off by one error, 1 is added at the end.
*
* Since only the magnitude of the distance in either direction is needed, this
* method returns the largest absolute value of X or Y.
*
* The final result of this algorithm is an integer representing how far, rounded
* up, a certain region is from the screen's edges in any direction, measured in
* "region units". This algorithm may be flawed, in which case, I recommend simply
* replacing it with a boolean check, to see if the region's distance from the player
* is larger than a certain value. This algorithm lacks the advantages I initially
* expected, so that may be beneficial at some point.
*/
//locations relative to the camera
int x = region->GetX() - camera.x;
int y = region->GetY() - camera.y;
//if the region is visible, return -1
if (x >= -mapPager.GetRegionWidth() * tileSheet.GetTileW() && x < camera.width &&
y >= -mapPager.GetRegionHeight() * tileSheet.GetTileH() && y < camera.height) {
return -1;
}
//prune the screen's area from the algorithm; get the pseudo-indexes
if (x < 0) x /= (mapPager.GetRegionWidth() * tileSheet.GetTileW());
if (y < 0) y /= (mapPager.GetRegionHeight() * tileSheet.GetTileH());
if (x > 0) x = (x - camera.width) / (mapPager.GetRegionWidth() * tileSheet.GetTileW()) + 1;
if (y > 0) y = (y - camera.height) / (mapPager.GetRegionHeight() * tileSheet.GetTileH()) + 1;
//return the pseudo-index with the greatest magnitude
return std::max(abs(x), abs(y));
}
void InWorld::UpdateMap() {
//prune distant regions
for (auto it = mapPager.GetContainer()->begin(); it != mapPager.GetContainer()->end(); /* EMPTY */) {
if (CheckBufferDistance(*it) > 2) {
//debugging
cout << "unloading: " << (*it)->GetX() << ", " << (*it)->GetY() << endl;
mapPager.UnloadRegion((*it)->GetX(), (*it)->GetY());
//reset
it = mapPager.GetContainer()->begin();
continue;
}
++it;
}
//TODO: make the region units official
int regionUnitX = mapPager.GetRegionWidth() * tileSheet.GetTileW();
int regionUnitY = mapPager.GetRegionHeight() * tileSheet.GetTileH();
//request empty regions, including buffers (-1 & +1 region unit)
for (int i = snapToBase(regionUnitX, camera.x - regionUnitX); i <= snapToBase(regionUnitX, camera.x + camera.width + regionUnitX); i += regionUnitX) {
for (int j = snapToBase(regionUnitY, camera.y - regionUnitY); j <= snapToBase(regionUnitY, camera.y + camera.height + regionUnitY); j += regionUnitY) {
if (!mapPager.FindRegion(i, j)) {
RequestRegion(i, j);
}
}
}
}
+121
View File
@@ -0,0 +1,121 @@
/* Copyright: (c) Kayne Ruse 2013
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef INWORLD_HPP_
#define INWORLD_HPP_
//maps
#include "map_generator.hpp"
#include "map_file_format.hpp"
#include "region_pager.hpp"
//networking
#include "udp_network_utility.hpp"
#include "network_packet.hpp"
#include "serial.hpp"
//graphics
#include "image.hpp"
#include "raster_font.hpp"
#include "button.hpp"
#include "tile_sheet.hpp"
//common
#include "config_utility.hpp"
#include "frame_rate.hpp"
//client
#include "base_scene.hpp"
#include "player_character.hpp"
//STL
#include <map>
class InWorld : public BaseScene {
public:
//Public access members
InWorld(ConfigUtility* const, UDPNetworkUtility* const, int* const);
~InWorld();
protected:
//Frame loop
void FrameStart();
void Update(double delta);
void FrameEnd();
void RenderFrame();
void Render(SDL_Surface* const);
//Event handlers
void QuitEvent();
void MouseMotion(SDL_MouseMotionEvent const&);
void MouseButtonDown(SDL_MouseButtonEvent const&);
void MouseButtonUp(SDL_MouseButtonEvent const&);
void KeyDown(SDL_KeyboardEvent const&);
void KeyUp(SDL_KeyboardEvent const&);
//Network handlers
void HandlePacket(NetworkPacket);
void HandleDisconnect(NetworkPacket);
void HandlePlayerNew(NetworkPacket);
void HandlePlayerDelete(NetworkPacket);
void HandlePlayerUpdate(NetworkPacket);
void HandleRegionContent(NetworkPacket);
//Server control
void SendState();
void RequestDisconnect();
void RequestShutDown();
void RequestRegion(int x, int y);
//utilities
int CheckBufferDistance(Region* const);
void UpdateMap();
//globals
ConfigUtility& config;
FrameRate fps;
UDPNetworkUtility& network;
int& clientIndex;
//graphics
Image buttonImage;
RasterFont font;
TileSheet tileSheet;
//map
RegionPager<BlankGenerator, DummyFormat> mapPager;
//UI
Button disconnectButton;
Button shutDownButton;
struct {
int x = 0, y = 0;
int width = 0, height = 0;
int marginX = 0, marginY = 0;
} camera;
//game
std::map<int, PlayerCharacter> playerCharacters;
PlayerCharacter* localCharacter = nullptr;
int playerIndex = -1;
};
#endif
+204
View File
@@ -0,0 +1,204 @@
/* Copyright: (c) Kayne Ruse 2013
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "lobby_menu.hpp"
#include "channels.hpp"
#include <stdexcept>
//-------------------------
//Public access members
//-------------------------
LobbyMenu::LobbyMenu(ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex):
config(*argConfig),
network(*argNetwork),
clientIndex(*argClientIndex)
{
//setup the utility objects
image.LoadSurface(config["dir.interface"] + "button_menu.bmp");
image.SetClipH(image.GetClipH()/3);
font.LoadSurface(config["dir.fonts"] + "pk_white_8.bmp");
//pass the utility objects
search.SetImage(&image);
search.SetFont(&font);
join.SetImage(&image);
join.SetFont(&font);
back.SetImage(&image);
back.SetFont(&font);
//set the button positions
search.SetX(50);
search.SetY(50 + image.GetClipH() * 0);
join.SetX(50);
join.SetY(50 + image.GetClipH() * 1);
back.SetX(50);
back.SetY(50 + image.GetClipH() * 2);
//set the button texts
search.SetText("Search");
join.SetText("Join");
back.SetText("Back");
//set the server list's position
listBox = {300, 50, 200, font.GetCharH()};
}
LobbyMenu::~LobbyMenu() {
//
}
//-------------------------
//Frame loop
//-------------------------
void LobbyMenu::FrameStart() {
//
}
void LobbyMenu::Update(double delta) {
//suck in all waiting packets
NetworkPacket packet;
while(network.Receive()) {
deserialize(&packet, network.GetInData());
packet.meta.srcAddress = network.GetInPacket()->address;
HandlePacket(packet);
}
}
void LobbyMenu::FrameEnd() {
//
}
void LobbyMenu::Render(SDL_Surface* const screen) {
search.DrawTo(screen);
join.DrawTo(screen);
back.DrawTo(screen);
for (int i = 0; i < serverInfo.size(); i++) {
//draw the selected server's highlight
if (selection == &serverInfo[i]) {
SDL_Rect r = listBox;
r.y += i * listBox.h;
SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 255, 127, 39));
}
//draw the server name
font.DrawStringTo(serverInfo[i].name, screen, listBox.x, listBox.y + i*listBox.h);
}
}
//-------------------------
//Event handlers
//-------------------------
void LobbyMenu::MouseMotion(SDL_MouseMotionEvent const& motion) {
search.MouseMotion(motion);
join.MouseMotion(motion);
back.MouseMotion(motion);
}
void LobbyMenu::MouseButtonDown(SDL_MouseButtonEvent const& button) {
search.MouseButtonDown(button);
join.MouseButtonDown(button);
back.MouseButtonDown(button);
}
void LobbyMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) {
if (search.MouseButtonUp(button) == Button::State::HOVER) {
//the vars
NetworkPacket packet;
char buffer[PACKET_BUFFER_SIZE];
//broadcast to the network, or a specific server
packet.meta.type = NetworkPacket::Type::BROADCAST_REQUEST;
serialize(&packet, buffer);
network.Send(config["server.host"].c_str(), config.Int("server.port"), buffer, PACKET_BUFFER_SIZE);
//reset the server list
serverInfo.clear();
selection = nullptr;
}
else if (join.MouseButtonUp(button) == Button::State::HOVER && selection != nullptr) {
//the vars
NetworkPacket packet;
char buffer[PACKET_BUFFER_SIZE];
//join the selected server
packet.meta.type = NetworkPacket::Type::JOIN_REQUEST;
serialize(&packet, buffer);
network.Send(&selection->address, buffer, PACKET_BUFFER_SIZE);
selection = nullptr;
}
else if (back.MouseButtonUp(button) == Button::State::HOVER) {
SetNextScene(SceneList::MAINMENU);
}
else if (
//has the user selected a server on the list?
button.x > listBox.x &&
button.x < listBox.x + listBox.w &&
button.y > listBox.y &&
button.y < listBox.y + listBox.h * serverInfo.size()
) {
selection = &serverInfo[(button.y - listBox.y)/listBox.h];
}
else {
selection = nullptr;
}
}
void LobbyMenu::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
case SDLK_ESCAPE:
SetNextScene(SceneList::MAINMENU);
break;
}
}
void LobbyMenu::KeyUp(SDL_KeyboardEvent const& key) {
//
}
void LobbyMenu::HandlePacket(NetworkPacket packet) {
switch(packet.meta.type) {
case NetworkPacket::Type::BROADCAST_RESPONSE: {
ServerInformation server;
server.name = packet.serverInfo.name;
server.address = packet.meta.srcAddress;
serverInfo.push_back(server);
}
break;
case NetworkPacket::Type::JOIN_RESPONSE:
clientIndex = packet.clientInfo.index;
network.Bind(&packet.meta.srcAddress, Channels::SERVER);
SetNextScene(SceneList::INWORLD);
break;
//handle errors
default:
throw(std::runtime_error("Unknown NetworkPacket::Type encountered"));
break;
}
}
@@ -19,34 +19,27 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef LOBBY_HPP_
#define LOBBY_HPP_
#ifndef LOBBYMENU_HPP_
#define LOBBYMENU_HPP_
#include "base_scene.hpp"
#include "utilities.hpp"
#include "defines.hpp"
#include "singleton.hpp"
#include "server_entry.hpp"
#include "packet.hpp"
#include "network_queue.hpp"
#include "information_manager.hpp"
#include "image.hpp"
#include "raster_font.hpp"
#include "button.hpp"
#include "config_utility.hpp"
#include "surface_manager.hpp"
#include "udp_network_utility.hpp"
#include "button.hpp"
#include "raster_font.hpp"
#include "network_packet.hpp"
#include "serial.hpp"
#include <vector>
#include <string>
class Lobby : public BaseScene {
class LobbyMenu : public BaseScene {
public:
//Public access members
Lobby();
~Lobby();
LobbyMenu(ConfigUtility* const, UDPNetworkUtility* const, int* const);
~LobbyMenu();
protected:
//Frame loop
@@ -62,28 +55,32 @@ protected:
void KeyDown(SDL_KeyboardEvent const&);
void KeyUp(SDL_KeyboardEvent const&);
//utilities
int HandlePacket(Packet);
void BroadcastNetwork();
void PushServer(Packet&);
void ConnectToServer(ServerEntry*);
void BeginGame(Packet&);
void HandlePacket(NetworkPacket);
//services
ConfigUtility* configUtil = Singleton<ConfigUtility>::Get();
SurfaceManager* surfaceMgr = Singleton<SurfaceManager>::Get();
UDPNetworkUtility* netUtil = Singleton<UDPNetworkUtility>::Get();
InformationManager* infoMgr = Singleton<InformationManager>::Get();
//global
ConfigUtility& config;
UDPNetworkUtility& network;
int& clientIndex;
//members
Button refreshButton;
Button joinButton;
Button backButton;
Image image;
RasterFont font;
Button search;
Button join;
Button back;
//server list
struct ServerInformation {
std::string name;
IPaddress address;
};
std::vector<ServerInformation> serverInfo;
//a terrible hack, forgive me
//I'd love a proper gui system for this
SDL_Rect listBox;
std::vector<ServerEntry> serverList;
ServerEntry* selectedServer = nullptr;
ServerInformation* selection = nullptr;
};
#endif
@@ -21,27 +21,42 @@
*/
#include "main_menu.hpp"
#include <iostream>
using namespace std;
//-------------------------
//Public access members
//-------------------------
MainMenu::MainMenu() {
#ifdef DEBUG
cout << "entering MainMenu" << endl;
#endif
startButton.Setup(50, 50, surfaceMgr->Get("button"), surfaceMgr->Get("font"), "Start");
optionsButton.Setup(50, 100, surfaceMgr->Get("button"), surfaceMgr->Get("font"), "Options");
quitButton.Setup(50, 150, surfaceMgr->Get("button"), surfaceMgr->Get("font"), "Quit");
MainMenu::MainMenu(ConfigUtility* const argConfig):
config(*argConfig)
{
//setup the utility objects
image.LoadSurface(config["dir.interface"] + "button_menu.bmp");
image.SetClipH(image.GetClipH()/3);
font.LoadSurface(config["dir.fonts"] + "pk_white_8.bmp");
//pass the utility objects
startButton.SetImage(&image);
startButton.SetFont(&font);
optionsButton.SetImage(&image);
optionsButton.SetFont(&font);
quitButton.SetImage(&image);
quitButton.SetFont(&font);
//set the button positions
startButton.SetX(50);
startButton.SetY(50 + image.GetClipH() * 0);
optionsButton.SetX(50);
optionsButton.SetY(50 + image.GetClipH() * 1);
quitButton.SetX(50);
quitButton.SetY(50 + image.GetClipH() * 2);
//set the button texts
startButton.SetText("Start");
optionsButton.SetText("Options");
quitButton.SetText("Quit");
}
MainMenu::~MainMenu() {
#ifdef DEBUG
cout << "leaving MainMenu" << endl;
#endif
//
}
//-------------------------
@@ -84,10 +99,10 @@ void MainMenu::MouseButtonDown(SDL_MouseButtonEvent const& button) {
void MainMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) {
if (startButton.MouseButtonUp(button) == Button::State::HOVER) {
SetNextScene(SceneList::LOBBY);
SetNextScene(SceneList::LOBBYMENU);
}
if (optionsButton.MouseButtonUp(button) == Button::State::HOVER) {
SetNextScene(SceneList::OPTIONSCREEN);
SetNextScene(SceneList::OPTIONSMENU);
}
if (quitButton.MouseButtonUp(button) == Button::State::HOVER) {
QuitEvent();
@@ -98,6 +113,10 @@ void MainMenu::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
case SDLK_ESCAPE:
QuitEvent();
break;
break;
}
}
void MainMenu::KeyUp(SDL_KeyboardEvent const& key) {
//
}
@@ -23,32 +23,38 @@
#define MAINMENU_HPP_
#include "base_scene.hpp"
#include "singleton.hpp"
#include "surface_manager.hpp"
#include "config_utility.hpp"
#include "image.hpp"
#include "raster_font.hpp"
#include "button.hpp"
class MainMenu : public BaseScene {
public:
/* Public access members */
MainMenu();
//Public access members
MainMenu(ConfigUtility* const);
~MainMenu();
protected:
/* Frame loop */
//Frame loop
void FrameStart();
void Update(double delta);
void FrameEnd();
void Render(SDL_Surface* const);
/* Event handlers */
//Event handlers
void MouseMotion(SDL_MouseMotionEvent const&);
void MouseButtonDown(SDL_MouseButtonEvent const&);
void MouseButtonUp(SDL_MouseButtonEvent const&);
void KeyDown(SDL_KeyboardEvent const&);
void KeyUp(SDL_KeyboardEvent const&);
SurfaceManager* surfaceMgr = Singleton<SurfaceManager>::Get();
//globals
ConfigUtility& config;
//members
Image image;
RasterFont font;
Button startButton;
Button optionsButton;
Button quitButton;
+43
View File
@@ -0,0 +1,43 @@
#config
INCLUDES+=. .. ../../common ../../common/graphics ../../common/map ../../common/network ../../common/ui
LIBS+=
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES))
#source
CXXSRC=$(wildcard *.cpp)
CSRC=$(wildcard *.c)
#objects
OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
OBJ+=$(addprefix $(OBJDIR)/,$(CSRC:.c=.o))
#output
OUTDIR=..
OUT=$(addprefix $(OUTDIR)/,libclient.a)
#targets
all: $(OBJ) $(OUT)
ar -crs $(OUT) $(OBJ)
$(OBJ): | $(OBJDIR)
$(OUT): | $(OUTDIR)
$(OBJDIR):
mkdir $(OBJDIR)
$(OUTDIR):
mkdir $(OUTDIR)
$(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
$(OBJDIR)/%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
clean:
$(RM) *.o *.a *.exe
rebuild: clean all
@@ -19,59 +19,84 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "option_screen.hpp"
#include <iostream>
using namespace std;
#include "options_menu.hpp"
//-------------------------
//Public access members
//-------------------------
OptionScreen::OptionScreen() {
#ifdef DEBUG
cout << "entering OptionScreen" << endl;
#endif
backButton.Setup(50, 50, surfaceMgr->Get("button"), surfaceMgr->Get("font"), "Back");
OptionsMenu::OptionsMenu(ConfigUtility* const argConfig):
config(*argConfig)
{
//setup the utility objects
image.LoadSurface(config["dir.interface"] + "button_menu.bmp");
image.SetClipH(image.GetClipH()/3);
font.LoadSurface(config["dir.fonts"] + "pk_white_8.bmp");
//pass the utility objects
backButton.SetImage(&image);
backButton.SetFont(&font);
//set the button positions
backButton.SetX(50);
backButton.SetY(50 + image.GetClipH() * 0);
//set the button texts
backButton.SetText("Back");
}
OptionScreen::~OptionScreen() {
#ifdef DEBUG
cout << "leaving OptionScreen" << endl;
#endif
OptionsMenu::~OptionsMenu() {
//
}
//-------------------------
//Frame loop
//-------------------------
void OptionScreen::Render(SDL_Surface* const screen) {
void OptionsMenu::FrameStart() {
//
}
void OptionsMenu::Update(double delta) {
//
}
void OptionsMenu::FrameEnd() {
//
}
void OptionsMenu::Render(SDL_Surface* const screen) {
backButton.DrawTo(screen);
font.DrawStringTo("Oh, were you looking for the options screen?", screen, 50, 30);
}
//-------------------------
//Event handlers
//-------------------------
void OptionScreen::MouseMotion(SDL_MouseMotionEvent const& motion) {
void OptionsMenu::MouseMotion(SDL_MouseMotionEvent const& motion) {
backButton.MouseMotion(motion);
}
void OptionScreen::MouseButtonDown(SDL_MouseButtonEvent const& button) {
void OptionsMenu::MouseButtonDown(SDL_MouseButtonEvent const& button) {
backButton.MouseButtonDown(button);
}
void OptionScreen::MouseButtonUp(SDL_MouseButtonEvent const& button) {
void OptionsMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) {
if (backButton.MouseButtonUp(button) == Button::State::HOVER) {
SetNextScene(SceneList::MAINMENU);
}
}
void OptionScreen::KeyDown(SDL_KeyboardEvent const& key) {
void OptionsMenu::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
case SDLK_ESCAPE:
SetNextScene(SceneList::MAINMENU);
break;
break;
}
}
void OptionsMenu::KeyUp(SDL_KeyboardEvent const& key) {
//
}
@@ -19,32 +19,42 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef OPTIONSCREEN_HPP_
#define OPTIONSCREEN_HPP_
#ifndef OPTIONSMENU_HPP_
#define OPTIONSMENU_HPP_
#include "base_scene.hpp"
#include "singleton.hpp"
#include "surface_manager.hpp"
#include "config_utility.hpp"
#include "image.hpp"
#include "raster_font.hpp"
#include "button.hpp"
class OptionScreen : public BaseScene {
class OptionsMenu : public BaseScene {
public:
/* Public access members */
OptionScreen();
~OptionScreen();
//Public access members
OptionsMenu(ConfigUtility* const);
~OptionsMenu();
protected:
/* Frame loop */
//Frame loop
void FrameStart();
void Update(double delta);
void FrameEnd();
void Render(SDL_Surface* const);
/* Event handlers */
//Event handlers
void MouseMotion(SDL_MouseMotionEvent const&);
void MouseButtonDown(SDL_MouseButtonEvent const&);
void MouseButtonUp(SDL_MouseButtonEvent const&);
void KeyDown(SDL_KeyboardEvent const&);
void KeyUp(SDL_KeyboardEvent const&);
SurfaceManager* surfaceMgr = Singleton<SurfaceManager>::Get();
//globals
ConfigUtility& config;
//members
Image image;
RasterFont font;
Button backButton;
};
@@ -19,36 +19,33 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "image.hpp"
#include "splash_screen.hpp"
Image::Image(SDL_Surface* p) {
SetSurface(p);
//-------------------------
//Public access members
//-------------------------
SplashScreen::SplashScreen(ConfigUtility* const argConfig):
config(*argConfig)
{
logo.LoadSurface(config["dir.logos"] + "krstudios.bmp");
startTick = std::chrono::steady_clock::now();
}
Image::Image(SDL_Surface* p, SDL_Rect r) {
SetSurface(p, r);
SplashScreen::~SplashScreen() {
//
}
SDL_Surface* Image::SetSurface(SDL_Surface* p) {
if (!(surface = p)) {
clip = {0, 0, 0, 0};
//-------------------------
//Frame loop
//-------------------------
void SplashScreen::Update(double delta) {
if (std::chrono::steady_clock::now() - startTick > std::chrono::duration<int>(1)) {
SetNextScene(SceneList::MAINMENU);
}
else {
clip = {0, 0, (Uint16)surface->w, (Uint16)surface->h};
}
return surface;
}
SDL_Surface* Image::SetSurface(SDL_Surface* const p, SDL_Rect r) {
surface = p;
clip = r;
return surface;
}
void Image::DrawTo(SDL_Surface* dest, Sint16 x, Sint16 y) {
if (!surface) {
return;
}
SDL_Rect sclip = clip, dclip = {x,y};
SDL_BlitSurface(surface, &sclip, dest, &dclip);
void SplashScreen::Render(SDL_Surface* const screen) {
logo.DrawTo(screen, (screen->w - logo.GetClipW()) / 2, (screen->h - logo.GetClipH()) / 2);
}
@@ -23,31 +23,29 @@
#define SPLASHSCREEN_HPP_
#include "base_scene.hpp"
#include "singleton.hpp"
#include "config_utility.hpp"
#include "surface_manager.hpp"
#include "image.hpp"
#include <chrono>
class SplashScreen : public BaseScene {
public:
/* Public access members */
SplashScreen();
//Public access members
SplashScreen(ConfigUtility* const);
~SplashScreen();
protected:
/* Frame loop */
void RunFrame(double delta);
void RenderFrame();
void LoadResources();
//Frame loop
void Update(double delta);
void Render(SDL_Surface* const);
bool loaded = false;
ConfigUtility* configUtil = Singleton<ConfigUtility>::Get();
SurfaceManager* surfaceMgr = Singleton<SurfaceManager>::Get();
//globals
ConfigUtility& config;
//members
std::chrono::steady_clock::time_point startTick;
Image logo;
std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
};
#endif
-86
View File
@@ -1,86 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "splash_screen.hpp"
#include <iostream>
using namespace std;
//-------------------------
//Public access members
//-------------------------
SplashScreen::SplashScreen() {
#ifdef DEBUG
cout << "entering SplashScreen" << endl;
#endif
logo.SetSurface(surfaceMgr->Load("splash-logo", configUtil->String("logos") + "/krstudios.bmp"));
}
SplashScreen::~SplashScreen() {
surfaceMgr->Free("splash-logo");
#ifdef DEBUG
cout << "leaving SplashScreen" << endl;
#endif
}
//-------------------------
//Frame loop
//-------------------------
void SplashScreen::RunFrame(double delta) {
HandleEvents();
if (!loaded) {
//never repeat this
loaded = true;
//quick draw
RenderFrame();
LoadResources();
}
if (std::chrono::steady_clock::now() - start > std::chrono::duration<int>(1)) {
SetNextScene(SceneList::MAINMENU);
}
}
void SplashScreen::RenderFrame() {
SDL_FillRect(GetScreen(), 0, 0);
int x = (GetScreen()->w - logo.GetClipW()) / 2;
int y = (GetScreen()->h - logo.GetClipH()) / 2;
logo.DrawTo(GetScreen(), x, y);
SDL_Flip(GetScreen());
}
void SplashScreen::LoadResources() {
//standard
surfaceMgr->Load("font", configUtil->String("fonts") + "/pokemon_dark_font.bmp");
surfaceMgr->Load("button", configUtil->String("interface") + "/button.bmp");
//debugging
surfaceMgr->Load("elliot", configUtil->String("sprites") + "/elliot2.bmp");
surfaceMgr->Load("coa", configUtil->String("sprites") + "/coa2.bmp");
surfaceMgr->Load("flower", configUtil->String("sprites") + "/aniflower.bmp");
surfaceMgr->Load("terrain", configUtil->String("tilesets") + "/terrain.bmp");
//TODO
}
@@ -21,8 +21,9 @@
*/
#include "config_utility.hpp"
#include <stdexcept>
#include <cstdlib>
#include <fstream>
#include <stdexcept>
using namespace std;
@@ -74,3 +75,31 @@ void ConfigUtility::Load(string fname) {
is.close();
}
std::string& ConfigUtility::String(std::string s) {
return table[s];
}
int ConfigUtility::Integer(std::string s) {
std::map<std::string, std::string>::iterator it = table.find(s);
if (it == table.end()) {
return 0;
}
return atoi(it->second.c_str());
}
double ConfigUtility::Double(std::string s) {
std::map<std::string, std::string>::iterator it = table.find(s);
if (it == table.end()) {
return 0.0;
}
return atof(it->second.c_str());
}
bool ConfigUtility::Boolean(std::string s) {
std::map<std::string, std::string>::iterator it = table.find(s);
if (it == table.end()) {
return false;
}
return it->second == "true";
}
@@ -24,40 +24,32 @@
#include <map>
#include <string>
#include <cstdlib>
class ConfigUtility {
public:
ConfigUtility() {}
ConfigUtility() = default;
ConfigUtility(std::string s) { Load(s); }
void Load(std::string fname);
std::string String(std::string s) {
return table[s];
}
const char* CString(std::string s) {
return table[s].c_str();
}
int Integer(std::string s) {
return atoi(table[s].c_str());
}
double Double(std::string s) {
return atof(table[s].c_str());
}
bool Boolean(std::string s) {
return table[s] == "true";
}
//convert to a type
std::string& String(std::string);
int Integer(std::string);
double Double(std::string);
bool Boolean(std::string);
//shorthand
std::string& operator[](std::string s) {
return table[s];
return String(s);
}
int Int(std::string s) {
return Integer(s);
}
int Bool(std::string s) {
bool Bool(std::string s) {
return Boolean(s);
}
//OO breaker
std::map<std::string, std::string>* GetMap() {
return &table;
}
@@ -1,4 +1,4 @@
/* Copyright: (c) Kayne Ruse 2013
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
@@ -22,7 +22,27 @@
#ifndef FRAMERATE_HPP_
#define FRAMERATE_HPP_
int ClockFrameRate();
int GetFrameRate();
#include <chrono>
class FrameRate {
public:
typedef std::chrono::high_resolution_clock Clock;
FrameRate() = default;
int Calculate() {
frameCount++;
if (Clock::now() - tick >= std::chrono::duration<int>(1)) {
lastFrameRate = frameCount;
frameCount = 0;
tick = Clock::now();
}
return lastFrameRate;
}
int GetFrameRate() { return lastFrameRate; }
private:
int frameCount = 0;
int lastFrameRate = 0;
Clock::time_point tick = Clock::now();
};
#endif
+145
View File
@@ -0,0 +1,145 @@
/* Copyright: (c) Kayne Ruse 2013
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "image.hpp"
#include <stdexcept>
#include <sstream>
Image& Image::operator=(Image const& rhs) {
//don't screw yourself
if (this == &rhs) {
return *this;
}
FreeSurface();
//Copy the other Image's stuff
surface = rhs.surface;
clip = rhs.clip;
local = false;
}
Image& Image::operator=(Image&& rhs) {
//don't screw yourself
if (this == &rhs) {
return *this;
}
FreeSurface();
//Steal the other Image's stuff
surface = rhs.surface;
clip = rhs.clip;
local = rhs.local;
rhs.surface = nullptr;
rhs.clip = {0, 0, 0, 0};
rhs.local = false;
}
SDL_Surface* Image::LoadSurface(std::string fname) {
FreeSurface();
SDL_Surface* p = SDL_LoadBMP(fname.c_str());
if (!p) {
std::ostringstream os;
os << "Failed to load file: " << fname;
throw(std::runtime_error(os.str()));
}
surface = p;
clip = {0, 0, (Uint16)surface->w, (Uint16)surface->h};
local = true;
SetTransparentColor(255, 0, 255); //default
return surface;
}
SDL_Surface* Image::CreateSurface(Uint16 w, Uint16 h) {
FreeSurface();
Uint32 rmask, gmask, bmask, amask;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0xff000000;
gmask = 0x00ff0000;
bmask = 0x0000ff00;
amask = 0x000000ff;
#else
rmask = 0x000000ff;
gmask = 0x0000ff00;
bmask = 0x00ff0000;
amask = 0xff000000;
#endif
SDL_Surface* p = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, rmask, gmask, bmask, amask);
if (!p) {
throw(std::runtime_error("Failed to create Image surface"));
}
surface = p;
clip = {0, 0, (Uint16)surface->w, (Uint16)surface->h};
local = true;
SetTransparentColor(255, 0, 255); //default
return surface;
}
SDL_Surface* Image::SetSurface(SDL_Surface* p) {
FreeSurface();
if (!p) {
throw(std::invalid_argument("No surface pointer provided"));
}
surface = p;
clip = {0, 0, (Uint16)surface->w, (Uint16)surface->h};
local = false;
return surface;
}
void Image::FreeSurface() {
if (local) {
SDL_FreeSurface(surface);
local = false;
}
surface = nullptr;
clip = {0, 0, 0, 0};
}
void Image::DrawTo(SDL_Surface* dest, Sint16 x, Sint16 y) {
if (!surface) {
throw(std::logic_error("No image surface to draw"));
}
SDL_Rect sclip = clip, dclip = {x,y};
SDL_BlitSurface(surface, &sclip, dest, &dclip);
}
void Image::SetTransparentColor(Uint8 r, Uint8 g, Uint8 b) {
if (!surface) {
throw(std::logic_error("Failed to set the transparent color"));
}
if (!local) {
throw(std::logic_error("Cannot set the transparent color of a non-local surface"));
}
SDL_SetColorKey(surface, SDL_SRCCOLORKEY, SDL_MapRGB(surface->format, r, g, b));
}
void Image::ClearTransparentColor() {
if (!surface) {
throw(std::logic_error("Failed to clear the transparent color"));
}
if (!local) {
throw(std::logic_error("Cannot clear the transparent color of a non-local surface"));
}
SDL_SetColorKey(surface, 0, 0);
}
@@ -23,17 +23,26 @@
#define IMAGE_HPP_
#include "SDL/SDL.h"
#include <string>
class Image {
public:
Image() = default;
Image(SDL_Surface*);
Image(SDL_Surface*, SDL_Rect);
~Image() = default;
Image(Image const& rhs) { *this = rhs; }
Image(Image&& rhs) { *this = std::move(rhs); }
Image(std::string fname) { LoadSurface(fname); }
Image(Uint16 w, Uint16 h) { CreateSurface(w, h); }
Image(SDL_Surface* p) { SetSurface(p); }
~Image() { FreeSurface(); }
Image& operator=(Image const&);
Image& operator=(Image&&);
SDL_Surface* LoadSurface(std::string fname);
SDL_Surface* CreateSurface(Uint16 w, Uint16 h);
SDL_Surface* SetSurface(SDL_Surface*);
SDL_Surface* SetSurface(SDL_Surface*, SDL_Rect);
SDL_Surface* GetSurface() const { return surface; }
void FreeSurface();
void DrawTo(SDL_Surface* const, Sint16 x, Sint16 y);
@@ -50,9 +59,15 @@ public:
Sint16 GetClipY() const { return clip.y; }
Uint16 GetClipW() const { return clip.w; }
Uint16 GetClipH() const { return clip.h; }
bool GetLocal() const { return local; }
void SetTransparentColor(Uint8 r, Uint8 g, Uint8 b);
void ClearTransparentColor();
protected:
SDL_Surface* surface = nullptr;
SDL_Rect clip = {0, 0, 0, 0};
bool local = false;
};
#endif
@@ -1,20 +1,21 @@
#config
LIBDIR=..
LOCALLIBS=
LIB=
INCLUDES=
INCLUDES+=. .. ../map
LIBS+=
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES))
#source
SRC=$(wildcard *.cpp)
CXXSRC=$(wildcard *.cpp)
CSRC=$(wildcard *.c)
#objects
OBJDIR=obj
OBJ=$(addprefix $(OBJDIR)/,$(SRC:.cpp=.o))
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
OBJ+=$(addprefix $(OBJDIR)/,$(CSRC:.c=.o))
#output
OUTDIR=../out
OUT=$(addprefix $(OUTDIR)/,libCodebase.a)
OUTDIR=../..
OUT=$(addprefix $(OUTDIR)/,libcommon.a)
#targets
all: $(OBJ) $(OUT)
@@ -33,6 +34,9 @@ $(OUTDIR):
$(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
$(OBJDIR)/%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
clean:
$(RM) *.o *.a *.exe
+102
View File
@@ -0,0 +1,102 @@
/* Copyright: (c) Kayne Ruse 2013
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "sprite_sheet.hpp"
#include <stdexcept>
#include <sstream>
void SpriteSheet::Update(double delta) {
if (delay && (tick += delta) >= delay) {
if (++xIndex >= xCount) {
xIndex = 0;
}
tick = 0;
}
image.SetClipX(xIndex * image.GetClipW());
image.SetClipY(yIndex * image.GetClipH());
}
SDL_Surface* SpriteSheet::LoadSurface(std::string fname, Uint16 xCellCount, Uint16 yCellCount) {
image.LoadSurface(fname);
xCount = xCellCount;
yCount = yCellCount;
image.SetClipW(image.GetSurface()->w / xCount);
image.SetClipH(image.GetSurface()->h / yCount);
xIndex = yIndex = 0;
delay = tick = 0.0;
}
SDL_Surface* SpriteSheet::SetSurface(SDL_Surface* surface, Uint16 xCellCount, Uint16 yCellCount) {
image.SetSurface(surface);
xCount = xCellCount;
yCount = yCellCount;
image.SetClipW(image.GetSurface()->w / xCount);
image.SetClipH(image.GetSurface()->h / yCount);
xIndex = yIndex = 0;
delay = tick = 0.0;
}
void SpriteSheet::FreeSurface() {
image.FreeSurface();
xCount = yCount = 0;
xIndex = yIndex = 0;
delay = tick = 0.0;
}
Uint16 SpriteSheet::SetXCount(Uint16 i) {
xIndex = 0;
return xCount = i;
}
Uint16 SpriteSheet::SetYCount(Uint16 i) {
yIndex = 0;
return yCount = i;
}
Uint16 SpriteSheet::SetXIndex(Uint16 i) {
if (i > xCount) {
std::ostringstream os;
os << "Cannot set x index to " << i;
throw(std::invalid_argument(os.str()));
}
return xIndex = i;
}
Uint16 SpriteSheet::SetYIndex(Uint16 i) {
if (i > yCount) {
std::ostringstream os;
os << "Cannot set y index to " << i;
throw(std::invalid_argument(os.str()));
}
return yIndex = i;
}
double SpriteSheet::SetDelay(double d) {
tick = 0;
return delay = d;
}
+66
View File
@@ -0,0 +1,66 @@
/* Copyright: (c) Kayne Ruse 2013
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef SPRITESHEET_HPP_
#define SPRITESHEET_HPP_
#include "image.hpp"
class SpriteSheet {
public:
SpriteSheet() = default;
SpriteSheet(std::string fname, Uint16 xCellCount, Uint16 yCellCount) { LoadSurface(fname, xCellCount, yCellCount); }
SpriteSheet(SDL_Surface* surface, Uint16 xCellCount, Uint16 yCellCount) { SetSurface(surface, xCellCount, yCellCount); }
~SpriteSheet() { FreeSurface(); };
void Update(double delta);
SDL_Surface* LoadSurface(std::string fname, Uint16 xCellCount, Uint16 yCellCount);
SDL_Surface* SetSurface(SDL_Surface* surface, Uint16 xCellCount, Uint16 yCellCount);
SDL_Surface* GetSurface() { return image.GetSurface(); }
void FreeSurface();
void DrawTo(SDL_Surface* const dest, Sint16 x, Sint16 y) { image.DrawTo(dest, x, y); }
//accessors and mutators
Image* GetImage() { return &image; } //OO breaker
Uint16 SetXCount(Uint16);
Uint16 SetYCount(Uint16);
Uint16 SetXIndex(Uint16);
Uint16 SetYIndex(Uint16);
Uint16 GetXCount() const { return xCount; }
Uint16 GetYCount() const { return yCount; }
Uint16 GetXIndex() const { return xIndex; }
Uint16 GetYIndex() const { return yIndex; }
double SetDelay(double d);
double GetDelay() const { return delay; }
private:
Image image;
Uint16 xCount = 0, yCount = 0; //number of cells
Uint16 xIndex = 0, yIndex = 0; //current cell being drawn
double delay = 0.0, tick = 0.0;
};
#endif
+61
View File
@@ -0,0 +1,61 @@
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "tile_sheet.hpp"
void TileSheet::Load(std::string fname, int xc, int yc) {
XCount = xc;
YCount = yc;
image.LoadSurface(fname);
image.SetClipW(image.GetClipW()/XCount);
image.SetClipH(image.GetClipH()/YCount);
}
void TileSheet::Unload() {
image.FreeSurface();
XCount = YCount = 0;
}
void TileSheet::DrawTo(SDL_Surface* const dest, int x, int y, Region::type_t tile) {
//0 is invisible
if (tile == 0) return;
image.SetClipX((tile-1) % XCount * image.GetClipW());
image.SetClipY((tile-1) / XCount * image.GetClipH());
image.DrawTo(dest, x, y);
}
void TileSheet::DrawRegionTo(SDL_Surface* const dest, Region* const region, int camX, int camY) {
Region::type_t tile = 0;
for (register int i = 0; i < region->GetWidth(); ++i) {
for (register int j = 0; j < region->GetHeight(); ++j) {
for (register int k = 0; k < region->GetDepth(); ++k) {
tile = region->GetTile(i, j, k);
//0 is invisible
if (tile == 0) continue;
image.SetClipX((tile-1) % XCount * image.GetClipW());
image.SetClipY((tile-1) / XCount * image.GetClipH());
image.DrawTo(dest,
region->GetX() + i * image.GetClipW() - camX,
region->GetY() + j * image.GetClipH() - camY);
}
}
}
}
+54
View File
@@ -0,0 +1,54 @@
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef TILESHEET_HPP_
#define TILESHEET_HPP_
#include "region.hpp"
#include "image.hpp"
#include <string>
class TileSheet {
public:
TileSheet() = default;
TileSheet(std::string f, int x, int y) { Load(f, x, y); }
~TileSheet() = default;
void Load(std::string fname, int XCount, int YCount);
void Unload();
void DrawTo(SDL_Surface* const dest, int x, int y, Region::type_t tile);
void DrawRegionTo(SDL_Surface* const dest, Region* const region, int camX, int camY);
//accessors
Image* GetImage() { return &image; }
int GetXCount() { return XCount; }
int GetYCount() { return YCount; }
int GetTileW() { return image.GetClipW(); }
int GetTileH() { return image.GetClipH(); }
private:
Image image;
int XCount = 0, YCount = 0;
};
#endif
+48
View File
@@ -0,0 +1,48 @@
#config
INCLUDES+=.
LIBS+=
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES))
#source
CXXSRC=$(wildcard *.cpp)
CSRC=$(wildcard *.c)
#objects
OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
OBJ+=$(addprefix $(OBJDIR)/,$(CSRC:.c=.o))
#output
OUTDIR=..
OUT=$(addprefix $(OUTDIR)/,libcommon.a)
#targets
all: $(OBJ) $(OUT)
ar -crs $(OUT) $(OBJ)
$(MAKE) -C graphics
$(MAKE) -C map
$(MAKE) -C script
$(MAKE) -C network
$(MAKE) -C ui
$(OBJ): | $(OBJDIR)
$(OUT): | $(OUTDIR)
$(OBJDIR):
mkdir $(OBJDIR)
$(OUTDIR):
mkdir $(OUTDIR)
$(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
$(OBJDIR)/%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
clean:
$(RM) *.o *.a *.exe
rebuild: clean all
+43
View File
@@ -0,0 +1,43 @@
#config
INCLUDES+=. .. ../graphics
LIBS+=
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES))
#source
CXXSRC=$(wildcard *.cpp)
CSRC=$(wildcard *.c)
#objects
OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
OBJ+=$(addprefix $(OBJDIR)/,$(CSRC:.c=.o))
#output
OUTDIR=../..
OUT=$(addprefix $(OUTDIR)/,libcommon.a)
#targets
all: $(OBJ) $(OUT)
ar -crs $(OUT) $(OBJ)
$(OBJ): | $(OBJDIR)
$(OUT): | $(OUTDIR)
$(OBJDIR):
mkdir $(OBJDIR)
$(OUTDIR):
mkdir $(OUTDIR)
$(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
$(OBJDIR)/%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
clean:
$(RM) *.o *.a *.exe
rebuild: clean all
+79
View File
@@ -0,0 +1,79 @@
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "map_file_format.hpp"
#include <stdexcept>
void DummyFormat::Load(Region** const ptr, int width, int height, int depth, int x, int y) {
//EMPTY
}
void DummyFormat::Save(Region* const ptr) {
//EMPTY
}
/*
void VerboseFormat::Load(Region** const ptr, int x, int y) {
//TODO
}
void VerboseFormat::Save(Region* const ptr) {
//TODO
}
void CompactFormat::Load(Region** const ptr, int x, int y) {
//TODO
}
void CompactFormat::Save(Region* const ptr) {
//TODO
}
*/
void LuaFormat::Load(Region** const ptr, int width, int height, int depth, int x, int y) {
//something to load into
(*ptr) = new Region(width, height, depth, x, y);
//API hook
lua_getglobal(state, "Region");
lua_getfield(state, -1, "Load");
lua_pushlightuserdata(state, *ptr);
lua_pushstring(state, saveDir.c_str());
if (lua_pcall(state, 2, 1, 0) != LUA_OK) {
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(state, -1) ));
}
if (lua_toboolean(state, -1) == false) {
delete (*ptr);
(*ptr) = nullptr;
}
lua_pop(state, 2);
}
void LuaFormat::Save(Region* const ptr) {
//API hook
lua_getglobal(state, "Region");
lua_getfield(state, -1, "Save");
lua_pushlightuserdata(state, ptr);
lua_pushstring(state, saveDir.c_str());
if (lua_pcall(state, 2, 0, 0) != LUA_OK) {
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(state, -1) ));
}
lua_pop(state, 1);
}
+79
View File
@@ -0,0 +1,79 @@
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef MAPFILEFORMAT_HPP_
#define MAPFILEFORMAT_HPP_
#include "region.hpp"
#include "lua/lua.hpp"
#include <string>
class DummyFormat {
public:
void Load(Region** const, int width, int height, int depth, int x, int y);
void Save(Region* const);
std::string SetSaveDir(std::string s) { return saveDir = s; }
std::string GetSaveDir() { return saveDir; }
private:
std::string saveDir;
};
/*
class VerboseFormat {
public:
void Load(Region** const, int width, int height, int depth, int x, int y);
void Save(Region* const);
std::string SetSaveDir(std::string s) { return saveDir = s; }
std::string GetSaveDir() { return saveDir; }
private:
std::string saveDir;
};
class CompactFormat {
public:
void Load(Region** const, int width, int height, int depth, int x, int y);
void Save(Region* const);
std::string SetSaveDir(std::string s) { return saveDir = s; }
std::string GetSaveDir() { return saveDir; }
private:
std::string saveDir;
};
*/
class LuaFormat {
public:
void Load(Region** const, int width, int height, int depth, int x, int y);
void Save(Region* const);
std::string SetSaveDir(std::string s) { return saveDir = s; }
std::string GetSaveDir() { return saveDir; }
lua_State* SetLuaState(lua_State* L) { return state = L; }
lua_State* GetLuaState() { return state; }
private:
std::string saveDir;
lua_State* state = nullptr;
};
#endif
+68
View File
@@ -0,0 +1,68 @@
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "map_generator.hpp"
#include <stdexcept>
void BlankGenerator::Create(Region** const ptr, int width, int height, int depth, int x, int y) {
(*ptr) = new Region(width, height, depth, x, y);
}
void BlankGenerator::Unload(Region* const ptr) {
delete ptr;
}
/*
void PerlinGenerator::Create(Region** const ptr, int width, int height, int depth, int x, int y) {
(*ptr) = new Region(width, height, depth, x, y);
}
void PerlinGenerator::Unload(Region* const ptr) {
delete ptr;
}
*/
void LuaGenerator::Create(Region** const ptr, int width, int height, int depth, int x, int y) {
//something to work on
(*ptr) = new Region(width, height, depth, x, y);
//API hook
lua_getglobal(state, "Region");
lua_getfield(state, -1, "Create");
lua_pushlightuserdata(state, *ptr);
if (lua_pcall(state, 1, 0, 0) != LUA_OK) {
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(state, -1) ));
}
lua_pop(state, 1);
}
void LuaGenerator::Unload(Region* const ptr) {
//API hook
lua_getglobal(state, "Region");
lua_getfield(state, -1, "Unload");
lua_pushlightuserdata(state, ptr);
if (lua_pcall(state, 1, 0, 0) != LUA_OK) {
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(state, -1) ));
}
lua_pop(state, 1);
//clean up the memory
delete ptr;
}
@@ -1,4 +1,4 @@
/* Copyright: (c) Kayne Ruse 2013
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
@@ -19,22 +19,38 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef INFORMATIONMANAGER_HPP_
#define INFORMATIONMANAGER_HPP_
#ifndef MAPGENERATOR_HPP_
#define MAPGENERATOR_HPP_
class InformationManager {
#include "region.hpp"
#include "lua/lua.hpp"
class BlankGenerator {
public:
int SetClientIndex(int i) { return clientIndex = i; }
int GetClientIndex() { return clientIndex; }
void ResetClientIndex() { clientIndex = -1; }
//one player at a time
int SetPlayerIndex(int i) { return playerIndex = i; }
int GetPlayerIndex() { return playerIndex; }
void ResetPlayerIndex() { playerIndex = -1; }
void Create(Region** const, int width, int height, int depth, int x, int y);
void Unload(Region* const);
private:
int clientIndex = -1;
int playerIndex = -1;
//
};
/*
class PerlinGenerator {
public:
void Create(Region** const, int width, int height, int depth, int x, int y);
void Unload(Region* const);
private:
//
};
*/
class LuaGenerator {
public:
void Create(Region** const, int width, int height, int depth, int x, int y);
void Unload(Region* const);
lua_State* SetLuaState(lua_State* L) { return state = L; }
lua_State* GetLuaState() { return state; }
private:
lua_State* state = nullptr;
};
#endif
@@ -1,4 +1,4 @@
/* Copyright: (c) Kayne Ruse 2013
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
@@ -19,26 +19,41 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "sprite_sheet.hpp"
#include "region.hpp"
SpriteSheet::SpriteSheet(SDL_Surface* s, Uint16 w, Uint16 h) {
SetSurface(s, w, h);
}
void SpriteSheet::Update(double delta) {
if (interval && (ticks += delta) >= interval) {
if (++currentFrame >= maxFrames) {
currentFrame = 0;
Region::Region(int argWidth, int argHeight, int argDepth, int argX, int argY):
width(argWidth),
height(argHeight),
depth(argDepth),
x(argX),
y(argY)
{
tiles = new type_t**[width];
for (register int i = 0; i < width; ++i) {
tiles[i] = new type_t*[height];
for (register int j = 0; j < height; ++j) {
tiles[i][j] = new type_t[depth];
for (register int k = 0; k < depth; ++k) {
tiles[i][j][k] = 0;
}
}
ticks = 0;
}
image.SetClipX(currentFrame * image.GetClipW());
image.SetClipY(currentStrip * image.GetClipH());
}
SDL_Surface* SpriteSheet::SetSurface(SDL_Surface* const s, Uint16 w, Uint16 h) {
image.SetSurface(s, {0, 0, w, h});
currentFrame = 0; maxFrames = image.GetSurface()->w / image.GetClipW();
currentStrip = 0; maxStrips = image.GetSurface()->h / image.GetClipH();
interval = ticks = 0;
Region::~Region() {
for (register int i = 0; i < width; ++i) {
for (register int j = 0; j < height; j++) {
delete tiles[i][j];
}
delete tiles[i];
}
delete tiles;
}
Region::type_t Region::SetTile(int x, int y, int z, type_t v) {
return tiles[x][y][z] = v;
}
Region::type_t Region::GetTile(int x, int y, int z) {
return tiles[x][y][z];
}
@@ -1,4 +1,4 @@
/* Copyright: (c) Kayne Ruse 2013
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
@@ -19,31 +19,39 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef SURFACEMANAGER_HPP_
#define SURFACEMANAGER_HPP_
#ifndef REGION_HPP_
#define REGION_HPP_
#include "SDL/SDL.h"
//temporary?
#define REGION_WIDTH 20
#define REGION_HEIGHT 20
#define REGION_DEPTH 3
#include <map>
#include <string>
class SurfaceManager {
class Region {
public:
SurfaceManager() = default;
~SurfaceManager() noexcept;
typedef unsigned short type_t;
SDL_Surface* Load(std::string key, std::string fname);
SDL_Surface* Reload(std::string key, std::string fname);
SDL_Surface* Get(std::string key);
SDL_Surface* Set(std::string key, SDL_Surface* ptr);
void Free(std::string key);
void FreeAll();
Region() = delete;
Region(int width, int height, int depth, int x, int y);
~Region();
SDL_Surface* operator[](std::string key) { return Get(key); };
type_t SetTile(int x, int y, int z, type_t v);
type_t GetTile(int x, int y, int z);
//accessors
int GetWidth() const { return width; }
int GetHeight() const { return height; }
int GetDepth() const { return depth; }
int GetX() const { return x; }
int GetY() const { return y; }
private:
SDL_Surface* LoadSurface(std::string key, std::string fname);
typedef std::map<std::string, SDL_Surface*> MapType;
MapType surfaceMap;
const int width;
const int height;
const int depth;
const int x;
const int y;
type_t*** tiles = nullptr;
};
#endif
+77
View File
@@ -0,0 +1,77 @@
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "region_pager.hpp"
#include "utility.hpp"
RegionPagerBase::RegionPagerBase(int argWidth, int argHeight, int argDepth):
regionWidth(argWidth),
regionHeight(argHeight),
regionDepth(argDepth)
{
//EMPTY
}
RegionPagerBase::~RegionPagerBase() {
//EMPTY
}
Region::type_t RegionPagerBase::SetTile(int x, int y, int z, Region::type_t v) {
Region* ptr = GetRegion(x, y);
return ptr->SetTile(x - ptr->GetX(), y - ptr->GetY(), z, v);
}
Region::type_t RegionPagerBase::GetTile(int x, int y, int z) {
Region* ptr = GetRegion(x, y);
return ptr->GetTile(x - ptr->GetX(), y - ptr->GetY(), z);
}
Region* RegionPagerBase::GetRegion(int x, int y) {
//snap the coords
x = snapToBase(regionWidth, x);
y = snapToBase(regionHeight, y);
//get the region by various means
//TODO: revert this try/catch point
Region* ptr = nullptr;
ptr = FindRegion(x, y);
if (ptr) return ptr;
ptr = LoadRegion(x, y);
if (ptr) return ptr;
return CreateRegion(x, y);
}
Region* RegionPagerBase::FindRegion(int x, int y) {
//find the region
for (std::list<Region*>::iterator it = regionList.begin(); it != regionList.end(); it++) {
if ((*it)->GetX() == x && (*it)->GetY() == y) {
return *it;
}
}
return nullptr;
}
Region* RegionPagerBase::PushRegion(Region* ptr) {
regionList.push_front(ptr);
return regionList.front();
}
+157
View File
@@ -0,0 +1,157 @@
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef REGIONPAGER_HPP_
#define REGIONPAGER_HPP_
#include "region.hpp"
#include "utility.hpp"
#include <list>
class RegionPagerBase {
public:
RegionPagerBase() = default;
RegionPagerBase(int regionWidth, int regionHeight, int regionDepth);
virtual ~RegionPagerBase();
//tile manipulation
Region::type_t SetTile(int x, int y, int z, Region::type_t v);
Region::type_t GetTile(int x, int y, int z);
//region manipulation
Region* GetRegion(int x, int y);
Region* FindRegion(int x, int y);
Region* PushRegion(Region*);
//interface
virtual Region* LoadRegion(int x, int y) = 0;
virtual Region* SaveRegion(int x, int y) = 0;
virtual Region* CreateRegion(int x, int y) = 0;
virtual void UnloadRegion(int x, int y) = 0;
//TODO: delete?
//accessors & mutators
//NOTE: don't change the sizes mid-program, it will cause issues
int SetRegionWidth(int i) { return regionWidth = i; }
int SetRegionHeight(int i) { return regionHeight = i; }
int SetRegionDepth(int i) { return regionDepth = i; }
int GetRegionWidth() const { return regionWidth; }
int GetRegionHeight() const { return regionHeight; }
int GetRegionDepth() const { return regionDepth; }
std::list<Region*>* GetContainer() { return &regionList; }
protected:
int regionWidth;
int regionHeight;
int regionDepth;
std::list<Region*> regionList;
};
template<typename MapGenerator, typename MapFileFormat>
class RegionPager : public RegionPagerBase {
public:
RegionPager() = default;
RegionPager(int w, int h, int d):
RegionPagerBase(w, h, d)
{
//EMPTY
}
~RegionPager() {
UnloadAll();
}
Region* LoadRegion(int x, int y) {
//snap the coords
x = snapToBase(regionWidth, x);
y = snapToBase(regionHeight, y);
//load the region if possible
Region* ptr = nullptr;
format.Load(&ptr, regionWidth, regionHeight, regionDepth, x, y);
if (ptr) {
regionList.push_back(ptr);
return ptr;
}
return nullptr;
}
Region* SaveRegion(int x, int y) {
//snap the coords
x = snapToBase(regionWidth, x);
y = snapToBase(regionHeight, y);
//find & save the region
for (std::list<Region*>::iterator it = regionList.begin(); it != regionList.end(); it++) {
if ((*it)->GetX() == x && (*it)->GetY() == y) {
format.Save(*it);
return *it;
}
}
return nullptr;
}
Region* CreateRegion(int x, int y) {
//snap the coords
x = snapToBase(regionWidth, x);
y = snapToBase(regionHeight, y);
//create and push the object
Region* ptr = nullptr;
generator.Create(&ptr, regionWidth, regionHeight, regionDepth, x, y);
regionList.push_back(ptr);
return ptr;
}
void UnloadRegion(int x, int y) {
//snap the coords
x = snapToBase(regionWidth, x);
y = snapToBase(regionHeight, y);
for (std::list<Region*>::iterator it = regionList.begin(); it != regionList.end(); /* EMPTY */) {
if ((*it)->GetX() == x && (*it)->GetY() == y) {
generator.Unload(*it);
regionList.erase(it);
//reset the loop, because of reasons
it = regionList.begin();
continue;
}
++it;
}
}
void UnloadAll() {
for (auto& it : regionList) {
generator.Unload(it);
}
regionList.clear();
}
//accessors
MapGenerator* GetGenerator() { return &generator; }
MapFileFormat* GetFormat() { return &format; }
protected:
MapGenerator generator;
MapFileFormat format;
};
#endif
@@ -1,20 +1,21 @@
#config
LIBDIR=..
LOCALLIBS=$(LIBDIR)/out/libCodebase.a
LIB=
INCLUDES=$(LIBDIR)/Codebase
INCLUDES+=. .. ../map
LIBS+=
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES))
#source
SRC=$(wildcard *.cpp)
CXXSRC=$(wildcard *.cpp)
CSRC=$(wildcard *.c)
#objects
OBJDIR=obj
OBJ=$(addprefix $(OBJDIR)/,$(SRC:.cpp=.o))
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
OBJ+=$(addprefix $(OBJDIR)/,$(CSRC:.c=.o))
#output
OUTDIR=../out
OUT=$(addprefix $(OUTDIR)/,libCommon.a)
OUTDIR=../..
OUT=$(addprefix $(OUTDIR)/,libcommon.a)
#targets
all: $(OBJ) $(OUT)
@@ -33,6 +34,9 @@ $(OUTDIR):
$(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
$(OBJDIR)/%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
clean:
$(RM) *.o *.a *.exe
@@ -19,42 +19,59 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef PACKETTYPE_HPP_
#define PACKETTYPE_HPP_
#ifndef NETWORKPACKET_HPP_
#define NETWORKPACKET_HPP_
#include "vector2.hpp"
#include "region.hpp"
#include "SDL_net/SDL_net.h"
#include "SDL/SDL_net.h"
#define PACKET_STRING_SIZE 100
#pragma pack(push, 0)
union Packet {
//the type of packet being sent
union NetworkPacket {
//types of packets
enum class Type {
//default: there is something wrong
NONE = 0,
//not used
PING = 1,
PONG = 2,
//Searching for a server to join
BROADCAST_REQUEST = 3,
BROADCAST_RESPONSE = 4,
//try to join the server
JOIN_REQUEST = 5,
JOIN_RESPONSE = 6,
//disconnect from the server
DISCONNECT = 7,
//mass update
SYNCHRONIZE = 8,
PLAYER_NEW = 9,
PLAYER_DELETE = 10,
PLAYER_UPDATE = 11,
//shut down the server
SHUTDOWN = 9,
//Player movement, etc.
PLAYER_NEW = 10,
PLAYER_DELETE = 11,
PLAYER_UPDATE = 12,
//map data
REGION_REQUEST = 13,
REGION_CONTENT = 14,
};
//metadata on the packet itself
struct Metadata {
Type type;
IPaddress address;
int clientIndex;
IPaddress srcAddress;
}meta;
//information about the server
@@ -63,26 +80,38 @@ union Packet {
//TODO: version info
char name[PACKET_STRING_SIZE];
//TODO: player count
//TODO: map format
}serverInfo;
//information about a specific player
struct PlayerInformation {
//information about the client
struct ClientInformation {
Metadata meta;
int index;
}clientInfo;
//information about a player
struct PlayerInformation {
Metadata meta;
int clientIndex;
int playerIndex;
char handle[PACKET_STRING_SIZE];
char avatar[PACKET_STRING_SIZE];
Vector2 position;
Vector2 motion;
//TODO Playerdata
}playerInfo;
//zero the packet
Packet() {
//map data
struct RegionInformation {
Metadata meta;
int width, height, depth, x, y;
Region* region;
}regionInfo;
//defaults
NetworkPacket() {
meta.type = Type::NONE;
meta.address.host = 0;
meta.address.port = 0;
meta.clientIndex = -1;
};
meta.srcAddress = {0,0};
}
};
#pragma pack(pop)
+299
View File
@@ -0,0 +1,299 @@
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "serial.hpp"
#include "map_generator.hpp"
#include <cstring>
//-------------------------
//internal serialization functions
//-------------------------
void serializeType(NetworkPacket* packet, char* buffer) {
memcpy(buffer, &packet->meta.type, sizeof(NetworkPacket::Type));
}
void serializeServer(NetworkPacket* packet, char* buffer) {
memcpy(buffer, &packet->meta.type, sizeof(NetworkPacket::Type));
buffer += sizeof(NetworkPacket::Type);
memcpy(buffer, packet->serverInfo.name, PACKET_STRING_SIZE);
}
void serializeClient(NetworkPacket* packet, char* buffer) {
memcpy(buffer, &packet->meta.type, sizeof(NetworkPacket::Type));
buffer += sizeof(NetworkPacket::Type);
memcpy(buffer, &packet->clientInfo.index, sizeof(int));
}
void serializePlayer(NetworkPacket* packet, char* buffer) {
memcpy(buffer, &packet->meta.type, sizeof(NetworkPacket::Type));
buffer += sizeof(NetworkPacket::Type);
//indexes
memcpy(buffer, &packet->playerInfo.clientIndex, sizeof(int));
buffer += sizeof(int);
memcpy(buffer, &packet->playerInfo.playerIndex, sizeof(int));
buffer += sizeof(int);
//text
memcpy(buffer, packet->playerInfo.handle, PACKET_STRING_SIZE);
buffer += PACKET_STRING_SIZE;
memcpy(buffer, packet->playerInfo.avatar, PACKET_STRING_SIZE);
buffer += PACKET_STRING_SIZE;
//vectors
memcpy(buffer, &packet->playerInfo.position.x, sizeof(double));
buffer += sizeof(double);
memcpy(buffer, &packet->playerInfo.position.y, sizeof(double));
buffer += sizeof(double);
memcpy(buffer, &packet->playerInfo.motion.x, sizeof(double));
buffer += sizeof(double);
memcpy(buffer, &packet->playerInfo.motion.y, sizeof(double));
}
void serializeRegionFormat(NetworkPacket* packet, char* buffer) {
memcpy(buffer, &packet->meta.type, sizeof(NetworkPacket::Type));
buffer += sizeof(NetworkPacket::Type);
//size
memcpy(buffer, &packet->regionInfo.width, sizeof(int));
buffer += sizeof(int);
memcpy(buffer, &packet->regionInfo.height, sizeof(int));
buffer += sizeof(int);
memcpy(buffer, &packet->regionInfo.depth, sizeof(int));
buffer += sizeof(int);
//x & y
memcpy(buffer, &packet->regionInfo.x, sizeof(int));
buffer += sizeof(int);
memcpy(buffer, &packet->regionInfo.y, sizeof(int));
}
void serializeRegionContent(NetworkPacket* packet, char* buffer) {
//format
memcpy(buffer, &packet->meta.type, sizeof(NetworkPacket::Type));
buffer += sizeof(NetworkPacket::Type);
//size
*reinterpret_cast<int*>(buffer) = packet->regionInfo.region->GetWidth();
buffer += sizeof(int);
*reinterpret_cast<int*>(buffer) = packet->regionInfo.region->GetHeight();
buffer += sizeof(int);
*reinterpret_cast<int*>(buffer) = packet->regionInfo.region->GetDepth();
buffer += sizeof(int);
//x & y
*reinterpret_cast<int*>(buffer) = packet->regionInfo.region->GetX();
buffer += sizeof(int);
*reinterpret_cast<int*>(buffer) = packet->regionInfo.region->GetY();
buffer += sizeof(int);
//content
for (register int i = 0; i < packet->regionInfo.region->GetWidth(); i++) {
for (register int j = 0; j < packet->regionInfo.region->GetHeight(); j++) {
for (register int k = 0; k < packet->regionInfo.region->GetDepth(); k++) {
*reinterpret_cast<Region::type_t*>(buffer) = packet->regionInfo.region->GetTile(i, j, k);
buffer += sizeof(Region::type_t);
}
}
}
}
//-------------------------
//internal deserialization functions
//-------------------------
void deserializeType(NetworkPacket* packet, char* buffer) {
memcpy(&packet->meta.type, buffer, sizeof(NetworkPacket::Type));
}
void deserializeServer(NetworkPacket* packet, char* buffer) {
memcpy(&packet->meta.type, buffer, sizeof(NetworkPacket::Type));
buffer += sizeof(NetworkPacket::Type);
memcpy(packet->serverInfo.name, buffer, PACKET_STRING_SIZE);
}
void deserializeClient(NetworkPacket* packet, char* buffer) {
memcpy(&packet->meta.type, buffer, sizeof(NetworkPacket::Type));
buffer += sizeof(NetworkPacket::Type);
memcpy(&packet->clientInfo.index, buffer, sizeof(int));
}
void deserializePlayer(NetworkPacket* packet, char* buffer) {
memcpy(&packet->meta.type, buffer, sizeof(NetworkPacket::Type));
buffer += sizeof(NetworkPacket::Type);
//indexes
memcpy(&packet->playerInfo.clientIndex, buffer, sizeof(int));
buffer += sizeof(int);
memcpy(&packet->playerInfo.playerIndex, buffer, sizeof(int));
buffer += sizeof(int);
//text
memcpy(packet->playerInfo.handle, buffer, PACKET_STRING_SIZE);
buffer += PACKET_STRING_SIZE;
memcpy(packet->playerInfo.avatar, buffer, PACKET_STRING_SIZE);
buffer += PACKET_STRING_SIZE;
//vectors
memcpy(&packet->playerInfo.position.x, buffer, sizeof(double));
buffer += sizeof(double);
memcpy(&packet->playerInfo.position.y, buffer, sizeof(double));
buffer += sizeof(double);
memcpy(&packet->playerInfo.motion.x, buffer, sizeof(double));
buffer += sizeof(double);
memcpy(&packet->playerInfo.motion.y, buffer, sizeof(double));
}
void deserializeRegionFormat(NetworkPacket* packet, char* buffer) {
memcpy(&packet->meta.type, buffer, sizeof(NetworkPacket::Type));
buffer += sizeof(NetworkPacket::Type);
//size
memcpy(&packet->regionInfo.width, buffer, sizeof(int));
buffer += sizeof(int);
memcpy(&packet->regionInfo.height, buffer, sizeof(int));
buffer += sizeof(int);
memcpy(&packet->regionInfo.depth, buffer, sizeof(int));
buffer += sizeof(int);
//x & y
memcpy(&packet->regionInfo.x, buffer, sizeof(int));
buffer += sizeof(int);
memcpy(&packet->regionInfo.y, buffer, sizeof(int));
}
void deserializeRegionContent(NetworkPacket* packet, char* buffer) {
//format
deserializeRegionFormat(packet, buffer);
buffer += sizeof(int) * 5 + sizeof(NetworkPacket::Type);
//content
BlankGenerator().Create(
&packet->regionInfo.region,
packet->regionInfo.width,
packet->regionInfo.height,
packet->regionInfo.depth,
packet->regionInfo.x,
packet->regionInfo.y
);
for (register int i = 0; i < packet->regionInfo.region->GetWidth(); i++) {
for (register int j = 0; j < packet->regionInfo.region->GetHeight(); j++) {
for (register int k = 0; k < packet->regionInfo.region->GetDepth(); k++) {
packet->regionInfo.region->SetTile(i, j, k, *reinterpret_cast<Region::type_t*>(buffer));
buffer += sizeof(Region::type_t);
}
}
}
}
//-------------------------
//the interface functions
//-------------------------
void serialize(NetworkPacket* packet, void* buffer) {
switch(packet->meta.type) {
//No extra data
case NetworkPacket::Type::NONE:
case NetworkPacket::Type::PING:
case NetworkPacket::Type::PONG:
case NetworkPacket::Type::BROADCAST_REQUEST:
case NetworkPacket::Type::JOIN_REQUEST:
case NetworkPacket::Type::SYNCHRONIZE:
serializeType(packet, reinterpret_cast<char*>(buffer));
break;
//Server info
case NetworkPacket::Type::BROADCAST_RESPONSE:
serializeServer(packet, reinterpret_cast<char*>(buffer));
break;
//Client info
case NetworkPacket::Type::JOIN_RESPONSE:
case NetworkPacket::Type::DISCONNECT:
case NetworkPacket::Type::SHUTDOWN:
serializeClient(packet, reinterpret_cast<char*>(buffer));
break;
//Player info
case NetworkPacket::Type::PLAYER_NEW:
case NetworkPacket::Type::PLAYER_DELETE:
case NetworkPacket::Type::PLAYER_UPDATE:
serializePlayer(packet, reinterpret_cast<char*>(buffer));
break;
//region info
case NetworkPacket::Type::REGION_REQUEST:
serializeRegionFormat(packet, reinterpret_cast<char*>(buffer));
break;
case NetworkPacket::Type::REGION_CONTENT:
serializeRegionContent(packet, reinterpret_cast<char*>(buffer));
break;
}
}
void deserialize(NetworkPacket* packet, void* buffer) {
//find the type, so that you can actually deserialize the packet!
deserializeType(packet, reinterpret_cast<char*>(buffer));
switch(packet->meta.type) {
//No extra data
case NetworkPacket::Type::NONE:
case NetworkPacket::Type::PING:
case NetworkPacket::Type::PONG:
case NetworkPacket::Type::BROADCAST_REQUEST:
case NetworkPacket::Type::JOIN_REQUEST:
case NetworkPacket::Type::SYNCHRONIZE:
//NOTHING
break;
//Server info
case NetworkPacket::Type::BROADCAST_RESPONSE:
deserializeServer(packet, reinterpret_cast<char*>(buffer));
break;
//Client info
case NetworkPacket::Type::JOIN_RESPONSE:
case NetworkPacket::Type::DISCONNECT:
case NetworkPacket::Type::SHUTDOWN:
deserializeClient(packet, reinterpret_cast<char*>(buffer));
break;
//Player info
case NetworkPacket::Type::PLAYER_NEW:
case NetworkPacket::Type::PLAYER_DELETE:
case NetworkPacket::Type::PLAYER_UPDATE:
deserializePlayer(packet, reinterpret_cast<char*>(buffer));
break;
//region info
case NetworkPacket::Type::REGION_REQUEST:
deserializeRegionFormat(packet, reinterpret_cast<char*>(buffer));
break;
case NetworkPacket::Type::REGION_CONTENT:
deserializeRegionContent(packet, reinterpret_cast<char*>(buffer));
break;
}
}
@@ -1,4 +1,4 @@
/* Copyright: (c) Kayne Ruse 2013
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
@@ -19,16 +19,19 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef DEFINES_HPP_
#define DEFINES_HPP_
#ifndef SERIAL_HPP_
#define SERIAL_HPP_
#define GAME_CHANNEL 0
#define CHAT_CHANNEL 1
#include "network_packet.hpp"
#define WALKING_SPEED 140
/* Sending regions are the largest type of packet
* content: width * height * depth * sizoeof(type)
* map format: sizeof(int) * 5
* metadata: sizeof(metadata)
*/
#define PACKET_BUFFER_SIZE REGION_WIDTH * REGION_HEIGHT * REGION_DEPTH * sizeof(Region::type_t) + sizeof(int) * 5 + sizeof(NetworkPacket::Metadata)
enum class CardinalDirection {
NORTH, SOUTH, EAST, WEST
};
void serialize(NetworkPacket* const, void*);
void deserialize(NetworkPacket* const, void*);
#endif
@@ -22,7 +22,7 @@
#ifndef UDPNETWORKUTILITY_HPP_
#define UDPNETWORKUTILITY_HPP_
#include "SDL_net/SDL_net.h"
#include "SDL/SDL_net.h"
class UDPNetworkUtility {
public:
@@ -32,17 +32,9 @@ public:
void Open(int port, int packSize);
void Close();
//bind to an available channel
int Bind(const char* ip, int port) {
Bind(ip, port, -1);
}
int Bind(IPaddress* add) {
Bind(add, -1);
}
//bind to certain channel
int Bind(const char* ip, int port, int channel);
int Bind(IPaddress* add, int channel);
//bind to a channel
int Bind(const char* ip, int port, int channel = -1);
int Bind(IPaddress* add, int channel = -1);
void Unbind(int channel);
IPaddress* GetIPAddress(int channel) {
+72
View File
@@ -0,0 +1,72 @@
/*
** $Id: linit.c,v 1.32 2011/04/08 19:17:36 roberto Exp $
** Initialization of libraries for lua.c and other clients
** See Copyright Notice in lua.h
*/
/* Modified for use in Tortuga, renamed to linit.cpp
*/
/*
** If you embed Lua in your program and need to open the standard
** libraries, call luaL_openlibs in your program. If you need a
** different set of libraries, copy this file to your project and edit
** it to suit your needs.
*/
#define linit_c
#define LUA_LIB
#include "lua/lua.hpp"
#include "region_api.hpp"
/*
** these libs are loaded by lua.c and are readily available to any Lua
** program
*/
static const luaL_Reg loadedlibs[] = {
/* Standard libs */
{"_G", luaopen_base},
{LUA_LOADLIBNAME, luaopen_package},
{LUA_COLIBNAME, luaopen_coroutine},
{LUA_TABLIBNAME, luaopen_table},
{LUA_IOLIBNAME, luaopen_io},
{LUA_OSLIBNAME, luaopen_os},
{LUA_STRLIBNAME, luaopen_string},
{LUA_BITLIBNAME, luaopen_bit32},
{LUA_MATHLIBNAME, luaopen_math},
{LUA_DBLIBNAME, luaopen_debug},
/* custom libs */
{LUA_REGIONLIBNAME, luaopen_regionapi},
{NULL, NULL}
};
/*
** these libs are preloaded and must be required before used
*/
static const luaL_Reg preloadedlibs[] = {
{NULL, NULL}
};
LUALIB_API void luaL_openlibs (lua_State *L) {
const luaL_Reg *lib;
/* call open functions from 'loadedlibs' and set results to global table */
for (lib = loadedlibs; lib->func; lib++) {
luaL_requiref(L, lib->name, lib->func, 1);
lua_pop(L, 1); /* remove lib */
}
/* add open functions from 'preloadedlibs' into 'package.preload' table */
luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD");
for (lib = preloadedlibs; lib->func; lib++) {
lua_pushcfunction(L, lib->func);
lua_setfield(L, -2, lib->name);
}
lua_pop(L, 1); /* remove _PRELOAD table */
}
+43
View File
@@ -0,0 +1,43 @@
#config
INCLUDES+=. .. ../map
LIBS+=
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES))
#source
CXXSRC=$(wildcard *.cpp)
CSRC=$(wildcard *.c)
#objects
OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
OBJ+=$(addprefix $(OBJDIR)/,$(CSRC:.c=.o))
#output
OUTDIR=../..
OUT=$(addprefix $(OUTDIR)/,libcommon.a)
#targets
all: $(OBJ) $(OUT)
ar -crs $(OUT) $(OBJ)
$(OBJ): | $(OBJDIR)
$(OUT): | $(OUTDIR)
$(OBJDIR):
mkdir $(OBJDIR)
$(OUTDIR):
mkdir $(OUTDIR)
$(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
$(OBJDIR)/%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
clean:
$(RM) *.o *.a *.exe
rebuild: clean all
+91
View File
@@ -0,0 +1,91 @@
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "region_api.hpp"
#include "region.hpp"
static int setTile(lua_State* L) {
Region* ptr = (Region*)lua_touserdata(L, 1);
ptr->SetTile(lua_tointeger(L, 2)-1, lua_tointeger(L, 3)-1, lua_tointeger(L, 4)-1, lua_tointeger(L, 5));
return 0;
}
static int getTile(lua_State* L) {
Region* ptr = (Region*)lua_touserdata(L, 1);
int ret = ptr->GetTile(lua_tointeger(L, 2)-1, lua_tointeger(L, 3)-1, lua_tointeger(L, 4)-1);
lua_pushnumber(L, ret);
return 1;
}
static int getWidth(lua_State* L) {
Region* ptr = (Region*)lua_touserdata(L, 1);
lua_pushinteger(L, ptr->GetWidth());
return 1;
}
static int getHeight(lua_State* L) {
Region* ptr = (Region*)lua_touserdata(L, 1);
lua_pushinteger(L, ptr->GetHeight());
return 1;
}
static int getDepth(lua_State* L) {
Region* ptr = (Region*)lua_touserdata(L, 1);
lua_pushinteger(L, ptr->GetDepth());
return 1;
}
static int getX(lua_State* L) {
Region* ptr = (Region*)lua_touserdata(L, 1);
lua_pushinteger(L, ptr->GetX());
return 1;
}
static int getY(lua_State* L) {
Region* ptr = (Region*)lua_touserdata(L, 1);
lua_pushinteger(L, ptr->GetY());
return 1;
}
static int dummy(lua_State* L) {
return 0;
}
static const luaL_Reg regionlib[] = {
{"SetTile",setTile},
{"GetTile",getTile},
{"GetWidth",getWidth},
{"GetHeight",getHeight},
{"GetDepth",getDepth},
{"GetX",getX},
{"GetY",getY},
{"Create", dummy},
{"Unload", dummy},
{"Load", dummy},
{"Save", dummy},
{nullptr, nullptr}
};
LUAMOD_API int luaopen_regionapi(lua_State* L) {
luaL_newlib(L, regionlib);
return 1;
}
@@ -1,4 +1,4 @@
/* Copyright: (c) Kayne Ruse 2013
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
@@ -19,14 +19,12 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef CLIENTENTRY_HPP_
#define CLIENTENTRY_HPP_
#ifndef REGIONAPI_HPP_
#define REGIONAPI_HPP_
#include "SDL_net/SDL_net.h"
#include "lua/lua.hpp"
struct ClientEntry {
int index;
IPaddress address;
};
#define LUA_REGIONLIBNAME "Region"
LUAMOD_API int luaopen_regionapi(lua_State* L);
#endif
@@ -23,27 +23,8 @@
#include <stdexcept>
Button::Button(Sint16 i, Sint16 j, SDL_Surface* imageSurface, SDL_Surface* fontSurface, std::string s) {
Setup(i, j, imageSurface, fontSurface, s);
}
void Button::Setup(Sint16 i, Sint16 j, SDL_Surface* imageSurface, SDL_Surface* fontSurface, std::string s) {
x = i;
y = j;
SetSurfaces(imageSurface, fontSurface);
SetText(s);
}
Button::State Button::MouseMotion(SDL_MouseMotionEvent const& motion) {
if (motion.state & SDL_BUTTON_LMASK) {
return CalcState(motion.x, motion.y, true);
}
else {
return CalcState(motion.x, motion.y, false);
}
return state;
return CalcState(motion.x, motion.y, motion.state & SDL_BUTTON_LMASK);
}
Button::State Button::MouseButtonDown(SDL_MouseButtonEvent const& button) {
@@ -61,41 +42,40 @@ Button::State Button::MouseButtonUp(SDL_MouseButtonEvent const& button) {
}
void Button::DrawTo(SDL_Surface* const dest) {
image.DrawTo(dest, x, y);
font.DrawStringTo(text, dest, textX + x, textY + y);
if (!image || !font) {
throw(std::runtime_error("Surface not set for Button"));
}
image->SetClipY(state * image->GetClipH());
image->DrawTo(dest, x, y);
font->DrawStringTo(text, dest, textX + x, textY + y);
}
void Button::SetSurfaces(SDL_Surface* imageSurface, SDL_Surface* fontSurface) {
//graphical stuff
image.SetSurface(imageSurface);
image.SetClipH(image.GetClipH() / 3); //3 phases
font.SetSurface(fontSurface);
//reset textX & textY
SetText(text);
}
std::string Button::SetText(std::string s) {
//one line
text = s;
textX = (image.GetClipW() / 2) - (font.GetCharW() * text.size() / 2);
textY = (image.GetClipH() / 2) - (font.GetCharH() / 2);
std::string Button::SetText(std::string t) {
if (!image || !font) {
throw(std::runtime_error("Surface not set for Button"));
}
//one line, cache the position
text = t;
textX = (image->GetClipW() / 2) - (font->GetCharW() * text.size() / 2);
textY = (image->GetClipH() / 2) - (font->GetCharH() / 2);
return text;
}
Button::State Button::CalcState(Sint16 i, Sint16 j, bool leftPressed) {
if (i < x || i > (x + image.GetClipW()) ||
j < y || j > (y + image.GetClipH())
if (!image || !font) {
throw(std::runtime_error("Surface not set for Button"));
}
//if out of bounds
if (i < x || i >= (x + image->GetClipW()) ||
j < y || j >= (y + image->GetClipH())
) {
image.SetClipY(0);
return state = State::NORMAL;
}
if (leftPressed) {
image.SetClipY(image.GetClipH()*2);
return state = State::PRESSED;
}
else {
image.SetClipY(image.GetClipH());
return state = State::HOVER;
}
}
@@ -27,54 +27,66 @@
#include <string>
//3-phases, no toggle, centred text
/* 3-phases, no toggle, centred text
* This class uses the size of the provided image as its bounds. Also,
* The provided image should be formatted correctly.
*
* The button's image should be divided into 3 sections virtucally,
* which act as the different button images. The clip width & height of the
* Image should be set manually, and the height should be 1/3 of the total
* graphical data.
*/
class Button {
public:
enum class State {
NORMAL, HOVER, PRESSED
enum State {
NORMAL = 0, HOVER = 1, PRESSED = 2
};
Button() = default;
Button(Sint16 x, Sint16 y, SDL_Surface* imageSurface, SDL_Surface* fontSurface, std::string text = "");
~Button() = default;
void Setup(Sint16 x, Sint16 y, SDL_Surface* imageSurface, SDL_Surface* fontSurface, std::string text = "");
//return the current state
//handle input
State MouseMotion(SDL_MouseMotionEvent const&);
State MouseButtonDown(SDL_MouseButtonEvent const&);
State MouseButtonUp(SDL_MouseButtonEvent const&);
State GetState() const {
return state;
}
//yet another draw function
void DrawTo(SDL_Surface* const);
//simple accessors and mutators
//accessors and mutators
Image* SetImage(Image* const ptr) { return image = ptr; }
Image* GetImage() { return image; }
RasterFont* SetFont(RasterFont* const ptr) { return font = ptr; }
RasterFont* GetFont() { return font; }
Sint16 SetX(Sint16 i) { return x = i; }
Sint16 SetY(Sint16 i) { return y = i; }
Sint16 GetX() const { return x; }
Sint16 GetY() const { return y; }
void SetSurfaces(SDL_Surface* image, SDL_Surface* font);
std::string SetText(std::string s);
std::string GetText() const { return text; }
//raw access, be careful
Image* GetImage() { return &image; }
RasterFont* GetFont() { return &font; }
//debug
Sint16 SetTextX(Sint16 i) { return textX = i; }
Sint16 SetTextY(Sint16 i) { return textY = i; }
Sint16 GetTextX() const { return textX; }
Sint16 GetTextY() const { return textY; }
State SetState(State s) { return state = s; }
State GetState() const { return state; }
std::string SetText(std::string);
std::string GetText() const { return text; }
private:
State CalcState(Sint16 x, Sint16 y, bool leftPressed);
//point to the provided external objects
Image* image = nullptr;
RasterFont* font = nullptr;
//positions
Sint16 x = 0, y = 0;
Sint16 textX = 0, textY = 0; //prevent recalc every loop
Image image;
RasterFont font;
Sint16 textX = 0, textY = 0;
//
State state = State::NORMAL;
std::string text;
};
+43
View File
@@ -0,0 +1,43 @@
#config
INCLUDES+=. .. ../graphics
LIBS+=
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES))
#source
CXXSRC=$(wildcard *.cpp)
CSRC=$(wildcard *.c)
#objects
OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
OBJ+=$(addprefix $(OBJDIR)/,$(CSRC:.c=.o))
#output
OUTDIR=../..
OUT=$(addprefix $(OUTDIR)/,libcommon.a)
#targets
all: $(OBJ) $(OUT)
ar -crs $(OUT) $(OBJ)
$(OBJ): | $(OBJDIR)
$(OUT): | $(OUTDIR)
$(OBJDIR):
mkdir $(OBJDIR)
$(OUTDIR):
mkdir $(OUTDIR)
$(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
$(OBJDIR)/%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
clean:
$(RM) *.o *.a *.exe
rebuild: clean all
+139
View File
@@ -0,0 +1,139 @@
/* Copyright: (c) Kayne Ruse 2013
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "menu_bar.hpp"
#include <stdexcept>
#include <sstream>
void MenuBar::DrawTo(SDL_Surface* const dest) {
for (auto& i : entries) {
i.DrawTo(dest);
}
}
void MenuBar::MouseMotion(SDL_MouseMotionEvent const& motion) {
for (auto& i : entries) {
i.MouseMotion(motion);
}
}
void MenuBar::MouseButtonDown(SDL_MouseButtonEvent const& button) {
for (auto& i : entries) {
i.MouseButtonDown(button);
}
}
void MenuBar::MouseButtonUp(SDL_MouseButtonEvent const& button, int* entry, int* butt) {
*entry = *butt = -1;
int ret = -1;
for (auto& i : entries) {
ret = i.MouseButtonUp(button);
if (ret != -1) {
*entry = (&i - entries.data());
*butt = ret;
}
}
}
void MenuBar::SetEntries(std::vector<std::vector<std::string>> info) {
if (!image || !font) {
throw(std::runtime_error("Surfaces not loaded into the menu bar"));
}
entries.clear();
for (int i = 0; i < info.size(); i++) {
//create the entry & the main button
entries.push_back(MenuBarEntry());
entries[i].mainButton.SetImage(image);
entries[i].mainButton.SetFont(font);
entries[i].mainButton.SetText(info[i][0]);
entries[i].mainButton.SetX(i * image->GetClipW());
entries[i].mainButton.SetY(0);
for (int j = 0; j < info[i].size()-1; j++) {
//create each drop button in this entry
entries[i].dropButtons.push_back(Button());
entries[i].dropButtons[j].SetImage(image);
entries[i].dropButtons[j].SetFont(font);
entries[i].dropButtons[j].SetText(info[i][j+1]);
entries[i].dropButtons[j].SetX(i * image->GetClipW());
entries[i].dropButtons[j].SetY((j+1) * image->GetClipH());
}
}
}
void MenuBar::MenuBarEntry::DrawTo(SDL_Surface* const dest) {
//only draw the dropButtons in the user has this menu open
mainButton.DrawTo(dest);
if (!open) {
return;
}
for (auto& i : dropButtons) {
i.DrawTo(dest);
}
}
void MenuBar::MenuBarEntry::MouseMotion(SDL_MouseMotionEvent const& motion) {
//open the menu
bool o = mainButton.MouseMotion(motion) == Button::State::PRESSED;
if (!(open |= o)) {
return;
}
for (auto& i : dropButtons) {
//dragging down the menu
o |= i.MouseMotion(motion) == Button::State::PRESSED;
}
open = o;
}
void MenuBar::MenuBarEntry::MouseButtonDown(SDL_MouseButtonEvent const& button) {
//open the menu
if (!(open = mainButton.MouseButtonDown(button) == Button::State::PRESSED)) {
return;
}
//update the others anyway
for (auto& i : dropButtons) {
i.MouseButtonDown(button);
}
}
int MenuBar::MenuBarEntry::MouseButtonUp(SDL_MouseButtonEvent const& button) {
int ret = -1;
mainButton.MouseButtonUp(button);
for (auto& i : dropButtons) {
//the user just released this button
if (i.GetState() != i.MouseButtonUp(button) && i.GetState() == Button::State::HOVER && open) {
//get this button's index
ret = (&i - dropButtons.data());
}
}
open = false;
return ret;
}
+91
View File
@@ -0,0 +1,91 @@
/* Copyright: (c) Kayne Ruse 2013
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef MENUBAR_HPP_
#define MENUBAR_HPP_
#include "image.hpp"
#include "raster_font.hpp"
#include "button.hpp"
#include <string>
#include <vector>
/* I've redesigned this so that the contents of the menu bar can't change during run time.
* This is more restrictive but I'm focusing on getting this working first.
* The Image and Font pointers must be set before the text data is entered.
*
* This class needs a rewrite.
*/
class MenuBar {
public:
MenuBar() = default;
~MenuBar() = default;
//yet another draw function
void DrawTo(SDL_Surface* const dest);
//user inputs
void MouseMotion(SDL_MouseMotionEvent const&);
void MouseButtonDown(SDL_MouseButtonEvent const&);
void MouseButtonUp(SDL_MouseButtonEvent const&, int* entry, int* button);
//manage the entries & buttons
void SetEntries(std::vector<std::vector<std::string>> info);
void ClearEntries() { entries.clear(); }
//Accessors and mutators
Image* SetImage(Image* const ptr) { return image = ptr; }
Image* GetImage() { return image; }
RasterFont* SetFont(RasterFont* const ptr) { return font = ptr; }
RasterFont* GetFont() { return font; }
private:
class MenuBarEntry;
std::vector<MenuBarEntry> entries;
Image* image = nullptr;
RasterFont* font = nullptr;
};
class MenuBar::MenuBarEntry {
public:
MenuBarEntry() = default;
~MenuBarEntry() = default;
void DrawTo(SDL_Surface* const dest);
void MouseMotion(SDL_MouseMotionEvent const&);
void MouseButtonDown(SDL_MouseButtonEvent const&);
int MouseButtonUp(SDL_MouseButtonEvent const&);
private:
Button mainButton;
std::vector<Button> dropButtons;
bool open = false;
friend class MenuBar;
};
#endif
@@ -23,9 +23,9 @@
#include <stdexcept>
RasterFont::RasterFont(SDL_Surface* p) {
SetSurface(p);
}
/* It might be more efficient to render to a different surface (like an Image)
* rather than calling this function with all of it's '%' and '/'.
*/
void RasterFont::DrawStringTo(std::string s, SDL_Surface* const dest, Sint16 x, Sint16 y) {
if (!image.GetSurface()) {
@@ -34,16 +34,27 @@ void RasterFont::DrawStringTo(std::string s, SDL_Surface* const dest, Sint16 x,
const Uint16 w = image.GetClipW();
const Uint16 h = image.GetClipH();
for (int i = 0; i < s.size(); i++) {
image.SetClipX(s[i] % w * w);
image.SetClipY(s[i] / h * h);
image.SetClipX(s[i] % 16 * w);
image.SetClipY(s[i] / 16 * h);
image.DrawTo(dest, x + i * w, y);
}
}
SDL_Surface* RasterFont::SetSurface(SDL_Surface* p) {
if (image.SetSurface(p)) {
image.SetClipW(image.GetSurface()->w/16);
image.SetClipH(image.GetSurface()->h/16);
}
/* Note: This class can only take a raster font with 16*16 characters, and the
* indevidual characters must have the same dimensions. Overall this class is too
* restrictive; I suggest using a 3rd party library.
*/
SDL_Surface* RasterFont::LoadSurface(std::string fname) {
image.LoadSurface(fname);
image.SetClipW(image.GetSurface()->w/16);
image.SetClipH(image.GetSurface()->h/16);
return image.GetSurface();
}
SDL_Surface* RasterFont::SetSurface(SDL_Surface* p) {
image.SetSurface(p);
image.SetClipW(image.GetSurface()->w/16);
image.SetClipH(image.GetSurface()->h/16);
return image.GetSurface();
}
@@ -24,21 +24,29 @@
#include "image.hpp"
#include <string>
class RasterFont {
public:
RasterFont() = default;
RasterFont(SDL_Surface* p);
RasterFont(RasterFont const& rhs) { *this = rhs; }
RasterFont(RasterFont&& rhs) { *this = std::move(rhs); }
RasterFont(std::string fname) { LoadSurface(fname); }
RasterFont(SDL_Surface* p) { SetSurface(p); }
~RasterFont() = default;
RasterFont& operator=(RasterFont const& rhs) { image = rhs.image; }
RasterFont& operator=(RasterFont&& rhs) { image = std::move(rhs.image); }
void DrawStringTo(std::string, SDL_Surface* const, Sint16 x, Sint16 y);
//Accessors and Mutators
SDL_Surface* LoadSurface(std::string);
SDL_Surface* SetSurface(SDL_Surface*);
SDL_Surface* GetSurface() const { return image.GetSurface(); }
Uint16 GetCharW() { return image.GetClipW(); }
Uint16 GetCharH() { return image.GetClipH(); }
void FreeSurface() { image.FreeSurface(); }
Uint16 GetCharW() const { return image.GetClipW(); }
Uint16 GetCharH() const { return image.GetClipH(); }
private:
Image image;
};
@@ -19,12 +19,41 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "utilities.hpp"
#include "utility.hpp"
#include <cstdio>
#include <algorithm>
std::string itos(int i) {
int snapToBase(int base, int x) {
//snap to a grid
if (x < 0) {
x++;
return x / base * base - base;
}
return x / base * base;
}
std::string truncatePath(std::string pathname) {
return std::string(
std::find_if(
pathname.rbegin(),
pathname.rend(),
[](char ch) -> bool {
//windows only
return ch == '/' || ch == '\\';
// //unix only
// return ch == '/';
}).base(),
pathname.end());
}
std::string to_string_custom(int i) {
char buffer[20];
snprintf(buffer, 20, "%d", i);
return std::string(buffer);
}
int to_integer_custom(std::string s) {
int ret = 0;
sscanf(s.c_str(), "%d", &ret);
return ret;
}
@@ -19,20 +19,30 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef PLAYERENTRY_HPP_
#define PLAYERENTRY_HPP_
#include "vector2.hpp"
#ifndef UTILITY_HPP_
#define UTILITY_HPP_
#include <string>
struct PlayerEntry {
int index;
int clientIndex;
std::string handle;
std::string avatar;
Vector2 position;
Vector2 motion;
int snapToBase(int base, int x);
std::string truncatePath(std::string pathname);
//fixing known bugs in g++
std::string to_string_custom(int i);
int to_integer_custom(std::string);
//wow
template<typename ContainerT, typename PredicateT>
void erase_if(ContainerT& items, const PredicateT& predicate) {
for(auto it = items.begin(); it != items.end(); /* empty */) {
if(predicate(*it)) {
it = items.erase(it);
}
else {
++it;
}
}
};
#endif
@@ -27,11 +27,14 @@
class Vector2 {
public:
double x = 0, y = 0;
double x, y;
//This is explicitly a POD
Vector2() = default;
Vector2(double i, double j) {
x = i; y = j;
}
Vector2(double i, double j): x(i), y(j) {};
~Vector2() = default;
Vector2& operator=(Vector2 const&) = default;
double Length() const {
return sqrt(x*x+y*y);
}
@@ -46,26 +49,52 @@ public:
}
//Arithmetic operators
Vector2 operator+(Vector2 v) const { return Vector2(x + v.x, y + v.y); }
Vector2 operator-(Vector2 v) const { return Vector2(x - v.x, y - v.y); }
Vector2 operator*(Vector2 v) const { return Vector2(x * v.x, y * v.y); }
Vector2 operator*(double d) const { return Vector2(x * d, y * d); }
Vector2 operator+(Vector2 v) const {
Vector2 ret;
ret.x = x + v.x;
ret.y = y + v.y;
return ret;
}
Vector2 operator-(Vector2 v) const {
Vector2 ret;
ret.x = x - v.x;
ret.y = y - v.y;
return ret;
}
Vector2 operator*(Vector2 v) const {
Vector2 ret;
ret.x = x * v.x;
ret.y = y * v.y;
return ret;
}
Vector2 operator*(double d) const {
Vector2 ret;
ret.x = x * d;
ret.y = y * d;
return ret;
}
Vector2 operator/(Vector2 v) {
if (!v.x || !v.y)
throw(std::domain_error("Divide by zero"));
return Vector2(x / v.x, y / v.y);
Vector2 ret;
ret.x = x / v.x;
ret.y = y / v.y;
return ret;
}
Vector2 operator/(double d) {
if (!d)
throw(std::domain_error("Divide by zero"));
return Vector2(x / d, y / d);
Vector2 ret;
ret.x = x / d;
ret.y = y / d;
return ret;
}
bool operator==(Vector2 v) { return (x == v.x && y == v.y); }
bool operator!=(Vector2 v) { return (x != v.x || y != v.y); }
//member templates
//member templates (curry the above operators)
template<typename T> Vector2 operator+=(T t) { return *this = *this + t; }
template<typename T> Vector2 operator-=(T t) { return *this = *this - t; }
template<typename T> Vector2 operator*=(T t) { return *this = *this * t; }
@@ -74,7 +103,7 @@ public:
template<typename T> bool operator!=(T t) { return (x != t || y != t); }
};
//non-member templates
//non-member templates (flip the order)
template<typename T> Vector2 operator+(T t, Vector2 v) { return v + t; }
template<typename T> Vector2 operator-(T t, Vector2 v) { return v - t; }
template<typename T> Vector2 operator*(T t, Vector2 v) { return v * t; }
+1 -1
View File
@@ -34,7 +34,7 @@ SDL_Surface* BaseScene::screen = nullptr;
//-------------------------
BaseScene::BaseScene() {
nextScene = SceneList::CONTINUE;
//
}
BaseScene::~BaseScene() {
+5 -5
View File
@@ -28,18 +28,18 @@
class BaseScene {
public:
/* Public access members */
//Public access members
BaseScene();
virtual ~BaseScene();
/* Program control */
//Program control
static SDL_Surface* SetScreen(int w, int h, int bpp = 0, Uint32 flags = SDL_HWSURFACE|SDL_DOUBLEBUF);
static SDL_Surface* GetScreen();
SceneList SetNextScene(SceneList sceneIndex);
SceneList GetNextScene() const;
/* Frame loop */
//Frame loop
virtual void RunFrame(double delta);
virtual void RenderFrame();
@@ -50,7 +50,7 @@ protected:
virtual void FrameEnd() {}
virtual void Render(SDL_Surface* const screen) {}
/* Event handlers */
//Event handlers
virtual void QuitEvent() { SetNextScene(SceneList::QUIT); }
virtual void MouseMotion(SDL_MouseMotionEvent const&) {}
virtual void MouseButtonDown(SDL_MouseButtonEvent const&) {}
@@ -68,7 +68,7 @@ protected:
private:
static SDL_Surface* screen;
SceneList nextScene;
SceneList nextScene = SceneList::CONTINUE;
};
#endif
+20 -8
View File
@@ -5,7 +5,7 @@
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* including commercial EditorApplications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
@@ -24,12 +24,19 @@
#include <stdexcept>
#include <chrono>
//-------------------------
//Static declarations
//-------------------------
EditorApplication EditorApplication::instance;
//-------------------------
//Scene headers
//-------------------------
//Add the custom scene headers here
#include "map_editor.hpp"
#include "editor_scene.hpp"
#include "testificate_scene.hpp"
//-------------------------
//Public access members
@@ -40,21 +47,22 @@ EditorApplication::EditorApplication() {
}
EditorApplication::~EditorApplication() {
UnloadScene();
//
}
void EditorApplication::Init() {
config.Load("rsc\\config.cfg");
if (SDL_Init(SDL_INIT_VIDEO))
throw(std::runtime_error("Failed to initialize SDL"));
BaseScene::SetScreen(800, 600);
BaseScene::SetScreen(config.Int("screen.w"), config.Int("screen.h"));
}
void EditorApplication::Proc() {
LoadScene(SceneList::FIRST);
//prepare the time system
typedef std::chrono::high_resolution_clock Clock;
typedef std::chrono::steady_clock Clock;
Clock::duration delta(16 * Clock::duration::period::den / std::milli::den);
Clock::time_point simTime = Clock::now();
@@ -89,7 +97,6 @@ void EditorApplication::Proc() {
}
void EditorApplication::Quit() {
UnloadScene();
SDL_Quit();
}
@@ -103,10 +110,15 @@ void EditorApplication::LoadScene(SceneList sceneIndex) {
switch(sceneIndex) {
//add scene creation calls here
case SceneList::FIRST:
case SceneList::MAPEDITOR:
activeScene = new MapEditor();
case SceneList::EDITORSCENE:
activeScene = new EditorScene(&config);
break;
case SceneList::TESTIFICATESCENE:
activeScene = new TestificateScene(&config);
break;
default:
throw(std::logic_error("Failed to recognize the scene index"));
}
+10 -7
View File
@@ -24,26 +24,29 @@
#include "scene_list.hpp"
#include "base_scene.hpp"
#include "SDL/SDL.h"
#include "config_utility.hpp"
class EditorApplication {
public:
/* Public access members */
private:
EditorApplication();
~EditorApplication();
static EditorApplication instance;
public:
static EditorApplication* GetInstance() { return &instance; }
void Init();
void Proc();
void Quit();
EditorApplication(EditorApplication const&) = delete;
EditorApplication(EditorApplication const&&) = delete;
private:
/* Private access members */
//Private access members
void LoadScene(SceneList sceneIndex);
void UnloadScene();
//globals
ConfigUtility config;
BaseScene* activeScene = nullptr;
};
+235
View File
@@ -0,0 +1,235 @@
/* Copyright: (c) Kayne Ruse 2013
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "editor_scene.hpp"
#include "utility.hpp"
#include <cstdio>
#include <iostream>
#include <stdexcept>
using namespace std;
//-------------------------
//Public access members
//-------------------------
EditorScene::EditorScene(ConfigUtility* const arg1):
config(*arg1)
{
//create the debugging "window"
debugInfo.CreateSurface(256, 256);
//setup the utility objects
font.LoadSurface(config["dir.fonts"] + "pk_white_8.bmp");
buttonImage.LoadSurface(config["dir.interface"] + "button_menu.bmp");
buttonImage.SetClipH(buttonImage.GetClipH()/3);
//setup the menu bar
menuBar.SetFont(&font);
menuBar.SetImage(&buttonImage);
menuBar.SetEntries({
{"File", "New", "Open", "Save", "Close"},
{"Edit", "Set Tile", "Set Brush", "Script"},
{"Debug", "Debug On", "Debug Off", "Toggle", "Testificate"}
});
//setup the map
pager.SetRegionWidth(REGION_WIDTH);
pager.SetRegionHeight(REGION_HEIGHT);
pager.SetRegionDepth(REGION_DEPTH);
//debug
tsheet.Load(config["dir.tilesets"] + "terrain.bmp", 12, 15);
for (int i = 0; i < REGION_WIDTH; i++) {
for (int j = 0; j < REGION_HEIGHT; j++) {
pager.SetTile(i, j, 0, 14);
}
}
pager.SetTile(5, 10, 1, 48);
}
EditorScene::~EditorScene() {
//
}
//-------------------------
//Frame loop
//-------------------------
void EditorScene::FrameStart() {
//
}
void EditorScene::Update(double delta) {
//
}
void EditorScene::FrameEnd() {
//
}
void EditorScene::Render(SDL_Surface* const screen) {
tsheet.DrawRegionTo(screen, pager.GetRegion(0, 0), camera.x, camera.y);
/* //debug
for (int i = 0; i < pager.GetRegionWidth()*2; i++) {
for (int j = 0; j < pager.GetRegionHeight()*2; j++) {
for (int k = 0; k < pager.GetRegionDepth(); k++) {
//TODO: skip the out-of-bounds regions
tsheet.DrawTo(
screen,
i*tsheet.GetTileW()-camera.x,
j*tsheet.GetTileH()-camera.y,
pager.GetTile(i,j,k)
);
}
}
}
*/
//draw a big bar across the top (hackish)
buttonImage.SetClipY(0);
for (int i = 0; i < screen->w; i += buttonImage.GetClipW()) {
buttonImage.DrawTo(screen, i, 0);
}
//draw the menu bar
menuBar.DrawTo(screen);
//draw some debugging info
if (debugOpen) {
SDL_FillRect(debugInfo.GetSurface(), 0, 0);
DrawToDebugInfo(string("camera.x: ") + to_string_custom(camera.x), 0);
DrawToDebugInfo(string("camera.y: ") + to_string_custom(camera.y), 1);
debugInfo.DrawTo(screen, screen->w - debugInfo.GetClipW(), buttonImage.GetClipH());
}
}
void EditorScene::DrawToDebugInfo(std::string str, int line) {
//draw the debug info on the right, with a grey background
SDL_Rect clip = {
Sint16(debugInfo.GetClipW() - str.size() * font.GetCharW()),
Sint16(font.GetCharH() * line),
Uint16(str.size() * font.GetCharW()),
Uint16(font.GetCharH())
};
SDL_FillRect(debugInfo.GetSurface(), &clip, SDL_MapRGB(debugInfo.GetSurface()->format, 64, 64, 64));
font.DrawStringTo(str, debugInfo.GetSurface(), clip.x, clip.y);
}
//-------------------------
//Event handlers
//-------------------------
void EditorScene::MouseMotion(SDL_MouseMotionEvent const& motion) {
menuBar.MouseMotion(motion);
if (motion.state & SDL_BUTTON_RMASK) {
camera.x -= motion.xrel;
camera.y -= motion.yrel;
}
}
void EditorScene::MouseButtonDown(SDL_MouseButtonEvent const& button) {
menuBar.MouseButtonDown(button);
}
void EditorScene::MouseButtonUp(SDL_MouseButtonEvent const& button) {
int entry, drop;
menuBar.MouseButtonUp(button, &entry, &drop);
HandleMenuOption(entry, drop);
}
void EditorScene::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
case SDLK_ESCAPE:
QuitEvent();
break;
case SDLK_SPACE:
camera.x = 0;
camera.y = 0;
break;
case SDLK_TAB:
debugOpen = !debugOpen;
break;
}
}
void EditorScene::KeyUp(SDL_KeyboardEvent const& key) {
//
}
//-------------------------
//Members
//-------------------------
void EditorScene::HandleMenuOption(int entry, int drop) {
//manage input from the menu bar
switch(entry) {
case 0: //File
switch(drop) {
case 0:
//TODO: NEW
break;
case 1:
//TODO: OPEN
break;
case 2:
//TODO: SAVE
break;
case 3:
//TODO: CLOSE
break;
}
break;
case 1: //Edit
switch(drop) {
case 0:
//TODO: SET TILE
break;
case 1:
//TODO: SET BRUSH
break;
case 2:
//TODO: SCRIPT
break;
}
break;
case 2: //Debug
switch(drop) {
case 0:
debugOpen = true;
break;
case 1:
debugOpen = false;
break;
case 2:
debugOpen = !debugOpen;
break;
case 3:
SetNextScene(SceneList::TESTIFICATESCENE);
break;
}
break;
}
}
+30 -39
View File
@@ -19,33 +19,26 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef INWORLD_HPP_
#define INWORLD_HPP_
#ifndef EDITORSCENE_HPP_
#define EDITORSCENE_HPP_
#include "base_scene.hpp"
#include "utilities.hpp"
#include "defines.hpp"
#include "singleton.hpp"
#include "packet.hpp"
#include "network_queue.hpp"
#include "information_manager.hpp"
#include "player_character.hpp"
#include "config_utility.hpp"
#include "surface_manager.hpp"
#include "udp_network_utility.hpp"
#include "button.hpp"
#include "image.hpp"
#include "raster_font.hpp"
#include "frame_rate.hpp"
#include "menu_bar.hpp"
#include <map>
#include "region_pager.hpp"
#include "map_generator.hpp"
#include "map_file_format.hpp"
#include "tile_sheet.hpp"
class InWorld : public BaseScene {
class EditorScene : public BaseScene {
public:
//Public access members
InWorld();
~InWorld();
EditorScene(ConfigUtility* const);
~EditorScene();
protected:
//Frame loop
@@ -55,35 +48,33 @@ protected:
void Render(SDL_Surface* const);
//Event handlers
void QuitEvent();
void MouseMotion(SDL_MouseMotionEvent const&);
void MouseButtonDown(SDL_MouseButtonEvent const&);
void MouseButtonUp(SDL_MouseButtonEvent const&);
void KeyDown(SDL_KeyboardEvent const&);
void KeyUp(SDL_KeyboardEvent const&);
//Utilities
int HandlePacket(Packet);
void Disconnect();
void ExitGame();
void HandleDisconnection(Packet&);
void AddPlayer(Packet&);
void RemovePlayer(Packet&);
void UpdatePlayer(Packet&);
void SendState();
//services
ConfigUtility* configUtil = Singleton<ConfigUtility>::Get();
SurfaceManager* surfaceMgr = Singleton<SurfaceManager>::Get();
UDPNetworkUtility* netUtil = Singleton<UDPNetworkUtility>::Get();
InformationManager* infoMgr = Singleton<InformationManager>::Get();
//members
void HandleMenuOption(int entry, int drop);
//globals
ConfigUtility& config;
//debugging tools
void DrawToDebugInfo(std::string, int line);
Image debugInfo;
bool debugOpen = true;
RasterFont font;
std::map<int, PlayerCharacter> playerCharacters;
Image buttonImage;
MenuBar menuBar;
struct {
int x = 0, y = 0;
} camera;
RegionPager<BlankGenerator, DummyFormat> pager;
TileSheet tsheet;
};
#endif
+6 -11
View File
@@ -27,21 +27,16 @@
using namespace std;
int main(int, char**) {
#ifdef DEBUG
cout << "Beginning program" << endl;
#endif
cout << "Beginning editor" << endl;
try {
EditorApplication app;
app.Init();
app.Proc();
app.Quit();
EditorApplication::GetInstance()->Init();
EditorApplication::GetInstance()->Proc();
EditorApplication::GetInstance()->Quit();
}
catch(exception& e) {
cerr << "Fatal error: " << e.what() << endl;
cerr << "Fatal exception thrown: " << e.what() << endl;
return 1;
}
#ifdef DEBUG
cout << "Clean exit" << endl;
#endif
return 0;
}
}
+11 -7
View File
@@ -1,16 +1,17 @@
#config
LIBDIR=../libs
LOCALLIBS=$(LIBDIR)/out/libCodebase.a $(LIBDIR)/out/libCommon.a
LIB=$(LOCALLIBS) -lmingw32 -lSDLmain -lSDL
INCLUDES=$(LIBDIR)/Codebase $(LIBDIR)/common
INCLUDES+=../common ../common/graphics ../common/map ../common/ui
LIBS+=../libcommon.a -lmingw32 -lSDLmain -lSDL -llua
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES))
#source
SRC=$(wildcard *.cpp)
CXXSRC=$(wildcard *.cpp)
CSRC=$(wildcard *.c)
#objects
OBJDIR=obj
OBJ=$(addprefix $(OBJDIR)/,$(SRC:.cpp=.o))
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
OBJ+=$(addprefix $(OBJDIR)/,$(CSRC:.c=.o))
#output
OUTDIR=../out
@@ -18,7 +19,7 @@ OUT=$(addprefix $(OUTDIR)/,editor)
#targets
all: $(OBJ) $(OUT)
$(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIB)
$(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIBS)
$(OBJ): | $(OBJDIR)
@@ -33,6 +34,9 @@ $(OUTDIR):
$(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
$(OBJDIR)/%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
clean:
$(RM) *.o *.a *.exe
+2 -1
View File
@@ -29,7 +29,8 @@ enum class SceneList {
FIRST,
//custom indexes
MAPEDITOR,
TESTIFICATESCENE,
EDITORSCENE,
};
#endif
@@ -19,17 +19,24 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "map_editor.hpp"
#include "testificate_scene.hpp"
#include <iostream>
using std::cout;
using std::endl;
//-------------------------
//Public access members
//-------------------------
MapEditor::MapEditor() {
TestificateScene::TestificateScene(ConfigUtility* const arg1):
config(*arg1)
{
//
}
MapEditor::~MapEditor() {
TestificateScene::~TestificateScene() {
//
}
@@ -37,19 +44,19 @@ MapEditor::~MapEditor() {
//Frame loop
//-------------------------
void MapEditor::FrameStart() {
void TestificateScene::FrameStart() {
//
}
void MapEditor::Update(double delta) {
void TestificateScene::Update(double delta) {
//
}
void MapEditor::FrameEnd() {
void TestificateScene::FrameEnd() {
//
}
void MapEditor::Render(SDL_Surface* const screen) {
void TestificateScene::Render(SDL_Surface* const screen) {
//
}
@@ -57,26 +64,28 @@ void MapEditor::Render(SDL_Surface* const screen) {
//Event handlers
//-------------------------
void MapEditor::MouseMotion(SDL_MouseMotionEvent const& motion) {
void TestificateScene::MouseMotion(SDL_MouseMotionEvent const& motion) {
//
}
void MapEditor::MouseButtonDown(SDL_MouseButtonEvent const& button) {
void TestificateScene::MouseButtonDown(SDL_MouseButtonEvent const& button) {
//
}
void MapEditor::MouseButtonUp(SDL_MouseButtonEvent const& button) {
void TestificateScene::MouseButtonUp(SDL_MouseButtonEvent const& button) {
//
}
void MapEditor::KeyDown(SDL_KeyboardEvent const& key) {
void TestificateScene::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
case SDLK_ESCAPE:
QuitEvent();
break;
// QuitEvent();
SetNextScene(SceneList::EDITORSCENE);
break;
}
}
void MapEditor::KeyUp(SDL_KeyboardEvent const& key) {
void TestificateScene::KeyUp(SDL_KeyboardEvent const& key) {
//
}
@@ -19,16 +19,18 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef MAPEDITOR_HPP_
#define MAPEDITOR_HPP_
#ifndef TESTIFICATESCENE_HPP_
#define TESTIFICATESCENE_HPP_
#include "base_scene.hpp"
class MapEditor : public BaseScene {
#include "config_utility.hpp"
class TestificateScene : public BaseScene {
public:
//Public access members
MapEditor();
~MapEditor();
TestificateScene(ConfigUtility* const);
~TestificateScene();
protected:
//Frame loop
@@ -43,6 +45,9 @@ protected:
void MouseButtonUp(SDL_MouseButtonEvent const&);
void KeyDown(SDL_KeyboardEvent const&);
void KeyUp(SDL_KeyboardEvent const&);
//globals
ConfigUtility& config;
};
#endif
-44
View File
@@ -1,44 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "frame_rate.hpp"
#include <chrono>
typedef std::chrono::high_resolution_clock Clock;
static int frameCount = 0;
static int lastFrameRate = 0;
static Clock::time_point tick = Clock::now();
int ClockFrameRate() {
frameCount++;
if (Clock::now() - tick >= std::chrono::duration<int>(1)) {
lastFrameRate = frameCount;
frameCount = 0;
tick = Clock::now();
}
return lastFrameRate;
}
int GetFrameRate() {
return lastFrameRate;
}
-66
View File
@@ -1,66 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef SPRITESHEET_HPP_
#define SPRITESHEET_HPP_
#include "image.hpp"
#include "SDL/SDL.h"
class SpriteSheet {
public:
SpriteSheet() = default;
SpriteSheet(SDL_Surface*, Uint16 w, Uint16 h);
~SpriteSheet() = default;
void Update(double delta);
SDL_Surface* SetSurface(SDL_Surface* const, Uint16 w, Uint16 h);
SDL_Surface* GetSurface() const {
return image.GetSurface();
}
void DrawTo(SDL_Surface* const dest, Sint16 x, Sint16 y) {
image.DrawTo(dest, x, y);
}
//Accessors and Mutators
double SetInterval(double i) { return interval = i; }
double GetInterval() const { return interval; }
int SetCurrentFrame(int i) { return currentFrame = i; }
int SetCurrentStrip(int i) { return currentStrip = i; }
Uint16 GetFrameWidth() const { return image.GetClipW(); }
Uint16 GetFrameHeight() const { return image.GetClipH(); }
int GetCurrentFrame() const { return currentFrame; };
int GetCurrentStrip() const { return currentStrip; };
int GetMaxFrames() const { return maxFrames; }
int GetMaxStrips() const { return maxStrips; }
private:
Image image;
int currentFrame = 0, maxFrames = 0;
int currentStrip = 0, maxStrips = 0;
double interval = 0, ticks = 0;
};
#endif
-85
View File
@@ -1,85 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "surface_manager.hpp"
#include <stdexcept>
SurfaceManager::~SurfaceManager() noexcept {
FreeAll();
}
SDL_Surface* SurfaceManager::Load(std::string key, std::string fname) {
MapType::iterator it = surfaceMap.find(key);
if (it != surfaceMap.end()) {
throw(std::runtime_error(std::string("Surface already loaded: ") + key + std::string(", ") + fname));
}
return LoadSurface(key, fname);
}
SDL_Surface* SurfaceManager::Reload(std::string key, std::string fname) {
MapType::iterator it = surfaceMap.find(key);
if (it != surfaceMap.end()) {
SDL_FreeSurface(it->second);
surfaceMap.erase(it);
}
return LoadSurface(key, fname);
}
SDL_Surface* SurfaceManager::Get(std::string key) {
MapType::iterator it = surfaceMap.find(key);
if (it == surfaceMap.end()) {
throw(std::runtime_error(std::string("Could not find key: ") + key));
}
return it->second;
}
SDL_Surface* SurfaceManager::Set(std::string key, SDL_Surface* ptr) {
MapType::iterator it = surfaceMap.find(key);
if (it != surfaceMap.end()) {
throw(std::runtime_error(std::string("Key already exists: ") + key));
}
return surfaceMap[key] = ptr;
}
void SurfaceManager::Free(std::string key) {
MapType::iterator it = surfaceMap.find(key);
if (it != surfaceMap.end()) {
SDL_FreeSurface(it->second);
surfaceMap.erase(it);
}
}
void SurfaceManager::FreeAll() {
for (auto it : surfaceMap) {
SDL_FreeSurface(it.second);
}
surfaceMap.clear();
}
SDL_Surface* SurfaceManager::LoadSurface(std::string key, std::string fname) {
SDL_Surface* ptr = SDL_LoadBMP(fname.c_str());
if (!ptr) {
throw(std::runtime_error(std::string("Failed to load file: ") + fname));
}
SDL_SetColorKey(ptr, SDL_SRCCOLORKEY, SDL_MapRGB(ptr->format, 255, 0, 255)); //default
return surfaceMap[key] = ptr;
}
-452
View File
@@ -1,452 +0,0 @@
/*
SDL_net: An example cross-platform network library for use with SDL
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/* $Id$ */
#ifndef _SDL_NET_H
#define _SDL_NET_H
#include "SDL/SDL.h"
#include "SDL/SDL_endian.h"
#include "SDL/SDL_version.h"
#include "SDL/begin_code.h"
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
/* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL
*/
#define SDL_NET_MAJOR_VERSION 1
#define SDL_NET_MINOR_VERSION 2
#define SDL_NET_PATCHLEVEL 8
/* This macro can be used to fill a version structure with the compile-time
* version of the SDL_net library.
*/
#define SDL_NET_VERSION(X) \
{ \
(X)->major = SDL_NET_MAJOR_VERSION; \
(X)->minor = SDL_NET_MINOR_VERSION; \
(X)->patch = SDL_NET_PATCHLEVEL; \
}
/* This function gets the version of the dynamically linked SDL_net library.
it should NOT be used to fill a version structure, instead you should
use the SDL_NET_VERSION() macro.
*/
extern DECLSPEC const SDL_version * SDLCALL SDLNet_Linked_Version(void);
/* Initialize/Cleanup the network API
SDL must be initialized before calls to functions in this library,
because this library uses utility functions from the SDL library.
*/
extern DECLSPEC int SDLCALL SDLNet_Init(void);
extern DECLSPEC void SDLCALL SDLNet_Quit(void);
/***********************************************************************/
/* IPv4 hostname resolution API */
/***********************************************************************/
typedef struct {
Uint32 host; /* 32-bit IPv4 host address */
Uint16 port; /* 16-bit protocol port */
} IPaddress;
/* Resolve a host name and port to an IP address in network form.
If the function succeeds, it will return 0.
If the host couldn't be resolved, the host portion of the returned
address will be INADDR_NONE, and the function will return -1.
If 'host' is NULL, the resolved host will be set to INADDR_ANY.
*/
#ifndef INADDR_ANY
#define INADDR_ANY 0x00000000
#endif
#ifndef INADDR_NONE
#define INADDR_NONE 0xFFFFFFFF
#endif
#ifndef INADDR_LOOPBACK
#define INADDR_LOOPBACK 0x7f000001
#endif
#ifndef INADDR_BROADCAST
#define INADDR_BROADCAST 0xFFFFFFFF
#endif
extern DECLSPEC int SDLCALL SDLNet_ResolveHost(IPaddress *address, const char *host, Uint16 port);
/* Resolve an ip address to a host name in canonical form.
If the ip couldn't be resolved, this function returns NULL,
otherwise a pointer to a static buffer containing the hostname
is returned. Note that this function is not thread-safe.
*/
extern DECLSPEC const char * SDLCALL SDLNet_ResolveIP(const IPaddress *ip);
/* Get the addresses of network interfaces on this system.
This returns the number of addresses saved in 'addresses'
*/
extern DECLSPEC int SDLCALL SDLNet_GetLocalAddresses(IPaddress *addresses, int maxcount);
/***********************************************************************/
/* TCP network API */
/***********************************************************************/
typedef struct _TCPsocket *TCPsocket;
/* Open a TCP network socket
If ip.host is INADDR_NONE or INADDR_ANY, this creates a local server
socket on the given port, otherwise a TCP connection to the remote
host and port is attempted. The address passed in should already be
swapped to network byte order (addresses returned from
SDLNet_ResolveHost() are already in the correct form).
The newly created socket is returned, or NULL if there was an error.
*/
extern DECLSPEC TCPsocket SDLCALL SDLNet_TCP_Open(IPaddress *ip);
/* Accept an incoming connection on the given server socket.
The newly created socket is returned, or NULL if there was an error.
*/
extern DECLSPEC TCPsocket SDLCALL SDLNet_TCP_Accept(TCPsocket server);
/* Get the IP address of the remote system associated with the socket.
If the socket is a server socket, this function returns NULL.
*/
extern DECLSPEC IPaddress * SDLCALL SDLNet_TCP_GetPeerAddress(TCPsocket sock);
/* Send 'len' bytes of 'data' over the non-server socket 'sock'
This function returns the actual amount of data sent. If the return value
is less than the amount of data sent, then either the remote connection was
closed, or an unknown socket error occurred.
*/
extern DECLSPEC int SDLCALL SDLNet_TCP_Send(TCPsocket sock, const void *data,
int len);
/* Receive up to 'maxlen' bytes of data over the non-server socket 'sock',
and store them in the buffer pointed to by 'data'.
This function returns the actual amount of data received. If the return
value is less than or equal to zero, then either the remote connection was
closed, or an unknown socket error occurred.
*/
extern DECLSPEC int SDLCALL SDLNet_TCP_Recv(TCPsocket sock, void *data, int maxlen);
/* Close a TCP network socket */
extern DECLSPEC void SDLCALL SDLNet_TCP_Close(TCPsocket sock);
/***********************************************************************/
/* UDP network API */
/***********************************************************************/
/* The maximum channels on a a UDP socket */
#define SDLNET_MAX_UDPCHANNELS 32
/* The maximum addresses bound to a single UDP socket channel */
#define SDLNET_MAX_UDPADDRESSES 4
typedef struct _UDPsocket *UDPsocket;
typedef struct {
int channel; /* The src/dst channel of the packet */
Uint8 *data; /* The packet data */
int len; /* The length of the packet data */
int maxlen; /* The size of the data buffer */
int status; /* packet status after sending */
IPaddress address; /* The source/dest address of an incoming/outgoing packet */
} UDPpacket;
/* Allocate/resize/free a single UDP packet 'size' bytes long.
The new packet is returned, or NULL if the function ran out of memory.
*/
extern DECLSPEC UDPpacket * SDLCALL SDLNet_AllocPacket(int size);
extern DECLSPEC int SDLCALL SDLNet_ResizePacket(UDPpacket *packet, int newsize);
extern DECLSPEC void SDLCALL SDLNet_FreePacket(UDPpacket *packet);
/* Allocate/Free a UDP packet vector (array of packets) of 'howmany' packets,
each 'size' bytes long.
A pointer to the first packet in the array is returned, or NULL if the
function ran out of memory.
*/
extern DECLSPEC UDPpacket ** SDLCALL SDLNet_AllocPacketV(int howmany, int size);
extern DECLSPEC void SDLCALL SDLNet_FreePacketV(UDPpacket **packetV);
/* Open a UDP network socket
If 'port' is non-zero, the UDP socket is bound to a local port.
The 'port' should be given in native byte order, but is used
internally in network (big endian) byte order, in addresses, etc.
This allows other systems to send to this socket via a known port.
*/
extern DECLSPEC UDPsocket SDLCALL SDLNet_UDP_Open(Uint16 port);
/* Set the percentage of simulated packet loss for packets sent on the socket.
*/
extern DECLSPEC void SDLCALL SDLNet_UDP_SetPacketLoss(UDPsocket sock, int percent);
/* Bind the address 'address' to the requested channel on the UDP socket.
If the channel is -1, then the first unbound channel will be bound with
the given address as it's primary address.
If the channel is already bound, this new address will be added to the
list of valid source addresses for packets arriving on the channel.
If the channel is not already bound, then the address becomes the primary
address, to which all outbound packets on the channel are sent.
This function returns the channel which was bound, or -1 on error.
*/
extern DECLSPEC int SDLCALL SDLNet_UDP_Bind(UDPsocket sock, int channel, const IPaddress *address);
/* Unbind all addresses from the given channel */
extern DECLSPEC void SDLCALL SDLNet_UDP_Unbind(UDPsocket sock, int channel);
/* Get the primary IP address of the remote system associated with the
socket and channel. If the channel is -1, then the primary IP port
of the UDP socket is returned -- this is only meaningful for sockets
opened with a specific port.
If the channel is not bound and not -1, this function returns NULL.
*/
extern DECLSPEC IPaddress * SDLCALL SDLNet_UDP_GetPeerAddress(UDPsocket sock, int channel);
/* Send a vector of packets to the the channels specified within the packet.
If the channel specified in the packet is -1, the packet will be sent to
the address in the 'src' member of the packet.
Each packet will be updated with the status of the packet after it has
been sent, -1 if the packet send failed.
This function returns the number of packets sent.
*/
extern DECLSPEC int SDLCALL SDLNet_UDP_SendV(UDPsocket sock, UDPpacket **packets, int npackets);
/* Send a single packet to the specified channel.
If the channel specified in the packet is -1, the packet will be sent to
the address in the 'src' member of the packet.
The packet will be updated with the status of the packet after it has
been sent.
This function returns 1 if the packet was sent, or 0 on error.
NOTE:
The maximum size of the packet is limited by the MTU (Maximum Transfer Unit)
of the transport medium. It can be as low as 250 bytes for some PPP links,
and as high as 1500 bytes for ethernet.
*/
extern DECLSPEC int SDLCALL SDLNet_UDP_Send(UDPsocket sock, int channel, UDPpacket *packet);
/* Receive a vector of pending packets from the UDP socket.
The returned packets contain the source address and the channel they arrived
on. If they did not arrive on a bound channel, the the channel will be set
to -1.
The channels are checked in highest to lowest order, so if an address is
bound to multiple channels, the highest channel with the source address
bound will be returned.
This function returns the number of packets read from the network, or -1
on error. This function does not block, so can return 0 packets pending.
*/
extern DECLSPEC int SDLCALL SDLNet_UDP_RecvV(UDPsocket sock, UDPpacket **packets);
/* Receive a single packet from the UDP socket.
The returned packet contains the source address and the channel it arrived
on. If it did not arrive on a bound channel, the the channel will be set
to -1.
The channels are checked in highest to lowest order, so if an address is
bound to multiple channels, the highest channel with the source address
bound will be returned.
This function returns the number of packets read from the network, or -1
on error. This function does not block, so can return 0 packets pending.
*/
extern DECLSPEC int SDLCALL SDLNet_UDP_Recv(UDPsocket sock, UDPpacket *packet);
/* Close a UDP network socket */
extern DECLSPEC void SDLCALL SDLNet_UDP_Close(UDPsocket sock);
/***********************************************************************/
/* Hooks for checking sockets for available data */
/***********************************************************************/
typedef struct _SDLNet_SocketSet *SDLNet_SocketSet;
/* Any network socket can be safely cast to this socket type */
typedef struct _SDLNet_GenericSocket {
int ready;
} *SDLNet_GenericSocket;
/* Allocate a socket set for use with SDLNet_CheckSockets()
This returns a socket set for up to 'maxsockets' sockets, or NULL if
the function ran out of memory.
*/
extern DECLSPEC SDLNet_SocketSet SDLCALL SDLNet_AllocSocketSet(int maxsockets);
/* Add a socket to a set of sockets to be checked for available data */
#define SDLNet_TCP_AddSocket(set, sock) \
SDLNet_AddSocket(set, SDL_reinterpret_cast(SDLNet_GenericSocket, sock))
#define SDLNet_UDP_AddSocket(set, sock) \
SDLNet_AddSocket(set, SDL_reinterpret_cast(SDLNet_GenericSocket, sock))
extern DECLSPEC int SDLCALL SDLNet_AddSocket(SDLNet_SocketSet set, SDLNet_GenericSocket sock);
/* Remove a socket from a set of sockets to be checked for available data */
#define SDLNet_TCP_DelSocket(set, sock) \
SDLNet_DelSocket(set, SDL_reinterpret_cast(SDLNet_GenericSocket, sock))
#define SDLNet_UDP_DelSocket(set, sock) \
SDLNet_DelSocket(set, SDL_reinterpret_cast(SDLNet_GenericSocket, sock))
extern DECLSPEC int SDLCALL SDLNet_DelSocket(SDLNet_SocketSet set, SDLNet_GenericSocket sock);
/* This function checks to see if data is available for reading on the
given set of sockets. If 'timeout' is 0, it performs a quick poll,
otherwise the function returns when either data is available for
reading, or the timeout in milliseconds has elapsed, which ever occurs
first. This function returns the number of sockets ready for reading,
or -1 if there was an error with the select() system call.
*/
extern DECLSPEC int SDLCALL SDLNet_CheckSockets(SDLNet_SocketSet set, Uint32 timeout);
/* After calling SDLNet_CheckSockets(), you can use this function on a
socket that was in the socket set, to find out if data is available
for reading.
*/
#define SDLNet_SocketReady(sock) \
((sock != NULL) && SDL_reinterpret_cast(SDLNet_GenericSocket, sock)->ready)
/* Free a set of sockets allocated by SDL_NetAllocSocketSet() */
extern DECLSPEC void SDLCALL SDLNet_FreeSocketSet(SDLNet_SocketSet set);
/***********************************************************************/
/* Platform-independent data conversion functions */
/***********************************************************************/
/* Write a 16/32 bit value to network packet buffer */
extern DECLSPEC void SDLCALL SDLNet_Write16(Uint16 value, void *area);
extern DECLSPEC void SDLCALL SDLNet_Write32(Uint32 value, void *area);
/* Read a 16/32 bit value from network packet buffer */
extern DECLSPEC Uint16 SDLCALL SDLNet_Read16(void *area);
extern DECLSPEC Uint32 SDLCALL SDLNet_Read32(void *area);
/***********************************************************************/
/* Error reporting functions */
/***********************************************************************/
/* We'll use SDL's functions for error reporting */
#define SDLNet_SetError SDL_SetError
#define SDLNet_GetError SDL_GetError
/* I'm eventually going to try to disentangle SDL_net from SDL, thus making
SDL_net an independent X-platform networking toolkit. Not today though....
extern no_parse_DECLSPEC void SDLCALL SDLNet_SetError(const char *fmt, ...);
extern no_parse_DECLSPEC char * SDLCALL SDLNet_GetError(void);
*/
/* Inline macro functions to read/write network data */
/* Warning, some systems have data access alignment restrictions */
#if defined(sparc) || defined(mips)
#define SDL_DATA_ALIGNED 1
#endif
#ifndef SDL_DATA_ALIGNED
#define SDL_DATA_ALIGNED 0
#endif
/* Write a 16 bit value to network packet buffer */
#if !SDL_DATA_ALIGNED
#define SDLNet_Write16(value, areap) \
(*SDL_reinterpret_cast(Uint16 *, areap) = SDL_SwapBE16(value))
#else
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
#define SDLNet_Write16(value, areap) \
do \
{ \
Uint8 *area = SDL_reinterpret_cast(Uint8 *, areap); \
area[0] = (value >> 8) & 0xFF; \
area[1] = value & 0xFF; \
} while ( 0 )
#else
#define SDLNet_Write16(value, areap) \
do \
{ \
Uint8 *area = SDL_reinterpret_cast(Uint8 *, areap); \
area[1] = (value >> 8) & 0xFF; \
area[0] = value & 0xFF; \
} while ( 0 )
#endif
#endif /* !SDL_DATA_ALIGNED */
/* Write a 32 bit value to network packet buffer */
#if !SDL_DATA_ALIGNED
#define SDLNet_Write32(value, areap) \
*SDL_reinterpret_cast(Uint32 *, areap) = SDL_SwapBE32(value);
#else
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
#define SDLNet_Write32(value, areap) \
do \
{ \
Uint8 *area = SDL_reinterpret_cast(Uint8 *, areap); \
area[0] = (value >> 24) & 0xFF; \
area[1] = (value >> 16) & 0xFF; \
area[2] = (value >> 8) & 0xFF; \
area[3] = value & 0xFF; \
} while ( 0 )
#else
#define SDLNet_Write32(value, areap) \
do \
{ \
Uint8 *area = SDL_reinterpret_cast(Uint8 *, areap); \
area[3] = (value >> 24) & 0xFF; \
area[2] = (value >> 16) & 0xFF; \
area[1] = (value >> 8) & 0xFF; \
area[0] = value & 0xFF; \
} while ( 0 )
#endif
#endif /* !SDL_DATA_ALIGNED */
/* Read a 16 bit value from network packet buffer */
#if !SDL_DATA_ALIGNED
#define SDLNet_Read16(areap) \
(SDL_SwapBE16(*SDL_reinterpret_cast(Uint16 *, areap)))
#else
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
#define SDLNet_Read16(areap) \
(((SDL_reinterpret_cast(Uint8 *, areap))[0] << 8) | (SDL_reinterpret_cast(Uint8 *, areap))[1] << 0)
#else
#define SDLNet_Read16(areap) \
(((SDL_reinterpret_cast(Uint8 *, areap))[1] << 8) | (SDL_reinterpret_cast(Uint8 *, areap))[0] << 0)
#endif
#endif /* !SDL_DATA_ALIGNED */
/* Read a 32 bit value from network packet buffer */
#if !SDL_DATA_ALIGNED
#define SDLNet_Read32(areap) \
(SDL_SwapBE32(*SDL_reinterpret_cast(Uint32 *, areap)))
#else
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
#define SDLNet_Read32(areap) \
(((SDL_reinterpret_cast(Uint8 *, areap))[0] << 24) | ((SDL_reinterpret_cast(Uint8 *, areap))[1] << 16) | \
((SDL_reinterpret_cast(Uint8 *, areap))[2] << 8) | (SDL_reinterpret_cast(Uint8 *, areap))[3] << 0)
#else
#define SDLNet_Read32(areap) \
(((SDL_reinterpret_cast(Uint8 *, areap))[3] << 24) | ((SDL_reinterpret_cast(Uint8 *, areap))[2] << 16) | \
((SDL_reinterpret_cast(Uint8 *, areap))[1] << 8) | (SDL_reinterpret_cast(Uint8 *, areap))[0] << 0)
#endif
#endif /* !SDL_DATA_ALIGNED */
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#include "SDL/close_code.h"
#endif /* _SDL_NET_H */
-269
View File
@@ -1,269 +0,0 @@
/*
SDL_net: An example cross-platform network library for use with SDL
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/* $Id$ */
#include <string.h>
#include "SDL/SDL_endian.h"
#include "SDLnetsys.h"
#include "SDL_net.h"
const SDL_version *SDLNet_Linked_Version(void)
{
static SDL_version linked_version;
SDL_NET_VERSION(&linked_version);
return(&linked_version);
}
/* Since the UNIX/Win32/BeOS code is so different from MacOS,
we'll just have two completely different sections here.
*/
static int SDLNet_started = 0;
#ifndef __USE_W32_SOCKETS
#include <signal.h>
#endif
#ifndef __USE_W32_SOCKETS
int SDLNet_GetLastError(void)
{
return errno;
}
void SDLNet_SetLastError(int err)
{
errno = err;
}
#endif
/* Initialize/Cleanup the network API */
int SDLNet_Init(void)
{
if ( !SDLNet_started ) {
#ifdef __USE_W32_SOCKETS
/* Start up the windows networking */
WORD version_wanted = MAKEWORD(1,1);
WSADATA wsaData;
if ( WSAStartup(version_wanted, &wsaData) != 0 ) {
SDLNet_SetError("Couldn't initialize Winsock 1.1\n");
return(-1);
}
#else
/* SIGPIPE is generated when a remote socket is closed */
void (*handler)(int);
handler = signal(SIGPIPE, SIG_IGN);
if ( handler != SIG_DFL ) {
signal(SIGPIPE, handler);
}
#endif
}
++SDLNet_started;
return(0);
}
void SDLNet_Quit(void)
{
if ( SDLNet_started == 0 ) {
return;
}
if ( --SDLNet_started == 0 ) {
#ifdef __USE_W32_SOCKETS
/* Clean up windows networking */
if ( WSACleanup() == SOCKET_ERROR ) {
if ( WSAGetLastError() == WSAEINPROGRESS ) {
#ifndef _WIN32_WCE
WSACancelBlockingCall();
#endif
WSACleanup();
}
}
#else
/* Restore the SIGPIPE handler */
void (*handler)(int);
handler = signal(SIGPIPE, SIG_DFL);
if ( handler != SIG_IGN ) {
signal(SIGPIPE, handler);
}
#endif
}
}
/* Resolve a host name and port to an IP address in network form */
int SDLNet_ResolveHost(IPaddress *address, const char *host, Uint16 port)
{
int retval = 0;
/* Perform the actual host resolution */
if ( host == NULL ) {
address->host = INADDR_ANY;
} else {
address->host = inet_addr(host);
if ( address->host == INADDR_NONE ) {
struct hostent *hp;
hp = gethostbyname(host);
if ( hp ) {
memcpy(&address->host,hp->h_addr,hp->h_length);
} else {
retval = -1;
}
}
}
address->port = SDL_SwapBE16(port);
/* Return the status */
return(retval);
}
/* Resolve an ip address to a host name in canonical form.
If the ip couldn't be resolved, this function returns NULL,
otherwise a pointer to a static buffer containing the hostname
is returned. Note that this function is not thread-safe.
*/
/* Written by Miguel Angel Blanch.
* Main Programmer of Arianne RPG.
* http://come.to/arianne_rpg
*/
const char *SDLNet_ResolveIP(const IPaddress *ip)
{
struct hostent *hp;
struct in_addr in;
hp = gethostbyaddr((const char *)&ip->host, sizeof(ip->host), AF_INET);
if ( hp != NULL ) {
return hp->h_name;
}
in.s_addr = ip->host;
return inet_ntoa(in);
}
int SDLNet_GetLocalAddresses(IPaddress *addresses, int maxcount)
{
int count = 0;
#ifdef SIOCGIFCONF
/* Defined on Mac OS X */
#ifndef _SIZEOF_ADDR_IFREQ
#define _SIZEOF_ADDR_IFREQ sizeof
#endif
SOCKET sock;
struct ifconf conf;
char data[4096];
struct ifreq *ifr;
struct sockaddr_in *sock_addr;
sock = socket(AF_INET, SOCK_DGRAM, 0);
if ( sock == INVALID_SOCKET ) {
return 0;
}
conf.ifc_len = sizeof(data);
conf.ifc_buf = (caddr_t) data;
if ( ioctl(sock, SIOCGIFCONF, &conf) < 0 ) {
closesocket(sock);
return 0;
}
ifr = (struct ifreq*)data;
while ((char*)ifr < data+conf.ifc_len) {
if (ifr->ifr_addr.sa_family == AF_INET) {
if (count < maxcount) {
sock_addr = (struct sockaddr_in*)&ifr->ifr_addr;
addresses[count].host = sock_addr->sin_addr.s_addr;
addresses[count].port = sock_addr->sin_port;
}
++count;
}
ifr = (struct ifreq*)((char*)ifr + _SIZEOF_ADDR_IFREQ(*ifr));
}
closesocket(sock);
#elif defined(__WIN32__)
PIP_ADAPTER_INFO pAdapterInfo;
PIP_ADAPTER_INFO pAdapter;
PIP_ADDR_STRING pAddress;
DWORD dwRetVal = 0;
ULONG ulOutBufLen = sizeof (IP_ADAPTER_INFO);
pAdapterInfo = (IP_ADAPTER_INFO *) SDL_malloc(sizeof (IP_ADAPTER_INFO));
if (pAdapterInfo == NULL) {
return 0;
}
if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == ERROR_BUFFER_OVERFLOW) {
pAdapterInfo = (IP_ADAPTER_INFO *) SDL_realloc(pAdapterInfo, ulOutBufLen);
if (pAdapterInfo == NULL) {
return 0;
}
dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);
}
if (dwRetVal == NO_ERROR) {
for (pAdapter = pAdapterInfo; pAdapter; pAdapter = pAdapter->Next) {
for (pAddress = &pAdapterInfo->IpAddressList; pAddress; pAddress = pAddress->Next) {
if (count < maxcount) {
addresses[count].host = inet_addr(pAddress->IpAddress.String);
addresses[count].port = 0;
}
++count;
}
}
}
SDL_free(pAdapterInfo);
#endif
return count;
}
#if !SDL_DATA_ALIGNED /* function versions for binary compatibility */
/* Write a 16 bit value to network packet buffer */
#undef SDLNet_Write16
void SDLNet_Write16(Uint16 value, void *areap)
{
(*(Uint16 *)(areap) = SDL_SwapBE16(value));
}
/* Write a 32 bit value to network packet buffer */
#undef SDLNet_Write32
void SDLNet_Write32(Uint32 value, void *areap)
{
*(Uint32 *)(areap) = SDL_SwapBE32(value);
}
/* Read a 16 bit value from network packet buffer */
#undef SDLNet_Read16
Uint16 SDLNet_Read16(void *areap)
{
return (SDL_SwapBE16(*(Uint16 *)(areap)));
}
/* Read a 32 bit value from network packet buffer */
#undef SDLNet_Read32
Uint32 SDLNet_Read32(void *areap)
{
return (SDL_SwapBE32(*(Uint32 *)(areap)));
}
#endif /* !SDL_DATA_ALIGNED */
-295
View File
@@ -1,295 +0,0 @@
/*
SDL_net: An example cross-platform network library for use with SDL
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/* $Id$ */
#include "SDLnetsys.h"
#include "SDL_net.h"
/* The network API for TCP sockets */
/* Since the UNIX/Win32/BeOS code is so different from MacOS,
we'll just have two completely different sections here.
*/
struct _TCPsocket {
int ready;
SOCKET channel;
IPaddress remoteAddress;
IPaddress localAddress;
int sflag;
};
/* Open a TCP network socket
If 'remote' is NULL, this creates a local server socket on the given port,
otherwise a TCP connection to the remote host and port is attempted.
The newly created socket is returned, or NULL if there was an error.
*/
TCPsocket SDLNet_TCP_Open(IPaddress *ip)
{
TCPsocket sock;
struct sockaddr_in sock_addr;
/* Allocate a TCP socket structure */
sock = (TCPsocket)malloc(sizeof(*sock));
if ( sock == NULL ) {
SDLNet_SetError("Out of memory");
goto error_return;
}
/* Open the socket */
sock->channel = socket(AF_INET, SOCK_STREAM, 0);
if ( sock->channel == INVALID_SOCKET ) {
SDLNet_SetError("Couldn't create socket");
goto error_return;
}
/* Connect to remote, or bind locally, as appropriate */
if ( (ip->host != INADDR_NONE) && (ip->host != INADDR_ANY) ) {
// ######### Connecting to remote
memset(&sock_addr, 0, sizeof(sock_addr));
sock_addr.sin_family = AF_INET;
sock_addr.sin_addr.s_addr = ip->host;
sock_addr.sin_port = ip->port;
/* Connect to the remote host */
if ( connect(sock->channel, (struct sockaddr *)&sock_addr,
sizeof(sock_addr)) == SOCKET_ERROR ) {
SDLNet_SetError("Couldn't connect to remote host");
goto error_return;
}
sock->sflag = 0;
} else {
// ########## Binding locally
memset(&sock_addr, 0, sizeof(sock_addr));
sock_addr.sin_family = AF_INET;
sock_addr.sin_addr.s_addr = INADDR_ANY;
sock_addr.sin_port = ip->port;
/*
* Windows gets bad mojo with SO_REUSEADDR:
* http://www.devolution.com/pipermail/sdl/2005-September/070491.html
* --ryan.
*/
#ifndef WIN32
/* allow local address reuse */
{ int yes = 1;
setsockopt(sock->channel, SOL_SOCKET, SO_REUSEADDR, (char*)&yes, sizeof(yes));
}
#endif
/* Bind the socket for listening */
if ( bind(sock->channel, (struct sockaddr *)&sock_addr,
sizeof(sock_addr)) == SOCKET_ERROR ) {
SDLNet_SetError("Couldn't bind to local port");
goto error_return;
}
if ( listen(sock->channel, 5) == SOCKET_ERROR ) {
SDLNet_SetError("Couldn't listen to local port");
goto error_return;
}
/* Set the socket to non-blocking mode for accept() */
#if defined(__BEOS__) && defined(SO_NONBLOCK)
/* On BeOS r5 there is O_NONBLOCK but it's for files only */
{
long b = 1;
setsockopt(sock->channel, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
}
#elif defined(O_NONBLOCK)
{
fcntl(sock->channel, F_SETFL, O_NONBLOCK);
}
#elif defined(WIN32)
{
unsigned long mode = 1;
ioctlsocket (sock->channel, FIONBIO, &mode);
}
#elif defined(__OS2__)
{
int dontblock = 1;
ioctl(sock->channel, FIONBIO, &dontblock);
}
#else
#warning How do we set non-blocking mode on other operating systems?
#endif
sock->sflag = 1;
}
sock->ready = 0;
#ifdef TCP_NODELAY
/* Set the nodelay TCP option for real-time games */
{ int yes = 1;
setsockopt(sock->channel, IPPROTO_TCP, TCP_NODELAY, (char*)&yes, sizeof(yes));
}
#endif /* TCP_NODELAY */
/* Fill in the channel host address */
sock->remoteAddress.host = sock_addr.sin_addr.s_addr;
sock->remoteAddress.port = sock_addr.sin_port;
/* The socket is ready */
return(sock);
error_return:
SDLNet_TCP_Close(sock);
return(NULL);
}
/* Accept an incoming connection on the given server socket.
The newly created socket is returned, or NULL if there was an error.
*/
TCPsocket SDLNet_TCP_Accept(TCPsocket server)
{
TCPsocket sock;
struct sockaddr_in sock_addr;
socklen_t sock_alen;
/* Only server sockets can accept */
if ( ! server->sflag ) {
SDLNet_SetError("Only server sockets can accept()");
return(NULL);
}
server->ready = 0;
/* Allocate a TCP socket structure */
sock = (TCPsocket)malloc(sizeof(*sock));
if ( sock == NULL ) {
SDLNet_SetError("Out of memory");
goto error_return;
}
/* Accept a new TCP connection on a server socket */
sock_alen = sizeof(sock_addr);
sock->channel = accept(server->channel, (struct sockaddr *)&sock_addr,
&sock_alen);
if ( sock->channel == INVALID_SOCKET ) {
SDLNet_SetError("accept() failed");
goto error_return;
}
#ifdef WIN32
{
/* passing a zero value, socket mode set to block on */
unsigned long mode = 0;
ioctlsocket (sock->channel, FIONBIO, &mode);
}
#elif defined(O_NONBLOCK)
{
int flags = fcntl(sock->channel, F_GETFL, 0);
fcntl(sock->channel, F_SETFL, flags & ~O_NONBLOCK);
}
#endif /* WIN32 */
sock->remoteAddress.host = sock_addr.sin_addr.s_addr;
sock->remoteAddress.port = sock_addr.sin_port;
sock->sflag = 0;
sock->ready = 0;
/* The socket is ready */
return(sock);
error_return:
SDLNet_TCP_Close(sock);
return(NULL);
}
/* Get the IP address of the remote system associated with the socket.
If the socket is a server socket, this function returns NULL.
*/
IPaddress *SDLNet_TCP_GetPeerAddress(TCPsocket sock)
{
if ( sock->sflag ) {
return(NULL);
}
return(&sock->remoteAddress);
}
/* Send 'len' bytes of 'data' over the non-server socket 'sock'
This function returns the actual amount of data sent. If the return value
is less than the amount of data sent, then either the remote connection was
closed, or an unknown socket error occurred.
*/
int SDLNet_TCP_Send(TCPsocket sock, const void *datap, int len)
{
const Uint8 *data = (const Uint8 *)datap; /* For pointer arithmetic */
int sent, left;
/* Server sockets are for accepting connections only */
if ( sock->sflag ) {
SDLNet_SetError("Server sockets cannot send");
return(-1);
}
/* Keep sending data until it's sent or an error occurs */
left = len;
sent = 0;
SDLNet_SetLastError(0);
do {
len = send(sock->channel, (const char *) data, left, 0);
if ( len > 0 ) {
sent += len;
left -= len;
data += len;
}
} while ( (left > 0) && ((len > 0) || (SDLNet_GetLastError() == EINTR)) );
return(sent);
}
/* Receive up to 'maxlen' bytes of data over the non-server socket 'sock',
and store them in the buffer pointed to by 'data'.
This function returns the actual amount of data received. If the return
value is less than or equal to zero, then either the remote connection was
closed, or an unknown socket error occurred.
*/
int SDLNet_TCP_Recv(TCPsocket sock, void *data, int maxlen)
{
int len;
/* Server sockets are for accepting connections only */
if ( sock->sflag ) {
SDLNet_SetError("Server sockets cannot receive");
return(-1);
}
SDLNet_SetLastError(0);
do {
len = recv(sock->channel, (char *) data, maxlen, 0);
} while ( SDLNet_GetLastError() == EINTR );
sock->ready = 0;
return(len);
}
/* Close a TCP network socket */
void SDLNet_TCP_Close(TCPsocket sock)
{
if ( sock != NULL ) {
if ( sock->channel != INVALID_SOCKET ) {
closesocket(sock->channel);
}
free(sock);
}
}
-528
View File
@@ -1,528 +0,0 @@
/*
SDL_net: An example cross-platform network library for use with SDL
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/* $Id$ */
#include "SDLnetsys.h"
#include "SDL_net.h"
#ifdef __WIN32__
#define srandom srand
#define random rand
#endif
struct UDP_channel {
int numbound;
IPaddress address[SDLNET_MAX_UDPADDRESSES];
};
struct _UDPsocket {
int ready;
SOCKET channel;
IPaddress address;
struct UDP_channel binding[SDLNET_MAX_UDPCHANNELS];
/* For debugging purposes */
int packetloss;
};
/* Allocate/free a single UDP packet 'size' bytes long.
The new packet is returned, or NULL if the function ran out of memory.
*/
extern UDPpacket *SDLNet_AllocPacket(int size)
{
UDPpacket *packet;
int error;
error = 1;
packet = (UDPpacket *)malloc(sizeof(*packet));
if ( packet != NULL ) {
packet->maxlen = size;
packet->data = (Uint8 *)malloc(size);
if ( packet->data != NULL ) {
error = 0;
}
}
if ( error ) {
SDLNet_SetError("Out of memory");
SDLNet_FreePacket(packet);
packet = NULL;
}
return(packet);
}
int SDLNet_ResizePacket(UDPpacket *packet, int newsize)
{
Uint8 *newdata;
newdata = (Uint8 *)malloc(newsize);
if ( newdata != NULL ) {
free(packet->data);
packet->data = newdata;
packet->maxlen = newsize;
}
return(packet->maxlen);
}
extern void SDLNet_FreePacket(UDPpacket *packet)
{
if ( packet ) {
if ( packet->data )
free(packet->data);
free(packet);
}
}
/* Allocate/Free a UDP packet vector (array of packets) of 'howmany' packets,
each 'size' bytes long.
A pointer to the packet array is returned, or NULL if the function ran out
of memory.
*/
UDPpacket **SDLNet_AllocPacketV(int howmany, int size)
{
UDPpacket **packetV;
packetV = (UDPpacket **)malloc((howmany+1)*sizeof(*packetV));
if ( packetV != NULL ) {
int i;
for ( i=0; i<howmany; ++i ) {
packetV[i] = SDLNet_AllocPacket(size);
if ( packetV[i] == NULL ) {
break;
}
}
packetV[i] = NULL;
if ( i != howmany ) {
SDLNet_SetError("Out of memory");
SDLNet_FreePacketV(packetV);
packetV = NULL;
}
}
return(packetV);
}
void SDLNet_FreePacketV(UDPpacket **packetV)
{
if ( packetV ) {
int i;
for ( i=0; packetV[i]; ++i ) {
SDLNet_FreePacket(packetV[i]);
}
free(packetV);
}
}
/* Since the UNIX/Win32/BeOS code is so different from MacOS,
we'll just have two completely different sections here.
*/
/* Open a UDP network socket
If 'port' is non-zero, the UDP socket is bound to a fixed local port.
*/
UDPsocket SDLNet_UDP_Open(Uint16 port)
{
UDPsocket sock;
struct sockaddr_in sock_addr;
socklen_t sock_len;
/* Allocate a UDP socket structure */
sock = (UDPsocket)malloc(sizeof(*sock));
if ( sock == NULL ) {
SDLNet_SetError("Out of memory");
goto error_return;
}
memset(sock, 0, sizeof(*sock));
memset(&sock_addr, 0, sizeof(sock_addr));
/* Open the socket */
sock->channel = socket(AF_INET, SOCK_DGRAM, 0);
if ( sock->channel == INVALID_SOCKET )
{
SDLNet_SetError("Couldn't create socket");
goto error_return;
}
/* Bind locally, if appropriate */
sock_addr.sin_family = AF_INET;
sock_addr.sin_addr.s_addr = INADDR_ANY;
sock_addr.sin_port = SDL_SwapBE16(port);
/* Bind the socket for listening */
if ( bind(sock->channel, (struct sockaddr *)&sock_addr,
sizeof(sock_addr)) == SOCKET_ERROR ) {
SDLNet_SetError("Couldn't bind to local port");
goto error_return;
}
/* Get the bound address and port */
sock_len = sizeof(sock_addr);
if ( getsockname(sock->channel, (struct sockaddr *)&sock_addr, &sock_len) < 0 ) {
perror("getsockname");
SDLNet_SetError("Couldn't get socket address");
goto error_return;
}
/* Fill in the channel host address */
sock->address.host = sock_addr.sin_addr.s_addr;
sock->address.port = sock_addr.sin_port;
#ifdef SO_BROADCAST
/* Allow LAN broadcasts with the socket */
{ int yes = 1;
setsockopt(sock->channel, SOL_SOCKET, SO_BROADCAST, (char*)&yes, sizeof(yes));
}
#endif
#ifdef IP_ADD_MEMBERSHIP
/* Receive LAN multicast packets on 224.0.0.1
This automatically works on Mac OS X, Linux and BSD, but needs
this code on Windows.
*/
/* A good description of multicast can be found here:
http://www.docs.hp.com/en/B2355-90136/ch05s05.html
*/
/* FIXME: Add support for joining arbitrary groups to the API */
{
struct ip_mreq g;
g.imr_multiaddr.s_addr = inet_addr("224.0.0.1");
g.imr_interface.s_addr = INADDR_ANY;
setsockopt(sock->channel, IPPROTO_IP, IP_ADD_MEMBERSHIP,
(char*)&g, sizeof(g));
}
#endif
/* The socket is ready */
return(sock);
error_return:
SDLNet_UDP_Close(sock);
return(NULL);
}
void SDLNet_UDP_SetPacketLoss(UDPsocket sock, int percent)
{
/* FIXME: We may want this behavior to be reproducible
but there isn't a portable reentrant random
number generator with good randomness.
*/
srandom(SDL_GetTicks());
if (percent < 0) {
percent = 0;
} else if (percent > 100) {
percent = 100;
}
sock->packetloss = percent;
}
/* Verify that the channel is in the valid range */
static int ValidChannel(int channel)
{
if ( (channel < 0) || (channel >= SDLNET_MAX_UDPCHANNELS) ) {
SDLNet_SetError("Invalid channel");
return(0);
}
return(1);
}
/* Bind the address 'address' to the requested channel on the UDP socket.
If the channel is -1, then the first unbound channel will be bound with
the given address as it's primary address.
If the channel is already bound, this new address will be added to the
list of valid source addresses for packets arriving on the channel.
If the channel is not already bound, then the address becomes the primary
address, to which all outbound packets on the channel are sent.
This function returns the channel which was bound, or -1 on error.
*/
int SDLNet_UDP_Bind(UDPsocket sock, int channel, const IPaddress *address)
{
struct UDP_channel *binding;
if ( sock == NULL ) {
SDLNet_SetError("Passed a NULL socket");
return(-1);
}
if ( channel == -1 ) {
for ( channel=0; channel < SDLNET_MAX_UDPCHANNELS; ++channel ) {
binding = &sock->binding[channel];
if ( binding->numbound < SDLNET_MAX_UDPADDRESSES ) {
break;
}
}
} else {
if ( ! ValidChannel(channel) ) {
return(-1);
}
binding = &sock->binding[channel];
}
if ( binding->numbound == SDLNET_MAX_UDPADDRESSES ) {
SDLNet_SetError("No room for new addresses");
return(-1);
}
binding->address[binding->numbound++] = *address;
return(channel);
}
/* Unbind all addresses from the given channel */
void SDLNet_UDP_Unbind(UDPsocket sock, int channel)
{
if ( (channel >= 0) && (channel < SDLNET_MAX_UDPCHANNELS) ) {
sock->binding[channel].numbound = 0;
}
}
/* Get the primary IP address of the remote system associated with the
socket and channel.
If the channel is not bound, this function returns NULL.
*/
IPaddress *SDLNet_UDP_GetPeerAddress(UDPsocket sock, int channel)
{
IPaddress *address;
address = NULL;
switch (channel) {
case -1:
/* Return the actual address of the socket */
address = &sock->address;
break;
default:
/* Return the address of the bound channel */
if ( ValidChannel(channel) &&
(sock->binding[channel].numbound > 0) ) {
address = &sock->binding[channel].address[0];
}
break;
}
return(address);
}
/* Send a vector of packets to the the channels specified within the packet.
If the channel specified in the packet is -1, the packet will be sent to
the address in the 'src' member of the packet.
Each packet will be updated with the status of the packet after it has
been sent, -1 if the packet send failed.
This function returns the number of packets sent.
*/
int SDLNet_UDP_SendV(UDPsocket sock, UDPpacket **packets, int npackets)
{
int numsent, i, j;
struct UDP_channel *binding;
int status;
int sock_len;
struct sockaddr_in sock_addr;
if ( sock == NULL ) {
SDLNet_SetError("Passed a NULL socket");
return(0);
}
/* Set up the variables to send packets */
sock_len = sizeof(sock_addr);
numsent = 0;
for ( i=0; i<npackets; ++i )
{
/* Simulate packet loss, if desired */
if (sock->packetloss) {
if ((random()%100) <= sock->packetloss) {
packets[i]->status = packets[i]->len;
++numsent;
continue;
}
}
/* if channel is < 0, then use channel specified in sock */
if ( packets[i]->channel < 0 )
{
sock_addr.sin_addr.s_addr = packets[i]->address.host;
sock_addr.sin_port = packets[i]->address.port;
sock_addr.sin_family = AF_INET;
status = sendto(sock->channel,
packets[i]->data, packets[i]->len, 0,
(struct sockaddr *)&sock_addr,sock_len);
if ( status >= 0 )
{
packets[i]->status = status;
++numsent;
}
}
else
{
/* Send to each of the bound addresses on the channel */
#ifdef DEBUG_NET
printf("SDLNet_UDP_SendV sending packet to channel = %d\n", packets[i]->channel );
#endif
binding = &sock->binding[packets[i]->channel];
for ( j=binding->numbound-1; j>=0; --j )
{
sock_addr.sin_addr.s_addr = binding->address[j].host;
sock_addr.sin_port = binding->address[j].port;
sock_addr.sin_family = AF_INET;
status = sendto(sock->channel,
packets[i]->data, packets[i]->len, 0,
(struct sockaddr *)&sock_addr,sock_len);
if ( status >= 0 )
{
packets[i]->status = status;
++numsent;
}
}
}
}
return(numsent);
}
int SDLNet_UDP_Send(UDPsocket sock, int channel, UDPpacket *packet)
{
/* This is silly, but... */
packet->channel = channel;
return(SDLNet_UDP_SendV(sock, &packet, 1));
}
/* Returns true if a socket is has data available for reading right now */
static int SocketReady(SOCKET sock)
{
int retval = 0;
struct timeval tv;
fd_set mask;
/* Check the file descriptors for available data */
do {
SDLNet_SetLastError(0);
/* Set up the mask of file descriptors */
FD_ZERO(&mask);
FD_SET(sock, &mask);
/* Set up the timeout */
tv.tv_sec = 0;
tv.tv_usec = 0;
/* Look! */
retval = select(sock+1, &mask, NULL, NULL, &tv);
} while ( SDLNet_GetLastError() == EINTR );
return(retval == 1);
}
/* Receive a vector of pending packets from the UDP socket.
The returned packets contain the source address and the channel they arrived
on. If they did not arrive on a bound channel, the the channel will be set
to -1.
This function returns the number of packets read from the network, or -1
on error. This function does not block, so can return 0 packets pending.
*/
extern int SDLNet_UDP_RecvV(UDPsocket sock, UDPpacket **packets)
{
int numrecv, i, j;
struct UDP_channel *binding;
socklen_t sock_len;
struct sockaddr_in sock_addr;
if ( sock == NULL ) {
return(0);
}
numrecv = 0;
while ( packets[numrecv] && SocketReady(sock->channel) )
{
UDPpacket *packet;
packet = packets[numrecv];
sock_len = sizeof(sock_addr);
packet->status = recvfrom(sock->channel,
packet->data, packet->maxlen, 0,
(struct sockaddr *)&sock_addr,
&sock_len);
if ( packet->status >= 0 ) {
packet->len = packet->status;
packet->address.host = sock_addr.sin_addr.s_addr;
packet->address.port = sock_addr.sin_port;
packet->channel = -1;
for (i=(SDLNET_MAX_UDPCHANNELS-1); i>=0; --i )
{
binding = &sock->binding[i];
for ( j=binding->numbound-1; j>=0; --j )
{
if ( (packet->address.host == binding->address[j].host) &&
(packet->address.port == binding->address[j].port) )
{
packet->channel = i;
goto foundit; /* break twice */
}
}
}
foundit:
++numrecv;
}
else
{
packet->len = 0;
}
}
sock->ready = 0;
return(numrecv);
}
/* Receive a single packet from the UDP socket.
The returned packet contains the source address and the channel it arrived
on. If it did not arrive on a bound channel, the the channel will be set
to -1.
This function returns the number of packets read from the network, or -1
on error. This function does not block, so can return 0 packets pending.
*/
int SDLNet_UDP_Recv(UDPsocket sock, UDPpacket *packet)
{
UDPpacket *packets[2];
/* Receive a packet array of 1 */
packets[0] = packet;
packets[1] = NULL;
return(SDLNet_UDP_RecvV(sock, packets));
}
/* Close a UDP network socket */
extern void SDLNet_UDP_Close(UDPsocket sock)
{
if ( sock != NULL )
{
if ( sock->channel != INVALID_SOCKET )
{
closesocket(sock->channel);
}
free(sock);
}
}
-163
View File
@@ -1,163 +0,0 @@
/*
SDL_net: An example cross-platform network library for use with SDL
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/* $Id$ */
#include "SDLnetsys.h"
#include "SDL_net.h"
/* The select() API for network sockets */
struct SDLNet_Socket {
int ready;
SOCKET channel;
};
struct _SDLNet_SocketSet {
int numsockets;
int maxsockets;
struct SDLNet_Socket **sockets;
};
/* Allocate a socket set for use with SDLNet_CheckSockets()
This returns a socket set for up to 'maxsockets' sockets, or NULL if
the function ran out of memory.
*/
SDLNet_SocketSet SDLNet_AllocSocketSet(int maxsockets)
{
struct _SDLNet_SocketSet *set;
int i;
set = (struct _SDLNet_SocketSet *)malloc(sizeof(*set));
if ( set != NULL ) {
set->numsockets = 0;
set->maxsockets = maxsockets;
set->sockets = (struct SDLNet_Socket **)malloc
(maxsockets*sizeof(*set->sockets));
if ( set->sockets != NULL ) {
for ( i=0; i<maxsockets; ++i ) {
set->sockets[i] = NULL;
}
} else {
free(set);
set = NULL;
}
}
return(set);
}
/* Add a socket to a set of sockets to be checked for available data */
int SDLNet_AddSocket(SDLNet_SocketSet set, SDLNet_GenericSocket sock)
{
if ( sock != NULL ) {
if ( set->numsockets == set->maxsockets ) {
SDLNet_SetError("socketset is full");
return(-1);
}
set->sockets[set->numsockets++] = (struct SDLNet_Socket *)sock;
}
return(set->numsockets);
}
/* Remove a socket from a set of sockets to be checked for available data */
int SDLNet_DelSocket(SDLNet_SocketSet set, SDLNet_GenericSocket sock)
{
int i;
if ( sock != NULL ) {
for ( i=0; i<set->numsockets; ++i ) {
if ( set->sockets[i] == (struct SDLNet_Socket *)sock ) {
break;
}
}
if ( i == set->numsockets ) {
SDLNet_SetError("socket not found in socketset");
return(-1);
}
--set->numsockets;
for ( ; i<set->numsockets; ++i ) {
set->sockets[i] = set->sockets[i+1];
}
}
return(set->numsockets);
}
/* This function checks to see if data is available for reading on the
given set of sockets. If 'timeout' is 0, it performs a quick poll,
otherwise the function returns when either data is available for
reading, or the timeout in milliseconds has elapsed, which ever occurs
first. This function returns the number of sockets ready for reading,
or -1 if there was an error with the select() system call.
*/
int SDLNet_CheckSockets(SDLNet_SocketSet set, Uint32 timeout)
{
int i;
SOCKET maxfd;
int retval;
struct timeval tv;
fd_set mask;
/* Find the largest file descriptor */
maxfd = 0;
for ( i=set->numsockets-1; i>=0; --i ) {
if ( set->sockets[i]->channel > maxfd ) {
maxfd = set->sockets[i]->channel;
}
}
/* Check the file descriptors for available data */
do {
SDLNet_SetLastError(0);
/* Set up the mask of file descriptors */
FD_ZERO(&mask);
for ( i=set->numsockets-1; i>=0; --i ) {
FD_SET(set->sockets[i]->channel, &mask);
}
/* Set up the timeout */
tv.tv_sec = timeout/1000;
tv.tv_usec = (timeout%1000)*1000;
/* Look! */
retval = select(maxfd+1, &mask, NULL, NULL, &tv);
} while ( SDLNet_GetLastError() == EINTR );
/* Mark all file descriptors ready that have data available */
if ( retval > 0 ) {
for ( i=set->numsockets-1; i>=0; --i ) {
if ( FD_ISSET(set->sockets[i]->channel, &mask) ) {
set->sockets[i]->ready = 1;
}
}
}
return(retval);
}
/* Free a set of sockets allocated by SDL_NetAllocSocketSet() */
extern void SDLNet_FreeSocketSet(SDLNet_SocketSet set)
{
if ( set ) {
free(set->sockets);
free(set);
}
}
-94
View File
@@ -1,94 +0,0 @@
/*
SDL_net: An example cross-platform network library for use with SDL
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/* $Id$ */
/* Include normal system headers */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef _WIN32_WCE
#include <errno.h>
#endif
/* Include system network headers */
#if defined(__WIN32__) || defined(WIN32)
#define __USE_W32_SOCKETS
#ifdef _WIN64
#include <winsock2.h>
#include <ws2tcpip.h>
#else
#include <winsock.h>
/* NOTE: windows socklen_t is signed
* and is defined only for winsock2. */
typedef int socklen_t;
#endif /* W64 */
#include <iphlpapi.h>
#else /* UNIX */
#include <sys/types.h>
#ifdef __FreeBSD__
#include <sys/socket.h>
#endif
#include <sys/ioctl.h>
#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>
#include <netinet/in.h>
#ifndef __BEOS__
#include <arpa/inet.h>
#endif
#ifdef linux /* FIXME: what other platforms have this? */
#include <netinet/tcp.h>
#endif
#include <sys/socket.h>
#include <net/if.h>
#include <netdb.h>
#endif /* WIN32 */
/* FIXME: What platforms need this? */
#if 0
typedef Uint32 socklen_t;
#endif
/* System-dependent definitions */
#ifndef __USE_W32_SOCKETS
#ifdef __OS2__
#define closesocket soclose
#else /* !__OS2__ */
#define closesocket close
#endif /* __OS2__ */
#define SOCKET int
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#endif /* __USE_W32_SOCKETS */
#ifdef __USE_W32_SOCKETS
#define SDLNet_GetLastError WSAGetLastError
#define SDLNet_SetLastError WSASetLastError
#ifndef EINTR
#define EINTR WSAEINTR
#endif
#else
int SDLNet_GetLastError(void);
void SDLNet_SetLastError(int err);
#endif
-39
View File
@@ -1,39 +0,0 @@
#config
LIBDIR=..
LOCALLIBS=
LIB=
INCLUDES=
CFLAGS+=$(addprefix -I,$(INCLUDES))
#source
SRC=$(wildcard *.c)
#objects
OBJDIR=obj
OBJ=$(addprefix $(OBJDIR)/,$(SRC:.c=.o))
#output
OUTDIR=../out
OUT=$(addprefix $(OUTDIR)/,libSDL_net.a)
#targets
all: $(OBJ) $(OUT)
ar -crs $(OUT) $(OBJ)
$(OBJ): | $(OBJDIR)
$(OUT): | $(OUTDIR)
$(OBJDIR):
mkdir $(OBJDIR)
$(OUTDIR):
mkdir $(OUTDIR)
$(OBJDIR)/%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
clean:
$(RM) *.o *.a *.exe
rebuild: clean all
-110
View File
@@ -1,110 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "network_queue.hpp"
#include "singleton.hpp"
#include "udp_network_utility.hpp"
#include "SDL/SDL_thread.h"
#include <stdexcept>
#include <deque>
static SDL_sem* lock = SDL_CreateSemaphore(1);
static SDL_Thread* queueThread = nullptr;
static std::deque<Packet> queue;
static bool running = false;
static int networkQueue(void*) {
UDPNetworkUtility* netUtil = Singleton<UDPNetworkUtility>::Get();
while(running) {
SDL_SemWait(lock);
while(netUtil->Receive()) {
Packet p;
memcpy(&p, netUtil->GetInData(), sizeof(Packet));
p.meta.address = netUtil->GetInPacket()->address;
queue.push_back(p);
}
SDL_SemPost(lock);
SDL_Delay(10);
}
return 0;
}
void beginQueueThread() {
if (running) {
return;
}
running = true;
if (!(queueThread = SDL_CreateThread(networkQueue, nullptr))) {
throw(std::runtime_error("Failed to create the network thread"));
}
}
void endQueueThread() {
if (!running) {
return;
}
running = false;
SDL_WaitThread(queueThread, nullptr);
queueThread = nullptr;
}
void killQueueThread() {
if (!running) {
return;
}
running = false;
SDL_KillThread(queueThread);
queueThread = nullptr;
}
Packet peekNetworkPacket() {
SDL_SemWait(lock);
Packet p;
if (queue.size() > 0) {
Packet p = queue[0];
}
SDL_SemPost(lock);
return p;
}
Packet popNetworkPacket() {
SDL_SemWait(lock);
Packet p;
if (queue.size() > 0) {
p = queue[0];
queue.pop_front();
}
SDL_SemPost(lock);
return p;
}
void flushNetworkQueue() {
UDPNetworkUtility* netUtil = Singleton<UDPNetworkUtility>::Get();
SDL_SemWait(lock);
while(netUtil->Receive());
queue.clear();
SDL_SemPost(lock);
}
-34
View File
@@ -1,34 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef NETWORKQUEUE_HPP_
#define NETWORKQUEUE_HPP_
#include "packet.hpp"
void beginQueueThread();
void endQueueThread();
void killQueueThread();
Packet peekNetworkPacket();
Packet popNetworkPacket();
void flushNetworkQueue();
#endif
-35
View File
@@ -1,35 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef SERVERENTRY_HPP_
#define SERVERENTRY_HPP_
#include "SDL_net/SDL_net.h"
#include <string>
struct ServerEntry {
std::string name;
IPaddress address;
//TODO: player count
};
#endif
-38
View File
@@ -1,38 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef SINGLETON_HPP_
#define SINGLETON_HPP_
template<typename T>
class Singleton {
public:
static T* Get() {
return &instance;
}
private:
static T instance;
};
template<typename T>
T Singleton<T>::instance;
#endif
-29
View File
@@ -1,29 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef UTILITIES_HPP_
#define UTILITIES_HPP_
#include <string>
std::string itos(int i);
#endif
-13
View File
@@ -1,13 +0,0 @@
OUTDIR=out
all: $(OUTDIR)
$(MAKE) -C codebase
$(MAKE) -C common
$(OUTDIR):
mkdir $(OUTDIR)
clean:
$(RM) *.o *.a *.exe
rebuild: clean all
+11 -2
View File
@@ -1,11 +1,20 @@
#for use on Windows:
#MKDIR=mkdir
#RM=del /y
CXXFLAGS+=-static-libgcc -static-libstdc++
CFLAGS+=-static-libgcc
export
OUTDIR=out
all: $(OUTDIR)
$(MAKE) -C libs
$(MAKE) -C common
$(MAKE) -C server
$(MAKE) -C client
$(MAKE) -C editor
$(MAKE) -C test
$(OUTDIR):
mkdir $(OUTDIR)
+20 -11
View File
@@ -1,20 +1,29 @@
#configuration of the programs
server.host = 127.0.0.1
server.port = 1991
server.name = foobar
server.host = 255.255.255.255
server.port = 21795
server.name = local
server.dbname = database.db
screen.w = 800
screen.h = 600
screen.f = false
#directories
fonts = rsc/graphics/fonts
logos = rsc/graphics/logos
sprites = rsc/graphics/sprites
tilesets = rsc/graphics/tilesets
interface = rsc/graphics/interface
dir.fonts = rsc/graphics/fonts/
dir.logos = rsc/graphics/logos/
dir.sprites = rsc/graphics/sprites/
dir.tilesets = rsc/graphics/tilesets/
dir.interface = rsc/graphics/interface/
dir.scripts = rsc/scripts/
#map system
map.pager.width = 20
map.pager.height = 20
map.pager.depth = 3
#player options
player.handle = username
player.avatar = elliot2.bmp
#debugging
debug = true
avatar = elliot
handle = UserName

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Some files were not shown because too many files have changed in this diff Show More