News | Forum | People | FAQ | Links | Search | Register | Log in
Coding Help
This is a counterpart to the "Mapping Help" thread. If you need help with QuakeC coding, or questions about how to do some engine modification, this is the place for you! We've got a few coders here on the forum and hopefully someone knows the answer.
First | Previous | Next | Last
That Sounds Awesome 
but to answer your question, I don't know. probably! 
 
tbh I'd just special-case it.

netmen* are image lumps. serial, modem, ipx, tcp, etc options.
dim_* are greyed out versions of those.

the *8 size applies _only_ to transparent lumps, and only to their width. the height can always be any value it wants.
for non-transparent lumps, the width can be anything, even 1... at least in the software renderer. I imagine the gl renderer mandates a multiple-of-4 width, but not height.
I should probaly mention at this point that hexen2 has some &3 widths in its gfx.wad.
the two lmp groups that you name are not transparent, and thus can be any size they want, ish.

palette, colormap, conchars. these have special handling in the engine. the engine doesn't care about types.
other images in gfx.wad should never be mip textures, as that would be pointless.
any other wad with any other name should contain mip textures. any time that that's broken you can expect issues all round.

what I'm trying to say is that there isn't really any reason that the data must be of a specific format, unless the thing trying to read it requires it to be.
.wad dates back to doom, it really is just a collection of file lumps rather than some clever format with well-defined file types. 
Spike 
Thanks. I put a special case for conchars already, so I guess I'll do the same for lmp. Maybe there is some formula that would allow me to figure out the header type, but I'm not sure. I guess special case by name and size is probably safest :/ 
Wad Lump Types 
Than: it sounds like you already identified the special files for the most part, but I will clarify:
gfx.wad conchars.lmp - 128x128 raw image, color 0 is transparent (unlike other pics)

gfx.wad colormap.lmp - 256x64 image of nearest-match colors for light level shading (0-63, with 32 as neutral, 63 as 2x brightness), followed by a 32bit integer (which sometimes stored as a single byte instead), which is 32 in id1 and typically 32 in all mods (there might be some with 0), this number is how many palette entries are fullbright (256-n is the start of the n fullbright colors in other words).

gfx.wad palette.lmp - 256x3 array of RGB colors, not copyrighted (John Carmack explicitly stated that id do not care if you copy the palette, or even embed it in code).

Miptex wads also contain palette.lmp, but all other files in them are .mip.

All other files are consistently formatted, the transparent color in .lmp (and .spr for what it's worth) is 255, no other format supports transparent pixels.

Size restrictions:
.lmp - no real restrictions, but glquake has errors if the width is not a multiple of 4 (software quake has no such restriction), and software quake corrupts memory if an image exceeds the screen boundaries, so even centered 320x200 image is the practical limit.

.mip - glquake has errors if the width is not a multiple of 4, software quake requires the width and height to be a multiple of 16 (due to surfacecache having a hard-wired function for applying lightmaps to a 2x2, 4x4, 8x8, or 16x16 grouping of pixels).

If you wanted to solve a problem that has probably been vexing people for some years now, why not make a converter for combining two .tga 32bit color images (one .tga for albedo/diffuse, and one _glow.tga) into one .mip file (or .pcx for loading into .mdl and .spr editors) where the glow colors are mapped to fullbright range (according to colormap.lmp's value for how many fullbrights exist) and the regular .tga's colors map only into non-fullbright colors, it's always been a pet peeve of mine with the tools at hand, but as I was kind of rendering the quake formats obsolete over the years I never bothered.

Note that there are some special files outside the .wad as well that may not be obvious:

gfx/qpop.lmp - this is a 16x16 image (I think in Quake palette?) that is the quake logo, the general going theory on this is that the quake logo is trademarked and thus it would give them a way to sue people for distributing quake mods designed to be used with shareware quake (which lacks this file, and thus refuses to run mods).

end1.bin - shareware quake dos text to show on exit

end2.bin - registered quake dos text to show on exit 
/me Weeps 
I Have Two Stupid Questions 
1. I want to pass an entity field to a function. What's more efficient: to pass one field (say, a string) or an entity pointer? Assuming that other fields won't be needed in said function.

2. There are various styles of naming the functions in id1 QC: DerpDerp(), derp_derp(), even Derp_Derp(). Is that because various programmers didn't care about naming conventions, or is that meaningful in some way? 
Answers 
1. Pass the string, not the entity. All strings in QC are immutable and all you're doing is copying around the pointer, which is cheap. On the other hand if you send the entity, then you have to go through an extra two intructions each time you need to access the string, which is marginally more expensive.

2. There's no meaning, it's just that lots of id staff worked on the code and had different coding styles. There isn't even a good way to tidy the codebase back up into one convention: the fixed QC functions that the engine calls are all InitialCapital style like StartFrame and PutClientInServer, but unless you're going for a total conversion all the classnames are in lower_case_underscore format and you're stuck with those function name too!

So do whatever you're comfortable with in your own code, but I would recommend obeying the conventions on classnames - stick with lower_case_underscore for the names, starting with func_ for visible brush entities, trigger_ for invisible brush entities, and monster_, item_ OR info_ for point entities. 
 
1. If you pass the value, you can't write to it. The caller will need an extra intruction to pass the value, which is the same as if you read it once inside the function anyway.
If you pass the entity, you can change it to some other string, but reading will cost 1 more instruction (1 to read, 2 to write).

2. For engine->qc calls, I generally expect camelback function names combined with at least one underscore! which helps when the majority of functions are all lowercase. less possible conflicts.
spawn functions should probably be lower case, just because. however, there's at least one that isn't. oh well. 
 
Is QC performance ever a real concern these days to where an extra instruction here or there makes the difference between smooth and choppy gameplay? I don't know, I'm seriously asking. 
 
Thanks for the answers.

Willem, I doubt it. I just don't want to pick any bad habits if I can avoid it. Besides, I was curious. 
 
No. But very rarely yes.

A lot of code gets run once per frame or once every animation frame (typically 10 times a second). This kind of code can be messy without impacting performance on even a semi-modern machine.

The times where it can matter are when you are doing things in a loop during the same frame. For example, pathfinding, or searching for new enemy targets. 
 
dwere

Sure, I understand that. Tinkering with something like Quake is fun because you get to understand every nook and cranny after awhile. It's stable and unchanging and there's something comfortable about that. 
 
And something a little disheartening as a programmer. As you're figuring out more and more about how things work and what does what, you realize that Carmack came up with and wrote most of this from scratch 18+ years ago. Damn him... 
 
self.function = (void(float))funcWithFloatArg;

results in:
type mismatch for = (pointer and __variant)

What version of FTEQCC do I need to make that work? 
A New Version 
http://triptohell.info/moodles/fteqcc/ does all of that, as well as adding a bunch of warning for NOT doing it. 
 
Thanks! Shame that's buried on some hidden server. :( 
FTEQCC Documentation 
Is there any documentation for this?
All I could find was this: http://www.fteqw.com/wiki/index.php?title=FTEQCC_FAQ

For example, is it possible to have an array that is an entity member? 
Guess I Could Just Try It... 
seems to compile without errors. 
 
if it doesn't crash, then its a feature! 
Lordhavoc 
Thanks for all that info! Very useful to know.

I wonder how the guys behind the Quake specs figured it all out before the QuakeC source etc. was officially released by id. Must have taken a lot of trial and error. 
Spirit 
Spirit: Yeah, I was looking at the Quake Wiki the other day and thinking it looks a bit sad and needs some love. Perhaps we should get as much info from the Quake Specs about file formats as possible on the wiki, and finish off the level and monsters guide.

Part of the problem I had before is that there's just too much information per thing and it's annoying to have to basically write an entire article just about a level in a game that was released in 1996, even if that game happens to be one's favourite game. It might be worth looking at how the pages are formatted and thinking how to divide it up within the article so that more of the information is optional. 
Crosshair 0 
Okay.

I want to hide the crosshair during centerprints and other special events. This is easy.

I also want to remember the user's crosshair preference, because the only way to hide the crosshair is set the cvar to 0 .

It was easy when I was just assuming that the user's preference was "use the crosshair, always" because what kind of lunatic wouldn't? I forget who or where, but someone recently posted somewhere on func that they hate playing Quake with the crosshair on because it makes their aim worse or something. Fine, whatever, I'll try and support it.

If I save the value in a float in the progs somewhere, the crosshair doesn't come back if I restart the level or load a new map while it's hidden. If I save it in a safe cvar (like 'temp1' or setting a high bit in the value of 'registered'), the crosshair doesn't come back if I quit the game while it's hidden and restart later, because those cvars get reset.

Is there any other cvar I can use? Are the 'saved1-4' cvars safe to faff with? 
 
you should consider using a nosave var which will cause the progs to re-evaluate the state of the crosshair visibility after a map load. 
 
this isn't an answer, nor likely helpful.

...but is it worth going to all the trouble to fix that bug (crosshair setting doesn't return if user quits during a centerprint)? I understand the desire to fix it, but on the other hand... you're making a mod not a AAA title that needs to get certified. It doesn't seem like it would be that common an issue, nor one that most users couldn't fix themselves by turning the crosshair back on if it was off when they loaded a save. 
Pfffft 
I didn't need a crosshair when quake came out and I certainly don't need one after 17 years of playing the game.

The hitboxes for the enemies are bloody huge, it's not needed! 
First | Previous | Next | Last
You must be logged in to post in this thread.
Website copyright © 2002-2024 John Fitzgibbons. All posts are copyright their respective authors.