aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorVincent Hamm2007-04-27 12:58:35 +0000
committerVincent Hamm2007-04-27 12:58:35 +0000
commitc01aa37caaadb2e65667b1156a907e92e859fee8 (patch)
tree5c55328c78f6f1664f4f46baadee583fcff977ef /engines
parentedd9b31a483c07066537663a01c265d99d69ada7 (diff)
downloadscummvm-rg350-c01aa37caaadb2e65667b1156a907e92e859fee8.tar.gz
scummvm-rg350-c01aa37caaadb2e65667b1156a907e92e859fee8.tar.bz2
scummvm-rg350-c01aa37caaadb2e65667b1156a907e92e859fee8.zip
Add cruise source code for scummvm
svn-id: r26605
Diffstat (limited to 'engines')
-rw-r--r--engines/cruise/actor.cpp1080
-rw-r--r--engines/cruise/actor.h74
-rw-r--r--engines/cruise/background.cpp220
-rw-r--r--engines/cruise/background.h46
-rw-r--r--engines/cruise/backgroundIncrust.cpp222
-rw-r--r--engines/cruise/backgroundIncrust.h66
-rw-r--r--engines/cruise/cruise.cpp111
-rw-r--r--engines/cruise/cruise.h107
-rw-r--r--engines/cruise/cruise_main.cpp1688
-rw-r--r--engines/cruise/cruise_main.h101
-rw-r--r--engines/cruise/ctp.cpp423
-rw-r--r--engines/cruise/ctp.h64
-rw-r--r--engines/cruise/dataLoader.cpp532
-rw-r--r--engines/cruise/dataLoader.h38
-rw-r--r--engines/cruise/decompiler.cpp1549
-rw-r--r--engines/cruise/delphine-unpack.cpp176
-rw-r--r--engines/cruise/detection.cpp112
-rw-r--r--engines/cruise/font.cpp745
-rw-r--r--engines/cruise/font.h49
-rw-r--r--engines/cruise/fontCharacterTable.cpp195
-rw-r--r--engines/cruise/fontCharacterTable.h35
-rw-r--r--engines/cruise/function.cpp1718
-rw-r--r--engines/cruise/function.h39
-rw-r--r--engines/cruise/gfxModule.cpp657
-rw-r--r--engines/cruise/gfxModule.h72
-rw-r--r--engines/cruise/linker.cpp330
-rw-r--r--engines/cruise/linker.h34
-rw-r--r--engines/cruise/loadSave.cpp471
-rw-r--r--engines/cruise/loadSave.h34
-rw-r--r--engines/cruise/mainDraw.cpp1142
-rw-r--r--engines/cruise/mainDraw.h48
-rw-r--r--engines/cruise/menu.cpp321
-rw-r--r--engines/cruise/menu.h49
-rw-r--r--engines/cruise/mouse.cpp51
-rw-r--r--engines/cruise/mouse.h37
-rw-r--r--engines/cruise/object.cpp519
-rw-r--r--engines/cruise/object.h94
-rw-r--r--engines/cruise/overlay.cpp772
-rw-r--r--engines/cruise/overlay.h217
-rw-r--r--engines/cruise/perso.cpp260
-rw-r--r--engines/cruise/perso.h56
-rw-r--r--engines/cruise/polys.cpp323
-rw-r--r--engines/cruise/polys.h32
-rw-r--r--engines/cruise/script.cpp861
-rw-r--r--engines/cruise/script.h73
-rw-r--r--engines/cruise/stack.cpp85
-rw-r--r--engines/cruise/stack.h61
-rw-r--r--engines/cruise/stringSupport.cpp49
-rw-r--r--engines/cruise/stringSupport.h37
-rw-r--r--engines/cruise/various.cpp187
-rw-r--r--engines/cruise/various.h43
-rw-r--r--engines/cruise/vars.cpp182
-rw-r--r--engines/cruise/vars.h340
-rw-r--r--engines/cruise/volume.cpp518
-rw-r--r--engines/cruise/volume.h45
55 files changed, 17390 insertions, 0 deletions
diff --git a/engines/cruise/actor.cpp b/engines/cruise/actor.cpp
new file mode 100644
index 0000000000..35c852a82a
--- /dev/null
+++ b/engines/cruise/actor.cpp
@@ -0,0 +1,1080 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cruise/cruise.h"
+
+namespace Cruise {
+
+int16 mainProc13(int overlayIdx, int param1, actorStruct* pStartEntry, int param2)
+{
+ actorStruct* pCurrentEntry = pStartEntry->next;
+
+ while(pCurrentEntry)
+ {
+ if( (pCurrentEntry->overlayNumber == overlayIdx || overlayIdx == -1) &&
+ (pCurrentEntry->var4 == param1 || param1 == -1) &&
+ (pCurrentEntry->type == param2 || param2 == -1) &&
+ (pCurrentEntry->pathId != -2))
+ {
+ return 0;
+ }
+
+ pCurrentEntry = pCurrentEntry->next;
+ }
+
+ return 1;
+}
+
+actorStruct* findActor(int overlayIdx, int param1, actorStruct* pStartEntry, int param2)
+{
+ actorStruct* pCurrentEntry = pStartEntry->next;
+
+ while(pCurrentEntry)
+ {
+ if( (pCurrentEntry->overlayNumber == overlayIdx || overlayIdx == -1) &&
+ (pCurrentEntry->var4 == param1 || param1 == -1) &&
+ (pCurrentEntry->type == param2 || param2 == -1) )
+ {
+ return pCurrentEntry;
+ }
+
+ pCurrentEntry = pCurrentEntry->next;
+ }
+
+ return NULL;
+}
+
+int nclick_noeud;
+int flag_aff_chemin;
+
+void getPixel(int x, int y)
+{
+ int x_min, x_max, y_min, y_max;
+
+ ctpVar19Struct *polygone;
+ ctpVar19SubStruct *tableau;
+
+ polygone = ctpVar19; /* adr structure polygone */
+
+ while ( polygone->field_0 != (ctpVar19Struct*)-1)
+ {
+ tableau = &polygone->subStruct;
+
+ x_min = tableau->minX;
+ x_max = tableau->maxX;
+ y_min = tableau->minY;
+ y_max = tableau->maxY;
+
+ computedVar14 = tableau->boxIdx; /* numero polygone */
+
+ if ( walkboxChange[computedVar14]==0 && ((x>=x_min && x<=x_max) && (y>=y_min && y<=y_max)) )
+ {
+ // click was in given box
+ /* u = y-y_min;
+
+ //tableau+=u;
+ tableau = &polygone[u].subStruct;
+
+ x_min = tableau->minX;
+ x_max = tableau->maxX;
+
+ if ( (x>=x_min && x<=x_max) ) */
+ {
+ flag_obstacle=walkboxType[computedVar14]; /* sa couleur */
+
+ return;
+ }
+ }
+ polygone = polygone->field_0;
+ }
+
+ flag_obstacle=0;
+}
+
+int x_mouse;
+int y_mouse;
+
+int point_select;
+
+int table_ptselect[2][2];
+
+int X;
+int Y;
+
+int modelVar9;
+int modelVar10;
+
+void polydroite(int x1, int y1, int x2, int y2)
+{
+ int dx;
+ int dy;
+
+ int mD0;
+ int mD1;
+
+ int mA0;
+ int mA1;
+
+ int bp;
+ int cx;
+ int si;
+
+ int ax;
+ int bx;
+
+ modelVar9 = x1;
+ modelVar10 = y1;
+
+ dx = x2-x1;
+ dy = y2-y1;
+
+ mD0 = mD1 = 1;
+
+ if(dx<0)
+ {
+ dx = -dx;
+ mD0 = -1;
+ }
+
+ if(dy<0)
+ {
+ dy = -dy;
+ mD1 = -1;
+ }
+
+ if(dx<dy)
+ {
+ mA0 = 0;
+ bp = dx;
+ cx = dy;
+
+ mA1 = mD1;
+ }
+ else
+ {
+ mA1 = 0;
+ bp = dy;
+ cx = dx;
+
+ mA0 = mD0;
+ }
+
+ bp=bp*2;
+ dx=bp-cx;
+ si=dx-cx;
+
+ ax = modelVar9;
+ bx = modelVar10;
+
+ getPixel(modelVar9, modelVar10);
+
+ X = modelVar9;
+ Y = modelVar10;
+
+ if(flag_obstacle==0)
+ {
+ flag_obstacle = 1;
+ return;
+ }
+
+ while(--cx)
+ {
+ if(dx>0)
+ {
+ ax+=mD0;
+ bx+=mD1;
+ dx+=si;
+ }
+ else
+ {
+ ax+=mA0;
+ bx+=mA1;
+ dx+=bp;
+ }
+
+ getPixel(ax, bx);
+
+ X = ax;
+ Y = bx;
+
+ if(flag_obstacle==0)
+ {
+ flag_obstacle = 1;
+ return;
+ }
+ }
+
+ flag_obstacle = 0;
+}
+
+void poly2(int x1, int y1, int x2, int y2)
+{
+ int dx;
+ int dy;
+
+ int mD0;
+ int mD1;
+
+ int mA0;
+ int mA1;
+
+ int bp;
+ int cx;
+ int si;
+
+ int ax;
+ int bx;
+
+ modelVar9 = x1;
+ modelVar10 = y1;
+
+ dx = x2-x1;
+ dy = y2-y1;
+
+ mD0 = mD1 = 1;
+
+ if(dx<0)
+ {
+ dx = -dx;
+ mD0 = -1;
+ }
+
+ if(dy<0)
+ {
+ dy = -dy;
+ mD1 = -1;
+ }
+
+ if(dx<dy)
+ {
+ mA0 = 0;
+ bp = dx;
+ cx = dy;
+
+ mA1 = mD1;
+ }
+ else
+ {
+ mA1 = 0;
+ bp = dy;
+ cx = dx;
+
+ mA0 = mD0;
+ }
+
+ bp=bp*2;
+ dx=bp-cx;
+ si=dx-cx;
+
+ ax = modelVar9;
+ bx = modelVar10;
+
+ getPixel(modelVar9, modelVar10);
+
+ X = modelVar9;
+ Y = modelVar10;
+
+ if(flag_obstacle!=0)
+ {
+ flag_obstacle = 1;
+ return;
+ }
+
+ while(--cx)
+ {
+ if(dx>0)
+ {
+ ax+=mD0;
+ bx+=mD1;
+ dx+=si;
+ }
+ else
+ {
+ ax+=mA0;
+ bx+=mA1;
+ dx+=bp;
+ }
+
+ getPixel(ax, bx);
+
+ X = ax;
+ Y = bx;
+
+ if(flag_obstacle!=0)
+ {
+ flag_obstacle = 1;
+ return;
+ }
+ }
+
+ flag_obstacle = 0;
+}
+
+int point_proche( int16 table[][2] )
+{
+ int x1, y1, i, x, y, p;
+ int d1=1000;
+
+ ctpVar19 = ctpVar11;
+
+ if ( nclick_noeud == 1 )
+ {
+ x = x_mouse;
+ y = y_mouse;
+ x1 = table_ptselect[0][0];
+ y1 = table_ptselect[0][1];
+
+ ctpVar19 = ctpVar15;
+
+ getPixel( x, y );
+
+ if ( !flag_obstacle )
+ {
+ ctpVar19 = ctpVar11;
+
+ getPixel( x, y );
+
+ if ( flag_obstacle )
+ {
+ polydroite( x1, y1, x, y );
+ }
+ ctpVar19 = ctpVar15;
+ }
+ if ( !flag_obstacle ) /* dans flag_obstacle --> couleur du point */
+ {
+ x1 = table_ptselect[0][0];
+ y1 = table_ptselect[0][1];
+
+ poly2( x, y, x1, y1 );
+
+ x_mouse = X;
+ y_mouse = Y;
+ }
+ }
+ ctpVar19 = ctpVar11;
+
+ p = -1;
+ for ( i=0; i < ctp_routeCoordCount; i++ )
+ {
+ x = table[i][0];
+ y = table[i][1];
+
+ ctpProc2( x_mouse, y_mouse, x, y );
+ if ( ctpVar14 < d1 )
+ {
+ polydroite( x_mouse, y_mouse, x, y );
+
+ if ( !flag_obstacle && ctp_routes[i][0] > 0 )
+ {
+ d1 = ctpVar14;
+ p = i;
+ }
+ }
+ }
+
+ return ( p );
+}
+
+#define NBNOEUD 20
+
+int16 select_noeud[3];
+char solution[20+1];
+
+int prem;
+int prem2;
+int dist_chemin;
+int idsol;
+int solmax;
+
+char fl[NBNOEUD+1];
+char sol[NBNOEUD+1];
+char Fsol[NBNOEUD+1];
+
+int D;
+
+void explore( int depart, int arrivee )
+{
+ int id1, id2, i;
+
+ id1 = depart;
+
+ fl[id1]++;
+ sol[idsol++] = (char)id1;
+
+ if ( idsol > solmax )
+ {
+ fl[id1]=-1;
+ idsol--;
+
+ return;
+ }
+
+ while ( (i=fl[id1]) < 20 )
+ {
+ id2 = ctp_routes[id1][i+1];
+
+ if ( id2 == arrivee )
+ {
+ if ( idsol < solmax )
+ {
+ sol[idsol] = (char)arrivee;
+ D=0;
+ for ( i=0; i < idsol; i++ )
+ {
+ D = D+ctp_routeCoords[sol[i]][sol[i+1]];
+ Fsol[i]=sol[i];
+ }
+ prem2=0;
+ if (!prem)
+ {
+ dist_chemin = D;
+ prem = 1;
+ for ( i=0; i <= idsol; i++ )
+ {
+ solution[i] = sol[i];
+ }
+ solution[i++]=-1;
+ solution[i]=-1;
+ }
+ else if ( D < dist_chemin )
+ {
+ dist_chemin = D;
+ for ( i=0; i <= idsol; i++ )
+ {
+ solution[i] = sol[i];
+ }
+ solution[i++]=-1;
+ solution[i]=-1;
+ }
+ }
+ fl[id1]=-1;
+ idsol--;
+
+ return;
+ }
+ else if ((id2!=-1) && ((int)fl[id2]==-1) )
+ explore(id2,arrivee);
+ else if (id2==-1)
+ {
+ fl[id1]=-1;
+ idsol--;
+
+ return;
+ }
+ fl[id1]++;
+ }
+
+ fl[id1]=-1;
+ idsol--;
+}
+
+void chemin0( int depart, int arrivee )
+{
+ int i;
+ int y=30;
+
+ prem = 0;
+ prem2 = 0;
+ dist_chemin=0;
+ idsol = 0;
+ solmax=999;
+
+ for ( i=0; i < 20+1; i++ ) fl[i] = -1;
+
+ X=0,Y=30;
+
+ explore( depart, arrivee );
+}
+
+void valide_noeud( int16 table[], int16 p, int *nclick, int16 solution0[20+3][2] )
+{
+ int a, b, d, i, p1, x1, x2, y1, y2;
+ int y=30;
+
+ table[*nclick]=p;
+ table[(*nclick)+1]=-1;
+ table_ptselect[*nclick][0]=x_mouse;
+ table_ptselect[*nclick][1]=y_mouse;
+ (*nclick)++;
+ ctpVar19=ctpVar11;
+
+ if (*nclick==2) // second point
+ {
+ x1=table_ptselect[0][0];
+ y1=table_ptselect[0][1];
+ x2=table_ptselect[1][0];
+ y2=table_ptselect[1][1];
+ if ( (x1==x2) && (y1==y2))
+ {
+ return;
+ }
+ flag_aff_chemin=1;
+ ctpVar19=ctpVar15;
+
+ // can we go there directly ?
+ polydroite(x1,y1,x2,y2);
+ ////////////////
+ flag_obstacle = 0;
+ ////////////////
+ if (!flag_obstacle)
+ {
+ solution0[0][0]=x1;
+ solution0[0][1]=y1;
+ ctpVar19=ctpVar15;
+
+ poly2(x2,y2,ctp_routeCoords[select_noeud[1]][0],ctp_routeCoords[select_noeud[1]][1]);
+
+ solution0[1][0]=table_ptselect[1][0]=X;
+ solution0[1][1]=table_ptselect[1][1]=Y;
+ solution0[2][0]=-1;
+
+ if ( (x1==X) && (y1==Y))
+ {
+ flag_aff_chemin=0;
+ return;
+ }
+ }
+ else
+ {
+ // no, we take the fastest way
+ solution[0]=-1;
+ if (ctp_routes[select_noeud[0]][0]>0)
+ chemin0(table[0],table[1]);
+
+ if (solution[0]==-1)
+ {
+ x1=table_ptselect[0][0];
+ y1=table_ptselect[0][1];
+ polydroite(x1,y1,x_mouse,y_mouse);
+ solution0[0][0]=x1;
+ solution0[0][1]=y1;
+ solution0[1][0]=X;
+ solution0[1][1]=Y;
+
+ solution0[2][0]=-1;
+ if ( (x1==X) && (y1==Y))
+ {
+ flag_aff_chemin=0;
+ return;
+ }
+ }
+ else
+ {
+ solution0[0][0]=x1;
+ solution0[0][1]=y1;
+ i=0;
+ while (solution[i]!=-1)
+ {
+ p1=solution[i];
+ solution0[i+1][0]=ctp_routeCoords[p1][0];
+ solution0[++i][1]=ctp_routeCoords[p1][1];
+ }
+ ctpVar19=ctpVar15;
+ poly2(x2,y2,ctp_routeCoords[select_noeud[1]][0],ctp_routeCoords[select_noeud[1]][1]);
+ solution0[i+1][0]=table_ptselect[1][0]=X;
+ solution0[i+1][1]=table_ptselect[1][1]=Y;
+ solution0[i+2][0]=-1;
+ if ( (x1==X) && (y1==Y))
+ {
+ flag_aff_chemin=0;
+ return;
+ }
+
+ /****** COUPE LE CHEMIN ******/
+
+ i++;
+ d=0;
+ a=i;
+ flag_obstacle=1;
+ while (d!=a)
+ {
+ x1=solution0[d][0];
+ y1=solution0[d][1];
+
+ while (flag_obstacle && i!=d)
+ {
+ x2=solution0[i][0];
+ y2=solution0[i][1];
+ ctpVar19=ctpVar15;
+ polydroite(x1,y1,x2,y2);
+ i--;
+ }
+ flag_obstacle=1;
+ if (d!=i)
+ {
+ i++;
+ for (b=d+1;b<i;b++)
+ {
+ solution0[b][0]=-2;
+ }
+ }
+ else i++;
+ d=i;
+ i=a;
+ }
+ flag_obstacle=0;
+ }
+ }
+ }
+}
+
+//computePathfinding(returnVar2, params.X, params.Y, var34, var35, currentActor->stepX, currentActor->stepY);
+int16 computePathfinding(int16* pSolution, int16 X, int16 Y, int16 destX, int16 destY, int16 stepX, int16 stepY, int16 oldPathId)
+{
+ persoStruct* perso;
+ int num;
+
+ if(!polyStruct)
+ {
+ pSolution[0] = -1;
+ pSolution[1] = -1;
+
+ return -1;
+ }
+
+ if(oldPathId >= 0)
+ {
+ if(persoTable[oldPathId])
+ {
+ freePerso(oldPathId);
+ }
+ }
+
+ if(!flagCt)
+ {
+ int i;
+ int16* ptr;
+
+ for(i=0;i<10;i++) // 10 = num perso
+ {
+ if(!persoTable[i])
+ {
+ break;
+ }
+ }
+
+ if(i == 10)
+ {
+ pSolution[0] = -1;
+ pSolution[1] = -1;
+
+ return -1;
+ }
+
+ perso = persoTable[i] = (persoStruct*)malloc(sizeof(persoStruct));
+
+ ptr = perso->solution[0];
+
+ perso->inc_jo1 = stepX;
+ perso->inc_jo2 = stepY;
+
+ *(ptr++) = X;
+ *(ptr++) = Y;
+ *(ptr++) = pSolution[0] = destX;
+ *(ptr++) = pSolution[1] = destY;
+ *(ptr++) = -1;
+
+ pSolution[4] = computedVar14;
+
+ perso->inc_droite = 0;
+ perso->inc_chemin = 0;
+
+ return i;
+ }
+
+ nclick_noeud=0;
+ ctpVar19=ctpVar11;
+ flag_aff_chemin=0;
+
+ if (X==destX && Y==destY)
+ {
+ pSolution[0]=-1;
+ pSolution[1]=-1;
+
+ return(-1);
+ }
+
+/******* cherche le premier noeud ******/
+
+ getPixel(X,Y);
+
+ pSolution[4] = computedVar14;
+
+ x_mouse = X;
+ y_mouse = Y;
+
+ if (!flag_obstacle || (point_select=point_proche(ctp_routeCoords))==-1)
+ {
+ pSolution[0]=-1;
+ pSolution[1]=-1;
+
+ return(-1);
+ }
+
+ valide_noeud(select_noeud,point_select,&nclick_noeud,NULL);
+
+ flag_aff_chemin=0;
+
+/******* cherche le deuxieme noeud ******/
+
+ num=0;
+ while ( num < 10 && persoTable[num] != NULL ) num++;
+
+ if (num==10)
+ {
+ pSolution[0]=-1;
+ pSolution[1]=-1;
+ return(-1);
+ }
+
+ perso = persoTable[num] = (persoStruct*)malloc(sizeof(persoStruct));
+
+ perso->inc_jo1 = stepX;
+ perso->inc_jo2 = stepY;
+
+ x_mouse = destX;
+ y_mouse = destY;
+
+ if((point_select=point_proche(ctp_routeCoords))!=-1)
+ valide_noeud(select_noeud,point_select,&nclick_noeud,perso->solution);
+
+ if ( (!flag_aff_chemin) || ((table_ptselect[0][0]==table_ptselect[1][0]) && (table_ptselect[0][1]==table_ptselect[1][1]) ))
+ {
+ pSolution[0]=-1;
+ pSolution[1]=-1;
+ freePerso(num);
+
+ return(-1);
+ }
+
+ pSolution[0]=table_ptselect[1][0];
+ pSolution[1]=table_ptselect[1][1];
+ pSolution[4]=computedVar14;
+ perso->inc_chemin=0;
+ perso->inc_droite=0;
+
+ return (num);
+}
+
+void set_anim( int ovl, int obj, int start, int x, int y, int mat, int state )
+{
+ int newf, zoom;
+
+ newf = abs(mat)-1;
+
+ zoom = subOp22(y);
+ if (mat<0) zoom=-zoom;
+
+ setObjectPosition(ovl,obj,0, x);
+ setObjectPosition(ovl,obj,1, y);
+ setObjectPosition(ovl,obj,2, y);
+ setObjectPosition(ovl,obj,4, zoom);
+ setObjectPosition(ovl,obj,3, newf+start);
+ setObjectPosition(ovl,obj,5, state);
+}
+
+int raoul_move[][13] =
+{
+ { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0 }, /* dos */
+ { 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 0 }, /* droite */
+ { 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 0 }, /* face */
+ {-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-24, 0 } /* gauche */
+};
+
+int raoul_end[][13] =
+{
+ { 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* stat dos */
+ { 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* stat droite */
+ { 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* stat face */
+ {-38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* stat gauche */
+};
+
+int raoul_stat[][13]=
+{
+ { 53, 54, 55, 56, 57, 0, 0, 0, 0, 0, 0, 0, 0 }, /* ret dos-dr */
+ { 59, 60, 62, 63, 78, 0, 0, 0, 0, 0, 0, 0, 0 }, /* ret dr-face */
+ {-78,-63,-62,-60,-59, 0, 0, 0, 0, 0, 0, 0, 0 }, /* ret face-ga */
+ {-57,-56,-55,-54,-53, 0, 0, 0, 0, 0, 0, 0, 0 } /* ret ga-dos */
+};
+
+int raoul_invstat[][13]=
+{
+ {-53,-54,-55,-56,-57, 0, 0, 0, 0, 0, 0, 0, 0 }, /* ret dos-dr */
+ { 57, 56, 55, 54, 53, 0, 0, 0, 0, 0, 0, 0, 0 }, /* ret ga-dos */
+ { 78, 63, 62, 60, 59, 0, 0, 0, 0, 0, 0, 0, 0 }, /* ret face-ga */
+ {-59,-60,-62,-63,-78, 0, 0, 0, 0, 0, 0, 0, 0 } /* ret dr-face */
+
+};
+
+void processActors(void)
+{
+ objectParamsQuery params;
+ int16 returnVar2[5];
+ actorStruct* currentActor = &actorHead;
+
+ while(currentActor->next)
+ {
+ currentActor = currentActor->next;
+
+ if(!currentActor->freeze && ((currentActor->type == 0) || (currentActor->type == 1)))
+ {
+ getMultipleObjectParam(currentActor->overlayNumber,currentActor->var4,&params);
+
+ if(((animationStart && !currentActor->flag) || (!animationStart && currentActor->x_dest != -1 && currentActor->y_dest != -1)) && (currentActor->type == 0))
+ {
+ // mouse animation
+ if(!animationStart)
+ {
+ var34 = currentActor->x_dest;
+ var35 = currentActor->y_dest;
+
+ currentActor->x_dest = -1;
+ currentActor->y_dest = -1;
+
+ currentActor->flag = 1;
+ }
+
+ currentActor->pathId = computePathfinding(returnVar2, params.X, params.Y, var34, var35, currentActor->stepX, currentActor->stepY, currentActor->pathId);
+
+ if(currentActor->pathId == -1)
+ {
+ if((currentActor->endDirection != -1) && (currentActor->endDirection != currentActor->startDirection))
+ {
+ currentActor->phase = ANIM_PHASE_STATIC_END;
+ currentActor->nextDirection = currentActor->endDirection;
+ currentActor->endDirection = -1;
+ currentActor->counter = 0;
+ }
+ else
+ {
+ currentActor->pathId = -2;
+ currentActor->flag = 0;
+ currentActor->endDirection = -1;
+ currentActor->phase = ANIM_PHASE_WAIT;
+ }
+ }
+ else
+ {
+ currentActor->phase = ANIM_PHASE_STATIC;
+ currentActor->counter = -1;
+ }
+ }
+ else
+ if((currentActor->type == 1) && (currentActor->x_dest != -1) && (currentActor->y_dest != -1))
+ {
+ // track animation
+ currentActor->pathId = computePathfinding(returnVar2, params.X, params.Y, currentActor->x_dest, currentActor->y_dest, currentActor->stepX, currentActor->stepY, currentActor->pathId);
+
+ currentActor->x_dest = -1;
+ currentActor->y_dest = -1;
+
+ if(currentActor->pathId == -1)
+ {
+ if((currentActor->endDirection != -1) && (currentActor->endDirection != currentActor->startDirection))
+ {
+ currentActor->phase = ANIM_PHASE_STATIC_END;
+ currentActor->nextDirection = currentActor->endDirection;
+ currentActor->endDirection = -1;
+ currentActor->counter = 0;
+ }
+ else
+ {
+ currentActor->pathId = -2;
+ currentActor->flag = 0;
+ currentActor->endDirection = -1;
+ currentActor->phase = ANIM_PHASE_WAIT;
+ }
+ }
+ else
+ {
+ currentActor->phase = ANIM_PHASE_STATIC;
+ currentActor->counter = -1;
+ }
+ }
+
+ animationStart = 0;
+
+ if(currentActor->pathId >= 0 || currentActor->phase == ANIM_PHASE_STATIC_END)
+ {
+ switch(currentActor->phase)
+ {
+ case ANIM_PHASE_STATIC_END:
+ case ANIM_PHASE_STATIC:
+ {
+ if(currentActor->counter == -1 && currentActor->phase == ANIM_PHASE_STATIC)
+ {
+ affiche_chemin(currentActor->pathId, returnVar2);
+
+ if(returnVar2[0] == -1)
+ {
+ currentActor->pathId = -2;
+ currentActor->flag = 0;
+ currentActor->endDirection = -1;
+ currentActor->phase = ANIM_PHASE_WAIT;
+ break;
+ }
+
+ currentActor->x = returnVar2[0];
+ currentActor->y = returnVar2[1];
+ currentActor->nextDirection = returnVar2[2];
+ currentActor->poly = returnVar2[4];
+ currentActor->counter = 0;
+
+ if (currentActor->startDirection == currentActor->nextDirection)
+ currentActor->phase = ANIM_PHASE_MOVE;
+ }
+
+ if ((currentActor->counter>=0) && ((currentActor->phase==ANIM_PHASE_STATIC_END) || (currentActor->phase==ANIM_PHASE_STATIC)))
+ {
+ int newA;
+ int inc = 1;
+ int t_inc = currentActor->startDirection-1;
+
+ if (t_inc<0)
+ t_inc=3;
+
+ if (currentActor->nextDirection==t_inc)
+ inc=-1;
+
+ if (inc>0)
+ newA = raoul_stat[currentActor->startDirection][currentActor->counter++];
+ else
+ newA = raoul_invstat[currentActor->startDirection][currentActor->counter++];
+
+ if (newA==0)
+ {
+ currentActor->startDirection = currentActor->startDirection+inc;
+
+ if (currentActor->startDirection>3)
+ currentActor->startDirection=0;
+
+ if (currentActor->startDirection<0)
+ currentActor->startDirection=3;
+
+ currentActor->counter=0;
+
+ if (currentActor->startDirection==currentActor->nextDirection)
+ {
+ if (currentActor->phase == ANIM_PHASE_STATIC)
+ currentActor->phase = ANIM_PHASE_MOVE;
+ else
+ currentActor->phase = ANIM_PHASE_END;
+ }
+ else
+ {
+ newA = raoul_stat[currentActor->startDirection][currentActor->counter++];
+
+ if (inc==-1)
+ newA=-newA;
+
+ set_anim(currentActor->overlayNumber,currentActor->var4,currentActor->start,params.X,params.Y,newA,currentActor->poly);
+ break;
+ }
+ }
+ else
+ {
+ set_anim(currentActor->overlayNumber,currentActor->var4,currentActor->start,params.X,params.Y,newA,currentActor->poly);
+ break;
+ }
+ }
+ break;
+ }
+ case ANIM_PHASE_MOVE:
+ {
+ if (currentActor->counter>=1)
+ {
+ affiche_chemin(currentActor->pathId,returnVar2);
+ if (returnVar2[0]==-1)
+ {
+ if ((currentActor->endDirection==-1) || (currentActor->endDirection==currentActor->nextDirection))
+ {
+ currentActor->phase=ANIM_PHASE_END;
+ }
+ else
+ {
+ currentActor->phase = ANIM_PHASE_STATIC_END;
+ currentActor->nextDirection=currentActor->endDirection;
+ }
+ currentActor->counter=0;
+ break;
+ }
+ else
+ {
+ currentActor->x = returnVar2[0];
+ currentActor->y = returnVar2[1];
+ currentActor->nextDirection = returnVar2[2];
+ currentActor->poly = returnVar2[4];
+
+ /*
+ if (pl->next_dir!=pl->start_dir)
+ {
+ pl->phase=PHASE_STATIC;
+ pl->cnt=0;
+ break;
+ }
+ */
+ }
+ }
+
+ if (currentActor->phase==ANIM_PHASE_MOVE)
+ {
+ int newA;
+
+ currentActor->startDirection = currentActor->nextDirection;
+
+ newA = raoul_move[currentActor->startDirection][currentActor->counter++];
+ if (!newA)
+ {
+ currentActor->counter=0;
+ newA = raoul_move[currentActor->startDirection][currentActor->counter++];
+ }
+ set_anim(currentActor->overlayNumber,currentActor->var4,currentActor->start,currentActor->x,currentActor->y,newA,currentActor->poly);
+ break;
+ }
+
+ break;
+ }
+ case ANIM_PHASE_END:
+ {
+ int newA = raoul_end[currentActor->startDirection][0];
+
+ set_anim(currentActor->overlayNumber,currentActor->var4,currentActor->start,currentActor->x,currentActor->y,newA,currentActor->poly);
+
+ currentActor->pathId = -2;
+ currentActor->phase=ANIM_PHASE_WAIT;
+ currentActor->flag=0;
+ currentActor->endDirection=-1;
+ break;
+ }
+ default:
+ {
+ printf("Unimplemented currentActor->phase=%d in processActors()\n", currentActor->phase);
+ // exit(1);
+ }
+ }
+ }
+ }
+ }
+}
+} // End of namespace Cruise \ No newline at end of file
diff --git a/engines/cruise/actor.h b/engines/cruise/actor.h
new file mode 100644
index 0000000000..57db753460
--- /dev/null
+++ b/engines/cruise/actor.h
@@ -0,0 +1,74 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef _ACTOR_H_
+#define _ACTOR_H_
+
+namespace Cruise {
+
+enum animPhase
+{
+ ANIM_PHASE_WAIT = 0,
+ ANIM_PHASE_STATIC = 1,
+ ANIM_PHASE_MOVE = 2,
+ ANIM_PHASE_STATIC_END = 3,
+ ANIM_PHASE_END = 4,
+};
+
+typedef enum animPhase animPhase;
+
+struct actorStruct {
+ struct actorStruct* next;
+ struct actorStruct* prev;
+
+ int16 var4;
+ int16 type;
+ int16 overlayNumber;
+ int16 x_dest;
+ int16 y_dest;
+ int16 x;
+ int16 y;
+ int16 startDirection;
+ int16 nextDirection;
+ int16 endDirection;
+ int16 stepX;
+ int16 stepY;
+ int16 pathId;
+ animPhase phase;
+ int16 counter;
+ int16 poly;
+ int16 flag;
+ int16 start;
+ int16 freeze;
+};
+
+typedef struct actorStruct actorStruct;
+
+int16 mainProc13(int overlayIdx, int param1, actorStruct* pStartEntry, int param2);
+actorStruct* findActor(int overlayIdx, int param1, actorStruct* pStartEntry, int param2);
+void processActors(void);
+void getPixel(int x, int y);
+} // End of namespace Cruise
+
+#endif \ No newline at end of file
diff --git a/engines/cruise/background.cpp b/engines/cruise/background.cpp
new file mode 100644
index 0000000000..02312d1224
--- /dev/null
+++ b/engines/cruise/background.cpp
@@ -0,0 +1,220 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cruise/cruise_main.h"
+
+namespace Cruise {
+
+uint8 colorMode = 0;
+
+uint8* backgroundPtrtable[8] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; // wasn't initialized in original, but it's probably better
+backgroundTableStruct backgroundTable[8];
+
+char hwPage[64000];
+
+char* hwMemAddr[] =
+{
+ hwPage,
+};
+
+short int cvtPalette[0x20];
+
+int loadMEN(uint8** ptr)
+{
+ char* localPtr = (char*)*ptr;
+
+ if(!strcmp(localPtr,"MEN"))
+ {
+ localPtr+=4;
+
+ video4 = *(localPtr++);
+ video3 = *(localPtr++);
+ video2 = *(localPtr++);
+ colorOfSelectedSaveDrive = *(localPtr++);
+
+ *ptr = (uint8*)localPtr;
+
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+int CVTLoaded;
+
+int loadCVT(uint8** ptr)
+{
+ char* localPtr = (char*)*ptr;
+
+ if(!strcmp(localPtr,"CVT"))
+ {
+ int i;
+ localPtr+=4;
+
+ for(i=0;i<0x20;i++)
+ {
+ cvtPalette[i] = *(localPtr++);
+ }
+
+ *ptr = (uint8*)localPtr;
+
+ CVTLoaded = 1;
+
+ return 1;
+ }
+ else
+ {
+ CVTLoaded = 0;
+ return 0;
+ }
+}
+
+extern int lastFileSize;
+
+int loadBackground(char* name, int idx)
+{
+ uint8* ptr;
+ uint8* ptr2;
+ uint8* ptrToFree;
+
+ printf("Loading BG: %s\n",name);
+
+ if(!backgroundPtrtable[idx])
+ {
+ //if(!gfxModuleData.useEGA && !gfxModuleData.useVGA)
+ {
+ backgroundPtrtable[idx] = (uint8*)mallocAndZero(320*200/*64000*/);
+ }
+/* else
+ {
+ backgroundPtrtable[idx] = hwMemAddr[idx];
+ } */
+ }
+
+ if(!backgroundPtrtable[idx])
+ {
+ backgroundTable[idx].name[0] = 0;
+ return(-2);
+ }
+
+ ptrToFree = gfxModuleData.pPage10;
+ if(loadFileSub1(&ptrToFree,(uint8*)name,NULL)<0)
+ {
+ if(ptrToFree != gfxModuleData.pPage10)
+ free(ptrToFree);
+
+ return(-18);
+ }
+
+ if(lastFileSize == 32078 || lastFileSize == 32080 || lastFileSize == 32034)
+ {
+ colorMode = 0;
+ }
+ else
+ {
+ colorMode = 1;
+ }
+
+ ptr = ptrToFree;
+ ptr2 = ptrToFree;
+
+ if(!strcmpuint8(name,"LOGO.PI1"))
+ {
+ bgVar3=bgVar2;
+ bgVar1=1;
+ bgVar2=1;
+ }
+ else
+ {
+ if(bgVar1)
+ {
+ bgVar2=bgVar3;
+ bgVar1=0;
+ }
+ }
+
+ if(!strcmpuint8(ptr,"PAL"))
+ {
+ printf("Pal loading unsupported !\n");
+ exit(1);
+ }
+ else
+ {
+ if(!colorMode || ptr2[1] == 5)
+ {
+ ptr2+=2;
+
+ memcpy(palette,ptr2,0x20);
+ ptr2+=0x20;
+ flipGen(palette,0x20);
+ ptr2 += 0x7D00;
+
+ loadMEN(&ptr2);
+ loadCVT(&ptr2);
+
+ gfxModuleData_gfxClearFrameBuffer(backgroundPtrtable[idx]);
+ gfxModuleData_field_60((char*)ptrToFree+34, 20, 200, (char*)backgroundPtrtable[idx], 0, 0);
+
+ gfxModuleData_setPal((uint8*)(palette + (idx << 6)));
+ }
+ else
+ if(ptr2[1] == 8)
+ {
+ int i;
+ ptr2+=2;
+
+ for(i=0;i<256*3;i++)
+ {
+ palette[i] = ptr2[i];
+ }
+ //memcpy(palette,ptr2,256*3);
+ ptr2+=256*3;
+
+ memcpy(backgroundPtrtable[idx], ptr2, 320*200);
+
+ gfxModuleData_setPal256(palette);
+ }
+ }
+
+ //if(ptrToFree != gfxModuleData.pPage10)
+ // free(ptrToFree);
+
+ if(gfxModuleData.useEGA || gfxModuleData.useTandy)
+ {
+ ASSERT(0);
+ }
+
+ if(gfxModuleData.useEGA || gfxModuleData.useTandy)
+ {
+ ASSERT(0);
+ }
+
+ strcpy(backgroundTable[idx].name, name);
+
+ return(0);
+}
+
+} // End of namespace Cruise
diff --git a/engines/cruise/background.h b/engines/cruise/background.h
new file mode 100644
index 0000000000..f458bc19d7
--- /dev/null
+++ b/engines/cruise/background.h
@@ -0,0 +1,46 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+#ifndef _BACKGROUND_H_
+#define _BACKGROUND_H_
+
+namespace Cruise {
+
+struct backgroundTableStruct
+{
+ char name[9];
+ char extention[6];
+};
+
+typedef struct backgroundTableStruct backgroundTableStruct;
+
+extern short int cvtPalette[0x20];
+extern int CVTLoaded;
+extern uint8* backgroundPtrtable[8];
+extern backgroundTableStruct backgroundTable[8];
+
+int loadBackground(char* name, int idx);
+} // End of namespace Cruise
+
+#endif
+
diff --git a/engines/cruise/backgroundIncrust.cpp b/engines/cruise/backgroundIncrust.cpp
new file mode 100644
index 0000000000..9f108072fa
--- /dev/null
+++ b/engines/cruise/backgroundIncrust.cpp
@@ -0,0 +1,222 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cruise/cruise_main.h"
+
+namespace Cruise {
+
+backgroundIncrustStruct backgroundIncrustHead;
+
+void resetBackgroundIncrustList(backgroundIncrustStruct* pHead)
+{
+ pHead->next = NULL;
+ pHead->prev = NULL;
+}
+
+// blit background to another one
+void addBackgroundIncrustSub1(int fileIdx, int X, int Y, char* ptr2, int16 scale, char* destBuffer, char* dataPtr)
+{
+ if(*dataPtr == 0)
+ {
+ ASSERT(0);
+ }
+
+ buildPolyModel(X, Y, scale, ptr2, destBuffer, dataPtr);
+}
+
+backgroundIncrustStruct* addBackgroundIncrust(int16 overlayIdx,int16 objectIdx,backgroundIncrustStruct* pHead,int16 scriptNumber,int16 scriptOverlay, int16 backgroundIdx, int16 param4)
+{
+ uint8* backgroundPtr;
+ uint8* ptr;
+ objectParamsQuery params;
+ backgroundIncrustStruct* newElement;
+ backgroundIncrustStruct* currentHead;
+ backgroundIncrustStruct* currentHead2;
+
+ getMultipleObjectParam(overlayIdx,objectIdx,&params);
+
+ ptr = filesDatabase[params.fileIdx].subData.ptr;
+
+ if(!ptr)
+ {
+ return NULL;
+ }
+
+ if(filesDatabase[params.fileIdx].subData.resourceType != 4 && filesDatabase[params.fileIdx].subData.resourceType != 8)
+ {
+ return NULL;
+ }
+
+ backgroundPtr = backgroundPtrtable[backgroundIdx];
+
+ if(!backgroundPtr)
+ {
+ ASSERT(0);
+ return NULL;
+ }
+
+ currentHead = pHead;
+ currentHead2 = currentHead->next;
+
+ while(currentHead2)
+ {
+ currentHead = currentHead2;
+ currentHead2 = currentHead->next;
+ }
+
+ newElement = (backgroundIncrustStruct*)mallocAndZero(sizeof(backgroundIncrustStruct));
+
+ if(!newElement)
+ return NULL;
+
+ newElement->next = currentHead->next;
+ currentHead->next = newElement;
+
+ if(!currentHead2)
+ {
+ currentHead2 = pHead;
+ }
+
+ newElement->prev = currentHead2->prev;
+ currentHead2->prev = newElement;
+
+ newElement->objectIdx = objectIdx;
+ newElement->field_6 = param4;
+ newElement->backgroundIdx = backgroundIdx;
+ newElement->overlayIdx = overlayIdx;
+ newElement->scriptNumber = scriptNumber;
+ newElement->scriptOverlayIdx = scriptOverlay;
+ newElement->X = params.X;
+ newElement->Y = params.Y;
+ newElement->scale = params.scale;
+ newElement->field_E = params.fileIdx;
+ newElement->var34 = filesDatabase[params.fileIdx].subData.index;
+ newElement->ptr = NULL;
+ strcpy(newElement->name, filesDatabase[params.fileIdx].subData.name);
+
+ if(filesDatabase[params.fileIdx].subData.resourceType == 4) // sprite
+ {
+ int width = filesDatabase[params.fileIdx].width;
+ int height = filesDatabase[params.fileIdx].height;
+
+ currentTransparent = filesDatabase[params.fileIdx].subData.transparency;
+ mainDrawSub4(width, height, NULL, (char*)filesDatabase[params.fileIdx].subData.ptr, newElement->Y, newElement->X, (char*)backgroundPtr, (char*)filesDatabase[params.fileIdx].subData.ptr);
+ // ASSERT(0);
+ }
+ else // poly
+ {
+ /* if(param4 == 1)
+ {
+ int var_A;
+ int var_8;
+ int var_6;
+ char* var_10;
+
+ mainDrawSub1Sub1(lvar[3], newElement->X, newElement->Y, &var_A, &var_8, &var_6, &var_10, lvar[4], filesDatabase[lvar[3]].subData.ptr);
+ ASSERT(0);
+ }*/
+
+ addBackgroundIncrustSub1(params.fileIdx, newElement->X, newElement->Y, NULL, params.scale, (char*)backgroundPtr, (char*)filesDatabase[params.fileIdx].subData.ptr );
+ }
+
+ return newElement;
+}
+
+void loadBackgroundIncrustFromSave(FILE* fileHandle)
+{
+ int16 numEntry;
+ backgroundIncrustStruct* ptr1;
+ backgroundIncrustStruct* ptr2;
+ int32 i;
+
+ fread(&numEntry,2,1,fileHandle);
+
+ ptr1 = &backgroundIncrustHead;
+ ptr2 = &backgroundIncrustHead;
+
+ for(i=0;i<numEntry;i++)
+ {
+ backgroundIncrustStruct* current = (backgroundIncrustStruct*)mallocAndZero(sizeof(backgroundIncrustStruct));
+
+ fseek(fileHandle, 4, SEEK_CUR);
+
+ fread(&current->objectIdx,2,1,fileHandle);
+ fread(&current->field_6,2,1,fileHandle);
+ fread(&current->overlayIdx,2,1,fileHandle);
+ fread(&current->X,2,1,fileHandle);
+ fread(&current->Y,2,1,fileHandle);
+ fread(&current->field_E,2,1,fileHandle);
+ fread(&current->scale,2,1,fileHandle);
+ fread(&current->backgroundIdx,2,1,fileHandle);
+ fread(&current->scriptNumber,2,1,fileHandle);
+ fread(&current->scriptOverlayIdx,2,1,fileHandle);
+ fread(&current->ptr,4,1,fileHandle);
+ fread(&current->field_1C,4,1,fileHandle);
+ fread(&current->size,2,1,fileHandle);
+ fread(&current->field_22,2,1,fileHandle);
+ fread(&current->field_24,2,1,fileHandle);
+ fread(current->name,14,1,fileHandle);
+ fread(&current->var34,2,1,fileHandle);
+
+ if(current->size)
+ {
+ current->ptr = (uint8*)mallocAndZero(current->size);
+ fread(current->ptr,current->size,1,fileHandle);
+ }
+
+ current->next = NULL;
+ ptr2 = current;
+ current->prev = backgroundIncrustHead.prev;
+ backgroundIncrustHead.prev = current;
+ ptr2 = current->next;
+ }
+}
+
+void regenerateBackgroundIncrust(backgroundIncrustStruct* pHead)
+{
+ printf("Need to regenerate backgroundIncrust\n");
+}
+
+void freeBackgroundIncrustList(backgroundIncrustStruct* pHead)
+{
+ backgroundIncrustStruct* pCurrent = pHead->next;
+
+ while(pCurrent)
+ {
+ backgroundIncrustStruct* pNext = pCurrent->next;
+
+ if(pCurrent->ptr)
+ {
+ free(pCurrent->ptr);
+ }
+
+ free(pCurrent);
+
+ pCurrent = pNext;
+ }
+
+ resetBackgroundIncrustList(pHead);
+}
+
+} // End of namespace Cruise
diff --git a/engines/cruise/backgroundIncrust.h b/engines/cruise/backgroundIncrust.h
new file mode 100644
index 0000000000..1f5fd756b2
--- /dev/null
+++ b/engines/cruise/backgroundIncrust.h
@@ -0,0 +1,66 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef _BACKGROUNDINCRUST_H_
+#define _BACKGROUNDINCRUST_H_
+
+namespace Cruise {
+
+struct backgroundIncrustStruct {
+ struct backgroundIncrustStruct* next;
+ struct backgroundIncrustStruct* prev;
+
+ uint16 objectIdx;
+ uint16 field_6;
+ uint16 overlayIdx;
+ uint16 X;
+ uint16 Y;
+ uint16 field_E;
+ uint16 scale;
+ uint16 backgroundIdx;
+ uint16 scriptNumber;
+ uint16 scriptOverlayIdx;
+ uint8* ptr;
+ int32 field_1C;
+ int16 size;
+ uint16 field_22;
+ uint16 field_24;
+ char name[14];
+ uint16 var34;
+};
+
+typedef struct backgroundIncrustStruct backgroundIncrustStruct;
+
+extern backgroundIncrustStruct backgroundIncrustHead;
+
+void resetBackgroundIncrustList(backgroundIncrustStruct* pHead);
+backgroundIncrustStruct* addBackgroundIncrust(int16 overlayIdx,int16 param2,backgroundIncrustStruct* pHead,int16 scriptNumber,int16 scriptOverlay, int16 backgroundIdx, int16 param4);
+void loadBackgroundIncrustFromSave(FILE* fileHandle);
+void regenerateBackgroundIncrust(backgroundIncrustStruct* pHead);
+void freeBackgroundIncrustList(backgroundIncrustStruct* pHead);
+
+} // End of namespace Cruise
+
+#endif
+
diff --git a/engines/cruise/cruise.cpp b/engines/cruise/cruise.cpp
new file mode 100644
index 0000000000..35298e2bbb
--- /dev/null
+++ b/engines/cruise/cruise.cpp
@@ -0,0 +1,111 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/stdafx.h"
+#include "common/file.h"
+#include "common/fs.h"
+#include "common/savefile.h"
+#include "common/config-manager.h"
+#include "common/system.h"
+
+#include "graphics/cursorman.h"
+
+#include "sound/mididrv.h"
+#include "sound/mixer.h"
+
+#include "cruise/cruise.h"
+
+namespace Cruise {
+
+//SoundDriver *g_soundDriver;
+//SfxPlayer *g_sfxPlayer;
+Common::SaveFileManager *g_saveFileMan;
+
+CruiseEngine *g_cruise;
+
+CruiseEngine::CruiseEngine(OSystem *syst) : Engine(syst) {
+ Common::addSpecialDebugLevel(kCruiseDebugScript, "Script", "Script debug level");
+
+ // Setup mixer
+ if (!_mixer->isReady()) {
+ warning("Sound initialization failed.");
+ }
+
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
+ _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
+
+ g_cruise = this;
+}
+
+CruiseEngine::~CruiseEngine() {
+}
+
+int CruiseEngine::init() {
+ // Detect game
+ if (!initGame()) {
+ GUIErrorMessage("No valid games were found in the specified directory.");
+ return -1;
+ }
+
+ // Initialize backend
+ _system->beginGFXTransaction();
+ initCommonGFX(false);
+ _system->initSize(320, 200);
+ _system->endGFXTransaction();
+
+ initialize();
+
+ return 0;
+}
+
+int CruiseEngine::go() {
+ CursorMan.showMouse(true);
+
+ Cruise::mainLoop();
+
+ return 0;
+}
+
+
+void CruiseEngine::initialize() {
+
+ fadeVar = 0;
+ ptr_something = (ctpVar19Struct*)mallocAndZero(sizeof(ctpVar19Struct)*0x200);
+
+ /*volVar1 = 0;
+ fileData1 = 0;*/
+
+ /*PAL_fileHandle = -1;*/
+
+ // video init stuff
+
+ loadSystemFont();
+
+ // another bit of video init
+
+ readVolCnf();
+
+}
+
+} // End of namespace Cruise
diff --git a/engines/cruise/cruise.h b/engines/cruise/cruise.h
new file mode 100644
index 0000000000..50d65cc0e9
--- /dev/null
+++ b/engines/cruise/cruise.h
@@ -0,0 +1,107 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CruisE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef CRUISE_H
+#define CRUISE_H
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+#include "common/util.h"
+
+#include "engines/engine.h"
+
+#include "cruise/cruise_main.h"
+
+namespace Cruise {
+
+enum CruiseGameType {
+ GType_CRUISE = 1
+};
+
+struct CRUISEGameDescription;
+
+class CruiseEngine : public Engine {
+
+protected:
+ int init();
+ int go();
+ void shutdown();
+
+ bool initGame();
+
+public:
+ CruiseEngine(OSystem *syst);
+ virtual ~CruiseEngine();
+
+ int getGameType() const;
+ uint32 getFeatures() const;
+ Common::Language getLanguage() const;
+ Common::Platform getPlatform() const;
+
+ bool loadSaveDirectory(void);
+ void makeSystemMenu(void);
+
+ const CRUISEGameDescription *_gameDescription;
+
+private:
+ void initialize(void);
+ bool makeLoad(char *saveName);
+ void mainLoop(int bootScriptIdx);
+
+ bool _preLoad;
+};
+
+extern CruiseEngine *g_cruise;
+
+#define BOOT_PRC_NAME "AUTO00.PRC"
+
+enum {
+ VAR_MOUSE_X_MODE = 253,
+ VAR_MOUSE_X_POS = 249,
+ VAR_MOUSE_Y_MODE = 251,
+ VAR_MOUSE_Y_POS = 250
+};
+
+enum {
+ MOUSE_CURSOR_NORMAL = 0,
+ MOUSE_CURSOR_DISK,
+ MOUSE_CURSOR_CROSS
+};
+
+enum {
+ kCruiseDebugScript = 1 << 0
+};
+
+enum {
+ kCmpEQ = (1 << 0),
+ kCmpGT = (1 << 1),
+ kCmpLT = (1 << 2)
+};
+
+
+extern Common::SaveFileManager *g_saveFileMan; // TEMP
+
+} // End of namespace Cruise
+
+#endif
diff --git a/engines/cruise/cruise_main.cpp b/engines/cruise/cruise_main.cpp
new file mode 100644
index 0000000000..841db68fe1
--- /dev/null
+++ b/engines/cruise/cruise_main.cpp
@@ -0,0 +1,1688 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/stdafx.h"
+#include "common/events.h"
+
+#include "cruise/cruise_main.h"
+#include <time.h>
+
+namespace Cruise {
+
+unsigned int timer = 0;
+
+void drawSolidBox(int32 x1, int32 y1, int32 x2, int32 y2, uint8 color)
+{
+ int32 i;
+ int32 j;
+
+ for(i=x1;i<x2;i++)
+ {
+ for(j=y1;j<y2;j++)
+ {
+ globalScreen[j*320+i] = color;
+ }
+ }
+}
+
+void drawBlackSolidBoxSmall()
+{
+// gfxModuleData.drawSolidBox(64,100,256,117,0);
+ drawSolidBox(64,100,256,117,0);
+}
+
+void resetRaster(uint8* rasterPtr, int32 rasterSize)
+{
+ memset(rasterPtr,0,rasterSize);
+}
+
+
+void drawInfoStringSmallBlackBox(uint8* string)
+{
+ //uint8 buffer[256];
+
+ gfxModuleData_field_90();
+ gfxModuleData_gfxWaitVSync();
+ drawBlackSolidBoxSmall();
+
+ drawString(10,100,string,gfxModuleData.pPage10,video4,300);
+
+ gfxModuleData_flip();
+
+ flipScreen();
+
+ while(1);
+}
+
+void loadPakedFileToMem(int fileIdx, uint8* buffer)
+{
+ //changeCursor(1);
+
+ currentVolumeFile.seek(volumePtrToFileDescriptor[fileIdx].offset,SEEK_SET);
+ currentVolumeFile.read(buffer,volumePtrToFileDescriptor[fileIdx].size);
+}
+
+int loadScriptSub1(int scriptIdx, int param)
+{
+ objDataStruct* ptr2;
+ int counter;
+ int i;
+
+ if(!overlayTable[scriptIdx].ovlData)
+ return(0);
+
+ ptr2 = overlayTable[scriptIdx].ovlData->objDataTable;
+
+ if(!ptr2)
+ return(0);
+
+ if(overlayTable[scriptIdx].ovlData->numObjData==0)
+ return(0);
+
+ counter = 0;
+
+ for(i=0;i<overlayTable[scriptIdx].ovlData->numObjData;i++)
+ {
+ if(ptr2[i].var0 == param)
+ {
+ counter++;
+ }
+ }
+
+ return(counter);
+}
+
+void saveShort(void* ptr, short int var)
+{
+ *(int16*)ptr = var;
+
+ flipShort((int16*)ptr);
+}
+
+int16 loadShort(void* ptr)
+{
+ short int temp;
+
+ temp = *(int16*)ptr;
+
+ flipShort(&temp);
+
+ return(temp);
+}
+
+
+void resetFileEntryRange(int param1, int param2)
+{
+ int i;
+
+ for(i=param1;i<param2;i++)
+ {
+ resetFileEntry(i);
+ }
+}
+
+int getProcParam(int overlayIdx, int param2, uint8* name)
+{
+ int numExport;
+ int i;
+ exportEntryStruct* exportDataPtr;
+ uint8* exportNamePtr;
+ uint8 exportName[80];
+
+ if(!overlayTable[overlayIdx].alreadyLoaded)
+ return 0;
+
+ if(!overlayTable[overlayIdx].ovlData)
+ return 0;
+
+ numExport = overlayTable[overlayIdx].ovlData->numExport;
+ exportDataPtr = overlayTable[overlayIdx].ovlData->exportDataPtr;
+ exportNamePtr = overlayTable[overlayIdx].ovlData->exportNamesPtr;
+
+ if(!exportNamePtr)
+ return 0;
+
+ for(i=0;i<numExport;i++)
+ {
+ if(exportDataPtr[i].var4 == param2)
+ {
+ strcpyuint8(exportName,exportDataPtr[i].offsetToName+exportNamePtr);
+
+ if(!strcmpuint8(exportName,name))
+ {
+ return(exportDataPtr[i].idx);
+ }
+ }
+ }
+
+ return 0;
+}
+
+void changeScriptParamInList(int param1, int param2, scriptInstanceStruct* pScriptInstance,int newValue, int param3)
+{
+ pScriptInstance = pScriptInstance->nextScriptPtr;
+ while(pScriptInstance)
+ {
+ if( (pScriptInstance->overlayNumber == param1 || param1 == -1)
+ &&(pScriptInstance->scriptNumber == param2 || param2 == -1)
+ &&(pScriptInstance->var12 == param3 || param3 == -1))
+ {
+ pScriptInstance->var12 = newValue;
+ }
+
+ pScriptInstance = pScriptInstance->nextScriptPtr;
+ }
+}
+
+
+void initBigVar3()
+{
+ int i;
+
+ for(i=0;i<257;i++)
+ {
+ if(filesDatabase[i].subData.ptr)
+ {
+ free(filesDatabase[i].subData.ptr);
+ }
+
+ filesDatabase[i].subData.ptr = NULL;
+ filesDatabase[i].subData.ptr2 = NULL;
+
+ filesDatabase[i].subData.index = -1;
+ filesDatabase[i].subData.resourceType = 0;
+ }
+}
+
+void resetPtr2(scriptInstanceStruct* ptr)
+{
+ ptr->nextScriptPtr = NULL;
+ ptr->scriptNumber = -1;
+}
+
+void resetPtr(objectStruct* ptr)
+{
+ ptr->next = NULL;
+ ptr->prev = NULL;
+}
+
+void resetActorPtr(actorStruct* ptr)
+{
+ ptr->next = NULL;
+ ptr->prev = NULL;
+}
+
+ovlData3Struct* getOvlData3Entry(int32 scriptNumber, int32 param)
+{
+ ovlDataStruct* ovlData = overlayTable[scriptNumber].ovlData;
+
+ if(!ovlData)
+ {
+ return NULL;
+ }
+
+ if(param<0)
+ {
+ return NULL;
+ }
+
+ if(ovlData->numScripts1 <= param)
+ {
+ return NULL;
+ }
+
+ if(!ovlData->data3Table)
+ {
+ return NULL;
+ }
+
+ return(&ovlData->data3Table[param]);
+}
+
+ovlData3Struct* scriptFunc1Sub2(int32 scriptNumber, int32 param)
+{
+ ovlDataStruct* ovlData = overlayTable[scriptNumber].ovlData;
+
+ if(!ovlData)
+ {
+ return NULL;
+ }
+
+ if(param<0)
+ {
+ return NULL;
+ }
+
+ if(ovlData->numScripts2 <= param)
+ {
+ return NULL;
+ }
+
+ if(!ovlData->ptr1)
+ {
+ return NULL;
+ }
+
+ return((ovlData3Struct*)(ovlData->ptr1+param*0x1C));
+}
+
+void scriptFunc2(int scriptNumber,scriptInstanceStruct* scriptHandle, int param, int param2)
+{
+ if(scriptHandle->nextScriptPtr)
+ {
+ if(scriptNumber == scriptHandle->nextScriptPtr->overlayNumber || scriptNumber != -1)
+ {
+ if(param2 == scriptHandle->nextScriptPtr->scriptNumber || param2 != -1)
+ {
+ scriptHandle->nextScriptPtr->sysKey = param;
+ }
+ }
+ }
+}
+
+uint8* getDataFromData3(ovlData3Struct* ptr, int param)
+{
+ uint8* dataPtr;
+
+ if(!ptr)
+ return(NULL);
+
+ dataPtr = ptr->dataPtr;
+
+ if(!dataPtr)
+ return(NULL);
+
+ switch(param)
+ {
+ case 0:
+ {
+ return(dataPtr);
+ }
+ case 1:
+ {
+ return(dataPtr + ptr->offsetToSubData3); // strings
+ }
+ case 2:
+ {
+ return(dataPtr + ptr->offsetToSubData2);
+ }
+ case 3:
+ {
+ return(dataPtr + ptr->offsetToImportData); // import data
+ }
+ case 4:
+ {
+ return(dataPtr + ptr->offsetToImportName); // import names
+ }
+ case 5:
+ {
+ return(dataPtr + ptr->offsetToSubData5);
+ }
+ default:
+ {
+ return(NULL);
+ }
+ }
+}
+
+void printInfoBlackBox(char* string)
+{
+}
+
+void waitForPlayerInput()
+{
+}
+
+void getFileExtention(const char* name,char* buffer)
+{
+ while(*name != '.' && *name)
+ {
+ name++;
+ }
+
+ strcpy(buffer,name);
+}
+
+void removeExtention(const char* name, char* buffer) // not like in original
+{
+ char* ptr;
+
+ strcpy(buffer,name);
+
+ ptr = strchr(buffer,'.');
+
+ if(ptr)
+ *ptr = 0;
+}
+
+int lastFileSize;
+
+int loadFileSub1(uint8** ptr, uint8* name, uint8* ptr2)
+{
+ int i;
+ char buffer[256];
+ int fileIdx;
+ int unpackedSize;
+ uint8* unpackedBuffer;
+
+ for(i=0;i<64;i++)
+ {
+ if(mediumVar[i].ptr)
+ {
+ if(!strcmpuint8(mediumVar[i].name,name))
+ {
+ printf("Unsupported code in loadFIleSub1 !\n");
+ exit(1);
+ }
+ }
+ }
+
+ getFileExtention((char*)name,buffer);
+
+ if(!strcmp(buffer,".SPL"))
+ {
+ removeExtention((char*)name,buffer);
+
+ // if(useH32)
+ {
+ strcatuint8(buffer,".H32");
+ }
+ /* else
+ if(useAdlib)
+ {
+ strcatuint8(buffer,".ADL");
+ }
+ else
+ {
+ strcatuint8(buffer,".HP");
+ }*/
+ }
+ else
+ {
+ strcpyuint8(buffer,name);
+ }
+
+ fileIdx = findFileInDisks((uint8*)buffer);
+
+ if(fileIdx<0)
+ return(-18);
+
+ unpackedSize = loadFileVar1 = volumePtrToFileDescriptor[fileIdx].extSize + 2;
+
+ // TODO: here, can unpack in gfx module buffer
+ unpackedBuffer = (uint8*)mallocAndZero(unpackedSize);
+
+ if(!unpackedBuffer)
+ {
+ return(-2);
+ }
+
+ lastFileSize = unpackedSize;
+
+ if(volumePtrToFileDescriptor[fileIdx].size +2 != unpackedSize)
+ {
+ unsigned short int realUnpackedSize;
+ uint8* tempBuffer;
+ uint8* pakedBuffer = (uint8*) mallocAndZero(volumePtrToFileDescriptor[fileIdx].size +2);
+
+ loadPakedFileToMem(fileIdx,pakedBuffer);
+
+ realUnpackedSize = *(uint16*)(pakedBuffer+volumePtrToFileDescriptor[fileIdx].size-2);
+ flipShort((int16*)&realUnpackedSize);
+
+ lastFileSize = realUnpackedSize;
+
+ tempBuffer = (uint8*)mallocAndZero(realUnpackedSize);
+
+ decomp((uint8*)pakedBuffer+volumePtrToFileDescriptor[fileIdx].size-4,(uint8*)unpackedBuffer+realUnpackedSize,realUnpackedSize);
+
+ free(pakedBuffer);
+ }
+ else
+ {
+ loadPakedFileToMem(fileIdx,unpackedBuffer);
+ }
+
+ *ptr = unpackedBuffer;
+
+ return(1);
+}
+
+void resetFileEntry(int32 entryNumber)
+{
+ if(entryNumber>=257)
+ return;
+
+ if(!filesDatabase[entryNumber].subData.ptr)
+ return;
+
+ free(filesDatabase[entryNumber].subData.ptr);
+
+ filesDatabase[entryNumber].subData.ptr = NULL;
+ filesDatabase[entryNumber].subData.ptr2 = NULL;
+ filesDatabase[entryNumber].widthInColumn = 0;
+ filesDatabase[entryNumber].width = 0;
+ filesDatabase[entryNumber].resType = 0;
+ filesDatabase[entryNumber].height = 0;
+ filesDatabase[entryNumber].subData.index = -1;
+ filesDatabase[entryNumber].subData.resourceType = 0;
+ filesDatabase[entryNumber].subData.field_1C = 0;
+ filesDatabase[entryNumber].subData.name[0] = 0;
+
+}
+
+uint8* mainProc14(uint16 overlay, uint16 idx)
+{
+ ASSERT(0);
+
+ return NULL;
+}
+
+int initAllData(void)
+{
+ int i;
+
+ setupFuncArray();
+ setupOpcodeTable();
+ initOverlayTable();
+
+ setup1 = 0;
+ currentActiveBackgroundPlane = 0;
+
+ freeDisk();
+
+ initVar5[0] = -1;
+ initVar5[3] = -1;
+ initVar5[6] = -1;
+ initVar5[9] = -1;
+
+ menuTable[0] = NULL;
+
+ for(i=0;i<2000;i++)
+ {
+ globalVars[i] = 0;
+ }
+
+ for(i=0;i<8;i++)
+ {
+ backgroundTable[i].name[0] = 0;
+ }
+
+ for(i=0;i<257;i++)
+ {
+ filesDatabase[i].subData.ptr = NULL;
+ filesDatabase[i].subData.ptr2 = NULL;
+ }
+
+ initBigVar3();
+
+ resetPtr2(&scriptHandle2);
+ resetPtr2(&scriptHandle1);
+
+ resetPtr(&objectHead);
+
+ resetActorPtr(&actorHead);
+ resetBackgroundIncrustList(&backgroundIncrustHead);
+
+ bootOverlayNumber = loadOverlay((uint8*)"AUTO00");
+
+#ifdef DUMP_SCRIPT
+ loadOverlay("TITRE");
+ loadOverlay("TOM");
+ loadOverlay("XX2");
+ loadOverlay("SUPER");
+ loadOverlay("BEBE1");
+ loadOverlay("BIBLIO");
+ loadOverlay("BRACAGE");
+ loadOverlay("CONVERS");
+ loadOverlay("DAF");
+ loadOverlay("DAPHNEE");
+ loadOverlay("DESIRE");
+ loadOverlay("FAB");
+ loadOverlay("FABIANI");
+ loadOverlay("FIN");
+ loadOverlay("FIN01");
+ loadOverlay("FINBRAC");
+ loadOverlay("GEN");
+ loadOverlay("GENDEB");
+ loadOverlay("GIFLE");
+ loadOverlay("HECTOR");
+ loadOverlay("HECTOR2");
+ loadOverlay("I00");
+ loadOverlay("I01");
+ loadOverlay("I04");
+ loadOverlay("I06");
+ loadOverlay("I07");
+ loadOverlay("INVENT");
+ loadOverlay("JULIO");
+ loadOverlay("LOGO");
+ loadOverlay("MANOIR");
+ loadOverlay("MISSEL");
+ loadOverlay("POKER");
+ loadOverlay("PROJ");
+ loadOverlay("REB");
+ loadOverlay("REBECCA");
+ loadOverlay("ROS");
+ loadOverlay("ROSE");
+ loadOverlay("S01");
+ loadOverlay("S02");
+ loadOverlay("S03");
+ loadOverlay("S04");
+ loadOverlay("S06");
+ loadOverlay("S07");
+ loadOverlay("S08");
+ loadOverlay("S09");
+ loadOverlay("S10");
+ loadOverlay("S103");
+ loadOverlay("S11");
+ loadOverlay("S113");
+ loadOverlay("S12");
+ loadOverlay("S129");
+ loadOverlay("S131");
+ loadOverlay("S132");
+ loadOverlay("S133");
+ loadOverlay("int16");
+ loadOverlay("S17");
+ loadOverlay("S18");
+ loadOverlay("S19");
+ loadOverlay("S20");
+ loadOverlay("S21");
+ loadOverlay("S22");
+ loadOverlay("S23");
+ loadOverlay("S24");
+ loadOverlay("S25");
+ loadOverlay("S26");
+ loadOverlay("S27");
+ loadOverlay("S29");
+ loadOverlay("S30");
+ loadOverlay("S31");
+ loadOverlay("int32");
+ loadOverlay("S33");
+ loadOverlay("S33B");
+ loadOverlay("S34");
+ loadOverlay("S35");
+ loadOverlay("S36");
+ loadOverlay("S37");
+ loadOverlay("SHIP");
+ loadOverlay("SUPER");
+ loadOverlay("SUZAN");
+ loadOverlay("SUZAN2");
+ loadOverlay("TESTA1");
+ loadOverlay("TESTA2");
+ //exit(1);
+#endif
+
+ if(bootOverlayNumber)
+ {
+ positionInStack = 0;
+
+ attacheNewScriptToTail(bootOverlayNumber,&scriptHandle2,0,20,0,0,scriptType_20);
+ scriptFunc2(bootOverlayNumber,&scriptHandle2,1,0);
+ }
+
+ strcpyuint8(systemStrings.bootScriptName,"AUTO00");
+
+ return(bootOverlayNumber);
+}
+
+int removeFinishedScripts(scriptInstanceStruct* ptrHandle)
+{
+ scriptInstanceStruct* ptr = ptrHandle->nextScriptPtr; // can't destruct the head
+ scriptInstanceStruct* oldPtr = ptrHandle;
+
+ if(!ptr)
+ return(0);
+
+ do
+ {
+ if(ptr->scriptNumber == -1)
+ {
+ oldPtr->nextScriptPtr = ptr->nextScriptPtr;
+
+ if(ptr->var6 && ptr->varA)
+ {
+ // free(ptr->var6);
+ }
+
+ free(ptr);
+
+ ptr = oldPtr->nextScriptPtr;
+ }
+ else
+ {
+ oldPtr = ptr;
+ ptr = ptr->nextScriptPtr;
+ }
+ }while(ptr);
+
+ return(0);
+}
+
+int nePasAffichierMenuDialogue;
+int var37 = 0;
+int var38 = 0;
+
+int getCursorFromObject(int mouseX, int mouseY, int* outX, int* outY)
+{
+ int16 var_2;
+ int16 var_4;
+ int16 var_14;
+ int16 var_16;
+ objectParamsQuery params;
+ int16 var_10;
+ int16 var_E;
+ int16 var_C;
+// int16 var_42;
+ int16 var_A;
+ int16 var_6;
+
+ char objectName[80];
+
+ objectStruct* currentObject = objectHead.prev;
+
+ while(currentObject)
+ {
+ if(currentObject->overlay >= 0)
+ {
+ if(overlayTable[currentObject->overlay].alreadyLoaded)
+ {
+ if(currentObject->type == 4 || currentObject->type == 1 || currentObject->type == 9 || currentObject->type == 3)
+ {
+ strcpy(objectName, getObjectName(currentObject->idx, overlayTable[currentObject->overlay].ovlData->specialString2));
+
+ if(strlen(objectName))
+ {
+ if(currentObject->hide == 0)
+ {
+ var_2 = currentObject->idx;
+ var_4 = currentObject->overlay;
+ var_14 = currentObject->followObjectIdx;
+ var_16 = currentObject->followObjectOverlayIdx;
+
+ getMultipleObjectParam(currentObject->overlay, currentObject->idx, &params);
+
+ var_10 = 0;
+ var_E = 0;
+ var_C = 0;
+
+ if((var_4 != var_16) && (var_2 != var_14))
+ {
+ objectParamsQuery params;
+ getMultipleObjectParam(var_16, var_14, &params);
+
+ var_C = params.X;
+ var_E = params.Y;
+ var_10 = params.fileIdx;
+ }
+
+ if(params.var5 >= 0 && params.fileIdx >= 0)
+ {
+ if(currentObject->type == 3)
+ {
+ assert(0);
+
+ var_2 = params.scale;
+ var_A = params.X + var_C;
+
+ // TODO: this var3 is stupid, investigate...
+ if((var_A <= mouseX) && (var_A + params.fileIdx >= mouseX) && (mouseY >= params.Y + var_E) && (params.Y + var_E + var2 >= mouseY))
+ {
+ *outX = var_16;
+ *outY = var_14;
+
+ return(currentObject->type);
+ }
+ }
+ else
+ if(currentObject->type == 4 || currentObject->type == 1 || currentObject->type == 9 )
+ {
+ int si;
+ int var_8;
+ int di;
+
+ var_A = params.X + var_C;
+ var_6 = params.Y + var_E;
+
+ di = params.fileIdx;
+
+ if(di<0)
+ {
+ di += var_10;
+ }
+
+/* if((filesDatabase[di].subData.resourceType == 8) && (filesDatabase[di].subData.ptr))
+ {
+ assert(0);
+ }
+ else */
+ {
+ var_4 = filesDatabase[di].resType;
+
+ if(var_4 == 1)
+ {
+ var_C = filesDatabase[di].widthInColumn/2;
+ }
+ else
+ {
+ var_C = filesDatabase[di].width;
+ }
+
+ var_8 = filesDatabase[di].height;
+
+ var_2 = mouseX - var_A;
+ si = mouseY - var_6;
+
+ if(var_2>0)
+ {
+ if(var_C>var_2)
+ {
+ if(si>0)
+ {
+ if(var_8>=si)
+ {
+ if(filesDatabase[di].subData.ptr)
+ {
+ if(var_4 == 1)
+ {
+ }
+ else
+ {
+ }
+
+ printf("should compare to mask in getCursorFromObject...\n");
+
+ *outX = var_16;
+ *outY = var_14;
+
+ printf("Selected: %s\n", objectName);
+
+ return currentObject->type;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ currentObject = currentObject->prev;
+ }
+
+ *outX = 0;
+ *outY = 0;
+
+ return -1;
+}
+
+char keyboardVar = 0;
+
+void freeStuff2(void)
+{
+ printf("implement freeStuff2\n");
+}
+
+void *allocAndZero(int size)
+{
+ void *ptr;
+
+ ptr = malloc(size);
+ memset(ptr,0,size);
+
+ return ptr;
+}
+
+char* getObjectName(int index, uint8* string)
+{
+ int i;
+ char* ptr = (char*)string;
+
+ if(!string)
+ return NULL;
+
+ for(i=0;i<index;i++)
+ {
+ while(*ptr)
+ {
+ ptr++;
+ }
+ ptr++;
+ }
+ return ptr;
+}
+
+int buildInventorySub1(int overlayIdx, int objIdx)
+{
+ objDataStruct* pObjectData = getObjectDataFromOverlay(overlayIdx, objIdx);
+
+ if(pObjectData)
+ {
+ return pObjectData->var1;
+ }
+ else
+ {
+ return -11;
+ }
+}
+
+void buildInventory(int X, int Y)
+{
+ int numObjectInInventory;
+ menuStruct* pMenu;
+
+ pMenu = createMenu(X, Y, "Inventaire");
+
+ menuTable[1] = pMenu;
+
+ if(pMenu)
+ {
+ numObjectInInventory = 0;
+
+ if(numOfLoadedOverlay > 1)
+ {
+ int i;
+
+ for(i=1;i<numOfLoadedOverlay;i++)
+ {
+ ovlDataStruct* pOvlData = overlayTable[i].ovlData;
+
+ if(pOvlData && pOvlData->objDataTable)
+ {
+ int var_2;
+
+ var_2 = 0;
+
+ if(pOvlData->numObjData)
+ {
+ int j;
+
+ for(j=0;j<pOvlData->numObjData;j++)
+ {
+ if(buildInventorySub1(i,j) != 3)
+ {
+ int16 returnVar;
+
+ getSingleObjectParam(i,j,5,&returnVar);
+
+ if(returnVar<-1)
+ {
+ addSelectableMenuEntry(i,j,pMenu,1,-1,getObjectName(j, pOvlData->specialString2));
+ numObjectInInventory++;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if(numObjectInInventory == 0)
+ {
+ freeMenu(menuTable[1]);
+ menuTable[1] = NULL;
+ }
+}
+
+int currentMenuElementX;
+int currentMenuElementY;
+menuElementStruct* currentMenuElement;
+
+menuElementSubStruct* getSelectedEntryInMenu(menuStruct* pMenu)
+{
+ menuElementStruct* pMenuElement;
+
+ if(pMenu == NULL)
+ {
+ return NULL;
+ }
+
+ if(pMenu->numElements == 0)
+ {
+ return NULL;
+ }
+
+ pMenuElement = pMenu->ptrNextElement;
+
+ while(pMenuElement)
+ {
+ if(pMenuElement->varC)
+ {
+ currentMenuElementX = pMenuElement->x;
+ currentMenuElementY = pMenuElement->y;
+ currentMenuElement = pMenuElement;
+
+ return pMenuElement->ptrSub;
+ }
+
+ pMenuElement = pMenuElement->next;
+ }
+
+ return NULL;
+}
+
+int callInventoryObject(int param0, int param1, int x, int y)
+{
+ int var_2C;
+ int var_30;
+ int var_28;
+ int var_1E;
+ int16 returnVar;
+
+ var_30 = -1;
+
+ getSingleObjectParam(param0,param1,5,&returnVar);
+
+ var_2C = 0;
+ var_28 = 1;
+
+ for(var_1E=1;var_1E<numOfLoadedOverlay;var_1E++)
+ {
+ ovlDataStruct* var_2A = overlayTable[var_1E].ovlData;
+ if(var_2A->ptr1)
+ {
+ int var_18;
+ int var_14;
+
+ var_18 = var_2A->numLinkData;
+
+ if(var_18)
+ {
+ int var_16;
+
+ var_16 = 0;
+
+ for(var_14 = 0; var_14 < var_18;var_14++)
+ {
+ objDataStruct* pObject;
+ linkDataStruct* var_34;
+ int var_2;
+
+ var_34 = &var_2A->linkDataPtr[var_14];
+
+ var_2 = var_34->stringIdx;
+
+ if(!var_2)
+ {
+ var_2 = var_1E;
+ }
+
+ pObject = getObjectDataFromOverlay(var_2,var_34->stringNameOffset);
+
+ if(var_2 == param0)
+ {
+ if(param1 == var_34->stringNameOffset)
+ {
+ if(pObject)
+ {
+ if(pObject->var1 != 3)
+ {
+ char var_214[80];
+ char var_1C4[80];
+ char var_174[80];
+ char var_124[80];
+ char var_D4[80];
+ char var_84[80];
+
+ ovlDataStruct* var_12;
+ ovlDataStruct* var_22;
+
+ int var_E = var_34->varIdx;
+ int cx = var_34->stringIdx;
+ int var_C = var_34->procIdx;
+
+ int di = var_E;
+ if(var_E == 0)
+ di = var_1E;
+
+ var_2 = cx;
+ if(cx == 0)
+ var_2 = var_1E;
+
+ if(var_C == 0)
+ var_C = var_1E;
+
+ var_12 = NULL;
+ var_22 = NULL;
+
+ var_214[0] = 0;
+ var_1C4[0] = 0;
+ var_174[0] = 0;
+ var_124[0] = 0;
+ var_D4[0] = 0;
+ var_84[0] = 0;
+
+ if(di>0)
+ {
+ var_22 = overlayTable[di].ovlData;
+ }
+
+ if(var_2>0)
+ {
+ var_12 = overlayTable[var_2].ovlData;
+ }
+
+ if(var_12)
+ {
+ if(var_34->stringNameOffset)
+ {
+ var_30 = var_34->field_1A;
+ if(var_28)
+ {
+ if(var_12->specialString2)
+ {
+ if(var_30==-1 || var_30 == returnVar)
+ {
+ char* ptrName = getObjectName(var_34->stringNameOffset, var_12->specialString2);
+
+ menuTable[0] = createMenu(x,y,ptrName);
+ var_28 = 0;
+ }
+ }
+ }
+ }
+ }
+
+ if(var_22)
+ {
+ if(var_34->varNameOffset>=0)
+ {
+ if(var_22->specialString1)
+ {
+ char* ptr = getObjectName(var_34->varNameOffset, var_22->specialString1);
+
+ strcpy(var_214, ptr);
+
+ if(var_28 == 0)
+ {
+ if(var_30 ==-1 || var_30 == returnVar)
+ {
+ if(strlen(var_214))
+ {
+ attacheNewScriptToTail(var_1E,&scriptHandle1,var_34->field_2, 30, currentScriptPtr->scriptNumber,currentScriptPtr->overlayNumber, scriptType_30);
+ }
+ else
+ {
+ if(var_22->specialString1)
+ {
+ char* ptr = getObjectName(var_34->varNameOffset, var_22->specialString1);
+
+ var_2C = 1;
+
+ addSelectableMenuEntry(var_1E, var_14, menuTable[0], 1, -1, ptr);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return var_2C;
+}
+
+int processInventory(void)
+{
+ if(menuTable[1])
+ {
+ menuElementSubStruct* pMenuElementSub = getSelectedEntryInMenu(menuTable[1]);
+
+ if(pMenuElementSub)
+ {
+ int var2;
+ int var4;
+
+ var2 = pMenuElementSub->var2;
+ var4 = pMenuElementSub->var4;
+
+ freeMenu(menuTable[1]);
+ menuTable[1] = NULL;
+
+ callInventoryObject(var2, var4, currentMenuElementX+80, currentMenuElementY);
+
+ return 1;
+ }
+ else
+ {
+ freeMenu(menuTable[1]);
+ menuTable[1] = NULL;
+ }
+ }
+
+ return 0;
+}
+
+int processInput(void)
+{
+ menuStruct* var_5C;
+
+ int16 mouseX;
+ int16 mouseY;
+ int16 button;
+
+ /*if(inputSub1keyboad())
+ {
+ return 1;
+ }*/
+
+ button = 0;
+
+ if(sysKey != -1)
+ {
+ button = sysKey;
+ mouseX = var11;
+ mouseY = var12;
+ sysKey = -1;
+ }
+ else
+ {
+ if(automaticMode == 0)
+ {
+ getMouseStatus(&main10, &mouseX, &button, &mouseY);
+ }
+ }
+
+ if(button)
+ {
+ nePasAffichierMenuDialogue = 0;
+ }
+
+ if(userDelay)
+ {
+ userDelay--;
+ return 0;
+ }
+
+ // test both buttons
+
+ if(((button&3) == 3) || keyboardVar == 0x44 || keyboardVar == 0x53)
+ {
+ changeCursor(0);
+ keyboardVar = 0;
+ return(playerMenu(mouseX, mouseY));
+ }
+
+ if(!userEnabled)
+ {
+ return 0;
+ }
+
+ if(currentActiveMenu != -1)
+ {
+ var_5C = menuTable[currentActiveMenu];
+
+ if(var_5C)
+ {
+ updateMenuMouse(mouseX,mouseY,var_5C);
+ }
+ }
+
+ if(var6)
+ {
+ ASSERT(0);
+ }
+
+ if(button & 1)
+ {
+ if(nePasAffichierMenuDialogue == 0)
+ {
+ nePasAffichierMenuDialogue = 1;
+
+ if(mouseVar1)
+ {
+ ASSERT(0);
+ }
+
+ if(var38 == 0) // are we in inventory mode ?
+ {
+ if(menuTable[0] == 0)
+ {
+ int X;
+ int Y;
+ int objIdx;
+
+ objIdx = getCursorFromObject(mouseX, mouseY, &X, &Y);
+
+ if(objIdx != -1)
+ {
+ //ASSERT(0);
+ //moveActor(X,Y,mouseVar1);
+ }
+ else
+ {
+ var34 = mouseX;
+ var35 = mouseY;
+ animationStart=true;
+ var38=0;
+ }
+ }
+ //ASSERT(0);
+ }
+ else
+ {
+ if(processInventory())
+ {
+ var37 = 1;
+ currentActiveMenu = 0;
+ var38 = 0;
+ }
+ else
+ {
+ currentActiveMenu = -1;
+ var38 = 0;
+ }
+
+ return 0;
+ }
+
+ //ASSERT(0);
+ }
+ }
+
+ if((button & 2) || (keyboardVar == 0x43) || (keyboardVar == 0x52))
+ {
+ if(nePasAffichierMenuDialogue == 0)
+ {
+ keyboardVar = 0;
+
+ if((mouseVar1 == 0) && (menuTable[0]))
+ {
+ ASSERT(0);
+ freeMenu(menuTable[0]);
+ menuTable[0] = NULL;
+ var37 = 0;
+ var38 = 0;
+ currentActiveMenu = -1;
+ }
+
+ if(var37 || var38 || menuTable[1])
+ {
+ nePasAffichierMenuDialogue = 1;
+ return 0;
+ }
+
+ buildInventory(mouseX, mouseY);
+
+ if(menuTable[1])
+ {
+ currentActiveMenu = 1;
+ var38 = 1;
+ }
+ else
+ {
+ var38 = 1;
+ }
+
+ nePasAffichierMenuDialogue = 1;
+ return 0;
+ }
+ }
+ return 0;
+}
+
+int oldMouseX;
+int oldMouseY;
+
+void manageEvents(int count) {
+ Common::Event event;
+
+ Common::EventManager *eventMan = g_system->getEventManager();
+ while (eventMan->pollEvent(event)) {
+ switch (event.type) {
+ /* case Common::EVENT_LBUTTONDOWN:
+ mouseLeft = 1;
+ break;
+ case Common::EVENT_RBUTTONDOWN:
+ mouseRight = 1;
+ break;
+ case Common::EVENT_MOUSEMOVE:
+ break;*/
+ case Common::EVENT_QUIT:
+ g_system->quit();
+ break;
+ /* case Common::EVENT_KEYDOWN:
+ switch (event.kbd.keycode) {
+ case '\n':
+ case '\r':
+ case 261: // Keypad 5
+ if (allowPlayerInput) {
+ mouseLeft = 1;
+ }
+ break;
+ case 27: // ESC
+ if (allowPlayerInput) {
+ mouseRight = 1;
+ }
+ break;
+ case 282: // F1
+ if (allowPlayerInput) {
+ playerCommand = 0; // EXAMINE
+ makeCommandLine();
+ }
+ break;
+ case 283: // F2
+ if (allowPlayerInput) {
+ playerCommand = 1; // TAKE
+ makeCommandLine();
+ }
+ break;
+ case 284: // F3
+ if (allowPlayerInput) {
+ playerCommand = 2; // INVENTORY
+ makeCommandLine();
+ }
+ break;
+ case 285: // F4
+ if (allowPlayerInput) {
+ playerCommand = 3; // USE
+ makeCommandLine();
+ }
+ break;
+ case 286: // F5
+ if (allowPlayerInput) {
+ playerCommand = 4; // ACTIVATE
+ makeCommandLine();
+ }
+ break;
+ case 287: // F6
+ if (allowPlayerInput) {
+ playerCommand = 5; // SPEAK
+ makeCommandLine();
+ }
+ break;
+ case 290: // F9
+ if (allowPlayerInput && !inMenu) {
+ makeActionMenu();
+ makeCommandLine();
+ }
+ break;
+ case 291: // F10
+ if (!disableSystemMenu && !inMenu) {
+ g_cine->makeSystemMenu();
+ }
+ break;
+ default:
+ //lastKeyStroke = event.kbd.keycode;
+ break;
+ }
+ break; */
+ default:
+ break;
+ }
+ }
+
+ /*if (count) {
+ mouseData.left = mouseLeft;
+ mouseData.right = mouseRight;
+ mouseLeft = 0;
+ mouseRight = 0;
+ }
+*/
+ int i;
+
+ for (i = 0; i < count; i++) {
+ //FIXME(?): Maybe there's a better way to "fix" this?
+ //
+ //Since not all backends/ports can update the screen
+ //100 times per second, only update the screen every
+ //other frame (1000 / 2 * 10 i.e. 50 times per second max.)
+ if (i % 2)
+ g_system->updateScreen();
+ g_system->delayMillis(10);
+ manageEvents(0);
+ }
+}
+
+void mainLoop(void)
+{
+ #define SPEED 40 /* Ticks per Frame */
+ #define SLEEP_MIN 20 /* Minimum time a sleep takes, usually 2*GRAN */
+ #define SLEEP_GRAN 1 /* Granularity of sleep */
+
+ int frames=0; /* Number of frames displayed */
+ int32 t_start,t_left;
+ uint32 t_end;
+ int32 q=0; /* Dummy */
+
+ int enableUser = 0;
+ int16 mouseX;
+ int16 mouseY;
+ int16 mouseButton;
+
+ scriptNameBuffer[0] = 0;
+ systemStrings.bootScriptName[0] = 0;
+ initVar4[0] = 0;
+ currentActiveMenu = -1;
+ main14 = -1;
+ mouseVar1 = 0;
+ main21 = 0;
+ main22 = 0;
+ main7 = 0;
+ main8 = 0;
+ main15 = 0;
+
+ if(initAllData())
+ {
+ int playerDontAskQuit = 1;
+ int quitValue2 = 1;
+ int quitValue = 0;
+
+ do
+ {
+ frames++;
+// t_start=Osystem_GetTicks();
+
+// readKeyboard();
+ playerDontAskQuit = processInput();
+
+ //if(enableUser)
+ {
+ userEnabled = 1;
+ enableUser = 0;
+ }
+
+ manageScripts(&scriptHandle1);
+ manageScripts(&scriptHandle2);
+
+ removeFinishedScripts(&scriptHandle1);
+ removeFinishedScripts(&scriptHandle2);
+
+ processActors();
+
+ if(var0)
+ {
+ ASSERT(0);
+ /* main3 = 0;
+ var24 = 0;
+ var23 = 0;
+
+ freeStuff2(); */
+ }
+
+ if(initVar4[0])
+ {
+ ASSERT(0);
+/* redrawStrings(0,&initVar4,8);
+
+ waitForPlayerInput();
+
+ initVar4 = 0; */
+ }
+
+ if(affichePasMenuJoueur)
+ {
+ if(main5)
+ fadeVar = 0;
+
+ /*if(fadeVar)
+ {
+ // TODO!
+ }*/
+
+ mainDraw(0);
+ flipScreen();
+
+ /* if(userEnabled && !main7 && !main15 && currentActiveMenu == -1)
+ {
+ getMouseStatus(&main10, &mouseX, &mouseButton, &mouseY);
+
+ if(mouseX != oldMouseX && mouseY != oldMouseY)
+ {
+ int cursorType;
+ int newCursor1;
+ int newCursor2;
+
+ oldMouseX = mouseX;
+ oldMouseY = mouseY;
+
+ cursorType = getCursorFromObject(mouseX, mouseY, &newCursor1, &newCursor2);
+
+ if(cursorType == 9)
+ {
+ changeCursor(5);
+ }
+ else
+ if(cursorType == -1)
+ {
+ changeCursor(6);
+ }
+ else
+ {
+ changeCursor(4);
+ }
+
+ }
+ }
+ else*/
+ {
+ changeCursor(0);
+ }
+
+ if(main7)
+ {
+ ASSERT(0);
+ }
+
+ if(main15)
+ {
+ ASSERT(0);
+ }
+
+ if(main14 != -1)
+ {
+ ASSERT(0);
+ }
+ }
+
+ // t_end = t_start+SPEED;
+// t_left=t_start-Osystem_GetTicks()+SPEED;
+#ifndef FASTDEBUG
+ /* if(t_left>0)
+ if(t_left>SLEEP_MIN)
+ Osystem_Delay(t_left-SLEEP_GRAN);
+ while(Osystem_GetTicks()<t_end){q++;}; */
+#endif
+ manageEvents(4);
+
+ }while(!playerDontAskQuit && quitValue2 && quitValue != 7);
+ }
+
+}
+
+int oldmain(int argc, char* argv[])
+{
+ printf("Cruise for a corpse recode\n");
+
+// OSystemInit();
+// osystem = new OSystem;
+
+ printf("Osystem Initialized\n");
+
+ printf("Initializing engine...\n");
+
+// initBuffer(scaledScreen,640,400);
+
+ fadeVar = 0;
+
+ //lowLevelInit();
+
+ // arg parser stuff
+
+ ptr_something = (ctpVar19Struct*)mallocAndZero(sizeof(ctpVar19Struct)*0x200);
+
+ /*volVar1 = 0;
+ fileData1 = 0;*/
+
+ /*PAL_fileHandle = -1;*/
+
+ // video init stuff
+
+ loadSystemFont();
+
+ // another bit of video init
+
+ if(!readVolCnf())
+ {
+ printf("Fatal: unable to load vol.cnf !\n");
+ return(-1);
+ }
+
+ printf("Entering main loop...\n");
+ mainLoop();
+
+ //freeStuff();
+
+ //freePtr(ptr_something);
+
+ return(0);
+}
+
+void changeCursor(uint16 cursorType)
+{
+ //printf("changeCursor %d\n", cursorType);
+}
+
+void* mallocAndZero(int32 size)
+{
+ void* ptr;
+
+ ptr = malloc(size);
+ memset(ptr,0,size);
+ return ptr;
+}
+
+} // End of namespace Cruise
diff --git a/engines/cruise/cruise_main.h b/engines/cruise/cruise_main.h
new file mode 100644
index 0000000000..0ca40229dc
--- /dev/null
+++ b/engines/cruise/cruise_main.h
@@ -0,0 +1,101 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef _CRUISE_H_
+#define _CRUISE_H_
+
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+
+#include "cruise/overlay.h"
+#include "cruise/object.h"
+#include "cruise/ctp.h"
+#include "cruise/actor.h"
+#include "cruise/vars.h"
+#include "cruise/font.h"
+#include "cruise/volume.h"
+#include "cruise/fontCharacterTable.h"
+#include "cruise/stack.h"
+#include "cruise/script.h"
+#include "cruise/various.h"
+#include "cruise/stringSupport.h"
+#include "cruise/function.h"
+#include "cruise/loadSave.h"
+#include "cruise/linker.h"
+#include "cruise/mouse.h"
+#include "cruise/gfxModule.h"
+#include "cruise/dataLoader.h"
+#include "cruise/perso.h"
+#include "cruise/menu.h"
+
+#include "cruise/background.h"
+#include "cruise/backgroundIncrust.h"
+
+#include "cruise/mainDraw.h"
+
+namespace Cruise {
+
+/*#define DUMP_SCRIPT
+#define DUMP_OBJECT*/
+
+#define ASSERT_PTR assert
+#define ASSERT assert
+
+
+int32 decomp(uint8 * in, uint8 * out, int32 size);
+
+ovlData3Struct* getOvlData3Entry(int32 scriptNumber, int32 param);
+ovlData3Struct* scriptFunc1Sub2(int32 scriptNumber, int32 param);
+int16 loadShort(void* ptr);
+void resetFileEntry(int32 entryNumber);
+void saveShort(void* ptr, int16 var);
+void* mallocAndZero(int32 size);
+uint8* mainProc14(uint16 overlay, uint16 idx);
+void printInfoBlackBox(char* string);
+void waitForPlayerInput(void);
+int loadCtp(uint8* ctpName);
+void loadPakedFileToMem(int fileIdx, uint8* buffer);
+int loadScriptSub1(int scriptIdx, int param);
+void resetFileEntryRange(int param1, int param2);
+int getProcParam(int overlayIdx, int param2, uint8* name);
+void changeScriptParamInList(int param1, int param2, scriptInstanceStruct* pScriptInstance,int newValue, int param3);
+uint8* getDataFromData3(ovlData3Struct* ptr, int param);
+int32 prepareWordRender(int32 param, int32 var1,int16* out2, uint8* ptr3,uint8* string);
+void removeExtention(const char* name, char* buffer);
+void resetRaster(uint8* rasterPtr, int32 rasterSize);
+void changeCursor(uint16 cursorType);
+void resetPtr(objectStruct* ptr);
+void resetPtr2(scriptInstanceStruct* ptr);
+void getFileExtention(const char* name,char* buffer);
+void *allocAndZero(int size);
+void freeStuff2(void);
+char* getObjectName(int index, uint8* string);
+void mainLoop(void);
+} // End of namespace Cruise
+
+#endif
diff --git a/engines/cruise/ctp.cpp b/engines/cruise/ctp.cpp
new file mode 100644
index 0000000000..10a09f6260
--- /dev/null
+++ b/engines/cruise/ctp.cpp
@@ -0,0 +1,423 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cruise/cruise_main.h"
+
+namespace Cruise {
+
+ctpVar19Struct* ptr_something;
+ctpVar19Struct* polyStruct;
+ctpVar19Struct* ctpVar11;
+ctpVar19Struct* ctpVar13;
+ctpVar19Struct* ctpVar15;
+
+uint8* ctpVar17;
+ctpVar19Struct* ctpVar19;
+
+int currentWalkBoxCenterX;
+int currentWalkBoxCenterY;
+int currentWalkBoxCenterXBis;
+int currentWalkBoxCenterYBis;
+
+int ctpVarUnk;
+uint8 walkboxTable[0x12];
+
+int ctpProc2(int varX, int varY, int paramX, int paramY)
+{
+ int diffX = abs(paramX - varX);
+ int diffY = abs(paramY - varY);
+
+ if(diffX > diffY)
+ {
+ diffY = diffX;
+ }
+
+ ctpVar14 = diffY; // highest difference
+ return(diffY);
+}
+
+// this function process path finding coordinates
+void loadCtpSub2(short int coordCount, short int* ptr) // coordCount = ctp_routeCoordCount, ptr = ctpVar8
+{
+ int i;
+ int offset = 0;
+
+ short int* cur_ctp_routeCoords = (short int*)ctp_routeCoords; // coordinates table
+ int8* cur_ctp_routes = (int8*)ctp_routes;
+
+ for(i = 0; i < coordCount; i++) // for i < ctp_routeCoordCount
+ {
+ int varX = cur_ctp_routeCoords[0]; // x
+ int varY = cur_ctp_routeCoords[1]; // y
+
+ int di = 0;
+ int var4Offset = 2;
+
+ while(*(int16*) cur_ctp_routes > di) // while (coordCount > counter++)
+ {
+ int idx = *(int16*)(cur_ctp_routes + var4Offset);
+ ptr[offset + idx] = ctpProc2(varX , varY, ctp_routeCoords[idx][0], ctp_routeCoords[idx * 2][1]);
+
+ var4Offset += 2;
+ di++;
+ }
+
+ offset += 10;
+ cur_ctp_routes += 20;
+ cur_ctp_routeCoords += 2;
+ }
+}
+
+void getWalkBoxCenter(int boxIdx, uint16* walkboxTable)
+{
+ int minX = 1000;
+ int minY = 1000;
+ int maxX = -1;
+ int maxY = -1;
+
+ ASSERT(boxIdx <= 15); // max number of walkboxes is 16
+ ASSERT(walkboxTable[boxIdx * 40]); // we should never have an empty walk box
+
+ if(walkboxTable[boxIdx * 40] > 0)
+ {
+ int numPoints = walkboxTable[boxIdx * 40];
+ uint16* pCurrentPtr = walkboxTable + (boxIdx * 40) + 1;
+
+ int i;
+
+ for(i = 0; i < numPoints; i++)
+ {
+ int X = *(pCurrentPtr++);
+ int Y = *(pCurrentPtr++);;
+
+ if(X < minX)
+ minX = X;
+
+ if(X > maxX)
+ maxX = X;
+
+ if(Y < minY)
+ minY = Y;
+
+ if(Y > maxY)
+ maxY = Y;
+ }
+ }
+
+ currentWalkBoxCenterX = ((maxX - minX) / 2) + minX;
+ currentWalkBoxCenterY = ((maxY - minY) / 2) + minY;
+}
+
+// ax dx bx
+void renderCTPWalkBox(int X1, int Y1, int X2, int scale, int Y2, uint16* walkboxData)
+{
+ int numPoints;
+ int wbSelf1;
+ int wbSelf2;
+ int i;
+ int16* destination;
+
+ wbSelf1 = upscaleValue(X1, scale) - X2;
+ wbSelf2 = upscaleValue(Y1, scale) - Y2;
+
+ numPoints = *(walkboxData++);
+
+ destination = polyBuffer2;
+
+ for(i = 0; i < numPoints; i++)
+ {
+ int pointX = *(walkboxData++);
+ int pointY = *(walkboxData++);
+
+ int scaledX = upscaleValue(pointX, scale) - wbSelf1;
+ int scaledY = upscaleValue(pointY, scale) - wbSelf2;
+
+ *(destination++) = scaledX >> 16;
+ *(destination++) = scaledY >> 16;
+ }
+
+ m_color = 0;
+ ctpVarUnk = 0;
+
+ for(i = 0; i < numPoints; i++)
+ {
+ walkboxTable[i] = i;
+ }
+
+ drawPolyMode2((char*)walkboxTable, numPoints);
+}
+
+// this process the walkboxes
+void loadCtpSub1(int boxIdx, int scale, uint16* walkboxTable, ctpVar19Struct* param4)
+{
+ int minX = 1000;
+ int minY = 1000;
+ int maxX = -1;
+ int maxY = -1;
+
+ ctpVar19Struct* var_1C;
+ ctpVar19Struct* var_12;
+ int16* var_18;
+ int16* si;
+ // int16* di;
+ // uint8* cx;
+ // int bx;
+ // int ax;
+ // int var_2;
+ int var_E;
+ int var_C = 1000;
+ int var_A = 0;
+ ctpVar19SubStruct* subStruct;
+
+ ASSERT(boxIdx <= 15);
+
+ if(walkboxTable[boxIdx * 40] > 0) // is walkbox used ?
+ {
+ getWalkBoxCenter(boxIdx, walkboxTable);
+
+ currentWalkBoxCenterYBis = currentWalkBoxCenterY;
+ currentWalkBoxCenterXBis = currentWalkBoxCenterX;
+ // + 512
+ renderCTPWalkBox(currentWalkBoxCenterX, currentWalkBoxCenterY, currentWalkBoxCenterX, scale + 0x200, currentWalkBoxCenterY, walkboxTable + boxIdx * 40);
+
+ var_1C = param4;
+ var_12 = var_1C + 1; // next
+
+ var_18 = polyBuffer3;
+ var_E = 0;
+
+ si = &polyBuffer3[1];
+ /* if(*si>=0)
+ {
+ di = si;
+ cx = var_12;
+
+ do
+ {
+ di++;
+ bx = di[-1];
+ ax = di[0];
+ di++;
+
+ var_2 = ax;
+ if(var_C < bx)
+ {
+ var_C = bx;
+ }
+
+ if(var_2 < var_A)
+ {
+ var_A = var_2;
+ }
+
+ *cx = bx;
+ cx++;
+ *cx = var_2;
+ cx++;
+ var_E ++;
+ }while(di);
+
+ var_12 = cx;
+ }*/
+
+ /*************/
+ {
+ int i;
+ int numPoints;
+ uint16* pCurrentPtr = walkboxTable + boxIdx * 40;
+
+ numPoints = *(pCurrentPtr++);
+
+ for(i = 0; i < numPoints; i++)
+ {
+ int X = *(pCurrentPtr++);
+ int Y = *(pCurrentPtr++);
+
+ if(X < minX)
+ minX = X;
+
+ if(X > maxX)
+ maxX = X;
+
+ if(Y < minY)
+ minY = Y;
+
+ if(Y > maxY)
+ maxY = Y;
+ }
+ }
+ /************/
+
+ var_1C->field_0 = var_12;
+ ctpVar13 = var_12;
+ var_12->field_0 = (ctpVar19Struct*)(-1);
+
+ subStruct = &var_1C->subStruct;
+
+ subStruct->boxIdx = boxIdx;
+ subStruct->type = walkboxType[boxIdx];
+ subStruct->minX = minX;
+ subStruct->maxX = maxX;
+ subStruct->minY = minY;
+ subStruct->maxY = maxY;
+ }
+}
+
+int loadCtp(uint8* ctpName)
+{
+ int walkboxCounter; // si
+ uint8* ptr;
+ uint8* dataPointer; // ptr2
+ char fileType[5]; // string2
+ short int segementSizeTable[7]; // tempTable
+ char string[32];
+
+ if(ctpVar1 == 0)
+ {
+ int i;
+
+ for(i = 0; i < 10; i++)
+ {
+ persoTable[i] = NULL;
+ }
+ }
+
+ if(!loadFileSub1(&ptr,ctpName,0))
+ {
+ free(ptr);
+ return(-18);
+ }
+
+ dataPointer = ptr;
+
+ fileType[4] = 0;
+ memcpy(fileType, dataPointer, 4); // get the file type, first 4 bytes of the CTP file
+ dataPointer += 4;
+
+ if(strcmp(fileType, "CTP "))
+ {
+ free(ptr);
+ return(0);
+ }
+
+ memcpy(&ctp_routeCoordCount , dataPointer, 2); // get the number of path-finding coordinates
+ dataPointer += 2;
+ flipShort(&ctp_routeCoordCount);
+
+ memcpy(segementSizeTable, dataPointer, 0xE);
+ dataPointer += 0xE; // + 14
+ flipGen(segementSizeTable, 0xE);
+
+ memcpy(ctp_routeCoords, dataPointer, segementSizeTable[0]); // get the path-finding coordinates
+ dataPointer += segementSizeTable[0];
+ flipGen(ctp_routeCoords, segementSizeTable[0]);
+
+ memcpy(ctp_routes, dataPointer, segementSizeTable[1]); // get the path-finding line informations (indexing the routeCoords array)
+ dataPointer += segementSizeTable[1];
+ flipGen(ctp_routes, segementSizeTable[1]);
+
+ memcpy(ctp_walkboxTable, dataPointer, segementSizeTable[2]);// get the walkbox coordinates and lines
+ dataPointer += segementSizeTable[2];
+ flipGen(ctp_walkboxTable, segementSizeTable[2]);
+
+ if(ctpVar1)
+ {
+ dataPointer += segementSizeTable[3];
+ dataPointer += segementSizeTable[4];
+ }
+ else
+ {
+ memcpy(walkboxType, dataPointer, segementSizeTable[3]); // get the walkbox type
+ dataPointer += segementSizeTable[3];
+ flipGen(walkboxType, segementSizeTable[3]); // Type: 0x00 - non walkable, 0x01 - walkable, 0x02 - exit zone
+
+ memcpy(walkboxChange, dataPointer, segementSizeTable[4]); // change indicator, walkbox type can change, i.e. blocked by object (values are either 0x00 or 0x01)
+ dataPointer += segementSizeTable[4];
+ flipGen(walkboxChange, segementSizeTable[4]);
+ }
+
+ memcpy(ctpVar6, dataPointer, segementSizeTable[5]); // unknown? always 2*16 bytes (used by S24.CTP, S33.CTP, S33_2.CTP, S34.CTP, S35.CTP, S36.CTP; values can be 0x00, 0x01, 0x03, 0x05)
+ dataPointer += segementSizeTable[5];
+ flipGen(ctpVar6,segementSizeTable[5]);
+
+ memcpy(ctp_scale, dataPointer, segementSizeTable[6]); // scale values for the walkbox coordinates (don't know why there is a need for scaling walkboxes)
+ dataPointer += segementSizeTable[6];
+ flipGen(ctp_scale, segementSizeTable[6]); // ok
+
+ free(ptr);
+
+ strcpyuint8(string, currentCtpName);
+
+ numberOfWalkboxes = segementSizeTable[6] / 2; // get the number of walkboxes
+
+ loadCtpSub2(ctp_routeCoordCount, ctpVar8); // process path-finding stuff
+
+ polyStruct = ctpVar11 = ctpVar13 = ptr_something;
+
+ ptr = (uint8*) polyStruct;
+
+ walkboxCounter = numberOfWalkboxes;
+
+ while((--walkboxCounter) >= 0)
+ {
+ loadCtpSub1(walkboxCounter, 0, ctp_walkboxTable, ctpVar13);
+ }
+
+ ctpVar15 = ctpVar13 + 1; // was after the -1 thing
+
+ walkboxCounter = numberOfWalkboxes;
+
+ while(--walkboxCounter)
+ {
+ loadCtpSub1(walkboxCounter, ctp_scale[walkboxCounter] * 20, ctp_walkboxTable, ctpVar13);
+ }
+
+ //ctpVar17 = ctpVar13 - ptr + 4;
+
+ {
+ int numOfUsedEntries = ctpVar13 - (ctpVar19Struct*) ptr;
+ numOfUsedEntries++;// there is a -1 entry at the end... Original was only mallocing numOfUsedEntries*sizeof(ctpVar19Struct)+4, but this is a bit ugly...
+ ctpVar13 = ctpVar11 = polyStruct = (ctpVar19Struct*)malloc(numOfUsedEntries * sizeof(ctpVar19Struct));
+ }
+
+ walkboxCounter = numberOfWalkboxes;
+ while((--walkboxCounter) >= 0)
+ {
+ loadCtpSub1(walkboxCounter, 0, ctp_walkboxTable, ctpVar13);
+ }
+
+ ctpVar15 = ctpVar13 + 1;
+
+ walkboxCounter = numberOfWalkboxes;
+ while(--walkboxCounter)
+ {
+ loadCtpSub1(walkboxCounter, ctp_scale[walkboxCounter] * 20, ctp_walkboxTable, ctpVar13);
+ }
+
+ ctpVar19 = ctpVar11;
+
+ return(1);
+}
+
+} // End of namespace Cruise
diff --git a/engines/cruise/ctp.h b/engines/cruise/ctp.h
new file mode 100644
index 0000000000..397f87a5d6
--- /dev/null
+++ b/engines/cruise/ctp.h
@@ -0,0 +1,64 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef _CTP_H_
+#define _CTP_H_
+
+namespace Cruise {
+
+struct ctpVar19SubStruct
+{
+ uint16 boxIdx; //0
+ uint16 type; //2
+ uint16 minX; //4
+ uint16 maxX; //6
+ uint16 minY; //8
+ uint16 maxY; //A
+};
+
+typedef struct ctpVar19SubStruct ctpVar19SubStruct;
+
+struct ctpVar19Struct
+{
+ struct ctpVar19Struct* field_0; //0
+ ctpVar19SubStruct subStruct;
+};
+
+typedef struct ctpVar19Struct ctpVar19Struct;
+
+extern ctpVar19Struct* ptr_something;
+extern ctpVar19Struct* polyStruct;
+extern ctpVar19Struct* ctpVar11;
+extern ctpVar19Struct* ctpVar13;
+extern ctpVar19Struct* ctpVar15;
+
+extern uint8* ctpVar17;
+extern ctpVar19Struct* ctpVar19;
+
+int loadCtp(uint8* ctpName);
+int ctpProc2(int varX, int varY, int paramX, int paramY);
+
+} // End of namespace Cruise
+
+#endif \ No newline at end of file
diff --git a/engines/cruise/dataLoader.cpp b/engines/cruise/dataLoader.cpp
new file mode 100644
index 0000000000..dcc1e8cca6
--- /dev/null
+++ b/engines/cruise/dataLoader.cpp
@@ -0,0 +1,532 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cruise/cruise_main.h"
+
+namespace Cruise {
+
+void loadSetEntry(uint8* name, uint8* ptr, int currentEntryIdx, int currentDestEntry);
+void loadFNTSub(uint8* ptr, int destIdx);
+
+enum fileTypeEnum
+{
+ type_UNK,
+ type_SPL,
+ type_SET,
+ type_FNT,
+};
+
+typedef enum fileTypeEnum fileTypeEnum;
+
+int loadSingleFile;
+
+// TODO: Unify decodeGfxFormat1, decodeGfxFormat4 and decodeGfxFormat5
+
+void decodeGfxFormat1(dataFileEntry* pCurrentFileEntry)
+{
+ uint8* buffer;
+ uint8* dataPtr = pCurrentFileEntry->subData.ptr;
+
+ int spriteSize = pCurrentFileEntry->height * pCurrentFileEntry->widthInColumn * 8;
+ int x = 0;
+
+ buffer = (uint8*)malloc(spriteSize);
+
+ while (x < spriteSize)
+ {
+ uint8 c;
+ uint16 p0;
+
+ p0 = (dataPtr[0] << 8) | dataPtr[1];
+
+ /* decode planes */
+ for (c = 0; c < 16; c++)
+ {
+ buffer[x+c] = ((p0 >> 15) & 1);
+
+ p0 <<= 1;
+ }
+
+ x+=16;
+
+ dataPtr+=2;
+ }
+
+ pCurrentFileEntry->subData.ptr = buffer;
+}
+
+
+void decodeGfxFormat4(dataFileEntry* pCurrentFileEntry)
+{
+ uint8* buffer;
+ uint8* dataPtr = pCurrentFileEntry->subData.ptr;
+
+ int spriteSize = pCurrentFileEntry->height * pCurrentFileEntry->widthInColumn * 2;
+ int x = 0;
+
+ buffer = (uint8*)malloc(spriteSize);
+
+ while (x < spriteSize)
+ {
+ uint8 c;
+ uint16 p0;
+ uint16 p1;
+ uint16 p2;
+ uint16 p3;
+
+ p0 = (dataPtr[0] << 8) | dataPtr[1];
+ p1 = (dataPtr[2] << 8) | dataPtr[3];
+ p2 = (dataPtr[4] << 8) | dataPtr[5];
+ p3 = (dataPtr[6] << 8) | dataPtr[7];
+
+ /* decode planes */
+ for (c = 0; c < 16; c++)
+ {
+ buffer[x+c] = ((p0 >> 15) & 1) | ((p1 >> 14) & 2) | ((p2 >> 13) & 4) | ((p3 >> 12) & 8);
+
+ p0 <<= 1;
+ p1 <<= 1;
+ p2 <<= 1;
+ p3 <<= 1;
+ }
+
+ x+=16;
+
+ dataPtr+=8;
+ }
+
+ pCurrentFileEntry->subData.ptr = buffer;
+}
+
+void decodeGfxFormat5(dataFileEntry* pCurrentFileEntry)
+{
+ uint8* buffer;
+ uint8* dataPtr = pCurrentFileEntry->subData.ptr;
+
+ int spriteSize = pCurrentFileEntry->height * pCurrentFileEntry->widthInColumn;
+ int x = 0;
+ int range = pCurrentFileEntry->height * pCurrentFileEntry->width;
+
+ buffer = (uint8*)malloc(spriteSize);
+
+ while (x < spriteSize)
+ {
+ uint8 c;
+ uint16 p0;
+ uint16 p1;
+ uint16 p2;
+ uint16 p3;
+ uint16 p4;
+
+ p0 = (dataPtr[0 + range * 0] << 8) | dataPtr[1 + range * 0];
+ p1 = (dataPtr[0 + range * 1] << 8) | dataPtr[1 + range * 1];
+ p2 = (dataPtr[0 + range * 2] << 8) | dataPtr[1 + range * 2];
+ p3 = (dataPtr[0 + range * 3] << 8) | dataPtr[1 + range * 3];
+ p4 = (dataPtr[0 + range * 4] << 8) | dataPtr[1 + range * 4];
+
+ /* decode planes */
+ for (c = 0; c < 16; c++)
+ {
+ buffer[x+c] = ((p0 >> 15) & 1) | ((p1 >> 14) & 2) | ((p2 >> 13) & 4) | ((p3 >> 12) & 8) | ((p4 >> 11) & 16);
+
+ p0 <<= 1;
+ p1 <<= 1;
+ p2 <<= 1;
+ p3 <<= 1;
+ p4 <<= 1;
+ }
+
+ x+=16;
+
+ dataPtr+=2;
+ }
+
+ pCurrentFileEntry->subData.ptr = buffer;
+}
+
+int updateResFileEntry(int height, int width, int entryNumber, int resType)
+{
+ int div = 0;
+ int size;
+
+ resetFileEntry(entryNumber);
+
+ filesDatabase[entryNumber].subData.field_1C = 0;
+
+ size = height * width; // for sprites: width * height
+
+ if(resType == 4)
+ {
+ div = size / 4;
+ }
+ else if (resType == 5)
+ {
+ width = (width * 8) / 5;
+ }
+
+ filesDatabase[entryNumber].subData.ptr = (uint8*)mallocAndZero(size + div);
+
+ if(!filesDatabase[entryNumber].subData.ptr)
+ return(-2);
+
+ filesDatabase[entryNumber].widthInColumn = width;
+ filesDatabase[entryNumber].subData.ptr2 = filesDatabase[entryNumber].subData.ptr+size;
+ filesDatabase[entryNumber].width = width / 8;
+ filesDatabase[entryNumber].resType = resType;
+ filesDatabase[entryNumber].height = height;
+ filesDatabase[entryNumber].subData.index = -1;
+
+ return entryNumber;
+}
+
+
+int createResFileEntry(int width, int height, int resType)
+{
+ int i;
+ int entryNumber;
+ int div = 0;
+ int size;
+
+ printf("Executing untested createResFileEntry!\n");
+ exit(1);
+
+ for(i = 0; i < 257; i++)
+ {
+ if(!filesDatabase[i].subData.ptr)
+ break;
+ }
+
+ if(i >= 257)
+ {
+ return(-19);
+ }
+
+ entryNumber = i;
+
+ filesDatabase[entryNumber].subData.field_1C = 0;
+
+ size = width * height; // for sprites: width * height
+
+ if(resType == 4)
+ {
+ div = size / 4;
+ }
+ else if (resType == 5)
+ {
+ width = (width * 8) / 5;
+ }
+
+ filesDatabase[entryNumber].subData.ptr = (uint8*)mallocAndZero(size + div);
+
+ if(filesDatabase[entryNumber].subData.ptr)
+ {
+ return(-2);
+ }
+
+ filesDatabase[entryNumber].widthInColumn = width;
+ filesDatabase[entryNumber].subData.ptr2 = filesDatabase[entryNumber].subData.ptr + size;
+ filesDatabase[entryNumber].width = width / 8;
+ filesDatabase[entryNumber].resType = resType;
+ filesDatabase[entryNumber].height = height;
+ filesDatabase[entryNumber].subData.index = -1;
+
+ return entryNumber;
+}
+
+fileTypeEnum getFileType(uint8* name)
+{
+ char extentionBuffer[16];
+
+ fileTypeEnum newFileType = type_UNK;
+
+ getFileExtention((char*)name,extentionBuffer);
+
+ if(!strcmp(extentionBuffer,".SPL"))
+ {
+ newFileType = type_SPL;
+ }
+ else
+ if(!strcmp(extentionBuffer,".SET"))
+ {
+ newFileType = type_SET;
+ }
+ else
+ if(!strcmp(extentionBuffer,".FNT"))
+ {
+ newFileType = type_FNT;
+ }
+
+ ASSERT(newFileType != type_UNK);
+
+ return newFileType;
+}
+
+int getNumMaxEntiresInSet(uint8* ptr)
+{
+ uint16 numEntries = *(uint16*)(ptr + 4);
+ flipShort(&numEntries);
+
+ return numEntries;
+}
+
+int loadFileMode2(uint8* name, int startIdx, int currentEntryIdx, int numIdx)
+{
+ uint8* ptr = NULL;
+ fileTypeEnum fileType;
+
+ fileType = getFileType(name);
+
+ loadFileSub1(&ptr, name, NULL);
+
+ switch(fileType)
+ {
+ case type_SET:
+ {
+ int i;
+ int numMaxEntriesInSet = getNumMaxEntiresInSet(ptr);
+
+ for(i = 0; i < numIdx; i++)
+ {
+ if ((currentEntryIdx + i) > numMaxEntriesInSet)
+ {
+ return 0; // exit if limit is reached
+ }
+ loadSetEntry(name, ptr, currentEntryIdx + i, startIdx + i);
+ }
+
+ break;
+ }
+ case type_FNT:
+ {
+ loadFNTSub(ptr, startIdx);
+ break;
+ }
+ }
+ return 0;
+}
+
+int loadFullBundle(uint8* name, int startIdx)
+{
+ uint8* ptr = NULL;
+ fileTypeEnum fileType;
+
+ fileType = getFileType(name);
+
+ loadFileSub1(&ptr,name,NULL);
+
+ switch(fileType)
+ {
+ case type_SET:
+ {
+ int i;
+ int numMaxEntriesInSet;
+
+ numMaxEntriesInSet = getNumMaxEntiresInSet(ptr); // get maximum number of sprites/animations in SET file
+
+ for(i = 0; i < numMaxEntriesInSet; i++)
+ {
+ loadSetEntry(name, ptr, i, startIdx+i);
+ }
+
+ break;
+ }
+ case type_FNT:
+ {
+ loadFNTSub(ptr, startIdx);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+void loadFNTSub(uint8* ptr, int destIdx)
+{
+ uint8* ptr2 = ptr;
+ uint8* destPtr;
+ int fileIndex;
+ uint32 fontSize;
+
+ ptr2 += 4;
+ memcpy(&loadFileVar1, ptr2, 4);
+
+ flipLong(&loadFileVar1);
+
+ if(destIdx == -1)
+ {
+ fileIndex = createResFileEntry(loadFileVar1, 1 ,1);
+ }
+ else
+ {
+ fileIndex = updateResFileEntry(loadFileVar1, 1, destIdx, 1);
+ }
+
+ destPtr = filesDatabase[fileIndex].subData.ptr;
+
+ memcpy(destPtr, ptr2, loadFileVar1);
+
+ memcpy(&fontSize,ptr2,4);
+ flipLong(&fontSize);
+
+ if(destPtr!=NULL)
+ {
+ int32 i;
+ uint8* currentPtr;
+
+ destPtr = filesDatabase[fileIndex].subData.ptr;
+
+ flipLong((int32*) destPtr);
+ flipLong((int32*) (destPtr + 4));
+ flipGen(destPtr + 8, 6);
+
+ currentPtr = destPtr + 14;
+
+ for(i = 0; i < *(int16*) (destPtr + 8); i++)
+ {
+ flipLong((int32*) currentPtr);
+ currentPtr += 4;
+
+ flipGen(currentPtr, 8);
+ currentPtr += 8;
+ }
+ }
+}
+
+void loadSetEntry(uint8* name, uint8* ptr, int currentEntryIdx, int currentDestEntry)
+{
+ uint8* ptr2;
+ uint8* ptr3;
+ int offset;
+ int sec = 0;
+ uint16 numIdx;
+
+ if (!strcmpuint8(ptr,"SEC"))
+ {
+ sec = 1;
+ }
+
+ ptr2 = ptr + 4;
+
+ memcpy(&numIdx,ptr2,2);
+ flipShort(&numIdx);
+
+ ptr3 = ptr + 6;
+
+ offset = currentEntryIdx*16;
+
+ {
+ uint8* ptr4;
+ int resourceSize;
+ int fileIndex;
+ setHeaderEntry localBuffer;
+ uint8* ptr5;
+
+ ptr4 = ptr + offset + 6;
+
+ memcpy(&localBuffer, ptr4, sizeof(setHeaderEntry));
+
+ flipLong((int32*) &localBuffer.field_0);
+ flipGen(&localBuffer.width, 12);
+
+ if ((sec == 1) || (localBuffer.type == 5))
+ {
+ localBuffer.width = localBuffer.width - (localBuffer.type * 2); // Type 1: Width - (1*2) , Type 5: Width - (5*2)
+ }
+
+ resourceSize = localBuffer.width * localBuffer.height;
+
+ if(currentDestEntry == -1)
+ {
+ fileIndex = createResFileEntry(localBuffer.width,localBuffer.height,localBuffer.type);
+ }
+ else
+ {
+ fileIndex = updateResFileEntry(localBuffer.height, localBuffer.width, currentDestEntry, localBuffer.type);
+ }
+
+ if(fileIndex < 0)
+ {
+ return; // TODO: buffer is not freed
+ }
+
+ ptr5 = ptr3 + localBuffer.field_0 + numIdx * 16;
+
+ memcpy(filesDatabase[fileIndex].subData.ptr,ptr5, resourceSize);
+ ptr5 += resourceSize;
+
+ switch(localBuffer.type)
+ {
+ case 0:
+ {
+ filesDatabase[fileIndex].subData.resourceType = 8;
+ break;
+ }
+ case 1:
+ {
+ filesDatabase[fileIndex].subData.resourceType = 2;
+ decodeGfxFormat1(&filesDatabase[fileIndex]);
+ break;
+ }
+ case 4:
+ {
+ filesDatabase[fileIndex].width *= 2;
+ filesDatabase[fileIndex].subData.resourceType = 4;
+ decodeGfxFormat4(&filesDatabase[fileIndex]);
+ break;
+ }
+ case 5:
+ {
+ if (sec == 0)
+ {
+ // TODO sec type 5 needs special conversion. cut out 2 bytes at every width/5 position.
+ return;
+ }
+ filesDatabase[fileIndex].subData.resourceType = 4;
+ decodeGfxFormat5(&filesDatabase[fileIndex]);
+ break;
+ }
+ case 8:
+ {
+ filesDatabase[fileIndex].subData.resourceType = 4; // dummy !
+ break;
+ }
+ default:
+ {
+ printf("Unsuported gfx loading type: %d\n", localBuffer.type);
+ break;
+ }
+ }
+
+ filesDatabase[fileIndex].subData.index = currentDestEntry;
+ filesDatabase[fileIndex].subData.transparency = localBuffer.transparency; /*% 0x10*/;
+
+ strcpyuint8(filesDatabase[fileIndex].subData.name,name);
+ }
+
+ // TODO: free
+
+ return;
+}
+
+} // End of namespace Cruise
diff --git a/engines/cruise/dataLoader.h b/engines/cruise/dataLoader.h
new file mode 100644
index 0000000000..859a0372dc
--- /dev/null
+++ b/engines/cruise/dataLoader.h
@@ -0,0 +1,38 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef _DATALOADER_H_
+#define _DATALOADER_H_
+
+namespace Cruise {
+
+int loadData(uint8* name, int startIdx);
+int loadFileMode2(uint8* name, int param, int startIdx, int numIdx);
+int loadFileSub1(uint8** ptr, uint8* name, uint8* ptr2);
+
+int loadFullBundle(uint8* name, int startIdx);
+
+} // End of namespace Cruise
+
+#endif \ No newline at end of file
diff --git a/engines/cruise/decompiler.cpp b/engines/cruise/decompiler.cpp
new file mode 100644
index 0000000000..bb0c4af816
--- /dev/null
+++ b/engines/cruise/decompiler.cpp
@@ -0,0 +1,1549 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cruise/cruise_main.h"
+
+namespace Cruise {
+
+#include <stdarg.h>
+
+#ifdef DUMP_SCRIPT
+
+#define numMaxLignes 100000
+#define lineMaxSize 10000
+
+int currentLineType = 0;
+
+struct decompileLineStruct
+{
+ int lineOffset;
+ char line[lineMaxSize];
+ int indent;
+ int type;
+ int pendingElse;
+};
+
+struct decompileLineStruct decompileLineTable[numMaxLignes];
+
+int positionInDecompileLineTable;
+
+int failed;
+
+char* currentDecompScript;
+scriptInstanceStruct dummy;
+scriptInstanceStruct* currentDecompScriptPtr = &dummy;
+
+uint8* getDataFromData3(ovlData3Struct* ptr, int param);
+
+opcodeTypeFunction decompOpcodeTypeTable[64];
+
+int currentLineIdx = 0;
+
+unsigned long int currentOffset;
+
+unsigned long int dumpIdx = 0;
+
+FILE* fHandle = NULL;
+
+#define DECOMPILER_STACK_DEPTH 100
+#define DECOMPILER_STACK_ENTRY_SIZE 5000
+
+char tempbuffer[5000];
+
+char decompileStack[DECOMPILER_STACK_DEPTH][DECOMPILER_STACK_ENTRY_SIZE];
+
+unsigned long int decompileStackPosition = 0;
+
+uint8 stringName[256];
+
+ovlData3Struct* currentScript;
+
+ovlDataStruct* currentDecompOvl;
+int currentDecompScriptIdx;
+
+char decompSaveOpcodeVar[256];
+
+uint8* getStringNameFromIdx(uint16 stringTypeIdx, char* offset)
+{
+ switch(stringTypeIdx&7)
+ {
+ case 2:
+ {
+ sprintf(stringName,"\"%s\"",currentScript->dataPtr+currentScript->offsetToSubData3 + atoi(offset));
+ break;
+ }
+ case 5:
+ {
+ sprintf(stringName,"vars[%s]",offset);
+ break;
+ }
+ default:
+ {
+ sprintf(stringName,"string[%d][%s]",stringTypeIdx&7,offset);
+ break;
+ }
+ }
+
+ return stringName;
+}
+
+char* resolveMessage(char* messageIdxString)
+{
+ char buffer[500];
+ int variable;
+
+ variable = atoi(messageIdxString);
+ sprintf(buffer,"%d",variable);
+
+ if(strcmp(buffer,messageIdxString))
+ {
+ return messageIdxString;
+ }
+ else
+ {
+ return currentDecompOvl->stringTable[atoi(messageIdxString)].string;
+ }
+}
+
+void pushDecomp(char* string, ...)
+{
+ va_list va;
+
+ va_start(va,string);
+ vsprintf(decompileStack[decompileStackPosition],string,va);
+ va_end(va);
+
+ // fprintf(fHandle, "----> %s\n",decompileStack[decompileStackPosition]);
+
+ decompileStackPosition++;
+}
+
+void resolveDecompShort(char* buffer)
+{
+ ovlData3Struct* data3Ptr = currentScript;
+
+ {
+ int i;
+
+ importScriptStruct* importEntry = (importScriptStruct*) (data3Ptr->dataPtr + data3Ptr->offsetToImportData);
+
+ for(i=0;i<data3Ptr->numImport;i++)
+ {
+ switch(importEntry->type)
+ {
+ case 20: // script
+ case 30:
+ case 40:
+ case 50:
+ {
+ if(importEntry->offset == currentDecompScriptPtr->var4 - 3) // param1
+ {
+ sprintf(buffer,data3Ptr->dataPtr+data3Ptr->offsetToImportName+importEntry->offsetToName);
+ return;
+ }
+ if(importEntry->offset == currentDecompScriptPtr->var4 - 6) // param2
+ {
+ sprintf(buffer,"linkedIdx");
+ return;
+ }
+ break;
+ }
+ default:
+ {
+ if(importEntry->offset == currentDecompScriptPtr->var4 - 4)
+ {
+ sprintf(buffer,data3Ptr->dataPtr+data3Ptr->offsetToImportName+importEntry->offsetToName);
+ return;
+ }
+ }
+ }
+ importEntry++;
+ }
+ }
+
+ buffer[0] = 0;
+
+}
+
+void resolveDecompChar(char* buffer)
+{
+ ovlData3Struct* data3Ptr = currentScript;
+
+ {
+ int i;
+
+ importScriptStruct* importEntry = (importScriptStruct*) (data3Ptr->dataPtr + data3Ptr->offsetToImportData);
+
+ for(i=0;i<data3Ptr->numImport;i++)
+ {
+ switch(importEntry->type)
+ {
+ default:
+ {
+ if(importEntry->offset == currentDecompScriptPtr->var4 - 2)
+ {
+ sprintf(buffer,data3Ptr->dataPtr+data3Ptr->offsetToImportName+importEntry->offsetToName);
+ return;
+ }
+ }
+ }
+ importEntry++;
+ }
+ }
+
+ buffer[0] = 0;
+
+}
+
+char* popDecomp()
+{
+ // printf("<----\n");
+
+ if(!decompileStackPosition)
+ {
+ return("");
+ }
+
+ decompileStackPosition--;
+
+ return decompileStack[decompileStackPosition];
+}
+
+void getByteFromDecompScript(char* buffer)
+{
+ short int var = currentDecompScript[currentDecompScriptPtr->var4];
+
+ currentDecompScriptPtr->var4 = currentDecompScriptPtr->var4+1;
+
+ if(var==-1)
+ {
+ resolveDecompChar(buffer);
+
+ if(buffer[0])
+ return;
+ }
+
+ sprintf(buffer,"%d",var);
+}
+
+char getByteFromDecompScriptReal(void)
+{
+ short int var = currentDecompScript[currentDecompScriptPtr->var4];
+
+ currentDecompScriptPtr->var4 = currentDecompScriptPtr->var4+1;
+
+ return var;
+}
+
+void getShortFromDecompScript(char* buffer)
+{
+ short int var = *(int16*)(currentDecompScript+currentDecompScriptPtr->var4);
+
+ currentDecompScriptPtr->var4 = currentDecompScriptPtr->var4+2;
+
+ flipShort(&var);
+
+ if(var == -1)
+ {
+ resolveDecompShort(buffer);
+
+ if(buffer[0])
+ return;
+ }
+
+ sprintf(buffer,"%d",var);
+}
+
+short int getShortFromDecompScriptReal(void)
+{
+ short int var = *(int16*)(currentDecompScript+currentDecompScriptPtr->var4);
+
+ currentDecompScriptPtr->var4 = currentDecompScriptPtr->var4+2;
+
+ flipShort(&var);
+
+ return var;
+}
+
+void addDecomp(char* string, ...)
+{
+ va_list va;
+
+ /* fprintf(fHandle,"%d: ",currentLineIdx);
+
+ va_start(va,string);
+ vfprintf(fHandle,string,va);
+ va_end(va);
+
+ fprintf(fHandle,"\n"); */
+
+ struct decompileLineStruct* pLineStruct = &decompileLineTable[positionInDecompileLineTable++];
+
+ pLineStruct->lineOffset = currentLineIdx;
+ pLineStruct->indent = 0;
+ pLineStruct->type = currentLineType;
+ pLineStruct->line[0] = 0;
+ pLineStruct->pendingElse = 0;
+
+ va_start(va,string);
+ vsprintf(pLineStruct->line, string,va);
+ va_end(va);
+
+ currentLineIdx = currentDecompScriptPtr->var4;
+ currentLineType = 0;
+
+ /*printf("%d: ",currentOffset);
+
+ va_start(va,string);
+ vprintf(string,va);
+ va_end(va);
+
+ printf("\n");*/
+}
+
+void resolveVarName(char* ovlIdxString, int varType, char* varIdxString, char* outputName)
+{
+ int varIdx = atoi(varIdxString);
+
+ strcpy(outputName,"");
+
+ if(varType == 2)
+ {
+ strcpy(outputName, getStringNameFromIdx(varType, varIdxString));
+ return;
+ }
+ if(varType == 1)
+ {
+ sprintf(outputName, "localVar_%s", varIdxString);
+ return;
+ }
+
+ if(!strcmp(ovlIdxString,"0"))
+ {
+ int i;
+
+ for(i=0;i<currentDecompOvl->numExport;i++)
+ {
+ if(varIdx == currentDecompOvl->exportDataPtr[i].idx)
+ {
+ if( ((currentDecompOvl->exportDataPtr[i].var4&0xF0) == 0) && varType != 0x20) // var
+ {
+ strcpy(outputName, currentDecompOvl->exportNamesPtr + currentDecompOvl->exportDataPtr[i].offsetToName);
+ return;
+ }
+ if( (currentDecompOvl->exportDataPtr[i].var4) == 20 && varType == 0x20) // script
+ {
+ strcpy(outputName, currentDecompOvl->exportNamesPtr + currentDecompOvl->exportDataPtr[i].offsetToName);
+ return;
+ }
+ }
+ }
+ sprintf(outputName, "ovl(%s).[%d][%s]", ovlIdxString, varType, varIdxString);
+ }
+ else
+ {
+ strcpy(outputName, ovlIdxString);
+ }
+}
+
+int decompLoadVar(void)
+{
+ switch(currentScriptOpcodeType)
+ {
+ case 0:
+ {
+ char buffer[256];
+
+ getShortFromDecompScript(buffer);
+
+ pushDecomp(buffer);
+
+ return(0);
+ }
+ // string
+ case 1:
+ {
+ char buffer1[256];
+ char buffer2[256];
+ char buffer3[256];
+ char varName[256];
+
+ getByteFromDecompScript(buffer1);
+ getByteFromDecompScript(buffer2);
+
+ getShortFromDecompScript(buffer3);
+
+ resolveVarName(buffer2,atoi(buffer1) & 7,buffer3, varName);
+
+ pushDecomp("%s",varName);
+ return(0);
+ }
+ case 2:
+ {
+ char buffer1[256];
+ char buffer2[256];
+ char buffer3[256];
+ char varName[256];
+
+ getByteFromDecompScript(buffer1);
+ getByteFromDecompScript(buffer2);
+
+ getShortFromDecompScript(buffer3);
+
+ resolveVarName(buffer2,atoi(buffer1) & 7,buffer3, varName);
+
+ pushDecomp("%s",varName);
+ return(0);
+ }
+ case 5:
+ {
+ char buffer1[256];
+ char buffer2[256];
+ char buffer3[256];
+ char varName[256];
+
+ getByteFromDecompScript(buffer1);
+ getByteFromDecompScript(buffer2);
+
+ getShortFromDecompScript(buffer3);
+
+ resolveVarName(buffer2,atoi(buffer1) & 7,buffer3, varName);
+
+ pushDecomp("%s[%s]",varName,decompSaveOpcodeVar);
+ return(0);
+ }
+ default:
+ {
+ printf("Unsupported type %d in opcodeType0\n",currentScriptOpcodeType);
+ failed = 1;
+ }
+ }
+}
+
+int decompSaveVar(void)
+{
+// int var = popVar();
+
+ switch(currentScriptOpcodeType)
+ {
+ case 0:
+ {
+ addDecomp(popDecomp());
+ return(0);
+ }
+ // modify string
+ case 1:
+ {
+ char buffer1[256];
+ char buffer2[256];
+ char buffer3[256];
+ char varName[256];
+ uint8 type;
+
+ getByteFromDecompScript(buffer1);
+ getByteFromDecompScript(buffer2);
+
+ getShortFromDecompScript(buffer3);
+
+ type = atoi(buffer1) & 7;
+
+ resolveVarName(buffer2,type,buffer3, varName);
+
+ addDecomp("%s = %s",varName,popDecomp());
+ break;
+ }
+ case 2:
+ {
+ char buffer1[256];
+ char buffer2[256];
+ char buffer3[256];
+
+ getByteFromDecompScript(buffer1);
+ getByteFromDecompScript(buffer2);
+
+ getShortFromDecompScript(buffer3);
+
+ addDecomp("ovl(%s).setVar(%s,%s) = %s",buffer2,buffer1,buffer3,popDecomp());
+ break;
+ }
+ case 4:
+ {
+ strcpy(decompSaveOpcodeVar,popDecomp());
+ break;
+ }
+ case 5:
+ {
+ char buffer1[256];
+ char buffer2[256];
+ char buffer3[256];
+ char varName[256];
+ uint8 type;
+
+ getByteFromDecompScript(buffer1);
+ getByteFromDecompScript(buffer2);
+
+ getShortFromDecompScript(buffer3);
+
+ type = atoi(buffer1) & 7;
+
+ resolveVarName(buffer2,type,buffer3, varName);
+
+ addDecomp("%s[%s] = %s",varName,decompSaveOpcodeVar,popDecomp());
+ break;
+ }
+ default:
+ {
+ printf("Unsupported type %d in opcodeType1\n",currentScriptOpcodeType);
+ failed = 1;
+ }
+ }
+
+ return(0);
+}
+
+int decompOpcodeType2(void)
+{
+ switch(currentScriptOpcodeType)
+ {
+ case 1:
+ {
+ char buffer3[256];
+ char varName[256];
+ int byte1 = getByteFromDecompScriptReal();
+ int byte2 = getByteFromDecompScriptReal();
+ getShortFromDecompScript(buffer3);
+
+ resolveVarName("0",byte1 & 7,buffer3, varName);
+
+ pushDecomp(varName);
+
+ break;
+ }
+ case 5:
+ {
+ int byte1 = getByteFromDecompScriptReal();
+ int byte2 = getByteFromDecompScriptReal();
+ short int short1 = getShortFromDecompScriptReal();
+
+ int8* ptr = scriptDataPtrTable[byte1 & 7] + short1;
+
+ if((byte1&7) == 2)
+ {
+ pushDecomp("\"%s\"[%s]",ptr,decompSaveOpcodeVar);
+ }
+ else
+ if((byte1&7) == 5)
+ {
+ pushDecomp("freeString[%d][%s]",short1,decompSaveOpcodeVar);
+ }
+ else
+ {
+ printf("Unsupported type %d in opcodeType2\n",byte1 & 7);
+ failed = 1;
+ }
+ break;
+ }
+ default:
+ {
+ printf("Unsupported type %d in opcodeType2\n",currentScriptOpcodeType);
+ failed = 1;
+ }
+ }
+ return(0);
+}
+
+int decompMath(void)
+{
+ char* param1 = popDecomp();
+ char* param2 = popDecomp();
+
+ switch(currentScriptOpcodeType)
+ {
+ case 0:
+ {
+ sprintf(tempbuffer,"%s+%s",param1,param2);
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 1:
+ {
+ sprintf(tempbuffer,"%s/%s",param1,param2);
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 2:
+ {
+ sprintf(tempbuffer,"%s-%s",param1,param2);
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 3:
+ {
+ sprintf(tempbuffer,"%s*%s",param1,param2);
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 4:
+ {
+ sprintf(tempbuffer,"%s\%%s",param1,param2);
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 5:
+ case 7:
+ {
+ sprintf(tempbuffer,"%s|%s",param1,param2);
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 6:
+ {
+ sprintf(tempbuffer,"%s&%s",param1,param2);
+ pushDecomp(tempbuffer);
+ break;
+ }
+
+ default:
+ {
+ sprintf(tempbuffer,"decompMath(%d,%s,%s)",currentScriptOpcodeType,param1,param2);
+ pushDecomp(tempbuffer);
+ break;
+ }
+ }
+ return(0);
+}
+
+int decompBoolCompare(void)
+{
+ char* param1;
+ char* param2;
+
+ param1 = popDecomp();
+ param2 = popDecomp();
+
+ sprintf(tempbuffer,"compare(%s,%s)",param1,param2);
+ pushDecomp(tempbuffer);
+
+ return 0;
+}
+
+int decompTest(void)
+{
+ unsigned long int oldOffset = currentDecompScriptPtr->var4;
+ short int offset = getShortFromDecompScriptReal();
+
+ switch(currentScriptOpcodeType)
+ {
+ case 0:
+ {
+ currentLineType = 1;
+ addDecomp("test '!(bitMask & 1)' and goto %d",offset+oldOffset);
+ break;
+ }
+ case 1:
+ {
+ currentLineType = 1;
+ addDecomp("test '(bitMask & 1)' and goto %d",offset+oldOffset);
+ break;
+ }
+ case 2:
+ {
+ currentLineType = 1;
+ addDecomp("test '(bitMask & 2)' and goto %d",offset+oldOffset);
+ break;
+ }
+ case 3:
+ {
+ currentLineType = 1;
+ addDecomp("test '(bitMask & 3)' and goto %d",offset+oldOffset);
+ break;
+ }
+ case 4:
+ {
+ currentLineType = 1;
+ addDecomp("test '(bitMask & 4)' and goto %d",offset+oldOffset);
+ break;
+ }
+ case 5:
+ {
+ currentLineType = 1;
+ addDecomp("test '(bitMask & 5)' and goto %d",offset+oldOffset);
+ break;
+ }
+ case 6:
+ {
+ currentLineType = 2;
+ addDecomp("test 'never' and goto %d",offset+oldOffset);
+ break;
+ }
+ case 7:
+ {
+ currentLineType = 3;
+ addDecomp("goto %d",offset+oldOffset);
+ break;
+ }
+
+ }
+
+ return 0;
+}
+
+int decompCompare(void)
+{
+ char* param;
+
+ param = popDecomp();
+
+ addDecomp("sign(%s)",param);
+
+/*
+ if(!pop)
+ si = 1;
+
+ if(pop<0)
+ {
+ si |= 4;
+ }
+
+ if(pop>0)
+ {
+ si |= 2;
+ }
+
+ currentScriptPtr->bitMask = si;
+*/
+
+ return 0;
+}
+
+
+int decompSwapStack(void)
+{
+ char* stack1;
+ char* stack2;
+ char buffer1[4000];
+ char buffer2[4000];
+
+ stack1 = popDecomp();
+ stack2 = popDecomp();
+
+ strcpyuint8(buffer1,stack1);
+ strcpyuint8(buffer2,stack2);
+
+ pushDecomp(buffer1);
+ pushDecomp(buffer2);
+
+ return 0;
+}
+
+int decompFunction(void)
+{
+ currentScriptOpcodeType = getByteFromDecompScriptReal();
+// addDecomp("OP_%X", currentScriptOpcodeType);
+ switch(currentScriptOpcodeType)
+ {
+ case 0x1:
+ {
+ pushDecomp("_setMain5()");
+ break;
+ }
+ case 0x2:
+ {
+ pushDecomp("_prepareFade()");
+ break;
+ }
+ case 0x3:
+ {
+ sprintf(tempbuffer,"_loadBackground(%s,%s)",popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x4:
+ {
+ sprintf(tempbuffer,"_loadFullBundle(%s,%s)",popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x5:
+ {
+ sprintf(tempbuffer,"_addObject(%s,%s,%s)",popDecomp(),popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x6:
+ {
+ unsigned long int numArg = atoi(popDecomp());
+ char* ovlStr;
+ char* idxStr;
+ int i;
+ char functionName[100];
+
+ idxStr = popDecomp();
+ ovlStr = popDecomp();
+
+ resolveVarName(ovlStr, 0x20, idxStr, functionName);
+
+ sprintf(tempbuffer,"_startASync(%s",functionName);
+
+ for(i=0;i<numArg;i++)
+ {
+ strcatuint8(tempbuffer,",");
+ strcatuint8(tempbuffer,popDecomp());
+ }
+
+ strcatuint8(tempbuffer,")");
+
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x7:
+ {
+ char* var1;
+ char* objIdxStr;
+ char* ovlStr;
+ char varName[256];
+ int i;
+
+ var1 = popDecomp();
+ objIdxStr = popDecomp();
+ ovlStr = popDecomp();
+
+ sprintf(tempbuffer,"_createObjectFromOvlData(ovl:%s,dataIdx:%s,%s)",ovlStr,objIdxStr,var1);
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x8:
+ {
+ sprintf(tempbuffer,"_removeObjectFromList(%s,%s,%s)",popDecomp(),popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x9:
+ {
+ pushDecomp("_freeobjectList()");
+ break;
+ }
+ case 0xA:
+ {
+ sprintf(tempbuffer,"_removeScript(ovl(%s),%s)",popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0xB:
+ {
+ sprintf(tempbuffer,"_resetFilesEntries(%s,%s)",popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0xC:
+ {
+ sprintf(tempbuffer,"_loadOverlay(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0xD:
+ {
+ sprintf(tempbuffer,"_palManipulation(%s,%s,%s,%s,%s)",popDecomp(),popDecomp(),popDecomp(),popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0xE:
+ {
+ sprintf(tempbuffer,"_playSample(%s,%s,%s,%s)",popDecomp(),popDecomp(),popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x10:
+ {
+ sprintf(tempbuffer,"_releaseScript2(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x11:
+ {
+ sprintf(tempbuffer,"_getOverlayIdx(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x13:
+ {
+ sprintf(tempbuffer,"_displayMessage(%s,\"%s\",%s,%s,%s,%s)",popDecomp(),resolveMessage(popDecomp()),popDecomp(),popDecomp(),popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x14:
+ {
+ sprintf(tempbuffer,"_removeObject(ovl(%s),%s)",popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x15:
+ {
+ pushDecomp("_pauseScript()");
+ break;
+ }
+ case 0x16:
+ {
+ sprintf(tempbuffer,"_op_16(%s,%s,%s,%s,%s,%s)",popDecomp(),popDecomp(),popDecomp(),popDecomp(),popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x17:
+ {
+ sprintf(tempbuffer,"_loadCtp(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x18:
+ {
+ sprintf(tempbuffer,"_op_18(%s,%s,%s,%s,%s,%s,%s)",popDecomp(),popDecomp(),popDecomp(),popDecomp(),popDecomp(),popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x19:
+ {
+ sprintf(tempbuffer,"_op_19(%s,%s,%s)",popDecomp(),popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x1A:
+ {
+ sprintf(tempbuffer,"_setupScaleFormula(%s,%s,%s,%s)",popDecomp(),popDecomp(),popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x1E:
+ {
+ sprintf(tempbuffer,"_op_1E(%s,%s,%s,%s,%s,%s)",popDecomp(),popDecomp(),popDecomp(),popDecomp(),popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x21:
+ {
+ sprintf(tempbuffer,"_isActorLoaded(%s,%s,%s)",popDecomp(),popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x22:
+ {
+ sprintf(tempbuffer,"_computeScale(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x23:
+ {
+ sprintf(tempbuffer,"_convertToScale(%s,%s)",popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x24:
+ {
+ sprintf(tempbuffer,"_op_24(%s,%s,%s,%s)",popDecomp(),popDecomp(),popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x27:
+ {
+ sprintf(tempbuffer,"_getWalkBoxCollision(%s,%s)",popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x28:
+ {
+ sprintf(tempbuffer,"_changeSaveAllowedState(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x29:
+ {
+ pushDecomp("_freeAllPerso()");
+ break;
+ }
+ case 0x2B:
+ {
+ sprintf(tempbuffer,"_getProcIdx(%s,%s)",popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x2C:
+ {
+ sprintf(tempbuffer,"_setObjectPosition(%s,%s,%s)",popDecomp(),popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x2E:
+ {
+ sprintf(tempbuffer,"_releaseScript(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x2F:
+ {
+ sprintf(tempbuffer,"_addBackgroundIncrust(%s,%s,%s)",popDecomp(),popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x30:
+ {
+ sprintf(tempbuffer,"_removeBackgroundIncrust(%s,%s)",popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x31:
+ {
+ sprintf(tempbuffer,"_op_31(%s,%s)",popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x32:
+ {
+ pushDecomp("_freeBackgroundInscrustList()");
+ break;
+ }
+ case 0x35:
+ {
+ sprintf(tempbuffer,"_op35(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x37:
+ {
+ sprintf(tempbuffer,"_op37(%s,%s)",popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x38:
+ {
+ sprintf(tempbuffer,"_removeBackground(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x39:
+ {
+ sprintf(tempbuffer,"_SetActiveBackgroundPlane(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x3A:
+ {
+ sprintf(tempbuffer,"_setVar49(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x3B:
+ {
+ pushDecomp("_op3B()");
+ break;
+ }
+ case 0x3C:
+ {
+ sprintf(tempbuffer,"_rand(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x3D:
+ {
+ sprintf(tempbuffer,"_loadMusic(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x3E:
+ {
+ pushDecomp("_op_3E()");
+ break;
+ }
+ case 0x3F:
+ {
+ pushDecomp("_op_3F()");
+ break;
+ }
+ case 0x40:
+ {
+ pushDecomp("_op_40()");
+ break;
+ }
+ case 0x41:
+ {
+ sprintf(tempbuffer,"_isFileLoaded2(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x45:
+ {
+ pushDecomp("_stopSound()");
+ break;
+ }
+ case 0x49:
+ {
+ sprintf(tempbuffer,"_op49(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x54:
+ {
+ sprintf(tempbuffer,"_setFontVar(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x56:
+ {
+ sprintf(tempbuffer,"_changeCutSceneState(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x57:
+ {
+ pushDecomp("_getMouseX()");
+ break;
+ }
+ case 0x58:
+ {
+ pushDecomp("_getMouseY()");
+ break;
+ }
+ case 0x59:
+ {
+ pushDecomp("_getMouse3()");
+ break;
+ }
+ case 0x5A:
+ {
+ sprintf(tempbuffer,"_isFileLoaded(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x5B:
+ {
+ pushDecomp("_regenerateBackgroundIncrust()");
+ break;
+ }
+ case 0x5C:
+ {
+ sprintf(tempbuffer,"_op_5C(%s,%s)",popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x5E:
+ {
+ sprintf(tempbuffer,"_op_5E(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x60:
+ {
+ sprintf(tempbuffer,"_op_60(%s,%s,%s,%s,%s)",popDecomp(),popDecomp(),popDecomp(),popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x61:
+ {
+ sprintf(tempbuffer,"_op61(%s,%s)",popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x62:
+ {
+ pushDecomp("_pauseCallingScript()");
+ break;
+ }
+ case 0x63:
+ {
+ pushDecomp("_resumeScript()");
+ break;
+ }
+ case 0x64:
+ {
+ unsigned long int numArg = atoi(popDecomp());
+ char* ovlStr;
+ char* idxStr;
+ int i;
+ char functionName[256];
+
+ idxStr = popDecomp();
+ ovlStr = popDecomp();
+
+ resolveVarName(ovlStr, 0x20, idxStr, functionName);
+
+ sprintf(tempbuffer,"%s(",functionName);
+
+ for(i=0;i<numArg;i++)
+ {
+ if(i)
+ strcatuint8(tempbuffer,",");
+ strcatuint8(tempbuffer,popDecomp());
+ }
+
+ strcatuint8(tempbuffer,")");
+
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x65:
+ {
+ sprintf(tempbuffer,"_addWaitObject(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)",popDecomp(),popDecomp(),popDecomp(),popDecomp(),popDecomp(),popDecomp(),popDecomp(),popDecomp(),popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x66:
+ {
+ sprintf(tempbuffer,"_op_66(%s,%s)",popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x67:
+ {
+ sprintf(tempbuffer,"_loadAudioResource(%s,%s)",popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x68:
+ {
+ pushDecomp("_freeMediumVar()");
+ break;
+ }
+ case 0x6A:
+ {
+ sprintf(tempbuffer,"_op_6A(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x6B:
+ {
+ sprintf(tempbuffer,"_loadData(%s,%s,%s,%s)",popDecomp(),popDecomp(),popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x6C:
+ {
+ sprintf(tempbuffer,"_op_6C(%s,%s)",popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x6D:
+ {
+ sprintf(tempbuffer,"_strcpy(%s,%s)",popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x6E:
+ {
+ sprintf(tempbuffer,"_op_6E(%s,%s)",popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x6F:
+ {
+ unsigned long int numArg = atoi(popDecomp());
+ char* ovlStr;
+ char* idxStr;
+ int i;
+
+ idxStr = popDecomp();
+ ovlStr = popDecomp();
+
+ sprintf(tempbuffer,"_op_6F(%s,%s",idxStr,ovlStr);
+
+ for(i=0;i<numArg;i++)
+ {
+ strcatuint8(tempbuffer,",");
+ strcatuint8(tempbuffer,popDecomp());
+ }
+
+ strcatuint8(tempbuffer,")");
+
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x70:
+ {
+ sprintf(tempbuffer,"_comment(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x71:
+ {
+ sprintf(tempbuffer,"_op71(%s,%s,%s,%s,%s)",popDecomp(),popDecomp(),popDecomp(),popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x72:
+ {
+ sprintf(tempbuffer,"_op72(%s,%s)",popDecomp(),popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x73:
+ {
+ sprintf(tempbuffer,"_op73(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x74:
+ {
+ sprintf(tempbuffer,"_getInitVar1()");
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x76:
+ {
+ sprintf(tempbuffer,"_op_76(%s,%s)",popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x77:
+ {
+ sprintf(tempbuffer,"_op_77(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x78:
+ {
+ sprintf(tempbuffer,"_op_78(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x79:
+ {
+ sprintf(tempbuffer,"_EnterPlayerMenu(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x7B:
+ {
+ sprintf(tempbuffer,"_op_7B(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x7C:
+ {
+ sprintf(tempbuffer,"_op_7C(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x7D:
+ {
+ pushDecomp("_freeAllMenu()");
+ break;
+ }
+ default:
+ {
+ addDecomp("OP_%X", currentScriptOpcodeType);
+ printf("OPCODE: %X\n",currentScriptOpcodeType);
+ failed = 1;
+ break;
+ }
+ }
+
+// pushDecomp("functionDummyPush");
+
+ return(0);
+}
+
+uint8 stop = 0;
+
+int decompStop(void)
+{
+ stop = 1;
+ addDecomp("stop\n");
+ return 0;
+}
+
+int decompBreak(void)
+{
+ addDecomp("break");
+ return 0;
+}
+
+void generateIndentation(void)
+{
+ int i;
+
+ for(i=0;i<positionInDecompileLineTable;i++)
+ {
+ if(decompileLineTable[i].type != 0)
+ {
+ char* gotoStatement;
+ int destLine;
+ int destLineIdx;
+
+ gotoStatement = strstr(decompileLineTable[i].line,"goto");
+ assert(gotoStatement);
+ gotoStatement = strchr(gotoStatement,' ')+1;
+
+ destLine = atoi(gotoStatement);
+
+ {
+ int j;
+
+ destLineIdx = -1;
+
+ for(j=0;j<positionInDecompileLineTable;j++)
+ {
+ if(decompileLineTable[j].lineOffset == destLine)
+ {
+ destLineIdx = j;
+ break;
+ }
+ }
+
+ assert(destLineIdx != -1);
+
+ if(destLineIdx>i)
+ {
+ int j;
+
+ for(j=i+1;j<destLineIdx;j++)
+ {
+ decompileLineTable[j].indent++;
+ }
+
+ if(strstr(decompileLineTable[destLineIdx-1].line,"goto") == decompileLineTable[destLineIdx-1].line)
+ {
+ //decompileLineTable[destLineIdx-1].pendingElse = 1;
+ }
+ }
+ }
+ }
+ }
+}
+
+void dumpScript(uint8* ovlName, ovlDataStruct* ovlData,int idx)
+{
+ uint8 opcodeType;
+ char buffer[256];
+ int i;
+
+ char temp[256];
+ char scriptName[256];
+
+ sprintf(temp,"%d",idx);
+
+ failed = 0;
+
+ currentScript = &ovlData->data3Table[idx];
+
+ currentDecompScript = currentScript->dataPtr;
+ currentDecompScriptPtr->var4 = 0;
+
+ currentDecompOvl = ovlData;
+ currentDecompScriptIdx = idx;
+
+ currentLineIdx = 0;
+ positionInDecompileLineTable = 0;
+ currentLineType = 0;
+
+ resolveVarName("0",0x20,temp, scriptName);
+
+ printf("decompiling script %d - %s\n",idx,scriptName);
+
+ // return;
+
+// scriptDataPtrTable[1] = *(char**)(ptr+0x6);
+ scriptDataPtrTable[2] = getDataFromData3(currentScript, 1); // strings
+ scriptDataPtrTable[5] = ovlData->data4Ptr; // free strings
+ scriptDataPtrTable[6] = ovlData->ptr8;
+
+ stop = 0;
+
+ sprintf(buffer,"%s-%02d-%s.txt",ovlName,idx,scriptName);
+ fHandle = fopen(buffer,"w+");
+
+ decompileStackPosition = 0;
+
+ for(i=0;i<64;i++)
+ {
+ decompOpcodeTypeTable[i] = NULL;
+ }
+
+ decompOpcodeTypeTable[1] = decompLoadVar;
+ decompOpcodeTypeTable[2] = decompSaveVar;
+ decompOpcodeTypeTable[3] = decompOpcodeType2;
+ decompOpcodeTypeTable[4] = decompMath;
+ decompOpcodeTypeTable[5] = decompBoolCompare;
+ decompOpcodeTypeTable[6] = decompTest;
+ decompOpcodeTypeTable[7] = decompCompare;
+ decompOpcodeTypeTable[8] = decompSwapStack;
+ decompOpcodeTypeTable[9] = decompFunction;
+ decompOpcodeTypeTable[10] = decompStop;
+ decompOpcodeTypeTable[12] = decompBreak;
+
+ do
+ {
+ currentOffset = currentDecompScriptPtr->var4;
+
+ opcodeType = getByteFromDecompScriptReal();
+
+ currentScriptOpcodeType = opcodeType & 7;
+
+ if(!decompOpcodeTypeTable[(opcodeType&0xFB)>>3])
+ {
+ printf("Unsupported opcode type %d in decomp\n",(opcodeType&0xFB)>>3);
+ return;
+ }
+
+
+ //printf("Optype: %d\n",(opcodeType&0xFB)>>3);
+
+ decompOpcodeTypeTable[(opcodeType&0xFB)>>3]();
+
+ if(failed)
+ {
+ printf("Aborting decompilation..\n");
+ fclose(fHandle);
+ return;
+ }
+
+ }while(!stop);
+
+ dumpIdx++;
+
+ generateIndentation();
+
+ for(i=0;i<positionInDecompileLineTable;i++)
+ {
+ int j;
+
+ if(decompileLineTable[i].pendingElse)
+ {
+ fprintf(fHandle,"%05d:\t", decompileLineTable[i].lineOffset);
+ fprintf(fHandle,"else", decompileLineTable[i].line);
+ fprintf(fHandle,"\n");
+ }
+
+ fprintf(fHandle,"%05d:\t", decompileLineTable[i].lineOffset);
+ for(j=0;j<decompileLineTable[i].indent;j++)
+ {
+ fprintf(fHandle,"\t");
+ }
+ fprintf(fHandle,"%s", decompileLineTable[i].line);
+ fprintf(fHandle,"\n");
+ }
+
+ fclose(fHandle);
+}
+
+#endif
+
+} // End of namespace Cruise
+
diff --git a/engines/cruise/delphine-unpack.cpp b/engines/cruise/delphine-unpack.cpp
new file mode 100644
index 0000000000..796753656d
--- /dev/null
+++ b/engines/cruise/delphine-unpack.cpp
@@ -0,0 +1,176 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cruise/cruise_main.h"
+
+namespace Cruise {
+
+uint32 crc; // variable at 5C5A
+uint32 bitbucket; // dx:bx
+
+uint16 swap16(uint16 r)
+{
+ return (r >> 8) | (r << 8);
+}
+
+#define loadd(p, d) {\
+ d = *(--p);\
+ d |= (*(--p)) << 8;\
+ d |= (*(--p)) << 16;\
+ d |= (*(--p)) << 24;\
+}
+
+#define store(p, b) *(--p) = b
+#define getbit(p, b) {\
+ b = (uint8)(bitbucket & 1);\
+ bitbucket >>= 1;\
+ if (!bitbucket) {\
+ loadd(p, bitbucket);\
+ crc ^= bitbucket;\
+ b = (uint8)(bitbucket & 1);\
+ bitbucket >>= 1;\
+ bitbucket |= 0x80000000;\
+ }\
+}
+
+#define loadbits(p, b) {\
+ b = 0;\
+ do {\
+ getbit(p, bit);\
+ b <<= 1;\
+ b |= bit;\
+ nbits--;\
+ } while (nbits);\
+}
+
+int32 decomp(uint8 * in, uint8 * out, int32 size) {
+ uint8 bit; // Carry flag
+ uint8 nbits; // cl
+ uint8 byte; // ch
+ uint16 counter; // bp
+ uint16 var; // variable at 5C58
+ uint16 ptr;
+ uint16 flags;
+ enum {
+ DO_COPY,
+ DO_UNPACK
+ } action;
+
+ loadd(in, crc);
+ loadd(in, bitbucket);
+ crc ^= bitbucket;
+
+ do { // 5A4C
+ getbit(in, bit);
+ if (!bit) { // 5A94
+ getbit(in, bit);
+ if (!bit) { // 5AC8
+ nbits = 3;
+ byte = 0;
+ action = DO_COPY;
+ } else { // 5ACA
+ var = 1;
+ nbits = 8;
+ action = DO_UNPACK;
+ }
+ } else { // 5B4F
+ nbits = 2;
+ loadbits(in, flags);
+ if (flags < 2) {
+ nbits = flags + 9; // 5BC3
+ var = flags + 2;
+ action = DO_UNPACK;
+ } else if (flags == 3) {
+ nbits = 8; // 5B4A
+ byte = 8;
+ action = DO_COPY;
+ } else {
+ nbits = 8;
+ loadbits(in, var);
+ nbits = 12;
+ action = DO_UNPACK;
+ }
+ }
+
+ switch (action) {
+ case DO_COPY:
+ // 5AD1
+ loadbits(in, counter); // 5AFD
+ counter += byte;
+ counter++;
+ size -= counter;
+ do {
+ nbits = 8;
+ loadbits(in, byte); // 5B3F
+ store(out, byte);
+ counter--;
+ } while (counter); // 5B45
+ break;
+ case DO_UNPACK:
+ // 5BD3
+ loadbits(in, ptr); // 5BFF
+ counter = var + 1;
+ size -= counter;
+ do {
+ byte = *(out + ptr - 1);
+ store(out, byte);
+ counter--;
+ } while(counter);
+ }
+ } while (size > 0);
+ // 5C32
+ // ???
+
+ if (crc) {
+ return -1;
+ } else {
+ return 0;
+ }
+}
+/*
+int main(void) {
+ FILE * in, * out;
+ uint8 * bufin, * bufout;
+ uint32 isize, osize;
+
+ in = fopen("FIN.FR", "rb");
+ out = fopen("FIN.FR.out", "wb");
+
+ fseek(in, -4, SEEK_END);
+ bufin = (uint8 *) mallocAndZero((isize = ftell(in)));
+ fread(&osize, 4, 1, in);
+ osize = (osize >> 24) | ((osize >> 8) & 0xff00) | ((osize << 8) & 0xff0000) | (osize << 24);
+ bufout = (uint8 *) mallocAndZero(osize);
+ fseek(in, 0, SEEK_SET);
+ fread(bufin, 1, isize, in);
+
+ decomp(bufin + isize, bufout + osize, osize);
+
+ fwrite(bufout, 1, osize, out);
+ fclose(out);
+ fclose(in);
+}*/
+
+
+} // End of namespace Cruise
diff --git a/engines/cruise/detection.cpp b/engines/cruise/detection.cpp
new file mode 100644
index 0000000000..15f8d44877
--- /dev/null
+++ b/engines/cruise/detection.cpp
@@ -0,0 +1,112 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/stdafx.h"
+
+#include "base/plugins.h"
+
+#include "common/advancedDetector.h"
+
+#include "cruise/cruise.h"
+
+namespace Cruise {
+struct CRUISEGameDescription {
+ Common::ADGameDescription desc;
+
+ int gameType;
+ uint32 features;
+};
+
+int CruiseEngine::getGameType() const { return _gameDescription->gameType; }
+uint32 CruiseEngine::getFeatures() const { return _gameDescription->features; }
+Common::Language CruiseEngine::getLanguage() const { return _gameDescription->desc.language; }
+Common::Platform CruiseEngine::getPlatform() const { return _gameDescription->desc.platform; }
+
+}
+
+static const PlainGameDescriptor cruiseGames[] = {
+ {"cruise", "Cinematique evo.2 engine game"},
+ {"cruise", "Cruise for a corps"},
+ {0, 0}
+};
+
+static const Common::ADObsoleteGameID obsoleteGameIDsTable[] = {
+ {"cruise", "cruise", Common::kPlatformUnknown},
+ {0, 0, Common::kPlatformUnknown}
+};
+
+namespace Cruise {
+
+static const CRUISEGameDescription gameDescriptions[] = {
+ {
+ {
+ "cruise",
+ "",
+ AD_ENTRY1("D1", "41a7a4d426dbd048eb369cfee4bb2717"),
+ Common::FR_FRA,
+ Common::kPlatformPC,
+ Common::ADGF_NO_FLAGS
+ },
+ GType_CRUISE,
+ 0,
+ },
+
+ { AD_TABLE_END_MARKER, 0, 0 }
+};
+
+}
+
+static const Common::ADParams detectionParams = {
+ // Pointer to ADGameDescription or its superset structure
+ (const byte *)Cruise::gameDescriptions,
+ // Size of that superset structure
+ sizeof(Cruise::CRUISEGameDescription),
+ // Number of bytes to compute MD5 sum for
+ 5000,
+ // List of all engine targets
+ cruiseGames,
+ // Structure for autoupgrading obsolete targets
+ obsoleteGameIDsTable,
+ // Name of single gameid (optional)
+ "cruise",
+ // List of files for file-based fallback detection (optional)
+ 0,
+ // Fallback callback
+ 0,
+ // Flags
+ Common::kADFlagAugmentPreferredTarget
+};
+
+ADVANCED_DETECTOR_DEFINE_PLUGIN(CRUISE, Cruise::CruiseEngine, detectionParams);
+
+REGISTER_PLUGIN(CRUISE, "Cinematique evo 2 engine", "Cruise for a Corpse (C) Delphine Software");
+
+namespace Cruise {
+
+bool CruiseEngine::initGame() {
+ _gameDescription = (const CRUISEGameDescription *)Common::AdvancedDetector::detectBestMatchingGame(detectionParams);
+ return (_gameDescription != 0);
+}
+
+} // End of namespace Cruise
diff --git a/engines/cruise/font.cpp b/engines/cruise/font.cpp
new file mode 100644
index 0000000000..65883d6c6f
--- /dev/null
+++ b/engines/cruise/font.cpp
@@ -0,0 +1,745 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/file.h"
+
+#include "cruise/cruise_main.h"
+
+namespace Cruise {
+
+// (old: fontProc1(int16 param, uint8* ptr1, uint8* ptr2))
+int32 getLineHeight(int16 charCount, uint8* fontPtr, uint8* fontPrt_Desc)
+{
+ uint8* dest;
+ int32 highestChar = 0;
+ int32 i;
+
+ if(!charCount)
+ {
+ return(0);
+ }
+ dest = fontPrt_Desc + 6; // fontPtr + 20 // char height
+
+ for(i = 0; i < charCount; i++)
+ {
+ if((*(int16*) dest) > highestChar)
+ {
+ highestChar = *(int16*) dest;
+ }
+ dest += 12;
+ }
+ return highestChar;
+}
+
+// this function determins how many lines the text will have (old: fontProc2(int32 param1, int32 param2, uint8* ptr, uint8* string))
+int32 getTextLineCount(int32 rightBorder_X, int32 wordSpacingWidth, uint8* ptr, uint8* textString)
+{
+ uint8* localString = textString;
+ uint8* currentStringPtr;
+ uint8 character;
+
+ int32 var_6 = 0;
+ int32 lineLength = 0;
+
+ uint8* tempPtr;
+
+ if(!*localString)
+ {
+ return(0);
+ }
+ currentStringPtr = localString;
+ character = *localString;
+
+ do
+ {
+ int32 charData = fontCharacterTable[character];
+
+ if(character == '|')
+ {
+ lineLength = rightBorder_X;
+ localString = tempPtr;
+ }
+ else
+ {
+ if(charData >= 0)
+ { // + 0xA jump to last 2 bytes of the 12 bytes slice = letter width
+ lineLength += wordSpacingWidth + *(int16*) (ptr + 0xA + charData * 12);
+ }
+ else
+ {
+ if(character == ' ')
+ {
+ lineLength += wordSpacingWidth + 5;
+ localString = currentStringPtr;
+ }
+ }
+ }
+
+ tempPtr = currentStringPtr;
+
+ if(rightBorder_X <= lineLength)
+ {
+ var_6 += rightBorder_X;
+ currentStringPtr = localString;
+ tempPtr = localString;
+ lineLength = 0;
+ }
+
+ character = *(tempPtr++);
+ currentStringPtr = tempPtr;
+
+ } while(character);
+
+ if(lineLength == 0)
+ {
+ return (var_6 / rightBorder_X);
+ }
+ else
+ {
+ return ((var_6 + rightBorder_X) / rightBorder_X);
+ }
+}
+
+void loadFNT(void* fileNameChar)
+{
+ uint8 header[6];
+ int32 fontSize;
+ int32 data2;
+ uint8 data3[6];
+ uint8* fileName = (uint8*) fileNameChar;
+ _systemFNT = NULL;
+
+ Common::File fontFileHandle;
+
+ if(!fontFileHandle.exists((char*)fileName))
+ {
+ return;
+ }
+
+ fontFileHandle.open((char*)fileName);
+
+ fontFileHandle.read(header, 4);
+
+ if(strcmpuint8(header, "FNT") == 0)
+ {
+ fontFileHandle.read(&fontSize, 4);
+ flipLong(&fontSize);
+
+ fontFileHandle.read(&data2, 4);
+ flipLong(&data2);
+
+ fontFileHandle.read(data3, 6); // may need an endian flip ?
+ flipGen(&data3, 6);
+
+ _systemFNT = (uint8*) mallocAndZero(fontSize);
+
+ if(_systemFNT != NULL)
+ {
+ int32 i;
+ uint8* currentPtr;
+
+ fontFileHandle.seek(0);
+ fontFileHandle.read(header, 4); // not really require, we could fseek to 4
+
+ fontFileHandle.read(_systemFNT, fontSize);
+
+ flipLong((int32*) _systemFNT);
+ flipLong((int32*) (_systemFNT + 4));
+ flipGen(_systemFNT + 8, 6);
+
+ currentPtr = _systemFNT + 14;
+
+ for(i = 0; i < *(int16*) (_systemFNT + 8); i++)
+ {
+ flipLong((int32*) currentPtr);
+ currentPtr += 4;
+
+ flipGen(currentPtr, 8);
+ currentPtr += 8;
+ }
+ }
+ }
+
+ fontFileHandle.close();
+}
+
+void loadSystemFont(void)
+{
+ int32 i;
+
+ video2 = 15;
+ video4 = 9;
+ video3 = 13;
+ colorOfSelectedSaveDrive = 10;
+
+ for(i = 0; i < 64; i++)
+ {
+ mediumVar[i].ptr = 0;
+ mediumVar[i].field_1C = 0;
+ }
+
+ initVar1 = 0;
+ main5 = 0;
+ var22 = 0;
+ initVar2 = 0;
+ initVar3 = 0;
+ currentActiveBackgroundPlane = 0;
+
+ //changeCursor();
+
+ initVar4[0] = 0;
+
+ loadFNT("system.fnt");
+}
+
+void flipShort(int16* var)
+{
+ uint8* varPtr = (uint8*) var;
+ uint8 temp = varPtr[0];
+ varPtr[0] = varPtr[1];
+ varPtr[1] = temp;
+}
+
+void flipShort(uint16* var)
+{
+ uint8* varPtr = (uint8*) var;
+ uint8 temp = varPtr[0];
+ varPtr[0] = varPtr[1];
+ varPtr[1] = temp;
+}
+
+void flipLong(int32* var)
+{
+ char swap1;
+ char swap2;
+ char* varPtr = (char*) var;
+
+ swap1 = varPtr[0];
+ varPtr[0] = varPtr[3];
+ varPtr[3] = swap1;
+
+ swap2 = varPtr[1];
+ varPtr[1] = varPtr[2];
+ varPtr[2] = swap2;
+}
+
+void flipLong(uint32* var)
+{
+ char swap1;
+ char swap2;
+ char* varPtr = (char*) var;
+
+ swap1 = varPtr[0];
+ varPtr[0] = varPtr[3];
+ varPtr[3] = swap1;
+
+ swap2 = varPtr[1];
+ varPtr[1] = varPtr[2];
+ varPtr[2] = swap2;
+}
+
+void flipGen(void* var, int32 length)
+{
+ int i;
+ short int* varPtr = (int16*) var;
+
+ for(i = 0; i < (length / 2); i++)
+ {
+ flipShort(&varPtr[i]);
+ }
+}
+
+
+void renderWord(uint8* fontPtr_Data, uint8* outBufferPtr, int32 drawPosPixel_X, int32 heightOff, int32 height, int32 param4, int32 stringRenderBufferSize, int32 width, int32 charWidth)
+{
+ int i;
+ int j;
+ uint8* fontPtr_Data2 = fontPtr_Data + height * 2;
+
+ outBufferPtr += heightOff * width * 2; // param2 = height , param6 = width
+ outBufferPtr += drawPosPixel_X; // param1 = drawPosPixel_X
+
+ for(i = 0; i < height; i++) // y++
+ {
+ uint16 currentColor1 = (*(fontPtr_Data) << 8) | *(fontPtr_Data + 1);
+ uint16 currentColor2 = (*(fontPtr_Data2) << 8) | *(fontPtr_Data2 + 1);
+
+ fontPtr_Data += 2;
+ fontPtr_Data2 += 2;
+
+ for (j = 0; j < charWidth; j++)
+ {
+ *outBufferPtr = ((currentColor1 >> 15) & 1) | ((currentColor2 >> 14) & 2);
+ outBufferPtr++;
+
+ currentColor1 <<= 1;
+ currentColor2 <<= 1;
+ }
+ outBufferPtr += (width * 2) - charWidth;
+ }
+}
+
+// returns character count and pixel size (via pointer) per line of the string (old: prepareWordRender(int32 param, int32 var1, int16* out2, uint8* ptr3, uint8* string))
+int32 prepareWordRender(int32 inRightBorder_X, int32 wordSpacingWidth, int16* strPixelLength, uint8* ptr3, uint8* textString)
+{
+ uint8* localString = textString;
+
+ int32 counter = 0;
+ int32 finish = 0;
+ int32 temp_pc = 0; // var_A // temporary pixel count save
+ int32 temp_cc = 0; // var_C // temporary char count save
+ int32 pixelCount = 0; // si
+
+ do
+ {
+ uint8 character = *(localString++);
+ int16 charData = fontCharacterTable[character];
+
+ if(character == ' ')
+ {
+ temp_cc = counter;
+ temp_pc = pixelCount;
+
+ if(pixelCount + wordSpacingWidth + 5 >= inRightBorder_X)
+ {
+ finish = 1;
+ }
+ else
+ {
+ pixelCount += wordSpacingWidth + 5 ;
+ }
+ }
+ else
+ {
+ if(character == '|' || !character)
+ {
+ finish = 1;
+ }
+ else
+ {
+ if(charData)
+ {
+ if(pixelCount + wordSpacingWidth + *(int16*) ((ptr3 + charData * 12) + 0xA) >= inRightBorder_X)
+ {
+ finish = 1;
+ if(temp_pc)
+ {
+ pixelCount = temp_pc;
+ counter = temp_cc;
+ }
+ }
+ else
+ {
+ pixelCount += wordSpacingWidth + *(int16*) ((ptr3 + charData * 12) + 0xA);
+ }
+ }
+ }
+ }
+ counter++;
+ } while(!finish);
+
+ *strPixelLength = (int16) pixelCount;
+ return counter;
+}
+
+
+void drawString(int32 x, int32 y, uint8* string, uint8* buffer, uint8 color, int32 inRightBorder_X)
+{
+ uint8* fontPtr;
+ uint8* fontPtr_Data; // ptr2
+ uint8* fontPtr_Desc; // ptr3
+ int32 wordSpacingWidth; // var1
+ int32 wordSpacingHeight; // var2
+ int32 rightBorder_X; // param2
+ int32 lineHeight; // fontProc1result
+ int32 numLines;
+ int32 stringHeight;
+ int32 stringFinished;
+ int32 stringWidth; // var_1C
+ int32 stringRenderBufferSize;
+ int32 useDynamicBuffer;
+ uint8* currentStrRenderBuffer;
+ // int32 var_8; // don't need that on
+ int32 heightOffset; // var_12
+ int32 renderBufferSize; // var_1E
+ int needFlip;
+
+ if(!buffer || !string)
+ {
+ return;
+ }
+
+ if(fontFileIndex != -1)
+ {
+ fontPtr = filesDatabase[fontFileIndex].subData.ptr;
+
+ if(!fontPtr)
+ {
+ fontPtr = _systemFNT;
+ }
+ }
+ else
+ {
+ fontPtr = _systemFNT;
+ }
+
+ if(!fontPtr)
+ {
+ return;
+ }
+
+ fontPtr_Data = fontPtr + *(int16*) (fontPtr + 4);
+ fontPtr_Desc = fontPtr + 14;
+
+ lineHeight = getLineHeight(*(int16*) (fontPtr + 8), fontPtr, fontPtr_Desc); // ok
+
+ wordSpacingWidth = *(int16*) (fontPtr + 10);
+ wordSpacingHeight = *(int16*) (fontPtr + 12);
+
+ if(inRightBorder_X > 310)
+ {
+ rightBorder_X = 310;
+ }
+ else
+ {
+ rightBorder_X = inRightBorder_X;
+ }
+ if(x + rightBorder_X > 319)
+ {
+ x = 319 - rightBorder_X;
+ }
+ if(y < 0)
+ {
+ y = 0;
+ }
+ if(x < 0)
+ {
+ x = 0;
+ }
+ numLines = getTextLineCount(rightBorder_X, wordSpacingWidth, fontPtr_Desc, string); // ok
+
+ if(!numLines)
+ {
+ return;
+ }
+ stringHeight = ((wordSpacingHeight + lineHeight + 2) * numLines) + 1;
+
+ if (y + stringHeight > 199)
+ {
+ y = 200 - stringHeight;
+ }
+ stringFinished = 0;
+ stringWidth = (rightBorder_X / 16) + 2;
+ stringRenderBufferSize = stringWidth * stringHeight * 4;
+ inRightBorder_X = rightBorder_X;
+
+ if(stringRenderBufferSize > 0x2000)
+ {
+ currentStrRenderBuffer = (uint8*) mallocAndZero(stringRenderBufferSize);
+
+ if(!currentStrRenderBuffer)
+ {
+ return;
+ }
+ useDynamicBuffer = 1;
+ }
+ else
+ {
+ currentStrRenderBuffer = (uint8*) ptr_something;
+ useDynamicBuffer = 0;
+ }
+
+ resetRaster(currentStrRenderBuffer, stringRenderBufferSize);
+
+ // var_8 = 0;
+ heightOffset = 0;
+ renderBufferSize = stringRenderBufferSize;
+
+ do
+ {
+ int spacesCount = 0; // si
+ char character = *(string);
+ short int strPixelLength; // var_16;
+ uint8* ptrStringEnd; // var_4 //ok
+ int drawPosPixel_X; // di
+
+ while(character == ' ')
+ {
+ spacesCount++;
+ character = *(string + spacesCount);
+ }
+
+ string += spacesCount;
+ ptrStringEnd = string + prepareWordRender(inRightBorder_X, wordSpacingWidth, &strPixelLength, fontPtr_Desc, string); //ok
+
+ if(inRightBorder_X > strPixelLength)
+ {
+ drawPosPixel_X = (inRightBorder_X - strPixelLength) / 2;
+ }
+ else
+ {
+ drawPosPixel_X = 0;
+ }
+ // drawPosPixel_X = var_8;
+
+ do
+ {
+ uint8 character = *(string++);
+
+ short int data = fontCharacterTable[character];
+
+ if(character)
+ {
+ if(character == ' ' || character == 0x7D)
+ {
+ drawPosPixel_X += var1 + 5;
+ }
+ else
+ {
+ if(data)
+ {
+ short int* si = (int16*) (fontPtr_Desc + data * 12);
+ //int var_2 = si[5];
+
+ renderWord(fontPtr_Data + si[0], currentStrRenderBuffer, drawPosPixel_X, si[4] - si[3] + lineHeight + heightOffset, si[3], si[2], renderBufferSize / 2, stringWidth * 2, si[5]);
+
+ drawPosPixel_X += wordSpacingWidth + si[5];
+ }
+ }
+ }
+ else
+ {
+ stringFinished = 1;
+ }
+
+ if(ptrStringEnd <= string)
+ {
+ break;
+ }
+
+ } while(!stringFinished);
+
+ // var_8 = 0;
+ heightOffset = wordSpacingHeight + lineHeight;
+
+ } while(!stringFinished);
+
+ needFlip = 0;
+
+ if(buffer == gfxModuleData.pPage00)
+ {
+ if(gfxModuleData.field_1 != 0)
+ {
+ needFlip = 1;
+ gfxModuleData_field_90();
+ }
+
+ gfxModuleData_gfxWaitVSync();
+ }
+
+ gfxModuleData_field_64((char*)currentStrRenderBuffer, stringWidth, stringHeight, (char*)buffer, x, y, 0);
+ gfxModuleData_field_64((char*)currentStrRenderBuffer, stringWidth, stringHeight, (char*)buffer, x, y, color);
+
+ if(needFlip)
+ {
+ gfxModuleData_flip();
+ }
+
+ if(useDynamicBuffer)
+ {
+ free(currentStrRenderBuffer);
+ }
+}
+
+
+// calculates all necessary datas and renders text
+gfxEntryStruct* renderText(int inRightBorder_X, uint8* string)
+{
+ uint8* fontPtr;
+ uint8* fontPtr_Data; // pt2
+ uint8* fontPtr_Desc; // ptr3
+ int32 wordSpacingWidth; // var1 //0 or -1
+ int32 wordSpacingHeight; // var2 //0 or -1
+ int32 rightBorder_X;
+ int32 lineHeight; // fontProc1result
+ int32 numLines;
+ int32 stringHeight;
+ int32 stringFinished;
+ int32 stringWidth; // var_1C
+ int32 stringRenderBufferSize;
+ // int32 useDynamicBuffer;
+ uint8* currentStrRenderBuffer;
+ // int32 var_8; // don't need that one
+ int32 heightOffset; // var_12 // how much pixel-lines have already been drawn
+ // int32 var_1E;
+ gfxEntryStruct* generatedGfxEntry;
+
+ // check if string is empty
+ if(!string)
+ {
+ return NULL;
+ }
+
+ // check if font has been loaded, else get system font
+ if(fontFileIndex != -1)
+ {
+ fontPtr = filesDatabase[fontFileIndex].subData.ptr;
+
+ if(!fontPtr)
+ {
+ fontPtr = _systemFNT;
+ }
+ }
+ else
+ {
+ fontPtr = _systemFNT;
+ }
+
+ if(!fontPtr)
+ {
+ return NULL;
+ }
+ fontPtr_Data = fontPtr + *(int16*) (fontPtr + 4); // offset to char data
+ fontPtr_Desc = fontPtr + 14; // offset to char description
+
+ lineHeight = getLineHeight(*(int16*) (fontPtr + 8), fontPtr, fontPtr_Desc); // ok
+
+ wordSpacingWidth = *(int16*) (fontPtr + 10);
+ wordSpacingHeight = *(int16*) (fontPtr + 12);
+
+ // if right border is higher then screenwidth (+ spacing), adjust border
+ if(inRightBorder_X > 310)
+ {
+ rightBorder_X = 310;
+ }
+ else
+ {
+ rightBorder_X = inRightBorder_X;
+ }
+ numLines = getTextLineCount(rightBorder_X, wordSpacingWidth, fontPtr_Desc, string); // ok
+
+ if(!numLines)
+ {
+ return NULL;
+ }
+
+ stringHeight = ((wordSpacingHeight + lineHeight + 2) * numLines) + 1;
+ stringFinished = 0;
+ stringWidth = rightBorder_X + 2; // max render width to the right
+ stringRenderBufferSize = stringWidth * stringHeight * 4;
+ inRightBorder_X = rightBorder_X;
+
+ currentStrRenderBuffer = (uint8*) mallocAndZero(stringRenderBufferSize);
+ resetRaster(currentStrRenderBuffer, stringRenderBufferSize);
+
+ generatedGfxEntry = (gfxEntryStruct*) malloc(sizeof(gfxEntryStruct));
+ generatedGfxEntry->imagePtr = currentStrRenderBuffer;
+ generatedGfxEntry->imageSize = stringRenderBufferSize / 2;
+ generatedGfxEntry->fontIndex = fontFileIndex;
+ generatedGfxEntry->height = stringHeight;
+ generatedGfxEntry->width = stringWidth; // maximum render width to the right
+
+ // var_8 = 0;
+ heightOffset = 0;
+
+ do
+ {
+ int spacesCount = 0; // si
+ char character = *string;
+ short int strPixelLength; // var_16
+ uint8* ptrStringEnd; // var_4 //ok
+ int drawPosPixel_X; // di
+
+ // find first letter in string, skip all spaces
+ while(character == ' ')
+ {
+ spacesCount++;
+ character = *(string + spacesCount);
+ }
+
+ string += spacesCount;
+
+ // returns character count and pixel length (via pointer) per line of the text string
+ ptrStringEnd = string + prepareWordRender(inRightBorder_X, wordSpacingWidth, &strPixelLength, fontPtr_Desc, string); //ok
+
+ // determine how much space is left to the right and left (center text)
+ if(inRightBorder_X > strPixelLength)
+ {
+ //var_8 = (inRightBorder_X - strPixelLength) / 2;
+ drawPosPixel_X = (inRightBorder_X - strPixelLength) / 2;
+ }
+ else
+ {
+ drawPosPixel_X = 0;
+ }
+ //drawPosPixel_X = var_8;
+
+ // draw textline, character wise
+ do
+ {
+ uint8 character = *(string++);
+
+ short int charData = fontCharacterTable[character]; // get character position
+
+ if(character)
+ {
+ if(character == ' ' || character == 0x7C)
+ {
+ drawPosPixel_X += wordSpacingWidth + 5; // if char = "space" adjust word starting postion (don't render space though);
+ }
+ else
+ {
+ if(charData >= 0)
+ {
+ short int* si = (int16*) (fontPtr_Desc + charData * 12); // offset font data
+ // int var_2 = si[5]; // don't need this
+
+ // should ist be stringRenderBufferSize/2 for the second last param?
+ renderWord(fontPtr_Data + si[0], currentStrRenderBuffer, drawPosPixel_X, si[4] - si[3] + lineHeight + heightOffset, si[3], si[2], stringRenderBufferSize, stringWidth / 2, si[5]);
+
+ drawPosPixel_X += wordSpacingWidth + si[5];
+ }
+ }
+ }
+ else
+ {
+ stringFinished = 1; // character = 0x00
+ }
+
+ // check if string already reached the end
+ if(ptrStringEnd <= string)
+ {
+ break;
+ }
+ } while(!stringFinished);
+
+ // var_8 = 0;
+ heightOffset += wordSpacingHeight + lineHeight;
+ }while(!stringFinished);
+
+ return generatedGfxEntry;
+}
+
+
+} // End of namespace Cruise
diff --git a/engines/cruise/font.h b/engines/cruise/font.h
new file mode 100644
index 0000000000..b0810d0384
--- /dev/null
+++ b/engines/cruise/font.h
@@ -0,0 +1,49 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef _FONT_H_
+#define _FONT_H_
+
+namespace Cruise {
+
+void loadFNT(void* fileName);
+void loadSystemFont(void);
+
+//////////////////////////////////////////////////
+void flipShort(int16* var);
+void flipShort(uint16* var);
+void flipLong(int32* var); // TODO: move away
+void flipLong(uint32* var); // TODO: move away
+void flipGen(void* var, int32 length);
+
+int32 getLineHeight(int16 charCount, uint8* fontPtr, uint8* fontPrt_Desc); // fontProc1
+int32 getTextLineCount(int32 rightBorder_X, int32 wordSpacingWidth, uint8* ptr, uint8* textString); // fontProc2
+
+void renderWord(uint8* fontPtr_Data, uint8* outBufferPtr, int32 drawPosPixel_X, int32 heightOff, int32 height, int32 param4, int32 stringRenderBufferSize, int32 width , int32 charWidth);
+gfxEntryStruct* renderText(int inRightBorder_X, uint8* string);
+void drawString(int32 x, int32 y, uint8* string, uint8* buffer, uint8 color, int32 inRightBorder_X);
+
+} // End of namespace Cruise
+
+#endif \ No newline at end of file
diff --git a/engines/cruise/fontCharacterTable.cpp b/engines/cruise/fontCharacterTable.cpp
new file mode 100644
index 0000000000..06bea3f601
--- /dev/null
+++ b/engines/cruise/fontCharacterTable.cpp
@@ -0,0 +1,195 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cruise/cruise_main.h"
+
+namespace Cruise {
+
+int16 fontCharacterTable[256]={
+-1,
+-1,
+-1,
+-1,
+-1,
+-1,
+-1,
+-1,
+-1,
+-1,
+-1,
+-1,
+-1,
+-1,
+-1,
+-1,
+-1,
+-1,
+-1,
+-1,
+-1,
+-1,
+-1,
+-1,
+-1,
+-1,
+-1,
+-1,
+-1,
+-1,
+-1,
+-1,
+-1,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+ 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
+ 86, 87, 88, 89, 90, 91, 92,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ 106, 105,
+ -1,
+ -1,
+ -1,
+ -1,
+ 107, 108,
+ -1,-1,
+ 109, 110,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,-1,
+ 111, -1,
+ 112,
+ -1,-1,
+ 113,
+ 114,
+ -1,
+ -1,
+ 116, 93,
+ -1,
+ 118,
+ -1,
+ 94,
+ -1,
+ 117,
+ 115,
+ 96,
+ 95,
+ 97,
+ 98,
+ -1,
+ -1,
+ 99,
+ 100,
+ -1,
+ -1,
+ -1,
+ -1,
+ 101,
+ -1,
+ 102,
+ -1,
+ -1,
+ 103,
+ -1,
+ 104,
+ -1,
+ -1,
+ -1,
+ -1,
+};
+
+
+} // End of namespace Cruise
diff --git a/engines/cruise/fontCharacterTable.h b/engines/cruise/fontCharacterTable.h
new file mode 100644
index 0000000000..79f1647707
--- /dev/null
+++ b/engines/cruise/fontCharacterTable.h
@@ -0,0 +1,35 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef _FONTCHARACTERTABLE_H_
+#define _FONTCHARACTERTABLE_H_
+
+namespace Cruise {
+
+extern short int fontCharacterTable[256];
+
+} // End of namespace Cruise
+
+#endif
+
diff --git a/engines/cruise/function.cpp b/engines/cruise/function.cpp
new file mode 100644
index 0000000000..ed81853cc5
--- /dev/null
+++ b/engines/cruise/function.cpp
@@ -0,0 +1,1718 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cruise/cruise_main.h"
+
+namespace Cruise {
+
+opcodeFunction opcodeTablePtr[256];
+
+struct actorTableStruct
+{
+ int data[13];
+};
+
+typedef struct actorTableStruct actorTableStruct;
+
+actorTableStruct actorTable1[] = {
+ {
+ 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ },
+ {
+ 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ },
+ {
+ 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ },
+ {
+ -38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }
+};
+
+int16 Op_loadOverlay(void)
+{
+ uint8* originalScriptName;
+ uint8 scriptName[38];
+ int returnValue;
+
+ scriptName[0] = 0;
+
+ originalScriptName = (uint8*)popPtr();
+
+ if(originalScriptName)
+ {
+ strcpyuint8(scriptName,originalScriptName);
+ }
+
+ if(!scriptName[0] || !originalScriptName)
+ {
+ return(0);
+ }
+
+ strToUpper(scriptName);
+
+ //gfxModuleData.field_84();
+ //gfxModuleData.field_84();
+
+ returnValue = loadOverlay(scriptName);
+
+ updateAllScriptsImports();
+
+ strcpyuint8(scriptNameBuffer,scriptName);
+
+ return(returnValue);
+}
+
+int16 Op_strcpy(void)
+{
+ char* ptr1 = (char*)popPtr();
+ char* ptr2 = (char*)popPtr();
+
+ //printf("strcpy %s\n",ptr1);
+
+ while(*ptr1)
+ {
+ *ptr2 = *ptr1;
+
+ ptr2++;
+ ptr1++;
+ }
+
+ *ptr2 = 0;
+
+ return(0);
+}
+
+int16 Op_startScript(void)
+{
+ int scriptIdx;
+ int ovlIdx;
+ uint8* ptr;
+ uint8* ptr2;
+
+ short int popTable[256]; // TODO: check original size;
+
+ int numOfArgToPop = popVar();
+
+ int i=0;
+
+ for(i=0;i<numOfArgToPop;i++)
+ {
+ popTable[numOfArgToPop-i-1] = popVar();
+ }
+
+ scriptIdx = popVar();
+ ovlIdx = popVar();
+
+ if(!ovlIdx)
+ {
+ ovlIdx = currentScriptPtr->overlayNumber;
+ }
+
+ ptr = attacheNewScriptToTail(ovlIdx,&scriptHandle2,scriptIdx,currentScriptPtr->type,currentScriptPtr->scriptNumber,currentScriptPtr->overlayNumber,scriptType_Minus20);
+
+ if(!ptr)
+ return(0);
+
+ if(numOfArgToPop<=0)
+ {
+ return(0);
+ }
+
+ ptr2 = ptr;
+
+ for(i=0;i<numOfArgToPop;i++)
+ {
+ saveShort(ptr2,popTable[i]);
+ ptr2+=2;
+ }
+
+ return(0);
+}
+
+int16 Op_startObject(void)
+{
+ int pop1 = popVar();
+ int pop2;
+ int overlay;
+
+ if(pop1-1>0)
+ {
+ printf("Unsuported arg pop in Op_6!\n");
+ exit(1);
+ }
+
+ pop2 = popVar();
+ overlay = popVar();
+
+ if(!overlay)
+ overlay = currentScriptPtr->overlayNumber;
+
+ if(!overlay)
+ return(0);
+
+ attacheNewScriptToTail(overlay,&scriptHandle2,pop2,currentScriptPtr->type,currentScriptPtr->scriptNumber,currentScriptPtr->overlayNumber,scriptType_20);
+
+ if(pop1>0)
+ {
+ printf("Unsupported art send in op6!\n");
+ exit(1);
+ }
+
+ return(0);
+}
+
+int16 Op_37(void)
+{
+ int pop1 = popVar();
+ int pop2 = popVar();
+
+ if(!pop2)
+ pop2 = currentScriptPtr->overlayNumber;
+
+ var30 = pop2;
+ var31 = pop1;
+
+ return(0);
+}
+
+int16 Op_GetMouseX(void) // TODO: implement properly
+{
+ int16 dummy;
+ int16 mouseX;
+ int16 mouseY;
+ int16 mouseButton;
+
+ getMouseStatus(&dummy, &mouseX, &mouseButton, &mouseY);
+
+ return(mouseX);
+}
+
+int16 Op_GetMouseY(void) // TODO: implement properly
+{
+ int16 dummy;
+ int16 mouseX;
+ int16 mouseY;
+ int16 mouseButton;
+
+ getMouseStatus(&dummy, &mouseX, &mouseButton, &mouseY);
+
+ return(mouseY);
+}
+
+int16 Op_rand(void) // TODO: implement
+{
+ int var = popVar();
+
+ if(var<2)
+ {
+ return(0);
+ }
+
+// return(8);
+ return(rand()%var);
+}
+
+int16 Op_E(void) // TODO: implement
+{
+ popVar();
+ popVar();
+ popVar();
+ popVar();
+
+ // printf("Op_E, implement (sound related)\n");
+
+ return(0);
+}
+
+int16 Op_freeAllPerso(void)
+{
+ freeAllPerso();
+ return(0);
+}
+
+void freeObjectList(objectStruct* pListHead)
+{
+ int var_2 = 0;
+ objectStruct* pCurrent = pListHead->next;
+
+ while(pCurrent)
+ {
+ objectStruct* pNext = pCurrent->next;
+
+ if(pCurrent->hide == 0)
+ {
+ free(pCurrent->gfxPtr);
+ free(pCurrent);
+ }
+
+ var_2 = 1;
+
+ pCurrent = pNext;
+ }
+
+ if(var_2)
+ {
+ resetPtr(pListHead);
+ }
+}
+
+int16 Op_freeObjectList(void)
+{
+ freeObjectList(&objectHead);
+ return(0);
+}
+
+int16 Op_freeBackgroundInscrustList(void)
+{
+ freeBackgroundIncrustList(&backgroundIncrustHead);
+ return(0);
+}
+
+int16 Op_removeBackground(void)
+{
+ int backgroundIdx;
+
+ backgroundIdx = popVar();
+
+ printf("Op_removeBackground: remove background %d\n",backgroundIdx);
+ return(0);
+}
+
+int16 Op_freeMediumVar(void)
+{
+ // TODO: implement
+ printf("Op_freeMediumVar, implement\n");
+ return(0);
+}
+
+int16 Op_14(void)
+{
+ int idx;
+ int overlay;
+
+ idx = popVar();
+ overlay = popVar();
+
+ if(!overlay)
+ {
+ overlay = currentScriptPtr->overlayNumber;
+ }
+
+ removeObjectFromList(overlay, idx, &objectHead, currentActiveBackgroundPlane, 5);
+
+ return(0);
+}
+
+int16 Op_isFileLoaded(void)
+{
+ int16 i;
+ uint8 name[36] = "";
+ uint8* ptr;
+
+ ptr = (uint8*)popPtr();
+
+ if(!ptr)
+ {
+ return -1;
+ }
+
+ strcpyuint8(name,ptr);
+ strToUpper(name);
+
+ for(i=0;i<257;i++)
+ {
+ if(!strcmpuint8(name,filesDatabase[i].subData.name))
+ {
+ return(i);
+ }
+ }
+
+ return -1;
+}
+
+int16 Op_resetFilesEntries(void)
+{
+ int var1;
+ int var2;
+
+ var1 = popVar();
+ var2 = popVar();
+
+ resetFileEntryRange(var2,var1);
+
+ return(0);
+}
+
+int16 Op_comment(void)
+{
+ char* var;
+
+ var = (char*)popPtr();
+
+ printf("COMMENT: \"%s\"\n",var);
+
+ return(0);
+}
+
+int16 Op_removeScript(void)
+{
+ int idx;
+ int overlay;
+
+ idx = popVar();
+ overlay = popVar();
+
+ if(!overlay)
+ {
+ overlay = currentScriptPtr->overlayNumber;
+ }
+
+ removeScript(overlay,idx,&scriptHandle2);
+
+ return(0);
+}
+
+int16 Op_releaseScript2(void)
+{
+ uint8 localName[36] = "";
+ uint8* namePtr;
+
+ namePtr = (uint8*)popPtr();
+
+ strcpyuint8(localName,namePtr);
+
+ if(localName[0])
+ {
+ strToUpper(localName);
+ releaseOverlay((char*)localName);
+ }
+
+ return 0;
+}
+
+int16 Op_2B(void)
+{
+ uint8 name[36] = "";
+ uint8* ptr;
+ int param;
+
+ ptr = (uint8*)popPtr();
+
+ strcpyuint8(name,ptr);
+
+ param = getProcParam(popVar(),20,name);
+
+ return param;
+}
+
+int16 Op_freeAllMenu(void)
+{
+ // TODO: implement
+ printf("Op_freeAllMenu, implement\n");
+
+ return 0;
+}
+
+int16 Op_EnterPlayerMenu(void)
+{
+ int oldValue = entrerMenuJoueur;
+ entrerMenuJoueur = popVar();
+
+ return oldValue;
+}
+
+int16 Op_ChangeSaveAllowedState(void)
+{
+ int oldValue = userEnabled;
+ int newValue = popVar();
+
+ if(newValue != -1)
+ {
+ userEnabled = newValue;
+ }
+
+ return oldValue;
+}
+
+int16 Op_changeCutSceneState(void)
+{
+ int oldValue = affichePasMenuJoueur;
+ int newValue = popVar();
+
+ if(newValue != -1)
+ {
+ affichePasMenuJoueur = newValue;
+ }
+
+ return oldValue;
+}
+
+int16 Op_62(void)
+{
+ if(currentScriptPtr->var1A == 20)
+ {
+ changeScriptParamInList(currentScriptPtr->var18,currentScriptPtr->var16,&scriptHandle2,9997,-1);
+ }
+ else
+ if(currentScriptPtr->var1A == 30)
+ {
+ changeScriptParamInList(currentScriptPtr->var18,currentScriptPtr->var16,&scriptHandle1,9997,-1);
+ }
+
+ return 0;
+}
+
+int16 Op_loadBackground(void)
+{
+ int result = 0;
+ uint8 bgName[36] = "";
+ uint8* ptr;
+ int bgIdx;
+
+ ptr = (uint8*)popPtr();
+
+ strcpyuint8(bgName,ptr);
+
+ bgIdx = popVar();
+
+ if(bgIdx >= 0 || bgIdx < 8)
+ {
+ strToUpper(bgName);
+
+ gfxModuleData_gfxWaitVSync();
+ gfxModuleData_gfxWaitVSync();
+
+ result = loadBackground((char*)bgName,bgIdx);
+ }
+
+ changeCursor(0);
+
+ return result;
+}
+
+int16 Op_isFileLoaded2(void)
+{
+ int param;
+
+ param = popVar();
+
+ if(param<0 || param>255)
+ {
+ return 0;
+ }
+
+ if(filesDatabase[param].subData.ptr)
+ {
+ return 1;
+ }
+
+ return 0;
+}
+
+int16 Op_loadFile(void)
+{
+ int param1;
+ int param2;
+ int param3;
+ uint8 name[36] = "";
+ uint8* ptr;
+
+ ptr = (uint8*)popPtr();
+
+ strcpyuint8(name,ptr);
+
+ param1 = popVar();
+ param2 = popVar();
+ param3 = popVar();
+
+ if(param3 >= 0 || param3 < 257)
+ {
+ strToUpper(name);
+
+ gfxModuleData_gfxWaitVSync();
+ gfxModuleData_gfxWaitVSync();
+
+ saveVar6[0] = 0;
+
+ loadFileMode2(name,param3,param2,param1);
+
+ saveVar6[0] = 0;
+ }
+
+ changeCursor(0);
+ return 0;
+}
+
+int16 Op_loadFullBundle(void)
+{
+ int param1;
+// int param2;
+// int param3;
+ uint8 name[36] = "";
+ uint8* ptr;
+ int result = 0;
+
+ ptr = (uint8*)popPtr();
+
+ strcpyuint8(name,ptr);
+
+ param1 = popVar();
+
+ if(param1 >= 0 || param1 < 257)
+ {
+ strToUpper(name);
+
+ gfxModuleData_gfxWaitVSync();
+ gfxModuleData_gfxWaitVSync();
+
+ result = loadFullBundle(name,param1);
+ }
+
+ changeCursor(0);
+ return result;
+}
+
+int16 Op_7(void)
+{
+ int param1 = popVar();
+ int objIdx = popVar();
+ int ovlIdx = popVar();
+
+ if(!ovlIdx)
+ ovlIdx = currentScriptPtr->overlayNumber;
+
+ Op_7Sub(ovlIdx,objIdx,param1);
+
+ return(0);
+}
+
+int16 Op_GetInitVar1(void)
+{
+ return initVar1;
+}
+
+int16 Op_prepareFadeOut(void)
+{
+ printf("Op_prepareFadeOut dummy\n");
+ return 0;
+}
+
+int16 isOverlayLoaded(uint8* name)
+{
+ int16 i;
+
+ for(i=1;i<numOfLoadedOverlay;i++)
+ {
+ if(!strcmpuint8(overlayTable[i].overlayName,name) && overlayTable[i].alreadyLoaded)
+ {
+ return i;
+ }
+ }
+
+ return 0;
+}
+
+int16 Op_isOverlayLoaded(void)
+{
+ uint8 name[36] = "";
+ uint8* ptr;
+
+ ptr = (uint8*)popPtr();
+
+ strcpyuint8(name,ptr);
+ strToUpper(name);
+
+ return(isOverlayLoaded(name));
+}
+
+int16 Op_2C(void)
+{
+ int16 returnParam;
+
+ int16 param1 = popVar();
+ int16 param2 = popVar();
+ int16 param3 = popVar();
+ int16 param4 = popVar();
+
+ getSingleObjectParam(param4,param3,param2,&returnParam);
+ setObjectPosition(param4,param3,param2,param1);
+
+ return returnParam;
+}
+
+int16 Op_setMain5(void)
+{
+ main5 = 1;
+ return 0;
+}
+
+int16 Op_GetMouseClick3(void)
+{
+ int16 dummy;
+ int16 mouseX;
+ int16 mouseY;
+ int16 mouseButton;
+
+ getMouseStatus(&dummy, &mouseX, &mouseButton, &mouseY);
+
+ if(mouseButton&4)
+ return 1;
+ return 0;
+}
+
+int16 Op_5(void)
+{
+ int16 param1 = popVar();
+ int16 param2 = popVar();
+ int16 overlayIdx = popVar();
+
+ if(!overlayIdx)
+ overlayIdx = currentScriptPtr->overlayNumber;
+
+ addObject(overlayIdx,param2,&objectHead,currentScriptPtr->type,currentScriptPtr->scriptNumber,currentScriptPtr->overlayNumber,currentActiveBackgroundPlane,param1);
+
+ return 0;
+}
+
+int16 Op_2F(void)
+{
+ int16 param1 = popVar();
+ int16 param2 = popVar();
+
+ int16 overlayIdx = popVar();
+
+ if(!overlayIdx)
+ overlayIdx = currentScriptPtr->overlayNumber;
+
+ addBackgroundIncrust(overlayIdx,param2,&backgroundIncrustHead,currentScriptPtr->scriptNumber,currentScriptPtr->overlayNumber,currentActiveBackgroundPlane,param1);
+
+ return 0;
+}
+
+int16 Op_8(void)
+{
+ int var1 = popVar();
+ int objectIdx = popVar();
+ int ovlNumber = popVar();
+
+ if(!ovlNumber)
+ {
+ ovlNumber = currentScriptPtr->overlayNumber;
+ }
+
+ removeObjectFromList(ovlNumber, objectIdx, &objectHead, currentActiveBackgroundPlane, var1);
+
+ return 0;
+}
+
+int16 fontFileIndex;
+
+int16 Op_SetFontFileIndex(void)
+{
+ fontFileIndex = popVar();
+
+ return 0;
+}
+
+int16 Op_63(void)
+{
+ if(currentScriptPtr->var1A == 0x14)
+ {
+ changeScriptParamInList(currentScriptPtr->var18,currentScriptPtr->var16,&scriptHandle2,0,-1);
+ }
+ else
+ if(currentScriptPtr->var1A == 0x1E)
+ {
+ changeScriptParamInList(currentScriptPtr->var18,currentScriptPtr->var16,&scriptHandle1,0,-1);
+ }
+
+ return 0;
+}
+
+int16 op7CVar = 0;
+
+int16 Op_7C(void)
+{
+ int16 temp = op7CVar;
+ int16 newVar;
+
+ newVar = popVar();
+ if(newVar != -1)
+ {
+ op7CVar = newVar;
+ }
+ return temp;
+}
+
+int16 Op_message(void)
+{
+ int16 color = popVar();
+ int16 var_2 = popVar();
+ int16 var_4 = popVar();
+ int16 var_6 = popVar();
+ int16 var_8 = popVar();
+ int16 overlayIdx = popVar();
+
+ if(!overlayIdx)
+ overlayIdx = currentScriptPtr->overlayNumber;
+
+ if( color == -1 )
+ {
+ color = 0;
+ //ASSERT(0);
+ //color = calcTabSomething();
+ }
+ else
+ {
+ if(CVTLoaded)
+ {
+ color = cvtPalette[color];
+ }
+ }
+
+ createTextObject(overlayIdx, var_8, &objectHead, currentScriptPtr->scriptNumber, currentScriptPtr->overlayNumber, currentActiveBackgroundPlane, color, var_2, var_4, var_6);
+
+ return 0;
+}
+
+int16 Op_loadAudioResource(void)
+{
+ popPtr();
+ popVar();
+
+ return 0;
+}
+
+int16 Op_loadCtp(void)
+{
+ return loadCtp((uint8*)popPtr());
+}
+
+int16 Op_loadMusic(void)
+{
+ popPtr();
+ return 0;
+}
+
+int16 Op_21(void)
+{
+ int param1 = popVar();
+ int param2 = popVar();
+ int overlay = popVar();
+
+ if(!overlay)
+ overlay = currentScriptPtr->overlayNumber;
+
+ return mainProc13(overlay, param2, &actorHead, param1);
+}
+
+int16 Op_76(void)
+{
+ popPtr();
+ popVar();
+
+ return 0;
+}
+
+int16 Op_65(void)
+{
+ objectStruct* pObject;
+ int var_C = popVar();
+ int var_E = popVar();
+ int var_4 = popVar();
+ int var_10 = popVar();
+ int var_12 = popVar();
+ int di = popVar();
+ int var_8 = popVar();
+ int var_2 = popVar();
+ int var_6 = popVar();
+ int overlay = popVar();
+
+ if(!overlay)
+ overlay = currentScriptPtr->overlayNumber;
+
+ pObject = addObject(overlay, var_6, &objectHead, currentScriptPtr->type, currentScriptPtr->scriptNumber, currentScriptPtr->overlayNumber, currentActiveBackgroundPlane, 4);
+
+ if(!pObject)
+ return 0;
+
+ pObject->field_2C = var_C;
+ pObject->field_30 = var_E;
+ pObject->nextAnimDelay = var_4;
+ pObject->field_26 = var_10;
+ pObject->field_22 = var_12;
+ pObject->field_20 = di;
+ pObject->field_2A = var_8;
+ pObject->field_28 = var_2;
+
+ if(var_8)
+ {
+ if(currentScriptPtr->type == 20)
+ {
+ changeScriptParamInList(currentScriptPtr->overlayNumber, currentScriptPtr->scriptNumber, &scriptHandle2, 9996, -1);
+ }
+ else
+ if(currentScriptPtr->type == 30)
+ {
+ changeScriptParamInList(currentScriptPtr->overlayNumber, currentScriptPtr->scriptNumber, &scriptHandle1, 9996, -1);
+ }
+ }
+
+ if(var_2 == 5)
+ {
+ Op_7Sub(pObject->overlay, pObject->idx, di);
+ }
+ else
+ {
+ setObjectPosition(pObject->overlay, pObject->idx, pObject->field_28, di);
+ }
+
+ if(var_4 < 0)
+ {
+ objectParamsQuery params;
+
+ getMultipleObjectParam(overlay, var_6, &params);
+ pObject->currentAnimDelay = params.var6;
+ }
+
+ return 0;
+}
+
+int16 Op_66(void)
+{
+ objectParamsQuery params;
+ int index = popVar();
+ int overlay = popVar();
+
+ if(!overlay)
+ overlay = currentScriptPtr->overlayNumber;
+
+ getMultipleObjectParam(overlay, index, &params);
+
+ return params.var7;
+}
+
+int16 Op_SetActiveBackgroundPlane(void)
+{
+ int currentPlane = currentActiveBackgroundPlane;
+ int newPlane = popVar();
+
+ if(newPlane >= 0 && newPlane < 8)
+ {
+ if(backgroundPtrtable[newPlane])
+ {
+ currentActiveBackgroundPlane = newPlane;
+ initVar3 = 1;
+ }
+ }
+
+ return currentPlane;
+}
+
+int op6AVar;
+
+int16 Op_6A(void)
+{
+ op6AVar = popVar();
+ return 0;
+}
+
+int op7BVar = 0;
+
+int16 Op_7B(void)
+{
+ int di = popVar();
+ int si = 1 - op7BVar;
+ int sign;
+
+ if(di)
+ {
+ sign = di/(abs(di));
+ }
+ else
+ {
+ sign = 0;
+ }
+
+ op7BVar = -sign;
+
+ return si;
+}
+
+void removeBackgroundIncrust(int overlay, int idx, backgroundIncrustStruct* pHead)
+{
+ objectParamsQuery params;
+ int var_4;
+ int var_6;
+
+ backgroundIncrustStruct* pCurrent;
+ backgroundIncrustStruct* pCurrentHead;
+
+ getMultipleObjectParam(overlay, idx, &params);
+
+ var_4 = params.X;
+ var_6 = params.Y;
+
+ pCurrent = pHead->next;
+
+ while(pCurrent)
+ {
+ if( (pCurrent->overlayIdx == overlay || overlay == -1) &&
+ (pCurrent->objectIdx == idx || idx == -1) &&
+ (pCurrent->X == var_4) &&
+ (pCurrent->Y == var_6))
+ {
+ pCurrent->field_6 = -1;
+ }
+
+ pCurrent = pCurrent->next;
+ }
+
+ pCurrentHead = pHead;
+ pCurrent = pHead->next;
+
+ while(pCurrent)
+ {
+ if(pCurrent->field_6 == -1)
+ {
+ backgroundIncrustStruct* pNext = pCurrent->next;
+ backgroundIncrustStruct* bx = pCurrentHead;
+ backgroundIncrustStruct* cx;
+
+ bx->next = pNext;
+ cx = pNext;
+
+ if(!pNext)
+ {
+ cx = pHead;
+ }
+
+ bx = cx;
+ bx->prev = pCurrent->next;
+
+ if(pCurrent->ptr)
+ {
+ free(pCurrent->ptr);
+ }
+
+ free(pCurrent);
+
+ pCurrent = pNext;
+ }
+ else
+ {
+ pCurrentHead = pCurrent;
+ pCurrent = pCurrent->next;
+ }
+ }
+}
+
+
+int16 Op_removeBackgroundIncrust(void)
+{
+ int idx = popVar();
+ int overlay = popVar();
+
+ if(!overlay)
+ {
+ overlay = currentScriptPtr->overlayNumber;
+ }
+
+ removeBackgroundIncrust(overlay, idx, &backgroundIncrustHead);
+
+ return 0;
+}
+
+int16 Op_D(void) // TODO: palette manipulation
+{
+ int var_4 = popVar();
+ int var_6 = popVar();
+ int var_8 = popVar();
+ int si = popVar();
+ int di = popVar();
+
+ return 0;
+}
+
+int16 Op_78(void)
+{
+ int si = var41;
+
+ var41 = popVar();
+
+ return si;
+}
+
+int16 Op_releaseOverlay(void)
+{
+ int overlayIdx;
+
+ overlayIdx = popVar();
+
+ if(strlen(overlayTable[overlayIdx].overlayName))
+ {
+ releaseOverlay(overlayTable[overlayIdx].overlayName);
+ }
+
+ return 0;
+}
+
+int16 Op_drawLine(void)
+{
+ int di = popVar();
+ int var_2 = popVar();
+ int var_4 = popVar();
+ int var_6 = popVar();
+ uint8* ptr = (uint8*)popPtr();
+
+ //drawLinePtr(var_6, var_4, var_2, ptr);
+
+ // flipGen(ptr);
+
+ return 0;
+}
+
+int16 Op_61(void)
+{
+ int si = popVar();
+ popVar();
+
+ return si;
+}
+
+int16 Op_1A(void)
+{
+ var46 = popVar();
+ var45 = popVar();
+ var42 = popVar();
+ var39 = popVar();
+ return 0;
+}
+
+int16 subOp22(int param)
+{
+ return (((param - var46)*(var39-var42))/(var45 - var46))+var42;
+}
+
+int16 subOp23(int param1, int param2)
+{
+ return (param1*param2)>>8;
+}
+
+int16 Op_23(void)
+{
+ int si = popVar();
+ int dx = popVar();
+
+ return subOp23(dx,si);
+}
+
+int16 Op_22(void)
+{
+ return(subOp22(popVar()));
+}
+
+actorStruct* addAnimation(int overlay, int idx, actorStruct* pHead2, int param, int param2)
+{
+ actorStruct* pCurrent;
+ actorStruct* pHead = pHead2;
+ actorStruct* si = pHead->next;
+ actorStruct* bx = pHead;
+ actorStruct* pNewElement;
+
+ if(si)
+ {
+ do
+ {
+ bx = si;
+ si = bx->next;
+ }while(si);
+ }
+
+ pHead = bx;
+ pCurrent = si;
+
+ if(pCurrent && (pCurrent->overlayNumber == overlay) && (pCurrent->var4 == idx) && (pCurrent->type == param2))
+ {
+ return NULL;
+ }
+ else
+ {
+ actorStruct* cx;
+
+ si = pNewElement = (actorStruct*)malloc(sizeof(actorStruct));
+
+ pNewElement->next = pHead->next;
+ pHead->next = pNewElement;
+
+ cx = pCurrent;
+
+ if(!pCurrent)
+ {
+ cx = pHead;
+ }
+
+ bx = cx;
+ si->prev = bx->prev;
+ bx->prev = si;
+ si->var4 = idx;
+ si->type = param2;
+ si->pathId = -1;
+ si->overlayNumber = overlay;
+ si->startDirection = param;
+ si->nextDirection = -1;
+ si->stepX = 5;
+ si->stepY = 2;
+ si->phase = ANIM_PHASE_WAIT;
+ si->flag = 0;
+ si->freeze = 0;
+
+ return si;
+ }
+}
+
+int flag_obstacle; // computedVar14Bis
+
+void checkCollisionWithWalkBoxesBoundingBoxes(int x, int y)
+{
+ ctpVar19Struct* di = ctpVar19;
+
+ do
+ {
+ int minX;
+ int maxX;
+ int minY;
+ int maxY;
+
+ ctpVar19SubStruct* subStruct;
+
+ if(-1 == (int) di->field_0) // ok, ugly, but it's in the original
+ {
+ flag_obstacle = 0;
+ return;
+ }
+
+ subStruct = &di->subStruct;
+
+ minX = subStruct->minX;
+ maxX = subStruct->maxX;
+ minY = subStruct->minY;
+ maxY = subStruct->maxY;
+
+ computedVar14 = subStruct->boxIdx; // Box index
+
+ if(!(walkboxChange[subStruct->boxIdx]) && (minY >= x) && (maxY <= x) && (minX >= y) && (maxX <= y))
+ {
+ /**************/
+
+ flag_obstacle = walkboxType[computedVar14];
+
+ /**************/
+ }
+
+ di = di->field_0;
+ } while(1);
+
+ flag_obstacle = 0;
+}
+
+// add animation
+int16 Op_18(void)
+{
+ int var_C = popVar();
+ int var_E = popVar();
+ int direction = popVar();
+ int var_8 = popVar();
+ int var_A = popVar();
+ int var_2 = popVar();
+ int overlay = popVar();
+
+ if(!overlay)
+ {
+ overlay = currentScriptPtr->overlayNumber;
+ }
+
+ if(direction>=0 && direction<=3)
+ {
+ actorStruct* si;
+
+ si = addAnimation(overlay, var_2, &actorHead, direction, var_A);
+
+ if(si)
+ {
+ int var_4;
+ objectParamsQuery params;
+
+ getMultipleObjectParam(overlay, var_2, &params);
+
+ si->x = params.X;
+ si->y = params.Y;
+ si->x_dest = -1;
+ si->y_dest = -1;
+ si->endDirection = -1;
+ si->start = var_8;
+ si->stepX = var_E;
+ si->stepY = var_C;
+
+ var_A = abs(actorTable1[direction].data[0]) - 1;
+
+ var_4 = subOp22(params.Y);
+
+ if(actorTable1[direction].data[0] < 0)
+ {
+ var_4 = - var_4;
+ }
+
+ checkCollisionWithWalkBoxesBoundingBoxes(params.X, params.Y);
+
+ setObjectPosition(overlay, var_2, 3, var_8 + var_A);
+ setObjectPosition(overlay, var_2, 4, var_4);
+ setObjectPosition(overlay, var_2, 5, computedVar14);
+
+ animationStart = 0;
+ }
+ }
+
+ return 0;
+}
+
+int16 Op_regenerateBackgroundIncrust(void)
+{
+ regenerateBackgroundIncrust(&backgroundIncrustHead);
+ return 0;
+}
+
+int16 Op_SetStringColors(void)
+{
+ // TODO: here ignore if low color mode
+
+ colorOfSelectedSaveDrive = (uint8)popVar();
+ video2 = (uint8)popVar();
+ video3 = (uint8)popVar();
+ video4 = (uint8)popVar();
+
+ return 0;
+}
+
+int16 Op_1E(void) // setup actor position
+{
+ actorStruct* pActor;
+
+ int var0 = popVar();
+ int actorY = popVar();
+ int actorX = popVar();
+ int var1 = popVar();
+ int var2 = popVar();
+ int overlay = popVar();
+
+ if(!overlay)
+ {
+ overlay = currentScriptPtr->overlayNumber;
+ }
+
+ pActor = findActor(overlay,var2,&actorHead,var1);
+
+ if(!pActor)
+ {
+ return 1;
+ }
+
+ animationStart = 0;
+
+ pActor->x_dest = actorX;
+ pActor->y_dest = actorY;
+ pActor->flag = 1;
+ pActor->endDirection = var0;
+
+ return 0;
+}
+
+int16 Op_45(void)
+{
+ printf("Partial op 45 stop sound\n");
+
+ return 0;
+}
+
+int16 Op_5C(void)
+{
+ popPtr();
+ popVar();
+
+ printf("Partial op 5C\n");
+
+ return 0;
+}
+
+int16 Op_5E(void)
+{
+ popVar();
+
+ printf("Partial op 5E (sound related)\n");
+
+ return 0;
+}
+
+int16 Op_3E(void)
+{
+ printf("Partial op 3E (sound related)\n");
+
+ return 0;
+}
+
+void setVar49Value(int value)
+{
+ flagCt = value;
+}
+
+int16 Op_3A(void)
+{
+ setVar49Value(1);
+ return 0;
+}
+
+int16 Op_3B(void)
+{
+ setVar49Value(0);
+ return 0;
+}
+
+int16 Op_3F(void)
+{
+ printf("Partial op 3F (sound related)\n");
+ return 0;
+}
+
+int16 Op_40(void)
+{
+ printf("Partial op 40 (sound related)\n");
+ //freeStuff1();
+ freeStuff2();
+
+ var24 = 0;
+ var23 = 0;
+ return 0;
+}
+
+int16 Op_19(void)
+{
+ popVar();
+ popVar();
+ popVar();
+
+ printf("Partial op 19 (remove actor)\n");
+
+ return 0;
+}
+
+int16 Op_6C(void)
+{
+ int var0;
+ int var1;
+ int temp;
+
+ var0 = popVar();
+ var1 = popVar();
+
+ if(!var1)
+ {
+ var1 = currentScriptPtr->overlayNumber;
+ }
+
+ temp = overlayTable[var1].executeScripts;
+ overlayTable[var1].executeScripts = var0;
+
+ return temp;
+}
+
+void configureAllObjects(int overlayIdx, objectStruct* pObject, int var4, int var0, int var1, int var2, int var3)
+{
+ while(pObject)
+ {
+ if((pObject->overlay == overlayIdx) || (overlayIdx == -1))
+ {
+ if((pObject->idx == var4) || (var4 == -1))
+ {
+ if((pObject->type == var3) || (var3 == -1))
+ {
+ if((pObject->backgroundPlane == var2) || (var2 == -1))
+ {
+ if((pObject->hide == var1) || (var1 == -1))
+ {
+ pObject->hide = var0;
+ }
+ }
+ }
+ }
+ }
+
+ pObject = pObject->next;
+ }
+}
+
+int16 Op_16(void)
+{
+ int var0;
+ int var1;
+ int var2;
+ int var3;
+ int var4;
+ int var5;
+
+ var0 = popVar();
+ var1 = popVar();
+ var2 = popVar();
+ var3 = popVar();
+ var4 = popVar();
+ var5 = popVar();
+
+ if(!var5)
+ {
+ var5 = currentScriptPtr->overlayNumber;
+ }
+
+ configureAllObjects(var5, &objectHead, var4, var0, var1, var2, var3);
+
+ return 0;
+}
+
+void Op_60Sub(int overlayIdx, actorStruct* pActorHead, int var0, int var1, int var2, int var3)
+{
+ actorStruct* pActor = findActor(overlayIdx, var0, pActorHead, var3);
+
+ if(pActor)
+ {
+ if((pActor->freeze == var2) || (var2 == -1))
+ {
+ pActor->freeze = var1;
+ }
+ }
+}
+
+int16 Op_60(void)
+{
+ int var0;
+ int var1;
+ int var2;
+ int var3;
+ int var4;
+
+ var0 = popVar();
+ var1 = popVar();
+ var2 = popVar();
+ var3 = popVar();
+ var4 = popVar();
+
+ if(!var4)
+ {
+ var4 = currentScriptPtr->overlayNumber;
+ }
+
+ Op_60Sub(var4, &actorHead, var3, var0, var1, var2);
+
+ return 0;
+}
+
+int16 Op_6F(void)
+{
+ int numArgs = popVar();
+
+ assert(numArgs == 0);
+
+ {
+ int var = popVar();
+ char* string = (char*)popPtr();
+
+ printf("partial opcode 6F sprintf (%s)\n", string);
+ }
+
+ return 0;
+}
+
+int16 Op_6E(void)
+{
+ char* ptr0 = (char*)popPtr();
+ char* ptr1 = (char*)popPtr();
+
+ printf("partial opcode 6E (%s)(%s)\n", ptr0, ptr1);
+
+ return 0;
+}
+
+int16 Op_72(void)
+{
+ int var0 = popVar();
+ char* ptr = (char*)popPtr();
+ int var1 = popVar();
+
+ if(!var1)
+ var1 = currentScriptPtr->overlayNumber;
+
+ return getProcParam(var1, var0, (uint8*)ptr);
+}
+
+int16 Op_2A(void)
+{
+ char var_26[36];
+ char* ptr = (char*)popPtr();
+ int overlayIdx;
+
+ var_26[0] = 0;
+
+ if(ptr)
+ {
+ strcpy(var_26, ptr);
+ }
+
+ overlayIdx = popVar();
+
+ if(!overlayIdx)
+ overlayIdx = currentScriptPtr->overlayNumber;
+
+ return getProcParam(overlayIdx, 40, (uint8*)var_26);
+}
+
+void setupOpcodeTable(void)
+{
+ int i;
+
+ for(i=0;i<256;i++)
+ {
+ opcodeTablePtr[i] = NULL;
+ }
+
+ opcodeTablePtr[0x1] = Op_setMain5;
+ opcodeTablePtr[0x2] = Op_prepareFadeOut;
+ opcodeTablePtr[0x3] = Op_loadBackground;
+ opcodeTablePtr[0x4] = Op_loadFullBundle;
+ opcodeTablePtr[0x5] = Op_5;
+ opcodeTablePtr[0x6] = Op_startObject;
+ opcodeTablePtr[0x7] = Op_7;
+ opcodeTablePtr[0x8] = Op_8;
+ opcodeTablePtr[0x9] = Op_freeObjectList;
+ opcodeTablePtr[0xA] = Op_removeScript;
+ opcodeTablePtr[0xB] = Op_resetFilesEntries;
+ opcodeTablePtr[0xC] = Op_loadOverlay;
+ opcodeTablePtr[0xD] = Op_D;
+ opcodeTablePtr[0xE] = Op_E;
+ opcodeTablePtr[0x10] = Op_releaseScript2;
+ opcodeTablePtr[0x11] = Op_isOverlayLoaded;
+ opcodeTablePtr[0x13] = Op_message;
+ opcodeTablePtr[0x14] = Op_14;
+ opcodeTablePtr[0x16] = Op_16;
+ opcodeTablePtr[0x17] = Op_loadCtp;
+ opcodeTablePtr[0x18] = Op_18;
+ opcodeTablePtr[0x19] = Op_19;
+ opcodeTablePtr[0x1A] = Op_1A;
+ opcodeTablePtr[0x1E] = Op_1E;
+ opcodeTablePtr[0x21] = Op_21;
+ opcodeTablePtr[0x22] = Op_22;
+ opcodeTablePtr[0x24] = Op_SetStringColors;
+ opcodeTablePtr[0x28] = Op_ChangeSaveAllowedState;
+ opcodeTablePtr[0x29] = Op_freeAllPerso;
+ opcodeTablePtr[0x2A] = Op_2A;
+ opcodeTablePtr[0x2B] = Op_2B;
+ opcodeTablePtr[0x2C] = Op_2C;
+ opcodeTablePtr[0x2E] = Op_releaseOverlay;
+ opcodeTablePtr[0x2F] = Op_2F;
+ opcodeTablePtr[0x30] = Op_removeBackgroundIncrust;
+ opcodeTablePtr[0x32] = Op_freeBackgroundInscrustList;
+ opcodeTablePtr[0x37] = Op_37;
+ opcodeTablePtr[0x38] = Op_removeBackground;
+ opcodeTablePtr[0x39] = Op_SetActiveBackgroundPlane;
+ opcodeTablePtr[0x3A] = Op_3A;
+ opcodeTablePtr[0x3B] = Op_3B;
+ opcodeTablePtr[0x3C] = Op_rand;
+ opcodeTablePtr[0x3D] = Op_loadMusic;
+ opcodeTablePtr[0x3E] = Op_3E;
+ opcodeTablePtr[0x3F] = Op_3F;
+ opcodeTablePtr[0x40] = Op_40;
+ opcodeTablePtr[0x41] = Op_isFileLoaded2;
+ opcodeTablePtr[0x45] = Op_45;
+ opcodeTablePtr[0x54] = Op_SetFontFileIndex;
+ opcodeTablePtr[0x56] = Op_changeCutSceneState;
+ opcodeTablePtr[0x57] = Op_GetMouseX;
+ opcodeTablePtr[0x58] = Op_GetMouseY;
+ opcodeTablePtr[0x59] = Op_GetMouseClick3;
+ opcodeTablePtr[0x5A] = Op_isFileLoaded;
+ opcodeTablePtr[0x5B] = Op_regenerateBackgroundIncrust;
+ opcodeTablePtr[0x5C] = Op_5C;
+ opcodeTablePtr[0x5E] = Op_5E;
+ opcodeTablePtr[0x60] = Op_60;
+ opcodeTablePtr[0x61] = Op_61;
+ opcodeTablePtr[0x62] = Op_62;
+ opcodeTablePtr[0x63] = Op_63;
+ opcodeTablePtr[0x64] = Op_startScript;
+ opcodeTablePtr[0x65] = Op_65;
+ opcodeTablePtr[0x66] = Op_66;
+ opcodeTablePtr[0x67] = Op_loadAudioResource;
+ opcodeTablePtr[0x68] = Op_freeMediumVar;
+ opcodeTablePtr[0x6A] = Op_6A;
+ opcodeTablePtr[0x6B] = Op_loadFile;
+ opcodeTablePtr[0x6C] = Op_6C;
+ opcodeTablePtr[0x6D] = Op_strcpy;
+ opcodeTablePtr[0x6E] = Op_6E;
+ opcodeTablePtr[0x6F] = Op_6F;
+ opcodeTablePtr[0x70] = Op_comment;
+ opcodeTablePtr[0x71] = Op_drawLine;
+ opcodeTablePtr[0x72] = Op_72;
+ opcodeTablePtr[0x74] = Op_GetInitVar1;
+ opcodeTablePtr[0x76] = Op_76;
+ opcodeTablePtr[0x79] = Op_EnterPlayerMenu;
+ opcodeTablePtr[0x78] = Op_78;
+ opcodeTablePtr[0x7B] = Op_7B;
+ opcodeTablePtr[0x7C] = Op_7C;
+ opcodeTablePtr[0x7D] = Op_freeAllMenu;
+ // TODO: copy the opcodes here
+}
+
+int32 opcodeType8(void)
+{
+ int opcode = getByteFromScript();
+
+ if(!opcode)
+ return(-21);
+
+ if(opcode>0x100)
+ return(-21);
+
+ if(opcodeTablePtr[opcode])
+ {
+ //printf("Function: %X\n",opcode);
+ pushVar(opcodeTablePtr[opcode]());
+ return(0);
+ }
+ else
+ {
+ printf("Unsupported opcode %X in opcode type 8\n",opcode);
+ // exit(1);
+ }
+
+ return 0;
+
+}
+
+
+} // End of namespace Cruise
diff --git a/engines/cruise/function.h b/engines/cruise/function.h
new file mode 100644
index 0000000000..c30bd18fb5
--- /dev/null
+++ b/engines/cruise/function.h
@@ -0,0 +1,39 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef _FUNCTION_H_
+#define _FUNCTION_H_
+
+namespace Cruise {
+
+extern int flag_obstacle;
+void setupOpcodeTable(void);
+int32 opcodeType8(void);
+int16 subOp22(int param);
+int16 subOp23(int param1, int param2);
+
+} // End of namespace Cruise
+
+#endif
+
diff --git a/engines/cruise/gfxModule.cpp b/engines/cruise/gfxModule.cpp
new file mode 100644
index 0000000000..763cb8bae1
--- /dev/null
+++ b/engines/cruise/gfxModule.cpp
@@ -0,0 +1,657 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/stdafx.h"
+#include "common/system.h"
+
+#include "cruise/cruise_main.h"
+
+namespace Cruise {
+
+uint8 page00[320 * 200];
+uint8 page10[320 * 200];
+
+char screen[320 * 200];
+palEntry lpalette[256];
+short globalAtariScreen[320 * 200 / 4];
+
+gfxModuleDataStruct gfxModuleData =
+{
+ 0, // field_1
+ 0, // use Tandy
+ 0, // use EGA
+ 1, // use VGA
+
+ page00, // pPage00
+ page10, // pPage10
+};
+
+void gfxModuleData_gfxClearFrameBuffer(uint8* ptr)
+{
+ memset(ptr, 0, 64000);
+}
+
+void gfxModuleData_gfxCopyScreen(char* sourcePtr, char* destPtr)
+{
+ memcpy(destPtr, sourcePtr, 64000);
+}
+
+void outputBit(char* buffer, int bitPlaneNumber, uint8 data)
+{
+ *(buffer +(8000 * bitPlaneNumber)) = data;
+}
+
+
+void gfxModuleData_field_60(char* sourcePtr, int width, int height, char* destPtr, int x, int y)
+{/*
+ int loc_1064;
+ int loc_10AA;
+ int loc_10AD;
+ int loc_10C5;
+ int loc_10DF;
+ int loc_10EC;
+ int loc_1147;
+ int loc_114B;
+ int loc_117C = 0xF8;
+ int loc_11DC;
+ int loc_1277;
+ int loc_12D9;
+ int loc_12DD;
+
+ int loc_11E7;
+ int loc_127A;
+ int loc_1203;
+ int loc_122B;
+ int loc_117F;
+ int loc_11EF;
+ int loc_1217;
+ int loc_12E1;
+
+ int tempSwap;
+
+ int cx;
+ int bp;
+ int bpSave;
+
+ char* diPtr;
+ char* siPtr;
+
+ int direction = 1;
+ int dx = height;
+ int ax = width;
+ int es = ax << 1;
+ int bx = 0;
+ int di = 199;
+ int si;
+
+ ax = y;
+ si = 0;
+
+ if(y>199) // out of screen vertically
+ return;
+
+ if(y<0) // cropped on the top
+ {
+ cx = bx;
+ bx -= ax;
+ dx -= bx;
+ if(dx <= 0)
+ {
+ return;
+ }
+ ax = es; // es = size of a line ?
+ ax*=(bx&0xFF); // bx number of lines to skip vertically
+ si+=ax;
+ ax = cx;
+ }
+
+ bx = ax;
+ ax += dx;
+ ax--;
+
+ if(ax > di)
+ {
+ ax -= di;
+ dx -= ax;
+
+ if(dx <= 0)
+ {
+ return;
+ }
+ }
+
+ ax = dx;
+ loc_10DF = ax;
+ ax = bx;
+ loc_10AD = ax;
+
+ bx = 0;
+ di = 319;
+
+ ax = x;
+ dx = ax;
+ cx = ax&0xFF;
+ cx &= 7;
+ {
+ int cl = cx;
+ int ch = cl;
+
+ cl-=8;
+ cl=-cl;
+ cl&=7;
+ ax = (ch<<8) | (cl);
+ }
+ loc_1064 = ax;
+ ax = es;
+ ax <<= 3;
+
+ tempSwap = dx;
+ dx = ax;
+ ax = tempSwap;
+
+ if(ax > di)
+ {
+ return;
+ }
+
+ cx = ax;
+ cx += dx;
+ cx --;
+
+ dx >>= 3;
+
+ dx = dx&0xFF;
+
+ if(cx<bx)
+ {
+ return;
+ }
+
+ if(cx>di)
+ {
+ cx -= di;
+ cx >>= 3;
+ dx = (dx&0xFF00) | (((dx&0xFF) - (cx&0xFF))&0xFF);
+ dx = ((cx&0xFF)<<8) | (dx&0xFF);
+ di = 0xF8F9;
+ }
+ else
+ {
+ di = 0xF8F8;
+ }
+
+ if(ax<bx)
+ {
+ ax -= bx;
+ ax = -ax;
+ ax >>= 3;
+
+ si += ax;
+ dx = (dx&0xFF00) | (((dx&0xFF)-(ax&0xFF))&0xFF);
+ dx = (((dx&0xFF00) + ((ax&0xFF)<<8))&0xFF00) | (dx&0xFF);
+ ax = bx;
+ cx = di;
+ cx = (248<<8)|(cx&0xFF);
+ di = cx;
+ }
+
+ loc_10AA = ax;
+ ax = (ax&0xFF00) | (((dx&0xFF00)>>8)&0xFF);
+ ax = ax&0xFF;
+ loc_10C5 = ax;
+ ax = (ax&0xFF00) | (dx&0xFF);
+
+ dx = loc_1064;
+
+ if(dx)
+ {
+ if(di&1)
+ {
+ loc_10C5++;
+ }
+
+ bx = ax;
+ ax--;
+ loc_11DC = ax;
+
+ if(di&0x100)
+ {
+ bx--;
+ }
+
+ ax = bx;
+ ax -= 40;
+ ax = -ax;
+ loc_12D9 = ax;
+ ax = di;
+ loc_1277 = ax&0xFF;
+ ax = (ax&0xFF00) | (((ax&0xFF00)>>8)&0xFF);
+ loc_117C = ax&0xFF;
+ }
+ else
+ {
+ loc_10EC = ax;
+ ax -= 40;
+ ax = -ax;
+ loc_1147 = ax;
+ }
+
+ bx = loc_10AA;
+ ax = loc_10AD;
+ bx = ((((((bx&0xFF00)>>8)&0xFF) + (ax&0xFF))<<8)&0xFF00) | (bx&0xFF);
+
+ bx>>=3;
+ ax<<=3;
+
+ bx+=ax;
+
+ diPtr = destPtr;
+ diPtr += bx;
+
+ ax = loc_10C5;
+ ax<<=2;
+ loc_114B = ax;
+ loc_12DD = ax;
+ ax = si;
+ ax <<=2;
+ siPtr = sourcePtr;
+
+ siPtr+=ax;
+
+ bp = loc_10DF;
+ bx = dx;
+ dx = 974;
+
+ if(!bx) // no crop ?
+ {
+ do // for each line
+ {
+ bpSave = bp;
+ cx = loc_10EC;
+
+ do // for the line
+ {
+ outputBit(diPtr,0,*(siPtr));
+ outputBit(diPtr,1,*(siPtr+1));
+ outputBit(diPtr,2,*(siPtr+2));
+ outputBit(diPtr,3,*(siPtr+3));
+
+ siPtr+=4;
+ diPtr++;
+ }while(--cx);
+
+ diPtr += loc_1147; // interline
+ siPtr += loc_114B;
+ bp = bpSave;
+ }while(--bp);
+ }
+ else // croped
+ {
+ ASSERT(0);
+ loc_1156:
+ ax = (ax&0xFF00) | bx&0xFF;
+ loc_11E7 = ax&0xFF;
+ loc_127A = ax&0xFF;
+ loc_1203 = ax&0xFF;
+ loc_122B = ax&0xFF;
+
+ ax = (ax&0xFF00) | (((bx&0xFF00)>>8)&0xFF);
+ loc_117F = ax&0xFF;
+ loc_11EF = ax&0xFF;
+ loc_1217 = ax&0xFF;
+
+ do // main copy loop
+ {
+ ax = bp;
+ loc_12E1 = ax;
+
+ if(loc_117C == 0xF8)
+ {
+ direction = 1;
+ }
+ else
+ {
+ direction = -1;
+ }
+
+ if(direction == -1)
+ {
+ goto label_11DC;
+ }
+
+ cx = loc_117F;
+
+ ax = (ax&0xFF00) | (((*siPtr)&0xFF)>>cx)&0xFF;
+ dx = (((ax&0xFF)<<8)&0xFF00) | (dx&0xFF);
+ ax = (((ax&0xFF)<<8)&0xFF00) | (ax&0xFF);
+
+ ax = (ax&0xFF00) | (((*(siPtr+1))&0xFF)>>cx)&0xFF;
+ dx = (dx&0xFF00) | (ax&0xFF);
+ ax = ((((((ax&0xFF00)>>8)&0xFF) | (ax&0xFF))<<8)&0xFF00) | (ax&0xFF);
+
+ ax = (ax&0xFF00) | (((*(siPtr+2))&0xFF)>>cx)&0xFF;
+ bx = (((ax&0xFF)<<8)&0xFF00) | (bx&0xFF);
+ ax = ((((((ax&0xFF00)>>8)&0xFF) | (ax&0xFF))<<8)&0xFF00) | (ax&0xFF);
+
+ ax = (ax&0xFF00) | (((*(siPtr+3))&0xFF)>>cx)&0xFF;
+ bx = (bx&0xFF00) | (ax&0xFF);
+ ax = ((((((ax&0xFF00)>>8)&0xFF) | (ax&0xFF))<<8)&0xFF00) | (ax&0xFF);
+
+ if(ax)
+ {
+ bp = dx;
+ ax = (ax&0xFF00) | (*diPtr)&0xFF;
+ ax = (ax&0xFF00) | 8;
+
+ outputBit(diPtr,0,(bp>>8)&0xFF);
+ outputBit(diPtr,1,(bp&0xFF));
+ outputBit(diPtr,2,(bx>>8)&0xFF);
+ outputBit(diPtr,3,(bx&0xFF));
+ }
+
+ diPtr++;
+
+ label_11DC:
+
+ bp = loc_11DC;
+ if(bp >0)
+ {
+ do
+ {
+ cx = loc_11E7;
+
+ ax = (ax&0xFF00) | (((*siPtr)&0xFF)>>cx)&0xFF;
+ dx = (((ax&0xFF)<<8)&0xFF00) | (dx&0xFF);
+ cx = loc_11EF;
+ ax = (ax&0xFF00) | (((*(siPtr+4))&0xFF)>>cx)&0xFF;
+ dx = (((dx&0xFF00) | (((ax&0xFF)<<8)&0xFF00))&0xFF00) | (dx&0xFF);
+ ax = (ax&0xFF00) | (((ax&0xFF) | (((dx&0xFF00)>>8)&0xFF))&0xFF);
+ ax = ((ax&0xFF)<<8) | (ax&0xFF);
+
+ ax = (ax&0xFF00) | (((*(siPtr+5))&0xFF)>>cx)&0xFF;
+ dx = (dx&0xFF00) | (ax&0xFF);
+ cx = loc_1203;
+ ax = (ax&0xFF00) | (((*(siPtr+1))&0xFF)>>cx)&0xFF;
+ dx = (dx&0xFF00) | ((dx&0xFF) | (ax&0xFF));
+ ax = (ax&0xFF00) | ((ax&0xFF) | dx&0xFF);
+ ax = (ax&0xFF00) | ((ax&0xFF)<<8) | (ax&0xFF);
+
+ ax = (ax&0xFF00) | (((*(siPtr+2))&0xFF)>>cx)&0xFF;
+ bx = (((ax&0xFF)<<8)&0xFF00) | (bx&0xFF);
+ cx = loc_1217;
+ ax = (ax&0xFF00) | (((*(siPtr+7))&0xFF)>>cx)&0xFF;
+ bx = (((bx&0xFF00) | (((ax&0xFF)<<8)&0xFF00))&0xFF00) | (bx&0xFF);
+ ax = (ax&0xFF00) | ((ax&0xFF) | ((bx&0xFF00)>>8));
+ ax = (ax&0xFF00) | ((ax&0xFF)<<8) | (ax&0xFF);
+
+ ax = (ax&0xFF00) | (((*(siPtr+7))&0xFF)>>cx)&0xFF;
+ bx = (bx&0xFF00) | (ax&0xFF);
+ cx = loc_122B;
+ ax = (ax&0xFF00) | (((*(siPtr+3))&0xFF)>>cx)&0xFF;
+ bx = (bx&0xFF00) | ((bx&0xFF) | (ax&0xFF));
+ ax = (ax&0xFF00) | ((ax&0xFF) | bx&0xFF);
+ ax = (ax&0xFF00) | ((ax&0xFF)<<8) | (ax&0xFF);
+
+ if(ax)
+ {
+ cx = dx;
+ ax = (ax&0xFF00) | (*diPtr)&0xFF;
+ ax = (ax&0xFF00) | 8;
+
+ outputBit(diPtr,0,(cx>>8)&0xFF);
+ outputBit(diPtr,1,(cx&0xFF));
+ outputBit(diPtr,2,(cx>>8)&0xFF);
+ outputBit(diPtr,3,(cx&0xFF));
+ }
+
+ siPtr += 4;
+ diPtr++;
+ }while(--bp);
+ }
+
+ if(loc_122B == 0xF8)
+ {
+ direction = 1;
+ }
+ else
+ {
+ direction = -1;
+ }
+
+ if(direction == -1)
+ {
+ goto label_12D9;
+ }
+
+ cx = loc_127A;
+
+ ax = (ax&0xFF00) | (((*siPtr)&0xFF)>>cx)&0xFF;
+ dx = (((ax&0xFF)<<8)&0xFF00) | (dx&0xFF);
+ ax = (((ax&0xFF)<<8)&0xFF00) | (ax&0xFF);
+
+ ax = (ax&0xFF00) | (((*(siPtr+1))&0xFF)>>cx)&0xFF;
+ dx = (dx&0xFF00) | (ax&0xFF);
+ ax = ((((((ax&0xFF00)>>8)&0xFF) | (ax&0xFF))<<8)&0xFF00) | (ax&0xFF);
+
+ ax = (ax&0xFF00) | (((*(siPtr+2))&0xFF)>>cx)&0xFF;
+ bx = (((ax&0xFF)<<8)&0xFF00) | (bx&0xFF);
+ ax = ((((((ax&0xFF00)>>8)&0xFF) | (ax&0xFF))<<8)&0xFF00) | (ax&0xFF);
+
+ ax = (ax&0xFF00) | (((*(siPtr+3))&0xFF)>>cx)&0xFF;
+ bx = (bx&0xFF00) | (ax&0xFF);
+ ax = ((((((ax&0xFF00)>>8)&0xFF) | (ax&0xFF))<<8)&0xFF00) | (ax&0xFF);
+
+ if(ax)
+ {
+ bp = dx;
+ ax = (ax&0xFF00) | (*diPtr)&0xFF;
+ ax = (ax&0xFF00) | 8;
+
+ outputBit(diPtr,0,(bp>>8)&0xFF);
+ outputBit(diPtr,1,(bp&0xFF));
+ outputBit(diPtr,2,(bx>>8)&0xFF);
+ outputBit(diPtr,3,(bx&0xFF));
+ }
+
+ siPtr+=4;
+
+ label_12D9:
+ diPtr+=loc_12D9;
+ siPtr+=loc_12DD;
+ bp = loc_12E1;
+
+ }while(--bp);
+ }*/
+
+ {
+ int cols = 320;
+ int rows = 200;
+ int row;
+ int col;
+ int i;
+ uint8* pP;
+ short atariScreen[320*200/4];
+
+ for(i=0;i<rows*cols/4;i++)
+ {
+ atariScreen[i] = *(int16*)sourcePtr;
+ flipShort(&atariScreen[i]);
+ sourcePtr+=2;
+ }
+
+ memcpy(globalAtariScreen,atariScreen,sizeof(atariScreen));
+
+ pP = (uint8*)destPtr;
+
+ for ( row = 0; row < rows; ++row )
+ {
+ for ( col = 0; col < cols; ++col, ++pP )
+ {
+ long int c, ind, b, plane;
+
+ ind = 80 * row + ( ( col >> 4 ) << 2 );
+ b = 0x8000 >> ( col & 0xf );
+ c = 0;
+
+ for ( plane = 0; plane < 4; ++plane )
+ {
+ if ( b & atariScreen[ind+plane] )
+ {
+ c |= (1 << plane);
+ }
+ }
+
+ *pP = (uint8)c;
+ }
+ }
+ }
+/*
+ {
+ int i;
+ int j;
+
+ for(i=x;i<height+x;i++)
+ {
+ for(j=y;j<width*16+y;j++)
+ {
+ if(i>=0&&i<200&&j>=0&&j<320)
+ destPtr[i*320+j] = *(sourcePtr++);
+ }
+ }
+ }*/
+}
+
+void gfxModuleData_setPal256(int16* ptr)
+{
+ int R;
+ int G;
+ int B;
+ int i;
+
+ for(i = 0; i < 256;i++)
+ {
+ R=*(ptr++);
+ G=*(ptr++);
+ B=*(ptr++);
+
+ lpalette[i].R = R;
+ lpalette[i].G = G;
+ lpalette[i].B = B;
+ lpalette[i].A = 255;
+ }
+}
+
+void gfxModuleData_setPal(uint8* ptr)
+{
+ int i;
+ int R;
+ int G;
+ int B;
+
+ for(i = 0; i < 16; i++)
+ {
+#define convertRatio 36.571428571428571428571428571429
+ short int atariColor = *(int16*)ptr;
+ //flipShort(&atariColor);
+ ptr += 2;
+
+ R = (int)(convertRatio*((atariColor & 0x700) >> 8));
+ G = (int)(convertRatio*((atariColor & 0x070) >> 4));
+ B = (int)(convertRatio*((atariColor & 0x007)));
+
+ if(R > 0xFF)
+ R = 0xFF;
+ if(G> 0xFF)
+ G = 0xFF;
+ if(B >0xFF)
+ B = 0xFF;
+
+ lpalette[i].R = R;
+ lpalette[i].G = G;
+ lpalette[i].B = B;
+ lpalette[i].A = 255;
+
+ }
+}
+
+void gfxModuleData_field_90(void)
+{
+}
+
+void gfxModuleData_gfxWaitVSync(void)
+{
+}
+
+void gfxModuleData_flip(void)
+{
+}
+
+void gfxModuleData_field_64(char* sourceBuffer, int width, int height, char* dest, int x, int y, int color)
+{
+ int i;
+ int j;
+
+ x = 0;
+ y = 0;
+
+ for(i = 0; i < height; i++)
+ {
+ for(j = 0; j < width; j++)
+ {
+ dest[(y + i) * 320 / 4 + x + j] = sourceBuffer[i * width + j];
+ }
+ }
+}
+
+void gfxModuleData_flipScreen(void)
+{
+ memcpy(globalScreen, gfxModuleData.pPage00,320*200);
+
+ flip();
+}
+
+void flip()
+{
+ int i;
+ byte paletteRGBA[256 * 4];
+ uint8* outPtr = scaledScreen;
+ uint8* inPtr = globalScreen;
+
+
+ for(i=0;i<256;i++)
+ {
+ paletteRGBA[i * 4 + 0] = lpalette[i].R;
+ paletteRGBA[i * 4 + 1] = lpalette[i].G;
+ paletteRGBA[i * 4 + 2] = lpalette[i].B;
+ paletteRGBA[i * 4 + 3] = 0xFF;
+ }
+ g_system->setPalette(paletteRGBA, 0, 16);
+
+ g_system->copyRectToScreen(globalScreen, 320, 0, 0, 320, 200);
+ g_system->updateScreen();
+
+}
+
+
+} // End of namespace Cruise
diff --git a/engines/cruise/gfxModule.h b/engines/cruise/gfxModule.h
new file mode 100644
index 0000000000..7fa4a5a888
--- /dev/null
+++ b/engines/cruise/gfxModule.h
@@ -0,0 +1,72 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef _GFXMODULE_H_
+#define _GFXMODULE_H_
+
+namespace Cruise {
+
+struct gfxModuleDataStruct
+{
+ int field_1;
+ int useTandy;
+ int useEGA;
+ int useVGA;
+
+ uint8* pPage00;
+ uint8* pPage10;
+};
+
+struct palEntry
+{
+ uint8 R;
+ uint8 G;
+ uint8 B;
+ uint8 A;
+};
+
+typedef struct gfxModuleDataStruct gfxModuleDataStruct;
+typedef struct palEntry palEntry;
+
+extern gfxModuleDataStruct gfxModuleData;
+extern palEntry lpalette[256];
+extern short globalAtariScreen[320*200/4];
+
+void gfxModuleData_gfxClearFrameBuffer(uint8* ptr);
+void gfxModuleData_setPal(uint8* ptr);
+void gfxModuleData_field_90(void);
+void gfxModuleData_gfxWaitVSync(void);
+void gfxModuleData_flip(void);
+void gfxModuleData_field_64(char* sourceBuffer, int width, int height, char* dest, int x, int y, int color);
+void gfxModuleData_gfxCopyScreen(char* sourcePtr,char* destPtr);
+void gfxModuleData_field_60(char* sourcePtr, int width, int height, char* destPtr, int x, int y);
+void gfxModuleData_flipScreen(void);
+void gfxModuleData_setPal256(int16* ptr);
+void flip(void);
+
+
+} // End of namespace Cruise
+
+#endif
+
diff --git a/engines/cruise/linker.cpp b/engines/cruise/linker.cpp
new file mode 100644
index 0000000000..7e10f4633c
--- /dev/null
+++ b/engines/cruise/linker.cpp
@@ -0,0 +1,330 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cruise/cruise_main.h"
+
+namespace Cruise {
+
+exportEntryStruct* parseExport(int* out1, int* pExportedFuncionIdx, char* buffer)
+{
+ char localBuffer[256];
+ uint8 functionName[256];
+ uint8 overlayName[256];
+ char* dotPtr;
+ char* ptr2;
+ int idx;
+ int numExport;
+ exportEntryStruct* currentExportEntry;
+ uint8* entity1Name;
+ int i;
+
+ *out1 = 0;
+ *pExportedFuncionIdx = 0;
+
+ strcpyuint8(localBuffer, buffer);
+ dotPtr = strchr(localBuffer,'.');
+
+ if(dotPtr)
+ {
+ strcpyuint8(functionName,dotPtr+1);
+ *dotPtr = 0;
+
+ strcpyuint8(overlayName,localBuffer);
+ }
+ else
+ {
+ overlayName[0] = 0;
+
+ strcpyuint8(functionName,buffer);
+ }
+
+ ptr2 = strchr((char*)functionName,':');
+
+ if(ptr2)
+ {
+ *ptr2 = 0;
+
+ *out1 = 1;
+ }
+
+ strToUpper(overlayName);
+ strToUpper(functionName);
+ if(strlen((char*)overlayName) == 0)
+ return NULL;
+
+ idx = findOverlayByName2(overlayName);
+
+ if(idx == -4)
+ return(NULL);
+
+ if(overlayTable[idx].alreadyLoaded == 0)
+ return(NULL);
+
+ if(!overlayTable[idx].ovlData)
+ return(NULL);
+
+ numExport = overlayTable[idx].ovlData->numExport;
+ currentExportEntry = overlayTable[idx].ovlData->exportDataPtr;
+ entity1Name = overlayTable[idx].ovlData->exportNamesPtr;
+
+ if(!entity1Name)
+ return(0);
+
+ for(i=0;i<numExport;i++)
+ {
+ uint8 exportedName[256];
+ uint8* name = entity1Name + currentExportEntry->offsetToName;
+
+ strcpyuint8(exportedName,name);
+ strToUpper(exportedName);
+
+ if(!strcmpuint8(functionName,exportedName))
+ {
+ *pExportedFuncionIdx = idx;
+
+ return(currentExportEntry);
+ }
+
+ currentExportEntry++;
+ }
+
+ return(NULL);
+}
+
+
+int updateScriptImport(int ovlIdx)
+{
+ char buffer[256];
+ ovlDataStruct* ovlData;
+ int numData3;
+ int size5;
+ int numImport;
+ int param;
+ int var_32;
+ ovlData3Struct* pScript;
+// char* importDataPtr;
+// char* namePtr;
+// char* linkDataPtr;
+
+ if(!overlayTable[ovlIdx].ovlData)
+ return(-4);
+
+ ovlData = overlayTable[ovlIdx].ovlData;
+
+ numData3 = ovlData->numScripts1;
+ size5 = ovlData->numScripts2;
+ numImport = ovlData->numImport;
+ param = 0;
+
+ // do it for the 2 first string types
+ do
+ {
+
+ int i = 0;
+
+ if(param == 0)
+ {
+ var_32 = numData3;
+ }
+ else
+ {
+ var_32 = size5;
+ }
+
+ if(var_32)
+ {
+ do
+ {
+ importScriptStruct* ptrImportData;
+ uint8* ptrImportName;
+ uint8* ptrData;
+
+ int var_22 = 0;
+
+ if(param == 0)
+ {
+ pScript = getOvlData3Entry(ovlIdx, i);
+ }
+ else
+ {
+ pScript = scriptFunc1Sub2(ovlIdx, i);
+ }
+
+ ptrImportData = (importScriptStruct*) (pScript->dataPtr + pScript->offsetToImportData); // import data
+ ptrImportName = pScript->dataPtr + pScript->offsetToImportName; // import name
+ ptrData = pScript->dataPtr;
+
+ var_22 = 0;
+
+ if(pScript->numImport > 0)
+ {
+ int counter = pScript->numImport;
+
+ do
+ {
+ int param2 = ptrImportData->type;
+
+ if(param2 != 70)
+ {
+ exportEntryStruct* ptrDest2;
+ int out1;
+ int out2;
+
+ strcpyuint8(buffer,ptrImportName + ptrImportData->offsetToName);
+ ptrDest2 = parseExport(&out1,&out2,buffer);
+
+ if(ptrDest2 && out2)
+ {
+ int temp = ptrImportData->offset;
+ if(out1) //is sub function... (ie 'invent.livre:s')
+ {
+ uint8* ptr = ptrData + temp;
+
+ *(ptr+1) = out2;
+ *(int16*)(ptr+2) = ptrDest2->idx;
+
+ flipShort((int16*)(ptr+2));
+ }
+ else
+ {
+ if(param2 == 20 || param2 == 30 || param2 == 40 || param2 == 50 ) // this patch a double push
+ {
+ uint8* ptr = ptrData + temp;
+
+ *(ptr+1) = 0;
+ *(ptr+2) = out2; // update the overlay number
+
+ *(int16*)(ptr+4) = ptrDest2->idx;
+
+ flipShort((int16*)(ptr+4));
+ }
+ else
+ {
+ int var_4 = ptrDest2->var4;
+
+ if(var_4&1)
+ {
+ param2 = 8;
+ }
+ else
+ {
+ param2 = 16;
+ }
+
+ if(var_4>=0 && var_4<=3)
+ {
+ param2 |= 5;
+ }
+ else
+ {
+ param2 |= 6;
+ }
+
+ *(ptrData + temp) = param2;
+ *(ptrData + temp + 1 ) = out2;
+
+ *(int16*)(ptrData + temp + 2) = ptrDest2->idx;
+
+ flipShort((int16*)(ptrData + temp + 2));
+ }
+ }
+ }
+ }
+
+ ptrImportData++;
+ }while(--counter);
+ }
+
+ }while(++i<var_32);
+
+ }
+
+ }while(++param<2);
+
+ if(ovlData->importDataPtr && ovlData->importNamePtr && numImport)
+ {
+ int numImport2 = numImport;
+ int i;
+
+ for(i=0;i<numImport2;i++)
+ {
+ char buffer[256];
+ int out1;
+ int foundExportIdx;
+ exportEntryStruct* pFoundExport;
+ int linkType;
+ int linkEntryIdx;
+
+ strcpyuint8(buffer,ovlData->importNamePtr + ovlData->importDataPtr[i].nameOffset);
+
+ pFoundExport = parseExport(&out1,&foundExportIdx,buffer);
+
+ linkType = ovlData->importDataPtr[i].linkType;
+ linkEntryIdx = ovlData->importDataPtr[i].linkIdx;
+
+ if(pFoundExport && foundExportIdx)
+ {
+ switch(linkType)
+ {
+ case 0: // var
+ {
+ ovlData->linkDataPtr[linkEntryIdx].varIdx = foundExportIdx;
+ ovlData->linkDataPtr[linkEntryIdx].varNameOffset = pFoundExport->offsetToName;
+ break;
+ }
+ case 1: // string
+ {
+ ovlData->linkDataPtr[linkEntryIdx].stringIdx = foundExportIdx;
+ ovlData->linkDataPtr[linkEntryIdx].stringNameOffset = pFoundExport->offsetToName;
+ break;
+ }
+ case 2: // proc
+ {
+ ovlData->linkDataPtr[linkEntryIdx].procIdx = foundExportIdx;
+ ovlData->linkDataPtr[linkEntryIdx].procNameOffset = pFoundExport->offsetToName;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return(0);
+}
+
+// check that the newly loaded isn't used by the already loaded overlays
+void updateAllScriptsImports(void)
+{
+ int i;
+
+ for(i=0;i<90;i++)
+ {
+ if(overlayTable[i].ovlData && overlayTable[i].alreadyLoaded)
+ {
+ updateScriptImport(i);
+ }
+ }
+}
+
+} // End of namespace Cruise
diff --git a/engines/cruise/linker.h b/engines/cruise/linker.h
new file mode 100644
index 0000000000..13c40bbd3a
--- /dev/null
+++ b/engines/cruise/linker.h
@@ -0,0 +1,34 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef _LINKER_H_
+#define _LINKER_H_
+
+namespace Cruise {
+
+void updateAllScriptsImports(void);
+
+} // End of namespace Cruise
+
+#endif
diff --git a/engines/cruise/loadSave.cpp b/engines/cruise/loadSave.cpp
new file mode 100644
index 0000000000..3c9c069da9
--- /dev/null
+++ b/engines/cruise/loadSave.cpp
@@ -0,0 +1,471 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cruise/cruise_main.h"
+
+namespace Cruise {
+
+void loadSavegameDataSub1(FILE* fileHandle)
+{
+ int i;
+
+ for(i=1;i<numOfLoadedOverlay;i++)
+ {
+ filesData[i].field_4 = NULL;
+ filesData[i].field_0 = NULL;
+ filesData2[i].field_0 = 0;
+
+ if(overlayTable[i].alreadyLoaded)
+ {
+ fread(&filesData2[i].field_0,2,1,fileHandle);
+
+ if(filesData2[i].field_0)
+ {
+ filesData[i].field_0 = (uint8*)mallocAndZero(filesData2[i].field_0);
+ if(filesData[i].field_0)
+ {
+ fread(filesData[i].field_0,filesData2[i].field_0,1,fileHandle);
+ }
+ }
+
+ fread(&filesData2[i].field_2,2,1,fileHandle);
+
+ if(filesData2[i].field_2)
+ {
+ filesData[i].field_4 = (uint8*)mallocAndZero(filesData2[i].field_2*12);
+ if(filesData[i].field_4)
+ {
+ fread(filesData[i].field_4,filesData2[i].field_2*12,1,fileHandle);
+ }
+ }
+ }
+ }
+}
+
+void loadScriptsFromSave(FILE* fileHandle,scriptInstanceStruct* entry)
+{
+ short int numScripts;
+ int i;
+
+ fread(&numScripts,2,1,fileHandle);
+
+ for(i=0;i<numScripts;i++)
+ {
+ scriptInstanceStruct* ptr = (scriptInstanceStruct*)mallocAndZero(sizeof(scriptInstanceStruct));
+
+ fread(ptr,0x1C,1,fileHandle); // use 0x1C as our scriptInstanceStruct is bigger than in original because of cross platform problems
+
+ fread(&ptr->varA,2,1,fileHandle);
+
+ if(ptr->varA)
+ {
+ ptr->var6 = (uint8*)mallocAndZero(ptr->varA);
+
+ fread(ptr->var6,ptr->varA,1,fileHandle);
+ }
+
+ /////////
+ ptr->bitMask = *((int16*)ptr+1);
+ /////////
+
+ ptr->nextScriptPtr = 0;
+
+ entry->nextScriptPtr = ptr;
+ entry = ptr;
+ }
+}
+
+void loadSavegameDataSub2(FILE * f)
+{
+ unsigned short int n_chunks;
+ int i;
+ objectStruct *p;
+ objectStruct *t;
+
+ objectHead.next = NULL; // Not in ASM code, but I guess the variable is defaulted
+ // to this value in the .exe
+
+ fread(&n_chunks, 2, 1, f);
+ // BIG ENDIAN MACHINES, PLEASE SWAP IT
+
+ p = &objectHead;
+
+ for (i = 0; i < n_chunks; i++)
+ {
+ t = (objectStruct *) mallocAndZero(sizeof(objectStruct));
+
+ fseek(f, 4, SEEK_CUR);
+ fread(&t->idx, 1, 0x30, f);
+
+ t->next = NULL;
+ p->next = t;
+ t->prev = objectHead.prev;
+ objectHead.prev = t;
+ p = t;
+ }
+}
+
+void loadSavegameActor(FILE* fileHandle)
+{
+ short int numEntry;
+ actorStruct* ptr;
+ int i;
+
+ fread(&numEntry,2,1,fileHandle);
+
+ ptr = &actorHead;
+
+ for(i=0;i<numEntry;i++)
+ {
+ actorStruct* current = (actorStruct*)mallocAndZero(sizeof(actorStruct));
+ fseek(fileHandle, 4, SEEK_CUR);
+ fread(&current->var4,0x26,1,fileHandle);
+
+ current->next = NULL;
+ ptr->next = current;
+ current->prev = actorHead.prev;
+ actorHead.prev = current;
+ ptr = current->next;
+ }
+}
+
+void loadSavegameDataSub5(FILE* fileHandle)
+{
+ if(var1)
+ {
+ fread(&saveVar1,1,1,fileHandle);
+
+ if(saveVar1)
+ {
+ fread(saveVar2,saveVar1,1,fileHandle);
+ }
+ }
+ else
+ {
+ fread(&saveVar1,1,1,fileHandle);
+ }
+
+}
+
+void loadSavegameDataSub6(FILE* fileHandle)
+{
+ int32 var;
+
+ fread(&var,4,1,fileHandle);
+ flipLong(&var);
+
+ if(var)
+ {
+ int i;
+
+ fread(&numberOfWalkboxes, 2, 1, fileHandle);
+
+ if(numberOfWalkboxes)
+ {
+ fread(walkboxType, numberOfWalkboxes * 2, 1, fileHandle);
+ fread(walkboxType, numberOfWalkboxes * 2, 1, fileHandle);
+ }
+
+ for(i=0;i<10;i++)
+ {
+ fread(&persoTable[i],4,1,fileHandle);
+
+ if(persoTable[i])
+ {
+ assert(sizeof(persoStruct) == 0x6AA);
+ persoTable[i] = (persoStruct*)mallocAndZero(sizeof(persoStruct));
+ fread(persoTable[i],0x6AA,1,fileHandle);
+ }
+ }
+ }
+}
+
+
+int loadSavegameData(int saveGameIdx)
+{
+ char buffer[256];
+ FILE* fileHandle;
+ char saveIdentBuffer[6];
+ int j;
+ int initVar1Save;
+ objectStruct* currentObjectHead;
+
+ sprintf(buffer,"CR.%d",saveGameIdx);
+
+ fileHandle = fopen(buffer,"rb");
+
+ if(!fileHandle)
+ {
+ printInfoBlackBox("Sauvegarde non trouvée...");
+ waitForPlayerInput();
+ return(-1);
+ }
+
+ printInfoBlackBox("Chargement en cours...");
+
+ fread(saveIdentBuffer,6,1,fileHandle);
+
+ if(strcmp(saveIdentBuffer,"SAVPC"))
+ {
+ fclose(fileHandle);
+ return(-1);
+ }
+
+ //initVars();
+
+ fread(&var1,2,1,fileHandle);
+ fread(&var2,2,1,fileHandle);
+ fread(&var3,2,1,fileHandle);
+ fread(&var4,2,1,fileHandle);
+ fread(&userEnabled,2,1,fileHandle);
+ fread(&var6,2,1,fileHandle);
+ fread(&var7,2,1,fileHandle);
+ fread(&var8,2,1,fileHandle);
+ fread(&userDelay,2,1,fileHandle);
+ fread(&sysKey,2,1,fileHandle);
+ fread(&var11,2,1,fileHandle);
+ fread(&var12,2,1,fileHandle);
+ fread(&var13,2,1,fileHandle);
+ fread(&var14,2,1,fileHandle);
+ fread(&affichePasMenuJoueur,2,1,fileHandle);
+ fread(&var20,2,1,fileHandle);
+ fread(&var22,2,1,fileHandle);
+ fread(&var23,2,1,fileHandle);
+ fread(&var24,2,1,fileHandle);
+ fread(&automaticMode,2,1,fileHandle);
+
+ // video param (not loaded in EGA mode)
+
+ fread(&video4,2,1,fileHandle);
+ fread(&video2,2,1,fileHandle);
+ fread(&video3,2,1,fileHandle);
+ fread(&colorOfSelectedSaveDrive,2,1,fileHandle);
+
+ //
+
+ fread(&var30,2,1,fileHandle);
+ fread(&var31,2,1,fileHandle);
+ fread(&var34,2,1,fileHandle);
+ fread(&var35,2,1,fileHandle);
+ fread(&animationStart,2,1,fileHandle);
+ fread(&currentActiveBackgroundPlane,2,1,fileHandle);
+ fread(&initVar3,2,1,fileHandle);
+ fread(&initVar2,2,1,fileHandle);
+ fread(&var22,2,1,fileHandle);
+ fread(&main5,2,1,fileHandle);
+ fread(&numOfLoadedOverlay,2,1,fileHandle);
+ fread(&setup1,2,1,fileHandle);
+ fread(&fontFileIndex,2,1,fileHandle);
+ fread(&currentActiveMenu,2,1,fileHandle);
+ fread(&main7,2,1,fileHandle); // ok
+ fread(&main17,2,1,fileHandle);
+ fread(&main14,2,1,fileHandle);
+ fread(&main8,2,1,fileHandle);
+ fread(&var39,2,1,fileHandle);
+ fread(&var42,2,1,fileHandle);
+ fread(&var45,2,1,fileHandle);
+ fread(&var46,2,1,fileHandle);
+ fread(&var47,2,1,fileHandle);
+ fread(&var48,2,1,fileHandle);
+ fread(&flagCt,2,1,fileHandle);
+ fread(&var41,2,1,fileHandle);
+ fread(&entrerMenuJoueur,2,1,fileHandle);
+
+ fread(var50,64,1,fileHandle);
+ fread(var50,64,1,fileHandle); // Hu ? why 2 times ?
+ fread(&systemStrings,sizeof(systemStrings),1,fileHandle); // ok
+ fread(currentCtpName,40,1,fileHandle);
+ fread(backgroundTable,120,1,fileHandle);
+ fread(palette,256,2,fileHandle); // ok
+ fread(initVar5,24,1,fileHandle);
+ fread(globalVars,setup1*2,1,fileHandle);
+ fread(filesDatabase,9766,1,fileHandle);
+ fread(overlayTable,40*numOfLoadedOverlay,1,fileHandle); // ok
+ fread(mediumVar,0x880,1,fileHandle);
+
+ loadSavegameDataSub1(fileHandle);
+ loadScriptsFromSave(fileHandle,&scriptHandle2);
+ loadScriptsFromSave(fileHandle,&scriptHandle1);
+
+ loadSavegameDataSub2(fileHandle);
+ loadBackgroundIncrustFromSave(fileHandle);
+ loadSavegameActor(fileHandle);
+ loadSavegameDataSub5(fileHandle);
+ loadSavegameDataSub6(fileHandle);
+
+ fclose(fileHandle); // finished with loading !!!!! Yatta !
+
+ for(j=0;j<64;j++)
+ {
+ mediumVar[j].ptr=NULL;
+ }
+
+ for(j=1;j<numOfLoadedOverlay;j++)
+ {
+ if(overlayTable[j].alreadyLoaded)
+ {
+ overlayTable[j].alreadyLoaded = 0;
+ loadOverlay((uint8*)overlayTable[j].overlayName);
+
+ if(overlayTable[j].alreadyLoaded)
+ {
+ ovlDataStruct* ovlData = overlayTable[j].ovlData;
+
+ if(filesData[j].field_0)
+ {
+ if(ovlData->data4Ptr)
+ {
+ free(ovlData->data4Ptr);
+ }
+
+ ovlData->data4Ptr = (uint8*)filesData[j].field_0;
+ ovlData->sizeOfData4 = filesData2[j].field_0;
+ }
+
+ if(filesData[j].field_4)
+ {
+ if(ovlData->objData2WorkTable)
+ {
+ free(ovlData->objData2WorkTable);
+ }
+
+ ovlData->objData2WorkTable = (objectParams*)filesData[j].field_4; // TODO: fix !
+ ovlData->size9 = filesData2[j].field_2;
+ }
+
+ }
+ }
+ }
+
+ updateAllScriptsImports();
+
+ saveVar6[0] = 0;
+
+ initVar1Save = initVar1;
+
+ for(j=0;j<257;j++)
+ {
+ if(filesDatabase[j].subData.ptr)
+ {
+ int i;
+ int k;
+
+ for(i=j+1;i<257;i++)
+ {
+ if(filesDatabase[i].subData.ptr)
+ {
+ if(strcmpuint8(filesDatabase[j].subData.name,filesDatabase[i].subData.name))
+ {
+ break;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ for(k=j;k<i;k++)
+ {
+ if(filesDatabase[k].subData.ptr2)
+ initVar1 = 0;
+
+ filesDatabase[k].subData.ptr = NULL;
+ filesDatabase[k].subData.ptr2 = NULL;
+ }
+
+ if(i<2)
+ {
+ printf("Unsupported mono file load!\n");
+ exit(1);
+ //loadFileMode1(filesDatabase[j].subData.name,filesDatabase[j].subData.var4);
+ }
+ else
+ {
+ loadFileMode2((uint8*)filesDatabase[j].subData.name,filesDatabase[j].subData.index, j, i-j);
+ j = i-1;
+ }
+
+ initVar1 = initVar1Save;
+ }
+ }
+
+ saveVar6[0] = 0;
+
+ currentObjectHead = objectHead.next;
+
+ while(currentObjectHead)
+ {
+ if(currentObjectHead->type == 5)
+ {
+ uint8* ptr = mainProc14(currentObjectHead->overlay,currentObjectHead->idx);
+
+ ASSERT(0);
+
+ if(ptr)
+ {
+ ASSERT(0);
+ //*(int16*)(currentobjectHead->datas+0x2E) = getSprite(ptr,*(int16*)(currentobjectHead->datas+0xE));
+ }
+ else
+ {
+ //*(int16*)(currentobjectHead->datas+0x2E) = 0;
+ }
+ }
+
+ currentObjectHead = currentObjectHead->next;
+ }
+
+ //TODO: here, restart music
+
+ if(strlen((char*)currentCtpName))
+ {
+ ctpVar1 = 1;
+ loadCtp(currentCtpName);
+ ctpVar1 = 0;
+ }
+
+ //prepareFadeOut();
+ //gfxModuleData.gfxFunction8();
+
+ for(j=0;j<8;j++)
+ {
+ if(strlen((char*)backgroundTable[j].name))
+ {
+ loadBackground(backgroundTable[j].name,j);
+ }
+ }
+
+ regenerateBackgroundIncrust(&backgroundIncrustHead);
+
+ // to finish
+
+ changeCursor(0);
+ mainDraw(1);
+ flipScreen();
+
+ return(0);
+}
+
+} // End of namespace Cruise
diff --git a/engines/cruise/loadSave.h b/engines/cruise/loadSave.h
new file mode 100644
index 0000000000..8acacaf36e
--- /dev/null
+++ b/engines/cruise/loadSave.h
@@ -0,0 +1,34 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef _LOADSAVE_H_
+#define _LOADSAVE_H_
+
+namespace Cruise {
+
+int loadSavegameData(int saveGameIdx);
+
+} // End of namespace Cruise
+
+#endif
diff --git a/engines/cruise/mainDraw.cpp b/engines/cruise/mainDraw.cpp
new file mode 100644
index 0000000000..7e938bdb96
--- /dev/null
+++ b/engines/cruise/mainDraw.cpp
@@ -0,0 +1,1142 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cruise/cruise_main.h"
+#include "polys.h"
+
+namespace Cruise {
+
+int currentTransparent;
+
+struct drawVar1Struct
+{
+ struct drawVar1Struct* next;
+ short int field_2;
+ short int field_4;
+ short int field_6;
+ short int field_8;
+ objectStruct* field_A;
+};
+
+typedef struct drawVar1Struct drawVar1Struct;
+
+drawVar1Struct drawVar1;
+
+
+void mainDraw6(void)
+{
+ drawVar1Struct* pCurrent = drawVar1.next;
+
+ while(pCurrent)
+ {
+ drawVar1Struct* next = pCurrent->next;
+
+ if(pCurrent->field_6 == 5)
+ {
+ Op_7Sub(pCurrent->field_2, pCurrent->field_4, pCurrent->field_8);
+ }
+ else
+ {
+ setObjectPosition(pCurrent->field_2, pCurrent->field_4, pCurrent->field_6, pCurrent->field_8);
+ }
+
+ if(pCurrent->field_A->nextAnimDelay < 0)
+ {
+ objectParamsQuery params;
+
+ getMultipleObjectParam(pCurrent->field_2, pCurrent->field_4, &params);
+
+ pCurrent->field_A->currentAnimDelay = params.var6-1;
+ }
+
+ free(pCurrent);
+
+ pCurrent = next;
+ }
+}
+
+void flipScreen(void)
+{
+ uint8* swapPtr;
+
+ swapPtr = gfxModuleData.pPage00;
+ gfxModuleData.pPage00 = gfxModuleData.pPage10;
+ gfxModuleData.pPage10 = swapPtr;
+
+ gfxModuleData_flipScreen();
+
+ /*memcpy(globalAtariScreen, gfxModuleData.pPage00, 16000);
+ convertAtariToRaw(gfxModuleData.pPage00,globalScreen,200,320);*/
+}
+
+int spriteX1;
+int spriteX2;
+int spriteY1;
+int spriteY2;
+
+char* polyOutputBuffer;
+
+void pixel(int x, int y, char color)
+{
+ if(x >= 0 && x < 320 && y >= 0 && y < 200)
+ polyOutputBuffer[320*y+x] = color;
+}
+
+// this function checks if the dataPtr is not 0, else it retrives the data for X, Y, scale and DataPtr again (OLD: mainDrawSub1Sub1)
+void getPolyData(int fileIndex, int X, int Y, int *outScale, int *outY, int *outX, char **outDataPtr, int scale, char* dataPtr)
+{
+ if(*(uint16*) dataPtr == 0)
+ {
+ uint16 newFileIndex;
+ uint16 newX;
+ char* newDataPtr; // this one is quite useless
+ uint16 newY;
+
+ dataPtr += 2;
+ newFileIndex = *(uint16*) dataPtr;
+ flipShort(&newFileIndex);
+
+ dataPtr += 2;
+ newX = *(uint16*) dataPtr;
+ flipShort(&newX);
+
+ newDataPtr = dataPtr; // useless
+
+ newY = *(uint16*) (newDataPtr + 2);
+ flipShort(&newY);
+
+ newFileIndex += fileIndex;
+
+ if(newFileIndex >= 0)
+ {
+ if(filesDatabase[newFileIndex].resType == 0 && filesDatabase[newFileIndex].subData.ptr)
+ {
+ dataPtr = (char*)filesDatabase[newFileIndex].subData.ptr;
+ }
+ }
+
+ scale = -scale;
+ X -= newX;
+ Y -= newY;
+ }
+
+ *outDataPtr = dataPtr;
+ *outX = X;
+ *outY = Y;
+ *outScale = scale;
+}
+
+int upscaleValue(int value, int scale)
+{
+ return (((value * scale) << 8) / 2);
+}
+
+int m_flipLeftRight;
+int m_useSmallScale;
+int m_lowerX;
+int m_lowerY;
+int m_coordCount;
+int m_first_X;
+int m_first_Y;
+int m_scaleValue;
+int m_current_X;
+int m_current_Y;
+int m_color;
+
+int16 polyBuffer[512];
+int16 polyBuffer2[512];
+int16 polyBuffer3[404];
+int16 polyBuffer4[512];
+
+// this function fills the sizeTable for the poly (OLD: mainDrawSub1Sub2)
+void getPolySize(int positionX, int positionY, int scale, int sizeTable[4], unsigned char* dataPtr)
+{
+ int upperBorder;
+ int lowerBorder;
+ m_flipLeftRight = 0;
+
+ if(scale < 0) // flip left right
+ {
+ m_flipLeftRight = 1;
+ scale = -scale;
+ }
+
+ // X1
+
+ upperBorder = *(dataPtr + 3);
+
+ if(m_flipLeftRight)
+ {
+ upperBorder = -upperBorder;
+ }
+
+ upperBorder = (upscaleValue(upperBorder, scale) + 0x8000) >> 16;
+ upperBorder = -upperBorder;
+ lowerBorder = upperBorder;
+
+ // X2
+
+ upperBorder = *(dataPtr + 1);
+ upperBorder -= *(dataPtr + 3);
+
+ if(m_flipLeftRight)
+ {
+ upperBorder = -upperBorder;
+ }
+
+ upperBorder = (upscaleValue(upperBorder, scale) + 0x8000) >> 16;
+
+ if(upperBorder < lowerBorder) // exchange borders if lower > upper
+ {
+ int temp = upperBorder;
+ upperBorder = lowerBorder;
+ lowerBorder = temp;
+ }
+
+ sizeTable[0] = lowerBorder; // left
+ sizeTable[1] = upperBorder; // right
+
+ // Y1
+
+ upperBorder = *(dataPtr + 4);
+ upperBorder = (upscaleValue(upperBorder, scale) + 0x8000) >> 16;
+ upperBorder = -upperBorder;
+ lowerBorder = upperBorder;
+
+ // Y2
+
+ upperBorder = *(dataPtr + 2);
+ upperBorder -= *(dataPtr + 4);
+ upperBorder = (upscaleValue(upperBorder, scale) + 0x8000) >> 16;
+
+ if(upperBorder < lowerBorder) // exchange borders if lower > upper
+ {
+ int temp = upperBorder;
+ upperBorder = lowerBorder;
+ lowerBorder = temp;
+ }
+
+ sizeTable[2] = lowerBorder; // bottom
+ sizeTable[3] = upperBorder; // top
+}
+
+void blitPolyMode1(char* dest, char* ptr, int16* buffer, char color)
+{
+}
+
+void blitPolyMode2(char* dest, int16* buffer, char color)
+{
+}
+
+int polySize1;
+int polySize2;
+int polySize3;
+int polySize4;
+
+int polyVar1;
+int16* polyVar2;
+
+void drawPolySub(void)
+{
+ int i;
+
+ for(i = 0; i < polyVar1; i++)
+ {
+ line(polyBuffer4[i * 2], polyBuffer4[i * 2 + 1], polyBuffer4[(i + 1) * 2], polyBuffer4[(i + 1) * 2 + 1], m_color & 0xF);
+ }
+
+ fillpoly(polyBuffer4, polyVar1, m_color & 0xF);
+}
+
+char* drawPolyMode1(char* dataPointer, int linesToDraw)
+{
+ int index;
+ int16* pBufferDest;
+
+ polyVar1 = linesToDraw;
+ pBufferDest = &polyBuffer4[polyVar1 * 2];
+ index = *(dataPointer++);
+
+ polySize1 = polySize2 = pBufferDest[-2] = pBufferDest[-2 + linesToDraw * 2] = polyBuffer2[index * 2];
+ polySize1 = polySize2 = pBufferDest[-1] = pBufferDest[-1 + linesToDraw * 2] = polyBuffer2[(index * 2) + 1];
+
+ linesToDraw--;
+
+ pBufferDest -= 2;
+
+ polyVar2 = pBufferDest;
+
+ do
+ {
+ int value;
+
+ index = *(dataPointer++);
+ value = pBufferDest[-2] = pBufferDest[-2 + polyVar1 * 2] = polyBuffer2[index * 2];
+
+ if(value < polySize1)
+ {
+ polySize1 = value;
+ }
+ if(value > polySize2)
+ {
+ polySize2 = value;
+ }
+
+ value = pBufferDest[-1] = pBufferDest[-1 + polyVar1 * 2] = polyBuffer2[(index * 2) + 1];
+
+ if(value > polySize4)
+ {
+ polySize4 = value;
+ }
+ if(value < polySize3)
+ {
+ polySize3 = value;
+ polyVar2 = pBufferDest - 4;
+ }
+ pBufferDest -= 2;
+
+ } while(--linesToDraw);
+
+ drawPolySub();
+
+ return dataPointer;
+}
+
+char* drawPolyMode2(char* dataPointer, int linesToDraw)
+{
+ int index;
+ int16* pBufferDest;
+
+ pBufferDest = polyBuffer4;
+ polyVar1 = linesToDraw;
+ polyVar2 = polyBuffer4;
+ index = *(dataPointer++);
+
+ polySize1 = polySize2 = pBufferDest[0] = pBufferDest[linesToDraw * 2] = polyBuffer2[index * 2];
+ polySize1 = polySize2 = pBufferDest[1] = pBufferDest[linesToDraw * 2 + 1] = polyBuffer2[(index * 2) + 1];
+
+ linesToDraw--;
+
+ pBufferDest += 2;
+
+ do
+ {
+ int value;
+
+ index = *(dataPointer++);
+ value = pBufferDest[0] = pBufferDest[polyVar1 * 2] = polyBuffer2[index * 2];
+
+ if(value < polySize1)
+ {
+ polySize1 = value;
+ }
+ if(value > polySize2)
+ {
+ polySize2 = value;
+ }
+
+ value = pBufferDest[1] = pBufferDest[polyVar1 * 2 + 1] = polyBuffer2[(index * 2) + 1];
+
+ if(value > polySize4)
+ {
+ polySize4 = value;
+ }
+ if(value < polySize3)
+ {
+ polySize3 = value;
+ polyVar2 = pBufferDest;
+ }
+
+ pBufferDest += 2;
+
+ } while(--linesToDraw);
+
+ drawPolySub();
+
+ return dataPointer;
+}
+
+// this function builds the poly model and then calls the draw functions (OLD: mainDrawSub1Sub5)
+void buildPolyModel(int positionX, int positionY, int scale, char* ptr2, char* destBuffer, char* dataPtr)
+{
+ int counter = 0; // numbers of coordinates to process
+ int startX = 0; // first X in model
+ int startY = 0; // first Y in model
+ int x = 0; // current X
+ int y = 0; // current Y
+ int offsetXinModel = 0; // offset of the X value in the model
+ int offsetYinModel = 0; // offset of the Y value in the model
+ unsigned char* dataPointer = (unsigned char*)dataPtr;
+ int16* ptrPoly_1_Buf = polyBuffer;
+ int16* ptrPoly_2_Buf;
+ polyOutputBuffer = destBuffer; // global
+
+ m_flipLeftRight = 0;
+ m_useSmallScale = 0;
+ m_lowerX = *(dataPointer + 3);
+ m_lowerY = *(dataPointer + 4);
+
+ if(scale < 0)
+ {
+ scale = -scale; // flip left right
+ m_flipLeftRight = 1;
+ }
+
+ if(scale < 0x180) // If scale is smaller than 384
+ {
+ m_useSmallScale = 1;
+ m_scaleValue = scale << 1; // double scale
+ }
+ else
+ {
+ m_scaleValue = scale;
+ }
+
+ dataPointer += 5;
+
+ m_coordCount = (*(dataPointer++)) + 1; // original uses +1 here but its later substracted again, we could skip it
+ m_first_X = *(dataPointer++);
+ m_first_Y = *(dataPointer++);
+ startX = m_lowerX - m_first_X;
+ startY = m_lowerY - m_first_Y;
+
+ if(m_useSmallScale)
+ {
+ startX >>= 1;
+ startY >>= 1;
+ }
+
+ if(m_flipLeftRight)
+ {
+ startX = -startX;
+ }
+
+ /*
+ NOTE:
+
+ The original code continues here with using X, Y instead of startX and StartY.
+
+ Original code:
+ positionX -= (upscaleValue(startX, m_scaleValue) + 0x8000) >> 16;
+ positionY -= (upscaleValue(startX, m_scaleValue) + 0x8000) >> 16;
+ */
+
+ // get coordinates from data
+
+ startX = positionX - ((upscaleValue(startX, m_scaleValue) + 0x8000) >> 16);
+ startY = positionY - ((upscaleValue(startY, m_scaleValue) + 0x8000) >> 16);
+
+ ptrPoly_1_Buf[0] = 0;
+ ptrPoly_1_Buf[1] = 0;
+ ptrPoly_1_Buf += 2;
+ counter = m_coordCount - 1 - 1; // skip the first pair, we already have the values
+
+ do
+ {
+ x = *(dataPointer++) - m_first_X;
+ y = *(dataPointer++) - m_first_Y;
+
+ if(m_useSmallScale) // shrink all coordinates by factor 2 if a scale smaller than 384 is used
+ {
+ x >>= 1;
+ y >>= 1;
+ }
+
+ ptrPoly_1_Buf[0] = offsetXinModel - x;
+ ptrPoly_1_Buf++;
+ offsetXinModel = x;
+
+ ptrPoly_1_Buf[0] = -(offsetYinModel - y);
+ ptrPoly_1_Buf++;
+ offsetYinModel = y;
+
+ } while(--counter);
+
+ // scale and adjust coordinates with offset (using two polybuffers by doing that)
+
+ /*
+ NOTE: Is there a need for having two, a scaled and unscaled polybuffer?
+ */
+
+ ptrPoly_2_Buf = polyBuffer;
+ ptrPoly_1_Buf = polyBuffer2;
+ counter = m_coordCount - 1; // reset counter // process first pair two
+ m_current_X = 0;
+ m_current_Y = 0;
+
+ do
+ {
+ x = ptrPoly_2_Buf[0];
+
+ if(m_flipLeftRight == 0)
+ {
+ x = -x;
+ }
+
+ //////////////////
+
+ m_current_X += upscaleValue(x, m_scaleValue);
+ ptrPoly_1_Buf[0] = ((m_current_X + 0x8000) >> 16) + startX; // adjust X value with start offset
+
+ m_current_Y += upscaleValue(ptrPoly_2_Buf[1], m_scaleValue);
+ ptrPoly_1_Buf[1] = ((m_current_Y + 0x8000) >> 16) + startY; // adjust Y value with start offset
+
+ /////////////////
+
+ ptrPoly_1_Buf += 2;
+ ptrPoly_2_Buf += 2;
+
+ } while(--counter);
+
+ // position of the dataPointer is m_coordCount * 2
+
+ do
+ {
+ int linesToDraw = *dataPointer++;
+
+ if(linesToDraw > 1) // if value not zero
+ {
+ uint16 minimumScale;
+
+ m_color = *dataPointer; // color
+ dataPointer += 2;
+
+ minimumScale = *(uint16*) (dataPointer);
+ dataPointer += 2;
+
+ flipShort(&minimumScale);
+
+ if(minimumScale > scale) // if the scale is too small, for the model to be drawn ...
+ {
+ dataPointer += linesToDraw; // ... skip ahead
+ }
+ else
+ {
+ if(m_flipLeftRight)
+ {
+ dataPointer = (unsigned char*)drawPolyMode1((char*)dataPointer, linesToDraw);
+ }
+ else
+ {
+ dataPointer = (unsigned char*)drawPolyMode2((char*)dataPointer, linesToDraw);
+ }
+
+ if(destBuffer)
+ {
+ if(ptr2)
+ {
+ blitPolyMode1(destBuffer, ptr2, polyBuffer3, m_color & 0xF);
+ }
+ else
+ {
+ blitPolyMode2(destBuffer, polyBuffer3, m_color & 0xF);
+ }
+ }
+ }
+ }
+ else
+ {
+ dataPointer += 4;
+ }
+ } while(*dataPointer != 0xFF);
+}
+
+// draw poly sprite (OLD: mainDrawSub1)
+void mainDrawPolygons(int fileIndex, objectStruct* pObject, int X, int scale, int Y, char* destBuffer, char* dataPtr)
+{
+ int newX;
+ int newY;
+ int newScale;
+ char* newDataPtr;
+ char* ptr2; // unused
+ int var_8; // unused
+
+ int sizeTable[4]; // 0 = left, 1 = right, 2 = bottom, 3 = top
+
+ // this function checks if the dataPtr is not 0, else it retrives the data for X, Y, scale and DataPtr again (OLD: mainDrawSub1Sub1)
+ getPolyData(fileIndex, X, Y, &newScale, &newY, &newX, &newDataPtr, scale, dataPtr);
+
+ // this function fills the sizeTable for the poly (OLD: mainDrawSub1Sub2)
+ getPolySize(newX, newY, newScale, sizeTable, (unsigned char*)newDataPtr);
+
+ spriteX2 = sizeTable[0] - 2; // left border
+ spriteX1 = sizeTable[1] + 18; // right border
+ spriteY2 = sizeTable[2] - 2; // bottom border
+ spriteY1 = sizeTable[3] + 2; // top border
+
+/* if (X == 28 && Y == 80 && scale == 1024) {
+ printf("0--> x1: %i, y1: %i, x2: %i, y2: %i\n", sizeTable[1], sizeTable[3], sizeTable[0], sizeTable[2]);
+ printf("1--> x1: %i, y1: %i, x2: %i, y2: %i\n", spriteX1, spriteY1, spriteX2, spriteY2);
+ } */
+ if(spriteX2 >= 320)
+ return;
+ if(spriteX1 < 0)
+ return;
+ if(spriteY2 >= 200)
+ return;
+ if(spriteY1 < 0)
+ return;
+
+ if(spriteX2 < 0)
+ {
+ spriteX2 = 0;
+ }
+ if(spriteX1 > 320)
+ {
+ spriteX1 = 320;
+ }
+ if(spriteY2 < 0)
+ {
+ spriteY2 = 0;
+ }
+ if(spriteY1 > 200)
+ {
+ spriteY1 = 200;
+ }
+
+ if(spriteX1 == spriteX2)
+ return;
+ if(spriteY1 == spriteY2)
+ return;
+
+ ptr2 = NULL;
+ var_8 = 0;
+
+ if(pObject)
+ {
+ objectStruct* pCurrentObject = pObject;
+
+ do
+ {
+ if(pCurrentObject->type == 2)
+ {
+ // ASSERT(0);
+ }
+
+ pCurrentObject = pCurrentObject->next;
+ } while(pCurrentObject);
+ }
+
+ // this function builds the poly model and then calls the draw functions (OLD: mainDrawSub1Sub5)
+ buildPolyModel(newX, newY, newScale, ptr2, destBuffer, newDataPtr);
+}
+
+void mainSprite(int globalX, int globalY, gfxEntryStruct* pGfxPtr, uint8* ouputPtr, int newColor, int idx)
+{
+ // this is used for font only
+
+ if(pGfxPtr)
+ {
+ uint8* initialOuput;
+ uint8* output;
+ int i;
+ int j;
+ int x;
+ int y;
+ uint8* ptr = pGfxPtr->imagePtr;
+ int height = pGfxPtr->height;
+ int width = pGfxPtr->width;
+
+ if(globalY < 0)
+ {
+ globalY = 0;
+ }
+
+ if(globalY + pGfxPtr->height >= 198)
+ {
+ globalY = 198 - pGfxPtr->height;
+ }
+
+ initialOuput = ouputPtr + (globalY*320) + globalX;
+
+ y = globalY;
+ x = globalX;
+
+ for(i = 0; i < height; i++)
+ {
+ output = initialOuput + 320 * i;
+
+ for(j = 0; j < width; j++)
+ {
+ uint8 color = *(ptr++);
+
+ if(color)
+ {
+ if((x >= 0) && (x < 320) && (y >= 0) && (y < 200))
+ {
+ if(color == 1)
+ {
+ *output = (uint8) 0;
+ }
+ else
+ {
+ *output = (uint8) newColor;
+ }
+ }
+ }
+ output++;
+ }
+ }
+ }
+}
+
+void mainDrawSub4(int objX1, int var_6, objectStruct* currentObjPtr, char* data1, int objY2, int objX2, char* output, char* data2)
+{
+ int x = 0;
+ int y = 0;
+
+ for(y = 0; y < var_6; y++)
+ {
+ for(x = 0; x < (objX1 * 8); x++)
+ {
+ uint8 color = (data1[0]);
+ data1++;
+
+ if((x + objX2) >= 0 && (x + objX2) < 320 && (y + objY2) >= 0 && (y + objY2) < 200)
+ {
+ if(color != currentTransparent)
+ {
+ output[320 * (y + objY2) + x + objX2] = color;
+ }
+ }
+ }
+ }
+}
+
+void mainDraw5(int overlayIdx, int idx, int field_28, objectStruct* pObject, int newVal)
+{
+ drawVar1Struct* pNewEntry;
+
+ pNewEntry = (drawVar1Struct*)malloc(sizeof(drawVar1Struct));
+
+ pNewEntry->next = drawVar1.next;
+ drawVar1.next = pNewEntry;
+
+ pNewEntry->field_2 = overlayIdx;
+ pNewEntry->field_4 = idx;
+ pNewEntry->field_6 = field_28;
+ pNewEntry->field_8 = newVal;
+ pNewEntry->field_A = pObject;
+}
+
+#ifdef _DEBUG
+void drawCtp(void)
+{
+ int i;
+
+ if(ctp_walkboxTable)
+ {
+ for(i = 0; i < 15; i++)
+ {
+ uint16* dataPtr = &ctp_walkboxTable[i * 40];
+ int type = walkboxType[i]; // show different types in different colors
+
+ if(*dataPtr)
+ {
+ int j;
+ fillpoly((short*)dataPtr+1, *dataPtr, type);
+
+ for(j = 0; j < (*dataPtr - 1); j++)
+ {
+ line(dataPtr[1 + j * 2], dataPtr[1 + j * 2 + 1], dataPtr[1 + (j + 1) * 2], dataPtr[1 + ( j + 1) * 2 + 1], 0);
+ }
+
+ line(dataPtr[1 + j * 2], dataPtr[1 + j * 2 + 1], dataPtr[1], dataPtr[2], 0);
+ }
+ }
+ }
+}
+#endif
+
+void drawMenu(menuStruct* pMenu)
+{
+ if(pMenu && pMenu->numElements)
+ {
+ int height;
+ int x;
+ int y;
+ int var_10;
+ int bx;
+ int newX;
+ int var_6;
+ int currentY;
+ int var_8;
+ int di;
+ menuElementStruct* si;
+
+ height = pMenu->gfx->height;
+ x = pMenu->x;
+ y = pMenu->y;
+
+ var_10 = pMenu->gfx->width / (199 - (pMenu->gfx->width * 2));
+
+ bx = var_10 / (pMenu->numElements + 1); // rustine...
+
+ if(!bx)
+ {
+ bx++;
+
+ if((pMenu->numElements * height) + y > 199 - height)
+ {
+ y = ((-1 - pMenu->numElements) * height) + 200;
+ }
+ }
+ else
+ {
+ if(var_10 % pMenu->numElements)
+ {
+ bx++;
+ }
+
+ y = height;
+ }
+
+ newX = 320 * (2 - bx);
+
+ if(newX < x)
+ {
+ x = newX;
+ }
+
+ if(x < 0)
+ {
+ x = 0;
+ }
+
+ var_6 = (80 * (bx-1)) + x;
+
+ if(var_6 <= 320)
+ {
+ mainSprite(var_6, y - height, pMenu->gfx, gfxModuleData.pPage10, video4, 320);
+ }
+
+ currentY = y;
+ var_8 = 0;
+ di = x;
+
+ si = pMenu->ptrNextElement;
+
+ if(si)
+ {
+ do
+ {
+ int color;
+
+ gfxEntryStruct* var_2 = si->gfx;
+
+ si->x = di;
+ si->y = currentY;
+ si->varA = 320;
+
+ if(si->varC)
+ {
+ color = video3;
+ }
+ else
+ {
+ if(si->color != 255)
+ {
+ color = si->color;
+ }
+ else
+ {
+ color = video2;
+ }
+ }
+
+ if(di < 320)
+ {
+ mainSprite(di, currentY, var_2, gfxModuleData.pPage10, color, 320);
+ }
+
+ currentY += height;
+ var_8++;
+
+ if(var_8 == var_10)
+ {
+ var_8 = 0;
+ di += 320;
+ currentY = y;
+ }
+
+ si = si->next;
+ } while(si);
+ }
+ }
+}
+
+int getValueFromObjectQuerry(objectParamsQuery* params, int idx)
+{
+ switch(idx)
+ {
+ case 0:
+ return params->X;
+ case 1:
+ return params->Y;
+ case 2:
+ return params->baseFileIdx;
+ case 3:
+ return params->fileIdx;
+ case 4:
+ return params->scale;
+ case 5:
+ return params->var5;
+ case 6:
+ return params->var6;
+ case 7:
+ return params->var7;
+ }
+
+ assert(0);
+
+ return 0;
+}
+
+void mainDraw(int16 param)
+{
+ uint8* bgPtr;
+ objectStruct* currentObjPtr;
+ int16 currentObjIdx;
+ int16 objX1 = 0;
+ int16 objY1 = 0;
+ int16 objZ1 = 0;
+ int16 objX2;
+ int16 objY2;
+ int16 spriteHeight;
+
+
+ if(fadeVar)
+ {
+ return;
+ }
+
+ bgPtr = backgroundPtrtable[currentActiveBackgroundPlane];
+
+ if(bgPtr)
+ {
+ gfxModuleData_gfxCopyScreen((char*)bgPtr,(char*)gfxModuleData.pPage10);
+ }
+
+ drawVar1.next = NULL;
+
+ currentObjPtr = objectHead.next;
+
+#ifdef _DEBUG
+ polyOutputBuffer = (char*)bgPtr;
+ drawCtp();
+#endif
+
+ //-------------------------------------------------- DRAW OBJECTS TYPE 4 -----------------------------------------//
+
+ while(currentObjPtr)
+ {
+ if((currentActiveBackgroundPlane == currentObjPtr->backgroundPlane) && (currentObjPtr->hide == 0) && (currentObjPtr->type == 4))
+ {
+ int16 fileIdx;
+ objectParamsQuery params;
+
+ currentObjIdx = currentObjPtr->idx;
+
+ if((currentObjPtr->followObjectOverlayIdx == currentObjPtr->overlay) && (currentObjPtr->followObjectIdx == currentObjPtr->idx))
+ {
+ objX1 = 0;
+ objY1 = 0;
+ objZ1 = 0;
+ }
+ else
+ {
+ // Declaring this twice ?
+ // objectParamsQuery params;
+
+ getMultipleObjectParam(currentObjPtr->followObjectOverlayIdx, currentObjPtr->followObjectIdx, &params);
+
+ objX1 = params.X;
+ objY1 = params.Y;
+ objZ1 = params.fileIdx;
+ }
+
+ getMultipleObjectParam(currentObjPtr->overlay, currentObjIdx, &params);
+
+ objX2 = objX1 + params.X;
+ objY2 = objY1 + params.Y;
+
+ fileIdx = params.fileIdx;
+
+ if(fileIdx >= 0)
+ {
+ fileIdx += objZ1;
+ }
+
+ if((params.var5 >= 0) && (fileIdx >= 0) && filesDatabase[fileIdx].subData.ptr)
+ {
+ if(filesDatabase[fileIdx].subData.resourceType == 8)
+ {
+ mainDrawPolygons(fileIdx, currentObjPtr, objX2, params.scale, objY2, (char*)gfxModuleData.pPage10, (char*)filesDatabase[fileIdx].subData.ptr); // poly
+ }
+ else if(filesDatabase[fileIdx].subData.resourceType == 6)
+ {
+ }
+ else if(filesDatabase[fileIdx].resType == 1)
+ {
+ }
+ else if(filesDatabase[fileIdx].subData.resourceType == 4)
+ {
+ objX1 = filesDatabase[fileIdx].width; // width
+ spriteHeight = filesDatabase[fileIdx].height; // height
+
+ if(filesDatabase[fileIdx].subData.ptr)
+ {
+ currentTransparent = filesDatabase[fileIdx].subData.transparency;
+
+ mainDrawSub4(objX1, spriteHeight, currentObjPtr, (char*)filesDatabase[fileIdx].subData.ptr, objY2, objX2, (char*)gfxModuleData.pPage10, (char*)filesDatabase[fileIdx].subData.ptr);
+ }
+ }
+ }
+
+ if((currentObjPtr->field_26 != 0) && (param == 0))
+ {
+ if(currentObjPtr->currentAnimDelay <= 0)
+ {
+ int newVal;
+ objX1 = 1;
+
+ newVal = getValueFromObjectQuerry(&params,currentObjPtr->field_28) + currentObjPtr->field_26;
+
+ if(currentObjPtr->field_26 > 0)
+ {
+ if(currentObjPtr->field_22 < newVal)
+ {
+ if(currentObjPtr->field_30 >= 0)
+ {
+ int16 data2;
+
+ newVal = currentObjPtr->field_20;
+
+ if(currentObjPtr->field_30 > 0)
+ {
+ currentObjPtr->field_30--;
+ }
+
+ data2 = currentObjPtr->field_20;
+
+ objX1 = 0;
+ currentObjPtr->field_26 = 0;
+
+ if(currentObjPtr->field_2A) // should we resume the script ?
+ {
+ if(currentObjPtr->field_1A == 20)
+ {
+ changeScriptParamInList(currentObjPtr->field_18, currentObjPtr->field_16, &scriptHandle2, 0, -1);
+ }
+ else
+ if(currentObjPtr->field_1A == 30)
+ {
+ changeScriptParamInList(currentObjPtr->field_18, currentObjPtr->field_16, &scriptHandle1, 0, -1);
+ }
+ }
+ newVal = data2;
+ }
+ }
+ }
+ else
+ {
+ ASSERT(0);
+ /* if(currentObjPtr->field_22>newVal)
+ {
+ } */
+ }
+
+ if(currentObjPtr->nextAnimDelay >= 0)
+ {
+ currentObjPtr->currentAnimDelay = currentObjPtr->nextAnimDelay;
+ }
+
+ if(currentObjPtr->field_2C >= 0 && (currentObjPtr->field_2C == newVal) && currentObjPtr->field_2A != 0)
+ {
+ if(currentObjPtr->field_1A == 20)
+ {
+ changeScriptParamInList(currentObjPtr->field_18, currentObjPtr->field_16, &scriptHandle2, 0, -1);
+ }
+ else
+ if(currentObjPtr->field_1A == 30)
+ {
+ changeScriptParamInList(currentObjPtr->field_18, currentObjPtr->field_16, &scriptHandle1, 0, -1);
+ }
+
+ currentObjPtr->field_2A = 0;
+ }
+
+ if(objX1)
+ {
+ mainDraw5(currentObjPtr->overlay, currentObjPtr->idx, currentObjPtr->field_28, currentObjPtr, newVal);
+ }
+ }
+ else
+ {
+ currentObjPtr->currentAnimDelay--;
+ }
+ }
+ }
+
+ currentObjPtr = currentObjPtr->next;
+ }
+
+ //----------------------------------------------------------------------------------------------------------------//
+
+ mainDraw6();
+ var20 = 0;
+
+ //-------------------------------------------------- DRAW OBJECTS TYPE 5 -----------------------------------------//
+
+ currentObjPtr = objectHead.next;
+
+ while(currentObjPtr)
+ {
+ if(currentObjPtr->type == 5 && currentObjPtr->hide == 0)
+ {
+ mainSprite(currentObjPtr->field_A, currentObjPtr->field_C, currentObjPtr->gfxPtr, gfxModuleData.pPage10, currentObjPtr->field_10, currentObjPtr->spriteIdx);
+ var20 = 1;
+ }
+ currentObjPtr = currentObjPtr->next;
+ }
+
+ //----------------------------------------------------------------------------------------------------------------//
+
+ if(currentActiveMenu != -1)
+ {
+ if(menuTable[currentActiveMenu])
+ {
+ drawMenu(menuTable[currentActiveMenu]);
+ return;
+ }
+ }
+
+ if(mouseVar1)
+ {
+ ASSERT(0);
+ // TODO: draw mouse here
+ }
+}
+
+} // End of namespace Cruise
diff --git a/engines/cruise/mainDraw.h b/engines/cruise/mainDraw.h
new file mode 100644
index 0000000000..eb3c5b64e8
--- /dev/null
+++ b/engines/cruise/mainDraw.h
@@ -0,0 +1,48 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef _MAINDRAW_H_
+#define _MAINDRAW_H_
+
+namespace Cruise {
+
+extern int currentTransparent;
+extern int16 polyBuffer3[404];
+extern int16 polyBuffer2[512];
+extern int m_color;
+
+int upscaleValue(int value, int scale);
+
+void pixel(int x, int y, char color);
+void mainDraw(int16 param);
+void flipScreen(void);
+void buildPolyModel(int X, int Y, int scale, char* ptr2, char* destBuffer, char* dataPtr);
+void getPolyData(int fileIndex, int X, int Y, int *newScale, int *newY, int *newX, char **newDataPtr, int scale, char* dataPtr);
+void mainDrawSub4(int objX1, int var_6, objectStruct* currentObjPtr, char* data1, int objY2, int objX2, char* output, char* data2);
+char* drawPolyMode2(char* si, int cx);
+
+} // End of namespace Cruise
+
+#endif
+
diff --git a/engines/cruise/menu.cpp b/engines/cruise/menu.cpp
new file mode 100644
index 0000000000..5837415ffc
--- /dev/null
+++ b/engines/cruise/menu.cpp
@@ -0,0 +1,321 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cruise/cruise_main.h"
+
+namespace Cruise {
+
+menuStruct* menuTable[8];
+
+menuStruct* createMenu(int X, int Y, char* menuName)
+{
+ menuStruct* entry;
+
+ entry = (menuStruct*)malloc(sizeof(menuStruct));
+ ASSERT(entry);
+
+ entry->x = X - 80;
+ entry->y = Y;
+ entry->stringPtr = menuName;
+ entry->numElements = 0;
+ entry->ptrNextElement = NULL;
+ entry->gfx = renderText(160, (uint8*)menuName);
+
+ return entry;
+}
+
+// TODO: rewrite to remove the goto
+void addSelectableMenuEntry(int var0, int var1, menuStruct* pMenu, int var2, int color, char* menuText)
+{
+ menuElementStruct* di;
+ menuElementStruct* var_6;
+ menuElementStruct* pNewElement;
+ menuElementSubStruct* pSubStruct;
+ menuElementSubStruct* pSubStructCurrent;
+
+ if(pMenu->numElements <= 48)
+ {
+ var_6 = pMenu->ptrNextElement;
+
+ if(var_6)
+ {
+ do
+ {
+ di = var_6;
+ if(var2)
+ {
+ if(!strcmp(var_6->string, menuText))
+ {
+ pNewElement = var_6;
+ pSubStruct = (menuElementSubStruct*)allocAndZero(sizeof(menuElementSubStruct));
+ ASSERT(pSubStruct);
+
+ pSubStruct->pNext = NULL;
+ pSubStruct->var2 = var0;
+ pSubStruct->var4 = var1;
+
+ pSubStructCurrent = pNewElement->ptrSub;
+
+ if(!pSubStructCurrent)
+ {
+ pNewElement->ptrSub = pSubStruct;
+ return;
+ }
+
+ if(pSubStructCurrent->pNext)
+ {
+ do
+ {
+ pSubStructCurrent = pSubStructCurrent->pNext;
+ }while(pSubStructCurrent->pNext);
+ }
+
+ pSubStructCurrent->pNext = pSubStruct;
+ return;
+ }
+ }
+ var_6 = var_6->next;
+ }
+ while(var_6);
+
+ var_6 = di;
+ }
+
+ pNewElement = (menuElementStruct*)allocAndZero(sizeof(menuElementStruct));
+ ASSERT(pNewElement);
+ pSubStruct = (menuElementSubStruct*)allocAndZero(sizeof(menuElementSubStruct));
+ ASSERT(pSubStruct);
+
+ pNewElement->string = menuText;
+ pNewElement->next = NULL;
+ pNewElement->varC = 0;
+ pNewElement->color = color;
+ pNewElement->gfx = renderText(160,(uint8*)menuText);
+
+ if(var_6 == NULL)
+ {
+ pMenu->ptrNextElement = pNewElement;
+ }
+ else
+ {
+ var_6->next = pNewElement;
+ }
+
+ pNewElement->ptrSub = pSubStruct;
+
+ pSubStruct->pNext = NULL;
+ pSubStruct->var2 = var0;
+ pSubStruct->var4 = var1;
+
+ pMenu->numElements++;
+ }
+}
+
+void updateMenuMouse(int mouseX, int mouseY, menuStruct* pMenu)
+{
+ if(pMenu)
+ {
+ if(pMenu->gfx)
+ {
+ int height = pMenu->gfx->height; // rustine
+ int var_2 = 0;
+ menuElementStruct* pCurrentEntry = pMenu->ptrNextElement;
+
+ while(pCurrentEntry)
+ {
+ pCurrentEntry->varC = 0;
+
+ if(var_2 == 0)
+ {
+ if((mouseX > pCurrentEntry->x) && ((pCurrentEntry->x + 160) >= mouseX))
+ {
+ if((mouseY > pCurrentEntry->y) && ((pCurrentEntry->y + height) >= mouseY))
+ {
+ var_2 = 1;
+ pCurrentEntry->varC = 1;
+ }
+ }
+ }
+
+ pCurrentEntry = pCurrentEntry->next;
+ }
+ }
+ }
+}
+
+int processMenu(menuStruct* pMenu)
+{
+ int16 mouseX;
+ int16 mouseY;
+ int16 mouseButton;
+ int di;
+ int si;
+ currentActiveMenu = 0;
+
+ mainDraw(1);
+ flipScreen();
+
+ di = 0;
+ si = 0;
+
+ do
+ {
+ getMouseStatus(&main10, &mouseX, &mouseButton, &mouseY);
+
+ updateMenuMouse(mouseX, mouseY, pMenu);
+
+ if(mouseButton)
+ {
+ if(di)
+ {
+ si = 1;
+ }
+ }
+ else
+ {
+ di = 1;
+ }
+
+ mainDraw(1);
+ flipScreen();
+
+// readKeyboard();
+ }while(!si);
+
+ currentActiveMenu = -1;
+
+ mainDraw(1);
+ flipScreen();
+
+ return 0;
+}
+
+int playerMenu(int menuX, int menuY)
+{
+ int retourMenu;
+ int restartGame = 0;
+
+ if(entrerMenuJoueur && affichePasMenuJoueur)
+ {
+ if(var0)
+ {
+ systemStrings.param = 0;
+ var24 = 0;
+ var23 = 0;
+ freeStuff2();
+ }
+/*
+ if(currentMenu)
+ {
+ freeMenu(currentMenu);
+ currentMenu = 0;
+ var37 = 0;
+ var38 = 0;
+ main9 = -1;
+ }
+
+ if(inventoryMenu)
+ {
+ freeMenu(inventoryMenu);
+ inventoryMenu = 0;
+ var37 = 0;
+ var38 = 0;
+ main9 = -1;
+ }*/
+
+/* if(mouseVar2)
+ {
+ free3(mouseVar2);
+ } */
+
+/* mouseVar2 = 0;
+ mouseVar1 = 0; */
+ freeDisk();
+
+ menuTable[0] = createMenu(menuX, menuY, "Menu Joueur");
+ ASSERT(menuTable[0]);
+
+ addSelectableMenuEntry(0, 3, menuTable[0], 1, -1, "Lecteur de Sauvegarde");
+ if(userEnabled)
+ {
+ addSelectableMenuEntry(0, 4, menuTable[0], 1, -1, "Sauvegarde");
+ }
+ addSelectableMenuEntry(0, 5, menuTable[0], 1, -1, "Chargement");
+ addSelectableMenuEntry(0, 6, menuTable[0], 1, -1, "Recommencer le jeu");
+ addSelectableMenuEntry(0, 7, menuTable[0], 1, -1, "Chargement");
+
+ retourMenu = processMenu(menuTable[0]);
+ }
+
+ return 0;
+}
+
+void freeGfx(gfxEntryStruct* pGfx)
+{
+ if(pGfx->imagePtr)
+ {
+ free(pGfx->imagePtr);
+ }
+
+ free(pGfx);
+}
+
+void freeMenu(menuStruct* pMenu)
+{
+ menuElementStruct* pElement = pMenu->ptrNextElement;
+
+ while(pElement)
+ {
+ menuElementStruct* next;
+ menuElementSubStruct* pSub = pElement->ptrSub;
+
+ next = pElement->next;
+
+ while(pSub)
+ {
+ menuElementSubStruct* next;
+
+ next = pSub->pNext;
+
+ free(pSub);
+
+ pSub=next;
+ }
+
+ if(pElement->gfx)
+ {
+ freeGfx(pElement->gfx);
+ }
+
+ free(pElement);
+
+ pElement = next;
+ }
+
+ freeGfx(pMenu->gfx);
+ free(pMenu);
+}
+
+} // End of namespace Cruise
+
diff --git a/engines/cruise/menu.h b/engines/cruise/menu.h
new file mode 100644
index 0000000000..df49304b20
--- /dev/null
+++ b/engines/cruise/menu.h
@@ -0,0 +1,49 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+namespace Cruise {
+
+struct menuStruct
+{
+ char* stringPtr;
+ gfxEntryStruct* gfx;
+ int x;
+ int y;
+ int numElements;
+ menuElementStruct* ptrNextElement;
+};
+
+typedef struct menuStruct menuStruct;
+
+extern menuStruct* menuTable[8];
+
+menuStruct* createMenu(int X, int Y, char* menuName);
+void addSelectableMenuEntry(int var0, int var1, menuStruct* pMenu, int var2, int color, char* menuText);
+void updateMenuMouse(int mouseX, int mouseY, menuStruct* pMenu);
+int processMenu(menuStruct* pMenu);
+void freeMenu(menuStruct* pMenu);
+int playerMenu(int menuX, int menuY);
+
+
+} // End of namespace Cruise
diff --git a/engines/cruise/mouse.cpp b/engines/cruise/mouse.cpp
new file mode 100644
index 0000000000..801f2dc63d
--- /dev/null
+++ b/engines/cruise/mouse.cpp
@@ -0,0 +1,51 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cruise/cruise_main.h"
+
+namespace Cruise {
+
+int16 main10;
+
+void getMouseStatus(int16* pMouseVar, int16* pMouseX, int16* pMouseButton, int16* pMouseY)
+{
+ // mouseStatusStruct localStatus;
+
+ // OSystem_GetMouseStatus(&localStatus);
+
+ *pMouseX = 0;
+ *pMouseY = 0;
+
+ *pMouseButton = 0;
+/*
+ if(localStatus.left)
+ *pMouseButton |= 1;
+ if(localStatus.right)
+ *pMouseButton |= 2;
+ if(localStatus.middle)
+ *pMouseButton |= 4;
+ */
+}
+
+} // End of namespace Cruise
diff --git a/engines/cruise/mouse.h b/engines/cruise/mouse.h
new file mode 100644
index 0000000000..fb72c111ba
--- /dev/null
+++ b/engines/cruise/mouse.h
@@ -0,0 +1,37 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef _MOUSE_H_
+#define _MOUSE_H_
+
+namespace Cruise {
+
+extern int16 main10;
+
+void getMouseStatus(int16* pMouseVar, int16* pMouseX, int16* pMouseButton, int16* pMouseY);
+
+} // End of namespace Cruise
+
+#endif
+
diff --git a/engines/cruise/object.cpp b/engines/cruise/object.cpp
new file mode 100644
index 0000000000..4d53a36a4f
--- /dev/null
+++ b/engines/cruise/object.cpp
@@ -0,0 +1,519 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cruise/cruise_main.h"
+
+namespace Cruise {
+
+//10 values:
+/*
+
+0 = X
+1 = Y
+3 = fileIdx
+4 = scale
+
+*/
+
+objDataStruct* getObjectDataFromOverlay(int ovlIdx,int objIdx)
+{
+ objDataStruct* var_6;
+
+ if(ovlIdx<1 || objIdx <0)
+ return NULL;
+
+ if(!overlayTable[ovlIdx].ovlData)
+ return NULL;
+
+ if(overlayTable[ovlIdx].ovlData->numObjData <= objIdx)
+ return NULL;
+
+ var_6 = overlayTable[ovlIdx].ovlData->objDataTable;
+
+ if(!var_6)
+ return NULL;
+
+ return (&var_6[objIdx]);
+}
+
+int16 getMultipleObjectParam(int16 overlayIdx,int16 objectIdx,objectParamsQuery* returnParam)
+{
+ int16 size;
+ int16 var_A;
+ int16 var_14;
+ objectParams* ptr2;
+ objDataStruct* ptr;
+ ovlDataStruct* ovlData;
+// int16 type;
+
+ ptr = getObjectDataFromOverlay(overlayIdx,objectIdx);
+
+ if(!ptr)
+ return -11;
+
+ ovlData = overlayTable[overlayIdx].ovlData;
+
+ switch(ptr->var1)
+ {
+ case 0:
+ {
+ ptr2 = &ovlData->objData2SourceTable[ptr->var5];
+
+ var_14 = globalVars[*(int16*)(&overlayTable[overlayIdx].field_14 + ptr->var6)];
+
+ var_A = ptr2->var5;
+
+ break;
+ }
+ case 1:
+ {
+ ptr2 = &ovlData->objData2WorkTable[ptr->var4];
+
+ var_A = var_14 = ptr2->var5;
+ size = var_A + ptr->var5;
+
+ if(ptr->var5 + var_14<=ovlData->size8)
+ {
+ var_A = ovlData->objData2SourceTable[ptr->var5 + var_14].var5;
+ }
+ break;
+ }
+ default:
+ {
+ printf("unsupported case %d in getMultipleObjectParam\n", ptr->var1);
+ exit(1);
+ }
+ }
+
+ returnParam->X = ptr2->X;
+ returnParam->Y = ptr2->Y;
+ returnParam->baseFileIdx = ptr2->baseFileIdx;
+ returnParam->fileIdx = ptr2->var3;
+ returnParam->scale = ptr2->scale;
+ returnParam->var5 = var_14;
+ returnParam->var6 = var_A;
+ returnParam->var7 = ptr->var3;
+
+ return 0;
+}
+
+objectStruct* addObject(int16 overlayIdx,int16 param2,objectStruct* pHead,int16 scriptType,int16 scriptNumber,int16 scriptOverlay, int16 param3, int16 param4)
+{
+ int16 var;
+
+ objectStruct* newElement;
+ objectStruct* currentHead = pHead;
+ objectStruct* currentHead2;
+ objectStruct* currentHead3;
+
+ if(getSingleObjectParam(overlayIdx,param2,2,&var)<0)
+ {
+ return 0;
+ }
+
+ currentHead3 = currentHead;
+ currentHead2 = currentHead->next;
+
+ while(currentHead2)
+ {
+ if(currentHead2->type == 3)
+ {
+ break;
+ }
+
+ if(currentHead2->type != 5)
+ {
+ int16 lvar2;
+
+ getSingleObjectParam(currentHead2->overlay,currentHead2->idx,2,&lvar2);
+
+ if(lvar2 > var)
+ break;
+ }
+
+ currentHead3 = currentHead2;
+ currentHead2 = currentHead2->next;
+ }
+
+ if(currentHead2)
+ {
+ if( (currentHead2->overlay == overlayIdx) &&
+ (currentHead2->backgroundPlane == param3) &&
+ (currentHead2->idx == param2) &&
+ (currentHead2->type == param4))
+
+ return NULL;
+ }
+
+ currentHead = currentHead2;
+
+ newElement = (objectStruct*)mallocAndZero(sizeof(objectStruct));
+
+ if(!newElement)
+ return 0;
+
+ newElement->next = currentHead3->next;
+ currentHead3->next = newElement;
+
+ newElement->idx = param2;
+ newElement->type = param4;
+ newElement->backgroundPlane = param3;
+ newElement->overlay = overlayIdx;
+ newElement->hide = 0;
+ newElement->field_16 = scriptNumber;
+ newElement->field_18 = scriptOverlay;
+ newElement->gfxPtr = NULL;
+ newElement->followObjectIdx = param2;
+ newElement->followObjectOverlayIdx = overlayIdx;
+ newElement->field_1A = scriptType;
+ newElement->field_20 = 0;
+ newElement->field_22 = 0;
+ newElement->nextAnimDelay = 0;
+ newElement->field_2C = 0;
+ newElement->currentAnimDelay = 0;
+ newElement->field_2A = 0;
+ newElement->field_26 = 0;
+ newElement->field_30 = 0;
+
+ if(currentHead)
+ {
+ newElement->prev = currentHead->prev;
+ currentHead->prev = newElement;
+ }
+ else
+ {
+ newElement->prev = pHead->prev;
+ pHead->prev = newElement;
+ }
+
+
+ return newElement;
+}
+
+void setObjectPosition(int16 param1,int16 objIdx,int16 param3,int16 param4)
+{
+ objDataStruct* ptr;
+ objectParams* ptr2;
+
+ ptr = getObjectDataFromOverlay(param1, objIdx);
+
+ if(!ptr)
+ {
+ return;
+ ASSERT(0);
+ }
+
+ //overlayTable[param1].ovlData
+
+ switch(ptr->var1)
+ {
+ case 1:
+ {
+ ptr2 = &overlayTable[param1].ovlData->objData2WorkTable[ptr->var4];
+
+ switch(param3)
+ {
+ case 0: // x
+ {
+ ptr2->X = param4;
+ break;
+ }
+ case 1: // y
+ {
+ ptr2->Y = param4;
+ break;
+ }
+ case 2: // base file
+ {
+ ptr2->baseFileIdx = param4;
+ break;
+ }
+ case 3:
+ {
+ ptr2->var3 = param4;
+ break;
+ }
+ case 4: // scale
+ {
+ ptr2->scale = param4;
+ break;
+ }
+ case 5: // box colision
+ {
+ ptr2->var5 = param4;
+ break;
+ }
+ default:
+ {
+ ASSERT(0);
+ }
+ }
+
+ break;
+ }
+ default:
+ {
+ ASSERT(0);
+ }
+ }
+}
+
+void Op_7Sub1(int16 param1, int16 param2, objectStruct* objPtr)
+{
+ int16 var;
+ objectStruct* var8;
+ objectStruct* var40;
+ objectStruct* var3E;
+ objectStruct* currentObjPtrPrevious;
+ objectStruct* currentObjPtr2;
+ objectStruct* match;
+
+ getSingleObjectParam(param1,param2,2,&var);
+
+ currentObjPtrPrevious = objPtr;
+ currentObjPtr2 = objPtr->next;
+
+ match = NULL;
+ var40 = NULL;
+ var3E = NULL;
+ var8 = objPtr;
+
+ while(currentObjPtr2)
+ {
+ if((currentObjPtr2->overlay == param1) && (currentObjPtr2->idx == param2)) // found
+ {
+ currentObjPtrPrevious->next = currentObjPtr2->next;
+
+ if(currentObjPtr2->next)
+ {
+ currentObjPtr2->next->prev = currentObjPtr2->prev;
+ }
+ else
+ {
+ objPtr->prev = currentObjPtr2->prev;
+ }
+
+ if(var40)
+ {
+ var40->prev = currentObjPtr2;
+ }
+ else
+ {
+ var3E = currentObjPtr2;
+ }
+
+ currentObjPtr2->prev = NULL;
+
+ currentObjPtr2->next = var40;
+
+ var40 = currentObjPtr2;
+
+ if(match == NULL)
+ {
+ match = currentObjPtr2;
+ }
+ }
+ else
+ {
+ if(currentObjPtr2->type == 5)
+ {
+ var2 = 32000;
+ }
+ else
+ {
+ int16 varC;
+
+ getSingleObjectParam(currentObjPtr2->overlay,currentObjPtr2->idx,2,&varC);
+
+ var2 = varC;
+ }
+
+ if(var>var2)
+ {
+ var8 = currentObjPtr2;
+ }
+
+ currentObjPtrPrevious=currentObjPtrPrevious->next;
+ }
+
+ currentObjPtr2 = currentObjPtr2->next;
+ }
+
+ if(match)
+ {
+ objectStruct* temp;
+
+ temp = var8->next;
+
+ var8->next = var40;
+ match->next = temp;
+
+ if(objPtr!=var8)
+ {
+ var40->prev = var8;
+ }
+
+ if(!temp)
+ {
+ temp = match;
+ }
+
+ temp->prev = match;
+ }
+}
+
+int16 Op_7Sub(int ovlIdx,int objIdx,int param2)
+{
+ objDataStruct* ptr;
+// uint16 param;
+ ovlDataStruct* ovlData;
+
+ ptr = getObjectDataFromOverlay(ovlIdx,objIdx);
+
+ if(!ptr)
+ return -11;
+
+ ovlData = overlayTable[ovlIdx].ovlData;
+
+ switch(ptr->var1)
+ {
+ case 0:
+ {
+ globalVars[overlayTable[ovlIdx].field_14 + ptr->var6] = param2;
+ Op_7Sub1(ovlIdx,param2,&objectHead);
+ break;
+ }
+ case 1:
+ {
+ objectParams* destEntry;
+ objectParams* sourceEntry;
+
+ if(ptr->var5+param2 > ovlData->size8)
+ {
+ return 0;
+ }
+
+ destEntry = &ovlData->objData2WorkTable[ptr->var4];
+ sourceEntry = &ovlData->objData2SourceTable[ptr->var5 + param2];
+
+ memcpy(destEntry,sourceEntry,sizeof(objectParams));
+
+ destEntry->var5 = param2;
+
+ Op_7Sub1(ovlIdx,param2,&objectHead);
+ break;
+ }
+ default:
+ {
+ printf("Unsupported param = %d in Op_7Sub\n",ptr->var1);
+ // exit(1);
+ }
+ }
+
+ return 0;
+}
+
+int16 getSingleObjectParam(int16 overlayIdx,int16 param2,int16 param3,int16* returnParam)
+{
+ int var_A = 0;
+ char* ptr3 = NULL;
+ objDataStruct* ptr;
+ ovlDataStruct* ovlData;
+ objectParams* ptr2;
+
+ ptr = getObjectDataFromOverlay(overlayIdx,param2);
+
+ if(!ptr)
+ return -11;
+
+ ovlData = overlayTable[overlayIdx].ovlData;
+
+ switch(ptr->var1)
+ {
+ case 0:
+ case 3:
+ {
+ var_A = globalVars[ptr->var6];
+
+ ptr2 = &ovlData->objData2SourceTable[ptr->var5];
+ break;
+ }
+ case 1:
+ {
+ ptr2 = &ovlData->objData2WorkTable[ptr->var4];
+
+ var_A = ptr2->var5;
+ break;
+ }
+ default:
+ {
+ printf("Unsupported case %d in getSingleObjectParam\n",ptr->var1);
+ exit(1);
+ }
+ }
+
+ switch(param3)
+ {
+ case 0:
+ {
+ *returnParam = ptr2->X;
+ break;
+ }
+ case 1:
+ {
+ *returnParam = ptr2->Y;
+ break;
+ }
+ case 2:
+ {
+ *returnParam = ptr2->baseFileIdx;
+ break;
+ }
+ case 3:
+ {
+ *returnParam = ptr2->var3;
+ break;
+ }
+ case 4:
+ {
+ *returnParam = ptr2->scale;
+ break;
+ }
+ case 5:
+ {
+ *returnParam = var_A;
+ break;
+ }
+ default:
+ {
+ printf("Unsupported case %d in getSingleObjectParam case 1\n",param3);
+ exit(1);
+ }
+ }
+
+ return 0;
+}
+
+
+} // End of namespace Cruise
diff --git a/engines/cruise/object.h b/engines/cruise/object.h
new file mode 100644
index 0000000000..620de44879
--- /dev/null
+++ b/engines/cruise/object.h
@@ -0,0 +1,94 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef _OBJECT_H_
+#define _OBJECT_H_
+
+namespace Cruise {
+
+struct gfxEntryStruct
+{
+ uint8* imagePtr;
+ int imageSize;
+ int fontIndex;
+ int height;
+ int width; // for font: max right border; for sprite: just width
+};
+
+typedef struct gfxEntryStruct gfxEntryStruct;
+
+struct objectStruct
+{
+ struct objectStruct* next;
+ struct objectStruct* prev;
+ int16 idx;
+ int16 type;
+ int16 overlay ;
+ int16 field_A ;
+ int16 field_C ;
+ int16 spriteIdx ;
+ int16 field_10;
+ int16 backgroundPlane;
+ int16 hide;
+ int16 field_16;
+ int16 field_18;
+ int16 field_1A;
+ int16 followObjectOverlayIdx;
+ int16 followObjectIdx;
+ int16 field_20;
+ int16 field_22;
+ int16 nextAnimDelay;
+ int16 field_26;
+ int16 field_28;
+ int16 field_2A;
+ int16 field_2C;
+ int16 currentAnimDelay;
+ int16 field_30;
+ gfxEntryStruct* gfxPtr;
+};
+
+typedef struct objectStruct objectStruct;
+
+struct objectParamsQuery
+{
+ int16 X;
+ int16 Y;
+ int16 baseFileIdx;
+ int16 fileIdx;
+ int16 scale;
+ int16 var5;
+ int16 var6;
+ int16 var7;
+};
+
+typedef struct objectParamsQuery objectParamsQuery;
+
+objectStruct* addObject(int16 overlayIdx,int16 param2,objectStruct* pHead,int16 scriptType,int16 scriptNumber,int16 scriptOverlay, int16 param3, int16 param4);
+objDataStruct* getObjectDataFromOverlay(int ovlIdx,int objIdx);
+int16 getSingleObjectParam(int16 overlayIdx,int16 param2,int16 param3,int16* returnParam);
+int16 getMultipleObjectParam(int16 overlayIdx,int16 objectIdx,objectParamsQuery* returnParam);
+
+} // End of namespace Cruise
+
+#endif \ No newline at end of file
diff --git a/engines/cruise/overlay.cpp b/engines/cruise/overlay.cpp
new file mode 100644
index 0000000000..8cff91674b
--- /dev/null
+++ b/engines/cruise/overlay.cpp
@@ -0,0 +1,772 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cruise/cruise_main.h"
+
+namespace Cruise {
+
+overlayStruct overlayTable[90];
+int numOfLoadedOverlay;
+
+void initOverlayTable(void)
+{
+ int i;
+
+ for(i=0;i<90;i++)
+ {
+ overlayTable[i].overlayName[0] = 0;
+ overlayTable[i].ovlData = NULL;
+ overlayTable[i].alreadyLoaded = 0;
+ overlayTable[i].executeScripts = 0;
+ }
+
+ numOfLoadedOverlay = 1;
+}
+
+int loadOverlay(uint8* scriptName)
+{
+ int newNumberOfScript;
+ bool scriptNotLoadedBefore;
+ int scriptIdx;
+ uint8 fileName[50];
+ int fileIdx;
+ int unpackedSize;
+ char* unpackedBuffer;
+ char* scriptPtr;
+ ovlDataStruct* ovlData;
+
+ printf("Load overlay: %s\n",scriptName);
+
+ newNumberOfScript = numOfLoadedOverlay;
+
+ scriptNotLoadedBefore = false;
+
+ scriptIdx = findOverlayByName((char*)scriptName);
+
+ if(scriptIdx == -4)
+ {
+ scriptIdx = numOfLoadedOverlay;
+
+ newNumberOfScript++;
+
+ scriptNotLoadedBefore = true;
+ }
+
+ if(overlayTable[scriptIdx].alreadyLoaded)
+ {
+ return (scriptIdx);
+ }
+
+ overlayTable[scriptIdx].ovlData = (ovlDataStruct*) mallocAndZero(sizeof(ovlDataStruct));
+
+ if(!overlayTable[scriptIdx].ovlData)
+ return(-2);
+
+ strcpyuint8(overlayTable[scriptIdx].overlayName, scriptName);
+
+ overlayTable[scriptIdx].alreadyLoaded = 1;
+
+ numOfLoadedOverlay = newNumberOfScript;
+
+ overlayTable[scriptIdx].ovlData->scriptNumber = scriptIdx;
+
+ strcpyuint8(fileName,scriptName);
+
+ strcatuint8(fileName,".OVL");
+
+ printf("Attempting to load overlay file %s...\n", fileName);
+
+ fileIdx = findFileInDisks(fileName);
+
+ if(fileIdx<0)
+ {
+ printf("Unable to load overlay %s !\n", scriptName);
+ //releaseScript(scriptName);
+ return(-18);
+ }
+
+ unpackedSize = volumePtrToFileDescriptor[fileIdx].extSize + 2;
+
+ // TODO: here, can unpack in gfx module buffer
+ unpackedBuffer = (char*)mallocAndZero(unpackedSize);
+
+ if(!unpackedBuffer)
+ {
+ return(-2);
+ }
+
+ if(volumePtrToFileDescriptor[fileIdx].size +2 != unpackedSize)
+ {
+ char* tempBuffer;
+ uint16 realUnpackedSize;
+ char* pakedBuffer = (char*) mallocAndZero(volumePtrToFileDescriptor[fileIdx].size +2);
+
+ loadPakedFileToMem(fileIdx,(uint8*)pakedBuffer);
+
+ realUnpackedSize = *(int16*)(pakedBuffer+volumePtrToFileDescriptor[fileIdx].size-2);
+ flipShort(&realUnpackedSize);
+
+ tempBuffer = (char*)mallocAndZero(realUnpackedSize);
+
+ decomp((uint8*)pakedBuffer+volumePtrToFileDescriptor[fileIdx].size-4,(uint8*)unpackedBuffer+realUnpackedSize,realUnpackedSize);
+
+ free(pakedBuffer);
+ }
+ else
+ {
+ loadPakedFileToMem(fileIdx,(uint8*)unpackedBuffer);
+ }
+
+ printf("OVL loading done...\n");
+
+ scriptPtr = unpackedBuffer;
+
+ ovlData = overlayTable[scriptIdx].ovlData;
+
+ memcpy(ovlData,scriptPtr, sizeof(ovlDataStruct));
+
+ ovlData->data3Table = NULL;
+ ovlData->ptr1 = NULL;
+ ovlData->objDataTable = NULL;
+ ovlData->objData2SourceTable = NULL;
+ ovlData->objData2WorkTable = NULL;
+ ovlData->stringTable = NULL;
+ ovlData->exportDataPtr = NULL;
+ ovlData->importDataPtr = NULL;
+ ovlData->linkDataPtr = NULL;
+ ovlData->specialString1 = NULL;
+ ovlData->specialString2 = NULL;
+ ovlData->importNamePtr = NULL;
+ ovlData->exportNamesPtr = NULL;
+ ovlData->data4Ptr = NULL;
+ ovlData->ptr8 = NULL;
+ ovlData->numScripts1 = readB16(scriptPtr+60);
+ ovlData->numScripts2 = readB16(scriptPtr+62);
+ ovlData->numExport = readB16(scriptPtr+64);
+ ovlData->numImport = readB16(scriptPtr+66);
+ ovlData->numLinkData = readB16(scriptPtr+68);
+ ovlData->numObjData = readB16(scriptPtr+70);
+ ovlData->numStrings = readB16(scriptPtr+72);
+ ovlData->size8 = readB16(scriptPtr+74);
+ ovlData->size9 = readB16(scriptPtr+76);
+ ovlData->nameExportSize = readB16(scriptPtr+78);
+ ovlData->exportNamesSize = readB16(scriptPtr+80);
+ ovlData->specialString2Length = readB16(scriptPtr+82);
+ ovlData->sizeOfData4 = readB16(scriptPtr+84);
+ ovlData->size12 = readB16(scriptPtr+86);
+ ovlData->specialString1Length = readB16(scriptPtr+88);
+ ovlData->scriptNumber = readB16(scriptPtr+90);
+
+ scriptPtr += 92;
+
+ if(ovlData->numExport) // export data
+ {
+ int i;
+ ovlData->exportDataPtr = (exportEntryStruct*)mallocAndZero(ovlData->numExport*sizeof(exportEntryStruct));
+
+ if(!ovlData->exportDataPtr)
+ {
+ return(-2);
+ }
+
+ for(i=0;i<ovlData->numExport;i++)
+ {
+ ovlData->exportDataPtr[i].var0 = readB16(scriptPtr);
+ ovlData->exportDataPtr[i].var2 = readB16(scriptPtr+2);
+ ovlData->exportDataPtr[i].var4 = readB16(scriptPtr+4);
+ ovlData->exportDataPtr[i].idx = readB16(scriptPtr+6);
+ ovlData->exportDataPtr[i].offsetToName = readB16(scriptPtr+8);
+
+ scriptPtr+=10;
+ }
+ }
+
+ if(ovlData->exportNamesSize) // export names
+ {
+ ovlData->exportNamesPtr = (uint8*)mallocAndZero(ovlData->exportNamesSize);
+
+ if(!ovlData->exportNamesPtr)
+ {
+ return(-2);
+ }
+
+ memcpy(ovlData->exportNamesPtr, scriptPtr, ovlData->exportNamesSize);
+ scriptPtr += ovlData->exportNamesSize;
+ }
+
+ if(ovlData->numImport) // import data
+ {
+ int i;
+
+ ovlData->importDataPtr = (importDataStruct*)mallocAndZero(ovlData->numImport * sizeof(importDataStruct));
+
+ if(!ovlData->importDataPtr)
+ {
+ return(-2);
+ }
+
+ for(i=0;i<ovlData->numImport;i++)
+ {
+ ovlData->importDataPtr[i].var0 = readB16(scriptPtr);
+ ovlData->importDataPtr[i].var1 = readB16(scriptPtr+2);
+ ovlData->importDataPtr[i].linkType = readB16(scriptPtr+4);
+ ovlData->importDataPtr[i].linkIdx = readB16(scriptPtr+6);
+ ovlData->importDataPtr[i].nameOffset = readB16(scriptPtr+8);
+
+ scriptPtr+=10;
+ }
+ }
+
+ if(ovlData->nameExportSize) // import name
+ {
+ ovlData->importNamePtr = (uint8*)mallocAndZero(ovlData->nameExportSize);
+
+ if(!ovlData->importNamePtr)
+ {
+ return(-2);
+ }
+
+ memcpy(ovlData->importNamePtr, scriptPtr, ovlData->nameExportSize);
+ scriptPtr += ovlData->nameExportSize;
+ }
+
+ if(ovlData->numLinkData) // link data
+ {
+ ASSERT(sizeof(linkDataStruct) == 0x22);
+
+ ovlData->linkDataPtr = (linkDataStruct*)mallocAndZero(ovlData->numLinkData*sizeof(linkDataStruct));
+
+ if(!ovlData->linkDataPtr)
+ {
+ return(-2);
+ }
+
+ memcpy(ovlData->linkDataPtr, scriptPtr, ovlData->numLinkData*sizeof(linkDataStruct));
+ scriptPtr += ovlData->numLinkData*sizeof(linkDataStruct);
+ flipGen(ovlData->linkDataPtr,ovlData->numLinkData*sizeof(linkDataStruct));
+ }
+
+ if(ovlData->numScripts1) // script
+ {
+ ovlData3Struct* tempPtr;
+ int i;
+
+ ovlData->data3Table = (ovlData3Struct*)mallocAndZero(ovlData->numScripts1 * sizeof(ovlData3Struct));
+
+ if(!ovlData->data3Table)
+ {
+/* releaseScript(scriptIdx,scriptName);
+
+ if(freeIsNeeded)
+ {
+ freePtr(unpackedBuffer);
+ } */
+
+ return(-2);
+ }
+
+ memcpy(ovlData->data3Table, scriptPtr, ovlData->numScripts1 * sizeof(ovlData3Struct));
+ scriptPtr += ovlData->numScripts1 * 0x1C;
+
+ flipGen(ovlData->data3Table,ovlData->numScripts1 * sizeof(ovlData3Struct));
+
+ tempPtr = ovlData->data3Table;
+
+ for(i=0;i<ovlData->numScripts1;i++)
+ {
+ uint8* ptr = tempPtr->dataPtr = (uint8*) mallocAndZero(tempPtr->sizeOfData);
+
+ if(!ptr)
+ {
+ /* releaseScript(scriptIdx,scriptName);
+
+ if(freeIsNeeded)
+ {
+ freePtr(unpackedBuffer);
+ } */
+
+ return(-2);
+ }
+
+ memcpy( ptr, scriptPtr, tempPtr->sizeOfData );
+ scriptPtr+= tempPtr->sizeOfData;
+
+ if(tempPtr->offsetToImportData)
+ {
+ flipGen(ptr+tempPtr->offsetToImportData,tempPtr->numImport*10);
+ }
+
+ if(tempPtr->offsetToSubData2)
+ {
+ flipGen(ptr+tempPtr->offsetToImportData,tempPtr->subData2Size*10);
+ }
+
+ tempPtr++;
+ }
+ }
+
+ if(ovlData->numScripts2)
+ {
+ ovlData3Struct* tempPtr;
+ int i;
+
+ ovlData->ptr1 = (uint8*)mallocAndZero(ovlData->numScripts2*0x1C);
+
+ if(!ovlData->ptr1)
+ {
+ return(-2);
+ }
+
+ memcpy(ovlData->ptr1, scriptPtr, ovlData->numScripts2 * 0x1C);
+ scriptPtr += ovlData->numScripts2*0x1C;
+ flipGen(ovlData->ptr1,ovlData->numScripts2*0x1C);
+
+ tempPtr = (ovlData3Struct*)ovlData->ptr1;
+
+ for(i=0;i<ovlData->numScripts2;i++)
+ {
+ uint8* ptr = tempPtr->dataPtr = (uint8*) mallocAndZero(tempPtr->sizeOfData);
+
+ if(!ptr)
+ {
+ /* releaseScript(scriptIdx,scriptName);
+
+ if(freeIsNeeded)
+ {
+ freePtr(unpackedBuffer);
+ } */
+
+ return(-2);
+ }
+
+ memcpy( ptr, scriptPtr, tempPtr->sizeOfData );
+ scriptPtr+= tempPtr->sizeOfData;
+
+ if(tempPtr->offsetToImportData)
+ {
+ flipGen(ptr+tempPtr->offsetToImportData,tempPtr->numImport*10);
+ }
+
+ if(tempPtr->offsetToSubData2)
+ {
+ flipGen(ptr+tempPtr->offsetToImportData,tempPtr->subData2Size*10);
+ }
+
+ tempPtr++;
+ }
+ }
+
+ if(ovlData->size12)
+ {
+ ovlData->ptr8 = (uint8*)mallocAndZero(ovlData->size12);
+
+ if(!ovlData->ptr8)
+ {
+/* releaseScript(scriptIdx,scriptName);
+
+ if(freeIsNeeded)
+ {
+ freePtr(unpackedBuffer);
+ } */
+
+ return(-2);
+ }
+
+ memcpy(ovlData->ptr8, scriptPtr, ovlData->size12);
+ scriptPtr += ovlData->size12;
+ }
+
+ if(ovlData->numObjData)
+ {
+ int i;
+ ovlData->objDataTable = (objDataStruct*)mallocAndZero(ovlData->numObjData*sizeof(objDataStruct));
+
+ if(!ovlData->objDataTable)
+ {
+/* releaseScript(scriptIdx,scriptName);
+
+ if(freeIsNeeded)
+ {
+ freePtr(unpackedBuffer);
+ } */
+
+ return(-2);
+ }
+
+ for(i=0;i<ovlData->numObjData;i++)
+ {
+ ovlData->objDataTable[i].var0 = *(int16*)scriptPtr;
+ scriptPtr+=2;
+ flipShort(&ovlData->objDataTable[i].var0);
+
+ ovlData->objDataTable[i].var1 = *(int16*)scriptPtr;
+ scriptPtr+=2;
+ flipShort(&ovlData->objDataTable[i].var1);
+
+ ovlData->objDataTable[i].var2 = *(int16*)scriptPtr;
+ scriptPtr+=2;
+ flipShort(&ovlData->objDataTable[i].var2);
+
+ ovlData->objDataTable[i].var3 = *(int16*)scriptPtr;
+ scriptPtr+=2;
+ flipShort(&ovlData->objDataTable[i].var3);
+
+ ovlData->objDataTable[i].var4 = *(int16*)scriptPtr;
+ scriptPtr+=2;
+ flipShort(&ovlData->objDataTable[i].var4);
+
+ ovlData->objDataTable[i].var5 = *(int16*)scriptPtr;
+ scriptPtr+=2;
+ flipShort(&ovlData->objDataTable[i].var5);
+
+ ovlData->objDataTable[i].var6 = *(int16*)scriptPtr;
+ scriptPtr+=2;
+ flipShort(&ovlData->objDataTable[i].var6);
+ }
+
+ if(scriptNotLoadedBefore)
+ {
+ int var1;
+ int var2;
+
+ overlayTable[scriptIdx].field_14 = (char)setup1;
+
+ var1 = loadScriptSub1(scriptIdx,3);
+ var2 = loadScriptSub1(scriptIdx,0);
+
+ setup1 = var1 + var2;
+ }
+ }
+
+ if(ovlData->size9)
+ {
+ ovlData->objData2WorkTable = (objectParams*)mallocAndZero(ovlData->size9 * sizeof(objectParams));
+ memset(ovlData->objData2WorkTable, 0, ovlData->size9 * sizeof(objectParams));
+
+ if(!ovlData->objData2WorkTable)
+ {
+/* releaseScript(scriptIdx,scriptName);
+
+ if(freeIsNeeded)
+ {
+ freePtr(unpackedBuffer);
+ } */
+
+ return(-2);
+ }
+ }
+
+ if(ovlData->size8)
+ {
+ ovlData->objData2SourceTable = (objectParams*)mallocAndZero(ovlData->size8 * sizeof(objectParams));
+
+ if(!ovlData->objData2SourceTable)
+ {
+/* releaseScript(scriptIdx,scriptName);
+
+ if(freeIsNeeded)
+ {
+ freePtr(unpackedBuffer);
+ } */
+
+ return(-2);
+ }
+
+ memcpy(ovlData->objData2SourceTable, scriptPtr, ovlData->size8*12); // TODO: made read item by item
+ scriptPtr += ovlData->size8*12;
+ flipGen(ovlData->objData2SourceTable,ovlData->size8*12);
+ }
+
+ if(ovlData->numStrings)
+ {
+ int i;
+
+ ovlData->stringTable = (stringEntryStruct*)mallocAndZero(ovlData->numStrings*sizeof(stringEntryStruct));
+
+ for(i=0;i<ovlData->numStrings;i++)
+ {
+ ovlData->stringTable[i].idx = *(int16*)scriptPtr;
+ flipShort(&ovlData->stringTable[i].idx);
+ scriptPtr+=2;
+ }
+ }
+
+/* if(freeIsNeeded)
+ {
+ freePtr(unpackedBuffer);
+ } */
+
+ if(ovlData->sizeOfData4)
+ {
+ ovlData->data4Ptr = (uint8*)mallocAndZero(ovlData->sizeOfData4);
+ memset(ovlData->data4Ptr,0,ovlData->sizeOfData4);
+
+ if(!ovlData->data4Ptr)
+ {
+ //releaseScript(scriptIdx,scriptName);
+ return(-2);
+ }
+ }
+
+ if(ovlData->specialString1Length /*|| ovlData->specialString2Length*/ || ovlData->stringTable)
+ {
+ int i;
+ int unpackedSize;
+ int fileIdx;
+ uint8 fileName[50];
+ char* unpackedBuffer;
+
+ strcpyuint8(fileName,scriptName);
+
+ strcatuint8(fileName,".FR");
+
+ fileIdx = findFileInDisks(fileName);
+
+ if(fileIdx<0)
+ {
+ //releaseScript(scriptName);
+ return(-18);
+ }
+
+ unpackedSize = volumePtrToFileDescriptor[fileIdx].extSize + 2;
+
+ // TODO: here, can unpack in gfx module buffer
+ unpackedBuffer = (char*)mallocAndZero(unpackedSize);
+
+ if(!unpackedBuffer)
+ {
+ return(-2);
+ }
+
+ if(volumePtrToFileDescriptor[fileIdx].size +2 != unpackedSize)
+ {
+ short int realUnpackedSize;
+ char* pakedBuffer = (char*) mallocAndZero(volumePtrToFileDescriptor[fileIdx].size +2);
+
+ loadPakedFileToMem(fileIdx,(uint8*)pakedBuffer);
+
+ realUnpackedSize = *(int16*)(pakedBuffer+volumePtrToFileDescriptor[fileIdx].size-2);
+ flipShort(&realUnpackedSize);
+
+ decomp((uint8*)pakedBuffer+volumePtrToFileDescriptor[fileIdx].size-4,(uint8*)unpackedBuffer+realUnpackedSize,realUnpackedSize);
+
+ free(pakedBuffer);
+ }
+ else
+ {
+ loadPakedFileToMem(fileIdx,(uint8*)unpackedBuffer);
+ }
+
+ scriptPtr = unpackedBuffer;
+
+ memcpy(&ovlData->specialString1Length,scriptPtr,2);
+ scriptPtr+=2;
+ flipShort(&ovlData->specialString1Length); // recheck if needed
+
+ if(ovlData->specialString1Length)
+ {
+ ovlData->specialString1 = (uint8*)mallocAndZero(ovlData->specialString1Length);
+
+ if(!ovlData->specialString1)
+ {
+ /* releaseScript(scriptIdx,scriptName);
+
+ if(freeIsNeeded)
+ {
+ freePtr(unpackedBuffer);
+ } */
+
+ return(-2);
+ }
+
+ memcpy(ovlData->specialString1, scriptPtr, ovlData->specialString1Length);
+ scriptPtr += ovlData->specialString1Length;
+ }
+
+ memcpy(&ovlData->specialString2Length,scriptPtr,2);
+ scriptPtr+=2;
+ flipShort(&ovlData->specialString2Length); // recheck if needed
+
+ if(ovlData->specialString2Length)
+ {
+ ovlData->specialString2 = (uint8*)mallocAndZero(ovlData->specialString2Length);
+
+ if(!ovlData->specialString2)
+ {
+ /* releaseScript(scriptIdx,scriptName);
+
+ if(freeIsNeeded)
+ {
+ freePtr(unpackedBuffer);
+ } */
+
+ return(-2);
+ }
+
+ memcpy(ovlData->specialString2, scriptPtr, ovlData->specialString2Length);
+ scriptPtr += ovlData->specialString2Length;
+ }
+
+ for(i=0;i<ovlData->numStrings;i++)
+ {
+ ovlData->stringTable[i].length = *(int16*)scriptPtr;
+ scriptPtr +=2;
+ flipShort(&ovlData->stringTable[i].length);
+
+ if(ovlData->stringTable[i].length)
+ {
+ ovlData->stringTable[i].string = (char*)mallocAndZero(ovlData->stringTable[i].length);
+
+ if(!ovlData->stringTable[i].string)
+ {
+ /* releaseScript(scriptIdx,scriptName);
+
+ if(freeIsNeeded)
+ {
+ freePtr(unpackedBuffer);
+ } */
+
+ return(-2);
+ }
+
+ memcpy(ovlData->stringTable[i].string,scriptPtr,ovlData->stringTable[i].length);
+ scriptPtr += ovlData->stringTable[i].length;
+ }
+ }
+ }
+
+#ifdef DUMP_SCRIPT
+ {
+ int i;
+ for(i=0;i<ovlData->numScripts1;i++)
+ {
+ dumpScript(scriptName,ovlData,i);
+ }
+ }
+#endif
+#ifdef DUMP_OBJECT
+ {
+ int i;
+ FILE* fHandle;
+ char nameBundle[100];
+ sprintf(nameBundle, "%s-objs.txt",scriptName);
+
+ fHandle = fopen(nameBundle, "w+");
+ ASSERT(fHandle);
+
+ for(i=0;i<ovlData->numLinkData;i++)
+ {
+ linkDataStruct* var_34;
+ var_34 = &ovlData->linkDataPtr[i];
+
+ if(ovlData->specialString2)
+ {
+ fprintf(fHandle,"----- object %02d -----\n", i);
+ if(var_34->stringNameOffset != 0xFFFF)
+ {
+ fprintf(fHandle,"name: %s\n",getObjectName(var_34->stringNameOffset, ovlData->specialString2));
+ }
+ }
+ }
+
+ fclose(fHandle);
+ }
+#endif
+
+ return(scriptIdx);
+}
+
+int releaseOverlay(const char* name)
+{
+ int overlayIdx;
+ ovlDataStruct* ovlDataPtr;
+
+ overlayIdx = findOverlayByName(name);
+
+ if(overlayIdx == -4)
+ return -4;
+
+ if(overlayTable[overlayIdx].alreadyLoaded == 0)
+ return -4;
+
+ overlayTable[overlayIdx].alreadyLoaded = 0;
+
+ ovlDataPtr = overlayTable[overlayIdx].ovlData;
+
+ if(!ovlDataPtr)
+ return -4;
+/*
+ if(overlayTable[overlayIdx].var1E)
+ {
+ free(overlayTable[overlayIdx].var1E);
+ overlayTable[overlayIdx].var1E = NULL;
+ }
+
+ if(overlayTable[overlayIdx].var16)
+ {
+ free(overlayTable[overlayIdx].var16);
+ overlayTable[overlayIdx].var16 = NULL;
+ } */
+
+ removeScript(overlayIdx,-1,&scriptHandle2);
+ removeScript(overlayIdx,-1,&scriptHandle2);
+
+ removeScript(overlayIdx,-1,&scriptHandle1);
+ removeScript(overlayIdx,-1,&scriptHandle1);
+
+ printf("releaseOverlay: finish !\n");
+
+ return 0;
+}
+
+int32 findOverlayByName2(uint8* name)
+{
+ int i;
+
+ for(i=1;i<numOfLoadedOverlay;i++)
+ {
+ if(!strcmpuint8(overlayTable[i].overlayName,name))
+ return(i);
+ }
+
+ return(-4);
+}
+
+int findOverlayByName(const char* overlayName)
+{
+ int i;
+
+ for(i=1;i<numOfLoadedOverlay;i++)
+ {
+ if(!strcmp(overlayTable[i].overlayName,overlayName))
+ {
+ return(i);
+ }
+ }
+
+ return(-4);
+}
+
+
+} // End of namespace Cruise
diff --git a/engines/cruise/overlay.h b/engines/cruise/overlay.h
new file mode 100644
index 0000000000..f5e3ec4fdc
--- /dev/null
+++ b/engines/cruise/overlay.h
@@ -0,0 +1,217 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef _OVERLAY_H_
+#define _OVERLAY_H_
+
+namespace Cruise {
+
+struct importScriptStruct
+{
+ uint16 var0;
+ uint16 var1;
+ uint16 type;
+ uint16 offset;
+ uint16 offsetToName;
+};
+
+typedef struct importScriptStruct importScriptStruct;
+
+struct exportEntryStruct
+{
+ uint16 var0;
+ uint16 var2;
+ uint16 var4;
+ uint16 idx;
+ uint16 offsetToName;
+};
+
+typedef struct exportEntryStruct exportEntryStruct;
+
+struct ovlData3Struct
+{
+ uint8* dataPtr; //0
+ short int sizeOfData; //4
+ short int offsetToSubData3; //6
+ short int offsetToImportData; //8
+ short int offsetToSubData2;
+ short int offsetToImportName;
+ short int offsetToSubData5;
+ short int sysKey;
+ short int var12;
+ short int numImport;
+ short int subData2Size;
+ short int var18;
+ short int var1A;
+};
+
+typedef struct ovlData3Struct ovlData3Struct;
+
+struct stringEntryStruct
+{
+ char* string;
+ short int length;
+ short int idx;
+};
+
+typedef struct stringEntryStruct stringEntryStruct;
+
+struct linkDataStruct
+{
+ uint16 field_0;
+ uint16 field_2;
+ uint16 field_4;
+ uint16 varIdx;
+ uint16 varNameOffset;
+ uint16 stringIdx;
+ uint16 stringNameOffset;
+ uint16 procIdx;
+ uint16 procNameOffset;
+
+ int16 field_12;
+ int16 field_14;
+ int16 field_16;
+ int16 field_18;
+ int16 field_1A;
+ int16 field_1C;
+ int16 field_1E;
+ int16 field_20;
+};
+
+typedef struct linkDataStruct linkDataStruct;
+
+struct importDataStruct
+{
+ uint16 var0; // 0
+ uint16 var1; // 2
+ uint16 linkType; // 4
+ uint16 linkIdx; // 6
+ uint16 nameOffset;
+};
+
+typedef struct importDataStruct importDataStruct;
+
+struct objDataStruct
+{
+ int16 var0;
+ int16 var1;
+ int16 var2;
+ int16 var3;
+ int16 var4;
+ int16 var5;
+ int16 var6;
+};
+
+typedef struct objDataStruct objDataStruct;
+
+struct objectParams
+{
+ int16 X;
+ int16 Y;
+ int16 baseFileIdx;
+ int16 var3;
+ int16 scale;
+ int16 var5;
+};
+
+typedef struct objectParams objectParams;
+
+struct ovlDataStruct
+{
+ ovlData3Struct* data3Table;
+ uint8* ptr1;
+ objDataStruct* objDataTable;
+ objectParams* objData2SourceTable;
+ objectParams* objData2WorkTable;
+ stringEntryStruct* stringTable;
+ exportEntryStruct* exportDataPtr;
+ importDataStruct* importDataPtr;
+ linkDataStruct* linkDataPtr;
+ uint8* specialString1;
+ uint8* specialString2;
+ uint8* importNamePtr;
+ uint8* exportNamesPtr;
+ uint8* data4Ptr;
+ uint8* ptr8;
+ unsigned short int numScripts1;
+ unsigned short int numScripts2;
+ unsigned short int numExport;
+ unsigned short int numImport;
+ unsigned short int numLinkData;
+ unsigned short int numObjData;
+ unsigned short int numStrings;
+ unsigned short int size8;
+ unsigned short int size9;
+ unsigned short int nameExportSize;
+ unsigned short int exportNamesSize;
+ unsigned short int specialString2Length;
+ unsigned short int sizeOfData4;
+ unsigned short int size12;
+ unsigned short int specialString1Length;
+ unsigned short int scriptNumber;
+};
+
+typedef struct ovlDataStruct ovlDataStruct;
+
+struct overlayStruct
+{
+ char overlayName[14];
+ ovlDataStruct* ovlData;
+ short int alreadyLoaded;
+ char field_14;
+ char field_15;
+ char field_16;
+ char field_17;
+ char field_18;
+ char field_19;
+ char field_1A;
+ char field_1B;
+ char field_1C;
+ char field_1D;
+ char field_1E;
+ char field_1F;
+ char field_20;
+ char field_21;
+ char field_22;
+ char field_23;
+ char field_24;
+ char field_25;
+ short int executeScripts;
+};
+
+typedef struct overlayStruct overlayStruct;
+
+extern overlayStruct overlayTable[90];
+extern int numOfLoadedOverlay;
+
+void initOverlayTable(void);
+int loadOverlay(uint8* scriptName);
+int32 findOverlayByName2(uint8* name);
+int findOverlayByName(const char* overlayName);
+int releaseOverlay(const char* name);
+
+
+} // End of namespace Cruise
+
+#endif
diff --git a/engines/cruise/perso.cpp b/engines/cruise/perso.cpp
new file mode 100644
index 0000000000..5bc6c783d4
--- /dev/null
+++ b/engines/cruise/perso.cpp
@@ -0,0 +1,260 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cruise/cruise_main.h"
+
+namespace Cruise {
+
+persoStruct* persoTable[10];
+
+int16 computedVar14;
+
+void freePerso(int persoIdx)
+{
+ if(persoTable[persoIdx])
+ {
+ free(persoTable[persoIdx]);
+ persoTable[persoIdx] = NULL;
+ }
+}
+
+void freeAllPerso(void)
+{
+ int i;
+
+ for(i=0;i<10;i++)
+ {
+ freePerso(i);
+ }
+
+ if(polyStruct)
+ {
+ free(polyStruct);
+ }
+
+ ctpVar17 = NULL;
+ polyStruct = NULL;
+
+ strcpy((char*)currentCtpName, "");
+}
+
+int pathVar0;
+
+unsigned int inc_droite2,inc_jo;
+
+int direction( int x1, int y1, int x2, int y2, int inc_jo1, int inc_jo2 )
+{
+ int h, v, h1, v1;
+
+ h1 = x1-x2; h = abs(h1);
+ v1 = y1-y2; v = abs(v1);
+
+ if ( v > h )
+ {
+ if ( h > 30 ) inc_jo = inc_jo1-inc_jo2;
+ else inc_jo = inc_jo2;
+
+ if ( v1 < 0 ) return ( 2 );
+ else return ( 0 );
+ }
+ else
+ {
+ inc_jo = inc_jo1;
+
+ if ( h1 < 0 ) return ( 1 );
+ else return ( 3 );
+ }
+}
+
+void cor_droite(int x1,int y1,int x2,int y2, int16 cor_joueur[400][2])
+{
+ int16* di = (int16*)cor_joueur;
+ int dx;
+ int dy;
+
+ int mD0;
+ int mD1;
+
+ int mA0;
+ int mA1;
+
+ int bp;
+ int cx;
+ int si;
+
+ int ax;
+ int bx;
+
+ di[0] = x1;
+ di[1] = y1;
+ di+=2;
+
+ dx = x2-x1;
+ dy = y2-y1;
+
+ mD0 = mD1 = 1;
+
+ if(dx<0)
+ {
+ dx = -dx;
+ mD0 = -1;
+ }
+
+ if(dy<0)
+ {
+ dy = -dy;
+ mD1 = -1;
+ }
+
+ if(dx<dy)
+ {
+ mA0 = 0;
+ bp = dx;
+ cx = dy;
+
+ mA1 = mD1;
+ }
+ else
+ {
+ mA1 = 0;
+ bp = dy;
+ cx = dx;
+
+ mA0 = mD0;
+ }
+
+ bp=bp*2;
+ dx=bp-cx;
+ si=dx-cx;
+
+ ax = x1;
+ bx = y1;
+
+ while(--cx)
+ {
+ if(dx>0)
+ {
+ ax+=mD0;
+ bx+=mD1;
+ dx+=si;
+ }
+ else
+ {
+ ax+=mA0;
+ bx+=mA1;
+ dx+=bp;
+ }
+
+ di[0] = ax;
+ di[1] = bx;
+ di+=2;
+ }
+
+ flag_obstacle = 0;
+ inc_droite2 = (di-(int16*)cor_joueur)/2;
+}
+
+void processActorWalk(int16 resx_y[4], int16* inc_droite, int16* inc_droite0, int16* inc_chemin, int16 cor_joueur[400][2], int16 solution0[NUM_NODES+3][2], int16* inc_jo1, int16* inc_jo2, int16* dir_perso, int16* inc_jo0, int16 num)
+{
+ int x1, x2, y1, y2;
+ int i, u;
+
+ u = 0;
+ inc_jo = *inc_jo0;
+
+ i = *inc_chemin;
+
+ if ( ! *inc_droite )
+ {
+ x1 = solution0[i][0];
+ y1 = solution0[i][1];
+ i++;
+ if ( solution0[i][0] != -1 )
+ {
+ do
+ {
+ if (solution0[i][0]!=-2)
+ {
+ x2 = solution0[i][0];
+ y2 = solution0[i][1];
+ if ( (x1==x2) && (y1==y2))
+ {
+ resx_y[0]=-1;
+ resx_y[1]=-1;
+ freePerso(num);
+
+ return;
+ }
+ cor_droite(x1,y1,x2,y2,cor_joueur);
+ *inc_droite0=inc_droite2;
+ *dir_perso=resx_y[2]=direction(x1,y1,x2,y2,*inc_jo1,*inc_jo2);
+ *inc_jo0=inc_jo;
+ u=1;
+ }
+ else i++;
+
+ } while ( solution0[i][0] !=-1 && !u );
+ }
+ if ( !u )
+ {
+ resx_y[0]=-1;
+ resx_y[1]=-1;
+ freePerso(num);
+
+ return;
+ }
+ *inc_chemin=i;
+ }
+
+ resx_y[0]=cor_joueur[*inc_droite][0];
+ resx_y[1]=cor_joueur[*inc_droite][1];
+ resx_y[2]=*dir_perso;
+ resx_y[3]=subOp22(resx_y[1]);
+
+ getPixel(resx_y[0],resx_y[1]);
+ resx_y[4]=computedVar14;
+
+ u=subOp23(resx_y[3],inc_jo);
+ if (!u) u=1;
+ *inc_droite+=u;
+
+ if ((*inc_droite)>=(*inc_droite0))
+ {
+ *inc_droite=0;
+ resx_y[0]=solution0[*inc_chemin][0];
+ resx_y[1]=solution0[*inc_chemin][1];
+ }
+
+}
+
+void affiche_chemin(int16 persoIdx, int16* returnVar)
+{
+ persoStruct* pPerso = persoTable[persoIdx];
+
+ ASSERT(pPerso);
+
+ processActorWalk(returnVar, &pPerso->inc_droite, &pPerso->inc_droite0, &pPerso->inc_chemin, pPerso->coordinates, pPerso->solution, &pPerso->inc_jo1, &pPerso->inc_jo2, &pPerso->dir_perso, &pPerso->inc_jo0, persoIdx);
+}
+
+} // End of namespace Cruise
diff --git a/engines/cruise/perso.h b/engines/cruise/perso.h
new file mode 100644
index 0000000000..9d316e17a9
--- /dev/null
+++ b/engines/cruise/perso.h
@@ -0,0 +1,56 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef _PERSO_H_
+#define _PERSO_H_
+
+namespace Cruise {
+
+#define NUM_NODES 20
+
+struct persoStruct
+{
+ int16 inc_droite; // 2
+ int16 inc_droite0; // 2
+ int16 inc_chemin; // 2
+ int16 coordinates[400][2]; // 1600
+ int16 solution[NUM_NODES+3][2]; //((20+3)*2*2)
+ int16 inc_jo1; // 2
+ int16 inc_jo2; // 2
+ int16 dir_perso; // 2
+ int16 inc_jo0; // 2
+};
+
+typedef struct persoStruct persoStruct;
+
+extern persoStruct* persoTable[10];
+extern int16 computedVar14;
+
+void freePerso(int persoIdx);
+void freeAllPerso(void);
+void affiche_chemin(int16 persoIdx, int16* returnVar);
+
+} // End of namespace Cruise
+
+#endif \ No newline at end of file
diff --git a/engines/cruise/polys.cpp b/engines/cruise/polys.cpp
new file mode 100644
index 0000000000..664b2dc004
--- /dev/null
+++ b/engines/cruise/polys.cpp
@@ -0,0 +1,323 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cruise/cruise_main.h"
+
+namespace Cruise {
+
+#include <stdlib.h>
+#include <math.h>
+
+typedef char ColorP;
+
+#define SCREENHEIGHT 200
+#define MAXPTS 10
+#define putdot(x,y) {if ((y >= 0) && (y < SCREENHEIGHT)) dots[y][counters[y]++] = x;}
+#define SWAP(x,y) {int temp = x; x = y; y = temp;}
+
+int MAX(int x, int y) {if(x>y){return x;}else{return y;}}
+int MIN(int x, int y) {if(x<y){return x;}else{return y;}}
+
+void hline(int x1, int x2, int y, char c) {
+ for (; x1 <= x2; x1++) {
+ pixel(x1, y, c);
+ }
+}
+
+void vline(int x, int y1, int y2, char c) {
+ for (; y1 <= y2; y1++) {
+ pixel(x, y1, c);
+ }
+}
+
+void bsubline_1(int x1, int y1, int x2, int y2, char c) {
+ int x, y, ddx, ddy, e;
+ ddx = abs(x2 - x1);
+ ddy = abs(y2 - y1) << 1;
+ e = ddx - ddy;
+ ddx <<= 1;
+
+ if (x1 > x2) {
+ SWAP(x1, x2);
+ SWAP(y1, y2);
+ }
+
+ for (x = x1, y = y1; x <= x2; x++) {
+
+ pixel(x, y, c);
+ if (e < 0) {
+ y++;
+ e += ddx - ddy;
+ } else {
+ e -= ddy;
+ }
+ }
+
+}
+void bsubline_2(int x1, int y1, int x2, int y2, char c) {
+
+ int x, y, ddx, ddy, e;
+ ddx = abs(x2 - x1) << 1;
+ ddy = abs(y2 - y1);
+ e = ddy - ddx;
+ ddy <<= 1;
+
+ if (y1 > y2) {
+ SWAP(x1, x2);
+ SWAP(y1, y2);
+ }
+
+
+ for (y = y1, x = x1; y <= y2; y++) {
+
+ pixel(x, y, c);
+ if (e < 0) {
+ x++;
+ e += ddy - ddx;
+ } else {
+ e -= ddx;
+ }
+ }
+
+}
+
+void bsubline_3(int x1, int y1, int x2, int y2, char c) {
+
+ int x, y, ddx, ddy, e;
+
+ ddx = abs(x1 - x2) << 1;
+ ddy = abs(y2 - y1);
+ e = ddy - ddx;
+ ddy <<= 1;
+
+ if (y1 > y2) {
+ SWAP(x1, x2);
+ SWAP(y1, y2);
+ }
+
+
+ for (y = y1, x = x1; y <= y2; y++) {
+
+ pixel(x, y, c);
+ if (e < 0) {
+ x--;
+ e += ddy - ddx;
+ } else {
+ e -= ddx;
+ }
+ }
+
+}
+
+void bsubline_4(int x1, int y1, int x2, int y2, char c) {
+
+ int x, y, ddx, ddy, e;
+
+ ddy = abs(y2 - y1) << 1;
+ ddx = abs(x1 - x2);
+ e = ddx - ddy;
+ ddx <<= 1;
+
+ if (x1 > x2) {
+ SWAP(x1, x2);
+ SWAP(y1, y2);
+ }
+
+ for (x = x1, y = y1; x <= x2; x++) {
+
+ pixel(x, y, c);
+ if (e < 0) {
+ y--;
+ e += ddx - ddy;
+ } else {
+ e -= ddy;
+ }
+ }
+}
+
+void line(int x1, int y1, int x2, int y2, char c) {
+
+ float k;
+
+ if ((x1 == x2) && (y1 == y2)) {
+ pixel(x1, y1, c);
+ return;
+ }
+
+ if (x1 == x2) {
+ vline(x1, MIN(y1, y2), MAX(y1, y2), c);
+ return;
+ }
+
+ if (y1 == y2) {
+ hline(MIN(x1, x2), MAX(x1, x2), y1, c);
+ return;
+ }
+
+ k = (float)(y2 - y1) / (float)(x2 - x1);
+
+ if ((k >= 0) && (k <= 1)) {
+ bsubline_1(x1, y1, x2, y2, c);
+ } else if (k > 1) {
+ bsubline_2(x1, y1, x2, y2, c);
+ } else if ((k < 0) && (k >= -1)) {
+ bsubline_4(x1, y1, x2, y2, c);
+ } else {
+ bsubline_3(x1, y1, x2, y2, c);
+ }
+}
+
+void fillpoly(short int* datas, int lineCount, ColorP color)
+{
+ static int dots[SCREENHEIGHT][MAXPTS];
+ static int counters[SCREENHEIGHT];
+ short int x1, y1, x2, y2;
+ int i, j, k, dir = -2;
+ double step, curx;
+
+ switch (lineCount)
+ {
+ case 0: // do nothing
+ return;
+ case 1: // draw pixel
+ pixel(datas[0], datas[1], color);
+ return;
+ case 2: // draw line
+ line(datas[0], datas[1], datas[2], datas[3], color);
+ return;
+ default: // go on and draw polygon
+ break;
+ }
+
+ // Reinit array counters
+
+ for (i = 0; i < SCREENHEIGHT; i++)
+ {
+ counters[i] = 0;
+ }
+ // Drawing lines
+
+ x2 = datas[lineCount * 2 - 2];
+ y2 = datas[lineCount * 2 - 1];
+
+ for (i = 0; i < lineCount; i++) {
+ x1 = x2;
+ y1 = y2;
+ x2 = datas[i * 2];
+ y2 = datas[i * 2 + 1];
+
+ // line(x1, y1, x2, y2, color);
+ // continue;
+
+ if (y1 == y2)
+ {
+ // printf("Horizontal line. x1: %i, y1: %i, x2: %i, y2: %i\n", x1, y1, x2, y2);
+ if (dir)
+ {
+ putdot(x1, y1);
+ dir = 0;
+ }
+ }
+ else
+ {
+ step = (double) (x2 - x1) / (y2 - y1);
+
+ // printf("x1: %i, y1 = %i, x2 = %i, y2 = %i, step: %f\n", x1, y1, x2, y2, step);
+
+ curx = x1;
+
+ if (y1 < y2) {
+ for (j = y1; j < y2; j++, curx += step) {
+ // printf("j = %i, curx = %f\n", j, curx);
+ putdot((int)(curx + 0.5), j);
+ }
+ if (dir == -1) {
+ // printf("Adding extra (%i, %i)\n", x1, y1);
+ putdot(x1, y1);
+ }
+ dir = 1;
+ } else {
+ for (j = y1; j > y2; j--, curx -= step) {
+ // printf("j = %i, curx = %f\n", j, curx);
+ putdot((int)(curx + 0.5), j);
+ }
+ if (dir == 1) {
+ // printf("Adding extra (%i, %i)\n", x1, y1);
+ putdot(x1, y1);
+ }
+ dir = -1;
+ }
+ }
+ }
+
+ x1 = x2;
+ y1 = y2;
+ x2 = datas[0];
+ y2 = datas[1];
+
+ if (((y1 < y2) && (dir == -1)) || ((y1 > y2) && (dir == 1)) || ((y1 == y2) && (dir == 0))) {
+ // printf("Adding final extra (%i, %i)\n", x1, y1);
+ putdot(x1, y1);
+ }
+
+ // NOTE: all counters should be even now. If not, this is a bad (color) thing :-P
+
+ // Sorting datas
+
+ for (i = 0; i < SCREENHEIGHT; i++) {
+ // Very bad sorting... but arrays are very small (0, 2 or 4), so it's no quite use...
+ for (j = 0; j < (counters[i] - 1); j++) {
+ for (k = 0; k < (counters[i] - 1); k++) {
+ if (dots[i][k] > dots[i][k + 1])
+ {
+ int temp;
+ temp = dots[i][k];
+ dots[i][k] = dots[i][k + 1];
+ dots[i][k + 1] = temp;
+ }
+ }
+ }
+ }
+
+ // Drawing.
+
+ for (i = 0; i < SCREENHEIGHT; i++) {
+ if (counters[i]) {
+ // printf("%i dots on line %i\n", counters[i], i);
+ for (j = 0; j < counters[i] - 1; j += 2) {
+ // printf("Drawing line (%i, %i)-%i\n", dots[i][j], dots[i][j + 1], i);
+ hline(dots[i][j], dots[i][j + 1], i, color);
+#ifdef DEBUGGING_POLYS
+ if ((!dots[i][j]) || !(dots[i][j + 1])) {
+ printf("fillpoly: BLARGH!\n");
+ exit(-1);
+ }
+#endif
+ }
+ }
+ }
+}
+
+} // End of namespace Cruise
+
diff --git a/engines/cruise/polys.h b/engines/cruise/polys.h
new file mode 100644
index 0000000000..902085fd45
--- /dev/null
+++ b/engines/cruise/polys.h
@@ -0,0 +1,32 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+namespace Cruise {
+
+typedef char ColorP;
+
+void fillpoly(short int * datas, int n, ColorP c);
+void line(int x1, int y1, int x2, int y2, ColorP color);
+
+} // End of namespace Cruise
diff --git a/engines/cruise/script.cpp b/engines/cruise/script.cpp
new file mode 100644
index 0000000000..dcb5f3812b
--- /dev/null
+++ b/engines/cruise/script.cpp
@@ -0,0 +1,861 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cruise/cruise_main.h"
+
+namespace Cruise {
+
+scriptInstanceStruct scriptHandle1;
+scriptInstanceStruct scriptHandle2;
+
+scriptInstanceStruct* currentScriptPtr;
+
+
+uint8 getByteFromScript(void)
+{
+ uint8 var = currentData3DataPtr[currentScriptPtr->var4];
+
+ currentScriptPtr->var4 = currentScriptPtr->var4+1;
+
+ return(var);
+}
+
+short int getShortFromScript(void)
+{
+ short int var = *(int16*)(currentData3DataPtr+currentScriptPtr->var4);
+
+ currentScriptPtr->var4 = currentScriptPtr->var4+2;
+
+ flipShort(&var);
+
+ return(var);
+}
+
+int32 opcodeType0(void) // load opcode
+{
+ switch(currentScriptOpcodeType)
+ {
+ case 0:
+ {
+ pushVar(getShortFromScript());
+ return(0);
+ }
+ case 1:
+ {
+ uint8* ptr;
+ int byte1 = getByteFromScript();
+ int byte2 = getByteFromScript();
+ short int short1 = getShortFromScript();
+
+ int var_E = byte1 & 7;
+
+ if(!var_E)
+ {
+ return(-10);
+ }
+
+ if(!byte2)
+ {
+ ptr = scriptDataPtrTable[var_E] + short1;
+ }
+ else // TODO:
+ {
+ if(!overlayTable[byte2].alreadyLoaded)
+ {
+ return(-7);
+ }
+
+ if(!overlayTable[byte2].ovlData)
+ {
+ return(-4);
+ }
+
+ if(var_E == 5)
+ {
+ ptr = overlayTable[byte2].ovlData->data4Ptr + short1;
+ }
+ else
+ {
+ assert(0);
+ }
+ }
+
+ if(((byte1 & 0x18)>>3)==1)
+ {
+ pushVar(loadShort(ptr));
+ return(0);
+ }
+ else
+ if(((byte1 & 0x18)>>3)==2)
+ {
+ pushVar(*ptr);
+ return(0);
+ }
+ else
+ {
+ printf("Unsupported code in opcodeType0 case 1!\n");
+ exit(1);
+ }
+
+ return(0);
+ }
+ case 2:
+ {
+ int16 var_16;
+ int di = getByteFromScript();
+ int si = getByteFromScript();
+ int var_2 = getShortFromScript();
+
+ if(!si)
+ {
+ si = currentScriptPtr->overlayNumber;
+ }
+
+ if(getSingleObjectParam(si, var_2, di, &var_16))
+ {
+ return -10;
+ }
+
+ pushVar(var_16);
+ return(0);
+
+ break;
+ }
+ case 5:
+ {
+ int byte1 = getByteFromScript();
+ int byte2 = getByteFromScript();
+ short int short1 = getShortFromScript();
+
+ short int var_12 = short1;
+ // short int var_10 = saveOpcodeVar;
+
+ int var_E = byte1 & 7;
+
+ uint8* ptr;
+
+ if(!var_E)
+ {
+ return(-10);
+ }
+
+ if(!byte2)
+ {
+ ptr = scriptDataPtrTable[var_E] + var_12;
+ }
+ else // TODO:
+ {
+ if(!overlayTable[byte2].alreadyLoaded)
+ {
+ return(-7);
+ }
+
+ if(!overlayTable[byte2].ovlData)
+ {
+ return(-4);
+ }
+
+ if(var_E == 5)
+ {
+ ptr = overlayTable[byte2].ovlData->data4Ptr + var_12;
+ }
+ else
+ {
+ assert(0);
+ }
+ }
+
+ if(((byte1 & 0x18)>>3)==1)
+ {
+ pushVar(loadShort(ptr+saveOpcodeVar*2)); // TODO: check this !
+ return(0);
+ }
+ else
+ if(((byte1 & 0x18)>>3)==2)
+ {
+ pushVar(*(ptr+saveOpcodeVar));
+ return(0);
+ }
+ else
+ {
+ printf("Unsupported code in opcodeType0 case 1!\n");
+ exit(1);
+ }
+
+ return(0);
+ }
+ default:
+ {
+ printf("Unsupported type %d in opcodeType0\n",currentScriptOpcodeType);
+ exit(1);
+ }
+ }
+
+ return 0;
+}
+
+int32 opcodeType1(void) // save opcode
+{
+ int var = popVar();
+ int offset = 0;
+
+ switch(currentScriptOpcodeType)
+ {
+ case 0:
+ {
+ return(0); // strange, but happens also in original interpreter
+ }
+ case 5:
+ {
+ offset = saveOpcodeVar;
+ }
+ case 1:
+ {
+ int var_A = 0;
+
+ int byte1 = getByteFromScript();
+ int byte2 = getByteFromScript();
+
+ int short1 = getShortFromScript();
+
+ int var_6 = byte1 & 7;
+
+ int var_C = short1;
+
+ uint8* ptr;
+ int type2;
+
+ if(!var_6)
+ return(-10);
+
+ var_C = short1;
+
+ if(byte2)
+ {
+ if(!overlayTable[byte2].alreadyLoaded)
+ {
+ return(-7);
+ }
+
+ if(!overlayTable[byte2].ovlData)
+ {
+ return(-4);
+ }
+
+ if(var_6 == 5)
+ {
+ ptr = overlayTable[byte2].ovlData->data4Ptr + var_C;
+ }
+ else
+ {
+ ASSERT(0);
+ }
+ }
+ else
+ {
+ ptr = scriptDataPtrTable[var_6] + var_C;
+ }
+
+ type2 = ((byte1 & 0x18)>>3);
+
+ switch(type2)
+ {
+ case 1:
+ {
+ saveShort(ptr+var_A+offset*2,var);
+ return 0;
+ }
+ case 2:
+ {
+ *(ptr+var_A+offset) = var;
+ return(0);
+ }
+ default:
+ {
+ printf("Unsupported code in opcodeType1 case 1!\n");
+ exit(1);
+ }
+ }
+
+ break;
+ }
+ case 2:
+ {
+ int mode = getByteFromScript();
+ int di = getByteFromScript();
+ int var_4 = getShortFromScript();
+
+ if(!di)
+ {
+ di = currentScriptPtr->overlayNumber;
+ }
+
+ if(var == 0x85) // Special case to handle...
+ {
+ ASSERT(0);
+ }
+
+ setObjectPosition(di, var_4, mode, var);
+
+ break;
+ }
+ case 4:
+ {
+ saveOpcodeVar = var;
+ break;
+ }
+ default:
+ {
+ printf("Unsupported type %d in opcodeType1\n",currentScriptOpcodeType);
+ exit(1);
+ }
+ }
+
+ return(0);
+}
+
+
+int32 opcodeType2(void)
+{
+ int offset = saveOpcodeVar;
+ int byte1 = getByteFromScript();
+ int byte2 = getByteFromScript();
+ short int short1 = getShortFromScript();
+
+ ASSERT(currentScriptOpcodeType == 1 || currentScriptOpcodeType == 5);
+
+ if(currentScriptOpcodeType == 5)
+ short1 += saveOpcodeVar;
+
+ ASSERT(byte1 & 7);
+
+ if(!(byte1 & 7))
+ {
+ return(-10);
+ }
+
+ if(!byte2)
+ {
+ int type2;
+ uint8* ptr = scriptDataPtrTable[byte1 & 7] + short1;
+
+ type2 = ((byte1&0x18)>>3);
+
+ ASSERT(type2 == 1 || type2 == 2);
+
+ switch(type2)
+ {
+ case 1:
+ {
+ pushPtr(ptr + offset);
+ return(0);
+ }
+ case 2:
+ {
+ pushPtr(ptr);
+ return(0);
+ }
+ default :
+ {
+ return(-10);
+ }
+ }
+ }
+ else
+ {
+ printf("Unsupported code in opcodeType2 case 1!\n");
+ exit(1);
+ }
+
+ return 0;
+}
+
+int32 opcodeType10(void) // break
+{
+ return(0);
+}
+
+int32 opcodeType11(void) // break
+{
+ return(1);
+}
+
+int32 opcodeType4(void) // test
+{
+ int boolVar = 0;
+
+ int var1 = popVar();
+ int var2 = popVar();
+
+ switch(currentScriptOpcodeType)
+ {
+ case 0:
+ {
+ if(var2!=var1)
+ boolVar = 1;
+ break;
+ }
+ case 1:
+ {
+ if(var2==var1)
+ boolVar = 1;
+ break;
+ }
+ case 2:
+ {
+ if(var2<var1)
+ boolVar = 1;
+ break;
+ }
+ case 3:
+ {
+ if(var2<=var1)
+ boolVar = 1;
+ break;
+ }
+ case 4:
+ {
+ if(var2>var1)
+ boolVar = 1;
+ break;
+ }
+ case 5:
+ {
+ if(var2>=var1)
+ boolVar = 1;
+ break;
+ }
+
+ }
+
+ pushVar(boolVar);
+
+ return(0);
+}
+
+int32 opcodeType6(void)
+{
+ int si = 0;
+
+ int pop = popVar();
+
+ if(!pop)
+ si = 1;
+
+ if(pop<0)
+ {
+ si |= 4;
+ }
+
+ if(pop>0)
+ {
+ si |= 2;
+ }
+
+ currentScriptPtr->bitMask = si;
+
+ return(0);
+}
+
+int32 opcodeType7(void)
+{
+ int var1 = popVar();
+ int var2 = popVar();
+
+ pushVar(var1);
+ pushVar(var2);
+
+ return(0);
+}
+
+int32 opcodeType5(void)
+{
+ int offset = currentScriptPtr->var4;
+ int short1 = getShortFromScript();
+ int newSi = short1 + offset;
+ int bitMask = currentScriptPtr->bitMask;
+
+ switch(currentScriptOpcodeType)
+ {
+ case 0:
+ {
+ if(!(bitMask & 1))
+ {
+ currentScriptPtr->var4 = newSi;
+ }
+ break;
+ }
+ case 1:
+ {
+ if(bitMask & 1)
+ {
+ currentScriptPtr->var4 = newSi;
+ }
+ break;
+ }
+ case 2:
+ {
+ if(bitMask & 2)
+ {
+ currentScriptPtr->var4 = newSi;
+ }
+ break;
+ }
+ case 3:
+ {
+ if(bitMask & 3)
+ {
+ currentScriptPtr->var4 = newSi;
+ }
+ break;
+ }
+ case 4:
+ {
+ if(bitMask & 4)
+ {
+ currentScriptPtr->var4 = newSi;
+ }
+ break;
+ }
+ case 5:
+ {
+ if(bitMask & 5)
+ {
+ currentScriptPtr->var4 = newSi;
+ }
+ break;
+ }
+ case 6:
+ {
+ break; // never
+ }
+ case 7:
+ {
+ currentScriptPtr->var4 = newSi; //always
+ }
+ }
+
+ return(0);
+}
+
+int32 opcodeType3(void) // math
+{
+ int pop1 = popVar();
+ int pop2 = popVar();
+
+ switch(currentScriptOpcodeType)
+ {
+ case 0:
+ {
+ pushVar(pop1+pop2);
+ return(0);
+ }
+ case 1:
+ {
+ pushVar(pop1/pop2);
+ return(0);
+ }
+ case 2:
+ {
+ pushVar(pop1-pop2);
+ return(0);
+ }
+ case 3:
+ {
+ pushVar(pop1*pop2);
+ return(0);
+ }
+ case 4:
+ {
+ pushVar(pop1%pop2);
+ return(0);
+ }
+ case 7:
+ case 5:
+ {
+ pushVar(pop2|pop1);
+ return(0);
+ }
+ case 6:
+ {
+ pushVar(pop2&pop1);
+ return(0);
+ }
+ }
+
+ return 0;
+}
+
+int32 opcodeType9(void) // stop script
+{
+ //printf("Stop a script of overlay %s\n",overlayTable[currentScriptPtr->overlayNumber].overlayName);
+ currentScriptPtr->scriptNumber = -1;
+ return(1);
+}
+
+
+void setupFuncArray()
+{
+ int i;
+
+ for(i=0;i<64;i++)
+ {
+ opcodeTypeTable[i] = NULL;
+ }
+
+ opcodeTypeTable[1] = opcodeType0;
+ opcodeTypeTable[2] = opcodeType1;
+ opcodeTypeTable[3] = opcodeType2;
+ opcodeTypeTable[4] = opcodeType3;
+ opcodeTypeTable[5] = opcodeType4;
+ opcodeTypeTable[6] = opcodeType5;
+ opcodeTypeTable[7] = opcodeType6;
+ opcodeTypeTable[8] = opcodeType7;
+ opcodeTypeTable[9] = opcodeType8;
+ opcodeTypeTable[10] = opcodeType9;
+ opcodeTypeTable[11] = opcodeType10;
+ opcodeTypeTable[12] = opcodeType11;
+}
+
+int removeScript(int overlay,int idx,scriptInstanceStruct* headPtr)
+{
+ scriptInstanceStruct* scriptPtr;
+
+ scriptPtr = headPtr->nextScriptPtr;
+
+ if(scriptPtr)
+ {
+ do
+ {
+ if(scriptPtr->overlayNumber == overlay && (scriptPtr->scriptNumber == idx || idx == -1))
+ {
+ scriptPtr->scriptNumber = -1;
+ }
+
+ scriptPtr = scriptPtr->nextScriptPtr;
+ }
+ while(scriptPtr);
+ }
+
+ return(0);
+}
+
+uint8* attacheNewScriptToTail(int16 overlayNumber,scriptInstanceStruct* scriptHandlePtr,int16 param, int16 arg0, int16 arg1, int16 arg2, scriptTypeEnum scriptType)
+{
+ int useArg3Neg = 0;
+ ovlData3Struct* data3Ptr;
+ scriptInstanceStruct* tempPtr;
+ int var_C;
+ scriptInstanceStruct* oldTail;
+
+ //printf("Starting script %d of overlay %s\n",param,overlayTable[overlayNumber].overlayName);
+
+ if(scriptType<0)
+ {
+ useArg3Neg = 1;
+ scriptType = (scriptTypeEnum)-scriptType;
+ }
+
+ if(scriptType == 20)
+ {
+ data3Ptr = getOvlData3Entry(overlayNumber,param);
+ }
+ else
+ {
+ if(scriptType == 30)
+ {
+ data3Ptr = scriptFunc1Sub2(overlayNumber,param);
+ }
+ else
+ {
+ return(NULL);
+ }
+ }
+
+ if(!data3Ptr)
+ {
+ return(NULL);
+ }
+
+ if(!data3Ptr->dataPtr)
+ {
+ return(NULL);
+ }
+
+ var_C = data3Ptr->sysKey;
+
+ oldTail = scriptHandlePtr;
+
+ while(oldTail->nextScriptPtr) // go to the end of the list
+ {
+ oldTail=oldTail->nextScriptPtr;
+ }
+
+ tempPtr = (scriptInstanceStruct*)mallocAndZero(sizeof(scriptInstanceStruct));
+
+ if(!tempPtr)
+ return(NULL);
+
+ tempPtr->var6 = NULL;
+
+ if(var_C)
+ {
+ tempPtr->var6 = (uint8*)mallocAndZero(var_C);
+ }
+
+ tempPtr->varA = var_C;
+ tempPtr->nextScriptPtr = NULL;
+ tempPtr->var4 = 0;
+
+ tempPtr->scriptNumber = param;
+ tempPtr->overlayNumber = overlayNumber;
+
+ if(scriptType == 20) // Obj or not ?
+ {
+ tempPtr->sysKey = useArg3Neg;
+ }
+ else
+ {
+ tempPtr->sysKey = 1;
+ }
+
+ tempPtr->var12 = 0;
+ tempPtr->type = scriptType;
+ tempPtr->var18 = arg2;
+ tempPtr->var16 = arg1;
+ tempPtr->var1A = arg0;
+ tempPtr->nextScriptPtr = oldTail->nextScriptPtr; // should always be NULL as it's the tail
+
+ oldTail->nextScriptPtr = tempPtr; // attache the new node to the list
+
+ return(tempPtr->var6);
+}
+
+int executeScripts(scriptInstanceStruct* ptr)
+{
+ int numScript2;
+ ovlData3Struct* ptr2;
+ ovlDataStruct* ovlData;
+ uint8 opcodeType;
+
+ numScript2 = ptr->scriptNumber;
+
+ if(ptr->type == 20)
+ {
+ ptr2 = getOvlData3Entry(ptr->overlayNumber,numScript2);
+
+ if(!ptr2)
+ {
+ return(-4);
+ }
+ }
+ else
+ {
+ if(ptr->type == 30)
+ {
+ ptr2 = scriptFunc1Sub2(ptr->overlayNumber,numScript2);
+
+ if(!ptr2)
+ {
+ return(-4);
+ }
+ }
+ else
+ {
+ return(-6);
+ }
+ }
+
+ if(!overlayTable[ptr->overlayNumber].alreadyLoaded)
+ {
+ return(-7);
+ }
+
+ ovlData = overlayTable[ptr->overlayNumber].ovlData;
+
+ if(!ovlData)
+ return(-4);
+
+ currentData3DataPtr = ptr2->dataPtr;
+
+ scriptDataPtrTable[1] = (uint8*)ptr->var6;
+ scriptDataPtrTable[2] = getDataFromData3(ptr2, 1);
+ scriptDataPtrTable[5] = ovlData->data4Ptr; // free strings
+ scriptDataPtrTable[6] = ovlData->ptr8;
+
+ currentScriptPtr = ptr;
+
+ positionInStack = 0;
+
+ do
+ {
+ if(currentScriptPtr->var4 == 290 && currentScriptPtr->overlayNumber == 4 && currentScriptPtr->scriptNumber == 0)
+ {
+ currentScriptPtr->var4 = 923;
+ }
+ opcodeType = getByteFromScript();
+
+ //printf("opType: %d\n",(opcodeType&0xFB)>>3);
+
+ currentScriptOpcodeType = opcodeType & 7;
+
+ if(!opcodeTypeTable[(opcodeType&0xFB)>>3])
+ {
+ printf("Unsupported opcode type %d\n",(opcodeType&0xFB)>>3);
+ exit(1);
+ return(-21);
+ }
+ }while(!opcodeTypeTable[(opcodeType&0xFB)>>3]());
+
+ return(0);
+}
+
+void manageScripts(scriptInstanceStruct* scriptHandle)
+{
+ scriptInstanceStruct* ptr = scriptHandle;
+
+ if(ptr)
+ {
+ do
+ {
+ if(!overlayTable[ptr->overlayNumber].executeScripts)
+ {
+ if(ptr->scriptNumber != -1 && ptr->var12 == 0 && ptr->sysKey != 0)
+ {
+ executeScripts(ptr);
+ }
+
+ if(ptr->sysKey == 0)
+ {
+ ptr->sysKey = 1;
+ }
+ }
+
+ ptr = ptr->nextScriptPtr;
+
+ }while(ptr);
+ }
+}
+
+} // End of namespace Cruise
diff --git a/engines/cruise/script.h b/engines/cruise/script.h
new file mode 100644
index 0000000000..dd3f671a8c
--- /dev/null
+++ b/engines/cruise/script.h
@@ -0,0 +1,73 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef _SCRIPT_H_
+#define _SCRIPT_H_
+
+namespace Cruise {
+
+enum scriptTypeEnum
+{
+ scriptType_Minus20 = -20,
+ scriptType_Minus30 = -30,
+ scriptType_20 = 20,
+ scriptType_30 = 30
+};
+
+typedef enum scriptTypeEnum scriptTypeEnum;
+
+struct scriptInstanceStruct
+{
+ struct scriptInstanceStruct* nextScriptPtr;
+ int16 var4;
+ uint8* var6;
+ int16 varA;
+ int16 scriptNumber;
+ int16 overlayNumber;
+ int16 sysKey;
+ int16 var12;
+ scriptTypeEnum type;
+ int16 var16;
+ int16 var18;
+ int16 var1A;
+////// EXTRA ! not in original code. Needed for cross platform.
+ int16 bitMask;
+};
+
+typedef struct scriptInstanceStruct scriptInstanceStruct;
+
+extern scriptInstanceStruct scriptHandle1;
+extern scriptInstanceStruct scriptHandle2;
+extern scriptInstanceStruct* currentScriptPtr;
+
+void setupFuncArray(void);
+uint8 getByteFromScript(void);
+
+int removeScript(int overlay,int idx,scriptInstanceStruct* headPtr);
+uint8* attacheNewScriptToTail(int16 overlayNumber,scriptInstanceStruct* scriptHandlePtr,int16 param, int16 arg0, int16 arg1, int16 arg2, scriptTypeEnum scriptType);
+void manageScripts(scriptInstanceStruct* scriptHandle);
+
+} // End of namespace Cruise
+
+#endif
diff --git a/engines/cruise/stack.cpp b/engines/cruise/stack.cpp
new file mode 100644
index 0000000000..d83a496281
--- /dev/null
+++ b/engines/cruise/stack.cpp
@@ -0,0 +1,85 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cruise/cruise_main.h"
+
+namespace Cruise {
+
+// 4 type bigger than the old one, but much safer/cleaner
+stackElementStruct scriptStack[SIZE_STACK];
+
+// VAR
+
+void pushVar(int16 var)
+{
+ if(positionInStack<SIZE_STACK)
+ {
+ scriptStack[positionInStack].data.shortVar = var;
+ scriptStack[positionInStack].type = STACK_SHORT;
+ positionInStack++;
+ }
+}
+
+int16 popVar(void)
+{
+ if(positionInStack<=0)
+ {
+ return(0);
+ }
+
+ positionInStack--;
+
+ ASSERT(scriptStack[positionInStack].type == STACK_SHORT);
+
+ return(scriptStack[positionInStack].data.shortVar);
+}
+
+//// PTR
+
+void pushPtr(void* ptr)
+{
+ if(positionInStack<SIZE_STACK)
+ {
+ scriptStack[positionInStack].data.ptrVar = ptr;
+ scriptStack[positionInStack].type = STACK_PTR;
+ positionInStack++;
+ }
+}
+
+void* popPtr()
+{
+ if(positionInStack<=0)
+ {
+ return(0);
+ }
+
+ positionInStack--;
+
+ ASSERT(scriptStack[positionInStack].type == STACK_PTR);
+
+ return(scriptStack[positionInStack].data.ptrVar);
+}
+
+} // End of namespace Cruise
+
diff --git a/engines/cruise/stack.h b/engines/cruise/stack.h
new file mode 100644
index 0000000000..0d04bb0318
--- /dev/null
+++ b/engines/cruise/stack.h
@@ -0,0 +1,61 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef _STACK_H_
+#define _STACK_H_
+
+namespace Cruise {
+
+#define SIZE_STACK 0x200
+
+enum stackElementTypeEnum
+{
+ STACK_SHORT,
+ STACK_PTR
+};
+
+typedef enum stackElementTypeEnum stackElementTypeEnum;
+
+struct stackElementStruct
+{
+ stackElementTypeEnum type;
+
+ union
+ {
+ void* ptrVar;
+ int16 shortVar;
+ } data;
+};
+
+typedef struct stackElementStruct stackElementStruct;
+
+int16 popVar(void);
+void pushVar(int16 var);
+
+void pushPtr(void* ptr);
+void* popPtr(void);
+
+} // End of namespace Cruise
+
+#endif
diff --git a/engines/cruise/stringSupport.cpp b/engines/cruise/stringSupport.cpp
new file mode 100644
index 0000000000..8e9a5fa5ac
--- /dev/null
+++ b/engines/cruise/stringSupport.cpp
@@ -0,0 +1,49 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cruise/cruise_main.h"
+
+namespace Cruise {
+
+void strcpyuint8(void* dest, void* source)
+{
+ strcpy((char*)dest,(char*)source);
+}
+
+void strcatuint8(void* dest, void* source)
+{
+ strcat((char*)dest,(char*)source);
+}
+
+uint8 strcmpuint8(void* string1, void* string2)
+{
+ return strcmp((char*)string1,(char*)string2);
+}
+
+FILE* fopenuint8(void* name, void* param)
+{
+ return fopen((char*)name,(char*)param);
+}
+
+} // End of namespace Cruise
diff --git a/engines/cruise/stringSupport.h b/engines/cruise/stringSupport.h
new file mode 100644
index 0000000000..dca3091520
--- /dev/null
+++ b/engines/cruise/stringSupport.h
@@ -0,0 +1,37 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef _STRING_SUPPORT_H_
+#define _STRING_SUPPORT_H_
+
+namespace Cruise {
+
+void strcpyuint8(void* dest, void* source);
+void strcatuint8(void* dest, void* source);
+uint8 strcmpuint8(void* string1, void* string2);
+FILE* fopenuint8(void* name, void* param);
+
+} // End of namespace Cruise
+
+#endif
diff --git a/engines/cruise/various.cpp b/engines/cruise/various.cpp
new file mode 100644
index 0000000000..883623b549
--- /dev/null
+++ b/engines/cruise/various.cpp
@@ -0,0 +1,187 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cruise/cruise_main.h"
+
+namespace Cruise {
+
+uint16 var0 = 0;
+uint16 fadeVar;
+uint16 main15;
+
+int16 readB16(void* ptr)
+{
+ int16 temp;
+
+ temp = *(int16*)ptr;
+ flipShort(&temp);
+
+ return temp;
+}
+
+void freeObject(objectStruct* objPtr)
+{
+ if(objPtr)
+ {
+ /* if(objPtr->next)
+ free(objPtr->next); */
+
+ //free(objPtr);
+ }
+}
+
+void removeObjectFromList(int ovlNumber, int objectIdx, objectStruct* objPtr, int backgroundPlane, int arg)
+{
+ objectStruct* currentObj = objPtr->next;
+ objectStruct* previous;
+
+ while(currentObj)
+ {
+ objectStruct* si;
+
+ si = currentObj;
+
+ if( (si->overlay == ovlNumber || ovlNumber == -1) &&
+ (si->idx == objectIdx || objectIdx == -1) &&
+ (si->type == arg || arg == -1) &&
+ (si->backgroundPlane == backgroundPlane || backgroundPlane == -1) )
+ {
+ si->type = -1;
+ }
+
+ currentObj = si->next;
+ }
+
+ previous = objPtr;
+ currentObj = objPtr->next;
+
+ while(currentObj)
+ {
+ objectStruct* si;
+
+ si = currentObj;
+
+ if(si->type == -1)
+ {
+ objectStruct* dx;
+ previous->next = si->next;
+
+ dx = si->next;
+
+ if(!si->next)
+ {
+ dx = objPtr;
+ }
+
+ dx->prev = si->prev;
+
+ freeObject(si);
+
+ free(si);
+
+ currentObj = dx;
+ }
+ else
+ {
+ currentObj = si->next;
+ previous = si;
+ }
+ }
+}
+
+char* getText(int textIndex, int overlayIndex)
+{
+ if(!overlayTable[overlayIndex].ovlData)
+ {
+ return NULL;
+ }
+
+ if(!overlayTable[overlayIndex].ovlData->stringTable)
+ {
+ return NULL;
+ }
+
+ return overlayTable[overlayIndex].ovlData->stringTable[textIndex].string;
+}
+
+void createTextObject(int overlayIdx, int oldVar8, objectStruct *pObject, int scriptNumber, int scriptOverlayNumber, int backgroundPlane, int16 color, int oldVar2, int oldVar4, int oldVar6)
+{
+ char* ax;
+ objectStruct* savePObject = pObject;
+ objectStruct* cx;
+
+ objectStruct* pNewElement;
+ objectStruct* si = pObject->next;
+ objectStruct* var_2;
+
+ while(si)
+ {
+ pObject = si;
+ si = si->next;
+ }
+
+ var_2 = si;
+
+ pNewElement = (objectStruct*)malloc(sizeof(objectStruct));
+
+ pNewElement->next = pObject->next;
+ pObject->next = pNewElement;
+
+ pNewElement->idx = oldVar8;
+ pNewElement->type = 5;
+ pNewElement->backgroundPlane = backgroundPlane;
+ pNewElement->overlay = overlayIdx;
+ pNewElement->field_A = oldVar6;
+ pNewElement->field_C = oldVar4;
+ pNewElement->spriteIdx = oldVar2;
+ pNewElement->field_10 = color;
+ pNewElement->hide = 0;
+ pNewElement->field_16 = scriptNumber;
+ pNewElement->field_18 = scriptOverlayNumber;
+ pNewElement->gfxPtr = NULL;
+
+ if(var_2)
+ {
+ cx = var_2;
+ }
+ else
+ {
+ cx = savePObject;
+ }
+
+ pNewElement->prev = cx->prev;
+ cx->prev = pNewElement;
+
+ ax = getText(oldVar8, overlayIdx);
+
+ if(ax)
+ {
+ pNewElement->gfxPtr = renderText(oldVar2, (uint8*)ax);
+ }
+}
+
+} // End of namespace Cruise
+
+
+
diff --git a/engines/cruise/various.h b/engines/cruise/various.h
new file mode 100644
index 0000000000..e91e2a87ae
--- /dev/null
+++ b/engines/cruise/various.h
@@ -0,0 +1,43 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef _VARIOUS_H_
+#define _VARIOUS_H_
+
+namespace Cruise {
+
+extern uint16 var0;
+extern uint16 fadeVar;
+extern uint16 main15;
+
+int16 readB16(void* ptr);
+
+void createTextObject(int overlayIdx, int oldVar8, objectStruct *pObject, int scriptNumber, int scriptOverlayNumber, int backgroundPlane, int16 color, int oldVar2, int oldVar4, int oldVar6);
+void removeObjectFromList(int ovlNumber, int objectIdx, objectStruct* objPtr, int backgroundPlane, int arg);
+objectStruct* addObject(int16 overlayIdx,int16 param2,objectStruct* pHead,int16 scriptType,int16 scriptNumber,int16 scriptOverlay, int16 param3, int16 param4);
+int16 Op_7Sub(int ovlIdx,int param1,int param2);
+
+} // End of namespace Cruise
+
+#endif
diff --git a/engines/cruise/vars.cpp b/engines/cruise/vars.cpp
new file mode 100644
index 0000000000..eab348e3d0
--- /dev/null
+++ b/engines/cruise/vars.cpp
@@ -0,0 +1,182 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cruise/cruise_main.h"
+
+namespace Cruise {
+
+uint8* _systemFNT;
+
+uint8 video2 = 1;
+uint8 video3 = 3;
+uint8 video4 = 2;
+uint8 colorOfSelectedSaveDrive = 5;
+
+int16 initVar1;
+int16 initVar2;
+int16 initVar3;
+uint8 initVar4[90];
+
+int16 currentActiveBackgroundPlane;
+int16 main5;
+int16 var22 = 0;
+
+filesDataStruct filesData[90];
+filesData2Struct filesData2[90];
+
+mediumVarStruct mediumVar[64];
+
+volumeDataStruct volumeData[20];
+
+int32 volumeDataLoaded = 0;
+
+int16 numOfDisks;
+
+uint8 scriptNameBuffer[15];
+int16 currentActiveMenu;
+int16 main14;
+int16 mouseVar1;
+int16 main21;
+int16 main22;
+int16 main7;
+int16 main8;
+
+int16 currentDiskNumber = 1;
+
+Common::File currentVolumeFile;
+
+int16 currentCursor;
+
+int16 volumeNumEntry;
+fileEntry* volumePtrToFileDescriptor = NULL;
+
+uint32 volumeFileDescriptorSize;
+int16 volumeSizeOfEntry;
+int16 volumeNumberOfEntry;
+
+int16 affichePasMenuJoueur = 1;
+
+int16 globalVars[2000];
+
+dataFileEntry filesDatabase[257];
+
+int16 bootOverlayNumber;
+
+int16 initVar5[12];
+
+objectStruct objectHead;
+
+opcodeTypeFunction opcodeTypeTable[64];
+
+
+int16 positionInStack;
+
+actorStruct actorHead;
+
+
+int16 setup1;
+
+uint8* currentData3DataPtr;
+uint8* scriptDataPtrTable[7];
+
+int16 currentScriptOpcodeType;
+
+int16 saveOpcodeVar;
+
+int16 var30 = 0;
+int16 var31 = 0;
+
+int16 var1;
+int16 var2;
+int16 var3;
+int16 var4;
+int16 userEnabled;
+int16 var5;
+int16 var6;
+int16 var7;
+int16 var8;
+int16 userDelay;
+int16 sysKey = -1;
+int16 var11 = 0;
+int16 var12;
+int16 var13;
+int16 var14;
+int16 var20;
+int16 var23;
+int16 var24;
+int16 automaticMode;
+int16 var34;
+int16 var35;
+int16 animationStart;
+
+int16 main17;
+int16 var39;
+int16 entrerMenuJoueur;
+int16 var41;
+int16 var42;
+int16 var45;
+int16 var46;
+int16 var47;
+int16 var48;
+int16 flagCt;
+
+int8 var50[64];
+int16 palette[256*3];
+
+systemStringsStruct systemStrings;
+
+uint8 currentCtpName[40];
+
+int16 saveVar1;
+uint8 saveVar2[97]; // recheck size
+
+int16 numberOfWalkboxes; // saveVar3
+int16 walkboxType[15]; // saveVar4
+int16 walkboxChange[15]; // saveVar5
+
+uint8 saveVar6[16];
+
+int32 loadFileVar1;
+
+int16 ctpVar1 = 0;
+int16 ctp_routeCoordCount; // ctpVar2
+int16 ctp_routeCoords[20][2]; // ctpVar3
+int16 ctp_routes[20][10];
+uint16 ctp_walkboxTable[15 * 40]; // ctpVar5
+int8 ctpVar6[32];
+int16 ctp_scale[15]; // ctpVar7
+int16 ctpVar8[200];
+
+int16 ctpVar14;
+
+int16 bgVar1;
+int16 bgVar2;
+int16 bgVar3;
+
+uint8 globalScreen[320*200];
+uint8 scaledScreen[640*400];
+
+//OSystem *osystem;
+
+} // End of namespace Cruise
diff --git a/engines/cruise/vars.h b/engines/cruise/vars.h
new file mode 100644
index 0000000000..11e36fe6ff
--- /dev/null
+++ b/engines/cruise/vars.h
@@ -0,0 +1,340 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef _VARS_H_
+#define _VARS_H_
+
+#include "common/file.h"
+
+namespace Cruise {
+
+struct menuElementSubStruct
+{
+ struct menuElementSubStruct* pNext;
+ int16 var2;
+ int16 var4;
+};
+
+typedef struct menuElementSubStruct menuElementSubStruct;
+
+struct menuElementStruct
+{
+ struct menuElementStruct* next;
+ char* string;
+ int x;
+ int y;
+ int varA;
+ int varC;
+ unsigned char color;
+ gfxEntryStruct* gfx;
+ menuElementSubStruct* ptrSub;
+};
+
+typedef struct menuElementStruct menuElementStruct;
+
+typedef int32(*opcodeTypeFunction)(void);
+typedef int16(*opcodeFunction)(void);
+
+
+extern uint8* _systemFNT;
+extern int16 fontFileIndex;
+
+extern uint8 video2;
+extern uint8 video3;
+extern uint8 video4;
+extern uint8 colorOfSelectedSaveDrive;
+
+extern int16 initVar1;
+extern int16 initVar2;
+extern int16 initVar3;
+extern uint8 initVar4[90];
+
+extern int16 currentActiveBackgroundPlane;
+extern int16 main5;
+extern int16 var22;
+
+
+struct mediumVarStruct
+{
+ uint8 name[16];
+ int16 field_10;
+ int16 field_12;
+ int16 field_14;
+ int16 field_16;
+ uint8* ptr;
+ int16 field_1C;
+ int16 field_1E;
+ int16 field_20;
+};
+
+typedef struct mediumVarStruct mediumVarStruct;
+
+struct filesDataStruct
+{
+ uint8* field_0;
+ uint8* field_4;
+};
+
+typedef struct filesDataStruct filesDataStruct;
+
+struct filesData2Struct
+{
+ int16 field_0;
+ int16 field_2;
+};
+
+typedef struct filesData2Struct filesData2Struct;
+
+struct fileName
+{
+ uint8 name[13];
+};
+
+typedef struct fileName fileName;
+
+struct setHeaderEntry
+{
+ int16 field_0; // offset ptr part 1
+ int16 field_2; // offset ptr part 2
+ int16 width;
+ int16 height;
+ int16 type; // resource type, ie. sprites 0,1,4,5 and 8
+ int16 transparency;
+ int16 field_C;
+ int16 field_E;
+};
+
+typedef struct setHeaderEntry setHeaderEntry;
+
+struct volumeDataStruct
+{
+ char ident[10];
+ fileName* ptr;
+ int16 diskNumber;
+ int32 size;
+};
+
+typedef struct volumeDataStruct volumeDataStruct;
+
+struct fileEntry
+{
+ uint8 name[14];
+ int32 offset;
+ int32 size;
+ int32 extSize;
+ int32 unk3; // unused
+};
+
+typedef struct fileEntry fileEntry;
+
+struct dataFileEntrySub
+{
+ uint8* ptr;
+ int16 index; // sprite index
+ char name[14];
+ int16 transparency; // sprite transparency
+ uint8* ptr2;
+ uint8 resourceType; // sprite and image type 2,4,8 , fnt = 7, spl = 6
+ uint8 field_1B;
+ int16 field_1C;
+};
+
+typedef struct dataFileEntrySub dataFileEntrySub;
+
+struct dataFileEntry
+{
+ int16 widthInColumn;
+ int16 width;
+ int16 resType;
+ int16 height;
+ dataFileEntrySub subData;
+};
+
+typedef struct dataFileEntry dataFileEntry;
+
+struct systemStringsStruct
+{
+ int8 param;
+ uint8 string[12];
+ uint8 bootScriptName[8];
+};
+
+typedef struct systemStringsStruct systemStringsStruct;
+
+extern filesDataStruct filesData[90];
+extern filesData2Struct filesData2[90];
+
+extern mediumVarStruct mediumVar[64];
+
+extern volumeDataStruct volumeData[20];
+
+extern int32 volumeDataLoaded;
+
+extern int16 numOfDisks;
+
+extern uint8 scriptNameBuffer[15];
+extern int16 currentActiveMenu;
+extern int16 main14;
+extern int16 mouseVar1;
+extern int16 main21;
+extern int16 main22;
+extern int16 main7;
+extern int16 main8;
+
+
+extern int16 currentDiskNumber;
+
+extern Common::File currentVolumeFile;
+
+extern int16 currentCursor;
+
+extern int16 volumeNumEntry;
+extern fileEntry* volumePtrToFileDescriptor;
+
+extern uint32 volumeFileDescriptorSize;
+extern int16 volumeSizeOfEntry;
+extern int16 volumeNumberOfEntry;
+
+extern int16 affichePasMenuJoueur;
+
+extern int16 globalVars[2000];
+extern dataFileEntry filesDatabase[257];
+
+extern int16 bootOverlayNumber;
+
+extern int16 initVar5[12];
+
+extern objectStruct objectHead;
+
+extern opcodeTypeFunction opcodeTypeTable[64];
+
+extern int16 positionInStack;
+extern actorStruct actorHead;
+
+extern int16 setup1;
+
+extern uint8* currentData3DataPtr;
+extern uint8* scriptDataPtrTable[7];
+
+extern int16 currentScriptOpcodeType;
+
+extern int16 saveOpcodeVar;
+
+extern int16 var30;
+extern int16 var31;
+
+extern int16 var1;
+extern int16 var2;
+extern int16 var3;
+extern int16 var4;
+extern int16 userEnabled;
+extern int16 var5;
+extern int16 var6;
+extern int16 var7;
+extern int16 var8;
+extern int16 userDelay;
+extern int16 sysKey;
+extern int16 var11;
+extern int16 var12;
+extern int16 var13;
+extern int16 var14;
+extern int16 var20;
+extern int16 var23;
+extern int16 var24;
+extern int16 automaticMode;
+extern int16 var34;
+extern int16 var35;
+extern int16 animationStart;
+
+extern int16 main17;
+extern int16 var39;
+extern int16 entrerMenuJoueur;
+extern int16 var39;
+extern int16 var41;
+extern int16 var42;
+extern int16 var45;
+extern int16 var46;
+extern int16 var47;
+extern int16 var48;
+extern int16 flagCt;
+
+extern int8 var50[64];
+extern int16 palette[256*3];
+
+extern systemStringsStruct systemStrings;
+
+extern uint8 currentCtpName[40];
+
+extern int16 saveVar1;
+extern uint8 saveVar2[97]; // recheck size
+
+extern int16 numberOfWalkboxes; // saveVar3
+extern int16 walkboxType[15]; // saveVar4 // Type: 0x00 - non walkable, 0x01 - walkable, 0x02 - exit zone
+extern int16 walkboxChange[15]; // saveVar5 // walkbox can change its type: 0x00 - not changeable, 0x01 - changeable
+ // Assumption: To change the type: walkboxType[i] -= walkboxChane[i] and vice versa
+extern uint8 saveVar6[16];
+
+extern int32 loadFileVar1;
+
+extern int16 ctpVar1;
+extern int16 ctp_routeCoordCount; // ctpVar2 // number of path-finding coordinates
+extern int16 ctp_routeCoords[20][2]; // ctpVar3 // path-finding coordinates array
+
+/* ctp_routeCoords:
+
+ correct size would be: ctp_routes[routeCoordCount * 4]
+ coordinate information with x (2 bytes) and y (2 bytes)
+*/
+
+extern int16 ctp_routes[20][10]; // path-finding line information
+
+/* ctp_routes:
+
+ correct size would be: ctp_routes[routeCoordCount * 20 * 2]
+ array is seperate in 20 * 2 bytes slices.
+ first 2 bytes of the slice indicate how many coordinates/lines are following (lineCount)
+ after that there are lineCount * 2 bytes following with indexes pointing on the routeCoords table
+ the root x,y for the lines is the coordinate in the routeCoords array, which fits to the current slice
+ for the 20 * i slice the root x,y is routeCoords[i], routeCoords[i+2]
+ the unused rest of the slice if filled up with 0xFF
+*/
+extern uint16 ctp_walkboxTable[15 * 40]; // ctpVar5 // walkboxes coordinates and lines
+extern int8 ctpVar6[32];
+extern int16 ctp_scale[15]; // ctpVar7 // scaling information for walkboxes
+extern int16 ctpVar8[200];
+
+extern int16 ctpVar14;
+
+extern int16 bgVar1;
+extern int16 bgVar2;
+extern int16 bgVar3;
+
+extern uint8 globalScreen[320*200];
+extern uint8 scaledScreen[640*400];
+
+//extern OSystem *osystem;
+
+} // End of namespace Cruise
+
+#endif \ No newline at end of file
diff --git a/engines/cruise/volume.cpp b/engines/cruise/volume.cpp
new file mode 100644
index 0000000000..ef877d6026
--- /dev/null
+++ b/engines/cruise/volume.cpp
@@ -0,0 +1,518 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cruise/cruise_main.h"
+
+namespace Cruise {
+
+FILE* PAL_fileHandle = NULL;
+uint8* PAL_ptr = NULL;
+
+int16 numLoadedPal;
+int16 fileData2;
+
+void loadPal(volumeDataStruct* entry)
+{
+ char name[20];
+
+ return;
+
+ if(PAL_fileHandle)
+ {
+ fclose(PAL_fileHandle);
+ }
+
+ removeExtention(entry->ident, name);
+ strcat(name,".PAL");
+
+ PAL_fileHandle = fopen(name,"rb");
+
+ fread(&numLoadedPal, 2, 1, PAL_fileHandle);
+ fread(&fileData2, 2, 1, PAL_fileHandle);
+
+ flipShort(&numLoadedPal);
+ flipShort(&fileData2);
+
+ PAL_ptr = (uint8*)malloc(numLoadedPal*fileData2);
+}
+
+int getVolumeDataEntry(volumeDataStruct* entry)
+{
+ char buffer[256];
+ int i;
+
+ volumeNumEntry = 0;
+ volumeNumberOfEntry = 0;
+
+ if(currentVolumeFile.isOpen())
+ {
+ freeDisk();
+ }
+
+ askDisk(-1);
+
+ strcpyuint8(buffer,entry->ident);
+
+ currentVolumeFile.open(buffer);
+
+ if(!currentVolumeFile.isOpen())
+ {
+ return(-14);
+ }
+
+ changeCursor(1);
+
+ currentVolumeFile.read(&volumeNumberOfEntry,2);
+ currentVolumeFile.read(&volumeSizeOfEntry,2);
+
+ flipShort(&volumeNumberOfEntry);
+ flipShort(&volumeSizeOfEntry);
+
+ volumeNumEntry = volumeNumberOfEntry;
+
+ assert(volumeSizeOfEntry == 14+4+4+4+4);
+
+ volumePtrToFileDescriptor = (fileEntry*)mallocAndZero(sizeof(fileEntry) * volumeNumEntry);
+
+ for(i=0;i<volumeNumEntry;i++)
+ {
+ volumePtrToFileDescriptor[i].name[0] = 0;
+ volumePtrToFileDescriptor[i].offset = 0;
+ volumePtrToFileDescriptor[i].size = 0;
+ volumePtrToFileDescriptor[i].extSize = 0;
+ volumePtrToFileDescriptor[i].unk3 = 0;
+ }
+
+ for(i=0;i<volumeNumEntry;i++)
+ {
+ currentVolumeFile.read(&volumePtrToFileDescriptor[i].name, 14);
+ currentVolumeFile.read(&volumePtrToFileDescriptor[i].offset, 4);
+ currentVolumeFile.read(&volumePtrToFileDescriptor[i].size, 4);
+ currentVolumeFile.read(&volumePtrToFileDescriptor[i].extSize, 4);
+ currentVolumeFile.read(&volumePtrToFileDescriptor[i].unk3, 4);
+ }
+
+ for(i=0;i<volumeNumEntry;i++)
+ {
+ flipLong(&volumePtrToFileDescriptor[i].offset);
+ flipLong(&volumePtrToFileDescriptor[i].size);
+ flipLong(&volumePtrToFileDescriptor[i].extSize);
+ }
+
+ loadPal(entry);
+
+ return 0;
+}
+
+int searchFileInVolCnf(uint8* fileName,int32 diskNumber)
+{
+ int foundDisk = -1;
+ int i;
+
+ for(i=0;i<numOfDisks;i++)
+ {
+ if(volumeData[i].diskNumber == diskNumber)
+ {
+ int j;
+ int numOfEntry = volumeData[i].size / 13;
+
+ for(j=0;j<numOfEntry;j++)
+ {
+ if(!strcmpuint8(volumeData[i].ptr[j].name,fileName))
+ {
+ return(i);
+ }
+ }
+ }
+ }
+
+ return(foundDisk);
+}
+
+int32 findFileInDisksSub1(uint8* fileName)
+{
+ int foundDisk = -1;
+ int i;
+
+ for(i=0;i<numOfDisks;i++)
+ {
+ int j;
+ int numOfEntry = volumeData[i].size / 13;
+
+ for(j=0;j<numOfEntry;j++)
+ {
+ if(!strcmpuint8(volumeData[i].ptr[j].name,fileName))
+ {
+ return(i);
+ }
+ }
+ }
+
+ return(foundDisk);
+}
+
+void strToUpper(uint8* fileName)
+{
+ char character;
+
+ do
+ {
+ character = *fileName;
+
+ if(character>='a' && character<='z')
+ {
+ character&=0xDF;
+ *fileName = character;
+ }
+
+ fileName++;
+
+ }while(character);
+}
+
+int16 fileExist(uint8* fileName)
+{
+ FILE* fHandle;
+
+ fHandle = fopenuint8(fileName,"rb");
+
+ if(fHandle)
+ {
+ fclose(fHandle);
+ return(0);
+ }
+
+ return(1);
+}
+
+void freeDisk(void)
+{
+ if(currentVolumeFile.isOpen())
+ {
+ currentVolumeFile.close();
+ free(volumePtrToFileDescriptor);
+ }
+
+ /* TODO
+ if(PAL_fileHandle)
+ {
+ freeAllDataPtr();
+ }
+ */
+}
+
+int16 findFileInList(uint8* fileName)
+{
+ int i;
+
+ if(!currentVolumeFile.isOpen())
+ {
+ return(-1);
+ }
+
+ strToUpper(fileName);
+
+ if(volumeNumEntry<=0)
+ {
+ return(-1);
+ }
+
+ for(i=0;i<volumeNumEntry;i++)
+ {
+ if(!strcmpuint8(volumePtrToFileDescriptor[i].name,fileName))
+ {
+ return(i);
+ }
+ }
+
+ return(-1);
+}
+
+void askDisk(int16 discNumber)
+{
+ char diskNumberString[256];
+ uint8 fileName[256];
+ uint8 string[256];
+ char messageDrawn = 0;
+
+ if(discNumber != -1)
+ {
+ currentDiskNumber = discNumber;
+ }
+
+ // skip drive selection stuff
+
+ strcpyuint8(fileName,"VOL.");
+ sprintf(diskNumberString,"%d",currentDiskNumber);
+ strcatuint8(fileName,diskNumberString);
+
+ strcpyuint8(string,"INSERER LE DISQUE ");
+ strcatuint8(string,diskNumberString);
+ strcatuint8(string," EN ");
+
+// while(fileExist(fileName))
+ {
+ if(!messageDrawn)
+ {
+ drawMsgString(string);
+ messageDrawn = 1;
+ }
+ }
+
+ changeCursor(currentCursor);
+}
+
+
+
+int16 findFileInDisks(uint8* fileName)
+{
+ int disk;
+ int fileIdx;
+
+ strToUpper(fileName);
+
+ if(!volumeDataLoaded)
+ {
+ printf("CNF wasn't loaded, reading now...\n");
+ if(currentVolumeFile.isOpen())
+ {
+ askDisk(-1);
+ freeDisk();
+ }
+
+ askDisk(1);
+ readVolCnf();
+ }
+
+ if(currentVolumeFile.isOpen())
+ {
+ askDisk(-1);
+ }
+
+ fileIdx = findFileInList(fileName);
+
+ if(fileIdx>=0)
+ {
+ return(fileIdx);
+ }
+
+ disk = searchFileInVolCnf(fileName,currentDiskNumber);
+
+ if(disk>=0)
+ {
+ int temp;
+
+ printf("File found on disk %d\n", disk);
+
+ if(currentVolumeFile.isOpen())
+ {
+ askDisk(-1);
+ }
+
+ freeDisk();
+
+ askDisk(volumeData[disk].diskNumber);
+
+ getVolumeDataEntry(&volumeData[disk]);
+
+ temp = findFileInList(fileName);
+
+ if(temp>=0)
+ return(temp);
+
+ return(-1);
+
+ }
+ else
+ {
+ int temp;
+
+ temp = findFileInDisksSub1(fileName);
+
+ if(temp>=0)
+ {
+ int temp2;
+
+ askDisk(volumeData[temp].diskNumber);
+
+ getVolumeDataEntry(&volumeData[temp]);
+
+ temp2 = findFileInList(fileName);
+
+ if(temp2>=0)
+ return(temp2);
+ }
+
+
+ return(-1);
+ }
+}
+
+int16 readVolCnf(void)
+{
+ int i;
+ Common::File fileHandle;
+ short int sizeHEntry;
+
+ volumeDataLoaded = 0;
+
+ for(i=0;i<20;i++)
+ {
+ volumeData[i].ident[0] = 0;
+ volumeData[i].ptr = NULL;
+ volumeData[i].diskNumber = i+1;
+ volumeData[i].size = 0;
+ }
+
+ fileHandle.open("VOL.CNF");
+
+ if(!fileHandle.isOpen())
+ {
+ return(0);
+ }
+
+ fileHandle.read(&numOfDisks,2);
+ flipShort(&numOfDisks);
+
+ fileHandle.read(&sizeHEntry,2);
+ flipShort(&sizeHEntry); // size of one header entry - 20 bytes
+
+ for(i=0;i<numOfDisks;i++)
+ {
+ // fread(&volumeData[i],20,1,fileHandle);
+ fileHandle.read(&volumeData[i].ident, 10);
+ fileHandle.read(&volumeData[i].ptr, 4);
+ fileHandle.read(&volumeData[i].diskNumber, 2);
+ fileHandle.read(&volumeData[i].size, 4);
+
+ flipShort(&volumeData[i].diskNumber);
+ printf("Disk number: %d\n", volumeData[i].diskNumber);
+ flipLong(&volumeData[i].size);
+ }
+
+ for(i=0;i<numOfDisks;i++)
+ {
+ fileName* ptr;
+
+ fileHandle.read(&volumeData[i].size,4);
+ flipLong(&volumeData[i].size);
+
+ ptr = (fileName*)mallocAndZero(volumeData[i].size);
+
+ volumeData[i].ptr = ptr;
+
+ if(!ptr)
+ {
+ fileHandle.close();
+ return(-2);
+ }
+
+ fileHandle.read(ptr,volumeData[i].size);
+ }
+
+ fileHandle.close();
+
+ volumeDataLoaded = 1;
+
+//#define dumpResources
+#ifdef dumpResources
+
+ for(i=0;i<numOfDisks;i++)
+ {
+ int j;
+ char nameBuffer[256];
+ fileEntry* buffer;
+
+ sprintf(nameBuffer,"D%d.",i+1);
+
+ fileHandle = fopen(nameBuffer,"rb");
+
+ short int numEntry;
+ short int sizeEntry;
+
+ fread(&numEntry,2,1,fileHandle);
+ fread(&sizeEntry,2,1,fileHandle);
+
+ flipShort(&numEntry);
+ flipShort(&sizeEntry);
+
+ buffer = (fileEntry*)mallocAndZero(numEntry*sizeEntry);
+
+ fread(buffer,numEntry*sizeEntry,1,fileHandle);
+
+ for(j=0;j<numEntry;j++)
+ {
+ flipLong(&buffer[j].offset);
+ flipLong(&buffer[j].size);
+ flipLong(&buffer[j].unk2);
+ flipLong(&buffer[j].unk3);
+
+ fseek(fileHandle, buffer[j].offset, SEEK_SET);
+
+ char* bufferLocal;
+ bufferLocal = (char*)mallocAndZero(buffer[j].size);
+
+ fread(bufferLocal,buffer[j].size,1,fileHandle);
+
+ char nameBuffer[256];
+
+ sprintf(nameBuffer,"D%d.dmp/%s",i+1,buffer[j].name);
+
+ if(buffer[j].size == buffer[j].unk2)
+ {
+ FILE* fOut = fopen(nameBuffer,"wb+");
+ fwrite(bufferLocal,buffer[j].size,1,fOut);
+ fclose(fOut);
+ }
+ else
+ {
+ char* uncompBuffer = (char*)mallocAndZero(buffer[j].unk2+500);
+
+ decomp((uint8*)bufferLocal+buffer[j].size-4,(uint8*)uncompBuffer+buffer[j].unk2+500,buffer[j].unk2);
+
+ FILE* fOut = fopen(nameBuffer,"wb+");
+ fwrite(uncompBuffer+500,buffer[j].unk2,1,fOut);
+ fclose(fOut);
+
+ //free(uncompBuffer);
+
+ }
+
+ free(bufferLocal);
+ }
+ }
+
+#endif
+
+ return(1);
+}
+
+///////////////////////////::
+
+void drawMsgString(uint8* string)
+{
+ //printf("%s\n",string);
+}
+
+} // End of namespace Cruise
diff --git a/engines/cruise/volume.h b/engines/cruise/volume.h
new file mode 100644
index 0000000000..4e057a4773
--- /dev/null
+++ b/engines/cruise/volume.h
@@ -0,0 +1,45 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef _VOLUME_H_
+#define _VOLUME_H_
+
+namespace Cruise {
+
+int16 readVolCnf(void);
+int16 findFileInDisks(uint8* fileName);
+int16 fileExist(uint8* fileName);
+void freeDisk(void);
+int16 findFileInList(uint8* fileName);
+
+////////////////
+
+void strToUpper(uint8* fileName);
+void drawMsgString(uint8* string);
+void askDisk(int16 discNumber);
+void setObjectPosition(int16 param1,int16 param2,int16 param3,int16 param4);
+
+} // End of namespace Cruise
+
+#endif