コード例 #1
0
ファイル: sprite.cpp プロジェクト: 86400/scummvm
void Sprite::render() {
	if (dirtyPixels) {
		dirtyPixels = false;
		GSPGPU_FlushDataCache(pixels, w * h * format.bytesPerPixel);
		C3D_SafeDisplayTransfer((u32*)pixels, GX_BUFFER_DIM(w, h), (u32*)texture.data, GX_BUFFER_DIM(w, h), TEXTURE_TRANSFER_FLAGS);
		gspWaitForPPF();
	}
	C3D_TexBind(0, &texture);

	C3D_BufInfo *bufInfo = C3D_GetBufInfo();
	BufInfo_Init(bufInfo);
	BufInfo_Add(bufInfo, vertices, sizeof(vertex), 2, 0x10);
	C3D_DrawArrays(GPU_TRIANGLE_STRIP, 0, 4);
}
コード例 #2
0
ファイル: AppImpl.cpp プロジェクト: nehalem501/open-tgm
void load_texture(C3D_Tex *tex, const u8 *img, const u32 img_size) {
	unsigned int width, height;
	u8* image;

	lodepng_decode32(&image, &width, &height, img, img_size);

	u8 *gpusrc = (u8 *) linearAlloc(width * height * 4);

	// lodepng outputs big endian rgba so we need to convert
	convert_endianess(gpusrc, image, width * height);

	// ensure data is in physical ram
	GSPGPU_FlushDataCache(gpusrc, width * height * 4);

	// Load the texture and bind it to the first texture unit
	C3D_TexInit(tex, width, height, GPU_RGBA8);

	// Convert image to 3DS tiled texture format
	C3D_SyncDisplayTransfer((u32*)gpusrc, GX_BUFFER_DIM(width, height), (u32*) tex->data, GX_BUFFER_DIM(width, height), TEXTURE_TRANSFER_FLAGS);

	C3D_TexSetFilter(tex, GPU_LINEAR, GPU_NEAREST);

	free(image);
	linearFree(gpusrc);
}
コード例 #3
0
ファイル: gpu.c プロジェクト: Chibiyima/ctrulib
void gpuFrameEnd(void)
{
	// Finish rendering
	GPU_FinishDrawing();
	GPUCMD_Finalize();
	GPUCMD_FlushAndRun(NULL);
	gspWaitForP3D(); // Wait for the rendering to complete

	// Transfer the GPU output to the framebuffer
	GX_SetDisplayTransfer(NULL, colorBuf, GX_BUFFER_DIM(240, 400),
		(u32*)gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL), GX_BUFFER_DIM(240, 400),
		DISPLAY_TRANSFER_FLAGS);
	gspWaitForPPF(); // Wait for the transfer to complete

	// Reset the command buffer
	GPUCMD_SetBufferOffset(0);
};
コード例 #4
0
ファイル: gfx_3ds.cpp プロジェクト: rychenga/GameYob
void gfxLoadBorder(u8* imgData, int imgWidth, int imgHeight) {
    if(imgData == NULL || (borderInit && (borderWidth != imgWidth || borderHeight != imgHeight))) {
        if(borderInit) {
            C3D_TexDelete(&borderTexture);
            borderInit = false;
        }

        borderWidth = 0;
        borderHeight = 0;
        gpuBorderWidth = 0;
        gpuBorderHeight = 0;

        if(imgData == NULL) {
            return;
        }
    }

    // Adjust the texture to power-of-two dimensions.
    borderWidth = imgWidth;
    borderHeight = imgHeight;
    gpuBorderWidth = (int) pow(2, ceil(log(borderWidth) / log(2)));
    gpuBorderHeight = (int) pow(2, ceil(log(borderHeight) / log(2)));

    // Create the texture.
    if(!borderInit && !C3D_TexInit(&borderTexture, gpuBorderWidth, gpuBorderHeight, GPU_RGBA8)) {
        return;
    }

    C3D_TexSetFilter(&borderTexture, GPU_LINEAR, GPU_LINEAR);

    // Copy the texture to a power-of-two sized buffer.
    u32* imgBuffer = (u32*) imgData;
    u32* temp = (u32*) linearAlloc(gpuBorderWidth * gpuBorderHeight * sizeof(u32));
    for(int x = 0; x < borderWidth; x++) {
        for(int y = 0; y < borderHeight; y++) {
            temp[y * gpuBorderWidth + x] = imgBuffer[y * borderWidth + x];
        }
    }

    GSPGPU_FlushDataCache(temp, gpuBorderWidth * gpuBorderHeight * sizeof(u32));
    if(R_SUCCEEDED(GX_DisplayTransfer(temp, (u32) GX_BUFFER_DIM(gpuBorderWidth, gpuBorderHeight), (u32*) borderTexture.data, (u32) GX_BUFFER_DIM(gpuBorderWidth, gpuBorderHeight), GX_TRANSFER_FLIP_VERT(1) | GX_TRANSFER_OUT_TILED(1) | GX_TRANSFER_RAW_COPY(0) | GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGBA8) | GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO)))) {
        gspWaitForPPF();
    }

    linearFree(temp);

    GSPGPU_InvalidateDataCache(borderTexture.data, borderTexture.size);

    borderInit = true;
}
コード例 #5
0
ファイル: sf2d.c プロジェクト: Voka/lpp-3ds
void sf2d_end_frame()
{
	GPU_FinishDrawing();
	GPUCMD_Finalize();
	GPUCMD_FlushAndRun();
	gspWaitForP3D();

	//Copy the GPU rendered FB to the screen FB
	if (cur_screen == GFX_TOP) {
		GX_DisplayTransfer(gpu_fb_addr, GX_BUFFER_DIM(240, 400),
			(u32 *)gfxGetFramebuffer(GFX_TOP, cur_side, NULL, NULL),
			GX_BUFFER_DIM(240, 400), 0x1000);
	} else {
		GX_DisplayTransfer(gpu_fb_addr, GX_BUFFER_DIM(240, 320),
			(u32 *)gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL),
			GX_BUFFER_DIM(240, 320), 0x1000);
	}
	gspWaitForPPF();

	//Clear the screen
	GX_MemoryFill(gpu_fb_addr, clear_color, &gpu_fb_addr[0x2EE00],
		0x201, gpu_depth_fb_addr, 0x00000000, &gpu_depth_fb_addr[0x2EE00], 0x201);
	gspWaitForPSC0();
}
コード例 #6
0
ファイル: main.c プロジェクト: Cruel/3ds-examples
//---------------------------------------------------------------------------------
static void sceneInit(void) {
//---------------------------------------------------------------------------------
	int i;

	// Load the vertex shader, create a shader program and bind it
	vshader_dvlb = DVLB_ParseFile((u32*)vshader_shbin, vshader_shbin_size);
	shaderProgramInit(&program);
	shaderProgramSetVsh(&program, &vshader_dvlb->DVLE[0]);
	C3D_BindProgram(&program);

	// Get the location of the uniforms
	uLoc_projection = shaderInstanceGetUniformLocation(program.vertexShader, "projection");

	// Configure attributes for use with the vertex shader
	// Attribute format and element count are ignored in immediate mode
	C3D_AttrInfo* attrInfo = C3D_GetAttrInfo();
	AttrInfo_Init(attrInfo);
	AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3); // v0=position
	AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 2); // v2=texcoord

	// Compute the projection matrix
	// Note: we're setting top to 240 here so origin is at top left.
	Mtx_OrthoTilt(&projection, 0.0, 400.0, 240.0, 0.0, 0.0, 1.0);

	// Configure buffers
	C3D_BufInfo* bufInfo = C3D_GetBufInfo();
	BufInfo_Init(bufInfo);

	unsigned char* image;
	unsigned width, height;

	lodepng_decode32(&image, &width, &height, ballsprites_png, ballsprites_png_size);

	u8 *gpusrc = linearAlloc(width*height*4);

	// GX_DisplayTransfer needs input buffer in linear RAM
	u8* src=image; u8 *dst=gpusrc;

	// lodepng outputs big endian rgba so we need to convert
	for(int i = 0; i<width*height; i++) {
		int r = *src++;
		int g = *src++;
		int b = *src++;
		int a = *src++;

		*dst++ = a;
		*dst++ = b;
		*dst++ = g;
		*dst++ = r;
	}

	// ensure data is in physical ram
	GSPGPU_FlushDataCache(gpusrc, width*height*4);

	// Load the texture and bind it to the first texture unit
	C3D_TexInit(&spritesheet_tex, width, height, GPU_RGBA8);

	// Convert image to 3DS tiled texture format
	C3D_SafeDisplayTransfer ((u32*)gpusrc, GX_BUFFER_DIM(width,height), (u32*)spritesheet_tex.data, GX_BUFFER_DIM(width,height), TEXTURE_TRANSFER_FLAGS);
	gspWaitForPPF();

	C3D_TexSetFilter(&spritesheet_tex, GPU_LINEAR, GPU_NEAREST);
	C3D_TexBind(0, &spritesheet_tex);

	free(image);
	linearFree(gpusrc);

	// Configure the first fragment shading substage to just pass through the texture color
	// See https://www.opengl.org/sdk/docs/man2/xhtml/glTexEnv.xml for more insight
	C3D_TexEnv* env = C3D_GetTexEnv(0);
	C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, 0, 0);
	C3D_TexEnvOp(env, C3D_Both, 0, 0, 0);
	C3D_TexEnvFunc(env, C3D_Both, GPU_REPLACE);

	srand(time(NULL));

	for(i = 0; i < NUM_SPRITES; i++) {
		//random place and speed
		sprites[i].x = (rand() % (400 - 32 )) << 8;
		sprites[i].y = (rand() % (240 - 32 )) << 8 ;
		sprites[i].dx = (rand() & 0xFF) + 0x100;
		sprites[i].dy = (rand() & 0xFF) + 0x100;
		sprites[i].image = rand() & 3;

		if(rand() & 1)
			sprites[i].dx = -sprites[i].dx;
		if(rand() & 1)
			sprites[i].dy = -sprites[i].dy;
	}

	// Configure depth test to overwrite pixels with the same depth (needed to draw overlapping sprites)
	C3D_DepthTest(true, GPU_GEQUAL, GPU_WRITE_ALL);
}
コード例 #7
0
ファイル: gfx_3ds.cpp プロジェクト: rychenga/GameYob
void gfxDrawScreen() {
    int screenTexSize = 256;
    u32* transferBuffer = screenBuffer;
    GPU_TEXTURE_FILTER_PARAM filter = GPU_NEAREST;

    if(scaleMode != 0 && scaleFilter != 0) {
        filter = GPU_LINEAR;

        if(scaleFilter == 2) {
            screenTexSize = 512;
            transferBuffer = scale2xBuffer;

            gfxScale2xRGBA8888(screenBuffer, 256, scale2xBuffer, 512, 256, 224);
        }
    }

    if(!screenInit || screenTexture.width != screenTexSize || screenTexture.height != screenTexSize) {
        if(screenInit) {
            C3D_TexDelete(&screenTexture);
            screenInit = false;
        }

        screenInit = C3D_TexInit(&screenTexture, screenTexSize, screenTexSize, GPU_RGBA8);
    }

    C3D_TexSetFilter(&screenTexture, filter, filter);

    GSPGPU_FlushDataCache(transferBuffer, screenTexSize * screenTexSize * sizeof(u32));
    if(R_SUCCEEDED(GX_DisplayTransfer(transferBuffer, (u32) GX_BUFFER_DIM(screenTexSize, screenTexSize), (u32*) screenTexture.data, (u32) GX_BUFFER_DIM(screenTexSize, screenTexSize), GX_TRANSFER_FLIP_VERT(1) | GX_TRANSFER_OUT_TILED(1) | GX_TRANSFER_RAW_COPY(0) | GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGBA8) | GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO)))) {
        gspWaitForPPF();
    }

    GSPGPU_InvalidateDataCache(screenTexture.data, screenTexture.size);

    if(!C3D_FrameBegin(0)) {
        return;
    }

    C3D_RenderTarget* target = gameScreen == 0 ? targetTop : targetBottom;

    C3D_FrameDrawOn(target);
    C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, shaderInstanceGetUniformLocation(program.vertexShader, "projection"), gameScreen == 0 ? &projectionTop : &projectionBottom);

    u16 viewportWidth = target->renderBuf.colorBuf.height;
    u16 viewportHeight = target->renderBuf.colorBuf.width;

    // Draw the screen.
    if(screenInit) {
        // Calculate the VBO dimensions.
        int screenWidth = 256;
        int screenHeight = 224;
        if(scaleMode == 1) {
            screenWidth *= 1.25f;
            screenHeight *= 1.25f;
        } else if(scaleMode == 2) {
            screenWidth *= 1.50f;
            screenHeight *= 1.50f;
        } else if(scaleMode == 3) {
            screenWidth *= viewportHeight / (float) screenHeight;
            screenHeight = viewportHeight;
        } else if(scaleMode == 4) {
            screenWidth = viewportWidth;
            screenHeight = viewportHeight;
        }

        // Calculate VBO points.
        const float x1 = ((int) viewportWidth - screenWidth) / 2.0f;
        const float y1 = ((int) viewportHeight - screenHeight) / 2.0f;
        const float x2 = x1 + screenWidth;
        const float y2 = y1 + screenHeight;

        static const float baseTX2 = 256.0f / 256.0f;
        static const float baseTY2 = 224.0f / 256.0f;
        static const float baseFilterMod = 0.25f / 256.0f;

        float tx2 = baseTX2;
        float ty2 = baseTY2;
        if(scaleMode != 0 && scaleFilter == 1) {
            tx2 -= baseFilterMod;
            ty2 -= baseFilterMod;
        }

        C3D_TexBind(0, &screenTexture);

        C3D_ImmDrawBegin(GPU_TRIANGLES);

        C3D_ImmSendAttrib(x1, y1, 0.5f, 0.0f);
        C3D_ImmSendAttrib(0, 0, 0.0f, 0.0f);

        C3D_ImmSendAttrib(x2, y2, 0.5f, 0.0f);
        C3D_ImmSendAttrib(tx2, ty2, 0.0f, 0.0f);

        C3D_ImmSendAttrib(x2, y1, 0.5f, 0.0f);
        C3D_ImmSendAttrib(tx2, 0, 0.0f, 0.0f);

        C3D_ImmSendAttrib(x1, y1, 0.5f, 0.0f);
        C3D_ImmSendAttrib(0, 0, 0.0f, 0.0f);

        C3D_ImmSendAttrib(x1, y2, 0.5f, 0.0f);
        C3D_ImmSendAttrib(0, ty2, 0.0f, 0.0f);

        C3D_ImmSendAttrib(x2, y2, 0.5f, 0.0f);
        C3D_ImmSendAttrib(tx2, ty2, 0.0f, 0.0f);

        C3D_ImmDrawEnd();
    }

    // Draw the border.
    if(borderInit && scaleMode != 4) {
        // Calculate VBO points.
        int scaledBorderWidth = borderWidth;
        int scaledBorderHeight = borderHeight;
        if(borderScaleMode == 1) {
            if(scaleMode == 1) {
                scaledBorderWidth *= 1.25f;
                scaledBorderHeight *= 1.25f;
            } else if(scaleMode == 2) {
                scaledBorderWidth *= 1.50f;
                scaledBorderHeight *= 1.50f;
            } else if(scaleMode == 3) {
                scaledBorderWidth *= viewportHeight / 224.0f;
                scaledBorderHeight *= viewportHeight / 224.0f;
            } else if(scaleMode == 4) {
                scaledBorderWidth *= viewportWidth / 256.0f;
                scaledBorderHeight *= viewportHeight / 224.0f;
            }
        }

        const float x1 = ((int) viewportWidth - scaledBorderWidth) / 2.0f;
        const float y1 = ((int) viewportHeight - scaledBorderHeight) / 2.0f;
        const float x2 = x1 + scaledBorderWidth;
        const float y2 = y1 + scaledBorderHeight;

        float tx2 = (float) borderWidth / (float) gpuBorderWidth;
        float ty2 = (float) borderHeight / (float) gpuBorderHeight;

        C3D_TexBind(0, &borderTexture);

        C3D_ImmDrawBegin(GPU_TRIANGLES);

        C3D_ImmSendAttrib(x1, y1, 0.5f, 0.0f);
        C3D_ImmSendAttrib(0, 0, 0.0f, 0.0f);

        C3D_ImmSendAttrib(x2, y2, 0.5f, 0.0f);
        C3D_ImmSendAttrib(tx2, ty2, 0.0f, 0.0f);

        C3D_ImmSendAttrib(x2, y1, 0.5f, 0.0f);
        C3D_ImmSendAttrib(tx2, 0, 0.0f, 0.0f);

        C3D_ImmSendAttrib(x1, y1, 0.5f, 0.0f);
        C3D_ImmSendAttrib(0, 0, 0.0f, 0.0f);

        C3D_ImmSendAttrib(x1, y2, 0.5f, 0.0f);
        C3D_ImmSendAttrib(0, ty2, 0.0f, 0.0f);

        C3D_ImmSendAttrib(x2, y2, 0.5f, 0.0f);
        C3D_ImmSendAttrib(tx2, ty2, 0.0f, 0.0f);

        C3D_ImmDrawEnd();
    }

    C3D_FrameEnd(0);
}
コード例 #8
0
ファイル: main.c プロジェクト: yuriks/mgba
static void _setup(struct GBAGUIRunner* runner) {
	struct GBAOptions opts = {
		.useBios = true,
		.logLevel = 0,
		.idleOptimization = IDLE_LOOP_DETECT
	};
	GBAConfigLoadDefaults(&runner->context.config, &opts);
	runner->context.gba->logHandler = GBA3DSLog;
	runner->context.gba->rotationSource = &rotation.d;
	if (hasSound) {
		runner->context.gba->stream = &stream;
	}

	GBAVideoSoftwareRendererCreate(&renderer);
	renderer.outputBuffer = linearAlloc(256 * VIDEO_VERTICAL_PIXELS * 2);
	renderer.outputBufferStride = 256;
	runner->context.renderer = &renderer.d;

	GBAAudioResizeBuffer(&runner->context.gba->audio, AUDIO_SAMPLES);
}

static void _gameLoaded(struct GBAGUIRunner* runner) {
	if (runner->context.gba->memory.hw.devices & HW_TILT) {
		HIDUSER_EnableAccelerometer();
	}
	if (runner->context.gba->memory.hw.devices & HW_GYRO) {
		HIDUSER_EnableGyroscope();
	}

#if RESAMPLE_LIBRARY == RESAMPLE_BLIP_BUF
	double ratio = GBAAudioCalculateRatio(1, 60, 1);
	blip_set_rates(runner->context.gba->audio.left,  GBA_ARM7TDMI_FREQUENCY, 0x8000 * ratio);
	blip_set_rates(runner->context.gba->audio.right, GBA_ARM7TDMI_FREQUENCY, 0x8000 * ratio);
#endif
	if (hasSound) {
		memset(audioLeft, 0, AUDIO_SAMPLES * sizeof(int16_t));
		memset(audioRight, 0, AUDIO_SAMPLES * sizeof(int16_t));
	}
}

static void _gameUnloaded(struct GBAGUIRunner* runner) {
	if (hasSound) {
		CSND_SetPlayState(8, 0);
		CSND_SetPlayState(9, 0);
		csndExecCmds(false);
	}

	if (runner->context.gba->memory.hw.devices & HW_TILT) {
		HIDUSER_DisableAccelerometer();
	}
	if (runner->context.gba->memory.hw.devices & HW_GYRO) {
		HIDUSER_DisableGyroscope();
	}
}

static void _drawFrame(struct GBAGUIRunner* runner, bool faded) {
	GX_SetDisplayTransfer(0, renderer.outputBuffer, GX_BUFFER_DIM(256, VIDEO_VERTICAL_PIXELS), tex->data, GX_BUFFER_DIM(256, VIDEO_VERTICAL_PIXELS), 0x000002202);
	GSPGPU_FlushDataCache(0, tex->data, 256 * VIDEO_VERTICAL_PIXELS * 2);
#if RESAMPLE_LIBRARY == RESAMPLE_BLIP_BUF
	if (!hasSound) {
		blip_clear(runner->context.gba->audio.left);
		blip_clear(runner->context.gba->audio.right);
	}
#endif
	gspWaitForPPF();
	_drawStart();
	sf2d_draw_texture_scale_blend(tex, 40, 296, 1, -1, 0xFFFFFF3F | (faded ? 0 : 0xC0));
	_drawEnd();
}