void msgbox(const char *title, const char *fmt, ...) { char content[512]; va_list args; va_start(args, fmt); vsprintf(content, fmt, args); show_msgbox(title, content); va_end(args); }
int Read() { VRAM = init_VRAM(); AllClr_VRAM( VRAM ); char * VRAM_A = init_VRAM(); AllClr_VRAM( VRAM_A ); char * VRAM_B = init_VRAM(); AllClr_VRAM( VRAM_B ); int total_page , page = 0 , i ,last_key_pressed=0; char buff[1000] , statue_bar[100]; int auto_down = 0 , _auto = 0 , mark = 1 ; int user_contrast = *p_contrast; long auto_time = 0 ; int msg_utf8 = 0; auto_down = _auto = 0 ; strcpy( txtname , fname ); TXT = fopen( txtname , "rb" ) ; fseek(TXT , 0 , SEEK_END); filesize = ftell( TXT ); total_page = divid(); memset( buff , 0x0 , 1000 ); load_mark( &page , total_page , 1 ); fseek( TXT , pagepos[page] , SEEK_SET ); fread( buff , pagepos[ page+1 ] - pagepos[ page ] , 1 , TXT ); AllFill_VRAM(VRAM_A,cl_bg); PrintChStr( VRAM_A , 0 , 0 , buff , cl_fg , cl_bg ); PutDisp_DDVRAM( VRAM_A ); auto_down = 0 ; while( 1 ) { if(isKeyPressed(KEY_NSPIRE_SCRATCHPAD)) { wait_no_key_pressed(); if(msg_utf8==0) i = show_msgbox_3b( "提示" , "调用API必须保证文本为UTF-8编码,也就是此时用nNovel无法正常阅读,要继续吗?" , "确定" , "取消" ,"确定且不再提示" ); else i = 1; if( i == 3 ) { i = 1; msg_utf8 = 1; } if( i == 1 ) { wait_no_key_pressed(); show_msgbox( "本页内容:" , buff ); } } if(isKeyPressed(KEY_NSPIRE_MULTIPLY)) { if( is_cx && (*p_contrast)< 225) (*p_contrast)++; else if( (!is_cx) && (*p_contrast) < 0xc0 ) (*p_contrast)++; } else if(isKeyPressed(KEY_NSPIRE_DIVIDE)) { if( is_cx && (*p_contrast)> 1 ) (*p_contrast)--; else if( (!is_cx) && (*p_contrast) >50 ) (*p_contrast)--; } else if(isKeyPressed(KEY_NSPIRE_TAB)) { i = num_input(VRAM , 30 , 30 , " ����ҳ��" ); if( i == -1) continue; else if( i == 0 ){ page = 0;} else if( i > total_page){ page = total_page;} else page = i - 1; memset( buff , 0x0 , 1000 ); fseek( TXT , pagepos[page] , SEEK_SET ); fread( buff , pagepos[ page +1 ] - pagepos[ page ] , 1 , TXT ); AllFill_VRAM(VRAM_A,cl_bg); PrintChStr( VRAM_A , 0 , 0 , buff , cl_fg , cl_bg ); PutDisp_DDVRAM( VRAM_A ); wait_no_key_pressed(); } else if(isKeyPressed(KEY_NSPIRE_DOC)) { save_mark( page , total_page , 0 ); wait_no_key_pressed(); } else if(isKeyPressed(KEY_NSPIRE_MENU)) { load_mark( &page , total_page , 0 ); memset( buff , 0x0 , 1000 ); fseek( TXT , pagepos[page] , SEEK_SET ); fread( buff , pagepos[ page +1 ] - pagepos[ page ] , 1 , TXT ); AllFill_VRAM(VRAM_B,cl_bg); PrintChStr( VRAM_A , 0 , 0 , buff , cl_fg , cl_bg ); PutDisp_DDVRAM( VRAM_A ); wait_no_key_pressed(); } else if(isKeyPressed(KEY_NSPIRE_SHIFT)) { if(cl_bg == 15) { cl_fg = 15; cl_bg = 0; } else { cl_fg = 0; cl_bg = 15; } memset( buff , 0x0 , 1000 ); fseek( TXT , pagepos[page] , SEEK_SET ); fread( buff , pagepos[ page +1 ] - pagepos[ page ] , 1 , TXT ); AllFill_VRAM(VRAM_A,cl_bg); PrintChStr( VRAM_A , 0 , 0 , buff , cl_fg , cl_bg ); PutDisp_DDVRAM( VRAM_A ); wait_no_key_pressed(); } if((*p_RTC - auto_time)%(_auto) != 0) mark = 0; if( ( isKeyPressed(KEY_NSPIRE_DOWN ) || isKeyPressed(KEY_NSPIRE_MINUS )|| auto_down == 1 )&& page < total_page ) { auto_down = 0; page++; memset( buff , 0x0 , 1000 ); fseek( TXT , pagepos[page] , SEEK_SET ); fread( buff , pagepos[ page +1 ] - pagepos[ page ] , 1 , TXT ); if( cl_bg != 15 ) AllFill_VRAM(VRAM_B,cl_bg); else AllClr_VRAM(VRAM_B); PrintChStr( VRAM_B , 0 , 0 , buff , cl_fg , cl_bg ); if( config.show_page_slide == 1 ) slide_down(statue_bar , VRAM_A , VRAM_B , 1 ); else { Fill_Rect_VRAM( VRAM_B , 0 , 224 , 320 , 240 , 0 ); PrintChStr( VRAM_B , 0 , 224 , statue_bar , 15 , 0 ); PutDisp_DDVRAM(VRAM_B); for( i=0 ; i<=FIRST_KEY_WAIT ; i++ ) { if((!isKeyPressed(KEY_NSPIRE_DOWN )|| isKeyPressed(KEY_NSPIRE_MINUS ))) break; if(last_key_pressed) break; sleep(1); if( i == FIRST_KEY_WAIT ) last_key_pressed = 1; } } memcpy(VRAM_A,VRAM_B,SCREEN_BYTES_SIZE); } else if( isKeyPressed(KEY_NSPIRE_UP )|| isKeyPressed(KEY_NSPIRE_PLUS ) ) { if( page == 0 ) continue; page --; memset( buff , 0x0 , 1000 ); fseek( TXT , pagepos[page] , SEEK_SET ); fread( buff , pagepos[ page +1 ] - pagepos[ page ], 1 , TXT ); AllFill_VRAM(VRAM_B,cl_bg); PrintChStr( VRAM_B , 0 , 0 , buff , cl_fg , cl_bg ); if( config.show_page_slide == 1 ) slide_up( statue_bar , VRAM_B , VRAM_A , 1 ); else { Fill_Rect_VRAM( VRAM_B , 0 , 224 , 320 , 240 , 0 ); PrintChStr( VRAM_B , 0 , 224 , statue_bar , 15 , 0 ); PutDisp_DDVRAM(VRAM_B); for( i=0 ; i<=FIRST_KEY_WAIT ; i++ ) { if((!isKeyPressed(KEY_NSPIRE_UP )|| isKeyPressed(KEY_NSPIRE_PLUS ))) break; if(last_key_pressed) break; sleep(1); if( i == FIRST_KEY_WAIT ) last_key_pressed = 1; } } memcpy(VRAM_A,VRAM_B,SCREEN_BYTES_SIZE); } else last_key_pressed = 0; memcpy(VRAM,VRAM_A,SCREEN_BYTES_SIZE); Fill_Rect_VRAM( VRAM , 0 , 224 , 320 , 240 , 0 ); if( config.show_time ) { update_time(); if( config.show_second ) sprintf(statue_bar , " %d%d:%d%d:%d%d %5d/%5d %4s", time.hour/10 , time.hour%10 , time.minute/10, time.minute%10 , time.second/10 , time.second%10 , page +1 , total_page +1 , _auto == 0?"":"Auto"); else sprintf(statue_bar , " %d%d:%d%d %5d/%5d %4s", time.hour/10 , time.hour%10 , time.minute/10, time.minute%10 , page +1 , total_page +1 ,_auto == 0?"":"Auto"); } else { sprintf(statue_bar , " %5d/%5d", page +1 , total_page +1 ); } PrintChStr( VRAM , 0 , 224 , statue_bar , 15 , 0 ); // DrawMiniString_VRAM(VRAM , 0 , 228 , statue_bar , 15 , 0 ); PutDisp_DDVRAM(VRAM); if( ! config.show_time ) { if( !(isKeyPressed(KEY_NSPIRE_UP)||isKeyPressed(KEY_NSPIRE_DOWN)) ) wait_key_pressed(); } if( isKeyPressed(KEY_NSPIRE_ESC)) { if(isKeyPressed(KEY_NSPIRE_CTRL)) goto exit; switch(menu(VRAM,10,10," �˵�\nҳ����ת(Tab)\n�Զ���ҳ\n��ȡ��ǩ(menu)\n������ǩ(doc)\n����\nҹ��ģʽ(shift)\n�����ǩ��ҳ���˳�\n����API�鿴��ҳ(��ǩ��)\n�˳�(ctrl+esc)\n","\n������λ����ת������λ��\n����/�ر��Զ���ҳ\n����ǩ�ļ��ж�ȡ����\n����ǩ�ļ���д�����\n�鿴��������\n����ҹ��ģʽ(��ɫ)\n��������ɵ�������ǩ�ͷ�ҳ�Ľ���ļ�\n����MsgBox����ʾ��ҳ����\n�˳�����\n") ) { case 1://ҳ����ת { i = num_input(SCREEN_BASE_ADDRESS , 30 , 30 , " ����ҳ��" ); if( i == -1) break; else if( i == 0 ){ page = 0;} else if( i > total_page){ page = total_page;} else page = i - 1; memset( buff , 0x0 , 1000 ); fseek( TXT , pagepos[page] , SEEK_SET ); fread( buff , pagepos[ page +1 ] - pagepos[ page ] , 1 , TXT ); AllFill_VRAM(VRAM_A,cl_bg); PrintChStr( VRAM_A , 0 , 0 , buff , cl_fg , cl_bg ); PutDisp_DDVRAM( VRAM_A ); break; } case 2://�Զ���ҳ { if( _auto != 0 ) { _auto = 0 ; mark = 1; break; } _auto = num_input( SCREEN_BASE_ADDRESS , 30 , 30 , "��������" ); if(_auto == -1) _auto = 0; auto_time = *p_RTC; break; } case 3: //��ȡ��ǩ { load_mark( &page , total_page , 0 ); memset( buff , 0x0 , 1000 ); fseek( TXT , pagepos[page] , SEEK_SET ); fread( buff , pagepos[ page +1 ] - pagepos[ page ] , 1 , TXT ); AllFill_VRAM(VRAM_B,cl_bg); PrintChStr( VRAM_A , 0 , 0 , buff , cl_fg , cl_bg ); PutDisp_DDVRAM( VRAM_A ); break; } case 4: save_mark( page , total_page , 0 );break;//������ǩ case 5: //���� { setup_config(); memset( buff , 0x0 , 1000 ); fseek( TXT , pagepos[page] , SEEK_SET ); fread( buff , pagepos[ page +1 ] - pagepos[ page ] , 1 , TXT ); AllFill_VRAM(VRAM_A,cl_bg); PrintChStr( VRAM_A , 0 , 0 , buff , cl_fg , cl_bg ); PutDisp_DDVRAM( VRAM_A ); break; } case 6: //��ɫ { if(cl_bg == 15) { cl_fg = 15; cl_bg = 0; } else { cl_fg = 0; cl_bg = 15; } memset( buff , 0x0 , 1000 ); fseek( TXT , pagepos[page] , SEEK_SET ); fread( buff , pagepos[ page +1 ] - pagepos[ page ] , 1 , TXT ); AllFill_VRAM(VRAM_A,cl_bg); PrintChStr( VRAM_A , 0 , 0 , buff , cl_fg , cl_bg ); PutDisp_DDVRAM( VRAM_A ); break; } case 7: //�����ǩ { char path[ 50 ]; for( i = 0 ; i < strlen(txtname) - 8 ; i ++ ) path[i] = txtname[i] ; path[ i ] = 0; strcat( path , ".div" ); remove(path); for( i = 0 ; i < strlen(txtname) - 8 ; i ++ ) path[i] = txtname[i] ; path[ i ] = 0; strcat( path , ".sav" ); remove(path); goto exit2; } case 8://API { wait_no_key_pressed(); if(msg_utf8==0) i = show_msgbox_3b( "提示" , "调用API必须保证文本为UTF-8编码,也就是此时用nNovel无法正常阅读,要继续吗?" , "确定" , "取消" ,"确定且不再提示" ); else i = 1; if( i == 3 ) { i = 1; msg_utf8 = 1; } if( i == 1 ) { wait_no_key_pressed(); show_msgbox( "本页内容:" , buff ); break; } else break; } case 9: goto exit;//�˳� default :wait_no_key_pressed();break; } wait_no_key_pressed(); } if( config.auto_save ) if( page%config.auto_save_time==0 ) save_mark( page , total_page , 1 ); if( (*p_RTC - auto_time)%(_auto) == 0 && mark == 0) { mark = 1 ; auto_down = 1 ; auto_time = *p_RTC; } } exit: save_mark( page , total_page , 1 ); exit2: * p_contrast = user_contrast; fclose( TXT ); close_VRAM( VRAM_A );close_VRAM( VRAM_B ); close_VRAM( VRAM ); return 0; }
extern "C" int zehn_load(NUC_FILE *file, void **mem_ptr, int (**entry)(int,char*[]), bool *supports_hww) { Zehn_header header; // The Zehn file may not begin at the file start size_t file_start = nuc_ftell(file); if(nuc_fread(&header, sizeof(header), 1, file) != 1) return 1; if(header.signature != ZEHN_SIGNATURE || header.version != ZEHN_VERSION || header.file_size > header.alloc_size) { puts("[Zehn] This Zehn file is not supported!"); return 1; } Storage<Zehn_reloc> relocs(header.reloc_count); Storage<Zehn_flag> flags(header.flag_count); Storage<uint8_t> extra_data(header.extra_size); if(nuc_fread(reinterpret_cast<void*>(relocs.data), sizeof(Zehn_reloc), header.reloc_count, file) != header.reloc_count || nuc_fread(reinterpret_cast<void*>(flags.data), sizeof(Zehn_flag), header.flag_count, file) != header.flag_count || nuc_fread(reinterpret_cast<void*>(extra_data.data), 1, header.extra_size, file) != header.extra_size) { puts("[Zehn] File read failed!"); return 1; } size_t remaining_mem = header.alloc_size - nuc_ftell(file) + file_start, remaining_file = header.file_size - nuc_ftell(file) + file_start; if(emu_debug_alloc_ptr) { if(emu_debug_alloc_size < remaining_mem) { puts("[Zehn] emu_debug_alloc_size too small!"); *mem_ptr = malloc(remaining_mem); } else *mem_ptr = emu_debug_alloc_ptr; } else *mem_ptr = malloc(remaining_mem); uint8_t *base = reinterpret_cast<uint8_t*>(*mem_ptr); if(!base) { puts("[Zehn] Memory allocation failed!"); return 1; } if(relocs.data[0].type == Zehn_reloc_type::FILE_COMPRESSED) { if(relocs.data[0].offset != static_cast<int>(Zehn_compress_type::ZLIB)) { puts("[Zehn] Compression format not supported!"); return 1; } Storage<uint8_t> compressed(remaining_file); if(nuc_fread(compressed.data, remaining_file, 1, file) != 1) { puts("[Zehn] File read failed!"); return 1; } uLongf dest_len = remaining_mem; if(uncompress(base, &dest_len, compressed.data, remaining_file) != Z_OK) { puts("[Zehn] Decompression failed!"); return 1; } std::fill(base + dest_len, base + remaining_mem, 0); } else { if(nuc_fread(base, remaining_file, 1, file) != 1) { puts("[Zehn] File read failed!"); return 1; } // Fill rest with zeros (.bss and other NOBITS sections) std::fill(base + remaining_file, base + remaining_mem, 0); } const char *application_name = "(unknown)", *application_author = "(unknown)", *application_notice = "(no notice)"; unsigned int application_version = 1, ndless_version_min = 0, ndless_version_max = UINT_MAX, ndless_revision_min = 0, ndless_revision_max = UINT_MAX; // Iterate through each flag for(Zehn_flag &f : flags) { const char *ptr; switch(f.type) { case Zehn_flag_type::EXECUTABLE_NAME: if(!zehn_check_string(extra_data.begin(), f, 255, &application_name)) { puts("[Zehn] Invalid application name!"); return 1; } break; case Zehn_flag_type::EXECUTABLE_NOTICE: if(zehn_check_string(extra_data.begin(), f, 1024, &ptr)) application_notice = ptr; break; case Zehn_flag_type::EXECUTABLE_AUTHOR: if(zehn_check_string(extra_data.begin(), f, 128, &ptr)) application_author = ptr; break; case Zehn_flag_type::EXECUTABLE_VERSION: application_version = f.data; break; case Zehn_flag_type::NDLESS_VERSION_MIN: ndless_version_min = f.data; break; case Zehn_flag_type::NDLESS_REVISION_MIN: ndless_revision_min = f.data; break; case Zehn_flag_type::NDLESS_VERSION_MAX: ndless_version_max = f.data; break; case Zehn_flag_type::NDLESS_REVISION_MAX: ndless_revision_max = f.data; break; case Zehn_flag_type::RUNS_ON_COLOR: if(f.data == false && has_colors) { msgbox("Error", "The application %s doesn't support CX and CM calculators!", application_name); return 2; } break; case Zehn_flag_type::RUNS_ON_CLICKPAD: if(f.data == false && !is_touchpad) { msgbox("Error", "The application %s doesn't support clickpads!", application_name); return 2; } break; case Zehn_flag_type::RUNS_ON_TOUCHPAD: if(f.data == false && is_touchpad) { msgbox("Error", "The application %s doesn't support touchpads!", application_name); return 2; } break; case Zehn_flag_type::RUNS_ON_32MB: if(f.data == false && (!has_colors || is_cm)) { msgbox("Error", "The application %s requires more than 32MB of RAM!", application_name); return 2; } break; case Zehn_flag_type::RUNS_ON_HWW: *supports_hww = f.data; break; default: break; } } // Show some information about the executable if(isKeyPressed(KEY_NSPIRE_CAT)) { char info[1536]; sprintf(info, "Name: %s Version: %u\nAuthor: %s\nNotice: %s", application_name, application_version, application_author, application_notice); show_msgbox("Information about the executable", info); return 2; } if(NDLESS_VERSION < ndless_version_min || (NDLESS_VERSION == ndless_version_min && NDLESS_REVISION < ndless_revision_min)) { msgbox("Error", "The application %s requires at least ndless %d.%d.%d!", application_name, ndless_version_min / 10, ndless_version_min % 10, ndless_revision_min); return 2; } if(NDLESS_VERSION > ndless_version_max || (NDLESS_VERSION == ndless_version_max && NDLESS_REVISION > ndless_revision_max)) { if(ndless_revision_max != UINT_MAX) msgbox("Error", "The application %s requires ndless %d.%d.%d or older!", application_name, ndless_version_max / 10, ndless_version_max % 10, ndless_revision_max); else msgbox("Error", "The application %s requires ndless %d.%d or older!", application_name, ndless_version_max / 10, ndless_version_max % 10); return 2; } // Iterate through the reloc table for(Zehn_reloc &r : relocs) { if(r.offset >= remaining_mem) { puts("[Zehn] Wrong reloc in Zehn file!"); return 1; } // No alignment guaranteed! uint32_t *place = reinterpret_cast<uint32_t*>(base + r.offset); switch(r.type) { //Handled above case Zehn_reloc_type::FILE_COMPRESSED: break; case Zehn_reloc_type::UNALIGNED_RELOC: if(r.offset != 0) { printf("[Zehn] Unexpected UNALIGNED_RELOC value %lu!\n", r.offset); return 1; } break; case Zehn_reloc_type::ADD_BASE: wu32(place, ru32(place) + reinterpret_cast<uint32_t>(base)); break; case Zehn_reloc_type::ADD_BASE_GOT: { uint32_t u32; while((u32 = ru32(place)) != 0xFFFFFFFF) wu32(place++, u32 + reinterpret_cast<uint32_t>(base)); break; } case Zehn_reloc_type::SET_ZERO: wu32(place, 0); break; default: printf("[Zehn] Unsupported reloc %d!\n", static_cast<int>(r.type)); return 1; } } *entry = reinterpret_cast<int (*)(int,char*[])>(base + header.entry_offset); return 0; }
void select_file(char result[13]) { static int page = 0; // Remember selections while the program runs static int index = 0; int maxindex = 0; bool rerender = true; for(;;) { if (get_keys(BUTTON1) && index >= 0) { // File selected, get the name and return if (get_name(result, page, index)) return; else rerender = true; // Couldn't find file, maybe fs has changed? } if (get_keys(BUTTON2)) { // Refresh //f_flush(&fatfs); rerender = true; } if (get_keys(BUTTON4)) { show_msgbox("About PAWN_APP", "Pawn scripting language for DSO Quad\n" "(C) 2012 Petteri Aimonen <*****@*****.**>\n" "\n" "Built " __DATE__ " at " __TIME__ "\n" "Git id " COMMITID "\n" "GCC version " __VERSION__ ); rerender = true; } if (peek_keys(SCROLL1_LEFT | SCROLL1_RIGHT | SCROLL2_LEFT | SCROLL2_RIGHT)) { // Clear old cursor show_cursor(index, 0); // Update index if (get_keys(SCROLL1_LEFT)) index -= 4; if (get_keys(SCROLL1_RIGHT)) index += 4; if (get_keys(SCROLL2_LEFT)) index -= 1; if (get_keys(SCROLL2_RIGHT)) index += 1; if (index < 0) { if (page > 0) { page--; render_screen(page, &maxindex); index += 12; } else { index = 0; } } if (index >= maxindex) { if (maxindex > ICONS_ON_SCREEN) { page++; index -= 12; rerender = true; } else { index = maxindex - 1; } } // Draw new cursor show_cursor(index, RGB(128, 128, 255)); } if (rerender) { render_screen(page, &maxindex); show_cursor(index, RGB(128, 128, 255)); rerender = false; if (index >= maxindex) index = maxindex - 1; } } }
int main(void) { __Set(BEEP_VOLUME, 0); // USART1 8N1 115200bps debug port RCC->APB2ENR |= RCC_APB2ENR_USART1EN; USART1->BRR = 72000000 / 115200; USART1->CR1 = USART_CR1_UE | USART_CR1_TE | USART_CR1_RE; gpio_usart1_tx_mode(GPIO_AFOUT_10); gpio_usart1_rx_mode(GPIO_HIGHZ_INPUT); printf("\nBoot!\n"); // Reduce the wait states of the FPGA & LCD interface // It works for me, hopefully it works for you too :) FSMC_BTR1 = 0x10100110; FSMC_BTR2 = 0x10100110; __Set(ADC_CTRL, EN); __Set(ADC_MODE, SEPARATE); alterbios_init(); int status = alterbios_check(); if (status < 0) { char buf[100]; snprintf(buf, sizeof(buf), "AlterBIOS not found or too old: %d\n" "Please install it from https://github.com/PetteriAimonen/AlterBIOS", status); while (1) show_msgbox("AlterBIOS is required", buf); } get_keys(ALL_KEYS); // Clear key buffer while (true) { select_file(amx_filename); get_keys(ANY_KEY); __Clear_Screen(0); char error[50] = {0}; int status = loadprogram(amx_filename, error, sizeof(error)); if (status != 0) { char buffer[200]; snprintf(buffer, sizeof(buffer), "Loading of program %s failed:\n\n" "Error %d: %s\n\n" "%s\n", amx_filename, status, my_aux_StrError(status), error); printf(buffer); printf(amx_filename); show_msgbox("Program load failed", buffer); } else { int idle_func = -1; if (amx_FindPublic(&amx, "@idle", &idle_func) != 0) idle_func = -1; cell ret; status = amx_Exec(&amx, &ret, AMX_EXEC_MAIN); while (status == AMX_ERR_SLEEP) { AMX nested_amx = amx; uint32_t end = get_time() + amx.pri; do { status = doevents(&nested_amx); } while (get_time() < end && status == 0); if (status == 0) status = amx_Exec(&amx, &ret, AMX_EXEC_CONT); else amx = nested_amx; // Report errors properly } if (status == 0 && idle_func != -1) { // Main() exited, keep running idle function. do { status = doevents(&amx); if (status == 0) status = amx_Exec(&amx, &ret, idle_func); } while (status == 0 && ret != 0); } amxcleanup_wavein(&amx); amxcleanup_file(&amx); if (status == AMX_ERR_EXIT && ret == 0) status = 0; // Ignore exit(0), but inform about e.g. exit(1) if (status != 0) { show_pawn_traceback(amx_filename, &amx, status); } else { draw_menubar("Close", "", "", ""); while (!get_keys(BUTTON1)); } } } return 0; }
void show_pawn_traceback(const char *filename, AMX *amx, int return_status) { AMX_HEADER *hdr = (AMX_HEADER*)amx->base; char buffer[500]; char *p = buffer; char *end = buffer + 500; p += snprintf(p, REMAINING, "Virtual machine error: %s\n", my_aux_StrError(return_status)); p += snprintf(p, REMAINING, "CIP: %08lx PRI: %08lx ALT: %08lx\n", amx->cip, amx->pri, amx->alt); if (hdr->flags & AMX_FLAG_OVERLAY) { p += snprintf(p, REMAINING, "Current overlay index: %d\n", amx->ovl_index); } p += snprintf(p, REMAINING, "\n"); { FIL *file = &amx_file; AMX_DEBUG_INFO dbg; char tmp[40]; bool have_dbg = false; if (!(hdr->flags & AMX_FLAG_DEBUG)) { p += snprintf(p, REMAINING, "Symbolic debug info not available. " "Please recompile with -d2.\n"); } else { have_dbg = amxdbg_load(file, amx, &dbg); if (!have_dbg) { p += snprintf(p, REMAINING, "Failed to load symbolic debug info.\n"); } } if (have_dbg) { unsigned location = amx->cip; if (hdr->flags & AMX_FLAG_OVERLAY) { location = (amx->cip << 16) | amx->ovl_index; } if (amxdbg_find_location(&dbg, location, tmp, sizeof(tmp))) { p += snprintf(p, REMAINING, "Location: %s\n", tmp); } if (amxdbg_format_locals(&dbg, amx, amx->frm, location, tmp, sizeof(tmp))) { p += snprintf(p, REMAINING, " %s\n", tmp); } } int i = 1; unsigned frame = amx->frm, caller; while (i < 4 && (caller = amxdbg_get_caller(amx, &frame)) != 0) { if (have_dbg && amxdbg_find_location(&dbg, caller, tmp, sizeof(tmp))) { p += snprintf(p, REMAINING, "Caller %d: %s\n", i, tmp); } else { p += snprintf(p, REMAINING, "Caller %d: %08x\n", i, caller); } if (have_dbg && amxdbg_format_locals(&dbg, amx, frame, caller, tmp, sizeof(tmp))) { p += snprintf(p, REMAINING, " %s\n", tmp); } i++; } } { FIL file; unsigned bytes; unsigned len = strlen(buffer); f_open(&file, "crash.txt", FA_WRITE | FA_CREATE_ALWAYS); f_write(&file, buffer, len, &bytes); f_close(&file); if (bytes == len) { p += snprintf(p, REMAINING, "\nThis message was written also to crash.txt."); } } show_msgbox("Program crashed", buffer); }
int main(void) { t_gravity_particles gravity_particles; t_particle_system* particle_system; t_particle* p; int i; show_msgbox( "Ndless - Particle System Demo", "------------------------\n" " Particle System Demo\n" \ "© 2010-2011 by the Ndless Team\n" "------------------------\n" "+ Add a particle\n" "- Remove a particle\n" "* Increase gravity\n" "/ Decrease gravity\n" "C Enable/Disable collision detection\n" "T Enable/Disable trace mode\n" "S Clear screen\n" "ESC - Exit" ); if (is_classic) { // programs are started with the screen cleared on non-classic void *scrbuf = malloc(SCREEN_BYTES_SIZE); memcpy(scrbuf, SCREEN_BASE_ADDRESS, SCREEN_BYTES_SIZE); for (i = 0; i < 0x0F; ++i) { fade(scrbuf, 1); sleep(70); if (isKeyPressed(KEY_NSPIRE_ESC)) { free(scrbuf); return 0; } } free(scrbuf); } clrscr(); lcd_ingray(); gravity_particles_construct(&gravity_particles, 0.00006672f, 100); particle_system = &(gravity_particles.particleSystem); particle_system->detectCol = false; particle_system->trace = false; particle_system_start(particle_system); p = particle_construct3(&(t_vector){0.f, 0.f, 0.f}, &(t_vector){0.f, 0.f, 0.f}, 1500.f, 4, BLACK); (void) particle_system_addParticle(particle_system, p); add_particle(&gravity_particles); while (!isKeyPressed(KEY_NSPIRE_ESC)) { gravity_particles_draw(&gravity_particles); // Add a particule (+) if (isKeyPressed(KEY_NSPIRE_PLUS)) { if (particle_system->nParticles == 0) { p = particle_construct3(&(t_vector){0.f, 0.f, 0.f}, &(t_vector){0.f, 0.f, 0.f}, 1500.f, 4, BLACK); (void) particle_system_addParticle(particle_system, p); } add_particle(&gravity_particles); while (isKeyPressed(KEY_NSPIRE_PLUS)); } // Remove a particle (-) if (isKeyPressed(KEY_NSPIRE_MINUS)) { remove_particle(&gravity_particles); while (isKeyPressed(KEY_NSPIRE_MINUS)); } // High gravity (*) if (isKeyPressed(KEY_NSPIRE_MULTIPLY)) { gravity_particles.gravitationalConstant *= 10.f; while (isKeyPressed(KEY_NSPIRE_MULTIPLY)); } // Low gravity (/) if (isKeyPressed(KEY_NSPIRE_DIVIDE)) { gravity_particles.gravitationalConstant /= 10.f; while (isKeyPressed(KEY_NSPIRE_DIVIDE)); } // Collision (C) if (isKeyPressed(KEY_NSPIRE_C)) { particle_system->detectCol = !particle_system->detectCol; while (isKeyPressed(KEY_NSPIRE_C)); } // Collision (T) if (isKeyPressed(KEY_NSPIRE_T)) { particle_system->trace = !particle_system->trace; while (isKeyPressed(KEY_NSPIRE_T)); } // Collision (S) if (isKeyPressed(KEY_NSPIRE_S)) { clearScreen(); while (isKeyPressed(KEY_NSPIRE_S)); } } gravity_particles_destruct(&gravity_particles); return 0; }