/*----------------------------------------------------------------------------- graphic00 -----------------------------------------------------------------------------*/ void graphic_00(void) { Dynamic* dynamic_ptr; NNScTask *t; static LookAt lookat; u16 perspNorm; u32 cnt; /* specify display list buffer/task buffer */ dynamic_ptr = &gfx_dynamic[gfx_gtask_no]; glist_ptr = &gfx_glist[gfx_gtask_no][0]; t = &gfx_task[gfx_gtask_no]; /* set RSP and RDP */ gfxRCPInit(); /* clear frame buffer and Z buffer */ gfxClearCfb(); /* calculate and set projection matrix */ guPerspective(&dynamic_ptr->projection, &perspNorm, 33, 320.0/240.0, 10, 2000, 1.0); guLookAtReflect(&dynamic_ptr->viewing, &lookat, 0, 50, -600 , 0, 0, 0, 0, 1, 0); gSPPerspNormalize(glist_ptr++, perspNorm); gSPLookAt(glist_ptr++, &lookat); gSPMatrix(glist_ptr++, &(dynamic_ptr->projection), G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH); gSPMatrix(glist_ptr++, &(dynamic_ptr->viewing), G_MTX_PROJECTION | G_MTX_MUL | G_MTX_NOPUSH); /* draw model */ for(cnt = 0; cnt < numControllers; cnt++){ ModelController(dynamic_ptr,&mtx_cont[cnt]); } /* end top-level display list */ gDPFullSync(glist_ptr++); gSPEndDisplayList(glist_ptr++); /* Flush the dynamic segment */ osWritebackDCacheAll(); gfxTaskStart(t, gfx_glist[gfx_gtask_no], (s32)(glist_ptr - gfx_glist[gfx_gtask_no]) * sizeof (Gfx), GFX_GSPCODE_F3DEX, NN_SC_SWAPBUFFER); }
/* * gameloop -- main loop of game * Called by gameproc; runs in gameThread. * Parameter: rsp_static_addr, the R4300 address where the * rsp_static segment was loaded */ static void gameloop(char *rsp_static_addr) { int oddframe = 0; /* Odd or even rendered frame? Start with even. */ int firstframe = 1; /* First frame? */ dynamic_stuff *generate; /* Dynamic info we're generating now */ Gfx *glistp0; /* Start of this frame's dynamic display list */ Gfx *glistp; /* Current position in dynamic display list */ OSTask *gentask; /* Task we're generating */ float t; /* Weight of 1st set of morph verticies */ int dir; /* Direction in which we're morphing */ int pausecnt; /* Countdown for "stickiness" at morph extremes */ t = 0.0; dir = 1; pausecnt = 0; while (1) { /* Start task on RSP, built in previous iteration of loop. */ if (!firstframe) osSpTaskStart(gentask); /* * Set up pointers to dynamic stuff. We're always generating one set * of dynamic data and drawing another. */ generate = &(dynamic[(oddframe ? 0 : 1)]); /* glist portion of generated dynamic data */ glistp0 = &(generate->glist[0]); glistp = glistp0; /* This one will be incremented as list is built */ /* * Tell RSP where each segment is */ gSPSegment(glistp++, 0, 0x0); /* Physical address segment */ /* Static segment (mapping never changes) */ gSPSegment(glistp++, STATIC_SEG, OS_K0_TO_PHYSICAL(rsp_static_addr)); /* Dynamic segment (mapping changes every frame) */ gSPSegment(glistp++, DYNAMIC_SEG, OS_K0_TO_PHYSICAL(generate)); /* RSP and RDP setup, and screen clear */ gSPDisplayList(glistp++, rspinit_dl); gSPDisplayList(glistp++, rdpinit_dl); #ifdef FB32BIT gDPSetColorImage(glistp++, G_IM_FMT_RGBA, G_IM_SIZ_32b, SCREEN_WD, OS_K0_TO_PHYSICAL(oddframe ? cfb_A : cfb_B)); #else gDPSetColorImage(glistp++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WD, OS_K0_TO_PHYSICAL(oddframe ? cfb_A : cfb_B)); #endif gSPDisplayList(glistp++, scrnclr_dl); /* Must set color image again after zbuffer clear */ #ifdef FB32BIT gDPSetColorImage(glistp++, G_IM_FMT_RGBA, G_IM_SIZ_32b, SCREEN_WD, OS_K0_TO_PHYSICAL(oddframe ? cfb_A : cfb_B)); #else gDPSetColorImage(glistp++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WD, OS_K0_TO_PHYSICAL(oddframe ? cfb_A : cfb_B)); #endif /* Set Z-buffer */ gDPSetDepthImage(glistp++, OS_K0_TO_PHYSICAL(zbuffer)); /* * Matrix setup, and call display list that does real work */ drawframe(generate, &glistp, t); /* * Put an END on the top-level display list, and check that we * haven't overflowed the buffer. */ gDPFullSync(glistp++); /* Only need this if you want 'accurate' SP done? */ gSPEndDisplayList(glistp++); #ifdef DEBUG if ((int)(glistp - glistp0) > GLIST_SIZE) { /* does this check work?? */ osSyncPrintf("*** GLIST OVERFLOW ***\n"); /* Could quit here or something */ } #endif /* Update morph parameter t */ if (pausecnt == 0) { t += dir*(1.0/60.0); /* A full 60 frames to do the morph */ if (t < 0.0) {t = 0.0; dir = 1; pausecnt = 60;} if (t > 1.0) {t = 1.0; dir = -1; pausecnt = 60;} } else { pausecnt--; } /* * Build graphics task * Note that all addresses are KSEG0, even if used by the RSP. * Conversion is done by the task routines. */ gentask = &(task[oddframe ? 0 : 1]); gentask->t.type = M_GFXTASK; gentask->t.flags = 0x0; gentask->t.ucode_boot = (u64*) rspbootTextStart; gentask->t.ucode_boot_size = ((int)rspbootTextEnd - (int)rspbootTextStart); gentask->t.ucode = (u64*) gspF3DEX2_xbusTextStart; /* use XBUS */ gentask->t.ucode_data = (u64*) gspF3DEX2_xbusDataStart; gentask->t.ucode_size = 4096; gentask->t.ucode_data_size = 2048; gentask->t.dram_stack = (u64*) dram_stack; gentask->t.dram_stack_size = SP_DRAM_STACK_SIZE64; gentask->t.output_buff = (u64*) NULL; gentask->t.output_buff_size= (u64*) NULL; gentask->t.yield_data_ptr = (u64*) NULL; /* Graphics only - no yielding */ gentask->t.yield_data_size = 0x0; gentask->t.data_ptr = (u64*) glistp0; gentask->t.data_size = ((int) glistp - (int) glistp0); /* * Flush the whole cache. Should just do parts of it. */ osWritebackDCacheAll(); if (!firstframe) { /* Wait for task completion (message from RDP) */ osRecvMesg(&RDPDoneMessageQ, NULL, OS_MESG_BLOCK); /* * Specify frame buffer to be displayed starting at next retrace. * We display the one that we've just finished rendering. */ osViSwapBuffer(oddframe ? cfb_B : cfb_A); } /* * Wait for the retrace before rendering next frame * (otherwise we might overwrite the frame which is being displayed). * But first, make sure that the retrace queue is empty in case we * took too long to render the last frame. */ if (MQ_IS_FULL(&RetraceMessageQ)) osRecvMesg(&RetraceMessageQ, NULL, OS_MESG_NOBLOCK); osRecvMesg(&RetraceMessageQ, NULL, OS_MESG_BLOCK); /* Switch to our other set of variables */ oddframe ^= 1; /* No longer the first frame */ firstframe = 0; } /* while(1) */ } /* gameloop */
void mainproc(void *arg) { int i, j; int cont_no = 0; int error, readerror; u8 bitpattern; u16 button = 0, oldbutton = 0, newbutton = 0; u32 stat; char console_text[50]; osCreateMesgQueue(&pifMesgQueue, pifMesgBuf, NUM_MESSAGE); osSetEventMesg(OS_EVENT_SI, &pifMesgQueue, dummyMessage); osContInit(&pifMesgQueue, &bitpattern, &contstat[0]); for (i = 0; i < MAXCONTROLLERS; i++) { if ((bitpattern & (1<<i)) && ((contstat[i].type & CONT_TYPE_MASK) == CONT_TYPE_NORMAL)) { controller[i] = CONT_VALID; } else { controller[i] = CONT_INVALID; } } osCreateMesgQueue(&dmaMessageQ, dmaMessageBuf, 1); pi_handle = osCartRomInit(); pi_ddrom_handle = osDriveRomInit(); bzero(blockData, 0x1000); readerror = -1; init_draw(); setcolor(0,255,0); draw_puts("If you see this for a long period of time,\nsomething f****d up. Sorry."); LeoCJCreateLeoManager((OSPri)OS_PRIORITY_LEOMGR-1, (OSPri)OS_PRIORITY_LEOMGR, LeoMessages, NUM_LEO_MESGS); LeoResetClear(); setbgcolor(15,15,15); clear_draw(); setcolor(0,255,0); draw_puts("\f\n 64DD IPL dumper v0.01b by LuigiBlood & marshallh\n ----------------------------------------\n"); setcolor(255,255,255); draw_puts(" PRESS START TO DUMP"); while(1) { osContStartReadData(&pifMesgQueue); osRecvMesg(&pifMesgQueue, NULL, OS_MESG_BLOCK); osContGetReadData(&contdata[0]); if (contdata[cont_no].errno & CONT_NO_RESPONSE_ERROR) { button = oldbutton; } else { oldbutton = button; button = contdata[cont_no].button; } newbutton = ~oldbutton & button; if (newbutton & START_BUTTON) { //DUMP!! //64drive, enable write to SDRAM/ROM srand(osGetCount()); // necessary to generate unique short 8.3 filenames on memory card ciEnableRomWrites(); draw_puts("\f\n\n\n\n\n Let's dump! Don't turn off the console!\n\n"); osInvalDCache((void *)&blockData, (s32) 0x1000); dmaIoMesgBuf.hdr.pri = OS_MESG_PRI_NORMAL; dmaIoMesgBuf.hdr.retQueue = &dmaMessageQ; dmaIoMesgBuf.dramAddr = &blockData; dmaIoMesgBuf.devAddr = IPLoffset; dmaIoMesgBuf.size = 0x1000; for (IPLoffset = 0; IPLoffset < 0x400000; IPLoffset += 0x1000) { //read 64DD IPL osWritebackDCacheAll(); dmaIoMesgBuf.hdr.pri = OS_MESG_PRI_NORMAL; dmaIoMesgBuf.hdr.retQueue = &dmaMessageQ; dmaIoMesgBuf.dramAddr = (void *)&blockData; dmaIoMesgBuf.devAddr = 0xA6000000 + IPLoffset; dmaIoMesgBuf.size = 0x1000; osEPiStartDma(pi_ddrom_handle, &dmaIoMesgBuf, OS_READ); osRecvMesg(&dmaMessageQ, NULL, OS_MESG_BLOCK); //Write to 64drive osWritebackDCacheAll(); dmaIoMesgBuf.hdr.pri = OS_MESG_PRI_NORMAL; dmaIoMesgBuf.hdr.retQueue = &dmaMessageQ; dmaIoMesgBuf.dramAddr = (void *)&blockData; dmaIoMesgBuf.devAddr = 0xB0000000 + IPLoffset; dmaIoMesgBuf.size = 0x1000; osEPiStartDma(pi_handle, &dmaIoMesgBuf, OS_WRITE); osRecvMesg(&dmaMessageQ, NULL, OS_MESG_BLOCK); } //DONE!! NOW WRITE TO SD fat_start(); draw_puts("\n - DONE !!\n"); for(;;); } } }