initial Nintendo 64 support

This commit is contained in:
psxdev 2024-03-30 21:40:19 +01:00
parent f004011fd2
commit a04921ab32
7 changed files with 849 additions and 24 deletions

View File

@ -22,6 +22,8 @@
# - Android (ARM, ARM64) # - Android (ARM, ARM64)
# > PLATFORM_DREAMCAST: # > PLATFORM_DREAMCAST:
# - Sega Dreamcast (SH4) # - Sega Dreamcast (SH4)
# > PLATFORM_NINTENDO64:
# - Nintendo 64 (MIPS4300)
# #
# Many thanks to Milan Nikolic (@gen2brain) for implementing Android platform pipeline. # Many thanks to Milan Nikolic (@gen2brain) for implementing Android platform pipeline.
# Many thanks to Emanuele Petriglia for his contribution on GNU/Linux pipeline. # Many thanks to Emanuele Petriglia for his contribution on GNU/Linux pipeline.
@ -52,7 +54,7 @@
# Define required environment variables # Define required environment variables
#------------------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------------------
# Define target platform: PLATFORM_DESKTOP, PLATFORM_DRM, PLATFORM_ANDROID, PLATFORM_WEB, PLATFORM_DREAMCAST # Define target platform: PLATFORM_DESKTOP, PLATFORM_DRM, PLATFORM_ANDROID, PLATFORM_WEB, PLATFORM_DREAMCAST, PLATFORM_NINTENDO64
PLATFORM ?= PLATFORM_DREAMCAST PLATFORM ?= PLATFORM_DREAMCAST
# Define required raylib variables # Define required raylib variables
@ -224,6 +226,12 @@ ifeq ($(PLATFORM),PLATFORM_DREAMCAST)
PLATFORM_SHELL = sh PLATFORM_SHELL = sh
endif endif
#Nintendo64
ifeq ($(PLATFORM),PLATFORM_NINTENDO64)
PLATFORM_OS = NINTENDO64
PLATFORM_SHELL = sh
endif
# Define raylib graphics api depending on selected platform # Define raylib graphics api depending on selected platform
ifeq ($(PLATFORM),PLATFORM_DESKTOP) ifeq ($(PLATFORM),PLATFORM_DESKTOP)
# By default use OpenGL 3.3 on desktop platforms # By default use OpenGL 3.3 on desktop platforms
@ -255,6 +263,12 @@ ifeq ($(PLATFORM),PLATFORM_DREAMCAST)
# By default use OpenGL 1.1 on DREAMCAST # By default use OpenGL 1.1 on DREAMCAST
GRAPHICS = GRAPHICS_API_OPENGL_11 GRAPHICS = GRAPHICS_API_OPENGL_11
endif endif
ifeq ($(PLATFORM),PLATFORM_NINTENDO64)
# By default use OpenGL 1.1 on NINTENDO64
GRAPHICS = GRAPHICS_API_OPENGL_11
endif
# Define default C compiler and archiver to pack library: CC, AR # Define default C compiler and archiver to pack library: CC, AR
#------------------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------------------
CC = gcc CC = gcc
@ -302,6 +316,12 @@ ifeq ($(PLATFORM),PLATFORM_ANDROID)
AR = $(ANDROID_TOOLCHAIN)/bin/llvm-ar AR = $(ANDROID_TOOLCHAIN)/bin/llvm-ar
endif endif
ifeq ($(PLATFORM),PLATFORM_NINTENDO64)
include $(N64_INST)/include/raylib4Nintendo64.mk
CC = $(N64_CC)
AR = $(N64_AR)
endif
ifeq ($(PLATFORM),PLATFORM_DREAMCAST) ifeq ($(PLATFORM),PLATFORM_DREAMCAST)
CC = $(KOS_CC) CC = $(KOS_CC)
AR = $(KOS_AR) AR = $(KOS_AR)
@ -453,6 +473,11 @@ endif
#------------------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------------------
INCLUDE_PATHS = -I. INCLUDE_PATHS = -I.
ifeq ($(PLATFORM),PLATFORM_NINTENDO64)
CFLAGS = $(N64_CFLAGS) -D$(PLATFORM) -D$(GRAPHICS)
INCLUDE_PATHS = $(N64_INCLUDEDIR)
endif
ifeq ($(PLATFORM),PLATFORM_DREAMCAST) ifeq ($(PLATFORM),PLATFORM_DREAMCAST)
CFLAGS = $(KOS_CFLAGS) -D$(PLATFORM) -D$(GRAPHICS) CFLAGS = $(KOS_CFLAGS) -D$(PLATFORM) -D$(GRAPHICS)
INCLUDE_PATHS = $(KOS_INC_PATHS) INCLUDE_PATHS = $(KOS_INC_PATHS)
@ -765,6 +790,9 @@ android_native_app_glue.o : $(NATIVE_APP_GLUE)/android_native_app_glue.c
# RAYLIB_INSTALL_PATH should be the desired full path to libraylib. No relative paths. # RAYLIB_INSTALL_PATH should be the desired full path to libraylib. No relative paths.
#DESTDIR ?= /usr/local #DESTDIR ?= /usr/local
ifeq ($(PLATFORM),PLATFORM_NINTENDO64)
PREFIX ?= $(N64_ROOTDIR)/mips64-elf
endif
ifeq ($(PLATFORM),PLATFORM_DREAMCAST) ifeq ($(PLATFORM),PLATFORM_DREAMCAST)
PREFIX ?= $(KOS_PORTS) PREFIX ?= $(KOS_PORTS)
endif endif

View File

@ -154,7 +154,7 @@
#define SUPPORT_FILEFORMAT_GIF 1 #define SUPPORT_FILEFORMAT_GIF 1
#define SUPPORT_FILEFORMAT_QOI 1 #define SUPPORT_FILEFORMAT_QOI 1
//#define SUPPORT_FILEFORMAT_PSD 1 //#define SUPPORT_FILEFORMAT_PSD 1
#define SUPPORT_FILEFORMAT_DDS 1 //#define SUPPORT_FILEFORMAT_DDS 1
//#define SUPPORT_FILEFORMAT_HDR 1 //#define SUPPORT_FILEFORMAT_HDR 1
//#define SUPPORT_FILEFORMAT_PIC 1 //#define SUPPORT_FILEFORMAT_PIC 1
//#define SUPPORT_FILEFORMAT_KTX 1 //#define SUPPORT_FILEFORMAT_KTX 1

View File

@ -0,0 +1,707 @@
/**********************************************************************************************
*
* rcore_dreamcast - Functions to manage window, graphics device and inputs
*
* PLATFORM: NINTENDO64
* - Nintendo 64
*
* LIMITATIONS:
* - Limitation 01
* - Limitation 02
*
* POSSIBLE IMPROVEMENTS:
* - Improvement 01
* - Improvement 02
*
* ADDITIONAL NOTES:
* - Port done by Antonio Jose Ramos Marquez aka bigboss @psxdev
*
* CONFIGURATION:
* #define RCORE_PLATFORM_CUSTOM_FLAG
* Custom flag for rcore on target platform -not used-
*
* DEPENDENCIES:
* Nintendo64 libdragon and toolchains - Provides C API to access Nintendo 64 homebrew functionality
*
*
* LICENSE: zlib/libpng
*
* Copyright (c) 2013-2023 Ramon Santamaria (@raysan5) and contributors
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose, including commercial
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not claim that you
* wrote the original software. If you use this software in a product, an acknowledgment
* in the product documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
* as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
#include <libdragon.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/gl_integration.h>
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
typedef struct rayFontN64
{
Texture2D fontGLTextures[224];
surface_t fontSurfaces[224];
}RayFontN64;
#define RAYLIB4N64_MAX_SURFACE_LIMIT 10 //You can change this limit
typedef struct {
// TODO: Define the platform specific variables required
surface_t zbuffer;
surface_t *disp;
RayFontN64 rayFonts;
surface_t surfaces[RAYLIB4N64_MAX_SURFACE_LIMIT];
unsigned int surface_index;
// Display data
//EGLDisplay device; // Native display device (physical screen connection)
//EGLSurface surface; // Surface to draw on, framebuffers (connected to context)
//EGLContext context; // Graphic context, mode in which drawing can be done
//EGLConfig config; // Graphic config
} PlatformData;
#define SUPPORT_DEFAULT_FONT 1
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
extern CoreData CORE; // Global CORE state context
static PlatformData platform = { 0 }; // Platform specific data
//----------------------------------------------------------------------------------
// Module Internal Functions Declaration
//----------------------------------------------------------------------------------
int InitPlatform(void); // Initialize platform (graphics, inputs and more)
bool InitGraphicsDevice(void); // Initialize graphics device
Texture2D rayDefaultFontsGetTextureFromGlyph(int index);
void rayDefaultFontsInitSurfaceBuffers();
void rayDefaultFontGliphGlTextureInit(Font font,int index);
Texture2D getFontGLTextureId(char *text);
//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
// NOTE: Functions declaration is provided by raylib.h
//----------------------------------------------------------------------------------
// Module Functions Definition: Window and Graphics Device
//----------------------------------------------------------------------------------
// Check if application should close
bool WindowShouldClose(void)
{
if (CORE.Window.ready) return CORE.Window.shouldClose;
else return true;
}
// Toggle fullscreen mode
void ToggleFullscreen(void)
{
TRACELOG(LOG_WARNING, "ToggleFullscreen() not available on target platform");
}
// Toggle borderless windowed mode
void ToggleBorderlessWindowed(void)
{
TRACELOG(LOG_WARNING, "ToggleBorderlessWindowed() not available on target platform");
}
// Set window state: maximized, if resizable
void MaximizeWindow(void)
{
TRACELOG(LOG_WARNING, "MaximizeWindow() not available on target platform");
}
// Set window state: minimized
void MinimizeWindow(void)
{
TRACELOG(LOG_WARNING, "MinimizeWindow() not available on target platform");
}
// Set window state: not minimized/maximized
void RestoreWindow(void)
{
TRACELOG(LOG_WARNING, "RestoreWindow() not available on target platform");
}
// Set window configuration state using flags
void SetWindowState(unsigned int flags)
{
TRACELOG(LOG_WARNING, "SetWindowState() not available on target platform");
}
// Clear window configuration state flags
void ClearWindowState(unsigned int flags)
{
TRACELOG(LOG_WARNING, "ClearWindowState() not available on target platform");
}
// Set icon for window
void SetWindowIcon(Image image)
{
TRACELOG(LOG_WARNING, "SetWindowIcon() not available on target platform");
}
// Set icon for window
void SetWindowIcons(Image *images, int count)
{
TRACELOG(LOG_WARNING, "SetWindowIcons() not available on target platform");
}
// Set title for window
void SetWindowTitle(const char *title)
{
CORE.Window.title = title;
}
// Set window position on screen (windowed mode)
void SetWindowPosition(int x, int y)
{
TRACELOG(LOG_WARNING, "SetWindowPosition() not available on target platform");
}
// Set monitor for the current window
void SetWindowMonitor(int monitor)
{
TRACELOG(LOG_WARNING, "SetWindowMonitor() not available on target platform");
}
// Set window minimum dimensions (FLAG_WINDOW_RESIZABLE)
void SetWindowMinSize(int width, int height)
{
CORE.Window.screenMin.width = width;
CORE.Window.screenMin.height = height;
}
// Set window maximum dimensions (FLAG_WINDOW_RESIZABLE)
void SetWindowMaxSize(int width, int height)
{
CORE.Window.screenMax.width = width;
CORE.Window.screenMax.height = height;
}
// Set window dimensions
void SetWindowSize(int width, int height)
{
TRACELOG(LOG_WARNING, "SetWindowSize() not available on target platform");
}
// Set window opacity, value opacity is between 0.0 and 1.0
void SetWindowOpacity(float opacity)
{
TRACELOG(LOG_WARNING, "SetWindowOpacity() not available on target platform");
}
// Set window focused
void SetWindowFocused(void)
{
TRACELOG(LOG_WARNING, "SetWindowFocused() not available on target platform");
}
// Get native window handle
void *GetWindowHandle(void)
{
TRACELOG(LOG_WARNING, "GetWindowHandle() not implemented on target platform");
return NULL;
}
// Get number of monitors
int GetMonitorCount(void)
{
TRACELOG(LOG_WARNING, "GetMonitorCount() not implemented on target platform");
return 1;
}
// Get number of monitors
int GetCurrentMonitor(void)
{
TRACELOG(LOG_WARNING, "GetCurrentMonitor() not implemented on target platform");
return 0;
}
// Get selected monitor position
Vector2 GetMonitorPosition(int monitor)
{
TRACELOG(LOG_WARNING, "GetMonitorPosition() not implemented on target platform");
return (Vector2){ 0, 0 };
}
// Get selected monitor width (currently used by monitor)
int GetMonitorWidth(int monitor)
{
TRACELOG(LOG_WARNING, "GetMonitorWidth() not implemented on target platform");
return 0;
}
// Get selected monitor height (currently used by monitor)
int GetMonitorHeight(int monitor)
{
TRACELOG(LOG_WARNING, "GetMonitorHeight() not implemented on target platform");
return 0;
}
// Get selected monitor physical width in millimetres
int GetMonitorPhysicalWidth(int monitor)
{
TRACELOG(LOG_WARNING, "GetMonitorPhysicalWidth() not implemented on target platform");
return 0;
}
// Get selected monitor physical height in millimetres
int GetMonitorPhysicalHeight(int monitor)
{
TRACELOG(LOG_WARNING, "GetMonitorPhysicalHeight() not implemented on target platform");
return 0;
}
// Get selected monitor refresh rate
int GetMonitorRefreshRate(int monitor)
{
TRACELOG(LOG_WARNING, "GetMonitorRefreshRate() not implemented on target platform");
return 0;
}
// Get the human-readable, UTF-8 encoded name of the selected monitor
const char *GetMonitorName(int monitor)
{
TRACELOG(LOG_WARNING, "GetMonitorName() not implemented on target platform");
return "";
}
// Get window position XY on monitor
Vector2 GetWindowPosition(void)
{
TRACELOG(LOG_WARNING, "GetWindowPosition() not implemented on target platform");
return (Vector2){ 0, 0 };
}
// Get window scale DPI factor for current monitor
Vector2 GetWindowScaleDPI(void)
{
TRACELOG(LOG_WARNING, "GetWindowScaleDPI() not implemented on target platform");
return (Vector2){ 1.0f, 1.0f };
}
// Set clipboard text content
void SetClipboardText(const char *text)
{
TRACELOG(LOG_WARNING, "SetClipboardText() not implemented on target platform");
}
// Get clipboard text content
// NOTE: returned string is allocated and freed by GLFW
const char *GetClipboardText(void)
{
TRACELOG(LOG_WARNING, "GetClipboardText() not implemented on target platform");
return NULL;
}
// Show mouse cursor
void ShowCursor(void)
{
CORE.Input.Mouse.cursorHidden = false;
}
// Hides mouse cursor
void HideCursor(void)
{
CORE.Input.Mouse.cursorHidden = true;
}
// Enables cursor (unlock cursor)
void EnableCursor(void)
{
// Set cursor position in the middle
SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2);
CORE.Input.Mouse.cursorHidden = false;
}
// Disables cursor (lock cursor)
void DisableCursor(void)
{
// Set cursor position in the middle
SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2);
CORE.Input.Mouse.cursorHidden = true;
}
// Swap back buffer with front buffer (screen drawing)
void SwapScreenBuffer(void)
{
gl_context_end();
rdpq_detach_show();
}
//----------------------------------------------------------------------------------
// Module Functions Definition: Misc
//----------------------------------------------------------------------------------
// Get elapsed time measure in seconds since InitTimer()
double GetTime(void)
{
disable_interrupts();
double time=(double)(get_ticks_us() - CORE.Time.base)*1e-6;
enable_interrupts();
return time;
}
// Open URL with default system browser (if available)
// NOTE: This function is only safe to use if you control the URL given.
// A user could craft a malicious string performing another action.
// Only call this function yourself not with user input or make sure to check the string yourself.
// Ref: https://github.com/raysan5/raylib/issues/686
void OpenURL(const char *url)
{
// Security check to (partially) avoid malicious code on target platform
if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character");
else
{
// TODO:
}
}
//----------------------------------------------------------------------------------
// Module Functions Definition: Inputs
//----------------------------------------------------------------------------------
// Set internal gamepad mappings
int SetGamepadMappings(const char *mappings)
{
TRACELOG(LOG_WARNING, "SetGamepadMappings() not implemented on target platform");
return 0;
}
// Set mouse position XY
void SetMousePosition(int x, int y)
{
CORE.Input.Mouse.currentPosition = (Vector2){ (float)x, (float)y };
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
}
// Set mouse cursor
void SetMouseCursor(int cursor)
{
TRACELOG(LOG_WARNING, "SetMouseCursor() not implemented on target platform");
}
// Register all input events
void PollInputEvents(void)
{
joypad_style_t style;
joypad_accessory_type_t accessory_type;
bool rumble_supported;
bool rumble_active;
joypad_inputs_t inputs;
#if defined(SUPPORT_GESTURES_SYSTEM)
// NOTE: Gestures update must be called every frame to reset gestures correctly
// because ProcessGestureEvent() is just called on an event, not every frame
UpdateGestures();
#endif
// Reset keys/chars pressed registered
CORE.Input.Keyboard.keyPressedQueueCount = 0;
CORE.Input.Keyboard.charPressedQueueCount = 0;
// Reset key repeats
for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) CORE.Input.Keyboard.keyRepeatInFrame[i] = 0;
// Reset last gamepad button/axis registered state
CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN
//CORE.Input.Gamepad.axisCount = 0;
// Register previous touch states
for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.previousTouchState[i] = CORE.Input.Touch.currentTouchState[i];
// TODO: Add callbacks for connect / disconnected pads
// Reset touch positions
// TODO: It resets on target platform the mouse position and not filled again until a move-event,
// so, if mouse is not moved it returns a (0, 0) position... this behaviour should be reviewed!
//for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.position[i] = (Vector2){ 0, 0 };
// Register previous keys states
// NOTE: Android supports up to 260 keys
//for (int i = 0; i < 260; i++)
//{
// CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i];
// CORE.Input.Keyboard.keyRepeatInFrame[i] = 0;
//}
// TODO: Poll input events for current plaform
/*TODO N64
joypad_poll();
JOYPAD_PORT_FOREACH (port)
{
style = joypad_get_style(port);
accessory_type = joypad_get_accessory_type(port);
rumble_supported = joypad_get_rumble_supported(port);
rumble_active = joypad_get_rumble_active(port);
inputs = joypad_get_inputs(port);
if (rumble_supported)
{
if (inputs.btn.a && !rumble_active)
{
joypad_set_rumble_active(port, true);
}
else if (!inputs.btn.a && rumble_active)
{
joypad_set_rumble_active(port, false);
}
}
}
*/
}
void CustomLog(int msgType, const char *text, va_list args)
{
char buffer[1024] = { 0 };
vsnprintf(buffer,1024, text, args);
buffer[1024-1] = 0;
switch (msgType)
{
case LOG_TRACE: debugf("[N64][TRACE]: %s\n",buffer); break;
case LOG_DEBUG: debugf("[N64][DEBUG]: %s\n",buffer); break;
case LOG_INFO: debugf("[N64][INFO]: %s\n",buffer); break;
case LOG_WARNING: debugf("[N64][WARNING]: %s\n",buffer); break;
case LOG_ERROR: debugf("[N64][ERROR]: %s\n",buffer); break;
case LOG_FATAL: debugf("[N64][FATAL]: %s\n",buffer); break;
default: break;
}
}
//----------------------------------------------------------------------------------
// Module Internal Functions Definition
//----------------------------------------------------------------------------------
//Set all surface buffer for each glyph to NULL
void rayDefaultFontsInitSurfaceBuffers()
{
for(int i=0;i<224;i++)
{
platform.rayFonts.fontSurfaces[i].buffer=NULL;
}
}
void rlLoadTextureN64(const void *data, int width, int height, int format, int mipmapCount)
{
if(platform.surface_index>=RAYLIB4N64_MAX_SURFACE_LIMIT)
{
TraceLog(LOG_ERROR,"Limit for surfaces in raylib4Nintendo64 is %d",RAYLIB4N64_MAX_SURFACE_LIMIT);
return 0;
}
//todo load different mipmap level using mipmapCount by now we wil use only level 0
//todo using different GL format to transform to supported internal format by now we will use only FMT_RGBA32
platform.surfaces[platform.surface_index].flags = FMT_RGBA32 | SURFACE_FLAGS_OWNEDBUFFER;
platform.surfaces[platform.surface_index].width = (uint32_t)width;
platform.surfaces[platform.surface_index].height = (uint32_t)height;
platform.surfaces[platform.surface_index].stride = TEX_FORMAT_PIX2BYTES(FMT_RGBA32, width);
platform.surfaces[platform.surface_index].buffer = data;
glSurfaceTexImageN64(GL_TEXTURE_2D, 0, &(platform.surfaces[platform.surface_index]), &(rdpq_texparms_t){.s.repeats = 0, .t.repeats = 0});
platform.surface_index++;
}
void rayDefaultFontGliphGlTextureInit(Font font,int index)
{
//If gliph was not initialized before generate texture from glyph image
if(platform.rayFonts.fontSurfaces[index].buffer==NULL)
{
platform.rayFonts.fontSurfaces[index].flags = FMT_RGBA32 | SURFACE_FLAGS_OWNEDBUFFER;
platform.rayFonts.fontSurfaces[index].width = (uint32_t) (font.recs[index].width);
platform.rayFonts.fontSurfaces[index].height = (uint32_t)(font.recs[index].height);
platform.rayFonts.fontSurfaces[index].stride = TEX_FORMAT_PIX2BYTES(FMT_RGBA32, platform.rayFonts.fontSurfaces[index].width);
platform.rayFonts.fontSurfaces[index].buffer = (font.glyphs[index].image.data);
glGenTextures(1,&(platform.rayFonts.fontGLTextures[index].id));
glBindTexture(GL_TEXTURE_2D, platform.rayFonts.fontGLTextures[index].id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture to repeat on x-axis
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture to repeat on y-axis
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Alternative: GL_LINEAR
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Alternative: GL_LINEAR*/
glSurfaceTexImageN64(GL_TEXTURE_2D, 0, &(platform.rayFonts.fontSurfaces[index]), &(rdpq_texparms_t){.s.repeats = 0, .t.repeats = 0});
platform.rayFonts.fontGLTextures[index].width=font.recs[index].width;
platform.rayFonts.fontGLTextures[index].height= font.recs[index].height;
platform.rayFonts.fontGLTextures[index].mipmaps=1;
platform.rayFonts.fontGLTextures[index].format=PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
}
}
Texture2D getFontGLTextureId(char *text)
{
int codepointByteCount;
int codepoint = GetCodepointNext(text, &codepointByteCount);
int index = GetGlyphIndex(GetFontDefault(), codepoint);
if(platform.rayFonts.fontGLTextures[index].id==0)
{
TraceLog(LOG_ERROR, "%s texture not initalized for %s", __FUNCTION__,text);
rayDefaultFontGliphGlTextureInit(GetFontDefault(),index);
}
else
{
//TraceLog(LOG_INFO, "%s textureinitalized for %s ", __FUNCTION__,text);
}
return platform.rayFonts.fontGLTextures[index];
}
Texture2D rayDefaultFontsGetTextureFromGlyph(int index)
{
Texture2D texture = { 0 };
texture.id = platform.rayFonts.fontGLTextures[index].id;
texture.width = platform.rayFonts.fontGLTextures[index].width;
texture.height = platform.rayFonts.fontGLTextures[index].height;
texture.mipmaps = platform.rayFonts.fontGLTextures[index].mipmaps;
texture.format = platform.rayFonts.fontGLTextures[index].format;
return texture;
}
// Initialize platform: graphics, inputs and more
int InitPlatform(void)
{
SetTraceLogCallback(CustomLog);
debug_init_isviewer();
debug_init_usblog();
TRACELOG(LOG_INFO, "Initializing raylib %s", RAYLIB_VERSION);
TRACELOG(LOG_INFO, "Platform backend: NINTENDO64");
TRACELOG(LOG_INFO, "PLATFORM: Nintendo 64 init");
dfs_init(DFS_DEFAULT_LOCATION);
display_init(RESOLUTION_320x240, DEPTH_16_BPP, 3, GAMMA_NONE, FILTERS_RESAMPLE_ANTIALIAS_DEDITHER);
rdpq_init();
gl_init();
#if DEBUG_RDP
rdpq_debug_start();
rdpq_debug_log(true);
#endif
joypad_init();
rayDefaultFontsInitSurfaceBuffers();
platform.zbuffer = surface_alloc(FMT_RGBA16, display_get_width(), display_get_height());
platform.disp = display_get();
rdpq_attach(platform.disp, &platform.zbuffer);
gl_context_begin();
CORE.Window.fullscreen = true;
CORE.Window.flags |= FLAG_FULLSCREEN_MODE;
CORE.Window.display.width = 320;//CORE.Window.screen.width; // User desired width
CORE.Window.display.height = 240;//CORE.Window.screen.height; // User desired height
CORE.Window.screen.width=314;
CORE.Window.screen.height=240;
CORE.Window.render.width = CORE.Window.screen.width;
CORE.Window.render.height = CORE.Window.screen.height;
CORE.Window.eventWaiting = false;
CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default
CORE.Window.currentFbo.width = CORE.Window.screen.width;
CORE.Window.currentFbo.height = CORE.Window.screen.height;
CORE.Input.Mouse.currentPosition.x = (float)CORE.Window.screen.width/2.0f;
CORE.Input.Mouse.currentPosition.y = (float)CORE.Window.screen.height/2.0f;
CORE.Input.Mouse.scale = (Vector2){ 1.0f, 1.0f };
// At this point we need to manage render size vs screen size
// NOTE: This function use and modify global module variables:
// -> CORE.Window.screen.width/CORE.Window.screen.height
// -> CORE.Window.render.width/CORE.Window.render.height
// -> CORE.Window.screenScale
SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height);
//ANativeWindow_setBuffersGeometry(platform.app->window, CORE.Window.render.width, CORE.Window.render.height, displayFormat);
//ANativeWindow_setBuffersGeometry(platform.app->window, 0, 0, displayFormat); // Force use of native display size
{
CORE.Window.render.width = CORE.Window.screen.width;
CORE.Window.render.height = CORE.Window.screen.height;
CORE.Window.currentFbo.width = CORE.Window.render.width;
CORE.Window.currentFbo.height = CORE.Window.render.height;
TRACELOG(LOG_INFO, "PLATFORM: Device initialized successfully");
TRACELOG(LOG_INFO, " > Display size: %i x %i", CORE.Window.display.width, CORE.Window.display.height);
TRACELOG(LOG_INFO, " > Screen size: %i x %i", CORE.Window.screen.width, CORE.Window.screen.height);
TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height);
TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y);
}
// Load OpenGL extensions
// NOTE: GL procedures address loader is required to load extensions
//rlLoadExtensions(eglGetProcAddress);
//const char *gl_exts = (char *) glGetString(GL_EXTENSIONS);
//TRACELOG(LOG_INFO,"PLATFORM: GL_VENDOR: \"%s\"", glGetString(GL_VENDOR));
//TRACELOG(LOG_INFO,"PLATFORM: GL_VERSION: \"%s\"", glGetString(GL_VERSION));
//TRACELOG(LOG_INFO,"PLATFORM: GL_RENDERER: \"%s\"", glGetString(GL_RENDERER));
//TRACELOG(LOG_INFO,"PLATFORM: SL_VERSION: \"%s\"", glGetString(GL_SHADING_LANGUAGE_VERSION));
CORE.Window.ready = true;
// Initialize hi-res timer
InitTimer();
// Initialize base path for storage
CORE.Storage.basePath = GetWorkingDirectory();
TRACELOG(LOG_INFO, "PLATFORM: Initialized");
return 0;
}
// Close platform
void ClosePlatform(void)
{
// TODO: De-initialize graphics, inputs and more
}
// EOF

View File

@ -21,7 +21,8 @@
* - Android (ARM, ARM64) * - Android (ARM, ARM64)
* > PLATFORM_DREAMCAST: * > PLATFORM_DREAMCAST:
* - Sega Dreamcast (SH4) * - Sega Dreamcast (SH4)
* * > PLATFORM_NINTENDO64:
* - Nintendo 64 (MIPS4300)
* CONFIGURATION: * CONFIGURATION:
* #define SUPPORT_DEFAULT_FONT (default) * #define SUPPORT_DEFAULT_FONT (default)
* Default font is loaded on window initialization to be available for the user to render simple text. * Default font is loaded on window initialization to be available for the user to render simple text.
@ -182,9 +183,13 @@ __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigne
#define DIRENT_FREE RL_FREE #define DIRENT_FREE RL_FREE
#include "external/dirent.h" // Required for: DIR, opendir(), closedir() [Used in LoadDirectoryFiles()] #include "external/dirent.h" // Required for: DIR, opendir(), closedir() [Used in LoadDirectoryFiles()]
#else
#if defined(PLATFORM_NINTENDO64)
//avoid dirent on Nintendo 64
#else #else
#include <dirent.h> // Required for: DIR, opendir(), closedir() [Used in LoadDirectoryFiles()] #include <dirent.h> // Required for: DIR, opendir(), closedir() [Used in LoadDirectoryFiles()]
#endif #endif
#endif
#if defined(_WIN32) #if defined(_WIN32)
#include <direct.h> // Required for: _getch(), _chdir() #include <direct.h> // Required for: _getch(), _chdir()
@ -503,6 +508,8 @@ const char *TextFormat(const char *text, ...); // Formatting of tex
#include "platforms/rcore_android.c" #include "platforms/rcore_android.c"
#elif defined(PLATFORM_DREAMCAST) #elif defined(PLATFORM_DREAMCAST)
#include "platforms/rcore_dreamcast.c" #include "platforms/rcore_dreamcast.c"
#elif defined(PLATFORM_NINTENDO64)
#include "platforms/rcore_nintendo64.c"
#else #else
// TODO: Include your custom platform backend! // TODO: Include your custom platform backend!
// i.e software rendering backend or console backend! // i.e software rendering backend or console backend!
@ -573,6 +580,8 @@ void InitWindow(int width, int height, const char *title)
TRACELOG(LOG_INFO, "Platform backend: ANDROID"); TRACELOG(LOG_INFO, "Platform backend: ANDROID");
#elif defined(PLATFORM_DREAMCAST) #elif defined(PLATFORM_DREAMCAST)
TRACELOG(LOG_INFO, "Platform backend: DREAMCAST"); TRACELOG(LOG_INFO, "Platform backend: DREAMCAST");
#elif defined(PLATFORM_NINTENDO64)
TRACELOG(LOG_INFO, "Platform backend: NINTENDO64");
#else #else
// TODO: Include your custom platform backend! // TODO: Include your custom platform backend!
// i.e software rendering backend or console backend! // i.e software rendering backend or console backend!
@ -641,7 +650,11 @@ void InitWindow(int width, int height, const char *title)
#if defined(SUPPORT_MODULE_RSHAPES) #if defined(SUPPORT_MODULE_RSHAPES)
// Set font white rectangle for shapes drawing, so shapes and text can be batched together // Set font white rectangle for shapes drawing, so shapes and text can be batched together
// WARNING: rshapes module is required, if not available, default internal white rectangle is used // WARNING: rshapes module is required, if not available, default internal white rectangle is used
#if defined(PLATFORM_NINTENDO64)
Rectangle rec=(Rectangle){ 0.0f, 0.0f, 5.0f, 10.0f };
#else
Rectangle rec = GetFontDefault().recs[95]; Rectangle rec = GetFontDefault().recs[95];
#endif
if (CORE.Window.flags & FLAG_MSAA_4X_HINT) if (CORE.Window.flags & FLAG_MSAA_4X_HINT)
{ {
// NOTE: We try to maxime rec padding to avoid pixel bleeding on MSAA filtering // NOTE: We try to maxime rec padding to avoid pixel bleeding on MSAA filtering
@ -676,6 +689,9 @@ void InitWindow(int width, int height, const char *title)
// Initialize random seed // Initialize random seed
SetRandomSeed((unsigned int)time(NULL)); SetRandomSeed((unsigned int)time(NULL));
#if defined(PLATFORM_NINTENDO64)
SwapScreenBuffer();
#endif
} }
// Close window and unload OpenGL context // Close window and unload OpenGL context
@ -831,7 +847,13 @@ void BeginDrawing(void)
{ {
// WARNING: Previously to BeginDrawing() other render textures drawing could happen, // WARNING: Previously to BeginDrawing() other render textures drawing could happen,
// consequently the measure for update vs draw is not accurate (only the total frame time is accurate) // consequently the measure for update vs draw is not accurate (only the total frame time is accurate)
#if defined(PLATFORM_NINTENDO64)
platform.disp = display_get();
rdpq_attach(platform.disp, &platform.zbuffer);
gl_context_begin();
#endif
CORE.Time.current = GetTime(); // Number of elapsed seconds since InitTimer() CORE.Time.current = GetTime(); // Number of elapsed seconds since InitTimer()
CORE.Time.update = CORE.Time.current - CORE.Time.previous; CORE.Time.update = CORE.Time.current - CORE.Time.previous;
CORE.Time.previous = CORE.Time.current; CORE.Time.previous = CORE.Time.current;
@ -1886,6 +1908,7 @@ bool IsFileExtension(const char *fileName, const char *ext)
bool DirectoryExists(const char *dirPath) bool DirectoryExists(const char *dirPath)
{ {
bool result = false; bool result = false;
#if !defined(PLATFORM_VITA) && !defined(PLATFORM_ORBIS) && !defined(PLATFORM_PROSPERO) && !defined(PLATFORM_NINTENDO64)
DIR *dir = opendir(dirPath); DIR *dir = opendir(dirPath);
if (dir != NULL) if (dir != NULL)
@ -1893,7 +1916,7 @@ bool DirectoryExists(const char *dirPath)
result = true; result = true;
closedir(dir); closedir(dir);
} }
#endif
return result; return result;
} }
@ -2059,9 +2082,11 @@ const char *GetWorkingDirectory(void)
{ {
static char currentDir[MAX_FILEPATH_LENGTH] = { 0 }; static char currentDir[MAX_FILEPATH_LENGTH] = { 0 };
memset(currentDir, 0, MAX_FILEPATH_LENGTH); memset(currentDir, 0, MAX_FILEPATH_LENGTH);
#if !defined(PLATFORM_VITA) && !defined(PLATFORM_ORBIS) && !defined(PLATFORM_PROSPERO) && !defined(PLATFORM_NINTENDO64)
char *path = GETCWD(currentDir, MAX_FILEPATH_LENGTH - 1); char *path = GETCWD(currentDir, MAX_FILEPATH_LENGTH - 1);
#else
char *path=".";
#endif
return path; return path;
} }
@ -2151,6 +2176,7 @@ FilePathList LoadDirectoryFiles(const char *dirPath)
unsigned int fileCounter = 0; unsigned int fileCounter = 0;
struct dirent *entity; struct dirent *entity;
#if !defined(PLATFORM_VITA) && !defined(PLATFORM_ORBIS) && !defined(PLATFORM_PROSPERO) && !defined(PLATFORM_NINTENDO64)
DIR *dir = opendir(dirPath); DIR *dir = opendir(dirPath);
if (dir != NULL) // It's a directory if (dir != NULL) // It's a directory
@ -2177,7 +2203,7 @@ FilePathList LoadDirectoryFiles(const char *dirPath)
if (files.count != files.capacity) TRACELOG(LOG_WARNING, "FILEIO: Read files count do not match capacity allocated"); if (files.count != files.capacity) TRACELOG(LOG_WARNING, "FILEIO: Read files count do not match capacity allocated");
} }
else TRACELOG(LOG_WARNING, "FILEIO: Failed to open requested directory"); // Maybe it's a file... else TRACELOG(LOG_WARNING, "FILEIO: Failed to open requested directory"); // Maybe it's a file...
#endif
return files; return files;
} }
@ -2210,10 +2236,13 @@ void UnloadDirectoryFiles(FilePathList files)
// Change working directory, returns true on success // Change working directory, returns true on success
bool ChangeDirectory(const char *dir) bool ChangeDirectory(const char *dir)
{ {
#if !defined(PLATFORM_VITA) && !defined(PLATFORM_ORBIS) && !defined(PLATFORM_PROSPERO) && !defined(PLATFORM_NINTENDO64)
bool result = CHDIR(dir); bool result = CHDIR(dir);
if (result != 0) TRACELOG(LOG_WARNING, "SYSTEM: Failed to change to directory: %s", dir); if (result != 0) TRACELOG(LOG_WARNING, "SYSTEM: Failed to change to directory: %s", dir);
#else
bool result=1;
#endif
return (result == 0); return (result == 0);
} }
@ -3081,7 +3110,11 @@ void InitTimer(void)
} }
else TRACELOG(LOG_WARNING, "TIMER: Hi-resolution timer not available"); else TRACELOG(LOG_WARNING, "TIMER: Hi-resolution timer not available");
#endif #endif
#if defined(PLATFORM_NINTENDO64)
disable_interrupts();
CORE.Time.base = get_ticks_us();
enable_interrupts();
#endif
CORE.Time.previous = GetTime(); // Get time as double CORE.Time.previous = GetTime(); // Get time as double
} }
@ -3106,7 +3139,7 @@ void SetupViewport(int width, int height)
// Set orthographic projection to current framebuffer size // Set orthographic projection to current framebuffer size
// NOTE: Configured top-left corner as (0, 0) // NOTE: Configured top-left corner as (0, 0)
#if defined(PLATFORM_DREAMCAST) #if defined(PLATFORM_DREAMCAST) || defined(PLATFORM_NINTENDO64)
rlOrtho(0, CORE.Window.render.width, CORE.Window.render.height, 0, -1.0f, 1.0f); rlOrtho(0, CORE.Window.render.width, CORE.Window.render.height, 0, -1.0f, 1.0f);
#else #else
rlOrtho(0, CORE.Window.render.width, CORE.Window.render.height, 0, 0.0f, 1.0f); rlOrtho(0, CORE.Window.render.width, CORE.Window.render.height, 0, 0.0f, 1.0f);
@ -3200,7 +3233,7 @@ static void ScanDirectoryFiles(const char *basePath, FilePathList *files, const
{ {
static char path[MAX_FILEPATH_LENGTH] = { 0 }; static char path[MAX_FILEPATH_LENGTH] = { 0 };
memset(path, 0, MAX_FILEPATH_LENGTH); memset(path, 0, MAX_FILEPATH_LENGTH);
#if !defined(PLATFORM_VITA) && !defined(PLATFORM_ORBIS) && !defined(PLATFORM_PROSPERO) && !defined(PLATFORM_NINTENDO64)
struct dirent *dp = NULL; struct dirent *dp = NULL;
DIR *dir = opendir(basePath); DIR *dir = opendir(basePath);
@ -3236,6 +3269,7 @@ static void ScanDirectoryFiles(const char *basePath, FilePathList *files, const
closedir(dir); closedir(dir);
} }
else TRACELOG(LOG_WARNING, "FILEIO: Directory cannot be opened (%s)", basePath); else TRACELOG(LOG_WARNING, "FILEIO: Directory cannot be opened (%s)", basePath);
#endif
} }
// Scan all files and directories recursively from a base path // Scan all files and directories recursively from a base path
@ -3243,7 +3277,7 @@ static void ScanDirectoryFilesRecursively(const char *basePath, FilePathList *fi
{ {
char path[MAX_FILEPATH_LENGTH] = { 0 }; char path[MAX_FILEPATH_LENGTH] = { 0 };
memset(path, 0, MAX_FILEPATH_LENGTH); memset(path, 0, MAX_FILEPATH_LENGTH);
#if !defined(PLATFORM_VITA) && !defined(PLATFORM_ORBIS) && !defined(PLATFORM_PROSPERO) && !defined(PLATFORM_NINTENDO64)
struct dirent *dp = NULL; struct dirent *dp = NULL;
DIR *dir = opendir(basePath); DIR *dir = opendir(basePath);
@ -3289,6 +3323,7 @@ static void ScanDirectoryFilesRecursively(const char *basePath, FilePathList *fi
closedir(dir); closedir(dir);
} }
else TRACELOG(LOG_WARNING, "FILEIO: Directory cannot be opened (%s)", basePath); else TRACELOG(LOG_WARNING, "FILEIO: Directory cannot be opened (%s)", basePath);
#endif
} }
#if defined(SUPPORT_AUTOMATION_EVENTS) #if defined(SUPPORT_AUTOMATION_EVENTS)

View File

@ -1837,7 +1837,13 @@ void rlEnableBackfaceCulling(void) { glEnable(GL_CULL_FACE); }
void rlDisableBackfaceCulling(void) { glDisable(GL_CULL_FACE); } void rlDisableBackfaceCulling(void) { glDisable(GL_CULL_FACE); }
// Set color mask active for screen read/draw // Set color mask active for screen read/draw
void rlColorMask(bool r, bool g, bool b, bool a) { glColorMask(r, g, b, a); } void rlColorMask(bool r, bool g, bool b, bool a)
{
#if defined(PLATFORM_NINTENDO64)
#else
glColorMask(r, g, b, a);
#endif
}
// Set face culling mode // Set face culling mode
void rlSetCullFace(int mode) void rlSetCullFace(int mode)
@ -1873,7 +1879,7 @@ void rlEnablePointMode(void)
#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33) #if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33)
// NOTE: glPolygonMode() not available on OpenGL ES // NOTE: glPolygonMode() not available on OpenGL ES
glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
#if defined(PLATFORM_DREAMCAST) //fix needed on gldc by now hardcoded here to avoid compiling errors #if defined(PLATFORM_DREAMCAST) || defined(PLATFORM_NINTENDO64)//fix needed on gldc by now hardcoded here to avoid compiling errors. Also Not defined in libdragon
glEnable(0x8642/*GL_PROGRAM_POINT_SIZE*/); glEnable(0x8642/*GL_PROGRAM_POINT_SIZE*/);
#else #else
glEnable(GL_PROGRAM_POINT_SIZE); glEnable(GL_PROGRAM_POINT_SIZE);
@ -2180,7 +2186,11 @@ void rlglInit(int width, int height)
// Initialize OpenGL default states // Initialize OpenGL default states
//---------------------------------------------------------- //----------------------------------------------------------
// Init state: Depth test // Init state: Depth test
glDepthFunc(GL_LEQUAL); // Type of depth testing to apply #if defined(PLATFORM_NINTENDO64) //to review in libdragon
glDepthFunc(GL_LESS_INTERPENETRATING_N64); // Type of depth testing to apply
#else
glDepthFunc(GL_LEQUAL);
#endif // Type of depth testing to apply
glDisable(GL_DEPTH_TEST); // Disable depth testing for 2D (only used for 3D) glDisable(GL_DEPTH_TEST); // Disable depth testing for 2D (only used for 3D)
// Init state: Blending mode // Init state: Blending mode
@ -3081,12 +3091,13 @@ unsigned int rlLoadTexture(const void *data, int width, int height, int format,
TRACELOGD("TEXTURE: Load mipmap level %i (%i x %i), size: %i, offset: %i", i, mipWidth, mipHeight, mipSize, mipOffset); TRACELOGD("TEXTURE: Load mipmap level %i (%i x %i), size: %i, offset: %i", i, mipWidth, mipHeight, mipSize, mipOffset);
if (glInternalFormat != 0) if (glInternalFormat != 0)
{ {
#if !defined(PLATFORM_NINTENDO64)
if (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) glTexImage2D(GL_TEXTURE_2D, i, glInternalFormat, mipWidth, mipHeight, 0, glFormat, glType, dataPtr); if (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) glTexImage2D(GL_TEXTURE_2D, i, glInternalFormat, mipWidth, mipHeight, 0, glFormat, glType, dataPtr);
#if !defined(GRAPHICS_API_OPENGL_11) #if !defined(GRAPHICS_API_OPENGL_11)
else glCompressedTexImage2D(GL_TEXTURE_2D, i, glInternalFormat, mipWidth, mipHeight, 0, mipSize, dataPtr); else glCompressedTexImage2D(GL_TEXTURE_2D, i, glInternalFormat, mipWidth, mipHeight, 0, mipSize, dataPtr);
#endif #endif
#endif
#if defined(GRAPHICS_API_OPENGL_33) #if defined(GRAPHICS_API_OPENGL_33)
if (format == RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE) if (format == RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE)
{ {
@ -3147,7 +3158,9 @@ unsigned int rlLoadTexture(const void *data, int width, int height, int format,
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
} }
#endif #endif
#if defined(PLATFORM_NINTENDO64) //glTextParameter must be set before upload to gpu
rlLoadTextureN64(data,width,height,format,mipmapCount);
#endif
// At this point we have the texture loaded in GPU and texture parameters configured // At this point we have the texture loaded in GPU and texture parameters configured
// NOTE: If mipmaps were not in data, they are not generated automatically // NOTE: If mipmaps were not in data, they are not generated automatically
@ -3304,7 +3317,10 @@ void rlUpdateTexture(unsigned int id, int offsetX, int offsetY, int width, int h
if ((glInternalFormat != 0) && (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB)) if ((glInternalFormat != 0) && (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB))
{ {
#if defined(PLATFORM_NINTENDO64)
#else
glTexSubImage2D(GL_TEXTURE_2D, 0, offsetX, offsetY, width, height, glFormat, glType, data); glTexSubImage2D(GL_TEXTURE_2D, 0, offsetX, offsetY, width, height, glFormat, glType, data);
#endif
} }
else TRACELOG(RL_LOG_WARNING, "TEXTURE: [ID %i] Failed to update for current texture format (%i)", id, format); else TRACELOG(RL_LOG_WARNING, "TEXTURE: [ID %i] Failed to update for current texture format (%i)", id, format);
} }
@ -3449,7 +3465,10 @@ void *rlReadTexturePixels(unsigned int id, int width, int height, int format)
if ((glInternalFormat != 0) && (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB)) if ((glInternalFormat != 0) && (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB))
{ {
pixels = RL_MALLOC(size); pixels = RL_MALLOC(size);
#if defined(PLATFORM_NINTENDO64)
#else
glGetTexImage(GL_TEXTURE_2D, 0, glFormat, glType, pixels); glGetTexImage(GL_TEXTURE_2D, 0, glFormat, glType, pixels);
#endif
} }
else TRACELOG(RL_LOG_WARNING, "TEXTURE: [ID %i] Data retrieval not suported for pixel format (%i)", id, format); else TRACELOG(RL_LOG_WARNING, "TEXTURE: [ID %i] Data retrieval not suported for pixel format (%i)", id, format);
@ -3492,8 +3511,10 @@ unsigned char *rlReadScreenPixels(int width, int height)
// NOTE 1: glReadPixels returns image flipped vertically -> (0,0) is the bottom left corner of the framebuffer // NOTE 1: glReadPixels returns image flipped vertically -> (0,0) is the bottom left corner of the framebuffer
// NOTE 2: We are getting alpha channel! Be careful, it can be transparent if not cleared properly! // NOTE 2: We are getting alpha channel! Be careful, it can be transparent if not cleared properly!
#if defined(PLATFORM_NINTENDO64)
#else
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, screenData); glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, screenData);
#endif
// Flip image vertically! // Flip image vertically!
unsigned char *imgData = (unsigned char *)RL_MALLOC(width*height*4*sizeof(unsigned char)); unsigned char *imgData = (unsigned char *)RL_MALLOC(width*height*4*sizeof(unsigned char));

View File

@ -59,8 +59,9 @@
#include <float.h> // Required for: FLT_EPSILON #include <float.h> // Required for: FLT_EPSILON
#include <stdlib.h> // Required for: RL_FREE #include <stdlib.h> // Required for: RL_FREE
#if defined(PLATFORM_DREAMCAST)|| defined(PLATFORM_NINTENDO64)
#include "utils.h" // Required for: TRACELOG() macros used when i was testing on Dreamcast #include "utils.h" // Required for: TRACELOG() macros used when i was testing on Dreamcast
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Defines and Macros // Defines and Macros
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------

View File

@ -151,6 +151,11 @@ extern void LoadFontDefault(void);
extern void UnloadFontDefault(void); extern void UnloadFontDefault(void);
#endif #endif
#if defined(PLATFORM_NINTENDO64)
void rayDefaultFontsInitSurfaceBuffers();
void rayDefaultFontGliphGlTextureInit(Font font,int index);
Texture2D rayDefaultFontsGetTextureFromGlyph(int index);
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module Functions Definition // Module Functions Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -227,7 +232,7 @@ extern void LoadFontDefault(void)
// Re-construct image from defaultFontData and generate OpenGL texture // Re-construct image from defaultFontData and generate OpenGL texture
//---------------------------------------------------------------------- //----------------------------------------------------------------------
#if defined(PLATFORM_DREAMCAST) #if defined(PLATFORM_DREAMCAST) || defined(PLATFORM_NINTENDO64)
Image imFont = { Image imFont = {
.data = RL_CALLOC(128*128, 4), // 4 bytes per pixel (rgb + alpha) there are some issues with different format in Dreamcast so to avoid problems for text by now we will use this .data = RL_CALLOC(128*128, 4), // 4 bytes per pixel (rgb + alpha) there are some issues with different format in Dreamcast so to avoid problems for text by now we will use this
.width = 128, .width = 128,
@ -247,7 +252,16 @@ extern void LoadFontDefault(void)
// we must consider data as little-endian order (alpha + gray) // we must consider data as little-endian order (alpha + gray)
((unsigned int *)imFont.data)[i + j] = 0xffffffff; ((unsigned int *)imFont.data)[i + j] = 0xffffffff;
} }
else ((unsigned int *)imFont.data)[i + j] = 0x000000ff; else
{
#if defined(PLATFORM_DREAMCAST)
((unsigned int *)imFont.data)[i + j] = 0x000000ff;
#endif
#if defined(PLATFORM_NINTENDO64)
((unsigned int *)imFont.data)[i + j] = 0xff000000;
#endif
}
} }
counter++; counter++;
@ -278,7 +292,14 @@ extern void LoadFontDefault(void)
counter++; counter++;
} }
#endif #endif
#if defined(PLATFORM_NINTENDO64)
defaultFont.texture.width = imFont.width;
defaultFont.texture.height = imFont.height;
defaultFont.texture.mipmaps = 1;
defaultFont.texture.format = imFont.format;
#else
defaultFont.texture = LoadTextureFromImage(imFont); defaultFont.texture = LoadTextureFromImage(imFont);
#endif
// Reconstruct charSet using charsWidth[], charsHeight, charsDivisor, glyphCount // Reconstruct charSet using charsWidth[], charsHeight, charsDivisor, glyphCount
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -322,7 +343,10 @@ extern void LoadFontDefault(void)
// Fill character image data from fontClear data // Fill character image data from fontClear data
defaultFont.glyphs[i].image = ImageFromImage(imFont, defaultFont.recs[i]); defaultFont.glyphs[i].image = ImageFromImage(imFont, defaultFont.recs[i]);
} }
#if defined(PLATFORM_NINTENDO64) //We load only glyph 95 to use with shapes
rayDefaultFontGliphGlTextureInit(defaultFont,95);
defaultFont.texture = rayDefaultFontsGetTextureFromGlyph(95);
#endif
UnloadImage(imFont); UnloadImage(imFont);
defaultFont.baseSize = (int)defaultFont.recs[0].height; defaultFont.baseSize = (int)defaultFont.recs[0].height;
@ -1200,6 +1224,9 @@ void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, f
{ {
if ((codepoint != ' ') && (codepoint != '\t')) if ((codepoint != ' ') && (codepoint != '\t'))
{ {
#if defined(PLATFORM_NINTENDO64)
rayDefaultFontGliphGlTextureInit(font,index);
#endif
DrawTextCodepoint(font, codepoint, (Vector2){ position.x + textOffsetX, position.y + textOffsetY }, fontSize, tint); DrawTextCodepoint(font, codepoint, (Vector2){ position.x + textOffsetX, position.y + textOffsetY }, fontSize, tint);
} }
@ -1242,11 +1269,17 @@ void DrawTextCodepoint(Font font, int codepoint, Vector2 position, float fontSiz
// Character source rectangle from font texture atlas // Character source rectangle from font texture atlas
// NOTE: We consider chars padding when drawing, it could be required for outline/glow shader effects // NOTE: We consider chars padding when drawing, it could be required for outline/glow shader effects
#if defined(PLATFORM_NINTENDO64)
Rectangle srcRec = { 0.0f - (float)font.glyphPadding, 0.0f - (float)font.glyphPadding,
font.recs[index].width + 2.0f*font.glyphPadding, font.recs[index].height + 2.0f*font.glyphPadding };
// Draw the character texture on the screen
DrawTexturePro(rayDefaultFontsGetTextureFromGlyph(index), srcRec, dstRec, (Vector2){ 0, 0 }, 0.0f, tint);
#else
Rectangle srcRec = { font.recs[index].x - (float)font.glyphPadding, font.recs[index].y - (float)font.glyphPadding, Rectangle srcRec = { font.recs[index].x - (float)font.glyphPadding, font.recs[index].y - (float)font.glyphPadding,
font.recs[index].width + 2.0f*font.glyphPadding, font.recs[index].height + 2.0f*font.glyphPadding }; font.recs[index].width + 2.0f*font.glyphPadding, font.recs[index].height + 2.0f*font.glyphPadding };
// Draw the character texture on the screen // Draw the character texture on the screen
DrawTexturePro(font.texture, srcRec, dstRec, (Vector2){ 0, 0 }, 0.0f, tint); DrawTexturePro(font.texture, srcRec, dstRec, (Vector2){ 0, 0 }, 0.0f, tint);
#endif
} }
// Draw multiple character (codepoints) // Draw multiple character (codepoints)