Welcome...
===================================================================================================
PLEASE KEEP THIS WORKSHOP CLEAN. Do not post your Demos here. You can ask or say "Thank you", or give some other related Feedback or Notes and improvements.
Also if you like my help, Donate with PayPal: YES i LOVE THAT HELP & WANT DONATE
===================================================================================================
so again, welcome to my workshop in Demo and Cracktro Coding for PS1 with PSY-Q SDK. From time2time i will post some useful Tutorials for some Functions, Effects, Music, PS1 Video, 3D Objects, Sprite usage and many more.
Most of the code was written in the past days (1998 - 2002) when i was an active Member in PARADOX, LIGHTFORCE, MUPS and UNDERCOVER-AGENTS.
In these Days the Groups released fresh new PS1 Games as a complete "PSX Game ISO" and distributed em through the Internet on Scene Boards/FTP's like ISOHUNT ect. To mentioned where the ISO came from, Groups always made some Cracktros, Trainers and Pal to NTSC or NTSC to PAL Selectors. Sometimes we removed also Copy protection known as: LC1 and LC2 nested in V-Rally 2 or Soulreaver Legacy of Kain.
Why only 1 exe file? it was important and inevitable to pack the original "Game-exe" to get free space for own Code of Cracktros/ Selectors or Trainers.
The new modified "PS1 Game EXE", taken from the original Game-BIN, MUST always have exactly! the same size after including a "Cracktro Code" into the "Original PS1 Game-EXE". Than the modified "PS1 Game EXE", injected back into the "GAME-BIN", all in all must have the same file and sector size to work properly. Otherwise the Game failed to boot up from Disc in the PS1 Console.
Injecting a Cracktro into a Game was/ is only possible, if we included own Code into the "Original PS1 Game Exe"! No other solution will work
When i packed a "PS1 Game EXE" of eg. 400 KB, i had with luck, a result of 150 KB. OLé yeah --> now i had 250 KB free Space for own "Code, the Cracktro" to include in front of the "Original PS1 GAME".
To get PAL and NTSC values for a pal/ntsc patcher next to our demo/ intro first run:
DOLCT.BAT next to LCT.EXE
And today i am done with a new rewritten Tool, a Windows App that do the LCT job. You must no longer rename and edit by hand your files to get on the Values.
SCRENNSHOTS:
LINK with description in the Download Era. The Tool is also attached to this post until now.
viewtopic.php?f=75&t=4022
what is GAME.RNC? ...just simply the SLES or SLUS PS1 Exe file, taken from our original mounted Game - BIN.
- copy SLES_25.30 or how ever it's named into the same folder next to dolct.bat, lct.exe
- rename SLES_25.30 to game.rnc
At this point, we have renamed the original SLES/ SLUS to game.rnc but NOT PACKED/ CRUNCHED YET!
- start the BATCH
the output give us all information for pal and ntsc needs.
No longer needed to go though this steps. Just simple use my Windows LCT Tool APP.
Batch command:
Code: Select all
lct game.rnc > PatchData.txt
Exit
Code: Select all
Resident Evil 3 french pal
Load address...........: 0x80010000
Decrunch to............: 0x8000f800
Exec address...........: 0x80011bd8
Debug-Protection at....: 0x80096554 (NOP out)
0x80096558 (NOP out)
Hook Magickey finder at: 0x80096838 (0x08003C00)
Insert Magic-Key at....: 0x80096830 (0x34C6xxxx)
Anti-ModChip protection: 0x80096810 (NOP out)
0x80096818 (NOP out)
0x80096820 (NOP out)
Patch GetVideoMode() at: 0x80082ecc (0x24020001 for PAL, 0x24020000 for NTSC)
0x80082ed0 (NOP out)
Patch X-Delta at.......: 0x8008d958 (0x24900030 for PAL, 0x24900010 for NTSC)
0x8008d95c (0x24900030 for PAL, 0x24900010 for NTSC)
TO CLARIFY THE PACKER THAT I USE/ USED: is NOT UPX or other related windows based exe packer. We programmed our own tool to do this job.
THE TOOL IS CALLED: RNC.EXE
don't forget as i mentioned, rnc.exe (packing the original SLUS or SLES) is the last step before we start to code our demo/ intro.
Now copy game.rnc into the same folder next to RNC.EXE and RNC.BAT
The Batch File contain the following command line:
Code: Select all
rnc p d game.rnc
you can download the tool from the attachment to this post.
the 3rd file that we need is called: DEPACK.SRC
in this file we must add the: Decrunch to ADDRESS . You can find this value in the PatchData.txt
a snipped from depack.src:
Code: Select all
xdef depack1
xdef start1
idest equ $8000f800 ;Decrunch to
section rnc
;
;-----------------
; UNPACK GAME
;-----------------
;
depack1 LA a0,game ;Start
LI a1,idest ;Destination
NOP
J unpack ;unpack
NOP
;
;---------------
; START GAME
;---------------
;
start1 LI a1,idest+16 ;Start Address
LW a1,(a1) ;grab
NOP
J a1 ;start
NOP
unpack sub sp,sp,$58
SW a0,$0000(sp)
SW a1,$0004(sp)
SW a2,$0008(sp)
SW a3,$000c(sp)
SW t0,$0010(sp)
SW t1,$0014(sp)
SW t2,$0018(sp)
SW t3,$001c(sp)
SW t4,$0020(sp)
SW t5,$0024(sp)
SW t6,$0028(sp)
SW t7,$002c(sp)
SW s0,$0030(sp)
SW s1,$0034(sp)
SW s2,$0038(sp)
SW s3,$003c(sp)
SW s4,$0040(sp)
SW s5,$0044(sp)
SW s6,$0048(sp)
SW s7,$004c(sp)
SW ra,$0050(sp)
OR s0,a0,R0
OR s1,a1,R0
JAL lab708
NOP
LW a0,$0000(sp)
LW a1,$0004(sp)
LW a2,$0008(sp)
LW a3,$000c(sp)
LW t0,$0010(sp)
LW t1,$0014(sp)
LW t2,$0018(sp)
LW t3,$001c(sp)
LW t4,$0020(sp)
LW t5,$0024(sp)
LW t6,$0028(sp)
LW t7,$002c(sp)
LW s0,$0030(sp)
LW s1,$0034(sp)
LW s2,$0038(sp)
LW s3,$003c(sp)
LW s4,$0040(sp)
LW s5,$0044(sp)
LW s6,$0048(sp)
LW s7,$004c(sp)
LW ra,$0050(sp)
ADDI sp,sp,$0058
JR ra
NOP
lab708 sub v1,zero,1
ANDI v1,v1,$00ff
SLL a0,v1,$18
SLL a1,v1,$1f
SRL a3,a1,$10
NOR a2,R0,v1
sub sp,sp,$180
OR s2,sp,R0
sub sp,sp,8
SW ra,$0000(sp)
ADDI s0,s0,$0004
JAL laba04
NOP
ADDI s3,s0,$000a
OR s4,s1,R0
LBU t6,$0001(s3)
LBU at,$0000(s3)
OR t7,R0,R0
SLL t6,t6,08
OR t6,t6,at
ADD s5,s4,t0
ADDI t0,R0,$0002
ADDI t1,R0,$0002
JAL lab994
NOP
LW ra,$0000(sp)
ADDI sp,sp,$0008
lab774 sub sp,sp,8
SW ra,$0000(sp)
OR s0,s2,R0
JAL laba28
NOP
ADDI s0,s2,$0080
JAL laba28
NOP
ADDI s0,s2,$0100
JAL laba28
NOP
sub t0,R0,1
ADDI t1,R0,$0010
JAL lab994
NOP
LW ra,$0000(sp)
ADDI sp,sp,$0008
OR t4,t0,R0
sub at,R0,1
SRL at,at,$10
sub t4,t4,1
AND t4,at,t4
J lab834
NOP
lab7d4 ADDI s0,s2,$0080
sub sp,sp,8
SW ra,$0000(sp)
OR t0,R0,R0
JAL lab8bc
NOP
SUBU t0,R0,t0
ADD s1,s4,t0
sub s1,s1,1
ADDI s0,s2,$0100
JAL lab8bc
NOP
LW ra,$0000(sp)
ADDI sp,sp,$0008
ADDI s4,s4,$0001
LBU at,$0000(s1)
ADDI s1,s1,$0001
SB at,-1(s4)
lab81c ADDI s4,s4,$0001
LBU at,$0000(s1)
ADDI s1,s1,$0001
SB at,-1(s4)
BNE t0,R0,lab81c
subI t0,t0,1
lab834 sub sp,sp,8
SW ra,$0000(sp)
OR s0,s2,R0
JAL lab8bc
NOP
LW ra,$0000(sp)
ADDI sp,sp,$0008
sub t0,t0,1
BLTZ t0,lab89c
NOP
sub sp,sp,8
SW ra,$0000(sp)
JAL labba8
NOP
LW ra,$0000(sp)
ADDI sp,sp,$0008
LBU at,$0001(s3)
LBU t0,$0000(s3)
SLL at,at,8
OR t0,at,t0
SLLV t0,t0,t7
ADDI t1,R0,$0001
SLLV t1,t1,t7
subu t1,t1,1
AND t6,t6,t1
OR t6,t0,t6
lab89c BNE t4,R0,lab7d4
sub t4,t4,1
SUB at,s4,s5
BLTZ at,lab774
NOP
ADDI sp,sp,$0180
JR ra
NOP
lab8bc LBU t0,$0000(s0)
LBU at,$0001(s0)
ADDI s0,s0,$0002
SLL t0,t0,08
OR t0,at,t0
AND t0,t0,t6
LBU at,$0000(s0)
LBU v0,$0001(s0)
ADDI s0,s0,$0002
SLL at,at,08
OR at,at,v0
SUB t0,t0,at
BNE t0,R0,lab8bc
NOP
LBU t1,$003c(s0)
NOP
SUB t7,t7,t1
BGEZ t7,lab920
NOP
sub sp,sp,8
SW ra,$0000(sp)
JAL lab9c8
NOP
LW ra,$0000(sp)
ADDI sp,sp,$0008
lab920 SRLV t6,t6,t1
LBU t0,$003d(s0)
NOP
sub at,t0,2
BLTZ at,lab98c
NOP
sub t0,t0,1
OR t1,t0,R0
OR t2,t0,R0
LBU at,$003e(s0)
LBU t0,$003f(s0)
SLL at,at,8
OR t0,at,t0
AND t0,t0,t6
SUB t7,t7,t1
BGEZ t7,lab97c
NOP
sub sp,sp,8
SW ra,$0000(sp)
JAL lab9c8
NOP
LW ra,$0000(sp)
ADDI sp,sp,$0008
lab97c SRLV t6,t6,t1
ADDI at,R0,$0001
SLLV at,at,t2
OR t0,at,t0
lab98c JR ra
NOP
lab994 AND t0,t6,t0
SUB t7,t7,t1
BGEZ t7,lab9bc
NOP
sub sp,sp,8
SW ra,$0000(sp)
JAL lab9c8
NOP
LW ra,$0000(sp)
ADDI sp,sp,$0008
lab9bc SRLV t6,t6,t1
JR ra
NOP
lab9c8 ADD t7,t7,t1
SRLV t6,t6,t7
ADDI s3,s3,$0004
LBU at,-2(s3)
LBU v0,-1(s3)
sub s3,s3,2
SLL at,at,$10
SLL v0,v0,$18
OR t6,t6,v0
OR t6,t6,at
SUB t1,t1,t7
ADDI t7,R0,$0010
SUB t7,t7,t1
JR ra
NOP
laba04 ADDI t1,R0,$0003
laba08 SLL t0,t0,8
LBU at,$0000(s0)
ADDI s0,s0,$0001
OR t0,at,t0
BNE t1,R0,laba08
sub t1,1
JR ra
NOP
laba28 ADDI t0,R0,$001f
ADDI t1,R0,$0005
sub sp,sp,8
SW ra,$0000(sp)
JAL lab994
NOP
LW ra,$0000(sp)
ADDI sp,sp,$0008
sub t0,t0,1
BLTZ t0,labba0
NOP
OR t2,t0,R0
OR t3,t0,R0
sub sp,sp,$10
OR s1,sp,R0
laba64 ADDI t0,R0,$000f
ADDI t1,R0,$0004
sub sp,sp,8
SW ra,$0000(sp)
JAL lab994
NOP
LW ra,$0000(sp)
ADDI sp,sp,$0008
SB t0,$0000(s1)
ADDI s1,s1,$0001
BNE t2,R0,laba64
sub t2,t2,1
OR t0,a1,R0
ADDI t1,R0,$0001
OR t2,R0,R0
sub sp,sp,$10
SW t5,$0000(sp)
SW t6,$0004(sp)
SW t7,$0008(sp)
labab0 OR t4,t3,R0
ADDI s1,sp,$0010
labab8 LBU at,$0000(s1)
ADDI s1,s1,$0001
BNE t1,at,labb74
NOP
ADDI t5,R0,$0001
SLLV t5,t5,t1
sub t5,t5,1
SB t5,$0001(s0)
SRL at,t5,8
SB at,$0000(s0)
ADDI s0,s0,$0002
OR t5,t2,R0
SLL at,t5,$10
SRL t5,t5,$10
OR t5,t5,at
OR t7,t1,R0
sub t7,t7,1
labafc sub at,R0,1
SRL at,at,$10
AND t6,at,t6
AND at,t5,a3
SLL t5,t5,01
SRL t6,t6,01
BEQ at,R0,labb20
NOP
OR t6,t6,a3
labb20 BNE t7,R0,labafc
sub t7,t7,1
ADDI t5,R0,$0010
SUB t5,t5,t1
SRLV t6,t6,t5
SB t6,$0001(s0)
SRL at,t6,8
SB at,$0000(s0)
ADDI s0,s0,$0002
SB t1,$003c(s0)
OR t5,t3,R0
SUBU t5,t5,t4
SB t5,$003d(s0)
ADDI t6,R0,$0001
subu t5,t5,1
SLLV t6,t6,t5
subu t6,t6,1
SB t6,$003f(s0)
SRL at,t6,8
SB at,$003e(s0)
ADDU t2,t2,t0
labb74 BNE t4,R0,labab8
sub t4,t4,1
SRL t0,t0,1
ADDI t1,t1,$0001
ADDI at,R0,$0011
BNE t1,at,labab0
LW t5,$0000(sp)
LW t6,$0004(sp)
LW t7,$0008(sp)
ADDI sp,sp,$0010
ADDI sp,sp,$0010
labba0 JR ra
NOP
labba8 LBU at,$0000(s3)
NOP
SB at,$0000(s4)
ADDI s4,s4,$0001
ADDI s3,s3,$0001
BNE t0,R0,labba8
sub t0,t0,1
JR ra
NOP
;--------------------------
; the Game (RNC-Crunched)
;--------------------------
game incbin game.rnc
;
paste NOT: 0x8000f800
paste only: 8000f800
thats it. save and close depack.src
Later the file was compiled with "Hook points" and ASM Addresses to load up from the correct EXE MEM-ADDRESS and Disc-Sector. You can see it in the source code called as: ASM .... and *ficken (ficken = german and means "fuck" so we fucked SONY ). When pressed on the Gamepad "X" or "O", the game does now boot/load for the desired "TV Video Norm". Show a nice Cracktro, play a funny sound and remove copy protection or offer a "Trainer menu". Creating a PPF File was always done with our magic tools (one of them: "magic sector key"). MSK.exe scan the whole PS1 ISO and print the exact position of the Exe File and other important information.
UPDATE:
after 20 years i decided to code a FILERESIZER Windows Tool. Information attached
Here comes a screenshot:
UPDATE
I didn't noticed that there exist a newer Windows Tool called CDmage.
To make it easy to add your final patch back into the game.bin use this nice tool, if you don't intend to share your patch. In this case you must create a ppf file as described and you must follow the way with MSK.exe and so on.
A PPF File is a well known File that include all the Code and changes by a group for a Game. It can easily be distributed through the Internet, when Gamers wanna play US, EUR or JAP Games around the Globe in the desired "TV Norm" ... need to play with a Trainer or removing the Copy protection.
A PPF file mostly have a file size from 30 kb - 2 mb and contain all code to modify a original PS1 Game ISO. With a simple tool, like ppfOmat, you can choose the original ISO and the PPF-File which is to inject.
Here comes another screenshot:
UPDATE:
If you wanna convert your music.mod for the project, just simply use my new Tool. It is also attached to this Workshop (only 32BIT Version at the moment)
get all information from here: http://www.psxdev.net/forum/viewtopic.php?f=75&t=4037
Feel free to check back for updates.
===========================================================================================
If you want start coding, i want suggest this TUTORIAL, from the very Beginning.
The Tutorial explain Hardware and Source Code.
The Tutorial is only in GERMAN and based on the very close and familiar PSY-Q, called PSX GNU
see all Information here:
PSXGNU TUTORIAL for DEMO CODING. sorry, only in German
===========================================================================================
HERE: CODING RECTANGLE & LINES with Code...
Grab all Files incl. a Demo for PS1 EMU: the LINK is DEAD, back soon
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 SNIPPET OF OUR CRACKS
// ======================================================
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;
}
a old treasure (my old WebPage) from 1999 or so, hosted back online here:
http://www.inc-games-design.de/oldHosting/UCA/news.html
inc.