folkertvanverseveld / aoe Goto Github PK
View Code? Open in Web Editor NEWRe-implementation of Age of Empires and the Rise of Rome expansion
License: Apache License 2.0
Re-implementation of Age of Empires and the Rise of Rome expansion
License: Apache License 2.0
Upgrade primitive UI and document UI flows. Both the original and the
expansion should have the same flows, but verify this just in case.
The code duplication for the tools and game engine is getting really
messy. The original version provided some common genie code as a
library, which is probably the best in the long term.
compute and broadcast player score
Most small label text items are misaligned vertically, but it is a real mystery
to me why this is happening. It looks like libfreetype does not like the fonts,
but we can't much about that if that's the case...
Anyway, it is a known issue (see bugs file), but it would be nice if we can find
a good and permanent workaround...
I tried the latest revision (d28041e) with the "Age of Empires Demo" (from here).
As expected, it didn't work, since this port has a fixed data location using the cdrom path. The installed demo has this structure:
├── aelaunch.dll
├── AoEHlp.dll
├── campaign
│ ├── Armies at War, A Combat Showcase.cpn
│ └── Reign of the Hittites.cpn
├── data
│ ├── aggressive 3 attackers.per
│ ├── aggressive no defend.per
│ ├── aggressive.per
│ ├── aichall.ai
│ ├── aoe.ply
│ ├── Archers Bronze.ai
│ ├── Archers Iron.ai
│ ├── Assyria Ballista.ai
│ ├── Assyria Bowmen.ai
│ ├── Babylon Scouts.ai
│ ├── Babylon Swordsmen.ai
│ ├── Border.drs
│ ├── Cav Archer Iron.ai
│ ├── Cavalry Bronze.ai
│ ├── Cavalry Iron.ai
│ ├── Choson Axemen.ai
│ ├── Choson Swordsmen.ai
│ ├── closedpw.exe
│ ├── Death Match Assyria.ai
│ ├── Death Match Babylon.ai
│ ├── Death Match Choson.ai
│ ├── Death Match Egypt.ai
│ ├── Death Match Greek.ai
│ ├── Death Match Hittite.ai
│ ├── Death Match Minoa.ai
│ ├── Death Match Persia.ai
│ ├── Death Match Phoenicia.ai
│ ├── Death Match Shang.ai
│ ├── Death Match Sumeria.ai
│ ├── Death Match Yamato.ai
│ ├── Default.ai
│ ├── Default.cty
│ ├── Default.per
│ ├── Defensive.per
│ ├── Egypt Chariots.ai
│ ├── Egypt War Elephants.ai
│ ├── Elephant Archer Iron.ai
│ ├── empires.dat
│ ├── graphics.drs
│ ├── Greek Phalanx.ai
│ ├── Hittite Bowmen.ai
│ ├── Hittite Horse Archers.ai
│ ├── Immortal Assyria.ai
│ ├── Immortal Egypt.ai
│ ├── Immortal Greek.ai
│ ├── Immortal Minoa.ai
│ ├── Immortal Sumeria.ai
│ ├── Immortal Yamato.ai
│ ├── Infantry Bronze.ai
│ ├── Infantry Stone.ai
│ ├── Infantry Tool.ai
│ ├── Interfac.drs
│ ├── Minoa Composite bowmen.ai
│ ├── Passive Aggressive.per
│ ├── Passive.per
│ ├── Persia Elephant Archers.ai
│ ├── Phalanx Bronze.ai
│ ├── Phalanx Iron.ai
│ ├── Phoenicia Elephants.ai
│ ├── Priest Bronze.ai
│ ├── Priest Iron.ai
│ ├── rules.rps
│ ├── shadow.col
│ ├── Shang Cavalry.ai
│ ├── Shang Clubmen.ai
│ ├── Shang Heavy Cavalry.ai
│ ├── sounds.drs
│ ├── Sumeria Catapults.ai
│ ├── Sumeria Scouts.ai
│ ├── super aggressive.per
│ ├── Terrain.drs
│ ├── TILEEDGE.DAT
│ ├── Trireme Bronze.ai
│ ├── Trireme Iron.ai
│ ├── War Elephant Iron.ai
│ ├── wonderonly.ai
│ └── Yamato Heavy Cavalry.ai
├── docs
│ ├── assyrian.doc
│ ├── bablnian.doc
│ ├── choson.doc
│ ├── egyptian.doc
│ ├── greek.doc
│ ├── hittite.doc
│ ├── minoan.doc
│ ├── persian.doc
│ ├── phnician.doc
│ ├── README.doc
│ ├── shang.doc
│ ├── sumerian.doc
│ └── yamato.doc
├── empires.exe
├── EMPIRES.HLP
├── eula.txt
├── fonts
│ ├── arialbd.ttf
│ ├── arial.ttf
│ ├── comicbd.ttf
│ ├── comic.ttf
│ ├── coprgtb.ttf
│ └── coprgtl.ttf
├── language.dll
├── learn
│ └── Learn.txt
├── savegame
│ └── SAVEGAME.TXT
├── scenario
│ ├── Multiplayer Rumble (8-Player).scn
│ └── scenario.inf
├── SETUPENU.DLL
├── sound
│ ├── BIRD.WAV
│ ├── desert1.WAV
│ ├── forest1.wav
│ ├── LOST.MID
│ ├── MUSIC1.MID
│ ├── MUSIC2.MID
│ ├── MUSIC3.MID
│ ├── MUSIC4.MID
│ ├── MUSIC5.MID
│ ├── MUSIC6.MID
│ ├── MUSIC7.MID
│ ├── MUSIC8.MID
│ ├── MUSIC9.MID
│ ├── ocean1.wav
│ ├── OPEN.MID
│ ├── wind1.WAV
│ ├── wind2.wav
│ └── WON.MID
└── UNINSTAL.EXE
I modified a little the paths in the code to match what we have. This is the diff:
diff --git a/empiresx/fs.cpp b/empiresx/fs.cpp
index f6335bb..868916e 100644
--- a/empiresx/fs.cpp
+++ b/empiresx/fs.cpp
@@ -136,16 +136,10 @@ bool FS::find_cdrom(OS &os) {
}
}
#else
- path_cdrom = "/media/cdrom/";
- if (std::ifstream("/media/cdrom/SYSTEM/FONTS/ARIAL.TTF", std::ios::binary))
+ path_cdrom = "./";
+ if (std::ifstream(path_cdrom + "FONTS/ARIAL.TTF", std::ios::binary))
return true;
- if (std::ifstream("/media/cdrom/system/fonts/arial.ttf", std::ios::binary))
- return true;
-
- path_cdrom = "/media/" + os.username + "/cdrom/";
- if (std::ifstream(path_cdrom + "SYSTEM/FONTS/ARIAL.TTF", std::ios::binary))
- return true;
- if (std::ifstream(path_cdrom + "system/fonts/arial.ttf", std::ios::binary))
+ if (std::ifstream(path_cdrom + "fonts/arial.ttf", std::ios::binary))
return true;
#endif
return false;
@@ -158,20 +152,20 @@ void FS::init(OS &os) {
Font FS::open_ttf(const std::string &name, int ptsize) {
std::string base(name);
- std::string path(path_cdrom + "system/fonts/" + base), orig(path);
+ std::string path(path_cdrom + "/fonts/" + base), orig(path);
TTF_Font *f;
if ((f = TTF_OpenFont(path.c_str(), ptsize)) != NULL)
return Font(f, ptsize);
tolower(base);
- path = path_cdrom + "system/fonts/" + base;
+ path = path_cdrom + "/fonts/" + base;
if ((f = TTF_OpenFont(path.c_str(), ptsize)) != NULL)
return Font(f, ptsize);
toupper(base);
- path = path_cdrom + "SYSTEM/FONTS/" + base;
+ path = path_cdrom + "/FONTS/" + base;
if ((f = TTF_OpenFont(path.c_str(), ptsize)) != NULL)
return Font(f, ptsize);
@@ -181,20 +175,20 @@ Font FS::open_ttf(const std::string &name, int ptsize) {
DRS FS::open_drs(const std::string &name, bool map) {
std::string base(name);
- std::string path(path_cdrom + "game/data/" + base), orig(path);
+ std::string path(path_cdrom + "data/" + base), orig(path);
iofd fd;
if ((fd = iofd_open(path)) != FD_INVALID)
return DRS(path, fd, map);
tolower(base);
- path = path_cdrom + "game/data/" + base;
+ path = path_cdrom + "data/" + base;
if ((fd = iofd_open(path)) != FD_INVALID)
return DRS(path, fd, map);
toupper(base);
- path = path_cdrom + "GAME/DATA/" + base;
+ path = path_cdrom + "DATA/" + base;
if ((fd = iofd_open(path)) != FD_INVALID)
return DRS(path, fd, map);
@@ -204,20 +198,20 @@ DRS FS::open_drs(const std::string &name, bool map) {
PE FS::open_pe(const std::string &name) {
std::string base(name);
- std::string path(path_cdrom + "game/" + base), orig(path);
+ std::string path(path_cdrom + base), orig(path);
iofd fd;
if ((fd = iofd_open(path)) != FD_INVALID)
return PE(path, fd);
tolower(base);
- path = path_cdrom + "game/" + base;
+ path = path_cdrom + base;
if ((fd = iofd_open(path)) != FD_INVALID)
return PE(path, fd);
toupper(base);
- path = path_cdrom + "GAME/" + base;
+ path = path_cdrom + base;
if ((fd = iofd_open(path)) != FD_INVALID)
return PE(path, fd);
@@ -227,28 +221,28 @@ PE FS::open_pe(const std::string &name) {
Mix_Music *FS::open_msc(const std::string &name) {
std::string base(name);
- std::string path(path_cdrom + "game/sound/" + base);
+ std::string path(path_cdrom + "sound/" + base);
Mix_Music *msc;
if ((msc = Mix_LoadMUS(path.c_str())) != 0)
return msc;
toupper(base);
- path = path_cdrom + "GAME/SOUND/" + base;
+ path = path_cdrom + "SOUND/" + base;
return Mix_LoadMUS(path.c_str());
}
Mix_Chunk *FS::open_wav(const std::string &name) {
std::string base(name);
- std::string path(path_cdrom + "game/sound/" + base);
+ std::string path(path_cdrom + "sound/" + base);
Mix_Chunk *sfx;
if ((sfx = Mix_LoadWAV(path.c_str())) != 0)
return sfx;
toupper(base);
- path = path_cdrom + "GAME/SOUND/" + base;
+ path = path_cdrom + "SOUND/" + base;
return Mix_LoadWAV(path.c_str());
}
However, this still fails with:
Could not load animation 50100: bad id
Is it possible to support the demo? It will allow users to easily test this reimplementation without buying the full game.
Old reverse engineering samples are not used for a long time, so investigate what can be reused and what can be deleted forever.
The backgrounds use a custom text file format which contains multiple
reference IDs to shp/slp files. In order to properly render backgrounds
we have to:
The dimensions are probably hardcoded, since all supported fullscreen
resolutions are 640x480, 800x600, 1024x768 and 1280x1024 were 800x600 is
the best fit and other dimensions just stretch the background to make it
fit.
The rendering process is probably just blitting the background picture,
but we have to reverse engineer this to make sure that's all that's
required.
In-game video's are using an AVI codec that is not properly supported by
the open source AVI library. Except the very first intro, all even and
odd frames look swapped, giving lots of jitter.
There is no workaround at the moment on linux, because I am definitely
not going to write an AVI player myself... on windows, we may use the
win32 API, but something tells me that is not going to be easy either...
SDL is tightly intertwined with our graphics and user interface
subsystem, which makes it more difficult to provide a configurable
interface for other rendering libraries like OpenGL.
For each rendering library, we have to completely test all functionality
to make sure the game runs smoothly regardless the configuration. Note
that SDL fullscreen mode breaks on my machine (probably due to
propietary driver with xrandr), but we have to test the game on multiple
devices to verify this.
Hi, I'm a big fan of AoE and really like your project. I'm contributing to this project, which is a reverse-engeneering effort of the Genie game engine. Since that's part of your work on this big project, I thought it was better for us to share as much as possible, for you to check your port's behaviour against the actual decompiled code and for us, to integrate your findings and decompiled/understood functions inside the code. For example, I really liked this one.
So, if you want, you could share with us the IDB file you're working on.
And keep up the good work, man 😄
We need easy to implement and easy to use debug facilities:
After a game has ended. The user achievements menu is very limited.
Some proposed improvements:
Implement true type font subsystem using libSDL2_ttf and default to
/usr/share/fonts/ and scan subdirectories for fonts and fall back to
~/.fonts if nothing could be found.
All symbols residing in src/genie/ are not using the same name
convention, because some are prefixed with genie_, some with ge_, and
some with nothing at all. This is partially caused by redesigns of
several components and moving code around and partially due to a lack of
consistency.
In C, it is more troublesome to make sure identifiers are unique, we
could prefix all exported symbols in src/genie/ with genie_, but we can
also wait to do this once the project has more game mechanics before
releasing a prototype
The code in src/game/ and src/tools/ is not subject to this, since these
are just using our genie game engine and are not required to use a
strict name convention.
Currently, I am the only contributor to the project so a change can be
easily made, but I think it is better to settle on a convention before
more people start contributing.
While True Type Font support is nice, libfreetype sucks for many fonts.
This is not acceptable. Therefore, we are going to prerender all fonts,
which will also improve performance.
Since the original game fonts cannot be used due to copyright
constraints, we are going to provide a font dumper tool such that these
can be manually created with an original game license. We are also going
to provide alternative fonts for anyone who doesn't want to bother doing
this manually.
All audio effects (and maybe background music) will be streamed using
OpenAL, because OpenAL is a very powerful library that eases real-time
audio manipulation.
Upgrade the game engine to play effects and extend this to support more
sophisticated playback techniques.
Since the project has started, several engines have been written to try out different approaches. As the goals of this project were narrowed down further, it has become apparent that the best approach to make it maintainable for a single person is to use relatively modern technology (i.e. OpenGL without using fancy shaders as AoE does not need flexible stuff, just easy-to-use stuff) and use several libraries that have already accomplished these goals.
There are really good midi renditions of the original game sound track, such as the Roland SC-88 midi soundtrack. It would be nice if the game also supports playing these tracks or even custom ones if the player wants to.
Color palette textures are more or less supported at the moment, but
I'm going to port some palette handling code from another project of
mine that is more stable and robust. It also supports color palette
textures with an alpha channel (I thought that should not be possible,
but I was wrong).
AGPLv3 seems too limited for my goals, so I'm going to change the license to Apache 2, which should also ensure all IP rights are still protected for Microsoft as I do not claim any ownership whatsoever about all the in game assets etc.
As the original game only runs in fullscreen mode, whereas our port supports windowed and fullscreen mode, we need to clip the cursor to give the same mouse cursor experience.
MinGW g++ fails to compile the master branch as the toolchain interprets code differently compared to MSVC++. This may be ISO C++ issues, but could be compiler specific. Need to investigate this. Potential patch has been written, just need to check it later.
Use gcc backtrace extension, or libunwind or addr2line for backtracing
during a crash to create proper crash logs that can be dumped to a file
for easy bugreporting.
The double fault handler just keeps track whether the crash handler has
been invoked already and calls abort if it's already been called.
While libpev serves it purpose, it gives more problems than it solves
when it comes to cross-platform support. On windows, this prevents us
from providing a 64 bit version since the language files only support 32
bit architectures.
Only string and bitmap support should be enough.
It would be nice if the remake is at least as fast as the original, so use the Tracy Profiler to track down performance bottlenecks.
The game is powered by our custom written genie game engine. Currently,
the building process is cumbersome, ugly and error-prone (i.e. including
source files directly).
The following options are available:
The first option is probably the best. We need to investigate this and
implement a proof-of-concept.
birds are now stationary. they should move randomly to tiles.
Development has been suspended for almost 6 months on the public repo
because the reverse enginering process took much longer than expected. I
am also very busy irl but I am doing my best to resume this project step
by step.
I have been thinking for a long time about the best way to continue this
project. There is a lot of ugly code and even some broken stuff as well.
I am currently thinking about the following:
And also the following much more time consuming points:
Even though multiple other projects have similar goals to this project,
I have noticed a long time ago that each project has their own problems.
The last thing I am writing down to make sure I don't forget it: make
sure that even slow old computers, maybe even as old as computers with
the original soft- and hardware requirements, are able to run this game.
Implement a way to save and restore a multiplayer session.
Motivation:
Multiplayer games are disrupted easily by desynchronisation errors. This
is very frustrating since the game does not support saving and restoring
multiplayer sessions.
It would be nice if the first playable prototype provides a simple
multiplayer server that clients can connect to and play a match.
The list above is incomplete, but should be a good starting point.
When I want to build the game in /path/to/aoe
with make
, I get the following error:
make: *** No rule to make target 'game', needed by 'default'. Stop.
Actually there is no game rule/target in the aoe/Makefile
. I figured out that when out-commenting the default: genie game
line with #
, it works pretty much so far.
To be able to test properly, it helps to have a working scenario editor
Proper unit selection, player or gaia units, as well as static (e.g.
trees, berry bushes) and dynamic resources (e.g. gazelle, lions) is
difficult.
As far as I can tell, the original game does bounds checking as follows:
Lately, I've been developing a lot on windows due to hw and OS stability issues... and since the game is originally written for windows anyway, it makes no sense to drop windows support. Therefore, while I am refactoring the project, I am going to port the game to windows while doing so.
Tools may or may not be ported to windows, because they are not as important.
During the game, any user (for now or do we want restrictions?) should be able to control the gamespeed. This includes pausing and unpausing the game.
All legitimate versions of Age of Empires (as far as we know) have been
shipped on CD-ROM only. A CD-ROM subsystem is going to be implemented
that automagically recognizes the CD-ROM drive and reads all asset
files.
This also makes it easier for us to verify which version of Age of
Empires is installed on the CD-ROM and makes it easier for end-users to
run the game directly from the CD-ROM rather than installing the game
through wine and then running our remake to be able to play the game.
The following has to be implemented:
We have finally implemented enough user interface and low-level components in
the main game to be able to start a dummy single player game with dummy players.
The following points must be completed before we can play a real game:
The original game was released on a CD-ROM and the setup program takes care of
the installation process. However, it would be nice if we could reverse engineer
the setup and figure out how the installation process takes place.
Porting the installer itself will probably be tracked in another issue, because
this issue is really big and takes a lot of time.
Currently, the following has to be implemented:
This list is not complete and subject to changes.
Because of a disparity in skill between players, I suggest having handicaps for players. e.g. the following (with varying levels). These handicaps would be assignable to players, in the lobby.
It might also be best to have positive handicaps as well, for players that are less skilled at the game.
Looking at Empire Earth II for example, this is the worst handicap that a player can have:
Of course there are more possibilities, like e.g. conversion resistance.
Record a video or something about the progress of the project.
Hi!
We, the https://github.com/SFTtech/openage project, would like to motivate you to contribute to our code. We also have fun reinventing wheels by attaching rockets to them, but we attached some rockets already and if we do it right, our engine will support Rise of Rome
as well.
Of course I can understand if you want to do it on your own for fun, but we both may profit more when we focus on a single engine (which is, say, FUCKIN HARD TO IMPLEMENT anyway).
Cheers,
JJ
Hi. You. I build it with cygwin sucessed but run have some error. First, i run it show error need all library .dll in cygwin/bin. When i copy all .dll file to folder game and run again program auto close windows game, don't show any error.
You can make vmware os file with all build sucssess or video install?
Enhance command flow experience by providing integrated console in the
game. Depending on our needs, we could add support for VT-100 terminals
to be able to execute shell commands in it (although this may be
vulnerable to scripts etc.).
The console must be a configurable option in the general configuration
script. This ensures one can compile the project as close to the
original game as possible.
The following is going to be implemented:
Determine or reverse-engineer the civilizations and unit statistics for both the
original Age of Empires as well as the Rise of Rome expansion. Note that these
statistics were often changed by patches back then.
Implemented:
Some statistics were provided by the card foldout of the original Age of
Empires for macOS 9, but this foldout is missing multiple columns that we
have to reverse-engineer.
graphical effects like explosions, projectile debris, move to and waypoint markers need to be implemented. these particles can't interact with anything.
The original game ships with multiple AVI files that are played at
different moments while running the game. logo1, logo2 and intro are
played before the game menu shows up and the other files are played
before and after a campaign.
Currently, we have written a simple wrapper that calls the command line
wrapper for VLC to play these files. Unfortunately, the video codec
seems to be unknown to VLC, because the key frames are not recognized
correctly and the playback is jittering.
We certainly don't want to write our own AVI player because that adds
way too much cruft to the game engine, but we have to investigate
alternatives to improve the video playback.
We could try ffplay, but ffplay seems to suffer from the exact same
problem and has these additional problems:
The top and bottom menubar in the scenario editor are not rendered properly. Many pixels are skipped (see image)
steps:
The original game provides multiple screen resolutions in game and in all menu's for 640x480
, 800x600
and 1024x768
. Besides supporting these resolutions, it should also provide windowed and fullscreen support and eventually even larger resolutions like 1920x1080
, but the latter is probably for a separate issue.
entity animations run at different speeds. currently, they all run at the same speed.
Doesn't seem to build anymore (from a clean sync and build)...
make[1]: *** No rule to make target '../genie/libgenie.a', needed by 'cheat'. Stop.
I assume it's related to bff4917
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.