WORKSHOP CODING INTROS & DEMOS

General Programming help in C, C++ or ASM, Compiling / Debugging, and R3000A Central Processing Unit (CPU) information
User avatar
inc^lightforce
Psy-Q Enthusiast
Psy-Q Enthusiast
Posts: 162
Joined: March 7th, 2013, 7:34 am
I am a: Programmer Windows+PS1, GFX Artist
PlayStation Model: Black
Skype: a5recordings
Location: Germany

Re: WORKSHOP CODING INTROS & DEMOS

Post by inc^lightforce » June 25th, 2020, 2:01 pm

another day another tutorial

This simple Tutorial should help all beginner to get into the matter of Demo/ Cracktro Coding.

Image

all necessary files you will find attached to this post

don't forget to fix the path in the batch files

- i made a "TimTool_Map.PSX" for the used images. Load this MAP into the TimTool and find out what's happen here.

regards

Today:
- coding a Snowstorm
- a Lava Wobbler
- displaying correctly a 2 tiled Background Picture ( made by SUPERWILL29 )
- playing music
- and have a nice sinus scroll text

Code: Select all

//--------------------------------------------------------------------------
//
// - just a simple democode to display a separated 16 bit Background image
// - a 16 bit Font Image
// - a lava like Wobbler
// - Snow on 4 planes with GsLine
// - Music
// 
//   to run the Demo directly after compiling use the following Batch Command:
//
//   ePSXe.exe demo.exe -nogui
//
//   have a closer look in the Batch File, alter your personal path
//
//
//	 This Sourcecode Blueprint was altered for you from different Projects
//   that i made in the late nineties 
//  
//	 Inc^Lightforce in June 2020
//
//   our retro webpage from the Paradox days: 
//   http://www.inc-games-design.de/oldHosting/UCA/news.html
//
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// I N C L U D E S
//--------------------------------------------------------------------------
#include <sys/types.h>
#include <stdlib.h>
#include <libetc.h>
#include <libgte.h>
#include <libgpu.h>
#include <libgs.h>
#include <libsnd.h>
#include <libmath.h>
#include <libspu.h>
#include "hitmod.h" 	// MUSIC PLAYER
#include "pad.h"		// USE GAMEPAD
#include "sinuss.h"		// SINUS FOR SCROLLER
#include "colorsin.h"   // SINUS MIX for WOBBLER
#include "sinstuff.h"   // SINUS MIX for WOBBLER
//---------------------------------------------------------------------
// ASM ADRESS DEFINITION
//---------------------------------------------------------------------
#define NOP	 0x00000000
#define PAL	 0x24020001
#define	NTSC 0x24020000
//---------------------------------------------------------------------
#define ORDERING_TABLE_LENGTH (12)
#define MAX_NO_PACKETS  (4000)
#define	rnd(max)	((rand()*(max))/(32768)+1)
#define SCRSPEED 2   // Scrollspeed Scroll Text
#define YPOS     100 // Y-Position Scroll Text
//---------------------------------------------------------------------
// STARS as SNOW
//---------------------------------------------------------------------
#define STARSC 1000 // Amount of Stars
#define SPEED     1 // Max Scroll-Speed
#define PLANE     4 // Amount of Stars, Layers
//---------------------------------------------------------------------
//
// G L O B A L S
//
//---------------------------------------------------------------------
GsOT		othWorld[2];
GsOT_TAG	otWorld[2][1<<ORDERING_TABLE_LENGTH];
PACKET		out_packet[2][(MAX_NO_PACKETS * 24)];
u_long		PADstatus=0;	// Var to store PAD-Status
u_char      HZMode=MODE_NTSC;
int		    currentBuffer;	// actual Buffer for "double buffering"
int         v_countGFX=0, v_countCODE=0; // HSync Counter


int Xangle,Yangle,depth;
int Xangle2,Yangle2;
int iScrollOffset=0;
//---------------------------------------------------------------------
// LOCATE FILENAMES from Data\*.OBJ
//---------------------------------------------------------------------
extern char sound[];	// music
extern char font[];		// our scroll font
extern char LeftBck[];	// Background Image Left Side  ---> using a 320pix large Image can not displayed by PS1, thats why we split
extern char RightBck[]; // Background Image Right Side ---> using a 320pix large Image can not displayed by PS1, thats why we split
//---------------------------------------------------------------------
// DEFINE STARS COORDINATES
//---------------------------------------------------------------------
typedef struct
  {
  int x;              // X-Koordinate des Sterns   
  int y;              // Y-Koordinate des Sterns
  int z;              // PLANE-ID
  } STAR;

STAR Stars[STARSC];
GsLINE          line; // TO DISPLAY a DOT for our STARS
//---------------------------------------------------------------------
// DEFINE the vertical Wobble
//---------------------------------------------------------------------
GsGLINE		Wobble[320]; //Wobble Lines 

GsSPRITE	sprLeftBck;  // create Sprite from Background Image Left Side
GsSPRITE	sprRightBck; // create Sprite from Background Image Right Side

int Video_MODE=0;
//---------------------------------------------------------------------
//----------DEFINE TEXT and Sinus for our Scrollerl Wobble-------------
//---------------------------------------------------------------------
GsSPRITE      sprLetter;
static int iSinOff1=0;
#define MAXSINVALUE 256 // Sin-height

static char scrtxt[] = "             HELLO SUPERWILL29=== NOW A SMALL TEST INTRO TO CHECK OUT YOUR "                       "BACKGROUND IMAGE= THE SOUND IS PLAYING WELL=== "					   "I ALSO ADDED SOME SNOW AND A LAVA LIKE WOBBLER=== "					   "IF THE INTRO SHOULD START A GAME PRESS X AND PLAY====== CODE BY INC= 2020= "					   "MUSIC BY OTIS=               PEACE                  ";

char *pBaseText = scrtxt;
//--------------------------------------------------------------------------
//
// P R O T O T Y P E S
//
//--------------------------------------------------------------------------
void InitialiseGraphics(int,int,int); // Width, Height, MODE
void UpdateWorld();
void RenderWorld(char cClear);
void LoadTIMData (u_long *tMemAddress); // RAM -> VRam
void SetSpriteInfo(GsSPRITE *tSprite, u_long tMemAddress, long tX, long tY, int tCut);
void InitStars(void);
void MoveStars(void);
void init_Wobble(void);
void do_Wobble(void);
void DrawScroller(void);

int logosinoff=0;
int savedlogosin=0;
int logosinoff2=0;   //Wobble Sin
int savedlogosin2=0; //Wobble Sin
int anzfontabc=0;
static int isinit=0;
//--------------------------------------------------------------------------
//
//
//
// Procedure Main()
//
//
//
//--------------------------------------------------------------------------
int main()
{
	u_long lTmp1;
	u_long	*ficken;

	PadInit(0);     // Joypad Init

//---------------------------------------------------------------------
// Init the Line and prepare only a DOT for the STAR Procedure
//---------------------------------------------------------------------
InitStars();
//---------------------------------------------------------------------
// Setup the Video Mode for the first start
//---------------------------------------------------------------------
 if (*(char *)0xbfc7ff52=='E')	// E(urope) --> PAL; A(merica) and J(apan) both use NTSC
	{
		HZMode=MODE_PAL;
	}
	else
	{
		HZMode=MODE_NTSC;
	}
 InitialiseGraphics(320,240,HZMode); // GFX Init, inkl. Init akt. Buffer...
//---------------------------------------------------------------------
// Init the MOD Player and start music
//---------------------------------------------------------------------
	MOD_Init();
  	MOD_Load((u_char *) sound);
  	MOD_Start();
//---------------------------------------------------------------------
// LOCATE FILENAMES and load them from Data\*.OBJ
//---------------------------------------------------------------------
LoadTIMData((u_long*)font);
LoadTIMData((u_long*)RightBck);
LoadTIMData((u_long*)LeftBck);

init_Wobble(); // Init Wobble als GsGLINE´s
//---------------------------------------------------------------------
// Correct the Background Images to its right positions
//---------------------------------------------------------------------
SetSpriteInfo(&sprLeftBck,(u_long)LeftBck,0,0,0);
SetSpriteInfo(&sprRightBck,(u_long)RightBck,0,0,0);
sprLeftBck.mx=sprRightBck.mx=0;
sprRightBck.my=sprLeftBck.my=0;
//--------------------------------------------------------------------------  
// Init the Letters from our Font Image
//--------------------------------------------------------------------------  
   SetSpriteInfo(&sprLetter,(u_long)font,0,0,3); //x, y, z
   sprLetter.w=sprLetter.h=32;					 // height of one Letter
   sprLetter.mx=sprLetter.my=0;
   sprLetter.v=sprLetter.u=0;
{
   GsSortSprite(&sprLetter,&othWorld[currentBuffer],2);
   RenderWorld(1);
}
//--------------------------------------------------------------------------
// Show us a short Text on Startup
//--------------------------------------------------------------------------   
{
  int iTmp1;
  for (iTmp1=0;iTmp1<60;iTmp1+=1) // set time to stay ---> change 60

	{
		FntLoad(960,256);
		FntOpen(8,100,300,140,0,200);//x,y
		FntPrint("\t\tJust a simple Tutorial\n\n\t     by Inc of Lightforce\n\n\n\t\t\t ");
		RenderWorld(1);
		VSync(2);
	}
}
//--------------------------------------------------------------------------
//
//
// MAIN LOOP
//
//
//--------------------------------------------------------------------------
while(1)
 {
	int iTmp1,iTmp2,iTmp3,iTmp4,iTmp5;
	PADstatus=PadRead(4);
		if(PADstatus&Pad1x){Video_MODE=1; break;	} // press X on Pad - run Game in Pal Mode
		if(PADstatus&Pad1crc){Video_MODE=2; break;	} // press O on Pad - run Game in NTSC Mode

	do_Wobble(); // start the Lava Wobbler
	//--------------------------------------------------------------------------
	// DECLARE BOTH SIDES on the correct position of our BACKGROUND IMAGES
	//--------------------------------------------------------------------------
	sprLeftBck.x=0;
	sprLeftBck.y=sprRightBck.y=0;
	sprRightBck.x=160;

	GsSortFastSprite(&sprLeftBck,&othWorld[currentBuffer],10);
	GsSortFastSprite(&sprRightBck,&othWorld[currentBuffer],10);
	//--------------------------------------------------------------------------

	MoveStars();
	DrawScroller();  
	RenderWorld(60);
 }
	//--------------------------------------------------------------------------
	// If Pad Break, free Mem
	//--------------------------------------------------------------------------
	SpuInit();
	SpuQuit();
 	MOD_Stop();
	MOD_Free();
	//VSync(3);
	PadStop();
  	ResetGraph(0);
  	StopCallback();
//--------------------------------------------------------------------------
//
// PATCH Values if creating a PAL to NTSC Selector: Video_MODE==1 (PAL)
//			     							        Video_MODE==2 (NTSC)
//--------------------------------------------------------------------------
//
//if(Video_MODE==1)
//{
//ficken = (u_long *) 0x80063bbc; *ficken = 0x24020001; // Get Video
//ficken = (u_long *) 0x80063bc0; *ficken = NOP;        // Get Video
//
//ficken = (u_long *)0x80068dc8;  *ficken = 0x24910030; // X-Delta
//ficken = (u_long *)0x80068dcc;  *ficken = 0x24910030; // X-Delta
//}
//--------------------------------------------------------------------------
//
//
// IF PATCHING a PS1 GAME ADD THE CORRECT LOAD ADDRESS to START THE GAME
//
//
//--------------------------------------------------------------------------
// asm("nop");
// asm("j  0x80011bd8"); // ExecAdresse to run the Game
// asm("nop");
//return 0;
}
//--------------------------------------------------------------------------
//
//
// GLOBAL HARDWARE VALUES AND DEFINITIONS
//
//
//--------------------------------------------------------------------------
void InitialiseGraphics(int SCRWidth,int SCRHeight,int HZMode)
  {
   SetVideoMode(HZMode);

   if ((HZMode == MODE_NTSC) && (SCRHeight==256)) SCRHeight=240;
    
   GsInitGraph(SCRWidth, SCRHeight, GsNONINTER|GsOFSGPU, 0, 0);

    // define double buffering for draw mode
    //		(X-Coordinate , Y-Coordinate   -> Buffer 0 (0,0)
    //		 X-Coordinate , Y-Coordinate   -> Buffer 1 (0,YRes) )
   GsDefDispBuff(0, 0, 0, SCRHeight);
    // correct Errors from the Library
   if (SCRHeight == 256) GsDISPENV.screen.h=256;

   othWorld[0].length = ORDERING_TABLE_LENGTH;
   othWorld[1].length = ORDERING_TABLE_LENGTH;
   othWorld[0].org = otWorld[0];
   othWorld[1].org = otWorld[1];
   GsClearOt(0,0,&othWorld[0]);
   GsClearOt(0,0,&othWorld[1]);

    // get the current Buffer
   currentBuffer=GsGetActiveBuff();

   // create address for "Packet"
   GsSetWorkBase((PACKET*)out_packet[currentBuffer]);
  }
void RenderWorld(char cClear)
  {
    // ------------------------------------ "Old List"
   v_countCODE=VSync(1);
   DrawSync(0);
   v_countGFX = VSync(1);
   VSync(0);	// wait for the GPU until old List is ready

    // swap Buffer: (Display / Drawing)
   GsSwapDispBuff();

    // ------------------------------------ "Current List"

    // "register" a "ClearScreen"-Command in OT
    //  R, G, B
   if (cClear==1)  GsSortClear(0, 0, 0,&othWorld[currentBuffer]);
   if (cClear==60) GsSortClear(0, 0, 0,&othWorld[currentBuffer]);
   if (cClear==255)  GsSortClear(0, 0, 0,&othWorld[currentBuffer]);


    // start DrawMode (the GPU is drawing the OT in the background)
   GsDrawOt(&othWorld[currentBuffer]);
   FntFlush(-1);

    // ------------------------------------ "New List Liste"

    // init next OT !!!
    // get the current Buffer
    currentBuffer=GsGetActiveBuff();

    // set address for packet building
    GsSetWorkBase((PACKET*)out_packet[currentBuffer]);

    // delete the content of the OT
    GsClearOt(0, 0, &othWorld[currentBuffer]);

    // OT is now ready to receive GsSort... Commands
  }
void LoadTIMData(u_long *tMemAddress)
  {
  RECT tRect;
  GsIMAGE tTim;

  DrawSync(0);
  tMemAddress++;
  GsGetTimInfo(tMemAddress, &tTim);   // save TIM-Information in tTim
  tRect.x = tTim.px;
  tRect.y = tTim.py;
  tRect.w = tTim.pw;
  tRect.h = tTim.ph;
  LoadImage(&tRect, tTim.pixel);	 // load TIM-Data into the VideoRam
  DrawSync(0);

  if ((tTim.pmode >> 3) & 0x01)
    {
    tRect.x = tTim.cx;
    tRect.y = tTim.cy;
    tRect.w = tTim.cw;
    tRect.h = tTim.ch;
    LoadImage(&tRect, tTim.clut);	 // load CLUT into the VideoRam
    };

   DrawSync(0);					     // warte until the GPU is ready
  }
void SetSpriteInfo(GsSPRITE *tSprite, u_long tMemAddress, long tX, long tY, int tCut)
  {
  GsIMAGE tTim;					     // TIM image Information

  tMemAddress += 4;				     // Pointer to any Data
  GsGetTimInfo((u_long *) tMemAddress, &tTim);	// get TIM Info from tTim

  tSprite->x = tX;				     // set Coordinates according to
  tSprite->y = tY;				     // the Info at a Call

  switch (tTim.pmode & 3)			 // X-Value depending from the BitDepht
    {
    case 0: tSprite->w = tTim.pw << 2;
            tSprite->u = (tTim.px & 0x3f) * 4;
            break;
    case 1: tSprite->w = tTim.pw << 1;
            tSprite->u = (tTim.px & 0x3f) * 2;
            break;
    default: tSprite->w = tTim.pw;
             tSprite->u = tTim.px & 0x3f; 
    };

  tSprite->h = tTim.ph;
  tSprite->v = tTim.py & 0xff;

  tSprite->tpage = GetTPage((tTim.pmode & 3),0,tTim.px,tTim.py);

  tSprite->attribute = (tTim.pmode & 3) << 24;

  tSprite->cx = tTim.cx;			 // Set CLUT from Sprite
  tSprite->cy = tTim.cy;

  tSprite->r = tSprite->g = tSprite->b = 128;	// normal Intensiti (of Colors)
  // set as Standard
  tSprite->mx = tSprite->w/2;					// Reference the sprite to the middle coordinates
  tSprite->my = tSprite->h/2;					// not necessary

  tSprite->scalex = tSprite->scaley = ONE;	    // skale to 1 (normale Size)
  tSprite->rotate = 0;				            // Angle of rotation to 0

  if (tCut)					                    // trim Sprite if the Tim
    tSprite->w -= tCut;				            // have a "illegal" range
  };
//-------------------------------------------------------------------------------
// Procedure Scroller()
//-------------------------------------------------------------------------------
void DrawScroller(void)
{
  int iTmp1,iTmp2,iTmp3;
  char *pText;

  iSinOff1+=8;iSinOff1%=MAXSINVALUE;

  if (iScrollOffset<=-32) {pBaseText++;iScrollOffset+=32;}
  
  iScrollOffset-=SCRSPEED;

  if (*pBaseText==NULL) // Scroll End
     pBaseText=scrtxt;

     pText=pBaseText;   // Temp Textpointer

  for (iTmp1=0;iTmp1<30;iTmp1++) // view max 11 Letter
    {
		iTmp2=*pText;
		if (iTmp2) // If Letter >0
		{
			  if (iTmp2>'Z') iTmp2=' ';
			  iTmp2-=' ';
			  // Destination Coordinates
				 sprLetter.x=iScrollOffset+32*iTmp1;
				 iTmp3=SinusS1[(iSinOff1+sprLetter.x)%MAXSINVALUE];

				 sprLetter.y=YPOS+iTmp3; // Source Coordinates
				 sprLetter.x+= SinusS1[(iSinOff1+sprLetter.x)%MAXSINVALUE]*4/3;//2+logosin[logosinoff2]/2+logosin3[i]/2;
				 sprLetter.u=(iTmp2%8)*32;
				 sprLetter.v=(iTmp2/8)*32;
				 GsSortSprite(&sprLetter,&othWorld[currentBuffer],3); // "3" Scroller Z Order
				 pText++;
		}
    }
}
//-------------------------------------------------------------------------------
// EndProcedure Scroller
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
// Procedure STARS()
//-------------------------------------------------------------------------------
void InitStars(void)
  {
  int l,zi;
  srand(1);
  for(l=0;l<STARSC;l++)                
    {
    zi=rand()%320;
    Stars[l].x=zi;
    zi=rand()%240;
    Stars[l].y=zi;
    zi=rand()%PLANE;
    Stars[l].z=zi+1;
    }
  }
void MoveStars(void)
  {
  int i;
  for(i=0; i<STARSC; i++)
    {        
    Stars[i].y+=SPEED*Stars[i].z;
    if(Stars[i].y>320)
      Stars[i].y=0;
    line.x0 = line.x1 = Stars[i].x+colorsin[logosinoff2]+scalesin[i];
    line.y0 = line.y1 = Stars[i].y;//=240+logosin[logosinoff2]+2+logosin3[i];
    line.r = 255;
    line.g = line.b =Stars[i].z*255;
    GsSortLine(&line,&othWorld[currentBuffer],1);
    }
  }
//-------------------------------------------------------------------------------
// EndProcedure STARS
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
// Procedure LavaWobbler()
//-------------------------------------------------------------------------------
void init_Wobble()
{
int i=0;
for(i=0;i<241;i++)
  {
Wobble[i]=Wobble[0];
Wobble[i].y0=Wobble[i].y1=i;//80;
Wobble[i].x0=0;
Wobble[i].x1=50;//i;
Wobble[i].r0=Wobble[i].b0=Wobble[i].g0=0;
Wobble[i].r1=Wobble[i].b1=Wobble[i].g1=0;
  }
}
void do_Wobble()
{
int j;
int i;
logosinoff2=savedlogosin2;
for(i=0;i<241;i++)
{
j=i+1;
Wobble[i].r0=20;
Wobble[i].g0=147;
Wobble[i].b0=130;//colorsin;
Wobble[i].r1=0;
Wobble[i].g1=5;
Wobble[i].b1=65;//0;

Wobble[i].attribute=(2<<24)+(0<<29)+(1<<30);
Wobble[i].x0=10+logosin[logosinoff2]/2+logosin1[i]/2+colorsin[i]/2;
Wobble[i].x1=100+logosin[logosinoff2]/2+logosin3[i]/2;

GsSortGLine(&Wobble[i],&othWorld[currentBuffer], 1);
logosinoff2++;
if(logosinoff2==520)logosinoff2=0;
}
savedlogosin2++;
if(savedlogosin2==520) savedlogosin2=0;
}
//-------------------------------------------------------------------------------
// EndProcedure LavaWobbler()
//-------------------------------------------------------------------------------
inc.
You do not have the required permissions to view the files attached to this post.

User avatar
inc^lightforce
Psy-Q Enthusiast
Psy-Q Enthusiast
Posts: 162
Joined: March 7th, 2013, 7:34 am
I am a: Programmer Windows+PS1, GFX Artist
PlayStation Model: Black
Skype: a5recordings
Location: Germany

Re: WORKSHOP CODING INTROS & DEMOS

Post by inc^lightforce » July 4th, 2020, 7:32 am

another day another tutorial

i noticed that my tutorial for Trainer Coding is missing.

now here it comes:

Image

Code: Select all

//--------------------------------------------------------------------------
// I N C L U D E S
//--------------------------------------------------------------------------
#include <sys/types.h>
#include <stdlib.h>
#include <libetc.h>
#include <libgte.h>
#include <libgpu.h>
#include <libgs.h>
#include <libsnd.h>
#include <libmath.h>
#include <libspu.h>
#include "hitmod.h"
#include "pad.h"
#include "colorsin.h"

//-------------------- ASM ADRESS DEFINITION --------------------------
//---------------------------------------------------------------------
#define NOP		0x00000000
#define PAL		0x24020001
#define	NTSC		0x24020000
int Video_MODE=0;
//---------------------------------------------------------------------

#define ORDERING_TABLE_LENGTH (12)
#define MAX_NO_PACKETS  (4000)

//---------------------------------------------------------------------
//---------------------SINUS INCLUDE-----------------------------------
//---------------------------------------------------------------------
//#include        "sinuss.h"
// includes  short   SinusS1[]   //256 Values, min -15, max 15 , spd +2
//           short   SinusS2[]   // 256 Values, min -10, max 10, spd -1

//---------------------------------------------------------------------
//-------------DEFINITION STARS ind THE  BACKGROUND--------------------
//---------------------------------------------------------------------
#define STARSC         50 // how much stars ?
#define SPEED            1 // Max Scrollspeed
#define PLANE            4 // Layers for the stars
//#define	rnd(max)	((rand()*(max))/(32768)+1)

//---------------------------------------------------------------------
//--------------- define scroller ------------------------------
//---------------------------------------------------------------------
//#define SCRSPEED          2 // Scrollspeed text
//#define YPOS            207 // Y-Position  on screen - text

//--------------------------------------------------------------------------
// G L O B A L S
//--------------------------------------------------------------------------
GsOT		othWorld[2];
GsOT_TAG	otWorld[2][1<<ORDERING_TABLE_LENGTH];
PACKET		out_packet[2][(MAX_NO_PACKETS * 24)];
int		currentBuffer,delay=0;	// current buffer for "double buffering"
u_long		PADstatus=0;	// Var to store PAD-Status

int             v_countGFX=0, v_countCODE=0; // HSync counter
u_char          HZMode=MODE_PAL;
//-------------------------------------------------------------------------
// load external wobble picture
//-------------------------------------------------------------------------
//extern char al[];

//---------------------------------------------------------------------
//----------read external infos from our images-----------------
//---------------------------------------------------------------------
extern char intro[]; // sound
extern char lef[];  // left background image
extern char rig[]; // right background image

typedef struct
  {
  int x;              // X-Coordinate Stars
  int y;              // Y-Coordinate Stars
  int z;              // PLANE-ID
  } STAR;

STAR Stars[STARSC];
//---------------------------------------------------------------------
//---------- Font-Sprites & Textures related to our typer -------------
//---------------------------------------------------------------------
extern char font1[];
#define	PAGEW	(30)
#define	PAGEH	(8)

#define	ZEICHEN	(32)// <--- how much letters in one row of our Font-Image?
#define	ZEILEN	(3)// <---  how many rows of letters in our Font - Image?
#define	MAX_CHAR (PAGEH*PAGEW)

GsSPRITE fontspr[ZEICHEN * ZEILEN];
GsSPRITE page[MAX_CHAR];
//-----------------------------------------------------------------------------
//--------------------SPRITE DEFINITION---------------------------
//-----------------------------------------------------------------------------
GsSPRITE	sprLetter; // letter for our typer
GsSPRITE	sprLef; // left Background image
GsSPRITE	sprRig; // right Background image

GsLINE		line; //horizontal linie
GsGLINE		line2;// again
GsGLINE		line3;// and again
GsGLINE		line4;
GsGLINE		line5;
GsGLINE		line6;
GsGLINE		line7;

GsGLINE		Wobble[320]; //Wobble Lines 

//--------------------------------------------------------------------------
// P R O T O T Y P E S
//--------------------------------------------------------------------------
void InitialiseGraphics(int,int,int); // Width, Height, MODE
void UpdateWorld();
void RenderWorld(char cClear);

void LoadTIMData (u_long *tMemAddress); // RAM -> VRam
void SetSpriteInfo(GsSPRITE *tSprite, u_long tMemAddress, long tX, long tY, int tCut);

void init_LogoSprites(void);

void	init_Typer(void);
void	do_Typer(void);
void	init_Page(int);
void  InitStars(void);
void  MoveStars(void);
void  init_Wobble(void);
void  do_Wobble(void);
void  setFlags(void);
void	init_Menu(void);
void	do_Menu(void);

int logosinoff=0;
int savedlogosin=0;
int logosinoff2=0; //Wobble Sin
int savedlogosin2=0; //Wobble Sin
//-------------- ABC-table and scroll font for typer------------------
#define	FONT_W	(8)
#define	FONT_H	(10)
int anzfontabc=0;
static int isinit=0;
char fontabc[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789,.-+*#!\"%&/()=?;:ÖÄÜöäüß ";
//-----------------------
// Anzahl der Textseiten
//-----------------------
#define PAGES	18  // <------------ how many pages?

//-------------------------------
// here the pages
//-------------------------------
char texte[PAGEH*PAGES][PAGEW]=

{
//    1   5    10   15   20   25   30  SIGNS      max. SIGNS
//    |   |    |    |    |    |    |   
    {"                              "},// 1
    {"                              "},// 2
    {"   SPECIAL PREVIEW VERSION !  "},// 3
    {"                              "},// 4
    {"                              "},// 5
    {"      DO NOT DISTRIBUTE !     "},// 6
    {"                              "},// 7
    {"                              "},// 8
  
    {"                              "},// 1
    {"                              "},// 2
    {"                              "},// 3
    {"                              "},// 4
    {"                              "},// 5
    {"      M A I N  E R R O R      "},// 6
    {"                              "},// 7
    {"                              "},// 8

    {"                              "},// 1
    {"                              "},// 2
    {"                              "},// 3
    {"                              "},// 4
    {"                              "},// 5
    {"         PLEASE WAIT...       "},// 6
    {"                              "},// 7
    {"                              "},// 8

    {"                              "},// 1
    {"                              "},// 2
    {"                              "},// 3
    {"                              "},// 4
    {"                              "},// 5
    {"     UNDERCOVER - AGENTS      "},// 6
    {"                              "},// 7
    {"                              "},// 8

    {"                              "},// 1
    {"                              "},// 2
    {"                              "},// 3
    {"                              "},// 4
    {"                              "},// 5
    {"          BRINGS YOU          "},// 6
    {"                              "},// 7
    {"                              "},// 8

    {"                              "},// 1
    {"                              "},// 2
    {"                              "},// 3
    {"                              "},// 4
    {"      ALIEN RESURRECTION      "},// 5
    {"US by Fox Interactive (c) 2000"},// 6
    {"                              "},// 7
    {"                              "},// 8

    {"     UNDERCOVER - AGENTS      "},// 1
    {"                              "},// 2
    {"                              "},// 3
    {" Are very proud to present you"},// 4
    {"  a long awaited Game.....    "},// 5
    {"                              "},// 6
    {"   supplied by: JOE - COXS    "},// 7
    {"                              "},// 8

    {"     UNDERCOVER - AGENTS      "},// 1
    {"                              "},// 2
    {"Coding................... INC."},// 3
    {"Sound.................... INC."},// 4
    {"Graphix.................. INC."},// 5
    {"Pal 2 Ntsc Switch..... GANDHI."},// 6
    {"Trainer................ GOOSE."},// 7
    {"                              "},// 8 

    {"     UNDERCOVER - AGENTS      "},// 1
    {"                              "},// 2
    {"  Yes this time u can watch   "},// 3
    {"      our In-Game-Intro.      "},// 4
    {"                              "},// 5
    {"                              "},// 6
    {"                              "},// 7
    {"                              "},// 8

    {"     UNDERCOVER - AGENTS      "},// 1
    {"                              "},// 2
    {"                              "},// 3
    {"                              "},// 4
    {"( X ) for PAL - ( O ) for NTSC"},// 5
    {"                              "},// 6
    {"                              "},// 7
    {"                              "},// 8

    {"     UNDERCOVER - AGENTS      "},// 1
    {"                              "},// 2
    {" will Greet following Groups: "},// 3
    {"                              "},// 4
    {" - Paradox - Ulfc - Kalisto - "},// 5
    {"    - Trsi - TDD - Napalm -   "},// 6
    {"    - Hydrogen - Hitmen -     "},// 7
    {"                              "},// 8

    {"     UNDERCOVER - AGENTS      "},// 1
    {"                              "},// 2
    {"will Greet following Peoples: "},// 3
    {"                              "},// 4
    {"- Zero G. - Phantom - Manson -"},// 5
    {"  - Crazy - Lowang - Daisy -  "},// 6
    {" - Tursi - Obi Wahn - MrPs2 - "},// 7
    {"                              "},// 8

    {"     UNDERCOVER - AGENTS      "},// 1
    {"                              "},// 2
    {"are looking for motivated and "},// 3
    {"  skilled GFX + SFX + CODERS  "},// 4
    {"like you. Feel free to contact"},// 5
    {"us on Efnet Irc: #psx2german. "},// 6
    {"        Or try www HQ         "},// 7
    {"                              "},// 8

    {"                              "},// 1
    {" Special Greetings From Goose "},// 2
    {"                              "},// 2
    {"             to:              "},// 3
    {"                              "},// 4
    {" -Mr C Hurn- & -Mr Rick McQ-  "},// 5
    {"                              "},// 6
    {"                              "},// 7

    {"                              "},// 1
    {"                              "},// 2
    {"                              "},// 2
    {"                              "},// 3
    {"HTTP://GO.TO/UNDERCOVER-AGENTS"},// 4
    {"                              "},// 5
    {"                              "},// 6
    {"                              "},// 7

    {"                              "},// 1
    {"                              "},// 2
    {"                              "},// 2
    {"                              "},// 3
    {"    F A T A L   E R R O R     "},// 4
    {"  There is a life form from   "},// 5
    {"        ANOTHER WORLD         "},// 6
    {"                              "},// 7

    {"                              "},// 1
    {"                              "},// 2
    {"                              "},// 3
    {"                              "},// 3
    {"                              "},// 3
    {"   M A L F U N c T I O N !    "},// 4
    {"                              "},// 5
    {"                              "},// 6

    {"                              "},// 1
    {"                              "},// 2
    {"                              "},// 2
    {"                              "},// 2
    {"                              "},// 3
    {"         R E L O A D..        "},// 4
    {"                              "},// 5
    {"                              "},// 6

};



//---------------------------
// HOW MANY TRAINER OPTIONS
//---------------------------
#define NUMTRAIN	2
//-------------------------
// Lines for the TRAINER selection
//-------------------------
GsGLINE		mline[4];
//---------------------------
// the Traineroptions itself
//---------------------------
GsSPRITE	sprMenu[NUMTRAIN*40];
int			choice[NUMTRAIN];
char		options[NUMTRAIN*2][50]=
{
//	 |                                        |
	{"Internal Trainer:       No"},
	{"Research Mode:          No"},

	{"Internal Trainer:      Yes"},
	{"Research Mode:         Yes"},

};

//--------------------------------------------------------------------------
// Function:	main() 
// Description:	--
// Parameters:	--
// Returns:	int
// Notes:	N/A
//--------------------------------------------------------------------------
int main()
  {
u_long	*ficken;
  u_long lTmp1;
//-------------------- INIT DER SLIDINGS -----------------------------------
    int iLogoPos=0,iLogoSpd=1,iTmp1;
    int iPdxPos=640,iPdxSpd=2;	
    int iPdxPos1=800,iPdxSpd1=2;

  int i,j;
  int temp,temp1;
  int Move=0;
//-------------------------------------------------------------------------  
PadInit(0);     // Joypad Init
 
init_Typer();

if (*(char *)0xbfc7ff52=='E')	// E(urope) --> PAL; A(merica) and J(apan) both use NTSC
	{
		HZMode=MODE_PAL;
	}
	else
	{
		HZMode=MODE_NTSC;
	}
	InitialiseGraphics(320,240,HZMode); // GFX Init, incl. Init act. Buffer...

//--------------------------------------------------------------------------
//-------------------------LOAD MUSIC and PLAY------------------------
//--------------------------------------------------------------------------
MOD_Init();
MOD_Load((u_char *) intro); // our music
MOD_Start();
//--------------------------------------------------------------------------  
//------------------READ FROM THE EXTERNAL IMAGES-----------------------
//--------------------------------------------------------------------------  
LoadTIMData((u_long*)font1);
LoadTIMData((u_long*)lef);
LoadTIMData((u_long*)rig);

// GANDHI...
  for (iTmp1=0;iTmp1<10;iTmp1+=1)

   {
do_Typer();
    if (iTmp1==28) VSync(80); // wait...

    RenderWorld(1);
    }
// --------------------------- INIT LOGO -----------------------------------
SetSpriteInfo(&sprRig,(u_long)rig,235,121,3);//x,y
SetSpriteInfo(&sprLef,(u_long)lef,80,119,3);//x,y

//--------------------------------------------------------------------------  
init_Wobble(); // Init Wobble as GsGLINE´s
InitStars();
init_Menu();
// ------------------------------------
// --------   MAIL LOOP    --------
// ------------------------------------
   
while(1)
 {
int iTmp1,iTmp2,iTmp3,iTmp4,iTmp5;
   if(++delay==6)	delay=0;
   PADstatus=PadRead(4);
   if(PADstatus&Pad1x){Video_MODE=1; break;	} 
	if(PADstatus&Pad1crc){Video_MODE=2; break;	}

do_Typer();
do_Wobble();
do_Menu();

//----------------------------------------------------
//---------- DEFINITION FOR SPRITE's LAYERS -----------
//----------------------------------------------------
GsSortSprite(&sprLef,&othWorld[currentBuffer],3);
GsSortSprite(&sprRig,&othWorld[currentBuffer],3);
//----------------------------------------------------
//---------------SHOW us the STARS  --------------------
MoveStars();

RenderWorld(1);
  }
SpuInit();
	SpuQuit();
	MOD_Stop();
MOD_Free();
	//VSync(3);
	PadStop();
  	ResetGraph(0);
  	StopCallback();
	//-------------------------------------------------------------
	//------------------PATCH FUNCTION- DECRUNCH GAME------------
	//-------------------------------------------------------------
	EnterCriticalSection();
	depack1();
	ExitCriticalSection();
	copy_start();
	setFlags();
	//-------------------------------------------
	// add Patch for Video Mode ==1 (PAL)
	//			     Video_MODE==2 (NTSC)
	//-------------------------------------------

        if(Video_MODE==1)
        {
          ficken = (u_long *)0x80089dd8;      *ficken = 0x24020001; // Get Video
          ficken = (u_long *)0x80089ddc;      *ficken = NOP;        // Get Video

          ficken = (u_long *)0x80084654;         *ficken = 0x24900030; // X-Delta
          ficken = (u_long *)0x80084658;         *ficken = 0x24900030; // X-Delta
        }

//-------------------------------------------------------------
//************************* starts game ***********************
//-------------------------------------------------------------
asm("nop");
asm("j 0x8008656c"); // ExecAddress to load the Game
asm("nop");
//return 0;
  }

void InitStars(void)
  {
  int l,zi;
  srand(1);
  for(l=0;l<STARSC;l++)                
    {
    zi=rand()%320;
    Stars[l].x=zi;
    zi=rand()%160;
    Stars[l].y=zi;
    zi=rand()%PLANE;
    Stars[l].z=zi+1;
    }
  }

void MoveStars(void)
  {
  int i;

  for(i=0; i<STARSC; i++)
    {        
    Stars[i].x+=SPEED*Stars[i].z;
    if(Stars[i].x>320)
      Stars[i].x=0;
    line.x0 = line.x1 = Stars[i].x;
    line.y0 = line.y1 = Stars[i].y;
    line.r = rand()%250;		//1;
    line.g = 250- rand()%245;	
    line.b =Stars[i].z*50;

    GsSortLine(&line,&othWorld[currentBuffer],2);
    }
  }
//------------------------------------------------------------------------------
// F U N K T I O N S   D E F I N I T I O N E N
//------------------------------------------------------------------------------
void InitialiseGraphics(int SCRWidth,int SCRHeight,int HZMode)
  {
  SetVideoMode(HZMode);

  if ((HZMode == MODE_NTSC) && (SCRHeight==256)) SCRHeight=240;
  GsInitGraph(SCRWidth, SCRHeight, GsNONINTER|GsOFSGPU, 0, 0);
  GsDefDispBuff(0, 0, 0, SCRHeight);
  if (SCRHeight == 256) GsDISPENV.screen.h=256;
  othWorld[0].length = ORDERING_TABLE_LENGTH;
  othWorld[1].length = ORDERING_TABLE_LENGTH;
  othWorld[0].org = otWorld[0];
  othWorld[1].org = otWorld[1];
  GsClearOt(0,0,&othWorld[0]);
  GsClearOt(0,0,&othWorld[1]);
  currentBuffer=GsGetActiveBuff();
  GsSetWorkBase((PACKET*)out_packet[currentBuffer]);
  }
//------------------------------------------------------------------------------
// Function:	RenderWorld(char cClear)
// Description:	Diese Funktion ist zuständig für den DoubleBuffer...
//		(ordering tables etc)
// Parameters:	char cClear: bei True wird ein "CLS" der OT hinzugefügt
// Returns:	void
// Notes:	--
//------------------------------------------------------------------------------
void RenderWorld(char cClear)
  {
    // ------------------------------------ "Alte Liste"
  v_countCODE=VSync(1);
  DrawSync(0);
  v_countGFX = VSync(1);
  VSync(0);	// warte bis die GPU mit der "alten Liste" fertig ist
    // tausche die beiden Puffer (Display / Drawing)
  GsSwapDispBuff();
    // ------------------------------------ "aktuelle Liste"
    // "registriere" ein "ClearScreen"-Kommando im OT  R, G, B
if (cClear==1)  GsSortClear( 0, 0, 0,&othWorld[currentBuffer]); //hintergrundfarbe
if (cClear==155)  GsSortClear( 0,  0,  0,&othWorld[currentBuffer]);
    // starte den Zeichenvorgang (die GPU zeichnet die OT im Hintergrund)
  GsDrawOt(&othWorld[currentBuffer]);
  FntFlush(-1);
// ------------------------------------ "NEUE Liste"
  currentBuffer=GsGetActiveBuff();
  GsSetWorkBase((PACKET*)out_packet[currentBuffer]);
  GsClearOt(0, 0, &othWorld[currentBuffer]);
  }
//------------------------------------------------------------------------------
// Function:	LoadTIMData (u_long tMemAddress)
// Description:	transferiert ein .TIM File vom Hauptspeicher ins VideoRam
// Parameters:	u_long tMemAddress - Adresse des TIMs im Hauptspeicher
// Returns:	void
// Notes:	--
//------------------------------------------------------------------------------

void LoadTIMData(u_long *tMemAddress)
  {
  RECT tRect;
  GsIMAGE tTim;

  DrawSync(0);
  //tMemAddress += 4;                             // pointer auf Datenbeginn setzen
  tMemAddress++;
  GsGetTimInfo(tMemAddress, &tTim);   // TIM-Informationen in tTim speichern
  tRect.x = tTim.px;
  tRect.y = tTim.py;
  tRect.w = tTim.pw;
  tRect.h = tTim.ph;
  LoadImage(&tRect, tTim.pixel);		// Lade TIM-Daten ins VideoRam
  DrawSync(0);

  if ((tTim.pmode >> 3) & 0x01)
    {
    tRect.x = tTim.cx;
    tRect.y = tTim.cy;
    tRect.w = tTim.cw;
    tRect.h = tTim.ch;
    LoadImage(&tRect, tTim.clut);		// lade CLUT ins VideoRam
    };

  DrawSync(0);					// warte bis GPU fertig ist
  }
//------------------------------------------------------------------------------
// Function:	SetSpriteInfo(...)
//------------------------------------------------------------------------------

void SetSpriteInfo(GsSPRITE *tSprite, u_long tMemAddress, long tX, long tY, int tCut)
  {
  GsIMAGE tTim;					// TIM image Information

  tMemAddress += 4;				// Pointer auf Daten
  GsGetTimInfo((u_long *) tMemAddress, &tTim);	// TIM Info in tTim holen

  tSprite->x = tX;				// setze Koordinaten gemäß
  tSprite->y = tY;				// den Angaben bei Aufruf

  switch (tTim.pmode & 3)			// X-Werte abhängig von der BitTiefe!
    {
    case 0: tSprite->w = tTim.pw << 2;
            tSprite->u = (tTim.px & 0x3f) * 4;
            break;
    case 1: tSprite->w = tTim.pw << 1;
            tSprite->u = (tTim.px & 0x3f) * 2;
            break;
    default: tSprite->w = tTim.pw;
             tSprite->u = tTim.px & 0x3f; 
    };

  tSprite->h = tTim.ph;
  tSprite->v = tTim.py & 0xff;

  tSprite->tpage = GetTPage((tTim.pmode & 3),0,tTim.px,tTim.py);
  tSprite->attribute = (tTim.pmode & 3) << 24;
  tSprite->cx = tTim.cx;			// CLUT von Sprite angeben
  tSprite->cy = tTim.cy;
  tSprite->r = tSprite->g = tSprite->b = 128;	// normale Intensität (der Farben)
  tSprite->mx = tSprite->w/2;			// Referenzpunkt des Sprites auf Mitte
  tSprite->my = tSprite->h/2;			// setzen (nicht erforderlich)
  tSprite->scalex = tSprite->scaley = ONE;	// Vergrößerung auf 1 (normale Größe)
  tSprite->rotate = 0;				// Drehwinkel auf 0
  if (tCut)					// Sprite "beschneiden" wenn das Tim
    tSprite->w -= tCut;				// eine "illegale" Breite hat...
  };
//-----------------------------------------------------------------
// INIT WOBBLE GsGLINE´s
//-----------------------------------------------------------------
void init_Wobble()
{
int i=0;
for(i=0;i<320;i++)
  {
	Wobble[i]=Wobble[0];
	Wobble[i].x0=Wobble[i].x1=i;
	Wobble[i].y0=60;
	Wobble[i].y1=100;
	Wobble[i].r0=Wobble[i].b0=Wobble[i].g0=0;
	Wobble[i].r1=Wobble[i].b1=Wobble[i].g1=0;
  }
}

void do_Wobble()
{
int j;
int i;
logosinoff2=savedlogosin2;


for(i=0;i<320;i++)
{
j=i+1;
Wobble[i].attribute=(2<<24)+(0<<29)+(1<<30);
Wobble[i].r0=Wobble[i].b0=0;
Wobble[i].g0=30;//colorsin;
Wobble[i].r1=Wobble[i].b1=Wobble[i].g1=0;
Wobble[i].y0=155+logosin[logosinoff2]/2+logosin4[i]/2;
Wobble[i].y1=190+logosin[logosinoff2]/2+logosin3[i]/2;
GsSortGLine(&Wobble[i],&othWorld[currentBuffer], 3);

logosinoff2++;
if(logosinoff2==520)logosinoff2=0;
}
savedlogosin2++;
if(savedlogosin2==520) savedlogosin2=0;
}

//===========================
// Typer Font init
//===========================
void init_Typer()
{
	GsIMAGE	fontimg;
	
	int	i=0,j=0,k=0;
	unsigned char	fontxy[ZEICHEN*ZEILEN*2];
	anzfontabc=strlen(fontabc);
//--------------------------------------------
// calculate X+Y Offsets inner Textur
//--------------------------------------------
for(i=0;i<ZEILEN;i++)
{
	for(j=0;j<ZEICHEN;j++)
	{
	fontxy[k++]=(j*FONT_W);	// X Offset
	fontxy[k++]=(i*FONT_H);	// Y Offset
	}
}
//---------------------------------------
// Textur and all Sprites init
//----------------------------------------

SetSpriteInfo(&fontspr[0],(u_long)font1,0,0,1);

j=0;
fontspr[0].w=FONT_W;
fontspr[0].h=FONT_H;
fontspr[0].u=fontxy[j++];
fontspr[0].v=fontxy[j++];
for(i=1;i<anzfontabc;i++)
{
	fontspr[i]=fontspr[0];
	fontspr[i].u=fontxy[j++];
	fontspr[i].v=fontxy[j++];
 }
}
//================
// Schow Typer
//================
void do_Typer()
{
  static int	act_x=0,act_y=0,act_p=0;
  static int	charcnt=0,delaycnt=10*10,
  clrcount=55;
  int	i=0,subit=-2;
logosinoff=savedlogosin;

//charcnt=MAX_CHAR;
//-----------------------------
// erase Page?
//-----------------------------
if(clrcount==55)
{
//---------------------------------------------------------------------
// if current page is not inited, do it now
//---------------------------------------------------------------------
if(isinit==0)
	{
		init_Page(act_p);
		isinit++;
	}
//-----------------------------------
// show each page per letter (type mode)
//-----------------------------------
for(i=0;i<charcnt;i++)
	{
	page[i].r=0; page[i].g=0-(colorsin[logosinoff]); page[i].b=0;
	GsSortFastSprite(&page[i],&othWorld[currentBuffer],3);
        logosinoff--;

	if (logosinoff==10) logosinoff=520;
	}
        savedlogosin++;
	if (savedlogosin==1040) savedlogosin=5;	
//-------------------------------------------------------
// if one Letter or Sign is missing, add one more
//-------------------------------------------------------
if(charcnt<MAX_CHAR)
{
	charcnt++;
}
//----------------------------------------------------
// ok, now we have em all, wait ... and delete current Page
//----------------------------------------------------
else
	{
		if(--delaycnt==0)
		{
		delaycnt=10*10;
		clrcount--;
		}
	}
}
//----------------------
// ok, bring new Page
//----------------------
else
	{
	if(++act_p==PAGES)	act_p=0;
	charcnt=0;
	isinit=0;
	clrcount=55;
	}
}
//==================================================
// fill Sprite-Array for our Typer
//==================================================
void init_Page(int pagenum)
{
int	h,i,j,k=0;

//--------------------------------------------------
// calculate the sprites
//--------------------------------------------------
for(h=0;h<PAGEH;h++)
{
	for(i=0;i<PAGEW;i++)
	{
		for(j=0;j<anzfontabc;j++)
		{
//-------------------------------------------------
// if SPACE , do not show a Sprite
//-------------------------------------------------
	if(texte[h+(PAGEH*pagenum)][i]==' ')
	{
		page[k++].w=0;
		break;
	}
//------------------------------------------------
// add Letter into the correct sprite
//------------------------------------------------
      if(texte[h+(PAGEH*pagenum)][i]==fontabc[j])
{
     page[k  ]=fontspr[j];
     page[k  ].x=42+(i*FONT_W);	 // set X Position for the Page
     page[k++].y=20+(h*FONT_H); // set Y Position for the Page
     break;
    }
   }
  }
 }
}

void setFlags()			// replace all four flags with a single pointer
        {
	int i;

	char *char_base;
	char *char_offset;

	char_base = (char *)0x8000E800;

	
for(i=0;i<NUMTRAIN;i++)
	{
	char_offset=char_base+i;

		if(choice[i]==1)
		{
		*char_offset=1;
		}
		else
			{
			*char_offset=0;
			}
		}



	}



void init_Menu()
{
	int	i;
	for(i=0;i<NUMTRAIN;i++)
	{
		choice[i]=0;
	}
//-----------------
// Linie #1 (first line above)
	//-----------------
	mline[0].attribute=0;
	mline[0].x0=56;	mline[0].y0=170-1;
	mline[0].x1=160;mline[0].y1=170-1;
	mline[0].r0=0;	mline[0].r1=255;
	mline[0].g0=255; mline[0].g1=255;
	mline[0].b0=0;mline[0].b1=255;
	//-----------------
	// Linie #2 (2nd line above)
	//-----------------
	mline[1].attribute=0;
	mline[1].x0=160;mline[1].y0=170-1;
	mline[1].x1=262;mline[1].y1=170-1;
	mline[1].r0=255;mline[1].r1=0;
	mline[1].g0=255;mline[1].g1=255;
	mline[1].b0=255;mline[1].b1=0;
	//-----------------
	// Linie #3 (3rd line above)
	//-----------------
	mline[2].attribute=0;
	mline[2].x0=56;	mline[2].y0=170+FONT_H-1;
	mline[2].x1=160;mline[2].y1=170+FONT_H-1;
	mline[2].r0=0;	mline[2].r1=255;
	mline[2].g0=255; mline[2].g1=255;
	mline[2].b0=0;mline[2].b1=255;
	//-----------------
	// Linie #4 (4th line above)
	//-----------------
	mline[3].attribute=0;
	mline[3].x0=160;mline[3].y0=170+FONT_H-1;
	mline[3].x1=262;mline[3].y1=170+FONT_H-1;
	mline[3].r0=255;mline[3].r1=0;
	mline[3].g0=255;mline[3].g1=255;
	mline[3].b0=255;mline[3].b1=0;
}
//
//=======================
// SHOW Options-Menu
//=======================
//
void do_Menu()
{
	int	h,i,j,k=0;
	int	numSprites=0;
	int	yPos=145;
	int	len,offi;
	static int startat=0;
	static int colcnt=30,coladd=4;
	static int coly=144,coloff=0;		// start position of the option bar
	//--------------------------------------
	// calculate the sprites
	//--------------------------------------
	for(h=0;h<3;h++)
	{
		offi=startat+h+(choice[startat+h]*NUMTRAIN);
		len=strlen(options[offi]);
		for(i=0;i<len;i++)
		{
			numSprites++;
			for(j=0;j<anzfontabc;j++)
			{
//-------------------------------------------------
// if SPACE, don't show a Letter / Sprite
				//-------------------------------------------------
				if(options[offi][i]==' ') // tab ??
				{
					sprMenu[k++].w=0;
					break;
				}
//------------------------------------------------
// add Letter into the Sprite
				//------------------------------------------------
				if(options[offi][i]==fontabc[j])
				{	
					fontspr[j].g=(logosin[logosinoff2]%110)+130;//200;
					fontspr[j].r=0;
					fontspr[j].b=0;
					sprMenu[k  ]=fontspr[j];
					sprMenu[k  ].x=(160-(len*FONT_W)/2)+(i*FONT_W);
					sprMenu[k++].y=yPos;
					break;
				}
			}
		}
		yPos+=FONT_H;
		if((h+1)==NUMTRAIN)
		{
			break;
		}
	}
	//-----------------------
	// add Sprites
	//-----------------------
	for(i=0;i<numSprites;i++)
	{
		GsSortFastSprite(&sprMenu[i],&othWorld[currentBuffer],0);
	}
	//------------------------------
	// Y-Position des Selector-Bars
	//------------------------------
	mline[0].y0=mline[0].y1=(coloff*FONT_H)+coly;
	mline[1].y0=mline[1].y1=(coloff*FONT_H)+coly;
	mline[2].y0=mline[2].y1=(coloff*FONT_H)+coly+FONT_H;
	mline[3].y0=mline[3].y1=(coloff*FONT_H)+coly+FONT_H;
//---------------------
// move Color gradient
//---------------------
//mline[0].x1+=coladd;
//mline[1].x0+=coladd;
//mline[2].x1+=(coladd*-1);
//mline[3].x0+=(coladd*-1);
	if(--colcnt==0)
	{
		colcnt=60;
		coladd*=-1;
}
//------------------------
// Add Selector-Bar
//------------------------
GsSortGLine(&mline[0],&othWorld[currentBuffer],0);
GsSortGLine(&mline[1],&othWorld[currentBuffer],0);
GsSortGLine(&mline[2],&othWorld[currentBuffer],0);
	GsSortGLine(&mline[3],&othWorld[currentBuffer],0);
	//-----------------------
	// call Joypad
	//-----------------------
	if(delay==0)
	{
		//-------------------
		// Joypad up?
		//-------------------
		if(PADstatus&Pad1Up)		// coloff == bar position 0..6
		{				// startat == menu position 0..NUMTRAIN
			if(coloff==0)		// if the bar is at the top of it`s range
			{
				if(startat!=0)  //  if the first option is not at the top of menu
				{
					startat--;	// shift menu DOWN one position
				}
			}
			else
			{
				coloff--;	// reduce the position fo the bar by one if it is 						// not at the top of it`s range
			}
		}
		//--------------------
		// Joypad down?
		//--------------------
		if(PADstatus&Pad1Down)
		{
			if((coloff==2)||(coloff==NUMTRAIN-1)) // 10 values option 0..9
			{				    //if option bar is at bottom of range
							    //or if the bar is at the final 							    //trainer option
				if((startat+3)<NUMTRAIN)    // if more options to be shown
				{
					startat++;	// first option on display +1 position
				}
			}
			else
			{
				coloff++;	// coloff == position of option bar
			}
		}
//-------------------------
// Joypad left (NO)?
//-------------------------
if(PADstatus&Pad1Left)
{
	choice[startat+coloff]=0;
}
//---------------------------
// Joypad right (YES)?
		//---------------------------
		if(PADstatus&Pad1Right)
		{
			choice[startat+coloff]=1;
		}
	}
}
add Trainer Values into Icarus.obj, don't miss copy.obj, tob0ins.asm
You do not have the required permissions to view the files attached to this post.

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest