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
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:59 pm

How can I unlock Slus_007.08 without compress?

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

Post by inc^lightforce » May 18th, 2022, 1:04 pm

Yes it is possible. Easy. But remember: Soul Reaver is libcrypt 2 protected.
The psx exe must be cracked too.

Lct.exe gives you the correct LC addresses. See patchdata.txt
Last edited by inc^lightforce on January 27th, 2023, 10:13 am, edited 1 time in total.

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

Post by globodepre » May 19th, 2022, 4:12 am

=============================
Magic PSX Patching Tool v0.1
-----------------------------
(c) 2000 - AVH of PARADOX
=============================

Load address...........: 0x80010000
Decrunch to............: 0x8000f800
Exec address...........: 0x800b6e98

Patch GetVideoMode() at: 0x800c2854 (0x24020001 for PAL, 0x24020000 for NTSC)
0x800c2858 (NOP out)

Patch X-Delta at.......: 0x800bb108 (0x24900030 for PAL, 0x24900010 for NTSC)
0x800bb10c (0x24900030 for PAL, 0x24900010 for NTSC)

>>> I managed to do the compression, but it didn't break the lock.
I could not understand the tutorial step to do that removes the lock. That is what to do and where is the Slus lock.
Can you help me with this unlock?
link for down in the Slus_007.08 https://we.tl/t-lpR19D6hUu

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

Post by globodepre » May 20th, 2022, 8:38 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
I managed to do the compression, but it didn't break the lock.
I could not understand the tutorial step to do that removes the lock. That is what to do and where is the Slus lock.
Can you help me with this unlock?
link for down in the Slus_007.08 https://we.tl/t-lpR19D6hUu

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 » May 22nd, 2022, 2:10 am

globodepre wrote: 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?
try my tool, you can find it on this page:
viewtopic.php?f=75&t=3938

the american version of soul reader has no libcrypt / modchip protection

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

Post by globodepre » May 24th, 2022, 5:00 pm

>>> scorpion2k81: american version of soul reader has no libcrypt / modchip protection <<<

Actually to make copies there is no lock, but... if the contents of the .ISO specifically the BIGFILE file is edited, the game crashes. The limit will be the two videos of Eidos and Cristal dinamics.

There is a way to just remove the lock without having to compress the SLUS_007.08

If anyone can help me, thanks in advance.

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 » June 3rd, 2022, 7:06 pm

globodepre wrote: May 24th, 2022, 5:00 pm >>> scorpion2k81: american version of soul reader has no libcrypt / modchip protection <<<

Actually to make copies there is no lock, but... if the contents of the .ISO specifically the BIGFILE file is edited, the game crashes. The limit will be the two videos of Eidos and Cristal dinamics.

There is a way to just remove the lock without having to compress the SLUS_007.08

If anyone can help me, thanks in advance.
I sent you a PM

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

Post by globodepre » June 9th, 2022, 11:09 am

Friend thanks for your attention. I will look for the programs and continue the project. Thanks for all the help.

User avatar
KevinZ22U
What is PSXDEV?
What is PSXDEV?
Posts: 2
Joined: Aug 15, 2022
Location: Mexico

Post by KevinZ22U » August 15th, 2022, 6:06 am


tna9rish
What is PSXDEV?
What is PSXDEV?
Posts: 2
Joined: Jul 14, 2022
PlayStation Model: SCPH-1002

Post by tna9rish » September 3rd, 2022, 5:53 am

Can you make a video tutorial on how to inject the codes directly to the ps1 gaùe please ?? because I didn't get it all since I have no knowledge about C language and stuff like that

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

Post by inc^lightforce » November 17th, 2022, 11:05 am

tna9rish wrote: September 3rd, 2022, 5:53 am Can you make a video tutorial on how to inject the codes directly to the ps1 gaùe please ?? because I didn't get it all since I have no knowledge about C language and stuff like that
first of all: you need knowledge about C Programming. If not, learn it. Sorry that it sounds harsh but you need to know what are you doing.

i bring light at the darkness very soon. i open a workshop that handle Trainer Coding. but it will take a while until x mas

User avatar
masterg0r0
Active PSXDEV User
Active PSXDEV User
Posts: 65
Joined: Jul 18, 2021
I am a: Programmer
Motto: They see me rollin'
PlayStation Model: 1002+7502
Location: UK

Post by masterg0r0 » November 17th, 2022, 12:18 pm

Plenty of information is readily available on both the net and in books.
PSX Dev. Console: SCPH-7502 (PAL), MM3, Xplorer with Caetla 0.38.

Computer: Compaq Armada 1750, Windows 98SE, Pentium II 333MHz, 256MB RAM, 40GB IDE HDD, ESS AudioDrive, CD Drive, 3.5" Floppy (broken).

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

Post by inc^lightforce » December 11th, 2022, 4:35 pm

To all who have questions:
I'm back online.
contact me via Skype!

Do not spam the "WORKSHOP" !!!

thanks
I'm using Windows 7 - x86 now and it should be fine

Contact me at: Skype: a5recordings

shouts

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

Post by inc^lightforce » December 25th, 2022, 6:27 pm

MrBengali wrote: May 24th, 2020, 6:35 am Hello Inc,

Nice post. Bring back old memory. Regarding Rob Northern Packer (PPIBM/RNC), I was wondering if there is aversion running on a modern pc somewhere ? I am trying to compile some old intro of mine but I am still missing a couple
of items, incl. this good old packer :)

Thanks.
i have rewritten a windows app that handle the rnc work. download is in the entry post.

cheeeeerrs

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

Post by inc^lightforce » December 30th, 2022, 8:53 pm

another day another tutorial for the Workshop


the last Day to uncover and revealing another Sourcecode for my Workshop in 2022.

This Demo i wrote and used in 2000 for:
- SPIDERMAN - SPIN AND CATCH DA EVIL
- NHL 2001 german
- Kingsley's Adventure (Multi)

Today:
- a moving Logo from left to right and back
- an image that act to a predefined Sinus Code - made with SinusLab by Hitmen
- a nice Sinus Scroller for the Info-Text
- Music
- Falling leaves that are rotating


Plain Code:

Code: Select all

//==========================================================================
//																		   |
//  NEW DATE: 			DECEMBER 30th 2022								   |	
//	CODER:				Inc of Lightforce 2000							   |
//  SDK:	 			PSYQ											   |
//  EMULATOR:			EPSXE 1.6.0										   |
//	EDITOR:				NOTEPAD++ V8.4.7								   |
//																		   |
//  PROGRAM: 			SPIDERMAN / ALSO THE LIGHTFORCE LOADER CODE 	   |
//	SAME SOURCE Code:	https://youtu.be/RQp4BZMgtlI					   |
//																		   |
//==========================================================================

//--------------------------------------------------------------------------
// 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 "sinstuff.h"

//---------------------------------------------------------------------
#define NOP		0x00000000
//---------------------------------------------------------------------

#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

//---------------------------------------------------------------------
//
// SCROLLERR DEFINITION
//
//---------------------------------------------------------------------
#define SCRSPEED          2 // Scrollspeed Text
#define YPOS            207 // Y-Position  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;	// actual Buffer for "double buffering"
u_long		PADstatus=0;	// Var to save PAD-Status

int         v_countGFX=0, v_countCODE=0; // HSync Counter
u_char      HZMode=MODE_NTSC;

//---------------------------------------------------------------------
//
// READ NAME BY USED PICTURES and or OBJECTS , SOUND etc.
//
//---------------------------------------------------------------------
extern char intro[]; // sound file
extern char kali[];	 // LEAF 1
extern char kali2[]; // LEAF 2
extern char kali3[]; // LEAF 3
extern char kali4[]; // LEAF 4
extern char font[];	 // Sinus Font
extern char laub[];  // The Logos Left side because it is too large
extern char laub1[]; // The Logos Right side because it is too large
extern char right[];

//---------------------------------------------------------------------
//
// Include SINUS to Scroll Text
//
//---------------------------------------------------------------------
static int iSinOff1=0;
//static int iSinOff2=0; // each have 256 Values... create your own with Sinuslab.exe
#define MAXSINVALUE 256  // height of Sinus Curve

static char scrtxt[] = "               ==== EVERYBODY WATCH OUT===="                       " LONG TIME NO SEE EACH LONG TIME NO SEE===="                       " UNDERCOVER < AGENTS BRINGS YOU: SPIDERMAN"                       " GERMAN BY ACTIVISION (C) 2000= SPIN AND CATCH DA EVIL:)"                       "====== PRESS ( START ) FOR PLAYING OR READ THAT NICE SCROLLER AND LISTEN TO A FINE TUNE :)"                       " === INTRO CREDITZ:=====  CODING: INC= < SOUND: INC="                       " < GFX: INC==== GREEZ"                       " WE LIKE TO SEND AT: PARADOX < B=A=D= < COXS <"                       " LIGHTFORCE < MUPS < KALISTO < UTOPIA < HYDROGEN <"                       " TRSI < TDD < FUZZION < CRACKTRO=DE"                       " < CRAZY < LOWANG < SDC < AVH < MR=PS2 < PHANTOM < TURSI < FERRY"                       " < ZERO G====== UCA GROUP: INC < GANDHI < OBI WAHN"                       " < CRAZY < LOWANG < DAISY < JOE < DAYWALKER=====WE ARE LOOKING FOR MOTIVATED CODERS AND GFX ARTISTS LIKE YOU"                       "==FEEL FREE TO CONTACT US ON EFNET PSX2GERMAN OR AT HQ DA UNDERCOVER HP FOR JOIN OUR PARTY===========           ";

//-----------------------------------------------------------------------------
//
// MAKE SPRITES + DEFINITION
//
//-----------------------------------------------------------------------------
GsSPRITE	sprKali[10];
GsSPRITE	sprKali2[10];
GsSPRITE	sprKali3[10];
GsSPRITE	sprKali4[10];

GsSPRITE	sprLetter;
GsSPRITE	sprLaub;
GsSPRITE	sprLaub1;
GsSPRITE	sprRight[250];
GsLINE		line; 				// horizontal line
GsGLINE		line2;				// horizontal line

char *pBaseText = scrtxt;
int iScrollOffset=0;

//--------------------------------------------------------------------------
//
// 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 DrawScroller(void);

int logosinoff=0;
int logosin1off=360;
int logosin2off=0;
int logosin3off=0;
int savedlogosin=0;
int savedlogosin1=0;
int savedlogosin2=0;
int savedlogosin3=0;

//--------------------------------------------------------------------------
//
// Function:	main() MAIN PROGRAM
// Description:	--
// Parameters:	--
// Returns:	int
// Notes:	N/A
//
//--------------------------------------------------------------------------
int main()
  {
  u_long lTmp1;
//-------------------- INIT OF THE  SLIDINGS -----------------------------------
  int iLogoPos=0,iLogoSpd=1,iTmp1;
  int iKaliPos2=-200,iKaliSpd2=1;	
  int iKaliPos3=-100,iKaliSpd3=2;	
  int iKaliPos4=-70,iKaliSpd4=2;	
//  int iKaliPos5=-70,iKaliSpd5=1;	
//  int iKaliPos6=0,iKaliSpd6=2;	
//  int iKaliPos7=-50,iKaliSpd7=1;	

  int iLaubPos=100,iLaubSpd=1;	
  int iLaubPos1=347,iLaubSpd1=1;	
  int i,j;
  int temp,temp1;
  int Move=1;//0;
//-------------------------------------------------------------------------  
PadInit(0);     // Joypad Init
init_LogoSprites();

  InitialiseGraphics(320,240,MODE_NTSC); // GFX Init, incl. Init active Buffer...

  FntLoad(960,256);
  FntOpen(0, 85, 320, 220, 0, 512);
  FntPrint("       X --> PAL       O --> NTSC\n");

RenderWorld(1);RenderWorld(1); // 2x bcause DoubleBuffering...

/*   // CHOOSE FREQUENCY
  while (1)
    {
    PADstatus=PadRead(4);

    if (PADstatus & Pad1crc)
      break; // HZMode Initvalue == MODE_NTSC

    if (PADstatus & Pad1x)
      {HZMode=MODE_PAL;break;
	}
    } */
 
 InitialiseGraphics(320,240,HZMode); // GFX Init, incl. Init act. Buffer...

//--------------------------------------------------------------------------
//
// LOAD MUSIC AND PLAY
//
//--------------------------------------------------------------------------
MOD_Init();
MOD_Load((u_char *)intro); // the Music File
MOD_Start();

//--------------------------------------------------------------------------  
//
// READ EXTERNAL INFO FROM USED PICTURES
//
//--------------------------------------------------------------------------  
LoadTIMData((u_long*)kali);
LoadTIMData((u_long*)kali4);
LoadTIMData((u_long*)kali2);
LoadTIMData((u_long*)kali3);

LoadTIMData((u_long*)font);
LoadTIMData((u_long*)laub);
LoadTIMData((u_long*)laub1);

LoadTIMData((u_long*)right);

// --------------------------- INIT LOGO -----------------------------------
SetSpriteInfo(&sprKali[0],(u_long)kali,100,120,1);
sprKali[0].v+=0;sprKali[0].h-=3;
SetSpriteInfo(&sprKali4[0],(u_long)kali4,170,120,1);
SetSpriteInfo(&sprKali2[0],(u_long)kali2,50,120,1);
SetSpriteInfo(&sprKali3[0],(u_long)kali3,290,120,1);
//SetSpriteInfo(&sprKali4[0],(u_long)kali,20,120,1);
//SetSpriteInfo(&sprKali4[0],(u_long)kali4,290,120,1);

SetSpriteInfo(&sprLaub,(u_long)laub,100,22,3);//x,y
SetSpriteInfo(&sprLaub1,(u_long)laub1,347,20,3);//x,y
//--------------------------------------------------------------------------  
//
// INIT LETTERS FOR SINUS SCROLLER
//
//--------------------------------------------------------------------------  
SetSpriteInfo(&sprLetter,(u_long)font,0,0,1);
	sprLetter.w=sprLetter.h=16;	// height of one used Letter
	sprLetter.mx=sprLetter.my=0;
	sprLetter.v=sprLetter.u=0;
{
 GsSortSprite(&sprLetter,&othWorld[currentBuffer],2);
 RenderWorld(1);
}
// -------------------------------------------------------------------------
//
//
// START MAIN LOOP
//
//
// -------------------------------------------------------------------------
   
while(1)
 {
int iTmp1,iTmp2,iTmp3,iTmp4,iTmp5;

   PADstatus=PadRead(4);
   if ((PADstatus&Pad1Start)) break;
//--------------------------------------------------------------------------
//
// SLIDINGS
//
//--------------------------------------------------------------------------
//  LOGO sliding from left to right and back
//
  if (iLogoPos<-40) iLogoSpd=2;
  if (iLogoPos>240) iLogoSpd=-502;
  iLogoPos+=iLogoSpd;

  if (iLaubPos<-17) iLaubSpd=1;
  if (iLaubPos>100) iLaubSpd=-1;
  iLaubPos+=iLaubSpd;
  if (iLaubPos1<230) iLaubSpd1=1;
  if (iLaubPos1>347) iLaubSpd1=-1;
  iLaubPos1+=iLaubSpd1;

//--------------------------------------------------------------------
//
//	SLIDING: the fallen leaves 
//  replace them with other images like a Star from my Lightforce Demo
//
//--------------------------------------------------------------------

  if (iKaliPos2<-30) iKaliSpd2=1;
  if (iKaliPos2>260) iKaliSpd2=-500;
  iKaliPos2+=iKaliSpd2;

    if (iKaliPos3<-10) iKaliSpd3=1;
    if (iKaliPos3>260) iKaliSpd3=-600;
    iKaliPos3+=iKaliSpd3;

    if (iKaliPos4<-100) iKaliSpd4=2;
    if (iKaliPos4>260) iKaliSpd4=-600;
    iKaliPos4+=iKaliSpd4;

//    if (iKaliPos5<0) iKaliSpd5=1;
//    if (iKaliPos5>250) iKaliSpd5=-600;
//    iKaliPos5+=iKaliSpd5;

//    if (iKaliPos6<0) iKaliSpd6=1;
//    if (iKaliPos6>250) iKaliSpd6=-500;
//    iKaliPos6+=iKaliSpd6;

//    if (iKaliPos7<0) iKaliSpd7=1;
//    if (iKaliPos7>250) iKaliSpd7=-500;
//    iKaliPos7+=iKaliSpd7;

//--------------------------------------------------
//
// FREE SLIDER FUNCION
//
//--------------------------------------------------
 sprKali[0].y=iLogoPos;
 sprKali4[0].y=iKaliPos4;
 sprKali2[0].y=iKaliPos2;
 sprKali3[0].y=iKaliPos3;

 sprLaub.x=iLaubPos;
 sprLaub1.x=iLaubPos1;


   //  sprInc.y=iIncPos2;
   //  sprUa1.x=iUa1Pos2;

//--------------------------------------------------
//
// Images ROTATION
//
//--------------------------------------------------
sprKali[0].rotate=ONE*iLogoPos;
GsSortSprite(&sprKali[0],&othWorld[currentBuffer],1);

sprKali2[0].rotate=ONE*iKaliPos2;
GsSortSprite(&sprKali2[0],&othWorld[currentBuffer],3);

sprKali3[0].rotate=ONE*iKaliPos3;
GsSortSprite(&sprKali3[0],&othWorld[currentBuffer],3);

sprKali4[0].rotate=ONE*iKaliPos4;
GsSortSprite(&sprKali4[0],&othWorld[currentBuffer],1);

//----------------------------------------------------
//
// Z PLANE DEFINITONS
//
//----------------------------------------------------
GsSortSprite(&sprLaub,&othWorld[currentBuffer],1);
GsSortSprite(&sprLaub1,&othWorld[currentBuffer],1);
//----------------------------------------------------
//
// MoveStars(); // no stars uses here
//
// wave the Tree trunk
logosinoff=savedlogosin;
logosin1off=savedlogosin1;
logosin2off=savedlogosin2;
logosin3off=savedlogosin3;

for(i=0;i<250;i++) //height of an image
{
   sprRight[i].x=logosin1[logosinoff]+100;/*64 -32 70 +32*/
{
  int iLogoPos=0,iLogoSpd=1,iTmp1;
  if (iLogoPos<-40) iLogoSpd=1;
  if (iLogoPos>40) iLogoSpd=-1;
  iLogoPos+=iLogoSpd;
//  sprLeft[60].rotate=ONE*iLogoPos;
}
//   sprLeft.y=0+i;
//   sprLeft.mx=0;
//   sprLeft.my=0;   

   sprRight[i].y=0+i;
   sprRight[i].mx=0;
   sprRight[i].my=-10;   


   GsSortFastSprite(&sprRight[i], &othWorld[currentBuffer], 2);

   logosinoff++;
   if (logosinoff==400) logosinoff=0;
   logosin1off++;
   if (logosin1off==400) logosin1off=0;
   logosin2off++;
   if (logosin2off==400) logosin2off=0;
   logosin3off++;
   if (logosin3off==400) logosin3off=0;
   }
savedlogosin++;
   if (savedlogosin==400) savedlogosin=0;
   savedlogosin1++;
   if (savedlogosin1==400) savedlogosin1=0;
   savedlogosin2++;
   if (savedlogosin2==400) savedlogosin2=0;
   savedlogosin3++;
   if (savedlogosin3==400) savedlogosin3=0;

//--------------------------------------------------------
//
// DRAW 3 LINES
//
//--------------------------------------------------------
//	line2.r0=238;line2.g0=226;line2.b0=240;
	line2.r1=238;line2.g1=226;line2.b1=240;
//	line2.x0=0;
//      line2.y0=0;
//      line2.y1=0;
        line2.x1=319;

//	line3.r0=238;line3.g0=226;line3.b0=240;
//	line3.r1=238;line3.g1=226;line3.b1=240;
//	line3.x0=116;line3.x1=276;
//      line3.y0=97,line3.y1=97;

    GsSortGLine(&line2,&othWorld[currentBuffer],1);
    line2.y0=line2.y1=239;
    GsSortGLine(&line2,&othWorld[currentBuffer],1);

//  GsSortGLine(&line3,&othWorld[currentBuffer],1);
//  line3.y0=0,line3.y1=120;
//  GsSortGLine(&line3,&othWorld[currentBuffer],1);
//-------------------------------------------------------------
DrawScroller();  
RenderWorld(1);
  }
  MOD_Stop();MOD_Free();VSync(3);

  PadStop();
  ResetGraph(0);
  StopCallback();
//-------------------------------------------------------------
//
//
// PATCH: DECRUNCH THE GAME
//
//
//-------------------------------------------------------------
EnterCriticalSection();
depack1();
start1();
ExitCriticalSection();
//-------------------------------------------------------------
//
// START THE ORIGINAL GAME
//
//-------------------------------------------------------------
asm("nop");
asm("j 0x8008119c"); // ExecAdresse to extract the Game to play
asm("nop");
//_96_init();//printf("_96_Init\n");
//LoadExec("cdrom:\\SCES_000.10;1",0x801fff00,0); Load an extra exe File from the demo

  return 0;
  }

void DrawScroller(void)
{
  int iTmp1,iTmp2,iTmp3;
  char *pText;

  iSinOff1+=4;iSinOff1%=MAXSINVALUE;
//  iSinOff2+=254;iSinOff2%=MAXSINVALUE;// + 254 equal to -2


  if (iScrollOffset<=-32) {pBaseText++;iScrollOffset+=16;}
  // expand to -32, because we have a horizontal sinus...
  iScrollOffset-=SCRSPEED;

  if (*pBaseText==NULL) // End Scrolltext
     pBaseText=scrtxt;
     pText=pBaseText;   // temp Text Pointer

  for (iTmp1=0;iTmp1<30;iTmp1++) // show max 11 signs
    {
    iTmp2=*pText;
    if (iTmp2) // if Signs >0
      {
      if (iTmp2>'Z') iTmp2=' ';
      iTmp2-=' ';
    //  // target Coordinates
      sprLetter.x=iScrollOffset+16*iTmp1;
      iTmp3=SinusS1[(iSinOff1+sprLetter.x)%MAXSINVALUE];
//    -SinusS2[iSinOff2];
      sprLetter.y=YPOS+iTmp3; // source Coordinates
      sprLetter.x+= SinusS1[(iSinOff1+sprLetter.x)%MAXSINVALUE]/2;
      sprLetter.u=(iTmp2%8)*16;
      sprLetter.v=(iTmp2/8)*16;
      GsSortSprite(&sprLetter,&othWorld[currentBuffer],1); //"2" Scroller Layer
      pText++;
      }
    }
  }
  
//------------------------------------------------------------------------------
//
//
// F U N K T I O N S   D E F I N I T I O N E N
//
//
//------------------------------------------------------------------------------
// Function:	InitialiseGraphics()
// Description:	ini GFX System
// Parameters:	MODE_USED	-> PAL, NTSC
// Returns:	void
// Notes:	Attention: Ini also for 3d! (Coord absolute middle!!)
//------------------------------------------------------------------------------

void InitialiseGraphics(int SCRWidth,int SCRHeight,int HZMode)
  {
  SetVideoMode(HZMode);

  if ((HZMode == MODE_NTSC) && (SCRHeight==256)) SCRHeight=240;
    // 		Init VRAM (Resolution X, Resolution Y,
    //		Interlace  0/1 off/on | Offset 0/1 GTE/GPU,
    //		Ditherflag 0/1 off/on,
    //		VRAM Modus 0/1  16/24 Bit)
  GsInitGraph(SCRWidth, SCRHeight, GsNONINTER|GsOFSGPU, 0, 0);

    // Definition 2 "Double Buffer" to draw
    //		(X-Coordinate , Y-Coordinate   -> Buffer 0 (0,0)
    //		 X-Coordinate , Y-Coordinate   -> Buffer 1 (0,YRes) )
  GsDefDispBuff(0, 0, 0, SCRHeight);
    // Correct errors in the Libraries
  if (SCRHeight == 256) GsDISPENV.screen.h=256;


  // Init 3D GFX, ! REMEMBER: Coordniate"middle" set to Center!!!
  // GsInit3D();

  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]);

    // grab current Buffer
  currentBuffer=GsGetActiveBuff();

    // set Adress for "Packet"-Building
  GsSetWorkBase((PACKET*)out_packet[currentBuffer]);
  }
//------------------------------------------------------------------------------
//
// Function:	RenderWorld(char cClear)
// Description:	This Function handle the DoubleBuffer...
//				(ordering tables etc)
// Parameters:	char cClear: if True set "CLS" for OT
// Returns:		void
// Notes:		--
//
//------------------------------------------------------------------------------

void RenderWorld(char cClear)
  {
    // ------------------------------------ "old List"

  v_countCODE=VSync(1);
  DrawSync(0);
  v_countGFX = VSync(1);
  VSync(0);	// wait until GPU is reade with the "old List"

    // switch both Buffers (Display / Drawing)
  GsSwapDispBuff();

    // ------------------------------------ "current List"

    // "register" a "ClearScreen"-command in OT  R, G, B
if (cClear==1)  GsSortClear( 35, 45, 0,&othWorld[currentBuffer]); // background color
if (cClear==155)  GsSortClear( 0, 0,  0,&othWorld[currentBuffer]);


    // start draw modus ( GPU is drawinging the OT in the background )
  GsDrawOt(&othWorld[currentBuffer]);
  FntFlush(-1);
// ------------------------------------ "new List"

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

    // set Adress for "Packet" creation
  GsSetWorkBase((PACKET*)out_packet[currentBuffer]);

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

    // OT is now reade to receive GsSort... Commands
  }
//------------------------------------------------------------------------------
//
// Function:	LoadTIMData (u_long tMemAddress)
// Description:	transfer a .TIM File from Main Mem into VideoRam
// Parameters:	u_long tMemAddress - Adress by TIMs in the main MEM
// Returns:	void
// Notes:	--
//
//------------------------------------------------------------------------------

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

  DrawSync(0);
  //tMemAddress += 4;                 // set pointer to File start
  tMemAddress++;
  GsGetTimInfo(tMemAddress, &tTim);   // save TIM-Informations in Tim
  tRect.x = tTim.px;
  tRect.y = tTim.py;
  tRect.w = tTim.pw;
  tRect.h = tTim.ph;
  LoadImage(&tRect, tTim.pixel);	  // Load TIM-Files in 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 in VideoRam
    };

  DrawSync(0);					      // wait until GPU has finished its work
  }
//------------------------------------------------------------------------------
//
// Function:	SetSpriteInfo(...)
// Description:	Init an amount of Input for Sprites
// Parameters:	- set Pointer to Sprite structure
//				- Adress (RAM) by the connected TIMs
//				- Position of a Sprite   X and Y
//				- CutParameter: correct the Clut Error, shrink a sprite to
//		  		  avoid ugly stripes in the graphic the image
// Returns:		void
// Notes:		Set "reference point" by a Sprite in the middle
// Attentione:  this have no effect to GsSortFastSprite !!!!
//------------------------------------------------------------------------------

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

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

  tSprite->x = tX;				// set Coordinates for
  tSprite->y = tY;				// definition on call

  switch (tTim.pmode & 3)		// X-Value depending on its BitDepth
    {
    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 = (tTim.px / 64) + 16* (tTim.py / 256);
  tSprite->tpage = GetTPage((tTim.pmode & 3),0,tTim.px,tTim.py);

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

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

  tSprite->r = tSprite->g = tSprite->b = 128;	// normal intensity ( by its colors)
												// set to Standard
  tSprite->mx = tSprite->w/2;					// Referencing point for a sprite of its middle point
  tSprite->my = tSprite->h/2;					// set it ( not necessary )

  tSprite->scalex = tSprite->scaley = ONE;	// Skale to 1 (normal Size)
  tSprite->rotate = 0;						// Rotate Degree to 0

  if (tCut)									// Sprite "shrink" if a Tim
    tSprite->w -= tCut;						// have an illegal width
  };

void init_LogoSprites()
{
int i=0,j=0,k=0;
  SetSpriteInfo(&sprRight[250],(u_long)right,0,0,3);//x,y

sprRight[250].w=160;
sprRight[250].h=1;
sprRight[250].u=0;
sprRight[250].v-=30;

sprLetter.w=16;
sprLetter.h=1;
sprLetter.u=0;
sprLetter.v-=30;

for(i=1;i<250;i++) // 68 the height of the picture
//for(i=1;i<240;i++) // 68 the height of the picture
   {
	sprRight[i]=sprRight[250];
	sprRight[i].u=0;
	sprRight[i].v=i;
   }
}
Image

The Code is the same that i used for this Cracktro:
[youtube]https://youtu.be/RQp4BZMgtlI[/youtube]

You download the altered Sourcecode by this Patch:
[youtube]https://youtu.be/RRRLPuAYPdU[/youtube]


The Folder contain all Files. Make sure that you correct your Paths to your local Emulator.

See Batch file:

Code: Select all

@echo off
@echo.
@echo.
@echo.
@echo.
@echo.
@echo.
@echo.
@echo.
@echo.
::================================
:: some colors for different lines
::================================
call color 0e 
echo        DELETING OLD OBJ FILES
@echo.
@echo.
::================================
:: a short pause
::================================
@ping -n 3 localhost> nul
@rem del *.obj
@rem del *.bin
@echo.
::================================
:: clear screen
::================================
@cls
@echo.
@rem spasm -b tob0ins.asm tob0ins.bin
@rem asmpsx /l icarus.asm,icarus.obj
@rem asmpsx /l copyroutine.asm,copy.obj
@ping -n 2 localhost> nul
call color 0e 
asmpsx.exe /l/oat- depack.src, depack.obj
@echo.
@echo.
call color 0a
@ccpsx -O3 -Xo$80100000 main.c data/*.obj copy.obj icarus.obj depack.obj -omain.cpe, main.sym, mem.map
@echo.
@echo.
@echo.
@echo.
@cpe2x main.cpe
@echo.
@echo off
@del mem.map main.cpe mem.map
@echo.
@echo.
@echo.
echo.renaming main.exe to SPIDERMAN.exe
@ren main.exe SPIDERMAN.exe
@echo.
@echo.
@echo.
echo.the Compiled Patch will now copied to the PSX EMU FOLDER and RUN automatically
@echo.
@echo off
@move SPIDERMAN.exe C:\__ANAKIN\PS1_EMU
@cd C:\__ANAKIN\PS1_EMU
@ePSXe.exe SPIDERMAN.exe -nogui

rem @ping -n 1 localhost> nul
rem exit
DRAWER LIST:

Image

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.
Last edited by inc^lightforce on February 16th, 2023, 7:57 am, edited 1 time in total.

User avatar
masterg0r0
Active PSXDEV User
Active PSXDEV User
Posts: 65
Joined: Jul 18, 2021
I am a: Programmer
Motto: They see me rollin'
PlayStation Model: 1002+7502
Location: UK

Post by masterg0r0 » January 2nd, 2023, 7:11 am

Thanks for the tutorial, Lightforce.
PSX Dev. Console: SCPH-7502 (PAL), MM3, Xplorer with Caetla 0.38.

Computer: Compaq Armada 1750, Windows 98SE, Pentium II 333MHz, 256MB RAM, 40GB IDE HDD, ESS AudioDrive, CD Drive, 3.5" Floppy (broken).

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

Post by inc^lightforce » January 12th, 2023, 5:56 pm

Sorry but i noticed that some one here try to be a God of programming.
TROLLS WILL BE BANNED PERMANENTLY !

Why all of you, who are Newbe's do not accept and honor the Workshop to learn how to code something on an PS1 and be lucky that i share my knowledge and Source Codes????

This is really ridiculous what i get in my inBox these Days.


IF it does not change immediately i close this WORKSHOP and delete all my files.


regards

Inc
Last edited by inc^lightforce on January 20th, 2023, 6:21 pm, edited 1 time in total.

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

Post by inc^lightforce » January 20th, 2023, 5:49 am

I have programmed a new Tool for these days. old DOS MOD Converter rewritten for modern Windows Versions:

Image

get all information from here:

viewtopic.php?f=75&t=4037


happy Coding

inc.
Last edited by inc^lightforce on February 19th, 2023, 6:55 pm, edited 1 time in total.

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

Post by inc^lightforce » February 12th, 2023, 8:46 pm

another day another tutorial for the first Workshop in 2023

today you can have a look into Sprite usage like Bubbles in a Demo with 2 scroll text lines.


I have programmed this patch in 2002 for:

The_Baseball_2_Jap_Psx-ORGASM


Get all information from the attached Files.
It include the original Images, Tim Files and the Map.psx that you can load into TimTool.

Also the commented SourceCode and a compiled PS1 Exe File that you can run and view in epsxe 1.6.0

Image

The Folder contain all Files. Make sure that you correct your Paths to your local Emulator.

See Batch file:

Code: Select all

@echo off
@echo.
@echo.
@echo.
@echo.
@echo.
@echo.
@echo.
@echo.
@echo.
::================================
:: some colors for different lines
::================================
call color 0e 
echo        DELETING OLD OBJ FILES
@echo.
@echo.
::================================
:: a short pause
::================================
@ping -n 3 localhost> nul
@del depack.obj
@rem del *.bin
@echo.
::================================
:: clear screen
::================================
@cls
@echo.
@ping -n 2 localhost> nul
call color 0e
asmpsx.exe /l/oat- depack.src,depack.obj
@echo.
@echo.
call color 0a
@ccpsx -O3 -Xo$80090000 main.c DATA/*.obj DATA/Include_H/*.h depack1.obj -omain.cpe
@echo.
@echo.
@echo.
@echo.
@cpe2x main.cpe
@echo.
@echo off
@del main.cpe
@echo.
@echo.
@echo.
echo.renaming main.exe to BubblesDemo.exe
@ren main.exe BubblesDemo.exe
@echo.
@echo.
@echo.
echo.the Compiled Patch will now copied to the PSX EMU FOLDER and RUN automatically
@echo.
@echo off
@move BubblesDemo.exe C:\__ANAKIN\PS1_EMU
@cd C:\__ANAKIN\PS1_EMU
@ePSXe.exe BubblesDemo.exe -nogui

rem @ping -n 1 localhost> nul
rem exit

Folder Structure:

Image

Code: Select all

//***************************************************************
//
//    LOADER code by Inc. - UCA - Lightforce		
//
//
//    proggy-type:  ---- PAL to NTSC PATCH ----
//
//    original  code and program:   07.08.2002
//
//    now for your pleasure rewritten in February 2023
//
//	  CODE, GFX: INC. Lightforce !!
//
//    recoded with Notepad
//    tested with epsxe 1.60
//
//
//***************************************************************
//
// 			 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 "DATA\Include_H\PAD.H"
#include "DATA\Include_H\SINUSS.H"
#include "DATA\Include_H\COLORSIN.H"
#include "Data\Include_H\Hitmod.H"
//***************************************************************
//
//           A S M  ADDRESS DEFINITION
//
//***************************************************************
#define NOP		0x00000000
#define PAL		0x24020001
#define	NTSC	0x24020000
int Video_MODE=0;
//---------------------------------------------------------------
#define DEVELOPEMENT
#define ORDERING_TABLE_LENGTH 	(12)
#define MAX_NO_PACKETS  		(3000)
#define	rnd(max)				((rand()*(max))/(32768)+1)
#define OBJECTMAX 100			/* Max Objects defines maximum number of logical objects a 3D model can be divided into*/
#define SCRSPEED          1 	// Scrollspeed der Laufschrift
#define YPOS              225 	// Y-Position der Laufschrift
#define XPOS              317 	// Y-Position der Laufschrift
//***************************************************************
//
// Bubbles  Definition
#define MAXBLASEN (30)
// Bubbles End
//
//***************************************************************
extern char re[];		//right site of the background image
extern char li[]; 		//left site of the background image
extern char ka[];		//represent the quater in the right corner
extern char music[]; 	//HITMOD-Modul 
extern char font[];		// draw font scroller 1	
extern char font1[];	// draw font scroller 2
extern char blg[];		// Bubble big
extern char blm[];		// Bubble medium
extern char blk[];		// Bubble small

//***************************************************************
//
// values for our used scrolltest
//
//***************************************************************
static int iSinOff1=0;
static int iSinOff2=0;
//***************************************************************
//
// type your text here ( i used two languages back in the days)
//
//***************************************************************
#define MAXSINVALUE 256
char scrtxt[] = ">>>>>>>>>>>HI>ALL===>TODAY>PRESENTED>A>GAME>CALLED"
                "D>THE>BASEBALL>2>BY>D3>PUBLISHER>NTSC>JAP>=>IT S>BEE"
                "N>A>LONG>TIME>AGO>THAT>YOU>HAD>SEEN>A>COOL>NTSC>TO>PAL"
                ">SELECTOR=>CODING>GFX>AND>THIS>LITTLE>RMX>OF>DE"
                ">LA>SOUL>WAS>COMPLETE>DONE>BY>INC=>OF>UNDERCO"
                "VER>AGENTS=>YES>WE>ARE>ALIFE>=>TODAY>WE>GOT>THE>0"
                "8=08=2002=>NOBODY>OF>US>KNOW>HOW>LONG>WE>WILL>CO"
                "DE>SOME>NICE>TROS>FOR>THIS>CONSOLE=>CAUSE>PS1>WIL"
                "L>DIE>VERY>SOON=>BUT>NO>PROBLEM>WITH>THAT=>I>WILL"
                ">CHANGE>TO>PS2>AND>GO>AHEAD>WITH>NICE>CODINGS===="
                ">SOME>GREETS>I>WILL>SEND>OUT>TO>ANY>FRIENDS>AND>I"
                ">HOPE>ALL>YOU>READ>THIS>=>GANDHI>=>OBI>WAHN>=>GOO"
                "SE>=>ZWEIFELD>=>ALIEN>=>TURSI>=>PHANTOM>=>TRASHER"
                ">=>ZERO>G=>=>SJAAK>=>AUMATT>=>LOWANG>=>CRAZY>=>RK"
                "R>=>HUDSON>=>MP>=>CRACKTRO=DE>=====>WHERE>HAS>OUR"
                ">UNITY>GONE>TODAY?>IF>YOU>ARE>A>SKILLED>CODER>OR>MUSICI"
                "AN>OR>YOU>ARE>A>NICE>GFX>ARTIST>AND>NEED>A>JOB>SO>FEEL>FREE>TO>C"
                "ONTACT>US>AT>IRC>USING>EFNET>IN>CHANNEL:>LIGHTFOR"
                "CE>OR>CHANNEL>UCA===YOU>ALSO>CAN>LEAVE>ME>A>E<MA"
                "IL:>MAILGATE_A5R <AT>GMY=DE=>WE>GOT>A>LOT>OF>WORK>"
                "TO>DO>FOR>SPEED>UP>OUR>BUSINESS>OF>SUPPORTING>THE"
                ">NEWEST>GAMES>ON>EVERY>CONSOLE>THAT>EXIST=>MAYBE>"
                "YOU>CAN>GET>GAMES>FASTER>THAN>THE>OFFICIAL>RELEASE="
                "DATES>IN>SHOPS>SO>DONT>HESITATE>TO>CONTACT>US=>>"
                ">>BYE>BYE=>I>WILL>GO>SLEEP>NOW=>IT>S>LATE>AND>THE>"
                "INTRO>IS>FINISHED=>PRESS>(X)>FOR>PAL>OR>(O)>FOR>NTSC>"
                "FUN=>>>>>>>>>>>>>>>>>RELOAD>>>>>>>>>>>>>>>>>>>>>>"
                ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>";

char scrtxt1[] = ">>>>>>>>>>>>>>>>HALLO>IHR===>HEUTE>PRESENTIEREN>W"
                 "IR>EUCH>EIN>FEINES>GAME>THE>BASEBALL>2>BY>D3>PUBL"
                 "ISHER>JAP>NTSC=>ES>IST>NUN>SCHON>NE>WEILE>HER;>D"
                 "ASS>ICH>MAL>WIEDER>EIN>>HMMMM;>UNGLAUBLICH>COOLES"
                 ">INTRO>AUF>DER>PSX>GECODET>HAB=>PROGRAMMIERT;>GRA"
                 "FIK>UND>DER>SOUND>WURDEN>VON>INC=>OF>UCA>IN>EINER"
                 ">NACHT>ZUSAMMENGWUERFELT=>JO>UNDERCOVER>AGENTS>GI"
                 "BTS>NOCH>HE>HE=>HEUTE>HABEN>WIR>NUN>SCHON>DEN>08="
                 "08=2002=>HAPPY>BIRTHDAY>DJ>CAIN=>===>MAL>SEHEN>WI"
                 "E>LANGE>WIR>NOCH>AUF>DER>PS1>FEINE>INTROS>CODEN>W"
                 "ERDEN;>DA>JA>IMMER>WENIGER>SPIELE>KOMMEN>UND>BALD"
                 ">WIRD>DAS>TEIL>GANZ>TOD>SEIN=>ABER>DAS>SOLL>UNS>M"
                 "AL>NICHT>STOEREN>DENN>DANN>HABEN>WIR>EINEN>GRUND>"
                 "AUF>DER>PS2>WEITERZUMACHEN====>NUN>NOCH>GRUESSE>A"
                 "N>DIE>LEUTZ>DIE>ICH>UND>WIR>SO>KENNEN>UND>ICH>HOF"
                 "FE;>DASS>DIE>AUCH>ANKOMMEN=>=>GANDHI>=>OBI>WAHN>="
                 ">GOOSE>=>ZWEIFELD>=>ALIEN>=>TURSI>=>PHANTOM>=>TRA"
                 "SHER>=>ZERO>G=>=>SJAAK>=>AUMATT>=>LOWANG>=>CRAZY>"
                 "=>RKR>=>HUDSON>=>MP>=>DIE>FETTESTE>CRACKTRO=DE>SE"
                 "ITE>IM>NETZ>=>UND>ALL>DIE;>DIE>GEGRUESST>WERDEN>W"
                 "OLLEN;>ICH>ABER>VERGESSEN>HABE>SORRY>=>WAS>IST>AU"
                 "S>DER>PS1>SZENE>GEWURDEN?>===>NUN>ISSES>06=UHR>ZE"
                 "IT>ZUM>PENNEN>UND>NOCH>NEN>KAFFEE>ZU>SCHLUERFEN=="
                 "=>WER>MOTIVATION>BESITZT>UND>AUCH>CODED>ODER>SOUN"
                 "D>ODER>GRAFIKER>MACHT;>IST>DANN>MELDE>ER>SIE>SICH"
                 ">BEI>MIR=>HAB>IMMER>ARBEIT>FUER>EUCH>HE>HE>HE>==="
                 ">DJ<INC>AT>Q<BASE=CO=UK=>ODER>IM>IRC>EFNET;>USE>M"
                 "IRC>CHANNEL:>UCA>>>>>>>>RELOAD";
//***************************************************************
//
// FONT & Sprite Textures 
//
//***************************************************************
GsSPRITE	sprLi;			//Background image left
GsSPRITE	sprRe;			//Background image right
GsSPRITE	sprLetter;		// Font 1
GsSPRITE	sprLetter1;		// FONT 2
GsSPRITE	sprKa;			// Quater

GsSPRITE 	Sprites[300];	//Gandhi-Sprites
GsBOXF		myBox[4];
GsSPRITE	sprBlG[100];	// Bubbles Big
GsSPRITE	sprBlM[100];	// Bubbles Medium
GsSPRITE	sprBlK[100];    // Bubbles Small


char            *pBaseText = scrtxt;
char            *pBaseText1 = scrtxt1;

int sin1=0;
int sin2=0;
int logosinoff=0;
int iScrollOffset=0;
int iScrollOffset1=0;
int iScrollOffset2=0;
int delay=0;
int test,test1;
//***************************************************************
//
// 			   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;		// current Buffer for "double buffering"
u_long		PADstatus=0;	// Value to save PAD-Status
int         v_countGFX=0, v_countCODE=0; // HSync Counter
u_char      HZMode=MODE_NTSC;
//***************************************************************
//
//			END G L O B A L S
//
//
//***************************************************************
//
//		       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 InitBackGroundTiles(void);
void DrawScroller(void);
void init_Typer(void);
void do_Typer(void);
void init_Page(int);
void do_Vorhang(void); // it`s the fade in effect
void MoveBlasen(void); // Move Bubbles
void initBlasen(void); // init Bubbles
//***************************************************************
//
// Function:	main()
// Description:	--
// Parameters:	--
// Returns:	int
// Notes:	N/A
//
//***************************************************************

int main()
  {
	u_long	*ficken;
  	u_long lTmp1;
     	int i,j;
	int temp,temp1;

PadInit(0);     // Joypad Init
//***************************************************************
//
// AUTO PSX MODE SELECT if the original game is NTSC
//
//***************************************************************
 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...
//***************************************************************
	MOD_Init();
  	MOD_Load((u_char *) music);
  	MOD_Start();
//***************************************************************
	LoadTIMData((u_long*)li); 				// left background
	LoadTIMData((u_long*)re); 				// right background
	LoadTIMData((u_long*)ka);               // Quater
	LoadTIMData((u_long*)font);				// font 1
	LoadTIMData((u_long*)font1);            // font 2
	LoadTIMData((u_long*)blg); 				// Bbbles big
	LoadTIMData((u_long*)blm);				// Bbbles medioun
	LoadTIMData((u_long*)blk);				// Bbbles small
//***************************************************************
//
// INIT SPRITES
//
//***************************************************************
SetSpriteInfo(&sprRe,(u_long)re,0,0,0); // right background
SetSpriteInfo(&sprLi,(u_long)li,0,0,0); // left background
SetSpriteInfo(&sprKa,(u_long)ka,0,0,0); // the quater
SetSpriteInfo(&sprBlG[0],(u_long)blg,0,0,0); // Bubble-Big
SetSpriteInfo(&sprBlM[0],(u_long)blm,0,0,0); // Bubble-medium
SetSpriteInfo(&sprBlK[0],(u_long)blk,0,0,0); // Bubble-small
//***************************************************************
//
// devs and sprite for scroll text//
//
//***************************************************************
SetSpriteInfo(&sprLetter,(u_long)font,0,0,0);
sprLetter.w=sprLetter.h=32;
sprLetter.mx=sprLetter.my=32;

SetSpriteInfo(&sprLetter1,(u_long)font1,0,0,0);
sprLetter1.w=sprLetter1.h=32;
sprLetter1.mx=sprLetter1.my=32;
//***************************************************************
//
// some devinition for our Bubbles//
//
//***************************************************************
for (i=0;i<MAXBLASEN;i++)
   {    
    sprBlG[i]=sprBlG[0];
    sprBlG[i].mx=8;
    sprBlG[i].my=8;
    sprBlM[i]=sprBlM[0];
    sprBlK[i]=sprBlK[0];
    }
initBlasen();
//***************************************************************
//
//
//   M A I N
//
//
//***************************************************************
while(1)
 {
	int iTmp1,iTmp2,iTmp4,iTmp5;
	int i,k;
	PADstatus=PadRead(4);
MoveBlasen();
    	if(PADstatus&Pad1x){Video_MODE=1; break;	} // JOYPAD Input
		if(PADstatus&Pad1crc){Video_MODE=2; break;	} // JOYPAD Input

GsSortSprite(&sprLi, &othWorld[currentBuffer], 4);
GsSortSprite(&sprRe, &othWorld[currentBuffer], 4);
GsSortSprite(&sprKa, &othWorld[currentBuffer], 2);

sprRe.x=245; // Position right Background
sprRe.y=120; // Position right Background
sprLi.x=85;  // Position left Background
sprLi.y=120; // Position left Background

sprKa.x=293; // Position quater
sprKa.y=213; // Position quater

do_Vorhang(); // the Demo Fading
	
delay++;//printf("DELAY %D\n",delay);
if(delay>70) 
{	delay=70;
	DrawScroller();	
}

			
RenderWorld(60);
       }
  	SpuInit();
	SpuQuit();
 	MOD_Stop();
	MOD_Free();
	PadStop();
  	ResetGraph(0);
  	StopCallback();
	//***************************************************************
	//  defintition PATCH FUNKTION - Game decrunch
	//***************************************************************
	EnterCriticalSection();
	depack1();
	ExitCriticalSection();
	//***************************************************************
	//
	// define patching Video_MODE==1 (PAL)
	//			       Video_MODE==2 (NTSC)
	//
	//***************************************************************
        if(Video_MODE==1)
        {
          ficken = (u_long *)0x800955ec;         *ficken = 0x24020001; // Get Video
          ficken = (u_long *)0x800955f0;         *ficken = NOP;        // Get Video

          ficken = (u_long *)0x800934e8;         *ficken = 0x24900030; // X-Delta
          ficken = (u_long *)0x800934ec;         *ficken = 0x24900030; // X-Delta
        }
//***************************************************************
//
// if game pad button hit...
//
// start game
//
//***************************************************************
asm("nop");
asm("j 0x8009dcf8"); // ExecAddress to load the Game
asm("nop");
}
//
//   END MAIN
//***************************************************************
//
// 	 D E F I N I T I O N S
//
// Function:	InitialiseGraphics()
// Description:	initialisiert das Grafik-System
// Parameters:	MODE_USED	-> PAL, NTSC
// Returns:		void
// Notes:		NOTE: Init also for 3D! (Coordinates centering)
//
//***************************************************************
void InitialiseGraphics(int SCRWidth,int SCRHeight,int HZMode)
  {
  SetVideoMode(HZMode);

  if ((HZMode == MODE_NTSC) && (SCRHeight==256)) SCRHeight=240;
    // Init VRAM (Resolution Y,
    // interlace  0/1 off/ on Offset 0/1 GTE/GPU,
    // Ditherflag 0/1 off/ on,
    // VRAM Mode 0/1  16/24 Bit)
  GsInitGraph(SCRWidth, SCRHeight, GsNONINTER|GsOFSGPU, 0, 0);
    // Define "Double Buffer" 
    // X-Koordinate , Y-Koordinate   -> Buffer 0 (0,0)
    // X-Koordinate , Y-Koordinate   -> Buffer 1 (0,YRes) )
  GsDefDispBuff(0, 0, 0, SCRHeight);
    // correct errors occurs by libs
    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 actual Buffer
  currentBuffer=GsGetActiveBuff();

   // set Address for "Packet"-Builing
  GsSetWorkBase((PACKET*)out_packet[currentBuffer]);
  }

//***************************************************************
//
// Function:	RenderWorld(char cClear)
// Description:	this Function handle DoubleBuffer...
// (ordering tables etc)
// Parameters:	char cClear: on True do and add "CLS" at OT
// Returns:	void
// Notes:	--
//
//***************************************************************
void RenderWorld(char cClear)
  {
    // old list

  v_countCODE=VSync(1);
  DrawSync(0);
  v_countGFX = VSync(1);
  VSync(0);	// waite unti GPU is ready with "old List"

  // switchBuffer (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(207,156,79,&othWorld[currentBuffer]);
  if (cClear==255)  GsSortClear(0,0,0,&othWorld[currentBuffer]);
  // start drawing (GPU draw the OT in the background)
  GsDrawOt(&othWorld[currentBuffer]);
  FntFlush(-1);
  // ------------------------------------ "NEW List"
  // init next OT
  // grab current Buffer
  currentBuffer=GsGetActiveBuff();
  // create address for packet building
  GsSetWorkBase((PACKET*)out_packet[currentBuffer]);
  // delete content of OT
  GsClearOt(0, 0, &othWorld[currentBuffer]);
  // OT is now rerady to receive GsSort... Commands
  }
//***************************************************************
//
// Function:	LoadTIMData (u_long tMemAddress)
// Description:	transfer a .TIM File from Main Mem into VidMem
// Parameters:	u_long tMemAddress - Adress by a TIM in MAin Mem
// Returns:		void
// Notes:		--
//
//***************************************************************

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);	 // 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);	// load CLUT into VideoRam
    };

  DrawSync(0);					   // waite until GPU is done
  }
//***************************************************************
//
// Function:	SetSpriteInfo(...)
// Description:	Init# something for Sprites
// Parameters:	- Pointer to structuro of a Sprite
//				- Address (RAM) for TIMs
//				- Position X und Y
//				- CutParameter: correct Sprite if we need it smaller
//		          if we face ugly stripes next to our images by the TIM files
// Returns:	    void
// Notes:	    Sett rev point in the absolute middle
// Watch out:   this has no effect to GsSortFastSprite
//
//***************************************************************

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

  tMemAddress += 4;				// Pointer to File
  GsGetTimInfo((u_long *) tMemAddress, &tTim);	// get TIM Info in tTim

  tSprite->x = tX;				// set Coordinates
  tSprite->y = tY;				

  switch (tTim.pmode & 3)		// X-Values depending by the Bit Depth
    {
    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 Intensity (Colors)
						                 // set to Standard
  tSprite->mx = tSprite->w/2;			 // Ref-Point of Sprites to the middle
  tSprite->my = tSprite->h/2;			
  tSprite->scalex = tSprite->scaley = ONE;	// Scale to 1 (original Size)
  tSprite->rotate = 0;				        // Rotation to 0

  if (tCut)							// cut Sprite if our TIM have 
    tSprite->w -= tCut;				// an "illegal" width
  };
//***************************************************************
//
// Bubbles Code
//
//
//***************************************************************
void initBlasen()
  {
  int l,zi,zi2,zi3;
  srand(1);
  for(l=0;l<MAXBLASEN;l++)
    {
    zi=rand()%420;
    sprBlG[l].x=zi;
    zi=rand()%340;
    sprBlG[l].y=zi;
    zi2=rand()%410;
    sprBlM[l].x=zi;
    zi2=rand()%340;
    sprBlM[l].y=zi2;
    }
  }
void MoveBlasen()
{
int i=0,j=0,k=0;

if(test<1) test1+=1;
if(test>20) test1-=1;
test+=test1;
iSinOff1+=1;iSinOff1%=MAXSINVALUE;
iSinOff2+=255;iSinOff2%=MAXSINVALUE;// + 254 = -2
  for (i=0;i<MAXBLASEN;i++)
      {
      	sprBlG[i].y-=2;
      	if (sprBlG[i].y==-10) sprBlG[i].y=250;
	sprBlG[i].mx=(SinusS1[iSinOff1]-(SinusS2[iSinOff2]));
	sprBlG[i].mx=sprBlG[i*2].mx+(SinusS1[iSinOff1]);
	sprBlG[i].mx=sprBlG[i*3].mx-(SinusS1[iSinOff2]);
	sprBlG[i].mx=sprBlG[i*2].mx+(SinusS2[iSinOff1]);
	sprBlM[i].y-=2;
      	if (sprBlM[i].y==-10) sprBlM[i].y=250;
	sprBlM[i].mx=(SinusS1[iSinOff1]-(SinusS2[iSinOff2]));
        sprBlM[i].mx=sprBlM[i*2].mx+(SinusS1[iSinOff1]);
	sprBlM[i].mx=sprBlM[i*3].mx-(SinusS1[iSinOff2]);
	sprBlM[i].mx=sprBlM[i*2].mx+(SinusS2[iSinOff1]);
	GsSortSprite(&sprBlG[i], &othWorld[currentBuffer], 1);
	GsSortSprite(&sprBlM[i], &othWorld[currentBuffer], 1);
 }
}
//***************************************************************
//
// DRAW SCROLL TExT
//
//***************************************************************
void DrawScroller(void)
  {
  int iTmp1,iTmp2,iTmp3,iTmp4,iTmp5;
  char *pText;
  char *pText1;

iSinOff1+=4;iSinOff1%=MAXSINVALUE;

  if (iScrollOffset<=-32) {pBaseText++;iScrollOffset+=32;}
  iScrollOffset-=SCRSPEED;
  if (*pBaseText==NULL) // end of Scroll text...
  pBaseText=scrtxt;

  if (iScrollOffset1<=-32) {pBaseText1++;iScrollOffset1+=32;}
  iScrollOffset1-=SCRSPEED;
  if (*pBaseText1==NULL) // end of scroll text
  pBaseText1=scrtxt1;

  pText=pBaseText;    	// pointer for Txt
  pText1=pBaseText1;    // temp Text pointe

  for (iTmp1=0;iTmp1<32;iTmp1++)   // show max 11 Signs
//  for (iTmp5=0;iTmp5<32;iTmp5++) // show max 11 Signs
  {
  iTmp2=*pText;
  if (iTmp2) // if Signs >0
  iTmp4=*pText1;
  if (iTmp4) // if Signs >0
  {
  if (iTmp2>'Z') iTmp2=' ';
  iTmp2-=' ';     // target Coordinates
  if (iTmp4>'Z') iTmp4=' ';
  iTmp4-=' ';    // target Coordinates
//***************************************************************
//
// SINUS IMPLEMENT
//
//***************************************************************
iTmp3=SinusS1[(iSinOff1+sprLetter.x)%MAXSINVALUE];
sprLetter.x+= SinusS1[(iSinOff2+sprLetter.x)%MAXSINVALUE]/2;


  sprLetter.x=iScrollOffset+32*iTmp1;
  sprLetter.y=YPOS+iTmp3;  // source coordinates
  sprLetter.u=(iTmp2%8)*32;
  sprLetter.v=(iTmp2/8)*32;
  GsSortSprite(&sprLetter,&othWorld[currentBuffer],3);
  pText++;

  sprLetter1.y=iScrollOffset1+32*iTmp1;
  sprLetter1.x=XPOS;//+iTmp3;  // source coordinates iTmp3 = sinus
  sprLetter1.u=(iTmp4%8)*32;
  sprLetter1.v=(iTmp4/8)*32;
  GsSortSprite(&sprLetter1,&othWorld[currentBuffer],3);
  pText1++;
  }
  }
  }
//***************************************************************
//
// START UP FADE IN
//
//***************************************************************
void do_Vorhang()
{
static char fade;
myBox[0].w=myBox[1].w=320;
myBox[0].h=myBox[1].h=120;
myBox[0].x=myBox[1].x=0;
myBox[0].y=0-fade;
myBox[1].y=120+fade;
GsSortBoxFill(&myBox[0],&othWorld[currentBuffer],0);
GsSortBoxFill(&myBox[1],&othWorld[currentBuffer],0);
if(fade<128)
fade++;
}


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.
Last edited by inc^lightforce on February 16th, 2023, 7:55 am, edited 3 times in total.

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

Post by inc^lightforce » February 16th, 2023, 7:32 am

another day another tutorial in 2023

today you can check, how to use a Sprite Sheet that contain a animated Character.

thats it:
Image


- 2 Lines on Top and the Bottom of the screen
- Typer


I have programmed this patch in 2001 for:

Saiyuki: Journey West (C) Koei


Get all information from the attached Files.
It include the original Images, Tim Files, *.bmp and the source gfx by the sprite sheet. use coreldraws
Photopaint to load it properly.

Also the commented SourceCode and a compiled PS1 Exe File that you can run and view in epsxe 1.6.0

Image

The Folder contain all Files. Make sure that you correct your Paths to your local Emulator.

See Batch file:

Code: Select all

@echo off
@echo.
@echo.
@echo.
@echo.
@echo.
@echo.
@echo.
@echo.
@echo.
::================================
:: some colors for different lines
::================================
call color 0e 
echo        DELETING OLD OBJ FILES
@echo.
@echo.
::================================
:: a short pause
::================================
@ping -n 2 localhost> nul
@del depack.obj
@rem del *.bin
@echo.
::================================
:: clear screen
::================================
@cls
@echo.
@ping -n 2 localhost> nul
call color 0e
asmpsx.exe /l/oat- depack.src,depack.obj
@echo.
@echo.
call color 0a
@ccpsx -O3 -Xo$80090000 main.c DATA\*.obj DATA\Include_H\*.h depack.obj -omain.cpe
@echo.
@echo.
@echo.
@echo.
@cpe2x main.cpe
@echo.
@echo off
@del main.cpe
@echo.
@echo.
@echo.
echo.renaming main.exe to CharacterDemo.exe
@ren main.exe CharacterDemo.exe
@echo.
@echo.
@echo.
echo.the Compiled Patch will now copied to the PSX EMU FOLDER and RUN automatically
@echo.
@echo off
@move CharacterDemo.exe C:\__ANAKIN\PS1_EMU
@cd C:\__ANAKIN\PS1_EMU
@ePSXe.exe CharacterDemo.exe -nogui


rem @ping -n 1 localhost> nul
rem exit
Folder Structure:

Image

Code: Select all

//--------------------------------------------------------------------------
//
//
//	LOADER code by Inc. - UCA - Lightforce
//
//
//	Saiyuki: Journey West (C) Koei
//	==============================
//
//	proggy-type:  NTSC to PAL PATCH
//	
//	original code and program:   20/08/2001
//
//	out now for your pleasure and education, rewritten in February 2023
//
//	CODE, GFX: INC. Lightforce !!
//	SOUND: SOBEC (R.i.P. BRO) & INC.
//
//
//  recoded with Notepad
//  tested with epsxe 1.60
//
//
//--------------------------------------------------------------------------




//--------------------------------------------------------------------------
//
//
// 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 "Data\Include_H\PAD.H"
#include "Data\Include_H\Hitmod.H"
//--------------------------------------------------------------------------
//
//
//	ASM ADRESS DEFINITION
//
//
//--------------------------------------------------------------------------
#define NOP		0x00000000
#define PAL		0x24020001
#define	NTSC	0x24020000
//--------------------------------------------------------------------------
#define DEVELOPEMENT
#define ORDERING_TABLE_LENGTH (12)
#define MAX_NO_PACKETS  (4000)
#define	rnd(max)	((rand()*(max))/(32768)+1)
//--------------------------------------------------------------------------
//
//
//	DEFINITION FOR THE CHARACTER, our MONSTER
//
//
//--------------------------------------------------------------------------
#define MONSTERSPRITES 4
#define	MAXCHAR	4
//--------------------------------------------------------------------------
//
//
//	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;	// BUFFER for DOUBLE BUFFERING
u_long PADstatus=0;	// Var to save PAD-Status
int v_countGFX=0, v_countCODE=0; // HSync Zaehler
u_char HZMode=MODE_NTSC; // auto Vid-Mode on start

int Xangle,Yangle,depth;
int Xangle2,Yangle2;

extern char music[];	// external Soundfile
extern char font1[];	// Image that contain the letters and signs
extern char Monster[];	// the running Monster on our screen
extern char rechts[];	// right background image
extern char links[];	// left background image
extern char logo[];		// Group Logo
extern char baum[];		// Tree image for the Foreground
//--------------------------------------------------------------------------
//
//
// Font-Sprites & Textures for the Typer
//
//
//--------------------------------------------------------------------------
#define	PAGEW	(27)	// Page Width
#define	PAGEH	(8)		// Page Height
#define	SIGNS	(32)	// <--- how many signs in we have in the source Image?
#define	ROWS	(3)		// <--- how much Rows? see the image in the Image Folder
#define	MAX_CHAR (PAGEH*PAGEW)

GsSPRITE fontspr[SIGNS * ROWS];
GsSPRITE page[MAX_CHAR];
//--------------------------------------------------------------------------
//
//
//	some more Definition for our Monster 
//
//
//--------------------------------------------------------------------------
GsSPRITE	scroll[MAXCHAR];
GsSPRITE	sprMonster[MONSTERSPRITES];
//--------------------------------------------------------------------------
//
//
//	Create Lines on top and the Bottom of the Demo Screen
//
//
//--------------------------------------------------------------------------
GsGLINE	line2;
GsGLINE	line5;
GsGLINE	line6;
GsGLINE	line7;

int Video_MODE=0;

GsSPRITE	sprLogo;		// Sprite for Group Logo
GsSPRITE	sprRechts;		// right background
GsSPRITE	sprLinks;		// left background
GsSPRITE	sprBaum[10];	// some trees in the foreground
//--------------------------------------------------------------------------
//
//
// 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);
//--------------------------------------------------------------------------
//
//
// Procedure for our Typer and the Pages
//
//
//--------------------------------------------------------------------------
void init_Typer(void);
void do_Typer(void);
void init_Page(int);
//--------------------------------------------------------------------------
//
//
// Procedure for our Monster
//
//
//--------------------------------------------------------------------------
void init_Monster(void);
//--------------------------------------------------------------------------
//
//	ABC-Table for our Typer
//
//
//--------------------------------------------------------------------------
#define	FONT_W	(8)		// width of one Letter
#define	FONT_H	(10)	// height of one Letter
int anzfontabc=0;
static int isinit=0;
char fontabc[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789,.-+*#!\"%&/()=?;:ÖÄÜöäüß ";
//--------------------------------------------------------------------------
//
//
// how much pages
//
//
//--------------------------------------------------------------------------
#define PAGES	8  // <------------ how much pages to type
//--------------------------------------------------------------------------
//
//
// the Page
//
//
//--------------------------------------------------------------------------
char texte[PAGEH*PAGES][PAGEW]=
{
//    1   5    10   15   20   25   30  SIGNS      max. SIGNS
//    |   |    |    |    |    |    |     
    {"                           "},// 1
    {"                           "},// 2
    {"                           "},// 3
    {"    NEVER  STOP  CoDING    "},// 4
    {"                           "},// 5
    {"                           "},// 6
    {" a fine Ntsc2Pal Selector  "},// 7
    {"                           "},// 8

    {"                           "},// 1
    {"                           "},// 2
    {"             We            "},// 3
    {"                           "},// 4
    {"are very proud to bring you"},// 5
    {"  SAIYUKI JOURNEY WEST US  "},// 6
    {"         (C) KOEI          "},// 8
    {"                           "},// 7

    {"                           "},// 1
    {"           Enjoy           "},// 2
    {" the nice GFX and Animation"},// 3
    {" painted by inc. of - UCA -"},// 4
    {"                           "},// 5
    {"     Press (X) for PAL     "},// 6
    {"           or do           "},// 7
    {"       (O) for NTSC        "},// 8

    {"                           "},// 1
    {"             We            "},// 2
    {"                           "},// 3
    {"  send big Shouts out to   "},// 4
    {" Friends +  Crews we like  "},// 5
    {"                           "},// 6
    {"                           "},// 7
    {"                           "},// 8

    {"                           "},// 1
    {"                           "},// 2
    {"         -ACCESSION-       "},// 3
    {"      -ECHELON-CAPITAL-    "},// 4
    {" -EURASIA-OLDSKOOL-KALISTO-"},// 5
    {"-HIGH SOCIETY-PARADOX-TRSI-"},// 6
    {"    -UNDERCOVER  AGENTS-   "},// 7
    {"          -DRASTIC-        "},// 8

    {"                           "},// 1
    {"                           "},// 2
    {"   C O D I N G + G F X     "},// 3
    {"  INC. undercover agents   "},// 4
    {"                           "},// 5
    {"         S O U N D         "},// 6
    {" SbC of LFC + INC. OF UCA  "},// 7
    {"                           "},// 8

    {"                           "},// 1
    {"                           "},// 2
    {"            IRc?           "},// 3
    {"                           "},// 4
    {"           Efnet:          "},// 5
    {"                           "},// 6
    {"        #lightforce        "},// 7
    {"                           "},// 8

    {"                           "},// 1
    {"                           "},// 2
    {"                           "},// 3
    {"                           "},// 4
    {"         R E L O A D       "},// 5
    {"                           "},// 6
    {"                           "},// 7
    {"                           "},// 8
};
//--------------------------------------------------------------------------
//
//
// Function:	main()
//
//
//--------------------------------------------------------------------------
int main()
{
u_long lTmp1;
u_long *ficken;

int i,j;
int temp,temp1;
//--------------------------------------------------------------------------
//
//
// INIT THE LOOP for our MONSTER
//
//
//--------------------------------------------------------------------------
int Move=0;
int	delay=0;
int	anzspr=0,sinspeed=2,scrollspeed=0;
int	step=0,scrpos=0,sincount=0,sincount2=0;
int	speeds[]={0,1,2,4};//,8,16};
int iMonsterPos=-200,iMonsterSpd=1;	
char Monsterabc[]="0123@"; // we have 4 animated Sprites of the Monster

scrollspeed=1;		// how fast to llop in the Sprite Sheet
Xangle=Yangle=1; 	// init x angle and y angle

PadInit(0);			// Joypad Init
//--------------------------------------------------------------------------
//
//
// AUTO PSX MODE SELECT if the original game is NTSC
//
//
//--------------------------------------------------------------------------
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...

MOD_Init();					// for the hitmod player 
MOD_Load((u_char *) music);	// the music for the Patch
MOD_Start();				// play music

// Load external TIM identifiers
LoadTIMData((u_long*)rechts);	// right background
LoadTIMData((u_long*)links);	// left background
LoadTIMData((u_long*)font1);	// font for the typer
LoadTIMData((u_long*)logo);		// Group Logo [ LIGHTFORCE ]
LoadTIMData((u_long*)Monster);	// animated Monster
LoadTIMData((u_long*)baum);		// foreground trees

// position in relation to size of: right background
SetSpriteInfo(&sprRechts,(u_long)rechts,240,120,1);
// position in relation to size of: left background
SetSpriteInfo(&sprLinks,(u_long)links,80,120,1);
// position in relation to size of: LIGHTFORCE LOGO
SetSpriteInfo(&sprLogo,(u_long)logo,160,40,1);
// position in relation to size of: foreground trees
SetSpriteInfo(&sprBaum[0],(u_long)baum,270,165,1); //breite,h”he
SetSpriteInfo(&sprBaum[1],(u_long)baum,10,180,1); //breite,h”he
SetSpriteInfo(&sprBaum[2],(u_long)baum,25,175,1); //breite,h”he
// fixing tree position
sprBaum[0].v+=2;sprBaum[0].h-=2;
sprBaum[1].v+=2;sprBaum[1].h-=2;
sprBaum[2].v+=2;sprBaum[2].h-=2;

// define Monster Sprite 
SetSpriteInfo(&sprMonster[0],(u_long)Monster,0,0,3);
sprMonster[0].y=182;
sprMonster[0].mx=20;
sprMonster[0].my=27;
  
init_Typer();

init_Monster();
//------------------------------------------------------------------------------------------------
//
//
//
//	M A I N
//
//
//
//------------------------------------------------------------------------------------------------
while(1)
{
	int iTmp1,iTmp2,iTmp3,iTmp4,iTmp5;
	PADstatus=PadRead(4);
	
	// WAIT until the gamer push X to start in PAL MODE
	if(PADstatus&Pad1x){Video_MODE=1; break;	} 
	// WAIT until the gamer push X to start in NTSC MODE
	if(PADstatus&Pad1crc){Video_MODE=2; break;	}	
	
	//--------------------------------------------------------------------------------------------
	//
	//   SETUP Character animation
	//
	//--------------------------------------------------------------------------------------------
	for(i=0;i<1;i++)
     	for(j=0;j<4;j++) // play sprite animation from 0-4 
        
	if(Monsterabc[scrpos+i]!='@')
   
			{
			if(Monsterabc[scrpos+i]==Monsterabc[j])
			scroll[i]=sprMonster[j];         
			}  
	else
			scrpos=0;

			step+=speeds[scrollspeed];
				
    if(step==4)
      {scrpos++;step=0;}

	for(i=0;i<MAXCHAR;i++)
	
	{
		if(iMonsterPos >540)Move-=1;	// the Monster start to run outside of the screen
		if(iMonsterPos ==-200)Move+=1;	// the Monster comes back outside of the screen

		iMonsterPos+=Move;
		scroll[i].x=iMonsterPos;
		scroll[i].scalex=ONE*Move;//*(-1);
		GsSortSprite(&scroll[i],&othWorld[currentBuffer],3); // 3 = Z-Index
	}

	do_Typer();

	//--------------------------------------------------------------------------------------------
	//
	//
	// DRAW 4 LINES TO FRAME THE SCREEN onTop and Bottom
	//
	//
	//--------------------------------------------------------------------------------------------
	// TOP LEFT
    line2.r0=200;line2.g0=200;line2.b0=200;
    line2.x1=0;line2.x0=160;
    line2.y0=line2.y1=0;
	// TOP RIGHT
    line7.r0=200;line7.g0=200;line7.b0=200;
    line7.x0=160;line7.x1=320;
    line7.y0=line7.y1=0;
	// BOTTOM LEFT
    line5.r0=200;line5.g0=200;line5.b0=200;
    line5.x1=0;line5.x0=160;
    line5.y0=line5.y1=238;
	// BOTTOM RIGHT
    line6.r0=200;line6.g0=200;line6.b0=200;
    line6.x0=160;line6.x1=320;
    line6.y0=line6.y1=238;

	GsSortGLine(&line2,&othWorld[currentBuffer],1);
	GsSortGLine(&line5,&othWorld[currentBuffer],1);
	GsSortGLine(&line6,&othWorld[currentBuffer],1);
	GsSortGLine(&line7,&othWorld[currentBuffer],1);

	// LOGO in the FOREGROUND - Z-Index 1
    GsSortSprite(&sprLogo,&othWorld[currentBuffer],1);
	// BACKGROUND RIGHT - Z-Index 4
    GsSortSprite(&sprRechts,&othWorld[currentBuffer],4);	
 	// BACKGROUND LEFT - Z-Index 4
	GsSortSprite(&sprLinks,&othWorld[currentBuffer],4);
	// TREE 1 in the FOREGROUND - Z-Index 2
    GsSortSprite(&sprBaum[0],&othWorld[currentBuffer],2);
	// TREE 2 in the FOREGROUND - Z-Index 2
    GsSortSprite(&sprBaum[1],&othWorld[currentBuffer],2);
    // TREE 3 in the FOREGROUND - Z-Index 2
	GsSortSprite(&sprBaum[2],&othWorld[currentBuffer],2);

	RenderWorld(60);

}
	// if a button was pressed on the gamepad
	SpuInit();
	SpuQuit();
 	MOD_Stop();
	MOD_Free();
	PadStop();
  	ResetGraph(0);
  	StopCallback();
//------------------------------------------------------------------------------------------------
//
//
//
// PATCH FUNCTION- DECRUNCH THE GAME
//
//
//
//------------------------------------------------------------------------------------------------
	EnterCriticalSection();
	depack1();
	ExitCriticalSection();
//------------------------------------------------------------------------------------------------
//
//
// add Video Norm values:
// Video_MODE==1 (PAL)  // if we have a original NTSC Game and want to patch to PAL
// Video_MODE==2 (NTSC) // if we have a original PAL Game and want to patch to NTSC
//
//
//------------------------------------------------------------------------------------------------

        if(Video_MODE==1) // 1 for PAL
        {
          // VALUES from the LCT Tool
		  ficken = (u_long *)0x800a049c;         *ficken = 0x24020001;// Get Video
          ficken = (u_long *)0x800a04a0;         *ficken = NOP;       // Get Video

          ficken = (u_long *)0x800aa978;         *ficken = 0x24900030; // X-Delta
          ficken = (u_long *)0x800aa97c;         *ficken = 0x24900030; // X-Delta
        }

//------------------------------------------------------------------------------------------------
//
// START THE GAME NOW
//
//------------------------------------------------------------------------------------------------
asm("nop");
asm("j 0x8009f684"); // ExecAdress to load the original Game
asm("nop");

}

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);
  // definition "Double Buffer"
  //		(X-Coordinate , Y-Coordinate   -> Buffer 0 (0,0)
  //		 X-Coordinate , Y-Coordinate   -> Buffer 1 (0,YRes) )
  GsDefDispBuff(0, 0, 0, SCRHeight);
  // fixing 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 current Buffer
  currentBuffer=GsGetActiveBuff();

  // Address for packet sizing
  GsSetWorkBase((PACKET*)out_packet[currentBuffer]);
  }

void RenderWorld(char cClear)
  {
  // Old List
  v_countCODE=VSync(1);
  DrawSync(0);
  v_countGFX = VSync(1);
  VSync(0);	// wait until the GPU has done the OLD LIST

  // flip Buffer (Display / Drawing)
  GsSwapDispBuff();
  // NEW/ 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]);

  // startDrawing ( GPU draw the OT in the background
  GsDrawOt(&othWorld[currentBuffer]);
  FntFlush(-1);
  // NEW LIST
  // init next OT !!!
  // get current Buffer
  currentBuffer=GsGetActiveBuff();
  // set Address for "Packet"-Building
  GsSetWorkBase((PACKET*)out_packet[currentBuffer]);
  // delete old content in 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-Infos into 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 VideoRam
    };

  DrawSync(0);						// wait until GPU is done with its task
  }

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

  tMemAddress += 4;				// Pointer to the Files
  GsGetTimInfo((u_long *) tMemAddress, &tTim);	// get TIM Infos from tTim

  tSprite->x = tX;				// set Coordinates x
  tSprite->y = tY;				// set Coordinates y

  switch (tTim.pmode & 3)		// X-Values depending from its Bit Depth!
    {
    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 Intensity (Colors)
												// set to Standard
  tSprite->mx = tSprite->w/2;					// set Ref. Point to the center of a sprite
  tSprite->my = tSprite->h/2;					// now not necessary

  tSprite->scalex = tSprite->scaley = ONE;		// skale to normal size ---> 1
  tSprite->rotate = 0;							// rotate in degree? set to zero ---> 0

  if (tCut)							// cut Sprite if TIM have
    tSprite->w -= tCut;				// a illegal width
  };

//------------------------------------------------------------------------------------------------
//
//
// DEFINITION of the 4 pictures of the Monsters Position in the Sprite sheet
//
//
//------------------------------------------------------------------------------------------------
void init_Monster()
{
	int	i=0,j=0;
	unsigned char Monsterxy[]={0,0,60,0,0,55,60,55}; // cut the correct position to its dimensions
	
	sprMonster[0].w=60;
  	sprMonster[0].h=55;
  	sprMonster[0].u=Monsterxy[j++];
  	sprMonster[0].v=Monsterxy[j++];
	
	for(i=1;i<4;i++)
	{
		sprMonster[i]=sprMonster[0];
    	sprMonster[i].u=Monsterxy[j++];
    	sprMonster[i].v=Monsterxy[j++];
	}
}
//------------------------------------------------------------------------------------------------
//
//
//	INIT Typer Font
//
//
//------------------------------------------------------------------------------------------------
void init_Typer()
{
	GsIMAGE	fontimg;
	int	i=0,j=0,k=0;
	unsigned char	fontxy[SIGNS*ROWS*2];
	anzfontabc=strlen(fontabc);
// X+Y Offsets in the Texture
for(i=0;i<ROWS;i++)
{
	for(j=0;j<SIGNS;j++)
	{
	fontxy[k++]=(j*FONT_W);	// X Offset
	fontxy[k++]=(i*FONT_H);	// Y Offset
	}
}
// Texture and all Sprite 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++];
 }
}
// do Typer
void do_Typer()
{
  static int	act_x=0,act_y=0,act_p=0;
  static int	charcnt=0,delaycnt=50*10,
  clrcount=122;
  int	i=0,subit=-2;
// charcnt=MAX_CHAR;
// delete the current Text Page now?
if(clrcount==122)
{
// if init is not done, do it now
if(isinit==0)
	{
		init_Page(act_p);
		isinit++;
	}
// start typing now
for(i=0;i<charcnt;i++)
	{
	page[i].r=22; page[i].g=75; page[i].b=93;
	GsSortFastSprite(&page[i],&othWorld[currentBuffer],1);
	}
// if a Sign or Letter is missing, go on
if(charcnt<MAX_CHAR)
{
	charcnt++;
}
// ok, now we have all content of the text page... wait and erase then
else
	{
		if(--delaycnt==0)
		{
		delaycnt=50*10;
		clrcount--;
		}
	}
}
// ok, bring next text page
else
	{
	if(++act_p==PAGES)	act_p=0;
	charcnt=0;
	isinit=0;
	clrcount=122;
	}
}
// fill Sprite-Array for the Typer
void init_Page(int pagenum)
{
int	h,i,j,k=0;
// do some math for the sprites
for(h=0;h<PAGEH;h++)
{
	for(i=0;i<PAGEW;i++)
	{
		for(j=0;j<anzfontabc;j++)
		{
// if SPACE in text, do not show a Sprite
	if(texte[h+(PAGEH*pagenum)][i]==' ')
	{
		page[k++].w=0;
		break;
	}
// set the correct Letter as the correct Sprite
      if(texte[h+(PAGEH*pagenum)][i]==fontabc[j])
{
     page[k  ]=fontspr[j];
     page[k  ].x=55+(i*FONT_W);	// set position of the Typer on the Demoscreen X Axis
     page[k++].y=60+(h*FONT_H);	// set position of the Typer on the Demoscreen Y Axis
     break;
    }
   }
  }
 }
}
	
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.

Post Reply

Who is online

Users browsing this forum: No registered users and 4 guests