Page 1 of 1
Question about transition
Posted: May 24th, 2018, 5:08 am
by NITROYUASH
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?
Re: Question about transition
Posted: May 24th, 2018, 6:41 am
by Sblorgz
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.
Re: Question about transition
Posted: May 26th, 2018, 9:49 pm
by NITROYUASH
Okay, after 2 days of mistakes, i'm still don't get it how it works.
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();
}
}
EPSXE crash:
Re: Question about transition
Posted: May 27th, 2018, 2:02 am
by Sblorgz
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.
Re: Question about transition
Posted: June 22nd, 2018, 9:53 pm
by NITROYUASH
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).
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;
}
}
Re: Question about transition
Posted: June 23rd, 2018, 2:04 am
by Sblorgz
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.
Re: Question about transition
Posted: June 23rd, 2018, 2:34 am
by Shadow
Sony has some TILE examples in Psy-Q.
Re: Question about transition
Posted: June 23rd, 2018, 2:47 am
by NITROYUASH
Sblorgz
It's working! I forgot to create a second TILE. lol!
Re: Question about transition
Posted: June 25th, 2018, 8:57 am
by NITROYUASH
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'''
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]);
// <-
}
}
Did i miss something important again?
Re: Question about transition
Posted: June 25th, 2018, 6:19 pm
by Sblorgz
You're still doing it incorrectly, you need something like this:
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]);
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().
Re: Question about transition
Posted: June 25th, 2018, 9:29 pm
by NITROYUASH
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);
Re: Question about transition
Posted: June 26th, 2018, 2:21 pm
by Sblorgz
Try a better solution like a loop to initialize those primitives:
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
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.
Re: Question about transition
Posted: June 26th, 2018, 8:51 pm
by NITROYUASH
Huh. Without ClearOTagR() tiles didn't work (invisible?).
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]);
}
}
Re: Question about transition
Posted: June 26th, 2018, 10:57 pm
by Sblorgz
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.
Re: Question about transition
Posted: June 27th, 2018, 12:36 am
by NITROYUASH
tried everything, but...
Without ClearOTagR() tiles didn't work
._ .
Re: Question about transition
Posted: June 27th, 2018, 1:09 am
by Sblorgz
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.
Re: Question about transition
Posted: June 27th, 2018, 1:39 am
by NITROYUASH
Posting the whole thing again instead of snippets would help in figuring out what you're missing.
I will sent my project in your PM, okay?
Re: Question about transition
Posted: June 27th, 2018, 2:13 am
by Sblorgz
Sure, send a pastebin link, it's easier to read.
Re: Question about transition
Posted: June 27th, 2018, 6:31 am
by NITROYUASH
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();
}
}