Here are some "big" things you might want to look at:
- Deriving APP from System from Input. You shouldn't need all this inheritance. Try think in terms of composition instead (APP contains a Game, a Menu, a Window and an Input...).
- Use the Single Responsibility Principle to guide your design. Your classes do too much.
- I would be pretty impressed if you managed to implement a sane copy constructor for the System class! I don't know how I would do it, how do you copy the screen? I think that your copy constructor is probably incorrect, and that your class should be noncopyable. Don't forget to obey the rule of three.
- You have so many "initialisation" function.
- There are constructors, Init(), Setup(), load_file(), load_info()...
- I wouldn't know what order to call them in.
- I might forget to call one
- You shouldn't need to pass a Character's "frame number" into its own Draw() method. It has the frame number inside it, so it can manage it itself.
- I am suspicious of the order of precendence in the expression "error = menu() != 0". Use parentheses to clarify your intent, or split the expression into a statement and the conditional after.
- APP seems to contain two different sets of logic, one for the menu and one for the game. One solution to this is to create a class to represent the menu and the game, and have APP simply call whichever is "active".
Minor stylistic issues.
- APP conflicts with your established naming scheme. Consider "Application" or "Game" instead.
- APP.h lacks include guards, but you're using them in System.h. Aim for consistency, use them everywhere or nowhere. The portable thing is to use them everywhere.
- System::Setup takes a (non-const) character pointer. Consider using std::string to match the rest of your appļication.
- Consider passing std::string instances by reference.
- The for loop setup, condition and progress statements are unrelated in APP::main_loop. Consider using a while loop instead. Particularly odd is resetting the value every so often - it makes sense for what you want to do but it makes your loop look really unusual.
- Pass SDL_Events by value or const reference, not by non-const pointer.
- You use integers for error conditions, but this only makes sense if you have a known mapping from error conditions to solutions. There doesn't appear to be a consistent one in your application. One option is to make a big error enum, another is to use exceptions with meaningful types and error strings. Finally, you could just rely on the logs and return boolean values.
- I prefer to have only one place in my application where I convert to C's unusual "main returning 0 is success" rule. The rest of my application usually uses booleans or exceptions.