Part of it is macros, but the bigger part of it (besides the bootloaders that everyone plays with - but the bootloader isn't required) is the vast interface library, which the build process uses to hide a bunch of the complexity from the end user. It supplies a ton of functions and other useful bits to hide the complexity of manipulating the ports and such to do anything useful (you don't have to use the library, though - but it is always compiled in when you use the Arduino's IDE - you'd have to modify the Java source of the IDE to change this - a lot of us on the Arduino forums hopes this changes, and that advanced users will be able to bypass or alter this behavior). On top of this base, other users have built other interface libraries (which if the library become very popular, it will get incorporated into the "standard" library base in a later release of the IDE) which help for various tasks and such.
I honestly don't have a problem with simplifying coding; if that was really such an issue, we would've never moved past the ENIAC's plugboards (ok, that's severe and untrue - but the fact is, this is the normal and historical progression of computing - plugboards to direct machine code to assemblers to compilers to object orientation to ???).
We should be doing everything possible to make programming a simpler task for humans, not a more complex task. The Arduino is one of these kinds of projects, making programming and hardware development accessible and easier to understand for non-programmers and non-hardware people. I think the project has done a very admirable job of this...