Question about transition
-
NITROYUASH Verified
- Serious PSXDEV User
- Posts: 124
- Joined: Jan 07, 2018
- I am a: Game Designer
- PlayStation Model: SCPH-5502
- Location: Russian Federation
- Contact:
Question about transition
Hi PSXDEV :>
I want to do smooth transition between screens, but i have no idea how it works.
Can you explain how it works in PS1?
I want to do smooth transition between screens, but i have no idea how it works.
Can you explain how it works in PS1?
You would use a TILE + DMODE primitive that covers the whole screen, create the DMODE as subtractive color, then change the TILE RGB to change fade transition. RGB = 255 means the mask will make the screen fully black, RGB = 0 makes the screen visible again.
-
NITROYUASH Verified
- Serious PSXDEV User
- Posts: 124
- Joined: Jan 07, 2018
- I am a: Game Designer
- PlayStation Model: SCPH-5502
- Location: Russian Federation
- Contact:
Okay, after 2 days of mistakes, i'm still don't get it how it works.
Did i miss something?
EPSXE crash:
Did i miss something?
Code: Select all
void TileTest () {
DR_MODE dr_prim;
TILE tl_prim;
FntLoad(960, 256);
FntOpen(0, 0, SCREENXRES, SCREENYRES, 0, 512);
SetTile16(&tl_prim);
SetDrawMode(&dr_prim, 0, 0, GetTPage(0, 0, 0, 0), 0);
SetSemiTrans(&tl_prim, 0);
MargePrim(&dr_prim, &tl_prim);
setRGB0(&tl_prim, 128, 128, 128);
setXY0(&tl_prim, CENTERX, CENTERY);
setWH (&tl_prim, 64, 64);
while (1) {
PrepDisp();
sp_cursor();
FntPrint("\n\n %c TILE Test %c", cursor[pos], cursor[pos]);
AddPrim(&myOT[ActiveBuffer], &tl_prim);
Display();
}
}
► Show Spoiler
That's because you need two primitives, one per draw environment. Also, you need to set the transparency flag on TILEs otherwise blending won't trigger.
-
NITROYUASH Verified
- Serious PSXDEV User
- Posts: 124
- Joined: Jan 07, 2018
- I am a: Game Designer
- PlayStation Model: SCPH-5502
- Location: Russian Federation
- Contact:
alright, i'm back and ready for educating
so, where i can find some good examples how TILEs working? It's seems that my code isn't working (still no tiles).
so, where i can find some good examples how TILEs working? It's seems that my code isn't working (still no tiles).
Code: Select all
// Loading basic PS1 libraries
#include <sys/types.h>
#include <libgte.h>
#include <libgpu.h>
#include <libetc.h>
#include <stdlib.h>
#include <stdio.h>
#define OT_LENGTH 12 // OT precision/size
#define OT_ENTRIES 1<<OT_LENGTH
#define MAX_PRIMS 16384 // Primitive area size
// Screen resolution
#define SCREENXRES 320
#define SCREENYRES 240
// Calculate center of screen
#define CENTERX SCREENXRES/2
#define CENTERY SCREENYRES/2
// Stuff for display and rendering
DISPENV disp;
DRAWENV draw;
RECT ClearRect ={ 0, 0, SCREENXRES, SCREENYRES };
u_long myOT[2][OT_ENTRIES]; // Ordering table (contains pointers to primitives)
u_long myPrims[2][MAX_PRIMS]; // Primitive list (can contain various primitive types)
u_long *myPrimPtr=0; // Next primitive pointer
int ActivePage=0;
// Spinning cursor
static char pos=0;
static char cur_frame=0;
char cursor[4]={'/','-','\\','i'};
int main();
void Init();
void sp_cursor();
int main() {
DR_MODE dr_prim;
TILE tl_prim;
long i, p, t, OTz, OTc, Flag, nclip;
int NumPrims;
int r, g, b;
Init();
FntLoad(960, 256);
FntOpen(0, 0, SCREENXRES, SCREENYRES, 0, 512);
SetTile(&tl_prim);
SetDrawMode(&dr_prim, 0, 0, GetTPage(0, 0, 0, 0), 0);
SetSemiTrans(&tl_prim, 1);
MargePrim(&dr_prim, &tl_prim);
setRGB0(&tl_prim, 128, 128, 128);
setXY0(&tl_prim, 120, 120);
setWH (&tl_prim, 64, 64);
while (1) {
// Toggle buffer index
ActivePage = (ActivePage + 1) & 1;
// Clear the current OT
ClearOTagR(&myOT[ActivePage][0], OT_ENTRIES);
sp_cursor();
FntPrint("\n\n %c TILE Test %c", cursor[pos], cursor[pos]);
AddPrim(&myOT[ActivePage][OTc], &dr_prim);
// Prepare to switch buffers
SetDefDispEnv(&disp, 0, 256*ActivePage, SCREENXRES, SCREENYRES);
SetDefDrawEnv(&draw, 0, 256*(1-ActivePage), SCREENXRES, SCREENYRES);
// Wait for all drawing to finish and wait for VSync
while(DrawSync(1));
VSync(0);
if (PadRead(0) & PADRright) r++;
if (PadRead(0) & PADRup) g++;
if (PadRead(0) & PADRdown) b++;
if (PadRead(0) & PADL1) r--;
if (PadRead(0) & PADL2) g--;
if (PadRead(0) & PADR1) b--;
// Switch display buffers
PutDispEnv(&disp);
PutDrawEnv(&draw);
// Clear the drawing buffer before drawing the next frame
ClearRect.y = 256*(1-ActivePage);
ClearImage(&ClearRect, 0, 0, 0);
// Begin drawing the new frame
DrawOTag(&myOT[ActivePage][OT_ENTRIES-1]);
FntFlush(0);
SetDispMask(1);
}
}
void Init() {
// Reset the GPU and initialize the controller
ResetGraph(0);
PadInit(0);
SetVideoMode(0);
// Init font system
FntLoad(960, 0);
FntOpen(0, 0, SCREENXRES, SCREENYRES, 0, 512);
// Initialize and setup the GTE
InitGeom();
SetGeomOffset(CENTERX, CENTERY);
SetGeomScreen(CENTERX);
// Set the display and draw environments
SetDefDispEnv(&disp, 0, 0, SCREENXRES, SCREENYRES);
SetDefDrawEnv(&draw, 0, 256, SCREENXRES, SCREENYRES);
// Set the new display/drawing environments
VSync(0);
PutDispEnv(&disp);
PutDrawEnv(&draw);
ClearImage(&ClearRect, 0, 0, 0);
}
void sp_cursor() {
cur_frame++;
if (cur_frame >= 8) {
cur_frame = 0;
pos = (pos+1) % 4;
}
}
► Show Spoiler
You still have only one primitive for each type, you need two per frame: they have to be different or otherwise DMA will commit suicide. Also you aren't setting any blending mode in DR_MODE.
-
Shadow Verified
- Admin / PSXDEV
- Posts: 2670
- Joined: Dec 31, 2012
- PlayStation Model: H2000/5502
- Discord: Shadow^PSXDEV
Sony has some TILE examples in Psy-Q.
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.
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.
-
NITROYUASH Verified
- Serious PSXDEV User
- Posts: 124
- Joined: Jan 07, 2018
- I am a: Game Designer
- PlayStation Model: SCPH-5502
- Location: Russian Federation
- Contact:
Sblorgz
It's working! I forgot to create a second TILE. lol!
It's working! I forgot to create a second TILE. lol!
► Show Spoiler
-
NITROYUASH Verified
- Serious PSXDEV User
- Posts: 124
- Joined: Jan 07, 2018
- I am a: Game Designer
- PlayStation Model: SCPH-5502
- Location: Russian Federation
- Contact:
Transition effect is working, but i have yet another trouble.
If i'm loading some sprites/textures/etc, there is high chance to crash the game or get some graphical garbage on the screen. But sometimes everything is fine o_o'''
Did i miss something important again?
If i'm loading some sprites/textures/etc, there is high chance to crash the game or get some graphical garbage on the screen. But sometimes everything is fine o_o'''
Code: Select all
void TileTest () {
DR_MODE dr_prim;
TILE tl_prim;
TILE tl_prim_2;
int rt = 255, gt = 255, bt = 255;
FntLoad(960, 256);
FntOpen(0, 0, SCREENXRES, SCREENYRES, 0, 512);
SetTile(&tl_prim);
SetDrawMode(&dr_prim, 0, 0, GetTPage(0, 2, 0, 0), 0);
SetSemiTrans(&tl_prim, 1);
setXY0(&tl_prim, 0, 0);
setWH (&tl_prim, SCREENXRES, SCREENYRES);
MargePrim(&dr_prim, &tl_prim_2);
STARTSCR[0] = PrepDataSPR(MenuSCRTim[2], CENTERX, CENTERY, 128, 128, 128);
STARTSCR[0].w = 256;
STARTSCR[1].w = 64;
STARTSCR[1] = PrepDataSPR(MenuSCRTim[2], CENTERX+256, CENTERY, 128, 128, 128);
STARTSCR[1].tpage = (GetTPage(2,0,256,240))+5;
START_TEXT = PrepDataSPR(MenuSCRTim[1], CENTERX, CENTERY+75, 128, 128, 128);
while (1) {
//PrepDisp();
//PrepDisp ->
ActiveBuffer = GsGetActiveBuff();
GsSetWorkBase((PACKET*)GPUPacketArea[ActiveBuffer]);
GsClearOt(0, 0, &myOT[ActiveBuffer][0]);
// <-
setRGB0(&tl_prim, rt, gt, bt);
AddPrim((u_long *)&myOT[ActiveBuffer][0], &tl_prim);
AddPrim((u_long *)&myOT[ActiveBuffer][0], &tl_prim_2);
AddPrim((u_long *)&myOT[ActiveBuffer][0], &dr_prim);
GsSortSprite(&START_TEXT, &myOT[ActiveBuffer][0], 0);
GsSortSprite(&STARTSCR[0], &myOT[ActiveBuffer][0], 0);
GsSortSprite(&STARTSCR[1], &myOT[ActiveBuffer][0], 0);
if (PadRead(0) & PADL1) rt++, gt++, bt++;
if (PadRead(0) & PADR1) rt--, gt--, bt--;
if (PadRead(0) & PADselect) rt = 0, gt = 0, bt = 0;
if (PadRead(0) & PADstart) rt = 255, gt = 255, bt = 255;
DrawOTag((u_long *)&myOT[ActiveBuffer][0]);
//Display();
//Display ->
VSync(0);
GsSwapDispBuff();
GsSortClear(0, 0, 0, &myOT[ActiveBuffer][0]);
GsDrawOt(&myOT[ActiveBuffer][0]);
// <-
}
}
► Show Spoiler
You're still doing it incorrectly, you need something like this:
Also don't bother with MargePrim(), it's pretty much broken when two primitives are not consecutive in memory. On top of that, there's no need for DrawOTag() if you already have GsDrawOt().
Code: Select all
// declaration
TILE t[2];
DR_MODE m[2];
[...]
// inside draw loop
AddPrim((u_long *)&myOT[ActiveBuffer][0], &t[ActiveBuffer]);
AddPrim((u_long *)&myOT[ActiveBuffer][0], &m[ActiveBuffer]);
-
NITROYUASH Verified
- Serious PSXDEV User
- Posts: 124
- Joined: Jan 07, 2018
- I am a: Game Designer
- PlayStation Model: SCPH-5502
- Location: Russian Federation
- Contact:
And TILE/DR attributes need to be like this (without MergePrim), right?
Code: Select all
SetTile(&tile[2]);
SetDrawMode(&dr_prim[2], 0, 0, GetTPage(0, 2, 0, 0), 0);
SetSemiTrans(&tile[2], 1);
setRGB0(&tile[2], 128, 128, 128);
setXY0(&tile[2], 0, 0);
setWH (&tile[2], SCREENXRES, SCREENYRES);
Try a better solution like a loop to initialize those primitives:
Remember to use macros instead of functions (they all start with a lowercase letter), they tend to bloat the binary a bit, but they provide a good boost in performance.
Code: Select all
// after declaration
for(i = 0; i < 2; i++)
{
setTile(&tile[i]);
setDrawMode(&dr_prim[i], 0, 0, getTPage(0, 2, 0, 0), 0);
setSemiTrans(&tile[i], 1);
setRGB0(&tile[i], 128, 128, 128);
setXY0(&tile[i], 0, 0);
setWH (&tile[i], SCREENXRES, SCREENYRES);
}
//draw loop goes here
-
NITROYUASH Verified
- Serious PSXDEV User
- Posts: 124
- Joined: Jan 07, 2018
- I am a: Game Designer
- PlayStation Model: SCPH-5502
- Location: Russian Federation
- Contact:
Huh. Without ClearOTagR() tiles didn't work (invisible?).
Of course with ClearOTag all screen is clearing except TILE's.
Tile test code:
Of course with ClearOTag all screen is clearing except TILE's.
Tile test code:
Code: Select all
void TileTest () {
DR_MODE dr_prim[2];
TILE tile[2];
int rt = 0, gt = 0, bt = 0;
int i;
for(i = 0; i < 2; i++)
{
SetTile(&tile[i]);
SetDrawMode(&dr_prim[i], 0, 0, getTPage(0, 0, 0, 0), 0);
SetSemiTrans(&tile[i], 0);
setXY0(&tile[i], 220, 64);
setWH (&tile[i], SCREENXRES/4, SCREENYRES/4);
}
FntLoad(960, 256);
FntOpen(0, 0, SCREENXRES, SCREENYRES, 0, 512);
STARTSCR[0] = PrepDataSPR(MenuSCRTim[2], CENTERX, CENTERY, 128, 128, 128);
STARTSCR[0].w = 256;
while (1) {
ActiveBuffer = GsGetActiveBuff();
GsSetWorkBase((PACKET*)GPUPacketArea[ActiveBuffer]);
GsClearOt(0, 0, &myOT[ActiveBuffer][0]);
ClearOTagR((u_long *)&myOT[ActiveBuffer][0], OT_ENTRIES);
for(i = 0; i < 2; i++) {
setRGB0(&tile[i], rt, gt, bt);
}
AddPrim((u_long *)&myOT[ActiveBuffer][0], &tile[ActiveBuffer]);
AddPrim((u_long *)&myOT[ActiveBuffer][0], &dr_prim[ActiveBuffer]);
GsSortSprite(&STARTSCR[0], &myOT[ActiveBuffer][0], 0);
if (PadRead(0) & PADL1) rt++, gt++, bt++;
if (PadRead(0) & PADR1) rt--, gt--, bt--;
if (PadRead(0) & PADselect) rt = 0, gt = 0, bt = 0;
if (PadRead(0) & PADstart) rt = 255, gt = 255, bt = 255;
if (PadRead(0) & PADRright) break;
if (rt < 1 || gt < 1 || bt < 1) rt = gt = bt = 0;
if (rt > 255 || gt > 255 || bt > 255) rt = gt = bt = 255;
FntFlush(-1);
VSync(0);
GsSwapDispBuff();
GsSortClear(0, 0, 0, &myOT[ActiveBuffer][0]);
GsDrawOt(&myOT[ActiveBuffer][0]);
}
}
You have a call to ClearOTagR() that isn't necessary because it's already in GsClearOt(). Also do not update both TILE primitives' RGB channels, only redefine those for the current buffer TILE or otherwise you will get glitches with colors jumping around.
-
NITROYUASH Verified
- Serious PSXDEV User
- Posts: 124
- Joined: Jan 07, 2018
- I am a: Game Designer
- PlayStation Model: SCPH-5502
- Location: Russian Federation
- Contact:
tried everything, but...
._ .Without ClearOTagR() tiles didn't work
You can't mix libgpu and libgs unless you know exactly what the latter does internally. With that said, I think you are missing quite a few initialization points for libgs internals, like OTag definitions for size and ot starting pointers. Functions such as GsClearOt require a GsOT structure for myOt, which in your code was declared as a simple u_long. Posting the whole thing again instead of snippets would help in figuring out what you're missing.
-
NITROYUASH Verified
- Serious PSXDEV User
- Posts: 124
- Joined: Jan 07, 2018
- I am a: Game Designer
- PlayStation Model: SCPH-5502
- Location: Russian Federation
- Contact:
I will sent my project in your PM, okay?Posting the whole thing again instead of snippets would help in figuring out what you're missing.
Sure, send a pastebin link, it's easier to read.
-
NITROYUASH Verified
- Serious PSXDEV User
- Posts: 124
- Joined: Jan 07, 2018
- I am a: Game Designer
- PlayStation Model: SCPH-5502
- Location: Russian Federation
- Contact:
We found a solution. Perhaps it will be useful for someone :)
Code: Select all
void TileTest () {
DR_MODE dr_prim[2];
TILE tile[2];
int rt = 255, gt = 255, bt = 255;
int i;
for(i = 0; i < 2; i++)
{
SetTile(&tile[i]);
SetDrawMode(&dr_prim[i], 0, 0, getTPage(0, 2, 0, 0), 0);
SetSemiTrans(&tile[i], 1);
setXY0(&tile[i], 0, 0);
setWH (&tile[i], SCREENXRES, SCREENYRES);
}
FntLoad(960, 256);
FntOpen(0, 0, SCREENXRES, SCREENYRES, 0, 512);
while (1) {
PrepDisp();
for(i = 0; i < 2; i++) setRGB0(&tile[i], rt, gt, bt);
sp_cursor();
FntPrint("\n\n %c TILE Test %c", cursor[pos], cursor[pos]);
FntPrint("\n\n R:%d G:%d B:%d ", rt, gt, bt);
AddPrim((u_long *)myOT[ActiveBuffer][0].org, &tile[ActiveBuffer]);
AddPrim((u_long *)myOT[ActiveBuffer][0].org, &dr_prim[ActiveBuffer]);
if (PadRead(0) & PADL1) rt++, gt++, bt++;
if (PadRead(0) & PADR1) rt--, gt--, bt--;
if (PadRead(0) & PADselect) rt = 0, gt = 0, bt = 0;
if (PadRead(0) & PADstart) rt = 255, gt = 255, bt = 255;
if (rt < 1 || gt < 1 || bt < 1) rt = gt = bt = 0;
if (rt > 255 || gt > 255 || bt > 255) rt = gt = bt = 255;
Display();
}
}
Who is online
Users browsing this forum: No registered users and 2 guests