WORKSHOP CODING INTROS & DEMOS for Play Station 1

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

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
Verified
Psy-Q Enthusiast
Psy-Q Enthusiast
Posts: 248
Joined: Mar 07, 2013
I am a: Programmer Windows+PS1, GFX Artist
PlayStation Model: Black
Location: Germany

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.asm, don't miss copy.obj, tob0ins.asm
You do not have the required permissions to view the files attached to this post.
Last edited by inc^lightforce on June 10th, 2021, 1:22 am, edited 1 time in total.

User avatar
inc^lightforce
Verified
Psy-Q Enthusiast
Psy-Q Enthusiast
Posts: 248
Joined: Mar 07, 2013
I am a: Programmer Windows+PS1, GFX Artist
PlayStation Model: Black
Location: Germany

Post by inc^lightforce » April 3rd, 2021, 10:33 pm

another day in 2021, another tutorial

HERE: CODING A 3D STARSFIELD THAT COMING FROM THE BACK INTO THE FRONT


Image

Code: Select all

/*
	3D Starfield  -  makes a starfield which can be used as a background
	Inc. 2021
*/
#include <sys/types.h>
#include <libgte.h>
#include <libgpu.h>
#include <libetc.h>
#include <libgs.h>
#include "pad.h"

#define OT_LENGTH	10
GsOT myOT[2];
GsOT_TAG myOT_TAG[2][1<<OT_LENGTH];

#define PACKETMAX	1000
PACKET GPUPacketArea[2][PACKETMAX*24];

#define SCREEN_WIDTH	320
#define SCREEN_HEIGHT	240

typedef struct{
	int x;					//star structure - has and x, y and z coordinate
	int y;
	int z;
	GsLINE line;			//GsLINE strcuture that make a star pixel
}Star;

#define MAX_STARS	300
#define star_w		8000	//determines the width of the area that stars 'appear' in
Star myStars[MAX_STARS];


int i;					//integer used for counting
u_long pad;
int speed=2;

/******** prototypes *********/
int main();
void InitAll(void);
void DisplayAll(int);
void InitSprite(GsIMAGE *, GsSPRITE *);
void InitStarField(void);
void DoStarField(int);
/******* methods ************/
int main() {
	int activeBuffer;
	
	SetVideoMode(MODE_PAL);
//	SetVideoMode(MODE_NTSC);
	InitAll();						//inits system
	InitStarField();				//inits starfield

	while (1) {
		activeBuffer=GsGetActiveBuff();
		GsSetWorkBase((PACKET*)GPUPacketArea[activeBuffer]);
		GsClearOt(0, 0, &myOT[activeBuffer]);
		FntPrint("speed=%d",speed);
		DoStarField(activeBuffer);		//this adds the starfield to the OT and moves the stars
		DisplayAll(activeBuffer);
	}
}
void InitStarField(void) {
	//inits starfield
	srand();					  //init the randomiser (for creating random star allocations)
	
	for(i=0; i<MAX_STARS; i++) {  //this bit sets up each 'star' (MAX_STARS number of them)
		myStars[i].x=star_w-(rand()*(2*star_w))/(32767+1);	//set stars x-coordinate
		myStars[i].y=star_w-(rand()*(2*star_w))/(32767+1);	//set stars y-coordinate
		myStars[i].z=(rand()*(80))/(32767+1)+1;			    //set stars z-coordinate 1-81 (cant be zero since +1)
		myStars[i].line.r=myStars[i].line.g=myStars[i].line.b=255;
	}//for
}

void DoStarField(int activeBuffer) {
	//this is what makes the stars 'move', it also adds the stars to the OT
	int x,y,z;
	
	for(i=1;i<MAX_STARS;i++) {
		if (myStars[i].z<2) myStars[i].z=100;	//if the star has reached you then put it back to come toward you again
		//divide by c so that as star gets closer it seems to move faster past you
		x=(myStars[i].x) / (myStars[i].z);		//sets x value of stars
		y=(myStars[i].y) / (myStars[i].z);		//sets y value of stars
		myStars[i].z-=speed;				    //moves stars toward you
		myStars[i].line.x1=myStars[i].line.x0=x+SCREEN_WIDTH/2;			//centres starfields x value onscreen
		myStars[i].line.y1=myStars[i].line.y0=y+SCREEN_HEIGHT/2;		//centres starfields y value onscreen
		
		GsSortLine(&myStars[i].line,&myOT[activeBuffer],0);	//sorts stars into OT)
	}
}
void DisplayAll(int currentBuffer) {
	DrawSync(0);
	VSync(0);
	GsSwapDispBuff();
	GsSortClear(0,0,0,&myOT[currentBuffer]);
	GsDrawOt(&myOT[currentBuffer]);
	FntFlush(-1);
}
void InitAll(void) {
	GsInitGraph(SCREEN_WIDTH, SCREEN_HEIGHT, GsINTER|GsOFSGPU, 0,0);
	GsDefDispBuff(0,0,0,SCREEN_HEIGHT);
	myOT[0].length=OT_LENGTH;
	myOT[1].length=OT_LENGTH;
	myOT[0].org=myOT_TAG[0];
	myOT[1].org=myOT_TAG[1];
	GsClearOt(0,0,&myOT[0]);
	GsClearOt(0,0,&myOT[1]);
	
	PadInit(0);

	FntLoad(960, 256);
	FntOpen(10,10,SCREEN_WIDTH-10,SCREEN_HEIGHT-20,0,512);
	SetDispMask(1);  /* start display */
}

void InitSprite(GsIMAGE *im, GsSPRITE *sp) {
	int bits;
	int widthCompression;
	RECT myRect;
		
	bits=im->pmode&0x03;
	if (bits==0) widthCompression=4;
	else if (bits==1) widthCompression=2;
	else if (bits==2) widthCompression=1;
	else if (bits==3) printf("\nunsupported file format (24bit tim)!\n");
	
	myRect.x = im->px;
	myRect.y = im->py;
	myRect.w = im->pw;
	myRect.h = im->ph;
	LoadImage( &myRect, im->pixel );		//loads image data to frame buffer
	
	printf("\nimage bit type =%d\n",bits);

	sp->attribute = (bits<<24);
	sp->x = SCREEN_WIDTH/2-((im->pw*widthCompression)/2);	//center sprite's x value
	sp->y = SCREEN_HEIGHT/2-im->ph/2;			//center sprite's y value
	sp->w = im->pw*widthCompression;
	sp->h = im->ph;
	sp->tpage=GetTPage(bits, 0, im->px, im->py);
	sp->u=0;
	sp->v=0;
	if (bits==0||bits==1) {
		//checks if image is 4 or 8 bit
		myRect.x = im->cx;
		myRect.y = im->cy;
		myRect.w = im->cw;
		myRect.h = im->ch;
		LoadImage( &myRect, im->clut );		//loads clut to frame buffer if needed
		sp->cx=im->cx;
		sp->cy=im->cy;
	}
	sp->r=128;
	sp->g=128;
	sp->b=128;
	sp->mx=0;//(im->pw*widthCompression)/2;
	sp->my=0;//im->ph/2;
	sp->scalex=ONE;
	sp->scaley=ONE;
	sp->rotate=0;
}
Compile and test it with ePSXe EMU

QUESTIONS? ASK
have Fun
You do not have the required permissions to view the files attached to this post.

User avatar
Shadow
Verified
Admin / PSXDEV
Admin / PSXDEV
Posts: 2670
Joined: Dec 31, 2012
PlayStation Model: H2000/5502
Discord: Shadow^PSXDEV

Post by Shadow » May 26th, 2021, 2:41 pm

Nice simple demos. Good work! Very useful for beginners. Keep them coming Inc :)
Development Console: SCPH-5502 with 8MB RAM, MM3 Modchip, PAL 60 Colour Modification (for NTSC), PSIO Switch Board, DB-9 breakout headers for both RGB and Serial output and an Xplorer with CAETLA 0.34.

PlayStation Development PC: Windows 98 SE, Pentium 3 at 400MHz, 128MB SDRAM, DTL-H2000, DTL-H2010, DTL-H201A, DTL-S2020 (with 4GB SCSI-2 HDD), 21" Sony G420, CD-R burner, 3.25" and 5.25" Floppy Diskette Drives, ZIP 100 Diskette Drive and an IBM Model M keyboard.

kiryuureno
What is PSXDEV?
What is PSXDEV?
Posts: 3
Joined: Oct 28, 2021
PlayStation Model: SCPH-1002

Post by kiryuureno » November 5th, 2021, 11:13 pm

Sorry for not being able to run the tutorial completely. It's very good, but my brain couldn't process some parts... And I need some help plz.

First DEPACK.SRC must be compiled with the psqy project, correct? (I'm using the alien resurrection trainer example). Up to this point I was able to successfully run and compile to INTRO.EXE and loader.exe (I dont now what i make with loader.exe).

It is confusing for me to understand the part where it indicates the starting address of the PatchData.txt file and then there is the part of CDIMAGE MSK.EXE, with more information that confuses where and what should be used, or where to use the information...

And finally, the patch creation part to use with PFF-oMatic. Using MAKEPPF I tried to put INTRO.EXE and SLUS006.33 to create the patch file and apply it to the Alien Ressurection ISO, but it didn't work...

Well in the end I followed the tutorial but I couldn't do what I wanted, join the intro with the game. Some information gaps are missing for me to be able to make it work.

Someone can help me plz? Im love playStation and Im trying to learn some, but im beginer here and need some help.

Rabatini
Interested PSXDEV User
Interested PSXDEV User
Posts: 8
Joined: Nov 04, 2020

Post by Rabatini » November 7th, 2021, 12:57 am

kiryuureno wrote: November 5th, 2021, 11:13 pm Sorry for not being able to run the tutorial completely. It's very good, but my brain couldn't process some parts... And I need some help plz.

First DEPACK.SRC must be compiled with the psqy project, correct? (I'm using the alien resurrection trainer example). Up to this point I was able to successfully run and compile to INTRO.EXE and loader.exe (I dont now what i make with loader.exe).

It is confusing for me to understand the part where it indicates the starting address of the PatchData.txt file and then there is the part of CDIMAGE MSK.EXE, with more information that confuses where and what should be used, or where to use the information...

And finally, the patch creation part to use with PFF-oMatic. Using MAKEPPF I tried to put INTRO.EXE and SLUS006.33 to create the patch file and apply it to the Alien Ressurection ISO, but it didn't work...

Well in the end I followed the tutorial but I couldn't do what I wanted, join the intro with the game. Some information gaps are missing for me to be able to make it work.

Someone can help me plz? Im love playStation and Im trying to learn some, but im beginer here and need some help.
Hi There!

you have to take your SLUS with no compression, uses cd mage, extract the slus
put slus in DOCL, RENAME .BAT TO YOUR SLUS.
like lct "yourslusname" > PatchData.txt
lct will creat a txt with these informations, of course it will change slus to slus.
=============================
Magic PSX Patching Tool v0.1
-----------------------------
(c) 2000 - AVH of PARADOX
=============================

Load address...........: 0x80010000
Decrunch to............: 0x8000f800
Exec address...........: 0x80140324
The load address you will put in the .bat compilation.
ccpsx -O3 -Xo$80100000 MAIN.c data/*.obj depack.obj -oMAIN.cpe
Decrunch value will go inside depack.src
idest equ $8000f800 ;Decrunch to
and finally
Exec adress inside the main.c
//-------------------------------------------------------------
//************************* starts game ***********************
//-------------------------------------------------------------
asm("nop");
asm("j 0x80140324");
you put your slus adress

that is it.

But i think, some games do not accept the RNC compress, i have recently fnd a game that do not work, even praying...hehhe, but is not in your case.

kiryuureno
What is PSXDEV?
What is PSXDEV?
Posts: 3
Joined: Oct 28, 2021
PlayStation Model: SCPH-1002

Post by kiryuureno » November 10th, 2021, 9:54 pm

Rabatini wrote: November 7th, 2021, 12:57 am
kiryuureno wrote: November 5th, 2021, 11:13 pm Sorry for not being able to run the tutorial completely. It's very good, but my brain couldn't process some parts... And I need some help plz.

First DEPACK.SRC must be compiled with the psqy project, correct? (I'm using the alien resurrection trainer example). Up to this point I was able to successfully run and compile to INTRO.EXE and loader.exe (I dont now what i make with loader.exe).

It is confusing for me to understand the part where it indicates the starting address of the PatchData.txt file and then there is the part of CDIMAGE MSK.EXE, with more information that confuses where and what should be used, or where to use the information...

And finally, the patch creation part to use with PFF-oMatic. Using MAKEPPF I tried to put INTRO.EXE and SLUS006.33 to create the patch file and apply it to the Alien Ressurection ISO, but it didn't work...

Well in the end I followed the tutorial but I couldn't do what I wanted, join the intro with the game. Some information gaps are missing for me to be able to make it work.

Someone can help me plz? Im love playStation and Im trying to learn some, but im beginer here and need some help.
Hi There!

you have to take your SLUS with no compression, uses cd mage, extract the slus
put slus in DOCL, RENAME .BAT TO YOUR SLUS.
like lct "yourslusname" > PatchData.txt
lct will creat a txt with these informations, of course it will change slus to slus.
=============================
Magic PSX Patching Tool v0.1
-----------------------------
(c) 2000 - AVH of PARADOX
=============================

Load address...........: 0x80010000
Decrunch to............: 0x8000f800
Exec address...........: 0x80140324
The load address you will put in the .bat compilation.
ccpsx -O3 -Xo$80100000 MAIN.c data/*.obj depack.obj -oMAIN.cpe
Decrunch value will go inside depack.src
idest equ $8000f800 ;Decrunch to
and finally
Exec adress inside the main.c
//-------------------------------------------------------------
//************************* starts game ***********************
//-------------------------------------------------------------
asm("nop");
asm("j 0x80140324");
you put your slus adress

that is it.

But i think, some games do not accept the RNC compress, i have recently fnd a game that do not work, even praying...hehhe, but is not in your case.
Thanks brother! You help me !

That can make I see my errors, and I see some games use a different load address than whats show in DOCL in my tests.

Rabatini
Interested PSXDEV User
Interested PSXDEV User
Posts: 8
Joined: Nov 04, 2020

Post by Rabatini » November 11th, 2021, 9:29 am


Thanks brother! You help me !

That can make I see my errors, and I see some games use a different load address than whats show in DOCL in my tests.
You're welcome!
Yes, and seems if its different the depack will not work, i think its problem with ram size.
i find this problem with few games.
Only way to manage it, it not packing with rnc, clean the memory and make a jumper to the original exe once again.

R3k
Interested PSXDEV User
Interested PSXDEV User
Posts: 7
Joined: Jan 02, 2022

Post by R3k » January 3rd, 2022, 9:04 am

Hi! I am interested in writing a small loader to inject my own code before the game starts. It is mostly for the LibCrypt cracks for games that have their code encrypted (Spyro 3) or packed somewhere else (Sydney 2000, Final Fantasy). The problem is I neither do not know how to code nor I want to learn it. I have got only a basic assembler knowledge. I thought I could use the iNC published sources to achieve that. After setting these stupid PSX compilers, I was finally able to compile the code. I used the Alien Resurrection trainer sources. The game I want to pack is Sydney 2000. Here is the result of LCT:

Code: Select all

Load address...........: 0x80020000
Decrunch to............: 0x8001f800
Exec address...........: 0x80020070
Game.rnc I obtained from the iNC's packer.
Here is my main.c:

Code: Select all

int main()
{

	//-------------------------------------------------------------
	//------------------PATCH FUNKTION- Spiel entpacken------------
	//-------------------------------------------------------------
	EnterCriticalSection();
	depack1();
	ExitCriticalSection();

//-------------------------------------------------------------
//************************* starts game ***********************
//-------------------------------------------------------------
asm("nop");
asm("j 0x80020070"); // ExecAdresse um spiel dann zu laden
asm("nop");
return 0;
}
Here is the DEPACK.SRC address:

Code: Select all

idest	equ	$8001f800	;Decrunch to
depack.obj compilation:

Code: Select all

asmpsx /l/oat- depack.src,depack.obj
Here is the ccpsx command:

Code: Select all

ccpsx -O3 -Xo$80020000 main.c depack.obj -omain.cpe
I used cpe2psx next, resized the executable and injected into the image file using CDmage. But the game does not seem to be unpacking at all, tested in the no$psx and PCSX2. I assume my lack of knowledge is the problem here, as the main.c file is incomplete probably, isn't it?

Rabatini
Interested PSXDEV User
Interested PSXDEV User
Posts: 8
Joined: Nov 04, 2020

Post by Rabatini » January 4th, 2022, 7:32 am

Hi which version of the game is?
the USA one give me this LCT

Code: Select all

Load address...........: 0x801f4c38
Decrunch to............: 0x801f4438
Exec address...........: 0x801ff914

R3k
Interested PSXDEV User
Interested PSXDEV User
Posts: 7
Joined: Jan 02, 2022

Post by R3k » January 4th, 2022, 10:04 am

Thank you for the reply! I am testing the PAL UK version. But I have figured it out eventually. It is the ccpsx -Xo$80020000, which was causing the problem. It does work when the -Xo$80100000 is used instead. I do not understand what it is responsible for though.

I have started fiddling with the trainer files. It looks like the tob0ins.bin contains the hook on the 0xb60 syscall. The copy.obj does handle all the memory and hook operations for the trainer to work. The icarus.obj does contain the trainer codes meant to be placed at the 0x8000e800. It is perfectly suited to my needs. Thank you iNC for sharing the knowledge and work! Even though so many years passed when the popularity of PSX was at its peak.

I was always under impression of the PARADOX skills (and all BAD, LFC, HLG, MUPS relatives). These LC games look very easy to patch out with emulators nowadays, but I can only imagine how hard it was back then with limited resources and tools to do the job correctly (and as fast as possible).

User avatar
inc^lightforce
Verified
Psy-Q Enthusiast
Psy-Q Enthusiast
Posts: 248
Joined: Mar 07, 2013
I am a: Programmer Windows+PS1, GFX Artist
PlayStation Model: Black
Location: Germany

Post by inc^lightforce » February 28th, 2022, 2:35 am

R3k wrote: January 4th, 2022, 10:04 am . Thank you iNC for sharing the knowledge and work! Even though so many years passed when the popularity of PSX was at its peak.

I was always under impression of the PARADOX skills (and all BAD, LFC, HLG, MUPS relatives). These LC games look very easy to patch out with emulators nowadays, but I can only imagine how hard it was back then with limited resources and tools to do the job correctly (and as fast as possible).
yes it was a hard time back in the days. there was no emulator that took out the LC Fu** automatically. We worked hard, near to a half year to get things up on run and don't forget, we had only real hardware.
- Windows 98
- comm card
- Action Replay
- PlayStation

and psyQ and our own programmed tools. that days it was a big secret around the Loaders on HOW TO.
but i decided back in the last years to publish anything and more will come after i find more time.

I'm working on a Windows Tool that allow People to create Cracktros, Loaders or Trainers via drag and drop with an nice User Interface for easy PSX coding and compiling. WYSIWYG.


try alpha:
www.inc-games-design.de/Tools/inc_PSX_D ... _alpha.rar
You do not have the required permissions to view the files attached to this post.

User avatar
scorpion2k81
Active PSXDEV User
Active PSXDEV User
Posts: 57
Joined: Feb 24, 2022
I am a: Programmer
PlayStation Model: SCPH-5502
Location: Italy

Post by scorpion2k81 » February 28th, 2022, 9:41 am

Thanks INC for all the tutorials and for this new tool ...
I tried to create a simple menu to start games but I always get an error when I start games with epsxe.
I have followed all the steps to enter the values in the various files but I always get an error when I start the game.
These are all my steps: (I used castlevania sotn USA SLUS_000.67)
(1) - I use CDMage to extract slus_000.67 file
(2) - I renamed slus file to game.rnc
(2) - lct game.rnc > PatchData.txt
Load address...........: 0x80010000
Decrunch to............: 0x8000f800
Exec address...........: 0x80010dfc
(3) - I put the various values in these files :
Decrunch value -> DEPACK.SRC
Exec address -> main.c
Load address -> make.bat
(4) - I compressed the game.rnc file with rnc.exe, then I moved the compressed file to the project folder
(5) - I created the main.exe file, then resized it with PS1-FileResizer
(6) - With CDMage I imported the new file

I have attached the small project file with the epsxe error screenshot.
What am I doing wrong?
You do not have the required permissions to view the files attached to this post.

User avatar
inc^lightforce
Verified
Psy-Q Enthusiast
Psy-Q Enthusiast
Posts: 248
Joined: Mar 07, 2013
I am a: Programmer Windows+PS1, GFX Artist
PlayStation Model: Black
Location: Germany

Post by inc^lightforce » February 28th, 2022, 4:04 pm

so far, your progress is correct, but also not forget to call at the last line in your batch:
EXEFIXUP.exe main.exe

unfortunatly i have no old hardware that i can turn over to set up a running sdk and on windows 11 x64 i guess PSYQ won't run at all.

i must check the main.c at least, it could take 5 minutes but i have no compatible environment here. i'll get back soon to help.

User avatar
scorpion2k81
Active PSXDEV User
Active PSXDEV User
Posts: 57
Joined: Feb 24, 2022
I am a: Programmer
PlayStation Model: SCPH-5502
Location: Italy

Post by scorpion2k81 » February 28th, 2022, 5:20 pm

inc^lightforce wrote: February 28th, 2022, 4:04 pm so far, your progress is correct, but also not forget to call at the last line in your batch:
EXEFIXUP.exe main.exe
I use a new WIN32 cpe2x, work on new windows10 64Bit. This version added auto "round up to 2048" and header sign.
It replaces the old version of cpe2x and automatically adds the exefixup function.
I used it to build your alien project and it works great with the game. If I create my own menu for other games I get the epsxe error.
You do not have the required permissions to view the files attached to this post.

User avatar
inc^lightforce
Verified
Psy-Q Enthusiast
Psy-Q Enthusiast
Posts: 248
Joined: Mar 07, 2013
I am a: Programmer Windows+PS1, GFX Artist
PlayStation Model: Black
Location: Germany

Post by inc^lightforce » March 1st, 2022, 2:19 am

Ok,
I need your game.bin ( untouched ) that you want to change. I write a Main.c for you, but i must test my compilation with your game. All the further communication via PM please. I want to keep this workshop clean as possible.
Best
Inc

R3k
Interested PSXDEV User
Interested PSXDEV User
Posts: 7
Joined: Jan 02, 2022

Post by R3k » March 6th, 2022, 2:05 am

inc^lightforce wrote: February 28th, 2022, 2:35 am
R3k wrote: January 4th, 2022, 10:04 am . Thank you iNC for sharing the knowledge and work! Even though so many years passed when the popularity of PSX was at its peak.

I was always under impression of the PARADOX skills (and all BAD, LFC, HLG, MUPS relatives). These LC games look very easy to patch out with emulators nowadays, but I can only imagine how hard it was back then with limited resources and tools to do the job correctly (and as fast as possible).
yes it was a hard time back in the days. there was no emulator that took out the LC Fu** automatically. We worked hard, near to a half year to get things up on run and don't forget, we had only real hardware.
- Windows 98
- comm card
- Action Replay
- PlayStation

and psyQ and our own programmed tools. that days it was a big secret around the Loaders on HOW TO.
but i decided back in the last years to publish anything and more will come after i find more time.

I'm working on a Windows Tool that allow People to create Cracktros, Loaders or Trainers via drag and drop with an nice User Interface for easy PSX coding and compiling. WYSIWYG.


try alpha:
www.inc-games-design.de/Tools/inc_PSX_D ... _alpha.rar
Instead of writing my own code, I ended up hooking the patched executable to insert the fixed code before launching the game. That is how I fixed two most known PDX fuck ups - Spyro 3 PAL and Sydney 2000 UK. Additionally, I corrected the issue with both cracktros not working on the old PS1 models (and some PS1 emulators) with different GPU.

Yeah, back then it looked like only two groups were skilled enough to write good loaders, intros and cracks - KALiSTO and PARADOX (including all its relatives like LiGHTFORCE, BAD, MUPS or HOOLiGANS). But since the KAL was an American group, they did not participate in the Libcrypt cracking scene. Practically, the European, PDX related groups did not have any competition, especially when more sophisticated LC versions started to appear.

Rabatini
Interested PSXDEV User
Interested PSXDEV User
Posts: 8
Joined: Nov 04, 2020

Post by Rabatini » April 24th, 2022, 1:52 am

inc^lightforce wrote: March 1st, 2022, 2:19 am Ok,
I need your game.bin ( untouched ) that you want to change. I write a Main.c for you, but i must test my compilation with your game. All the further communication via PM please. I want to keep this workshop clean as possible.
Best
Inc
Hello Inc.
I have the sam problem, some games works as glove, and another gives error.

User avatar
Dedok179
Serious PSXDEV User
Serious PSXDEV User
Posts: 86
Joined: Jun 11, 2015
I am a: Programmer, Beginning reverser
PlayStation Model: SCPH-5502
Discord: Dedok179#2632
Location: Tula,RU

Post by Dedok179 » April 24th, 2022, 4:42 pm

Of all the games for which I made trainers through the Builder, only two games did not work for me - Rapid Reload Gunners Heaven and Gran Turismo 2

globodepre
Interested PSXDEV User
Interested PSXDEV User
Posts: 6
Joined: May 17, 2022
PlayStation Model: scph1001
Location: América

Post by globodepre » May 17th, 2022, 4:55 pm

Friends, two doubts, my project is with Slus_007.08 - Legacy of Kain Soul Reaver. First doubt, with this step by step will the slus be unlocked? Second doubt, is there a way to make the initialization automatic without having to press "X" or "O" to enter the Eidos video?

Post Reply

Who is online

Users browsing this forum: No registered users and 3 guests