› Foros › Retro y descatalogado › Consolas clásicas
The N64 hardware has something called a Z-Buffer, and thanks to that, we were able to design the terrain and visuals however we wanted. (Super Mario 64 – 1996 Developer Interviews)
This was a huge advantage for them. In contrast, for Crash Bandicoot -- which came out for the PS1 at the same time -- we had to use over an hour of pre-computation distributed across a dozen SGI workstations for each level to get a high poly count on hardware lacking a Z-buffer.
A Z-buffer is critical, because sorting polygons is O(n^2), not O(n lg n). This is because cyclic overlap breaks the transitive property required for an N lg N sorting algorithm.
The PS2 got Sony to parity; at that point both Nintendo and Sony had shipped hardware with Z-buffers.
Did you consider any other alternatives? Curious if you had any other ideas that you sidelined as being too crazy.
No, that idea was crazy enough. The collision detection system and camera control code were also insane. Mark Cerny helped me make the collision code fast enough. Very clever assembly language tricks there, and we used 2K of "scratchpad" static RAM built in to the PS1 (for some reason) to make it fast enough.
Can you expand on how the precompute trick works further? So you're precomputing the order of the scenery/level polygons because of their predictable movement but how does that combine with objects with unpredictable movement (Crash, enemies etc.) when you render a frame? Did the limitations of this trick limit the gameplay you wanted?
I've been meaning to write a blog post about this, but here's a brief summary.
We wrote a software renderer for the SGI that exactly replicated how the PS1 hardware would render. I wrote an imperfect clone for Crash 1, then Stephen White wrote a pixel-accurate one for Crash 2. (This is why Crash 1 has "crispies", as Andy called them -- little pixel-sized glitches in the background -- and Crash 2 does not.)
When computing a level, we'd sample N points along the rail as we moved the camera forward through the level. At each point, we'd render the entire scene using the software renderer, then recover the rendered list of polygons, in sorted order, from the (software) Z buffer. We'd then store this sorted list of polygons for each of the N frames, using delta compression between frames to keep the size manageable. The pre-computation phase would choose N empirically, based on much change happened from frame to frame in any given section of the level; basically it would make N as large as it could be without blowing out the page allocation (which was in turn determined by how fast we could read from the CD).
This handled all the polygons in the background, which was completely static. For foreground objects like Crash, enemies, gems, etc, we'd bucket sort them in as we rendered the background. This required manual tuning in some cases, so we had an editor where we could manually adjust the "push-back" (i.e., bucket adjustment) for each object in real time while playing the game. These magic values were then stored with the associated objects as part of the level data. If we couldn't make an object sort in right via bucket adjustment, we'd change the background slightly until it worked. In other words, it was a massive hack.
In terms of gameplay, we took our inspiration primarily from Donkey Kong Country, which had linear gameplay. So the rail model actually worked really well for the gameplay we were trying to achieve. (DKC is still an awesome SNES game; check it out if you haven't played it recently.)
How did Spyro end up getting past this limitation to have a free roaming camera with a good poly count?
The Hastings brothers (who were actually down the hall from us when we were writing Crash) are really awesome coders. Even so, however, I don't think Spyro for PS1 actually had anywhere near Crash's effective polygon count. Crash himself was over 750 polygons, which was not bad for an entire frame of a PS 1 game.
radorn escribió:La verdad es que yo no se casi nada de las tecnicas matematicas que mencionas.
1=1
2=10
3=11
4=100
5=101
6=110
7=111
8=1000
radorn escribió:Una objeccion que tengo a tu explicacion es que si el responsable de las lineas extra fuese el proceso renderizador,
BMBx64 escribió:Por lo pronto necesito tomar el control de la posición de pantalla, luego podré experimentar y ver cuales son los rangos de pintado y resoluciones útiles.
video format timings
NTSC
color 3579545.45~ Hz (315MHz / 88)
hsync 15750/1.001
vsync 60/1.001
line 63,55~ microsec
PAL
color 4433618.75 Hz (+/- 0.5 Hz)
hsync 15625 Hz
vsync 50 Hz
line 64 microsec
MPAL
color 3575611.00 Hz
hsync 15750 Hz
vsync 60 Hz
line 63.492063492063492063492063492063 us
N64 timings
Xtal1=X
VCLK_ = Video Clock
NTSC Xn 14318181.81~Hz
VCLKn 48681818.18~Hz (Xn * 17 / 5) ((((315/88)*4)*17)/5)
FSCn 3579545.45~Hz (Xn * 1 / 4) (315/88)
PAL Xp 17734475.00 Hz
VCLKp 49656530.00 Hz (Xp * 14 / 5)
FSCp 4433618.75 Hz (Xp * 1 / 4)
MPAL Xm 14302446.00 Hz
VCLKm 48628318.00 Hz (Xm 17 / 5)
FSCm 3575611.50 Hz (Xm 1 / 4)
Xtal2=Y
Y=14705882.352941176470588235294118 Hz
RCLK 250 MHz = Y * 17
Rambus Clock
RCPclk = RCLK / 4 = 62.5 MHz
CPUclk = RCPclk * 1.5 = 93.75 MHz
--------------------------------------------------------------------------------
Here I'll try to calculate plausible video timings for the N64.
Pixel clock values can be calculated from known data.
Actual Hsync and Vsync timings are a result of line lenght in pixels and
display height in lines, which are set in software by the libraries that
control the VI, which is the element that puts the video data on the bus that
goes to the DAC. This is a 7bit wide bus with a fixed clock derived from the
color carrier frecuency, and sends sequences of 4 7-bit bytes, containing the
values for R, G, and B, and a control byte that signals, among other things,
the synchronization pulses that the DAC should generate. The pixel clock of
the N64 video subsystem is, therefore, a quarter of the video bus frecuency.
This scheme imposes that analog video lines have a fixed lenght in pixels.
I don't know what values actual games use or can use, so I'll try to calculate
possible timings by trying several reasonable values.
-------------------PAL N64--------------------
(283.75 * 15625) + 25
PAL carrier = 283.75 x 15625 = 4433593.75 -> +25 = 4433618.75 Hz
PAL color cycles per line = 283.75 or 283.7516
N64 PAL crystal = 17734475.00 Hz
|-> 1/4 (0.25x) = 4433618.75 Hz (PAL color)
|-> 14/5 (2.80x) = 49656530.00 Hz (video bus)
pixel clock = videobus / 4 (1 clock per RGB byte + 1 clock for signaling byte)
49656530 / 4 = 12414132.5 pixels per second
---50Hz modes for PAL N64---
794-pix lines = 15634.927581863979848866498740554 Hsync
+9.927581863979848866498740554 Hz vs STD
line duration = 63.959362444375392320003028806080 microsec
283.57142857142857142857142857143 chroma cycles
312 line 288p = 50.111947377769166182264419040238 Vsync
313 line 288p = 49.951845309469584181682104602409 Vsync
625 line 576i = 50.031768261964735516372795969773 Vsync
\ 25.015884130982367758186397984887 fps
795-pix lines = 15615.261006289308176100628930818 Hsync
-9.738993710691823899371069182 Hz vs STD
line duration = 64.039915797579895333000513729008 microsec
283.92857142857142857142857142857 chroma cycles
312 line 288p = 50.048913481696500564425092726980 Vsync
313 line 288p = 49.889012799646352000321498181527 Vsync
625 line 576i = 49.968835220125786163522012578616 Vsync
\ 24.984417610062893081761006289308 fps
796-pix lines = 15595.643844221105527638190954774 Hsync
-29.356155778894472361809045226 Hz vs STD
line duration = 64.120469150784398345997998651939 microsec
284.28571428571428571428571428571 chroma cycles
312 line 288p = 49.986037962247133101404458188378 Vsync
313 line 288p = 49.826338160450816382230642028032 Vsync
625 line 576i = 49.906060301507537688442211055276 Vsync
\ 24.953030150753768844221105527638 fps
---60Hz modes made for PAL N64---
nominal line lenght = pixel clock / horizontal sync
NTSC (12414132.5 / (15750 / 1.001)) = 788.98708777777777777777777777778
SysM (12414132.5 / 15750) = 788.19888888888888888888888888889
trying 788 789 790
788-pix lines = 15753.975253807106598984771573604 Hsync
+19.709519541372333250505839338327 Hz vs STD
line duration = 63.476042325148374242018119268503 microsec
chroma cycles
262 line 240p = 60.129676541248498469407525090092 Vsync
263 line 240p = 59.901046592422458551272895717125 Vsync
525 line 480i = 60.015143824027072758037225042301 Vsync
\ 30.007571912013536379018612521150 fps
789-pix lines = 15734.008238276299112801013941698 Hsync
-0.25749598943515293325179256738192 Hz vs STD
line duration = 63.555555555555555555555555555554 microsec
chroma cycles
262 line 240p = 60.053466558306485163362648632435 Vsync
263 line 240p = 59.825126381278703850954425633833 Vsync
525 line 480i = 59.939079002957329953527672158850 Vsync
\ 29.969539501478664976763836079425 fps
790-pix lines = 15714.091772151898734177215189873 Hsync
-20.173962113835531557050544392317 Hz vs STD
line duration = 63.637149031557380268013089114364 microsec
chroma cycles
262 line 240p = 59.977449512030147840371050343028 Hsync
263 line 240p = 59.749398373201135871396255474804 Hsync
525 line 480i = 59.863206751054852320675105485230 Hsync
\ 29.931603375527426160337552742615 fps
-------------------NTSC N64----------------------
NTSC carrier = 315000000/88 = 3579545.4545454545454545454545455
NTSC 227.5 chroma cycles per line
N64 NTSC crystal = 14318181.8181818181818181818181818 Hz
|-> 1/4 (0.25x) = 3579545.4545454545454545454545455 Hz (NTSC color)
|-> 17/5 (3.40x) = 48681818.1818181818181818181818182 Hz (video bus)
pixel clock = ((315000000/88)*(17/5)) = 12170454.545454545454545454545455
---60Hz modes---
nominal line lenght = pixel clock / horizontal sync
NTSC ((315000000/88)*(17/5))/(15750/1.001) = 773.5
SysM ((315000000/88)*(17/5))/(15750) = 772.72727272727272727272727272727
trying 772 773 774
(((315000000/88)*(17/5))/772)
772 pix lines = 15764.837494112105511069241639190
+30.571759846371245334975904924091 Hz vs STD
line duration = 63.432306255835667600373482726423
262 line 240p = 60.171135473710326378126876485457
263 line 240p = 59.942347886357815631441983418973
525 line 480i = 60.056523787093735280263777673105
\ 30.028261893546867640131888836552
(((315000000/88)*(17/5))/773)
773 pix lines = 15744.443137716100199929436669411
line duration = 63.432306255835667600373482726423
262 line 240p = 60.093294418763741221104720112255
263 line 240p = 59.864802805004183269693675549090
525 line 480i = 59.978831000823238856874044454898
\ 29.989415500411619428437022227449
(((315000000/88)*(17/5))/774)
774 pix lines = 15724.101479915433403805496828753
line duration = 63.596638655462184873949579831931
262 line 240p = 60.015654503494020625211819957071
263 line 240p = 59.787458098537769596218619120732
525 line 480i = 59.901338971106412966878083157153
\ 29.950669485553206483439041578576
Sogun escribió:Sin embargo hace poco he visto cosas brutales en GE. No sé si se puede hacer todo con el editor o si lo han hackeado por su cuenta, porque parece que la comunidad está desdoblada entre el foro que he mencionado antes y un canal de discord y es difícil seguir la pista. Hay hacks con sonido para las pisadas como en PD; con cinemáticas al principio, en medio y al final del nivel, diálogos hablados... y luego está esto (especialmente a partir del minuto 10:27):
SubEye
Lo veo ahora y ese primer nivel era premonitorio.
Sogun escribió:@Calculinho
Pues no tengo ni idea de si funciona en consola. El parche no estaba en GoldenEye Vault y no lo he probado.
__registers[1] = 0x00000140; /* base offset for field 1 */
__registers[2] = 0x00000140; /* width */
__registers[5] = 0x03E52239; /* burst */
__registers[6] = 0x0000020D; /* vsync */
__registers[7] = 0x00000C15; /* hsync */
__registers[8] = 0x0C150C15; /* leap */
__registers[9] = 0x006C02EC; /* hstart */
__registers[10] = 0x002501FF; /* vstart for field 1 */
__registers[11] = 0x000E0204; /* vburst for field 1 */
__registers[12] = 0x00000200; /* x-scale */
__registers[13] = 0x00000400; /* y-scale */
static vi_state_t vi_state = {
0x0000324E, // status, 0
0x00200000, // origin, 1
0x00000140, // width, 2
0x00000002, // intr, 3
0x00000000, // current, 4
0x03E52239, // burst, 5
0x0000020D, // v_sync, 6
0x00000C15, // h_sync, 7
0x0C150C15, // leap, 8
0x006C02EC, // h_start, 9
0x002501FF, // v_start, 10
0x000E0204, // v_burst, 11
0x00000200, // x_scale, 12
0x00000400, // y_scale, 13
};
0x3000 // control
0x0200 // AA resample
0x0040 // serrate
0x0008 // gamma correct
0x0004 // gamma correct dither
0x0002 // 16bit color mode
--
0x324E
BMBx64 escribió: @cegador
Eso estaría bien, a tí te gustaba modelar 3D no?
BMBx64 escribió:Ya que ésto va de curiosidades y el hilo ésta muy parado dejo un vídeo de como se hicieron las intros de Resident Evil 2 (y no me refiero a meterlas en el cartucho )
@cegador
Genial, aunque el desarrollo de las librerías se ha ralentizado por completo, la verdad es que hace un año por esta época era mucho más optimista
Oystein Aarseth escribió:Gracias por el video @BMBx64
Y gran juego este RE 2, si bien N64 no tuvo todos los RE, creo que se llevo el mejor juego de la trilogía original de esa generación , porque del primero es mejor el REmake.
Sexy MotherFucker escribió:@sinovic ¿no está ese unreleased en forma de rom por ahí rulando aún?
sinovic escribió:Oystein Aarseth escribió:Gracias por el video @BMBx64
Y gran juego este RE 2, si bien N64 no tuvo todos los RE, creo que se llevo el mejor juego de la trilogía original de esa generación , porque del primero es mejor el REmake.
Yo siempre espere el RE0 version N64 . Lo esperaba con muchas ganas en la consola pero bueno... lo cancelaron y salio pal cubo.
Seria genial que en una hipotetica N64 mini lanzaran de regalo esa version (RE0 N64) como hicieron con el star fox 2 en snes mini... seria genial.
ewin escribió:
Preferiria el Mother 64, que se confirmó que estaba acabado..
http://starmen.net/eb64/images/
sinovic escribió:ewin escribió:
Preferiria el Mother 64, que se confirmó que estaba acabado..
http://starmen.net/eb64/images/
Cuestiones de gusto supongo. En lo personal no soy fanatico de los RPG.