Commits

blipi committed 22bb484

v0.5
Initial commit
OOSK accepts input.
Still need to accurate press speed
No space/del/special keys yet

Comments (0)

Files changed (4)

+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <malloc.h>
+#include <string.h>
+#include <assert.h>
+#include <unistd.h>
+#include <math.h>
+#include <string.h>
+
+#include <lv2/process.h>
+#include <psl1ght/lv2/thread.h>
+#include <sysmodule/sysmodule.h>
+#include <sysutil/events.h>
+
+#include <sys/stat.h>
+#include <sysutil/events.h>
+#include <io/msg.h>
+#include <io/pad.h> 
+#include <io/mouse.h> 
+#include <sysmodule/sysmodule.h>
+
+#include <tiny3d.h>
+#include <pngdec\loadpng.h>
+#include <io/pad.h> 
+#include <sys\time.h>
+
+#include "types.h"
+#include "oskdialog.h"
+
+
+//Tiny3D Resources
+u32 *texture_mem;
+u32 * texture_pointer;
+
+//SDK modules
+u32 module_flag;
+
+volatile u8 running = 1;
+
+void releaseAll() {
+	
+	sysUnregisterCallback(EVENT_SLOT0);
+	//sys_ppu_thread_join(thread1_id, &retval);
+	
+	if(module_flag & 2)
+		SysUnloadModule(SYSMODULE_PNGDEC);
+
+	if(module_flag & 1)
+		SysUnloadModule(SYSMODULE_FS);
+
+	running = 0;
+}
+
+int loadModules( void ){
+	if(SysLoadModule(SYSMODULE_FS)!=0) return 0; else module_flag |=1;
+
+	if(SysLoadModule(SYSMODULE_PNGDEC)!=0) return 0; else module_flag |=2;
+
+	return 1;
+}
+
+void loadTexture()
+{
+
+    texture_mem = (u32*)tiny3d_AllocTexture(64*1024*1024); // alloc 64MB of space for textures (this pointer can be global)    
+
+    if(!texture_mem) return; // fail!
+
+    texture_pointer = texture_mem;
+}
+
+static void sys_callback(uint64_t status, uint64_t param, void* userdata) {
+
+     switch (status) {
+		case EVENT_REQUEST_EXITAPP:
+			releaseAll();
+			sysProcessExit(1);
+			break;
+      
+       default:
+		   break;
+         
+	}
+}
+
+int main(int argc, const char* argv[], const char* envp[])
+{
+	tiny3d_Init(1024*1024);
+	tiny3d_Project2D();
+
+	loadModules();
+		
+	ioPadInit(7);
+	
+    loadTexture();
+	
+	sysRegisterCallback(EVENT_SLOT0, sys_callback, NULL);
+
+
+	OSK *cOSK = new OSK(texture_pointer, "/dev_hdd0/game/RNA000001/USRDIR");
+	texture_pointer = cOSK->getTexturePointer();
+
+	texture_pointer = cOSK->loadFont(0, "/dev_hdd0/game/RNA000001/USRDIR", texture_pointer);
+
+	osk_point point = {300, 200};
+	cOSK->setPos(point);
+
+	char *buffer = NULL;
+
+	/*** - MAIN LOOP - ***/
+	while( running ){
+		
+		tiny3d_Clear(0xff555555, TINY3D_CLEAR_ALL);
+
+        // Enable alpha Test
+        tiny3d_AlphaTest(1, 0x10, TINY3D_ALPHA_FUNC_GEQUAL);
+
+        // Enable alpha blending.
+        tiny3d_BlendFunc(1, (blend_src_func)(TINY3D_BLEND_FUNC_SRC_RGB_SRC_ALPHA | TINY3D_BLEND_FUNC_SRC_ALPHA_SRC_ALPHA),
+            (blend_dst_func)(NV30_3D_BLEND_FUNC_DST_RGB_ONE_MINUS_SRC_ALPHA | NV30_3D_BLEND_FUNC_DST_ALPHA_ZERO),
+            (blend_func)(TINY3D_BLEND_RGB_FUNC_ADD | TINY3D_BLEND_ALPHA_FUNC_ADD));
+
+		tiny3d_Project2D();
+
+		if(cOSK->getStatus() == OSK_INITIALIZED)
+			cOSK->open();
+		else if(cOSK->getStatus() == OSK_RUNNING){
+			cOSK->draw();
+			cOSK->handlePad();
+		}else if(cOSK->getStatus() == OSK_RETURN)
+			buffer = cOSK->getBuffer();
+		else if(cOSK->getStatus() == OSK_END)
+			DrawString(200, 200, buffer);
+				
+        tiny3d_Flip();
+
+		sysCheckCallback();
+
+	}
+	
+	return 0;
+
+}
+#include "oskdialog.h"
+
+u8 osk_loaded = 0;
+FT_Face face;
+
+char key_array[2][4][10] = {
+	{
+		{'!', '"', '�', '$', '%', '&', '/', '(', ')', '='},
+		{'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'},
+		{'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', '�'},
+		{'Z', 'X', 'C', 'V', 'B', 'N', 'M', ';', ':', '_'}
+	},
+	{
+		{'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'},
+		{'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p'},
+		{'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', '�'},
+		{'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '-'}
+	}
+};
+
+struct block_data{
+	u8 blocked;
+	u16 delay;
+	long uval;
+};
+
+block_data lblock = {0}, rblock = {0}, ublock = {0}, dblock = {0};
+block_data xblock = {0};
+
+
+
+void TTF_to_Bitmap(u8 chr, u8 * bitmap, short *w, short *h, short *y_correction){
+	FT_Set_Pixel_Sizes(face, (*w), (*h));
+    
+	FT_GlyphSlot slot = face->glyph;
+
+	memset(bitmap, 0, (*w) * (*h));
+
+	if(FT_Load_Char(face, (char) chr, FT_LOAD_RENDER )) {(*w) = 0; return;}
+
+	int n, m, ww;
+
+	*y_correction = (*h) - 1 - slot->bitmap_top;
+    
+	ww = 0;
+
+	for(n = 0; n < slot->bitmap.rows; n++) {
+		for (m = 0; m < slot->bitmap.width; m++) {
+
+			if(m >= (*w) || n >= (*h)) continue;
+            
+			bitmap[m] = (u8) slot->bitmap.buffer[ww + m];
+		}
+    
+	bitmap += *w;
+
+	ww += slot->bitmap.width;
+	}
+
+	*w = ((slot->advance.x + 31) >> 6) + ((slot->bitmap_left < 0) ? -slot->bitmap_left : 0);
+	*h = slot->bitmap.rows;
+}
+
+void Debug(char *format, ...){
+	char str[1024];
+	char filename[1024];
+
+    va_list argp;        
+    va_start(argp, format);
+	vsprintf(str, format, argp);
+	va_end(argp);
+
+	FILE *fDebug;
+	sprintf(filename, "/dev_hdd0/game/%s/USRDIR/log.txt", "RNA000001");
+	fDebug = fopen(filename, "a+");
+
+	fputs(str, fDebug);
+
+	fclose(fDebug);
+}
+
+
+
+OSK::OSK(u32 *texture_pointer, char *usrdir){
+	this->png_displayer = &this->png_displayer_f;
+	this->png_loader = NULL;
+	this->status = OSK_INITIALIZED;
+	this->mode = 1;
+	this->sel_row = 0;
+	this->sel_num = 0;
+	this->ttf_inited = 0;
+	this->font_slot = -1;
+	this->texture_pointer = texture_pointer;
+
+	if(osk_loaded == 0){
+		char path[1024] = {0};
+		
+		sprintf(path, "%s/BTN.PNG", usrdir);
+		this->btn = this->png_loader_f(path, this->texture_pointer);
+		this->texture_pointer = this->btn->texture_pointer;
+
+		sprintf(path, "%s/SPACE.PNG", usrdir);
+		this->space = this->png_loader_f(path, this->texture_pointer);		
+		this->texture_pointer = this->space->texture_pointer;
+
+		osk_loaded = 1;
+	}
+}
+
+OSK::OSK(method_a *png_loader, method_b *png_displayer, char *usrdir){
+	this->png_loader = png_loader;
+	this->png_displayer = png_displayer;
+	this->status = OSK_INITIALIZED;
+	this->mode = 1;
+	this->sel_row = 0;
+	this->sel_num = 0;
+	this->ttf_inited = 0;
+	this->font_slot = -1;
+	this->texture_pointer = 0;
+
+	if(osk_loaded == 0){
+		char path[1024] = {0};
+		
+		sprintf(path, "%s/BTN.PNG", usrdir);
+		this->btn = (*this->png_loader)(path);
+		this->btn->width = 35.3333;
+		this->btn->height = 41.2444;
+
+		sprintf(path, "%s/SPACE.PNG", usrdir);
+		this->space = (*this->png_loader)(path);
+
+		osk_loaded = 1;
+	}
+}
+
+u32* OSK::loadFont(u8 slot, char *usrdir, u32 *texture_pointer){
+	this->font_slot = slot;
+	
+	if(!usrdir)
+		return this->texture_pointer;
+
+	if(!texture_pointer)
+		return NULL;
+
+	if(slot == 0)
+		ResetFont();
+
+	char path[1024] = {0};		
+	sprintf(path, "%s/pala.ttf", usrdir);
+
+	if(!ttf_inited){
+		FT_Init_FreeType(&freetype);
+		ttf_inited = 1;
+	}
+
+    if(FT_New_Face(freetype, path, 0, &face)) return NULL;
+	
+	this->texture_pointer = (u32 *) AddFontFromTTF((u8 *) texture_pointer, 32, 255, 32, 32, TTF_to_Bitmap);
+
+	FT_Done_FreeType(freetype);
+	ttf_inited = 0;
+
+	return this->texture_pointer;
+}
+
+void OSK::DrawRect2D(u32 rgba, float x, float y, float width, float height){
+    tiny3d_SetPolygon(TINY3D_QUADS);
+	
+    tiny3d_VertexPos(x  , y  , 65535);
+    tiny3d_VertexColor(rgba);
+
+    tiny3d_VertexPos(x + width, y  , 65535);
+
+    tiny3d_VertexPos(x + width, y + height, 65535);
+
+    tiny3d_VertexPos(x , y + height, 65535);
+    tiny3d_End();
+}
+
+void OSK::DrawBorders2D(u32 rgba, float x, float y, float w, float h, u32 border){
+	this->DrawRect2D(rgba, x-border, y-border, w+(border*2), border);
+	this->DrawRect2D(rgba, x+w, y-border, border, h+(border*2));
+	this->DrawRect2D(rgba, x-border, y+h, w+(border*2), border);
+	this->DrawRect2D(rgba, x-border, y-border, border, h+(border*2));
+}
+
+u8 OSK::draw(){
+	if(status != OSK_RUNNING)
+		return -1;
+
+	float x0;
+	float y0;
+
+	float x = x0 = this->pos.x;
+	float y = y0 = this->pos.y;
+	
+	float w = 35.3333;
+	float h = 41.2444;
+
+	//barra donde se muestra lo escrito
+	this->btn->x = x + w/2;
+	this->btn->y = y;
+	this->btn->width = (w+5)*9;
+	this->btn->alpha = 0x99;
+	if(this->png_displayer != NULL)
+		(*this->png_displayer)(this->btn);
+	else
+		this->png_displayer_f(this->btn);
+	
+	if(this->font_slot >= 0){		
+		SetCurrentFont(this->font_slot);
+		SetFontSize(18, 20);
+		SetFontColor(0xFFFFFFFF, 0x0);
+		
+		DrawString(x + w/2 + 15, y + h/2 - 20/2 - 5, this->buffer);
+	}
+
+	this->btn->width = w;
+	this->btn->height = h;
+	this->btn->alpha = 0xFF;
+
+	y = y0 = y0 + h + 10;
+
+	for(int i = 0; i < 4; i++){
+		for(int n = 0; n < 10; n++){
+
+			this->btn->x = x;
+			this->btn->y = y;
+
+			if(this->png_displayer != NULL)
+				(*this->png_displayer)(this->btn);
+			else
+				this->png_displayer_f(this->btn);
+
+			if(this->sel_num == n && this->sel_row == i)
+				this->DrawBorders2D(0xFFFFFFFF, x, y, w-1, h, 3);
+
+			if(this->font_slot >= 0)
+				DrawFormatString(x + w/2 - 18/2 + 3, y + h/2 - 20/2 - 5, "%c", key_array[this->mode][i][n]);
+			
+			x += w + 5;
+		}
+
+		x = x0 = x0 + w/2;
+		y = y0 = y0 + h + 10;
+	}
+
+	return 0;
+}
+
+u8 OSK::handlePad(){
+	if(this->status != OSK_RUNNING)
+		return -1;
+
+	PadData paddata;
+	PadInfo padinfo;
+
+	ioPadGetInfo(&padinfo);
+
+	struct timeval time_now;
+	gettimeofday(&time_now, NULL);
+	long cur_time = time_now.tv_sec * 1000 + time_now.tv_usec/1000;
+	
+	for(int i = 0; i < MAX_PADS; i++){
+		if(padinfo.status[i]){
+			ioPadGetData(i, &paddata);
+			
+			//ioPadSetPortSetting(i, CELL_PAD_SETTING_PRESS_ON);
+			ioPadSetPortSetting(i, CELL_PAD_SETTING_SENSOR_ON);
+
+			s8 plusn = 0;
+			s8 plusr = 0;
+
+			if(paddata.BTN_RIGHT){
+				if(!rblock.blocked){
+					plusn = 1;
+					rblock.blocked = 1;
+					rblock.delay = 1000;
+					rblock.uval = cur_time;
+				}else{
+					long elapsed = ((cur_time-rblock.uval > 0)?cur_time-rblock.uval:rblock.uval-cur_time);
+					if(elapsed >= rblock.delay){
+						plusn = 1;
+						rblock.uval = cur_time;
+						rblock.delay = 300;
+					}
+				}
+			}else
+				rblock.blocked = 0;
+			
+			if(paddata.BTN_LEFT){
+				if(!lblock.blocked){
+					plusn = -1;
+					lblock.blocked = 1;
+					lblock.delay = 1000;
+					lblock.uval = cur_time;
+				}else{
+					long elapsed = ((cur_time-lblock.uval > 0)?cur_time-lblock.uval:lblock.uval-cur_time);
+					if(elapsed >= lblock.delay){
+						plusn = -1;
+						lblock.uval = cur_time;
+						lblock.delay = 300;
+					}
+				}
+			}else
+				lblock.blocked = 0;
+
+			if(paddata.BTN_UP){
+				if(!ublock.blocked){
+					plusr = -1;
+					ublock.blocked = 1;
+					ublock.delay = 1000;
+					ublock.uval = cur_time;
+				}else{
+					long elapsed = ((cur_time-ublock.uval > 0)?cur_time-ublock.uval:ublock.uval-cur_time);
+					if(elapsed >= ublock.delay){
+						plusr = -1;
+						ublock.uval = cur_time;
+						ublock.delay = 300;
+					}
+				}
+			}else
+				ublock.blocked = 0;
+
+			if(paddata.BTN_DOWN){
+				if(!dblock.blocked){
+					plusr = 1;
+					dblock.blocked = 1;
+					dblock.delay = 1000;
+					dblock.uval = cur_time;
+				}else{
+					long elapsed = ((cur_time-dblock.uval > 0)?cur_time-dblock.uval:dblock.uval-cur_time);
+					if(elapsed >= dblock.delay){
+						plusr = 1;
+						dblock.uval = cur_time;
+						dblock.delay = 300;
+					}
+				}
+			}else
+				dblock.blocked = 0;
+
+			if(paddata.BTN_CROSS){
+				if(!xblock.blocked){
+					
+					if(this->sel_num >= 0 && this->sel_num <= 9 && this->sel_row >= 0 && this->sel_row <= 3){
+						if(strlen(this->buffer) >= 255)
+							continue;
+
+						char buf[5];
+						sprintf(buf, "%c", key_array[this->mode][this->sel_row][this->sel_num]);
+						strcat(this->buffer, buf);
+					}
+
+					xblock.blocked = 1;
+					xblock.delay = 1000;
+					xblock.uval = cur_time;
+				}else{
+					long elapsed = ((cur_time-xblock.uval > 0)?cur_time-xblock.uval:xblock.uval-cur_time);
+					if(elapsed >= xblock.delay){
+						
+						if(this->sel_num >= 0 && this->sel_num <= 9 && this->sel_row >= 0 && this->sel_row <= 3){
+							if(strlen(this->buffer) >= 255)
+								continue;
+
+							char buf[5];
+							sprintf(buf, "%c", key_array[this->mode][this->sel_row][this->sel_num]);
+							strcat(this->buffer, buf);
+						}
+
+						xblock.uval = cur_time;
+						xblock.delay = 300;
+					}
+				}
+			}else
+				xblock.blocked = 0;
+
+			if(paddata.BTN_START){
+				this->status = OSK_RETURN;
+				//Callback
+			}
+
+			if(plusn != 0){
+				this->sel_num += plusn;
+
+				if(this->sel_num < 0)
+					this->sel_num = 9;
+				else if(this->sel_num >= 10)
+					this->sel_num = 0;
+			}
+			
+			if(plusr != 0){
+				this->sel_row += plusr;
+
+				if(this->sel_row < 0)
+					this->sel_row = 3;
+				else if(this->sel_row >= 4)
+					this->sel_row = 0;
+			}
+
+			break; //Solo queremos el PAD 0
+		}		
+	}
+
+	return 0;
+}
+
+void OSK::setPos(osk_point npos){
+	this->pos.x = npos.x;
+	this->pos.y = npos.y;
+}
+#ifndef OSK_DIALOG_H
+#define OSK_DIALOG_H
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <malloc.h>
+#include <string.h>
+
+#include <tiny3d.h>
+#include <pngdec\loadpng.h>
+#include <io/pad.h> 
+#include <sys/time.h>
+
+#include <libfont.h>
+#include <ft2build.h>
+#include <freetype/freetype.h> 
+#include <freetype/ftglyph.h>
+
+#include <time.h>
+
+#include "types.h"
+
+struct _png_loader{
+	PngDatas png;
+	u32 offset;
+	u16 width;
+	u16 height;
+	u16 x;
+	u16 y;
+
+	u8 alpha;
+
+	u32 *texture_pointer;
+};
+
+enum osk_status{
+	OSK_INITIALIZED=0,
+	OSK_RUNNING,
+	OSK_ABORT,
+	OSK_RETURN,
+	OSK_END
+};
+
+struct osk_point{
+	float x;
+	float y;
+};
+
+
+
+typedef _png_loader* (method_a)(char*);
+typedef u8 (method_b)(_png_loader*);
+
+class OSK{
+private:
+	method_a *png_loader;
+	method_b *png_displayer;
+	u32 *texture_pointer;
+
+	int ttf_inited;
+	FT_Library freetype;
+	u8 font_slot;
+
+	osk_status status;
+	osk_point pos;
+
+	_png_loader *btn;
+	_png_loader *space;
+
+	u8 mode;
+	s8 sel_num;
+	s8 sel_row;
+
+	char buffer[256];
+
+	static _png_loader* png_loader_f(char * path, u32 *texture_pointer){
+		_png_loader *png = (_png_loader*)malloc(sizeof(_png_loader));
+		memset(png, 0, sizeof(_png_loader));
+
+		LoadPNG(&(png->png), path);
+
+		if(png->png.bmp_out){
+			memcpy(texture_pointer, png->png.bmp_out, png->png.wpitch * png->png.height);
+            
+			free(png->png.bmp_out);
+			png->png.bmp_out = texture_pointer;
+			texture_pointer += (png->png.wpitch/4 * png->png.height + 3) & ~3; 
+			png->offset = tiny3d_TextureOffset(png->png.bmp_out);
+		}
+
+		png->texture_pointer = texture_pointer;
+		png->alpha = 0xFF;
+
+		return png;
+	};
+
+	static u8 png_displayer_f(_png_loader* png){
+		tiny3d_SetTexture(0, png->offset, png->png.width, png->png.height, png->png.wpitch, TINY3D_TEX_FORMAT_A8R8G8B8, 1);
+		tiny3d_SetPolygon(TINY3D_QUADS);
+	
+		tiny3d_VertexPos(png->x  , png->y  , 1);   
+		tiny3d_VertexColor(0xFFFFFF00 + png->alpha);
+		tiny3d_VertexTexture(0.0f, 0.0f);
+
+		tiny3d_VertexPos(png->x + png->width, png->y  , 1);
+		tiny3d_VertexTexture(1.0f, 0.0f);
+
+		tiny3d_VertexPos(png->x + png->width, png->y + png->height, 1);
+		tiny3d_VertexTexture(1.0f, 1.0f);
+
+		tiny3d_VertexPos(png->x  , png->y + png->height, 1);
+		tiny3d_VertexTexture(0.0f, 1.0f);
+		tiny3d_End();
+
+		return 0;
+	};
+
+	void DrawRect2D(u32 rgba, float x, float y, float width, float height);
+	void DrawBorders2D(u32 rgba, float x, float y, float w, float h, u32 border);
+
+public:
+	OSK(){ status = OSK_INITIALIZED; sel_row = 0; sel_num = 0; png_loader = NULL; png_displayer = NULL; font_slot = -1; ttf_inited = 0; mode = 1; };
+	OSK(u32 *texture_pointer, char *usrdir);
+	OSK(method_a *png_loader, method_b *png_displayer, char *usrdir);
+
+	u32* loadFont(u8 slot, char *usrdir, u32 *texture_pointer);
+
+	u8 draw();
+	u8 handlePad();
+
+	u8 open(){ status = OSK_RUNNING; memset(buffer, 0, 256); return 0; };
+
+	u32 *getTexturePointer(){ return this->texture_pointer; };
+	osk_status getStatus(){ return this->status; };
+
+	char *getBuffer(){ this->status = OSK_END; return this->buffer; };
+
+	void setPos(osk_point npos);
+};
+
+#endif
+#ifndef TYPES_H
+#define TYPES_H
+
+
+#endif
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.