GDCC: An Alternative ACS Compiler [0.15.0]

Any utility that assists in the creation of mods, assets, etc, go here. For example: Ultimate Doom Builder, Slade, WadSmoosh, Oblige, etc.
Forum rules
The Projects forums are ONLY for YOUR PROJECTS! If you are asking questions about a project, either find that project's thread, or start a thread in the General section instead.

Got a cool project idea but nothing else? Put it in the project ideas thread instead!

Projects for any Doom-based engine (especially 3DGE) are perfectly acceptable here too.

Please read the full rules for more details.
Post Reply
User avatar
DavidPH
Posts: 382
Joined: Fri Aug 28, 2009 1:46 pm

Re: GDCC: An Alternative ACS Compiler

Post by DavidPH »

Development continues, with gdcc-acc now being very close to a drop-in replacement for acc. It supports acc's single argument command line interface, its scope-free functions, implicit conversion between str and int, and other stuff. It still cannot call undeclared functions (requiring either function definitions to be reordered or to use forward declarations) and does not allow labels on declarations. Both of which are in the TODO file, though not necessarily for in the immediate future.

More importantly, I need to know if anyone is using the C front with Zandronum 2.x. In particular, libc. There is a major rewrite of the I/O portion of libc waiting for the official release of Zandronum 3.0 in order to remove the __GDCC__NoFuncPtr option. However, I have been told on IRC that there is probably no one using gdcc-cc with 2.x. So if that is not the case, now is the time to say something.
User avatar
Nash
 
 
Posts: 17439
Joined: Mon Oct 27, 2003 12:07 am
Location: Kuala Lumpur, Malaysia
Contact:

Re: GDCC: An Alternative ACS Compiler

Post by Nash »

GDCC-ACC is amazing, I am no longer using acc.exe for ALL of my projects, my entire weather system code has been rewritten to compile with GDCC-ACC and I've managed to cut down an estimated 500 lines of code because of it. Structs and enums are life.

This would have NEVER been possible with ACC:

Code: Select all

enum ELevelStates
{
    LEVELSTATE_ENTER,
    LEVELSTATE_PLAY,
    LEVELSTATE_EXIT,
}

struct FPlayer
{
    int strafe, strafemod;
    int sway, swaymod;
    bool isLightSourceOn;
    bool isSprinting;
    bool isAttacking;
    bool isCameraAnimationDisabled;
    int animState;
}

struct FWorld
{
    int TimeUpdateTics, TimeUpdateTicDelay, TimeUpdateInc;
    bool TimeInitialized;
    int TimeTotalSeconds, TimeTotalDays;

    // these two used to be world variables instead of global; why?
    int TimeInstanceCount, GameInstanceCount;

    int LastTotalDays;

    // Seconds in a day.
    int TimeHour, TimeMinute, TimeSecond;
    int TimeHourOld;

    // Number of days.
    int TimeYear,
        TimeMonth, // This is the number for human to read, starting at 1. For zero-based array operation, this number has to be subtracted by 1.
        TimeDay,
        TimeDayOfWeek;

    int MonthDay[12];

    str MonthName[12];
    str DayOfWeekName[7];
    str MonthNameShort[12];
    str DayOfWeekNameShort[7];

    int SkyRGB_Night;
    int SkyRGB_Sunrise;
    int SkyRGB_Day;
    int SkyRGB_Sunset;

    int SkyRGB_Mult;

    // since gdcc supports the fixed type, these should probably be converted eventually
    int SunAlphaCounter, SunAlphaCounterMax, SunAlpha, SunAngle;
    int MoonAlphaCounter, MoonAlphaCounterMax, MoonAlpha, MoonAngle;
    int StarAlphaCounter, StarAlphaCounterMax, StarAlpha;

    int MoonPhase;

    int Desaturation;

    int skydome_random_alpha_target, skydome_random_alpha;
    int stars_random_alpha_target, stars_random_alpha;

    int OutsideSectorStart, OutsideSectorEnd;

    int PuddleCounter;
    int PuddleCounterDelay;

    int Overcast;                            // overcast status, in hours
    int Overcast_LastHour;                    // last time it overcasted
    int Overcast_TransitionCounter;            // for smoothening transitions to and from overcasting

    int Raining, Raining_TransitionCounter;

    int Raining_DensityMult;                 // user settable rain density multiplier

    int Thunderstorm;                        // thunderstorm, in hours

    int Overcast_Chance;                    // chance for overcast
    int Raining_Chance;                        // chance to rain
    int Thunderstorm_Chance;                // chance for thunderstorm (must be raining or overcast first)

    int ThunderTics;
    int ThunderSkyColor;

    int Skylight_Mult;

    bool isDay, isNight;

    int Time1, Time2, Time3, Time4, Time5, Time6, Time7, Time8;
    
    int LevelState;
    
    // this map cannot be played
    // (for cutscenes and shit)
    bool IsLevelUnplayable;
}

#libdefine MAXACTORS 0x01000000 // 16,777,216

struct ZActor
{
    int baseID, refID;

    // holds refID of this actor's container
    int containerID;

    // NPC, zombie or player?
    int type;

    // only 1 copy of this actor allowed, ever. subsequent spawns will fail and print a warning
    bool isUnique;

    // protected = cannot be killed by anything except players
    // essential = cannot be killed, ever
    bool deathProtection;

    int sex;
    int ethnicity;

    // only for players
    int hairType, facialHairType,
        hairLength, facialHairLength;
    int faceType;
    int muscle, fat;

    // for NPC dialogues, can have up to 8 expressions
    str portraitPic[8];

    // which dialog set does this NPC have
    // (conversation ID)
    int dialogSet;

    // which schedule/AI script to follow
    // (for idle behavior or sleep/travel schedules.
    // can also be given by dialogs to perform scripted scenes)
    int AIpackage;

    // which user script to run when this actor dies
    str deathScript;

    // stats
        // attributes
    int level,
        health, maxHealth,
        stamina, maxStamina,
        hunger, maxHunger,
        thirst, maxThirst,
        energy, maxEnergy,
        strength,
        mind,
        agility,
        vitality,
        charisma,
        luck,
        // skills
        blade,
        blunt,
        bow,
        unarmed,
        guns,
        electrical,
        carpentry,
        cooking,
        farming,
        sneak,
        perception,
        hunting,
        medicine,
        athletics,
        persuasion;

    // head has been destroyed, this actor can no longer turn into a zombie or reanimate
    bool isReallyDead;

    // all zombies have this enabled
    bool isUndead;

    // limb damages are in percent
    int headHealth,
        torsoHealth,
        armLHealth,
        armRHealth,
        legLHealth,
        legRHealth;

    // a list of the refIDs of this actor's active effects ((de)buffs)
    int activeEffect[100];

    // currently equipped stuff
    // holds refIDs of items to be equipped
    int curWeapon,
        curLight,
        // clothes
        curGlasses,
        curUnderShirt,
        curShirt,
        curGloves,
        curUnderPants,
        curPants,
        curShoes,
        // armor
        curHelmet,
        curBodyArmor,
        curArmLAmor,
        curArmRArmor,
        curLegLArmor,
        curLegRArmor;
}

//===========================================================================
//
// GLOBAL VARIABLES
//
//===========================================================================

global FPlayer        1: player[MAXPLAYERS];
global FWorld        2: LADworld[1];
global ZActor        3: LADactor[MAXACTORS];

 
See that global value allocation at the end? I only used up 3. With acc.exe, I almost already hit the limit of 64, and I wasn't even able to create 10% of what I needed!

+1 endorsement from me!
User avatar
Nash
 
 
Posts: 17439
Joined: Mon Oct 27, 2003 12:07 am
Location: Kuala Lumpur, Malaysia
Contact:

Re: GDCC: An Alternative ACS Compiler

Post by Nash »

Dave -

I have a big library fully written for GDCC-ACC. I have this file, mablib.acs, which exposes functions for modders and mappers to use in their map scripts (like in GZDoom Builder's script editor)

Code: Select all

//===========================================================================
//
// maplib.acs
//
// Gives access to engine functions from map scripts
//
// Written by Nash Muhandes
//
//===========================================================================

#library "LADgame"

#include "zcommon.acs"
#include "LAD_spec.acs"
#include "LAD_defs.acs"

#import "../acs_src/zdata.acs"
#import "../acs_src/zmain.acs"
#import "../acs_src/video.acs"
#import "../acs_src/time.acs"
#import "../acs_src/weather.acs"
 
So, in GZDoom Builder, all the mapper has to do is have this script:

Image

to have access to my library's functions.

So the question is, is this even possible, and would it actually work correctly when compiled?

The point is, GZDB uses regular acc.exe. I would prefer it if I don't have to force mappers to use GDCC just to compile their maps from within the editor - I just want their workflow to remain unchanged - but have access to extra goodies by #including maplib.acs

The stuff in this post are mockups, I don't actually have enough time to personally test this myself, figured I'd get more precise answers if I asked you!
User avatar
Nash
 
 
Posts: 17439
Joined: Mon Oct 27, 2003 12:07 am
Location: Kuala Lumpur, Malaysia
Contact:

Re: GDCC: An Alternative ACS Compiler

Post by Nash »

Feature request:

Make it generate an error file if it can't find a #include (currently it doesn't)
User avatar
DavidPH
Posts: 382
Joined: Fri Aug 28, 2009 1:46 pm

Re: GDCC: An Alternative ACS Compiler

Post by DavidPH »

I would suggest importing dummy versions of those ACS files, where the functions are defined with empty bodies. That will give acc the information it needs, without exposing it to the GDCC extensions that it cannot process.

And I will see to fixing up the file not found error messages soon.
User avatar
DavidPH
Posts: 382
Joined: Fri Aug 28, 2009 1:46 pm

Re: GDCC: An Alternative ACS Compiler

Post by DavidPH »

File open failure will now get written by --error-file correctly. Additionally, I added a fallback for non-exception errors so that any program failure should at least generate some sort of error file.

In more general news, stdio-rewrite branch has been merged, bringing scanf and an experimental string streams API! String streams allow you to open strings for reading or writing as FILE streams. And scanf allows for easier reading structure plaintext data. (However, %[ and %p are not yet supported.) This merge also means the end of Zandronum 2.x support for the C front, although the ACS front remains compatible with older versions.
User avatar
Nash
 
 
Posts: 17439
Joined: Mon Oct 27, 2003 12:07 am
Location: Kuala Lumpur, Malaysia
Contact:

Re: GDCC: An Alternative ACS Compiler

Post by Nash »

Thank you!

Regarding file I/O; would it be possible for someone to write that stuff in C but somehow keep my project still in gdcc-acc and utilize the file IO? I've always wanted a custom data lump for defining data instead of grossly hacking the LANGUAGE lump...
User avatar
DavidPH
Posts: 382
Joined: Fri Aug 28, 2009 1:46 pm

Re: GDCC: An Alternative ACS Compiler

Post by DavidPH »

All of the current FILE stream types in GDCC's libc operate on in-memory data. It is not possible to actually read lumps without adding native extensions to ZDoom. Extensions which would likely benefit from not being designed around acc's limitations, but that's another discussion for another place.

More generally: It is possible to define functions in C which can be called from ACS, and to declare ACS-defined functions in C. There are some caveats, and it might be simpler to define scripts in C that are executed by the ACS, but both are available as options.

Code: Select all

[[extern("ACS"), call("LangACS")]]
void ThisFunctionCouldBeDefinedInACS(int a, int b);

[[extern("ACS"), call("LangACS")]]
int ThisFunctionCanBeCalledFromACS(void)
{
   return 42; // Most original return value, do not steal.
}
The biggest issue is that StkCall functions (which LangACS translates to) cannot directly call StdCall functions (which LangC translates to), and therefore require a ScriptI or ScriptS intermediary.
User avatar
Nash
 
 
Posts: 17439
Joined: Mon Oct 27, 2003 12:07 am
Location: Kuala Lumpur, Malaysia
Contact:

Re: GDCC: An Alternative ACS Compiler

Post by Nash »

DavidPH wrote:I would suggest importing dummy versions of those ACS files, where the functions are defined with empty bodies. That will give acc the information it needs, without exposing it to the GDCC extensions that it cannot process.
I tried this, and it doesn't work. As in, GZDoom Builder doesn't complain and it does compile the map's ACS, but in-game, it just doesn't do anything. Do you need me to provide you an example project?
User avatar
DavidPH
Posts: 382
Joined: Fri Aug 28, 2009 1:46 pm

Re: GDCC: An Alternative ACS Compiler

Post by DavidPH »

A minimal example demonstrating the problem would be very helpful, yes.
User avatar
Nash
 
 
Posts: 17439
Joined: Mon Oct 27, 2003 12:07 am
Location: Kuala Lumpur, Malaysia
Contact:

Re: GDCC: An Alternative ACS Compiler

Post by Nash »

User avatar
DavidPH
Posts: 382
Joined: Fri Aug 28, 2009 1:46 pm

Re: GDCC: An Alternative ACS Compiler

Post by DavidPH »

You need to either name your bytecode file maplib.o, or change maplib.acs to use #library "awesome". What is happening is that the #library directive is used to determine the lump name to import at load time, but it is not matched with the actual name of the bytecode file. This is what the "Could not find ACS library X." error message in ZDoom's log means.
User avatar
Nash
 
 
Posts: 17439
Joined: Mon Oct 27, 2003 12:07 am
Location: Kuala Lumpur, Malaysia
Contact:

Re: GDCC: An Alternative ACS Compiler

Post by Nash »

Argh... it works in the test file, but not in the actual project! I'm zipping up my entire project and sending to you!

EDIT: SOLVED! It turns out that maplib.acs cannot be built as part of the bumi.o along with the other source files. I had to remove maplib.acs into another folder. When bumi.o is built without maplib.acs, everything magically works!
User avatar
Nash
 
 
Posts: 17439
Joined: Mon Oct 27, 2003 12:07 am
Location: Kuala Lumpur, Malaysia
Contact:

Re: GDCC: An Alternative ACS Compiler

Post by Nash »

Now for a different question:

What about access to variables and #defines? Can I do duplicate #defines in the maplib.acs? And for variables, can I just declare them again in maplib.acs and somehow the map script will refer to the correct variable in the main library?
User avatar
DavidPH
Posts: 382
Joined: Fri Aug 28, 2009 1:46 pm

Re: GDCC: An Alternative ACS Compiler

Post by DavidPH »

Yes, #libdefine the macros and define the objects without initializers. And yes, you should at no point actually compile the dummy ACS file; just import it.
Post Reply

Return to “Creation, Conversion, and Editing”