diff --git a/3dcam-tri-quads.c b/3dcam-tri-quads.c
index 60ed042..4b1ba0d 100644
--- a/3dcam-tri-quads.c
+++ b/3dcam-tri-quads.c
@@ -48,13 +48,6 @@
 
 #define FOV CENTERX                             // With a FOV of 1/2, camera focal length is ~= 16 mm / 90°
                                                 // Lower values mean wider angle
-// Camera frustum : 4:3 aspect ratio
-// normalized to 0-4096
-
-#define HH 3072  // half height == tan(90/2) == 1 
-
-#define HW 4096  // half width == HH * (4/3) ~= 1.333
-
 // pixel > cm : used in physics calculations
 
 #define SCALE 4
@@ -338,7 +331,7 @@ void callback();
 
 int main() {
     
-   VECTOR sp = {0,0,0};
+   VECTOR sp = {CENTERX,CENTERY,0};
    VECTOR wp = {0,0,0};
     
     // FIXME : Poly subdiv
@@ -420,6 +413,17 @@ int main() {
     
     setCameraPos(camPtr->campos->pos, camPtr->campos->rot);
     
+    // Find curCamAngle if using pre-calculated BGs
+    
+    if (camMode == 2) {                              
+          
+        if (camPtr->tim_data){
+    
+            curCamAngle = 1;
+    
+        }
+    }
+    
 	// Main loop
 	
     //~ while (1) {
@@ -576,31 +580,71 @@ int main() {
         // Fixed Camera angle
         if (camMode == 2) {                              
           
+          
+            // If BG images exist
+            
             if (camPtr->tim_data){
-                
-                //~ drawBG();
-                
-            //~ }
             
-                if ( actorPtr->pos2D.vx + actorPtr->body->max.vx / 2 > SCREENXRES ) { 
-            
-            
-            //~ if (curCamAngle > 4) {
+                if ( camAngles[ curCamAngle ]->fw.v0.vx ) {
+                    
+                    //~ FntPrint("v3 : %d, v2 : %d\n", camAngles[ curCamAngle ]->fw.v3.vx, camAngles[ curCamAngle ]->fw.v2.vx); 
+                    //~ FntPrint("v1 : %d, v2 : %d\n", camAngles[ curCamAngle ]->fw.v1.vy, camAngles[ curCamAngle ]->fw.v2.vy); 
 
-                //~ curCamAngle = 0;
+                    // If actor in camAngle->fw area of screen
+                    
+                    if ( actorPtr->pos2D.vx + CENTERX > camAngles[ curCamAngle ]->fw.v3.vx &&  
+                         
+                         actorPtr->pos2D.vx + CENTERX < camAngles[ curCamAngle ]->fw.v2.vx &&
+                         
+                         actorPtr->pos2D.vy + CENTERY > camAngles[ curCamAngle ]->fw.v3.vy &&  
+                         
+                         actorPtr->pos2D.vy + CENTERY < camAngles[ curCamAngle ]->fw.v2.vy
+                          
+                        ) { 
+                    
+                        if (curCamAngle < 5) {
 
-            //~ }
+                            curCamAngle++;
 
-                    if (curCamAngle < 5) {
+                            camPtr = camAngles[ curCamAngle ];
 
-                        curCamAngle++;
-
-                        camPtr = camAngles[ curCamAngle ];
-
-                        LoadTexture(camPtr->tim_data, camPtr->BGtim);
+                            LoadTexture(camPtr->tim_data, camPtr->BGtim);
 
+                        }
+                    
                     }
+                    
+                }
                 
+                if ( camAngles[ curCamAngle ]->bw.v0.vx ) {
+                    
+                    FntPrint("v3 : %d, v3 : %d\n", camAngles[ curCamAngle ]->bw.v3.vx, camAngles[ curCamAngle ]->bw.v3.vy); 
+                    FntPrint("v2 : %d, v2 : %d\n", camAngles[ curCamAngle ]->bw.v2.vx, camAngles[ curCamAngle ]->bw.v2.vy);
+                
+                    // If actor in camAngle->bw area of screen
+                    
+                    if ( actorPtr->pos2D.vx + CENTERX < camAngles[ curCamAngle ]->bw.v3.vx &&  
+                         
+                         actorPtr->pos2D.vx + CENTERX > camAngles[ curCamAngle ]->bw.v2.vx &&
+                    
+                         actorPtr->pos2D.vy + CENTERY < camAngles[ curCamAngle ]->bw.v3.vy &&  
+                     
+                         actorPtr->pos2D.vy + CENTERY > camAngles[ curCamAngle ]->bw.v2.vy
+                      
+                        ) { 
+            
+                        if (curCamAngle > 0) {
+
+                            curCamAngle--;
+
+                            camPtr = camAngles[ curCamAngle ];
+
+                            LoadTexture(camPtr->tim_data, camPtr->BGtim);
+
+                        }
+                    
+                    }
+                    
                 }
             
             }
@@ -732,7 +776,7 @@ int main() {
                 //~ FntPrint("Cam %d, %d, %d\n", camera.pos.vx, camera.pos.vy, camera.pos.vz);
                 //~ FntPrint("Pos: %d Cur: %d\nTheta y: %d x: %d\n", camPath.pos, camPath.cursor, theta.vy, theta.vx);
 
-                FntPrint("%d", camAngleToAct.vy);
+                //~ FntPrint("%d", camAngleToAct.vy);
 
                 if ( camAngleToAct.vy < -50 ) {  
           
@@ -786,7 +830,7 @@ int main() {
     
         //~ dt = time/180+1 - time/180;
         
-        // Spatial partitioning
+    // Spatial partitioning
         
         for ( int msh = 0; msh < curNode->siblings->index; msh ++ ) {
         
@@ -804,8 +848,8 @@ int main() {
                 }
             
             }
-            
-            //~ // Moveable prop
+        
+// FIXME !            //~ // Moveable prop
             
             //~ if (  !getIntCollision( *propPtr->body , *curNode->siblings->list[msh]->plane->body).vx &&
                   //~ !getIntCollision( *propPtr->body , *curNode->siblings->list[msh]->plane->body).vz ) {
@@ -901,8 +945,13 @@ int main() {
             // }
         }
         
-        worldToScreen(actorPtr->pos, &actorPtr->pos2D);
+        if ( (camMode == 2) && (camPtr->tim_data ) ) {
+      
+            worldToScreen(actorPtr->pos, &actorPtr->pos2D);
         
+        }
+
+    
     // Camera setup 
         
         // position of cam relative to actor
@@ -923,9 +972,9 @@ int main() {
                 
                 drawBG();
         
-                //~ // Loop on camAngles
+                // Loop on camAngles
         
-                    for ( int mesh = 0 ; mesh < camAngles[curCamAngle]->index; mesh ++ ) {
+                    for ( int mesh = 0 ; mesh < camAngles[ curCamAngle ]->index; mesh ++ ) {
                         
                         transformMesh(camAngles[curCamAngle]->objects[mesh]);
                         
@@ -933,6 +982,8 @@ int main() {
                         
                     }
                 
+                // Get screen coordinates of actor
+        
             //~ }
         }
         
@@ -987,7 +1038,7 @@ int main() {
         }
     
     }    
-        
+    
         // Find and apply light rotation matrix
 
         RotMatrix(&lgtang, &rotlgt);	
@@ -1006,17 +1057,14 @@ int main() {
 
         //~ FntPrint("CurNode : %x\nIndex: %d", curNode, curNode->siblings->index);
         
-        screenToWorld(&sp, &wp);
-        
         FntPrint("Time    : %d dt :%d\n", VSync(-1) / 60, dt);
+        FntPrint("%d\n", curCamAngle );
+        //~ FntPrint("Actor    : %d %d\n", actorPtr->pos->vx, actorPtr->pos->vy);
         
-        FntPrint("Actor    : %d %d\n", actorPtr->pos2D.vx + actorPtr->body->max.vx / 2, actorPtr->pos2D.vy);
+        FntPrint("%d %d\n", actorPtr->pos->vx, actorPtr->pos->vy);
+        FntPrint("%d %d\n", actorPtr->pos2D.vx + CENTERX, actorPtr->pos2D.vy + CENTERY);
         
-        //~ FntPrint("%d %d\n", actorPtr->pos->vx, actorPtr->pos2D.vx);
-        //~ FntPrint("%d %d\n", actorPtr->pos->vy, actorPtr->pos2D.vy);
-        //~ FntPrint("%d %d\n", actorPtr->pos->vz, actorPtr->pos2D.vz);
-        
-        FntPrint("%d - %d %d %d\n", sp.vx , wp.vx, wp.vy, wp.vz);
+        //~ FntPrint(" %d %d %d\n", wp.vx, wp.vy, wp.vz);
         
         FntFlush(-1);
 		
@@ -1091,8 +1139,8 @@ void init() {
 
 	FntLoad(FNT_POS_X, FNT_POS_Y);
 
-	FntOpen(16, 180, 240, 96, 0, 512);
-	
+	FntOpen(16, 90, 240, 180, 0, 512);
+
     // Lighting setup
     
     SetColorMatrix(&cmat);
@@ -1113,8 +1161,8 @@ void display(void){
 
     ResetGraph(1);
 
-
     PutDispEnv(&disp[db]);
+    
     PutDrawEnv(&draw[db]);
 
     SetDispMask(1);
@@ -1122,9 +1170,6 @@ void display(void){
     // Main OT
     DrawOTag(otdisc[db] + OT2LEN - 1);
     
-    // Secondary OT
-    //~ DrawOTag(ot[db] + OTLEN - 1);
-    
     db = !db;
 
     nextpri = primbuff[db];
@@ -1965,7 +2010,7 @@ VECTOR getVectorTo( VECTOR actor, VECTOR target ) {
 
 void worldToScreen( VECTOR * worldPos, VECTOR * screenPos ) {
 	
-    int	distToScreen; // corresponds to FOV
+    int	distToScreen;    // corresponds to FOV
 	
     MATRIX	curRot;      // current rotation matrix
 	
@@ -1977,53 +2022,68 @@ void worldToScreen( VECTOR * worldPos, VECTOR * screenPos ) {
 	
 	// Get Rotation, Translation coordinates, apply perspective correction
     
-    // Muliply world coordinates vector by current rotation matrix, store in s
+    // Muliply world coordinates vector by current rotation matrix, store in screenPos
     
 	ApplyMatrixLV(&curRot, worldPos, screenPos);
     
-    // Get world translation vectors from rot and add to s.vx, vy, vz
+    // Get world translation vectors from rot and add to screenPos vx, vy, vz
 	
     applyVector(screenPos, curRot.t[0], curRot.t[1], curRot.t[2], +=);
 	
     // Correct perspective
     
-    screenPos -> vz = distToScreen; // Start with vz to avoid division by 0 below
-    
-    screenPos -> vx = screenPos -> vx * distToScreen / ( screenPos -> vz );
+    screenPos -> vx = screenPos -> vx * distToScreen / ( screenPos -> vz + 1 ) ; // Add 1 to avoid division by 0
 	
-    screenPos -> vy = screenPos -> vy * distToScreen / ( screenPos -> vz ); 
+    screenPos -> vy = screenPos -> vy * distToScreen / ( screenPos -> vz + 1 ) ; 
+    
+    screenPos -> vz = distToScreen ;
     
 };
 
 void screenToWorld( VECTOR * screenPos, VECTOR * worldPos ) {
 	
-    int	distToScreen; // corresponds to FOV
+    int	distToScreen;           // corresponds to FOV
 	
-    MATRIX	curRot, rotT;      // current rotation matrix
+    MATRIX	curRot, invRot;    // current rotation matrix, transpose matrix
 	
-    VECTOR curTrans;
+    VECTOR Trans;               // working translation vector
     
-	// Get current matrix and projection */
+	// Get current matrix and projection
     
 	distToScreen = ReadGeomScreen();	
 
-	ReadRotMatrix(&curRot);
+	ReadRotMatrix( &curRot );
 
-    PushMatrix();
+    PushMatrix();               // Store matrix on the stack (slow!)
 	
-    // Get current translation
+    //// worldTrans = invRot * (screenPos - Rot.t)
     
-    curTrans.vx = screenPos->vx - curRot.t[0];
-
-    curTrans.vy = screenPos->vy - curRot.t[1];
-
-    curTrans.vz = screenPos->vz - curRot.t[2];
-
-    TransposeMatrix(&curRot, &rotT);
+    // Get world translation
     
-    // 
+    Trans.vx = screenPos->vx - curRot.t[0]; // Substract world translation from screenpos
+
+    Trans.vy = screenPos->vy - curRot.t[1];
+
+    Trans.vz = screenPos->vz - curRot.t[2];
     
-    ApplyMatrixLV(&rotT, &curTrans, worldPos);
+    
+    // We want the inverse of the current rotation matrix.
+    //
+    // Inverse matrix : M^-1 = 1 / detM * T(M)
+    // We know that the determinant of a rotation matrix is 1, thus:
+    // M^-1 = T(M) 
+    //
+    // Get transpose of current rotation matrix
+    // > The transpose of a matrix is a new matrix whose rows are the columns of the original.
+    // https://www.quora.com/What-is-the-geometric-interpretation-of-the-transpose-of-a-matrix
+    
+    TransposeMatrix( &curRot, &invRot );
+
+    // Multiply the transpose of current rotation matrix by the current translation vector
+    
+    ApplyMatrixLV( &invRot, &Trans, worldPos );
+    
+    // Get original rotation matrix back
     
     PopMatrix();