Jump to content
DZR_Mikhail

AAR (After Action Review - replay of your battle in Arma2)

Recommended Posts

well,guys:

i find some codes using for record the events during the simulation ,the codes are created by the sofeware multigen vega, it is named the "vgVCR",hope to help you! it is c++ codes created by VC++6.0 !

/*

============================================================================

$Revision: 1.13 $ $Date: 1996/12/06 04:44:20 $

============================================================================

PARADIGM SIMULATION INCORPORATED

Copyright 1996 by Paradigm Simulation, Inc.

No part of this source code may be reproduced or distrubuted in any

form or by any means, or stored in a database or retrieval system,

without the prior written consent of Paradigm Simulation, Inc.

============================================================================

*/

#include <stdio.h> /* definition of printf */

#include <stdlib.h> /* definition of exit */

#include <vg.h> /* include file for Vega */

#include <pf.h> /* include file for Performer */

#include <vgfx.h> /* Vega special effects public hdr */

#include "vgvcr.h" /* public vegaVCR header file */

#define VCR_FILE "./default01.vcr"

/*

* Function Prototypes

*/

static void processKey( vgWindow *win );

static void createVCR( void );

static void TimeDrawCallback( vgCommon *chan, void *udata );

static void handleKey( int key );

static void toggleProp( void *handle, int what );

vgVCR *vcr; /* current VCR enabled for keyboard input */

vgScene *scene;

vgEnv *env;

float tod;

vgMotion *mot;

vgChannel *chan;

vgGfx *gfx;

float cw, ch;

/***************************************************************************

*

* main()

*

* Example of a writing code to create and use VCRs. vcrAPI.c

* demonstrates a keyboard input only application. This sample

* also demonstrates VegaVCR's ability to record objects that are

* dynamically added to and removed from a scene. The blimp object

* is dynamically added to and removed from the scene.

*

***************************************************************************/

void main ( int argc , char *argv[] )

{

vgWindow *win;

vgObserver *main_obs;

vgObject *blimp;

vgPosition *pos; /* temporary position */

vgMat mat; /* work matrix */

unsigned added = FALSE;

unsigned deleted = FALSE;

double addTime;

double delTime;

if ( argc < 2 )

{

printf ( "syntax : %s <config file>\n" , argv[0] );

exit ( -1 );

}

/* Initialize, define, and configure the system */

vgInitSys();

vgInitFx(); /* initialize special effects */

vgInitVCR(); /* initialize VCR */

vgDefineSys( argv[1] );

vgConfigSys();

win = vgGetWin( 0 );

blimp = vgFindObj( "blimp" );

scene = vgGetScene( 0 );

env = vgGetEnv( 0 );

main_obs = vgFindObserv( "main" ); /* locate the main observer */

tod = vgGetProp( env, VGENV_TOD );

mot = vgGetMot( 0 );

chan = vgGetChan( 0 );

gfx = vgGetGfx( 0 );

/*

* Create and enable VCR 0 for input

*/

createVCR();

addTime = vgGetFrameTime() + 20.0; /* add blimp 50 secs from now */

delTime = vgGetFrameTime() + 30.0; /* del blimp 65 secs from now */

pos = vgNewPos();

vgIdentMat( mat );

/* the real-time loop */

while ( 1 )

{

if ( !((int) vgGetProp( vcr, VGVCR_STATE ) & VGVCR_PLAY) )

{

if ( !added && (vgGetFrameTime() > addTime) )

{

if ( blimp)

{

vgAddSceneObj( scene, blimp );

added = TRUE;

}

else

vgNotify( VG_NOTICE, VG_APP, "Blimp object could not be found\n" );

}

if ( added && !deleted && (vgGetFrameTime() > delTime) )

{

deleted = TRUE;

vgRemSceneObj( scene, blimp );

}

}

vgSyncFrame ();

vgFrame ();

processKey( win );

}

vgExit( 0 );

}

/*

* Keyboard only input for this sample - to make sure users can indeed

* have just keyboard input if they so desire

*/

enum Key { RECORD = VGWIN_ALTR, PLAY = VGWIN_ALTP, STOP = VGWIN_ALTS,

PAUSE = VGWIN_ALTX, REWIND = VGWIN_ALTW, FF = VGWIN_ALTF };

/***************************************************************************

*

* processKey()

*

***************************************************************************/

void processKey( vgWindow *win )

{

int key = vgGetWinKey( win );

if ( key )

{

if ( key <= '9' && key > '0' ) /* 1-9 */

{

unsigned i = key - '0' - 1; /* key 1 corresponds to VCR 0 */

if ( vgGetVCR( i ) )

vcr = vgGetVCR( i );

return;

}

if ( vcr )

switch ( (int) vgGetProp( vcr, VGVCR_STATE ) )

{

case VGVCR_RECORD:

if ( key == STOP )

vgVCRStop( vcr );

else if ( key == PLAY )

{

vgVCRStop( vcr );

vgVCRPlay( vcr );

}

else if ( key == PAUSE )

vgVCRPause( vcr );

else

handleKey( key );

break;

case VGVCR_PLAY:

case VGVCR_FF:

if ( key == STOP )

vgVCRStop( vcr );

else if ( key == PAUSE )

vgVCRPause( vcr );

else if ( key == FF )

vgVCRFF( vcr );

else if ( key == REWIND )

vgVCRRewind( vcr );

else if ( key == PLAY )

vgVCRPlay( vcr ); /* disable FF */

else

handleKey( key );

break;

case VGVCR_STOP:

if ( key == RECORD )

vgVCRRecord( vcr );

else if ( key == PLAY )

vgVCRPlay( vcr );

else if ( key == REWIND )

vgVCRRewind( vcr );

else

handleKey( key );

break;

default: /* VGVCR_PAUSE */

if ( (((int) vgGetProp( vcr, VGVCR_STATE ) & VGVCR_RECORD) &&

(key == PAUSE || key == RECORD)) ||

(((int) vgGetProp( vcr, VGVCR_STATE ) & VGVCR_PLAY) &&

(key == PAUSE || key == PLAY)) )

vgVCRPause( vcr );

else if ( key == STOP )

vgVCRStop( vcr );

else

handleKey( key );

break;

}

}

}

/***************************************************************************

*

* createVCR()

*

***************************************************************************/

static void createVCR()

{

if ( (vcr = vgNewVCR()) )

{

vgSystem *sys = vgGetSys();

vgName( vcr, "CNN" );

vgVCRInFileName( vcr, VCR_FILE );

vgVCROutFileName( vcr, VCR_FILE );

vgProp( vcr, VGVCR_INTERPOLATE, VG_OFF );

vgProp( vcr, VGVCR_FREQUENCY, 15 ); /* 15 Hz */

vgProp( vcr, VGVCR_VCRLIST, VGVCR_ENV ); /* all env */

vgVCRRegisterInstance( vcr, vgFindObserv( "main" ), NULL );

vgVCRRegisterInstance( vcr, vgFindPlyr( "car" ), NULL );

/*

* Record the parts of the car, but do not record the parts of the blimp

*/

vgVCRRegisterInstance( vcr, vgFindObj( "car" ), (void *) VGVCR_PARTS );

vgVCRRegisterInstance( vcr, vgFindObj( "blimp" ), NULL );

vgMakeVCR( vcr );

vgVCRRegisterInstance( vcr, vgFindFx( "smoke" ), NULL );

vgVCRRegisterInstance( vcr, vgFindFx( "fire" ), NULL );

#ifndef IRISGL /* calculations for OpenGL only */

{

int wl, wr, wb, wt;

float cl, cr, cb, ct;

vgWindow *win;

win = vgGetChanWin( chan );

vgGetWinSize( win, &wl, &wr, &wb, &wt );

vgGetChanViewport( chan, &cl, &cr, &cb, &ct );

cw = (cr - cl) * (wr - wl);

ch = (ct - cb) * (wt - wb);

}

#endif

vgAddFunc( chan, VGCHAN_POSTDRAW, TimeDrawCallback, NULL );

}

}

#define kBoxL 10

#define kBoxB 10

static char *states[] =

{

"REWIND", /* 0x000 */

"STOP", /* 0x001 */

"RECORD", /* 0x002 */

"",

"PLAY", /* 0x004 */

"FAST FORWARD", /* 0x005 */

"", "",

"PAUSE", /* 0x008 */

"",

"PAUSE", /* 0x00A pause from rec */

"",

"PAUSE", /* 0x00B pause from play */

"PAUSE" /* 0x00B pause from ff */

};

/***************************************************************************

*

* TimeDrawCallback()

*

* This is the channel post draw callback which will draw the

* hud on top of the channel which has already been drawn

*

***************************************************************************/

#ifdef IRISGL

void TimeDrawCallback( vgCommon *chan, void *udata )

{

char str[VG_MAXSTRING];

char name[VG_MAXSTRING];

float time;

int hour, min, sec;

Matrix mv, mp;

/*

* Convert time (in seconds) into hours, minutes and seconds

*/

time = vgVCRGetElapsedTime( vcr );

hour = (int) time/3600.0;

time -= hour*3600.0;

min = (int) time/60.0;

time -= min*60.0;

sec = (int) time;

vgGetName( vcr, name );

sprintf( str, "\"VegaVCR - %s\" Time: %.2d:%.2d:%.2d %s",

name, hour, min, sec, states[(int)vgGetProp( vcr, VGVCR_STATE )] );

/*

* pushstate:

* Save drawing state, so when the callback relinquishes control

* of application, application will know how to carry on.

*/

pfPushState();

pfBasicState ( );

pfDisable( PFEN_TEXTURE );

pfDisable( PFEN_FOG );

pfDisable( PFEN_LIGHTING );

pfTransparency( PFTR_FAST );

zbuffer( FALSE ); /* disable zbuffer */

/*

* GL/OpenGL function calls to draw hud

*/

mmode( MPROJECTION );

getmatrix( mp );

mmode( MVIEWING );

getmatrix( mv );

ortho2 ( 0, 1280, 0, 1024 ); /* make viewing matrix ortho */

mmode( MVIEWING );

pfPushIdentMatrix();

RGBcolor( 255, 0, 0); /* color is red */

vgFontSize( 30, 40 ); /* set char size */

vgFontPos ( kBoxL + 20, kBoxB + 24, 0 ); /* draw string here */

vgDrawFont( str ); /* draw string */

/*

* popstate:

* restore drawing state basically put it back the way it was

*/

zbuffer( TRUE );

pfPopMatrix(); /* restore matrix */

pfPopState(); /* restore state */

mmode( MPROJECTION );

loadmatrix( mp );

mmode( MVIEWING );

loadmatrix( mv );

}

#else

void TimeDrawCallback( vgCommon *chan, void *udata )

{

char str[VG_MAXSTRING];

char name[VG_MAXSTRING];

float time;

int hour, min, sec;

int orgmmode; /* original mat mode */

int zbuf;

/*

* Convert time (in seconds) into hours, minutes and seconds

*/

time = vgVCRGetElapsedTime( vcr );

hour = (int) time/3600.0;

time -= hour*3600.0;

min = (int) time/60.0;

time -= min*60.0;

sec = (int) time;

vgGetName( vcr, name );

sprintf( str, "\"VegaVCR - %s\" Time: %.2d:%.2d:%.2d %s",

name, hour, min, sec, states[(int)vgGetProp( vcr, VGVCR_STATE )] );

pfPushState();

pfBasicState();

zbuf = glIsEnabled( GL_DEPTH_TEST );

if ( zbuf ) glDisable( GL_DEPTH_TEST );

glGetIntegerv( GL_MATRIX_MODE, &orgmmode );

glMatrixMode( GL_PROJECTION );

glPushMatrix();

glLoadIdentity();

gluOrtho2D( 0.0, cw - 1.0, 0.0, ch - 1.1 );

glMatrixMode( GL_MODELVIEW );

glPushMatrix();

glLoadIdentity();

glColor3f( 1.0, 0.0, 0.0 );

vgFontSize( 20, 30 ); /* set char size */

vgFontPos ( kBoxL + 20, kBoxB + 24, 0 ); /* draw string here */

vgDrawFont( str ); /* draw string */

/*

* popstate:

* restore drawing state basically put it back the way it was

*/

glPopMatrix();

glMatrixMode( GL_PROJECTION );

glPopMatrix();

glMatrixMode( orgmmode );

if ( zbuf ) glEnable( GL_DEPTH_TEST );

pfPopState();

}

#endif

/***************************************************************************

*

* handleKey()

*

* Assumptions:

*

* env, chan, gfx are non-NULL

*

***************************************************************************/

void handleKey( int key )

{

switch ( key )

{

case 'D':

tod += .01;

if ( tod > 1.0 ) tod = 1.0;

vgProp( env, VGENV_TOD, tod );

break;

case 'd':

tod -= .01;

if ( tod < 0.0 ) tod = 0.0;

vgProp( env, VGENV_TOD, tod );

break;

case 'f':

toggleProp( gfx, VGGFX_FOG );

break;

case 'j':

toggleProp( chan, VGCHAN_RENDER );

break;

case 'l':

toggleProp( gfx, VGGFX_LIGHTING );

break;

case 'm':

/* Toggle motion model type */

if ( mot )

{

long m = (int) vgGetProp( mot, VGMOT_MODEL );

if ( ++m > VGMOT_WARP ) m = VGMOT_SPIN;

vgProp( mot, VGMOT_MODEL, (float) m );

}

break;

case 'P':

if ( mot )

{

vgPosition *tpos = vgNewPos();

float x, y, z, h, p, r;

vgGetPos( (vgCPos *) mot, tpos );

vgGetPosVec( tpos, &x, &y, &z, &h, &p, &r );

printf( "(x,y,z) = (%7.3f,%7.3f,%7.3f)\n", x,y,z );

printf( "(h,p,r) = (%7.3f,%7.3f,%7.3f)\n", h,p,r );

vgDelPos( tpos );

}

break;

case 's':

{

unsigned stats = vgGetProp( chan, VGCHAN_STATSSEL );

if ( ++stats > 4 ) stats = 0;

vgProp( chan, VGCHAN_STATSSEL, stats );

break;

}

case 'T':

toggleProp( gfx, VGGFX_TRANSPARENCY );

break;

case 't':

toggleProp( gfx, VGGFX_TEXTURE );

break;

case 'u':

toggleProp( gfx, VGGFX_BACKFACE );

break;

case 'x':

/* Toggle motion model state */

if ( mot ) toggleProp( mot, VGCOMMON_ENABLED );

break;

case 'w':

toggleProp( gfx, VGGFX_WIREFRAME );

break;

case 'z':

toggleProp( gfx, VGGFX_ZBUFFER );

break;

case '?':

printf( " D : increase time of day (brightness)\n" );

printf( " d : decrease time of day (brightness)\n" );

printf( " f : toggle fog (on/off)\n" );

printf( " j : toggle channel rendering (on/off)\n" );

printf( " l : toggle graphics state lighting (on/off)\n" );

printf( " m : cycle motion model type\n" );

printf( " P : print current eyepoint location\n" );

printf( " s : cycle statistics\n" );

printf( " T : toggle transparency (on/off)\n" );

printf( " t : toggle texture (on/off)\n" );

printf( " u : toggle backface display (on/off)\n" );

printf( " x : toggle motion model state (on/off)\n" );

printf( " w : toggle wireframe display (on/off)\n" );

printf( " z : toggle Z-Buffer (on/off)\n" );

break;

default:

break;

}

}

/***************************************************************************

*

* toggleProp()

*

* Toggle property of instance from on -> off -> on

*

***************************************************************************/

static void toggleProp( void *handle, int what )

{

if ( handle != NULL )

vgProp( handle, what, !((int) vgGetProp( handle, what )) );

}

---------- Post added at 09:59 PM ---------- Previous post was at 09:57 PM ----------

VCR API

This is an example of how to create and use Vega VCRs. vcrAPI.c demonstrates a keyboard input only application. This sample also demonstrates VegaVCR's ability to record objects that are dynamically added to and removed from a scene. The blimp object is dynamically added to and removed from the scene. VCR usage is as follows:

alt w = rewind

alt s = stop

alt r = record

alt p = play

alt f = fast forward

alt x = pause

Keys 1-9 on top of keyboard enable VCR numbers 1-9 to accept input from the keyboard

D = increase time of day

d = decrease time of day

f = toggle fog on/off

j = toggle channel rendering on/off

l = toggle lighting on/off

m = toggle motion model type

P = print current eyepoint location

s = show stats

T = toggle transparency on/off

t = toggle textures on/off

u = toggle backfacing

x = toggle motion model state on/off

w = toggle wireframe on/off

z = toggle Z-buffer on/off

Share this post


Link to post
Share on other sites

Seems it's the code for a very specific functionality and I can't guess how to use this. My Delphi part seems pretty well done, but the most work now must be done to create more stable and efficient scripting in Arma.

Anyways, thank you rcdxph, for your support.

Share this post


Link to post
Share on other sites

Sorry, no news or updates. Been busy with personal matters :( Looks like will be this way for few months more :(

Share this post


Link to post
Share on other sites

I'm planning to review my code and start planning the work on buffered read\write inside arma. Probably this will finally solve all the issues concerning units limitation and playback lag.

No ETA, though. I'm just planning and trying to recall all the details in my mess of code. I'll let you know if any progress follows.

Share this post


Link to post
Share on other sites

I have seen 2 years ago in Charlie Foxtrot, Campaign 2 ,BAttle 1 a replay of one of our Battles. This replay recorded all the GPS markers on the map of one team, so you could track the movement of all the 35 people playing on BLUFOR and 31 playing on OPFOR (if you watched the replay for OPFOR ). I still have the replay mission with all the scripts and the man who made it is still available. You could just load the mission in the editor and repaly the battle by watchign the movment of the markers on Chenarus. It doesn´t replay the movment or the ballistics, but it is a start :).

Share this post


Link to post
Share on other sites

Helo, this thing will be very useful for AAR lite which is planned to do exactly what you say with couple of other features, like showing who shoot and what was target, who died and who's injured, etc. YThis script of your can save a lot of time for me because tracing positions is the first part of my work :)

Please, share it with us. I'll be very grateful. Thanks in advance.

Share this post


Link to post
Share on other sites

Helo, honestly, I believe that only two things can prevent Jones from sharing his scripts. He is either preparing a huge AAR project himself to compete mine, or he is going to sell his scripts because invested a lot of work in it.

If he makes his own AAR, I'll be totally happy and will help as much as I can and even stop my own project for a more experienced coder to deal with it.

If he makes it commercial. No problem. I respect this choice.

Anyways, I'm able to create the same scripts with same or more extended functionality. Actually I planned it before long time ago. Revealing these scripts of Jones just cut some months of scripting for me. But without them, I'll just spend a bit more time to develop them myself.

In any case these scripts are inevitable :)

If you decide to share the scripts with me, I promise on your or Jones' first demand I will delete any signs of his scripts from my HDD and remove all you ask from AAR and will not use any part of this code in my projects.

So it's up to you to decide. Thanks for understanding.

Share this post


Link to post
Share on other sites

Good news! Jones kindly explained every detail on his work and shared all the source files with his permission to use them in AAR.

As soon as I have time I'll dig in to integrate everything in my projects.

Share this post


Link to post
Share on other sites

Great news!!!

Good luck for the full AAR project too. That would be so amazing to have working.

I wonder if it will be easier in ARMA3....?

Share this post


Link to post
Share on other sites

Thanks for the support guyz. :bounce3:

Another priority shift for AAR project. Now the next step is final and definite. Apart from buffered write method, which is a technical task, I've decided to force myself into making a fully working map-playback.

And another major change for the whole AAR is that I decided not to create a separate aar type file for replay, which is an enormous task to do and I guess it can slow down whole development. I chose a more simple way to bring AAR sooner with not that huge ambitious list of features.

AAR will be recording everything as intended, but playback will be totally changed. After the record you will have one quite big sqf file, which will feature a standalone AAR script. I mean, this sqf file will not be requiring AAR at all, because it will have all the functions and controls and the replay data just inside. The only thing you'd need to do is to execute this file in game anyway you wish.

For those who will have AAR mod installed there I guess will be just an interface with some 10 slots where replays in folder will be automatically loaded and some neat button to play, stop, rewind and pause.

So, what I plan to do in the nearest future is make AAR which will record positions, fires, targets and killers, deaths and injuries, units being afoot or driving vehicles and... that's it for now.

It will be played back only at your map. Markers will be moving, rotating, changing color to indicate it's condition or action, they'll change shape as well to indicate whether it's soldier, land\air vehicle or a dead body.

Markers will also have texts to show you nicks of players and names of vehicles. Bot will have just AI written there.

And I will be trying very hard to implement pause and step 5 seconds back\forward.

And that's it. Less difficult, less picturesque, but at least it will exist. So to say, better than nothing but an Alpha Demo. :j:

I wonder if it will be easier in ARMA3....?

I've got to know from reliable sources that A3 will have amazing stuff for developers which will simplify such things that I try to do.

Share this post


Link to post
Share on other sites

Ok, made a lot of good coding today. Many things worked better than I thought. But now need some help on optimizing my cycles.

The problem is that something somewhere runs not async. I can guess ACRE has a lot of data being sent to plugin pipe and I never see it impacting performance.

When I run my function multiple times I definitely see game siezed by my script. It all processed and no data lost, but it runs for more than aa minute while processed frames count 25 at max and game is frozen almost all time, not playable.

Can you suggest some proper way to make this all totally async and without impecting performance?

Here's how It's done in my way.

I make a function

AAR_fnc_writePipe = compile preprocessFile "fnc_AAR_buffered_write.sqf";

Function splits array into minor partions and sends to jayarma2lib named pipe like this

<data> spawn jayarma2lib_fnc_writePipe;

then I forEach through AllUNits, gather the array with properties and send it to the above function.

Here are rough code of my files with all the unneeded things ripped out.

======= START record_data.sqf

{

AAR_fnc_writePipe = compile preprocessFile "fnc_AAR_buffered_write.sqf";

while(true) do {

<here I gather all the info>

_unit_array = [_x,_Cpos,_CDir,_animate,_state, _vehicle, _driver, _gunner,_commander];

_write_array = ["unit", _frame, time, _unit_array];

[armaData, _write_array] spawn AAR_fnc_writePipe;

} forEach recUnits;

sleep 0.05; //fps, tried 0.1 etc…

}

// this cycle is for each fps

======= END record_data.sqf

======= START fnc_AAR_buffered_write.sqf

_handle = _this select 0;

_data = call compile format["%1",_this select 1];

<here I get all needed vars from _data>

[_handle, format["%1;%2;%3;%4;%5;unit",_frame, time, _the_unit, "state", _state]] spawn jayarma2lib_fnc_writePipe;

======= END fnc_AAR_buffered_write.sqf

Share this post


Link to post
Share on other sites

a few ideas

a) let the server or another player instance record in case you cannot optimize it more

b) how many position updates do you really need per second

c) write to pipe not for each unit, but cache the data of all/several units in an array inside arma first before writing to the pipe - if that is the bottlekneck

Edited by .kju [PvPscene]

Share this post


Link to post
Share on other sites

PvPscene, thanks for the ideas.

a) they'll freeze too :)

b) well, 10 separate small blocks of data per every unit in function are updated to the pipe... and units can count... I do not plan to limit it's number... at least 50-60 to suit most community needs.

c) this idea was already mentioned once, but I just cannot get it. I mean, I lack theory and cannot guess the algorithm. I can create and update this monster array, but I cannot understand how to:

1) clean it after I dumped a record from it to the pipe

2) deal with it in the main dump cycle. I mean, How can I foraech an array which is updated constantly and enormously?

Any ideas?

---------- Post added at 01:53 PM ---------- Previous post was at 12:17 PM ----------

May be I'll create an array per every frame with dynamic naming pattern. Like frame_###. Then I'll read these arrays using the naming pattern alike.

Store already filled arrays names in a separate array, like _frame_count = [frame_0, frame_1, frame_2 ...]

_fcount = count(_frame_count)// count all the frames already filled with data

for [{_fn=1},{_fn<=fcount},{_fn=_fn+1}] do {

_array_to_dump = call compile format["_frame_%1",_fn];

//dump_array

//and clear it

call compile format["_frame_%1 = '0' ",_fn];

}

Crazy?

Edited by zvukoper

Share this post


Link to post
Share on other sites

I dont get what you are doing there.

You only need:

======= START record_data.sqf

{

AAR_fnc_writePipe = compile preprocessFile "fnc_AAR_buffered_write.sqf";

while(true) do
{
	_dataArray = [];
	{
		<here I gather all the info>

		_unit_array = [_x,_Cpos,_CDir,_animate,_state, _vehicle, _driver, _gunner,_commander];
		_write_array = ["unit", _frame, time, _unit_array];

		_dataArray set [count _dataArray, [armaData, _write_array]];
	} forEach recUnits;

	_dataArray spawn AAR_fnc_writePipe;

	sleep 0.05; //fps, tried 0.1 etc…
};
}
// this cycle is for each fps
======= END record_data.sqf

Share this post


Link to post
Share on other sites

_dataArray set [count _dataArray, [armaData, _write_array]]; 

that's a nice find to use count... Thanks.

Then I need this global constantly growing array to be dumped record by record (element by element) to jayarma2lib_fnc_writePipe. And I must clear the records from this array that I've already dumped. I guess it's not be working if I try to manipulate the global actively updated array on the fly? If I create a cycle in my function to forEach this array, then it will end on the last element ignoring the newly added... Sorry, I'm really a newbie and try to force my brain to understand this as hard as I can :j:

Share this post


Link to post
Share on other sites

Well the basic questions are:

# Is the writing to the pipe the bottleneck (likely)

# How much data can you get through the pipe in one go

# What is the data limit an array in the arma engine can handle

If the pipe is the bottleneck, you need to make sure to call at seldom as possible.

You should be able to test/verify this with dummy data easily.

Share this post


Link to post
Share on other sites
# Is the writing to the pipe the bottleneck (likely)

Yeah, likely.

I'll try to substitute it with for example CopyToClipboard and see what changes as soon as I get to my PC... tomorrow I guess :(

# How much data can you get through the pipe in one go

4096 bytes, that's why I split every type of gathered data into a separate block of transfer\array

If you noticed, at some point in the past I've done a quite good demo of recording firefight and playbacking it. I never thought I'd be able to create something like this. I was so impressed that I decided to keep this project whatever it costs. But the problem was that it was limited to 5-6 units at most. If I added more - jlib got clogged and lost data.

REC -

ktPzEJEvsPA

PLAY -

6FpJMO9Cf7s

# What is the data limit an array in the arma engine can handle

Probably 300mb, because that's the limit for pbo size. But I don't even wanna be figuring it out and I'd rather implement some "precessed data" deleting mechanism.

AAR must be able to record hours and hours of battle. I will implement cutting it to 100mb parts automatically in the external aaplication which will dump data to files.

---------- Post added at 04:12 PM ---------- Previous post was at 04:05 PM ----------

Please, have a look at this illustration. That's how I see it working.

yBXKCFVBRAg

Nevermind the tiny animation issues when it's just moving down. Moving down means nothing. The idea is just that data blocks or unit arrays are stacked in the queue to be sent to external app.

---------- Post added at 04:36 PM ---------- Previous post was at 04:12 PM ----------

Stacking in this example must be handled asynchronously and independently of what is currently being happeinig in game, of the currently grabbed frame. Recording just stacks and buffer sends data to ext app in a consequtive, ordered way without clogging jlib.

---------- Post added at 04:39 PM ---------- Previous post was at 04:36 PM ----------

Then I plan to dump everything inside a SQLite db so that all frames and data inside could be effectively sorted. THen I'll read it back in a sroted manner and generate an sqf file, which once executed will playback the replay.

---------- Post added at 06:00 PM ---------- Previous post was at 04:39 PM ----------

YES!!!! Mahuja had just kindly explained everything to me and I definitely have all the info I need to implement this cache. Wish me luck and time guyz :)

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×