Rumah > pembangunan bahagian belakang > Golang > Golang pada PSP (dan bahasa lain)

Golang pada PSP (dan bahasa lain)

Linda Hamilton
Lepaskan: 2025-01-03 12:33:43
asal
1026 orang telah melayarinya

Saya memutuskan untuk mencuba menggunakan Golang pada PSP dan meneroka beberapa pendekatan, termasuk mengalihkan Clang, menggunakan TinyGo dan menyusun Golang ke JavaScript dengan GopherJS. Kemudian, saya terjumpa pengguna bernama aethiopicuschan pada PSP homebrew Discord, yang mencuba matlamat yang sama menggunakan WebAssembly. Contoh beliau berfungsi pada PPSSPP tetapi bukan pada perkakasan sebenar.

Apa pun, saya terpaksa menangguhkan projek saya kerana peperiksaan akan datang. Tetapi, beberapa bulan kemudian, saya menemui artikel di mana aethiopicuschan berjaya menyusun Golang ke WASM dan menjalankannya pada PSP menggunakan penterjemah WASM.
Pendekatannya menggunakan penterjemah Wasm yang dipanggil Wasm3 untuk menjalankan kod, tetapi saya tahu saya boleh melakukan yang lebih baik. Saya tahu tentang projek seperti Wasm2C yang menukar binari Wasm anda kepada C.
Teruja, saya mendalami topik ini dan menemui artikel tentang menyusun WebAssembly kepada kod C mudah alih. Mereka menggunakan pengkompil dipanggil w2c2, yang saya rasa adalah sekuelnya.

Selepas berjam-jam bermain-main dengan CMake, saya berjaya mencipta contoh yang berkesan menggunakan TinyGo dan menyasarkan WASI. Saya juga membungkus fungsi raylib, InitWindow (psp mempunyai port raylib), dengan matlamat mengalihkan pengikatan raylib-go ke platform WASM-to-C ini. Contoh berjaya mengikat fungsi C InitWindow kepada kod WASM yang disusun.

Seperti yang anda lihat, ia kelihatan seperti mana-mana kod golang lain

package main

import "time"

import rl "github.com/gen2brain/raylib-go/raylib"

func main() {

    rl.InitWindow(480, 272, "Psp test")
    for {
        time.Sleep(time.Millisecond * 16)
    }
}
Salin selepas log masuk

tetapi dalam pakej rl, kami mengimport fungsi C, kami memberikannya tandatangan fungsi juga. Ingatlah.


package rl

//go:wasmimport rl InitWindow
func c_InitWindow(width int32, height int32, title string)

// InitWindow - Initialize Window and OpenGL Graphics

func InitWindow(width int32, height int32, title string) {
    c_InitWindow(width, height, title)
}
Salin selepas log masuk

mari pecahkan kod ini langkah demi langkah.

#define __GLIBC_USE

#include <raylib.h>
#include <stdio.h>
#include <time.h>

#include <pspkernel.h>
PSP_MODULE_INFO("WasiExample", 0, 1, 0);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER);
#include "pspdebug.h"
#define printf pspDebugScreenPrintf

Salin selepas log masuk

mula-mula kami mengimport perpustakaan psp, dan menyediakan plat dandang, kami juga mengimport port raylib

di sini kami mengimport apl modul yang disusun.h
kami juga mengimport "runtime" wasi yang disediakan oleh w2c2

// // the compiled wasm -> C code
#include "app.h"
// // wasi runtime
#include "w2c2_base.h"
#include "wasi.h"

extern wasmMemory* e_memory;  // the WASM memory.
void trap(Trap trap)
{
  fprintf(stderr, "TRAP: %s\n", trapDescription(trap));
  abort();
}

wasmMemory* wasiMemory(void* instance)
{
  return app_memory((appInstance*)instance);
}
extern char** environ;

Salin selepas log masuk

Fungsi perangkap ialah plat dandang,
fungsi wasiMemory ialah fungsi pembantu yang saya buat untuk fungsi pembantu yang lain

char* getCStringFromMemory(void* memoryptr, U32 offset, U32 length)
{
  wasmMemory* memory = wasiMemory(memoryptr);
  char* str = (char*)(memory->data + offset);
  char* result = (char*)malloc(
    length + 1);  // Allocate space for the string + null terminator
  if (result == NULL) {
    fprintf(stderr, "Memory allocation failed\n");
    return NULL;
  }

  // Copy the string from WASI memory to local memory
  for (U32 i = 0; i < length; ++i) {
    result[i] = str[i];
  }
  result[length] = '<pre class="brush:php;toolbar:false">void rl__InitWindow(
  void* memoryptr, U32 width, U32 height, U32 offset, U32 length)
{
  char* title = getCStringFromMemory(memoryptr, offset, length);
  InitWindow(width, height, title);
  bool ready = IsWindowReady();
  if (ready) {
    // this will print to the psp screen.
    printf("Window was created");
  }
}

Salin selepas log masuk
'; // Null-terminate the string return result; }

semua fungsi ini lakukan ialah ia mengambil penuding memori untuk penuding memori rentetan (dalam wasm kita mengendalikan rentetan dengan menghantar offset memori, dan panjang rentetan), dan mengembalikan rentetan C menggunakan ofset dan panjang

ini ialah fungsi C yang kami panggil dari kod golang kami, saya terpaksa mentakrifkannya sendiri.

int main(int argc, char* argv[])
{
  pspDebugScreenInit();
  appInstance i;
  appInstantiate(&i, NULL);
  if (!wasiInit(argc, argv, environ)) {
    fprintf(stderr, "failed to initialize WASI\n");
    return 1;
  }

  app__start(&i);
  appFreeInstance(&i);
  return 0;
}
Salin selepas log masuk

kami sedang membaca args yang dilalui oleh wasm yang ditranspilkan, dan menyampaikannya kepada raylib.


ini adalah beberapa lagi boilerplate, yang kami lakukan hanyalah menjalankan fungsi utama kod golang, yang dieksport sebagai app_start()

Golang on PSP (and other languages)

ia berfungsi!

Ini ialah tangkapan skrin psp ?emulator?.
tetapi ia juga berfungsi pada perkakasan asal.

Tinggalkan sebarang soalan di ruangan komen!

Atas ialah kandungan terperinci Golang pada PSP (dan bahasa lain). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan