diff options
Diffstat (limited to 'engines/cruise')
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,¶ms); + + 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,¶ms); + + 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(¤t->objectIdx,2,1,fileHandle); + fread(¤t->field_6,2,1,fileHandle); + fread(¤t->overlayIdx,2,1,fileHandle); + fread(¤t->X,2,1,fileHandle); + fread(¤t->Y,2,1,fileHandle); + fread(¤t->field_E,2,1,fileHandle); + fread(¤t->scale,2,1,fileHandle); + fread(¤t->backgroundIdx,2,1,fileHandle); + fread(¤t->scriptNumber,2,1,fileHandle); + fread(¤t->scriptOverlayIdx,2,1,fileHandle); + fread(¤t->ptr,4,1,fileHandle); + fread(¤t->field_1C,4,1,fileHandle); + fread(¤t->size,2,1,fileHandle); + fread(¤t->field_22,2,1,fileHandle); + fread(¤t->field_24,2,1,fileHandle); + fread(current->name,14,1,fileHandle); + fread(¤t->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, ¶ms); + + 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, ¶ms); + + 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, ¶ms); + 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, ¶ms); + + 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, ¶ms); + + 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, ¶ms); + + 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(¤t->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(¤tActiveBackgroundPlane,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(¤tActiveMenu,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, ¶ms); + + 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, ¶ms); + + objX1 = params.X; + objY1 = params.Y; + objZ1 = params.fileIdx; + } + + getMultipleObjectParam(currentObjPtr->overlay, currentObjIdx, ¶ms); + + 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(¶ms,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 |