123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- program gxsprites;
- {$J+}
- {$macro on}
- {$mode objfpc}
- uses
- cmem, ctypes, gctypes, gccore;
- {$include inc/textures.tpl.inc}
- {$link build/textures.tpl.o}
- const
- ballsprites = 0;
- const
- DEFAULT_FIFO_SIZE = (256 * 1024);
- const
- RAND_MAX = 2147483647;
- var
- frameBuffer: array [0..1] of pcuint32 = (nil, nil);
- rmode: PGXRModeObj = nil;
- const
- NUM_SPRITES = 1024;
- //simple sprite struct
- type
- TSprite = record
- x, y: cint; // screen co-ordinates
- dx, dy: cint; // velocity
- image: cint;
- end;
- var
- sprites: array [0..NUM_SPRITES - 1] of TSprite;
- texObj: GXTexObj;
- fb: cuint32; // initial framebuffer index
- first_frame: cuint32;
- yscale: f32;
- xfbHeight: cuint32;
- perspective: Mtx44;
- GXmodelView2D: Mtx;
- gp_fifo: pointer = nil;
- background: GXColor = (r: 0; g: 0; b: 0; a: $ff; );
- i: cint;
- spriteTPL: TPLFile;
- texCoords: array[0..31] of f32 = (
- 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.0, 0.5,
- 0.5, 0.0, 1.0, 0.0, 1.0, 0.5, 0.5, 0.5,
- 0.0, 0.5, 0.5, 0.5, 0.5, 1.0, 0.0, 1.0,
- 0.5, 0.5, 1.0, 0.5, 1.0, 1.0, 0.5, 1.0);
- procedure drawSpriteTex(x, y, Width, Height, image: cint);
- var
- texIndex: cint;
- begin
- texIndex := image * 8;
- GX_Begin(GX_QUADS, GX_VTXFMT0, 4); // Draw A Quad
- GX_Position2f32(x, y); // Top Left
- GX_TexCoord2f32(texCoords[texIndex], texCoords[texIndex + 1]);
- texIndex := texIndex + 2;
- GX_Position2f32(x + Width - 1, y); // Top Right
- GX_TexCoord2f32(texCoords[texIndex], texCoords[texIndex + 1]);
- texIndex := texIndex + 2;
- GX_Position2f32(x + Width - 1, y + Height - 1); // Bottom Right
- GX_TexCoord2f32(texCoords[texIndex], texCoords[texIndex + 1]);
- texIndex := texIndex + 2;
- GX_Position2f32(x, y + Height - 1); // Bottom Left
- GX_TexCoord2f32(texCoords[texIndex], texCoords[texIndex + 1]);
- GX_End(); // Done Drawing The Quad
- end;
- begin
- VIDEO_Init();
- rmode := VIDEO_GetPreferredMode(nil);
- fb := 0;
- first_frame := 1;
- // allocate 2 framebuffers for double buffering
- frameBuffer[0] := (SYS_AllocateFramebuffer(rmode));
- frameBuffer[1] := (SYS_AllocateFramebuffer(rmode));
- VIDEO_Configure(rmode);
- VIDEO_SetNextFramebuffer(frameBuffer[fb]);
- VIDEO_SetBlack(False);
- VIDEO_Flush();
- VIDEO_WaitVSync();
- if (rmode^.viTVMode and VI_NON_INTERLACE) <> 0 then
- VIDEO_WaitVSync();
- // setup the fifo and then init the flipper
- gp_fifo := memalign(32, DEFAULT_FIFO_SIZE);
- memset(gp_fifo, 0, DEFAULT_FIFO_SIZE);
- fb := fb xor 1;
- GX_Init(gp_fifo, DEFAULT_FIFO_SIZE);
- // clears the bg to color and clears the z buffer
- GX_SetCopyClear(background, $00ffffff);
- // other gx setup
- GX_SetViewport(0, 0, rmode^.fbWidth, rmode^.efbHeight, 0, 1);
- yscale := GX_GetYScaleFactor(rmode^.efbHeight, rmode^.xfbHeight);
- xfbHeight := GX_SetDispCopyYScale(yscale);
- GX_SetScissor(0, 0, rmode^.fbWidth, rmode^.efbHeight);
- GX_SetDispCopySrc(0, 0, rmode^.fbWidth, rmode^.efbHeight);
- GX_SetDispCopyDst(rmode^.fbWidth, xfbHeight);
- GX_SetCopyFilter(rmode^.aa, rmode^.sample_pattern, GX_TRUE, rmode^.vfilter);
- if rmode^.viHeight = 2 * rmode^.xfbHeight then
- GX_SetFieldMode(rmode^.field_rendering, GX_ENABLE)
- else
- GX_SetFieldMode(rmode^.field_rendering, GX_DISABLE);
- if (rmode^.aa) <> 0 then
- GX_SetPixelFmt(GX_PF_RGB565_Z16, GX_ZC_LINEAR)
- else
- GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
- GX_SetCullMode(GX_CULL_NONE);
- GX_CopyDisp(frameBuffer[fb], GX_TRUE);
- GX_SetDispCopyGamma(GX_GM_1_0);
- // setup the vertex descriptor
- // tells the flipper to expect direct data
- GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_F32, 0);
- GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
- GX_SetNumChans(1);
- GX_SetNumTexGens(1);
- GX_SetTevOp(GX_TEVSTAGE0, GX_REPLACE);
- GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
- GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
- GX_InvalidateTexAll();
- TPL_OpenTPLFromMemory(@spriteTPL, @textures_tpl, textures_tpl_size);
- TPL_GetTexture(@spriteTPL, ballsprites, @texObj);
- GX_LoadTexObj(@texObj, GX_TEXMAP0);
- guOrtho(perspective, 0, 479, 0, 639, 0, 300);
- GX_LoadProjectionMtx(perspective, GX_ORTHOGRAPHIC);
- WPAD_Init();
- randomize();
- for i := 0 to NUM_SPRITES - 1 do
- begin
- //random place and speed
- sprites[i].x := random(640 - 32 + 1) shl 8;
- sprites[i].y := random(480 - 32 + 1) shl 8;
- sprites[i].dx := random($FF + 1) + $100;
- sprites[i].dy := random($FF + 1) + $100;
- sprites[i].image := random(4);
- if random(2) <> 0 then
- sprites[i].dx := -sprites[i].dx;
- if random(2) <> 0 then
- sprites[i].dy := -sprites[i].dy;
- end;
- while True do
- begin
- WPAD_ScanPads();
- if (WPAD_ButtonsDown(0) and WPAD_BUTTON_HOME) <> 0 then
- exit;
- GX_SetViewport(0, 0, rmode^.fbWidth, rmode^.efbHeight, 0, 1);
- GX_InvVtxCache();
- GX_InvalidateTexAll();
- GX_ClearVtxDesc();
- GX_SetVtxDesc(GX_VA_POS, GX_DIRECT);
- GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
- guMtxIdentity(GXmodelView2D);
- guMtxTransApply(GXmodelView2D, GXmodelView2D, 0.0, 0.0, -5.0);
- GX_LoadPosMtxImm(GXmodelView2D, GX_PNMTX0);
- for i := 0 to NUM_SPRITES - 1 do
- begin
- sprites[i].x := sprites[i].x + sprites[i].dx;
- sprites[i].y := sprites[i].y + sprites[i].dy;
- //check for collision with the screen boundaries
- if (sprites[i].x < (1 shl 8)) or (sprites[i].x > ((640 - 32) shl 8)) then
- sprites[i].dx := -sprites[i].dx;
- if (sprites[i].y < (1 shl 8)) or (sprites[i].y > ((480 - 32) shl 8)) then
- sprites[i].dy := -sprites[i].dy;
- drawSpriteTex(sprites[i].x shr 8, sprites[i].y shr 8, 32, 32, sprites[i].image);
- end;
- GX_DrawDone();
- GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
- GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR);
- GX_SetAlphaUpdate(GX_TRUE);
- GX_SetColorUpdate(GX_TRUE);
- GX_CopyDisp(frameBuffer[fb], GX_TRUE);
- VIDEO_SetNextFramebuffer(frameBuffer[fb]);
- if (first_frame) <> 0 then
- begin
- VIDEO_SetBlack(False);
- first_frame := 0;
- end;
- VIDEO_Flush();
- VIDEO_WaitVSync();
- fb := fb xor 1; // flip framebuffer
- end;
- end.
|