| LoseThos has a numeric integrator built-in. This allows solving of differential equations. If you can formulate the derivative equations, you can do real-time simulations in games or whatever. I think there are many new and exciting applications for numeric integration. See /LT/DEMO/WinMgr2.CPZ for a demo you can try. It repositions the windows on the screen as though repulsive forces are spreading them out. You might want to tweak it by adding damping since it now oscillates. |
|||||
The following are declared in /LT/OSMain/ADAM.HPZ: public class Ode {
I8 n; double base_t; double t; double h; double tolerance_start; double tolerance; double *state; double *DstateDt; double *state_scale; double *initial_state; double *temp0,*temp1,*temp2,*temp3,
public class Order2D3 {
The following is the code found in /LT/DEMO/WinMgr2.CPZ. You should #include it with the "ADAM_INCLUDE" option from the right-click menu when you click the filename in a directory listing. This essentially places the code into kernel space. There is no such distinction in LoseThos, but when you include it from the Adam task, it will not be Free()d when the user task is killed; it's #included by the Adam task and the Adam task never dies. Note: This program modifies the window coordinates found in the task state structure, tss. It so happens that horizontal coordinates are scaled by 4. (Screen text memory stores 4-bytes per character, and we're going under-the-hood by modifying operating system structures.) The operating system uses a Runge-Kutta algorithm on any Ordinary Differential Equation structure placed into a special doubly-linked-list (queue) found off each task state structure. This results in real-time updates of coordinates or whatever the values are that are placed in the o.d.e. "state" vector. (A system task in the background integrates all the differential equations in all task ode queues by applying an adaptive step-size Runge-Kutta method. It interpolates to arrive at real-time, smooth timing. The algorithm doesn't normally yield uniform timing, so interpolation is used. Be aware that the derivative calculation routine will be called at times out-of-order with each other and is not sync'ed with real time.) //This is an alternative window manager. //It augments the existing one found //in $LK,"::/LT/ADAM/WINDOW.CPZ","FI:::/LT/ADAM/WINDOW.CPZ"$. It uses //the real-time differential equation //solver to reposition windows as though //they were repulsively charged particles. //I find this window manager to be a //novelty, not desirable for actual //use. You're welcome to add it, or //some variation to your start-up //scripts if you like it. It's not //fully debugged. //I had to cheat to make this work. //I added $LK,"CRTf_HAS_BEEN_RESIZED2","MN:CRTf_HAS_BEEN_RESIZED2"$ and //modified $LK,"::/LT/ADAM/WINDOW.CPZ","FI:::/LT/ADAM/WINDOW.CPZ"$. Ode *o=NULL; I8 tss_cnt=0; TssStruct *tss_map=NULL; void EndTsk() {
OdeDel(o); Free(tss_map); Exit; void MyDerivative(Ode *o,double t,Order2D3 *state,Order2D3 *DstateDt) {
double f,d,dd,dx,dy; MemSet(DstateDt,0,sizeof(Order2D3)*tss_cnt); for (i=0;i<tss_cnt;i++) {
DstateDt[i].y=state[i].DyDt; for (j=0;j<tss_cnt;j++) {
dx=state[i].x-state[j].x; dy=state[i].y-state[j].y; dd=Sqr(dx)+Sqr(dy)+1.0; d=Sqrt(dd);
dy/=d; //Square of the distance would be more //like a physics force, but this works //better.
DstateDt[i].DyDt+=f*dy; }
void WinMngTsk() {
I8 i,x,y,j,cnt; Order2D3 *tempo; TssStruct *tss; //This makes so this task doesn't get //swapped-out unless voluntarily. Preempt(OFF); Fs->end_task_cb=&EndTsk; while (TRUE) {
tss=Fs->next_tss; while (tss!=Fs) {
i=0; tss=Fs->next_tss; while (tss!=Fs) {
if (o) {
OdeDel(o); Free(tss_map);
o=OdeNew(cnt*sizeof(Order2D3)); tss_map=MAlloc(sizeof(U4)*cnt); i=0; tss=Fs->next_tss; while (tss!=Fs) {
tempo=o->state+sizeof(Order2D3)*i; tempo->x=(tss->window_left+tss->window_right) >>1; tempo->y=(tss->window_top+tss->window_bottom) >>1; tempo->z=0; tempo->DxDt=0; tempo->DyDt=0; tempo->DzDt=0; i++;
tss=tss->next_tss;
o->derivative=&MyDerivative; o->tolerance_start=.1; InsQue(o,Fs->last_ode);
Sleep(60); cnt=0; tss=Fs->next_tss; while (tss!=Fs) {
if (cnt==tss_cnt) {
i=0; tss=Fs->next_tss; while (tss!=Fs) {
same=FALSE;
for (i=0;i<tss_cnt;i++) {
tempo=o->state+sizeof(Order2D3)*i; x=tss->window_right-tss->window_left; y=tss->window_bottom-tss->window_top; if (Bt(&tss->crt_flags,CRTf_HAS_BEEN_RESIZED2)) {
>>1; tempo->y=(tss->window_top+tss->window_bottom) >>1; tempo->DxDt=0; tempo->DyDt=0;
j&=-4; if (j<4) j=4; if (j+x>tss->crt_width-12)
j=tempo->y-y>>1; if (j<2)
x=(tss->window_left+tss->window_right)>>1; y=(tss->window_top+tss->window_bottom)>>1; if (tempo->x>x+8)
Btr(&tss->crt_flags,CRTf_HAS_BEEN_RESIZED2);
Spawn(&WinMngTsk,"WINMGR2"); |
|||||