How to draw simple rectangle

General Programming help in C, C++ or ASM, Compiling / Debugging, and R3000A Central Processing Unit (CPU) information
Post Reply
sinaptik
Donator & Supporter
Donator & Supporter
Posts: 18
Joined: Jan 09, 2013

How to draw simple rectangle

Post by sinaptik » January 26th, 2013, 4:16 pm

I'm slowly understanding how to code for the ps1, mostly by looking at other peoples' source code. I'm yet to find out how to draw a simple 2d rectangle, something like this:

fillRect(Xposition, Yposition, length, width);

Anyone have some simple code that will achieve this?


Thanks

User avatar
t0rxe
C Programming Expert
C Programming Expert
Posts: 139
Joined: Dec 19, 2012
Motto: /\OX[]
PlayStation Model: SCPH-5502
Location: Australia

Post by t0rxe » January 26th, 2013, 7:32 pm

Just make a 1x1 pixel as a TIM, and use code to stretch it and position it on the screen where you wish.
It will also allow you to also use more features, such as rotation and colour shading.
"Nostalgia isn't a big enough word to describe the PlayStation from my eyes"

sinaptik
Donator & Supporter
Donator & Supporter
Posts: 18
Joined: Jan 09, 2013

Post by sinaptik » January 26th, 2013, 8:33 pm

t0rxe wrote:Just make a 1x1 pixel as a TIM, and use code to stretch it and position it on the screen where you wish.
It will also allow you to also use more features, such as rotation and colour shading.
I know that may sound simple to you, but I (just starting out in ps1 dev) barely know what a TIM is, let alone how to use one.

I'm using ot_example.zip from http://www.reocities.com/timessquare/ch ... ource.html as a guide.

It just draws a starfield which is just little rectangles - pretty much what I want to learn.

User avatar
t0rxe
C Programming Expert
C Programming Expert
Posts: 139
Joined: Dec 19, 2012
Motto: /\OX[]
PlayStation Model: SCPH-5502
Location: Australia

Post by t0rxe » January 26th, 2013, 8:43 pm

Okay, I will make a TIM example for you. Give me a few minutes...

All you will need to do is load up TIMTOOL and add the included TIM into it.
You will then see where I have positioned it in the framebuffer, and how the code makes sense.
"Nostalgia isn't a big enough word to describe the PlayStation from my eyes"

User avatar
t0rxe
C Programming Expert
C Programming Expert
Posts: 139
Joined: Dec 19, 2012
Motto: /\OX[]
PlayStation Model: SCPH-5502
Location: Australia

Post by t0rxe » January 27th, 2013, 12:07 am

Here you are (followed the PSXDEV.net comment layout):
timexample.zip
Just use CATFLAP or PSEXE.COM to upload it to your PSX (unless you are using an emulator).
Use Psy-Q to compile it. Make sure you upload 'image.TIM' to '0x80025000' before loading the PS-EXE.

If you want to include the TIM in the PS-EXE so you don't need to upload it separately (because you're using an emulator for development), you will need to include it in the compilers MAKEFILE as an object or header file. You will also need to change some code for it to work if you do it that way.
You do not have the required permissions to view the files attached to this post.
"Nostalgia isn't a big enough word to describe the PlayStation from my eyes"

sinaptik
Donator & Supporter
Donator & Supporter
Posts: 18
Joined: Jan 09, 2013

Post by sinaptik » January 27th, 2013, 7:36 am

Thanks for the example, sadly I'm using an emulator so I can't run it.

Why is using a TIM better than the method in ot_example.zip? Only the added things like rotation and shading? If I wanted to make a game that only had a 320x256 grid of pixels, would the ot_example.zip way of drawing be okay?

User avatar
t0rxe
C Programming Expert
C Programming Expert
Posts: 139
Joined: Dec 19, 2012
Motto: /\OX[]
PlayStation Model: SCPH-5502
Location: Australia

Post by t0rxe » January 27th, 2013, 2:45 pm

It would be alright, but it is a lot more hard work and it is a bit more complex.
The TIM method is just easier to control and use.
Though, by using your method, you would save a tiny bit of RAM and give a significant speed increase.

See this code (old code): http://www.geocities.co.jp/Playtown/200 ... ly2d.c.txt

Code: Select all

#include	"syscall.h"

void Clear_(void)
{
}

void gpuInit(void)
{
	SendGPU(0);		/* GPUÆ’Å Æ’ZÆ’bÆ’g ? */
	Clear_();
	SendGPU(0x03000000);	/* •\Ž¦ƒ}ƒXƒN (•\Ž¦—LŒø) */
	Clear_();
	SendGPU(0x06c60260);	/* ƒXƒNƒŠ[ƒ“…•½ŠJŽn/I—¹ (0/256) */
	Clear_();
	SendGPU(0x07040010);	/* ƒXƒNƒŠ[ƒ“‚’¼ŠJŽn/I—¹ (0/240) */
	Clear_();
	GPU_cw(0xe1000400);	/* •`‰æƒ‚[ƒhi•\Ž¦—̈æ‚É•`‰æ ƒfƒBƒU‚È‚µ tpage0j*/
	Clear_();
	GPU_cw(0xe3000000);	/* •`‰æ—̈æŽn“_ (0,0) */
	Clear_();
	GPU_cw(0xe407ffff);	/* •`‰æ—̈æI“_ (1023,511) */
	Clear_();
	GPU_cw(0xe5000000);	/* •`‰æƒIƒtƒZƒbƒg (0,0) */
	Clear_();
	SendGPU(0x08000000);	/* •\Ž¦ƒ‚[ƒh 256x240/NTSC/ƒmƒ“ƒCƒ“ƒ^[ƒŒ[ƒX */
}

void test(void)
{
	struct {
		unsigned char r0,g0,b0,code;
		short	x0,y0;
		short	w,h;
	} boxf = {
		0,0,0,0x02,	//•
		0,0,
		256,240
	};

	struct {
		unsigned char r0,g0,b0,code;
		short	x0,y0;
		short	x1,y1;
		short	x2,y2;
	} polyF3 = {
		255,0,0,0x20,	//Ô
		50,0,
		0,100,
		100,100
	};

	struct {
		unsigned char r0,g0,b0,code;
		short	x0,y0;
		unsigned char r1,g1,b1,pad1;
		short	x1,y1;
		unsigned char r2,g2,b2,pad2;
		short	x2,y2;
	} polyG3 = {
		255,0,0,0x30,	//Ô
		150,0,
		0,255,0,0,		//—Î
		100,100,
		0,0,255,0,		//Â
		200,100
	};

	GPU_cwb(&boxf,sizeof(boxf)/sizeof(long));	/* ”wŒi“h‚è‚‚Ԃµ */
	GPU_cwb(&polyF3,sizeof(polyF3)/sizeof(long));	/* ƒtƒ‰ƒbƒgŽOŠpŒ` */
	GPU_cwb(&polyG3,sizeof(polyG3)/sizeof(long)); /* ƒOƒ[ŽOŠpŒ` */
}

int main(int argc,char **argv)
{
	gpuInit();
	test();
	for(;;) ;
}

"Nostalgia isn't a big enough word to describe the PlayStation from my eyes"

sinaptik
Donator & Supporter
Donator & Supporter
Posts: 18
Joined: Jan 09, 2013

Post by sinaptik » February 4th, 2013, 4:35 pm

I'm stuck again :(

All I want to do is draw with double buffering:

setRGB0(&(player.tile), 0, 0, 0);

AddPrim(1, &(player.tile));

where player is TILE_1

Orion_
Verified
Legendary Programmer
Legendary Programmer
Posts: 240
Joined: Aug 13, 2012
I am a: Programmer
PlayStation Model: Net Yaroze
Location: France
Contact:

Post by Orion_ » February 5th, 2013, 3:48 am

check out the PSY-Q sdk pdf named "LIBREF46.PDF"
you have a bunch of ready to use functions like GsSortBoxFill to draw a rectangle

I have a little playstation lib that I made on top of psy-q sdk, it's not state of the art code, but it can help to code easier.
I would need some time to make a tutorial on how to use it and release it, it could help some of you
Retro game development on Playstation and other consoles http://orionsoft.free.fr/

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 20th, 2013, 5:42 am

i can provide a simple Stars Scroller. made with GsSortLine. not used TIM.
Grab the FILES HERE: STARS DEMO GSLINE

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" // gives the Font a nice GREEN Effect

//-------------------- ASM ADRESS DEFINITION --------------------------
//---------------------------------------------------------------------

//---------------------------------------------------------------------
#define ORDERING_TABLE_LENGTH (12)
#define MAX_NO_PACKETS  (4000)
//---------------------------------------------------------------------
//-------------DEFINITION STARS IN BACKGROUND      --------------------
//---------------------------------------------------------------------
#define STARSC         50 // COUNT OF STARS
#define SPEED            1 // Max Scroll SPEED
#define PLANE            4 // MAXIMUM LAYERS for STARS
//--------------------------------------------------------------------------
// 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;	// SAVE PADSTATUS
int             v_countGFX=0, v_countCODE=0; // HSync COUNTER
u_char          HZMode=MODE_NTSC; // Not needed in here. it's for our Patches
//---------------------------------------------------------------------
//---------- READ INFO FROM EXTERNAL OBJECTS          -----------------
//---------------------------------------------------------------------
extern char intro[];
extern char logl[];
extern char logr[];
extern char lef[];
extern char rig[];

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

STAR Stars[STARSC];
//---------------------------------------------------------------------
//---------- Font-Sprites & Textures for TYPER            -------------
//---------------------------------------------------------------------
extern char font1[];
#define	PAGEW	(30)
#define	PAGEH	(8)

#define	ZEICHEN	(32)// <--- How much Letters in a line of used Font
#define	ZEILEN	(3)// <--- Wieviele Rows in used font
#define	MAX_CHAR (PAGEH*PAGEW)

GsSPRITE fontspr[ZEICHEN * ZEILEN];
GsSPRITE page[MAX_CHAR];
//-----------------------------------------------------------------------------
//--------------------SPRITES & DEFENITION          ---------------------------
//-----------------------------------------------------------------------------
GsSPRITE	sprLetter;
GsSPRITE	sprLogl;
GsSPRITE	sprLogr;
GsSPRITE	sprLef;
GsSPRITE	sprRig;

GsLINE		line; // horizontally line
GsGLINE		line2;// again
GsGLINE		line3;// again :)
GsGLINE		line4;
GsGLINE		line5;
GsGLINE		line6;
GsGLINE		line7;

GsGLINE		Wobble[320]; //Wobble Lines 

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

int logosinoff=0;
int savedlogosin=0;
int logosinoff2=0; //Wobble Sin
int savedlogosin2=0; //Wobble Sin
//-------------- ABC-Table & Scroller for Typer ------------------
#define	FONT_W	(8)
#define	FONT_H	(10)
int anzfontabc=0;
static int isinit=0;
char fontabc[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789,.-+*#!\"%&/()=?;:ÖÄÜöäüß ";
//-----------------------
// Count of Pages
//-----------------------
#define PAGES	7  // <------------ How many Signs

//-------------------------------
// The Page starts here
//-------------------------------
char texte[PAGEH*PAGES][PAGEW]=

{
//    1   5    10   15   20   25   30  SIGNS      max. SIGNS
//    |   |    |    |    |    |    |     
    {"                              "},// 1
    {"                              "},// 2
    {"                              "},// 3
    {"                              "},// 4
    {"                              "},// 5
    {"         P A R A D O X        "},// 6
    {"                              "},// 7
    {"                              "},// 8

    {"                              "},// 1
    {"                              "},// 2
    {"                              "},// 3
    {"                              "},// 4
    {"                              "},// 5
    {"             A N D            "},// 6
    {"                              "},// 7
    {"                              "},// 8

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

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

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

    {"         P A R A D O X        "},// 1
    {"                              "},// 2
    {"                              "},// 3
    {"  Say hello to new talented   "},// 4
    {"   Members for codings each   "},// 5
    {"       and every Time:        "},// 6
    {"      Gandhi and  Inc.        "},// 7
    {"    the Dudeds by U.C.A.      "},// 8


    {"         P A R A D O X        "},// 1
    {"                              "},// 2
    {"                              "},// 3
    {"                              "},// 4
    {"Coding................... INC."},// 5
    {"Sound.................... INC."},// 6
    {"Graphix.................. INC."},// 7
    {"                              "},// 8


};
//--------------------------------------------------------------------------
// Function:	main() MAIN PROG
// Description:	--
// Parameters:	--
// Returns:	int
// Notes:	N/A
//--------------------------------------------------------------------------
int main()
  {

  u_long lTmp1;
//-------------------- INIT SLIDING LOGO -----------------------------------
    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();


  InitialiseGraphics(320,240,MODE_NTSC); // GFX Init, inkl. Init current Buffer...

//  FntLoad(960,256);     // not needed here . it's code for our Patches
//  FntOpen(0, 85, 320, 220, 0, 512); // not needed here . it's code for our Patches
//  FntPrint("       X --> PAL       O --> NTSC\n"); // not needed here . it's code for our Patches
RenderWorld(1);RenderWorld(1); // 2x da DoubleBuffering...

// Chose FREQUENZY // not needed here . it's code for our Patches
//  while (1)      // not needed here . it's code for our Patches
//    {            // not needed here . it's code for our Patches

//    PADstatus=PadRead(4); // not needed here . it's code for our Patches

//    if (PADstatus & Pad1crc) // not needed here . it's code for our Patches
//      break; // HZMode Initvalue == MODE_NTSC // not needed here . it's code for our Patches

//    if (PADstatus & Pad1x) // not needed here . it's code for our Patches
//      {HZMode=MODE_PAL;break; // not needed here . it's code for our Patches
//	} // not needed here . it's code for our Patches
//} // not needed here . it's code for our Patches

 InitialiseGraphics(320,240,HZMode); // GFX Init, incl. Init current Buffer...

//--------------------------------------------------------------------------
//-------------------------LOAD MUSIC AND PLAY      ------------------------
//--------------------------------------------------------------------------
MOD_Init();
MOD_Load((u_char *) intro); // intro is the name of the sound file
MOD_Start();
//--------------------------------------------------------------------------  
//------------------ READ EXTERNAL INFO FROM GFX     -----------------------
//--------------------------------------------------------------------------  
LoadTIMData((u_long*)logl);
LoadTIMData((u_long*)logr);
LoadTIMData((u_long*)font1);
LoadTIMData((u_long*)lef);
LoadTIMData((u_long*)rig);

  for (iTmp1=0;iTmp1<1456;iTmp1+=1)
   {
do_Typer();
    if (iTmp1==28) VSync(80); // WAIT any SECONDS
    RenderWorld(1); // DRAW
    }
// --------------------------- INIT LOGO -----------------------------------
SetSpriteInfo(&sprLogl,(u_long)logl,80,30,1);
SetSpriteInfo(&sprLogr,(u_long)logr,240,30,1);
SetSpriteInfo(&sprRig,(u_long)rig,235,121,3);//x,y
SetSpriteInfo(&sprLef,(u_long)lef,80,119,3);//x,y
//--------------------------------------------------------------------------  
//--------------------- INIT LETTERS      ----------------------------------  
//--------------------------------------------------------------------------  
   sprLetter.w=sprLetter.h=16;// height of 1 Letter
   sprLetter.mx=sprLetter.my=0;
   sprLetter.v=sprLetter.u=0;
{
 GsSortSprite(&sprLetter,&othWorld[currentBuffer],2);
 RenderWorld(1);
}
//--------------------------------------------------------------------------  
init_Wobble(); // Init Wobble as GsGLINE´s
InitStars();

// ------------------------------------
// --------   MAIN PROGRAMM    --------
// ------------------------------------
   
while(1)
 {
int iTmp1,iTmp2,iTmp3,iTmp4,iTmp5;

   PADstatus=PadRead(4);
   if ((PADstatus&Pad1Start)) break;

do_Typer();
do_Wobble();
//-----------------LOGO S L I D I N G S----------------
    if (iLogoPos<-40) iLogoSpd=1;
    if (iLogoPos>40) iLogoSpd=-1;
    iLogoPos+=iLogoSpd;

  if (iPdxPos<-100) iPdxSpd=2;
  if (iPdxPos>260) iPdxSpd=-2;
  iPdxPos+=iPdxSpd;
  if (iPdxPos1<60) iPdxSpd1=2;
  if (iPdxPos1>420) iPdxSpd1=-2;
  iPdxPos1+=iPdxSpd1;
//--------------------------------------------------
//--------- GIVE SLIDINGS FREE              --------
//--------------------------------------------------
sprLogl.x=iPdxPos;
sprLogr.x=iPdxPos1;
//---------- LAYER DEFENITION OF SPRITES  -----------
GsSortSprite(&sprLogl,&othWorld[currentBuffer],1);
GsSortSprite(&sprLogr,&othWorld[currentBuffer],1);
GsSortSprite(&sprLef,&othWorld[currentBuffer],3);
GsSortSprite(&sprRig,&othWorld[currentBuffer],3);
//----------------------------------------------------
MoveStars();
//----------------DRAW 3 LINES       ------------------
        line2.r0=150;line2.g0=100;line2.b0=40;
        line2.x1=10;line2.x0=160;
        line2.y0=line2.y1=80;

        line7.r0=150;line7.g0=100;line7.b0=40;
        line7.x0=160;line7.x1=309;
        line7.y0=line7.y1=80;

        line5.r0=150;line5.g0=100;line5.b0=40;
        line5.x1=10;line5.x0=160;
        line5.y0=line5.y1=157;
        
        line6.r0=150;line6.g0=100;line6.b0=40;
        line6.x0=160;line6.x1=309;
        line6.y0=line6.y1=157;

	line3.r0=1;line3.g0=120;line3.b0=0;
	line3.x0=line3.x1=320;
      	line3.y0=0;line3.y1=240;
	
	line4.r0=1;line4.g0=120;line4.b0=0;
	line4.x0=0;line4.x1=320;
      	line4.y0=line4.y1=120;
	
	GsSortGLine(&line2,&othWorld[currentBuffer],1);
	GsSortGLine(&line5,&othWorld[currentBuffer],1);
	GsSortGLine(&line6,&othWorld[currentBuffer],1);
	GsSortGLine(&line7,&othWorld[currentBuffer],1);

//-------------------------------------------------------------
RenderWorld(1);
  }
//  MOD_Stop();MOD_Free();VSync(3); 
//  PadStop();
//  ResetGraph(0);
//  StopCallback();
//-------------------------------------------------------------
//------------------PATCH FUNKTION- Spiel entpacken------------
//-------------------------------------------------------------
//EnterCriticalSection();
//depack1();
//start1();
//ExitCriticalSection();
//-------------------------------------------------------------
//************************* starts game ***********************
//-------------------------------------------------------------
//asm("nop");
//asm("j 0x8008656c"); // ExecAddress --> Load Game after PAD BREAK
//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 = 1;
    line.g = line.b =Stars[i].z*50;
    GsSortLine(&line,&othWorld[currentBuffer],2);
    }
  }
//------------------------------------------------------------------------------
// F U N C T I O N    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]);
  }
//------------------------------------------------------------------------------
void RenderWorld(char cClear)
  {
  v_countCODE=VSync(1);
  DrawSync(0);
  v_countGFX = VSync(1);
  VSync(0);	
  GsSwapDispBuff();
// "check "ClearScreen"-Kommando in OT  R, G, B
if (cClear==1)  GsSortClear( 0, 0, 0,&othWorld[currentBuffer]); //background Color
if (cClear==155)  GsSortClear( 0,  0,  0,&othWorld[currentBuffer]);
    // start Draw (GPU is drawing OT in Background)
  GsDrawOt(&othWorld[currentBuffer]);
  FntFlush(-1);
// ------------------------------------ "NEW LIST
  currentBuffer=GsGetActiveBuff();
  GsSetWorkBase((PACKET*)out_packet[currentBuffer]);
  GsClearOt(0, 0, &othWorld[currentBuffer]);
  }
//------------------------------------------------------------------------------
void LoadTIMData(u_long *tMemAddress)
  {
  RECT tRect;
  GsIMAGE tTim;

  DrawSync(0);
  tMemAddress++;
  GsGetTimInfo(tMemAddress, &tTim);   // SAVE TIM-Info in TIM
  tRect.x = tTim.px;
  tRect.y = tTim.py;
  tRect.w = tTim.pw;
  tRect.h = tTim.ph;
  LoadImage(&tRect, tTim.pixel);		// Load TIM-DATA 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 ready
  }
//------------------------------------------------------------------------------
// Function:	SetSpriteInfo(...)
//------------------------------------------------------------------------------

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

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

  tSprite->x = tX;				// CORDINATES
  tSprite->y = tY;				// CORDINATES

  switch (tTim.pmode & 3)			// X-Value depends of Depth Bit!
    {
    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;			// give CLUT by Sprite
  tSprite->cy = tTim.cy;
  tSprite->r = tSprite->g = tSprite->b = 128;	// normally Intensity (of Colours)
  tSprite->mx = tSprite->w/2;			// Ref Point to Sprite Center
  tSprite->my = tSprite->h/2;			
  tSprite->scalex = tSprite->scaley = ONE;	// Skale to 1 (normal Size)
  tSprite->rotate = 0;				// Rotation to 0
  if (tCut)					// Cut Sprite if Tim
    tSprite->w -= tCut;				// have an ivailid Size
  };
//-----------------------------------------------------------------
// 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);
//--------------------------------------------
// X+Y Offset Calculating in between of 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 & 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++];
 }
}
//================
// DO 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 actual Page not set. do it now
//---------------------------------------------------------------------
if(isinit==0)
	{
		init_Page(act_p);
		isinit++;
	}
//-----------------------------------
// Do Pager, letter by letter
//-----------------------------------
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 Sign is missed. do one more
//-------------------------------------------------------
if(charcnt<MAX_CHAR)
{
	charcnt++;
}
//----------------------------------------------------
// ok, now all shown... now wait and erase
//----------------------------------------------------
else
	{
		if(--delaycnt==0)
		{
		delaycnt=10*10;
		clrcount--;
		}
	}
}
//----------------------
// ok, get new page
//----------------------
else
	{
	if(++act_p==PAGES)	act_p=0;
	charcnt=0;
	isinit=0;
	clrcount=55;
	}
}
//=================================
// fill here Sprite-Array for Typer
//=================================
void init_Page(int pagenum)
{
int	h,i,j,k=0;

//--------------------------------------------------
// calculate Sprites
//--------------------------------------------------
for(h=0;h<PAGEH;h++)
{
	for(i=0;i<PAGEW;i++)
	{
		for(j=0;j<anzfontabc;j++)
		{
//-------------------------------------------------
// if "SPACE" ? don't show a letter or Sign
//-------------------------------------------------
	if(texte[h+(PAGEH*pagenum)][i]==' ')
	{
		page[k++].w=0;
		break;
	}
//------------------------------------------------
// give Letter the correct Sprite
//------------------------------------------------
      if(texte[h+(PAGEH*pagenum)][i]==fontabc[j])
{
     page[k  ]=fontspr[j];
     page[k  ].x=42+(i*FONT_W);	// on which X Cord it should Print?
     page[k++].y=65+(h*FONT_H);	// on which Y Cord it should Print?
     break;
    }
   }
  }
 }
}
Compile and test with ePSXe EMU
have Phun
Last edited by inc^lightforce on April 20th, 2013, 12:13 pm, 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 20th, 2013, 12:00 pm

.... I'm yet to find out how to draw a simple 2d rectangle, something like this:
fillRect(Xposition, Yposition, length, width); Anyone have some simple code that will achieve this?
And here comes the 2D RECTANGLE CODE: NO GFX USED -> only Code.

Grab all Files incl. a Demo for PS1 EMU here

Image

Code: Select all

//***************************************************************
//    THIS WAS OUR LOADER FOR Medal of Honor 2 - Underground PAL
//    ===========================================================
//    Many Lines i removed !!!
//    Original Source:   27/10/2000
//
//***************************************************************
//--------------------------------------------------------------------------
// 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" // For Sound
#include "pad.h" // PAD
#include "sinuss.h" // Sinus made with Sinuslab by Hitmen
#include "Sinstuff.h" // Sinus made with Sinuslab by Hitmen

#define	MAXCHAR	42
#define DEVELOPEMENT
#define ORDERING_TABLE_LENGTH (5)
#define MAX_NO_PACKETS  (3000)
#define	rnd(max)	((rand()*(max))/(32768)+1)
//--------------------------------------------------------------------------
// 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;	
u_long		PADstatus=0;	// Save PAD STATUS
int             v_countGFX=0, v_countCODE=0; // HSync Counter
u_char          HZMode=MODE_NTSC;

int Xangle,Yangle,depth;
int Xangle2,Yangle2;
int iScrollOffset=0;
extern char shades[]; // sound file

//-------------------------
// Font-Sprites & Textures
//-------------------------
GsBOXF		mybox[6]; // 2D RECTANGLE
GsLINE      line[360];
GsGLINE		line2[4];
int Video_MODE=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_line(void);
void do_line(void);  // INIT LINE
void do_bar(void);   // INIT RECTANGLE
void init_bar(void); // INIT RECTANGLE
void init_Kloetze(void); // 2D RECTANGLE

int sin1=0;
int sin2=0;

int main()
  {
  u_long lTmp1;
  int i,j,k;
  int temp,temp1;
  int iTmp1,iTmp2,iTmp3,iTmp4;
	iTmp1=-60;
	iTmp2=-280;
	iTmp3=320;
	iTmp4=500;
	Xangle=Yangle=1;	//init x angle and y angle

	PadInit(0);     // Joypad Init

// CHECKS AUTO REGION , INPUT VALUES FOR PAL or NTSC PATCH HERE	
 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(); // Sound Check
  	MOD_Load((u_char *) shades); // load Sound
  	MOD_Start(); // play Sound

	init_line(); // INIT LINE
	init_bar();  // 2D RECTANGLE
	init_Kloetze(); // 2D RECTANGLE

for (i=0;i<140;i++)
// ------------------------------------
// --------   M A I N    --------
// ------------------------------------
while(1)
 {
PADstatus=PadRead(4);
	if(PADstatus&Pad1x){Video_MODE=1; break;	} 
	if(PADstatus&Pad1crc){Video_MODE=2; break;	}

	do_line(); // GO FOR LINE
	do_bar(); // GO FOR RECTANGLE

	// Define RECTANGLE MOVEMENT
	iTmp1+=1;
	iTmp2+=1;
	iTmp3-=1;
	iTmp4-=1;
		if(iTmp1>320) iTmp1=-50;
		if(iTmp2>320) iTmp2=iTmp1-200;
		if(iTmp3<-150) iTmp3=320;
		if(iTmp4<-150) iTmp4=iTmp3+190;

mybox[0].x=iTmp1;
mybox[1].x=iTmp2;
mybox[2].x=iTmp2+40;
mybox[3].x=iTmp3;
mybox[4].x=iTmp4;
mybox[5].x=iTmp4;

GsSortBoxFill(&mybox[0],&othWorld[currentBuffer],2);
GsSortBoxFill(&mybox[1],&othWorld[currentBuffer],2);
GsSortBoxFill(&mybox[2],&othWorld[currentBuffer],2);
GsSortBoxFill(&mybox[3],&othWorld[currentBuffer],2);
GsSortBoxFill(&mybox[4],&othWorld[currentBuffer],2);
GsSortBoxFill(&mybox[5],&othWorld[currentBuffer],2);
	
RenderWorld(60);

    }
// NOT IMPORTANT. THIS IS THE REST, A SNIPPED OF OUR CRACK
	SpuInit();
	SpuQuit();
 	MOD_Stop();
	MOD_Free();
	//VSync(3);
	PadStop();
  	ResetGraph(0);
  	StopCallback();
// ===============================================	
}
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);
// Correct Error in 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();

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

void RenderWorld(char cClear)
  {
// ------------------------------------ " AN OLD LIST"

  v_countCODE=VSync(1);
  DrawSync(0);
  v_countGFX = VSync(1);
  VSync(0);	// wait until GPU are finished OLD LIST

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

// ------------------------------------ "ACTUAL LIST"

// "Register" a "ClearScreen"- Command in OT
//  R, G, B
  if (cClear==1)  GsSortClear(0, 0, 0,&othWorld[currentBuffer]);  // here can be changed the screen background Color
  if (cClear==60) GsSortClear(78, 0, 92,&othWorld[currentBuffer]); // here can be changed the screen background Color
  if (cClear==255)  GsSortClear(255, 255, 255,&othWorld[currentBuffer]); // here can be changed the screen background Color


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

// ------------------------------------ "NEW LIST"

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

// set Address for Packets
  GsSetWorkBase((PACKET*)out_packet[currentBuffer]);

// erase Content of OT
  GsClearOt(0, 0, &othWorld[currentBuffer]);

// OT is now ready for new OT Commands
  }

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

  DrawSync(0);
  tMemAddress++;
  GsGetTimInfo(tMemAddress, &tTim);   // SAVE TIM-Information to tTim
  tRect.x = tTim.px;
  tRect.y = tTim.py;
  tRect.w = tTim.pw;
  tRect.h = tTim.ph;
  LoadImage(&tRect, tTim.pixel);		// Load TIM-Data 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 is ready
  }

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

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

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

  switch (tTim.pmode & 3)			// X-Value depends on 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 of Sprite
  tSprite->cy = tTim.cy;

  tSprite->r = tSprite->g = tSprite->b = 128;	// Colour intensity
// set to Standart
  tSprite->mx = tSprite->w/2;			// Ref-POINT to the CENTER of a Sprite
  tSprite->my = tSprite->h/2;			

  tSprite->scalex = tSprite->scaley = ONE;	// Scale to 1 (real Size)
  tSprite->rotate = 0;				// rotation angle to 0 ZERO

  if (tCut)					// Cut Sprite if a Sprite have an illegal size
    tSprite->w -= tCut;				
  };
//===============================================
// REGISTER ALL LINES (position + rgb)
//===============================================
void init_line()
{
	line2[0].x0=0;
	line2[0].y0=65;
	line2[0].x1=160;
	line2[0].y1=65;
   
	line2[2].x0=160;
	line2[2].y0=65;
	line2[2].x1=320;
	line2[2].y1=65;
	
	line2[1].x0=0;
	line2[1].y0=179;
	line2[1].x1=160;
	line2[1].y1=179;

	line2[3].x0=160;
	line2[3].y0=179;
	line2[3].x1=320;
	line2[3].y1=179;
	
}

//======================================================
// DRAW THE LINES
//======================================================
void do_line()
{	
	GsSortGLine(&line2[0],&othWorld[currentBuffer],3);
    line2[0].r0=78;
	line2[0].g0=0;
	line2[0].b0=92;
	line2[0].r1=255;
	line2[0].g1=255;
	line2[0].b1=255;
	
	GsSortGLine(&line2[2],&othWorld[currentBuffer],3);
	
	line2[2].r0=255;
	line2[2].g0=255;
	line2[2].b0=255;
	line2[2].r1=78;
	line2[2].g1=0;
	line2[2].b1=92;
	
	GsSortGLine(&line2[1],&othWorld[currentBuffer],3);

	line2[1].r0=78;
	line2[1].g0=0;
	line2[1].b0=92;
	line2[1].r1=255;
	line2[1].g1=255;
	line2[1].b1=255;
	
	GsSortGLine(&line2[3],&othWorld[currentBuffer],3);

	line2[3].r0=255;
	line2[3].g0=255;
	line2[3].b0=255;
	line2[3].r1=78;
	line2[3].g1=0;
	line2[3].b1=92;
}

void do_bar()
{
int i,j;
if(sin1>=359)	sin1=0;	
sin2=sin1=sin1+1;

for(i=0;i<359;i++)
	{
	j=i+1;
	line[i].attribute=(1<<28)+(1<<27)+(2<<24)+(0<<28)+(1<<30);
	line[i].r=32;
	line[i].g=0;
	line[i].b=41;
	line[i].x0=150;
	line[i].x1=165+(scalesin[j]+scalesin2[sin2]/2);
	line[i].y0=120;
	line[i].y1=120+(scalesin2[j]/2);

	GsSortLine(&line[i],&othWorld[currentBuffer],3);
	sin2+=2;
	if(sin2>=360)	sin2-=360;
	}
}

void init_bar()
{
int k;
for(k=0;k<360;k++)
	{
	line[k]=line[0];
	line[k].y0=60;
	line[k].y1=100;
	line[k].r=line[k].b=line[k].g=128;
	}

}

void init_Kloetze() // 2D RECTANGLE
{int iTmp1,iTmp2,iTmp3,iTmp4;
	iTmp1=-60;
	iTmp2=-280;
	iTmp3=320;
	iTmp4=500;
		mybox[0].w=31;
		mybox[0].h=24;
		mybox[0].y=10;
		mybox[0].r=104;mybox[0].g=0;mybox[0].b=122;
		mybox[1].w=76;
		mybox[1].h=20;
		mybox[1].y=45;
		mybox[1].r=104;mybox[1].g=0;mybox[1].b=122;
		mybox[2].w=20;
		mybox[2].h=55;
		mybox[2].y=5;
		mybox[2].r=104;mybox[2].g=0;mybox[2].b=122;
		mybox[3].w=56;
		mybox[3].h=51;
		mybox[3].y=180;
		mybox[3].r=104;mybox[3].g=0;mybox[3].b=122;
		mybox[4].w=20;
		mybox[4].h=58;
		mybox[4].y=180;
		mybox[4].r=104;mybox[4].g=0;mybox[4].b=122;
		mybox[5].w=135;
		mybox[5].h=20;
		mybox[5].y=206;
		mybox[5].r=104;mybox[5].g=0;mybox[5].b=122;
}
have Fun while Coding. Questions? ASK .

inc.
Last edited by inc^lightforce on April 21st, 2013, 3:20 am, edited 1 time in total.

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

Post by Shadow » April 20th, 2013, 2:25 pm

Nice! Great programming right there.
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.

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 21st, 2013, 3:07 am

thank you :)

i've done many many more in the past. In my 2 examples i shrunk many Lines of Program Code. Originally It's included more Code for patching Games but not important for sinaptiks Question.

Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests