diff --git a/quakec/csaddon/src/csaddon.qc b/quakec/csaddon/src/csaddon.qc index d3226d212..9e9eb835b 100644 --- a/quakec/csaddon/src/csaddon.qc +++ b/quakec/csaddon/src/csaddon.qc @@ -7,9 +7,11 @@ enum MODE_INITIAL=0, MODE_LIGHTEDIT=1, - MODE_SPLINEEDIT=2 + MODE_SPLINEEDIT=2, + MODE_PARTICLEEDIT=3 }; +var vector vidsize = '640 480 0'; vector curmousepos; float mousedown; @@ -106,10 +108,20 @@ void() wrap_renderscene = col = '1 1 1'; drawrawstring('64 0 0'*(MODE_SPLINEEDIT-1), "SPLINES", '8 8 0', col, 1); + if (autocvar_ca_editormode == MODE_PARTICLEEDIT) + col = '1 0 0'; + else if (curmousepos_y < 8 && curmousepos_x >= 64*(MODE_PARTICLEEDIT-1) && curmousepos_x < 64*MODE_PARTICLEEDIT) + col = '0 0 1'; + else + col = '1 1 1'; + drawrawstring('64 0 0'*(MODE_PARTICLEEDIT-1), "PARTICLES", '8 8 0', col, 1); + if (autocvar_ca_editormode == MODE_LIGHTEDIT) editor_lights_overlay(curmousepos); else if (autocvar_ca_editormode == MODE_SPLINEEDIT) editor_spline_overlay(curmousepos); + else if (autocvar_ca_editormode == MODE_PARTICLEEDIT) + editor_particles_overlay(curmousepos); drawcharacter(curmousepos - '4 4', '+', '8 8', '1 1 1', 1); }; @@ -136,6 +148,11 @@ float (float event, float parama, float paramb) wrap_InputEvent = if (editor_spline_key(parama, paramb, curmousepos)) return TRUE; } + else if (autocvar_ca_editormode == MODE_PARTICLEEDIT) + { + if (editor_particles_key(parama, paramb, curmousepos)) + return TRUE; + } if (parama == 512) { mousedown = 1; @@ -162,10 +179,10 @@ float (float event, float parama, float paramb) wrap_InputEvent = curmousepos_x = 0; if (curmousepos_y < 0) curmousepos_y = 0; - if (curmousepos_x > 640) - curmousepos_x = 640; - if (curmousepos_y > 480) - curmousepos_y = 480; + if (curmousepos_x > vidsize_x) + curmousepos_x = vidsize_x; + if (curmousepos_y > vidsize_y) + curmousepos_y = vidsize_y; return TRUE; } else if (event == 3) @@ -188,6 +205,9 @@ float (float event, float parama, float paramb) wrap_InputEvent = /*this is a fallback function, in case the main progs does not have one*/ void(float width, float height, float do2d) CSQC_UpdateView = { + vidsize_x = width; + vidsize_y = height; + vidsize_z = 0; clearscene(); setproperty(VF_DRAWENGINESBAR, 1); setproperty(VF_DRAWCROSSHAIR, 1); diff --git a/quakec/csaddon/src/csaddon.src b/quakec/csaddon/src/csaddon.src index 1f8eeb3b5..46284b5aa 100644 --- a/quakec/csaddon/src/csaddon.src +++ b/quakec/csaddon/src/csaddon.src @@ -1,7 +1,10 @@ ../csaddon.dat //pr_dumpplatform -FFTE -Fdefines -TCS -O csplat +opts.qc csplat.qc editor_lights.qc +textfield.qc +editor_particles.qc cam.qc csaddon.qc diff --git a/quakec/csaddon/src/csplat.qc b/quakec/csaddon/src/csplat.qc new file mode 100644 index 000000000..ec655f52e --- /dev/null +++ b/quakec/csaddon/src/csplat.qc @@ -0,0 +1,679 @@ +/* +This file was automatically generated by FTE QuakeWorld v1.01 +This file can be regenerated by issuing the following command: +pr_dumpplatform -FFTE -Fdefines -TCS -O csplat +Available options: +-Ffte - target only FTE (optimations and additional extensions) +-Tnq - dump specifically NQ fields +-Tqw - dump specifically QW fields +-Tcs - dump specifically CSQC fields +-Fdefines - generate #defines instead of constants +-O - write to a different qc file +*/ +#pragma noref 1 +#pragma target FTE +#define CSQC +entity self; +entity other; +entity world; +float time; +float cltime; +float frametime; +float player_localentnum; +float player_localnum; +float maxclients; +float clientcommandframe; +float servercommandframe; +string mapname; +float intermission; +vector v_forward, v_up, v_right; +vector view_angles; +float trace_allsolid, trace_startsolid, trace_fraction; +vector trace_endpos, trace_plane_normal; +float trace_plane_dist; +entity trace_ent; +float trace_inopen; +float trace_inwater; +float input_timelength; +vector input_angles; +vector input_movevalues; +float input_buttons; +float input_impulse; +void end_sys_globals; +.float modelindex; +.vector absmin, absmax; +.float entnum; +.float drawmask; +.void() predraw; +.float movetype; +.float solid; +.vector origin; +.vector oldorigin; +.vector velocity; +.vector angles; +.vector avelocity; +.float pmove_flags; +.string classname; +.float renderflags; +.string model; +.float frame; +.float frame1time; +.float frame2; +.float frame2time; +.float lerpfrac; +.float skin; +.float effects; +.vector mins, maxs; +.vector size; +.void() touch; +.void() think; +.void() blocked; +.float nextthink; +.entity chain; +.entity enemy; +.float flags; +.float colormap; +.entity owner; +void end_sys_fields; +.vector punchangle; +.float gravity; +.float hull; +.entity movechain; +.void() chainmoved; +.float dimension_solid; +.float dimension_hit; +.float scale; +.float fatness; +.float alpha; +.entity tag_entity; +.float skeletonindex; +.vector colormod; +.float friction; +.float erp; +.float jointtype; +.float mass; +.float bouncefactor; +.float bouncestop; +.float forceshader; +.float baseframe; +.float baseframe2; +.float baseframe1time; +.float baseframe2time; +.float baselerpfrac; +.float basebone; +.float bonecontrol1; +.float bonecontrol2; +.float bonecontrol3; +.float bonecontrol4; +.float bonecontrol5; +.float subblendfrac; +.float basesubblendfrac; +.vector glowmod; +.float ideal_pitch; +.float pitch_speed; +var float physics_mode = 2; +#define TRUE 1 +#define FALSE 0 +#define MOVETYPE_NONE 0 +#define MOVETYPE_WALK 3 +#define MOVETYPE_STEP 4 +#define MOVETYPE_FLY 5 +#define MOVETYPE_TOSS 6 +#define MOVETYPE_PUSH 7 +#define MOVETYPE_NOCLIP 8 +#define MOVETYPE_FLYMISSILE 9 +#define MOVETYPE_BOUNCE 10 +#define MOVETYPE_BOUNCEMISSILE 11 +#define MOVETYPE_FOLLOW 12 +#define MOVETYPE_PHYSICS 32 +#define SOLID_NOT 0 +#define SOLID_TRIGGER 1 +#define SOLID_BBOX 2 +#define SOLID_SLIDEBOX 3 +#define SOLID_BSP 4 +#define SOLID_CORPSE 5 +#define SOLID_LADDER 20 +#define SOLID_PHYSICS_BOX 32 +#define SOLID_PHYSICS_SPHERE 33 +#define SOLID_PHYSICS_CAPSULE 34 +#define JOINTTYPE_FIXED -1 +#define JOINTTYPE_POINT 1 +#define JOINTTYPE_HINGE 2 +#define JOINTTYPE_SLIDER 3 +#define JOINTTYPE_UNIVERSAL 4 +#define JOINTTYPE_HINGE2 5 +#define CONTENT_EMPTY -1 +#define CONTENT_SOLID -2 +#define CONTENT_WATER -3 +#define CONTENT_SLIME -4 +#define CONTENT_LAVA -5 +#define CONTENT_SKY -6 +#define CHAN_AUTO 0 +#define CHAN_WEAPON 1 +#define CHAN_VOICE 2 +#define CHAN_ITEM 3 +#define CHAN_BODY 4 +#define ATTN_NONE 0 +#define ATTN_NORM 1 +#define FL_FLY 1 +#define FL_SWIM 2 +#define FL_CLIENT 8 +#define FL_INWATER 16 +#define FL_MONSTER 32 +#define FL_ITEM 256 +#define FL_ONGROUND 512 +#define FL_PARTIALGROUND 1024 +#define FL_WATERJUMP 2048 +#define FL_FINDABLE_NONSOLID 16384 +#define MOVE_NORMAL 0 +#define MOVE_NOMONSTERS 1 +#define MOVE_MISSILE 2 +#define MOVE_HITMODEL 4 +#define MOVE_TRIGGERS 16 +#define MOVE_EVERYTHING 32 +#define MOVE_ENTCHAIN 128 +#define EF_BRIGHTFIELD 1 +#define EF_MUZZLEFLASH 2 +#define EF_BRIGHTLIGHT 4 +#define EF_DIMLIGHT 8 +#define EF_ADDITIVE 32 +#define EF_BLUE 64 +#define EF_RED 128 +#define EF_FULLBRIGHT 512 +#define EF_NODEPTHTEST 8192 +#define STAT_HEALTH 0 +#define STAT_WEAPON 2 +#define STAT_AMMO 3 +#define STAT_ARMOR 4 +#define STAT_WEAPONFRAME 5 +#define STAT_SHELLS 6 +#define STAT_NAILS 7 +#define STAT_ROCKETS 8 +#define STAT_CELLS 9 +#define STAT_ACTIVEWEAPON 10 +#define STAT_TOTALSECRETS 11 +#define STAT_TOTALMONSTERS 12 +#define STAT_SECRETS 13 +#define STAT_MONSTERS 14 +#define STAT_ITEMS 15 +#define STAT_VIEWHEIGHT 16 +#define STAT_VIEW2 20 +#define STAT_VIEWZOOM 21 +#define VF_MIN 1 +#define VF_MIN_X 2 +#define VF_MIN_Y 3 +#define VF_SIZE 4 +#define VF_SIZE_X 5 +#define VF_SIZE_Y 6 +#define VF_VIEWPORT 7 +#define VF_FOV 8 +#define VF_FOVX 9 +#define VF_ORIGIN 11 +#define VF_ORIGIN_X 12 +#define VF_ORIGIN_Y 13 +#define VF_ORIGIN_Z 14 +#define VF_ANGLES 15 +#define VF_ANGLES_X 16 +#define VF_ANGLES_Y 17 +#define VF_ANGLES_Z 18 +#define VF_DRAWWORLD 19 +#define VF_DRAWENGINESBAR 20 +#define VF_DRAWCROSSHAIR 21 +#define VF_CL_VIEWANGLES 33 +#define VF_CL_VIEWANGLES_X 34 +#define VF_CL_VIEWANGLES_Y 35 +#define VF_CL_VIEWANGLES_Z 36 +#define VF_PERSPECTIVE 200 +#define VF_LPLAYER 202 +#define VF_AFOV 203 +#define RF_VIEWMODEL 1 +#define RF_EXTERNALMODEL 2 +#define RF_DEPTHHACK 4 +#define RF_ADDITIVE 8 +#define RF_USEAXIS 16 +#define RF_NOSHADOW 32 +#define RF_FRAMETIMESARESTARTTIMES 64 +#define RF_NOAUTOADD 128 +#define FILE_READ 0 +#define FILE_APPEND 1 +#define FILE_WRITE 2 +#define FILE_READNL 4 +#define FILE_MMAP_READ 5 +#define FILE_MMAP_RW 6 +#define MOVE_LAGGED 64 +#define MASK_ENGINE 1 +#define MASK_VIEWMODEL 2 +#define LFIELD_ORIGIN 0 +#define LFIELD_COLOUR 1 +#define LFIELD_RADIUS 2 +#define LFIELD_FLAGS 3 +#define LFIELD_STYLE 4 +#define LFIELD_ANGLES 5 +#define LFIELD_FOV 6 +#define LFIELD_CORONA 7 +#define LFIELD_CORONASCALE 8 +#define LFIELD_CUBEMAPNAME 9 +#define LFIELD_AMBIENTSCALE 10 +#define LFIELD_DIFFUSESCALE 11 +#define LFIELD_SPECULARSCALE 12 +#define LFLAG_NORMALMODE 1 +#define LFLAG_REALTIMEMODE 2 +#define LFLAG_LIGHTMAP 4 +#define LFLAG_FLASHBLEND 8 +#define LFLAG_NOSHADOWS 256 +#define LFLAG_SHADOWMAP 512 +#define LFLAG_CREPUSCULAR 1024 +void(vector) makevectors = #1; +void(entity e, vector o) setorigin = #2; +void(entity e, string m) setmodel = #3; +void(entity e, vector min, vector max) setsize = #4; +#ifdef SSQC +void(float style, float val) lightstylestatic = #5; +void() break = #6; +#endif +float() random = #7; +void(entity e, float chan, string samp, float vol, float atten, optional float speedpct, optional float flags) sound = #8; +vector(vector v) normalize = #9; +void(string e) error = #10; +void(string e) objerror = #11; +float(vector v) vlen = #12; +float(vector v) vectoyaw = #13; +entity() spawn = #14; +void(entity e) remove = #15; +void(vector v1, vector v2, float nomonsters, entity ent) traceline = #16; +#ifdef SSQC +entity() checkclient = #17; +#endif +entity(entity start, .string fld, string match) find = #18; +void(string s) precache_sound = #19; +void(string s) precache_model = #20; +#ifdef SSQC +void(entity client, string s) stuffcmd = #21; +#endif +entity(vector org, float rad) findradius = #22; +#ifdef SSQC +void(string s) bprint = #23; +void(entity client, string s) sprint = #24; +#endif +void(string s, ...) dprint = #25; +string(float val) ftos = #26; +string(vector val) vtos = #27; +void() coredump = #28; +void() traceon = #29; +void() traceoff = #30; +void(entity e) eprint = #31; +float(float yaw, float dist) walkmove = #32; +float() droptofloor = #34; +void(float lightstyle, string stylestring) lightstyle = #35; +float(float) rint = #36; +float(float) floor = #37; +float(float) ceil = #38; +//float(vector v) qtest_canreach = #39; +float(entity ent) checkbottom = #40; +float(vector pos) pointcontents = #41; +float(float) fabs = #43; +#ifdef SSQC +vector(entity player, float missilespeed) aim = #44; +#endif +float(string) cvar = #45; +void(string, ...) localcmd = #46; +entity(entity) nextent = #47; +void(vector pos, vector dir, float colour, float count) particle = #48; +#define ChangeYaw changeyaw +void() changeyaw = #49; +vector(vector fwd, optional vector up) vectoangles = #51; +#ifdef SSQC +void(float to, float val) WriteByte = #52; +void(float to, float val) WriteChar = #53; +void(float to, float val) WriteShort = #54; +void(float to, float val) WriteLong = #55; +void(float to, float val) WriteCoord = #56; +void(float to, float val) WriteAngle = #57; +void(float to, string val) WriteString = #58; +void(float to, entity val) WriteEntity = #59; +#endif +float(float angle) sin = #60; +float(float angle) cos = #61; +float(float value) sqrt = #62; +void(entity ent) changepitch = #63; +void(entity ent, entity ignore) tracetoss = #64; +string(entity ent) etos = #65; +void(float step) movetogoal = #67; +#ifdef SSQC +void(string s) precache_file = #68; +#endif +void(entity e) makestatic = #69; +#ifdef SSQC +void(string mapname) changelevel = #70; +#endif +void(string cvarname, string valuetoset) cvar_set = #72; +#ifdef SSQC +void(entity ent, string text, ...) centerprint = #73; +#endif +void (vector pos, string samp, float vol, float atten) ambientsound = #74; +void(string str) precache_model2 = #75; +void(string str) precache_sound2 = #76; +#ifdef SSQC +void(string str) precache_file2 = #77; +void() setspawnparms = #78; +void(entity killer, entity killee) logfrag = #79; +string(entity e, string key) infokey = #80; +#endif +float(string) stof = #81; +#ifdef SSQC +void(vector where, float set) multicast = #82; +#endif +void(vector start, vector mins, vector maxs, vector end, float nomonsters, entity ent) tracebox = #90; +vector() randomvec = #91; +vector(vector org) getlight = #92; +void(string cvarname, string defaultvalue) registercvar = #93; +float(float a, float b, ...) min = #94; +float(float a, float b, ...) max = #95; +float(float minimum, float val, float maximum) bound = #96; +float(float value, float exp) pow = #97; +entity(entity start, .float fld, float match) findfloat = #98; +float(string extname) checkextension = #99; +#ifdef SSQC +float(string builtinname) builtin_find = #100; +float(float value) anglemod = #102; +void(string slot, string picname, float x, float y, float zone, optional entity player) showpic = #104; +void(string slot, optional entity player) hidepic = #105; +void(string slot, float x, float y, float zone, optional entity player) movepic = #106; +void(string slot, string picname, optional entity player) changepic = #107; +#endif +float(string filename, float mode, optional float mmapminsize) fopen = #110; +void(float fhandle) fclose = #111; +string(float fhandle) fgets = #112; +void(float fhandle, string s) fputs = #113; +float(string s) strlen = #114; +string(string s1, optional string s2, ...) strcat = #115; +string(string s, float start, float length) substring = #116; +vector(string s) stov = #117; +string(string s) strzone = #118; +void(string s) strunzone = #119; +#ifdef SSQC +void(string cvar, float val) cvar_setf = #176; +#endif +float(string modelname, optional float queryonly) getmodelindex = #200; +__variant(float prnum, string funcname, ...) externcall = #201; +float(string progsname) addprogs = #202; +__variant(float prnum, string varname) externvalue = #203; +void(float prnum, __variant newval, string varname) externset = #204; +float(string input, string token) instr = #206; +void(float portal, float state) openportal = #207; +#ifdef SSQC +float(float attributes, string effectname, ...) RegisterTempEnt = #208; +void(float type, vector pos, ...) CustomTempEnt = #209; +float(optional float sleeptime) fork = #210; +#endif +void(optional __variant ret) abort = #211; +#ifdef SSQC +void(float sleeptime) sleep = #212; +void(entity player, string key, string value) forceinfokey = #213; +void(string filename, float starttag, entity edict) chat = #214; +#endif +void(vector org, vector dmin, vector dmax, float colour, float effect, float count) particle2 = #215; +void(vector org, vector box, float colour, float effect, float count) particle3 = #216; +void(vector org, float radius, float colour, float effect, float count) particle4 = #217; +float(float number, float quantity) bitshift = #218; +void(vector pos) te_lightningblood = #219; +float(string s1, string sub, optional float startidx) strstrofs = #221; +float(string str, float index) str2chr = #222; +string(float chr, ...) chr2str = #223; +string(float ccase, float redalpha, float redchars, string str, ...) strconv = #224; +string(float pad, string str1, ...) strpad = #225; +string(string old, string key, string value) infoadd = #226; +string(string info, string key) infoget = #227; +float(string s1, string s2, float len) strncmp = #228; +float(string s1, string s2) strcasecmp = #229; +float(string s1, string s2, float len) strncasecmp = #230; +void() calltimeofday = #231; +#ifdef SSQC +void(float num, float type, .void fld) clientstat = #232; +void(float num, float type, string name) globalstat = #233; +void(entity player) isbackbuffered = #234; +#endif +void(vector angle) rotatevectorsbyangle = #235; +void(vector fwd, vector right, vector up) rotatevectorsbyvectors = #236; +float(float mdlindex, string skinname) skinforname = #237; +#ifdef CSQC +float(string shadername, optional string defaultshader, ...) shaderforname = #238; +#endif +void(vector org, optional float count) te_bloodqw = #239; +#ifdef SSQC +float(vector viewpos, entity entity) checkpvs = #240; +entity(string match, optional float matchnum) matchclientname = #241; +void(string dest, string content) sendpacket = #242; +#endif +#ifdef CSQC +vector(entity ent, float tagnum) rotatevectorsbytag = #244; +#endif +int(string) stoi = #259; +string(int) itos = #260; +int(string) stoh = #261; +string(int) htos = #262; +float(float modlindex, optional float useabstransforms) skel_create = #263; +float(float skel, entity ent, float modelindex, float retainfrac, float firstbone, float lastbone, optional float addfrac) skel_build = #264; +float(float skel) skel_get_numbones = #265; +string(float skel, float bonenum) skel_get_bonename = #266; +float(float skel, float bonenum) skel_get_boneparent = #267; +float(float skel, string tagname) skel_find_bone = #268; +vector(float skel, float bonenum) skel_get_bonerel = #269; +vector(float skel, float bonenum) skel_get_boneabs = #270; +void(float skel, float bonenum, vector org, optional vector fwd, optional vector right, optional vector up) skel_set_bone = #271; +void(float skel, float bonenum, vector org, optional vector fwd, optional vector right, optional vector up) skel_mul_bone = #272; +void(float skel, float startbone, float endbone, vector org, optional vector fwd, optional vector right, optional vector up) skel_mul_bones = #273; +void(float skeldst, float skelsrc, float startbone, float entbone) skel_copybones = #274; +void(float skel) skel_delete = #275; +void(float modidx, string framename) frameforname = #276; +float(float modidx, float framenum) frameduration = #277; +void(float action, vector pos, float radius, float quant) terrain_edit = #278; +void() touchtriggers = #279; +#ifdef SSQC +void(float buf, float fl) writefloat = #280; +#endif +float*(float skel) skel_mmap = #282; +void(entity ent, float bonenum, vector org, optional vector angorfwd, optional vector right, optional vector up) skel_set_bone_world = #283; +#ifdef CSQC +void() clearscene = #300; +void(float mask) addentities = #301; +void(entity ent) addentity = #302; +#define setviewprop setproperty +float(float property, ...) setproperty = #303; +void() renderscene = #304; +float(vector org, float radius, vector lightcolours) dynamiclight_add = #305; +void(string texturename) R_BeginPolygon = #306; +void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex = #307; +void() R_EndPolygon = #308; +#define getviewprop getproperty +__variant(float property) getproperty = #309; +vector (vector v) unproject = #310; +vector (vector v) project = #311; +void(float width, vector pos1, vector pos2) drawline = #315; +float(string name) iscachedpic = #316; +string(string name, float trywad) precache_pic = #317; +vector(string picname) draw_getimagesize = #318; +void(string name) freepic = #319; +float(vector position, float character, vector scale, vector rgb, float alpha, optional float flag) drawcharacter = #320; +float(vector position, string text, vector scale, vector rgb, float alpha, optional float flag) drawrawstring = #321; +float(vector position, string pic, vector size, vector rgb, float alpha, optional float flag) drawpic = #322; +float(vector position, vector size, vector rgb, float alpha, optional float flag) drawfill = #323; +void(float x, float y, float width, float height) drawsetcliparea = #324; +void(void) drawresetcliparea = #325; +float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring = #326; +float(string text, float usecolours, optional vector fontsize) stringwidth = #327; +void(vector pos, vector sz, string pic, vector srcpos, vector srcsz, vector rgb, float alpha, float flag) drawsubpic = #328; +float(float stnum) getstati = #330; +#define getstatf getstatbits +float(float stnum, optional float firstbit, optional float bitcount) getstatbits = #331; +string(float firststnum) getstats = #332; +void(entity e, float mdlindex) setmodelindex = #333; +string(float mdlindex) modelnameforindex = #334; +#endif +float(string effectname) particleeffectnum = #335; +void(float effectnum, entity ent, vector start, vector end) trailparticles = #336; +void(float effectnum, vector origin, optional vector dir, optional float count) pointparticles = #337; +#ifdef CSQC +void(string s, ...) cprint = #338; +#endif +void(string s, ...) print = #339; +#ifdef CSQC +string(float keynum) keynumtostring = #340; +float(string keyname) stringtokeynum = #341; +string(float keynum) getkeybind = #342; +vector() getmousepos = #344; +float(float framenum) getinputstate = #345; +void(float sens) setsensitivityscaler = #346; +#endif +void(entity ent) runstandardplayerphysics = #347; +#ifdef CSQC +string(float playernum, string keyname) getplayerkeyvalue = #348; +float() isdemo = #349; +float() isserver = #350; +void(vector origin, vector forward, vector right, vector up) SetListener = #351; +void(string cmdname) registercommand = #352; +#endif +float(entity ent) wasfreed = #353; +#ifdef CSQC +string(string key) serverkey = #354; +string() getentitytoken = #355; +void(string evname, string evargs, ...) sendevent = #359; +float() readbyte = #360; +float() readchar = #361; +float() readshort = #362; +float() readlong = #363; +float() readcoord = #364; +float() readangle = #365; +string() readstring = #366; +float() readfloat = #367; +float() readentitynum = #368; +float(string modelname, float(float isnew) updatecallback, float flags) deltalisten = #371; +__variant(float lno, float fld) dynamiclight_get = #372; +void(float lno, float fld, __variant value) dynamiclight_set = #373; +string(float efnum, float body) particleeffectquery = #374; +#endif +void(entity from, entity to) copyentity = #400; +#ifdef SSQC +void(entity from, entity to) setcolors = #401; +#endif +entity(string field, string match) findchain = #402; +entity(float fld, float match) findchainfloat = #403; +void(vector org, string modelname, float startframe, float endframe, float framerate) effect = #404; +void(vector org, vector dir, float count) te_blood = #405; +void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower = #406; +void(vector org, vector color) te_explosionrgb = #407; +void(vector mincorner, vector maxcorner, vector vel, float howmany, float color, float gravityflag, float randomveljitter) te_particlecube = #408; +void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain = #409; +void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow = #410; +void(vector org, vector vel, float howmany) te_spark = #411; +void(vector org) te_gunshotquad = #412; +void(vector org) te_spikequad = #413; +void(vector org) te_superspikequad = #414; +void(vector org) te_explosionquad = #415; +void(vector org) te_smallflash = #416; +void(vector org, float radius, float lifetime, vector color) te_customflash = #417; +void(vector org) te_gunshot = #418; +void(vector org) te_spike = #419; +void(vector org) te_superspike = #420; +void(vector org) te_explosion = #421; +void(vector org) te_tarexplosion = #422; +void(vector org) te_wizspike = #423; +void(vector org) te_knightspike = #424; +void(vector org) te_lavasplash = #425; +void(vector org) te_teleport = #426; +void(vector org, float color, float colorlength) te_explosion2 = #427; +void(entity own, vector start, vector end) te_lightning1 = #428; +void(entity own, vector start, vector end) te_lightning2 = #429; +void(entity own, vector start, vector end) te_lightning3 = #430; +void(entity own, vector start, vector end) te_beam = #431; +void(vector dir) vectorvectors = #432; +void(vector org) te_plasmaburn = #433; +float(entity e, float s) getsurfacenumpoints = #434; +vector(entity e, float s, float n) getsurfacepoint = #435; +vector(entity e, float s) getsurfacenormal = #436; +string(entity e, float s) getsurfacetexture = #437; +float(entity e, vector p) getsurfacenearpoint = #438; +#ifdef SSQC +void(entity e, string s) clientcommand = #440; +#endif +float(string s) tokenize = #441; +string(float n) argv = #442; +#ifdef SSQC +void(entity e, entity tagentity, string tagname) setattachment = #443; +#endif +float(string pattern, float caseinsensitive, float quiet) search_begin = #444; +void(float handle) search_end = #445; +float(float handle) search_getsize = #446; +string(float handle, float num) search_getfilename = #447; +string(string cvarname) cvar_string = #448; +entity(entity start, .entity fld, float match) findflags = #449; +entity(.float fld, float match) findchainflags = #450; +float(entity ent, string tagname) gettagindex = #451; +vector(entity ent, float tagindex) gettaginfo = #452; +#ifdef SSQC +void(entity player) dropclient = #453; +entity() spawnclient = #454; +float(entity client) clienttype = #455; +void(float target, string str) WriteUnterminatedString = #456; +#endif +entity(float entnum) edict_num = #459; +float() buf_create = #460; +void(float bufhandle) buf_del = #461; +float(float bufhandle) buf_getsize = #462; +void(float bufhandle_from, float bufhandle_to) buf_copy = #463; +void(float bufhandle, float sortpower, float backward) buf_sort = #464; +string(float bufhandle, string glue) buf_implode = #465; +string(float bufhandle, float string_index) bufstr_get = #466; +void(float bufhandle, float string_index, string str) bufstr_set = #467; +float(float bufhandle, string str, float order) bufstr_add = #468; +void(float bufhandle, float string_index) bufstr_free = #469; +float(float s) asin = #471; +float(float c) acos = #472; +float(float t) atan = #473; +float(float c, float s) atan2 = #474; +float(float a) tan = #475; +float(string s) strlennocol = #476; +string(string s) strdecolorize = #477; +string(float uselocaltime, string format, ...) strftime = #478; +float(string s, string separator1, ...) tokenizebyseparator = #479; +string(string s) strtolower = #480; +string(string s) strtoupper = #481; +string(string s) cvar_defstring = #482; +#ifdef CSQC +void(vector origin, string sample, float volume, float attenuation) pointsound = #483; +#endif +string(string search, string replace, string subject) strreplace = #484; +string(string search, string replace, string subject) strireplace = #485; +//vector(entity e, float s, float n, float a) getsurfacepointattribute = #486; +#ifdef CSQC +float(string name) gecko_create = #487; +void(string name) gecko_destroy = #488; +void(string name, string URI) gecko_navigate = #489; +float(string name, float key, float eventtype) gecko_keyevent = #490; +void(string name, float x, float y) gecko_mousemove = #491; +void(string name, float w, float h) gecko_resize = #492; +vector(string name) gecko_get_texture_extent = #493; +#endif +float(float caseinsensitive, string s, ...) crc16 = #494; +float(string name) cvar_type = #495; +//float() numentityfields = #496; +//string(float fieldnum) entityfieldname = #497; +//float(float fieldnum) entityfieldtype = #498; +//string(float fieldnum, entity ent) getentityfieldstring = #499; +//float(float fieldnum, entity ent, string s) putentityfieldstring = #500; +//void(float to, string s, float sz) WritePicture = #501; +string(string filename) whichpack = #503; +string(string in) uri_escape = #510; +string(string in) uri_unescape = #511; +float(entity ent) num_for_edict = #512; +void(string str) tokenize_console = #514; +float(float idx) argv_start_index = #515; +float(float idx) argv_end_index = #516; +string(string cvarname) cvar_description = #518; +#ifdef CSQC +float(optional float timetype) gettime = #519; +#endif +#ifdef SSQC +float(string mname) precache_vwep_model = #532; +#endif +#pragma noref 0 diff --git a/quakec/csaddon/src/editor_lights.qc b/quakec/csaddon/src/editor_lights.qc index 10acc713f..09f2d9c54 100644 --- a/quakec/csaddon/src/editor_lights.qc +++ b/quakec/csaddon/src/editor_lights.qc @@ -18,15 +18,15 @@ void() editor_lights_add = setmodel(tempent, autocvar_cg_editor_lightmodel); while(l > 0) { - l = l-1; + l = l-1.0; if (l == selectedlight) { - if (gettime(0)*5 & 1) + if (gettime(0)*5f & 1) continue; - tempent.effects |= 8192; + tempent.effects |= 8192f; } else - tempent.effects &~= 8192; + tempent.effects &~= 8192f; if (!(float)dynamiclight_get(l, LFIELD_RADIUS)) continue; setorigin(tempent, dynamiclight_get(l, LFIELD_ORIGIN)); @@ -34,28 +34,31 @@ void() editor_lights_add = } }; -#define NUMLFIELDS 11 +#define NUMLFIELDS 14 static string fldname[NUMLFIELDS+1] = { "bad", - "num", - "org", - "rgb", - "rad", - "flg", - "sty", - "ang", - "fov", - "cmp", - "cor", - "csc" + " num", + " org", + " rgb", + " rad", + " flg", + " sty", + " ang", + " fov", + " cmp", + " cor", + " csc", + " amb", + " dif", + " spc" }; -static string(float fld, float foredit) readfield = +static string(int fld, float foredit) readfield = { switch(fld) { case 1: if (foredit) return ftos(selectedlight); - return strcat(ftos(selectedlight), " / ", ftos(dynamiclight_get(-1, -1))); + return strcat(ftos(selectedlight), " / ", ftos(dynamiclight_get(-1f, -1f))); case 2: return vtos(dynamiclight_get(selectedlight, LFIELD_ORIGIN)); case 3: @@ -85,6 +88,12 @@ static string(float fld, float foredit) readfield = return ftos(dynamiclight_get(selectedlight, LFIELD_CORONA)); case 11: return ftos(dynamiclight_get(selectedlight, LFIELD_CORONASCALE)); + case 12: + return ftos(dynamiclight_get(selectedlight, LFIELD_AMBIENTSCALE)); + case 13: + return ftos(dynamiclight_get(selectedlight, LFIELD_DIFFUSESCALE)); + case 14: + return ftos(dynamiclight_get(selectedlight, LFIELD_SPECULARSCALE)); default: return ""; } @@ -115,7 +124,7 @@ static void(float fld, string newval) writefield = if (strstrofs(newval, "c")>=0) fl |= LFLAG_NOSHADOWS; if (strstrofs(newval, "s")>=0) fl |= LFLAG_SHADOWMAP; if (strstrofs(newval, "r")>=0) fl |= LFLAG_CREPUSCULAR; - dynamiclight_set(selectedlight, LFIELD_FLAGS, fl); + dynamiclight_set(selectedlight, LFIELD_FLAGS, (float)fl); return; case 6: dynamiclight_set(selectedlight, LFIELD_STYLE, stof(newval)); @@ -135,6 +144,15 @@ static void(float fld, string newval) writefield = case 11: dynamiclight_set(selectedlight, LFIELD_CORONASCALE, stof(newval)); return; + case 12: + dynamiclight_set(selectedlight, LFIELD_AMBIENTSCALE, stof(newval)); + return; + case 13: + dynamiclight_set(selectedlight, LFIELD_DIFFUSESCALE, stof(newval)); + return; + case 14: + dynamiclight_set(selectedlight, LFIELD_SPECULARSCALE, stof(newval)); + return; default: return; } @@ -142,13 +160,13 @@ static void(float fld, string newval) writefield = void(vector m) editor_lights_overlay = { - float i; + int i; string s; vector col; - m_y = floor((m_y - 32) / 8); + m_y = floor((m_y - 32f) / 8f); - for (i = 1; i <= NUMLFIELDS; i++) + for (i = 1f; i <= NUMLFIELDS; i++) { if (editfield == i) s = editvalue; @@ -163,30 +181,30 @@ void(vector m) editor_lights_overlay = else col = '1 1 1'; - drawrawstring('0 32 0' + '0 8 0' * i, s, '8 8 0', col, 1); + drawrawstring('0 32 0' + '0 8 0' * (float)i, s, '8 8 0', col, 1); } i+=1; if (editfield == 5) { - drawrawstring('0 32 0' + '0 8 0' * i, "d: dynamic mode\n", '8 8 0', '1 1 1', 1); i+=1; - drawrawstring('0 32 0' + '0 8 0' * i, "w: realtime world lights mode\n", '8 8 0', '1 1 1', 1); i+=1; - drawrawstring('0 32 0' + '0 8 0' * i, "l: lightmap hack (not valid above index 32)\n", '8 8 0', '1 1 1', 1); i+=1; - drawrawstring('0 32 0' + '0 8 0' * i, "f: flashblend coronas\n", '8 8 0', '1 1 1', 1); i+=1; - drawrawstring('0 32 0' + '0 8 0' * i, "c: does not cast shadows\n", '8 8 0', '1 1 1', 1); i+=1; - drawrawstring('0 32 0' + '0 8 0' * i, "s: shadowmapped light\n", '8 8 0', '1 1 1', 1); i+=1; - drawrawstring('0 32 0' + '0 8 0' * i, "r: crepuscular rays\n", '8 8 0', '1 1 1', 1); i+=1; + drawrawstring('0 32 0' + '0 8 0' * (float)i, "d: dynamic mode\n", '8 8 0', '1 1 1', 1); i+=1; + drawrawstring('0 32 0' + '0 8 0' * (float)i, "w: realtime world lights mode\n", '8 8 0', '1 1 1', 1); i+=1; + drawrawstring('0 32 0' + '0 8 0' * (float)i, "l: lightmap hack (not valid above index 32)\n", '8 8 0', '1 1 1', 1); i+=1; + drawrawstring('0 32 0' + '0 8 0' * (float)i, "f: flashblend coronas\n", '8 8 0', '1 1 1', 1); i+=1; + drawrawstring('0 32 0' + '0 8 0' * (float)i, "c: does not cast shadows\n", '8 8 0', '1 1 1', 1); i+=1; + drawrawstring('0 32 0' + '0 8 0' * (float)i, "s: shadowmapped light\n", '8 8 0', '1 1 1', 1); i+=1; + drawrawstring('0 32 0' + '0 8 0' * (float)i, "r: crepuscular rays\n", '8 8 0', '1 1 1', 1); i+=1; } else { - drawrawstring('0 32 0' + '0 8 0' * i, "+/- change selected light\n", '8 8 0', '1 1 1', 1); i+=1; - drawrawstring('0 32 0' + '0 8 0' * i, "mouse also selects lights\n", '8 8 0', '1 1 1', 1); i+=1; - drawrawstring('0 32 0' + '0 8 0' * i, "m moves the light to the crosshair\n", '8 8 0', '1 1 1', 1); i+=1; - drawrawstring('0 32 0' + '0 8 0' * i, "i inserts new light\n", '8 8 0', '1 1 1', 1); i+=1; - drawrawstring('0 32 0' + '0 8 0' * i, "p points the light to aim at the crosshair\n", '8 8 0', '1 1 1', 1); i+=1; - drawrawstring('0 32 0' + '0 8 0' * i, "[ and ] move the light towards/away from indicated plane\n", '8 8 0', '1 1 1', 1); i+=1; - drawrawstring('0 32 0' + '0 8 0' * i, "don't forget to save\n", '8 8 0', '1 1 1', 1); i+=1; + drawrawstring('0 32 0' + '0 8 0' * (float)i, "+/- change selected light\n", '8 8 0', '1 1 1', 1); i+=1; + drawrawstring('0 32 0' + '0 8 0' * (float)i, "mouse also selects lights\n", '8 8 0', '1 1 1', 1); i+=1; + drawrawstring('0 32 0' + '0 8 0' * (float)i, "m moves the light to the crosshair\n", '8 8 0', '1 1 1', 1); i+=1; + drawrawstring('0 32 0' + '0 8 0' * (float)i, "i inserts new light\n", '8 8 0', '1 1 1', 1); i+=1; + drawrawstring('0 32 0' + '0 8 0' * (float)i, "p points the light to aim at the crosshair\n", '8 8 0', '1 1 1', 1); i+=1; + drawrawstring('0 32 0' + '0 8 0' * (float)i, "[ and ] move the light towards/away from indicated plane\n", '8 8 0', '1 1 1', 1); i+=1; + drawrawstring('0 32 0' + '0 8 0' * (float)i, "don't forget to save\n", '8 8 0', '1 1 1', 1); i+=1; } }; @@ -194,7 +212,7 @@ static void(vector fwd, vector vorg) selectbestlight = { float l, b=selectedlight, d, bd; vector ldir; - l = dynamiclight_get(-1, -1); + l = dynamiclight_get(-1f, -1f); while(l > 0) { l--; @@ -223,7 +241,7 @@ float(float keyc, float unic, vector m) editor_lights_key = strunzone(editvalue); editfield = 0; } - editfield = floor((m_y - 32) / 8); + editfield = floor((m_y - 32f) / 8f); if (editfield <= 0 || editfield > NUMLFIELDS || m_x >= 64) { editfield = 0; @@ -282,8 +300,8 @@ float(float keyc, float unic, vector m) editor_lights_key = else if (keyc == 'p') { traceline(o, t, TRUE, world); - vector ang = vectoangles((trace_endpos + trace_plane_normal*4) - (vector)dynamiclight_get(selectedlight, LFIELD_ORIGIN)); - ang_x *= -1; + vector ang = vectoangles((trace_endpos + trace_plane_normal*4f) - (vector)dynamiclight_get(selectedlight, LFIELD_ORIGIN)); + ang_x *= -1f; dynamiclight_set(selectedlight, LFIELD_ANGLES, ang); /*if we're pointing the light at something, it should probably have a fov*/ @@ -306,7 +324,7 @@ float(float keyc, float unic, vector m) editor_lights_key = /*place it at the pointed location*/ traceline(o, t, TRUE, world); - dynamiclight_set(selectedlight, LFIELD_ORIGIN, trace_endpos + trace_plane_normal*4); + dynamiclight_set(selectedlight, LFIELD_ORIGIN, trace_endpos + trace_plane_normal*4f); break; } } diff --git a/quakec/csaddon/src/editor_particles.qc b/quakec/csaddon/src/editor_particles.qc new file mode 100644 index 000000000..f0e13ead9 --- /dev/null +++ b/quakec/csaddon/src/editor_particles.qc @@ -0,0 +1,410 @@ + +static float cureffect; +static float curmodified; +textfield_linedesc_t fields[100] = +{ + {"shader", "shader \\n{\\nshaderbody\\n}"}, + {"texture", "texture "}, + {"tcoords", "tcoords [coordscale] [randcount] [randsinc]\ncoordscale is an optional divisor for more readable numbers.\nrandcount is a the number of images used in particlefont image.\nrandsinc is the amount to add to s coords to display each sequential randomized image."}, + {"rotationstart", "rotationstart [maxangle]\nan angle of 45 will give you a particle aligned to screen coords"}, + {"rotationspeed", "rotationspeed \nspecifies a range of rotational speeds. You probably want to set the min value as negative."}, + {"beamtexstep", "beamtexstep "}, + {"scale", "scale [max]\nValues are 4 times higher than quake units"}, + {"scalerand", "use scale instead"}, + {"scalefactor", "scalefactor \nHow much the particle shrinks with distance.\n1=true scaling"}, + {"scaledelta", "scaledelta \nHow much the particle's scale changes per second"}, + {"step", "step \nworld distance between each particle within a particle trail."}, + {"count", "count \nProvides a multiplier value independant from the particle() builtin or other mechanisms"}, + {"alpha", "alpha \nInitial opacity of particle. 0 is invisible, 1 is fully visible."}, + {"alphachange", "depricated. use alphadelta"}, + {"alphadelta", "alphadelta \n How much the alpha value changes per second"}, + {"die", "die [max]\nHow long the particle lives for"}, + {"diesubrand", "depricated. use die"}, + {"randomvel", ""}, + {"veladd", ""}, + {"orgadd", ""}, + {"friction", ""}, + {"gravity", "gravity \nParticle's downwards velocity will be increased by this much per second"}, + {"clipbounce", ""}, + {"assoc", "assoc \nWhen the effect is spawned, the associated effect will also be spawned. Can chain."}, + {"inwater", "inwater \nIf the particle effect is spawned underwater, the named effect will be used instead."}, + {"model", "model \nSpawns a the sprite/model when the effect is spawned.\nCan be specified multiple times and a random model line will be used.\nModels with only 1 frame will animate skins instead."}, + {"colorindex", "colourindex \nIf set, the particle's colour will be set to this palette index instead of the particle's rgb field."}, + {"colorrand", "depricated"}, + {"citracer", "citracer\nFlag that syncronizes colorindex-based palette indexes with spawn ordering ala quake."}, + {"red", "depricated, use rgb."}, + {"green", "depricated, use rgb."}, + {"blue", "depricated, use rgb."}, + {"rgb", "rgb \nInitial colour of particle, in a scale of 0 to 255."}, + {"reddelta", "depricated, use rgbdelta."}, + {"greendelta", "depricated, use rgbdelta."}, + {"bluedelta", "depricated, use rgbdelta."}, + {"rgbdelta", "rgbdelta \nSpecifies the change in particle colours over a second of time. The effective range is 0 to 255, but larger values might be needed for short-lived effects."}, + {"rgbdeltatime", "rgbdeltatime \nOnce the particle reaches this age, its rgb values will stop changing."}, + {"redrand", "depricated"}, + {"greenrand", "depricated"}, + {"bluerand", "depricated"}, + {"rgbrand", "rgbrand \nThis rgb value will be multiplied by a random value between 0 and 1 and added to the particle's initial rgb value. All three channels channels are scaled independantly."}, + {"rgbrandsync", "rgbrandsync \nThis rgb value will be multiplied by a random value between 0 and 1 and added to the particle's initial rgb value. All three channels will be scaled the same."}, + {"redrandsync", "depricated"}, + {"greenrandsync", "depricated"}, + {"bluerandsync", "depricated"}, + {"stains", "stains \nSpecifies a multiplier for the radius of a stain if the particle impacts upon a wall"}, + {"blend", "blend \nOne of add, subtract, blendcolour, or blendalpha. Particles with additive blend modes will render fastest due to no depth sorting requirement."}, + {"spawnmode", ""}, + {"type", "type \nOne of:\nbeam - quads generated between particles\nspark - a single line drawn in direction of motion\nsparkfan - triangle fan oriented in direction of motion\ntexturedspark - quads extruded along line of motion\ndecal - motionless effect that attaches to surfaces around the center of the effect\nnormal - simple screen-facing quad"}, + {"isbeam", "depricated, use type."}, + {"spawntime", ""}, + {"spawnchance", ""}, + {"cliptype", ""}, + {"clipcount", ""}, + {"emit", ""}, + {"emitinterval", ""}, + {"emitintervalrand", ""}, + {"emitstart", ""}, + {"areaspread", ""}, + {"areaspreadvert", ""}, + {"offsetspread", ""}, + {"offsetspreadvert", ""}, + {"spawnorg", ""}, + {"spawnvel", ""}, + {"spawnparm1", ""}, + {"spawnparm2", ""}, + {"up", ""}, + {"rampmode", ""}, + {"rampindexlist", ""}, + {"rampindex", ""}, + {"ramp", ""}, + {"perframe", ""}, + {"averageout", ""}, + {"nostate", ""}, + {"nospreadfirst", ""}, + {"nospreadlast", ""}, + {"lightradius", ""}, + {"lightradiusfade", ""}, + {"lightradiusrgb", ""}, + {"lightradiusrgbfade", ""}, + {"lighttime", ""}, + {__NULL__} +}; + +static textfield_t tf_particle; + +#define MAXPARTICLETYPES 200 +typedef struct +{ + string efname; + int start; + int end; +} particledesc_t; +particledesc_t pdesc[MAXPARTICLETYPES]; +int numptypes; +string particlesfile; + +static entity ptrailent; +float mousedown; + +static void(string descname) saveparticle; + +static void(float newef) selecteffect = +{ + if (newef == cureffect) + return; + + if (curmodified) + saveparticle(cvar_string("ca_particleset")); + curmodified = FALSE; + + cureffect = floor(newef); + if (cureffect < 0) + cureffect = 0; + + textfield_fill(&tf_particle, substring(particlesfile, pdesc[cureffect].start, pdesc[cureffect].end - pdesc[cureffect].start)); + + if (ptrailent) + remove(ptrailent); + ptrailent = world; +}; + + + +static int(string src, int *start) skipblock = +{ + string line; + int ls = *start, le; + int level = 0; + /*parse a string from the start of one { to its closing }*/ + + while(1) + { + le = strstrofs(particlesfile, "\n", ls); + if (le < 0) + break; + + line = substring(particlesfile, ls, le - ls); + tokenize_console(line); + line = argv(0); + if (line == "{") + { + if (!level) + *start = le+1; + ++level; + } + else if (line == "}") + { + if (level == 1) + return ls; + --level; + } + else if (!level) + return le+1; + + ls = le+1; + } + + return ls; +}; + +static void() updateloadedparticles = +{ + string line; + int ls, le; + int ce = cureffect; + while(numptypes>0) + { + --numptypes; + strunzone(pdesc[numptypes].efname); + } + + ls = 0; + while(1) + { + le = strstrofs(particlesfile, "\n", ls); + if (le < 0) + break; +// print("line: ", substring(particlesfile, ls, le - ls), "\n"); + if (le - ls > 7) + if (substring(particlesfile, ls, 6) == "r_part") + { + line = substring(particlesfile, ls, le - ls); + tokenize_console(line); + if (argv(0) == "r_part") + { + pdesc[numptypes].efname = strzone(argv(1)); + pdesc[numptypes].start = le+1; + le = skipblock(particlesfile, &pdesc[numptypes].start); + pdesc[numptypes].end = le; + +// print("particle: ", pdesc[numptypes].efname, "\n", substring(particlesfile, pdesc[numptypes].start, pdesc[numptypes].end - pdesc[numptypes].start), "\n"); + ++numptypes; + } + } + ls = le+1; + } + + cureffect = -1; + selecteffect(ce); +}; + +static void(string descname) loadparticles = +{ + float f; + + /*kill old string*/ + if (particlesfile) + strunzone(particlesfile); + particlesfile = (string)0; + +/*load new string*/ + f = fopen(strcat("particles/", descname, ".cfg"), FILE_READNL); + if (f >= 0) + { + particlesfile = strzone(fgets(f)); + fclose(f); + } + + /*and find out where the particles are*/ + updateloadedparticles(); + + localcmd(particlesfile); + localcmd("\n"); +}; + +static void(string descname) saveparticle = +{ + float f; + string newfile; + + /*only do this if there's something to save*/ + if (cureffect < 0) + return; + + newfile = textfield_strcat(&tf_particle); + newfile = strcat(substring(particlesfile, 0, pdesc[cureffect].start), newfile, substring(particlesfile, pdesc[cureffect].end, -1)); + + strunzone(particlesfile); + particlesfile = ""; + + particlesfile = strzone(newfile); + + if (descname != "") + { + f = fopen(strcat("particles/", descname, ".cfg"), FILE_WRITE); + if (f >= 0) + { + fputs(f, particlesfile); + fclose(f); + } + } + + /*and recalculate where the particles are*/ + updateloadedparticles(); +}; + +static void() applyparticles = +{ + if (tf_particle.dirty) + { + string sln; + int i; + if (cureffect >= numptypes) + return; + + localcmd("r_part \""); + localcmd(pdesc[cureffect].efname); + localcmd("\"\n{\n"); + textfield_localcmd(&tf_particle); + localcmd("}\n"); + + sln = strcat("+", pdesc[cureffect].efname); + for (i = cureffect + 1; i < numptypes; i++) + { + if (pdesc[i].efname == sln) + { + localcmd("r_part \""); + localcmd(pdesc[i].efname); + localcmd("\"\n{\n"); + localcmd(substring(particlesfile, pdesc[i].start, pdesc[i].end - pdesc[i].start)); + localcmd("}\n"); + } + } + + tf_particle.dirty = FALSE; + + curmodified = TRUE; + } +}; + +float(float keyc, float unic, vector m) editor_particles_key = +{ + if (m_y > 16 && m_y < 24 && m_x < 128) + { + string oval = strcat(cvar_string("ca_particleset")); + if (keyc == 127) + cvar_set("ca_particleset", substring(oval, 0, -2)); + else if (unic) + cvar_set("ca_particleset", strcat(oval, chr2str(unic))); + else + return FALSE; + + applyparticles(); + if (curmodified) + saveparticle(oval); + curmodified = FALSE; + + oval = cvar_string("ca_particleset"); + loadparticles(oval); + return TRUE; + } + + if (m_y < 32) + return FALSE; + + /*middle mouse*/ + if (keyc == 514) + { + mousedown = 3; + + applyparticles(); + } + else if (m_x < 128) + { + if (keyc == 512) + { + float ef, y; + ef = cureffect - 10; + if (ef < 0) + ef = 0; + y = 32; + + selecteffect(ef + (m_y - y)/8); + } + return TRUE; + } + else + { + return textfield_key(&tf_particle, keyc, unic, m - '128 32 0'); + } + return FALSE; +}; + +void(vector mousepos) editor_particles_overlay = +{ + string n; + float ef; + vector y; + vector col; + string setname = cvar_string("ca_particleset"); + + if (!numptypes) + { + loadparticles(setname); + } + + if (mousedown == 3 && cureffect >= 0 && cureffect < numptypes) + { + vector t = unproject(mousepos + '0 0 8192'); + vector o = unproject(mousepos); + traceline(o, t, TRUE, world); + + trace_endpos += trace_plane_normal * 4; + if (!ptrailent) + { + ptrailent = spawn(); + ptrailent.origin = trace_endpos; + + pointparticles(particleeffectnum(pdesc[cureffect].efname), trace_endpos, '0 0 -1', 1); + } + trailparticles(particleeffectnum(pdesc[cureffect].efname), ptrailent, ptrailent.origin, trace_endpos); + ptrailent.origin = trace_endpos; + } + else if (ptrailent) + { + remove(ptrailent); + ptrailent = world; + } + + if (mousepos_y > 16 && mousepos_y < 24 && mousepos_x < 128) + drawstring('0 16 0', strcat(setname, ((time*4)&1)?"^1\x0b":""), '8 8 0', '1 1 1', 1, 0); + else + drawstring('0 16 0', ((setname=="")?"NO SET LOADED":setname), '8 8 0', '1 1 1', 1, 0); + + ef = cureffect - 10; + if (ef < 0) + ef = 0; + y = '0 32 0'; + for (; ; ef++) + { + if (ef >= numptypes) + break; + n = pdesc[ef].efname; + + col = '1 1 1'; + if (ef == cureffect) + col = '1 0 0'; + drawrawstring(y, n, '8 8 0', col, 1, 0); + y_y += 8; + } + + textfield_draw('128 32 0', &tf_particle, &fields); +}; diff --git a/quakec/csaddon/src/opts.qc b/quakec/csaddon/src/opts.qc new file mode 100644 index 000000000..acbb12d1d --- /dev/null +++ b/quakec/csaddon/src/opts.qc @@ -0,0 +1,2 @@ +//#pragma flag enable assumeint +//#pragma flag enable typeexplicit \ No newline at end of file diff --git a/quakec/csaddon/src/textfield.qc b/quakec/csaddon/src/textfield.qc new file mode 100644 index 000000000..ed9f12309 --- /dev/null +++ b/quakec/csaddon/src/textfield.qc @@ -0,0 +1,339 @@ +/*reusable code to draw/edit/etc some generic text object*/ +/*consult the brief blurb above each function to see what it does*/ + +/*this file deals with textfield_t pointers. allocate your textfield somewhere yourself (probably as a global, this is QC after all), before invoking this code with a pointer to it*/ +#define TEXTFIELD_LINES 200i +typedef struct +{ + string lines[TEXTFIELD_LINES]; + int cursorline; + int cursorcol; + int linecount; + int dirty; +} textfield_t; + +/*this is a text description thing*/ +typedef struct +{ + string name; + string desc; +} textfield_linedesc_t; + +/*destroys the contents of a text field, releasing strings to the system (and clears ready for reuse)*/ +void(textfield_t *fld) textfield_clean = +{ + while(fld->linecount) + { + fld->linecount = fld->linecount - 1i; + strunzone(fld->lines[fld->linecount]); + fld->lines[fld->linecount] = (string)__NULL__; + } + fld->cursorline = 0i; + fld->cursorcol = 0i; + fld->dirty = TRUE; //because its changed +}; +#pragma wrasm 1 +/*fill a text field with data from a string. new lines are supported, but leading tabs and spaces will be stripped*/ +void(textfield_t *fld, string text) textfield_fill = +{ + string line; + float start, end, term; + + while(fld->linecount) + { + fld->linecount = fld->linecount - 1i; + strunzone(fld->lines[fld->linecount]); + fld->lines[fld->linecount] = (string)__NULL__; + } + + fld->cursorline = -1i; + fld->cursorcol = -1i; + start = 0; + for(;;) + { + end = strstrofs(text, "\n", start); + if (end < 0) + break; + while(text[start] == '\t') + ++start; +term = end; +if (term) if (text[term-1] == '\r') term--; + line = substring(text, start, term - start); + end += 1; + + if (fld->linecount == TEXTFIELD_LINES) + break; + fld->lines[fld->linecount] = strzone(line); + fld->linecount = fld->linecount + 1i; + + start = end; + } + fld->dirty = TRUE; +}; +#pragma wrasm 0 + +/*draws the text field on the screen at a given position. +there's no size argument, so make sure data doesn't cause the display to overflow intended area (personally I'm just going to put it at the bottom+right of the screen)*/ +void(vector pos, textfield_t *fld, textfield_linedesc_t *fields) textfield_draw = +{ + string t; + int l; + int nummatches; + int lastmatch; + for (l = 0i; l < fld->linecount; l+=1i, pos_y += 8) + { + if (l == fld->cursorline && ((cltime * 4) & 1)) + { + t = substring(fld->lines[l], 0, fld->cursorcol); + drawrawstring(pos, t, '8 8 0', '1 1 1', 1, 0); + drawrawstring(pos + (0+fld->cursorcol) * '8 0 0', "\x0b", '8 8 0', '1 0 0', 1, 0); + t = substring(fld->lines[l], fld->cursorcol+1, -1); + drawrawstring(pos + (1+fld->cursorcol) * '8 0 0', t, '8 8 0', '1 1 1', 1, 0); + } + else + drawrawstring(pos, fld->lines[l], '8 8 0', '1 1 1', 1, 0); + } + + if (fld->cursorline < 0) + return; + + pos_y += 8; + pos_x += 64; + string cmd = fld->lines[fld->cursorline]; + float llen = strstrofs(cmd, " "); + if (llen < 0f) + llen = strlen(cmd); + cmd = substring(cmd, 0, llen); + + /*show command completion box*/ + for (l = 0; fields[l].name; l++) + { + if (!strncmp(fields[l].name, cmd, llen)) + { + nummatches++; + lastmatch = l; + /*if its an exact match, then stop here*/ + if (cmd == fields[l].name) + { + nummatches = 1; + break; + } + } + } + + if (nummatches == 1 && strlen(fields[lastmatch].name) == llen) + { + drawrawstring(pos, fields[lastmatch].desc, '8 8 0', '0 1 1', 1, 0); + } + else + { + /*show command completion box*/ + for (l = 0; fields[l].name; l++) + { + if (!strncmp(fields[l].name, cmd, llen)) + { + drawrawstring(pos, fields[l].name, '8 8 0', '0 1 1', 1, 0); + pos_y += 8; + } + } + } +}; + +/*send the entire text field into the localcmd builtin, newlines and all*/ +void(textfield_t *fld) textfield_localcmd = +{ + int l; + for (l = 0i; l < fld->linecount; l+=1i) + { + localcmd(fld->lines[l]); + localcmd("\n"); + } +}; + +/*returns the current contents of the text field as a single tempstring (strcat, woo)*/ +string(textfield_t *fld) textfield_strcat = +{ + int l; + string res; + for (l = 0i; l < fld->linecount; l+=1i) + { + res = strcat(res, fld->lines[l], "\n"); + } + return res; +}; + +/*if the user clicks+presses+etc upon the text field, do the magic here +the caller will need to track selected wigit themselves.*/ +float(textfield_t *fld, float keyc, float unic, vector m) textfield_key +{ + int i; + string l,r; + /*mouse*/ + if (keyc == 512) + { + fld->cursorline = floor(m_y / 8); + fld->cursorcol = floor(m_x / 8); + if (fld->cursorline > fld->linecount && fld->linecount) + fld->cursorline = -1i; + return TRUE; + } + else if (fld->cursorline == -1i) + { + /*if its not active, do nothing*/ + return FALSE; + } + /*escape*/ + else if (keyc == 27) + { + fld->cursorline = -1i; + return TRUE; + } + /*backspace*/ + else if (keyc == 127) + { + if (fld->cursorline >= fld->linecount) + { + /*we're beyond the bounds of the buffer*/ + if (fld->cursorline) + fld->cursorline = fld->cursorline - 1i; + } + else if (fld->cursorcol) + { + /*simple delete*/ + l = substring(fld->lines[fld->cursorline], 0, fld->cursorcol-1); + r = substring(fld->lines[fld->cursorline], fld->cursorcol, -1); + strunzone(fld->lines[fld->cursorline]); + fld->lines[fld->cursorline] = strzone(strcat(l, r)); + fld->cursorcol = fld->cursorcol - 1i; + } + else if (fld->cursorline) + { + /*at the start of the line, merge the line with thee previous*/ + l = fld->lines[(fld->cursorline - 1i)]; + r = fld->lines[fld->cursorline]; + fld->cursorcol = strlen(l); + l = strcat(l, r); + strunzone(fld->lines[fld->cursorline - 1i]); + fld->lines[fld->cursorline - 1i] = strzone(l); + for (i = fld->cursorline; i < fld->linecount - 1i; i++) + { + fld->lines[i] = fld->lines[i + 1i]; + } + fld->cursorline = fld->cursorline - 1i; + fld->linecount = fld->linecount - 1i; + } + } + /*delete*/ + else if (keyc == 8) + { + if (fld->cursorline >= fld->linecount) + { + /*we're beyond the bounds of the buffer*/ + if (fld->cursorline) + fld->cursorline = fld->cursorline - 1i; + } + else if (fld->cursorcol >= strlen(fld->lines[fld->cursorline])) + { + /*we're at the end of the line, merge next line in to this one*/ + l = fld->lines[(fld->cursorline)]; + r = fld->lines[fld->cursorline + 1i]; + fld->cursorcol = strlen(l); + l = strcat(l, r); + strunzone(fld->lines[fld->cursorline]); + fld->lines[fld->cursorline] = strzone(l); + for (i = fld->cursorline + 1i; i < fld->linecount - 1i; i++) + { + fld->lines[i] = fld->lines[i + 1i]; + } + fld->linecount = fld->linecount - 1i; + } + else + { + /*simple delete*/ + l = substring(fld->lines[fld->cursorline], 0, fld->cursorcol); + r = substring(fld->lines[fld->cursorline], fld->cursorcol + 1, -1); + strunzone(fld->lines[fld->cursorline]); + fld->lines[fld->cursorline] = strzone(strcat(l, r)); + fld->cursorcol = fld->cursorcol - 1i; + } + } + /*home*/ + else if (keyc == 151) + { + fld->cursorcol = 0; + } + /*end*/ + else if (keyc == 152) + { + fld->cursorcol = strlen(fld->lines[fld->cursorline]); + } + /*leftarrow*/ + else if (keyc == 130) + { + if (fld->cursorcol) + fld->cursorcol = fld->cursorcol - 1i; + } + /*rightarrow*/ + else if (keyc == 131) + { + fld->cursorcol = fld->cursorcol + 1i; + } + /*uparrow*/ + else if (keyc == 128) + { + if (fld->cursorline) + fld->cursorline = fld->cursorline - 1i; + } + /*downarrow*/ + else if (keyc == 129) + { + if (fld->cursorline < fld->linecount) + fld->cursorline = fld->cursorline + 1i; + } + /*return*/ + else if (keyc == 13) + { + if (fld->linecount < TEXTFIELD_LINES) + { + /*shift trailing lines down*/ + fld->linecount = fld->linecount + 1i; + for (i = fld->linecount - 1i; i > fld->cursorline; i--) + { + fld->lines[i] = fld->lines[i - 1i]; + } + /*set the new line to the second half of the current line*/ + fld->lines[fld->cursorline + 1i] = strzone(substring(fld->lines[fld->cursorline], fld->cursorcol, -1)); + /*update the old line to be the first half only*/ + r = strzone(substring(fld->lines[fld->cursorline], 0, fld->cursorcol)); + strunzone(fld->lines[fld->cursorline]); + fld->lines[fld->cursorline] = r; + /*and set the cursor properly*/ + fld->cursorline = fld->cursorline + 1i; + fld->cursorcol = 0; + } + } + /*printable char*/ + else if (unic) + { + if (fld->cursorline >= fld->linecount) + { + fld->cursorline = fld->linecount; + fld->linecount += 1i; + fld->lines[fld->cursorline] = strzone(chr2str(unic)); + fld->cursorcol = 1i; + } + else + { + l = substring(fld->lines[fld->cursorline], 0, fld->cursorcol); + r = substring(fld->lines[fld->cursorline], fld->cursorcol, -1); + strunzone(fld->lines[fld->cursorline]); + fld->lines[fld->cursorline] = strzone(strcat(l, chr2str(unic), r)); + fld->cursorcol = fld->cursorcol+1i; + } + + } + else + return FALSE; + fld->dirty = TRUE; + return TRUE; +}