/* ----------------------------------------------- GTASC - GTA adaptation for TI Calculators ----------------------------------------------- Programmed by : Olivier SANGALA Version : 1.2 License : Free under GNU General Public License ( see "gpl.txt" ) Release Date : 05/01/2007 Platform : TI89/TI92+/V200 Website : http://olivier.sangala.free.fr Email : olivier_sangala@hotmail.com ---------- License ---------- Copyright (C) 2002-2007 Olivier SANGALA 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //----------------------------------------------------------------------------- #define USE_TI89 // Compile for TI-89 #define USE_TI92PLUS // Compile for TI-92 Plus #define USE_V200 // Compile for V200 // #define OPTIMIZE_ROM_CALLS // Use ROM Call Optimization #define MIN_AMS 100 // Compile for AMS 1.00 or higher #define SAVE_SCREEN // Save/Restore LCD Contents //-------------------------------------------------------------------------- #include // Include All Header Files #include #include "defines.h" #include "kblib.h" #include "menulib.h" #include "tmde.h" #include "graphics.h" //--------------------------------------------------------------------------- // KBLIB variables extern short kb_state; extern short kb_state_DOWN; extern short kb_state_UP; //----------------------------------------------------------------------------- // menulib variables extern TMenu * Menu; //--------------------------------------------------------------------------- // tmde variables extern int FrameCounter; extern TCamera Camera; extern unsigned char * TileMap; extern unsigned short * TileData; extern TPoint8 TMSize; extern int scx; extern int scy; extern int TileMasked; extern int BlankSquare; extern int TilePalette; extern char * Plane0; extern char * Plane1; //-------------------------------------------------------------------------- TGame*Game; /* data_char list of chars : !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_' '0' -> index=15 'A' -> index=32 */ //--------------------------------------------------------------------------- // gangs_area byte gangs_area[4][6]= { {0 ,0 ,70 ,70 ,PED_SKIN_L,VEH_SKIN_L}, {0 ,150,80 ,240,PED_SKIN_S,VEH_SKIN_S}, {140,0 ,240,70 ,PED_SKIN_Y,VEH_SKIN_Y}, {140,150,240,240,PED_SKIN_Z,VEH_SKIN_Z}}; // gates_pos byte gates_pos[8]={52,53,54,55,124,125,126,127}; // secrets positions byte secrets_pos[10][2]= {{0,118},{40,26},{133,51},{205,104},{254,119}, {27,247},{83,129},{173,207},{217,247},{123,180}}; //--------------------------------------------------------------------------- // races checkpoints byte races_checkpoints[6][10][2]= {{{152,12},{232,13},{233,72},{205,73},{204,25},{187,25},{186,31},{170,31},{170,41},{179,41}}, {{167,66},{168,71},{233,73},{231,110},{166,110},{165,95},{153,94},{153,85},{113,84},{113,73}}, {{10,107},{13,11},{115,13},{115,63},{168,65},{168,109},{231,108},{231,14},{164,13},{164,30}}, {{6,246},{6,221},{18,221},{18,241},{80,241},{80,162},{57,162},{57,196},{73,196},{73,169}}, {{252,236},{252,131},{157,130},{157,159},{182,159},{183,141},{245,142},{245,119},{94,119},{93,242}}, {{92,242},{91,139},{53,138},{54,102},{126,103},{125,139},{94,138},{94,218},{241,219},{241,237}}}; // veh speeds (*SPEED_LCD) int veh_speeds[17]={ 3,2,3,4,3, 4,3,4,3,3, 2,2,3,5,4, 4,3}; // races times int races_times[6]={80,80,125,170,150,150}; // save var char save_var[]="gtasav"; //-------------------------------------------------------------------------- char* Var_GetPtr(char*str) { HSym hs = SymFind(SYMSTR(str)); if (!hs.folder) return NULL; char*ptr = (char*)HeapDeref((DerefSym(hs))->handle); return (ptr+2); } //-------------------------------------------------------------------------- char* Var_Create(char*str,int size) { int size2=size+2; int size3=size2+2; HSym hsym = SymAdd (SYMSTR (str)); // HeapAlloc must be executed before DerefSym // because of possible garbage collection. HANDLE handle = HeapAlloc (size3); SYM_ENTRY *SymPtr = (DerefSym (hsym)); MULTI_EXPR *VarPtr = HeapDeref (SymPtr->handle = handle); char*ptr=VarPtr->Expr; VarPtr->Size = size2; // length of the variable data ptr+=size; *ptr++ = 0; // end-of-string marker *ptr++ = STR_TAG; // the last byte is the type (see STR_TAG) return (VarPtr->Expr); } //--------------------------------------------------------------------------- void NewGame(void) { // reset game data memset(Game,0,sizeof(TGame)); // Start by foot Game->motion_type=MT_PED; Game->MainPed = &Game->Peds[0]; Game->MainVeh = NULL; Game->MainVeh2 = NULL; // MainPed position TPed*P=Game->MainPed; Ped_Init(P); P->enable=1; MainPed_Init(); TMission*Miss=&Game->Miss; Miss->flag_begin=1; // get ready next mission // start with $5000 Game->Save.cash=5; // debug //Game->Save.fugitive_factor=4; // MISSIONS // debug -> jump to mission #X /* Game->Save.progress_story=10; Game->Save.progress_races=6; Game->Save.progress_secrets=10; */ } //--------------------------------------------------------------------------- void MainPed_Init(void) { // position (163,45) Game->MainPed->MD.Pos.y = (16*163)+4; Game->MainPed->MD.Pos.x = (16*45)+4; // angle Game->MainPed->MD.angle=0; Ped_OnNewAngle(Game->MainPed); Game->MainPed->MD.speed=0; Game->MainPed->CC_behaviour=BH_Ped_None; Game->MainPed->skin=PED_SKIN_CIV; // health - ammo Game->MainPed->health=MAINPED_HEALTH_INIT; Game->MainPed->bullets=99; } //--------------------------------------------------------------------------- void PlaceCamera(void) { // viewer - debug if (Game->viewer_active) { Camera.Position.y = Game->viewer_y; Camera.Position.x = Game->viewer_x; return; } // place given motion type if (Game->motion_type==MT_PED) { Camera.Position.x = Game->MainPed->MD.Pos.x+4; Camera.Position.y = Game->MainPed->MD.Pos.y+4; } else { Camera.Position.x = Game->MainVeh->MD.Pos.x+8; Camera.Position.y = Game->MainVeh->MD.Pos.y+8; } // shake it ! if (Game->bShakeCamera) { Camera.Position.x+=(random(16)-8); Camera.Position.y+=(random(16)-8); } } //--------------------------------------------------------------------------- void DrawSprites(void) { int a; TileMasked=1; TilePalette=PAL_0123; // ***** Target ***** // tn=0x8F TMission*Miss=&Game->Miss; if (Miss->target_enable) { short*src=TileData+MUL32(0x8F); TPoint PP; if (Miss->target_type==TT_PLACE) // TT_PLACE PP=Miss->target_PP; else // TT_VEH PP=Miss->target_V->MD.Pos; if (FrameCounter&1) DrawSprite16(PP.x,PP.y,src); } // race // tn=0x8F if (Game->Save.progress_races<6) { int ry=MUL16(races_checkpoints[Game->Save.progress_races][Game->race_cpindex][0]); int rx=MUL16(races_checkpoints[Game->Save.progress_races][Game->race_cpindex][1]); short*src=TileData+MUL32(0x8F); DrawSprite16(rx,ry,src); } // secret // tn=0x86 if (Game->Save.progress_secrets<10) { int sy=secrets_pos[Game->Save.progress_secrets][0]; int sx=secrets_pos[Game->Save.progress_secrets][1]; if (FrameCounter&1) DrawSprite16(MUL16(sx),MUL16(sy),TileData+MUL32(0x86)); } // ***** PEDS ***** char pskin_str[]="-CLSYZ"; TPed*P=Game->Peds; for (a=0;aenable && !Ped_IsIntoVeh(P)) { int x=P->MD.Pos.x; int y=P->MD.Pos.y; // get TD ptr, since state changes each frame Ped_LoadTD(P); if (P->skin!=PED_SKIN_CIV) { char ch=pskin_str[P->skin]; DrawSprite8(x,y-8,CharGetData(ch)); } DrawSprite8(x,y,P->TileData); } // ***** VEHS ***** TVeh*V=Game->Vehs; for (a=0;aenable) { if (V->health==0) TilePalette=PAL_0333; else if (V->health==1) TilePalette=((FrameCounter&1)?PAL_0123:PAL_0333); else TilePalette=PAL_0123; DrawSprite16(V->MD.Pos.x,V->MD.Pos.y,V->TileData); } // ***** Bullets ***** TBullet*B=Game->Bullets; for (a=0;aenable) { int tn=(B->MD.angle&7); char*src=data_bullets+MUL16(tn); DrawSprite8(B->MD.Pos.x,B->MD.Pos.y,src); } TileMasked=0; TilePalette=PAL_0123; // ***** Garage Roofs ***** BlankSquare=1; DrawRoof(GARAGE1_SPRAY,0x96,0x97,0x96,0x97); DrawRoof(GARAGE1_CRUSHER,0xA7,0xA7,0xA7,0xA7); DrawRoof(GARAGE1_VEHPARK,0x90,0x91,0xA0,0xA1); DrawRoof(GARAGE2_SPRAY,0x96,0x97,0x96,0x97); DrawRoof(GARAGE2_CRUSHER,0xA7,0xA7,0xA7,0xA7); DrawRoof(GARAGE2_VEHPARK,0x90,0x91,0xA0,0xA1); DrawRoof(GARAGE2_VEHPARK2,0x99,0x9A,0xA9,0xAA); DrawRoof(GARAGE2_BOMB,0x9C,0x9D,0xAC,0xAD); BlankSquare=0; // gates // gates positions // y=gates_pos && x=118 // tn=0x98 // 118*16=1888 short*src=TileData+MUL32(0x98); for (a=0;a<8;a++) DrawSprite16(1888,MUL16(gates_pos[a]),src); } //--------------------------------------------------------------------------- void DrawRoof(byte y,byte x,byte tn00,byte tn01,byte tn10,byte tn11) { int yy=MUL16((int)y); int xx=MUL16((int)x); DrawSprite16(xx,yy,TileData+MUL32(tn00)); DrawSprite16(xx+16,yy,TileData+MUL32(tn01)); DrawSprite16(xx,yy+16,TileData+MUL32(tn10)); DrawSprite16(xx+16,yy+16,TileData+MUL32(tn11)); } //--------------------------------------------------------------------------- void DrawWindows(void) { // Mission Target : bottom - left TMission*Miss=&Game->Miss; TPoint PS1=Game->MainPed->MD.Pos; TPoint PS2=Game->MainVeh->MD.Pos; TPoint PS=(Game->motion_type==MT_PED?PS1:PS2); if (Miss->target_enable) { TPoint PP; if (Miss->target_type==TT_PLACE) // TT_PLACE PP=Miss->target_PP; else // TT_VEH PP=Miss->target_V->MD.Pos; int angle=GetFastAngle16(PS,PP); DrawWinTile8(0,92,data_arrows+MUL16(angle)); } // race target : top - left if (Game->Save.progress_races<6) { TPoint PR; int ry=MUL16(races_checkpoints[Game->Save.progress_races][Game->race_cpindex][0]); int rx=MUL16(races_checkpoints[Game->Save.progress_races][Game->race_cpindex][1]); PR.y=ry; PR.x=rx; int angle=GetFastAngle16(PS,PR); DrawWinTile8(0,0,data_arrows+MUL16(angle)); } // race timer : top-right if (Game->race_timer_visible) { int v=Game->race_timer; int v0='0'; int v1='0'; int v2='0'; while (v>=100) {v-=100;v0++;} while (v>=10) {v-=10;v1++;} while (v>=1) {v-=1;v2++;} DrawWinTile8(136,0,CharGetData(v0)); DrawWinTile8(144,0,CharGetData(v1)); DrawWinTile8(152,0,CharGetData(v2)); } } //--------------------------------------------------------------------------- void ShakeCamera(void) { int a; Game->bShakeCamera=1; // 16 screen refreshes for (a=0;a<16;a++) DrawScreen(); Game->bShakeCamera=0; } //-------------------------------------------------------------------------- void KB_ProcessMisc(void) { Game->exit_game=0; // viewer if (Game->viewer_active) { if (kb_state&KEYFLAGS_DOWN) Game->viewer_y+=8; if (kb_state&KEYFLAGS_UP) Game->viewer_y-=8; if (kb_state&KEYFLAGS_RIGHT) Game->viewer_x+=8; if (kb_state&KEYFLAGS_LEFT) Game->viewer_x-=8; } // OTHER KEYS if (kb_state_DOWN&KEYFLAGS_PLUS) OSContrastUp(); if (kb_state_DOWN&KEYFLAGS_MINUS) OSContrastDn(); if (kb_state_DOWN&KEYFLAGS_ESC) { Menu_Pause(); } if (kb_state_DOWN&KEYFLAGS_SHIFT) off(); // debug - screnshot //if (kb_state_DOWN&KEYFLAGS_ENTER) //WaitForKeyDOWN(KEYFLAGS_2ND); } //--------------------------------------------------------------------------- void KB_ProcessGame(void) { if (Game->motion_type==MT_PED) KeysForPed(); else KeysForVeh(); } //--------------------------------------------------------------------------- void KeysForPed(void) { TPed*P=Game->MainPed; TMotionData*MD=&P->MD; P->turn_ease++; int speed_step=64; int speed_max=SPEED_LCD; // SPEED if (kb_state&KEYFLAGS_2ND) { if (MD->speed_way) { MD->speed-=speed_step; if (MD->speed<0) {MD->speed=0;MD->speed_way^=1;} } else { MD->speed+=speed_step; if (MD->speed>speed_max) MD->speed=speed_max; } } else if (kb_state&KEYFLAGS_DOWN) { if (MD->speed_way) { MD->speed+=16; if (MD->speed>speed_max) MD->speed=speed_max; } else { MD->speed-=16; if (MD->speed<0) {MD->speed=0;MD->speed_way^=1;} } } // SLOW DOWN else { MD->speed-=speed_step; if (MD->speed<0) MD->speed=0; } // ANGLE if (!(P->turn_ease&1)) { if (kb_state&KEYFLAGS_LEFT) { MD->speed_way?MD->angle++:MD->angle--; MD->angle&=15; } if (kb_state&KEYFLAGS_RIGHT) { MD->speed_way?MD->angle--:MD->angle++; MD->angle&=15; } } // OTHER KEYS if (kb_state_DOWN&KEYFLAGS_ALPHA) Ped_Shoot(P); if (kb_state_DOWN&KEYFLAGS_DIAMOND) Veh_GoInto(); } //--------------------------------------------------------------------------- void KeysForVeh(void) { TVeh*V=Game->MainVeh; TMotionData*MD=&V->MD; V->turn_ease++; int speed_step=16; int speed_max=SPEED_LCD*veh_speeds[V->skin]; // SPEED if (kb_state&KEYFLAGS_2ND) { if (MD->speed_way) { MD->speed-=speed_step; if (MD->speed<0) {MD->speed=0;MD->speed_way^=1;} } else { MD->speed+=speed_step; if (MD->speed>speed_max) MD->speed=speed_max; } } else if (kb_state&KEYFLAGS_DOWN) { if (MD->speed_way) { MD->speed+=16; if (MD->speed>speed_max) MD->speed=speed_max; } else { MD->speed-=16; if (MD->speed<0) {MD->speed=0;MD->speed_way^=1;} } } // SLOW DOWN else { MD->speed-=16; if (MD->speed<0) MD->speed=0; } // ANGLE if (!(V->turn_ease&3) && MD->speed) { if (kb_state&KEYFLAGS_LEFT) { MD->speed_way?MD->angle++:MD->angle--; MD->angle&=15; } if (kb_state&KEYFLAGS_RIGHT) { MD->speed_way?MD->angle--:MD->angle++; MD->angle&=15; } } // OTHER KEYS if (kb_state_DOWN&KEYFLAGS_DIAMOND) Veh_GetOut(); if (kb_state_DOWN&KEYFLAGS_ENTER && Game->Save.game_finished) SelectVehicle(); } //--------------------------------------------------------------------------- void ShowStats(void) { TSave*S=&Game->Save; PortSet(GetPlane(0),239,127); ClrScr(); PortSet(GetPlane(1),239,127); ClrScr(); // ShowStats FontSetSys(0); clrscr(); int perc = (100*(S->progress_story+S->progress_races+S->progress_secrets))/26; printf("Progress : %d %% \n",perc); printf("Cash : $%d000 \n",S->cash); printf("Missions completed : %d/10 \n",S->progress_story); printf("Races completed : %d/6 \n",S->progress_races); printf("Secrets found : %d/10 \n",S->progress_secrets); printf("Vehicles hijacked : %d \n",S->vehs_hijacked); printf("Vehicles crushed : %d \n",S->vehs_crushed); printf("Vehicles blown up : %d \n",S->vehs_blown); printf("Vehicles resprayed : %d \n",S->vehs_resprayed); printf("Pedestrians killed : %d \n",S->peds_killed); int pt=S->playing_time; int m=pt/60; int s=pt%60; printf("Playing time : %03d:%02d \n",m,s); printf("Fugitive factor : %d/4 \n",S->fugitive_factor); printf("Wasted counter : %d \n",S->wasted_counter); printf("Busted counter : %d \n",S->busted_counter); FontSetSys(1); PortRestore(); WaitForKeyDOWN(KEYFLAGS_2ND); WaitForAllKeysReleased(); } //--------------------------------------------------------------------------- void Menu_Options(void) { for (;;) { MenuNew2(); MenuAddTitle("Options"); char buffer[64]; sprintf(buffer,"White Streets : %s",Game->Save.white_streets?"Yes":"No"); MenuAddItem(buffer); sprintf(buffer,"White Paving : %s",Game->Save.white_paving?"Yes":"No"); MenuAddItem(buffer); sprintf(buffer,"Back"); MenuAddItem(buffer); MenuDo(); if (Menu->Index==0) Game->Save.white_streets^=1; if (Menu->Index==1) Game->Save.white_paving^=1; else if (Menu->Index==2) break; } } //--------------------------------------------------------------------------- void Menu_Pause(void) { for (;;) { MenuNew2(); MenuAddTitle("Pause Menu"); MenuAddItem("Continue"); MenuAddItem("Stats"); MenuAddItem("Options"); MenuAddItem("Save Game"); MenuAddItem("Quit"); MenuDo(); if (Menu->Index==0) break; else if (Menu->Index==1) ShowStats(); else if (Menu->Index==2) Menu_Options(); else if (Menu->Index==3) Game_Save(); else if (Menu->Index==4) { MenuNew2(); MenuAddTitle("Quit?"); MenuAddItem("No"); MenuAddItem("Yes"); MenuDo(); if (Menu->Index==1) { Game->exit_game=1; break; } } } } //--------------------------------------------------------------------------- void ShowMsg(char*str) { PortSet(GetPlane(0),239,127); ClrScr(); PortSet(GetPlane(1),239,127); ClrScr(); FontSetSys(0); clrscr(); printf(str); printf("\n\n"); printf("Press ENTER..."); FontSetSys(1); PortRestore(); WaitForKeyDOWN(KEYFLAGS_ENTER); WaitForAllKeysReleased(); } //--------------------------------------------------------------------------- void Game_Save(void) { char*ptr=Var_GetPtr(save_var); // check if var already exists if (!ptr) { ptr=Var_Create(save_var,sizeof(TSave)); } else { MenuNew2(); MenuAddTitle("OverWrite ?"); MenuAddItem("No"); MenuAddItem("Yes"); MenuDo(); if (Menu->Index==0) return; } memcpy(ptr,&Game->Save,sizeof(TSave)); ShowMsg("Game Saved!"); } //--------------------------------------------------------------------------- void Game_Load(void) { char*ptr=Var_GetPtr(save_var); if (!ptr) { ShowMsg("No Saved Game!"); return; } memcpy(&Game->Save,ptr,sizeof(TSave)); } //--------------------------------------------------------------------------- /* "void SelectVehicle(void)" previously used for MIDTOWN MADNESS enabled function in GTA, when game finished */ void SelectVehicle(void) { int x=0; int y=0; ClearGrayScreen2B(GetPlane(0),GetPlane(1)); // 16*2*16 = 512 for (y=0;y<4;y++) for (x=0;x<5;x++) if ((5*y+x)VP_Veh+MUL512(5*y+x); GraySprite16_OR(16*x,16*y,16,src,src+16,GetPlane(0),GetPlane(1)); } // cursor x=0; y=0; for (;;) { short*src=TileData+MUL32(0x8F); GraySprite16_XOR(16*x,16*y,16,src,src+16,GetPlane(0),GetPlane(1)); WaitForKeyDOWN(0xFFFF); GraySprite16_XOR(16*x,16*y,16,src,src+16,GetPlane(0),GetPlane(1)); if (kb_state&KEYFLAGS_LEFT && x>0) x--; if (kb_state&KEYFLAGS_RIGHT && x<4) x++; if (kb_state&KEYFLAGS_UP && y>0) y--; if (kb_state&KEYFLAGS_DOWN && y<3) y++; if (kb_state&KEYFLAGS_2ND && (5*y+x)MainVeh; V->skin=(5*y+x); Veh_LoadTD(V); //WaitForKeyDOWN(KEYFLAGS_2ND); //WaitForAllKeysReleased(); } //-------------------------------------------------------------------------- /* Show gangs respective vehs, peds representation, names */ void ShowGroups(void) { ClearGrayScreen2B(Plane0,Plane1); // CLSYZ char symbols[5]={'C','L','S','Y','Z'}; int vehids[5]={VEH_SKIN_COP,VEH_SKIN_L,VEH_SKIN_S,VEH_SKIN_Y,VEH_SKIN_Z,}; char* labels[5]={"COP","LOONY","SCIENTIST","YAKUSA","ZAIBATSU"}; int a=0; for (a=0;a<5;a++) { // symbol - 0,0 DrawWinTile8(0,0+20*a,CharGetData(symbols[a])); // ped - 0,8 DrawWinTile8(0,8+20*a,Game->VP_Ped+16); // veh - 16,0 DrawWinTile16(16,0+20*a,Game->VP_Veh+MUL512(vehids[a])); // label - 48,0 char*str=labels[a]; int b=0; for (b=0;b<(signed)strlen(str);b++) DrawWinTile8(48+8*b,0+20*a,CharGetData(str[b])); } FastCopyScreen (Plane0,GetPlane(0)); FastCopyScreen (Plane1,GetPlane(1)); WaitForKeyDOWN(KEYFLAGS_2ND); WaitForAllKeysReleased(); } //-------------------------------------------------------------------------- /* get char tile pattern from char */ char* CharGetData(char ch) { if (ch>='A' && ch<='Z') return data_char+MUL16((int)(32+ch-'A')); else if (ch>='0' && ch<='9') return data_char+MUL16((int)(15+ch-'0')); else return data_char; } //-------------------------------------------------------------------------- /* 16 possible angles : 0-15 get angle from P1 to P2 */ int GetFastAngle16(TPoint Point1, TPoint Point2) { // trigonometric view int dx = Point2.x-Point1.x; int dy = -(Point2.y-Point1.y); int cos8[16]={7,6,4,1,-1,-4,-6,-7,-7,-6,-4,-1,1,4,6,7}; int sin8[16]={1,4,6,7,7,6,4,1,-1,-4,-6,-7,-7,-6,-4,-1}; int a=0; for (a=0;a<16;a++) { int r0=a; int r1=((a+1)&15); // tests for lines 0 and 1 int p0=cos8[r0]*dy-sin8[r0]*dx; int p1=cos8[r1]*dy-sin8[r1]*dx; // between lines 0 and 1 if (p0>=0 && p1<0) return ((4-a)&15); } // else return 0; } //--------------------------------------------------------------------------- int GetTurnAngleWay(int angle1, int angle2) { // function not used /* // 0 - left // 1 - right int diff=((angle2-angle1)&15); return ((diff<=8)?1:0); */ return 0; } //--------------------------------------------------------------------------- byte GET_TN(byte x,byte y) { // function not used // word offset=(word)Game->TMSizeX*(word)y+(word)x; // return TileMap[offset]; return 0; } //--------------------------------------------------------------------------- // get tile ptr on tilemap from position byte* GET_PTR(byte x,byte y) { word offset=(word)Game->TMSizeX*(word)y+(word)x; return (byte*)(TileMap+offset); } //--------------------------------------------------------------------------- // takes care of variables using time void OnTimer(void) { int a; // TIMER = 1s if (Game->TimeCounter++<22) return; Game->TimeCounter=0; // race_timer Game->race_timer--; // stop_delay TVeh*V=Game->Vehs; for (a=0;aCC_flag_stopdelay) V->CC_flag_stopdelay--; TPed*P=Game->Peds; for (a=0;aCC_flag_stopdelay) P->CC_flag_stopdelay--; // dead_disappear_counter P=Game->Peds; for (a=0;adead_disappear_counter++; // flip - invisible_counter P=Game->Peds; for (a=0;ainvisible_counter++; V=Game->Vehs; for (a=0;ainvisible_counter++; // STATS - playing_time Game->Save.playing_time++; // MISSION TIMER // MISSIONS FLAGS if (Game->Miss.timer_enable) { if (Game->Miss.timer_value==1) { Game->Miss.timer_value=0; Game->Miss.flag_timer=1; } else if (Game->Miss.timer_value==0) { // } else { Game->Miss.timer_value--; } } // blow_timer V=Game->Vehs; for (a=0;aenable) if (V->health==1) if (V->blow_timer++==5) { Veh_Blow(V); } } //--------------------------------------------------------------------------- int Check_Wasted(void) { TPed*P=Game->MainPed; int r=(!P->health); return (r); } //--------------------------------------------------------------------------- int Check_Busted(void) { // must be wanted if (!Game->Save.fugitive_factor) return 0; TPed*P=Game->MainPed; // must be by foot if (Ped_IsIntoVeh(P)) return 0; // CHECK BUSTED // ie if any cop close to mainped TPed*P2=Game->Peds; int a=0; for (a=0;aenable && P2->health && !Ped_IsIntoVeh(P2) && P2->skin==PED_SKIN_COP) { int dx=P2->MD.Pos.x-P->MD.Pos.x; int dy=P2->MD.Pos.y-P->MD.Pos.y; int c=(abs(dx)<4 && abs(dy)<4); if (c) return 1; } return (0); } //--------------------------------------------------------------------------- // Main Function void _main(void) { TGame GameA; Game=&GameA; TMenu MenuA; Menu = &MenuA; // LOAD VAR PTRS short*VP_TileData = (unsigned short*)Var_GetPtr("gtatd"); char*VP_TileMap1 = (unsigned char*)Var_GetPtr("gtatm"); short*VP_Veh = (unsigned short*)Var_GetPtr("gtaveh"); if (!VP_TileData) return; if (!VP_TileMap1) return; if (!VP_Veh) return; // LOAD TILEMAP byte*ptr=(byte*)VP_TileMap1; TMSize.y=*ptr++; TMSize.x=*ptr++; TileMap=ptr; TileData = VP_TileData; randomize(); TMDE_Enable(); // AUTHOR INFO FontSetSys(0); clrscr(); printf("Grand Theft Auto : Sin City \n\n"); printf("Version 1.2 \n\n"); printf("Programmed by Olivier Sangala \n"); printf("http://olivier.sangala.free.fr \n"); printf("olivier_sangala@hotmail.com \n"); FontSetSys(1); ngetchx(); // KB_Enable KB_Enable(); WaitForAllKeysReleased(); GrayOn(); for (;;) { MenuNew2(); MenuAddTitle("Main Menu"); MenuAddItem("New Game"); MenuAddItem("Continue"); MenuAddItem("Quit"); MenuDo(); if (Menu->Index==0 || Menu->Index==1) { // NEW GAME NewGame(); Game->VP_Ped=data_peds; Game->VP_TileData=VP_TileData; Game->VP_TileMap1=VP_TileMap1; Game->VP_Veh=VP_Veh; // TMSize Game->TMSizeY=TMSize.y; Game->TMSizeX=TMSize.x; // debug - viewer /* Game->viewer_active = 1; Game->viewer_y = (16*TMSize.y)/2; Game->viewer_x = (16*TMSize.x)/2; */ // if continue if (Menu->Index==1) Game_Load(); // ShowGroups ShowGroups(); // MAIN LOOP for (;;) { // LCD TICK DrawScreen(); // GET KB STATE GetKeyboardState(); // MISC KEYS KB_ProcessMisc(); if (Game->exit_game) break; // IMPORTANT // busted / wasted -> mission end int wasted_flag=Check_Wasted(); int busted_flag=Check_Busted(); if (wasted_flag || busted_flag) { // mission end TMission*Miss=&Game->Miss; if (Miss->step>=1) // if mission started Miss_Lose(); // busted / wasted if (wasted_flag) { Game->Save.wasted_counter++; ShowMsg("Wasted !"); } if (busted_flag) { Game->Save.busted_counter++; ShowMsg("Busted !"); } // fugitive_factor Game->Save.fugitive_factor=0; // if into vehicle -> get out TPed*P=Game->MainPed; P->MD.speed = 0; Game->motion_type=MT_PED; Game->MainVeh=NULL; Game->MainVeh2=NULL; // remove ammo P->bullets=0; // initial place MainPed_Init(); continue; } // GAME PROCESS OnTimer(); Motion_Tick(); Miss_Code(); // flag_shake if (Game->flag_shake) { Game->flag_shake=0; ShakeCamera(); } // respray if (VehInGarage(GARAGE1_SPRAY) || VehInGarage(GARAGE2_SPRAY)) if (Game->Save.fugitive_factor || Game->MainVeh->health!=VEH_HEALTH) if (Game->Save.cash>=1) // if enough cash ($1000) { ShowMsg("Resprayed!!"); Game->Save.cash-=1; // costs $1000 Game->Save.vehs_resprayed++; Game->Miss.flag_respray=1; Game->Miss.ResprayVeh=Game->MainVeh; Game->MainVeh->health=VEH_HEALTH; Game->Save.fugitive_factor=0; } // crusher if (VehInGarage(GARAGE1_CRUSHER) || VehInGarage(GARAGE2_CRUSHER)) { ShowMsg("Crushed!!"); Game->Save.vehs_crushed++; Game->Miss.flag_crushed=1; Game->Miss.CrushedVeh=Game->MainVeh; Miss_GarageOut(); } // flag_secret if (Game->flag_secret) { Game->flag_secret=0; Game->Save.progress_secrets++; ShowMsg("You found a secret!!!"); if (Game->Save.progress_secrets==10) { ShowMsg("Congratulations!! You found all secrets!!"); } } // race_timer if (Game->race_cpindex!=0 && Game->race_timer==0) { Game->race_cpindex=0; Game->race_timer_visible=0; ShowMsg("Time is out for race!"); } // flag_race if (Game->flag_race) { Game->flag_race=0; // start race if (Game->race_cpindex==0) { Game->race_timer=races_times[Game->Save.progress_races]; Game->race_timer_visible=1; } Game->race_cpindex++; if (Game->race_cpindex==10) { Game->race_cpindex=0; Game->race_timer_visible=0; Game->Save.progress_races++; ShowMsg("Congratulations! You completed this race!"); if (Game->Save.progress_races==6) { ShowMsg("Congratulations!! You completed all races!!"); } } } // gates_open if (!Game->Save.gates_open) { if (Game->Save.progress_story>=5 && Game->Save.progress_races>=3 && Game->Save.progress_secrets>=5) { Game->Save.gates_open=1; ShowMsg("Information : midtown gates are opened. You can now reach east side city!"); } } // game_finished if (!Game->Save.game_finished) { if (Game->Save.progress_story>=10 && Game->Save.progress_races>=6 && Game->Save.progress_secrets>=10) { Game->Save.game_finished=1; ShowMsg("Congratulations!!!! You finished the game!!!!"); ShowMsg("Check out ENTER key when you're driving..."); } } } } else if (Menu->Index==2) { break; } } // KB_Disable GrayOff(); WaitForAllKeysReleased(); KB_Disable(); TMDE_Disable(); }