part: implement some functions (windows & display)
part: - remove mlx3ds_3dskey.h, instead use hid.h - add definitions of: - mlx_init() - mlx_new_window() - mlx_clear_window() - mlx_destroy_window() - mlx_pixel_put() - mlx_new_image() - mlx_get_data_addr() - mlx_put_image_to_window() - mlx_destroy_image() dev: - Makefile: add rule check_headers - Makefile: add variable FLAGS (call 'make rule FLAGS=flags' to add flags to compilation) - add /dev/norm.sh: nicer norminette - add tester in main(), and related utilsconsole.* docs: - make clear mlx_get_data_addr() docs
This commit is contained in:
parent
c7d0dba4fd
commit
13b93106ee
19 changed files with 766 additions and 141 deletions
26
Makefile
26
Makefile
|
@ -56,7 +56,7 @@ RSF := $(TOPDIR)/$(RESOURCES)/template.rsf
|
||||||
# options for code generation
|
# options for code generation
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft
|
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft
|
||||||
COMMON := -Wall -O2 -mword-relocations -fomit-frame-pointer -ffunction-sections $(ARCH) $(INCLUDE) -D__3DS__
|
COMMON := -Wall -O2 -mword-relocations -fomit-frame-pointer -ffunction-sections $(ARCH) $(INCLUDE) -D__3DS__ $(FLAGS)
|
||||||
CFLAGS := $(COMMON) -std=gnu99
|
CFLAGS := $(COMMON) -std=gnu99
|
||||||
CXXFLAGS := $(COMMON) -fno-rtti -fno-exceptions -std=gnu++11
|
CXXFLAGS := $(COMMON) -fno-rtti -fno-exceptions -std=gnu++11
|
||||||
ASFLAGS := $(ARCH)
|
ASFLAGS := $(ARCH)
|
||||||
|
@ -343,3 +343,27 @@ endef
|
||||||
#---------------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------------
|
||||||
endif
|
endif
|
||||||
#---------------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Added by Zy
|
||||||
|
# To check if the headers are protected and if they include everything they need.
|
||||||
|
check_headers :
|
||||||
|
@ERROR=0; \
|
||||||
|
for HEADER in $(wildcard *.h) $(wildcard **/*.h) $(wildcard *.hpp) $(wildcard **/*.hpp); \
|
||||||
|
do \
|
||||||
|
echo "check header $$HEADER..."; \
|
||||||
|
> __tmp_check_header.cpp echo "#include \"$$HEADER\""; \
|
||||||
|
>> __tmp_check_header.cpp echo "#include \"$$HEADER\""; \
|
||||||
|
>> __tmp_check_header.cpp echo "int main(void) {}"; \
|
||||||
|
$(CPP) $(INCLUDE) $(COMMON) $(LIBS) -o __tmp_check_header.out -c __tmp_check_header.cpp; \
|
||||||
|
if [ $$? -ne 0 ]; \
|
||||||
|
then \
|
||||||
|
ERROR=1; \
|
||||||
|
/bin/echo " ### error :( ###"; \
|
||||||
|
else \
|
||||||
|
/bin/echo " ### good :) ###"; \
|
||||||
|
fi; \
|
||||||
|
2> /dev/null rm -- "__tmp_check_header.out" "__tmp_check_header.c"; \
|
||||||
|
done; \
|
||||||
|
if [ $$ERROR -eq 0 ]; then true; else false; fi;
|
||||||
|
|
||||||
|
.PHONY : check_headers
|
||||||
|
|
19
dev/norm.sh
Executable file
19
dev/norm.sh
Executable file
|
@ -0,0 +1,19 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Use the norminette but without all these rules that make coding harder.
|
||||||
|
|
||||||
|
norminette | grep -v \
|
||||||
|
"INVALID_HEADER
|
||||||
|
VAR_DECL_START_FUNC
|
||||||
|
EMPTY_LINE_FUNCTION
|
||||||
|
TOO_MANY_ARGS
|
||||||
|
TOO_MANY_FUNCS
|
||||||
|
TOO_MANY_LINES
|
||||||
|
PREPROC_CONSTANT
|
||||||
|
MACRO_FUNC_FORBIDDEN
|
||||||
|
GLOBAL_VAR_DETECTED
|
||||||
|
WRONG_SCOPE_COMMENT
|
||||||
|
MULT_DECL_LINE
|
||||||
|
GOTO_FBIDDEN
|
||||||
|
LABEL_FBIDDEN
|
||||||
|
TERNARY_FBIDDEN"
|
|
@ -33,7 +33,6 @@
|
||||||
#ifndef MLX_H
|
#ifndef MLX_H
|
||||||
# define MLX_H
|
# define MLX_H
|
||||||
|
|
||||||
# include "mlx3ds_3dskey.h"
|
|
||||||
# include "mlx3ds_typealiases.h"
|
# include "mlx3ds_typealiases.h"
|
||||||
# include "mlx_init.h"
|
# include "mlx_init.h"
|
||||||
# include "mlx_window.h"
|
# include "mlx_window.h"
|
||||||
|
|
|
@ -1,95 +0,0 @@
|
||||||
/**
|
|
||||||
* mlx3ds_3dskey.h
|
|
||||||
* for the project "MinilibX for 3DS"
|
|
||||||
* by Zy
|
|
||||||
* at https://github.com/frzysk/mlx3ds
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enum of all the keys of the 3ds.
|
|
||||||
*
|
|
||||||
* These are the same constants defined in hid.h from devkitPro,
|
|
||||||
* but with documentation that basically repeat what the name
|
|
||||||
* of the constants already say.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MLX3DS_3DSKEY_H
|
|
||||||
# define MLX3DS_3DSKEY_H
|
|
||||||
|
|
||||||
# define BIT(n) 1U << n
|
|
||||||
|
|
||||||
/// @brief Represents a key of the 3DS.
|
|
||||||
typedef enum e_3dskey
|
|
||||||
{
|
|
||||||
/* BUTTONS */
|
|
||||||
|
|
||||||
/// @brief A button
|
|
||||||
KEY_A = BIT(0),
|
|
||||||
/// @brief B button
|
|
||||||
KEY_B = BIT(1),
|
|
||||||
/// @brief X button
|
|
||||||
KEY_X = BIT(10),
|
|
||||||
/// @brief Y button
|
|
||||||
KEY_Y = BIT(11),
|
|
||||||
/// @brief Select button
|
|
||||||
KEY_SELECT = BIT(2),
|
|
||||||
/// @brief Start button
|
|
||||||
KEY_START = BIT(3),
|
|
||||||
/// @brief R button
|
|
||||||
KEY_R = BIT(8),
|
|
||||||
/// @brief L button
|
|
||||||
KEY_L = BIT(9),
|
|
||||||
|
|
||||||
/* DIRECTIONS */
|
|
||||||
|
|
||||||
/// @brief D-Pad Right
|
|
||||||
KEY_DRIGHT = BIT(4),
|
|
||||||
/// @brief D-Pad Left
|
|
||||||
KEY_DLEFT = BIT(5),
|
|
||||||
/// @brief D-Pad Up
|
|
||||||
KEY_DUP = BIT(6),
|
|
||||||
/// @brief D-Pad Down
|
|
||||||
KEY_DDOWN = BIT(7),
|
|
||||||
/// @brief C-Pad Right
|
|
||||||
KEY_CPAD_RIGHT= BIT(28),
|
|
||||||
/// @brief C-Pad Left
|
|
||||||
KEY_CPAD_LEFT = BIT(29),
|
|
||||||
/// @brief C-Pad Up
|
|
||||||
KEY_CPAD_UP = BIT(30),
|
|
||||||
/// @brief C-Pad Down
|
|
||||||
KEY_CPAD_DOWN = BIT(31),
|
|
||||||
|
|
||||||
/* TOUCH */
|
|
||||||
|
|
||||||
// ??? unsure what KEY_TOUCH is... TODO
|
|
||||||
KEY_TOUCH = BIT(20),
|
|
||||||
|
|
||||||
/* New 3DS */
|
|
||||||
|
|
||||||
/// @brief C-Stick Right (only for New 3DS)
|
|
||||||
KEY_CSTICK_RIGHT = BIT(24),
|
|
||||||
/// @brief C-Stick Left (only for New 3DS)
|
|
||||||
KEY_CSTICK_LEFT = BIT(25),
|
|
||||||
/// @brief C-Stick Up (only for New 3DS)
|
|
||||||
KEY_CSTICK_UP = BIT(26),
|
|
||||||
/// @brief C-Stick Down (only for New 3DS)
|
|
||||||
KEY_CSTICK_DOWN = BIT(27),
|
|
||||||
/// @brief ZL button (only for New 3DS)
|
|
||||||
KEY_ZL = BIT(14),
|
|
||||||
/// @brief ZR button (only for New 3DS)
|
|
||||||
KEY_ZR = BIT(15),
|
|
||||||
|
|
||||||
// TODO implement catch-all directions?
|
|
||||||
/*
|
|
||||||
// ???
|
|
||||||
KEY_UP = KEY_DUP | KEY_CPAD_UP, ///< D-Pad Up or Circle Pad Up
|
|
||||||
// ???
|
|
||||||
KEY_DOWN = KEY_DDOWN | KEY_CPAD_DOWN, ///< D-Pad Down or Circle Pad Down
|
|
||||||
// ???
|
|
||||||
KEY_LEFT = KEY_DLEFT | KEY_CPAD_LEFT, ///< D-Pad Left or Circle Pad Left
|
|
||||||
// ???
|
|
||||||
KEY_RIGHT = KEY_DRIGHT | KEY_CPAD_RIGHT, ///< D-Pad Right or Circle PadRight
|
|
||||||
*/
|
|
||||||
} t_3dskey;
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -27,7 +27,6 @@
|
||||||
# define MLX_HOOK_H
|
# define MLX_HOOK_H
|
||||||
|
|
||||||
# include "mlx3ds_typealiases.h"
|
# include "mlx3ds_typealiases.h"
|
||||||
# include "mlx3ds_3dskey.h"
|
|
||||||
|
|
||||||
/// @brief Doesn't do anything, the 3DS doesn't have a mouse.
|
/// @brief Doesn't do anything, the 3DS doesn't have a mouse.
|
||||||
///
|
///
|
||||||
|
@ -43,14 +42,14 @@ int _mlx_mouse_hook(t_win win_ptr, int (*funct_ptr)(), void *param);
|
||||||
/// @param win_ptr Window to affect.
|
/// @param win_ptr Window to affect.
|
||||||
/// @param funct_ptr Function to call when the event occurs. `keycode` is the
|
/// @param funct_ptr Function to call when the event occurs. `keycode` is the
|
||||||
/// key pressed (note that they are obviously different than
|
/// key pressed (note that they are obviously different than
|
||||||
/// the keyboard ones, see 'mlx3ds_3ds_key.h')).
|
/// the keyboard ones, use the KEY_* constants from hid.h)).
|
||||||
/// (TODO what was the name of the key constants use with mlx?)
|
/// (TODO what was the name of the key constants use with mlx?)
|
||||||
/// `param` is set as the address given to mlx_key_hook().
|
/// `param` is set as the address given to mlx_key_hook().
|
||||||
/// The return value is unused.
|
/// The return value is unused.
|
||||||
/// @param param Address to pass to the function every time it is called.
|
/// @param param Address to pass to the function every time it is called.
|
||||||
/// @return Unused.
|
/// @return Unused.
|
||||||
int _mlx_key_hook(t_win win_ptr,
|
int _mlx_key_hook(t_win win_ptr,
|
||||||
int (*funct_ptr)(t_3dskey keycode, void *param), void *param);
|
int (*funct_ptr)(int keycode, void *param), void *param);
|
||||||
|
|
||||||
/// @brief Assign a function which will be called when the window should be
|
/// @brief Assign a function which will be called when the window should be
|
||||||
/// redrawn.
|
/// redrawn.
|
||||||
|
|
|
@ -37,22 +37,23 @@
|
||||||
/// @param width Desired width of the image.
|
/// @param width Desired width of the image.
|
||||||
/// @param height Desired height of the image.
|
/// @param height Desired height of the image.
|
||||||
/// @return A reference to the image. NULL if failed.
|
/// @return A reference to the image. NULL if failed.
|
||||||
t_image _mlx_new_image(void *mlx_ptr, int width, int height);
|
t_image mlx_new_image(void *mlx_ptr, int width, int height);
|
||||||
|
|
||||||
/// @brief Get an address containing all the pixel values of the image. The user
|
/// @brief Get an address containing all the pixel values of the image. The user
|
||||||
/// can then modify the image using this pointer directly.
|
/// can then modify the image using this pointer directly.
|
||||||
///
|
///
|
||||||
/// @param img_ptr Image to use.
|
/// @param img_ptr Image to use.
|
||||||
/// @param bits_per_pixel Will be filled with the number of bits used for each
|
/// @param bits_per_pixel Will be filled with the number of bits used for each
|
||||||
/// pixel. Will always be 24.
|
/// pixel. Can be NULL, result will always be 24.
|
||||||
/// @param size_line Will be filled with the number of bytes used to store
|
/// @param size_line Will be filled with the number of bytes used to store
|
||||||
/// a line of the image, aka 3 * width.
|
/// a line of the image, aka 3 * width. Can be NULL.
|
||||||
/// @param endian Will be filled with the endianness of all color values.
|
/// @param endian Will be filled with the endianness of all color values.
|
||||||
/// 1 for big endian, 0 for little endian. Will always be 1.
|
/// 1 for big endian, 0 for little endian. Can be NULL, result
|
||||||
|
/// will always be 1.
|
||||||
/// @return Address to the data of the image.
|
/// @return Address to the data of the image.
|
||||||
/// Use `data[y * size_line + x * 3]` to get the first color value (red)
|
/// Use `data[y * size_line + x * 3]` to get the first color value (red)
|
||||||
/// of a specific pixel.
|
/// of a specific pixel.
|
||||||
char *_mlx_get_data_addr(t_image img_ptr, int *bits_per_pixel,
|
char *mlx_get_data_addr(t_image img_ptr, int *bits_per_pixel,
|
||||||
int *size_line, int *endian);
|
int *size_line, int *endian);
|
||||||
|
|
||||||
/// @brief Draw an image on the window.
|
/// @brief Draw an image on the window.
|
||||||
|
@ -63,7 +64,7 @@ char *_mlx_get_data_addr(t_image img_ptr, int *bits_per_pixel,
|
||||||
/// @param x x position of the image to draw.
|
/// @param x x position of the image to draw.
|
||||||
/// @param y y position of the image to draw.
|
/// @param y y position of the image to draw.
|
||||||
/// @return Unused.
|
/// @return Unused.
|
||||||
int _mlx_put_image_to_window(t_mlx mlx_ptr, t_win win_ptr, t_image img_ptr,
|
int mlx_put_image_to_window(t_mlx mlx_ptr, t_win win_ptr, t_image img_ptr,
|
||||||
int x, int y);
|
int x, int y);
|
||||||
|
|
||||||
// ???
|
// ???
|
||||||
|
@ -79,6 +80,6 @@ t_image _mlx_xpm_file_to_image(void *mlx_ptr, char *filename,
|
||||||
/// @param mlx_ptr mlx connection identifier returned by mlx_init().
|
/// @param mlx_ptr mlx connection identifier returned by mlx_init().
|
||||||
/// @param img_ptr Image to destroy.
|
/// @param img_ptr Image to destroy.
|
||||||
/// @return Unused.
|
/// @return Unused.
|
||||||
int _mlx_destroy_image(t_mlx mlx_ptr, t_image img_ptr);
|
int mlx_destroy_image(t_mlx mlx_ptr, t_image img_ptr);
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -35,6 +35,8 @@
|
||||||
///
|
///
|
||||||
/// @return The mlx connection identifier to use for all other functions.
|
/// @return The mlx connection identifier to use for all other functions.
|
||||||
/// NULL if failed.
|
/// NULL if failed.
|
||||||
t_mlx _mlx_init(void); // TODO should call this before REALLY anything else?
|
t_mlx mlx_init(void); // TODO should call this before REALLY anything else?
|
||||||
|
|
||||||
|
// TODO a mlx_end() necessary?
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -41,7 +41,7 @@
|
||||||
/// @param y y position of the pixel to set.
|
/// @param y y position of the pixel to set.
|
||||||
/// @param color Color to use in 0x00RRGGBB format.
|
/// @param color Color to use in 0x00RRGGBB format.
|
||||||
/// @return Unused.
|
/// @return Unused.
|
||||||
int _mlx_pixel_put(t_mlx mlx_ptr, t_win win_ptr, int x, int y, int color);
|
int mlx_pixel_put(t_mlx mlx_ptr, t_win win_ptr, int x, int y, int color);
|
||||||
|
|
||||||
/// @brief Print text on the window.
|
/// @brief Print text on the window.
|
||||||
///
|
///
|
||||||
|
|
|
@ -41,20 +41,21 @@
|
||||||
/// Maximum 240 to be able to adapt to the top screen of the 3DS.
|
/// Maximum 240 to be able to adapt to the top screen of the 3DS.
|
||||||
/// @param title The title of the window. Unused in the 3DS.
|
/// @param title The title of the window. Unused in the 3DS.
|
||||||
/// @return A reference to the window. NULL if failed.
|
/// @return A reference to the window. NULL if failed.
|
||||||
t_win _mlx_new_window(t_mlx mlx_ptr, int size_x, int size_y, char *title);
|
t_win mlx_new_window(t_mlx mlx_ptr, int size_x, int size_y,
|
||||||
|
const char *title);
|
||||||
|
|
||||||
/// @brief Clear the window in black.
|
/// @brief Clear the window in black.
|
||||||
///
|
///
|
||||||
/// @param mlx_ptr mlx connection identifier returned by mlx_init().
|
/// @param mlx_ptr mlx connection identifier returned by mlx_init().
|
||||||
/// @param win_ptr Window to affect.
|
/// @param win_ptr Window to affect.
|
||||||
/// @return Unused.
|
/// @return Unused.
|
||||||
int _mlx_clear_window(t_mlx mlx_ptr, t_win win_ptr);
|
int mlx_clear_window(t_mlx mlx_ptr, t_win win_ptr);
|
||||||
|
|
||||||
/// @brief Destroy a window.
|
/// @brief Destroy a window.
|
||||||
///
|
///
|
||||||
/// @param mlx_ptr mlx connection identifier returned by mlx_init().
|
/// @param mlx_ptr mlx connection identifier returned by mlx_init().
|
||||||
/// @param win_ptr Window to destroy.
|
/// @param win_ptr Window to destroy.
|
||||||
/// @return Unused.
|
/// @return Unused.
|
||||||
int _mlx_destroy_window(t_mlx mlx_ptr, t_win win_ptr);
|
int mlx_destroy_window(t_mlx mlx_ptr, t_win win_ptr);
|
||||||
|
|
||||||
#endif
|
#endif
|
52
include/utilsconsole.hpp
Normal file
52
include/utilsconsole.hpp
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/**
|
||||||
|
* utilsconsole.hpp
|
||||||
|
* by Zy
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* utilsconsole.hpp (uc_*() functions)
|
||||||
|
* Utility functions for the 3DS console.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
/// @brief To use with uc_menu(): Represent an element of the menu.
|
||||||
|
typedef struct {
|
||||||
|
/// @brief Displayed name.
|
||||||
|
string name;
|
||||||
|
/// @brief true if this button can be used to change the value of a number.
|
||||||
|
bool is_number_prompt;
|
||||||
|
/// @brief Only if is_number_prompt is true: the number to change.
|
||||||
|
int *value;
|
||||||
|
/// @brief Only if is_number_prompt is true: the minimum value possible for
|
||||||
|
/// value.
|
||||||
|
int min;
|
||||||
|
/// @brief Only if is_number_prompt is true: the maximum value possible for
|
||||||
|
/// value.
|
||||||
|
int max;
|
||||||
|
} s_uc_menu_element;
|
||||||
|
|
||||||
|
/// @brief Display a menu with several items in the console.
|
||||||
|
/// @details
|
||||||
|
/// Non-blocking function, must be called in loop.
|
||||||
|
/// Only one menu can work at the same time. 'elements' must not change in
|
||||||
|
/// address.
|
||||||
|
/// @param elements A pointer to a vector of all the elements of the menu.
|
||||||
|
/// @return The index of the confirmed element. If none, return -1.
|
||||||
|
int uc_menu(vector<s_uc_menu_element> &elements);
|
||||||
|
|
||||||
|
/// @brief Display a menu quickly using only confirm buttons.
|
||||||
|
/// @details
|
||||||
|
/// Blocking function. Will return -1 if aptMainLoop() becomes false.
|
||||||
|
/// @param str Text representing each element. The last parameter must be NULL.
|
||||||
|
/// @return The index of the confirmed element.
|
||||||
|
int uc_menu_quick(const char *str, ...);
|
||||||
|
|
||||||
|
/// @brief Blocks the program until the user presses A.
|
||||||
|
/// @details Will also return if aptMainLoop() becomes false.
|
||||||
|
void uc_pause(void);
|
189
source/main.cpp
189
source/main.cpp
|
@ -1,25 +1,182 @@
|
||||||
#include <3ds.h>
|
extern "C" {
|
||||||
#include <stdio.h>
|
#include "mlx.h"
|
||||||
|
#include "3ds.h"
|
||||||
|
}
|
||||||
|
#include <iostream>
|
||||||
|
#include <string.h>
|
||||||
|
#include "utilsconsole.hpp"
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
using namespace std;
|
||||||
gfxInitDefault();
|
|
||||||
consoleInit(GFX_TOP, NULL);
|
|
||||||
|
|
||||||
printf("Test Code::Blocks project!");
|
static void draw_rainbow_image(t_mlx mlx, t_win win, int x, int y)
|
||||||
|
{
|
||||||
|
cout << "Draw rainbow image at (" << x << "," << y << ")..." << endl;
|
||||||
|
uc_pause();
|
||||||
|
{
|
||||||
|
static const u32 red = 0xFF0000;
|
||||||
|
static const u32 green = 0x00FF00;
|
||||||
|
static const u32 blue = 0x0000FF;
|
||||||
|
t_image img = mlx_new_image(mlx, 30, 30);
|
||||||
|
char *img_data = mlx_get_data_addr(img, NULL, NULL, NULL);
|
||||||
|
for (int x = 0; x < 30; x++)
|
||||||
|
{
|
||||||
|
for (int y = 0; y < 20; y++)
|
||||||
|
{
|
||||||
|
if (x < 10)
|
||||||
|
memcpy(img_data + 3 * (y * 30 + x), &red, 3);
|
||||||
|
else if (x < 20)
|
||||||
|
memcpy(img_data + 3 * (y * 30 + x), &green, 3);
|
||||||
|
else
|
||||||
|
memcpy(img_data + 3 * (y * 30 + x), &blue, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mlx_put_image_to_window(mlx, win, img, x, y);
|
||||||
|
mlx_destroy_image(mlx, img);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
printf("\x1b[20;15HPress Start to exit.");
|
int main(void) {
|
||||||
|
void *const mlx = mlx_init();
|
||||||
|
void *win;
|
||||||
|
|
||||||
while(aptMainLoop()) {
|
// MENU
|
||||||
gspWaitForVBlank();
|
{
|
||||||
hidScanInput();
|
switch (uc_menu_quick("pixels", "images", "quit", NULL))
|
||||||
|
{
|
||||||
if(hidKeysDown() & KEY_START)
|
case 0:
|
||||||
|
goto pixels;
|
||||||
break;
|
break;
|
||||||
|
case 1:
|
||||||
gfxFlushBuffers();
|
goto images;
|
||||||
gfxSwapBuffers();
|
break;
|
||||||
|
}
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pixels:
|
||||||
|
cout << "create window..." << endl;
|
||||||
|
uc_pause();
|
||||||
|
win = mlx_new_window(mlx, 400, 240, "hey");
|
||||||
|
|
||||||
|
cout << "clear window..." << endl;
|
||||||
|
uc_pause();
|
||||||
|
mlx_clear_window(mlx, win);
|
||||||
|
|
||||||
|
cout
|
||||||
|
<< "Put pixels for red green and blue" << endl
|
||||||
|
<< "at the top-left corner..." << endl;
|
||||||
|
uc_pause();
|
||||||
|
{
|
||||||
|
int block_y = 20;
|
||||||
|
for (
|
||||||
|
int block_x = 20, color = 0xFF0000;
|
||||||
|
block_x <= 60;
|
||||||
|
block_x += 20, color = color >> 8
|
||||||
|
)
|
||||||
|
for (int x = 0; x < 10; x++)
|
||||||
|
for (int y = 0; y < 10; y++)
|
||||||
|
mlx_pixel_put(mlx, win, block_x + x, block_y + y, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << "clear window..." << endl;
|
||||||
|
uc_pause();
|
||||||
|
mlx_clear_window(mlx, win);
|
||||||
|
|
||||||
|
cout << "destroy window..." << endl;
|
||||||
|
uc_pause();
|
||||||
|
mlx_destroy_window(mlx, win);
|
||||||
|
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
images:
|
||||||
|
cout << "create window..." << endl;
|
||||||
|
uc_pause();
|
||||||
|
win = mlx_new_window(mlx, 400, 240, "hoi");
|
||||||
|
|
||||||
|
cout << "clear window..." << endl;
|
||||||
|
uc_pause();
|
||||||
|
mlx_clear_window(mlx, win);
|
||||||
|
|
||||||
|
draw_rainbow_image(mlx, win, 185, 110);
|
||||||
|
draw_rainbow_image(mlx, win, -15, 100);
|
||||||
|
draw_rainbow_image(mlx, win, 385, 120);
|
||||||
|
draw_rainbow_image(mlx, win, 170, -10);
|
||||||
|
draw_rainbow_image(mlx, win, 200, 230);
|
||||||
|
draw_rainbow_image(mlx, win, -15, -10);
|
||||||
|
draw_rainbow_image(mlx, win, 385, -10);
|
||||||
|
draw_rainbow_image(mlx, win, -15, 230);
|
||||||
|
draw_rainbow_image(mlx, win, 385, 230);
|
||||||
|
|
||||||
|
cout << "Draw RG image at (20,10)..." << endl;
|
||||||
|
uc_pause();
|
||||||
|
{
|
||||||
|
t_image img = mlx_new_image(mlx, 30, 20);
|
||||||
|
char *img_data = mlx_get_data_addr(img, NULL, NULL, NULL);
|
||||||
|
for (int x = 0; x < 30; x++)
|
||||||
|
{
|
||||||
|
for (int y = 0; y < 20; y++)
|
||||||
|
{
|
||||||
|
u32 color =
|
||||||
|
((0xFF0000 * x / 30) & 0xFF0000)
|
||||||
|
| ((0x00FF00 * y / 20) & 0x00FF00);
|
||||||
|
memcpy(img_data + 3 * (y * 30 + x), &color, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mlx_put_image_to_window(mlx, win, img, 20, 10);
|
||||||
|
mlx_destroy_image(mlx, img);
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << "Draw GB image at (50,0)..." << endl;
|
||||||
|
uc_pause();
|
||||||
|
{
|
||||||
|
t_image img = mlx_new_image(mlx, 10, 50);
|
||||||
|
char *img_data = mlx_get_data_addr(img, NULL, NULL, NULL);
|
||||||
|
for (int x = 0; x < 10; x++)
|
||||||
|
{
|
||||||
|
for (int y = 0; y < 50; y++)
|
||||||
|
{
|
||||||
|
u32 color =
|
||||||
|
((0x00FF00 * x / 10) & 0x00FF00)
|
||||||
|
| ((0x0000FF * y / 50) & 0x0000FF);
|
||||||
|
memcpy(img_data + 3 * (y * 10 + x), &color, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mlx_put_image_to_window(mlx, win, img, 50, 0);
|
||||||
|
mlx_destroy_image(mlx, img);
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << "Draw BR image at (200,100)..." << endl;
|
||||||
|
uc_pause();
|
||||||
|
{
|
||||||
|
t_image img = mlx_new_image(mlx, 100, 100);
|
||||||
|
char *img_data = mlx_get_data_addr(img, NULL, NULL, NULL);
|
||||||
|
for (int x = 0; x < 100; x++)
|
||||||
|
{
|
||||||
|
for (int y = 0; y < 100; y++)
|
||||||
|
{
|
||||||
|
u32 color =
|
||||||
|
((0x0000FF * x / 100) & 0x0000FF)
|
||||||
|
| ((0xFF0000 * y / 100) & 0xFF0000);
|
||||||
|
memcpy(img_data + 3 * (y * 100 + x), &color, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mlx_put_image_to_window(mlx, win, img, 200, 100);
|
||||||
|
mlx_destroy_image(mlx, img);
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << "clear window..." << endl;
|
||||||
|
uc_pause();
|
||||||
|
mlx_clear_window(mlx, win);
|
||||||
|
|
||||||
|
cout << "destroy window..." << endl;
|
||||||
|
uc_pause();
|
||||||
|
mlx_destroy_window(mlx, win);
|
||||||
|
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
end:
|
||||||
|
cout << "Exit..." << endl;
|
||||||
|
uc_pause();
|
||||||
|
|
||||||
gfxExit();
|
gfxExit();
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
123
source/mlx_image.c
Normal file
123
source/mlx_image.c
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
/**
|
||||||
|
* mlx_image.c
|
||||||
|
* for the project "MinilibX for 3DS"
|
||||||
|
* by Zy
|
||||||
|
* at https://github.com/frzysk/mlx3ds
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mlx_image.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "mlx_internal.h"
|
||||||
|
#include "mlx_inline.c"
|
||||||
|
|
||||||
|
t_image mlx_new_image(void *mlx_ptr, int width, int height)
|
||||||
|
{
|
||||||
|
t_internal_image *r;
|
||||||
|
|
||||||
|
(void)mlx_ptr;
|
||||||
|
r = NULL;
|
||||||
|
r = malloc(sizeof(t_internal_image));
|
||||||
|
if (!r)
|
||||||
|
goto error;
|
||||||
|
r->data = NULL;
|
||||||
|
r->data = malloc(width * height * 3 * sizeof(u8));
|
||||||
|
if (!r->data)
|
||||||
|
goto error;
|
||||||
|
r->width = width;
|
||||||
|
r->height = height;
|
||||||
|
return (r);
|
||||||
|
|
||||||
|
error:
|
||||||
|
free(r);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mlx_destroy_image(t_mlx mlx_ptr, t_image img_ptr)
|
||||||
|
{
|
||||||
|
if (img_ptr)
|
||||||
|
free(((t_internal_image *)img_ptr)->data);
|
||||||
|
free(img_ptr);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *mlx_get_data_addr(t_image img_ptr, int *bits_per_pixel,
|
||||||
|
int *size_line, int *endian)
|
||||||
|
{
|
||||||
|
if (bits_per_pixel)
|
||||||
|
*bits_per_pixel = 24;
|
||||||
|
if (size_line)
|
||||||
|
*size_line = 3 * ((t_internal_image *)img_ptr)->width;
|
||||||
|
if (endian)
|
||||||
|
*endian = 1;
|
||||||
|
return ((char *)((t_internal_image *)img_ptr)->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Return the minimum between a and b.
|
||||||
|
/// @param a Number a.
|
||||||
|
/// @param b Number b.
|
||||||
|
/// @return The result.
|
||||||
|
static inline int min(int a, int b)
|
||||||
|
{
|
||||||
|
return (a < b ? a : b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Return the maximum between a and b.
|
||||||
|
/// @param a Number a.
|
||||||
|
/// @param b Number b.
|
||||||
|
/// @return The result.
|
||||||
|
static inline int max(int a, int b)
|
||||||
|
{
|
||||||
|
return (a > b ? a : b);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mlx_put_image_to_window(t_mlx mlx_ptr, t_win win_ptr, t_image img_ptr,
|
||||||
|
int x, int y)
|
||||||
|
{
|
||||||
|
// buffers
|
||||||
|
u8 *frame_data, *img_data;
|
||||||
|
int // dimensions
|
||||||
|
frame_width, frame_height, img_width, img_height,
|
||||||
|
// interval of pixels to draw, to avoid drawing outside of the buffer
|
||||||
|
min_x_on_screen, max_x_on_screen, min_y_on_screen, max_y_on_screen,
|
||||||
|
// position relative to frame
|
||||||
|
x_on_screen, y_on_screen;
|
||||||
|
// variables that contain results of constant expressions
|
||||||
|
int a, b;
|
||||||
|
u8 *c, *d, *e, *f;
|
||||||
|
|
||||||
|
mlx3ds_internal_drawstart(mlx_ptr, win_ptr);
|
||||||
|
frame_data = ((t_internal_win *)win_ptr)->framebuffer;
|
||||||
|
frame_width = ((t_internal_win *)win_ptr)->framebuffer_width;
|
||||||
|
frame_height = ((t_internal_win *)win_ptr)->framebuffer_height;
|
||||||
|
img_data = ((t_internal_image *)img_ptr)->data;
|
||||||
|
img_width = ((t_internal_image *)img_ptr)->width;
|
||||||
|
img_height = ((t_internal_image *)img_ptr)->height;
|
||||||
|
min_x_on_screen = max(x, 0);
|
||||||
|
max_x_on_screen = min(x + img_width, frame_width);
|
||||||
|
min_y_on_screen = max(y, 0);
|
||||||
|
max_y_on_screen = min(y + img_height, frame_height);
|
||||||
|
a = 3 * img_width;
|
||||||
|
b = 3 * frame_height;
|
||||||
|
c = img_data - 3 * x - a * y;
|
||||||
|
d = frame_data - 3 + b;
|
||||||
|
|
||||||
|
x_on_screen = min_x_on_screen;
|
||||||
|
while (x_on_screen < max_x_on_screen)
|
||||||
|
{
|
||||||
|
e = c + 3 * x_on_screen;
|
||||||
|
f = d + b * x_on_screen;
|
||||||
|
|
||||||
|
y_on_screen = min_y_on_screen;
|
||||||
|
while (y_on_screen < max_y_on_screen)
|
||||||
|
{
|
||||||
|
mlx_inline_drawcolor(
|
||||||
|
f - 3 * y_on_screen,
|
||||||
|
e + a * y_on_screen);
|
||||||
|
y_on_screen++;
|
||||||
|
}
|
||||||
|
x_on_screen++;
|
||||||
|
}
|
||||||
|
mlx3ds_internal_drawend(mlx_ptr, win_ptr);
|
||||||
|
return (0);
|
||||||
|
}
|
29
source/mlx_init.c
Normal file
29
source/mlx_init.c
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/**
|
||||||
|
* mlx_init.c
|
||||||
|
* for the project "MinilibX for 3DS"
|
||||||
|
* by Zy
|
||||||
|
* at https://github.com/frzysk/mlx3ds
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mlx_init.h"
|
||||||
|
|
||||||
|
#include "mlx_internal.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "3ds.h"
|
||||||
|
|
||||||
|
static t_internal_mlx g_internal_mlx = {
|
||||||
|
.is_init_called = false,
|
||||||
|
.top_window = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
t_mlx mlx_init(void)
|
||||||
|
{
|
||||||
|
if (g_internal_mlx.is_init_called)
|
||||||
|
mlx3ds_internal_fatalerror("mlx_init() must be called only once");
|
||||||
|
g_internal_mlx.is_init_called = true;
|
||||||
|
gfxInitDefault();
|
||||||
|
gfxSetDoubleBuffering(GFX_TOP, false);
|
||||||
|
gfxSetDoubleBuffering(GFX_BOTTOM, false);
|
||||||
|
consoleInit(GFX_BOTTOM, NULL);
|
||||||
|
return (&g_internal_mlx);
|
||||||
|
}
|
31
source/mlx_inline.c
Normal file
31
source/mlx_inline.c
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/**
|
||||||
|
* mlx_inline.c
|
||||||
|
* for the project "MinilibX for 3DS"
|
||||||
|
* by Zy
|
||||||
|
* at https://github.com/frzysk/mlx3ds
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "3ds.h"
|
||||||
|
|
||||||
|
/// @brief Write a color at a specific location of the memory,
|
||||||
|
/// the 3 color values will be in the same order.
|
||||||
|
/// It's basically a memcpy of 3 bytes.
|
||||||
|
/// @param dest Address to the first color value of the destination.
|
||||||
|
/// @param src Address to the first color value of the source.
|
||||||
|
inline void mlx_inline_drawcolor(u8 *dest, u8 *src)
|
||||||
|
{
|
||||||
|
dest[0] = src[0];
|
||||||
|
dest[1] = src[1];
|
||||||
|
dest[2] = src[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Write a color at a specific location of the memory,
|
||||||
|
/// the 3 color values will be in opposite order.
|
||||||
|
/// @param dest Address to the first color value of the destination.
|
||||||
|
/// @param src Address to the first color value of the source.
|
||||||
|
inline void mlx_inline_drawcolor_invert(u8 *dest, u8 *src)
|
||||||
|
{
|
||||||
|
dest[2] = src[0];
|
||||||
|
dest[1] = src[1];
|
||||||
|
dest[0] = src[2];
|
||||||
|
}
|
35
source/mlx_internal.cpp
Normal file
35
source/mlx_internal.cpp
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
/**
|
||||||
|
* mlx_internal.cpp
|
||||||
|
* for the project "MinilibX for 3DS"
|
||||||
|
* by Zy
|
||||||
|
* at https://github.com/frzysk/mlx3ds
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "utilsconsole.hpp"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "mlx_internal.h"
|
||||||
|
#include "3ds.h"
|
||||||
|
|
||||||
|
void mlx3ds_internal_fatalerror(const char *msg)
|
||||||
|
{
|
||||||
|
consoleInit(GFX_BOTTOM, NULL);
|
||||||
|
printf("\e[0;31m[mlx3ds] Fatal error:\e[0m\n%s\n", msg);
|
||||||
|
uc_pause();
|
||||||
|
}
|
||||||
|
|
||||||
|
void mlx3ds_internal_drawstart(
|
||||||
|
t_internal_mlx *mlx_ptr, t_internal_win *win_ptr)
|
||||||
|
{
|
||||||
|
win_ptr->framebuffer = gfxGetFramebuffer(GFX_TOP, GFX_LEFT,
|
||||||
|
&win_ptr->framebuffer_height, &win_ptr->framebuffer_width);
|
||||||
|
gspWaitForVBlank();
|
||||||
|
}
|
||||||
|
|
||||||
|
void mlx3ds_internal_drawend(
|
||||||
|
t_internal_mlx *mlx_ptr, t_internal_win *win_ptr)
|
||||||
|
{
|
||||||
|
gfxFlushBuffers();
|
||||||
|
gfxSwapBuffers();
|
||||||
|
}
|
||||||
|
}
|
71
source/mlx_internal.h
Normal file
71
source/mlx_internal.h
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
/**
|
||||||
|
* mlx_internal.c
|
||||||
|
* for the project "MinilibX for 3DS"
|
||||||
|
* by Zy
|
||||||
|
* at https://github.com/frzysk/mlx3ds
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal utils of the mlx3ds.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "3ds.h"
|
||||||
|
|
||||||
|
/// @brief Write an error message and exit the program.
|
||||||
|
///
|
||||||
|
/// @param msg Message to write. Must use less than 38 colons.
|
||||||
|
void mlx3ds_internal_fatalerror(const char *msg);
|
||||||
|
|
||||||
|
typedef struct s_internal_win t_internal_win;
|
||||||
|
|
||||||
|
/// @brief Content of the mlx connection identifier.
|
||||||
|
typedef struct s_internal_mlx
|
||||||
|
{
|
||||||
|
/// @brief is true after mlx_init() was called, is false before.
|
||||||
|
bool is_init_called;
|
||||||
|
/// @brief Window displayed on the top screen.
|
||||||
|
t_internal_win *top_window;
|
||||||
|
} t_internal_mlx;
|
||||||
|
|
||||||
|
/// @brief Represents a window.
|
||||||
|
typedef struct s_internal_win
|
||||||
|
{
|
||||||
|
/// @brief mlx connection identifier
|
||||||
|
t_internal_mlx *mlx;
|
||||||
|
/// @brief Width of the window
|
||||||
|
int width;
|
||||||
|
/// @brief Height of the window
|
||||||
|
int height;
|
||||||
|
/// @brief Buffer of the screen.
|
||||||
|
u8 *framebuffer;
|
||||||
|
/// @brief Width of the screen (on x).
|
||||||
|
u16 framebuffer_width;
|
||||||
|
/// @brief Height of the screen (on y).
|
||||||
|
u16 framebuffer_height;
|
||||||
|
} t_internal_win;
|
||||||
|
|
||||||
|
/// @brief Represents an image in memory.
|
||||||
|
typedef struct s_internal_image
|
||||||
|
{
|
||||||
|
/// @brief Width of the image
|
||||||
|
int width;
|
||||||
|
/// @brief Height of the image
|
||||||
|
int height;
|
||||||
|
/// @brief Address of the image data. Returned by mlx_get_data_addr().
|
||||||
|
u8 *data;
|
||||||
|
} t_internal_image;
|
||||||
|
|
||||||
|
/// @brief To call before drawing. Init winptr->framebuffer.
|
||||||
|
///
|
||||||
|
/// @param mlx_ptr mlx connection identifier
|
||||||
|
/// @param win_ptr Reference to the window to draw on.
|
||||||
|
void mlx3ds_internal_drawstart(
|
||||||
|
t_internal_mlx *mlx_ptr, t_internal_win *win_ptr);
|
||||||
|
|
||||||
|
/// @brief To call when finish drawing. Flush and swap buffers.
|
||||||
|
///
|
||||||
|
/// @param mlx_ptr mlx connection identifier
|
||||||
|
/// @param win_ptr Reference to the window to draw on.
|
||||||
|
void mlx3ds_internal_drawend(
|
||||||
|
t_internal_mlx *mlx_ptr, t_internal_win *win_ptr);
|
32
source/mlx_put.c
Normal file
32
source/mlx_put.c
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/**
|
||||||
|
* mlx_put.c
|
||||||
|
* for the project "MinilibX for 3DS"
|
||||||
|
* by Zy
|
||||||
|
* at https://github.com/frzysk/mlx3ds
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mlx_put.h"
|
||||||
|
|
||||||
|
#include "mlx_internal.h"
|
||||||
|
#include "mlx_inline.c"
|
||||||
|
|
||||||
|
int mlx_pixel_put(t_mlx mlx_ptr, t_win win_ptr, int x, int y, int color)
|
||||||
|
{
|
||||||
|
u8 *frame;
|
||||||
|
|
||||||
|
mlx3ds_internal_drawstart(mlx_ptr, win_ptr);
|
||||||
|
|
||||||
|
if (x < 0 || x >= ((t_internal_win *)win_ptr)->framebuffer_width
|
||||||
|
|| y < 0 || y >= ((t_internal_win *)win_ptr)->framebuffer_height)
|
||||||
|
return (0);
|
||||||
|
frame = ((t_internal_win *)win_ptr)->framebuffer;
|
||||||
|
mlx_inline_drawcolor(
|
||||||
|
frame + 3 * (
|
||||||
|
(x + 1) * ((t_internal_win *)win_ptr)->framebuffer_height - y - 1
|
||||||
|
),
|
||||||
|
(u8 *)&color);
|
||||||
|
|
||||||
|
mlx3ds_internal_drawend(mlx_ptr, win_ptr);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
52
source/mlx_window.c
Normal file
52
source/mlx_window.c
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/**
|
||||||
|
* mlx_window.c
|
||||||
|
* for the project "MinilibX for 3DS"
|
||||||
|
* by Zy
|
||||||
|
* at https://github.com/frzysk/mlx3ds
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mlx_window.h"
|
||||||
|
|
||||||
|
#include "3ds.h"
|
||||||
|
#include "mlx_internal.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
t_win mlx_new_window(t_mlx mlx_ptr, int size_x, int size_y, const char *title)
|
||||||
|
{
|
||||||
|
t_internal_win *r;
|
||||||
|
|
||||||
|
(void)title;
|
||||||
|
if (size_x > GSP_SCREEN_HEIGHT_TOP || size_y > GSP_SCREEN_WIDTH)
|
||||||
|
mlx3ds_internal_fatalerror("Window too big for the screen");
|
||||||
|
r = malloc(sizeof(t_internal_win));
|
||||||
|
if (!r)
|
||||||
|
return (NULL);
|
||||||
|
r->mlx = mlx_ptr;
|
||||||
|
r->width = size_x;
|
||||||
|
r->height = size_y;
|
||||||
|
r->framebuffer = NULL;
|
||||||
|
return (r);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mlx_clear_window(t_mlx mlx_ptr, t_win win_ptr)
|
||||||
|
{
|
||||||
|
u8 *frame_i;
|
||||||
|
u8 *frame;
|
||||||
|
|
||||||
|
mlx3ds_internal_drawstart(mlx_ptr, win_ptr);
|
||||||
|
frame = ((t_internal_win *)win_ptr)->framebuffer;
|
||||||
|
frame_i = frame
|
||||||
|
+ 3 * ((t_internal_win *)win_ptr)->framebuffer_width
|
||||||
|
* ((t_internal_win *)win_ptr)->framebuffer_height;
|
||||||
|
while (--frame_i >= frame)
|
||||||
|
*frame_i = 0x00;
|
||||||
|
mlx3ds_internal_drawend(mlx_ptr, win_ptr);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mlx_destroy_window(t_mlx mlx_ptr, t_win win_ptr)
|
||||||
|
{
|
||||||
|
((t_internal_mlx *)mlx_ptr)->top_window = NULL;
|
||||||
|
free(win_ptr);
|
||||||
|
return (0);
|
||||||
|
}
|
93
source/utilsconsole.cpp
Normal file
93
source/utilsconsole.cpp
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
/**
|
||||||
|
* utilsconsole.cpp
|
||||||
|
* by Zy
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "utilsconsole.hpp"
|
||||||
|
|
||||||
|
#include <3ds.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
int uc_menu(vector<s_uc_menu_element> &elements) {
|
||||||
|
static void *lastElements = NULL;
|
||||||
|
static size_t selected = 0;
|
||||||
|
|
||||||
|
bool confirmed = false;
|
||||||
|
|
||||||
|
if (&elements != lastElements) {
|
||||||
|
// init if new menu
|
||||||
|
consoleClear();
|
||||||
|
lastElements = &elements;
|
||||||
|
selected = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// read inputs
|
||||||
|
hidScanInput();
|
||||||
|
if (hidKeysDown() & KEY_UP) {
|
||||||
|
if (selected-- == 0)
|
||||||
|
selected += elements.size();
|
||||||
|
}
|
||||||
|
else if (hidKeysDown() & KEY_DOWN) {
|
||||||
|
if (++selected >= elements.size())
|
||||||
|
selected -= elements.size();
|
||||||
|
}
|
||||||
|
else if (!elements[selected].is_number_prompt) {
|
||||||
|
if (hidKeysDown() & KEY_A) {
|
||||||
|
confirmed = true;
|
||||||
|
lastElements = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (hidKeysDown() & KEY_LEFT)
|
||||||
|
if (*elements[selected].value > elements[selected].min)
|
||||||
|
(*elements[selected].value)--;
|
||||||
|
if (hidKeysDown() & KEY_RIGHT)
|
||||||
|
if (*elements[selected].value < elements[selected].max)
|
||||||
|
(*elements[selected].value)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// display
|
||||||
|
cout << "\e[H\e[0m";
|
||||||
|
for (size_t i = 0; i < elements.size(); i++) {
|
||||||
|
cout << (i == selected && !confirmed ? "\e[7m" : "")
|
||||||
|
<< elements[i].name << "\e[0m";
|
||||||
|
if (elements[i].is_number_prompt)
|
||||||
|
cout
|
||||||
|
<< ((*(elements[i].value) == elements[i].min) ? " " : " <")
|
||||||
|
<< *(elements[i].value)
|
||||||
|
<< ((*(elements[i].value) == elements[i].max) ? " " : ">");
|
||||||
|
cout << "\e[0K" << endl;
|
||||||
|
}
|
||||||
|
if (!confirmed)
|
||||||
|
cout << "\e[2m" << "[Up/Down] Move / "
|
||||||
|
<< (elements[selected].is_number_prompt ?
|
||||||
|
"[Left/Right] Modify" : "(A) Confirm") << "\e[0K" << endl;
|
||||||
|
else
|
||||||
|
cout << "\e[2mOK.\e[0K\e[0m" << endl;
|
||||||
|
|
||||||
|
return confirmed ? selected : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int uc_menu_quick(const char *str, ...) {
|
||||||
|
va_list arguments;
|
||||||
|
auto elements = vector<s_uc_menu_element>();
|
||||||
|
for (va_start(arguments, str); str; str = va_arg(arguments, const char *))
|
||||||
|
elements.push_back({str, false, NULL, 0, 0});
|
||||||
|
|
||||||
|
int r = -1;
|
||||||
|
while (r < 0 && aptMainLoop())
|
||||||
|
r = uc_menu(elements);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
void uc_pause(void) {
|
||||||
|
cout << "\e[0;2mPress (A) to continue...\e[0m" << endl;
|
||||||
|
while (aptMainLoop()) {
|
||||||
|
hidScanInput();
|
||||||
|
if (hidKeysDown() & KEY_A)
|
||||||
|
break;
|
||||||
|
gfxFlushBuffers();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue