Author Topic: [TEST RESULT] Test port of RetroArch running on gcw0  (Read 21591 times)

BlockABoots

  • Posts: 131
Re: [TEST RESULT] Test port of RetroArch running on gcw0
« Reply #40 on: November 09, 2013, 05:19:37 pm »
Sorry ment the GPU clock

"set GPU clock to 500 MHz (was 432 MHz)"

deBeauharnais

  • Posts: 30
Re: [TEST RESULT] Test port of RetroArch running on gcw0
« Reply #41 on: June 22, 2014, 09:42:39 pm »
Any update about retroarch, guys?

Malleus

  • Posts: 67
Re: [TEST RESULT] Test port of RetroArch running on gcw0
« Reply #42 on: June 23, 2014, 08:44:56 am »
yes, would be interesting to know if tripplebuffering helps any for example   :)

forphucksakes

  • Posts: 71
Re: [TEST RESULT] Test port of RetroArch running on gcw0
« Reply #43 on: December 06, 2014, 04:43:27 pm »
^bump
forphucksakes

iesposta

  • Posts: 7
Re: [TEST RESULT] Test port of RetroArch running on gcw0
« Reply #44 on: January 10, 2015, 07:15:55 pm »
Any update about retroarch, guys?

+1 for Retroarch OR update Stella 2600!

Nebuleon

  • Guest
Re: [TEST RESULT] Test port of RetroArch running on gcw0
« Reply #45 on: January 10, 2015, 08:45:02 pm »
+1 for Retroarch OR update Stella 2600!
Stella 2600 is out of the scope of this thread. Please talk about that on the Stella thread.

Kivutar

  • Posts: 1
Re: [TEST RESULT] Test port of RetroArch running on gcw0
« Reply #46 on: December 04, 2015, 06:48:25 pm »
I added a vivante_fbdev context driver in retroarch one year ago. It is based on the mali_fbdev by maister.

You need to configure with --enable-gles --disable-kms --enable-vivante_fbdev

It has been tested extensively on Vivante GC2000, and may work on Vivante GC800.

You should try it on gcw0 :)

Radioboy86

  • Posts: 270
Re: [TEST RESULT] Test port of RetroArch running on gcw0
« Reply #47 on: December 07, 2015, 02:55:12 am »
Hey guys any chance i could get help on porting this to the a320 owners Opendingux?

Soruce code? Can you guys compile it? I am very dumb at this. i try and i try and... I fail :D


the_gama (OP)

  • Posts: 155
Re: [TEST RESULT] Test port of RetroArch running on gcw0
« Reply #48 on: February 08, 2016, 06:06:05 pm »
Hi, I would like to make a new build of retroarch for the gcw0.

I wrote a gfx context driver based on the vivante_fbdev driver.  But I get the following error during build:

Code: [Select]
/opt/gcw0-toolchain/usr/lib/gcc/mipsel-gcw0-linux-uclibc/4.9.1/../../../../mipsel-gcw0-linux-uclibc/bin/ld: obj-unix/input/drivers/udev_input.o: undefined reference to symbol '[email protected]@LIBUDEV_183'
/opt/gcw0-toolchain/usr/lib/gcc/mipsel-gcw0-linux-uclibc/4.9.1/../../../../mipsel-gcw0-linux-uclibc/bin/ld: note: '[email protected]@LIBUDEV_183' is defined in DSO /opt/gcw0-toolchain/usr/mipsel-gcw0-linux-uclibc/sysroot/lib/libudev.so.1 so try adding it to the linker command line
/opt/gcw0-toolchain/usr/mipsel-gcw0-linux-uclibc/sysroot/lib/libudev.so.1: could not read symbols: Invalid operation
collect2: error: ld returned 1 exit status

I run configure with the following commands:

Code: [Select]
export PATH=$PATH:/opt/gcw0-toolchain/usr/bin:/opt/gcw0-toolchain/usr/mipsel-gcw0-linux-uclibc/sysroot/usr/bin
then

Code: [Select]
./configure --host=mipsel-gcw0-linux-uclibc --prefix=/tmp --enable-gles --disable-kms --enable-opendingux_fbdev --enable-alsa --with-gles_libs="-lGLESv2 -lEGL"

Anyone knows what causes the error?

By the way, does anyone have a more recent toolchain?  The official link is from 2014.

David Knight

  • Posts: 577
Re: [TEST RESULT] Test port of RetroArch running on gcw0
« Reply #49 on: February 08, 2016, 06:20:14 pm »
Code: [Select]
/opt/gcw0-toolchain/usr/lib/gcc/mipsel-gcw0-linux-uclibc/4.9.1/../../../../mipsel-gcw0-linux-uclibc/bin/ld: obj-unix/input/drivers/udev_input.o: undefined reference to symbol '[email protected]@LIBUDEV_183'
/opt/gcw0-toolchain/usr/lib/gcc/mipsel-gcw0-linux-uclibc/4.9.1/../../../../mipsel-gcw0-linux-uclibc/bin/ld: note: '[email protected]@LIBUDEV_183' is defined in DSO /opt/gcw0-toolchain/usr/mipsel-gcw0-linux-uclibc/sysroot/lib/libudev.so.1 so try adding it to the linker command line
/opt/gcw0-toolchain/usr/mipsel-gcw0-linux-uclibc/sysroot/lib/libudev.so.1: could not read symbols: Invalid operation
collect2: error: ld returned 1 exit status
As the error message states this is a linking error, have you tried adding "-ludev"?

the_gama (OP)

  • Posts: 155
Re: [TEST RESULT] Test port of RetroArch running on gcw0
« Reply #50 on: February 08, 2016, 07:44:44 pm »
Thanks David, RetroArch's autoconf file uses pkg-config to automatically add library dependencies.

Do you know how do I set pkg-config enviroment variables?

Quickman

  • Posts: 220
Re: [TEST RESULT] Test port of RetroArch running on gcw0
« Reply #51 on: February 08, 2016, 11:48:30 pm »
@the_gama  at the beginning of your post you stated, "My main interest was having accurate and fast snes emulation on the console."

 I'm curious, what your reasoning for porting RA would be at this point? Unless I'm completely mistaken (which is possible because I literally just got a GCW zero) I was made to believe the SNES emulation was running really well.

 Either way, thank you so much for your creativity and hard work! I'm always curious to see what people are building on and creating! Thank you

the_gama (OP)

  • Posts: 155
Re: [TEST RESULT] Test port of RetroArch running on gcw0
« Reply #52 on: February 10, 2016, 06:37:55 pm »
@the_gama  at the beginning of your post you stated, "My main interest was having accurate and fast snes emulation on the console."

Well, I wrote that back in 2013 :).  Only a few emulators were released by then, and I wanted to try retroarch and specially the snes cores on the zero. 

I only port stuff as a hobby, and I am a huge fan of retroarch.  Those are the only reasons to try it now :).



the_gama (OP)

  • Posts: 155
Re: [TEST RESULT] Test port of RetroArch running on gcw0
« Reply #53 on: February 10, 2016, 06:58:08 pm »
Ok, I managed to built the latest revision of retroarch yesterday, and I am testing the different features available from the RGUI menu. 

I tested the network option to download assets and stuff, but unfortunately there is a connection error.
I looked through the code and found an small application to test the network connection used by retroarch.

These are the two main files,

Code: [Select]
#include <stdio.h>
#include <net/net_http.h>
#include <net/net_compat.h>

#ifdef _WIN32
#include <winsock2.h>
#endif

int main(void)
{
   char   *data;
   struct http_t *http1 = NULL, *http3 = NULL;
   struct http_connection_t *conn1 = NULL, *conn3 = NULL;
   size_t len, pos = 0, tot = 0;

   fprintf(stderr, "http_test: network_init()\n");
   if (!network_init())
      return -1;

   fprintf(stderr, "http_test: net_http_connection_new()\n");
   conn1 = net_http_connection_new("http://buildbot.libretro.com/nightly/win-x86/latest/mednafen_psx_libretro.dll.zip");
   if (!conn1)
      goto error;

   while (!net_http_connection_iterate(conn1)) {}
   if (!net_http_connection_done(conn1))
   {
      fprintf(stderr, "http_test: malformed url\n");
      goto error;
   }

   fprintf(stderr, "http_test: net_http_new()\n");
   http1 = net_http_new(conn1);
   if (!http1)
      goto error;

   fprintf(stderr, "http_test: net_http_update()\n");
   while (!net_http_update(http1, &pos, &tot))
      fprintf(stderr, "%.9lu / %.9lu        \r",pos,tot);

   conn3 = net_http_connection_new("http://www.wikipedia.org/");
   if (!conn3)
      goto error;

   while (!net_http_connection_iterate(conn3)) {}
   if (!net_http_connection_done(conn3))
   {
      fprintf(stderr, "http_test: malformed url\n");
      goto error;
   }

   http3 = net_http_new(conn3);
   if (!http3)
      goto error;
   
   while (!net_http_update(http3, NULL, NULL)) {}

   data  = (char*)net_http_data(http3, &len, false);

   fprintf(stderr, "%.*s\n", (int)256, data);

error:
   if ( http1 )
      net_http_delete( http1 );

   if ( conn1 )
      net_http_connection_free( conn1 );

   if ( http3 )
      net_http_delete( http3 );

   if ( conn3 )
      net_http_connection_free( conn3 );

   
   network_deinit();

   return 0;
}

Code: [Select]
/*  RetroArch - A frontend for libretro.
 *  Copyright (C) 2011-2015 - Daniel De Matteis
 *  Copyright (C) 2014-2015 - Alfred Agrell
 *
 *  RetroArch is free software: you can redistribute it and/or modify it under the terms
 *  of the GNU General Public License as published by the Free Software Found-
 *  ation, either version 3 of the License, or (at your option) any later version.
 *
 *  RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 *  PURPOSE.  See the GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along with RetroArch.
 *  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#include <net/net_http.h>
#include <net/net_compat.h>
#include <compat/strl.h>

enum
{
   P_HEADER_TOP = 0,
   P_HEADER,
   P_BODY,
   P_BODY_CHUNKLEN,
   P_DONE,
   P_ERROR
};

enum
{
   T_FULL = 0,
   T_LEN,
   T_CHUNK
};

struct http_t
{
int fd;
int status;

char part;
char bodytype;
bool error;

size_t pos;
size_t len;
size_t buflen;
char * data;
};

struct http_connection_t
{
   char *domain;
   char *location;
   char *urlcopy;
   char *scan;
   int port;
};


static int net_http_new_socket(const char *domain, int port)
{
   int fd;
#ifndef _WIN32
#ifndef VITA
   struct timeval timeout;
#endif
#endif
   struct addrinfo hints, *addr = NULL;
   char portstr[16] = {0};
   
   /* Initialize the network. */
   if (!network_init())
      return -1;

   snprintf(portstr, sizeof(portstr), "%i", port);

   memset(&hints, 0, sizeof(hints));
   hints.ai_family   = AF_UNSPEC;
   hints.ai_socktype = SOCK_STREAM;
   hints.ai_flags    = 0;
   
   if (getaddrinfo_retro(domain, portstr, &hints, &addr) < 0)
      return -1;
   if (!addr)
      return -1;

   fd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);

#ifndef _WIN32
#ifndef VITA
   timeout.tv_sec=4;
   timeout.tv_usec=0;
   setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof timeout);
#endif
#endif
   if (connect(fd, addr->ai_addr, addr->ai_addrlen) != 0)
   {
      freeaddrinfo_retro(addr);
      socket_close(fd);
      return -1;
   }

   freeaddrinfo_retro(addr);

   if (!socket_nonblock(fd))
   {
      socket_close(fd);
      return -1;
   }

   return fd;
}

static void net_http_send(int fd, bool * error,
      const char * data, size_t len)
{
   if (*error)
      return;

   while (len)
   {
      ssize_t thislen = send(fd, data, len, MSG_NOSIGNAL);

      if (thislen <= 0)
      {
         if (!isagain(thislen))
            continue;

         *error=true;
         return;
      }

      data += thislen;
      len  -= thislen;
   }
}

static void net_http_send_str(int fd, bool *error, const char *text)
{
   net_http_send(fd, error, text, strlen(text));
}

static ssize_t net_http_recv(int fd, bool *error,
      uint8_t *data, size_t maxlen)
{
   ssize_t bytes;

   if (*error)
      return -1;

   bytes = recv(fd, (char*)data, maxlen, 0);

   if (bytes > 0)
      return bytes;
   else if (bytes == 0)
      return -1;
   else if (isagain(bytes))
      return 0;

   *error=true;
   return -1;
}

struct http_connection_t *net_http_connection_new(const char *url)
{
   size_t length;
   char **domain = NULL;
   struct http_connection_t *conn = (struct http_connection_t*)calloc(1,
         sizeof(struct http_connection_t));

   if (!conn)
      return NULL;

   length             = strlen(url) + 1;
   conn->urlcopy      = (char*)malloc(length);

   if (!conn->urlcopy)
      goto error;

   strlcpy(conn->urlcopy, url, length);

   if (strncmp(url, "http://", strlen("http://")) != 0)
      goto error;

   conn->scan    = conn->urlcopy + strlen("http://");

   domain        = &conn->domain;

   *domain = conn->scan;

   return conn;

error:
   if (conn->urlcopy)
      free(conn->urlcopy);
   conn->urlcopy = NULL;
   free(conn);
   return NULL;
}

bool net_http_connection_iterate(struct http_connection_t *conn)
{
   if (!conn)
      return false;
   if (*conn->scan != '/' && *conn->scan != ':' && *conn->scan != '\0')
   {
      conn->scan++;
      return false;
   }
   return true;
}

bool net_http_connection_done(struct http_connection_t *conn)
{
   char **location = NULL;

   if (!conn)
      return false;

   location = &conn->location;

   if (*conn->scan == '\0')
      return false;

   *conn->scan   = '\0';
   conn->port   = 80;

   if (*conn->scan == ':')
   {

      if (!isdigit((int)conn->scan[1]))
         return false;

      conn->port = strtoul(conn->scan + 1, &conn->scan, 10);

      if (*conn->scan != '/')
         return false;
   }

   *location = conn->scan + 1;

   return true;
}

void net_http_connection_free(struct http_connection_t *conn)
{
   if (!conn)
      return;

   if (conn->urlcopy)
      free(conn->urlcopy);

   free(conn);
}

const char *net_http_connection_url(struct http_connection_t *conn)
{
   return conn->urlcopy;
}

struct http_t *net_http_new(struct http_connection_t *conn)
{
   bool error;
   int fd = -1;
   struct http_t *state      = NULL;

   if (!conn)
      goto error;

   fd = net_http_new_socket(conn->domain, conn->port);
   if (fd == -1)
      goto error;

   error=false;

   /* This is a bit lazy, but it works. */
   net_http_send_str(fd, &error, "GET /");
   net_http_send_str(fd, &error, conn->location);
   net_http_send_str(fd, &error, " HTTP/1.1\r\n");

   net_http_send_str(fd, &error, "Host: ");
   net_http_send_str(fd, &error, conn->domain);

   if (conn->port != 80)
   {
      char portstr[16] = {0};

      snprintf(portstr, sizeof(portstr), ":%i", conn->port);
      net_http_send_str(fd, &error, portstr);
   }

   net_http_send_str(fd, &error, "\r\n");
   net_http_send_str(fd, &error, "Connection: close\r\n");
   net_http_send_str(fd, &error, "\r\n");

   if (error)
      goto error;

   state          = (struct http_t*)malloc(sizeof(struct http_t));
   state->fd      = fd;
   state->status  = -1;
   state->data    = NULL;
   state->part    = P_HEADER_TOP;
   state->bodytype= T_FULL;
   state->error   = false;
   state->pos     = 0;
   state->len     = 0;
   state->buflen  = 512;
   state->data    = (char*)malloc(state->buflen);

   if (!state->data)
      goto error;

   return state;

error:
   if (fd != -1)
      socket_close(fd);
   return NULL;
}

int net_http_fd(struct http_t *state)
{
   if (!state)
      return 0;
   return state->fd;
}

bool net_http_update(struct http_t *state, size_t* progress, size_t* total)
{
   ssize_t newlen = 0;

   if (!state || state->error)
      goto fail;

   if (state->part < P_BODY)
   {
      newlen = net_http_recv(state->fd, &state->error,
            (uint8_t*)state->data + state->pos, state->buflen - state->pos);

      if (newlen < 0)
         goto fail;

      if (state->pos + newlen >= state->buflen - 64)
      {
         state->buflen *= 2;
         state->data = (char*)realloc(state->data, state->buflen);
      }
      state->pos += newlen;

      while (state->part < P_BODY)
      {
         char *dataend = state->data + state->pos;
         char *lineend = (char*)memchr(state->data, '\n', state->pos);

         if (!lineend)
            break;
         *lineend='\0';
         if (lineend != state->data && lineend[-1]=='\r')
            lineend[-1]='\0';

         if (state->part == P_HEADER_TOP)
         {
            if (strncmp(state->data, "HTTP/1.", strlen("HTTP/1."))!=0)
               goto fail;
            state->status = strtoul(state->data + strlen("HTTP/1.1 "), NULL, 10);
            state->part   = P_HEADER;
         }
         else
         {
            if (!strncmp(state->data, "Content-Length: ",
                     strlen("Content-Length: ")))
            {
               state->bodytype = T_LEN;
               state->len = strtol(state->data +
                     strlen("Content-Length: "), NULL, 10);
            }
            if (!strcmp(state->data, "Transfer-Encoding: chunked"))
               state->bodytype = T_CHUNK;

            /* TODO: save headers somewhere */
            if (state->data[0]=='\0')
            {
               state->part = P_BODY;
               if (state->bodytype == T_CHUNK)
                  state->part = P_BODY_CHUNKLEN;
            }
         }

         memmove(state->data, lineend + 1, dataend-(lineend+1));
         state->pos = (dataend-(lineend + 1));
      }
      if (state->part >= P_BODY)
      {
         newlen = state->pos;
         state->pos = 0;
      }
   }

   if (state->part >= P_BODY && state->part < P_DONE)
   {
      if (!newlen)
      {
         newlen = net_http_recv(state->fd, &state->error,
               (uint8_t*)state->data + state->pos,
               state->buflen - state->pos);

         if (newlen < 0)
         {
            if (state->bodytype == T_FULL)
            {
               state->part = P_DONE;
               state->data = (char*)realloc(state->data, state->len);
            }
            else
               goto fail;
            newlen=0;
         }

         if (state->pos + newlen >= state->buflen - 64)
         {
            state->buflen *= 2;
            state->data = (char*)realloc(state->data, state->buflen);
         }
      }

parse_again:
      if (state->bodytype == T_CHUNK)
      {
         if (state->part == P_BODY_CHUNKLEN)
         {
            state->pos += newlen;
            if (state->pos - state->len >= 2)
            {
               /*
                * len=start of chunk including \r\n
                * pos=end of data
                */

               char *fullend = state->data + state->pos;
               char *end     = (char*)memchr(state->data + state->len + 2,
                     '\n', state->pos - state->len - 2);

               if (end)
               {
                  size_t chunklen = strtoul(state->data+state->len, NULL, 16);
                  state->pos      = state->len;
                  end++;

                  memmove(state->data+state->len, end, fullend-end);

                  state->len      = chunklen;
                  newlen          = (fullend - end);

                  /*
                     len=num bytes
                     newlen=unparsed bytes after \n
                     pos=start of chunk including \r\n
                     */

                  state->part = P_BODY;
                  if (state->len == 0)
                  {
                     state->part = P_DONE;
                     state->len  = state->pos;
                     state->data = (char*)realloc(state->data, state->len);
                  }
                  goto parse_again;
               }
            }
         }
         else if (state->part == P_BODY)
         {
            if ((size_t)newlen >= state->len)
            {
               state->pos += state->len;
               newlen     -= state->len;
               state->len  = state->pos;
               state->part = P_BODY_CHUNKLEN;
               goto parse_again;
            }
            else
            {
               state->pos += newlen;
               state->len -= newlen;
            }
         }
      }
      else
      {
         state->pos += newlen;

         if (state->pos == state->len)
         {
            state->part = P_DONE;
            state->data = (char*)realloc(state->data, state->len);
         }
         if (state->pos > state->len)
            goto fail;
      }
   }

   if (progress)
      *progress = state->pos;

   if (total)
   {
      if (state->bodytype == T_LEN)
         *total=state->len;
      else
         *total=0;
   }

   return (state->part == P_DONE);

fail:
   if (state)
   {
      state->error  = true;
      state->part   = P_ERROR;
      state->status = -1;
   }

   return true;
}

int net_http_status(struct http_t *state)
{
   if (state)
      return state->status;
   return -1;
}

uint8_t* net_http_data(struct http_t *state, size_t* len, bool accept_error)
{
   if (!state)
      return NULL;

   if (!accept_error && net_http_error(state))
   {
      if (len)
         *len=0;
      return NULL;
   }

   if (len)
      *len=state->len;

   return (uint8_t*)state->data;
}

void net_http_delete(struct http_t *state)
{
   if (!state)
      return;

   if (state->fd != -1)
      socket_close(state->fd);
   free(state);
}

bool net_http_error(struct http_t *state)
{
   return (state->error || state->status<200 || state->status>299);
}

Failure occurs on line 103 of the second file: if (connect(fd, addr->ai_addr, addr->ai_addrlen) != 0)

Can anyone help me to find what could be causing this failure?
I can post all the files to build the sample test if you would like.

Quickman

  • Posts: 220
Re: [TEST RESULT] Test port of RetroArch running on gcw0
« Reply #54 on: February 10, 2016, 07:15:53 pm »
@the_gama  at the beginning of your post you stated, "My main interest was having accurate and fast snes emulation on the console."

Well, I wrote that back in 2013 :).  Only a few emulators were released by then, and I wanted to try retroarch and specially the snes cores on the zero. 

I only port stuff as a hobby, and I am a huge fan of retroarch.  Those are the only reasons to try it now :).

@the_gama that's awesome. Passion projects are the best! Thanks for your hard work and I look forward to seeing all the updates! Also, thank you so much for your response. :D
I'll stay tuned :)

gameblabla

  • Posts: 1364
Re: [TEST RESULT] Test port of RetroArch running on gcw0
« Reply #55 on: February 10, 2016, 09:55:04 pm »
Failure occurs on line 103 of the second file: if (connect(fd, addr->ai_addr, addr->ai_addrlen) != 0)
Can anyone help me to find what could be causing this failure?
I can post all the files to build the sample test if you would like.
Could you please tell us how you compiled Retroarch ?
Because last time i tried, i got a non-working executable. (it was not even bringing up the RGUI)

the_gama (OP)

  • Posts: 155
Re: [TEST RESULT] Test port of RetroArch running on gcw0
« Reply #56 on: February 11, 2016, 01:48:14 am »
Could you please tell us how you compiled Retroarch ?
Because last time i tried, i got a non-working executable. (it was not even bringing up the RGUI)

Yes, of course.  All that is needed is a gfx_context_driver to use the gles video driver, autoconf and pkg-config takes care of everything else.  I will post all the steps to build it, I just need to prepare a patch with the changes.

 

Post a new topic
Post a new topic