/* PowerComPress v0.9 Copyright (C) 2005 Jonas Gehring PowerComPress is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. PowerComPress is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with PowerComPress; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // C Source File // Created 22.09.2005; 21:18:34 #include #include #include #include #include "pcpress.h" #include "brieflz.h" #include "boolsoft.h" #include "advdialogs.h" #include "FontUtils.h" #include "font_4x6_Hex.h" short item = 0, showfirst = 0; char folder[9]; char var[18]; BOOL isfolder, isgroup; OPTIONS options; void *GrayPlane0, *GrayPlane1; #define ICONHEIGHT 5 // Icons unsigned char icons[4][ICONHEIGHT] = { {0x60, 0xFC, 0xFC, 0xFC, 0xFC}, // Folder {0x88, 0x70, 0x50, 0x70, 0x88}, // Archived {0xE0, 0xB0, 0x90, 0x90, 0xF0} // Group }; // Mod of the AdvDlgProgressBar()-function of Advanced Dialogs v0.91 volatile short time[2]; // Seconds, Minutes long steps[2]; //long progress[3]; BOOL first; short rate; char timestr[6]; short CX, CY; CALLBACK void TimeUp(void) { if (++time[0] > 59) { time[0] = 0; time[1]++; } GrayDrawRect(TXTSTART+CX+81, 52+CY, TXTSTART+CX+100, 58+CY, COLOR_LIGHTGRAY, RECT_FILLED); sprintf(timestr, "%d%d:%d%d", time[1]/10, time[1]-((time[1]/10)*10), time[0]/10, time[0]-((time[0]/10)*10)); GrayDrawStrExt(TXTSTART+CX+81, 52+CY, timestr, A_NORMAL, F_4x6); } void ProgressBarDraw(long pos1, long pos2, long pos3) { if (first) { first = FALSE; OSVRegisterTimer(1, 20, TimeUp); sprintf(timestr, "%d%d:%d%d", time[1]/10, time[1]-((time[1]/10)*10), time[0]/10, time[0]-((time[0]/10)*10)); GrayDrawStrExt(TXTSTART+CX+81, 52+CY, timestr, A_NORMAL, F_4x6); } /* if ((((pos1+1)*108)/steps[0]) > 108) { pos1 = steps[0]; } if ((((pos2+1)*108)/steps[0]) > 108) { pos2 = steps[1]; } if ((((pos3+1)*108)/steps[0]) > 108) { pos3 = steps[1]; }*/ // Draw progress bars GrayDrawRect(26+CX, 41+CY, 26+((((pos1+1)*108)/steps[0]))+CX, 47+CY, COLOR_BLACK, RECT_FILLED); GrayDrawRect(26+CX, 61+CY, 26+((((pos2+1)*108)/steps[1]))+CX, 67+CY, COLOR_DARKGRAY, RECT_FILLED); GrayDrawRect(26+CX, 61+CY, 26+((((pos3+1)*108)/steps[1]))+CX, 67+CY, COLOR_BLACK, RECT_FILLED); } void ProgressBarClose(void) { OSVFreeTimer(1); } void ProgressBarInit(const char *title, const char *str1, const char *str2, long steps1, long steps2, BOOL ResetTime) { CX = (LCD_WIDTH - 160) / 2; CY = (LCD_HEIGHT - 100) / 2; // Draw dialog box GrayDrawRect(20+CX, 27+CY, 140+CX, 80+CY, COLOR_LIGHTGRAY, RECT_FILLED); GrayDrawRect(20+CX, 20+CY, 140+CX, 27+CY, COLOR_BLACK, RECT_FILLED); GrayFastDrawHLine(21+CX, 141+CX, 81+CY, COLOR_BLACK); GrayFastDrawLine(141+CX, 21+CY, 141+CX, 81+CY, COLOR_BLACK); // Add title GrayDrawStrExt(0, 21+CY, title, A_XOR | A_CENTERED, F_4x6); // Add messages GrayDrawStrExt(TXTSTART+CX-10, 32+CY, str1, A_NORMAL, F_4x6); GrayDrawStrExt(TXTSTART+CX-10, 52+CY, str2, A_NORMAL, F_4x6); // Draw progress bars GrayDrawRect(25+CX, 40+CY, 135+CX, 48+CY, COLOR_BLACK, RECT_EMPTY); GrayDrawRect(25+CX, 60+CY, 135+CX, 68+CY, COLOR_BLACK, RECT_EMPTY); // Register progress variables //memset(progress, 0, sizeof(long)*3); steps[0] = steps1+1; steps[1] = steps2+1; if (ResetTime) { memset(&time, 0, sizeof(short)*2); } first = TRUE; Wait(1); } // Shows an About Screen void AboutScreen(void) { // Initialize dialog AdvDlgInit(100, 58, "PowerComPress", B_ESC, B_OK, TRUE, save_int_1); // Add dialog elements AdvDlgAdd(AD_TEXT, "PowerComPress", NULL, 0, 0, 0, TXT_CENTERED); AdvDlgAdd(AD_TEXT, "- "COMMENT_VERSION_STRING" -", NULL, 0, 0, 0, TXT_CENTERED); AdvDlgAdd(AD_TEXT, "written by saubue,", NULL, 0, 0, 0, TXT_CENTERED); AdvDlgAdd(AD_TEXT, "member of boolsoft.", NULL, 0, 0, 0, TXT_CENTERED); AdvDlgAdd(AD_TEXT, "boolsoft.mobifiles.de", NULL, 0, 0, 0, TXT_CENTERED); AdvDlgDo(); } // Draw Frames and menu void DrawFrames(void) { short lineheight; GrayDrawRect(12, 9, LCD_WIDTH-10, LCD_HEIGHT-7, COLOR_DARKGRAY, RECT_EMPTY); GrayDrawRect(11, 8, LCD_WIDTH-11, LCD_HEIGHT-8, COLOR_BLACK, RECT_EMPTY); GrayDrawRect(12, 9, LCD_WIDTH-12, 16, options.Theme ? 0 : 3, RECT_FILLED); GrayDrawRect(12, 17, LCD_WIDTH-12, LCD_HEIGHT-9, options.Theme, RECT_FILLED); if (options.Theme == THEME_BLACK) { lineheight = 17; } else { lineheight = 15; } if (!CALCULATOR) { GrayDrawStrExt(13, 10, "F1:File F2:Options F3:About F4:Exit", A_XOR, F_4x6); GrayDrawLine(43, 9, 43, lineheight, options.Theme); GrayDrawLine(83, 9, 83, lineheight, options.Theme); GrayDrawLine(118, 9, 118, lineheight, options.Theme); } else { GrayDrawStrExt(13, 10, " F1:File F2:Options F3:About F4:Exit", A_XOR, F_4x6); GrayDrawLine(68, 9, 68, lineheight, options.Theme); GrayDrawLine(128, 9, 128, lineheight, options.Theme); GrayDrawLine(180, 9, 180, lineheight, options.Theme); } } // Sets options void SetOptions(void) { short i, xpos; BOOL item = 0; //char type[6], buffer[18]; const char *optiont[2] = { "Set options", "Change theme" }; if (!CALCULATOR) { xpos = 44; } else { xpos = 69; } GrayFastDrawLine(xpos, 17, xpos+51, 17, COLOR_BLACK); // Show menu for (i = 0; i <= 7*2; i++) { GrayFastDrawLine(xpos, 18+i, xpos+51, 18+i, COLOR_BLACK); GrayFastDrawLine(xpos+1, 18+i, xpos+50, 18+i, COLOR_WHITE); if (!(i%7) && i > 0) GrayDrawStrExt(xpos+1, 12+i, optiont[(i/7)-1], A_NORMAL, F_4x6); Wait(2); } GrayFastDrawLine(xpos, 7*3+11, xpos+51, 7*3+11, COLOR_BLACK); GrayInvertRect(xpos+1, 18+(item*7), xpos+50, 24+(item*7)); do { // This saves battery power pokeIO(0x600005, 0b10111); if (_keytest(RR_DOWN) || _keytest(RR_UP)) { Wait(50); GrayInvertRect(xpos+1, 18+(item*7), xpos+50, 24+(item*7)); item = !item; GrayInvertRect(xpos+1, 18+(item*7), xpos+50, 24+(item*7)); } else if (_keytest(RR_ESC)) { ClearKbdQueue(); return; } } while (!_keytest(RR_ENTER) && !_keytest(RR_ENTER2)); if (!item) { ClearKbdQueue(); // Initialize dialog AdvDlgInit(100, 58, "PowerComPress", B_ESC, B_OK, TRUE, save_int_1); // Add dialog elements AdvDlgAdd(AD_TEXT, "Always...", NULL, 0, 0, 0, TXT_STANDARD); AdvDlgAdd(AD_CHECKBOX, "archive output file(s)", NULL, 0, 0, options.AlwaysArcVar, 0); AdvDlgAdd(AD_CHECKBOX, "delete original file(s)", NULL, 0, 0, options.AlwaysDelVar, 0); AdvDlgAdd(AD_CHECKBOX, "split GroupFiles", NULL, 0, 0, options.AlwaysSplitVar, 0); if (!AdvDlgDo()) { return; } options.AlwaysArcVar = AD_CHECKED[0]; options.AlwaysDelVar = AD_CHECKED[1]; options.AlwaysSplitVar = AD_CHECKED[2]; SaveOptions(); } else { if (options.Theme == THEME_WHITE) { options.Theme = THEME_BLACK; } else { options.Theme = THEME_WHITE; } SaveOptions(); DrawFrames(); } } // Marks a menu item (can be used for marking and unmarking) // FALSE = Rectangle void MenuMarkItem(short itemno) { short i; for (i = 0; i < 7; i++) { FastDrawHLine_R(GrayPlane0, 12, LCD_WIDTH-12, 20+(itemno*8)+i, A_XOR); } } // Open menu (TRUE = action, FALSE = nothing) BOOL Menu(SYM_ENTRY *var) { short i, item = 0; char type[6], buffer[18]; BOOL valid[6]; const char *options[6] = { "Add to Group", "Extract", "Archive", "Unarchive ", "Delete", "Cancel" }; const char *shortcuts[6] = { "[+]", "[-]", "[ALPHA]", "[ALPHA]", " ", "[ESC]", }; FontSetSys(F_4x6); sprintf(shortcuts[4], "[%c]", 21); if (CALCULATOR) { for (i = 0; i < 2; i++) { strcpy(shortcuts[i+2], "[HAND]"); } } VarTypeToStr(var, type); memset(valid, TRUE, sizeof(valid)); GrayFastDrawLine(12, 17, 91, 17, COLOR_BLACK); // Show menu for (i = 0; i <= 7*6; i++) { GrayFastDrawLine(12, 18+i, 91, 18+i, COLOR_BLACK); GrayFastDrawLine(13, 18+i, 90, 18+i, COLOR_WHITE); if (!(i%7) && i > 0) { if ((!isgroup && (((i/7) == 2 && strncmp(type, ".pcp", 4)) || ((i/7) == 3 && (var->flags.bits.archived || isfolder)) || ((i/7) == 4 && (!var->flags.bits.archived || isfolder)))) || ((i/7) != 2 && (i/7) != 6 && isgroup)) { GraySetAMSPlane(LIGHT_PLANE); DrawStr(14, 12+i, options[(i/7)-1], A_NORMAL); DrawStr(64, 12+i, shortcuts[(i/7)-1], A_NORMAL); valid[(i/7)-1] = FALSE; } else { GrayDrawStrExt(14, 12+i, options[(i/7)-1], A_NORMAL, F_4x6); GrayDrawStrExt(64, 12+i, shortcuts[(i/7)-1], A_NORMAL, F_4x6); } } Wait(2); } GrayFastDrawLine(12, 8*6+12, 91, 8*6+12, COLOR_BLACK); ClearKbdQueue(); // Find first valid item while (!valid[item]) { item = (item+1) % 5; }; GrayInvertRect(13, 18+(item*7), 90, 24+(item*7)); do { // This saves battery power pokeIO(0x600005, 0b10111); if (_keytest(RR_DOWN)) { Wait(50); GrayInvertRect(13, 18+(item*7), 90, 24+(item*7)); do { item = (item+1) % 6; } while (!valid[item]); GrayInvertRect(13, 18+(item*7), 90, 24+(item*7)); } else if (_keytest(RR_UP)) { Wait(50); GrayInvertRect(13, 18+(item*7), 90, 24+(item*7)); do { item = item ? item-1 : 5; } while (!valid[item]); GrayInvertRect(13, 18+(item*7), 90, 24+(item*7)); } else if (_keytest(RR_ESC)) { ClearKbdQueue(); return FALSE; } } while (!_keytest(RR_ENTER) && !_keytest(RR_ENTER2)); ClearKbdQueue(); memset(buffer, 0, sizeof(buffer)); sprintf(buffer, "%s%c%s", folder, append[0], var->name); if (item == 0) // Add to GroupFile { if (isfolder) { buffer[strlen(buffer)-1] = '\0'; return CompressFolder(buffer); } else { AddVarToGroup(buffer); return REDRAW; } } else if (item == 1) // Extract { if (!isgroup) { return ExtractGroup(buffer, NULL); } else { return EXTRACT_VAR; } } else if (item == 2 || item == 3) // (Un)archive { ArchiveVar(buffer); } else if (item == 4) // Delete { if (!isfolder) { DeleteVar(buffer); } else { buffer[strlen(buffer)-1] = '\0'; DeleteFolder(buffer); } return REDRAW; } else if (item == 5) // Cancel { return REDRAW; } return REDRAW; } // Browse a list of files BOOL Browse(char *title, char *names, char *types, char *sizes, char *csizes, short numitems) { char varbuff[20], str[6]; short i, noit = 8; SYM_ENTRY *symptr; // ...compability! if (CALCULATOR) { noit += 3; } // File or folder? if (isfolder) { noit++; } if (!isfolder && (strcspn(title, append) == strlen(title))) { strcat(title, append); } // Select a file from the menu do { GrayDrawRect(12, 17, LCD_WIDTH-12, LCD_HEIGHT-9, options.Theme, RECT_FILLED); if (!isfolder && !isgroup) { Sprite8_XOR_R(14, 21, ICONHEIGHT, icons[0], GrayPlane1); } if (isgroup) { Sprite8_XOR_R(15, 21, ICONHEIGHT, icons[2], GrayPlane1); } GrayUserDrawStr(22, 21, title); // Draw the first eight (or eleven) items onto the screen for (i = showfirst; i < showfirst+noit; i++) { if (i < numitems) { varbuff[0] = 0; // Add folder icon if (isfolder) { Sprite8_XOR_R(14, 21+((i-showfirst)*8), ICONHEIGHT, icons[0], GrayPlane1); } else { strcat(varbuff, title); strncat(varbuff, &names[(i*9)], 8); if (!isgroup) { symptr = DerefSym(SymFind(SYMSTR(varbuff))); // State of the variable if (symptr->flags.bits.archived) Sprite8_XOR_R(16, (29+((i-showfirst)*8)-(isfolder*8)), ICONHEIGHT, icons[1], GrayPlane1); } else { strncpy(str, &csizes[6*i], 6); GrayUserDrawStr(124, (29+((i-showfirst)*8)-(isfolder*8)), str); } strncpy(str, &types[6*i], 6); GrayUserDrawStr(75, (29+((i-showfirst)*8)-(isfolder*8)), str); strncpy(str, &sizes[6*i], 6); GrayUserDrawStr(100, (29+((i-showfirst)*8)-(isfolder*8)), str); } varbuff[0] = 0; if (!isgroup) { strncat(varbuff, &names[(i*9)], 8); } else { strncat(varbuff, &names[(i*13)], 17); } GrayUserDrawStr(23-isfolder, 29+((i-showfirst)*8)-(isfolder*8), varbuff); } } MenuMarkItem(item+1-isfolder); do { varbuff[0] = 0; strcat(varbuff, title); strncat(varbuff, &names[(item+showfirst)*9+(isgroup*4)], 8); // This saves battery power pokeIO(0x600005, 0b10111); // Scroll up if (_keytest(RR_UP)) { Wait(50); MenuMarkItem(item+1-isfolder); if (item < 1) { if (--showfirst < 0) { if (numitems > noit-1) { item = noit-1; showfirst = numitems-(noit); } else { item = numitems-1; showfirst = 0; } } break; } item--; MenuMarkItem(item+1-isfolder); } // Scroll down else if (_keytest(RR_DOWN)) { Wait(50); MenuMarkItem(item+1-isfolder); if (item > noit-2 || item == numitems-1) { if (++showfirst > numitems-noit) { item = 0; showfirst = 0; } break; } item++; MenuMarkItem(item+1-isfolder); } // Add Var To Group else if (_keytest(RR_PLUS) && !isgroup) { ClearKbdQueue(); if (isfolder) { strncpy(folder, &names[(item+showfirst)*9], 8); return CompressFolder(varbuff); } else { AddVarToGroup(varbuff); return REDRAW; } } // Extract Var From Group else if (_keytest(RR_MINUS)/* && !isgroup*/) { if (!isgroup) { return ExtractGroup(varbuff, NULL); } else { return EXTRACT_VAR; } } // Enter menu else if (_keytest(RR_F1)/* && !isgroup*/) { ClearKbdQueue(); if (isfolder) { strncpy(folder, &names[(item+showfirst)*9], 8); } strcpy(var, varbuff); if ((i = Menu(DerefSym(SymFind(SYMSTR(varbuff))))) > 1) { return i; } else { break; } } // Set options else if (_keytest(RR_F2)) { ClearKbdQueue(); SetOptions(); return REDRAW; } // Show about screen else if (_keytest(RR_F3)) { ClearKbdQueue(); AboutScreen(); } // Exit else if (_keytest(RR_F4)) { ClearKbdQueue(); return EXIT; } // Back to parent view else if (_keytest(RR_ESC)) { ClearKbdQueue(); item = 0; showfirst = 0; if (!isgroup) { memset(folder, 0, 9); } return PARENT; } // Enter child view else if (!isgroup && (_keytest(RR_ENTER) || _keytest(RR_ENTER2))) { ClearKbdQueue(); if (isfolder) strncpy(folder, &names[(item+showfirst)*9], 8); else strcpy(var, varbuff); return CHILD; } // Delete variable else if (!isfolder && _keytest(RR_BCKSPC)) { ClearKbdQueue(); if (!DeleteVar(varbuff)) { break; } //folder[strlen(folder)-1] = 0; return REDRAW; } // Delete folder else if (isfolder && _keytest(RR_BCKSPC)) { ClearKbdQueue(); if (!DeleteFolder(varbuff)) { break; } return REDRAW; } // (Un)archive variable else if (_keytest(RR_HAND) || _keytest(RR_ALPHA)) { ClearKbdQueue(); ArchiveVar(varbuff); break; } } while (TRUE); } while (TRUE); } // Initializes (manages) browsing short InitBrowsing(short action) { SYM_ENTRY *symptr = NULL; char title[10]; short counter = 0, i = 0; char *names, *types, *sizes; isgroup = FALSE; // Register first SYM_ENTRY if (action == FFOLDER) { item = 0; showfirst = 0; isfolder = TRUE; symptr = SymFindFirst(NULL, 0); } else if (action == FFILE) { isfolder = FALSE; symptr = SymFindFirst(SYMSTR(folder), FO_SINGLE_FOLDER); } else if (action == FGROUP) { return ViewGroupEntries(var); } // Count items while (symptr) { if (strncmp(symptr->name, "pcpress", 7) && strncmp(symptr->name, "pcpdata", 7) && strncmp(symptr->name, "pcpcfg", 7) && !symptr->flags.bits.twin && !symptr->flags.bits.local && !symptr->flags.bits.hidden) { counter++; } symptr = SymFindNext(); } // Check for empty folders if (!counter) { AdvDlgMessage("PowerComPress - Error", "Empty folder", B_OK); return PARENT; } // Allocate space for the buffers if ((names = malloc(sizeof(char)*9*counter)) == NULL) { ExitPCP(OUTOFMEM); } if ((types = malloc(sizeof(char)*6*counter)) == NULL) { free(names); ExitPCP(OUTOFMEM); } if ((sizes = malloc(sizeof(char)*6*counter)) == NULL) { free(names); free(types); ExitPCP(OUTOFMEM); } if (isfolder) { symptr = SymFindFirst(NULL, 0); } else { symptr = SymFindFirst(SYMSTR(folder), FO_SINGLE_FOLDER); AdvDlgProgressBar("PowerComPress", "Reading contents...", counter); } // Get a list of the entries of folder "folder" while (symptr) { if (strncmp(symptr->name, "pcpress", 7) && strncmp(symptr->name, "pcpdata", 7) && strncmp(symptr->name, "pcpcfg", 7) && !symptr->flags.bits.twin && !symptr->flags.bits.local && !symptr->flags.bits.hidden) { strncpy(&names[9*i], symptr->name, 8); if (!isfolder) { VarTypeToStr(symptr, &types[6*i]); sprintf(&sizes[6*i], "%lu", GetVarSize(symptr)+2); } i++; } if (!isfolder) { AdvDlgProgressUp(); } symptr = SymFindNext(); } if (action == FFOLDER) { isfolder = TRUE; title[0] = 0; } else if (action == FFILE) { isfolder = FALSE; strcpy(title, folder); } isgroup = FALSE; i = Browse(title, names, types, sizes, NULL, counter); free(names); free(sizes); free(types); if (i == EXIT) { ExitPCP(NORMAL); } return i; } // Set up the GUI (main program loop) void StartGUI(void) { short action, bcur = FFOLDER; if (!LoadOptions()) { BoolsoftIntro(TRUE); options.AlwaysArcVar = TRUE; options.AlwaysDelVar = FALSE; options.AlwaysSplitVar = FALSE; options.Theme = THEME_WHITE; SaveOptions(); } // Turn on Grayscale GFX if (!GrayOn()) { return; } GrayPlane0 = GrayGetPlane(LIGHT_PLANE); GrayPlane1 = GrayGetPlane(DARK_PLANE); FastCopyScreen(screenbuffer, GrayPlane0); FastCopyScreen(screenbuffer, GrayPlane1); DrawFrames(); SetUserFont(font_4x6, 4, 6); // Begin with the browsing do { action = InitBrowsing(bcur); if (action == CHILD && (bcur == FFOLDER || bcur == FFILE)) { if (bcur == FFOLDER) { item = 0; showfirst = 0; } bcur++; } else if (action == PARENT && (bcur == FFILE|| bcur == FGROUP)) { bcur--; } else if (action == REDRAW && bcur == FFILE) { bcur = FFILE; } else if (action == EXIT) { ExitPCP(NORMAL); } } while (TRUE); ExitPCP(NORMAL); }