├── static ├── demo.mp4 └── image.png ├── LICENSE ├── LibSpritesGUI ├── spritegui.h ├── spritesgui_types.h ├── spritesgui_arm32_optimization.s └── spritesgui.c └── README.md /static/demo.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Angelic47/LibSpritesGUI_12864/HEAD/static/demo.mp4 -------------------------------------------------------------------------------- /static/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Angelic47/LibSpritesGUI_12864/HEAD/static/image.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Angelic47 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LibSpritesGUI/spritegui.h: -------------------------------------------------------------------------------- 1 | #ifndef __SPRITESGUI__ 2 | #define __SPRITESGUI__ 3 | 4 | #include "spritesgui_types.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | typedef union _SPGUI_RENDERBUFFER 11 | { 12 | SPGUI_UINT8 data[2]; 13 | SPGUI_UINT16 buffer; 14 | } SPGUI_RENDERBUFFER, * PSPGUI_RENDERBUFFER; 15 | 16 | extern SPGUI_LAYER_FIRST spgui_firstLayer; 17 | extern SPGUI_LAYER spgui_layer[4]; 18 | 19 | SPGUI_VOID spgui_portable_outputData(SPGUI_BYTE data); 20 | 21 | SPGUI_VOID spgui_render(); 22 | SPGUI_VOID spgui_set_sprite(SPGUI_UINT8 id, PSPGUI_SPRITE sprite); 23 | SPGUI_VOID spgui_set_layer_sprite(PSPGUI_LAYER_FIRST layer, SPGUI_UINT8 x, SPGUI_UINT8 y, SPGUI_UINT8 id); 24 | SPGUI_VOID spgui_set_layer_alpha(PSPGUI_LAYER layer, SPGUI_UINT8 x, SPGUI_UINT8 y, SPGUI_UINT8 id); 25 | SPGUI_VOID spgui_set_layer_sprite_and_alpha(PSPGUI_LAYER layer, SPGUI_UINT8 x, SPGUI_UINT8 y, SPGUI_UINT8 id); 26 | SPGUI_VOID spgui_set_layer_mode(PSPGUI_LAYER_FIRST layer, SPGUI_LAYER_MODE mode); 27 | SPGUI_VOID spgui_set_layer_offset_x(PSPGUI_LAYER_FIRST layer, SPGUI_LAYER_MODE x); 28 | SPGUI_VOID spgui_set_layer_offset_y(PSPGUI_LAYER_FIRST layer, SPGUI_LAYER_MODE y); 29 | 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LibSpritesGUI 2 | 3 | 上古神器 I : 精灵图2D图形引擎 4 | 5 | 想要一个能在单片机上运行的高性能的2D图形引擎, 却不知道怎么如何下手? 没问题! 6 | 7 | 想要制作一些简单的GUI, 却苦于不想写字库的处理? 没问题! 8 | 9 | 想要开发一点复杂的GUI, 但是资源有限跑不动市面上的GUI库? 没问题! 10 | 11 | 甚至是想要制作复杂的动画, 甚至是制作一款2D RPG游戏? 也是没问题! 12 | 13 | 让这个库帮你解决掉这些烦恼! 14 | 15 | **注意: 该项目因涉及大量整型运算优化, 需要至少16位机方可运行** 16 | 17 | **请放弃手里的51单片机吧, 建议使用STM32/ESP8266/ESP32等更加先进又便宜的设备来运行** 18 | 19 | ![image](static/image.png) 20 | 21 | (演示视频位于static/demo.mp4) 22 | 23 | # 它可以做什么? 24 | 25 | - 128x64分辨率, 黑白输出, 适合绝大多数便宜的12864屏幕 26 | 27 | - 最大可同时输出256个完全不同的精灵图 28 | 29 | - 支持5个图层(查找表)的叠加渲染 30 | 31 | - 除背景图层外, 每个图层均支持图层透明度信息 32 | 33 | - 每个图层均支持横向或纵向滚屏模式 34 | 35 | - 高强度优化, 算法内无任何浮点和除法算法, 在STM32F103C6T6(64MHz HSI)环境下能够稳定24-30FPS+ 36 | 37 | - 仅需4.5KB的几乎挑战极限的内存占用 38 | 39 | # 所以这到底是个什么黑科技? 40 | 41 | 这个库源于一个非常古老的技术 —— 精灵图技术, 在早期的FC游戏机、SFC游戏机、GBA游戏机等曾经被大规模应用. 42 | 43 | 后随着时间的流逝和技术的发展, 这项技术逐渐被丰富的空余资源和更高的处理器性能所遗忘. 44 | 45 | 如今这项技术就像是消失在了互联网上, 几乎再也找不到它的影子了. 更有很多人听都没听说过这种2D引擎技术. 46 | 47 | 这个项目就是想将这一种古老而高效的技术保存下来, 让大家重新有机会能够学习到这种技术 —— 原来一个黑白12864屏不仅仅是可以显示几个汉字, 其实还可以这样玩! 48 | 49 | # 所以能给我讲讲它的原理么? 50 | 51 | 当然可以! 52 | 53 | 每个精灵图都是一个8x8的像素图, 你可以理解为这是 “字库” . 54 | 55 | 这个库要做的就是根据每个图层的精灵图编号信息, 找到对应的字库, 进行图层位移和叠加计算之后输出在屏幕上. 56 | 57 | 因为精灵图可以重复使用, 且算法并没有直接保存完整的图形内容, 所以该算法十分节省内存资源. 58 | 59 | 而计算精灵图本身也不是一件复杂的事情, 并不需要消耗太多的CPU资源. 60 | 61 | 因此这个技术曾在早期的游戏机上得到过大规模的应用, 虽然时代可能已经将其忘记, 但是这真的非常适合运行在小内存单片机上! 62 | 63 | # 所以有没有Example代码呢? 64 | 65 | 当然有的啦, 正在整理, 稍后上传, 大家莫急. 66 | 67 | # 所以最后, 开源许可证呢? 68 | MIT License, 代码无任何担保. 不过, 如果你发现了什么BUG, 欢迎提出issue或者开pull request. 69 | -------------------------------------------------------------------------------- /LibSpritesGUI/spritesgui_types.h: -------------------------------------------------------------------------------- 1 | #ifndef __SPRITESGUI_TYPES__ 2 | #define __SPRITESGUI_TYPES__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | // SpritesGUI �������ݽṹ���� 9 | 10 | // ������������(��λ: �������) 11 | #define SPGUI_MARCO_NAMEDTABLE_X 16 12 | #define SPGUI_MARCO_NAMEDTABLE_Y 8 13 | 14 | // ����Ԫ�ظ��� 15 | #define SPGUI_MARCO_MAXSPRITE 256 16 | 17 | typedef unsigned short SPGUI_UINT16; 18 | typedef unsigned long SPGUI_UINT32; 19 | typedef unsigned char SPGUI_UINT8; 20 | typedef unsigned char SPGUI_BYTE; 21 | typedef void SPGUI_VOID; 22 | 23 | typedef SPGUI_UINT8 SPGUI_SPRITEID; 24 | 25 | typedef SPGUI_UINT8 SPGUI_LAYER_MODE; 26 | #define SPGUI_LAYER_MODE_LANDSCAPE 0 27 | #define SPGUI_LAYER_MODE_PORTRAIT 1 28 | 29 | typedef SPGUI_UINT8 SPGUI_POSITIONX; 30 | typedef SPGUI_UINT8 SPGUI_POSITIONY; 31 | 32 | // ����ͼ��, 8 * 8 33 | // ������ȡģ, 1byteΪ����8����, һ��8bytes 34 | typedef struct _SPGUI_SPRITE 35 | { 36 | SPGUI_UINT8 data[8]; 37 | } SPGUI_SPRITE, *PSPGUI_SPRITE; 38 | 39 | // ��������ݽṹ 40 | typedef struct _SPGUI_SPRITES_LIST 41 | { 42 | SPGUI_SPRITE sprites[SPGUI_MARCO_MAXSPRITE]; 43 | } SPGUI_SPRITES_LIST, *PSPGUI_SPRITES_LIST; 44 | 45 | // �������������ݽṹ 46 | typedef union _SPGUI_NAMED_TABLE 47 | { 48 | SPGUI_SPRITEID sprites_landscape[SPGUI_MARCO_NAMEDTABLE_X * 2][SPGUI_MARCO_NAMEDTABLE_Y]; 49 | SPGUI_SPRITEID sprites_portrait[SPGUI_MARCO_NAMEDTABLE_X][SPGUI_MARCO_NAMEDTABLE_Y * 2]; 50 | } SPGUI_NAMED_TABLE, *PSPGUI_NAMED_TABLE; 51 | 52 | // ����ͼ���ײ�ṹ, �ײ�û��͸���� 53 | typedef struct _SPGUI_LAYER_FIRST 54 | { 55 | SPGUI_NAMED_TABLE main; 56 | SPGUI_LAYER_MODE mode; 57 | SPGUI_POSITIONX posx; 58 | SPGUI_POSITIONY posy; 59 | } SPGUI_LAYER_FIRST, * PSPGUI_LAYER_FIRST; 60 | 61 | 62 | // ����ͼ��ṹ, ÿ��ͼ�������������� 63 | typedef struct _SPGUI_LAYER 64 | { 65 | SPGUI_LAYER_FIRST basiclayer; 66 | SPGUI_NAMED_TABLE alpha; 67 | } SPGUI_LAYER, * PSPGUI_LAYER; 68 | 69 | #ifdef __cplusplus 70 | } 71 | #endif 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /LibSpritesGUI/spritesgui_arm32_optimization.s: -------------------------------------------------------------------------------- 1 | .section .text.spgui_get_byte,"ax",%progbits 2 | .global spgui_get_byte 3 | .type spgui_get_byte, %function 4 | .extern spgui_spriteList 5 | .syntax unified 6 | spgui_get_byte: 7 | ldrb.w r7, [r0, #0x100] // layer->mode 8 | cmp r7, #0x00 9 | bne loc_mode_portrait 10 | loc_mode_landscape: 11 | ldrb.w r7, [r0, #0x101] // layer->posx 12 | add r7, r1 // x += layer->posx 13 | and r7, #0xff 14 | and r8, r7, #0x07 // xdelta = x & 0x07 15 | lsr r7, #0x03 // x = x >> 3 16 | //mov r9, #0x08 // spritesid = layer->main.sprites_landscape[x][ydiv8] 17 | //mul r9, r7 18 | lsl r9, r7, #0x03 19 | add r0, r9 20 | ldrb r0, [r0, r2] 21 | //mov r9, #0x08 // spgui_spriteList.sprites[spritesid].data[xdelta] 22 | //mul r9, r0 23 | //lsl r9, r0, #0x03 24 | add r9, r8, r0, LSL#3 25 | ldr r0, =spgui_spriteList 26 | //add r0, r9 27 | ldrb r0, [r0, r9] 28 | bx lr 29 | loc_mode_portrait: 30 | and r8, r1, #0x07 // xdelta = x & 0x07 31 | lsr r7, r1, #0X03 // x = x >> 3 32 | // mov r9, #0x08 // ypos = ydiv8 * 8 + layer->posy 33 | // mul r9, r2 34 | lsl r9, r2, #0x03 35 | ldrb.w r10, [r0, #0x102] 36 | add r9, r10 37 | and r10, r9, #0x07 // ydelta = ypos & 0x07 38 | lsr r9, #0x03 // ypos = ypos >> 3 39 | // lsl r7, #0x04 // mul r7, r7, #0x10 40 | add r0, r0, r7, LSL#4 41 | and r9, #0x0f 42 | ldrb r11, [r0, r9] 43 | add r9, #0x01 44 | and r9, #0x0f 45 | ldrb r12, [r0, r9] 46 | ldr r0, =spgui_spriteList 47 | lsl r11, #0x03 // mul r11, r11, #0x08 48 | lsl r12, #0x03 // mul r12, r12, #0x08 49 | add r7, r0, r12 50 | add r0, r11 51 | ldrb r0, [r0, r8] 52 | ldrb r7, [r7, r8] 53 | lsl r7, #0x08 54 | orr r0, r7 55 | lsr r0, r10 56 | and r0, #0xff 57 | bx lr 58 | 59 | .section .text.spgui_get_alpha,"ax",%progbits 60 | .global spgui_get_alpha 61 | .type spgui_get_alpha, %function 62 | .extern spgui_spriteList 63 | .syntax unified 64 | spgui_get_alpha: 65 | ldrb.w r7, [r0, #0x100] // layer->mode 66 | cmp r7, #0x00 67 | bne loc_mode_portrait_alpha 68 | loc_mode_landscape_alpha: 69 | ldrb.w r7, [r0, #0x101] // layer->posx 70 | add r7, r1 // x += layer->posx 71 | and r7, #0xff 72 | and r8, r7, #0x07 // xdelta = x & 0x07 73 | lsr r7, #0x03 // x = x >> 3 74 | //mov r9, #0x08 // spritesid = layer->main.sprites_landscape[x][ydiv8] 75 | //mul r9, r7 76 | lsl r9, r7, #0x03 77 | add r0, #0x103 78 | add r0, r9 79 | ldrb r0, [r0, r2] 80 | //mov r9, #0x08 // spgui_spriteList.sprites[spritesid].data[xdelta] 81 | //mul r9, r0 82 | //lsl r9, r0, #0x03 83 | add r9, r8, r0, LSL#3 84 | ldr r0, =spgui_spriteList 85 | //add r0, r9 86 | ldrb r0, [r0, r9] 87 | bx lr 88 | loc_mode_portrait_alpha: 89 | and r8, r1, #0x07 // xdelta = x & 0x07 90 | lsr r7, r1, #0X03 // x = x >> 3 91 | //mov r9, #0x08 // ypos = ydiv8 * 8 + layer->posy 92 | //mul r9, r2 93 | lsl r9, r2, #0x03 94 | ldrb.w r10, [r0, #0x102] 95 | add r9, r10 96 | and r10, r9, #0x07 // ydelta = ypos & 0x07 97 | lsr r9, #0x03 // ypos = ypos >> 3 98 | //lsl r7, #0x04 // mul r7, r7, #0x10 99 | add r0, r0, r7, LSL#4 100 | add r0, #0x103 101 | and r9, #0x0f 102 | ldrb r11, [r0, r9] 103 | add r9, #0x01 104 | and r9, #0x0f 105 | ldrb r12, [r0, r9] 106 | ldr r0, =spgui_spriteList 107 | lsl r11, #0x03 // mul r11, r11, #0x08 108 | lsl r12, #0x03 // mul r12, r12, #0x08 109 | add r7, r0, r12 110 | add r0, r11 111 | ldrb r0, [r0, r8] 112 | ldrb r7, [r7, r8] 113 | lsl r7, #0x08 114 | orr r0, r7 115 | lsr r0, r10 116 | and r0, #0xff 117 | bx lr 118 | 119 | .section .text.spgui_render,"ax",%progbits 120 | .global spgui_render 121 | .type spgui_render, %function 122 | .extern spgui_firstLayer 123 | .extern spgui_layer 124 | .extern spgui_get_byte 125 | .extern spgui_get_alpha 126 | .extern spgui_portable_outputData 127 | spgui_render: 128 | push {r0-r12} 129 | mov r3, lr 130 | push {r3} 131 | 132 | ldr r2, =0x00 // ydiv8 = 0 133 | ldr r1, =0x00 // x = 0 134 | 135 | loc_ydiv8_loop_start: 136 | loc_x_loop_start: 137 | 138 | ldr r0, =spgui_firstLayer 139 | bl spgui_get_byte 140 | mov r3, r0 141 | 142 | ldr r4, =spgui_layer 143 | ldr r6, =0x00 144 | loc_layer_loop_start: 145 | mov r0, r4 146 | bl spgui_get_alpha 147 | mov r5, r0 148 | mov r0, r4 149 | bl spgui_get_byte 150 | and r0, r5 151 | bic r3, r5 152 | orr r3, r0 153 | ldr r5, =0x203 154 | add r4, r5 155 | add r6, #0x01 156 | cmp r6, #0x04 157 | bne loc_layer_loop_start 158 | 159 | mov r0, r3 160 | push {r0-r12} 161 | bl spgui_portable_outputData 162 | pop {r0-r12} 163 | 164 | add r1, #0x01 165 | cmp r1, #0x80 166 | bne loc_x_loop_start 167 | mov r1, #0x00 168 | add r2, #0x01 169 | cmp r2, #0x08 170 | bne loc_ydiv8_loop_start 171 | 172 | pop {r3} 173 | mov lr, r3 174 | pop {r0-r12} 175 | BX LR 176 | -------------------------------------------------------------------------------- /LibSpritesGUI/spritesgui.c: -------------------------------------------------------------------------------- 1 | #include "spritesgui_types.h" 2 | #include "spritegui.h" 3 | 4 | SPGUI_LAYER_FIRST spgui_firstLayer; 5 | SPGUI_LAYER spgui_layer[4]; 6 | 7 | SPGUI_SPRITES_LIST spgui_spriteList; 8 | 9 | /* 10 | SPGUI_BYTE spgui_get_byte(PSPGUI_LAYER_FIRST layer, SPGUI_UINT8 x, SPGUI_UINT8 ydiv8) 11 | { 12 | SPGUI_UINT8 spritesid; 13 | SPGUI_UINT8 ydelta; 14 | SPGUI_UINT8 xdelta; 15 | SPGUI_UINT8 ypos; 16 | SPGUI_RENDERBUFFER buffer; 17 | switch (layer->mode) 18 | { 19 | case SPGUI_LAYER_MODE_LANDSCAPE: 20 | x += layer->posx; 21 | xdelta = x & 0x07; 22 | x = x >> 3; 23 | spritesid = layer->main.sprites_landscape[x][ydiv8]; 24 | return spgui_spriteList.sprites[spritesid].data[xdelta]; 25 | case SPGUI_LAYER_MODE_PORTRAIT: 26 | xdelta = x & 0x07; 27 | x = x >> 3; 28 | ypos = ydiv8 * 8 + layer->posy; 29 | ydelta = ypos & 0x07; 30 | ypos = ypos >> 3; 31 | spritesid = layer->main.sprites_portrait[x][ypos & 0xf]; 32 | buffer.data[0] = spgui_spriteList.sprites[spritesid].data[xdelta]; 33 | ypos += 1; 34 | spritesid = layer->main.sprites_portrait[x][ypos & 0xf]; 35 | buffer.data[1] = spgui_spriteList.sprites[spritesid].data[xdelta]; 36 | buffer.buffer >>= ydelta; 37 | return buffer.data[0]; 38 | default: 39 | // shouldn't be happen 40 | return 0; 41 | } 42 | } 43 | 44 | SPGUI_BYTE spgui_get_alpha(PSPGUI_LAYER layer, SPGUI_UINT8 x, SPGUI_UINT8 ydiv8) 45 | { 46 | SPGUI_UINT8 spritesid; 47 | SPGUI_UINT8 ydelta; 48 | SPGUI_UINT8 xdelta; 49 | SPGUI_UINT8 ypos; 50 | SPGUI_RENDERBUFFER buffer; 51 | switch (layer->basiclayer.mode) 52 | { 53 | case SPGUI_LAYER_MODE_LANDSCAPE: 54 | x += layer->basiclayer.posx; 55 | xdelta = x & 0x07; 56 | x = x >> 3; 57 | spritesid = layer->alpha.sprites_landscape[x][ydiv8]; 58 | return spgui_spriteList.sprites[spritesid].data[xdelta]; 59 | case SPGUI_LAYER_MODE_PORTRAIT: 60 | xdelta = x & 0x07; 61 | x = x >> 3; 62 | ypos = ydiv8 * 8 + layer->basiclayer.posy; 63 | ydelta = ypos & 0x07; 64 | ypos = ypos >> 3; 65 | spritesid = layer->alpha.sprites_portrait[x][ypos & 0xf]; 66 | buffer.data[0] = spgui_spriteList.sprites[spritesid].data[xdelta]; 67 | ypos += 1; 68 | spritesid = layer->alpha.sprites_portrait[x][ypos & 0xf]; 69 | buffer.data[1] = spgui_spriteList.sprites[spritesid].data[xdelta]; 70 | buffer.buffer >>= ydelta; 71 | return buffer.data[0]; 72 | default: 73 | // shouldn't be happen 74 | return 0; 75 | } 76 | } 77 | 78 | SPGUI_VOID spgui_render() 79 | { 80 | SPGUI_BYTE renderByteResult; 81 | 82 | SPGUI_BYTE renderingByte; 83 | SPGUI_BYTE renderingAlpha; 84 | 85 | SPGUI_UINT8 x, ydiv8, layer; 86 | 87 | for (ydiv8 = 0; ydiv8 < 8; ydiv8++) 88 | { 89 | for (x = 0; x < 128; x++) 90 | { 91 | renderByteResult = spgui_get_byte(&spgui_firstLayer, x, ydiv8); 92 | 93 | for (layer = 0; layer < 4; layer++) 94 | { 95 | renderingByte = spgui_get_byte(&(spgui_layer[layer]), x, ydiv8); 96 | renderingAlpha = spgui_get_alpha(&(spgui_layer[layer]), x, ydiv8); 97 | renderByteResult = (renderingByte & renderingAlpha) | (~renderingAlpha & renderByteResult); 98 | } 99 | 100 | spgui_portable_outputData(renderByteResult); 101 | } 102 | } 103 | } 104 | */ 105 | 106 | SPGUI_VOID spgui_set_sprite(SPGUI_UINT8 id, PSPGUI_SPRITE sprite) 107 | { 108 | SPGUI_UINT8 i; 109 | for (i = 0; i < 8; i++) 110 | spgui_spriteList.sprites[id].data[i] = sprite->data[i]; 111 | } 112 | 113 | SPGUI_VOID spgui_set_layer_sprite(PSPGUI_LAYER_FIRST layer, SPGUI_UINT8 x, SPGUI_UINT8 y, SPGUI_UINT8 id) 114 | { 115 | switch (layer->mode) 116 | { 117 | case SPGUI_LAYER_MODE_LANDSCAPE: 118 | layer->main.sprites_landscape[x][y] = id; 119 | break; 120 | case SPGUI_LAYER_MODE_PORTRAIT: 121 | layer->main.sprites_portrait[x][y] = id; 122 | break; 123 | default: 124 | break; 125 | } 126 | } 127 | 128 | SPGUI_VOID spgui_set_layer_alpha(PSPGUI_LAYER layer, SPGUI_UINT8 x, SPGUI_UINT8 y, SPGUI_UINT8 id) 129 | { 130 | switch (layer->basiclayer.mode) 131 | { 132 | case SPGUI_LAYER_MODE_LANDSCAPE: 133 | layer->alpha.sprites_landscape[x][y] = id; 134 | break; 135 | case SPGUI_LAYER_MODE_PORTRAIT: 136 | layer->alpha.sprites_portrait[x][y] = id; 137 | break; 138 | default: 139 | break; 140 | } 141 | } 142 | 143 | SPGUI_VOID spgui_set_layer_sprite_and_alpha(PSPGUI_LAYER layer, SPGUI_UINT8 x, SPGUI_UINT8 y, SPGUI_UINT8 id) 144 | { 145 | spgui_set_layer_sprite(layer, x, y, id); 146 | spgui_set_layer_alpha(layer, x, y, id); 147 | } 148 | 149 | SPGUI_VOID spgui_set_layer_mode(PSPGUI_LAYER_FIRST layer, SPGUI_LAYER_MODE mode) 150 | { 151 | layer->mode = mode; 152 | } 153 | 154 | SPGUI_VOID spgui_set_layer_offset_x(PSPGUI_LAYER_FIRST layer, SPGUI_LAYER_MODE x) 155 | { 156 | layer->posx = x; 157 | } 158 | 159 | SPGUI_VOID spgui_set_layer_offset_y(PSPGUI_LAYER_FIRST layer, SPGUI_LAYER_MODE y) 160 | { 161 | layer->posy = y; 162 | } 163 | --------------------------------------------------------------------------------