1 // 2 // 3 4 #include "testing.h" 5 6 #include "scripting/api/objs/vecmath.h" 7 #include "scripting/api/objs/enums.h" 8 #include "scripting/api/objs/texture.h" 9 #include "scripting/api/objs/object.h" 10 #include "scripting/api/objs/particle.h" 11 12 #include "scripting/lua/LuaValue.h" 13 14 #include "scripting/api/objs/bytearray.h" 15 #include "scripting/api/objs/audio_stream.h" 16 #include "sound/audiostr.h" 17 18 #include "physics/physics.h" 19 #include "graphics/2d.h" 20 #include "io/timer.h" 21 #include "particle/particle.h" 22 #include "playerman/player.h" 23 #include "cutscene/movie.h" 24 #include "network/multi_options.h" 25 26 27 namespace scripting { 28 namespace api { 29 30 //*************************Testing stuff************************* 31 //This section is for stuff that's considered experimental. 32 ADE_LIB(l_Testing, "Testing", "ts", "Experimental or testing stuff"); 33 34 ADE_FUNC(openAudioStreamMem, 35 l_Testing, 36 "string snddata, enumeration stream_type /* AUDIOSTREAM_* values */", 37 "Opens an audio stream of the specified in-memory file contents and type.", 38 "audio_stream", 39 "A handle to the opened stream or invalid on error") 40 { 41 luacpp::LuaValue snddata_arr(L); 42 enum_h streamTypeEnum; 43 if (!ade_get_args(L, "ao", &snddata_arr, l_Enum.Get(&streamTypeEnum))) { 44 return ade_set_args(L, "o", l_AudioStream.Set(-1)); 45 } 46 47 int streamType; 48 switch (streamTypeEnum.index) { 49 case LE_ASF_EVENTMUSIC: 50 streamType = ASF_EVENTMUSIC; 51 break; 52 case LE_ASF_MENUMUSIC: 53 streamType = ASF_MENUMUSIC; 54 break; 55 case LE_ASF_VOICE: 56 streamType = ASF_VOICE; 57 break; 58 default: 59 LuaError(L, "Invalid audio stream type %d.", streamTypeEnum.index); 60 return ade_set_args(L, "o", l_AudioStream.Set(-1)); 61 } 62 63 64 if (!snddata_arr.pushValue(L)) 65 return ade_set_args(L, "o", l_AudioStream.Set(-1)); 66 if (!lua_isstring(L, -1)) { 67 lua_pop(L, 1); 68 LuaError(L, "Expected binary string containing audio."); 69 return ade_set_args(L, "o", l_AudioStream.Set(-1)); 70 } 71 72 size_t snd_len; 73 auto snddata = lua_tolstring(L, -1, &snd_len); 74 75 int ah = audiostream_open_mem(reinterpret_cast<const uint8_t *>(snddata), snd_len, streamType); 76 lua_pop(L, 1); 77 if (ah < 0) { 78 LuaError(L,"Stream could not be opened. Did you pass valid audio?"); 79 return ade_set_args(L, "o", l_AudioStream.Set(-1)); 80 } 81 82 return ade_set_args(L, "o", l_AudioStream.Set(ah)); 83 } 84 85 86 ADE_FUNC(avdTest, l_Testing, NULL, "Test the AVD Physics code", NULL, NULL) 87 { 88 (void)L; // unused parameter 89 90 static bool initialized = false; 91 static avd_movement avd; 92 93 if(!initialized) 94 { 95 avd.setAVD(10.0f, 3.0f, 1.0f, 1.0f, 0.0f); 96 initialized = true; 97 } 98 for(int i = 0; i < 3000; i++) 99 { 100 float Pc, Vc; 101 avd.get((float)i/1000.0f, &Pc, &Vc); 102 gr_set_color(0, 255, 0); 103 gr_pixel(i/10, gr_screen.clip_bottom - (int)(Pc*10.0f), GR_RESIZE_NONE); 104 gr_set_color(255, 0, 0); 105 gr_pixel(i/10, gr_screen.clip_bottom - (int)(Vc*10.0f), GR_RESIZE_NONE); 106 107 avd.get(&Pc, &Vc); 108 gr_set_color(255, 255, 255); 109 gr_pixel((timestamp()%3000)/10, gr_screen.clip_bottom - (int)(Pc*10.0f), GR_RESIZE_NONE); 110 gr_pixel((timestamp()%3000)/10, gr_screen.clip_bottom - (int)(Vc*10.0f), GR_RESIZE_NONE); 111 } 112 113 return ADE_RETURN_NIL; 114 } 115 116 ADE_FUNC_DEPRECATED(createParticle, 117 l_Testing, 118 "vector Position, vector Velocity, number Lifetime, number Radius, enumeration Type, [number " 119 "TracerLength=-1, boolean Reverse=false, texture Texture=Nil, object AttachedObject=Nil]", 120 "Creates a particle. Use PARTICLE_* enumerations for type." 121 "Reverse reverse animation, if one is specified" 122 "Attached object specifies object that Position will be (and always be) relative to.", 123 "particle", 124 "Handle to the created particle", 125 gameversion::version(19, 0, 0, 0), 126 "Not available in the testing library anymore. Use gr.createPersistentParticle instead.") 127 { 128 particle::particle_info pi; 129 pi.type = particle::PARTICLE_DEBUG; 130 pi.optional_data = -1; 131 pi.attached_objnum = -1; 132 pi.attached_sig = -1; 133 pi.reverse = 0; 134 135 // Need to consume tracer_length parameter but it isn't used anymore 136 float temp; 137 138 enum_h *type = NULL; 139 bool rev=false; 140 object_h *objh=NULL; 141 texture_h* texture = nullptr; 142 if (!ade_get_args(L, "ooffo|fboo", l_Vector.Get(&pi.pos), l_Vector.Get(&pi.vel), &pi.lifetime, &pi.rad, 143 l_Enum.GetPtr(&type), &temp, &rev, l_Texture.GetPtr(&texture), l_Object.GetPtr(&objh))) 144 return ADE_RETURN_NIL; 145 146 if(type != NULL) 147 { 148 switch(type->index) 149 { 150 case LE_PARTICLE_DEBUG: 151 pi.type = particle::PARTICLE_DEBUG; 152 break; 153 case LE_PARTICLE_FIRE: 154 pi.type = particle::PARTICLE_FIRE; 155 break; 156 case LE_PARTICLE_SMOKE: 157 pi.type = particle::PARTICLE_SMOKE; 158 break; 159 case LE_PARTICLE_SMOKE2: 160 pi.type = particle::PARTICLE_SMOKE2; 161 break; 162 case LE_PARTICLE_BITMAP: 163 if (texture == nullptr || !texture->isValid()) { 164 LuaError(L, "Invalid texture specified for createParticle()!"); 165 return ADE_RETURN_NIL; 166 } else { 167 pi.optional_data = texture->handle; 168 pi.type = particle::PARTICLE_BITMAP; 169 } 170 break; 171 } 172 } 173 174 if(rev) 175 pi.reverse = 0; 176 177 if(objh != NULL && objh->IsValid()) 178 { 179 pi.attached_objnum = OBJ_INDEX(objh->objp); 180 pi.attached_sig = objh->objp->signature; 181 } 182 183 particle::WeakParticlePtr p = particle::createPersistent(&pi); 184 185 if (!p.expired()) 186 return ade_set_args(L, "o", l_Particle.Set(particle_h(p))); 187 else 188 return ADE_RETURN_NIL; 189 } 190 191 ADE_FUNC(getStack, l_Testing, NULL, "Generates an ADE stackdump", "string", "Current Lua stack") 192 { 193 char buf[10240] = {'\0'}; 194 ade_stackdump(L, buf); 195 return ade_set_args(L, "s", buf); 196 } 197 198 ADE_FUNC(isCurrentPlayerMulti, l_Testing, NULL, "Returns whether current player is a multiplayer pilot or not.", "boolean", "Whether current player is a multiplayer pilot or not") 199 { 200 if(Player == NULL) 201 return ade_set_error(L, "b", false); 202 203 if(!(Player->flags & PLAYER_FLAGS_IS_MULTI)) 204 return ADE_RETURN_FALSE; 205 206 return ADE_RETURN_TRUE; 207 } 208 209 ADE_FUNC(isPXOEnabled, l_Testing, NULL, "Returns whether PXO is currently enabled in the configuration.", "boolean", "Whether PXO is enabled or not") 210 { 211 if(!(Multi_options_g.pxo)) 212 return ADE_RETURN_FALSE; 213 214 return ADE_RETURN_TRUE; 215 } 216 217 ADE_FUNC(playCutscene, l_Testing, NULL, "Forces a cutscene by the specified filename string to play. Should really only be used in a non-gameplay state (i.e. start of GS_STATE_BRIEFING) otherwise odd side effects may occur. Highly Experimental.", "string", NULL) 218 { 219 //This whole thing is a quick hack and can probably be done way better, but is currently functioning fine for my purposes. 220 const char* filename; 221 222 if (!ade_get_args(L, "s", &filename)) 223 return ADE_RETURN_FALSE; 224 225 movie::play(filename); 226 227 return ADE_RETURN_TRUE; 228 } 229 230 231 } 232 } 233 234